1- import {
2- type WritableAtom ,
3- Text ,
4- TagVirtualNode ,
5- TextVirtualNode ,
6- Flag ,
7- component ,
8- memo ,
9- useMemo ,
10- atom ,
11- } from '@dark-engine/core' ;
1+ import { Text , TagVirtualNode , TextVirtualNode , component , memo , useMemo } from '@dark-engine/core' ;
122import { type SyntheticEvent as E , createRoot , table , tbody , div , button } from '@dark-engine/platform-browser' ;
3+ import { type Signal , signal , useSelected } from '@dark-engine/signals' ;
134
145const createMeasurer = ( ) => {
156 let startTime : number ;
@@ -46,11 +37,11 @@ const buildData = (count, prefix = ''): Array<DataItem> => {
4637 . fill ( 0 )
4738 . map ( ( ) => ( {
4839 id : ++ nextId ,
49- name$ : atom ( `item: ${ nextId } ${ prefix } ` ) ,
40+ name$ : signal ( `item: ${ nextId } ${ prefix } ` ) ,
5041 } ) ) ;
5142} ;
5243
53- type DataItem = { id : number ; name$ : WritableAtom < string > } ;
44+ type DataItem = { id : number ; name$ : Signal < string > } ;
5445
5546type HeaderProps = {
5647 onCreate : ( e : E < MouseEvent > ) => void ;
@@ -104,25 +95,26 @@ const Header = component<HeaderProps>(
10495const MemoHeader = memo ( Header , ( ) => false ) ;
10596
10697type NameProps = {
107- name$ : WritableAtom < string > ;
98+ name$ : Signal < string > ;
10899} ;
109100
110- const Name = component < NameProps > ( ( { name$ } ) => new TextVirtualNode ( name$ . val ( ) ) ) ;
101+ const Name = component < NameProps > ( ( { name$ } ) => new TextVirtualNode ( name$ . get ( ) ) ) ;
111102
112103type RowProps = {
113104 id : number ;
114- name$ : WritableAtom < string > ;
115- selected$ : WritableAtom < number > ;
105+ name$ : Signal < string > ;
106+ selected$ : Signal < number > ;
116107 onRemove : ( id : number , e : E < MouseEvent > ) => void ;
117108 onHighlight : ( id : number , e : E < MouseEvent > ) => void ;
118109} ;
119110
120- const Row = component < RowProps > ( ( { id, selected$, name$, onRemove, onHighlight } ) => {
111+ const Row = component < RowProps > ( ( { id, name$, selected$, onRemove, onHighlight } ) => {
112+ const isSelected = useSelected ( selected$ , id ) === id ;
113+
121114 return new TagVirtualNode (
122115 'tr' ,
123116 {
124- class : selected$ . val ( null , id ) === id ? 'selected' : undefined ,
125- [ Flag . STATIC_SLOT_OPT ] : true ,
117+ class : isSelected ? 'selected' : undefined ,
126118 } ,
127119 [
128120 new TagVirtualNode ( 'td' , { } , [ Name ( { name$ } ) ] ) ,
@@ -138,15 +130,17 @@ const Row = component<RowProps>(({ id, selected$, name$, onRemove, onHighlight }
138130
139131const MemoRow = memo ( Row , ( ) => false ) ;
140132
133+ const equal = ( ) => false ;
134+
141135type State = {
142- data$ : WritableAtom < Array < DataItem > > ;
143- selected$ : WritableAtom < number > ;
136+ data$ : Signal < Array < DataItem > > ;
137+ selected$ : Signal < number > ;
144138} ;
145139
146140const App = component ( ( ) => {
147- const state = useMemo < State > ( ( ) => ( { data$ : atom ( [ ] ) , selected$ : atom ( ) } ) , [ ] ) ;
141+ const state = useMemo < State > ( ( ) => ( { data$ : signal ( [ ] , { equal } ) , selected$ : signal ( undefined ) } ) , [ ] ) ;
148142 const { data$, selected$ } = state ;
149- const items = data$ . val ( ) ;
143+ const data = data$ . get ( ) ;
150144
151145 const handleCreate = ( e : E < MouseEvent > ) => {
152146 measurer . start ( 'create' ) ;
@@ -157,23 +151,23 @@ const App = component(() => {
157151 const handlePrepend = ( e : E < MouseEvent > ) => {
158152 measurer . start ( 'prepend' ) ;
159153 e . stopPropagation ( ) ;
160- const data = data$ . get ( ) ;
154+ const data = data$ . peek ( ) ;
161155 data . unshift ( ...buildData ( 1000 , '^^^' ) ) ;
162156 data$ . set ( data ) ;
163157 measurer . stop ( ) ;
164158 } ;
165159 const handleAppend = ( e : E < MouseEvent > ) => {
166160 measurer . start ( 'append' ) ;
167161 e . stopPropagation ( ) ;
168- const data = data$ . get ( ) ;
162+ const data = data$ . peek ( ) ;
169163 data . push ( ...buildData ( 1000 , '^^^' ) ) ;
170164 data$ . set ( data ) ;
171165 measurer . stop ( ) ;
172166 } ;
173167 const handleInsertDifferent = ( e : E < MouseEvent > ) => {
174168 measurer . start ( 'insert different' ) ;
175169 e . stopPropagation ( ) ;
176- const data = data$ . get ( ) ;
170+ const data = data$ . peek ( ) ;
177171 data . splice ( 0 , 0 , ...buildData ( 5 , '***' ) ) ;
178172 data . splice ( 8 , 0 , ...buildData ( 2 , '***' ) ) ;
179173 data$ . set ( data ) ;
@@ -182,17 +176,18 @@ const App = component(() => {
182176 const handleUpdateAll = ( e : E < MouseEvent > ) => {
183177 measurer . start ( 'update every 10th' ) ;
184178 e . stopPropagation ( ) ;
185- const data = data$ . get ( ) ;
179+ const data = data$ . peek ( ) ;
186180
187181 for ( let i = 0 ; i < data . length ; i += 10 ) {
188182 data [ i ] . name$ . set ( x => x + '!!!' ) ;
189183 }
184+
190185 measurer . stop ( ) ;
191186 } ;
192187 const handleRemove = ( id : number , e : E < MouseEvent > ) => {
193188 measurer . start ( 'remove' ) ;
194189 e . stopPropagation ( ) ;
195- const data = data$ . get ( ) ;
190+ const data = data$ . peek ( ) ;
196191 const idx = data . findIndex ( x => x . id === id ) ;
197192 idx !== - 1 && data . splice ( idx , 1 ) ;
198193 data$ . set ( data ) ;
@@ -205,7 +200,7 @@ const App = component(() => {
205200 measurer . stop ( ) ;
206201 } ;
207202 const handleSwap = ( e : E < MouseEvent > ) => {
208- const data = data$ . get ( ) ;
203+ const data = data$ . peek ( ) ;
209204 if ( data . length === 0 ) return ;
210205 measurer . start ( 'swap' ) ;
211206 e . stopPropagation ( ) ;
@@ -235,9 +230,8 @@ const App = component(() => {
235230 table ( {
236231 class : 'table' ,
237232 slot : tbody ( {
238- key : items . length > 0 ? 1 : 2 ,
239- [ Flag . MEMO_SLOT_OPT ] : true ,
240- slot : items . map ( item => {
233+ key : data . length > 0 ? 1 : 2 ,
234+ slot : data . map ( item => {
241235 const { id, name$ } = item ;
242236
243237 return MemoRow ( {
0 commit comments