@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/es/index.mjs CHANGED
@@ -29,23 +29,6 @@ function untag(message) {
29
29
  return message.startsWith("[di-wise-neo]") ? message.substring(13).trimStart() : message;
30
30
  }
31
31
 
32
- // @internal
33
- function createInjectionContext() {
34
- let current = null;
35
- function provide(next) {
36
- const prev = current;
37
- current = next;
38
- return ()=>current = prev;
39
- }
40
- function use() {
41
- return current;
42
- }
43
- return [
44
- provide,
45
- use
46
- ];
47
- }
48
-
49
32
  // @internal
50
33
  function invariant(condition) {
51
34
  if (!condition) {
@@ -115,18 +98,33 @@ function createResolution() {
115
98
  // @internal
116
99
  const [provideInjectionContext, useInjectionContext] = createInjectionContext();
117
100
  // @internal
118
- function ensureInjectionContext(fn) {
101
+ function ensureInjectionContext(name) {
119
102
  const context = useInjectionContext();
120
- assert(context, `${fn.name}() can only be invoked within an injection context`);
103
+ assert(context, `${name} can only be invoked within an injection context`);
121
104
  return context;
122
105
  }
106
+ function createInjectionContext() {
107
+ let current = null;
108
+ function provide(next) {
109
+ const prev = current;
110
+ current = next;
111
+ return ()=>current = prev;
112
+ }
113
+ function use() {
114
+ return current;
115
+ }
116
+ return [
117
+ provide,
118
+ use
119
+ ];
120
+ }
123
121
 
124
122
  function inject(token, name) {
125
- const context = ensureInjectionContext(inject);
123
+ const context = ensureInjectionContext("inject()");
126
124
  return context.container.resolve(token, name);
127
125
  }
128
126
  function injectBy(thisArg, token, name) {
129
- const context = ensureInjectionContext(injectBy);
127
+ const context = ensureInjectionContext("injectBy()");
130
128
  const resolution = context.resolution;
131
129
  const currentFrame = resolution.stack.peek();
132
130
  if (!currentFrame) {
@@ -144,7 +142,7 @@ function injectBy(thisArg, token, name) {
144
142
  }
145
143
 
146
144
  function injectAll(token) {
147
- const context = ensureInjectionContext(injectAll);
145
+ const context = ensureInjectionContext("injectAll()");
148
146
  return context.container.resolveAll(token);
149
147
  }
150
148
 
@@ -240,11 +238,11 @@ const classIdentityMap = new WeakMap();
240
238
  const metadataMap = new WeakMap();
241
239
 
242
240
  function optional(token, name) {
243
- const context = ensureInjectionContext(optional);
241
+ const context = ensureInjectionContext("optional()");
244
242
  return context.container.resolve(token, true, name);
245
243
  }
246
244
  function optionalBy(thisArg, token, name) {
247
- const context = ensureInjectionContext(optionalBy);
245
+ const context = ensureInjectionContext("optionalBy()");
248
246
  const resolution = context.resolution;
249
247
  const currentFrame = resolution.stack.peek();
250
248
  if (!currentFrame) {
@@ -262,7 +260,7 @@ function optionalBy(thisArg, token, name) {
262
260
  }
263
261
 
264
262
  function optionalAll(token) {
265
- const context = ensureInjectionContext(optionalAll);
263
+ const context = ensureInjectionContext("optionalAll()");
266
264
  return context.container.resolveAll(token, true);
267
265
  }
268
266
 
@@ -428,26 +426,9 @@ class TokenRegistry {
428
426
  function isBuilder(provider) {
429
427
  return builders.has(provider);
430
428
  }
431
- /**
432
- * Create a one-off type token from a factory function.
433
- *
434
- * @example
435
- * ```ts
436
- * class Wizard {
437
- * wand = inject(
438
- * build(() => {
439
- * const wand = inject(Wand);
440
- * wand.owner = this;
441
- * // ...
442
- * return wand;
443
- * }),
444
- * );
445
- * }
446
- * ```
447
- *
448
- * @__NO_SIDE_EFFECTS__
449
- */ function build(factory) {
450
- const token = createType(`Build<${getTypeName(factory)}>`);
429
+ // @__NO_SIDE_EFFECTS__
430
+ function build(factory, name) {
431
+ const token = createType(name ?? `Build<${getTypeName(factory)}>`);
451
432
  const provider = {
452
433
  useFactory: factory
453
434
  };
@@ -575,6 +556,9 @@ function isDisposable(value) {
575
556
  }
576
557
  } else {
577
558
  const [token, provider, options] = args;
559
+ const existingProvider = isExistingProvider(provider);
560
+ const name = existingProvider ? undefined : provider.name;
561
+ assert(name === undefined || name.trim(), "the provider name qualifier cannot be empty or blank");
578
562
  if (isClassProvider(provider)) {
579
563
  const metadata = getMetadata(provider.useClass);
580
564
  const registration = {
@@ -594,12 +578,11 @@ function isDisposable(value) {
594
578
  this.resolveProviderValue(registration, registration.provider);
595
579
  }
596
580
  } else {
597
- const existingProvider = isExistingProvider(provider);
598
581
  if (existingProvider) {
599
582
  assert(token !== provider.useExisting, `the useExisting token ${token.name} cannot be the same as the token being registered`);
600
583
  }
601
584
  this.myTokenRegistry.set(token, {
602
- name: existingProvider ? undefined : provider.name,
585
+ name: name,
603
586
  provider: provider,
604
587
  options: options
605
588
  });
@@ -1152,12 +1135,12 @@ function OptionalAll(token) {
1152
1135
  * const wizard = container.resolve(Wizard);
1153
1136
  * wizard.getWand(); // => Wand
1154
1137
  * ```
1155
- */ const Injector = /*@__PURE__*/ build(function Injector() {
1156
- const context = ensureInjectionContext(Injector);
1138
+ */ const Injector = /*@__PURE__*/ build(()=>{
1139
+ const context = ensureInjectionContext("Injector factory");
1157
1140
  const resolution = context.resolution;
1158
1141
  const dependentFrame = resolution.stack.peek();
1159
1142
  const dependentRef = dependentFrame && resolution.dependents.get(dependentFrame.provider);
1160
- function withCurrentContext(fn) {
1143
+ function withContext(fn) {
1161
1144
  if (useInjectionContext()) {
1162
1145
  return fn();
1163
1146
  }
@@ -1169,18 +1152,17 @@ function OptionalAll(token) {
1169
1152
  try {
1170
1153
  return fn();
1171
1154
  } finally{
1172
- for (const cleanup of cleanups){
1173
- cleanup?.();
1174
- }
1155
+ cleanups.forEach((cleanup)=>cleanup?.());
1175
1156
  }
1176
1157
  }
1177
1158
  return {
1178
- inject: (token, name)=>withCurrentContext(()=>inject(token, name)),
1179
- injectAll: (token)=>withCurrentContext(()=>injectAll(token)),
1180
- optional: (token, name)=>withCurrentContext(()=>optional(token, name)),
1181
- optionalAll: (token)=>withCurrentContext(()=>optionalAll(token))
1159
+ inject: (token, name)=>withContext(()=>inject(token, name)),
1160
+ injectAll: (token)=>withContext(()=>injectAll(token)),
1161
+ optional: (token, name)=>withContext(()=>optional(token, name)),
1162
+ optionalAll: (token)=>withContext(()=>optionalAll(token)),
1163
+ runInContext: withContext
1182
1164
  };
1183
- });
1165
+ }, "Injector");
1184
1166
 
1185
1167
  /**
1186
1168
  * Applies middleware functions to a container.