@preact/signals 1.1.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @preact/signals
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#387](https://github.com/preactjs/signals/pull/387) [`6e4dab4`](https://github.com/preactjs/signals/commit/6e4dab4e8c99217aa2837037a5fc82ee852ee288) Thanks [@XantreGodlike](https://github.com/XantreGodlike)! - Removed difference in behaviour between adapters, signals that use a JSX value will correctly re-render the whole component rather than attempting the JSX-Text optimization.
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`256a331`](https://github.com/preactjs/signals/commit/256a331b5335e54f7e918b3f1068fb9d92d1c613)]:
12
+ - @preact/signals-core@1.4.0
13
+
14
+ ## 1.1.5
15
+
16
+ ### Patch Changes
17
+
18
+ - [#381](https://github.com/preactjs/signals/pull/381) [`e655e7f`](https://github.com/preactjs/signals/commit/e655e7f86c321dca12e760e21c01f2dbfafade47) Thanks [@JoviDeCroock](https://github.com/JoviDeCroock)! - Allow for context to propagate to components using context
19
+
3
20
  ## 1.1.4
4
21
 
5
22
  ### Patch Changes
package/README.md CHANGED
@@ -19,6 +19,7 @@ npm install @preact/signals
19
19
  - [`computed(fn)`](../../README.md#computedfn)
20
20
  - [`effect(fn)`](../../README.md#effectfn)
21
21
  - [`batch(fn)`](../../README.md#batchfn)
22
+ - [`untracked(fn)`](../../README.md#untrackedfn)
22
23
  - [Preact Integration](#preact-integration)
23
24
  - [Hooks](#hooks)
24
25
  - [Rendering optimizations](#rendering-optimizations)
package/dist/signals.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { signal, computed, batch, effect, Signal, type ReadonlySignal } from "@preact/signals-core";
2
- export { signal, computed, batch, effect, Signal, type ReadonlySignal };
1
+ import { signal, computed, batch, effect, Signal, type ReadonlySignal, untracked } from "@preact/signals-core";
2
+ export { signal, computed, batch, effect, Signal, type ReadonlySignal, untracked, };
3
3
  export declare function useSignal<T>(value: T): Signal<T>;
4
4
  export declare function useComputed<T>(compute: () => T): ReadonlySignal<T>;
5
5
  export declare function useSignalEffect(cb: () => void | (() => void)): void;
package/dist/signals.js CHANGED
@@ -1 +1 @@
1
- var r,n,i=require("preact"),t=require("preact/hooks"),f=require("@preact/signals-core");function o(r,n){i.options[r]=n.bind(null,i.options[r]||function(){})}function e(r){if(n)n();n=r&&r.S()}function u(r){var n=this,i=r.data,o=useSignal(i);o.value=i;var e=t.useMemo(function(){var r=n.__v;while(r=r.__)if(r.__c){r.__c.__$f|=4;break}n.__$u.c=function(){n.base.data=e.peek()};return f.computed(function(){var r=o.value.value;return 0===r?0:!0===r?"":r||""})},[]);return e.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,n){if("string"==typeof n.type){var i,t=n.props;for(var o in t)if("children"!==o){var e=t[o];if(e instanceof f.Signal){if(!i)n.__np=i={};i[o]=e;t[o]=e.peek()}}}r(n)});o("__r",function(n,i){e();var t,o=i.__c;if(o){o.__$f&=-2;if(void 0===(t=o.__$u))o.__$u=t=function(r){var n;f.effect(function(){n=this});n.c=function(){o.__$f|=1;o.setState({})};return n}()}r=o;e(t);n(i)});o("__e",function(n,i,t,f){e();r=void 0;n(i,t,f)});o("diffed",function(n,i){e();r=void 0;var t;if("string"==typeof i.type&&(t=i.__e)){var f=i.__np,o=i.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 p=u[s],d=f[s];if(void 0===p){p=a(t,s,d,o);u[s]=p}else p.o(d,o)}}}n(i)});function a(r,n,i,t){var o=n in r&&void 0===r.ownerSVGElement,e=f.signal(i);return{o:function(r,n){e.value=r;t=n},d:f.effect(function(){var i=e.value.value;if(t[n]!==i){t[n]=i;if(o)r[n]=i;else if(i)r.setAttribute(n,i);else r.removeAttribute(n)}})}}o("unmount",function(r,n){if("string"==typeof n.type){var i=n.__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=n.__c;if(e){var u=e.__$u;if(u){e.__$u=void 0;u.d()}}}r(n)});o("__h",function(r,n,i,t){if(t<3)n.__$f|=2;r(n,i,t)});i.Component.prototype.shouldComponentUpdate=function(r,n){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 n)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.useComputed=function(n){var i=t.useRef(n);i.current=n;r.__$f|=4;return t.useMemo(function(){return f.computed(function(){return i.current()})},[])};exports.useSignal=useSignal;exports.useSignalEffect=function(r){var n=t.useRef(r);n.current=r;t.useEffect(function(){return f.effect(function(){return n.current()})},[])};//# sourceMappingURL=signals.js.map
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;if(!n.isValidElement(u.peek())&&3===(null==(r=i.base)?void 0:r.nodeType))i.base.data=u.peek();else{i.__$f|=1;i.setState({})}};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 +1 @@
1
- {"version":3,"file":"signals.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\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 { signal, computed, batch, effect, Signal, type ReadonlySignal };\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 Text(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\t// Replace this component's vdom updater with a direct text one:\n\t\tthis._updater!._callback = () => {\n\t\t\t(this.base as Text).data = s.peek();\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}\nText.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: Text },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\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)\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","preact","require","hooks","signalsCore","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","finishUpdate","_start","Text","_ref","data","currentSignal","useSignal","value","s","useMemo","v","_this","__v","__","__c","_updateFlags","_updater","_callback","base","peek","computed","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","this","__b","old","vnode","i","signalProps","__np","component","update","effect","setState","createUpdater","error","oldVNode","dom","__e","renderedProps","_updaters","updaters","prop","_dispose","_signal","createPropUpdater","signal","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","_updater2","index","Component","shouldComponentUpdate","state","_sources","HAS_PENDING_UPDATE","_i","exports","batch","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\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\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\n\t\t\t(this.base as Text).data = s.peek();\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","isValidElement","peek","base","nodeType","setState","computed","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","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 +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.hooks,n.signalsCore)}(this,function(n,i,r,t){var f,e;function o(n,r){i.options[n]=r.bind(null,i.options[n]||function(){})}function u(n){if(e)e();e=n&&n.S()}function a(n){var i=this,f=n.data,e=useSignal(f);e.value=f;var o=r.useMemo(function(){var n=i.__v;while(n=n.__)if(n.__c){n.__c.__$f|=4;break}i.__$u.c=function(){i.base.data=o.peek()};return t.computed(function(){var n=e.value.value;return 0===n?0:!0===n?"":n||""})},[]);return o.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,f=i.props;for(var e in f)if("children"!==e){var o=f[e];if(o instanceof t.Signal){if(!r)i.__np=r={};r[e]=o;f[e]=o.peek()}}}n(i)});o("__r",function(n,i){u();var r,e=i.__c;if(e){e.__$f&=-2;if(void 0===(r=e.__$u))e.__$u=r=function(n){var i;t.effect(function(){i=this});i.c=function(){e.__$f|=1;e.setState({})};return i}()}f=e;u(r);n(i)});o("__e",function(n,i,r,t){u();f=void 0;n(i,r,t)});o("diffed",function(n,i){u();f=void 0;var r;if("string"==typeof i.type&&(r=i.__e)){var t=i.__np,e=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 d=o[s],l=t[s];if(void 0===d){d=c(r,s,l,e);o[s]=d}else d.o(l,e)}}}n(i)});function c(n,i,r,f){var e=i in n&&void 0===n.ownerSVGElement,o=t.signal(r);return{o:function(n,i){o.value=n;f=i},d:t.effect(function(){var r=o.value.value;if(f[i]!==r){f[i]=r;if(e)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 f in t){var e=t[f];if(e)e.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)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 f in n)if("__source"!==f&&n[f]!==this.props[f])return!0;for(var e in this.props)if(!(e 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.useComputed=function(n){var i=r.useRef(n);i.current=n;f.__$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(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.hooks,n.signalsCore)}(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;if(!i.isValidElement(u.peek())&&3===(null==(n=e.base)?void 0:n.nodeType))e.base.data=u.peek();else{e.__$f|=1;e.setState({})}};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 +1 @@
1
- {"version":3,"file":"signals.min.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\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 { signal, computed, batch, effect, Signal, type ReadonlySignal };\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 Text(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\t// Replace this component's vdom updater with a direct text one:\n\t\tthis._updater!._callback = () => {\n\t\t\t(this.base as Text).data = s.peek();\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}\nText.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: Text },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\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)\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","hooks","signalsCore","this","currentComponent","hook","hookName","hookFn","options","bind","setCurrentUpdater","updater","finishUpdate","_start","Text","_ref","data","currentSignal","useSignal","value","s","useMemo","v","_this","__v","__","__c","_updateFlags","_updater","_callback","base","peek","computed","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","i","signalProps","__np","component","update","effect","setState","createUpdater","error","oldVNode","dom","__e","renderedProps","_updaters","updaters","prop","_dispose","_signal","createPropUpdater","signal","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","_updater2","index","Component","shouldComponentUpdate","state","_sources","HAS_PENDING_UPDATE","_i","batch","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\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\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\n\t\t\t(this.base as Text).data = s.peek();\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","hooks","signalsCore","this","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","isValidElement","peek","base","nodeType","setState","computed","displayName","Object","defineProperties","Signal","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","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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"}
package/dist/signals.mjs CHANGED
@@ -1 +1 @@
1
- import{Component as t,options as i}from"preact";import{useMemo as e,useRef as n,useEffect as o}from"preact/hooks";import{Signal as r,computed as f,signal as l,effect as s}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";function c(t,e){i[t]=e.bind(null,i[t]||(()=>{}))}let u,a;function d(t){if(a)a();a=t&&t.S()}function p({data:t}){const i=useSignal(t);i.value=t;const n=e(()=>{let t=this.__v;while(t=t.__)if(t.__c){t.__c.__$f|=4;break}this.__$u.c=()=>{this.base.data=n.peek()};return f(()=>{let t=i.value.value;return 0===t?0:!0===t?"":t||""})},[]);return n.value}p.displayName="_st";Object.defineProperties(r.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:p},props:{configurable:!0,get(){return{data:this}}},__b:{configurable:!0,value:1}});c("__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)});c("__r",(t,i)=>{d();let e,n=i.__c;if(n){n.__$f&=-2;e=n.__$u;if(void 0===e)n.__$u=e=function(t){let i;s(function(){i=this});i.c=()=>{n.__$f|=1;n.setState({})};return i}()}u=n;d(e);t(i)});c("__e",(t,i,e,n)=>{d();u=void 0;t(i,e,n)});c("diffed",(t,i)=>{d();u=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=h(e,o,f,n);i[o]=r}else r.o(f,n)}}}t(i)});function h(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:s(()=>{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)}})}}c("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)});c("__h",(t,i,e,n)=>{if(n<3)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 e(()=>l(t),[])}function useComputed(t){const i=n(t);i.current=t;u.__$f|=4;return e(()=>f(()=>i.current()),[])}function useSignalEffect(t){const i=n(t);i.current=t;o(()=>s(()=>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 r}from"preact/hooks";import{Signal as f,computed as l,signal as s,effect as u}from"@preact/signals-core";export{Signal,batch,computed,effect,signal,untracked}from"@preact/signals-core";function c(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;if(!e(o.peek())&&3===(null==(t=this.base)?void 0:t.nodeType))this.base.data=o.peek();else{this.__$f|=1;this.setState({})}};return l(()=>{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}});c("__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)});c("__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;u(function(){i=this});i.c=()=>{n.__$f|=1;n.setState({})};return i}()}a=n;h(e);t(i)});c("__e",(t,i,e,n)=>{h();a=void 0;t(i,e,n)});c("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=s(e);return{o:(t,i)=>{r.value=t;n=i},d:u(()=>{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)}})}}c("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)});c("__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(()=>s(t),[])}function useComputed(t){const i=o(t);i.current=t;a.__$f|=4;return n(()=>l(()=>i.current()),[])}function useSignalEffect(t){const i=o(t);i.current=t;r(()=>u(()=>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 } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\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 { signal, computed, batch, effect, Signal, type ReadonlySignal };\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 Text(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\t// Replace this component's vdom updater with a direct text one:\n\t\tthis._updater!._callback = () => {\n\t\t\t(this.base as Text).data = s.peek();\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}\nText.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: Text },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\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)\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","useMemo","useRef","useEffect","Signal","computed","signal","effect","batch","hook","hookName","hookFn","bind","currentComponent","finishUpdate","setCurrentUpdater","updater","_start","Text","data","currentSignal","useSignal","value","s","v","this","__v","__","__c","_updateFlags","_updater","_callback","base","peek","displayName","Object","defineProperties","prototype","constructor","configurable","undefined","type","props","get","__b","old","vnode","signalProps","i","__np","component","update","setState","createUpdater","error","oldVNode","dom","__e","updaters","_updaters","prop","_dispose","createPropUpdater","renderedProps","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","index","shouldComponentUpdate","state","_sources","HAS_PENDING_UPDATE","compute","$compute","current","useSignalEffect","cb","callback","useComputed"],"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\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\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\n\t\t\t(this.base as Text).data = s.peek();\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","peek","base","nodeType","setState","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","useSignalEffect","cb","callback"],"mappings":"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"}
@@ -1 +1 @@
1
- import{Component as n,options as r}from"preact";import{useMemo as i,useRef as t,useEffect as f}from"preact/hooks";import{Signal as o,computed as e,signal as u,effect as a}from"@preact/signals-core";export{Signal,batch,computed,effect,signal}from"@preact/signals-core";var c,v;function s(n,i){r[n]=i.bind(null,r[n]||function(){})}function l(n){if(v)v();v=n&&n.S()}function d(n){var r=this,t=n.data,f=useSignal(t);f.value=t;var o=i(function(){var n=r.__v;while(n=n.__)if(n.__c){n.__c.__$f|=4;break}r.__$u.c=function(){r.base.data=o.peek()};return e(function(){var n=f.value.value;return 0===n?0:!0===n?"":n||""})},[]);return o.value}d.displayName="_st";Object.defineProperties(o.prototype,{constructor:{configurable:!0,value:void 0},type:{configurable:!0,value:d},props:{configurable:!0,get:function(){return{data:this}}},__b:{configurable:!0,value:1}});s("__b",function(n,r){if("string"==typeof r.type){var i,t=r.props;for(var f in t)if("children"!==f){var e=t[f];if(e instanceof o){if(!i)r.__np=i={};i[f]=e;t[f]=e.peek()}}}n(r)});s("__r",function(n,r){l();var i,t=r.__c;if(t){t.__$f&=-2;if(void 0===(i=t.__$u))t.__$u=i=function(n){var r;a(function(){r=this});r.c=function(){t.__$f|=1;t.setState({})};return r}()}c=t;l(i);n(r)});s("__e",function(n,r,i,t){l();c=void 0;n(r,i,t)});s("diffed",function(n,r){l();c=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 v=o[a],s=t[a];if(void 0===v){v=p(i,a,s,f);o[a]=v}else v.o(s,f)}}}n(r)});function p(n,r,i,t){var f=r in n&&void 0===n.ownerSVGElement,o=u(i);return{o:function(n,r){o.value=n;t=r},d:a(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)}})}}s("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)});s("__h",function(n,r,i,t){if(t<3)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 i(function(){return u(n)},[])}function useComputed(n){var r=t(n);r.current=n;c.__$f|=4;return i(function(){return e(function(){return r.current()})},[])}function useSignalEffect(n){var r=t(n);r.current=n;f(function(){return a(function(){return r.current()})},[])}export{useComputed,useSignal,useSignalEffect};//# sourceMappingURL=signals.module.js.map
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;if(!i(e.peek())&&3===(null==(n=r.base)?void 0:n.nodeType))r.base.data=e.peek();else{r.__$f|=1;r.setState({})}};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 +1 @@
1
- {"version":3,"file":"signals.module.js","sources":["../src/index.ts"],"sourcesContent":["import { options, Component } from \"preact\";\nimport { useRef, useMemo, useEffect } from \"preact/hooks\";\nimport {\n\tsignal,\n\tcomputed,\n\tbatch,\n\teffect,\n\tSignal,\n\ttype ReadonlySignal,\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 { signal, computed, batch, effect, Signal, type ReadonlySignal };\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 Text(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\t// Replace this component's vdom updater with a direct text one:\n\t\tthis._updater!._callback = () => {\n\t\t\t(this.base as Text).data = s.peek();\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}\nText.displayName = \"_st\";\n\nObject.defineProperties(Signal.prototype, {\n\tconstructor: { configurable: true, value: undefined },\n\ttype: { configurable: true, value: Text },\n\tprops: {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn { data: this };\n\t\t},\n\t},\n\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)\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","useMemo","useRef","useEffect","Signal","computed","signal","effect","batch","currentComponent","hook","hookName","hookFn","bind","setCurrentUpdater","updater","finishUpdate","_start","Text","_ref","data","currentSignal","useSignal","value","s","v","_this","__v","__","__c","_updateFlags","_updater","_callback","base","peek","displayName","Object","defineProperties","prototype","constructor","configurable","undefined","type","props","get","this","__b","old","vnode","i","signalProps","__np","component","update","setState","createUpdater","error","oldVNode","dom","__e","renderedProps","_updaters","updaters","prop","_dispose","_signal","createPropUpdater","_update","propSignal","setAsProperty","ownerSVGElement","changeSignal","newSignal","newProps","setAttribute","removeAttribute","_updater2","index","shouldComponentUpdate","state","_sources","HAS_PENDING_UPDATE","_i","useComputed","compute","$compute","current","useSignalEffect","cb","callback"],"mappings":"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"}
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\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\n\t\t\t(this.base as Text).data = s.peek();\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) {\n\treturn useMemo(() => signal<T>(value), []);\n}\n\nexport function useComputed<T>(compute: () => T) {\n\tconst $compute = useRef(compute);\n\t$compute.current = compute;\n\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","peek","base","nodeType","setState","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","useSignalEffect","cb","callback"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preact/signals",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "license": "MIT",
5
5
  "description": "Manage state with style in Preact",
6
6
  "keywords": [],
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "mangle": "../../mangle.json",
36
36
  "dependencies": {
37
- "@preact/signals-core": "^1.3.1"
37
+ "@preact/signals-core": "^1.4.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "preact": "10.x"
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { options, Component } from "preact";
1
+ import { options, Component, isValidElement } from "preact";
2
2
  import { useRef, useMemo, useEffect } from "preact/hooks";
3
3
  import {
4
4
  signal,
@@ -7,6 +7,7 @@ import {
7
7
  effect,
8
8
  Signal,
9
9
  type ReadonlySignal,
10
+ untracked,
10
11
  } from "@preact/signals-core";
11
12
  import {
12
13
  VNode,
@@ -18,7 +19,15 @@ import {
18
19
  AugmentedElement as Element,
19
20
  } from "./internal";
20
21
 
21
- export { signal, computed, batch, effect, Signal, type ReadonlySignal };
22
+ export {
23
+ signal,
24
+ computed,
25
+ batch,
26
+ effect,
27
+ Signal,
28
+ type ReadonlySignal,
29
+ untracked,
30
+ };
22
31
 
23
32
  const HAS_PENDING_UPDATE = 1 << 0;
24
33
  const HAS_HOOK_STATE = 1 << 1;
@@ -62,7 +71,7 @@ function createUpdater(update: () => void) {
62
71
  * A wrapper component that renders a Signal directly as a Text node.
63
72
  * @todo: in Preact 11, just decorate Signal with `type:null`
64
73
  */
65
- function Text(this: AugmentedComponent, { data }: { data: Signal }) {
74
+ function SignalValue(this: AugmentedComponent, { data }: { data: Signal }) {
66
75
  // hasComputeds.add(this);
67
76
 
68
77
  // Store the props.data signal in another signal so that
@@ -80,8 +89,13 @@ function Text(this: AugmentedComponent, { data }: { data: Signal }) {
80
89
  }
81
90
  }
82
91
 
83
- // Replace this component's vdom updater with a direct text one:
84
92
  this._updater!._callback = () => {
93
+ if (isValidElement(s.peek()) || this.base?.nodeType !== 3) {
94
+ this._updateFlags |= HAS_PENDING_UPDATE;
95
+ this.setState({});
96
+ return;
97
+ }
98
+
85
99
  (this.base as Text).data = s.peek();
86
100
  };
87
101
 
@@ -94,11 +108,11 @@ function Text(this: AugmentedComponent, { data }: { data: Signal }) {
94
108
 
95
109
  return s.value;
96
110
  }
97
- Text.displayName = "_st";
111
+ SignalValue.displayName = "_st";
98
112
 
99
113
  Object.defineProperties(Signal.prototype, {
100
114
  constructor: { configurable: true, value: undefined },
101
- type: { configurable: true, value: Text },
115
+ type: { configurable: true, value: SignalValue },
102
116
  props: {
103
117
  configurable: true,
104
118
  get() {
@@ -271,7 +285,7 @@ hook(OptionsTypes.UNMOUNT, (old, vnode: VNode) => {
271
285
 
272
286
  /** Mark components that use hook state so we can skip sCU optimization. */
273
287
  hook(OptionsTypes.HOOK, (old, component, index, type) => {
274
- if (type < 3)
288
+ if (type < 3 || type === 9)
275
289
  (component as AugmentedComponent)._updateFlags |= HAS_HOOK_STATE;
276
290
  old(component, index, type);
277
291
  });
@@ -1,11 +1,12 @@
1
1
  import {
2
- signal,
3
2
  computed,
4
3
  useComputed,
5
4
  useSignalEffect,
6
5
  Signal,
6
+ signal,
7
7
  } from "@preact/signals";
8
- import { createElement, createRef, render } from "preact";
8
+ import { createElement, createRef, render, createContext } from "preact";
9
+ import { useContext, useState } from "preact/hooks";
9
10
  import { setupRerender, act } from "preact/test-utils";
10
11
 
11
12
  const sleep = (ms?: number) => new Promise(r => setTimeout(r, ms));
@@ -33,7 +34,7 @@ describe("@preact/signals", () => {
33
34
  });
34
35
  });
35
36
 
36
- describe("Text bindings", () => {
37
+ describe("SignalValue bindings", () => {
37
38
  it("should render text without signals", () => {
38
39
  render(<span>test</span>, scratch);
39
40
  const span = scratch.firstChild;
@@ -41,7 +42,7 @@ describe("@preact/signals", () => {
41
42
  expect(text).to.have.property("data", "test");
42
43
  });
43
44
 
44
- it("should render Signals as Text", () => {
45
+ it("should render Signals as SignalValue", () => {
45
46
  const sig = signal("test");
46
47
  render(<span>{sig}</span>, scratch);
47
48
  const span = scratch.firstChild;
@@ -50,7 +51,7 @@ describe("@preact/signals", () => {
50
51
  expect(text).to.have.property("data", "test");
51
52
  });
52
53
 
53
- it("should update Signal-based Text (no parent component)", () => {
54
+ it("should update Signal-based SignalValue (no parent component)", () => {
54
55
  const sig = signal("test");
55
56
  render(<span>{sig}</span>, scratch);
56
57
 
@@ -59,13 +60,13 @@ describe("@preact/signals", () => {
59
60
 
60
61
  sig.value = "changed";
61
62
 
62
- // should not remount/replace Text
63
+ // should not remount/replace SignalValue
63
64
  expect(scratch.firstChild!.firstChild!).to.equal(text);
64
65
  // should update the text in-place
65
66
  expect(text).to.have.property("data", "changed");
66
67
  });
67
68
 
68
- it("should update Signal-based Text (in a parent component)", async () => {
69
+ it("should update Signal-based SignalValue (in a parent component)", async () => {
69
70
  const sig = signal("test");
70
71
  const spy = sinon.spy();
71
72
  function App({ x }: { x: typeof sig }) {
@@ -80,7 +81,7 @@ describe("@preact/signals", () => {
80
81
 
81
82
  sig.value = "changed";
82
83
 
83
- // should not remount/replace Text
84
+ // should not remount/replace SignalValue
84
85
  expect(scratch.firstChild!.firstChild!).to.equal(text);
85
86
  // should update the text in-place
86
87
  expect(text).to.have.property("data", "changed");
@@ -89,7 +90,7 @@ describe("@preact/signals", () => {
89
90
  expect(spy).not.to.have.been.called;
90
91
  });
91
92
 
92
- it("should support swapping Signals in Text positions", async () => {
93
+ it("should support swapping Signals in SignalValue positions", async () => {
93
94
  const sig = signal("test");
94
95
  const spy = sinon.spy();
95
96
  function App({ x }: { x: typeof sig }) {
@@ -107,7 +108,7 @@ describe("@preact/signals", () => {
107
108
  expect(spy).to.have.been.called;
108
109
  spy.resetHistory();
109
110
 
110
- // should not remount/replace Text
111
+ // should not remount/replace SignalValue
111
112
  expect(scratch.firstChild!.firstChild!).to.equal(text);
112
113
  // should update the text in-place
113
114
  expect(text).to.have.property("data", "different");
@@ -130,6 +131,85 @@ describe("@preact/signals", () => {
130
131
  await sleep();
131
132
  expect(spy).not.to.have.been.called;
132
133
  });
134
+
135
+ it("should support rendering JSX in SignalValue positions", async () => {
136
+ const sig = signal(<span>test</span>);
137
+ function App({ x }: { x: typeof sig }) {
138
+ return <span>{x}</span>;
139
+ }
140
+
141
+ render(<App x={sig} />, scratch);
142
+
143
+ const text = scratch.firstChild!.firstChild!;
144
+
145
+ expect(text.textContent).to.equal("test");
146
+ expect(text).to.be.an.instanceOf(HTMLSpanElement);
147
+ expect(text).to.have.property("firstChild").that.is.an.instanceOf(Text);
148
+ });
149
+
150
+ it("JSX in SignalValue should be reactive", async () => {
151
+ const sig = signal(<span>test</span>);
152
+ const spy = sinon.spy();
153
+ function App({ x }: { x: typeof sig }) {
154
+ spy();
155
+ return <span>{x}</span>;
156
+ }
157
+
158
+ render(<App x={sig} />, scratch);
159
+ expect(spy).to.have.been.calledOnce;
160
+ spy.resetHistory();
161
+
162
+ const text = scratch.firstChild!.firstChild!;
163
+
164
+ expect(text.textContent).to.equal("test");
165
+ expect(text).to.be.an.instanceOf(HTMLSpanElement);
166
+ expect(text).to.have.property("firstChild").that.is.an.instanceOf(Text);
167
+
168
+ sig.value = <div>a</div>;
169
+
170
+ expect(spy).not.to.have.been.calledOnce;
171
+
172
+ rerender();
173
+ scratch.firstChild!.firstChild!.textContent!.should.equal("a");
174
+ });
175
+
176
+ it("should support swapping between JSX and string in SignalValue positions", async () => {
177
+ const sig = signal<JSX.Element | string>(<span>test</span>);
178
+ function App({ x }: { x: typeof sig }) {
179
+ return <span>{x}</span>;
180
+ }
181
+
182
+ render(<App x={sig} />, scratch);
183
+
184
+ let text = scratch.firstChild!.firstChild!;
185
+
186
+ expect(text.textContent).to.equal("test");
187
+ expect(text).to.be.an.instanceOf(HTMLSpanElement);
188
+ expect(text).to.have.property("firstChild").that.is.an.instanceOf(Text);
189
+ sig.value = "a";
190
+ rerender();
191
+ text = scratch.firstChild!.firstChild!;
192
+ expect(text.nodeType).to.equal(Node.TEXT_NODE);
193
+ expect(text.textContent).to.equal("a");
194
+
195
+ sig.value = "b";
196
+ expect(text.textContent).to.equal("b");
197
+
198
+ sig.value = <div>c</div>;
199
+ rerender();
200
+ await sleep();
201
+ text = scratch.firstChild!.firstChild!;
202
+
203
+ expect(text).to.be.an.instanceOf(HTMLDivElement);
204
+ expect(text.textContent).to.equal("c");
205
+ sig.value = <span>d</span>;
206
+ rerender();
207
+ await sleep();
208
+
209
+ text = scratch.firstChild!.firstChild!;
210
+ expect(text).to.be.an.instanceOf(HTMLSpanElement);
211
+ expect(text.textContent).to.equal("d");
212
+ });
133
213
  });
134
214
 
135
215
  describe("Component bindings", () => {
@@ -417,6 +497,45 @@ describe("@preact/signals", () => {
417
497
  });
418
498
  });
419
499
 
500
+ describe("hooks mixed with signals", () => {
501
+ it("signals should not stop context from propagating", () => {
502
+ const ctx = createContext({ test: "should-not-exist" });
503
+ let update: any;
504
+
505
+ function Provider(props: any) {
506
+ const [test, setTest] = useState("foo");
507
+ update = setTest;
508
+ return <ctx.Provider value={{ test }}>{props.children}</ctx.Provider>;
509
+ }
510
+
511
+ const s = signal("baz");
512
+ function Test() {
513
+ const value = useContext(ctx);
514
+ return (
515
+ <p>
516
+ {value.test} {s.value}
517
+ </p>
518
+ );
519
+ }
520
+
521
+ function App() {
522
+ return (
523
+ <Provider>
524
+ <Test />
525
+ </Provider>
526
+ );
527
+ }
528
+
529
+ render(<App />, scratch);
530
+
531
+ expect(scratch.innerHTML).to.equal("<p>foo baz</p>");
532
+ act(() => {
533
+ update("bar");
534
+ });
535
+ expect(scratch.innerHTML).to.equal("<p>bar baz</p>");
536
+ });
537
+ });
538
+
420
539
  describe("useSignalEffect()", () => {
421
540
  it("should be invoked after commit", async () => {
422
541
  const ref = createRef();
package/test/ssr.test.tsx CHANGED
@@ -15,7 +15,7 @@ describe("@preact/signals", () => {
15
15
  expect(() => renderToString(<App />)).not.to.throw();
16
16
  });
17
17
 
18
- describe("Text bindings", () => {
18
+ describe("SignalValue bindings", () => {
19
19
  it("should render strings", () => {
20
20
  const s = signal("hello");
21
21
  expect(renderToString(<p>{s}</p>)).to.equal(`<p>hello</p>`);