@preact/signals 1.3.1 → 2.0.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,12 +1,29 @@
1
1
  # @preact/signals
2
2
 
3
- ## 1.3.1
3
+ ## 2.0.0
4
4
 
5
- ### Patch Changes
5
+ ### Major Changes
6
+
7
+ - [#604](https://github.com/preactjs/signals/pull/604) [`fea3e8d`](https://github.com/preactjs/signals/commit/fea3e8da7a36944d87310678fad291aeacc55d8d) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Defer all DOM updates by an animation frame, this should make it so
8
+ that any previously synchronous DOM update will be instead delayed by an
9
+ animation frame. This allows Preact to first perform its own render
10
+ cycle and then our direct DOM updates to occur. These will now
11
+ be performed in a batched way which is more performant as the browser
12
+ is prepared to handle these during the animation frame.
13
+
14
+ This does impact how Preact based signals are tested, when
15
+ you perform a signal update, you'll need to wrap it in `act`. In a way
16
+ this was always the case, as a signal update that resulted in
17
+ a Preact state update would require it to be wrapped in `act`, but
18
+ now this is the norm.
6
19
 
7
- - [#620](https://github.com/preactjs/signals/pull/620) [`4cda002`](https://github.com/preactjs/signals/commit/4cda002b9661b0fc936e9659e59d8b5979e7793b) Thanks [@developit](https://github.com/developit)! - Simplify text update patch to avoid using new internals
20
+ ### Minor Changes
21
+
22
+ - [#595](https://github.com/preactjs/signals/pull/595) [`499428a`](https://github.com/preactjs/signals/commit/499428aa7e7db3e250b3c257debf054a6368c010) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Align signal effects with animation-frames for better performance
23
+
24
+ ### Patch Changes
8
25
 
9
- - [#618](https://github.com/preactjs/signals/pull/618) [`021c726`](https://github.com/preactjs/signals/commit/021c726452046614eadae548d54af6ccb9832c14) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Ensure that the Effects versions are updated when using it as a JSX Signal
26
+ - [#609](https://github.com/preactjs/signals/pull/609) [`8e6e2de`](https://github.com/preactjs/signals/commit/8e6e2de5a2af27832ea139a7b76fc63ae56cc1f1) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Change timing to a double microtask so we are behind the Preact render queue but can't delay as much as a user-input coming in.
10
27
 
11
28
  ## 1.3.0
12
29
 
package/dist/signals.js CHANGED
@@ -1 +1 @@
1
- var r,i,n=require("preact"),t=require("preact/hooks"),f=require("@preact/signals-core");function o(r,i){n.options[r]=i.bind(null,n.options[r]||function(){})}function e(r){if(i)i();i=r&&r.S()}function u(r){var i=this,o=r.data,e=useSignal(o);e.value=o;var u=t.useMemo(function(){var r=i.__v;while(r=r.__)if(r.__c){r.__c.__$f|=4;break}i.__$u.c=function(){var r,t=i.__$u.S(),f=u.value;t();if(n.isValidElement(f)||3!==(null==(r=i.base)?void 0:r.nodeType)){i.__$f|=1;i.setState({})}else i.base.data=f};return f.computed(function(){var r=e.value.value;return 0===r?0:!0===r?"":r||""})},[]);return u.value}u.displayName="_st";Object.defineProperties(f.Signal.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:u},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});o("__b",function(r,i){if("string"==typeof i.type){var n,t=i.props;for(var o in t)if("children"!==o){var e=t[o];if(e instanceof f.Signal){if(!n)i.__np=n={};n[o]=e;t[o]=e.peek()}}}r(i)});o("__r",function(i,n){e();var t,o=n.__c;if(o){o.__$f&=-2;if(void 0===(t=o.__$u))o.__$u=t=function(r){var i;f.effect(function(){i=this});i.c=function(){o.__$f|=1;o.setState({})};return i}()}r=o;e(t);i(n)});o("__e",function(i,n,t,f){e();r=void 0;i(n,t,f)});o("diffed",function(i,n){e();r=void 0;var t;if("string"==typeof n.type&&(t=n.__e)){var f=n.__np,o=n.props;if(f){var u=t.U;if(u)for(var v in u){var c=u[v];if(void 0!==c&&!(v in f)){c.d();u[v]=void 0}}else t.U=u={};for(var s in f){var l=u[s],p=f[s];if(void 0===l){l=a(t,s,p,o);u[s]=l}else l.o(p,o)}}}i(n)});function a(r,i,n,t){var o=i in r&&void 0===r.ownerSVGElement,e=f.signal(n);return{o:function(r,i){e.value=r;t=i},d:f.effect(function(){var n=e.value.value;if(t[i]!==n){t[i]=n;if(o)r[i]=n;else if(n)r.setAttribute(i,n);else r.removeAttribute(i)}})}}o("unmount",function(r,i){if("string"==typeof i.type){var n=i.__e;if(n){var t=n.U;if(t){n.U=void 0;for(var f in t){var o=t[f];if(o)o.d()}}}}else{var e=i.__c;if(e){var u=e.__$u;if(u){e.__$u=void 0;u.d()}}}r(i)});o("__h",function(r,i,n,t){if(t<3||9===t)i.__$f|=2;r(i,n,t)});n.Component.prototype.shouldComponentUpdate=function(r,i){var n=this.__$u;if(!(n&&void 0!==n.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(var t in i)return!0;for(var f in r)if("__source"!==f&&r[f]!==this.props[f])return!0;for(var o in this.props)if(!(o in r))return!0;return!1};function useSignal(r){return t.useMemo(function(){return f.signal(r)},[])}exports.Signal=f.Signal;exports.batch=f.batch;exports.computed=f.computed;exports.effect=f.effect;exports.signal=f.signal;exports.untracked=f.untracked;exports.useComputed=function(i){var n=t.useRef(i);n.current=i;r.__$f|=4;return t.useMemo(function(){return f.computed(function(){return n.current()})},[])};exports.useSignal=useSignal;exports.useSignalEffect=function(r){var i=t.useRef(r);i.current=r;t.useEffect(function(){return f.effect(function(){return i.current()})},[])};//# sourceMappingURL=signals.js.map
1
+ var i,n,r=require("preact"),t=require("preact/hooks"),f=require("@preact/signals-core");function o(i,n){r.options[i]=n.bind(null,r.options[i]||function(){})}function e(i){if(n)n();n=i&&i.S()}function u(i){var n=this,o=i.data,e=useSignal(o);e.value=o;var u=t.useMemo(function(){var i=n,t=n.__v;while(t=t.__)if(t.__c){t.__c.__$f|=4;break}var o=f.computed(function(){var i=e.value.value;return 0===i?0:!0===i?"":i||""}),a=f.computed(function(){var i;return r.isValidElement(o.value)||3!==(null==(i=n.base)?void 0:i.nodeType)});n.__$u.c=function(){var i;if(!r.isValidElement(u.peek())&&3===(null==(i=n.base)?void 0:i.nodeType))n.base.data=u.peek();else{n.__$f|=1;n.setState({})}};f.effect(function(){if(!c)c=this.N;this.N=g;if(a.value&&i.base)i.base.data=o.value});return o},[]);return u.value}u.displayName="_st";Object.defineProperties(f.Signal.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:u},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});o("__b",function(i,n){if("string"==typeof n.type){var r,t=n.props;for(var o in t)if("children"!==o){var e=t[o];if(e instanceof f.Signal){if(!r)n.__np=r={};r[o]=e;t[o]=e.peek()}}}i(n)});o("__r",function(n,r){e();var t,o=r.__c;if(o){o.__$f&=-2;if(void 0===(t=o.__$u))o.__$u=t=function(i){var n;f.effect(function(){n=this});n.c=function(){o.__$f|=1;o.setState({})};return n}()}i=o;e(t);n(r)});o("__e",function(n,r,t,f){e();i=void 0;n(r,t,f)});o("diffed",function(n,r){e();i=void 0;var t;if("string"==typeof r.type&&(t=r.__e)){var f=r.__np,o=r.props;if(f){var u=t.U;if(u)for(var c in u){var v=u[c];if(void 0!==v&&!(c in f)){v.d();u[c]=void 0}}else t.U=u={};for(var s in f){var l=u[s],h=f[s];if(void 0===l){l=a(t,s,h,o);u[s]=l}else l.o(h,o)}}}n(r)});function a(i,n,r,t){var o=n in i&&void 0===i.ownerSVGElement,e=f.signal(r);return{o:function(i,n){e.value=i;t=n},d:f.effect(function(){if(!c)c=this.N;this.N=g;var r=e.value.value;if(t[n]!==r){t[n]=r;if(o)i[n]=r;else if(r)i.setAttribute(n,r);else i.removeAttribute(n)}})}}o("unmount",function(i,n){if("string"==typeof n.type){var r=n.__e;if(r){var t=r.U;if(t){r.U=void 0;for(var f in t){var o=t[f];if(o)o.d()}}}}else{var e=n.__c;if(e){var u=e.__$u;if(u){e.__$u=void 0;u.d()}}}i(n)});o("__h",function(i,n,r,t){if(t<3||9===t)n.__$f|=2;i(n,r,t)});r.Component.prototype.shouldComponentUpdate=function(i,n){var r=this.__$u;if(!(r&&void 0!==r.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(var t in n)return!0;for(var f in i)if("__source"!==f&&i[f]!==this.props[f])return!0;for(var o in this.props)if(!(o in i))return!0;return!1};function useSignal(i){return t.useMemo(function(){return f.signal(i)},[])}var c,v=[],s=[],l="undefined"==typeof requestAnimationFrame?setTimeout:requestAnimationFrame,h=function(i){queueMicrotask(function(){queueMicrotask(i)})};function d(){f.batch(function(){var i;while(i=v.shift())c.call(i)})}function p(){if(1===v.push(this))(r.options.requestAnimationFrame||l)(d)}function _(){f.batch(function(){var i;while(i=s.shift())c.call(i)})}function g(){if(1===s.push(this))(r.options.requestAnimationFrame||h)(_)}exports.Signal=f.Signal;exports.batch=f.batch;exports.computed=f.computed;exports.effect=f.effect;exports.signal=f.signal;exports.untracked=f.untracked;exports.useComputed=function(n){var r=t.useRef(n);r.current=n;i.__$f|=4;return t.useMemo(function(){return f.computed(function(){return r.current()})},[])};exports.useSignal=useSignal;exports.useSignalEffect=function(i){var n=t.useRef(i);n.current=i;t.useEffect(function(){return f.effect(function(){if(!c)c=this.N;this.N=p;return n.current()})},[])};//# sourceMappingURL=signals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis._updater!._callback = () => {\n\t\t\tconst end = this._updater!._start();\n\t\t\tconst value = s.value;\n\t\t\tend();\n\n\t\t\tif (isValidElement(value) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t} else {\n\t\t\t\t(this.base as Text).data = value;\n\t\t\t}\n\t\t};\n\n\t\treturn computed(() => {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(() => {\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\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(() => callback.current());\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["currentComponent","finishUpdate","preact","require","hooks","signalsCore","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","_start","SignalValue","_ref","_this","this","data","currentSignal","useSignal","value","s","useMemo","v","__v","__","__c","_updateFlags","_updater","_callback","_this$base","end","isValidElement","base","nodeType","setState","computed","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","peek","component","update","effect","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","signal","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","Component","shouldComponentUpdate","state","_sources","exports","batch","untracked","useComputed","compute","$compute","useRef","current","useSignalEffect","cb","callback","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"signals.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\tlet self = this;\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst wrappedSignal = computed(function (this: Effect) {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\n\t\tconst isText = computed(\n\t\t\t() => isValidElement(wrappedSignal.value) || this.base?.nodeType !== 3\n\t\t);\n\n\t\tthis._updater!._callback = () => {\n\t\t\tif (isValidElement(s.peek()) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t(this.base as Text).data = s.peek();\n\t\t};\n\n\t\teffect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst val = wrappedSignal.value;\n\t\t\tif (isText.value && self.base) {\n\t\t\t\t(self.base as Text).data = val;\n\t\t\t}\n\t\t});\n\n\t\treturn wrappedSignal;\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nlet oldNotify: (this: Effect) => void,\n\teffectsQueue: Array<Effect> = [],\n\tdomQueue: Array<Effect> = [];\n\nconst deferEffects =\n\ttypeof requestAnimationFrame === \"undefined\"\n\t\t? setTimeout\n\t\t: requestAnimationFrame;\n\nconst deferDomUpdates = (cb: any) => {\n\tqueueMicrotask(() => {\n\t\tqueueMicrotask(cb);\n\t});\n};\n\nfunction flushEffects() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = effectsQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyEffects(this: Effect) {\n\tif (effectsQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferEffects)(flushEffects);\n\t}\n}\n\nfunction flushDomUpdates() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = domQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyDomUpdates(this: Effect) {\n\tif (domQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferDomUpdates)(flushDomUpdates);\n\t}\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyEffects;\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["currentComponent","finishUpdate","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","_start","SignalValue","_ref","_this","this","data","currentSignal","useSignal","value","s","useMemo","self","v","__v","__","__c","_updateFlags","wrappedSignal","computed","isText","_this$base","isValidElement","base","nodeType","_updater","_callback","_this$base2","peek","setState","effect","oldNotify","_notify","notifyDomUpdates","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","component","update","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","signal","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","Component","shouldComponentUpdate","state","_sources","effectsQueue","domQueue","deferEffects","requestAnimationFrame","setTimeout","deferDomUpdates","cb","queueMicrotask","flushEffects","batch","inst","shift","call","notifyEffects","push","flushDomUpdates","exports","signalsCore","untracked","useComputed","compute","$compute","useRef","current","useSignalEffect","callback","useEffect"],"mappings":"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"}
@@ -1 +1 @@
1
- !function(n,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("preact"),require("preact/hooks"),require("@preact/signals-core")):"function"==typeof define&&define.amd?define(["exports","preact","preact/hooks","@preact/signals-core"],i):i((n||self).preactSignals={},n.preact,n.preactHooks,n.preactSignalsCore)}(this,function(n,i,r,t){var e,f;function o(n,r){i.options[n]=r.bind(null,i.options[n]||function(){})}function u(n){if(f)f();f=n&&n.S()}function a(n){var e=this,f=n.data,o=useSignal(f);o.value=f;var u=r.useMemo(function(){var n=e.__v;while(n=n.__)if(n.__c){n.__c.__$f|=4;break}e.__$u.c=function(){var n,r=e.__$u.S(),t=u.value;r();if(i.isValidElement(t)||3!==(null==(n=e.base)?void 0:n.nodeType)){e.__$f|=1;e.setState({})}else e.base.data=t};return t.computed(function(){var n=o.value.value;return 0===n?0:!0===n?"":n||""})},[]);return u.value}a.displayName="_st";Object.defineProperties(t.Signal.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:a},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});o("__b",function(n,i){if("string"==typeof i.type){var r,e=i.props;for(var f in e)if("children"!==f){var o=e[f];if(o instanceof t.Signal){if(!r)i.__np=r={};r[f]=o;e[f]=o.peek()}}}n(i)});o("__r",function(n,i){u();var r,f=i.__c;if(f){f.__$f&=-2;if(void 0===(r=f.__$u))f.__$u=r=function(n){var i;t.effect(function(){i=this});i.c=function(){f.__$f|=1;f.setState({})};return i}()}e=f;u(r);n(i)});o("__e",function(n,i,r,t){u();e=void 0;n(i,r,t)});o("diffed",function(n,i){u();e=void 0;var r;if("string"==typeof i.type&&(r=i.__e)){var t=i.__np,f=i.props;if(t){var o=r.U;if(o)for(var a in o){var v=o[a];if(void 0!==v&&!(a in t)){v.d();o[a]=void 0}}else r.U=o={};for(var s in t){var l=o[s],d=t[s];if(void 0===l){l=c(r,s,d,f);o[s]=l}else l.o(d,f)}}}n(i)});function c(n,i,r,e){var f=i in n&&void 0===n.ownerSVGElement,o=t.signal(r);return{o:function(n,i){o.value=n;e=i},d:t.effect(function(){var r=o.value.value;if(e[i]!==r){e[i]=r;if(f)n[i]=r;else if(r)n.setAttribute(i,r);else n.removeAttribute(i)}})}}o("unmount",function(n,i){if("string"==typeof i.type){var r=i.__e;if(r){var t=r.U;if(t){r.U=void 0;for(var e in t){var f=t[e];if(f)f.d()}}}}else{var o=i.__c;if(o){var u=o.__$u;if(u){o.__$u=void 0;u.d()}}}n(i)});o("__h",function(n,i,r,t){if(t<3||9===t)i.__$f|=2;n(i,r,t)});i.Component.prototype.shouldComponentUpdate=function(n,i){var r=this.__$u;if(!(r&&void 0!==r.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(var t in i)return!0;for(var e in n)if("__source"!==e&&n[e]!==this.props[e])return!0;for(var f in this.props)if(!(f in n))return!0;return!1};function useSignal(n){return r.useMemo(function(){return t.signal(n)},[])}n.Signal=t.Signal;n.batch=t.batch;n.computed=t.computed;n.effect=t.effect;n.signal=t.signal;n.untracked=t.untracked;n.useComputed=function(n){var i=r.useRef(n);i.current=n;e.__$f|=4;return r.useMemo(function(){return t.computed(function(){return i.current()})},[])};n.useSignal=useSignal;n.useSignalEffect=function(n){var i=r.useRef(n);i.current=n;r.useEffect(function(){return t.effect(function(){return i.current()})},[])}});//# sourceMappingURL=signals.min.js.map
1
+ !function(i,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("preact"),require("preact/hooks"),require("@preact/signals-core")):"function"==typeof define&&define.amd?define(["exports","preact","preact/hooks","@preact/signals-core"],n):n((i||self).preactSignals={},i.preact,i.preactHooks,i.preactSignalsCore)}(this,function(i,n,r,t){var e,f;function o(i,r){n.options[i]=r.bind(null,n.options[i]||function(){})}function u(i){if(f)f();f=i&&i.S()}function a(i){var e=this,f=i.data,o=useSignal(f);o.value=f;var u=r.useMemo(function(){var i=e,r=e.__v;while(r=r.__)if(r.__c){r.__c.__$f|=4;break}var f=t.computed(function(){var i=o.value.value;return 0===i?0:!0===i?"":i||""}),a=t.computed(function(){var i;return n.isValidElement(f.value)||3!==(null==(i=e.base)?void 0:i.nodeType)});e.__$u.c=function(){var i;if(!n.isValidElement(u.peek())&&3===(null==(i=e.base)?void 0:i.nodeType))e.base.data=u.peek();else{e.__$f|=1;e.setState({})}};t.effect(function(){if(!v)v=this.N;this.N=b;if(a.value&&i.base)i.base.data=f.value});return f},[]);return u.value}a.displayName="_st";Object.defineProperties(t.Signal.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:a},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});o("__b",function(i,n){if("string"==typeof n.type){var r,e=n.props;for(var f in e)if("children"!==f){var o=e[f];if(o instanceof t.Signal){if(!r)n.__np=r={};r[f]=o;e[f]=o.peek()}}}i(n)});o("__r",function(i,n){u();var r,f=n.__c;if(f){f.__$f&=-2;if(void 0===(r=f.__$u))f.__$u=r=function(i){var n;t.effect(function(){n=this});n.c=function(){f.__$f|=1;f.setState({})};return n}()}e=f;u(r);i(n)});o("__e",function(i,n,r,t){u();e=void 0;i(n,r,t)});o("diffed",function(i,n){u();e=void 0;var r;if("string"==typeof n.type&&(r=n.__e)){var t=n.__np,f=n.props;if(t){var o=r.U;if(o)for(var a in o){var v=o[a];if(void 0!==v&&!(a in t)){v.d();o[a]=void 0}}else r.U=o={};for(var s in t){var l=o[s],d=t[s];if(void 0===l){l=c(r,s,d,f);o[s]=l}else l.o(d,f)}}}i(n)});function c(i,n,r,e){var f=n in i&&void 0===i.ownerSVGElement,o=t.signal(r);return{o:function(i,n){o.value=i;e=n},d:t.effect(function(){if(!v)v=this.N;this.N=b;var r=o.value.value;if(e[n]!==r){e[n]=r;if(f)i[n]=r;else if(r)i.setAttribute(n,r);else i.removeAttribute(n)}})}}o("unmount",function(i,n){if("string"==typeof n.type){var r=n.__e;if(r){var t=r.U;if(t){r.U=void 0;for(var e in t){var f=t[e];if(f)f.d()}}}}else{var o=n.__c;if(o){var u=o.__$u;if(u){o.__$u=void 0;u.d()}}}i(n)});o("__h",function(i,n,r,t){if(t<3||9===t)n.__$f|=2;i(n,r,t)});n.Component.prototype.shouldComponentUpdate=function(i,n){var r=this.__$u;if(!(r&&void 0!==r.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(var t in n)return!0;for(var e in i)if("__source"!==e&&i[e]!==this.props[e])return!0;for(var f in this.props)if(!(f in i))return!0;return!1};function useSignal(i){return r.useMemo(function(){return t.signal(i)},[])}var v,s=[],l=[],d="undefined"==typeof requestAnimationFrame?setTimeout:requestAnimationFrame,h=function(i){queueMicrotask(function(){queueMicrotask(i)})};function p(){t.batch(function(){var i;while(i=s.shift())v.call(i)})}function _(){if(1===s.push(this))(n.options.requestAnimationFrame||d)(p)}function g(){t.batch(function(){var i;while(i=l.shift())v.call(i)})}function b(){if(1===l.push(this))(n.options.requestAnimationFrame||h)(g)}i.Signal=t.Signal;i.batch=t.batch;i.computed=t.computed;i.effect=t.effect;i.signal=t.signal;i.untracked=t.untracked;i.useComputed=function(i){var n=r.useRef(i);n.current=i;e.__$f|=4;return r.useMemo(function(){return t.computed(function(){return n.current()})},[])};i.useSignal=useSignal;i.useSignalEffect=function(i){var n=r.useRef(i);n.current=i;r.useEffect(function(){return t.effect(function(){if(!v)v=this.N;this.N=_;return n.current()})},[])}});//# sourceMappingURL=signals.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.min.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis._updater!._callback = () => {\n\t\t\tconst end = this._updater!._start();\n\t\t\tconst value = s.value;\n\t\t\tend();\n\n\t\t\tif (isValidElement(value) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t} else {\n\t\t\t\t(this.base as Text).data = value;\n\t\t\t}\n\t\t};\n\n\t\treturn computed(() => {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(() => {\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\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(() => callback.current());\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["g","f","exports","module","require","define","amd","globalThis","self","preactSignals","preact","preactHooks","preactSignalsCore","this","hooks","signalsCore","currentComponent","finishUpdate","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","_start","SignalValue","_ref","_this","data","currentSignal","useSignal","value","s","useMemo","v","__v","__","__c","_updateFlags","_updater","_callback","_this$base","end","isValidElement","base","nodeType","setState","computed","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","peek","component","update","effect","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","signal","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","Component","shouldComponentUpdate","state","_sources","batch","untracked","useComputed","compute","$compute","useRef","current","useSignalEffect","cb","callback","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"signals.min.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\tlet self = this;\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst wrappedSignal = computed(function (this: Effect) {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\n\t\tconst isText = computed(\n\t\t\t() => isValidElement(wrappedSignal.value) || this.base?.nodeType !== 3\n\t\t);\n\n\t\tthis._updater!._callback = () => {\n\t\t\tif (isValidElement(s.peek()) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t(this.base as Text).data = s.peek();\n\t\t};\n\n\t\teffect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst val = wrappedSignal.value;\n\t\t\tif (isText.value && self.base) {\n\t\t\t\t(self.base as Text).data = val;\n\t\t\t}\n\t\t});\n\n\t\treturn wrappedSignal;\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nlet oldNotify: (this: Effect) => void,\n\teffectsQueue: Array<Effect> = [],\n\tdomQueue: Array<Effect> = [];\n\nconst deferEffects =\n\ttypeof requestAnimationFrame === \"undefined\"\n\t\t? setTimeout\n\t\t: requestAnimationFrame;\n\nconst deferDomUpdates = (cb: any) => {\n\tqueueMicrotask(() => {\n\t\tqueueMicrotask(cb);\n\t});\n};\n\nfunction flushEffects() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = effectsQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyEffects(this: Effect) {\n\tif (effectsQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferEffects)(flushEffects);\n\t}\n}\n\nfunction flushDomUpdates() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = domQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyDomUpdates(this: Effect) {\n\tif (domQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferDomUpdates)(flushDomUpdates);\n\t}\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyEffects;\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["currentComponent","finishUpdate","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","_start","SignalValue","_ref","_this","this","data","currentSignal","useSignal","value","s","useMemo","self","v","__v","__","__c","_updateFlags","wrappedSignal","computed","isText","_this$base","isValidElement","base","nodeType","_updater","_callback","_this$base2","peek","setState","effect","oldNotify","_notify","notifyDomUpdates","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","component","update","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","signal","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","Component","shouldComponentUpdate","state","_sources","effectsQueue","domQueue","deferEffects","requestAnimationFrame","setTimeout","deferDomUpdates","cb","queueMicrotask","flushEffects","batch","inst","shift","call","notifyEffects","push","flushDomUpdates","exports","signalsCore","untracked","useComputed","compute","$compute","useRef","current","useSignalEffect","callback","useEffect"],"mappings":"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"}
package/dist/signals.mjs CHANGED
@@ -1 +1 @@
1
- import{Component as t,options as i,isValidElement as e}from"preact";import{useMemo as n,useRef as o,useEffect as r}from"preact/hooks";import{Signal as f,computed as s,signal as l,effect as c}from"@preact/signals-core";export{Signal,batch,computed,effect,signal,untracked}from"@preact/signals-core";function u(t,e){i[t]=e.bind(null,i[t]||(()=>{}))}let a,d;function h(t){if(d)d();d=t&&t.S()}function p({data:t}){const i=useSignal(t);i.value=t;const o=n(()=>{let t=this.__v;while(t=t.__)if(t.__c){t.__c.__$f|=4;break}this.__$u.c=()=>{var t;const i=this.__$u.S(),n=o.value;i();if(e(n)||3!==(null==(t=this.base)?void 0:t.nodeType)){this.__$f|=1;this.setState({})}else this.base.data=n};return s(()=>{let t=i.value.value;return 0===t?0:!0===t?"":t||""})},[]);return o.value}p.displayName="_st";Object.defineProperties(f.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:p},props:{configurable:!0,get(){return{data:this}}},__b:{configurable:!0,value:1}});u("__b",(t,i)=>{if("string"==typeof i.type){let t,e=i.props;for(let n in e){if("children"===n)continue;let o=e[n];if(o instanceof f){if(!t)i.__np=t={};t[n]=o;e[n]=o.peek()}}}t(i)});u("__r",(t,i)=>{h();let e,n=i.__c;if(n){n.__$f&=-2;e=n.__$u;if(void 0===e)n.__$u=e=function(t){let i;c(function(){i=this});i.c=()=>{n.__$f|=1;n.setState({})};return i}()}a=n;h(e);t(i)});u("__e",(t,i,e,n)=>{h();a=void 0;t(i,e,n)});u("diffed",(t,i)=>{h();a=void 0;let e;if("string"==typeof i.type&&(e=i.__e)){let t=i.__np,n=i.props;if(t){let i=e.U;if(i)for(let e in i){let n=i[e];if(void 0!==n&&!(e in t)){n.d();i[e]=void 0}}else{i={};e.U=i}for(let o in t){let r=i[o],f=t[o];if(void 0===r){r=v(e,o,f,n);i[o]=r}else r.o(f,n)}}}t(i)});function v(t,i,e,n){const o=i in t&&void 0===t.ownerSVGElement,r=l(e);return{o:(t,i)=>{r.value=t;n=i},d:c(()=>{const e=r.value.value;if(n[i]!==e){n[i]=e;if(o)t[i]=e;else if(e)t.setAttribute(i,e);else t.removeAttribute(i)}})}}u("unmount",(t,i)=>{if("string"==typeof i.type){let t=i.__e;if(t){const i=t.U;if(i){t.U=void 0;for(let t in i){let e=i[t];if(e)e.d()}}}}else{let t=i.__c;if(t){const i=t.__$u;if(i){t.__$u=void 0;i.d()}}}t(i)});u("__h",(t,i,e,n)=>{if(n<3||9===n)i.__$f|=2;t(i,e,n)});t.prototype.shouldComponentUpdate=function(t,i){const e=this.__$u;if(!(e&&void 0!==e.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(let t in i)return!0;for(let i in t)if("__source"!==i&&t[i]!==this.props[i])return!0;for(let i in this.props)if(!(i in t))return!0;return!1};function useSignal(t){return n(()=>l(t),[])}function useComputed(t){const i=o(t);i.current=t;a.__$f|=4;return n(()=>s(()=>i.current()),[])}function useSignalEffect(t){const i=o(t);i.current=t;r(()=>c(()=>i.current()),[])}export{useComputed,useSignal,useSignalEffect};//# sourceMappingURL=signals.mjs.map
1
+ import{Component as t,options as i,isValidElement as e}from"preact";import{useMemo as n,useRef as o,useEffect as f}from"preact/hooks";import{Signal as r,computed as s,effect as u,signal as c,batch as l}from"@preact/signals-core";export{Signal,batch,computed,effect,signal,untracked}from"@preact/signals-core";function a(t,e){i[t]=e.bind(null,i[t]||(()=>{}))}let h,d;function p(t){if(d)d();d=t&&t.S()}function v({data:t}){const i=useSignal(t);i.value=t;const o=n(()=>{let t=this,n=this.__v;while(n=n.__)if(n.__c){n.__c.__$f|=4;break}const f=s(function(){let t=i.value.value;return 0===t?0:!0===t?"":t||""}),r=s(()=>{var t;return e(f.value)||3!==(null==(t=this.base)?void 0:t.nodeType)});this.__$u.c=()=>{var t;if(!e(o.peek())&&3===(null==(t=this.base)?void 0:t.nodeType))this.base.data=o.peek();else{this.__$f|=1;this.setState({})}};u(function(){if(!m)m=this.N;this.N=A;if(r.value&&t.base)t.base.data=f.value});return f},[]);return o.value}v.displayName="_st";Object.defineProperties(r.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:v},props:{configurable:!0,get(){return{data:this}}},__b:{configurable:!0,value:1}});a("__b",(t,i)=>{if("string"==typeof i.type){let t,e=i.props;for(let n in e){if("children"===n)continue;let o=e[n];if(o instanceof r){if(!t)i.__np=t={};t[n]=o;e[n]=o.peek()}}}t(i)});a("__r",(t,i)=>{p();let e,n=i.__c;if(n){n.__$f&=-2;e=n.__$u;if(void 0===e)n.__$u=e=function(t){let i;u(function(){i=this});i.c=()=>{n.__$f|=1;n.setState({})};return i}()}h=n;p(e);t(i)});a("__e",(t,i,e,n)=>{p();h=void 0;t(i,e,n)});a("diffed",(t,i)=>{p();h=void 0;let e;if("string"==typeof i.type&&(e=i.__e)){let t=i.__np,n=i.props;if(t){let i=e.U;if(i)for(let e in i){let n=i[e];if(void 0!==n&&!(e in t)){n.d();i[e]=void 0}}else{i={};e.U=i}for(let o in t){let f=i[o],r=t[o];if(void 0===f){f=_(e,o,r,n);i[o]=f}else f.o(r,n)}}}t(i)});function _(t,i,e,n){const o=i in t&&void 0===t.ownerSVGElement,f=c(e);return{o:(t,i)=>{f.value=t;n=i},d:u(function(){if(!m)m=this.N;this.N=A;const e=f.value.value;if(n[i]!==e){n[i]=e;if(o)t[i]=e;else if(e)t.setAttribute(i,e);else t.removeAttribute(i)}})}}a("unmount",(t,i)=>{if("string"==typeof i.type){let t=i.__e;if(t){const i=t.U;if(i){t.U=void 0;for(let t in i){let e=i[t];if(e)e.d()}}}}else{let t=i.__c;if(t){const i=t.__$u;if(i){t.__$u=void 0;i.d()}}}t(i)});a("__h",(t,i,e,n)=>{if(n<3||9===n)i.__$f|=2;t(i,e,n)});t.prototype.shouldComponentUpdate=function(t,i){const e=this.__$u;if(!(e&&void 0!==e.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(let t in i)return!0;for(let i in t)if("__source"!==i&&t[i]!==this.props[i])return!0;for(let i in this.props)if(!(i in t))return!0;return!1};function useSignal(t){return n(()=>c(t),[])}function useComputed(t){const i=o(t);i.current=t;h.__$f|=4;return n(()=>s(()=>i.current()),[])}let m,g=[],b=[];const k="undefined"==typeof requestAnimationFrame?setTimeout:requestAnimationFrame,y=t=>{queueMicrotask(()=>{queueMicrotask(t)})};function q(){l(()=>{let t;while(t=g.shift())m.call(t)})}function w(){if(1===g.push(this))(i.requestAnimationFrame||k)(q)}function x(){l(()=>{let t;while(t=b.shift())m.call(t)})}function A(){if(1===b.push(this))(i.requestAnimationFrame||y)(x)}function useSignalEffect(t){const i=o(t);i.current=t;f(()=>u(function(){if(!m)m=this.N;this.N=w;return i.current()}),[])}export{useComputed,useSignal,useSignalEffect};//# sourceMappingURL=signals.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.mjs","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis._updater!._callback = () => {\n\t\t\tconst end = this._updater!._start();\n\t\t\tconst value = s.value;\n\t\t\tend();\n\n\t\t\tif (isValidElement(value) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t} else {\n\t\t\t\t(this.base as Text).data = value;\n\t\t\t}\n\t\t};\n\n\t\treturn computed(() => {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(() => {\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\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(() => callback.current());\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["Component","options","isValidElement","useMemo","useRef","useEffect","Signal","computed","signal","effect","batch","untracked","hook","hookName","hookFn","bind","currentComponent","finishUpdate","setCurrentUpdater","updater","_start","SignalValue","data","currentSignal","useSignal","value","s","v","this","__v","__","__c","_updateFlags","_updater","_callback","_this$base","end","base","nodeType","setState","displayName","Object","defineProperties","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","peek","component","update","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","shouldComponentUpdate","state","_sources","HAS_PENDING_UPDATE","useComputed","compute","$compute","current","useSignalEffect","cb","callback"],"mappings":"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"}
1
+ {"version":3,"file":"signals.mjs","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\tlet self = this;\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst wrappedSignal = computed(function (this: Effect) {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\n\t\tconst isText = computed(\n\t\t\t() => isValidElement(wrappedSignal.value) || this.base?.nodeType !== 3\n\t\t);\n\n\t\tthis._updater!._callback = () => {\n\t\t\tif (isValidElement(s.peek()) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t(this.base as Text).data = s.peek();\n\t\t};\n\n\t\teffect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst val = wrappedSignal.value;\n\t\t\tif (isText.value && self.base) {\n\t\t\t\t(self.base as Text).data = val;\n\t\t\t}\n\t\t});\n\n\t\treturn wrappedSignal;\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nlet oldNotify: (this: Effect) => void,\n\teffectsQueue: Array<Effect> = [],\n\tdomQueue: Array<Effect> = [];\n\nconst deferEffects =\n\ttypeof requestAnimationFrame === \"undefined\"\n\t\t? setTimeout\n\t\t: requestAnimationFrame;\n\nconst deferDomUpdates = (cb: any) => {\n\tqueueMicrotask(() => {\n\t\tqueueMicrotask(cb);\n\t});\n};\n\nfunction flushEffects() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = effectsQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyEffects(this: Effect) {\n\tif (effectsQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferEffects)(flushEffects);\n\t}\n}\n\nfunction flushDomUpdates() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = domQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyDomUpdates(this: Effect) {\n\tif (domQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferDomUpdates)(flushDomUpdates);\n\t}\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyEffects;\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["Component","options","isValidElement","useMemo","useRef","useEffect","Signal","computed","effect","signal","batch","untracked","hook","hookName","hookFn","bind","currentComponent","finishUpdate","setCurrentUpdater","updater","_start","SignalValue","data","currentSignal","useSignal","value","s","self","this","v","__v","__","__c","_updateFlags","wrappedSignal","isText","_this$base","base","nodeType","_updater","_callback","_this$base2","peek","setState","oldNotify","_notify","notifyDomUpdates","displayName","Object","defineProperties","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","component","update","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","shouldComponentUpdate","state","_sources","useComputed","compute","$compute","current","effectsQueue","domQueue","deferEffects","requestAnimationFrame","setTimeout","deferDomUpdates","cb","queueMicrotask","flushEffects","inst","shift","call","notifyEffects","push","flushDomUpdates","useSignalEffect","callback"],"mappings":"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"}
@@ -1 +1 @@
1
- import{Component as n,options as r,isValidElement as i}from"preact";import{useMemo as t,useRef as f,useEffect as o}from"preact/hooks";import{Signal as e,computed as u,signal as a,effect as c}from"@preact/signals-core";export{Signal,batch,computed,effect,signal,untracked}from"@preact/signals-core";var v,s;function l(n,i){r[n]=i.bind(null,r[n]||function(){})}function d(n){if(s)s();s=n&&n.S()}function p(n){var r=this,f=n.data,o=useSignal(f);o.value=f;var e=t(function(){var n=r.__v;while(n=n.__)if(n.__c){n.__c.__$f|=4;break}r.__$u.c=function(){var n,t=r.__$u.S(),f=e.value;t();if(i(f)||3!==(null==(n=r.base)?void 0:n.nodeType)){r.__$f|=1;r.setState({})}else r.base.data=f};return u(function(){var n=o.value.value;return 0===n?0:!0===n?"":n||""})},[]);return e.value}p.displayName="_st";Object.defineProperties(e.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:p},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});l("__b",function(n,r){if("string"==typeof r.type){var i,t=r.props;for(var f in t)if("children"!==f){var o=t[f];if(o instanceof e){if(!i)r.__np=i={};i[f]=o;t[f]=o.peek()}}}n(r)});l("__r",function(n,r){d();var i,t=r.__c;if(t){t.__$f&=-2;if(void 0===(i=t.__$u))t.__$u=i=function(n){var r;c(function(){r=this});r.c=function(){t.__$f|=1;t.setState({})};return r}()}v=t;d(i);n(r)});l("__e",function(n,r,i,t){d();v=void 0;n(r,i,t)});l("diffed",function(n,r){d();v=void 0;var i;if("string"==typeof r.type&&(i=r.__e)){var t=r.__np,f=r.props;if(t){var o=i.U;if(o)for(var e in o){var u=o[e];if(void 0!==u&&!(e in t)){u.d();o[e]=void 0}}else i.U=o={};for(var a in t){var c=o[a],s=t[a];if(void 0===c){c=_(i,a,s,f);o[a]=c}else c.o(s,f)}}}n(r)});function _(n,r,i,t){var f=r in n&&void 0===n.ownerSVGElement,o=a(i);return{o:function(n,r){o.value=n;t=r},d:c(function(){var i=o.value.value;if(t[r]!==i){t[r]=i;if(f)n[r]=i;else if(i)n.setAttribute(r,i);else n.removeAttribute(r)}})}}l("unmount",function(n,r){if("string"==typeof r.type){var i=r.__e;if(i){var t=i.U;if(t){i.U=void 0;for(var f in t){var o=t[f];if(o)o.d()}}}}else{var e=r.__c;if(e){var u=e.__$u;if(u){e.__$u=void 0;u.d()}}}n(r)});l("__h",function(n,r,i,t){if(t<3||9===t)r.__$f|=2;n(r,i,t)});n.prototype.shouldComponentUpdate=function(n,r){var i=this.__$u;if(!(i&&void 0!==i.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(var t in r)return!0;for(var f in n)if("__source"!==f&&n[f]!==this.props[f])return!0;for(var o in this.props)if(!(o in n))return!0;return!1};function useSignal(n){return t(function(){return a(n)},[])}function useComputed(n){var r=f(n);r.current=n;v.__$f|=4;return t(function(){return u(function(){return r.current()})},[])}function useSignalEffect(n){var r=f(n);r.current=n;o(function(){return c(function(){return r.current()})},[])}export{useComputed,useSignal,useSignalEffect};//# sourceMappingURL=signals.module.js.map
1
+ import{Component as i,options as n,isValidElement as r}from"preact";import{useMemo as t,useRef as f,useEffect as o}from"preact/hooks";import{Signal as u,computed as e,effect as a,signal as c,batch as v}from"@preact/signals-core";export{Signal,batch,computed,effect,signal,untracked}from"@preact/signals-core";var s,l;function d(i,r){n[i]=r.bind(null,n[i]||function(){})}function h(i){if(l)l();l=i&&i.S()}function p(i){var n=this,f=i.data,o=useSignal(f);o.value=f;var u=t(function(){var i=n,t=n.__v;while(t=t.__)if(t.__c){t.__c.__$f|=4;break}var f=e(function(){var i=o.value.value;return 0===i?0:!0===i?"":i||""}),c=e(function(){var i;return r(f.value)||3!==(null==(i=n.base)?void 0:i.nodeType)});n.__$u.c=function(){var i;if(!r(u.peek())&&3===(null==(i=n.base)?void 0:i.nodeType))n.base.data=u.peek();else{n.__$f|=1;n.setState({})}};a(function(){if(!m)m=this.N;this.N=A;if(c.value&&i.base)i.base.data=f.value});return f},[]);return u.value}p.displayName="_st";Object.defineProperties(u.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:p},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});d("__b",function(i,n){if("string"==typeof n.type){var r,t=n.props;for(var f in t)if("children"!==f){var o=t[f];if(o instanceof u){if(!r)n.__np=r={};r[f]=o;t[f]=o.peek()}}}i(n)});d("__r",function(i,n){h();var r,t=n.__c;if(t){t.__$f&=-2;if(void 0===(r=t.__$u))t.__$u=r=function(i){var n;a(function(){n=this});n.c=function(){t.__$f|=1;t.setState({})};return n}()}s=t;h(r);i(n)});d("__e",function(i,n,r,t){h();s=void 0;i(n,r,t)});d("diffed",function(i,n){h();s=void 0;var r;if("string"==typeof n.type&&(r=n.__e)){var t=n.__np,f=n.props;if(t){var o=r.U;if(o)for(var u in o){var e=o[u];if(void 0!==e&&!(u in t)){e.d();o[u]=void 0}}else r.U=o={};for(var a in t){var c=o[a],v=t[a];if(void 0===c){c=_(r,a,v,f);o[a]=c}else c.o(v,f)}}}i(n)});function _(i,n,r,t){var f=n in i&&void 0===i.ownerSVGElement,o=c(r);return{o:function(i,n){o.value=i;t=n},d:a(function(){if(!m)m=this.N;this.N=A;var r=o.value.value;if(t[n]!==r){t[n]=r;if(f)i[n]=r;else if(r)i.setAttribute(n,r);else i.removeAttribute(n)}})}}d("unmount",function(i,n){if("string"==typeof n.type){var r=n.__e;if(r){var t=r.U;if(t){r.U=void 0;for(var f in t){var o=t[f];if(o)o.d()}}}}else{var u=n.__c;if(u){var e=u.__$u;if(e){u.__$u=void 0;e.d()}}}i(n)});d("__h",function(i,n,r,t){if(t<3||9===t)n.__$f|=2;i(n,r,t)});i.prototype.shouldComponentUpdate=function(i,n){var r=this.__$u;if(!(r&&void 0!==r.s||4&this.__$f))return!0;if(3&this.__$f)return!0;for(var t in n)return!0;for(var f in i)if("__source"!==f&&i[f]!==this.props[f])return!0;for(var o in this.props)if(!(o in i))return!0;return!1};function useSignal(i){return t(function(){return c(i)},[])}function useComputed(i){var n=f(i);n.current=i;s.__$f|=4;return t(function(){return e(function(){return n.current()})},[])}var m,g=[],b=[],k="undefined"==typeof requestAnimationFrame?setTimeout:requestAnimationFrame,y=function(i){queueMicrotask(function(){queueMicrotask(i)})};function q(){v(function(){var i;while(i=g.shift())m.call(i)})}function w(){if(1===g.push(this))(n.requestAnimationFrame||k)(q)}function x(){v(function(){var i;while(i=b.shift())m.call(i)})}function A(){if(1===b.push(this))(n.requestAnimationFrame||y)(x)}function useSignalEffect(i){var n=f(i);n.current=i;o(function(){return a(function(){if(!m)m=this.N;this.N=w;return n.current()})},[])}export{useComputed,useSignal,useSignalEffect};//# sourceMappingURL=signals.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"signals.module.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tthis._updater!._callback = () => {\n\t\t\tconst end = this._updater!._start();\n\t\t\tconst value = s.value;\n\t\t\tend();\n\n\t\t\tif (isValidElement(value) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t} else {\n\t\t\t\t(this.base as Text).data = value;\n\t\t\t}\n\t\t};\n\n\t\treturn computed(() => {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(() => {\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\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(() => callback.current());\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["Component","options","isValidElement","useMemo","useRef","useEffect","Signal","computed","signal","effect","batch","untracked","currentComponent","finishUpdate","hook","hookName","hookFn","bind","setCurrentUpdater","updater","_start","SignalValue","_ref","_this","this","data","currentSignal","useSignal","value","s","v","__v","__","__c","_updateFlags","_updater","_callback","_this$base","end","base","nodeType","setState","displayName","Object","defineProperties","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","peek","component","update","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","shouldComponentUpdate","state","_sources","useComputed","compute","$compute","current","useSignalEffect","cb","callback"],"mappings":"oBA+BAA,aAAAC,oBAAAC,MAAA,2BAAAC,YAAAC,eAAAC,MAAA,gCAAAC,cAAAC,YAAAC,YAAAC,MAAA,8BAAAH,OAAAI,MAAAH,SAAAE,OAAAD,OAAAG,cAAA,uBAAA,IAUIC,EACAC,EANJ,SAASC,EAA6BC,EAAaC,GAElDf,EAAQc,GAAYC,EAAOC,KAAK,KAAMhB,EAAQc,IAAc,aAC7D,CAKA,SAASG,EAAkBC,GAE1B,GAAIN,EAAcA,IAElBA,EAAeM,GAAWA,EAAQC,GACnC,CAwBA,SAASC,EAAWC,OAAqDC,EAAAC,KAAxBC,EAAIH,EAAJG,KAK1CC,EAAgBC,UAAUF,GAChCC,EAAcE,MAAQH,EAEtB,IAAMI,EAAI1B,EAAQ,WAEjB,IAAI2B,EAAIP,EAAKQ,IACb,MAAQD,EAAIA,EAAEE,GACb,GAAIF,EAAEG,IAAK,CACVH,EAAEG,IAAIC,MArDY,EAsDlB,KACA,CAGFX,EAAKY,KAAUC,EAAY,WAAK,IAAAC,EACzBC,EAAMf,EAAKY,KAAUf,IACrBQ,EAAQC,EAAED,MAChBU,IAEA,GAAIpC,EAAe0B,IAAkC,KAAf,OAATS,EAAAd,EAAKgB,WAAI,EAATF,EAAWG,UAAgB,CACvDjB,EAAKW,MAlEkB,EAmEvBX,EAAKkB,SAAS,GACd,MACClB,EAAKgB,KAAcd,KAAOG,CAE7B,EAEA,OAAOrB,EAAS,WACf,IACIsB,EADOH,EAAcE,MACZA,MACb,OAAa,IAANC,EAAU,GAAU,IAANA,EAAa,GAAKA,GAAK,EAC7C,EACD,EAAG,IAEH,OAAOA,EAAED,KACV,CACAP,EAAYqB,YAAc,MAE1BC,OAAOC,iBAAiBtC,EAAOuC,UAAW,CACzCC,YAAa,CAAEC,cAAc,EAAMnB,WAAOoB,GAC1CC,KAAM,CAAEF,cAAc,EAAMnB,MAAOP,GACnC6B,MAAO,CACNH,cAAc,EACdI,eACC,MAAO,CAAE1B,KAAMD,KAChB,GAKD4B,IAAK,CAAEL,cAAc,EAAMnB,MAAO,KAInCd,QAAwB,SAACuC,EAAKC,GAC7B,GAA0B,iBAAfA,EAAML,KAAmB,CACnC,IAAIM,EAEAL,EAAQI,EAAMJ,MAClB,IAAK,IAAIM,KAAKN,EACb,GAAU,aAANM,EAAJ,CAEA,IAAI5B,EAAQsB,EAAMM,GAClB,GAAI5B,aAAiBtB,EAAQ,CAC5B,IAAKiD,EAAaD,EAAMG,KAAOF,EAAc,CAAA,EAC7CA,EAAYC,GAAK5B,EACjBsB,EAAMM,GAAK5B,EAAM8B,MACjB,CAPqB,CASvB,CAEDL,EAAIC,EACL,GAGAxC,QAA0B,SAACuC,EAAKC,GAC/BpC,IAEA,IAAIC,EAEAwC,EAAYL,EAAMrB,IACtB,GAAI0B,EAAW,CACdA,EAAUzB,OAAgB,EAG1B,QAAgBc,KADhB7B,EAAUwC,EAAUxB,MAEnBwB,EAAUxB,KAAWhB,EAhHxB,SAAuByC,GACtB,IAAIzC,EACJV,EAAO,WACNU,EAAUK,IACX,GACAL,EAAQiB,EA2GuC,WAC5CuB,EAAUzB,MArIa,EAsIvByB,EAAUlB,SAAS,GACpB,EA7GF,OAAOtB,CACR,CAyGkC0C,EAKhC,CAEDjD,EAAmB+C,EACnBzC,EAAkBC,GAClBkC,EAAIC,EACL,GAGAxC,EAAI,MAA2B,SAACuC,EAAKS,EAAOR,EAAOS,GAClD7C,IACAN,OAAmBoC,EACnBK,EAAIS,EAAOR,EAAOS,EACnB,GAGAjD,WAA0B,SAACuC,EAAKC,GAC/BpC,IACAN,OAAmBoC,EAEnB,IAAIgB,EAIJ,GAA0B,iBAAfV,EAAML,OAAsBe,EAAMV,EAAMW,KAAiB,CACnE,IAAIf,EAAQI,EAAMG,KACdS,EAAgBZ,EAAMJ,MAC1B,GAAIA,EAAO,CACV,IAAIiB,EAAWH,EAAII,EACnB,GAAID,EACH,IAAK,IAAIE,KAAQF,EAAU,CAC1B,IAAIhD,EAAUgD,EAASE,GACvB,QAAgBrB,IAAZ7B,KAA2BkD,KAAQnB,GAAQ,CAC9C/B,EAAQmD,IAERH,EAASE,QAAQrB,CACjB,CACD,MAGDgB,EAAII,EADJD,EAAW,CAAA,EAGZ,IAAK,IAAIE,KAAQnB,EAAO,CACvB,IAAI/B,EAAUgD,EAASE,GACnB7D,EAAS0C,EAAMmB,GACnB,QAAgBrB,IAAZ7B,EAAuB,CAC1BA,EAAUoD,EAAkBP,EAAKK,EAAM7D,EAAQ0D,GAC/CC,EAASE,GAAQlD,CACjB,MACAA,EAAQqD,EAAQhE,EAAQ0D,EAEzB,CACD,CACD,CACDb,EAAIC,EACL,GAEA,SAASiB,EACRP,EACAK,EACAI,EACAvB,GAEA,IAAMwB,EACLL,KAAQL,QAIgBhB,IAAxBgB,EAAIW,gBAECC,EAAepE,EAAOiE,GAC5B,MAAO,CACND,EAAS,SAACK,EAAmBC,GAC5BF,EAAahD,MAAQiD,EACrB3B,EAAQ4B,CACT,EACAR,EAAU7D,EAAO,WAChB,IAAMmB,EAAQgD,EAAahD,MAAMA,MAEjC,GAAIsB,EAAMmB,KAAUzC,EAApB,CACAsB,EAAMmB,GAAQzC,EACd,GAAI8C,EAEHV,EAAIK,GAAQzC,OACFA,GAAAA,EACVoC,EAAIe,aAAaV,EAAMzC,QAEvBoC,EAAIgB,gBAAgBX,EAPrBnB,CASD,GAEF,CAGApC,YAA2B,SAACuC,EAAKC,GAChC,GAA0B,iBAAfA,EAAML,KAAmB,CACnC,IAAIe,EAAMV,EAAMW,IAEhB,GAAID,EAAK,CACR,IAAMG,EAAWH,EAAII,EACrB,GAAID,EAAU,CACbH,EAAII,OAAYpB,EAChB,IAAK,IAAIqB,KAAQF,EAAU,CAC1B,IAAIhD,EAAUgD,EAASE,GACvB,GAAIlD,EAASA,EAAQmD,GACrB,CACD,CACD,CACD,KAAM,CACN,IAAIX,EAAYL,EAAMrB,IACtB,GAAI0B,EAAW,CACd,IAAMxC,EAAUwC,EAAUxB,KAC1B,GAAIhB,EAAS,CACZwC,EAAUxB,UAAWa,EACrB7B,EAAQmD,GACR,CACD,CACD,CACDjB,EAAIC,EACL,GAGAxC,EAAI,MAAoB,SAACuC,EAAKM,EAAWsB,EAAOhC,GAC/C,GAAIA,EAAO,GAAc,IAATA,EACdU,EAAiCzB,MAnQb,EAoQtBmB,EAAIM,EAAWsB,EAAOhC,EACvB,GAMAjD,EAAU6C,UAAUqC,sBAAwB,SAE3ChC,EACAiC,GAGA,IAAMhE,EAAUK,KAAKW,KA0BrB,KAzBmBhB,QAAgC6B,IAArB7B,EAAQiE,GAjRjB,EA0SA5D,KAAKU,MAA+B,SAIzD,GAAqB,EAAjBV,KAAKU,KAAsD,OAAO,EAGtE,IAAK,IAAIsB,KAAK2B,EAAO,OAAO,EAG5B,IAAK,IAAI3B,KAAKN,EACb,GAAU,aAANM,GAAoBN,EAAMM,KAAOhC,KAAK0B,MAAMM,GAAI,OACpD,EACD,IAAK,IAAIA,KAAKhC,KAAK0B,MAAO,KAAMM,KAAKN,GAAQ,OAAO,EAGpD,OAAO,CACR,WAIgBvB,UAAaC,GAC5B,OAAOzB,EAAQ,kBAAMK,EAAsBoB,EAAM,EAAE,GACpD,UAEgByD,YAAeC,GAC9B,IAAMC,EAAWnF,EAAOkF,GACxBC,EAASC,QAAUF,EAClB1E,EAAwCsB,MAtUpB,EAuUrB,OAAO/B,EAAQ,WAAA,OAAMI,EAAY,WAAM,OAAAgF,EAASC,SAAS,EAAC,EAAE,GAC7D,UAEgBC,gBAAgBC,GAC/B,IAAMC,EAAWvF,EAAOsF,GACxBC,EAASH,QAAUE,EAEnBrF,EAAU,WACT,OAAOI,EAAO,WAAA,OAAMkF,EAASH,SAAS,EACvC,EAAG,GACJ,QAAAH,YAAA1D,UAAA8D"}
1
+ {"version":3,"file":"signals.module.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component, isValidElement } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n} from \"@preact/signals-core\";\nimport {\n\tVNode,\n\tOptionsTypes,\n\tHookFn,\n\tEffect,\n\tPropertyUpdater,\n\tAugmentedComponent,\n\tAugmentedElement as Element,\n} from \"./internal\";\n\nexport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\n\tuntracked,\n};\n\nconst HAS_PENDING_UPDATE = 1 << 0;\nconst HAS_HOOK_STATE = 1 << 1;\nconst HAS_COMPUTEDS = 1 << 2;\n\n// Install a Preact options hook\nfunction hook<T extends OptionsTypes>(hookName: T, hookFn: HookFn<T>) {\n\t// @ts-ignore-next-line private options hooks usage\n\toptions[hookName] = hookFn.bind(null, options[hookName] || (() => {}));\n}\n\nlet currentComponent: AugmentedComponent | undefined;\nlet finishUpdate: (() => void) | undefined;\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/** @todo This may be needed for complex prop value detection. */\n// function isSignalValue(value: any): value is Signal {\n// \tif (typeof value !== \"object\" || value == null) return false;\n// \tif (value instanceof Signal) return true;\n// \t// @TODO: uncomment this when we land Reactive (ideally behind a brand check)\n// \t// for (let i in value) if (value[i] instanceof Signal) return true;\n// \treturn false;\n// }\n\n/**\n * A wrapper component that renders a Signal directly as a Text node.\n * @todo: in Preact 11, just decorate Signal with `type:null`\n */\nfunction SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {\n\t// hasComputeds.add(this);\n\n\t// Store the props.data signal in another signal so that\n\t// passing a new signal reference re-runs the text computed:\n\tconst currentSignal = useSignal(data);\n\tcurrentSignal.value = data;\n\n\tconst s = useMemo(() => {\n\t\tlet self = this;\n\t\t// mark the parent component as having computeds so it gets optimized\n\t\tlet v = this.__v;\n\t\twhile ((v = v.__!)) {\n\t\t\tif (v.__c) {\n\t\t\t\tv.__c._updateFlags |= HAS_COMPUTEDS;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst wrappedSignal = computed(function (this: Effect) {\n\t\t\tlet data = currentSignal.value;\n\t\t\tlet s = data.value;\n\t\t\treturn s === 0 ? 0 : s === true ? \"\" : s || \"\";\n\t\t});\n\n\t\tconst isText = computed(\n\t\t\t() => isValidElement(wrappedSignal.value) || this.base?.nodeType !== 3\n\t\t);\n\n\t\tthis._updater!._callback = () => {\n\t\t\tif (isValidElement(s.peek()) || this.base?.nodeType !== 3) {\n\t\t\t\tthis._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tthis.setState({});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t(this.base as Text).data = s.peek();\n\t\t};\n\n\t\teffect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst val = wrappedSignal.value;\n\t\t\tif (isText.value && self.base) {\n\t\t\t\t(self.base as Text).data = val;\n\t\t\t}\n\t\t});\n\n\t\treturn wrappedSignal;\n\t}, []);\n\n\treturn s.value;\n}\nSignalValue.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: SignalValue },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\t// Setting a VNode's _depth to 1 forces Preact to clone it before modifying:\n\t// https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77\n\t// @todo remove this for Preact 11\n\t__b: { configurable: true, value: 1 },\n});\n\n/** Inject low-level property/attribute bindings for Signals into Preact's diff */\nhook(OptionsTypes.DIFF, (old, vnode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet signalProps: Record<string, any> | undefined;\n\n\t\tlet props = vnode.props;\n\t\tfor (let i in props) {\n\t\t\tif (i === \"children\") continue;\n\n\t\t\tlet value = props[i];\n\t\t\tif (value instanceof Signal) {\n\t\t\t\tif (!signalProps) vnode.__np = signalProps = {};\n\t\t\t\tsignalProps[i] = value;\n\t\t\t\tprops[i] = value.peek();\n\t\t\t}\n\t\t}\n\t}\n\n\told(vnode);\n});\n\n/** Set up Updater before rendering a component */\nhook(OptionsTypes.RENDER, (old, vnode) => {\n\tsetCurrentUpdater();\n\n\tlet updater;\n\n\tlet component = vnode.__c;\n\tif (component) {\n\t\tcomponent._updateFlags &= ~HAS_PENDING_UPDATE;\n\n\t\tupdater = component._updater;\n\t\tif (updater === undefined) {\n\t\t\tcomponent._updater = updater = createUpdater(() => {\n\t\t\t\tcomponent._updateFlags |= HAS_PENDING_UPDATE;\n\t\t\t\tcomponent.setState({});\n\t\t\t});\n\t\t}\n\t}\n\n\tcurrentComponent = component;\n\tsetCurrentUpdater(updater);\n\told(vnode);\n});\n\n/** Finish current updater if a component errors */\nhook(OptionsTypes.CATCH_ERROR, (old, error, vnode, oldVNode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\told(error, vnode, oldVNode);\n});\n\n/** Finish current updater after rendering any VNode */\nhook(OptionsTypes.DIFFED, (old, vnode) => {\n\tsetCurrentUpdater();\n\tcurrentComponent = undefined;\n\n\tlet dom: Element;\n\n\t// vnode._dom is undefined during string rendering,\n\t// so we use this to skip prop subscriptions during SSR.\n\tif (typeof vnode.type === \"string\" && (dom = vnode.__e as Element)) {\n\t\tlet props = vnode.__np;\n\t\tlet renderedProps = vnode.props;\n\t\tif (props) {\n\t\t\tlet updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater !== undefined && !(prop in props)) {\n\t\t\t\t\t\tupdater._dispose();\n\t\t\t\t\t\t// @todo we could just always invoke _dispose() here\n\t\t\t\t\t\tupdaters[prop] = undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tupdaters = {};\n\t\t\t\tdom._updaters = updaters;\n\t\t\t}\n\t\t\tfor (let prop in props) {\n\t\t\t\tlet updater = updaters[prop];\n\t\t\t\tlet signal = props[prop];\n\t\t\t\tif (updater === undefined) {\n\t\t\t\t\tupdater = createPropUpdater(dom, prop, signal, renderedProps);\n\t\t\t\t\tupdaters[prop] = updater;\n\t\t\t\t} else {\n\t\t\t\t\tupdater._update(signal, renderedProps);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\nfunction createPropUpdater(\n\tdom: Element,\n\tprop: string,\n\tpropSignal: Signal,\n\tprops: Record<string, any>\n): PropertyUpdater {\n\tconst setAsProperty =\n\t\tprop in dom &&\n\t\t// SVG elements need to go through `setAttribute` because they\n\t\t// expect things like SVGAnimatedTransformList instead of strings.\n\t\t// @ts-ignore\n\t\tdom.ownerSVGElement === undefined;\n\n\tconst changeSignal = signal(propSignal);\n\treturn {\n\t\t_update: (newSignal: Signal, newProps: typeof props) => {\n\t\t\tchangeSignal.value = newSignal;\n\t\t\tprops = newProps;\n\t\t},\n\t\t_dispose: effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyDomUpdates;\n\t\t\tconst value = changeSignal.value.value;\n\t\t\t// If Preact just rendered this value, don't render it again:\n\t\t\tif (props[prop] === value) return;\n\t\t\tprops[prop] = value;\n\t\t\tif (setAsProperty) {\n\t\t\t\t// @ts-ignore-next-line silly\n\t\t\t\tdom[prop] = value;\n\t\t\t} else if (value) {\n\t\t\t\tdom.setAttribute(prop, value);\n\t\t\t} else {\n\t\t\t\tdom.removeAttribute(prop);\n\t\t\t}\n\t\t}),\n\t};\n}\n\n/** Unsubscribe from Signals when unmounting components/vnodes */\nhook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {\n\tif (typeof vnode.type === \"string\") {\n\t\tlet dom = vnode.__e as Element | undefined;\n\t\t// vnode._dom is undefined during string rendering\n\t\tif (dom) {\n\t\t\tconst updaters = dom._updaters;\n\t\t\tif (updaters) {\n\t\t\t\tdom._updaters = undefined;\n\t\t\t\tfor (let prop in updaters) {\n\t\t\t\t\tlet updater = updaters[prop];\n\t\t\t\t\tif (updater) updater._dispose();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlet component = vnode.__c;\n\t\tif (component) {\n\t\t\tconst updater = component._updater;\n\t\t\tif (updater) {\n\t\t\t\tcomponent._updater = undefined;\n\t\t\t\tupdater._dispose();\n\t\t\t}\n\t\t}\n\t}\n\told(vnode);\n});\n\n/** Mark components that use hook state so we can skip sCU optimization. */\nhook(OptionsTypes.HOOK, (old, component, index, type) => {\n\tif (type < 3 || type === 9)\n\t\t(component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;\n\told(component, index, type);\n});\n\n/**\n * Auto-memoize components that use Signals/Computeds.\n * Note: Does _not_ optimize components that use hook/class state.\n */\nComponent.prototype.shouldComponentUpdate = function (\n\tthis: AugmentedComponent,\n\tprops,\n\tstate\n) {\n\t// @todo: Once preactjs/preact#3671 lands, this could just use `currentUpdater`:\n\tconst updater = this._updater;\n\tconst hasSignals = updater && updater._sources !== undefined;\n\n\t// let reason;\n\t// if (!hasSignals && !hasComputeds.has(this)) {\n\t// \treason = \"no signals or computeds\";\n\t// } else if (hasPendingUpdate.has(this)) {\n\t// \treason = \"has pending update\";\n\t// } else if (hasHookState.has(this)) {\n\t// \treason = \"has hook state\";\n\t// }\n\t// if (reason) {\n\t// \tif (!this) reason += \" (`this` bug)\";\n\t// \tconsole.log(\"not optimizing\", this?.constructor?.name, \": \", reason, {\n\t// \t\tdetails: {\n\t// \t\t\thasSignals,\n\t// \t\t\thasComputeds: hasComputeds.has(this),\n\t// \t\t\thasPendingUpdate: hasPendingUpdate.has(this),\n\t// \t\t\thasHookState: hasHookState.has(this),\n\t// \t\t\tdeps: Array.from(updater._deps),\n\t// \t\t\tupdater,\n\t// \t\t},\n\t// \t});\n\t// }\n\n\t// if this component used no signals or computeds, update:\n\tif (!hasSignals && !(this._updateFlags & HAS_COMPUTEDS)) return true;\n\n\t// if there is a pending re-render triggered from Signals,\n\t// or if there is hook or class state, update:\n\tif (this._updateFlags & (HAS_PENDING_UPDATE | HAS_HOOK_STATE)) return true;\n\n\t// @ts-ignore\n\tfor (let i in state) return true;\n\n\t// if any non-Signal props changed, update:\n\tfor (let i in props) {\n\t\tif (i !== \"__source\" && props[i] !== this.props[i]) return true;\n\t}\n\tfor (let i in this.props) if (!(i in props)) return true;\n\n\t// this is a purely Signal-driven component, don't update:\n\treturn false;\n};\n\nexport function useSignal<T>(value: T): Signal<T>;\nexport function useSignal<T = undefined>(): Signal<T | undefined>;\nexport function useSignal<T>(value?: T) {\n\treturn useMemo(() => signal<T | undefined>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\t(currentComponent as AugmentedComponent)._updateFlags |= HAS_COMPUTEDS;\n\treturn useMemo(() => computed<T>(() => $compute.current()), []);\n}\n\nlet oldNotify: (this: Effect) => void,\n\teffectsQueue: Array<Effect> = [],\n\tdomQueue: Array<Effect> = [];\n\nconst deferEffects =\n\ttypeof requestAnimationFrame === \"undefined\"\n\t\t? setTimeout\n\t\t: requestAnimationFrame;\n\nconst deferDomUpdates = (cb: any) => {\n\tqueueMicrotask(() => {\n\t\tqueueMicrotask(cb);\n\t});\n};\n\nfunction flushEffects() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = effectsQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyEffects(this: Effect) {\n\tif (effectsQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferEffects)(flushEffects);\n\t}\n}\n\nfunction flushDomUpdates() {\n\tbatch(() => {\n\t\tlet inst: Effect | undefined;\n\t\twhile ((inst = domQueue.shift())) {\n\t\t\toldNotify.call(inst);\n\t\t}\n\t});\n}\n\nfunction notifyDomUpdates(this: Effect) {\n\tif (domQueue.push(this) === 1) {\n\t\t(options.requestAnimationFrame || deferDomUpdates)(flushDomUpdates);\n\t}\n}\n\nexport function useSignalEffect(cb: () => void | (() => void)) {\n\tconst callback = useRef(cb);\n\tcallback.current = cb;\n\n\tuseEffect(() => {\n\t\treturn effect(function (this: Effect) {\n\t\t\tif (!oldNotify) oldNotify = this._notify;\n\t\t\tthis._notify = notifyEffects;\n\t\t\treturn callback.current();\n\t\t});\n\t}, []);\n}\n\n/**\n * @todo Determine which Reactive implementation we'll be using.\n * @internal\n */\n// export function useReactive<T extends object>(value: T): Reactive<T> {\n// \treturn useMemo(() => reactive<T>(value), []);\n// }\n\n/**\n * @internal\n * Update a Reactive's using the properties of an object or other Reactive.\n * Also works for Signals.\n * @example\n * // Update a Reactive with Object.assign()-like syntax:\n * const r = reactive({ name: \"Alice\" });\n * update(r, { name: \"Bob\" });\n * update(r, { age: 42 }); // property 'age' does not exist in type '{ name?: string }'\n * update(r, 2); // '2' has no properties in common with '{ name?: string }'\n * console.log(r.name.value); // \"Bob\"\n *\n * @example\n * // Update a Reactive with the properties of another Reactive:\n * const A = reactive({ name: \"Alice\" });\n * const B = reactive({ name: \"Bob\", age: 42 });\n * update(A, B);\n * console.log(`${A.name} is ${A.age}`); // \"Bob is 42\"\n *\n * @example\n * // Update a signal with assign()-like syntax:\n * const s = signal(42);\n * update(s, \"hi\"); // Argument type 'string' not assignable to type 'number'\n * update(s, {}); // Argument type '{}' not assignable to type 'number'\n * update(s, 43);\n * console.log(s.value); // 43\n *\n * @param obj The Reactive or Signal to be updated\n * @param update The value, Signal, object or Reactive to update `obj` to match\n * @param overwrite If `true`, any properties `obj` missing from `update` are set to `undefined`\n */\n/*\nexport function update<T extends SignalOrReactive>(\n\tobj: T,\n\tupdate: Partial<Unwrap<T>>,\n\toverwrite = false\n) {\n\tif (obj instanceof Signal) {\n\t\tobj.value = peekValue(update);\n\t} else {\n\t\tfor (let i in update) {\n\t\t\tif (i in obj) {\n\t\t\t\tobj[i].value = peekValue(update[i]);\n\t\t\t} else {\n\t\t\t\tlet sig = signal(peekValue(update[i]));\n\t\t\t\tsig[KEY] = i;\n\t\t\t\tobj[i] = sig;\n\t\t\t}\n\t\t}\n\t\tif (overwrite) {\n\t\t\tfor (let i in obj) {\n\t\t\t\tif (!(i in update)) {\n\t\t\t\t\tobj[i].value = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n*/\n"],"names":["currentComponent","finishUpdate","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","_start","SignalValue","_ref","_this","this","data","currentSignal","useSignal","value","s","useMemo","self","v","__v","__","__c","_updateFlags","wrappedSignal","computed","isText","_this$base","isValidElement","base","nodeType","_updater","_callback","_this$base2","peek","setState","effect","oldNotify","_notify","notifyDomUpdates","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","component","update","createUpdater","error","oldVNode","dom","__e","renderedProps","updaters","_updaters","prop","_dispose","signal","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","Component","shouldComponentUpdate","state","_sources","useComputed","compute","$compute","useRef","current","effectsQueue","domQueue","deferEffects","requestAnimationFrame","setTimeout","deferDomUpdates","cb","queueMicrotask","flushEffects","batch","inst","shift","call","notifyEffects","push","flushDomUpdates","useSignalEffect","callback","useEffect"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preact/signals",
3
- "version": "1.3.1",
3
+ "version": "2.0.0",
4
4
  "license": "MIT",
5
5
  "description": "Manage state with style in Preact",
6
6
  "keywords": [],
package/src/index.ts CHANGED
@@ -80,6 +80,7 @@ function SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {
80
80
  currentSignal.value = data;
81
81
 
82
82
  const s = useMemo(() => {
83
+ let self = this;
83
84
  // mark the parent component as having computeds so it gets optimized
84
85
  let v = this.__v;
85
86
  while ((v = v.__!)) {
@@ -89,24 +90,35 @@ function SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {
89
90
  }
90
91
  }
91
92
 
92
- this._updater!._callback = () => {
93
- const end = this._updater!._start();
94
- const value = s.value;
95
- end();
93
+ const wrappedSignal = computed(function (this: Effect) {
94
+ let data = currentSignal.value;
95
+ let s = data.value;
96
+ return s === 0 ? 0 : s === true ? "" : s || "";
97
+ });
96
98
 
97
- if (isValidElement(value) || this.base?.nodeType !== 3) {
99
+ const isText = computed(
100
+ () => isValidElement(wrappedSignal.value) || this.base?.nodeType !== 3
101
+ );
102
+
103
+ this._updater!._callback = () => {
104
+ if (isValidElement(s.peek()) || this.base?.nodeType !== 3) {
98
105
  this._updateFlags |= HAS_PENDING_UPDATE;
99
106
  this.setState({});
100
- } else {
101
- (this.base as Text).data = value;
107
+ return;
102
108
  }
109
+ (this.base as Text).data = s.peek();
103
110
  };
104
111
 
105
- return computed(() => {
106
- let data = currentSignal.value;
107
- let s = data.value;
108
- return s === 0 ? 0 : s === true ? "" : s || "";
112
+ effect(function (this: Effect) {
113
+ if (!oldNotify) oldNotify = this._notify;
114
+ this._notify = notifyDomUpdates;
115
+ const val = wrappedSignal.value;
116
+ if (isText.value && self.base) {
117
+ (self.base as Text).data = val;
118
+ }
109
119
  });
120
+
121
+ return wrappedSignal;
110
122
  }, []);
111
123
 
112
124
  return s.value;
@@ -241,7 +253,9 @@ function createPropUpdater(
241
253
  changeSignal.value = newSignal;
242
254
  props = newProps;
243
255
  },
244
- _dispose: effect(() => {
256
+ _dispose: effect(function (this: Effect) {
257
+ if (!oldNotify) oldNotify = this._notify;
258
+ this._notify = notifyDomUpdates;
245
259
  const value = changeSignal.value.value;
246
260
  // If Preact just rendered this value, don't render it again:
247
261
  if (props[prop] === value) return;
@@ -361,12 +375,61 @@ export function useComputed<T>(compute: () => T) {
361
375
  return useMemo(() => computed<T>(() => $compute.current()), []);
362
376
  }
363
377
 
378
+ let oldNotify: (this: Effect) => void,
379
+ effectsQueue: Array<Effect> = [],
380
+ domQueue: Array<Effect> = [];
381
+
382
+ const deferEffects =
383
+ typeof requestAnimationFrame === "undefined"
384
+ ? setTimeout
385
+ : requestAnimationFrame;
386
+
387
+ const deferDomUpdates = (cb: any) => {
388
+ queueMicrotask(() => {
389
+ queueMicrotask(cb);
390
+ });
391
+ };
392
+
393
+ function flushEffects() {
394
+ batch(() => {
395
+ let inst: Effect | undefined;
396
+ while ((inst = effectsQueue.shift())) {
397
+ oldNotify.call(inst);
398
+ }
399
+ });
400
+ }
401
+
402
+ function notifyEffects(this: Effect) {
403
+ if (effectsQueue.push(this) === 1) {
404
+ (options.requestAnimationFrame || deferEffects)(flushEffects);
405
+ }
406
+ }
407
+
408
+ function flushDomUpdates() {
409
+ batch(() => {
410
+ let inst: Effect | undefined;
411
+ while ((inst = domQueue.shift())) {
412
+ oldNotify.call(inst);
413
+ }
414
+ });
415
+ }
416
+
417
+ function notifyDomUpdates(this: Effect) {
418
+ if (domQueue.push(this) === 1) {
419
+ (options.requestAnimationFrame || deferDomUpdates)(flushDomUpdates);
420
+ }
421
+ }
422
+
364
423
  export function useSignalEffect(cb: () => void | (() => void)) {
365
424
  const callback = useRef(cb);
366
425
  callback.current = cb;
367
426
 
368
427
  useEffect(() => {
369
- return effect(() => callback.current());
428
+ return effect(function (this: Effect) {
429
+ if (!oldNotify) oldNotify = this._notify;
430
+ this._notify = notifyEffects;
431
+ return callback.current();
432
+ });
370
433
  }, []);
371
434
  }
372
435
 
package/src/internal.d.ts CHANGED
@@ -4,6 +4,7 @@ import { Signal } from "@preact/signals-core";
4
4
  export interface Effect {
5
5
  _sources: object | undefined;
6
6
  _start(): () => void;
7
+ _notify: () => void;
7
8
  _callback(): void;
8
9
  _dispose(): void;
9
10
  }