better-effect 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +47 -15
  2. package/dist/adapters/iti.d.mts +3 -1
  3. package/dist/adapters/iti.d.mts.map +1 -1
  4. package/dist/adapters/iti.mjs +1 -2
  5. package/dist/adapters/iti.mjs.map +1 -1
  6. package/dist/context-B4yO5LaH.mjs +80 -0
  7. package/dist/context-B4yO5LaH.mjs.map +1 -0
  8. package/dist/errors-BXKc7juX.d.mts +8 -0
  9. package/dist/errors-BXKc7juX.d.mts.map +1 -0
  10. package/dist/index-BFgG9zZC.d.mts +374 -0
  11. package/dist/index-BFgG9zZC.d.mts.map +1 -0
  12. package/dist/{index-DMfjhNR_.d.mts → index-BddlcJK6.d.mts} +21 -267
  13. package/dist/index-BddlcJK6.d.mts.map +1 -0
  14. package/dist/index.d.mts +36 -77
  15. package/dist/index.d.mts.map +1 -1
  16. package/dist/index.mjs +163 -47
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/internal-identity-Cm4-KIUj.mjs +122 -0
  19. package/dist/internal-identity-Cm4-KIUj.mjs.map +1 -0
  20. package/dist/map-layer-backend-BodcEeNA.mjs +52 -0
  21. package/dist/map-layer-backend-BodcEeNA.mjs.map +1 -0
  22. package/dist/map-layer-backend-CGibcwkc.d.mts +42 -0
  23. package/dist/map-layer-backend-CGibcwkc.d.mts.map +1 -0
  24. package/dist/runtime/explicit.d.mts +18 -0
  25. package/dist/runtime/explicit.d.mts.map +1 -0
  26. package/dist/runtime/explicit.mjs +46 -0
  27. package/dist/runtime/explicit.mjs.map +1 -0
  28. package/dist/runtime/node.d.mts +13 -0
  29. package/dist/runtime/node.d.mts.map +1 -0
  30. package/dist/runtime/node.mjs +21 -0
  31. package/dist/runtime/node.mjs.map +1 -0
  32. package/dist/testing.d.mts +2 -22
  33. package/dist/testing.mjs +2 -58
  34. package/package.json +3 -1
  35. package/dist/errors-GR3K_nRu.mjs +0 -74
  36. package/dist/errors-GR3K_nRu.mjs.map +0 -1
  37. package/dist/index-DMfjhNR_.d.mts.map +0 -1
  38. package/dist/internal-identity-C6Awrc33.mjs +0 -27
  39. package/dist/internal-identity-C6Awrc33.mjs.map +0 -1
  40. package/dist/testing.d.mts.map +0 -1
  41. package/dist/testing.mjs.map +0 -1
@@ -0,0 +1,52 @@
1
+ import { l as ServiceNotFoundError, n as DuplicateServiceError, o as ServiceTagCollisionError, t as assertServiceCompatibility } from "./internal-identity-Cm4-KIUj.mjs";
2
+ //#region src/layer/map-layer-backend.ts
3
+ /** Native map-backed Layer backend used by Runtime when no adapter is supplied. */
4
+ var MapLayerBackend = class {
5
+ providers = /* @__PURE__ */ new Map();
6
+ instances = /* @__PURE__ */ new Map();
7
+ pending = /* @__PURE__ */ new Map();
8
+ /** Register a provider, rejecting duplicate or colliding Service tags. */
9
+ register(registration) {
10
+ const tag = registration.service.serviceTag;
11
+ const existing = this.providers.get(tag);
12
+ if (existing) {
13
+ if (existing.service !== registration.service) throw new ServiceTagCollisionError(existing.service, registration.service);
14
+ throw new DuplicateServiceError(registration.service);
15
+ }
16
+ this.providers.set(tag, registration);
17
+ }
18
+ /** Resolve and cache a provider instance by Service tag. */
19
+ async resolve(token) {
20
+ const tag = token.serviceTag;
21
+ const provider = this.providers.get(tag);
22
+ if (!provider) throw new ServiceNotFoundError(token);
23
+ const validate = (instance) => {
24
+ assertServiceCompatibility(token, provider.service, instance);
25
+ return instance;
26
+ };
27
+ const cached = this.instances.get(tag);
28
+ if (cached !== void 0) return validate(cached);
29
+ const pending = this.pending.get(tag);
30
+ if (pending) return validate(await pending);
31
+ const acquisition = Promise.resolve().then(() => provider.acquire()).then((instance) => {
32
+ validate(instance);
33
+ this.instances.set(tag, instance);
34
+ return instance;
35
+ }).finally(() => {
36
+ this.pending.delete(tag);
37
+ });
38
+ this.pending.set(tag, acquisition);
39
+ return validate(await acquisition);
40
+ }
41
+ /** Clear pending acquisitions, cached instances, and provider registrations. */
42
+ async disposeAll() {
43
+ if (this.pending.size > 0) await Promise.allSettled(this.pending.values());
44
+ this.instances.clear();
45
+ this.pending.clear();
46
+ this.providers.clear();
47
+ }
48
+ };
49
+ //#endregion
50
+ export { MapLayerBackend as t };
51
+
52
+ //# sourceMappingURL=map-layer-backend-BodcEeNA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-layer-backend-BodcEeNA.mjs","names":[],"sources":["../src/layer/map-layer-backend.ts"],"sourcesContent":["import { assertServiceCompatibility } from './internal-identity'\n\nimport { DuplicateServiceError, ServiceTagCollisionError } from './errors'\n\nimport type { LayerBackend } from './backend'\nimport type { LayerRegistration } from './types'\n\nimport { ServiceNotFoundError, type AnyServiceToken } from '../service'\n\ntype LayerAcquiredValue = Awaited<ReturnType<LayerRegistration['acquire']>>\n\n/** Native map-backed Layer backend used by Runtime when no adapter is supplied. */\nexport class MapLayerBackend implements LayerBackend {\n private readonly providers = new Map<string, LayerRegistration>()\n\n private readonly instances = new Map<string, LayerAcquiredValue>()\n\n private readonly pending = new Map<string, Promise<LayerAcquiredValue>>()\n\n /** Register a provider, rejecting duplicate or colliding Service tags. */\n register(registration: LayerRegistration): void {\n const tag = registration.service.serviceTag\n const existing = this.providers.get(tag)\n\n if (existing) {\n if (existing.service !== registration.service) {\n throw new ServiceTagCollisionError(existing.service, registration.service)\n }\n\n throw new DuplicateServiceError(registration.service)\n }\n\n this.providers.set(tag, registration)\n }\n\n /** Resolve and cache a provider instance by Service tag. */\n async resolve<T extends AnyServiceToken>(token: T): Promise<InstanceType<T>> {\n const tag = token.serviceTag\n const provider = this.providers.get(tag)\n\n if (!provider) {\n throw new ServiceNotFoundError(token)\n }\n\n const validate = (instance: LayerAcquiredValue): InstanceType<T> => {\n assertServiceCompatibility(token, provider.service, instance)\n\n // SAFETY: The provider and requested token share a tag, and compatibility checks verify the registered members before restoring the token-specific instance type.\n return instance as InstanceType<T>\n }\n\n const cached = this.instances.get(tag)\n\n if (cached !== undefined) {\n return validate(cached)\n }\n\n const pending = this.pending.get(tag)\n\n if (pending) {\n return validate(await pending)\n }\n\n const acquisition = Promise.resolve()\n .then(() => provider.acquire())\n .then((instance) => {\n validate(instance)\n this.instances.set(tag, instance)\n\n return instance\n })\n .finally(() => {\n this.pending.delete(tag)\n })\n\n this.pending.set(tag, acquisition)\n\n return validate(await acquisition)\n }\n\n /** Clear pending acquisitions, cached instances, and provider registrations. */\n async disposeAll(): Promise<void> {\n if (this.pending.size > 0) {\n await Promise.allSettled(this.pending.values())\n }\n\n this.instances.clear()\n this.pending.clear()\n this.providers.clear()\n }\n}\n"],"mappings":";;;AAYA,IAAa,kBAAb,MAAqD;CACnD,4BAA6B,IAAI,IAA+B;CAEhE,4BAA6B,IAAI,IAAgC;CAEjE,0BAA2B,IAAI,IAAyC;;CAGxE,SAAS,cAAuC;EAC9C,MAAM,MAAM,aAAa,QAAQ;EACjC,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,IAAI,UAAU;GACZ,IAAI,SAAS,YAAY,aAAa,SACpC,MAAM,IAAI,yBAAyB,SAAS,SAAS,aAAa,OAAO;GAG3E,MAAM,IAAI,sBAAsB,aAAa,OAAO;EACtD;EAEA,KAAK,UAAU,IAAI,KAAK,YAAY;CACtC;;CAGA,MAAM,QAAmC,OAAoC;EAC3E,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,IAAI,CAAC,UACH,MAAM,IAAI,qBAAqB,KAAK;EAGtC,MAAM,YAAY,aAAkD;GAClE,2BAA2B,OAAO,SAAS,SAAS,QAAQ;GAG5D,OAAO;EACT;EAEA,MAAM,SAAS,KAAK,UAAU,IAAI,GAAG;EAErC,IAAI,WAAW,KAAA,GACb,OAAO,SAAS,MAAM;EAGxB,MAAM,UAAU,KAAK,QAAQ,IAAI,GAAG;EAEpC,IAAI,SACF,OAAO,SAAS,MAAM,OAAO;EAG/B,MAAM,cAAc,QAAQ,QAAQ,CAAC,CAClC,WAAW,SAAS,QAAQ,CAAC,CAAC,CAC9B,MAAM,aAAa;GAClB,SAAS,QAAQ;GACjB,KAAK,UAAU,IAAI,KAAK,QAAQ;GAEhC,OAAO;EACT,CAAC,CAAC,CACD,cAAc;GACb,KAAK,QAAQ,OAAO,GAAG;EACzB,CAAC;EAEH,KAAK,QAAQ,IAAI,KAAK,WAAW;EAEjC,OAAO,SAAS,MAAM,WAAW;CACnC;;CAGA,MAAM,aAA4B;EAChC,IAAI,KAAK,QAAQ,OAAO,GACtB,MAAM,QAAQ,WAAW,KAAK,QAAQ,OAAO,CAAC;EAGhD,KAAK,UAAU,MAAM;EACrB,KAAK,QAAQ,MAAM;EACnB,KAAK,UAAU,MAAM;CACvB;AACF"}
@@ -0,0 +1,42 @@
1
+ import { F as ServiceContract, N as AnyServiceToken, O as InferYieldRequirements, P as ServiceClass, R as ServiceRequirements, a as ServiceResolver, j as ServiceRequirement } from "./index-BFgG9zZC.mjs";
2
+ //#region src/utils/types.d.ts
3
+ type MaybePromise<T> = T | PromiseLike<T>;
4
+ //#endregion
5
+ //#region src/layer/types.d.ts
6
+ /** Runtime-facing provider registration supplied by a Layer backend. */
7
+ interface LayerRegistration {
8
+ /** The class-backed Service token provided by this registration. */
9
+ readonly service: ServiceClass<any, any>;
10
+ /** Lazily acquire the Service instance; concrete types are erased at this backend boundary. */
11
+ readonly acquire: () => MaybePromise<unknown>;
12
+ }
13
+ /** Generator shape used by `Layer.gen` and `Layer.scopedGen`. */
14
+ type LayerGenerator<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown> = ServiceRequirement<unknown>> = () => AsyncGenerator<Yield, ServiceContract<InstanceType<S>>, unknown>;
15
+ /** Service requirements inferred from a provider's methods and generator. */
16
+ type LayerGeneratorRequirements<S extends ServiceClass<any, any>, Yield extends ServiceRequirement<unknown>> = ServiceRequirements<InstanceType<S>> | InferYieldRequirements<Yield>;
17
+ //#endregion
18
+ //#region src/layer/backend.d.ts
19
+ /** Runtime adapter responsible for registering, resolving, and disposing Layer providers. */
20
+ interface LayerBackend extends ServiceResolver {
21
+ /** Register one Service provider with the backend. */
22
+ register(registration: LayerRegistration): MaybePromise<void>;
23
+ /** Dispose all backend-owned instances and provider registrations. */
24
+ disposeAll(): MaybePromise<void>;
25
+ }
26
+ //#endregion
27
+ //#region src/layer/map-layer-backend.d.ts
28
+ /** Native map-backed Layer backend used by Runtime when no adapter is supplied. */
29
+ declare class MapLayerBackend implements LayerBackend {
30
+ private readonly providers;
31
+ private readonly instances;
32
+ private readonly pending;
33
+ /** Register a provider, rejecting duplicate or colliding Service tags. */
34
+ register(registration: LayerRegistration): void;
35
+ /** Resolve and cache a provider instance by Service tag. */
36
+ resolve<T extends AnyServiceToken>(token: T): Promise<InstanceType<T>>;
37
+ /** Clear pending acquisitions, cached instances, and provider registrations. */
38
+ disposeAll(): Promise<void>;
39
+ }
40
+ //#endregion
41
+ export { LayerRegistration as a, LayerGeneratorRequirements as i, LayerBackend as n, MaybePromise as o, LayerGenerator as r, MapLayerBackend as t };
42
+ //# sourceMappingURL=map-layer-backend-CGibcwkc.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map-layer-backend-CGibcwkc.d.mts","names":[],"sources":["../src/utils/types.ts","../src/layer/types.ts","../src/layer/backend.ts","../src/layer/map-layer-backend.ts"],"mappings":";;KAAY,aAAa,KAAK,IAAI,YAAY;;;;UCK7B;;WAEN,SAAS;;WAGT,eAAe;;;KAId,eACV,UAAU,wBACV,cAAc,8BAA8B,qCACpC,eAAe,OAAO,gBAAgB,aAAa;;KAGjD,2BACV,UAAU,wBACV,cAAc,+BACZ,oBAAoB,aAAa,MAAM,uBAAuB;;;;UCjBjD,qBAAqB;;EAEpC,SAAS,cAAc,oBAAoB;;EAG3C,cAAc;;;;;cCCH,2BAA2B;mBACrB;mBAEA;mBAEA;;EAGjB,SAAS,cAAc;;EAgBjB,QAAQ,UAAU,iBAAiB,OAAO,IAAI,QAAQ,aAAa;;EA6CnE,cAAc"}
@@ -0,0 +1,18 @@
1
+ import { c as RuntimeContextStorage, s as RuntimeContext } from "../index-BFgG9zZC.mjs";
2
+ import { t as RuntimeContextNotConfiguredError } from "../errors-BXKc7juX.mjs";
3
+ //#region src/runtime/explicit.d.ts
4
+ /**
5
+ * RuntimeContextStorage for hosts without transparent async context support.
6
+ *
7
+ * Context remains active until an async callback settles. Callers must avoid
8
+ * overlapping async runs on one instance; use NodeRuntimeContextStorage when
9
+ * concurrent async branches need isolation.
10
+ */
11
+ declare class ExplicitRuntimeContextStorage implements RuntimeContextStorage {
12
+ private context;
13
+ run<A>(context: RuntimeContext, program: () => A): A;
14
+ current(): RuntimeContext;
15
+ }
16
+ //#endregion
17
+ export { ExplicitRuntimeContextStorage, type RuntimeContext, RuntimeContextNotConfiguredError, type RuntimeContextStorage };
18
+ //# sourceMappingURL=explicit.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explicit.d.mts","names":[],"sources":["../../src/runtime/explicit.ts"],"mappings":";;;;;;;;;;cAgBa,yCAAyC;UAC5C;EAER,IAAI,GAAG,SAAS,gBAAgB,eAAe,IAAI;EAkCnD,WAAW"}
@@ -0,0 +1,46 @@
1
+ import { c as RuntimeContextNotConfiguredError, s as withActiveRuntimeContextStorage } from "../context-B4yO5LaH.mjs";
2
+ //#region src/runtime/explicit.ts
3
+ const isPromiseLike = (value) => Object(value) === value && "then" in Object(value);
4
+ /**
5
+ * RuntimeContextStorage for hosts without transparent async context support.
6
+ *
7
+ * Context remains active until an async callback settles. Callers must avoid
8
+ * overlapping async runs on one instance; use NodeRuntimeContextStorage when
9
+ * concurrent async branches need isolation.
10
+ */
11
+ var ExplicitRuntimeContextStorage = class {
12
+ context;
13
+ run(context, program) {
14
+ return withActiveRuntimeContextStorage(this, () => {
15
+ const previous = this.context;
16
+ this.context = context;
17
+ let value;
18
+ try {
19
+ value = program();
20
+ } catch (cause) {
21
+ this.context = previous;
22
+ throw cause;
23
+ }
24
+ if (!isPromiseLike(value)) {
25
+ this.context = previous;
26
+ return value;
27
+ }
28
+ return Promise.resolve(value).then((resolved) => {
29
+ this.context = previous;
30
+ return resolved;
31
+ }, (cause) => {
32
+ this.context = previous;
33
+ throw cause;
34
+ });
35
+ });
36
+ }
37
+ current() {
38
+ const context = this.context;
39
+ if (!context) throw new RuntimeContextNotConfiguredError();
40
+ return context;
41
+ }
42
+ };
43
+ //#endregion
44
+ export { ExplicitRuntimeContextStorage, RuntimeContextNotConfiguredError };
45
+
46
+ //# sourceMappingURL=explicit.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explicit.mjs","names":[],"sources":["../../src/runtime/explicit.ts"],"sourcesContent":["import { RuntimeContextNotConfiguredError } from './errors'\n\nimport { withActiveRuntimeContextStorage } from './context'\n\nimport type { RuntimeContext, RuntimeContextStorage } from './context'\n\nconst isPromiseLike = <A>(value: A): value is A & PromiseLike<unknown> =>\n Object(value) === value && 'then' in Object(value)\n\n/**\n * RuntimeContextStorage for hosts without transparent async context support.\n *\n * Context remains active until an async callback settles. Callers must avoid\n * overlapping async runs on one instance; use NodeRuntimeContextStorage when\n * concurrent async branches need isolation.\n */\nexport class ExplicitRuntimeContextStorage implements RuntimeContextStorage {\n private context: RuntimeContext | undefined\n\n run<A>(context: RuntimeContext, program: () => A): A {\n return withActiveRuntimeContextStorage(this, () => {\n const previous = this.context\n this.context = context\n\n let value: A\n\n try {\n value = program()\n } catch (cause) {\n this.context = previous\n throw cause\n }\n\n if (!isPromiseLike(value)) {\n this.context = previous\n return value\n }\n\n // ponytail: one mutable slot keeps the explicit adapter tiny; use a host-provided async context for concurrent branches.\n // SAFETY: PromiseLike values are normalized only to restore the storage after settlement; the public generic retains the callback's awaited shape.\n return Promise.resolve(value).then(\n (resolved) => {\n this.context = previous\n return resolved\n },\n (cause) => {\n this.context = previous\n throw cause\n }\n ) as A\n })\n }\n\n current(): RuntimeContext {\n const context = this.context\n\n if (!context) {\n throw new RuntimeContextNotConfiguredError()\n }\n\n return context\n }\n}\n\nexport { RuntimeContextNotConfiguredError } from './errors'\n\nexport type { RuntimeContext, RuntimeContextStorage } from './context'\n"],"mappings":";;AAMA,MAAM,iBAAoB,UACxB,OAAO,KAAK,MAAM,SAAS,UAAU,OAAO,KAAK;;;;;;;;AASnD,IAAa,gCAAb,MAA4E;CAC1E;CAEA,IAAO,SAAyB,SAAqB;EACnD,OAAO,gCAAgC,YAAY;GACjD,MAAM,WAAW,KAAK;GACtB,KAAK,UAAU;GAEf,IAAI;GAEJ,IAAI;IACF,QAAQ,QAAQ;GAClB,SAAS,OAAO;IACd,KAAK,UAAU;IACf,MAAM;GACR;GAEA,IAAI,CAAC,cAAc,KAAK,GAAG;IACzB,KAAK,UAAU;IACf,OAAO;GACT;GAIA,OAAO,QAAQ,QAAQ,KAAK,CAAC,CAAC,MAC3B,aAAa;IACZ,KAAK,UAAU;IACf,OAAO;GACT,IACC,UAAU;IACT,KAAK,UAAU;IACf,MAAM;GACR,CACF;EACF,CAAC;CACH;CAEA,UAA0B;EACxB,MAAM,UAAU,KAAK;EAErB,IAAI,CAAC,SACH,MAAM,IAAI,iCAAiC;EAG7C,OAAO;CACT;AACF"}
@@ -0,0 +1,13 @@
1
+ import { c as RuntimeContextStorage, s as RuntimeContext } from "../index-BFgG9zZC.mjs";
2
+ import { t as RuntimeContextNotConfiguredError } from "../errors-BXKc7juX.mjs";
3
+ //#region src/runtime/node.d.ts
4
+ /** RuntimeContextStorage backed by Node/Bun async context propagation. */
5
+ declare class NodeRuntimeContextStorage implements RuntimeContextStorage {
6
+ run<A>(context: RuntimeContext, program: () => A): A;
7
+ current(): RuntimeContext;
8
+ }
9
+ /** Shared Node/Bun storage used by the compatibility APIs and default Runtime. */
10
+ declare const nodeRuntimeContextStorage: NodeRuntimeContextStorage;
11
+ //#endregion
12
+ export { NodeRuntimeContextStorage, type RuntimeContext, RuntimeContextNotConfiguredError, type RuntimeContextStorage, nodeRuntimeContextStorage };
13
+ //# sourceMappingURL=node.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.mts","names":[],"sources":["../../src/runtime/node.ts"],"mappings":";;;;cAWa,qCAAqC;EAChD,IAAI,GAAG,SAAS,gBAAgB,eAAe,IAAI;EAInD,WAAW;;;cAYA,2BAAyB"}
@@ -0,0 +1,21 @@
1
+ import { c as RuntimeContextNotConfiguredError, s as withActiveRuntimeContextStorage } from "../context-B4yO5LaH.mjs";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+ //#region src/runtime/node.ts
4
+ const storage = new AsyncLocalStorage();
5
+ /** RuntimeContextStorage backed by Node/Bun async context propagation. */
6
+ var NodeRuntimeContextStorage = class {
7
+ run(context, program) {
8
+ return withActiveRuntimeContextStorage(this, () => storage.run(context, program));
9
+ }
10
+ current() {
11
+ const context = storage.getStore();
12
+ if (!context) throw new RuntimeContextNotConfiguredError();
13
+ return context;
14
+ }
15
+ };
16
+ /** Shared Node/Bun storage used by the compatibility APIs and default Runtime. */
17
+ const nodeRuntimeContextStorage = new NodeRuntimeContextStorage();
18
+ //#endregion
19
+ export { NodeRuntimeContextStorage, RuntimeContextNotConfiguredError, nodeRuntimeContextStorage };
20
+
21
+ //# sourceMappingURL=node.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.mjs","names":[],"sources":["../../src/runtime/node.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\n\nimport { RuntimeContextNotConfiguredError } from './errors'\n\nimport { withActiveRuntimeContextStorage } from './context'\n\nimport type { RuntimeContext, RuntimeContextStorage } from './context'\n\nconst storage = new AsyncLocalStorage<RuntimeContext>()\n\n/** RuntimeContextStorage backed by Node/Bun async context propagation. */\nexport class NodeRuntimeContextStorage implements RuntimeContextStorage {\n run<A>(context: RuntimeContext, program: () => A): A {\n return withActiveRuntimeContextStorage(this, () => storage.run(context, program))\n }\n\n current(): RuntimeContext {\n const context = storage.getStore()\n\n if (!context) {\n throw new RuntimeContextNotConfiguredError()\n }\n\n return context\n }\n}\n\n/** Shared Node/Bun storage used by the compatibility APIs and default Runtime. */\nexport const nodeRuntimeContextStorage = new NodeRuntimeContextStorage()\n\nexport { RuntimeContextNotConfiguredError } from './errors'\n\nexport type { RuntimeContext, RuntimeContextStorage } from './context'\n"],"mappings":";;;AAQA,MAAM,UAAU,IAAI,kBAAkC;;AAGtD,IAAa,4BAAb,MAAwE;CACtE,IAAO,SAAyB,SAAqB;EACnD,OAAO,gCAAgC,YAAY,QAAQ,IAAI,SAAS,OAAO,CAAC;CAClF;CAEA,UAA0B;EACxB,MAAM,UAAU,QAAQ,SAAS;EAEjC,IAAI,CAAC,SACH,MAAM,IAAI,iCAAiC;EAG7C,OAAO;CACT;AACF;;AAGA,MAAa,4BAA4B,IAAI,0BAA0B"}
@@ -1,22 +1,2 @@
1
- import { d as LayerRegistration, t as LayerBackend, z as AnyServiceToken } from "./index-DMfjhNR_.mjs";
2
- //#region src/testing/memory-layer-backend.d.ts
3
- /**
4
- * In-memory Layer backend for tests and small local programs.
5
- *
6
- * Providers are lazy, instances are cached by Service tag, and all cached
7
- * state is cleared by `disposeAll()`.
8
- */
9
- declare class MemoryLayerBackend implements LayerBackend {
10
- private readonly providers;
11
- private readonly instances;
12
- private readonly pending;
13
- /** Register a provider, rejecting duplicate or colliding Service tags. */
14
- register(registration: LayerRegistration): void;
15
- /** Resolve and cache a provider instance by Service tag. */
16
- resolve<T extends AnyServiceToken>(token: T): Promise<InstanceType<T>>;
17
- /** Clear pending acquisitions, cached instances, and provider registrations. */
18
- disposeAll(): Promise<void>;
19
- }
20
- //#endregion
21
- export { MemoryLayerBackend };
22
- //# sourceMappingURL=testing.d.mts.map
1
+ import { t as MapLayerBackend } from "./map-layer-backend-CGibcwkc.mjs";
2
+ export { MapLayerBackend as MemoryLayerBackend };
package/dist/testing.mjs CHANGED
@@ -1,58 +1,2 @@
1
- import { a as ServiceTagCollisionError, o as ServiceNotFoundError, t as DuplicateServiceError } from "./errors-GR3K_nRu.mjs";
2
- import { t as assertServiceCompatibility } from "./internal-identity-C6Awrc33.mjs";
3
- //#region src/testing/memory-layer-backend.ts
4
- /**
5
- * In-memory Layer backend for tests and small local programs.
6
- *
7
- * Providers are lazy, instances are cached by Service tag, and all cached
8
- * state is cleared by `disposeAll()`.
9
- */
10
- var MemoryLayerBackend = class {
11
- providers = /* @__PURE__ */ new Map();
12
- instances = /* @__PURE__ */ new Map();
13
- pending = /* @__PURE__ */ new Map();
14
- /** Register a provider, rejecting duplicate or colliding Service tags. */
15
- register(registration) {
16
- const tag = registration.service.serviceTag;
17
- const existing = this.providers.get(tag);
18
- if (existing) {
19
- if (existing.service !== registration.service) throw new ServiceTagCollisionError(existing.service, registration.service);
20
- throw new DuplicateServiceError(registration.service);
21
- }
22
- this.providers.set(tag, registration);
23
- }
24
- /** Resolve and cache a provider instance by Service tag. */
25
- async resolve(token) {
26
- const tag = token.serviceTag;
27
- const provider = this.providers.get(tag);
28
- if (!provider) throw new ServiceNotFoundError(token);
29
- const validate = (instance) => {
30
- assertServiceCompatibility(token, provider.service, instance);
31
- return instance;
32
- };
33
- const cached = this.instances.get(tag);
34
- if (cached !== void 0) return validate(cached);
35
- const pending = this.pending.get(tag);
36
- if (pending) return validate(await pending);
37
- const acquisition = Promise.resolve(provider.acquire()).then((instance) => {
38
- validate(instance);
39
- this.instances.set(tag, instance);
40
- return instance;
41
- }).finally(() => {
42
- this.pending.delete(tag);
43
- });
44
- this.pending.set(tag, acquisition);
45
- return validate(await acquisition);
46
- }
47
- /** Clear pending acquisitions, cached instances, and provider registrations. */
48
- async disposeAll() {
49
- if (this.pending.size > 0) await Promise.allSettled(this.pending.values());
50
- this.instances.clear();
51
- this.pending.clear();
52
- this.providers.clear();
53
- }
54
- };
55
- //#endregion
56
- export { MemoryLayerBackend };
57
-
58
- //# sourceMappingURL=testing.mjs.map
1
+ import { t as MapLayerBackend } from "./map-layer-backend-BodcEeNA.mjs";
2
+ export { MapLayerBackend as MemoryLayerBackend };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-effect",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Effect-inspired application architecture for better-result with typechecked Services and environments, scoped resource lifetimes, and pluggable DI backends.",
5
5
  "keywords": [
6
6
  "better-result",
@@ -28,6 +28,8 @@
28
28
  "exports": {
29
29
  ".": "./dist/index.mjs",
30
30
  "./adapters/iti": "./dist/adapters/iti.mjs",
31
+ "./runtime/explicit": "./dist/runtime/explicit.mjs",
32
+ "./runtime/node": "./dist/runtime/node.mjs",
31
33
  "./testing": "./dist/testing.mjs",
32
34
  "./package.json": "./package.json"
33
35
  },
@@ -1,74 +0,0 @@
1
- //#region src/service/errors.ts
2
- /** Thrown when a Service is accessed without an active runtime resolver. */
3
- var ServiceRuntimeNotConfiguredError = class extends Error {
4
- constructor() {
5
- super("No ServiceResolver is available in the current runtime context");
6
- this.name = "ServiceRuntimeNotConfiguredError";
7
- }
8
- };
9
- /** Thrown when a runtime has no provider for the requested Service tag. */
10
- var ServiceNotFoundError = class extends Error {
11
- service;
12
- constructor(service) {
13
- super(`Service "${service.serviceTag}" was not provided`);
14
- this.service = service;
15
- this.name = "ServiceNotFoundError";
16
- }
17
- };
18
- //#endregion
19
- //#region src/layer/errors.ts
20
- /** Thrown when a Layer registers the same Service tag more than once. */
21
- var DuplicateServiceError = class extends Error {
22
- service;
23
- constructor(service) {
24
- super(`Duplicate service tag "${service.serviceTag}"`);
25
- this.service = service;
26
- this.name = "DuplicateServiceError";
27
- }
28
- };
29
- /** Thrown when one Service tag is associated with incompatible constructors. */
30
- var ServiceTagCollisionError = class extends Error {
31
- existing;
32
- incoming;
33
- constructor(existing, incoming) {
34
- super(`Service tag "${incoming.serviceTag}" is already associated with "${existing.name}" and cannot be associated with "${incoming.name}"`);
35
- this.existing = existing;
36
- this.incoming = incoming;
37
- this.name = "ServiceTagCollisionError";
38
- }
39
- };
40
- /** Thrown when a backend fails while registering a Layer provider. */
41
- var LayerRegistrationError = class extends Error {
42
- service;
43
- registrationCause;
44
- cleanupCause;
45
- constructor(service, registrationCause, cleanupCause) {
46
- super(service ? `Failed to register service "${service.serviceTag}"` : "Failed to build Layer", { cause: registrationCause });
47
- this.service = service;
48
- this.registrationCause = registrationCause;
49
- this.cleanupCause = cleanupCause;
50
- this.name = "LayerRegistrationError";
51
- }
52
- };
53
- /** Thrown when one or more Layer-owned resources fail during disposal. */
54
- var LayerDisposeError = class extends Error {
55
- causes;
56
- constructor(causes) {
57
- super(`Failed to dispose Layer (${causes.length} error${causes.length === 1 ? "" : "s"})`);
58
- this.causes = causes;
59
- this.name = "LayerDisposeError";
60
- }
61
- };
62
- /** Thrown when a Layer generator yields a value other than a Service requirement. */
63
- var LayerGeneratorYieldError = class extends Error {
64
- service;
65
- constructor(service) {
66
- super(`Layer.gen("${service.serviceTag}") yielded an unsupported value`);
67
- this.service = service;
68
- this.name = "LayerGeneratorYieldError";
69
- }
70
- };
71
- //#endregion
72
- export { ServiceTagCollisionError as a, LayerRegistrationError as i, LayerDisposeError as n, ServiceNotFoundError as o, LayerGeneratorYieldError as r, ServiceRuntimeNotConfiguredError as s, DuplicateServiceError as t };
73
-
74
- //# sourceMappingURL=errors-GR3K_nRu.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-GR3K_nRu.mjs","names":[],"sources":["../src/service/errors.ts","../src/layer/errors.ts"],"sourcesContent":["import type { AnyServiceToken } from './types'\n\n/** Thrown when a Service is accessed without an active runtime resolver. */\nexport class ServiceRuntimeNotConfiguredError extends Error {\n constructor() {\n super('No ServiceResolver is available in the current runtime context')\n\n this.name = 'ServiceRuntimeNotConfiguredError'\n }\n}\n\n/** Thrown when a runtime has no provider for the requested Service tag. */\nexport class ServiceNotFoundError extends Error {\n constructor(readonly service: AnyServiceToken) {\n super(`Service \"${service.serviceTag}\" was not provided`)\n\n this.name = 'ServiceNotFoundError'\n }\n}\n","import type { AnyServiceToken, ServiceClass } from '../service'\nimport type { ScopeOutcome } from '../scope'\n\ntype LayerCause = Extract<ScopeOutcome, { readonly status: 'failure' }>['cause']\n\n/** Thrown when a Layer registers the same Service tag more than once. */\nexport class DuplicateServiceError extends Error {\n constructor(readonly service: ServiceClass<any>) {\n super(`Duplicate service tag \"${service.serviceTag}\"`)\n\n this.name = 'DuplicateServiceError'\n }\n}\n\n/** Thrown when one Service tag is associated with incompatible constructors. */\nexport class ServiceTagCollisionError extends Error {\n constructor(\n readonly existing: AnyServiceToken,\n readonly incoming: AnyServiceToken\n ) {\n super(\n `Service tag \"${incoming.serviceTag}\" is already associated with \"${existing.name}\" ` +\n `and cannot be associated with \"${incoming.name}\"`\n )\n\n this.name = 'ServiceTagCollisionError'\n }\n}\n\n/** Thrown when a backend fails while registering a Layer provider. */\nexport class LayerRegistrationError extends Error {\n constructor(\n readonly service: ServiceClass<any> | undefined,\n readonly registrationCause: LayerCause,\n readonly cleanupCause?: LayerCause\n ) {\n super(\n service ? `Failed to register service \"${service.serviceTag}\"` : 'Failed to build Layer',\n {\n cause: registrationCause\n }\n )\n\n this.name = 'LayerRegistrationError'\n }\n}\n\n/** Thrown when one or more Layer-owned resources fail during disposal. */\nexport class LayerDisposeError extends Error {\n constructor(readonly causes: readonly unknown[]) {\n super(`Failed to dispose Layer (${causes.length} error${causes.length === 1 ? '' : 's'})`)\n\n this.name = 'LayerDisposeError'\n }\n}\n\n/** Thrown when a Layer generator yields a value other than a Service requirement. */\nexport class LayerGeneratorYieldError extends Error {\n constructor(readonly service: ServiceClass<any>) {\n super(`Layer.gen(\"${service.serviceTag}\") yielded an unsupported value`)\n\n this.name = 'LayerGeneratorYieldError'\n }\n}\n"],"mappings":";;AAGA,IAAa,mCAAb,cAAsD,MAAM;CAC1D,cAAc;EACZ,MAAM,gEAAgE;EAEtE,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,uBAAb,cAA0C,MAAM;CACzB;CAArB,YAAY,SAAmC;EAC7C,MAAM,YAAY,QAAQ,WAAW,mBAAmB;EADrC,KAAA,UAAA;EAGnB,KAAK,OAAO;CACd;AACF;;;;ACZA,IAAa,wBAAb,cAA2C,MAAM;CAC1B;CAArB,YAAY,SAAqC;EAC/C,MAAM,0BAA0B,QAAQ,WAAW,EAAE;EADlC,KAAA,UAAA;EAGnB,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,2BAAb,cAA8C,MAAM;CAEvC;CACA;CAFX,YACE,UACA,UACA;EACA,MACE,gBAAgB,SAAS,WAAW,gCAAgC,SAAS,KAAK,mCAC9C,SAAS,KAAK,EACpD;EANS,KAAA,WAAA;EACA,KAAA,WAAA;EAOT,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,yBAAb,cAA4C,MAAM;CAErC;CACA;CACA;CAHX,YACE,SACA,mBACA,cACA;EACA,MACE,UAAU,+BAA+B,QAAQ,WAAW,KAAK,yBACjE,EACE,OAAO,kBACT,CACF;EATS,KAAA,UAAA;EACA,KAAA,oBAAA;EACA,KAAA,eAAA;EAST,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,oBAAb,cAAuC,MAAM;CACtB;CAArB,YAAY,QAAqC;EAC/C,MAAM,4BAA4B,OAAO,OAAO,QAAQ,OAAO,WAAW,IAAI,KAAK,IAAI,EAAE;EADtE,KAAA,SAAA;EAGnB,KAAK,OAAO;CACd;AACF;;AAGA,IAAa,2BAAb,cAA8C,MAAM;CAC7B;CAArB,YAAY,SAAqC;EAC/C,MAAM,cAAc,QAAQ,WAAW,gCAAgC;EADpD,KAAA,UAAA;EAGnB,KAAK,OAAO;CACd;AACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DMfjhNR_.d.mts","names":[],"sources":["../src/service/types.ts","../src/effect/types.ts","../src/service/service.ts","../src/service/runtime.ts","../src/service/errors.ts","../src/scope/errors.ts","../src/scope/types.ts","../src/internal/variance.ts","../src/utils/types.ts","../src/internal/missing-dependencies.ts","../src/layer/metadata.ts","../src/layer/inference.ts","../src/layer/types.ts","../src/layer/layer.ts","../src/layer/errors.ts","../src/runtime/outcome.ts","../src/layer/backend.ts"],"mappings":"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"}
@@ -1,27 +0,0 @@
1
- import { a as ServiceTagCollisionError } from "./errors-GR3K_nRu.mjs";
2
- //#region src/layer/internal-identity.ts
3
- const serviceMemberNames = (token) => {
4
- const names = /* @__PURE__ */ new Set();
5
- let prototype = token.prototype;
6
- while (prototype && prototype !== Object.prototype) {
7
- for (const name of Object.getOwnPropertyNames(prototype)) if (name !== "constructor") names.add(name);
8
- for (const symbol of Object.getOwnPropertySymbols(prototype)) names.add(symbol);
9
- prototype = Object.getPrototypeOf(prototype);
10
- }
11
- return [...names];
12
- };
13
- /**
14
- * Check the runtime portion of a same-tag association before returning it.
15
- * TypeScript remains authoritative for full structural compatibility; this
16
- * check catches the common incompatible-method collision after erasure.
17
- */
18
- const assertServiceCompatibility = (requested, registered, instance) => {
19
- if (requested === registered || requested.serviceTag !== registered.serviceTag) return;
20
- const candidate = Object(instance);
21
- if (candidate !== instance) throw new ServiceTagCollisionError(registered, requested);
22
- for (const name of serviceMemberNames(requested)) if (!(name in candidate)) throw new ServiceTagCollisionError(registered, requested);
23
- };
24
- //#endregion
25
- export { assertServiceCompatibility as t };
26
-
27
- //# sourceMappingURL=internal-identity-C6Awrc33.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-identity-C6Awrc33.mjs","names":[],"sources":["../src/layer/internal-identity.ts"],"sourcesContent":["import type { AnyServiceToken } from '../service'\n\nimport { ServiceTagCollisionError } from './errors'\n\nimport type { LayerRegistration } from './types'\n\ntype LayerAcquiredValue = Awaited<ReturnType<LayerRegistration['acquire']>>\n\nconst serviceMemberNames = (token: AnyServiceToken): readonly (string | symbol)[] => {\n const names = new Set<string | symbol>()\n let prototype = token.prototype\n\n while (prototype && prototype !== Object.prototype) {\n for (const name of Object.getOwnPropertyNames(prototype)) {\n if (name !== 'constructor') {\n names.add(name)\n }\n }\n\n for (const symbol of Object.getOwnPropertySymbols(prototype)) {\n names.add(symbol)\n }\n\n prototype = Object.getPrototypeOf(prototype)\n }\n\n return [...names]\n}\n\n/**\n * Check the runtime portion of a same-tag association before returning it.\n * TypeScript remains authoritative for full structural compatibility; this\n * check catches the common incompatible-method collision after erasure.\n */\nexport const assertServiceCompatibility = (\n requested: AnyServiceToken,\n registered: AnyServiceToken,\n instance: LayerAcquiredValue\n): void => {\n if (requested === registered || requested.serviceTag !== registered.serviceTag) {\n return\n }\n\n const candidate = Object(instance)\n\n // SAFETY: Service providers are object instances; Object() lets this runtime boundary reject rogue primitive values without trusting their static type.\n if (candidate !== instance) {\n throw new ServiceTagCollisionError(registered, requested)\n }\n\n for (const name of serviceMemberNames(requested)) {\n if (!(name in candidate)) {\n throw new ServiceTagCollisionError(registered, requested)\n }\n }\n}\n"],"mappings":";;AAQA,MAAM,sBAAsB,UAAyD;CACnF,MAAM,wBAAQ,IAAI,IAAqB;CACvC,IAAI,YAAY,MAAM;CAEtB,OAAO,aAAa,cAAc,OAAO,WAAW;EAClD,KAAK,MAAM,QAAQ,OAAO,oBAAoB,SAAS,GACrD,IAAI,SAAS,eACX,MAAM,IAAI,IAAI;EAIlB,KAAK,MAAM,UAAU,OAAO,sBAAsB,SAAS,GACzD,MAAM,IAAI,MAAM;EAGlB,YAAY,OAAO,eAAe,SAAS;CAC7C;CAEA,OAAO,CAAC,GAAG,KAAK;AAClB;;;;;;AAOA,MAAa,8BACX,WACA,YACA,aACS;CACT,IAAI,cAAc,cAAc,UAAU,eAAe,WAAW,YAClE;CAGF,MAAM,YAAY,OAAO,QAAQ;CAGjC,IAAI,cAAc,UAChB,MAAM,IAAI,yBAAyB,YAAY,SAAS;CAG1D,KAAK,MAAM,QAAQ,mBAAmB,SAAS,GAC7C,IAAI,EAAE,QAAQ,YACZ,MAAM,IAAI,yBAAyB,YAAY,SAAS;AAG9D"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"testing.d.mts","names":[],"sources":["../src/testing/memory-layer-backend.ts"],"mappings":";;;;;;;;cAmBa,8BAA8B;mBACxB;mBAEA;mBAEA;;EAGjB,SAAS,cAAc;;EAgBjB,QAAQ,UAAU,iBAAiB,OAAO,IAAI,QAAQ,aAAa;;EA4CnE,cAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"testing.mjs","names":[],"sources":["../src/testing/memory-layer-backend.ts"],"sourcesContent":["import {\n DuplicateServiceError,\n ServiceTagCollisionError,\n type LayerBackend,\n type LayerRegistration\n} from '../layer'\n\nimport { ServiceNotFoundError, type AnyServiceToken } from '../service'\n\nimport { assertServiceCompatibility } from '../layer/internal-identity'\n\ntype LayerAcquiredValue = Awaited<ReturnType<LayerRegistration['acquire']>>\n\n/**\n * In-memory Layer backend for tests and small local programs.\n *\n * Providers are lazy, instances are cached by Service tag, and all cached\n * state is cleared by `disposeAll()`.\n */\nexport class MemoryLayerBackend implements LayerBackend {\n private readonly providers = new Map<string, LayerRegistration>()\n\n private readonly instances = new Map<string, LayerAcquiredValue>()\n\n private readonly pending = new Map<string, Promise<LayerAcquiredValue>>()\n\n /** Register a provider, rejecting duplicate or colliding Service tags. */\n register(registration: LayerRegistration): void {\n const tag = registration.service.serviceTag\n const existing = this.providers.get(tag)\n\n if (existing) {\n if (existing.service !== registration.service) {\n throw new ServiceTagCollisionError(existing.service, registration.service)\n }\n\n throw new DuplicateServiceError(registration.service)\n }\n\n this.providers.set(tag, registration)\n }\n\n /** Resolve and cache a provider instance by Service tag. */\n async resolve<T extends AnyServiceToken>(token: T): Promise<InstanceType<T>> {\n const tag = token.serviceTag\n const provider = this.providers.get(tag)\n\n if (!provider) {\n throw new ServiceNotFoundError(token)\n }\n\n const validate = (instance: LayerAcquiredValue): InstanceType<T> => {\n assertServiceCompatibility(token, provider.service, instance)\n\n // SAFETY: The provider and requested token share a tag, and compatibility checks verify the registered members before restoring the token-specific instance type.\n return instance as InstanceType<T>\n }\n\n const cached = this.instances.get(tag)\n\n if (cached !== undefined) {\n return validate(cached)\n }\n\n const pending = this.pending.get(tag)\n\n if (pending) {\n return validate(await pending)\n }\n\n const acquisition = Promise.resolve(provider.acquire())\n .then((instance) => {\n validate(instance)\n this.instances.set(tag, instance)\n\n return instance\n })\n .finally(() => {\n this.pending.delete(tag)\n })\n\n this.pending.set(tag, acquisition)\n\n return validate(await acquisition)\n }\n\n /** Clear pending acquisitions, cached instances, and provider registrations. */\n async disposeAll(): Promise<void> {\n if (this.pending.size > 0) {\n await Promise.allSettled(this.pending.values())\n }\n\n this.instances.clear()\n this.pending.clear()\n this.providers.clear()\n }\n}\n"],"mappings":";;;;;;;;;AAmBA,IAAa,qBAAb,MAAwD;CACtD,4BAA6B,IAAI,IAA+B;CAEhE,4BAA6B,IAAI,IAAgC;CAEjE,0BAA2B,IAAI,IAAyC;;CAGxE,SAAS,cAAuC;EAC9C,MAAM,MAAM,aAAa,QAAQ;EACjC,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,IAAI,UAAU;GACZ,IAAI,SAAS,YAAY,aAAa,SACpC,MAAM,IAAI,yBAAyB,SAAS,SAAS,aAAa,OAAO;GAG3E,MAAM,IAAI,sBAAsB,aAAa,OAAO;EACtD;EAEA,KAAK,UAAU,IAAI,KAAK,YAAY;CACtC;;CAGA,MAAM,QAAmC,OAAoC;EAC3E,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,IAAI,CAAC,UACH,MAAM,IAAI,qBAAqB,KAAK;EAGtC,MAAM,YAAY,aAAkD;GAClE,2BAA2B,OAAO,SAAS,SAAS,QAAQ;GAG5D,OAAO;EACT;EAEA,MAAM,SAAS,KAAK,UAAU,IAAI,GAAG;EAErC,IAAI,WAAW,KAAA,GACb,OAAO,SAAS,MAAM;EAGxB,MAAM,UAAU,KAAK,QAAQ,IAAI,GAAG;EAEpC,IAAI,SACF,OAAO,SAAS,MAAM,OAAO;EAG/B,MAAM,cAAc,QAAQ,QAAQ,SAAS,QAAQ,CAAC,CAAC,CACpD,MAAM,aAAa;GAClB,SAAS,QAAQ;GACjB,KAAK,UAAU,IAAI,KAAK,QAAQ;GAEhC,OAAO;EACT,CAAC,CAAC,CACD,cAAc;GACb,KAAK,QAAQ,OAAO,GAAG;EACzB,CAAC;EAEH,KAAK,QAAQ,IAAI,KAAK,WAAW;EAEjC,OAAO,SAAS,MAAM,WAAW;CACnC;;CAGA,MAAM,aAA4B;EAChC,IAAI,KAAK,QAAQ,OAAO,GACtB,MAAM,QAAQ,WAAW,KAAK,QAAQ,OAAO,CAAC;EAGhD,KAAK,UAAU,MAAM;EACrB,KAAK,QAAQ,MAAM;EACnB,KAAK,UAAU,MAAM;CACvB;AACF"}