orez-sync-executor 0.11.1 → 0.11.2
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/dist/realtime/host.d.ts +7 -0
- package/dist/realtime/host.d.ts.map +1 -0
- package/dist/realtime/host.js +77 -0
- package/dist/realtime/host.js.map +1 -0
- package/dist/realtime/hub.d.ts +67 -0
- package/dist/realtime/hub.d.ts.map +1 -0
- package/dist/realtime/hub.js +456 -0
- package/dist/realtime/hub.js.map +1 -0
- package/dist/realtime/index.d.ts +24 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +27 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/local.d.ts +15 -0
- package/dist/realtime/local.d.ts.map +1 -0
- package/dist/realtime/local.js +63 -0
- package/dist/realtime/local.js.map +1 -0
- package/dist/realtime/manifest.d.ts +51 -0
- package/dist/realtime/manifest.d.ts.map +1 -0
- package/dist/realtime/manifest.js +110 -0
- package/dist/realtime/manifest.js.map +1 -0
- package/dist/realtime/message-port.d.ts +34 -0
- package/dist/realtime/message-port.d.ts.map +1 -0
- package/dist/realtime/message-port.js +141 -0
- package/dist/realtime/message-port.js.map +1 -0
- package/dist/realtime/producer-socket.d.ts +10 -0
- package/dist/realtime/producer-socket.d.ts.map +1 -0
- package/dist/realtime/producer-socket.js +90 -0
- package/dist/realtime/producer-socket.js.map +1 -0
- package/dist/realtime/producer.d.ts +16 -0
- package/dist/realtime/producer.d.ts.map +1 -0
- package/dist/realtime/producer.js +51 -0
- package/dist/realtime/producer.js.map +1 -0
- package/dist/realtime/protocol.d.ts +99 -0
- package/dist/realtime/protocol.d.ts.map +1 -0
- package/dist/realtime/protocol.js +191 -0
- package/dist/realtime/protocol.js.map +1 -0
- package/dist/realtime/publisher.d.ts +28 -0
- package/dist/realtime/publisher.d.ts.map +1 -0
- package/dist/realtime/publisher.js +309 -0
- package/dist/realtime/publisher.js.map +1 -0
- package/dist/realtime/socket-host.d.ts +25 -0
- package/dist/realtime/socket-host.d.ts.map +1 -0
- package/dist/realtime/socket-host.js +105 -0
- package/dist/realtime/socket-host.js.map +1 -0
- package/dist/realtime/store.d.ts +28 -0
- package/dist/realtime/store.d.ts.map +1 -0
- package/dist/realtime/store.js +0 -0
- package/dist/realtime/store.js.map +1 -0
- package/dist/realtime/writer.d.ts +17 -0
- package/dist/realtime/writer.d.ts.map +1 -0
- package/dist/realtime/writer.js +138 -0
- package/dist/realtime/writer.js.map +1 -0
- package/package.json +5 -1
- package/dist/adapters.d.ts +0 -25
- package/dist/adapters.d.ts.map +0 -1
- package/dist/adapters.js +0 -116
- package/dist/adapters.js.map +0 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RealtimePublisher } from './publisher.js';
|
|
2
|
+
import { FieldWriter } from './writer.js';
|
|
3
|
+
import type { RealtimeHub, HubProducer } from './hub.js';
|
|
4
|
+
import type { StreamingManifest } from './manifest.js';
|
|
5
|
+
import type { PublisherTransport } from './publisher.js';
|
|
6
|
+
export type RealtimeProducer = {
|
|
7
|
+
readonly fields: FieldWriter;
|
|
8
|
+
readonly publisher: RealtimePublisher;
|
|
9
|
+
};
|
|
10
|
+
export type ProducerOptions = {
|
|
11
|
+
readonly manifest: StreamingManifest;
|
|
12
|
+
readonly onError?: (message: string) => void;
|
|
13
|
+
};
|
|
14
|
+
export declare function createProducer(transport: PublisherTransport, options: ProducerOptions): RealtimeProducer;
|
|
15
|
+
export declare function inProcessTransport(hub: RealtimeHub, producer: HubProducer): PublisherTransport;
|
|
16
|
+
//# sourceMappingURL=producer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"producer.d.ts","sourceRoot":"","sources":["../../src/realtime/producer.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAEzC,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAA;CACtC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IAIpC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CAC7C,CAAA;AAED,wBAAgB,cAAc,CAC5B,SAAS,EAAE,kBAAkB,EAC7B,OAAO,EAAE,eAAe,GACvB,gBAAgB,CAQlB;AASD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,WAAW,GACpB,kBAAkB,CAcpB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// The producer role, identical on every surface.
|
|
2
|
+
//
|
|
3
|
+
// A producer is whatever generates values: a browser agent loop, an application
|
|
4
|
+
// server, a Rust daemon. What differs between them is only how their frames
|
|
5
|
+
// reach the hub (a direct call, a MessagePort, a WebSocket). What must NOT
|
|
6
|
+
// differ is the API they write through, because otherwise moving a producer
|
|
7
|
+
// between surfaces means rewriting it.
|
|
8
|
+
//
|
|
9
|
+
// So the transport varies and this does not. Every surface builds its producer
|
|
10
|
+
// here, and every producer gets the same two handles:
|
|
11
|
+
//
|
|
12
|
+
// fields imperative: set(handle, value), generations managed for you.
|
|
13
|
+
// This is what a token loop wants and what most code should use.
|
|
14
|
+
// publisher the explicit generation API underneath, for a producer that
|
|
15
|
+
// needs to control begin, commit, and end itself.
|
|
16
|
+
import { RealtimePublisher } from './publisher.js';
|
|
17
|
+
import { FieldWriter } from './writer.js';
|
|
18
|
+
export function createProducer(transport, options) {
|
|
19
|
+
const publisher = new RealtimePublisher(transport, options.manifest);
|
|
20
|
+
const fields = new FieldWriter(publisher, {
|
|
21
|
+
onError: (error, topic) => {
|
|
22
|
+
options.onError?.(`${topic.table}.${topic.field}: ${error.message}`);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
return { fields, publisher };
|
|
26
|
+
}
|
|
27
|
+
// The transport for a producer that shares a process with the hub: the local
|
|
28
|
+
// single-client host and the browser worker. `begin` and `publish` are direct
|
|
29
|
+
// calls, so there is nothing to serialize and nothing to await.
|
|
30
|
+
//
|
|
31
|
+
// A rejection throws, which is what the publisher's own failure handling
|
|
32
|
+
// expects; it converts that into a reported error rather than letting it reach
|
|
33
|
+
// the producer's loop.
|
|
34
|
+
export function inProcessTransport(hub, producer) {
|
|
35
|
+
return {
|
|
36
|
+
begin: (topic, streamID) => {
|
|
37
|
+
const result = hub.beginGeneration(producer, topic, streamID);
|
|
38
|
+
if (!result.ok)
|
|
39
|
+
throw new Error(result.reason);
|
|
40
|
+
},
|
|
41
|
+
publish: (update) => {
|
|
42
|
+
const result = hub.publish(producer, update);
|
|
43
|
+
if (!result.ok)
|
|
44
|
+
throw new Error(result.reason);
|
|
45
|
+
},
|
|
46
|
+
// Nothing to release: the generation closed when its terminal update was
|
|
47
|
+
// published, and there is no socket whose bookkeeping could outlive it.
|
|
48
|
+
end: () => { },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=producer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"producer.js","sourceRoot":"","sources":["../../src/realtime/producer.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,EAAE;AACF,gFAAgF;AAChF,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,uCAAuC;AACvC,EAAE;AACF,+EAA+E;AAC/E,sDAAsD;AACtD,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,2EAA2E;AAC3E,+DAA+D;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAoBzC,MAAM,UAAU,cAAc,CAC5B,SAA6B,EAC7B,OAAwB;IAExB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;IACpE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,SAAS,EAAE;QACxC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACxB,OAAO,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QACtE,CAAC;KACF,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;AAC9B,CAAC;AAED,6EAA6E;AAC7E,8EAA8E;AAC9E,gEAAgE;AAChE,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,uBAAuB;AACvB,MAAM,UAAU,kBAAkB,CAChC,GAAgB,EAChB,QAAqB;IAErB,OAAO;QACL,KAAK,EAAE,CAAC,KAAoB,EAAE,QAAgB,EAAE,EAAE;YAChD,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAA;YAC7D,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;QACD,OAAO,EAAE,CAAC,MAAmB,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAC5C,IAAI,CAAC,MAAM,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC;QACD,yEAAyE;QACzE,wEAAwE;QACxE,GAAG,EAAE,GAAG,EAAE,GAAE,CAAC;KACd,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export type RealtimeKeyValue = string | number | boolean | null;
|
|
2
|
+
export type RealtimeTopic = {
|
|
3
|
+
readonly table: string;
|
|
4
|
+
readonly key: Readonly<Record<string, RealtimeKeyValue>>;
|
|
5
|
+
readonly field: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function canonicalPrimaryKey(primaryKey: readonly string[], key: Readonly<Record<string, RealtimeKeyValue>>): string;
|
|
8
|
+
export declare const TOPIC_SEPARATOR = "\u001F";
|
|
9
|
+
export declare function canonicalTopic(primaryKey: readonly string[], topic: RealtimeTopic): string;
|
|
10
|
+
export type SubscribeFrame = readonly ['subscribe', {
|
|
11
|
+
readonly topic: RealtimeTopic;
|
|
12
|
+
}];
|
|
13
|
+
export type UnsubscribeFrame = readonly ['unsubscribe', {
|
|
14
|
+
readonly topic: RealtimeTopic;
|
|
15
|
+
}];
|
|
16
|
+
export type ClientFrame = SubscribeFrame | UnsubscribeFrame;
|
|
17
|
+
export type BeginFrame = readonly [
|
|
18
|
+
'begin',
|
|
19
|
+
{
|
|
20
|
+
readonly topic: RealtimeTopic;
|
|
21
|
+
readonly streamID: string;
|
|
22
|
+
}
|
|
23
|
+
];
|
|
24
|
+
export type PublishFrame = readonly ['publish', {
|
|
25
|
+
readonly update: FieldUpdate;
|
|
26
|
+
}];
|
|
27
|
+
export type ProducerFrame = BeginFrame | PublishFrame;
|
|
28
|
+
export type BeginResultFrame = readonly [
|
|
29
|
+
'begin-result',
|
|
30
|
+
{
|
|
31
|
+
readonly streamID: string;
|
|
32
|
+
readonly topic: string | null;
|
|
33
|
+
readonly reason: string | null;
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
export type PublishRejectedFrame = readonly [
|
|
37
|
+
'publish-rejected',
|
|
38
|
+
{
|
|
39
|
+
readonly topic: string;
|
|
40
|
+
readonly streamID: string;
|
|
41
|
+
readonly reason: string;
|
|
42
|
+
}
|
|
43
|
+
];
|
|
44
|
+
export type SupersededFrame = readonly [
|
|
45
|
+
'superseded',
|
|
46
|
+
{
|
|
47
|
+
readonly topic: string;
|
|
48
|
+
readonly streamID: string;
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
export type ProducerHostFrame = BeginResultFrame | PublishRejectedFrame | SupersededFrame;
|
|
52
|
+
export type SubscribedFrame = readonly [
|
|
53
|
+
'subscribed',
|
|
54
|
+
{
|
|
55
|
+
readonly topic: string;
|
|
56
|
+
readonly status: 'active' | 'pending';
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
export type SubscribeErrorFrame = readonly [
|
|
60
|
+
'subscribe-error',
|
|
61
|
+
{
|
|
62
|
+
readonly topic: string;
|
|
63
|
+
readonly reason: string;
|
|
64
|
+
}
|
|
65
|
+
];
|
|
66
|
+
export type FieldUpdate = {
|
|
67
|
+
readonly topic: string;
|
|
68
|
+
readonly streamID: string;
|
|
69
|
+
readonly seq: number;
|
|
70
|
+
readonly op: 'snapshot';
|
|
71
|
+
readonly value: unknown;
|
|
72
|
+
} | {
|
|
73
|
+
readonly topic: string;
|
|
74
|
+
readonly streamID: string;
|
|
75
|
+
readonly seq: number;
|
|
76
|
+
readonly op: 'append';
|
|
77
|
+
readonly text: string;
|
|
78
|
+
} | {
|
|
79
|
+
readonly topic: string;
|
|
80
|
+
readonly streamID: string;
|
|
81
|
+
readonly seq: number;
|
|
82
|
+
readonly op: 'end';
|
|
83
|
+
} | {
|
|
84
|
+
readonly topic: string;
|
|
85
|
+
readonly streamID: string;
|
|
86
|
+
readonly seq: number;
|
|
87
|
+
readonly op: 'abort';
|
|
88
|
+
};
|
|
89
|
+
export type FieldFrame = readonly ['field', {
|
|
90
|
+
readonly updates: readonly FieldUpdate[];
|
|
91
|
+
}];
|
|
92
|
+
export type WakeFrame = readonly ['wake', Record<string, never>];
|
|
93
|
+
export type HostFrame = FieldFrame | SubscribeErrorFrame | SubscribedFrame | WakeFrame;
|
|
94
|
+
export declare const LEGACY_WAKE_FRAME = "wake";
|
|
95
|
+
export declare function isLegacyWake(raw: string): boolean;
|
|
96
|
+
export type AnyFrame = ClientFrame | HostFrame | ProducerFrame | ProducerHostFrame;
|
|
97
|
+
export declare function encodeFrame(frame: AnyFrame): string;
|
|
98
|
+
export declare function decodeFrame(raw: string): AnyFrame | undefined;
|
|
99
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/realtime/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// Wire protocol for orez realtime field streaming.
|
|
2
|
+
//
|
|
3
|
+
// Field values are ephemeral: they never enter the Zero store, never advance a
|
|
4
|
+
// cookie, and never survive a reload. The durable value is whatever the
|
|
5
|
+
// ordinary Zero row says. A stream is a presentation-latency optimization over
|
|
6
|
+
// that row, so a dropped frame costs latency and can never cost correctness.
|
|
7
|
+
//
|
|
8
|
+
// Two publish modes, declared per field in the manifest and fixed for the life
|
|
9
|
+
// of the field, so no host ever branches on frame shape at runtime:
|
|
10
|
+
//
|
|
11
|
+
// - `append` (string columns): a frame carries only the new characters. Cost
|
|
12
|
+
// per frame stays flat as the value grows, which is the whole point for token
|
|
13
|
+
// streams. The host accumulates, so a subscriber that arrives at token 900
|
|
14
|
+
// gets one snapshot and then appends.
|
|
15
|
+
// - `replace` (every other column type): a frame carries the complete value.
|
|
16
|
+
// Correct for any JSON-representable column, and the right cost model for
|
|
17
|
+
// fields that change at semantic-event frequency rather than per token.
|
|
18
|
+
//
|
|
19
|
+
// Recovery is the host's accumulator, not a client-side replay buffer. Frames
|
|
20
|
+
// travel over one WebSocket, so they arrive in order or the socket is gone; a
|
|
21
|
+
// reconnect resubscribes and gets a fresh snapshot. `seq` therefore only has to
|
|
22
|
+
// fence a superseded generation and mark where a snapshot ended.
|
|
23
|
+
// The canonical primary-key encoding, mirroring sync_core::value::canonical_pk
|
|
24
|
+
// byte for byte: primary-key columns in the schema's declared order, each key
|
|
25
|
+
// and value serialized as JSON. Both sides derive topics independently and must
|
|
26
|
+
// land on the same string, so harness/fixtures/canonical-pk-vectors.json is
|
|
27
|
+
// asserted here as well as in the native and wasm builds.
|
|
28
|
+
export function canonicalPrimaryKey(primaryKey, key) {
|
|
29
|
+
let out = '{';
|
|
30
|
+
for (let index = 0; index < primaryKey.length; index++) {
|
|
31
|
+
const column = primaryKey[index];
|
|
32
|
+
if (index > 0)
|
|
33
|
+
out += ',';
|
|
34
|
+
out += `${JSON.stringify(column)}:${JSON.stringify(key[column] ?? null)}`;
|
|
35
|
+
}
|
|
36
|
+
return `${out}}`;
|
|
37
|
+
}
|
|
38
|
+
// ASCII unit separator. A Zero table or column name cannot contain it, and the
|
|
39
|
+
// encoded primary key is JSON where it would appear escaped, so the three parts
|
|
40
|
+
// of a topic can never run together ambiguously. Written as an escape rather
|
|
41
|
+
// than a literal so it stays visible in source.
|
|
42
|
+
export const TOPIC_SEPARATOR = '\u001f';
|
|
43
|
+
// A topic's wire identity. Field frames carry this string rather than the
|
|
44
|
+
// structured topic: it is the map key on both sides, and re-deriving it per
|
|
45
|
+
// frame would be pure overhead.
|
|
46
|
+
export function canonicalTopic(primaryKey, topic) {
|
|
47
|
+
const key = canonicalPrimaryKey(primaryKey, topic.key);
|
|
48
|
+
return `${topic.table}${TOPIC_SEPARATOR}${topic.field}${TOPIC_SEPARATOR}${key}`;
|
|
49
|
+
}
|
|
50
|
+
// The legacy notification-only channel sent the bare text "wake". It stays
|
|
51
|
+
// accepted so an old client against a new host, or a new client against the
|
|
52
|
+
// /wake route during migration, still pulls.
|
|
53
|
+
export const LEGACY_WAKE_FRAME = 'wake';
|
|
54
|
+
export function isLegacyWake(raw) {
|
|
55
|
+
return raw === LEGACY_WAKE_FRAME;
|
|
56
|
+
}
|
|
57
|
+
export function encodeFrame(frame) {
|
|
58
|
+
return JSON.stringify(frame);
|
|
59
|
+
}
|
|
60
|
+
// Parsing is total: a malformed frame returns undefined rather than throwing,
|
|
61
|
+
// because a socket message is attacker-influenced input on the host side and a
|
|
62
|
+
// throw inside a message handler would tear down an otherwise healthy socket.
|
|
63
|
+
export function decodeFrame(raw) {
|
|
64
|
+
if (isLegacyWake(raw))
|
|
65
|
+
return ['wake', {}];
|
|
66
|
+
let parsed;
|
|
67
|
+
try {
|
|
68
|
+
parsed = JSON.parse(raw);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
if (!Array.isArray(parsed) || parsed.length !== 2)
|
|
74
|
+
return undefined;
|
|
75
|
+
const [kind, body] = parsed;
|
|
76
|
+
if (typeof kind !== 'string' || !body || typeof body !== 'object')
|
|
77
|
+
return undefined;
|
|
78
|
+
switch (kind) {
|
|
79
|
+
case 'subscribe':
|
|
80
|
+
case 'unsubscribe': {
|
|
81
|
+
const topic = body.topic;
|
|
82
|
+
return isTopic(topic) ? [kind, { topic }] : undefined;
|
|
83
|
+
}
|
|
84
|
+
case 'subscribed': {
|
|
85
|
+
const { topic, status } = body;
|
|
86
|
+
if (typeof topic !== 'string')
|
|
87
|
+
return undefined;
|
|
88
|
+
if (status !== 'active' && status !== 'pending')
|
|
89
|
+
return undefined;
|
|
90
|
+
return ['subscribed', { topic, status }];
|
|
91
|
+
}
|
|
92
|
+
case 'subscribe-error': {
|
|
93
|
+
const { topic, reason } = body;
|
|
94
|
+
if (typeof topic !== 'string' || typeof reason !== 'string')
|
|
95
|
+
return undefined;
|
|
96
|
+
return ['subscribe-error', { topic, reason }];
|
|
97
|
+
}
|
|
98
|
+
case 'field': {
|
|
99
|
+
const updates = body.updates;
|
|
100
|
+
if (!Array.isArray(updates))
|
|
101
|
+
return undefined;
|
|
102
|
+
const decoded = [];
|
|
103
|
+
for (const update of updates) {
|
|
104
|
+
const valid = decodeUpdate(update);
|
|
105
|
+
if (!valid)
|
|
106
|
+
return undefined;
|
|
107
|
+
decoded.push(valid);
|
|
108
|
+
}
|
|
109
|
+
return ['field', { updates: decoded }];
|
|
110
|
+
}
|
|
111
|
+
case 'begin': {
|
|
112
|
+
const { topic, streamID } = body;
|
|
113
|
+
if (!isTopic(topic) || typeof streamID !== 'string' || !streamID)
|
|
114
|
+
return undefined;
|
|
115
|
+
return ['begin', { topic, streamID }];
|
|
116
|
+
}
|
|
117
|
+
case 'publish': {
|
|
118
|
+
const update = decodeUpdate(body.update);
|
|
119
|
+
return update ? ['publish', { update }] : undefined;
|
|
120
|
+
}
|
|
121
|
+
case 'begin-result': {
|
|
122
|
+
const { streamID, topic, reason } = body;
|
|
123
|
+
if (typeof streamID !== 'string')
|
|
124
|
+
return undefined;
|
|
125
|
+
if (topic !== null && typeof topic !== 'string')
|
|
126
|
+
return undefined;
|
|
127
|
+
if (reason !== null && typeof reason !== 'string')
|
|
128
|
+
return undefined;
|
|
129
|
+
return ['begin-result', { streamID, topic, reason }];
|
|
130
|
+
}
|
|
131
|
+
case 'publish-rejected': {
|
|
132
|
+
const { topic, streamID, reason } = body;
|
|
133
|
+
if (typeof topic !== 'string' || typeof streamID !== 'string')
|
|
134
|
+
return undefined;
|
|
135
|
+
if (typeof reason !== 'string')
|
|
136
|
+
return undefined;
|
|
137
|
+
return ['publish-rejected', { topic, streamID, reason }];
|
|
138
|
+
}
|
|
139
|
+
case 'superseded': {
|
|
140
|
+
const { topic, streamID } = body;
|
|
141
|
+
if (typeof topic !== 'string' || typeof streamID !== 'string')
|
|
142
|
+
return undefined;
|
|
143
|
+
return ['superseded', { topic, streamID }];
|
|
144
|
+
}
|
|
145
|
+
case 'wake':
|
|
146
|
+
return ['wake', {}];
|
|
147
|
+
default:
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function decodeUpdate(update) {
|
|
152
|
+
if (!update || typeof update !== 'object')
|
|
153
|
+
return undefined;
|
|
154
|
+
const { topic, streamID, seq, op } = update;
|
|
155
|
+
if (typeof topic !== 'string' || typeof streamID !== 'string')
|
|
156
|
+
return undefined;
|
|
157
|
+
if (typeof seq !== 'number' || !Number.isSafeInteger(seq) || seq < 0)
|
|
158
|
+
return undefined;
|
|
159
|
+
switch (op) {
|
|
160
|
+
case 'snapshot':
|
|
161
|
+
return { topic, streamID, seq, op, value: update.value };
|
|
162
|
+
case 'append': {
|
|
163
|
+
const text = update.text;
|
|
164
|
+
return typeof text === 'string' ? { topic, streamID, seq, op, text } : undefined;
|
|
165
|
+
}
|
|
166
|
+
case 'abort':
|
|
167
|
+
case 'end':
|
|
168
|
+
return { topic, streamID, seq, op };
|
|
169
|
+
default:
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function isTopic(value) {
|
|
174
|
+
if (!value || typeof value !== 'object')
|
|
175
|
+
return false;
|
|
176
|
+
const { table, key, field } = value;
|
|
177
|
+
if (typeof table !== 'string' || !table)
|
|
178
|
+
return false;
|
|
179
|
+
if (typeof field !== 'string' || !field)
|
|
180
|
+
return false;
|
|
181
|
+
if (!key || typeof key !== 'object' || Array.isArray(key))
|
|
182
|
+
return false;
|
|
183
|
+
for (const entry of Object.values(key)) {
|
|
184
|
+
const type = typeof entry;
|
|
185
|
+
if (entry !== null && type !== 'string' && type !== 'number' && type !== 'boolean') {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/realtime/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { StreamingManifest } from './manifest.js';
|
|
2
|
+
import type { FieldUpdate, RealtimeTopic } from './protocol.js';
|
|
3
|
+
export type PublisherTransport = {
|
|
4
|
+
readonly publish: (update: FieldUpdate) => Promise<void> | void;
|
|
5
|
+
readonly begin: (topic: RealtimeTopic, streamID: string) => Promise<void> | void;
|
|
6
|
+
readonly end: (streamID: string) => Promise<void> | void;
|
|
7
|
+
};
|
|
8
|
+
export type BeginOptions = {
|
|
9
|
+
readonly namespace: string;
|
|
10
|
+
readonly key: Readonly<Record<string, boolean | null | number | string>>;
|
|
11
|
+
};
|
|
12
|
+
export type StreamSession<Value> = {
|
|
13
|
+
readonly streamID: string;
|
|
14
|
+
readonly topic: RealtimeTopic;
|
|
15
|
+
set(value: Value): void;
|
|
16
|
+
flush(): Promise<void>;
|
|
17
|
+
finish(value: Value, commit: () => Promise<void>): Promise<void>;
|
|
18
|
+
abort(): Promise<void>;
|
|
19
|
+
};
|
|
20
|
+
export declare class RealtimePublisher {
|
|
21
|
+
#private;
|
|
22
|
+
constructor(transport: PublisherTransport, manifest: StreamingManifest, options?: {
|
|
23
|
+
readonly now?: () => number;
|
|
24
|
+
readonly randomID?: () => string;
|
|
25
|
+
});
|
|
26
|
+
begin<Value = string>(table: string, field: string, options: BeginOptions): Promise<StreamSession<Value>>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publisher.d.ts","sourceRoot":"","sources":["../../src/realtime/publisher.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAsB,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE/D,MAAM,MAAM,kBAAkB,GAAG;IAG/B,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAG/D,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChF,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACzD,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAA;CACzE,CAAA;AAED,MAAM,MAAM,aAAa,CAAC,KAAK,IAAI;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAA;IAI7B,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IAEvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,CAAA;AAcD,qBAAa,iBAAiB;;gBAO1B,SAAS,EAAE,kBAAkB,EAC7B,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE;QAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAA;KAAO;IAQ3E,KAAK,CAAC,KAAK,GAAG,MAAM,EACxB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;CAyBjC"}
|