@lppedd/di-wise-neo 0.7.2 → 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
  };
@@ -1156,12 +1137,12 @@ function OptionalAll(token) {
1156
1137
  * const wizard = container.resolve(Wizard);
1157
1138
  * wizard.getWand(); // => Wand
1158
1139
  * ```
1159
- */ const Injector = /*@__PURE__*/ build(function Injector() {
1160
- const context = ensureInjectionContext(Injector);
1140
+ */ const Injector = /*@__PURE__*/ build(()=>{
1141
+ const context = ensureInjectionContext("Injector factory");
1161
1142
  const resolution = context.resolution;
1162
1143
  const dependentFrame = resolution.stack.peek();
1163
1144
  const dependentRef = dependentFrame && resolution.dependents.get(dependentFrame.provider);
1164
- function withCurrentContext(fn) {
1145
+ function withContext(fn) {
1165
1146
  if (useInjectionContext()) {
1166
1147
  return fn();
1167
1148
  }
@@ -1173,18 +1154,17 @@ function OptionalAll(token) {
1173
1154
  try {
1174
1155
  return fn();
1175
1156
  } finally{
1176
- for (const cleanup of cleanups){
1177
- cleanup?.();
1178
- }
1157
+ cleanups.forEach((cleanup)=>cleanup?.());
1179
1158
  }
1180
1159
  }
1181
1160
  return {
1182
- inject: (token, name)=>withCurrentContext(()=>inject(token, name)),
1183
- injectAll: (token)=>withCurrentContext(()=>injectAll(token)),
1184
- optional: (token, name)=>withCurrentContext(()=>optional(token, name)),
1185
- 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
1186
1166
  };
1187
- });
1167
+ }, "Injector");
1188
1168
 
1189
1169
  /**
1190
1170
  * Applies middleware functions to a container.