@signaldb/core 2.0.0-beta.21 → 2.0.0-beta.22

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 (46) hide show
  1. package/README.md +3 -3
  2. package/dist/.vite/manifest.json +61 -59
  3. package/dist/AsyncDataAdapter.d.ts +15 -2
  4. package/dist/AutoFetchDataAdapter.d.ts +13 -2
  5. package/dist/Collection/Observer.d.ts +1 -1
  6. package/dist/Collection/index.d.ts +11 -12
  7. package/dist/DataAdapter.d.ts +19 -3
  8. package/dist/WorkerDataAdapterHost.d.ts +19 -6
  9. package/dist/index.cjs.js +4 -4
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.mjs +4 -4
  12. package/dist/index12.cjs.js +1 -1
  13. package/dist/index12.mjs +1 -1
  14. package/dist/index15.cjs.js +6 -2
  15. package/dist/index15.mjs +6 -2
  16. package/dist/index17.cjs.js +4 -2
  17. package/dist/index17.mjs +4 -3
  18. package/dist/index18.cjs.js +1 -0
  19. package/dist/index18.mjs +1 -1
  20. package/dist/index28.cjs.js +15 -5
  21. package/dist/index28.mjs +15 -5
  22. package/dist/index29.cjs.js +29 -16
  23. package/dist/index29.mjs +29 -16
  24. package/dist/index33.cjs.js +17 -49
  25. package/dist/index33.mjs +17 -49
  26. package/dist/index34.cjs.js +45 -445
  27. package/dist/index34.mjs +45 -445
  28. package/dist/index35.cjs.js +132 -65
  29. package/dist/index35.mjs +132 -65
  30. package/dist/index36.cjs.js +385 -531
  31. package/dist/index36.mjs +386 -533
  32. package/dist/index37.cjs.js +68 -17
  33. package/dist/index37.mjs +68 -17
  34. package/dist/index38.cjs.js +536 -319
  35. package/dist/index38.mjs +538 -321
  36. package/dist/index39.cjs.js +301 -466
  37. package/dist/index39.mjs +301 -466
  38. package/dist/index40.cjs.js +484 -0
  39. package/dist/index40.mjs +484 -0
  40. package/dist/index5.cjs.js +3 -3
  41. package/dist/index5.mjs +3 -3
  42. package/dist/index6.cjs.js +1 -0
  43. package/dist/index6.mjs +1 -1
  44. package/dist/types/StorageAdapter.d.ts +80 -0
  45. package/dist/utils/executeStorageQuery.d.ts +28 -0
  46. package/package.json +1 -1
@@ -56,7 +56,7 @@ var DefaultDataAdapter = class {
56
56
  await this.fetchItemsFromStorage(collection);
57
57
  }).catch((error) => {
58
58
  if (!this.options.onError) {
59
- console.error(`Error during data persistence operation in collection ${collection.name}`, error);
59
+ console.error(`Error during storage operation in collection ${collection.name}`, error);
60
60
  return;
61
61
  }
62
62
  this.options.onError(collection.name, error instanceof Error ? error : new Error(error));
@@ -112,7 +112,8 @@ var DefaultDataAdapter = class {
112
112
  const { sort, skip, limit, fields } = options || {};
113
113
  const sorted = sort ? require_sortItems.default(items, sort) : items;
114
114
  const skipped = skip ? sorted.slice(skip) : sorted;
115
- return require_projectItems.default(limit ? skipped.slice(0, limit) : skipped, fields);
115
+ const limited = limit ? skipped.slice(0, limit) : skipped;
116
+ return require_projectItems.default(limited, fields);
116
117
  }
117
118
  flushQueuedQueryUpdates(collection) {
118
119
  if (!this.queuedQueryUpdates.get(collection.name)) return;
@@ -204,7 +205,10 @@ var DefaultDataAdapter = class {
204
205
  modified: [modifiedItem],
205
206
  removed: []
206
207
  });
207
- return [modifiedItem];
208
+ return {
209
+ items: [modifiedItem],
210
+ previousItems: [item]
211
+ };
208
212
  },
209
213
  updateMany: async (selector, modifier) => {
210
214
  const { $setOnInsert, ...restModifier } = modifier;
@@ -228,7 +232,10 @@ var DefaultDataAdapter = class {
228
232
  modified: changedItems,
229
233
  removed: []
230
234
  });
231
- return changedItems;
235
+ return {
236
+ items: changedItems,
237
+ previousItems: items
238
+ };
232
239
  },
233
240
  replaceOne: async (selector, replacement) => {
234
241
  const item = this.getItem(collection, selector);
@@ -249,7 +256,10 @@ var DefaultDataAdapter = class {
249
256
  modified: [modifiedItem],
250
257
  removed: []
251
258
  });
252
- return [modifiedItem];
259
+ return {
260
+ items: [modifiedItem],
261
+ previousItems: [item]
262
+ };
253
263
  },
254
264
  removeOne: async (selector) => {
255
265
  const item = this.getItem(collection, selector);
package/dist/index28.mjs CHANGED
@@ -56,7 +56,7 @@ var DefaultDataAdapter = class {
56
56
  await this.fetchItemsFromStorage(collection);
57
57
  }).catch((error) => {
58
58
  if (!this.options.onError) {
59
- console.error(`Error during data persistence operation in collection ${collection.name}`, error);
59
+ console.error(`Error during storage operation in collection ${collection.name}`, error);
60
60
  return;
61
61
  }
62
62
  this.options.onError(collection.name, error instanceof Error ? error : new Error(error));
@@ -112,7 +112,8 @@ var DefaultDataAdapter = class {
112
112
  const { sort, skip, limit, fields } = options || {};
113
113
  const sorted = sort ? sortItems(items, sort) : items;
114
114
  const skipped = skip ? sorted.slice(skip) : sorted;
115
- return projectItems(limit ? skipped.slice(0, limit) : skipped, fields);
115
+ const limited = limit ? skipped.slice(0, limit) : skipped;
116
+ return projectItems(limited, fields);
116
117
  }
117
118
  flushQueuedQueryUpdates(collection) {
118
119
  if (!this.queuedQueryUpdates.get(collection.name)) return;
@@ -204,7 +205,10 @@ var DefaultDataAdapter = class {
204
205
  modified: [modifiedItem],
205
206
  removed: []
206
207
  });
207
- return [modifiedItem];
208
+ return {
209
+ items: [modifiedItem],
210
+ previousItems: [item]
211
+ };
208
212
  },
209
213
  updateMany: async (selector, modifier) => {
210
214
  const { $setOnInsert, ...restModifier } = modifier;
@@ -228,7 +232,10 @@ var DefaultDataAdapter = class {
228
232
  modified: changedItems,
229
233
  removed: []
230
234
  });
231
- return changedItems;
235
+ return {
236
+ items: changedItems,
237
+ previousItems: items
238
+ };
232
239
  },
233
240
  replaceOne: async (selector, replacement) => {
234
241
  const item = this.getItem(collection, selector);
@@ -249,7 +256,10 @@ var DefaultDataAdapter = class {
249
256
  modified: [modifiedItem],
250
257
  removed: []
251
258
  });
252
- return [modifiedItem];
259
+ return {
260
+ items: [modifiedItem],
261
+ previousItems: [item]
262
+ };
253
263
  },
254
264
  removeOne: async (selector) => {
255
265
  const item = this.getItem(collection, selector);
@@ -9,6 +9,20 @@ const require_queryId = require("./index26.cjs.js");
9
9
  const require_DefaultDataAdapter = require("./index28.cjs.js");
10
10
  //#region src/Collection/index.ts
11
11
  /**
12
+ * Splits what a backend returned from a write into the changed items and their previous state.
13
+ * @param result - What the backend's write method returned.
14
+ * @returns The changed items, and what each of them was before the write. An adapter that cannot
15
+ * report the previous state yields an empty list, and the `'changed'` event omits its third
16
+ * argument.
17
+ */
18
+ function splitWriteResult(result) {
19
+ if (Array.isArray(result)) return {
20
+ items: result,
21
+ previousItems: []
22
+ };
23
+ return result;
24
+ }
25
+ /**
12
26
  * Represents a collection of data items with support for in-memory operations,
13
27
  * persistence, reactivity, and event-based notifications. The collection provides
14
28
  * CRUD operations, observer patterns, and batch operations.
@@ -153,7 +167,7 @@ var Collection = class Collection extends require_EventEmitter.default {
153
167
  /**
154
168
  * Checks whether the collection is currently performing a pull operation
155
169
  * ⚡️ this function is reactive!
156
- * (loading data from the persistence adapter).
170
+ * (loading data from storage).
157
171
  * @returns A boolean indicating if the collection is in the process of pulling data.
158
172
  */
159
173
  isPulling() {
@@ -162,7 +176,7 @@ var Collection = class Collection extends require_EventEmitter.default {
162
176
  /**
163
177
  * Checks whether the collection is currently performing a push operation
164
178
  * ⚡️ this function is reactive!
165
- * (saving data to the persistence adapter).
179
+ * (saving data to storage).
166
180
  * @returns A boolean indicating if the collection is in the process of pushing data.
167
181
  */
168
182
  isPushing() {
@@ -202,17 +216,16 @@ var Collection = class Collection extends require_EventEmitter.default {
202
216
  this.fieldTracking = enable;
203
217
  }
204
218
  /**
205
- * Resolves when the persistence adapter finished initializing
219
+ * Resolves when the storage adapter finished initializing
206
220
  * and the collection is ready to be used.
207
221
  * @returns A promise that resolves when the collection is ready.
208
222
  * @example
209
223
  * ```ts
210
- * const collection = new Collection({
211
- * persistence: // ...
212
- * })
213
- * await collection.isReady()
224
+ * const collection = new Collection('items', dataAdapter)
225
+ * await collection.ready()
214
226
  *
215
- * collection.insert({ name: 'Item 1' })
227
+ * await collection.insert({ name: 'Item 1' })
228
+ * ```
216
229
  */
217
230
  async ready() {
218
231
  return this.backend.isReady();
@@ -281,7 +294,7 @@ var Collection = class Collection extends require_EventEmitter.default {
281
294
  return this.queryListenersMap.get(id) ?? 0;
282
295
  }
283
296
  /**
284
- * Disposes the collection, unregisters persistence adapters, clears memory, and
297
+ * Disposes the collection, unregisters storage adapters, clears memory, and
285
298
  * cleans up all resources used by the collection.
286
299
  * @returns A promise that resolves when the collection is disposed.
287
300
  */
@@ -480,7 +493,7 @@ var Collection = class Collection extends require_EventEmitter.default {
480
493
  const item = await this.getItem(selector, { async: true });
481
494
  if (item != null) this.emit("validate", require_modify.default(require_deepClone.default(item), restModifier));
482
495
  }
483
- const changes = await this.withPushState(() => this.backend.updateOne(selector, modifier));
496
+ const { items: changes, previousItems } = splitWriteResult(await this.withPushState(() => this.backend.updateOne(selector, modifier)));
484
497
  if (changes.length === 0) {
485
498
  if (!options?.upsert) return 0;
486
499
  const newItem = require_modify.default({}, {
@@ -493,7 +506,7 @@ var Collection = class Collection extends require_EventEmitter.default {
493
506
  await this.insert(newItem);
494
507
  return 1;
495
508
  }
496
- changes.forEach((item) => this.emit("changed", item, restModifier));
509
+ changes.forEach((item, index) => this.emit("changed", item, restModifier, previousItems[index]));
497
510
  this.emit("updateOne", selector, modifier);
498
511
  this.executeInDebugMode((callstack) => this.emit("_debug.updateOne", callstack, selector, modifier));
499
512
  return changes.length;
@@ -515,7 +528,7 @@ var Collection = class Collection extends require_EventEmitter.default {
515
528
  if (this.listenerCount("validate") > 0) (await this.getItems(selector, { async: true })).forEach((item) => {
516
529
  this.emit("validate", require_modify.default(require_deepClone.default(item), restModifier));
517
530
  });
518
- const changes = await this.withPushState(() => this.backend.updateMany(selector, modifier));
531
+ const { items: changes, previousItems } = splitWriteResult(await this.withPushState(() => this.backend.updateMany(selector, modifier)));
519
532
  if (changes.length === 0) {
520
533
  if (!options?.upsert) return 0;
521
534
  const newItem = require_modify.default({}, {
@@ -528,8 +541,8 @@ var Collection = class Collection extends require_EventEmitter.default {
528
541
  await this.insert(newItem);
529
542
  return 1;
530
543
  }
531
- changes.forEach((item) => {
532
- this.emit("changed", item, restModifier);
544
+ changes.forEach((item, index) => {
545
+ this.emit("changed", item, restModifier, previousItems[index]);
533
546
  });
534
547
  this.emit("updateMany", selector, modifier);
535
548
  this.executeInDebugMode((callstack) => this.emit("_debug.updateMany", callstack, selector, modifier));
@@ -554,13 +567,13 @@ var Collection = class Collection extends require_EventEmitter.default {
554
567
  ...replacement
555
568
  });
556
569
  }
557
- const changes = await this.withPushState(() => this.backend.replaceOne(selector, replacement));
570
+ const { items: changes, previousItems } = splitWriteResult(await this.withPushState(() => this.backend.replaceOne(selector, replacement)));
558
571
  if (changes.length === 0) {
559
572
  if (!options?.upsert) return 0;
560
573
  await this.insert(replacement);
561
574
  return 1;
562
575
  }
563
- changes.forEach((item) => this.emit("changed", item, replacement));
576
+ changes.forEach((item, index) => this.emit("changed", item, replacement, previousItems[index]));
564
577
  this.emit("replaceOne", selector, replacement);
565
578
  this.executeInDebugMode((callstack) => this.emit("_debug.replaceOne", callstack, selector, replacement));
566
579
  return changes.length;
package/dist/index29.mjs CHANGED
@@ -9,6 +9,20 @@ import queryId from "./index26.mjs";
9
9
  import DefaultDataAdapter from "./index28.mjs";
10
10
  //#region src/Collection/index.ts
11
11
  /**
12
+ * Splits what a backend returned from a write into the changed items and their previous state.
13
+ * @param result - What the backend's write method returned.
14
+ * @returns The changed items, and what each of them was before the write. An adapter that cannot
15
+ * report the previous state yields an empty list, and the `'changed'` event omits its third
16
+ * argument.
17
+ */
18
+ function splitWriteResult(result) {
19
+ if (Array.isArray(result)) return {
20
+ items: result,
21
+ previousItems: []
22
+ };
23
+ return result;
24
+ }
25
+ /**
12
26
  * Represents a collection of data items with support for in-memory operations,
13
27
  * persistence, reactivity, and event-based notifications. The collection provides
14
28
  * CRUD operations, observer patterns, and batch operations.
@@ -153,7 +167,7 @@ var Collection = class Collection extends EventEmitter {
153
167
  /**
154
168
  * Checks whether the collection is currently performing a pull operation
155
169
  * ⚡️ this function is reactive!
156
- * (loading data from the persistence adapter).
170
+ * (loading data from storage).
157
171
  * @returns A boolean indicating if the collection is in the process of pulling data.
158
172
  */
159
173
  isPulling() {
@@ -162,7 +176,7 @@ var Collection = class Collection extends EventEmitter {
162
176
  /**
163
177
  * Checks whether the collection is currently performing a push operation
164
178
  * ⚡️ this function is reactive!
165
- * (saving data to the persistence adapter).
179
+ * (saving data to storage).
166
180
  * @returns A boolean indicating if the collection is in the process of pushing data.
167
181
  */
168
182
  isPushing() {
@@ -202,17 +216,16 @@ var Collection = class Collection extends EventEmitter {
202
216
  this.fieldTracking = enable;
203
217
  }
204
218
  /**
205
- * Resolves when the persistence adapter finished initializing
219
+ * Resolves when the storage adapter finished initializing
206
220
  * and the collection is ready to be used.
207
221
  * @returns A promise that resolves when the collection is ready.
208
222
  * @example
209
223
  * ```ts
210
- * const collection = new Collection({
211
- * persistence: // ...
212
- * })
213
- * await collection.isReady()
224
+ * const collection = new Collection('items', dataAdapter)
225
+ * await collection.ready()
214
226
  *
215
- * collection.insert({ name: 'Item 1' })
227
+ * await collection.insert({ name: 'Item 1' })
228
+ * ```
216
229
  */
217
230
  async ready() {
218
231
  return this.backend.isReady();
@@ -281,7 +294,7 @@ var Collection = class Collection extends EventEmitter {
281
294
  return this.queryListenersMap.get(id) ?? 0;
282
295
  }
283
296
  /**
284
- * Disposes the collection, unregisters persistence adapters, clears memory, and
297
+ * Disposes the collection, unregisters storage adapters, clears memory, and
285
298
  * cleans up all resources used by the collection.
286
299
  * @returns A promise that resolves when the collection is disposed.
287
300
  */
@@ -480,7 +493,7 @@ var Collection = class Collection extends EventEmitter {
480
493
  const item = await this.getItem(selector, { async: true });
481
494
  if (item != null) this.emit("validate", modify(deepClone(item), restModifier));
482
495
  }
483
- const changes = await this.withPushState(() => this.backend.updateOne(selector, modifier));
496
+ const { items: changes, previousItems } = splitWriteResult(await this.withPushState(() => this.backend.updateOne(selector, modifier)));
484
497
  if (changes.length === 0) {
485
498
  if (!options?.upsert) return 0;
486
499
  const newItem = modify({}, {
@@ -493,7 +506,7 @@ var Collection = class Collection extends EventEmitter {
493
506
  await this.insert(newItem);
494
507
  return 1;
495
508
  }
496
- changes.forEach((item) => this.emit("changed", item, restModifier));
509
+ changes.forEach((item, index) => this.emit("changed", item, restModifier, previousItems[index]));
497
510
  this.emit("updateOne", selector, modifier);
498
511
  this.executeInDebugMode((callstack) => this.emit("_debug.updateOne", callstack, selector, modifier));
499
512
  return changes.length;
@@ -515,7 +528,7 @@ var Collection = class Collection extends EventEmitter {
515
528
  if (this.listenerCount("validate") > 0) (await this.getItems(selector, { async: true })).forEach((item) => {
516
529
  this.emit("validate", modify(deepClone(item), restModifier));
517
530
  });
518
- const changes = await this.withPushState(() => this.backend.updateMany(selector, modifier));
531
+ const { items: changes, previousItems } = splitWriteResult(await this.withPushState(() => this.backend.updateMany(selector, modifier)));
519
532
  if (changes.length === 0) {
520
533
  if (!options?.upsert) return 0;
521
534
  const newItem = modify({}, {
@@ -528,8 +541,8 @@ var Collection = class Collection extends EventEmitter {
528
541
  await this.insert(newItem);
529
542
  return 1;
530
543
  }
531
- changes.forEach((item) => {
532
- this.emit("changed", item, restModifier);
544
+ changes.forEach((item, index) => {
545
+ this.emit("changed", item, restModifier, previousItems[index]);
533
546
  });
534
547
  this.emit("updateMany", selector, modifier);
535
548
  this.executeInDebugMode((callstack) => this.emit("_debug.updateMany", callstack, selector, modifier));
@@ -554,13 +567,13 @@ var Collection = class Collection extends EventEmitter {
554
567
  ...replacement
555
568
  });
556
569
  }
557
- const changes = await this.withPushState(() => this.backend.replaceOne(selector, replacement));
570
+ const { items: changes, previousItems } = splitWriteResult(await this.withPushState(() => this.backend.replaceOne(selector, replacement)));
558
571
  if (changes.length === 0) {
559
572
  if (!options?.upsert) return 0;
560
573
  await this.insert(replacement);
561
574
  return 1;
562
575
  }
563
- changes.forEach((item) => this.emit("changed", item, replacement));
576
+ changes.forEach((item, index) => this.emit("changed", item, replacement, previousItems[index]));
564
577
  this.emit("replaceOne", selector, replacement);
565
578
  this.executeInDebugMode((callstack) => this.emit("_debug.replaceOne", callstack, selector, replacement));
566
579
  return changes.length;
@@ -1,53 +1,21 @@
1
- const require_getMatchingKeys = require("./index14.cjs.js");
2
- //#region src/utils/storageIndexQuery.ts
1
+ //#region src/utils/compact.ts
3
2
  /**
4
- * Builds the index provider a data adapter uses to narrow a selector down through
5
- * a storage adapter's index.
6
- *
7
- * Every adapter that keeps its data in a `StorageAdapter` needs exactly this, and
8
- * each of them used to carry its own copy — three transcriptions of one set of
9
- * rules about null, `$exists`, inclusion and exclusion, which is how they drift
10
- * apart without anyone noticing. The index is keyed by `serializeValue(value)`,
11
- * which is what `getMatchingKeys` produces, so the two only agree while they stay
12
- * in one place.
13
- * @template T - The type of the items in the collection.
14
- * @template I - The type of the unique identifier for the items.
15
- * @param storage - The storage adapter holding the index.
16
- * @param field - The indexed field this provider answers for.
17
- * @returns A query function for `getIndexInfo`.
3
+ * Checks if a value is truthy.
4
+ * @template T - The type of the value.
5
+ * @param value - The value to check.
6
+ * @returns A boolean indicating if the value is truthy.
18
7
  */
19
- function storageIndexQuery(storage, field) {
20
- return async (flatSelector) => {
21
- if (!Object.hasOwnProperty.call(flatSelector, field)) return { matched: false };
22
- const index = await storage.readIndex(field);
23
- const fieldSelector = flatSelector[field];
24
- const filtersForNull = fieldSelector == null || fieldSelector.$exists === false;
25
- const keys = filtersForNull ? {
26
- include: null,
27
- exclude: [...index.keys()].filter((key) => key != null)
28
- } : require_getMatchingKeys.default(field, flatSelector);
29
- if (keys.include == null && keys.exclude == null) return { matched: false };
30
- let includedIds = [];
31
- if (keys.include == null) for (const set of index.values()) for (const id of set) includedIds.push(id);
32
- else for (const key of keys.include) {
33
- const idSet = index.get(key);
34
- if (idSet) for (const id of idSet) includedIds.push(id);
35
- }
36
- if (keys.exclude != null) {
37
- const excludedIds = /* @__PURE__ */ new Set();
38
- for (const key of keys.exclude) {
39
- const idSet = index.get(key);
40
- if (idSet) for (const id of idSet) excludedIds.add(id);
41
- }
42
- includedIds = includedIds.filter((id) => !excludedIds.has(id));
43
- }
44
- return {
45
- matched: true,
46
- ids: includedIds,
47
- fields: [field],
48
- keepSelector: filtersForNull
49
- };
50
- };
8
+ function truthy(value) {
9
+ return !!value;
10
+ }
11
+ /**
12
+ * Filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) from an array.
13
+ * @template T - The type of the elements in the array.
14
+ * @param array - The array to filter.
15
+ * @returns A new array containing only the truthy values from the input array.
16
+ */
17
+ function compact(array) {
18
+ return array.filter(truthy);
51
19
  }
52
20
  //#endregion
53
- exports.default = storageIndexQuery;
21
+ exports.default = compact;
package/dist/index33.mjs CHANGED
@@ -1,53 +1,21 @@
1
- import getMatchingKeys from "./index14.mjs";
2
- //#region src/utils/storageIndexQuery.ts
1
+ //#region src/utils/compact.ts
3
2
  /**
4
- * Builds the index provider a data adapter uses to narrow a selector down through
5
- * a storage adapter's index.
6
- *
7
- * Every adapter that keeps its data in a `StorageAdapter` needs exactly this, and
8
- * each of them used to carry its own copy — three transcriptions of one set of
9
- * rules about null, `$exists`, inclusion and exclusion, which is how they drift
10
- * apart without anyone noticing. The index is keyed by `serializeValue(value)`,
11
- * which is what `getMatchingKeys` produces, so the two only agree while they stay
12
- * in one place.
13
- * @template T - The type of the items in the collection.
14
- * @template I - The type of the unique identifier for the items.
15
- * @param storage - The storage adapter holding the index.
16
- * @param field - The indexed field this provider answers for.
17
- * @returns A query function for `getIndexInfo`.
3
+ * Checks if a value is truthy.
4
+ * @template T - The type of the value.
5
+ * @param value - The value to check.
6
+ * @returns A boolean indicating if the value is truthy.
18
7
  */
19
- function storageIndexQuery(storage, field) {
20
- return async (flatSelector) => {
21
- if (!Object.hasOwnProperty.call(flatSelector, field)) return { matched: false };
22
- const index = await storage.readIndex(field);
23
- const fieldSelector = flatSelector[field];
24
- const filtersForNull = fieldSelector == null || fieldSelector.$exists === false;
25
- const keys = filtersForNull ? {
26
- include: null,
27
- exclude: [...index.keys()].filter((key) => key != null)
28
- } : getMatchingKeys(field, flatSelector);
29
- if (keys.include == null && keys.exclude == null) return { matched: false };
30
- let includedIds = [];
31
- if (keys.include == null) for (const set of index.values()) for (const id of set) includedIds.push(id);
32
- else for (const key of keys.include) {
33
- const idSet = index.get(key);
34
- if (idSet) for (const id of idSet) includedIds.push(id);
35
- }
36
- if (keys.exclude != null) {
37
- const excludedIds = /* @__PURE__ */ new Set();
38
- for (const key of keys.exclude) {
39
- const idSet = index.get(key);
40
- if (idSet) for (const id of idSet) excludedIds.add(id);
41
- }
42
- includedIds = includedIds.filter((id) => !excludedIds.has(id));
43
- }
44
- return {
45
- matched: true,
46
- ids: includedIds,
47
- fields: [field],
48
- keepSelector: filtersForNull
49
- };
50
- };
8
+ function truthy(value) {
9
+ return !!value;
10
+ }
11
+ /**
12
+ * Filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) from an array.
13
+ * @template T - The type of the elements in the array.
14
+ * @param array - The array to filter.
15
+ * @returns A new array containing only the truthy values from the input array.
16
+ */
17
+ function compact(array) {
18
+ return array.filter(truthy);
51
19
  }
52
20
  //#endregion
53
- export { storageIndexQuery as default };
21
+ export { compact as default };