55 createMemo ,
66 createSignal ,
77 destroySignal ,
8+ isSignal ,
89 link ,
910 Signal ,
1011 type CompareFunc ,
@@ -345,16 +346,35 @@ export class Kernel {
345346
346347 const propertyReaders = new Map < string , SignalReader < any > > ( ) ;
347348
349+ const getUseProperty = < T = any > ( name : string , compare ?: CompareFunc < T > ) : SignalReader < T > => {
350+ let propReader = propertyReaders . get ( name ) ;
351+ if ( propReader === undefined ) {
352+ propReader = createSignal < any > ( undefined , compare ? { compare} : undefined ) . get ;
353+ propertyReaders . set ( name , propReader ) ;
354+ const con = link ( entry . entity . getPropertyReader ( name ) , propReader ) ;
355+ unsubscribeSecondary . add ( con . destroy . bind ( con ) ) ;
356+ }
357+ return propReader ;
358+ } ;
359+
348360 const shadowObject = eventize (
349361 new constructor ( {
350362 entity : entry . entity ,
351363
352- provideContext < T = unknown > ( name : string | symbol , initialValue ?: T , isEqual ?: CompareFunc < T > ) {
364+ provideContext < T = unknown > ( name : string | symbol , sourceOrInitialValue ?: T | SignalReader < T > , isEqual ?: CompareFunc < T > ) {
353365 let ctxProvider = contextProviders . get ( name ) ;
354366
355367 if ( ctxProvider == null ) {
368+ const isSig = isSignal ( sourceOrInitialValue ) ;
369+ const initialValue = isSig ? undefined : ( sourceOrInitialValue as T ) ;
370+
356371 ctxProvider = createSignal ( initialValue , isEqual ? { compare : isEqual } : undefined ) ;
357372
373+ if ( isSig ) {
374+ const ln = link ( sourceOrInitialValue as SignalReader < T > , ctxProvider ) ;
375+ unsubscribeSecondary . add ( ln . destroy . bind ( ln ) ) ;
376+ }
377+
358378 const ln = link ( ctxProvider , entry . entity . provideContext ( name ) ) ;
359379 unsubscribeSecondary . add ( ln . destroy . bind ( ln ) ) ;
360380 contextProviders . set ( name , ctxProvider ) ;
@@ -363,12 +383,20 @@ export class Kernel {
363383 return ctxProvider ;
364384 } ,
365385
366- provideGlobalContext < T = unknown > ( name : string | symbol , initialValue ?: T , isEqual ?: CompareFunc < T > ) {
386+ provideGlobalContext < T = unknown > ( name : string | symbol , sourceOrInitialValue ?: T | SignalReader < T > , isEqual ?: CompareFunc < T > ) {
367387 let ctxProvider = contextRootProviders . get ( name ) ;
368388
369389 if ( ctxProvider == null ) {
390+ const isSig = isSignal ( sourceOrInitialValue ) ;
391+ const initialValue = isSig ? undefined : ( sourceOrInitialValue as T ) ;
392+
370393 ctxProvider = createSignal ( initialValue , isEqual ? { compare : isEqual } : undefined ) ;
371394
395+ if ( isSig ) {
396+ const ln = link ( sourceOrInitialValue as SignalReader < T > , ctxProvider ) ;
397+ unsubscribeSecondary . add ( ln . destroy . bind ( ln ) ) ;
398+ }
399+
372400 const ln = link ( ctxProvider , entry . entity . provideGlobalContext ( name ) ) ;
373401 unsubscribeSecondary . add ( ln . destroy . bind ( ln ) ) ;
374402 contextRootProviders . set ( name , ctxProvider ) ;
@@ -399,15 +427,39 @@ export class Kernel {
399427 return ctxReader ;
400428 } ,
401429
402- useProperty < T = any > ( name : string , compare ?: CompareFunc < T > ) : SignalReader < T > {
403- let propReader = propertyReaders . get ( name ) ;
404- if ( propReader === undefined ) {
405- propReader = createSignal < any > ( undefined , compare ? { compare} : undefined ) . get ;
406- propertyReaders . set ( name , propReader ) ;
407- const con = link ( entry . entity . getPropertyReader ( name ) , propReader ) ;
408- unsubscribeSecondary . add ( con . destroy . bind ( con ) ) ;
430+ useProperty : getUseProperty ,
431+
432+ useProperties < K extends string > ( props : Record < K , string > ) : Record < K , SignalReader < any > > {
433+ const result = { } as Record < K , SignalReader < any > > ;
434+ for ( const key in props ) {
435+ if ( Object . prototype . hasOwnProperty . call ( props , key ) ) {
436+ result [ key ] = getUseProperty ( props [ key ] ) ;
437+ }
409438 }
410- return propReader ;
439+ return result ;
440+ } ,
441+
442+ useResource < T > ( factory : ( ) => T | undefined , cleanup ?: ( resource : T ) => void ) : Signal < T | undefined > {
443+ const resourceSignal = createSignal < T | undefined > ( undefined ) ;
444+ unsubscribeSecondary . add ( ( ) => destroySignal ( resourceSignal ) ) ;
445+
446+ const effect = createEffect ( ( ) => {
447+ const resource = factory ( ) ;
448+ resourceSignal . set ( resource ) ;
449+
450+ if ( resource !== undefined && cleanup ) {
451+ return ( ) => {
452+ cleanup ( resource ) ;
453+ resourceSignal . set ( undefined ) ;
454+ } ;
455+ }
456+ return ( ) => {
457+ resourceSignal . set ( undefined ) ;
458+ } ;
459+ } ) ;
460+ unsubscribeSecondary . add ( effect . destroy ) ;
461+
462+ return resourceSignal ;
411463 } ,
412464
413465 createEffect ( ...args : Parameters < typeof createEffect > ) : ReturnType < typeof createEffect > {
0 commit comments