cry-synced-db-client 0.1.216 → 0.1.218

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/index.js CHANGED
@@ -7684,17 +7684,30 @@ var _SyncedDb = class _SyncedDb {
7684
7684
  }
7685
7685
  }
7686
7686
  }
7687
- /** Stringify an Id parameter (ObjectId → hex string). */
7687
+ /**
7688
+ * Stringify an Id parameter (ObjectId → hex string).
7689
+ *
7690
+ * Throws when `id` is falsy (null, undefined, 0, "", false) or is a
7691
+ * stringified-falsy value ("undefined", "null", "0", "false", "").
7692
+ * Passing a garbage _id creates a stuck dirty item that can never be
7693
+ * uploaded (server rejects it) and can never be auto-healed (library
7694
+ * doesn't know the correct _id). Fail-fast prevents silent data loss.
7695
+ */
7688
7696
  normalizeId(id, method, collection) {
7689
7697
  if (!id && id !== void 0) {
7690
- console.error(
7691
- `[SyncedDb] SyncedDb.${method != null ? method : "?"}("${collection != null ? collection : "?"}"): id parameter is falsy (${JSON.stringify(id)}). This is a bug \u2014 the caller must provide a valid _id.`
7692
- );
7698
+ const msg = `[SyncedDb] SyncedDb.${method != null ? method : "?"}("${collection != null ? collection : "?"}"): id parameter is falsy (${JSON.stringify(id)}). This is a bug \u2014 the caller must provide a valid _id.`;
7699
+ console.error(msg);
7700
+ throw new Error(msg);
7693
7701
  }
7694
7702
  if (typeof id === "string" && _SyncedDb.STRINGIFIED_FALSY.has(id)) {
7695
- console.error(
7696
- `[SyncedDb] SyncedDb.${method != null ? method : "?"}("${collection != null ? collection : "?"}"): id is a stringified falsy value ("${id}"). This is a bug \u2014 a falsy value was coerced to string before being passed as _id.`
7697
- );
7703
+ const msg = `[SyncedDb] SyncedDb.${method != null ? method : "?"}("${collection != null ? collection : "?"}"): id is a stringified falsy value ("${id}"). This is a bug \u2014 a falsy value was coerced to string before being passed as _id.`;
7704
+ console.error(msg);
7705
+ throw new Error(msg);
7706
+ }
7707
+ if (id === void 0) {
7708
+ const msg = `[SyncedDb] SyncedDb.${method != null ? method : "?"}("${collection != null ? collection : "?"}"): id parameter is undefined. This is a bug \u2014 the caller must provide a valid _id.`;
7709
+ console.error(msg);
7710
+ throw new Error(msg);
7698
7711
  }
7699
7712
  return typeof id === "object" && id !== null ? String(id) : id;
7700
7713
  }
@@ -7976,7 +7989,30 @@ var DexieDb = class extends Dexie {
7976
7989
  }
7977
7990
  return table;
7978
7991
  }
7979
- idToString(id) {
7992
+ /**
7993
+ * Convert an Id to its string representation for IndexedDB key storage.
7994
+ * Throws on falsy values to prevent stuck-dirty items with garbage
7995
+ * _id values like "undefined" / "null" that can never be uploaded.
7996
+ */
7997
+ idToString(id, debugContext) {
7998
+ if (!id && id !== void 0) {
7999
+ console.error(
8000
+ `[DexieDb.idToString] id is falsy (${JSON.stringify(id)}, type ${typeof id}). `,
8001
+ debugContext
8002
+ );
8003
+ }
8004
+ if (id === void 0) {
8005
+ console.error(
8006
+ `[DexieDb.idToString] id is undefined. `,
8007
+ debugContext
8008
+ );
8009
+ }
8010
+ if (typeof id === "string" && (id === "undefined" || id === "null" || id === "0" || id === "false" || id === "")) {
8011
+ console.error(
8012
+ `[DexieDb.idToString] id is a stringified falsy value ("${id}"). `,
8013
+ debugContext
8014
+ );
8015
+ }
7980
8016
  return String(id);
7981
8017
  }
7982
8018
  /** Ensure _id is a primitive string. IndexedDB rejects ObjectId objects as keys. */
@@ -7987,7 +8023,7 @@ var DexieDb = class extends Dexie {
7987
8023
  }
7988
8024
  async save(collection, id, data) {
7989
8025
  const table = this.getTable(collection);
7990
- const key = this.idToString(id);
8026
+ const key = this.idToString(id, { collection, id, data, calledFrom: "DexieDb/save" });
7991
8027
  const existing = await table.get(key);
7992
8028
  if (existing) {
7993
8029
  await table.update(key, data);
@@ -8032,14 +8068,14 @@ var DexieDb = class extends Dexie {
8032
8068
  }
8033
8069
  async deleteOne(collection, id) {
8034
8070
  const table = this.getTable(collection);
8035
- const key = this.idToString(id);
8071
+ const key = this.idToString(id, { collection, id, calledFrom: "DexieDb/deleteOne" });
8036
8072
  await table.delete(key);
8037
8073
  }
8038
8074
  async deleteMany(collection, ids) {
8039
8075
  if (ids.length === 0) return;
8040
8076
  const table = this.getTable(collection);
8041
8077
  const keys = [];
8042
- for (const id of ids) keys.push(this.idToString(id));
8078
+ for (const id of ids) keys.push(this.idToString(id, { collection, id, ids, calledFrom: "DexieDb/deleteMany" }));
8043
8079
  await table.bulkDelete(keys);
8044
8080
  }
8045
8081
  async saveCollection(collection, data) {
@@ -8056,14 +8092,14 @@ var DexieDb = class extends Dexie {
8056
8092
  }
8057
8093
  async getById(collection, id) {
8058
8094
  const table = this.getTable(collection);
8059
- const key = this.idToString(id);
8095
+ const key = this.idToString(id, { collection, id, calledFrom: "DexieDb/getById" });
8060
8096
  return await table.get(key);
8061
8097
  }
8062
8098
  async getByIds(collection, ids) {
8063
8099
  if (ids.length === 0) return [];
8064
8100
  const table = this.getTable(collection);
8065
8101
  const keys = [];
8066
- for (const id of ids) keys.push(this.idToString(id));
8102
+ for (const id of ids) keys.push(this.idToString(id, { collection, ids, calledFrom: "DexieDb/getByIds" }));
8067
8103
  return await table.bulkGet(keys);
8068
8104
  }
8069
8105
  async getAll(collection) {
@@ -8116,7 +8152,7 @@ var DexieDb = class extends Dexie {
8116
8152
  }
8117
8153
  async addDirtyChange(collection, id, changes, baseMeta) {
8118
8154
  if (isMetaOnlyChanges(changes)) return;
8119
- const stringId = this.idToString(id);
8155
+ const stringId = this.idToString(id, { collection, id, changes, baseMeta, calledFrom: "DexieDb/addDirtyChange" });
8120
8156
  const existing = await this.dirtyChanges.get([collection, stringId]);
8121
8157
  const now = Date.now();
8122
8158
  if (existing) {
@@ -8143,12 +8179,12 @@ var DexieDb = class extends Dexie {
8143
8179
  if (filtered.length === 0) return;
8144
8180
  const now = Date.now();
8145
8181
  const keys = [];
8146
- for (const c of filtered) keys.push([collection, this.idToString(c.id)]);
8182
+ for (const c of filtered) keys.push([collection, this.idToString(c.id, { collection, changesList, c, calledFrom: "DexieDb/addDirtyChangesBatch" })]);
8147
8183
  const existingEntries = await this.dirtyChanges.bulkGet(keys);
8148
8184
  const toWrite = [];
8149
8185
  for (let i = 0; i < filtered.length; i++) {
8150
8186
  const changeItem = filtered[i];
8151
- const stringId = this.idToString(changeItem.id);
8187
+ const stringId = this.idToString(changeItem.id, { collection, changesList, changeItem, calledFrom: "DexieDb/addDirtyChangesBatch" });
8152
8188
  const existing = existingEntries[i];
8153
8189
  if (existing) {
8154
8190
  rebaseDirtyOnServerAdvance(existing, changeItem.changes, changeItem.baseMeta);
@@ -8170,19 +8206,19 @@ var DexieDb = class extends Dexie {
8170
8206
  await this.dirtyChanges.bulkPut(toWrite);
8171
8207
  }
8172
8208
  async getDirtyChange(collection, id) {
8173
- const stringId = this.idToString(id);
8209
+ const stringId = this.idToString(id, { collection, id, calledFrom: "DexieDb/getDirtyChange" });
8174
8210
  return this.dirtyChanges.get([collection, stringId]);
8175
8211
  }
8176
8212
  async getDirtyChangesBatch(collection, ids) {
8177
8213
  const result = /* @__PURE__ */ new Map();
8178
8214
  if (ids.length === 0) return result;
8179
8215
  const keys = [];
8180
- for (const id of ids) keys.push([collection, this.idToString(id)]);
8216
+ for (const id of ids) keys.push([collection, this.idToString(id, { collection, ids, id, calledFrom: "DexieDb/getDirtyChangesBatch" })]);
8181
8217
  const entries = await this.dirtyChanges.bulkGet(keys);
8182
8218
  for (let i = 0; i < ids.length; i++) {
8183
8219
  const entry = entries[i];
8184
8220
  if (entry) {
8185
- result.set(this.idToString(ids[i]), entry);
8221
+ result.set(this.idToString(ids[i], { collection, ids, entry, calledFrom: "DexieDb/getDirtyChangesBatch" }), entry);
8186
8222
  }
8187
8223
  }
8188
8224
  return result;
@@ -8191,7 +8227,7 @@ var DexieDb = class extends Dexie {
8191
8227
  var _a;
8192
8228
  if (ids.length === 0) return [];
8193
8229
  const keys = [];
8194
- for (const id of ids) keys.push([collection, this.idToString(id)]);
8230
+ for (const id of ids) keys.push([collection, this.idToString(id, { collection, id, ids, calledFrom: "DexieDb/incrementDirtyUploadAttempts" })]);
8195
8231
  const entries = await this.dirtyChanges.bulkGet(keys);
8196
8232
  const now = Date.now();
8197
8233
  const toUpdate = [];
@@ -8227,7 +8263,7 @@ var DexieDb = class extends Dexie {
8227
8263
  return newlyStuck;
8228
8264
  }
8229
8265
  async clearDirtyChange(collection, id) {
8230
- const stringId = this.idToString(id);
8266
+ const stringId = this.idToString(id, { collection, id, calledFrom: "DexieDb/clearDirtyChange" });
8231
8267
  await this.dirtyChanges.delete([collection, stringId]);
8232
8268
  }
8233
8269
  async clearDirtyChangesBatch(collection, ids) {
@@ -8235,7 +8271,7 @@ var DexieDb = class extends Dexie {
8235
8271
  const promises = [];
8236
8272
  for (const id of ids) {
8237
8273
  promises.push(
8238
- this.dirtyChanges.delete([collection, this.idToString(id)])
8274
+ this.dirtyChanges.delete([collection, this.idToString(id, { collection, id, ids, calledFrom: "DexieDb/clearDirtyChangesBatch" })])
8239
8275
  );
8240
8276
  }
8241
8277
  await Promise.all(promises);
@@ -15,6 +15,11 @@ export declare class DexieDb extends Dexie implements I_DexieDb {
15
15
  private _isNewDatabase;
16
16
  constructor(tenant: string, collectionConfigs: CollectionConfig<any>[]);
17
17
  private getTable;
18
+ /**
19
+ * Convert an Id to its string representation for IndexedDB key storage.
20
+ * Throws on falsy values to prevent stuck-dirty items with garbage
21
+ * _id values like "undefined" / "null" that can never be uploaded.
22
+ */
18
23
  private idToString;
19
24
  /** Ensure _id is a primitive string. IndexedDB rejects ObjectId objects as keys. */
20
25
  private ensureStringId;
@@ -617,7 +617,15 @@ export declare class SyncedDb implements I_SyncedDb {
617
617
  */
618
618
  private _autoRegisterTemporaryForFind;
619
619
  private static readonly STRINGIFIED_FALSY;
620
- /** Stringify an Id parameter (ObjectId → hex string). */
620
+ /**
621
+ * Stringify an Id parameter (ObjectId → hex string).
622
+ *
623
+ * Throws when `id` is falsy (null, undefined, 0, "", false) or is a
624
+ * stringified-falsy value ("undefined", "null", "0", "false", "").
625
+ * Passing a garbage _id creates a stuck dirty item that can never be
626
+ * uploaded (server rejects it) and can never be auto-healed (library
627
+ * doesn't know the correct _id). Fail-fast prevents silent data loss.
628
+ */
621
629
  private normalizeId;
622
630
  /**
623
631
  * Warn if a query/data object has `_id` present but falsy.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.216",
3
+ "version": "0.1.218",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",