@entifix/business 0.1.1 → 0.1.3
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/README.md +3 -3
- package/dist/use-case/load/index.d.ts +2 -0
- package/dist/use-case/load/index.d.ts.map +1 -1
- package/dist/use-case/load/index.js +2 -0
- package/dist/use-case/load/index.js.map +1 -1
- package/dist/use-case/load/load-all.uc.d.ts +19 -0
- package/dist/use-case/load/load-all.uc.d.ts.map +1 -0
- package/dist/use-case/load/load-all.uc.js +35 -0
- package/dist/use-case/load/load-all.uc.js.map +1 -0
- package/dist/use-case/load/resolve-links.uc.d.ts +20 -0
- package/dist/use-case/load/resolve-links.uc.d.ts.map +1 -0
- package/dist/use-case/load/resolve-links.uc.js +23 -0
- package/dist/use-case/load/resolve-links.uc.js.map +1 -0
- package/dist/wiring/wiring-registry.d.ts +2 -3
- package/dist/wiring/wiring-registry.d.ts.map +1 -1
- package/dist/wiring/wiring-registry.js +2 -3
- package/dist/wiring/wiring-registry.js.map +1 -1
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -12,9 +12,9 @@ pnpm add @entifix/business effect
|
|
|
12
12
|
|
|
13
13
|
## Entry points
|
|
14
14
|
|
|
15
|
-
| Import | What it holds
|
|
16
|
-
| ------------------- |
|
|
17
|
-
| `@entifix/business` | Port tags, `getUCFactory` / `loadUCFactory` / `saveUCFactory` / `deleteUCFactory`, `HealthRegistryLayer`, `makeShutdownRegistry` |
|
|
15
|
+
| Import | What it holds |
|
|
16
|
+
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
17
|
+
| `@entifix/business` | Port tags, `getUCFactory` / `loadUCFactory` / `saveUCFactory` / `deleteUCFactory`, `loadAllUCFactory` (every record a request keeps, page by page), `resolveLinksUCFactory` (chosen links of many records), `HealthRegistryLayer`, `makeShutdownRegistry` |
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/use-case/load/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/use-case/load/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/use-case/load/index.ts"],"sourcesContent":["export * from './load.uc.js';\n"],"names":[],"mappings":"AAAA,cAAc,eAAe"}
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/load/index.ts"],"sourcesContent":["export * from './load.uc.js';\nexport * from './load-all.uc.js';\nexport * from './resolve-links.uc.js';\n"],"names":[],"mappings":"AAAA,cAAc,eAAe;AAC7B,cAAc,mBAAmB;AACjC,cAAc,wBAAwB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Entity, EntityLoadRequest } 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
|
+
/** A request for every record it keeps: paging is the use case's to set. */
|
|
6
|
+
export type UnpagedRequest<TEntity extends Entity> = Omit<EntityLoadRequest<TEntity>, 'page' | 'pageSize'>;
|
|
7
|
+
/** How many records `loadAllUCFactory` asks the repository for at a time. */
|
|
8
|
+
export declare const LOAD_ALL_PAGE_SIZE = 100;
|
|
9
|
+
/**
|
|
10
|
+
* Every record the request in `EntityLoadRequestTag` keeps, filtered and
|
|
11
|
+
* sorted as it asks, read page by page until the repository's `total` is
|
|
12
|
+
* reached.
|
|
13
|
+
*
|
|
14
|
+
* The request's own `page` and `pageSize` are ignored: asking for one page
|
|
15
|
+
* as large as can be counted works against an in-memory source, but a real
|
|
16
|
+
* adapter would hand that size to its database.
|
|
17
|
+
*/
|
|
18
|
+
export declare function loadAllUCFactory<TEntity extends Entity>(pageSize?: number): Effect.Effect<TEntity[], import("@entifix/core").EntifixError, import("../../index.js").ConfigurationRepositoryTag | EntityRepositoryTag | EntityLoadRequestTag>;
|
|
19
|
+
//# sourceMappingURL=load-all.uc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-all.uc.d.ts","sourceRoot":"","sources":["../../../src/use-case/load/load-all.uc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,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,4EAA4E;AAC5E,MAAM,MAAM,cAAc,CAAC,OAAO,SAAS,MAAM,IAAI,IAAI,CACvD,iBAAiB,CAAC,OAAO,CAAC,EAC1B,MAAM,GAAG,UAAU,CACpB,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,SAAS,MAAM,EACrD,QAAQ,GAAE,MAA2B,oKAuBtC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { EntityRepositoryTag } from '../../repository/entity.repository.js';
|
|
4
|
+
import { EntityLoadRequestTag } from '../../repository/entity-mixins.repository.js';
|
|
5
|
+
/** How many records `loadAllUCFactory` asks the repository for at a time. */ export const LOAD_ALL_PAGE_SIZE = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Every record the request in `EntityLoadRequestTag` keeps, filtered and
|
|
8
|
+
* sorted as it asks, read page by page until the repository's `total` is
|
|
9
|
+
* reached.
|
|
10
|
+
*
|
|
11
|
+
* The request's own `page` and `pageSize` are ignored: asking for one page
|
|
12
|
+
* as large as can be counted works against an in-memory source, but a real
|
|
13
|
+
* adapter would hand that size to its database.
|
|
14
|
+
*/ export function loadAllUCFactory(pageSize = LOAD_ALL_PAGE_SIZE) {
|
|
15
|
+
return Effect.gen(function*() {
|
|
16
|
+
const entityRepository = yield* EntityRepositoryTag;
|
|
17
|
+
const entityLoadRequest = yield* EntityLoadRequestTag;
|
|
18
|
+
// EntityLoadRequestTag carries no generic type, as in `loadUCFactory`.
|
|
19
|
+
const request = entityLoadRequest;
|
|
20
|
+
const items = [];
|
|
21
|
+
for(let page = 1;; page += 1){
|
|
22
|
+
const result = yield* entityRepository.load(_extends({}, request, {
|
|
23
|
+
page,
|
|
24
|
+
pageSize
|
|
25
|
+
}));
|
|
26
|
+
items.push(...result.items);
|
|
27
|
+
// An empty page ends the read too, should `total` overstate it.
|
|
28
|
+
if (result.items.length === 0 || items.length >= result.total) {
|
|
29
|
+
return items;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=load-all.uc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/load/load-all.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\n/** A request for every record it keeps: paging is the use case's to set. */\nexport type UnpagedRequest<TEntity extends Entity> = Omit<\n EntityLoadRequest<TEntity>,\n 'page' | 'pageSize'\n>;\n\n/** How many records `loadAllUCFactory` asks the repository for at a time. */\nexport const LOAD_ALL_PAGE_SIZE = 100;\n\n/**\n * Every record the request in `EntityLoadRequestTag` keeps, filtered and\n * sorted as it asks, read page by page until the repository's `total` is\n * reached.\n *\n * The request's own `page` and `pageSize` are ignored: asking for one page\n * as large as can be counted works against an in-memory source, but a real\n * adapter would hand that size to its database.\n */\nexport function loadAllUCFactory<TEntity extends Entity>(\n pageSize: number = LOAD_ALL_PAGE_SIZE,\n) {\n return Effect.gen(function* () {\n const entityRepository = yield* EntityRepositoryTag;\n const entityLoadRequest = yield* EntityLoadRequestTag;\n\n // EntityLoadRequestTag carries no generic type, as in `loadUCFactory`.\n const request = entityLoadRequest as unknown as EntityLoadRequest<TEntity>;\n\n const items: TEntity[] = [];\n for (let page = 1; ; page += 1) {\n const result = yield* entityRepository.load<TEntity>({\n ...request,\n page,\n pageSize,\n });\n items.push(...result.items);\n // An empty page ends the read too, should `total` overstate it.\n if (result.items.length === 0 || items.length >= result.total) {\n return items;\n }\n }\n });\n}\n"],"names":["Effect","EntityRepositoryTag","EntityLoadRequestTag","LOAD_ALL_PAGE_SIZE","loadAllUCFactory","pageSize","gen","entityRepository","entityLoadRequest","request","items","page","result","load","push","length","total"],"mappings":";AACA,SAASA,MAAM,QAAQ,SAAS;AAEhC,SAASC,mBAAmB,QAAQ,wCAAwC;AAC5E,SAASC,oBAAoB,QAAQ,+CAA+C;AAQpF,2EAA2E,GAC3E,OAAO,MAAMC,qBAAqB,IAAI;AAEtC;;;;;;;;CAQC,GACD,OAAO,SAASC,iBACdC,WAAmBF,kBAAkB;IAErC,OAAOH,OAAOM,GAAG,CAAC;QAChB,MAAMC,mBAAmB,OAAON;QAChC,MAAMO,oBAAoB,OAAON;QAEjC,uEAAuE;QACvE,MAAMO,UAAUD;QAEhB,MAAME,QAAmB,EAAE;QAC3B,IAAK,IAAIC,OAAO,IAAKA,QAAQ,EAAG;YAC9B,MAAMC,SAAS,OAAOL,iBAAiBM,IAAI,CAAU,aAChDJ;gBACHE;gBACAN;;YAEFK,MAAMI,IAAI,IAAIF,OAAOF,KAAK;YAC1B,gEAAgE;YAChE,IAAIE,OAAOF,KAAK,CAACK,MAAM,KAAK,KAAKL,MAAMK,MAAM,IAAIH,OAAOI,KAAK,EAAE;gBAC7D,OAAON;YACT;QACF;IACF;AACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type EntifixError, type Entity } from '@entifix/core';
|
|
2
|
+
import { Effect } from 'effect';
|
|
3
|
+
import { EntityLinkResolverTag } from '../../repository/entity-link-resolver.repository.js';
|
|
4
|
+
/** The members of an entity that link to other records. */
|
|
5
|
+
export type LinkMember<TEntity> = {
|
|
6
|
+
[TKey in keyof TEntity & string]: TEntity[TKey] extends {
|
|
7
|
+
readonly entityConstructor: unknown;
|
|
8
|
+
readonly isLoaded: boolean;
|
|
9
|
+
} ? TKey : never;
|
|
10
|
+
}[keyof TEntity & string];
|
|
11
|
+
/**
|
|
12
|
+
* Resolves `members` of every record, in place, through the
|
|
13
|
+
* `EntityLinkResolverTag` in context, and hands the records back.
|
|
14
|
+
*
|
|
15
|
+
* A record read with its linked records (a post with its tags) then reads
|
|
16
|
+
* each through `targetOf`/`targetsOf`, with no `id → record` map built by
|
|
17
|
+
* hand. Every link resolves concurrently; one that fails fails the whole.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveLinksUCFactory<TEntity extends Entity>(records: readonly TEntity[], members: readonly LinkMember<TEntity>[]): Effect.Effect<TEntity[], EntifixError, EntityLinkResolverTag>;
|
|
20
|
+
//# sourceMappingURL=resolve-links.uc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-links.uc.d.ts","sourceRoot":"","sources":["../../../src/use-case/load/resolve-links.uc.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,MAAM,EAEZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qDAAqD,CAAC;AAE5F,2DAA2D;AAC3D,MAAM,MAAM,UAAU,CAAC,OAAO,IAAI;KAC/B,IAAI,IAAI,MAAM,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS;QACtD,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;QACpC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;KAC5B,GACG,IAAI,GACJ,KAAK;CACV,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC;AAM1B;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,SAAS,MAAM,EAC1D,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,OAAO,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,iEAexC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
import { EntityLinkResolverTag } from '../../repository/entity-link-resolver.repository.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves `members` of every record, in place, through the
|
|
5
|
+
* `EntityLinkResolverTag` in context, and hands the records back.
|
|
6
|
+
*
|
|
7
|
+
* A record read with its linked records (a post with its tags) then reads
|
|
8
|
+
* each through `targetOf`/`targetsOf`, with no `id → record` map built by
|
|
9
|
+
* hand. Every link resolves concurrently; one that fails fails the whole.
|
|
10
|
+
*/ export function resolveLinksUCFactory(records, members) {
|
|
11
|
+
return Effect.gen(function*() {
|
|
12
|
+
const resolver = yield* EntityLinkResolverTag;
|
|
13
|
+
yield* Effect.forEach(records.flatMap((record)=>members.map((member)=>record[member].resolve(resolver))), (resolved)=>resolved, {
|
|
14
|
+
concurrency: 'unbounded',
|
|
15
|
+
discard: true
|
|
16
|
+
});
|
|
17
|
+
return [
|
|
18
|
+
...records
|
|
19
|
+
];
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=resolve-links.uc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/use-case/load/resolve-links.uc.ts"],"sourcesContent":["import {\n type EntifixError,\n type Entity,\n type EntityLinkResolver,\n} from '@entifix/core';\nimport { Effect } from 'effect';\n\nimport { EntityLinkResolverTag } from '../../repository/entity-link-resolver.repository.js';\n\n/** The members of an entity that link to other records. */\nexport type LinkMember<TEntity> = {\n [TKey in keyof TEntity & string]: TEntity[TKey] extends {\n readonly entityConstructor: unknown;\n readonly isLoaded: boolean;\n }\n ? TKey\n : never;\n}[keyof TEntity & string];\n\ntype ResolvableLink = {\n resolve(resolver: EntityLinkResolver): Effect.Effect<unknown, EntifixError>;\n};\n\n/**\n * Resolves `members` of every record, in place, through the\n * `EntityLinkResolverTag` in context, and hands the records back.\n *\n * A record read with its linked records (a post with its tags) then reads\n * each through `targetOf`/`targetsOf`, with no `id → record` map built by\n * hand. Every link resolves concurrently; one that fails fails the whole.\n */\nexport function resolveLinksUCFactory<TEntity extends Entity>(\n records: readonly TEntity[],\n members: readonly LinkMember<TEntity>[],\n) {\n return Effect.gen(function* () {\n const resolver = yield* EntityLinkResolverTag;\n yield* Effect.forEach(\n records.flatMap(record =>\n members.map(member =>\n (record[member] as ResolvableLink).resolve(resolver),\n ),\n ),\n resolved => resolved,\n { concurrency: 'unbounded', discard: true },\n );\n return [...records];\n });\n}\n"],"names":["Effect","EntityLinkResolverTag","resolveLinksUCFactory","records","members","gen","resolver","forEach","flatMap","record","map","member","resolve","resolved","concurrency","discard"],"mappings":"AAKA,SAASA,MAAM,QAAQ,SAAS;AAEhC,SAASC,qBAAqB,QAAQ,sDAAsD;AAgB5F;;;;;;;CAOC,GACD,OAAO,SAASC,sBACdC,OAA2B,EAC3BC,OAAuC;IAEvC,OAAOJ,OAAOK,GAAG,CAAC;QAChB,MAAMC,WAAW,OAAOL;QACxB,OAAOD,OAAOO,OAAO,CACnBJ,QAAQK,OAAO,CAACC,CAAAA,SACdL,QAAQM,GAAG,CAACC,CAAAA,SACV,AAACF,MAAM,CAACE,OAAO,CAAoBC,OAAO,CAACN,aAG/CO,CAAAA,WAAYA,UACZ;YAAEC,aAAa;YAAaC,SAAS;QAAK;QAE5C,OAAO;eAAIZ;SAAQ;IACrB;AACF"}
|
|
@@ -3,9 +3,8 @@ import { Context, Effect, Layer } from 'effect';
|
|
|
3
3
|
* The queue shapes a subscriber may ask for (ADR 0030).
|
|
4
4
|
*
|
|
5
5
|
* Duplicated from `SubscriptionMode` in `@entifix/transactions` rather than
|
|
6
|
-
* imported: that package
|
|
7
|
-
*
|
|
8
|
-
* the build on it. The same duplication exists in `tools/slices/src/types.ts`
|
|
6
|
+
* imported: that package is T2, **above** this one at T1, so the edge would
|
|
7
|
+
* point upward and the tier rule fails the build on it. The same duplication exists in `tools/slices/src/types.ts`
|
|
9
8
|
* for the same reason, and both lists are pinned by a spec.
|
|
10
9
|
*/
|
|
11
10
|
export declare const BOUND_SUBSCRIPTION_MODES: readonly ["work", "broadcast"];
|
|
@@ -1 +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
|
|
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;;;;;;;GAOG;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"}
|
|
@@ -3,9 +3,8 @@ import { Context, Effect, Layer, Ref } from 'effect';
|
|
|
3
3
|
* The queue shapes a subscriber may ask for (ADR 0030).
|
|
4
4
|
*
|
|
5
5
|
* Duplicated from `SubscriptionMode` in `@entifix/transactions` rather than
|
|
6
|
-
* imported: that package
|
|
7
|
-
*
|
|
8
|
-
* the build on it. The same duplication exists in `tools/slices/src/types.ts`
|
|
6
|
+
* imported: that package is T2, **above** this one at T1, so the edge would
|
|
7
|
+
* point upward and the tier rule fails the build on it. The same duplication exists in `tools/slices/src/types.ts`
|
|
9
8
|
* for the same reason, and both lists are pinned by a spec.
|
|
10
9
|
*/ export const BOUND_SUBSCRIPTION_MODES = [
|
|
11
10
|
'work',
|
|
@@ -1 +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
|
|
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 is T2, **above** this one at T1, so the edge would\n * point upward and the tier rule fails 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;;;;;;;CAOC,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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entifix/business",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "The ports every adapter implements — repository, session, token, health — and the generic get, load, save and delete use-cases.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,9 +31,6 @@
|
|
|
31
31
|
],
|
|
32
32
|
"nx": {
|
|
33
33
|
"tags": [
|
|
34
|
-
"layer:entifix",
|
|
35
|
-
"scope:shared",
|
|
36
|
-
"entifix:contract",
|
|
37
34
|
"tier:1"
|
|
38
35
|
],
|
|
39
36
|
"sourceRoot": "packages/ts/business/src",
|
|
@@ -55,7 +52,7 @@
|
|
|
55
52
|
},
|
|
56
53
|
"dependencies": {
|
|
57
54
|
"@swc/helpers": "0.5.23",
|
|
58
|
-
"@entifix/core": "0.1.
|
|
55
|
+
"@entifix/core": "0.1.3"
|
|
59
56
|
},
|
|
60
57
|
"peerDependencies": {
|
|
61
58
|
"effect": ">=3.22 <4"
|