@syncular/client 0.0.6-95 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +713 -11
- package/dist/auth-leases.d.ts +11 -0
- package/dist/auth-leases.d.ts.map +1 -0
- package/dist/auth-leases.js +140 -0
- package/dist/auth-leases.js.map +1 -0
- package/dist/blob-limits.d.ts +15 -0
- package/dist/blob-limits.d.ts.map +1 -0
- package/dist/blob-limits.js +66 -0
- package/dist/blob-limits.js.map +1 -0
- package/dist/bridge-client.d.ts +69 -0
- package/dist/bridge-client.d.ts.map +1 -0
- package/dist/bridge-client.js +282 -0
- package/dist/bridge-client.js.map +1 -0
- package/dist/client-config.d.ts +6 -0
- package/dist/client-config.d.ts.map +1 -0
- package/dist/client-config.js +18 -0
- package/dist/client-config.js.map +1 -0
- package/dist/client.d.ts +65 -397
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +150 -960
- package/dist/client.js.map +1 -1
- package/dist/command-history.d.ts +35 -0
- package/dist/command-history.d.ts.map +1 -0
- package/dist/command-history.js +378 -0
- package/dist/command-history.js.map +1 -0
- package/dist/console-diagnostics.d.ts +33 -0
- package/dist/console-diagnostics.d.ts.map +1 -0
- package/dist/console-diagnostics.js +496 -0
- package/dist/console-diagnostics.js.map +1 -0
- package/dist/crdt-yjs/index.d.ts +4 -0
- package/dist/crdt-yjs/index.d.ts.map +1 -0
- package/dist/crdt-yjs/index.js +4 -0
- package/dist/crdt-yjs/index.js.map +1 -0
- package/dist/crdt-yjs/webview-host-facade.d.ts +126 -0
- package/dist/crdt-yjs/webview-host-facade.d.ts.map +1 -0
- package/dist/crdt-yjs/webview-host-facade.js +284 -0
- package/dist/crdt-yjs/webview-host-facade.js.map +1 -0
- package/dist/crdt-yjs/yjs-document-field-adapter.d.ts +153 -0
- package/dist/crdt-yjs/yjs-document-field-adapter.d.ts.map +1 -0
- package/dist/crdt-yjs/yjs-document-field-adapter.js +406 -0
- package/dist/crdt-yjs/yjs-document-field-adapter.js.map +1 -0
- package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts +73 -0
- package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts.map +1 -0
- package/dist/crdt-yjs/yjs-prosemirror-bridge.js +169 -0
- package/dist/crdt-yjs/yjs-prosemirror-bridge.js.map +1 -0
- package/dist/database.d.ts +83 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +916 -0
- package/dist/database.js.map +1 -0
- package/dist/diagnostics.d.ts +10 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +83 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/errors.d.ts +24 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +211 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated-bridge.d.ts +365 -0
- package/dist/generated-bridge.d.ts.map +1 -0
- package/dist/generated-bridge.js +250 -0
- package/dist/generated-bridge.js.map +1 -0
- package/dist/index.d.ts +13 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -25
- package/dist/index.js.map +1 -1
- package/dist/mutations.d.ts +4 -72
- package/dist/mutations.d.ts.map +1 -1
- package/dist/mutations.js +2 -568
- package/dist/mutations.js.map +1 -1
- package/dist/network.d.ts +3 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +17 -0
- package/dist/network.js.map +1 -0
- package/dist/react/index.d.ts +169 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +628 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react-native/index.d.ts +35 -0
- package/dist/react-native/index.d.ts.map +1 -0
- package/dist/react-native/index.js +49 -0
- package/dist/react-native/index.js.map +1 -0
- package/dist/runtime-contract.d.ts +13 -0
- package/dist/runtime-contract.d.ts.map +1 -0
- package/dist/runtime-contract.js +24 -0
- package/dist/runtime-contract.js.map +1 -0
- package/dist/rust-client.d.ts +106 -0
- package/dist/rust-client.d.ts.map +1 -0
- package/dist/rust-client.js +936 -0
- package/dist/rust-client.js.map +1 -0
- package/dist/sentry.d.ts +35 -0
- package/dist/sentry.d.ts.map +1 -0
- package/dist/sentry.js +155 -0
- package/dist/sentry.js.map +1 -0
- package/dist/sql-safety.d.ts +3 -0
- package/dist/sql-safety.d.ts.map +1 -0
- package/dist/sql-safety.js +62 -0
- package/dist/sql-safety.js.map +1 -0
- package/dist/syncular-runtime-artifacts.json +61 -0
- package/dist/tauri/index.d.ts +35 -0
- package/dist/tauri/index.d.ts.map +1 -0
- package/dist/tauri/index.js +114 -0
- package/dist/tauri/index.js.map +1 -0
- package/dist/types.d.ts +1059 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/wasm/.syncular-wasm-profile +1 -0
- package/dist/wasm/syncular-runtime-artifact.json +21 -0
- package/dist/wasm/syncular.d.ts +207 -0
- package/dist/wasm/syncular.js +2341 -0
- package/dist/wasm/syncular_bg.wasm +0 -0
- package/dist/wasm/syncular_bg.wasm.d.ts +97 -0
- package/dist/wasm-bindings/runtime-contract.d.ts +22 -0
- package/dist/wasm-bindings/runtime-contract.d.ts.map +1 -0
- package/dist/wasm-bindings/runtime-contract.js +112 -0
- package/dist/wasm-bindings/runtime-contract.js.map +1 -0
- package/dist/wasm-core/.syncular-wasm-profile +1 -0
- package/dist/wasm-core/syncular-runtime-artifact.json +17 -0
- package/dist/wasm-core/syncular.d.ts +162 -0
- package/dist/wasm-core/syncular.js +1847 -0
- package/dist/wasm-core/syncular_bg.wasm +0 -0
- package/dist/wasm-core/syncular_bg.wasm.d.ts +77 -0
- package/dist/wasm-perf/.syncular-wasm-profile +1 -0
- package/dist/wasm-perf/syncular-runtime-artifact.json +21 -0
- package/dist/wasm-perf/syncular.d.ts +207 -0
- package/dist/wasm-perf/syncular.js +2341 -0
- package/dist/wasm-perf/syncular_bg.wasm +0 -0
- package/dist/wasm-perf/syncular_bg.wasm.d.ts +97 -0
- package/dist/wasm-runtime.d.ts +18 -0
- package/dist/wasm-runtime.d.ts.map +1 -0
- package/dist/wasm-runtime.js +28 -0
- package/dist/wasm-runtime.js.map +1 -0
- package/dist/worker-client.d.ts +123 -0
- package/dist/worker-client.d.ts.map +1 -0
- package/dist/worker-client.js +1686 -0
- package/dist/worker-client.js.map +1 -0
- package/dist/worker-entry.d.ts +2 -0
- package/dist/worker-entry.d.ts.map +1 -0
- package/dist/worker-entry.js +479 -0
- package/dist/worker-entry.js.map +1 -0
- package/dist/worker-protocol.d.ts +64 -0
- package/dist/worker-protocol.d.ts.map +1 -0
- package/dist/worker-protocol.js +16 -0
- package/dist/worker-protocol.js.map +1 -0
- package/dist/worker-realtime.d.ts +39 -0
- package/dist/worker-realtime.d.ts.map +1 -0
- package/dist/worker-realtime.js +677 -0
- package/dist/worker-realtime.js.map +1 -0
- package/package.json +124 -17
- package/src/auth-leases.ts +251 -0
- package/src/blob-limits.ts +98 -0
- package/src/bridge-client.ts +512 -0
- package/src/client-config.ts +29 -0
- package/src/client.ts +256 -1414
- package/src/command-history.ts +623 -0
- package/src/console-diagnostics.ts +617 -0
- package/src/crdt-yjs/index.ts +3 -0
- package/src/crdt-yjs/webview-host-facade.ts +477 -0
- package/src/crdt-yjs/yjs-document-field-adapter.ts +733 -0
- package/src/crdt-yjs/yjs-prosemirror-bridge.ts +272 -0
- package/src/database.ts +1342 -0
- package/src/diagnostics.ts +116 -0
- package/src/errors.ts +269 -0
- package/src/generated-bridge.ts +741 -0
- package/src/index.ts +21 -25
- package/src/mutations.ts +12 -821
- package/src/network.ts +32 -0
- package/src/react/index.ts +1036 -0
- package/src/react-native/index.ts +152 -0
- package/src/runtime-contract.ts +48 -0
- package/src/rust-client.ts +1488 -0
- package/src/sentry.ts +215 -0
- package/src/sql-safety.ts +61 -0
- package/src/tauri/index.ts +211 -0
- package/src/types.ts +1356 -0
- package/src/wasm-bindings/generated-wasm-bindings.d.ts +70 -0
- package/src/wasm-bindings/runtime-contract.ts +158 -0
- package/src/wasm-runtime.ts +76 -0
- package/src/worker-client.ts +2215 -0
- package/src/worker-entry.ts +584 -0
- package/src/worker-protocol.ts +109 -0
- package/src/worker-realtime.ts +843 -0
- package/dist/blobs/index.d.ts +0 -7
- package/dist/blobs/index.d.ts.map +0 -1
- package/dist/blobs/index.js +0 -7
- package/dist/blobs/index.js.map +0 -1
- package/dist/blobs/manager.d.ts +0 -345
- package/dist/blobs/manager.d.ts.map +0 -1
- package/dist/blobs/manager.js +0 -749
- package/dist/blobs/manager.js.map +0 -1
- package/dist/blobs/migrate.d.ts +0 -14
- package/dist/blobs/migrate.d.ts.map +0 -1
- package/dist/blobs/migrate.js +0 -59
- package/dist/blobs/migrate.js.map +0 -1
- package/dist/blobs/types.d.ts +0 -62
- package/dist/blobs/types.d.ts.map +0 -1
- package/dist/blobs/types.js +0 -5
- package/dist/blobs/types.js.map +0 -1
- package/dist/conflicts.d.ts +0 -31
- package/dist/conflicts.d.ts.map +0 -1
- package/dist/conflicts.js +0 -112
- package/dist/conflicts.js.map +0 -1
- package/dist/create-client.d.ts +0 -118
- package/dist/create-client.d.ts.map +0 -1
- package/dist/create-client.js +0 -178
- package/dist/create-client.js.map +0 -1
- package/dist/engine/SyncEngine.d.ts +0 -272
- package/dist/engine/SyncEngine.d.ts.map +0 -1
- package/dist/engine/SyncEngine.js +0 -1860
- package/dist/engine/SyncEngine.js.map +0 -1
- package/dist/engine/index.d.ts +0 -6
- package/dist/engine/index.d.ts.map +0 -1
- package/dist/engine/index.js +0 -6
- package/dist/engine/index.js.map +0 -1
- package/dist/engine/types.d.ts +0 -345
- package/dist/engine/types.d.ts.map +0 -1
- package/dist/engine/types.js +0 -7
- package/dist/engine/types.js.map +0 -1
- package/dist/handlers/collection.d.ts +0 -6
- package/dist/handlers/collection.d.ts.map +0 -1
- package/dist/handlers/collection.js +0 -21
- package/dist/handlers/collection.js.map +0 -1
- package/dist/handlers/create-handler.d.ts +0 -120
- package/dist/handlers/create-handler.d.ts.map +0 -1
- package/dist/handlers/create-handler.js +0 -145
- package/dist/handlers/create-handler.js.map +0 -1
- package/dist/handlers/types.d.ts +0 -83
- package/dist/handlers/types.d.ts.map +0 -1
- package/dist/handlers/types.js +0 -5
- package/dist/handlers/types.js.map +0 -1
- package/dist/migrate.d.ts +0 -19
- package/dist/migrate.d.ts.map +0 -1
- package/dist/migrate.js +0 -238
- package/dist/migrate.js.map +0 -1
- package/dist/outbox.d.ts +0 -112
- package/dist/outbox.d.ts.map +0 -1
- package/dist/outbox.js +0 -294
- package/dist/outbox.js.map +0 -1
- package/dist/plugins/incrementing-version.d.ts +0 -34
- package/dist/plugins/incrementing-version.d.ts.map +0 -1
- package/dist/plugins/incrementing-version.js +0 -83
- package/dist/plugins/incrementing-version.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -3
- package/dist/plugins/index.d.ts.map +0 -1
- package/dist/plugins/index.js +0 -3
- package/dist/plugins/index.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -49
- package/dist/plugins/types.d.ts.map +0 -1
- package/dist/plugins/types.js +0 -15
- package/dist/plugins/types.js.map +0 -1
- package/dist/proxy/connection.d.ts +0 -33
- package/dist/proxy/connection.d.ts.map +0 -1
- package/dist/proxy/connection.js +0 -153
- package/dist/proxy/connection.js.map +0 -1
- package/dist/proxy/dialect.d.ts +0 -46
- package/dist/proxy/dialect.d.ts.map +0 -1
- package/dist/proxy/dialect.js +0 -58
- package/dist/proxy/dialect.js.map +0 -1
- package/dist/proxy/driver.d.ts +0 -42
- package/dist/proxy/driver.d.ts.map +0 -1
- package/dist/proxy/driver.js +0 -78
- package/dist/proxy/driver.js.map +0 -1
- package/dist/proxy/index.d.ts +0 -10
- package/dist/proxy/index.d.ts.map +0 -1
- package/dist/proxy/index.js +0 -10
- package/dist/proxy/index.js.map +0 -1
- package/dist/proxy/mutations.d.ts +0 -9
- package/dist/proxy/mutations.d.ts.map +0 -1
- package/dist/proxy/mutations.js +0 -11
- package/dist/proxy/mutations.js.map +0 -1
- package/dist/pull-engine.d.ts +0 -48
- package/dist/pull-engine.d.ts.map +0 -1
- package/dist/pull-engine.js +0 -648
- package/dist/pull-engine.js.map +0 -1
- package/dist/push-engine.d.ts +0 -18
- package/dist/push-engine.d.ts.map +0 -1
- package/dist/push-engine.js +0 -167
- package/dist/push-engine.js.map +0 -1
- package/dist/query/FingerprintCollector.d.ts +0 -18
- package/dist/query/FingerprintCollector.d.ts.map +0 -1
- package/dist/query/FingerprintCollector.js +0 -28
- package/dist/query/FingerprintCollector.js.map +0 -1
- package/dist/query/QueryContext.d.ts +0 -33
- package/dist/query/QueryContext.d.ts.map +0 -1
- package/dist/query/QueryContext.js +0 -16
- package/dist/query/QueryContext.js.map +0 -1
- package/dist/query/fingerprint.d.ts +0 -61
- package/dist/query/fingerprint.d.ts.map +0 -1
- package/dist/query/fingerprint.js +0 -91
- package/dist/query/fingerprint.js.map +0 -1
- package/dist/query/index.d.ts +0 -7
- package/dist/query/index.d.ts.map +0 -1
- package/dist/query/index.js +0 -7
- package/dist/query/index.js.map +0 -1
- package/dist/query/tracked-select.d.ts +0 -18
- package/dist/query/tracked-select.d.ts.map +0 -1
- package/dist/query/tracked-select.js +0 -90
- package/dist/query/tracked-select.js.map +0 -1
- package/dist/schema.d.ts +0 -83
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js +0 -7
- package/dist/schema.js.map +0 -1
- package/dist/subscription-state.d.ts +0 -46
- package/dist/subscription-state.d.ts.map +0 -1
- package/dist/subscription-state.js +0 -185
- package/dist/subscription-state.js.map +0 -1
- package/dist/sync-loop.d.ts +0 -34
- package/dist/sync-loop.d.ts.map +0 -1
- package/dist/sync-loop.js +0 -253
- package/dist/sync-loop.js.map +0 -1
- package/dist/sync.d.ts +0 -32
- package/dist/sync.d.ts.map +0 -1
- package/dist/sync.js +0 -55
- package/dist/sync.js.map +0 -1
- package/dist/utils/id.d.ts +0 -17
- package/dist/utils/id.d.ts.map +0 -1
- package/dist/utils/id.js +0 -46
- package/dist/utils/id.js.map +0 -1
- package/src/blobs/index.ts +0 -7
- package/src/blobs/manager.ts +0 -1027
- package/src/blobs/migrate.ts +0 -67
- package/src/blobs/types.ts +0 -84
- package/src/client.test.ts +0 -417
- package/src/conflicts.ts +0 -171
- package/src/create-client.test.ts +0 -83
- package/src/create-client.ts +0 -330
- package/src/engine/SyncEngine.test.ts +0 -254
- package/src/engine/SyncEngine.ts +0 -2375
- package/src/engine/index.ts +0 -6
- package/src/engine/types.ts +0 -419
- package/src/handlers/collection.ts +0 -36
- package/src/handlers/create-handler.ts +0 -330
- package/src/handlers/types.ts +0 -108
- package/src/migrate.ts +0 -318
- package/src/outbox.ts +0 -383
- package/src/plugins/incrementing-version.ts +0 -133
- package/src/plugins/index.ts +0 -2
- package/src/plugins/types.ts +0 -63
- package/src/proxy/connection.ts +0 -191
- package/src/proxy/dialect.ts +0 -76
- package/src/proxy/driver.ts +0 -126
- package/src/proxy/index.ts +0 -10
- package/src/proxy/mutations.ts +0 -18
- package/src/pull-engine.test.ts +0 -151
- package/src/pull-engine.ts +0 -855
- package/src/push-engine.ts +0 -216
- package/src/query/FingerprintCollector.ts +0 -29
- package/src/query/QueryContext.ts +0 -54
- package/src/query/fingerprint.ts +0 -109
- package/src/query/index.ts +0 -10
- package/src/query/tracked-select.ts +0 -139
- package/src/schema.ts +0 -94
- package/src/subscription-state.ts +0 -259
- package/src/sync-loop.ts +0 -379
- package/src/sync.ts +0 -170
- package/src/utils/id.ts +0 -55
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @syncular/client - Declarative client handler helper
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
ColumnCodecDialect,
|
|
7
|
-
ColumnCodecSource,
|
|
8
|
-
ScopeDefinition,
|
|
9
|
-
ScopeKeysFromDefinitions,
|
|
10
|
-
ScopeValuesFromPatterns,
|
|
11
|
-
SyncChange,
|
|
12
|
-
SyncSnapshot,
|
|
13
|
-
} from '@syncular/core';
|
|
14
|
-
import {
|
|
15
|
-
applyCodecsToDbRow,
|
|
16
|
-
isRecord,
|
|
17
|
-
normalizeScopes,
|
|
18
|
-
toTableColumnCodecs,
|
|
19
|
-
} from '@syncular/core';
|
|
20
|
-
import { sql } from 'kysely';
|
|
21
|
-
import type { SyncClientDb } from '../schema';
|
|
22
|
-
import type {
|
|
23
|
-
ClientClearContext,
|
|
24
|
-
ClientHandlerContext,
|
|
25
|
-
ClientSnapshotHookContext,
|
|
26
|
-
ClientTableHandler,
|
|
27
|
-
} from './types';
|
|
28
|
-
|
|
29
|
-
const MAX_INSERT_BIND_PARAMETERS = 900;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Options for creating a declarative client handler.
|
|
33
|
-
*/
|
|
34
|
-
export interface CreateClientHandlerOptions<
|
|
35
|
-
DB extends SyncClientDb,
|
|
36
|
-
TableName extends keyof DB & string,
|
|
37
|
-
ScopeDefs extends readonly ScopeDefinition[] = readonly ScopeDefinition[],
|
|
38
|
-
> {
|
|
39
|
-
/** Table name in the database */
|
|
40
|
-
table: TableName;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Scope definitions for this table.
|
|
44
|
-
* Can be simple strings (column auto-derived) or objects with explicit mapping.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* ```typescript
|
|
48
|
-
* // Simple: column auto-derived from placeholder
|
|
49
|
-
* scopes: ['user:{user_id}', 'org:{org_id}']
|
|
50
|
-
*
|
|
51
|
-
* // Explicit: when column differs from pattern variable
|
|
52
|
-
* scopes: [
|
|
53
|
-
* { pattern: 'user:{user_id}', column: 'owner_id' }
|
|
54
|
-
* ]
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
scopes: ScopeDefs;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Subscription configuration for this table.
|
|
61
|
-
* - `true` (default): Subscribe to this table with default scopes/params
|
|
62
|
-
* - `false`: Don't subscribe (handler only for local mutations)
|
|
63
|
-
* - Object: Subscribe with custom scopes and params
|
|
64
|
-
*/
|
|
65
|
-
subscribe?:
|
|
66
|
-
| boolean
|
|
67
|
-
| {
|
|
68
|
-
scopes?: ScopeValuesFromPatterns<ScopeDefs>;
|
|
69
|
-
params?: Record<string, unknown>;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/** Primary key column name (default: 'id') */
|
|
73
|
-
primaryKey?: keyof DB[TableName] & string;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Optional version column name (e.g. 'server_version') to store `change.row_version`.
|
|
77
|
-
* If omitted, row_version is ignored by the default handler.
|
|
78
|
-
*/
|
|
79
|
-
versionColumn?: keyof DB[TableName] & string;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Optional column codec resolver.
|
|
83
|
-
* Receives `{ table, column, sqlType?, dialect? }` and returns a codec.
|
|
84
|
-
*/
|
|
85
|
-
codecs?: ColumnCodecSource;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Dialect used for codec dialect overrides.
|
|
89
|
-
* Default: 'sqlite'
|
|
90
|
-
*/
|
|
91
|
-
codecDialect?: ColumnCodecDialect;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Override: Apply a snapshot.
|
|
95
|
-
* Default: upsert all rows (no delete on isFirstPage).
|
|
96
|
-
*/
|
|
97
|
-
applySnapshot?: (
|
|
98
|
-
ctx: ClientHandlerContext<DB>,
|
|
99
|
-
snapshot: SyncSnapshot
|
|
100
|
-
) => Promise<void>;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Override: Apply a single change.
|
|
104
|
-
* Default: upsert on upsert, delete on delete.
|
|
105
|
-
*/
|
|
106
|
-
applyChange?: (
|
|
107
|
-
ctx: ClientHandlerContext<DB>,
|
|
108
|
-
change: SyncChange
|
|
109
|
-
) => Promise<void>;
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Override: Clear all data for this table.
|
|
113
|
-
* Default: delete all rows from the table.
|
|
114
|
-
*/
|
|
115
|
-
clearAll?: (ctx: ClientClearContext<DB>) => Promise<void>;
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Hook: Called when a snapshot begins (isFirstPage = true).
|
|
119
|
-
* Default: no-op.
|
|
120
|
-
*/
|
|
121
|
-
onSnapshotStart?: (ctx: ClientSnapshotHookContext<DB>) => Promise<void>;
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Hook: Called when a snapshot ends (isLastPage = true).
|
|
125
|
-
* Default: no-op.
|
|
126
|
-
*/
|
|
127
|
-
onSnapshotEnd?: (ctx: ClientSnapshotHookContext<DB>) => Promise<void>;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Create a declarative client table handler with sensible defaults.
|
|
132
|
-
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```typescript
|
|
135
|
-
* import { createClientHandler } from '@syncular/client';
|
|
136
|
-
* import type { ClientDb } from './db.generated';
|
|
137
|
-
*
|
|
138
|
-
* export const tasksHandler = createClientHandler<ClientDb, 'tasks'>({
|
|
139
|
-
* table: 'tasks',
|
|
140
|
-
* scopes: ['user:{user_id}'], // column auto-derived from placeholder
|
|
141
|
-
* });
|
|
142
|
-
*
|
|
143
|
-
* // With custom column mapping:
|
|
144
|
-
* export const tasksHandler = createClientHandler<ClientDb, 'tasks'>({
|
|
145
|
-
* table: 'tasks',
|
|
146
|
-
* scopes: [{ pattern: 'user:{user_id}', column: 'owner_id' }],
|
|
147
|
-
* });
|
|
148
|
-
*
|
|
149
|
-
* // With soft delete pattern:
|
|
150
|
-
* export const tasksHandler = createClientHandler<ClientDb, 'tasks'>({
|
|
151
|
-
* table: 'tasks',
|
|
152
|
-
* scopes: ['user:{user_id}'],
|
|
153
|
-
* onSnapshotStart: async (ctx) => {
|
|
154
|
-
* await ctx.trx.updateTable('tasks')
|
|
155
|
-
* .set({ _sync_stale: 1 })
|
|
156
|
-
* .where('user_id', '=', ctx.scopeKey.split(':')[1])
|
|
157
|
-
* .execute();
|
|
158
|
-
* },
|
|
159
|
-
* onSnapshotEnd: async (ctx) => {
|
|
160
|
-
* await ctx.trx.deleteFrom('tasks')
|
|
161
|
-
* .where('_sync_stale', '=', 1)
|
|
162
|
-
* .execute();
|
|
163
|
-
* },
|
|
164
|
-
* });
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
export function createClientHandler<
|
|
168
|
-
DB extends SyncClientDb,
|
|
169
|
-
TableName extends keyof DB & string,
|
|
170
|
-
ScopeDefs extends readonly ScopeDefinition[] = readonly ScopeDefinition[],
|
|
171
|
-
>(
|
|
172
|
-
options: CreateClientHandlerOptions<DB, TableName, ScopeDefs>
|
|
173
|
-
): ClientTableHandler<DB, TableName, ScopeKeysFromDefinitions<ScopeDefs>> {
|
|
174
|
-
const { table, scopes: scopeDefs } = options;
|
|
175
|
-
const primaryKey =
|
|
176
|
-
options.primaryKey ?? ('id' as keyof DB[TableName] & string);
|
|
177
|
-
const versionColumn = options.versionColumn;
|
|
178
|
-
const codecDialect = options.codecDialect ?? 'sqlite';
|
|
179
|
-
const codecCache = new Map<string, ReturnType<typeof toTableColumnCodecs>>();
|
|
180
|
-
const resolveTableCodecs = (row: Record<string, unknown>) => {
|
|
181
|
-
const codecs = options.codecs;
|
|
182
|
-
if (!codecs) return {};
|
|
183
|
-
const columns = Object.keys(row);
|
|
184
|
-
if (columns.length === 0) return {};
|
|
185
|
-
const cacheKey = columns.slice().sort().join('\u0000');
|
|
186
|
-
const cached = codecCache.get(cacheKey);
|
|
187
|
-
if (cached) return cached;
|
|
188
|
-
const resolved = toTableColumnCodecs(table, codecs, columns, {
|
|
189
|
-
dialect: codecDialect,
|
|
190
|
-
});
|
|
191
|
-
codecCache.set(cacheKey, resolved);
|
|
192
|
-
return resolved;
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
// Normalize scopes to pattern map (stored for metadata)
|
|
196
|
-
const scopeColumnMap = normalizeScopes(scopeDefs);
|
|
197
|
-
const scopePatterns = Object.keys(scopeColumnMap);
|
|
198
|
-
|
|
199
|
-
// Default applySnapshot: upsert all rows
|
|
200
|
-
const defaultApplySnapshot = async (
|
|
201
|
-
ctx: ClientHandlerContext<DB>,
|
|
202
|
-
snapshot: SyncSnapshot
|
|
203
|
-
): Promise<void> => {
|
|
204
|
-
const rows: Array<Record<string, unknown>> = [];
|
|
205
|
-
for (const row of snapshot.rows ?? []) {
|
|
206
|
-
if (!isRecord(row)) continue;
|
|
207
|
-
rows.push(applyCodecsToDbRow(row, resolveTableCodecs(row), codecDialect));
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (rows.length === 0) return;
|
|
211
|
-
|
|
212
|
-
// Get column names from first row
|
|
213
|
-
const columns = Object.keys(rows[0]!);
|
|
214
|
-
if (columns.length === 0) return;
|
|
215
|
-
const updateColumns = columns.filter((c) => c !== primaryKey);
|
|
216
|
-
|
|
217
|
-
const onConflict =
|
|
218
|
-
updateColumns.length === 0
|
|
219
|
-
? sql`do nothing`
|
|
220
|
-
: sql`do update set ${sql.join(
|
|
221
|
-
updateColumns.map(
|
|
222
|
-
(col) => sql`${sql.ref(col)} = ${sql.ref(`excluded.${col}`)}`
|
|
223
|
-
),
|
|
224
|
-
sql`, `
|
|
225
|
-
)}`;
|
|
226
|
-
|
|
227
|
-
const maxRowsPerInsert = Math.max(
|
|
228
|
-
1,
|
|
229
|
-
Math.floor(MAX_INSERT_BIND_PARAMETERS / columns.length)
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
for (
|
|
233
|
-
let startIndex = 0;
|
|
234
|
-
startIndex < rows.length;
|
|
235
|
-
startIndex += maxRowsPerInsert
|
|
236
|
-
) {
|
|
237
|
-
const batchRows = rows.slice(startIndex, startIndex + maxRowsPerInsert);
|
|
238
|
-
|
|
239
|
-
await sql`
|
|
240
|
-
insert into ${sql.table(table)} (${sql.join(columns.map((c) => sql.ref(c)))})
|
|
241
|
-
values ${sql.join(
|
|
242
|
-
batchRows.map(
|
|
243
|
-
(row) =>
|
|
244
|
-
sql`(${sql.join(
|
|
245
|
-
columns.map((col) => sql.val(row[col] ?? null)),
|
|
246
|
-
sql`, `
|
|
247
|
-
)})`
|
|
248
|
-
),
|
|
249
|
-
sql`, `
|
|
250
|
-
)}
|
|
251
|
-
on conflict (${sql.ref(primaryKey)}) ${onConflict}
|
|
252
|
-
`.execute(ctx.trx);
|
|
253
|
-
}
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// Default applyChange: upsert on upsert, delete on delete
|
|
257
|
-
const defaultApplyChange = async (
|
|
258
|
-
ctx: ClientHandlerContext<DB>,
|
|
259
|
-
change: SyncChange
|
|
260
|
-
): Promise<void> => {
|
|
261
|
-
if (change.op === 'delete') {
|
|
262
|
-
await sql`
|
|
263
|
-
delete from ${sql.table(table)}
|
|
264
|
-
where ${sql.ref(primaryKey)} = ${sql.val(change.row_id)}
|
|
265
|
-
`.execute(ctx.trx);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const row = isRecord(change.row_json)
|
|
270
|
-
? applyCodecsToDbRow(
|
|
271
|
-
change.row_json,
|
|
272
|
-
resolveTableCodecs(change.row_json),
|
|
273
|
-
codecDialect
|
|
274
|
-
)
|
|
275
|
-
: {};
|
|
276
|
-
const insertRow: Record<string, unknown> = {
|
|
277
|
-
...row,
|
|
278
|
-
[primaryKey]: change.row_id,
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
versionColumn &&
|
|
283
|
-
change.row_version !== null &&
|
|
284
|
-
change.row_version !== undefined
|
|
285
|
-
) {
|
|
286
|
-
insertRow[versionColumn] = change.row_version;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const columns = Object.keys(insertRow);
|
|
290
|
-
const updateColumns = columns.filter((c) => c !== primaryKey);
|
|
291
|
-
const onConflict =
|
|
292
|
-
updateColumns.length === 0
|
|
293
|
-
? sql`do nothing`
|
|
294
|
-
: sql`do update set ${sql.join(
|
|
295
|
-
updateColumns.map(
|
|
296
|
-
(col) => sql`${sql.ref(col)} = ${sql.ref(`excluded.${col}`)}`
|
|
297
|
-
),
|
|
298
|
-
sql`, `
|
|
299
|
-
)}`;
|
|
300
|
-
|
|
301
|
-
await sql`
|
|
302
|
-
insert into ${sql.table(table)} (${sql.join(columns.map((c) => sql.ref(c)))})
|
|
303
|
-
values (${sql.join(
|
|
304
|
-
columns.map((col) => sql.val(insertRow[col] ?? null)),
|
|
305
|
-
sql`, `
|
|
306
|
-
)})
|
|
307
|
-
on conflict (${sql.ref(primaryKey)}) ${onConflict}
|
|
308
|
-
`.execute(ctx.trx);
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
// Default clearAll: delete all rows from the table
|
|
312
|
-
const defaultClearAll = async (
|
|
313
|
-
ctx: ClientClearContext<DB>
|
|
314
|
-
): Promise<void> => {
|
|
315
|
-
await sql`delete from ${sql.table(table)}`.execute(ctx.trx);
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
return {
|
|
319
|
-
table,
|
|
320
|
-
scopePatterns,
|
|
321
|
-
subscribe: options.subscribe,
|
|
322
|
-
|
|
323
|
-
applySnapshot: options.applySnapshot ?? defaultApplySnapshot,
|
|
324
|
-
applyChange: options.applyChange ?? defaultApplyChange,
|
|
325
|
-
clearAll: options.clearAll ?? defaultClearAll,
|
|
326
|
-
|
|
327
|
-
onSnapshotStart: options.onSnapshotStart,
|
|
328
|
-
onSnapshotEnd: options.onSnapshotEnd,
|
|
329
|
-
};
|
|
330
|
-
}
|
package/src/handlers/types.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @syncular/client - Sync client table handler interface
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type {
|
|
6
|
-
ScopeValues,
|
|
7
|
-
ScopeValuesForKeys,
|
|
8
|
-
SyncChange,
|
|
9
|
-
SyncSnapshot,
|
|
10
|
-
} from '@syncular/core';
|
|
11
|
-
import type { Transaction } from 'kysely';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Context passed to client table handler methods.
|
|
15
|
-
*/
|
|
16
|
-
export interface ClientHandlerContext<DB> {
|
|
17
|
-
/** Database transaction */
|
|
18
|
-
trx: Transaction<DB>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Extended context for snapshot lifecycle hooks.
|
|
23
|
-
*/
|
|
24
|
-
export interface ClientSnapshotHookContext<DB>
|
|
25
|
-
extends ClientHandlerContext<DB> {
|
|
26
|
-
/** The table being snapshotted */
|
|
27
|
-
table: string;
|
|
28
|
-
/** The scope values for this subscription */
|
|
29
|
-
scopes: ScopeValues;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Context for clearAll/clearScope operations.
|
|
34
|
-
*/
|
|
35
|
-
export interface ClientClearContext<DB> extends ClientHandlerContext<DB> {
|
|
36
|
-
/** The scope values to clear (data matching these scopes should be removed) */
|
|
37
|
-
scopes: ScopeValues;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Subscription configuration for a handler.
|
|
42
|
-
*/
|
|
43
|
-
export interface HandlerSubscriptionConfig<ScopeKeys extends string = string> {
|
|
44
|
-
/** Scope values for this subscription */
|
|
45
|
-
scopes?: ScopeValuesForKeys<ScopeKeys>;
|
|
46
|
-
/** Params for this subscription */
|
|
47
|
-
params?: Record<string, unknown>;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Client-side table handler for applying sync snapshots and changes.
|
|
52
|
-
*/
|
|
53
|
-
export interface ClientTableHandler<
|
|
54
|
-
DB,
|
|
55
|
-
TableName extends keyof DB & string = keyof DB & string,
|
|
56
|
-
ScopeKeys extends string = string,
|
|
57
|
-
> {
|
|
58
|
-
/** Table name (used as identifier in sync operations) */
|
|
59
|
-
table: TableName;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Scope patterns used by this table.
|
|
63
|
-
* Used for deriving safe default subscriptions in `createClient`.
|
|
64
|
-
*/
|
|
65
|
-
scopePatterns?: string[];
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Subscription configuration.
|
|
69
|
-
* - `true`: Subscribe to this table (default)
|
|
70
|
-
* - `false`: Don't subscribe (local-only handler)
|
|
71
|
-
* - Object: Subscribe with custom scopes/params
|
|
72
|
-
*/
|
|
73
|
-
subscribe?: boolean | HandlerSubscriptionConfig<ScopeKeys>;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Apply a snapshot page for this table.
|
|
77
|
-
* The handler is responsible for upserting the rows.
|
|
78
|
-
*/
|
|
79
|
-
applySnapshot(
|
|
80
|
-
ctx: ClientHandlerContext<DB>,
|
|
81
|
-
snapshot: SyncSnapshot
|
|
82
|
-
): Promise<void>;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Clear local data for this table matching the given scopes.
|
|
86
|
-
* Used when subscription is removed or revoked.
|
|
87
|
-
* If scopes is empty, clear all data for this table.
|
|
88
|
-
*/
|
|
89
|
-
clearAll(ctx: ClientClearContext<DB>): Promise<void>;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Apply a single change (upsert/delete).
|
|
93
|
-
* Must be idempotent (retries may re-apply).
|
|
94
|
-
*/
|
|
95
|
-
applyChange(ctx: ClientHandlerContext<DB>, change: SyncChange): Promise<void>;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Optional: Called when a snapshot begins (isFirstPage = true).
|
|
99
|
-
* Use this for marking existing rows as stale before applying snapshot.
|
|
100
|
-
*/
|
|
101
|
-
onSnapshotStart?(ctx: ClientSnapshotHookContext<DB>): Promise<void>;
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Optional: Called when a snapshot ends (isLastPage = true).
|
|
105
|
-
* Use this for cleaning up stale rows after snapshot is complete.
|
|
106
|
-
*/
|
|
107
|
-
onSnapshotEnd?(ctx: ClientSnapshotHookContext<DB>): Promise<void>;
|
|
108
|
-
}
|