@prabhask5/stellar-engine 1.0.3

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 (138) hide show
  1. package/README.md +295 -0
  2. package/dist/actions/remoteChange.d.ts +79 -0
  3. package/dist/actions/remoteChange.d.ts.map +1 -0
  4. package/dist/actions/remoteChange.js +300 -0
  5. package/dist/actions/remoteChange.js.map +1 -0
  6. package/dist/auth/admin.d.ts +12 -0
  7. package/dist/auth/admin.d.ts.map +1 -0
  8. package/dist/auth/admin.js +23 -0
  9. package/dist/auth/admin.js.map +1 -0
  10. package/dist/auth/offlineCredentials.d.ts +41 -0
  11. package/dist/auth/offlineCredentials.d.ts.map +1 -0
  12. package/dist/auth/offlineCredentials.js +121 -0
  13. package/dist/auth/offlineCredentials.js.map +1 -0
  14. package/dist/auth/offlineLogin.d.ts +34 -0
  15. package/dist/auth/offlineLogin.d.ts.map +1 -0
  16. package/dist/auth/offlineLogin.js +75 -0
  17. package/dist/auth/offlineLogin.js.map +1 -0
  18. package/dist/auth/offlineSession.d.ts +22 -0
  19. package/dist/auth/offlineSession.d.ts.map +1 -0
  20. package/dist/auth/offlineSession.js +54 -0
  21. package/dist/auth/offlineSession.js.map +1 -0
  22. package/dist/auth/resolveAuthState.d.ts +24 -0
  23. package/dist/auth/resolveAuthState.d.ts.map +1 -0
  24. package/dist/auth/resolveAuthState.js +69 -0
  25. package/dist/auth/resolveAuthState.js.map +1 -0
  26. package/dist/config.d.ts +53 -0
  27. package/dist/config.d.ts.map +1 -0
  28. package/dist/config.js +55 -0
  29. package/dist/config.js.map +1 -0
  30. package/dist/conflicts.d.ts +70 -0
  31. package/dist/conflicts.d.ts.map +1 -0
  32. package/dist/conflicts.js +321 -0
  33. package/dist/conflicts.js.map +1 -0
  34. package/dist/data.d.ts +77 -0
  35. package/dist/data.d.ts.map +1 -0
  36. package/dist/data.js +360 -0
  37. package/dist/data.js.map +1 -0
  38. package/dist/database.d.ts +31 -0
  39. package/dist/database.d.ts.map +1 -0
  40. package/dist/database.js +51 -0
  41. package/dist/database.js.map +1 -0
  42. package/dist/debug.d.ts +11 -0
  43. package/dist/debug.d.ts.map +1 -0
  44. package/dist/debug.js +48 -0
  45. package/dist/debug.js.map +1 -0
  46. package/dist/deviceId.d.ts +16 -0
  47. package/dist/deviceId.d.ts.map +1 -0
  48. package/dist/deviceId.js +48 -0
  49. package/dist/deviceId.js.map +1 -0
  50. package/dist/engine.d.ts +14 -0
  51. package/dist/engine.d.ts.map +1 -0
  52. package/dist/engine.js +1903 -0
  53. package/dist/engine.js.map +1 -0
  54. package/dist/entries/actions.d.ts +2 -0
  55. package/dist/entries/actions.d.ts.map +1 -0
  56. package/dist/entries/actions.js +3 -0
  57. package/dist/entries/actions.js.map +1 -0
  58. package/dist/entries/auth.d.ts +7 -0
  59. package/dist/entries/auth.d.ts.map +1 -0
  60. package/dist/entries/auth.js +6 -0
  61. package/dist/entries/auth.js.map +1 -0
  62. package/dist/entries/config.d.ts +3 -0
  63. package/dist/entries/config.d.ts.map +1 -0
  64. package/dist/entries/config.js +3 -0
  65. package/dist/entries/config.js.map +1 -0
  66. package/dist/entries/stores.d.ts +9 -0
  67. package/dist/entries/stores.d.ts.map +1 -0
  68. package/dist/entries/stores.js +9 -0
  69. package/dist/entries/stores.js.map +1 -0
  70. package/dist/entries/types.d.ts +11 -0
  71. package/dist/entries/types.d.ts.map +1 -0
  72. package/dist/entries/types.js +2 -0
  73. package/dist/entries/types.js.map +1 -0
  74. package/dist/entries/utils.d.ts +3 -0
  75. package/dist/entries/utils.d.ts.map +1 -0
  76. package/dist/entries/utils.js +4 -0
  77. package/dist/entries/utils.js.map +1 -0
  78. package/dist/index.d.ts +32 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +39 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/operations.d.ts +73 -0
  83. package/dist/operations.d.ts.map +1 -0
  84. package/dist/operations.js +227 -0
  85. package/dist/operations.js.map +1 -0
  86. package/dist/queue.d.ts +32 -0
  87. package/dist/queue.d.ts.map +1 -0
  88. package/dist/queue.js +377 -0
  89. package/dist/queue.js.map +1 -0
  90. package/dist/realtime.d.ts +57 -0
  91. package/dist/realtime.d.ts.map +1 -0
  92. package/dist/realtime.js +491 -0
  93. package/dist/realtime.js.map +1 -0
  94. package/dist/reconnectHandler.d.ts +16 -0
  95. package/dist/reconnectHandler.d.ts.map +1 -0
  96. package/dist/reconnectHandler.js +21 -0
  97. package/dist/reconnectHandler.js.map +1 -0
  98. package/dist/runtime/runtimeConfig.d.ts +27 -0
  99. package/dist/runtime/runtimeConfig.d.ts.map +1 -0
  100. package/dist/runtime/runtimeConfig.js +133 -0
  101. package/dist/runtime/runtimeConfig.js.map +1 -0
  102. package/dist/stores/authState.d.ts +57 -0
  103. package/dist/stores/authState.d.ts.map +1 -0
  104. package/dist/stores/authState.js +154 -0
  105. package/dist/stores/authState.js.map +1 -0
  106. package/dist/stores/network.d.ts +9 -0
  107. package/dist/stores/network.d.ts.map +1 -0
  108. package/dist/stores/network.js +97 -0
  109. package/dist/stores/network.js.map +1 -0
  110. package/dist/stores/remoteChanges.d.ts +142 -0
  111. package/dist/stores/remoteChanges.d.ts.map +1 -0
  112. package/dist/stores/remoteChanges.js +353 -0
  113. package/dist/stores/remoteChanges.js.map +1 -0
  114. package/dist/stores/sync.d.ts +35 -0
  115. package/dist/stores/sync.d.ts.map +1 -0
  116. package/dist/stores/sync.js +115 -0
  117. package/dist/stores/sync.js.map +1 -0
  118. package/dist/supabase/auth.d.ts +60 -0
  119. package/dist/supabase/auth.d.ts.map +1 -0
  120. package/dist/supabase/auth.js +298 -0
  121. package/dist/supabase/auth.js.map +1 -0
  122. package/dist/supabase/client.d.ts +15 -0
  123. package/dist/supabase/client.d.ts.map +1 -0
  124. package/dist/supabase/client.js +149 -0
  125. package/dist/supabase/client.js.map +1 -0
  126. package/dist/supabase/validate.d.ts +11 -0
  127. package/dist/supabase/validate.d.ts.map +1 -0
  128. package/dist/supabase/validate.js +38 -0
  129. package/dist/supabase/validate.js.map +1 -0
  130. package/dist/types.d.ts +78 -0
  131. package/dist/types.d.ts.map +1 -0
  132. package/dist/types.js +16 -0
  133. package/dist/types.js.map +1 -0
  134. package/dist/utils.d.ts +24 -0
  135. package/dist/utils.d.ts.map +1 -0
  136. package/dist/utils.js +56 -0
  137. package/dist/utils.js.map +1 -0
  138. package/package.json +84 -0
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Sync Operation Helpers
3
+ *
4
+ * Provides utilities for:
5
+ * - Transforming operations to Supabase mutations
6
+ * - Creating operation items
7
+ * - Operation coalescing logic
8
+ */
9
+ /**
10
+ * Transform a SyncOperationItem into a Supabase mutation payload.
11
+ * This is called by the sync engine when pushing to Supabase.
12
+ *
13
+ * @param operation The operation to transform
14
+ * @param currentValue The current value of the field (needed for increment operations)
15
+ * @returns The payload to send to Supabase
16
+ */
17
+ export function operationToMutation(operation, currentValue) {
18
+ switch (operation.operationType) {
19
+ case 'create':
20
+ return {
21
+ mutationType: 'insert',
22
+ payload: {
23
+ id: operation.entityId,
24
+ ...operation.value
25
+ }
26
+ };
27
+ case 'delete':
28
+ return {
29
+ mutationType: 'update',
30
+ payload: {
31
+ deleted: true,
32
+ updated_at: operation.timestamp
33
+ }
34
+ };
35
+ case 'increment': {
36
+ // For increment, we need to compute the new value
37
+ // currentValue should be provided by the caller from the local entity
38
+ const base = typeof currentValue === 'number' ? currentValue : 0;
39
+ const delta = typeof operation.value === 'number' ? operation.value : 0;
40
+ const newValue = base + delta;
41
+ if (!operation.field) {
42
+ throw new Error('Increment operation requires a field');
43
+ }
44
+ return {
45
+ mutationType: 'update',
46
+ payload: {
47
+ [operation.field]: newValue,
48
+ updated_at: operation.timestamp
49
+ }
50
+ };
51
+ }
52
+ case 'set': {
53
+ // For set, we either have a single field or a full payload
54
+ if (operation.field) {
55
+ // Single field set
56
+ return {
57
+ mutationType: 'update',
58
+ payload: {
59
+ [operation.field]: operation.value,
60
+ updated_at: operation.timestamp
61
+ }
62
+ };
63
+ }
64
+ else {
65
+ // Full payload set
66
+ return {
67
+ mutationType: 'update',
68
+ payload: {
69
+ ...operation.value,
70
+ updated_at: operation.timestamp
71
+ }
72
+ };
73
+ }
74
+ }
75
+ default:
76
+ throw new Error(`Unknown operation type: ${operation.operationType}`);
77
+ }
78
+ }
79
+ /**
80
+ * Infer the appropriate operation type based on the value and field name.
81
+ *
82
+ * @param value The value being set
83
+ * @param fieldName The name of the field
84
+ * @param isIncrement Whether this is a known increment operation
85
+ * @returns The inferred operation type
86
+ */
87
+ export function inferOperationType(_value, _fieldName, isIncrement) {
88
+ if (isIncrement) {
89
+ return 'increment';
90
+ }
91
+ // All non-increment operations are 'set'
92
+ return 'set';
93
+ }
94
+ /**
95
+ * Create an increment operation item.
96
+ */
97
+ export function createIncrementOperation(table, entityId, field, delta, timestamp) {
98
+ return {
99
+ table,
100
+ entityId,
101
+ operationType: 'increment',
102
+ field,
103
+ value: delta,
104
+ timestamp,
105
+ retries: 0
106
+ };
107
+ }
108
+ /**
109
+ * Create a set operation item for a single field.
110
+ */
111
+ export function createSetOperation(table, entityId, field, value, timestamp) {
112
+ return {
113
+ table,
114
+ entityId,
115
+ operationType: 'set',
116
+ field,
117
+ value,
118
+ timestamp,
119
+ retries: 0
120
+ };
121
+ }
122
+ /**
123
+ * Create a set operation item for multiple fields.
124
+ */
125
+ export function createMultiFieldSetOperation(table, entityId, fields, timestamp) {
126
+ return {
127
+ table,
128
+ entityId,
129
+ operationType: 'set',
130
+ value: fields,
131
+ timestamp,
132
+ retries: 0
133
+ };
134
+ }
135
+ /**
136
+ * Create a create operation item.
137
+ */
138
+ export function createCreateOperation(table, entityId, payload, timestamp) {
139
+ return {
140
+ table,
141
+ entityId,
142
+ operationType: 'create',
143
+ value: payload,
144
+ timestamp,
145
+ retries: 0
146
+ };
147
+ }
148
+ /**
149
+ * Create a delete operation item.
150
+ */
151
+ export function createDeleteOperation(table, entityId, timestamp) {
152
+ return {
153
+ table,
154
+ entityId,
155
+ operationType: 'delete',
156
+ timestamp,
157
+ retries: 0
158
+ };
159
+ }
160
+ /**
161
+ * Check if two operations can be coalesced together.
162
+ *
163
+ * Coalescing rules:
164
+ * - Same table + entityId + operationType can be coalesced
165
+ * - Increment operations: can be coalesced if same field (sums deltas)
166
+ * - Set operations: can be coalesced (keeps merged/latest values)
167
+ * - Create/delete: cannot coalesce (would lose intent)
168
+ */
169
+ export function canCoalesce(a, b) {
170
+ if (a.table !== b.table || a.entityId !== b.entityId) {
171
+ return false;
172
+ }
173
+ // Same operation type on same field can be coalesced
174
+ if (a.operationType === b.operationType) {
175
+ // Create and delete cannot coalesce (would lose intent)
176
+ if (a.operationType === 'create' || a.operationType === 'delete') {
177
+ return false;
178
+ }
179
+ // For increment operations, must be same field
180
+ if (a.operationType === 'increment') {
181
+ // Both must have a field specified
182
+ if (!a.field || !b.field) {
183
+ return false;
184
+ }
185
+ // Must be the same field
186
+ return a.field === b.field;
187
+ }
188
+ // For set operations with a specific field, must be same field
189
+ if (a.field && b.field && a.field !== b.field) {
190
+ return false;
191
+ }
192
+ return true;
193
+ }
194
+ return false;
195
+ }
196
+ /**
197
+ * Coalesce two operations into one.
198
+ *
199
+ * Coalescing strategy by operation type:
200
+ * - Increment: sum the deltas (e.g., +1 and +1 = +2)
201
+ * - Set: keep the newer value (last-write-wins)
202
+ *
203
+ * @param older The older operation
204
+ * @param newer The newer operation
205
+ * @returns The coalesced operation
206
+ */
207
+ export function coalesceOperations(older, newer) {
208
+ // For increment operations: sum the deltas
209
+ if (older.operationType === 'increment' && newer.operationType === 'increment') {
210
+ const olderDelta = typeof older.value === 'number' ? older.value : 0;
211
+ const newerDelta = typeof newer.value === 'number' ? newer.value : 0;
212
+ const summedDelta = olderDelta + newerDelta;
213
+ return {
214
+ ...older,
215
+ // Keep older's id and timestamp for queue management and backoff
216
+ value: summedDelta
217
+ };
218
+ }
219
+ // For set operations: keep the newer value but preserve older's id/timestamp
220
+ return {
221
+ ...newer,
222
+ id: older.id,
223
+ // Keep oldest timestamp for backoff calculation
224
+ timestamp: older.timestamp
225
+ };
226
+ }
227
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/operations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAA4B,EAC5B,YAAsB;IAEtB,QAAQ,SAAS,CAAC,aAAa,EAAE,CAAC;QAChC,KAAK,QAAQ;YACX,OAAO;gBACL,YAAY,EAAE,QAAQ;gBACtB,OAAO,EAAE;oBACP,EAAE,EAAE,SAAS,CAAC,QAAQ;oBACtB,GAAI,SAAS,CAAC,KAAiC;iBAChD;aACF,CAAC;QAEJ,KAAK,QAAQ;YACX,OAAO;gBACL,YAAY,EAAE,QAAQ;gBACtB,OAAO,EAAE;oBACP,OAAO,EAAE,IAAI;oBACb,UAAU,EAAE,SAAS,CAAC,SAAS;iBAChC;aACF,CAAC;QAEJ,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,kDAAkD;YAClD,sEAAsE;YACtE,MAAM,IAAI,GAAG,OAAO,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,MAAM,KAAK,GAAG,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,KAAK,CAAC;YAE9B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC1D,CAAC;YAED,OAAO;gBACL,YAAY,EAAE,QAAQ;gBACtB,OAAO,EAAE;oBACP,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,QAAQ;oBAC3B,UAAU,EAAE,SAAS,CAAC,SAAS;iBAChC;aACF,CAAC;QACJ,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,2DAA2D;YAC3D,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBACpB,mBAAmB;gBACnB,OAAO;oBACL,YAAY,EAAE,QAAQ;oBACtB,OAAO,EAAE;wBACP,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,KAAK;wBAClC,UAAU,EAAE,SAAS,CAAC,SAAS;qBAChC;iBACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,mBAAmB;gBACnB,OAAO;oBACL,YAAY,EAAE,QAAQ;oBACtB,OAAO,EAAE;wBACP,GAAI,SAAS,CAAC,KAAiC;wBAC/C,UAAU,EAAE,SAAS,CAAC,SAAS;qBAChC;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED;YACE,MAAM,IAAI,KAAK,CAAC,2BAA4B,SAA+B,CAAC,aAAa,EAAE,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAAe,EACf,UAAkB,EAClB,WAAqB;IAErB,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,yCAAyC;IACzC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAa,EACb,QAAgB,EAChB,KAAa,EACb,KAAa,EACb,SAAiB;IAEjB,OAAO;QACL,KAAK;QACL,QAAQ;QACR,aAAa,EAAE,WAAW;QAC1B,KAAK;QACL,KAAK,EAAE,KAAK;QACZ,SAAS;QACT,OAAO,EAAE,CAAC;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAa,EACb,QAAgB,EAChB,KAAa,EACb,KAAc,EACd,SAAiB;IAEjB,OAAO;QACL,KAAK;QACL,QAAQ;QACR,aAAa,EAAE,KAAK;QACpB,KAAK;QACL,KAAK;QACL,SAAS;QACT,OAAO,EAAE,CAAC;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAC1C,KAAa,EACb,QAAgB,EAChB,MAA+B,EAC/B,SAAiB;IAEjB,OAAO;QACL,KAAK;QACL,QAAQ;QACR,aAAa,EAAE,KAAK;QACpB,KAAK,EAAE,MAAM;QACb,SAAS;QACT,OAAO,EAAE,CAAC;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,QAAgB,EAChB,OAAgC,EAChC,SAAiB;IAEjB,OAAO;QACL,KAAK;QACL,QAAQ;QACR,aAAa,EAAE,QAAQ;QACvB,KAAK,EAAE,OAAO;QACd,SAAS;QACT,OAAO,EAAE,CAAC;KACX,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,KAAa,EACb,QAAgB,EAChB,SAAiB;IAEjB,OAAO;QACL,KAAK;QACL,QAAQ;QACR,aAAa,EAAE,QAAQ;QACvB,SAAS;QACT,OAAO,EAAE,CAAC;KACX,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,CAAoB,EAAE,CAAoB;IACpE,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qDAAqD;IACrD,IAAI,CAAC,CAAC,aAAa,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;QACxC,wDAAwD;QACxD,IAAI,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,CAAC,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;YACjE,OAAO,KAAK,CAAC;QACf,CAAC;QAED,+CAA+C;QAC/C,IAAI,CAAC,CAAC,aAAa,KAAK,WAAW,EAAE,CAAC;YACpC,mCAAmC;YACnC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,yBAAyB;YACzB,OAAO,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC;QAC7B,CAAC;QAED,+DAA+D;QAC/D,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAwB,EACxB,KAAwB;IAExB,2CAA2C;IAC3C,IAAI,KAAK,CAAC,aAAa,KAAK,WAAW,IAAI,KAAK,CAAC,aAAa,KAAK,WAAW,EAAE,CAAC;QAC/E,MAAM,UAAU,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,UAAU,GAAG,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;QAE5C,OAAO;YACL,GAAG,KAAK;YACR,iEAAiE;YACjE,KAAK,EAAE,WAAW;SACnB,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,OAAO;QACL,GAAG,KAAK;QACR,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,gDAAgD;QAChD,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { SyncOperationItem } from './types';
2
+ /**
3
+ * Coalesce multiple operations to the same entity into fewer operations.
4
+ * This dramatically reduces the number of server requests and data transfer.
5
+ *
6
+ * PERFORMANCE OPTIMIZED:
7
+ * - Single DB fetch at start (no re-fetching between phases)
8
+ * - All processing done in memory
9
+ * - Batch deletes and updates at the end
10
+ */
11
+ export declare function coalescePendingOps(): Promise<number>;
12
+ export declare function getPendingSync(): Promise<SyncOperationItem[]>;
13
+ export declare function cleanupFailedItems(): Promise<{
14
+ count: number;
15
+ tables: string[];
16
+ }>;
17
+ export declare function removeSyncItem(id: number): Promise<void>;
18
+ export declare function incrementRetry(id: number): Promise<void>;
19
+ export declare function getPendingEntityIds(): Promise<Set<string>>;
20
+ /**
21
+ * Queue a sync operation using the intent-based format.
22
+ */
23
+ export declare function queueSyncOperation(item: Omit<SyncOperationItem, 'id' | 'timestamp' | 'retries'>): Promise<void>;
24
+ /**
25
+ * Helper to queue a create operation.
26
+ */
27
+ export declare function queueCreateOperation(table: string, entityId: string, payload: Record<string, unknown>): Promise<void>;
28
+ /**
29
+ * Helper to queue a delete operation.
30
+ */
31
+ export declare function queueDeleteOperation(table: string, entityId: string): Promise<void>;
32
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AASjD;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CA8O1D;AAmFD,wBAAsB,cAAc,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAOnE;AAGD,wBAAsB,kBAAkB,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAuBvF;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG9D;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU9D;AAGD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAIhE;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,WAAW,GAAG,SAAS,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC,CASf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzF"}
package/dist/queue.js ADDED
@@ -0,0 +1,377 @@
1
+ import { debugWarn } from './debug';
2
+ import { getEngineConfig } from './config';
3
+ // Max retries before giving up on a sync item
4
+ const MAX_SYNC_RETRIES = 5;
5
+ function getDb() {
6
+ return getEngineConfig().db;
7
+ }
8
+ /**
9
+ * Coalesce multiple operations to the same entity into fewer operations.
10
+ * This dramatically reduces the number of server requests and data transfer.
11
+ *
12
+ * PERFORMANCE OPTIMIZED:
13
+ * - Single DB fetch at start (no re-fetching between phases)
14
+ * - All processing done in memory
15
+ * - Batch deletes and updates at the end
16
+ */
17
+ export async function coalescePendingOps() {
18
+ const db = getDb();
19
+ const allItems = (await db.table('syncQueue').toArray());
20
+ if (allItems.length <= 1)
21
+ return 0;
22
+ // Track changes in memory - apply in batch at the end
23
+ const idsToDelete = new Set();
24
+ const itemUpdates = new Map();
25
+ // Track which items are still "alive" (not marked for deletion)
26
+ const isAlive = (item) => item.id !== undefined && !idsToDelete.has(item.id);
27
+ // Helper to mark item for deletion
28
+ const markDeleted = (item) => {
29
+ if (item.id !== undefined)
30
+ idsToDelete.add(item.id);
31
+ };
32
+ // Helper to mark item for update
33
+ const markUpdated = (item, updates) => {
34
+ if (item.id !== undefined) {
35
+ const existing = itemUpdates.get(item.id) || {};
36
+ itemUpdates.set(item.id, { ...existing, ...updates });
37
+ }
38
+ };
39
+ // Helper to get effective value (considering pending updates)
40
+ const getEffectiveValue = (item) => {
41
+ if (item.id !== undefined && itemUpdates.has(item.id)) {
42
+ return itemUpdates.get(item.id).value ?? item.value;
43
+ }
44
+ return item.value;
45
+ };
46
+ // === STEP 1: Group all operations by entity ===
47
+ const entityGroups = new Map();
48
+ for (const item of allItems) {
49
+ const key = `${item.table}:${item.entityId}`;
50
+ if (!entityGroups.has(key))
51
+ entityGroups.set(key, []);
52
+ entityGroups.get(key).push(item);
53
+ }
54
+ // === STEP 2: Process each entity group ===
55
+ for (const [, items] of entityGroups) {
56
+ // Sort by timestamp to understand the sequence
57
+ items.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
58
+ const hasCreate = items.some((i) => i.operationType === 'create');
59
+ const hasDelete = items.some((i) => i.operationType === 'delete');
60
+ // Case 1: CREATE followed eventually by DELETE -> cancel everything for this entity
61
+ if (hasCreate && hasDelete) {
62
+ for (const item of items) {
63
+ markDeleted(item);
64
+ }
65
+ continue;
66
+ }
67
+ // Case 2: No CREATE but has DELETE -> remove all non-delete operations
68
+ if (!hasCreate && hasDelete) {
69
+ for (const item of items) {
70
+ if (item.operationType !== 'delete') {
71
+ markDeleted(item);
72
+ }
73
+ }
74
+ continue;
75
+ }
76
+ // Case 3: Has CREATE but no DELETE -> merge all updates/sets into create
77
+ if (hasCreate && !hasDelete) {
78
+ const createItem = items.find((i) => i.operationType === 'create');
79
+ const otherItems = items.filter((i) => i.operationType !== 'create');
80
+ if (createItem && otherItems.length > 0) {
81
+ let mergedPayload = { ...createItem.value };
82
+ for (const item of otherItems) {
83
+ if (item.operationType === 'set') {
84
+ if (item.field) {
85
+ mergedPayload[item.field] = item.value;
86
+ }
87
+ else if (typeof item.value === 'object' && item.value !== null) {
88
+ mergedPayload = { ...mergedPayload, ...item.value };
89
+ }
90
+ }
91
+ else if (item.operationType === 'increment' && item.field) {
92
+ const currentVal = typeof mergedPayload[item.field] === 'number'
93
+ ? mergedPayload[item.field]
94
+ : 0;
95
+ const delta = typeof item.value === 'number' ? item.value : 0;
96
+ mergedPayload[item.field] = currentVal + delta;
97
+ }
98
+ }
99
+ markUpdated(createItem, { value: mergedPayload });
100
+ for (const item of otherItems) {
101
+ markDeleted(item);
102
+ }
103
+ }
104
+ continue;
105
+ }
106
+ // Case 4: No create, no delete - handle increment/set interactions and same-type coalescing
107
+ processFieldOperations(items, markDeleted, markUpdated);
108
+ }
109
+ // === STEP 3: Coalesce remaining INCREMENT operations (not yet deleted) ===
110
+ const incrementGroups = new Map();
111
+ for (const item of allItems) {
112
+ if (item.operationType === 'increment' && item.field && isAlive(item)) {
113
+ const key = `${item.table}:${item.entityId}:${item.field}`;
114
+ if (!incrementGroups.has(key))
115
+ incrementGroups.set(key, []);
116
+ incrementGroups.get(key).push(item);
117
+ }
118
+ }
119
+ for (const [, items] of incrementGroups) {
120
+ const aliveItems = items.filter(isAlive);
121
+ if (aliveItems.length <= 1)
122
+ continue;
123
+ aliveItems.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
124
+ let totalDelta = 0;
125
+ for (const item of aliveItems) {
126
+ const effectiveValue = getEffectiveValue(item);
127
+ const delta = typeof effectiveValue === 'number' ? effectiveValue : 0;
128
+ totalDelta += delta;
129
+ }
130
+ const oldestItem = aliveItems[0];
131
+ markUpdated(oldestItem, { value: totalDelta });
132
+ for (let i = 1; i < aliveItems.length; i++) {
133
+ markDeleted(aliveItems[i]);
134
+ }
135
+ }
136
+ // === STEP 4: Coalesce remaining SET operations (not yet deleted) ===
137
+ const setGroups = new Map();
138
+ for (const item of allItems) {
139
+ if (item.operationType === 'set' && isAlive(item)) {
140
+ const key = `${item.table}:${item.entityId}`;
141
+ if (!setGroups.has(key))
142
+ setGroups.set(key, []);
143
+ setGroups.get(key).push(item);
144
+ }
145
+ }
146
+ for (const [, items] of setGroups) {
147
+ const aliveItems = items.filter(isAlive);
148
+ if (aliveItems.length <= 1)
149
+ continue;
150
+ aliveItems.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
151
+ let mergedValue = {};
152
+ for (const item of aliveItems) {
153
+ const effectiveValue = getEffectiveValue(item);
154
+ if (item.field) {
155
+ mergedValue[item.field] = effectiveValue;
156
+ }
157
+ else if (typeof effectiveValue === 'object' && effectiveValue !== null) {
158
+ mergedValue = { ...mergedValue, ...effectiveValue };
159
+ }
160
+ }
161
+ const oldestItem = aliveItems[0];
162
+ markUpdated(oldestItem, { value: mergedValue, field: undefined });
163
+ for (let i = 1; i < aliveItems.length; i++) {
164
+ markDeleted(aliveItems[i]);
165
+ }
166
+ }
167
+ // === STEP 5: Remove no-op operations ===
168
+ for (const item of allItems) {
169
+ if (!isAlive(item))
170
+ continue;
171
+ let shouldDelete = false;
172
+ const effectiveValue = getEffectiveValue(item);
173
+ // Zero-delta increments are no-ops
174
+ if (item.operationType === 'increment') {
175
+ const delta = typeof effectiveValue === 'number' ? effectiveValue : 0;
176
+ if (delta === 0) {
177
+ shouldDelete = true;
178
+ }
179
+ }
180
+ // Empty sets or sets with only updated_at are no-ops
181
+ if (item.operationType === 'set') {
182
+ const pendingUpdate = item.id !== undefined ? itemUpdates.get(item.id) : undefined;
183
+ const effectiveField = pendingUpdate?.field !== undefined ? pendingUpdate.field : item.field;
184
+ if (effectiveField) {
185
+ if (effectiveField === 'updated_at') {
186
+ shouldDelete = true;
187
+ }
188
+ }
189
+ else if (typeof effectiveValue === 'object' && effectiveValue !== null) {
190
+ const payload = effectiveValue;
191
+ const keys = Object.keys(payload).filter((k) => k !== 'updated_at');
192
+ if (keys.length === 0) {
193
+ shouldDelete = true;
194
+ }
195
+ }
196
+ else if (effectiveValue === undefined || effectiveValue === null) {
197
+ shouldDelete = true;
198
+ }
199
+ }
200
+ if (shouldDelete) {
201
+ markDeleted(item);
202
+ }
203
+ }
204
+ // === STEP 6: Apply all changes in batch ===
205
+ const deleteIds = Array.from(idsToDelete);
206
+ // Filter out updates for items we're deleting
207
+ const finalUpdates = [];
208
+ for (const [id, changes] of itemUpdates) {
209
+ if (!idsToDelete.has(id)) {
210
+ finalUpdates.push({ id, changes });
211
+ }
212
+ }
213
+ const syncQueue = db.table('syncQueue');
214
+ // Batch delete
215
+ if (deleteIds.length > 0) {
216
+ await syncQueue.bulkDelete(deleteIds);
217
+ }
218
+ // Batch update (Dexie doesn't have bulkUpdate, so we use a transaction)
219
+ if (finalUpdates.length > 0) {
220
+ await db.transaction('rw', syncQueue, async () => {
221
+ for (const { id, changes } of finalUpdates) {
222
+ await syncQueue.update(id, changes);
223
+ }
224
+ });
225
+ }
226
+ return deleteIds.length;
227
+ }
228
+ /**
229
+ * Process increment/set interactions for the same field within an entity (in-memory).
230
+ */
231
+ function processFieldOperations(items, markDeleted, markUpdated) {
232
+ // Group by field
233
+ const fieldGroups = new Map();
234
+ for (const item of items) {
235
+ if (item.field && (item.operationType === 'increment' || item.operationType === 'set')) {
236
+ const key = item.field;
237
+ if (!fieldGroups.has(key))
238
+ fieldGroups.set(key, []);
239
+ fieldGroups.get(key).push(item);
240
+ }
241
+ }
242
+ for (const [, fieldItems] of fieldGroups) {
243
+ if (fieldItems.length <= 1)
244
+ continue;
245
+ // Sort by timestamp
246
+ fieldItems.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
247
+ const hasIncrement = fieldItems.some((i) => i.operationType === 'increment');
248
+ const hasSet = fieldItems.some((i) => i.operationType === 'set');
249
+ if (hasIncrement && hasSet) {
250
+ // Find the last set operation
251
+ const lastSetIndex = fieldItems.map((i) => i.operationType).lastIndexOf('set');
252
+ const lastSet = fieldItems[lastSetIndex];
253
+ // Check if there are increments AFTER the last set
254
+ const incrementsAfterSet = fieldItems
255
+ .slice(lastSetIndex + 1)
256
+ .filter((i) => i.operationType === 'increment');
257
+ if (incrementsAfterSet.length > 0) {
258
+ // SET followed by INCREMENT(s): sum increments and add to set value
259
+ let totalDelta = 0;
260
+ for (const inc of incrementsAfterSet) {
261
+ totalDelta += typeof inc.value === 'number' ? inc.value : 0;
262
+ }
263
+ const baseValue = typeof lastSet.value === 'number' ? lastSet.value : 0;
264
+ const finalValue = baseValue + totalDelta;
265
+ markUpdated(lastSet, { value: finalValue });
266
+ // Delete all increments after the set
267
+ for (const inc of incrementsAfterSet) {
268
+ markDeleted(inc);
269
+ }
270
+ }
271
+ // Delete all operations BEFORE the last set (they're overwritten anyway)
272
+ const itemsBeforeLastSet = fieldItems.slice(0, lastSetIndex);
273
+ for (const item of itemsBeforeLastSet) {
274
+ markDeleted(item);
275
+ }
276
+ }
277
+ }
278
+ }
279
+ // Exponential backoff: check if item should be retried based on retry count
280
+ // Returns true if enough time has passed since last attempt
281
+ function shouldRetryItem(item) {
282
+ if (item.retries >= MAX_SYNC_RETRIES)
283
+ return false;
284
+ // First attempt (retries=0) is always immediate
285
+ if (item.retries === 0)
286
+ return true;
287
+ // Exponential backoff for retries: 2^(retries-1) seconds (1s, 2s, 4s, 8s)
288
+ const backoffMs = Math.pow(2, item.retries - 1) * 1000;
289
+ const lastAttempt = new Date(item.timestamp).getTime();
290
+ const now = Date.now();
291
+ return now - lastAttempt >= backoffMs;
292
+ }
293
+ export async function getPendingSync() {
294
+ const db = getDb();
295
+ const allItems = (await db.table('syncQueue')
296
+ .orderBy('timestamp')
297
+ .toArray());
298
+ // Filter to only items that should be retried (haven't exceeded max retries and backoff has passed)
299
+ return allItems.filter((item) => shouldRetryItem(item));
300
+ }
301
+ // Remove items that have exceeded max retries and return details for notification
302
+ export async function cleanupFailedItems() {
303
+ const db = getDb();
304
+ const allItems = (await db.table('syncQueue').toArray());
305
+ const failedItems = allItems.filter((item) => item.retries >= MAX_SYNC_RETRIES);
306
+ const affectedTables = new Set();
307
+ for (const item of failedItems) {
308
+ affectedTables.add(item.table);
309
+ if (item.id) {
310
+ debugWarn(`Sync item permanently failed after ${MAX_SYNC_RETRIES} retries:`, {
311
+ table: item.table,
312
+ operationType: item.operationType,
313
+ entityId: item.entityId
314
+ });
315
+ await db.table('syncQueue').delete(item.id);
316
+ }
317
+ }
318
+ return {
319
+ count: failedItems.length,
320
+ tables: Array.from(affectedTables)
321
+ };
322
+ }
323
+ export async function removeSyncItem(id) {
324
+ const db = getDb();
325
+ await db.table('syncQueue').delete(id);
326
+ }
327
+ export async function incrementRetry(id) {
328
+ const db = getDb();
329
+ const item = await db.table('syncQueue').get(id);
330
+ if (item) {
331
+ // Update retry count and timestamp for exponential backoff calculation
332
+ await db.table('syncQueue').update(id, {
333
+ retries: item.retries + 1,
334
+ timestamp: new Date().toISOString()
335
+ });
336
+ }
337
+ }
338
+ // Get entity IDs that have pending sync operations
339
+ export async function getPendingEntityIds() {
340
+ const db = getDb();
341
+ const pending = (await db.table('syncQueue').toArray());
342
+ return new Set(pending.map((item) => item.entityId));
343
+ }
344
+ /**
345
+ * Queue a sync operation using the intent-based format.
346
+ */
347
+ export async function queueSyncOperation(item) {
348
+ const db = getDb();
349
+ const fullItem = {
350
+ ...item,
351
+ timestamp: new Date().toISOString(),
352
+ retries: 0
353
+ };
354
+ await db.table('syncQueue').add(fullItem);
355
+ }
356
+ /**
357
+ * Helper to queue a create operation.
358
+ */
359
+ export async function queueCreateOperation(table, entityId, payload) {
360
+ await queueSyncOperation({
361
+ table,
362
+ entityId,
363
+ operationType: 'create',
364
+ value: payload
365
+ });
366
+ }
367
+ /**
368
+ * Helper to queue a delete operation.
369
+ */
370
+ export async function queueDeleteOperation(table, entityId) {
371
+ await queueSyncOperation({
372
+ table,
373
+ entityId,
374
+ operationType: 'delete'
375
+ });
376
+ }
377
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}