moost 0.6.41 → 0.6.43

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/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  let _wooksjs_event_core = require("@wooksjs/event-core");
3
- let _prostojs_infact = require("@prostojs/infact");
4
3
  let _prostojs_mate = require("@prostojs/mate");
5
4
  let _prostojs_logger = require("@prostojs/logger");
5
+ let _prostojs_infact = require("@prostojs/infact");
6
6
  let hookable = require("hookable");
7
7
  let wooks = require("wooks");
8
8
 
@@ -48,12 +48,38 @@ let stamped = false;
48
48
  if (stamped) return;
49
49
  stamped = true;
50
50
  stampModuleIdentity({
51
- version: "0.6.41",
51
+ version: "0.6.43",
52
52
  path: typeof __filename === "string" ? __filename : require("url").pathToFileURL(__filename).href
53
53
  });
54
54
  }
55
55
  stampOnce();
56
56
 
57
+ //#endregion
58
+ //#region packages/moost/src/adapter-brand.ts
59
+ /**
60
+ * Static key an adapter class names itself under, independently of its class
61
+ * identity — e.g. `static readonly [MOOST_ADAPTER_BRAND] = '@moostjs/event-http/MoostHttp'`.
62
+ *
63
+ * DI keys classes by identity. When two copies of an adapter package are loaded
64
+ * (a dev server evaluating one copy while Node loads another for an externalized
65
+ * dependency, or a bundle next to an external), a library resolving the adapter
66
+ * with `useControllerContext().instantiate(MoostHttp)` holds the *other* copy's
67
+ * class and finds nothing. With a brand, `instantiate()` still returns the
68
+ * attached adapter (and warns once about the duplicate copy).
69
+ */ const MOOST_ADAPTER_BRAND = Symbol.for("moost:adapter-brand");
70
+ /** The {@link MOOST_ADAPTER_BRAND} of a class (inherited by subclasses), if it carries one. */ function getAdapterBrand(classConstructor) {
71
+ if (typeof classConstructor !== "function") return;
72
+ const brand = classConstructor[MOOST_ADAPTER_BRAND];
73
+ return typeof brand === "string" ? brand : void 0;
74
+ }
75
+ /**
76
+ * Provide-registry token `Moost.init()` files a branded adapter under next to its
77
+ * class — the lookup `instantiate()` uses for an adapter class that is not the
78
+ * attached one (another package copy, or a base class of the attached adapter).
79
+ */ function adapterProvideToken(brand) {
80
+ return `moost:adapter:${brand}`;
81
+ }
82
+
57
83
  //#endregion
58
84
  //#region packages/moost/src/logger.ts
59
85
  let defaultLogger;
@@ -96,6 +122,124 @@ function getDefaultLogger(topic) {
96
122
  return merged.toSorted((a, b) => a.priority - b.priority);
97
123
  }
98
124
 
125
+ //#endregion
126
+ //#region packages/moost/src/event-scope.ts
127
+ function _define_property$2(obj, key, value) {
128
+ if (key in obj) Object.defineProperty(obj, key, {
129
+ value,
130
+ enumerable: true,
131
+ configurable: true,
132
+ writable: true
133
+ });
134
+ else obj[key] = value;
135
+ return obj;
136
+ }
137
+ let _scopeChar = "a";
138
+ let _scopeNum = 0;
139
+ function nextScopeId() {
140
+ if (_scopeNum >= Number.MAX_SAFE_INTEGER) {
141
+ _scopeNum = 0;
142
+ _scopeChar = _scopeChar === "z" ? "a" : String.fromCodePoint((_scopeChar.codePointAt(0) ?? 97) + 1);
143
+ }
144
+ return `__moost_${_scopeChar}_${++_scopeNum}`;
145
+ }
146
+ const scopeIdSlot = (0, _wooksjs_event_core.cached)(() => nextScopeId());
147
+ /**
148
+ * Composable returning the moost DI scope ID of the current event. Generated on first call
149
+ * and cached on the event context itself — never inherited from a parent context, so a child
150
+ * event (a workflow run started with `eventContext`, a WebSocket message) owns its scope
151
+ * instead of sharing, and later releasing, its parent's.
152
+ */ const useScopeId = (ctx) => (ctx ?? (0, _wooksjs_event_core.current)()).getOwn(scopeIdSlot);
153
+ /** Registers a DI scope for the given ID and returns an unscope function. */ function registerEventScope(scopeId) {
154
+ const infact = getMoostInfact();
155
+ infact.registerScope(scopeId);
156
+ return () => {
157
+ infact.unregisterScope(scopeId);
158
+ };
159
+ }
160
+ const NO_ISOLATION = /* @__PURE__ */ new Set();
161
+ /** Copy-on-write child: reads fall through to the parent, every write stays in the child. */ let ForkedEventContext = class ForkedEventContext extends _wooksjs_event_core.EventContext {
162
+ set(slot, value) {
163
+ this.setOwn(slot, value);
164
+ }
165
+ _shouldTraverseParent(id) {
166
+ return !this.isolated.has(id);
167
+ }
168
+ constructor(parent, isolated) {
169
+ super({
170
+ logger: parent.logger,
171
+ parent
172
+ }), _define_property$2(this, "isolated", void 0), this.isolated = isolated;
173
+ }
174
+ };
175
+ /**
176
+ * Creates a copy-on-write child of an event context. Reads fall through to the parent
177
+ * (request, headers, auth, already computed slots); every write — `ctx.set()`, a controller
178
+ * context, a composable's state — stays in the child, so running code in the child never
179
+ * clobbers the parent event's state. The child owns its moost DI scope id (see
180
+ * {@link withControllerContext} to share the parent's).
181
+ *
182
+ * Run code in it with `run(child, fn)`.
183
+ *
184
+ * @example
185
+ * ```ts
186
+ * const child = forkEventContext({ isolate: [useMyState] })
187
+ * await run(child, () => doWork())
188
+ * ```
189
+ */ function forkEventContext(opts) {
190
+ const parent = opts?.parent ?? (0, _wooksjs_event_core.current)();
191
+ if (!opts?.isolate) return new ForkedEventContext(parent, NO_ISOLATION);
192
+ const ids = /* @__PURE__ */ new Set();
193
+ for (const slot of opts.isolate) ids.add(("_slot" in slot ? slot._slot : slot)._id);
194
+ return new ForkedEventContext(parent, ids);
195
+ }
196
+ /**
197
+ * Runs `fn` in a copy-on-write child of the current event (see {@link forkEventContext})
198
+ * whose controller context is `instance` / `method` — another controller's hooks, permission
199
+ * checks and `useControllerContext()` consumers run as if the event had been routed to it,
200
+ * without touching the current event's state. `FOR_EVENT` dependencies resolve in the parent's
201
+ * DI scope by default (`shareScope`).
202
+ *
203
+ * Use it to call into another controller's logic within the same event. Do not run a moost
204
+ * event handler (a routed handler function) inside a scope-sharing child: a handler registers
205
+ * and releases its own scope — use an adapter-level invocation (e.g. `MoostHttp.invoke()`) for that.
206
+ *
207
+ * @returns what `fn` returns (a promise stays a promise)
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * const source = await useControllerContext().instantiate(IssueController)
212
+ * const allowed = await withControllerContext(source, 'list', () => source.allowedFor(ids))
213
+ * ```
214
+ */ function withControllerContext(instance, method, fn, opts) {
215
+ const parent = opts?.parent ?? (0, _wooksjs_event_core.current)();
216
+ const child = forkEventContext({
217
+ parent,
218
+ isolate: opts?.isolate
219
+ });
220
+ setControllerContext(instance, method, opts?.route ?? "", {
221
+ prefix: opts?.prefix,
222
+ ctx: child
223
+ });
224
+ if (opts?.shareScope !== false) {
225
+ child.setOwn(scopeIdSlot, useScopeId(parent));
226
+ return (0, _wooksjs_event_core.run)(child, fn);
227
+ }
228
+ const release = registerEventScope(useScopeId(child));
229
+ let result;
230
+ try {
231
+ result = (0, _wooksjs_event_core.run)(child, fn);
232
+ } catch (error) {
233
+ release();
234
+ throw error;
235
+ }
236
+ if (!isThenable(result)) {
237
+ release();
238
+ return result;
239
+ }
240
+ return Promise.resolve(result).finally(release);
241
+ }
242
+
99
243
  //#endregion
100
244
  //#region packages/moost/src/pipes/run-pipes.ts
101
245
  function runPipes(pipes, initialValue, metas, level) {
@@ -389,6 +533,23 @@ const controllerPrefixKey = globalKey("controller.prefix");
389
533
  _ctx.set(controllerRouteKey, route);
390
534
  if (opts?.prefix !== void 0) _ctx.set(controllerPrefixKey, opts.prefix);
391
535
  }
536
+ /** Brands already warned about by {@link brandedAdapterFor} (one warning per process). */ const reportedAdapterCopies = /* @__PURE__ */ new Set();
537
+ /**
538
+ * The attached adapter `instantiate(c)` resolves through its brand (see `MOOST_ADAPTER_BRAND`)
539
+ * when `c` is not that adapter's own class: a base class of a custom adapter, or the adapter class
540
+ * from another copy of its package (warned once). `undefined` → the plain DI lookup applies.
541
+ */ function brandedAdapterFor(controller, c) {
542
+ const brand = getAdapterBrand(c);
543
+ if (brand === void 0) return;
544
+ const adapter = getMoostInfact().getInstanceRegistries(controller).provide?.[adapterProvideToken(brand)]?.fn();
545
+ const attached = adapter ? (0, _prostojs_mate.getConstructor)(adapter) : void 0;
546
+ if (!attached || attached === c || c.prototype instanceof attached) return;
547
+ if (!(adapter instanceof c) && !reportedAdapterCopies.has(brand)) {
548
+ reportedAdapterCopies.add(brand);
549
+ getDefaultLogger("moost").warn(`instantiate(${c.name}) resolved the attached adapter through its brand "${brand}": the class passed in comes from another copy of its package. Two copies of a package split its module state — make the bundler / SSR externalization load one copy (for @moostjs/vite see the ssrExternalCheck warnings).`);
550
+ }
551
+ return adapter;
552
+ }
392
553
  /**
393
554
  * Provides access to the current controller context within an event handler.
394
555
  * Returns utilities for accessing the controller instance, method metadata, and DI.
@@ -401,7 +562,9 @@ const controllerPrefixKey = globalKey("controller.prefix");
401
562
  const getControllerMeta = () => getMoostMate().read(getController());
402
563
  const getMethodMeta = (name) => getMoostMate().read(getController(), name || getMethod());
403
564
  function instantiate(c) {
404
- return getMoostInfact().getForInstance(getController(), c);
565
+ const controller = getController();
566
+ const adapter = brandedAdapterFor(controller, c);
567
+ return adapter ? Promise.resolve(adapter) : getMoostInfact().getForInstance(controller, c);
405
568
  }
406
569
  return {
407
570
  instantiate,
@@ -437,21 +600,33 @@ const interceptResultKey = globalKey("interceptor.result");
437
600
 
438
601
  //#endregion
439
602
  //#region packages/moost/src/adapter-utils.ts
440
- let _scopeChar = "a";
441
- let _scopeNum = 0;
442
- function nextScopeId() {
443
- if (_scopeNum >= Number.MAX_SAFE_INTEGER) {
444
- _scopeNum = 0;
445
- _scopeChar = _scopeChar === "z" ? "a" : String.fromCodePoint((_scopeChar.codePointAt(0) ?? 97) + 1);
446
- }
447
- return `__moost_${_scopeChar}_${++_scopeNum}`;
448
- }
449
- /** Composable returning the moost scope ID for the current event. Generates on first call, caches for subsequent calls. */ const useScopeId = (0, _wooksjs_event_core.defineWook)(() => nextScopeId());
450
- /** Registers a DI scope for the given ID and returns an unscope function. */ function registerEventScope(scopeId) {
451
- const infact = getMoostInfact();
452
- infact.registerScope(scopeId);
453
- return () => {
454
- infact.unregisterScope(scopeId);
603
+ const noop = () => {};
604
+ /**
605
+ * Registers an event's DI scope, held by its handler lifecycle and, with `adapterHolds`, by
606
+ * the adapter too. Each release is idempotent; the scope is dropped once every holder let go,
607
+ * so an adapter signal that fires early (a client disconnect mid-handler) cannot pull the
608
+ * scope from under a running handler. Built outside the handler closure so a long-lived
609
+ * adapter listener (the response 'close' of a streamed body) retains only the scope.
610
+ */ function holdEventScope(scopeId, adapterHolds) {
611
+ const drop = registerEventScope(scopeId);
612
+ let holders = adapterHolds ? 2 : 1;
613
+ const hold = () => {
614
+ let held = true;
615
+ return () => {
616
+ if (held) {
617
+ held = false;
618
+ if (--holders === 0) drop();
619
+ }
620
+ };
621
+ };
622
+ const releaseLifecycle = hold();
623
+ return {
624
+ releaseLifecycle,
625
+ failLifecycle: (error) => {
626
+ releaseLifecycle();
627
+ throw error;
628
+ },
629
+ unscope: adapterHolds ? hold() : noop
455
630
  };
456
631
  }
457
632
  /**
@@ -460,6 +635,7 @@ function nextScopeId() {
460
635
  * handler invocation, and cleanup — optimised for sync-first execution.
461
636
  */ function defineMoostEventHandler(options) {
462
637
  const ci = (0, _wooksjs_event_core.getContextInjector)();
638
+ const manualUnscope = !!options.manualUnscope;
463
639
  const handlerSpanName = `Handler:${options.targetPath}`;
464
640
  const handlerAttrs = {
465
641
  "moost.handler": options.controllerMethod || "",
@@ -469,7 +645,7 @@ function nextScopeId() {
469
645
  const ctx = (0, _wooksjs_event_core.current)();
470
646
  const scopeId = useScopeId(ctx);
471
647
  const logger = (0, _wooksjs_event_core.useLogger)(options.loggerTitle, ctx);
472
- const unscope = registerEventScope(scopeId);
648
+ const { unscope, releaseLifecycle, failLifecycle } = holdEventScope(scopeId, manualUnscope);
473
649
  let response;
474
650
  let hookOptions;
475
651
  function getHookOptions() {
@@ -485,14 +661,17 @@ function nextScopeId() {
485
661
  let interceptorHandler;
486
662
  let raise = false;
487
663
  try {
664
+ const result = start();
665
+ return isThenable(result) ? result.then(void 0, failLifecycle) : result;
666
+ } catch (error) {
667
+ return failLifecycle(error);
668
+ }
669
+ function start() {
488
670
  if (options.hooks?.init) {
489
671
  const hookResult = options.hooks.init(getHookOptions());
490
672
  if (isThenable(hookResult)) return hookResult.then(afterInit);
491
673
  }
492
674
  return afterInit();
493
- } catch (error) {
494
- if (!options.manualUnscope) unscope();
495
- throw error;
496
675
  }
497
676
  function afterInit() {
498
677
  const instanceResult = options.getControllerInstance();
@@ -576,7 +755,6 @@ function nextScopeId() {
576
755
  return finalize();
577
756
  }, (error) => {
578
757
  if (options.logErrors) logger.error(String(error));
579
- if (!options.manualUnscope) unscope();
580
758
  throw error;
581
759
  });
582
760
  response = afterResult;
@@ -585,7 +763,7 @@ function nextScopeId() {
585
763
  return finalize();
586
764
  }
587
765
  function finalize() {
588
- if (!options.manualUnscope) unscope();
766
+ releaseLifecycle();
589
767
  if (options.hooks?.end) {
590
768
  const endResult = options.hooks.end(getHookOptions());
591
769
  if (isThenable(endResult)) return endResult.then(() => {
@@ -2138,7 +2316,11 @@ function _define_property(obj, key, value) {
2138
2316
  this.setProvideRegistry((0, _prostojs_infact.createProvideRegistry)([Moost, () => this], [_prostojs_logger.ProstoLogger, () => this.logger], ["MOOST_LOGGER", () => this.logger]));
2139
2317
  for (const a of this.adapters) {
2140
2318
  const constructor = (0, _prostojs_mate.getConstructor)(a);
2141
- if (constructor) this.setProvideRegistry((0, _prostojs_infact.createProvideRegistry)([constructor, () => a]));
2319
+ if (constructor) {
2320
+ this.setProvideRegistry((0, _prostojs_infact.createProvideRegistry)([constructor, () => a]));
2321
+ const brand = getAdapterBrand(constructor);
2322
+ if (brand !== void 0) this.setProvideRegistry((0, _prostojs_infact.createProvideRegistry)([adapterProvideToken(brand), () => a]));
2323
+ }
2142
2324
  if (typeof a.getProvideRegistry === "function") this.setProvideRegistry(a.getProvideRegistry());
2143
2325
  }
2144
2326
  this.unregisteredControllers.unshift({ controller: this });
@@ -2592,6 +2774,7 @@ exports.Interceptor = Interceptor;
2592
2774
  exports.InterceptorHandler = InterceptorHandler;
2593
2775
  exports.Label = Label;
2594
2776
  exports.LoggerTopic = LoggerTopic;
2777
+ exports.MOOST_ADAPTER_BRAND = MOOST_ADAPTER_BRAND;
2595
2778
  exports.MOOST_MODULE_IDENTITY_KEY = MOOST_MODULE_IDENTITY_KEY;
2596
2779
  exports.Moost = Moost;
2597
2780
  exports.MoostDispose = MoostDispose;
@@ -2667,6 +2850,7 @@ Object.defineProperty(exports, 'eventTypeKey', {
2667
2850
  return _wooksjs_event_core.eventTypeKey;
2668
2851
  }
2669
2852
  });
2853
+ exports.forkEventContext = forkEventContext;
2670
2854
  Object.defineProperty(exports, 'getClassKey', {
2671
2855
  enumerable: true,
2672
2856
  get: function () {
@@ -2751,4 +2935,5 @@ Object.defineProperty(exports, 'useLogger', {
2751
2935
  }
2752
2936
  });
2753
2937
  exports.useOvertake = useOvertake;
2754
- exports.useScopeId = useScopeId;
2938
+ exports.useScopeId = useScopeId;
2939
+ exports.withControllerContext = withControllerContext;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import * as _wooksjs_event_core from '@wooksjs/event-core';
2
- import { EventContext, Logger, Key } from '@wooksjs/event-core';
1
+ import { EventContext, Logger, Accessor, Key } from '@wooksjs/event-core';
3
2
  export { Cached, ContextInjector, EventContext, EventContextOptions, Key, Logger, cached, createEventContext, current, eventTypeKey, getContextInjector, key, replaceContextInjector, resetContextInjector, run, useLogger } from '@wooksjs/event-core';
4
3
  import { TProvideRegistry, TReplaceRegistry, Infact, TProvideFn } from '@prostojs/infact';
5
4
  export { TProvideRegistry, createProvideRegistry, createReplaceRegistry, getClassKey } from '@prostojs/infact';
@@ -1288,10 +1287,6 @@ interface TMoostEventHandlerOptions<T> {
1288
1287
  controllerPrefix?: string;
1289
1288
  handlerType: string;
1290
1289
  }
1291
- /** Composable returning the moost scope ID for the current event. Generates on first call, caches for subsequent calls. */
1292
- declare const useScopeId: _wooksjs_event_core.WookComposable<string>;
1293
- /** Registers a DI scope for the given ID and returns an unscope function. */
1294
- declare function registerEventScope(scopeId: string): () => void;
1295
1290
  /**
1296
1291
  * Creates the complete event handler lifecycle processor used by adapters.
1297
1292
  * Handles scope registration, controller resolution, interceptors, argument resolution,
@@ -1299,6 +1294,96 @@ declare function registerEventScope(scopeId: string): () => void;
1299
1294
  */
1300
1295
  declare function defineMoostEventHandler<T>(options: TMoostEventHandlerOptions<T>): () => unknown;
1301
1296
 
1297
+ /**
1298
+ * Static key an adapter class names itself under, independently of its class
1299
+ * identity — e.g. `static readonly [MOOST_ADAPTER_BRAND] = '@moostjs/event-http/MoostHttp'`.
1300
+ *
1301
+ * DI keys classes by identity. When two copies of an adapter package are loaded
1302
+ * (a dev server evaluating one copy while Node loads another for an externalized
1303
+ * dependency, or a bundle next to an external), a library resolving the adapter
1304
+ * with `useControllerContext().instantiate(MoostHttp)` holds the *other* copy's
1305
+ * class and finds nothing. With a brand, `instantiate()` still returns the
1306
+ * attached adapter (and warns once about the duplicate copy).
1307
+ */
1308
+ declare const MOOST_ADAPTER_BRAND: unique symbol;
1309
+
1310
+ /**
1311
+ * Composable returning the moost DI scope ID of the current event. Generated on first call
1312
+ * and cached on the event context itself — never inherited from a parent context, so a child
1313
+ * event (a workflow run started with `eventContext`, a WebSocket message) owns its scope
1314
+ * instead of sharing, and later releasing, its parent's.
1315
+ */
1316
+ declare const useScopeId: (ctx?: EventContext) => string;
1317
+ /** Registers a DI scope for the given ID and returns an unscope function. */
1318
+ declare function registerEventScope(scopeId: string): () => void;
1319
+ /** A slot a child context must not read through from its parent: a `key()` / `cached()` slot, or a `defineWook` composable. */
1320
+ type TIsolatedSlot = Accessor<any> | {
1321
+ readonly _slot: Accessor<any>;
1322
+ };
1323
+ /** Options for {@link forkEventContext}. */
1324
+ interface TForkEventContextOptions {
1325
+ /** The context to fork. Default: the current event context. */
1326
+ parent?: EventContext;
1327
+ /**
1328
+ * Slots the child never reads through from the parent — they are computed or stored in
1329
+ * the child only. Pass the per-event state the child must not inherit (a composable the
1330
+ * parent already built is bound to the parent's context).
1331
+ */
1332
+ isolate?: Iterable<TIsolatedSlot>;
1333
+ }
1334
+ /**
1335
+ * Creates a copy-on-write child of an event context. Reads fall through to the parent
1336
+ * (request, headers, auth, already computed slots); every write — `ctx.set()`, a controller
1337
+ * context, a composable's state — stays in the child, so running code in the child never
1338
+ * clobbers the parent event's state. The child owns its moost DI scope id (see
1339
+ * {@link withControllerContext} to share the parent's).
1340
+ *
1341
+ * Run code in it with `run(child, fn)`.
1342
+ *
1343
+ * @example
1344
+ * ```ts
1345
+ * const child = forkEventContext({ isolate: [useMyState] })
1346
+ * await run(child, () => doWork())
1347
+ * ```
1348
+ */
1349
+ declare function forkEventContext(opts?: TForkEventContextOptions): EventContext;
1350
+ /** Options for {@link withControllerContext}. */
1351
+ interface TWithControllerContextOptions extends TForkEventContextOptions {
1352
+ /**
1353
+ * `true` (default): the child runs in the parent event's DI scope — `FOR_EVENT` instances
1354
+ * resolve to (and are shared with) the parent event's. The parent must be a moost event
1355
+ * whose handler is still running.
1356
+ *
1357
+ * `false`: the child gets its own DI scope, registered for the duration of `fn` and
1358
+ * released when `fn` settles — `FOR_EVENT` instances are fresh and dropped afterwards.
1359
+ */
1360
+ shareScope?: boolean;
1361
+ /** The route reported by `useControllerContext().getRoute()` in the child. Default: `''`. */
1362
+ route?: string;
1363
+ /** The prefix reported by `useControllerContext().getPrefix()` in the child. */
1364
+ prefix?: string;
1365
+ }
1366
+ /**
1367
+ * Runs `fn` in a copy-on-write child of the current event (see {@link forkEventContext})
1368
+ * whose controller context is `instance` / `method` — another controller's hooks, permission
1369
+ * checks and `useControllerContext()` consumers run as if the event had been routed to it,
1370
+ * without touching the current event's state. `FOR_EVENT` dependencies resolve in the parent's
1371
+ * DI scope by default (`shareScope`).
1372
+ *
1373
+ * Use it to call into another controller's logic within the same event. Do not run a moost
1374
+ * event handler (a routed handler function) inside a scope-sharing child: a handler registers
1375
+ * and releases its own scope — use an adapter-level invocation (e.g. `MoostHttp.invoke()`) for that.
1376
+ *
1377
+ * @returns what `fn` returns (a promise stays a promise)
1378
+ *
1379
+ * @example
1380
+ * ```ts
1381
+ * const source = await useControllerContext().instantiate(IssueController)
1382
+ * const allowed = await withControllerContext(source, 'list', () => source.allowedFor(ids))
1383
+ * ```
1384
+ */
1385
+ declare function withControllerContext<T extends object, R>(instance: T, method: keyof T | string, fn: () => R, opts?: TWithControllerContextOptions): R;
1386
+
1302
1387
  /**
1303
1388
  * Returns the own method names of an instance, including inherited methods
1304
1389
  * from parent classes.
@@ -1455,5 +1540,5 @@ declare function createLogger(opts?: Partial<TProstoLoggerOptions>): ProstoLogge
1455
1540
  /** Default colored console transport used by Moost loggers. */
1456
1541
  declare const loggerConsoleTransport: _prostojs_logger.TProstoLoggerTransportFn<any>;
1457
1542
 
1458
- export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, LoggerTopic, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, disposeInstances, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, globalKey, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptResult, setOvertake, stampModuleIdentity, stampOnce, useControllerContext, useHandlerPaths, useInterceptResult, useOvertake, useScopeId };
1459
- export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TControllerRegistration, TControllersGroup, TDisposeError, TDisposeOptions, TDisposeResult, TEmpty, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostModuleIdentity, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives };
1543
+ export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, createLogger, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, disposeInstances, forkEventContext, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, globalKey, isThenable, loggerConsoleTransport, mergeSorted, registerEventScope, resolvePipe, setControllerContext, setInfactLoggingOptions, setInterceptResult, setOvertake, stampModuleIdentity, stampOnce, useControllerContext, useHandlerPaths, useInterceptResult, useOvertake, useScopeId, withControllerContext };
1544
+ export type { TAny, TAnyFn, TClassConstructor, TContextInjectorHook, TControllerOverview, TControllerRegistration, TControllersGroup, TDisposeError, TDisposeOptions, TDisposeResult, TEmpty, TForkEventContextOptions, TFunction, TGetHandlerPathsOptions, TInjectableScope, TInterceptorAfterFn, TInterceptorBeforeFn, TInterceptorData, TInterceptorDef, TInterceptorDefFactory, TInterceptorEntry, TInterceptorErrorFn, TIsolatedSlot, TLogger, TMoostAdapter, TMoostAdapterOptions, TMoostEventHandlerHookOptions, TMoostEventHandlerOptions, TMoostHandler, TMoostMetadata, TMoostModuleIdentity, TMoostOptions, TMoostParamsMetadata, TObject, TOvertakeFn, TPipeData, TPipeFn, TPipeMetas, TPrimitives, TWithControllerContextOptions };
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { ContextInjector, cached, createEventContext, createEventContext as createEventContext$1, current, current as current$1, defineWook, eventTypeKey, getContextInjector, getContextInjector as getContextInjector$1, key, key as key$1, replaceContextInjector, resetContextInjector, run, useLogger, useLogger as useLogger$1, useRouteParams } from "@wooksjs/event-core";
2
- import { Infact, createProvideRegistry, createProvideRegistry as createProvideRegistry$1, createReplaceRegistry, createReplaceRegistry as createReplaceRegistry$1, getClassKey, getClassKey as getClassKey$1 } from "@prostojs/infact";
1
+ import { ContextInjector, EventContext, cached, cached as cached$1, createEventContext, createEventContext as createEventContext$1, current, current as current$1, eventTypeKey, getContextInjector, getContextInjector as getContextInjector$1, key, key as key$1, replaceContextInjector, resetContextInjector, run, run as run$1, useLogger, useLogger as useLogger$1, useRouteParams } from "@wooksjs/event-core";
3
2
  import { Mate, getConstructor, getConstructor as getConstructor$1, isConstructor, isConstructor as isConstructor$1 } from "@prostojs/mate";
4
3
  import { ProstoLogger, ProstoLogger as ProstoLogger$1, coloredConsole, createConsoleTransort } from "@prostojs/logger";
4
+ import { Infact, createProvideRegistry, createProvideRegistry as createProvideRegistry$1, createReplaceRegistry, createReplaceRegistry as createReplaceRegistry$1, getClassKey, getClassKey as getClassKey$1 } from "@prostojs/infact";
5
5
  import { Hookable } from "hookable";
6
6
  import { clearGlobalWooks, getGlobalWooks } from "wooks";
7
7
 
@@ -47,12 +47,38 @@ let stamped = false;
47
47
  if (stamped) return;
48
48
  stamped = true;
49
49
  stampModuleIdentity({
50
- version: "0.6.41",
50
+ version: "0.6.43",
51
51
  path: typeof __filename === "string" ? __filename : import.meta.url
52
52
  });
53
53
  }
54
54
  stampOnce();
55
55
 
56
+ //#endregion
57
+ //#region packages/moost/src/adapter-brand.ts
58
+ /**
59
+ * Static key an adapter class names itself under, independently of its class
60
+ * identity — e.g. `static readonly [MOOST_ADAPTER_BRAND] = '@moostjs/event-http/MoostHttp'`.
61
+ *
62
+ * DI keys classes by identity. When two copies of an adapter package are loaded
63
+ * (a dev server evaluating one copy while Node loads another for an externalized
64
+ * dependency, or a bundle next to an external), a library resolving the adapter
65
+ * with `useControllerContext().instantiate(MoostHttp)` holds the *other* copy's
66
+ * class and finds nothing. With a brand, `instantiate()` still returns the
67
+ * attached adapter (and warns once about the duplicate copy).
68
+ */ const MOOST_ADAPTER_BRAND = Symbol.for("moost:adapter-brand");
69
+ /** The {@link MOOST_ADAPTER_BRAND} of a class (inherited by subclasses), if it carries one. */ function getAdapterBrand(classConstructor) {
70
+ if (typeof classConstructor !== "function") return;
71
+ const brand = classConstructor[MOOST_ADAPTER_BRAND];
72
+ return typeof brand === "string" ? brand : void 0;
73
+ }
74
+ /**
75
+ * Provide-registry token `Moost.init()` files a branded adapter under next to its
76
+ * class — the lookup `instantiate()` uses for an adapter class that is not the
77
+ * attached one (another package copy, or a base class of the attached adapter).
78
+ */ function adapterProvideToken(brand) {
79
+ return `moost:adapter:${brand}`;
80
+ }
81
+
56
82
  //#endregion
57
83
  //#region packages/moost/src/logger.ts
58
84
  let defaultLogger;
@@ -95,6 +121,124 @@ function getDefaultLogger(topic) {
95
121
  return merged.toSorted((a, b) => a.priority - b.priority);
96
122
  }
97
123
 
124
+ //#endregion
125
+ //#region packages/moost/src/event-scope.ts
126
+ function _define_property$2(obj, key, value) {
127
+ if (key in obj) Object.defineProperty(obj, key, {
128
+ value,
129
+ enumerable: true,
130
+ configurable: true,
131
+ writable: true
132
+ });
133
+ else obj[key] = value;
134
+ return obj;
135
+ }
136
+ let _scopeChar = "a";
137
+ let _scopeNum = 0;
138
+ function nextScopeId() {
139
+ if (_scopeNum >= Number.MAX_SAFE_INTEGER) {
140
+ _scopeNum = 0;
141
+ _scopeChar = _scopeChar === "z" ? "a" : String.fromCodePoint((_scopeChar.codePointAt(0) ?? 97) + 1);
142
+ }
143
+ return `__moost_${_scopeChar}_${++_scopeNum}`;
144
+ }
145
+ const scopeIdSlot = cached$1(() => nextScopeId());
146
+ /**
147
+ * Composable returning the moost DI scope ID of the current event. Generated on first call
148
+ * and cached on the event context itself — never inherited from a parent context, so a child
149
+ * event (a workflow run started with `eventContext`, a WebSocket message) owns its scope
150
+ * instead of sharing, and later releasing, its parent's.
151
+ */ const useScopeId = (ctx) => (ctx ?? current$1()).getOwn(scopeIdSlot);
152
+ /** Registers a DI scope for the given ID and returns an unscope function. */ function registerEventScope(scopeId) {
153
+ const infact = getMoostInfact();
154
+ infact.registerScope(scopeId);
155
+ return () => {
156
+ infact.unregisterScope(scopeId);
157
+ };
158
+ }
159
+ const NO_ISOLATION = /* @__PURE__ */ new Set();
160
+ /** Copy-on-write child: reads fall through to the parent, every write stays in the child. */ let ForkedEventContext = class ForkedEventContext extends EventContext {
161
+ set(slot, value) {
162
+ this.setOwn(slot, value);
163
+ }
164
+ _shouldTraverseParent(id) {
165
+ return !this.isolated.has(id);
166
+ }
167
+ constructor(parent, isolated) {
168
+ super({
169
+ logger: parent.logger,
170
+ parent
171
+ }), _define_property$2(this, "isolated", void 0), this.isolated = isolated;
172
+ }
173
+ };
174
+ /**
175
+ * Creates a copy-on-write child of an event context. Reads fall through to the parent
176
+ * (request, headers, auth, already computed slots); every write — `ctx.set()`, a controller
177
+ * context, a composable's state — stays in the child, so running code in the child never
178
+ * clobbers the parent event's state. The child owns its moost DI scope id (see
179
+ * {@link withControllerContext} to share the parent's).
180
+ *
181
+ * Run code in it with `run(child, fn)`.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * const child = forkEventContext({ isolate: [useMyState] })
186
+ * await run(child, () => doWork())
187
+ * ```
188
+ */ function forkEventContext(opts) {
189
+ const parent = opts?.parent ?? current$1();
190
+ if (!opts?.isolate) return new ForkedEventContext(parent, NO_ISOLATION);
191
+ const ids = /* @__PURE__ */ new Set();
192
+ for (const slot of opts.isolate) ids.add(("_slot" in slot ? slot._slot : slot)._id);
193
+ return new ForkedEventContext(parent, ids);
194
+ }
195
+ /**
196
+ * Runs `fn` in a copy-on-write child of the current event (see {@link forkEventContext})
197
+ * whose controller context is `instance` / `method` — another controller's hooks, permission
198
+ * checks and `useControllerContext()` consumers run as if the event had been routed to it,
199
+ * without touching the current event's state. `FOR_EVENT` dependencies resolve in the parent's
200
+ * DI scope by default (`shareScope`).
201
+ *
202
+ * Use it to call into another controller's logic within the same event. Do not run a moost
203
+ * event handler (a routed handler function) inside a scope-sharing child: a handler registers
204
+ * and releases its own scope — use an adapter-level invocation (e.g. `MoostHttp.invoke()`) for that.
205
+ *
206
+ * @returns what `fn` returns (a promise stays a promise)
207
+ *
208
+ * @example
209
+ * ```ts
210
+ * const source = await useControllerContext().instantiate(IssueController)
211
+ * const allowed = await withControllerContext(source, 'list', () => source.allowedFor(ids))
212
+ * ```
213
+ */ function withControllerContext(instance, method, fn, opts) {
214
+ const parent = opts?.parent ?? current$1();
215
+ const child = forkEventContext({
216
+ parent,
217
+ isolate: opts?.isolate
218
+ });
219
+ setControllerContext(instance, method, opts?.route ?? "", {
220
+ prefix: opts?.prefix,
221
+ ctx: child
222
+ });
223
+ if (opts?.shareScope !== false) {
224
+ child.setOwn(scopeIdSlot, useScopeId(parent));
225
+ return run$1(child, fn);
226
+ }
227
+ const release = registerEventScope(useScopeId(child));
228
+ let result;
229
+ try {
230
+ result = run$1(child, fn);
231
+ } catch (error) {
232
+ release();
233
+ throw error;
234
+ }
235
+ if (!isThenable(result)) {
236
+ release();
237
+ return result;
238
+ }
239
+ return Promise.resolve(result).finally(release);
240
+ }
241
+
98
242
  //#endregion
99
243
  //#region packages/moost/src/pipes/run-pipes.ts
100
244
  function runPipes(pipes, initialValue, metas, level) {
@@ -388,6 +532,23 @@ const controllerPrefixKey = globalKey("controller.prefix");
388
532
  _ctx.set(controllerRouteKey, route);
389
533
  if (opts?.prefix !== void 0) _ctx.set(controllerPrefixKey, opts.prefix);
390
534
  }
535
+ /** Brands already warned about by {@link brandedAdapterFor} (one warning per process). */ const reportedAdapterCopies = /* @__PURE__ */ new Set();
536
+ /**
537
+ * The attached adapter `instantiate(c)` resolves through its brand (see `MOOST_ADAPTER_BRAND`)
538
+ * when `c` is not that adapter's own class: a base class of a custom adapter, or the adapter class
539
+ * from another copy of its package (warned once). `undefined` → the plain DI lookup applies.
540
+ */ function brandedAdapterFor(controller, c) {
541
+ const brand = getAdapterBrand(c);
542
+ if (brand === void 0) return;
543
+ const adapter = getMoostInfact().getInstanceRegistries(controller).provide?.[adapterProvideToken(brand)]?.fn();
544
+ const attached = adapter ? getConstructor$1(adapter) : void 0;
545
+ if (!attached || attached === c || c.prototype instanceof attached) return;
546
+ if (!(adapter instanceof c) && !reportedAdapterCopies.has(brand)) {
547
+ reportedAdapterCopies.add(brand);
548
+ getDefaultLogger("moost").warn(`instantiate(${c.name}) resolved the attached adapter through its brand "${brand}": the class passed in comes from another copy of its package. Two copies of a package split its module state — make the bundler / SSR externalization load one copy (for @moostjs/vite see the ssrExternalCheck warnings).`);
549
+ }
550
+ return adapter;
551
+ }
391
552
  /**
392
553
  * Provides access to the current controller context within an event handler.
393
554
  * Returns utilities for accessing the controller instance, method metadata, and DI.
@@ -400,7 +561,9 @@ const controllerPrefixKey = globalKey("controller.prefix");
400
561
  const getControllerMeta = () => getMoostMate().read(getController());
401
562
  const getMethodMeta = (name) => getMoostMate().read(getController(), name || getMethod());
402
563
  function instantiate(c) {
403
- return getMoostInfact().getForInstance(getController(), c);
564
+ const controller = getController();
565
+ const adapter = brandedAdapterFor(controller, c);
566
+ return adapter ? Promise.resolve(adapter) : getMoostInfact().getForInstance(controller, c);
404
567
  }
405
568
  return {
406
569
  instantiate,
@@ -436,21 +599,33 @@ const interceptResultKey = globalKey("interceptor.result");
436
599
 
437
600
  //#endregion
438
601
  //#region packages/moost/src/adapter-utils.ts
439
- let _scopeChar = "a";
440
- let _scopeNum = 0;
441
- function nextScopeId() {
442
- if (_scopeNum >= Number.MAX_SAFE_INTEGER) {
443
- _scopeNum = 0;
444
- _scopeChar = _scopeChar === "z" ? "a" : String.fromCodePoint((_scopeChar.codePointAt(0) ?? 97) + 1);
445
- }
446
- return `__moost_${_scopeChar}_${++_scopeNum}`;
447
- }
448
- /** Composable returning the moost scope ID for the current event. Generates on first call, caches for subsequent calls. */ const useScopeId = defineWook(() => nextScopeId());
449
- /** Registers a DI scope for the given ID and returns an unscope function. */ function registerEventScope(scopeId) {
450
- const infact = getMoostInfact();
451
- infact.registerScope(scopeId);
452
- return () => {
453
- infact.unregisterScope(scopeId);
602
+ const noop = () => {};
603
+ /**
604
+ * Registers an event's DI scope, held by its handler lifecycle and, with `adapterHolds`, by
605
+ * the adapter too. Each release is idempotent; the scope is dropped once every holder let go,
606
+ * so an adapter signal that fires early (a client disconnect mid-handler) cannot pull the
607
+ * scope from under a running handler. Built outside the handler closure so a long-lived
608
+ * adapter listener (the response 'close' of a streamed body) retains only the scope.
609
+ */ function holdEventScope(scopeId, adapterHolds) {
610
+ const drop = registerEventScope(scopeId);
611
+ let holders = adapterHolds ? 2 : 1;
612
+ const hold = () => {
613
+ let held = true;
614
+ return () => {
615
+ if (held) {
616
+ held = false;
617
+ if (--holders === 0) drop();
618
+ }
619
+ };
620
+ };
621
+ const releaseLifecycle = hold();
622
+ return {
623
+ releaseLifecycle,
624
+ failLifecycle: (error) => {
625
+ releaseLifecycle();
626
+ throw error;
627
+ },
628
+ unscope: adapterHolds ? hold() : noop
454
629
  };
455
630
  }
456
631
  /**
@@ -459,6 +634,7 @@ function nextScopeId() {
459
634
  * handler invocation, and cleanup — optimised for sync-first execution.
460
635
  */ function defineMoostEventHandler(options) {
461
636
  const ci = getContextInjector$1();
637
+ const manualUnscope = !!options.manualUnscope;
462
638
  const handlerSpanName = `Handler:${options.targetPath}`;
463
639
  const handlerAttrs = {
464
640
  "moost.handler": options.controllerMethod || "",
@@ -468,7 +644,7 @@ function nextScopeId() {
468
644
  const ctx = current$1();
469
645
  const scopeId = useScopeId(ctx);
470
646
  const logger = useLogger$1(options.loggerTitle, ctx);
471
- const unscope = registerEventScope(scopeId);
647
+ const { unscope, releaseLifecycle, failLifecycle } = holdEventScope(scopeId, manualUnscope);
472
648
  let response;
473
649
  let hookOptions;
474
650
  function getHookOptions() {
@@ -484,14 +660,17 @@ function nextScopeId() {
484
660
  let interceptorHandler;
485
661
  let raise = false;
486
662
  try {
663
+ const result = start();
664
+ return isThenable(result) ? result.then(void 0, failLifecycle) : result;
665
+ } catch (error) {
666
+ return failLifecycle(error);
667
+ }
668
+ function start() {
487
669
  if (options.hooks?.init) {
488
670
  const hookResult = options.hooks.init(getHookOptions());
489
671
  if (isThenable(hookResult)) return hookResult.then(afterInit);
490
672
  }
491
673
  return afterInit();
492
- } catch (error) {
493
- if (!options.manualUnscope) unscope();
494
- throw error;
495
674
  }
496
675
  function afterInit() {
497
676
  const instanceResult = options.getControllerInstance();
@@ -575,7 +754,6 @@ function nextScopeId() {
575
754
  return finalize();
576
755
  }, (error) => {
577
756
  if (options.logErrors) logger.error(String(error));
578
- if (!options.manualUnscope) unscope();
579
757
  throw error;
580
758
  });
581
759
  response = afterResult;
@@ -584,7 +762,7 @@ function nextScopeId() {
584
762
  return finalize();
585
763
  }
586
764
  function finalize() {
587
- if (!options.manualUnscope) unscope();
765
+ releaseLifecycle();
588
766
  if (options.hooks?.end) {
589
767
  const endResult = options.hooks.end(getHookOptions());
590
768
  if (isThenable(endResult)) return endResult.then(() => {
@@ -2137,7 +2315,11 @@ function _define_property(obj, key, value) {
2137
2315
  this.setProvideRegistry(createProvideRegistry$1([Moost, () => this], [ProstoLogger$1, () => this.logger], ["MOOST_LOGGER", () => this.logger]));
2138
2316
  for (const a of this.adapters) {
2139
2317
  const constructor = getConstructor$1(a);
2140
- if (constructor) this.setProvideRegistry(createProvideRegistry$1([constructor, () => a]));
2318
+ if (constructor) {
2319
+ this.setProvideRegistry(createProvideRegistry$1([constructor, () => a]));
2320
+ const brand = getAdapterBrand(constructor);
2321
+ if (brand !== void 0) this.setProvideRegistry(createProvideRegistry$1([adapterProvideToken(brand), () => a]));
2322
+ }
2141
2323
  if (typeof a.getProvideRegistry === "function") this.setProvideRegistry(a.getProvideRegistry());
2142
2324
  }
2143
2325
  this.unregisteredControllers.unshift({ controller: this });
@@ -2561,4 +2743,4 @@ function _define_property(obj, key, value) {
2561
2743
  }
2562
2744
 
2563
2745
  //#endregion
2564
- export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, ContextInjector, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, LoggerTopic, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, ProstoLogger, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, cached, clearGlobalWooks, createEventContext, createLogger, createProvideRegistry, createReplaceRegistry, current, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, disposeInstances, eventTypeKey, getClassKey, getConstructor, getContextInjector, getGlobalWooks, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, globalKey, isConstructor, isThenable, key, loggerConsoleTransport, mergeSorted, registerEventScope, replaceContextInjector, resetContextInjector, resolvePipe, run, setControllerContext, setInfactLoggingOptions, setInterceptResult, setOvertake, stampModuleIdentity, stampOnce, useControllerContext, useHandlerPaths, useInterceptResult, useLogger, useOvertake, useScopeId };
2746
+ export { After, ApplyDecorators, Before, Circular, Const, ConstFactory, ContextInjector, Controller, Description, HandlerPaths, Id, ImportController, Inherit, Inject, InjectEventLogger, InjectFromScope, InjectMoost, InjectMoostLogger, InjectScopeVars, Injectable, Intercept, Interceptor, InterceptorHandler, Label, LoggerTopic, MOOST_ADAPTER_BRAND, MOOST_MODULE_IDENTITY_KEY, Moost, MoostDispose, MoostInit, OnError, Optional, Overtake, Param, Params, Pipe, ProstoLogger, Provide, Replace, Required, Resolve, Response, TInterceptorPriority, TPipePriority, Value, cached, clearGlobalWooks, createEventContext, createLogger, createProvideRegistry, createReplaceRegistry, current, defineAfterInterceptor, defineBeforeInterceptor, defineErrorInterceptor, defineInfactScope, defineInterceptor, defineMoostEventHandler, definePipeFn, disposeInstances, eventTypeKey, forkEventContext, getClassKey, getConstructor, getContextInjector, getGlobalWooks, getHandlerPaths, getInfactScopeVars, getInfactSingletonInstances, getInstanceOwnMethods, getInstanceOwnProps, getMoostInfact, getMoostMate, getNewMoostInfact, globalKey, isConstructor, isThenable, key, loggerConsoleTransport, mergeSorted, registerEventScope, replaceContextInjector, resetContextInjector, resolvePipe, run, setControllerContext, setInfactLoggingOptions, setInterceptResult, setOvertake, stampModuleIdentity, stampOnce, useControllerContext, useHandlerPaths, useInterceptResult, useLogger, useOvertake, useScopeId, withControllerContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moost",
3
- "version": "0.6.41",
3
+ "version": "0.6.43",
4
4
  "description": "moost",
5
5
  "keywords": [
6
6
  "composables",
@@ -41,15 +41,15 @@
41
41
  "@prostojs/infact": "^0.6.0",
42
42
  "@prostojs/logger": "^0.4.3",
43
43
  "@prostojs/mate": "^0.5.0",
44
- "@wooksjs/event-core": "^0.7.24",
44
+ "@wooksjs/event-core": "^0.7.26",
45
45
  "hookable": "^5.5.3",
46
- "wooks": "^0.7.24"
46
+ "wooks": "^0.7.26"
47
47
  },
48
48
  "devDependencies": {
49
- "@wooksjs/event-http": "^0.7.24",
50
- "@wooksjs/http-body": "^0.7.24",
49
+ "@wooksjs/event-http": "^0.7.26",
50
+ "@wooksjs/http-body": "^0.7.26",
51
51
  "vitest": "3.2.7",
52
- "@moostjs/event-http": "^0.6.41"
52
+ "@moostjs/event-http": "^0.6.43"
53
53
  },
54
54
  "scripts": {
55
55
  "pub": "pnpm publish --access public",