1
1
/** @module resolve */ /** for typedoc */
2
- import { extend , pick , map , filter } from "../common/common" ;
3
- import { not } from "../common/hof" ;
4
- import { isInjectable } from "../common/predicates" ;
2
+ import { pick , map , extend } from "../common/common" ;
5
3
6
4
import { services } from "../common/coreservices" ;
7
5
import { trace } from "../common/trace" ;
8
6
import { Resolvables , IOptions1 } from "./interface" ;
9
7
10
8
import { ResolveContext } from "./resolveContext" ;
9
+ import { stringify } from "../common/strings" ;
11
10
12
11
/**
13
12
* The basic building block for the resolve system.
@@ -22,18 +21,39 @@ import {ResolveContext} from "./resolveContext";
22
21
* parameter to those fns.
23
22
*/
24
23
export class Resolvable {
25
- name : string ;
24
+ token : any ;
26
25
resolveFn : Function ;
27
26
deps : string [ ] ;
28
27
29
28
promise : Promise < any > = undefined ;
29
+ resolved : boolean = false ;
30
30
data : any ;
31
-
32
- constructor ( name : string , resolveFn : Function , preResolvedData ?: any ) {
33
- this . name = name ;
34
- this . resolveFn = resolveFn ;
35
- this . deps = services . $injector . annotate ( resolveFn , services . $injector . strictDi ) ;
36
- this . data = preResolvedData ;
31
+
32
+ /**
33
+ * This constructor creates a Resolvable copy
34
+ */
35
+ constructor ( resolvable : Resolvable )
36
+
37
+ /**
38
+ * This constructor creates a new `Resolvable`
39
+ *
40
+ * @param token The new resolvable's injection token, such as `"userList"` (a string) or `UserService` (a class).
41
+ * When this token is used during injection, the resolved value will be injected.
42
+ * @param resolveFn The function that returns the resolved value, or a promise for the resolved value
43
+ * @param deps An array of dependencies, which will be injected into the `resolveFn`
44
+ * @param data Pre-resolved data. If the resolve value is already known, it may be provided here.
45
+ */
46
+ constructor ( token : any , resolveFn : Function , deps ?: any [ ] , data ?: any )
47
+ constructor ( token , resolveFn ?: Function , deps ?: any [ ] , data ?: any ) {
48
+ if ( token instanceof Resolvable ) {
49
+ extend ( this , token ) ;
50
+ } else {
51
+ this . token = token ;
52
+ this . resolveFn = resolveFn ;
53
+ this . deps = deps ;
54
+ this . data = data ;
55
+ this . resolved = data !== undefined ;
56
+ }
37
57
}
38
58
39
59
// synchronous part:
@@ -48,15 +68,15 @@ export class Resolvable {
48
68
// - store unwrapped data
49
69
// - resolve the Resolvable's promise
50
70
resolveResolvable ( resolveContext : ResolveContext , options : IOptions1 = { } ) {
51
- let { name , deps, resolveFn} = this ;
71
+ let { deps, resolveFn} = this ;
52
72
53
73
trace . traceResolveResolvable ( this , options ) ;
54
74
// First, set up an overall deferred/promise for this Resolvable
55
75
let deferred = services . $q . defer ( ) ;
56
76
this . promise = deferred . promise ;
57
77
// Load a map of all resolvables for this state from the context path
58
78
// Omit the current Resolvable from the result, so we don't try to inject this into this
59
- let ancestorsByName : Resolvables = resolveContext . getResolvables ( null , { omitOwnLocals : [ name ] } ) ;
79
+ let ancestorsByName : Resolvables = resolveContext . getResolvables ( null , { omitOwnLocals : [ this . token ] } ) ;
60
80
61
81
// Limit the ancestors Resolvables map to only those that the current Resolvable fn's annotations depends on
62
82
let depResolvables : Resolvables = < any > pick ( ancestorsByName , deps ) ;
@@ -86,17 +106,10 @@ export class Resolvable {
86
106
}
87
107
88
108
toString ( ) {
89
- return `Resolvable(name : ${ this . name } , requires: [${ this . deps } ])` ;
109
+ return `Resolvable(token : ${ stringify ( this . token ) } , requires: [${ this . deps . map ( stringify ) } ])` ;
90
110
}
91
111
92
- /**
93
- * Validates the result map as a "resolve:" style object, then transforms the resolves into Resolvable[]
94
- */
95
- static makeResolvables ( resolves : { [ key : string ] : Function ; } ) : Resolvable [ ] {
96
- // If a hook result is an object, it should be a map of strings to functions.
97
- let invalid = filter ( resolves , not ( isInjectable ) ) , keys = Object . keys ( invalid ) ;
98
- if ( keys . length )
99
- throw new Error ( `Invalid resolve key/value: ${ keys [ 0 ] } /${ invalid [ keys [ 0 ] ] } ` ) ;
100
- return Object . keys ( resolves ) . map ( key => new Resolvable ( key , resolves [ key ] ) ) ;
112
+ clone ( ) : Resolvable {
113
+ return new Resolvable ( this ) ;
101
114
}
102
115
}
0 commit comments