@ng-org/alien-deepsignals 0.1.2-alpha.5 → 0.1.2-alpha.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/README.md +55 -374
- package/dist/core.d.ts +66 -60
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +70 -82
- package/dist/deepSignal.d.ts +19 -5
- package/dist/deepSignal.d.ts.map +1 -1
- package/dist/deepSignal.js +214 -141
- package/dist/effect.d.ts.map +1 -1
- package/dist/effect.js +8 -1
- package/dist/hooks/react/useDeepSignal.d.ts +1 -1
- package/dist/hooks/react/useDeepSignal.d.ts.map +1 -1
- package/dist/hooks/react/useDeepSignal.js +5 -2
- package/dist/hooks/svelte/index.d.ts +0 -1
- package/dist/hooks/svelte/index.d.ts.map +1 -1
- package/dist/hooks/svelte/useDeepSignal.svelte.d.ts +3 -15
- package/dist/hooks/svelte/useDeepSignal.svelte.d.ts.map +1 -1
- package/dist/hooks/svelte/useDeepSignal.svelte.js +29 -63
- package/dist/hooks/svelte4/index.d.ts +4 -0
- package/dist/hooks/svelte4/index.d.ts.map +1 -0
- package/dist/hooks/svelte4/index.js +8 -0
- package/dist/hooks/svelte4/useDeepSignal.svelte.d.ts +27 -0
- package/dist/hooks/svelte4/useDeepSignal.svelte.d.ts.map +1 -0
- package/dist/hooks/svelte4/useDeepSignal.svelte.js +91 -0
- package/dist/hooks/vue/useDeepSignal.d.ts +2 -2
- package/dist/hooks/vue/useDeepSignal.d.ts.map +1 -1
- package/dist/hooks/vue/useDeepSignal.js +22 -74
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/test/frontend/astro-app/src/components/ReactPanel.d.ts.map +1 -1
- package/dist/test/frontend/astro-app/src/components/{ReactPanel.js → ReactPanel.jsx} +56 -45
- package/dist/test/frontend/playwright/crossFrameworkHooks.spec.js +13 -3
- package/dist/test/frontend/utils/mockData.d.ts.map +1 -1
- package/dist/test/frontend/utils/mockData.js +13 -4
- package/dist/test/lib/index.test.js +16 -3
- package/dist/test/lib/misc.test.js +104 -1
- package/dist/test/lib/watch.test.js +2 -11
- package/dist/types.d.ts +94 -19
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/watch.d.ts +37 -0
- package/dist/watch.d.ts.map +1 -1
- package/dist/watch.js +35 -0
- package/package.json +8 -5
- package/dist/test/frontend/astro-app/src/components/PerfSuiteClient.d.ts +0 -4
- package/dist/test/frontend/astro-app/src/components/PerfSuiteClient.d.ts.map +0 -1
- package/dist/test/frontend/astro-app/src/components/PerfSuiteClient.js +0 -225
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.d.ts +0 -4
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.d.ts.map +0 -1
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfDeep.js +0 -150
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.d.ts +0 -4
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.d.ts.map +0 -1
- package/dist/test/frontend/astro-app/src/components/perf/react/ReactPerfNative.js +0 -184
- package/dist/test/frontend/playwright/perfSuite.spec.d.ts +0 -2
- package/dist/test/frontend/playwright/perfSuite.spec.d.ts.map +0 -1
- package/dist/test/frontend/playwright/perfSuite.spec.js +0 -128
- package/dist/test/frontend/utils/perfScenarios.d.ts +0 -15
- package/dist/test/frontend/utils/perfScenarios.d.ts.map +0 -1
- package/dist/test/frontend/utils/perfScenarios.js +0 -287
- package/dist/test/lib/core.test.d.ts +0 -2
- package/dist/test/lib/core.test.d.ts.map +0 -1
- package/dist/test/lib/core.test.js +0 -53
package/dist/effect.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// Copyright (c) 2025 Laurin Weger, Par le Peuple, NextGraph.org developers
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
// Licensed under the Apache License, Version 2.0
|
|
5
|
+
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
|
6
|
+
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
|
7
|
+
// at your option. All files in the project carrying such
|
|
8
|
+
// notice may not be copied, modified, or distributed except
|
|
9
|
+
// according to those terms.
|
|
3
10
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
4
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
12
|
exports.effect = effect;
|
|
@@ -10,7 +17,7 @@ function effect(run) {
|
|
|
10
17
|
const registerCleanup = (fn) => {
|
|
11
18
|
cleanup = fn;
|
|
12
19
|
};
|
|
13
|
-
const stop = (0, core_1.
|
|
20
|
+
const stop = (0, core_1.alienEffect)(() => {
|
|
14
21
|
if (cleanup) {
|
|
15
22
|
try {
|
|
16
23
|
cleanup();
|
|
@@ -6,7 +6,7 @@ import { DeepSignalOptions } from "../..";
|
|
|
6
6
|
* is rerendered as well.
|
|
7
7
|
*
|
|
8
8
|
* @param object The object that should become reactive
|
|
9
|
-
* @param
|
|
9
|
+
* @param options When the object is not a deepSignal already, options passed to {@link deepSignal}.
|
|
10
10
|
* @returns The deepSignal object of the object param. On every change, the returned object will change (a new no-op proxy is created) around the deepSignal object.
|
|
11
11
|
*/
|
|
12
12
|
declare const useSignal: <T extends object>(object: T, deepSignalOptions?: DeepSignalOptions) => import("../..").DeepSignal<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeepSignal.d.ts","sourceRoot":"","sources":["../../../src/hooks/react/useDeepSignal.ts"],"names":[],"mappings":"AAYA,OAAO,EAAc,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEtD;;;;;;;;;GASG;AACH,QAAA,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAC/B,QAAQ,CAAC,EACT,oBAAoB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"useDeepSignal.d.ts","sourceRoot":"","sources":["../../../src/hooks/react/useDeepSignal.ts"],"names":[],"mappings":"AAYA,OAAO,EAAc,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEtD;;;;;;;;;GASG;AACH,QAAA,MAAM,SAAS,GAAI,CAAC,SAAS,MAAM,EAC/B,QAAQ,CAAC,EACT,oBAAoB,iBAAiB,kCAyCxC,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -19,12 +19,15 @@ const __1 = require("../..");
|
|
|
19
19
|
* is rerendered as well.
|
|
20
20
|
*
|
|
21
21
|
* @param object The object that should become reactive
|
|
22
|
-
* @param
|
|
22
|
+
* @param options When the object is not a deepSignal already, options passed to {@link deepSignal}.
|
|
23
23
|
* @returns The deepSignal object of the object param. On every change, the returned object will change (a new no-op proxy is created) around the deepSignal object.
|
|
24
24
|
*/
|
|
25
25
|
const useSignal = (object, deepSignalOptions) => {
|
|
26
26
|
// Create the actual deepSignal object from the raw object (if the object is a deepSignal object already, it returns itself).
|
|
27
|
-
const signal = (0, react_1.useMemo)(() => (0, __1.deepSignal)(object,
|
|
27
|
+
const signal = (0, react_1.useMemo)(() => (0, __1.deepSignal)(object, {
|
|
28
|
+
replaceProxiesInBranchOnChange: true, // Set so that react can detect change in object hierarchy by equality comparison.
|
|
29
|
+
...deepSignalOptions,
|
|
30
|
+
}), [object, deepSignalOptions]);
|
|
28
31
|
// Create a shallow proxy of the original object which can be disposed and a new one
|
|
29
32
|
// recreated on rerenders so that react knows it changed on comparisons.
|
|
30
33
|
const proxyRef = (0, react_1.useRef)(new Proxy(signal, {}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/svelte/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/svelte/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -1,16 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DeepSignalOptions, RevertDeepSignal } from "../../index";
|
|
3
|
-
/** Base result contract for a deepSignal-backed Svelte integration. */
|
|
4
|
-
export interface UseDeepSignalResult<T> extends Readable<T> {
|
|
5
|
-
/** Derive a nested selection; re-runs when the underlying tree version increments. */
|
|
6
|
-
select<U>(selector: (tree: T) => U): Readable<U>;
|
|
7
|
-
/** Stop receiving further updates (invoked automatically on component destroy). */
|
|
8
|
-
dispose(): void;
|
|
9
|
-
/** Replace root shape contents (mutative merge) – enables Svelte writable store binding semantics. */
|
|
10
|
-
set(next: Partial<T> | T): void;
|
|
11
|
-
/** Functional update helper using current tree snapshot. */
|
|
12
|
-
update(updater: (current: T) => T | void): void;
|
|
13
|
-
}
|
|
1
|
+
import { DeepSignalOptions, DeepSignal } from "../../index";
|
|
14
2
|
/**
|
|
15
3
|
* Create a rune from a deepSignal object (creates one if it is just a regular object).
|
|
16
4
|
*
|
|
@@ -19,9 +7,9 @@ export interface UseDeepSignalResult<T> extends Readable<T> {
|
|
|
19
7
|
* is rerendered as well.
|
|
20
8
|
*
|
|
21
9
|
* @param object The object that should become reactive
|
|
22
|
-
* @param
|
|
10
|
+
* @param options Options passed to {@link deepSignal}.
|
|
23
11
|
* @returns A rune for using the deepSignal object in svelte.
|
|
24
12
|
*/
|
|
25
|
-
export declare function useDeepSignal<T extends object>(object: T
|
|
13
|
+
export declare function useDeepSignal<T extends object>(object: T, options?: DeepSignalOptions): T extends DeepSignal<any> ? T : DeepSignal<T>;
|
|
26
14
|
export default useDeepSignal;
|
|
27
15
|
//# sourceMappingURL=useDeepSignal.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeepSignal.svelte.d.ts","sourceRoot":"","sources":["../../../src/hooks/svelte/useDeepSignal.svelte.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDeepSignal.svelte.d.ts","sourceRoot":"","sources":["../../../src/hooks/svelte/useDeepSignal.svelte.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,iBAAiB,EAAc,UAAU,EAAE,MAAM,aAAa,CAAC;AAExE;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC1C,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE,iBAAiB,GAab,CAAC,SAAS,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAC9D;AAyBD,eAAe,aAAa,CAAC"}
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.useDeepSignal = useDeepSignal;
|
|
13
|
-
const
|
|
14
|
-
const svelte_1 = require("svelte");
|
|
13
|
+
const reactivity_1 = require("svelte/reactivity");
|
|
15
14
|
const index_1 = require("../../index");
|
|
16
15
|
/**
|
|
17
16
|
* Create a rune from a deepSignal object (creates one if it is just a regular object).
|
|
@@ -21,70 +20,37 @@ const index_1 = require("../../index");
|
|
|
21
20
|
* is rerendered as well.
|
|
22
21
|
*
|
|
23
22
|
* @param object The object that should become reactive
|
|
24
|
-
* @param
|
|
23
|
+
* @param options Options passed to {@link deepSignal}.
|
|
25
24
|
* @returns A rune for using the deepSignal object in svelte.
|
|
26
25
|
*/
|
|
27
26
|
function useDeepSignal(object, options) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
};
|
|
47
|
-
if (object instanceof Promise) {
|
|
48
|
-
object.then(init);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
init(object);
|
|
52
|
-
}
|
|
53
|
-
const dispose = () => {
|
|
54
|
-
isDestroyed = true;
|
|
55
|
-
if (unsubscribe)
|
|
56
|
-
unsubscribe();
|
|
57
|
-
};
|
|
58
|
-
(0, svelte_1.onDestroy)(dispose);
|
|
59
|
-
const deep = (0, store_1.derived)(version, () => deepProxy);
|
|
60
|
-
const select = (selector) => (0, store_1.derived)(deep, (t) => (t ? selector(t) : undefined));
|
|
61
|
-
// Expose Svelte store contract by delegating subscribe to deep store.
|
|
62
|
-
const applyReplacement = (next) => {
|
|
63
|
-
if (!deepProxy || !next || typeof next !== "object")
|
|
64
|
-
return;
|
|
65
|
-
// Remove keys absent in next
|
|
66
|
-
for (const k of Object.keys(deepProxy)) {
|
|
67
|
-
if (!(k in next))
|
|
68
|
-
delete deepProxy[k];
|
|
69
|
-
}
|
|
70
|
-
// Assign / overwrite provided keys
|
|
71
|
-
Object.assign(deepProxy, next);
|
|
27
|
+
const ret = (0, index_1.deepSignal)(object, {
|
|
28
|
+
...options,
|
|
29
|
+
subscriberFactories: (options?.subscriberFactories ?? new Set()).union(new Set([subscriberFactory])),
|
|
30
|
+
});
|
|
31
|
+
// onDestroy(() => {
|
|
32
|
+
// // TODO: Tell signal that subscriber can be removed?
|
|
33
|
+
// });
|
|
34
|
+
return ret;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Calls Svelte's `createSubscriber` and wraps it for compatibility with
|
|
38
|
+
* deepSignal's external subscriber format.
|
|
39
|
+
* @returns
|
|
40
|
+
*/
|
|
41
|
+
const subscriberFactory = () => {
|
|
42
|
+
let setter;
|
|
43
|
+
let onSet = () => {
|
|
44
|
+
setter?.();
|
|
72
45
|
};
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (!deepProxy)
|
|
82
|
-
return;
|
|
83
|
-
const result = updater(deepProxy);
|
|
84
|
-
if (result && typeof result === "object")
|
|
85
|
-
applyReplacement(result);
|
|
86
|
-
},
|
|
46
|
+
const onGet = (0, reactivity_1.createSubscriber)((update) => {
|
|
47
|
+
setter = () => {
|
|
48
|
+
update();
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
onGet,
|
|
53
|
+
onSet,
|
|
87
54
|
};
|
|
88
|
-
|
|
89
|
-
}
|
|
55
|
+
};
|
|
90
56
|
exports.default = useDeepSignal;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/svelte4/index.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
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.useDeepSignal = void 0;
|
|
7
|
+
const useDeepSignal_svelte_js_1 = __importDefault(require("./useDeepSignal.svelte.js"));
|
|
8
|
+
exports.useDeepSignal = useDeepSignal_svelte_js_1.default;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type Readable } from "svelte/store";
|
|
2
|
+
import { DeepSignalOptions, UnwrapDeepSignal } from "../../index";
|
|
3
|
+
/** Base result contract for a deepSignal-backed Svelte integration. */
|
|
4
|
+
export interface UseDeepSignalResult<T> extends Readable<T> {
|
|
5
|
+
/** Derive a nested selection; re-runs when the underlying tree version increments. */
|
|
6
|
+
select<U>(selector: (tree: T) => U): Readable<U>;
|
|
7
|
+
/** Stop receiving further updates (invoked automatically on component destroy). */
|
|
8
|
+
dispose(): void;
|
|
9
|
+
/** Replace root shape contents (mutative merge) – enables Svelte writable store binding semantics. */
|
|
10
|
+
set(next: Partial<T> | T): void;
|
|
11
|
+
/** Functional update helper using current tree snapshot. */
|
|
12
|
+
update(updater: (current: T) => T | void): void;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a store from a deepSignal object (creates one if it is just a regular object).
|
|
16
|
+
*
|
|
17
|
+
* Modifications to the returned deepSignal object cause an immediate rerender.
|
|
18
|
+
* If modifications of the object are made from somewhere else, the component
|
|
19
|
+
* is rerendered as well.
|
|
20
|
+
*
|
|
21
|
+
* @param object The object that should become reactive
|
|
22
|
+
* @param options Options passed to {@link deepSignal}.
|
|
23
|
+
* @returns A store for using the deepSignal object in svelte.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useDeepSignal<T extends object>(object: T | Promise<T>, options?: DeepSignalOptions): UseDeepSignalResult<UnwrapDeepSignal<T>>;
|
|
26
|
+
export default useDeepSignal;
|
|
27
|
+
//# sourceMappingURL=useDeepSignal.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeepSignal.svelte.d.ts","sourceRoot":"","sources":["../../../src/hooks/svelte4/useDeepSignal.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,EAAqB,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAGH,iBAAiB,EAEjB,gBAAgB,EACnB,MAAM,aAAa,CAAC;AAGrB,uEAAuE;AACvE,MAAM,WAAW,mBAAmB,CAAC,CAAC,CAAE,SAAQ,QAAQ,CAAC,CAAC,CAAC;IACvD,sFAAsF;IACtF,MAAM,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACjD,mFAAmF;IACnF,OAAO,IAAI,IAAI,CAAC;IAChB,sGAAsG;IACtG,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAChC,4DAA4D;IAC5D,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;CACnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC1C,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,CAAC,EAAE,iBAAiB,GAC5B,mBAAmB,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAkE1C;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright (c) 2025 Laurin Weger, Par le Peuple, NextGraph.org developers
|
|
3
|
+
// All rights reserved.
|
|
4
|
+
// Licensed under the Apache License, Version 2.0
|
|
5
|
+
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
|
|
6
|
+
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
|
7
|
+
// at your option. All files in the project carrying such
|
|
8
|
+
// notice may not be copied, modified, or distributed except
|
|
9
|
+
// according to those terms.
|
|
10
|
+
// SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.useDeepSignal = useDeepSignal;
|
|
13
|
+
const store_1 = require("svelte/store");
|
|
14
|
+
const svelte_1 = require("svelte");
|
|
15
|
+
const index_1 = require("../../index");
|
|
16
|
+
const deepSignal_1 = require("../../deepSignal");
|
|
17
|
+
/**
|
|
18
|
+
* Create a store from a deepSignal object (creates one if it is just a regular object).
|
|
19
|
+
*
|
|
20
|
+
* Modifications to the returned deepSignal object cause an immediate rerender.
|
|
21
|
+
* If modifications of the object are made from somewhere else, the component
|
|
22
|
+
* is rerendered as well.
|
|
23
|
+
*
|
|
24
|
+
* @param object The object that should become reactive
|
|
25
|
+
* @param options Options passed to {@link deepSignal}.
|
|
26
|
+
* @returns A store for using the deepSignal object in svelte.
|
|
27
|
+
*/
|
|
28
|
+
function useDeepSignal(object, options) {
|
|
29
|
+
const version = (0, store_1.writable)(-1);
|
|
30
|
+
let deepProxy;
|
|
31
|
+
let unsubscribe;
|
|
32
|
+
let isDestroyed = false;
|
|
33
|
+
const init = (obj) => {
|
|
34
|
+
if (isDestroyed)
|
|
35
|
+
return;
|
|
36
|
+
deepProxy = (0, index_1.deepSignal)(obj, options);
|
|
37
|
+
const rootId = (0, deepSignal_1.getDeepSignalRootId)(deepProxy);
|
|
38
|
+
const initialVersion = (0, deepSignal_1.getDeepSignalVersion)(deepProxy) ?? 0;
|
|
39
|
+
unsubscribe = (0, index_1.subscribeDeepMutations)(deepProxy, (batch) => {
|
|
40
|
+
if (!rootId)
|
|
41
|
+
return;
|
|
42
|
+
if (batch.patches.length) {
|
|
43
|
+
version.set(batch.version);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
version.set(initialVersion);
|
|
47
|
+
};
|
|
48
|
+
if (object instanceof Promise) {
|
|
49
|
+
object.then(init);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
init(object);
|
|
53
|
+
}
|
|
54
|
+
const dispose = () => {
|
|
55
|
+
isDestroyed = true;
|
|
56
|
+
if (unsubscribe)
|
|
57
|
+
unsubscribe();
|
|
58
|
+
};
|
|
59
|
+
(0, svelte_1.onDestroy)(dispose);
|
|
60
|
+
const deep = (0, store_1.derived)(version, () => deepProxy);
|
|
61
|
+
const select = (selector) => (0, store_1.derived)(deep, (t) => (t ? selector(t) : undefined));
|
|
62
|
+
// Expose Svelte store contract by delegating subscribe to deep store.
|
|
63
|
+
const applyReplacement = (next) => {
|
|
64
|
+
if (!deepProxy || !next || typeof next !== "object")
|
|
65
|
+
return;
|
|
66
|
+
// Remove keys absent in next
|
|
67
|
+
for (const k of Object.keys(deepProxy)) {
|
|
68
|
+
if (!(k in next))
|
|
69
|
+
delete deepProxy[k];
|
|
70
|
+
}
|
|
71
|
+
// Assign / overwrite provided keys
|
|
72
|
+
Object.assign(deepProxy, next);
|
|
73
|
+
};
|
|
74
|
+
const store = {
|
|
75
|
+
select,
|
|
76
|
+
dispose,
|
|
77
|
+
subscribe: deep.subscribe,
|
|
78
|
+
set(next) {
|
|
79
|
+
applyReplacement(next);
|
|
80
|
+
},
|
|
81
|
+
update(updater) {
|
|
82
|
+
if (!deepProxy)
|
|
83
|
+
return;
|
|
84
|
+
const result = updater(deepProxy);
|
|
85
|
+
if (result && typeof result === "object")
|
|
86
|
+
applyReplacement(result);
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
return store;
|
|
90
|
+
}
|
|
91
|
+
exports.default = useDeepSignal;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { type MaybeRefOrGetter } from "vue";
|
|
2
2
|
import { DeepSignal, DeepSignalOptions } from "../../";
|
|
3
3
|
/**
|
|
4
|
-
* Create or use an existing deepSignal object in your component.
|
|
4
|
+
* Create or use an existing (child) deepSignal object in your component.
|
|
5
5
|
* Modifications to the returned deepSignal object cause an immediate rerender.
|
|
6
6
|
* If modifications of the object are made from somewhere else, the component
|
|
7
7
|
* is rerendered as well.
|
|
8
8
|
*
|
|
9
9
|
* @param object The object that should become reactive (can be a ref or getter)
|
|
10
|
-
* @param options
|
|
10
|
+
* @param options Options passed to {@link deepSignal}.
|
|
11
11
|
* @returns The deepSignal object of the object param.
|
|
12
12
|
*
|
|
13
13
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeepSignal.d.ts","sourceRoot":"","sources":["../../../src/hooks/vue/useDeepSignal.ts"],"names":[],"mappings":"AAUA,OAAO,
|
|
1
|
+
{"version":3,"file":"useDeepSignal.d.ts","sourceRoot":"","sources":["../../../src/hooks/vue/useDeepSignal.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,KAAK,CAAC;AAEhE,OAAO,EAAE,UAAU,EAAc,iBAAiB,EAAS,MAAM,QAAQ,CAAC;AAE1E;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC1C,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,OAAO,CAAC,EAAE,iBAAiB,GAC5B,UAAU,CAAC,CAAC,CAAC,CAaf;AAkBD,eAAe,aAAa,CAAC"}
|
|
@@ -13,89 +13,37 @@ exports.useDeepSignal = useDeepSignal;
|
|
|
13
13
|
const vue_1 = require("vue");
|
|
14
14
|
const __1 = require("../../");
|
|
15
15
|
/**
|
|
16
|
-
* Create or use an existing deepSignal object in your component.
|
|
16
|
+
* Create or use an existing (child) deepSignal object in your component.
|
|
17
17
|
* Modifications to the returned deepSignal object cause an immediate rerender.
|
|
18
18
|
* If modifications of the object are made from somewhere else, the component
|
|
19
19
|
* is rerendered as well.
|
|
20
20
|
*
|
|
21
21
|
* @param object The object that should become reactive (can be a ref or getter)
|
|
22
|
-
* @param options
|
|
22
|
+
* @param options Options passed to {@link deepSignal}.
|
|
23
23
|
* @returns The deepSignal object of the object param.
|
|
24
24
|
*
|
|
25
25
|
*/
|
|
26
|
-
// Note partly written with the help of Gemini 3.
|
|
27
26
|
function useDeepSignal(object, options) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
let stopHandle;
|
|
32
|
-
// Watch the input object for changes.
|
|
33
|
-
const stopWatchingSource = (0, vue_1.watch)(() => (0, vue_1.toValue)(object), (newObj) => {
|
|
34
|
-
if (stopHandle) {
|
|
35
|
-
stopHandle.stopListening();
|
|
36
|
-
stopHandle = undefined;
|
|
37
|
-
}
|
|
38
|
-
if (newObj) {
|
|
39
|
-
currentSignal = (0, __1.deepSignal)(newObj, options);
|
|
40
|
-
stopHandle = (0, __1.watch)(currentSignal, ({ patches }) => {
|
|
41
|
-
if (patches.length > 0)
|
|
42
|
-
version.value++;
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
// Trigger Vue update.
|
|
46
|
-
version.value++;
|
|
47
|
-
}, { immediate: true });
|
|
48
|
-
// Determines the initial target for the Proxy (array vs object).
|
|
49
|
-
const initialVal = (0, vue_1.toValue)(object);
|
|
50
|
-
const proxyTarget = (Array.isArray(initialVal) ? [] : {});
|
|
51
|
-
// Proxy that creates Vue dependency on version for any access.
|
|
52
|
-
const proxy = new Proxy(proxyTarget, {
|
|
53
|
-
get(target, key) {
|
|
54
|
-
if (key === "__raw")
|
|
55
|
-
return currentSignal;
|
|
56
|
-
// Track version to create reactive dependency.
|
|
57
|
-
version.value;
|
|
58
|
-
// Delegate to current signal.
|
|
59
|
-
const actualTarget = currentSignal || target;
|
|
60
|
-
const value = Reflect.get(actualTarget, key);
|
|
61
|
-
// Bind methods to maintain correct `this` context.
|
|
62
|
-
return typeof value === "function"
|
|
63
|
-
? value.bind(actualTarget)
|
|
64
|
-
: value;
|
|
65
|
-
},
|
|
66
|
-
set(target, key, value) {
|
|
67
|
-
// Delegate to current signal.
|
|
68
|
-
const actualTarget = currentSignal || target;
|
|
69
|
-
return Reflect.set(actualTarget, key, value);
|
|
70
|
-
},
|
|
71
|
-
has(target, key) {
|
|
72
|
-
version.value;
|
|
73
|
-
const actualTarget = currentSignal || target;
|
|
74
|
-
return Reflect.has(actualTarget, key);
|
|
75
|
-
},
|
|
76
|
-
ownKeys(target) {
|
|
77
|
-
version.value;
|
|
78
|
-
const actualTarget = currentSignal || target;
|
|
79
|
-
return Reflect.ownKeys(actualTarget);
|
|
80
|
-
},
|
|
81
|
-
getOwnPropertyDescriptor(target, key) {
|
|
82
|
-
version.value;
|
|
83
|
-
const actualTarget = currentSignal || target;
|
|
84
|
-
const desc = Reflect.getOwnPropertyDescriptor(actualTarget, key);
|
|
85
|
-
return desc ? { ...desc, configurable: true } : undefined;
|
|
86
|
-
},
|
|
27
|
+
const deepProxy = (0, __1.deepSignal)((0, vue_1.toValue)(object), {
|
|
28
|
+
...options,
|
|
29
|
+
subscriberFactories: (options?.subscriberFactories ?? new Set()).union(new Set([subscriberFactory])),
|
|
87
30
|
});
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
stopHandle.stopListening();
|
|
93
|
-
}
|
|
94
|
-
catch {
|
|
95
|
-
// ignore
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
return proxy;
|
|
31
|
+
// onBeforeUnmount(() => {
|
|
32
|
+
// // TODO: Tell signal that subscriber can be removed?
|
|
33
|
+
// });
|
|
34
|
+
return deepProxy;
|
|
100
35
|
}
|
|
36
|
+
/** Calls Vue's customRef for notifications of value changes. */
|
|
37
|
+
const subscriberFactory = () => {
|
|
38
|
+
let onGet;
|
|
39
|
+
let onSet;
|
|
40
|
+
// We don't use the actually returned value of the get/set.
|
|
41
|
+
// We only need it to notify Vue, since Dep is not exposed directly.
|
|
42
|
+
(0, vue_1.customRef)((track, trigger) => {
|
|
43
|
+
onGet = track;
|
|
44
|
+
onSet = trigger;
|
|
45
|
+
return { get() { }, set() { } };
|
|
46
|
+
});
|
|
47
|
+
return { onGet: onGet, onSet: onSet };
|
|
48
|
+
};
|
|
101
49
|
exports.default = useDeepSignal;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { addWithId, deepSignal, getRaw, isDeepSignal, shallow, subscribeDeepMutations, } from "./deepSignal";
|
|
2
2
|
export * from "./core";
|
|
3
3
|
export * from "./watch";
|
|
4
|
-
export * from "./effect";
|
|
5
4
|
export * from "./types";
|
|
6
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,SAAS,EACT,UAAU,EACV,MAAM,EACN,YAAY,EACZ,OAAO,EACP,sBAAsB,GACzB,MAAM,cAAc,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,8 +14,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
17
|
+
exports.subscribeDeepMutations = exports.shallow = exports.isDeepSignal = exports.getRaw = exports.deepSignal = exports.addWithId = void 0;
|
|
18
|
+
var deepSignal_1 = require("./deepSignal");
|
|
19
|
+
Object.defineProperty(exports, "addWithId", { enumerable: true, get: function () { return deepSignal_1.addWithId; } });
|
|
20
|
+
Object.defineProperty(exports, "deepSignal", { enumerable: true, get: function () { return deepSignal_1.deepSignal; } });
|
|
21
|
+
Object.defineProperty(exports, "getRaw", { enumerable: true, get: function () { return deepSignal_1.getRaw; } });
|
|
22
|
+
Object.defineProperty(exports, "isDeepSignal", { enumerable: true, get: function () { return deepSignal_1.isDeepSignal; } });
|
|
23
|
+
Object.defineProperty(exports, "shallow", { enumerable: true, get: function () { return deepSignal_1.shallow; } });
|
|
24
|
+
Object.defineProperty(exports, "subscribeDeepMutations", { enumerable: true, get: function () { return deepSignal_1.subscribeDeepMutations; } });
|
|
18
25
|
__exportStar(require("./core"), exports);
|
|
19
26
|
__exportStar(require("./watch"), exports);
|
|
20
|
-
__exportStar(require("./effect"), exports);
|
|
21
27
|
__exportStar(require("./types"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactPanel.d.ts","sourceRoot":"","sources":["../../../../../../src/test/frontend/astro-app/src/components/ReactPanel.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ReactPanel.d.ts","sourceRoot":"","sources":["../../../../../../src/test/frontend/astro-app/src/components/ReactPanel.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAM1D,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EA6LvB,CAAC;AAwGF,eAAe,UAAU,CAAC"}
|