dexie-cloud-addon 4.4.7 → 4.4.9

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.
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * ==========================================================================
10
10
  *
11
- * Version 4.4.7, Fri Mar 27 2026
11
+ * Version 4.4.9, Tue Mar 31 2026
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -3699,6 +3699,14 @@ function loadCachedAccessToken(db) {
3699
3699
  });
3700
3700
  return Promise.resolve(currentUser.accessToken);
3701
3701
  }
3702
+ // If the current user is not logged in (no isLoggedIn flag), there's no
3703
+ // token to load from the database — skip the Dexie.ignoreTransaction() call.
3704
+ // This avoids a crash in service worker context where Dexie's Promise zone
3705
+ // (PSD.transless.env) may be undefined when called from within an active
3706
+ // rw transaction (e.g. during applyServerChanges).
3707
+ if (!(currentUser === null || currentUser === void 0 ? void 0 : currentUser.isLoggedIn)) {
3708
+ return Promise.resolve(null);
3709
+ }
3702
3710
  return Dexie.ignoreTransaction(() => loadAccessToken(db).then((user) => {
3703
3711
  var _a, _b;
3704
3712
  if (user === null || user === void 0 ? void 0 : user.accessToken) {
@@ -3760,7 +3768,7 @@ function _sync(db_1, options_1, schema_1) {
3760
3768
  return __awaiter(this, arguments, void 0, function* (db, options, schema, { isInitialSync, cancelToken, justCheckIfNeeded, purpose } = {
3761
3769
  isInitialSync: false,
3762
3770
  }) {
3763
- var _a, _b, _c;
3771
+ var _a, _b, _c, _d, _e;
3764
3772
  if (!justCheckIfNeeded) {
3765
3773
  console.debug('SYNC STARTED', { isInitialSync, purpose });
3766
3774
  }
@@ -3834,7 +3842,7 @@ function _sync(db_1, options_1, schema_1) {
3834
3842
  // Offload large blobs to blob storage before sync
3835
3843
  //
3836
3844
  let processedChangeSet = clientChangeSet;
3837
- const maxStringLength = (_c = (_b = db.cloud.options) === null || _b === void 0 ? void 0 : _b.maxStringLength) !== null && _c !== void 0 ? _c : 32768;
3845
+ const maxStringLength = (_e = (_c = (_b = db.cloud.options) === null || _b === void 0 ? void 0 : _b.largeStringThreshold) !== null && _c !== void 0 ? _c : (_d = db.cloud.options) === null || _d === void 0 ? void 0 : _d.maxStringLength) !== null && _e !== void 0 ? _e : 32768;
3838
3846
  const hasLargeBlobs = hasLargeBlobsInOperations(clientChangeSet, maxStringLength);
3839
3847
  if (hasLargeBlobs) {
3840
3848
  processedChangeSet = yield offloadBlobsInOperations(clientChangeSet, databaseUrl, () => loadCachedAccessToken(db), maxStringLength);
@@ -4280,8 +4288,9 @@ class BlobDownloadTracker {
4280
4288
  if (!promise) {
4281
4289
  promise = loadCachedAccessToken(this.db)
4282
4290
  .then((accessToken) => {
4283
- if (!accessToken)
4284
- throw new Error('No access token available for blob download');
4291
+ // accessToken may be null for anonymous/unauthenticated users.
4292
+ // Public realm blobs (rlm-public) are accessible without auth.
4293
+ // downloadBlob will omit the Authorization header when token is null.
4285
4294
  return downloadBlob(blobRef, dbUrl, accessToken);
4286
4295
  })
4287
4296
  .finally(() => this.inFlight.delete(blobRef.ref));
@@ -4294,19 +4303,22 @@ class BlobDownloadTracker {
4294
4303
  /**
4295
4304
  * Download blob data from server via proxy endpoint.
4296
4305
  * Uses auth header for authentication (same as sync).
4306
+ * When accessToken is null, the request is made without Authorization header —
4307
+ * this allows downloading blobs from public realms (rlm-public) for
4308
+ * unauthenticated users.
4297
4309
  *
4298
4310
  * @param blobRef - The BlobRef to download
4299
4311
  * @param dbUrl - Base URL for the database (e.g., 'https://mydb.dexie.cloud')
4300
- * @param accessToken - Access token for authentication
4312
+ * @param accessToken - Access token for authentication, or null for anonymous access
4301
4313
  */
4302
4314
  function downloadBlob(blobRef, dbUrl, accessToken) {
4303
4315
  return __awaiter(this, void 0, void 0, function* () {
4304
4316
  const downloadUrl = `${dbUrl}/blob/${blobRef.ref}`;
4305
- const response = yield fetch(downloadUrl, {
4306
- headers: {
4307
- Authorization: `Bearer ${accessToken}`,
4308
- },
4309
- });
4317
+ const headers = {};
4318
+ if (accessToken) {
4319
+ headers['Authorization'] = `Bearer ${accessToken}`;
4320
+ }
4321
+ const response = yield fetch(downloadUrl, { headers });
4310
4322
  if (!response.ok) {
4311
4323
  throw new Error(`Failed to download blob ${blobRef.ref}: ${response.status} ${response.statusText}`);
4312
4324
  }
@@ -8317,7 +8329,7 @@ function dexieCloud(dexie) {
8317
8329
  const downloading$ = createDownloadingState();
8318
8330
  dexie.cloud = {
8319
8331
  // @ts-ignore
8320
- version: "4.4.7",
8332
+ version: "4.4.9",
8321
8333
  options: Object.assign({}, DEFAULT_OPTIONS),
8322
8334
  schema: null,
8323
8335
  get currentUserId() {
@@ -8345,18 +8357,27 @@ function dexieCloud(dexie) {
8345
8357
  invites: getInvitesObservable(dexie),
8346
8358
  roles: getGlobalRolesObservable(dexie),
8347
8359
  configure(options) {
8348
- // Validate maxStringLength Infinity disables offloading, otherwise must be
8349
- // a finite number between 100 and the server limit (32768).
8360
+ // Validate largeStringThreshold (preferred) or maxStringLength (deprecated)
8361
+ // Infinity disables offloading, otherwise must be a finite number between 100
8362
+ // and the server limit (32768).
8350
8363
  // Minimum 100 prevents accidental offloading of primary keys and short strings
8351
8364
  // that would break sync.
8352
8365
  const MIN_STRING_LENGTH = 100;
8353
8366
  const MAX_SERVER_STRING_LENGTH = 32768;
8354
- if (options.maxStringLength !== undefined &&
8355
- options.maxStringLength !== Infinity &&
8356
- (!Number.isFinite(options.maxStringLength) ||
8357
- options.maxStringLength < MIN_STRING_LENGTH ||
8358
- options.maxStringLength > MAX_SERVER_STRING_LENGTH)) {
8359
- throw new Error(`maxStringLength must be Infinity or a finite number in [${MIN_STRING_LENGTH}, ${MAX_SERVER_STRING_LENGTH}]. Got: ${options.maxStringLength}`);
8367
+ if (options.maxStringLength !== undefined) {
8368
+ console.warn('maxStringLength is deprecated, use largeStringThreshold instead');
8369
+ // If largeStringThreshold is not explicitly set, migrate to new name
8370
+ if (options.largeStringThreshold === undefined) {
8371
+ options = Object.assign(Object.assign({}, options), { largeStringThreshold: options.maxStringLength });
8372
+ }
8373
+ }
8374
+ const thresholdValue = options.largeStringThreshold;
8375
+ if (thresholdValue !== undefined &&
8376
+ thresholdValue !== Infinity &&
8377
+ (!Number.isFinite(thresholdValue) ||
8378
+ thresholdValue < MIN_STRING_LENGTH ||
8379
+ thresholdValue > MAX_SERVER_STRING_LENGTH)) {
8380
+ throw new Error(`largeStringThreshold must be Infinity or a finite number in [${MIN_STRING_LENGTH}, ${MAX_SERVER_STRING_LENGTH}]. Got: ${thresholdValue}`);
8360
8381
  }
8361
8382
  options = dexie.cloud.options = Object.assign(Object.assign({}, dexie.cloud.options), options);
8362
8383
  configuredProgramatically = true;
@@ -8753,7 +8774,7 @@ function dexieCloud(dexie) {
8753
8774
  }
8754
8775
  }
8755
8776
  // @ts-ignore
8756
- dexieCloud.version = "4.4.7";
8777
+ dexieCloud.version = "4.4.9";
8757
8778
  Dexie.Cloud = dexieCloud;
8758
8779
 
8759
8780
  // In case the SW lives for a while, let it reuse already opened connections: