@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,242 @@
1
+ /**
2
+ * Eviction policy for when storage quota is exceeded.
3
+ */
4
+ export const EvictionPolicy = {
5
+ /** Evict least recently used documents first */
6
+ LRU: 'lru',
7
+ /** Evict oldest documents first (by creation time) */
8
+ Oldest: 'oldest',
9
+ /** Evict lowest priority documents first */
10
+ Priority: 'priority',
11
+ };
12
+ /** Default quota: 50MB */
13
+ const DEFAULT_QUOTA_BYTES = 50 * 1024 * 1024;
14
+ /** Default warning threshold: 80% */
15
+ const DEFAULT_WARNING_THRESHOLD = 0.8;
16
+ /** Priority order for eviction (lower = evict first) */
17
+ const PRIORITY_EVICTION_ORDER = {
18
+ low: 0,
19
+ normal: 1,
20
+ high: 2,
21
+ };
22
+ /**
23
+ * Manages storage quota and eviction for persistence providers.
24
+ */
25
+ export class QuotaManager {
26
+ persistence;
27
+ quotaBytes;
28
+ warningThreshold;
29
+ evictionPolicy;
30
+ autoEvict;
31
+ // Event callbacks
32
+ warningCallbacks = new Set();
33
+ fullCallbacks = new Set();
34
+ // Document metadata for eviction tracking
35
+ documentMetadata = new Map();
36
+ // Track if warning has been emitted to avoid duplicates
37
+ warningEmitted = false;
38
+ constructor(persistence, config = {}) {
39
+ this.persistence = persistence;
40
+ this.quotaBytes = config.quotaBytes ?? DEFAULT_QUOTA_BYTES;
41
+ this.warningThreshold = config.warningThreshold ?? DEFAULT_WARNING_THRESHOLD;
42
+ this.evictionPolicy = config.evictionPolicy ?? EvictionPolicy.Oldest;
43
+ this.autoEvict = config.autoEvict ?? false;
44
+ }
45
+ /**
46
+ * Get the current storage usage in bytes.
47
+ */
48
+ async getStorageUsage() {
49
+ let totalBytes = 0;
50
+ // Iterate through all tracked documents
51
+ for (const metadata of this.documentMetadata.values()) {
52
+ totalBytes += metadata.size;
53
+ }
54
+ return totalBytes;
55
+ }
56
+ /**
57
+ * Get the configured storage quota in bytes.
58
+ */
59
+ getStorageQuota() {
60
+ return this.quotaBytes;
61
+ }
62
+ /**
63
+ * Get current usage as a percentage (0-100).
64
+ */
65
+ async getUsagePercent() {
66
+ const usage = await this.getStorageUsage();
67
+ return (usage / this.quotaBytes) * 100;
68
+ }
69
+ /**
70
+ * Check quota and emit events / perform eviction as needed.
71
+ */
72
+ async checkQuota() {
73
+ const usage = await this.getStorageUsage();
74
+ const usagePercent = (usage / this.quotaBytes) * 100;
75
+ // Check warning threshold
76
+ if (usagePercent >= this.warningThreshold * 100) {
77
+ if (!this.warningEmitted) {
78
+ this.emitWarning({
79
+ usageBytes: usage,
80
+ quotaBytes: this.quotaBytes,
81
+ usagePercent,
82
+ });
83
+ this.warningEmitted = true;
84
+ }
85
+ }
86
+ else {
87
+ // Reset warning flag when below threshold
88
+ this.warningEmitted = false;
89
+ }
90
+ // Check if quota exceeded
91
+ if (usage > this.quotaBytes) {
92
+ const overageBytes = usage - this.quotaBytes;
93
+ this.emitFull({
94
+ usageBytes: usage,
95
+ quotaBytes: this.quotaBytes,
96
+ overageBytes,
97
+ });
98
+ // Auto-evict if enabled
99
+ if (this.autoEvict) {
100
+ await this.evict(overageBytes);
101
+ }
102
+ }
103
+ }
104
+ /**
105
+ * Track document creation for eviction purposes.
106
+ */
107
+ async trackCreation(collection, docId) {
108
+ const key = this.metadataKey(collection, docId);
109
+ const data = await this.persistence.load(collection, docId);
110
+ const size = data?.length ?? 0;
111
+ const now = Date.now();
112
+ this.documentMetadata.set(key, {
113
+ collection,
114
+ docId,
115
+ size,
116
+ createdAt: now,
117
+ lastAccessedAt: now,
118
+ priority: 'normal',
119
+ });
120
+ }
121
+ /**
122
+ * Track document access for LRU eviction.
123
+ */
124
+ async trackAccess(collection, docId) {
125
+ const key = this.metadataKey(collection, docId);
126
+ const existing = this.documentMetadata.get(key);
127
+ if (existing) {
128
+ existing.lastAccessedAt = Date.now();
129
+ }
130
+ else {
131
+ // If not tracked, start tracking
132
+ await this.trackCreation(collection, docId);
133
+ }
134
+ }
135
+ /**
136
+ * Track document priority for priority-based eviction.
137
+ */
138
+ async trackPriority(collection, docId, priority) {
139
+ const key = this.metadataKey(collection, docId);
140
+ const existing = this.documentMetadata.get(key);
141
+ if (existing) {
142
+ existing.priority = priority;
143
+ }
144
+ else {
145
+ // If not tracked, start tracking
146
+ await this.trackCreation(collection, docId);
147
+ const metadata = this.documentMetadata.get(key);
148
+ if (metadata) {
149
+ metadata.priority = priority;
150
+ }
151
+ }
152
+ }
153
+ /**
154
+ * Evict documents to free at least the specified bytes.
155
+ * @param bytesToFree - Minimum bytes to free
156
+ * @returns Number of documents evicted
157
+ */
158
+ async evict(bytesToFree) {
159
+ const candidates = this.getEvictionCandidates();
160
+ let freedBytes = 0;
161
+ let evictedCount = 0;
162
+ for (const metadata of candidates) {
163
+ if (freedBytes >= bytesToFree) {
164
+ break;
165
+ }
166
+ // Delete the document
167
+ await this.persistence.delete(metadata.collection, metadata.docId);
168
+ // Remove from tracking
169
+ const key = this.metadataKey(metadata.collection, metadata.docId);
170
+ this.documentMetadata.delete(key);
171
+ freedBytes += metadata.size;
172
+ evictedCount++;
173
+ }
174
+ return evictedCount;
175
+ }
176
+ /**
177
+ * Subscribe to storage warning events.
178
+ */
179
+ onStorageWarning(callback) {
180
+ this.warningCallbacks.add(callback);
181
+ return () => {
182
+ this.warningCallbacks.delete(callback);
183
+ };
184
+ }
185
+ /**
186
+ * Subscribe to storage full events.
187
+ */
188
+ onStorageFull(callback) {
189
+ this.fullCallbacks.add(callback);
190
+ return () => {
191
+ this.fullCallbacks.delete(callback);
192
+ };
193
+ }
194
+ /**
195
+ * Get eviction candidates sorted by the configured policy.
196
+ */
197
+ getEvictionCandidates() {
198
+ const candidates = Array.from(this.documentMetadata.values());
199
+ switch (this.evictionPolicy) {
200
+ case EvictionPolicy.LRU:
201
+ // Sort by last access time (oldest first)
202
+ return candidates.sort((a, b) => a.lastAccessedAt - b.lastAccessedAt);
203
+ case EvictionPolicy.Oldest:
204
+ // Sort by creation time (oldest first)
205
+ return candidates.sort((a, b) => a.createdAt - b.createdAt);
206
+ case EvictionPolicy.Priority:
207
+ // Sort by priority (lowest first), then by creation time
208
+ return candidates.sort((a, b) => {
209
+ const priorityDiff = PRIORITY_EVICTION_ORDER[a.priority] - PRIORITY_EVICTION_ORDER[b.priority];
210
+ if (priorityDiff !== 0) {
211
+ return priorityDiff;
212
+ }
213
+ return a.createdAt - b.createdAt;
214
+ });
215
+ default:
216
+ return candidates;
217
+ }
218
+ }
219
+ /**
220
+ * Create a unique key for document metadata.
221
+ */
222
+ metadataKey(collection, docId) {
223
+ return `${collection}:${docId}`;
224
+ }
225
+ /**
226
+ * Emit storage warning event.
227
+ */
228
+ emitWarning(event) {
229
+ for (const callback of this.warningCallbacks) {
230
+ callback(event);
231
+ }
232
+ }
233
+ /**
234
+ * Emit storage full event.
235
+ */
236
+ emitFull(event) {
237
+ for (const callback of this.fullCallbacks) {
238
+ callback(event);
239
+ }
240
+ }
241
+ }
242
+ //# sourceMappingURL=quota-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quota-manager.js","sourceRoot":"","sources":["../../src/persistence/quota-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Persistence provider interface for offline-first sync.
3
+ *
4
+ * Implementations handle storage of documents and state vectors
5
+ * for CRDT synchronization.
6
+ */
7
+ export interface PersistenceProvider {
8
+ /**
9
+ * Save a document's data to storage.
10
+ * @param collection - Collection name
11
+ * @param docId - Document ID
12
+ * @param data - Binary data to store
13
+ */
14
+ save(collection: string, docId: string, data: Uint8Array): Promise<void>;
15
+ /**
16
+ * Load a document's data from storage.
17
+ * @param collection - Collection name
18
+ * @param docId - Document ID
19
+ * @returns The stored data, or undefined if not found
20
+ */
21
+ load(collection: string, docId: string): Promise<Uint8Array | undefined>;
22
+ /**
23
+ * List all document IDs in a collection.
24
+ * @param collection - Collection name
25
+ * @returns Array of document IDs
26
+ */
27
+ list(collection: string): Promise<string[]>;
28
+ /**
29
+ * Delete a document from storage.
30
+ * @param collection - Collection name
31
+ * @param docId - Document ID
32
+ */
33
+ delete(collection: string, docId: string): Promise<void>;
34
+ /**
35
+ * Save a state vector for a document.
36
+ * State vectors track sync progress for CRDT convergence.
37
+ * @param collection - Collection name
38
+ * @param docId - Document ID
39
+ * @param vector - Binary state vector data
40
+ */
41
+ saveStateVector(collection: string, docId: string, vector: Uint8Array): Promise<void>;
42
+ /**
43
+ * Load a state vector for a document.
44
+ * @param collection - Collection name
45
+ * @param docId - Document ID
46
+ * @returns The stored state vector, or undefined if not found
47
+ */
48
+ loadStateVector(collection: string, docId: string): Promise<Uint8Array | undefined>;
49
+ /**
50
+ * Close the persistence provider and release resources.
51
+ */
52
+ close?(): Promise<void>;
53
+ }
54
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzE;;;;;OAKG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAEzE;;;;OAIG;IACH,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5C;;;;OAIG;IACH,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;;;;OAMG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtF;;;;;OAKG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;IAEpF;;OAEG;IACH,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/persistence/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * OfflineEdgeProvider - React context provider for the offline edge client.
3
+ *
4
+ * Provides the OfflineEdgeClient to the component tree and handles
5
+ * initialization lifecycle including loading and error states.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { OfflineEdgeProvider, useOfflineEdgeClient } from '@fatagnus/dink-sync/react';
10
+ * import { MemoryPersistence } from '@fatagnus/dink-sync/persistence';
11
+ *
12
+ * function App() {
13
+ * return (
14
+ * <OfflineEdgeProvider
15
+ * config={{ serverUrl: 'nats://localhost:4222', apiKey: 'your-api-key' }}
16
+ * persistence={new MemoryPersistence()}
17
+ * >
18
+ * <TaskList />
19
+ * </OfflineEdgeProvider>
20
+ * );
21
+ * }
22
+ *
23
+ * function TaskList() {
24
+ * const client = useOfflineEdgeClient();
25
+ * const tasks = client.collection<Task>('tasks');
26
+ * // ...
27
+ * }
28
+ * ```
29
+ */
30
+ import { type ReactNode } from 'react';
31
+ import type { OfflineEdgeClient, OfflineEdgeConfig } from '../client/types.js';
32
+ import type { PersistenceProvider } from '../persistence/types.js';
33
+ /**
34
+ * Props for the OfflineEdgeProvider component.
35
+ */
36
+ export interface OfflineEdgeProviderProps {
37
+ /** Configuration for the offline edge client */
38
+ config: OfflineEdgeConfig;
39
+ /** Persistence provider for offline storage */
40
+ persistence: PersistenceProvider;
41
+ /** Children to render */
42
+ children: ReactNode;
43
+ /** Optional callback for initialization errors */
44
+ onError?: (error: Error) => void;
45
+ }
46
+ /**
47
+ * Internal context state.
48
+ */
49
+ interface OfflineEdgeContextState {
50
+ /** The initialized client, or null if not yet ready */
51
+ client: OfflineEdgeClient | null;
52
+ /** True while initializing */
53
+ isLoading: boolean;
54
+ /** True when client is ready to use */
55
+ isReady: boolean;
56
+ /** Error if initialization failed */
57
+ error: Error | null;
58
+ }
59
+ /**
60
+ * Internal context for the offline edge provider.
61
+ * Exported for use by useOfflineEdge hook.
62
+ */
63
+ export declare const OfflineEdgeContext: import("react").Context<OfflineEdgeContextState | null>;
64
+ /**
65
+ * OfflineEdgeProvider component.
66
+ *
67
+ * Wraps your app to provide the OfflineEdgeClient to all child components.
68
+ * Handles initialization on mount and cleanup on unmount.
69
+ */
70
+ export declare function OfflineEdgeProvider({ config, persistence, children, onError, }: OfflineEdgeProviderProps): ReactNode;
71
+ /**
72
+ * Hook to access the offline edge client directly.
73
+ *
74
+ * Throws if the client is not yet initialized. Use useOfflineEdge()
75
+ * if you need to handle loading states.
76
+ *
77
+ * @throws Error if used outside of OfflineEdgeProvider
78
+ * @throws Error if client is not yet initialized
79
+ *
80
+ * @example
81
+ * ```tsx
82
+ * function TaskList() {
83
+ * const client = useOfflineEdgeClient();
84
+ * const tasks = client.collection<Task>('tasks');
85
+ * // ...
86
+ * }
87
+ * ```
88
+ */
89
+ export declare function useOfflineEdgeClient(): OfflineEdgeClient;
90
+ export {};
91
+ //# sourceMappingURL=OfflineEdgeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OfflineEdgeProvider.d.ts","sourceRoot":"","sources":["../../src/react/OfflineEdgeProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAElB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,gDAAgD;IAChD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,+CAA+C;IAC/C,WAAW,EAAE,mBAAmB,CAAC;IACjC,yBAAyB;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,kDAAkD;IAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAED;;GAEG;AACH,UAAU,uBAAuB;IAC/B,uDAAuD;IACvD,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjC,8BAA8B;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,yDAAsD,CAAC;AAEtF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,WAAW,EACX,QAAQ,EACR,OAAO,GACR,EAAE,wBAAwB,GAAG,SAAS,CAmEtC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CAYxD"}
@@ -0,0 +1,127 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * OfflineEdgeProvider - React context provider for the offline edge client.
4
+ *
5
+ * Provides the OfflineEdgeClient to the component tree and handles
6
+ * initialization lifecycle including loading and error states.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { OfflineEdgeProvider, useOfflineEdgeClient } from '@fatagnus/dink-sync/react';
11
+ * import { MemoryPersistence } from '@fatagnus/dink-sync/persistence';
12
+ *
13
+ * function App() {
14
+ * return (
15
+ * <OfflineEdgeProvider
16
+ * config={{ serverUrl: 'nats://localhost:4222', apiKey: 'your-api-key' }}
17
+ * persistence={new MemoryPersistence()}
18
+ * >
19
+ * <TaskList />
20
+ * </OfflineEdgeProvider>
21
+ * );
22
+ * }
23
+ *
24
+ * function TaskList() {
25
+ * const client = useOfflineEdgeClient();
26
+ * const tasks = client.collection<Task>('tasks');
27
+ * // ...
28
+ * }
29
+ * ```
30
+ */
31
+ import { createContext, useContext, useState, useEffect, useRef, } from 'react';
32
+ import { offlineEdge } from '../client/index.js';
33
+ /**
34
+ * Internal context for the offline edge provider.
35
+ * Exported for use by useOfflineEdge hook.
36
+ */
37
+ export const OfflineEdgeContext = createContext(null);
38
+ /**
39
+ * OfflineEdgeProvider component.
40
+ *
41
+ * Wraps your app to provide the OfflineEdgeClient to all child components.
42
+ * Handles initialization on mount and cleanup on unmount.
43
+ */
44
+ export function OfflineEdgeProvider({ config, persistence, children, onError, }) {
45
+ const [state, setState] = useState({
46
+ client: null,
47
+ isLoading: true,
48
+ isReady: false,
49
+ error: null,
50
+ });
51
+ // Track the edge instance for cleanup
52
+ const edgeRef = useRef(null);
53
+ const mountedRef = useRef(true);
54
+ useEffect(() => {
55
+ mountedRef.current = true;
56
+ const initializeClient = async () => {
57
+ try {
58
+ // Create the edge instance
59
+ const edge = offlineEdge.create({
60
+ persistence,
61
+ config,
62
+ });
63
+ edgeRef.current = edge;
64
+ // Initialize (loads persisted data)
65
+ await edge.init();
66
+ // Get the client
67
+ const client = edge.get();
68
+ if (mountedRef.current) {
69
+ setState({
70
+ client,
71
+ isLoading: false,
72
+ isReady: true,
73
+ error: null,
74
+ });
75
+ }
76
+ }
77
+ catch (err) {
78
+ const error = err instanceof Error ? err : new Error(String(err));
79
+ if (mountedRef.current) {
80
+ setState({
81
+ client: null,
82
+ isLoading: false,
83
+ isReady: false,
84
+ error,
85
+ });
86
+ onError?.(error);
87
+ }
88
+ }
89
+ };
90
+ initializeClient();
91
+ // Cleanup on unmount
92
+ return () => {
93
+ mountedRef.current = false;
94
+ edgeRef.current = null;
95
+ };
96
+ }, [config, persistence, onError]);
97
+ return (_jsx(OfflineEdgeContext.Provider, { value: state, children: children }));
98
+ }
99
+ /**
100
+ * Hook to access the offline edge client directly.
101
+ *
102
+ * Throws if the client is not yet initialized. Use useOfflineEdge()
103
+ * if you need to handle loading states.
104
+ *
105
+ * @throws Error if used outside of OfflineEdgeProvider
106
+ * @throws Error if client is not yet initialized
107
+ *
108
+ * @example
109
+ * ```tsx
110
+ * function TaskList() {
111
+ * const client = useOfflineEdgeClient();
112
+ * const tasks = client.collection<Task>('tasks');
113
+ * // ...
114
+ * }
115
+ * ```
116
+ */
117
+ export function useOfflineEdgeClient() {
118
+ const context = useContext(OfflineEdgeContext);
119
+ if (context === null) {
120
+ throw new Error('useOfflineEdgeClient must be used within an OfflineEdgeProvider');
121
+ }
122
+ if (!context.isReady || !context.client) {
123
+ throw new Error('OfflineEdgeClient is not yet initialized. Use useOfflineEdge() to handle loading states.');
124
+ }
125
+ return context.client;
126
+ }
127
+ //# sourceMappingURL=OfflineEdgeProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OfflineEdgeProvider.js","sourceRoot":"","sources":["../../src/react/OfflineEdgeProvider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * SyncedOfflineEdgeProvider - React context provider for SyncedOfflineEdge.
3
+ *
4
+ * Provides the SyncedOfflineEdge instance to the component tree and handles
5
+ * initialization lifecycle including loading and error states.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { SyncedOfflineEdgeProvider, useSyncedOfflineEdgeClient } from '@fatagnus/dink-sync/react';
10
+ * import { MemoryPersistence } from '@fatagnus/dink-sync/persistence';
11
+ *
12
+ * function App() {
13
+ * return (
14
+ * <SyncedOfflineEdgeProvider
15
+ * config={{ serverUrl: 'nats://localhost:4222', apiKey: 'your-api-key' }}
16
+ * persistence={new MemoryPersistence()}
17
+ * syncConfig={{ tasks: 'auto', drafts: 'manual' }}
18
+ * >
19
+ * <TaskList />
20
+ * </SyncedOfflineEdgeProvider>
21
+ * );
22
+ * }
23
+ *
24
+ * function TaskList() {
25
+ * const { edge, isReady } = useSyncedOfflineEdgeClient();
26
+ * if (!isReady) return <Loading />;
27
+ *
28
+ * const tasks = edge.collection<Task>('tasks');
29
+ * // ...
30
+ * }
31
+ * ```
32
+ */
33
+ import { type ReactNode } from 'react';
34
+ import type { SyncedOfflineEdge, SyncConfigMap, SyncLifecycleHooks } from '../client/synced-offline-edge-types.js';
35
+ import type { OfflineEdgeConfig } from '../client/types.js';
36
+ import type { PersistenceProvider } from '../persistence/types.js';
37
+ import type { Transport } from '../client/transport.js';
38
+ /**
39
+ * Props for the SyncedOfflineEdgeProvider component.
40
+ */
41
+ export interface SyncedOfflineEdgeProviderProps {
42
+ /** Configuration for the offline edge client */
43
+ config: OfflineEdgeConfig;
44
+ /** Persistence provider for offline storage */
45
+ persistence: PersistenceProvider;
46
+ /** Optional per-collection sync mode configuration */
47
+ syncConfig?: SyncConfigMap;
48
+ /** Optional lifecycle hooks for customizing sync behavior */
49
+ hooks?: SyncLifecycleHooks;
50
+ /** Children to render */
51
+ children: ReactNode;
52
+ /** Optional callback for initialization errors */
53
+ onError?: (error: Error) => void;
54
+ /** Optional custom transport for testing */
55
+ transport?: Transport;
56
+ }
57
+ /**
58
+ * Internal context state.
59
+ */
60
+ interface SyncedOfflineEdgeContextState {
61
+ /** The initialized SyncedOfflineEdge, or null if not yet ready */
62
+ edge: SyncedOfflineEdge | null;
63
+ /** True while initializing */
64
+ isLoading: boolean;
65
+ /** True when edge is ready to use */
66
+ isReady: boolean;
67
+ /** Error if initialization failed */
68
+ error: Error | null;
69
+ }
70
+ /**
71
+ * Internal context for the SyncedOfflineEdge provider.
72
+ * Exported for use by custom hooks.
73
+ */
74
+ export declare const SyncedOfflineEdgeContext: import("react").Context<SyncedOfflineEdgeContextState | null>;
75
+ /**
76
+ * SyncedOfflineEdgeProvider component.
77
+ *
78
+ * Wraps your app to provide the SyncedOfflineEdge to all child components.
79
+ * Handles initialization on mount and cleanup on unmount.
80
+ */
81
+ export declare function SyncedOfflineEdgeProvider({ config, persistence, syncConfig, hooks, children, onError, transport, }: SyncedOfflineEdgeProviderProps): ReactNode;
82
+ /**
83
+ * Hook to access the SyncedOfflineEdge context.
84
+ *
85
+ * Returns the full context state including loading state, error, and the edge instance.
86
+ *
87
+ * @throws Error if used outside of SyncedOfflineEdgeProvider
88
+ *
89
+ * @example
90
+ * ```tsx
91
+ * function TaskList() {
92
+ * const { edge, isLoading, isReady, error } = useSyncedOfflineEdgeClient();
93
+ *
94
+ * if (isLoading) return <Loading />;
95
+ * if (error) return <Error error={error} />;
96
+ * if (!isReady) return null;
97
+ *
98
+ * const tasks = edge.collection<Task>('tasks');
99
+ * // ...
100
+ * }
101
+ * ```
102
+ */
103
+ export declare function useSyncedOfflineEdgeClient(): SyncedOfflineEdgeContextState;
104
+ export {};
105
+ //# sourceMappingURL=SyncedOfflineEdgeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SyncedOfflineEdgeProvider.d.ts","sourceRoot":"","sources":["../../src/react/SyncedOfflineEdgeProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EACnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,gDAAgD;IAChD,MAAM,EAAE,iBAAiB,CAAC;IAC1B,+CAA+C;IAC/C,WAAW,EAAE,mBAAmB,CAAC;IACjC,sDAAsD;IACtD,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,yBAAyB;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,kDAAkD;IAClD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,4CAA4C;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;GAEG;AACH,UAAU,6BAA6B;IACrC,kEAAkE;IAClE,IAAI,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC/B,8BAA8B;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,wBAAwB,+DAA4D,CAAC;AAElG;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,WAAW,EACX,UAAU,EACV,KAAK,EACL,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE,8BAA8B,GAAG,SAAS,CAwE5C;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,0BAA0B,IAAI,6BAA6B,CAQ1E"}