@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.
Files changed (233) hide show
  1. package/README.md +227 -709
  2. package/dist/apply.d.ts +80 -0
  3. package/dist/apply.js +301 -0
  4. package/dist/blob.d.ts +127 -0
  5. package/dist/blob.js +201 -0
  6. package/dist/bun-database.d.ts +22 -0
  7. package/dist/bun-database.js +61 -0
  8. package/dist/client.d.ts +320 -69
  9. package/dist/client.js +1627 -163
  10. package/dist/content-type.d.ts +2 -0
  11. package/dist/content-type.js +2 -0
  12. package/dist/database.d.ts +35 -80
  13. package/dist/database.js +32 -947
  14. package/dist/encryption.d.ts +47 -0
  15. package/dist/encryption.js +75 -0
  16. package/dist/errors.d.ts +8 -22
  17. package/dist/errors.js +10 -207
  18. package/dist/http.d.ts +32 -0
  19. package/dist/http.js +196 -0
  20. package/dist/index.d.ts +28 -16
  21. package/dist/index.js +25 -12
  22. package/dist/invalidation.d.ts +69 -0
  23. package/dist/invalidation.js +84 -0
  24. package/dist/leader-lock.d.ts +28 -0
  25. package/dist/leader-lock.js +38 -0
  26. package/dist/multi-tab.d.ts +134 -0
  27. package/dist/multi-tab.js +399 -0
  28. package/dist/node-database.d.ts +41 -0
  29. package/dist/node-database.js +133 -0
  30. package/dist/outbox.d.ts +56 -0
  31. package/dist/outbox.js +140 -0
  32. package/dist/schema.d.ts +107 -0
  33. package/dist/schema.js +267 -0
  34. package/dist/state.d.ts +40 -0
  35. package/dist/state.js +77 -0
  36. package/dist/transport.d.ts +44 -0
  37. package/dist/transport.js +7 -0
  38. package/dist/wasm-database.d.ts +30 -0
  39. package/dist/wasm-database.js +170 -0
  40. package/dist/window.d.ts +64 -0
  41. package/dist/window.js +0 -0
  42. package/dist/worker-entry.d.ts +16 -2
  43. package/dist/worker-entry.js +300 -456
  44. package/dist/worker-host.d.ts +174 -0
  45. package/dist/worker-host.js +536 -0
  46. package/dist/worker-protocol.d.ts +173 -61
  47. package/dist/worker-protocol.js +7 -16
  48. package/package.json +45 -112
  49. package/src/apply.ts +435 -0
  50. package/src/blob.ts +333 -0
  51. package/src/bun-database.ts +75 -0
  52. package/src/client.ts +2247 -277
  53. package/src/content-type.ts +2 -0
  54. package/src/database.ts +63 -1389
  55. package/src/encryption.ts +123 -0
  56. package/src/errors.ts +11 -265
  57. package/src/http.ts +254 -0
  58. package/src/index.ts +25 -20
  59. package/src/invalidation.ts +128 -0
  60. package/src/leader-lock.ts +68 -0
  61. package/src/multi-tab.ts +550 -0
  62. package/src/node-database.ts +180 -0
  63. package/src/outbox.ts +206 -0
  64. package/src/schema.ts +397 -0
  65. package/src/state.ts +126 -0
  66. package/src/transport.ts +52 -0
  67. package/src/wasm-database.ts +279 -0
  68. package/src/window.ts +0 -0
  69. package/src/worker-entry.ts +391 -545
  70. package/src/worker-host.ts +800 -0
  71. package/src/worker-protocol.ts +204 -99
  72. package/dist/auth-leases.d.ts +0 -11
  73. package/dist/auth-leases.d.ts.map +0 -1
  74. package/dist/auth-leases.js +0 -140
  75. package/dist/auth-leases.js.map +0 -1
  76. package/dist/blob-limits.d.ts +0 -15
  77. package/dist/blob-limits.d.ts.map +0 -1
  78. package/dist/blob-limits.js +0 -66
  79. package/dist/blob-limits.js.map +0 -1
  80. package/dist/bridge-client.d.ts +0 -69
  81. package/dist/bridge-client.d.ts.map +0 -1
  82. package/dist/bridge-client.js +0 -282
  83. package/dist/bridge-client.js.map +0 -1
  84. package/dist/client-config.d.ts +0 -6
  85. package/dist/client-config.d.ts.map +0 -1
  86. package/dist/client-config.js +0 -18
  87. package/dist/client-config.js.map +0 -1
  88. package/dist/client.d.ts.map +0 -1
  89. package/dist/client.js.map +0 -1
  90. package/dist/command-history.d.ts +0 -35
  91. package/dist/command-history.d.ts.map +0 -1
  92. package/dist/command-history.js +0 -378
  93. package/dist/command-history.js.map +0 -1
  94. package/dist/console-diagnostics.d.ts +0 -33
  95. package/dist/console-diagnostics.d.ts.map +0 -1
  96. package/dist/console-diagnostics.js +0 -496
  97. package/dist/console-diagnostics.js.map +0 -1
  98. package/dist/crdt-yjs/index.d.ts +0 -4
  99. package/dist/crdt-yjs/index.d.ts.map +0 -1
  100. package/dist/crdt-yjs/index.js +0 -4
  101. package/dist/crdt-yjs/index.js.map +0 -1
  102. package/dist/crdt-yjs/webview-host-facade.d.ts +0 -126
  103. package/dist/crdt-yjs/webview-host-facade.d.ts.map +0 -1
  104. package/dist/crdt-yjs/webview-host-facade.js +0 -284
  105. package/dist/crdt-yjs/webview-host-facade.js.map +0 -1
  106. package/dist/crdt-yjs/yjs-document-field-adapter.d.ts +0 -153
  107. package/dist/crdt-yjs/yjs-document-field-adapter.d.ts.map +0 -1
  108. package/dist/crdt-yjs/yjs-document-field-adapter.js +0 -406
  109. package/dist/crdt-yjs/yjs-document-field-adapter.js.map +0 -1
  110. package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts +0 -73
  111. package/dist/crdt-yjs/yjs-prosemirror-bridge.d.ts.map +0 -1
  112. package/dist/crdt-yjs/yjs-prosemirror-bridge.js +0 -169
  113. package/dist/crdt-yjs/yjs-prosemirror-bridge.js.map +0 -1
  114. package/dist/database.d.ts.map +0 -1
  115. package/dist/database.js.map +0 -1
  116. package/dist/diagnostics.d.ts +0 -10
  117. package/dist/diagnostics.d.ts.map +0 -1
  118. package/dist/diagnostics.js +0 -83
  119. package/dist/diagnostics.js.map +0 -1
  120. package/dist/errors.d.ts.map +0 -1
  121. package/dist/errors.js.map +0 -1
  122. package/dist/generated-bridge.d.ts +0 -365
  123. package/dist/generated-bridge.d.ts.map +0 -1
  124. package/dist/generated-bridge.js +0 -250
  125. package/dist/generated-bridge.js.map +0 -1
  126. package/dist/index.d.ts.map +0 -1
  127. package/dist/index.js.map +0 -1
  128. package/dist/mutations.d.ts +0 -72
  129. package/dist/mutations.d.ts.map +0 -1
  130. package/dist/mutations.js +0 -63
  131. package/dist/mutations.js.map +0 -1
  132. package/dist/network.d.ts +0 -3
  133. package/dist/network.d.ts.map +0 -1
  134. package/dist/network.js +0 -17
  135. package/dist/network.js.map +0 -1
  136. package/dist/react/index.d.ts +0 -169
  137. package/dist/react/index.d.ts.map +0 -1
  138. package/dist/react/index.js +0 -628
  139. package/dist/react/index.js.map +0 -1
  140. package/dist/react-native/index.d.ts +0 -35
  141. package/dist/react-native/index.d.ts.map +0 -1
  142. package/dist/react-native/index.js +0 -49
  143. package/dist/react-native/index.js.map +0 -1
  144. package/dist/runtime-contract.d.ts +0 -13
  145. package/dist/runtime-contract.d.ts.map +0 -1
  146. package/dist/runtime-contract.js +0 -24
  147. package/dist/runtime-contract.js.map +0 -1
  148. package/dist/rust-client.d.ts +0 -106
  149. package/dist/rust-client.d.ts.map +0 -1
  150. package/dist/rust-client.js +0 -938
  151. package/dist/rust-client.js.map +0 -1
  152. package/dist/sentry.d.ts +0 -35
  153. package/dist/sentry.d.ts.map +0 -1
  154. package/dist/sentry.js +0 -155
  155. package/dist/sentry.js.map +0 -1
  156. package/dist/sql-safety.d.ts +0 -3
  157. package/dist/sql-safety.d.ts.map +0 -1
  158. package/dist/sql-safety.js +0 -62
  159. package/dist/sql-safety.js.map +0 -1
  160. package/dist/syncular-runtime-artifacts.json +0 -61
  161. package/dist/tauri/index.d.ts +0 -35
  162. package/dist/tauri/index.d.ts.map +0 -1
  163. package/dist/tauri/index.js +0 -114
  164. package/dist/tauri/index.js.map +0 -1
  165. package/dist/types.d.ts +0 -1096
  166. package/dist/types.d.ts.map +0 -1
  167. package/dist/types.js +0 -2
  168. package/dist/types.js.map +0 -1
  169. package/dist/wasm/.syncular-wasm-profile +0 -1
  170. package/dist/wasm/syncular-runtime-artifact.json +0 -21
  171. package/dist/wasm/syncular.d.ts +0 -207
  172. package/dist/wasm/syncular.js +0 -2341
  173. package/dist/wasm/syncular_bg.wasm +0 -0
  174. package/dist/wasm/syncular_bg.wasm.d.ts +0 -97
  175. package/dist/wasm-bindings/runtime-contract.d.ts +0 -22
  176. package/dist/wasm-bindings/runtime-contract.d.ts.map +0 -1
  177. package/dist/wasm-bindings/runtime-contract.js +0 -112
  178. package/dist/wasm-bindings/runtime-contract.js.map +0 -1
  179. package/dist/wasm-core/.syncular-wasm-profile +0 -1
  180. package/dist/wasm-core/syncular-runtime-artifact.json +0 -17
  181. package/dist/wasm-core/syncular.d.ts +0 -162
  182. package/dist/wasm-core/syncular.js +0 -1847
  183. package/dist/wasm-core/syncular_bg.wasm +0 -0
  184. package/dist/wasm-core/syncular_bg.wasm.d.ts +0 -77
  185. package/dist/wasm-perf/.syncular-wasm-profile +0 -1
  186. package/dist/wasm-perf/syncular-runtime-artifact.json +0 -21
  187. package/dist/wasm-perf/syncular.d.ts +0 -207
  188. package/dist/wasm-perf/syncular.js +0 -2341
  189. package/dist/wasm-perf/syncular_bg.wasm +0 -0
  190. package/dist/wasm-perf/syncular_bg.wasm.d.ts +0 -97
  191. package/dist/wasm-runtime.d.ts +0 -23
  192. package/dist/wasm-runtime.d.ts.map +0 -1
  193. package/dist/wasm-runtime.js +0 -69
  194. package/dist/wasm-runtime.js.map +0 -1
  195. package/dist/worker-client.d.ts +0 -123
  196. package/dist/worker-client.d.ts.map +0 -1
  197. package/dist/worker-client.js +0 -1735
  198. package/dist/worker-client.js.map +0 -1
  199. package/dist/worker-entry.d.ts.map +0 -1
  200. package/dist/worker-entry.js.map +0 -1
  201. package/dist/worker-protocol.d.ts.map +0 -1
  202. package/dist/worker-protocol.js.map +0 -1
  203. package/dist/worker-realtime.d.ts +0 -39
  204. package/dist/worker-realtime.d.ts.map +0 -1
  205. package/dist/worker-realtime.js +0 -677
  206. package/dist/worker-realtime.js.map +0 -1
  207. package/src/auth-leases.ts +0 -251
  208. package/src/blob-limits.ts +0 -98
  209. package/src/bridge-client.ts +0 -512
  210. package/src/client-config.ts +0 -29
  211. package/src/command-history.ts +0 -623
  212. package/src/console-diagnostics.ts +0 -617
  213. package/src/crdt-yjs/index.ts +0 -3
  214. package/src/crdt-yjs/webview-host-facade.ts +0 -477
  215. package/src/crdt-yjs/yjs-document-field-adapter.ts +0 -733
  216. package/src/crdt-yjs/yjs-prosemirror-bridge.ts +0 -272
  217. package/src/diagnostics.ts +0 -116
  218. package/src/generated-bridge.ts +0 -741
  219. package/src/mutations.ts +0 -168
  220. package/src/network.ts +0 -32
  221. package/src/react/index.ts +0 -1036
  222. package/src/react-native/index.ts +0 -152
  223. package/src/runtime-contract.ts +0 -48
  224. package/src/rust-client.ts +0 -1491
  225. package/src/sentry.ts +0 -215
  226. package/src/sql-safety.ts +0 -61
  227. package/src/tauri/index.ts +0 -211
  228. package/src/types.ts +0 -1397
  229. package/src/wasm-bindings/generated-wasm-bindings.d.ts +0 -70
  230. package/src/wasm-bindings/runtime-contract.ts +0 -158
  231. package/src/wasm-runtime.ts +0 -145
  232. package/src/worker-client.ts +0 -2289
  233. package/src/worker-realtime.ts +0 -843
@@ -1,64 +1,176 @@
1
- import type { SyncularGeneratedWorkerRequest } from './generated-bridge';
2
- import type { SyncularBootstrapStatus, SyncularDiagnosticEvent, SyncularErrorCategory, SyncularErrorCode, SyncularErrorRecommendedAction, SyncularLiveQueryEvent, SyncularRealtimeConnectionState, SyncularRowsChangedEvent } from './types';
3
- export declare const SYNCULAR_WORKER_PROTOCOL_VERSION = 2;
4
- export interface SyncularWorkerErrorPayload {
5
- code: SyncularErrorCode;
6
- message: string;
7
- category?: SyncularErrorCategory;
8
- retryable?: boolean;
9
- recommendedAction?: SyncularErrorRecommendedAction;
10
- name?: string;
11
- stack?: string;
12
- details?: unknown;
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.js';
21
+ import type { ConflictRecord, LeaseState, MutationInput, PresencePeer, RejectionRecord, SchemaFloor, SubscribeInput, SyncClientLimits, SyncSummary, WindowState } from './client.js';
22
+ import type { SqlRow, SqlValue } from './database.js';
23
+ import type { InvalidationEvent } from './invalidation.js';
24
+ import type { OutboxCommit } from './outbox.js';
25
+ import type { ClientSchema } from './schema.js';
26
+ import type { SubscriptionRecord } from './state.js';
27
+ import type { WindowBase } from './window.js';
28
+ /** The handle exists but this tab lost the leader election (TODO 3.2). */
29
+ export declare const NOT_LEADER_CODE = "client.not_leader";
30
+ /** The worker (or its RPC channel) failed outside protocol semantics. */
31
+ export declare const WORKER_FAILED_CODE = "client.worker_failed";
32
+ export type WorkerDatabaseInit = {
33
+ /** THE persistent mode: opfs-sahpool, named database. */
34
+ readonly mode: 'persistent';
35
+ readonly name: string;
36
+ /** Optional pool directory override (default `.syncular/<name>`). */
37
+ readonly directory?: string;
38
+ } | {
39
+ /**
40
+ * Bootstrap-provided database (tests inject bun:sqlite here). The
41
+ * worker entry MUST have an `openDatabase` override or init fails.
42
+ */
43
+ readonly mode: 'custom';
44
+ readonly options?: unknown;
45
+ };
46
+ export interface WorkerEndpoints {
47
+ /** POST target for SSP2 sync rounds (§1.1). */
48
+ readonly syncUrl: string;
49
+ /** Segment download base URL; omit when segments are not served. */
50
+ readonly segmentsUrl?: string;
51
+ /** Blob upload/download base URL (§5.9); omit when blobs are unused. */
52
+ readonly blobsUrl?: string;
53
+ /**
54
+ * WebSocket URL for §8 realtime. The literal placeholder `{clientId}`
55
+ * is substituted with the (possibly persisted) client id after start.
56
+ */
57
+ readonly realtimeUrl?: string;
13
58
  }
14
- export declare function createSyncularWorkerErrorPayload(code: SyncularErrorCode, message?: string, options?: {
15
- name?: string;
16
- stack?: string;
17
- details?: unknown;
18
- }): SyncularWorkerErrorPayload;
19
- export type { SyncularWorkerRealtimeOptions, SyncularWorkerRuntimeArtifact, } from './generated-bridge';
20
- export type SyncularWorkerRequest = SyncularGeneratedWorkerRequest;
21
- interface SyncularWorkerResponseBase {
22
- id: number;
23
- protocolVersion: typeof SYNCULAR_WORKER_PROTOCOL_VERSION;
59
+ export interface WorkerInitConfig {
60
+ readonly schema: ClientSchema;
61
+ readonly database: WorkerDatabaseInit;
62
+ readonly endpoints: WorkerEndpoints;
63
+ readonly clientId?: string;
64
+ readonly limits?: SyncClientLimits;
65
+ /**
66
+ * Worker-side host loop (§8.4): coalesce wake-ups into jittered
67
+ * `syncUntilIdle` rounds inside the worker. Default true.
68
+ */
69
+ readonly autoSync?: boolean;
70
+ /** Max jitter before a coalesced auto-sync round (default 200 ms). */
71
+ readonly wakeJitterMs?: number;
24
72
  }
25
- interface SyncularWorkerEventBase {
26
- protocolVersion: typeof SYNCULAR_WORKER_PROTOCOL_VERSION;
73
+ /** Successful init reply. */
74
+ export interface WorkerInitResult {
75
+ readonly clientId: string;
27
76
  }
28
- export type SyncularWorkerResponse = (SyncularWorkerResponseBase & {
29
- ok: true;
30
- value?: unknown;
31
- }) | (SyncularWorkerResponseBase & {
32
- ok: false;
33
- error: SyncularWorkerErrorPayload;
34
- });
35
- export type SyncularWorkerEvent = (SyncularWorkerEventBase & {
36
- type: 'liveQueryEvents';
37
- events: Array<SyncularLiveQueryEvent<Record<string, unknown>>>;
38
- }) | (SyncularWorkerEventBase & SyncularRowsChangedEvent & {
39
- type: 'rowsChanged';
40
- }) | (SyncularWorkerEventBase & {
41
- type: 'bootstrapChanged';
42
- bootstrap: SyncularBootstrapStatus;
43
- }) | (SyncularWorkerEventBase & {
44
- type: 'realtimeState';
45
- state: SyncularRealtimeConnectionState;
46
- }) | (SyncularWorkerEventBase & {
47
- type: 'presenceEvent';
48
- action: 'join' | 'leave' | 'update' | 'snapshot';
49
- scopeKey: string;
50
- clientId?: string;
51
- actorId?: string;
52
- metadata?: Record<string, unknown>;
53
- entries?: Array<{
54
- clientId: string;
55
- actorId: string;
56
- joinedAt: number;
57
- metadata?: Record<string, unknown>;
58
- }>;
59
- }) | (SyncularWorkerEventBase & {
60
- type: 'diagnostic';
61
- event: SyncularDiagnosticEvent;
62
- });
63
- export type SyncularWorkerOutboundMessage = SyncularWorkerResponse | SyncularWorkerEvent;
64
- //# sourceMappingURL=worker-protocol.d.ts.map
77
+ export interface WorkerApi {
78
+ subscribe(input: SubscribeInput): void;
79
+ unsubscribe(id: string): void;
80
+ /** §4.8 windowed subscriptions: set the live units for a window base. */
81
+ setWindow(base: WindowBase, units: readonly string[]): Promise<void>;
82
+ /** §4.8 completeness oracle (I3): the windowed-in units for a base. */
83
+ windowState(base: WindowBase): WindowState;
84
+ mutate(mutations: readonly MutationInput[]): string;
85
+ sync(): Promise<SyncSummary>;
86
+ syncUntilIdle(maxRounds?: number): Promise<SyncSummary>;
87
+ query(sql: string, params?: readonly SqlValue[]): SqlRow[];
88
+ conflicts(): readonly ConflictRecord[];
89
+ rejections(): readonly RejectionRecord[];
90
+ schemaFloor(): SchemaFloor | undefined;
91
+ /** §7.3.5: the opaque auth-lease state, or undefined. */
92
+ leaseState(): LeaseState | undefined;
93
+ /** §7.4.5: true while a schema-bump reset + first re-bootstrap runs. */
94
+ upgrading(): boolean;
95
+ syncNeeded(): boolean;
96
+ pendingCommits(): OutboxCommit[];
97
+ subscriptions(): SubscriptionRecord[];
98
+ subscription(id: string): SubscriptionRecord | undefined;
99
+ connectRealtime(): Promise<void>;
100
+ disconnectRealtime(): void;
101
+ /** §8.6 presence: publish/clear a scope-keyed presence document. */
102
+ setPresence(scopeKey: string, doc: Record<string, unknown> | null): void;
103
+ /** §8.6 presence: the peers currently present on a scope key. */
104
+ presence(scopeKey: string): readonly PresencePeer[];
105
+ /** §5.9 blobs: stage bytes (returns the canonical ref) / resolve bytes. */
106
+ uploadBlob(bytes: Uint8Array, options?: {
107
+ readonly mediaType?: string;
108
+ readonly name?: string;
109
+ }): Promise<BlobRef>;
110
+ fetchBlob(blobIdOrRef: string): Promise<CachedBlob>;
111
+ /** Sever/restore the transport + realtime (offline simulation, demos). */
112
+ setOffline(offline: boolean): void;
113
+ close(): Promise<void>;
114
+ }
115
+ export type WorkerMethod = keyof WorkerApi;
116
+ /** `call` for method M, with args typed straight off `WorkerApi`. */
117
+ export type WorkerCallMessage = {
118
+ [M in WorkerMethod]: {
119
+ readonly t: 'call';
120
+ readonly id: number;
121
+ readonly method: M;
122
+ readonly args: Parameters<WorkerApi[M]>;
123
+ };
124
+ }[WorkerMethod];
125
+ export type MainToWorkerMessage = {
126
+ readonly t: 'init';
127
+ readonly id: number;
128
+ readonly config: WorkerInitConfig;
129
+ } | WorkerCallMessage;
130
+ export interface WorkerErrorShape {
131
+ readonly code: string;
132
+ readonly message: string;
133
+ readonly retryable: boolean;
134
+ }
135
+ export type SyncWorkerEvent = {
136
+ readonly kind: 'sync-needed';
137
+ readonly reason: 'hello' | WakeReason;
138
+ } | {
139
+ readonly kind: 'conflict';
140
+ readonly conflict: ConflictRecord;
141
+ } | {
142
+ /** An autoSync round finished (or failed) inside the worker. */
143
+ readonly kind: 'synced';
144
+ readonly summary?: SyncSummary;
145
+ readonly error?: WorkerErrorShape;
146
+ } | {
147
+ /** §7.4.5: the schema-bump `upgrading` state changed in the worker. */
148
+ readonly kind: 'upgrading';
149
+ readonly upgrading: boolean;
150
+ } | {
151
+ /** §8.6: presence on a scope key changed inside the worker. */
152
+ readonly kind: 'presence';
153
+ readonly scopeKey: string;
154
+ } | {
155
+ /**
156
+ * TODO 3.1 / I1: one coalesced apply-batch invalidation. `Set`s
157
+ * structured-clone across the worker boundary, so the event crosses
158
+ * verbatim — the handle re-emits it to `onInvalidate` listeners.
159
+ */
160
+ readonly kind: 'invalidate';
161
+ readonly event: InvalidationEvent;
162
+ };
163
+ export type WorkerToMainMessage = {
164
+ readonly t: 'ready';
165
+ } | {
166
+ readonly t: 'result';
167
+ readonly id: number;
168
+ readonly value: unknown;
169
+ } | {
170
+ readonly t: 'error';
171
+ readonly id: number;
172
+ readonly error: WorkerErrorShape;
173
+ } | {
174
+ readonly t: 'event';
175
+ readonly event: SyncWorkerEvent;
176
+ };
@@ -1,16 +1,7 @@
1
- import { SYNCULAR_ERROR_DEFINITIONS } from '@syncular/core';
2
- export const SYNCULAR_WORKER_PROTOCOL_VERSION = 2;
3
- export function createSyncularWorkerErrorPayload(code, message, options = {}) {
4
- const definition = SYNCULAR_ERROR_DEFINITIONS[code];
5
- return {
6
- code,
7
- message: message ?? definition.message,
8
- category: definition.category,
9
- retryable: definition.retryable,
10
- recommendedAction: definition.recommendedAction,
11
- ...(options.name ? { name: options.name } : {}),
12
- ...(options.stack ? { stack: options.stack } : {}),
13
- ...(options.details !== undefined ? { details: options.details } : {}),
14
- };
15
- }
16
- //# sourceMappingURL=worker-protocol.js.map
1
+ // ---------------------------------------------------------------------------
2
+ // Client-local error codes (never wire codes; §10 stays server-owned)
3
+ // ---------------------------------------------------------------------------
4
+ /** The handle exists but this tab lost the leader election (TODO 3.2). */
5
+ export const NOT_LEADER_CODE = 'client.not_leader';
6
+ /** The worker (or its RPC channel) failed outside protocol semantics. */
7
+ export const WORKER_FAILED_CODE = 'client.worker_failed';
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@syncular/client",
3
- "version": "0.1.3",
4
- "description": "Syncular Rust-owned SQLite browser client with optional React, host bridge, and CRDT adapter subpaths",
3
+ "version": "0.2.0",
4
+ "description": "Syncular TypeScript client core offline-first sync over SQLite (WASM/OPFS, Bun, Node)",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Benjamin Kniffler",
7
7
  "homepage": "https://syncular.dev",
8
8
  "repository": {
9
9
  "type": "git",
10
10
  "url": "https://github.com/syncular/syncular.git",
11
- "directory": "packages/client"
11
+ "directory": "packages/web-client"
12
12
  },
13
13
  "bugs": {
14
14
  "url": "https://github.com/syncular/syncular/issues"
@@ -16,18 +16,15 @@
16
16
  "keywords": [
17
17
  "sync",
18
18
  "offline-first",
19
+ "realtime",
19
20
  "database",
20
- "typescript",
21
- "rust",
22
- "wasm",
23
- "sqlite",
24
- "kysely"
21
+ "typescript"
25
22
  ],
26
- "private": false,
23
+ "type": "module",
24
+ "sideEffects": false,
27
25
  "publishConfig": {
28
26
  "access": "public"
29
27
  },
30
- "type": "module",
31
28
  "exports": {
32
29
  ".": {
33
30
  "bun": "./src/index.ts",
@@ -37,130 +34,66 @@
37
34
  "default": "./dist/index.js"
38
35
  }
39
36
  },
40
- "./worker": {
41
- "bun": "./src/worker-entry.ts",
42
- "browser": "./src/worker-entry.ts",
43
- "import": {
44
- "types": "./dist/worker-entry.d.ts",
45
- "default": "./dist/worker-entry.js"
46
- }
47
- },
48
- "./sentry": {
49
- "bun": "./src/sentry.ts",
50
- "browser": "./src/sentry.ts",
37
+ "./bun": {
38
+ "bun": "./src/bun-database.ts",
39
+ "browser": "./src/bun-database.ts",
51
40
  "import": {
52
- "types": "./dist/sentry.d.ts",
53
- "default": "./dist/sentry.js"
41
+ "types": "./dist/bun-database.d.ts",
42
+ "default": "./dist/bun-database.js"
54
43
  }
55
44
  },
56
- "./react": {
57
- "bun": "./src/react/index.ts",
58
- "browser": "./src/react/index.ts",
45
+ "./node": {
46
+ "bun": "./src/node-database.ts",
47
+ "browser": "./src/node-database.ts",
59
48
  "import": {
60
- "types": "./dist/react/index.d.ts",
61
- "default": "./dist/react/index.js"
49
+ "types": "./dist/node-database.d.ts",
50
+ "default": "./dist/node-database.js"
62
51
  }
63
52
  },
64
- "./tauri": {
65
- "bun": "./src/tauri/index.ts",
53
+ "./wasm": {
54
+ "bun": "./src/wasm-database.ts",
55
+ "browser": "./src/wasm-database.ts",
66
56
  "import": {
67
- "types": "./dist/tauri/index.d.ts",
68
- "default": "./dist/tauri/index.js"
57
+ "types": "./dist/wasm-database.d.ts",
58
+ "default": "./dist/wasm-database.js"
69
59
  }
70
60
  },
71
- "./react-native": {
72
- "bun": "./src/react-native/index.ts",
73
- "import": {
74
- "types": "./dist/react-native/index.d.ts",
75
- "default": "./dist/react-native/index.js"
76
- }
77
- },
78
- "./crdt-yjs": {
79
- "bun": "./src/crdt-yjs/index.ts",
80
- "browser": "./src/crdt-yjs/index.ts",
61
+ "./worker": {
62
+ "bun": "./src/worker-entry.ts",
63
+ "browser": "./src/worker-entry.ts",
81
64
  "import": {
82
- "types": "./dist/crdt-yjs/index.d.ts",
83
- "default": "./dist/crdt-yjs/index.js"
65
+ "types": "./dist/worker-entry.d.ts",
66
+ "default": "./dist/worker-entry.js"
84
67
  }
85
68
  }
86
69
  },
87
- "scripts": {
88
- "generate:bridge": "bun scripts/generate-bridge.ts",
89
- "generate:wasm-types": "bun scripts/generate-wasm-bindings.ts",
90
- "test": "bun test src/*.test.ts src/react/*.test.ts src/tauri/*.test.ts src/react-native/*.test.ts src/crdt-yjs/*.test.ts",
91
- "test:wasm:auth": "bun run build:wasm:dev && bun test src/__tests__/auth-hono.wasm.test.ts",
92
- "test:wasm:hono": "bun run build:wasm:dev && bun test src/__tests__/*-hono.wasm.test.ts",
93
- "test:wasm:variants": "bun run build:wasm:core && bun test src/__tests__/variant-core.wasm.test.ts",
94
- "tsgo": "tsgo --noEmit",
95
- "build:wasm": "bun scripts/build-syncular-wasm.ts --variant full && bun run generate:wasm-types && bun scripts/size-syncular-wasm.ts --check --report ../../.context/wasm-size/syncular-wasm-size.txt",
96
- "build:wasm:perf": "bun scripts/build-syncular-wasm.ts --out-dir dist/wasm-perf --variant full-perf --artifact-name full-perf --release-opt-level 3",
97
- "build:wasm:core": "bun scripts/build-syncular-wasm.ts --out-dir dist/wasm-core --features web-owned-sqlite-core --variant core",
98
- "build:wasm:variants": "bun run build:wasm && bun run build:wasm:perf && bun run build:wasm:core && bun run catalog:wasm && bun run size:wasm:core && bun run size:wasm:perf",
99
- "build:wasm:dev": "bun scripts/build-syncular-wasm.ts --dev && bun run generate:wasm-types",
100
- "catalog:wasm": "bun scripts/write-syncular-wasm-catalog.ts --artifact dist/wasm-core --artifact dist/wasm --artifact dist/wasm-perf",
101
- "size:wasm": "bun scripts/size-syncular-wasm.ts",
102
- "size:wasm:check": "bun scripts/size-syncular-wasm.ts --check --attribution --report ../../.context/wasm-size/syncular-wasm-size.txt",
103
- "size:wasm:core": "bun scripts/size-syncular-wasm.ts --wasm dist/wasm-core/syncular_bg.wasm --report ../../.context/wasm-size/syncular-wasm-core-size.txt",
104
- "size:wasm:perf": "bun scripts/size-syncular-wasm.ts --wasm dist/wasm-perf/syncular_bg.wasm --report ../../.context/wasm-size/syncular-wasm-perf-size.txt",
105
- "build": "bun run build:wasm:variants && tsgo",
106
- "release": "syncular-publish"
107
- },
108
- "dependencies": {
109
- "@syncular/core": "0.1.3",
110
- "kysely": "^0.28.0",
111
- "kysely-generic-sqlite": "^1.2.1"
112
- },
113
- "devDependencies": {
114
- "@happy-dom/global-registrator": "^20.8.9",
115
- "@sentry/react": "^10.47.0",
116
- "@syncular/config": "0.0.0",
117
- "@testing-library/react": "^16.3.2",
118
- "@types/react": "^19.2.14",
119
- "hono": "^4.12.15",
120
- "react": "*",
121
- "yjs": "^13.6.30"
122
- },
123
70
  "files": [
124
- "dist/*.d.ts",
125
- "dist/*.d.ts.map",
126
- "dist/*.js",
127
- "dist/*.js.map",
128
- "dist/crdt-yjs",
129
- "dist/react",
130
- "dist/react-native",
131
- "dist/syncular-runtime-artifacts.json",
132
- "dist/tauri",
133
- "dist/wasm",
134
- "dist/wasm-bindings",
135
- "dist/wasm-core",
136
- "dist/wasm-perf",
71
+ "dist",
137
72
  "src",
73
+ "README.md",
138
74
  "!src/**/*.test.ts",
139
75
  "!src/**/*.test.tsx",
140
- "!src/**/__tests__/**",
141
- "!dist/**/*.test.*",
142
- "!dist/**/__tests__/**",
143
- "!test/**",
144
- "!tests/**"
76
+ "!dist/**/*.test.js",
77
+ "!dist/**/*.test.d.ts"
145
78
  ],
79
+ "scripts": {
80
+ "verify:node": "bun build ./test/node-database/verify-node.mjs --target=node --external better-sqlite3 --outfile=./.verify-node.built.mjs && node ./.verify-node.built.mjs"
81
+ },
82
+ "dependencies": {
83
+ "@sqlite.org/sqlite-wasm": "^3.53.0-build1",
84
+ "@syncular/core": "0.2.0"
85
+ },
146
86
  "peerDependencies": {
147
- "@sentry/react": "^10.47.0",
148
- "react": "^18.0.0 || ^19.0.0",
149
- "react-native": "*",
150
- "yjs": "^13.6.30"
87
+ "better-sqlite3": ">=11"
151
88
  },
152
89
  "peerDependenciesMeta": {
153
- "@sentry/react": {
154
- "optional": true
155
- },
156
- "react": {
157
- "optional": true
158
- },
159
- "react-native": {
160
- "optional": true
161
- },
162
- "yjs": {
90
+ "better-sqlite3": {
163
91
  "optional": true
164
92
  }
93
+ },
94
+ "devDependencies": {
95
+ "@syncular/server": "0.2.0",
96
+ "@types/better-sqlite3": "^7.6.13",
97
+ "better-sqlite3": "^12.11.1"
165
98
  }
166
99
  }