@syncular/client 0.1.2 → 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/dist/client.d.ts
CHANGED
|
@@ -1,78 +1,329 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SyncClient — the B3 client protocol core (SPEC.md §§3–8 client side).
|
|
3
|
+
*
|
|
4
|
+
* A plain library running on whatever thread it is constructed on
|
|
5
|
+
* (worker-OPTIONAL, REVISE B3): storage behind `ClientDatabase`, network
|
|
6
|
+
* behind `SyncTransport`/`SegmentDownloader`/`RealtimeConnector`, multi-tab
|
|
7
|
+
* ownership behind `LeaderLock`. One combined push+pull request per
|
|
8
|
+
* `sync()` round (§7.2); local reads go straight to the database.
|
|
9
|
+
*/
|
|
10
|
+
import { type RowValue, type ScopeMap, type WakeReason } from '@syncular/core';
|
|
11
|
+
import { type BlobRef, type BlobTransport, type CachedBlob } from './blob.js';
|
|
12
|
+
import type { ClientDatabase, SqlRow, SqlValue } from './database.js';
|
|
13
|
+
import type { EncryptionConfig } from './encryption.js';
|
|
14
|
+
import { type InvalidationListener } from './invalidation.js';
|
|
15
|
+
import { type LeaderLock } from './leader-lock.js';
|
|
16
|
+
import { type OutboxCommit, type OutboxOperation } from './outbox.js';
|
|
17
|
+
import { type ClientSchema } from './schema.js';
|
|
18
|
+
import { type SubscriptionRecord } from './state.js';
|
|
19
|
+
import type { RealtimeConnector, SegmentDownloader, SyncTransport } from './transport.js';
|
|
20
|
+
import { type WindowBase } from './window.js';
|
|
21
|
+
export type MutationInput = {
|
|
22
|
+
readonly table: string;
|
|
23
|
+
readonly op: 'upsert';
|
|
24
|
+
/** Full-row values keyed by column name (§6.1: full row payloads). */
|
|
25
|
+
readonly values: Readonly<Record<string, unknown>>;
|
|
26
|
+
readonly baseVersion?: number;
|
|
27
|
+
} | {
|
|
28
|
+
readonly table: string;
|
|
29
|
+
readonly op: 'delete';
|
|
30
|
+
readonly rowId: string;
|
|
31
|
+
readonly baseVersion?: number;
|
|
32
|
+
};
|
|
33
|
+
/** A §6.3 conflict result, surfaced to the app — never auto-resolved. */
|
|
34
|
+
export interface ConflictRecord {
|
|
35
|
+
readonly clientCommitId: string;
|
|
36
|
+
readonly opIndex: number;
|
|
37
|
+
readonly table: string;
|
|
38
|
+
readonly rowId: string;
|
|
39
|
+
readonly code: string;
|
|
40
|
+
readonly message: string;
|
|
41
|
+
readonly serverVersion: number;
|
|
42
|
+
/** The current server row, decoded — resolve without a round-trip. */
|
|
43
|
+
readonly serverRow: Readonly<Record<string, RowValue>>;
|
|
44
|
+
/** The losing local operation (absent only for malformed op indexes). */
|
|
45
|
+
readonly operation?: OutboxOperation;
|
|
12
46
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
hasConflicts: boolean;
|
|
22
|
-
requiresAction: boolean;
|
|
47
|
+
/** A non-conflict `error` result from a rejected commit (§6.3). */
|
|
48
|
+
export interface RejectionRecord {
|
|
49
|
+
readonly clientCommitId: string;
|
|
50
|
+
readonly opIndex: number;
|
|
51
|
+
readonly code: string;
|
|
52
|
+
readonly message: string;
|
|
53
|
+
readonly retryable: boolean;
|
|
54
|
+
readonly operation?: OutboxOperation;
|
|
23
55
|
}
|
|
24
|
-
export interface
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
uploaded: number;
|
|
28
|
-
failed: number;
|
|
29
|
-
}>;
|
|
30
|
-
retrieve(ref: BlobRef): Promise<Uint8Array>;
|
|
56
|
+
export interface SchemaFloor {
|
|
57
|
+
readonly requiredSchemaVersion?: number;
|
|
58
|
+
readonly latestSchemaVersion?: number;
|
|
31
59
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
60
|
+
/**
|
|
61
|
+
* §7.3.5: the client's view of its current auth lease — opaque state, the
|
|
62
|
+
* mirror of `schemaFloor`. `leaseId`/`expiresAtMs` come from the last
|
|
63
|
+
* `LEASE` frame; `errorCode` is set (and syncing stops on the lease) when
|
|
64
|
+
* the server rejects a round with a request-level lease code (§7.3.4).
|
|
65
|
+
* The lease is never cryptographically verified by the client (§7.3
|
|
66
|
+
* non-goal 1), and lease errors never purge local data (§7.3.4).
|
|
67
|
+
*/
|
|
68
|
+
export interface LeaseState {
|
|
69
|
+
readonly leaseId?: string;
|
|
70
|
+
readonly expiresAtMs?: number;
|
|
71
|
+
/** `sync.auth_lease_required` | `sync.auth_lease_revoked` when stopped. */
|
|
72
|
+
readonly errorCode?: string;
|
|
38
73
|
}
|
|
39
|
-
export interface
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
74
|
+
export interface SyncSummary {
|
|
75
|
+
/** Commits sent in this round's push half. */
|
|
76
|
+
readonly pushed: number;
|
|
77
|
+
/** clientCommitIds drained (`applied` or `cached`, §6.3). */
|
|
78
|
+
readonly applied: readonly string[];
|
|
79
|
+
/** clientCommitIds rejected and dropped from the outbox. */
|
|
80
|
+
readonly rejected: readonly string[];
|
|
81
|
+
/** clientCommitIds kept for retry (`sync.idempotency_cache_miss`). */
|
|
82
|
+
readonly retryable: readonly string[];
|
|
83
|
+
/** New conflict records surfaced this round. */
|
|
84
|
+
readonly conflicts: readonly ConflictRecord[];
|
|
85
|
+
/** `COMMIT` frames applied locally. */
|
|
86
|
+
readonly commitsApplied: number;
|
|
87
|
+
/** Snapshot rows applied from segments. */
|
|
88
|
+
readonly segmentRowsApplied: number;
|
|
89
|
+
/** Subscriptions still mid-bootstrap (resume token pending). */
|
|
90
|
+
readonly bootstrapping: readonly string[];
|
|
91
|
+
/** Subscriptions reset via `sync.cursor_expired` (re-pull needed). */
|
|
92
|
+
readonly resets: readonly string[];
|
|
93
|
+
/** Subscriptions revoked this round (§3.3 purge ran). */
|
|
94
|
+
readonly revoked: readonly string[];
|
|
95
|
+
/** Subscriptions stopped by a fatal configuration error (§3.3/§5.6
|
|
96
|
+
* fail-closed: no local scope-column mapping). */
|
|
97
|
+
readonly failed: readonly string[];
|
|
98
|
+
/** Present when the server declared a schema floor — syncing stopped. */
|
|
99
|
+
readonly schemaFloor?: SchemaFloor;
|
|
100
|
+
/** §6.1 splitBatch: outbox commits held back from THIS request because
|
|
101
|
+
* including them would exceed the per-request operation cap. They remain
|
|
102
|
+
* queued; sync-needed stays raised and `syncUntilIdle` keeps going. */
|
|
103
|
+
readonly deferredCommits?: number;
|
|
43
104
|
}
|
|
44
|
-
export interface
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
105
|
+
export interface SyncClientLimits {
|
|
106
|
+
readonly limitCommits?: number;
|
|
107
|
+
readonly limitSnapshotRows?: number;
|
|
108
|
+
readonly maxSnapshotPages?: number;
|
|
109
|
+
/**
|
|
110
|
+
* §4.2 accept bitmask; defaults to inline + external rows (0b0011)
|
|
111
|
+
* plus sqlite images (bit 2) when the database backend implements
|
|
112
|
+
* `withSqliteImage` and a segment downloader is configured (§5.3).
|
|
113
|
+
*/
|
|
114
|
+
readonly accept?: number;
|
|
115
|
+
}
|
|
116
|
+
export interface SyncClientConfig {
|
|
117
|
+
readonly database: ClientDatabase;
|
|
118
|
+
readonly schema: ClientSchema;
|
|
119
|
+
readonly transport: SyncTransport;
|
|
120
|
+
readonly segments?: SegmentDownloader;
|
|
121
|
+
/** Blob upload/download (§5.9). Required to use `uploadBlob`/`fetchBlob`. */
|
|
122
|
+
readonly blobs?: BlobTransport;
|
|
123
|
+
/**
|
|
124
|
+
* §5.9.7 B1 blob-cache size cap (bytes). When the sum of cached body sizes
|
|
125
|
+
* exceeds this, zero-ref, non-pinned bodies are evicted LRU-first after each
|
|
126
|
+
* cache write (referenced/pinned bodies are never evicted — correctness
|
|
127
|
+
* beats the cap). Absent ⇒ retain until storage pressure (the shipped
|
|
128
|
+
* default; a referenced body always stays resolvable without a re-download).
|
|
129
|
+
*/
|
|
130
|
+
readonly blobCacheMaxBytes?: number;
|
|
131
|
+
readonly realtime?: RealtimeConnector;
|
|
132
|
+
/** Stable per-device id (§1.5); defaults to a persisted random UUID. */
|
|
133
|
+
readonly clientId?: string;
|
|
134
|
+
readonly leaderLock?: LeaderLock;
|
|
135
|
+
readonly lockName?: string;
|
|
136
|
+
readonly limits?: SyncClientLimits;
|
|
137
|
+
readonly now?: () => number;
|
|
138
|
+
/** §8: hello `requiresSync` or a wake-up — run a pull soon. */
|
|
139
|
+
readonly onSyncNeeded?: (reason: 'hello' | WakeReason) => void;
|
|
140
|
+
readonly onConflict?: (conflict: ConflictRecord) => void;
|
|
141
|
+
/**
|
|
142
|
+
* §7.4.5: the schema-bump `upgrading` state changed. `true` when a reset
|
|
143
|
+
* (wipe + re-bootstrap) began, `false` when the first post-reset
|
|
144
|
+
* bootstrap round reached idle — the app's cue to re-run live queries.
|
|
145
|
+
*/
|
|
146
|
+
readonly onUpgrading?: (upgrading: boolean) => void;
|
|
147
|
+
/**
|
|
148
|
+
* §8.6 presence: a scope-mate's presence on a key this client holds
|
|
149
|
+
* changed (join/update/leave). Fired after the local presence map is
|
|
150
|
+
* updated — the app's cue to re-render who's-online.
|
|
151
|
+
*/
|
|
152
|
+
readonly onPresence?: (scopeKey: string) => void;
|
|
153
|
+
/**
|
|
154
|
+
* §5.11 client-side encryption. Supplies the key material (`keyProvider`)
|
|
155
|
+
* and key selection (`keyIdFor`) for columns the generated schema marks
|
|
156
|
+
* `encrypted`. Absent ⇒ no columns are encrypted (a schema with encrypted
|
|
157
|
+
* columns then fails loud on the first encode/apply — a missing key is
|
|
158
|
+
* `client.decrypt_failed`, never silent plaintext).
|
|
159
|
+
*/
|
|
160
|
+
readonly encryption?: EncryptionConfig;
|
|
161
|
+
}
|
|
162
|
+
/** §8.6 a peer's ephemeral presence document on a scope key. */
|
|
163
|
+
export interface PresencePeer {
|
|
164
|
+
readonly actorId: string;
|
|
165
|
+
readonly clientId: string;
|
|
166
|
+
readonly doc: Record<string, unknown>;
|
|
65
167
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
168
|
+
export interface SubscribeInput {
|
|
169
|
+
readonly id: string;
|
|
170
|
+
readonly table: string;
|
|
171
|
+
readonly scopes: ScopeMap;
|
|
172
|
+
readonly params?: string;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* The live state of a window base (§4.8) — the completeness oracle (I3),
|
|
176
|
+
* as plain serializable data so it crosses the worker/follower boundary
|
|
177
|
+
* unchanged. `units` are the scope values currently windowed-in; a query
|
|
178
|
+
* touching only these is answerable in full locally. Use
|
|
179
|
+
* {@link windowComplete} for the per-value verdict a live query renders
|
|
180
|
+
* "this data may be partial" from.
|
|
181
|
+
*/
|
|
182
|
+
export interface WindowState {
|
|
183
|
+
/** Windowed-in units for this base, ordered by value. */
|
|
184
|
+
readonly units: readonly string[];
|
|
185
|
+
}
|
|
186
|
+
/** True iff `unit` is windowed-in for this snapshot (a registry hit, I3). */
|
|
187
|
+
export declare function windowComplete(state: WindowState, unit: string): boolean;
|
|
188
|
+
export declare class SyncClient {
|
|
69
189
|
#private;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
constructor(client: LifecycleClient, options?: SyncularClientLifecycleOptions);
|
|
190
|
+
constructor(config: SyncClientConfig);
|
|
191
|
+
/** Acquire leadership, create local tables, resolve the clientId. */
|
|
73
192
|
start(): Promise<void>;
|
|
74
|
-
|
|
75
|
-
|
|
193
|
+
close(): Promise<void>;
|
|
194
|
+
get clientId(): string;
|
|
195
|
+
/** The underlying database — raw SQL is the local query API (B3). */
|
|
196
|
+
get database(): ClientDatabase;
|
|
197
|
+
query(sql: string, params?: readonly SqlValue[]): SqlRow[];
|
|
198
|
+
/**
|
|
199
|
+
* Subscribe to fine-grained invalidation. The callback fires ONCE per
|
|
200
|
+
* apply batch (never per row, I1) with the `{tables, scopeKeys}` touched
|
|
201
|
+
* this batch (§3.1 vocabulary, I2). Returns an unsubscribe function.
|
|
202
|
+
*
|
|
203
|
+
* Every local mutation flows through the same choke point: `COMMIT`
|
|
204
|
+
* apply, segment apply, the optimistic overlay rebuild, the §3.3 purge,
|
|
205
|
+
* the §7.4.3 schema-bump reset, and local `mutate`. `tables` is the
|
|
206
|
+
* reliable floor; `scopeKeys` refines it wherever the source carried
|
|
207
|
+
* per-row scopes (COMMIT changes) or a scope map (segments/purge).
|
|
208
|
+
*/
|
|
209
|
+
onInvalidate(listener: InvalidationListener): () => void;
|
|
210
|
+
/**
|
|
211
|
+
* Stage a blob for attachment (§5.9.7): hash the bytes into the content
|
|
212
|
+
* address, cache them locally, and queue the upload (flushed before the
|
|
213
|
+
* next push — B4). Returns the canonical `BlobRef` **string** to store in
|
|
214
|
+
* a `blob_ref` column of a mutation. The referencing row MUST be written
|
|
215
|
+
* (via `mutate`) after this call so upload-before-push holds (§5.9.3).
|
|
216
|
+
*/
|
|
217
|
+
uploadBlob(bytes: Uint8Array, options?: {
|
|
218
|
+
readonly mediaType?: string;
|
|
219
|
+
readonly name?: string;
|
|
220
|
+
}): Promise<BlobRef>;
|
|
221
|
+
/** Serialize a BlobRef to the canonical string a `blob_ref` column holds. */
|
|
222
|
+
blobRefString(ref: BlobRef): string;
|
|
223
|
+
/**
|
|
224
|
+
* Resolve blob bytes for a `blobId` (§5.9.7): a content-addressed cache
|
|
225
|
+
* hit serves without a network fetch (B1); a miss downloads via the blob
|
|
226
|
+
* transport (§5.9.5), verifies the content address, caches, and returns.
|
|
227
|
+
* Accepts a raw `blob_ref` column string or a bare `blobId`.
|
|
228
|
+
*/
|
|
229
|
+
fetchBlob(blobIdOrRef: string): Promise<CachedBlob>;
|
|
230
|
+
/** Flush any queued blob uploads (§5.9.7 B4); safe to call standalone. */
|
|
231
|
+
flushBlobUploads(): Promise<void>;
|
|
232
|
+
get conflicts(): readonly ConflictRecord[];
|
|
233
|
+
get rejections(): readonly RejectionRecord[];
|
|
234
|
+
/** Non-undefined once the server declared a schema floor (§1.6). */
|
|
235
|
+
get schemaFloor(): SchemaFloor | undefined;
|
|
236
|
+
/**
|
|
237
|
+
* §7.4.5: true while a schema-bump reset + first re-bootstrap is in
|
|
238
|
+
* flight — the app's "upgrading…" cue. Clears when the first post-reset
|
|
239
|
+
* bootstrap round reaches idle (every subscription past its fresh
|
|
240
|
+
* bootstrap).
|
|
241
|
+
*/
|
|
242
|
+
get upgrading(): boolean;
|
|
243
|
+
/**
|
|
244
|
+
* §7.3.5: the current auth-lease state (opaque). Undefined until a
|
|
245
|
+
* `LEASE` frame arrives. `errorCode` is set when a round was rejected
|
|
246
|
+
* with a request-level lease code — syncing on the lease has stopped.
|
|
247
|
+
*/
|
|
248
|
+
get leaseState(): LeaseState | undefined;
|
|
249
|
+
/** §7.3.5: remaining lease validity in ms (`expiresAtMs − now`), or
|
|
250
|
+
* `undefined` if no lease is held. Negative once expired. */
|
|
251
|
+
leaseRemainingMs(now?: number): number | undefined;
|
|
252
|
+
/** True when syncing is stopped pending a client upgrade. */
|
|
253
|
+
get stopped(): boolean;
|
|
254
|
+
/** §8: a hello/wake-up asked for a pull that has not run yet. */
|
|
255
|
+
get syncNeeded(): boolean;
|
|
256
|
+
/**
|
|
257
|
+
* §8.6 presence on a scope key: the current peers present there (a map
|
|
258
|
+
* of `actorId clientId` → peer). Empty for a key with no present peers.
|
|
259
|
+
* Ephemeral — reflects only what the socket has delivered.
|
|
260
|
+
*/
|
|
261
|
+
presence(scopeKey: string): readonly PresencePeer[];
|
|
262
|
+
/** Every scope key this client currently has presence state for. */
|
|
263
|
+
presenceKeys(): string[];
|
|
264
|
+
/**
|
|
265
|
+
* §8.6: subscribe to presence changes (join/update/leave on any held key).
|
|
266
|
+
* The subscribable twin of the `onPresence` config callback — React's
|
|
267
|
+
* `usePresence` targets this so many components can watch one client.
|
|
268
|
+
* Returns an unsubscribe function.
|
|
269
|
+
*/
|
|
270
|
+
onPresence(listener: (scopeKey: string) => void): () => void;
|
|
271
|
+
/**
|
|
272
|
+
* §8.6.2 publish (or clear, `doc: null`) this client's presence document
|
|
273
|
+
* for `scopeKey`. Requires a live socket; the document is ephemeral and
|
|
274
|
+
* lost on disconnect (the server emits leave). Authorization is the
|
|
275
|
+
* connection's registration (§8.6.3) — an unheld key is rejected loudly
|
|
276
|
+
* by the server with `presence.forbidden`.
|
|
277
|
+
*/
|
|
278
|
+
setPresence(scopeKey: string, doc: Record<string, unknown> | null): void;
|
|
279
|
+
subscriptions(): SubscriptionRecord[];
|
|
280
|
+
subscription(id: string): SubscriptionRecord | undefined;
|
|
281
|
+
pendingCommits(): OutboxCommit[];
|
|
282
|
+
subscribe(input: SubscribeInput): void;
|
|
283
|
+
unsubscribe(id: string): void;
|
|
284
|
+
/**
|
|
285
|
+
* Set the live window units for a base (§4.8): a value-sharded family of
|
|
286
|
+
* subscriptions, one per unit. Computes the diff against the registry —
|
|
287
|
+
* added units get fresh subscriptions (image-lane bootstrap on the next
|
|
288
|
+
* sync); removed units are unsubscribed and evicted, fused in one local
|
|
289
|
+
* transaction (E1–E4). Idempotent: calling with the same units is a
|
|
290
|
+
* no-op. Re-entry (a unit removed then re-added) cancels any deferred
|
|
291
|
+
* eviction and fresh-bootstraps.
|
|
292
|
+
*
|
|
293
|
+
* The change takes effect on the next `sync()`/socket round — the pull's
|
|
294
|
+
* subscription list (now with the added unit, without the removed one)
|
|
295
|
+
* re-registers realtime at round end (§8.7). No socket cycle needed.
|
|
296
|
+
*/
|
|
297
|
+
setWindow(base: WindowBase, units: readonly string[]): Promise<void>;
|
|
298
|
+
/**
|
|
299
|
+
* The completeness oracle (§4.8 I3): which units of a base are windowed-in
|
|
300
|
+
* locally, and a per-unit verdict a live query renders "may be partial"
|
|
301
|
+
* from. A query whose scope footprint includes an un-windowed unit is
|
|
302
|
+
* NOT answerable in full — the host widens or shows partial, never
|
|
303
|
+
* silently-complete.
|
|
304
|
+
*/
|
|
305
|
+
windowState(base: WindowBase): WindowState;
|
|
306
|
+
/**
|
|
307
|
+
* Record one atomic local commit (§7.1): appended to the outbox in
|
|
308
|
+
* schema-agnostic form and applied optimistically to the local mirror.
|
|
309
|
+
* Returns the generated `clientCommitId`.
|
|
310
|
+
*/
|
|
311
|
+
mutate(mutations: readonly MutationInput[]): string;
|
|
312
|
+
/**
|
|
313
|
+
* One combined push+pull round (§1.5, §7.2). The core owns one loop: a
|
|
314
|
+
* concurrent `sync()` while one is already outstanding is rejected loudly
|
|
315
|
+
* (the app must coalesce its own wake-ups, §8.4) — this check is
|
|
316
|
+
* SYNCHRONOUS so the second caller sees the first still in flight before
|
|
317
|
+
* the op chain would otherwise queue it. The round then runs serialized on
|
|
318
|
+
* the operation chain so it never interleaves with a delta apply or a
|
|
319
|
+
* `setWindow` at an await point.
|
|
320
|
+
*/
|
|
321
|
+
sync(): Promise<SyncSummary>;
|
|
322
|
+
/**
|
|
323
|
+
* Pull repeatedly until quiescent: no commits delivered, no bootstrap
|
|
324
|
+
* pages pending, no resets to recover (§4.5 "pull again" SHOULD).
|
|
325
|
+
*/
|
|
326
|
+
syncUntilIdle(maxRounds?: number): Promise<SyncSummary>;
|
|
327
|
+
connectRealtime(): Promise<void>;
|
|
328
|
+
disconnectRealtime(): void;
|
|
76
329
|
}
|
|
77
|
-
export {};
|
|
78
|
-
//# sourceMappingURL=client.d.ts.map
|