@codebelt/classy-store 0.0.2 → 0.1.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/dist/index.cjs +8 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +15 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/index.mjs.map +1 -1
- package/dist/react/react.cjs +1 -1
- package/dist/react/react.mjs +1 -1
- package/dist/{snapshot-CR8nA2Ob.cjs → snapshot-BKVFJLuo.cjs} +24 -19
- package/dist/snapshot-BKVFJLuo.cjs.map +1 -0
- package/dist/{snapshot-C8JDLu8L.mjs → snapshot-P0QPV1ER.mjs} +19 -14
- package/dist/snapshot-P0QPV1ER.mjs.map +1 -0
- package/dist/utils/index.cjs +2 -2
- package/dist/utils/index.cjs.map +1 -1
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.mjs +2 -2
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/snapshot-C8JDLu8L.mjs.map +0 -1
- package/dist/snapshot-CR8nA2Ob.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_snapshot = require('./snapshot-
|
|
2
|
+
const require_snapshot = require('./snapshot-BKVFJLuo.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/collections/collections.ts
|
|
5
5
|
/**
|
|
6
|
-
* A Map-like class backed by a plain array so `
|
|
6
|
+
* A Map-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
7
7
|
*
|
|
8
8
|
* Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
9
9
|
* like `.set()` would be invisible to the store. `ReactiveMap` solves this by
|
|
@@ -11,7 +11,7 @@ const require_snapshot = require('./snapshot-CR8nA2Ob.cjs');
|
|
|
11
11
|
*
|
|
12
12
|
* Usage:
|
|
13
13
|
* ```ts
|
|
14
|
-
* const myStore =
|
|
14
|
+
* const myStore = createClassyStore({ users: reactiveMap<string, User>() });
|
|
15
15
|
* myStore.users.set('id1', { name: 'Alice' }); // reactive
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
@@ -80,7 +80,7 @@ var ReactiveMap = class {
|
|
|
80
80
|
}
|
|
81
81
|
};
|
|
82
82
|
/**
|
|
83
|
-
* A Set-like class backed by a plain array so `
|
|
83
|
+
* A Set-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
84
84
|
*
|
|
85
85
|
* Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
86
86
|
* like `.add()` would be invisible to the store. `ReactiveSet` solves this by
|
|
@@ -88,7 +88,7 @@ var ReactiveMap = class {
|
|
|
88
88
|
*
|
|
89
89
|
* Usage:
|
|
90
90
|
* ```ts
|
|
91
|
-
* const myStore =
|
|
91
|
+
* const myStore = createClassyStore({ tags: reactiveSet<string>(['urgent']) });
|
|
92
92
|
* myStore.tags.add('bug'); // reactive
|
|
93
93
|
* ```
|
|
94
94
|
*/
|
|
@@ -149,7 +149,7 @@ var ReactiveSet = class {
|
|
|
149
149
|
};
|
|
150
150
|
/**
|
|
151
151
|
* Creates a reactive Map-like collection backed by a plain array.
|
|
152
|
-
* Wrap the parent object with `
|
|
152
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
153
153
|
*
|
|
154
154
|
* @param initial - Optional iterable of `[key, value]` pairs.
|
|
155
155
|
*/
|
|
@@ -158,7 +158,7 @@ function reactiveMap(initial) {
|
|
|
158
158
|
}
|
|
159
159
|
/**
|
|
160
160
|
* Creates a reactive Set-like collection backed by a plain array.
|
|
161
|
-
* Wrap the parent object with `
|
|
161
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
162
162
|
*
|
|
163
163
|
* @param initial - Optional iterable of values.
|
|
164
164
|
*/
|
|
@@ -192,11 +192,11 @@ function shallowEqual(a, b) {
|
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
//#endregion
|
|
195
|
+
exports.createClassyStore = require_snapshot.createClassyStore;
|
|
195
196
|
exports.getVersion = require_snapshot.getVersion;
|
|
196
197
|
exports.reactiveMap = reactiveMap;
|
|
197
198
|
exports.reactiveSet = reactiveSet;
|
|
198
199
|
exports.shallowEqual = shallowEqual;
|
|
199
200
|
exports.snapshot = require_snapshot.snapshot;
|
|
200
|
-
exports.store = require_snapshot.store;
|
|
201
201
|
exports.subscribe = require_snapshot.subscribe;
|
|
202
202
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["PROXYABLE"],"sources":["../src/collections/collections.ts","../src/utils/equality/equality.ts"],"sourcesContent":["import {PROXYABLE} from '../utils/internal/internal';\n\n// ── ReactiveMap ───────────────────────────────────────────────────────────────\n\n/**\n * A Map-like class backed by a plain array so `store()` can proxy mutations.\n *\n * Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.set()` would be invisible to the store. `ReactiveMap` solves this by\n * storing entries in a plain array (`_entries`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = store({ users: reactiveMap<string, User>() });\n * myStore.users.set('id1', { name: 'Alice' }); // reactive\n * ```\n */\nexport class ReactiveMap<K, V> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _entries: [K, V][] = [];\n\n /** Deduplicates initial entries by key (last value wins, matching native `Map`). */\n constructor(initial?: Iterable<[K, V]>) {\n if (initial) {\n for (const [k, v] of initial) {\n const index = this._entries.findIndex(([ek]) => Object.is(ek, k));\n if (index !== -1) {\n this._entries[index] = [k, v];\n } else {\n this._entries.push([k, v]);\n }\n }\n }\n }\n\n /** Returns the number of entries. */\n get size(): number {\n return this._entries.length;\n }\n\n /** Returns the value for `key`, or `undefined`. O(n) linear scan. */\n get(key: K): V | undefined {\n const entry = this._entries.find(([k]) => Object.is(k, key));\n return entry ? entry[1] : undefined;\n }\n\n /** Returns `true` if `key` exists. O(n) linear scan. */\n has(key: K): boolean {\n return this._entries.some(([k]) => Object.is(k, key));\n }\n\n /** Sets `key` to `value`. Updates in-place if key exists, appends otherwise. */\n set(key: K, value: V): this {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index !== -1) {\n this._entries[index] = [key, value];\n } else {\n this._entries.push([key, value]);\n }\n return this;\n }\n\n /** Removes the entry for `key`. Returns `true` if found. */\n delete(key: K): boolean {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index === -1) return false;\n this._entries.splice(index, 1);\n return true;\n }\n\n /** Removes all entries. Uses splice to trigger proxy notification. */\n clear(): void {\n this._entries.splice(0, this._entries.length);\n }\n\n /** Returns an iterator over the keys. */\n keys(): IterableIterator<K> {\n return this._entries.map(([k]) => k)[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<V> {\n return this._entries.map(([, v]) => v)[Symbol.iterator]();\n }\n\n /** Returns an iterator over [key, value] pairs. */\n entries(): IterableIterator<[K, V]> {\n return this._entries.map(([k, v]) => [k, v] as [K, V])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each entry, matching the native `Map.forEach` signature. */\n forEach(callback: (value: V, key: K, map: ReactiveMap<K, V>) => void): void {\n for (const [k, v] of this._entries) {\n callback(v, k, this);\n }\n }\n\n /** Enables `for...of` iteration over [key, value] pairs. */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.entries();\n }\n}\n\n// ── ReactiveSet ───────────────────────────────────────────────────────────────\n\n/**\n * A Set-like class backed by a plain array so `store()` can proxy mutations.\n *\n * Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.add()` would be invisible to the store. `ReactiveSet` solves this by\n * storing items in a plain array (`_items`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = store({ tags: reactiveSet<string>(['urgent']) });\n * myStore.tags.add('bug'); // reactive\n * ```\n */\nexport class ReactiveSet<T> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _items: T[] = [];\n\n /** Deduplicates initial values using `Object.is` comparison. */\n constructor(initial?: Iterable<T>) {\n if (initial) {\n for (const v of initial) {\n if (!this._items.some((item) => Object.is(item, v))) {\n this._items.push(v);\n }\n }\n }\n }\n\n /** Returns the number of unique items. */\n get size(): number {\n return this._items.length;\n }\n\n /** Returns `true` if `value` exists. O(n) linear scan. */\n has(value: T): boolean {\n return this._items.some((item) => Object.is(item, value));\n }\n\n /** Adds `value` if not already present (no-op for duplicates). */\n add(value: T): this {\n if (!this.has(value)) {\n this._items.push(value);\n }\n return this;\n }\n\n /** Removes `value`. Returns `true` if found. */\n delete(value: T): boolean {\n const index = this._items.findIndex((item) => Object.is(item, value));\n if (index === -1) return false;\n this._items.splice(index, 1);\n return true;\n }\n\n /** Removes all items. Uses splice to trigger proxy notification. */\n clear(): void {\n this._items.splice(0, this._items.length);\n }\n\n /** Returns an iterator over the values (same as `values()`, matching Set API). */\n keys(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over [value, value] pairs, matching the native Set API. */\n entries(): IterableIterator<[T, T]> {\n return this._items.map((v) => [v, v] as [T, T])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each item, matching the native `Set.forEach` signature. */\n forEach(callback: (value: T, key: T, set: ReactiveSet<T>) => void): void {\n for (const v of this._items) {\n callback(v, v, this);\n }\n }\n\n /** Enables `for...of` iteration over values. */\n [Symbol.iterator](): IterableIterator<T> {\n return this.values();\n }\n}\n\n// ── Factory functions ─────────────────────────────────────────────────────────\n\n/**\n * Creates a reactive Map-like collection backed by a plain array.\n * Wrap the parent object with `store()` for full reactivity.\n *\n * @param initial - Optional iterable of `[key, value]` pairs.\n */\nexport function reactiveMap<K, V>(\n initial?: Iterable<[K, V]>,\n): ReactiveMap<K, V> {\n return new ReactiveMap(initial);\n}\n\n/**\n * Creates a reactive Set-like collection backed by a plain array.\n * Wrap the parent object with `store()` for full reactivity.\n *\n * @param initial - Optional iterable of values.\n */\nexport function reactiveSet<T>(initial?: Iterable<T>): ReactiveSet<T> {\n return new ReactiveSet(initial);\n}\n","/**\n * Shallow-equal comparison for objects and arrays.\n * Useful as a custom `isEqual` for `useStore` selectors that return objects/arrays.\n *\n * - Primitives compared with `Object.is`.\n * - Arrays: length + element-wise `Object.is`.\n * - Objects: key count + value-wise `Object.is`.\n */\nexport function shallowEqual<T>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== 'object' ||\n a === null ||\n typeof b !== 'object' ||\n b === null\n ) {\n return false;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n }\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (\n !Object.hasOwn(b, key) ||\n !Object.is(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n )\n ) {\n return false;\n }\n }\n return true;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["PROXYABLE"],"sources":["../src/collections/collections.ts","../src/utils/equality/equality.ts"],"sourcesContent":["import {PROXYABLE} from '../utils/internal/internal';\n\n// ── ReactiveMap ───────────────────────────────────────────────────────────────\n\n/**\n * A Map-like class backed by a plain array so `createClassyStore()` can proxy mutations.\n *\n * Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.set()` would be invisible to the store. `ReactiveMap` solves this by\n * storing entries in a plain array (`_entries`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = createClassyStore({ users: reactiveMap<string, User>() });\n * myStore.users.set('id1', { name: 'Alice' }); // reactive\n * ```\n */\nexport class ReactiveMap<K, V> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _entries: [K, V][] = [];\n\n /** Deduplicates initial entries by key (last value wins, matching native `Map`). */\n constructor(initial?: Iterable<[K, V]>) {\n if (initial) {\n for (const [k, v] of initial) {\n const index = this._entries.findIndex(([ek]) => Object.is(ek, k));\n if (index !== -1) {\n this._entries[index] = [k, v];\n } else {\n this._entries.push([k, v]);\n }\n }\n }\n }\n\n /** Returns the number of entries. */\n get size(): number {\n return this._entries.length;\n }\n\n /** Returns the value for `key`, or `undefined`. O(n) linear scan. */\n get(key: K): V | undefined {\n const entry = this._entries.find(([k]) => Object.is(k, key));\n return entry ? entry[1] : undefined;\n }\n\n /** Returns `true` if `key` exists. O(n) linear scan. */\n has(key: K): boolean {\n return this._entries.some(([k]) => Object.is(k, key));\n }\n\n /** Sets `key` to `value`. Updates in-place if key exists, appends otherwise. */\n set(key: K, value: V): this {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index !== -1) {\n this._entries[index] = [key, value];\n } else {\n this._entries.push([key, value]);\n }\n return this;\n }\n\n /** Removes the entry for `key`. Returns `true` if found. */\n delete(key: K): boolean {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index === -1) return false;\n this._entries.splice(index, 1);\n return true;\n }\n\n /** Removes all entries. Uses splice to trigger proxy notification. */\n clear(): void {\n this._entries.splice(0, this._entries.length);\n }\n\n /** Returns an iterator over the keys. */\n keys(): IterableIterator<K> {\n return this._entries.map(([k]) => k)[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<V> {\n return this._entries.map(([, v]) => v)[Symbol.iterator]();\n }\n\n /** Returns an iterator over [key, value] pairs. */\n entries(): IterableIterator<[K, V]> {\n return this._entries.map(([k, v]) => [k, v] as [K, V])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each entry, matching the native `Map.forEach` signature. */\n forEach(callback: (value: V, key: K, map: ReactiveMap<K, V>) => void): void {\n for (const [k, v] of this._entries) {\n callback(v, k, this);\n }\n }\n\n /** Enables `for...of` iteration over [key, value] pairs. */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.entries();\n }\n}\n\n// ── ReactiveSet ───────────────────────────────────────────────────────────────\n\n/**\n * A Set-like class backed by a plain array so `createClassyStore()` can proxy mutations.\n *\n * Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.add()` would be invisible to the store. `ReactiveSet` solves this by\n * storing items in a plain array (`_items`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = createClassyStore({ tags: reactiveSet<string>(['urgent']) });\n * myStore.tags.add('bug'); // reactive\n * ```\n */\nexport class ReactiveSet<T> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _items: T[] = [];\n\n /** Deduplicates initial values using `Object.is` comparison. */\n constructor(initial?: Iterable<T>) {\n if (initial) {\n for (const v of initial) {\n if (!this._items.some((item) => Object.is(item, v))) {\n this._items.push(v);\n }\n }\n }\n }\n\n /** Returns the number of unique items. */\n get size(): number {\n return this._items.length;\n }\n\n /** Returns `true` if `value` exists. O(n) linear scan. */\n has(value: T): boolean {\n return this._items.some((item) => Object.is(item, value));\n }\n\n /** Adds `value` if not already present (no-op for duplicates). */\n add(value: T): this {\n if (!this.has(value)) {\n this._items.push(value);\n }\n return this;\n }\n\n /** Removes `value`. Returns `true` if found. */\n delete(value: T): boolean {\n const index = this._items.findIndex((item) => Object.is(item, value));\n if (index === -1) return false;\n this._items.splice(index, 1);\n return true;\n }\n\n /** Removes all items. Uses splice to trigger proxy notification. */\n clear(): void {\n this._items.splice(0, this._items.length);\n }\n\n /** Returns an iterator over the values (same as `values()`, matching Set API). */\n keys(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over [value, value] pairs, matching the native Set API. */\n entries(): IterableIterator<[T, T]> {\n return this._items.map((v) => [v, v] as [T, T])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each item, matching the native `Set.forEach` signature. */\n forEach(callback: (value: T, key: T, set: ReactiveSet<T>) => void): void {\n for (const v of this._items) {\n callback(v, v, this);\n }\n }\n\n /** Enables `for...of` iteration over values. */\n [Symbol.iterator](): IterableIterator<T> {\n return this.values();\n }\n}\n\n// ── Factory functions ─────────────────────────────────────────────────────────\n\n/**\n * Creates a reactive Map-like collection backed by a plain array.\n * Wrap the parent object with `createClassyStore()` for full reactivity.\n *\n * @param initial - Optional iterable of `[key, value]` pairs.\n */\nexport function reactiveMap<K, V>(\n initial?: Iterable<[K, V]>,\n): ReactiveMap<K, V> {\n return new ReactiveMap(initial);\n}\n\n/**\n * Creates a reactive Set-like collection backed by a plain array.\n * Wrap the parent object with `createClassyStore()` for full reactivity.\n *\n * @param initial - Optional iterable of values.\n */\nexport function reactiveSet<T>(initial?: Iterable<T>): ReactiveSet<T> {\n return new ReactiveSet(initial);\n}\n","/**\n * Shallow-equal comparison for objects and arrays.\n * Useful as a custom `isEqual` for `useStore` selectors that return objects/arrays.\n *\n * - Primitives compared with `Object.is`.\n * - Arrays: length + element-wise `Object.is`.\n * - Objects: key count + value-wise `Object.is`.\n */\nexport function shallowEqual<T>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== 'object' ||\n a === null ||\n typeof b !== 'object' ||\n b === null\n ) {\n return false;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n }\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (\n !Object.hasOwn(b, key) ||\n !Object.is(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n )\n ) {\n return false;\n }\n }\n return true;\n}\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -10,7 +10,7 @@ declare const PROXYABLE: unique symbol;
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/collections/collections.d.ts
|
|
12
12
|
/**
|
|
13
|
-
* A Map-like class backed by a plain array so `
|
|
13
|
+
* A Map-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
14
14
|
*
|
|
15
15
|
* Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
16
16
|
* like `.set()` would be invisible to the store. `ReactiveMap` solves this by
|
|
@@ -18,7 +18,7 @@ declare const PROXYABLE: unique symbol;
|
|
|
18
18
|
*
|
|
19
19
|
* Usage:
|
|
20
20
|
* ```ts
|
|
21
|
-
* const myStore =
|
|
21
|
+
* const myStore = createClassyStore({ users: reactiveMap<string, User>() });
|
|
22
22
|
* myStore.users.set('id1', { name: 'Alice' }); // reactive
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
@@ -52,7 +52,7 @@ declare class ReactiveMap<K, V> {
|
|
|
52
52
|
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* A Set-like class backed by a plain array so `
|
|
55
|
+
* A Set-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
56
56
|
*
|
|
57
57
|
* Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
58
58
|
* like `.add()` would be invisible to the store. `ReactiveSet` solves this by
|
|
@@ -60,7 +60,7 @@ declare class ReactiveMap<K, V> {
|
|
|
60
60
|
*
|
|
61
61
|
* Usage:
|
|
62
62
|
* ```ts
|
|
63
|
-
* const myStore =
|
|
63
|
+
* const myStore = createClassyStore({ tags: reactiveSet<string>(['urgent']) });
|
|
64
64
|
* myStore.tags.add('bug'); // reactive
|
|
65
65
|
* ```
|
|
66
66
|
*/
|
|
@@ -93,14 +93,14 @@ declare class ReactiveSet<T> {
|
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* Creates a reactive Map-like collection backed by a plain array.
|
|
96
|
-
* Wrap the parent object with `
|
|
96
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
97
97
|
*
|
|
98
98
|
* @param initial - Optional iterable of `[key, value]` pairs.
|
|
99
99
|
*/
|
|
100
100
|
declare function reactiveMap<K, V>(initial?: Iterable<[K, V]>): ReactiveMap<K, V>;
|
|
101
101
|
/**
|
|
102
102
|
* Creates a reactive Set-like collection backed by a plain array.
|
|
103
|
-
* Wrap the parent object with `
|
|
103
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
104
104
|
*
|
|
105
105
|
* @param initial - Optional iterable of values.
|
|
106
106
|
*/
|
|
@@ -118,13 +118,18 @@ declare function reactiveSet<T>(initial?: Iterable<T>): ReactiveSet<T>;
|
|
|
118
118
|
*
|
|
119
119
|
* @param instance - A class instance (or plain object) to make reactive.
|
|
120
120
|
* @returns The same object wrapped in a reactive Proxy.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* const myStore = createClassyStore(new MyClass());
|
|
125
|
+
* ```
|
|
121
126
|
*/
|
|
122
|
-
declare function
|
|
127
|
+
declare function createClassyStore<T extends object>(instance: T): T;
|
|
123
128
|
/**
|
|
124
129
|
* Subscribe to store changes. The callback fires once per batched mutation
|
|
125
130
|
* (coalesced via `queueMicrotask`), not once per individual property write.
|
|
126
131
|
*
|
|
127
|
-
* @param proxy - A reactive proxy created by `
|
|
132
|
+
* @param proxy - A reactive proxy created by `createClassyStore()`.
|
|
128
133
|
* @param callback - Invoked after each batched mutation.
|
|
129
134
|
* @returns An unsubscribe function. Call it to stop receiving notifications.
|
|
130
135
|
*/
|
|
@@ -152,7 +157,7 @@ declare function getVersion(proxy: object): number;
|
|
|
152
157
|
* per snapshot and their results are stable across snapshots when dependencies
|
|
153
158
|
* haven't changed (cross-snapshot memoization).
|
|
154
159
|
*
|
|
155
|
-
* @param proxyStore - A reactive proxy created by `
|
|
160
|
+
* @param proxyStore - A reactive proxy created by `createClassyStore()`.
|
|
156
161
|
* @returns A deeply frozen plain-JS object (Snapshot<T>).
|
|
157
162
|
*/
|
|
158
163
|
declare function snapshot<T extends object>(proxyStore: T): Snapshot<T>;
|
|
@@ -168,5 +173,5 @@ declare function snapshot<T extends object>(proxyStore: T): Snapshot<T>;
|
|
|
168
173
|
*/
|
|
169
174
|
declare function shallowEqual<T>(a: T, b: T): boolean;
|
|
170
175
|
//#endregion
|
|
171
|
-
export { type ReactiveMap, type ReactiveSet, type Snapshot, getVersion, reactiveMap, reactiveSet, shallowEqual, snapshot,
|
|
176
|
+
export { type ReactiveMap, type ReactiveSet, type Snapshot, createClassyStore, getVersion, reactiveMap, reactiveSet, shallowEqual, snapshot, subscribe };
|
|
172
177
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/utils/internal/internal.ts","../src/collections/collections.ts","../src/core/core.ts","../src/snapshot/snapshot.ts","../src/utils/equality/equality.ts"],"mappings":";;;;;;AAOA;;cAAa,SAAA;;;;;AAAb;;;;;;;;ACUA;;;cAAa,WAAA;EAAA,QACH,SAAA;EAGM;EAAd,QAAA,GAAW,CAAA,EAAG,CAAA;EAGqB;cAAvB,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA;EAmB1B;EAAA,IALL,IAAA,CAAA;EAWK;EANT,GAAA,CAAI,GAAA,EAAK,CAAA,GAAI,CAAA;EAWM;EALnB,GAAA,CAAI,GAAA,EAAK,CAAA;EA6BgB;EAxBzB,GAAA,CAAI,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,CAAA;EA6BQ;EAlB3B,MAAA,CAAO,GAAA,EAAK,CAAA;EAuBiB;EAf7B,KAAA,CAAA;EAeW;EAVX,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EAeS;EAVlC,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EAU8B;EALzD,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EAYO;EAPvC,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA,EAAG,CAAA;EAOpC;EAAA,CAApB,MAAA,CAAO,QAAA,KAAa,gBAAA,EAAkB,CAAA,EAAG,CAAA;AAAA;;;;;;;;;;;;;;cAoB/B,WAAA;EAAA,QACH,SAAA;EA9EJ;EAiFJ,MAAA,EAAQ,CAAA;EA3ER;cA8EY,OAAA,GAAU,QAAA,CAAS,CAAA;EA9E3B;EAAA,IAyFA,IAAA,CAAA;EApFK;EAyFT,GAAA,CAAI,KAAA,EAAO,CAAA;EAzFQ;EA8FnB,GAAA,CAAI,KAAA,EAAO,CAAA;EAnFX;EA2FA,MAAA,CAAO,KAAA,EAAO,CAAA;EA3FP;EAmGP,KAAA,CAAA;EAtFA;EA2FA,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EA3FA;EAgGzB,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EA3FjB;EAgGV,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EA3FhC;EAgGA,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA;EAhGzB;EAAA,CAuG5B,MAAA,CAAO,QAAA,KAAa,gBAAA,CAAiB,CAAA;AAAA;;;;;;;iBAaxB,WAAA,MAAA,CACd,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA,KACtB,WAAA,CAAY,CAAA,EAAG,CAAA;;;;;;;iBAUF,WAAA,GAAA,CAAe,OAAA,GAAU,QAAA,CAAS,CAAA,IAAK,WAAA,CAAY,CAAA
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/utils/internal/internal.ts","../src/collections/collections.ts","../src/core/core.ts","../src/snapshot/snapshot.ts","../src/utils/equality/equality.ts"],"mappings":";;;;;;AAOA;;cAAa,SAAA;;;;;AAAb;;;;;;;;ACUA;;;cAAa,WAAA;EAAA,QACH,SAAA;EAGM;EAAd,QAAA,GAAW,CAAA,EAAG,CAAA;EAGqB;cAAvB,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA;EAmB1B;EAAA,IALL,IAAA,CAAA;EAWK;EANT,GAAA,CAAI,GAAA,EAAK,CAAA,GAAI,CAAA;EAWM;EALnB,GAAA,CAAI,GAAA,EAAK,CAAA;EA6BgB;EAxBzB,GAAA,CAAI,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,CAAA;EA6BQ;EAlB3B,MAAA,CAAO,GAAA,EAAK,CAAA;EAuBiB;EAf7B,KAAA,CAAA;EAeW;EAVX,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EAeS;EAVlC,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EAU8B;EALzD,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EAYO;EAPvC,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA,EAAG,CAAA;EAOpC;EAAA,CAApB,MAAA,CAAO,QAAA,KAAa,gBAAA,EAAkB,CAAA,EAAG,CAAA;AAAA;;;;;;;;;;;;;;cAoB/B,WAAA;EAAA,QACH,SAAA;EA9EJ;EAiFJ,MAAA,EAAQ,CAAA;EA3ER;cA8EY,OAAA,GAAU,QAAA,CAAS,CAAA;EA9E3B;EAAA,IAyFA,IAAA,CAAA;EApFK;EAyFT,GAAA,CAAI,KAAA,EAAO,CAAA;EAzFQ;EA8FnB,GAAA,CAAI,KAAA,EAAO,CAAA;EAnFX;EA2FA,MAAA,CAAO,KAAA,EAAO,CAAA;EA3FP;EAmGP,KAAA,CAAA;EAtFA;EA2FA,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EA3FA;EAgGzB,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EA3FjB;EAgGV,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EA3FhC;EAgGA,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA;EAhGzB;EAAA,CAuG5B,MAAA,CAAO,QAAA,KAAa,gBAAA,CAAiB,CAAA;AAAA;;;;;;;iBAaxB,WAAA,MAAA,CACd,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA,KACtB,WAAA,CAAY,CAAA,EAAG,CAAA;;;;;;;iBAUF,WAAA,GAAA,CAAe,OAAA,GAAU,QAAA,CAAS,CAAA,IAAK,WAAA,CAAY,CAAA;;;;;;;;AAvMnE;;;;;;;;;;;;iBCiRgB,iBAAA,kBAAA,CAAoC,QAAA,EAAU,CAAA,GAAI,CAAA;;;;;;;;;iBAYlD,SAAA,CAAU,KAAA,UAAe,QAAA;;;;;;;;iBAkBzB,UAAA,CAAW,KAAA;;;;;AFzT3B;;;;;;;;ACUA;;;;;;iBEwUgB,QAAA,kBAAA,CAA2B,UAAA,EAAY,CAAA,GAAI,QAAA,CAAS,CAAA;;;;;;AHlVpE;;;;;iBICgB,YAAA,GAAA,CAAgB,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -10,7 +10,7 @@ declare const PROXYABLE: unique symbol;
|
|
|
10
10
|
//#endregion
|
|
11
11
|
//#region src/collections/collections.d.ts
|
|
12
12
|
/**
|
|
13
|
-
* A Map-like class backed by a plain array so `
|
|
13
|
+
* A Map-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
14
14
|
*
|
|
15
15
|
* Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
16
16
|
* like `.set()` would be invisible to the store. `ReactiveMap` solves this by
|
|
@@ -18,7 +18,7 @@ declare const PROXYABLE: unique symbol;
|
|
|
18
18
|
*
|
|
19
19
|
* Usage:
|
|
20
20
|
* ```ts
|
|
21
|
-
* const myStore =
|
|
21
|
+
* const myStore = createClassyStore({ users: reactiveMap<string, User>() });
|
|
22
22
|
* myStore.users.set('id1', { name: 'Alice' }); // reactive
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
@@ -52,7 +52,7 @@ declare class ReactiveMap<K, V> {
|
|
|
52
52
|
[Symbol.iterator](): IterableIterator<[K, V]>;
|
|
53
53
|
}
|
|
54
54
|
/**
|
|
55
|
-
* A Set-like class backed by a plain array so `
|
|
55
|
+
* A Set-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
56
56
|
*
|
|
57
57
|
* Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
58
58
|
* like `.add()` would be invisible to the store. `ReactiveSet` solves this by
|
|
@@ -60,7 +60,7 @@ declare class ReactiveMap<K, V> {
|
|
|
60
60
|
*
|
|
61
61
|
* Usage:
|
|
62
62
|
* ```ts
|
|
63
|
-
* const myStore =
|
|
63
|
+
* const myStore = createClassyStore({ tags: reactiveSet<string>(['urgent']) });
|
|
64
64
|
* myStore.tags.add('bug'); // reactive
|
|
65
65
|
* ```
|
|
66
66
|
*/
|
|
@@ -93,14 +93,14 @@ declare class ReactiveSet<T> {
|
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* Creates a reactive Map-like collection backed by a plain array.
|
|
96
|
-
* Wrap the parent object with `
|
|
96
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
97
97
|
*
|
|
98
98
|
* @param initial - Optional iterable of `[key, value]` pairs.
|
|
99
99
|
*/
|
|
100
100
|
declare function reactiveMap<K, V>(initial?: Iterable<[K, V]>): ReactiveMap<K, V>;
|
|
101
101
|
/**
|
|
102
102
|
* Creates a reactive Set-like collection backed by a plain array.
|
|
103
|
-
* Wrap the parent object with `
|
|
103
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
104
104
|
*
|
|
105
105
|
* @param initial - Optional iterable of values.
|
|
106
106
|
*/
|
|
@@ -118,13 +118,18 @@ declare function reactiveSet<T>(initial?: Iterable<T>): ReactiveSet<T>;
|
|
|
118
118
|
*
|
|
119
119
|
* @param instance - A class instance (or plain object) to make reactive.
|
|
120
120
|
* @returns The same object wrapped in a reactive Proxy.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* const myStore = createClassyStore(new MyClass());
|
|
125
|
+
* ```
|
|
121
126
|
*/
|
|
122
|
-
declare function
|
|
127
|
+
declare function createClassyStore<T extends object>(instance: T): T;
|
|
123
128
|
/**
|
|
124
129
|
* Subscribe to store changes. The callback fires once per batched mutation
|
|
125
130
|
* (coalesced via `queueMicrotask`), not once per individual property write.
|
|
126
131
|
*
|
|
127
|
-
* @param proxy - A reactive proxy created by `
|
|
132
|
+
* @param proxy - A reactive proxy created by `createClassyStore()`.
|
|
128
133
|
* @param callback - Invoked after each batched mutation.
|
|
129
134
|
* @returns An unsubscribe function. Call it to stop receiving notifications.
|
|
130
135
|
*/
|
|
@@ -152,7 +157,7 @@ declare function getVersion(proxy: object): number;
|
|
|
152
157
|
* per snapshot and their results are stable across snapshots when dependencies
|
|
153
158
|
* haven't changed (cross-snapshot memoization).
|
|
154
159
|
*
|
|
155
|
-
* @param proxyStore - A reactive proxy created by `
|
|
160
|
+
* @param proxyStore - A reactive proxy created by `createClassyStore()`.
|
|
156
161
|
* @returns A deeply frozen plain-JS object (Snapshot<T>).
|
|
157
162
|
*/
|
|
158
163
|
declare function snapshot<T extends object>(proxyStore: T): Snapshot<T>;
|
|
@@ -168,5 +173,5 @@ declare function snapshot<T extends object>(proxyStore: T): Snapshot<T>;
|
|
|
168
173
|
*/
|
|
169
174
|
declare function shallowEqual<T>(a: T, b: T): boolean;
|
|
170
175
|
//#endregion
|
|
171
|
-
export { type ReactiveMap, type ReactiveSet, type Snapshot, getVersion, reactiveMap, reactiveSet, shallowEqual, snapshot,
|
|
176
|
+
export { type ReactiveMap, type ReactiveSet, type Snapshot, createClassyStore, getVersion, reactiveMap, reactiveSet, shallowEqual, snapshot, subscribe };
|
|
172
177
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/utils/internal/internal.ts","../src/collections/collections.ts","../src/core/core.ts","../src/snapshot/snapshot.ts","../src/utils/equality/equality.ts"],"mappings":";;;;;;AAOA;;cAAa,SAAA;;;;;AAAb;;;;;;;;ACUA;;;cAAa,WAAA;EAAA,QACH,SAAA;EAGM;EAAd,QAAA,GAAW,CAAA,EAAG,CAAA;EAGqB;cAAvB,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA;EAmB1B;EAAA,IALL,IAAA,CAAA;EAWK;EANT,GAAA,CAAI,GAAA,EAAK,CAAA,GAAI,CAAA;EAWM;EALnB,GAAA,CAAI,GAAA,EAAK,CAAA;EA6BgB;EAxBzB,GAAA,CAAI,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,CAAA;EA6BQ;EAlB3B,MAAA,CAAO,GAAA,EAAK,CAAA;EAuBiB;EAf7B,KAAA,CAAA;EAeW;EAVX,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EAeS;EAVlC,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EAU8B;EALzD,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EAYO;EAPvC,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA,EAAG,CAAA;EAOpC;EAAA,CAApB,MAAA,CAAO,QAAA,KAAa,gBAAA,EAAkB,CAAA,EAAG,CAAA;AAAA;;;;;;;;;;;;;;cAoB/B,WAAA;EAAA,QACH,SAAA;EA9EJ;EAiFJ,MAAA,EAAQ,CAAA;EA3ER;cA8EY,OAAA,GAAU,QAAA,CAAS,CAAA;EA9E3B;EAAA,IAyFA,IAAA,CAAA;EApFK;EAyFT,GAAA,CAAI,KAAA,EAAO,CAAA;EAzFQ;EA8FnB,GAAA,CAAI,KAAA,EAAO,CAAA;EAnFX;EA2FA,MAAA,CAAO,KAAA,EAAO,CAAA;EA3FP;EAmGP,KAAA,CAAA;EAtFA;EA2FA,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EA3FA;EAgGzB,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EA3FjB;EAgGV,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EA3FhC;EAgGA,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA;EAhGzB;EAAA,CAuG5B,MAAA,CAAO,QAAA,KAAa,gBAAA,CAAiB,CAAA;AAAA;;;;;;;iBAaxB,WAAA,MAAA,CACd,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA,KACtB,WAAA,CAAY,CAAA,EAAG,CAAA;;;;;;;iBAUF,WAAA,GAAA,CAAe,OAAA,GAAU,QAAA,CAAS,CAAA,IAAK,WAAA,CAAY,CAAA
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/utils/internal/internal.ts","../src/collections/collections.ts","../src/core/core.ts","../src/snapshot/snapshot.ts","../src/utils/equality/equality.ts"],"mappings":";;;;;;AAOA;;cAAa,SAAA;;;;;AAAb;;;;;;;;ACUA;;;cAAa,WAAA;EAAA,QACH,SAAA;EAGM;EAAd,QAAA,GAAW,CAAA,EAAG,CAAA;EAGqB;cAAvB,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA;EAmB1B;EAAA,IALL,IAAA,CAAA;EAWK;EANT,GAAA,CAAI,GAAA,EAAK,CAAA,GAAI,CAAA;EAWM;EALnB,GAAA,CAAI,GAAA,EAAK,CAAA;EA6BgB;EAxBzB,GAAA,CAAI,GAAA,EAAK,CAAA,EAAG,KAAA,EAAO,CAAA;EA6BQ;EAlB3B,MAAA,CAAO,GAAA,EAAK,CAAA;EAuBiB;EAf7B,KAAA,CAAA;EAeW;EAVX,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EAeS;EAVlC,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EAU8B;EALzD,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EAYO;EAPvC,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA,EAAG,CAAA;EAOpC;EAAA,CAApB,MAAA,CAAO,QAAA,KAAa,gBAAA,EAAkB,CAAA,EAAG,CAAA;AAAA;;;;;;;;;;;;;;cAoB/B,WAAA;EAAA,QACH,SAAA;EA9EJ;EAiFJ,MAAA,EAAQ,CAAA;EA3ER;cA8EY,OAAA,GAAU,QAAA,CAAS,CAAA;EA9E3B;EAAA,IAyFA,IAAA,CAAA;EApFK;EAyFT,GAAA,CAAI,KAAA,EAAO,CAAA;EAzFQ;EA8FnB,GAAA,CAAI,KAAA,EAAO,CAAA;EAnFX;EA2FA,MAAA,CAAO,KAAA,EAAO,CAAA;EA3FP;EAmGP,KAAA,CAAA;EAtFA;EA2FA,IAAA,CAAA,GAAQ,gBAAA,CAAiB,CAAA;EA3FA;EAgGzB,MAAA,CAAA,GAAU,gBAAA,CAAiB,CAAA;EA3FjB;EAgGV,OAAA,CAAA,GAAW,gBAAA,EAAkB,CAAA,EAAG,CAAA;EA3FhC;EAgGA,OAAA,CAAQ,QAAA,GAAW,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,CAAA,EAAG,GAAA,EAAK,WAAA,CAAY,CAAA;EAhGzB;EAAA,CAuG5B,MAAA,CAAO,QAAA,KAAa,gBAAA,CAAiB,CAAA;AAAA;;;;;;;iBAaxB,WAAA,MAAA,CACd,OAAA,GAAU,QAAA,EAAU,CAAA,EAAG,CAAA,KACtB,WAAA,CAAY,CAAA,EAAG,CAAA;;;;;;;iBAUF,WAAA,GAAA,CAAe,OAAA,GAAU,QAAA,CAAS,CAAA,IAAK,WAAA,CAAY,CAAA;;;;;;;;AAvMnE;;;;;;;;;;;;iBCiRgB,iBAAA,kBAAA,CAAoC,QAAA,EAAU,CAAA,GAAI,CAAA;;;;;;;;;iBAYlD,SAAA,CAAU,KAAA,UAAe,QAAA;;;;;;;;iBAkBzB,UAAA,CAAW,KAAA;;;;;AFzT3B;;;;;;;;ACUA;;;;;;iBEwUgB,QAAA,kBAAA,CAA2B,UAAA,EAAY,CAAA,GAAI,QAAA,CAAS,CAAA;;;;;;AHlVpE;;;;;iBICgB,YAAA,GAAA,CAAgB,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { a as subscribe, i as
|
|
1
|
+
import { a as subscribe, i as getVersion, n as createClassyStore, o as PROXYABLE, t as snapshot } from "./snapshot-P0QPV1ER.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/collections/collections.ts
|
|
4
4
|
/**
|
|
5
|
-
* A Map-like class backed by a plain array so `
|
|
5
|
+
* A Map-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
6
6
|
*
|
|
7
7
|
* Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
8
8
|
* like `.set()` would be invisible to the store. `ReactiveMap` solves this by
|
|
@@ -10,7 +10,7 @@ import { a as subscribe, i as store, o as PROXYABLE, r as getVersion, t as snaps
|
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
12
|
* ```ts
|
|
13
|
-
* const myStore =
|
|
13
|
+
* const myStore = createClassyStore({ users: reactiveMap<string, User>() });
|
|
14
14
|
* myStore.users.set('id1', { name: 'Alice' }); // reactive
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
@@ -79,7 +79,7 @@ var ReactiveMap = class {
|
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
81
|
/**
|
|
82
|
-
* A Set-like class backed by a plain array so `
|
|
82
|
+
* A Set-like class backed by a plain array so `createClassyStore()` can proxy mutations.
|
|
83
83
|
*
|
|
84
84
|
* Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations
|
|
85
85
|
* like `.add()` would be invisible to the store. `ReactiveSet` solves this by
|
|
@@ -87,7 +87,7 @@ var ReactiveMap = class {
|
|
|
87
87
|
*
|
|
88
88
|
* Usage:
|
|
89
89
|
* ```ts
|
|
90
|
-
* const myStore =
|
|
90
|
+
* const myStore = createClassyStore({ tags: reactiveSet<string>(['urgent']) });
|
|
91
91
|
* myStore.tags.add('bug'); // reactive
|
|
92
92
|
* ```
|
|
93
93
|
*/
|
|
@@ -148,7 +148,7 @@ var ReactiveSet = class {
|
|
|
148
148
|
};
|
|
149
149
|
/**
|
|
150
150
|
* Creates a reactive Map-like collection backed by a plain array.
|
|
151
|
-
* Wrap the parent object with `
|
|
151
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
152
152
|
*
|
|
153
153
|
* @param initial - Optional iterable of `[key, value]` pairs.
|
|
154
154
|
*/
|
|
@@ -157,7 +157,7 @@ function reactiveMap(initial) {
|
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
159
|
* Creates a reactive Set-like collection backed by a plain array.
|
|
160
|
-
* Wrap the parent object with `
|
|
160
|
+
* Wrap the parent object with `createClassyStore()` for full reactivity.
|
|
161
161
|
*
|
|
162
162
|
* @param initial - Optional iterable of values.
|
|
163
163
|
*/
|
|
@@ -191,5 +191,5 @@ function shallowEqual(a, b) {
|
|
|
191
191
|
}
|
|
192
192
|
|
|
193
193
|
//#endregion
|
|
194
|
-
export { getVersion, reactiveMap, reactiveSet, shallowEqual, snapshot,
|
|
194
|
+
export { createClassyStore, getVersion, reactiveMap, reactiveSet, shallowEqual, snapshot, subscribe };
|
|
195
195
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/collections/collections.ts","../src/utils/equality/equality.ts"],"sourcesContent":["import {PROXYABLE} from '../utils/internal/internal';\n\n// ── ReactiveMap ───────────────────────────────────────────────────────────────\n\n/**\n * A Map-like class backed by a plain array so `store()` can proxy mutations.\n *\n * Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.set()` would be invisible to the store. `ReactiveMap` solves this by\n * storing entries in a plain array (`_entries`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = store({ users: reactiveMap<string, User>() });\n * myStore.users.set('id1', { name: 'Alice' }); // reactive\n * ```\n */\nexport class ReactiveMap<K, V> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _entries: [K, V][] = [];\n\n /** Deduplicates initial entries by key (last value wins, matching native `Map`). */\n constructor(initial?: Iterable<[K, V]>) {\n if (initial) {\n for (const [k, v] of initial) {\n const index = this._entries.findIndex(([ek]) => Object.is(ek, k));\n if (index !== -1) {\n this._entries[index] = [k, v];\n } else {\n this._entries.push([k, v]);\n }\n }\n }\n }\n\n /** Returns the number of entries. */\n get size(): number {\n return this._entries.length;\n }\n\n /** Returns the value for `key`, or `undefined`. O(n) linear scan. */\n get(key: K): V | undefined {\n const entry = this._entries.find(([k]) => Object.is(k, key));\n return entry ? entry[1] : undefined;\n }\n\n /** Returns `true` if `key` exists. O(n) linear scan. */\n has(key: K): boolean {\n return this._entries.some(([k]) => Object.is(k, key));\n }\n\n /** Sets `key` to `value`. Updates in-place if key exists, appends otherwise. */\n set(key: K, value: V): this {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index !== -1) {\n this._entries[index] = [key, value];\n } else {\n this._entries.push([key, value]);\n }\n return this;\n }\n\n /** Removes the entry for `key`. Returns `true` if found. */\n delete(key: K): boolean {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index === -1) return false;\n this._entries.splice(index, 1);\n return true;\n }\n\n /** Removes all entries. Uses splice to trigger proxy notification. */\n clear(): void {\n this._entries.splice(0, this._entries.length);\n }\n\n /** Returns an iterator over the keys. */\n keys(): IterableIterator<K> {\n return this._entries.map(([k]) => k)[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<V> {\n return this._entries.map(([, v]) => v)[Symbol.iterator]();\n }\n\n /** Returns an iterator over [key, value] pairs. */\n entries(): IterableIterator<[K, V]> {\n return this._entries.map(([k, v]) => [k, v] as [K, V])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each entry, matching the native `Map.forEach` signature. */\n forEach(callback: (value: V, key: K, map: ReactiveMap<K, V>) => void): void {\n for (const [k, v] of this._entries) {\n callback(v, k, this);\n }\n }\n\n /** Enables `for...of` iteration over [key, value] pairs. */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.entries();\n }\n}\n\n// ── ReactiveSet ───────────────────────────────────────────────────────────────\n\n/**\n * A Set-like class backed by a plain array so `store()` can proxy mutations.\n *\n * Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.add()` would be invisible to the store. `ReactiveSet` solves this by\n * storing items in a plain array (`_items`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = store({ tags: reactiveSet<string>(['urgent']) });\n * myStore.tags.add('bug'); // reactive\n * ```\n */\nexport class ReactiveSet<T> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _items: T[] = [];\n\n /** Deduplicates initial values using `Object.is` comparison. */\n constructor(initial?: Iterable<T>) {\n if (initial) {\n for (const v of initial) {\n if (!this._items.some((item) => Object.is(item, v))) {\n this._items.push(v);\n }\n }\n }\n }\n\n /** Returns the number of unique items. */\n get size(): number {\n return this._items.length;\n }\n\n /** Returns `true` if `value` exists. O(n) linear scan. */\n has(value: T): boolean {\n return this._items.some((item) => Object.is(item, value));\n }\n\n /** Adds `value` if not already present (no-op for duplicates). */\n add(value: T): this {\n if (!this.has(value)) {\n this._items.push(value);\n }\n return this;\n }\n\n /** Removes `value`. Returns `true` if found. */\n delete(value: T): boolean {\n const index = this._items.findIndex((item) => Object.is(item, value));\n if (index === -1) return false;\n this._items.splice(index, 1);\n return true;\n }\n\n /** Removes all items. Uses splice to trigger proxy notification. */\n clear(): void {\n this._items.splice(0, this._items.length);\n }\n\n /** Returns an iterator over the values (same as `values()`, matching Set API). */\n keys(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over [value, value] pairs, matching the native Set API. */\n entries(): IterableIterator<[T, T]> {\n return this._items.map((v) => [v, v] as [T, T])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each item, matching the native `Set.forEach` signature. */\n forEach(callback: (value: T, key: T, set: ReactiveSet<T>) => void): void {\n for (const v of this._items) {\n callback(v, v, this);\n }\n }\n\n /** Enables `for...of` iteration over values. */\n [Symbol.iterator](): IterableIterator<T> {\n return this.values();\n }\n}\n\n// ── Factory functions ─────────────────────────────────────────────────────────\n\n/**\n * Creates a reactive Map-like collection backed by a plain array.\n * Wrap the parent object with `store()` for full reactivity.\n *\n * @param initial - Optional iterable of `[key, value]` pairs.\n */\nexport function reactiveMap<K, V>(\n initial?: Iterable<[K, V]>,\n): ReactiveMap<K, V> {\n return new ReactiveMap(initial);\n}\n\n/**\n * Creates a reactive Set-like collection backed by a plain array.\n * Wrap the parent object with `store()` for full reactivity.\n *\n * @param initial - Optional iterable of values.\n */\nexport function reactiveSet<T>(initial?: Iterable<T>): ReactiveSet<T> {\n return new ReactiveSet(initial);\n}\n","/**\n * Shallow-equal comparison for objects and arrays.\n * Useful as a custom `isEqual` for `useStore` selectors that return objects/arrays.\n *\n * - Primitives compared with `Object.is`.\n * - Arrays: length + element-wise `Object.is`.\n * - Objects: key count + value-wise `Object.is`.\n */\nexport function shallowEqual<T>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== 'object' ||\n a === null ||\n typeof b !== 'object' ||\n b === null\n ) {\n return false;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n }\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (\n !Object.hasOwn(b, key) ||\n !Object.is(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n )\n ) {\n return false;\n }\n }\n return true;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/collections/collections.ts","../src/utils/equality/equality.ts"],"sourcesContent":["import {PROXYABLE} from '../utils/internal/internal';\n\n// ── ReactiveMap ───────────────────────────────────────────────────────────────\n\n/**\n * A Map-like class backed by a plain array so `createClassyStore()` can proxy mutations.\n *\n * Native `Map` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.set()` would be invisible to the store. `ReactiveMap` solves this by\n * storing entries in a plain array (`_entries`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = createClassyStore({ users: reactiveMap<string, User>() });\n * myStore.users.set('id1', { name: 'Alice' }); // reactive\n * ```\n */\nexport class ReactiveMap<K, V> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _entries: [K, V][] = [];\n\n /** Deduplicates initial entries by key (last value wins, matching native `Map`). */\n constructor(initial?: Iterable<[K, V]>) {\n if (initial) {\n for (const [k, v] of initial) {\n const index = this._entries.findIndex(([ek]) => Object.is(ek, k));\n if (index !== -1) {\n this._entries[index] = [k, v];\n } else {\n this._entries.push([k, v]);\n }\n }\n }\n }\n\n /** Returns the number of entries. */\n get size(): number {\n return this._entries.length;\n }\n\n /** Returns the value for `key`, or `undefined`. O(n) linear scan. */\n get(key: K): V | undefined {\n const entry = this._entries.find(([k]) => Object.is(k, key));\n return entry ? entry[1] : undefined;\n }\n\n /** Returns `true` if `key` exists. O(n) linear scan. */\n has(key: K): boolean {\n return this._entries.some(([k]) => Object.is(k, key));\n }\n\n /** Sets `key` to `value`. Updates in-place if key exists, appends otherwise. */\n set(key: K, value: V): this {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index !== -1) {\n this._entries[index] = [key, value];\n } else {\n this._entries.push([key, value]);\n }\n return this;\n }\n\n /** Removes the entry for `key`. Returns `true` if found. */\n delete(key: K): boolean {\n const index = this._entries.findIndex(([k]) => Object.is(k, key));\n if (index === -1) return false;\n this._entries.splice(index, 1);\n return true;\n }\n\n /** Removes all entries. Uses splice to trigger proxy notification. */\n clear(): void {\n this._entries.splice(0, this._entries.length);\n }\n\n /** Returns an iterator over the keys. */\n keys(): IterableIterator<K> {\n return this._entries.map(([k]) => k)[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<V> {\n return this._entries.map(([, v]) => v)[Symbol.iterator]();\n }\n\n /** Returns an iterator over [key, value] pairs. */\n entries(): IterableIterator<[K, V]> {\n return this._entries.map(([k, v]) => [k, v] as [K, V])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each entry, matching the native `Map.forEach` signature. */\n forEach(callback: (value: V, key: K, map: ReactiveMap<K, V>) => void): void {\n for (const [k, v] of this._entries) {\n callback(v, k, this);\n }\n }\n\n /** Enables `for...of` iteration over [key, value] pairs. */\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.entries();\n }\n}\n\n// ── ReactiveSet ───────────────────────────────────────────────────────────────\n\n/**\n * A Set-like class backed by a plain array so `createClassyStore()` can proxy mutations.\n *\n * Native `Set` uses internal slots that ES6 Proxy can't intercept, so mutations\n * like `.add()` would be invisible to the store. `ReactiveSet` solves this by\n * storing items in a plain array (`_items`) that the proxy can track.\n *\n * Usage:\n * ```ts\n * const myStore = createClassyStore({ tags: reactiveSet<string>(['urgent']) });\n * myStore.tags.add('bug'); // reactive\n * ```\n */\nexport class ReactiveSet<T> {\n static [PROXYABLE] = true;\n\n /** @internal Backing storage — proxied by store(). */\n _items: T[] = [];\n\n /** Deduplicates initial values using `Object.is` comparison. */\n constructor(initial?: Iterable<T>) {\n if (initial) {\n for (const v of initial) {\n if (!this._items.some((item) => Object.is(item, v))) {\n this._items.push(v);\n }\n }\n }\n }\n\n /** Returns the number of unique items. */\n get size(): number {\n return this._items.length;\n }\n\n /** Returns `true` if `value` exists. O(n) linear scan. */\n has(value: T): boolean {\n return this._items.some((item) => Object.is(item, value));\n }\n\n /** Adds `value` if not already present (no-op for duplicates). */\n add(value: T): this {\n if (!this.has(value)) {\n this._items.push(value);\n }\n return this;\n }\n\n /** Removes `value`. Returns `true` if found. */\n delete(value: T): boolean {\n const index = this._items.findIndex((item) => Object.is(item, value));\n if (index === -1) return false;\n this._items.splice(index, 1);\n return true;\n }\n\n /** Removes all items. Uses splice to trigger proxy notification. */\n clear(): void {\n this._items.splice(0, this._items.length);\n }\n\n /** Returns an iterator over the values (same as `values()`, matching Set API). */\n keys(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over the values. */\n values(): IterableIterator<T> {\n return this._items[Symbol.iterator]();\n }\n\n /** Returns an iterator over [value, value] pairs, matching the native Set API. */\n entries(): IterableIterator<[T, T]> {\n return this._items.map((v) => [v, v] as [T, T])[Symbol.iterator]();\n }\n\n /** Calls `callback` for each item, matching the native `Set.forEach` signature. */\n forEach(callback: (value: T, key: T, set: ReactiveSet<T>) => void): void {\n for (const v of this._items) {\n callback(v, v, this);\n }\n }\n\n /** Enables `for...of` iteration over values. */\n [Symbol.iterator](): IterableIterator<T> {\n return this.values();\n }\n}\n\n// ── Factory functions ─────────────────────────────────────────────────────────\n\n/**\n * Creates a reactive Map-like collection backed by a plain array.\n * Wrap the parent object with `createClassyStore()` for full reactivity.\n *\n * @param initial - Optional iterable of `[key, value]` pairs.\n */\nexport function reactiveMap<K, V>(\n initial?: Iterable<[K, V]>,\n): ReactiveMap<K, V> {\n return new ReactiveMap(initial);\n}\n\n/**\n * Creates a reactive Set-like collection backed by a plain array.\n * Wrap the parent object with `createClassyStore()` for full reactivity.\n *\n * @param initial - Optional iterable of values.\n */\nexport function reactiveSet<T>(initial?: Iterable<T>): ReactiveSet<T> {\n return new ReactiveSet(initial);\n}\n","/**\n * Shallow-equal comparison for objects and arrays.\n * Useful as a custom `isEqual` for `useStore` selectors that return objects/arrays.\n *\n * - Primitives compared with `Object.is`.\n * - Arrays: length + element-wise `Object.is`.\n * - Objects: key count + value-wise `Object.is`.\n */\nexport function shallowEqual<T>(a: T, b: T): boolean {\n if (Object.is(a, b)) return true;\n if (\n typeof a !== 'object' ||\n a === null ||\n typeof b !== 'object' ||\n b === null\n ) {\n return false;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n }\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (\n !Object.hasOwn(b, key) ||\n !Object.is(\n (a as Record<string, unknown>)[key],\n (b as Record<string, unknown>)[key],\n )\n ) {\n return false;\n }\n }\n return true;\n}\n"],"mappings":"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"}
|
package/dist/react/react.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_snapshot = require('../snapshot-
|
|
2
|
+
const require_snapshot = require('../snapshot-BKVFJLuo.cjs');
|
|
3
3
|
let proxy_compare = require("proxy-compare");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
|
package/dist/react/react.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as subscribe,
|
|
1
|
+
import { a as subscribe, r as getInternal, t as snapshot } from "../snapshot-P0QPV1ER.mjs";
|
|
2
2
|
import { createProxy, isChanged } from "proxy-compare";
|
|
3
3
|
import { useCallback, useRef, useSyncExternalStore } from "react";
|
|
4
4
|
|
|
@@ -126,7 +126,7 @@ function evaluateComputed(internal, prop, getterFn, receiver) {
|
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* Retrieve the internal bookkeeping for a store proxy.
|
|
129
|
-
* Throws if the object was not created with `
|
|
129
|
+
* Throws if the object was not created with `createClassyStore()`.
|
|
130
130
|
*/
|
|
131
131
|
function getInternal(proxy) {
|
|
132
132
|
const internal = internalsMap.get(proxy);
|
|
@@ -248,15 +248,20 @@ function createStoreProxy(target, parent) {
|
|
|
248
248
|
*
|
|
249
249
|
* @param instance - A class instance (or plain object) to make reactive.
|
|
250
250
|
* @returns The same object wrapped in a reactive Proxy.
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```ts
|
|
254
|
+
* const myStore = createClassyStore(new MyClass());
|
|
255
|
+
* ```
|
|
251
256
|
*/
|
|
252
|
-
function
|
|
257
|
+
function createClassyStore(instance) {
|
|
253
258
|
return createStoreProxy(instance, null);
|
|
254
259
|
}
|
|
255
260
|
/**
|
|
256
261
|
* Subscribe to store changes. The callback fires once per batched mutation
|
|
257
262
|
* (coalesced via `queueMicrotask`), not once per individual property write.
|
|
258
263
|
*
|
|
259
|
-
* @param proxy - A reactive proxy created by `
|
|
264
|
+
* @param proxy - A reactive proxy created by `createClassyStore()`.
|
|
260
265
|
* @param callback - Invoked after each batched mutation.
|
|
261
266
|
* @returns An unsubscribe function. Call it to stop receiving notifications.
|
|
262
267
|
*/
|
|
@@ -284,7 +289,7 @@ function getVersion(proxy) {
|
|
|
284
289
|
* Version-stamped snapshot cache for tracked (proxied) sub-trees.
|
|
285
290
|
* Key: raw target object → [version, frozen snapshot].
|
|
286
291
|
*/
|
|
287
|
-
const
|
|
292
|
+
const snapshotCache = /* @__PURE__ */ new WeakMap();
|
|
288
293
|
/**
|
|
289
294
|
* Cache for untracked nested objects (never accessed through the proxy).
|
|
290
295
|
* Key: the raw mutable object → frozen deep clone.
|
|
@@ -303,7 +308,7 @@ const snapshotGetterCache = /* @__PURE__ */ new WeakMap();
|
|
|
303
308
|
* boundaries: if `this.items` hasn't changed between snapshots (same
|
|
304
309
|
* reference via structural sharing), the getter returns the same result.
|
|
305
310
|
*/
|
|
306
|
-
const
|
|
311
|
+
const crossSnapshotMemo = /* @__PURE__ */ new WeakMap();
|
|
307
312
|
/**
|
|
308
313
|
* Run a getter against the snapshot with dependency tracking.
|
|
309
314
|
*
|
|
@@ -337,7 +342,7 @@ function computeWithTracking(snap, getterFn) {
|
|
|
337
342
|
* guarantees stable refs for unchanged sub-trees). For getter properties
|
|
338
343
|
* this invokes the getter (which is itself memoized), then compares.
|
|
339
344
|
*/
|
|
340
|
-
function
|
|
345
|
+
function areMemoizedDepsValid(currentSnap, deps) {
|
|
341
346
|
for (const dep of deps) {
|
|
342
347
|
const currentValue = Reflect.get(currentSnap, dep.prop, currentSnap);
|
|
343
348
|
if (!Object.is(currentValue, dep.value)) return false;
|
|
@@ -356,16 +361,16 @@ function areMemoedDepsValid(currentSnap, deps) {
|
|
|
356
361
|
function evaluateSnapshotGetter(currentSnap, target, key, getterFn) {
|
|
357
362
|
const perSnapCache = snapshotGetterCache.get(currentSnap);
|
|
358
363
|
if (perSnapCache?.has(key)) return perSnapCache.get(key);
|
|
359
|
-
let memoMap =
|
|
364
|
+
let memoMap = crossSnapshotMemo.get(target);
|
|
360
365
|
const prev = memoMap?.get(key);
|
|
361
366
|
let result;
|
|
362
|
-
if (prev &&
|
|
367
|
+
if (prev && areMemoizedDepsValid(currentSnap, prev.deps)) result = prev.result;
|
|
363
368
|
else {
|
|
364
369
|
const computation = computeWithTracking(currentSnap, getterFn);
|
|
365
370
|
result = computation.result;
|
|
366
371
|
if (!memoMap) {
|
|
367
372
|
memoMap = /* @__PURE__ */ new Map();
|
|
368
|
-
|
|
373
|
+
crossSnapshotMemo.set(target, memoMap);
|
|
369
374
|
}
|
|
370
375
|
memoMap.set(key, {
|
|
371
376
|
deps: computation.deps,
|
|
@@ -479,7 +484,7 @@ function installMemoizedGetters(snap, target) {
|
|
|
479
484
|
* are installed as lazy-memoizing accessors via `installMemoizedGetters`.
|
|
480
485
|
*/
|
|
481
486
|
function createSnapshotRecursive(target, internal) {
|
|
482
|
-
const cached =
|
|
487
|
+
const cached = snapshotCache.get(target);
|
|
483
488
|
if (cached && cached[0] === internal.version) return cached[1];
|
|
484
489
|
let snap;
|
|
485
490
|
if (Array.isArray(target)) {
|
|
@@ -496,7 +501,7 @@ function createSnapshotRecursive(target, internal) {
|
|
|
496
501
|
installMemoizedGetters(snap, target);
|
|
497
502
|
}
|
|
498
503
|
Object.freeze(snap);
|
|
499
|
-
|
|
504
|
+
snapshotCache.set(target, [internal.version, snap]);
|
|
500
505
|
return snap;
|
|
501
506
|
}
|
|
502
507
|
/**
|
|
@@ -512,7 +517,7 @@ function createSnapshotRecursive(target, internal) {
|
|
|
512
517
|
* per snapshot and their results are stable across snapshots when dependencies
|
|
513
518
|
* haven't changed (cross-snapshot memoization).
|
|
514
519
|
*
|
|
515
|
-
* @param proxyStore - A reactive proxy created by `
|
|
520
|
+
* @param proxyStore - A reactive proxy created by `createClassyStore()`.
|
|
516
521
|
* @returns A deeply frozen plain-JS object (Snapshot<T>).
|
|
517
522
|
*/
|
|
518
523
|
function snapshot(proxyStore) {
|
|
@@ -527,6 +532,12 @@ Object.defineProperty(exports, 'PROXYABLE', {
|
|
|
527
532
|
return PROXYABLE;
|
|
528
533
|
}
|
|
529
534
|
});
|
|
535
|
+
Object.defineProperty(exports, 'createClassyStore', {
|
|
536
|
+
enumerable: true,
|
|
537
|
+
get: function () {
|
|
538
|
+
return createClassyStore;
|
|
539
|
+
}
|
|
540
|
+
});
|
|
530
541
|
Object.defineProperty(exports, 'findGetterDescriptor', {
|
|
531
542
|
enumerable: true,
|
|
532
543
|
get: function () {
|
|
@@ -551,16 +562,10 @@ Object.defineProperty(exports, 'snapshot', {
|
|
|
551
562
|
return snapshot;
|
|
552
563
|
}
|
|
553
564
|
});
|
|
554
|
-
Object.defineProperty(exports, 'store', {
|
|
555
|
-
enumerable: true,
|
|
556
|
-
get: function () {
|
|
557
|
-
return store;
|
|
558
|
-
}
|
|
559
|
-
});
|
|
560
565
|
Object.defineProperty(exports, 'subscribe', {
|
|
561
566
|
enumerable: true,
|
|
562
567
|
get: function () {
|
|
563
568
|
return subscribe;
|
|
564
569
|
}
|
|
565
570
|
});
|
|
566
|
-
//# sourceMappingURL=snapshot-
|
|
571
|
+
//# sourceMappingURL=snapshot-BKVFJLuo.cjs.map
|