Skip to content

Commit 3987d4f

Browse files
committed
Combined WORKERS.md into README
1 parent 15d015a commit 3987d4f

2 files changed

Lines changed: 101 additions & 106 deletions

File tree

packages/sse/README.md

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Primitives for [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web
1212

1313
- [`makeSSE`](#makesse) — Base non-reactive primitive. Creates an `EventSource` and returns a cleanup function. No Solid lifecycle.
1414
- [`createSSE`](#createsse) — Reactive primitive. Accepts a reactive URL, integrates with Solid's owner lifecycle, and returns signals for `data`, `error`, and `readyState`.
15-
- [`makeSSEWorker`](./WORKERS.md) — Runs the SSE connection inside a Web Worker or SharedWorker. See [WORKERS.md](./WORKERS.md).
15+
- [`makeSSEWorker`](#running-sse-in-a-worker) — Runs the SSE connection inside a Web Worker or SharedWorker.
1616
- [Built-in transformers](#built-in-transformers)`json`, `ndjson`, `lines`, `number`, `safe`, `pipe`.
1717

1818
## Installation
@@ -212,12 +212,6 @@ createSSE("https://api.example.com/events", {
212212
return <For each={messages}>{msg => <p>{msg}</p>}</For>;
213213
```
214214

215-
## Running SSE in a Worker
216-
217-
For high-frequency streams or performance-sensitive apps you can offload the `EventSource` connection to a Web Worker, keeping network I/O off the main thread. The reactive API (`data`, `readyState`, `reconnect`, …) is identical — only the transport moves.
218-
219-
See [WORKERS.md](./WORKERS.md) for setup instructions, SharedWorker usage, and the full type reference.
220-
221215
## Built-in transformers
222216

223217
Ready-made `transform` functions for the most common SSE data formats. Pass one as the `transform` option to `createSSE`:
@@ -324,6 +318,106 @@ const { data } = createSSE<string>(url, {
324318
});
325319
```
326320

321+
## Running SSE in a Worker
322+
323+
`@solid-primitives/sse` ships a `makeSSEWorker` adapter that moves the `EventSource` connection into a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) or a [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker). The reactive API you get back from `createSSE` is identical — `data`, `readyState`, `reconnect`, etc. work exactly as documented above.
324+
325+
### When to use this
326+
327+
- **High-frequency streams** — parsing and dispatching many events per second on the main thread can cause jank. Moving the connection to a Worker keeps that work off the UI thread.
328+
- **SharedWorker** — if multiple tabs in the same origin connect to the same SSE endpoint, a SharedWorker lets them share a single Worker process (though each tab still gets its own `EventSource` connection inside the worker).
329+
330+
For typical usage — a handful of events per second — the standard `createSSE` is simpler and sufficient.
331+
332+
### Setup
333+
334+
The adapter is in a separate subpath so it adds zero bytes to the main bundle when not used.
335+
336+
```ts
337+
import { makeSSEWorker } from "@solid-primitives/sse/worker";
338+
```
339+
340+
You also need the companion handler script that runs inside the Worker:
341+
342+
```ts
343+
import "@solid-primitives/sse/worker-handler";
344+
```
345+
346+
Load it via your bundler's `new URL(…, import.meta.url)` syntax to get a correctly resolved URL at build time.
347+
348+
### Dedicated Worker
349+
350+
```ts
351+
import { createSSE } from "@solid-primitives/sse";
352+
import { makeSSEWorker } from "@solid-primitives/sse/worker";
353+
354+
const worker = new Worker(new URL("@solid-primitives/sse/worker-handler", import.meta.url), {
355+
type: "module",
356+
});
357+
358+
const { data, readyState, error, close, reconnect } = createSSE<{ msg: string }>(
359+
"https://api.example.com/events",
360+
{
361+
source: makeSSEWorker(worker),
362+
transform: JSON.parse,
363+
reconnect: { retries: 3, delay: 2000 },
364+
},
365+
);
366+
```
367+
368+
That's the only change compared to a standard `createSSE` call — pass `source: makeSSEWorker(worker)` and everything else stays the same.
369+
370+
### SharedWorker
371+
372+
A SharedWorker is shared across all tabs on the same origin. Pass `sw.port` (a `MessagePort`) in place of the `Worker` instance:
373+
374+
```ts
375+
import { createSSE } from "@solid-primitives/sse";
376+
import { makeSSEWorker } from "@solid-primitives/sse/worker";
377+
378+
const sw = new SharedWorker(new URL("@solid-primitives/sse/worker-handler", import.meta.url), {
379+
type: "module",
380+
});
381+
sw.port.start(); // required to activate a MessagePort
382+
383+
const { data } = createSSE("https://api.example.com/events", {
384+
source: makeSSEWorker(sw.port),
385+
});
386+
```
387+
388+
`makeSSEWorker` accepts anything that satisfies `SSEWorkerTarget` — both `Worker` and `MessagePort` do.
389+
390+
### How it works
391+
392+
`makeSSEWorker(target)` returns an `SSESourceFn`, the same factory interface that `createSSE` uses internally. When `createSSE` opens a connection it calls this factory instead of the default `makeSSE`, which:
393+
394+
1. Creates a `WorkerEventSource` — an `EventTarget` that posts a `connect` message to the Worker and re-dispatches `open` / `message` / `error` events received back from it.
395+
2. The Worker script (`worker-handler`) receives the `connect` message, creates a real `EventSource` there, and posts events back via `postMessage`.
396+
3. `createSSE`'s reactive machinery — signals, reconnect timer, URL tracking, `onCleanup` — runs on the main thread as normal; it just talks to a `WorkerEventSource` instead of a real `EventSource`.
397+
398+
### Type reference
399+
400+
```ts
401+
// @solid-primitives/sse/worker
402+
403+
function makeSSEWorker(target: SSEWorkerTarget): SSESourceFn;
404+
405+
/** Accepted by makeSSEWorker — satisfied by both Worker and SharedWorker.port */
406+
type SSEWorkerTarget = {
407+
postMessage(data: SSEWorkerMessage): void;
408+
addEventListener(type: "message", listener: (e: MessageEvent<SSEWorkerMessage>) => void): void;
409+
removeEventListener(type: "message", listener: (e: MessageEvent<SSEWorkerMessage>) => void): void;
410+
};
411+
412+
/** Messages exchanged between the main thread and the Worker */
413+
type SSEWorkerMessage =
414+
| { type: "connect"; id: string; url: string; withCredentials?: boolean; events?: string[] }
415+
| { type: "disconnect"; id: string }
416+
| { type: "open"; id: string }
417+
| { type: "message"; id: string; data: string; eventType: string }
418+
| { type: "error"; id: string; readyState: SSEReadyStateValue };
419+
```
420+
327421
## Changelog
328422

329423
See [CHANGELOG.md](./CHANGELOG.md).

packages/sse/WORKERS.md

Lines changed: 0 additions & 99 deletions
This file was deleted.

0 commit comments

Comments
 (0)