@preact/signals-react 1.0.0 → 1.0.2
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 +26 -0
- package/README.md +71 -0
- package/dist/signals.js +1 -1
- package/dist/signals.js.map +1 -1
- package/dist/signals.min.js +1 -1
- package/dist/signals.min.js.map +1 -1
- package/dist/signals.mjs +1 -1
- package/dist/signals.mjs.map +1 -1
- package/dist/signals.module.js +1 -1
- package/dist/signals.module.js.map +1 -1
- package/package.json +10 -6
- package/src/index.ts +21 -13
- package/test/{exports.test.ts → exports.test.tsx} +0 -0
- package/test/{index.test.ts → index.test.tsx} +37 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# @preact/signals-react
|
|
2
2
|
|
|
3
|
+
## 1.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#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.
|
|
8
|
+
|
|
9
|
+
* [#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.
|
|
10
|
+
|
|
11
|
+
- [#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
|
|
12
|
+
|
|
13
|
+
- 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)]:
|
|
14
|
+
- @preact/signals-core@1.1.1
|
|
15
|
+
|
|
16
|
+
## 1.0.1
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 62439c9: Fixes invalid React peer dependency range for environments with strict peerDeps
|
|
21
|
+
- Updated dependencies [336bb34]
|
|
22
|
+
- Updated dependencies [bc0080c]
|
|
23
|
+
- Updated dependencies [7228418]
|
|
24
|
+
- Updated dependencies [32abe07]
|
|
25
|
+
- Updated dependencies [4782b41]
|
|
26
|
+
- Updated dependencies [bf6af3b]
|
|
27
|
+
- @preact/signals-core@1.1.0
|
|
28
|
+
|
|
3
29
|
## 1.0.0
|
|
4
30
|
|
|
5
31
|
### Major Changes
|
package/README.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
# Signals
|
|
3
|
+
|
|
4
|
+
Signals is a performant state management library with two primary goals:
|
|
5
|
+
|
|
6
|
+
1. Make it as easy as possible to write business logic for small up to complex apps. No matter how complex your logic is, your app updates should stay fast without you needing to think about it. Signals automatically optimize state updates behind the scenes to trigger the fewest updates necessary. They are lazy by default and automatically skip signals that no one listens to.
|
|
7
|
+
2. Integrate into frameworks as if they were native built-in primitives. You don't need any selectors, wrapper functions, or anything else. Signals can be accessed directly and your component will automatically re-render when the signal's value changes.
|
|
8
|
+
|
|
9
|
+
Read the [announcement post](https://preactjs.com/blog/introducing-signals/) to learn more about which problems signals solves and how it came to be.
|
|
10
|
+
|
|
11
|
+
## Installation:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install @preact/signals-react
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- [Guide / API](../../README.md#guide--api)
|
|
18
|
+
- [`signal(initialValue)`](../../README.md#signalinitialvalue)
|
|
19
|
+
- [`signal.peek()`](../../README.md#signalpeek)
|
|
20
|
+
- [`computed(fn)`](../../README.md#computedfn)
|
|
21
|
+
- [`effect(fn)`](../../README.md#effectfn)
|
|
22
|
+
- [`batch(fn)`](../../README.md#batchfn)
|
|
23
|
+
- [React Integration](#react-integration)
|
|
24
|
+
- [Hooks](#hooks)
|
|
25
|
+
- [License](#license)
|
|
26
|
+
|
|
27
|
+
## React Integration
|
|
28
|
+
|
|
29
|
+
The React integration can be installed via:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm install @preact/signals-react
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Similar to the Preact integration, the React adapter allows you to access signals directly inside your components and will automatically subscribe to them.
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
import { signal } from "@preact/signals-react";
|
|
39
|
+
|
|
40
|
+
const count = signal(0);
|
|
41
|
+
|
|
42
|
+
function CounterValue() {
|
|
43
|
+
// Whenver the `count` signal is updated, we'll
|
|
44
|
+
// re-render this component automatically for you
|
|
45
|
+
return <p>Value: {count.value}</p>;
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Hooks
|
|
50
|
+
|
|
51
|
+
If you need to instantiate new signals inside your components, you can use the `useSignal` or `useComputed` hook.
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
import { useSignal, useComputed } from "@preact/signals-react";
|
|
55
|
+
|
|
56
|
+
function Counter() {
|
|
57
|
+
const count = useSignal(0);
|
|
58
|
+
const double = useComputed(() => count.value * 2);
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<button onClick={() => count.value++}>
|
|
62
|
+
Value: {count.value}, value x 2 = {double.value}
|
|
63
|
+
</button>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
`MIT`, see the [LICENSE](../../LICENSE) file.
|
|
71
|
+
|
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.
|
|
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,v=o("a").$$typeof;Object.defineProperties(n.Signal.prototype,{$$typeof:{configurable:!0,value:v},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){(s=r)&&(f=s)}});var l,p=!1,g=function(){return{}};Object.defineProperty(r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher,"current",{get:function(){return l},set:function(r){if(l=r,!p)if(f&&r&&!x(r)){p=!0;var n=r.useReducer(g,{})[1];p=!1;var t=i.get(f);t?t._u=n:(t=c(n),i.set(f,t)),a(t)}else a()}});var b=new Map;function x(r){var n=b.get(r);if(void 0!==n)return n;var t=r.useCallback.length<2||/warnInvalidHookAccess/.test(r.useCallback);return b.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
|
package/dist/signals.js.map
CHANGED
|
@@ -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.
|
|
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: { 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._updater = 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"],"names":["React","require","signalsCore","_interopDefaultLegacy","e","default","finishUpdate","React__default","createElement","type","props","i","v","Signal","value","apply","this","arguments","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","signal","undefined","_updater","lastOwner","$$typeof","Object","defineProperties","prototype","configurable","_ref","data","get","ref","currentOwner","defineProperty","internals","ReactCurrentOwner","set","owner","currentDispatcher","lock","ReactCurrentDispatcher","api","isInvalidHookAccessor","rerender","useReducer","UPDATE","updaterForComponent","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","exports","batch","computed","effect","useComputed","compute","$compute","useRef","current","useMemo","useSignal"],"mappings":"AAwBA,IAAAA,EAAAC,QAAA,SAAAC,EAAAD,QAAA,wBAAA,SAAAE,EAAAC,GAAA,OAAAA,GAAA,iBAAAA,GAAA,YAAAA,EAAAA,EAAAC,QAAAD,CAAA,CAAA,IA+BIE,EA/BJC,eAAAJ,EAAAH,GAAmBQ,EAAGR,EAAMQ,cAE5BR,EAAMQ,cAAgB,SAAUC,EAAMC,GACrC,GAAoB,iBAAhBD,GAA4BC,EAC/B,IAAK,IAALC,KAAAD,EAAqB,CACpB,IAAKE,EAAGF,EAAMC,GACJ,aAANA,GAAoBC,aAAaC,EAArCA,SAECH,EAAMC,GAAKC,EAAEE,MAEd,CAGF,OAAoBN,EAACO,MAAMC,KAAMC,UACjC,EAkBD,MAA4B,IAA5BC,QAEA,SAASC,EAAkBC,GAEtBd,GAAcA,GAAa,GAAM,GAErCA,EAAec,GAAWA,EAAQC,GAClC,CAED,SAAAC,EAAuBF,GACtB,IAAMG,EAAIC,EAAMA,YAACC,GAEjB,OADAF,EAAEG,GAAWN,EACNG,CACP,CAWD,IAcAI,EAdcC,EAAGpB,EAAc,KAAKoB,SACpCC,OAAOC,iBAAiBjB,EAAAA,OAAOkB,UAAW,CACzCH,SAAU,CAAEI,cAAc,EAAMlB,MAAOc,GACvCnB,KAAM,CAAEuB,cAAc,EAAMlB,MAT7B,SAAwCmB,GACvC,OADuCA,EAAxBC,KACHpB,KACZ,GAQAJ,MAAO,CACNsB,cAAc,EACdG,IAFM,WAGL,MAAO,CAAED,KAAMlB,KACf,GAEFoB,IAAK,CAAEJ,cAAc,EAAMlB,MAAO,QAKnC,IAAIuB,EAAkC,KACtCR,OAAOS,eAAeC,EAAAA,mDAAUC,kBAAmB,UAAW,CAC7DL,IAD6D,WAE5D,OACAE,CAAA,EACDI,IAAIC,SAAAA,IACHL,EAAeK,KACGf,EAAYU,EAC9B,IAIF,IAEAM,EAFIC,GAAO,IACI,WAAA,MAAO,CAAA,CAAP,EAEff,OAAOS,eAAeC,EAAAA,mDAAUM,uBAAwB,UAAW,CAClEV,IADkE,WAEjE,QACA,EACDM,IAJkE,SAI9DK,GAEH,GADAH,EAAoBG,GAChBF,EACJ,GAAIjB,GAAamB,IAAQC,EAAsBD,GAAM,CAGpDF,GAAO,EACP,IAAcI,EAAGF,EAAIG,WAAWC,EAAQ,CAAA,GAAI,GAC5CN,GAAO,EAEP,IAAWxB,EAAG+B,EAAoBhB,IAAIR,GACjCP,EAIJA,EAAQM,GAAWsB,GAHnB5B,EAAUE,EAAc0B,GACxBG,EAAoBV,IAAId,EAAWP,IAIpCD,EAAkBC,EAClB,MACAD,GAED,IAKF,IAA0BiC,EAAG,IAAIC,IACjC,SAAAN,EAA+BD,GAC9B,IAAMQ,EAASF,EAAqBjB,IAAIW,GACxC,QAAerB,IAAX6B,EAAsB,SAE1B,IAAaC,EACZT,EAAIU,YAAYC,OAAS,GACzB,wBAAwBC,KAAKZ,EAAIU,aAElC,OADAJ,EAAqBX,IAAIK,EAAKS,GACvBA,CACP,CAUAI,QAAA9C,OAAAX,EAAAW,OAAA8C,QAAAC,MAAA1D,EAAA0D,MAAAD,QAAAE,SAAA3D,EAAA2D,SAAAF,QAAAG,OAAA5D,EAAA4D,OAAAH,QAAAnC,OAAAtB,EAAAsB,OAAAmC,QAAAI,qBAJ8BC,GAC9B,IAAcC,EAAGC,EAAMA,OAACF,GAExB,OADAC,EAASE,QAAUH,EACZI,UAAQ,WAAA,OAAcP,EAAAA,SAAI,kBAAcI,EAACE,SAAf,EAAlB,EAA6C,GAC5D,EAAAR,QAAAU,UAReA,SAAavD,GAC5B,OAAcsD,EAAAA,QAAC,WAAM5C,OAAAA,EAAAA,OAAUV,EAAhB,EAAwB,GACvC"}
|
package/dist/signals.min.js
CHANGED
|
@@ -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
|
|
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 u,i=/*#__PURE__*/t(e),o=i.createElement;i.createElement=function(n,e){if("string"==typeof n&&e)for(var t in e){var u=e[t];"children"!==t&&u instanceof r.Signal&&(e[t]=u.value)}return o.apply(this,arguments)};var f=new WeakMap;function c(n){u&&u(!0,!0),u=n&&n._()}function a(n){var e=r.signal(void 0);return e._u=n,e}var l,s=o("a").$$typeof;Object.defineProperties(r.Signal.prototype,{$$typeof:{configurable:!0,value:s},type:{configurable:!0,value:function(n){return n.data.value}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});var v=null;Object.defineProperty(e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,"current",{get:function(){return v},set:function(n){(v=n)&&(l=v)}});var p,d=!1,g=function(){return{}};Object.defineProperty(e.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentDispatcher,"current",{get:function(){return p},set:function(n){if(p=n,!d)if(l&&n&&!y(n)){d=!0;var e=n.useReducer(g,{})[1];d=!1;var r=f.get(l);r?r._u=e:(r=a(e),f.set(l,r)),c(r)}else c()}});var b=new Map;function y(n){var e=b.get(n);if(void 0!==e)return e;var r=n.useCallback.length<2||/warnInvalidHookAccess/.test(n.useCallback);return b.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
|
package/dist/signals.min.js.map
CHANGED
|
@@ -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.
|
|
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: { 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._updater = 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"],"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","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","signal","undefined","_updater","lastOwner","$$typeof","Object","defineProperties","prototype","configurable","_ref","data","get","ref","currentOwner","defineProperty","internals","ReactCurrentOwner","set","owner","currentDispatcher","lock","ReactCurrentDispatcher","api","isInvalidHookAccessor","rerender","useReducer","UPDATE","updaterForComponent","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","batch","computed","effect","useComputed","compute","$compute","useRef","current","useMemo","useSignal"],"mappings":"CAwBA,SAAAA,EAAAC,GAAA,iBAAAC,SAAA,oBAAAC,OAAAF,EAAAC,QAAAE,QAAA,SAAAA,QAAA,yBAAA,mBAAAC,QAAAA,OAAAC,IAAAD,OAAA,CAAA,UAAA,QAAA,wBAAAJ,GAAAA,GAAAD,EAAA,oBAAAO,WAAAA,WAAAP,GAAAQ,MAAAC,aAAA,CAAA,EAAAT,EAAAU,MAAAV,EAAAW,YAAA,CAAA,CAAAC,KAAA,SAAAV,EAAAW,EAAAF,GAAA,SAAAG,EAAAC,GAAA,OAAAA,GAAA,iBAAAA,GAAA,YAAAA,EAAAA,EAAAC,QAAAD,CAAA,CAAA,IA+BIE,EA/BJC,eAAAJ,EAAAD,GAAmBM,EAAGN,EAAMM,cAE5BN,EAAMM,cAAgB,SAAUC,EAAMC,GACrC,GAAoB,iBAAhBD,GAA4BC,EAC/B,IAAK,IAALC,KAAAD,EAAqB,CACpB,IAAKE,EAAGF,EAAMC,GACJ,aAANA,GAAoBC,aAAaC,EAArCA,SAECH,EAAMC,GAAKC,EAAEE,MAEd,CAGF,OAAoBN,EAACO,MAAMd,KAAMe,UACjC,EAkBD,MAA4B,IAA5BC,QAEA,SAASC,EAAkBC,GAEtBb,GAAcA,GAAa,GAAM,GAErCA,EAAea,GAAWA,EAAQC,GAClC,CAED,SAAAC,EAAuBF,GACtB,IAAMG,EAAIC,EAAMA,YAACC,GAEjB,OADAF,EAAEG,GAAWN,EACNG,CACP,CAWD,IAcAI,EAdcC,EAAGnB,EAAc,KAAKmB,SACpCC,OAAOC,iBAAiBhB,EAAAA,OAAOiB,UAAW,CACzCH,SAAU,CAAEI,cAAc,EAAMjB,MAAOa,GACvClB,KAAM,CAAEsB,cAAc,EAAMjB,MAT7B,SAAwCkB,GACvC,OADuCA,EAAxBC,KACHnB,KACZ,GAQAJ,MAAO,CACNqB,cAAc,EACdG,IAFM,WAGL,MAAO,CAAED,KAAMhC,KACf,GAEFkC,IAAK,CAAEJ,cAAc,EAAMjB,MAAO,QAKnC,IAAIsB,EAAkC,KACtCR,OAAOS,eAAeC,EAAAA,mDAAUC,kBAAmB,UAAW,CAC7DL,IAD6D,WAE5D,OACAE,CAAA,EACDI,IAAIC,SAAAA,IACHL,EAAeK,KACGf,EAAYU,EAC9B,IAIF,IAEAM,EAFIC,GAAO,IACI,WAAA,MAAO,CAAA,CAAP,EAEff,OAAOS,eAAeC,EAAAA,mDAAUM,uBAAwB,UAAW,CAClEV,IADkE,WAEjE,QACA,EACDM,IAJkE,SAI9DK,GAEH,GADAH,EAAoBG,GAChBF,EACJ,GAAIjB,GAAamB,IAAQC,EAAsBD,GAAM,CAGpDF,GAAO,EACP,IAAcI,EAAGF,EAAIG,WAAWC,EAAQ,CAAA,GAAI,GAC5CN,GAAO,EAEP,IAAWxB,EAAG+B,EAAoBhB,IAAIR,GACjCP,EAIJA,EAAQM,GAAWsB,GAHnB5B,EAAUE,EAAc0B,GACxBG,EAAoBV,IAAId,EAAWP,IAIpCD,EAAkBC,EAClB,MACAD,GAED,IAKF,IAA0BiC,EAAG,IAAIC,IACjC,SAAAN,EAA+BD,GAC9B,IAAMQ,EAASF,EAAqBjB,IAAIW,GACxC,QAAerB,IAAX6B,EAAsB,SAE1B,IAAaC,EACZT,EAAIU,YAAYC,OAAS,GACzB,wBAAwBC,KAAKZ,EAAIU,aAElC,OADAJ,EAAqBX,IAAIK,EAAKS,GACvBA,CACP,CAUA/D,EAAAsB,OAAAb,EAAAa,OAAAtB,EAAAmE,MAAA1D,EAAA0D,MAAAnE,EAAAoE,SAAA3D,EAAA2D,SAAApE,EAAAqE,OAAA5D,EAAA4D,OAAArE,EAAAgC,OAAAvB,EAAAuB,OAAAhC,EAAAsE,qBAJ8BC,GAC9B,IAAcC,EAAGC,EAAMA,OAACF,GAExB,OADAC,EAASE,QAAUH,EACZI,UAAQ,WAAA,OAAcP,EAAAA,SAAI,kBAAcI,EAACE,SAAf,EAAlB,EAA6C,GAC5D,EAAA1E,EAAA4E,UAReA,SAAarD,GAC5B,OAAcoD,EAAAA,QAAC,WAAM3C,OAAAA,EAAAA,OAAUT,EAAhB,EAAwB,GACvC,CAMA"}
|
package/dist/signals.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import t,{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as
|
|
1
|
+
import t,{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as e,useMemo as n,useRef as r}from"react";import{Signal as o,signal as c,computed as i}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";const u=t.createElement;let a;t.createElement=function(t,e){if("string"==typeof t&&e)for(let t in e){let n=e[t];"children"!==t&&n instanceof o&&(e[t]=n.value)}return u.apply(this,arguments)};const l=new WeakMap;function f(t){a&&a(!0,!0),a=t&&t._()}function s(t){const e=c(void 0);return e._u=t,e}const p=u("a").$$typeof;let g;Object.defineProperties(o.prototype,{$$typeof:{configurable:!0,value:p},type:{configurable:!0,value:function({data:t}){return t.value}},props:{configurable:!0,get(){return{data:this}}},ref:{configurable:!0,value:null}});let b=null;Object.defineProperty(e.ReactCurrentOwner,"current",{get:()=>b,set(t){b=t,b&&(g=b)}});let d=!1;const m=()=>({});let v;Object.defineProperty(e.ReactCurrentDispatcher,"current",{get:()=>v,set(t){if(v=t,!d)if(g&&t&&!j(t)){d=!0;const e=t.useReducer(m,{})[1];d=!1;let n=l.get(g);n?n._u=e:(n=s(e),l.set(g,n)),f(n)}else f()}});const h=new Map;function j(t){const e=h.get(t);if(void 0!==e)return e;const n=t.useCallback.length<2||/warnInvalidHookAccess/.test(t.useCallback);return h.set(t,n),n}function w(t){return n(()=>c(t),[])}function y(t){const e=r(t);return e.current=t,n(()=>i(()=>e.current()),[])}export{y as useComputed,w as useSignal};//# sourceMappingURL=signals.mjs.map
|
package/dist/signals.mjs.map
CHANGED
|
@@ -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.
|
|
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: { 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._updater = 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"],"names":["React","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","useMemo","useRef","Signal","signal","computed","batch","effect","createElement","finishUpdate","type","props","i","v","value","apply","this","arguments","updaterForComponent","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","undefined","_updater","$$typeof","lastOwner","Object","defineProperties","prototype","configurable","data","get","ref","defineProperty","internals","ReactCurrentOwner","currentOwner","set","owner","lock","UPDATE","currentDispatcher","ReactCurrentDispatcher","api","isInvalidHookAccessor","rerender","useReducer","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","useSignal","useComputed","compute","$compute","current"],"mappings":"OAwBAA,yDAAAC,aAAAC,YAAAC,MAAA,yBAAAC,YAAAC,cAAAC,MAAA,8BAAAF,OAAAG,MAAAD,SAAAE,OAAAH,WAAA,uBAAA,MAAmBI,EAAGT,EAAMS,cA+B5B,IAAIC,EA7BJV,EAAMS,cAAgB,SAAUE,EAAMC,GACrC,GAAoB,iBAATD,GAAqBC,EAC/B,IAAK,IAAIC,KAAKD,EAAO,CACpB,IAAIE,EAAIF,EAAMC,GACJ,aAANA,GAAoBC,aAAxBV,IAECQ,EAAMC,GAAKC,EAAEC,MAEd,CAGF,OAAoBN,EAACO,MAAMC,KAAMC,UACjC,EAkBD,MAAMC,EAAsB,IAA5BC,QAEA,SAASC,EAAkBC,GAEtBZ,GAAcA,GAAa,GAAM,GAErCA,EAAeY,GAAWA,EAAQC,GAClC,CAED,SAAAC,EAAuBF,GACtB,MAAMG,EAAIpB,OAAOqB,GAEjB,OADAD,EAAEE,GAAWL,EAEbG,CAAA,CAWD,QAAiBhB,EAAc,KAAKmB,SAcpC,IAAIC,EAbJC,OAAOC,iBAAiB3B,EAAO4B,UAAW,CACzCJ,SAAU,CAAEK,cAAc,EAAMlB,MAAOa,GACvCjB,KAAM,CAAEsB,cAAc,EAAMlB,MAT7B,UAAcmB,KAAEA,IACf,OAAOA,EAAKnB,KACZ,GAQAH,MAAO,CACNqB,cAAc,EACdE,MACC,MAAO,CAAED,KAAMjB,KACf,GAEFmB,IAAK,CAAEH,cAAc,EAAMlB,MAAO,QAKnC,MAAsC,KACtCe,OAAOO,eAAeC,EAAUC,kBAAmB,UAAW,CAC7DJ,IAAG,IACKK,EAERC,IAAIC,GACHF,EAAeE,EACXF,IAAcX,EAAYW,EAC9B,IAIF,IAAQG,GAAG,EACX,MAAYC,EAAG,KAAO,CAAP,GACf,IAAIC,EACJf,OAAOO,eAAeC,EAAUQ,uBAAwB,UAAW,CAClEX,IAAG,IAEFU,EACDJ,IAAIM,GAEH,GADAF,EAAoBE,GAChBJ,EACJ,GAAId,GAAakB,IAAQC,EAAsBD,GAAM,CAGpDJ,GAAO,EACP,MAAMM,EAAWF,EAAIG,WAAWN,EAAQ,CAAA,GAAI,GAC5CD,GAAO,EAEP,IAAWrB,EAAGH,EAAoBgB,IAAIN,GACjCP,EAIJA,EAAQK,GAAWsB,GAHnB3B,EAAUE,EAAcyB,GACxB9B,EAAoBsB,IAAIZ,EAAWP,IAIpCD,EAAkBC,EAClB,MACAD,GAED,IAKF,MAA0B8B,EAAG,IAAIC,IACjC,SAAAJ,EAA+BD,GAC9B,MAAMM,EAASF,EAAqBhB,IAAIY,GACxC,QAAerB,IAAX2B,EAAsB,OAAOA,EAEjC,MAAaC,EACZP,EAAIQ,YAAYC,OAAS,GACzB,wBAAwBC,KAAKV,EAAIQ,aAElC,OADAJ,EAAqBV,IAAIM,EAAKO,GACvBA,CACP,UAEKI,EAAuB3C,GAC5B,OAAcb,EAAC,IAAMG,EAAUU,GAAQ,GACvC,CAEK,SAAA4C,EAAyBC,GAC9B,MAAcC,EAAG1D,EAAOyD,GAExB,OADAC,EAASC,QAAUF,EACZ1D,EAAQ,IAAMI,EAAY,IAAMuD,EAASC,WAAY,GAC5D,QAAAH,iBAAAD"}
|
package/dist/signals.module.js
CHANGED
|
@@ -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
|
|
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 u,signal as i,computed as o}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";var a,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 u&&(n[t]=e.value)}return c.apply(this,arguments)};var f=new WeakMap;function v(r){a&&a(!0,!0),a=r&&r._()}function l(r){var n=i(void 0);return n._u=r,n}var s,p=c("a").$$typeof;Object.defineProperties(u.prototype,{$$typeof:{configurable:!0,value:p},type:{configurable:!0,value:function(r){return r.data.value}},props:{configurable:!0,get:function(){return{data:this}}},ref:{configurable:!0,value:null}});var g=null;Object.defineProperty(n.ReactCurrentOwner,"current",{get:function(){return g},set:function(r){(g=r)&&(s=g)}});var b,d=!1,m=function(){return{}};Object.defineProperty(n.ReactCurrentDispatcher,"current",{get:function(){return b},set:function(r){if(b=r,!d)if(s&&r&&!j(r)){d=!0;var n=r.useReducer(m,{})[1];d=!1;var t=f.get(s);t?t._u=n:(t=l(n),f.set(s,t)),v(t)}else v()}});var h=new Map;function j(r){var n=h.get(r);if(void 0!==n)return n;var t=r.useCallback.length<2||/warnInvalidHookAccess/.test(r.useCallback);return h.set(r,t),t}function w(r){return t(function(){return i(r)},[])}function y(r){var n=e(r);return n.current=r,t(function(){return o(function(){return n.current()})},[])}export{y as useComputed,w as useSignal};//# 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.
|
|
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: { 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._updater = 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"],"names":["React","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","useMemo","useRef","Signal","signal","computed","batch","effect","finishUpdate","createElement","type","props","i","v","value","apply","this","arguments","WeakMap","setCurrentUpdater","updater","_setCurrent","createUpdater","s","undefined","_updater","lastOwner","$$typeof","Object","defineProperties","prototype","configurable","_ref","data","get","ref","currentOwner","defineProperty","internals","ReactCurrentOwner","set","owner","currentDispatcher","lock","ReactCurrentDispatcher","api","isInvalidHookAccessor","rerender","useReducer","UPDATE","updaterForComponent","invalidHookAccessors","Map","cached","invalid","useCallback","length","test","useSignal","useComputed","compute","$compute","current"],"mappings":"OAwBAA,yDAAAC,aAAAC,YAAAC,MAAA,yBAAAC,YAAAC,cAAAC,MAAA,8BAAAF,OAAAG,MAAAD,SAAAE,OAAAH,WAAA,uBAAA,IA+BII,EA/BeC,EAAGV,EAAMU,cAE5BV,EAAMU,cAAgB,SAAUC,EAAMC,GACrC,GAAoB,iBAAhBD,GAA4BC,EAC/B,IAAK,IAALC,KAAAD,EAAqB,CACpB,IAAKE,EAAGF,EAAMC,GACJ,aAANA,GAAoBC,aAAaV,IAEpCQ,EAAMC,GAAKC,EAAEC,MAEd,CAGF,OAAoBL,EAACM,MAAMC,KAAMC,UACjC,EAkBD,MAA4B,IAA5BC,QAEA,SAASC,EAAkBC,GAEtBZ,GAAcA,GAAa,GAAM,GAErCA,EAAeY,GAAWA,EAAQC,GAClC,CAED,SAAAC,EAAuBF,GACtB,IAAMG,EAAInB,OAAOoB,GAEjB,OADAD,EAAEE,GAAWL,EACNG,CACP,CAWD,IAcAG,EAdcC,EAAGlB,EAAc,KAAKkB,SACpCC,OAAOC,iBAAiB1B,EAAO2B,UAAW,CACzCH,SAAU,CAAEI,cAAc,EAAMjB,MAAOa,GACvCjB,KAAM,CAAEqB,cAAc,EAAMjB,MAT7B,SAAwCkB,GACvC,OADuCA,EAAxBC,KACHnB,KACZ,GAQAH,MAAO,CACNoB,cAAc,EACdG,IAFM,WAGL,MAAO,CAAED,KAAMjB,KACf,GAEFmB,IAAK,CAAEJ,cAAc,EAAMjB,MAAO,QAKnC,IAAIsB,EAAkC,KACtCR,OAAOS,eAAeC,EAAUC,kBAAmB,UAAW,CAC7DL,IAD6D,WAE5D,OACAE,CAAA,EACDI,IAAIC,SAAAA,IACHL,EAAeK,KACGf,EAAYU,EAC9B,IAIF,IAEAM,EAFIC,GAAO,IACI,WAAA,MAAO,CAAA,CAAP,EAEff,OAAOS,eAAeC,EAAUM,uBAAwB,UAAW,CAClEV,IADkE,WAEjE,QACA,EACDM,IAJkE,SAI9DK,GAEH,GADAH,EAAoBG,GAChBF,EACJ,GAAIjB,GAAamB,IAAQC,EAAsBD,GAAM,CAGpDF,GAAO,EACP,IAAcI,EAAGF,EAAIG,WAAWC,EAAQ,CAAA,GAAI,GAC5CN,GAAO,EAEP,IAAWvB,EAAG8B,EAAoBhB,IAAIR,GACjCN,EAIJA,EAAQK,GAAWsB,GAHnB3B,EAAUE,EAAcyB,GACxBG,EAAoBV,IAAId,EAAWN,IAIpCD,EAAkBC,EAClB,MACAD,GAED,IAKF,IAA0BgC,EAAG,IAAIC,IACjC,SAAAN,EAA+BD,GAC9B,IAAMQ,EAASF,EAAqBjB,IAAIW,GACxC,QAAerB,IAAX6B,EAAsB,SAE1B,IAAaC,EACZT,EAAIU,YAAYC,OAAS,GACzB,wBAAwBC,KAAKZ,EAAIU,aAElC,OADAJ,EAAqBX,IAAIK,EAAKS,GACvBA,CACP,CAEeI,SAAAA,EAAa5C,GAC5B,OAAcb,EAAC,WAAMG,OAAAA,EAAUU,EAAhB,EAAwB,GACvC,UAEK6C,EAAyBC,GAC9B,IAAcC,EAAG3D,EAAO0D,GAExB,OADAC,EAASC,QAAUF,EACZ3D,EAAQ,WAAA,OAAcI,EAAI,kBAAcwD,EAACC,SAAf,EAAlB,EAA6C,GAC5D,QAAAH,iBAAAD"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@preact/signals-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "",
|
|
6
6
|
"keywords": [],
|
|
7
7
|
"authors": [
|
|
8
8
|
"The Preact Authors (https://github.com/preactjs/signals/contributors)"
|
|
9
9
|
],
|
|
10
|
-
"repository":
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/preactjs/signals",
|
|
13
|
+
"directory": "packages/react"
|
|
14
|
+
},
|
|
11
15
|
"bugs": "https://github.com/preactjs/signals/issues",
|
|
12
16
|
"homepage": "https://preactjs.com",
|
|
13
17
|
"funding": {
|
|
@@ -22,19 +26,19 @@
|
|
|
22
26
|
"source": "src/index.ts",
|
|
23
27
|
"exports": {
|
|
24
28
|
".": {
|
|
29
|
+
"types": "./dist/signals.d.ts",
|
|
25
30
|
"browser": "./dist/signals.module.js",
|
|
26
31
|
"umd": "./dist/signals.umd.js",
|
|
27
32
|
"import": "./dist/signals.mjs",
|
|
28
|
-
"require": "./dist/signals.js"
|
|
29
|
-
"types": "./dist/signals.d.ts"
|
|
33
|
+
"require": "./dist/signals.js"
|
|
30
34
|
}
|
|
31
35
|
},
|
|
32
36
|
"mangle": "../../mangle.json",
|
|
33
37
|
"dependencies": {
|
|
34
|
-
"@preact/signals-core": "^1.
|
|
38
|
+
"@preact/signals-core": "^1.1.1"
|
|
35
39
|
},
|
|
36
40
|
"peerDependencies": {
|
|
37
|
-
"react": "17.x
|
|
41
|
+
"react": "17.x || 18.x"
|
|
38
42
|
},
|
|
39
43
|
"devDependencies": {
|
|
40
44
|
"react": "^18.2.0",
|
package/src/index.ts
CHANGED
|
@@ -65,7 +65,6 @@ function setCurrentUpdater(updater?: Updater) {
|
|
|
65
65
|
|
|
66
66
|
function createUpdater(updater: () => void) {
|
|
67
67
|
const s = signal(undefined) as Updater;
|
|
68
|
-
s._canActivate = true;
|
|
69
68
|
s._updater = updater;
|
|
70
69
|
return s;
|
|
71
70
|
}
|
|
@@ -81,22 +80,29 @@ function Text({ data }: { data: Signal }) {
|
|
|
81
80
|
//@ts-ignore-next-line
|
|
82
81
|
const $$typeof = createElement("a").$$typeof;
|
|
83
82
|
Object.defineProperties(Signal.prototype, {
|
|
84
|
-
$$typeof: { value: $$typeof },
|
|
85
|
-
type: { value: Text },
|
|
83
|
+
$$typeof: { configurable: true, value: $$typeof },
|
|
84
|
+
type: { configurable: true, value: Text },
|
|
86
85
|
props: {
|
|
86
|
+
configurable: true,
|
|
87
87
|
get() {
|
|
88
88
|
return { data: this };
|
|
89
89
|
},
|
|
90
90
|
},
|
|
91
|
-
ref: { value: null },
|
|
91
|
+
ref: { configurable: true, value: null },
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
// Track the current owner (roughly equiv to current vnode)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
let lastOwner: ReactOwner | undefined;
|
|
96
|
+
let currentOwner: ReactOwner | null = null;
|
|
97
|
+
Object.defineProperty(internals.ReactCurrentOwner, "current", {
|
|
98
|
+
get() {
|
|
99
|
+
return currentOwner;
|
|
100
|
+
},
|
|
101
|
+
set(owner) {
|
|
102
|
+
currentOwner = owner;
|
|
103
|
+
if (currentOwner) lastOwner = currentOwner;
|
|
104
|
+
},
|
|
105
|
+
});
|
|
100
106
|
|
|
101
107
|
// Track the current dispatcher (roughly equiv to current component impl)
|
|
102
108
|
let lock = false;
|
|
@@ -109,17 +115,19 @@ Object.defineProperty(internals.ReactCurrentDispatcher, "current", {
|
|
|
109
115
|
set(api) {
|
|
110
116
|
currentDispatcher = api;
|
|
111
117
|
if (lock) return;
|
|
112
|
-
if (api && !isInvalidHookAccessor(api)) {
|
|
118
|
+
if (lastOwner && api && !isInvalidHookAccessor(api)) {
|
|
113
119
|
// prevent re-injecting useReducer when the Dispatcher
|
|
114
120
|
// context changes to run the reducer callback:
|
|
115
121
|
lock = true;
|
|
116
122
|
const rerender = api.useReducer(UPDATE, {})[1];
|
|
117
123
|
lock = false;
|
|
118
|
-
|
|
119
|
-
let updater = updaterForComponent.get(
|
|
124
|
+
|
|
125
|
+
let updater = updaterForComponent.get(lastOwner);
|
|
120
126
|
if (!updater) {
|
|
121
127
|
updater = createUpdater(rerender);
|
|
122
|
-
updaterForComponent.set(
|
|
128
|
+
updaterForComponent.set(lastOwner, updater);
|
|
129
|
+
} else {
|
|
130
|
+
updater._updater = rerender;
|
|
123
131
|
}
|
|
124
132
|
setCurrentUpdater(updater);
|
|
125
133
|
} else {
|
|
File without changes
|
|
@@ -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
|
|
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
|
|
|
@@ -24,7 +24,7 @@ describe("@preact/signals-react", () => {
|
|
|
24
24
|
|
|
25
25
|
describe("Text bindings", () => {
|
|
26
26
|
it("should render text without signals", () => {
|
|
27
|
-
render(
|
|
27
|
+
render(<span>test</span>);
|
|
28
28
|
const span = scratch.firstChild;
|
|
29
29
|
const text = span?.firstChild;
|
|
30
30
|
expect(text).to.have.property("data", "test");
|
|
@@ -32,7 +32,7 @@ describe("@preact/signals-react", () => {
|
|
|
32
32
|
|
|
33
33
|
it("should render Signals as Text", () => {
|
|
34
34
|
const sig = signal("test");
|
|
35
|
-
render(
|
|
35
|
+
render(<span>{sig}</span>);
|
|
36
36
|
const span = scratch.firstChild;
|
|
37
37
|
expect(span).to.have.property("firstChild").that.is.an.instanceOf(Text);
|
|
38
38
|
const text = span?.firstChild;
|
|
@@ -41,7 +41,7 @@ describe("@preact/signals-react", () => {
|
|
|
41
41
|
|
|
42
42
|
it("should update Signal-based Text (no parent component)", () => {
|
|
43
43
|
const sig = signal("test");
|
|
44
|
-
render(
|
|
44
|
+
render(<span>{sig}</span>);
|
|
45
45
|
|
|
46
46
|
const text = scratch.firstChild!.firstChild!;
|
|
47
47
|
expect(text).to.have.property("data", "test");
|
|
@@ -59,9 +59,9 @@ describe("@preact/signals-react", () => {
|
|
|
59
59
|
it("should update Signal-based Text (in a parent component)", () => {
|
|
60
60
|
const sig = signal("test");
|
|
61
61
|
function App({ x }: { x: typeof sig }) {
|
|
62
|
-
return
|
|
62
|
+
return <span>{x}</span>;
|
|
63
63
|
}
|
|
64
|
-
render(
|
|
64
|
+
render(<App x={sig} />);
|
|
65
65
|
|
|
66
66
|
const text = scratch.firstChild!.firstChild!;
|
|
67
67
|
expect(text).to.have.property("data", "test");
|
|
@@ -83,10 +83,10 @@ describe("@preact/signals-react", () => {
|
|
|
83
83
|
|
|
84
84
|
function App() {
|
|
85
85
|
const value = sig.value;
|
|
86
|
-
return
|
|
86
|
+
return <p>{value}</p>;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
render(
|
|
89
|
+
render(<App />);
|
|
90
90
|
expect(scratch.textContent).to.equal("foo");
|
|
91
91
|
|
|
92
92
|
act(() => {
|
|
@@ -107,10 +107,10 @@ describe("@preact/signals-react", () => {
|
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
const str = arr.value.join(", ");
|
|
110
|
-
return
|
|
110
|
+
return <p>{str}</p>;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
const fn = () => render(
|
|
113
|
+
const fn = () => render(<App />);
|
|
114
114
|
expect(fn).not.to.throw;
|
|
115
115
|
});
|
|
116
116
|
|
|
@@ -119,16 +119,16 @@ describe("@preact/signals-react", () => {
|
|
|
119
119
|
|
|
120
120
|
function Child() {
|
|
121
121
|
const value = sig.value;
|
|
122
|
-
return
|
|
122
|
+
return <p>{value}</p>;
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const spy = sinon.spy();
|
|
126
126
|
function App() {
|
|
127
127
|
spy();
|
|
128
|
-
return
|
|
128
|
+
return <Child />;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
render(
|
|
131
|
+
render(<App />);
|
|
132
132
|
expect(scratch.textContent).to.equal("foo");
|
|
133
133
|
|
|
134
134
|
act(() => {
|
|
@@ -142,15 +142,15 @@ describe("@preact/signals-react", () => {
|
|
|
142
142
|
|
|
143
143
|
function Inner() {
|
|
144
144
|
const value = sig.value;
|
|
145
|
-
return
|
|
145
|
+
return <p>{value}</p>;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
function App() {
|
|
149
149
|
sig.value;
|
|
150
|
-
return useMemo(() =>
|
|
150
|
+
return useMemo(() => <Inner foo={1} />, []);
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
render(
|
|
153
|
+
render(<App />);
|
|
154
154
|
expect(scratch.textContent).to.equal("foo");
|
|
155
155
|
|
|
156
156
|
act(() => {
|
|
@@ -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
|
});
|