ditox 2.4.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -13
- package/dist/browser/index.d.ts +9 -8
- package/dist/browser/index.js +1 -1
- package/dist/cjs/container.d.ts +6 -8
- package/dist/cjs/container.js +47 -26
- package/dist/cjs/container.js.map +1 -1
- package/dist/cjs/modules.d.ts +4 -3
- package/dist/cjs/modules.js +54 -20
- package/dist/cjs/modules.js.map +1 -1
- package/dist/esm/container.d.ts +6 -8
- package/dist/esm/container.js +46 -24
- package/dist/esm/container.js.map +1 -1
- package/dist/esm/modules.d.ts +4 -3
- package/dist/esm/modules.js +53 -19
- package/dist/esm/modules.js.map +1 -1
- package/dist/umd/index.d.ts +9 -8
- package/dist/umd/index.js +1 -1
- package/package.json +2 -3
- package/src/container.test.ts +132 -52
- package/src/container.ts +62 -29
- package/src/modules.test.ts +69 -6
- package/src/modules.ts +69 -27
package/src/modules.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {Container} from './container';
|
|
2
|
-
import {injectable} from './utils';
|
|
3
2
|
import {Token, token} from './tokens';
|
|
3
|
+
import {injectable} from './utils';
|
|
4
4
|
|
|
5
5
|
type AnyObject = Record<string, any>;
|
|
6
6
|
type EmptyObject = Record<string, never>;
|
|
@@ -73,19 +73,21 @@ export type AnyModuleDeclaration = ModuleDeclaration<Module<AnyObject>>;
|
|
|
73
73
|
* Options for module binding.
|
|
74
74
|
*
|
|
75
75
|
* `scope` types:
|
|
76
|
-
* - `singleton` - **This is the default**. The
|
|
77
|
-
* - `scoped` - The
|
|
76
|
+
* - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.
|
|
77
|
+
* - `scoped` - The value is created and cached by the nearest container which owns the factory function.
|
|
78
78
|
*/
|
|
79
79
|
export type BindModuleOptions = {
|
|
80
80
|
scope?: 'scoped' | 'singleton';
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
+
type ModuleDeclarationWithOptions = {
|
|
84
|
+
module: ModuleDeclaration<AnyObject>;
|
|
85
|
+
options: BindModuleOptions;
|
|
86
|
+
};
|
|
87
|
+
|
|
83
88
|
export type ModuleBindingEntry =
|
|
84
89
|
| ModuleDeclaration<AnyObject>
|
|
85
|
-
|
|
|
86
|
-
module: ModuleDeclaration<AnyObject>;
|
|
87
|
-
options: BindModuleOptions;
|
|
88
|
-
};
|
|
90
|
+
| ModuleDeclarationWithOptions;
|
|
89
91
|
|
|
90
92
|
/**
|
|
91
93
|
* Binds the dependency module to the container
|
|
@@ -103,54 +105,94 @@ export function bindModule<T extends Module<AnyObject>>(
|
|
|
103
105
|
moduleDeclaration: ModuleDeclaration<T>,
|
|
104
106
|
options?: BindModuleOptions,
|
|
105
107
|
): void {
|
|
106
|
-
const
|
|
107
|
-
moduleDeclaration
|
|
108
|
-
|
|
108
|
+
const rootEntry: ModuleBindingEntry = {
|
|
109
|
+
module: moduleDeclaration,
|
|
110
|
+
options: options ?? {},
|
|
111
|
+
};
|
|
109
112
|
|
|
110
|
-
const
|
|
113
|
+
const bfsVisits = new Set<ModuleBindingEntry>([rootEntry]);
|
|
114
|
+
const bfsQueue: ModuleBindingEntry[] = [rootEntry];
|
|
115
|
+
|
|
116
|
+
let bfsIndex = 0;
|
|
117
|
+
while (bfsIndex < bfsQueue.length) {
|
|
118
|
+
const entry = bfsQueue[bfsIndex];
|
|
119
|
+
|
|
120
|
+
const m = 'module' in entry ? entry.module : entry;
|
|
121
|
+
|
|
122
|
+
m.imports?.forEach((depEntry) => {
|
|
123
|
+
if (!bfsVisits.has(depEntry)) {
|
|
124
|
+
bfsVisits.add(depEntry);
|
|
125
|
+
bfsQueue.push(depEntry);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
bfsIndex++;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < bfsQueue.length; i++) {
|
|
133
|
+
const entry = bfsQueue[i];
|
|
134
|
+
const m = 'module' in entry ? entry.module : entry;
|
|
135
|
+
m.beforeBinding?.(container);
|
|
136
|
+
}
|
|
111
137
|
|
|
112
|
-
|
|
113
|
-
|
|
138
|
+
for (let i = 0; i < bfsQueue.length; i++) {
|
|
139
|
+
const entry = bfsQueue[i];
|
|
140
|
+
bindModuleEntry(container, entry);
|
|
114
141
|
}
|
|
115
142
|
|
|
116
|
-
|
|
117
|
-
|
|
143
|
+
for (let i = bfsQueue.length - 1; i >= 0; i--) {
|
|
144
|
+
const entry = bfsQueue[i];
|
|
145
|
+
const m = 'module' in entry ? entry.module : entry;
|
|
146
|
+
m.afterBinding?.(container);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function bindModuleEntry(
|
|
151
|
+
container: Container,
|
|
152
|
+
entry: ModuleBindingEntry,
|
|
153
|
+
): void {
|
|
154
|
+
let module: ModuleDeclaration<AnyObject>;
|
|
155
|
+
let options: BindModuleOptions | undefined;
|
|
156
|
+
|
|
157
|
+
if ('module' in entry) {
|
|
158
|
+
module = entry.module;
|
|
159
|
+
options = entry.options;
|
|
160
|
+
} else {
|
|
161
|
+
module = entry;
|
|
118
162
|
}
|
|
119
163
|
|
|
164
|
+
const scope = options?.scope;
|
|
120
165
|
const exportedValueTokens = new Set<Token<unknown>>();
|
|
166
|
+
const moduleExports = module.exports;
|
|
121
167
|
|
|
122
|
-
if (
|
|
123
|
-
const keys = Object.keys(
|
|
168
|
+
if (moduleExports) {
|
|
169
|
+
const keys = Object.keys(moduleExports);
|
|
124
170
|
|
|
125
171
|
keys.forEach((valueKey) => {
|
|
126
|
-
const valueToken =
|
|
172
|
+
const valueToken = moduleExports[valueKey];
|
|
127
173
|
if (valueToken) {
|
|
128
174
|
exportedValueTokens.add(valueToken);
|
|
129
175
|
|
|
130
176
|
container.bindFactory(
|
|
131
177
|
valueToken,
|
|
132
|
-
injectable((module) => module[valueKey], token),
|
|
178
|
+
injectable((module) => module[valueKey], module.token),
|
|
133
179
|
{scope},
|
|
134
180
|
);
|
|
135
181
|
}
|
|
136
182
|
});
|
|
137
183
|
}
|
|
138
184
|
|
|
139
|
-
container.bindFactory(token, factory, {
|
|
185
|
+
container.bindFactory(module.token, module.factory, {
|
|
140
186
|
scope,
|
|
141
|
-
onRemoved: (
|
|
142
|
-
if (
|
|
143
|
-
|
|
187
|
+
onRemoved: (moduleInstance) => {
|
|
188
|
+
if (moduleInstance.destroy) {
|
|
189
|
+
moduleInstance.destroy();
|
|
144
190
|
}
|
|
145
191
|
|
|
146
192
|
exportedValueTokens.forEach((valueToken) => container.remove(valueToken));
|
|
147
193
|
exportedValueTokens.clear();
|
|
148
194
|
},
|
|
149
195
|
});
|
|
150
|
-
|
|
151
|
-
if (afterBinding) {
|
|
152
|
-
afterBinding(container);
|
|
153
|
-
}
|
|
154
196
|
}
|
|
155
197
|
|
|
156
198
|
/**
|