lanka 1.0.0 → 1.0.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.
- package/dist/{LankaScenarioLocator-BGQHwf3n.d.ts → LankaScenarioLocator-CLkq4MaJ.d.ts} +1 -1
- package/dist/{LankaSharedStoreLocator-MvCpav5F.d.ts → LankaSharedStoreLocator-zS2kLu-S.d.ts} +21 -0
- package/dist/_extend/index.d.ts +4 -4
- package/dist/_extend/index.js +3 -3
- package/dist/_internal/index.d.ts +3 -3
- package/dist/{activeRuntime-FcsSJvUg.d.ts → activeRuntime-DT4gB16d.d.ts} +2 -2
- package/dist/bootstrap/index.d.ts +4 -4
- package/dist/bootstrap/index.js +5 -5
- package/dist/{chunk-RYFZCAQ3.js → chunk-63ST2UKP.js} +12 -12
- package/dist/chunk-63ST2UKP.js.map +1 -0
- package/dist/{chunk-Q3SOVBIJ.js → chunk-HZAIAGWS.js} +4 -4
- package/dist/{chunk-Q3SOVBIJ.js.map → chunk-HZAIAGWS.js.map} +1 -1
- package/dist/{chunk-FIR4XTBL.js → chunk-MYZQYOMD.js} +10 -12
- package/dist/chunk-MYZQYOMD.js.map +1 -0
- package/dist/{chunk-ILQNYQY5.js → chunk-UE2C76OR.js} +32 -18
- package/dist/chunk-UE2C76OR.js.map +1 -0
- package/dist/{chunk-EWVDJYCC.js → chunk-YXI4OQEV.js} +2 -6
- package/dist/chunk-YXI4OQEV.js.map +1 -0
- package/dist/{createLankaScope-Bc_vChRs.d.ts → createLankaScope-BiFxNQgl.d.ts} +1 -1
- package/dist/gateway/index.js +1 -2
- package/dist/gateway/index.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/locator/index.d.ts +6 -54
- package/dist/locator/index.js +1 -1
- package/dist/scenario/index.js +2 -2
- package/dist/viewmodel/index.js +4 -2
- package/dist/viewmodel/index.js.map +1 -1
- package/package.json +2 -2
- package/skills/lanka-core/SKILL.md +1 -1
- package/skills/lanka-core/reference.md +1 -1
- package/skills/lanka-packages/SKILL.md +1 -1
- package/dist/chunk-EWVDJYCC.js.map +0 -1
- package/dist/chunk-FIR4XTBL.js.map +0 -1
- package/dist/chunk-ILQNYQY5.js.map +0 -1
- package/dist/chunk-RYFZCAQ3.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/_internal/case-convert/caseConvert.ts","../src/locator/_abstractions/lanka-locator/ALankaLocator.ts","../src/locator/_internal/find-exported-class/findExportedClass.ts","../src/locator/singleton/lanka-singleton-locator/LankaSingletonLocator.ts","../src/locator/shared-store/lanka-shared-store-locator/LankaSharedStoreLocator.ts"],"sourcesContent":["export function caseConvert(\n\tstr: string,\n\ttoCase: \"camelCase\" | \"kebabCase\" | \"snakeCase\" | \"pascalCase\" | \"titleCase\",\n): string {\n\tif (!str || typeof str !== \"string\") return str;\n\n\tconst words = str\n\t\t.replace(/([A-Z])/g, \" $1\")\n\t\t.trim()\n\t\t.split(/\\s+|_|-/)\n\t\t.filter((word) => word);\n\n\tswitch (toCase) {\n\t\tcase \"camelCase\":\n\t\t\treturn words\n\t\t\t\t.map((word, index) =>\n\t\t\t\t\tindex === 0\n\t\t\t\t\t\t? word.toLowerCase()\n\t\t\t\t\t\t: word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(),\n\t\t\t\t)\n\t\t\t\t.join(\"\");\n\t\tcase \"kebabCase\":\n\t\t\treturn words.map((word) => word.toLowerCase()).join(\"-\");\n\t\tcase \"snakeCase\":\n\t\t\treturn words.map((word) => word.toLowerCase()).join(\"_\");\n\t\tcase \"pascalCase\":\n\t\t\treturn words\n\t\t\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n\t\t\t\t.join(\"\");\n\t\tcase \"titleCase\":\n\t\t\treturn words\n\t\t\t\t.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n\t\t\t\t.join(\" \");\n\t\tdefault:\n\t\t\treturn str;\n\t}\n}\n","import type { ILankaLocator } from \"../../_interfaces/ILankaLocator\";\nimport { caseConvert } from \"../../../_internal/case-convert/caseConvert\";\n\n/**\n * Base locator configuration.\n */\nexport interface ILankaLocatorConfig<TInstance> {\n\t/** How to find a constructor by class name. */\n\tfindClassByName: (name: string) => (new () => TInstance) | undefined;\n\t/** How to create an object from a constructor. */\n\tcreateInstance?: (Class: new () => TInstance) => TInstance;\n\t/** Custom resolution by name, when the ordinary one is not enough. */\n\tgetInstanceByName?: (name: string) => TInstance | undefined;\n\t/** What to say when there is no such object. */\n\tnotFoundError?: (name: string, propertyName: string) => string;\n}\n\n/**\n * The locator base: resolves objects by property name (camelCase), translating\n * it into a class name (PascalCase).\n *\n * Handles what every locator shares — name translation, construction on first\n * use from the barrel's exports, and caching what was constructed.\n */\nexport abstract class ALankaLocator<TInstance> implements ILankaLocator<TInstance> {\n\tprotected readonly instanceCache: Map<string, TInstance> = new Map();\n\tprotected readonly registeredClasses: Map<string, new () => TInstance> = new Map();\n\tprotected readonly registeredInstances: Map<string, TInstance> = new Map();\n\tprotected readonly config: ILankaLocatorConfig<TInstance> & {\n\t\tcreateInstance: (Class: new () => TInstance) => TInstance;\n\t\tnotFoundError: (name: string, propertyName: string) => string;\n\t};\n\n\tprotected constructor(config: ILankaLocatorConfig<TInstance>) {\n\t\t// The defaults are applied AFTER the spread, so an explicit `undefined` —\n\t\t// which a caller forwarding its own optional config passes — falls back\n\t\t// instead of removing the only thing that can construct an instance.\n\t\tthis.config = {\n\t\t\t...config,\n\t\t\tcreateInstance: config.createInstance ?? ((Class) => new Class()),\n\t\t\tnotFoundError:\n\t\t\t\tconfig.notFoundError ??\n\t\t\t\t((name, propertyName) =>\n\t\t\t\t\t`Instance \"${name}\" (accessed as \"${propertyName}\") not found.`),\n\t\t};\n\t}\n\n\t/**\n\t * The class a name resolves to: hand-registered FIRST, then the consumer's\n\t * barrel.\n\t *\n\t * One owner for both callers, and that is the whole point of it existing.\n\t * `registeredClasses` used to be read inside each locator's own\n\t * `findClassByName`, and only two of the four did it — singletons and shared\n\t * stores worked, gateways and scenarios silently dropped the class. Moving the\n\t * read into `getInstanceByName` fixed those two and broke a third path:\n\t * `LankaSingletonLocator.createScopedInstance` calls `findClassByName`\n\t * directly, so a registered class stopped resolving inside a scope. Ten tests\n\t * said so.\n\t *\n\t * Both callers go through here now. A fourth caller added later gets the\n\t * precedence for free instead of having to remember it.\n\t *\n\t * The precedence itself matches `registeredInstances` below: what a caller\n\t * handed over wins over what the barrel happens to export under that name,\n\t * because the caller is usually a test substituting a double.\n\t */\n\tprotected classFor(instanceName: string): (new () => TInstance) | undefined {\n\t\treturn (\n\t\t\tthis.registeredClasses.get(instanceName) ?? this.config.findClassByName(instanceName)\n\t\t);\n\t}\n\n\t/**\n\t * An object by class name.\n\t *\n\t * The cache first, then custom resolution when configured, and only then\n\t * construction.\n\t */\n\tprotected getInstanceByName(instanceName: string): TInstance | undefined {\n\t\tif (this.instanceCache.has(instanceName)) {\n\t\t\treturn this.instanceCache.get(instanceName);\n\t\t}\n\n\t\t// What was handed to us already built. Ahead of the barrel, and ahead of\n\t\t// custom resolution: a test's double must win over what the barrel exports.\n\t\tif (this.registeredInstances.has(instanceName)) {\n\t\t\treturn this.registeredInstances.get(instanceName);\n\t\t}\n\n\t\t// Custom resolution when configured.\n\t\tif (this.config.getInstanceByName) {\n\t\t\tconst instance = this.config.getInstanceByName(instanceName);\n\t\t\tif (instance) {\n\t\t\t\tthis.instanceCache.set(instanceName, instance);\n\t\t\t\treturn instance;\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise find the class and construct.\n\t\tconst Class = this.classFor(instanceName);\n\t\tif (Class) {\n\t\t\tconst instance = this.config.createInstance(Class);\n\t\t\tthis.instanceCache.set(instanceName, instance);\n\t\t\treturn instance;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * An object by property name (camelCase).\n\t *\n\t * Throws when there is none: a silent `undefined` would surface layers later.\n\t */\n\tpublic get(propertyName: string): TInstance {\n\t\tconst instanceName = caseConvert(propertyName, \"pascalCase\");\n\t\tconst instance = this.getInstanceByName(instanceName);\n\n\t\tif (!instance) {\n\t\t\tthrow new Error(this.config.notFoundError(instanceName, propertyName));\n\t\t}\n\n\t\treturn instance;\n\t}\n\n\t/**\n\t * Clears the instance cache. Required by tests.\n\t */\n\tpublic clearCache(): void {\n\t\tthis.instanceCache.clear();\n\t}\n\n\t// ── Registration by hand ─────────────────────────────────────────────────\n\t//\n\t// Every locator needs it, for the same two reasons: a test supplies a double,\n\t// and an application supplies an object it built itself. It lives here rather\n\t// than in each locator because three copies of four one-line methods are three\n\t// places for the cache invalidation to be forgotten.\n\n\t/**\n\t * Registers a class by hand, ahead of the consumer's barrel.\n\t *\n\t * The cache entry is dropped: what it holds was built from the previous class.\n\t */\n\tpublic register(className: string, Class: new () => TInstance): void {\n\t\tthis.registeredClasses.set(className, Class);\n\t\tthis.instanceCache.delete(className);\n\t}\n\n\t/**\n\t * Registers an already-built object by hand.\n\t *\n\t * It goes straight into the cache: there is nothing left to construct, and a\n\t * later lookup must not build a rival.\n\t */\n\tpublic registerInstance(className: string, instance: TInstance): void {\n\t\tthis.registeredInstances.set(className, instance);\n\t\tthis.instanceCache.set(className, instance);\n\t}\n\n\t/** Removes a class or object registered by hand, and what was built from it. */\n\tpublic unregister(className: string): void {\n\t\tthis.registeredClasses.delete(className);\n\t\tthis.registeredInstances.delete(className);\n\t\tthis.instanceCache.delete(className);\n\t}\n\n\t/** Whether this name resolves to anything the locator already holds. */\n\tpublic isRegistered(className: string): boolean {\n\t\treturn (\n\t\t\tthis.registeredClasses.has(className) ||\n\t\t\tthis.registeredInstances.has(className) ||\n\t\t\tthis.instanceCache.has(className)\n\t\t);\n\t}\n}\n","/**\n * Finds a class in a module's ES namespace by name.\n *\n * An ES namespace is an ordinary object and `module[name]` is enough. Walking\n * `Reflect.ownKeys`, reading property descriptors and wrapping field access in\n * `try/catch` guards against what does not happen.\n *\n * ## Why a fallback pass over `Class.name` is worse than useless\n *\n * It is written for the case where the export name was lost to minification. But\n * `Class.name`.\n *\n * minification loses `Class.name` too — so the fallback looks for something a\n * built bundle no longer has, creating an impression of protection where there\n * is none.\n *\n * Resolution still works when the export name differs from the class name, which\n * `locator.contract.test.ts` pins: the lookup is by EXPORT KEY, and that is what\n * the consumer writes in the barrel.\n */\nexport function findExportedClass<TInstance>(\n\tmodule: object,\n\texportName: string,\n): (new () => TInstance) | undefined {\n\t// `in` first, then indexing. An ES namespace answers `undefined` for a missing\n\t// key, but a mocked module does not: vitest returns a proxy that THROWS on an\n\t// unknown key.\n\tif (!(exportName in module)) return undefined;\n\n\t// OWN properties only, and `in` alone was not enough. It walks the prototype\n\t// chain, so `\"constructor\" in module` is true for any plain object and\n\t// `module.constructor` is `Object` — a function WITH a prototype, which both\n\t// checks below accept. The locator would have handed back a class the barrel\n\t// never exported. `toString` and its siblings only escaped by luck: built-in\n\t// methods have no `.prototype`.\n\t//\n\t// It is asked SECOND, never first: `in` is what tolerates a vitest module\n\t// proxy, and this narrowing is only ever consulted for a key that already\n\t// exists. A real ES namespace has a null prototype, so nothing changes there.\n\tif (!Object.hasOwn(module, exportName)) return undefined;\n\n\tconst candidate = (module as Record<string, unknown>)[exportName];\n\n\t// `typeof === \"function\"` would also admit a plain function: it has a\n\t// `prototype` too. They cannot be told apart before calling, and that is a\n\t// deliberate boundary — the locator trusts the barrel, and `@lankajs/tool-di`\n\t// verifies the barrel.\n\treturn typeof candidate === \"function\" && candidate.prototype\n\t\t? (candidate as new () => TInstance)\n\t\t: undefined;\n}\n","import { ALankaLocator } from \"../../_abstractions/lanka-locator/ALankaLocator\";\nimport { findExportedClass } from \"../../_internal/find-exported-class/findExportedClass\";\n/**\n * Classes come from the consumer's barrel.\n *\n * Adding one is ONE export line: types are inferred, autocomplete works, and no\n * list has to be maintained. A list maintained by hand is a list that eventually\n * falls behind the code.\n */\nimport * as SingletonsModule from \"@lanka_di/Singletons\";\n\n/**\n * LankaSingletonLocator configuration.\n */\nexport interface ILankaSingletonLocatorConfig {\n\t/** The module holding singleton classes — the consumer's barrel. */\n\tsingletonIndexModule?: Record<string, unknown>;\n}\n\n/**\n * Resolves singletons by property name (camelCase) or class name (PascalCase),\n * constructing them on first use and caching them.\n *\n * A class arrives either from the consumer's barrel or registered by hand — the\n * latter for tests and for objects that arrive already built.\n */\nexport class LankaSingletonLocator extends ALankaLocator<unknown> {\n\tprivate readonly singletonIndexModule?: Record<string, unknown>;\n\n\tconstructor(config?: ILankaSingletonLocatorConfig) {\n\t\tsuper({\n\t\t\tfindClassByName: (className: string) => {\n\t\t\t\t// Order: the application's barrel, then an extra module if one was\n\t\t\t\t// given. Hand-registered classes are read by `ALankaLocator` itself,\n\t\t\t\t// ahead of this callback — they used to be read here, and the copy is\n\t\t\t\t// what let the gateway and scenario locators forget them entirely.\n\t\t\t\t//\n\t\t\t\t// Each source is checked ONCE, by export key. A fallback pass over\n\t\t\t\t// `Class.name` looks for something a built bundle no longer has:\n\t\t\t\t// minification loses class names exactly as it loses export names.\n\t\t\t\treturn (\n\t\t\t\t\tfindExportedClass<unknown>(SingletonsModule, className) ??\n\t\t\t\t\t(this.singletonIndexModule\n\t\t\t\t\t\t? findExportedClass<unknown>(this.singletonIndexModule, className)\n\t\t\t\t\t\t: undefined)\n\t\t\t\t);\n\t\t\t},\n\t\t\tcreateInstance: (Class) => {\n\t\t\t\treturn new Class();\n\t\t\t},\n\t\t\tnotFoundError: (className, propertyName) =>\n\t\t\t\t`Singleton \"${className}\" (accessed as \"${propertyName}\") not found. ` +\n\t\t\t\t`Make sure the class is exported from @lanka_di/Singletons.ts or registered via registerSingleton method.`,\n\t\t});\n\n\t\tthis.singletonIndexModule = config?.singletonIndexModule;\n\t}\n\n\t/**\n\t * Creates a NEW service object, bypassing the locator's cache.\n\t *\n\t * For scopes: they take the class from here and set the lifetime themselves.\n\t * The root cache is untouched — otherwise the first resolution inside a scope\n\t * would replace the application's root object.\n\t */\n\tpublic createScopedInstance(className: string, propertyName: string): unknown {\n\t\t// `classFor`, not `config.findClassByName`: a hand-registered class must\n\t\t// resolve inside a scope exactly as it does at the root.\n\t\tconst Class = this.classFor(className);\n\t\tif (!Class) {\n\t\t\tthrow new Error(this.config.notFoundError(className, propertyName));\n\t\t}\n\t\treturn this.config.createInstance(Class);\n\t}\n}\n","import { ALankaLocator } from \"../../_abstractions/lanka-locator/ALankaLocator\";\nimport { findExportedClass } from \"../../_internal/find-exported-class/findExportedClass\";\nimport { ALankaSharedStore } from \"../../../viewmodel/_abstractions/lanka-shared-store/ALankaSharedStore\";\nimport * as SharedStoresModule from \"@lanka_di/SharedStores\";\n\ntype TSharedStoreState = object;\n\n/**\n * LankaSharedStoreLocator configuration.\n */\nexport interface ILankaSharedStoreLocatorConfig {\n\t/** The module holding shared store classes — the consumer's barrel. */\n\tsharedStoreIndexModule?: Record<string, unknown>;\n}\n\n/**\n * Resolves shared stores by property name (camelCase) or class name\n * (PascalCase), constructing them on first use and caching them.\n */\nexport class LankaSharedStoreLocator extends ALankaLocator<ALankaSharedStore<TSharedStoreState>> {\n\tprivate readonly sharedStoreIndexModule?: Record<string, unknown>;\n\n\tconstructor(config?: ILankaSharedStoreLocatorConfig) {\n\t\tsuper({\n\t\t\tfindClassByName: (className: string) => {\n\t\t\t\t// Hand-registered classes are read by `ALankaLocator` itself, ahead of\n\t\t\t\t// this callback. This is only the barrel.\n\t\t\t\treturn (\n\t\t\t\t\tfindExportedClass<ALankaSharedStore<TSharedStoreState>>(\n\t\t\t\t\t\tSharedStoresModule,\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t) ??\n\t\t\t\t\t(this.sharedStoreIndexModule\n\t\t\t\t\t\t? findExportedClass<ALankaSharedStore<TSharedStoreState>>(\n\t\t\t\t\t\t\t\tthis.sharedStoreIndexModule,\n\t\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: undefined)\n\t\t\t\t);\n\t\t\t},\n\t\t\tcreateInstance: (Class) => {\n\t\t\t\treturn new Class();\n\t\t\t},\n\t\t\tnotFoundError: (className, propertyName) =>\n\t\t\t\t`SharedStore \"${className}\" (accessed as \"${propertyName}\") not found. ` +\n\t\t\t\t`Make sure the class extends ALankaSharedStore and is exported from @lanka_di/SharedStores.ts ` +\n\t\t\t\t`or registered via registerSharedStore method.`,\n\t\t});\n\n\t\tthis.sharedStoreIndexModule = config?.sharedStoreIndexModule;\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -283,14 +283,10 @@ var ALankaScenario = class _ALankaScenario {
|
|
|
283
283
|
}
|
|
284
284
|
};
|
|
285
285
|
|
|
286
|
-
// ../tools/testing/_fixtures/.lanka_di/Scenarios.ts
|
|
287
|
-
var Scenarios_exports = {};
|
|
288
|
-
|
|
289
286
|
export {
|
|
290
287
|
lankaEventBus,
|
|
291
288
|
ALankaScenario,
|
|
292
289
|
LankaScenarioVMRegistry,
|
|
293
|
-
LankaScenariosRegistry
|
|
294
|
-
Scenarios_exports
|
|
290
|
+
LankaScenariosRegistry
|
|
295
291
|
};
|
|
296
|
-
//# sourceMappingURL=chunk-
|
|
292
|
+
//# sourceMappingURL=chunk-YXI4OQEV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scenario/event-bus/_facades/lanka-event-bus/lankaEventBus.ts","../src/scenario/_registries/lanka-scenario-vm-registry/LankaScenarioVMRegistry.ts","../src/scenario/_registries/lanka-scenarios-registry/LankaScenariosRegistry.ts","../src/scenario/_abstractions/lanka-scenario/ALankaScenario.ts"],"sourcesContent":["import { requireActiveRuntime } from \"../../../../_internal/active-runtime/activeRuntime\";\nimport type { ILankaEventLog } from \"../../../_interfaces/ILankaEventLog\";\nimport type { ILankaEventMetadata } from \"../../../_interfaces/ILankaEventMetadata\";\nimport type { TLankaEventBusMiddleware } from \"../../../_types/TLankaEventBusMiddleware\";\nimport type { LankaEventBusInstance } from \"../../lanka-event-bus-instance/LankaEventBusInstance\";\nimport type { TLankaReplayRequest } from \"../../lanka-event-bus-instance/LankaEventBusInstance\";\n\n/**\n * Ambient bus: the active instance's, reachable without holding it.\n *\n * Every member is one line of delegation and that is all this does. It exists\n * for callers that cannot hold an instance — a user-extended `ALankaScenario`,\n * the scenario bootstrap.\n *\n * An object rather than a class with a default instance, and the difference is\n * not cosmetic: this owns no state, so a second one would delegate to the same\n * runtime and be the same object under another name. Where an ambient DOES own\n * state — storage — the class is real and a second instance means something.\n *\n * Isolation belongs to the instance holder: `lanka.eventBus.dispatch(…)`. This\n * cannot offer it — by definition it serves the ONE active instance, so two\n * instances in one process share nothing through it.\n */\nconst bus = (): LankaEventBusInstance => requireActiveRuntime().eventBus;\n\nexport const lankaEventBus = Object.freeze({\n\tenableLogs: (): void => {\n\t\tbus().enableLogs();\n\t},\n\n\tdisableLogs: (): void => {\n\t\tbus().disableLogs();\n\t},\n\n\tregisterEvent: (eventType: string, metadata: ILankaEventMetadata): void => {\n\t\tbus().registerEvent(eventType, metadata);\n\t},\n\n\tgetRegisteredEvents: () => bus().getRegisteredEvents(),\n\n\tgetEventInfo: (eventType: string): ILankaEventMetadata | null => bus().getEventInfo(eventType),\n\n\tgetSubscriptions: (eventType: string): number => bus().getSubscriptions(eventType),\n\n\tsubscribe: <T>(\n\t\teventType: string,\n\t\tcallback: (data: T) => void,\n\t\toptions?: { priority?: number; replay?: TLankaReplayRequest; usedBy?: string },\n\t): (() => void) => bus().subscribe(eventType, callback, options),\n\n\tunsubscribe: <T>(eventType: string, callback: (data: T) => void): void => {\n\t\tbus().unsubscribe(eventType, callback);\n\t},\n\n\tdispatch: <T>(eventType: string, data?: T, usedBy?: string): void => {\n\t\tbus().dispatch(eventType, data, usedBy);\n\t},\n\n\taddMiddleware: <T>(middleware: TLankaEventBusMiddleware<T>): void => {\n\t\tbus().addMiddleware(middleware);\n\t},\n\n\tremoveMiddleware: <T>(middleware: TLankaEventBusMiddleware<T>): void => {\n\t\tbus().removeMiddleware(middleware);\n\t},\n\n\tgetEventLogs: (eventType?: string, limit = 100): ILankaEventLog[] =>\n\t\tbus().getEventLogs(eventType, limit),\n\n\tclearEvent: (eventType: string): void => {\n\t\tbus().clearEvent(eventType);\n\t},\n\n\tclearAllEvents: (): void => {\n\t\tbus().clearAllEvents();\n\t},\n\n\treset: (): void => {\n\t\tbus().reset();\n\t},\n});\n","import { requireActiveRuntime } from \"../../../_internal/active-runtime/activeRuntime\";\nimport { ILankaScenarioVM } from \"../../_interfaces/ILankaScenarioVM\";\n\n/**\n * The registry of ViewModels that use scenarios.\n *\n * They arrive by themselves: the factory registers a ViewModel when it declares\n * scenario handlers.\n */\nexport class LankaScenarioVMRegistry {\n\tprivate registeredViewModels: Set<ILankaScenarioVM> = new Set();\n\n\t/**\n\t * Public: the registry belongs to a framework instance rather than to the\n\t * module.\n\t */\n\tpublic constructor() {}\n\n\t/**\n\t * The active instance's registry, for callers that cannot hold one — the\n\t * static `LankaScenarioBootstrap`. Instance holders read `lanka.viewModels`.\n\t */\n\tpublic static getInstance(): LankaScenarioVMRegistry {\n\t\treturn requireActiveRuntime().viewModels;\n\t}\n\n\t/** Whether this ViewModel is already registered. */\n\tpublic isRegistered(viewModel: ILankaScenarioVM): boolean {\n\t\treturn this.registeredViewModels.has(viewModel);\n\t}\n\n\t/**\n\t * Registers a ViewModel.\n\t *\n\t * @returns `false` when it was already registered\n\t */\n\tpublic register(viewModel: ILankaScenarioVM): boolean {\n\t\tif (this.registeredViewModels.has(viewModel)) {\n\t\t\treturn false;\n\t\t}\n\t\tthis.registeredViewModels.add(viewModel);\n\t\treturn true;\n\t}\n\n\t/** Removes a ViewModel from the registry. */\n\tpublic unregister(viewModel: ILankaScenarioVM): void {\n\t\tthis.registeredViewModels.delete(viewModel);\n\t}\n\n\t/** Every registered ViewModel. */\n\tpublic getAllViewModels(): ILankaScenarioVM[] {\n\t\treturn Array.from(this.registeredViewModels);\n\t}\n\n\t/**\n\t * Clears every registered ViewModel. Required by tests.\n\t */\n\tpublic clear(): void {\n\t\tthis.registeredViewModels.clear();\n\t}\n\n\t/**\n\t * Unsubscribes every registered ViewModel from its scenarios and clears the\n\t * registry.\n\t *\n\t * Without it tests are not isolated: a subscription leaks from test to test.\n\t */\n\tpublic resetAll(): void {\n\t\tthis.registeredViewModels.forEach((vm) => {\n\t\t\ttry {\n\t\t\t\tvm.resetScenario();\n\t\t\t} catch {\n\t\t\t\t// One failing to reset is no reason to fail the rest.\n\t\t\t}\n\t\t});\n\t\tthis.clear();\n\t}\n}\n","import { requireActiveRuntime } from \"../../../_internal/active-runtime/activeRuntime\";\nimport { ILankaScenario } from \"../../_interfaces/ILankaScenario\";\nimport { ALankaScenario } from \"../../_abstractions/lanka-scenario/ALankaScenario\";\nimport { ILankaScenarioVM } from \"../../_interfaces/ILankaScenarioVM\";\nimport { LankaScenarioVMRegistry } from \"../lanka-scenario-vm-registry/LankaScenarioVMRegistry\";\nimport type { ILankaScenarioMetadata } from \"../../_interfaces/ILankaScenarioMetadata\";\n\n/**\n * The scenario registry: both those that registered themselves and those\n * registered by hand.\n *\n * `ALankaScenario` subclasses arrive here automatically unless they opted out.\n */\nexport class LankaScenariosRegistry {\n\tprivate registeredScenarios: Map<string, ILankaScenario<unknown>> = new Map();\n\tprivate scenarioMetadata: Map<string, ILankaScenarioMetadata> = new Map();\n\n\t/**\n\t * Public: the registry belongs to a framework instance rather than to the\n\t * module.\n\t */\n\tpublic constructor() {}\n\n\t/**\n\t * The active instance's registry, for callers that cannot hold one:\n\t * `ALankaScenario` (a base class the consumer extends) and the static\n\t * `LankaScenarioBootstrap`. Instance holders read `lanka.scenarios`.\n\t */\n\tpublic static getInstance(): LankaScenariosRegistry {\n\t\treturn requireActiveRuntime().scenarios;\n\t}\n\n\t/**\n\t * Registers a scenario by hand.\n\t *\n\t * @param scenario What to register\n\t * @returns `false` when it was already registered\n\t */\n\tpublic register(scenario: ILankaScenario<unknown>): boolean {\n\t\tif (this.registeredScenarios.has(scenario.name)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.registeredScenarios.set(scenario.name, scenario);\n\t\tthis.scenarioMetadata.set(scenario.name, {\n\t\t\tscenario,\n\t\t\tname: scenario.name,\n\t\t\teventType: scenario.eventType,\n\t\t\tdataTypeName: scenario.dataTypeName,\n\t\t\tisRegistered: true,\n\t\t});\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Unregister a scenario\n\t * @param scenarioName Name of the scenario to unregister\n\t * @returns true if unregistered successfully, false if not found\n\t */\n\tpublic unregister(scenarioName: string): boolean {\n\t\tif (!this.registeredScenarios.has(scenarioName)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst metadata = this.scenarioMetadata.get(scenarioName);\n\t\tif (metadata) {\n\t\t\tmetadata.isRegistered = false;\n\t\t}\n\n\t\tthis.registeredScenarios.delete(scenarioName);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get metadata for a specific scenario\n\t * @param scenarioName Name of the scenario\n\t * @returns Scenario metadata or undefined if not found\n\t */\n\tpublic getMetadata(scenarioName: string): ILankaScenarioMetadata | undefined {\n\t\treturn this.scenarioMetadata.get(scenarioName);\n\t}\n\n\t/** Every registered scenario. */\n\tpublic getAllScenarios(): ILankaScenario<unknown>[] {\n\t\treturn Array.from(this.registeredScenarios.values());\n\t}\n\n\t/** Metadata of every scenario. */\n\tpublic getAllMetadata(): ILankaScenarioMetadata[] {\n\t\treturn Array.from(this.scenarioMetadata.values());\n\t}\n\n\t/** Whether a scenario with this name is registered. */\n\tpublic isRegistered(scenarioName: string): boolean {\n\t\treturn this.registeredScenarios.has(scenarioName);\n\t}\n\n\t/**\n\t * Collects every scenario that registered itself at construction.\n\t */\n\tpublic collectAutoRegisteredScenarios(): void {\n\t\t// Take those that registered themselves at construction.\n\t\tconst autoRegistered = ALankaScenario.getAutoRegisteredScenarios();\n\t\tautoRegistered.forEach((scenario) => {\n\t\t\tif (!this.registeredScenarios.has(scenario.name)) {\n\t\t\t\tthis.register(scenario);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * A scenario by name.\n\t *\n\t * @returns `undefined` when there is none\n\t */\n\tpublic getScenarioByName(scenarioName: string): ILankaScenario<unknown> | undefined {\n\t\treturn this.registeredScenarios.get(scenarioName);\n\t}\n\n\t/** Every registered ViewModel. */\n\tpublic getAllViewModels(): ILankaScenarioVM[] {\n\t\treturn LankaScenarioVMRegistry.getInstance().getAllViewModels();\n\t}\n\n\t/**\n\t * Clears every registered scenario. Required by tests.\n\t */\n\tpublic clear(): void {\n\t\tthis.registeredScenarios.clear();\n\t\tthis.scenarioMetadata.clear();\n\t}\n}\n","import type { TLankaReplayRequest } from \"../../event-bus/lanka-event-bus-instance/LankaEventBusInstance\";\nimport { ILankaScenario } from \"../../_interfaces/ILankaScenario\";\nimport { LankaScenariosRegistry } from \"../../_registries/lanka-scenarios-registry/LankaScenariosRegistry\";\nimport { lankaLogger } from \"../../../logger/lanka-logger/LankaLogger\";\nimport { lankaEventBus } from \"../../event-bus/_facades/lanka-event-bus/lankaEventBus\";\n\n/**\n * The base of a scenario — a named unit of coordination over the event bus.\n *\n * A subclass declares `name`, `eventType` and `dataTypeName`, calls `trigger()`\n * when the event happens, and ViewModels subscribe to it and unsubscribe.\n *\n * Scenarios register THEMSELVES unless the subclass sets the static\n * `skipAutoRegistration`.\n *\n * ```ts\n * export class SessionUpdated extends ALankaScenario<TSession> {\n * readonly name = \"SessionUpdated\";\n * readonly eventType = \"session.updated\";\n * readonly dataTypeName = \"TSession\";\n * }\n * ```\n */\nexport abstract class ALankaScenario<TData = void> implements ILankaScenario<TData> {\n\tabstract readonly name: string;\n\tabstract readonly eventType: string;\n\tabstract readonly dataTypeName: string;\n\n\t/** A subclass sets this to opt out of self-registration. */\n\tstatic skipAutoRegistration?: boolean;\n\n\t/**\n\t * The self-registration pool.\n\t *\n\t * Class-level deliberately: a registry of DEFINITIONS, not runtime state. The\n\t * classes come from one barrel and both framework instances must see the same\n\t * list — splitting it would be divergence, not isolation.\n\t */\n\tprivate static autoRegisteredScenarios: Set<ALankaScenario<unknown>> = new Set();\n\n\t/** Registers the scenario itself unless the subclass opted out. */\n\tconstructor() {\n\t\t// The constructor comes from the actual class, that is the subclass.\n\t\tconst constructor = this.constructor as typeof ALankaScenario;\n\n\t\t// Register unless opted out.\n\t\tif (!constructor.skipAutoRegistration) {\n\t\t\tALankaScenario.autoRegisteredScenarios.add(this);\n\t\t}\n\t}\n\n\t/**\n\t * Every scenario that registered itself.\n\t *\n\t * @internal\n\t */\n\tpublic static getAutoRegisteredScenarios(): ALankaScenario<unknown>[] {\n\t\treturn Array.from(ALankaScenario.autoRegisteredScenarios);\n\t}\n\n\t/**\n\t * Clears the auto-registration pool. Required by tests.\n\t * @internal\n\t */\n\tpublic static clearAutoRegisteredScenarios(): void {\n\t\tALankaScenario.autoRegisteredScenarios.clear();\n\t}\n\n\t/**\n\t * Registers the scenario by hand.\n\t *\n\t * @returns `false` when it was already registered\n\t */\n\tpublic register(): boolean {\n\t\treturn LankaScenariosRegistry.getInstance().register(this);\n\t}\n\n\t/**\n\t * Removes the scenario from the registry.\n\t *\n\t * @returns `false` when it was not there\n\t */\n\tpublic unregister(): boolean {\n\t\treturn LankaScenariosRegistry.getInstance().unregister(this.name);\n\t}\n\n\ttrigger(data?: TData): void {\n\t\tlankaLogger.printScenarioLog(\"TRIGGER Scenario\", this.name, data);\n\t\tlankaEventBus.dispatch(this.eventType, data, this.name);\n\t}\n\n\t/**\n\t * Subscribes a handler and returns an unsubscribe function.\n\t *\n\t * Without the return, unsubscribing is possible only by callback identity, and\n\t * every ViewModel factory has to keep a map of references for it.\n\t */\n\tsubscribe(\n\t\tcallback: (data?: TData) => void,\n\t\toptions?: {\n\t\t\tpriority?: number;\n\t\t\treplay?: TLankaReplayRequest;\n\t\t\tusedBy?: string;\n\t\t},\n\t): () => void {\n\t\tlankaLogger.printScenarioLog(\"SUBSCRIBE Scenario\", this.name, this.dataTypeName);\n\t\treturn lankaEventBus.subscribe(this.eventType, callback, {\n\t\t\t...options,\n\t\t\tusedBy: options?.usedBy ?? this.name,\n\t\t});\n\t}\n}\n"],"mappings":"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","names":[]}
|
package/dist/gateway/index.js
CHANGED
|
@@ -297,8 +297,7 @@ var ALankaGateway = class {
|
|
|
297
297
|
if (path.startsWith("/")) return path;
|
|
298
298
|
if (path.startsWith("?")) return `${this.basePath}${path}`;
|
|
299
299
|
const left = this.basePath.endsWith("/") ? this.basePath.slice(0, -1) : this.basePath;
|
|
300
|
-
|
|
301
|
-
return `${left}/${right}`;
|
|
300
|
+
return `${left}/${path}`;
|
|
302
301
|
}
|
|
303
302
|
/**
|
|
304
303
|
* Prefixes the API base URL from the host contract.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/gateway/request/_abstractions/lanka-request/ALankaRequest.ts","../../src/gateway/request/_abstractions/lanka-transport-request/ALankaTransportRequest.ts","../../src/gateway/transport/lanka-fetch-json-transport/LankaFetchJsonTransport.ts","../../src/gateway/request/lanka-fetch-json-request/LankaFetchJsonRequest.ts","../../src/gateway/_utils/build-lanka-query-params/buildLankaQueryParams.ts","../../src/gateway/_abstractions/lanka-gateway/ALankaGateway.ts","../../src/gateway/_factories/create-lanka-gateway/createLankaGateway.ts","../../src/gateway/transport/lanka-fetch-transport/LankaFetchTransport.ts","../../src/gateway/request/lanka-fetch-request/LankaFetchRequest.ts","../../src/gateway/request/_factories/create-lanka-fetch-request/createLankaFetchRequest.ts","../../src/gateway/request/_factories/create-lanka-fetch-json-request/createLankaFetchJsonRequest.ts","../../src/gateway/transport/lanka-fetch-form-data-transport/LankaFetchFormDataTransport.ts","../../src/gateway/request/lanka-fetch-form-data-request/LankaFetchFormDataRequest.ts","../../src/gateway/request/_factories/create-lanka-fetch-form-data-request/createLankaFetchFormDataRequest.ts"],"sourcesContent":["import type { TLankaErrorHandler } from \"../../../../errors/_types/TLankaErrorHandler\";\nimport type { ILankaRequest } from \"../../../_interfaces/ILankaRequest\";\nimport type { TLankaExecuteOptions } from \"../../../_types/TLankaExecuteOptions\";\nimport { handleLankaApiError } from \"../../../../errors/handle-lanka-api-error/handleLankaApiError\";\nimport { getLankaFlags } from \"../../../../config/get-lanka-flags/getLankaFlags\";\nimport { getLankaHost } from \"../../../../config/get-lanka-host/getLankaHost\";\nimport { lankaHttpInFlight } from \"../../../inflight/lankaHttpInFlight\";\nimport { LankaError } from \"../../../../errors/lanka-error/LankaError\";\nimport { getActiveRuntime } from \"../../../../_internal/active-runtime/activeRuntime\";\nimport { composeLankaRequestMiddleware } from \"../../lankaRequestMiddleware\";\nimport type { ILankaRequestContext } from \"../../lankaRequestMiddleware\";\n\n/**\n * Tags whatever the transport threw with a kind.\n *\n * Here rather than in the transports: `execute` is the single point EVERY\n * request passes through, and tagging in each of the four transports would be\n * four places to forget it.\n *\n * A real `fetch` throws `TypeError` on a broken connection and a `DOMException`\n * named `AbortError` on cancellation; it does not throw on a status code at all.\n *\n * An already-tagged error is NOT re-tagged: a request-policy plugin may report\n * `domain`, and rewriting that to `network` would lose the one thing the kind\n * exists for.\n */\nfunction classifyTransportError(error: unknown, timedOut: boolean): LankaError {\n\tif (LankaError.is(error)) return error;\n\n\t// The name is read off ANYTHING, not only off `Error`.\n\t//\n\t// `DOMException` — how `fetch` reports cancellation — does not extend `Error`\n\t// everywhere: in a browser yes, in jsdom no. An `instanceof Error` check lets\n\t// cancellation past the tagging, and a raw `AbortError` reaches the app with\n\t// neither `kind` nor `status`: retry policy reads it as non-retryable and the\n\t// app as an unknown error, so a cancelled request is shown to the user as a\n\t// failure.\n\tconst name = readErrorName(error);\n\tconst isAbort = name === \"AbortError\" || name === \"TimeoutError\";\n\tif (isAbort) {\n\t\t// Only whoever assembled the lifetime knows who aborted: `AbortSignal` has\n\t\t// one `abort` for everyone. The distinction carries a decision — a timeout\n\t\t// is shown, a cancellation is not.\n\t\tconst timedOutHere = timedOut || name === \"TimeoutError\";\n\t\treturn new LankaError({\n\t\t\tkind: timedOutHere ? \"timeout\" : \"aborted\",\n\t\t\tmessage: timedOutHere ? getLankaHost().timeoutErrorMessage() : readErrorMessage(error),\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\t// `network` ONLY for what looks like a transport failure. A real `fetch`\n\t// throws `TypeError`; everything else comes from code we did not write — the\n\t// app's error handler, a response transformer, a broken plugin — and calling\n\t// that a network failure would invite the user to retry a request that\n\t// arrived and was processed.\n\t//\n\t// Unknown stays unknown and passes through. The framework asserts only what\n\t// it knows.\n\tif (error instanceof TypeError) {\n\t\treturn new LankaError({\n\t\t\tkind: \"network\",\n\t\t\tmessage: getLankaHost().networkErrorMessage(),\n\t\t\tissues: [error.message],\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\treturn error as LankaError;\n}\n\n/** The error name, off `Error`, `DOMException` or anything else carrying one. */\nfunction readErrorName(error: unknown): string | undefined {\n\tif (typeof error !== \"object\" || error === null) return undefined;\n\tconst name: unknown = (error as { name?: unknown }).name;\n\treturn typeof name === \"string\" ? name : undefined;\n}\n\n/**\n * The error text, when there is one.\n *\n * An object without `message` is not stringified: `String({})` yields\n * `[object Object]`, which occupies the message slot and says nothing. Empty is\n * more honest.\n */\nfunction readErrorMessage(error: unknown): string {\n\tif (typeof error === \"string\") return error;\n\tif (typeof error !== \"object\" || error === null) return \"\";\n\tconst message: unknown = (error as { message?: unknown }).message;\n\treturn typeof message === \"string\" ? message : \"\";\n}\n\n/**\n * How a gateway request goes on the wire.\n *\n * A subclass declares one method, `request()`, and does only its own work there:\n * `LankaFetchJsonRequest` returns parsed JSON, `LankaFetchFormDataRequest`\n * returns the whole response, a custom transport returns whatever it likes.\n *\n * Overriding `request()` customises the request flow, failure handling, mock\n * substitution, response transformation and log interception.\n */\nexport abstract class ALankaRequest<TOptions = RequestInit> implements ILankaRequest<TOptions> {\n\tprotected readonly errorHandler?: TLankaErrorHandler;\n\tprotected readonly useMock: boolean;\n\n\tprotected constructor(config: { errorHandler?: TLankaErrorHandler; useMock?: boolean }) {\n\t\tconst flags = getLankaFlags();\n\n\t\t// The default error-body handler lives HERE because the request is the only\n\t\t// thing that sees the `Response`. Put on the gateway it would sit in a field\n\t\t// nobody reads — the request takes the handler from ITS OWN config — and a\n\t\t// consumer passing `errorHandler` to the gateway would get silence.\n\t\t//\n\t\t// The parse is cheap: core reads the body once and takes `message` from it;\n\t\t// backend-specific shapes are parsed by `@lankajs/plugin-http`.\n\t\tthis.errorHandler = config.errorHandler ?? handleLankaApiError;\n\n\t\tthis.useMock = config.useMock ?? flags.isMockMode ?? false;\n\t}\n\n\t/**\n\t * Performs the request and returns its result — a response, JSON or a custom\n\t * type.\n\t *\n\t * @param endpoint Full URL\n\t * @param options Transport-specific options\n\t * @param mockHandler Mock, when there is one\n\t */\n\tprotected abstract request<TReturn = Response>(\n\t\tendpoint: string,\n\t\toptions?: TOptions,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn>;\n\n\t/**\n\t * The single point EVERY gateway request passes through.\n\t *\n\t * Hence the in-flight accounting here: intent prefetch stands down while\n\t * anything else is on the wire. The `finally` matters more than the increment —\n\t * a rejected request that never decremented would disable prefetching for the\n\t * rest of the session.\n\t */\n\tpublic async execute<TReturn = Response>(\n\t\tendpoint: string,\n\t\toptions?: TLankaExecuteOptions<TOptions>,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn> {\n\t\tconst runtime = getActiveRuntime();\n\t\tconst { signal, timeoutMs, ...rest } = (options ?? {}) as TLankaExecuteOptions<TOptions>;\n\t\t// The caller's deadline travels IN THE CONTEXT, not only in the closure:\n\t\t// otherwise a policy assigning deadlines per request class could not tell\n\t\t// \"no deadline given\" from \"given by the caller\" and would override an\n\t\t// explicit request with a blanket default.\n\t\tconst fallbackDeadline = runtime?.requestTimeoutMs;\n\n\t\t// No options passed means none are produced. Destructuring yields `{}` even\n\t\t// from `undefined`, and handing that empty object to the transport would\n\t\t// change the request: \"no options\" and \"empty options\" are different\n\t\t// statements, and the transport is entitled to tell them apart.\n\t\tconst passedOptions: unknown = options === undefined ? undefined : rest;\n\n\t\t/*\n\t\t * The lifetime is assembled PER ATTEMPT, not per call, and that does two\n\t\t * things at once.\n\t\t *\n\t\t * Under retry a shared deadline would start the third attempt with whatever\n\t\t * the first two left, so the retry aborts before reaching the server.\n\t\t *\n\t\t * And it is the only way to let middleware set the deadline: `ctx.timeoutMs`\n\t\t * is read on every attempt, which is how a request-policy plugin assigns a\n\t\t * deadline per request CLASS — a file upload and a list read cannot share\n\t\t * one value.\n\t\t *\n\t\t * Caller cancellation stays end-to-end: one `signal` for all attempts.\n\t\t */\n\t\tlet lastTimedOut = false;\n\n\t\t// Tagging happens INSIDE, around the request itself, not in the outer\n\t\t// catch: middleware must receive an already-tagged error, or a retrying\n\t\t// middleware cannot tell a network failure from a domain rejection and\n\t\t// retries what must not be retried. The outer catch stays as a backstop.\n\t\tconst perform = async (ctx: ILankaRequestContext): Promise<unknown> => {\n\t\t\tconst lifetime = createRequestLifetime(signal, ctx.timeoutMs ?? fallbackDeadline);\n\t\t\ttry {\n\t\t\t\treturn await this.request<TReturn>(\n\t\t\t\t\tctx.endpoint,\n\t\t\t\t\twithSignal(ctx.options, lifetime.signal) as TOptions,\n\t\t\t\t\tmockHandler,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tlastTimedOut = lifetime.timedOut();\n\t\t\t\tthrow classifyTransportError(error, lastTimedOut);\n\t\t\t} finally {\n\t\t\t\tlifetime.dispose();\n\t\t\t}\n\t\t};\n\n\t\tconst run = composeLankaRequestMiddleware(runtime?.requestMiddleware ?? [], perform);\n\n\t\tlankaHttpInFlight.begin();\n\t\ttry {\n\t\t\t// The chain runs INSIDE the same guard as the request. A catch placed\n\t\t\t// outside would leave a permanent +1 when a plugin throws, disabling\n\t\t\t// prefetch for the rest of the session — the very defect this `finally`\n\t\t\t// exists to prevent.\n\t\t\treturn (await run({\n\t\t\t\tendpoint,\n\t\t\t\toptions: passedOptions,\n\t\t\t\tattempt: 1,\n\t\t\t\ttimeoutMs,\n\t\t\t})) as TReturn;\n\t\t} catch (error) {\n\t\t\tthrow classifyTransportError(error, lastTimedOut);\n\t\t} finally {\n\t\t\tlankaHttpInFlight.end();\n\t\t}\n\t}\n}\n\ninterface IRequestLifetime {\n\treadonly signal: AbortSignal | undefined;\n\t/** Whether OUR timer aborted the request rather than the caller. */\n\ttimedOut(): boolean;\n\tdispose(): void;\n}\n\n/**\n * Combines the caller's signal and our own timeout into one request lifetime.\n *\n * The outcome looks the same — an interrupted request — but the decisions\n * differ: a timeout is shown and offered for retry, a user cancellation is not\n * shown at all. `AbortSignal` does not distinguish them: one `abort`, whose\n * reason belongs to whoever got there first. Hence the private flag.\n *\n * Not `AbortSignal.timeout` alone: it cannot combine with a foreign signal\n * without `AbortSignal.any`, which older engines lack. Assembling by hand works\n * everywhere and costs one listener.\n */\nfunction createRequestLifetime(\n\texternal: AbortSignal | undefined,\n\ttimeoutMs: number | undefined,\n): IRequestLifetime {\n\tif (!external && !timeoutMs) {\n\t\treturn { signal: undefined, timedOut: () => false, dispose: () => undefined };\n\t}\n\n\tconst controller = new AbortController();\n\tlet expired = false;\n\n\tconst timer =\n\t\ttimeoutMs === undefined\n\t\t\t? undefined\n\t\t\t: setTimeout(() => {\n\t\t\t\t\texpired = true;\n\t\t\t\t\tcontroller.abort(new DOMException(\"Request timed out\", \"TimeoutError\"));\n\t\t\t\t}, timeoutMs);\n\n\tconst onExternalAbort = (): void => {\n\t\tcontroller.abort(external?.reason);\n\t};\n\n\tif (external) {\n\t\tif (external.aborted) onExternalAbort();\n\t\telse external.addEventListener(\"abort\", onExternalAbort, { once: true });\n\t}\n\n\treturn {\n\t\tsignal: controller.signal,\n\t\ttimedOut: () => expired,\n\t\tdispose: () => {\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\texternal?.removeEventListener(\"abort\", onExternalAbort);\n\t\t},\n\t};\n}\n\n/**\n * Attaches the signal to the options, inventing nothing.\n *\n * With no options and no signal the transport receives `undefined` — exactly\n * what the caller passed. An empty object instead looks harmless but is a\n * different statement, and the transport is entitled to tell them apart.\n */\nfunction withSignal(options: unknown, signal: AbortSignal | undefined): unknown {\n\tif (signal === undefined) return options;\n\treturn { ...(options ?? {}), signal };\n}\n","import { ALankaRequest } from \"../lanka-request/ALankaRequest\";\nimport { LankaError } from \"../../../../errors/lanka-error/LankaError\";\nimport { getLankaFlags } from \"../../../../config/get-lanka-flags/getLankaFlags\";\nimport { getLankaHost } from \"../../../../config/get-lanka-host/getLankaHost\";\nimport type { ILankaTransport } from \"../../../_interfaces/ILankaTransport\";\nimport type { TLankaErrorHandler } from \"../../../../errors/_types/TLankaErrorHandler\";\n\nexport interface ILankaTransportRequestConfig<TOptions> {\n\ttransport?: ILankaTransport<TOptions>;\n\terrorHandler?: TLankaErrorHandler;\n\tuseMock?: boolean;\n}\n\n/**\n * The shape every fetch-backed request has: mock, send, check, parse.\n *\n * The three concrete requests differ in exactly two places — which transport\n * they default to, and how they turn a successful `Response` into a value. Both\n * are parameters of this template, so a fourth kind is a subclass with one\n * method rather than a fourth copy of the sequence.\n */\nexport abstract class ALankaTransportRequest<\n\tTOptions = RequestInit,\n> extends ALankaRequest<TOptions> {\n\tprotected readonly transport: ILankaTransport<TOptions>;\n\n\tprotected constructor(\n\t\tconfig: ILankaTransportRequestConfig<TOptions>,\n\t\tcreateDefaultTransport: () => ILankaTransport<TOptions>,\n\t) {\n\t\tconst flags = getLankaFlags();\n\n\t\tsuper({\n\t\t\terrorHandler: config.errorHandler,\n\t\t\tuseMock: config.useMock ?? flags.isMockMode ?? false,\n\t\t});\n\n\t\tthis.transport = config.transport ?? createDefaultTransport();\n\t}\n\n\tprotected async request<TReturn>(\n\t\tendpoint: string,\n\t\toptions?: TOptions,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn> {\n\t\tif (this.useMock && mockHandler) {\n\t\t\treturn await mockHandler();\n\t\t}\n\n\t\tconst response = await this.transport.request(endpoint, options);\n\t\tif (!response.ok) return await this.refuse(response);\n\n\t\treturn await this.parse<TReturn>(response);\n\t}\n\n\t/**\n\t * Turns a successful response into the value the caller asked for.\n\t *\n\t * The one step that genuinely differs between request kinds.\n\t */\n\tprotected abstract parse<TReturn>(response: Response): Promise<TReturn>;\n\n\t/**\n\t * Refuses an unsuccessful response, and never returns.\n\t *\n\t * `TLankaErrorHandler` is typed `Promise<never>` — a handler must throw. It is\n\t * still CALLED and then followed by a throw, because a handler that breaks its\n\t * contract and returns would otherwise hand `undefined` back as if the request\n\t * had succeeded, and a non-value must never become a value.\n\t */\n\tprotected async refuse(response: Response): Promise<never> {\n\t\tif (this.errorHandler) {\n\t\t\tawait this.errorHandler(response);\n\t\t}\n\n\t\t// Kind `http`, not a bare Error: the server answered, and answered with a\n\t\t// code. Without the kind this reads as a network failure, and the user is\n\t\t// offered a retry of a request that already got a meaningful answer.\n\t\tthrow new LankaError({\n\t\t\tkind: \"http\",\n\t\t\tmessage: getLankaHost().httpErrorMessage(response.status),\n\t\t\tstatus: response.status,\n\t\t});\n\t}\n}\n","import type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\n\n/**\n * HTTP Fetch JSON transport implementation.\n * Uses native fetch API with JSON-specific headers.\n * Automatically sets Content-Type to application/json for requests with body.\n * For project-specific logic (auth, error handling, etc.), use `request` parameter\n * in Gateway config or create a custom transport.\n */\nexport class LankaFetchJsonTransport implements ILankaTransport<RequestInit> {\n\tasync request(resource: RequestInfo, options?: RequestInit): Promise<Response> {\n\t\t// Only set Content-Type if body exists and is not FormData\n\t\tif (options?.body && !(options.body instanceof FormData)) {\n\t\t\tconst headers = new Headers(options.headers);\n\n\t\t\t// If body is object, stringify it\n\t\t\tlet body = options.body;\n\t\t\tif (\n\t\t\t\ttypeof body === \"object\" &&\n\t\t\t\t!(body instanceof FormData) &&\n\t\t\t\t!(body instanceof Blob)\n\t\t\t) {\n\t\t\t\tbody = JSON.stringify(body);\n\t\t\t}\n\n\t\t\theaders.set(\"Content-Type\", \"application/json\");\n\n\t\t\treturn await fetch(resource, {\n\t\t\t\t...options,\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t});\n\t\t}\n\n\t\t// No body or FormData - use options as-is\n\t\treturn await fetch(resource, options);\n\t}\n}\n","import { ALankaTransportRequest } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransportRequestConfig } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\nimport { LankaFetchJsonTransport } from \"../../transport/lanka-fetch-json-transport/LankaFetchJsonTransport\";\nimport { LankaError } from \"../../../errors/lanka-error/LankaError\";\n\n/** The JSON request: parses the body, and refuses a body that is not JSON. */\n/**\n * A request kind that answers a parsed JSON body — what most endpoints return.\n *\n * A gateway holds one, and is handed it rather than constructing it, which is\n * what lets a test give the same gateway a transport that never leaves the\n * process. `createLankaFetchJsonRequest()` builds the same class.\n */\nexport class LankaFetchJsonRequest<\n\tTOptions = RequestInit,\n> extends ALankaTransportRequest<TOptions> {\n\tconstructor(config: ILankaTransportRequestConfig<TOptions> = {}) {\n\t\tsuper(config, () => new LankaFetchJsonTransport() as ILankaTransport<TOptions>);\n\t}\n\n\t/**\n\t * Parses the body, or names the failure.\n\t *\n\t * The content type is read for the ERROR MESSAGE only. Using it to choose\n\t * between two parse paths, where the second answers `{}` for any non-empty\n\t * body it cannot parse, fails silently: the caller's schema is the first thing\n\t * to notice, and the caller's SCREEN is where it shows up.\n\t *\n\t * A measured case: a dev server whose `/api` fell through to the SPA fallback\n\t * answered `200 text/html` with `index.html`. Turned into `{}`, the schema\n\t * refused it and a person read a validator's issue list on the sign-in card. A\n\t * body a JSON transport cannot parse is never a value — it is a misrouted\n\t * request, and saying so names the actual failure.\n\t */\n\tprotected async parse<TReturn>(response: Response): Promise<TReturn> {\n\t\tconst contentType = response.headers.get(\"content-type\");\n\n\t\tconst text = await response.text();\n\t\tif (!text) {\n\t\t\treturn undefined as TReturn;\n\t\t}\n\n\t\ttry {\n\t\t\treturn JSON.parse(text) as TReturn;\n\t\t} catch (error) {\n\t\t\t// `schema`, not `network`: the request arrived, the server answered, and\n\t\t\t// the answer was the wrong shape. Not cosmetic — a network failure\n\t\t\t// invites a retry, while retrying a broken contract is pointless and\n\t\t\t// blaming the user for it more so.\n\t\t\tthrow new LankaError({\n\t\t\t\tkind: \"schema\",\n\t\t\t\tmessage:\n\t\t\t\t\t`Failed to parse JSON response (content-type: ${contentType ?? \"none\"}): ` +\n\t\t\t\t\t`${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t}\n}\n","import { TLankaQueryParams } from \"../../_types/TLankaQueryParams\";\nimport { TLankaQueryBuilder } from \"../../_types/TLankaQueryBuilder\";\n\n/**\n * The query string a gateway sends, from the object a method was called with.\n *\n * Arrays become `key[]` repeated, nested objects become `key[inner]`: the shape\n * most JSON APIs read back without being told about it.\n *\n * Plain loops over `Object.keys` rather than `Object.entries` and `forEach`: this\n * runs on every request that carries a filter, and the pair array `entries`\n * builds — two allocations per key, thrown away immediately — is a cost with\n * nothing to show for it.\n */\nexport const buildLankaQueryParams: TLankaQueryBuilder = <T extends Record<string, unknown>>(\n\tinput: T,\n): URLSearchParams => {\n\tconst params = new URLSearchParams();\n\n\tconst append = (key: string, value: TLankaQueryParams): void => {\n\t\tif (value == null) return;\n\n\t\tif (Array.isArray(value)) {\n\t\t\t// The bracketed key once for the whole array, not once per element.\n\t\t\tconst itemKey = `${key}[]`;\n\t\t\tfor (let index = 0; index < value.length; index += 1) append(itemKey, value[index]);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tconst inner = value as Record<string, TLankaQueryParams>;\n\t\t\tconst innerKeys = Object.keys(inner);\n\n\t\t\tfor (let index = 0; index < innerKeys.length; index += 1) {\n\t\t\t\tconst innerKey = innerKeys[index];\n\t\t\t\tappend(`${key}[${innerKey}]`, inner[innerKey]);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tparams.append(key, String(value));\n\t};\n\n\tconst source = input as Record<string, TLankaQueryParams>;\n\tconst keys = Object.keys(source);\n\n\tfor (let index = 0; index < keys.length; index += 1) append(keys[index], source[keys[index]]);\n\n\treturn params;\n};\n","import type { IALankaGatewayConfig } from \"../../_interfaces/IALankaGatewayConfig\";\nimport { lankaLogger } from \"../../../logger/lanka-logger/LankaLogger\";\nimport { LankaFetchJsonRequest } from \"../../request/lanka-fetch-json-request/LankaFetchJsonRequest\";\nimport type { ILankaRequest } from \"../../_interfaces/ILankaRequest\";\nimport type { TLankaExecuteOptions } from \"../../_types/TLankaExecuteOptions\";\nimport { buildLankaQueryParams } from \"../../_utils/build-lanka-query-params/buildLankaQueryParams\";\nimport { TLankaQueryParams } from \"../../_types/TLankaQueryParams\";\nimport { TLankaQueryBuilder } from \"../../_types/TLankaQueryBuilder\";\nimport { getLankaFlags } from \"../../../config/get-lanka-flags/getLankaFlags\";\nimport { getLankaHost } from \"../../../config/get-lanka-host/getLankaHost\";\n\nexport abstract class ALankaGateway<TOptions = RequestInit> {\n\tprotected requestExecutor: ILankaRequest<TOptions>;\n\tprotected queryParamsHandler: TLankaQueryBuilder;\n\n\tprotected readonly useMock: boolean;\n\tprotected readonly basePath: string;\n\n\tprotected constructor(config: IALankaGatewayConfig<TOptions>) {\n\t\tlankaLogger.printGatewayLog(\"Create gateway\", this);\n\t\tconst flags = getLankaFlags();\n\t\tthis.useMock = config.useMock ?? flags.isMockMode ?? false;\n\n\t\t// A gateway with nothing said about transport talks JSON over `fetch`, which\n\t\t// is what almost every one of them does. Supplying a request is how a gateway\n\t\t// stops being ordinary — a raw `Response`, a multipart upload, a transport\n\t\t// that never leaves the process — and that stays a decision rather than a\n\t\t// line every gateway has to carry to be born.\n\t\tthis.requestExecutor = config.request ?? new LankaFetchJsonRequest<TOptions>();\n\n\t\tthis.basePath = config.basePath ?? \"\";\n\t\tthis.queryParamsHandler = config.queryParamsHandler ?? buildLankaQueryParams;\n\t}\n\n\t/**\n\t * Resolves endpoint for request.\n\t * - Absolute paths (starting with \"/\") are returned as-is\n\t * - Relative paths are joined with basePath\n\t * - Query-only strings like \"?a=1\" are attached to basePath\n\t */\n\tprotected endpoint(path: string = \"\"): string {\n\t\t// An absolute URL is detected BEFORE joining with `basePath`, not after:\n\t\t// otherwise `https://other.host/health` first becomes\n\t\t// `/things/https://other.host/health` and there is nothing left to detect.\n\t\tif (isAbsoluteUrl(path)) return path;\n\n\t\treturn this.withApiBase(this.resolvePath(path));\n\t}\n\n\t/**\n\t * Joins `basePath` and the method path.\n\t */\n\tprivate resolvePath(path: string): string {\n\t\tif (!path) return this.basePath;\n\n\t\tif (path.startsWith(\"/\")) return path;\n\n\t\tif (path.startsWith(\"?\")) return `${this.basePath}${path}`;\n\n\t\tconst left = this.basePath.endsWith(\"/\") ? this.basePath.slice(0, -1) : this.basePath;\n\t\tconst right = path.startsWith(\"/\") ? path.slice(1) : path;\n\t\treturn `${left}/${right}`;\n\t}\n\n\t/**\n\t * Prefixes the API base URL from the host contract.\n\t *\n\t * Here rather than in every consumer: otherwise each consumer knows the URL\n\t * and the framework does not, and a realtime plugin would have to know a\n\t * specific application's build.\n\t *\n\t * Declaring the field and not using it would be worse than not declaring it: a\n\t * declaration nothing is built from is a second truth, free to diverge from\n\t * the first.\n\t *\n\t * An absolute URL never reaches here — `endpoint()` filters it out before the\n\t * join.\n\t */\n\tprivate withApiBase(path: string): string {\n\t\tconst base = withoutTrailingSlashes(getLankaHost().apiBaseUrl);\n\t\tif (!base) return path;\n\t\tif (!path) return base;\n\n\t\treturn path.startsWith(\"/\") ? `${base}${path}` : `${base}/${path}`;\n\t}\n\n\tprotected buildQueryParams<T extends object>(params: T): URLSearchParams {\n\t\treturn this.queryParamsHandler(params as Record<string, TLankaQueryParams>);\n\t}\n\n\tprotected async request<TReturn = unknown>(\n\t\tpath: string,\n\t\toptions?: TLankaExecuteOptions<TOptions>,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn> {\n\t\treturn this.requestExecutor.execute<TReturn>(this.endpoint(path), options, mockHandler);\n\t}\n\n\t/**\n\t * Allows to replace request implementation at runtime (e.g. feature flags / tests).\n\t * If you prefer static customization - override `request()` in a subclass.\n\t */\n\tprotected setRequest(request: ILankaRequest<TOptions>): void {\n\t\tthis.requestExecutor = request;\n\t}\n\n\tprotected setQueryParamsHandler(handler: TLankaQueryBuilder): void {\n\t\tthis.queryParamsHandler = handler;\n\t}\n}\n\n/**\n * A scheme plus `//` — a URL that already knows where it is going.\n *\n * A standalone function rather than a method: it is not about a particular\n * gateway, and `endpoint()` needs it before any joining.\n */\nfunction isAbsoluteUrl(path: string): boolean {\n\t// The cheap half first: a scheme needs `://`, and `includes` answers without\n\t// starting the regex engine. Every relative path an application writes — which\n\t// is nearly all of them — stops on this line.\n\tif (!path.includes(\"://\")) return false;\n\n\treturn /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(path);\n}\n\n/**\n * The API base without its trailing slashes, remembered between calls.\n *\n * The host answers the same string for the life of an application, and trimming\n * it is a regex replace otherwise run on every endpoint of every request. One\n * entry is enough: there is one active host, and a second framework in the same\n * process simply replaces what is remembered here.\n */\nlet lastRawBase: string | null = null;\nlet lastTrimmedBase = \"\";\n\nfunction withoutTrailingSlashes(base: string): string {\n\tif (base !== lastRawBase) {\n\t\tlastRawBase = base;\n\t\tlastTrimmedBase = base.replace(/\\/+$/, \"\");\n\t}\n\n\treturn lastTrimmedBase;\n}\n","import { ALankaGateway } from \"../../_abstractions/lanka-gateway/ALankaGateway\";\nimport type { IALankaGatewayConfig } from \"../../_interfaces/IALankaGatewayConfig\";\nimport type { ILankaGatewayContext } from \"../../_interfaces/ILankaGatewayContext\";\n\n/** What a gateway is built from, whichever style builds it. */\nexport interface ILankaGatewayConfig<\n\tTOptions,\n\tTMethods extends object,\n> extends IALankaGatewayConfig<TOptions> {\n\t/** The endpoints this gateway offers, written over its own surface. */\n\tmethods: (context: ILankaGatewayContext<TOptions>) => TMethods;\n}\n\n/**\n * A gateway, without writing a class.\n *\n * The bridge below is the whole mechanism, and it lives here rather than on the\n * base for two reasons. The language reads `protected` from inside a deriving\n * class body and nowhere else, so a factory outside the hierarchy could only\n * reach the public half — the wrong one. And a `toStyleContext` ON the base\n * would put `TOptions` in a method's parameter position, making the class\n * invariant in it: every `ALankaGateway<unknown>` the locator holds would stop\n * accepting a gateway typed for `RequestInit`.\n *\n * One implementation: what comes back is an instance of `ALankaGateway`, so a\n * behaviour fix reaches both styles at once.\n */\nexport const createLankaGateway = <TOptions, TMethods extends object>(\n\tconfig: ILankaGatewayConfig<TOptions, TMethods>,\n): TMethods => {\n\tclass FunctionalGateway extends ALankaGateway<TOptions> {\n\t\t// The base keeps a protected constructor — it is abstract, and a consumer\n\t\t// reaching for `new ALankaGateway()` would get an object with no endpoints.\n\t\t// A subclass may widen it, and this one is the subclass.\n\t\tpublic constructor(gatewayConfig: IALankaGatewayConfig<TOptions>) {\n\t\t\tsuper(gatewayConfig);\n\t\t}\n\n\t\tpublic build(): TMethods {\n\t\t\treturn config.methods({\n\t\t\t\tendpoint: (path) => this.endpoint(path),\n\t\t\t\trequest: (path, options, mockHandler) => this.request(path, options, mockHandler),\n\t\t\t\tbuildQueryParams: (params) => this.buildQueryParams(params),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn new FunctionalGateway(config).build();\n};\n","import type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\n\n/**\n * HTTP Fetch transport implementation.\n * Uses native fetch API without any project-specific decorators.\n * For project-specific logic (auth, error handling, etc.), use `request` parameter\n * in Gateway config or create a custom transport.\n */\nexport class LankaFetchTransport implements ILankaTransport<RequestInit> {\n\tasync request(resource: RequestInfo, options?: RequestInit): Promise<Response> {\n\t\treturn await fetch(resource, options);\n\t}\n}\n","import { ALankaTransportRequest } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransportRequestConfig } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\nimport { LankaFetchTransport } from \"../../transport/lanka-fetch-transport/LankaFetchTransport\";\n\n/**\n * The raw request: hands the `Response` back untouched.\n *\n * The minimal, extensible case — a caller wanting headers, a stream or a blob\n * reads them off the response itself.\n */\nexport class LankaFetchRequest<TOptions = RequestInit> extends ALankaTransportRequest<TOptions> {\n\tconstructor(config: ILankaTransportRequestConfig<TOptions> = {}) {\n\t\tsuper(config, () => new LankaFetchTransport() as ILankaTransport<TOptions>);\n\t}\n\n\tprotected parse<TReturn>(response: Response): Promise<TReturn> {\n\t\treturn Promise.resolve(response as unknown as TReturn);\n\t}\n}\n","import { LankaFetchRequest } from \"../../lanka-fetch-request/LankaFetchRequest\";\nimport type { ILankaTransportRequestConfig } from \"../../_abstractions/lanka-transport-request/ALankaTransportRequest\";\n\n/**\n * The functional style of `LankaFetchRequest`: the raw `Response`, for a download or a stream.\n *\n * One line, and that is the point — the factory IS the class, so a behaviour\n * cannot exist in one style and not the other.\n */\nexport const createLankaFetchRequest = <TOptions = RequestInit>(\n\tconfig: ILankaTransportRequestConfig<TOptions> = {},\n): LankaFetchRequest<TOptions> => new LankaFetchRequest<TOptions>(config);\n","import { LankaFetchJsonRequest } from \"../../lanka-fetch-json-request/LankaFetchJsonRequest\";\nimport type { ILankaTransportRequestConfig } from \"../../_abstractions/lanka-transport-request/ALankaTransportRequest\";\n\n/**\n * The functional style of `LankaFetchJsonRequest`: a JSON body, which is what most endpoints answer.\n *\n * One line, and that is the point — the factory IS the class, so a behaviour\n * cannot exist in one style and not the other.\n */\nexport const createLankaFetchJsonRequest = <TOptions = RequestInit>(\n\tconfig: ILankaTransportRequestConfig<TOptions> = {},\n): LankaFetchJsonRequest<TOptions> => new LankaFetchJsonRequest<TOptions>(config);\n","import type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\n\n/**\n * HTTP Fetch FormData transport implementation.\n * Uses native fetch API optimized for FormData requests.\n * Does not set Content-Type header (browser will set it automatically with boundary).\n * For project-specific logic (auth, error handling, etc.), use `request` parameter\n * in Gateway config or create a custom transport.\n */\nexport class LankaFetchFormDataTransport implements ILankaTransport<RequestInit> {\n\tasync request(resource: RequestInfo, options?: RequestInit): Promise<Response> {\n\t\tconst formDataOptions: RequestInit = { ...options };\n\n\t\t// Remove Content-Type header if body is FormData (browser will set it with boundary)\n\t\tif (formDataOptions.body instanceof FormData && formDataOptions.headers) {\n\t\t\tconst headers = new Headers(formDataOptions.headers);\n\t\t\theaders.delete(\"Content-Type\");\n\t\t\tformDataOptions.headers = headers;\n\t\t}\n\n\t\treturn await fetch(resource, formDataOptions);\n\t}\n}\n","import { ALankaTransportRequest } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransportRequestConfig } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\nimport { LankaFetchFormDataTransport } from \"../../transport/lanka-fetch-form-data-transport/LankaFetchFormDataTransport\";\n\n/**\n * The multipart request: hands the `Response` back untouched.\n *\n * Differs from `LankaFetchRequest` only in its transport — the one that must NOT\n * set `content-type`, because the browser writes it with the boundary and a\n * hand-set header leaves the body unparseable to the server.\n */\nexport class LankaFetchFormDataRequest<\n\tTOptions = RequestInit,\n> extends ALankaTransportRequest<TOptions> {\n\tconstructor(config: ILankaTransportRequestConfig<TOptions> = {}) {\n\t\tsuper(config, () => new LankaFetchFormDataTransport() as ILankaTransport<TOptions>);\n\t}\n\n\tprotected parse<TReturn>(response: Response): Promise<TReturn> {\n\t\treturn Promise.resolve(response as unknown as TReturn);\n\t}\n}\n","import { LankaFetchFormDataRequest } from \"../../lanka-fetch-form-data-request/LankaFetchFormDataRequest\";\nimport type { ILankaTransportRequestConfig } from \"../../_abstractions/lanka-transport-request/ALankaTransportRequest\";\n\n/**\n * The functional style of `LankaFetchFormDataRequest`: a multipart body, for an upload.\n *\n * One line, and that is the point — the factory IS the class, so a behaviour\n * cannot exist in one style and not the other.\n */\nexport const createLankaFetchFormDataRequest = <TOptions = RequestInit>(\n\tconfig: ILankaTransportRequestConfig<TOptions> = {},\n): LankaFetchFormDataRequest<TOptions> => new LankaFetchFormDataRequest<TOptions>(config);\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/gateway/request/_abstractions/lanka-request/ALankaRequest.ts","../../src/gateway/request/_abstractions/lanka-transport-request/ALankaTransportRequest.ts","../../src/gateway/transport/lanka-fetch-json-transport/LankaFetchJsonTransport.ts","../../src/gateway/request/lanka-fetch-json-request/LankaFetchJsonRequest.ts","../../src/gateway/_utils/build-lanka-query-params/buildLankaQueryParams.ts","../../src/gateway/_abstractions/lanka-gateway/ALankaGateway.ts","../../src/gateway/_factories/create-lanka-gateway/createLankaGateway.ts","../../src/gateway/transport/lanka-fetch-transport/LankaFetchTransport.ts","../../src/gateway/request/lanka-fetch-request/LankaFetchRequest.ts","../../src/gateway/request/_factories/create-lanka-fetch-request/createLankaFetchRequest.ts","../../src/gateway/request/_factories/create-lanka-fetch-json-request/createLankaFetchJsonRequest.ts","../../src/gateway/transport/lanka-fetch-form-data-transport/LankaFetchFormDataTransport.ts","../../src/gateway/request/lanka-fetch-form-data-request/LankaFetchFormDataRequest.ts","../../src/gateway/request/_factories/create-lanka-fetch-form-data-request/createLankaFetchFormDataRequest.ts"],"sourcesContent":["import type { TLankaErrorHandler } from \"../../../../errors/_types/TLankaErrorHandler\";\nimport type { ILankaRequest } from \"../../../_interfaces/ILankaRequest\";\nimport type { TLankaExecuteOptions } from \"../../../_types/TLankaExecuteOptions\";\nimport { handleLankaApiError } from \"../../../../errors/handle-lanka-api-error/handleLankaApiError\";\nimport { getLankaFlags } from \"../../../../config/get-lanka-flags/getLankaFlags\";\nimport { getLankaHost } from \"../../../../config/get-lanka-host/getLankaHost\";\nimport { lankaHttpInFlight } from \"../../../inflight/lankaHttpInFlight\";\nimport { LankaError } from \"../../../../errors/lanka-error/LankaError\";\nimport { getActiveRuntime } from \"../../../../_internal/active-runtime/activeRuntime\";\nimport { composeLankaRequestMiddleware } from \"../../lankaRequestMiddleware\";\nimport type { ILankaRequestContext } from \"../../lankaRequestMiddleware\";\n\n/**\n * Tags whatever the transport threw with a kind.\n *\n * Here rather than in the transports: `execute` is the single point EVERY\n * request passes through, and tagging in each of the four transports would be\n * four places to forget it.\n *\n * A real `fetch` throws `TypeError` on a broken connection and a `DOMException`\n * named `AbortError` on cancellation; it does not throw on a status code at all.\n *\n * An already-tagged error is NOT re-tagged: a request-policy plugin may report\n * `domain`, and rewriting that to `network` would lose the one thing the kind\n * exists for.\n */\nfunction classifyTransportError(error: unknown, timedOut: boolean): LankaError {\n\tif (LankaError.is(error)) return error;\n\n\t// The name is read off ANYTHING, not only off `Error`.\n\t//\n\t// `DOMException` — how `fetch` reports cancellation — does not extend `Error`\n\t// everywhere: in a browser yes, in jsdom no. An `instanceof Error` check lets\n\t// cancellation past the tagging, and a raw `AbortError` reaches the app with\n\t// neither `kind` nor `status`: retry policy reads it as non-retryable and the\n\t// app as an unknown error, so a cancelled request is shown to the user as a\n\t// failure.\n\tconst name = readErrorName(error);\n\tconst isAbort = name === \"AbortError\" || name === \"TimeoutError\";\n\tif (isAbort) {\n\t\t// Only whoever assembled the lifetime knows who aborted: `AbortSignal` has\n\t\t// one `abort` for everyone. The distinction carries a decision — a timeout\n\t\t// is shown, a cancellation is not.\n\t\tconst timedOutHere = timedOut || name === \"TimeoutError\";\n\t\treturn new LankaError({\n\t\t\tkind: timedOutHere ? \"timeout\" : \"aborted\",\n\t\t\tmessage: timedOutHere ? getLankaHost().timeoutErrorMessage() : readErrorMessage(error),\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\t// `network` ONLY for what looks like a transport failure. A real `fetch`\n\t// throws `TypeError`; everything else comes from code we did not write — the\n\t// app's error handler, a response transformer, a broken plugin — and calling\n\t// that a network failure would invite the user to retry a request that\n\t// arrived and was processed.\n\t//\n\t// Unknown stays unknown and passes through. The framework asserts only what\n\t// it knows.\n\tif (error instanceof TypeError) {\n\t\treturn new LankaError({\n\t\t\tkind: \"network\",\n\t\t\tmessage: getLankaHost().networkErrorMessage(),\n\t\t\tissues: [error.message],\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\treturn error as LankaError;\n}\n\n/** The error name, off `Error`, `DOMException` or anything else carrying one. */\nfunction readErrorName(error: unknown): string | undefined {\n\tif (typeof error !== \"object\" || error === null) return undefined;\n\tconst name: unknown = (error as { name?: unknown }).name;\n\treturn typeof name === \"string\" ? name : undefined;\n}\n\n/**\n * The error text, when there is one.\n *\n * An object without `message` is not stringified: `String({})` yields\n * `[object Object]`, which occupies the message slot and says nothing. Empty is\n * more honest.\n */\nfunction readErrorMessage(error: unknown): string {\n\tif (typeof error === \"string\") return error;\n\tif (typeof error !== \"object\" || error === null) return \"\";\n\tconst message: unknown = (error as { message?: unknown }).message;\n\treturn typeof message === \"string\" ? message : \"\";\n}\n\n/**\n * How a gateway request goes on the wire.\n *\n * A subclass declares one method, `request()`, and does only its own work there:\n * `LankaFetchJsonRequest` returns parsed JSON, `LankaFetchFormDataRequest`\n * returns the whole response, a custom transport returns whatever it likes.\n *\n * Overriding `request()` customises the request flow, failure handling, mock\n * substitution, response transformation and log interception.\n */\nexport abstract class ALankaRequest<TOptions = RequestInit> implements ILankaRequest<TOptions> {\n\tprotected readonly errorHandler?: TLankaErrorHandler;\n\tprotected readonly useMock: boolean;\n\n\tprotected constructor(config: { errorHandler?: TLankaErrorHandler; useMock?: boolean }) {\n\t\tconst flags = getLankaFlags();\n\n\t\t// The default error-body handler lives HERE because the request is the only\n\t\t// thing that sees the `Response`. Put on the gateway it would sit in a field\n\t\t// nobody reads — the request takes the handler from ITS OWN config — and a\n\t\t// consumer passing `errorHandler` to the gateway would get silence.\n\t\t//\n\t\t// The parse is cheap: core reads the body once and takes `message` from it;\n\t\t// backend-specific shapes are parsed by `@lankajs/plugin-http`.\n\t\tthis.errorHandler = config.errorHandler ?? handleLankaApiError;\n\n\t\tthis.useMock = config.useMock ?? flags.isMockMode ?? false;\n\t}\n\n\t/**\n\t * Performs the request and returns its result — a response, JSON or a custom\n\t * type.\n\t *\n\t * @param endpoint Full URL\n\t * @param options Transport-specific options\n\t * @param mockHandler Mock, when there is one\n\t */\n\tprotected abstract request<TReturn = Response>(\n\t\tendpoint: string,\n\t\toptions?: TOptions,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn>;\n\n\t/**\n\t * The single point EVERY gateway request passes through.\n\t *\n\t * Hence the in-flight accounting here: intent prefetch stands down while\n\t * anything else is on the wire. The `finally` matters more than the increment —\n\t * a rejected request that never decremented would disable prefetching for the\n\t * rest of the session.\n\t */\n\tpublic async execute<TReturn = Response>(\n\t\tendpoint: string,\n\t\toptions?: TLankaExecuteOptions<TOptions>,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn> {\n\t\tconst runtime = getActiveRuntime();\n\t\tconst { signal, timeoutMs, ...rest } = (options ?? {}) as TLankaExecuteOptions<TOptions>;\n\t\t// The caller's deadline travels IN THE CONTEXT, not only in the closure:\n\t\t// otherwise a policy assigning deadlines per request class could not tell\n\t\t// \"no deadline given\" from \"given by the caller\" and would override an\n\t\t// explicit request with a blanket default.\n\t\tconst fallbackDeadline = runtime?.requestTimeoutMs;\n\n\t\t// No options passed means none are produced. Destructuring yields `{}` even\n\t\t// from `undefined`, and handing that empty object to the transport would\n\t\t// change the request: \"no options\" and \"empty options\" are different\n\t\t// statements, and the transport is entitled to tell them apart.\n\t\tconst passedOptions: unknown = options === undefined ? undefined : rest;\n\n\t\t/*\n\t\t * The lifetime is assembled PER ATTEMPT, not per call, and that does two\n\t\t * things at once.\n\t\t *\n\t\t * Under retry a shared deadline would start the third attempt with whatever\n\t\t * the first two left, so the retry aborts before reaching the server.\n\t\t *\n\t\t * And it is the only way to let middleware set the deadline: `ctx.timeoutMs`\n\t\t * is read on every attempt, which is how a request-policy plugin assigns a\n\t\t * deadline per request CLASS — a file upload and a list read cannot share\n\t\t * one value.\n\t\t *\n\t\t * Caller cancellation stays end-to-end: one `signal` for all attempts.\n\t\t */\n\t\tlet lastTimedOut = false;\n\n\t\t// Tagging happens INSIDE, around the request itself, not in the outer\n\t\t// catch: middleware must receive an already-tagged error, or a retrying\n\t\t// middleware cannot tell a network failure from a domain rejection and\n\t\t// retries what must not be retried. The outer catch stays as a backstop.\n\t\tconst perform = async (ctx: ILankaRequestContext): Promise<unknown> => {\n\t\t\tconst lifetime = createRequestLifetime(signal, ctx.timeoutMs ?? fallbackDeadline);\n\t\t\ttry {\n\t\t\t\treturn await this.request<TReturn>(\n\t\t\t\t\tctx.endpoint,\n\t\t\t\t\twithSignal(ctx.options, lifetime.signal) as TOptions,\n\t\t\t\t\tmockHandler,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tlastTimedOut = lifetime.timedOut();\n\t\t\t\tthrow classifyTransportError(error, lastTimedOut);\n\t\t\t} finally {\n\t\t\t\tlifetime.dispose();\n\t\t\t}\n\t\t};\n\n\t\tconst run = composeLankaRequestMiddleware(runtime?.requestMiddleware ?? [], perform);\n\n\t\tlankaHttpInFlight.begin();\n\t\ttry {\n\t\t\t// The chain runs INSIDE the same guard as the request. A catch placed\n\t\t\t// outside would leave a permanent +1 when a plugin throws, disabling\n\t\t\t// prefetch for the rest of the session — the very defect this `finally`\n\t\t\t// exists to prevent.\n\t\t\treturn (await run({\n\t\t\t\tendpoint,\n\t\t\t\toptions: passedOptions,\n\t\t\t\tattempt: 1,\n\t\t\t\ttimeoutMs,\n\t\t\t})) as TReturn;\n\t\t} catch (error) {\n\t\t\tthrow classifyTransportError(error, lastTimedOut);\n\t\t} finally {\n\t\t\tlankaHttpInFlight.end();\n\t\t}\n\t}\n}\n\ninterface IRequestLifetime {\n\treadonly signal: AbortSignal | undefined;\n\t/** Whether OUR timer aborted the request rather than the caller. */\n\ttimedOut(): boolean;\n\tdispose(): void;\n}\n\n/**\n * Combines the caller's signal and our own timeout into one request lifetime.\n *\n * The outcome looks the same — an interrupted request — but the decisions\n * differ: a timeout is shown and offered for retry, a user cancellation is not\n * shown at all. `AbortSignal` does not distinguish them: one `abort`, whose\n * reason belongs to whoever got there first. Hence the private flag.\n *\n * Not `AbortSignal.timeout` alone: it cannot combine with a foreign signal\n * without `AbortSignal.any`, which older engines lack. Assembling by hand works\n * everywhere and costs one listener.\n */\nfunction createRequestLifetime(\n\texternal: AbortSignal | undefined,\n\ttimeoutMs: number | undefined,\n): IRequestLifetime {\n\tif (!external && !timeoutMs) {\n\t\treturn { signal: undefined, timedOut: () => false, dispose: () => undefined };\n\t}\n\n\tconst controller = new AbortController();\n\tlet expired = false;\n\n\tconst timer =\n\t\ttimeoutMs === undefined\n\t\t\t? undefined\n\t\t\t: setTimeout(() => {\n\t\t\t\t\texpired = true;\n\t\t\t\t\tcontroller.abort(new DOMException(\"Request timed out\", \"TimeoutError\"));\n\t\t\t\t}, timeoutMs);\n\n\tconst onExternalAbort = (): void => {\n\t\tcontroller.abort(external?.reason);\n\t};\n\n\tif (external) {\n\t\tif (external.aborted) onExternalAbort();\n\t\telse external.addEventListener(\"abort\", onExternalAbort, { once: true });\n\t}\n\n\treturn {\n\t\tsignal: controller.signal,\n\t\ttimedOut: () => expired,\n\t\tdispose: () => {\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\texternal?.removeEventListener(\"abort\", onExternalAbort);\n\t\t},\n\t};\n}\n\n/**\n * Attaches the signal to the options, inventing nothing.\n *\n * With no options and no signal the transport receives `undefined` — exactly\n * what the caller passed. An empty object instead looks harmless but is a\n * different statement, and the transport is entitled to tell them apart.\n */\nfunction withSignal(options: unknown, signal: AbortSignal | undefined): unknown {\n\tif (signal === undefined) return options;\n\treturn { ...(options ?? {}), signal };\n}\n","import { ALankaRequest } from \"../lanka-request/ALankaRequest\";\nimport { LankaError } from \"../../../../errors/lanka-error/LankaError\";\nimport { getLankaFlags } from \"../../../../config/get-lanka-flags/getLankaFlags\";\nimport { getLankaHost } from \"../../../../config/get-lanka-host/getLankaHost\";\nimport type { ILankaTransport } from \"../../../_interfaces/ILankaTransport\";\nimport type { TLankaErrorHandler } from \"../../../../errors/_types/TLankaErrorHandler\";\n\nexport interface ILankaTransportRequestConfig<TOptions> {\n\ttransport?: ILankaTransport<TOptions>;\n\terrorHandler?: TLankaErrorHandler;\n\tuseMock?: boolean;\n}\n\n/**\n * The shape every fetch-backed request has: mock, send, check, parse.\n *\n * The three concrete requests differ in exactly two places — which transport\n * they default to, and how they turn a successful `Response` into a value. Both\n * are parameters of this template, so a fourth kind is a subclass with one\n * method rather than a fourth copy of the sequence.\n */\nexport abstract class ALankaTransportRequest<\n\tTOptions = RequestInit,\n> extends ALankaRequest<TOptions> {\n\tprotected readonly transport: ILankaTransport<TOptions>;\n\n\tprotected constructor(\n\t\tconfig: ILankaTransportRequestConfig<TOptions>,\n\t\tcreateDefaultTransport: () => ILankaTransport<TOptions>,\n\t) {\n\t\tconst flags = getLankaFlags();\n\n\t\tsuper({\n\t\t\terrorHandler: config.errorHandler,\n\t\t\tuseMock: config.useMock ?? flags.isMockMode ?? false,\n\t\t});\n\n\t\tthis.transport = config.transport ?? createDefaultTransport();\n\t}\n\n\tprotected async request<TReturn>(\n\t\tendpoint: string,\n\t\toptions?: TOptions,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn> {\n\t\tif (this.useMock && mockHandler) {\n\t\t\treturn await mockHandler();\n\t\t}\n\n\t\tconst response = await this.transport.request(endpoint, options);\n\t\tif (!response.ok) return await this.refuse(response);\n\n\t\treturn await this.parse<TReturn>(response);\n\t}\n\n\t/**\n\t * Turns a successful response into the value the caller asked for.\n\t *\n\t * The one step that genuinely differs between request kinds.\n\t */\n\tprotected abstract parse<TReturn>(response: Response): Promise<TReturn>;\n\n\t/**\n\t * Refuses an unsuccessful response, and never returns.\n\t *\n\t * `TLankaErrorHandler` is typed `Promise<never>` — a handler must throw. It is\n\t * still CALLED and then followed by a throw, because a handler that breaks its\n\t * contract and returns would otherwise hand `undefined` back as if the request\n\t * had succeeded, and a non-value must never become a value.\n\t */\n\tprotected async refuse(response: Response): Promise<never> {\n\t\tif (this.errorHandler) {\n\t\t\tawait this.errorHandler(response);\n\t\t}\n\n\t\t// Kind `http`, not a bare Error: the server answered, and answered with a\n\t\t// code. Without the kind this reads as a network failure, and the user is\n\t\t// offered a retry of a request that already got a meaningful answer.\n\t\tthrow new LankaError({\n\t\t\tkind: \"http\",\n\t\t\tmessage: getLankaHost().httpErrorMessage(response.status),\n\t\t\tstatus: response.status,\n\t\t});\n\t}\n}\n","import type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\n\n/**\n * HTTP Fetch JSON transport implementation.\n * Uses native fetch API with JSON-specific headers.\n * Automatically sets Content-Type to application/json for requests with body.\n * For project-specific logic (auth, error handling, etc.), use `request` parameter\n * in Gateway config or create a custom transport.\n */\nexport class LankaFetchJsonTransport implements ILankaTransport<RequestInit> {\n\tasync request(resource: RequestInfo, options?: RequestInit): Promise<Response> {\n\t\t// Only set Content-Type if body exists and is not FormData\n\t\tif (options?.body && !(options.body instanceof FormData)) {\n\t\t\tconst headers = new Headers(options.headers);\n\n\t\t\t// If body is object, stringify it\n\t\t\tlet body = options.body;\n\t\t\tif (\n\t\t\t\ttypeof body === \"object\" &&\n\t\t\t\t!(body instanceof FormData) &&\n\t\t\t\t!(body instanceof Blob)\n\t\t\t) {\n\t\t\t\tbody = JSON.stringify(body);\n\t\t\t}\n\n\t\t\theaders.set(\"Content-Type\", \"application/json\");\n\n\t\t\treturn await fetch(resource, {\n\t\t\t\t...options,\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t});\n\t\t}\n\n\t\t// No body or FormData - use options as-is\n\t\treturn await fetch(resource, options);\n\t}\n}\n","import { ALankaTransportRequest } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransportRequestConfig } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\nimport { LankaFetchJsonTransport } from \"../../transport/lanka-fetch-json-transport/LankaFetchJsonTransport\";\nimport { LankaError } from \"../../../errors/lanka-error/LankaError\";\n\n/** The JSON request: parses the body, and refuses a body that is not JSON. */\n/**\n * A request kind that answers a parsed JSON body — what most endpoints return.\n *\n * A gateway holds one, and is handed it rather than constructing it, which is\n * what lets a test give the same gateway a transport that never leaves the\n * process. `createLankaFetchJsonRequest()` builds the same class.\n */\nexport class LankaFetchJsonRequest<\n\tTOptions = RequestInit,\n> extends ALankaTransportRequest<TOptions> {\n\tconstructor(config: ILankaTransportRequestConfig<TOptions> = {}) {\n\t\tsuper(config, () => new LankaFetchJsonTransport() as ILankaTransport<TOptions>);\n\t}\n\n\t/**\n\t * Parses the body, or names the failure.\n\t *\n\t * The content type is read for the ERROR MESSAGE only. Using it to choose\n\t * between two parse paths, where the second answers `{}` for any non-empty\n\t * body it cannot parse, fails silently: the caller's schema is the first thing\n\t * to notice, and the caller's SCREEN is where it shows up.\n\t *\n\t * A measured case: a dev server whose `/api` fell through to the SPA fallback\n\t * answered `200 text/html` with `index.html`. Turned into `{}`, the schema\n\t * refused it and a person read a validator's issue list on the sign-in card. A\n\t * body a JSON transport cannot parse is never a value — it is a misrouted\n\t * request, and saying so names the actual failure.\n\t */\n\tprotected async parse<TReturn>(response: Response): Promise<TReturn> {\n\t\tconst contentType = response.headers.get(\"content-type\");\n\n\t\tconst text = await response.text();\n\t\tif (!text) {\n\t\t\treturn undefined as TReturn;\n\t\t}\n\n\t\ttry {\n\t\t\treturn JSON.parse(text) as TReturn;\n\t\t} catch (error) {\n\t\t\t// `schema`, not `network`: the request arrived, the server answered, and\n\t\t\t// the answer was the wrong shape. Not cosmetic — a network failure\n\t\t\t// invites a retry, while retrying a broken contract is pointless and\n\t\t\t// blaming the user for it more so.\n\t\t\tthrow new LankaError({\n\t\t\t\tkind: \"schema\",\n\t\t\t\tmessage:\n\t\t\t\t\t`Failed to parse JSON response (content-type: ${contentType ?? \"none\"}): ` +\n\t\t\t\t\t`${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\tcause: error,\n\t\t\t});\n\t\t}\n\t}\n}\n","import { TLankaQueryParams } from \"../../_types/TLankaQueryParams\";\nimport { TLankaQueryBuilder } from \"../../_types/TLankaQueryBuilder\";\n\n/**\n * The query string a gateway sends, from the object a method was called with.\n *\n * Arrays become `key[]` repeated, nested objects become `key[inner]`: the shape\n * most JSON APIs read back without being told about it.\n *\n * Plain loops over `Object.keys` rather than `Object.entries` and `forEach`: this\n * runs on every request that carries a filter, and the pair array `entries`\n * builds — two allocations per key, thrown away immediately — is a cost with\n * nothing to show for it.\n */\nexport const buildLankaQueryParams: TLankaQueryBuilder = <T extends Record<string, unknown>>(\n\tinput: T,\n): URLSearchParams => {\n\tconst params = new URLSearchParams();\n\n\tconst append = (key: string, value: TLankaQueryParams): void => {\n\t\tif (value == null) return;\n\n\t\tif (Array.isArray(value)) {\n\t\t\t// The bracketed key once for the whole array, not once per element.\n\t\t\tconst itemKey = `${key}[]`;\n\t\t\tfor (let index = 0; index < value.length; index += 1) append(itemKey, value[index]);\n\n\t\t\treturn;\n\t\t}\n\n\t\tif (typeof value === \"object\") {\n\t\t\tconst inner = value as Record<string, TLankaQueryParams>;\n\t\t\tconst innerKeys = Object.keys(inner);\n\n\t\t\tfor (let index = 0; index < innerKeys.length; index += 1) {\n\t\t\t\tconst innerKey = innerKeys[index];\n\t\t\t\tappend(`${key}[${innerKey}]`, inner[innerKey]);\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tparams.append(key, String(value));\n\t};\n\n\tconst source = input as Record<string, TLankaQueryParams>;\n\tconst keys = Object.keys(source);\n\n\tfor (let index = 0; index < keys.length; index += 1) append(keys[index], source[keys[index]]);\n\n\treturn params;\n};\n","import type { IALankaGatewayConfig } from \"../../_interfaces/IALankaGatewayConfig\";\nimport { lankaLogger } from \"../../../logger/lanka-logger/LankaLogger\";\nimport { LankaFetchJsonRequest } from \"../../request/lanka-fetch-json-request/LankaFetchJsonRequest\";\nimport type { ILankaRequest } from \"../../_interfaces/ILankaRequest\";\nimport type { TLankaExecuteOptions } from \"../../_types/TLankaExecuteOptions\";\nimport { buildLankaQueryParams } from \"../../_utils/build-lanka-query-params/buildLankaQueryParams\";\nimport { TLankaQueryParams } from \"../../_types/TLankaQueryParams\";\nimport { TLankaQueryBuilder } from \"../../_types/TLankaQueryBuilder\";\nimport { getLankaFlags } from \"../../../config/get-lanka-flags/getLankaFlags\";\nimport { getLankaHost } from \"../../../config/get-lanka-host/getLankaHost\";\n\nexport abstract class ALankaGateway<TOptions = RequestInit> {\n\tprotected requestExecutor: ILankaRequest<TOptions>;\n\tprotected queryParamsHandler: TLankaQueryBuilder;\n\n\tprotected readonly useMock: boolean;\n\tprotected readonly basePath: string;\n\n\tprotected constructor(config: IALankaGatewayConfig<TOptions>) {\n\t\tlankaLogger.printGatewayLog(\"Create gateway\", this);\n\t\tconst flags = getLankaFlags();\n\t\tthis.useMock = config.useMock ?? flags.isMockMode ?? false;\n\n\t\t// A gateway with nothing said about transport talks JSON over `fetch`, which\n\t\t// is what almost every one of them does. Supplying a request is how a gateway\n\t\t// stops being ordinary — a raw `Response`, a multipart upload, a transport\n\t\t// that never leaves the process — and that stays a decision rather than a\n\t\t// line every gateway has to carry to be born.\n\t\tthis.requestExecutor = config.request ?? new LankaFetchJsonRequest<TOptions>();\n\n\t\tthis.basePath = config.basePath ?? \"\";\n\t\tthis.queryParamsHandler = config.queryParamsHandler ?? buildLankaQueryParams;\n\t}\n\n\t/**\n\t * Resolves endpoint for request.\n\t * - Absolute paths (starting with \"/\") are returned as-is\n\t * - Relative paths are joined with basePath\n\t * - Query-only strings like \"?a=1\" are attached to basePath\n\t */\n\tprotected endpoint(path: string = \"\"): string {\n\t\t// An absolute URL is detected BEFORE joining with `basePath`, not after:\n\t\t// otherwise `https://other.host/health` first becomes\n\t\t// `/things/https://other.host/health` and there is nothing left to detect.\n\t\tif (isAbsoluteUrl(path)) return path;\n\n\t\treturn this.withApiBase(this.resolvePath(path));\n\t}\n\n\t/**\n\t * Joins `basePath` and the method path.\n\t */\n\tprivate resolvePath(path: string): string {\n\t\tif (!path) return this.basePath;\n\n\t\tif (path.startsWith(\"/\")) return path;\n\n\t\tif (path.startsWith(\"?\")) return `${this.basePath}${path}`;\n\n\t\t// No leading-slash case here: the check above already returned for one, so\n\t\t// stripping it again was a branch no input could take — uncoverable by\n\t\t// construction, and it counted against the coverage floor that gates this\n\t\t// package.\n\t\tconst left = this.basePath.endsWith(\"/\") ? this.basePath.slice(0, -1) : this.basePath;\n\t\treturn `${left}/${path}`;\n\t}\n\n\t/**\n\t * Prefixes the API base URL from the host contract.\n\t *\n\t * Here rather than in every consumer: otherwise each consumer knows the URL\n\t * and the framework does not, and a realtime plugin would have to know a\n\t * specific application's build.\n\t *\n\t * Declaring the field and not using it would be worse than not declaring it: a\n\t * declaration nothing is built from is a second truth, free to diverge from\n\t * the first.\n\t *\n\t * An absolute URL never reaches here — `endpoint()` filters it out before the\n\t * join.\n\t */\n\tprivate withApiBase(path: string): string {\n\t\tconst base = withoutTrailingSlashes(getLankaHost().apiBaseUrl);\n\t\tif (!base) return path;\n\t\tif (!path) return base;\n\n\t\treturn path.startsWith(\"/\") ? `${base}${path}` : `${base}/${path}`;\n\t}\n\n\tprotected buildQueryParams<T extends object>(params: T): URLSearchParams {\n\t\treturn this.queryParamsHandler(params as Record<string, TLankaQueryParams>);\n\t}\n\n\tprotected async request<TReturn = unknown>(\n\t\tpath: string,\n\t\toptions?: TLankaExecuteOptions<TOptions>,\n\t\tmockHandler?: () => Promise<TReturn>,\n\t): Promise<TReturn> {\n\t\treturn this.requestExecutor.execute<TReturn>(this.endpoint(path), options, mockHandler);\n\t}\n\n\t/**\n\t * Allows to replace request implementation at runtime (e.g. feature flags / tests).\n\t * If you prefer static customization - override `request()` in a subclass.\n\t */\n\tprotected setRequest(request: ILankaRequest<TOptions>): void {\n\t\tthis.requestExecutor = request;\n\t}\n\n\tprotected setQueryParamsHandler(handler: TLankaQueryBuilder): void {\n\t\tthis.queryParamsHandler = handler;\n\t}\n}\n\n/**\n * A scheme plus `//` — a URL that already knows where it is going.\n *\n * A standalone function rather than a method: it is not about a particular\n * gateway, and `endpoint()` needs it before any joining.\n */\nfunction isAbsoluteUrl(path: string): boolean {\n\t// The cheap half first: a scheme needs `://`, and `includes` answers without\n\t// starting the regex engine. Every relative path an application writes — which\n\t// is nearly all of them — stops on this line.\n\tif (!path.includes(\"://\")) return false;\n\n\treturn /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(path);\n}\n\n/**\n * The API base without its trailing slashes, remembered between calls.\n *\n * The host answers the same string for the life of an application, and trimming\n * it is a regex replace otherwise run on every endpoint of every request. One\n * entry is enough: there is one active host, and a second framework in the same\n * process simply replaces what is remembered here.\n */\nlet lastRawBase: string | null = null;\nlet lastTrimmedBase = \"\";\n\nfunction withoutTrailingSlashes(base: string): string {\n\tif (base !== lastRawBase) {\n\t\tlastRawBase = base;\n\t\tlastTrimmedBase = base.replace(/\\/+$/, \"\");\n\t}\n\n\treturn lastTrimmedBase;\n}\n","import { ALankaGateway } from \"../../_abstractions/lanka-gateway/ALankaGateway\";\nimport type { IALankaGatewayConfig } from \"../../_interfaces/IALankaGatewayConfig\";\nimport type { ILankaGatewayContext } from \"../../_interfaces/ILankaGatewayContext\";\n\n/** What a gateway is built from, whichever style builds it. */\nexport interface ILankaGatewayConfig<\n\tTOptions,\n\tTMethods extends object,\n> extends IALankaGatewayConfig<TOptions> {\n\t/** The endpoints this gateway offers, written over its own surface. */\n\tmethods: (context: ILankaGatewayContext<TOptions>) => TMethods;\n}\n\n/**\n * A gateway, without writing a class.\n *\n * The bridge below is the whole mechanism, and it lives here rather than on the\n * base for two reasons. The language reads `protected` from inside a deriving\n * class body and nowhere else, so a factory outside the hierarchy could only\n * reach the public half — the wrong one. And a `toStyleContext` ON the base\n * would put `TOptions` in a method's parameter position, making the class\n * invariant in it: every `ALankaGateway<unknown>` the locator holds would stop\n * accepting a gateway typed for `RequestInit`.\n *\n * One implementation: what comes back is an instance of `ALankaGateway`, so a\n * behaviour fix reaches both styles at once.\n */\nexport const createLankaGateway = <TOptions, TMethods extends object>(\n\tconfig: ILankaGatewayConfig<TOptions, TMethods>,\n): TMethods => {\n\tclass FunctionalGateway extends ALankaGateway<TOptions> {\n\t\t// The base keeps a protected constructor — it is abstract, and a consumer\n\t\t// reaching for `new ALankaGateway()` would get an object with no endpoints.\n\t\t// A subclass may widen it, and this one is the subclass.\n\t\tpublic constructor(gatewayConfig: IALankaGatewayConfig<TOptions>) {\n\t\t\tsuper(gatewayConfig);\n\t\t}\n\n\t\tpublic build(): TMethods {\n\t\t\treturn config.methods({\n\t\t\t\tendpoint: (path) => this.endpoint(path),\n\t\t\t\trequest: (path, options, mockHandler) => this.request(path, options, mockHandler),\n\t\t\t\tbuildQueryParams: (params) => this.buildQueryParams(params),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn new FunctionalGateway(config).build();\n};\n","import type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\n\n/**\n * HTTP Fetch transport implementation.\n * Uses native fetch API without any project-specific decorators.\n * For project-specific logic (auth, error handling, etc.), use `request` parameter\n * in Gateway config or create a custom transport.\n */\nexport class LankaFetchTransport implements ILankaTransport<RequestInit> {\n\tasync request(resource: RequestInfo, options?: RequestInit): Promise<Response> {\n\t\treturn await fetch(resource, options);\n\t}\n}\n","import { ALankaTransportRequest } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransportRequestConfig } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\nimport { LankaFetchTransport } from \"../../transport/lanka-fetch-transport/LankaFetchTransport\";\n\n/**\n * The raw request: hands the `Response` back untouched.\n *\n * The minimal, extensible case — a caller wanting headers, a stream or a blob\n * reads them off the response itself.\n */\nexport class LankaFetchRequest<TOptions = RequestInit> extends ALankaTransportRequest<TOptions> {\n\tconstructor(config: ILankaTransportRequestConfig<TOptions> = {}) {\n\t\tsuper(config, () => new LankaFetchTransport() as ILankaTransport<TOptions>);\n\t}\n\n\tprotected parse<TReturn>(response: Response): Promise<TReturn> {\n\t\treturn Promise.resolve(response as unknown as TReturn);\n\t}\n}\n","import { LankaFetchRequest } from \"../../lanka-fetch-request/LankaFetchRequest\";\nimport type { ILankaTransportRequestConfig } from \"../../_abstractions/lanka-transport-request/ALankaTransportRequest\";\n\n/**\n * The functional style of `LankaFetchRequest`: the raw `Response`, for a download or a stream.\n *\n * One line, and that is the point — the factory IS the class, so a behaviour\n * cannot exist in one style and not the other.\n */\nexport const createLankaFetchRequest = <TOptions = RequestInit>(\n\tconfig: ILankaTransportRequestConfig<TOptions> = {},\n): LankaFetchRequest<TOptions> => new LankaFetchRequest<TOptions>(config);\n","import { LankaFetchJsonRequest } from \"../../lanka-fetch-json-request/LankaFetchJsonRequest\";\nimport type { ILankaTransportRequestConfig } from \"../../_abstractions/lanka-transport-request/ALankaTransportRequest\";\n\n/**\n * The functional style of `LankaFetchJsonRequest`: a JSON body, which is what most endpoints answer.\n *\n * One line, and that is the point — the factory IS the class, so a behaviour\n * cannot exist in one style and not the other.\n */\nexport const createLankaFetchJsonRequest = <TOptions = RequestInit>(\n\tconfig: ILankaTransportRequestConfig<TOptions> = {},\n): LankaFetchJsonRequest<TOptions> => new LankaFetchJsonRequest<TOptions>(config);\n","import type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\n\n/**\n * HTTP Fetch FormData transport implementation.\n * Uses native fetch API optimized for FormData requests.\n * Does not set Content-Type header (browser will set it automatically with boundary).\n * For project-specific logic (auth, error handling, etc.), use `request` parameter\n * in Gateway config or create a custom transport.\n */\nexport class LankaFetchFormDataTransport implements ILankaTransport<RequestInit> {\n\tasync request(resource: RequestInfo, options?: RequestInit): Promise<Response> {\n\t\tconst formDataOptions: RequestInit = { ...options };\n\n\t\t// Remove Content-Type header if body is FormData (browser will set it with boundary)\n\t\tif (formDataOptions.body instanceof FormData && formDataOptions.headers) {\n\t\t\tconst headers = new Headers(formDataOptions.headers);\n\t\t\theaders.delete(\"Content-Type\");\n\t\t\tformDataOptions.headers = headers;\n\t\t}\n\n\t\treturn await fetch(resource, formDataOptions);\n\t}\n}\n","import { ALankaTransportRequest } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransportRequestConfig } from \"../_abstractions/lanka-transport-request/ALankaTransportRequest\";\nimport type { ILankaTransport } from \"../../_interfaces/ILankaTransport\";\nimport { LankaFetchFormDataTransport } from \"../../transport/lanka-fetch-form-data-transport/LankaFetchFormDataTransport\";\n\n/**\n * The multipart request: hands the `Response` back untouched.\n *\n * Differs from `LankaFetchRequest` only in its transport — the one that must NOT\n * set `content-type`, because the browser writes it with the boundary and a\n * hand-set header leaves the body unparseable to the server.\n */\nexport class LankaFetchFormDataRequest<\n\tTOptions = RequestInit,\n> extends ALankaTransportRequest<TOptions> {\n\tconstructor(config: ILankaTransportRequestConfig<TOptions> = {}) {\n\t\tsuper(config, () => new LankaFetchFormDataTransport() as ILankaTransport<TOptions>);\n\t}\n\n\tprotected parse<TReturn>(response: Response): Promise<TReturn> {\n\t\treturn Promise.resolve(response as unknown as TReturn);\n\t}\n}\n","import { LankaFetchFormDataRequest } from \"../../lanka-fetch-form-data-request/LankaFetchFormDataRequest\";\nimport type { ILankaTransportRequestConfig } from \"../../_abstractions/lanka-transport-request/ALankaTransportRequest\";\n\n/**\n * The functional style of `LankaFetchFormDataRequest`: a multipart body, for an upload.\n *\n * One line, and that is the point — the factory IS the class, so a behaviour\n * cannot exist in one style and not the other.\n */\nexport const createLankaFetchFormDataRequest = <TOptions = RequestInit>(\n\tconfig: ILankaTransportRequestConfig<TOptions> = {},\n): LankaFetchFormDataRequest<TOptions> => new LankaFetchFormDataRequest<TOptions>(config);\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,13 +2,13 @@ export { ALankaPlugin, ILankaBootstrapConfig, ILankaInstance, ILankaInstanceConf
|
|
|
2
2
|
export { ILankaRoleFactory, ILankaRoleOpening, TLankaRoleOpener, defineLankaRole } from './role/index.js';
|
|
3
3
|
export { ILankaHostConfig, createLankaHost, getLankaFlags, getLankaHost } from './config/index.js';
|
|
4
4
|
export { I as ILankaFlags, a as ILankaHost, b as ILankaRuntimeConfig } from './ILankaRuntimeConfig-Vl436GWK.js';
|
|
5
|
-
export { I as ILankaLocatorConfig } from './LankaSharedStoreLocator-
|
|
5
|
+
export { I as ILankaLocatorConfig } from './LankaSharedStoreLocator-zS2kLu-S.js';
|
|
6
6
|
export { lankaLogger } from './logger/index.js';
|
|
7
7
|
export { I as ILankaErrorInit, L as LankaError, T as TLankaErrorKind } from './LankaError-B1HtuIkw.js';
|
|
8
|
-
import './createLankaScope-
|
|
9
|
-
import './activeRuntime-
|
|
8
|
+
import './createLankaScope-BiFxNQgl.js';
|
|
9
|
+
import './activeRuntime-DT4gB16d.js';
|
|
10
10
|
import './ILankaScenarioVM-DuCyPoyT.js';
|
|
11
|
-
import './LankaScenarioLocator-
|
|
11
|
+
import './LankaScenarioLocator-CLkq4MaJ.js';
|
|
12
12
|
import './ILankaScenarioMetadata-Bu-yggTZ.js';
|
|
13
13
|
import './ALankaGateway-ExlRGT3D.js';
|
|
14
14
|
import './lankaStandardValidator-CL-r-zEV.js';
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
createLanka,
|
|
7
7
|
resetActiveLanka,
|
|
8
8
|
startLanka
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-63ST2UKP.js";
|
|
10
|
+
import "./chunk-HZAIAGWS.js";
|
|
11
|
+
import "./chunk-MYZQYOMD.js";
|
|
12
|
+
import "./chunk-YXI4OQEV.js";
|
|
13
13
|
import {
|
|
14
14
|
createLankaHost
|
|
15
15
|
} from "./chunk-XESL274R.js";
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
import {
|
|
21
21
|
getLankaHost
|
|
22
22
|
} from "./chunk-RKYKK6MN.js";
|
|
23
|
-
import "./chunk-
|
|
23
|
+
import "./chunk-UE2C76OR.js";
|
|
24
24
|
import {
|
|
25
25
|
lankaLogger
|
|
26
26
|
} from "./chunk-C2HP7CRD.js";
|
package/dist/locator/index.d.ts
CHANGED
|
@@ -1,24 +1,15 @@
|
|
|
1
|
-
export { I as ILankaScope } from '../createLankaScope-
|
|
2
|
-
export { a as ILankaLocator, I as ILankaLocatorConfig, c as ILankaSharedStoreLocatorConfig, d as ILankaSingletonLocatorConfig } from '../LankaSharedStoreLocator-
|
|
1
|
+
export { I as ILankaScope } from '../createLankaScope-BiFxNQgl.js';
|
|
2
|
+
export { a as ILankaLocator, I as ILankaLocatorConfig, c as ILankaSharedStoreLocatorConfig, d as ILankaSingletonLocatorConfig } from '../LankaSharedStoreLocator-zS2kLu-S.js';
|
|
3
|
+
import * as GatewaysModule from '@lanka_di/Gateways';
|
|
3
4
|
import { A as ALankaGateway } from '../ALankaGateway-ExlRGT3D.js';
|
|
5
|
+
import * as ScenariosModule from '@lanka_di/Scenarios';
|
|
6
|
+
import * as SingletonsModule from '@lanka_di/Singletons';
|
|
7
|
+
import * as SharedStoresModule from '@lanka_di/SharedStores';
|
|
4
8
|
import { A as ALankaSharedStore } from '../ALankaSharedStore-B7uepuuk.js';
|
|
5
9
|
import '../lankaStandardValidator-CL-r-zEV.js';
|
|
6
10
|
import '@standard-schema/spec';
|
|
7
11
|
import 'zustand/vanilla';
|
|
8
12
|
|
|
9
|
-
/**
|
|
10
|
-
* The singletons this app publishes to `lanka`.
|
|
11
|
-
*
|
|
12
|
-
* Add one export line per class; the framework derives the locator from these
|
|
13
|
-
* exports, so there is nothing else to register.
|
|
14
|
-
*
|
|
15
|
-
* @example export { AnalyticsService } from "../src/...";
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
declare namespace SingletonsModule {
|
|
19
|
-
export { };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
13
|
/**
|
|
23
14
|
* The singleton marker: "this class is published by the application in
|
|
24
15
|
* `lankaSingletons`".
|
|
@@ -87,19 +78,6 @@ type TLankaSingletons = {
|
|
|
87
78
|
|
|
88
79
|
declare const lankaSingletons: TLankaSingletons;
|
|
89
80
|
|
|
90
|
-
/**
|
|
91
|
-
* The shared stores this app publishes to `lanka`.
|
|
92
|
-
*
|
|
93
|
-
* Add one export line per class; the framework derives the locator from these
|
|
94
|
-
* exports, so there is nothing else to register.
|
|
95
|
-
*
|
|
96
|
-
* @example export { UserSharedStore } from "../src/...";
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
|
-
declare namespace SharedStoresModule {
|
|
100
|
-
export { };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
81
|
/**
|
|
104
82
|
* Shared-store classes read from the consumer's barrel.
|
|
105
83
|
*
|
|
@@ -135,19 +113,6 @@ type TLankaSharedStores = {
|
|
|
135
113
|
*/
|
|
136
114
|
declare const lankaSharedStores: TLankaSharedStores;
|
|
137
115
|
|
|
138
|
-
/**
|
|
139
|
-
* The gateways this app publishes to `lanka`.
|
|
140
|
-
*
|
|
141
|
-
* Add one export line per class; the framework derives the locator from these
|
|
142
|
-
* exports, so there is nothing else to register.
|
|
143
|
-
*
|
|
144
|
-
* @example export { UserGateway } from "../src/...";
|
|
145
|
-
*/
|
|
146
|
-
|
|
147
|
-
declare namespace GatewaysModule {
|
|
148
|
-
export { };
|
|
149
|
-
}
|
|
150
|
-
|
|
151
116
|
/**
|
|
152
117
|
* Gateway classes read from the consumer's barrel.
|
|
153
118
|
*
|
|
@@ -190,19 +155,6 @@ type TLankaGateways = {
|
|
|
190
155
|
*/
|
|
191
156
|
declare const lankaGateways: TLankaGateways;
|
|
192
157
|
|
|
193
|
-
/**
|
|
194
|
-
* The scenarios this app publishes to `lanka`.
|
|
195
|
-
*
|
|
196
|
-
* Add one export line per class; the framework derives the locator from these
|
|
197
|
-
* exports, so there is nothing else to register.
|
|
198
|
-
*
|
|
199
|
-
* @example export { SessionScenario } from "../src/...";
|
|
200
|
-
*/
|
|
201
|
-
|
|
202
|
-
declare namespace ScenariosModule {
|
|
203
|
-
export { };
|
|
204
|
-
}
|
|
205
|
-
|
|
206
158
|
/**
|
|
207
159
|
* Scenario classes read from the consumer's barrel.
|
|
208
160
|
*
|
package/dist/locator/index.js
CHANGED
package/dist/scenario/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
lankaScenarioBootstrap
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-HZAIAGWS.js";
|
|
4
4
|
import {
|
|
5
5
|
ALankaScenario,
|
|
6
6
|
lankaEventBus
|
|
7
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-YXI4OQEV.js";
|
|
8
8
|
import "../chunk-C2HP7CRD.js";
|
|
9
9
|
import "../chunk-D27MREPB.js";
|
|
10
10
|
import "../chunk-BGVDPDX4.js";
|
package/dist/viewmodel/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import {
|
|
3
3
|
lankaScenarioBootstrap
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-HZAIAGWS.js";
|
|
5
|
+
import "../chunk-YXI4OQEV.js";
|
|
6
6
|
import {
|
|
7
7
|
lankaLogger
|
|
8
8
|
} from "../chunk-C2HP7CRD.js";
|
|
@@ -379,8 +379,10 @@ var lazySlot = (config) => {
|
|
|
379
379
|
}
|
|
380
380
|
};
|
|
381
381
|
};
|
|
382
|
+
var PROMISE_MEMBERS = /* @__PURE__ */ new Set(["then", "catch", "finally"]);
|
|
382
383
|
var forwardEveryMember = (slot) => (_target, property) => {
|
|
383
384
|
if (property === "dispose") return slot.release;
|
|
385
|
+
if (PROMISE_MEMBERS.has(property)) return void 0;
|
|
384
386
|
return (...args) => {
|
|
385
387
|
const built = slot.get();
|
|
386
388
|
const member = built[property];
|