@fatagnus/dink-sync 1.0.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 (186) hide show
  1. package/README.md +312 -0
  2. package/dist/client/attachment.d.ts +225 -0
  3. package/dist/client/attachment.d.ts.map +1 -0
  4. package/dist/client/attachment.js +402 -0
  5. package/dist/client/attachment.js.map +1 -0
  6. package/dist/client/binary-encoding.d.ts +45 -0
  7. package/dist/client/binary-encoding.d.ts.map +1 -0
  8. package/dist/client/binary-encoding.js +90 -0
  9. package/dist/client/binary-encoding.js.map +1 -0
  10. package/dist/client/collection.d.ts +10 -0
  11. package/dist/client/collection.d.ts.map +1 -0
  12. package/dist/client/collection.js +924 -0
  13. package/dist/client/collection.js.map +1 -0
  14. package/dist/client/compression.d.ts +56 -0
  15. package/dist/client/compression.d.ts.map +1 -0
  16. package/dist/client/compression.js +173 -0
  17. package/dist/client/compression.js.map +1 -0
  18. package/dist/client/crdt/index.d.ts +2 -0
  19. package/dist/client/crdt/index.d.ts.map +1 -0
  20. package/dist/client/crdt/index.js +2 -0
  21. package/dist/client/crdt/index.js.map +1 -0
  22. package/dist/client/crdt/yjs-doc.d.ts +88 -0
  23. package/dist/client/crdt/yjs-doc.d.ts.map +1 -0
  24. package/dist/client/crdt/yjs-doc.js +123 -0
  25. package/dist/client/crdt/yjs-doc.js.map +1 -0
  26. package/dist/client/index.d.ts +66 -0
  27. package/dist/client/index.d.ts.map +1 -0
  28. package/dist/client/index.js +233 -0
  29. package/dist/client/index.js.map +1 -0
  30. package/dist/client/mock-transport.d.ts +155 -0
  31. package/dist/client/mock-transport.d.ts.map +1 -0
  32. package/dist/client/mock-transport.js +292 -0
  33. package/dist/client/mock-transport.js.map +1 -0
  34. package/dist/client/network-detector.d.ts +65 -0
  35. package/dist/client/network-detector.d.ts.map +1 -0
  36. package/dist/client/network-detector.js +147 -0
  37. package/dist/client/network-detector.js.map +1 -0
  38. package/dist/client/provisioning.d.ts +126 -0
  39. package/dist/client/provisioning.d.ts.map +1 -0
  40. package/dist/client/provisioning.js +125 -0
  41. package/dist/client/provisioning.js.map +1 -0
  42. package/dist/client/signal.d.ts +13 -0
  43. package/dist/client/signal.d.ts.map +1 -0
  44. package/dist/client/signal.js +27 -0
  45. package/dist/client/signal.js.map +1 -0
  46. package/dist/client/sync-engine.d.ts +298 -0
  47. package/dist/client/sync-engine.d.ts.map +1 -0
  48. package/dist/client/sync-engine.js +904 -0
  49. package/dist/client/sync-engine.js.map +1 -0
  50. package/dist/client/synced-edge.d.ts +109 -0
  51. package/dist/client/synced-edge.d.ts.map +1 -0
  52. package/dist/client/synced-edge.js +179 -0
  53. package/dist/client/synced-edge.js.map +1 -0
  54. package/dist/client/synced-offline-edge-types.d.ts +540 -0
  55. package/dist/client/synced-offline-edge-types.d.ts.map +1 -0
  56. package/dist/client/synced-offline-edge-types.js +10 -0
  57. package/dist/client/synced-offline-edge-types.js.map +1 -0
  58. package/dist/client/synced-offline-edge.d.ts +54 -0
  59. package/dist/client/synced-offline-edge.d.ts.map +1 -0
  60. package/dist/client/synced-offline-edge.js +731 -0
  61. package/dist/client/synced-offline-edge.js.map +1 -0
  62. package/dist/client/transport.d.ts +202 -0
  63. package/dist/client/transport.d.ts.map +1 -0
  64. package/dist/client/transport.js +409 -0
  65. package/dist/client/transport.js.map +1 -0
  66. package/dist/client/types.d.ts +622 -0
  67. package/dist/client/types.d.ts.map +1 -0
  68. package/dist/client/types.js +60 -0
  69. package/dist/client/types.js.map +1 -0
  70. package/dist/client/validation.d.ts +61 -0
  71. package/dist/client/validation.d.ts.map +1 -0
  72. package/dist/client/validation.js +57 -0
  73. package/dist/client/validation.js.map +1 -0
  74. package/dist/client/versioning.d.ts +134 -0
  75. package/dist/client/versioning.d.ts.map +1 -0
  76. package/dist/client/versioning.js +304 -0
  77. package/dist/client/versioning.js.map +1 -0
  78. package/dist/index.d.ts +40 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +51 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/persistence/encryption.d.ts +114 -0
  83. package/dist/persistence/encryption.d.ts.map +1 -0
  84. package/dist/persistence/encryption.js +286 -0
  85. package/dist/persistence/encryption.js.map +1 -0
  86. package/dist/persistence/index.d.ts +21 -0
  87. package/dist/persistence/index.d.ts.map +1 -0
  88. package/dist/persistence/index.js +20 -0
  89. package/dist/persistence/index.js.map +1 -0
  90. package/dist/persistence/memory.d.ts +32 -0
  91. package/dist/persistence/memory.d.ts.map +1 -0
  92. package/dist/persistence/memory.js +57 -0
  93. package/dist/persistence/memory.js.map +1 -0
  94. package/dist/persistence/migrations.d.ts +106 -0
  95. package/dist/persistence/migrations.d.ts.map +1 -0
  96. package/dist/persistence/migrations.js +176 -0
  97. package/dist/persistence/migrations.js.map +1 -0
  98. package/dist/persistence/pending-queue.d.ts +109 -0
  99. package/dist/persistence/pending-queue.d.ts.map +1 -0
  100. package/dist/persistence/pending-queue.js +249 -0
  101. package/dist/persistence/pending-queue.js.map +1 -0
  102. package/dist/persistence/pglite.d.ts +72 -0
  103. package/dist/persistence/pglite.d.ts.map +1 -0
  104. package/dist/persistence/pglite.js +126 -0
  105. package/dist/persistence/pglite.js.map +1 -0
  106. package/dist/persistence/quota-manager.d.ts +134 -0
  107. package/dist/persistence/quota-manager.d.ts.map +1 -0
  108. package/dist/persistence/quota-manager.js +242 -0
  109. package/dist/persistence/quota-manager.js.map +1 -0
  110. package/dist/persistence/types.d.ts +54 -0
  111. package/dist/persistence/types.d.ts.map +1 -0
  112. package/dist/persistence/types.js +2 -0
  113. package/dist/persistence/types.js.map +1 -0
  114. package/dist/react/OfflineEdgeProvider.d.ts +91 -0
  115. package/dist/react/OfflineEdgeProvider.d.ts.map +1 -0
  116. package/dist/react/OfflineEdgeProvider.js +127 -0
  117. package/dist/react/OfflineEdgeProvider.js.map +1 -0
  118. package/dist/react/SyncedOfflineEdgeProvider.d.ts +105 -0
  119. package/dist/react/SyncedOfflineEdgeProvider.d.ts.map +1 -0
  120. package/dist/react/SyncedOfflineEdgeProvider.js +138 -0
  121. package/dist/react/SyncedOfflineEdgeProvider.js.map +1 -0
  122. package/dist/react/index.d.ts +50 -0
  123. package/dist/react/index.d.ts.map +1 -0
  124. package/dist/react/index.js +51 -0
  125. package/dist/react/index.js.map +1 -0
  126. package/dist/react/useCollection.d.ts +77 -0
  127. package/dist/react/useCollection.d.ts.map +1 -0
  128. package/dist/react/useCollection.js +113 -0
  129. package/dist/react/useCollection.js.map +1 -0
  130. package/dist/react/useCollectionSyncMode.d.ts +61 -0
  131. package/dist/react/useCollectionSyncMode.d.ts.map +1 -0
  132. package/dist/react/useCollectionSyncMode.js +93 -0
  133. package/dist/react/useCollectionSyncMode.js.map +1 -0
  134. package/dist/react/useConnectionState.d.ts +44 -0
  135. package/dist/react/useConnectionState.d.ts.map +1 -0
  136. package/dist/react/useConnectionState.js +46 -0
  137. package/dist/react/useConnectionState.js.map +1 -0
  138. package/dist/react/useDocumentSyncStatus.d.ts +72 -0
  139. package/dist/react/useDocumentSyncStatus.d.ts.map +1 -0
  140. package/dist/react/useDocumentSyncStatus.js +110 -0
  141. package/dist/react/useDocumentSyncStatus.js.map +1 -0
  142. package/dist/react/useOfflineEdge.d.ts +58 -0
  143. package/dist/react/useOfflineEdge.d.ts.map +1 -0
  144. package/dist/react/useOfflineEdge.js +54 -0
  145. package/dist/react/useOfflineEdge.js.map +1 -0
  146. package/dist/react/usePendingChanges.d.ts +67 -0
  147. package/dist/react/usePendingChanges.d.ts.map +1 -0
  148. package/dist/react/usePendingChanges.js +90 -0
  149. package/dist/react/usePendingChanges.js.map +1 -0
  150. package/dist/react/useRejectedDocuments.d.ts +112 -0
  151. package/dist/react/useRejectedDocuments.d.ts.map +1 -0
  152. package/dist/react/useRejectedDocuments.js +213 -0
  153. package/dist/react/useRejectedDocuments.js.map +1 -0
  154. package/dist/react/useSyncControls.d.ts +96 -0
  155. package/dist/react/useSyncControls.d.ts.map +1 -0
  156. package/dist/react/useSyncControls.js +112 -0
  157. package/dist/react/useSyncControls.js.map +1 -0
  158. package/dist/react/useSyncProgress.d.ts +78 -0
  159. package/dist/react/useSyncProgress.d.ts.map +1 -0
  160. package/dist/react/useSyncProgress.js +90 -0
  161. package/dist/react/useSyncProgress.js.map +1 -0
  162. package/dist/react/useSyncRejected.d.ts +47 -0
  163. package/dist/react/useSyncRejected.d.ts.map +1 -0
  164. package/dist/react/useSyncRejected.js +55 -0
  165. package/dist/react/useSyncRejected.js.map +1 -0
  166. package/dist/react/useSyncStatus.d.ts +56 -0
  167. package/dist/react/useSyncStatus.d.ts.map +1 -0
  168. package/dist/react/useSyncStatus.js +59 -0
  169. package/dist/react/useSyncStatus.js.map +1 -0
  170. package/dist/react/useSyncedOfflineEdge.d.ts +69 -0
  171. package/dist/react/useSyncedOfflineEdge.d.ts.map +1 -0
  172. package/dist/react/useSyncedOfflineEdge.js +65 -0
  173. package/dist/react/useSyncedOfflineEdge.js.map +1 -0
  174. package/dist/service-worker/index.d.ts +7 -0
  175. package/dist/service-worker/index.d.ts.map +1 -0
  176. package/dist/service-worker/index.js +7 -0
  177. package/dist/service-worker/index.js.map +1 -0
  178. package/dist/service-worker/sync-worker.d.ts +230 -0
  179. package/dist/service-worker/sync-worker.d.ts.map +1 -0
  180. package/dist/service-worker/sync-worker.js +471 -0
  181. package/dist/service-worker/sync-worker.js.map +1 -0
  182. package/dist/types.d.ts +6 -0
  183. package/dist/types.d.ts.map +1 -0
  184. package/dist/types.js +3 -0
  185. package/dist/types.js.map +1 -0
  186. package/package.json +95 -0
@@ -0,0 +1,471 @@
1
+ /**
2
+ * Service Worker Background Sync for Dink Offline-First SDK
3
+ *
4
+ * Provides:
5
+ * - Background Sync API registration for one-time sync when online
6
+ * - Periodic Background Sync for regular sync intervals
7
+ * - Fallback interval-based sync for browsers without Background Sync
8
+ * - Message passing between main thread and service worker
9
+ * - IndexedDB access for pending queue in service worker context
10
+ */
11
+ /**
12
+ * Message types for communication between main thread and service worker
13
+ */
14
+ export const SyncWorkerMessageType = {
15
+ /** Request sync from main thread */
16
+ SYNC_REQUEST: 'SYNC_REQUEST',
17
+ /** Sync completed successfully */
18
+ SYNC_COMPLETE: 'SYNC_COMPLETE',
19
+ /** Sync failed with error */
20
+ SYNC_ERROR: 'SYNC_ERROR',
21
+ /** Notify worker of pending changes count */
22
+ PENDING_CHANGES: 'PENDING_CHANGES',
23
+ /** Request to register a sync tag */
24
+ REGISTER_SYNC: 'REGISTER_SYNC',
25
+ };
26
+ /**
27
+ * BackgroundSyncManager - Main thread API for Background Sync
28
+ *
29
+ * Manages registration of background sync events and provides
30
+ * fallback for browsers without Background Sync support.
31
+ */
32
+ export class BackgroundSyncManager {
33
+ registration;
34
+ fallbackTimer = null;
35
+ fallbackHandler = null;
36
+ constructor(registration) {
37
+ this.registration = registration;
38
+ }
39
+ /**
40
+ * Check if Background Sync API is supported
41
+ */
42
+ isSupported() {
43
+ return 'sync' in this.registration;
44
+ }
45
+ /**
46
+ * Check if Periodic Background Sync API is supported
47
+ */
48
+ isPeriodicSyncSupported() {
49
+ return 'periodicSync' in this.registration;
50
+ }
51
+ /**
52
+ * Request a one-time background sync
53
+ * @param tag - Unique tag to identify this sync
54
+ * @returns true if registration succeeded, false otherwise
55
+ */
56
+ async requestSync(tag) {
57
+ if (!this.isSupported()) {
58
+ console.warn('Background Sync is not supported in this browser');
59
+ return false;
60
+ }
61
+ try {
62
+ await this.registration.sync.register(tag);
63
+ return true;
64
+ }
65
+ catch (error) {
66
+ console.error('Failed to register background sync:', error);
67
+ return false;
68
+ }
69
+ }
70
+ /**
71
+ * Request periodic background sync
72
+ * @param tag - Unique tag to identify this periodic sync
73
+ * @param minInterval - Minimum interval between syncs in milliseconds
74
+ * @returns true if registration succeeded, false otherwise
75
+ */
76
+ async requestPeriodicSync(tag, minInterval) {
77
+ if (!this.isPeriodicSyncSupported()) {
78
+ console.warn('Periodic Background Sync is not supported in this browser');
79
+ return false;
80
+ }
81
+ try {
82
+ const periodicSync = this.registration.periodicSync;
83
+ await periodicSync.register(tag, { minInterval });
84
+ return true;
85
+ }
86
+ catch (error) {
87
+ console.error('Failed to register periodic background sync:', error);
88
+ return false;
89
+ }
90
+ }
91
+ /**
92
+ * Unregister a periodic background sync
93
+ * @param tag - Tag of the periodic sync to unregister
94
+ */
95
+ async unregisterPeriodicSync(tag) {
96
+ if (!this.isPeriodicSyncSupported()) {
97
+ return;
98
+ }
99
+ try {
100
+ const periodicSync = this.registration.periodicSync;
101
+ await periodicSync.unregister(tag);
102
+ }
103
+ catch (error) {
104
+ console.error('Failed to unregister periodic background sync:', error);
105
+ }
106
+ }
107
+ /**
108
+ * Get all active sync tags
109
+ * @returns Array of active sync tags
110
+ */
111
+ async getActiveSyncTags() {
112
+ if (!this.isSupported()) {
113
+ return [];
114
+ }
115
+ try {
116
+ const sync = this.registration.sync;
117
+ return await sync.getTags();
118
+ }
119
+ catch (error) {
120
+ console.error('Failed to get sync tags:', error);
121
+ return [];
122
+ }
123
+ }
124
+ /**
125
+ * Set the fallback sync handler for browsers without Background Sync
126
+ * @param handler - Async function to call for sync
127
+ */
128
+ setFallbackSyncHandler(handler) {
129
+ this.fallbackHandler = handler;
130
+ }
131
+ /**
132
+ * Start fallback interval-based sync
133
+ * Only activates if Background Sync is not supported
134
+ * @param intervalMs - Sync interval in milliseconds
135
+ */
136
+ startFallbackSync(intervalMs) {
137
+ // Don't use fallback if native Background Sync is supported
138
+ if (this.isSupported()) {
139
+ return;
140
+ }
141
+ this.stopFallbackSync();
142
+ if (this.fallbackHandler) {
143
+ this.fallbackTimer = setInterval(async () => {
144
+ try {
145
+ await this.fallbackHandler?.();
146
+ }
147
+ catch (error) {
148
+ console.error('Fallback sync failed:', error);
149
+ }
150
+ }, intervalMs);
151
+ }
152
+ }
153
+ /**
154
+ * Stop fallback interval-based sync
155
+ */
156
+ stopFallbackSync() {
157
+ if (this.fallbackTimer) {
158
+ clearInterval(this.fallbackTimer);
159
+ this.fallbackTimer = null;
160
+ }
161
+ }
162
+ /**
163
+ * Post a message to the service worker
164
+ * @param message - Message to send
165
+ */
166
+ postMessage(message) {
167
+ if (this.registration.active) {
168
+ this.registration.active.postMessage(message);
169
+ }
170
+ }
171
+ }
172
+ /**
173
+ * SyncWorkerHandler - Service Worker side handler
174
+ *
175
+ * Handles sync events and messages in the service worker context.
176
+ */
177
+ export class SyncWorkerHandler {
178
+ syncHandler = null;
179
+ periodicSyncHandler = null;
180
+ tagPrefix = null;
181
+ errorCallbacks = new Set();
182
+ lastChanceCallbacks = new Set();
183
+ /**
184
+ * Set the tag prefix for filtering sync events
185
+ * @param prefix - Only handle sync events with tags starting with this prefix
186
+ */
187
+ setTagPrefix(prefix) {
188
+ this.tagPrefix = prefix;
189
+ }
190
+ /**
191
+ * Set the sync handler function
192
+ * @param handler - Async function to call when sync event fires
193
+ */
194
+ setSyncHandler(handler) {
195
+ this.syncHandler = handler;
196
+ }
197
+ /**
198
+ * Set the periodic sync handler function
199
+ * @param handler - Async function to call when periodic sync event fires
200
+ */
201
+ setPeriodicSyncHandler(handler) {
202
+ this.periodicSyncHandler = handler;
203
+ }
204
+ /**
205
+ * Handle a sync event from the Background Sync API
206
+ * @param event - Sync event
207
+ */
208
+ async handleSyncEvent(event) {
209
+ // Check tag prefix if set
210
+ if (this.tagPrefix && !event.tag.startsWith(this.tagPrefix)) {
211
+ return;
212
+ }
213
+ if (!this.syncHandler) {
214
+ return;
215
+ }
216
+ try {
217
+ await this.syncHandler(event.tag);
218
+ }
219
+ catch (error) {
220
+ const err = error instanceof Error ? error : new Error(String(error));
221
+ // Notify error callbacks
222
+ for (const callback of this.errorCallbacks) {
223
+ callback(err);
224
+ }
225
+ // If this is the last chance, notify those callbacks too
226
+ if (event.lastChance) {
227
+ for (const callback of this.lastChanceCallbacks) {
228
+ callback(event.tag);
229
+ }
230
+ }
231
+ }
232
+ }
233
+ /**
234
+ * Handle a periodic sync event
235
+ * @param event - Periodic sync event
236
+ */
237
+ async handlePeriodicSyncEvent(event) {
238
+ if (!this.periodicSyncHandler) {
239
+ return;
240
+ }
241
+ try {
242
+ await this.periodicSyncHandler(event.tag);
243
+ }
244
+ catch (error) {
245
+ const err = error instanceof Error ? error : new Error(String(error));
246
+ for (const callback of this.errorCallbacks) {
247
+ callback(err);
248
+ }
249
+ }
250
+ }
251
+ /**
252
+ * Handle a message from the main thread
253
+ * @param event - Message event
254
+ */
255
+ async handleMessage(event) {
256
+ const message = event.data;
257
+ switch (message.type) {
258
+ case SyncWorkerMessageType.REGISTER_SYNC:
259
+ // Registration is handled by the main thread, this is just for coordination
260
+ break;
261
+ case SyncWorkerMessageType.PENDING_CHANGES:
262
+ // Trigger sync when there are pending changes
263
+ if (this.syncHandler && message.payload.count && message.payload.count > 0) {
264
+ try {
265
+ await this.syncHandler('pending-changes');
266
+ }
267
+ catch (error) {
268
+ const err = error instanceof Error ? error : new Error(String(error));
269
+ for (const callback of this.errorCallbacks) {
270
+ callback(err);
271
+ }
272
+ }
273
+ }
274
+ break;
275
+ case SyncWorkerMessageType.SYNC_REQUEST:
276
+ if (this.syncHandler) {
277
+ try {
278
+ await this.syncHandler('manual-sync');
279
+ }
280
+ catch (error) {
281
+ const err = error instanceof Error ? error : new Error(String(error));
282
+ for (const callback of this.errorCallbacks) {
283
+ callback(err);
284
+ }
285
+ }
286
+ }
287
+ break;
288
+ }
289
+ }
290
+ /**
291
+ * Subscribe to error events
292
+ * @param callback - Function to call when an error occurs
293
+ * @returns Unsubscribe function
294
+ */
295
+ onError(callback) {
296
+ this.errorCallbacks.add(callback);
297
+ return () => {
298
+ this.errorCallbacks.delete(callback);
299
+ };
300
+ }
301
+ /**
302
+ * Subscribe to last chance events
303
+ * Called when a sync fails and it's the browser's last attempt
304
+ * @param callback - Function to call on last chance
305
+ * @returns Unsubscribe function
306
+ */
307
+ onLastChance(callback) {
308
+ this.lastChanceCallbacks.add(callback);
309
+ return () => {
310
+ this.lastChanceCallbacks.delete(callback);
311
+ };
312
+ }
313
+ }
314
+ /**
315
+ * Generate a service worker script string for background sync
316
+ *
317
+ * This generates a self-contained service worker script that can be
318
+ * registered to handle background sync events and access IndexedDB
319
+ * for the pending queue.
320
+ *
321
+ * @param config - Configuration for the script
322
+ * @returns Service worker script as a string
323
+ */
324
+ export function createSyncWorkerScript(config) {
325
+ const storeName = config.storeName ?? '__pending_changes__';
326
+ return `
327
+ // Dink Background Sync Service Worker
328
+ // Auto-generated - do not edit directly
329
+
330
+ const SYNC_TAG = '${config.syncTag}';
331
+ const PERIODIC_SYNC_TAG = '${config.periodicSyncTag ?? ''}';
332
+ const DB_NAME = '${config.dbName}';
333
+ const STORE_NAME = '${storeName}';
334
+
335
+ // Open IndexedDB for pending queue access
336
+ function openDB() {
337
+ return new Promise((resolve, reject) => {
338
+ const request = indexedDB.open(DB_NAME);
339
+ request.onerror = () => reject(request.error);
340
+ request.onsuccess = () => resolve(request.result);
341
+ });
342
+ }
343
+
344
+ // Get pending changes from IndexedDB
345
+ async function getPendingChanges() {
346
+ try {
347
+ const db = await openDB();
348
+ return new Promise((resolve, reject) => {
349
+ const tx = db.transaction(STORE_NAME, 'readonly');
350
+ const store = tx.objectStore(STORE_NAME);
351
+ const request = store.getAll();
352
+ request.onerror = () => reject(request.error);
353
+ request.onsuccess = () => resolve(request.result || []);
354
+ });
355
+ } catch (error) {
356
+ console.error('Failed to get pending changes:', error);
357
+ return [];
358
+ }
359
+ }
360
+
361
+ // Perform sync operation
362
+ async function performSync() {
363
+ const pendingChanges = await getPendingChanges();
364
+
365
+ if (pendingChanges.length === 0) {
366
+ return;
367
+ }
368
+
369
+ // Notify clients that sync is starting
370
+ const clients = await self.clients.matchAll();
371
+ clients.forEach(client => {
372
+ client.postMessage({
373
+ type: 'SYNC_STARTED',
374
+ payload: { count: pendingChanges.length }
375
+ });
376
+ });
377
+
378
+ // The actual sync is performed by the main thread
379
+ // Service worker just triggers and coordinates
380
+ clients.forEach(client => {
381
+ client.postMessage({
382
+ type: 'SYNC_REQUEST',
383
+ payload: { changes: pendingChanges.length }
384
+ });
385
+ });
386
+ }
387
+
388
+ // Handle one-time background sync
389
+ self.addEventListener('sync', (event) => {
390
+ if (event.tag === SYNC_TAG || event.tag.startsWith('dink-')) {
391
+ event.waitUntil(performSync());
392
+ }
393
+ });
394
+
395
+ // Handle periodic background sync
396
+ ${config.periodicSyncTag ? `
397
+ self.addEventListener('periodicsync', (event) => {
398
+ if (event.tag === PERIODIC_SYNC_TAG) {
399
+ event.waitUntil(performSync());
400
+ }
401
+ });
402
+ ` : ''}
403
+
404
+ // Handle messages from main thread
405
+ self.addEventListener('message', (event) => {
406
+ const { type, payload } = event.data || {};
407
+
408
+ switch (type) {
409
+ case 'SYNC_REQUEST':
410
+ performSync();
411
+ break;
412
+ case 'PENDING_CHANGES':
413
+ if (payload && payload.count > 0) {
414
+ // Register sync to ensure it happens
415
+ self.registration.sync.register(SYNC_TAG).catch(err => {
416
+ console.warn('Failed to register sync:', err);
417
+ });
418
+ }
419
+ break;
420
+ }
421
+ });
422
+
423
+ // Activate immediately
424
+ self.addEventListener('activate', (event) => {
425
+ event.waitUntil(self.clients.claim());
426
+ });
427
+
428
+ console.log('Dink Background Sync Service Worker initialized');
429
+ `;
430
+ }
431
+ /**
432
+ * Register the background sync service worker
433
+ *
434
+ * @param scriptUrl - URL of the service worker script
435
+ * @param options - Registration options
436
+ * @returns BackgroundSyncManager instance
437
+ */
438
+ export async function registerSyncWorker(scriptUrl, options) {
439
+ if (!('serviceWorker' in navigator)) {
440
+ throw new Error('Service Workers are not supported in this browser');
441
+ }
442
+ const registration = await navigator.serviceWorker.register(scriptUrl, options);
443
+ // Wait for the service worker to be ready
444
+ await navigator.serviceWorker.ready;
445
+ return new BackgroundSyncManager(registration);
446
+ }
447
+ /**
448
+ * Get the BackgroundSyncManager for an existing service worker
449
+ *
450
+ * @returns BackgroundSyncManager instance or null if no service worker
451
+ */
452
+ export async function getBackgroundSyncManager() {
453
+ if (!('serviceWorker' in navigator)) {
454
+ return null;
455
+ }
456
+ const registration = await navigator.serviceWorker.ready;
457
+ return new BackgroundSyncManager(registration);
458
+ }
459
+ /**
460
+ * Default sync tag for Dink background sync
461
+ */
462
+ export const DEFAULT_SYNC_TAG = 'dink-sync';
463
+ /**
464
+ * Default periodic sync tag for Dink background sync
465
+ */
466
+ export const DEFAULT_PERIODIC_SYNC_TAG = 'dink-periodic-sync';
467
+ /**
468
+ * Default minimum interval for periodic sync (1 hour)
469
+ */
470
+ export const DEFAULT_PERIODIC_SYNC_INTERVAL = 60 * 60 * 1000;
471
+ //# sourceMappingURL=sync-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-worker.js","sourceRoot":"","sources":["../../src/service-worker/sync-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface SyncConfig {
2
+ serverUrl: string;
3
+ apiKey: string;
4
+ }
5
+ export type ConnectionState = "disconnected" | "connecting" | "connected" | "reconnecting";
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ // Sync SDK types
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,iBAAiB"}
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@fatagnus/dink-sync",
3
+ "version": "1.0.0",
4
+ "description": "Offline-first sync SDK for Dink edge platform with Effect.ts",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./client": {
14
+ "types": "./dist/client/index.d.ts",
15
+ "import": "./dist/client/index.js"
16
+ },
17
+ "./persistence": {
18
+ "types": "./dist/persistence/index.d.ts",
19
+ "import": "./dist/persistence/index.js"
20
+ },
21
+ "./react": {
22
+ "types": "./dist/react/index.d.ts",
23
+ "import": "./dist/react/index.js"
24
+ }
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "clean": "rm -rf dist",
29
+ "prebuild": "npm run clean",
30
+ "prepublishOnly": "npm run build",
31
+ "test": "vitest run",
32
+ "test:watch": "vitest",
33
+ "test:e2e": "vitest run --config vitest.e2e.config.ts",
34
+ "test:browser": "vitest run --config vitest.browser.config.ts",
35
+ "lint": "eslint src --ext .ts",
36
+ "typecheck": "tsc --noEmit"
37
+ },
38
+ "keywords": [
39
+ "dink",
40
+ "sync",
41
+ "offline-first",
42
+ "crdt",
43
+ "effect",
44
+ "nats"
45
+ ],
46
+ "author": "Ozan Turksever",
47
+ "license": "Apache-2.0",
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/ozanturksever/dink.git",
51
+ "directory": "sdk/typescript-sync"
52
+ },
53
+ "publishConfig": {
54
+ "access": "public"
55
+ },
56
+ "sideEffects": false,
57
+ "dependencies": {
58
+ "@electric-sql/pglite": "^0.2.0",
59
+ "effect": "^3.19.0",
60
+ "nats": "^2.19.0",
61
+ "yjs": "^13.6.29"
62
+ },
63
+ "peerDependencies": {
64
+ "react": ">=17.0.0"
65
+ },
66
+ "peerDependenciesMeta": {
67
+ "react": {
68
+ "optional": true
69
+ }
70
+ },
71
+ "devDependencies": {
72
+ "@testing-library/react": "^16.3.1",
73
+ "@types/node": "^20.10.0",
74
+ "@types/react": "^18.3.27",
75
+ "@typescript-eslint/eslint-plugin": "^6.13.0",
76
+ "@typescript-eslint/parser": "^6.13.0",
77
+ "@vitest/browser": "^1.0.0",
78
+ "convex": "^1.31.3",
79
+ "eslint": "^8.55.0",
80
+ "jsdom": "^27.4.0",
81
+ "playwright": "^1.40.0",
82
+ "testcontainers": "^10.7.1",
83
+ "typescript": "^5.3.0",
84
+ "vitest": "^1.0.0",
85
+ "zod": "^4.3.5"
86
+ },
87
+ "engines": {
88
+ "node": ">=18.0.0"
89
+ },
90
+ "files": [
91
+ "dist",
92
+ "README.md",
93
+ "LICENSE"
94
+ ]
95
+ }