@parlor/sync 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"","sourcesContent":["import type { Principal } from \"@parlor/core\";\n\nexport interface ServerChannel {\n readonly event: string;\n connect(connection: ChannelConnection): () => void;\n}\n\nexport interface ChannelConnection {\n readonly clientId: string | undefined;\n readonly scope: string;\n /** Who holds the stream; absent when the server resolves no identity. */\n readonly principal?: Principal | undefined;\n /** Aborts when the stream ends, including when its holder's credential is revoked. */\n readonly closed?: AbortSignal | undefined;\n send(data: string): void;\n}\n\nexport interface ClientChannel {\n readonly event: string;\n opened(): void;\n receive(data: string): void;\n closed(): void;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAiB,MAAM,UAAU,CAAC;AACjE,OAAO,EACL,gBAAgB,EAIhB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,OAAO,EAAiB,MAAM,UAAU,CAAC;AACjE,OAAO,EACL,gBAAgB,EAIhB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC","sourcesContent":["export { parseSseChunk, readSse, type SseFrame } from \"./sse.js\";\nexport {\n createSyncClient,\n type SyncClient,\n type SyncClientOptions,\n type SyncRequest,\n SyncRequestTimeout,\n SyncUnauthorized,\n} from \"./sync-client.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/client/sse.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,IAAI,IAAI,GAAG,MAAM,CAAC;IAClB,SAAS,CAAC;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACnC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACvD,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAgC,EAChC,OAAkC,EAClC,MAAoB,EACpB,OAAoB;IAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,OAAO,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,MAAM,KAAK,IAAI,MAAM;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/client/sse.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,IAAI,IAAI,GAAG,MAAM,CAAC;IAClB,SAAS,CAAC;QACR,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,MAAM;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC3B,IAAI,KAAK,GAAG,SAAS,CAAC;QACtB,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YACnC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;gBAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBACvD,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAgC,EAChC,OAAkC,EAClC,MAAoB,EACpB,OAAoB;IAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAChC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACzD,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,SAAS,CAAC;YACR,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,IAAI;gBAAE,MAAM;YAChB,OAAO,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,MAAM,KAAK,IAAI,MAAM;gBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC","sourcesContent":["export interface SseFrame {\n readonly event: string;\n readonly data: string;\n}\n\nexport function parseSseChunk(buffer: string): { frames: SseFrame[]; rest: string } {\n const frames: SseFrame[] = [];\n let rest = buffer;\n for (;;) {\n const end = rest.indexOf(\"\\n\\n\");\n if (end === -1) break;\n const block = rest.slice(0, end);\n rest = rest.slice(end + 2);\n let event = \"message\";\n const data: string[] = [];\n for (const line of block.split(\"\\n\")) {\n if (line.startsWith(\":\")) continue;\n if (line.startsWith(\"event:\")) event = line.slice(6).trim();\n else if (line.startsWith(\"data:\")) data.push(line.slice(5).trimStart());\n }\n if (data.length > 0) frames.push({ event, data: data.join(\"\\n\") });\n }\n return { frames, rest };\n}\n\nexport async function readSse(\n body: ReadableStream<Uint8Array>,\n onFrame: (frame: SseFrame) => void,\n signal?: AbortSignal,\n onChunk?: () => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n const abort = () => void reader.cancel().catch(() => {});\n signal?.addEventListener(\"abort\", abort, { once: true });\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n onChunk?.();\n buffer += decoder.decode(value, { stream: true });\n const { frames, rest } = parseSseChunk(buffer);\n buffer = rest;\n for (const frame of frames) onFrame(frame);\n }\n } finally {\n signal?.removeEventListener(\"abort\", abort);\n }\n}\n"]}
@@ -21,6 +21,19 @@ export interface SyncClientOptions {
21
21
  * negotiated one, so a caller can only slow polling down.
22
22
  */
23
23
  readonly pollEveryMs?: (() => number) | undefined;
24
+ /**
25
+ * Where to read from while the client has no cursor of its own: the encoded cursor of the
26
+ * oldest data the page holds, so the first stream does not replay what that data already
27
+ * shows. Defaults to the start of the retained log.
28
+ */
29
+ readonly startAt?: (() => string) | undefined;
30
+ /**
31
+ * The server could not replay every event since the client's cursor: the client fell
32
+ * more than one batch behind, or behind what the server keeps. Sync continues from
33
+ * `cursor`, where the client's streams stand now; reread whatever predates it. Without
34
+ * it, the client is never reset and a poll pages through the backlog.
35
+ */
36
+ readonly onReset?: ((cursor: string) => void) | undefined;
24
37
  /** Bounds a negotiation or a poll, not the SSE stream. Defaults to 10 s. */
25
38
  readonly requestTimeoutMs?: number | undefined;
26
39
  /**
@@ -36,7 +49,8 @@ export interface SyncClientOptions {
36
49
  readonly onResume?: (() => void) | undefined;
37
50
  /**
38
51
  * The server refused the credential (401 or 403). The client never degrades to polling
39
- * on it; it keeps retrying the negotiation with backoff. Defaults to `onError`.
52
+ * on it; it keeps retrying the negotiation with backoff, unless this calls `stop`.
53
+ * Defaults to `onError`.
40
54
  */
41
55
  readonly onUnauthorized?: ((error: SyncUnauthorized) => void) | undefined;
42
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-client.d.ts","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"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"}
@@ -133,10 +133,22 @@ export function createSyncClient(options) {
133
133
  }, settings.coalesceMs);
134
134
  }
135
135
  };
136
- const since = () => (cursor === INITIAL_CURSOR ? "" : encodeCursor(cursor));
136
+ const held = () => (cursor === INITIAL_CURSOR ? "" : encodeCursor(cursor));
137
+ const since = () => cursor === INITIAL_CURSOR ? (options.startAt?.() ?? "") : encodeCursor(cursor);
138
+ const missedSince = () => `since=${encodeURIComponent(since())}${options.onReset ? "&reset=1" : ""}`;
139
+ const take = (batch) => {
140
+ if (!batch.reset) {
141
+ accept(batch.events);
142
+ return;
143
+ }
144
+ cursor = decodeCursor(batch.cursor);
145
+ guarded(() => options.onReset?.(batch.cursor));
146
+ };
137
147
  const poll = async (mine) => {
138
148
  const batch = await withTimeout(async (signal) => {
139
- const response = await options.request(`${basePath}/sync?since=${encodeURIComponent(since())}`, { signal });
149
+ const response = await options.request(`${basePath}/sync?${missedSince()}`, {
150
+ signal,
151
+ });
140
152
  if (refused(response))
141
153
  throw new SyncUnauthorized(response.status);
142
154
  if (!response.ok)
@@ -145,7 +157,7 @@ export function createSyncClient(options) {
145
157
  });
146
158
  if (mine !== epoch)
147
159
  throw new StaleRequest();
148
- accept(batch.events);
160
+ take(batch);
149
161
  if (running && negotiated === "poll")
150
162
  resumed();
151
163
  };
@@ -226,7 +238,7 @@ export function createSyncClient(options) {
226
238
  live = current;
227
239
  rearm();
228
240
  try {
229
- const response = await options.request(`${endpoint}?since=${encodeURIComponent(since())}`, {
241
+ const response = await options.request(`${endpoint}?${missedSince()}`, {
230
242
  headers: { accept: "text/event-stream" },
231
243
  signal: own.signal,
232
244
  });
@@ -240,7 +252,7 @@ export function createSyncClient(options) {
240
252
  await readSse(response.body, (frame) => {
241
253
  if (frame.event === "message") {
242
254
  const batch = JSON.parse(frame.data);
243
- accept(batch.events);
255
+ take(batch);
244
256
  const parsed = decodeCursor(batch.cursor);
245
257
  if (compareCursors(parsed, cursor) > 0)
246
258
  cursor = parsed;
@@ -437,7 +449,7 @@ export function createSyncClient(options) {
437
449
  },
438
450
  reconnectNow,
439
451
  get cursor() {
440
- return since();
452
+ return held();
441
453
  },
442
454
  get transport() {
443
455
  return transport;
@@ -1 +1 @@
1
- {"version":3,"file":"sync-client.js","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-client.js","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ClientChannel } from \"../channel.js\";\nimport {\n compareCursors,\n cursorOf,\n decodeCursor,\n encodeCursor,\n INITIAL_CURSOR,\n LEGACY_KEEP_ALIVE_MS,\n type SyncBatch,\n type SyncCursor,\n type SyncEvent,\n type SyncNegotiation,\n streamLivenessMs,\n} from \"../protocol.js\";\nimport { readSse } from \"./sse.js\";\n\nexport type SyncRequest = (path: string, init?: RequestInit) => Promise<Response>;\n\nexport interface SyncClientOptions {\n readonly request: SyncRequest;\n readonly basePath?: string | undefined;\n readonly clientId?: string | undefined;\n readonly onEvents: (events: SyncEvent[]) => void;\n readonly onError?: ((error: unknown) => void) | undefined;\n readonly coalesceMs?: number | undefined;\n readonly safetyPollMs?: number | undefined;\n readonly hiddenPollMs?: number | undefined;\n readonly reconnectBaseMs?: number | undefined;\n readonly reconnectMaxMs?: number | undefined;\n readonly isHidden?: (() => boolean) | undefined;\n readonly setTimeout?: typeof globalThis.setTimeout | undefined;\n readonly clearTimeout?: typeof globalThis.clearTimeout | undefined;\n readonly channels?: readonly ClientChannel[] | undefined;\n /**\n * Read each time the next poll is scheduled; the interval is the larger of this and the\n * negotiated one, so a caller can only slow polling down.\n */\n readonly pollEveryMs?: (() => number) | undefined;\n /**\n * Where to read from while the client has no cursor of its own: the encoded cursor of the\n * oldest data the page holds, so the first stream does not replay what that data already\n * shows. Defaults to the start of the retained log.\n */\n readonly startAt?: (() => string) | undefined;\n /**\n * The server could not replay every event since the client's cursor: the client fell\n * more than one batch behind, or behind what the server keeps. Sync continues from\n * `cursor`, where the client's streams stand now; reread whatever predates it. Without\n * it, the client is never reset and a poll pages through the backlog.\n */\n readonly onReset?: ((cursor: string) => void) | undefined;\n /** Bounds a negotiation or a poll, not the SSE stream. Defaults to 10 s. */\n readonly requestTimeoutMs?: number | undefined;\n /**\n * What the server negotiated, each time it does; `SyncClient.transport` reads `poll`\n * during the fallback poll of a failed negotiation, this never does.\n */\n readonly onNegotiated?: ((transport: \"sse\" | \"poll\") => void) | undefined;\n /**\n * The negotiated transport's connection came back after a failure: a stream reopened\n * after it dropped, or a poll succeeded after a failed one. A fallback poll on an SSE\n * deployment does not count.\n */\n readonly onResume?: (() => void) | undefined;\n /**\n * The server refused the credential (401 or 403). The client never degrades to polling\n * on it; it keeps retrying the negotiation with backoff, unless this calls `stop`.\n * Defaults to `onError`.\n */\n readonly onUnauthorized?: ((error: SyncUnauthorized) => void) | undefined;\n}\n\nexport class SyncUnauthorized extends Error {\n override readonly name = \"SyncUnauthorized\";\n constructor(readonly status: number) {\n super(`sync was refused with HTTP ${status}`);\n }\n}\n\nexport class SyncRequestTimeout extends Error {\n override readonly name = \"SyncRequestTimeout\";\n constructor(readonly ms: number) {\n super(`sync request timed out after ${ms} ms`);\n }\n}\n\nclass StaleRequest extends Error {\n override readonly name = \"StaleRequest\";\n}\n\nconst refused = (response: Response) =>\n response.status === 401 || response.status === 403;\n\nexport interface SyncClient {\n start(): void;\n stop(): void;\n /**\n * Registers a channel after `start`, for features loaded lazily. It opens at once when\n * the live stream's handshake lists it, else on the next stream. Returns the detach.\n */\n addChannel(channel: ClientChannel): () => void;\n /**\n * Skips the remaining reconnect backoff, for `online` and visibility events. While\n * polling it polls at once; with a stream open or a request in flight it does nothing.\n */\n reconnectNow(): void;\n readonly cursor: string;\n readonly transport: \"sse\" | \"poll\" | undefined;\n}\n\nconst DEFAULTS = {\n coalesceMs: 250,\n safetyPollMs: 60_000,\n hiddenPollMs: 10_000,\n reconnectBaseMs: 1000,\n reconnectMaxMs: 30_000,\n requestTimeoutMs: 10_000,\n};\n\ninterface Handshake {\n readonly capabilities: readonly string[];\n readonly keepAliveMs: number | undefined;\n}\n\nfunction parseHandshake(handshake: string): Handshake {\n try {\n const { capabilities, keepAliveMs } = JSON.parse(handshake) as {\n capabilities?: unknown;\n keepAliveMs?: unknown;\n };\n return {\n capabilities: Array.isArray(capabilities)\n ? capabilities.filter((c): c is string => typeof c === \"string\")\n : [],\n keepAliveMs:\n typeof keepAliveMs === \"number\" && keepAliveMs > 0 ? keepAliveMs : undefined,\n };\n } catch {\n return { capabilities: [], keepAliveMs: undefined };\n }\n}\n\nexport function createSyncClient(options: SyncClientOptions): SyncClient {\n const basePath = options.basePath ?? \"/_parlor\";\n const settings = {\n coalesceMs: options.coalesceMs ?? DEFAULTS.coalesceMs,\n safetyPollMs: options.safetyPollMs ?? DEFAULTS.safetyPollMs,\n hiddenPollMs: options.hiddenPollMs ?? DEFAULTS.hiddenPollMs,\n reconnectBaseMs: options.reconnectBaseMs ?? DEFAULTS.reconnectBaseMs,\n reconnectMaxMs: options.reconnectMaxMs ?? DEFAULTS.reconnectMaxMs,\n requestTimeoutMs: options.requestTimeoutMs ?? DEFAULTS.requestTimeoutMs,\n clientId: options.clientId,\n onError: options.onError,\n };\n const schedule: (fn: () => void, ms: number) => ReturnType<typeof setTimeout> =\n options.setTimeout ?? ((fn, ms) => globalThis.setTimeout(fn, ms));\n const cancel: (id: ReturnType<typeof setTimeout>) => void =\n options.clearTimeout ?? ((id) => globalThis.clearTimeout(id));\n const isHidden = options.isHidden ?? (() => false);\n const channels = new Map((options.channels ?? []).map((c) => [c.event, c]));\n const guarded = (run: () => void) => {\n try {\n run();\n } catch (error) {\n settings.onError?.(error);\n }\n };\n\n let cursor: SyncCursor = INITIAL_CURSOR;\n let transport: \"sse\" | \"poll\" | undefined;\n let negotiated: \"sse\" | \"poll\" | undefined;\n let interrupted = false;\n let running = false;\n let controller: AbortController | undefined;\n let pollTimer: ReturnType<typeof setTimeout> | undefined;\n let flushTimer: ReturnType<typeof setTimeout> | undefined;\n let pending: SyncEvent[] = [];\n let reconnectDelay = settings.reconnectBaseMs;\n let endReconnectWait: (() => void) | undefined;\n let connectTimer: ReturnType<typeof setTimeout> | undefined;\n let epoch = 0;\n const inflight = new Set<AbortController>();\n\n const withTimeout = async <T>(run: (signal: AbortSignal) => Promise<T>): Promise<T> => {\n const mine = epoch;\n const own = new AbortController();\n inflight.add(own);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const expired = new Promise<never>((_, reject) => {\n timer = schedule(() => {\n own.abort();\n reject(new SyncRequestTimeout(settings.requestTimeoutMs));\n }, settings.requestTimeoutMs);\n });\n try {\n const result = await Promise.race([run(own.signal), expired]);\n if (mine !== epoch) throw new StaleRequest();\n return result;\n } catch (error) {\n if (mine !== epoch) throw new StaleRequest();\n throw error;\n } finally {\n inflight.delete(own);\n if (timer !== undefined) cancel(timer);\n }\n };\n\n const resumed = () => {\n if (!interrupted) return;\n interrupted = false;\n guarded(() => options.onResume?.());\n };\n\n const accept = (events: readonly SyncEvent[]) => {\n for (const event of events) {\n const at = cursorOf(event);\n if (compareCursors(at, cursor) <= 0) continue;\n cursor = at;\n if (event.source && event.source === settings.clientId) continue;\n pending.push(event);\n }\n if (pending.length > 0 && flushTimer === undefined) {\n flushTimer = schedule(() => {\n flushTimer = undefined;\n const batch = pending;\n pending = [];\n options.onEvents(batch);\n }, settings.coalesceMs);\n }\n };\n\n const held = () => (cursor === INITIAL_CURSOR ? \"\" : encodeCursor(cursor));\n const since = () =>\n cursor === INITIAL_CURSOR ? (options.startAt?.() ?? \"\") : encodeCursor(cursor);\n const missedSince = () =>\n `since=${encodeURIComponent(since())}${options.onReset ? \"&reset=1\" : \"\"}`;\n\n const take = (batch: SyncBatch) => {\n if (!batch.reset) {\n accept(batch.events);\n return;\n }\n cursor = decodeCursor(batch.cursor);\n guarded(() => options.onReset?.(batch.cursor));\n };\n\n const poll = async (mine: number) => {\n const batch = await withTimeout(async (signal) => {\n const response = await options.request(`${basePath}/sync?${missedSince()}`, {\n signal,\n });\n if (refused(response)) throw new SyncUnauthorized(response.status);\n if (!response.ok) throw new Error(`sync poll failed with HTTP ${response.status}`);\n return (await response.json()) as SyncBatch;\n });\n if (mine !== epoch) throw new StaleRequest();\n take(batch);\n if (running && negotiated === \"poll\") resumed();\n };\n\n const schedulePoll = (ms: number) => {\n if (!running) return;\n if (pollTimer !== undefined) cancel(pollTimer);\n pollTimer = schedule(() => {\n pollTimer = undefined;\n let halted = false;\n const mine = epoch;\n void poll(mine)\n .catch((error: unknown) => {\n if (error instanceof StaleRequest || mine !== epoch) {\n halted = true;\n return;\n }\n if (negotiated === \"poll\") interrupted = true;\n if (error instanceof SyncUnauthorized) {\n halted = true;\n unauthorized(error);\n if (transport === \"poll\") {\n transport = undefined;\n connectTimer = schedule(() => {\n connectTimer = undefined;\n void connect();\n }, backoff());\n }\n return;\n }\n settings.onError?.(error);\n })\n .finally(() => {\n if (!halted) schedulePoll(nextPollDelay());\n });\n }, ms);\n };\n\n const nextPollDelay = () => {\n if (transport === \"sse\") return settings.safetyPollMs;\n const base = Math.max(negotiatedPollMs, options.pollEveryMs?.() ?? 0);\n return isHidden() ? Math.max(base, settings.hiddenPollMs) : base;\n };\n let negotiatedPollMs = 2000;\n\n const negotiate = async (): Promise<SyncNegotiation> => {\n return withTimeout(async (signal) => {\n const response = await options.request(`${basePath}/sync/token`, {\n method: \"POST\",\n signal,\n });\n if (refused(response)) throw new SyncUnauthorized(response.status);\n if (!response.ok)\n throw new Error(`sync negotiation failed with HTTP ${response.status}`);\n return (await response.json()) as SyncNegotiation;\n });\n };\n\n interface LiveStream {\n listed: ReadonlySet<string>;\n readonly open: Set<ClientChannel>;\n }\n let live: LiveStream | undefined;\n\n const stream = async (endpoint: string) => {\n const own = new AbortController();\n controller = own;\n let keepAliveMs = LEGACY_KEEP_ALIVE_MS;\n let silent = false;\n let watchdog: ReturnType<typeof setTimeout> | undefined;\n const rearm = () => {\n if (watchdog !== undefined) cancel(watchdog);\n watchdog = schedule(() => {\n silent = true;\n own.abort();\n }, streamLivenessMs(keepAliveMs));\n };\n const open = new Set<ClientChannel>();\n const current: LiveStream = { listed: new Set(), open };\n live = current;\n rearm();\n try {\n const response = await options.request(`${endpoint}?${missedSince()}`, {\n headers: { accept: \"text/event-stream\" },\n signal: own.signal,\n });\n if (refused(response)) throw new SyncUnauthorized(response.status);\n if (!response.ok || !response.body) {\n throw new Error(`sync stream failed with HTTP ${response.status}`);\n }\n reconnectDelay = settings.reconnectBaseMs;\n resumed();\n await readSse(\n response.body,\n (frame) => {\n if (frame.event === \"message\") {\n const batch = JSON.parse(frame.data) as SyncBatch;\n take(batch);\n const parsed = decodeCursor(batch.cursor);\n if (compareCursors(parsed, cursor) > 0) cursor = parsed;\n return;\n }\n if (frame.event === \"handshake\") {\n const handshake = parseHandshake(frame.data);\n keepAliveMs = handshake.keepAliveMs ?? LEGACY_KEEP_ALIVE_MS;\n rearm();\n current.listed = new Set(handshake.capabilities);\n for (const event of handshake.capabilities) {\n const channel = channels.get(event);\n if (!channel || open.has(channel)) continue;\n open.add(channel);\n guarded(() => channel.opened());\n }\n return;\n }\n const channel = channels.get(frame.event);\n if (channel && open.has(channel)) guarded(() => channel.receive(frame.data));\n },\n own.signal,\n rearm,\n );\n } catch (error) {\n if (!silent) throw error;\n } finally {\n if (watchdog !== undefined) cancel(watchdog);\n if (live === current) live = undefined;\n for (const channel of open) guarded(() => channel.closed());\n }\n };\n\n const unauthorized = (error: SyncUnauthorized) => {\n if (pollTimer !== undefined) cancel(pollTimer);\n pollTimer = undefined;\n (options.onUnauthorized ?? settings.onError)?.(error);\n };\n\n const backoff = () => {\n const delay = reconnectDelay;\n reconnectDelay = Math.min(reconnectDelay * 2, settings.reconnectMaxMs);\n return delay;\n };\n\n let connecting = false;\n const connect = async () => {\n if (connecting) return;\n connecting = true;\n const mine = epoch;\n try {\n await connectLoop(mine);\n } finally {\n if (mine === epoch) connecting = false;\n }\n };\n\n const connectLoop = async (mine: number) => {\n const active = () => running && mine === epoch;\n for (;;) {\n if (!active()) return;\n let endpoint: string | undefined;\n try {\n const negotiation = await negotiate();\n if (!active()) return;\n negotiatedPollMs = negotiation.pollIntervalMs;\n negotiated = negotiation.transport;\n guarded(() => options.onNegotiated?.(negotiation.transport));\n if (negotiation.transport === \"poll\") {\n transport = \"poll\";\n schedulePoll(0);\n return;\n }\n endpoint = negotiation.endpoint;\n } catch (error) {\n if (!active()) return;\n interrupted = true;\n if (error instanceof SyncUnauthorized) {\n transport = undefined;\n unauthorized(error);\n } else {\n settings.onError?.(error);\n if (transport !== \"poll\") {\n transport = \"poll\";\n schedulePoll(negotiatedPollMs);\n }\n }\n }\n if (endpoint !== undefined) {\n transport = \"sse\";\n schedulePoll(settings.safetyPollMs);\n try {\n await stream(endpoint);\n } catch (error) {\n if (!active()) return;\n if (error instanceof SyncUnauthorized) unauthorized(error);\n else settings.onError?.(error);\n }\n interrupted = true;\n }\n if (!active()) return;\n const delay = backoff();\n await new Promise<void>((resolve) => {\n const timer = schedule(() => {\n endReconnectWait = undefined;\n resolve();\n }, delay);\n endReconnectWait = () => {\n cancel(timer);\n endReconnectWait = undefined;\n resolve();\n };\n });\n }\n };\n\n const detachChannel = (channel: ClientChannel) => {\n if (channels.get(channel.event) !== channel) return;\n channels.delete(channel.event);\n if (live?.open.delete(channel)) guarded(() => channel.closed());\n };\n\n const start = () => {\n if (running) return;\n running = true;\n void connect();\n };\n\n const reconnectNow = () => {\n if (!running) return;\n if (endReconnectWait) {\n reconnectDelay = settings.reconnectBaseMs;\n endReconnectWait();\n } else if (connectTimer !== undefined) {\n cancel(connectTimer);\n connectTimer = undefined;\n reconnectDelay = settings.reconnectBaseMs;\n void connect();\n }\n if (transport === \"poll\" && pollTimer !== undefined) schedulePoll(0);\n };\n\n const stop = () => {\n running = false;\n epoch += 1;\n for (const request of inflight) request.abort();\n inflight.clear();\n controller?.abort();\n controller = undefined;\n connecting = false;\n endReconnectWait?.();\n if (pollTimer !== undefined) cancel(pollTimer);\n if (flushTimer !== undefined) cancel(flushTimer);\n if (connectTimer !== undefined) cancel(connectTimer);\n pollTimer = flushTimer = connectTimer = undefined;\n pending = [];\n };\n\n return {\n start,\n stop,\n addChannel(channel) {\n const replaced = channels.get(channel.event);\n if (replaced === channel) return () => detachChannel(channel);\n if (replaced) detachChannel(replaced);\n channels.set(channel.event, channel);\n if (live?.listed.has(channel.event)) {\n live.open.add(channel);\n guarded(() => channel.opened());\n }\n return () => detachChannel(channel);\n },\n reconnectNow,\n get cursor() {\n return held();\n },\n get transport() {\n return transport;\n },\n };\n}\n"]}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,qBAAqB,GAKtB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,qBAAqB,GAKtB,MAAM,eAAe,CAAC","sourcesContent":["export type { ChannelConnection, ClientChannel, ServerChannel } from \"./channel.js\";\nexport {\n compareCursors,\n cursorOf,\n decodeCursor,\n encodeCursor,\n INITIAL_CURSOR,\n SYNC_CHANNEL,\n SYNC_PROTOCOL_VERSION,\n type SyncBatch,\n type SyncCursor,\n type SyncEvent,\n type SyncNegotiation,\n} from \"./protocol.js\";\n"]}
@@ -22,6 +22,13 @@ export declare function cursorOf(event: SyncEvent): SyncCursor;
22
22
  export interface SyncBatch {
23
23
  readonly events: readonly SyncEvent[];
24
24
  readonly cursor: string;
25
+ /**
26
+ * The server cannot replay every event after the cursor the client sent: there are more
27
+ * than one batch of them, or pruning may have removed some. `events` is empty and
28
+ * `cursor` is where the client's streams stand now, so anything derived from events
29
+ * before it may be stale. Sent only to a client that asks with `reset=1`.
30
+ */
31
+ readonly reset?: true | undefined;
25
32
  }
26
33
  export interface SyncNegotiation {
27
34
  readonly protocol: typeof SYNC_PROTOCOL_VERSION;
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,YAAY,gBAAgB,CAAC;AAC1C,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAI3C,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,UAAmC,CAAC;AAEjE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAEvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAMvD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAGnE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAErD;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,qBAAqB,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,eAAO,MAAM,qBAAqB,IAAI,CAAC;AACvC,eAAO,MAAM,YAAY,gBAAgB,CAAC;AAC1C,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAI3C,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,cAAc,EAAE,UAAmC,CAAC;AAEjE,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAEvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAMvD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAGnE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAErD;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,OAAO,qBAAqB,CAAC;IAChD,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO,WAAW,GAAG,CAAC,GAAG,yBAAyB,CAAC;AACrD,CAAC;AAcD,MAAM,CAAC,MAAM,cAAc,GAAe,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAEjE,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,cAAc,CAAC;IACrE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC;IACzE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAa,EAAE,CAAa;IACzD,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IAC1D,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAgB;IACvC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;AAClD,CAAC"}
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AACvC,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAC;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAE3C,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAEvC,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,OAAO,WAAW,GAAG,CAAC,GAAG,yBAAyB,CAAC;AACrD,CAAC;AAcD,MAAM,CAAC,MAAM,cAAc,GAAe,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAEjE,MAAM,UAAU,YAAY,CAAC,MAAkB;IAC7C,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,cAAc,CAAC;IACrE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,cAAc,CAAC;IACzE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAa,EAAE,CAAa;IACzD,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IAC1D,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAgB;IACvC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;AAClD,CAAC","sourcesContent":["import type { Tag } from \"@parlor/core\";\n\nexport const SYNC_PROTOCOL_VERSION = 1;\nexport const SYNC_CHANNEL = \"parlor_sync\";\nexport const DEFAULT_KEEP_ALIVE_MS = 10_000;\nexport const LEGACY_KEEP_ALIVE_MS = 25_000;\n\nconst STREAM_LIVENESS_MARGIN_MS = 5000;\n\nexport function streamLivenessMs(keepAliveMs: number): number {\n return keepAliveMs * 2 + STREAM_LIVENESS_MARGIN_MS;\n}\n\nexport interface SyncEvent {\n readonly version: number;\n readonly id: string;\n readonly tags: readonly Tag[];\n readonly source?: string | undefined;\n}\n\nexport interface SyncCursor {\n readonly version: number;\n readonly id: string;\n}\n\nexport const INITIAL_CURSOR: SyncCursor = { version: 0, id: \"\" };\n\nexport function encodeCursor(cursor: SyncCursor): string {\n return `${cursor.version}.${cursor.id}`;\n}\n\nexport function decodeCursor(value: unknown): SyncCursor {\n if (typeof value !== \"string\" || value === \"\") return INITIAL_CURSOR;\n const separator = value.indexOf(\".\");\n const version = Number(separator === -1 ? value : value.slice(0, separator));\n if (!Number.isSafeInteger(version) || version < 0) return INITIAL_CURSOR;\n return { version, id: separator === -1 ? \"\" : value.slice(separator + 1) };\n}\n\nexport function compareCursors(a: SyncCursor, b: SyncCursor): number {\n if (a.version !== b.version) return a.version - b.version;\n return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;\n}\n\nexport function cursorOf(event: SyncEvent): SyncCursor {\n return { version: event.version, id: event.id };\n}\n\nexport interface SyncBatch {\n readonly events: readonly SyncEvent[];\n readonly cursor: string;\n /**\n * The server cannot replay every event after the cursor the client sent: there are more\n * than one batch of them, or pruning may have removed some. `events` is empty and\n * `cursor` is where the client's streams stand now, so anything derived from events\n * before it may be stale. Sent only to a client that asks with `reset=1`.\n */\n readonly reset?: true | undefined;\n}\n\nexport interface SyncNegotiation {\n readonly protocol: typeof SYNC_PROTOCOL_VERSION;\n readonly transport: \"sse\" | \"poll\";\n readonly endpoint: string;\n readonly pollIntervalMs: number;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/server/hub.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/server/hub.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DataProvider, Unlisten } from \"@parlor/core\";\n\nimport { SYNC_CHANNEL, type SyncEvent } from \"../protocol.js\";\nimport { parseNotifyPayload } from \"./store.js\";\n\nexport type SyncSubscriber = (event: SyncEvent) => void;\n\ninterface Subscription {\n readonly notify: SyncSubscriber;\n readonly onStop: (() => void) | undefined;\n}\n\nexport class SyncHub {\n readonly #subscribers = new Map<string, Set<Subscription>>();\n #unlisten: Unlisten | undefined;\n #starting: Promise<void> | undefined;\n\n constructor(private readonly data: DataProvider) {}\n\n get canPush(): boolean {\n return typeof this.data.listen === \"function\";\n }\n\n async start(): Promise<void> {\n if (!this.data.listen || this.#unlisten) return;\n const starting = (this.#starting ??= this.data\n .listen(\n SYNC_CHANNEL,\n (payload) => {\n const parsed = parseNotifyPayload(payload);\n if (parsed) this.publish(parsed.scope, parsed.event);\n },\n { onLost: () => this.#reconnectEveryStream() },\n )\n .then(\n (unlisten) => {\n if (this.#starting === starting) this.#unlisten = unlisten;\n else void unlisten();\n },\n (error: unknown) => {\n if (this.#starting === starting) this.#starting = undefined;\n throw error;\n },\n ));\n await starting;\n }\n\n #reconnectEveryStream(): void {\n this.#unlisten = undefined;\n this.#starting = undefined;\n const subscriptions = [...this.#subscribers.values()].flatMap((set) => [...set]);\n for (const { onStop } of subscriptions) onStop?.();\n }\n\n publish(scope: string, event: SyncEvent): void {\n for (const { notify } of this.#subscribers.get(scope) ?? []) notify(event);\n }\n\n subscribe(scope: string, notify: SyncSubscriber, onStop?: () => void): () => void {\n const subscription: Subscription = { notify, onStop };\n const set = this.#subscribers.get(scope) ?? new Set();\n set.add(subscription);\n this.#subscribers.set(scope, set);\n return () => {\n set.delete(subscription);\n if (set.size === 0) this.#subscribers.delete(scope);\n };\n }\n\n subscriberCount(scope?: string): number {\n if (scope) return this.#subscribers.get(scope)?.size ?? 0;\n let total = 0;\n for (const set of this.#subscribers.values()) total += set.size;\n return total;\n }\n\n async stop(): Promise<void> {\n const subscriptions = [...this.#subscribers.values()].flatMap((set) => [...set]);\n for (const { onStop } of subscriptions) onStop?.();\n await this.#unlisten?.();\n this.#unlisten = undefined;\n this.#starting = undefined;\n this.#subscribers.clear();\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  export { SyncHub, type SyncSubscriber } from "./hub.js";
2
2
  export { createPruner, DEFAULT_PRUNE_INTERVAL_MS, type Pruner } from "./pruner.js";
3
3
  export { DEFAULT_POLL_INTERVAL_MS, registerSyncRoutes, type StreamAuthority, type SyncRouteOptions, type SyncTransport, transportFromEnv, } from "./routes.js";
4
- export { ensureSyncTables, type NotifyPayload, parseNotifyPayload, PRUNE_LOCK_KEY, pruneSyncEvents, readSyncEvents, recordSyncEvent, type RecordSyncEventInput, RETENTION_MS, type SyncDatabase, } from "./store.js";
4
+ export { ensureSyncTables, type NotifyPayload, parseNotifyPayload, PRUNE_LOCK_KEY, pruneSyncEvents, readSyncCursor, readSyncEvents, recordSyncEvent, type RecordSyncEventInput, RETENTION_MS, type SyncDatabase, } from "./store.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,KAAK,aAAa,EAClB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,KAAK,oBAAoB,EACzB,YAAY,EACZ,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,KAAK,aAAa,EAClB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,eAAe,EACf,KAAK,oBAAoB,EACzB,YAAY,EACZ,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC"}
@@ -1,5 +1,5 @@
1
1
  export { SyncHub } from "./hub.js";
2
2
  export { createPruner, DEFAULT_PRUNE_INTERVAL_MS } from "./pruner.js";
3
3
  export { DEFAULT_POLL_INTERVAL_MS, registerSyncRoutes, transportFromEnv, } from "./routes.js";
4
- export { ensureSyncTables, parseNotifyPayload, PRUNE_LOCK_KEY, pruneSyncEvents, readSyncEvents, recordSyncEvent, RETENTION_MS, } from "./store.js";
4
+ export { ensureSyncTables, parseNotifyPayload, PRUNE_LOCK_KEY, pruneSyncEvents, readSyncCursor, readSyncEvents, recordSyncEvent, RETENTION_MS, } from "./store.js";
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAe,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAIlB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAEhB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EAEf,YAAY,GAEb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAe,MAAM,aAAa,CAAC;AACnF,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAIlB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAEhB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,eAAe,EAEf,YAAY,GAEb,MAAM,YAAY,CAAC","sourcesContent":["export { SyncHub, type SyncSubscriber } from \"./hub.js\";\nexport { createPruner, DEFAULT_PRUNE_INTERVAL_MS, type Pruner } from \"./pruner.js\";\nexport {\n DEFAULT_POLL_INTERVAL_MS,\n registerSyncRoutes,\n type StreamAuthority,\n type SyncRouteOptions,\n type SyncTransport,\n transportFromEnv,\n} from \"./routes.js\";\nexport {\n ensureSyncTables,\n type NotifyPayload,\n parseNotifyPayload,\n PRUNE_LOCK_KEY,\n pruneSyncEvents,\n readSyncCursor,\n readSyncEvents,\n recordSyncEvent,\n type RecordSyncEventInput,\n RETENTION_MS,\n type SyncDatabase,\n} from \"./store.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"pruner.js","sourceRoot":"","sources":["../../src/server/pruner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAC;AAEhE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAMvD,MAAM,UAAU,YAAY,CAC1B,IAAkB,EAClB,OAAO,GAIH,EAAE;IAEN,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,yBAAyB,CAAC;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC,CAAC;IACtF,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,OAAO;QACL,KAAK;YACH,IAAI,OAAO,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,UAAU;gBAAE,OAAO;YACjD,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,KAAK,eAAe,CAAC,IAAI,CAAC,IAAI,EAAkB,CAAC;iBAC9C,KAAK,CAAC,OAAO,CAAC;iBACd,OAAO,CAAC,GAAG,EAAE;gBACZ,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"pruner.js","sourceRoot":"","sources":["../../src/server/pruner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAC;AAEhE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAMvD,MAAM,UAAU,YAAY,CAC1B,IAAkB,EAClB,OAAO,GAIH,EAAE;IAEN,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,yBAAyB,CAAC;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,OAAO,GACX,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC,CAAC;IACtF,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC;IACjB,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,OAAO;QACL,KAAK;YACH,IAAI,OAAO,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,UAAU;gBAAE,OAAO;YACjD,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,GAAG,GAAG,EAAE,CAAC;YACb,KAAK,eAAe,CAAC,IAAI,CAAC,IAAI,EAAkB,CAAC;iBAC9C,KAAK,CAAC,OAAO,CAAC;iBACd,OAAO,CAAC,GAAG,EAAE;gBACZ,OAAO,GAAG,KAAK,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import type { DataProvider } from \"@parlor/core\";\n\nimport { pruneSyncEvents, type SyncDatabase } from \"./store.js\";\n\nexport const DEFAULT_PRUNE_INTERVAL_MS = 5 * 60 * 1000;\n\nexport interface Pruner {\n touch(): void;\n}\n\nexport function createPruner(\n data: DataProvider,\n options: {\n intervalMs?: number | undefined;\n now?: () => number;\n onError?: (error: unknown) => void;\n } = {},\n): Pruner {\n const intervalMs = options.intervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;\n const now = options.now ?? Date.now;\n const onError =\n options.onError ?? ((error) => console.error(\"[parlor] sync prune failed:\", error));\n let last = now();\n let running = false;\n return {\n touch() {\n if (running || now() - last < intervalMs) return;\n running = true;\n last = now();\n void pruneSyncEvents(data.read() as SyncDatabase)\n .catch(onError)\n .finally(() => {\n running = false;\n });\n },\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAA+B,KAAK,EAAE,EAAgB,MAAM,IAAI,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAYnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IAC3E;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS,CAAC;CACnF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,wBAAgB,gBAAgB,CAC9B,KAAK,GAAE,MAAM,GAAG,SAA6C,GAC5D,aAAa,GAAG,SAAS,CAE3B;AAOD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAsH3E"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAA+B,KAAK,EAAE,EAAgB,MAAM,IAAI,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAYnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,aAAa,EAAE,GAAG,SAAS,CAAC;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;IAC3E;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS,CAAC;CACnF;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,wBAAgB,gBAAgB,CAC9B,KAAK,GAAE,MAAM,GAAG,SAA6C,GAC5D,aAAa,GAAG,SAAS,CAE3B;AAwBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CA8G3E"}
@@ -1,6 +1,6 @@
1
1
  import { createEventStream, getQuery } from "h3";
2
2
  import { compareCursors, cursorOf, decodeCursor, DEFAULT_KEEP_ALIVE_MS, encodeCursor, SYNC_PROTOCOL_VERSION, } from "../protocol.js";
3
- import { readSyncEvents } from "./store.js";
3
+ import { readSyncBacklog, readSyncEvents } from "./store.js";
4
4
  export const DEFAULT_POLL_INTERVAL_MS = 2000;
5
5
  export function transportFromEnv(value = process.env.PARLOR_SYNC_TRANSPORT) {
6
6
  return value === "sse" || value === "poll" ? value : undefined;
@@ -9,6 +9,18 @@ function batch(events, since) {
9
9
  const last = events.at(-1);
10
10
  return { events, cursor: last ? encodeCursor(cursorOf(last)) : since };
11
11
  }
12
+ async function missedSince(db, streams, event) {
13
+ const query = getQuery(event);
14
+ const since = String(query.since ?? "");
15
+ if (query.reset !== "1") {
16
+ return batch(await readSyncEvents(db, streams, decodeCursor(since)), since);
17
+ }
18
+ const backlog = await readSyncBacklog(db, streams, decodeCursor(since));
19
+ if (backlog.resetTo) {
20
+ return { events: [], cursor: encodeCursor(backlog.resetTo), reset: true };
21
+ }
22
+ return batch(backlog.events, since);
23
+ }
12
24
  export function registerSyncRoutes(app, options) {
13
25
  const { basePath, data, hub, scope } = options;
14
26
  const streamsOf = async (request) => {
@@ -29,16 +41,14 @@ export function registerSyncRoutes(app, options) {
29
41
  pollIntervalMs,
30
42
  }));
31
43
  app.get(`${basePath}/sync`, async (event) => {
32
- const since = String(getQuery(event).since ?? "");
33
- const events = await readSyncEvents(db(), await streamsOf(event.req), decodeCursor(since));
44
+ const missed = await missedSince(db(), await streamsOf(event.req), event);
34
45
  event.res.headers.set("cache-control", "no-store");
35
- return batch(events, since);
46
+ return missed;
36
47
  });
37
48
  app.get(`${basePath}/sync/stream`, async (event) => {
38
49
  const streams = await streamsOf(event.req);
39
50
  const currentScope = streams[0];
40
51
  const authority = await options.authority?.(event.req);
41
- const sinceParam = String(getQuery(event).since ?? "");
42
52
  await hub.start();
43
53
  const stream = createEventStream(event);
44
54
  const send = (payload) => void stream.push(JSON.stringify(payload));
@@ -94,15 +104,13 @@ export function registerSyncRoutes(app, options) {
94
104
  },
95
105
  }));
96
106
  }
97
- const since = decodeCursor(sinceParam);
98
- const missed = await readSyncEvents(db(), streams, since).catch((error) => {
107
+ const missed = await missedSince(db(), streams, event).catch((error) => {
99
108
  detach();
100
109
  throw error;
101
110
  });
102
- if (missed.length > 0)
103
- send(batch(missed, sinceParam));
104
- const last = missed.at(-1);
105
- const caughtUpTo = last ? cursorOf(last) : since;
111
+ if (missed.events.length > 0 || missed.reset)
112
+ send(missed);
113
+ const caughtUpTo = decodeCursor(missed.cursor);
106
114
  const pending = arrivedDuringCatchUp
107
115
  .filter((syncEvent) => compareCursors(cursorOf(syncEvent), caughtUpTo) > 0)
108
116
  .sort((a, b) => compareCursors(cursorOf(a), cursorOf(b)));
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DataProvider, Principal } from \"@parlor/core\";\nimport { createEventStream, getQuery, type H3, type H3Event } from \"h3\";\n\nimport type { ServerChannel } from \"../channel.js\";\nimport {\n compareCursors,\n cursorOf,\n decodeCursor,\n DEFAULT_KEEP_ALIVE_MS,\n encodeCursor,\n type SyncBatch,\n type SyncEvent,\n type SyncNegotiation,\n SYNC_PROTOCOL_VERSION,\n} from \"../protocol.js\";\nimport type { SyncHub } from \"./hub.js\";\nimport { readSyncBacklog, readSyncEvents, type SyncDatabase } from \"./store.js\";\n\nexport type SyncTransport = \"sse\" | \"poll\";\n\nexport interface SyncRouteOptions {\n readonly basePath: string;\n readonly data: DataProvider;\n readonly hub: SyncHub;\n readonly scope: (request: Request) => string | Promise<string>;\n /**\n * The caller's own stream inside its scope, for events only its user should hear (an\n * action with `notifies: \"user\"`); read and pushed alongside the scope's.\n */\n readonly audience?: ((request: Request) => string | Promise<string>) | undefined;\n readonly transport?: SyncTransport | undefined;\n readonly pollIntervalMs?: number | undefined;\n readonly keepAliveMs?: number | undefined;\n readonly channels?: readonly ServerChannel[] | undefined;\n readonly clientId?: ((request: Request) => string | undefined) | undefined;\n /**\n * Who holds a stream and until when. A stream closes when `revoked` aborts, and a\n * stream without `channels` carries sync events only. Refusing a caller happens before\n * these routes run.\n */\n readonly authority?: ((request: Request) => Promise<StreamAuthority>) | undefined;\n}\n\nexport interface StreamAuthority {\n readonly principal: Principal;\n readonly revoked?: AbortSignal | undefined;\n readonly channels: boolean;\n}\n\nexport const DEFAULT_POLL_INTERVAL_MS = 2000;\n\nexport function transportFromEnv(\n value: string | undefined = process.env.PARLOR_SYNC_TRANSPORT,\n): SyncTransport | undefined {\n return value === \"sse\" || value === \"poll\" ? value : undefined;\n}\n\nfunction batch(events: SyncEvent[], since: string): SyncBatch {\n const last = events.at(-1);\n return { events, cursor: last ? encodeCursor(cursorOf(last)) : since };\n}\n\nasync function missedSince(\n db: SyncDatabase,\n streams: readonly string[],\n event: H3Event,\n): Promise<SyncBatch> {\n const query = getQuery(event);\n const since = String(query.since ?? \"\");\n if (query.reset !== \"1\") {\n return batch(await readSyncEvents(db, streams, decodeCursor(since)), since);\n }\n const backlog = await readSyncBacklog(db, streams, decodeCursor(since));\n if (backlog.resetTo) {\n return { events: [], cursor: encodeCursor(backlog.resetTo), reset: true };\n }\n return batch(backlog.events, since);\n}\n\nexport function registerSyncRoutes(app: H3, options: SyncRouteOptions): void {\n const { basePath, data, hub, scope } = options;\n const streamsOf = async (request: Request): Promise<readonly string[]> => {\n const own = await scope(request);\n const audience = await options.audience?.(request);\n return audience === undefined || audience === own ? [own] : [own, audience];\n };\n const transport: SyncTransport =\n options.transport ?? transportFromEnv() ?? (hub.canPush ? \"sse\" : \"poll\");\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;\n const keepAliveMs = options.keepAliveMs ?? DEFAULT_KEEP_ALIVE_MS;\n const db = () => data.read() as SyncDatabase;\n const channels = options.channels ?? [];\n const capabilities = channels.map((channel) => channel.event);\n\n app.post(`${basePath}/sync/token`, (): SyncNegotiation => ({\n protocol: SYNC_PROTOCOL_VERSION,\n transport,\n endpoint: `${basePath}/sync/stream`,\n pollIntervalMs,\n }));\n\n app.get(`${basePath}/sync`, async (event: H3Event) => {\n const missed = await missedSince(db(), await streamsOf(event.req), event);\n event.res.headers.set(\"cache-control\", \"no-store\");\n return missed;\n });\n\n app.get(`${basePath}/sync/stream`, async (event: H3Event) => {\n const streams = await streamsOf(event.req);\n const currentScope = streams[0]!;\n const authority = await options.authority?.(event.req);\n await hub.start();\n const stream = createEventStream(event);\n const send = (payload: SyncBatch) => void stream.push(JSON.stringify(payload));\n const sendLive = (syncEvent: SyncEvent) =>\n send({ events: [syncEvent], cursor: encodeCursor(cursorOf(syncEvent)) });\n\n let arrivedDuringCatchUp: SyncEvent[] | undefined = [];\n const unsubscribes = streams.map((name) =>\n hub.subscribe(\n name,\n (syncEvent) => {\n if (arrivedDuringCatchUp) arrivedDuringCatchUp.push(syncEvent);\n else sendLive(syncEvent);\n },\n () => void stream.close(),\n ),\n );\n const keepAlive = setInterval(\n () => void stream.pushComment(\"keep-alive\"),\n keepAliveMs,\n );\n const disconnects: (() => void)[] = [];\n const ended = new AbortController();\n let detached = false;\n const revoked = authority?.revoked;\n const closeRevoked = () => void stream.close();\n const detach = () => {\n if (detached) return;\n detached = true;\n ended.abort();\n clearInterval(keepAlive);\n revoked?.removeEventListener(\"abort\", closeRevoked);\n for (const unsubscribe of unsubscribes) unsubscribe();\n for (const disconnect of disconnects) disconnect();\n };\n stream.onClosed(detach);\n if (revoked?.aborted) closeRevoked();\n else revoked?.addEventListener(\"abort\", closeRevoked, { once: true });\n\n void stream.push({\n event: \"handshake\",\n data: JSON.stringify({\n protocol: SYNC_PROTOCOL_VERSION,\n capabilities: authority?.channels === false ? [] : capabilities,\n keepAliveMs,\n }),\n });\n const clientId = options.clientId?.(event.req);\n for (const channel of authority?.channels === false ? [] : channels) {\n disconnects.push(\n channel.connect({\n clientId,\n scope: currentScope,\n ...(authority ? { principal: authority.principal } : {}),\n closed: ended.signal,\n send: (frame) => {\n if (!detached) void stream.push({ event: channel.event, data: frame });\n },\n }),\n );\n }\n const missed = await missedSince(db(), streams, event).catch((error: unknown) => {\n detach();\n throw error;\n });\n if (missed.events.length > 0 || missed.reset) send(missed);\n const caughtUpTo = decodeCursor(missed.cursor);\n const pending = arrivedDuringCatchUp\n .filter((syncEvent) => compareCursors(cursorOf(syncEvent), caughtUpTo) > 0)\n .sort((a, b) => compareCursors(cursorOf(a), cursorOf(b)));\n arrivedDuringCatchUp = undefined;\n for (const syncEvent of pending) sendLive(syncEvent);\n const body = await stream.send();\n if (event.req.headers.get(\"connection\") === \"keep-alive\") {\n event.res.headers.set(\"connection\", \"close\");\n }\n return body;\n });\n}\n"]}
@@ -15,6 +15,24 @@ export declare function recordSyncEvent(tx: SyncDatabase, input: RecordSyncEvent
15
15
  export declare function notifyPayload(scope: string, event: SyncEvent): string;
16
16
  /** One scope's events, or several streams' merged on the shared version order. */
17
17
  export declare function readSyncEvents(db: SyncDatabase, scope: string | readonly string[], since: SyncCursor, limit?: number): Promise<SyncEvent[]>;
18
+ export type SyncBacklog = {
19
+ readonly events: SyncEvent[];
20
+ readonly resetTo?: undefined;
21
+ } | {
22
+ readonly resetTo: SyncCursor;
23
+ };
24
+ /**
25
+ * Every event of these streams after `since`, or, when they cannot all be replayed, the
26
+ * cursor to reset to: there are more than one batch of them, or pruning removed events
27
+ * after `since`. The initial cursor asks for the retained log, so pruning never resets it.
28
+ */
29
+ export declare function readSyncBacklog(db: SyncDatabase, scope: string | readonly string[], since: SyncCursor): Promise<SyncBacklog>;
30
+ /**
31
+ * The last event of these streams, or the initial cursor when they have none. Read before
32
+ * a query, it marks what the query's answer already reflects: versions are allocated under
33
+ * one row lock, so any event committed later in these streams sorts after it.
34
+ */
35
+ export declare function readSyncCursor(db: SyncDatabase, scope: string | readonly string[]): Promise<SyncCursor>;
18
36
  export declare function pruneSyncEvents(db: SyncDatabase, retentionMs?: number): Promise<number>;
19
37
  export interface NotifyPayload {
20
38
  readonly scope: string;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAExD,eAAO,MAAM,YAAY,QAAsB,CAAC;AAChD,eAAO,MAAM,cAAc,UAAY,CAAC;AACxC,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAQ/C,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBtE;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,SAAS,CAAC,CA6BpB;AAGD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAIrE;AAeD,kFAAkF;AAClF,wBAAsB,cAAc,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EACjC,KAAK,EAAE,UAAU,EACjB,KAAK,GAAE,MAAkB,GACxB,OAAO,CAAC,SAAS,EAAE,CAAC,CAsBtB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQ7E"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAExE,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,SAAS,EAEf,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;AAExD,eAAO,MAAM,YAAY,QAAsB,CAAC;AAChD,eAAO,MAAM,cAAc,UAAY,CAAC;AACxC,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAQ/C,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BtE;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,SAAS,CAAC,CA6BpB;AAGD,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAIrE;AAeD,kFAAkF;AAClF,wBAAsB,cAAc,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EACjC,KAAK,EAAE,UAAU,EACjB,KAAK,GAAE,MAAkB,GACxB,OAAO,CAAC,SAAS,EAAE,CAAC,CAsBtB;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,GAC9D;IAAE,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC;AAErC;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,EACjC,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,WAAW,CAAC,CAUtB;AASD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAChC,OAAO,CAAC,UAAU,CAAC,CAerB;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAQ7E"}
@@ -1,5 +1,5 @@
1
1
  import { sql } from "drizzle-orm";
2
- import { compareCursors, SYNC_CHANNEL, } from "../protocol.js";
2
+ import { compareCursors, INITIAL_CURSOR, SYNC_CHANNEL, } from "../protocol.js";
3
3
  export const RETENTION_MS = 24 * 60 * 60 * 1000;
4
4
  export const PRUNE_LOCK_KEY = 7_311_207;
5
5
  export const NOTIFY_PAYLOAD_LIMIT_BYTES = 8000;
@@ -24,6 +24,11 @@ export async function ensureSyncTables(db) {
24
24
  insert into sync_version (id, v)
25
25
  select 1, greatest(coalesce((select max(version) from sync_events), 0), 0)
26
26
  on conflict (id) do nothing`);
27
+ await db.execute(sql `create table if not exists sync_pruned (id int primary key, version bigint not null)`);
28
+ await db.execute(sql `
29
+ insert into sync_pruned (id, version)
30
+ select 1, coalesce((select min(version) - 1 from sync_events), (select v from sync_version where id = 1))
31
+ on conflict (id) do nothing`);
27
32
  }
28
33
  export async function recordSyncEvent(tx, input) {
29
34
  if (input.tags.length === 0)
@@ -86,14 +91,54 @@ export async function readSyncEvents(db, scope, since, limit = MAX_BATCH) {
86
91
  }))
87
92
  .sort((a, b) => compareCursors(a, b));
88
93
  }
94
+ /**
95
+ * Every event of these streams after `since`, or, when they cannot all be replayed, the
96
+ * cursor to reset to: there are more than one batch of them, or pruning removed events
97
+ * after `since`. The initial cursor asks for the retained log, so pruning never resets it.
98
+ */
99
+ export async function readSyncBacklog(db, scope, since) {
100
+ const events = await readSyncEvents(db, scope, since, MAX_BATCH + 1);
101
+ const pruned = await readPrunedVersion(db);
102
+ const fromStart = compareCursors(since, INITIAL_CURSOR) === 0;
103
+ if (events.length <= MAX_BATCH && (fromStart || since.version >= pruned)) {
104
+ return { events };
105
+ }
106
+ const head = await readSyncCursor(db, scope);
107
+ const floor = { version: pruned, id: "" };
108
+ return { resetTo: compareCursors(head, floor) > 0 ? head : floor };
109
+ }
110
+ async function readPrunedVersion(db) {
111
+ const [row] = await rows(db.execute(sql `select version from sync_pruned where id = 1`));
112
+ return Number(row?.version ?? 0);
113
+ }
114
+ /**
115
+ * The last event of these streams, or the initial cursor when they have none. Read before
116
+ * a query, it marks what the query's answer already reflects: versions are allocated under
117
+ * one row lock, so any event committed later in these streams sorts after it.
118
+ */
119
+ export async function readSyncCursor(db, scope) {
120
+ const scopes = typeof scope === "string" ? [scope] : scope;
121
+ const lasts = scopes.map((one) => sql `(select version, id from sync_events where scope = ${one} order by version desc, id desc limit 1)`);
122
+ const found = await rows(db.execute(sql.join(lasts, sql ` union all `)));
123
+ return found
124
+ .map((row) => ({ version: Number(row.version), id: row.id }))
125
+ .reduce((latest, cursor) => (compareCursors(cursor, latest) > 0 ? cursor : latest), INITIAL_CURSOR);
126
+ }
89
127
  export async function pruneSyncEvents(db, retentionMs = RETENTION_MS) {
90
128
  return db.transaction(async (tx) => {
91
129
  const [lock] = await rows(tx.execute(sql `select pg_try_advisory_xact_lock(${PRUNE_LOCK_KEY}) as held`));
92
130
  if (!lock?.held)
93
131
  return 0;
94
132
  const cutoff = new Date(Date.now() - retentionMs);
95
- const deleted = await rows(tx.execute(sql `delete from sync_events where created_at < ${cutoff} returning id`));
96
- return deleted.length;
133
+ const [deleted] = await rows(tx.execute(sql `
134
+ with deleted as (
135
+ delete from sync_events where created_at < ${cutoff} returning version
136
+ ), marked as (
137
+ update sync_pruned set version = greatest(version, (select max(version) from deleted))
138
+ where id = 1
139
+ )
140
+ select count(*)::int as count from deleted`));
141
+ return deleted?.count ?? 0;
97
142
  });
98
143
  }
99
144
  export function parseNotifyPayload(payload) {
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Tag } from \"@parlor/core\";\nimport { sql } from \"drizzle-orm\";\nimport type { PgDatabase, PgQueryResultHKT } from \"drizzle-orm/pg-core\";\n\nimport {\n compareCursors,\n INITIAL_CURSOR,\n type SyncCursor,\n type SyncEvent,\n SYNC_CHANNEL,\n} from \"../protocol.js\";\n\nexport type SyncDatabase = PgDatabase<PgQueryResultHKT>;\n\nexport const RETENTION_MS = 24 * 60 * 60 * 1000;\nexport const PRUNE_LOCK_KEY = 7_311_207;\nexport const NOTIFY_PAYLOAD_LIMIT_BYTES = 8000;\nconst MAX_BATCH = 500;\n\nasync function rows<T>(query: Promise<unknown>): Promise<T[]> {\n const result = (await query) as { rows?: T[] } | T[];\n return Array.isArray(result) ? result : (result.rows ?? []);\n}\n\nexport async function ensureSyncTables(db: SyncDatabase): Promise<void> {\n await db.execute(sql`\n create table if not exists sync_events (\n id text primary key,\n version bigint not null,\n scope text not null,\n tags jsonb not null,\n source text,\n created_at timestamptz not null default clock_timestamp()\n )`);\n await db.execute(\n sql`create index if not exists sync_events_scope_version on sync_events (scope, version, id)`,\n );\n await db.execute(\n sql`create table if not exists sync_version (id int primary key, v bigint not null)`,\n );\n await db.execute(sql`\n insert into sync_version (id, v)\n select 1, greatest(coalesce((select max(version) from sync_events), 0), 0)\n on conflict (id) do nothing`);\n await db.execute(\n sql`create table if not exists sync_pruned (id int primary key, version bigint not null)`,\n );\n await db.execute(sql`\n insert into sync_pruned (id, version)\n select 1, coalesce((select min(version) - 1 from sync_events), (select v from sync_version where id = 1))\n on conflict (id) do nothing`);\n}\n\nexport interface RecordSyncEventInput {\n readonly scope: string;\n readonly tags: readonly Tag[];\n readonly source?: string | undefined;\n}\n\nexport async function recordSyncEvent(\n tx: SyncDatabase,\n input: RecordSyncEventInput,\n): Promise<SyncEvent> {\n if (input.tags.length === 0) throw new Error(\"A sync event needs at least one tag\");\n const id = crypto.randomUUID();\n const tags = JSON.stringify(input.tags);\n const inserted = await rows<{ version: number | string }>(\n tx.execute(sql`\n with alloc as (\n update sync_version\n set v = greatest(v + 1, (extract(epoch from clock_timestamp()) * 1000)::bigint)\n where id = 1\n returning v\n )\n insert into sync_events (id, version, scope, tags, source)\n select ${id}, alloc.v, ${input.scope}, ${tags}::jsonb, ${input.source ?? null}\n from alloc\n returning version`),\n );\n const row = inserted[0];\n if (!row) throw new Error(\"sync_version row is missing; run ensureSyncTables first\");\n const event: SyncEvent = {\n version: Number(row.version),\n id,\n tags: input.tags,\n source: input.source,\n };\n await tx.execute(\n sql`select pg_notify(${SYNC_CHANNEL}, ${notifyPayload(input.scope, event)})`,\n );\n return event;\n}\n\n// pg_notify rejects payloads of 8000 bytes or more; the row keeps the full tags.\nexport function notifyPayload(scope: string, event: SyncEvent): string {\n const full = JSON.stringify({ scope, event });\n if (new TextEncoder().encode(full).length < NOTIFY_PAYLOAD_LIMIT_BYTES) return full;\n return JSON.stringify({ scope, event: { ...event, tags: tableTags(event.tags) } });\n}\n\nfunction tableTags(tags: readonly Tag[]): Tag[] {\n const tables = new Set<string | number>();\n for (const tag of tags) if (tag[0] !== undefined) tables.add(tag[0]);\n return [...tables].map((table) => [table]);\n}\n\ninterface EventRow {\n id: string;\n version: number | string;\n tags: Tag[];\n source: string | null;\n}\n\n/** One scope's events, or several streams' merged on the shared version order. */\nexport async function readSyncEvents(\n db: SyncDatabase,\n scope: string | readonly string[],\n since: SyncCursor,\n limit: number = MAX_BATCH,\n): Promise<SyncEvent[]> {\n const scopes = typeof scope === \"string\" ? [scope] : scope;\n const found = await rows<EventRow>(\n db.execute(sql`\n select id, version, tags, source\n from sync_events\n where scope in (${sql.join(\n scopes.map((one) => sql`${one}`),\n sql`, `,\n )})\n and (version > ${since.version} or (version = ${since.version} and id > ${since.id}))\n order by version asc, id asc\n limit ${limit}`),\n );\n return found\n .map((row) => ({\n id: row.id,\n version: Number(row.version),\n tags: row.tags,\n source: row.source ?? undefined,\n }))\n .sort((a, b) => compareCursors(a, b));\n}\n\nexport type SyncBacklog =\n | { readonly events: SyncEvent[]; readonly resetTo?: undefined }\n | { readonly resetTo: SyncCursor };\n\n/**\n * Every event of these streams after `since`, or, when they cannot all be replayed, the\n * cursor to reset to: there are more than one batch of them, or pruning removed events\n * after `since`. The initial cursor asks for the retained log, so pruning never resets it.\n */\nexport async function readSyncBacklog(\n db: SyncDatabase,\n scope: string | readonly string[],\n since: SyncCursor,\n): Promise<SyncBacklog> {\n const events = await readSyncEvents(db, scope, since, MAX_BATCH + 1);\n const pruned = await readPrunedVersion(db);\n const fromStart = compareCursors(since, INITIAL_CURSOR) === 0;\n if (events.length <= MAX_BATCH && (fromStart || since.version >= pruned)) {\n return { events };\n }\n const head = await readSyncCursor(db, scope);\n const floor: SyncCursor = { version: pruned, id: \"\" };\n return { resetTo: compareCursors(head, floor) > 0 ? head : floor };\n}\n\nasync function readPrunedVersion(db: SyncDatabase): Promise<number> {\n const [row] = await rows<{ version: number | string }>(\n db.execute(sql`select version from sync_pruned where id = 1`),\n );\n return Number(row?.version ?? 0);\n}\n\n/**\n * The last event of these streams, or the initial cursor when they have none. Read before\n * a query, it marks what the query's answer already reflects: versions are allocated under\n * one row lock, so any event committed later in these streams sorts after it.\n */\nexport async function readSyncCursor(\n db: SyncDatabase,\n scope: string | readonly string[],\n): Promise<SyncCursor> {\n const scopes = typeof scope === \"string\" ? [scope] : scope;\n const lasts = scopes.map(\n (one) =>\n sql`(select version, id from sync_events where scope = ${one} order by version desc, id desc limit 1)`,\n );\n const found = await rows<{ id: string; version: number | string }>(\n db.execute(sql.join(lasts, sql` union all `)),\n );\n return found\n .map((row) => ({ version: Number(row.version), id: row.id }))\n .reduce<SyncCursor>(\n (latest, cursor) => (compareCursors(cursor, latest) > 0 ? cursor : latest),\n INITIAL_CURSOR,\n );\n}\n\nexport async function pruneSyncEvents(\n db: SyncDatabase,\n retentionMs: number = RETENTION_MS,\n): Promise<number> {\n return db.transaction(async (tx) => {\n const [lock] = await rows<{ held: boolean }>(\n tx.execute(sql`select pg_try_advisory_xact_lock(${PRUNE_LOCK_KEY}) as held`),\n );\n if (!lock?.held) return 0;\n const cutoff = new Date(Date.now() - retentionMs);\n const [deleted] = await rows<{ count: number }>(\n tx.execute(sql`\n with deleted as (\n delete from sync_events where created_at < ${cutoff} returning version\n ), marked as (\n update sync_pruned set version = greatest(version, (select max(version) from deleted))\n where id = 1\n )\n select count(*)::int as count from deleted`),\n );\n return deleted?.count ?? 0;\n });\n}\n\nexport interface NotifyPayload {\n readonly scope: string;\n readonly event: SyncEvent;\n}\n\nexport function parseNotifyPayload(payload: string): NotifyPayload | undefined {\n try {\n const parsed = JSON.parse(payload) as Partial<NotifyPayload>;\n if (typeof parsed.scope !== \"string\" || !parsed.event) return undefined;\n return { scope: parsed.scope, event: parsed.event };\n } catch {\n return undefined;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parlor/sync",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "homepage": "https://cychien.github.io/parlor",
5
5
  "bugs": "https://github.com/cychien/parlor/issues",
6
6
  "license": "MIT",
@@ -30,13 +30,13 @@
30
30
  "dependencies": {
31
31
  "drizzle-orm": "^0.45.4",
32
32
  "h3": "^2.0.1",
33
- "@parlor/core": "0.1.0"
33
+ "@parlor/core": "0.3.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/node": "^24.14.0",
37
37
  "typescript": "^7.0.2",
38
38
  "vitest": "^5.0.3",
39
- "@parlor/data": "0.1.0"
39
+ "@parlor/data": "0.3.0"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsc -p tsconfig.json",