@preact/signals-react 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @preact/signals-react
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#91](https://github.com/preactjs/signals/pull/91) [`fb74bb9`](https://github.com/preactjs/signals/commit/fb74bb9ce4e44192e1ee7d3d041274cc985db767) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - add the `useSignalEffect` hook
8
+
9
+ * [#183](https://github.com/preactjs/signals/pull/183) [`79ff1e7`](https://github.com/preactjs/signals/commit/79ff1e794dde9952db2d6d43b22cebfb2accc770) Thanks [@jviide](https://github.com/jviide)! - Add ability to run custom cleanup logic when an effect is disposed.
10
+
11
+ ```js
12
+ effect(() => {
13
+ console.log("This runs whenever a dependency changes");
14
+ return () => {
15
+ console.log("This runs when the effect is disposed");
16
+ });
17
+ });
18
+ ```
19
+
20
+ ### Patch Changes
21
+
22
+ - [#161](https://github.com/preactjs/signals/pull/161) [`6ac6923`](https://github.com/preactjs/signals/commit/6ac6923e5294f8a31ee1a009550b9891c3996cb4) Thanks [@jviide](https://github.com/jviide)! - Remove all usages of `Set`, `Map` and other allocation heavy objects in signals-core. This substaintially increases performance across all measurements.
23
+
24
+ - Updated dependencies [[`b4611cc`](https://github.com/preactjs/signals/commit/b4611cc9dee0ae09f4b378ba293c3203edc32be4), [`9802da5`](https://github.com/preactjs/signals/commit/9802da5274bb45c3cc28dda961b9b2d18535729a), [`6ac6923`](https://github.com/preactjs/signals/commit/6ac6923e5294f8a31ee1a009550b9891c3996cb4), [`79ff1e7`](https://github.com/preactjs/signals/commit/79ff1e794dde9952db2d6d43b22cebfb2accc770), [`3e31aab`](https://github.com/preactjs/signals/commit/3e31aabb812ddb0f7451deba38267f8384eff9d1)]:
25
+ - @preact/signals-core@1.2.0
26
+
27
+ ## 1.0.2
28
+
29
+ ### Patch Changes
30
+
31
+ - [#147](https://github.com/preactjs/signals/pull/147) [`3556499`](https://github.com/preactjs/signals/commit/355649903b766630b62cdd0f90a35d3eafa99fa9) Thanks [@developit](https://github.com/developit)! - Improve performance when rendering Signals as Text in Preact.
32
+
33
+ * [#148](https://github.com/preactjs/signals/pull/148) [`b948745`](https://github.com/preactjs/signals/commit/b948745de7b5b60a20ce3bdc5ee72d47d47f38ec) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - Move `types` field in `package.json` to the top of the entry list to ensure that TypeScript always finds it.
34
+
35
+ - [#146](https://github.com/preactjs/signals/pull/146) [`9e798fd`](https://github.com/preactjs/signals/commit/9e798fdaf419566530696f850ea7fc1fc649d3cd) Thanks [@marvinhagemeister](https://github.com/marvinhagemeister)! - fix(react): track owners separately, mutate updaters with dispatcher
36
+
37
+ - Updated dependencies [[`f2ba3d6`](https://github.com/preactjs/signals/commit/f2ba3d657bf8169c6ba1d47c0827aa18cfe1c947), [`160ea77`](https://github.com/preactjs/signals/commit/160ea7791f3adb55c562f5990e0b4848d8491a38), [`4385ea8`](https://github.com/preactjs/signals/commit/4385ea8c8358a154d8b789685bb061658ce1153f), [`b948745`](https://github.com/preactjs/signals/commit/b948745de7b5b60a20ce3bdc5ee72d47d47f38ec), [`00a59c6`](https://github.com/preactjs/signals/commit/00a59c6475bd4542fb934474d82d1e242b2ac870)]:
38
+ - @preact/signals-core@1.1.1
39
+
3
40
  ## 1.0.1
4
41
 
5
42
  ### Patch Changes
package/dist/signals.d.ts CHANGED
@@ -2,3 +2,4 @@ import { signal, computed, batch, effect, Signal, type ReadonlySignal } from "@p
2
2
  export { signal, computed, batch, effect, Signal, type ReadonlySignal };
3
3
  export declare function useSignal<T>(value: T): Signal<T>;
4
4
  export declare function useComputed<T>(compute: () => T): ReadonlySignal<T>;
5
+ export declare function useSignalEffect(cb: () => void | (() => void)): void;
package/dist/signals.js CHANGED
@@ -1 +1 @@
1
- var r=require("react"),n=require("@preact/signals-core");function t(r){return r&&"object"==typeof r&&"default"in r?r.default:r}var e,u=/*#__PURE__*/t(r),o=u.createElement;u.createElement=function(r,t){if("string"==typeof r&&t)for(var e in t){var u=t[e];"children"!==e&&u instanceof n.Signal&&(t[e]=u.value)}return o.apply(this,arguments)};var i=new WeakMap;function a(r){e&&e(!0,!0),e=r&&r._()}function c(r){var t=n.signal(void 0);return t._u=r,t}var f=o("a").$$typeof;Object.defineProperties(n.Signal.prototype,{$$typeof:{value:f},type:{value:function(r){return r.data.value}},props:{get:function(){return{data:this}}},ref:{value:null}});var v,s=!1,p=function(){return{}};Object.defineProperty(r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher,"current",{get:function(){return v},set:function(n){if(v=n,!s)if(n&&!x(n)){s=!0;var t=n.useReducer(p,{})[1];s=!1;var e=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner.current,u=i.get(e);u||(u=c(t),i.set(e,u)),a(u)}else a()}});var l=new Map;function x(r){var n=l.get(r);if(void 0!==n)return n;var t=r.useCallback.length<2||/warnInvalidHookAccess/.test(r.useCallback);return l.set(r,t),t}exports.Signal=n.Signal,exports.batch=n.batch,exports.computed=n.computed,exports.effect=n.effect,exports.signal=n.signal,exports.useComputed=function(t){var e=r.useRef(t);return e.current=t,r.useMemo(function(){return n.computed(function(){return e.current()})},[])},exports.useSignal=function(t){return r.useMemo(function(){return n.signal(t)},[])};//# sourceMappingURL=signals.js.map
1
+ var r=require("react"),n=require("@preact/signals-core");function t(r){return r&&"object"==typeof r&&"default"in r?r.default:r}var e,u=/*#__PURE__*/t(r),i=u.createElement;u.createElement=function(r,t){if("string"==typeof r&&t)for(var e in t){var u=t[e];if("children"!==e&&u instanceof n.Signal)t[e]=u.value}return i.apply(this,arguments)};var o=new WeakMap;function f(r){if(e)e();e=r&&r.S()}var c,a=i("a").$$typeof;Object.defineProperties(n.Signal.prototype,{$$typeof:{configurable:!0,value:a},type:{configurable:!0,value:function(r){return r.data.value}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});var s=null;Object.defineProperty(r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,"current",{get:function(){return s},set:function(r){if(s=r)c=s}});var v,l=!1,p=function(){return{}};Object.defineProperty(r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher,"current",{get:function(){return v},set:function(r){v=r;if(!l)if(c&&r&&!function(r){var n=g.get(r);if(void 0!==n)return n;var t=r.useCallback.length<2||/warnInvalidHookAccess/.test(r.useCallback);g.set(r,t);return t}(r)){l=!0;var t=r.useReducer(p,{})[1];l=!1;var e=o.get(c);if(!e){e=function(r){var t;n.effect(function(){t=this});t.c=r;return t}(t);o.set(c,e)}else e.c=t;f(e)}else f()}});var g=new Map;exports.Signal=n.Signal;exports.batch=n.batch;exports.computed=n.computed;exports.effect=n.effect;exports.signal=n.signal;exports.useComputed=function(t){var e=r.useRef(t);e.current=t;return r.useMemo(function(){return n.computed(function(){return e.current()})},[])};exports.useSignal=function(t){return r.useMemo(function(){return n.signal(t)},[])};exports.useSignalEffect=function(t){var e=r.useRef(t);e.current=t;r.useEffect(function(){return n.effect(function(){return e.current()})},[])};//# sourceMappingURL=signals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Updater, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: ReturnType<Updater[\"_setCurrent\"]> | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Updater>();\n\nfunction setCurrentUpdater(updater?: Updater) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate(true, true);\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._setCurrent();\n}\n\nfunction createUpdater(updater: () => void) {\n\tconst s = signal(undefined) as Updater;\n\ts._updater = updater;\n\treturn s;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { value: $$typeof },\n\ttype: { value: Text },\n\tprops: {\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { value: null },\n});\n\n// Track the current owner (roughly equiv to current vnode)\n// let currentOwner: ReactOwner;\n// Object.defineProperty(internals.ReactCurrentOwner, \"current\", {\n// \tget() { return currentOwner; },\n// \tset(owner) { currentOwner = owner; },\n// });\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\t\t\tconst currentOwner = internals.ReactCurrentOwner.current;\n\t\t\tlet updater = updaterForComponent.get(currentOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(currentOwner, updater);\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n"],"names":["finishUpdate","createElement","React","type","props","i","v","Signal","value","apply","this","arguments","updaterForComponent","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","signal","undefined","_updater","$$typeof","Object","defineProperties","prototype","_ref","data","get","ref","currentDispatcher","lock","UPDATE","defineProperty","internals","ReactCurrentDispatcher","set","api","isInvalidHookAccessor","rerender","useReducer","currentOwner","ReactCurrentOwner","current","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","exports","signalsCore","batch","computed","effect","useComputed","compute","useRef","$compute","useMemo","useSignal"],"mappings":"mIAuDAA,sBA/BMC,EAAgBC,EAAMD,cAE5BC,EAAMD,cAAgB,SAAUE,EAAMC,GACrC,GAAoB,iBAATD,GAAqBC,EAC/B,IAAK,IAAIC,KAAKD,EAAO,CACpB,IAAIE,EAAIF,EAAMC,GACJ,aAANA,GAAoBC,aAAaC,EAAAA,SAEpCH,EAAMC,GAAKC,EAAEE,MAEd,CAGF,OAAOP,EAAcQ,MAAMC,KAAMC,UACjC,EAkBD,IAAMC,EAAsB,IAA5BC,QAEA,SAAAC,EAA2BC,GAEtBf,GAAcA,GAAa,GAAM,GAErCA,EAAee,GAAWA,EAAQC,GAClC,CAED,SAASC,EAAcF,GACtB,IAAOG,EAAGC,EAAAA,YAAOC,GAEjB,OADAF,EAAEG,GAAWN,EAEbG,CAAA,CAWD,MAAiBjB,EAAc,KAAKqB,SACpCC,OAAOC,iBAAiBjB,EAAMA,OAACkB,UAAW,CACzCH,SAAU,CAAEd,MAAOc,GACnBnB,KAAM,CAAEK,MATT,SAAwCkB,GACvC,OADuCA,EAAxBC,KACHnB,KACZ,GAQAJ,MAAO,CACNwB,IAAG,WACF,MAAO,CAAED,KAAMjB,KACf,GAEFmB,IAAK,CAAErB,MAAO,QAWf,IAEAsB,EAFIC,GAAO,EACLC,EAAS,WAAA,MAAO,EAAP,EAEfT,OAAOU,eAAeC,EAAAA,mDAAUC,uBAAwB,UAAW,CAClEP,IAAG,WACF,OAAOE,CACP,EACDM,IAAIC,SAAAA,GAEH,GADAP,EAAoBO,GAChBN,EACJ,GAAIM,IAAQC,EAAsBD,GAAM,CAGvCN,GAAO,EACP,IAAMQ,EAAWF,EAAIG,WAAWR,EAAQ,CAAA,GAAI,GAC5CD,GAAO,EACP,IAAkBU,EAAGP,EAAAA,mDAAUQ,kBAAkBC,QAC7C5B,EAAUH,EAAoBgB,IAAIa,GACjC1B,IACJA,EAAUE,EAAcsB,GACxB3B,EAAoBwB,IAAIK,EAAc1B,IAEvCD,EAAkBC,EAClB,MACAD,GAED,IAKF,IAAM8B,EAAuB,IAA7BC,IACA,SAASP,EAAsBD,GAC9B,IAAMS,EAASF,EAAqBhB,IAAIS,GACxC,QAAejB,IAAX0B,EAAsB,OAAOA,EAEjC,IAAaC,EACZV,EAAIW,YAAYC,OAAS,GACzB,wBAAwBC,KAAKb,EAAIW,aAElC,OADAJ,EAAqBR,IAAIC,EAAKU,GAE9BA,CAAA,CAUAI,QAAA5C,OAAA6C,EAAA7C,OAAA4C,QAAAE,MAAAD,EAAAC,MAAAF,QAAAG,SAAAF,EAAAE,SAAAH,QAAAI,OAAAH,EAAAG,OAAAJ,QAAAhC,OAAAiC,EAAAjC,OAAAgC,QAAAK,YAJK,SAAyBC,GAC9B,MAAiBC,EAAAA,OAAOD,GAExB,OADAE,EAAShB,QAAUc,EACZG,EAAOA,QAAC,WAAA,OAAcN,EAAAA,SAAI,WAAMK,OAAAA,EAAShB,SAAf,EAAlB,EAA6C,GAC5D,EAAAQ,QAAAU,UARK,SAAuBrD,GAC5B,OAAcoD,EAAAA,QAAC,WAAMzC,OAAAA,EAAMA,OAAIX,EAAhB,EAAwB,GACvC"}
1
+ {"version":3,"file":"signals.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Effect, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: (() => void) | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Effect>();\n\nfunction setCurrentUpdater(updater?: Effect) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate();\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._start();\n}\n\nfunction createUpdater(update: () => void) {\n\tlet updater!: Effect;\n\teffect(function (this: Effect) {\n\t\tupdater = this;\n\t});\n\tupdater._callback = update;\n\treturn updater;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: $$typeof },\n\ttype: { configurable: true, value: Text },\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\n// Track the current owner (roughly equiv to current vnode)\nlet lastOwner: ReactOwner | undefined;\nlet currentOwner: ReactOwner | null = null;\nObject.defineProperty(internals.ReactCurrentOwner, \"current\", {\n\tget() {\n\t\treturn currentOwner;\n\t},\n\tset(owner) {\n\t\tcurrentOwner = owner;\n\t\tif (currentOwner) lastOwner = currentOwner;\n\t},\n});\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (lastOwner && api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\n\t\t\tlet updater = updaterForComponent.get(lastOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(lastOwner, updater);\n\t\t\t} else {\n\t\t\t\tupdater._callback = rerender;\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(() => {\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n"],"names":["React","require","signalsCore","_interopDefaultLegacy","e","default","finishUpdate","React__default","createElement","type","props","i","v","Signal","value","apply","this","arguments","updaterForComponent","setCurrentUpdater","updater","_start","lastOwner","$$typeof","Object","defineProperties","prototype","configurable","_ref","data","get","ref","currentOwner","defineProperty","internals","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","ReactCurrentOwner","set","owner","currentDispatcher","UPDATE","ReactCurrentDispatcher","api","lock","cached","invalidHookAccessors","undefined","invalid","useCallback","length","test","isInvalidHookAccessor","rerender","useReducer","update","effect","_callback","createUpdater","Map","exports","batch","computed","signal","useComputed","compute","$compute","useRef","current","useMemo","useSignal","useSignalEffect","cb","callback","useEffect"],"mappings":"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"}
@@ -1 +1 @@
1
- !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("@preact/signals-core")):"function"==typeof define&&define.amd?define(["exports","react","@preact/signals-core"],e):e((n||self).reactSignals={},n.react,n.signalsCore)}(this,function(n,e,r){function t(n){return n&&"object"==typeof n&&"default"in n?n.default:n}var i,u=/*#__PURE__*/t(e),o=u.createElement;u.createElement=function(n,e){if("string"==typeof n&&e)for(var t in e){var i=e[t];"children"!==t&&i instanceof r.Signal&&(e[t]=i.value)}return o.apply(this,arguments)};var f=new WeakMap;function a(n){i&&i(!0,!0),i=n&&n._()}function c(n){var e=r.signal(void 0);return e._u=n,e}var s=o("a").$$typeof;Object.defineProperties(r.Signal.prototype,{$$typeof:{value:s},type:{value:function(n){return n.data.value}},props:{get:function(){return{data:this}}},ref:{value:null}});var v,l=!1,p=function(){return{}};Object.defineProperty(e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher,"current",{get:function(){return v},set:function(n){if(v=n,!l)if(n&&!y(n)){l=!0;var r=n.useReducer(p,{})[1];l=!1;var t=e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner.current,i=f.get(t);i||(i=c(r),f.set(t,i)),a(i)}else a()}});var d=new Map;function y(n){var e=d.get(n);if(void 0!==e)return e;var r=n.useCallback.length<2||/warnInvalidHookAccess/.test(n.useCallback);return d.set(n,r),r}n.Signal=r.Signal,n.batch=r.batch,n.computed=r.computed,n.effect=r.effect,n.signal=r.signal,n.useComputed=function(n){var t=e.useRef(n);return t.current=n,e.useMemo(function(){return r.computed(function(){return t.current()})},[])},n.useSignal=function(n){return e.useMemo(function(){return r.signal(n)},[])}});//# sourceMappingURL=signals.min.js.map
1
+ !function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("react"),require("@preact/signals-core")):"function"==typeof define&&define.amd?define(["exports","react","@preact/signals-core"],e):e((n||self).reactSignals={},n.react,n.signalsCore)}(this,function(n,e,r){function t(n){return n&&"object"==typeof n&&"default"in n?n.default:n}var i,u=/*#__PURE__*/t(e),f=u.createElement;u.createElement=function(n,e){if("string"==typeof n&&e)for(var t in e){var i=e[t];if("children"!==t&&i instanceof r.Signal)e[t]=i.value}return f.apply(this,arguments)};var o=new WeakMap;function c(n){if(i)i();i=n&&n.S()}var a,l=f("a").$$typeof;Object.defineProperties(r.Signal.prototype,{$$typeof:{configurable:!0,value:l},type:{configurable:!0,value:function(n){return n.data.value}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});var s=null;Object.defineProperty(e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,"current",{get:function(){return s},set:function(n){if(s=n)a=s}});var v,p=!1,d=function(){return{}};Object.defineProperty(e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher,"current",{get:function(){return v},set:function(n){v=n;if(!p)if(a&&n&&!function(n){var e=g.get(n);if(void 0!==e)return e;var r=n.useCallback.length<2||/warnInvalidHookAccess/.test(n.useCallback);g.set(n,r);return r}(n)){p=!0;var e=n.useReducer(d,{})[1];p=!1;var t=o.get(a);if(!t){t=function(n){var e;r.effect(function(){e=this});e.c=n;return e}(e);o.set(a,t)}else t.c=e;c(t)}else c()}});var g=new Map;n.Signal=r.Signal;n.batch=r.batch;n.computed=r.computed;n.effect=r.effect;n.signal=r.signal;n.useComputed=function(n){var t=e.useRef(n);t.current=n;return e.useMemo(function(){return r.computed(function(){return t.current()})},[])};n.useSignal=function(n){return e.useMemo(function(){return r.signal(n)},[])};n.useSignalEffect=function(n){var t=e.useRef(n);t.current=n;e.useEffect(function(){return r.effect(function(){return t.current()})},[])}});//# sourceMappingURL=signals.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.min.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Updater, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: ReturnType<Updater[\"_setCurrent\"]> | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Updater>();\n\nfunction setCurrentUpdater(updater?: Updater) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate(true, true);\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._setCurrent();\n}\n\nfunction createUpdater(updater: () => void) {\n\tconst s = signal(undefined) as Updater;\n\ts._updater = updater;\n\treturn s;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { value: $$typeof },\n\ttype: { value: Text },\n\tprops: {\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { value: null },\n});\n\n// Track the current owner (roughly equiv to current vnode)\n// let currentOwner: ReactOwner;\n// Object.defineProperty(internals.ReactCurrentOwner, \"current\", {\n// \tget() { return currentOwner; },\n// \tset(owner) { currentOwner = owner; },\n// });\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\t\t\tconst currentOwner = internals.ReactCurrentOwner.current;\n\t\t\tlet updater = updaterForComponent.get(currentOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(currentOwner, updater);\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n"],"names":["finishUpdate","createElement","React","type","props","i","v","Signal","value","apply","this","arguments","updaterForComponent","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","signal","undefined","_updater","$$typeof","Object","defineProperties","prototype","_ref","data","get","ref","currentDispatcher","lock","UPDATE","defineProperty","internals","ReactCurrentDispatcher","set","api","isInvalidHookAccessor","rerender","useReducer","currentOwner","ReactCurrentOwner","current","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","exports","signalsCore","batch","computed","effect","useComputed","compute","useRef","$compute","useMemo","useSignal"],"mappings":"0ZAuDAA,sBA/BMC,EAAgBC,EAAMD,cAE5BC,EAAMD,cAAgB,SAAUE,EAAMC,GACrC,GAAoB,iBAATD,GAAqBC,EAC/B,IAAK,IAAIC,KAAKD,EAAO,CACpB,IAAIE,EAAIF,EAAMC,GACJ,aAANA,GAAoBC,aAAaC,EAAAA,SAEpCH,EAAMC,GAAKC,EAAEE,MAEd,CAGF,OAAOP,EAAcQ,MAAMC,KAAMC,UACjC,EAkBD,IAAMC,EAAsB,IAA5BC,QAEA,SAAAC,EAA2BC,GAEtBf,GAAcA,GAAa,GAAM,GAErCA,EAAee,GAAWA,EAAQC,GAClC,CAED,SAASC,EAAcF,GACtB,IAAOG,EAAGC,EAAAA,YAAOC,GAEjB,OADAF,EAAEG,GAAWN,EAEbG,CAAA,CAWD,MAAiBjB,EAAc,KAAKqB,SACpCC,OAAOC,iBAAiBjB,EAAMA,OAACkB,UAAW,CACzCH,SAAU,CAAEd,MAAOc,GACnBnB,KAAM,CAAEK,MATT,SAAwCkB,GACvC,OADuCA,EAAxBC,KACHnB,KACZ,GAQAJ,MAAO,CACNwB,IAAG,WACF,MAAO,CAAED,KAAMjB,KACf,GAEFmB,IAAK,CAAErB,MAAO,QAWf,IAEAsB,EAFIC,GAAO,EACLC,EAAS,WAAA,MAAO,EAAP,EAEfT,OAAOU,eAAeC,EAAAA,mDAAUC,uBAAwB,UAAW,CAClEP,IAAG,WACF,OAAOE,CACP,EACDM,IAAIC,SAAAA,GAEH,GADAP,EAAoBO,GAChBN,EACJ,GAAIM,IAAQC,EAAsBD,GAAM,CAGvCN,GAAO,EACP,IAAMQ,EAAWF,EAAIG,WAAWR,EAAQ,CAAA,GAAI,GAC5CD,GAAO,EACP,IAAkBU,EAAGP,EAAAA,mDAAUQ,kBAAkBC,QAC7C5B,EAAUH,EAAoBgB,IAAIa,GACjC1B,IACJA,EAAUE,EAAcsB,GACxB3B,EAAoBwB,IAAIK,EAAc1B,IAEvCD,EAAkBC,EAClB,MACAD,GAED,IAKF,IAAM8B,EAAuB,IAA7BC,IACA,SAASP,EAAsBD,GAC9B,IAAMS,EAASF,EAAqBhB,IAAIS,GACxC,QAAejB,IAAX0B,EAAsB,OAAOA,EAEjC,IAAaC,EACZV,EAAIW,YAAYC,OAAS,GACzB,wBAAwBC,KAAKb,EAAIW,aAElC,OADAJ,EAAqBR,IAAIC,EAAKU,GAE9BA,CAAA,CAUAI,EAAA5C,OAAA6C,EAAA7C,OAAA4C,EAAAE,MAAAD,EAAAC,MAAAF,EAAAG,SAAAF,EAAAE,SAAAH,EAAAI,OAAAH,EAAAG,OAAAJ,EAAAhC,OAAAiC,EAAAjC,OAAAgC,EAAAK,YAJK,SAAyBC,GAC9B,MAAiBC,EAAAA,OAAOD,GAExB,OADAE,EAAShB,QAAUc,EACZG,EAAOA,QAAC,WAAA,OAAcN,EAAAA,SAAI,WAAMK,OAAAA,EAAShB,SAAf,EAAlB,EAA6C,GAC5D,EAAAQ,EAAAU,UARK,SAAuBrD,GAC5B,OAAcoD,EAAAA,QAAC,WAAMzC,OAAAA,EAAMA,OAAIX,EAAhB,EAAwB,GACvC,CAMA"}
1
+ {"version":3,"file":"signals.min.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Effect, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: (() => void) | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Effect>();\n\nfunction setCurrentUpdater(updater?: Effect) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate();\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._start();\n}\n\nfunction createUpdater(update: () => void) {\n\tlet updater!: Effect;\n\teffect(function (this: Effect) {\n\t\tupdater = this;\n\t});\n\tupdater._callback = update;\n\treturn updater;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: $$typeof },\n\ttype: { configurable: true, value: Text },\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\n// Track the current owner (roughly equiv to current vnode)\nlet lastOwner: ReactOwner | undefined;\nlet currentOwner: ReactOwner | null = null;\nObject.defineProperty(internals.ReactCurrentOwner, \"current\", {\n\tget() {\n\t\treturn currentOwner;\n\t},\n\tset(owner) {\n\t\tcurrentOwner = owner;\n\t\tif (currentOwner) lastOwner = currentOwner;\n\t},\n});\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (lastOwner && api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\n\t\t\tlet updater = updaterForComponent.get(lastOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(lastOwner, updater);\n\t\t\t} else {\n\t\t\t\tupdater._callback = rerender;\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(() => {\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n"],"names":["g","f","exports","module","require","define","amd","globalThis","self","reactSignals","react","signalsCore","this","React","_interopDefaultLegacy","e","default","finishUpdate","React__default","createElement","type","props","i","v","Signal","value","apply","arguments","updaterForComponent","setCurrentUpdater","updater","_start","lastOwner","$$typeof","Object","defineProperties","prototype","configurable","_ref","data","get","ref","currentOwner","defineProperty","internals","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","ReactCurrentOwner","set","owner","currentDispatcher","UPDATE","ReactCurrentDispatcher","api","lock","cached","invalidHookAccessors","undefined","invalid","useCallback","length","test","isInvalidHookAccessor","rerender","useReducer","update","effect","_callback","createUpdater","Map","batch","computed","signal","useComputed","compute","$compute","useRef","current","useMemo","useSignal","useSignalEffect","cb","callback","useEffect"],"mappings":"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"}
package/dist/signals.mjs CHANGED
@@ -1 +1 @@
1
- import t,{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as n,useMemo as e,useRef as o}from"react";import{Signal as r,signal as c,computed as i}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";const s=t.createElement;let a;t.createElement=function(t,n){if("string"==typeof t&&n)for(let t in n){let e=n[t];"children"!==t&&e instanceof r&&(n[t]=e.value)}return s.apply(this,arguments)};const f=new WeakMap;function u(t){a&&a(!0,!0),a=t&&t._()}function l(t){const n=c(void 0);return n._u=t,n}const p=s("a").$$typeof;Object.defineProperties(r.prototype,{$$typeof:{value:p},type:{value:function({data:t}){return t.value}},props:{get(){return{data:this}}},ref:{value:null}});let d=!1;const g=()=>({});let m;Object.defineProperty(n.ReactCurrentDispatcher,"current",{get:()=>m,set(t){if(m=t,!d)if(t&&!h(t)){d=!0;const e=t.useReducer(g,{})[1];d=!1;const o=n.ReactCurrentOwner.current;let r=f.get(o);r||(r=l(e),f.set(o,r)),u(r)}else u()}});const v=new Map;function h(t){const n=v.get(t);if(void 0!==n)return n;const e=t.useCallback.length<2||/warnInvalidHookAccess/.test(t.useCallback);return v.set(t,e),e}function b(t){return e(()=>c(t),[])}function w(t){const n=o(t);return n.current=t,e(()=>i(()=>n.current()),[])}export{w as useComputed,b as useSignal};//# sourceMappingURL=signals.mjs.map
1
+ import t,{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as e,useMemo as n,useRef as r,useEffect as o}from"react";import{Signal as c,effect as i,signal as f,computed as u}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";const l=t.createElement;t.createElement=function(t,e){if("string"==typeof t&&e)for(let t in e){let n=e[t];if("children"!==t&&n instanceof c)e[t]=n.value}return l.apply(this,arguments)};let s;const a=new WeakMap;function p(t){if(s)s();s=t&&t.S()}const g=l("a").$$typeof;Object.defineProperties(c.prototype,{$$typeof:{configurable:!0,value:g},type:{configurable:!0,value:function({data:t}){return t.value}},props:{configurable:!0,get(){return{data:this}}},ref:{configurable:!0,value:null}});let b,d=null;Object.defineProperty(e.ReactCurrentOwner,"current",{get:()=>d,set(t){d=t;if(d)b=d}});let m=!1;const h=()=>({});let v;Object.defineProperty(e.ReactCurrentDispatcher,"current",{get:()=>v,set(t){v=t;if(!m)if(b&&t&&!function(t){const e=j.get(t);if(void 0!==e)return e;const n=t.useCallback.length<2||/warnInvalidHookAccess/.test(t.useCallback);j.set(t,n);return n}(t)){m=!0;const e=t.useReducer(h,{})[1];m=!1;let n=a.get(b);if(!n){n=function(t){let e;i(function(){e=this});e.c=t;return e}(e);a.set(b,n)}else n.c=e;p(n)}else p()}});const j=new Map;function w(t){return n(()=>f(t),[])}function y(t){const e=r(t);e.current=t;return n(()=>u(()=>e.current()),[])}function O(t){const e=r(t);e.current=t;o(()=>i(()=>e.current()),[])}export{y as useComputed,w as useSignal,O as useSignalEffect};//# sourceMappingURL=signals.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Updater, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: ReturnType<Updater[\"_setCurrent\"]> | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Updater>();\n\nfunction setCurrentUpdater(updater?: Updater) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate(true, true);\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._setCurrent();\n}\n\nfunction createUpdater(updater: () => void) {\n\tconst s = signal(undefined) as Updater;\n\ts._updater = updater;\n\treturn s;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { value: $$typeof },\n\ttype: { value: Text },\n\tprops: {\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { value: null },\n});\n\n// Track the current owner (roughly equiv to current vnode)\n// let currentOwner: ReactOwner;\n// Object.defineProperty(internals.ReactCurrentOwner, \"current\", {\n// \tget() { return currentOwner; },\n// \tset(owner) { currentOwner = owner; },\n// });\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\t\t\tconst currentOwner = internals.ReactCurrentOwner.current;\n\t\t\tlet updater = updaterForComponent.get(currentOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(currentOwner, updater);\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n"],"names":["createElement","React","finishUpdate","type","props","i","v","Signal","value","apply","this","arguments","updaterForComponent","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","signal","undefined","_updater","$$typeof","Object","defineProperties","prototype","data","get","ref","lock","UPDATE","currentDispatcher","defineProperty","internals","ReactCurrentDispatcher","set","api","isInvalidHookAccessor","rerender","useReducer","currentOwner","ReactCurrentOwner","current","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","useSignal","useMemo","useComputed","compute","$compute","useRef","computed"],"mappings":"qPAwBA,MAAMA,EAAgBC,EAAMD,cA+B5B,IAAIE,EA7BJD,EAAMD,cAAgB,SAAUG,EAAMC,GACrC,GAAoB,iBAATD,GAAqBC,EAC/B,IAAK,IAAIC,KAAKD,EAAO,CACpB,IAAIE,EAAIF,EAAMC,GACJ,aAANA,GAAoBC,aAAxBC,IAECH,EAAMC,GAAKC,EAAEE,MAEd,CAGF,OAAoBR,EAACS,MAAMC,KAAMC,UACjC,EAkBD,MAAyBC,EAAG,IAAIC,QAEhC,SAASC,EAAkBC,GAEtBb,GAAcA,GAAa,GAAM,GAErCA,EAAea,GAAWA,EAAQC,GAClC,CAED,SAASC,EAAcF,GACtB,MAAOG,EAAGC,OAAOC,GAEjB,OADAF,EAAEG,GAAWN,EAEbG,CAAA,CAWD,MAAMI,EAAWtB,EAAc,KAAKsB,SACpCC,OAAOC,iBAAiBjB,EAAOkB,UAAW,CACzCH,SAAU,CAAEd,MAAOc,GACnBnB,KAAM,CAAEK,MATT,UAAckB,KAAEA,IACf,OAAOA,EAAKlB,KACZ,GAQAJ,MAAO,CACNuB,MACC,MAAO,CAAED,KAAMhB,KACf,GAEFkB,IAAK,CAAEpB,MAAO,QAWf,IAAIqB,GAAO,EACX,MAAMC,EAAS,KAAO,CAAP,GACf,IAAAC,EACAR,OAAOS,eAAeC,EAAUC,uBAAwB,UAAW,CAClEP,IAAG,IAEFI,EACDI,IAAIC,GAEH,GADAL,EAAoBK,GAChBP,EACJ,GAAIO,IAAQC,EAAsBD,GAAM,CAGvCP,GAAO,EACP,MAAcS,EAAGF,EAAIG,WAAWT,EAAQ,CAAvB,GAA2B,GAC5CD,GAAO,EACP,MAAkBW,EAAGP,EAAUQ,kBAAkBC,QACjD,IAAI3B,EAAUH,EAAoBe,IAAIa,GACjCzB,IACJA,EAAUE,EAAcqB,GACxB1B,EAAoBuB,IAAIK,EAAczB,IAEvCD,EAAkBC,EAClB,MACAD,GAED,IAKF,MAAM6B,EAAuB,IAA7BC,IACA,SAASP,EAAsBD,GAC9B,MAAYS,EAAGF,EAAqBhB,IAAIS,GACxC,QAAehB,IAAXyB,EAAsB,OAAAA,EAE1B,MAAMC,EACLV,EAAIW,YAAYC,OAAS,GACzB,wBAAwBC,KAAKb,EAAIW,aAElC,OADAJ,EAAqBR,IAAIC,EAAKU,GACvBA,CACP,CAEeI,SAAAA,EAAa1C,GAC5B,OAAO2C,EAAQ,IAAMhC,EAAUX,GAAQ,GACvC,CAEK,SAAA4C,EAAyBC,GAC9B,MAAMC,EAAWC,EAAOF,GAExB,OADAC,EAASZ,QAAUW,EACZF,EAAQ,IAAMK,EAAY,IAAMF,EAASZ,WAAY,GAC5D,QAAAU,iBAAAF"}
1
+ {"version":3,"file":"signals.mjs","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Effect, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: (() => void) | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Effect>();\n\nfunction setCurrentUpdater(updater?: Effect) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate();\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._start();\n}\n\nfunction createUpdater(update: () => void) {\n\tlet updater!: Effect;\n\teffect(function (this: Effect) {\n\t\tupdater = this;\n\t});\n\tupdater._callback = update;\n\treturn updater;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: $$typeof },\n\ttype: { configurable: true, value: Text },\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\n// Track the current owner (roughly equiv to current vnode)\nlet lastOwner: ReactOwner | undefined;\nlet currentOwner: ReactOwner | null = null;\nObject.defineProperty(internals.ReactCurrentOwner, \"current\", {\n\tget() {\n\t\treturn currentOwner;\n\t},\n\tset(owner) {\n\t\tcurrentOwner = owner;\n\t\tif (currentOwner) lastOwner = currentOwner;\n\t},\n});\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (lastOwner && api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\n\t\t\tlet updater = updaterForComponent.get(lastOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(lastOwner, updater);\n\t\t\t} else {\n\t\t\t\tupdater._callback = rerender;\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(() => {\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n"],"names":["React","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","useMemo","useRef","useEffect","Signal","effect","signal","computed","batch","createElement","type","props","v","i","value","apply","this","arguments","updaterForComponent","WeakMap","updater","finishUpdate","_start","$$typeof","Object","defineProperties","prototype","configurable","data","get","ref","lastOwner","defineProperty","internals","ReactCurrentOwner","set","owner","currentOwner","lock","UPDATE","currentDispatcher","ReactCurrentDispatcher","api","cached","invalidHookAccessors","undefined","invalid","useCallback","length","test","isInvalidHookAccessor","useReducer","update","_callback","createUpdater","rerender","setCurrentUpdater","Map","useSignal","useComputed","compute","$compute","current","useSignalEffect","cb","callback"],"mappings":"OAyBAA,yDAAAC,aAAAC,YAAAC,eAAAC,MAAA,yBAAAC,YAAAC,YAAAC,cAAAC,MAAA,8BAAAH,OAAAI,MAAAD,SAAAF,OAAAC,WAAA,uBAAA,MAAmBG,EAAGV,EAAMU,cAE5BV,EAAMU,cAAgB,SAAUC,EAAMC,GACrC,GAAoB,iBAAhBD,GAA4BC,EAC/B,IAAK,SAASA,EAAO,CACpB,IAAIC,EAAID,EAAME,GACd,GAAU,aAANA,GAAoBD,aAAaR,EAEpCO,EAAME,GAAKD,EAAEE,KAEd,CAGF,OAAoBL,EAACM,MAAMC,KAAMC,UACjC,EAiBD,MACA,MAAyBC,EAAG,IAAIC,QAEhC,WAA2BC,GAE1B,GAAIC,EAAcA,IAElBA,EAAeD,GAAWA,EAAQE,GAClC,CAoBD,MAAcC,EAAGd,EAAc,KAAKc,SACpCC,OAAOC,iBAAiBrB,EAAOsB,UAAW,CACzCH,SAAU,CAAEI,cAAc,EAAMb,MAAOS,GACvCb,KAAM,CAAEiB,cAAc,EAAMb,MAT7B,UAAcc,KAAEA,IACf,SAAYd,KACZ,GAQAH,MAAO,CACNgB,cAAc,EACdE,MACC,MAAO,CAAED,KAAMZ,KACf,GAEFc,IAAK,CAAEH,cAAc,EAAMb,MAAO,QAInC,IAAIiB,IACkC,KACtCP,OAAOQ,eAAeC,EAAUC,kBAAmB,UAAW,CAC7DL,IAAG,MAGHM,IAAIC,GACHC,EAAeD,EACf,GAAIC,EAAcN,EAAYM,CAC9B,IAIF,IAAQC,GAAG,EACX,MAAMC,EAAS,KAAA,CAAA,GACf,IAAIC,EACJhB,OAAOQ,eAAeC,EAAUQ,uBAAwB,UAAW,CAClEZ,IAAG,IACKW,EAERL,IAAIO,GACHF,EAAoBE,EACpB,IAAIJ,EACJ,GAAIP,GAAaW,IAwBnB,SAA+BA,GAC9B,MAAYC,EAAGC,EAAqBf,IAAIa,GACxC,QAAeG,IAAXF,EAAsB,OAAOA,EAEjC,MAAaG,EACZJ,EAAIK,YAAYC,OAAS,GACzB,wBAAwBC,KAAKP,EAAIK,aAClCH,EAAqBT,IAAIO,EAAKI,GAC9B,OAAOA,CACP,CAjC0BI,CAAsBR,GAAM,CAGpDJ,GAAO,EACP,QAAiBI,EAAIS,WAAWZ,EAAQ,CAAA,GAAI,GAC5CD,GAAO,EAEP,MAAcpB,EAAoBW,IAAIE,GACtC,IAAKX,EAAS,CACbA,EAhEJ,SAAuBgC,GACtB,IAAAhC,EACAf,EAAO,WACNe,EAAUJ,IACV,GACDI,EAAQiC,EAAYD,EACpB,OAAOhC,CACP,CAyDakC,CAAcC,GACxBrC,EAAoBiB,IAAIJ,EAAWX,EACnC,MACAA,EAAQiC,EAAYE,EAErBC,EAAkBpC,EAClB,MACAoC,GAED,IAKF,QAA6B,IAA7BC,aAYMC,EAAuB5C,GAC5B,OAAcb,EAAC,IAAMK,EAAUQ,GAAQ,GACvC,UAEK6C,EAAyBC,GAC9B,MAAcC,EAAG3D,EAAO0D,GACxBC,EAASC,QAAUF,EACnB,OAAc3D,EAAC,IAAMM,EAAY,IAAMsD,EAASC,WAAY,GAC5D,UAEKC,EAA0BC,GAC/B,MAAcC,EAAG/D,EAAO8D,GACxBC,EAASH,QAAUE,EAEnB7D,EAAU,IACFE,EAAO,IACN4D,EAASH,WAEf,GACH,QAAAH,iBAAAD,eAAAK"}
@@ -1 +1 @@
1
- import r,{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as n,useMemo as t,useRef as e}from"react";import{Signal as a,signal as i,computed as o}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";var u,c=r.createElement;r.createElement=function(r,n){if("string"==typeof r&&n)for(var t in n){var e=n[t];"children"!==t&&e instanceof a&&(n[t]=e.value)}return c.apply(this,arguments)};var f=new WeakMap;function v(r){u&&u(!0,!0),u=r&&r._()}function p(r){var n=i(void 0);return n._u=r,n}var s=c("a").$$typeof;Object.defineProperties(a.prototype,{$$typeof:{value:s},type:{value:function(r){return r.data.value}},props:{get:function(){return{data:this}}},ref:{value:null}});var l,g=!1,d=function(){return{}};Object.defineProperty(n.ReactCurrentDispatcher,"current",{get:function(){return l},set:function(r){if(l=r,!g)if(r&&!h(r)){g=!0;var t=r.useReducer(d,{})[1];g=!1;var e=n.ReactCurrentOwner.current,a=f.get(e);a||(a=p(t),f.set(e,a)),v(a)}else v()}});var m=new Map;function h(r){var n=m.get(r);if(void 0!==n)return n;var t=r.useCallback.length<2||/warnInvalidHookAccess/.test(r.useCallback);return m.set(r,t),t}function b(r){return t(function(){return i(r)},[])}function w(r){var n=e(r);return n.current=r,t(function(){return o(function(){return n.current()})},[])}export{w as useComputed,b as useSignal};//# sourceMappingURL=signals.module.js.map
1
+ import n,{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as r,useMemo as t,useRef as e,useEffect as u}from"react";import{Signal as i,effect as f,signal as o,computed as c}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";var a,v=n.createElement;n.createElement=function(n,r){if("string"==typeof n&&r)for(var t in r){var e=r[t];if("children"!==t&&e instanceof i)r[t]=e.value}return v.apply(this,arguments)};var l=new WeakMap;function s(n){if(a)a();a=n&&n.S()}var p,g=v("a").$$typeof;Object.defineProperties(i.prototype,{$$typeof:{configurable:!0,value:g},type:{configurable:!0,value:function(n){return n.data.value}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});var b=null;Object.defineProperty(r.ReactCurrentOwner,"current",{get:function(){return b},set:function(n){if(b=n)p=b}});var m,d=!1,h=function(){return{}};Object.defineProperty(r.ReactCurrentDispatcher,"current",{get:function(){return m},set:function(n){m=n;if(!d)if(p&&n&&!function(n){var r=j.get(n);if(void 0!==r)return r;var t=n.useCallback.length<2||/warnInvalidHookAccess/.test(n.useCallback);j.set(n,t);return t}(n)){d=!0;var r=n.useReducer(h,{})[1];d=!1;var t=l.get(p);if(!t){t=function(n){var r;f(function(){r=this});r.c=n;return r}(r);l.set(p,t)}else t.c=r;s(t)}else s()}});var j=new Map;function w(n){return t(function(){return o(n)},[])}function y(n){var r=e(n);r.current=n;return t(function(){return c(function(){return r.current()})},[])}function O(n){var r=e(n);r.current=n;u(function(){return f(function(){return r.current()})},[])}export{y as useComputed,w as useSignal,O as useSignalEffect};//# sourceMappingURL=signals.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.module.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Updater, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: ReturnType<Updater[\"_setCurrent\"]> | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Updater>();\n\nfunction setCurrentUpdater(updater?: Updater) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate(true, true);\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._setCurrent();\n}\n\nfunction createUpdater(updater: () => void) {\n\tconst s = signal(undefined) as Updater;\n\ts._updater = updater;\n\treturn s;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { value: $$typeof },\n\ttype: { value: Text },\n\tprops: {\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\tref: { value: null },\n});\n\n// Track the current owner (roughly equiv to current vnode)\n// let currentOwner: ReactOwner;\n// Object.defineProperty(internals.ReactCurrentOwner, \"current\", {\n// \tget() { return currentOwner; },\n// \tset(owner) { currentOwner = owner; },\n// });\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\t\t\tconst currentOwner = internals.ReactCurrentOwner.current;\n\t\t\tlet updater = updaterForComponent.get(currentOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(currentOwner, updater);\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n"],"names":["finishUpdate","createElement","React","type","props","i","v","Signal","value","apply","this","arguments","updaterForComponent","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","signal","undefined","_updater","$$typeof","Object","defineProperties","prototype","_ref","data","get","ref","currentDispatcher","lock","UPDATE","defineProperty","internals","ReactCurrentDispatcher","set","api","isInvalidHookAccessor","rerender","useReducer","currentOwner","ReactCurrentOwner","current","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","useSignal","useMemo","useComputed","compute","useRef","$compute","computed"],"mappings":"qPAwBA,IA+BAA,EA/BMC,EAAgBC,EAAMD,cAE5BC,EAAMD,cAAgB,SAAUE,EAAMC,GACrC,GAAoB,iBAATD,GAAqBC,EAC/B,IAAK,IAAIC,KAAKD,EAAO,CACpB,IAAIE,EAAIF,EAAMC,GACJ,aAANA,GAAoBC,aAAaC,IAEpCH,EAAMC,GAAKC,EAAEE,MAEd,CAGF,OAAOP,EAAcQ,MAAMC,KAAMC,UACjC,EAkBD,IAAMC,EAAsB,IAA5BC,QAEA,SAAAC,EAA2BC,GAEtBf,GAAcA,GAAa,GAAM,GAErCA,EAAee,GAAWA,EAAQC,GAClC,CAED,SAASC,EAAcF,GACtB,IAAOG,EAAGC,OAAOC,GAEjB,OADAF,EAAEG,GAAWN,EAEbG,CAAA,CAWD,MAAiBjB,EAAc,KAAKqB,SACpCC,OAAOC,iBAAiBjB,EAAOkB,UAAW,CACzCH,SAAU,CAAEd,MAAOc,GACnBnB,KAAM,CAAEK,MATT,SAAwCkB,GACvC,OADuCA,EAAxBC,KACHnB,KACZ,GAQAJ,MAAO,CACNwB,IAAG,WACF,MAAO,CAAED,KAAMjB,KACf,GAEFmB,IAAK,CAAErB,MAAO,QAWf,IAEAsB,EAFIC,GAAO,EACLC,EAAS,WAAA,MAAO,EAAP,EAEfT,OAAOU,eAAeC,EAAUC,uBAAwB,UAAW,CAClEP,IAAG,WACF,OAAOE,CACP,EACDM,IAAIC,SAAAA,GAEH,GADAP,EAAoBO,GAChBN,EACJ,GAAIM,IAAQC,EAAsBD,GAAM,CAGvCN,GAAO,EACP,IAAMQ,EAAWF,EAAIG,WAAWR,EAAQ,CAAA,GAAI,GAC5CD,GAAO,EACP,IAAkBU,EAAGP,EAAUQ,kBAAkBC,QAC7C5B,EAAUH,EAAoBgB,IAAIa,GACjC1B,IACJA,EAAUE,EAAcsB,GACxB3B,EAAoBwB,IAAIK,EAAc1B,IAEvCD,EAAkBC,EAClB,MACAD,GAED,IAKF,IAAM8B,EAAuB,IAA7BC,IACA,SAASP,EAAsBD,GAC9B,IAAMS,EAASF,EAAqBhB,IAAIS,GACxC,QAAejB,IAAX0B,EAAsB,OAAOA,EAEjC,IAAaC,EACZV,EAAIW,YAAYC,OAAS,GACzB,wBAAwBC,KAAKb,EAAIW,aAElC,OADAJ,EAAqBR,IAAIC,EAAKU,GAE9BA,CAAA,CAEK,SAAAI,EAAuB3C,GAC5B,OAAc4C,EAAC,WAAMjC,OAAAA,EAAUX,EAAhB,EAAwB,GACvC,CAEK,SAAA6C,EAAyBC,GAC9B,MAAiBC,EAAOD,GAExB,OADAE,EAASb,QAAUW,EACZF,EAAQ,WAAA,OAAcK,EAAI,WAAMD,OAAAA,EAASb,SAAf,EAAlB,EAA6C,GAC5D,QAAAU,iBAAAF"}
1
+ {"version":3,"file":"signals.module.js","sources":["../src/index.ts"],"sourcesContent":["import {\n\tuseRef,\n\tuseMemo,\n\tuseEffect,\n\t// @ts-ignore-next-line\n\t// eslint-disable-next-line @typescript-eslint/no-unused-vars\n\t__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,\n} from \"react\";\nimport React from \"react\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n} from \"@preact/signals-core\";\nimport { Effect, ReactOwner, ReactDispatcher } from \"./internal\";\n\nexport { signal, computed, batch, effect, Signal, type ReadonlySignal };\n\n/**\n * Install a middleware into React.createElement to replace any Signals in props with their value.\n * @todo this likely needs to be duplicated for jsx()...\n */\nconst createElement = React.createElement;\n// @ts-ignore-next-line\nReact.createElement = function (type, props) {\n\tif (typeof type === \"string\" && props) {\n\t\tfor (let i in props) {\n\t\t\tlet v = props[i];\n\t\t\tif (i !== \"children\" && v instanceof Signal) {\n\t\t\t\t// createPropUpdater(props, i, v);\n\t\t\t\tprops[i] = v.value;\n\t\t\t}\n\t\t}\n\t}\n\t// @ts-ignore-next-line\n\treturn createElement.apply(this, arguments);\n};\n\n/*\n// This breaks React's controlled components implementation\nfunction createPropUpdater(props: any, prop: string, signal: Signal) {\n\tlet ref = props.ref;\n\tif (!ref) ref = props.ref = React.createRef();\n\teffect(() => {\n\t\tif (props) props[prop] = signal.value;\n\t\tlet el = ref.current;\n\t\tif (!el) return; // unsubscribe\n\t\t(el as any)[prop] = signal.value;\n\t});\n\tprops = null;\n}\n*/\n\nlet finishUpdate: (() => void) | undefined;\nconst updaterForComponent = new WeakMap<ReactOwner, Effect>();\n\nfunction setCurrentUpdater(updater?: Effect) {\n\t// end tracking for the current update:\n\tif (finishUpdate) finishUpdate();\n\t// start tracking the new update:\n\tfinishUpdate = updater && updater._start();\n}\n\nfunction createUpdater(update: () => void) {\n\tlet updater!: Effect;\n\teffect(function (this: Effect) {\n\t\tupdater = this;\n\t});\n\tupdater._callback = update;\n\treturn updater;\n}\n\n/**\n * A wrapper component that renders a Signal's value directly as a Text node.\n */\nfunction Text({ data }: { data: Signal }) {\n\treturn data.value;\n}\n\n// Decorate Signals so React renders them as <Text> components.\n//@ts-ignore-next-line\nconst $$typeof = createElement(\"a\").$$typeof;\nObject.defineProperties(Signal.prototype, {\n\t$$typeof: { configurable: true, value: $$typeof },\n\ttype: { configurable: true, value: Text },\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\n// Track the current owner (roughly equiv to current vnode)\nlet lastOwner: ReactOwner | undefined;\nlet currentOwner: ReactOwner | null = null;\nObject.defineProperty(internals.ReactCurrentOwner, \"current\", {\n\tget() {\n\t\treturn currentOwner;\n\t},\n\tset(owner) {\n\t\tcurrentOwner = owner;\n\t\tif (currentOwner) lastOwner = currentOwner;\n\t},\n});\n\n// Track the current dispatcher (roughly equiv to current component impl)\nlet lock = false;\nconst UPDATE = () => ({});\nlet currentDispatcher: ReactDispatcher;\nObject.defineProperty(internals.ReactCurrentDispatcher, \"current\", {\n\tget() {\n\t\treturn currentDispatcher;\n\t},\n\tset(api) {\n\t\tcurrentDispatcher = api;\n\t\tif (lock) return;\n\t\tif (lastOwner && api && !isInvalidHookAccessor(api)) {\n\t\t\t// prevent re-injecting useReducer when the Dispatcher\n\t\t\t// context changes to run the reducer callback:\n\t\t\tlock = true;\n\t\t\tconst rerender = api.useReducer(UPDATE, {})[1];\n\t\t\tlock = false;\n\n\t\t\tlet updater = updaterForComponent.get(lastOwner);\n\t\t\tif (!updater) {\n\t\t\t\tupdater = createUpdater(rerender);\n\t\t\t\tupdaterForComponent.set(lastOwner, updater);\n\t\t\t} else {\n\t\t\t\tupdater._callback = rerender;\n\t\t\t}\n\t\t\tsetCurrentUpdater(updater);\n\t\t} else {\n\t\t\tsetCurrentUpdater();\n\t\t}\n\t},\n});\n\n// We inject a useReducer into every function component via CurrentDispatcher.\n// This prevents injecting into anything other than a function component render.\nconst invalidHookAccessors = new Map();\nfunction isInvalidHookAccessor(api: ReactDispatcher) {\n\tconst cached = invalidHookAccessors.get(api);\n\tif (cached !== undefined) return cached;\n\t// we only want the real implementation, not the warning ones\n\tconst invalid =\n\t\tapi.useCallback.length < 2 ||\n\t\t/warnInvalidHookAccess/.test(api.useCallback as any);\n\tinvalidHookAccessors.set(api, invalid);\n\treturn invalid;\n}\n\nexport function useSignal<T>(value: T) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(() => {\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n"],"names":["React","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","useMemo","useRef","useEffect","Signal","effect","signal","computed","batch","finishUpdate","createElement","type","props","i","v","value","apply","this","arguments","updaterForComponent","setCurrentUpdater","updater","_start","lastOwner","$$typeof","Object","defineProperties","prototype","configurable","_ref","data","get","ref","currentOwner","defineProperty","internals","ReactCurrentOwner","set","owner","currentDispatcher","UPDATE","ReactCurrentDispatcher","api","lock","cached","invalidHookAccessors","undefined","invalid","useCallback","length","test","isInvalidHookAccessor","rerender","useReducer","update","_callback","createUpdater","Map","useSignal","useComputed","compute","$compute","current","useSignalEffect","cb","callback"],"mappings":"OAyBAA,yDAAAC,aAAAC,YAAAC,eAAAC,MAAA,yBAAAC,YAAAC,YAAAC,cAAAC,MAAA,8BAAAH,OAAAI,MAAAD,SAAAF,OAAAC,WAAA,uBAAA,IA+BIG,EA/BeC,EAAGX,EAAMW,cAE5BX,EAAMW,cAAgB,SAAUC,EAAMC,GACrC,GAAoB,oBAAYA,EAC/B,IAAK,IAAIC,KAATD,EAAqB,CACpB,IAAKE,EAAGF,EAAMC,GACd,GAAU,aAANA,GAAoBC,aAAxBV,EAECQ,EAAMC,GAAKC,EAAEC,KAEd,CAGF,OAAOL,EAAcM,MAAMC,KAAMC,UACjC,EAkBD,IAAMC,EAAsB,YAE5B,SAAAC,EAA2BC,GAE1B,GAAIZ,EAAcA,IAElBA,EAAeY,GAAWA,EAAQC,GAClC,CAoBD,IAcAC,EAdcC,EAAGd,EAAc,KAAKc,SACpCC,OAAOC,iBAAiBtB,EAAOuB,UAAW,CACzCH,SAAU,CAAEI,cAAc,EAAMb,MAAOS,GACvCb,KAAM,CAAEiB,cAAc,EAAMb,MAT7B,SAAwCc,GACvC,OADuCA,EAAxBC,KACHf,KACZ,GAQAH,MAAO,CACNgB,cAAc,EACdG,IAFM,WAGL,MAAO,CAAED,KAAMb,KACf,GAEFe,IAAK,CAAEJ,cAAc,EAAMb,MAAO,QAKnC,IAAIkB,EAAkC,KACtCR,OAAOS,eAAeC,EAAUC,kBAAmB,UAAW,CAC7DL,IAAG,WACF,OAAOE,CACP,EACDI,IAAIC,SAAAA,GAEH,GADAL,EAAeK,EACGf,EAAYU,CAC9B,IAIF,IAEAM,KAFW,EACCC,EAAG,iBAAO,CAAP,CAAA,EAEff,OAAOS,eAAeC,EAAUM,uBAAwB,UAAW,CAClEV,eACC,OACAQ,CAAA,EACDF,IAAIK,SAAAA,GACHH,EAAoBG,EACpB,IAAIC,EACJ,GAAIpB,GAAamB,IAwBnB,SAA+BA,GAC9B,IAAYE,EAAGC,EAAqBd,IAAIW,GACxC,QAAeI,IAAXF,EAAsB,OAAOA,EAEjC,IAAaG,EACZL,EAAIM,YAAYC,OAAS,GACzB,wBAAwBC,KAAKR,EAAIM,aAClCH,EAAqBR,IAAIK,EAAKK,GAC9B,OAAOA,CACP,CAjC0BI,CAAsBT,GAAM,CAGpDC,GAAO,EACP,IAAcS,EAAGV,EAAIW,WAAWb,EAAQ,CAAvB,GAA2B,GAC5CG,GAAO,EAEP,IAAWtB,EAAGF,EAAoBY,IAAIR,GACtC,IAAKF,EAAS,CACbA,EAhEJ,SAAuBiC,GACtB,IAAAjC,EACAhB,EAAO,WACNgB,EAAUJ,IACV,GACDI,EAAQkC,EAAYD,EACpB,OAAOjC,CACP,CAyDamC,CAAcJ,GACxBjC,EAAoBkB,IAAId,EAAWF,EACnC,MACAA,EAAQkC,EAAYH,EAErBhC,EAAkBC,EAClB,MACAD,GAED,IAKF,IAA0ByB,EAAG,IAA7BY,IAYM,SAAAC,EAAuB3C,GAC5B,OAAOd,EAAQ,WAAA,OAAYK,EAAIS,EAAhB,EAAwB,GACvC,CAEe4C,SAAAA,EAAeC,GAC9B,IAAcC,EAAG3D,EAAO0D,GACxBC,EAASC,QAAUF,EACnB,OAAc3D,EAAC,WAAMM,OAAAA,EAAY,WAAA,OAAcsD,EAACC,SAAf,EAAlB,EAA6C,GAC5D,UAEKC,EAA0BC,GAC/B,IAAcC,EAAG/D,EAAO8D,GACxBC,EAASH,QAAUE,EAEnB7D,EAAU,WACT,OAAOE,EAAO,WACb,OAAO4D,EAASH,SAChB,EACD,EAAE,GACH,QAAAH,iBAAAD,eAAAK"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preact/signals-react",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "license": "MIT",
5
5
  "description": "",
6
6
  "keywords": [],
@@ -9,7 +9,8 @@
9
9
  ],
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/preactjs/signals"
12
+ "url": "https://github.com/preactjs/signals",
13
+ "directory": "packages/react"
13
14
  },
14
15
  "bugs": "https://github.com/preactjs/signals/issues",
15
16
  "homepage": "https://preactjs.com",
@@ -25,16 +26,16 @@
25
26
  "source": "src/index.ts",
26
27
  "exports": {
27
28
  ".": {
29
+ "types": "./dist/signals.d.ts",
28
30
  "browser": "./dist/signals.module.js",
29
31
  "umd": "./dist/signals.umd.js",
30
32
  "import": "./dist/signals.mjs",
31
- "require": "./dist/signals.js",
32
- "types": "./dist/signals.d.ts"
33
+ "require": "./dist/signals.js"
33
34
  }
34
35
  },
35
36
  "mangle": "../../mangle.json",
36
37
  "dependencies": {
37
- "@preact/signals-core": "^1.1.0"
38
+ "@preact/signals-core": "^1.2.0"
38
39
  },
39
40
  "peerDependencies": {
40
41
  "react": "17.x || 18.x"
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  useRef,
3
3
  useMemo,
4
+ useEffect,
4
5
  // @ts-ignore-next-line
5
6
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
7
  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as internals,
@@ -14,7 +15,7 @@ import {
14
15
  Signal,
15
16
  type ReadonlySignal,
16
17
  } from "@preact/signals-core";
17
- import { Updater, ReactOwner, ReactDispatcher } from "./internal";
18
+ import { Effect, ReactOwner, ReactDispatcher } from "./internal";
18
19
 
19
20
  export { signal, computed, batch, effect, Signal, type ReadonlySignal };
20
21
 
@@ -53,20 +54,23 @@ function createPropUpdater(props: any, prop: string, signal: Signal) {
53
54
  }
54
55
  */
55
56
 
56
- let finishUpdate: ReturnType<Updater["_setCurrent"]> | undefined;
57
- const updaterForComponent = new WeakMap<ReactOwner, Updater>();
57
+ let finishUpdate: (() => void) | undefined;
58
+ const updaterForComponent = new WeakMap<ReactOwner, Effect>();
58
59
 
59
- function setCurrentUpdater(updater?: Updater) {
60
+ function setCurrentUpdater(updater?: Effect) {
60
61
  // end tracking for the current update:
61
- if (finishUpdate) finishUpdate(true, true);
62
+ if (finishUpdate) finishUpdate();
62
63
  // start tracking the new update:
63
- finishUpdate = updater && updater._setCurrent();
64
+ finishUpdate = updater && updater._start();
64
65
  }
65
66
 
66
- function createUpdater(updater: () => void) {
67
- const s = signal(undefined) as Updater;
68
- s._updater = updater;
69
- return s;
67
+ function createUpdater(update: () => void) {
68
+ let updater!: Effect;
69
+ effect(function (this: Effect) {
70
+ updater = this;
71
+ });
72
+ updater._callback = update;
73
+ return updater;
70
74
  }
71
75
 
72
76
  /**
@@ -80,22 +84,29 @@ function Text({ data }: { data: Signal }) {
80
84
  //@ts-ignore-next-line
81
85
  const $$typeof = createElement("a").$$typeof;
82
86
  Object.defineProperties(Signal.prototype, {
83
- $$typeof: { value: $$typeof },
84
- type: { value: Text },
87
+ $$typeof: { configurable: true, value: $$typeof },
88
+ type: { configurable: true, value: Text },
85
89
  props: {
90
+ configurable: true,
86
91
  get() {
87
92
  return { data: this };
88
93
  },
89
94
  },
90
- ref: { value: null },
95
+ ref: { configurable: true, value: null },
91
96
  });
92
97
 
93
98
  // Track the current owner (roughly equiv to current vnode)
94
- // let currentOwner: ReactOwner;
95
- // Object.defineProperty(internals.ReactCurrentOwner, "current", {
96
- // get() { return currentOwner; },
97
- // set(owner) { currentOwner = owner; },
98
- // });
99
+ let lastOwner: ReactOwner | undefined;
100
+ let currentOwner: ReactOwner | null = null;
101
+ Object.defineProperty(internals.ReactCurrentOwner, "current", {
102
+ get() {
103
+ return currentOwner;
104
+ },
105
+ set(owner) {
106
+ currentOwner = owner;
107
+ if (currentOwner) lastOwner = currentOwner;
108
+ },
109
+ });
99
110
 
100
111
  // Track the current dispatcher (roughly equiv to current component impl)
101
112
  let lock = false;
@@ -108,17 +119,19 @@ Object.defineProperty(internals.ReactCurrentDispatcher, "current", {
108
119
  set(api) {
109
120
  currentDispatcher = api;
110
121
  if (lock) return;
111
- if (api && !isInvalidHookAccessor(api)) {
122
+ if (lastOwner && api && !isInvalidHookAccessor(api)) {
112
123
  // prevent re-injecting useReducer when the Dispatcher
113
124
  // context changes to run the reducer callback:
114
125
  lock = true;
115
126
  const rerender = api.useReducer(UPDATE, {})[1];
116
127
  lock = false;
117
- const currentOwner = internals.ReactCurrentOwner.current;
118
- let updater = updaterForComponent.get(currentOwner);
128
+
129
+ let updater = updaterForComponent.get(lastOwner);
119
130
  if (!updater) {
120
131
  updater = createUpdater(rerender);
121
- updaterForComponent.set(currentOwner, updater);
132
+ updaterForComponent.set(lastOwner, updater);
133
+ } else {
134
+ updater._callback = rerender;
122
135
  }
123
136
  setCurrentUpdater(updater);
124
137
  } else {
@@ -150,3 +163,14 @@ export function useComputed<T>(compute: () => T) {
150
163
  $compute.current = compute;
151
164
  return useMemo(() => computed<T>(() => $compute.current()), []);
152
165
  }
166
+
167
+ export function useSignalEffect(cb: () => void | (() => void)) {
168
+ const callback = useRef(cb);
169
+ callback.current = cb;
170
+
171
+ useEffect(() => {
172
+ return effect(() => {
173
+ return callback.current();
174
+ });
175
+ }, []);
176
+ }
package/src/internal.d.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  import { Signal } from "@preact/signals-core";
2
2
 
3
+ export interface Effect {
4
+ _sources: object | undefined;
5
+ _start(): () => void;
6
+ _callback(): void;
7
+ _dispose(): void;
8
+ }
9
+
3
10
  export interface ReactOwner {
4
11
  _: never;
5
12
  }
@@ -2,7 +2,7 @@
2
2
  globalThis.IS_REACT_ACT_ENVIRONMENT = true;
3
3
 
4
4
  import { signal, useComputed } from "@preact/signals-react";
5
- import { createElement, useMemo } from "react";
5
+ import { createElement, useMemo, memo, StrictMode } from "react";
6
6
  import { createRoot, Root } from "react-dom/client";
7
7
  import { act } from "react-dom/test-utils";
8
8
 
@@ -158,5 +158,26 @@ describe("@preact/signals-react", () => {
158
158
  });
159
159
  expect(scratch.textContent).to.equal("bar");
160
160
  });
161
+
162
+ it("should consistently rerender in strict mode", async () => {
163
+ const sig = signal<string>(null!);
164
+
165
+ const Test = memo(() => <p>{sig.value}</p>);
166
+ const App = () => (
167
+ <StrictMode>
168
+ <Test />
169
+ </StrictMode>
170
+ );
171
+
172
+ for (let i = 0; i < 3; i++) {
173
+ const value = `${i}`;
174
+
175
+ act(() => {
176
+ sig.value = value;
177
+ render(<App />);
178
+ });
179
+ expect(scratch.textContent).to.equal(value);
180
+ }
181
+ });
161
182
  });
162
183
  });