@signaldb/svelte 2.0.0-beta.6 → 2.0.0-beta.7
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/dist/base/core/src/AsyncDataAdapter.d.ts +64 -0
- package/dist/base/core/src/AsyncDataAdapter.js +450 -0
- package/dist/base/core/src/AutoFetchDataAdapter.d.ts +112 -0
- package/dist/base/core/src/AutoFetchDataAdapter.js +652 -0
- package/dist/base/core/src/Collection/Cursor.d.ts +113 -0
- package/dist/base/core/src/Collection/Cursor.js +293 -0
- package/dist/base/core/src/Collection/Observer.d.ts +64 -0
- package/dist/base/core/src/Collection/Observer.js +181 -0
- package/dist/base/core/src/Collection/index.d.ts +294 -0
- package/dist/base/core/src/Collection/index.js +580 -0
- package/dist/base/core/src/Collection/types.d.ts +28 -0
- package/dist/base/core/src/Collection/types.js +2 -0
- package/dist/base/core/src/DataAdapter.d.ts +35 -0
- package/dist/base/core/src/DataAdapter.js +2 -0
- package/dist/base/core/src/DefaultDataAdapter.d.ts +35 -0
- package/dist/base/core/src/DefaultDataAdapter.js +398 -0
- package/dist/base/core/src/WorkerDataAdapter.d.ts +25 -0
- package/dist/base/core/src/WorkerDataAdapter.js +211 -0
- package/dist/base/core/src/WorkerDataAdapterHost.d.ts +62 -0
- package/dist/base/core/src/WorkerDataAdapterHost.js +409 -0
- package/dist/base/core/src/createIndex.d.ts +7 -0
- package/dist/base/core/src/createIndex.js +120 -0
- package/dist/base/core/src/createIndexProvider.d.ts +8 -0
- package/dist/base/core/src/createIndexProvider.js +11 -0
- package/dist/base/core/src/createReactivityAdapter.d.ts +8 -0
- package/dist/base/core/src/createReactivityAdapter.js +11 -0
- package/dist/base/core/src/createStorageAdapter.d.ts +9 -0
- package/dist/base/core/src/createStorageAdapter.js +11 -0
- package/dist/base/core/src/getIndexInfo.d.ts +39 -0
- package/dist/base/core/src/getIndexInfo.js +176 -0
- package/dist/base/core/src/index.d.ts +22 -0
- package/dist/base/core/src/index.js +39 -0
- package/dist/base/core/src/types/Dependency.d.ts +4 -0
- package/dist/base/core/src/types/Dependency.js +2 -0
- package/dist/base/core/src/types/IndexProvider.d.ts +26 -0
- package/dist/base/core/src/types/IndexProvider.js +2 -0
- package/dist/base/core/src/types/Modifier.d.ts +46 -0
- package/dist/base/core/src/types/Modifier.js +3 -0
- package/dist/base/core/src/types/ReactivityAdapter.d.ts +6 -0
- package/dist/base/core/src/types/ReactivityAdapter.js +2 -0
- package/dist/base/core/src/types/Selector.d.ts +46 -0
- package/dist/base/core/src/types/Selector.js +3 -0
- package/dist/base/core/src/types/Signal.d.ts +4 -0
- package/dist/base/core/src/types/Signal.js +2 -0
- package/dist/base/core/src/types/StorageAdapter.d.ts +20 -0
- package/dist/base/core/src/types/StorageAdapter.js +2 -0
- package/dist/base/core/src/utils/EventEmitter.d.ts +71 -0
- package/dist/base/core/src/utils/EventEmitter.js +144 -0
- package/dist/base/core/src/utils/batchOnNextTick.d.ts +16 -0
- package/dist/base/core/src/utils/batchOnNextTick.js +72 -0
- package/dist/base/core/src/utils/compact.d.ts +9 -0
- package/dist/base/core/src/utils/compact.js +21 -0
- package/dist/base/core/src/utils/createSignal.d.ts +14 -0
- package/dist/base/core/src/utils/createSignal.js +38 -0
- package/dist/base/core/src/utils/deepClone.d.ts +17 -0
- package/dist/base/core/src/utils/deepClone.js +68 -0
- package/dist/base/core/src/utils/get.d.ts +9 -0
- package/dist/base/core/src/utils/get.js +27 -0
- package/dist/base/core/src/utils/getMatchingKeys.d.ts +19 -0
- package/dist/base/core/src/utils/getMatchingKeys.js +49 -0
- package/dist/base/core/src/utils/intersection.d.ts +9 -0
- package/dist/base/core/src/utils/intersection.js +16 -0
- package/dist/base/core/src/utils/isEqual.d.ts +14 -0
- package/dist/base/core/src/utils/isEqual.js +43 -0
- package/dist/base/core/src/utils/isFieldExpression.d.ts +11 -0
- package/dist/base/core/src/utils/isFieldExpression.js +52 -0
- package/dist/base/core/src/utils/match.d.ts +12 -0
- package/dist/base/core/src/utils/match.js +16 -0
- package/dist/base/core/src/utils/modify.d.ts +14 -0
- package/dist/base/core/src/utils/modify.js +29 -0
- package/dist/base/core/src/utils/project.d.ts +15 -0
- package/dist/base/core/src/utils/project.js +43 -0
- package/dist/base/core/src/utils/queryId.d.ts +9 -0
- package/dist/base/core/src/utils/queryId.js +30 -0
- package/dist/base/core/src/utils/randomId.d.ts +7 -0
- package/dist/base/core/src/utils/randomId.js +12 -0
- package/dist/base/core/src/utils/reactiveOrAsync.d.ts +59 -0
- package/dist/base/core/src/utils/reactiveOrAsync.js +93 -0
- package/dist/base/core/src/utils/serializeValue.d.ts +12 -0
- package/dist/base/core/src/utils/serializeValue.js +27 -0
- package/dist/base/core/src/utils/set.d.ts +13 -0
- package/dist/base/core/src/utils/set.js +43 -0
- package/dist/base/core/src/utils/sortItems.d.ts +12 -0
- package/dist/base/core/src/utils/sortItems.js +23 -0
- package/dist/base/core/src/utils/uniqueBy.d.ts +10 -0
- package/dist/base/core/src/utils/uniqueBy.js +19 -0
- package/dist/reactivity-adapters/svelte/index.svelte.d.ts +10 -0
- package/dist/reactivity-adapters/svelte/index.svelte.js +36 -0
- package/package.json +3 -3
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* A strongly‑typed EventEmitter.
|
|
5
|
+
*/
|
|
6
|
+
class EventEmitter {
|
|
7
|
+
_maxListeners = 100;
|
|
8
|
+
/**
|
|
9
|
+
* We store a set of the listeners for each event.
|
|
10
|
+
*/
|
|
11
|
+
_listenerStore = new Map();
|
|
12
|
+
setMaxListeners(max) {
|
|
13
|
+
this._maxListeners = max;
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to an event with a listener function.
|
|
18
|
+
* @param eventName The event name (key of E).
|
|
19
|
+
* @param listener A function that receives the emitted arguments.
|
|
20
|
+
* @returns The emitter instance (for chaining).
|
|
21
|
+
*/
|
|
22
|
+
on(eventName, listener) {
|
|
23
|
+
// Get or create the Map for this particular event name.
|
|
24
|
+
let listenersSet = this._listenerStore.get(eventName);
|
|
25
|
+
if (!listenersSet) {
|
|
26
|
+
listenersSet = new Set();
|
|
27
|
+
this._listenerStore.set(eventName, listenersSet);
|
|
28
|
+
}
|
|
29
|
+
listenersSet.add(listener);
|
|
30
|
+
if (listenersSet.size > this._maxListeners) {
|
|
31
|
+
// eslint-disable-next-line no-console
|
|
32
|
+
console.warn(`Possible EventEmitter memory leak detected. ${listenersSet.size} ${String(eventName)} listeners added. Use emitter.setMaxListeners() to increase limit.`);
|
|
33
|
+
}
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Subscribe to an event with a listener function.
|
|
38
|
+
* @param eventName The event name (key of E).
|
|
39
|
+
* @param listener A function that receives the emitted arguments.
|
|
40
|
+
* @returns The emitter instance (for chaining).
|
|
41
|
+
*/
|
|
42
|
+
addListener(eventName, listener) {
|
|
43
|
+
return this.on(eventName, listener);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Subscribe to an event, handling it only once. Automatically removes
|
|
47
|
+
* the listener after it fires the first time.
|
|
48
|
+
* @param eventName The event name (key of E).
|
|
49
|
+
* @param listener A function that receives the emitted arguments.
|
|
50
|
+
* @returns The emitter instance (for chaining).
|
|
51
|
+
*/
|
|
52
|
+
once(eventName, listener) {
|
|
53
|
+
// We define a wrapper that calls the listener once, then unsubscribes itself.
|
|
54
|
+
const onceWrapper = ((...args) => {
|
|
55
|
+
listener(...args);
|
|
56
|
+
this.off(eventName, onceWrapper);
|
|
57
|
+
});
|
|
58
|
+
// Important: explicitly specify <K> to ensure TS sees the same type param
|
|
59
|
+
return this.on(eventName, onceWrapper);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Unsubscribe a previously subscribed listener.
|
|
63
|
+
* @param eventName The event name (key of E).
|
|
64
|
+
* @param listener The original function passed to `on` or `once`.
|
|
65
|
+
* @returns The emitter instance (for chaining).
|
|
66
|
+
*/
|
|
67
|
+
off(eventName, listener) {
|
|
68
|
+
const listenersSet = this._listenerStore.get(eventName);
|
|
69
|
+
if (!listenersSet)
|
|
70
|
+
return this;
|
|
71
|
+
listenersSet.delete(listener);
|
|
72
|
+
// Clean up if there are no more listeners for that event.
|
|
73
|
+
if (listenersSet.size === 0) {
|
|
74
|
+
this._listenerStore.delete(eventName);
|
|
75
|
+
}
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Unsubscribe a previously subscribed listener.
|
|
80
|
+
* @param eventName The event name (key of E).
|
|
81
|
+
* @param listener The original function passed to `on` or `once`.
|
|
82
|
+
* @returns The emitter instance (for chaining).
|
|
83
|
+
*/
|
|
84
|
+
removeListener(eventName, listener) {
|
|
85
|
+
return this.off(eventName, listener);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Emit (dispatch) an event with a variable number of arguments.
|
|
89
|
+
* @param eventName The event name (key of E).
|
|
90
|
+
* @param args The arguments to pass to subscribed listeners.
|
|
91
|
+
*/
|
|
92
|
+
emit(eventName, ...args) {
|
|
93
|
+
this.listeners(eventName).forEach((listener) => {
|
|
94
|
+
listener(...args);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Returns the array of listener functions currently registered for a given event.
|
|
99
|
+
* @param eventName The event name (key of E).
|
|
100
|
+
* @returns An array of listener functions.
|
|
101
|
+
*/
|
|
102
|
+
listeners(eventName) {
|
|
103
|
+
const listenersSet = this._listenerStore.get(eventName);
|
|
104
|
+
if (!listenersSet)
|
|
105
|
+
return [];
|
|
106
|
+
return [...listenersSet.values()];
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Returns the number of listeners for a given event.
|
|
110
|
+
* @param eventName The event name (key of E).
|
|
111
|
+
* @returns The number of listeners.
|
|
112
|
+
*/
|
|
113
|
+
listenerCount(eventName) {
|
|
114
|
+
const listenersSet = this._listenerStore.get(eventName);
|
|
115
|
+
return listenersSet ? listenersSet.size : 0;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Removes all listeners for a given event, or all events if none is specified.
|
|
119
|
+
* @param eventName Optional. If omitted, clears all events’ listeners.
|
|
120
|
+
* @returns The emitter instance (for chaining).
|
|
121
|
+
*/
|
|
122
|
+
removeAllListeners(eventName) {
|
|
123
|
+
if (eventName === undefined) {
|
|
124
|
+
// Remove listeners for all events
|
|
125
|
+
for (const [eventName_, listenersSet] of this._listenerStore.entries()) {
|
|
126
|
+
for (const listener of listenersSet.values()) {
|
|
127
|
+
this.off(eventName_, listener);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
this._listenerStore.clear();
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
const listenersSet = this._listenerStore.get(eventName);
|
|
134
|
+
if (listenersSet) {
|
|
135
|
+
for (const listener of listenersSet.values()) {
|
|
136
|
+
this.off(eventName, listener);
|
|
137
|
+
}
|
|
138
|
+
this._listenerStore.delete(eventName);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return this;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.default = EventEmitter;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Groups multiple calls by key and flushes them on the next tick (macrotask).
|
|
3
|
+
* @param onFlush - Function that will be called with the key and all queued items when flushing.
|
|
4
|
+
* @returns An object with `enqueue` and `flush` methods.
|
|
5
|
+
* @example
|
|
6
|
+
* const batcher = batchOnNextTick<string>(async (key, items) => {
|
|
7
|
+
* // items is an array of { args, resolve, reject }
|
|
8
|
+
* // do something once with all args...
|
|
9
|
+
* })
|
|
10
|
+
*
|
|
11
|
+
* batcher.enqueue("my-key", [arg1, arg2])
|
|
12
|
+
*/
|
|
13
|
+
export default function batchOnNextTick<TKey>(onFlush: (key: TKey, items: any[][]) => Promise<any[]>): {
|
|
14
|
+
enqueue: (key: TKey, args: any[]) => Promise<any>;
|
|
15
|
+
flush: (key: TKey) => Promise<void>;
|
|
16
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = batchOnNextTick;
|
|
4
|
+
/**
|
|
5
|
+
* Groups multiple calls by key and flushes them on the next tick (macrotask).
|
|
6
|
+
* @param onFlush - Function that will be called with the key and all queued items when flushing.
|
|
7
|
+
* @returns An object with `enqueue` and `flush` methods.
|
|
8
|
+
* @example
|
|
9
|
+
* const batcher = batchOnNextTick<string>(async (key, items) => {
|
|
10
|
+
* // items is an array of { args, resolve, reject }
|
|
11
|
+
* // do something once with all args...
|
|
12
|
+
* })
|
|
13
|
+
*
|
|
14
|
+
* batcher.enqueue("my-key", [arg1, arg2])
|
|
15
|
+
*/
|
|
16
|
+
function batchOnNextTick(onFlush) {
|
|
17
|
+
const queues = new Map();
|
|
18
|
+
/**
|
|
19
|
+
* Enqueue a call with the given key and arguments.
|
|
20
|
+
* @param key key to group calls
|
|
21
|
+
* @param args arguments for the call
|
|
22
|
+
* @returns A promise that resolves or rejects when the call is flushed.
|
|
23
|
+
*/
|
|
24
|
+
function enqueue(key, args) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
let q = queues.get(key);
|
|
27
|
+
if (!q) {
|
|
28
|
+
q = {
|
|
29
|
+
timer: null,
|
|
30
|
+
items: [],
|
|
31
|
+
flush: () => flush(key),
|
|
32
|
+
};
|
|
33
|
+
queues.set(key, q);
|
|
34
|
+
}
|
|
35
|
+
q.items.push({ args, resolve, reject });
|
|
36
|
+
if (q.timer == null) {
|
|
37
|
+
q.timer = setTimeout(() => {
|
|
38
|
+
q.timer = null;
|
|
39
|
+
void q.flush();
|
|
40
|
+
}, 0);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Flush the queue for the given key immediately.
|
|
46
|
+
* @param key key to flush
|
|
47
|
+
* @returns A promise that resolves when the flush is complete.
|
|
48
|
+
*/
|
|
49
|
+
async function flush(key) {
|
|
50
|
+
const q = queues.get(key);
|
|
51
|
+
if (!q || q.items.length === 0)
|
|
52
|
+
return;
|
|
53
|
+
if (q.timer != null) {
|
|
54
|
+
clearTimeout(q.timer);
|
|
55
|
+
q.timer = null;
|
|
56
|
+
}
|
|
57
|
+
const items = q.items.splice(0);
|
|
58
|
+
onFlush(key, items.map(i => i.args))
|
|
59
|
+
.then((results) => {
|
|
60
|
+
for (const [index, result] of results.entries()) {
|
|
61
|
+
const { resolve } = items[index];
|
|
62
|
+
resolve(result);
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.catch((error) => {
|
|
66
|
+
for (const { reject } of items) {
|
|
67
|
+
reject(error);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return { enqueue, flush };
|
|
72
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Truthy<T> = T extends false | '' | 0 | null | undefined ? never : T;
|
|
2
|
+
/**
|
|
3
|
+
* Filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) from an array.
|
|
4
|
+
* @template T - The type of the elements in the array.
|
|
5
|
+
* @param array - The array to filter.
|
|
6
|
+
* @returns A new array containing only the truthy values from the input array.
|
|
7
|
+
*/
|
|
8
|
+
export default function compact<T>(array: T[]): Truthy<T>[];
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = compact;
|
|
4
|
+
/**
|
|
5
|
+
* Checks if a value is truthy.
|
|
6
|
+
* @template T - The type of the value.
|
|
7
|
+
* @param value - The value to check.
|
|
8
|
+
* @returns A boolean indicating if the value is truthy.
|
|
9
|
+
*/
|
|
10
|
+
function truthy(value) {
|
|
11
|
+
return !!value;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Filters out falsy values (`false`, `''`, `0`, `null`, `undefined`) from an array.
|
|
15
|
+
* @template T - The type of the elements in the array.
|
|
16
|
+
* @param array - The array to filter.
|
|
17
|
+
* @returns A new array containing only the truthy values from the input array.
|
|
18
|
+
*/
|
|
19
|
+
function compact(array) {
|
|
20
|
+
return array.filter(truthy);
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type ReactivityAdapter from '../types/ReactivityAdapter';
|
|
2
|
+
import type Signal from '../types/Signal';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a reactive signal for managing state and triggering dependencies.
|
|
5
|
+
* The signal holds a value and provides methods to get and set the value,
|
|
6
|
+
* with optional equality checks and dependency tracking.
|
|
7
|
+
* @template T - The type of the value held by the signal.
|
|
8
|
+
* @param reactivityAdapter - An optional reactivity adapter for managing dependencies.
|
|
9
|
+
* @param initialValue - The initial value of the signal.
|
|
10
|
+
* @param isEqual - A custom equality function to determine if the new value is different
|
|
11
|
+
* from the current value (default is `Object.is`).
|
|
12
|
+
* @returns A signal object with `get` and `set` methods to manage the value.
|
|
13
|
+
*/
|
|
14
|
+
export default function createSignal<T>(reactivityAdapter: ReactivityAdapter | undefined, initialValue: T, isEqual?: (a: T, b: T) => boolean): Signal<T>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = createSignal;
|
|
4
|
+
/**
|
|
5
|
+
* Creates a reactive signal for managing state and triggering dependencies.
|
|
6
|
+
* The signal holds a value and provides methods to get and set the value,
|
|
7
|
+
* with optional equality checks and dependency tracking.
|
|
8
|
+
* @template T - The type of the value held by the signal.
|
|
9
|
+
* @param reactivityAdapter - An optional reactivity adapter for managing dependencies.
|
|
10
|
+
* @param initialValue - The initial value of the signal.
|
|
11
|
+
* @param isEqual - A custom equality function to determine if the new value is different
|
|
12
|
+
* from the current value (default is `Object.is`).
|
|
13
|
+
* @returns A signal object with `get` and `set` methods to manage the value.
|
|
14
|
+
*/
|
|
15
|
+
function createSignal(reactivityAdapter, initialValue, isEqual = Object.is) {
|
|
16
|
+
let value = initialValue;
|
|
17
|
+
const dependency = reactivityAdapter?.create();
|
|
18
|
+
const isInReactiveScope = () => {
|
|
19
|
+
if (!reactivityAdapter?.isInScope)
|
|
20
|
+
return true;
|
|
21
|
+
return reactivityAdapter.isInScope();
|
|
22
|
+
};
|
|
23
|
+
const signal = {
|
|
24
|
+
get() {
|
|
25
|
+
if (dependency && isInReactiveScope())
|
|
26
|
+
dependency.depend();
|
|
27
|
+
return value;
|
|
28
|
+
},
|
|
29
|
+
set(newValue) {
|
|
30
|
+
if (isEqual(value, newValue))
|
|
31
|
+
return;
|
|
32
|
+
value = newValue;
|
|
33
|
+
if (dependency)
|
|
34
|
+
dependency.notify();
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
return signal;
|
|
38
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performs a deep clone of a value, supporting various types including arrays, objects,
|
|
3
|
+
* Maps, Sets, Dates, and RegExps. Functions are not supported and will throw an error.
|
|
4
|
+
* @template T - The type of the value to clone.
|
|
5
|
+
* @param value - The value to deep clone.
|
|
6
|
+
* @returns A deep copy of the provided value.
|
|
7
|
+
* @throws {Error} An error if the value is a function, as cloning functions is not supported.
|
|
8
|
+
*/
|
|
9
|
+
export declare function clone<T>(value: T): T;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a deep clone of an object. Uses the `structuredClone` function if available,
|
|
12
|
+
* otherwise falls back to a manual deep clone implementation.
|
|
13
|
+
* @template T - The type of the object to clone.
|
|
14
|
+
* @param object - The object to deep clone.
|
|
15
|
+
* @returns A deep copy of the provided object.
|
|
16
|
+
*/
|
|
17
|
+
export default function deepClone<T>(object: T): T;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clone = clone;
|
|
4
|
+
exports.default = deepClone;
|
|
5
|
+
/**
|
|
6
|
+
* Performs a deep clone of a value, supporting various types including arrays, objects,
|
|
7
|
+
* Maps, Sets, Dates, and RegExps. Functions are not supported and will throw an error.
|
|
8
|
+
* @template T - The type of the value to clone.
|
|
9
|
+
* @param value - The value to deep clone.
|
|
10
|
+
* @returns A deep copy of the provided value.
|
|
11
|
+
* @throws {Error} An error if the value is a function, as cloning functions is not supported.
|
|
12
|
+
*/
|
|
13
|
+
function clone(value) {
|
|
14
|
+
// Functions
|
|
15
|
+
if (typeof value === 'function')
|
|
16
|
+
throw new Error('Cloning functions is not supported');
|
|
17
|
+
// Check for null or primitive types (string, number, boolean, etc.)
|
|
18
|
+
if (value === null || typeof value !== 'object')
|
|
19
|
+
return value;
|
|
20
|
+
// Dates
|
|
21
|
+
if (value instanceof Date)
|
|
22
|
+
return new Date(value);
|
|
23
|
+
// Arrays
|
|
24
|
+
if (Array.isArray(value))
|
|
25
|
+
return value.map(item => clone(item));
|
|
26
|
+
// Maps
|
|
27
|
+
if (value instanceof Map) {
|
|
28
|
+
const result = new Map();
|
|
29
|
+
value.forEach((currentValue, key) => {
|
|
30
|
+
result.set(key, clone(currentValue));
|
|
31
|
+
});
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
// Sets
|
|
35
|
+
if (value instanceof Set) {
|
|
36
|
+
const result = new Set();
|
|
37
|
+
value.forEach((currentValue) => {
|
|
38
|
+
result.add(clone(currentValue));
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
// RegExp
|
|
43
|
+
if (value instanceof RegExp)
|
|
44
|
+
return new RegExp(value);
|
|
45
|
+
// plain objects
|
|
46
|
+
const result = {};
|
|
47
|
+
for (const key in value) {
|
|
48
|
+
if (Object.hasOwnProperty.call(value, key)) {
|
|
49
|
+
result[key] = clone(value[key]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Creates a deep clone of an object. Uses the `structuredClone` function if available,
|
|
56
|
+
* otherwise falls back to a manual deep clone implementation.
|
|
57
|
+
* @template T - The type of the object to clone.
|
|
58
|
+
* @param object - The object to deep clone.
|
|
59
|
+
* @returns A deep copy of the provided object.
|
|
60
|
+
*/
|
|
61
|
+
function deepClone(object) {
|
|
62
|
+
// If structuredClone is available, use it
|
|
63
|
+
if (typeof structuredClone === 'function')
|
|
64
|
+
return structuredClone(object);
|
|
65
|
+
// Otherwise, perform a manual deep clone
|
|
66
|
+
/* istanbul ignore next -- @preserve */
|
|
67
|
+
return clone(object);
|
|
68
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieves the value at a specified path within an object.
|
|
3
|
+
* Supports dot and bracket notation for navigating nested properties.
|
|
4
|
+
* @template T - The type of the object to retrieve the value from.
|
|
5
|
+
* @param value - The object to navigate.
|
|
6
|
+
* @param path - The path (dot or bracket notation) to the desired value.
|
|
7
|
+
* @returns The value at the specified path, or `undefined` if the path does not exist.
|
|
8
|
+
*/
|
|
9
|
+
export default function get<T extends Record<string, any>>(value: T, path: string): any;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = get;
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves the value at a specified path within an object.
|
|
6
|
+
* Supports dot and bracket notation for navigating nested properties.
|
|
7
|
+
* @template T - The type of the object to retrieve the value from.
|
|
8
|
+
* @param value - The object to navigate.
|
|
9
|
+
* @param path - The path (dot or bracket notation) to the desired value.
|
|
10
|
+
* @returns The value at the specified path, or `undefined` if the path does not exist.
|
|
11
|
+
*/
|
|
12
|
+
function get(value, path) {
|
|
13
|
+
const normalized = path.replaceAll(/\[(\w+)\]/g, '.$1');
|
|
14
|
+
if (normalized.includes('..') || normalized.startsWith('.') || normalized.endsWith('.')) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const segments = normalized.split('.');
|
|
18
|
+
let current = value;
|
|
19
|
+
for (const key of segments) {
|
|
20
|
+
if (current == null)
|
|
21
|
+
return;
|
|
22
|
+
current = current[key];
|
|
23
|
+
}
|
|
24
|
+
if (current === undefined)
|
|
25
|
+
return;
|
|
26
|
+
return current;
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BaseItem } from '../Collection/types';
|
|
2
|
+
import type { FlatSelector } from '../types/Selector';
|
|
3
|
+
type KeyResult = {
|
|
4
|
+
include: (string | null)[] | null;
|
|
5
|
+
exclude: (string | null)[] | null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Extracts the matching and excluded keys for a given field in a selector.
|
|
9
|
+
* Supports serialized values and `$in`/`$nin` field expressions for optimization.
|
|
10
|
+
* Returns `null` for include/exclude if the field cannot be optimized.
|
|
11
|
+
* @template T - The type of the items in the selector.
|
|
12
|
+
* @template I - The type of the unique identifier for the items.
|
|
13
|
+
* @param field - The name of the field to extract matching keys for.
|
|
14
|
+
* @param selector - The selector object containing query criteria.
|
|
15
|
+
* @returns An object containing arrays of serialized included and excluded keys,
|
|
16
|
+
* or `null` if the field cannot be optimized.
|
|
17
|
+
*/
|
|
18
|
+
export default function getMatchingKeys<T extends BaseItem<I> = BaseItem, I = any>(field: string, selector: FlatSelector<T>): KeyResult;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = getMatchingKeys;
|
|
7
|
+
const isFieldExpression_1 = __importDefault(require("./isFieldExpression"));
|
|
8
|
+
const serializeValue_1 = __importDefault(require("./serializeValue"));
|
|
9
|
+
/**
|
|
10
|
+
* Extracts the matching and excluded keys for a given field in a selector.
|
|
11
|
+
* Supports serialized values and `$in`/`$nin` field expressions for optimization.
|
|
12
|
+
* Returns `null` for include/exclude if the field cannot be optimized.
|
|
13
|
+
* @template T - The type of the items in the selector.
|
|
14
|
+
* @template I - The type of the unique identifier for the items.
|
|
15
|
+
* @param field - The name of the field to extract matching keys for.
|
|
16
|
+
* @param selector - The selector object containing query criteria.
|
|
17
|
+
* @returns An object containing arrays of serialized included and excluded keys,
|
|
18
|
+
* or `null` if the field cannot be optimized.
|
|
19
|
+
*/
|
|
20
|
+
function getMatchingKeys(field, selector) {
|
|
21
|
+
const result = { include: null, exclude: null };
|
|
22
|
+
const fieldSelector = selector[field];
|
|
23
|
+
if (fieldSelector instanceof RegExp)
|
|
24
|
+
return result;
|
|
25
|
+
if (fieldSelector == null)
|
|
26
|
+
return result;
|
|
27
|
+
if ((0, isFieldExpression_1.default)(fieldSelector)) {
|
|
28
|
+
// Handle $ne operator
|
|
29
|
+
if (fieldSelector.$ne != null) {
|
|
30
|
+
result.exclude = [(0, serializeValue_1.default)(fieldSelector.$ne)];
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
// Handle $in operator
|
|
34
|
+
if (Array.isArray(fieldSelector.$in) && fieldSelector.$in.length > 0) {
|
|
35
|
+
result.include = fieldSelector.$in.map(serializeValue_1.default);
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
// Handle $nin operator
|
|
39
|
+
if (Array.isArray(fieldSelector.$nin) && fieldSelector.$nin.length > 0) {
|
|
40
|
+
result.exclude = fieldSelector.$nin.map(serializeValue_1.default);
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
// If there are other operators, we can't optimize
|
|
44
|
+
return { include: null, exclude: null };
|
|
45
|
+
}
|
|
46
|
+
// Direct value match
|
|
47
|
+
result.include = [(0, serializeValue_1.default)(fieldSelector)];
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes the intersection of multiple arrays, returning an array of unique elements
|
|
3
|
+
* that are present in all the input arrays.
|
|
4
|
+
* @template T - The type of elements in the arrays.
|
|
5
|
+
* @param arrays - A variable number of arrays to compute the intersection of.
|
|
6
|
+
* @returns An array containing the unique elements found in all the input arrays.
|
|
7
|
+
* - If no arrays are provided, returns an empty array.
|
|
8
|
+
*/
|
|
9
|
+
export default function intersection<T>(...arrays: T[][]): T[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = intersection;
|
|
4
|
+
/**
|
|
5
|
+
* Computes the intersection of multiple arrays, returning an array of unique elements
|
|
6
|
+
* that are present in all the input arrays.
|
|
7
|
+
* @template T - The type of elements in the arrays.
|
|
8
|
+
* @param arrays - A variable number of arrays to compute the intersection of.
|
|
9
|
+
* @returns An array containing the unique elements found in all the input arrays.
|
|
10
|
+
* - If no arrays are provided, returns an empty array.
|
|
11
|
+
*/
|
|
12
|
+
function intersection(...arrays) {
|
|
13
|
+
if (arrays.length === 0)
|
|
14
|
+
return [];
|
|
15
|
+
return [...new Set(arrays.reduce((a, b) => a.filter(c => b.includes(c))))];
|
|
16
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compares two values for deep equality.
|
|
3
|
+
* @param a - The first value to compare.
|
|
4
|
+
* @param b - The second value to compare.
|
|
5
|
+
* @returns - Returns `true` if the two values are deeply equal, otherwise `false`.
|
|
6
|
+
* @example
|
|
7
|
+
* isEqual({ a: 1 }, { a: 1 }); // true
|
|
8
|
+
* isEqual([1, 2], [1, 2]); // true
|
|
9
|
+
* isEqual(new Date(0), new Date(0)); // true
|
|
10
|
+
* isEqual(/abc/, /abc/); // true
|
|
11
|
+
* isEqual({ a: 1 }, { a: 2 }); // false
|
|
12
|
+
* isEqual(null, null); // true
|
|
13
|
+
*/
|
|
14
|
+
export default function isEqual<T, K>(a: T, b: K): boolean;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = isEqual;
|
|
4
|
+
/**
|
|
5
|
+
* Compares two values for deep equality.
|
|
6
|
+
* @param a - The first value to compare.
|
|
7
|
+
* @param b - The second value to compare.
|
|
8
|
+
* @returns - Returns `true` if the two values are deeply equal, otherwise `false`.
|
|
9
|
+
* @example
|
|
10
|
+
* isEqual({ a: 1 }, { a: 1 }); // true
|
|
11
|
+
* isEqual([1, 2], [1, 2]); // true
|
|
12
|
+
* isEqual(new Date(0), new Date(0)); // true
|
|
13
|
+
* isEqual(/abc/, /abc/); // true
|
|
14
|
+
* isEqual({ a: 1 }, { a: 2 }); // false
|
|
15
|
+
* isEqual(null, null); // true
|
|
16
|
+
*/
|
|
17
|
+
function isEqual(a, b) {
|
|
18
|
+
if (Object.is(a, b))
|
|
19
|
+
return true;
|
|
20
|
+
if (a instanceof RegExp && b instanceof RegExp)
|
|
21
|
+
return a.toString() === b.toString();
|
|
22
|
+
if (a instanceof Date && b instanceof Date)
|
|
23
|
+
return a.getTime() === b.getTime();
|
|
24
|
+
if (typeof a !== 'object')
|
|
25
|
+
return false;
|
|
26
|
+
if (typeof b !== 'object')
|
|
27
|
+
return false;
|
|
28
|
+
if (a === null)
|
|
29
|
+
return false;
|
|
30
|
+
if (b === null)
|
|
31
|
+
return false;
|
|
32
|
+
const aKeys = Object.keys(a);
|
|
33
|
+
const bKeys = Object.keys(b);
|
|
34
|
+
if (aKeys.length !== bKeys.length)
|
|
35
|
+
return false;
|
|
36
|
+
for (const key of aKeys) {
|
|
37
|
+
if (!bKeys.includes(key))
|
|
38
|
+
return false;
|
|
39
|
+
if (!isEqual(a[key], b[key]))
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FieldExpression } from '../types/Selector';
|
|
2
|
+
/**
|
|
3
|
+
* Determines whether a given object is a valid field expression.
|
|
4
|
+
* A field expression is an object containing query operators supported by MongoDB-style queries.
|
|
5
|
+
* @template T - The type of the field expression.
|
|
6
|
+
* @param expression - The object to test.
|
|
7
|
+
* @returns A boolean indicating whether the object is a valid field expression.
|
|
8
|
+
* - `true` if the object contains only recognized query operators.
|
|
9
|
+
* - `false` otherwise.
|
|
10
|
+
*/
|
|
11
|
+
export default function isFieldExpression<T>(expression: any): expression is FieldExpression<T>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = isFieldExpression;
|
|
4
|
+
const expressionKeys = new Set([
|
|
5
|
+
'$eq',
|
|
6
|
+
'$gt',
|
|
7
|
+
'$gte',
|
|
8
|
+
'$lt',
|
|
9
|
+
'$lte',
|
|
10
|
+
'$in',
|
|
11
|
+
'$nin',
|
|
12
|
+
'$ne',
|
|
13
|
+
'$exists',
|
|
14
|
+
'$not',
|
|
15
|
+
'$expr',
|
|
16
|
+
'$jsonSchema',
|
|
17
|
+
'$mod',
|
|
18
|
+
'$regex',
|
|
19
|
+
'$options',
|
|
20
|
+
'$text',
|
|
21
|
+
'$where',
|
|
22
|
+
'$all',
|
|
23
|
+
'$elemMatch',
|
|
24
|
+
'$size',
|
|
25
|
+
'$bitsAllClear',
|
|
26
|
+
'$bitsAllSet',
|
|
27
|
+
'$bitsAnyClear',
|
|
28
|
+
'$bitsAnySet',
|
|
29
|
+
]);
|
|
30
|
+
/**
|
|
31
|
+
* Determines whether a given object is a valid field expression.
|
|
32
|
+
* A field expression is an object containing query operators supported by MongoDB-style queries.
|
|
33
|
+
* @template T - The type of the field expression.
|
|
34
|
+
* @param expression - The object to test.
|
|
35
|
+
* @returns A boolean indicating whether the object is a valid field expression.
|
|
36
|
+
* - `true` if the object contains only recognized query operators.
|
|
37
|
+
* - `false` otherwise.
|
|
38
|
+
*/
|
|
39
|
+
function isFieldExpression(expression) {
|
|
40
|
+
if (typeof expression !== 'object' || expression == null) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const keys = Object.keys(expression);
|
|
44
|
+
if (keys.length === 0) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
const hasInvalidKeys = keys.some(key => !expressionKeys.has(key));
|
|
48
|
+
if (hasInvalidKeys)
|
|
49
|
+
return false;
|
|
50
|
+
const hasValidKeys = keys.every(key => expressionKeys.has(key));
|
|
51
|
+
return hasValidKeys;
|
|
52
|
+
}
|