@signaldb/core 1.7.1 → 2.0.0-beta.0

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 (88) hide show
  1. package/dist/.vite/manifest.json +125 -82
  2. package/dist/AsyncDataAdapter.d.ts +64 -0
  3. package/dist/AutoFetchDataAdapter.d.ts +113 -0
  4. package/dist/Collection/Cursor.d.ts +9 -9
  5. package/dist/Collection/Observer.d.ts +3 -2
  6. package/dist/Collection/index.d.ts +52 -46
  7. package/dist/Collection/types.d.ts +4 -9
  8. package/dist/DataAdapter.d.ts +33 -0
  9. package/dist/DefaultDataAdapter.d.ts +32 -0
  10. package/dist/WorkerDataAdapter.d.ts +22 -0
  11. package/dist/WorkerDataAdapterHost.d.ts +59 -0
  12. package/dist/createIndex.d.ts +7 -0
  13. package/dist/createStorageAdapter.d.ts +9 -0
  14. package/dist/{Collection/getIndexInfo.d.ts → getIndexInfo.d.ts} +17 -19
  15. package/dist/index.cjs.js +21 -17
  16. package/dist/index.cjs10.js +15 -26
  17. package/dist/index.cjs11.js +13 -10
  18. package/dist/index.cjs12.js +337 -3
  19. package/dist/index.cjs13.js +384 -110
  20. package/dist/index.cjs14.js +183 -67
  21. package/dist/index.cjs15.js +339 -8
  22. package/dist/index.cjs16.js +563 -20
  23. package/dist/index.cjs17.js +12 -4
  24. package/dist/index.cjs18.js +24 -5
  25. package/dist/index.cjs2.js +24 -30
  26. package/dist/index.cjs20.js +102 -13
  27. package/dist/index.cjs21.js +124 -21
  28. package/dist/index.cjs22.js +5 -77
  29. package/dist/index.cjs23.js +22 -79
  30. package/dist/index.cjs24.js +5 -16
  31. package/dist/index.cjs25.js +8 -27
  32. package/dist/index.cjs26.js +27 -7
  33. package/dist/index.cjs27.js +3 -5
  34. package/dist/index.cjs28.js +5 -27
  35. package/dist/index.cjs29.js +27 -40
  36. package/dist/index.cjs3.js +191 -441
  37. package/dist/index.cjs30.js +42 -0
  38. package/dist/index.cjs31.js +9 -0
  39. package/dist/index.cjs4.js +3 -165
  40. package/dist/index.cjs5.js +3 -66
  41. package/dist/index.cjs6.js +27 -3
  42. package/dist/index.cjs7.js +10 -3
  43. package/dist/index.cjs8.js +3 -3
  44. package/dist/index.cjs9.js +131 -3
  45. package/dist/index.d.ts +10 -8
  46. package/dist/index.mjs +15 -11
  47. package/dist/index10.mjs +15 -26
  48. package/dist/index11.mjs +13 -10
  49. package/dist/index12.mjs +337 -3
  50. package/dist/index13.mjs +384 -110
  51. package/dist/index14.mjs +183 -66
  52. package/dist/index15.mjs +339 -8
  53. package/dist/index16.mjs +563 -20
  54. package/dist/index17.mjs +12 -4
  55. package/dist/index18.mjs +24 -5
  56. package/dist/index2.mjs +24 -30
  57. package/dist/index20.mjs +102 -13
  58. package/dist/index21.mjs +123 -21
  59. package/dist/index22.mjs +5 -76
  60. package/dist/index23.mjs +22 -78
  61. package/dist/index24.mjs +5 -16
  62. package/dist/index25.mjs +8 -27
  63. package/dist/index26.mjs +27 -7
  64. package/dist/index27.mjs +3 -5
  65. package/dist/index28.mjs +5 -27
  66. package/dist/index29.mjs +27 -40
  67. package/dist/index3.mjs +191 -442
  68. package/dist/index30.mjs +43 -0
  69. package/dist/index31.mjs +10 -0
  70. package/dist/index4.mjs +3 -165
  71. package/dist/index5.mjs +3 -65
  72. package/dist/index6.mjs +27 -3
  73. package/dist/index7.mjs +10 -3
  74. package/dist/index8.mjs +3 -3
  75. package/dist/index9.mjs +131 -3
  76. package/dist/types/IndexProvider.d.ts +12 -7
  77. package/dist/types/StorageAdapter.d.ts +20 -0
  78. package/dist/utils/objectId.d.ts +8 -0
  79. package/dist/utils/queryId.d.ts +9 -0
  80. package/package.json +1 -1
  81. package/dist/AutoFetchCollection.d.ts +0 -60
  82. package/dist/Collection/createIndex.d.ts +0 -15
  83. package/dist/ReplicatedCollection.d.ts +0 -60
  84. package/dist/createMemoryAdapter.d.ts +0 -7
  85. package/dist/persistence/combinePersistenceAdapters.d.ts +0 -32
  86. package/dist/persistence/createPersistenceAdapter.d.ts +0 -9
  87. package/dist/types/MemoryAdapter.d.ts +0 -15
  88. package/dist/types/PersistenceAdapter.d.ts +0 -20
@@ -0,0 +1,43 @@
1
+ const expressionKeys = /* @__PURE__ */ new Set([
2
+ "$eq",
3
+ "$gt",
4
+ "$gte",
5
+ "$lt",
6
+ "$lte",
7
+ "$in",
8
+ "$nin",
9
+ "$ne",
10
+ "$exists",
11
+ "$not",
12
+ "$expr",
13
+ "$jsonSchema",
14
+ "$mod",
15
+ "$regex",
16
+ "$options",
17
+ "$text",
18
+ "$where",
19
+ "$all",
20
+ "$elemMatch",
21
+ "$size",
22
+ "$bitsAllClear",
23
+ "$bitsAllSet",
24
+ "$bitsAnyClear",
25
+ "$bitsAnySet"
26
+ ]);
27
+ function isFieldExpression(expression) {
28
+ if (typeof expression !== "object" || expression == null) {
29
+ return false;
30
+ }
31
+ const keys = Object.keys(expression);
32
+ if (keys.length === 0) {
33
+ return false;
34
+ }
35
+ const hasInvalidKeys = keys.some((key) => !expressionKeys.has(key));
36
+ if (hasInvalidKeys)
37
+ return false;
38
+ const hasValidKeys = keys.every((key) => expressionKeys.has(key));
39
+ return hasValidKeys;
40
+ }
41
+ export {
42
+ isFieldExpression as default
43
+ };
@@ -0,0 +1,10 @@
1
+ function uniqueBy(array, fn) {
2
+ const set = /* @__PURE__ */ new Set();
3
+ return array.filter((element) => {
4
+ const value = typeof fn === "function" ? fn(element) : element[fn];
5
+ return !set.has(value) && set.add(value);
6
+ });
7
+ }
8
+ export {
9
+ uniqueBy as default
10
+ };
package/dist/index4.mjs CHANGED
@@ -1,168 +1,6 @@
1
- import ReplicatedCollection from "./index23.mjs";
2
- import createSignal from "./index21.mjs";
3
- class AutoFetchCollection extends ReplicatedCollection {
4
- activeObservers = /* @__PURE__ */ new Map();
5
- observerTimeouts = /* @__PURE__ */ new Map();
6
- purgeDelay;
7
- idQueryCache = /* @__PURE__ */ new Map();
8
- itemsCache = /* @__PURE__ */ new Map();
9
- fetchQueryItems;
10
- triggerReload = null;
11
- reactivityAdapter = null;
12
- loadingSignals = /* @__PURE__ */ new Map();
13
- isFetchingSignal;
14
- mergeItems;
15
- /**
16
- * @param options {Object} - Options for the collection.
17
- * @param options.fetchQueryItems {Function} - A function that fetches items from the server. It takes the selector as an argument and returns a promise that resolves to an object with an `items` property.
18
- * @param options.purgeDelay {Number} - The delay in milliseconds before purging an item from the cache.
19
- */
20
- constructor(options) {
21
- let triggerRemoteChange;
22
- super({
23
- ...options,
24
- pull: () => Promise.resolve({
25
- items: [...this.itemsCache.values()].reduce((memo, items) => {
26
- const newItems = [...memo];
27
- items.forEach((item) => {
28
- const index = newItems.findIndex((i) => i.id === item.id);
29
- if (index === -1) {
30
- newItems.push(item);
31
- return;
32
- }
33
- newItems[index] = this.mergeItems(newItems[index], item);
34
- });
35
- return newItems;
36
- }, [])
37
- }),
38
- registerRemoteChange: async (onChange) => {
39
- triggerRemoteChange = onChange;
40
- }
41
- });
42
- this.mergeItems = options.mergeItems ?? ((itemA, itemB) => ({ ...itemA, ...itemB }));
43
- this.purgeDelay = options.purgeDelay ?? 1e4;
44
- this.isFetchingSignal = createSignal(options.reactivity, false);
45
- if (!triggerRemoteChange)
46
- throw new Error("No triggerRemoteChange method found. Looks like your persistence adapter was not registered");
47
- this.triggerReload = triggerRemoteChange;
48
- this.reactivityAdapter = options.reactivity ?? null;
49
- this.fetchQueryItems = options.fetchQueryItems;
50
- this.on("observer.created", (selector) => this.handleObserverCreation(selector ?? {}));
51
- this.on("observer.disposed", (selector) => setTimeout(() => this.handleObserverDisposal(selector ?? {}), 100));
52
- if (options.registerRemoteChange) {
53
- void options.registerRemoteChange(() => this.forceRefetch());
54
- }
55
- }
56
- /**
57
- * Registers a query manually that items should be fetched for it
58
- * @param selector {Object} Selector of the query
59
- */
60
- registerQuery(selector) {
61
- this.handleObserverCreation(selector);
62
- }
63
- /**
64
- * Unregisters a query manually that items are not fetched anymore for it
65
- * @param selector {Object} Selector of the query
66
- */
67
- unregisterQuery(selector) {
68
- this.handleObserverDisposal(selector);
69
- }
70
- getKeyForSelector(selector) {
71
- return JSON.stringify(selector);
72
- }
73
- async forceRefetch() {
74
- return Promise.all([...this.activeObservers.values()].map(({ selector }) => this.fetchSelector(selector))).then(() => {
75
- });
76
- }
77
- fetchSelector(selector) {
78
- this.isFetchingSignal.set(true);
79
- return this.fetchQueryItems(selector).then((response) => {
80
- if (!response.items)
81
- throw new Error("AutoFetchCollection currently only works with a full item response");
82
- this.itemsCache.set(this.getKeyForSelector(selector), response.items);
83
- response.items.forEach((item) => {
84
- const queries = this.idQueryCache.get(item.id) ?? [];
85
- queries.push(selector);
86
- this.idQueryCache.set(item.id, queries);
87
- });
88
- this.setLoading(selector, true);
89
- this.once("persistence.received", () => {
90
- this.setLoading(selector, false);
91
- });
92
- if (!this.triggerReload)
93
- throw new Error("No triggerReload method found. Looks like your persistence adapter was not registered");
94
- void this.triggerReload();
95
- }).catch((error) => {
96
- this.emit("persistence.error", error);
97
- }).finally(() => {
98
- this.isFetchingSignal.set(false);
99
- });
100
- }
101
- handleObserverCreation(selector) {
102
- const activeObservers = this.activeObservers.get(this.getKeyForSelector(selector))?.count ?? 0;
103
- this.activeObservers.set(this.getKeyForSelector(selector), {
104
- selector,
105
- count: activeObservers + 1
106
- });
107
- const timeout = this.observerTimeouts.get(this.getKeyForSelector(selector));
108
- if (timeout)
109
- clearTimeout(timeout);
110
- if (activeObservers === 0)
111
- void this.fetchSelector(selector);
112
- }
113
- handleObserverDisposal(selector) {
114
- const currentObservers = this.activeObservers.get(this.getKeyForSelector(selector))?.count ?? 0;
115
- const activeObservers = currentObservers - 1;
116
- if (activeObservers > 0) {
117
- this.activeObservers.set(this.getKeyForSelector(selector), {
118
- selector,
119
- count: activeObservers
120
- });
121
- return;
122
- }
123
- const timeout = this.observerTimeouts.get(this.getKeyForSelector(selector));
124
- if (timeout)
125
- clearTimeout(timeout);
126
- const removeObserver = () => {
127
- this.activeObservers.delete(this.getKeyForSelector(selector));
128
- this.itemsCache.delete(this.getKeyForSelector(selector));
129
- if (!this.triggerReload)
130
- throw new Error("No triggerReload method found. Looks like your persistence adapter was not registered");
131
- void this.triggerReload();
132
- };
133
- if (this.purgeDelay === 0) {
134
- removeObserver();
135
- return;
136
- }
137
- this.observerTimeouts.set(this.getKeyForSelector(selector), setTimeout(removeObserver, this.purgeDelay));
138
- }
139
- ensureSignal(selector) {
140
- if (!this.reactivityAdapter)
141
- throw new Error("No reactivity adapter found");
142
- if (!this.loadingSignals.has(this.getKeyForSelector(selector))) {
143
- this.loadingSignals.set(this.getKeyForSelector(selector), createSignal(this.reactivityAdapter, false));
144
- }
145
- return this.loadingSignals.get(this.getKeyForSelector(selector));
146
- }
147
- setLoading(selector, value) {
148
- const signal = this.ensureSignal(selector);
149
- signal.set(value);
150
- }
151
- /**
152
- * Indicates wether a query is currently been loaded
153
- * ⚡️ this function is reactive!
154
- * @param selector {Object} Selector of the query
155
- * @returns The loading state
156
- */
157
- isLoading(selector) {
158
- const isPushing = this.isPushing();
159
- if (!selector) {
160
- return this.isFetchingSignal.get() || isPushing;
161
- }
162
- const signal = this.ensureSignal(selector);
163
- return signal.get() || isPushing;
164
- }
1
+ function createStorageAdapter(definition) {
2
+ return definition;
165
3
  }
166
4
  export {
167
- AutoFetchCollection as default
5
+ createStorageAdapter as default
168
6
  };
package/dist/index5.mjs CHANGED
@@ -1,68 +1,6 @@
1
- import createPersistenceAdapter from "./index8.mjs";
2
- function createTemporaryFallbackExecutor(firstResolvingPromiseFunction, secondResolvingPromiseFunction, options) {
3
- const cacheTimeout = options?.cacheTimeout;
4
- let isResolved = false;
5
- let resolvedValue = null;
6
- let timeout = null;
7
- let secondaryPromise = null;
8
- return (...args) => {
9
- if (secondaryPromise == null) {
10
- if (timeout) {
11
- clearTimeout(timeout);
12
- timeout = null;
13
- }
14
- secondaryPromise = secondResolvingPromiseFunction(...args).then((result) => {
15
- {
16
- timeout = setTimeout(() => {
17
- isResolved = false;
18
- resolvedValue = null;
19
- secondaryPromise = null;
20
- }, cacheTimeout);
21
- }
22
- isResolved = true;
23
- resolvedValue = result;
24
- if (options?.onResolve)
25
- options.onResolve(resolvedValue);
26
- return result;
27
- });
28
- } else if (isResolved) {
29
- return secondaryPromise;
30
- }
31
- return firstResolvingPromiseFunction(...args);
32
- };
33
- }
34
- function combinePersistenceAdapters(slowAdapter, fastAdapter) {
35
- let handleChange = null;
36
- const readExecutor = createTemporaryFallbackExecutor(() => fastAdapter.load(), () => slowAdapter.load(), {
37
- cacheTimeout: 100,
38
- onResolve: (result) => {
39
- if (handleChange)
40
- void handleChange();
41
- void fastAdapter.save(result.items || [], {
42
- added: result.changes?.added || [],
43
- modified: result.changes?.modified || [],
44
- removed: result.changes?.removed || []
45
- });
46
- }
47
- });
48
- return createPersistenceAdapter({
49
- async register(onChange) {
50
- handleChange = onChange;
51
- await Promise.all([slowAdapter.register(onChange), fastAdapter.register(onChange)]);
52
- },
53
- async load() {
54
- const promise = readExecutor();
55
- return promise;
56
- },
57
- async save(items, changes) {
58
- await Promise.all([
59
- fastAdapter.save(items, changes),
60
- slowAdapter.save(items, changes)
61
- ]);
62
- }
63
- });
1
+ function createReactivityAdapter(definition) {
2
+ return definition;
64
3
  }
65
4
  export {
66
- createTemporaryFallbackExecutor,
67
- combinePersistenceAdapters as default
5
+ createReactivityAdapter as default
68
6
  };
package/dist/index6.mjs CHANGED
@@ -1,6 +1,30 @@
1
- function createIndexProvider(definition) {
2
- return definition;
1
+ function isEqual(a, b) {
2
+ if (Object.is(a, b))
3
+ return true;
4
+ if (a instanceof RegExp && b instanceof RegExp)
5
+ return a.toString() === b.toString();
6
+ if (a instanceof Date && b instanceof Date)
7
+ return a.getTime() === b.getTime();
8
+ if (typeof a !== "object")
9
+ return false;
10
+ if (typeof b !== "object")
11
+ return false;
12
+ if (a === null)
13
+ return false;
14
+ if (b === null)
15
+ return false;
16
+ const aKeys = Object.keys(a);
17
+ const bKeys = Object.keys(b);
18
+ if (aKeys.length !== bKeys.length)
19
+ return false;
20
+ for (const key of aKeys) {
21
+ if (!bKeys.includes(key))
22
+ return false;
23
+ if (!isEqual(a[key], b[key]))
24
+ return false;
25
+ }
26
+ return true;
3
27
  }
4
28
  export {
5
- createIndexProvider as default
29
+ isEqual as default
6
30
  };
package/dist/index7.mjs CHANGED
@@ -1,6 +1,13 @@
1
- function createMemoryAdapter(definition) {
2
- return definition;
1
+ import { update } from "mingo";
2
+ import deepClone from "./index19.mjs";
3
+ function modify(item, modifier) {
4
+ const hasOperators = Object.keys(modifier).some((key) => key.startsWith("$"));
5
+ if (!hasOperators)
6
+ return modifier;
7
+ const clonedItem = deepClone(item);
8
+ update(clonedItem, modifier);
9
+ return clonedItem;
3
10
  }
4
11
  export {
5
- createMemoryAdapter as default
12
+ modify as default
6
13
  };
package/dist/index8.mjs CHANGED
@@ -1,6 +1,6 @@
1
- function createPersistenceAdapter(definition) {
2
- return definition;
1
+ function randomId() {
2
+ return Array.from({ length: 16 }, () => "abcdefghijklmnopqrstuvwxyz0123456789"[Math.floor(Math.random() * 36)]).join("");
3
3
  }
4
4
  export {
5
- createPersistenceAdapter as default
5
+ randomId as default
6
6
  };
package/dist/index9.mjs CHANGED
@@ -1,6 +1,134 @@
1
- function createReactivityAdapter(definition) {
2
- return definition;
1
+ class EventEmitter {
2
+ _maxListeners = 100;
3
+ /**
4
+ * We store a set of the listeners for each event.
5
+ */
6
+ _listenerStore = /* @__PURE__ */ new Map();
7
+ setMaxListeners(max) {
8
+ this._maxListeners = max;
9
+ return this;
10
+ }
11
+ /**
12
+ * Subscribe to an event with a listener function.
13
+ * @param eventName The event name (key of E).
14
+ * @param listener A function that receives the emitted arguments.
15
+ * @returns The emitter instance (for chaining).
16
+ */
17
+ on(eventName, listener) {
18
+ let listenersSet = this._listenerStore.get(eventName);
19
+ if (!listenersSet) {
20
+ listenersSet = /* @__PURE__ */ new Set();
21
+ this._listenerStore.set(eventName, listenersSet);
22
+ }
23
+ listenersSet.add(listener);
24
+ if (listenersSet.size > this._maxListeners) {
25
+ console.warn(`Possible EventEmitter memory leak detected. ${listenersSet.size} ${String(eventName)} listeners added. Use emitter.setMaxListeners() to increase limit.`);
26
+ }
27
+ return this;
28
+ }
29
+ /**
30
+ * Subscribe to an event with a listener function.
31
+ * @param eventName The event name (key of E).
32
+ * @param listener A function that receives the emitted arguments.
33
+ * @returns The emitter instance (for chaining).
34
+ */
35
+ addListener(eventName, listener) {
36
+ return this.on(eventName, listener);
37
+ }
38
+ /**
39
+ * Subscribe to an event, handling it only once. Automatically removes
40
+ * the listener after it fires the first time.
41
+ * @param eventName The event name (key of E).
42
+ * @param listener A function that receives the emitted arguments.
43
+ * @returns The emitter instance (for chaining).
44
+ */
45
+ once(eventName, listener) {
46
+ const onceWrapper = ((...args) => {
47
+ listener(...args);
48
+ this.off(eventName, onceWrapper);
49
+ });
50
+ return this.on(eventName, onceWrapper);
51
+ }
52
+ /**
53
+ * Unsubscribe a previously subscribed listener.
54
+ * @param eventName The event name (key of E).
55
+ * @param listener The original function passed to `on` or `once`.
56
+ * @returns The emitter instance (for chaining).
57
+ */
58
+ off(eventName, listener) {
59
+ const listenersSet = this._listenerStore.get(eventName);
60
+ if (!listenersSet)
61
+ return this;
62
+ listenersSet.delete(listener);
63
+ if (listenersSet.size === 0) {
64
+ this._listenerStore.delete(eventName);
65
+ }
66
+ return this;
67
+ }
68
+ /**
69
+ * Unsubscribe a previously subscribed listener.
70
+ * @param eventName The event name (key of E).
71
+ * @param listener The original function passed to `on` or `once`.
72
+ * @returns The emitter instance (for chaining).
73
+ */
74
+ removeListener(eventName, listener) {
75
+ return this.off(eventName, listener);
76
+ }
77
+ /**
78
+ * Emit (dispatch) an event with a variable number of arguments.
79
+ * @param eventName The event name (key of E).
80
+ * @param args The arguments to pass to subscribed listeners.
81
+ */
82
+ emit(eventName, ...args) {
83
+ this.listeners(eventName).forEach((listener) => {
84
+ listener(...args);
85
+ });
86
+ }
87
+ /**
88
+ * Returns the array of listener functions currently registered for a given event.
89
+ * @param eventName The event name (key of E).
90
+ * @returns An array of listener functions.
91
+ */
92
+ listeners(eventName) {
93
+ const listenersSet = this._listenerStore.get(eventName);
94
+ if (!listenersSet)
95
+ return [];
96
+ return [...listenersSet.values()];
97
+ }
98
+ /**
99
+ * Returns the number of listeners for a given event.
100
+ * @param eventName The event name (key of E).
101
+ * @returns The number of listeners.
102
+ */
103
+ listenerCount(eventName) {
104
+ const listenersSet = this._listenerStore.get(eventName);
105
+ return listenersSet ? listenersSet.size : 0;
106
+ }
107
+ /**
108
+ * Removes all listeners for a given event, or all events if none is specified.
109
+ * @param eventName Optional. If omitted, clears all events’ listeners.
110
+ * @returns The emitter instance (for chaining).
111
+ */
112
+ removeAllListeners(eventName) {
113
+ if (eventName === void 0) {
114
+ for (const [eventName_, listenersSet] of this._listenerStore.entries()) {
115
+ for (const listener of listenersSet.values()) {
116
+ this.off(eventName_, listener);
117
+ }
118
+ }
119
+ this._listenerStore.clear();
120
+ } else {
121
+ const listenersSet = this._listenerStore.get(eventName);
122
+ if (listenersSet) {
123
+ for (const listener of listenersSet.values()) {
124
+ this.off(eventName, listener);
125
+ }
126
+ this._listenerStore.delete(eventName);
127
+ }
128
+ }
129
+ return this;
130
+ }
3
131
  }
4
132
  export {
5
- createReactivityAdapter as default
133
+ EventEmitter as default
6
134
  };
@@ -1,21 +1,26 @@
1
1
  import type { BaseItem } from '../Collection';
2
2
  import type { FlatSelector } from './Selector';
3
- type IndexResult = {
4
- positions: number[];
3
+ export type IndexResult<IdType> = {
4
+ ids: IdType[];
5
5
  fields: string[];
6
6
  keepSelector?: boolean;
7
7
  matched: true;
8
8
  } | {
9
- positions?: never;
9
+ ids?: never;
10
10
  fields?: never;
11
11
  keepSelector?: never;
12
12
  matched: false;
13
13
  };
14
+ export type SynchronousQueryFunction<T extends BaseItem<I> = BaseItem, I = any> = (selector: FlatSelector<T>) => IndexResult<I>;
15
+ export type AsynchronousQueryFunction<T extends BaseItem<I> = BaseItem, I = any> = (selector: FlatSelector<T>) => Promise<IndexResult<I>>;
14
16
  interface IndexProvider<T extends BaseItem<I> = BaseItem, I = any> {
15
- query(selector: FlatSelector<T>): IndexResult;
17
+ query: SynchronousQueryFunction<T, I>;
16
18
  rebuild(items: T[]): void;
19
+ insert(items: T[]): void;
20
+ remove(items: T[]): void;
21
+ update(pairs: {
22
+ oldItem: T;
23
+ newItem: T;
24
+ }[]): void;
17
25
  }
18
- export type LowLevelIndexProvider<T extends BaseItem<I> = BaseItem, I = any> = IndexProvider<T, I> & {
19
- _index: Map<string, Set<number>>;
20
- };
21
26
  export default IndexProvider;
@@ -0,0 +1,20 @@
1
+ export interface Changeset<T> {
2
+ added: T[];
3
+ modified: T[];
4
+ removed: T[];
5
+ }
6
+ export default interface StorageAdapter<T extends {
7
+ id: I;
8
+ } & Record<string, any>, I> {
9
+ setup(): Promise<void>;
10
+ teardown(): Promise<void>;
11
+ readAll(): Promise<T[]>;
12
+ readIds(positions: I[]): Promise<T[]>;
13
+ createIndex(field: string): Promise<void>;
14
+ dropIndex(field: string): Promise<void>;
15
+ readIndex(field: string): Promise<Map<any, Set<I>>>;
16
+ insert(items: T[]): Promise<void>;
17
+ replace(items: T[]): Promise<void>;
18
+ remove(items: T[]): Promise<void>;
19
+ removeAll(): Promise<void>;
20
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Generates a unique identifier for the given object.
3
+ * The same object will always receive the same identifier during its lifetime.
4
+ * Different objects will receive different identifiers.
5
+ * @param object - The object to generate an identifier for.
6
+ * @returns A unique identifier for the object.
7
+ */
8
+ export default function objectId(object: object): number;
@@ -0,0 +1,9 @@
1
+ import type { QueryOptions } from '../DataAdapter';
2
+ import type Selector from '../types/Selector';
3
+ /**
4
+ * Generates a unique identifier for a query based on its selector and options.
5
+ * @param selector - The selector object.
6
+ * @param options - The query options object (optional).
7
+ * @returns A unique identifier string for the query.
8
+ */
9
+ export default function queryId(selector: Selector<any>, options?: QueryOptions<any>): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaldb/core",
3
- "version": "1.7.1",
3
+ "version": "2.0.0-beta.0",
4
4
  "description": "SignalDB is a client-side database that provides a simple MongoDB-like interface to the data with first-class typescript support to achieve an optimistic UI. Data persistence can be achieved by using storage providers that store the data through a JSON interface to places such as localStorage.",
5
5
  "scripts": {
6
6
  "build": "rimraf dist && vite build",
@@ -1,60 +0,0 @@
1
- import type { BaseItem } from './Collection';
2
- import type { ReplicatedCollectionOptions } from './ReplicatedCollection';
3
- import ReplicatedCollection from './ReplicatedCollection';
4
- import type Selector from './types/Selector';
5
- interface AutoFetchOptions<T extends {
6
- id: I;
7
- } & Record<string, any>, I> {
8
- fetchQueryItems: (selector: Selector<T>) => ReturnType<ReplicatedCollectionOptions<T, I>['pull']>;
9
- purgeDelay?: number;
10
- registerRemoteChange?: (onChange: () => Promise<void>) => Promise<void>;
11
- mergeItems?: (itemA: T, itemB: T) => T;
12
- }
13
- export type AutoFetchCollectionOptions<T extends BaseItem<I>, I, U = T> = Omit<ReplicatedCollectionOptions<T, I, U>, 'pull' | 'registerRemoteChange'> & AutoFetchOptions<T, I>;
14
- /**
15
- * A special collection that automatically fetches items when they are needed.
16
- */
17
- export default class AutoFetchCollection<T extends BaseItem<I> = BaseItem, I = any, U = T> extends ReplicatedCollection<T, I, U> {
18
- private activeObservers;
19
- private observerTimeouts;
20
- private purgeDelay;
21
- private idQueryCache;
22
- private itemsCache;
23
- private fetchQueryItems;
24
- private triggerReload;
25
- private reactivityAdapter;
26
- private loadingSignals;
27
- private isFetchingSignal;
28
- private mergeItems;
29
- /**
30
- * @param options {Object} - Options for the collection.
31
- * @param options.fetchQueryItems {Function} - A function that fetches items from the server. It takes the selector as an argument and returns a promise that resolves to an object with an `items` property.
32
- * @param options.purgeDelay {Number} - The delay in milliseconds before purging an item from the cache.
33
- */
34
- constructor(options: AutoFetchCollectionOptions<T, I, U>);
35
- /**
36
- * Registers a query manually that items should be fetched for it
37
- * @param selector {Object} Selector of the query
38
- */
39
- registerQuery(selector: Selector<T>): void;
40
- /**
41
- * Unregisters a query manually that items are not fetched anymore for it
42
- * @param selector {Object} Selector of the query
43
- */
44
- unregisterQuery(selector: Selector<T>): void;
45
- private getKeyForSelector;
46
- private forceRefetch;
47
- private fetchSelector;
48
- private handleObserverCreation;
49
- private handleObserverDisposal;
50
- private ensureSignal;
51
- private setLoading;
52
- /**
53
- * Indicates wether a query is currently been loaded
54
- * ⚡️ this function is reactive!
55
- * @param selector {Object} Selector of the query
56
- * @returns The loading state
57
- */
58
- isLoading(selector?: Selector<T>): boolean;
59
- }
60
- export {};
@@ -1,15 +0,0 @@
1
- import type IndexProvider from '../types/IndexProvider';
2
- import type { BaseItem } from './types';
3
- /**
4
- * creates an index for a specific field but uses an external map to store the index
5
- * @param field name of the field
6
- * @param index the external map to use for the index
7
- * @returns an index provider to pass to the `indices` option of the collection constructor
8
- */
9
- export declare function createExternalIndex<T extends BaseItem<I> = BaseItem, I = any>(field: string, index: Map<string | undefined | null, Set<number>>): IndexProvider<T, I>;
10
- /**
11
- * creates an index for a specific field
12
- * @param field name of the field
13
- * @returns an index provider to pass to the `indices` option of the collection constructor
14
- */
15
- export default function createIndex<T extends BaseItem<I> = BaseItem, I = any>(field: string): IndexProvider<T, I>;