@fougere/core 0.16.8-alpha.0 → 0.17.1-alpha.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/README.md +1 -1
- package/dist/CallIdentity.js +2 -2
- package/dist/CallIdentity.js.map +1 -1
- package/dist/Declared.d.ts +2 -0
- package/dist/Declared.d.ts.map +1 -1
- package/dist/FrondDeclaration.d.ts.map +1 -1
- package/dist/FrondDeclaration.js +1 -0
- package/dist/FrondDeclaration.js.map +1 -1
- package/dist/boot/App.d.ts +4 -4
- package/dist/boot/App.d.ts.map +1 -1
- package/dist/boot/AppLifecycle.d.ts +2 -2
- package/dist/boot/AppLifecycle.js +3 -3
- package/dist/boot/AppLifecycle.js.map +1 -1
- package/dist/boot/bootstrap.d.ts.map +1 -1
- package/dist/boot/bootstrap.js +27 -28
- package/dist/boot/bootstrap.js.map +1 -1
- package/dist/boot/card.d.ts.map +1 -1
- package/dist/boot/card.js +30 -29
- package/dist/boot/card.js.map +1 -1
- package/dist/boot/install.d.ts +1 -1
- package/dist/boot/install.d.ts.map +1 -1
- package/dist/boot/install.js +15 -7
- package/dist/boot/install.js.map +1 -1
- package/dist/boot/peerOver.js +2 -2
- package/dist/boot/peerOver.js.map +1 -1
- package/dist/boot/ports.d.ts +2 -0
- package/dist/boot/ports.d.ts.map +1 -1
- package/dist/boot/ports.js +2 -0
- package/dist/boot/ports.js.map +1 -1
- package/dist/boot/remote.d.ts +7 -5
- package/dist/boot/remote.d.ts.map +1 -1
- package/dist/boot/remote.js +42 -29
- package/dist/boot/remote.js.map +1 -1
- package/dist/contract.d.ts +2 -2
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +3 -3
- package/dist/contract.js.map +1 -1
- package/dist/descriptor/ProviderEntry.d.ts +5 -0
- package/dist/descriptor/ProviderEntry.d.ts.map +1 -1
- package/dist/descriptor/bases.d.ts +7 -1
- package/dist/descriptor/bases.d.ts.map +1 -1
- package/dist/descriptor/bases.js +21 -5
- package/dist/descriptor/bases.js.map +1 -1
- package/dist/dispatch/ArgumentResolver.d.ts +7 -0
- package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
- package/dist/dispatch/ArgumentResolver.js +45 -12
- package/dist/dispatch/ArgumentResolver.js.map +1 -1
- package/dist/dispatch/Dispatcher.js +1 -1
- package/dist/dispatch/Dispatcher.js.map +1 -1
- package/dist/dispatch/HandlerFacade.d.ts.map +1 -1
- package/dist/dispatch/HandlerFacade.js +9 -8
- package/dist/dispatch/HandlerFacade.js.map +1 -1
- package/dist/dispatch/InFlight.d.ts +1 -1
- package/dist/dispatch/InFlight.d.ts.map +1 -1
- package/dist/dispatch/InFlight.js +2 -2
- package/dist/dispatch/InFlight.js.map +1 -1
- package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -1
- package/dist/dispatch/LocalRoutePolicy.js +7 -7
- package/dist/dispatch/LocalRoutePolicy.js.map +1 -1
- package/dist/dispatch/PresenterExecutor.d.ts +1 -3
- package/dist/dispatch/PresenterExecutor.d.ts.map +1 -1
- package/dist/dispatch/PresenterExecutor.js +1 -7
- package/dist/dispatch/PresenterExecutor.js.map +1 -1
- package/dist/dispatch/Release.js +0 -2
- package/dist/dispatch/Release.js.map +1 -1
- package/dist/dispatch/RouteRegistry.d.ts +1 -1
- package/dist/dispatch/RouteRegistry.d.ts.map +1 -1
- package/dist/dispatch/RouteRegistry.js +3 -3
- package/dist/dispatch/RouteRegistry.js.map +1 -1
- package/dist/dispatch/StorageGuard.d.ts.map +1 -1
- package/dist/dispatch/StorageGuard.js +3 -9
- package/dist/dispatch/StorageGuard.js.map +1 -1
- package/dist/dispatch/remoteRoutes.d.ts +1 -1
- package/dist/dispatch/remoteRoutes.d.ts.map +1 -1
- package/dist/dispatch/remoteRoutes.js +1 -1
- package/dist/dispatch/remoteRoutes.js.map +1 -1
- package/dist/dispatch/routeNotFound.d.ts.map +1 -1
- package/dist/dispatch/routeNotFound.js +6 -5
- package/dist/dispatch/routeNotFound.js.map +1 -1
- package/dist/dispatch/validateInput.d.ts +1 -1
- package/dist/dispatch/validateInput.d.ts.map +1 -1
- package/dist/dispatch/validateInput.js +1 -3
- package/dist/dispatch/validateInput.js.map +1 -1
- package/dist/entry/facade.d.ts +1 -1
- package/dist/entry/facade.d.ts.map +1 -1
- package/dist/entry/facade.js +2 -2
- package/dist/entry/facade.js.map +1 -1
- package/dist/entry/transport.js +1 -1
- package/dist/entry/transport.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/wire/CallRecord.d.ts +1 -1
- package/dist/wire/CallRecord.d.ts.map +1 -1
- package/dist/wire/FougereError.d.ts +8 -3
- package/dist/wire/FougereError.d.ts.map +1 -1
- package/dist/wire/FougereError.js +13 -4
- package/dist/wire/FougereError.js.map +1 -1
- package/dist/wire/FougereErrorOptions.d.ts +1 -1
- package/dist/wire/FougereErrorOptions.d.ts.map +1 -1
- package/dist/wire/FrondCall.d.ts +2 -2
- package/dist/wire/FrondCall.d.ts.map +1 -1
- package/dist/wire/OperationContext.d.ts +2 -2
- package/dist/wire/OperationContext.d.ts.map +1 -1
- package/dist/wire/RouteAddress.d.ts +1 -1
- package/dist/wire/RouteAddress.d.ts.map +1 -1
- package/dist/wire/RouteAddress.js +5 -5
- package/dist/wire/RouteAddress.js.map +1 -1
- package/dist/wire/RouteAddressInput.d.ts +1 -1
- package/dist/wire/RouteAddressInput.d.ts.map +1 -1
- package/dist/wire/RpcAnswer.d.ts +1 -1
- package/dist/wire/RpcAnswer.d.ts.map +1 -1
- package/dist/wire/RpcAnswer.js +1 -1
- package/dist/wire/RpcAnswer.js.map +1 -1
- package/dist/wire/SignedCall.d.ts +1 -1
- package/dist/wire/SignedCall.d.ts.map +1 -1
- package/dist/wire/StateShape.d.ts +1 -1
- package/dist/wire/StateShape.d.ts.map +1 -1
- package/dist/wire/StateShape.js +2 -2
- package/dist/wire/StateShape.js.map +1 -1
- package/dist/wire/card/IdentityCard.d.ts +10 -3
- package/dist/wire/card/IdentityCard.d.ts.map +1 -1
- package/dist/wire/card/IdentityCard.js +3 -1
- package/dist/wire/card/IdentityCard.js.map +1 -1
- package/dist/wire/drift.d.ts +2 -1
- package/dist/wire/drift.d.ts.map +1 -1
- package/dist/wire/drift.js +19 -16
- package/dist/wire/drift.js.map +1 -1
- package/dist/wire/http-error.js +2 -2
- package/dist/wire/http-error.js.map +1 -1
- package/package.json +3 -3
- package/src/CallIdentity.ts +2 -2
- package/src/Declared.ts +2 -0
- package/src/FrondDeclaration.ts +1 -0
- package/src/boot/App.ts +4 -4
- package/src/boot/AppLifecycle.ts +3 -3
- package/src/boot/bootstrap.ts +29 -30
- package/src/boot/card.ts +38 -29
- package/src/boot/install.ts +14 -8
- package/src/boot/peerOver.ts +2 -2
- package/src/boot/ports.ts +3 -0
- package/src/boot/remote.ts +52 -36
- package/src/contract.ts +3 -3
- package/src/descriptor/ProviderEntry.ts +5 -0
- package/src/descriptor/bases.ts +21 -5
- package/src/dispatch/ArgumentResolver.ts +49 -10
- package/src/dispatch/Dispatcher.ts +1 -1
- package/src/dispatch/HandlerFacade.ts +9 -10
- package/src/dispatch/InFlight.ts +2 -2
- package/src/dispatch/LocalRoutePolicy.ts +7 -7
- package/src/dispatch/PresenterExecutor.ts +0 -4
- package/src/dispatch/Release.ts +0 -2
- package/src/dispatch/RouteRegistry.ts +3 -3
- package/src/dispatch/StorageGuard.ts +3 -9
- package/src/dispatch/remoteRoutes.ts +2 -2
- package/src/dispatch/routeNotFound.ts +6 -5
- package/src/dispatch/validateInput.ts +0 -4
- package/src/entry/facade.ts +2 -2
- package/src/entry/transport.ts +1 -1
- package/src/index.ts +1 -1
- package/src/wire/CallRecord.ts +1 -1
- package/src/wire/FougereError.ts +16 -5
- package/src/wire/FougereErrorOptions.ts +1 -1
- package/src/wire/FrondCall.ts +2 -2
- package/src/wire/OperationContext.ts +2 -2
- package/src/wire/RouteAddress.ts +5 -5
- package/src/wire/RouteAddressInput.ts +1 -1
- package/src/wire/RpcAnswer.ts +1 -1
- package/src/wire/SignedCall.ts +1 -1
- package/src/wire/StateShape.ts +2 -2
- package/src/wire/card/IdentityCard.ts +9 -7
- package/src/wire/drift.ts +22 -27
- package/src/wire/http-error.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityCard.d.ts","sourceRoot":"","sources":["../../../src/wire/card/IdentityCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,
|
|
1
|
+
{"version":3,"file":"IdentityCard.d.ts","sourceRoot":"","sources":["../../../src/wire/card/IdentityCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,8EAA8E;QAC9E,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,gBAAgB,CAAA;SAAE,EAAE,CAAC;QACvD;;;WAGG;QACH,OAAO,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,EAAE,CAAA;SAAE,EAAE,CAAC;QAC3C,oFAAoF;QACpF,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,gBAAgB,CAAA;SAAE,EAAE,CAAC;KACtD,EAAE,CAAC;CACL;AAED,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAW/E"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ErrorCode } from '../ErrorCode.js';
|
|
2
2
|
import { FougereError } from '../FougereError.js';
|
|
3
|
-
/** The shape a card must have to be walked — `fronds`, and each frond's `facades`. */
|
|
3
|
+
/** The shape a card must have to be walked — `fronds`, and each frond's `entities` and `facades`. */
|
|
4
4
|
export function assertIdentityCard(value, source) {
|
|
5
5
|
const card = value;
|
|
6
6
|
const fronds = Array.isArray(card?.fronds) ? card.fronds : undefined;
|
|
@@ -11,6 +11,8 @@ export function assertIdentityCard(value, source) {
|
|
|
11
11
|
throw cardRefusal(source, 'a frond with no name');
|
|
12
12
|
if (!Array.isArray(frond.facades))
|
|
13
13
|
throw cardRefusal(source, `frond '${frond.name}' has no valid facades array`);
|
|
14
|
+
if (!Array.isArray(frond.entities))
|
|
15
|
+
throw cardRefusal(source, `frond '${frond.name}' has no valid entities array`);
|
|
14
16
|
}
|
|
15
17
|
return card;
|
|
16
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IdentityCard.js","sourceRoot":"","sources":["../../../src/wire/card/IdentityCard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"IdentityCard.js","sourceRoot":"","sources":["../../../src/wire/card/IdentityCard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAmBlD,qGAAqG;AACrG,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,MAAc;IAC/D,MAAM,IAAI,GAAG,KAAiC,CAAC;IAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,IAAI,CAAC,MAAM;QAAE,MAAM,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC1D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAChG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,MAAM,WAAW,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,IAAI,8BAA8B,CAAC,CAAC;QACjH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,MAAM,WAAW,CAAC,MAAM,EAAE,UAAU,KAAK,CAAC,IAAI,+BAA+B,CAAC,CAAC;IACrH,CAAC;IAED,OAAO,IAAoB,CAAC;AAC9B,CAAC;AAED,SAAS,WAAW,CAAC,MAAc,EAAE,IAAY;IAC/C,OAAO,IAAI,YAAY,CAAC;QACtB,IAAI,EAAE,SAAS,CAAC,cAAc;QAC9B,OAAO,EACL,GAAG,MAAM,uCAAuC,IAAI,KAAK;cACvD,mGAAmG;cACnG,+FAA+F;KACpG,CAAC,CAAC;AACL,CAAC"}
|
package/dist/wire/drift.d.ts
CHANGED
|
@@ -10,9 +10,10 @@ export interface CardDrift {
|
|
|
10
10
|
facade: string;
|
|
11
11
|
ops: string[];
|
|
12
12
|
}[];
|
|
13
|
-
/**
|
|
13
|
+
/** What an operation the consumer still calls answers, and how it moved. */
|
|
14
14
|
shapes: {
|
|
15
15
|
facade: string;
|
|
16
|
+
op: string;
|
|
16
17
|
changes: Change[];
|
|
17
18
|
}[];
|
|
18
19
|
/** A fact the consumer subscribes to whose shape moved, or that is gone. */
|
package/dist/wire/drift.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drift.d.ts","sourceRoot":"","sources":["../../src/wire/drift.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,MAAM,EAAyB,MAAM,iBAAiB,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qEAAqE;IACrE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAChD,
|
|
1
|
+
{"version":3,"file":"drift.d.ts","sourceRoot":"","sources":["../../src/wire/drift.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,MAAM,EAAyB,MAAM,iBAAiB,CAAC;AAC3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D,uFAAuF;AACvF,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,qEAAqE;IACrE,UAAU,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAChD,4EAA4E;IAC5E,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAC5D,4EAA4E;IAC5E,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;KAAE,EAAE,CAAC;CACvD;AAuBD,mFAAmF;AACnF,wBAAgB,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAO1F;AAmDD,uDAAuD;AACvD,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAKhD;AAED,8CAA8C;AAC9C,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,EAAE,CAalD"}
|
package/dist/wire/drift.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Card } from '@fougere/schema';
|
|
2
|
+
/** Every facade of a card, by name, and what each of its operations answers. */
|
|
2
3
|
function facadesOf(card, frond) {
|
|
3
4
|
const found = new Map();
|
|
4
5
|
for (const one of card.fronds) {
|
|
5
6
|
if (one.name !== frond)
|
|
6
7
|
continue;
|
|
7
|
-
for (const facade of one.facades)
|
|
8
|
-
found.set(facade.name,
|
|
9
|
-
}
|
|
8
|
+
for (const facade of one.facades)
|
|
9
|
+
found.set(facade.name, new Map(facade.ops.map((op) => [op.name, op.output])));
|
|
10
10
|
}
|
|
11
11
|
return found;
|
|
12
12
|
}
|
|
@@ -27,25 +27,28 @@ export function driftOf(mine, theirs, frond) {
|
|
|
27
27
|
driftInFacts(factsOf(mine, frond), factsOf(theirs, frond), drift);
|
|
28
28
|
return drift;
|
|
29
29
|
}
|
|
30
|
-
/** A door that is gone, an operation it no longer answers, or
|
|
30
|
+
/** A door that is gone, an operation it no longer answers, or an answer that changed shape. */
|
|
31
31
|
function driftInDoors(mine, theirs, drift) {
|
|
32
|
-
for (const [name,
|
|
32
|
+
for (const [name, ops] of mine) {
|
|
33
33
|
const there = theirs.get(name);
|
|
34
34
|
if (!there) {
|
|
35
35
|
drift.missingDoors.push(name);
|
|
36
36
|
continue;
|
|
37
37
|
}
|
|
38
|
-
const missing = [...
|
|
38
|
+
const missing = [...ops.keys()].filter((op) => !there.has(op));
|
|
39
39
|
if (missing.length > 0)
|
|
40
40
|
drift.missingOps.push({ facade: name, ops: missing.sort() });
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
for (const [op, output] of ops) {
|
|
42
|
+
const answered = there.get(op);
|
|
43
|
+
if (!output || !answered)
|
|
44
|
+
continue;
|
|
45
|
+
// `Card.diff` never guesses a rename — a field gone plus a field appeared lands in
|
|
46
|
+
// `ambiguous`, and only a declaration settles it. Here nobody can declare one, so the
|
|
47
|
+
// pair is reported as it is and a human reads it.
|
|
48
|
+
const moved = Card.fromDescriptor(output).diff(Card.fromDescriptor(answered));
|
|
49
|
+
if (moved.changes.length > 0)
|
|
50
|
+
drift.shapes.push({ facade: name, op, changes: moved.changes });
|
|
51
|
+
}
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
/** A fact nobody announces any more, or one whose payload moved under its readers. */
|
|
@@ -77,9 +80,9 @@ export function explain(drift) {
|
|
|
77
80
|
lines.push(`${drift.frond}.${facade} — you call it, it is not served`);
|
|
78
81
|
for (const { facade, ops } of drift.missingOps)
|
|
79
82
|
lines.push(`${drift.frond}.${facade} — gone: ${ops.join(', ')}`);
|
|
80
|
-
for (const { facade, changes } of drift.shapes) {
|
|
83
|
+
for (const { facade, op, changes } of drift.shapes) {
|
|
81
84
|
for (const change of changes)
|
|
82
|
-
lines.push(`${drift.frond}.${facade} — ${describe(change)}`);
|
|
85
|
+
lines.push(`${drift.frond}.${facade}.${op} — ${describe(change)}`);
|
|
83
86
|
}
|
|
84
87
|
for (const { fact, changes } of drift.facts) {
|
|
85
88
|
if (changes === 'gone') {
|
package/dist/wire/drift.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drift.js","sourceRoot":"","sources":["../../src/wire/drift.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAsC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"drift.js","sourceRoot":"","sources":["../../src/wire/drift.ts"],"names":[],"mappings":"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"}
|
package/dist/wire/http-error.js
CHANGED
|
@@ -36,12 +36,12 @@ function httpStatusFor(code) {
|
|
|
36
36
|
export function toPublicError(err) {
|
|
37
37
|
if (err.code !== ErrorCode.INTERNAL_ERROR)
|
|
38
38
|
return err.toJSON();
|
|
39
|
-
const where = [err.
|
|
39
|
+
const where = [err.address, err.operation].filter(Boolean).join('.');
|
|
40
40
|
log.error(`${where || 'internal'}: ${err.message}`, err.cause ?? err);
|
|
41
41
|
return {
|
|
42
42
|
code: ErrorCode.INTERNAL_ERROR,
|
|
43
43
|
message: 'Internal error',
|
|
44
|
-
...(err.
|
|
44
|
+
...(err.address && { address: err.address }),
|
|
45
45
|
...(err.operation && { operation: err.operation }),
|
|
46
46
|
};
|
|
47
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-error.js","sourceRoot":"","sources":["../../src/wire/http-error.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C;;;GAGG;AACH,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,WAAW,GAA8B;IAC7C,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,GAAG;IAClC,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;IAC5B,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,GAAG;IAC7B,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,GAAG;IAC1B,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,GAAG;IAC1B,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG;IACrB,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG;IACzB,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG;IACvB,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,GAAG;IACnC,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,GAAG;IACpC,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,GAAG;IAClC,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,GAAG;IACrC,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,GAAG;IAClC,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,GAAG;IAChC,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,GAAG;IAC/B,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,GAAG;IAChC,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;IAC5B,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,GAAG;IACpC,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,GAAG;CACjC,CAAC;AAEF,kDAAkD;AAClD,SAAS,aAAa,CAAC,IAAe;IACpC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;AAClC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,aAAa,CAAC,GAAiB;IAC7C,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,cAAc;QAAE,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"http-error.js","sourceRoot":"","sources":["../../src/wire/http-error.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C;;;GAGG;AACH,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,WAAW,GAA8B;IAC7C,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,GAAG;IAClC,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;IAC5B,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,GAAG;IAC7B,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,GAAG;IAC1B,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,GAAG;IAC1B,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,GAAG;IACrB,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG;IACzB,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG;IACvB,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,GAAG;IACnC,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,GAAG;IACpC,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,GAAG;IAClC,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,GAAG;IACrC,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,GAAG;IAClC,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,GAAG;IAChC,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,GAAG;IAC/B,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,GAAG;IAChC,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,GAAG;IAC5B,CAAC,SAAS,CAAC,mBAAmB,CAAC,EAAE,GAAG;IACpC,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,GAAG;CACjC,CAAC;AAEF,kDAAkD;AAClD,SAAS,aAAa,CAAC,IAAe;IACpC,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;AAClC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,aAAa,CAAC,GAAiB;IAC7C,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,cAAc;QAAE,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC;IAC/D,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,UAAU,KAAK,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;IAEtE,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,cAAc;QAC9B,OAAO,EAAE,gBAAgB;QACzB,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;QAC5C,GAAG,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;KACnD,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;QAChC,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;IACvE,CAAC;IACD,kFAAkF;IAClF,0EAA0E;IAC1E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC;QAC9B,IAAI,EAAE,SAAS,CAAC,cAAc;QAC9B,OAAO,EAAG,GAA4B,EAAE,OAAO,IAAI,gBAAgB;QACnE,KAAK,EAAE,GAAG;KACX,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;AACtD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1-alpha.0",
|
|
4
4
|
"description": "The core — scan, call contract, façades, remote stand-ins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"tsconfig"
|
|
62
62
|
],
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@fougere/container": "0.
|
|
65
|
-
"@fougere/schema": "0.
|
|
64
|
+
"@fougere/container": "0.17.1-alpha.0",
|
|
65
|
+
"@fougere/schema": "0.17.1-alpha.0",
|
|
66
66
|
"dequal": "^2.0.3"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
package/src/CallIdentity.ts
CHANGED
|
@@ -27,7 +27,7 @@ async function digestOf(input: unknown): Promise<string> {
|
|
|
27
27
|
/** What the envelope pins, as one comparable value. */
|
|
28
28
|
async function boundTo(call: SignedCall) {
|
|
29
29
|
return {
|
|
30
|
-
|
|
30
|
+
address: call.address,
|
|
31
31
|
op: call.op,
|
|
32
32
|
params: call.params ?? {},
|
|
33
33
|
query: call.query ?? {},
|
|
@@ -110,7 +110,7 @@ async function openWith(root: Verifier, token: string, presented: SignedCall): P
|
|
|
110
110
|
// call. Without it a captured envelope is a blank cheque until it expires.
|
|
111
111
|
const bound = JSON.stringify(payload.bound);
|
|
112
112
|
if (bound !== JSON.stringify(await boundTo(presented))) {
|
|
113
|
-
throw new Error(`Envelope was signed for a different call than ${presented.
|
|
113
|
+
throw new Error(`Envelope was signed for a different call than ${presented.address}.${presented.op}`);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
return {
|
package/src/Declared.ts
CHANGED
|
@@ -6,4 +6,6 @@ export type Declared = AbstractCtor | (Omit<DeclaredSubject, 'ctor'> & {
|
|
|
6
6
|
ctor: AbstractCtor;
|
|
7
7
|
/** The container key, when the class's own name cannot be trusted to survive a build. */
|
|
8
8
|
name?: string;
|
|
9
|
+
/** The class is `abstract` — a port and never a realization. The scan writes it; TypeScript erases it. */
|
|
10
|
+
abstract?: true;
|
|
9
11
|
});
|
package/src/FrondDeclaration.ts
CHANGED
|
@@ -151,6 +151,7 @@ export function frond(name: string, declared: FrondDeclaration = {}): FrondDescr
|
|
|
151
151
|
ctor: ctorOf(p),
|
|
152
152
|
deps: depsOf(p),
|
|
153
153
|
filePath: '',
|
|
154
|
+
...(typeof p !== 'function' && p.abstract ? { abstract: true as const } : {}),
|
|
154
155
|
}));
|
|
155
156
|
|
|
156
157
|
const seeds: SeedEntry[] = (declared.seeds ?? []).map((s) => ({
|
package/src/boot/App.ts
CHANGED
|
@@ -28,12 +28,12 @@ export interface App extends DispatchPort {
|
|
|
28
28
|
*/
|
|
29
29
|
schemaFor(entity: string): Promise<SchemaView>;
|
|
30
30
|
/** The facade a name exposes to one audience, or `undefined` when it exposes none. */
|
|
31
|
-
facadeFor(
|
|
31
|
+
facadeFor(address: string, surface?: string): Record<string, Function> | undefined;
|
|
32
32
|
/**
|
|
33
33
|
* The canonical contracts served beside a facade, after prefab + scan + config, binding, kind,
|
|
34
34
|
* topology and surface resolution.
|
|
35
35
|
*/
|
|
36
|
-
operationsFor(
|
|
36
|
+
operationsFor(address: string, surface?: string): EffectiveOperationsMap | undefined;
|
|
37
37
|
/** The facts this app has a listener for — what a carrier must subscribe to on its behalf. */
|
|
38
38
|
listensTo(): string[];
|
|
39
39
|
/** Hand a fact that came from OUTSIDE to the listeners in this process — and stop there. */
|
|
@@ -64,6 +64,6 @@ export interface App extends DispatchPort {
|
|
|
64
64
|
observe(observer: DispatchObserver): () => void;
|
|
65
65
|
/** Register a global app middleware (runs on every operation). */
|
|
66
66
|
use(middleware: AppMiddleware): void;
|
|
67
|
-
/** Register an app middleware scoped to
|
|
68
|
-
use(
|
|
67
|
+
/** Register an app middleware scoped to one address. */
|
|
68
|
+
use(address: string, middleware: AppMiddleware): void;
|
|
69
69
|
}
|
package/src/boot/AppLifecycle.ts
CHANGED
|
@@ -58,8 +58,8 @@ export async function closeAll(levels: readonly (() => unknown)[], refusals: str
|
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* The schema slot, as every boot fills it: the database is READ against the entities, and a
|
|
61
|
-
* boot that finds it behind refuses rather than writing to it. Writing is `fougere migrate
|
|
62
|
-
*
|
|
61
|
+
* boot that finds it behind refuses rather than writing to it. Writing is `fougere migrate`,
|
|
62
|
+
* or `migrating()` stated by a process whose database is born with it.
|
|
63
63
|
*
|
|
64
64
|
* Documented: [lifecycle](https://fougere.dev/docs/infra/lifecycle).
|
|
65
65
|
*/
|
|
@@ -75,7 +75,7 @@ export function checking(pending?: (app: App) => Promise<readonly string[]>): Ex
|
|
|
75
75
|
throw new Error(
|
|
76
76
|
`Fougere boot refused: the database is behind the entities (${behind.length}):\n`
|
|
77
77
|
+ behind.map((line) => ` ${line}`).join('\n')
|
|
78
|
-
+ '\n
|
|
78
|
+
+ '\n Your database: fougere migrate --latest --apply — a shared one: fougere freeze, then fougere migrate --apply',
|
|
79
79
|
);
|
|
80
80
|
},
|
|
81
81
|
};
|
package/src/boot/bootstrap.ts
CHANGED
|
@@ -37,7 +37,7 @@ import { resolveEffectiveOperations, type EffectiveOperationModel } from '../Eff
|
|
|
37
37
|
import { type EffectiveOperationsMap } from '../EffectiveOperationsMap.js';
|
|
38
38
|
|
|
39
39
|
import { InFlight } from '../dispatch/InFlight.js';
|
|
40
|
-
import {
|
|
40
|
+
import { RPC_ADDRESS } from '../wire/RpcAnswer.js';
|
|
41
41
|
import { Invocation } from '../wire/Invocation.js';
|
|
42
42
|
import { addressOf, facadeKeyOf, isFacadeKey } from '../wire/Facade.js';
|
|
43
43
|
import { identityCardOf } from './card.js';
|
|
@@ -227,7 +227,7 @@ function warnAboutRelations(relations: RelationCheck[], hosting: Hosting, log: L
|
|
|
227
227
|
function peerBehind(entity: string, router: RemoteRouter): Peer {
|
|
228
228
|
const ask = async (op: string, params: Record<string, unknown>): Promise<unknown> =>
|
|
229
229
|
(await router.route(entity)).transport(
|
|
230
|
-
{
|
|
230
|
+
{ address: RPC_ADDRESS, op },
|
|
231
231
|
{ ...Invocation.empty, params: params as never },
|
|
232
232
|
);
|
|
233
233
|
|
|
@@ -260,7 +260,7 @@ interface Dispatching {
|
|
|
260
260
|
dispatcher: Dispatcher;
|
|
261
261
|
/** Stays home: what this process serves, and nothing else. */
|
|
262
262
|
localDispatcher: Dispatcher;
|
|
263
|
-
getMiddlewares(
|
|
263
|
+
getMiddlewares(address: string): AppMiddleware[];
|
|
264
264
|
/** The one place a middleware is taken on — `App.use` is its late form, a frond's directory its early one. */
|
|
265
265
|
use(middleware: AppMiddleware, entity?: string): void;
|
|
266
266
|
}
|
|
@@ -297,7 +297,7 @@ function dispatching(
|
|
|
297
297
|
new LocalRoutePolicy((surface) => fronds.servedNames(surface)),
|
|
298
298
|
journalOf,
|
|
299
299
|
),
|
|
300
|
-
getMiddlewares: (
|
|
300
|
+
getMiddlewares: (address) => [...globalMiddlewares, ...(scopedMiddlewares.get(address) ?? [])],
|
|
301
301
|
use(middleware, entity) {
|
|
302
302
|
if (entity === undefined) {
|
|
303
303
|
globalMiddlewares.push(middleware);
|
|
@@ -427,17 +427,16 @@ function readings(
|
|
|
427
427
|
const found = fronds.entity(entity);
|
|
428
428
|
if (found) return found.entityClass;
|
|
429
429
|
if (remoteRouter) {
|
|
430
|
-
|
|
431
|
-
//
|
|
432
|
-
|
|
433
|
-
if (!
|
|
430
|
+
// An address that stores nothing publishes ops and no shape. Saying so beats handing back
|
|
431
|
+
// an empty schema, which would validate every input it was given.
|
|
432
|
+
const stored = await remoteRouter.schemaOf(entity);
|
|
433
|
+
if (!stored) {
|
|
434
434
|
throw new Error(
|
|
435
|
-
`
|
|
436
|
-
+ `Call its operations through the façade instead.`,
|
|
435
|
+
`No remote stores '${entity}', so it has no schema. Call its operations through the façade instead.`,
|
|
437
436
|
);
|
|
438
437
|
}
|
|
439
438
|
|
|
440
|
-
return
|
|
439
|
+
return stored;
|
|
441
440
|
}
|
|
442
441
|
throw new Error(notLoaded(entity));
|
|
443
442
|
};
|
|
@@ -471,40 +470,40 @@ function readings(
|
|
|
471
470
|
};
|
|
472
471
|
|
|
473
472
|
/** THE membership rule, stated once — every projection reads this and nothing else. */
|
|
474
|
-
const facadeFor = (
|
|
475
|
-
if (!surface) return facadeAt(facadeKeyOf(
|
|
473
|
+
const facadeFor = (address: string, surface?: string): Record<string, Function> | undefined => {
|
|
474
|
+
if (!surface) return facadeAt(facadeKeyOf(address), true);
|
|
476
475
|
|
|
477
|
-
const own = facadeAt(facadeKeyOf(
|
|
478
|
-
if (!fronds.owner(
|
|
479
|
-
sayNoSurfaceAcross(
|
|
476
|
+
const own = facadeAt(facadeKeyOf(address, surface), false);
|
|
477
|
+
if (!fronds.owner(address)) {
|
|
478
|
+
sayNoSurfaceAcross(address, surface);
|
|
480
479
|
|
|
481
480
|
return own;
|
|
482
481
|
}
|
|
483
482
|
|
|
484
|
-
const admitted = fronds.admits(surface,
|
|
483
|
+
const admitted = fronds.admits(surface, address);
|
|
485
484
|
if (admitted === false) return undefined;
|
|
486
485
|
if (own || admitted === undefined) return own;
|
|
487
486
|
|
|
488
|
-
const fallback = facadeAt(facadeKeyOf(
|
|
487
|
+
const fallback = facadeAt(facadeKeyOf(address), false);
|
|
489
488
|
|
|
490
489
|
return fallback
|
|
491
490
|
? facadeOperations(
|
|
492
491
|
localDispatcher,
|
|
493
|
-
|
|
494
|
-
routeRegistry.operationNames(
|
|
492
|
+
address,
|
|
493
|
+
routeRegistry.operationNames(address, surface),
|
|
495
494
|
surface,
|
|
496
495
|
)
|
|
497
496
|
: undefined;
|
|
498
497
|
};
|
|
499
498
|
|
|
500
|
-
const operationsFor = (
|
|
501
|
-
if (!surface) return effectiveByKey.get(facadeKeyOf(
|
|
499
|
+
const operationsFor = (address: string, surface?: string): EffectiveOperationsMap | undefined => {
|
|
500
|
+
if (!surface) return effectiveByKey.get(facadeKeyOf(address));
|
|
502
501
|
|
|
503
|
-
const own = effectiveByKey.get(facadeKeyOf(
|
|
504
|
-
const admitted = fronds.admits(surface,
|
|
502
|
+
const own = effectiveByKey.get(facadeKeyOf(address, surface));
|
|
503
|
+
const admitted = fronds.admits(surface, address);
|
|
505
504
|
if (admitted === false) return undefined;
|
|
506
505
|
|
|
507
|
-
return admitted ? (own ?? effectiveByKey.get(facadeKeyOf(
|
|
506
|
+
return admitted ? (own ?? effectiveByKey.get(facadeKeyOf(address))) : own;
|
|
508
507
|
};
|
|
509
508
|
|
|
510
509
|
const presenterFor = (entity: string): unknown | undefined => ownedBy(fronds, container, entity, presenterKeyOf(entity));
|
|
@@ -585,11 +584,11 @@ function answerRemotes(
|
|
|
585
584
|
: undefined));
|
|
586
585
|
|
|
587
586
|
const remoteFacades = new Map<string, Record<string, Function>>();
|
|
588
|
-
routeRegistry.addResolver(remoteRoutes((
|
|
589
|
-
const known = remoteFacades.get(
|
|
587
|
+
routeRegistry.addResolver(remoteRoutes((address) => {
|
|
588
|
+
const known = remoteFacades.get(address);
|
|
590
589
|
if (known) return known;
|
|
591
|
-
const facade = createRemoteFacade(
|
|
592
|
-
remoteFacades.set(
|
|
590
|
+
const facade = createRemoteFacade(address, remoteRouter, getMiddlewares, state);
|
|
591
|
+
remoteFacades.set(address, facade);
|
|
593
592
|
|
|
594
593
|
return facade;
|
|
595
594
|
}));
|
|
@@ -598,7 +597,7 @@ function answerRemotes(
|
|
|
598
597
|
/** Refused rather than replaced: two declarations of one name would make the answer depend on wiring order. */
|
|
599
598
|
function serveRpcOn(routeRegistry: RouteRegistry): App['serveRpc'] {
|
|
600
599
|
return (op, answer) => {
|
|
601
|
-
const address = new RouteAddress({
|
|
600
|
+
const address = new RouteAddress({ address: RPC_ADDRESS, operation: op });
|
|
602
601
|
if (routeRegistry.find(address)) {
|
|
603
602
|
throw new Error(
|
|
604
603
|
`[claim] rpc operation '${op}' is already served; a second declaration would depend on wiring order.\n`
|
package/src/boot/card.ts
CHANGED
|
@@ -12,6 +12,9 @@ type AnyFacade = Record<string, (invocation?: InvocationContext) => Promise<unkn
|
|
|
12
12
|
/** Serialize what the app hosts, for one audience. */
|
|
13
13
|
export function identityCardOf(app: App, surface?: string): IdentityCard {
|
|
14
14
|
const declared = app.fronds.schemas();
|
|
15
|
+
// An op's output that IS an entity travels under the entity's name, so a reader of the card
|
|
16
|
+
// ties it to that entity instead of guessing from the address.
|
|
17
|
+
const entityNames = new Map([...declared].map(([name, schema]) => [schema, name]));
|
|
15
18
|
|
|
16
19
|
return {
|
|
17
20
|
// What this app SERVES, never what instruments it. A frond an extension BROUGHT is a
|
|
@@ -20,31 +23,26 @@ export function identityCardOf(app: App, surface?: string): IdentityCard {
|
|
|
20
23
|
// facade and routing refused: `Two remotes serve 'export'`. `FrondDescriptor.brought` is
|
|
21
24
|
// the mark `calls`' panel and `rpc.topology` already read.
|
|
22
25
|
fronds: app.fronds.filter((frond) => !frond.brought).map((frond) => {
|
|
23
|
-
// What the frond answers to,
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
26
|
+
// What the frond answers to, and apart from it what it stores: an address is where a
|
|
27
|
+
// call goes, an entity is the shape of a row, and a handler may carry none.
|
|
28
|
+
const addresses = [...new Set(frond.handlers.map((handler) => handler.address))];
|
|
29
|
+
|
|
30
|
+
// An entity no served op takes or answers stays off the card: publishing it would give
|
|
31
|
+
// away the shape of a table nobody can reach — the auth tables, typically.
|
|
32
|
+
const reached = new Set<string>();
|
|
33
|
+
const facades = addresses.flatMap((address) => {
|
|
34
|
+
const ops = facadeOps(app, address, entityNames, reached, surface);
|
|
35
|
+
|
|
36
|
+
return ops.length === 0 ? [] : [{ name: address, ops }];
|
|
37
|
+
});
|
|
33
38
|
|
|
34
39
|
return {
|
|
35
40
|
name: frond.name,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return [{
|
|
42
|
-
name: address,
|
|
43
|
-
ops,
|
|
44
|
-
// Absent when nothing of that name is stored. A facade is still a facade.
|
|
45
|
-
...(entity ? { schema: Card.fromSchema(entity.entityClass, address).descriptor } : {}),
|
|
46
|
-
}];
|
|
47
|
-
}),
|
|
41
|
+
entities: frond.entities.filter((entity) => reached.has(entity.name)).map((entity) => ({
|
|
42
|
+
name: entity.name,
|
|
43
|
+
schema: Card.fromSchema(entity.entityClass, entity.name).descriptor,
|
|
44
|
+
})),
|
|
45
|
+
facades,
|
|
48
46
|
/** What leaves on its own — the same list on every surface, deliberately. */
|
|
49
47
|
facts: factsAnnouncedBy(frond.handlers).map((name) => {
|
|
50
48
|
const entityClass = declared.get(name);
|
|
@@ -56,19 +54,25 @@ export function identityCardOf(app: App, surface?: string): IdentityCard {
|
|
|
56
54
|
};
|
|
57
55
|
}
|
|
58
56
|
|
|
59
|
-
function facadeOps(
|
|
57
|
+
function facadeOps(
|
|
58
|
+
app: App,
|
|
59
|
+
address: string,
|
|
60
|
+
entityNames: Map<unknown, string>,
|
|
61
|
+
reached: Set<string>,
|
|
62
|
+
surface?: string,
|
|
63
|
+
): CardOp[] {
|
|
60
64
|
let facade: AnyFacade;
|
|
61
65
|
try {
|
|
62
|
-
facade = app.container.resolve<AnyFacade>(facadeKeyOf(
|
|
66
|
+
facade = app.container.resolve<AnyFacade>(facadeKeyOf(address, surface));
|
|
63
67
|
} catch {
|
|
64
68
|
return [];
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
// The façade is the list of names; the model is the resolved terms.
|
|
68
|
-
const effective = app.operationsFor(
|
|
72
|
+
const effective = app.operationsFor(address, surface);
|
|
69
73
|
if (!effective) {
|
|
70
74
|
throw new Error(
|
|
71
|
-
`Facade '${facadeKeyOf(
|
|
75
|
+
`Facade '${facadeKeyOf(address, surface)}' exists without an effective operation table. `
|
|
72
76
|
+ 'A facade and its table are built together, so no declaration can produce this.',
|
|
73
77
|
);
|
|
74
78
|
}
|
|
@@ -77,16 +81,21 @@ function facadeOps(app: App, entityName: string, surface?: string): CardOp[] {
|
|
|
77
81
|
const contract = effective.get(name);
|
|
78
82
|
if (!contract) {
|
|
79
83
|
throw new Error(
|
|
80
|
-
`Facade '${facadeKeyOf(
|
|
84
|
+
`Facade '${facadeKeyOf(address, surface)}' serves '${name}' without an effective contract. `
|
|
81
85
|
+ 'A facade and its table are built together, so no declaration can produce this.',
|
|
82
86
|
);
|
|
83
87
|
}
|
|
84
88
|
|
|
89
|
+
for (const view of [contract.input, contract.output]) {
|
|
90
|
+
const entity = entityNames.get(view);
|
|
91
|
+
if (entity) reached.add(entity);
|
|
92
|
+
}
|
|
93
|
+
|
|
85
94
|
return {
|
|
86
95
|
name,
|
|
87
96
|
...(contract?.description && { description: contract.description }),
|
|
88
|
-
...(contract?.input && { input: Card.fromSchema(contract.input, name).descriptor }),
|
|
89
|
-
...(contract?.output && { output: Card.fromSchema(contract.output, name).descriptor }),
|
|
97
|
+
...(contract?.input && { input: Card.fromSchema(contract.input, entityNames.get(contract.input) ?? name).descriptor }),
|
|
98
|
+
...(contract?.output && { output: Card.fromSchema(contract.output, entityNames.get(contract.output) ?? name).descriptor }),
|
|
90
99
|
...(contract?.cardinality && { cardinality: contract.cardinality }),
|
|
91
100
|
...(contract.errors?.length ? { errors: contract.errors } : {}),
|
|
92
101
|
kind: contract.kind,
|
package/src/boot/install.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { targetOf } from '../prefab/prefab.js';
|
|
|
28
28
|
import { ownersOf, sharedNames, storageInUserCode, crudOnOwned } from './ownership.js';
|
|
29
29
|
import { refuseArityDrift } from './arity.js';
|
|
30
30
|
import { StorageGuard } from '../dispatch/StorageGuard.js';
|
|
31
|
-
import { portBindings, seamChains, wrapping, SEAMS } from './ports.js';
|
|
31
|
+
import { heldKeyOf, portBindings, seamChains, wrapping, SEAMS } from './ports.js';
|
|
32
32
|
import { contractsKeyOf, facadeKeyOf } from '../wire/Facade.js';
|
|
33
33
|
import { inheritsCrud, subjectOf } from '../prefab/CrudConstructor.js';
|
|
34
34
|
import { repositoryKeyOf } from '../prefab/RepositoryConstructor.js';
|
|
@@ -77,7 +77,7 @@ export interface Assembly {
|
|
|
77
77
|
frondOf: Map<string, string>;
|
|
78
78
|
contractsOf: (operations: EffectiveOperationsMap) => OperationsMap;
|
|
79
79
|
/** Read at call time and never at boot, so a late registration still applies. */
|
|
80
|
-
getMiddlewares: (
|
|
80
|
+
getMiddlewares: (address: string) => AppMiddleware[];
|
|
81
81
|
/** Take a middleware on — every entity when no entity is named. */
|
|
82
82
|
use: (middleware: AppMiddleware, entity?: string) => void;
|
|
83
83
|
/**
|
|
@@ -310,17 +310,23 @@ function registerProviders(
|
|
|
310
310
|
// Registered from the INSIDE OUT, each wrapper asking for the one it stands in front
|
|
311
311
|
// of: the container resolves a dep by NAME, so wrapping is a substituted key and
|
|
312
312
|
// needs nothing of the container itself. The outermost answers under the port.
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
const realization = chain.at(-1)!;
|
|
314
|
+
const held = realization.deps.includes(port);
|
|
315
|
+
const wrappers = held ? chain : chain.slice(0, -1);
|
|
316
|
+
let inner = held ? heldKeyOf(port) : nameOf(realization);
|
|
317
|
+
if (held) scope.registerValue(inner, scope.resolve(port));
|
|
318
|
+
for (const wrapper of wrappers.slice(1).reverse()) {
|
|
315
319
|
const deps = ownLogger(nameOf(wrapper), wrapper.deps).map((dep) => (dep === port ? inner : dep));
|
|
316
320
|
inner = nameOf(wrapper);
|
|
317
321
|
scope.register(inner, wrapper.ctor, { deps, ...lifetimeOf(wrapper.ctor) });
|
|
318
322
|
}
|
|
319
323
|
const outermost = chain[0]!;
|
|
320
|
-
|
|
321
|
-
deps: ownLogger(nameOf(outermost), outermost.deps).map((dep) => (dep === port ?
|
|
324
|
+
const outermostOptions = {
|
|
325
|
+
deps: ownLogger(nameOf(outermost), outermost.deps).map((dep) => (dep === port ? inner : dep)),
|
|
322
326
|
...lifetimeOf(outermost.ctor),
|
|
323
|
-
}
|
|
327
|
+
};
|
|
328
|
+
if (wrappers.length > 0) scope.register(nameOf(outermost), outermost.ctor, outermostOptions);
|
|
329
|
+
scope.register(port, outermost.ctor, outermostOptions);
|
|
324
330
|
boundPorts.add(port);
|
|
325
331
|
frondLog.debug(`port ${port} → ${chain.map((one) => one.ctor.name).join(' → ')}`);
|
|
326
332
|
}
|
|
@@ -445,7 +451,7 @@ function buildFacadeInto(
|
|
|
445
451
|
routeRegistry.register(new OperationRoute(
|
|
446
452
|
'local',
|
|
447
453
|
new RouteAddress({
|
|
448
|
-
|
|
454
|
+
address: handler.address,
|
|
449
455
|
operation,
|
|
450
456
|
...(surface !== undefined ? { surface } : {}),
|
|
451
457
|
}),
|
package/src/boot/peerOver.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/** The two readings core serves everywhere, asked of one process over one transport. */
|
|
2
2
|
import { Invocation } from '../wire/Invocation.js';
|
|
3
|
-
import {
|
|
3
|
+
import { RPC_ADDRESS } from '../wire/RpcAnswer.js';
|
|
4
4
|
import type { Transport } from '../wire/Transport.js';
|
|
5
5
|
import type { Peer } from './Peer.js';
|
|
6
6
|
|
|
7
7
|
export function peerOver(transport: Transport): Peer {
|
|
8
8
|
const ask = (op: string, params: Record<string, unknown>) =>
|
|
9
|
-
transport({
|
|
9
|
+
transport({ address: RPC_ADDRESS, op }, { ...Invocation.empty, params: params as never });
|
|
10
10
|
|
|
11
11
|
return {
|
|
12
12
|
missing: async (entity, keys) =>
|
package/src/boot/ports.ts
CHANGED
|
@@ -20,6 +20,9 @@ import type { Diagnostic } from '../diagnostic.js';
|
|
|
20
20
|
*/
|
|
21
21
|
export const SEAMS = new Set(['Storage']);
|
|
22
22
|
|
|
23
|
+
/** Where a chain of wrappers finds what the scope already answered under its port — a builtin's own instance. */
|
|
24
|
+
export const heldKeyOf = (port: string): string => `held:${port}`;
|
|
25
|
+
|
|
23
26
|
/**
|
|
24
27
|
* What stands in front of each seam, outermost first — the same reading `portBindings`
|
|
25
28
|
* does, with no realization to find.
|