better-effect 0.3.0 → 0.5.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.
@@ -1,13 +1,21 @@
1
- import { U as AnyServiceToken, b as LayerProvider, r as LayerBackend } from "../index-Bg6ofRE1.mjs";
1
+ import { V as AnyServiceToken, t as LayerBackend, v as LayerRegistration } from "../index-D77AvuBl.mjs";
2
2
  //#region src/adapters/iti.d.ts
3
+ /**
4
+ * ITI-backed Layer backend.
5
+ *
6
+ * Install `iti` as the optional peer dependency and pass an instance to
7
+ * `Runtime.make` when using ITI's container implementation.
8
+ */
3
9
  declare class ItiLayerBackend implements LayerBackend {
4
10
  private container;
5
11
  private readonly keys;
6
12
  private readonly registered;
7
- private nextId;
8
13
  private keyFor;
9
- register(provider: LayerProvider): void;
14
+ /** Register a Layer provider under its deterministic Service-tag key. */
15
+ register(registration: LayerRegistration): void;
16
+ /** Resolve a registered Service through the ITI container. */
10
17
  resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>>;
18
+ /** Dispose all ITI-managed provider instances. */
11
19
  disposeAll(): Promise<void>;
12
20
  }
13
21
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"iti.d.mts","names":[],"sources":["../../src/adapters/iti.ts"],"mappings":";;cAMa,2BAA2B;UAC9B;mBAES;mBAEA;UAET;UAEA;EAgBR,SAAS,UAAU;EAgBnB,QAAQ,UAAU,iBAAiB,OAAO,IAAI,aAAa,KAAK,YAAY,aAAa;EAUnF,cAAc"}
1
+ {"version":3,"file":"iti.d.mts","names":[],"sources":["../../src/adapters/iti.ts"],"mappings":";;;;;;;;cAmBa,2BAA2B;UAC9B;mBAES;mBAEA;UAET;;EAgBR,SAAS,cAAc;;EAuBvB,QAAQ,UAAU,iBAAiB,OAAO,IAAI,aAAa,KAAK,YAAY,aAAa;;EAuBnF,cAAc"}
@@ -1,30 +1,50 @@
1
- import { n as DuplicateServiceError, o as ServiceNotFoundError } from "../errors-CnvKqBpb.mjs";
1
+ import { a as ServiceTagCollisionError, o as ServiceNotFoundError, t as DuplicateServiceError } from "../errors-GR3K_nRu.mjs";
2
+ import { t as assertServiceCompatibility } from "../internal-identity-BnZC3Au-.mjs";
2
3
  import { createContainer } from "iti";
3
4
  //#region src/adapters/iti.ts
5
+ /**
6
+ * ITI-backed Layer backend.
7
+ *
8
+ * Install `iti` as the optional peer dependency and pass an instance to
9
+ * `Runtime.make` when using ITI's container implementation.
10
+ */
4
11
  var ItiLayerBackend = class {
5
12
  container = createContainer();
6
- keys = /* @__PURE__ */ new WeakMap();
7
- registered = /* @__PURE__ */ new WeakSet();
8
- nextId = 0;
13
+ keys = /* @__PURE__ */ new Map();
14
+ registered = /* @__PURE__ */ new Map();
9
15
  keyFor(token) {
10
- const existing = this.keys.get(token);
16
+ const tag = token.serviceTag;
17
+ const existing = this.keys.get(tag);
11
18
  if (existing) return existing;
12
- const key = `better-effect:${token.name || "Service"}:${this.nextId++}`;
13
- this.keys.set(token, key);
19
+ const key = `better-effect:${tag}`;
20
+ this.keys.set(tag, key);
14
21
  return key;
15
22
  }
16
- register(provider) {
17
- const token = provider.service;
18
- if (this.registered.has(token)) throw new DuplicateServiceError(token);
23
+ /** Register a Layer provider under its deterministic Service-tag key. */
24
+ register(registration) {
25
+ const token = registration.service;
26
+ const tag = token.serviceTag;
27
+ const existing = this.registered.get(tag);
28
+ if (existing === token) throw new DuplicateServiceError(token);
29
+ if (existing) throw new ServiceTagCollisionError(existing, token);
19
30
  const key = this.keyFor(token);
20
- this.container = this.container.add({ [key]: provider.acquire });
21
- this.registered.add(token);
31
+ this.container = this.container.add({ [key]: registration.acquire });
32
+ this.registered.set(tag, token);
22
33
  }
34
+ /** Resolve a registered Service through the ITI container. */
23
35
  resolve(token) {
24
- if (!this.registered.has(token)) throw new ServiceNotFoundError(token);
36
+ if (!this.registered.has(token.serviceTag)) throw new ServiceNotFoundError(token);
37
+ const registered = this.registered.get(token.serviceTag);
25
38
  const key = this.keyFor(token);
26
- return this.container.get(key);
39
+ const resolved = this.container.get(key);
40
+ const validate = (instance) => {
41
+ assertServiceCompatibility(token, registered, instance);
42
+ return instance;
43
+ };
44
+ if (resolved && typeof resolved.then === "function") return Promise.resolve(resolved).then(validate);
45
+ return validate(resolved);
27
46
  }
47
+ /** Dispose all ITI-managed provider instances. */
28
48
  async disposeAll() {
29
49
  await this.container.disposeAll();
30
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"iti.mjs","names":[],"sources":["../../src/adapters/iti.ts"],"sourcesContent":["import { createContainer } from 'iti'\n\nimport { DuplicateServiceError, type LayerBackend, type LayerProvider } from '../layer'\n\nimport { ServiceNotFoundError, type AnyServiceToken } from '../service'\n\nexport class ItiLayerBackend implements LayerBackend {\n private container: any = createContainer()\n\n private readonly keys = new WeakMap<AnyServiceToken, string>()\n\n private readonly registered = new WeakSet<AnyServiceToken>()\n\n private nextId = 0\n\n private keyFor(token: AnyServiceToken): string {\n const existing = this.keys.get(token)\n\n if (existing) {\n return existing\n }\n\n const name = token.name || 'Service'\n\n const key = `better-effect:${name}:${this.nextId++}`\n\n this.keys.set(token, key)\n\n return key\n }\n\n register(provider: LayerProvider): void {\n const token = provider.service\n\n if (this.registered.has(token)) {\n throw new DuplicateServiceError(token)\n }\n\n const key = this.keyFor(token)\n\n this.container = this.container.add({\n [key]: provider.acquire\n })\n\n this.registered.add(token)\n }\n\n resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>> {\n if (!this.registered.has(token)) {\n throw new ServiceNotFoundError(token)\n }\n\n const key = this.keyFor(token)\n\n return this.container.get(key) as InstanceType<T> | PromiseLike<InstanceType<T>>\n }\n\n async disposeAll(): Promise<void> {\n await this.container.disposeAll()\n }\n}\n"],"mappings":";;;AAMA,IAAa,kBAAb,MAAqD;CACnD,YAAyB,gBAAgB;CAEzC,uBAAwB,IAAI,QAAiC;CAE7D,6BAA8B,IAAI,QAAyB;CAE3D,SAAiB;CAEjB,OAAe,OAAgC;EAC7C,MAAM,WAAW,KAAK,KAAK,IAAI,KAAK;EAEpC,IAAI,UACF,OAAO;EAKT,MAAM,MAAM,iBAFC,MAAM,QAAQ,UAEO,GAAG,KAAK;EAE1C,KAAK,KAAK,IAAI,OAAO,GAAG;EAExB,OAAO;CACT;CAEA,SAAS,UAA+B;EACtC,MAAM,QAAQ,SAAS;EAEvB,IAAI,KAAK,WAAW,IAAI,KAAK,GAC3B,MAAM,IAAI,sBAAsB,KAAK;EAGvC,MAAM,MAAM,KAAK,OAAO,KAAK;EAE7B,KAAK,YAAY,KAAK,UAAU,IAAI,GACjC,MAAM,SAAS,QAClB,CAAC;EAED,KAAK,WAAW,IAAI,KAAK;CAC3B;CAEA,QAAmC,OAA0D;EAC3F,IAAI,CAAC,KAAK,WAAW,IAAI,KAAK,GAC5B,MAAM,IAAI,qBAAqB,KAAK;EAGtC,MAAM,MAAM,KAAK,OAAO,KAAK;EAE7B,OAAO,KAAK,UAAU,IAAI,GAAG;CAC/B;CAEA,MAAM,aAA4B;EAChC,MAAM,KAAK,UAAU,WAAW;CAClC;AACF"}
1
+ {"version":3,"file":"iti.mjs","names":[],"sources":["../../src/adapters/iti.ts"],"sourcesContent":["import { createContainer } from 'iti'\n\nimport {\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\n/**\n * ITI-backed Layer backend.\n *\n * Install `iti` as the optional peer dependency and pass an instance to\n * `Runtime.make` when using ITI's container implementation.\n */\nexport class ItiLayerBackend implements LayerBackend {\n private container: any = createContainer()\n\n private readonly keys = new Map<string, string>()\n\n private readonly registered = new Map<string, AnyServiceToken>()\n\n private keyFor(token: AnyServiceToken): string {\n const tag = token.serviceTag\n const existing = this.keys.get(tag)\n\n if (existing) {\n return existing\n }\n\n const key = `better-effect:${tag}`\n\n this.keys.set(tag, key)\n\n return key\n }\n\n /** Register a Layer provider under its deterministic Service-tag key. */\n register(registration: LayerRegistration): void {\n const token = registration.service\n const tag = token.serviceTag\n const existing = this.registered.get(tag)\n\n if (existing === token) {\n throw new DuplicateServiceError(token)\n }\n\n if (existing) {\n throw new ServiceTagCollisionError(existing, token)\n }\n\n const key = this.keyFor(token)\n\n this.container = this.container.add({\n [key]: registration.acquire\n })\n\n this.registered.set(tag, token)\n }\n\n /** Resolve a registered Service through the ITI container. */\n resolve<T extends AnyServiceToken>(token: T): InstanceType<T> | PromiseLike<InstanceType<T>> {\n if (!this.registered.has(token.serviceTag)) {\n throw new ServiceNotFoundError(token)\n }\n\n const registered = this.registered.get(token.serviceTag)\n const key = this.keyFor(token)\n const resolved = this.container.get(key) as unknown\n\n const validate = (instance: unknown): InstanceType<T> => {\n assertServiceCompatibility(token, registered!, instance)\n\n return instance as InstanceType<T>\n }\n\n if (resolved && typeof (resolved as PromiseLike<unknown>).then === 'function') {\n return Promise.resolve(resolved).then(validate)\n }\n\n return validate(resolved)\n }\n\n /** Dispose all ITI-managed provider instances. */\n async disposeAll(): Promise<void> {\n await this.container.disposeAll()\n }\n}\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,kBAAb,MAAqD;CACnD,YAAyB,gBAAgB;CAEzC,uBAAwB,IAAI,IAAoB;CAEhD,6BAA8B,IAAI,IAA6B;CAE/D,OAAe,OAAgC;EAC7C,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,KAAK,IAAI,GAAG;EAElC,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,iBAAiB;EAE7B,KAAK,KAAK,IAAI,KAAK,GAAG;EAEtB,OAAO;CACT;;CAGA,SAAS,cAAuC;EAC9C,MAAM,QAAQ,aAAa;EAC3B,MAAM,MAAM,MAAM;EAClB,MAAM,WAAW,KAAK,WAAW,IAAI,GAAG;EAExC,IAAI,aAAa,OACf,MAAM,IAAI,sBAAsB,KAAK;EAGvC,IAAI,UACF,MAAM,IAAI,yBAAyB,UAAU,KAAK;EAGpD,MAAM,MAAM,KAAK,OAAO,KAAK;EAE7B,KAAK,YAAY,KAAK,UAAU,IAAI,GACjC,MAAM,aAAa,QACtB,CAAC;EAED,KAAK,WAAW,IAAI,KAAK,KAAK;CAChC;;CAGA,QAAmC,OAA0D;EAC3F,IAAI,CAAC,KAAK,WAAW,IAAI,MAAM,UAAU,GACvC,MAAM,IAAI,qBAAqB,KAAK;EAGtC,MAAM,aAAa,KAAK,WAAW,IAAI,MAAM,UAAU;EACvD,MAAM,MAAM,KAAK,OAAO,KAAK;EAC7B,MAAM,WAAW,KAAK,UAAU,IAAI,GAAG;EAEvC,MAAM,YAAY,aAAuC;GACvD,2BAA2B,OAAO,YAAa,QAAQ;GAEvD,OAAO;EACT;EAEA,IAAI,YAAY,OAAQ,SAAkC,SAAS,YACjE,OAAO,QAAQ,QAAQ,QAAQ,CAAC,CAAC,KAAK,QAAQ;EAGhD,OAAO,SAAS,QAAQ;CAC1B;;CAGA,MAAM,aAA4B;EAChC,MAAM,KAAK,UAAU,WAAW;CAClC;AACF"}
@@ -0,0 +1,74 @@
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
@@ -0,0 +1 @@
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'\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: unknown,\n readonly cleanupCause?: unknown\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;;;;ACfA,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"}