1- import {
2- ChangeDetectorRef ,
3- Injector ,
4- computed ,
5- effect ,
6- inject ,
7- runInInjectionContext ,
8- signal ,
9- untracked ,
10- type Signal ,
11- } from '@angular/core' ;
1+ import { ChangeDetectorRef , Injector , effect , inject , runInInjectionContext , signal , type Signal } from '@angular/core' ;
122import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader' ;
133import type {
144 NgtAnyRecord ,
@@ -30,6 +20,12 @@ export type NgtLoaderResults<
3020
3121const cached = new Map ( ) ;
3222
23+ function normalizeInputs ( input : string | string [ ] | Record < string , string > ) {
24+ if ( Array . isArray ( input ) ) return input ;
25+ if ( typeof input === 'string' ) return [ input ] ;
26+ return Object . values ( input ) ;
27+ }
28+
3329function load <
3430 TData ,
3531 TUrl extends string | string [ ] | Record < string , string > ,
@@ -45,25 +41,16 @@ function load<
4541 onProgress ?: ( event : ProgressEvent ) => void ;
4642 } = { }
4743) {
48- const computedUrls : Signal < string [ ] > = computed ( ( ) => {
49- const input = inputs ( ) ;
50- if ( Array . isArray ( input ) ) return input ;
51- if ( typeof input === 'string' ) return [ input ] ;
52- return Object . values ( input ) ;
53- } ) ;
54-
5544 return ( ) => {
56- const urls = computedUrls ( ) ;
57- const loaderConstructor = loaderConstructorFactory ( urls ) ;
58- const loader = new loaderConstructor ( ) ;
45+ const urls = normalizeInputs ( inputs ( ) ) ;
46+ const loader = new ( loaderConstructorFactory ( urls ) ) ( ) ;
5947 if ( extensions ) extensions ( loader ) ;
60-
61- return urls . map (
62- ( url ) =>
63- new Promise ( ( resolve , reject ) => {
64- if ( cached . has ( url ) ) {
65- resolve ( cached . get ( url ) ) ;
66- } else {
48+ // TODO: reevaluate this
49+ return urls . map ( ( url ) => {
50+ if ( ! cached . has ( url ) ) {
51+ cached . set (
52+ url ,
53+ new Promise ( ( resolve , reject ) => {
6754 loader . load (
6855 url ,
6956 ( data ) => {
@@ -72,15 +59,16 @@ function load<
7259 data as NgtAnyRecord ,
7360 makeObjectGraph ( ( data as NgtAnyRecord ) [ 'scene' ] )
7461 ) ;
75- cached . set ( url , data ) ;
7662 resolve ( data ) ;
7763 } ,
7864 onProgress ,
7965 ( error ) => reject ( new Error ( `[NGT] Could not load ${ url } : ${ error } ` ) )
8066 ) ;
81- }
82- } )
83- ) ;
67+ } )
68+ ) ;
69+ }
70+ return cached . get ( url ) ! ;
71+ } ) ;
8472 } ;
8573}
8674
@@ -103,31 +91,30 @@ export function injectNgtLoader<
10391 } = { }
10492) : Signal < NgtLoaderResults < TUrl , NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > > > {
10593 injector = assertInjectionContext ( injectNgtLoader , injector ) ;
94+ const response = signal < NgtLoaderResults < TUrl , NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > > > ( null ! ) ;
10695 return runInInjectionContext ( injector , ( ) => {
10796 const cdr = inject ( ChangeDetectorRef ) ;
108- const response = signal < NgtLoaderResults < TUrl , NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > > > ( null ! ) ;
10997 const effector = load ( loaderConstructorFactory , inputs , { extensions, onProgress } ) ;
11098
11199 requestAnimationInInjectionContext ( ( ) => {
112- effect ( ( ) => {
113- const originalUrls = untracked ( inputs ) ;
114- Promise . all ( effector ( ) )
115- . then ( ( results ) => {
116- if ( Array . isArray ( originalUrls ) ) return results ;
117- if ( typeof originalUrls === 'string' ) return results [ 0 ] ;
118- const keys = Object . keys ( originalUrls ) ;
119- return keys . reduce ( ( result , key ) => {
120- ( result as NgtAnyRecord ) [ key ] = results [ keys . indexOf ( key ) ] ;
121- return result ;
122- } , { } as { [ key in keyof TUrl ] : NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > } ) ;
123- } )
124- . then ( ( value ) => {
125- response . set (
126- value as NgtLoaderResults < TUrl , NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > >
127- ) ;
100+ effect (
101+ ( ) => {
102+ const originalUrls = inputs ( ) ;
103+ Promise . all ( effector ( ) ) . then ( ( results ) => {
104+ response . update ( ( ) => {
105+ if ( Array . isArray ( originalUrls ) ) return results ;
106+ if ( typeof originalUrls === 'string' ) return results [ 0 ] ;
107+ const keys = Object . keys ( originalUrls ) ;
108+ return keys . reduce ( ( result , key ) => {
109+ ( result as NgtAnyRecord ) [ key ] = results [ keys . indexOf ( key ) ] ;
110+ return result ;
111+ } , { } as { [ key in keyof TUrl ] : NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > } ) ;
112+ } ) ;
128113 safeDetectChanges ( cdr ) ;
129114 } ) ;
130- } ) ;
115+ } ,
116+ { allowSignalWrites : true }
117+ ) ;
131118 } ) ;
132119
133120 return response . asReadonly ( ) ;
0 commit comments