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

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 (145) hide show
  1. package/dist/.vite/manifest.json +183 -80
  2. package/dist/AsyncDataAdapter.d.ts +53 -7
  3. package/dist/AutoFetchDataAdapter.d.ts +4 -6
  4. package/dist/Collection/Cursor.d.ts +56 -4
  5. package/dist/Collection/Observer.d.ts +33 -0
  6. package/dist/Collection/index.d.ts +66 -19
  7. package/dist/Collection/types.d.ts +9 -2
  8. package/dist/DataAdapter.d.ts +24 -6
  9. package/dist/DefaultDataAdapter.d.ts +5 -5
  10. package/dist/WorkerDataAdapter.d.ts +57 -5
  11. package/dist/WorkerDataAdapterHost.d.ts +9 -7
  12. package/dist/createIndex.d.ts +2 -2
  13. package/dist/createIndexProvider.d.ts +2 -2
  14. package/dist/createReactivityAdapter.d.ts +2 -2
  15. package/dist/createStorageAdapter.d.ts +1 -1
  16. package/dist/getIndexInfo.d.ts +3 -4
  17. package/dist/index.cjs.js +33 -31
  18. package/dist/index.d.ts +6 -1
  19. package/dist/index.mjs +17 -32
  20. package/dist/index10.cjs.js +11 -0
  21. package/dist/index10.mjs +10 -18
  22. package/dist/index11.cjs.js +23 -0
  23. package/dist/index11.mjs +22 -15
  24. package/dist/index12.cjs.js +45 -0
  25. package/dist/index12.mjs +44 -353
  26. package/dist/index13.cjs.js +22 -0
  27. package/dist/index13.mjs +21 -419
  28. package/dist/index14.cjs.js +45 -0
  29. package/dist/index14.mjs +44 -206
  30. package/dist/index15.cjs.js +86 -0
  31. package/dist/index15.mjs +85 -388
  32. package/dist/index16.cjs.js +15 -0
  33. package/dist/index16.mjs +14 -579
  34. package/dist/index17.cjs.js +141 -0
  35. package/dist/index17.mjs +140 -152
  36. package/dist/index18.cjs.js +47 -0
  37. package/dist/index18.mjs +46 -26
  38. package/dist/index19.cjs.js +15 -0
  39. package/dist/index19.mjs +14 -41
  40. package/dist/index2.cjs.js +33 -0
  41. package/dist/index2.mjs +32 -258
  42. package/dist/index20.cjs.js +23 -0
  43. package/dist/index20.mjs +22 -16
  44. package/dist/index21.cjs.js +37 -0
  45. package/dist/index21.mjs +36 -104
  46. package/dist/index22.cjs.js +35 -0
  47. package/dist/index22.mjs +34 -128
  48. package/dist/index23.cjs.js +21 -0
  49. package/dist/index23.mjs +20 -7
  50. package/dist/index24.cjs.js +19 -0
  51. package/dist/index24.mjs +18 -27
  52. package/dist/index25.cjs.js +157 -0
  53. package/dist/index25.mjs +156 -11
  54. package/dist/index26.cjs.js +38 -0
  55. package/dist/index26.mjs +37 -29
  56. package/dist/index27.cjs.js +42 -0
  57. package/dist/index27.mjs +41 -46
  58. package/dist/index28.cjs.js +347 -0
  59. package/dist/index28.mjs +345 -7
  60. package/dist/index29.cjs.js +602 -0
  61. package/dist/index29.mjs +601 -7
  62. package/dist/index3.cjs.js +19 -0
  63. package/dist/index3.mjs +18 -556
  64. package/dist/index30.cjs.js +11 -0
  65. package/dist/index30.mjs +10 -42
  66. package/dist/index31.cjs.js +11 -0
  67. package/dist/index31.mjs +10 -29
  68. package/dist/index32.cjs.js +90 -0
  69. package/dist/index32.mjs +89 -10
  70. package/dist/index33.cjs.js +53 -0
  71. package/dist/index33.mjs +52 -5
  72. package/dist/index34.cjs.js +453 -0
  73. package/dist/index34.mjs +453 -0
  74. package/dist/index35.cjs.js +72 -0
  75. package/dist/index35.mjs +72 -0
  76. package/dist/index36.cjs.js +580 -0
  77. package/dist/index36.mjs +580 -0
  78. package/dist/index37.cjs.js +21 -0
  79. package/dist/index37.mjs +21 -0
  80. package/dist/index38.cjs.js +363 -0
  81. package/dist/index38.mjs +363 -0
  82. package/dist/index39.cjs.js +513 -0
  83. package/dist/index39.mjs +513 -0
  84. package/dist/index4.cjs.js +209 -0
  85. package/dist/index4.mjs +204 -5
  86. package/dist/index5.cjs.js +187 -0
  87. package/dist/index5.mjs +186 -5
  88. package/dist/index6.cjs.js +303 -0
  89. package/dist/index6.mjs +301 -28
  90. package/dist/index7.cjs.js +125 -0
  91. package/dist/index7.mjs +124 -12
  92. package/dist/index8.cjs.js +33 -0
  93. package/dist/index8.mjs +32 -5
  94. package/dist/index9.cjs.js +12 -0
  95. package/dist/index9.mjs +11 -133
  96. package/dist/types/IndexProvider.d.ts +2 -2
  97. package/dist/types/Modifier.d.ts +1 -1
  98. package/dist/types/ReactivityAdapter.d.ts +1 -1
  99. package/dist/types/StorageAdapter.d.ts +9 -1
  100. package/dist/utils/applyQueryOptions.d.ts +15 -0
  101. package/dist/utils/createSignal.d.ts +2 -2
  102. package/dist/utils/getMatchingKeys.d.ts +2 -2
  103. package/dist/utils/idIndexQuery.d.ts +20 -0
  104. package/dist/utils/incrementalQueryUpdate.d.ts +62 -0
  105. package/dist/utils/isFieldExpression.d.ts +1 -1
  106. package/dist/utils/match.d.ts +1 -1
  107. package/dist/utils/modify.d.ts +1 -1
  108. package/dist/utils/projectItems.d.ts +12 -0
  109. package/dist/utils/queryDelta.d.ts +83 -0
  110. package/dist/utils/queryId.d.ts +2 -2
  111. package/dist/utils/reactiveOrAsync.d.ts +59 -0
  112. package/dist/utils/storageIndexQuery.d.ts +20 -0
  113. package/package.json +1 -1
  114. package/dist/index.cjs10.js +0 -18
  115. package/dist/index.cjs11.js +0 -15
  116. package/dist/index.cjs12.js +0 -353
  117. package/dist/index.cjs13.js +0 -419
  118. package/dist/index.cjs14.js +0 -206
  119. package/dist/index.cjs15.js +0 -388
  120. package/dist/index.cjs16.js +0 -579
  121. package/dist/index.cjs17.js +0 -152
  122. package/dist/index.cjs18.js +0 -26
  123. package/dist/index.cjs19.js +0 -42
  124. package/dist/index.cjs2.js +0 -259
  125. package/dist/index.cjs20.js +0 -16
  126. package/dist/index.cjs21.js +0 -104
  127. package/dist/index.cjs22.js +0 -129
  128. package/dist/index.cjs23.js +0 -7
  129. package/dist/index.cjs24.js +0 -27
  130. package/dist/index.cjs25.js +0 -10
  131. package/dist/index.cjs26.js +0 -29
  132. package/dist/index.cjs27.js +0 -46
  133. package/dist/index.cjs28.js +0 -8
  134. package/dist/index.cjs29.js +0 -7
  135. package/dist/index.cjs3.js +0 -557
  136. package/dist/index.cjs30.js +0 -42
  137. package/dist/index.cjs31.js +0 -29
  138. package/dist/index.cjs32.js +0 -9
  139. package/dist/index.cjs33.js +0 -5
  140. package/dist/index.cjs4.js +0 -5
  141. package/dist/index.cjs5.js +0 -5
  142. package/dist/index.cjs6.js +0 -29
  143. package/dist/index.cjs7.js +0 -12
  144. package/dist/index.cjs8.js +0 -5
  145. package/dist/index.cjs9.js +0 -133
package/dist/index10.mjs CHANGED
@@ -1,19 +1,11 @@
1
- function get(value, path) {
2
- const normalized = path.replaceAll(/\[(\w+)\]/g, ".$1");
3
- if (normalized.includes("..") || normalized.startsWith(".") || normalized.endsWith(".")) {
4
- return;
5
- }
6
- const segments = normalized.split(".");
7
- let current = value;
8
- for (const key of segments) {
9
- if (current == null)
10
- return;
11
- current = current[key];
12
- }
13
- if (current === void 0)
14
- return;
15
- return current;
1
+ //#region src/createIndexProvider.ts
2
+ /**
3
+ * Creates an IndexProvider based on the given definition.
4
+ * @param definition - The definition of the IndexProvider.
5
+ * @returns The created IndexProvider.
6
+ */
7
+ function createIndexProvider(definition) {
8
+ return definition;
16
9
  }
17
- export {
18
- get as default
19
- };
10
+ //#endregion
11
+ export { createIndexProvider as default };
@@ -0,0 +1,23 @@
1
+ //#region src/utils/get.ts
2
+ /**
3
+ * Retrieves the value at a specified path within an object.
4
+ * Supports dot and bracket notation for navigating nested properties.
5
+ * @template T - The type of the object to retrieve the value from.
6
+ * @param value - The object to navigate.
7
+ * @param path - The path (dot or bracket notation) to the desired value.
8
+ * @returns The value at the specified path, or `undefined` if the path does not exist.
9
+ */
10
+ function get(value, path) {
11
+ const normalized = path.replaceAll(/\[(\w+)\]/g, ".$1");
12
+ if (normalized.includes("..") || normalized.startsWith(".") || normalized.endsWith(".")) return;
13
+ const segments = normalized.split(".");
14
+ let current = value;
15
+ for (const key of segments) {
16
+ if (current == null) return;
17
+ current = current[key];
18
+ }
19
+ if (current === void 0) return;
20
+ return current;
21
+ }
22
+ //#endregion
23
+ exports.default = get;
package/dist/index11.mjs CHANGED
@@ -1,16 +1,23 @@
1
- function serializeValue(value) {
2
- if (value == null)
3
- return null;
4
- if (typeof value === "string")
5
- return value;
6
- if (typeof value === "number")
7
- return value.toString();
8
- if (typeof value === "boolean")
9
- return value.toString();
10
- if (value instanceof Date)
11
- return value.toISOString();
12
- return JSON.stringify(value);
1
+ //#region src/utils/get.ts
2
+ /**
3
+ * Retrieves the value at a specified path within an object.
4
+ * Supports dot and bracket notation for navigating nested properties.
5
+ * @template T - The type of the object to retrieve the value from.
6
+ * @param value - The object to navigate.
7
+ * @param path - The path (dot or bracket notation) to the desired value.
8
+ * @returns The value at the specified path, or `undefined` if the path does not exist.
9
+ */
10
+ function get(value, path) {
11
+ const normalized = path.replaceAll(/\[(\w+)\]/g, ".$1");
12
+ if (normalized.includes("..") || normalized.startsWith(".") || normalized.endsWith(".")) return;
13
+ const segments = normalized.split(".");
14
+ let current = value;
15
+ for (const key of segments) {
16
+ if (current == null) return;
17
+ current = current[key];
18
+ }
19
+ if (current === void 0) return;
20
+ return current;
13
21
  }
14
- export {
15
- serializeValue as default
16
- };
22
+ //#endregion
23
+ export { get as default };
@@ -0,0 +1,45 @@
1
+ //#region src/utils/isFieldExpression.ts
2
+ var expressionKeys = new Set([
3
+ "$eq",
4
+ "$gt",
5
+ "$gte",
6
+ "$lt",
7
+ "$lte",
8
+ "$in",
9
+ "$nin",
10
+ "$ne",
11
+ "$exists",
12
+ "$not",
13
+ "$expr",
14
+ "$jsonSchema",
15
+ "$mod",
16
+ "$regex",
17
+ "$options",
18
+ "$text",
19
+ "$where",
20
+ "$all",
21
+ "$elemMatch",
22
+ "$size",
23
+ "$bitsAllClear",
24
+ "$bitsAllSet",
25
+ "$bitsAnyClear",
26
+ "$bitsAnySet"
27
+ ]);
28
+ /**
29
+ * Determines whether a given object is a valid field expression.
30
+ * A field expression is an object containing query operators supported by MongoDB-style queries.
31
+ * @template T - The type of the field expression.
32
+ * @param expression - The object to test.
33
+ * @returns A boolean indicating whether the object is a valid field expression.
34
+ * - `true` if the object contains only recognized query operators.
35
+ * - `false` otherwise.
36
+ */
37
+ function isFieldExpression(expression) {
38
+ if (typeof expression !== "object" || expression == null) return false;
39
+ const keys = Object.keys(expression);
40
+ if (keys.length === 0) return false;
41
+ if (keys.some((key) => !expressionKeys.has(key))) return false;
42
+ return keys.every((key) => expressionKeys.has(key));
43
+ }
44
+ //#endregion
45
+ exports.default = isFieldExpression;
package/dist/index12.mjs CHANGED
@@ -1,354 +1,45 @@
1
- import createIndex from "./index21.mjs";
2
- import getIndexInfo from "./index22.mjs";
3
- import deepClone from "./index19.mjs";
4
- import EventEmitter from "./index9.mjs";
5
- import isEqual from "./index6.mjs";
6
- import match from "./index23.mjs";
7
- import modify from "./index7.mjs";
8
- import project from "./index24.mjs";
9
- import queryId from "./index20.mjs";
10
- import serializeValue from "./index11.mjs";
11
- import sortItems from "./index25.mjs";
12
- function hasPendingUpdates(pendingUpdates) {
13
- return pendingUpdates.added.length > 0 || pendingUpdates.modified.length > 0 || pendingUpdates.removed.length > 0;
1
+ //#region src/utils/isFieldExpression.ts
2
+ var expressionKeys = new Set([
3
+ "$eq",
4
+ "$gt",
5
+ "$gte",
6
+ "$lt",
7
+ "$lte",
8
+ "$in",
9
+ "$nin",
10
+ "$ne",
11
+ "$exists",
12
+ "$not",
13
+ "$expr",
14
+ "$jsonSchema",
15
+ "$mod",
16
+ "$regex",
17
+ "$options",
18
+ "$text",
19
+ "$where",
20
+ "$all",
21
+ "$elemMatch",
22
+ "$size",
23
+ "$bitsAllClear",
24
+ "$bitsAllSet",
25
+ "$bitsAnyClear",
26
+ "$bitsAnySet"
27
+ ]);
28
+ /**
29
+ * Determines whether a given object is a valid field expression.
30
+ * A field expression is an object containing query operators supported by MongoDB-style queries.
31
+ * @template T - The type of the field expression.
32
+ * @param expression - The object to test.
33
+ * @returns A boolean indicating whether the object is a valid field expression.
34
+ * - `true` if the object contains only recognized query operators.
35
+ * - `false` otherwise.
36
+ */
37
+ function isFieldExpression(expression) {
38
+ if (typeof expression !== "object" || expression == null) return false;
39
+ const keys = Object.keys(expression);
40
+ if (keys.length === 0) return false;
41
+ if (keys.some((key) => !expressionKeys.has(key))) return false;
42
+ return keys.every((key) => expressionKeys.has(key));
14
43
  }
15
- class DefaultDataAdapter {
16
- items = /* @__PURE__ */ new Map();
17
- options;
18
- storageAdapters = /* @__PURE__ */ new Map();
19
- indices = /* @__PURE__ */ new Map();
20
- activeQueries = /* @__PURE__ */ new Map();
21
- queryEmitters = /* @__PURE__ */ new Map();
22
- queuedQueryUpdates = /* @__PURE__ */ new Map();
23
- cachedQueryResults = /* @__PURE__ */ new Map();
24
- constructor(options) {
25
- this.options = options || {};
26
- }
27
- ensureStorageAdapter(name) {
28
- if (this.storageAdapters.get(name))
29
- return;
30
- if (!this.options.storage)
31
- return;
32
- const adapter = this.options.storage(name);
33
- if (!adapter)
34
- return;
35
- this.storageAdapters.set(name, adapter);
36
- }
37
- rebuildIndices(collection) {
38
- const items = this.items.get(collection.name);
39
- if (!items)
40
- throw new Error(`Items not found for collection ${collection.name}`);
41
- const indices = this.indices.get(collection.name);
42
- if (!indices)
43
- throw new Error(`Indices not found for collection ${collection.name}`);
44
- indices.forEach((index) => index.rebuild([...items.values()]));
45
- }
46
- async setupStorageAdapter(collection) {
47
- const storageAdapter = this.storageAdapters.get(collection.name);
48
- if (!storageAdapter)
49
- return;
50
- return storageAdapter.setup().then(async () => {
51
- const items = await storageAdapter.readAll();
52
- this.items.set(collection.name, items.reduce((map, item) => {
53
- map.set(serializeValue(item.id), item);
54
- return map;
55
- }, /* @__PURE__ */ new Map()));
56
- this.rebuildIndices(collection);
57
- }).catch((error) => {
58
- if (!this.options.onError) {
59
- console.error(`Error during data persistence operation in collection ${collection.name}`, error);
60
- return;
61
- }
62
- this.options.onError(collection.name, error instanceof Error ? error : new Error(error));
63
- });
64
- }
65
- getIndexInfo(collection, selector) {
66
- if (selector != null && Object.keys(selector).length === 1 && "id" in selector && typeof selector.id !== "object") {
67
- return {
68
- matched: true,
69
- ids: [serializeValue(selector.id)],
70
- optimizedSelector: {}
71
- };
72
- }
73
- if (selector == null) {
74
- return {
75
- matched: false,
76
- ids: [],
77
- optimizedSelector: {}
78
- };
79
- }
80
- return getIndexInfo((this.indices.get(collection.name) ?? []).map((i) => i.query.bind(i)), selector);
81
- }
82
- applyIndexDeltas(collection, changes) {
83
- const indices = this.indices.get(collection.name) ?? [];
84
- for (const index of indices) {
85
- if (changes.modified)
86
- index.update(changes.modified);
87
- if (changes.added && changes.added.length > 0)
88
- index.insert(changes.added);
89
- if (changes.removed && changes.removed.length > 0)
90
- index.remove(changes.removed);
91
- }
92
- }
93
- getItem(collection, selector) {
94
- const memory = this.items.get(collection.name) ?? /* @__PURE__ */ new Map();
95
- const indexInfo = this.getIndexInfo(collection, selector);
96
- const items = indexInfo.matched ? indexInfo.ids.map((id) => memory.get(serializeValue(id))).filter((i) => i != null) : [...memory.values()];
97
- const item = items.find((document) => match(document, selector));
98
- return item;
99
- }
100
- queryItems(collection, selector) {
101
- const indexInfo = this.getIndexInfo(collection, selector);
102
- const matchItems = (item) => {
103
- if (indexInfo.optimizedSelector == null)
104
- return true;
105
- if (Object.keys(indexInfo.optimizedSelector).length <= 0)
106
- return true;
107
- const matches = match(item, indexInfo.optimizedSelector);
108
- return matches;
109
- };
110
- const items = this.items.get(collection.name);
111
- if (!indexInfo.matched) {
112
- if (isEqual(selector, {}))
113
- return [...items.values()];
114
- return [...items.values()].filter(matchItems);
115
- }
116
- const foundItems = indexInfo.ids.map((ids) => items.get(serializeValue(ids))).filter((i) => i != null);
117
- if (isEqual(indexInfo.optimizedSelector, {}))
118
- return foundItems;
119
- return foundItems.filter(matchItems);
120
- }
121
- executeQuery(collection, selector, options) {
122
- const items = this.queryItems(collection, selector || {});
123
- const { sort, skip, limit, fields } = options || {};
124
- const sorted = sort ? sortItems(items, sort) : items;
125
- const skipped = skip ? sorted.slice(skip) : sorted;
126
- const limited = limit ? skipped.slice(0, limit) : skipped;
127
- const idExcluded = fields && fields.id === 0;
128
- return limited.map((item) => {
129
- if (!fields)
130
- return item;
131
- return {
132
- ...idExcluded ? {} : { id: item.id },
133
- ...project(item, fields)
134
- };
135
- });
136
- }
137
- flushQueuedQueryUpdates(collection) {
138
- if (!this.queuedQueryUpdates.get(collection.name))
139
- return;
140
- const changes = this.queuedQueryUpdates.get(collection.name);
141
- if (!changes || !hasPendingUpdates(changes))
142
- return;
143
- this.queuedQueryUpdates.set(collection.name, { added: [], modified: [], removed: [] });
144
- const flatItems = [...changes.added, ...changes.modified, ...changes.removed];
145
- const itemIds = new Set(flatItems.map((i) => i.id));
146
- const queries = [
147
- ...this.activeQueries.get(collection.name)?.values() ?? []
148
- ].filter(({ selector, options }) => {
149
- const idsInQuery = this.cachedQueryResults.get(collection.name)?.get(queryId(selector, options))?.map((i) => i.id) ?? [];
150
- if (idsInQuery.some((id) => itemIds.has(id)))
151
- return true;
152
- return flatItems.some((item) => match(item, selector));
153
- });
154
- queries.forEach(({ selector, options }) => {
155
- this.executeAndCacheQuery(collection, selector, options);
156
- });
157
- }
158
- executeAndCacheQuery(collection, selector, options) {
159
- const result = this.executeQuery(collection, selector, options);
160
- this.cachedQueryResults.set(collection.name, this.cachedQueryResults.get(collection.name) || /* @__PURE__ */ new Map());
161
- this.cachedQueryResults.get(collection.name)?.set(queryId(selector, options), result);
162
- const emitter = this.queryEmitters.get(collection.name);
163
- if (!emitter)
164
- return;
165
- emitter.emit("change", selector, options, "complete");
166
- }
167
- updateQueries(collection, changes) {
168
- this.queuedQueryUpdates.set(collection.name, this.queuedQueryUpdates.get(collection.name) || { added: [], modified: [], removed: [] });
169
- this.queuedQueryUpdates.get(collection.name)?.added.push(...changes.added);
170
- this.queuedQueryUpdates.get(collection.name)?.modified.push(...changes.modified);
171
- this.queuedQueryUpdates.get(collection.name)?.removed.push(...changes.removed);
172
- this.flushQueuedQueryUpdates(collection);
173
- }
174
- createCollectionBackend(collection, indices) {
175
- this.ensureStorageAdapter(collection.name);
176
- this.items.set(collection.name, this.items.get(collection.name) ?? /* @__PURE__ */ new Map());
177
- this.queryEmitters.set(collection.name, this.queryEmitters.get(collection.name) ?? new EventEmitter());
178
- this.queryEmitters.get(collection.name)?.setMaxListeners(Infinity);
179
- this.activeQueries.set(collection.name, this.activeQueries.get(collection.name) || /* @__PURE__ */ new Map());
180
- this.indices.set(collection.name, indices.map((field) => createIndex(field)));
181
- this.rebuildIndices(collection);
182
- const persistenceReadyPromise = this.setupStorageAdapter(collection);
183
- const backend = {
184
- // CRUD operations
185
- insert: async (newItem) => {
186
- const items = this.items.get(collection.name);
187
- if (!items)
188
- throw new Error(`Items not found for collection ${collection.name}`);
189
- if (items.has(serializeValue(newItem.id))) {
190
- throw new Error(`Item with id '${newItem.id}' already exists`);
191
- }
192
- this.items.get(collection.name)?.set(serializeValue(newItem.id), newItem);
193
- await this.storageAdapters.get(collection.name)?.insert([newItem]);
194
- this.applyIndexDeltas(collection, { added: [newItem] });
195
- this.updateQueries(collection, {
196
- added: [],
197
- modified: [newItem],
198
- removed: []
199
- });
200
- return newItem;
201
- },
202
- updateOne: async (selector, modifier) => {
203
- const { $setOnInsert, ...restModifier } = modifier;
204
- const item = this.getItem(collection, selector);
205
- if (item == null)
206
- return [];
207
- const modifiedItem = modify(deepClone(item), restModifier);
208
- const hasItemWithSameId = item.id !== modifiedItem.id && this.getItem(collection, { id: modifiedItem.id }) != null;
209
- if (hasItemWithSameId) {
210
- throw new Error(`Item with id '${modifiedItem.id}' already exists`);
211
- }
212
- this.items.get(collection.name)?.set(serializeValue(modifiedItem.id), modifiedItem);
213
- await this.storageAdapters.get(collection.name)?.replace([modifiedItem]);
214
- this.applyIndexDeltas(collection, { modified: [{ oldItem: item, newItem: modifiedItem }] });
215
- this.updateQueries(collection, {
216
- added: [],
217
- modified: [modifiedItem],
218
- removed: []
219
- });
220
- return [modifiedItem];
221
- },
222
- updateMany: async (selector, modifier) => {
223
- const { $setOnInsert, ...restModifier } = modifier;
224
- const items = this.executeQuery(collection, selector, {});
225
- const changedItems = items.map((item) => {
226
- const modifiedItem = modify(deepClone(item), restModifier);
227
- const hasItemWithSameId = item.id !== modifiedItem.id && this.getItem(collection, { id: modifiedItem.id }) != null;
228
- if (hasItemWithSameId) {
229
- throw new Error(`Item with id '${modifiedItem.id}' already exists`);
230
- }
231
- return modifiedItem;
232
- });
233
- changedItems.forEach((item) => {
234
- this.items.get(collection.name)?.set(serializeValue(item.id), item);
235
- });
236
- await this.storageAdapters.get(collection.name)?.replace(changedItems);
237
- const pairs = items.map((oldItem, index) => ({ oldItem, newItem: changedItems[index] }));
238
- this.applyIndexDeltas(collection, { modified: pairs });
239
- this.updateQueries(collection, {
240
- added: [],
241
- modified: changedItems,
242
- removed: []
243
- });
244
- return changedItems;
245
- },
246
- replaceOne: async (selector, replacement) => {
247
- const item = this.getItem(collection, selector);
248
- if (item == null)
249
- return [];
250
- const hasItemWithSameId = item.id !== replacement.id && replacement.id != null && this.getItem(collection, { id: replacement.id }) != null;
251
- if (hasItemWithSameId) {
252
- throw new Error(`Item with id '${replacement.id}' already exists`);
253
- }
254
- const modifiedItem = { id: item.id, ...replacement };
255
- this.items.get(collection.name)?.set(serializeValue(modifiedItem.id), modifiedItem);
256
- await this.storageAdapters.get(collection.name)?.replace([modifiedItem]);
257
- this.applyIndexDeltas(collection, { modified: [{ oldItem: item, newItem: modifiedItem }] });
258
- this.updateQueries(collection, {
259
- added: [],
260
- modified: [modifiedItem],
261
- removed: []
262
- });
263
- return [modifiedItem];
264
- },
265
- removeOne: async (selector) => {
266
- const item = this.getItem(collection, selector);
267
- if (item == null)
268
- return [];
269
- this.items.get(collection.name)?.delete(serializeValue(item.id));
270
- await this.storageAdapters.get(collection.name)?.remove([item]);
271
- this.applyIndexDeltas(collection, { removed: [item] });
272
- this.updateQueries(collection, {
273
- added: [],
274
- modified: [],
275
- removed: [item]
276
- });
277
- return [item];
278
- },
279
- removeMany: async (selector) => {
280
- const items = backend.getQueryResult(selector, {});
281
- items.forEach((item) => {
282
- this.items.get(collection.name)?.delete(serializeValue(item.id));
283
- });
284
- await this.storageAdapters.get(collection.name)?.remove(items);
285
- this.applyIndexDeltas(collection, { removed: items });
286
- this.updateQueries(collection, {
287
- added: [],
288
- modified: [],
289
- removed: items
290
- });
291
- return items;
292
- },
293
- // methods for registering and unregistering queries that will be called from the collection during find/findOne
294
- registerQuery: (selector, options) => {
295
- this.activeQueries.set(collection.name, this.activeQueries.get(collection.name) || /* @__PURE__ */ new Map());
296
- this.activeQueries.get(collection.name)?.set(queryId(selector, options), {
297
- selector,
298
- options
299
- });
300
- this.executeAndCacheQuery(collection, selector, options);
301
- },
302
- unregisterQuery: (selector, options) => {
303
- if (!this.activeQueries.get(collection.name))
304
- return;
305
- this.activeQueries.get(collection.name)?.delete(queryId(selector, options));
306
- },
307
- getQueryState: () => "complete",
308
- onQueryStateChange: (selector, options, callback) => {
309
- const emitter = this.queryEmitters.get(collection.name);
310
- if (!emitter)
311
- throw new Error(`Query emitter not found for collection ${collection.name}`);
312
- const handler = (querySelector, queryOptions, state) => {
313
- if (queryId(querySelector, queryOptions) !== queryId(selector, options))
314
- return;
315
- callback(state);
316
- };
317
- emitter.on("change", handler);
318
- return () => {
319
- emitter.off("change", handler);
320
- };
321
- },
322
- getQueryError: () => null,
323
- getQueryResult: (selector, options) => {
324
- const isQueryActive = this.activeQueries.get(collection.name)?.has(queryId(selector, options));
325
- if (isQueryActive) {
326
- const results = this.cachedQueryResults.get(collection.name)?.get(queryId(selector, options));
327
- if (!results)
328
- throw new Error("Cached query results are not defined!");
329
- return results;
330
- }
331
- return this.executeQuery(collection, selector, options);
332
- },
333
- executeQuery: (selector, options) => Promise.resolve(this.executeQuery(collection, selector, options)),
334
- // lifecycle methods
335
- dispose: async () => {
336
- const adapter = this.storageAdapters.get(collection.name);
337
- if (adapter?.teardown)
338
- await adapter.teardown();
339
- this.storageAdapters.delete(collection.name);
340
- this.items.delete(collection.name);
341
- this.indices.delete(collection.name);
342
- this.activeQueries.delete(collection.name);
343
- this.queryEmitters.delete(collection.name);
344
- this.queuedQueryUpdates.delete(collection.name);
345
- this.cachedQueryResults.delete(collection.name);
346
- },
347
- isReady: () => persistenceReadyPromise
348
- };
349
- return backend;
350
- }
351
- }
352
- export {
353
- DefaultDataAdapter as default
354
- };
44
+ //#endregion
45
+ export { isFieldExpression as default };
@@ -0,0 +1,22 @@
1
+ //#region src/utils/serializeValue.ts
2
+ /**
3
+ * Serializes a value into a string representation.
4
+ * Handles various types, including strings, numbers, booleans, dates, and objects.
5
+ * Falls back to JSON stringification for unsupported types.
6
+ * @param value - The value to serialize.
7
+ * - Strings are returned as-is.
8
+ * - Numbers and booleans are converted to their string representation.
9
+ * - Dates are converted to ISO string format.
10
+ * - Other values are stringified using `JSON.stringify`.
11
+ * @returns A string representation of the value.
12
+ */
13
+ function serializeValue(value) {
14
+ if (value == null) return null;
15
+ if (typeof value === "string") return value;
16
+ if (typeof value === "number") return value.toString();
17
+ if (typeof value === "boolean") return value.toString();
18
+ if (value instanceof Date) return value.toISOString();
19
+ return JSON.stringify(value);
20
+ }
21
+ //#endregion
22
+ exports.default = serializeValue;