@fougere/core 0.8.4-alpha.0 → 0.9.0-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.
Files changed (112) hide show
  1. package/dist/boot/AppLifecycle.d.ts +8 -0
  2. package/dist/boot/AppLifecycle.d.ts.map +1 -1
  3. package/dist/boot/AppLifecycle.js.map +1 -1
  4. package/dist/boot/Emissions.d.ts +26 -0
  5. package/dist/boot/Emissions.d.ts.map +1 -1
  6. package/dist/boot/Emissions.js +143 -8
  7. package/dist/boot/Emissions.js.map +1 -1
  8. package/dist/boot/bootstrap.d.ts.map +1 -1
  9. package/dist/boot/bootstrap.js +77 -18
  10. package/dist/boot/bootstrap.js.map +1 -1
  11. package/dist/boot/hosted.d.ts.map +1 -1
  12. package/dist/boot/hosted.js +1 -0
  13. package/dist/boot/hosted.js.map +1 -1
  14. package/dist/boot/install.d.ts +2 -0
  15. package/dist/boot/install.d.ts.map +1 -1
  16. package/dist/boot/install.js +33 -4
  17. package/dist/boot/install.js.map +1 -1
  18. package/dist/boot/ports.d.ts +12 -3
  19. package/dist/boot/ports.d.ts.map +1 -1
  20. package/dist/boot/ports.js +51 -21
  21. package/dist/boot/ports.js.map +1 -1
  22. package/dist/boot/remote.d.ts.map +1 -1
  23. package/dist/boot/remote.js +3 -3
  24. package/dist/boot/remote.js.map +1 -1
  25. package/dist/boot/types.d.ts +16 -1
  26. package/dist/boot/types.d.ts.map +1 -1
  27. package/dist/builtin/LogLine.d.ts +38 -0
  28. package/dist/builtin/LogLine.d.ts.map +1 -0
  29. package/dist/builtin/LogLine.js +37 -0
  30. package/dist/builtin/LogLine.js.map +1 -0
  31. package/dist/builtin/logger.d.ts +57 -0
  32. package/dist/builtin/logger.d.ts.map +1 -1
  33. package/dist/builtin/logger.js +72 -17
  34. package/dist/builtin/logger.js.map +1 -1
  35. package/dist/config-loader.d.ts +2 -1
  36. package/dist/config-loader.d.ts.map +1 -1
  37. package/dist/config-loader.js.map +1 -1
  38. package/dist/contract.d.ts +3 -7
  39. package/dist/contract.d.ts.map +1 -1
  40. package/dist/contract.js +3 -4
  41. package/dist/contract.js.map +1 -1
  42. package/dist/conventions.d.ts +6 -0
  43. package/dist/conventions.d.ts.map +1 -1
  44. package/dist/conventions.js +3 -2
  45. package/dist/conventions.js.map +1 -1
  46. package/dist/declare.d.ts +11 -1
  47. package/dist/declare.d.ts.map +1 -1
  48. package/dist/declare.js +9 -0
  49. package/dist/declare.js.map +1 -1
  50. package/dist/descriptor/frond.d.ts +34 -0
  51. package/dist/descriptor/frond.d.ts.map +1 -1
  52. package/dist/descriptor/index.d.ts +1 -1
  53. package/dist/descriptor/index.d.ts.map +1 -1
  54. package/dist/descriptor/index.js +1 -1
  55. package/dist/descriptor/index.js.map +1 -1
  56. package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
  57. package/dist/dispatch/ArgumentResolver.js +6 -2
  58. package/dist/dispatch/ArgumentResolver.js.map +1 -1
  59. package/dist/dispatch/HandlerFacade.d.ts.map +1 -1
  60. package/dist/dispatch/HandlerFacade.js +2 -2
  61. package/dist/dispatch/HandlerFacade.js.map +1 -1
  62. package/dist/effective-operation.d.ts.map +1 -1
  63. package/dist/effective-operation.js +11 -7
  64. package/dist/effective-operation.js.map +1 -1
  65. package/dist/frond-config.d.ts +24 -0
  66. package/dist/frond-config.d.ts.map +1 -1
  67. package/dist/frond-config.js.map +1 -1
  68. package/dist/index.d.ts +30 -33
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +14 -13
  71. package/dist/index.js.map +1 -1
  72. package/dist/wire/Invocation.d.ts +1 -3
  73. package/dist/wire/Invocation.d.ts.map +1 -1
  74. package/dist/wire/Invocation.js +1 -5
  75. package/dist/wire/Invocation.js.map +1 -1
  76. package/dist/wire/binding.d.ts +9 -0
  77. package/dist/wire/binding.d.ts.map +1 -1
  78. package/dist/wire/binding.js +11 -6
  79. package/dist/wire/binding.js.map +1 -1
  80. package/dist/wire/emit.d.ts +35 -3
  81. package/dist/wire/emit.d.ts.map +1 -1
  82. package/dist/wire/emit.js +26 -3
  83. package/dist/wire/emit.js.map +1 -1
  84. package/dist/wire/loggerMiddleware.d.ts.map +1 -1
  85. package/dist/wire/loggerMiddleware.js +6 -0
  86. package/dist/wire/loggerMiddleware.js.map +1 -1
  87. package/package.json +4 -4
  88. package/src/boot/AppLifecycle.ts +8 -0
  89. package/src/boot/Emissions.ts +176 -8
  90. package/src/boot/bootstrap.ts +89 -17
  91. package/src/boot/hosted.ts +3 -1
  92. package/src/boot/install.ts +35 -4
  93. package/src/boot/ports.ts +71 -27
  94. package/src/boot/remote.ts +3 -3
  95. package/src/boot/types.ts +16 -1
  96. package/src/builtin/LogLine.ts +38 -0
  97. package/src/builtin/logger.ts +109 -17
  98. package/src/config-loader.ts +2 -1
  99. package/src/contract.ts +5 -9
  100. package/src/conventions.ts +9 -2
  101. package/src/declare.ts +19 -1
  102. package/src/descriptor/frond.ts +31 -0
  103. package/src/descriptor/index.ts +1 -1
  104. package/src/dispatch/ArgumentResolver.ts +6 -2
  105. package/src/dispatch/HandlerFacade.ts +2 -2
  106. package/src/effective-operation.ts +13 -7
  107. package/src/frond-config.ts +20 -0
  108. package/src/index.ts +36 -50
  109. package/src/wire/Invocation.ts +2 -7
  110. package/src/wire/binding.ts +17 -6
  111. package/src/wire/emit.ts +58 -6
  112. package/src/wire/loggerMiddleware.ts +6 -0
@@ -1,7 +1,15 @@
1
1
  import type { App } from './types.js';
2
+ import type { FrondDescriptor } from '../descriptor/frond.js';
2
3
  /** One process-level extension and its reversible lifecycle. */
3
4
  export interface Extension {
4
5
  name: string;
6
+ /**
7
+ * Fronds it brings — read BEFORE the ascent, since a frond is installed while the app is
8
+ * still being made and `up` receives one that already exists. This is how an optional
9
+ * package accepts a fact: `calls` and `observability` both want every `LogLine`, and a
10
+ * signature is the only way to ask for one.
11
+ */
12
+ fronds?: readonly FrondDescriptor[];
5
13
  up?(app: App): void | Promise<void>;
6
14
  down?(app: App): void | Promise<void>;
7
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AppLifecycle.d.ts","sourceRoot":"","sources":["../../src/boot/AppLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,gEAAgE;AAChE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,yEAAyE;AACzE,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAE3C,GAAG,CAAC,GAAG,UAAU,EAAE,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI;IAU5D,KAAK,IAAI,MAAM,EAAE;IAIX,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3B,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAapC;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CACvB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,EAC9D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,SAAS,CAYX"}
1
+ {"version":3,"file":"AppLifecycle.d.ts","sourceRoot":"","sources":["../../src/boot/AppLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,gEAAgE;AAChE,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,MAAM,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,yEAAyE;AACzE,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAE3C,GAAG,CAAC,GAAG,UAAU,EAAE,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI;IAU5D,KAAK,IAAI,MAAM,EAAE;IAIX,EAAE,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3B,IAAI,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;CAapC;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CACvB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,EAC9D,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GACjC,SAAS,CAYX"}
@@ -1 +1 @@
1
- {"version":3,"file":"AppLifecycle.js","sourceRoot":"","sources":["../../src/boot/AppLifecycle.ts"],"names":[],"mappings":"AASA,yEAAyE;AACzE,MAAM,OAAO,YAAY;IACN,OAAO,GAAgB,EAAE,CAAC;IAE3C,GAAG,CAAC,GAAG,UAA8C;QACnD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;YAC1E,IAAI,EAAE,KAAK,CAAC,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;;gBACvC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,EAAE,CAAC,GAAQ;QACf,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAQ;QACjB,MAAM,OAAO,GAAc,EAAE,CAAC;QAC9B,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,cAAc,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,kCAAkC,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF;AAED,mEAAmE;AACnE,MAAM,UAAU,SAAS,CACvB,OAA8D,EAC9D,MAAkC;IAElC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAEzC,qFAAqF;IACrF,kFAAkF;IAClF,OAAO;QACL,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,IAAI;gBAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"AppLifecycle.js","sourceRoot":"","sources":["../../src/boot/AppLifecycle.ts"],"names":[],"mappings":"AAiBA,yEAAyE;AACzE,MAAM,OAAO,YAAY;IACN,OAAO,GAAgB,EAAE,CAAC;IAE3C,GAAG,CAAC,GAAG,UAA8C;QACnD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;YAC1E,IAAI,EAAE,KAAK,CAAC,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;;gBACvC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,EAAE,CAAC,GAAQ;QACf,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO;YAAE,MAAM,SAAS,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAQ;QACjB,MAAM,OAAO,GAAc,EAAE,CAAC;QAC9B,KAAK,MAAM,SAAS,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,cAAc,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,kCAAkC,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF;AAED,mEAAmE;AACnE,MAAM,UAAU,SAAS,CACvB,OAA8D,EAC9D,MAAkC;IAElC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAEzC,qFAAqF;IACrF,kFAAkF;IAClF,OAAO;QACL,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,KAAK,EAAE,GAAQ,EAAE,EAAE;YACrB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,IAAI;gBAAE,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -13,28 +13,54 @@ export declare class Emissions {
13
13
  private readonly carry?;
14
14
  /** Who listens to what. Filled as each door's contracts are resolved. */
15
15
  private readonly subscribers;
16
+ /** Who FINISHES a fact, in the order they run — see `orderPipes`. */
17
+ private readonly pipes;
18
+ /** The order its OWNER declared, by fact — `pipes:` in `frond.config.ts`. */
19
+ private readonly ordered;
16
20
  /**
17
21
  * What is announced here, read from the DEPS and not from the subscribers: a handler declaring
18
22
  * `Emit<PostPublished>` must resolve it whether or not anybody listens, and announcing to nobody
19
23
  * is legal.
20
24
  */
21
25
  private readonly announced;
26
+ /** What is announced AND waited for — `Emit<T, A>`, where the second type says so. */
27
+ private readonly awaited;
22
28
  constructor(fronds: Fronds, shapes: Map<string, SchemaView>, container: Container, log: Logger, carry?: Carrier | undefined);
23
29
  /**
24
30
  * Who listens to what — read from the PLAN, where `{ kind: 'fact' }` is a sentence
25
31
  * `computeBindingPlan` already wrote, so nothing re-derives what a parameter is.
26
32
  */
27
33
  note(contracts: OperationsMap, door: string): void;
34
+ /** One more op that finishes this fact. What ORDER they run in is settled at `register`. */
35
+ private claimPipe;
36
+ /**
37
+ * Put the links in the order their fact's owner declared, and refuse what it did not.
38
+ *
39
+ * Two links with no order refuse: nothing would say which finished the fact, and scan
40
+ * order is not an answer — the same reason two implementations of a port refuse. One
41
+ * link needs no declaration, because there is nothing to order.
42
+ */
43
+ private orderPipes;
28
44
  /** The shape a fact is validated by, when the fact is a declared entity. */
29
45
  shapeOf(fact: string): SchemaView | undefined;
30
46
  /** The facts this process has a listener for — what a carrier subscribes to on its behalf. */
31
47
  listensTo(): string[];
48
+ /** The doors that accept one fact — the addresses a middleware must leave alone. */
49
+ doorsFor(fact: string): string[];
32
50
  /** Register one emission value per fact — announced here, or merely listened to. */
33
51
  register(): void;
34
52
  /** Announcing. */
35
53
  private announce;
36
54
  /** Receiving. */
37
55
  deliver(fact: string, payload: unknown): Promise<void>;
56
+ /**
57
+ * What the declared link answers, or the value as it stands when nothing declared one.
58
+ *
59
+ * Before anyone is handed anything, and once: every subscriber reads the same fact, which
60
+ * is the whole reason a fact can be said to be what happened. A link that refuses stops
61
+ * the announcement — it was finishing the fact, and half a fact is not one.
62
+ */
63
+ private finished;
38
64
  /**
39
65
  * The announcement realizes the fact's own `lifecycle.create` — a `created()` stamped, an id
40
66
  * generated, a default applied.
@@ -1 +1 @@
1
- {"version":3,"file":"Emissions.d.ts","sourceRoot":"","sources":["../../src/boot/Emissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQ1D,qFAAqF;AACrF,KAAK,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAExE,gFAAgF;AAChF,qBAAa,SAAS;IAalB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAfzB,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;gBAGtC,MAAM,EAAE,MAAM,EACG,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC/B,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,OAAO,YAAA;IAKlC;;;OAGG;IACH,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAWlD,4EAA4E;IAC5E,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI7C,8FAA8F;IAC9F,SAAS,IAAI,MAAM,EAAE;IAIrB,oFAAoF;IACpF,QAAQ,IAAI,IAAI;IAShB,kBAAkB;YACJ,QAAQ;IAmBtB,iBAAiB;IACX,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5D;;;OAGG;IACH,OAAO,CAAC,OAAO;IAOf,uFAAuF;IACvF,OAAO,CAAC,eAAe;IA8BvB,uFAAuF;IACvF,OAAO,CAAC,eAAe;CAMxB"}
1
+ {"version":3,"file":"Emissions.d.ts","sourceRoot":"","sources":["../../src/boot/Emissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQ1D,qFAAqF;AACrF,KAAK,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAExE,gFAAgF;AAChF,qBAAa,SAAS;IAsBlB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAxBzB,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAiC;IAE7D,qEAAqE;IACrE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IAEvD,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAEhD;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IAExC,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;gBAGpC,MAAM,EAAE,MAAM,EACG,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAC/B,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,EACX,KAAK,CAAC,EAAE,OAAO,YAAA;IAsBlC;;;OAGG;IACH,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAelD,4FAA4F;IAC5F,OAAO,CAAC,SAAS;IAOjB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IA8BlB,4EAA4E;IAC5E,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAI7C,8FAA8F;IAC9F,SAAS,IAAI,MAAM,EAAE;IAIrB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAIhC,oFAAoF;IACpF,QAAQ,IAAI,IAAI;IAyBhB,kBAAkB;YACJ,QAAQ;IAiDtB,iBAAiB;IACX,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB5D;;;;;;OAMG;YACW,QAAQ;IAyBtB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAOf,uFAAuF;IACvF,OAAO,CAAC,eAAe;IA8BvB,uFAAuF;IACvF,OAAO,CAAC,eAAe;CAMxB"}
@@ -1,8 +1,8 @@
1
- import { applyCreate, dotted } from '@fougere/schema';
1
+ import { applyCreate, dotted, lowerFirst } from '@fougere/schema';
2
2
  import { validationErrorsOf } from '../wire/errors.js';
3
- import { emitKeyOf, factsAnnouncedBy } from '../wire/emit.js';
3
+ import { awaitKeyOf, emitKeyOf, factsAnnouncedBy, factsAwaitedBy } from '../wire/emit.js';
4
4
  import { ambient } from '#ambient';
5
- import { EMPTY_INVOCATION } from '../wire/Invocation.js';
5
+ import { Invocation } from '../wire/Invocation.js';
6
6
  /** Emissions — the only place in Fougere where an initiator names a SUBJECT. */
7
7
  export class Emissions {
8
8
  shapes;
@@ -11,18 +11,37 @@ export class Emissions {
11
11
  carry;
12
12
  /** Who listens to what. Filled as each door's contracts are resolved. */
13
13
  subscribers = new Map();
14
+ /** Who FINISHES a fact, in the order they run — see `orderPipes`. */
15
+ pipes = new Map();
16
+ /** The order its OWNER declared, by fact — `pipes:` in `frond.config.ts`. */
17
+ ordered;
14
18
  /**
15
19
  * What is announced here, read from the DEPS and not from the subscribers: a handler declaring
16
20
  * `Emit<PostPublished>` must resolve it whether or not anybody listens, and announcing to nobody
17
21
  * is legal.
18
22
  */
19
23
  announced;
24
+ /** What is announced AND waited for — `Emit<T, A>`, where the second type says so. */
25
+ awaited;
20
26
  constructor(fronds, shapes, container, log, carry) {
21
27
  this.shapes = shapes;
22
28
  this.container = container;
23
29
  this.log = log;
24
30
  this.carry = carry;
25
31
  this.announced = new Set(fronds.flatMap((frond) => factsAnnouncedBy(frond.handlers)));
32
+ this.awaited = new Set(fronds.flatMap((frond) => factsAwaitedBy(frond.handlers)));
33
+ // Read from the frond that OWNS the fact: ordering is a decision about the fact, and
34
+ // a decision has one owner. A frond ordering a neighbour's fact is refused below.
35
+ this.ordered = new Map(fronds.flatMap((frond) => {
36
+ const owned = new Set(frond.entities.map((entity) => entity.name));
37
+ return Object.entries(frond.pipes ?? {}).map(([fact, order]) => {
38
+ if (!owned.has(lowerFirst(fact))) {
39
+ throw new Error(`Frond '${frond.name}' orders the links of '${fact}', which it does not own.\n`
40
+ + ' The order belongs to the frond that declares the entity — state `pipes:` there.');
41
+ }
42
+ return [lowerFirst(fact), order];
43
+ });
44
+ }));
26
45
  }
27
46
  /**
28
47
  * Who listens to what — read from the PLAN, where `{ kind: 'fact' }` is a sentence
@@ -31,6 +50,10 @@ export class Emissions {
31
50
  note(contracts, door) {
32
51
  for (const [op, contract] of contracts) {
33
52
  for (const bound of contract.binding ?? []) {
53
+ if (bound.source.kind === 'pipe') {
54
+ this.claimPipe(bound.source.factName, { door, op });
55
+ continue;
56
+ }
34
57
  if (bound.source.kind !== 'fact')
35
58
  continue;
36
59
  const listeners = this.subscribers.get(bound.source.factName) ?? [];
@@ -39,6 +62,44 @@ export class Emissions {
39
62
  }
40
63
  }
41
64
  }
65
+ /** One more op that finishes this fact. What ORDER they run in is settled at `register`. */
66
+ claimPipe(fact, taking) {
67
+ const held = this.pipes.get(fact) ?? [];
68
+ if (held.some((one) => `${one.door}.${one.op}` === `${taking.door}.${taking.op}`))
69
+ return;
70
+ held.push(taking);
71
+ this.pipes.set(fact, held);
72
+ }
73
+ /**
74
+ * Put the links in the order their fact's owner declared, and refuse what it did not.
75
+ *
76
+ * Two links with no order refuse: nothing would say which finished the fact, and scan
77
+ * order is not an answer — the same reason two implementations of a port refuse. One
78
+ * link needs no declaration, because there is nothing to order.
79
+ */
80
+ orderPipes() {
81
+ for (const [fact, links] of this.pipes) {
82
+ const declared = this.ordered.get(fact);
83
+ const named = (one) => `${one.door}.${one.op}`;
84
+ if (!declared) {
85
+ if (links.length < 2)
86
+ continue;
87
+ throw new Error(`${links.length} ops finish the fact '${fact}': ${links.map(named).join(', ')}.\n`
88
+ + ' They run one after another and nothing says in which order. State it on the '
89
+ + `frond that owns '${fact}':\n`
90
+ + ` export default { pipes: { ${fact}: ['FirstHandler', 'SecondHandler'] } };\n`
91
+ + ' Or make all but one accept `Fact<…>`, which changes nothing and reads it.');
92
+ }
93
+ const at = (one) => declared.findIndex((name) => doorOf(name) === one.door);
94
+ const unlisted = links.filter((one) => at(one) < 0);
95
+ if (unlisted.length > 0) {
96
+ throw new Error(`${unlisted.map(named).join(', ')} finish${unlisted.length > 1 ? '' : 'es'} the fact `
97
+ + `'${fact}', and '${fact}' orders ${declared.join(', ')} — so where it runs is not said.\n`
98
+ + ' Add it to `pipes:`, or make it accept `Fact<…>`.');
99
+ }
100
+ this.pipes.set(fact, [...links].sort((one, other) => at(one) - at(other)));
101
+ }
102
+ }
42
103
  /** The shape a fact is validated by, when the fact is a declared entity. */
43
104
  shapeOf(fact) {
44
105
  return this.shapes.get(fact);
@@ -47,31 +108,70 @@ export class Emissions {
47
108
  listensTo() {
48
109
  return [...this.subscribers.keys()];
49
110
  }
111
+ /** The doors that accept one fact — the addresses a middleware must leave alone. */
112
+ doorsFor(fact) {
113
+ return (this.subscribers.get(fact) ?? []).map(({ door }) => door);
114
+ }
50
115
  /** Register one emission value per fact — announced here, or merely listened to. */
51
116
  register() {
117
+ this.orderPipes();
52
118
  for (const fact of new Set([...this.announced, ...this.subscribers.keys()])) {
53
119
  this.container.registerValue(emitKeyOf(fact), (raw) => this.announce(fact, raw));
54
120
  }
121
+ for (const fact of this.awaited) {
122
+ // Waiting means knowing WHO, and a carrier publishes to whoever subscribed elsewhere
123
+ // without bringing anything back — so the answers would hold this process's
124
+ // subscribers only, and say nothing about it. Refused here rather than half-answered
125
+ // at the first call: the second type is in a signature, so a boot can read it.
126
+ if (this.carry) {
127
+ throw new Error(`'${fact}' is announced with an answer type, and this app has a carrier (\`onEmit\`).\n`
128
+ + ' Waiting means knowing who answers; a carrier reaches whoever subscribed '
129
+ + 'elsewhere and brings nothing back.\n'
130
+ + ` Name the subscribers in \`remotes:\`, or drop the second type of \`Emit<${fact}, …>\`.`);
131
+ }
132
+ this.container.registerValue(awaitKeyOf(fact), (raw) => this.announce(fact, raw, true));
133
+ }
55
134
  if (ambient.degraded && this.subscribers.size > 0) {
56
135
  this.log.warn('no async context on this runtime — an emission ring is not detected');
57
136
  }
58
137
  }
59
138
  /** Announcing. */
60
- async announce(fact, raw) {
139
+ async announce(fact, raw, waiting = false) {
61
140
  /**
62
141
  * A fact announced inside a frame that then rolls back is a lie, and nothing can take it back:
63
142
  * announcing is DISPATCH — every subscriber has been handed the fact and the carrier has
64
143
  * already put it on the wire — while the frame's writes are still provisional.
65
144
  */
66
145
  await ambient.beforeAnnounce(fact);
67
- const payload = this.stamped(fact, raw);
146
+ const payload = await this.finished(fact, this.stamped(fact, raw));
68
147
  /** Whoever is not in this process — and it is the ONLY way to reach them. */
69
148
  const delivery = this.carry?.(fact, payload);
70
149
  if (delivery)
71
150
  void Promise.resolve(delivery).catch((cause) => this.log.error(`${fact} — carrier refused it`, cause));
72
- for (const { door, op, done } of this.handToListeners(fact, payload)) {
73
- void done.catch((cause) => this.log.error(`${fact} → ${door}.${op}`, this.describeRefusal(fact, cause) ?? cause));
151
+ const handed = this.handToListeners(fact, payload);
152
+ if (!waiting) {
153
+ for (const { door, op, done } of handed) {
154
+ void done.catch((cause) => this.log.error(`${fact} → ${door}.${op}`, this.describeRefusal(fact, cause) ?? cause));
155
+ }
156
+ return [];
157
+ }
158
+ const settled = await Promise.allSettled(handed.map((one) => one.done));
159
+ // A subscriber that did not answer REFUSES the announcement, it does not shrink it: an
160
+ // announcer handed the survivors cannot tell three answers from two, and its own law
161
+ // then reads silence as consent — the room one would have refused gets booked.
162
+ const missing = settled.flatMap((result, at) => (result.status === 'rejected' ? [{ ...handed[at], reason: result.reason }] : []));
163
+ if (missing.length > 0) {
164
+ for (const { door, op, reason } of missing) {
165
+ this.log.error(`${fact} → ${door}.${op}`, this.describeRefusal(fact, reason) ?? reason);
166
+ }
167
+ throw new AggregateError(missing.map((one) => one.reason), `${fact} — ${missing.length} of ${handed.length} subscriber(s) did not answer`
168
+ + ` (${missing.map((one) => `${one.door}.${one.op}`).join(', ')}).`
169
+ + ' An announcement with an answer type waits for everyone: a partial answer would'
170
+ + ' look like a complete one.');
74
171
  }
172
+ // What answers NOTHING contributes nothing — a subscriber is free to have no opinion,
173
+ // and `Promise<void>` is how it says so.
174
+ return settled.flatMap((result) => (result.status === 'fulfilled' && result.value != null ? [result.value] : []));
75
175
  }
76
176
  /** Receiving. */
77
177
  async deliver(fact, payload) {
@@ -87,6 +187,33 @@ export class Emissions {
87
187
  + ` Nothing here holds it: the carrier decides whether it comes back.`);
88
188
  }
89
189
  }
190
+ /**
191
+ * What the declared link answers, or the value as it stands when nothing declared one.
192
+ *
193
+ * Before anyone is handed anything, and once: every subscriber reads the same fact, which
194
+ * is the whole reason a fact can be said to be what happened. A link that refuses stops
195
+ * the announcement — it was finishing the fact, and half a fact is not one.
196
+ */
197
+ async finished(fact, payload) {
198
+ let carried = payload;
199
+ for (const link of this.pipes.get(fact) ?? []) {
200
+ const facade = this.container.resolve(link.door);
201
+ const answered = await facade[link.op]({ ...Invocation.empty, input: carried });
202
+ // A link that answers nothing SUPPRESSES the fact — every subscriber was then handed
203
+ // `null` and crashed reading it, one message each. It is refused rather than named,
204
+ // because a fact is what HAPPENED: the announcer already said so and cannot be told
205
+ // otherwise, `Emit` returning void. Filtering belongs to whoever announces, or to
206
+ // each reader; it is not a link's to decide for everyone.
207
+ if (answered === null || answered === undefined) {
208
+ throw new Error(`${link.door}.${link.op} finishes the fact '${fact}' and answered nothing.\n`
209
+ + ' A link says what the fact IS, it does not take it back — the announcer has '
210
+ + 'already said it happened, and nothing can tell it otherwise.\n'
211
+ + ' Return the fact, amended or as it stands.');
212
+ }
213
+ carried = answered;
214
+ }
215
+ return carried;
216
+ }
90
217
  /**
91
218
  * The announcement realizes the fact's own `lifecycle.create` — a `created()` stamped, an id
92
219
  * generated, a default applied.
@@ -120,7 +247,7 @@ export class Emissions {
120
247
  catch (cause) {
121
248
  throw new Error(`${fact} → ${door} could not be reached`, { cause });
122
249
  }
123
- return facade[op]({ ...EMPTY_INVOCATION, input: payload });
250
+ return facade[op]({ ...Invocation.empty, input: payload });
124
251
  }),
125
252
  }));
126
253
  }
@@ -133,4 +260,12 @@ export class Emissions {
133
260
  + ` If '${fact}' gained a field, this copy is older than the sender's: re-run \`fougere sync\`.`;
134
261
  }
135
262
  }
263
+ /**
264
+ * The container key a declared CLASS NAME answers under — `RedactHandler` → `redactHandler`,
265
+ * the same key `facadeKeyOf` builds from an address.
266
+ */
267
+ function doorOf(declared) {
268
+ const key = lowerFirst(declared);
269
+ return key.endsWith('Handler') ? key : `${key}Handler`;
270
+ }
136
271
  //# sourceMappingURL=Emissions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Emissions.js","sourceRoot":"","sources":["../../src/boot/Emissions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Emissions.js","sourceRoot":"","sources":["../../src/boot/Emissions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/boot/bootstrap.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAwExD,uCAAuC;AACvC,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,CA4bvE"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/boot/bootstrap.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AA+ExD,uCAAuC;AACvC,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,CA6fvE"}
@@ -1,7 +1,11 @@
1
1
  import { lowerFirst } from '@fougere/schema';
2
2
  import { hostedBy } from './hosted.js';
3
3
  import { installFrond } from './install.js';
4
- import { Logger } from '../builtin/logger.js';
4
+ import { Carry, Logger } from '../builtin/logger.js';
5
+ import LogLine, { CARRIES_LINE } from '../builtin/LogLine.js';
6
+ import { emitKeyOf } from '../wire/emit.js';
7
+ /** The fact the boot announces, spelled once. */
8
+ const LOG_LINE = lowerFirst(LogLine.name);
5
9
  import { Config } from '../builtin/config.js';
6
10
  import { createRemoteRouter, createRemoteFacade } from './remote.js';
7
11
  import { Emissions } from './Emissions.js';
@@ -10,7 +14,8 @@ import { InFlight } from '../dispatch/InFlight.js';
10
14
  // The keys, each read from where its concept is declared — never respelled here.
11
15
  import { facadeKeyOf } from '../wire/call.js';
12
16
  import { identityCardOf } from './card.js';
13
- import { AppLifecycle } from './AppLifecycle.js';
17
+ import { AppLifecycle, migrating } from './AppLifecycle.js';
18
+ import { seeding } from './seed.js';
14
19
  import { storageKeyOf } from '../storage/port.js';
15
20
  import { presenterKeyOf } from '../prefab/presenter.js';
16
21
  import { RouteAddress } from '../wire/RouteAddress.js';
@@ -52,9 +57,16 @@ export async function createApp(options) {
52
57
  const container = options.createContainer();
53
58
  // Held out here, and not where the ascent reads it, because releasing needs it and
54
59
  // releasing has to work from the first line the boot takes something.
55
- const appLifecycle = new AppLifecycle().add(...(options.extensions ?? []));
60
+ // The conventional ascent, ordered here: tables, then rows, then whatever the host took
61
+ // on. Four hosts assembled these two members themselves — the order is not theirs to
62
+ // choose, and a host that forgot lost its migration in silence.
63
+ const appLifecycle = new AppLifecycle().add(migrating(options.migrate), seeding(), ...(options.extensions ?? []));
56
64
  /** The app once it exists — a refusal before that releases the two levels that do. */
57
65
  let built;
66
+ /** Where THIS boot's lines wait — never a process-wide slot, see `Carry`. */
67
+ const carry = new Carry();
68
+ /** Given back by `carry.to`, so a released app stops writing into a dead container. */
69
+ let stopAnnouncing;
58
70
  /**
59
71
  * Everything this app holds, let go in reverse of how it was taken: what an extension took on
60
72
  * last, then the container's own, then whoever handed a resource in.
@@ -65,6 +77,9 @@ export async function createApp(options) {
65
77
  // there and broken here, a refusing extension took the container and the connection
66
78
  // down with it, which is the leak this gesture exists to prevent.
67
79
  const refused = [];
80
+ // Whatever is still held will never reach a destination — the console had it.
81
+ stopAnnouncing?.();
82
+ carry.forget();
68
83
  const levels = [
69
84
  ...(built ? [() => appLifecycle.down(built)] : []),
70
85
  () => container.dispose(),
@@ -89,25 +104,31 @@ export async function createApp(options) {
89
104
  };
90
105
  try {
91
106
  // Boot chatter is debug by default; a host (e.g. the CLI) can quiet it.
92
- const log = new Logger('boot:app');
107
+ const log = new Logger('boot:app', { carry });
93
108
  // Builtins — registered under class name (PascalCase) for type-based DI.
94
109
  // No level here and none anywhere: a logger consults `setLogLevel`'s value at each
95
110
  // emission, so this instance survives a level change and so does every handler that
96
111
  // was handed it. A frond declaring `class X extends Logger` takes this key over,
97
112
  // like any other port.
98
- container.registerValue('Logger', new Logger('app'));
113
+ container.registerValue('Logger', new Logger('app', { carry }));
99
114
  container.register('Config', Config, { lifetime: 'singleton' });
100
115
  log.debug('builtins registered (Logger, Config)');
101
116
  // What this app hosts is HANDED IN — stated, scanned, or both (`hostedBy`). Producing
102
117
  // it may read a disk; consuming it never does, which is the whole reason this file names
103
118
  // no builtin and a Worker can run what it builds.
104
119
  const scanStart = performance.now();
105
- const { fronds, diagnostics } = await hostedBy(options);
120
+ // An extension's fronds sit beside the app's own: it is installed like any other, and
121
+ // its handlers resolve at call time — by which point the extension's `up` has put what
122
+ // they ask for in the container.
123
+ const brought = (options.extensions ?? [])
124
+ .flatMap((extension) => extension?.fronds ?? [])
125
+ .map((frond) => ({ ...frond, brought: true }));
126
+ const { fronds, diagnostics } = await hostedBy(brought.length > 0 ? { ...options, fronds: [...(options.fronds ?? []), ...brought] } : options);
106
127
  // An app that states nothing AND scans nothing is a mistake — unless something else it
107
128
  // declares brings its own entities, which an auth provider does. Refused here and not in
108
129
  // `hostedBy`, which is handed the frond sources and cannot see the rest of the app. The
109
130
  // condition is the KEYS, not the count: a scan that found nothing is an ordinary answer.
110
- if (!options.fronds && !options.scan && !options.auth) {
131
+ if (!options.fronds && !options.scan && !options.auth && brought.length === 0) {
111
132
  throw new Error('createApp needs `fronds:` (what this app states) or `scan:` (what a scanner found). '
112
133
  + 'Neither was given, and nothing else declares entities of its own.');
113
134
  }
@@ -177,14 +198,37 @@ export async function createApp(options) {
177
198
  const scoped = scopedMiddlewares.get(entity) ?? [];
178
199
  return [...globalMiddlewares, ...scoped];
179
200
  }
201
+ /**
202
+ * The one place a middleware is taken on. `App.use` is its late form, and a frond's
203
+ * `middlewares/` its early one — the app does not exist yet while fronds install.
204
+ */
205
+ function use(middleware, entity) {
206
+ if (entity === undefined) {
207
+ globalMiddlewares.push(middleware);
208
+ return;
209
+ }
210
+ const scoped = scopedMiddlewares.get(entity) ?? [];
211
+ scoped.push(middleware);
212
+ scopedMiddlewares.set(entity, scoped);
213
+ }
180
214
  assertOneOwnerPerKey(fronds, options.remotes);
181
215
  // Every entity of every frond, by name — so a fact can be validated where it LANDS, and
182
216
  // so a `reads:` clause can name a neighbour's.
183
217
  const entityByName = fronds.schemas();
218
+ // The line is core's, so its SHAPE is too: a destination that declares only a handler
219
+ // would otherwise be handed a line with no `at` — the announcement stamps `created()`
220
+ // off the shape, and the strict judge refuses what it did not stamp. Measured on
221
+ // `demos/observability`, where the ring held 11 calls and 0 lines.
222
+ if (!entityByName.has(LOG_LINE))
223
+ entityByName.set(LOG_LINE, LogLine);
184
224
  // Which frond holds an entity — what turns "a member is remote" into a refusal that
185
225
  // names the frond rather than the entity, since `remotes:` is declared per frond.
186
226
  const frondOf = new Map(fronds.flatMap((f) => f.entities.map((e) => [e.name, f.name])));
187
- const emissions = new Emissions(fronds, entityByName, container, log, options.onEmit);
227
+ // Its own writer, which does NOT announce: this is what carries a fact, and a line
228
+ // about carrying one would come back here. See `LoggerOptions.carries`.
229
+ const emissions = new Emissions(fronds, entityByName, container,
230
+ // No carry: this is what CARRIES a fact, and a line about carrying one comes back.
231
+ new Logger('boot:app'), options.onEmit);
188
232
  /** Canonical operation tables, indexed by the same audience key as their facades. */
189
233
  const effectiveByKey = new Map();
190
234
  const contractsOf = (operations) => new Map([...operations].map(([name, operation]) => [name, operation]));
@@ -196,7 +240,7 @@ export async function createApp(options) {
196
240
  // table, one emission list — so what a frond serves is there for the next one to find.
197
241
  const assembly = {
198
242
  container, routeRegistry, emissions, dispatcher, localDispatcher, effectiveByKey,
199
- boundPorts, operationModel, entityByName, frondOf, contractsOf, getMiddlewares,
243
+ boundPorts, operationModel, entityByName, frondOf, contractsOf, getMiddlewares, use,
200
244
  log, options,
201
245
  };
202
246
  for (const frond of fronds)
@@ -211,6 +255,27 @@ export async function createApp(options) {
211
255
  }
212
256
  // Once every door exists: what is announced here and what is listened to are both known.
213
257
  emissions.register();
258
+ // The boot's own lines, and every line after them. Held until here because a boot
259
+ // writes most of what a process logs and writes it before any door exists — so the
260
+ // lines that say what this app is made of are the ones a destination would miss.
261
+ // `LogLine` is core's for this reason: naming it costs no optional package.
262
+ // Which doors carry a line, read from who SUBSCRIBED — so a third party's destination
263
+ // is left alone by the two middlewares that observe every operation.
264
+ for (const door of emissions.doorsFor(LOG_LINE)) {
265
+ CARRIES_LINE.add(door.replace(/Handler$/, '').replace(/^./, (c) => c.toLowerCase()));
266
+ CARRIES_LINE.add(door);
267
+ }
268
+ if (emissions.listensTo().includes(LOG_LINE)) {
269
+ const emit = container.resolve(emitKeyOf(LogLine.name));
270
+ // `at` is the record's own epoch, and the entity says `created()` — so the line
271
+ // keeps WHEN IT WAS WRITTEN rather than when it was handed over, which for a held
272
+ // boot line is a different moment.
273
+ stopAnnouncing = carry.to(({ at, ...line }) => void emit({ ...line, at: new Date(at) }));
274
+ }
275
+ else {
276
+ // No destination in this app: the console had them, and holding more would grow.
277
+ carry.forget();
278
+ }
214
279
  /** The last resort, held by the container so every resolution path shares it. */
215
280
  container.setFallback?.((name) => {
216
281
  if (!remoteRouter)
@@ -399,15 +464,9 @@ export async function createApp(options) {
399
464
  return dispatchLifecycle.add(observer);
400
465
  },
401
466
  use(...args) {
402
- if (typeof args[0] === 'string') {
403
- const [entity, mw] = args;
404
- const list = scopedMiddlewares.get(entity) ?? [];
405
- list.push(mw);
406
- scopedMiddlewares.set(entity, list);
407
- }
408
- else {
409
- globalMiddlewares.push(args[0]);
410
- }
467
+ return typeof args[0] === 'string'
468
+ ? use(args[1], args[0])
469
+ : use(args[0]);
411
470
  },
412
471
  auth: authRuntime,
413
472
  };