@parlor/sync 0.0.0-stage → 0.1.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.
- package/LICENSE +21 -0
- package/README.md +10 -2
- package/dist/channel.d.ts +21 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +2 -0
- package/dist/channel.js.map +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/sse.d.ts +10 -0
- package/dist/client/sse.d.ts.map +1 -0
- package/dist/client/sse.js +48 -0
- package/dist/client/sse.js.map +1 -0
- package/dist/client/sync-client.d.ts +70 -0
- package/dist/client/sync-client.d.ts.map +1 -0
- package/dist/client/sync-client.js +447 -0
- package/dist/client/sync-client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +32 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +30 -0
- package/dist/protocol.js.map +1 -0
- package/dist/server/hub.d.ts +15 -0
- package/dist/server/hub.d.ts.map +1 -0
- package/dist/server/hub.js +75 -0
- package/dist/server/hub.js.map +1 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +5 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/pruner.d.ts +11 -0
- package/dist/server/pruner.d.ts.map +1 -0
- package/dist/server/pruner.js +23 -0
- package/dist/server/pruner.js.map +1 -0
- package/dist/server/routes.d.ts +36 -0
- package/dist/server/routes.d.ts.map +1 -0
- package/dist/server/routes.js +119 -0
- package/dist/server/routes.js.map +1 -0
- package/dist/server/store.d.ts +24 -0
- package/dist/server/store.d.ts.map +1 -0
- package/dist/server/store.js +110 -0
- package/dist/server/store.js.map +1 -0
- package/package.json +43 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-client.js","sourceRoot":"","sources":["../../src/client/sync-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { ChannelConnection, ClientChannel, ServerChannel } from "./channel.js";
|
|
2
|
+
export { compareCursors, cursorOf, decodeCursor, encodeCursor, INITIAL_CURSOR, SYNC_CHANNEL, SYNC_PROTOCOL_VERSION, type SyncBatch, type SyncCursor, type SyncEvent, type SyncNegotiation, } from "./protocol.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EACL,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Tag } from "@parlor/core";
|
|
2
|
+
export declare const SYNC_PROTOCOL_VERSION = 1;
|
|
3
|
+
export declare const SYNC_CHANNEL = "parlor_sync";
|
|
4
|
+
export declare const DEFAULT_KEEP_ALIVE_MS = 10000;
|
|
5
|
+
export declare const LEGACY_KEEP_ALIVE_MS = 25000;
|
|
6
|
+
export declare function streamLivenessMs(keepAliveMs: number): number;
|
|
7
|
+
export interface SyncEvent {
|
|
8
|
+
readonly version: number;
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly tags: readonly Tag[];
|
|
11
|
+
readonly source?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export interface SyncCursor {
|
|
14
|
+
readonly version: number;
|
|
15
|
+
readonly id: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const INITIAL_CURSOR: SyncCursor;
|
|
18
|
+
export declare function encodeCursor(cursor: SyncCursor): string;
|
|
19
|
+
export declare function decodeCursor(value: unknown): SyncCursor;
|
|
20
|
+
export declare function compareCursors(a: SyncCursor, b: SyncCursor): number;
|
|
21
|
+
export declare function cursorOf(event: SyncEvent): SyncCursor;
|
|
22
|
+
export interface SyncBatch {
|
|
23
|
+
readonly events: readonly SyncEvent[];
|
|
24
|
+
readonly cursor: string;
|
|
25
|
+
}
|
|
26
|
+
export interface SyncNegotiation {
|
|
27
|
+
readonly protocol: typeof SYNC_PROTOCOL_VERSION;
|
|
28
|
+
readonly transport: "sse" | "poll";
|
|
29
|
+
readonly endpoint: string;
|
|
30
|
+
readonly pollIntervalMs: number;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const SYNC_PROTOCOL_VERSION = 1;
|
|
2
|
+
export const SYNC_CHANNEL = "parlor_sync";
|
|
3
|
+
export const DEFAULT_KEEP_ALIVE_MS = 10_000;
|
|
4
|
+
export const LEGACY_KEEP_ALIVE_MS = 25_000;
|
|
5
|
+
const STREAM_LIVENESS_MARGIN_MS = 5000;
|
|
6
|
+
export function streamLivenessMs(keepAliveMs) {
|
|
7
|
+
return keepAliveMs * 2 + STREAM_LIVENESS_MARGIN_MS;
|
|
8
|
+
}
|
|
9
|
+
export const INITIAL_CURSOR = { version: 0, id: "" };
|
|
10
|
+
export function encodeCursor(cursor) {
|
|
11
|
+
return `${cursor.version}.${cursor.id}`;
|
|
12
|
+
}
|
|
13
|
+
export function decodeCursor(value) {
|
|
14
|
+
if (typeof value !== "string" || value === "")
|
|
15
|
+
return INITIAL_CURSOR;
|
|
16
|
+
const separator = value.indexOf(".");
|
|
17
|
+
const version = Number(separator === -1 ? value : value.slice(0, separator));
|
|
18
|
+
if (!Number.isSafeInteger(version) || version < 0)
|
|
19
|
+
return INITIAL_CURSOR;
|
|
20
|
+
return { version, id: separator === -1 ? "" : value.slice(separator + 1) };
|
|
21
|
+
}
|
|
22
|
+
export function compareCursors(a, b) {
|
|
23
|
+
if (a.version !== b.version)
|
|
24
|
+
return a.version - b.version;
|
|
25
|
+
return a.id < b.id ? -1 : a.id > b.id ? 1 : 0;
|
|
26
|
+
}
|
|
27
|
+
export function cursorOf(event) {
|
|
28
|
+
return { version: event.version, id: event.id };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DataProvider } from "@parlor/core";
|
|
2
|
+
import { type SyncEvent } from "../protocol.js";
|
|
3
|
+
export type SyncSubscriber = (event: SyncEvent) => void;
|
|
4
|
+
export declare class SyncHub {
|
|
5
|
+
#private;
|
|
6
|
+
private readonly data;
|
|
7
|
+
constructor(data: DataProvider);
|
|
8
|
+
get canPush(): boolean;
|
|
9
|
+
start(): Promise<void>;
|
|
10
|
+
publish(scope: string, event: SyncEvent): void;
|
|
11
|
+
subscribe(scope: string, notify: SyncSubscriber, onStop?: () => void): () => void;
|
|
12
|
+
subscriberCount(scope?: string): number;
|
|
13
|
+
stop(): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=hub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../src/server/hub.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG9D,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAOxD,qBAAa,OAAO;;IAKN,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,YAAY,EAAI;IAEnD,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAsB3B;IASD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAE7C;IAED,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAShF;IAED,eAAe,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAKtC;IAEK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAO1B;CACF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { SYNC_CHANNEL } from "../protocol.js";
|
|
2
|
+
import { parseNotifyPayload } from "./store.js";
|
|
3
|
+
export class SyncHub {
|
|
4
|
+
data;
|
|
5
|
+
#subscribers = new Map();
|
|
6
|
+
#unlisten;
|
|
7
|
+
#starting;
|
|
8
|
+
constructor(data) {
|
|
9
|
+
this.data = data;
|
|
10
|
+
}
|
|
11
|
+
get canPush() {
|
|
12
|
+
return typeof this.data.listen === "function";
|
|
13
|
+
}
|
|
14
|
+
async start() {
|
|
15
|
+
if (!this.data.listen || this.#unlisten)
|
|
16
|
+
return;
|
|
17
|
+
const starting = (this.#starting ??= this.data
|
|
18
|
+
.listen(SYNC_CHANNEL, (payload) => {
|
|
19
|
+
const parsed = parseNotifyPayload(payload);
|
|
20
|
+
if (parsed)
|
|
21
|
+
this.publish(parsed.scope, parsed.event);
|
|
22
|
+
}, { onLost: () => this.#reconnectEveryStream() })
|
|
23
|
+
.then((unlisten) => {
|
|
24
|
+
if (this.#starting === starting)
|
|
25
|
+
this.#unlisten = unlisten;
|
|
26
|
+
else
|
|
27
|
+
void unlisten();
|
|
28
|
+
}, (error) => {
|
|
29
|
+
if (this.#starting === starting)
|
|
30
|
+
this.#starting = undefined;
|
|
31
|
+
throw error;
|
|
32
|
+
}));
|
|
33
|
+
await starting;
|
|
34
|
+
}
|
|
35
|
+
#reconnectEveryStream() {
|
|
36
|
+
this.#unlisten = undefined;
|
|
37
|
+
this.#starting = undefined;
|
|
38
|
+
const subscriptions = [...this.#subscribers.values()].flatMap((set) => [...set]);
|
|
39
|
+
for (const { onStop } of subscriptions)
|
|
40
|
+
onStop?.();
|
|
41
|
+
}
|
|
42
|
+
publish(scope, event) {
|
|
43
|
+
for (const { notify } of this.#subscribers.get(scope) ?? [])
|
|
44
|
+
notify(event);
|
|
45
|
+
}
|
|
46
|
+
subscribe(scope, notify, onStop) {
|
|
47
|
+
const subscription = { notify, onStop };
|
|
48
|
+
const set = this.#subscribers.get(scope) ?? new Set();
|
|
49
|
+
set.add(subscription);
|
|
50
|
+
this.#subscribers.set(scope, set);
|
|
51
|
+
return () => {
|
|
52
|
+
set.delete(subscription);
|
|
53
|
+
if (set.size === 0)
|
|
54
|
+
this.#subscribers.delete(scope);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
subscriberCount(scope) {
|
|
58
|
+
if (scope)
|
|
59
|
+
return this.#subscribers.get(scope)?.size ?? 0;
|
|
60
|
+
let total = 0;
|
|
61
|
+
for (const set of this.#subscribers.values())
|
|
62
|
+
total += set.size;
|
|
63
|
+
return total;
|
|
64
|
+
}
|
|
65
|
+
async stop() {
|
|
66
|
+
const subscriptions = [...this.#subscribers.values()].flatMap((set) => [...set]);
|
|
67
|
+
for (const { onStop } of subscriptions)
|
|
68
|
+
onStop?.();
|
|
69
|
+
await this.#unlisten?.();
|
|
70
|
+
this.#unlisten = undefined;
|
|
71
|
+
this.#starting = undefined;
|
|
72
|
+
this.#subscribers.clear();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/server/hub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SyncHub, type SyncSubscriber } from "./hub.js";
|
|
2
|
+
export { createPruner, DEFAULT_PRUNE_INTERVAL_MS, type Pruner } from "./pruner.js";
|
|
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";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { SyncHub } from "./hub.js";
|
|
2
|
+
export { createPruner, DEFAULT_PRUNE_INTERVAL_MS } from "./pruner.js";
|
|
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";
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DataProvider } from "@parlor/core";
|
|
2
|
+
export declare const DEFAULT_PRUNE_INTERVAL_MS: number;
|
|
3
|
+
export interface Pruner {
|
|
4
|
+
touch(): void;
|
|
5
|
+
}
|
|
6
|
+
export declare function createPruner(data: DataProvider, options?: {
|
|
7
|
+
intervalMs?: number | undefined;
|
|
8
|
+
now?: () => number;
|
|
9
|
+
onError?: (error: unknown) => void;
|
|
10
|
+
}): Pruner;
|
|
11
|
+
//# sourceMappingURL=pruner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pruner.d.ts","sourceRoot":"","sources":["../../src/server/pruner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAIjD,eAAO,MAAM,yBAAyB,QAAgB,CAAC;AAEvD,MAAM,WAAW,MAAM;IACrB,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,YAAY,EAClB,OAAO,GAAE;IACP,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/B,GACL,MAAM,CAmBR"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { pruneSyncEvents } from "./store.js";
|
|
2
|
+
export const DEFAULT_PRUNE_INTERVAL_MS = 5 * 60 * 1000;
|
|
3
|
+
export function createPruner(data, options = {}) {
|
|
4
|
+
const intervalMs = options.intervalMs ?? DEFAULT_PRUNE_INTERVAL_MS;
|
|
5
|
+
const now = options.now ?? Date.now;
|
|
6
|
+
const onError = options.onError ?? ((error) => console.error("[parlor] sync prune failed:", error));
|
|
7
|
+
let last = now();
|
|
8
|
+
let running = false;
|
|
9
|
+
return {
|
|
10
|
+
touch() {
|
|
11
|
+
if (running || now() - last < intervalMs)
|
|
12
|
+
return;
|
|
13
|
+
running = true;
|
|
14
|
+
last = now();
|
|
15
|
+
void pruneSyncEvents(data.read())
|
|
16
|
+
.catch(onError)
|
|
17
|
+
.finally(() => {
|
|
18
|
+
running = false;
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=pruner.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DataProvider, Principal } from "@parlor/core";
|
|
2
|
+
import { type H3 } from "h3";
|
|
3
|
+
import type { ServerChannel } from "../channel.js";
|
|
4
|
+
import type { SyncHub } from "./hub.js";
|
|
5
|
+
export type SyncTransport = "sse" | "poll";
|
|
6
|
+
export interface SyncRouteOptions {
|
|
7
|
+
readonly basePath: string;
|
|
8
|
+
readonly data: DataProvider;
|
|
9
|
+
readonly hub: SyncHub;
|
|
10
|
+
readonly scope: (request: Request) => string | Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* The caller's own stream inside its scope, for events only its user should hear (an
|
|
13
|
+
* action with `notifies: "user"`); read and pushed alongside the scope's.
|
|
14
|
+
*/
|
|
15
|
+
readonly audience?: ((request: Request) => string | Promise<string>) | undefined;
|
|
16
|
+
readonly transport?: SyncTransport | undefined;
|
|
17
|
+
readonly pollIntervalMs?: number | undefined;
|
|
18
|
+
readonly keepAliveMs?: number | undefined;
|
|
19
|
+
readonly channels?: readonly ServerChannel[] | undefined;
|
|
20
|
+
readonly clientId?: ((request: Request) => string | undefined) | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Who holds a stream and until when. A stream closes when `revoked` aborts, and a
|
|
23
|
+
* stream without `channels` carries sync events only. Refusing a caller happens before
|
|
24
|
+
* these routes run.
|
|
25
|
+
*/
|
|
26
|
+
readonly authority?: ((request: Request) => Promise<StreamAuthority>) | undefined;
|
|
27
|
+
}
|
|
28
|
+
export interface StreamAuthority {
|
|
29
|
+
readonly principal: Principal;
|
|
30
|
+
readonly revoked?: AbortSignal | undefined;
|
|
31
|
+
readonly channels: boolean;
|
|
32
|
+
}
|
|
33
|
+
export declare const DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
34
|
+
export declare function transportFromEnv(value?: string | undefined): SyncTransport | undefined;
|
|
35
|
+
export declare function registerSyncRoutes(app: H3, options: SyncRouteOptions): void;
|
|
36
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { createEventStream, getQuery } from "h3";
|
|
2
|
+
import { compareCursors, cursorOf, decodeCursor, DEFAULT_KEEP_ALIVE_MS, encodeCursor, SYNC_PROTOCOL_VERSION, } from "../protocol.js";
|
|
3
|
+
import { readSyncEvents } from "./store.js";
|
|
4
|
+
export const DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
5
|
+
export function transportFromEnv(value = process.env.PARLOR_SYNC_TRANSPORT) {
|
|
6
|
+
return value === "sse" || value === "poll" ? value : undefined;
|
|
7
|
+
}
|
|
8
|
+
function batch(events, since) {
|
|
9
|
+
const last = events.at(-1);
|
|
10
|
+
return { events, cursor: last ? encodeCursor(cursorOf(last)) : since };
|
|
11
|
+
}
|
|
12
|
+
export function registerSyncRoutes(app, options) {
|
|
13
|
+
const { basePath, data, hub, scope } = options;
|
|
14
|
+
const streamsOf = async (request) => {
|
|
15
|
+
const own = await scope(request);
|
|
16
|
+
const audience = await options.audience?.(request);
|
|
17
|
+
return audience === undefined || audience === own ? [own] : [own, audience];
|
|
18
|
+
};
|
|
19
|
+
const transport = options.transport ?? transportFromEnv() ?? (hub.canPush ? "sse" : "poll");
|
|
20
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
21
|
+
const keepAliveMs = options.keepAliveMs ?? DEFAULT_KEEP_ALIVE_MS;
|
|
22
|
+
const db = () => data.read();
|
|
23
|
+
const channels = options.channels ?? [];
|
|
24
|
+
const capabilities = channels.map((channel) => channel.event);
|
|
25
|
+
app.post(`${basePath}/sync/token`, () => ({
|
|
26
|
+
protocol: SYNC_PROTOCOL_VERSION,
|
|
27
|
+
transport,
|
|
28
|
+
endpoint: `${basePath}/sync/stream`,
|
|
29
|
+
pollIntervalMs,
|
|
30
|
+
}));
|
|
31
|
+
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));
|
|
34
|
+
event.res.headers.set("cache-control", "no-store");
|
|
35
|
+
return batch(events, since);
|
|
36
|
+
});
|
|
37
|
+
app.get(`${basePath}/sync/stream`, async (event) => {
|
|
38
|
+
const streams = await streamsOf(event.req);
|
|
39
|
+
const currentScope = streams[0];
|
|
40
|
+
const authority = await options.authority?.(event.req);
|
|
41
|
+
const sinceParam = String(getQuery(event).since ?? "");
|
|
42
|
+
await hub.start();
|
|
43
|
+
const stream = createEventStream(event);
|
|
44
|
+
const send = (payload) => void stream.push(JSON.stringify(payload));
|
|
45
|
+
const sendLive = (syncEvent) => send({ events: [syncEvent], cursor: encodeCursor(cursorOf(syncEvent)) });
|
|
46
|
+
let arrivedDuringCatchUp = [];
|
|
47
|
+
const unsubscribes = streams.map((name) => hub.subscribe(name, (syncEvent) => {
|
|
48
|
+
if (arrivedDuringCatchUp)
|
|
49
|
+
arrivedDuringCatchUp.push(syncEvent);
|
|
50
|
+
else
|
|
51
|
+
sendLive(syncEvent);
|
|
52
|
+
}, () => void stream.close()));
|
|
53
|
+
const keepAlive = setInterval(() => void stream.pushComment("keep-alive"), keepAliveMs);
|
|
54
|
+
const disconnects = [];
|
|
55
|
+
const ended = new AbortController();
|
|
56
|
+
let detached = false;
|
|
57
|
+
const revoked = authority?.revoked;
|
|
58
|
+
const closeRevoked = () => void stream.close();
|
|
59
|
+
const detach = () => {
|
|
60
|
+
if (detached)
|
|
61
|
+
return;
|
|
62
|
+
detached = true;
|
|
63
|
+
ended.abort();
|
|
64
|
+
clearInterval(keepAlive);
|
|
65
|
+
revoked?.removeEventListener("abort", closeRevoked);
|
|
66
|
+
for (const unsubscribe of unsubscribes)
|
|
67
|
+
unsubscribe();
|
|
68
|
+
for (const disconnect of disconnects)
|
|
69
|
+
disconnect();
|
|
70
|
+
};
|
|
71
|
+
stream.onClosed(detach);
|
|
72
|
+
if (revoked?.aborted)
|
|
73
|
+
closeRevoked();
|
|
74
|
+
else
|
|
75
|
+
revoked?.addEventListener("abort", closeRevoked, { once: true });
|
|
76
|
+
void stream.push({
|
|
77
|
+
event: "handshake",
|
|
78
|
+
data: JSON.stringify({
|
|
79
|
+
protocol: SYNC_PROTOCOL_VERSION,
|
|
80
|
+
capabilities: authority?.channels === false ? [] : capabilities,
|
|
81
|
+
keepAliveMs,
|
|
82
|
+
}),
|
|
83
|
+
});
|
|
84
|
+
const clientId = options.clientId?.(event.req);
|
|
85
|
+
for (const channel of authority?.channels === false ? [] : channels) {
|
|
86
|
+
disconnects.push(channel.connect({
|
|
87
|
+
clientId,
|
|
88
|
+
scope: currentScope,
|
|
89
|
+
...(authority ? { principal: authority.principal } : {}),
|
|
90
|
+
closed: ended.signal,
|
|
91
|
+
send: (frame) => {
|
|
92
|
+
if (!detached)
|
|
93
|
+
void stream.push({ event: channel.event, data: frame });
|
|
94
|
+
},
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
const since = decodeCursor(sinceParam);
|
|
98
|
+
const missed = await readSyncEvents(db(), streams, since).catch((error) => {
|
|
99
|
+
detach();
|
|
100
|
+
throw error;
|
|
101
|
+
});
|
|
102
|
+
if (missed.length > 0)
|
|
103
|
+
send(batch(missed, sinceParam));
|
|
104
|
+
const last = missed.at(-1);
|
|
105
|
+
const caughtUpTo = last ? cursorOf(last) : since;
|
|
106
|
+
const pending = arrivedDuringCatchUp
|
|
107
|
+
.filter((syncEvent) => compareCursors(cursorOf(syncEvent), caughtUpTo) > 0)
|
|
108
|
+
.sort((a, b) => compareCursors(cursorOf(a), cursorOf(b)));
|
|
109
|
+
arrivedDuringCatchUp = undefined;
|
|
110
|
+
for (const syncEvent of pending)
|
|
111
|
+
sendLive(syncEvent);
|
|
112
|
+
const body = await stream.send();
|
|
113
|
+
if (event.req.headers.get("connection") === "keep-alive") {
|
|
114
|
+
event.res.headers.set("connection", "close");
|
|
115
|
+
}
|
|
116
|
+
return body;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Tag } from "@parlor/core";
|
|
2
|
+
import type { PgDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
|
|
3
|
+
import { type SyncCursor, type SyncEvent } from "../protocol.js";
|
|
4
|
+
export type SyncDatabase = PgDatabase<PgQueryResultHKT>;
|
|
5
|
+
export declare const RETENTION_MS: number;
|
|
6
|
+
export declare const PRUNE_LOCK_KEY = 7311207;
|
|
7
|
+
export declare const NOTIFY_PAYLOAD_LIMIT_BYTES = 8000;
|
|
8
|
+
export declare function ensureSyncTables(db: SyncDatabase): Promise<void>;
|
|
9
|
+
export interface RecordSyncEventInput {
|
|
10
|
+
readonly scope: string;
|
|
11
|
+
readonly tags: readonly Tag[];
|
|
12
|
+
readonly source?: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function recordSyncEvent(tx: SyncDatabase, input: RecordSyncEventInput): Promise<SyncEvent>;
|
|
15
|
+
export declare function notifyPayload(scope: string, event: SyncEvent): string;
|
|
16
|
+
/** One scope's events, or several streams' merged on the shared version order. */
|
|
17
|
+
export declare function readSyncEvents(db: SyncDatabase, scope: string | readonly string[], since: SyncCursor, limit?: number): Promise<SyncEvent[]>;
|
|
18
|
+
export declare function pruneSyncEvents(db: SyncDatabase, retentionMs?: number): Promise<number>;
|
|
19
|
+
export interface NotifyPayload {
|
|
20
|
+
readonly scope: string;
|
|
21
|
+
readonly event: SyncEvent;
|
|
22
|
+
}
|
|
23
|
+
export declare function parseNotifyPayload(payload: string): NotifyPayload | undefined;
|
|
24
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { sql } from "drizzle-orm";
|
|
2
|
+
import { compareCursors, SYNC_CHANNEL, } from "../protocol.js";
|
|
3
|
+
export const RETENTION_MS = 24 * 60 * 60 * 1000;
|
|
4
|
+
export const PRUNE_LOCK_KEY = 7_311_207;
|
|
5
|
+
export const NOTIFY_PAYLOAD_LIMIT_BYTES = 8000;
|
|
6
|
+
const MAX_BATCH = 500;
|
|
7
|
+
async function rows(query) {
|
|
8
|
+
const result = (await query);
|
|
9
|
+
return Array.isArray(result) ? result : (result.rows ?? []);
|
|
10
|
+
}
|
|
11
|
+
export async function ensureSyncTables(db) {
|
|
12
|
+
await db.execute(sql `
|
|
13
|
+
create table if not exists sync_events (
|
|
14
|
+
id text primary key,
|
|
15
|
+
version bigint not null,
|
|
16
|
+
scope text not null,
|
|
17
|
+
tags jsonb not null,
|
|
18
|
+
source text,
|
|
19
|
+
created_at timestamptz not null default clock_timestamp()
|
|
20
|
+
)`);
|
|
21
|
+
await db.execute(sql `create index if not exists sync_events_scope_version on sync_events (scope, version, id)`);
|
|
22
|
+
await db.execute(sql `create table if not exists sync_version (id int primary key, v bigint not null)`);
|
|
23
|
+
await db.execute(sql `
|
|
24
|
+
insert into sync_version (id, v)
|
|
25
|
+
select 1, greatest(coalesce((select max(version) from sync_events), 0), 0)
|
|
26
|
+
on conflict (id) do nothing`);
|
|
27
|
+
}
|
|
28
|
+
export async function recordSyncEvent(tx, input) {
|
|
29
|
+
if (input.tags.length === 0)
|
|
30
|
+
throw new Error("A sync event needs at least one tag");
|
|
31
|
+
const id = crypto.randomUUID();
|
|
32
|
+
const tags = JSON.stringify(input.tags);
|
|
33
|
+
const inserted = await rows(tx.execute(sql `
|
|
34
|
+
with alloc as (
|
|
35
|
+
update sync_version
|
|
36
|
+
set v = greatest(v + 1, (extract(epoch from clock_timestamp()) * 1000)::bigint)
|
|
37
|
+
where id = 1
|
|
38
|
+
returning v
|
|
39
|
+
)
|
|
40
|
+
insert into sync_events (id, version, scope, tags, source)
|
|
41
|
+
select ${id}, alloc.v, ${input.scope}, ${tags}::jsonb, ${input.source ?? null}
|
|
42
|
+
from alloc
|
|
43
|
+
returning version`));
|
|
44
|
+
const row = inserted[0];
|
|
45
|
+
if (!row)
|
|
46
|
+
throw new Error("sync_version row is missing; run ensureSyncTables first");
|
|
47
|
+
const event = {
|
|
48
|
+
version: Number(row.version),
|
|
49
|
+
id,
|
|
50
|
+
tags: input.tags,
|
|
51
|
+
source: input.source,
|
|
52
|
+
};
|
|
53
|
+
await tx.execute(sql `select pg_notify(${SYNC_CHANNEL}, ${notifyPayload(input.scope, event)})`);
|
|
54
|
+
return event;
|
|
55
|
+
}
|
|
56
|
+
// pg_notify rejects payloads of 8000 bytes or more; the row keeps the full tags.
|
|
57
|
+
export function notifyPayload(scope, event) {
|
|
58
|
+
const full = JSON.stringify({ scope, event });
|
|
59
|
+
if (new TextEncoder().encode(full).length < NOTIFY_PAYLOAD_LIMIT_BYTES)
|
|
60
|
+
return full;
|
|
61
|
+
return JSON.stringify({ scope, event: { ...event, tags: tableTags(event.tags) } });
|
|
62
|
+
}
|
|
63
|
+
function tableTags(tags) {
|
|
64
|
+
const tables = new Set();
|
|
65
|
+
for (const tag of tags)
|
|
66
|
+
if (tag[0] !== undefined)
|
|
67
|
+
tables.add(tag[0]);
|
|
68
|
+
return [...tables].map((table) => [table]);
|
|
69
|
+
}
|
|
70
|
+
/** One scope's events, or several streams' merged on the shared version order. */
|
|
71
|
+
export async function readSyncEvents(db, scope, since, limit = MAX_BATCH) {
|
|
72
|
+
const scopes = typeof scope === "string" ? [scope] : scope;
|
|
73
|
+
const found = await rows(db.execute(sql `
|
|
74
|
+
select id, version, tags, source
|
|
75
|
+
from sync_events
|
|
76
|
+
where scope in (${sql.join(scopes.map((one) => sql `${one}`), sql `, `)})
|
|
77
|
+
and (version > ${since.version} or (version = ${since.version} and id > ${since.id}))
|
|
78
|
+
order by version asc, id asc
|
|
79
|
+
limit ${limit}`));
|
|
80
|
+
return found
|
|
81
|
+
.map((row) => ({
|
|
82
|
+
id: row.id,
|
|
83
|
+
version: Number(row.version),
|
|
84
|
+
tags: row.tags,
|
|
85
|
+
source: row.source ?? undefined,
|
|
86
|
+
}))
|
|
87
|
+
.sort((a, b) => compareCursors(a, b));
|
|
88
|
+
}
|
|
89
|
+
export async function pruneSyncEvents(db, retentionMs = RETENTION_MS) {
|
|
90
|
+
return db.transaction(async (tx) => {
|
|
91
|
+
const [lock] = await rows(tx.execute(sql `select pg_try_advisory_xact_lock(${PRUNE_LOCK_KEY}) as held`));
|
|
92
|
+
if (!lock?.held)
|
|
93
|
+
return 0;
|
|
94
|
+
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;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export function parseNotifyPayload(payload) {
|
|
100
|
+
try {
|
|
101
|
+
const parsed = JSON.parse(payload);
|
|
102
|
+
if (typeof parsed.scope !== "string" || !parsed.event)
|
|
103
|
+
return undefined;
|
|
104
|
+
return { scope: parsed.scope, event: parsed.event };
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/server/store.ts"],"names":[],"mappings":"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"}
|