@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,57 @@
1
+ /**
2
+ * In-memory persistence provider.
3
+ *
4
+ * Stores documents and state vectors in memory using Maps.
5
+ * All data is lost when the instance is garbage collected.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const persistence = new MemoryPersistence();
10
+ * await persistence.save('tasks', 'task-1', encodedData);
11
+ * const data = await persistence.load('tasks', 'task-1');
12
+ * ```
13
+ */
14
+ export class MemoryPersistence {
15
+ documents = new Map();
16
+ stateVectors = new Map();
17
+ getOrCreateCollection(store, collection) {
18
+ let col = store.get(collection);
19
+ if (!col) {
20
+ col = new Map();
21
+ store.set(collection, col);
22
+ }
23
+ return col;
24
+ }
25
+ async save(collection, docId, data) {
26
+ const col = this.getOrCreateCollection(this.documents, collection);
27
+ col.set(docId, data);
28
+ }
29
+ async load(collection, docId) {
30
+ const col = this.documents.get(collection);
31
+ return col?.get(docId);
32
+ }
33
+ async list(collection) {
34
+ const col = this.documents.get(collection);
35
+ if (!col) {
36
+ return [];
37
+ }
38
+ return Array.from(col.keys());
39
+ }
40
+ async delete(collection, docId) {
41
+ const col = this.documents.get(collection);
42
+ col?.delete(docId);
43
+ }
44
+ async saveStateVector(collection, docId, vector) {
45
+ const col = this.getOrCreateCollection(this.stateVectors, collection);
46
+ col.set(docId, vector);
47
+ }
48
+ async loadStateVector(collection, docId) {
49
+ const col = this.stateVectors.get(collection);
50
+ return col?.get(docId);
51
+ }
52
+ async close() {
53
+ this.documents.clear();
54
+ this.stateVectors.clear();
55
+ }
56
+ }
57
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/persistence/memory.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,iBAAiB;IACpB,SAAS,GAAG,IAAI,GAAG,EAAmC,CAAC;IACvD,YAAY,GAAG,IAAI,GAAG,EAAmC,CAAC;IAE1D,qBAAqB,CAAC,KAA2C,EAAE,UAAkB;QAC3F,IAAI,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;YAChB,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB,EAAE,KAAa,EAAE,IAAgB;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB,EAAE,KAAa;QAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,OAAO,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,UAAkB,EAAE,KAAa;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,KAAa,EAAE,MAAkB;QACzE,MAAM,GAAG,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACtE,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAAkB,EAAE,KAAa;QACrD,MAAM,GAAG,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC9C,OAAO,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Schema migrations for persistence providers.
3
+ *
4
+ * Provides a migration system to upgrade persistence schemas without data loss.
5
+ * Supports both MemoryPersistence and PGlitePersistence providers.
6
+ */
7
+ import type { PersistenceProvider } from './types.js';
8
+ /**
9
+ * Migration definition interface.
10
+ */
11
+ export interface Migration {
12
+ /** Migration version number (must be positive integer) */
13
+ version: number;
14
+ /** Human-readable name for the migration */
15
+ name: string;
16
+ /** Function to apply the migration */
17
+ up: () => Promise<void>;
18
+ /** Optional function to rollback the migration */
19
+ down?: () => Promise<void>;
20
+ }
21
+ /**
22
+ * Record of an applied migration.
23
+ */
24
+ export interface MigrationRecord {
25
+ /** Migration version */
26
+ version: number;
27
+ /** Migration name */
28
+ name: string;
29
+ /** When the migration was applied */
30
+ appliedAt: Date;
31
+ }
32
+ /**
33
+ * Error thrown when a migration fails.
34
+ */
35
+ export declare class MigrationError extends Error {
36
+ /** The version of the failed migration */
37
+ readonly version: number;
38
+ /** The name of the failed migration */
39
+ readonly migrationName: string;
40
+ /** The original error that caused the failure */
41
+ readonly cause: Error;
42
+ constructor(version: number, name: string, cause: Error);
43
+ }
44
+ /**
45
+ * Interface for persistence providers that support migrations.
46
+ * Extends PersistenceProvider with migration metadata storage.
47
+ */
48
+ export interface MigratablePersistence extends PersistenceProvider {
49
+ }
50
+ /**
51
+ * Migration runner interface.
52
+ */
53
+ export interface MigrationRunner {
54
+ /**
55
+ * Get the current schema version.
56
+ * @returns Current version number (0 if no migrations have been applied)
57
+ */
58
+ getCurrentVersion(): Promise<number>;
59
+ /**
60
+ * Run all pending migrations.
61
+ * @param migrations - Array of migrations to potentially run
62
+ * @throws MigrationError if a migration fails
63
+ */
64
+ run(migrations: Migration[]): Promise<void>;
65
+ /**
66
+ * Get the history of applied migrations.
67
+ * @returns Array of migration records
68
+ */
69
+ getHistory(): Promise<MigrationRecord[]>;
70
+ /**
71
+ * Get pending migrations that haven't been applied yet.
72
+ * @param migrations - Array of available migrations
73
+ * @returns Array of migrations that need to be applied
74
+ */
75
+ getPending(migrations: Migration[]): Promise<Migration[]>;
76
+ }
77
+ /**
78
+ * Create a migration runner for a persistence provider.
79
+ *
80
+ * @param persistence - The persistence provider to manage migrations for
81
+ * @returns A MigrationRunner instance
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * import { MemoryPersistence } from './memory.js';
86
+ * import { createMigrationRunner, Migration } from './migrations.js';
87
+ *
88
+ * const persistence = new MemoryPersistence();
89
+ * const runner = createMigrationRunner(persistence);
90
+ *
91
+ * const migrations: Migration[] = [
92
+ * {
93
+ * version: 1,
94
+ * name: 'add_user_preferences',
95
+ * up: async () => {
96
+ * // Migration logic
97
+ * },
98
+ * },
99
+ * ];
100
+ *
101
+ * await runner.run(migrations);
102
+ * console.log('Current version:', await runner.getCurrentVersion());
103
+ * ```
104
+ */
105
+ export declare function createMigrationRunner(persistence: MigratablePersistence): MigrationRunner;
106
+ //# sourceMappingURL=migrations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/persistence/migrations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,qCAAqC;IACrC,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,0CAA0C;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;gBAEV,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;CAOxD;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;CAEjE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAErC;;;;OAIG;IACH,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5C;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAEzC;;;;OAIG;IACH,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;CAC3D;AA6ID;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,qBAAqB,GAAG,eAAe,CAEzF"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Schema migrations for persistence providers.
3
+ *
4
+ * Provides a migration system to upgrade persistence schemas without data loss.
5
+ * Supports both MemoryPersistence and PGlitePersistence providers.
6
+ */
7
+ /**
8
+ * Error thrown when a migration fails.
9
+ */
10
+ export class MigrationError extends Error {
11
+ /** The version of the failed migration */
12
+ version;
13
+ /** The name of the failed migration */
14
+ migrationName;
15
+ /** The original error that caused the failure */
16
+ cause;
17
+ constructor(version, name, cause) {
18
+ super(`Migration ${name} (v${version}) failed: ${cause.message}`);
19
+ this.name = 'MigrationError';
20
+ this.version = version;
21
+ this.migrationName = name;
22
+ this.cause = cause;
23
+ }
24
+ }
25
+ // Internal constants for metadata storage
26
+ const METADATA_COLLECTION = '_migrations_metadata';
27
+ const VERSION_DOC_ID = 'schema_version';
28
+ const HISTORY_DOC_ID = 'migration_history';
29
+ /**
30
+ * Encode a value to Uint8Array for persistence.
31
+ */
32
+ function encode(value) {
33
+ return new TextEncoder().encode(JSON.stringify(value));
34
+ }
35
+ /**
36
+ * Decode a Uint8Array to a value.
37
+ */
38
+ function decode(data) {
39
+ if (!data)
40
+ return undefined;
41
+ try {
42
+ return JSON.parse(new TextDecoder().decode(data));
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
48
+ /**
49
+ * Internal implementation of MigrationRunner.
50
+ */
51
+ class MigrationRunnerImpl {
52
+ persistence;
53
+ constructor(persistence) {
54
+ this.persistence = persistence;
55
+ }
56
+ async getCurrentVersion() {
57
+ const data = await this.persistence.load(METADATA_COLLECTION, VERSION_DOC_ID);
58
+ const version = decode(data);
59
+ return version?.version ?? 0;
60
+ }
61
+ async setCurrentVersion(version) {
62
+ await this.persistence.save(METADATA_COLLECTION, VERSION_DOC_ID, encode({ version }));
63
+ }
64
+ async getHistory() {
65
+ const data = await this.persistence.load(METADATA_COLLECTION, HISTORY_DOC_ID);
66
+ const history = decode(data);
67
+ if (!history?.records)
68
+ return [];
69
+ return history.records.map(record => ({
70
+ version: record.version,
71
+ name: record.name,
72
+ appliedAt: new Date(record.appliedAt),
73
+ }));
74
+ }
75
+ async addToHistory(version, name) {
76
+ const history = await this.getHistory();
77
+ history.push({
78
+ version,
79
+ name,
80
+ appliedAt: new Date(),
81
+ });
82
+ await this.persistence.save(METADATA_COLLECTION, HISTORY_DOC_ID, encode({
83
+ records: history.map(record => ({
84
+ version: record.version,
85
+ name: record.name,
86
+ appliedAt: record.appliedAt.toISOString(),
87
+ })),
88
+ }));
89
+ }
90
+ async getPending(migrations) {
91
+ const currentVersion = await this.getCurrentVersion();
92
+ // Sort by version and filter to pending
93
+ return [...migrations]
94
+ .sort((a, b) => a.version - b.version)
95
+ .filter(m => m.version > currentVersion);
96
+ }
97
+ async run(migrations) {
98
+ // Handle empty migrations array
99
+ if (migrations.length === 0) {
100
+ return;
101
+ }
102
+ // Validate migrations
103
+ this.validateMigrations(migrations);
104
+ // Get pending migrations
105
+ const pending = await this.getPending(migrations);
106
+ // Run each pending migration
107
+ for (const migration of pending) {
108
+ try {
109
+ await migration.up();
110
+ await this.setCurrentVersion(migration.version);
111
+ await this.addToHistory(migration.version, migration.name);
112
+ }
113
+ catch (err) {
114
+ // Attempt rollback if down function is available
115
+ if (migration.down) {
116
+ try {
117
+ await migration.down();
118
+ }
119
+ catch {
120
+ // Ignore rollback errors, throw original error
121
+ }
122
+ }
123
+ const error = err instanceof Error ? err : new Error(String(err));
124
+ throw new MigrationError(migration.version, migration.name, error);
125
+ }
126
+ }
127
+ }
128
+ validateMigrations(migrations) {
129
+ // Check for non-positive versions
130
+ for (const migration of migrations) {
131
+ if (migration.version <= 0) {
132
+ throw new Error(`Migration version must be a positive integer, got ${migration.version}`);
133
+ }
134
+ }
135
+ // Check for duplicate versions
136
+ const versions = new Set();
137
+ for (const migration of migrations) {
138
+ if (versions.has(migration.version)) {
139
+ throw new Error(`Duplicate migration version: ${migration.version}`);
140
+ }
141
+ versions.add(migration.version);
142
+ }
143
+ }
144
+ }
145
+ /**
146
+ * Create a migration runner for a persistence provider.
147
+ *
148
+ * @param persistence - The persistence provider to manage migrations for
149
+ * @returns A MigrationRunner instance
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * import { MemoryPersistence } from './memory.js';
154
+ * import { createMigrationRunner, Migration } from './migrations.js';
155
+ *
156
+ * const persistence = new MemoryPersistence();
157
+ * const runner = createMigrationRunner(persistence);
158
+ *
159
+ * const migrations: Migration[] = [
160
+ * {
161
+ * version: 1,
162
+ * name: 'add_user_preferences',
163
+ * up: async () => {
164
+ * // Migration logic
165
+ * },
166
+ * },
167
+ * ];
168
+ *
169
+ * await runner.run(migrations);
170
+ * console.log('Current version:', await runner.getCurrentVersion());
171
+ * ```
172
+ */
173
+ export function createMigrationRunner(persistence) {
174
+ return new MigrationRunnerImpl(persistence);
175
+ }
176
+ //# sourceMappingURL=migrations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/persistence/migrations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * PendingQueue - Persistent queue for pending sync changes.
3
+ *
4
+ * Ensures pending changes survive crashes/refreshes by persisting them
5
+ * to the underlying storage provider before adding to in-memory state.
6
+ */
7
+ import type { PersistenceProvider } from './types.js';
8
+ import { SyncPriority } from '../client/types.js';
9
+ import type { SyncPriority as SyncPriorityType } from '../client/types.js';
10
+ export { SyncPriority };
11
+ /**
12
+ * A pending change waiting to be synced.
13
+ */
14
+ export interface PendingChange {
15
+ /** Unique identifier for this change */
16
+ id: string;
17
+ /** Collection name */
18
+ collection: string;
19
+ /** Document ID */
20
+ docId: string;
21
+ /** Binary CRDT delta data */
22
+ delta: Uint8Array;
23
+ /** Timestamp when change was created */
24
+ timestamp: number;
25
+ /** Number of retry attempts (optional) */
26
+ retryCount?: number;
27
+ /** Sync priority (default: normal) */
28
+ priority?: SyncPriorityType;
29
+ }
30
+ /**
31
+ * Unsubscribe function type
32
+ */
33
+ export type Unsubscribe = () => void;
34
+ /**
35
+ * Persistent queue for pending sync changes.
36
+ *
37
+ * Changes are persisted to storage immediately when enqueued,
38
+ * ensuring they survive app crashes or page refreshes.
39
+ */
40
+ export declare class PendingQueue {
41
+ private persistence;
42
+ private changes;
43
+ private initialized;
44
+ private enqueueCallbacks;
45
+ private acknowledgeCallbacks;
46
+ constructor(persistence: PersistenceProvider);
47
+ /**
48
+ * Initialize the queue by loading pending changes from persistence.
49
+ */
50
+ init(): Promise<void>;
51
+ /**
52
+ * Add a change to the queue.
53
+ * The change is persisted to storage before being added to in-memory state.
54
+ */
55
+ enqueue(change: PendingChange): Promise<void>;
56
+ /**
57
+ * Acknowledge a change as synced, removing it from the queue.
58
+ */
59
+ acknowledge(id: string): Promise<void>;
60
+ /**
61
+ * List all pending changes for a specific document.
62
+ */
63
+ list(collection: string, docId: string): Promise<PendingChange[]>;
64
+ /**
65
+ * List all pending changes.
66
+ */
67
+ listAll(): Promise<PendingChange[]>;
68
+ /**
69
+ * List pending changes for a specific collection.
70
+ */
71
+ listByCollection(collection: string): Promise<PendingChange[]>;
72
+ /**
73
+ * Get total count of pending changes.
74
+ */
75
+ count(): Promise<number>;
76
+ /**
77
+ * Get count of pending changes for a specific collection.
78
+ */
79
+ countByCollection(collection: string): Promise<number>;
80
+ /**
81
+ * Clear all pending changes for a specific document.
82
+ */
83
+ clearDocument(collection: string, docId: string): Promise<void>;
84
+ /**
85
+ * Subscribe to enqueue events.
86
+ */
87
+ onEnqueue(callback: (change: PendingChange) => void): Unsubscribe;
88
+ /**
89
+ * Subscribe to acknowledge events.
90
+ */
91
+ onAcknowledge(callback: (id: string) => void): Unsubscribe;
92
+ /**
93
+ * Check if a specific change is pending.
94
+ */
95
+ has(id: string): boolean;
96
+ /**
97
+ * Get a specific pending change by ID.
98
+ */
99
+ get(id: string): PendingChange | undefined;
100
+ /**
101
+ * List all pending changes sorted by priority (high first) then timestamp.
102
+ */
103
+ listAllByPriority(): Promise<PendingChange[]>;
104
+ /**
105
+ * Update the priority of a pending change.
106
+ */
107
+ updatePriority(id: string, priority: SyncPriorityType): Promise<void>;
108
+ }
109
+ //# sourceMappingURL=pending-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-queue.d.ts","sourceRoot":"","sources":["../../src/persistence/pending-queue.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3E,OAAO,EAAE,YAAY,EAAE,CAAC;AAWxB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B;AAoDD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,oBAAoB,CAAmC;gBAEnD,WAAW,EAAE,mBAAmB;IAI5C;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB3B;;;OAGG;IACG,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBnD;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa5C;;OAEG;IACG,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAWvE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAKzC;;OAEG;IACG,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAUpE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAI9B;;OAEG;IACG,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU5D;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcrE;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,GAAG,WAAW;IAOjE;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW;IAO1D;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI1C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAgBnD;;OAEG;IACG,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;CAkB5E"}