@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/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
  };
@@ -1154,12 +1135,12 @@ function OptionalAll(token) {
1154
1135
  * const wizard = container.resolve(Wizard);
1155
1136
  * wizard.getWand(); // => Wand
1156
1137
  * ```
1157
- */ const Injector = /*@__PURE__*/ build(function Injector() {
1158
- const context = ensureInjectionContext(Injector);
1138
+ */ const Injector = /*@__PURE__*/ build(()=>{
1139
+ const context = ensureInjectionContext("Injector factory");
1159
1140
  const resolution = context.resolution;
1160
1141
  const dependentFrame = resolution.stack.peek();
1161
1142
  const dependentRef = dependentFrame && resolution.dependents.get(dependentFrame.provider);
1162
- function withCurrentContext(fn) {
1143
+ function withContext(fn) {
1163
1144
  if (useInjectionContext()) {
1164
1145
  return fn();
1165
1146
  }
@@ -1171,18 +1152,17 @@ function OptionalAll(token) {
1171
1152
  try {
1172
1153
  return fn();
1173
1154
  } finally{
1174
- for (const cleanup of cleanups){
1175
- cleanup?.();
1176
- }
1155
+ cleanups.forEach((cleanup)=>cleanup?.());
1177
1156
  }
1178
1157
  }
1179
1158
  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))
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
1184
1164
  };
1185
- });
1165
+ }, "Injector");
1186
1166
 
1187
1167
  /**
1188
1168
  * Applies middleware functions to a container.