@lppedd/di-wise-neo 0.7.1 → 0.8.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.
@@ -187,8 +187,6 @@ interface RegistrationOptions {
187
187
  * );
188
188
  * }
189
189
  * ```
190
- *
191
- * @__NO_SIDE_EFFECTS__
192
190
  */
193
191
  declare function build<Value>(factory: (...args: []) => Value): Type<Value>;
194
192
 
@@ -811,6 +809,17 @@ interface Injector {
811
809
  * or an empty array if the token is not registered in the container.
812
810
  */
813
811
  optionalAll<Value>(token: Token<Value>): NonNullable<Value>[];
812
+ /**
813
+ * Runs a function inside the injection context of this injector.
814
+ *
815
+ * Note that injection functions (`inject`, `injectAll`, `optional`, `optionalAll`)
816
+ * are only usable synchronously: they cannot be called from asynchronous callbacks
817
+ * or after any `await` points.
818
+ *
819
+ * @param fn The function to be run in the context of this injector.
820
+ * @returns The return value of the function, if any.
821
+ */
822
+ runInContext<ReturnType>(fn: () => ReturnType): ReturnType;
814
823
  }
815
824
  /**
816
825
  * Injector token for dynamic injections.
package/dist/cjs/index.js CHANGED
@@ -31,23 +31,6 @@ function untag(message) {
31
31
  return message.startsWith("[di-wise-neo]") ? message.substring(13).trimStart() : message;
32
32
  }
33
33
 
34
- // @internal
35
- function createInjectionContext() {
36
- let current = null;
37
- function provide(next) {
38
- const prev = current;
39
- current = next;
40
- return ()=>current = prev;
41
- }
42
- function use() {
43
- return current;
44
- }
45
- return [
46
- provide,
47
- use
48
- ];
49
- }
50
-
51
34
  // @internal
52
35
  function invariant(condition) {
53
36
  if (!condition) {
@@ -117,18 +100,33 @@ function createResolution() {
117
100
  // @internal
118
101
  const [provideInjectionContext, useInjectionContext] = createInjectionContext();
119
102
  // @internal
120
- function ensureInjectionContext(fn) {
103
+ function ensureInjectionContext(name) {
121
104
  const context = useInjectionContext();
122
- assert(context, `${fn.name}() can only be invoked within an injection context`);
105
+ assert(context, `${name} can only be invoked within an injection context`);
123
106
  return context;
124
107
  }
108
+ function createInjectionContext() {
109
+ let current = null;
110
+ function provide(next) {
111
+ const prev = current;
112
+ current = next;
113
+ return ()=>current = prev;
114
+ }
115
+ function use() {
116
+ return current;
117
+ }
118
+ return [
119
+ provide,
120
+ use
121
+ ];
122
+ }
125
123
 
126
124
  function inject(token, name) {
127
- const context = ensureInjectionContext(inject);
125
+ const context = ensureInjectionContext("inject()");
128
126
  return context.container.resolve(token, name);
129
127
  }
130
128
  function injectBy(thisArg, token, name) {
131
- const context = ensureInjectionContext(injectBy);
129
+ const context = ensureInjectionContext("injectBy()");
132
130
  const resolution = context.resolution;
133
131
  const currentFrame = resolution.stack.peek();
134
132
  if (!currentFrame) {
@@ -146,7 +144,7 @@ function injectBy(thisArg, token, name) {
146
144
  }
147
145
 
148
146
  function injectAll(token) {
149
- const context = ensureInjectionContext(injectAll);
147
+ const context = ensureInjectionContext("injectAll()");
150
148
  return context.container.resolveAll(token);
151
149
  }
152
150
 
@@ -242,11 +240,11 @@ const classIdentityMap = new WeakMap();
242
240
  const metadataMap = new WeakMap();
243
241
 
244
242
  function optional(token, name) {
245
- const context = ensureInjectionContext(optional);
243
+ const context = ensureInjectionContext("optional()");
246
244
  return context.container.resolve(token, true, name);
247
245
  }
248
246
  function optionalBy(thisArg, token, name) {
249
- const context = ensureInjectionContext(optionalBy);
247
+ const context = ensureInjectionContext("optionalBy()");
250
248
  const resolution = context.resolution;
251
249
  const currentFrame = resolution.stack.peek();
252
250
  if (!currentFrame) {
@@ -264,7 +262,7 @@ function optionalBy(thisArg, token, name) {
264
262
  }
265
263
 
266
264
  function optionalAll(token) {
267
- const context = ensureInjectionContext(optionalAll);
265
+ const context = ensureInjectionContext("optionalAll()");
268
266
  return context.container.resolveAll(token, true);
269
267
  }
270
268
 
@@ -430,26 +428,9 @@ class TokenRegistry {
430
428
  function isBuilder(provider) {
431
429
  return builders.has(provider);
432
430
  }
433
- /**
434
- * Create a one-off type token from a factory function.
435
- *
436
- * @example
437
- * ```ts
438
- * class Wizard {
439
- * wand = inject(
440
- * build(() => {
441
- * const wand = inject(Wand);
442
- * wand.owner = this;
443
- * // ...
444
- * return wand;
445
- * }),
446
- * );
447
- * }
448
- * ```
449
- *
450
- * @__NO_SIDE_EFFECTS__
451
- */ function build(factory) {
452
- const token = createType(`Build<${getTypeName(factory)}>`);
431
+ // @__NO_SIDE_EFFECTS__
432
+ function build(factory, name) {
433
+ const token = createType(name ?? `Build<${getTypeName(factory)}>`);
453
434
  const provider = {
454
435
  useFactory: factory
455
436
  };
@@ -577,6 +558,9 @@ function isDisposable(value) {
577
558
  }
578
559
  } else {
579
560
  const [token, provider, options] = args;
561
+ const existingProvider = isExistingProvider(provider);
562
+ const name = existingProvider ? undefined : provider.name;
563
+ assert(name === undefined || name.trim(), "the provider name qualifier cannot be empty or blank");
580
564
  if (isClassProvider(provider)) {
581
565
  const metadata = getMetadata(provider.useClass);
582
566
  const registration = {
@@ -596,12 +580,11 @@ function isDisposable(value) {
596
580
  this.resolveProviderValue(registration, registration.provider);
597
581
  }
598
582
  } else {
599
- const existingProvider = isExistingProvider(provider);
600
583
  if (existingProvider) {
601
584
  assert(token !== provider.useExisting, `the useExisting token ${token.name} cannot be the same as the token being registered`);
602
585
  }
603
586
  this.myTokenRegistry.set(token, {
604
- name: existingProvider ? undefined : provider.name,
587
+ name: name,
605
588
  provider: provider,
606
589
  options: options
607
590
  });
@@ -1154,12 +1137,12 @@ function OptionalAll(token) {
1154
1137
  * const wizard = container.resolve(Wizard);
1155
1138
  * wizard.getWand(); // => Wand
1156
1139
  * ```
1157
- */ const Injector = /*@__PURE__*/ build(function Injector() {
1158
- const context = ensureInjectionContext(Injector);
1140
+ */ const Injector = /*@__PURE__*/ build(()=>{
1141
+ const context = ensureInjectionContext("Injector factory");
1159
1142
  const resolution = context.resolution;
1160
1143
  const dependentFrame = resolution.stack.peek();
1161
1144
  const dependentRef = dependentFrame && resolution.dependents.get(dependentFrame.provider);
1162
- function withCurrentContext(fn) {
1145
+ function withContext(fn) {
1163
1146
  if (useInjectionContext()) {
1164
1147
  return fn();
1165
1148
  }
@@ -1171,18 +1154,17 @@ function OptionalAll(token) {
1171
1154
  try {
1172
1155
  return fn();
1173
1156
  } finally{
1174
- for (const cleanup of cleanups){
1175
- cleanup?.();
1176
- }
1157
+ cleanups.forEach((cleanup)=>cleanup?.());
1177
1158
  }
1178
1159
  }
1179
1160
  return {
1180
- inject: (token, name)=>withCurrentContext(()=>inject(token, name)),
1181
- injectAll: (token)=>withCurrentContext(()=>injectAll(token)),
1182
- optional: (token, name)=>withCurrentContext(()=>optional(token, name)),
1183
- optionalAll: (token)=>withCurrentContext(()=>optionalAll(token))
1161
+ inject: (token, name)=>withContext(()=>inject(token, name)),
1162
+ injectAll: (token)=>withContext(()=>injectAll(token)),
1163
+ optional: (token, name)=>withContext(()=>optional(token, name)),
1164
+ optionalAll: (token)=>withContext(()=>optionalAll(token)),
1165
+ runInContext: withContext
1184
1166
  };
1185
- });
1167
+ }, "Injector");
1186
1168
 
1187
1169
  /**
1188
1170
  * Applies middleware functions to a container.