@entifix/business 0.1.0-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.
- package/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/health/health-registry.d.ts +87 -0
- package/dist/health/health-registry.d.ts.map +1 -0
- package/dist/health/health-registry.js +58 -0
- package/dist/health/health-registry.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/repository/config.repository.d.ts +7 -0
- package/dist/repository/config.repository.d.ts.map +1 -0
- package/dist/repository/config.repository.js +5 -0
- package/dist/repository/config.repository.js.map +1 -0
- package/dist/repository/entity-link-resolver.repository.d.ts +34 -0
- package/dist/repository/entity-link-resolver.repository.d.ts.map +1 -0
- package/dist/repository/entity-link-resolver.repository.js +42 -0
- package/dist/repository/entity-link-resolver.repository.js.map +1 -0
- package/dist/repository/entity-mixins.repository.d.ts +13 -0
- package/dist/repository/entity-mixins.repository.d.ts.map +1 -0
- package/dist/repository/entity-mixins.repository.js +9 -0
- package/dist/repository/entity-mixins.repository.js.map +1 -0
- package/dist/repository/entity.repository.d.ts +15 -0
- package/dist/repository/entity.repository.d.ts.map +1 -0
- package/dist/repository/entity.repository.js +5 -0
- package/dist/repository/entity.repository.js.map +1 -0
- package/dist/sessions/one-time-token-store.d.ts +40 -0
- package/dist/sessions/one-time-token-store.d.ts.map +1 -0
- package/dist/sessions/one-time-token-store.js +5 -0
- package/dist/sessions/one-time-token-store.js.map +1 -0
- package/dist/sessions/session-store.d.ts +145 -0
- package/dist/sessions/session-store.d.ts.map +1 -0
- package/dist/sessions/session-store.js +5 -0
- package/dist/sessions/session-store.js.map +1 -0
- package/dist/shutdown/shutdown-registry.d.ts +84 -0
- package/dist/shutdown/shutdown-registry.d.ts.map +1 -0
- package/dist/shutdown/shutdown-registry.js +88 -0
- package/dist/shutdown/shutdown-registry.js.map +1 -0
- package/dist/tenancy/index.d.ts +2 -0
- package/dist/tenancy/index.d.ts.map +1 -0
- package/dist/tenancy/index.js +3 -0
- package/dist/tenancy/index.js.map +1 -0
- package/dist/tenancy/tenant-database-resolver.d.ts +38 -0
- package/dist/tenancy/tenant-database-resolver.d.ts.map +1 -0
- package/dist/tenancy/tenant-database-resolver.js +9 -0
- package/dist/tenancy/tenant-database-resolver.js.map +1 -0
- package/dist/tokens/token-service.d.ts +101 -0
- package/dist/tokens/token-service.d.ts.map +1 -0
- package/dist/tokens/token-service.js +5 -0
- package/dist/tokens/token-service.js.map +1 -0
- package/dist/use-case/delete/delete.uc.d.ts +13 -0
- package/dist/use-case/delete/delete.uc.d.ts.map +1 -0
- package/dist/use-case/delete/delete.uc.js +18 -0
- package/dist/use-case/delete/delete.uc.js.map +1 -0
- package/dist/use-case/delete/index.d.ts +2 -0
- package/dist/use-case/delete/index.d.ts.map +1 -0
- package/dist/use-case/delete/index.js +3 -0
- package/dist/use-case/delete/index.js.map +1 -0
- package/dist/use-case/get/get.uc.d.ts +12 -0
- package/dist/use-case/get/get.uc.d.ts.map +1 -0
- package/dist/use-case/get/get.uc.js +18 -0
- package/dist/use-case/get/get.uc.js.map +1 -0
- package/dist/use-case/get/index.d.ts +2 -0
- package/dist/use-case/get/index.d.ts.map +1 -0
- package/dist/use-case/get/index.js +3 -0
- package/dist/use-case/get/index.js.map +1 -0
- package/dist/use-case/load/index.d.ts +2 -0
- package/dist/use-case/load/index.d.ts.map +1 -0
- package/dist/use-case/load/index.js +3 -0
- package/dist/use-case/load/index.js.map +1 -0
- package/dist/use-case/load/load.uc.d.ts +6 -0
- package/dist/use-case/load/load.uc.d.ts.map +1 -0
- package/dist/use-case/load/load.uc.js +16 -0
- package/dist/use-case/load/load.uc.js.map +1 -0
- package/dist/use-case/save/index.d.ts +2 -0
- package/dist/use-case/save/index.d.ts.map +1 -0
- package/dist/use-case/save/index.js +3 -0
- package/dist/use-case/save/index.js.map +1 -0
- package/dist/use-case/save/save.uc.d.ts +16 -0
- package/dist/use-case/save/save.uc.d.ts.map +1 -0
- package/dist/use-case/save/save.uc.js +24 -0
- package/dist/use-case/save/save.uc.js.map +1 -0
- package/dist/wiring/wiring-registry.d.ts +74 -0
- package/dist/wiring/wiring-registry.d.ts.map +1 -0
- package/dist/wiring/wiring-registry.js +49 -0
- package/dist/wiring/wiring-registry.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/delete/index.ts"],"sourcesContent":["export * from './delete.uc.js';\n"],"names":[],"mappings":"AAAA,cAAc,iBAAiB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Entity } from '@entifix/core';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
4
|
+
import { EntityIdTag } from '../../repository/entity-mixins.repository.js';
|
|
5
|
+
/**
|
|
6
|
+
* Reads a single entity by id.
|
|
7
|
+
*
|
|
8
|
+
* The factory's type parameter is what makes the result usable without a cast
|
|
9
|
+
* at the call site — {@link EntityIdTag} carries no entity type of its own.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getUCFactory<TEntity extends Entity>(): Effect.Effect<TEntity, import("@entifix/core").EntifixError, import("../../index.js").ConfigurationRepositoryTag | EntityRepositoryTag | EntityIdTag>;
|
|
12
|
+
//# sourceMappingURL=get.uc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.uc.d.ts","sourceRoot":"","sources":["../../../src/use-case/get/get.uc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,8CAA8C,CAAC;AAE3E;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,SAAS,MAAM,2JASlD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
3
|
+
import { EntityIdTag } from '../../repository/entity-mixins.repository.js';
|
|
4
|
+
/**
|
|
5
|
+
* Reads a single entity by id.
|
|
6
|
+
*
|
|
7
|
+
* The factory's type parameter is what makes the result usable without a cast
|
|
8
|
+
* at the call site — {@link EntityIdTag} carries no entity type of its own.
|
|
9
|
+
*/ export function getUCFactory() {
|
|
10
|
+
return Effect.gen(function*() {
|
|
11
|
+
const entityRepository = yield* EntityRepositoryTag;
|
|
12
|
+
const entityId = yield* EntityIdTag;
|
|
13
|
+
const result = yield* entityRepository.get(entityId);
|
|
14
|
+
return result;
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=get.uc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/get/get.uc.ts"],"sourcesContent":["import { Entity } from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { EntityRepositoryTag } from '../../repository/entity.repository.js';\nimport { EntityIdTag } from '../../repository/entity-mixins.repository.js';\n\n/**\n * Reads a single entity by id.\n *\n * The factory's type parameter is what makes the result usable without a cast\n * at the call site — {@link EntityIdTag} carries no entity type of its own.\n */\nexport function getUCFactory<TEntity extends Entity>() {\n return Effect.gen(function* () {\n const entityRepository = yield* EntityRepositoryTag;\n const entityId = yield* EntityIdTag;\n\n const result = yield* entityRepository.get<TEntity>(entityId);\n\n return result;\n });\n}\n"],"names":["Effect","EntityRepositoryTag","EntityIdTag","getUCFactory","gen","entityRepository","entityId","result","get"],"mappings":"AACA,SAASA,MAAM,QAAQ,SAAS;AAEhC,SAASC,mBAAmB,QAAQ,wCAAwC;AAC5E,SAASC,WAAW,QAAQ,+CAA+C;AAE3E;;;;;CAKC,GACD,OAAO,SAASC;IACd,OAAOH,OAAOI,GAAG,CAAC;QAChB,MAAMC,mBAAmB,OAAOJ;QAChC,MAAMK,WAAW,OAAOJ;QAExB,MAAMK,SAAS,OAAOF,iBAAiBG,GAAG,CAAUF;QAEpD,OAAOC;IACT;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/use-case/get/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/get/index.ts"],"sourcesContent":["export * from './get.uc.js';\n"],"names":[],"mappings":"AAAA,cAAc,cAAc"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/use-case/load/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/load/index.ts"],"sourcesContent":["export * from './load.uc.js';\n"],"names":[],"mappings":"AAAA,cAAc,eAAe"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Entity } from '@entifix/core';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
4
|
+
import { EntityLoadRequestTag } from '../../repository/entity-mixins.repository.js';
|
|
5
|
+
export declare function loadUCFactory<TEntity extends Entity>(): Effect.Effect<import("@entifix/core").EntityPage<TEntity>, import("@entifix/core").EntifixError, import("../../index.js").ConfigurationRepositoryTag | EntityRepositoryTag | EntityLoadRequestTag>;
|
|
6
|
+
//# sourceMappingURL=load.uc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.uc.d.ts","sourceRoot":"","sources":["../../../src/use-case/load/load.uc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AAEpF,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,wMAenD"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
3
|
+
import { EntityLoadRequestTag } from '../../repository/entity-mixins.repository.js';
|
|
4
|
+
export function loadUCFactory() {
|
|
5
|
+
return Effect.gen(function*() {
|
|
6
|
+
const entityRepository = yield* EntityRepositoryTag;
|
|
7
|
+
const entityLoadRequest = yield* EntityLoadRequestTag;
|
|
8
|
+
// Type assertion to ensure the load request is of the correct entity type
|
|
9
|
+
// This is necessary because the EntityLoadRequestTag does not carry generic type information
|
|
10
|
+
const typedEntityLoadRequest = entityLoadRequest;
|
|
11
|
+
const result = yield* entityRepository.load(typedEntityLoadRequest);
|
|
12
|
+
return result;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=load.uc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/load/load.uc.ts"],"sourcesContent":["import { Entity, EntityLoadRequest } from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { EntityRepositoryTag } from '../../repository/entity.repository.js';\nimport { EntityLoadRequestTag } from '../../repository/entity-mixins.repository.js';\n\nexport function loadUCFactory<TEntity extends Entity>() {\n return Effect.gen(function* () {\n const entityRepository = yield* EntityRepositoryTag;\n const entityLoadRequest = yield* EntityLoadRequestTag;\n\n // Type assertion to ensure the load request is of the correct entity type\n // This is necessary because the EntityLoadRequestTag does not carry generic type information\n const typedEntityLoadRequest =\n entityLoadRequest as unknown as EntityLoadRequest<TEntity>;\n\n const result = yield* entityRepository.load<TEntity>(\n typedEntityLoadRequest,\n );\n return result;\n });\n}\n"],"names":["Effect","EntityRepositoryTag","EntityLoadRequestTag","loadUCFactory","gen","entityRepository","entityLoadRequest","typedEntityLoadRequest","result","load"],"mappings":"AACA,SAASA,MAAM,QAAQ,SAAS;AAEhC,SAASC,mBAAmB,QAAQ,wCAAwC;AAC5E,SAASC,oBAAoB,QAAQ,+CAA+C;AAEpF,OAAO,SAASC;IACd,OAAOH,OAAOI,GAAG,CAAC;QAChB,MAAMC,mBAAmB,OAAOJ;QAChC,MAAMK,oBAAoB,OAAOJ;QAEjC,0EAA0E;QAC1E,6FAA6F;QAC7F,MAAMK,yBACJD;QAEF,MAAME,SAAS,OAAOH,iBAAiBI,IAAI,CACzCF;QAEF,OAAOC;IACT;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/use-case/save/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/save/index.ts"],"sourcesContent":["export * from './save.uc.js';\n"],"names":[],"mappings":"AAAA,cAAc,eAAe"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Entity } from '@entifix/core';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
4
|
+
import { EntityTag } from '../../repository/entity-mixins.repository.js';
|
|
5
|
+
/**
|
|
6
|
+
* Persists an entity and returns whatever the repository considers the stored
|
|
7
|
+
* truth — which is not necessarily the input: a create round-trips through the
|
|
8
|
+
* adapter's id generation, so the returned entity is the one callers should
|
|
9
|
+
* render.
|
|
10
|
+
*
|
|
11
|
+
* Like {@link loadUCFactory}, this yields its inputs from context rather than
|
|
12
|
+
* taking them as arguments, so the same use-case saves over REST on the web and
|
|
13
|
+
* over Mongo on a backend.
|
|
14
|
+
*/
|
|
15
|
+
export declare function saveUCFactory<TEntity extends Entity>(): Effect.Effect<TEntity, [import("effect/Utils").YieldWrap<import("effect/Context").Tag<EntityRepositoryTag, import("../../index.js").EntityRepository>> | import("effect/Utils").YieldWrap<import("effect/Context").Tag<EntityTag, Entity>> | import("effect/Utils").YieldWrap<Effect.Effect<TEntity, import("@entifix/core").EntifixError, import("../../index.js").ConfigurationRepositoryTag>>] extends [import("effect/Utils").YieldWrap<Effect.Effect<infer _A, infer E, infer _R>>] ? E : never, [import("effect/Utils").YieldWrap<import("effect/Context").Tag<EntityRepositoryTag, import("../../index.js").EntityRepository>> | import("effect/Utils").YieldWrap<import("effect/Context").Tag<EntityTag, Entity>> | import("effect/Utils").YieldWrap<Effect.Effect<TEntity, import("@entifix/core").EntifixError, import("../../index.js").ConfigurationRepositoryTag>>] extends [import("effect/Utils").YieldWrap<Effect.Effect<infer _A_1, infer _E, infer R>>] ? R : never>;
|
|
16
|
+
//# sourceMappingURL=save.uc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.uc.d.ts","sourceRoot":"","sources":["../../../src/use-case/save/save.uc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AAEzE;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,47BAWnD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
3
|
+
import { EntityTag } from '../../repository/entity-mixins.repository.js';
|
|
4
|
+
/**
|
|
5
|
+
* Persists an entity and returns whatever the repository considers the stored
|
|
6
|
+
* truth — which is not necessarily the input: a create round-trips through the
|
|
7
|
+
* adapter's id generation, so the returned entity is the one callers should
|
|
8
|
+
* render.
|
|
9
|
+
*
|
|
10
|
+
* Like {@link loadUCFactory}, this yields its inputs from context rather than
|
|
11
|
+
* taking them as arguments, so the same use-case saves over REST on the web and
|
|
12
|
+
* over Mongo on a backend.
|
|
13
|
+
*/ export function saveUCFactory() {
|
|
14
|
+
return Effect.gen(function*() {
|
|
15
|
+
const entityRepository = yield* EntityRepositoryTag;
|
|
16
|
+
const entity = yield* EntityTag;
|
|
17
|
+
// EntityTag is not generic, so it carries the base `Entity`; the caller
|
|
18
|
+
// states the concrete type through the factory's parameter.
|
|
19
|
+
const result = yield* entityRepository.save(entity);
|
|
20
|
+
return result;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=save.uc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/save/save.uc.ts"],"sourcesContent":["import { Entity } from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { EntityRepositoryTag } from '../../repository/entity.repository.js';\nimport { EntityTag } from '../../repository/entity-mixins.repository.js';\n\n/**\n * Persists an entity and returns whatever the repository considers the stored\n * truth — which is not necessarily the input: a create round-trips through the\n * adapter's id generation, so the returned entity is the one callers should\n * render.\n *\n * Like {@link loadUCFactory}, this yields its inputs from context rather than\n * taking them as arguments, so the same use-case saves over REST on the web and\n * over Mongo on a backend.\n */\nexport function saveUCFactory<TEntity extends Entity>() {\n return Effect.gen(function* () {\n const entityRepository = yield* EntityRepositoryTag;\n const entity = yield* EntityTag;\n\n // EntityTag is not generic, so it carries the base `Entity`; the caller\n // states the concrete type through the factory's parameter.\n const result = yield* entityRepository.save<TEntity>(entity as TEntity);\n\n return result;\n });\n}\n"],"names":["Effect","EntityRepositoryTag","EntityTag","saveUCFactory","gen","entityRepository","entity","result","save"],"mappings":"AACA,SAASA,MAAM,QAAQ,SAAS;AAEhC,SAASC,mBAAmB,QAAQ,wCAAwC;AAC5E,SAASC,SAAS,QAAQ,+CAA+C;AAEzE;;;;;;;;;CASC,GACD,OAAO,SAASC;IACd,OAAOH,OAAOI,GAAG,CAAC;QAChB,MAAMC,mBAAmB,OAAOJ;QAChC,MAAMK,SAAS,OAAOJ;QAEtB,wEAAwE;QACxE,4DAA4D;QAC5D,MAAMK,SAAS,OAAOF,iBAAiBG,IAAI,CAAUF;QAErD,OAAOC;IACT;AACF"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Context, Effect, Layer } from 'effect';
|
|
2
|
+
/**
|
|
3
|
+
* The queue shapes a subscriber may ask for (ADR 0030).
|
|
4
|
+
*
|
|
5
|
+
* Duplicated from `SubscriptionMode` in `@entifix/transactions` rather than
|
|
6
|
+
* imported: that package sits at `entifix:transactions`, **above** this one at
|
|
7
|
+
* `entifix:contract`, so the edge would point upward and the boundary rule fails
|
|
8
|
+
* the build on it. The same duplication exists in `tools/slices/src/types.ts`
|
|
9
|
+
* for the same reason, and both lists are pinned by a spec.
|
|
10
|
+
*/
|
|
11
|
+
export declare const BOUND_SUBSCRIPTION_MODES: readonly ["work", "broadcast"];
|
|
12
|
+
export type BoundSubscriptionMode = (typeof BOUND_SUBSCRIPTION_MODES)[number];
|
|
13
|
+
/**
|
|
14
|
+
* One subscription a running process **actually bound**, recorded by the bus
|
|
15
|
+
* adapter as `subscribe` runs.
|
|
16
|
+
*
|
|
17
|
+
* Observed rather than declared, which is the whole point: a document generated
|
|
18
|
+
* from `tools/slices/` would agree with `tools/slices/` by construction and
|
|
19
|
+
* catch nothing (ADR 0031). `queue` is the broker's own name for it, so someone
|
|
20
|
+
* looking at depth in the management UI can match the two up.
|
|
21
|
+
*/
|
|
22
|
+
export interface BoundSubscription {
|
|
23
|
+
/** The **subscribing** slice — never the emitter. See `Subscription.slice`. */
|
|
24
|
+
readonly slice: string;
|
|
25
|
+
readonly pattern: string;
|
|
26
|
+
readonly mode: BoundSubscriptionMode;
|
|
27
|
+
readonly queue: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* What a process did with its bus, as opposed to what it can still reach.
|
|
31
|
+
*
|
|
32
|
+
* A sibling of `HealthRegistry` rather than part of it: a subscription is not a
|
|
33
|
+
* readiness fact — a bound queue says nothing about whether the broker is
|
|
34
|
+
* answering right now — and folding the two together would put entries in the
|
|
35
|
+
* readiness response that no probe can check.
|
|
36
|
+
*
|
|
37
|
+
* Both halves are cumulative and never cleared. `published` is a set of event
|
|
38
|
+
* **names** and nothing else: no payloads, no counts, no timestamps. Counts
|
|
39
|
+
* would be per-replica and un-alertable, which is the telemetry path ADR 0001
|
|
40
|
+
* already chose OTLP for.
|
|
41
|
+
*/
|
|
42
|
+
export interface WiringRegistry {
|
|
43
|
+
/** Called by the bus adapter once per binding, including after a reconnect. */
|
|
44
|
+
readonly recordSubscription: (bound: BoundSubscription) => Effect.Effect<void>;
|
|
45
|
+
/** Called by the bus adapter on every publish. Idempotent per name. */
|
|
46
|
+
readonly recordPublish: (eventName: string) => Effect.Effect<void>;
|
|
47
|
+
/** Every distinct binding, in the order it was first made. */
|
|
48
|
+
readonly subscriptions: Effect.Effect<readonly BoundSubscription[]>;
|
|
49
|
+
/** Every distinct event name emitted since boot, in first-seen order. */
|
|
50
|
+
readonly published: Effect.Effect<readonly string[]>;
|
|
51
|
+
}
|
|
52
|
+
declare const WiringRegistryTag_base: Context.TagClass<WiringRegistryTag, "WiringRegistryTag", WiringRegistry>;
|
|
53
|
+
/**
|
|
54
|
+
* DI tag for the wiring registry.
|
|
55
|
+
*
|
|
56
|
+
* It lives here, in the contract layer, so `@entifix/amqp` can record
|
|
57
|
+
* into it without depending on a shell — the same placement, and the same
|
|
58
|
+
* reason, as {@link HealthRegistryTag}.
|
|
59
|
+
*/
|
|
60
|
+
export declare class WiringRegistryTag extends WiringRegistryTag_base {
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Live registry over a `Ref`. Provide it **once** per service and share the
|
|
64
|
+
* instance (`Layer.provideMerge`), or the bus records into a registry the
|
|
65
|
+
* description route never reads.
|
|
66
|
+
*
|
|
67
|
+
* Both recorders deduplicate. A reconnect re-runs every consumer's setup
|
|
68
|
+
* against the new channel (`AmqpConnector.addConsumer`), so without it a broker
|
|
69
|
+
* restart would list the same binding twice; and a publisher emits the same
|
|
70
|
+
* event name continuously, so without it the list would grow without bound.
|
|
71
|
+
*/
|
|
72
|
+
export declare const WiringRegistryLayer: Layer.Layer<WiringRegistryTag>;
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=wiring-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wiring-registry.d.ts","sourceRoot":"","sources":["../../src/wiring/wiring-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAO,MAAM,QAAQ,CAAC;AAErD;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,gCAAiC,CAAC;AAEvE,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9E;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,kBAAkB,EAAE,CAC3B,KAAK,EAAE,iBAAiB,KACrB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,uEAAuE;IACvE,QAAQ,CAAC,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnE,8DAA8D;IAC9D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;IACpE,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CACtD;;AAED;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,sBAGpC;CAAG;AASN;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAuB9D,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Ref } from 'effect';
|
|
2
|
+
/**
|
|
3
|
+
* The queue shapes a subscriber may ask for (ADR 0030).
|
|
4
|
+
*
|
|
5
|
+
* Duplicated from `SubscriptionMode` in `@entifix/transactions` rather than
|
|
6
|
+
* imported: that package sits at `entifix:transactions`, **above** this one at
|
|
7
|
+
* `entifix:contract`, so the edge would point upward and the boundary rule fails
|
|
8
|
+
* the build on it. The same duplication exists in `tools/slices/src/types.ts`
|
|
9
|
+
* for the same reason, and both lists are pinned by a spec.
|
|
10
|
+
*/ export const BOUND_SUBSCRIPTION_MODES = [
|
|
11
|
+
'work',
|
|
12
|
+
'broadcast'
|
|
13
|
+
];
|
|
14
|
+
/**
|
|
15
|
+
* DI tag for the wiring registry.
|
|
16
|
+
*
|
|
17
|
+
* It lives here, in the contract layer, so `@entifix/amqp` can record
|
|
18
|
+
* into it without depending on a shell — the same placement, and the same
|
|
19
|
+
* reason, as {@link HealthRegistryTag}.
|
|
20
|
+
*/ export class WiringRegistryTag extends Context.Tag('WiringRegistryTag')() {
|
|
21
|
+
}
|
|
22
|
+
/** Whether two bindings are the same binding. */ const same = (a, b)=>a.slice === b.slice && a.pattern === b.pattern && a.mode === b.mode && a.queue === b.queue;
|
|
23
|
+
/**
|
|
24
|
+
* Live registry over a `Ref`. Provide it **once** per service and share the
|
|
25
|
+
* instance (`Layer.provideMerge`), or the bus records into a registry the
|
|
26
|
+
* description route never reads.
|
|
27
|
+
*
|
|
28
|
+
* Both recorders deduplicate. A reconnect re-runs every consumer's setup
|
|
29
|
+
* against the new channel (`AmqpConnector.addConsumer`), so without it a broker
|
|
30
|
+
* restart would list the same binding twice; and a publisher emits the same
|
|
31
|
+
* event name continuously, so without it the list would grow without bound.
|
|
32
|
+
*/ export const WiringRegistryLayer = Layer.effect(WiringRegistryTag, Effect.gen(function*() {
|
|
33
|
+
const subscriptions = yield* Ref.make([]);
|
|
34
|
+
const published = yield* Ref.make([]);
|
|
35
|
+
return {
|
|
36
|
+
recordSubscription: (bound)=>Ref.update(subscriptions, (current)=>current.some((existing)=>same(existing, bound)) ? current : [
|
|
37
|
+
...current,
|
|
38
|
+
bound
|
|
39
|
+
]),
|
|
40
|
+
recordPublish: (eventName)=>Ref.update(published, (current)=>current.includes(eventName) ? current : [
|
|
41
|
+
...current,
|
|
42
|
+
eventName
|
|
43
|
+
]),
|
|
44
|
+
subscriptions: Ref.get(subscriptions),
|
|
45
|
+
published: Ref.get(published)
|
|
46
|
+
};
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=wiring-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/wiring/wiring-registry.ts"],"sourcesContent":["import { Context, Effect, Layer, Ref } from 'effect';\n\n/**\n * The queue shapes a subscriber may ask for (ADR 0030).\n *\n * Duplicated from `SubscriptionMode` in `@entifix/transactions` rather than\n * imported: that package sits at `entifix:transactions`, **above** this one at\n * `entifix:contract`, so the edge would point upward and the boundary rule fails\n * the build on it. The same duplication exists in `tools/slices/src/types.ts`\n * for the same reason, and both lists are pinned by a spec.\n */\nexport const BOUND_SUBSCRIPTION_MODES = ['work', 'broadcast'] as const;\n\nexport type BoundSubscriptionMode = (typeof BOUND_SUBSCRIPTION_MODES)[number];\n\n/**\n * One subscription a running process **actually bound**, recorded by the bus\n * adapter as `subscribe` runs.\n *\n * Observed rather than declared, which is the whole point: a document generated\n * from `tools/slices/` would agree with `tools/slices/` by construction and\n * catch nothing (ADR 0031). `queue` is the broker's own name for it, so someone\n * looking at depth in the management UI can match the two up.\n */\nexport interface BoundSubscription {\n /** The **subscribing** slice — never the emitter. See `Subscription.slice`. */\n readonly slice: string;\n readonly pattern: string;\n readonly mode: BoundSubscriptionMode;\n readonly queue: string;\n}\n\n/**\n * What a process did with its bus, as opposed to what it can still reach.\n *\n * A sibling of `HealthRegistry` rather than part of it: a subscription is not a\n * readiness fact — a bound queue says nothing about whether the broker is\n * answering right now — and folding the two together would put entries in the\n * readiness response that no probe can check.\n *\n * Both halves are cumulative and never cleared. `published` is a set of event\n * **names** and nothing else: no payloads, no counts, no timestamps. Counts\n * would be per-replica and un-alertable, which is the telemetry path ADR 0001\n * already chose OTLP for.\n */\nexport interface WiringRegistry {\n /** Called by the bus adapter once per binding, including after a reconnect. */\n readonly recordSubscription: (\n bound: BoundSubscription,\n ) => Effect.Effect<void>;\n /** Called by the bus adapter on every publish. Idempotent per name. */\n readonly recordPublish: (eventName: string) => Effect.Effect<void>;\n /** Every distinct binding, in the order it was first made. */\n readonly subscriptions: Effect.Effect<readonly BoundSubscription[]>;\n /** Every distinct event name emitted since boot, in first-seen order. */\n readonly published: Effect.Effect<readonly string[]>;\n}\n\n/**\n * DI tag for the wiring registry.\n *\n * It lives here, in the contract layer, so `@entifix/amqp` can record\n * into it without depending on a shell — the same placement, and the same\n * reason, as {@link HealthRegistryTag}.\n */\nexport class WiringRegistryTag extends Context.Tag('WiringRegistryTag')<\n WiringRegistryTag,\n WiringRegistry\n>() {}\n\n/** Whether two bindings are the same binding. */\nconst same = (a: BoundSubscription, b: BoundSubscription): boolean =>\n a.slice === b.slice &&\n a.pattern === b.pattern &&\n a.mode === b.mode &&\n a.queue === b.queue;\n\n/**\n * Live registry over a `Ref`. Provide it **once** per service and share the\n * instance (`Layer.provideMerge`), or the bus records into a registry the\n * description route never reads.\n *\n * Both recorders deduplicate. A reconnect re-runs every consumer's setup\n * against the new channel (`AmqpConnector.addConsumer`), so without it a broker\n * restart would list the same binding twice; and a publisher emits the same\n * event name continuously, so without it the list would grow without bound.\n */\nexport const WiringRegistryLayer: Layer.Layer<WiringRegistryTag> = Layer.effect(\n WiringRegistryTag,\n Effect.gen(function* () {\n const subscriptions = yield* Ref.make<readonly BoundSubscription[]>([]);\n const published = yield* Ref.make<readonly string[]>([]);\n\n return {\n recordSubscription: bound =>\n Ref.update(subscriptions, current =>\n current.some(existing => same(existing, bound))\n ? current\n : [...current, bound],\n ),\n\n recordPublish: eventName =>\n Ref.update(published, current =>\n current.includes(eventName) ? current : [...current, eventName],\n ),\n\n subscriptions: Ref.get(subscriptions),\n published: Ref.get(published),\n };\n }),\n);\n"],"names":["Context","Effect","Layer","Ref","BOUND_SUBSCRIPTION_MODES","WiringRegistryTag","Tag","same","a","b","slice","pattern","mode","queue","WiringRegistryLayer","effect","gen","subscriptions","make","published","recordSubscription","bound","update","current","some","existing","recordPublish","eventName","includes","get"],"mappings":"AAAA,SAASA,OAAO,EAAEC,MAAM,EAAEC,KAAK,EAAEC,GAAG,QAAQ,SAAS;AAErD;;;;;;;;CAQC,GACD,OAAO,MAAMC,2BAA2B;IAAC;IAAQ;CAAY,CAAU;AA+CvE;;;;;;CAMC,GACD,OAAO,MAAMC,0BAA0BL,QAAQM,GAAG,CAAC;AAG9C;AAEL,+CAA+C,GAC/C,MAAMC,OAAO,CAACC,GAAsBC,IAClCD,EAAEE,KAAK,KAAKD,EAAEC,KAAK,IACnBF,EAAEG,OAAO,KAAKF,EAAEE,OAAO,IACvBH,EAAEI,IAAI,KAAKH,EAAEG,IAAI,IACjBJ,EAAEK,KAAK,KAAKJ,EAAEI,KAAK;AAErB;;;;;;;;;CASC,GACD,OAAO,MAAMC,sBAAsDZ,MAAMa,MAAM,CAC7EV,mBACAJ,OAAOe,GAAG,CAAC;IACT,MAAMC,gBAAgB,OAAOd,IAAIe,IAAI,CAA+B,EAAE;IACtE,MAAMC,YAAY,OAAOhB,IAAIe,IAAI,CAAoB,EAAE;IAEvD,OAAO;QACLE,oBAAoBC,CAAAA,QAClBlB,IAAImB,MAAM,CAACL,eAAeM,CAAAA,UACxBA,QAAQC,IAAI,CAACC,CAAAA,WAAYlB,KAAKkB,UAAUJ,UACpCE,UACA;uBAAIA;oBAASF;iBAAM;QAG3BK,eAAeC,CAAAA,YACbxB,IAAImB,MAAM,CAACH,WAAWI,CAAAA,UACpBA,QAAQK,QAAQ,CAACD,aAAaJ,UAAU;uBAAIA;oBAASI;iBAAU;QAGnEV,eAAed,IAAI0B,GAAG,CAACZ;QACvBE,WAAWhB,IAAI0B,GAAG,CAACV;IACrB;AACF,IACA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@entifix/business",
|
|
3
|
+
"version": "0.1.0-0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/r10c-technologies/entifix.git",
|
|
8
|
+
"directory": "packages/ts/business"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
"./package.json": "./package.json",
|
|
19
|
+
".": {
|
|
20
|
+
"@entifix/source": "./src/index.ts",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"!**/*.tsbuildinfo",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"nx": {
|
|
32
|
+
"tags": [
|
|
33
|
+
"layer:entifix",
|
|
34
|
+
"scope:shared",
|
|
35
|
+
"entifix:contract",
|
|
36
|
+
"tier:1"
|
|
37
|
+
],
|
|
38
|
+
"sourceRoot": "packages/ts/business/src",
|
|
39
|
+
"targets": {
|
|
40
|
+
"build": {
|
|
41
|
+
"executor": "@nx/js:swc",
|
|
42
|
+
"outputs": [
|
|
43
|
+
"{options.outputPath}"
|
|
44
|
+
],
|
|
45
|
+
"options": {
|
|
46
|
+
"outputPath": "packages/ts/business/dist",
|
|
47
|
+
"main": "packages/ts/business/src/index.ts",
|
|
48
|
+
"tsConfig": "packages/ts/business/tsconfig.lib.json",
|
|
49
|
+
"skipTypeCheck": true,
|
|
50
|
+
"stripLeadingPaths": true
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@swc/helpers": "0.5.23",
|
|
57
|
+
"@entifix/core": "0.1.0-0"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"effect": ">=3.22 <4"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"effect": "3.22.1"
|
|
64
|
+
}
|
|
65
|
+
}
|