@signaldb/core 1.0.0 → 1.2.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 (76) hide show
  1. package/README.md +2 -2
  2. package/dist/.vite/manifest.json +78 -64
  3. package/dist/Collection/index.d.ts +39 -16
  4. package/dist/Collection/types.d.ts +1 -1
  5. package/dist/devtools.d.ts +4 -0
  6. package/dist/index.cjs.js +19 -11
  7. package/dist/index.cjs10.js +27 -6
  8. package/dist/index.cjs11.js +6 -3
  9. package/dist/index.cjs12.js +3 -35
  10. package/dist/index.cjs13.js +141 -16
  11. package/dist/index.cjs14.js +38 -5
  12. package/dist/index.cjs15.js +2 -42
  13. package/dist/index.cjs16.js +5 -11
  14. package/dist/index.cjs17.js +40 -17
  15. package/dist/index.cjs18.js +11 -245
  16. package/dist/index.cjs19.js +16 -67
  17. package/dist/index.cjs2.js +104 -615
  18. package/dist/index.cjs20.js +251 -67
  19. package/dist/index.cjs21.js +68 -8
  20. package/dist/index.cjs22.js +83 -22
  21. package/dist/index.cjs23.js +8 -135
  22. package/dist/index.cjs24.js +25 -16
  23. package/dist/index.cjs25.js +144 -5
  24. package/dist/index.cjs26.js +5 -17
  25. package/dist/index.cjs27.js +15 -21
  26. package/dist/index.cjs28.js +21 -39
  27. package/dist/index.cjs29.js +40 -27
  28. package/dist/index.cjs3.js +669 -136
  29. package/dist/index.cjs30.js +27 -7
  30. package/dist/index.cjs31.js +9 -0
  31. package/dist/index.cjs4.js +166 -63
  32. package/dist/index.cjs5.js +66 -3
  33. package/dist/index.cjs6.js +2 -2
  34. package/dist/index.cjs7.js +2 -2
  35. package/dist/index.cjs8.js +2 -2
  36. package/dist/index.cjs9.js +3 -28
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.mjs +20 -12
  39. package/dist/index10.mjs +27 -6
  40. package/dist/index11.mjs +6 -3
  41. package/dist/index12.mjs +3 -34
  42. package/dist/index13.mjs +141 -16
  43. package/dist/index14.mjs +37 -5
  44. package/dist/index15.mjs +2 -41
  45. package/dist/index16.mjs +5 -11
  46. package/dist/index17.mjs +39 -17
  47. package/dist/index18.mjs +11 -244
  48. package/dist/index19.mjs +16 -66
  49. package/dist/index2.mjs +80 -615
  50. package/dist/index20.mjs +251 -67
  51. package/dist/index21.mjs +67 -8
  52. package/dist/index22.mjs +82 -22
  53. package/dist/index23.mjs +8 -135
  54. package/dist/index24.mjs +25 -15
  55. package/dist/index25.mjs +144 -5
  56. package/dist/index26.mjs +5 -17
  57. package/dist/index27.mjs +15 -21
  58. package/dist/index28.mjs +21 -39
  59. package/dist/index29.mjs +40 -27
  60. package/dist/index3.mjs +669 -136
  61. package/dist/index30.mjs +27 -7
  62. package/dist/index31.mjs +10 -0
  63. package/dist/index4.mjs +166 -62
  64. package/dist/index5.mjs +65 -3
  65. package/dist/index6.mjs +2 -2
  66. package/dist/index7.mjs +2 -2
  67. package/dist/index8.mjs +2 -2
  68. package/dist/index9.mjs +3 -28
  69. package/dist/persistence/combinePersistenceAdapters.d.ts +7 -7
  70. package/dist/types/MemoryAdapter.d.ts +2 -2
  71. package/dist/utils/EventEmitter.d.ts +75 -0
  72. package/dist/utils/deepClone.d.ts +2 -2
  73. package/dist/utils/set.d.ts +2 -2
  74. package/dist/utils/uniqueBy.d.ts +2 -2
  75. package/package.json +1 -1
  76. package/dist/types/EventEmitter.d.ts +0 -25
package/dist/index30.mjs CHANGED
@@ -1,10 +1,30 @@
1
- function uniqueBy(arr, fn) {
2
- const set = /* @__PURE__ */ new Set();
3
- return arr.filter((el) => {
4
- const value = typeof fn === "function" ? fn(el) : el[fn];
5
- return !set.has(value) && set.add(value);
6
- });
1
+ function set(object, path, value, deleteIfUndefined = false) {
2
+ if (object == null)
3
+ return object;
4
+ const segments = path.split(/[.[\]]/g);
5
+ if (segments[0] === "")
6
+ segments.shift();
7
+ if (segments.at(-1) === "")
8
+ segments.pop();
9
+ const apply = (node) => {
10
+ if (segments.length > 1) {
11
+ const key = segments.shift();
12
+ const nextIsNumber = !Number.isNaN(Number.parseInt(segments[0], 10));
13
+ if (node[key] === void 0) {
14
+ node[key] = nextIsNumber ? [] : {};
15
+ }
16
+ apply(node[key]);
17
+ } else {
18
+ if (deleteIfUndefined && value === void 0) {
19
+ delete node[segments[0]];
20
+ return;
21
+ }
22
+ node[segments[0]] = value;
23
+ }
24
+ };
25
+ apply(object);
26
+ return object;
7
27
  }
8
28
  export {
9
- uniqueBy as default
29
+ set as default
10
30
  };
@@ -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,70 +1,174 @@
1
- import createPersistenceAdapter from "./index7.mjs";
2
- function createTemporaryFallbackExecutor(firstResolvingPromiseFn, secondResolvingPromiseFn, options) {
3
- var _a;
4
- const cacheTimeout = (_a = options === null || options === void 0 ? void 0 : options.cacheTimeout) !== null && _a !== void 0 ? _a : 0;
5
- let isResolved = false;
6
- let resolvedValue = null;
7
- let timeout = null;
8
- let secondaryPromise = null;
9
- return (...args) => {
10
- if (secondaryPromise == null) {
11
- if (timeout) {
12
- clearTimeout(timeout);
13
- timeout = null;
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ import ReplicatedCollection from "./index22.mjs";
5
+ import createSignal from "./index19.mjs";
6
+ class AutoFetchCollection extends ReplicatedCollection {
7
+ /**
8
+ * @param options {Object} - Options for the collection.
9
+ * @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.
10
+ * @param options.purgeDelay {Number} - The delay in milliseconds before purging an item from the cache.
11
+ */
12
+ constructor(options) {
13
+ var _a;
14
+ let triggerRemoteChange;
15
+ super({
16
+ ...options,
17
+ pull: () => Promise.resolve({
18
+ items: [...this.itemsCache.values()].reduce((memo, items) => {
19
+ const newItems = [...memo];
20
+ items.forEach((item) => {
21
+ const index = newItems.findIndex((i) => i.id === item.id);
22
+ if (index === -1) {
23
+ newItems.push(item);
24
+ return;
25
+ }
26
+ newItems[index] = this.mergeItems(newItems[index], item);
27
+ });
28
+ return newItems;
29
+ }, [])
30
+ }),
31
+ registerRemoteChange: async (onChange) => {
32
+ triggerRemoteChange = onChange;
14
33
  }
15
- secondaryPromise = secondResolvingPromiseFn(...args).then((result) => {
16
- if (cacheTimeout > 0) {
17
- timeout = setTimeout(() => {
18
- isResolved = false;
19
- resolvedValue = null;
20
- secondaryPromise = null;
21
- }, cacheTimeout);
22
- }
23
- isResolved = true;
24
- resolvedValue = result;
25
- if (options === null || options === void 0 ? void 0 : options.onResolve)
26
- options.onResolve(resolvedValue);
27
- return result;
28
- });
29
- } else if (isResolved) {
30
- return secondaryPromise;
34
+ });
35
+ __publicField(this, "activeObservers", /* @__PURE__ */ new Map());
36
+ __publicField(this, "observerTimeouts", /* @__PURE__ */ new Map());
37
+ __publicField(this, "purgeDelay");
38
+ __publicField(this, "idQueryCache", /* @__PURE__ */ new Map());
39
+ __publicField(this, "itemsCache", /* @__PURE__ */ new Map());
40
+ __publicField(this, "fetchQueryItems");
41
+ __publicField(this, "triggerReload", null);
42
+ __publicField(this, "reactivityAdapter", null);
43
+ __publicField(this, "loadingSignals", /* @__PURE__ */ new Map());
44
+ __publicField(this, "isFetchingSignal");
45
+ __publicField(this, "mergeItems");
46
+ this.mergeItems = options.mergeItems ?? ((itemA, itemB) => ({ ...itemA, ...itemB }));
47
+ this.purgeDelay = options.purgeDelay ?? 1e4;
48
+ this.isFetchingSignal = createSignal((_a = options.reactivity) == null ? void 0 : _a.create(), false);
49
+ if (!triggerRemoteChange)
50
+ throw new Error("No triggerRemoteChange method found. Looks like your persistence adapter was not registered");
51
+ this.triggerReload = triggerRemoteChange;
52
+ this.reactivityAdapter = options.reactivity ?? null;
53
+ this.fetchQueryItems = options.fetchQueryItems;
54
+ this.on("observer.created", (selector) => this.handleObserverCreation(selector ?? {}));
55
+ this.on("observer.disposed", (selector) => setTimeout(() => this.handleObserverDisposal(selector ?? {}), 100));
56
+ if (options.registerRemoteChange) {
57
+ void options.registerRemoteChange(() => this.forceRefetch());
31
58
  }
32
- return firstResolvingPromiseFn(...args);
33
- };
34
- }
35
- function combinePersistenceAdapters(slowAdapter, fastAdapter) {
36
- let handleChange = null;
37
- const readExecutor = createTemporaryFallbackExecutor(() => fastAdapter.load(), () => slowAdapter.load(), {
38
- cacheTimeout: 100,
39
- onResolve: (result) => {
40
- var _a, _b, _c;
41
- if (handleChange)
42
- void handleChange();
43
- void fastAdapter.save(result.items || [], {
44
- added: ((_a = result.changes) === null || _a === void 0 ? void 0 : _a.added) || [],
45
- modified: ((_b = result.changes) === null || _b === void 0 ? void 0 : _b.modified) || [],
46
- removed: ((_c = result.changes) === null || _c === void 0 ? void 0 : _c.removed) || []
59
+ }
60
+ /**
61
+ * Registers a query manually that items should be fetched for it
62
+ * @param selector {Object} Selector of the query
63
+ */
64
+ registerQuery(selector) {
65
+ this.handleObserverCreation(selector);
66
+ }
67
+ /**
68
+ * Unregisters a query manually that items are not fetched anymore for it
69
+ * @param selector {Object} Selector of the query
70
+ */
71
+ unregisterQuery(selector) {
72
+ this.handleObserverDisposal(selector);
73
+ }
74
+ getKeyForSelector(selector) {
75
+ return JSON.stringify(selector);
76
+ }
77
+ async forceRefetch() {
78
+ return Promise.all([...this.activeObservers.values()].map(({ selector }) => this.fetchSelector(selector))).then(() => {
79
+ });
80
+ }
81
+ fetchSelector(selector) {
82
+ this.isFetchingSignal.set(true);
83
+ return this.fetchQueryItems(selector).then((response) => {
84
+ if (!response.items)
85
+ throw new Error("AutoFetchCollection currently only works with a full item response");
86
+ this.itemsCache.set(this.getKeyForSelector(selector), response.items);
87
+ response.items.forEach((item) => {
88
+ const queries = this.idQueryCache.get(item.id) ?? [];
89
+ queries.push(selector);
90
+ this.idQueryCache.set(item.id, queries);
91
+ });
92
+ this.setLoading(selector, true);
93
+ this.once("persistence.received", () => {
94
+ this.setLoading(selector, false);
47
95
  });
96
+ if (!this.triggerReload)
97
+ throw new Error("No triggerReload method found. Looks like your persistence adapter was not registered");
98
+ void this.triggerReload();
99
+ }).catch((error) => {
100
+ this.emit("persistence.error", error);
101
+ }).finally(() => {
102
+ this.isFetchingSignal.set(false);
103
+ });
104
+ }
105
+ handleObserverCreation(selector) {
106
+ var _a;
107
+ const activeObservers = ((_a = this.activeObservers.get(this.getKeyForSelector(selector))) == null ? void 0 : _a.count) ?? 0;
108
+ this.activeObservers.set(this.getKeyForSelector(selector), {
109
+ selector,
110
+ count: activeObservers + 1
111
+ });
112
+ const timeout = this.observerTimeouts.get(this.getKeyForSelector(selector));
113
+ if (timeout)
114
+ clearTimeout(timeout);
115
+ if (activeObservers === 0)
116
+ void this.fetchSelector(selector);
117
+ }
118
+ handleObserverDisposal(selector) {
119
+ var _a;
120
+ const currentObservers = ((_a = this.activeObservers.get(this.getKeyForSelector(selector))) == null ? void 0 : _a.count) ?? 0;
121
+ const activeObservers = currentObservers - 1;
122
+ if (activeObservers > 0) {
123
+ this.activeObservers.set(this.getKeyForSelector(selector), {
124
+ selector,
125
+ count: activeObservers
126
+ });
127
+ return;
128
+ }
129
+ const timeout = this.observerTimeouts.get(this.getKeyForSelector(selector));
130
+ if (timeout)
131
+ clearTimeout(timeout);
132
+ const removeObserver = () => {
133
+ this.activeObservers.delete(this.getKeyForSelector(selector));
134
+ this.itemsCache.delete(this.getKeyForSelector(selector));
135
+ if (!this.triggerReload)
136
+ throw new Error("No triggerReload method found. Looks like your persistence adapter was not registered");
137
+ void this.triggerReload();
138
+ };
139
+ if (this.purgeDelay === 0) {
140
+ removeObserver();
141
+ return;
142
+ }
143
+ this.observerTimeouts.set(this.getKeyForSelector(selector), setTimeout(removeObserver, this.purgeDelay));
144
+ }
145
+ ensureSignal(selector) {
146
+ if (!this.reactivityAdapter)
147
+ throw new Error("No reactivity adapter found");
148
+ if (!this.loadingSignals.has(this.getKeyForSelector(selector))) {
149
+ this.loadingSignals.set(this.getKeyForSelector(selector), createSignal(this.reactivityAdapter.create(), false));
48
150
  }
49
- });
50
- return createPersistenceAdapter({
51
- async register(onChange) {
52
- handleChange = onChange;
53
- await Promise.all([slowAdapter.register(onChange), fastAdapter.register(onChange)]);
54
- },
55
- async load() {
56
- const promise = readExecutor();
57
- return promise;
58
- },
59
- async save(items, changes) {
60
- await Promise.all([
61
- fastAdapter.save(items, changes),
62
- slowAdapter.save(items, changes)
63
- ]);
151
+ return this.loadingSignals.get(this.getKeyForSelector(selector));
152
+ }
153
+ setLoading(selector, value) {
154
+ const signal = this.ensureSignal(selector);
155
+ signal.set(value);
156
+ }
157
+ /**
158
+ * Indicates wether a query is currently been loaded
159
+ * ⚡️ this function is reactive!
160
+ * @param selector {Object} Selector of the query
161
+ * @returns The loading state
162
+ */
163
+ isLoading(selector) {
164
+ const isPushing = this.isPushing();
165
+ if (!selector) {
166
+ return this.isFetchingSignal.get() || isPushing;
64
167
  }
65
- });
168
+ const signal = this.ensureSignal(selector);
169
+ return signal.get() || isPushing;
170
+ }
66
171
  }
67
172
  export {
68
- createTemporaryFallbackExecutor,
69
- combinePersistenceAdapters as default
173
+ AutoFetchCollection as default
70
174
  };
package/dist/index5.mjs CHANGED
@@ -1,6 +1,68 @@
1
- function createIndexProvider(definition) {
2
- return definition;
1
+ import createPersistenceAdapter from "./index8.mjs";
2
+ function createTemporaryFallbackExecutor(firstResolvingPromiseFunction, secondResolvingPromiseFunction, options) {
3
+ const cacheTimeout = options == null ? void 0 : 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
+ options.onResolve(resolvedValue);
25
+ return result;
26
+ });
27
+ } else if (isResolved) {
28
+ return secondaryPromise;
29
+ }
30
+ return firstResolvingPromiseFunction(...args);
31
+ };
32
+ }
33
+ function combinePersistenceAdapters(slowAdapter, fastAdapter) {
34
+ let handleChange = null;
35
+ const readExecutor = createTemporaryFallbackExecutor(() => fastAdapter.load(), () => slowAdapter.load(), {
36
+ cacheTimeout: 100,
37
+ onResolve: (result) => {
38
+ var _a, _b, _c;
39
+ if (handleChange)
40
+ void handleChange();
41
+ void fastAdapter.save(result.items || [], {
42
+ added: ((_a = result.changes) == null ? void 0 : _a.added) || [],
43
+ modified: ((_b = result.changes) == null ? void 0 : _b.modified) || [],
44
+ removed: ((_c = result.changes) == null ? void 0 : _c.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
+ });
3
64
  }
4
65
  export {
5
- createIndexProvider as default
66
+ createTemporaryFallbackExecutor,
67
+ combinePersistenceAdapters as default
6
68
  };
package/dist/index6.mjs CHANGED
@@ -1,6 +1,6 @@
1
- function createMemoryAdapter(definition) {
1
+ function createIndexProvider(definition) {
2
2
  return definition;
3
3
  }
4
4
  export {
5
- createMemoryAdapter as default
5
+ createIndexProvider as default
6
6
  };
package/dist/index7.mjs CHANGED
@@ -1,6 +1,6 @@
1
- function createPersistenceAdapter(definition) {
1
+ function createMemoryAdapter(definition) {
2
2
  return definition;
3
3
  }
4
4
  export {
5
- createPersistenceAdapter as default
5
+ createMemoryAdapter as default
6
6
  };
package/dist/index8.mjs CHANGED
@@ -1,6 +1,6 @@
1
- function createReactivityAdapter(definition) {
1
+ function createPersistenceAdapter(definition) {
2
2
  return definition;
3
3
  }
4
4
  export {
5
- createReactivityAdapter as default
5
+ createPersistenceAdapter as default
6
6
  };
package/dist/index9.mjs CHANGED
@@ -1,31 +1,6 @@
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 (let i = 0; i < aKeys.length; i += 1) {
21
- const key = aKeys[i];
22
- if (!bKeys.includes(key))
23
- return false;
24
- if (!isEqual(a[key], b[key]))
25
- return false;
26
- }
27
- return true;
1
+ function createReactivityAdapter(definition) {
2
+ return definition;
28
3
  }
29
4
  export {
30
- isEqual as default
5
+ createReactivityAdapter as default
31
6
  };
@@ -4,19 +4,19 @@ import type PersistenceAdapter from '../types/PersistenceAdapter';
4
4
  * The first function is tried first, and if it resolves, its value is used.
5
5
  * If the first function fails or a fallback is required, the second function is executed.
6
6
  * An optional cache mechanism can store the result temporarily to improve performance.
7
- * @template Args - The argument types for the promise functions.
8
- * @template ReturnVal - The return value type of the promise functions.
9
- * @param firstResolvingPromiseFn - The primary promise-based function to execute.
10
- * @param secondResolvingPromiseFn - The secondary fallback promise-based function to execute.
7
+ * @template Arguments - The argument types for the promise functions.
8
+ * @template ReturnValue - The return value type of the promise functions.
9
+ * @param firstResolvingPromiseFunction - The primary promise-based function to execute.
10
+ * @param secondResolvingPromiseFunction - The secondary fallback promise-based function to execute.
11
11
  * @param [options] - Optional configuration.
12
12
  * @param [options.onResolve] - Callback executed when a promise resolves.
13
13
  * @param [options.cacheTimeout] - Time (in ms) to cache the resolved result.
14
14
  * @returns A function that executes the two promises as described.
15
15
  */
16
- export declare function createTemporaryFallbackExecutor<Args extends Array<any>, ReturnVal>(firstResolvingPromiseFn: (...args: Args) => Promise<ReturnVal>, secondResolvingPromiseFn: (...args: Args) => Promise<ReturnVal>, options?: {
17
- onResolve?: (returnValue: ReturnVal) => void;
16
+ export declare function createTemporaryFallbackExecutor<Arguments extends Array<any>, ReturnValue>(firstResolvingPromiseFunction: (...args: Arguments) => Promise<ReturnValue>, secondResolvingPromiseFunction: (...args: Arguments) => Promise<ReturnValue>, options?: {
17
+ onResolve?: (returnValue: ReturnValue) => void;
18
18
  cacheTimeout?: number;
19
- }): (...args: Args) => Promise<ReturnVal>;
19
+ }): (...args: Arguments) => Promise<ReturnValue>;
20
20
  /**
21
21
  * Combines two persistence adapters (fast and slow) into a single interface.
22
22
  * The fast adapter is used for quick read and write operations, while the slow adapter
@@ -9,7 +9,7 @@ export default abstract class MemoryAdapter<T = Record<string, any>> {
9
9
  abstract pop(): T | undefined;
10
10
  abstract splice(start: number, deleteCount?: number, ...items: T[]): T[];
11
11
  abstract map<U>(callbackfn: (value: T, index: number, array: T[]) => U): U[];
12
- abstract find(predicate: (value: T, index: number, obj: T[]) => boolean): T | undefined;
12
+ abstract find(predicate: (value: T, index: number, object: T[]) => boolean): T | undefined;
13
13
  abstract filter(predicate: (value: T, index: number, array: T[]) => unknown): T[];
14
- abstract findIndex(predicate: (value: T, index: number, obj: T[]) => boolean): number;
14
+ abstract findIndex(predicate: (value: T, index: number, object: T[]) => boolean): number;
15
15
  }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * A strongly‑typed EventEmitter using the native EventTarget under the hood.
3
+ */
4
+ export default class EventEmitter<Events extends Record<string | symbol, any>> extends EventTarget {
5
+ private _maxListeners;
6
+ /**
7
+ * We store a map of:
8
+ * eventName => (originalListener => wrappedListener)
9
+ *
10
+ * The "wrappedListener" is the actual function passed to `addEventListener()`.
11
+ */
12
+ private _listenerStore;
13
+ setMaxListeners(max: number): this;
14
+ /**
15
+ * Subscribe to an event with a listener function.
16
+ * @param eventName The event name (key of E).
17
+ * @param listener A function that receives the emitted arguments.
18
+ * @returns The emitter instance (for chaining).
19
+ */
20
+ on<K extends keyof Events>(eventName: K, listener: Events[K]): this;
21
+ /**
22
+ * Subscribe to an event with a listener function.
23
+ * @param eventName The event name (key of E).
24
+ * @param listener A function that receives the emitted arguments.
25
+ * @returns The emitter instance (for chaining).
26
+ */
27
+ addListener<K extends keyof Events>(eventName: K, listener: Events[K]): this;
28
+ /**
29
+ * Subscribe to an event, handling it only once. Automatically removes
30
+ * the listener after it fires the first time.
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
+ once<K extends keyof Events>(eventName: K, listener: Events[K]): this;
36
+ /**
37
+ * Unsubscribe a previously subscribed listener.
38
+ * @param eventName The event name (key of E).
39
+ * @param listener The original function passed to `on` or `once`.
40
+ * @returns The emitter instance (for chaining).
41
+ */
42
+ off<K extends keyof Events>(eventName: K, listener: Events[K]): this;
43
+ /**
44
+ * Unsubscribe a previously subscribed listener.
45
+ * @param eventName The event name (key of E).
46
+ * @param listener The original function passed to `on` or `once`.
47
+ * @returns The emitter instance (for chaining).
48
+ */
49
+ removeListener<K extends keyof Events>(eventName: K, listener: Events[K]): this;
50
+ /**
51
+ * Emit (dispatch) an event with a variable number of arguments.
52
+ * @param eventName The event name (key of E).
53
+ * @param args The arguments to pass to subscribed listeners.
54
+ * @returns A boolean indicating if the event was not cancelled.
55
+ */
56
+ emit<K extends keyof Events>(eventName: K, ...args: Parameters<Events[K]>): boolean;
57
+ /**
58
+ * Returns the array of listener functions currently registered for a given event.
59
+ * @param eventName The event name (key of E).
60
+ * @returns An array of listener functions.
61
+ */
62
+ listeners<K extends keyof Events>(eventName: K): Array<(...args: Parameters<Events[K]>) => void>;
63
+ /**
64
+ * Returns the number of listeners for a given event.
65
+ * @param eventName The event name (key of E).
66
+ * @returns The number of listeners.
67
+ */
68
+ listenerCount<K extends keyof Events>(eventName: K): number;
69
+ /**
70
+ * Removes all listeners for a given event, or all events if none is specified.
71
+ * @param eventName Optional. If omitted, clears all events’ listeners.
72
+ * @returns The emitter instance (for chaining).
73
+ */
74
+ removeAllListeners<K extends keyof Events>(eventName?: K): this;
75
+ }
@@ -11,7 +11,7 @@ export declare function clone<T>(value: T): T;
11
11
  * Creates a deep clone of an object. Uses the `structuredClone` function if available,
12
12
  * otherwise falls back to a manual deep clone implementation.
13
13
  * @template T - The type of the object to clone.
14
- * @param obj - The object to deep clone.
14
+ * @param object - The object to deep clone.
15
15
  * @returns A deep copy of the provided object.
16
16
  */
17
- export default function deepClone<T>(obj: T): T;
17
+ export default function deepClone<T>(object: T): T;
@@ -4,10 +4,10 @@
4
4
  * deleting the key if the value is `undefined` and the `deleteIfUndefined` flag is set to `true`.
5
5
  * @template T - The type of the object to modify.
6
6
  * @template K - The type of the value to set.
7
- * @param obj - The object to modify. The object is mutated directly.
7
+ * @param object - The object to modify. The object is mutated directly.
8
8
  * @param path - The path (dot or bracket notation) where the value should be set.
9
9
  * @param value - The value to set at the specified path.
10
10
  * @param deleteIfUndefined - A boolean indicating whether to delete the key if the value is `undefined` (default: `false`).
11
11
  * @returns The modified object.
12
12
  */
13
- export default function set<T extends object, K>(obj: T, path: string, value: K, deleteIfUndefined?: boolean): T;
13
+ export default function set<T extends object, K>(object: T, path: string, value: K, deleteIfUndefined?: boolean): T;
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Filters an array to ensure unique values based on a specified key or transformation function.
3
3
  * @template T - The type of the elements in the array.
4
- * @param arr - The array to filter for unique values.
4
+ * @param array - The array to filter for unique values.
5
5
  * @param fn - A key or transformation function to determine uniqueness.
6
6
  * - If a key is provided, it will use the corresponding property of each element for uniqueness.
7
7
  * - If a function is provided, it will use the return value of the function applied to each element for uniqueness.
8
8
  * @returns A new array containing only unique elements based on the specified key or transformation.
9
9
  */
10
- export default function uniqueBy<T>(arr: T[], fn: keyof T | ((item: T) => any)): T[];
10
+ export default function uniqueBy<T>(array: T[], fn: keyof T | ((item: T) => any)): T[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaldb/core",
3
- "version": "1.0.0",
3
+ "version": "1.2.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,25 +0,0 @@
1
- import { EventEmitter as BaseEventEmitter } from 'events';
2
- /**
3
- * Extends the `EventEmitter` class from Node.js to provide a strongly-typed
4
- * event emitter that enforces type safety for events and their corresponding listeners.
5
- * @template Events - A record where keys represent event names (string or symbol),
6
- * and values represent the listener function types for those events.
7
- */
8
- export default class EventEmitter<Events extends Record<string | symbol, any>> extends BaseEventEmitter {
9
- /**
10
- * Registers a listener for the specified event.
11
- * @template K - The key of the event in the `Events` record.
12
- * @param event - The name of the event to listen for.
13
- * @param listener - The listener function to execute when the event is emitted.
14
- * @returns The `EventEmitter` instance, allowing for method chaining.
15
- */
16
- on<K extends keyof Events>(event: K, listener: Events[K]): this;
17
- /**
18
- * Emits the specified event, triggering all registered listeners for that event.
19
- * @template K - The key of the event in the `Events` record.
20
- * @param event - The name of the event to emit.
21
- * @param args - The arguments to pass to the event listeners.
22
- * @returns A boolean indicating whether any listeners were triggered.
23
- */
24
- emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): boolean;
25
- }