1- import { options , Component , createElement } from "preact" ;
1+ import { options , Component } from "preact" ;
22import { useRef , useMemo } from "preact/hooks" ;
33import {
44 signal ,
@@ -92,18 +92,6 @@ function getElementUpdater(vnode: VNode) {
9292// return false;
9393// }
9494
95- /** Convert Signals within (nested) props.children into Text components */
96- function childToSignal < T > ( child : any , i : keyof T , arr : T ) {
97- if ( typeof child !== "object" || child == null ) {
98- // can't be a signal
99- } else if ( Array . isArray ( child ) ) {
100- child . forEach ( childToSignal ) ;
101- } else if ( child instanceof Signal ) {
102- // @ts -ignore-next-line yes, arr can accept VNodes:
103- arr [ i ] = createElement ( Text , { data : child } ) ;
104- }
105- }
106-
10795/**
10896 * A wrapper component that renders a Signal directly as a Text node.
10997 * @todo : in Preact 11, just decorate Signal with `type:null`
@@ -142,6 +130,21 @@ function Text(this: ComponentType, { data }: { data: Signal }) {
142130}
143131Text . displayName = "_st" ;
144132
133+ Object . defineProperties ( Signal . prototype , {
134+ constructor : { configurable : true } ,
135+ type : { configurable : true , value : Text } ,
136+ props : {
137+ configurable : true ,
138+ get ( ) {
139+ return { data : this } ;
140+ } ,
141+ } ,
142+ // Setting a VNode's _depth to 1 forces Preact to clone it before modifying:
143+ // https://github.com/preactjs/preact/blob/d7a433ee8463a7dc23a05111bb47de9ec729ad4d/src/diff/children.js#L77
144+ // @todo remove this for Preact 11
145+ __b : { configurable : true , value : 1 } ,
146+ } ) ;
147+
145148/** Inject low-level property/attribute bindings for Signals into Preact's diff */
146149hook ( OptionsTypes . DIFF , ( old , vnode ) => {
147150 if ( typeof vnode . type === "string" ) {
@@ -151,9 +154,9 @@ hook(OptionsTypes.DIFF, (old, vnode) => {
151154
152155 for ( let i in props ) {
153156 let value = props [ i ] ;
154- if ( i === "children" ) {
155- childToSignal ( value , "children" , props ) ;
156- } else if ( value instanceof Signal ) {
157+ if ( i === "children" ) continue ;
158+
159+ if ( value instanceof Signal ) {
157160 // first Signal prop triggers creation/cleanup of the updater:
158161 if ( ! updater ) updater = getElementUpdater ( vnode ) ;
159162 // track which props are Signals for precise updates:
0 commit comments