cry-synced-db-client 0.1.50 → 0.1.51

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
@@ -1127,6 +1127,8 @@ class SyncedDb {
1127
1127
  closing = false;
1128
1128
  releasingLeadershipDueToVisibility = false;
1129
1129
  visibilityChangeHandler;
1130
+ useObjectMetadata;
1131
+ _metadata = {};
1130
1132
  constructor(config) {
1131
1133
  this.tenant = config.tenant;
1132
1134
  this.dexieDb = config.dexieDb;
@@ -1158,6 +1160,7 @@ class SyncedDb {
1158
1160
  this.onBecameLeader = config.onBecameLeader;
1159
1161
  this.onLostLeadership = config.onLostLeadership;
1160
1162
  this.onInfrastructureError = config.onInfrastructureError;
1163
+ this.useObjectMetadata = config.useObjectMetadata ?? false;
1161
1164
  this.updaterId = Math.random().toString(36).substring(2, 15);
1162
1165
  this.syncedDbInstanceId = `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
1163
1166
  for (const col of config.collections) {
@@ -1339,7 +1342,7 @@ class SyncedDb {
1339
1342
  for (const [name] of this.collections) {
1340
1343
  const data = await this.dexieDb.getAll(name);
1341
1344
  const activeData = data.filter((item) => !item._deleted);
1342
- this.inMemDb.saveCollection(name, activeData);
1345
+ this._initCollectionInMem(name, activeData);
1343
1346
  const meta = await this.dexieDb.getSyncMeta(name);
1344
1347
  if (meta) {
1345
1348
  this.syncMetaCache.set(name, meta);
@@ -1617,10 +1620,11 @@ class SyncedDb {
1617
1620
  _lastUpdaterId: this.updaterId
1618
1621
  };
1619
1622
  this.schedulePendingChange(collection, id, newData, 0, "save");
1623
+ const currentMem = this.inMemDb.getById(collection, id);
1624
+ const merged = { ...currentMem || existing || { _id: id }, ...update };
1620
1625
  if (existing?._deleted) {} else {
1621
- this.inMemDb.save(collection, id, update);
1626
+ this._writeToInMemBatch(collection, [merged], "upsert");
1622
1627
  }
1623
- const merged = { ...existing || { _id: id }, ...update };
1624
1628
  return this.stripLocalFields(merged);
1625
1629
  }
1626
1630
  async upsert(collection, query, update) {
@@ -1653,7 +1657,7 @@ class SyncedDb {
1653
1657
  _lastUpdaterId: this.updaterId
1654
1658
  };
1655
1659
  this.schedulePendingChange(collection, id, newData, 0, "insert");
1656
- this.inMemDb.insert(collection, this.stripLocalFields(newData));
1660
+ this._writeToInMemBatch(collection, [this.stripLocalFields(newData)], "upsert");
1657
1661
  return this.stripLocalFields(newData);
1658
1662
  }
1659
1663
  async deleteOne(collection, id) {
@@ -1668,7 +1672,7 @@ class SyncedDb {
1668
1672
  _lastUpdaterId: this.updaterId
1669
1673
  };
1670
1674
  this.schedulePendingChange(collection, id, deleteUpdate, 0, "deleteOne");
1671
- this.inMemDb.deleteOne(collection, id);
1675
+ this._writeToInMemBatch(collection, [{ _id: id }], "delete");
1672
1676
  return this.stripLocalFields(existing);
1673
1677
  }
1674
1678
  async deleteMany(collection, query) {
@@ -1702,7 +1706,7 @@ class SyncedDb {
1702
1706
  await this.dexieDb.addDirtyChangesBatch(collection, dirtyChangesBatch);
1703
1707
  }
1704
1708
  if (idsToDelete.length > 0) {
1705
- this.inMemDb.deleteManyByIds(collection, idsToDelete);
1709
+ this._writeToInMemBatch(collection, idsToDelete.map((id) => ({ _id: id })), "delete");
1706
1710
  }
1707
1711
  return idsToDelete.length;
1708
1712
  }
@@ -1717,7 +1721,7 @@ class SyncedDb {
1717
1721
  }
1718
1722
  await this.withRestTimeout(this.restInterface.deleteOne(collection, { _id: id }), "hardDeleteOne");
1719
1723
  await this.dexieDb.deleteOne(collection, id);
1720
- this.inMemDb.deleteOne(collection, id);
1724
+ this._writeToInMemBatch(collection, [{ _id: id }], "delete");
1721
1725
  return this.stripLocalFields(existing);
1722
1726
  }
1723
1727
  async hardDelete(collection, query) {
@@ -1750,7 +1754,7 @@ class SyncedDb {
1750
1754
  try {
1751
1755
  await this.withRestTimeout(this.restInterface.deleteOne(collection, { _id: item.id }), "hardDelete");
1752
1756
  await this.dexieDb.deleteOne(collection, item.id);
1753
- this.inMemDb.deleteOne(collection, item.id);
1757
+ this._writeToInMemBatch(collection, [{ _id: item.id }], "delete");
1754
1758
  results.push(true);
1755
1759
  } catch (err) {
1756
1760
  console.error(`Failed to hard delete ${String(item.id)}:`, err);
@@ -1970,7 +1974,7 @@ class SyncedDb {
1970
1974
  }
1971
1975
  }
1972
1976
  await this.dexieDb.deleteCollection(collection);
1973
- this.inMemDb.deleteCollection(collection);
1977
+ this._clearCollectionInMem(collection);
1974
1978
  await this.dexieDb.deleteSyncMeta(collection);
1975
1979
  await this.dexieDb.clearDirtyChanges(collection);
1976
1980
  this.syncMetaCache.delete(collection);
@@ -2005,7 +2009,7 @@ class SyncedDb {
2005
2009
  }
2006
2010
  for (const collectionName of collectionNames) {
2007
2011
  await this.dexieDb.deleteCollection(collectionName);
2008
- this.inMemDb.deleteCollection(collectionName);
2012
+ this._clearCollectionInMem(collectionName);
2009
2013
  await this.dexieDb.deleteSyncMeta(collectionName);
2010
2014
  await this.dexieDb.clearDirtyChanges(collectionName);
2011
2015
  }
@@ -2019,6 +2023,75 @@ class SyncedDb {
2019
2023
  stripLocalFields(item) {
2020
2024
  return item;
2021
2025
  }
2026
+ _writeToInMemBatch(collection, items, operation) {
2027
+ if (items.length === 0)
2028
+ return;
2029
+ const config = this.collections.get(collection);
2030
+ if (operation === "upsert") {
2031
+ this.inMemDb.saveMany(collection, items);
2032
+ if (this.useObjectMetadata && config?.hasMetadata) {
2033
+ const ids = items.map((item) => item._id);
2034
+ let metadatas;
2035
+ if (config.onObjectsUpdated) {
2036
+ metadatas = config.onObjectsUpdated(items);
2037
+ } else if (config.onObjectUpdated) {
2038
+ metadatas = items.map((item) => config.onObjectUpdated(item));
2039
+ } else {
2040
+ return;
2041
+ }
2042
+ this._setObjectsMetadataInternal(collection, ids, metadatas);
2043
+ }
2044
+ } else if (operation === "delete") {
2045
+ const ids = items.map((item) => item._id);
2046
+ this.inMemDb.deleteManyByIds(collection, ids);
2047
+ if (this.useObjectMetadata && config?.hasMetadata) {
2048
+ this._deleteObjectsMetadataInternal(collection, ids);
2049
+ }
2050
+ }
2051
+ }
2052
+ _initCollectionInMem(collection, items) {
2053
+ this.inMemDb.saveCollection(collection, items);
2054
+ if (this.useObjectMetadata && items.length > 0) {
2055
+ const config = this.collections.get(collection);
2056
+ if (config?.hasMetadata) {
2057
+ const ids = items.map((item) => item._id);
2058
+ let metadatas;
2059
+ if (config.onObjectsUpdated) {
2060
+ metadatas = config.onObjectsUpdated(items);
2061
+ } else if (config.onObjectUpdated) {
2062
+ metadatas = items.map((item) => config.onObjectUpdated(item));
2063
+ } else {
2064
+ return;
2065
+ }
2066
+ this._setObjectsMetadataInternal(collection, ids, metadatas);
2067
+ }
2068
+ }
2069
+ }
2070
+ _clearCollectionInMem(collection) {
2071
+ this.inMemDb.deleteCollection(collection);
2072
+ if (this.useObjectMetadata) {
2073
+ this._metadata[collection]?.clear();
2074
+ delete this._metadata[collection];
2075
+ }
2076
+ }
2077
+ _setObjectsMetadataInternal(collection, ids, metadatas) {
2078
+ let map = this._metadata[collection];
2079
+ if (!map) {
2080
+ map = new Map;
2081
+ this._metadata[collection] = map;
2082
+ }
2083
+ for (let i = 0;i < ids.length; i++) {
2084
+ map.set(String(ids[i]), metadatas[i]);
2085
+ }
2086
+ }
2087
+ _deleteObjectsMetadataInternal(collection, ids) {
2088
+ const map = this._metadata[collection];
2089
+ if (map) {
2090
+ for (const id of ids) {
2091
+ map.delete(String(id));
2092
+ }
2093
+ }
2094
+ }
2022
2095
  getPendingKey(collection, id) {
2023
2096
  return `${collection}:${String(id)}`;
2024
2097
  }
@@ -2232,6 +2305,7 @@ class SyncedDb {
2232
2305
  const idsToUpdate = insertedAndUpdated.map((e) => e._id);
2233
2306
  const existingItems = await this.dexieDb.getByIds(collection, idsToUpdate);
2234
2307
  const dexieSaveBatch = [];
2308
+ const inMemUpdateBatch = [];
2235
2309
  for (let i = 0;i < insertedAndUpdated.length; i++) {
2236
2310
  const entity = insertedAndUpdated[i];
2237
2311
  const existing = existingItems[i];
@@ -2242,20 +2316,27 @@ class SyncedDb {
2242
2316
  _ts: entity._ts
2243
2317
  });
2244
2318
  }
2245
- this.inMemDb.save(collection, entity._id, {
2246
- _rev: entity._rev,
2247
- _ts: entity._ts
2248
- });
2319
+ const inMemItem = this.inMemDb.getById(collection, entity._id);
2320
+ if (inMemItem) {
2321
+ inMemUpdateBatch.push({
2322
+ ...inMemItem,
2323
+ _rev: entity._rev,
2324
+ _ts: entity._ts
2325
+ });
2326
+ }
2249
2327
  }
2250
2328
  if (dexieSaveBatch.length > 0) {
2251
2329
  await this.dexieDb.saveMany(collection, dexieSaveBatch);
2252
2330
  }
2331
+ if (inMemUpdateBatch.length > 0) {
2332
+ this._writeToInMemBatch(collection, inMemUpdateBatch, "upsert");
2333
+ }
2253
2334
  sentCount += insertedAndUpdated.length;
2254
2335
  }
2255
2336
  if (deleted.length > 0) {
2256
2337
  const deleteIds = deleted.map((e) => e._id);
2257
2338
  await this.dexieDb.deleteMany(collection, deleteIds);
2258
- this.inMemDb.deleteManyByIds(collection, deleteIds);
2339
+ this._writeToInMemBatch(collection, deleteIds.map((id) => ({ _id: id })), "delete");
2259
2340
  sentCount += deleted.length;
2260
2341
  }
2261
2342
  const allItems = [...inserted, ...updated, ...deleted];
@@ -2380,10 +2461,10 @@ class SyncedDb {
2380
2461
  await this.dexieDb.saveMany(collectionName, dexieBatch);
2381
2462
  }
2382
2463
  if (inMemSaveBatch.length > 0) {
2383
- this.inMemDb.saveMany(collectionName, inMemSaveBatch);
2464
+ this._writeToInMemBatch(collectionName, inMemSaveBatch, "upsert");
2384
2465
  }
2385
2466
  if (inMemDeleteIds.length > 0) {
2386
- this.inMemDb.deleteManyByIds(collectionName, inMemDeleteIds);
2467
+ this._writeToInMemBatch(collectionName, inMemDeleteIds.map((id) => ({ _id: id })), "delete");
2387
2468
  }
2388
2469
  if (maxTs) {
2389
2470
  await this.dexieDb.setSyncMeta(collectionName, maxTs);
@@ -2517,18 +2598,28 @@ class SyncedDb {
2517
2598
  if (dexieSaveBatch.length > 0) {
2518
2599
  await this.dexieDb.saveMany(collection, dexieSaveBatch);
2519
2600
  }
2520
- for (const item of inMemSaveIds) {
2521
- this.inMemDb.save(collection, item.id, {
2522
- _rev: item.rev,
2523
- _ts: item.ts
2524
- });
2601
+ if (inMemSaveIds.length > 0) {
2602
+ const inMemUpdateBatch = [];
2603
+ for (const item of inMemSaveIds) {
2604
+ const inMemItem = this.inMemDb.getById(collection, item.id);
2605
+ if (inMemItem) {
2606
+ inMemUpdateBatch.push({
2607
+ ...inMemItem,
2608
+ _rev: item.rev,
2609
+ _ts: item.ts
2610
+ });
2611
+ }
2612
+ }
2613
+ if (inMemUpdateBatch.length > 0) {
2614
+ this._writeToInMemBatch(collection, inMemUpdateBatch, "upsert");
2615
+ }
2525
2616
  }
2526
2617
  sentCount += insertedAndUpdated.length;
2527
2618
  }
2528
2619
  if (deleted.length > 0) {
2529
2620
  const deleteIds = deleted.map((e) => e._id);
2530
2621
  await this.dexieDb.deleteMany(collection, deleteIds);
2531
- this.inMemDb.deleteManyByIds(collection, deleteIds);
2622
+ this._writeToInMemBatch(collection, deleteIds.map((id) => ({ _id: id })), "delete");
2532
2623
  sentCount += deleted.length;
2533
2624
  }
2534
2625
  const allItems = [...inserted, ...updated, ...deleted];
@@ -2658,17 +2749,30 @@ class SyncedDb {
2658
2749
  }
2659
2750
  try {
2660
2751
  const items = await this.dexieDb.getByIds(collection, ids);
2752
+ const upsertBatch = [];
2753
+ const deleteBatch = [];
2661
2754
  let newItemsCount = 0;
2662
- for (const item of items) {
2663
- if (!item)
2755
+ for (let i = 0;i < ids.length; i++) {
2756
+ const item = items[i];
2757
+ const id = ids[i];
2758
+ if (!item) {
2759
+ deleteBatch.push({ _id: id });
2760
+ newItemsCount++;
2664
2761
  continue;
2762
+ }
2665
2763
  if (item._deleted) {
2666
- this.inMemDb.deleteOne(collection, item._id);
2764
+ deleteBatch.push({ _id: item._id });
2667
2765
  } else {
2668
- this.inMemDb.save(collection, item._id, this.stripLocalFields(item));
2766
+ upsertBatch.push(this.stripLocalFields(item));
2669
2767
  }
2670
2768
  newItemsCount++;
2671
2769
  }
2770
+ if (upsertBatch.length > 0) {
2771
+ this._writeToInMemBatch(collection, upsertBatch, "upsert");
2772
+ }
2773
+ if (deleteBatch.length > 0) {
2774
+ this._writeToInMemBatch(collection, deleteBatch, "delete");
2775
+ }
2672
2776
  if (this.onCrossTabSync && newItemsCount > 0) {
2673
2777
  try {
2674
2778
  this.onCrossTabSync(collection, newItemsCount);
@@ -2786,13 +2890,13 @@ class SyncedDb {
2786
2890
  if (!serverItem._deleted) {
2787
2891
  const memItem = this.inMemDb.getById(collectionName, serverItem._id);
2788
2892
  if (!memItem) {
2789
- this.inMemDb.insert(collectionName, this.stripLocalFields(serverItem));
2893
+ this._writeToInMemBatch(collectionName, [this.stripLocalFields(serverItem)], "upsert");
2790
2894
  }
2791
2895
  }
2792
2896
  } else {
2793
2897
  await this.dexieDb.insert(collectionName, serverItem);
2794
2898
  if (!serverItem._deleted) {
2795
- this.inMemDb.insert(collectionName, this.stripLocalFields(serverItem));
2899
+ this._writeToInMemBatch(collectionName, [this.stripLocalFields(serverItem)], "upsert");
2796
2900
  }
2797
2901
  }
2798
2902
  }
@@ -2816,7 +2920,7 @@ class SyncedDb {
2816
2920
  if (currentMemItem) {
2817
2921
  const merged = this.mergeLocalWithDelta(currentMemItem, serverDelta);
2818
2922
  if (!merged._deleted) {
2819
- this.inMemDb.save(collectionName, serverDelta._id, this.stripLocalFields(merged));
2923
+ this._writeToInMemBatch(collectionName, [this.stripLocalFields(merged)], "upsert");
2820
2924
  }
2821
2925
  pendingChange.data = {
2822
2926
  ...pendingChange.data,
@@ -2833,7 +2937,7 @@ class SyncedDb {
2833
2937
  await this.dexieDb.save(collectionName, serverDelta._id, merged);
2834
2938
  }
2835
2939
  if (!merged._deleted) {
2836
- this.inMemDb.save(collectionName, serverDelta._id, this.stripLocalFields(merged));
2940
+ this._writeToInMemBatch(collectionName, [this.stripLocalFields(merged)], "upsert");
2837
2941
  }
2838
2942
  } else {
2839
2943
  if (!metaChanged) {
@@ -2842,9 +2946,9 @@ class SyncedDb {
2842
2946
  const merged = this.mergeLocalWithDelta(localItem, serverDelta);
2843
2947
  await this.dexieDb.save(collectionName, serverDelta._id, merged);
2844
2948
  if (!merged._deleted) {
2845
- this.inMemDb.save(collectionName, serverDelta._id, this.stripLocalFields(merged));
2949
+ this._writeToInMemBatch(collectionName, [this.stripLocalFields(merged)], "upsert");
2846
2950
  } else {
2847
- this.inMemDb.deleteOne(collectionName, serverDelta._id);
2951
+ this._writeToInMemBatch(collectionName, [{ _id: serverDelta._id }], "delete");
2848
2952
  }
2849
2953
  }
2850
2954
  }
@@ -2879,7 +2983,48 @@ class SyncedDb {
2879
2983
  } else {
2880
2984
  await this.dexieDb.deleteOne(collectionName, id);
2881
2985
  }
2882
- this.inMemDb.deleteOne(collectionName, id);
2986
+ this._writeToInMemBatch(collectionName, [{ _id: id }], "delete");
2987
+ }
2988
+ getObjectMetadata(collection, _id) {
2989
+ return this._metadata[collection]?.get(String(_id));
2990
+ }
2991
+ getObjectsMetadata(collection, _ids) {
2992
+ const map = this._metadata[collection];
2993
+ if (!map) {
2994
+ return _ids.map(() => {
2995
+ return;
2996
+ });
2997
+ }
2998
+ return _ids.map((_id) => map.get(String(_id)));
2999
+ }
3000
+ setObjectMetadata(collection, _id, metadata) {
3001
+ let map = this._metadata[collection];
3002
+ if (!map) {
3003
+ map = new Map;
3004
+ this._metadata[collection] = map;
3005
+ }
3006
+ map.set(String(_id), metadata);
3007
+ }
3008
+ setObjectsMetadata(collection, _ids, metadatas) {
3009
+ let map = this._metadata[collection];
3010
+ if (!map) {
3011
+ map = new Map;
3012
+ this._metadata[collection] = map;
3013
+ }
3014
+ for (let i = 0;i < _ids.length; i++) {
3015
+ map.set(String(_ids[i]), metadatas[i]);
3016
+ }
3017
+ }
3018
+ deleteObjectMetadata(collection, _id) {
3019
+ this._metadata[collection]?.delete(String(_id));
3020
+ }
3021
+ deleteObjectsMetadata(collection, _ids) {
3022
+ const map = this._metadata[collection];
3023
+ if (map) {
3024
+ for (const _id of _ids) {
3025
+ map.delete(String(_id));
3026
+ }
3027
+ }
2883
3028
  }
2884
3029
  }
2885
3030
  // src/db/DexieDb.ts
@@ -81,6 +81,10 @@ export declare class SyncedDb implements I_SyncedDb {
81
81
  private releasingLeadershipDueToVisibility;
82
82
  /** Visibility change handler reference for cleanup */
83
83
  private visibilityChangeHandler?;
84
+ /** Whether object metadata feature is enabled */
85
+ private useObjectMetadata;
86
+ /** In-memory metadata store: collection -> (_id -> metadata) */
87
+ private _metadata;
84
88
  constructor(config: SyncedDbConfig);
85
89
  /** Get the unique instance ID for this SyncedDb */
86
90
  getInstanceId(): string;
@@ -181,6 +185,27 @@ export declare class SyncedDb implements I_SyncedDb {
181
185
  dropDatabase(force?: boolean): Promise<void>;
182
186
  private assertCollection;
183
187
  private stripLocalFields;
188
+ /**
189
+ * Centralized method for ALL in-mem writes.
190
+ * Handles metadata callbacks automatically when useObjectMetadata is enabled.
191
+ *
192
+ * @param collection - Collection name
193
+ * @param items - Objects to write (for upsert) or objects with _id (for delete)
194
+ * @param operation - 'upsert' to save/update, 'delete' to remove
195
+ */
196
+ private _writeToInMemBatch;
197
+ /**
198
+ * Initialize a collection in in-mem from Dexie data.
199
+ * Called during init().
200
+ */
201
+ private _initCollectionInMem;
202
+ /**
203
+ * Clear all data and metadata for a collection.
204
+ * Used by dropCollection().
205
+ */
206
+ private _clearCollectionInMem;
207
+ private _setObjectsMetadataInternal;
208
+ private _deleteObjectsMetadataInternal;
184
209
  private getPendingKey;
185
210
  private schedulePendingChange;
186
211
  private executePendingChange;
@@ -262,4 +287,10 @@ export declare class SyncedDb implements I_SyncedDb {
262
287
  */
263
288
  private mergeLocalWithDelta;
264
289
  private handleServerItemDelete;
290
+ getObjectMetadata<M>(collection: string, _id: Id): M | undefined;
291
+ getObjectsMetadata<M>(collection: string, _ids: Id[]): (M | undefined)[];
292
+ setObjectMetadata<M>(collection: string, _id: Id, metadata: M): void;
293
+ setObjectsMetadata<M>(collection: string, _ids: Id[], metadatas: M[]): void;
294
+ deleteObjectMetadata(collection: string, _id: Id): void;
295
+ deleteObjectsMetadata(collection: string, _ids: Id[]): void;
265
296
  }
@@ -201,13 +201,19 @@ export interface SyncInfo {
201
201
  /**
202
202
  * Konfiguracija za posamezno kolekcijo
203
203
  */
204
- export interface CollectionConfig<T extends DbEntity = any> {
204
+ export interface CollectionConfig<T extends DbEntity = any, M = any> {
205
205
  /** Ime kolekcije */
206
206
  name: string;
207
207
  /** Opcijski filter za velike tabele - omeji obseg sinhronizacije */
208
208
  query?: QuerySpec<any>;
209
209
  /** Opcijska funkcija za razreševanje konfliktov */
210
210
  resolveSyncConflict?(local: T, external: T): T;
211
+ /** Whether this collection uses in-memory metadata */
212
+ hasMetadata?: boolean;
213
+ /** Callback called when a single object is written to in-mem. Returns metadata to store. */
214
+ onObjectUpdated?(object: T): M;
215
+ /** Callback called when multiple objects are written to in-mem. Returns metadata array (same order as input). */
216
+ onObjectsUpdated?(objects: T[]): M[];
211
217
  }
212
218
  /**
213
219
  * Konfiguracija za SyncedDb - dependencies so podani kot parametri (DI)
@@ -284,6 +290,12 @@ export interface SyncedDbConfig {
284
290
  * Client code can use this to show warnings, log telemetry, or adjust behavior.
285
291
  */
286
292
  onInfrastructureError?: (info: InfrastructureErrorInfo) => void;
293
+ /**
294
+ * Enable in-memory object metadata feature.
295
+ * When true, collections with hasMetadata=true will have their metadata callbacks invoked
296
+ * whenever objects are written to in-mem. Default: false.
297
+ */
298
+ useObjectMetadata?: boolean;
287
299
  }
288
300
  /**
289
301
  * Glavna logika za sinhronizirano bazo podatkov
@@ -434,4 +446,46 @@ export interface I_SyncedDb {
434
446
  * @returns true if this instance holds the leader lock
435
447
  */
436
448
  isLeaderTab(): boolean;
449
+ /**
450
+ * Get metadata for a single object.
451
+ * @param collection Collection name
452
+ * @param _id Object ID
453
+ * @returns Metadata for the object, or undefined if not found
454
+ */
455
+ getObjectMetadata<M>(collection: string, _id: Id): M | undefined;
456
+ /**
457
+ * Get metadata for multiple objects.
458
+ * @param collection Collection name
459
+ * @param _ids Object IDs
460
+ * @returns Array of metadata in same order as input _ids (undefined for missing)
461
+ */
462
+ getObjectsMetadata<M>(collection: string, _ids: Id[]): (M | undefined)[];
463
+ /**
464
+ * Manually set metadata for a single object.
465
+ * Rarely needed - metadata callbacks handle this automatically.
466
+ * @param collection Collection name
467
+ * @param _id Object ID
468
+ * @param metadata Metadata to store
469
+ */
470
+ setObjectMetadata<M>(collection: string, _id: Id, metadata: M): void;
471
+ /**
472
+ * Manually set metadata for multiple objects.
473
+ * Rarely needed - metadata callbacks handle this automatically.
474
+ * @param collection Collection name
475
+ * @param _ids Object IDs
476
+ * @param metadatas Metadata array (same order as _ids)
477
+ */
478
+ setObjectsMetadata<M>(collection: string, _ids: Id[], metadatas: M[]): void;
479
+ /**
480
+ * Delete metadata for a single object.
481
+ * @param collection Collection name
482
+ * @param _id Object ID
483
+ */
484
+ deleteObjectMetadata(collection: string, _id: Id): void;
485
+ /**
486
+ * Delete metadata for multiple objects.
487
+ * @param collection Collection name
488
+ * @param _ids Object IDs
489
+ */
490
+ deleteObjectsMetadata(collection: string, _ids: Id[]): void;
437
491
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cry-synced-db-client",
3
- "version": "0.1.50",
3
+ "version": "0.1.51",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",