developer guide
Mock socket
Drive a real-time screen with no backend: a snapshot the moment it opens, then deltas on a timer, all from a seeded feed. Swap to a real socket in one line when you go live.
A live feed with no server
The mock socket stands in for a live WebSocket so you can build, demonstrate and test a
moving screen without standing up a backend first. It presents the same surface as the browser's own
socket: the same readyState and state constants, the same onopen,
onmessage, onclose and onerror, addEventListener,
send and close. Because the shape matches, the code that reads the feed does not
change when you point it at a real endpoint. It fires an opening snapshot the moment it connects, then a
steady stream of change batches on a timer, all from a generator you hand it.
Reach for it when you want to see a streaming interface work before the server exists, keep a demo alive with no infrastructure behind it, or write a test that asserts on an exact sequence of updates. It carries no dependencies, imports nothing from the grid core, and is plain JavaScript and timers, so it is safe to paste straight into a page or a sandbox. It pairs naturally with the data router and the streaming source, feeding one live stream to a whole screen, but it depends on neither any more than a real socket would.
Loading it
The mock socket ships in the main package, so if you already have the grid installed you have this too. Import what you need from the module entry:
import { MockWebSocket, opsFeed } from '@toclocoinc/lattice-grid/modules/mock-socket';
For a page with no build step, load it from the CDN. The module resolves as a standard ES module:
import { MockWebSocket, opsFeed } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.52.0/modules/mock-socket.esm.min.js';
There is also a UMD build that puts everything on a single browser global,
LatticeGridMockSocket, for a plain script tag:
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.52.0/modules/mock-socket.min.js"></script>
<script>
// The module lands on one browser global.
const { MockWebSocket, priceFeed } = window.LatticeGridMockSocket;
const socket = new MockWebSocket({ feed: priceFeed({ seed: 7 }), rate: 260 });
</script>
A running example
Open a socket with a feed, read the messages, and render them. A snapshot carries the full opening set of
rows; each delta carries the changes since. You parse event.data and switch on
kind, exactly as you would against a real feed that framed its messages the same way.
import { MockWebSocket, opsFeed } from '@toclocoinc/lattice-grid/modules/mock-socket';
// A live feed with no server: a snapshot the moment it opens, then deltas on a timer.
const socket = new MockWebSocket({ feed: opsFeed({ seed: 7 }), rate: 900, jitter: 300 });
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.kind === 'snapshot') {
// message.rows is the full opening set
} else {
// message.changes is [{ op: 'upsert' | 'delete', row }]
}
};
// Going live is the one line that changes; everything above stays as written:
// const socket = new WebSocket('wss://example.com/ops');
The constructor takes the feed plus a few timing controls: rate is the milliseconds between
deltas, jitter adds a random plus or minus on each gap so the stream does not look
mechanical, snapshotDelay is the pause before it opens, and pauseWhenHidden
holds the feed while the tab is in the background so it is not doing work no one is watching. Beyond the
standard socket surface, pause() and resume() let a demo hold and continue the
stream while the socket stays open, and a cosmetic url makes socket.url read
like the real thing.
Pairing it with the data router
The shipped feeds are built to drop straight into a routed screen: every record carries a
type, the property the router partitions on, and an id, its row key. Load the
snapshot and apply each delta, and one live stream fans out across several grids and a chart at once.
import { createDataRouter } from '@toclocoinc/lattice-grid/modules/data-router';
import { MockWebSocket, opsFeed } from '@toclocoinc/lattice-grid/modules/mock-socket';
const socket = new MockWebSocket({ feed: opsFeed({ seed: 7 }) });
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.kind === 'snapshot') router.load(message.rows);
else router.apply(message.changes);
};
Two feeds ship. opsFeed is a mixed operations stream of orders, shipments and incidents
across three regions, plus a throughput rollup, the kind of feed a routed dashboard splits many ways.
priceFeed is a market-data stream whose instrument prices random-walk each tick, each record
carrying a symbol, a last price, a change and a bid and ask straddling it. Both take a seed,
so the same inputs replay the same stream every time, which is what lets a demo and a test show the exact
same thing on every run.
Bringing your own feed
A feed is any iterator that yields a snapshot first and then deltas forever, so a plain generator function
is the easiest form. The exported rng gives you the same small seeded generator the shipped
feeds use, so a feed of your own can be seeded and repeatable in the same way.
import { MockWebSocket, rng } from '@toclocoinc/lattice-grid/modules/mock-socket';
function* ticks({ seed = 1 } = {}) {
const rand = rng(seed);
const rows = [{ id: 'A', type: 'sensor', reading: 20 }];
yield { kind: 'snapshot', rows };
for (;;) {
const reading = 20 + Math.round(rand() * 10);
yield { kind: 'delta', changes: [{ op: 'upsert', row: { id: 'A', type: 'sensor', reading } }] };
}
}
const socket = new MockWebSocket({ feed: ticks({ seed: 42 }), rate: 500 });
When a feed ends, the socket closes cleanly; when it throws, the error surfaces as an
error event rather than an uncaught exception, so a page reading it behaves the way it would
against a real feed that dropped.
See it running: the operations console partitions one ops feed across a screen, and the trading terminal drives a market view from the price feed. For the other ways to feed a grid, start from connect your data.