tetherdb 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.
Files changed (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +277 -0
  3. package/bin/tetherdb.js +7 -0
  4. package/dist/cli/args.d.cts +20 -0
  5. package/dist/cli/args.d.ts +20 -0
  6. package/dist/cli/args.d.ts.map +1 -0
  7. package/dist/cli/backend.d.cts +15 -0
  8. package/dist/cli/backend.d.ts +15 -0
  9. package/dist/cli/backend.d.ts.map +1 -0
  10. package/dist/cli/cli.d.cts +8 -0
  11. package/dist/cli/cli.d.ts +8 -0
  12. package/dist/cli/cli.d.ts.map +1 -0
  13. package/dist/cli/commands/apps.d.cts +9 -0
  14. package/dist/cli/commands/apps.d.ts +9 -0
  15. package/dist/cli/commands/apps.d.ts.map +1 -0
  16. package/dist/cli/commands/help.d.cts +5 -0
  17. package/dist/cli/commands/help.d.ts +5 -0
  18. package/dist/cli/commands/help.d.ts.map +1 -0
  19. package/dist/cli/commands/index.d.cts +8 -0
  20. package/dist/cli/commands/index.d.ts +8 -0
  21. package/dist/cli/commands/index.d.ts.map +1 -0
  22. package/dist/cli/commands/maintenance.d.cts +9 -0
  23. package/dist/cli/commands/maintenance.d.ts +9 -0
  24. package/dist/cli/commands/maintenance.d.ts.map +1 -0
  25. package/dist/cli/commands/serve.d.cts +14 -0
  26. package/dist/cli/commands/serve.d.ts +14 -0
  27. package/dist/cli/commands/serve.d.ts.map +1 -0
  28. package/dist/cli/commands/status.d.cts +9 -0
  29. package/dist/cli/commands/status.d.ts +9 -0
  30. package/dist/cli/commands/status.d.ts.map +1 -0
  31. package/dist/cli/commands/tables.d.cts +9 -0
  32. package/dist/cli/commands/tables.d.ts +9 -0
  33. package/dist/cli/commands/tables.d.ts.map +1 -0
  34. package/dist/cli/commands/users.d.cts +9 -0
  35. package/dist/cli/commands/users.d.ts +9 -0
  36. package/dist/cli/commands/users.d.ts.map +1 -0
  37. package/dist/cli/index.cjs +3999 -0
  38. package/dist/cli/index.cjs.map +1 -0
  39. package/dist/cli/index.d.cts +7 -0
  40. package/dist/cli/index.d.ts +7 -0
  41. package/dist/cli/index.d.ts.map +1 -0
  42. package/dist/cli/index.js +3958 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/client/auth.d.cts +155 -0
  45. package/dist/client/auth.d.ts +155 -0
  46. package/dist/client/auth.d.ts.map +1 -0
  47. package/dist/client/client.d.cts +122 -0
  48. package/dist/client/client.d.ts +122 -0
  49. package/dist/client/client.d.ts.map +1 -0
  50. package/dist/client/errors.d.cts +39 -0
  51. package/dist/client/errors.d.ts +39 -0
  52. package/dist/client/errors.d.ts.map +1 -0
  53. package/dist/client/index.cjs +1742 -0
  54. package/dist/client/index.cjs.map +1 -0
  55. package/dist/client/index.d.cts +12 -0
  56. package/dist/client/index.d.ts +12 -0
  57. package/dist/client/index.d.ts.map +1 -0
  58. package/dist/client/index.js +1707 -0
  59. package/dist/client/index.js.map +1 -0
  60. package/dist/client/shared/event.d.cts +29 -0
  61. package/dist/client/shared/event.d.ts +29 -0
  62. package/dist/client/shared/event.d.ts.map +1 -0
  63. package/dist/client/shared/id.d.cts +5 -0
  64. package/dist/client/shared/id.d.ts +5 -0
  65. package/dist/client/shared/id.d.ts.map +1 -0
  66. package/dist/client/storage.d.cts +183 -0
  67. package/dist/client/storage.d.ts +183 -0
  68. package/dist/client/storage.d.ts.map +1 -0
  69. package/dist/client/sync.d.cts +126 -0
  70. package/dist/client/sync.d.ts +126 -0
  71. package/dist/client/sync.d.ts.map +1 -0
  72. package/dist/client/table.d.cts +146 -0
  73. package/dist/client/table.d.ts +146 -0
  74. package/dist/client/table.d.ts.map +1 -0
  75. package/dist/index.cjs +1742 -0
  76. package/dist/index.cjs.map +1 -0
  77. package/dist/index.d.cts +7 -0
  78. package/dist/index.d.ts +7 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +1707 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/server/crypto.d.cts +55 -0
  83. package/dist/server/crypto.d.ts +55 -0
  84. package/dist/server/crypto.d.ts.map +1 -0
  85. package/dist/server/errors.d.cts +39 -0
  86. package/dist/server/errors.d.ts +39 -0
  87. package/dist/server/errors.d.ts.map +1 -0
  88. package/dist/server/index.cjs +3621 -0
  89. package/dist/server/index.cjs.map +1 -0
  90. package/dist/server/index.d.cts +10 -0
  91. package/dist/server/index.d.ts +10 -0
  92. package/dist/server/index.d.ts.map +1 -0
  93. package/dist/server/index.js +3569 -0
  94. package/dist/server/index.js.map +1 -0
  95. package/dist/server/lock.d.cts +56 -0
  96. package/dist/server/lock.d.ts +56 -0
  97. package/dist/server/lock.d.ts.map +1 -0
  98. package/dist/server/rate-limiter.d.cts +81 -0
  99. package/dist/server/rate-limiter.d.ts +81 -0
  100. package/dist/server/rate-limiter.d.ts.map +1 -0
  101. package/dist/server/server.d.cts +206 -0
  102. package/dist/server/server.d.ts +206 -0
  103. package/dist/server/server.d.ts.map +1 -0
  104. package/dist/server/storage/app.d.cts +70 -0
  105. package/dist/server/storage/app.d.ts +70 -0
  106. package/dist/server/storage/app.d.ts.map +1 -0
  107. package/dist/server/storage/base/app.d.cts +42 -0
  108. package/dist/server/storage/base/app.d.ts +42 -0
  109. package/dist/server/storage/base/app.d.ts.map +1 -0
  110. package/dist/server/storage/base/index.d.cts +5 -0
  111. package/dist/server/storage/base/index.d.ts +5 -0
  112. package/dist/server/storage/base/index.d.ts.map +1 -0
  113. package/dist/server/storage/base/storage.d.cts +40 -0
  114. package/dist/server/storage/base/storage.d.ts +40 -0
  115. package/dist/server/storage/base/storage.d.ts.map +1 -0
  116. package/dist/server/storage/base/table.d.cts +32 -0
  117. package/dist/server/storage/base/table.d.ts +32 -0
  118. package/dist/server/storage/base/table.d.ts.map +1 -0
  119. package/dist/server/storage/base/user.d.cts +31 -0
  120. package/dist/server/storage/base/user.d.ts +31 -0
  121. package/dist/server/storage/base/user.d.ts.map +1 -0
  122. package/dist/server/storage/file/app.d.cts +50 -0
  123. package/dist/server/storage/file/app.d.ts +50 -0
  124. package/dist/server/storage/file/app.d.ts.map +1 -0
  125. package/dist/server/storage/file/index.d.cts +5 -0
  126. package/dist/server/storage/file/index.d.ts +5 -0
  127. package/dist/server/storage/file/index.d.ts.map +1 -0
  128. package/dist/server/storage/file/storage.d.cts +67 -0
  129. package/dist/server/storage/file/storage.d.ts +67 -0
  130. package/dist/server/storage/file/storage.d.ts.map +1 -0
  131. package/dist/server/storage/file/table.d.cts +14 -0
  132. package/dist/server/storage/file/table.d.ts +14 -0
  133. package/dist/server/storage/file/table.d.ts.map +1 -0
  134. package/dist/server/storage/file/user.d.cts +14 -0
  135. package/dist/server/storage/file/user.d.ts +14 -0
  136. package/dist/server/storage/file/user.d.ts.map +1 -0
  137. package/dist/server/storage/index.d.cts +14 -0
  138. package/dist/server/storage/index.d.ts +14 -0
  139. package/dist/server/storage/index.d.ts.map +1 -0
  140. package/dist/server/storage/memory/app.d.cts +29 -0
  141. package/dist/server/storage/memory/app.d.ts +29 -0
  142. package/dist/server/storage/memory/app.d.ts.map +1 -0
  143. package/dist/server/storage/memory/index.d.cts +5 -0
  144. package/dist/server/storage/memory/index.d.ts +5 -0
  145. package/dist/server/storage/memory/index.d.ts.map +1 -0
  146. package/dist/server/storage/memory/storage.d.cts +47 -0
  147. package/dist/server/storage/memory/storage.d.ts +47 -0
  148. package/dist/server/storage/memory/storage.d.ts.map +1 -0
  149. package/dist/server/storage/memory/table.d.cts +17 -0
  150. package/dist/server/storage/memory/table.d.ts +17 -0
  151. package/dist/server/storage/memory/table.d.ts.map +1 -0
  152. package/dist/server/storage/memory/user.d.cts +21 -0
  153. package/dist/server/storage/memory/user.d.ts +21 -0
  154. package/dist/server/storage/memory/user.d.ts.map +1 -0
  155. package/dist/server/storage/sqlite/app.d.cts +31 -0
  156. package/dist/server/storage/sqlite/app.d.ts +31 -0
  157. package/dist/server/storage/sqlite/app.d.ts.map +1 -0
  158. package/dist/server/storage/sqlite/index.d.cts +5 -0
  159. package/dist/server/storage/sqlite/index.d.ts +5 -0
  160. package/dist/server/storage/sqlite/index.d.ts.map +1 -0
  161. package/dist/server/storage/sqlite/storage.d.cts +92 -0
  162. package/dist/server/storage/sqlite/storage.d.ts +92 -0
  163. package/dist/server/storage/sqlite/storage.d.ts.map +1 -0
  164. package/dist/server/storage/sqlite/table.d.cts +15 -0
  165. package/dist/server/storage/sqlite/table.d.ts +15 -0
  166. package/dist/server/storage/sqlite/table.d.ts.map +1 -0
  167. package/dist/server/storage/sqlite/user.d.cts +14 -0
  168. package/dist/server/storage/sqlite/user.d.ts +14 -0
  169. package/dist/server/storage/sqlite/user.d.ts.map +1 -0
  170. package/dist/server/storage/storage.d.cts +152 -0
  171. package/dist/server/storage/storage.d.ts +152 -0
  172. package/dist/server/storage/storage.d.ts.map +1 -0
  173. package/dist/server/storage/table.d.cts +45 -0
  174. package/dist/server/storage/table.d.ts +45 -0
  175. package/dist/server/storage/table.d.ts.map +1 -0
  176. package/dist/server/storage/user.d.cts +45 -0
  177. package/dist/server/storage/user.d.ts +45 -0
  178. package/dist/server/storage/user.d.ts.map +1 -0
  179. package/dist/server/sync.d.cts +67 -0
  180. package/dist/server/sync.d.ts +67 -0
  181. package/dist/server/sync.d.ts.map +1 -0
  182. package/dist/server/validate.d.cts +113 -0
  183. package/dist/server/validate.d.ts +113 -0
  184. package/dist/server/validate.d.ts.map +1 -0
  185. package/dist/shared/clock.d.cts +22 -0
  186. package/dist/shared/clock.d.ts +22 -0
  187. package/dist/shared/clock.d.ts.map +1 -0
  188. package/dist/shared/path.d.cts +12 -0
  189. package/dist/shared/path.d.ts +12 -0
  190. package/dist/shared/path.d.ts.map +1 -0
  191. package/dist/shared/types.d.cts +234 -0
  192. package/dist/shared/types.d.ts +234 -0
  193. package/dist/shared/types.d.ts.map +1 -0
  194. package/package.json +133 -0
@@ -0,0 +1,183 @@
1
+ import { type ChangeRecord, OperationType, type SnapshotRecord, type StoredRecord } from '../shared/types.js';
2
+ import { EventRegistry } from './shared/event.js';
3
+ import { Table } from './table.js';
4
+ /**
5
+ * Represents a pending mutation queue item within the internal IndexedDB outbox.
6
+ */
7
+ export interface OutboxEntry {
8
+ /** Auto-incrementing primary key in the outbox object store. */
9
+ localId?: number;
10
+ /** Transient batch correlation identifier. */
11
+ batchId?: string;
12
+ /** The mutation change record to be synced to the server. */
13
+ change: ChangeRecord;
14
+ /** Epoch timestamp when the entry was queued locally. */
15
+ createdAt: number;
16
+ }
17
+ /**
18
+ * Mutation item payload passed to `Storage.applyLocalChanges`.
19
+ */
20
+ export interface LocalMutationItem<T = unknown> {
21
+ /** Target record identifier. */
22
+ id: string;
23
+ /** Mutation operation type. */
24
+ op: OperationType;
25
+ /** Record data payload (defined on put). */
26
+ data?: T;
27
+ /** Correlated changelog entry to queue in outbox. */
28
+ change: ChangeRecord<T>;
29
+ }
30
+ /**
31
+ * Atomic transaction and local persistence manager wrapping IndexedDB.
32
+ * Coordinates user table stores, pending outbox changelogs, and sync metadata.
33
+ */
34
+ export declare class Storage {
35
+ /** Name of the local IndexedDB database. */
36
+ readonly name: string;
37
+ /** Unique client instance identifier used for monotonic logical clock tie-breaking. */
38
+ readonly clientId: string;
39
+ /** Reactive event registry triggered when mutations are committed to the local database. */
40
+ readonly onLocalChange: EventRegistry<void>;
41
+ private databasePromise;
42
+ private schemaMutex;
43
+ private tables;
44
+ /**
45
+ * Creates a new Storage instance.
46
+ *
47
+ * @param name - Name of the IndexedDB database.
48
+ */
49
+ constructor(name: string);
50
+ /**
51
+ * Obtains a typed table reference for reading, mutating, and subscribing to records.
52
+ * Tables are created dynamically on-demand if not already declared.
53
+ *
54
+ * @typeParam T - Data payload model type for records in this table.
55
+ * @param name - The table name.
56
+ * @returns A typed `Table<T>` instance.
57
+ */
58
+ table<T = unknown>(name: string): Table<T>;
59
+ /**
60
+ * Opens or returns the active IndexedDB connection, executing schema upgrades when needed.
61
+ *
62
+ * @returns A promise resolving to the open IDBDatabase instance.
63
+ */
64
+ getDatabase(): Promise<IDBDatabase>;
65
+ /**
66
+ * Dynamically ensures that multiple application tables exist in IndexedDB.
67
+ *
68
+ * @param tableNames - Array of table names to ensure.
69
+ */
70
+ ensureTables(tableNames: string[]): Promise<void>;
71
+ /**
72
+ * Ensures a single application table exists in IndexedDB.
73
+ *
74
+ * @param tableName - Name of the table to ensure.
75
+ */
76
+ ensureTable(tableName: string): Promise<void>;
77
+ /**
78
+ * Retrieves a metadata value from the internal metadata store.
79
+ *
80
+ * @typeParam T - Expected value type.
81
+ * @param key - The metadata key identifier.
82
+ * @returns The stored metadata value, or `undefined` if not set.
83
+ */
84
+ getMeta<T = unknown>(key: string): Promise<T | undefined>;
85
+ /**
86
+ * Sets a metadata value in the internal metadata store.
87
+ *
88
+ * @param key - The metadata key identifier.
89
+ * @param value - The value to store.
90
+ */
91
+ setMeta(key: string, value: unknown): Promise<void>;
92
+ /**
93
+ * Deletes a metadata entry from the internal metadata store.
94
+ *
95
+ * @param key - The metadata key identifier.
96
+ */
97
+ deleteMeta(key: string): Promise<void>;
98
+ /**
99
+ * Retrieves a single stored record by table and identifier.
100
+ *
101
+ * @typeParam T - Expected payload type.
102
+ * @param tableName - Table name.
103
+ * @param id - Record identifier.
104
+ * @returns Stored record or `undefined` if not found.
105
+ */
106
+ getRecord<T = unknown>(tableName: string, id: string): Promise<StoredRecord<T> | undefined>;
107
+ /**
108
+ * Retrieves multiple stored records by their identifiers in a single readonly transaction.
109
+ *
110
+ * @typeParam T - Expected payload type.
111
+ * @param tableName - Table name.
112
+ * @param ids - Array of record identifiers.
113
+ * @returns Map of found stored records keyed by id.
114
+ */
115
+ getRecords<T = unknown>(tableName: string, ids: string[]): Promise<Map<string, StoredRecord<T>>>;
116
+ /**
117
+ * Retrieves stored records from a specified table.
118
+ *
119
+ * @typeParam T - Data payload type.
120
+ * @param tableName - Table name.
121
+ * @returns Array of stored records with metadata.
122
+ */
123
+ getAllRecords<T = unknown>(tableName: string): Promise<StoredRecord<T>[]>;
124
+ /**
125
+ * Atomically persists a batch of local mutations alongside outbox changelog entries
126
+ * within a single IndexedDB transaction.
127
+ *
128
+ * @typeParam T - Data payload type.
129
+ * @param tableName - Target table name.
130
+ * @param mutations - List of mutations to apply and queue into outbox.
131
+ * @returns Array of newly stored records with updated metadata.
132
+ */
133
+ applyLocalChanges<T = unknown>(tableName: string, mutations: LocalMutationItem<T>[]): Promise<StoredRecord<T>[]>;
134
+ /**
135
+ * Retrieves all currently queued outbox entries awaiting sync.
136
+ *
137
+ * @param limit - Optional maximum number of entries to retrieve.
138
+ * @returns Array of pending outbox queue items.
139
+ */
140
+ getPendingOutbox(limit?: number): Promise<OutboxEntry[]>;
141
+ /**
142
+ * Clears acknowledged changes from the outbox by their local database IDs.
143
+ *
144
+ * @param localIds - Array of auto-incremented local outbox IDs to remove.
145
+ */
146
+ removeOutboxEntries(localIds: number[]): Promise<void>;
147
+ /**
148
+ * Applies an entire snapshot batch across tables atomically in a single transaction.
149
+ *
150
+ * @param snapshot - Array of record items to persist.
151
+ * @param seq - Global sequence number corresponding to this snapshot.
152
+ */
153
+ applySnapshotBatch(snapshot: SnapshotRecord[], seq: number): Promise<void>;
154
+ /**
155
+ * Applies a batch of incoming remote delta mutations atomically across tables
156
+ * in a single IndexedDB transaction without generating local outbox echo entries.
157
+ *
158
+ * @param changes - Array of change records received from the server.
159
+ * @param seq - New sequence number to record upon transaction commit.
160
+ */
161
+ applyRemoteChangesBatch(changes: ChangeRecord[], seq: number): Promise<void>;
162
+ /**
163
+ * Clears only user table stores, leaving internal metadata and outbox intact if desired.
164
+ *
165
+ * @param clearOutbox - Whether to clear the pending outbox queue as well (defaults to `true`).
166
+ */
167
+ clearTables(clearOutbox?: boolean): Promise<void>;
168
+ /**
169
+ * Clears all local table stores, outbox changelog entries, and metadata.
170
+ */
171
+ clearAllData(): Promise<void>;
172
+ /**
173
+ * Closes the active IndexedDB connection.
174
+ */
175
+ close(): Promise<void>;
176
+ private withDatabase;
177
+ private applyBatchRecords;
178
+ private clearStores;
179
+ private openDatabase;
180
+ private upgradeDatabase;
181
+ private createInternalStores;
182
+ }
183
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/client/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import { TetherClientError } from './errors.cjs';
2
+ import { EventRegistry } from './shared/event.cjs';
3
+ import type { Storage } from './storage.cjs';
4
+ /**
5
+ * Operational state of the synchronization coordinator.
6
+ */
7
+ export declare enum SyncStatus {
8
+ /** Disconnected from the remote synchronization server. */
9
+ Disconnected = 0,
10
+ /** Currently establishing a WebSocket connection. */
11
+ Connecting = 1,
12
+ /** Authenticated and actively synchronizing in real time. */
13
+ Connected = 2,
14
+ /** Synchronization halted due to an unrecoverable error (e.g. invalid auth token). */
15
+ Error = 3
16
+ }
17
+ /**
18
+ * Constructor signature for WebSocket implementations (native browser WebSocket or 'ws' package).
19
+ */
20
+ export type WebSocketConstructor = new (url: string | URL, protocols?: string | string[] | WebSocketInit) => WebSocket;
21
+ /**
22
+ * Configuration options for Sync.
23
+ */
24
+ export interface SyncOptions {
25
+ /** WebSocket URL of the sync endpoint (e.g. 'ws://localhost:8080/sync'). */
26
+ url?: string;
27
+ /** Signed authentication session token. */
28
+ token?: string;
29
+ /** Application namespace identifier. */
30
+ appId: string;
31
+ /** Unique client instance identifier. */
32
+ clientId: string;
33
+ /** Initial reconnection backoff delay in milliseconds (defaults to 1000). */
34
+ reconnectIntervalMs?: number;
35
+ /** Maximum reconnection backoff delay in milliseconds (defaults to 30000). */
36
+ maxReconnectIntervalMs?: number;
37
+ /** Periodic keepalive ping interval in milliseconds (defaults to 30000). Set to 0 to disable. */
38
+ pingIntervalMs?: number;
39
+ /** Debounce delay in milliseconds before pushing queued local outbox changes (defaults to 10). */
40
+ pushDebounceMs?: number;
41
+ /** Custom WebSocket constructor for Node.js environments. */
42
+ webSocketClass?: WebSocketConstructor;
43
+ /** Callback invoked when the server provides a refreshed session token. */
44
+ onTokenRefresh?: (token: string) => void;
45
+ /** Callback invoked when the server rejects authentication. */
46
+ onAuthError?: (message: string) => void;
47
+ }
48
+ /**
49
+ * Two-way WebSocket sync coordinator managing initial snapshot / diff downloads,
50
+ * batched outbox queue flushing, acknowledgments, and auto-reconnect backoff.
51
+ */
52
+ export declare class Sync {
53
+ /** Remote WebSocket endpoint URL. */
54
+ url?: string;
55
+ /** Application namespace identifier for partitioning synchronization channels. */
56
+ readonly appId: string;
57
+ /** Client identifier used for conflict resolution tie-breaking. */
58
+ readonly clientId: string;
59
+ /** Reactive event registry triggered whenever synchronization status transitions. */
60
+ readonly onStatusChange: EventRegistry<SyncStatus>;
61
+ /** Reactive event registry triggered whenever background sync or network errors occur. */
62
+ readonly onError: EventRegistry<TetherClientError>;
63
+ private token?;
64
+ private storage;
65
+ private options;
66
+ private webSocket;
67
+ private currentStatus;
68
+ private reconnectTimer;
69
+ private reconnectAttempts;
70
+ private pingTimer;
71
+ private pushTimer;
72
+ private isPushing;
73
+ private isDestroyed;
74
+ private pendingBatches;
75
+ private messageQueue;
76
+ /**
77
+ * Creates a new Sync instance.
78
+ *
79
+ * @param storage - Local storage coordinator.
80
+ * @param options - Configuration options for sync and connection.
81
+ */
82
+ constructor(storage: Storage, options: SyncOptions);
83
+ /**
84
+ * Current operational status of the sync coordinator.
85
+ */
86
+ get status(): SyncStatus;
87
+ /**
88
+ * Initiates a WebSocket connection to the sync endpoint and sends authentication.
89
+ *
90
+ * @param token - Optional session token to connect with.
91
+ * @param url - Optional WebSocket URL override.
92
+ */
93
+ connect(token?: string, url?: string): void;
94
+ /**
95
+ * Disconnects the active WebSocket connection.
96
+ */
97
+ disconnect(): void;
98
+ /**
99
+ * Permanently tears down the sync coordinator and cancels reconnection timers.
100
+ */
101
+ destroy(): void;
102
+ /**
103
+ * Schedules a debounced push of pending outbox mutations.
104
+ *
105
+ * @param delayMs - Optional override for debounce delay in milliseconds.
106
+ */
107
+ schedulePush(delayMs?: number): void;
108
+ /**
109
+ * Immediately extracts queued outbox changes and transmits them to the server.
110
+ */
111
+ pushOutbox(): Promise<void>;
112
+ private setStatus;
113
+ private startPing;
114
+ private stopPing;
115
+ private isOnline;
116
+ private handleOnline;
117
+ private handleOffline;
118
+ private scheduleReconnect;
119
+ private send;
120
+ private sendAuth;
121
+ private handleServerMessage;
122
+ private handleSnapshot;
123
+ private handleDiff;
124
+ private notifyTableRemoteEvents;
125
+ }
126
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1,126 @@
1
+ import { TetherClientError } from './errors.js';
2
+ import { EventRegistry } from './shared/event.js';
3
+ import type { Storage } from './storage.js';
4
+ /**
5
+ * Operational state of the synchronization coordinator.
6
+ */
7
+ export declare enum SyncStatus {
8
+ /** Disconnected from the remote synchronization server. */
9
+ Disconnected = 0,
10
+ /** Currently establishing a WebSocket connection. */
11
+ Connecting = 1,
12
+ /** Authenticated and actively synchronizing in real time. */
13
+ Connected = 2,
14
+ /** Synchronization halted due to an unrecoverable error (e.g. invalid auth token). */
15
+ Error = 3
16
+ }
17
+ /**
18
+ * Constructor signature for WebSocket implementations (native browser WebSocket or 'ws' package).
19
+ */
20
+ export type WebSocketConstructor = new (url: string | URL, protocols?: string | string[] | WebSocketInit) => WebSocket;
21
+ /**
22
+ * Configuration options for Sync.
23
+ */
24
+ export interface SyncOptions {
25
+ /** WebSocket URL of the sync endpoint (e.g. 'ws://localhost:8080/sync'). */
26
+ url?: string;
27
+ /** Signed authentication session token. */
28
+ token?: string;
29
+ /** Application namespace identifier. */
30
+ appId: string;
31
+ /** Unique client instance identifier. */
32
+ clientId: string;
33
+ /** Initial reconnection backoff delay in milliseconds (defaults to 1000). */
34
+ reconnectIntervalMs?: number;
35
+ /** Maximum reconnection backoff delay in milliseconds (defaults to 30000). */
36
+ maxReconnectIntervalMs?: number;
37
+ /** Periodic keepalive ping interval in milliseconds (defaults to 30000). Set to 0 to disable. */
38
+ pingIntervalMs?: number;
39
+ /** Debounce delay in milliseconds before pushing queued local outbox changes (defaults to 10). */
40
+ pushDebounceMs?: number;
41
+ /** Custom WebSocket constructor for Node.js environments. */
42
+ webSocketClass?: WebSocketConstructor;
43
+ /** Callback invoked when the server provides a refreshed session token. */
44
+ onTokenRefresh?: (token: string) => void;
45
+ /** Callback invoked when the server rejects authentication. */
46
+ onAuthError?: (message: string) => void;
47
+ }
48
+ /**
49
+ * Two-way WebSocket sync coordinator managing initial snapshot / diff downloads,
50
+ * batched outbox queue flushing, acknowledgments, and auto-reconnect backoff.
51
+ */
52
+ export declare class Sync {
53
+ /** Remote WebSocket endpoint URL. */
54
+ url?: string;
55
+ /** Application namespace identifier for partitioning synchronization channels. */
56
+ readonly appId: string;
57
+ /** Client identifier used for conflict resolution tie-breaking. */
58
+ readonly clientId: string;
59
+ /** Reactive event registry triggered whenever synchronization status transitions. */
60
+ readonly onStatusChange: EventRegistry<SyncStatus>;
61
+ /** Reactive event registry triggered whenever background sync or network errors occur. */
62
+ readonly onError: EventRegistry<TetherClientError>;
63
+ private token?;
64
+ private storage;
65
+ private options;
66
+ private webSocket;
67
+ private currentStatus;
68
+ private reconnectTimer;
69
+ private reconnectAttempts;
70
+ private pingTimer;
71
+ private pushTimer;
72
+ private isPushing;
73
+ private isDestroyed;
74
+ private pendingBatches;
75
+ private messageQueue;
76
+ /**
77
+ * Creates a new Sync instance.
78
+ *
79
+ * @param storage - Local storage coordinator.
80
+ * @param options - Configuration options for sync and connection.
81
+ */
82
+ constructor(storage: Storage, options: SyncOptions);
83
+ /**
84
+ * Current operational status of the sync coordinator.
85
+ */
86
+ get status(): SyncStatus;
87
+ /**
88
+ * Initiates a WebSocket connection to the sync endpoint and sends authentication.
89
+ *
90
+ * @param token - Optional session token to connect with.
91
+ * @param url - Optional WebSocket URL override.
92
+ */
93
+ connect(token?: string, url?: string): void;
94
+ /**
95
+ * Disconnects the active WebSocket connection.
96
+ */
97
+ disconnect(): void;
98
+ /**
99
+ * Permanently tears down the sync coordinator and cancels reconnection timers.
100
+ */
101
+ destroy(): void;
102
+ /**
103
+ * Schedules a debounced push of pending outbox mutations.
104
+ *
105
+ * @param delayMs - Optional override for debounce delay in milliseconds.
106
+ */
107
+ schedulePush(delayMs?: number): void;
108
+ /**
109
+ * Immediately extracts queued outbox changes and transmits them to the server.
110
+ */
111
+ pushOutbox(): Promise<void>;
112
+ private setStatus;
113
+ private startPing;
114
+ private stopPing;
115
+ private isOnline;
116
+ private handleOnline;
117
+ private handleOffline;
118
+ private scheduleReconnect;
119
+ private send;
120
+ private sendAuth;
121
+ private handleServerMessage;
122
+ private handleSnapshot;
123
+ private handleDiff;
124
+ private notifyTableRemoteEvents;
125
+ }
126
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/client/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import { OperationType, type StoredRecord } from '../shared/types.cjs';
2
+ import { EventRegistry } from './shared/event.cjs';
3
+ import type { Storage } from './storage.cjs';
4
+ /**
5
+ * Event describing a mutation (insert, update, delete) on a table record.
6
+ *
7
+ * @typeParam T - Data payload type.
8
+ */
9
+ export interface TableChangeEvent<T = unknown> {
10
+ /** The mutation operation type. */
11
+ op: OperationType;
12
+ /** The affected record identifier. */
13
+ id: string;
14
+ /** The new record data (defined on 'put' operations). */
15
+ data?: T;
16
+ /** `true` if the change originated from remote synchronization; `false` if triggered locally. */
17
+ isRemote?: boolean;
18
+ }
19
+ /**
20
+ * Entry item for bulk insertion/update via `Table.putAll`.
21
+ *
22
+ * @typeParam T - Data payload type.
23
+ */
24
+ export interface TablePutEntry<T = unknown> {
25
+ /** Target record identifier. */
26
+ id: string;
27
+ /** Record data payload. */
28
+ data: T;
29
+ }
30
+ /**
31
+ * Event notification callback fired when records are inserted, updated, or deleted.
32
+ * Always receives a list of change events.
33
+ *
34
+ * @typeParam T - Data payload type.
35
+ * @param events - List of change events that occurred.
36
+ */
37
+ export type TableChangeListener<T = unknown> = (events: TableChangeEvent<T>[]) => void;
38
+ /**
39
+ * Typed table wrapper providing local-first CRUD operations and reactive event subscriptions
40
+ * against an underlying IndexedDB table.
41
+ * Operations are batched by default for maximum performance.
42
+ *
43
+ * @typeParam T - The data type of records stored in this table.
44
+ */
45
+ export declare class Table<T = unknown> {
46
+ /** Reactive event registry triggered when records in this table are created, updated, or deleted. */
47
+ readonly onChange: EventRegistry<TableChangeEvent<T>[]>;
48
+ private tableName;
49
+ private storage;
50
+ /**
51
+ * Creates a new Table instance.
52
+ *
53
+ * @param tableName - Name of the table.
54
+ * @param storage - Local storage coordinator.
55
+ */
56
+ constructor(tableName: string, storage: Storage);
57
+ /**
58
+ * The name of the table.
59
+ */
60
+ get name(): string;
61
+ /**
62
+ * The client identifier for local mutations.
63
+ */
64
+ get clientId(): string;
65
+ /**
66
+ * Retrieves a single record by its identifier.
67
+ *
68
+ * @param id - The unique record identifier.
69
+ * @returns A promise resolving to the record data, or `undefined` if not found.
70
+ */
71
+ get(id: string): Promise<T | undefined>;
72
+ /**
73
+ * Retrieves records stored in this table, optionally filtered by a list of IDs.
74
+ *
75
+ * @param ids - Optional list of record identifiers to fetch. If omitted, retrieves all records.
76
+ * @returns A promise resolving to an array of record data objects.
77
+ */
78
+ getAll(ids?: string[]): Promise<T[]>;
79
+ /**
80
+ * Deletes all records in this table and queues tombstones for synchronization.
81
+ *
82
+ * @returns A promise resolving to the number of deleted records.
83
+ */
84
+ clear(): Promise<number>;
85
+ /**
86
+ * Retrieves a single stored record including metadata (version, timestamp).
87
+ *
88
+ * @param id - The unique record identifier.
89
+ * @returns A promise resolving to the stored record with metadata, or `undefined` if not found.
90
+ */
91
+ getWithMetadata(id: string): Promise<StoredRecord<T> | undefined>;
92
+ /**
93
+ * Retrieves all records with storage metadata (version, timestamp).
94
+ *
95
+ * @returns A promise resolving to an array of stored records with metadata.
96
+ */
97
+ getAllWithMetadata(): Promise<StoredRecord<T>[]>;
98
+ /**
99
+ * Stores or updates a record locally and triggers synchronization.
100
+ *
101
+ * @param id - The unique record identifier.
102
+ * @param data - The data payload to save.
103
+ * @returns A promise resolving to the saved data.
104
+ */
105
+ put(id: string, data: T): Promise<T>;
106
+ /**
107
+ * Atomically stores or updates multiple records locally in a single batch,
108
+ * queues outbox mutations, notifies subscribers with an event list, and triggers synchronization.
109
+ *
110
+ * @param entries - Array of record entries to save.
111
+ * @returns A promise resolving to the array of saved data objects.
112
+ */
113
+ putAll(entries: TablePutEntry<T>[]): Promise<T[]>;
114
+ /**
115
+ * Deletes a record locally by creating a tombstone and triggers synchronization.
116
+ *
117
+ * @param id - The unique record identifier to delete.
118
+ * @returns A promise resolving to `true` if the record existed and was deleted; otherwise `false`.
119
+ */
120
+ delete(id: string): Promise<boolean>;
121
+ /**
122
+ * Atomically deletes multiple records locally in a single batch,
123
+ * creates tombstones, notifies subscribers with an event list, and triggers synchronization.
124
+ *
125
+ * @param ids - Array of record identifiers to delete.
126
+ * @returns A promise resolving to the count of records that existed and were deleted.
127
+ */
128
+ deleteAll(ids: string[]): Promise<number>;
129
+ /**
130
+ * Subscribes to the complete list of records in this table.
131
+ * Immediately invokes the listener with the current records, and re-invokes it
132
+ * whenever any local or remote mutations occur on this table.
133
+ *
134
+ * @param listener - Callback receiving the latest array of records.
135
+ * @returns An unsubscribe function.
136
+ */
137
+ subscribeAll(listener: (items: T[]) => void): () => void;
138
+ /**
139
+ * Notifies registered subscribers of remote change events.
140
+ *
141
+ * @param events - The list of remote change events.
142
+ */
143
+ notifyRemoteChanges(events: TableChangeEvent<unknown>[]): void;
144
+ private createMutationItem;
145
+ }
146
+ //# sourceMappingURL=table.d.ts.map