@drakkar.software/starfish-client 2.0.0 → 2.2.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.
- package/dist/bindings/zustand.d.ts +2 -0
- package/dist/bindings/zustand.js +37 -4
- package/dist/bindings/zustand.js.map +2 -2
- package/dist/hash.d.ts +10 -0
- package/dist/hash.js +34 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +2 -2
- package/dist/mobile-lifecycle.js +2 -2
- package/dist/platform.d.ts +52 -0
- package/dist/platform.js +62 -0
- package/dist/polling.js +2 -2
- package/dist/sync.d.ts +8 -0
- package/package.json +2 -2
- package/dist/append.d.ts +0 -50
- package/dist/bindings/broadcast.d.ts +0 -19
- package/dist/bindings/broadcast.js +0 -65
- package/dist/bindings/react.d.ts +0 -12
- package/dist/bindings/react.js +0 -25
package/dist/index.js
CHANGED
|
@@ -198,6 +198,12 @@ function createSchemaValidator(ajv, schema) {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
// src/sync.ts
|
|
201
|
+
var AbortError = class extends Error {
|
|
202
|
+
constructor() {
|
|
203
|
+
super("SyncManager was aborted");
|
|
204
|
+
this.name = "AbortError";
|
|
205
|
+
}
|
|
206
|
+
};
|
|
201
207
|
var SyncManager = class {
|
|
202
208
|
client;
|
|
203
209
|
pullPath;
|
|
@@ -212,6 +218,7 @@ var SyncManager = class {
|
|
|
212
218
|
lastHash = null;
|
|
213
219
|
lastCheckpoint = 0;
|
|
214
220
|
localData = {};
|
|
221
|
+
aborted = false;
|
|
215
222
|
constructor(options) {
|
|
216
223
|
this.client = options.client;
|
|
217
224
|
this.pullPath = options.pullPath;
|
|
@@ -224,22 +231,35 @@ var SyncManager = class {
|
|
|
224
231
|
this.validate = options.validate;
|
|
225
232
|
this.encryptor = options.encryptor ?? (options.encryptionSecret && options.encryptionSalt ? createEncryptor(options.encryptionSecret, options.encryptionSalt, options.encryptionInfo) : null);
|
|
226
233
|
}
|
|
234
|
+
abort() {
|
|
235
|
+
this.aborted = true;
|
|
236
|
+
}
|
|
237
|
+
get isAborted() {
|
|
238
|
+
return this.aborted;
|
|
239
|
+
}
|
|
227
240
|
getData() {
|
|
228
241
|
return { ...this.localData };
|
|
229
242
|
}
|
|
230
243
|
getHash() {
|
|
231
244
|
return this.lastHash;
|
|
232
245
|
}
|
|
246
|
+
/** Set the last-known server hash. Used by persistence layers to restore state across restarts. */
|
|
247
|
+
setHash(hash) {
|
|
248
|
+
this.lastHash = hash;
|
|
249
|
+
}
|
|
233
250
|
getCheckpoint() {
|
|
234
251
|
return this.lastCheckpoint;
|
|
235
252
|
}
|
|
236
253
|
async pull() {
|
|
254
|
+
if (this.aborted) throw new AbortError();
|
|
237
255
|
this.logger?.pullStart(this.loggerName);
|
|
238
256
|
const start = performance.now();
|
|
239
257
|
try {
|
|
240
258
|
const result = await this.client.pull(this.pullPath, this.lastCheckpoint);
|
|
259
|
+
if (this.aborted) throw new AbortError();
|
|
241
260
|
if (this.encryptor) {
|
|
242
261
|
const decrypted = await this.encryptor.decrypt(result.data);
|
|
262
|
+
if (this.aborted) throw new AbortError();
|
|
243
263
|
this.localData = decrypted;
|
|
244
264
|
result.data = decrypted;
|
|
245
265
|
} else if (this.lastCheckpoint > 0) {
|
|
@@ -258,6 +278,7 @@ var SyncManager = class {
|
|
|
258
278
|
}
|
|
259
279
|
}
|
|
260
280
|
async push(data) {
|
|
281
|
+
if (this.aborted) throw new AbortError();
|
|
261
282
|
if (this.validate) {
|
|
262
283
|
const result = this.validate(data);
|
|
263
284
|
if (result !== true) throw new ValidationError(result);
|
|
@@ -269,19 +290,23 @@ var SyncManager = class {
|
|
|
269
290
|
while (attempt <= this.maxRetries) {
|
|
270
291
|
try {
|
|
271
292
|
const payload = this.encryptor ? await this.encryptor.encrypt(pendingData) : pendingData;
|
|
293
|
+
if (this.aborted) throw new AbortError();
|
|
272
294
|
const sig = this.signData ? await this.signData(stableStringify(payload)) : void 0;
|
|
295
|
+
if (this.aborted) throw new AbortError();
|
|
273
296
|
const result = await this.client.push(
|
|
274
297
|
this.pushPath,
|
|
275
298
|
payload,
|
|
276
299
|
this.lastHash,
|
|
277
300
|
sig
|
|
278
301
|
);
|
|
302
|
+
if (this.aborted) throw new AbortError();
|
|
279
303
|
this.lastHash = result.hash;
|
|
280
304
|
this.lastCheckpoint = result.timestamp;
|
|
281
305
|
this.localData = pendingData;
|
|
282
306
|
this.logger?.pushSuccess(this.loggerName, Math.round(performance.now() - start));
|
|
283
307
|
return result;
|
|
284
308
|
} catch (err) {
|
|
309
|
+
if (err instanceof AbortError) throw err;
|
|
285
310
|
if (!(err instanceof ConflictError) || attempt >= this.maxRetries) {
|
|
286
311
|
this.logger?.pushError(this.loggerName, err instanceof Error ? err.message : String(err));
|
|
287
312
|
throw err;
|
|
@@ -289,11 +314,14 @@ var SyncManager = class {
|
|
|
289
314
|
this.logger?.conflict(this.loggerName, attempt + 1);
|
|
290
315
|
try {
|
|
291
316
|
const remote = await this.client.pull(this.pullPath);
|
|
317
|
+
if (this.aborted) throw new AbortError();
|
|
292
318
|
const remoteData = this.encryptor ? await this.encryptor.decrypt(remote.data) : remote.data;
|
|
319
|
+
if (this.aborted) throw new AbortError();
|
|
293
320
|
this.lastHash = remote.hash;
|
|
294
321
|
this.lastCheckpoint = remote.timestamp;
|
|
295
322
|
pendingData = this.onConflict(pendingData, remoteData);
|
|
296
323
|
} catch (resolveErr) {
|
|
324
|
+
if (resolveErr instanceof AbortError) throw resolveErr;
|
|
297
325
|
const msg = resolveErr instanceof Error ? resolveErr.message : String(resolveErr);
|
|
298
326
|
this.logger?.pushError(this.loggerName, `Conflict resolution failed (attempt ${attempt + 1}): ${msg}`);
|
|
299
327
|
throw resolveErr;
|
|
@@ -1308,6 +1336,7 @@ async function pullEntitlements(client, userId, opts) {
|
|
|
1308
1336
|
}
|
|
1309
1337
|
}
|
|
1310
1338
|
export {
|
|
1339
|
+
AbortError,
|
|
1311
1340
|
ConflictError,
|
|
1312
1341
|
ENCRYPTED_KEY,
|
|
1313
1342
|
SnapshotHistory,
|