@syncular/client 0.1.3 → 0.2.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/README.md +227 -709
- package/dist/apply.d.ts +80 -0
- package/dist/apply.js +301 -0
- package/dist/blob.d.ts +127 -0
- package/dist/blob.js +201 -0
- package/dist/bun-database.d.ts +22 -0
- package/dist/bun-database.js +61 -0
- package/dist/client.d.ts +320 -69
- package/dist/client.js +1627 -163
- package/dist/content-type.d.ts +2 -0
- package/dist/content-type.js +2 -0
- package/dist/database.d.ts +35 -80
- package/dist/database.js +32 -947
- package/dist/encryption.d.ts +47 -0
- package/dist/encryption.js +75 -0
- package/dist/errors.d.ts +8 -22
- package/dist/errors.js +10 -207
- package/dist/http.d.ts +32 -0
- package/dist/http.js +196 -0
- package/dist/index.d.ts +28 -16
- package/dist/index.js +25 -12
- package/dist/invalidation.d.ts +69 -0
- package/dist/invalidation.js +84 -0
- package/dist/leader-lock.d.ts +28 -0
- package/dist/leader-lock.js +38 -0
- package/dist/multi-tab.d.ts +134 -0
- package/dist/multi-tab.js +399 -0
- package/dist/node-database.d.ts +41 -0
- package/dist/node-database.js +133 -0
- package/dist/outbox.d.ts +56 -0
- package/dist/outbox.js +140 -0
- package/dist/schema.d.ts +107 -0
- package/dist/schema.js +267 -0
- package/dist/state.d.ts +40 -0
- package/dist/state.js +77 -0
- package/dist/transport.d.ts +44 -0
- package/dist/transport.js +7 -0
- package/dist/wasm-database.d.ts +30 -0
- package/dist/wasm-database.js +170 -0
- package/dist/window.d.ts +64 -0
- package/dist/window.js +0 -0
- package/dist/worker-entry.d.ts +16 -2
- package/dist/worker-entry.js +300 -456
- package/dist/worker-host.d.ts +174 -0
- package/dist/worker-host.js +536 -0
- package/dist/worker-protocol.d.ts +173 -61
- package/dist/worker-protocol.js +7 -16
- package/package.json +45 -112
- package/src/apply.ts +435 -0
- package/src/blob.ts +333 -0
- package/src/bun-database.ts +75 -0
- package/src/client.ts +2247 -277
- package/src/content-type.ts +2 -0
- package/src/database.ts +63 -1389
- package/src/encryption.ts +123 -0
- package/src/errors.ts +11 -265
- package/src/http.ts +254 -0
- package/src/index.ts +25 -20
- package/src/invalidation.ts +128 -0
- package/src/leader-lock.ts +68 -0
- package/src/multi-tab.ts +550 -0
- package/src/node-database.ts +180 -0
- package/src/outbox.ts +206 -0
- package/src/schema.ts +397 -0
- package/src/state.ts +126 -0
- package/src/transport.ts +52 -0
- package/src/wasm-database.ts +279 -0
- package/src/window.ts +0 -0
- package/src/worker-entry.ts +391 -545
- package/src/worker-host.ts +800 -0
- package/src/worker-protocol.ts +204 -99
- package/dist/auth-leases.d.ts +0 -11
- package/dist/auth-leases.d.ts.map +0 -1
- package/dist/auth-leases.js +0 -140
- package/dist/auth-leases.js.map +0 -1
- package/dist/blob-limits.d.ts +0 -15
- package/dist/blob-limits.d.ts.map +0 -1
- package/dist/blob-limits.js +0 -66
- package/dist/blob-limits.js.map +0 -1
- package/dist/bridge-client.d.ts +0 -69
- package/dist/bridge-client.d.ts.map +0 -1
- package/dist/bridge-client.js +0 -282
- package/dist/bridge-client.js.map +0 -1
- package/dist/client-config.d.ts +0 -6
- package/dist/client-config.d.ts.map +0 -1
- package/dist/client-config.js +0 -18
- package/dist/client-config.js.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/command-history.d.ts +0 -35
- package/dist/command-history.d.ts.map +0 -1
- package/dist/command-history.js +0 -378
- package/dist/command-history.js.map +0 -1
- package/dist/console-diagnostics.d.ts +0 -33
- package/dist/console-diagnostics.d.ts.map +0 -1
- package/dist/console-diagnostics.js +0 -496
- package/dist/console-diagnostics.js.map +0 -1
- package/dist/crdt-yjs/index.d.ts +0 -4
- package/dist/crdt-yjs/index.d.ts.map +0 -1
- package/dist/crdt-yjs/index.js +0 -4
- package/dist/crdt-yjs/index.js.map +0 -1
- package/dist/crdt-yjs/webview-host-facade.d.ts +0 -126
- package/dist/crdt-yjs/webview-host-facade.d.ts.map +0 -1
- package/dist/crdt-yjs/webview-host-facade.js +0 -284
- package/dist/crdt-yjs/webview-host-facade.js.map +0 -1
- package/dist/crdt-yjs/yjs-document-field-adapter.d.ts +0 -153
- package/dist/crdt-yjs/yjs-document-field-adapter.d.ts.map +0 -1
- package/dist/crdt-yjs/yjs-document-field-adapter.js +0 -406
- package/dist/crdt-yjs/yjs-document-field-adapter.js.map +0 -1
- package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts +0 -73
- package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts.map +0 -1
- package/dist/crdt-yjs/yjs-prosemirror-bridge.js +0 -169
- package/dist/crdt-yjs/yjs-prosemirror-bridge.js.map +0 -1
- package/dist/database.d.ts.map +0 -1
- package/dist/database.js.map +0 -1
- package/dist/diagnostics.d.ts +0 -10
- package/dist/diagnostics.d.ts.map +0 -1
- package/dist/diagnostics.js +0 -83
- package/dist/diagnostics.js.map +0 -1
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/generated-bridge.d.ts +0 -365
- package/dist/generated-bridge.d.ts.map +0 -1
- package/dist/generated-bridge.js +0 -250
- package/dist/generated-bridge.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mutations.d.ts +0 -72
- package/dist/mutations.d.ts.map +0 -1
- package/dist/mutations.js +0 -63
- package/dist/mutations.js.map +0 -1
- package/dist/network.d.ts +0 -3
- package/dist/network.d.ts.map +0 -1
- package/dist/network.js +0 -17
- package/dist/network.js.map +0 -1
- package/dist/react/index.d.ts +0 -169
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js +0 -628
- package/dist/react/index.js.map +0 -1
- package/dist/react-native/index.d.ts +0 -35
- package/dist/react-native/index.d.ts.map +0 -1
- package/dist/react-native/index.js +0 -49
- package/dist/react-native/index.js.map +0 -1
- package/dist/runtime-contract.d.ts +0 -13
- package/dist/runtime-contract.d.ts.map +0 -1
- package/dist/runtime-contract.js +0 -24
- package/dist/runtime-contract.js.map +0 -1
- package/dist/rust-client.d.ts +0 -106
- package/dist/rust-client.d.ts.map +0 -1
- package/dist/rust-client.js +0 -938
- package/dist/rust-client.js.map +0 -1
- package/dist/sentry.d.ts +0 -35
- package/dist/sentry.d.ts.map +0 -1
- package/dist/sentry.js +0 -155
- package/dist/sentry.js.map +0 -1
- package/dist/sql-safety.d.ts +0 -3
- package/dist/sql-safety.d.ts.map +0 -1
- package/dist/sql-safety.js +0 -62
- package/dist/sql-safety.js.map +0 -1
- package/dist/syncular-runtime-artifacts.json +0 -61
- package/dist/tauri/index.d.ts +0 -35
- package/dist/tauri/index.d.ts.map +0 -1
- package/dist/tauri/index.js +0 -114
- package/dist/tauri/index.js.map +0 -1
- package/dist/types.d.ts +0 -1096
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/wasm/.syncular-wasm-profile +0 -1
- package/dist/wasm/syncular-runtime-artifact.json +0 -21
- package/dist/wasm/syncular.d.ts +0 -207
- package/dist/wasm/syncular.js +0 -2341
- package/dist/wasm/syncular_bg.wasm +0 -0
- package/dist/wasm/syncular_bg.wasm.d.ts +0 -97
- package/dist/wasm-bindings/runtime-contract.d.ts +0 -22
- package/dist/wasm-bindings/runtime-contract.d.ts.map +0 -1
- package/dist/wasm-bindings/runtime-contract.js +0 -112
- package/dist/wasm-bindings/runtime-contract.js.map +0 -1
- package/dist/wasm-core/.syncular-wasm-profile +0 -1
- package/dist/wasm-core/syncular-runtime-artifact.json +0 -17
- package/dist/wasm-core/syncular.d.ts +0 -162
- package/dist/wasm-core/syncular.js +0 -1847
- package/dist/wasm-core/syncular_bg.wasm +0 -0
- package/dist/wasm-core/syncular_bg.wasm.d.ts +0 -77
- package/dist/wasm-perf/.syncular-wasm-profile +0 -1
- package/dist/wasm-perf/syncular-runtime-artifact.json +0 -21
- package/dist/wasm-perf/syncular.d.ts +0 -207
- package/dist/wasm-perf/syncular.js +0 -2341
- package/dist/wasm-perf/syncular_bg.wasm +0 -0
- package/dist/wasm-perf/syncular_bg.wasm.d.ts +0 -97
- package/dist/wasm-runtime.d.ts +0 -23
- package/dist/wasm-runtime.d.ts.map +0 -1
- package/dist/wasm-runtime.js +0 -69
- package/dist/wasm-runtime.js.map +0 -1
- package/dist/worker-client.d.ts +0 -123
- package/dist/worker-client.d.ts.map +0 -1
- package/dist/worker-client.js +0 -1735
- package/dist/worker-client.js.map +0 -1
- package/dist/worker-entry.d.ts.map +0 -1
- package/dist/worker-entry.js.map +0 -1
- package/dist/worker-protocol.d.ts.map +0 -1
- package/dist/worker-protocol.js.map +0 -1
- package/dist/worker-realtime.d.ts +0 -39
- package/dist/worker-realtime.d.ts.map +0 -1
- package/dist/worker-realtime.js +0 -677
- package/dist/worker-realtime.js.map +0 -1
- package/src/auth-leases.ts +0 -251
- package/src/blob-limits.ts +0 -98
- package/src/bridge-client.ts +0 -512
- package/src/client-config.ts +0 -29
- package/src/command-history.ts +0 -623
- package/src/console-diagnostics.ts +0 -617
- package/src/crdt-yjs/index.ts +0 -3
- package/src/crdt-yjs/webview-host-facade.ts +0 -477
- package/src/crdt-yjs/yjs-document-field-adapter.ts +0 -733
- package/src/crdt-yjs/yjs-prosemirror-bridge.ts +0 -272
- package/src/diagnostics.ts +0 -116
- package/src/generated-bridge.ts +0 -741
- package/src/mutations.ts +0 -168
- package/src/network.ts +0 -32
- package/src/react/index.ts +0 -1036
- package/src/react-native/index.ts +0 -152
- package/src/runtime-contract.ts +0 -48
- package/src/rust-client.ts +0 -1491
- package/src/sentry.ts +0 -215
- package/src/sql-safety.ts +0 -61
- package/src/tauri/index.ts +0 -211
- package/src/types.ts +0 -1397
- package/src/wasm-bindings/generated-wasm-bindings.d.ts +0 -70
- package/src/wasm-bindings/runtime-contract.ts +0 -158
- package/src/wasm-runtime.ts +0 -145
- package/src/worker-client.ts +0 -2289
- package/src/worker-realtime.ts +0 -843
package/src/worker-protocol.ts
CHANGED
|
@@ -1,109 +1,214 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The worker RPC protocol (Direction decision 2, 2026-07-03): the whole
|
|
3
|
+
* client core runs in a Web Worker; the UI thread talks to it through
|
|
4
|
+
* this thin, multiplexed postMessage protocol. Exactly SIX message types
|
|
5
|
+
* (`init`, `call`, `ready`, `result`, `error`, `event`) — every logical
|
|
6
|
+
* API method multiplexes over `call`, every notification over `event`.
|
|
7
|
+
*
|
|
8
|
+
* Both sides derive their typing from ONE shared shape: `WorkerApi`.
|
|
9
|
+
* The worker implements it (`worker-entry.ts`); the handle projects it
|
|
10
|
+
* to promises (`worker-host.ts`). Everything crossing the boundary is
|
|
11
|
+
* structured-clone data — no functions, no class instances.
|
|
12
|
+
*
|
|
13
|
+
* Scheduling note (SPEC §8.4): the sync-needed signal is host-driven,
|
|
14
|
+
* and in worker mode the HOST LOOP LIVES IN THE WORKER — wake-ups
|
|
15
|
+
* coalesce into jittered `syncUntilIdle` rounds there (`autoSync`),
|
|
16
|
+
* so the UI thread never has to react to keep data flowing. Events are
|
|
17
|
+
* still forwarded to the handle for visibility.
|
|
18
|
+
*/
|
|
19
|
+
import type { WakeReason } from '@syncular/core';
|
|
20
|
+
import type { BlobRef, CachedBlob } from './blob';
|
|
3
21
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
ConflictRecord,
|
|
23
|
+
LeaseState,
|
|
24
|
+
MutationInput,
|
|
25
|
+
PresencePeer,
|
|
26
|
+
RejectionRecord,
|
|
27
|
+
SchemaFloor,
|
|
28
|
+
SubscribeInput,
|
|
29
|
+
SyncClientLimits,
|
|
30
|
+
SyncSummary,
|
|
31
|
+
WindowState,
|
|
32
|
+
} from './client';
|
|
33
|
+
import type { SqlRow, SqlValue } from './database';
|
|
34
|
+
import type { InvalidationEvent } from './invalidation';
|
|
35
|
+
import type { OutboxCommit } from './outbox';
|
|
36
|
+
import type { ClientSchema } from './schema';
|
|
37
|
+
import type { SubscriptionRecord } from './state';
|
|
38
|
+
import type { WindowBase } from './window';
|
|
39
|
+
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Client-local error codes (never wire codes; §10 stays server-owned)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
|
|
44
|
+
/** The handle exists but this tab lost the leader election (TODO 3.2). */
|
|
45
|
+
export const NOT_LEADER_CODE = 'client.not_leader';
|
|
46
|
+
/** The worker (or its RPC channel) failed outside protocol semantics. */
|
|
47
|
+
export const WORKER_FAILED_CODE = 'client.worker_failed';
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Init configuration (structured-clone safe)
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
export type WorkerDatabaseInit =
|
|
54
|
+
| {
|
|
55
|
+
/** THE persistent mode: opfs-sahpool, named database. */
|
|
56
|
+
readonly mode: 'persistent';
|
|
57
|
+
readonly name: string;
|
|
58
|
+
/** Optional pool directory override (default `.syncular/<name>`). */
|
|
59
|
+
readonly directory?: string;
|
|
60
|
+
}
|
|
61
|
+
| {
|
|
62
|
+
/**
|
|
63
|
+
* Bootstrap-provided database (tests inject bun:sqlite here). The
|
|
64
|
+
* worker entry MUST have an `openDatabase` override or init fails.
|
|
65
|
+
*/
|
|
66
|
+
readonly mode: 'custom';
|
|
67
|
+
readonly options?: unknown;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export interface WorkerEndpoints {
|
|
71
|
+
/** POST target for SSP2 sync rounds (§1.1). */
|
|
72
|
+
readonly syncUrl: string;
|
|
73
|
+
/** Segment download base URL; omit when segments are not served. */
|
|
74
|
+
readonly segmentsUrl?: string;
|
|
75
|
+
/** Blob upload/download base URL (§5.9); omit when blobs are unused. */
|
|
76
|
+
readonly blobsUrl?: string;
|
|
77
|
+
/**
|
|
78
|
+
* WebSocket URL for §8 realtime. The literal placeholder `{clientId}`
|
|
79
|
+
* is substituted with the (possibly persisted) client id after start.
|
|
80
|
+
*/
|
|
81
|
+
readonly realtimeUrl?: string;
|
|
25
82
|
}
|
|
26
83
|
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
...(options.details !== undefined ? { details: options.details } : {}),
|
|
46
|
-
};
|
|
84
|
+
export interface WorkerInitConfig {
|
|
85
|
+
readonly schema: ClientSchema;
|
|
86
|
+
readonly database: WorkerDatabaseInit;
|
|
87
|
+
readonly endpoints: WorkerEndpoints;
|
|
88
|
+
readonly clientId?: string;
|
|
89
|
+
readonly limits?: SyncClientLimits;
|
|
90
|
+
/**
|
|
91
|
+
* Worker-side host loop (§8.4): coalesce wake-ups into jittered
|
|
92
|
+
* `syncUntilIdle` rounds inside the worker. Default true.
|
|
93
|
+
*/
|
|
94
|
+
readonly autoSync?: boolean;
|
|
95
|
+
/** Max jitter before a coalesced auto-sync round (default 200 ms). */
|
|
96
|
+
readonly wakeJitterMs?: number;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** Successful init reply. */
|
|
100
|
+
export interface WorkerInitResult {
|
|
101
|
+
readonly clientId: string;
|
|
47
102
|
}
|
|
48
103
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
} from './generated-bridge';
|
|
53
|
-
export type SyncularWorkerRequest = SyncularGeneratedWorkerRequest;
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
// The logical API — the one shared shape (worker implements, handle projects)
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
54
107
|
|
|
55
|
-
interface
|
|
56
|
-
|
|
57
|
-
|
|
108
|
+
export interface WorkerApi {
|
|
109
|
+
subscribe(input: SubscribeInput): void;
|
|
110
|
+
unsubscribe(id: string): void;
|
|
111
|
+
/** §4.8 windowed subscriptions: set the live units for a window base. */
|
|
112
|
+
setWindow(base: WindowBase, units: readonly string[]): Promise<void>;
|
|
113
|
+
/** §4.8 completeness oracle (I3): the windowed-in units for a base. */
|
|
114
|
+
windowState(base: WindowBase): WindowState;
|
|
115
|
+
mutate(mutations: readonly MutationInput[]): string;
|
|
116
|
+
sync(): Promise<SyncSummary>;
|
|
117
|
+
syncUntilIdle(maxRounds?: number): Promise<SyncSummary>;
|
|
118
|
+
query(sql: string, params?: readonly SqlValue[]): SqlRow[];
|
|
119
|
+
conflicts(): readonly ConflictRecord[];
|
|
120
|
+
rejections(): readonly RejectionRecord[];
|
|
121
|
+
schemaFloor(): SchemaFloor | undefined;
|
|
122
|
+
/** §7.3.5: the opaque auth-lease state, or undefined. */
|
|
123
|
+
leaseState(): LeaseState | undefined;
|
|
124
|
+
/** §7.4.5: true while a schema-bump reset + first re-bootstrap runs. */
|
|
125
|
+
upgrading(): boolean;
|
|
126
|
+
syncNeeded(): boolean;
|
|
127
|
+
pendingCommits(): OutboxCommit[];
|
|
128
|
+
subscriptions(): SubscriptionRecord[];
|
|
129
|
+
subscription(id: string): SubscriptionRecord | undefined;
|
|
130
|
+
connectRealtime(): Promise<void>;
|
|
131
|
+
disconnectRealtime(): void;
|
|
132
|
+
/** §8.6 presence: publish/clear a scope-keyed presence document. */
|
|
133
|
+
setPresence(scopeKey: string, doc: Record<string, unknown> | null): void;
|
|
134
|
+
/** §8.6 presence: the peers currently present on a scope key. */
|
|
135
|
+
presence(scopeKey: string): readonly PresencePeer[];
|
|
136
|
+
/** §5.9 blobs: stage bytes (returns the canonical ref) / resolve bytes. */
|
|
137
|
+
uploadBlob(
|
|
138
|
+
bytes: Uint8Array,
|
|
139
|
+
options?: { readonly mediaType?: string; readonly name?: string },
|
|
140
|
+
): Promise<BlobRef>;
|
|
141
|
+
fetchBlob(blobIdOrRef: string): Promise<CachedBlob>;
|
|
142
|
+
/** Sever/restore the transport + realtime (offline simulation, demos). */
|
|
143
|
+
setOffline(offline: boolean): void;
|
|
144
|
+
close(): Promise<void>;
|
|
58
145
|
}
|
|
59
146
|
|
|
60
|
-
|
|
61
|
-
|
|
147
|
+
export type WorkerMethod = keyof WorkerApi;
|
|
148
|
+
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
// Messages (6 types total)
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
|
|
153
|
+
/** `call` for method M, with args typed straight off `WorkerApi`. */
|
|
154
|
+
export type WorkerCallMessage = {
|
|
155
|
+
[M in WorkerMethod]: {
|
|
156
|
+
readonly t: 'call';
|
|
157
|
+
readonly id: number;
|
|
158
|
+
readonly method: M;
|
|
159
|
+
readonly args: Parameters<WorkerApi[M]>;
|
|
160
|
+
};
|
|
161
|
+
}[WorkerMethod];
|
|
162
|
+
|
|
163
|
+
export type MainToWorkerMessage =
|
|
164
|
+
| {
|
|
165
|
+
readonly t: 'init';
|
|
166
|
+
readonly id: number;
|
|
167
|
+
readonly config: WorkerInitConfig;
|
|
168
|
+
}
|
|
169
|
+
| WorkerCallMessage;
|
|
170
|
+
|
|
171
|
+
export interface WorkerErrorShape {
|
|
172
|
+
readonly code: string;
|
|
173
|
+
readonly message: string;
|
|
174
|
+
readonly retryable: boolean;
|
|
62
175
|
}
|
|
63
176
|
|
|
64
|
-
export type
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
| (SyncularWorkerEventBase & {
|
|
103
|
-
type: 'diagnostic';
|
|
104
|
-
event: SyncularDiagnosticEvent;
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
export type SyncularWorkerOutboundMessage =
|
|
108
|
-
| SyncularWorkerResponse
|
|
109
|
-
| SyncularWorkerEvent;
|
|
177
|
+
export type SyncWorkerEvent =
|
|
178
|
+
| { readonly kind: 'sync-needed'; readonly reason: 'hello' | WakeReason }
|
|
179
|
+
| { readonly kind: 'conflict'; readonly conflict: ConflictRecord }
|
|
180
|
+
| {
|
|
181
|
+
/** An autoSync round finished (or failed) inside the worker. */
|
|
182
|
+
readonly kind: 'synced';
|
|
183
|
+
readonly summary?: SyncSummary;
|
|
184
|
+
readonly error?: WorkerErrorShape;
|
|
185
|
+
}
|
|
186
|
+
| {
|
|
187
|
+
/** §7.4.5: the schema-bump `upgrading` state changed in the worker. */
|
|
188
|
+
readonly kind: 'upgrading';
|
|
189
|
+
readonly upgrading: boolean;
|
|
190
|
+
}
|
|
191
|
+
| {
|
|
192
|
+
/** §8.6: presence on a scope key changed inside the worker. */
|
|
193
|
+
readonly kind: 'presence';
|
|
194
|
+
readonly scopeKey: string;
|
|
195
|
+
}
|
|
196
|
+
| {
|
|
197
|
+
/**
|
|
198
|
+
* TODO 3.1 / I1: one coalesced apply-batch invalidation. `Set`s
|
|
199
|
+
* structured-clone across the worker boundary, so the event crosses
|
|
200
|
+
* verbatim — the handle re-emits it to `onInvalidate` listeners.
|
|
201
|
+
*/
|
|
202
|
+
readonly kind: 'invalidate';
|
|
203
|
+
readonly event: InvalidationEvent;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export type WorkerToMainMessage =
|
|
207
|
+
| { readonly t: 'ready' }
|
|
208
|
+
| { readonly t: 'result'; readonly id: number; readonly value: unknown }
|
|
209
|
+
| {
|
|
210
|
+
readonly t: 'error';
|
|
211
|
+
readonly id: number;
|
|
212
|
+
readonly error: WorkerErrorShape;
|
|
213
|
+
}
|
|
214
|
+
| { readonly t: 'event'; readonly event: SyncWorkerEvent };
|
package/dist/auth-leases.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { type SyncAuthLeaseIssueRequest } from '@syncular/core';
|
|
2
|
-
import type { SyncularAppSchema, SyncularAuthHeaders, SyncularAuthLeaseRecord } from './types';
|
|
3
|
-
export declare function issueSyncularAuthLease(args: {
|
|
4
|
-
baseUrl: string;
|
|
5
|
-
headers: SyncularAuthHeaders;
|
|
6
|
-
request: SyncAuthLeaseIssueRequest;
|
|
7
|
-
appSchema?: SyncularAppSchema;
|
|
8
|
-
fetchImpl?: typeof fetch;
|
|
9
|
-
nowMs?: number;
|
|
10
|
-
}): Promise<SyncularAuthLeaseRecord>;
|
|
11
|
-
//# sourceMappingURL=auth-leases.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-leases.d.ts","sourceRoot":"","sources":["../src/auth-leases.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAE/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAEjB,wBAAsB,sBAAsB,CAAC,IAAI,EAAE;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,OAAO,EAAE,yBAAyB,CAAC;IACnC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAiCnC"}
|
package/dist/auth-leases.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { resolveUrlFromBase, } from '@syncular/core';
|
|
2
|
-
export async function issueSyncularAuthLease(args) {
|
|
3
|
-
if (args.appSchema) {
|
|
4
|
-
validateSyncularAuthLeaseIssueRequestAgainstAppSchema(args.request, args.appSchema);
|
|
5
|
-
}
|
|
6
|
-
const fetchImpl = args.fetchImpl ?? fetch;
|
|
7
|
-
const headers = new Headers(args.headers);
|
|
8
|
-
headers.set('accept', 'application/json');
|
|
9
|
-
headers.set('content-type', 'application/json');
|
|
10
|
-
const response = await fetchImpl(resolveUrlFromBase(args.baseUrl, 'auth-leases/issue'), {
|
|
11
|
-
method: 'POST',
|
|
12
|
-
headers,
|
|
13
|
-
body: JSON.stringify(args.request),
|
|
14
|
-
});
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
throw await authLeaseIssueHttpError(response);
|
|
17
|
-
}
|
|
18
|
-
const issueResponse = assertAuthLeaseIssueResponse(await response.json());
|
|
19
|
-
if (args.appSchema) {
|
|
20
|
-
validateSyncularAuthLeaseIssueResponseAgainstAppSchema(issueResponse, args.request.schemaVersion, args.appSchema);
|
|
21
|
-
}
|
|
22
|
-
return syncularAuthLeaseRecordFromIssueResponse(issueResponse, args.nowMs);
|
|
23
|
-
}
|
|
24
|
-
function validateSyncularAuthLeaseIssueRequestAgainstAppSchema(request, appSchema) {
|
|
25
|
-
validateSyncularAuthLeaseSchemaVersion(request.schemaVersion, appSchema, 'auth lease request');
|
|
26
|
-
if (request.ttlMs != null && request.ttlMs <= 0) {
|
|
27
|
-
throw new Error('auth lease request ttlMs must be positive');
|
|
28
|
-
}
|
|
29
|
-
validateSyncularAuthLeaseScopesAgainstAppSchema(request.scopes, appSchema, 'auth lease request');
|
|
30
|
-
}
|
|
31
|
-
function validateSyncularAuthLeaseIssueResponseAgainstAppSchema(response, requestSchemaVersion, appSchema) {
|
|
32
|
-
if (response.payload.schemaVersion !== requestSchemaVersion) {
|
|
33
|
-
throw new Error(`auth lease response schemaVersion ${response.payload.schemaVersion} does not match request schemaVersion ${requestSchemaVersion}`);
|
|
34
|
-
}
|
|
35
|
-
validateSyncularAuthLeaseSchemaVersion(response.payload.schemaVersion, appSchema, 'auth lease payload');
|
|
36
|
-
validateSyncularAuthLeaseScopesAgainstAppSchema(response.payload.scopes, appSchema, 'auth lease payload');
|
|
37
|
-
}
|
|
38
|
-
function validateSyncularAuthLeaseSchemaVersion(schemaVersion, appSchema, source) {
|
|
39
|
-
if (schemaVersion === appSchema.schemaVersion)
|
|
40
|
-
return;
|
|
41
|
-
throw new Error(`${source} schemaVersion ${schemaVersion} does not match generated app schema version ${appSchema.schemaVersion}`);
|
|
42
|
-
}
|
|
43
|
-
function validateSyncularAuthLeaseScopesAgainstAppSchema(scopes, appSchema, source) {
|
|
44
|
-
if (scopes.length === 0) {
|
|
45
|
-
throw new Error(`${source} must contain at least one generated table scope`);
|
|
46
|
-
}
|
|
47
|
-
for (const scope of scopes) {
|
|
48
|
-
validateSyncularAuthLeaseScopeAgainstAppSchema(scope, appSchema, source);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function validateSyncularAuthLeaseScopeAgainstAppSchema(scope, appSchema, source) {
|
|
52
|
-
if (scope.subscriptionId.trim() === '') {
|
|
53
|
-
throw new Error(`${source} scope subscriptionId must not be empty`);
|
|
54
|
-
}
|
|
55
|
-
const tableName = scope.table.trim();
|
|
56
|
-
if (tableName === '') {
|
|
57
|
-
throw new Error(`${source} scope table must not be empty`);
|
|
58
|
-
}
|
|
59
|
-
const table = appSchema.tables.find((table) => table.name === tableName);
|
|
60
|
-
if (!table) {
|
|
61
|
-
throw new Error(`${source} scope references unknown generated table ${tableName}`);
|
|
62
|
-
}
|
|
63
|
-
if (scope.operations.length === 0) {
|
|
64
|
-
throw new Error(`${source} scope for table ${tableName} must include at least one operation`);
|
|
65
|
-
}
|
|
66
|
-
for (const operation of scope.operations) {
|
|
67
|
-
const operationName = operation;
|
|
68
|
-
if (operationName !== 'upsert' && operationName !== 'delete') {
|
|
69
|
-
throw new Error(`${source} scope for table ${tableName} references unsupported operation ${operationName}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const scopeKeys = new Set(table.scopes.map((scope) => scope.name));
|
|
73
|
-
for (const key of Object.keys(scope.values)) {
|
|
74
|
-
if (!scopeKeys.has(key)) {
|
|
75
|
-
throw new Error(`${source} scope for table ${tableName} references unknown generated scope ${key}`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
for (const generatedScope of table.scopes) {
|
|
79
|
-
if (generatedScope.required && !(generatedScope.name in scope.values)) {
|
|
80
|
-
throw new Error(`${source} scope for table ${tableName} is missing required generated scope ${generatedScope.name}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
for (const [key, value] of Object.entries(scope.values)) {
|
|
84
|
-
validateSyncularAuthLeaseScopeValue(source, tableName, key, value);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
function validateSyncularAuthLeaseScopeValue(source, table, key, value) {
|
|
88
|
-
if (typeof value === 'string' && value.length > 0)
|
|
89
|
-
return;
|
|
90
|
-
if (Array.isArray(value) &&
|
|
91
|
-
value.length > 0 &&
|
|
92
|
-
value.every((entry) => typeof entry === 'string' && entry.length > 0)) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
throw new Error(`${source} scope ${table}.${key} must be a non-empty string or non-empty string array`);
|
|
96
|
-
}
|
|
97
|
-
function syncularAuthLeaseRecordFromIssueResponse(response, nowMs = Date.now()) {
|
|
98
|
-
return {
|
|
99
|
-
leaseId: response.payload.leaseId,
|
|
100
|
-
kid: response.protectedHeader.kid,
|
|
101
|
-
actorId: response.payload.actorId,
|
|
102
|
-
issuedAtMs: response.payload.issuedAtMs,
|
|
103
|
-
notBeforeMs: response.payload.notBeforeMs,
|
|
104
|
-
expiresAtMs: response.payload.expiresAtMs,
|
|
105
|
-
schemaVersion: response.payload.schemaVersion,
|
|
106
|
-
payloadJson: JSON.stringify(response.payload),
|
|
107
|
-
token: response.token,
|
|
108
|
-
status: 'active',
|
|
109
|
-
lastValidationError: null,
|
|
110
|
-
createdAtMs: response.payload.issuedAtMs,
|
|
111
|
-
updatedAtMs: Math.trunc(nowMs),
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
async function authLeaseIssueHttpError(response) {
|
|
115
|
-
const body = await response.text().catch(() => '');
|
|
116
|
-
return new Error(`Syncular auth lease issue failed with HTTP ${response.status}: ${body}`);
|
|
117
|
-
}
|
|
118
|
-
function assertAuthLeaseIssueResponse(value) {
|
|
119
|
-
if (!value || typeof value !== 'object') {
|
|
120
|
-
throw new Error('Syncular auth lease issue returned invalid JSON');
|
|
121
|
-
}
|
|
122
|
-
const response = value;
|
|
123
|
-
const payload = response.payload;
|
|
124
|
-
const protectedHeader = response.protectedHeader;
|
|
125
|
-
if (response.ok !== true ||
|
|
126
|
-
typeof response.token !== 'string' ||
|
|
127
|
-
!payload ||
|
|
128
|
-
typeof payload.leaseId !== 'string' ||
|
|
129
|
-
typeof payload.actorId !== 'string' ||
|
|
130
|
-
typeof payload.issuedAtMs !== 'number' ||
|
|
131
|
-
typeof payload.notBeforeMs !== 'number' ||
|
|
132
|
-
typeof payload.expiresAtMs !== 'number' ||
|
|
133
|
-
typeof payload.schemaVersion !== 'number' ||
|
|
134
|
-
!protectedHeader ||
|
|
135
|
-
typeof protectedHeader.kid !== 'string') {
|
|
136
|
-
throw new Error('Syncular auth lease issue returned an invalid lease');
|
|
137
|
-
}
|
|
138
|
-
return response;
|
|
139
|
-
}
|
|
140
|
-
//# sourceMappingURL=auth-leases.js.map
|
package/dist/auth-leases.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-leases.js","sourceRoot":"","sources":["../src/auth-leases.ts"],"names":[],"mappings":"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"}
|
package/dist/blob-limits.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { SyncularBlobLimits, SyncularBlobStoreOptions, SyncularDiagnosticSink } from './types';
|
|
2
|
-
export declare const DEFAULT_SYNCULAR_BROWSER_MAX_BLOB_PAYLOAD_BYTES: number;
|
|
3
|
-
export type SyncularBlobLimitOperation = 'store' | 'retrieve';
|
|
4
|
-
export type SyncularBlobLimitInput = Blob | File | Uint8Array;
|
|
5
|
-
export declare function resolveSyncularBlobLimits(limits: SyncularBlobLimits | undefined): Required<SyncularBlobLimits>;
|
|
6
|
-
export declare function syncularBlobInputSize(data: SyncularBlobLimitInput): number;
|
|
7
|
-
export declare function assertSyncularBlobPayloadLimit(args: {
|
|
8
|
-
operation: SyncularBlobLimitOperation;
|
|
9
|
-
size: number;
|
|
10
|
-
limits: SyncularBlobLimits | undefined;
|
|
11
|
-
options?: SyncularBlobStoreOptions;
|
|
12
|
-
refHash?: string;
|
|
13
|
-
diagnostics?: SyncularDiagnosticSink;
|
|
14
|
-
}): void;
|
|
15
|
-
//# sourceMappingURL=blob-limits.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blob-limits.d.ts","sourceRoot":"","sources":["../src/blob-limits.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,wBAAwB,EAExB,sBAAsB,EACvB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,+CAA+C,QAAmB,CAAC;AAEhF,MAAM,MAAM,0BAA0B,GAAG,OAAO,GAAG,UAAU,CAAC;AAE9D,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,IAAI,GAAG,UAAU,CAAC;AAE9D,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,kBAAkB,GAAG,SAAS,GACrC,QAAQ,CAAC,kBAAkB,CAAC,CAO9B;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,GAAG,MAAM,CAI1E;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE;IACnD,SAAS,EAAE,0BAA0B,CAAC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACvC,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,sBAAsB,CAAC;CACtC,GAAG,IAAI,CAYP"}
|
package/dist/blob-limits.js
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { SYNCULAR_ERROR_DEFINITIONS } from '@syncular/core';
|
|
2
|
-
import { SyncularClientError } from './errors.js';
|
|
3
|
-
export const DEFAULT_SYNCULAR_BROWSER_MAX_BLOB_PAYLOAD_BYTES = 64 * 1024 * 1024;
|
|
4
|
-
export function resolveSyncularBlobLimits(limits) {
|
|
5
|
-
return {
|
|
6
|
-
maxPayloadBytes: normalizeLimit(limits?.maxPayloadBytes, DEFAULT_SYNCULAR_BROWSER_MAX_BLOB_PAYLOAD_BYTES),
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
export function syncularBlobInputSize(data) {
|
|
10
|
-
if (data instanceof Uint8Array)
|
|
11
|
-
return data.byteLength;
|
|
12
|
-
const maybeSized = data;
|
|
13
|
-
return typeof maybeSized.size === 'number' ? maybeSized.size : 0;
|
|
14
|
-
}
|
|
15
|
-
export function assertSyncularBlobPayloadLimit(args) {
|
|
16
|
-
const limits = resolveSyncularBlobLimits(args.limits);
|
|
17
|
-
if (args.size <= limits.maxPayloadBytes)
|
|
18
|
-
return;
|
|
19
|
-
const error = createSyncularBlobTooLargeError({
|
|
20
|
-
operation: args.operation,
|
|
21
|
-
size: args.size,
|
|
22
|
-
maxPayloadBytes: limits.maxPayloadBytes,
|
|
23
|
-
options: args.options,
|
|
24
|
-
refHash: args.refHash,
|
|
25
|
-
});
|
|
26
|
-
args.diagnostics?.(createSyncularBlobLimitDiagnostic(error));
|
|
27
|
-
throw error;
|
|
28
|
-
}
|
|
29
|
-
function createSyncularBlobTooLargeError(args) {
|
|
30
|
-
const definition = SYNCULAR_ERROR_DEFINITIONS['blob.too_large'];
|
|
31
|
-
return new SyncularClientError({
|
|
32
|
-
code: 'blob.too_large',
|
|
33
|
-
category: definition.category,
|
|
34
|
-
retryable: definition.retryable,
|
|
35
|
-
recommendedAction: definition.recommendedAction,
|
|
36
|
-
message: `Syncular blob ${args.operation} payload is ${args.size} bytes; max is ${args.maxPayloadBytes} bytes.`,
|
|
37
|
-
details: {
|
|
38
|
-
operation: args.operation,
|
|
39
|
-
size: args.size,
|
|
40
|
-
maxPayloadBytes: args.maxPayloadBytes,
|
|
41
|
-
...(args.refHash ? { hash: args.refHash } : {}),
|
|
42
|
-
...(args.options?.mimeType ? { mimeType: args.options.mimeType } : {}),
|
|
43
|
-
...(args.options?.immediate !== undefined
|
|
44
|
-
? { immediate: args.options.immediate }
|
|
45
|
-
: {}),
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function createSyncularBlobLimitDiagnostic(error) {
|
|
50
|
-
return {
|
|
51
|
-
at: Date.now(),
|
|
52
|
-
level: 'warn',
|
|
53
|
-
source: 'blob',
|
|
54
|
-
code: error.code,
|
|
55
|
-
message: error.message,
|
|
56
|
-
details: error.details,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
function normalizeLimit(value, fallback) {
|
|
60
|
-
if (value === undefined)
|
|
61
|
-
return fallback;
|
|
62
|
-
if (!Number.isFinite(value) || value < 0)
|
|
63
|
-
return fallback;
|
|
64
|
-
return Math.floor(value);
|
|
65
|
-
}
|
|
66
|
-
//# sourceMappingURL=blob-limits.js.map
|
package/dist/blob-limits.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"blob-limits.js","sourceRoot":"","sources":["../src/blob-limits.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge-client.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { type SyncAuthLeaseIssueRequest, type SyncOperation } from '@syncular/core';
|
|
2
|
-
import { type Dialect } from 'kysely';
|
|
3
|
-
import type { SyncularBlobClientLike, SyncularClientLike } from './client';
|
|
4
|
-
import { type MutationReceipt } from './mutations';
|
|
5
|
-
import type { SyncularAuthLeaseRecord, SyncularClientEventSink, SyncularClientEventType, SyncularConflictResolution, SyncularConflictStats, SyncularConflictSummary, SyncularConnectionState, SyncularDiagnosticSnapshot, SyncularLifecycleState, SyncularOutboxStats, SyncularPresenceEntry, SyncularPresenceSink, SyncularSubscriptionSpec, SyncularSyncRequestOptions, SyncularSyncResult } from './types';
|
|
6
|
-
export interface SyncularBridgeQueryRequest {
|
|
7
|
-
sql: string;
|
|
8
|
-
parameters: readonly unknown[];
|
|
9
|
-
}
|
|
10
|
-
export interface SyncularBridgeQueryResult<Row extends Record<string, unknown> = Record<string, unknown>> {
|
|
11
|
-
rows: Row[];
|
|
12
|
-
numAffectedRows?: bigint | number | string;
|
|
13
|
-
insertId?: bigint | number | string | null;
|
|
14
|
-
}
|
|
15
|
-
export interface SyncularBridgeMutationBatch {
|
|
16
|
-
operations: SyncOperation[];
|
|
17
|
-
}
|
|
18
|
-
export interface SyncularBridgeStatus {
|
|
19
|
-
lifecycle?: SyncularLifecycleState;
|
|
20
|
-
connection?: SyncularConnectionState;
|
|
21
|
-
outbox?: SyncularOutboxStats | null;
|
|
22
|
-
conflicts?: SyncularConflictStats | null;
|
|
23
|
-
}
|
|
24
|
-
export interface SyncularBridgePresence {
|
|
25
|
-
get<TMetadata = Record<string, unknown>>(scopeKey: string): SyncularPresenceEntry<TMetadata>[];
|
|
26
|
-
join(scopeKey: string, metadata?: Record<string, unknown>): void;
|
|
27
|
-
leave(scopeKey: string): void;
|
|
28
|
-
updateMetadata(scopeKey: string, metadata: Record<string, unknown>): void;
|
|
29
|
-
onChange<TMetadata = Record<string, unknown>>(listener: SyncularPresenceSink<TMetadata>): () => void;
|
|
30
|
-
}
|
|
31
|
-
export interface SyncularBridgeConflicts {
|
|
32
|
-
list(): Promise<SyncularConflictSummary[]>;
|
|
33
|
-
retryKeepLocal(id: string): Promise<string>;
|
|
34
|
-
resolve(id: string, resolution: SyncularConflictResolution): Promise<void>;
|
|
35
|
-
}
|
|
36
|
-
export interface SyncularBridge {
|
|
37
|
-
open?(): Promise<void> | void;
|
|
38
|
-
close?(): Promise<void> | void;
|
|
39
|
-
executeSql<Row extends Record<string, unknown> = Record<string, unknown>>(request: SyncularBridgeQueryRequest): Promise<SyncularBridgeQueryResult<Row>> | SyncularBridgeQueryResult<Row>;
|
|
40
|
-
applyMutationsCommit(batch: SyncularBridgeMutationBatch): Promise<string | MutationReceipt> | string | MutationReceipt;
|
|
41
|
-
applyLeasedMutationsCommit?(batch: SyncularBridgeMutationBatch): Promise<string | MutationReceipt> | string | MutationReceipt;
|
|
42
|
-
sync?(): Promise<SyncularSyncResult>;
|
|
43
|
-
resumeFromBackground?(options?: SyncularSyncRequestOptions): Promise<SyncularSyncResult>;
|
|
44
|
-
start?(): Promise<void>;
|
|
45
|
-
stop?(): Promise<void>;
|
|
46
|
-
setSubscriptions?(subscriptions: readonly SyncularSubscriptionSpec[]): Promise<void>;
|
|
47
|
-
getStatus?(): Promise<SyncularBridgeStatus> | SyncularBridgeStatus;
|
|
48
|
-
issueAuthLease?(request: SyncAuthLeaseIssueRequest): Promise<SyncularAuthLeaseRecord>;
|
|
49
|
-
upsertAuthLease?(lease: SyncularAuthLeaseRecord): Promise<void>;
|
|
50
|
-
authLease?(leaseId: string): Promise<SyncularAuthLeaseRecord | null>;
|
|
51
|
-
activeAuthLeases?(actorId?: string | null, nowMs?: number): Promise<SyncularAuthLeaseRecord[]>;
|
|
52
|
-
diagnosticSnapshot?(): Promise<SyncularDiagnosticSnapshot>;
|
|
53
|
-
on?<T extends SyncularClientEventType>(event: T, listener: SyncularClientEventSink<T>): () => void;
|
|
54
|
-
presence?: SyncularBridgePresence;
|
|
55
|
-
conflicts?: SyncularBridgeConflicts;
|
|
56
|
-
blobs?: Partial<SyncularBlobClientLike>;
|
|
57
|
-
}
|
|
58
|
-
export interface CreateSyncularBridgeClientOptions {
|
|
59
|
-
bridge: SyncularBridge;
|
|
60
|
-
sync?: {
|
|
61
|
-
autoSyncAfterMutation?: boolean;
|
|
62
|
-
};
|
|
63
|
-
idColumn?: string;
|
|
64
|
-
versionColumn?: string | null;
|
|
65
|
-
omitColumns?: readonly string[];
|
|
66
|
-
}
|
|
67
|
-
export declare function createSyncularBridgeDialect(bridge: SyncularBridge): Dialect;
|
|
68
|
-
export declare function createSyncularBridgeClient<DB>(options: CreateSyncularBridgeClientOptions): Promise<SyncularClientLike<DB>>;
|
|
69
|
-
//# sourceMappingURL=bridge-client.d.ts.map
|