lanka 2.1.0 → 2.2.1

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.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/dist/{ILankaScenario-DQd9ZfUw.d.ts → ILankaScenario-7J3MoKiY.d.ts} +9 -0
  3. package/dist/{ILankaScenarioMetadata-BsDp0Bzm.d.ts → ILankaScenarioMetadata-DgOxvpwx.d.ts} +1 -1
  4. package/dist/LankaScenarioVMRegistry-CFzCpIFd.d.ts +46 -0
  5. package/dist/{LankaScenarioVMRegistry-DySAOaj2.d.ts → LankaScenariosRegistry-DiLN9xwy.d.ts} +3 -46
  6. package/dist/_extend/index.d.ts +27 -6
  7. package/dist/_extend/index.js +45 -39
  8. package/dist/_extend/index.js.map +1 -1
  9. package/dist/_internal/index.d.ts +5 -4
  10. package/dist/_internal/index.js +3 -1
  11. package/dist/_internal/index.js.map +1 -1
  12. package/dist/{activeRuntime-ByucLPhj.d.ts → activeRuntime-DxB62KN4.d.ts} +8 -4
  13. package/dist/bootstrap/index.d.ts +8 -7
  14. package/dist/bootstrap/index.js +11 -11
  15. package/dist/chunk-2ICKGQXS.js +21 -0
  16. package/dist/chunk-2ICKGQXS.js.map +1 -0
  17. package/dist/{chunk-MKKMTLOY.js → chunk-4VFVACSL.js} +38 -5
  18. package/dist/{chunk-MKKMTLOY.js.map → chunk-4VFVACSL.js.map} +1 -1
  19. package/dist/{chunk-SO7D5E7O.js → chunk-532WVMAF.js} +16 -16
  20. package/dist/chunk-532WVMAF.js.map +1 -0
  21. package/dist/{chunk-FII3PW2G.js → chunk-AMLUKB6A.js} +2 -2
  22. package/dist/{chunk-O5EUTNR6.js → chunk-DKLOCKS4.js} +2 -2
  23. package/dist/{chunk-42CWYVZJ.js → chunk-EH5WZSRJ.js} +5 -5
  24. package/dist/{chunk-RUMUFHSL.js → chunk-JGJBFELR.js} +2 -2
  25. package/dist/{chunk-NWEHOMTS.js → chunk-L27FF2IH.js} +3 -3
  26. package/dist/chunk-M4BK6GBV.js +90 -0
  27. package/dist/chunk-M4BK6GBV.js.map +1 -0
  28. package/dist/{chunk-BHQ2SQ7P.js → chunk-NMFNEVNE.js} +2 -2
  29. package/dist/{chunk-7DQUF2QR.js → chunk-SP5OUTWF.js} +2 -2
  30. package/dist/chunk-XTVEHYIZ.js +89 -0
  31. package/dist/chunk-XTVEHYIZ.js.map +1 -0
  32. package/dist/config/index.js +3 -3
  33. package/dist/{createLanka-DvUGu9Hl.d.ts → createLanka-AuiMfPL9.d.ts} +4 -4
  34. package/dist/{createLankaScope-CVoV0EwO.d.ts → createLankaScope-DeElRH-E.d.ts} +7 -1
  35. package/dist/errors/index.js +3 -3
  36. package/dist/gateway/index.js +6 -6
  37. package/dist/index.d.ts +8 -7
  38. package/dist/index.js +14 -14
  39. package/dist/locator/index.d.ts +111 -109
  40. package/dist/locator/index.js +35 -9
  41. package/dist/locator/index.js.map +1 -1
  42. package/dist/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.d.ts +1 -1
  43. package/dist/locator/scenario/lanka-scenario-locator/LankaScenarioLocator.js +5 -5
  44. package/dist/logger/index.js +3 -3
  45. package/dist/mock/index.js +3 -3
  46. package/dist/scenario/index.d.ts +18 -4
  47. package/dist/scenario/index.js +5 -5
  48. package/dist/stream/index.d.ts +8 -7
  49. package/dist/viewmodel/index.d.ts +1 -1
  50. package/dist/viewmodel/index.js +7 -6
  51. package/dist/viewmodel/index.js.map +1 -1
  52. package/package.json +2 -2
  53. package/skills/lanka-core/SKILL.md +3 -1
  54. package/skills/lanka-core/reference.md +21 -1
  55. package/skills/lanka-packages/SKILL.md +1 -1
  56. package/dist/chunk-H5TIUKRK.js +0 -59
  57. package/dist/chunk-H5TIUKRK.js.map +0 -1
  58. package/dist/chunk-SBITVBF7.js +0 -49
  59. package/dist/chunk-SBITVBF7.js.map +0 -1
  60. package/dist/chunk-SO7D5E7O.js.map +0 -1
  61. package/dist/chunk-XGMXT4XZ.js +0 -46
  62. package/dist/chunk-XGMXT4XZ.js.map +0 -1
  63. /package/dist/{chunk-FII3PW2G.js.map → chunk-AMLUKB6A.js.map} +0 -0
  64. /package/dist/{chunk-O5EUTNR6.js.map → chunk-DKLOCKS4.js.map} +0 -0
  65. /package/dist/{chunk-42CWYVZJ.js.map → chunk-EH5WZSRJ.js.map} +0 -0
  66. /package/dist/{chunk-RUMUFHSL.js.map → chunk-JGJBFELR.js.map} +0 -0
  67. /package/dist/{chunk-NWEHOMTS.js.map → chunk-L27FF2IH.js.map} +0 -0
  68. /package/dist/{chunk-BHQ2SQ7P.js.map → chunk-NMFNEVNE.js.map} +0 -0
  69. /package/dist/{chunk-7DQUF2QR.js.map → chunk-SP5OUTWF.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/viewmodel/_internal/lanka-vm-recipes/lankaVMRecipes.ts","../src/locator/_factories/create-lanka-scope/createLankaScope.ts"],"sourcesContent":["import type { ILankaReadableVM } from \"../../_interfaces/ILankaReadableVM\";\nimport type { ILankaScenarioVM } from \"../../../scenario/_interfaces/ILankaScenarioVM\";\n\n/** What a definition actually holds, kept where a consumer cannot reach it. */\nexport interface ILankaVMRecipe {\n\treadonly name: string;\n\treadonly build: () => ILankaReadableVM<object>;\n}\n\n/**\n * What `defineLankaVM` writes and `resolveLankaVM` reads.\n *\n * One object rather than two exported maps, because a file here holds one\n * runtime identity — and because the two halves are one mechanism: a recipe\n * nobody can resolve and an instance map keyed by nothing are each meaningless\n * alone.\n *\n * ## Weak at both ends, and both ends matter\n *\n * `recipes` is weak so a definition dropped by its module takes its recipe with\n * it. `instances` is weak in the SCOPE so a finished request's ViewModels go\n * when its scope does, and weak in the DEFINITION because the published type\n * invites `defineLankaVM({...})` written inline in a component or a loop — in a\n * browser the scope key is the framework instance and lives as long as the tab,\n * so a strong inner map would hold every inline definition and its ViewModel\n * for the life of the page.\n *\n * ## `owned` is the one strong set, and it is drained\n *\n * A scope handed to `resolveLankaVM` must be able to take its ViewModels OFF the\n * bus when it closes, and a WeakMap cannot be walked. So what a scope built is\n * also kept in a Set it can read — strong, because the scope must find these\n * even when nothing else holds them — and `release` hands the set over and\n * forgets it, so a closed scope keeps nothing alive.\n */\nexport const lankaVMRecipes = {\n\trecipes: new WeakMap<object, ILankaVMRecipe>(),\n\tinstances: new WeakMap<object, WeakMap<object, ILankaReadableVM<object>>>(),\n\towned: new WeakMap<object, Set<ILankaScenarioVM>>(),\n\n\t/** The instances belonging to one scope, created on first use. */\n\tforScope(scope: object): WeakMap<object, ILankaReadableVM<object>> {\n\t\tconst existing = this.instances.get(scope);\n\n\t\tif (existing) return existing;\n\n\t\tconst created = new WeakMap<object, ILankaReadableVM<object>>();\n\n\t\tthis.instances.set(scope, created);\n\n\t\treturn created;\n\t},\n\t/** Records that `scope` built a ViewModel that registered for scenarios. */\n\town(scope: object, viewModel: ILankaScenarioVM): void {\n\t\tconst set = this.owned.get(scope) ?? new Set<ILankaScenarioVM>();\n\t\tset.add(viewModel);\n\t\tthis.owned.set(scope, set);\n\t},\n\t/** Everything `scope` owns, handed over once; the scope then holds nothing. */\n\trelease(scope: object): ILankaScenarioVM[] {\n\t\tconst set = this.owned.get(scope);\n\t\tthis.owned.delete(scope);\n\t\tthis.instances.delete(scope);\n\t\treturn set ? [...set] : [];\n\t},\n};\n","import { caseConvert } from \"../../../_internal/case-convert/caseConvert\";\nimport { lankaLogger } from \"../../../logger/lanka-logger/LankaLogger\";\nimport { lankaVMRecipes } from \"../../../viewmodel/_internal/lanka-vm-recipes/lankaVMRecipes\";\nimport type { LankaScenarioVMRegistry } from \"../../../scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry\";\nimport type { LankaSingletonLocator } from \"../../singleton/lanka-singleton-locator/LankaSingletonLocator\";\n\n/**\n * A service lifetime other than \"as long as the application lives\".\n *\n * Everything resolved through `lankaSingletons.*` is a singleton for the life of\n * the app. Per-route, per-session and per-modal lifetimes otherwise rest on\n * discipline: every ViewModel calling `resetScenario()` and writing its own\n * `onReset`, in any of which it can be forgotten.\n *\n * A scope provides the same by construction: an object created in it goes away\n * with it, and nobody has to remember.\n *\n * ## What a scope does NOT do\n *\n * It does not shadow root objects and does not take them on close. It takes only\n * ITS OWN — the ones it created. A scope taking others' would be more dangerous\n * than no scopes at all: closing a screen would break the app.\n *\n * The same rule decides how a ViewModel becomes a scope's own: it is RESOLVED\n * in it, `resolveLankaVM(definition, { scope })`, never captured by having been\n * built while some callback ran. Those leave with the scope too — off the bus\n * and out of the registry.\n */\nexport interface ILankaScope {\n\t/** Resolves a service in this scope, creating it on first use. */\n\tresolve<TInstance>(propertyName: string): TInstance;\n\t/** Disposes everything this scope created and closes it. Idempotent. */\n\tdispose(): void;\n\t/** Whether the scope is closed. */\n\tisDisposed(): boolean;\n}\n\n/** A service may have a `dispose` — or may not. */\ninterface IMaybeDisposable {\n\tdispose?: () => void;\n}\n\nexport function createLankaScope(\n\tsingletons: LankaSingletonLocator,\n\tviewModels: LankaScenarioVMRegistry,\n): ILankaScope {\n\tconst instances = new Map<string, unknown>();\n\tlet disposed = false;\n\n\tconst scope: ILankaScope = {\n\t\tresolve<TInstance>(propertyName: string): TInstance {\n\t\t\tif (disposed) {\n\t\t\t\t// Resolving from a closed scope is almost always a reference leaked from\n\t\t\t\t// an already-unmounted screen. Silently handing out an object would\n\t\t\t\t// extend the life of what was closed, invisibly.\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The scope is closed: \"${propertyName}\" can no longer be resolved in it. ` +\n\t\t\t\t\t\t`This is usually a scope reference that outlived the screen that created it.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst className = caseConvert(propertyName, \"pascalCase\");\n\t\t\tif (instances.has(className)) return instances.get(className) as TInstance;\n\n\t\t\t// The class comes from the root locator while the OBJECT is created here:\n\t\t\t// a scope is a different lifetime, not a different set of services.\n\t\t\tconst instance = singletons.createScopedInstance(className, propertyName);\n\t\t\tinstances.set(className, instance);\n\t\t\treturn instance as TInstance;\n\t\t},\n\n\t\tdispose(): void {\n\t\t\tif (disposed) return;\n\t\t\tdisposed = true;\n\n\t\t\t// ViewModels first: a handler may still reach a service below.\n\t\t\tfor (const viewModel of lankaVMRecipes.release(scope)) {\n\t\t\t\ttry {\n\t\t\t\t\tviewModel.resetScenario();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlankaLogger.printBootstrapLog(\n\t\t\t\t\t\t\"Failed to reset a ViewModel's scenarios in the scope\",\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tviewModels.unregister(viewModel);\n\t\t\t}\n\n\t\t\tfor (const [name, instance] of instances) {\n\t\t\t\tconst disposable = instance as IMaybeDisposable;\n\t\t\t\tif (typeof disposable.dispose !== \"function\") continue;\n\t\t\t\ttry {\n\t\t\t\t\tdisposable.dispose();\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// One failure must not leave the rest alive: that is exactly what a\n\t\t\t\t\t// scope exists to prevent.\n\t\t\t\t\tlankaLogger.printBootstrapLog(\n\t\t\t\t\t\t`Failed to dispose \"${name}\" in the scope`,\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinstances.clear();\n\t\t},\n\n\t\tisDisposed: () => disposed,\n\t};\n\n\treturn scope;\n}\n"],"mappings":";;;;;;;;AAmCO,IAAM,iBAAiB;AAAA,EAC7B,SAAS,oBAAI,QAAgC;AAAA,EAC7C,WAAW,oBAAI,QAA2D;AAAA,EAC1E,OAAO,oBAAI,QAAuC;AAAA;AAAA,EAGlD,SAAS,OAA0D;AAClE,UAAM,WAAW,KAAK,UAAU,IAAI,KAAK;AAEzC,QAAI,SAAU,QAAO;AAErB,UAAM,UAAU,oBAAI,QAA0C;AAE9D,SAAK,UAAU,IAAI,OAAO,OAAO;AAEjC,WAAO;AAAA,EACR;AAAA;AAAA,EAEA,IAAI,OAAe,WAAmC;AACrD,UAAM,MAAM,KAAK,MAAM,IAAI,KAAK,KAAK,oBAAI,IAAsB;AAC/D,QAAI,IAAI,SAAS;AACjB,SAAK,MAAM,IAAI,OAAO,GAAG;AAAA,EAC1B;AAAA;AAAA,EAEA,QAAQ,OAAmC;AAC1C,UAAM,MAAM,KAAK,MAAM,IAAI,KAAK;AAChC,SAAK,MAAM,OAAO,KAAK;AACvB,SAAK,UAAU,OAAO,KAAK;AAC3B,WAAO,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC;AAAA,EAC1B;AACD;;;ACvBO,SAAS,iBACf,YACA,YACc;AACd,QAAM,YAAY,oBAAI,IAAqB;AAC3C,MAAI,WAAW;AAEf,QAAM,QAAqB;AAAA,IAC1B,QAAmB,cAAiC;AACnD,UAAI,UAAU;AAIb,cAAM,IAAI;AAAA,UACT,yBAAyB,YAAY;AAAA,QAEtC;AAAA,MACD;AAEA,YAAM,YAAY,YAAY,cAAc,YAAY;AACxD,UAAI,UAAU,IAAI,SAAS,EAAG,QAAO,UAAU,IAAI,SAAS;AAI5D,YAAM,WAAW,WAAW,qBAAqB,WAAW,YAAY;AACxE,gBAAU,IAAI,WAAW,QAAQ;AACjC,aAAO;AAAA,IACR;AAAA,IAEA,UAAgB;AACf,UAAI,SAAU;AACd,iBAAW;AAGX,iBAAW,aAAa,eAAe,QAAQ,KAAK,GAAG;AACtD,YAAI;AACH,oBAAU,cAAc;AAAA,QACzB,SAAS,OAAO;AACf,sBAAY;AAAA,YACX;AAAA,YACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UACtD;AAAA,QACD;AACA,mBAAW,WAAW,SAAS;AAAA,MAChC;AAEA,iBAAW,CAAC,MAAM,QAAQ,KAAK,WAAW;AACzC,cAAM,aAAa;AACnB,YAAI,OAAO,WAAW,YAAY,WAAY;AAC9C,YAAI;AACH,qBAAW,QAAQ;AAAA,QACpB,SAAS,OAAO;AAGf,sBAAY;AAAA,YACX,sBAAsB,IAAI;AAAA,YAC1B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,UACtD;AAAA,QACD;AAAA,MACD;AAEA,gBAAU,MAAM;AAAA,IACjB;AAAA,IAEA,YAAY,MAAM;AAAA,EACnB;AAEA,SAAO;AACR;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  requireActiveRuntime
3
- } from "./chunk-XGMXT4XZ.js";
3
+ } from "./chunk-XTVEHYIZ.js";
4
4
 
5
5
  // src/gateway/inflight/lankaHttpInFlight.ts
6
6
  function createInFlightCounter() {
@@ -36,4 +36,4 @@ export {
36
36
  createInFlightCounter,
37
37
  lankaHttpInFlight
38
38
  };
39
- //# sourceMappingURL=chunk-BHQ2SQ7P.js.map
39
+ //# sourceMappingURL=chunk-NMFNEVNE.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getActiveRuntime
3
- } from "./chunk-XGMXT4XZ.js";
3
+ } from "./chunk-XTVEHYIZ.js";
4
4
 
5
5
  // src/config/get-lanka-flags/getLankaFlags.ts
6
6
  function getLankaFlags() {
@@ -10,4 +10,4 @@ function getLankaFlags() {
10
10
  export {
11
11
  getLankaFlags
12
12
  };
13
- //# sourceMappingURL=chunk-7DQUF2QR.js.map
13
+ //# sourceMappingURL=chunk-SP5OUTWF.js.map
@@ -0,0 +1,89 @@
1
+ // src/_internal/active-runtime/lankaCopies.ts
2
+ var COPIES = /* @__PURE__ */ Symbol.for("lanka.copies");
3
+ var copies = () => {
4
+ const global = globalThis;
5
+ return global[COPIES] ??= /* @__PURE__ */ new Set();
6
+ };
7
+ var thisCopy = null;
8
+ var warned = false;
9
+ var otherCopies = () => [...copies()].filter((copy) => copy !== thisCopy);
10
+ var anotherIsRunning = () => otherCopies().some((copy) => copy() !== null);
11
+ var warnOnce = () => {
12
+ if (warned) return;
13
+ warned = true;
14
+ console.warn(
15
+ "[lanka] two copies of lanka are on this page. Each copy has its own runtime, so a scenario triggered through one never reaches a ViewModel registered with the other. If the modules on this page are meant to share state, ship ONE lanka: a singleton in Module Federation's `shared`, an import map, or `lanka` external in every module's build. If they are meant to be isolated, this is expected."
16
+ );
17
+ };
18
+ var join = (state) => {
19
+ thisCopy = state;
20
+ copies().add(state);
21
+ if (otherCopies().some((copy) => copy() === true)) warnOnce();
22
+ };
23
+ var noteActivation = (isDevelopment) => {
24
+ if (thisCopy) copies().add(thisCopy);
25
+ if (isDevelopment && anotherIsRunning()) warnOnce();
26
+ };
27
+ var lankaCopies = Object.freeze({ join, noteActivation, anotherIsRunning });
28
+
29
+ // src/_internal/active-runtime/activeRuntime.ts
30
+ var active = null;
31
+ var resolveRuntime = null;
32
+ var resolveScope = null;
33
+ var hadInstance = false;
34
+ function setActiveLankaRuntime(runtime) {
35
+ active = runtime;
36
+ if (runtime) {
37
+ hadInstance = true;
38
+ lankaCopies.noteActivation(runtime.getFlags().isDevelopment === true);
39
+ }
40
+ }
41
+ lankaCopies.join(() => active === null ? null : active.getFlags().isDevelopment === true);
42
+ function setLankaRuntimeResolver(resolver) {
43
+ resolveRuntime = resolver;
44
+ }
45
+ function getLankaProcessRuntime() {
46
+ return active;
47
+ }
48
+ function getActiveRuntime() {
49
+ return resolveRuntime ? resolveRuntime() : active;
50
+ }
51
+ function setLankaScopeResolver(resolver) {
52
+ resolveScope = resolver;
53
+ }
54
+ function hasLankaScopeResolver() {
55
+ return resolveScope !== null;
56
+ }
57
+ function getActiveLankaScope() {
58
+ return resolveScope ? resolveScope() : null;
59
+ }
60
+ var RELOADED_UNDER_AN_OPEN_PAGE = "a dev server kept this page open while lanka was upgraded or reinstalled, and a module loaded since then got the new files: reload the page";
61
+ function noInstanceMessage() {
62
+ if (resolveRuntime) {
63
+ return "lanka has no instance for this call. A runtime resolver is installed and answered with none, which on a server means the code ran outside a request scope \u2014 start one, or do this work inside it.";
64
+ }
65
+ if (lankaCopies.anotherIsRunning()) {
66
+ return `lanka used before an instance existed in THIS copy of the package, while another copy of lanka on this page has one. Either the module calling it bundled its own lanka \u2014 ship one: a singleton in Module Federation's \`shared\`, an import map, or \`lanka\` external in its build \u2014 or ${RELOADED_UNDER_AN_OPEN_PAGE}.`;
67
+ }
68
+ if (hadInstance) {
69
+ return "lanka has no instance: one was active in this copy and has been cleared \u2014 disposed, or deactivated by whatever manages instances here \u2014 and none has been activated since. Either the call outlived it (a timer, a subscription or a pending request still running after dispose), or a new one is due: createLanka({ host }) and activate it.";
70
+ }
71
+ return `lanka used before an instance existed. Call createLanka({ host }) and activate it. If that already ran on this page, it ran in another evaluation of lanka and this one started empty \u2014 most often, ${RELOADED_UNDER_AN_OPEN_PAGE}; or a module bundled a copy older than lanka 2.2.0, which does not announce itself to this one.`;
72
+ }
73
+ function requireActiveRuntime() {
74
+ const runtime = resolveRuntime ? resolveRuntime() : active;
75
+ if (!runtime) throw new Error(noInstanceMessage());
76
+ return runtime;
77
+ }
78
+
79
+ export {
80
+ setActiveLankaRuntime,
81
+ setLankaRuntimeResolver,
82
+ getLankaProcessRuntime,
83
+ getActiveRuntime,
84
+ setLankaScopeResolver,
85
+ hasLankaScopeResolver,
86
+ getActiveLankaScope,
87
+ requireActiveRuntime
88
+ };
89
+ //# sourceMappingURL=chunk-XTVEHYIZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/_internal/active-runtime/lankaCopies.ts","../src/_internal/active-runtime/activeRuntime.ts"],"sourcesContent":["/**\n * Which COPIES of the package are on this page, and whether any of them runs.\n *\n * A copy is one evaluation of this module — one bundle's `lanka`. Two instances\n * of one copy are the isolation `createLanka` promises; two copies are what a\n * build produces when separately bundled modules each carry their own `lanka`,\n * and then each copy's pointer knows only its own runtime. A scenario triggered\n * through one never reaches a ViewModel registered with the other, and nothing\n * anywhere reports it.\n *\n * The only place two copies can meet is the global object, under a name every\n * copy agrees on without importing anything: `Symbol.for`.\n *\n * Dependency-free for the same reason `activeRuntime.ts` is — it imports nothing\n * and adds no edge to the module graph. That is also what keeps hot reload from\n * reading as a second copy: an update re-evaluates the edited module and its\n * IMPORTERS, and a module that imports nothing is on no such path unless it is\n * the file being edited. A full reload starts a new global object.\n */\n\n/**\n * One copy, as the others see it: `null` while it has no runtime, otherwise\n * whether that runtime runs in development.\n */\nexport type TLankaCopyState = () => boolean | null;\n\nconst COPIES = Symbol.for(\"lanka.copies\");\n\nconst copies = (): Set<TLankaCopyState> => {\n\tconst global = globalThis as Record<symbol, Set<TLankaCopyState> | undefined>;\n\treturn (global[COPIES] ??= new Set<TLankaCopyState>());\n};\n\nlet thisCopy: TLankaCopyState | null = null;\nlet warned = false;\n\nconst otherCopies = (): TLankaCopyState[] => [...copies()].filter((copy) => copy !== thisCopy);\n\n/** Whether a copy of the package other than this one has a runtime. */\nconst anotherIsRunning = (): boolean => otherCopies().some((copy) => copy() !== null);\n\n/**\n * Once per copy, and only in development: a production page with two copies may\n * be two isolated applications on purpose, and the reader who can fix a build\n * is the one running it locally.\n */\nconst warnOnce = (): void => {\n\tif (warned) return;\n\n\twarned = true;\n\tconsole.warn(\n\t\t\"[lanka] two copies of lanka are on this page. Each copy has its own \" +\n\t\t\t\"runtime, so a scenario triggered through one never reaches a ViewModel \" +\n\t\t\t\"registered with the other. If the modules on this page are meant to share \" +\n\t\t\t\"state, ship ONE lanka: a singleton in Module Federation's `shared`, an \" +\n\t\t\t\"import map, or `lanka` external in every module's build. If they are \" +\n\t\t\t\"meant to be isolated, this is expected.\",\n\t);\n};\n\n/**\n * Puts this copy on the page's list, when the copy LOADS.\n *\n * Loading is the one moment a copy that is never started does anything the page\n * can see — and never starting is the commonest form of the accident: the shell\n * started lanka, a module bundled its own and saw no reason to. Whether to warn\n * is the RUNNING copy's call, since this one has no flags yet.\n */\nconst join = (state: TLankaCopyState): void => {\n\tthisCopy = state;\n\tcopies().add(state);\n\n\tif (otherCopies().some((copy) => copy() === true)) warnOnce();\n};\n\n/**\n * Called on every activation, which is not a hot path: `createLanka`, its\n * `bootstrap`, and one instance per request on a server.\n */\nconst noteActivation = (isDevelopment: boolean): void => {\n\t// Re-added, not assumed: whatever cleared the global list — a test between\n\t// cases — must not make a running copy invisible to the next one.\n\tif (thisCopy) copies().add(thisCopy);\n\n\tif (isDevelopment && anotherIsRunning()) warnOnce();\n};\n\n/**\n * The three questions a copy asks of the page, as one table: they share this\n * copy's identity and its one warning, so they are one subject.\n */\nexport const lankaCopies = Object.freeze({ join, noteActivation, anotherIsRunning });\n","import type { LankaEventBusInstance } from \"../../scenario/event-bus/lanka-event-bus-instance/LankaEventBusInstance\";\nimport type { LankaScenariosRegistry } from \"../../scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry\";\nimport type { LankaScenarioVMRegistry } from \"../../scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry\";\nimport type { ILankaRuntimeConfig } from \"../../config/_interfaces/ILankaRuntimeConfig\";\nimport type { ILankaInFlightCounter } from \"../../gateway/inflight/lankaHttpInFlight\";\nimport type { ILankaScenarioVM } from \"../../scenario/_interfaces/ILankaScenarioVM\";\nimport type { TLankaRequestMiddleware } from \"../../gateway/request/lankaRequestMiddleware\";\nimport type { LankaGatewayLocator } from \"../../locator/gateway/lanka-gateway-locator/LankaGatewayLocator\";\nimport type { LankaScenarioLocator } from \"../../locator/scenario/lanka-scenario-locator/LankaScenarioLocator\";\nimport type { LankaSingletonLocator } from \"../../locator/singleton/lanka-singleton-locator/LankaSingletonLocator\";\nimport type { LankaSharedStoreLocator } from \"../../locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator\";\nimport { lankaCopies } from \"./lankaCopies\";\n\n/**\n * The pointer to the framework instance that ambient facades resolve to.\n *\n * ## Why this module is separate and imports no value\n *\n * Framework state belongs to an instance (`createLanka`), but the callers of\n * `lankaEventBus.dispatch`, `getLankaFlags()`, `lankaSingletons.foo`, `lankaHttpInFlight` —\n * the ambient facades cannot hold one — a user-extended `ALankaScenario`, the\n * static `LankaScenarioBootstrap` — so they ask which instance is active.\n *\n * The module is dependency-free DELIBERATELY: every import here is `import type`\n * and disappears at compile time, except `lankaCopies`, which imports nothing\n * itself. Otherwise there would be a cycle\n * `createLanka → locator → gateway → config → createLanka`, and module\n * evaluation order would start deciding what ends up `undefined`.\n *\n * This is still a global pointer. Real isolation belongs to whoever holds an\n * instance: their own bus, registries and counter. The facades serve ONE active\n * instance — exactly what an application with one needs.\n */\nexport interface ILankaRuntime {\n\treadonly eventBus: LankaEventBusInstance;\n\treadonly scenarios: LankaScenariosRegistry;\n\treadonly viewModels: LankaScenarioVMRegistry;\n\treadonly inFlight: ILankaInFlightCounter;\n\t/**\n\t * Request wrappers, in registration order: the first wraps them all.\n\t *\n\t * An array, not a set: order carries meaning — retry must sit outside request\n\t * signing, or the second attempt goes out unsigned.\n\t */\n\treadonly requestMiddleware: readonly TLankaRequestMiddleware[];\n\t/** Default response deadline. `undefined` means no limit. */\n\treadonly requestTimeoutMs: number | undefined;\n\treadonly locators: {\n\t\treadonly gateways: LankaGatewayLocator;\n\t\treadonly scenarios: LankaScenarioLocator;\n\t\treadonly singletons: LankaSingletonLocator;\n\t\treadonly sharedStores: LankaSharedStoreLocator;\n\t};\n\treadonly config: ILankaRuntimeConfig;\n\t/**\n\t * Bootstrap state of the scenario layer.\n\t *\n\t * A mutable object rather than contract fields: `LankaScenarioBootstrap` is an\n\t * ambient facade and must write here without holding an instance.\n\t */\n\treadonly scenarioState: {\n\t\tbootstrapped: boolean;\n\t\tinitialized: WeakSet<ILankaScenarioVM>;\n\t};\n\tsetConfig(patch: ILankaRuntimeConfig): void;\n\tgetFlags(): NonNullable<ILankaRuntimeConfig[\"flags\"]>;\n}\n\n/**\n * How \"which instance is active\" is answered.\n *\n * A strategy, because the answer depends on where the code runs. In a browser\n * there is one instance per document and a module-level pointer IS the answer. In\n * a server process there is one instance per REQUEST, and a module-level pointer\n * is the bug: the last request to start would answer for all of them.\n */\nexport type TLankaRuntimeResolver = () => ILankaRuntime | null;\n\n/**\n * How \"which SCOPE is this\" is answered, which is a different question.\n *\n * `TLankaRuntimeResolver` answers which framework INSTANCE serves a call, and on\n * a server that is one per request. This answers which unit of work the call\n * belongs to, and the two are not interchangeable: `runInLankaServerScope`\n * creates its instance INSIDE the scope, and `createLanka` activates every\n * instance it builds — so the process pointer and the scope's runtime are the\n * same object during a request, and nothing downstream can tell \"inside a\n * scope\" from \"after one ended\".\n *\n * That distinction is what a per-scope lifetime needs. Without it a call made\n * outside every request resolves against the LAST request's runtime and is\n * handed the last stranger's state, which is the failure a scope exists to\n * abolish.\n *\n * Core ships no resolver here either, and knows only that the question exists.\n */\nexport type TLankaScopeResolver = () => object | null;\n\nlet active: ILankaRuntime | null = null;\nlet resolveRuntime: TLankaRuntimeResolver | null = null;\nlet resolveScope: TLankaScopeResolver | null = null;\n\n/**\n * Whether THIS copy has ever had an instance — what tells \"not yet\" from \"no\n * longer\" when a call finds none. Without it the one message named a missing\n * `createLanka` for a page that had been rendering off one for minutes.\n */\nlet hadInstance = false;\n\nexport function setActiveLankaRuntime(runtime: ILankaRuntime | null): void {\n\tactive = runtime;\n\n\tif (runtime) {\n\t\thadInstance = true;\n\t\tlankaCopies.noteActivation(runtime.getFlags().isDevelopment === true);\n\t}\n}\n\n// What another copy of the package asks this one, registered as this copy loads.\nlankaCopies.join(() => (active === null ? null : active.getFlags().isDevelopment === true));\n\n/**\n * Replaces the strategy, or restores the default one with `null`.\n *\n * The installed resolver is the WHOLE answer — the module-level pointer is not\n * consulted behind it. That is deliberate: a fallback would turn \"this ran\n * outside a request\" from a loud error into one request quietly reading another\n * request's instance, which is the failure this seam exists to make impossible.\n *\n * Core ships no resolver and knows of none. What installs one is a package that\n * knows the shape of a request; core knows only that the question has more than\n * one answer.\n */\nexport function setLankaRuntimeResolver(resolver: TLankaRuntimeResolver | null): void {\n\tresolveRuntime = resolver;\n}\n\n/**\n * The PROCESS's own instance, read without asking the strategy.\n *\n * `getActiveRuntime` consults the installed resolver and is the answer for\n * almost everything. This is the one question it cannot answer: what a call\n * would have resolved to if nobody had installed a resolver at all.\n *\n * It exists for a resolver that wants to DEFER. A server's resolver answers from\n * its request scope, and a process that also holds an ambient instance — a\n * worker with a cache, a dev server between reloads, a suite between cases —\n * has a right answer outside every scope that the resolver cannot see. Without\n * this, the first request in such a process makes every later ambient call fail\n * for the life of it.\n *\n * Not a fallback inside `getActiveRuntime`, deliberately: a resolver that wants\n * to defer says so, and one that wants a call outside its scope to fail loudly\n * goes on failing loudly. The choice belongs to whoever knows what a scope is.\n */\nexport function getLankaProcessRuntime(): ILankaRuntime | null {\n\treturn active;\n}\n\nexport function getActiveRuntime(): ILankaRuntime | null {\n\treturn resolveRuntime ? resolveRuntime() : active;\n}\n\n/**\n * Installs the strategy that says which unit of work a call belongs to.\n *\n * Installed by whoever knows what a scope IS — `@lankajs/host` wraps a request\n * in `AsyncLocalStorage` and answers from its store. A browser installs none,\n * and that is the right answer there: a tab is one scope for its whole life.\n */\nexport function setLankaScopeResolver(resolver: TLankaScopeResolver | null): void {\n\tresolveScope = resolver;\n}\n\n/** Whether anything at all knows how to answer \"which scope\". */\nexport function hasLankaScopeResolver(): boolean {\n\treturn resolveScope !== null;\n}\n\n/**\n * The current unit of work, or `null`.\n *\n * `null` means two different things and the caller has to tell them apart with\n * `hasLankaScopeResolver`: with no resolver installed there are no scopes and a\n * process-wide lifetime is correct; with one installed it means this call ran\n * OUTSIDE every scope, which on a server is a mistake worth failing on.\n */\nexport function getActiveLankaScope(): object | null {\n\treturn resolveScope ? resolveScope() : null;\n}\n\n/**\n * The same page keeping a stale evaluation of lanka beside a fresh one, which\n * is not a bundling accident: a dev server kept the page open while lanka was\n * upgraded or reinstalled, and a module loaded afterwards got the new files.\n */\nconst RELOADED_UNDER_AN_OPEN_PAGE =\n\t\"a dev server kept this page open while lanka was upgraded or reinstalled, and \" +\n\t\"a module loaded since then got the new files: reload the page\";\n\n/**\n * Why a call found no instance — four different causes, each with its own fix.\n *\n * Out of line, and only ever built on the way to a throw: the success path of\n * `requireActiveRuntime` stays exactly what it was.\n */\nfunction noInstanceMessage(): string {\n\tif (resolveRuntime) {\n\t\treturn (\n\t\t\t\"lanka has no instance for this call. A runtime resolver is installed and \" +\n\t\t\t\"answered with none, which on a server means the code ran outside a \" +\n\t\t\t\"request scope — start one, or do this work inside it.\"\n\t\t);\n\t}\n\n\tif (lankaCopies.anotherIsRunning()) {\n\t\treturn (\n\t\t\t\"lanka used before an instance existed in THIS copy of the package, while \" +\n\t\t\t\"another copy of lanka on this page has one. Either the module calling it \" +\n\t\t\t\"bundled its own lanka — ship one: a singleton in Module Federation's \" +\n\t\t\t\"`shared`, an import map, or `lanka` external in its build — or \" +\n\t\t\t`${RELOADED_UNDER_AN_OPEN_PAGE}.`\n\t\t);\n\t}\n\n\tif (hadInstance) {\n\t\treturn (\n\t\t\t\"lanka has no instance: one was active in this copy and has been cleared — \" +\n\t\t\t\"disposed, or deactivated by whatever manages instances here — and none has \" +\n\t\t\t\"been activated since. Either the call outlived it (a timer, a subscription \" +\n\t\t\t\"or a pending request still running after dispose), or a new one is due: \" +\n\t\t\t\"createLanka({ host }) and activate it.\"\n\t\t);\n\t}\n\n\t// A copy from before 2.2.0 never announces itself, so a stale one beside\n\t// this fresh one lands here rather than in the branch above.\n\treturn (\n\t\t\"lanka used before an instance existed. Call createLanka({ host }) and activate \" +\n\t\t\"it. If that already ran on this page, it ran in another evaluation of lanka \" +\n\t\t\"and this one started empty — most often, \" +\n\t\t`${RELOADED_UNDER_AN_OPEN_PAGE}; or a module bundled a copy older than lanka ` +\n\t\t\"2.2.0, which does not announce itself to this one.\"\n\t);\n}\n\n/**\n * The active instance, or a loud failure.\n *\n * No fallback, deliberately, for the same reason `getLankaHost` has none: an\n * instance created silently on the fly would mean subscriptions went to one bus\n * and events to another, and the divergence would surface three layers away.\n */\nexport function requireActiveRuntime(): ILankaRuntime {\n\t// The strategy is read here rather than through `getActiveRuntime()`: this is\n\t// the hottest path in the framework — every ambient facade, every request,\n\t// every dispatch — and a call that only forwards is a call that shows up in\n\t// `perf/`.\n\tconst runtime = resolveRuntime ? resolveRuntime() : active;\n\n\tif (!runtime) throw new Error(noInstanceMessage());\n\n\treturn runtime;\n}\n"],"mappings":";AA0BA,IAAM,SAAS,uBAAO,IAAI,cAAc;AAExC,IAAM,SAAS,MAA4B;AAC1C,QAAM,SAAS;AACf,SAAQ,OAAO,MAAM,MAAM,oBAAI,IAAqB;AACrD;AAEA,IAAI,WAAmC;AACvC,IAAI,SAAS;AAEb,IAAM,cAAc,MAAyB,CAAC,GAAG,OAAO,CAAC,EAAE,OAAO,CAAC,SAAS,SAAS,QAAQ;AAG7F,IAAM,mBAAmB,MAAe,YAAY,EAAE,KAAK,CAAC,SAAS,KAAK,MAAM,IAAI;AAOpF,IAAM,WAAW,MAAY;AAC5B,MAAI,OAAQ;AAEZ,WAAS;AACT,UAAQ;AAAA,IACP;AAAA,EAMD;AACD;AAUA,IAAM,OAAO,CAAC,UAAiC;AAC9C,aAAW;AACX,SAAO,EAAE,IAAI,KAAK;AAElB,MAAI,YAAY,EAAE,KAAK,CAAC,SAAS,KAAK,MAAM,IAAI,EAAG,UAAS;AAC7D;AAMA,IAAM,iBAAiB,CAAC,kBAAiC;AAGxD,MAAI,SAAU,QAAO,EAAE,IAAI,QAAQ;AAEnC,MAAI,iBAAiB,iBAAiB,EAAG,UAAS;AACnD;AAMO,IAAM,cAAc,OAAO,OAAO,EAAE,MAAM,gBAAgB,iBAAiB,CAAC;;;ACOnF,IAAI,SAA+B;AACnC,IAAI,iBAA+C;AACnD,IAAI,eAA2C;AAO/C,IAAI,cAAc;AAEX,SAAS,sBAAsB,SAAqC;AAC1E,WAAS;AAET,MAAI,SAAS;AACZ,kBAAc;AACd,gBAAY,eAAe,QAAQ,SAAS,EAAE,kBAAkB,IAAI;AAAA,EACrE;AACD;AAGA,YAAY,KAAK,MAAO,WAAW,OAAO,OAAO,OAAO,SAAS,EAAE,kBAAkB,IAAK;AAcnF,SAAS,wBAAwB,UAA8C;AACrF,mBAAiB;AAClB;AAoBO,SAAS,yBAA+C;AAC9D,SAAO;AACR;AAEO,SAAS,mBAAyC;AACxD,SAAO,iBAAiB,eAAe,IAAI;AAC5C;AASO,SAAS,sBAAsB,UAA4C;AACjF,iBAAe;AAChB;AAGO,SAAS,wBAAiC;AAChD,SAAO,iBAAiB;AACzB;AAUO,SAAS,sBAAqC;AACpD,SAAO,eAAe,aAAa,IAAI;AACxC;AAOA,IAAM,8BACL;AASD,SAAS,oBAA4B;AACpC,MAAI,gBAAgB;AACnB,WACC;AAAA,EAIF;AAEA,MAAI,YAAY,iBAAiB,GAAG;AACnC,WACC,uSAIG,2BAA2B;AAAA,EAEhC;AAEA,MAAI,aAAa;AAChB,WACC;AAAA,EAMF;AAIA,SACC,4MAGG,2BAA2B;AAGhC;AASO,SAAS,uBAAsC;AAKrD,QAAM,UAAU,iBAAiB,eAAe,IAAI;AAEpD,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,kBAAkB,CAAC;AAEjD,SAAO;AACR;","names":[]}
@@ -3,11 +3,11 @@ import {
3
3
  } from "../chunk-XESL274R.js";
4
4
  import {
5
5
  getLankaHost
6
- } from "../chunk-RUMUFHSL.js";
6
+ } from "../chunk-JGJBFELR.js";
7
7
  import {
8
8
  getLankaFlags
9
- } from "../chunk-7DQUF2QR.js";
10
- import "../chunk-XGMXT4XZ.js";
9
+ } from "../chunk-SP5OUTWF.js";
10
+ import "../chunk-XTVEHYIZ.js";
11
11
  export {
12
12
  createLankaHost,
13
13
  getLankaFlags,
@@ -1,5 +1,5 @@
1
- import { I as ILankaScope } from './createLankaScope-CVoV0EwO.js';
2
- import { I as ILankaRuntime } from './activeRuntime-ByucLPhj.js';
1
+ import { I as ILankaScope } from './createLankaScope-DeElRH-E.js';
2
+ import { I as ILankaRuntime } from './activeRuntime-DxB62KN4.js';
3
3
  import { a as ILankaHost, I as ILankaFlags } from './ILankaRuntimeConfig-Vl436GWK.js';
4
4
  import { T as TLankaRequestMiddleware } from './lankaRequestMiddleware-DAC5kCb7.js';
5
5
 
@@ -45,8 +45,8 @@ interface ILankaPlugin {
45
45
  *
46
46
  * **Ambient facades** — `lankaEventBus.dispatch`, `lankaSingletons.foo`,
47
47
  * `getLankaFlags()`, `lankaHttpInFlight` — resolve THE ONE active instance
48
- * (`internal/activeRuntime.ts`). Isolation belongs to whoever holds an instance;
49
- * a facade cannot offer it.
48
+ * (`_internal/active-runtime/activeRuntime.ts`). Isolation belongs to whoever
49
+ * holds an instance; a facade cannot offer it.
50
50
  *
51
51
  * One thing stays at module level deliberately: `ALankaScenario` collects
52
52
  * constructed scenarios into a static pool. That is a REGISTRY OF DEFINITIONS,
@@ -1,3 +1,4 @@
1
+ import { L as LankaScenarioVMRegistry } from './LankaScenarioVMRegistry-CFzCpIFd.js';
1
2
  import { LankaSingletonLocator } from './locator/singleton/lanka-singleton-locator/LankaSingletonLocator.js';
2
3
 
3
4
  /**
@@ -16,6 +17,11 @@ import { LankaSingletonLocator } from './locator/singleton/lanka-singleton-locat
16
17
  * It does not shadow root objects and does not take them on close. It takes only
17
18
  * ITS OWN — the ones it created. A scope taking others' would be more dangerous
18
19
  * than no scopes at all: closing a screen would break the app.
20
+ *
21
+ * The same rule decides how a ViewModel becomes a scope's own: it is RESOLVED
22
+ * in it, `resolveLankaVM(definition, { scope })`, never captured by having been
23
+ * built while some callback ran. Those leave with the scope too — off the bus
24
+ * and out of the registry.
19
25
  */
20
26
  interface ILankaScope {
21
27
  /** Resolves a service in this scope, creating it on first use. */
@@ -25,6 +31,6 @@ interface ILankaScope {
25
31
  /** Whether the scope is closed. */
26
32
  isDisposed(): boolean;
27
33
  }
28
- declare function createLankaScope(singletons: LankaSingletonLocator): ILankaScope;
34
+ declare function createLankaScope(singletons: LankaSingletonLocator, viewModels: LankaScenarioVMRegistry): ILankaScope;
29
35
 
30
36
  export { type ILankaScope as I, createLankaScope as c };
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createLankaApiError,
3
3
  handleLankaApiError
4
- } from "../chunk-O5EUTNR6.js";
4
+ } from "../chunk-DKLOCKS4.js";
5
5
  import "../chunk-J5LA3Q6D.js";
6
6
  import {
7
7
  LankaError
8
8
  } from "../chunk-G32H73QY.js";
9
- import "../chunk-RUMUFHSL.js";
10
- import "../chunk-XGMXT4XZ.js";
9
+ import "../chunk-JGJBFELR.js";
10
+ import "../chunk-XTVEHYIZ.js";
11
11
 
12
12
  // src/errors/read-lanka-field-errors/readLankaFieldErrors.ts
13
13
  var NONE = Object.freeze([]);
@@ -7,26 +7,26 @@ import {
7
7
  } from "../chunk-YR4MZXMU.js";
8
8
  import {
9
9
  lankaHttpInFlight
10
- } from "../chunk-BHQ2SQ7P.js";
10
+ } from "../chunk-NMFNEVNE.js";
11
11
  import {
12
12
  handleLankaApiError
13
- } from "../chunk-O5EUTNR6.js";
13
+ } from "../chunk-DKLOCKS4.js";
14
14
  import "../chunk-J5LA3Q6D.js";
15
15
  import {
16
16
  LankaError
17
17
  } from "../chunk-G32H73QY.js";
18
18
  import {
19
19
  getLankaHost
20
- } from "../chunk-RUMUFHSL.js";
20
+ } from "../chunk-JGJBFELR.js";
21
21
  import {
22
22
  lankaLogger
23
- } from "../chunk-FII3PW2G.js";
23
+ } from "../chunk-AMLUKB6A.js";
24
24
  import {
25
25
  getLankaFlags
26
- } from "../chunk-7DQUF2QR.js";
26
+ } from "../chunk-SP5OUTWF.js";
27
27
  import {
28
28
  getActiveRuntime
29
- } from "../chunk-XGMXT4XZ.js";
29
+ } from "../chunk-XTVEHYIZ.js";
30
30
 
31
31
  // src/gateway/request/_abstractions/lanka-request/ALankaRequest.ts
32
32
  function classifyTransportError(error, timedOut) {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { I as ILankaBootstrapConfig, a as ILankaInstance, b as ILankaInstanceConfig, c as ILankaPlugin, d as ILankaScenarioBootstrapConfig, e as ILankaServiceConfig, f as createLanka } from './createLanka-DvUGu9Hl.js';
1
+ export { I as ILankaBootstrapConfig, a as ILankaInstance, b as ILankaInstanceConfig, c as ILankaPlugin, d as ILankaScenarioBootstrapConfig, e as ILankaServiceConfig, f as createLanka } from './createLanka-AuiMfPL9.js';
2
2
  export { ALankaPlugin, ILankaStartOptions, TLankaStartConfig, resetActiveLanka, startLanka } from './bootstrap/index.js';
3
3
  export { ILankaRoleFactory, ILankaRoleOpening, TLankaRoleOpener, defineLankaRole } from './role/index.js';
4
4
  export { ILankaHostConfig, createLankaHost, getLankaFlags, getLankaHost } from './config/index.js';
@@ -6,13 +6,14 @@ export { I as ILankaFlags, a as ILankaHost, b as ILankaRuntimeConfig } from './I
6
6
  export { I as ILankaLocatorConfig } from './ALankaLocator-BUCCz0Q5.js';
7
7
  export { lankaLogger } from './logger/index.js';
8
8
  export { I as ILankaErrorInit, L as LankaError, T as TLankaErrorKind } from './LankaError-D6RWNyLM.js';
9
- import './createLankaScope-CVoV0EwO.js';
10
- import './locator/singleton/lanka-singleton-locator/LankaSingletonLocator.js';
11
- import './activeRuntime-ByucLPhj.js';
12
- import './ILankaScenario-DQd9ZfUw.js';
13
- import './LankaScenarioVMRegistry-DySAOaj2.js';
9
+ import './createLankaScope-DeElRH-E.js';
10
+ import './LankaScenarioVMRegistry-CFzCpIFd.js';
14
11
  import './ILankaScenarioVM-DKwjbIRq.js';
15
- import './ILankaScenarioMetadata-BsDp0Bzm.js';
12
+ import './locator/singleton/lanka-singleton-locator/LankaSingletonLocator.js';
13
+ import './activeRuntime-DxB62KN4.js';
14
+ import './ILankaScenario-7J3MoKiY.js';
15
+ import './LankaScenariosRegistry-DiLN9xwy.js';
16
+ import './ILankaScenarioMetadata-DgOxvpwx.js';
16
17
  import './lankaHttpInFlight-Bk1eIuSx.js';
17
18
  import './lankaRequestMiddleware-DAC5kCb7.js';
18
19
  import './locator/gateway/lanka-gateway-locator/LankaGatewayLocator.js';
package/dist/index.js CHANGED
@@ -6,33 +6,33 @@ import {
6
6
  createLanka,
7
7
  resetActiveLanka,
8
8
  startLanka
9
- } from "./chunk-SO7D5E7O.js";
10
- import "./chunk-SBITVBF7.js";
9
+ } from "./chunk-532WVMAF.js";
10
+ import "./chunk-M4BK6GBV.js";
11
11
  import "./chunk-BMF4TM2Z.js";
12
- import "./chunk-42CWYVZJ.js";
13
- import "./chunk-MKKMTLOY.js";
14
- import "./chunk-NWEHOMTS.js";
12
+ import "./chunk-EH5WZSRJ.js";
13
+ import "./chunk-24MUFFHF.js";
14
+ import "./chunk-3R2NO47A.js";
15
+ import "./chunk-JZJ6GXX3.js";
16
+ import "./chunk-N3275IPH.js";
17
+ import "./chunk-4VFVACSL.js";
18
+ import "./chunk-L27FF2IH.js";
15
19
  import {
16
20
  createLankaHost
17
21
  } from "./chunk-XESL274R.js";
18
- import "./chunk-BHQ2SQ7P.js";
22
+ import "./chunk-NMFNEVNE.js";
19
23
  import {
20
24
  LankaError
21
25
  } from "./chunk-G32H73QY.js";
22
26
  import {
23
27
  getLankaHost
24
- } from "./chunk-RUMUFHSL.js";
25
- import "./chunk-3R2NO47A.js";
26
- import "./chunk-24MUFFHF.js";
27
- import "./chunk-JZJ6GXX3.js";
28
- import "./chunk-N3275IPH.js";
28
+ } from "./chunk-JGJBFELR.js";
29
29
  import {
30
30
  lankaLogger
31
- } from "./chunk-FII3PW2G.js";
31
+ } from "./chunk-AMLUKB6A.js";
32
32
  import {
33
33
  getLankaFlags
34
- } from "./chunk-7DQUF2QR.js";
35
- import "./chunk-XGMXT4XZ.js";
34
+ } from "./chunk-SP5OUTWF.js";
35
+ import "./chunk-XTVEHYIZ.js";
36
36
  export {
37
37
  ALankaPlugin,
38
38
  LankaError,
@@ -1,121 +1,20 @@
1
- export { I as ILankaScope } from '../createLankaScope-CVoV0EwO.js';
1
+ export { I as ILankaScope } from '../createLankaScope-DeElRH-E.js';
2
2
  export { a as ILankaLocator, I as ILankaLocatorConfig } from '../ALankaLocator-BUCCz0Q5.js';
3
3
  import * as GatewaysModule from '@lanka_di/Gateways';
4
4
  import { A as ALankaGateway } from '../ALankaGateway-BrVPaZN5.js';
5
5
  import * as ScenariosModule from '@lanka_di/Scenarios';
6
6
  import * as SingletonsModule from '@lanka_di/Singletons';
7
+ export { ILankaSingletonLocatorConfig } from './singleton/lanka-singleton-locator/LankaSingletonLocator.js';
7
8
  import * as SharedStoresModule from '@lanka_di/SharedStores';
8
9
  import { A as ALankaSharedStore } from '../ALankaSharedStore-B7uepuuk.js';
9
10
  export { ILankaSharedStoreLocatorConfig } from './shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.js';
10
- export { ILankaSingletonLocatorConfig } from './singleton/lanka-singleton-locator/LankaSingletonLocator.js';
11
+ import '../LankaScenarioVMRegistry-CFzCpIFd.js';
12
+ import '../ILankaScenarioVM-DKwjbIRq.js';
11
13
  import '../lankaStandardValidator-BUFnysK0.js';
12
14
  import '@standard-schema/spec';
13
15
  import '../ILankaFieldError-D5931-vT.js';
14
16
  import 'zustand/vanilla';
15
17
 
16
- /**
17
- * The singleton marker: "this class is published by the application in
18
- * `lankaSingletons`".
19
- *
20
- * ## Why a marker when the class is exported anyway
21
- *
22
- * The other three locators have one: a gateway extends `ALankaGateway`, a
23
- * scenario has a `name`, a store extends `ALankaSharedStore`. Without a marker
24
- * the selection is "anything that is a function with a prototype", so a stray
25
- * export in the barrel — a helper, a companion class, an accidental re-export —
26
- * becomes part of the public `lankaSingletons.*`, and a typo in a name is caught
27
- * at runtime on first use, far from where it was made.
28
- *
29
- * ## A base class rather than a field
30
- *
31
- * A marker field can be put on anything, an object included, and the type would
32
- * again stop telling a class from a non-class. Inheritance also gives TypeScript
33
- * something it can select on in a mapped type.
34
- *
35
- * The class is empty deliberately: all it carries is the statement "I am meant
36
- * for the locator".
37
- */
38
- declare abstract class ALankaSingleton {
39
- /**
40
- * A runtime check, for the locator, which cannot see types.
41
- *
42
- * Looks at the prototype chain rather than the name: names are lost to
43
- * minification, and a name check would work only until the build.
44
- */
45
- static is(candidate: unknown): boolean;
46
- }
47
-
48
- /**
49
- * Singleton classes, read from the consumer's barrel.
50
- *
51
- * Adding one takes two steps and no registration:
52
- *
53
- * 1. write the class;
54
- * 2. add ONE export line to `.lanka_di/lankaSingletons.ts` at the project root.
55
- *
56
- * The type below is derived from that module's exports, so the property name
57
- * and the instance type appear by themselves.
58
- */
59
-
60
- /**
61
- * Turns a PascalCase class name into a camelCase property name: `UserProfile` → `userProfile`.
62
- */
63
- type TPascalToCamelCase$3<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
64
- /** Whether a type is a class constructor. */
65
- /**
66
- * A class marked as a singleton.
67
- *
68
- * Selecting on "is a constructor" admits anything, so a stray barrel export
69
- * silently becomes part of the public `lankaSingletons.*` and a typo is caught at
70
- * runtime on first use.
71
- */
72
- type TIsSingletonClass<T> = T extends new () => infer Instance ? Instance extends ALankaSingleton ? true : false : false;
73
- /**
74
- * Builds the singletons type from the barrel's exports.
75
- *
76
- * Derived automatically; no list has to be maintained by hand.
77
- */
78
- type TLankaSingletons = {
79
- [K in keyof typeof SingletonsModule as TIsSingletonClass<(typeof SingletonsModule)[K]> extends true ? TPascalToCamelCase$3<K & string> : never]: (typeof SingletonsModule)[K] extends new () => infer Instance ? Instance : never;
80
- };
81
-
82
- declare const lankaSingletons: TLankaSingletons;
83
-
84
- /**
85
- * Shared-store classes read from the consumer's barrel.
86
- *
87
- * Adding one takes two steps and no registration:
88
- *
89
- * 1. write a class extending `ALankaSharedStore`;
90
- * 2. add ONE export line to `.lanka_di/lankaSharedStores.ts` at the project root.
91
- *
92
- * The type below is derived from that module's exports, so the property name
93
- * and the instance type appear by themselves.
94
- */
95
-
96
- /**
97
- * Turns a PascalCase class name into a camelCase property name: `RoleEditorStore` → `roleEditorStore`.
98
- */
99
- type TPascalToCamelCase$2<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
100
- /** Whether the type is a shared-store class. */
101
- type TIsSharedStoreClass<T> = T extends new () => infer Instance ? Instance extends ALankaSharedStore<object> ? true : false : false;
102
- /**
103
- * Builds the shared-store type from every export of the barrel.
104
- *
105
- * Derived automatically; no list has to be maintained by hand.
106
- */
107
- type TLankaSharedStores = {
108
- [K in keyof typeof SharedStoresModule as TIsSharedStoreClass<(typeof SharedStoresModule)[K]> extends true ? TPascalToCamelCase$2<K & string> : never]: (typeof SharedStoresModule)[K] extends new () => infer Instance ? Instance : never;
109
- };
110
-
111
- /**
112
- * Access to every shared store at once.
113
- *
114
- * An `ALankaSharedStore` subclass appears here by itself once it is exported from
115
- * `@lanka_di/SharedStores`. The property is camelCase, the class name PascalCase.
116
- */
117
- declare const lankaSharedStores: TLankaSharedStores;
118
-
119
18
  /**
120
19
  * Gateway classes read from the consumer's barrel.
121
20
  *
@@ -131,7 +30,7 @@ declare const lankaSharedStores: TLankaSharedStores;
131
30
  /**
132
31
  * Turns a PascalCase class name into a camelCase property name: `UserGateway` → `userGateway`.
133
32
  */
134
- type TPascalToCamelCase$1<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
33
+ type TPascalToCamelCase$3<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
135
34
  /** Whether the type is a gateway class — an `ALankaGateway` subclass. */
136
35
  type TIsGatewayClass<T> = T extends new () => infer Instance ? Instance extends ALankaGateway<unknown> ? true : false : false;
137
36
  /**
@@ -140,7 +39,7 @@ type TIsGatewayClass<T> = T extends new () => infer Instance ? Instance extends
140
39
  * Derived automatically; no list has to be maintained by hand.
141
40
  */
142
41
  type TLankaGateways = {
143
- [K in keyof typeof GatewaysModule as TIsGatewayClass<(typeof GatewaysModule)[K]> extends true ? TPascalToCamelCase$1<K & string> : never]: (typeof GatewaysModule)[K] extends new () => infer Instance ? Instance : never;
42
+ [K in keyof typeof GatewaysModule as TIsGatewayClass<(typeof GatewaysModule)[K]> extends true ? TPascalToCamelCase$3<K & string> : never]: (typeof GatewaysModule)[K] extends new () => infer Instance ? Instance : never;
144
43
  };
145
44
 
146
45
  /**
@@ -173,13 +72,13 @@ declare const lankaGateways: TLankaGateways;
173
72
  /**
174
73
  * Turns a PascalCase class name into a camelCase property name: `SessionUpdated` → `sessionUpdated`.
175
74
  */
176
- type TPascalToCamelCase<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
75
+ type TPascalToCamelCase$2<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
177
76
  /** Extracts the scenario name from the constructor. */
178
77
  type TExtractScenarioName<T> = T extends new () => infer Instance ? Instance extends {
179
78
  readonly name: infer N;
180
79
  } ? N extends string ? N : never : never : never;
181
80
  /** Derives the property name from a scenario constructor. */
182
- type TScenarioPropertyName<T> = TPascalToCamelCase<TExtractScenarioName<T>>;
81
+ type TScenarioPropertyName<T> = TPascalToCamelCase$2<TExtractScenarioName<T>>;
183
82
  /** Whether the type is a scenario class — a constructor yielding a named instance. */
184
83
  type TIsScenarioClass<T> = T extends new () => infer Instance ? Instance extends {
185
84
  readonly name: string;
@@ -210,6 +109,38 @@ type TLankaScenarios = {
210
109
  */
211
110
  declare const lankaScenarios: TLankaScenarios;
212
111
 
112
+ /**
113
+ * The singleton marker: "this class is published by the application in
114
+ * `lankaSingletons`".
115
+ *
116
+ * ## Why a marker when the class is exported anyway
117
+ *
118
+ * The other three locators have one: a gateway extends `ALankaGateway`, a
119
+ * scenario has a `name`, a store extends `ALankaSharedStore`. Without a marker
120
+ * the selection is "anything that is a function with a prototype", so a stray
121
+ * export in the barrel — a helper, a companion class, an accidental re-export —
122
+ * becomes part of the public `lankaSingletons.*`, and a typo in a name is caught
123
+ * at runtime on first use, far from where it was made.
124
+ *
125
+ * ## A base class rather than a field
126
+ *
127
+ * A marker field can be put on anything, an object included, and the type would
128
+ * again stop telling a class from a non-class. Inheritance also gives TypeScript
129
+ * something it can select on in a mapped type.
130
+ *
131
+ * The class is empty deliberately: all it carries is the statement "I am meant
132
+ * for the locator".
133
+ */
134
+ declare abstract class ALankaSingleton {
135
+ /**
136
+ * A runtime check, for the locator, which cannot see types.
137
+ *
138
+ * Looks at the prototype chain rather than the name: names are lost to
139
+ * minification, and a name check would work only until the build.
140
+ */
141
+ static is(candidate: unknown): boolean;
142
+ }
143
+
213
144
  /**
214
145
  * The functional style of `ALankaSingleton`: a singleton declared by a function.
215
146
  *
@@ -234,4 +165,75 @@ declare const lankaScenarios: TLankaScenarios;
234
165
  */
235
166
  declare const createLankaSingleton: <TInstance extends object>(build: () => TInstance) => new () => TInstance;
236
167
 
168
+ /**
169
+ * Singleton classes, read from the consumer's barrel.
170
+ *
171
+ * Adding one takes two steps and no registration:
172
+ *
173
+ * 1. write the class;
174
+ * 2. add ONE export line to `.lanka_di/lankaSingletons.ts` at the project root.
175
+ *
176
+ * The type below is derived from that module's exports, so the property name
177
+ * and the instance type appear by themselves.
178
+ */
179
+
180
+ /**
181
+ * Turns a PascalCase class name into a camelCase property name: `UserProfile` → `userProfile`.
182
+ */
183
+ type TPascalToCamelCase$1<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
184
+ /** Whether a type is a class constructor. */
185
+ /**
186
+ * A class marked as a singleton.
187
+ *
188
+ * Selecting on "is a constructor" admits anything, so a stray barrel export
189
+ * silently becomes part of the public `lankaSingletons.*` and a typo is caught at
190
+ * runtime on first use.
191
+ */
192
+ type TIsSingletonClass<T> = T extends new () => infer Instance ? Instance extends ALankaSingleton ? true : false : false;
193
+ /**
194
+ * Builds the singletons type from the barrel's exports.
195
+ *
196
+ * Derived automatically; no list has to be maintained by hand.
197
+ */
198
+ type TLankaSingletons = {
199
+ [K in keyof typeof SingletonsModule as TIsSingletonClass<(typeof SingletonsModule)[K]> extends true ? TPascalToCamelCase$1<K & string> : never]: (typeof SingletonsModule)[K] extends new () => infer Instance ? Instance : never;
200
+ };
201
+
202
+ declare const lankaSingletons: TLankaSingletons;
203
+
204
+ /**
205
+ * Shared-store classes read from the consumer's barrel.
206
+ *
207
+ * Adding one takes two steps and no registration:
208
+ *
209
+ * 1. write a class extending `ALankaSharedStore`;
210
+ * 2. add ONE export line to `.lanka_di/lankaSharedStores.ts` at the project root.
211
+ *
212
+ * The type below is derived from that module's exports, so the property name
213
+ * and the instance type appear by themselves.
214
+ */
215
+
216
+ /**
217
+ * Turns a PascalCase class name into a camelCase property name: `RoleEditorStore` → `roleEditorStore`.
218
+ */
219
+ type TPascalToCamelCase<S extends string> = S extends `${infer P1}${infer P2}` ? `${Lowercase<P1>}${P2}` : S;
220
+ /** Whether the type is a shared-store class. */
221
+ type TIsSharedStoreClass<T> = T extends new () => infer Instance ? Instance extends ALankaSharedStore<object> ? true : false : false;
222
+ /**
223
+ * Builds the shared-store type from every export of the barrel.
224
+ *
225
+ * Derived automatically; no list has to be maintained by hand.
226
+ */
227
+ type TLankaSharedStores = {
228
+ [K in keyof typeof SharedStoresModule as TIsSharedStoreClass<(typeof SharedStoresModule)[K]> extends true ? TPascalToCamelCase<K & string> : never]: (typeof SharedStoresModule)[K] extends new () => infer Instance ? Instance : never;
229
+ };
230
+
231
+ /**
232
+ * Access to every shared store at once.
233
+ *
234
+ * An `ALankaSharedStore` subclass appears here by itself once it is exported from
235
+ * `@lanka_di/SharedStores`. The property is camelCase, the class name PascalCase.
236
+ */
237
+ declare const lankaSharedStores: TLankaSharedStores;
238
+
237
239
  export { ALankaSingleton, type TLankaGateways, type TLankaScenarios, type TLankaSharedStores, type TLankaSingletons, createLankaSingleton, lankaGateways, lankaScenarios, lankaSharedStores, lankaSingletons };