@preact/signals-react 3.6.2 → 3.7.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/package.json +1 -1
- package/runtime/dist/index.d.ts +2 -2
- package/runtime/dist/runtime.js +1 -1
- package/runtime/dist/runtime.js.map +1 -1
- package/runtime/dist/runtime.min.js +1 -1
- package/runtime/dist/runtime.min.js.map +1 -1
- package/runtime/dist/runtime.mjs +1 -1
- package/runtime/dist/runtime.mjs.map +1 -1
- package/runtime/dist/runtime.module.js +1 -1
- package/runtime/dist/runtime.module.js.map +1 -1
- package/runtime/src/index.ts +18 -8
- package/utils/dist/index.d.ts +6 -0
- package/utils/dist/utils.js +1 -1
- package/utils/dist/utils.js.map +1 -1
- package/utils/dist/utils.min.js +1 -1
- package/utils/dist/utils.min.js.map +1 -1
- package/utils/dist/utils.mjs +1 -1
- package/utils/dist/utils.mjs.map +1 -1
- package/utils/dist/utils.module.js +1 -1
- package/utils/dist/utils.module.js.map +1 -1
- package/utils/src/index.tsx +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @preact/signals-react
|
|
2
2
|
|
|
3
|
+
## 3.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#839](https://github.com/preactjs/signals/pull/839) [`18969fa`](https://github.com/preactjs/signals/commit/18969fada30397f537828af9e839acc7348f9684) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Add `componentName` to `useSignals` for debugging
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#836](https://github.com/preactjs/signals/pull/836) [`ac5032e`](https://github.com/preactjs/signals/commit/ac5032e63000cdb0bf84e20a1b44c161788a1607) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Ensure that the `For` and `Show` component have display-names
|
|
12
|
+
|
|
3
13
|
## 3.6.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/package.json
CHANGED
package/runtime/dist/index.d.ts
CHANGED
|
@@ -56,8 +56,8 @@ export declare function ensureFinalCleanup(): void;
|
|
|
56
56
|
* Custom hook to create the effect to track signals used during render and
|
|
57
57
|
* subscribe to changes to rerender the component when the signals change.
|
|
58
58
|
*/
|
|
59
|
-
export declare function _useSignalsImplementation(_usage?: EffectStoreUsage): EffectStore;
|
|
60
|
-
export declare function useSignals(usage?: EffectStoreUsage): EffectStore;
|
|
59
|
+
export declare function _useSignalsImplementation(_usage?: EffectStoreUsage, componentName?: string): EffectStore;
|
|
60
|
+
export declare function useSignals(usage?: EffectStoreUsage, componentName?: string): EffectStore;
|
|
61
61
|
export declare function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;
|
|
62
62
|
export declare function useSignal<T = undefined>(): Signal<T | undefined>;
|
|
63
63
|
export declare function useComputed<T>(compute: () => T, options?: SignalOptions<T>): ReadonlySignal<T>;
|
package/runtime/dist/runtime.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var n,t=require("@preact/signals-core"),e=require("react"),r=require("use-sync-external-store/shim/index.js"),i=e.version.split(".").map(Number)[0],
|
|
1
|
+
var n,t=require("@preact/signals-core"),e=require("react"),r=require("use-sync-external-store/shim/index.js"),i=e.version.split(".").map(Number)[0],o=[],u=Symbol.for(i>=19?"react.transitional.element":"react.element"),f="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__,c=Symbol.dispose||Symbol.for("Symbol.dispose");function s(t,e){var r=e.effect.S();n=e;return a.bind(e,t,r)}function a(t,e){e();n=t}var l,v,d=function(){},p=((l={o:0,effect:{s:void 0,c:function(){},S:function(){return d},d:function(){}},subscribe:function(){return d},getSnapshot:function(){return 0},S:function(){},f:function(){}})[c]=function(){},l),b=Promise.prototype.then.bind(Promise.resolve());function y(){if(!v)v=b(m)}function m(){var t;v=void 0;null==(t=n)||t.f()}var g="undefined"!=typeof window?e.useLayoutEffect:e.useEffect;function h(i,o){if(void 0===i)i=0;y();var u=e.useRef();if(null==u.current)if("undefined"==typeof window)u.current=p;else u.current=function(e,r){var i,o,u,a,l=0,v=t.effect(function(){o=this},{name:r||"Component"});o.c=function(){l=l+1|0;if(f){var n;null==(n=o.y)||n.call(o)}if(a)a()};return(i={o:e,effect:o,subscribe:function(n){a=n;return function(){l=l+1|0;a=void 0;v()}},getSnapshot:function(){return l},S:function(){if(null!=n){var t=n.o,e=this.o;if(0==t&&0==e||0==t&&1==e){n.f();u=s(void 0,this)}else if(1==t&&0==e||2==t&&0==e);else u=s(n,this)}else u=s(void 0,this)},f:function(){var n=u;u=void 0;null==n||n()}})[c]=function(){this.f()},i}(i,o);var a=u.current;r.useSyncExternalStore(a.subscribe,a.getSnapshot,a.getSnapshot);a.S();if(0===i)g(m);return a}Object.defineProperties(t.Signal.prototype,{$$typeof:{configurable:!0,value:u},type:{configurable:!0,value:function(n){var t=n.data,e=h(1);try{return t.value}finally{e.f()}}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});exports._useSignalsImplementation=h;exports.ensureFinalCleanup=y;exports.useComputed=function(n,r){var i=e.useRef(n);i.current=n;return e.useMemo(function(){return t.computed(function(){return i.current()},r)},o)};exports.useSignal=function(n,r){return e.useMemo(function(){return t.signal(n,r)},o)};exports.useSignalEffect=function(n,r){var i=e.useRef(n);i.current=n;e.useEffect(function(){return t.effect(function(){return i.current()},r)},o)};exports.useSignals=function(n,t){return h(n,t)};exports.wrapJsx=function(n){if("function"!=typeof n)return n;else return function(e,r){if("string"==typeof e&&r)for(var i in r){var o=r[i];if("children"!==i&&o instanceof t.Signal)r[i]=o.value}return n.call.apply(n,[n,e,r].concat([].slice.call(arguments,2)))}};//# sourceMappingURL=runtime.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(_usage: EffectStoreUsage): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(function (this: Effect) {\n\t\teffectInstance = this;\n\t});\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(usage?: EffectStoreUsage): EffectStore {\n\treturn _useSignalsImplementation(usage);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["currentStore","signalsCore","require","react","index_js","major","reactVersion","version","split","map","Number","Empty","ReactElemType","Symbol","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","symDispose","dispose","startComponentEffect","prevStore","nextStore","endEffect","effect","_start","finishComponentEffect","bind","_ref2","finalCleanup","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","f","_queueMicroTask","Promise","prototype","then","resolve","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","useLayoutEffect","useEffect","_useSignalsImplementation","storeRef","useRef","current","_ref","effectInstance","onChangeNotifyReact","unsubscribe","this","_effectInstance$_debu","_debugCallback","call","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","useSyncExternalStore","Object","defineProperties","Signal","$$typeof","configurable","value","type","_ref3","data","props","get","ref","exports","useComputed","compute","options","$compute","useMemo","computed","useSignal","signal","useSignalEffect","cb","callback","useSignals","usage","wrapJsx","jsx","i","v","apply","concat","slice","arguments"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(\n\t_usage: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(\n\t\tfunction (this: Effect) {\n\t\t\teffectInstance = this;\n\t\t},\n\t\t{ name: componentName || \"Component\" }\n\t);\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED,\n\tcomponentName?: string\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage, componentName);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(\n\tusage?: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\treturn _useSignalsImplementation(usage, componentName);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["currentStore","signalsCore","require","react","index_js","major","reactVersion","version","split","map","Number","Empty","ReactElemType","Symbol","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","symDispose","dispose","startComponentEffect","prevStore","nextStore","endEffect","effect","_start","finishComponentEffect","bind","_ref2","finalCleanup","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","f","_queueMicroTask","Promise","prototype","then","resolve","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","useLayoutEffect","useEffect","_useSignalsImplementation","componentName","storeRef","useRef","current","_ref","effectInstance","onChangeNotifyReact","unsubscribe","this","name","_effectInstance$_debu","_debugCallback","call","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","useSyncExternalStore","Object","defineProperties","Signal","$$typeof","configurable","value","type","_ref3","data","props","get","ref","exports","useComputed","compute","options","$compute","useMemo","computed","useSignal","signal","useSignalEffect","cb","callback","useSignals","usage","wrapJsx","jsx","i","v","apply","concat","slice","arguments"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@preact/signals-core"),require("react"),require("use-sync-external-store/shim/index.js")):"function"==typeof define&&define.amd?define(["exports","@preact/signals-core","react","use-sync-external-store/shim/index.js"],e):e((n||self).reactSignalsRuntime={},n.preactSignalsCore,n.react,n.index_js)}(this,function(n,e,t,i){var r,o=t.version.split(".").map(Number)[0],u=[],f=Symbol.for(o>=19?"react.transitional.element":"react.element"),c="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__,s=Symbol.dispose||Symbol.for("Symbol.dispose");function a(n,e){var t=e.effect.S();r=e;return l.bind(e,n,t)}function l(n,e){e();r=n}var d,v,p=function(){},y=((d={o:0,effect:{s:void 0,c:function(){},S:function(){return p},d:function(){}},subscribe:function(){return p},getSnapshot:function(){return 0},S:function(){},f:function(){}})[s]=function(){},d),b=Promise.prototype.then.bind(Promise.resolve());function h(){if(!v)v=b(g)}function g(){var n;v=void 0;null==(n=r)||n.f()}var m="undefined"!=typeof window?t.useLayoutEffect:t.useEffect;function w(n){if(void 0===n)n=0;h();var
|
|
1
|
+
!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@preact/signals-core"),require("react"),require("use-sync-external-store/shim/index.js")):"function"==typeof define&&define.amd?define(["exports","@preact/signals-core","react","use-sync-external-store/shim/index.js"],e):e((n||self).reactSignalsRuntime={},n.preactSignalsCore,n.react,n.index_js)}(this,function(n,e,t,i){var r,o=t.version.split(".").map(Number)[0],u=[],f=Symbol.for(o>=19?"react.transitional.element":"react.element"),c="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__,s=Symbol.dispose||Symbol.for("Symbol.dispose");function a(n,e){var t=e.effect.S();r=e;return l.bind(e,n,t)}function l(n,e){e();r=n}var d,v,p=function(){},y=((d={o:0,effect:{s:void 0,c:function(){},S:function(){return p},d:function(){}},subscribe:function(){return p},getSnapshot:function(){return 0},S:function(){},f:function(){}})[s]=function(){},d),b=Promise.prototype.then.bind(Promise.resolve());function h(){if(!v)v=b(g)}function g(){var n;v=void 0;null==(n=r)||n.f()}var m="undefined"!=typeof window?t.useLayoutEffect:t.useEffect;function w(n,o){if(void 0===n)n=0;h();var u=t.useRef();if(null==u.current)if("undefined"==typeof window)u.current=y;else u.current=function(n,t){var i,o,u,f,l=0,d=e.effect(function(){o=this},{name:t||"Component"});o.c=function(){l=l+1|0;if(c){var n;null==(n=o.y)||n.call(o)}if(f)f()};return(i={o:n,effect:o,subscribe:function(n){f=n;return function(){l=l+1|0;f=void 0;d()}},getSnapshot:function(){return l},S:function(){if(null!=r){var n=r.o,e=this.o;if(0==n&&0==e||0==n&&1==e){r.f();u=a(void 0,this)}else if(1==n&&0==e||2==n&&0==e);else u=a(r,this)}else u=a(void 0,this)},f:function(){var n=u;u=void 0;null==n||n()}})[s]=function(){this.f()},i}(n,o);var f=u.current;i.useSyncExternalStore(f.subscribe,f.getSnapshot,f.getSnapshot);f.S();if(0===n)m(g);return f}Object.defineProperties(e.Signal.prototype,{$$typeof:{configurable:!0,value:f},type:{configurable:!0,value:function(n){var e=n.data,t=w(1);try{return e.value}finally{t.f()}}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});n.u=w;n.ensureFinalCleanup=h;n.useComputed=function(n,i){var r=t.useRef(n);r.current=n;return t.useMemo(function(){return e.computed(function(){return r.current()},i)},u)};n.useSignal=function(n,i){return t.useMemo(function(){return e.signal(n,i)},u)};n.useSignalEffect=function(n,i){var r=t.useRef(n);r.current=n;t.useEffect(function(){return e.effect(function(){return r.current()},i)},u)};n.useSignals=function(n,e){return w(n,e)};n.wrapJsx=function(n){if("function"!=typeof n)return n;else return function(t,i){if("string"==typeof t&&i)for(var r in i){var o=i[r];if("children"!==r&&o instanceof e.Signal)i[r]=o.value}return n.call.apply(n,[n,t,i].concat([].slice.call(arguments,2)))}}});//# sourceMappingURL=runtime.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.min.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(_usage: EffectStoreUsage): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(function (this: Effect) {\n\t\teffectInstance = this;\n\t});\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(usage?: EffectStoreUsage): EffectStore {\n\treturn _useSignalsImplementation(usage);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["g","f","exports","module","require","define","amd","globalThis","self","reactSignalsRuntime","preactSignalsCore","react","index_js","this","signalsCore","currentStore","major","reactVersion","version","split","map","Number","Empty","ReactElemType","Symbol","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","symDispose","dispose","startComponentEffect","prevStore","nextStore","endEffect","effect","_start","finishComponentEffect","bind","_ref2","finalCleanup","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","_queueMicroTask","Promise","prototype","then","resolve","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","useLayoutEffect","useEffect","_useSignalsImplementation","storeRef","useRef","current","_ref","effectInstance","onChangeNotifyReact","unsubscribe","_effectInstance$_debu","_debugCallback","call","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","useSyncExternalStore","Object","defineProperties","Signal","$$typeof","configurable","value","type","_ref3","data","props","get","ref","useComputed","compute","options","$compute","useMemo","computed","useSignal","signal","useSignalEffect","cb","callback","useSignals","usage","wrapJsx","jsx","i","v","apply","concat","slice","arguments"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.min.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(\n\t_usage: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(\n\t\tfunction (this: Effect) {\n\t\t\teffectInstance = this;\n\t\t},\n\t\t{ name: componentName || \"Component\" }\n\t);\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED,\n\tcomponentName?: string\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage, componentName);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(\n\tusage?: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\treturn _useSignalsImplementation(usage, componentName);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["g","f","exports","module","require","define","amd","globalThis","self","reactSignalsRuntime","preactSignalsCore","react","index_js","this","signalsCore","currentStore","major","reactVersion","version","split","map","Number","Empty","ReactElemType","Symbol","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","symDispose","dispose","startComponentEffect","prevStore","nextStore","endEffect","effect","_start","finishComponentEffect","bind","_ref2","finalCleanup","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","_queueMicroTask","Promise","prototype","then","resolve","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","useLayoutEffect","useEffect","_useSignalsImplementation","componentName","storeRef","useRef","current","_ref","effectInstance","onChangeNotifyReact","unsubscribe","name","_effectInstance$_debu","_debugCallback","call","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","useSyncExternalStore","Object","defineProperties","Signal","$$typeof","configurable","value","type","_ref3","data","props","get","ref","useComputed","compute","options","$compute","useMemo","computed","useSignal","signal","useSignalEffect","cb","callback","useSignals","usage","wrapJsx","jsx","i","v","apply","concat","slice","arguments"],"mappings":"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"}
|
package/runtime/dist/runtime.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Signal as n,signal as t,computed as e,effect as o}from"@preact/signals-core";import{version as i,useRef as r,useMemo as f,useEffect as u,useLayoutEffect as s}from"react";import{useSyncExternalStore as c}from"use-sync-external-store/shim/index.js";const[l]=i.split(".").map(Number),a=[],d=Symbol.for(l>=19?"react.transitional.element":"react.element"),p="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__;function m(t){if("function"!=typeof t)return t;else return function(e,o,...i){if("string"==typeof e&&o)for(let t in o){let e=o[t];if("children"!==t&&e instanceof n)o[t]=e.value}return t.call(t,e,o,...i)}}const b=Symbol.dispose||Symbol.for("Symbol.dispose");let y;function g(n,t){const e=t.effect.S();y=t;return h.bind(t,n,e)}function h(n,t){t();y=n}const v=()=>{},w={o:0,effect:{s:void 0,c(){},S:()=>v,d(){}},subscribe:()=>v,getSnapshot:()=>0,S(){},f(){},[b](){}},_=Promise.prototype.then.bind(Promise.resolve());let S;function x(){if(!S)S=_(j)}function j(){var n;S=void 0;null==(n=y)||n.f()}const P="undefined"!=typeof window?s:u;function $(n=0){x();const
|
|
1
|
+
import{Signal as n,signal as t,computed as e,effect as o}from"@preact/signals-core";import{version as i,useRef as r,useMemo as f,useEffect as u,useLayoutEffect as s}from"react";import{useSyncExternalStore as c}from"use-sync-external-store/shim/index.js";const[l]=i.split(".").map(Number),a=[],d=Symbol.for(l>=19?"react.transitional.element":"react.element"),p="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__;function m(t){if("function"!=typeof t)return t;else return function(e,o,...i){if("string"==typeof e&&o)for(let t in o){let e=o[t];if("children"!==t&&e instanceof n)o[t]=e.value}return t.call(t,e,o,...i)}}const b=Symbol.dispose||Symbol.for("Symbol.dispose");let y;function g(n,t){const e=t.effect.S();y=t;return h.bind(t,n,e)}function h(n,t){t();y=n}const v=()=>{},w={o:0,effect:{s:void 0,c(){},S:()=>v,d(){}},subscribe:()=>v,getSnapshot:()=>0,S(){},f(){},[b](){}},_=Promise.prototype.then.bind(Promise.resolve());let S;function x(){if(!S)S=_(j)}function j(){var n;S=void 0;null==(n=y)||n.f()}const P="undefined"!=typeof window?s:u;function $(n=0,t){x();const e=r();if(null==e.current)if("undefined"==typeof window)e.current=w;else e.current=function(n,t){let e,i,r,f=0,u=o(function(){e=this},{name:t||"Component"});e.c=function(){f=f+1|0;if(p){var n;null==(n=e.y)||n.call(e)}if(r)r()};return{o:n,effect:e,subscribe(n){r=n;return function(){f=f+1|0;r=void 0;u()}},getSnapshot:()=>f,S(){if(null==y){i=g(void 0,this);return}const n=y.o,t=this.o;if(0==n&&0==t||0==n&&1==t){y.f();i=g(void 0,this)}else if(1==n&&0==t||2==n&&0==t);else i=g(y,this)},f(){const n=i;i=void 0;null==n||n()},[b](){this.f()}}}(n,t);const i=e.current;c(i.subscribe,i.getSnapshot,i.getSnapshot);i.S();if(0===n)P(j);return i}Object.defineProperties(n.prototype,{$$typeof:{configurable:!0,value:d},type:{configurable:!0,value:function({data:n}){const t=$(1);try{return n.value}finally{t.f()}}},props:{configurable:!0,get(){return{data:this}}},ref:{configurable:!0,value:null}});function k(n,t){return $(n,t)}function useSignal(n,e){return f(()=>t(n,e),a)}function useComputed(n,t){const o=r(n);o.current=n;return f(()=>e(()=>o.current(),t),a)}function useSignalEffect(n,t){const e=r(n);e.current=n;u(()=>o(function(){return e.current()},t),a)}export{$ as _useSignalsImplementation,x as ensureFinalCleanup,useComputed,useSignal,useSignalEffect,k as useSignals,m as wrapJsx};//# sourceMappingURL=runtime.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(_usage: EffectStoreUsage): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(function (this: Effect) {\n\t\teffectInstance = this;\n\t});\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(usage?: EffectStoreUsage): EffectStore {\n\treturn _useSignalsImplementation(usage);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["major","reactVersion","split","map","Number","Empty","ReactElemType","Symbol","for","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","wrapJsx","jsx","type","props","rest","i","v","Signal","value","call","symDispose","dispose","currentStore","startComponentEffect","prevStore","nextStore","endEffect","effect","_start","finishComponentEffect","bind","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","f","_queueMicroTask","Promise","prototype","then","resolve","finalCleanup","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","useLayoutEffect","useEffect","_useSignalsImplementation","storeRef","useRef","current","effectInstance","onChangeNotifyReact","version","unsubscribe","this","_effectInstance$_debu","_debugCallback","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","useSyncExternalStore","Object","defineProperties","$$typeof","configurable","data","get","ref","useSignals","usage","useSignal","options","useMemo","signal","useComputed","compute","$compute","computed","useSignalEffect","cb","callback"],"mappings":"8PAmBA,MAAOA,GAASC,EAAaC,MAAM,KAAKC,IAAIC,QACtCC,EAAQ,GAGRC,EAAgBC,OAAOC,IAC5BR,GAAS,GAAK,6BAA+B,iBAGxCS,EACa,oBAAXC,UAA4BA,OAAOC,4BAErC,SAAUC,EAAWC,GAC1B,GAAmB,mBAARA,EAAoB,OAAOA,OAEtC,OAAO,SAAUC,EAAWC,KAAeC,GAC1C,GAAoB,iBAATF,GAAqBC,EAC/B,IAAK,IAAIE,KAAKF,EAAO,CACpB,IAAIG,EAAIH,EAAME,GACd,GAAU,aAANA,GAAoBC,aAAaC,EACpCJ,EAAME,GAAKC,EAAEE,KAEf,CAGD,OAAOP,EAAIQ,KAAKR,EAAKC,EAAMC,KAAUC,EACtC,CACD,CAEA,MAAMM,EACJf,OAAegB,SAAWhB,OAAOC,IAAI,kBA0DvC,IAAIgB,EAEJ,SAASC,EACRC,EACAC,GAEA,MAAMC,EAAYD,EAAUE,OAAOC,IACnCN,EAAeG,EAEf,OAAOI,EAAsBC,KAAKL,EAAWD,EAAWE,EACzD,CAEA,SAASG,EAERL,EACAE,GAEAA,IACAJ,EAAeE,CAChB,CA4KA,MAAMO,EAAOA,OAyBPC,EAtBE,CACNC,EA9OgB,EA+OhBN,OAAQ,CACPO,OAAUC,EACVC,MACAR,EAAMA,IACkBG,EAExBM,OAEDC,UAASA,IACiBP,EAE1BQ,YAAWA,IAEX,EACAX,IAAW,EACXY,IAAM,EACNpB,CAACA,KAAW,GAMRqB,EAAkBC,QAAQC,UAAUC,KAAKd,KAAKY,QAAQG,WAE5D,IAAIC,EACY,SAAAC,IACf,IAAKD,EACJA,EAAeL,EAAgBO,EAEjC,CACA,SAASA,IAAoBC,IAAAA,EAC5BH,OAAeX,EACfc,OAAAA,EAAA3B,IAAA2B,EAAcT,GACf,CAEA,MAAMU,EACa,oBAAX1C,OAAyB2C,EAAkBC,EAMnC,SAAAC,EACfpB,EA1RiB,GA4RjBc,IAEA,MAAMO,EAAWC,IACjB,GAAwB,MAApBD,EAASE,QACZ,GAAsB,oBAAXhD,OACV8C,EAASE,QAAUxB,OAEnBsB,EAASE,QA9MZ,SAA2BvB,GAC1B,IAAIwB,EACA/B,EAEAgC,EADAC,EAAU,EAGVC,EAAcjC,EAAO,WACxB8B,EAAiBI,IAClB,GACAJ,EAAerB,EAAY,WAC1BuB,EAAWA,EAAU,EAAK,EAC1B,GAAIpD,EAAkB,CAAA,IAAAuD,EACrBA,OAAAA,EAAAL,EAAeM,IAAfD,EAA+B3C,KAAKsC,EACrC,CACA,GAAIC,EAAqBA,GAC1B,EAEA,MAAO,CACNzB,IACAN,OAAQ8B,EACRnB,UAAU0B,GACTN,EAAsBM,EAEtB,OAAO,WAWNL,EAAWA,EAAU,EAAK,EAC1BD,OAAsBvB,EACtByB,GACD,CACD,EACArB,YAAWA,IACHoB,EAER/B,IAuEC,GAAoBO,MAAhBb,EAA2B,CAC9BI,EAAYH,OAAqBY,EAAW0B,MAC5C,MACD,CAEA,MAAMI,EAAY3C,EAAaW,EACzBiC,EAAYL,KAAK5B,EAEvB,GA9Me,GA+MbgC,GA/Ma,GA+MaC,GA/Mb,GAgNbD,GA1MqB,GA0MKC,EAC1B,CAED5C,EAAakB,IACbd,EAAYH,OAAqBY,EAAW0B,KAC7C,MACEI,GAhNqB,GAgNrBA,GAtNa,GAsNqBC,GA1MlB,GA2MhBD,GAvNa,GAuNgBC,QAK9BxC,EAAYH,EAAqBD,EAAcuC,KAEjD,EACArB,IACC,MAAM2B,EAAMzC,EACZA,OAAYS,QACZgC,GAAAA,GACD,EACA/C,CAACA,KACAyC,KAAKrB,GACN,EAEF,CA2DsB4B,CAAkBnC,GAIvC,MAAMoC,EAAQf,EAASE,QACvBc,EAAqBD,EAAM/B,UAAW+B,EAAM9B,YAAa8B,EAAM9B,aAC/D8B,EAAMzC,IAEN,GA3SiB,IA2SbK,EAAsBiB,EAA0BF,GAEpD,OAAOqB,CACR,CAeAE,OAAOC,iBAAiBvD,EAAO0B,UAAW,CACzC8B,SAAU,CAAEC,cAAc,EAAMxD,MAAOd,GACvCQ,KAAM,CAAE8D,cAAc,EAAMxD,MAZ7B,UAAqByD,KAAEA,IACtB,MAAMN,EAAQhB,EAA0B,GACxC,IACC,OAAOsB,EAAKzD,KAGb,CAFC,QACAmD,EAAM7B,GACP,CACD,GAMC3B,MAAO,CACN6D,cAAc,EACdE,MACC,MAAO,CAAED,KAAMd,KAChB,GAEDgB,IAAK,CAAEH,cAAc,EAAMxD,MAAO,iBAGnB4D,EAAWC,GAC1B,OAAO1B,EAA0B0B,EAClC,CAIgB,SAAAC,UAAa9D,EAAW+D,GACvC,OAAOC,EACN,IAAMC,EAAsBjE,EAAO+D,GACnC9E,EAEF,CAEgB,SAAAiF,YACfC,EACAJ,GAEA,MAAMK,EAAW/B,EAAO8B,GACxBC,EAAS9B,QAAU6B,EACnB,OAAOH,EAAQ,IAAMK,EAAY,IAAMD,EAAS9B,UAAWyB,GAAU9E,EACtE,CAEgB,SAAAqF,gBACfC,EACAR,GAEA,MAAMS,EAAWnC,EAAOkC,GACxBC,EAASlC,QAAUiC,EAEnBrC,EAAU,IACFzB,EAAO,WACb,OAAO+D,EAASlC,SACjB,EAAGyB,GACD9E,EACJ,QAAAkD,+BAAAN,wBAAAqC,YAAAJ,UAAAQ,gBAAAV,gBAAApE"}
|
|
1
|
+
{"version":3,"file":"runtime.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(\n\t_usage: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(\n\t\tfunction (this: Effect) {\n\t\t\teffectInstance = this;\n\t\t},\n\t\t{ name: componentName || \"Component\" }\n\t);\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED,\n\tcomponentName?: string\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage, componentName);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(\n\tusage?: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\treturn _useSignalsImplementation(usage, componentName);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["major","reactVersion","split","map","Number","Empty","ReactElemType","Symbol","for","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","wrapJsx","jsx","type","props","rest","i","v","Signal","value","call","symDispose","dispose","currentStore","startComponentEffect","prevStore","nextStore","endEffect","effect","_start","finishComponentEffect","bind","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","f","_queueMicroTask","Promise","prototype","then","resolve","finalCleanup","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","useLayoutEffect","useEffect","_useSignalsImplementation","componentName","storeRef","useRef","current","effectInstance","onChangeNotifyReact","version","unsubscribe","this","name","_effectInstance$_debu","_debugCallback","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","useSyncExternalStore","Object","defineProperties","$$typeof","configurable","data","get","ref","useSignals","usage","useSignal","options","useMemo","signal","useComputed","compute","$compute","computed","useSignalEffect","cb","callback"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Signal as n,signal as t,computed as i,effect as r}from"@preact/signals-core";import{version as e,useRef as o,useMemo as u,useEffect as f,useLayoutEffect as c}from"react";import{useSyncExternalStore as a}from"use-sync-external-store/shim/index.js";var s=e.split(".").map(Number)[0],l=[],v=Symbol.for(s>=19?"react.transitional.element":"react.element"),d="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__;function p(t){if("function"!=typeof t)return t;else return function(i,r){if("string"==typeof i&&r)for(var e in r){var o=r[e];if("children"!==e&&o instanceof n)r[e]=o.value}return t.call.apply(t,[t,i,r].concat([].slice.call(arguments,2)))}}var m,b=Symbol.dispose||Symbol.for("Symbol.dispose");function y(n,t){var i=t.effect.S();m=t;return g.bind(t,n,i)}function g(n,t){t();m=n}var h,w,_=function(){},S=((h={o:0,effect:{s:void 0,c:function(){},S:function(){return _},d:function(){}},subscribe:function(){return _},getSnapshot:function(){return 0},S:function(){},f:function(){}})[b]=function(){},h),x=Promise.prototype.then.bind(Promise.resolve());function j(){if(!w)w=x(P)}function P(){var n;w=void 0;null==(n=m)||n.f()}var $="undefined"!=typeof window?c:f;function k(n){if(void 0===n)n=0;j();var
|
|
1
|
+
import{Signal as n,signal as t,computed as i,effect as r}from"@preact/signals-core";import{version as e,useRef as o,useMemo as u,useEffect as f,useLayoutEffect as c}from"react";import{useSyncExternalStore as a}from"use-sync-external-store/shim/index.js";var s=e.split(".").map(Number)[0],l=[],v=Symbol.for(s>=19?"react.transitional.element":"react.element"),d="undefined"!=typeof window&&!!window.__PREACT_SIGNALS_DEVTOOLS__;function p(t){if("function"!=typeof t)return t;else return function(i,r){if("string"==typeof i&&r)for(var e in r){var o=r[e];if("children"!==e&&o instanceof n)r[e]=o.value}return t.call.apply(t,[t,i,r].concat([].slice.call(arguments,2)))}}var m,b=Symbol.dispose||Symbol.for("Symbol.dispose");function y(n,t){var i=t.effect.S();m=t;return g.bind(t,n,i)}function g(n,t){t();m=n}var h,w,_=function(){},S=((h={o:0,effect:{s:void 0,c:function(){},S:function(){return _},d:function(){}},subscribe:function(){return _},getSnapshot:function(){return 0},S:function(){},f:function(){}})[b]=function(){},h),x=Promise.prototype.then.bind(Promise.resolve());function j(){if(!w)w=x(P)}function P(){var n;w=void 0;null==(n=m)||n.f()}var $="undefined"!=typeof window?c:f;function k(n,t){if(void 0===n)n=0;j();var i=o();if(null==i.current)if("undefined"==typeof window)i.current=S;else i.current=function(n,t){var i,e,o,u,f=0,c=r(function(){e=this},{name:t||"Component"});e.c=function(){f=f+1|0;if(d){var n;null==(n=e.y)||n.call(e)}if(u)u()};return(i={o:n,effect:e,subscribe:function(n){u=n;return function(){f=f+1|0;u=void 0;c()}},getSnapshot:function(){return f},S:function(){if(null!=m){var n=m.o,t=this.o;if(0==n&&0==t||0==n&&1==t){m.f();o=y(void 0,this)}else if(1==n&&0==t||2==n&&0==t);else o=y(m,this)}else o=y(void 0,this)},f:function(){var n=o;o=void 0;null==n||n()}})[b]=function(){this.f()},i}(n,t);var e=i.current;a(e.subscribe,e.getSnapshot,e.getSnapshot);e.S();if(0===n)$(P);return e}Object.defineProperties(n.prototype,{$$typeof:{configurable:!0,value:v},type:{configurable:!0,value:function(n){var t=n.data,i=k(1);try{return t.value}finally{i.f()}}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});function C(n,t){return k(n,t)}function useSignal(n,i){return u(function(){return t(n,i)},l)}function useComputed(n,t){var r=o(n);r.current=n;return u(function(){return i(function(){return r.current()},t)},l)}function useSignalEffect(n,t){var i=o(n);i.current=n;f(function(){return r(function(){return i.current()},t)},l)}export{k as _useSignalsImplementation,j as ensureFinalCleanup,useComputed,useSignal,useSignalEffect,C as useSignals,p as wrapJsx};//# sourceMappingURL=runtime.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.module.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(_usage: EffectStoreUsage): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(function (this: Effect) {\n\t\teffectInstance = this;\n\t});\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(usage?: EffectStoreUsage): EffectStore {\n\treturn _useSignalsImplementation(usage);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["Signal","signal","computed","effect","version","useRef","useMemo","useEffect","useLayoutEffect","useSyncExternalStore","major","reactVersion","split","map","Number","Empty","ReactElemType","Symbol","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","wrapJsx","jsx","type","props","i","v","value","call","apply","concat","slice","arguments","currentStore","symDispose","dispose","startComponentEffect","prevStore","nextStore","endEffect","_start","finishComponentEffect","bind","_ref2","finalCleanup","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","f","_queueMicroTask","Promise","prototype","then","resolve","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","_useSignalsImplementation","storeRef","current","_ref","effectInstance","onChangeNotifyReact","unsubscribe","this","_effectInstance$_debu","_debugCallback","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","Object","defineProperties","$$typeof","configurable","_ref3","data","get","ref","useSignals","usage","useSignal","options","useComputed","compute","$compute","useSignalEffect","cb","callback"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.module.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tsignal,\n\tcomputed,\n\teffect,\n\tSignal,\n\tReadonlySignal,\n\tSignalOptions,\n\tEffectOptions,\n} from \"@preact/signals-core\";\nimport {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\tuseLayoutEffect,\n\tversion as reactVersion,\n} from \"react\";\nimport { useSyncExternalStore } from \"use-sync-external-store/shim/index.js\";\nimport type { SignalsDevToolsAPI } from \"../../../debug/src/devtools\";\n\nconst [major] = reactVersion.split(\".\").map(Number);\nconst Empty = [] as const;\n// V19 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\n// V18 https://github.com/facebook/react/blob/346c7d4c43a0717302d446da9e7423a8e28d8996/packages/shared/ReactSymbols.js#L15\nconst ReactElemType = Symbol.for(\n\tmajor >= 19 ? \"react.transitional.element\" : \"react.element\"\n);\n\nconst DEVTOOLS_ENABLED =\n\ttypeof window !== \"undefined\" && !!window.__PREACT_SIGNALS_DEVTOOLS__;\n\nexport function wrapJsx<T>(jsx: T): T {\n\tif (typeof jsx !== \"function\") return jsx;\n\n\treturn function (type: any, props: any, ...rest: any[]) {\n\t\tif (typeof type === \"string\" && props) {\n\t\t\tfor (let i in props) {\n\t\t\t\tlet v = props[i];\n\t\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t\tprops[i] = v.value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jsx.call(jsx, type, props, ...rest);\n\t} as any as T;\n}\n\nconst symDispose: unique symbol =\n\t(Symbol as any).dispose || Symbol.for(\"Symbol.dispose\");\n\ninterface Effect {\n\t_sources: object | undefined;\n\t_debugCallback?: () => void;\n\t_start(): () => void;\n\t_callback(): void;\n\t_dispose(): void;\n}\n\n/**\n * Use this flag to represent a bare `useSignals` call that doesn't manually\n * close its effect store and relies on auto-closing when the next useSignals is\n * called or after a microtask\n */\nconst UNMANAGED = 0;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a component's render method. This is the default usage\n * that the react-transform plugin uses.\n */\nconst MANAGED_COMPONENT = 1;\n/**\n * Use this flag to represent a `useSignals` call that is manually closed by a\n * try/finally block in a hook body. This is the default usage that the\n * react-transform plugin uses.\n */\nconst MANAGED_HOOK = 2;\n\n/**\n * An enum defining how this store is used. See the documentation for each enum\n * member for more details.\n * @see {@link UNMANAGED}\n * @see {@link MANAGED_COMPONENT}\n * @see {@link MANAGED_HOOK}\n */\ntype EffectStoreUsage =\n\t| typeof UNMANAGED\n\t| typeof MANAGED_COMPONENT\n\t| typeof MANAGED_HOOK;\n\nexport interface EffectStore {\n\t/**\n\t * An enum defining how this hook is used and whether it is invoked in a\n\t * component's body or hook body. See the comment on `EffectStoreUsage` for\n\t * more details.\n\t */\n\treadonly _usage: EffectStoreUsage;\n\treadonly effect: Effect;\n\tsubscribe(onStoreChange: () => void): () => void;\n\tgetSnapshot(): number;\n\t/** startEffect - begin tracking signals used in this component */\n\t_start(): void;\n\t/** finishEffect - stop tracking the signals used in this component */\n\tf(): void;\n\t[symDispose](): void;\n}\n\nlet currentStore: EffectStore | undefined;\n\nfunction startComponentEffect(\n\tprevStore: EffectStore | undefined,\n\tnextStore: EffectStore\n) {\n\tconst endEffect = nextStore.effect._start();\n\tcurrentStore = nextStore;\n\n\treturn finishComponentEffect.bind(nextStore, prevStore, endEffect);\n}\n\nfunction finishComponentEffect(\n\tthis: EffectStore,\n\tprevStore: EffectStore | undefined,\n\tendEffect: () => void\n) {\n\tendEffect();\n\tcurrentStore = prevStore;\n}\n\n/**\n * A redux-like store whose store value is a positive 32bit integer (a\n * 'version').\n *\n * React subscribes to this store and gets a snapshot of the current 'version',\n * whenever the 'version' changes, we tell React it's time to update the\n * component (call 'onStoreChange').\n *\n * How we achieve this is by creating a binding with an 'effect', when the\n * `effect._callback' is called, we update our store version and tell React to\n * re-render the component ([1] We don't really care when/how React does it).\n *\n * [1]\n * @see https://react.dev/reference/react/useSyncExternalStore\n * @see\n * https://github.com/reactjs/rfcs/blob/main/text/0214-use-sync-external-store.md\n *\n * @param _usage An enum defining how this hook is used and whether it is\n * invoked in a component's body or hook body. See the comment on\n * `EffectStoreUsage` for more details.\n */\nfunction createEffectStore(\n\t_usage: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\tlet effectInstance!: Effect;\n\tlet endEffect: (() => void) | undefined;\n\tlet version = 0;\n\tlet onChangeNotifyReact: (() => void) | undefined;\n\n\tlet unsubscribe = effect(\n\t\tfunction (this: Effect) {\n\t\t\teffectInstance = this;\n\t\t},\n\t\t{ name: componentName || \"Component\" }\n\t);\n\teffectInstance._callback = function () {\n\t\tversion = (version + 1) | 0;\n\t\tif (DEVTOOLS_ENABLED) {\n\t\t\teffectInstance._debugCallback?.call(effectInstance);\n\t\t}\n\t\tif (onChangeNotifyReact) onChangeNotifyReact();\n\t};\n\n\treturn {\n\t\t_usage,\n\t\teffect: effectInstance,\n\t\tsubscribe(onStoreChange) {\n\t\t\tonChangeNotifyReact = onStoreChange;\n\n\t\t\treturn function () {\n\t\t\t\t/**\n\t\t\t\t * Rotate to next version when unsubscribing to ensure that components are re-run\n\t\t\t\t * when subscribing again.\n\t\t\t\t *\n\t\t\t\t * In StrictMode, 'memo'-ed components seem to keep a stale snapshot version, so\n\t\t\t\t * don't re-run after subscribing again if the version is the same as last time.\n\t\t\t\t *\n\t\t\t\t * Because we unsubscribe from the effect, the version may not change. We simply\n\t\t\t\t * set a new initial version in case of stale snapshots here.\n\t\t\t\t */\n\t\t\t\tversion = (version + 1) | 0;\n\t\t\t\tonChangeNotifyReact = undefined;\n\t\t\t\tunsubscribe();\n\t\t\t};\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn version;\n\t\t},\n\t\t_start() {\n\t\t\t// In general, we want to support two kinds of usages of useSignals:\n\t\t\t//\n\t\t\t// A) Managed: calling useSignals in a component or hook body wrapped in a\n\t\t\t// try/finally (like what the react-transform plugin does)\n\t\t\t//\n\t\t\t// B) Unmanaged: Calling useSignals directly without wrapping in a\n\t\t\t// try/finally\n\t\t\t//\n\t\t\t// For managed, we finish the effect in the finally block of the component\n\t\t\t// or hook body. For unmanaged, we finish the effect in the next\n\t\t\t// useSignals call or after a microtask.\n\t\t\t//\n\t\t\t// There are different tradeoffs which each approach. With managed, using\n\t\t\t// a try/finally ensures that only signals used in the component or hook\n\t\t\t// body are tracked. However, signals accessed in render props are missed\n\t\t\t// because the render prop is invoked in another component that may or may\n\t\t\t// not realize it is rendering signals accessed in the render prop it is\n\t\t\t// given.\n\t\t\t//\n\t\t\t// The other approach is \"unmanaged\": to call useSignals directly without\n\t\t\t// wrapping in a try/finally. This approach is easier to manually write in\n\t\t\t// situations where a build step isn't available but does open up the\n\t\t\t// possibility of catching signals accessed in other code before the\n\t\t\t// effect is closed (e.g. in a layout effect). Most situations where this\n\t\t\t// could happen are generally consider bad patterns or bugs. For example,\n\t\t\t// using a signal in a component and not having a call to `useSignals`\n\t\t\t// would be an bug. Or using a signal in `useLayoutEffect` is generally\n\t\t\t// not recommended since that layout effect won't update when the signals'\n\t\t\t// value change.\n\t\t\t//\n\t\t\t// To support both approaches, we need to track how each invocation of\n\t\t\t// useSignals is used, so we can properly transition between different\n\t\t\t// kinds of usages.\n\t\t\t//\n\t\t\t// The following table shows the different scenarios and how we should\n\t\t\t// handle them.\n\t\t\t//\n\t\t\t// Key:\n\t\t\t// 0 = UNMANAGED\n\t\t\t// 1 = MANAGED_COMPONENT\n\t\t\t// 2 = MANAGED_HOOK\n\t\t\t//\n\t\t\t// Pattern:\n\t\t\t// prev store usage -> this store usage: action to take\n\t\t\t//\n\t\t\t// - 0 -> 0: finish previous effect (unknown to unknown)\n\t\t\t//\n\t\t\t// We don't know how the previous effect was used, so we need to finish\n\t\t\t// it before starting the next effect.\n\t\t\t//\n\t\t\t// - 0 -> 1: finish previous effect\n\t\t\t//\n\t\t\t// Assume previous invocation was another component or hook from another\n\t\t\t// component. Nested component renders (renderToStaticMarkup within a\n\t\t\t// component's render) won't be supported with bare useSignals calls.\n\t\t\t//\n\t\t\t// - 0 -> 2: capture & restore\n\t\t\t//\n\t\t\t// Previous invocation could be a component or a hook. Either way,\n\t\t\t// restore it after our invocation so that it can continue to capture\n\t\t\t// any signals after we exit.\n\t\t\t//\n\t\t\t// - 1 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 1 -> 1: capture & restore (e.g. component calls renderToStaticMarkup)\n\t\t\t// - 1 -> 2: capture & restore (e.g. hook)\n\t\t\t//\n\t\t\t// - 2 -> 0: Do nothing. Signals already captured by current effect store\n\t\t\t// - 2 -> 1: capture & restore (e.g. hook calls renderToStaticMarkup)\n\t\t\t// - 2 -> 2: capture & restore (e.g. nested hook calls)\n\n\t\t\tif (currentStore == undefined) {\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst prevUsage = currentStore._usage;\n\t\t\tconst thisUsage = this._usage;\n\n\t\t\tif (\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == UNMANAGED) || // 0 -> 0\n\t\t\t\t(prevUsage == UNMANAGED && thisUsage == MANAGED_COMPONENT) // 0 -> 1\n\t\t\t) {\n\t\t\t\t// finish previous effect\n\t\t\t\tcurrentStore.f();\n\t\t\t\tendEffect = startComponentEffect(undefined, this);\n\t\t\t} else if (\n\t\t\t\t(prevUsage == MANAGED_COMPONENT && thisUsage == UNMANAGED) || // 1 -> 0\n\t\t\t\t(prevUsage == MANAGED_HOOK && thisUsage == UNMANAGED) // 2 -> 0\n\t\t\t) {\n\t\t\t\t// Do nothing since it'll be captured by current effect store\n\t\t\t} else {\n\t\t\t\t// nested scenarios, so capture and restore the previous effect store\n\t\t\t\tendEffect = startComponentEffect(currentStore, this);\n\t\t\t}\n\t\t},\n\t\tf() {\n\t\t\tconst end = endEffect;\n\t\t\tendEffect = undefined;\n\t\t\tend?.();\n\t\t},\n\t\t[symDispose]() {\n\t\t\tthis.f();\n\t\t},\n\t};\n}\n\nconst noop = () => {};\n\nfunction createEmptyEffectStore(): EffectStore {\n\treturn {\n\t\t_usage: UNMANAGED,\n\t\teffect: {\n\t\t\t_sources: undefined,\n\t\t\t_callback() {},\n\t\t\t_start() {\n\t\t\t\treturn /* endEffect */ noop;\n\t\t\t},\n\t\t\t_dispose() {},\n\t\t},\n\t\tsubscribe() {\n\t\t\treturn /* unsubscribe */ noop;\n\t\t},\n\t\tgetSnapshot() {\n\t\t\treturn 0;\n\t\t},\n\t\t_start() {},\n\t\tf() {},\n\t\t[symDispose]() {},\n\t};\n}\n\nconst emptyEffectStore = createEmptyEffectStore();\n\nconst _queueMicroTask = Promise.prototype.then.bind(Promise.resolve());\n\nlet finalCleanup: Promise<void> | undefined;\nexport function ensureFinalCleanup() {\n\tif (!finalCleanup) {\n\t\tfinalCleanup = _queueMicroTask(cleanupTrailingStore);\n\t}\n}\nfunction cleanupTrailingStore() {\n\tfinalCleanup = undefined;\n\tcurrentStore?.f();\n}\n\nconst useIsomorphicLayoutEffect =\n\ttypeof window !== \"undefined\" ? useLayoutEffect : useEffect;\n\n/**\n * Custom hook to create the effect to track signals used during render and\n * subscribe to changes to rerender the component when the signals change.\n */\nexport function _useSignalsImplementation(\n\t_usage: EffectStoreUsage = UNMANAGED,\n\tcomponentName?: string\n): EffectStore {\n\tensureFinalCleanup();\n\n\tconst storeRef = useRef<EffectStore>();\n\tif (storeRef.current == null) {\n\t\tif (typeof window === \"undefined\") {\n\t\t\tstoreRef.current = emptyEffectStore;\n\t\t} else {\n\t\t\tstoreRef.current = createEffectStore(_usage, componentName);\n\t\t}\n\t}\n\n\tconst store = storeRef.current;\n\tuseSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n\tstore._start();\n\t// note: _usage is a constant here, so conditional is okay\n\tif (_usage === UNMANAGED) useIsomorphicLayoutEffect(cleanupTrailingStore);\n\n\treturn store;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node or JSX.\n */\nfunction SignalValue({ data }: { data: Signal }) {\n\tconst store = _useSignalsImplementation(1);\n\ttry {\n\t\treturn data.value;\n\t} finally {\n\t\tstore.f();\n\t}\n}\n\n// Decorate Signals so React renders them as <SignalValue> components.\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: ReactElemType },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { configurable: true, value: null },\n});\n\nexport function useSignals(\n\tusage?: EffectStoreUsage,\n\tcomponentName?: string\n): EffectStore {\n\treturn _useSignalsImplementation(usage, componentName);\n}\n\nexport function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T, options?: SignalOptions<T>) {\n\treturn useMemo(\n\t\t() => signal<T | undefined>(value, options as SignalOptions),\n\t\tEmpty\n\t);\n}\n\nexport function useComputed<T>(\n\tcompute: () => T,\n\toptions?: SignalOptions<T>\n): ReadonlySignal<T> {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current(), options), Empty);\n}\n\nexport function useSignalEffect(\n\tcb: () => void | (() => void),\n\toptions?: EffectOptions\n) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\treturn callback.current();\n\t\t}, options);\n\t}, Empty);\n}\n\ndeclare global {\n\tinterface Window {\n\t\t__PREACT_SIGNALS_DEVTOOLS__: SignalsDevToolsAPI;\n\t}\n}\n"],"names":["Signal","signal","computed","effect","version","useRef","useMemo","useEffect","useLayoutEffect","useSyncExternalStore","major","reactVersion","split","map","Number","Empty","ReactElemType","Symbol","DEVTOOLS_ENABLED","window","__PREACT_SIGNALS_DEVTOOLS__","wrapJsx","jsx","type","props","i","v","value","call","apply","concat","slice","arguments","currentStore","symDispose","dispose","startComponentEffect","prevStore","nextStore","endEffect","_start","finishComponentEffect","bind","_ref2","finalCleanup","noop","emptyEffectStore","_usage","_sources","undefined","_callback","_dispose","subscribe","getSnapshot","f","_queueMicroTask","Promise","prototype","then","resolve","ensureFinalCleanup","cleanupTrailingStore","_currentStore","useIsomorphicLayoutEffect","_useSignalsImplementation","componentName","storeRef","current","_ref","effectInstance","onChangeNotifyReact","unsubscribe","this","name","_effectInstance$_debu","_debugCallback","onStoreChange","prevUsage","thisUsage","end","createEffectStore","store","Object","defineProperties","$$typeof","configurable","_ref3","data","get","ref","useSignals","usage","useSignal","options","useComputed","compute","$compute","useSignalEffect","cb","callback"],"mappings":"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"}
|
package/runtime/src/index.ts
CHANGED
|
@@ -146,15 +146,21 @@ function finishComponentEffect(
|
|
|
146
146
|
* invoked in a component's body or hook body. See the comment on
|
|
147
147
|
* `EffectStoreUsage` for more details.
|
|
148
148
|
*/
|
|
149
|
-
function createEffectStore(
|
|
149
|
+
function createEffectStore(
|
|
150
|
+
_usage: EffectStoreUsage,
|
|
151
|
+
componentName?: string
|
|
152
|
+
): EffectStore {
|
|
150
153
|
let effectInstance!: Effect;
|
|
151
154
|
let endEffect: (() => void) | undefined;
|
|
152
155
|
let version = 0;
|
|
153
156
|
let onChangeNotifyReact: (() => void) | undefined;
|
|
154
157
|
|
|
155
|
-
let unsubscribe = effect(
|
|
156
|
-
|
|
157
|
-
|
|
158
|
+
let unsubscribe = effect(
|
|
159
|
+
function (this: Effect) {
|
|
160
|
+
effectInstance = this;
|
|
161
|
+
},
|
|
162
|
+
{ name: componentName || "Component" }
|
|
163
|
+
);
|
|
158
164
|
effectInstance._callback = function () {
|
|
159
165
|
version = (version + 1) | 0;
|
|
160
166
|
if (DEVTOOLS_ENABLED) {
|
|
@@ -343,7 +349,8 @@ const useIsomorphicLayoutEffect =
|
|
|
343
349
|
* subscribe to changes to rerender the component when the signals change.
|
|
344
350
|
*/
|
|
345
351
|
export function _useSignalsImplementation(
|
|
346
|
-
_usage: EffectStoreUsage = UNMANAGED
|
|
352
|
+
_usage: EffectStoreUsage = UNMANAGED,
|
|
353
|
+
componentName?: string
|
|
347
354
|
): EffectStore {
|
|
348
355
|
ensureFinalCleanup();
|
|
349
356
|
|
|
@@ -352,7 +359,7 @@ export function _useSignalsImplementation(
|
|
|
352
359
|
if (typeof window === "undefined") {
|
|
353
360
|
storeRef.current = emptyEffectStore;
|
|
354
361
|
} else {
|
|
355
|
-
storeRef.current = createEffectStore(_usage);
|
|
362
|
+
storeRef.current = createEffectStore(_usage, componentName);
|
|
356
363
|
}
|
|
357
364
|
}
|
|
358
365
|
|
|
@@ -390,8 +397,11 @@ Object.defineProperties(Signal.prototype, {
|
|
|
390
397
|
ref: { configurable: true, value: null },
|
|
391
398
|
});
|
|
392
399
|
|
|
393
|
-
export function useSignals(
|
|
394
|
-
|
|
400
|
+
export function useSignals(
|
|
401
|
+
usage?: EffectStoreUsage,
|
|
402
|
+
componentName?: string
|
|
403
|
+
): EffectStore {
|
|
404
|
+
return _useSignalsImplementation(usage, componentName);
|
|
395
405
|
}
|
|
396
406
|
|
|
397
407
|
export function useSignal<T>(value: T, options?: SignalOptions<T>): Signal<T>;
|
package/utils/dist/index.d.ts
CHANGED
|
@@ -6,12 +6,18 @@ interface ShowProps<T = boolean> {
|
|
|
6
6
|
children: ReactNode | ((value: NonNullable<T>) => ReactNode);
|
|
7
7
|
}
|
|
8
8
|
export declare function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null;
|
|
9
|
+
export declare namespace Show {
|
|
10
|
+
var displayName: string;
|
|
11
|
+
}
|
|
9
12
|
interface ForProps<T> {
|
|
10
13
|
each: Signal<Array<T>> | ReadonlySignal<Array<T>> | (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);
|
|
11
14
|
fallback?: ReactNode;
|
|
12
15
|
children: (value: T, index: number) => ReactNode;
|
|
13
16
|
}
|
|
14
17
|
export declare function For<T>(props: ForProps<T>): JSX.Element | null;
|
|
18
|
+
export declare namespace For {
|
|
19
|
+
var displayName: string;
|
|
20
|
+
}
|
|
15
21
|
export declare function useLiveSignal<T>(value: T): Signal<T>;
|
|
16
22
|
export declare function useSignalRef<T>(value: T): Signal<T> & {
|
|
17
23
|
current: T;
|
package/utils/dist/utils.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var r=require("@preact/signals-react"),n=require("@preact/signals-react/runtime"),e=require("react"),t=function(r){n.useSignals();return"function"==typeof r.children?r.children(r.v,r.i):r.children}
|
|
1
|
+
var r=require("@preact/signals-react"),n=require("@preact/signals-react/runtime"),e=require("react"),t=function(r){n.useSignals();return"function"==typeof r.children?r.children(r.v,r.i):r.children};t.displayName="Item";function u(r){n.useSignals();var u="function"==typeof r.when?r.when():r.when.value;if(!u)return r.fallback||null;else return e.createElement(t,{v:u,children:r.children})}u.displayName="Show";function i(r){n.useSignals();var u=e.useMemo(function(){return new Map},[]),i=("function"==typeof r.each?r.each():r.each).value;if(!i.length)return r.fallback||null;var c=new Set(u.keys()),o=i.map(function(n,i){c.delete(n);if(!u.has(n)){var o=e.createElement(t,{v:n,key:i,i:i,children:r.children});u.set(n,o);return o}return u.get(n)});c.forEach(function(r){u.delete(r)});return e.createElement(e.Fragment,{children:o})}i.displayName="For";var c={configurable:!0,get:function(){return this.value},set:function(r){this.value=r}};exports.For=i;exports.Show=u;exports.useLiveSignal=function(n){var e=r.useSignal(n);if(e.peek()!==n)e.value=n;return e};exports.useSignalRef=function(n){var e=r.useSignal(n);if(!("current"in e))Object.defineProperty(e,"current",c);return e};//# sourceMappingURL=utils.js.map
|
package/utils/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nItem.displayName = \"Item\";\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\nShow.displayName = \"Show\";\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nFor.displayName = \"For\";\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["Item","props","useSignals","children","v","i","displayName","Show","value","when","fallback","createElement","For","cache","useMemo","Map","list","each","length","removed","Set","keys","items","map","key","has","result","set","get","forEach","Fragment","refSignalProto","configurable","this","exports","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty"],"mappings":"qGAWMA,EAAO,SAACC,GACbC,EAAUA,aACV,MAAiC,mBAAnBD,EAAME,SACjBF,EAAME,SAASF,EAAMG,EAAGH,EAAMI,GAC9BJ,EAAME,QACV,EAEAH,EAAKM,YAAc,OAEb,SAAUC,EAAkBN,GACjCC,EAAUA,aACV,IAAMM,EACiB,mBAAfP,EAAMQ,KAAsBR,EAAMQ,OAASR,EAAMQ,KAAKD,MAC9D,IAAKA,EAAO,OAAQP,EAAMS,UAA4B,UACtD,OAAOC,gBAACX,EAAK,CAAAI,EAAGI,EAAOL,SAAUF,EAAME,UACxC,CAEAI,EAAKD,YAAc,OAWH,SAAAM,EAAOX,GACtBC,EAAUA,aACV,IAAMW,EAAQC,EAAAA,QAAQ,WAAA,OAAU,IAAAC,GAAK,EAAE,IACnCC,GACoB,mBAAff,EAAMgB,KAAsBhB,EAAMgB,OAAShB,EAAMgB,MAGxDT,MAEF,IAAKQ,EAAKE,OAAQ,OAAQjB,EAAMS,UAA4B,KAE5D,IAAMS,EAAU,IAAIC,IAAIP,EAAMQ,QAExBC,EAAQN,EAAKO,IAAI,SAACf,EAAOgB,GAC9BL,EAAc,OAACX,GACf,IAAKK,EAAMY,IAAIjB,GAAQ,CACtB,IAAMkB,EACLf,gBAACX,GAAKI,EAAGI,EAAOgB,IAAKA,EAAKnB,EAAGmB,EAAKrB,SAAUF,EAAME,WAEnDU,EAAMc,IAAInB,EAAOkB,GACjB,OAAOA,CACR,CACA,OAAOb,EAAMe,IAAIpB,EAClB,GAEAW,EAAQU,QAAQ,SAAArB,GACfK,EAAY,OAACL,EACd,GAEA,OAAOG,gBAAcmB,EAAAA,SAAU,CAAE3B,SAAUmB,GAC5C,CAEAV,EAAIN,YAAc,MAclB,IAAMyB,EAAiB,CACtBC,cAAc,EACdJ,IAAA,WACC,OAAWK,KAACzB,KACb,EACAmB,aAAkBvB,GACjB6B,KAAKzB,MAAQJ,CACd,GACA8B,QAAAtB,IAAAA,EAAAsB,QAAA3B,KAAAA,EAAA2B,QAAAC,cApBe,SAAiB3B,GAChC,IAAM4B,EAAIC,EAASA,UAAC7B,GACpB,GAAI4B,EAAEE,SAAW9B,EAAO4B,EAAE5B,MAAQA,EAClC,OAAO4B,CACR,EAgBCF,QAAAK,aAdK,SAA0B/B,GAC/B,IAAMgC,EAAMH,EAASA,UAAC7B,GACtB,KAAM,YAAagC,GAClBC,OAAOC,eAAeF,EAAK,UAAWT,GACvC,OAAOS,CACR"}
|
package/utils/dist/utils.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@preact/signals-react"),require("@preact/signals-react/runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","@preact/signals-react","@preact/signals-react/runtime","react"],n):n((e||self).reactSignalsutils={},e.signalsReact,e.reactSignalsRuntime,e.react)}(this,function(e,n,t
|
|
1
|
+
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@preact/signals-react"),require("@preact/signals-react/runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","@preact/signals-react","@preact/signals-react/runtime","react"],n):n((e||self).reactSignalsutils={},e.signalsReact,e.reactSignalsRuntime,e.react)}(this,function(e,n,r,t){var i=function(e){r.useSignals();return"function"==typeof e.children?e.children(e.v,e.i):e.children};i.displayName="Item";function u(e){r.useSignals();var n="function"==typeof e.when?e.when():e.when.value;if(!n)return e.fallback||null;else return t.createElement(i,{v:n,children:e.children})}u.displayName="Show";function f(e){r.useSignals();var n=t.useMemo(function(){return new Map},[]),u=("function"==typeof e.each?e.each():e.each).value;if(!u.length)return e.fallback||null;var f=new Set(n.keys()),c=u.map(function(r,u){f.delete(r);if(!n.has(r)){var c=t.createElement(i,{v:r,key:u,i:u,children:e.children});n.set(r,c);return c}return n.get(r)});f.forEach(function(e){n.delete(e)});return t.createElement(t.Fragment,{children:c})}f.displayName="For";var c={configurable:!0,get:function(){return this.value},set:function(e){this.value=e}};e.For=f;e.Show=u;e.useLiveSignal=function(e){var r=n.useSignal(e);if(r.peek()!==e)r.value=e;return r};e.useSignalRef=function(e){var r=n.useSignal(e);if(!("current"in r))Object.defineProperty(r,"current",c);return r}});//# sourceMappingURL=utils.min.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.min.js","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["
|
|
1
|
+
{"version":3,"file":"utils.min.js","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nItem.displayName = \"Item\";\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\nShow.displayName = \"Show\";\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nFor.displayName = \"For\";\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["Item","props","useSignals","children","v","i","displayName","Show","value","when","fallback","createElement","For","cache","useMemo","Map","list","each","length","removed","Set","keys","items","map","key","has","result","set","get","forEach","Fragment","refSignalProto","configurable","this","exports","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty"],"mappings":"ybAWA,IAAMA,EAAO,SAACC,GACbC,EAAUA,aACV,MAAiC,mBAAnBD,EAAME,SACjBF,EAAME,SAASF,EAAMG,EAAGH,EAAMI,GAC9BJ,EAAME,QACV,EAEAH,EAAKM,YAAc,OAEb,SAAUC,EAAkBN,GACjCC,EAAUA,aACV,IAAMM,EACiB,mBAAfP,EAAMQ,KAAsBR,EAAMQ,OAASR,EAAMQ,KAAKD,MAC9D,IAAKA,EAAO,OAAQP,EAAMS,UAA4B,UACtD,OAAOC,gBAACX,EAAK,CAAAI,EAAGI,EAAOL,SAAUF,EAAME,UACxC,CAEAI,EAAKD,YAAc,OAWH,SAAAM,EAAOX,GACtBC,EAAUA,aACV,IAAMW,EAAQC,EAAAA,QAAQ,WAAA,OAAU,IAAAC,GAAK,EAAE,IACnCC,GACoB,mBAAff,EAAMgB,KAAsBhB,EAAMgB,OAAShB,EAAMgB,MAGxDT,MAEF,IAAKQ,EAAKE,OAAQ,OAAQjB,EAAMS,UAA4B,KAE5D,IAAMS,EAAU,IAAIC,IAAIP,EAAMQ,QAExBC,EAAQN,EAAKO,IAAI,SAACf,EAAOgB,GAC9BL,EAAc,OAACX,GACf,IAAKK,EAAMY,IAAIjB,GAAQ,CACtB,IAAMkB,EACLf,gBAACX,GAAKI,EAAGI,EAAOgB,IAAKA,EAAKnB,EAAGmB,EAAKrB,SAAUF,EAAME,WAEnDU,EAAMc,IAAInB,EAAOkB,GACjB,OAAOA,CACR,CACA,OAAOb,EAAMe,IAAIpB,EAClB,GAEAW,EAAQU,QAAQ,SAAArB,GACfK,EAAY,OAACL,EACd,GAEA,OAAOG,gBAAcmB,EAAAA,SAAU,CAAE3B,SAAUmB,GAC5C,CAEAV,EAAIN,YAAc,MAclB,IAAMyB,EAAiB,CACtBC,cAAc,EACdJ,IAAA,WACC,OAAWK,KAACzB,KACb,EACAmB,aAAkBvB,GACjB6B,KAAKzB,MAAQJ,CACd,GACA8B,EAAAtB,IAAAA,EAAAsB,EAAA3B,KAAAA,EAAA2B,EAAAC,cApBe,SAAiB3B,GAChC,IAAM4B,EAAIC,EAASA,UAAC7B,GACpB,GAAI4B,EAAEE,SAAW9B,EAAO4B,EAAE5B,MAAQA,EAClC,OAAO4B,CACR,EAgBCF,EAAAK,aAdK,SAA0B/B,GAC/B,IAAMgC,EAAMH,EAASA,UAAC7B,GACtB,KAAM,YAAagC,GAClBC,OAAOC,eAAeF,EAAK,UAAWT,GACvC,OAAOS,CACR,CASC"}
|
package/utils/dist/utils.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useSignal}from"@preact/signals-react";import{useSignals as t}from"@preact/signals-react/runtime";import{createElement as n,useMemo as r,Fragment as e}from"react";const
|
|
1
|
+
import{useSignal}from"@preact/signals-react";import{useSignals as t}from"@preact/signals-react/runtime";import{createElement as n,useMemo as r,Fragment as e}from"react";const o=n=>{t();return"function"==typeof n.children?n.children(n.v,n.i):n.children};o.displayName="Item";function c(r){t();const e="function"==typeof r.when?r.when():r.when.value;if(!e)return r.fallback||null;else return n(o,{v:e,children:r.children})}c.displayName="Show";function i(c){t();const i=r(()=>new Map,[]);let u=("function"==typeof c.each?c.each():c.each).value;if(!u.length)return c.fallback||null;const f=new Set(i.keys()),s=u.map((t,r)=>{f.delete(t);if(!i.has(t)){const e=n(o,{v:t,key:r,i:r,children:c.children});i.set(t,e);return e}return i.get(t)});f.forEach(t=>{i.delete(t)});return n(e,{children:s})}i.displayName="For";function u(t){const n=useSignal(t);if(n.peek()!==t)n.value=t;return n}function f(t){const n=useSignal(t);if(!("current"in n))Object.defineProperty(n,"current",s);return n}const s={configurable:!0,get(){return this.value},set(t){this.value=t}};export{i as For,c as Show,u as useLiveSignal,f as useSignalRef};//# sourceMappingURL=utils.mjs.map
|
package/utils/dist/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["
|
|
1
|
+
{"version":3,"file":"utils.mjs","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nItem.displayName = \"Item\";\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\nShow.displayName = \"Show\";\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nFor.displayName = \"For\";\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["Item","props","useSignals","children","v","i","displayName","Show","value","when","fallback","createElement","For","cache","useMemo","Map","list","each","length","removed","Set","keys","items","map","key","delete","has","result","set","get","forEach","Fragment","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty","refSignalProto","configurable","this"],"mappings":"yKAWA,MAAMA,EAAQC,IACbC,IACA,MAAiC,mBAAnBD,EAAME,SACjBF,EAAME,SAASF,EAAMG,EAAGH,EAAMI,GAC9BJ,EAAME,UAGVH,EAAKM,YAAc,OAEH,SAAAC,EAAkBN,GACjCC,IACA,MAAMM,EACiB,mBAAfP,EAAMQ,KAAsBR,EAAMQ,OAASR,EAAMQ,KAAKD,MAC9D,IAAKA,EAAO,OAAQP,EAAMS,UAA4B,UACtD,OAAOC,EAACX,EAAK,CAAAI,EAAGI,EAAOL,SAAUF,EAAME,UACxC,CAEAI,EAAKD,YAAc,gBAWHM,EAAOX,GACtBC,IACA,MAAMW,EAAQC,EAAQ,IAAM,IAAIC,IAAO,IACvC,IAAIC,GACoB,mBAAff,EAAMgB,KAAsBhB,EAAMgB,OAAShB,EAAMgB,MAGxDT,MAEF,IAAKQ,EAAKE,OAAQ,OAAQjB,EAAMS,UAA4B,KAE5D,MAAMS,EAAU,IAAIC,IAAIP,EAAMQ,QAExBC,EAAQN,EAAKO,IAAI,CAACf,EAAOgB,KAC9BL,EAAQM,OAAOjB,GACf,IAAKK,EAAMa,IAAIlB,GAAQ,CACtB,MAAMmB,EACLhB,EAACX,GAAKI,EAAGI,EAAOgB,IAAKA,EAAKnB,EAAGmB,EAAKrB,SAAUF,EAAME,WAEnDU,EAAMe,IAAIpB,EAAOmB,GACjB,OAAOA,CACR,CACA,OAAOd,EAAMgB,IAAIrB,EAAK,GAGvBW,EAAQW,QAAQtB,IACfK,EAAMY,OAAOjB,KAGd,OAAOG,EAAcoB,EAAU,CAAE5B,SAAUmB,GAC5C,CAEAV,EAAIN,YAAc,MAEF,SAAA0B,EAAiBxB,GAChC,MAAMyB,EAAIC,UAAU1B,GACpB,GAAIyB,EAAEE,SAAW3B,EAAOyB,EAAEzB,MAAQA,EAClC,OAAOyB,CACR,CAEM,SAAUG,EAAgB5B,GAC/B,MAAM6B,EAAMH,UAAU1B,GACtB,KAAM,YAAa6B,GAClBC,OAAOC,eAAeF,EAAK,UAAWG,GACvC,OAAOH,CACR,CACA,MAAMG,EAAiB,CACtBC,cAAc,EACdZ,MACC,OAAWa,KAAClC,KACb,EACAoB,IAAkBxB,GACjBsC,KAAKlC,MAAQJ,CACd,UACAQ,SAAAL,UAAAyB,mBAAAI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{useSignal}from"@preact/signals-react";import{useSignals as
|
|
1
|
+
import{useSignal}from"@preact/signals-react";import{useSignals as r}from"@preact/signals-react/runtime";import{createElement as n,useMemo as t,Fragment as e}from"react";var i=function(n){r();return"function"==typeof n.children?n.children(n.v,n.i):n.children};i.displayName="Item";function u(t){r();var e="function"==typeof t.when?t.when():t.when.value;if(!e)return t.fallback||null;else return n(i,{v:e,children:t.children})}u.displayName="Show";function o(u){r();var o=t(function(){return new Map},[]),c=("function"==typeof u.each?u.each():u.each).value;if(!c.length)return u.fallback||null;var f=new Set(o.keys()),a=c.map(function(r,t){f.delete(r);if(!o.has(r)){var e=n(i,{v:r,key:t,i:t,children:u.children});o.set(r,e);return e}return o.get(r)});f.forEach(function(r){o.delete(r)});return n(e,{children:a})}o.displayName="For";function c(r){var n=useSignal(r);if(n.peek()!==r)n.value=r;return n}function f(r){var n=useSignal(r);if(!("current"in n))Object.defineProperty(n,"current",a);return n}var a={configurable:!0,get:function(){return this.value},set:function(r){this.value=r}};export{o as For,u as Show,c as useLiveSignal,f as useSignalRef};//# sourceMappingURL=utils.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.module.js","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["
|
|
1
|
+
{"version":3,"file":"utils.module.js","sources":["../src/index.tsx"],"sourcesContent":["import { ReadonlySignal, Signal } from \"@preact/signals-core\";\nimport { useSignal } from \"@preact/signals-react\";\nimport { useSignals } from \"@preact/signals-react/runtime\";\nimport { Fragment, createElement, useMemo, ReactNode } from \"react\";\n\ninterface ShowProps<T = boolean> {\n\twhen: Signal<T> | ReadonlySignal<T> | (() => T);\n\tfallback?: ReactNode;\n\tchildren: ReactNode | ((value: NonNullable<T>) => ReactNode);\n}\n\nconst Item = (props: any) => {\n\tuseSignals();\n\treturn typeof props.children === \"function\"\n\t\t? props.children(props.v, props.i)\n\t\t: props.children;\n};\n\nItem.displayName = \"Item\";\n\nexport function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst value =\n\t\ttypeof props.when === \"function\" ? props.when() : props.when.value;\n\tif (!value) return (props.fallback as JSX.Element) || null;\n\treturn <Item v={value} children={props.children} />;\n}\n\nShow.displayName = \"Show\";\n\ninterface ForProps<T> {\n\teach:\n\t\t| Signal<Array<T>>\n\t\t| ReadonlySignal<Array<T>>\n\t\t| (() => Signal<Array<T>> | ReadonlySignal<Array<T>>);\n\tfallback?: ReactNode;\n\tchildren: (value: T, index: number) => ReactNode;\n}\n\nexport function For<T>(props: ForProps<T>): JSX.Element | null {\n\tuseSignals();\n\tconst cache = useMemo(() => new Map(), []);\n\tlet list = (\n\t\t(typeof props.each === \"function\" ? props.each() : props.each) as Signal<\n\t\t\tArray<T>\n\t\t>\n\t).value;\n\n\tif (!list.length) return (props.fallback as JSX.Element) || null;\n\n\tconst removed = new Set(cache.keys());\n\n\tconst items = list.map((value, key) => {\n\t\tremoved.delete(value);\n\t\tif (!cache.has(value)) {\n\t\t\tconst result = (\n\t\t\t\t<Item v={value} key={key} i={key} children={props.children} />\n\t\t\t);\n\t\t\tcache.set(value, result);\n\t\t\treturn result;\n\t\t}\n\t\treturn cache.get(value);\n\t});\n\n\tremoved.forEach(value => {\n\t\tcache.delete(value);\n\t});\n\n\treturn createElement(Fragment, { children: items });\n}\n\nFor.displayName = \"For\";\n\nexport function useLiveSignal<T>(value: T): Signal<T> {\n\tconst s = useSignal(value);\n\tif (s.peek() !== value) s.value = value;\n\treturn s;\n}\n\nexport function useSignalRef<T>(value: T) {\n\tconst ref = useSignal(value) as Signal<T> & { current: T };\n\tif (!(\"current\" in ref))\n\t\tObject.defineProperty(ref, \"current\", refSignalProto);\n\treturn ref;\n}\nconst refSignalProto = {\n\tconfigurable: true,\n\tget(this: Signal) {\n\t\treturn this.value;\n\t},\n\tset(this: Signal, v: any) {\n\t\tthis.value = v;\n\t},\n};\n"],"names":["Item","props","useSignals","children","v","i","displayName","Show","value","when","fallback","createElement","For","cache","useMemo","Map","list","each","length","removed","Set","keys","items","map","key","has","result","set","get","forEach","Fragment","useLiveSignal","s","useSignal","peek","useSignalRef","ref","Object","defineProperty","refSignalProto","configurable","this"],"mappings":"yKAWA,IAAMA,EAAO,SAACC,GACbC,IACA,MAAiC,mBAAnBD,EAAME,SACjBF,EAAME,SAASF,EAAMG,EAAGH,EAAMI,GAC9BJ,EAAME,QACV,EAEAH,EAAKM,YAAc,OAEb,SAAUC,EAAkBN,GACjCC,IACA,IAAMM,EACiB,mBAAfP,EAAMQ,KAAsBR,EAAMQ,OAASR,EAAMQ,KAAKD,MAC9D,IAAKA,EAAO,OAAQP,EAAMS,UAA4B,UACtD,OAAOC,EAACX,EAAK,CAAAI,EAAGI,EAAOL,SAAUF,EAAME,UACxC,CAEAI,EAAKD,YAAc,OAWH,SAAAM,EAAOX,GACtBC,IACA,IAAMW,EAAQC,EAAQ,WAAA,OAAU,IAAAC,GAAK,EAAE,IACnCC,GACoB,mBAAff,EAAMgB,KAAsBhB,EAAMgB,OAAShB,EAAMgB,MAGxDT,MAEF,IAAKQ,EAAKE,OAAQ,OAAQjB,EAAMS,UAA4B,KAE5D,IAAMS,EAAU,IAAIC,IAAIP,EAAMQ,QAExBC,EAAQN,EAAKO,IAAI,SAACf,EAAOgB,GAC9BL,EAAc,OAACX,GACf,IAAKK,EAAMY,IAAIjB,GAAQ,CACtB,IAAMkB,EACLf,EAACX,GAAKI,EAAGI,EAAOgB,IAAKA,EAAKnB,EAAGmB,EAAKrB,SAAUF,EAAME,WAEnDU,EAAMc,IAAInB,EAAOkB,GACjB,OAAOA,CACR,CACA,OAAOb,EAAMe,IAAIpB,EAClB,GAEAW,EAAQU,QAAQ,SAAArB,GACfK,EAAY,OAACL,EACd,GAEA,OAAOG,EAAcmB,EAAU,CAAE3B,SAAUmB,GAC5C,CAEAV,EAAIN,YAAc,MAEF,SAAAyB,EAAiBvB,GAChC,IAAMwB,EAAIC,UAAUzB,GACpB,GAAIwB,EAAEE,SAAW1B,EAAOwB,EAAExB,MAAQA,EAClC,OAAOwB,CACR,CAEM,SAAUG,EAAgB3B,GAC/B,IAAM4B,EAAMH,UAAUzB,GACtB,KAAM,YAAa4B,GAClBC,OAAOC,eAAeF,EAAK,UAAWG,GACvC,OAAOH,CACR,CACA,IAAMG,EAAiB,CACtBC,cAAc,EACdZ,IAAA,WACC,OAAWa,KAACjC,KACb,EACAmB,aAAkBvB,GACjBqC,KAAKjC,MAAQJ,CACd,UACAQ,SAAAL,UAAAwB,mBAAAI"}
|
package/utils/src/index.tsx
CHANGED
|
@@ -16,6 +16,8 @@ const Item = (props: any) => {
|
|
|
16
16
|
: props.children;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
+
Item.displayName = "Item";
|
|
20
|
+
|
|
19
21
|
export function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {
|
|
20
22
|
useSignals();
|
|
21
23
|
const value =
|
|
@@ -24,6 +26,8 @@ export function Show<T = boolean>(props: ShowProps<T>): JSX.Element | null {
|
|
|
24
26
|
return <Item v={value} children={props.children} />;
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
Show.displayName = "Show";
|
|
30
|
+
|
|
27
31
|
interface ForProps<T> {
|
|
28
32
|
each:
|
|
29
33
|
| Signal<Array<T>>
|
|
@@ -65,6 +69,8 @@ export function For<T>(props: ForProps<T>): JSX.Element | null {
|
|
|
65
69
|
return createElement(Fragment, { children: items });
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
For.displayName = "For";
|
|
73
|
+
|
|
68
74
|
export function useLiveSignal<T>(value: T): Signal<T> {
|
|
69
75
|
const s = useSignal(value);
|
|
70
76
|
if (s.peek() !== value) s.value = value;
|