@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.
- package/README.md +2 -2
- package/dist/.vite/manifest.json +78 -64
- package/dist/Collection/index.d.ts +39 -16
- package/dist/Collection/types.d.ts +1 -1
- package/dist/devtools.d.ts +4 -0
- package/dist/index.cjs.js +19 -11
- package/dist/index.cjs10.js +27 -6
- package/dist/index.cjs11.js +6 -3
- package/dist/index.cjs12.js +3 -35
- package/dist/index.cjs13.js +141 -16
- package/dist/index.cjs14.js +38 -5
- package/dist/index.cjs15.js +2 -42
- package/dist/index.cjs16.js +5 -11
- package/dist/index.cjs17.js +40 -17
- package/dist/index.cjs18.js +11 -245
- package/dist/index.cjs19.js +16 -67
- package/dist/index.cjs2.js +104 -615
- package/dist/index.cjs20.js +251 -67
- package/dist/index.cjs21.js +68 -8
- package/dist/index.cjs22.js +83 -22
- package/dist/index.cjs23.js +8 -135
- package/dist/index.cjs24.js +25 -16
- package/dist/index.cjs25.js +144 -5
- package/dist/index.cjs26.js +5 -17
- package/dist/index.cjs27.js +15 -21
- package/dist/index.cjs28.js +21 -39
- package/dist/index.cjs29.js +40 -27
- package/dist/index.cjs3.js +669 -136
- package/dist/index.cjs30.js +27 -7
- package/dist/index.cjs31.js +9 -0
- package/dist/index.cjs4.js +166 -63
- package/dist/index.cjs5.js +66 -3
- package/dist/index.cjs6.js +2 -2
- package/dist/index.cjs7.js +2 -2
- package/dist/index.cjs8.js +2 -2
- package/dist/index.cjs9.js +3 -28
- package/dist/index.d.ts +2 -0
- package/dist/index.mjs +20 -12
- package/dist/index10.mjs +27 -6
- package/dist/index11.mjs +6 -3
- package/dist/index12.mjs +3 -34
- package/dist/index13.mjs +141 -16
- package/dist/index14.mjs +37 -5
- package/dist/index15.mjs +2 -41
- package/dist/index16.mjs +5 -11
- package/dist/index17.mjs +39 -17
- package/dist/index18.mjs +11 -244
- package/dist/index19.mjs +16 -66
- package/dist/index2.mjs +80 -615
- package/dist/index20.mjs +251 -67
- package/dist/index21.mjs +67 -8
- package/dist/index22.mjs +82 -22
- package/dist/index23.mjs +8 -135
- package/dist/index24.mjs +25 -15
- package/dist/index25.mjs +144 -5
- package/dist/index26.mjs +5 -17
- package/dist/index27.mjs +15 -21
- package/dist/index28.mjs +21 -39
- package/dist/index29.mjs +40 -27
- package/dist/index3.mjs +669 -136
- package/dist/index30.mjs +27 -7
- package/dist/index31.mjs +10 -0
- package/dist/index4.mjs +166 -62
- package/dist/index5.mjs +65 -3
- package/dist/index6.mjs +2 -2
- package/dist/index7.mjs +2 -2
- package/dist/index8.mjs +2 -2
- package/dist/index9.mjs +3 -28
- package/dist/persistence/combinePersistenceAdapters.d.ts +7 -7
- package/dist/types/MemoryAdapter.d.ts +2 -2
- package/dist/utils/EventEmitter.d.ts +75 -0
- package/dist/utils/deepClone.d.ts +2 -2
- package/dist/utils/set.d.ts +2 -2
- package/dist/utils/uniqueBy.d.ts +2 -2
- package/package.json +1 -1
- package/dist/types/EventEmitter.d.ts +0 -25
package/dist/index30.mjs
CHANGED
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
29
|
+
set as default
|
|
10
30
|
};
|
package/dist/index31.mjs
ADDED
|
@@ -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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
69
|
-
combinePersistenceAdapters as default
|
|
173
|
+
AutoFetchCollection as default
|
|
70
174
|
};
|
package/dist/index5.mjs
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
66
|
+
createTemporaryFallbackExecutor,
|
|
67
|
+
combinePersistenceAdapters as default
|
|
6
68
|
};
|
package/dist/index6.mjs
CHANGED
package/dist/index7.mjs
CHANGED
package/dist/index8.mjs
CHANGED
package/dist/index9.mjs
CHANGED
|
@@ -1,31 +1,6 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
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
|
-
|
|
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
|
|
8
|
-
* @template
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
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<
|
|
17
|
-
onResolve?: (returnValue:
|
|
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:
|
|
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,
|
|
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,
|
|
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
|
|
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>(
|
|
17
|
+
export default function deepClone<T>(object: T): T;
|
package/dist/utils/set.d.ts
CHANGED
|
@@ -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
|
|
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>(
|
|
13
|
+
export default function set<T extends object, K>(object: T, path: string, value: K, deleteIfUndefined?: boolean): T;
|
package/dist/utils/uniqueBy.d.ts
CHANGED
|
@@ -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
|
|
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>(
|
|
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.
|
|
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
|
-
}
|