signalium 2.2.3 → 2.3.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/CHANGELOG.md +10 -0
- package/dist/cjs/development/config-B0MtLBgx.js.map +1 -1
- package/dist/cjs/development/{debug-3nd-6Gnf.js → debug-gCDAvnLM.js} +211 -207
- package/dist/cjs/development/debug-gCDAvnLM.js.map +1 -0
- package/dist/cjs/development/debug.js +9 -3
- package/dist/cjs/development/debug.js.map +1 -1
- package/dist/cjs/development/index.js +8 -8
- package/dist/cjs/development/react/index.js +43 -38
- package/dist/cjs/development/react/index.js.map +1 -1
- package/dist/cjs/development/snapshot-Di0yziPX.js +147 -0
- package/dist/cjs/development/snapshot-Di0yziPX.js.map +1 -0
- package/dist/cjs/development/transform/index.js +137 -118
- package/dist/cjs/development/transform/index.js.map +1 -1
- package/dist/cjs/development/utils.js +5 -3
- package/dist/cjs/development/utils.js.map +1 -1
- package/dist/cjs/production/config-B0MtLBgx.js.map +1 -1
- package/dist/cjs/production/{contexts-DoZWv_3I.js → contexts-Wgq2NOVX.js} +130 -133
- package/dist/cjs/production/contexts-Wgq2NOVX.js.map +1 -0
- package/dist/cjs/production/debug.js +61 -66
- package/dist/cjs/production/debug.js.map +1 -1
- package/dist/cjs/production/index.js +8 -8
- package/dist/cjs/production/react/index.js +43 -38
- package/dist/cjs/production/react/index.js.map +1 -1
- package/dist/cjs/production/snapshot-YJJyLbxS.js +147 -0
- package/dist/cjs/production/snapshot-YJJyLbxS.js.map +1 -0
- package/dist/cjs/production/transform/index.js +137 -118
- package/dist/cjs/production/transform/index.js.map +1 -1
- package/dist/cjs/production/utils.js +5 -3
- package/dist/cjs/production/utils.js.map +1 -1
- package/dist/esm/development/config-CPQL7hX-.js.map +1 -1
- package/dist/esm/development/{debug-BfudYKc4.js → debug-AoHfqs62.js} +195 -189
- package/dist/esm/development/debug-AoHfqs62.js.map +1 -0
- package/dist/esm/development/debug.js +1 -1
- package/dist/esm/development/index.js +6 -6
- package/dist/esm/development/react/index.js +43 -38
- package/dist/esm/development/react/index.js.map +1 -1
- package/dist/esm/development/snapshot-Bq0Um_hQ.js +148 -0
- package/dist/esm/development/snapshot-Bq0Um_hQ.js.map +1 -0
- package/dist/esm/development/transform/index.js +137 -118
- package/dist/esm/development/transform/index.js.map +1 -1
- package/dist/esm/development/utils.js +7 -4
- package/dist/esm/development/utils.js.map +1 -1
- package/dist/esm/internals/core-api.d.ts +2 -2
- package/dist/esm/internals/core-api.d.ts.map +1 -1
- package/dist/esm/internals/edge.d.ts +4 -4
- package/dist/esm/internals/edge.d.ts.map +1 -1
- package/dist/esm/internals/reactive.d.ts.map +1 -1
- package/dist/esm/internals/scheduling.d.ts.map +1 -1
- package/dist/esm/internals/signal.d.ts.map +1 -1
- package/dist/esm/internals/utils/snapshot.d.ts +29 -0
- package/dist/esm/internals/utils/snapshot.d.ts.map +1 -0
- package/dist/esm/production/config-CPQL7hX-.js.map +1 -1
- package/dist/esm/production/{contexts-CilfS6eG.js → contexts-X0gSj6rQ.js} +133 -136
- package/dist/esm/production/contexts-X0gSj6rQ.js.map +1 -0
- package/dist/esm/production/debug.js +51 -54
- package/dist/esm/production/debug.js.map +1 -1
- package/dist/esm/production/index.js +7 -7
- package/dist/esm/production/react/index.js +43 -38
- package/dist/esm/production/react/index.js.map +1 -1
- package/dist/esm/production/snapshot-CDS1d8mq.js +148 -0
- package/dist/esm/production/snapshot-CDS1d8mq.js.map +1 -0
- package/dist/esm/production/transform/index.js +137 -118
- package/dist/esm/production/transform/index.js.map +1 -1
- package/dist/esm/production/utils.js +7 -4
- package/dist/esm/production/utils.js.map +1 -1
- package/dist/esm/react/index.d.ts +1 -1
- package/dist/esm/react/index.d.ts.map +1 -1
- package/dist/esm/react/provider.d.ts.map +1 -1
- package/dist/esm/react/use-reactive.d.ts +1 -0
- package/dist/esm/react/use-reactive.d.ts.map +1 -1
- package/dist/esm/transform/callback.d.ts.map +1 -1
- package/dist/esm/transform/promise.d.ts.map +1 -1
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.d.ts.map +1 -1
- package/package.json +7 -5
- package/dist/cjs/development/core-api-C6HCIyL3.js +0 -55
- package/dist/cjs/development/core-api-C6HCIyL3.js.map +0 -1
- package/dist/cjs/development/debug-3nd-6Gnf.js.map +0 -1
- package/dist/cjs/production/contexts-DoZWv_3I.js.map +0 -1
- package/dist/cjs/production/core-api-CUviCxtM.js +0 -55
- package/dist/cjs/production/core-api-CUviCxtM.js.map +0 -1
- package/dist/esm/development/core-api-CjsScNn1.js +0 -56
- package/dist/esm/development/core-api-CjsScNn1.js.map +0 -1
- package/dist/esm/development/debug-BfudYKc4.js.map +0 -1
- package/dist/esm/production/contexts-CilfS6eG.js.map +0 -1
- package/dist/esm/production/core-api-tTQttL8R.js +0 -56
- package/dist/esm/production/core-api-tTQttL8R.js.map +0 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const react = require("react");
|
|
5
|
-
const contexts = require("../contexts-
|
|
6
|
-
const
|
|
5
|
+
const contexts = require("../contexts-Wgq2NOVX.js");
|
|
6
|
+
const snapshot = require("../snapshot-YJJyLbxS.js");
|
|
7
7
|
const ScopeContext = react.createContext(void 0);
|
|
8
8
|
function useScope() {
|
|
9
9
|
return react.useContext(ScopeContext);
|
|
@@ -15,20 +15,14 @@ function useContext(context) {
|
|
|
15
15
|
}
|
|
16
16
|
return scope.getContext(context) ?? context.defaultValue;
|
|
17
17
|
}
|
|
18
|
-
function ContextProvider({
|
|
19
|
-
children,
|
|
20
|
-
contexts: contexts$1 = [],
|
|
21
|
-
inherit = true
|
|
22
|
-
}) {
|
|
18
|
+
function ContextProvider({ children, contexts: contexts$1 = [], inherit = true }) {
|
|
23
19
|
const parentScope = react.useContext(ScopeContext) ?? contexts.getGlobalScope();
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ScopeContext.Provider, { value: scopeRef.current, children });
|
|
20
|
+
const scope = react.useMemo(
|
|
21
|
+
() => new contexts.SignalScope(contexts$1, inherit ? parentScope : void 0),
|
|
22
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23
|
+
[parentScope, inherit, contexts.hashValue(contexts$1)]
|
|
24
|
+
);
|
|
25
|
+
return jsxRuntime.jsx(ScopeContext.Provider, { value: scope, children });
|
|
32
26
|
}
|
|
33
27
|
const SuspendSignalsContext = react.createContext(false);
|
|
34
28
|
const SuspendSignalsProvider = SuspendSignalsContext.Provider;
|
|
@@ -44,31 +38,22 @@ function component(fn) {
|
|
|
44
38
|
propsRef.current = props;
|
|
45
39
|
let signal = fnSignalRef.current;
|
|
46
40
|
if (signal === void 0) {
|
|
47
|
-
fnSignalRef.current = signal = contexts.createReactiveSignal(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
},
|
|
54
|
-
[],
|
|
55
|
-
void 0,
|
|
56
|
-
scope
|
|
57
|
-
);
|
|
41
|
+
fnSignalRef.current = signal = contexts.createReactiveSignal({
|
|
42
|
+
compute: () => fn(propsRef.current),
|
|
43
|
+
equals: () => false,
|
|
44
|
+
isRelay: false,
|
|
45
|
+
tracer: void 0
|
|
46
|
+
}, [], void 0, scope);
|
|
58
47
|
signal._isLazy = true;
|
|
59
48
|
}
|
|
60
49
|
signal.setSuspended(suspended);
|
|
61
|
-
react.useSyncExternalStore(
|
|
62
|
-
signal.addListenerLazy(),
|
|
63
|
-
() => signal.updatedCount,
|
|
64
|
-
() => signal.updatedCount
|
|
65
|
-
);
|
|
50
|
+
react.useSyncExternalStore(signal.addListenerLazy(), () => signal.updatedCount, () => signal.updatedCount);
|
|
66
51
|
contexts.runSignal(signal);
|
|
67
52
|
return signal.value;
|
|
68
53
|
};
|
|
69
54
|
return (props) => {
|
|
70
55
|
const hash = contexts.hashValue(props);
|
|
71
|
-
return react.useMemo(() =>
|
|
56
|
+
return react.useMemo(() => jsxRuntime.jsx(Component, { ...props }), [hash]);
|
|
72
57
|
};
|
|
73
58
|
}
|
|
74
59
|
function useSignal(value, opts) {
|
|
@@ -94,11 +79,7 @@ const useStateSignal = (signal) => {
|
|
|
94
79
|
const useReactiveFnSignal = (signal) => {
|
|
95
80
|
const suspended = useSignalsSuspended();
|
|
96
81
|
signal.setSuspended(suspended);
|
|
97
|
-
return react.useSyncExternalStore(
|
|
98
|
-
signal.addListenerLazy(),
|
|
99
|
-
() => signal.value,
|
|
100
|
-
() => signal.value
|
|
101
|
-
);
|
|
82
|
+
return react.useSyncExternalStore(signal.addListenerLazy(), () => signal.value, () => signal.value);
|
|
102
83
|
};
|
|
103
84
|
const useReactivePromise = (promise) => {
|
|
104
85
|
if (contexts.isRelay(promise)) {
|
|
@@ -108,7 +89,7 @@ const useReactivePromise = (promise) => {
|
|
|
108
89
|
return promise;
|
|
109
90
|
};
|
|
110
91
|
const useReactiveFn = (fn, ...args) => {
|
|
111
|
-
const [, def] =
|
|
92
|
+
const [, def] = snapshot.getReactiveFnAndDefinition(fn);
|
|
112
93
|
const scope = useScope() ?? contexts.getGlobalScope();
|
|
113
94
|
const signal = scope.get(def, args);
|
|
114
95
|
const value = useReactiveFnSignal(signal);
|
|
@@ -138,11 +119,35 @@ function useReactive(signal, ...args) {
|
|
|
138
119
|
return useStateSignal(signal);
|
|
139
120
|
}
|
|
140
121
|
}
|
|
122
|
+
function useReactiveDeep(fn, ...args) {
|
|
123
|
+
if (contexts.getCurrentConsumer()) {
|
|
124
|
+
throw new Error("useReactiveDeep cannot be used inside of a reactive context. You can use the signal/function directly instead.");
|
|
125
|
+
}
|
|
126
|
+
const suspended = useSignalsSuspended();
|
|
127
|
+
const scope = useScope() ?? contexts.getGlobalScope();
|
|
128
|
+
const signalRef = react.useRef();
|
|
129
|
+
const cloneSignalRef = react.useRef();
|
|
130
|
+
const valueRef = react.useRef();
|
|
131
|
+
const [, def] = snapshot.getReactiveFnAndDefinition(fn);
|
|
132
|
+
const signal = scope.get(def, args);
|
|
133
|
+
if (signalRef.current !== signal) {
|
|
134
|
+
signalRef.current = signal;
|
|
135
|
+
cloneSignalRef.current = snapshot.reactiveSignal(() => {
|
|
136
|
+
const next = snapshot.snapshot(signal.value, valueRef.current);
|
|
137
|
+
valueRef.current = next;
|
|
138
|
+
return next;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const cloneSignal = cloneSignalRef.current;
|
|
142
|
+
cloneSignal.setSuspended(suspended);
|
|
143
|
+
return react.useSyncExternalStore(cloneSignal.addListenerLazy(), () => cloneSignal.value, () => cloneSignal.value);
|
|
144
|
+
}
|
|
141
145
|
exports.ContextProvider = ContextProvider;
|
|
142
146
|
exports.SuspendSignalsProvider = SuspendSignalsProvider;
|
|
143
147
|
exports.component = component;
|
|
144
148
|
exports.useContext = useContext;
|
|
145
149
|
exports.useReactive = useReactive;
|
|
150
|
+
exports.useReactiveDeep = useReactiveDeep;
|
|
146
151
|
exports.useSignal = useSignal;
|
|
147
152
|
exports.useSignalsSuspended = useSignalsSuspended;
|
|
148
153
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/react/context.ts","../../../../src/react/provider.tsx","../../../../src/react/suspend-signals-context.ts","../../../../src/react/component.tsx","../../../../src/react/use-signal.ts","../../../../src/react/use-reactive.ts"],"sourcesContent":["import { createContext, useContext as useReactContext } from 'react';\nimport { ContextImpl, SignalScope } from '../internals/contexts.js';\nimport { getCurrentConsumer } from '../internals/consumer.js';\nimport { Context } from '../types.js';\n\nexport const ScopeContext = createContext<SignalScope | undefined>(undefined);\n\nexport function useScope() {\n return useReactContext(ScopeContext);\n}\n\nexport function useContext<T>(context: Context<T>): T {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const scope = getCurrentConsumer()?.scope ?? useScope();\n\n if (!scope) {\n throw new Error('useContext must be used within a signal hook, a withContext, or a component');\n }\n\n return scope.getContext(context) ?? (context as unknown as ContextImpl<T>).defaultValue;\n}\n","import { useContext, useRef } from 'react';\nimport { ScopeContext } from './context.js';\nimport { ContextImpl, ContextPair, getGlobalScope, SignalScope } from '../internals/contexts.js';\n\nexport function ContextProvider<C extends unknown[]>({\n children,\n contexts = [],\n inherit = true,\n}: {\n children: React.ReactNode;\n contexts?: [...ContextPair<C>] | [];\n inherit?: boolean;\n}) {\n const parentScope = useContext(ScopeContext) ?? getGlobalScope();\n const scopeRef = useRef<SignalScope | null>(null);\n if (scopeRef.current === null) {\n scopeRef.current = new SignalScope(\n contexts as [ContextImpl<unknown>, unknown][],\n inherit ? parentScope : undefined,\n );\n }\n\n return <ScopeContext.Provider value={scopeRef.current}>{children}</ScopeContext.Provider>;\n}\n","import { createContext, useContext } from 'react';\n\nconst SuspendSignalsContext = createContext<boolean>(false);\n\nexport const SuspendSignalsProvider = SuspendSignalsContext.Provider;\n\nexport function useSignalsSuspended(): boolean {\n return useContext(SuspendSignalsContext);\n}\n","import { useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useScope } from './context.js';\nimport { useSignalsSuspended } from './suspend-signals-context.js';\nimport { createReactiveSignal, ReactiveSignal } from '../internals/reactive.js';\nimport { runSignal } from '../internals/get.js';\nimport { hashValue } from '../internals/utils/hash.js';\n\nexport default function component<Props extends object>(\n fn: (props: Props) => React.ReactNode | React.ReactNode[] | null,\n) {\n const Component = (props: Props) => {\n const scope = useScope();\n const suspended = useSignalsSuspended();\n\n const fnSignalRef = useRef<ReactiveSignal<React.ReactNode | React.ReactNode[] | null, []> | undefined>(undefined);\n const propsRef = useRef<Props>(props);\n\n propsRef.current = props;\n\n let signal = fnSignalRef.current;\n\n if (signal === undefined) {\n fnSignalRef.current = signal = createReactiveSignal(\n {\n compute: () => fn(propsRef.current),\n equals: () => false,\n isRelay: false,\n tracer: undefined,\n },\n [],\n undefined,\n scope,\n );\n\n signal._isLazy = true;\n }\n\n signal.setSuspended(suspended);\n\n // We always want to re-render when the signal is updated, regardless of\n // whether or not the result changed. This is because the signal is lazy,\n // so it will not be updated until the next render.\n useSyncExternalStore(\n signal.addListenerLazy(),\n () => signal.updatedCount,\n () => signal.updatedCount,\n );\n\n runSignal(signal as ReactiveSignal<any, any[]>);\n\n return signal.value;\n };\n\n return (props: Props) => {\n const hash = hashValue(props);\n // Renders Comp only when hash changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => <Component {...props} />, [hash]);\n };\n}\n","import { useRef } from 'react';\nimport { SignalOptions, Signal } from '../types.js';\nimport { signal } from '../index.js';\n\nexport function useSignal<T>(value: T, opts?: SignalOptions<T>): Signal<T> {\n const ref = useRef<Signal<T> | undefined>(undefined);\n\n if (!ref.current) {\n ref.current = signal(value, opts);\n }\n\n return ref.current;\n}\n","/* eslint-disable react-hooks/rules-of-hooks */\nimport { useCallback, useSyncExternalStore } from 'react';\nimport { ReactiveValue, Signal, ReactivePromise } from '../types.js';\nimport { getReactiveFnAndDefinition } from '../internals/core-api.js';\nimport { getCurrentConsumer } from '../internals/consumer.js';\nimport { ReactiveSignal } from '../internals/reactive.js';\nimport { isReactivePromise, isRelay, ReactivePromiseImpl } from '../internals/async.js';\nimport { StateSignal } from '../internals/signal.js';\nimport { useScope } from './context.js';\nimport { useSignalsSuspended } from './suspend-signals-context.js';\nimport { getGlobalScope } from '../internals/contexts.js';\n\nconst useStateSignal = <T>(signal: Signal<T>): T => {\n const suspended = useSignalsSuspended();\n return useSyncExternalStore(\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useCallback(suspended ? () => () => {} : onStoreChange => (signal as StateSignal<T>).addListener(onStoreChange), [\n signal,\n suspended,\n ]),\n () => signal.value,\n () => signal.value,\n );\n};\n\nconst useReactiveFnSignal = <R, Args extends unknown[]>(signal: ReactiveSignal<R, Args>): ReactiveValue<R> => {\n const suspended = useSignalsSuspended();\n\n signal.setSuspended(suspended);\n\n return useSyncExternalStore(\n signal.addListenerLazy(),\n () => signal.value,\n () => signal.value,\n );\n};\n\nconst useReactivePromise = <R>(promise: ReactivePromiseImpl<R>): ReactivePromise<R> => {\n if (isRelay(promise)) {\n useReactiveFnSignal(promise['_signal'] as ReactiveSignal<any, unknown[]>);\n }\n\n useStateSignal(promise['_version']);\n\n return promise as ReactivePromise<R>;\n};\n\nconst useReactiveFn = <R, Args extends readonly Narrowable[]>(fn: (...args: Args) => R, ...args: Args): R => {\n const [, def] = getReactiveFnAndDefinition(fn as any);\n\n const scope = useScope() ?? getGlobalScope();\n\n const signal = scope.get(def, args as any);\n const value = useReactiveFnSignal(signal);\n\n // Reactive promises can update their value independently of the signal, since\n // we reuse the same promise object for each result. We need to entangle the\n // version of the promise here so that we can trigger a re-render when the\n // promise value updates.\n //\n // If hooks could be called in dynamic order this would not be necessary, we\n // could entangle the promise when it is used. But, because that is not the\n // case, we need to eagerly entangle.\n if (typeof value === 'object' && value !== null && isReactivePromise(value)) {\n return useReactivePromise(value) as R;\n }\n\n return value as R;\n};\n\nconst isNonNullishAsyncSignal = (value: unknown): value is ReactivePromise<unknown> => {\n return typeof value === 'object' && value !== null && isReactivePromise(value as object);\n};\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ntype Narrowable = string | number | boolean | null | undefined | bigint | symbol | {};\n\nexport function useReactive<R>(signal: Signal<R>): R;\nexport function useReactive<R>(signal: ReactivePromise<R>): ReactivePromise<R>;\nexport function useReactive<R, Args extends readonly Narrowable[]>(fn: (...args: Args) => R, ...args: Args): R;\nexport function useReactive<R, Args extends readonly Narrowable[]>(\n signal: Signal<R> | ReactivePromise<R> | ((...args: Args) => R),\n ...args: Args\n): R | ReactivePromise<R> {\n if (getCurrentConsumer()) {\n if (typeof signal === 'function') {\n return signal(...args);\n } else if (isNonNullishAsyncSignal(signal)) {\n return signal as ReactivePromise<R>;\n } else {\n return (signal as Signal<R>).value;\n }\n }\n\n if (typeof signal === 'function') {\n return useReactiveFn(signal, ...args);\n } else if (typeof signal === 'object' && signal !== null && isReactivePromise(signal)) {\n return useReactivePromise(signal) as ReactivePromise<R>;\n } else {\n return useStateSignal(signal as Signal<R>);\n }\n}\n"],"names":["createContext","useReactContext","getCurrentConsumer","contexts","useContext","getGlobalScope","useRef","SignalScope","createReactiveSignal","useSyncExternalStore","runSignal","hashValue","useMemo","jsx","signal","useCallback","isRelay","getReactiveFnAndDefinition","isReactivePromise"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../.tsc-out/react/context.js","../../../../.tsc-out/react/provider.js","../../../../.tsc-out/react/suspend-signals-context.js","../../../../.tsc-out/react/component.js","../../../../.tsc-out/react/use-signal.js","../../../../.tsc-out/react/use-reactive.js"],"sourcesContent":["import { createContext, useContext as useReactContext } from 'react';\nimport { getCurrentConsumer } from '../internals/consumer.js';\nexport const ScopeContext = createContext(undefined);\nexport function useScope() {\n return useReactContext(ScopeContext);\n}\nexport function useContext(context) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n const scope = getCurrentConsumer()?.scope ?? useScope();\n if (!scope) {\n throw new Error('useContext must be used within a signal hook, a withContext, or a component');\n }\n return scope.getContext(context) ?? context.defaultValue;\n}\n","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useContext, useMemo } from 'react';\nimport { ScopeContext } from './context.js';\nimport { getGlobalScope, SignalScope } from '../internals/contexts.js';\nimport { hashValue } from '../internals/utils/hash.js';\nexport function ContextProvider({ children, contexts = [], inherit = true, }) {\n const parentScope = useContext(ScopeContext) ?? getGlobalScope();\n const scope = useMemo(() => new SignalScope(contexts, inherit ? parentScope : undefined), \n // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentScope, inherit, hashValue(contexts)]);\n return _jsx(ScopeContext.Provider, { value: scope, children: children });\n}\n","import { createContext, useContext } from 'react';\nconst SuspendSignalsContext = createContext(false);\nexport const SuspendSignalsProvider = SuspendSignalsContext.Provider;\nexport function useSignalsSuspended() {\n return useContext(SuspendSignalsContext);\n}\n","import { jsx as _jsx } from \"react/jsx-runtime\";\nimport { useMemo, useRef, useSyncExternalStore } from 'react';\nimport { useScope } from './context.js';\nimport { useSignalsSuspended } from './suspend-signals-context.js';\nimport { createReactiveSignal } from '../internals/reactive.js';\nimport { runSignal } from '../internals/get.js';\nimport { hashValue } from '../internals/utils/hash.js';\nexport default function component(fn) {\n const Component = (props) => {\n const scope = useScope();\n const suspended = useSignalsSuspended();\n const fnSignalRef = useRef(undefined);\n const propsRef = useRef(props);\n propsRef.current = props;\n let signal = fnSignalRef.current;\n if (signal === undefined) {\n fnSignalRef.current = signal = createReactiveSignal({\n compute: () => fn(propsRef.current),\n equals: () => false,\n isRelay: false,\n tracer: undefined,\n }, [], undefined, scope);\n signal._isLazy = true;\n }\n signal.setSuspended(suspended);\n // We always want to re-render when the signal is updated, regardless of\n // whether or not the result changed. This is because the signal is lazy,\n // so it will not be updated until the next render.\n useSyncExternalStore(signal.addListenerLazy(), () => signal.updatedCount, () => signal.updatedCount);\n runSignal(signal);\n return signal.value;\n };\n return (props) => {\n const hash = hashValue(props);\n // Renders Comp only when hash changes\n // eslint-disable-next-line react-hooks/exhaustive-deps\n return useMemo(() => _jsx(Component, { ...props }), [hash]);\n };\n}\n","import { useRef } from 'react';\nimport { signal } from '../index.js';\nexport function useSignal(value, opts) {\n const ref = useRef(undefined);\n if (!ref.current) {\n ref.current = signal(value, opts);\n }\n return ref.current;\n}\n","/* eslint-disable react-hooks/rules-of-hooks */\nimport { useCallback, useRef, useSyncExternalStore } from 'react';\nimport { getReactiveFnAndDefinition, reactiveSignal } from '../internals/core-api.js';\nimport { getCurrentConsumer } from '../internals/consumer.js';\nimport { isReactivePromise, isRelay } from '../internals/async.js';\nimport { snapshot } from '../internals/utils/snapshot.js';\nimport { useScope } from './context.js';\nimport { useSignalsSuspended } from './suspend-signals-context.js';\nimport { getGlobalScope } from '../internals/contexts.js';\nconst useStateSignal = (signal) => {\n const suspended = useSignalsSuspended();\n return useSyncExternalStore(\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useCallback(suspended ? () => () => { } : onStoreChange => signal.addListener(onStoreChange), [\n signal,\n suspended,\n ]), () => signal.value, () => signal.value);\n};\nconst useReactiveFnSignal = (signal) => {\n const suspended = useSignalsSuspended();\n signal.setSuspended(suspended);\n return useSyncExternalStore(signal.addListenerLazy(), () => signal.value, () => signal.value);\n};\nconst useReactivePromise = (promise) => {\n if (isRelay(promise)) {\n useReactiveFnSignal(promise['_signal']);\n }\n useStateSignal(promise['_version']);\n return promise;\n};\nconst useReactiveFn = (fn, ...args) => {\n const [, def] = getReactiveFnAndDefinition(fn);\n const scope = useScope() ?? getGlobalScope();\n const signal = scope.get(def, args);\n const value = useReactiveFnSignal(signal);\n // Reactive promises can update their value independently of the signal, since\n // we reuse the same promise object for each result. We need to entangle the\n // version of the promise here so that we can trigger a re-render when the\n // promise value updates.\n //\n // If hooks could be called in dynamic order this would not be necessary, we\n // could entangle the promise when it is used. But, because that is not the\n // case, we need to eagerly entangle.\n if (typeof value === 'object' && value !== null && isReactivePromise(value)) {\n return useReactivePromise(value);\n }\n return value;\n};\nconst isNonNullishAsyncSignal = (value) => {\n return typeof value === 'object' && value !== null && isReactivePromise(value);\n};\nexport function useReactive(signal, ...args) {\n if (getCurrentConsumer()) {\n if (typeof signal === 'function') {\n return signal(...args);\n }\n else if (isNonNullishAsyncSignal(signal)) {\n return signal;\n }\n else {\n return signal.value;\n }\n }\n if (typeof signal === 'function') {\n return useReactiveFn(signal, ...args);\n }\n else if (typeof signal === 'object' && signal !== null && isReactivePromise(signal)) {\n return useReactivePromise(signal);\n }\n else {\n return useStateSignal(signal);\n }\n}\nexport function useReactiveDeep(fn, ...args) {\n if (getCurrentConsumer()) {\n throw new Error('useReactiveDeep cannot be used inside of a reactive context. You can use the signal/function directly instead.');\n }\n const suspended = useSignalsSuspended();\n const scope = useScope() ?? getGlobalScope();\n const signalRef = useRef();\n const cloneSignalRef = useRef();\n const valueRef = useRef();\n const [, def] = getReactiveFnAndDefinition(fn);\n const signal = scope.get(def, args);\n if (signalRef.current !== signal) {\n signalRef.current = signal;\n cloneSignalRef.current = reactiveSignal(() => {\n const next = snapshot(signal.value, valueRef.current);\n valueRef.current = next;\n return next;\n });\n }\n const cloneSignal = cloneSignalRef.current;\n cloneSignal.setSuspended(suspended);\n return useSyncExternalStore(cloneSignal.addListenerLazy(), () => cloneSignal.value, () => cloneSignal.value);\n}\n"],"names":["createContext","useReactContext","getCurrentConsumer","contexts","useContext","getGlobalScope","useMemo","SignalScope","hashValue","_jsx","useRef","createReactiveSignal","useSyncExternalStore","runSignal","signal","useCallback","isRelay","getReactiveFnAndDefinition","isReactivePromise","reactiveSignal","snapshot"],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const contexts = require("./contexts-Wgq2NOVX.js");
|
|
3
|
+
const DERIVED_DEFINITION_MAP = /* @__PURE__ */ new WeakMap();
|
|
4
|
+
function getReactiveFnAndDefinition(fn, opts) {
|
|
5
|
+
let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);
|
|
6
|
+
if (!fnAndDef) {
|
|
7
|
+
const def = contexts.createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey);
|
|
8
|
+
const defScope = contexts.getCurrentScope();
|
|
9
|
+
const reactiveFn = (...args) => {
|
|
10
|
+
const scope = contexts.getCurrentScope(defScope);
|
|
11
|
+
const signal = scope.get(def, args);
|
|
12
|
+
return signal.value;
|
|
13
|
+
};
|
|
14
|
+
fnAndDef = [reactiveFn, def];
|
|
15
|
+
DERIVED_DEFINITION_MAP.set(fn, fnAndDef);
|
|
16
|
+
}
|
|
17
|
+
return fnAndDef;
|
|
18
|
+
}
|
|
19
|
+
function reactive(fn, opts) {
|
|
20
|
+
return getReactiveFnAndDefinition(fn, opts)[0];
|
|
21
|
+
}
|
|
22
|
+
const reactiveMethod = (owner, fn, opts) => {
|
|
23
|
+
const def = contexts.createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey);
|
|
24
|
+
const reactiveFn = (...args) => {
|
|
25
|
+
return contexts.getScopeOwner(owner).get(def, args).value;
|
|
26
|
+
};
|
|
27
|
+
DERIVED_DEFINITION_MAP.set(reactiveFn, [reactiveFn, def]);
|
|
28
|
+
return reactiveFn;
|
|
29
|
+
};
|
|
30
|
+
function relay(activate, opts) {
|
|
31
|
+
const scope = contexts.getCurrentScope();
|
|
32
|
+
return contexts.createRelay(activate, scope, opts);
|
|
33
|
+
}
|
|
34
|
+
const task = (fn, opts) => {
|
|
35
|
+
const scope = contexts.getCurrentScope();
|
|
36
|
+
return contexts.createTask(fn, scope, opts);
|
|
37
|
+
};
|
|
38
|
+
function watcher(fn, opts) {
|
|
39
|
+
const def = contexts.createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, void 0, opts?.tracer);
|
|
40
|
+
const scope = opts?.isolate ? new contexts.SignalScope([]) : contexts.getCurrentScope();
|
|
41
|
+
return contexts.createReactiveSignal(def, void 0, void 0, scope);
|
|
42
|
+
}
|
|
43
|
+
const reactiveSignal = (compute, opts) => {
|
|
44
|
+
const def = contexts.createReactiveDefinition(opts?.id, opts?.desc, compute, opts?.equals, false, void 0);
|
|
45
|
+
const scope = opts?.isolate ? new contexts.SignalScope([]) : contexts.getCurrentScope();
|
|
46
|
+
return contexts.createReactiveSignal(def, void 0, void 0, scope);
|
|
47
|
+
};
|
|
48
|
+
const getProto = Object.getPrototypeOf;
|
|
49
|
+
function snapshotArray(current, prev, snap) {
|
|
50
|
+
const prevArr = Array.isArray(prev) ? prev : void 0;
|
|
51
|
+
let changed = !prevArr || prevArr.length !== current.length;
|
|
52
|
+
const result = new Array(current.length);
|
|
53
|
+
for (let i = 0; i < current.length; i++) {
|
|
54
|
+
result[i] = snap(current[i], prevArr?.[i]);
|
|
55
|
+
if (!changed && result[i] !== prevArr[i]) {
|
|
56
|
+
changed = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return changed ? result : prevArr;
|
|
60
|
+
}
|
|
61
|
+
function snapshotPlainObject(current, prev, snap) {
|
|
62
|
+
const prevObj = prev !== null && prev !== void 0 && typeof prev === "object" && !Array.isArray(prev) ? prev : void 0;
|
|
63
|
+
const keys = Object.keys(current);
|
|
64
|
+
let changed = !prevObj || Object.keys(prevObj).length !== keys.length;
|
|
65
|
+
const result = {};
|
|
66
|
+
for (let i = 0; i < keys.length; i++) {
|
|
67
|
+
const key = keys[i];
|
|
68
|
+
result[key] = snap(current[key], prevObj?.[key]);
|
|
69
|
+
if (!changed && result[key] !== prevObj[key]) {
|
|
70
|
+
changed = true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return changed ? result : prevObj;
|
|
74
|
+
}
|
|
75
|
+
function snapshotReactivePromise(current, prev, snap) {
|
|
76
|
+
const prevObj = prev !== null && prev !== void 0 && typeof prev === "object" ? prev : void 0;
|
|
77
|
+
const value = snap(current.value, prevObj?.value);
|
|
78
|
+
const error = current.error;
|
|
79
|
+
const isPending = current.isPending;
|
|
80
|
+
const isRejected = current.isRejected;
|
|
81
|
+
const isResolved = current.isResolved;
|
|
82
|
+
const isReady = current.isReady;
|
|
83
|
+
const isSettled = current.isSettled;
|
|
84
|
+
if (prevObj && value === prevObj.value && error === prevObj.error && isPending === prevObj.isPending && isRejected === prevObj.isRejected && isResolved === prevObj.isResolved && isReady === prevObj.isReady && isSettled === prevObj.isSettled) {
|
|
85
|
+
return prevObj;
|
|
86
|
+
}
|
|
87
|
+
return { value, error, isPending, isRejected, isResolved, isReady, isSettled };
|
|
88
|
+
}
|
|
89
|
+
function snapshotMap(current, prev, snap) {
|
|
90
|
+
const prevMap = prev instanceof Map ? prev : void 0;
|
|
91
|
+
let changed = !prevMap || prevMap.size !== current.size;
|
|
92
|
+
const result = /* @__PURE__ */ new Map();
|
|
93
|
+
for (const [key, val] of current) {
|
|
94
|
+
const snapped = snap(val, prevMap?.get(key));
|
|
95
|
+
result.set(key, snapped);
|
|
96
|
+
if (!changed && snapped !== prevMap.get(key)) {
|
|
97
|
+
changed = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return changed ? result : prevMap;
|
|
101
|
+
}
|
|
102
|
+
function snapshotSet(current, prev, _snap) {
|
|
103
|
+
const prevSet = prev instanceof Set ? prev : void 0;
|
|
104
|
+
let changed = !prevSet || prevSet.size !== current.size;
|
|
105
|
+
const result = /* @__PURE__ */ new Set();
|
|
106
|
+
for (const val of current) {
|
|
107
|
+
const snapped = snapshot(val, prevSet?.has(val) ? val : void 0);
|
|
108
|
+
result.add(snapped);
|
|
109
|
+
if (!changed && !prevSet.has(snapped)) {
|
|
110
|
+
changed = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return changed ? result : prevSet;
|
|
114
|
+
}
|
|
115
|
+
const PROTO_TO_SNAPSHOT = /* @__PURE__ */ new Map([
|
|
116
|
+
[Object.prototype, snapshotPlainObject],
|
|
117
|
+
[Array.prototype, snapshotArray],
|
|
118
|
+
[Map.prototype, snapshotMap],
|
|
119
|
+
[Set.prototype, snapshotSet],
|
|
120
|
+
[null, snapshotPlainObject]
|
|
121
|
+
]);
|
|
122
|
+
const registerCustomSnapshot = (ctor, snapshotFn) => {
|
|
123
|
+
PROTO_TO_SNAPSHOT.set(ctor.prototype, snapshotFn);
|
|
124
|
+
};
|
|
125
|
+
function snapshot(currentValue, prevValue) {
|
|
126
|
+
if (currentValue === null || typeof currentValue !== "object") {
|
|
127
|
+
return currentValue;
|
|
128
|
+
}
|
|
129
|
+
if (contexts.isReactivePromise(currentValue)) {
|
|
130
|
+
return snapshotReactivePromise(currentValue, prevValue, snapshot);
|
|
131
|
+
}
|
|
132
|
+
const handler = PROTO_TO_SNAPSHOT.get(getProto(currentValue));
|
|
133
|
+
if (handler !== void 0) {
|
|
134
|
+
return handler(currentValue, prevValue, snapshot);
|
|
135
|
+
}
|
|
136
|
+
return currentValue;
|
|
137
|
+
}
|
|
138
|
+
exports.getReactiveFnAndDefinition = getReactiveFnAndDefinition;
|
|
139
|
+
exports.reactive = reactive;
|
|
140
|
+
exports.reactiveMethod = reactiveMethod;
|
|
141
|
+
exports.reactiveSignal = reactiveSignal;
|
|
142
|
+
exports.registerCustomSnapshot = registerCustomSnapshot;
|
|
143
|
+
exports.relay = relay;
|
|
144
|
+
exports.snapshot = snapshot;
|
|
145
|
+
exports.task = task;
|
|
146
|
+
exports.watcher = watcher;
|
|
147
|
+
//# sourceMappingURL=snapshot-YJJyLbxS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-YJJyLbxS.js","sources":["../../../.tsc-out/internals/core-api.js","../../../.tsc-out/internals/utils/snapshot.js"],"sourcesContent":["import { getCurrentScope, getScopeOwner, SignalScope } from './contexts.js';\nimport { createReactiveDefinition, createReactiveSignal, } from './reactive.js';\nimport { createRelay, createTask } from './async.js';\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const DERIVED_DEFINITION_MAP = new WeakMap();\nexport function getReactiveFnAndDefinition(fn, opts) {\n let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);\n if (!fnAndDef) {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n const defScope = getCurrentScope();\n const reactiveFn = (...args) => {\n const scope = getCurrentScope(defScope);\n const signal = scope.get(def, args);\n return signal.value;\n };\n fnAndDef = [reactiveFn, def];\n DERIVED_DEFINITION_MAP.set(fn, fnAndDef);\n }\n return fnAndDef;\n}\nexport function reactive(fn, opts) {\n return getReactiveFnAndDefinition(fn, opts)[0];\n}\nexport const reactiveMethod = (owner, fn, opts) => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n const reactiveFn = (...args) => {\n return getScopeOwner(owner).get(def, args).value;\n };\n DERIVED_DEFINITION_MAP.set(reactiveFn, [reactiveFn, def]);\n return reactiveFn;\n};\nexport function relay(activate, opts) {\n const scope = getCurrentScope();\n return createRelay(activate, scope, opts);\n}\nexport const task = (fn, opts) => {\n const scope = getCurrentScope();\n return createTask(fn, scope, opts);\n};\nexport function watcher(fn, opts) {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, undefined, opts?.tracer);\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n return createReactiveSignal(def, undefined, undefined, scope);\n}\n/**\n * Creates a reactive signal from a compute function. This is useful for when you\n * want to create a signal that does not receive parameters, but is still reactive.\n *\n * @param compute\n * @param opts\n * @returns\n */\nexport const reactiveSignal = (compute, opts) => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, compute, opts?.equals, false, undefined, undefined);\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n return createReactiveSignal(def, undefined, undefined, scope);\n};\n","import { isReactivePromise } from '../async.js';\nconst getProto = Object.getPrototypeOf;\nfunction snapshotArray(current, prev, snap) {\n const prevArr = Array.isArray(prev) ? prev : undefined;\n let changed = !prevArr || prevArr.length !== current.length;\n const result = new Array(current.length);\n for (let i = 0; i < current.length; i++) {\n result[i] = snap(current[i], prevArr?.[i]);\n if (!changed && result[i] !== prevArr[i]) {\n changed = true;\n }\n }\n return changed ? result : prevArr;\n}\nfunction snapshotPlainObject(current, prev, snap) {\n const prevObj = prev !== null && prev !== undefined && typeof prev === 'object' && !Array.isArray(prev)\n ? prev\n : undefined;\n const keys = Object.keys(current);\n let changed = !prevObj || Object.keys(prevObj).length !== keys.length;\n const result = {};\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n result[key] = snap(current[key], prevObj?.[key]);\n if (!changed && result[key] !== prevObj[key]) {\n changed = true;\n }\n }\n return changed ? result : prevObj;\n}\nfunction snapshotReactivePromise(current, prev, snap) {\n const prevObj = prev !== null && prev !== undefined && typeof prev === 'object' ? prev : undefined;\n const value = snap(current.value, prevObj?.value);\n const error = current.error;\n const isPending = current.isPending;\n const isRejected = current.isRejected;\n const isResolved = current.isResolved;\n const isReady = current.isReady;\n const isSettled = current.isSettled;\n if (prevObj &&\n value === prevObj.value &&\n error === prevObj.error &&\n isPending === prevObj.isPending &&\n isRejected === prevObj.isRejected &&\n isResolved === prevObj.isResolved &&\n isReady === prevObj.isReady &&\n isSettled === prevObj.isSettled) {\n return prevObj;\n }\n return { value, error, isPending, isRejected, isResolved, isReady, isSettled };\n}\nfunction snapshotMap(current, prev, snap) {\n const prevMap = prev instanceof Map ? prev : undefined;\n let changed = !prevMap || prevMap.size !== current.size;\n const result = new Map();\n for (const [key, val] of current) {\n const snapped = snap(val, prevMap?.get(key));\n result.set(key, snapped);\n if (!changed && snapped !== prevMap.get(key)) {\n changed = true;\n }\n }\n return changed ? result : prevMap;\n}\nfunction snapshotSet(current, prev, _snap) {\n const prevSet = prev instanceof Set ? prev : undefined;\n let changed = !prevSet || prevSet.size !== current.size;\n const result = new Set();\n for (const val of current) {\n const snapped = snapshot(val, prevSet?.has(val) ? val : undefined);\n result.add(snapped);\n if (!changed && !prevSet.has(snapped)) {\n changed = true;\n }\n }\n return changed ? result : prevSet;\n}\nconst PROTO_TO_SNAPSHOT = new Map([\n [Object.prototype, snapshotPlainObject],\n [Array.prototype, snapshotArray],\n [Map.prototype, snapshotMap],\n [Set.prototype, snapshotSet],\n [null, snapshotPlainObject],\n]);\n/**\n * Register a custom snapshot function for instances of a class.\n * The function receives the current value, the previous snapshot (or undefined),\n * and the recursive `snapshot` function for snapshotting nested values.\n *\n * Return `prev` when nothing has changed to preserve reference stability.\n *\n * @example\n * ```ts\n * registerCustomSnapshot(MyEntity, (current, prev, snapshot) => {\n * const name = snapshot(current.name, prev?.name);\n * const age = current.age;\n * if (prev && name === prev.name && age === prev.age) return prev;\n * return { name, age };\n * });\n * ```\n */\nexport const registerCustomSnapshot = (ctor, snapshotFn) => {\n PROTO_TO_SNAPSHOT.set(ctor.prototype, snapshotFn);\n};\n/**\n * Recursively snapshot a value with structural sharing.\n *\n * - Plain objects and arrays are deep-cloned; unchanged subtrees keep the same reference.\n * - ReactivePromise instances are read (establishing deps) and flattened to a plain object.\n * - Class instances (non-plain prototypes) are returned as-is unless a custom handler is registered.\n * - Primitives are returned directly.\n */\nexport function snapshot(currentValue, prevValue) {\n if (currentValue === null || typeof currentValue !== 'object') {\n return currentValue;\n }\n if (isReactivePromise(currentValue)) {\n return snapshotReactivePromise(currentValue, prevValue, snapshot);\n }\n const handler = PROTO_TO_SNAPSHOT.get(getProto(currentValue));\n if (handler !== undefined) {\n return handler(currentValue, prevValue, snapshot);\n }\n return currentValue;\n}\n"],"names":["createReactiveDefinition","getCurrentScope","getScopeOwner","createRelay","createTask","SignalScope","createReactiveSignal","isReactivePromise"],"mappings":"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"}
|