1
1
import { ChangeDetectorRef , inject } from '@angular/core' ;
2
2
import {
3
+ ReplaySubject ,
3
4
catchError ,
4
5
forkJoin ,
5
6
from ,
6
7
isObservable ,
7
8
map ,
8
- Observable ,
9
9
of ,
10
- ReplaySubject ,
11
10
retry ,
12
11
share ,
13
12
switchMap ,
14
13
take ,
15
14
tap ,
15
+ type Observable ,
16
16
} from 'rxjs' ;
17
17
import type { GLTF } from 'three/examples/jsm/loaders/GLTFLoader' ;
18
- import type { NgtBranchingReturn , NgtLoaderExtensions , NgtLoaderResult , NgtObjectMap } from './types' ;
18
+ import type {
19
+ NgtAnyRecord ,
20
+ NgtBranchingReturn ,
21
+ NgtLoaderExtensions ,
22
+ NgtLoaderProto ,
23
+ NgtLoaderReturnType ,
24
+ NgtObjectMap ,
25
+ } from './types' ;
19
26
import { makeObjectGraph } from './utils/make' ;
20
27
import { safeDetectChanges } from './utils/safe-detect-changes' ;
21
28
22
- interface NgtLoader {
23
- < TReturnType , TUrl extends string | string [ ] | Record < string , string > > (
24
- loaderConstructorFactory : ( inputs : TUrl ) => new ( ...args : any [ ] ) => NgtLoaderResult < TReturnType > ,
25
- input : TUrl | Observable < TUrl > ,
26
- extensions ?: NgtLoaderExtensions < NgtLoaderResult < TReturnType > > ,
27
- onProgress ?: ( event : ProgressEvent ) => void
28
- ) : Observable <
29
- TUrl extends string [ ]
30
- ? Array < NgtBranchingReturn < TReturnType , GLTF , GLTF & NgtObjectMap > >
31
- : TUrl extends object
32
- ? { [ key in keyof TUrl ] : NgtBranchingReturn < TReturnType , GLTF , GLTF & NgtObjectMap > }
33
- : NgtBranchingReturn < TReturnType , GLTF , GLTF & NgtObjectMap >
34
- > ;
35
- destroy : ( ) => void ;
36
- preLoad : < TReturnType , TUrl extends string | string [ ] | Record < string , string > > (
37
- loaderConstructorFactory : ( inputs : TUrl ) => new ( ...args : any [ ] ) => NgtLoaderResult < TReturnType > ,
38
- inputs : TUrl | Observable < TUrl > ,
39
- extensions ?: NgtLoaderExtensions
40
- ) => void ;
41
- }
42
-
43
29
export type NgtLoaderResults <
44
30
TInput extends string | string [ ] | Record < string , string > ,
45
31
TReturn
46
32
> = TInput extends string [ ] ? TReturn [ ] : TInput extends object ? { [ key in keyof TInput ] : TReturn } : TReturn ;
47
33
48
34
const cached = new Map < string , Observable < any > > ( ) ;
49
35
50
- function load < TReturnType , TUrl extends string | string [ ] | Record < string , string > > (
51
- loaderConstructorFactory : ( inputs : TUrl ) => new ( ...args : any [ ] ) => NgtLoaderResult < TReturnType > ,
36
+ function load <
37
+ TData ,
38
+ TUrl extends string | string [ ] | Record < string , string > ,
39
+ TLoaderConstructor extends NgtLoaderProto < TData >
40
+ > (
41
+ loaderConstructorFactory : ( inputs : TUrl ) => TLoaderConstructor ,
52
42
input : TUrl | Observable < TUrl > ,
53
- extensions ?: NgtLoaderExtensions ,
43
+ extensions ?: NgtLoaderExtensions < TLoaderConstructor > ,
54
44
onProgress ?: ( event : ProgressEvent ) => void
55
45
) {
56
46
const urls$ = isObservable ( input ) ? input : of ( input ) ;
@@ -67,7 +57,11 @@ function load<TReturnType, TUrl extends string | string[] | Record<string, strin
67
57
url ,
68
58
from ( loader . loadAsync ( url , onProgress ) ) . pipe (
69
59
tap ( ( data ) => {
70
- if ( data . scene ) Object . assign ( data , makeObjectGraph ( data . scene ) ) ;
60
+ if ( ( data as NgtAnyRecord ) [ 'scene' ] )
61
+ Object . assign (
62
+ data as NgtAnyRecord ,
63
+ makeObjectGraph ( ( data as NgtAnyRecord ) [ 'scene' ] )
64
+ ) ;
71
65
} ) ,
72
66
retry ( 2 ) ,
73
67
catchError ( ( err ) => {
@@ -86,12 +80,17 @@ function load<TReturnType, TUrl extends string | string[] | Record<string, strin
86
80
) ;
87
81
}
88
82
89
- function injectLoader < TReturnType , TUrl extends string | string [ ] | Record < string , string > > (
90
- loaderConstructorFactory : ( inputs : TUrl ) => new ( ...args : any [ ] ) => NgtLoaderResult < TReturnType > ,
83
+ export function injectNgtLoader <
84
+ TData ,
85
+ TUrl extends string | string [ ] | Record < string , string > ,
86
+ TLoaderConstructor extends NgtLoaderProto < TData > ,
87
+ TReturn = NgtLoaderReturnType < TData , TLoaderConstructor >
88
+ > (
89
+ loaderConstructorFactory : ( inputs : TUrl ) => TLoaderConstructor ,
91
90
input : TUrl | Observable < TUrl > ,
92
- extensions ?: NgtLoaderExtensions ,
91
+ extensions ?: NgtLoaderExtensions < TLoaderConstructor > ,
93
92
onProgress ?: ( event : ProgressEvent ) => void
94
- ) : Observable < NgtLoaderResults < TUrl , NgtBranchingReturn < TReturnType , GLTF , GLTF & NgtObjectMap > > > {
93
+ ) : Observable < NgtLoaderResults < TUrl , NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > > > {
95
94
const cdr = inject ( ChangeDetectorRef ) ;
96
95
97
96
return load ( loaderConstructorFactory , input , extensions , onProgress ) . pipe (
@@ -104,7 +103,7 @@ function injectLoader<TReturnType, TUrl extends string | string[] | Record<strin
104
103
return keys . reduce ( ( result , key ) => {
105
104
result [ key as keyof typeof result ] = results [ keys . indexOf ( key ) ] ;
106
105
return result ;
107
- } , { } as { [ key in keyof TUrl ] : NgtBranchingReturn < TReturnType , GLTF , GLTF & NgtObjectMap > } ) ;
106
+ } , { } as { [ key in keyof TUrl ] : NgtBranchingReturn < TReturn , GLTF , GLTF & NgtObjectMap > } ) ;
108
107
} ) ,
109
108
tap ( ( ) => {
110
109
requestAnimationFrame ( ( ) => void safeDetectChanges ( cdr ) ) ;
@@ -114,12 +113,18 @@ function injectLoader<TReturnType, TUrl extends string | string[] | Record<strin
114
113
) ;
115
114
}
116
115
117
- ( injectLoader as NgtLoader ) . destroy = ( ) => {
116
+ injectNgtLoader [ ' destroy' ] = ( ) => {
118
117
cached . clear ( ) ;
119
118
} ;
120
119
121
- ( injectLoader as NgtLoader ) . preLoad = ( loaderConstructorFactory , inputs , extensions ) => {
120
+ injectNgtLoader [ 'preLoad' ] = <
121
+ TData ,
122
+ TUrl extends string | string [ ] | Record < string , string > ,
123
+ TLoaderConstructor extends NgtLoaderProto < TData >
124
+ > (
125
+ loaderConstructorFactory : ( inputs : TUrl ) => TLoaderConstructor ,
126
+ inputs : TUrl | Observable < TUrl > ,
127
+ extensions ?: NgtLoaderExtensions < TLoaderConstructor >
128
+ ) => {
122
129
load ( loaderConstructorFactory , inputs , extensions ) . pipe ( take ( 1 ) ) . subscribe ( ) ;
123
130
} ;
124
-
125
- export const injectNgtLoader = injectLoader as NgtLoader ;
0 commit comments