@webpieces/core-context 0.3.324 → 0.3.325

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/core-context",
3
- "version": "0.3.324",
3
+ "version": "0.3.325",
4
4
  "description": "AsyncLocalStorage-based context management for request-scoped data",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -22,7 +22,7 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
- "@webpieces/core-util": "0.3.324",
25
+ "@webpieces/core-util": "0.3.325",
26
26
  "@inversifyjs/binding-decorators": "1.1.5",
27
27
  "inversify": "7.10.4",
28
28
  "reflect-metadata": "0.2.2"
@@ -24,10 +24,17 @@ export type FrameworkScope = 'singleton' | 'transient';
24
24
  */
25
25
  export declare function provideFrameworkSingleton(): ClassDecorator;
26
26
  /**
27
- * Framework equivalent of @provideSingletonAs: binds the impl to a token (Symbol or abstract
28
- * class) as a singleton, into the webpieces framework registry.
27
+ * Framework equivalent of @DefaultImplementationOn: marks this class as the DEFAULT (overridable)
28
+ * singleton implementation OF a contract token (Symbol or abstract class), into the webpieces
29
+ * framework registry. Binds `token -> thisClass` as a singleton.
30
+ *
31
+ * An app overrides it via appOverrides (loaded LAST), same idiom as AuthConfig:
32
+ * `(await options.rebind(TOKEN)).to(OtherImpl)`.
33
+ *
34
+ * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)`
35
+ * and expands this class's own dependencies.
29
36
  */
30
- export declare function provideFrameworkSingletonAs<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator;
37
+ export declare function DefaultFrameworkImplementationOn<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator;
31
38
  /**
32
39
  * Framework equivalent of @provideTransient: a NEW instance on every resolve. Use it for a
33
40
  * class a {@link Provider} hands out per call — e.g. one ProxyClient per API contract.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.provideFrameworkSingleton = provideFrameworkSingleton;
4
- exports.provideFrameworkSingletonAs = provideFrameworkSingletonAs;
4
+ exports.DefaultFrameworkImplementationOn = DefaultFrameworkImplementationOn;
5
5
  exports.provideFrameworkTransient = provideFrameworkTransient;
6
6
  exports.bindFrameworkProvider = bindFrameworkProvider;
7
7
  exports.buildFrameworkModule = buildFrameworkModule;
@@ -42,10 +42,18 @@ function provideFrameworkSingleton() {
42
42
  };
43
43
  }
44
44
  /**
45
- * Framework equivalent of @provideSingletonAs: binds the impl to a token (Symbol or abstract
46
- * class) as a singleton, into the webpieces framework registry.
45
+ * Framework equivalent of @DefaultImplementationOn: marks this class as the DEFAULT (overridable)
46
+ * singleton implementation OF a contract token (Symbol or abstract class), into the webpieces
47
+ * framework registry. Binds `token -> thisClass` as a singleton.
48
+ *
49
+ * An app overrides it via appOverrides (loaded LAST), same idiom as AuthConfig:
50
+ * `(await options.rebind(TOKEN)).to(OtherImpl)`.
51
+ *
52
+ * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)`
53
+ * and expands this class's own dependencies.
47
54
  */
48
- function provideFrameworkSingletonAs(serviceIdentifier) {
55
+ // webpieces-disable no-function-outside-class -- a decorator factory cannot be a class method
56
+ function DefaultFrameworkImplementationOn(serviceIdentifier) {
49
57
  // webpieces-disable no-any-unknown -- decorator target is any class constructor
50
58
  return (target) => {
51
59
  frameworkRegistry.push(new FrameworkBinding(serviceIdentifier, target));
@@ -1 +1 @@
1
- {"version":3,"file":"frameworkProvide.js","sourceRoot":"","sources":["../../../../../packages/core/core-context/src/frameworkProvide.ts"],"names":[],"mappings":";;AAoDA,8DAMC;AAMD,kEAMC;AAOD,8DAMC;AAwBD,sDAEC;AAOD,oDAoBC;AAxID,yCAA4C;AAE5C,uCAAqC;AAwBrC,MAAM,gBAAgB;IAEE;IACA;IACA;IAHpB,YACoB,iBAAoC,EACpC,MAAe,EACf,QAAwB,WAAW;QAFnC,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,WAAM,GAAN,MAAM,CAAS;QACf,UAAK,GAAL,KAAK,CAA8B;IACpD,CAAC;CACP;AAED,oGAAoG;AACpG,MAAM,wBAAwB;IAEN;IACA;IAFpB,YACoB,KAAwB,EACxB,MAAe;QADf,UAAK,GAAL,KAAK,CAAmB;QACxB,WAAM,GAAN,MAAM,CAAS;IAChC,CAAC;CACP;AAED,oGAAoG;AACpG,MAAM,iBAAiB,GAAuB,EAAE,CAAC;AAEjD,gGAAgG;AAChG,MAAM,yBAAyB,GAA+B,EAAE,CAAC;AAEjE;;;GAGG;AACH,SAAgB,yBAAyB;IACrC,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,iBAAiB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,SAAgB,2BAA2B,CAAI,iBAAuC;IAClF,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,iBAAiB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,8FAA8F;AAC9F,SAAgB,yBAAyB;IACrC,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,iBAAiB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,oHAAoH;AACpH,SAAgB,qBAAqB,CAAC,KAAwB,EAAE,MAAe;IAC3E,yBAAyB,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB;IAChC,OAAO,IAAI,2BAAe,CAAC,CAAC,OAAmC,EAAE,EAAE;QAC/D,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC1E,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;gBAChC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC9B,CAAC;QACL,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,yBAAyB,EAAE,CAAC;YAC9C,oFAAoF;YACpF,uEAAuE;YACvE,OAAO;iBACF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;iBACnB,cAAc,CAAC,CAAC,OAA0B,EAAE,EAAE,CAC3C,IAAI,kBAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;iBACnD,gBAAgB,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { ContainerModule } from 'inversify';\nimport type { ContainerModuleLoadOptions, ResolutionContext, ServiceIdentifier } from 'inversify';\nimport { Provider } from './provide';\n\n/**\n * Framework-only DI provider decorators — a SEPARATE registry from the client-facing\n * @provideSingleton (which uses @inversifyjs/binding-decorators' single global registry).\n *\n * WHY: binding-decorators registers every @provideSingleton class under ONE global\n * reflect-metadata key, and buildProviderModule() scoops up that whole key. If webpieces\n * framework classes (RouteBuilderImpl, the filters, WebpiecesRouter) used @provideSingleton,\n * a CLIENT app's buildProviderModule() would drag those framework internals into its own\n * container. To keep the two worlds separate:\n * - packages/** (framework libs) MUST use provideFrameworkSingleton (this registry),\n * enforced by the no-global-providesingleton-in-packages ESLint rule.\n * - apps/** (and downstream client projects) use plain @provideSingleton (the global one).\n * The router loads BOTH buildFrameworkModule() and buildProviderModule(), so everything\n * resolves — but a client's buildProviderModule() only ever sees the client's own classes.\n */\n\n// webpieces-disable no-any-unknown -- decorator targets are arbitrary class constructors\ntype AnyCtor = new (...args: any[]) => unknown;\n\n/** How a framework binding is scoped. Always explicit — never inherited from the container. */\nexport type FrameworkScope = 'singleton' | 'transient';\n\nclass FrameworkBinding {\n constructor(\n public readonly serviceIdentifier: ServiceIdentifier,\n public readonly target: AnyCtor,\n public readonly scope: FrameworkScope = 'singleton',\n ) {}\n}\n\n/** A Provider token paired with the class its get() resolves. See {@link bindFrameworkProvider}. */\nclass FrameworkProviderBinding {\n constructor(\n public readonly token: ServiceIdentifier,\n public readonly target: AnyCtor,\n ) {}\n}\n\n/** The webpieces-only binding registry (a plain module-level list, one per hosted core-context). */\nconst frameworkRegistry: FrameworkBinding[] = [];\n\n/** Provider<T> bindings, applied after frameworkRegistry so their targets are already bound. */\nconst frameworkProviderRegistry: FrameworkProviderBinding[] = [];\n\n/**\n * Framework equivalent of @provideSingleton: registers the class as a singleton bound to\n * itself, into the webpieces framework registry (NOT the binding-decorators global one).\n */\nexport function provideFrameworkSingleton(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n frameworkRegistry.push(new FrameworkBinding(target, target));\n return target;\n };\n}\n\n/**\n * Framework equivalent of @provideSingletonAs: binds the impl to a token (Symbol or abstract\n * class) as a singleton, into the webpieces framework registry.\n */\nexport function provideFrameworkSingletonAs<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n frameworkRegistry.push(new FrameworkBinding(serviceIdentifier, target));\n return target;\n };\n}\n\n/**\n * Framework equivalent of @provideTransient: a NEW instance on every resolve. Use it for a\n * class a {@link Provider} hands out per call — e.g. one ProxyClient per API contract.\n */\n// webpieces-disable no-function-outside-class -- a decorator factory cannot be a class method\nexport function provideFrameworkTransient(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n frameworkRegistry.push(new FrameworkBinding(target, target, 'transient'));\n return target;\n };\n}\n\n/**\n * Register a {@link Provider} subclass as the DI token that hands out `target` instances.\n *\n * The provider caches nothing; `target`'s own binding scope decides whether callers share one\n * instance (provideFrameworkSingleton -> lazy singleton) or get a fresh one each `get()`\n * (provideFrameworkTransient -> 1-to-many).\n *\n * The provider itself is a singleton — it holds only the resolve-lambda.\n *\n * `Provider<T>` is erased at runtime and cannot be its own token, so name one after T. The DI-graph\n * analyzer reads `target` from HERE, which is why it can draw `Consumer -> T` with no provider box:\n * a Provider is DI plumbing, not wiring anyone needs to see.\n *\n * ```typescript\n * // webpieces-disable no-symbol-di-tokens -- Provider<T> is erased at runtime; T names the token\n * export const PROXY_CLIENT_PROVIDER = Symbol.for('ProxyClientProvider');\n * bindFrameworkProvider(PROXY_CLIENT_PROVIDER, NodeProxyClient);\n *\n * constructor(@inject(PROXY_CLIENT_PROVIDER) private readonly provider: Provider<NodeProxyClient>) {}\n * ```\n */\n// webpieces-disable no-function-outside-class -- registry side-effect, called at module scope beside the decorators\nexport function bindFrameworkProvider(token: ServiceIdentifier, target: AnyCtor): void {\n frameworkProviderRegistry.push(new FrameworkProviderBinding(token, target));\n}\n\n/**\n * Build a ContainerModule binding every provideFrameworkSingleton(As)/Transient class, then\n * every registered Provider. Load this into the webpieces framework + app containers (the\n * router does this) alongside the client's own buildProviderModule().\n */\nexport function buildFrameworkModule(): ContainerModule {\n return new ContainerModule((options: ContainerModuleLoadOptions) => {\n for (const binding of frameworkRegistry) {\n const bindTo = options.bind(binding.serviceIdentifier).to(binding.target);\n if (binding.scope === 'transient') {\n bindTo.inTransientScope();\n } else {\n bindTo.inSingletonScope();\n }\n }\n for (const binding of frameworkProviderRegistry) {\n // toDynamicValue so the provider closes over the ResolutionContext. Each get() then\n // re-resolves `target`, letting TARGET's scope decide shared-vs-fresh.\n options\n .bind(binding.token)\n .toDynamicValue((context: ResolutionContext) =>\n new Provider(() => context.get(binding.target)))\n .inSingletonScope();\n }\n });\n}\n"]}
1
+ {"version":3,"file":"frameworkProvide.js","sourceRoot":"","sources":["../../../../../packages/core/core-context/src/frameworkProvide.ts"],"names":[],"mappings":";;AAoDA,8DAMC;AAcD,4EAMC;AAOD,8DAMC;AAwBD,sDAEC;AAOD,oDAoBC;AAhJD,yCAA4C;AAE5C,uCAAqC;AAwBrC,MAAM,gBAAgB;IAEE;IACA;IACA;IAHpB,YACoB,iBAAoC,EACpC,MAAe,EACf,QAAwB,WAAW;QAFnC,sBAAiB,GAAjB,iBAAiB,CAAmB;QACpC,WAAM,GAAN,MAAM,CAAS;QACf,UAAK,GAAL,KAAK,CAA8B;IACpD,CAAC;CACP;AAED,oGAAoG;AACpG,MAAM,wBAAwB;IAEN;IACA;IAFpB,YACoB,KAAwB,EACxB,MAAe;QADf,UAAK,GAAL,KAAK,CAAmB;QACxB,WAAM,GAAN,MAAM,CAAS;IAChC,CAAC;CACP;AAED,oGAAoG;AACpG,MAAM,iBAAiB,GAAuB,EAAE,CAAC;AAEjD,gGAAgG;AAChG,MAAM,yBAAyB,GAA+B,EAAE,CAAC;AAEjE;;;GAGG;AACH,SAAgB,yBAAyB;IACrC,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,iBAAiB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;GAUG;AACH,8FAA8F;AAC9F,SAAgB,gCAAgC,CAAI,iBAAuC;IACvF,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,iBAAiB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED;;;GAGG;AACH,8FAA8F;AAC9F,SAAgB,yBAAyB;IACrC,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,iBAAiB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,oHAAoH;AACpH,SAAgB,qBAAqB,CAAC,KAAwB,EAAE,MAAe;IAC3E,yBAAyB,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB;IAChC,OAAO,IAAI,2BAAe,CAAC,CAAC,OAAmC,EAAE,EAAE;QAC/D,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC1E,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;gBAChC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC9B,CAAC;QACL,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,yBAAyB,EAAE,CAAC;YAC9C,oFAAoF;YACpF,uEAAuE;YACvE,OAAO;iBACF,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;iBACnB,cAAc,CAAC,CAAC,OAA0B,EAAE,EAAE,CAC3C,IAAI,kBAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;iBACnD,gBAAgB,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { ContainerModule } from 'inversify';\nimport type { ContainerModuleLoadOptions, ResolutionContext, ServiceIdentifier } from 'inversify';\nimport { Provider } from './provide';\n\n/**\n * Framework-only DI provider decorators — a SEPARATE registry from the client-facing\n * @provideSingleton (which uses @inversifyjs/binding-decorators' single global registry).\n *\n * WHY: binding-decorators registers every @provideSingleton class under ONE global\n * reflect-metadata key, and buildProviderModule() scoops up that whole key. If webpieces\n * framework classes (RouteBuilderImpl, the filters, WebpiecesRouter) used @provideSingleton,\n * a CLIENT app's buildProviderModule() would drag those framework internals into its own\n * container. To keep the two worlds separate:\n * - packages/** (framework libs) MUST use provideFrameworkSingleton (this registry),\n * enforced by the no-global-providesingleton-in-packages ESLint rule.\n * - apps/** (and downstream client projects) use plain @provideSingleton (the global one).\n * The router loads BOTH buildFrameworkModule() and buildProviderModule(), so everything\n * resolves — but a client's buildProviderModule() only ever sees the client's own classes.\n */\n\n// webpieces-disable no-any-unknown -- decorator targets are arbitrary class constructors\ntype AnyCtor = new (...args: any[]) => unknown;\n\n/** How a framework binding is scoped. Always explicit — never inherited from the container. */\nexport type FrameworkScope = 'singleton' | 'transient';\n\nclass FrameworkBinding {\n constructor(\n public readonly serviceIdentifier: ServiceIdentifier,\n public readonly target: AnyCtor,\n public readonly scope: FrameworkScope = 'singleton',\n ) {}\n}\n\n/** A Provider token paired with the class its get() resolves. See {@link bindFrameworkProvider}. */\nclass FrameworkProviderBinding {\n constructor(\n public readonly token: ServiceIdentifier,\n public readonly target: AnyCtor,\n ) {}\n}\n\n/** The webpieces-only binding registry (a plain module-level list, one per hosted core-context). */\nconst frameworkRegistry: FrameworkBinding[] = [];\n\n/** Provider<T> bindings, applied after frameworkRegistry so their targets are already bound. */\nconst frameworkProviderRegistry: FrameworkProviderBinding[] = [];\n\n/**\n * Framework equivalent of @provideSingleton: registers the class as a singleton bound to\n * itself, into the webpieces framework registry (NOT the binding-decorators global one).\n */\nexport function provideFrameworkSingleton(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n frameworkRegistry.push(new FrameworkBinding(target, target));\n return target;\n };\n}\n\n/**\n * Framework equivalent of @DefaultImplementationOn: marks this class as the DEFAULT (overridable)\n * singleton implementation OF a contract token (Symbol or abstract class), into the webpieces\n * framework registry. Binds `token -> thisClass` as a singleton.\n *\n * An app overrides it via appOverrides (loaded LAST), same idiom as AuthConfig:\n * `(await options.rebind(TOKEN)).to(OtherImpl)`.\n *\n * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)`\n * and expands this class's own dependencies.\n */\n// webpieces-disable no-function-outside-class -- a decorator factory cannot be a class method\nexport function DefaultFrameworkImplementationOn<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n frameworkRegistry.push(new FrameworkBinding(serviceIdentifier, target));\n return target;\n };\n}\n\n/**\n * Framework equivalent of @provideTransient: a NEW instance on every resolve. Use it for a\n * class a {@link Provider} hands out per call — e.g. one ProxyClient per API contract.\n */\n// webpieces-disable no-function-outside-class -- a decorator factory cannot be a class method\nexport function provideFrameworkTransient(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n frameworkRegistry.push(new FrameworkBinding(target, target, 'transient'));\n return target;\n };\n}\n\n/**\n * Register a {@link Provider} subclass as the DI token that hands out `target` instances.\n *\n * The provider caches nothing; `target`'s own binding scope decides whether callers share one\n * instance (provideFrameworkSingleton -> lazy singleton) or get a fresh one each `get()`\n * (provideFrameworkTransient -> 1-to-many).\n *\n * The provider itself is a singleton — it holds only the resolve-lambda.\n *\n * `Provider<T>` is erased at runtime and cannot be its own token, so name one after T. The DI-graph\n * analyzer reads `target` from HERE, which is why it can draw `Consumer -> T` with no provider box:\n * a Provider is DI plumbing, not wiring anyone needs to see.\n *\n * ```typescript\n * // webpieces-disable no-symbol-di-tokens -- Provider<T> is erased at runtime; T names the token\n * export const PROXY_CLIENT_PROVIDER = Symbol.for('ProxyClientProvider');\n * bindFrameworkProvider(PROXY_CLIENT_PROVIDER, NodeProxyClient);\n *\n * constructor(@inject(PROXY_CLIENT_PROVIDER) private readonly provider: Provider<NodeProxyClient>) {}\n * ```\n */\n// webpieces-disable no-function-outside-class -- registry side-effect, called at module scope beside the decorators\nexport function bindFrameworkProvider(token: ServiceIdentifier, target: AnyCtor): void {\n frameworkProviderRegistry.push(new FrameworkProviderBinding(token, target));\n}\n\n/**\n * Build a ContainerModule binding every provideFrameworkSingleton(As)/Transient class, then\n * every registered Provider. Load this into the webpieces framework + app containers (the\n * router does this) alongside the client's own buildProviderModule().\n */\nexport function buildFrameworkModule(): ContainerModule {\n return new ContainerModule((options: ContainerModuleLoadOptions) => {\n for (const binding of frameworkRegistry) {\n const bindTo = options.bind(binding.serviceIdentifier).to(binding.target);\n if (binding.scope === 'transient') {\n bindTo.inTransientScope();\n } else {\n bindTo.inSingletonScope();\n }\n }\n for (const binding of frameworkProviderRegistry) {\n // toDynamicValue so the provider closes over the ResolutionContext. Each get() then\n // re-resolves `target`, letting TARGET's scope decide shared-vs-fresh.\n options\n .bind(binding.token)\n .toDynamicValue((context: ResolutionContext) =>\n new Provider(() => context.get(binding.target)))\n .inSingletonScope();\n }\n });\n}\n"]}
package/src/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { RequestContext } from './RequestContext';
2
2
  export { HttpRequest } from './HttpRequest';
3
- export { provideSingleton, provideSingletonAs, provideTransient } from './provide';
3
+ export { provideSingleton, DefaultImplementationOn, provideTransient } from './provide';
4
4
  export { Provider } from './provide';
5
- export { provideFrameworkSingleton, provideFrameworkSingletonAs, provideFrameworkTransient, bindFrameworkProvider, buildFrameworkModule, } from './frameworkProvide';
5
+ export { provideFrameworkSingleton, DefaultFrameworkImplementationOn, provideFrameworkTransient, bindFrameworkProvider, buildFrameworkModule, } from './frameworkProvide';
6
6
  export type { FrameworkScope } from './frameworkProvide';
7
7
  export { RequestContextHeaders } from './RequestContextHeaders';
8
8
  export { RequestContextReader } from './RequestContextReader';
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RequestContextReader = exports.RequestContextHeaders = exports.buildFrameworkModule = exports.bindFrameworkProvider = exports.provideFrameworkTransient = exports.provideFrameworkSingletonAs = exports.provideFrameworkSingleton = exports.Provider = exports.provideTransient = exports.provideSingletonAs = exports.provideSingleton = exports.HttpRequest = exports.RequestContext = void 0;
3
+ exports.RequestContextReader = exports.RequestContextHeaders = exports.buildFrameworkModule = exports.bindFrameworkProvider = exports.provideFrameworkTransient = exports.DefaultFrameworkImplementationOn = exports.provideFrameworkSingleton = exports.Provider = exports.provideTransient = exports.DefaultImplementationOn = exports.provideSingleton = exports.HttpRequest = exports.RequestContext = void 0;
4
4
  // Context management with AsyncLocalStorage
5
5
  var RequestContext_1 = require("./RequestContext");
6
6
  Object.defineProperty(exports, "RequestContext", { enumerable: true, get: function () { return RequestContext_1.RequestContext; } });
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "HttpRequest", { enumerable: true, get: function
10
10
  // DI provider decorators (shared DI seam; http-routing re-exports for back-compat)
11
11
  var provide_1 = require("./provide");
12
12
  Object.defineProperty(exports, "provideSingleton", { enumerable: true, get: function () { return provide_1.provideSingleton; } });
13
- Object.defineProperty(exports, "provideSingletonAs", { enumerable: true, get: function () { return provide_1.provideSingletonAs; } });
13
+ Object.defineProperty(exports, "DefaultImplementationOn", { enumerable: true, get: function () { return provide_1.DefaultImplementationOn; } });
14
14
  Object.defineProperty(exports, "provideTransient", { enumerable: true, get: function () { return provide_1.provideTransient; } });
15
15
  // Guice-style Provider<T> — lazy singleton OR fresh-per-get, decided by T's binding scope.
16
16
  var provide_2 = require("./provide");
@@ -19,7 +19,7 @@ Object.defineProperty(exports, "Provider", { enumerable: true, get: function ()
19
19
  // client's buildProviderModule() global scan). See frameworkProvide.ts.
20
20
  var frameworkProvide_1 = require("./frameworkProvide");
21
21
  Object.defineProperty(exports, "provideFrameworkSingleton", { enumerable: true, get: function () { return frameworkProvide_1.provideFrameworkSingleton; } });
22
- Object.defineProperty(exports, "provideFrameworkSingletonAs", { enumerable: true, get: function () { return frameworkProvide_1.provideFrameworkSingletonAs; } });
22
+ Object.defineProperty(exports, "DefaultFrameworkImplementationOn", { enumerable: true, get: function () { return frameworkProvide_1.DefaultFrameworkImplementationOn; } });
23
23
  Object.defineProperty(exports, "provideFrameworkTransient", { enumerable: true, get: function () { return frameworkProvide_1.provideFrameworkTransient; } });
24
24
  Object.defineProperty(exports, "bindFrameworkProvider", { enumerable: true, get: function () { return frameworkProvide_1.bindFrameworkProvider; } });
25
25
  Object.defineProperty(exports, "buildFrameworkModule", { enumerable: true, get: function () { return frameworkProvide_1.buildFrameworkModule; } });
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-context/src/index.ts"],"names":[],"mappings":";;;AAAA,4CAA4C;AAC5C,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,mGAAmG;AACnG,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AAEpB,mFAAmF;AACnF,qCAAmF;AAA1E,2GAAA,gBAAgB,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAC/D,2FAA2F;AAC3F,qCAAqC;AAA5B,mGAAA,QAAQ,OAAA;AACjB,sFAAsF;AACtF,wEAAwE;AACxE,uDAM4B;AALxB,6HAAA,yBAAyB,OAAA;AACzB,+HAAA,2BAA2B,OAAA;AAC3B,6HAAA,yBAAyB,OAAA;AACzB,yHAAA,qBAAqB,OAAA;AACrB,wHAAA,oBAAoB,OAAA;AAIxB,mFAAmF;AACnF,yFAAyF;AACzF,yBAAyB;AACzB,EAAE;AACF,8FAA8F;AAC9F,2FAA2F;AAC3F,uDAAuD;AACvD,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,oGAAoG;AACpG,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA","sourcesContent":["// Context management with AsyncLocalStorage\nexport { RequestContext } from './RequestContext';\n// Transport-neutral request stored in the context (http-routing's request type; re-exported there)\nexport { HttpRequest } from './HttpRequest';\n\n// DI provider decorators (shared DI seam; http-routing re-exports for back-compat)\nexport { provideSingleton, provideSingletonAs, provideTransient } from './provide';\n// Guice-style Provider<T> — lazy singleton OR fresh-per-get, decided by T's binding scope.\nexport { Provider } from './provide';\n// Framework-only DI registry (packages/** use these; keeps framework classes out of a\n// client's buildProviderModule() global scan). See frameworkProvide.ts.\nexport {\n provideFrameworkSingleton,\n provideFrameworkSingletonAs,\n provideFrameworkTransient,\n bindFrameworkProvider,\n buildFrameworkModule,\n} from './frameworkProvide';\nexport type { FrameworkScope } from './frameworkProvide';\n\n// Outbound headers for a SERVER: reads RequestContext directly, fails fast outside\n// RequestContext.run(...). Server-side clients (http-client-node, cloudtasks-client) and\n// http-routing use THIS.\n//\n// ContextMgr is deliberately NOT re-exported. It is the browser's answer (an app-held store),\n// and only @webpieces/http-client-browser may name it — importing it here would let a node\n// package reach for a ContextReader it has no use for.\nexport { RequestContextHeaders } from './RequestContextHeaders';\n// The browser store's server counterpart, still used by the logging packages + http-server filters.\nexport { RequestContextReader } from './RequestContextReader';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/core/core-context/src/index.ts"],"names":[],"mappings":";;;AAAA,4CAA4C;AAC5C,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,mGAAmG;AACnG,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AAEpB,mFAAmF;AACnF,qCAAwF;AAA/E,2GAAA,gBAAgB,OAAA;AAAE,kHAAA,uBAAuB,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AACpE,2FAA2F;AAC3F,qCAAqC;AAA5B,mGAAA,QAAQ,OAAA;AACjB,sFAAsF;AACtF,wEAAwE;AACxE,uDAM4B;AALxB,6HAAA,yBAAyB,OAAA;AACzB,oIAAA,gCAAgC,OAAA;AAChC,6HAAA,yBAAyB,OAAA;AACzB,yHAAA,qBAAqB,OAAA;AACrB,wHAAA,oBAAoB,OAAA;AAIxB,mFAAmF;AACnF,yFAAyF;AACzF,yBAAyB;AACzB,EAAE;AACF,8FAA8F;AAC9F,2FAA2F;AAC3F,uDAAuD;AACvD,iEAAgE;AAAvD,8HAAA,qBAAqB,OAAA;AAC9B,oGAAoG;AACpG,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA","sourcesContent":["// Context management with AsyncLocalStorage\nexport { RequestContext } from './RequestContext';\n// Transport-neutral request stored in the context (http-routing's request type; re-exported there)\nexport { HttpRequest } from './HttpRequest';\n\n// DI provider decorators (shared DI seam; http-routing re-exports for back-compat)\nexport { provideSingleton, DefaultImplementationOn, provideTransient } from './provide';\n// Guice-style Provider<T> — lazy singleton OR fresh-per-get, decided by T's binding scope.\nexport { Provider } from './provide';\n// Framework-only DI registry (packages/** use these; keeps framework classes out of a\n// client's buildProviderModule() global scan). See frameworkProvide.ts.\nexport {\n provideFrameworkSingleton,\n DefaultFrameworkImplementationOn,\n provideFrameworkTransient,\n bindFrameworkProvider,\n buildFrameworkModule,\n} from './frameworkProvide';\nexport type { FrameworkScope } from './frameworkProvide';\n\n// Outbound headers for a SERVER: reads RequestContext directly, fails fast outside\n// RequestContext.run(...). Server-side clients (http-client-node, cloudtasks-client) and\n// http-routing use THIS.\n//\n// ContextMgr is deliberately NOT re-exported. It is the browser's answer (an app-held store),\n// and only @webpieces/http-client-browser may name it — importing it here would let a node\n// package reach for a ContextReader it has no use for.\nexport { RequestContextHeaders } from './RequestContextHeaders';\n// The browser store's server counterpart, still used by the logging packages + http-server filters.\nexport { RequestContextReader } from './RequestContextReader';\n"]}
package/src/provide.d.ts CHANGED
@@ -22,18 +22,25 @@ import type { ServiceIdentifier } from 'inversify';
22
22
  */
23
23
  export declare function provideSingleton(): ClassDecorator;
24
24
  /**
25
- * Provides a singleton-scoped dependency bound to a specific token (Symbol or abstract class).
26
- * Use this in libraries/apis-external/** to bind an impl to the Symbol defined in libraries/apis/**.
25
+ * Marks this class as the DEFAULT (overridable) singleton implementation OF a contract token
26
+ * (a Symbol or an abstract class). Binds `token -> thisClass` as a singleton. Guice's
27
+ * `@ImplementedBy`, done impl-side so the api never imports the impl (no cycle).
28
+ *
29
+ * An app overrides the default via appOverrides, same idiom as AuthConfig:
30
+ * `(await options.rebind(TOKEN)).to(OtherImpl)`.
31
+ *
32
+ * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)`
33
+ * and expands this class's own dependencies instead of dead-ending as unresolved.
27
34
  *
28
35
  * Usage:
29
36
  * ```typescript
30
37
  * import { SOME_API_TOKEN } from '@myorg/some-api';
31
38
  *
32
- * @provideSingletonAs(SOME_API_TOKEN)
39
+ * @DefaultImplementationOn(SOME_API_TOKEN)
33
40
  * export class SomeApiImpl { ... }
34
41
  * ```
35
42
  */
36
- export declare function provideSingletonAs<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator;
43
+ export declare function DefaultImplementationOn<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator;
37
44
  /**
38
45
  * Provides a transient-scoped dependency (new instance every time).
39
46
  * When called without arguments, the decorated class binds to itself.
package/src/provide.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Provider = void 0;
4
4
  exports.provideSingleton = provideSingleton;
5
- exports.provideSingletonAs = provideSingletonAs;
5
+ exports.DefaultImplementationOn = DefaultImplementationOn;
6
6
  exports.provideTransient = provideTransient;
7
7
  require("reflect-metadata");
8
8
  const binding_decorators_1 = require("@inversifyjs/binding-decorators");
@@ -33,18 +33,26 @@ function provideSingleton() {
33
33
  };
34
34
  }
35
35
  /**
36
- * Provides a singleton-scoped dependency bound to a specific token (Symbol or abstract class).
37
- * Use this in libraries/apis-external/** to bind an impl to the Symbol defined in libraries/apis/**.
36
+ * Marks this class as the DEFAULT (overridable) singleton implementation OF a contract token
37
+ * (a Symbol or an abstract class). Binds `token -> thisClass` as a singleton. Guice's
38
+ * `@ImplementedBy`, done impl-side so the api never imports the impl (no cycle).
39
+ *
40
+ * An app overrides the default via appOverrides, same idiom as AuthConfig:
41
+ * `(await options.rebind(TOKEN)).to(OtherImpl)`.
42
+ *
43
+ * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)`
44
+ * and expands this class's own dependencies instead of dead-ending as unresolved.
38
45
  *
39
46
  * Usage:
40
47
  * ```typescript
41
48
  * import { SOME_API_TOKEN } from '@myorg/some-api';
42
49
  *
43
- * @provideSingletonAs(SOME_API_TOKEN)
50
+ * @DefaultImplementationOn(SOME_API_TOKEN)
44
51
  * export class SomeApiImpl { ... }
45
52
  * ```
46
53
  */
47
- function provideSingletonAs(serviceIdentifier) {
54
+ // webpieces-disable no-function-outside-class -- a decorator factory cannot be a class method
55
+ function DefaultImplementationOn(serviceIdentifier) {
48
56
  return (0, binding_decorators_1.provide)(serviceIdentifier, (bind) => bind.inSingletonScope());
49
57
  }
50
58
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"provide.js","sourceRoot":"","sources":["../../../../../packages/core/core-context/src/provide.ts"],"names":[],"mappings":";;;AAyBA,4CAKC;AAcD,gDAEC;AAcD,4CASC;AArED,4BAA0B;AAC1B,wEAA0D;AAG1D;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,SAAgB,gBAAgB;IAC5B,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,OAAO,IAAA,4BAAO,EAAC,MAAM,EAAE,CAAC,IAAuC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzG,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,kBAAkB,CAAI,iBAAuC;IACzE,OAAO,IAAA,4BAAO,EAAC,iBAAiB,EAAE,CAAC,IAAiC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACtG,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,gBAAgB;IAC5B,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,uFAAuF;QACvF,qFAAqF;QACrF,wEAAwE;QACxE,+FAA+F;QAC/F,OAAO,IAAA,4BAAO,EAAC,MAAM,EAAE,CAAC,IAAuC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzG,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAa,QAAQ;IACY;IAA7B,YAA6B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;IAEjD,GAAG;QACC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;CACJ;AAND,4BAMC","sourcesContent":["import 'reflect-metadata';\nimport { provide } from '@inversifyjs/binding-decorators';\nimport type { BindInWhenOnFluentSyntax, ServiceIdentifier } from 'inversify';\n\n/**\n * DI provider decorators (the lightweight DI seam shared across webpieces).\n *\n * These live in @webpieces/core-context — the lowest package that already owns\n * request-scoped context — so libraries (cloudtasks-client, http-client, …) can\n * register singletons WITHOUT depending on the server-side @webpieces/http-routing\n * package. http-routing re-exports them for back-compat.\n */\n\n/**\n * Provides a singleton-scoped dependency.\n * When called without arguments, the decorated class binds to itself.\n *\n * Usage:\n * ```typescript\n * @provideSingleton()\n * export class SaveController {\n * // ...\n * }\n * ```\n */\nexport function provideSingleton(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n return provide(target, (bind: BindInWhenOnFluentSyntax<unknown>) => bind.inSingletonScope())(target);\n };\n}\n\n/**\n * Provides a singleton-scoped dependency bound to a specific token (Symbol or abstract class).\n * Use this in libraries/apis-external/** to bind an impl to the Symbol defined in libraries/apis/**.\n *\n * Usage:\n * ```typescript\n * import { SOME_API_TOKEN } from '@myorg/some-api';\n *\n * @provideSingletonAs(SOME_API_TOKEN)\n * export class SomeApiImpl { ... }\n * ```\n */\nexport function provideSingletonAs<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator {\n return provide(serviceIdentifier, (bind: BindInWhenOnFluentSyntax<T>) => bind.inSingletonScope());\n}\n\n/**\n * Provides a transient-scoped dependency (new instance every time).\n * When called without arguments, the decorated class binds to itself.\n *\n * Usage:\n * ```typescript\n * @provideTransient()\n * export class TransientController {\n * // ...\n * }\n * ```\n */\nexport function provideTransient(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n // Call inTransientScope() EXPLICITLY. Omitting the scope call inherits the container's\n // defaultScope which, while Transient by default in inversify 7, would silently flip\n // meaning if anyone ever passed `new Container({ defaultScope: ... })`.\n // webpieces-disable no-any-unknown -- inversify's own fluent-syntax generic for a self-binding\n return provide(target, (bind: BindInWhenOnFluentSyntax<unknown>) => bind.inTransientScope())(target);\n };\n}\n\n/**\n * Provider<T> — Guice's object-oriented `Provider<T>`, which inversify does not have.\n *\n * Inversify's own `Provider<T>` is a FUNCTION type `(...args) => Promise<T>` and its\n * `toProvider()` binding is deprecated (\"Providers will be removed in v8\"), so we model\n * Guice's seam ourselves.\n *\n * It caches NOTHING, because `ResolutionContext.get()` already applies the BOUND SCOPE of `T`:\n *\n * T bound @provideFrameworkSingleton -> every get() returns the SAME instance, built on the\n * first call. That is a LAZY SINGLETON.\n * T bound @provideFrameworkTransient -> every get() builds a NEW instance. That is 1-to-many.\n *\n * A provider that cached internally would break the transient case outright: the second get()\n * would hand back the first instance.\n *\n * `get()` is SYNCHRONOUS, like Guice's. An async `get()` would force every consumer (e.g.\n * `ClientHttpFactory.createClient`) to become async, and neither Angular's `useFactory` nor\n * inversify's `toDynamicValue` can await.\n *\n * TypeScript erases generics, so `Provider<T>` has NO runtime identity and cannot itself be a DI\n * token. Register it against a Symbol naming T, with {@link bindFrameworkProvider}, and inject it\n * by that token — the declared type is what a reader needs, the Symbol is what inversify needs:\n *\n * ```typescript\n * // webpieces-disable no-symbol-di-tokens -- Provider<T> is erased at runtime; T names the token\n * export const TASK_PROXY_PROVIDER = Symbol.for('TaskProxyClientProvider');\n * bindFrameworkProvider(TASK_PROXY_PROVIDER, TaskProxyClient);\n *\n * constructor(@inject(TASK_PROXY_PROVIDER) private readonly provider: Provider<TaskProxyClient>) {}\n * ```\n *\n * Inject a Provider when you need a dependency LATER or REPEATEDLY rather than at construction\n * time — a lazily-created singleton, or a fresh instance per call.\n */\nexport class Provider<T> {\n constructor(private readonly resolve: () => T) {}\n\n get(): T {\n return this.resolve();\n }\n}\n"]}
1
+ {"version":3,"file":"provide.js","sourceRoot":"","sources":["../../../../../packages/core/core-context/src/provide.ts"],"names":[],"mappings":";;;AAyBA,4CAKC;AAsBD,0DAEC;AAcD,4CASC;AA7ED,4BAA0B;AAC1B,wEAA0D;AAG1D;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,SAAgB,gBAAgB;IAC5B,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,OAAO,IAAA,4BAAO,EAAC,MAAM,EAAE,CAAC,IAAuC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzG,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,8FAA8F;AAC9F,SAAgB,uBAAuB,CAAI,iBAAuC;IAC9E,OAAO,IAAA,4BAAO,EAAC,iBAAiB,EAAE,CAAC,IAAiC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;AACtG,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,gBAAgB;IAC5B,gFAAgF;IAChF,OAAO,CAAC,MAAW,EAAE,EAAE;QACnB,uFAAuF;QACvF,qFAAqF;QACrF,wEAAwE;QACxE,+FAA+F;QAC/F,OAAO,IAAA,4BAAO,EAAC,MAAM,EAAE,CAAC,IAAuC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzG,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAa,QAAQ;IACY;IAA7B,YAA6B,OAAgB;QAAhB,YAAO,GAAP,OAAO,CAAS;IAAG,CAAC;IAEjD,GAAG;QACC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;CACJ;AAND,4BAMC","sourcesContent":["import 'reflect-metadata';\nimport { provide } from '@inversifyjs/binding-decorators';\nimport type { BindInWhenOnFluentSyntax, ServiceIdentifier } from 'inversify';\n\n/**\n * DI provider decorators (the lightweight DI seam shared across webpieces).\n *\n * These live in @webpieces/core-context — the lowest package that already owns\n * request-scoped context — so libraries (cloudtasks-client, http-client, …) can\n * register singletons WITHOUT depending on the server-side @webpieces/http-routing\n * package. http-routing re-exports them for back-compat.\n */\n\n/**\n * Provides a singleton-scoped dependency.\n * When called without arguments, the decorated class binds to itself.\n *\n * Usage:\n * ```typescript\n * @provideSingleton()\n * export class SaveController {\n * // ...\n * }\n * ```\n */\nexport function provideSingleton(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n return provide(target, (bind: BindInWhenOnFluentSyntax<unknown>) => bind.inSingletonScope())(target);\n };\n}\n\n/**\n * Marks this class as the DEFAULT (overridable) singleton implementation OF a contract token\n * (a Symbol or an abstract class). Binds `token -> thisClass` as a singleton. Guice's\n * `@ImplementedBy`, done impl-side so the api never imports the impl (no cycle).\n *\n * An app overrides the default via appOverrides, same idiom as AuthConfig:\n * `(await options.rebind(TOKEN)).to(OtherImpl)`.\n *\n * The DI-graph designer reads this in pass 1, so `@inject(TOKEN)` renders as `TOKEN (thisClass)`\n * and expands this class's own dependencies instead of dead-ending as unresolved.\n *\n * Usage:\n * ```typescript\n * import { SOME_API_TOKEN } from '@myorg/some-api';\n *\n * @DefaultImplementationOn(SOME_API_TOKEN)\n * export class SomeApiImpl { ... }\n * ```\n */\n// webpieces-disable no-function-outside-class -- a decorator factory cannot be a class method\nexport function DefaultImplementationOn<T>(serviceIdentifier: ServiceIdentifier<T>): ClassDecorator {\n return provide(serviceIdentifier, (bind: BindInWhenOnFluentSyntax<T>) => bind.inSingletonScope());\n}\n\n/**\n * Provides a transient-scoped dependency (new instance every time).\n * When called without arguments, the decorated class binds to itself.\n *\n * Usage:\n * ```typescript\n * @provideTransient()\n * export class TransientController {\n * // ...\n * }\n * ```\n */\nexport function provideTransient(): ClassDecorator {\n // webpieces-disable no-any-unknown -- decorator target is any class constructor\n return (target: any) => {\n // Call inTransientScope() EXPLICITLY. Omitting the scope call inherits the container's\n // defaultScope which, while Transient by default in inversify 7, would silently flip\n // meaning if anyone ever passed `new Container({ defaultScope: ... })`.\n // webpieces-disable no-any-unknown -- inversify's own fluent-syntax generic for a self-binding\n return provide(target, (bind: BindInWhenOnFluentSyntax<unknown>) => bind.inTransientScope())(target);\n };\n}\n\n/**\n * Provider<T> — Guice's object-oriented `Provider<T>`, which inversify does not have.\n *\n * Inversify's own `Provider<T>` is a FUNCTION type `(...args) => Promise<T>` and its\n * `toProvider()` binding is deprecated (\"Providers will be removed in v8\"), so we model\n * Guice's seam ourselves.\n *\n * It caches NOTHING, because `ResolutionContext.get()` already applies the BOUND SCOPE of `T`:\n *\n * T bound @provideFrameworkSingleton -> every get() returns the SAME instance, built on the\n * first call. That is a LAZY SINGLETON.\n * T bound @provideFrameworkTransient -> every get() builds a NEW instance. That is 1-to-many.\n *\n * A provider that cached internally would break the transient case outright: the second get()\n * would hand back the first instance.\n *\n * `get()` is SYNCHRONOUS, like Guice's. An async `get()` would force every consumer (e.g.\n * `ClientHttpFactory.createClient`) to become async, and neither Angular's `useFactory` nor\n * inversify's `toDynamicValue` can await.\n *\n * TypeScript erases generics, so `Provider<T>` has NO runtime identity and cannot itself be a DI\n * token. Register it against a Symbol naming T, with {@link bindFrameworkProvider}, and inject it\n * by that token — the declared type is what a reader needs, the Symbol is what inversify needs:\n *\n * ```typescript\n * // webpieces-disable no-symbol-di-tokens -- Provider<T> is erased at runtime; T names the token\n * export const TASK_PROXY_PROVIDER = Symbol.for('TaskProxyClientProvider');\n * bindFrameworkProvider(TASK_PROXY_PROVIDER, TaskProxyClient);\n *\n * constructor(@inject(TASK_PROXY_PROVIDER) private readonly provider: Provider<TaskProxyClient>) {}\n * ```\n *\n * Inject a Provider when you need a dependency LATER or REPEATEDLY rather than at construction\n * time — a lazily-created singleton, or a fresh instance per call.\n */\nexport class Provider<T> {\n constructor(private readonly resolve: () => T) {}\n\n get(): T {\n return this.resolve();\n }\n}\n"]}