ditox 3.1.0 → 3.3.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 +135 -32
- package/dist/index.cjs +518 -0
- package/dist/index.cjs.map +1 -0
- package/dist/{umd/index.d.ts → index.d.cts} +195 -197
- package/dist/{browser/index.d.ts → index.d.ts} +195 -197
- package/dist/index.js +501 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +524 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +22 -19
- package/src/container.test.ts +34 -33
- package/src/container.ts +12 -6
- package/src/index.ts +26 -23
- package/src/modules.test.ts +172 -37
- package/src/modules.ts +22 -5
- package/src/tokens.test.ts +9 -8
- package/src/tokens.ts +2 -2
- package/src/utils.test.ts +18 -17
- package/src/utils.ts +21 -21
- package/dist/browser/index.js +0 -2
- package/dist/browser/index.js.map +0 -1
- package/dist/cjs/container.d.ts +0 -88
- package/dist/cjs/container.js +0 -216
- package/dist/cjs/container.js.map +0 -1
- package/dist/cjs/index.d.ts +0 -7
- package/dist/cjs/index.js +0 -24
- package/dist/cjs/index.js.map +0 -1
- package/dist/cjs/modules.d.ts +0 -121
- package/dist/cjs/modules.js +0 -143
- package/dist/cjs/modules.js.map +0 -1
- package/dist/cjs/tokens.d.ts +0 -56
- package/dist/cjs/tokens.js +0 -20
- package/dist/cjs/tokens.js.map +0 -1
- package/dist/cjs/utils.d.ts +0 -137
- package/dist/cjs/utils.js +0 -156
- package/dist/cjs/utils.js.map +0 -1
- package/dist/esm/container.d.ts +0 -88
- package/dist/esm/container.js +0 -211
- package/dist/esm/container.js.map +0 -1
- package/dist/esm/index.d.ts +0 -7
- package/dist/esm/index.js +0 -5
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/modules.d.ts +0 -121
- package/dist/esm/modules.js +0 -136
- package/dist/esm/modules.js.map +0 -1
- package/dist/esm/tokens.d.ts +0 -56
- package/dist/esm/tokens.js +0 -15
- package/dist/esm/tokens.js.map +0 -1
- package/dist/esm/utils.d.ts +0 -137
- package/dist/esm/utils.js +0 -145
- package/dist/esm/utils.js.map +0 -1
- package/dist/umd/index.js +0 -2
- package/dist/umd/index.js.map +0 -1
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.Ditox = {})));
|
|
5
|
+
})(this, function(exports) {
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
7
|
+
|
|
8
|
+
//#region src/tokens.ts
|
|
9
|
+
function token(options) {
|
|
10
|
+
const normalized = typeof options === "string" ? { description: options } : options;
|
|
11
|
+
return { symbol: (normalized === null || normalized === void 0 ? void 0 : normalized.key) ? Symbol.for(normalized.key) : Symbol(normalized === null || normalized === void 0 ? void 0 : normalized.description) };
|
|
12
|
+
}
|
|
13
|
+
function optional(token, optionalValue) {
|
|
14
|
+
return {
|
|
15
|
+
symbol: token.symbol,
|
|
16
|
+
isOptional: true,
|
|
17
|
+
optionalValue
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/container.ts
|
|
23
|
+
/**
|
|
24
|
+
* ResolverError is thrown by the resolver when a token is not found in a container.
|
|
25
|
+
*/
|
|
26
|
+
var ResolverError = class extends Error {
|
|
27
|
+
constructor(message) {
|
|
28
|
+
super(message);
|
|
29
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
30
|
+
this.name = "ResolverError";
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
/** @internal */
|
|
34
|
+
const CONTAINER = token("ditox.Container");
|
|
35
|
+
/** @internal */
|
|
36
|
+
const PARENT_CONTAINERS = token("ditox.ParentContainer");
|
|
37
|
+
/** @internal */
|
|
38
|
+
const RESOLVER = token("ditox.Resolver");
|
|
39
|
+
/** @internal */
|
|
40
|
+
const NOT_FOUND = Symbol();
|
|
41
|
+
/** @internal */
|
|
42
|
+
const DEFAULT_SCOPE = "singleton";
|
|
43
|
+
/** @internal */
|
|
44
|
+
const FACTORIES_MAP = token("ditox.FactoriesMap");
|
|
45
|
+
/** @internal */
|
|
46
|
+
function getScope(options) {
|
|
47
|
+
var _options$scope;
|
|
48
|
+
return (_options$scope = options === null || options === void 0 ? void 0 : options.scope) !== null && _options$scope !== void 0 ? _options$scope : DEFAULT_SCOPE;
|
|
49
|
+
}
|
|
50
|
+
/** @internal */
|
|
51
|
+
function getOnRemoved(options) {
|
|
52
|
+
return options.scope === void 0 || options.scope === "scoped" || options.scope === "singleton" ? options.onRemoved : void 0;
|
|
53
|
+
}
|
|
54
|
+
/** @internal */
|
|
55
|
+
function isInternalToken(token) {
|
|
56
|
+
return token.symbol === CONTAINER.symbol || token.symbol === PARENT_CONTAINERS.symbol || token.symbol === RESOLVER.symbol;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Creates a new dependency container.
|
|
60
|
+
*
|
|
61
|
+
* Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.
|
|
62
|
+
*
|
|
63
|
+
* @param parentArg - Optional parent container or an array of containers.
|
|
64
|
+
*/
|
|
65
|
+
function createContainer(parentArg) {
|
|
66
|
+
const parents = parentArg ? Array.isArray(parentArg) ? [...parentArg] : [parentArg] : void 0;
|
|
67
|
+
const values = /* @__PURE__ */ new Map();
|
|
68
|
+
const factories = /* @__PURE__ */ new Map();
|
|
69
|
+
const container = {
|
|
70
|
+
bindValue(token, value) {
|
|
71
|
+
if (isInternalToken(token)) return;
|
|
72
|
+
values.set(token.symbol, value);
|
|
73
|
+
},
|
|
74
|
+
bindFactory(token, factory, options) {
|
|
75
|
+
if (isInternalToken(token)) return;
|
|
76
|
+
factories.set(token.symbol, {
|
|
77
|
+
factory,
|
|
78
|
+
options
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
remove(token) {
|
|
82
|
+
var _factories$get;
|
|
83
|
+
if (isInternalToken(token)) return;
|
|
84
|
+
const options = (_factories$get = factories.get(token.symbol)) === null || _factories$get === void 0 ? void 0 : _factories$get.options;
|
|
85
|
+
if (options) executeOnRemoved(token.symbol, options);
|
|
86
|
+
values.delete(token.symbol);
|
|
87
|
+
factories.delete(token.symbol);
|
|
88
|
+
},
|
|
89
|
+
removeAll() {
|
|
90
|
+
factories.forEach((context, tokenSymbol) => {
|
|
91
|
+
if (context.options) executeOnRemoved(tokenSymbol, context.options);
|
|
92
|
+
});
|
|
93
|
+
values.clear();
|
|
94
|
+
factories.clear();
|
|
95
|
+
bindInternalTokens();
|
|
96
|
+
},
|
|
97
|
+
hasToken(token) {
|
|
98
|
+
return values.has(token.symbol) || factories.has(token.symbol) || parentContainersHaveToken(parents, token);
|
|
99
|
+
},
|
|
100
|
+
get(token) {
|
|
101
|
+
const value = resolver(token, container);
|
|
102
|
+
if (value !== NOT_FOUND) return value;
|
|
103
|
+
if (token.isOptional) return token.optionalValue;
|
|
104
|
+
},
|
|
105
|
+
resolve(token) {
|
|
106
|
+
var _token$symbol$descrip;
|
|
107
|
+
const value = resolver(token, container);
|
|
108
|
+
if (value !== NOT_FOUND) return value;
|
|
109
|
+
if (token.isOptional) return token.optionalValue;
|
|
110
|
+
throw new ResolverError(`Token "${(_token$symbol$descrip = token.symbol.description) !== null && _token$symbol$descrip !== void 0 ? _token$symbol$descrip : ""}" is not provided`);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
function resolver(token, origin) {
|
|
114
|
+
const value = values.get(token.symbol);
|
|
115
|
+
const hasValue = value !== void 0 || values.has(token.symbol);
|
|
116
|
+
if (hasValue && origin === container) return value;
|
|
117
|
+
const factoryContext = factories.get(token.symbol);
|
|
118
|
+
if (factoryContext) switch (getScope(factoryContext.options)) {
|
|
119
|
+
case "singleton": if (hasValue) return value;
|
|
120
|
+
else if (parentContainersHaveToken(parents, token)) break;
|
|
121
|
+
else {
|
|
122
|
+
const value = factoryContext.factory(container);
|
|
123
|
+
container.bindValue(token, value);
|
|
124
|
+
return value;
|
|
125
|
+
}
|
|
126
|
+
case "scoped": if (hasValue) return value;
|
|
127
|
+
else {
|
|
128
|
+
const value = factoryContext.factory(container);
|
|
129
|
+
container.bindValue(token, value);
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
case "transient": return factoryContext.factory(origin);
|
|
133
|
+
}
|
|
134
|
+
if (hasValue) return value;
|
|
135
|
+
if (parents) return parentContainersResolveToken(parents, token, origin);
|
|
136
|
+
return NOT_FOUND;
|
|
137
|
+
}
|
|
138
|
+
function executeOnRemoved(tokenSymbol, options) {
|
|
139
|
+
const onRemoved = getOnRemoved(options);
|
|
140
|
+
if (onRemoved) {
|
|
141
|
+
const value = values.get(tokenSymbol);
|
|
142
|
+
if (value !== void 0 || values.has(tokenSymbol)) onRemoved(value);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function bindInternalTokens() {
|
|
146
|
+
values.set(CONTAINER.symbol, container);
|
|
147
|
+
values.set(RESOLVER.symbol, resolver);
|
|
148
|
+
values.set(FACTORIES_MAP.symbol, factories);
|
|
149
|
+
if (parents) values.set(PARENT_CONTAINERS.symbol, parents);
|
|
150
|
+
}
|
|
151
|
+
bindInternalTokens();
|
|
152
|
+
return container;
|
|
153
|
+
}
|
|
154
|
+
function parentContainersHaveToken(parents, token) {
|
|
155
|
+
if (!parents) return false;
|
|
156
|
+
for (let i = 0; i < parents.length; i++) if (parents[i].hasToken(token)) return true;
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
function parentContainersResolveToken(parents, token, origin) {
|
|
160
|
+
for (const parentContainer of parents) {
|
|
161
|
+
const parentResolver = parentContainer.get(RESOLVER);
|
|
162
|
+
if (parentResolver) {
|
|
163
|
+
const resolved = parentResolver(token, origin);
|
|
164
|
+
if (resolved !== NOT_FOUND) return resolved;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return NOT_FOUND;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/utils.ts
|
|
172
|
+
/**
|
|
173
|
+
* Checks if a value is the token
|
|
174
|
+
*/
|
|
175
|
+
function isToken(value) {
|
|
176
|
+
return value !== void 0 && value !== null && typeof value === "object" && "symbol" in value && typeof value.symbol === "symbol";
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Rebinds the array by the token with added new value.
|
|
180
|
+
* @param container - Dependency container.
|
|
181
|
+
* @param token - Token for an array of values.
|
|
182
|
+
* @param value - New value which is added to the end of the array.
|
|
183
|
+
*/
|
|
184
|
+
function bindMultiValue(container, token, value) {
|
|
185
|
+
var _container$get;
|
|
186
|
+
const nextValues = [...(_container$get = container.get(token)) !== null && _container$get !== void 0 ? _container$get : [], value];
|
|
187
|
+
container.bindValue(token, nextValues);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Tries to resolve a value by the provided token.
|
|
191
|
+
*
|
|
192
|
+
* If an argument is an object which has tokens as its properties,
|
|
193
|
+
* then returns an object containing resolved values as properties.
|
|
194
|
+
|
|
195
|
+
* If a token is not found, then `undefined` value is used.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```ts
|
|
199
|
+
* const value = tryResolveValue(container, tokenA);
|
|
200
|
+
* console.log(value); // 1
|
|
201
|
+
*
|
|
202
|
+
* const props = tryResolveValue(container, {a: tokenA, b: tokenB});
|
|
203
|
+
* console.log(props); // {a: 1, b: 2}
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
function tryResolveValue(container, token) {
|
|
207
|
+
if (isToken(token)) return container.get(token);
|
|
208
|
+
const obj = {};
|
|
209
|
+
Object.keys(token).forEach((key) => obj[key] = container.get(token[key]));
|
|
210
|
+
return obj;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Returns an array of resolved values or objects with resolved values.
|
|
214
|
+
*
|
|
215
|
+
* If an item of the array is an object which has tokens as its properties,
|
|
216
|
+
* then returns an object containing resolved values as properties.
|
|
217
|
+
|
|
218
|
+
* If a token is not found, then `undefined` value is used.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```ts
|
|
222
|
+
* const items1 = tryResolveValues(container, tokenA);
|
|
223
|
+
* console.log(items1); // [1]
|
|
224
|
+
*
|
|
225
|
+
* const items2 = tryResolveValues(container, tokenA, {a: tokenA, b: tokenB});
|
|
226
|
+
* console.log(items2); // [1, {a: 1, b: 2}]
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
function tryResolveValues(container, ...tokens) {
|
|
230
|
+
return tokens.map((item) => tryResolveValue(container, item));
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Resolves a value by the provided token.
|
|
234
|
+
*
|
|
235
|
+
* If an argument is an object which has tokens as its properties,
|
|
236
|
+
* then returns an object containing resolved values as properties.
|
|
237
|
+
|
|
238
|
+
* If a value is not found by the token, then `ResolverError` is thrown.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```ts
|
|
242
|
+
* const value = resolveValue(container, tokenA);
|
|
243
|
+
* console.log(value); // 1
|
|
244
|
+
*
|
|
245
|
+
* const props = resolveValue(container, {a: tokenA, b: tokenB});
|
|
246
|
+
* console.log(props); // {a: 1, b: 2}
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
function resolveValue(container, token) {
|
|
250
|
+
if (isToken(token)) return container.resolve(token);
|
|
251
|
+
const obj = {};
|
|
252
|
+
Object.keys(token).forEach((key) => obj[key] = container.resolve(token[key]));
|
|
253
|
+
return obj;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Returns an array of resolved values or objects with resolved values.
|
|
257
|
+
*
|
|
258
|
+
* If an item of the array is an object which has tokens as its properties,
|
|
259
|
+
* then returns an object containing resolved values as properties.
|
|
260
|
+
|
|
261
|
+
* If a token is not found, then `ResolverError` is thrown.
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```ts
|
|
265
|
+
* const items1 = resolveValues(container, tokenA);
|
|
266
|
+
* console.log(items1); // [1]
|
|
267
|
+
*
|
|
268
|
+
* const items2 = resolveValues(container, tokenA, {a: tokenA, b: tokenB});
|
|
269
|
+
* console.log(items2); // [1, {a: 1, b: 2}]
|
|
270
|
+
* ```
|
|
271
|
+
*/
|
|
272
|
+
function resolveValues(container, ...tokens) {
|
|
273
|
+
return tokens.map((item) => resolveValue(container, item));
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Decorates a factory by passing resolved values as factory arguments.
|
|
277
|
+
*
|
|
278
|
+
* If an argument is an object which has tokens as its properties,
|
|
279
|
+
* then returns an object containing resolved values as properties.
|
|
280
|
+
*
|
|
281
|
+
* @param factory - A factory.
|
|
282
|
+
* @param tokens - Tokens which correspond to factory arguments.
|
|
283
|
+
*
|
|
284
|
+
* @return Decorated factory which takes a dependency container as a single argument.
|
|
285
|
+
*/
|
|
286
|
+
function injectable(factory, ...tokens) {
|
|
287
|
+
return (container) => {
|
|
288
|
+
const values = resolveValues(container, ...tokens);
|
|
289
|
+
return factory.apply(this, values);
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Decorates a class by passing resolved values as arguments to its constructor.
|
|
294
|
+
*
|
|
295
|
+
* If an argument is an object which has tokens as its properties,
|
|
296
|
+
* then returns an object containing resolved values as properties.
|
|
297
|
+
*
|
|
298
|
+
* @param constructor - Constructor of a class
|
|
299
|
+
* @param tokens - Tokens which correspond to constructor arguments
|
|
300
|
+
*
|
|
301
|
+
* @return A factory function which takes a dependency container as a single argument
|
|
302
|
+
* and returns a new created class.
|
|
303
|
+
*/
|
|
304
|
+
function injectableClass(constructor, ...tokens) {
|
|
305
|
+
return injectable((...values) => new constructor(...values), ...tokens);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/typeof.js
|
|
310
|
+
function _typeof(o) {
|
|
311
|
+
"@babel/helpers - typeof";
|
|
312
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
313
|
+
return typeof o;
|
|
314
|
+
} : function(o) {
|
|
315
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
316
|
+
}, _typeof(o);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/toPrimitive.js
|
|
321
|
+
function toPrimitive(t, r) {
|
|
322
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
323
|
+
var e = t[Symbol.toPrimitive];
|
|
324
|
+
if (void 0 !== e) {
|
|
325
|
+
var i = e.call(t, r || "default");
|
|
326
|
+
if ("object" != _typeof(i)) return i;
|
|
327
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
328
|
+
}
|
|
329
|
+
return ("string" === r ? String : Number)(t);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
//#endregion
|
|
333
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/toPropertyKey.js
|
|
334
|
+
function toPropertyKey(t) {
|
|
335
|
+
var i = toPrimitive(t, "string");
|
|
336
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
//#endregion
|
|
340
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/defineProperty.js
|
|
341
|
+
function _defineProperty(e, r, t) {
|
|
342
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
343
|
+
value: t,
|
|
344
|
+
enumerable: !0,
|
|
345
|
+
configurable: !0,
|
|
346
|
+
writable: !0
|
|
347
|
+
}) : e[r] = t, e;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
//#endregion
|
|
351
|
+
//#region \0@oxc-project+runtime@0.112.0/helpers/objectSpread2.js
|
|
352
|
+
function ownKeys(e, r) {
|
|
353
|
+
var t = Object.keys(e);
|
|
354
|
+
if (Object.getOwnPropertySymbols) {
|
|
355
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
356
|
+
r && (o = o.filter(function(r) {
|
|
357
|
+
return Object.getOwnPropertyDescriptor(e, r).enumerable;
|
|
358
|
+
})), t.push.apply(t, o);
|
|
359
|
+
}
|
|
360
|
+
return t;
|
|
361
|
+
}
|
|
362
|
+
function _objectSpread2(e) {
|
|
363
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
364
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
365
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function(r) {
|
|
366
|
+
_defineProperty(e, r, t[r]);
|
|
367
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r) {
|
|
368
|
+
Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
return e;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/modules.ts
|
|
376
|
+
/**
|
|
377
|
+
* Binds the dependency module to the container
|
|
378
|
+
* @param container - Dependency container.
|
|
379
|
+
* @param moduleDeclaration - Declaration of the dependency module.
|
|
380
|
+
* @param options - Options for module binding.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```ts
|
|
384
|
+
* bindModule(container, LOGGER_MODULE);
|
|
385
|
+
* ```
|
|
386
|
+
*/
|
|
387
|
+
function bindModule(container, moduleDeclaration, options) {
|
|
388
|
+
const rootEntry = {
|
|
389
|
+
module: moduleDeclaration,
|
|
390
|
+
options: options !== null && options !== void 0 ? options : {}
|
|
391
|
+
};
|
|
392
|
+
const bfsVisits = new Set([rootEntry]);
|
|
393
|
+
const bfsQueue = [rootEntry];
|
|
394
|
+
let bfsIndex = 0;
|
|
395
|
+
while (bfsIndex < bfsQueue.length) {
|
|
396
|
+
var _m$imports;
|
|
397
|
+
const entry = bfsQueue[bfsIndex];
|
|
398
|
+
(_m$imports = ("module" in entry ? entry.module : entry).imports) === null || _m$imports === void 0 || _m$imports.forEach((depEntry) => {
|
|
399
|
+
if (!bfsVisits.has(depEntry)) {
|
|
400
|
+
bfsVisits.add(depEntry);
|
|
401
|
+
bfsQueue.push(depEntry);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
bfsIndex++;
|
|
405
|
+
}
|
|
406
|
+
for (let i = 0; i < bfsQueue.length; i++) {
|
|
407
|
+
var _m$beforeBinding;
|
|
408
|
+
const entry = bfsQueue[i];
|
|
409
|
+
const m = "module" in entry ? entry.module : entry;
|
|
410
|
+
(_m$beforeBinding = m.beforeBinding) === null || _m$beforeBinding === void 0 || _m$beforeBinding.call(m, container);
|
|
411
|
+
}
|
|
412
|
+
for (let i = 0; i < bfsQueue.length; i++) {
|
|
413
|
+
const entry = bfsQueue[i];
|
|
414
|
+
bindModuleEntry(container, entry);
|
|
415
|
+
}
|
|
416
|
+
for (let i = bfsQueue.length - 1; i >= 0; i--) {
|
|
417
|
+
var _m$afterBinding;
|
|
418
|
+
const entry = bfsQueue[i];
|
|
419
|
+
const m = "module" in entry ? entry.module : entry;
|
|
420
|
+
(_m$afterBinding = m.afterBinding) === null || _m$afterBinding === void 0 || _m$afterBinding.call(m, container);
|
|
421
|
+
}
|
|
422
|
+
for (let i = bfsQueue.length - 1; i >= 0; i--) {
|
|
423
|
+
const entry = bfsQueue[i];
|
|
424
|
+
const m = "module" in entry ? entry.module : entry;
|
|
425
|
+
if (m.strategy === "eager") container.resolve(m.token);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
function bindModuleEntry(container, entry) {
|
|
429
|
+
let module;
|
|
430
|
+
let options;
|
|
431
|
+
if ("module" in entry) {
|
|
432
|
+
module = entry.module;
|
|
433
|
+
options = entry.options;
|
|
434
|
+
} else module = entry;
|
|
435
|
+
const scope = options === null || options === void 0 ? void 0 : options.scope;
|
|
436
|
+
const exportedValueTokens = /* @__PURE__ */ new Set();
|
|
437
|
+
const moduleExports = module.exports;
|
|
438
|
+
if (moduleExports) Object.keys(moduleExports).forEach((valueKey) => {
|
|
439
|
+
const valueToken = moduleExports[valueKey];
|
|
440
|
+
if (valueToken) {
|
|
441
|
+
exportedValueTokens.add(valueToken);
|
|
442
|
+
container.bindFactory(valueToken, injectable((module) => module[valueKey], module.token), { scope });
|
|
443
|
+
}
|
|
444
|
+
});
|
|
445
|
+
container.bindFactory(module.token, module.factory, {
|
|
446
|
+
scope,
|
|
447
|
+
onRemoved: (moduleInstance) => {
|
|
448
|
+
if (moduleInstance.destroy) moduleInstance.destroy();
|
|
449
|
+
exportedValueTokens.forEach((valueToken) => container.remove(valueToken));
|
|
450
|
+
exportedValueTokens.clear();
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Binds dependency modules to the container
|
|
456
|
+
*
|
|
457
|
+
* @param container - Dependency container for binding
|
|
458
|
+
* @param modules - Array of module binding entries: module declaration or `{module: ModuleDeclaration, options: BindModuleOptions}` objects.
|
|
459
|
+
*/
|
|
460
|
+
function bindModules(container, modules) {
|
|
461
|
+
modules.forEach((entry) => {
|
|
462
|
+
if ("module" in entry) bindModule(container, entry.module, entry.options);
|
|
463
|
+
else bindModule(container, entry);
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Declares a module binding
|
|
468
|
+
*
|
|
469
|
+
* @param declaration - a module declaration
|
|
470
|
+
* @param declaration.token - optional field
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```ts
|
|
474
|
+
* const LOGGER_MODULE = declareModule<LoggerModule>({
|
|
475
|
+
* factory: (container) => {
|
|
476
|
+
* const transport = container.resolve(TRANSPORT_TOKEN).open();
|
|
477
|
+
* return {
|
|
478
|
+
* logger: { log: (message) => transport.write(message) },
|
|
479
|
+
* destroy: () => transport.close(),
|
|
480
|
+
* }
|
|
481
|
+
* },
|
|
482
|
+
* exports: {
|
|
483
|
+
* logger: LOGGER_TOKEN,
|
|
484
|
+
* },
|
|
485
|
+
* });
|
|
486
|
+
* ```
|
|
487
|
+
*/
|
|
488
|
+
function declareModule(declaration) {
|
|
489
|
+
var _declaration$token;
|
|
490
|
+
return _objectSpread2(_objectSpread2({}, declaration), {}, { token: (_declaration$token = declaration.token) !== null && _declaration$token !== void 0 ? _declaration$token : token() });
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* @deprecated Use `declareModule` instead
|
|
494
|
+
*
|
|
495
|
+
* Declares bindings of several modules
|
|
496
|
+
*
|
|
497
|
+
* @param modules - module declaration entries
|
|
498
|
+
*/
|
|
499
|
+
function declareModuleBindings(modules) {
|
|
500
|
+
return declareModule({
|
|
501
|
+
factory: () => ({}),
|
|
502
|
+
imports: modules
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
//#endregion
|
|
507
|
+
exports.ResolverError = ResolverError;
|
|
508
|
+
exports.bindModule = bindModule;
|
|
509
|
+
exports.bindModules = bindModules;
|
|
510
|
+
exports.bindMultiValue = bindMultiValue;
|
|
511
|
+
exports.createContainer = createContainer;
|
|
512
|
+
exports.declareModule = declareModule;
|
|
513
|
+
exports.declareModuleBindings = declareModuleBindings;
|
|
514
|
+
exports.injectable = injectable;
|
|
515
|
+
exports.injectableClass = injectableClass;
|
|
516
|
+
exports.isToken = isToken;
|
|
517
|
+
exports.optional = optional;
|
|
518
|
+
exports.resolveValue = resolveValue;
|
|
519
|
+
exports.resolveValues = resolveValues;
|
|
520
|
+
exports.token = token;
|
|
521
|
+
exports.tryResolveValue = tryResolveValue;
|
|
522
|
+
exports.tryResolveValues = tryResolveValues;
|
|
523
|
+
});
|
|
524
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","names":[],"sources":["../src/tokens.ts","../src/container.ts","../src/utils.ts","../src/modules.ts"],"sourcesContent":["/**\n * @ignore\n * Binding token for mandatory value\n */\nexport type RequiredToken<T> = {\n symbol: symbol;\n type?: T; // Anchor for Typescript type inference.\n isOptional?: false;\n};\n\n/**\n * @ignore\n * Binding token for optional value\n */\nexport type OptionalToken<T> = {\n symbol: symbol;\n type?: T; // Anchor for Typescript type inference.\n isOptional: true;\n optionalValue: T;\n};\n\n/**\n * Binding token\n */\nexport type Token<T> = RequiredToken<T> | OptionalToken<T>;\n\n/**\n * Token options\n */\nexport type TokenOptions =\n | {\n /**\n * Key for token's symbol. It allows to create shareable tokens.\n */\n key: string;\n\n /** @ignore */\n description?: undefined;\n }\n | {\n /** Description for better error messages */\n description?: string;\n\n /** @ignore */\n key?: undefined;\n };\n\n/**\n * Creates a new binding token.\n * @param description - Token description for better error messages.\n */\nexport function token<T>(description?: string): Token<T>;\n/**\n * Creates a new binding token.\n * @param options - Token description for better error messages.\n */ export function token<T>(options?: TokenOptions): Token<T>;\nexport function token<T>(options?: TokenOptions | string): Token<T> {\n const normalized: TokenOptions | undefined =\n typeof options === 'string' ? { description: options } : options;\n\n const symbol: symbol = normalized?.key\n ? Symbol.for(normalized.key)\n : Symbol(normalized?.description);\n\n return { symbol };\n}\n\n/**\n * Decorate a token with an optional value.\n * This value is be used as default value in case a container does not have registered token.\n * @param token - Existed token.\n * @param optionalValue - Default value for the resolver.\n */\nexport function optional<T>(\n token: Token<T>,\n optionalValue: T,\n): OptionalToken<T>;\nexport function optional<T>(token: Token<T>): OptionalToken<T | undefined>;\nexport function optional<T>(\n token: Token<T>,\n optionalValue?: T,\n): OptionalToken<T | undefined> {\n return {\n symbol: token.symbol,\n isOptional: true,\n optionalValue,\n };\n}\n","import { Token, token } from './tokens';\n\n/**\n * ResolverError is thrown by the resolver when a token is not found in a container.\n */\nexport class ResolverError extends Error {\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n this.name = 'ResolverError';\n }\n}\n\n/**\n * @see https://github.com/mnasyrov/ditox#factory-lifetimes\n */\nexport type FactoryScope = 'scoped' | 'singleton' | 'transient';\n\n/**\n * Options for factory binding.\n *\n * `scope` types:\n * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.\n * - `scoped` - The value is created and cached by the nearest container which owns the factory function.\n * - `transient` - The value is created every time it is resolved.\n *\n * `scoped` and `singleton` scopes can have `onRemoved` callback. It is called when a token is removed from the container.\n */\nexport type FactoryOptions<T> =\n | {\n scope?: 'scoped' | 'singleton';\n onRemoved?: (value: T) => void;\n }\n | {\n scope: 'transient';\n };\n\n/**\n * Dependency container.\n */\nexport type Container = {\n /**\n * Binds a value for the token\n */\n bindValue<T>(token: Token<T>, value: T): void;\n\n /**\n * Binds a factory for the token.\n */\n bindFactory<T>(\n token: Token<T>,\n factory: (container: Container) => T,\n options?: FactoryOptions<T>,\n ): void;\n\n /**\n * Checks if the token is registered in the container hierarchy.\n */\n hasToken(token: Token<unknown>): boolean;\n\n /**\n * Returns a resolved value by the token, or returns `undefined` in case the token is not found.\n */\n get<T>(token: Token<T>): T | undefined;\n\n /**\n * Returns a resolved value by the token or throws `ResolverError` in case the token is not found.\n */\n resolve<T>(token: Token<T>): T;\n\n /**\n * Removes a binding for the token.\n */\n remove<T>(token: Token<T>): void;\n\n /**\n * Removes all bindings in the container.\n */\n removeAll(): void;\n};\n\n/**\n * A subset of Container interface that provides read-only access to dependency resolution.\n * This type is used for parent containers to allow token resolution without exposing mutation methods.\n */\nexport type ContainerResolver = Pick<Container, 'hasToken' | 'get' | 'resolve'>;\n\n/** @internal */\nexport const CONTAINER: Token<Container> = token('ditox.Container');\n/** @internal */\nexport const PARENT_CONTAINERS: Token<ReadonlyArray<Container>> = token(\n 'ditox.ParentContainer',\n);\n/** @internal */\nexport const RESOLVER: Token<Resolver> = token('ditox.Resolver');\n\n/** @internal */\nconst NOT_FOUND = Symbol();\n\n/** @internal */\nconst DEFAULT_SCOPE: FactoryScope = 'singleton';\n\n/** @internal */\ntype FactoryContext<T> = {\n factory: (container: Container) => T;\n options?: FactoryOptions<T>;\n};\n\n/** @internal */\ntype ValuesMap = Map<symbol, any>;\n\n/** @internal */\nexport type FactoriesMap = Map<symbol, FactoryContext<any>>;\n\n/** @internal */\nexport const FACTORIES_MAP: Token<FactoriesMap> = token('ditox.FactoriesMap');\n\n/** @internal */\ntype Resolver = <T>(token: Token<T>, origin: Container) => T | typeof NOT_FOUND;\n\n/** @internal */\nfunction getScope<T>(options?: FactoryOptions<T>): FactoryScope {\n return options?.scope ?? DEFAULT_SCOPE;\n}\n\n/** @internal */\nfunction getOnRemoved<T>(options: FactoryOptions<T>) {\n return options.scope === undefined ||\n options.scope === 'scoped' ||\n options.scope === 'singleton'\n ? options.onRemoved\n : undefined;\n}\n\n/** @internal */\nfunction isInternalToken<T>(token: Token<T>): boolean {\n return (\n token.symbol === CONTAINER.symbol ||\n token.symbol === PARENT_CONTAINERS.symbol ||\n token.symbol === RESOLVER.symbol\n );\n}\n\n/**\n * Creates a new dependency container.\n *\n * Container can have an optional parent to chain token resolution. The parent is used in case the current container does not have a registered token.\n *\n * @param parentArg - Optional parent container or an array of containers.\n */\nexport function createContainer(\n parentArg?: ContainerResolver | ReadonlyArray<ContainerResolver>,\n): Container {\n const parents: ReadonlyArray<ContainerResolver> | undefined = parentArg\n ? Array.isArray(parentArg)\n ? [...parentArg]\n : [parentArg]\n : undefined;\n\n const values: ValuesMap = new Map<symbol, any>();\n const factories: FactoriesMap = new Map<symbol, FactoryContext<any>>();\n\n const container: Container = {\n bindValue<T>(token: Token<T>, value: T): void {\n if (isInternalToken(token)) {\n return;\n }\n\n values.set(token.symbol, value);\n },\n\n bindFactory<T>(\n token: Token<T>,\n factory: (container: Container) => T,\n options?: FactoryOptions<T>,\n ): void {\n if (isInternalToken(token)) {\n return;\n }\n\n factories.set(token.symbol, { factory, options });\n },\n\n remove<T>(token: Token<T>): void {\n if (isInternalToken(token)) {\n return;\n }\n\n const options = factories.get(token.symbol)?.options;\n if (options) {\n executeOnRemoved(token.symbol, options);\n }\n\n values.delete(token.symbol);\n factories.delete(token.symbol);\n },\n\n removeAll(): void {\n factories.forEach((context, tokenSymbol) => {\n if (context.options) {\n executeOnRemoved(tokenSymbol, context.options);\n }\n });\n\n values.clear();\n factories.clear();\n bindInternalTokens();\n },\n\n hasToken(token: Token<unknown>): boolean {\n return (\n values.has(token.symbol) ||\n factories.has(token.symbol) ||\n parentContainersHaveToken(parents, token)\n );\n },\n\n get<T>(token: Token<T>): T | undefined {\n const value = resolver(token, container);\n if (value !== NOT_FOUND) {\n return value;\n }\n\n if (token.isOptional) {\n return token.optionalValue;\n }\n\n return undefined;\n },\n\n resolve<T>(token: Token<T>): T {\n const value = resolver(token, container);\n if (value !== NOT_FOUND) {\n return value;\n }\n\n if (token.isOptional) {\n return token.optionalValue;\n }\n\n throw new ResolverError(\n `Token \"${token.symbol.description ?? ''}\" is not provided`,\n );\n },\n };\n\n function resolver<T>(\n token: Token<T>,\n origin: Container,\n ): T | typeof NOT_FOUND {\n const value = values.get(token.symbol);\n const hasValue = value !== undefined || values.has(token.symbol);\n\n if (hasValue && origin === container) {\n return value;\n }\n\n const factoryContext = factories.get(token.symbol);\n if (factoryContext) {\n const scope = getScope(factoryContext.options);\n\n switch (scope) {\n case 'singleton': {\n if (hasValue) {\n return value;\n } else if (parentContainersHaveToken(parents, token)) {\n break;\n } else {\n // Cache the value in the same container where the factory is registered.\n const value = factoryContext.factory(container);\n container.bindValue(token, value);\n return value;\n }\n }\n\n case 'scoped': {\n if (hasValue) {\n return value;\n } else {\n // Create a value within the factory's container and cache it.\n const value = factoryContext.factory(container);\n container.bindValue(token, value);\n return value;\n }\n }\n\n case 'transient': {\n // Create a value within the origin container and don't cache it.\n return factoryContext.factory(origin);\n }\n }\n }\n\n if (hasValue) {\n return value;\n }\n\n if (parents) {\n return parentContainersResolveToken(parents, token, origin);\n }\n\n return NOT_FOUND;\n }\n\n function executeOnRemoved<T>(\n tokenSymbol: symbol,\n options: FactoryOptions<T>,\n ) {\n const onRemoved = getOnRemoved(options);\n if (onRemoved) {\n const value = values.get(tokenSymbol);\n if (value !== undefined || values.has(tokenSymbol)) {\n onRemoved(value);\n }\n }\n }\n\n function bindInternalTokens() {\n values.set(CONTAINER.symbol, container);\n values.set(RESOLVER.symbol, resolver);\n values.set(FACTORIES_MAP.symbol, factories);\n\n if (parents) {\n values.set(PARENT_CONTAINERS.symbol, parents);\n }\n }\n\n bindInternalTokens();\n return container;\n}\n\nfunction parentContainersHaveToken<T>(\n parents: ReadonlyArray<ContainerResolver> | undefined,\n token: Token<T>,\n): boolean {\n if (!parents) return false;\n\n for (let i = 0; i < parents.length; i++) {\n if (parents[i].hasToken(token)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction parentContainersResolveToken<T>(\n parents: ReadonlyArray<ContainerResolver>,\n token: Token<T>,\n origin: Container,\n): T | typeof NOT_FOUND {\n for (const parentContainer of parents) {\n const parentResolver = parentContainer.get(RESOLVER);\n if (parentResolver) {\n const resolved = parentResolver(token, origin);\n if (resolved !== NOT_FOUND) {\n return resolved;\n }\n }\n }\n\n return NOT_FOUND;\n}\n","import type { Container } from './container';\nimport { Token } from './tokens';\n\ntype ValuesProps = { [key: string]: unknown };\ntype TokenProps<Props extends ValuesProps> = {\n [K in keyof Props]: Token<Props[K]>;\n};\n\n/**\n * Checks if a value is the token\n */\nexport function isToken<T>(value: unknown): value is Token<T> {\n return (\n value !== undefined &&\n value !== null &&\n typeof value === 'object' &&\n 'symbol' in value &&\n typeof (value as any).symbol === 'symbol'\n );\n}\n\n/**\n * Rebinds the array by the token with added new value.\n * @param container - Dependency container.\n * @param token - Token for an array of values.\n * @param value - New value which is added to the end of the array.\n */\nexport function bindMultiValue<T>(\n container: Container,\n token: Token<ReadonlyArray<T>>,\n value: T,\n): void {\n const prevValues = container.get(token) ?? [];\n const nextValues = [...prevValues, value];\n container.bindValue(token, nextValues);\n}\n\n/**\n * Tries to resolve a value by the provided token.\n *\n * If an argument is an object which has tokens as its properties,\n * then returns an object containing resolved values as properties.\n\n * If a token is not found, then `undefined` value is used.\n *\n * @example\n * ```ts\n * const value = tryResolveValue(container, tokenA);\n * console.log(value); // 1\n *\n * const props = tryResolveValue(container, {a: tokenA, b: tokenB});\n * console.log(props); // {a: 1, b: 2}\n * ```\n */\nexport function tryResolveValue<\n Tokens extends Token<unknown> | { [key: string]: Token<unknown> },\n Values extends Tokens extends Token<infer V>\n ? V | undefined\n : Tokens extends TokenProps<infer Props>\n ? Partial<Props>\n : never,\n>(container: Container, token: Tokens): Values {\n if (isToken(token)) {\n return container.get(token) as Values;\n }\n\n const obj: any = {};\n Object.keys(token).forEach((key) => (obj[key] = container.get(token[key])));\n return obj;\n}\n\n/**\n * Returns an array of resolved values or objects with resolved values.\n *\n * If an item of the array is an object which has tokens as its properties,\n * then returns an object containing resolved values as properties.\n\n * If a token is not found, then `undefined` value is used.\n *\n * @example\n * ```ts\n * const items1 = tryResolveValues(container, tokenA);\n * console.log(items1); // [1]\n *\n * const items2 = tryResolveValues(container, tokenA, {a: tokenA, b: tokenB});\n * console.log(items2); // [1, {a: 1, b: 2}]\n * ```\n */\nexport function tryResolveValues<\n Tokens extends (Token<unknown> | { [key: string]: Token<unknown> })[],\n Values extends {\n [K in keyof Tokens]: Tokens[K] extends Token<infer V>\n ? V | undefined\n : Tokens[K] extends TokenProps<infer Props>\n ? Partial<Props>\n : never;\n },\n>(container: Container, ...tokens: Tokens): Values {\n return tokens.map((item) => tryResolveValue(container, item)) as Values;\n}\n\n/**\n * Resolves a value by the provided token.\n *\n * If an argument is an object which has tokens as its properties,\n * then returns an object containing resolved values as properties.\n\n * If a value is not found by the token, then `ResolverError` is thrown.\n *\n * @example\n * ```ts\n * const value = resolveValue(container, tokenA);\n * console.log(value); // 1\n *\n * const props = resolveValue(container, {a: tokenA, b: tokenB});\n * console.log(props); // {a: 1, b: 2}\n * ```\n */\nexport function resolveValue<\n Tokens extends Token<unknown> | { [key: string]: Token<unknown> },\n Values extends Tokens extends Token<infer V>\n ? V\n : Tokens extends TokenProps<infer Props>\n ? Props\n : never,\n>(container: Container, token: Tokens): Values {\n if (isToken(token)) {\n return container.resolve(token) as Values;\n }\n\n const obj: any = {};\n Object.keys(token).forEach(\n (key) => (obj[key] = container.resolve(token[key])),\n );\n return obj;\n}\n\n/**\n * Returns an array of resolved values or objects with resolved values.\n *\n * If an item of the array is an object which has tokens as its properties,\n * then returns an object containing resolved values as properties.\n\n * If a token is not found, then `ResolverError` is thrown.\n *\n * @example\n * ```ts\n * const items1 = resolveValues(container, tokenA);\n * console.log(items1); // [1]\n *\n * const items2 = resolveValues(container, tokenA, {a: tokenA, b: tokenB});\n * console.log(items2); // [1, {a: 1, b: 2}]\n * ```\n */\nexport function resolveValues<\n Tokens extends (Token<unknown> | { [key: string]: Token<unknown> })[],\n Values extends {\n [K in keyof Tokens]: Tokens[K] extends Token<infer V>\n ? V\n : Tokens[K] extends TokenProps<infer Props>\n ? Props\n : never;\n },\n>(container: Container, ...tokens: Tokens): Values {\n return tokens.map((item) => resolveValue(container, item)) as Values;\n}\n\n/**\n * Decorates a factory by passing resolved values as factory arguments.\n *\n * If an argument is an object which has tokens as its properties,\n * then returns an object containing resolved values as properties.\n *\n * @param factory - A factory.\n * @param tokens - Tokens which correspond to factory arguments.\n *\n * @return Decorated factory which takes a dependency container as a single argument.\n */\nexport function injectable<\n Tokens extends (Token<unknown> | { [key: string]: Token<unknown> })[],\n Values extends {\n [K in keyof Tokens]: Tokens[K] extends Token<infer V>\n ? V\n : Tokens[K] extends TokenProps<infer Props>\n ? Props\n : never;\n },\n Result,\n>(\n this: unknown,\n factory: (...params: Values) => Result,\n ...tokens: Tokens\n): (container: Container) => Result {\n return (container) => {\n const values: Values = resolveValues(container, ...tokens);\n return factory.apply(this, values);\n };\n}\n\n/**\n * Decorates a class by passing resolved values as arguments to its constructor.\n *\n * If an argument is an object which has tokens as its properties,\n * then returns an object containing resolved values as properties.\n *\n * @param constructor - Constructor of a class\n * @param tokens - Tokens which correspond to constructor arguments\n *\n * @return A factory function which takes a dependency container as a single argument\n * and returns a new created class.\n */\nexport function injectableClass<\n Tokens extends (Token<unknown> | { [key: string]: Token<unknown> })[],\n Values extends {\n [K in keyof Tokens]: Tokens[K] extends Token<infer V>\n ? V\n : Tokens[K] extends TokenProps<infer Props>\n ? Props\n : never;\n },\n Result,\n>(\n this: unknown,\n constructor: new (...params: Values) => Result,\n ...tokens: Tokens\n): (container: Container) => Result {\n return injectable<Tokens, Values, Result>(\n (...values) => new constructor(...values),\n ...tokens,\n );\n}\n","import { Container } from './container';\nimport { Token, token } from './tokens';\nimport { injectable } from './utils';\n\ntype AnyObject = Record<string, any>;\ntype EmptyObject = Record<string, never>;\n\ntype ModuleController = {\n /** Dispose the module and clean its resources */\n destroy?: () => void;\n};\n\n/**\n * Dependency module\n *\n * @example\n * ```ts\n * type LoggerModule = Module<{\n * logger: Logger;\n * }>;\n * ```\n */\nexport type Module<ModuleProps extends AnyObject = EmptyObject> =\n ModuleController & ModuleProps;\n\ntype GetModuleProps<T> = T extends Module<infer Props> ? Props : never;\n\n/**\n * Description how to bind the module in declarative way.\n *\n * @example\n * ```ts\n * const LOGGER_MODULE: ModuleDeclaration<LoggerModule> = {\n * token: LOGGER_MODULE_TOKEN,\n * factory: (container) => {\n * const transport = container.resolve(TRANSPORT_TOKEN).open();\n * return {\n * logger: { log: (message) => transport.write(message) },\n * destroy: () => transport.close(),\n * }\n * },\n * exports: {\n * logger: LOGGER_TOKEN,\n * },\n * };\n * ```\n */\nexport type ModuleDeclaration<T extends Module<AnyObject>> = {\n /** Token for the module */\n token: Token<T>;\n\n /** Modules for binding */\n imports?: ReadonlyArray<ModuleBindingEntry>;\n\n /** Factory of the module */\n factory: (container: Container) => T;\n\n /** Dictionary of module properties which are bound to tokens. */\n exports?: {\n [K in keyof GetModuleProps<T>]?: Token<GetModuleProps<T>[K]>;\n };\n\n /** Callback could be used to prepare an environment. It is called before binding the module. */\n beforeBinding?: (container: Container) => void;\n\n /** Callback could be used to export complex dependencies from the module. It is called after binding the module. */\n afterBinding?: (container: Container) => void;\n\n /**\n * Strategy for executing the factory:\n * - `lazy` - **This is the default**. The factory is called when the module is resolved.\n * - `eager` - The factory is called immediately after the module is bound to the container.\n */\n strategy?: 'eager' | 'lazy';\n};\n\nexport type AnyModuleDeclaration = ModuleDeclaration<Module<AnyObject>>;\n\n/**\n * Options for module binding.\n *\n * `scope` types:\n * - `singleton` - **This is the default**. The value is created and cached by the most distant parent container which owns the factory function.\n * - `scoped` - The value is created and cached by the nearest container which owns the factory function.\n */\nexport type BindModuleOptions = {\n scope?: 'scoped' | 'singleton';\n};\n\ntype ModuleDeclarationWithOptions = {\n module: ModuleDeclaration<AnyObject>;\n options: BindModuleOptions;\n};\n\nexport type ModuleBindingEntry =\n | ModuleDeclaration<AnyObject>\n | ModuleDeclarationWithOptions;\n\n/**\n * Binds the dependency module to the container\n * @param container - Dependency container.\n * @param moduleDeclaration - Declaration of the dependency module.\n * @param options - Options for module binding.\n *\n * @example\n * ```ts\n * bindModule(container, LOGGER_MODULE);\n * ```\n */\nexport function bindModule<T extends Module<AnyObject>>(\n container: Container,\n moduleDeclaration: ModuleDeclaration<T>,\n options?: BindModuleOptions,\n): void {\n const rootEntry: ModuleBindingEntry = {\n module: moduleDeclaration,\n options: options ?? {},\n };\n\n const bfsVisits = new Set<ModuleBindingEntry>([rootEntry]);\n const bfsQueue: ModuleBindingEntry[] = [rootEntry];\n\n let bfsIndex = 0;\n while (bfsIndex < bfsQueue.length) {\n const entry = bfsQueue[bfsIndex];\n\n const m = 'module' in entry ? entry.module : entry;\n\n m.imports?.forEach((depEntry) => {\n if (!bfsVisits.has(depEntry)) {\n bfsVisits.add(depEntry);\n bfsQueue.push(depEntry);\n }\n });\n\n bfsIndex++;\n }\n\n for (let i = 0; i < bfsQueue.length; i++) {\n const entry = bfsQueue[i];\n const m = 'module' in entry ? entry.module : entry;\n m.beforeBinding?.(container);\n }\n\n for (let i = 0; i < bfsQueue.length; i++) {\n const entry = bfsQueue[i];\n bindModuleEntry(container, entry);\n }\n\n for (let i = bfsQueue.length - 1; i >= 0; i--) {\n const entry = bfsQueue[i];\n const m = 'module' in entry ? entry.module : entry;\n m.afterBinding?.(container);\n }\n\n for (let i = bfsQueue.length - 1; i >= 0; i--) {\n const entry = bfsQueue[i];\n const m = 'module' in entry ? entry.module : entry;\n if (m.strategy === 'eager') {\n container.resolve(m.token);\n }\n }\n}\n\nfunction bindModuleEntry(\n container: Container,\n entry: ModuleBindingEntry,\n): void {\n let module: ModuleDeclaration<AnyObject>;\n let options: BindModuleOptions | undefined;\n\n if ('module' in entry) {\n module = entry.module;\n options = entry.options;\n } else {\n module = entry;\n }\n\n const scope = options?.scope;\n const exportedValueTokens = new Set<Token<unknown>>();\n const moduleExports = module.exports;\n\n if (moduleExports) {\n const keys = Object.keys(moduleExports);\n\n keys.forEach((valueKey) => {\n const valueToken = moduleExports[valueKey];\n if (valueToken) {\n exportedValueTokens.add(valueToken);\n\n container.bindFactory(\n valueToken,\n injectable((module) => module[valueKey], module.token),\n { scope },\n );\n }\n });\n }\n\n container.bindFactory(module.token, module.factory, {\n scope,\n onRemoved: (moduleInstance) => {\n if (moduleInstance.destroy) {\n moduleInstance.destroy();\n }\n\n exportedValueTokens.forEach((valueToken) => container.remove(valueToken));\n exportedValueTokens.clear();\n },\n });\n}\n\n/**\n * Binds dependency modules to the container\n *\n * @param container - Dependency container for binding\n * @param modules - Array of module binding entries: module declaration or `{module: ModuleDeclaration, options: BindModuleOptions}` objects.\n */\nexport function bindModules(\n container: Container,\n modules: ReadonlyArray<ModuleBindingEntry>,\n): void {\n modules.forEach((entry) => {\n if ('module' in entry) {\n bindModule(container, entry.module, entry.options);\n } else {\n bindModule(container, entry);\n }\n });\n}\n\n/**\n * Declares a module binding\n *\n * @param declaration - a module declaration\n * @param declaration.token - optional field\n *\n * @example\n * ```ts\n * const LOGGER_MODULE = declareModule<LoggerModule>({\n * factory: (container) => {\n * const transport = container.resolve(TRANSPORT_TOKEN).open();\n * return {\n * logger: { log: (message) => transport.write(message) },\n * destroy: () => transport.close(),\n * }\n * },\n * exports: {\n * logger: LOGGER_TOKEN,\n * },\n * });\n * ```\n */\nexport function declareModule<T extends Module<AnyObject>>(\n declaration: Omit<ModuleDeclaration<T>, 'token'> &\n Partial<Pick<ModuleDeclaration<T>, 'token'>>,\n): ModuleDeclaration<T> {\n return { ...declaration, token: declaration.token ?? token() };\n}\n\n/**\n * @deprecated Use `declareModule` instead\n *\n * Declares bindings of several modules\n *\n * @param modules - module declaration entries\n */\nexport function declareModuleBindings(\n modules: ReadonlyArray<ModuleBindingEntry>,\n): ModuleDeclaration<Module> {\n return declareModule({\n factory: () => ({}),\n imports: modules,\n });\n}\n"],"mappings":";;;;;;;;CAwDA,SAAgB,MAAS,SAA2C;EAClE,MAAM,aACJ,OAAO,YAAY,WAAW,EAAE,aAAa,SAAS,GAAG;AAM3D,SAAO,EAAE,iEAJc,WAAY,OAC/B,OAAO,IAAI,WAAW,IAAI,GAC1B,+DAAO,WAAY,YAAY,EAElB;;CAcnB,SAAgB,SACd,OACA,eAC8B;AAC9B,SAAO;GACL,QAAQ,MAAM;GACd,YAAY;GACZ;GACD;;;;;;;;CCjFH,IAAa,gBAAb,cAAmC,MAAM;EACvC,YAAY,SAAiB;AAC3B,SAAM,QAAQ;AACd,UAAO,eAAe,MAAM,IAAI,OAAO,UAAU;AACjD,QAAK,OAAO;;;;CA+EhB,MAAa,YAA8B,MAAM,kBAAkB;;CAEnE,MAAa,oBAAqD,MAChE,wBACD;;CAED,MAAa,WAA4B,MAAM,iBAAiB;;CAGhE,MAAM,YAAY,QAAQ;;CAG1B,MAAM,gBAA8B;;CAepC,MAAa,gBAAqC,MAAM,qBAAqB;;CAM7E,SAAS,SAAY,SAA2C;;AAC9D,6EAAO,QAAS,gEAAS;;;CAI3B,SAAS,aAAgB,SAA4B;AACnD,SAAO,QAAQ,UAAU,UACvB,QAAQ,UAAU,YAClB,QAAQ,UAAU,cAChB,QAAQ,YACR;;;CAIN,SAAS,gBAAmB,OAA0B;AACpD,SACE,MAAM,WAAW,UAAU,UAC3B,MAAM,WAAW,kBAAkB,UACnC,MAAM,WAAW,SAAS;;;;;;;;;CAW9B,SAAgB,gBACd,WACW;EACX,MAAM,UAAwD,YAC1D,MAAM,QAAQ,UAAU,GACtB,CAAC,GAAG,UAAU,GACd,CAAC,UAAU,GACb;EAEJ,MAAM,yBAAoB,IAAI,KAAkB;EAChD,MAAM,4BAA0B,IAAI,KAAkC;EAEtE,MAAM,YAAuB;GAC3B,UAAa,OAAiB,OAAgB;AAC5C,QAAI,gBAAgB,MAAM,CACxB;AAGF,WAAO,IAAI,MAAM,QAAQ,MAAM;;GAGjC,YACE,OACA,SACA,SACM;AACN,QAAI,gBAAgB,MAAM,CACxB;AAGF,cAAU,IAAI,MAAM,QAAQ;KAAE;KAAS;KAAS,CAAC;;GAGnD,OAAU,OAAuB;;AAC/B,QAAI,gBAAgB,MAAM,CACxB;IAGF,MAAM,4BAAU,UAAU,IAAI,MAAM,OAAO,kEAAE;AAC7C,QAAI,QACF,kBAAiB,MAAM,QAAQ,QAAQ;AAGzC,WAAO,OAAO,MAAM,OAAO;AAC3B,cAAU,OAAO,MAAM,OAAO;;GAGhC,YAAkB;AAChB,cAAU,SAAS,SAAS,gBAAgB;AAC1C,SAAI,QAAQ,QACV,kBAAiB,aAAa,QAAQ,QAAQ;MAEhD;AAEF,WAAO,OAAO;AACd,cAAU,OAAO;AACjB,wBAAoB;;GAGtB,SAAS,OAAgC;AACvC,WACE,OAAO,IAAI,MAAM,OAAO,IACxB,UAAU,IAAI,MAAM,OAAO,IAC3B,0BAA0B,SAAS,MAAM;;GAI7C,IAAO,OAAgC;IACrC,MAAM,QAAQ,SAAS,OAAO,UAAU;AACxC,QAAI,UAAU,UACZ,QAAO;AAGT,QAAI,MAAM,WACR,QAAO,MAAM;;GAMjB,QAAW,OAAoB;;IAC7B,MAAM,QAAQ,SAAS,OAAO,UAAU;AACxC,QAAI,UAAU,UACZ,QAAO;AAGT,QAAI,MAAM,WACR,QAAO,MAAM;AAGf,UAAM,IAAI,cACR,mCAAU,MAAM,OAAO,oFAAe,GAAG,mBAC1C;;GAEJ;EAED,SAAS,SACP,OACA,QACsB;GACtB,MAAM,QAAQ,OAAO,IAAI,MAAM,OAAO;GACtC,MAAM,WAAW,UAAU,UAAa,OAAO,IAAI,MAAM,OAAO;AAEhE,OAAI,YAAY,WAAW,UACzB,QAAO;GAGT,MAAM,iBAAiB,UAAU,IAAI,MAAM,OAAO;AAClD,OAAI,eAGF,SAFc,SAAS,eAAe,QAAQ,EAE9C;IACE,KAAK,YACH,KAAI,SACF,QAAO;aACE,0BAA0B,SAAS,MAAM,CAClD;SACK;KAEL,MAAM,QAAQ,eAAe,QAAQ,UAAU;AAC/C,eAAU,UAAU,OAAO,MAAM;AACjC,YAAO;;IAIX,KAAK,SACH,KAAI,SACF,QAAO;SACF;KAEL,MAAM,QAAQ,eAAe,QAAQ,UAAU;AAC/C,eAAU,UAAU,OAAO,MAAM;AACjC,YAAO;;IAIX,KAAK,YAEH,QAAO,eAAe,QAAQ,OAAO;;AAK3C,OAAI,SACF,QAAO;AAGT,OAAI,QACF,QAAO,6BAA6B,SAAS,OAAO,OAAO;AAG7D,UAAO;;EAGT,SAAS,iBACP,aACA,SACA;GACA,MAAM,YAAY,aAAa,QAAQ;AACvC,OAAI,WAAW;IACb,MAAM,QAAQ,OAAO,IAAI,YAAY;AACrC,QAAI,UAAU,UAAa,OAAO,IAAI,YAAY,CAChD,WAAU,MAAM;;;EAKtB,SAAS,qBAAqB;AAC5B,UAAO,IAAI,UAAU,QAAQ,UAAU;AACvC,UAAO,IAAI,SAAS,QAAQ,SAAS;AACrC,UAAO,IAAI,cAAc,QAAQ,UAAU;AAE3C,OAAI,QACF,QAAO,IAAI,kBAAkB,QAAQ,QAAQ;;AAIjD,sBAAoB;AACpB,SAAO;;CAGT,SAAS,0BACP,SACA,OACS;AACT,MAAI,CAAC,QAAS,QAAO;AAErB,OAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,QAAQ,IAClC,KAAI,QAAQ,GAAG,SAAS,MAAM,CAC5B,QAAO;AAIX,SAAO;;CAGT,SAAS,6BACP,SACA,OACA,QACsB;AACtB,OAAK,MAAM,mBAAmB,SAAS;GACrC,MAAM,iBAAiB,gBAAgB,IAAI,SAAS;AACpD,OAAI,gBAAgB;IAClB,MAAM,WAAW,eAAe,OAAO,OAAO;AAC9C,QAAI,aAAa,UACf,QAAO;;;AAKb,SAAO;;;;;;;;CC9VT,SAAgB,QAAW,OAAmC;AAC5D,SACE,UAAU,UACV,UAAU,QACV,OAAO,UAAU,YACjB,YAAY,SACZ,OAAQ,MAAc,WAAW;;;;;;;;CAUrC,SAAgB,eACd,WACA,OACA,OACM;;EAEN,MAAM,aAAa,CAAC,qBADD,UAAU,IAAI,MAAM,2DAAI,EAAE,EACV,MAAM;AACzC,YAAU,UAAU,OAAO,WAAW;;;;;;;;;;;;;;;;;;;CAoBxC,SAAgB,gBAOd,WAAsB,OAAuB;AAC7C,MAAI,QAAQ,MAAM,CAChB,QAAO,UAAU,IAAI,MAAM;EAG7B,MAAM,MAAW,EAAE;AACnB,SAAO,KAAK,MAAM,CAAC,SAAS,QAAS,IAAI,OAAO,UAAU,IAAI,MAAM,KAAK,CAAE;AAC3E,SAAO;;;;;;;;;;;;;;;;;;;CAoBT,SAAgB,iBASd,WAAsB,GAAG,QAAwB;AACjD,SAAO,OAAO,KAAK,SAAS,gBAAgB,WAAW,KAAK,CAAC;;;;;;;;;;;;;;;;;;;CAoB/D,SAAgB,aAOd,WAAsB,OAAuB;AAC7C,MAAI,QAAQ,MAAM,CAChB,QAAO,UAAU,QAAQ,MAAM;EAGjC,MAAM,MAAW,EAAE;AACnB,SAAO,KAAK,MAAM,CAAC,SAChB,QAAS,IAAI,OAAO,UAAU,QAAQ,MAAM,KAAK,CACnD;AACD,SAAO;;;;;;;;;;;;;;;;;;;CAoBT,SAAgB,cASd,WAAsB,GAAG,QAAwB;AACjD,SAAO,OAAO,KAAK,SAAS,aAAa,WAAW,KAAK,CAAC;;;;;;;;;;;;;CAc5D,SAAgB,WAYd,SACA,GAAG,QAC+B;AAClC,UAAQ,cAAc;GACpB,MAAM,SAAiB,cAAc,WAAW,GAAG,OAAO;AAC1D,UAAO,QAAQ,MAAM,MAAM,OAAO;;;;;;;;;;;;;;;CAgBtC,SAAgB,gBAYd,aACA,GAAG,QAC+B;AAClC,SAAO,YACJ,GAAG,WAAW,IAAI,YAAY,GAAG,OAAO,EACzC,GAAG,OACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CCxHH,SAAgB,WACd,WACA,mBACA,SACM;EACN,MAAM,YAAgC;GACpC,QAAQ;GACR,SAAS,mDAAW,EAAE;GACvB;EAED,MAAM,YAAY,IAAI,IAAwB,CAAC,UAAU,CAAC;EAC1D,MAAM,WAAiC,CAAC,UAAU;EAElD,IAAI,WAAW;AACf,SAAO,WAAW,SAAS,QAAQ;;GACjC,MAAM,QAAQ,SAAS;AAIvB,kBAFU,YAAY,QAAQ,MAAM,SAAS,OAE3C,yDAAS,SAAS,aAAa;AAC/B,QAAI,CAAC,UAAU,IAAI,SAAS,EAAE;AAC5B,eAAU,IAAI,SAAS;AACvB,cAAS,KAAK,SAAS;;KAEzB;AAEF;;AAGF,OAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;;GACxC,MAAM,QAAQ,SAAS;GACvB,MAAM,IAAI,YAAY,QAAQ,MAAM,SAAS;AAC7C,yBAAE,mFAAgB,UAAU;;AAG9B,OAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;GACxC,MAAM,QAAQ,SAAS;AACvB,mBAAgB,WAAW,MAAM;;AAGnC,OAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;;GAC7C,MAAM,QAAQ,SAAS;GACvB,MAAM,IAAI,YAAY,QAAQ,MAAM,SAAS;AAC7C,wBAAE,gFAAe,UAAU;;AAG7B,OAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;GAC7C,MAAM,QAAQ,SAAS;GACvB,MAAM,IAAI,YAAY,QAAQ,MAAM,SAAS;AAC7C,OAAI,EAAE,aAAa,QACjB,WAAU,QAAQ,EAAE,MAAM;;;CAKhC,SAAS,gBACP,WACA,OACM;EACN,IAAI;EACJ,IAAI;AAEJ,MAAI,YAAY,OAAO;AACrB,YAAS,MAAM;AACf,aAAU,MAAM;QAEhB,UAAS;EAGX,MAAM,0DAAQ,QAAS;EACvB,MAAM,sCAAsB,IAAI,KAAqB;EACrD,MAAM,gBAAgB,OAAO;AAE7B,MAAI,cAGF,CAFa,OAAO,KAAK,cAAc,CAElC,SAAS,aAAa;GACzB,MAAM,aAAa,cAAc;AACjC,OAAI,YAAY;AACd,wBAAoB,IAAI,WAAW;AAEnC,cAAU,YACR,YACA,YAAY,WAAW,OAAO,WAAW,OAAO,MAAM,EACtD,EAAE,OAAO,CACV;;IAEH;AAGJ,YAAU,YAAY,OAAO,OAAO,OAAO,SAAS;GAClD;GACA,YAAY,mBAAmB;AAC7B,QAAI,eAAe,QACjB,gBAAe,SAAS;AAG1B,wBAAoB,SAAS,eAAe,UAAU,OAAO,WAAW,CAAC;AACzE,wBAAoB,OAAO;;GAE9B,CAAC;;;;;;;;CASJ,SAAgB,YACd,WACA,SACM;AACN,UAAQ,SAAS,UAAU;AACzB,OAAI,YAAY,MACd,YAAW,WAAW,MAAM,QAAQ,MAAM,QAAQ;OAElD,YAAW,WAAW,MAAM;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;CAyBJ,SAAgB,cACd,aAEsB;;AACtB,2CAAY,oBAAa,6BAAO,YAAY,wEAAS,OAAO;;;;;;;;;CAU9D,SAAgB,sBACd,SAC2B;AAC3B,SAAO,cAAc;GACnB,gBAAgB,EAAE;GAClB,SAAS;GACV,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ditox",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "Dependency injection for
|
|
3
|
+
"version": "3.3.0",
|
|
4
|
+
"description": "Dependency injection for web applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Mikhail Nasyrov <mikhail@mnasyrov.com> (https://github.com/mnasyrov)",
|
|
7
7
|
"homepage": "https://github.com/mnasyrov/ditox",
|
|
8
8
|
"bugs": "https://github.com/mnasyrov/ditox/issues",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "https://github.com/mnasyrov/ditox.git"
|
|
11
|
+
"url": "git+https://github.com/mnasyrov/ditox.git"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [
|
|
14
14
|
"dependency container",
|
|
@@ -26,16 +26,6 @@
|
|
|
26
26
|
"engines": {
|
|
27
27
|
"node": ">=12"
|
|
28
28
|
},
|
|
29
|
-
"main": "dist/cjs/index.js",
|
|
30
|
-
"module": "dist/esm/index.js",
|
|
31
|
-
"jsnext:main": "dist/esm/index.js",
|
|
32
|
-
"unpkg": "dist/umd/index.js",
|
|
33
|
-
"umd:main": "dist/umd/index.js",
|
|
34
|
-
"browser": "dist/browser/index.js",
|
|
35
|
-
"react-native": "dist/browser/index.js",
|
|
36
|
-
"types": "dist/esm/index.d.ts",
|
|
37
|
-
"source": "src/index.ts",
|
|
38
|
-
"sideEffects": false,
|
|
39
29
|
"files": [
|
|
40
30
|
"dist",
|
|
41
31
|
"docs",
|
|
@@ -43,13 +33,26 @@
|
|
|
43
33
|
"LICENSE",
|
|
44
34
|
"README.md"
|
|
45
35
|
],
|
|
36
|
+
"type": "module",
|
|
37
|
+
"main": "./dist/index.cjs",
|
|
38
|
+
"module": "./dist/index.js",
|
|
39
|
+
"unpkg": "dist/index.umd.js",
|
|
40
|
+
"umd:main": "dist/index.umd.js",
|
|
41
|
+
"browser": "dist/index.js",
|
|
42
|
+
"react-native": "dist/index.js",
|
|
43
|
+
"types": "./dist/index.d.cts",
|
|
44
|
+
"source": "src/index.ts",
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"import": "./dist/index.js",
|
|
48
|
+
"require": "./dist/index.cjs"
|
|
49
|
+
},
|
|
50
|
+
"./package.json": "./package.json"
|
|
51
|
+
},
|
|
46
52
|
"scripts": {
|
|
47
|
-
"clean": "
|
|
48
|
-
"build": "
|
|
49
|
-
"build:cjs": "tsc -p tsconfig.build.json --outDir dist/cjs --module commonjs",
|
|
50
|
-
"build:esm": "tsc -p tsconfig.build.json --outDir dist/esm --module es2015",
|
|
51
|
-
"build:rollup": "rollup -c",
|
|
53
|
+
"clean": "rm -rf dist lib",
|
|
54
|
+
"build": "tsdown",
|
|
52
55
|
"typedoc": "typedoc"
|
|
53
56
|
},
|
|
54
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "b092f487c06b35fb2c1125303d6e4942bc2a66b9"
|
|
55
58
|
}
|