@fougere/core 0.6.0-alpha.0 → 0.8.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 (510) hide show
  1. package/README.md +1 -1
  2. package/dist/boot/AppLifecycle.d.ts +1 -1
  3. package/dist/boot/AppLifecycle.d.ts.map +1 -1
  4. package/dist/boot/AppLifecycle.js +13 -2
  5. package/dist/boot/AppLifecycle.js.map +1 -1
  6. package/dist/boot/Emissions.d.ts +13 -90
  7. package/dist/boot/Emissions.d.ts.map +1 -1
  8. package/dist/boot/Emissions.js +21 -118
  9. package/dist/boot/Emissions.js.map +1 -1
  10. package/dist/boot/ambient-port.d.ts +3 -24
  11. package/dist/boot/ambient-port.d.ts.map +1 -1
  12. package/dist/boot/ambient.als.d.ts.map +1 -1
  13. package/dist/boot/ambient.als.js +7 -12
  14. package/dist/boot/ambient.als.js.map +1 -1
  15. package/dist/boot/ambient.queue.d.ts +2 -5
  16. package/dist/boot/ambient.queue.d.ts.map +1 -1
  17. package/dist/boot/ambient.queue.js.map +1 -1
  18. package/dist/boot/apply.d.ts +1 -13
  19. package/dist/boot/apply.d.ts.map +1 -1
  20. package/dist/boot/apply.js +9 -16
  21. package/dist/boot/apply.js.map +1 -1
  22. package/dist/boot/auth.d.ts +2 -12
  23. package/dist/boot/auth.d.ts.map +1 -1
  24. package/dist/boot/boot.d.ts +3 -16
  25. package/dist/boot/boot.d.ts.map +1 -1
  26. package/dist/boot/boot.js +4 -11
  27. package/dist/boot/boot.js.map +1 -1
  28. package/dist/boot/bootstrap.d.ts.map +1 -1
  29. package/dist/boot/bootstrap.js +84 -130
  30. package/dist/boot/bootstrap.js.map +1 -1
  31. package/dist/boot/card.d.ts +1 -17
  32. package/dist/boot/card.d.ts.map +1 -1
  33. package/dist/boot/card.js +3 -32
  34. package/dist/boot/card.js.map +1 -1
  35. package/dist/boot/frame.d.ts +8 -32
  36. package/dist/boot/frame.d.ts.map +1 -1
  37. package/dist/boot/frame.js +17 -56
  38. package/dist/boot/frame.js.map +1 -1
  39. package/dist/boot/hosted.d.ts +2 -24
  40. package/dist/boot/hosted.d.ts.map +1 -1
  41. package/dist/boot/hosted.js +10 -15
  42. package/dist/boot/hosted.js.map +1 -1
  43. package/dist/boot/ownership.d.ts +3 -36
  44. package/dist/boot/ownership.d.ts.map +1 -1
  45. package/dist/boot/ownership.js +5 -40
  46. package/dist/boot/ownership.js.map +1 -1
  47. package/dist/boot/ports.d.ts +1 -14
  48. package/dist/boot/ports.d.ts.map +1 -1
  49. package/dist/boot/ports.js +1 -14
  50. package/dist/boot/ports.js.map +1 -1
  51. package/dist/boot/remote.d.ts +5 -38
  52. package/dist/boot/remote.d.ts.map +1 -1
  53. package/dist/boot/remote.js +8 -41
  54. package/dist/boot/remote.js.map +1 -1
  55. package/dist/boot/runner.d.ts +4 -21
  56. package/dist/boot/runner.d.ts.map +1 -1
  57. package/dist/boot/runner.js +4 -17
  58. package/dist/boot/runner.js.map +1 -1
  59. package/dist/boot/seed.d.ts +4 -31
  60. package/dist/boot/seed.d.ts.map +1 -1
  61. package/dist/boot/seed.js +6 -37
  62. package/dist/boot/seed.js.map +1 -1
  63. package/dist/boot/statement-drift.d.ts +2 -21
  64. package/dist/boot/statement-drift.d.ts.map +1 -1
  65. package/dist/boot/statement-drift.js +4 -9
  66. package/dist/boot/statement-drift.js.map +1 -1
  67. package/dist/boot/together.d.ts +4 -8
  68. package/dist/boot/together.d.ts.map +1 -1
  69. package/dist/boot/together.js +15 -50
  70. package/dist/boot/together.js.map +1 -1
  71. package/dist/boot/types.d.ts +31 -173
  72. package/dist/boot/types.d.ts.map +1 -1
  73. package/dist/builtin/config.d.ts +7 -0
  74. package/dist/builtin/config.d.ts.map +1 -0
  75. package/dist/builtin/config.js +15 -0
  76. package/dist/builtin/config.js.map +1 -0
  77. package/dist/{builtins → builtin}/logger.d.ts +4 -25
  78. package/dist/builtin/logger.d.ts.map +1 -0
  79. package/dist/{builtins → builtin}/logger.js +5 -32
  80. package/dist/builtin/logger.js.map +1 -0
  81. package/dist/config-loader.d.ts +9 -67
  82. package/dist/config-loader.d.ts.map +1 -1
  83. package/dist/config-loader.js +5 -18
  84. package/dist/config-loader.js.map +1 -1
  85. package/dist/contract.d.ts +15 -31
  86. package/dist/contract.d.ts.map +1 -1
  87. package/dist/contract.js +13 -26
  88. package/dist/contract.js.map +1 -1
  89. package/dist/criterion.d.ts +37 -0
  90. package/dist/criterion.d.ts.map +1 -0
  91. package/dist/criterion.js +28 -0
  92. package/dist/criterion.js.map +1 -0
  93. package/dist/crypto/encoding.d.ts +2 -15
  94. package/dist/crypto/encoding.d.ts.map +1 -1
  95. package/dist/crypto/encoding.js +2 -15
  96. package/dist/crypto/encoding.js.map +1 -1
  97. package/dist/crypto/node.d.ts.map +1 -1
  98. package/dist/crypto/node.js +1 -7
  99. package/dist/crypto/node.js.map +1 -1
  100. package/dist/crypto/port.d.ts +2 -18
  101. package/dist/crypto/port.d.ts.map +1 -1
  102. package/dist/crypto/port.js +1 -17
  103. package/dist/crypto/port.js.map +1 -1
  104. package/dist/crypto/webcrypto.d.ts.map +1 -1
  105. package/dist/crypto/webcrypto.js +1 -12
  106. package/dist/crypto/webcrypto.js.map +1 -1
  107. package/dist/declare.d.ts +19 -37
  108. package/dist/declare.d.ts.map +1 -1
  109. package/dist/declare.js +23 -30
  110. package/dist/declare.js.map +1 -1
  111. package/dist/define.d.ts +2 -3
  112. package/dist/define.d.ts.map +1 -1
  113. package/dist/define.js +2 -3
  114. package/dist/define.js.map +1 -1
  115. package/dist/descriptor/Fronds.d.ts +3 -28
  116. package/dist/descriptor/Fronds.d.ts.map +1 -1
  117. package/dist/descriptor/Fronds.js +6 -31
  118. package/dist/descriptor/Fronds.js.map +1 -1
  119. package/dist/descriptor/frond.d.ts +25 -60
  120. package/dist/descriptor/frond.d.ts.map +1 -1
  121. package/dist/descriptor/frond.js +5 -1
  122. package/dist/descriptor/frond.js.map +1 -1
  123. package/dist/dispatch/ArgumentResolver.d.ts +1 -1
  124. package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
  125. package/dist/dispatch/ArgumentResolver.js +5 -5
  126. package/dist/dispatch/ArgumentResolver.js.map +1 -1
  127. package/dist/dispatch/DispatchEvent.d.ts +2 -2
  128. package/dist/dispatch/DispatchEvent.d.ts.map +1 -1
  129. package/dist/dispatch/DispatchLifecycle.d.ts +1 -7
  130. package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -1
  131. package/dist/dispatch/DispatchLifecycle.js +1 -7
  132. package/dist/dispatch/DispatchLifecycle.js.map +1 -1
  133. package/dist/dispatch/DispatchPort.d.ts +1 -1
  134. package/dist/dispatch/DispatchPort.d.ts.map +1 -1
  135. package/dist/dispatch/Dispatcher.d.ts +1 -1
  136. package/dist/dispatch/Dispatcher.d.ts.map +1 -1
  137. package/dist/dispatch/Dispatcher.js +2 -2
  138. package/dist/dispatch/Dispatcher.js.map +1 -1
  139. package/dist/{boot → dispatch}/HandlerFacade.d.ts +25 -38
  140. package/dist/dispatch/HandlerFacade.d.ts.map +1 -0
  141. package/dist/{boot → dispatch}/HandlerFacade.js +65 -74
  142. package/dist/dispatch/HandlerFacade.js.map +1 -0
  143. package/dist/dispatch/LocalRoutePolicy.d.ts +1 -1
  144. package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -1
  145. package/dist/dispatch/LocalRoutePolicy.js +4 -4
  146. package/dist/dispatch/LocalRoutePolicy.js.map +1 -1
  147. package/dist/dispatch/OperationRoute.d.ts +2 -2
  148. package/dist/dispatch/OperationRoute.d.ts.map +1 -1
  149. package/dist/dispatch/OutputView.d.ts +3 -2
  150. package/dist/dispatch/OutputView.d.ts.map +1 -1
  151. package/dist/dispatch/OutputView.js +19 -1
  152. package/dist/dispatch/OutputView.js.map +1 -1
  153. package/dist/dispatch/Route.d.ts +2 -2
  154. package/dist/dispatch/Route.d.ts.map +1 -1
  155. package/dist/dispatch/RoutePolicy.d.ts +1 -1
  156. package/dist/dispatch/RoutePolicy.d.ts.map +1 -1
  157. package/dist/dispatch/RouteRegistry.d.ts +1 -1
  158. package/dist/dispatch/RouteRegistry.d.ts.map +1 -1
  159. package/dist/dispatch/RouteRegistry.js +2 -2
  160. package/dist/dispatch/RouteRegistry.js.map +1 -1
  161. package/dist/dispatch/RouteResolver.d.ts +2 -4
  162. package/dist/dispatch/RouteResolver.d.ts.map +1 -1
  163. package/dist/dispatch/StorageGuard.d.ts +40 -8
  164. package/dist/dispatch/StorageGuard.d.ts.map +1 -1
  165. package/dist/dispatch/StorageGuard.js +151 -20
  166. package/dist/dispatch/StorageGuard.js.map +1 -1
  167. package/dist/dispatch/presenterArguments.d.ts +7 -0
  168. package/dist/dispatch/presenterArguments.d.ts.map +1 -0
  169. package/dist/dispatch/presenterArguments.js +12 -0
  170. package/dist/dispatch/presenterArguments.js.map +1 -0
  171. package/dist/dispatch/remoteRoutes.d.ts +7 -0
  172. package/dist/dispatch/remoteRoutes.d.ts.map +1 -0
  173. package/dist/dispatch/{RemoteRouteResolver.js → remoteRoutes.js} +6 -10
  174. package/dist/dispatch/remoteRoutes.js.map +1 -0
  175. package/dist/dispatch/routeNotFound.d.ts +9 -0
  176. package/dist/dispatch/routeNotFound.d.ts.map +1 -0
  177. package/dist/dispatch/routeNotFound.js +21 -0
  178. package/dist/dispatch/routeNotFound.js.map +1 -0
  179. package/dist/dispatch/validateInput.d.ts +5 -0
  180. package/dist/dispatch/validateInput.d.ts.map +1 -0
  181. package/dist/dispatch/validateInput.js +20 -0
  182. package/dist/dispatch/validateInput.js.map +1 -0
  183. package/dist/effective-operation.d.ts +1 -24
  184. package/dist/effective-operation.d.ts.map +1 -1
  185. package/dist/effective-operation.js +21 -50
  186. package/dist/effective-operation.js.map +1 -1
  187. package/dist/emit.d.ts +4 -42
  188. package/dist/emit.d.ts.map +1 -1
  189. package/dist/emit.js +3 -39
  190. package/dist/emit.js.map +1 -1
  191. package/dist/entry/facade.d.ts +8 -0
  192. package/dist/entry/facade.d.ts.map +1 -0
  193. package/dist/entry/facade.js +28 -0
  194. package/dist/entry/facade.js.map +1 -0
  195. package/dist/entry/transport.d.ts +5 -0
  196. package/dist/entry/transport.d.ts.map +1 -0
  197. package/dist/entry/transport.js +11 -0
  198. package/dist/entry/transport.js.map +1 -0
  199. package/dist/frond-config.d.ts +7 -70
  200. package/dist/frond-config.d.ts.map +1 -1
  201. package/dist/frond-config.js +1 -9
  202. package/dist/frond-config.js.map +1 -1
  203. package/dist/identity-keys.d.ts +2 -5
  204. package/dist/identity-keys.d.ts.map +1 -1
  205. package/dist/identity-keys.js +3 -16
  206. package/dist/identity-keys.js.map +1 -1
  207. package/dist/identity.d.ts +4 -30
  208. package/dist/identity.d.ts.map +1 -1
  209. package/dist/identity.js +11 -73
  210. package/dist/identity.js.map +1 -1
  211. package/dist/imports.d.ts +1 -7
  212. package/dist/imports.d.ts.map +1 -1
  213. package/dist/imports.js +1 -7
  214. package/dist/imports.js.map +1 -1
  215. package/dist/index.d.ts +17 -24
  216. package/dist/index.d.ts.map +1 -1
  217. package/dist/index.js +10 -18
  218. package/dist/index.js.map +1 -1
  219. package/dist/loader.d.ts +1 -8
  220. package/dist/loader.d.ts.map +1 -1
  221. package/dist/loader.js +1 -8
  222. package/dist/loader.js.map +1 -1
  223. package/dist/node.d.ts +2 -11
  224. package/dist/node.d.ts.map +1 -1
  225. package/dist/node.js +2 -11
  226. package/dist/node.js.map +1 -1
  227. package/dist/prefab/collector.d.ts +1 -22
  228. package/dist/prefab/collector.d.ts.map +1 -1
  229. package/dist/prefab/collector.js +1 -22
  230. package/dist/prefab/collector.js.map +1 -1
  231. package/dist/prefab/crud.d.ts +16 -32
  232. package/dist/prefab/crud.d.ts.map +1 -1
  233. package/dist/prefab/crud.js +31 -58
  234. package/dist/prefab/crud.js.map +1 -1
  235. package/dist/prefab/mirror.d.ts +2 -24
  236. package/dist/prefab/mirror.d.ts.map +1 -1
  237. package/dist/prefab/mirror.js +2 -20
  238. package/dist/prefab/mirror.js.map +1 -1
  239. package/dist/prefab/prefab.d.ts +1 -7
  240. package/dist/prefab/prefab.d.ts.map +1 -1
  241. package/dist/prefab/prefab.js +1 -7
  242. package/dist/prefab/prefab.js.map +1 -1
  243. package/dist/prefab/presenter.d.ts +2 -36
  244. package/dist/prefab/presenter.d.ts.map +1 -1
  245. package/dist/prefab/presenter.js +2 -36
  246. package/dist/prefab/presenter.js.map +1 -1
  247. package/dist/prefab/repository.d.ts +5 -73
  248. package/dist/prefab/repository.d.ts.map +1 -1
  249. package/dist/prefab/repository.js +3 -16
  250. package/dist/prefab/repository.js.map +1 -1
  251. package/dist/scan/adapters.d.ts +3 -0
  252. package/dist/scan/adapters.d.ts.map +1 -0
  253. package/dist/scan/adapters.js +25 -0
  254. package/dist/scan/adapters.js.map +1 -0
  255. package/dist/scan/bundling.d.ts +1 -12
  256. package/dist/scan/bundling.d.ts.map +1 -1
  257. package/dist/scan/bundling.js +1 -12
  258. package/dist/scan/bundling.js.map +1 -1
  259. package/dist/scan/contract.d.ts +27 -0
  260. package/dist/scan/contract.d.ts.map +1 -0
  261. package/dist/scan/contract.js +46 -0
  262. package/dist/scan/contract.js.map +1 -0
  263. package/dist/scan/conventions.d.ts +6 -40
  264. package/dist/scan/conventions.d.ts.map +1 -1
  265. package/dist/scan/conventions.js +5 -34
  266. package/dist/scan/conventions.js.map +1 -1
  267. package/dist/scan/emit.d.ts +1 -5
  268. package/dist/scan/emit.d.ts.map +1 -1
  269. package/dist/scan/emit.js +10 -78
  270. package/dist/scan/emit.js.map +1 -1
  271. package/dist/scan/handler-parser.d.ts +4 -26
  272. package/dist/scan/handler-parser.d.ts.map +1 -1
  273. package/dist/scan/handler-parser.js +26 -83
  274. package/dist/scan/handler-parser.js.map +1 -1
  275. package/dist/scan/result.d.ts +3 -16
  276. package/dist/scan/result.d.ts.map +1 -1
  277. package/dist/scan/scanner.d.ts +2 -27
  278. package/dist/scan/scanner.d.ts.map +1 -1
  279. package/dist/scan/scanner.js +45 -133
  280. package/dist/scan/scanner.js.map +1 -1
  281. package/dist/scan/statement.d.ts.map +1 -1
  282. package/dist/scan/statement.js +60 -37
  283. package/dist/scan/statement.js.map +1 -1
  284. package/dist/source.d.ts +53 -0
  285. package/dist/source.d.ts.map +1 -0
  286. package/dist/source.js +18 -0
  287. package/dist/source.js.map +1 -0
  288. package/dist/storage.d.ts +13 -210
  289. package/dist/storage.d.ts.map +1 -1
  290. package/dist/storage.js +4 -68
  291. package/dist/storage.js.map +1 -1
  292. package/dist/store.d.ts +18 -0
  293. package/dist/store.d.ts.map +1 -0
  294. package/dist/store.js +179 -0
  295. package/dist/store.js.map +1 -0
  296. package/dist/verify.d.ts +5 -38
  297. package/dist/verify.d.ts.map +1 -1
  298. package/dist/verify.js +17 -37
  299. package/dist/verify.js.map +1 -1
  300. package/dist/wire/CallLog.d.ts +32 -0
  301. package/dist/wire/CallLog.d.ts.map +1 -0
  302. package/dist/{contract → wire}/CallLog.js.map +1 -1
  303. package/dist/wire/Invocation.d.ts +32 -0
  304. package/dist/wire/Invocation.d.ts.map +1 -0
  305. package/dist/wire/Invocation.js +66 -0
  306. package/dist/wire/Invocation.js.map +1 -0
  307. package/dist/{contract → wire}/RouteAddress.d.ts +5 -0
  308. package/dist/wire/RouteAddress.d.ts.map +1 -0
  309. package/dist/{contract → wire}/RouteAddress.js +7 -0
  310. package/dist/wire/RouteAddress.js.map +1 -0
  311. package/dist/wire/binding.d.ts +5 -21
  312. package/dist/wire/binding.d.ts.map +1 -1
  313. package/dist/wire/binding.js +5 -10
  314. package/dist/wire/binding.js.map +1 -1
  315. package/dist/wire/call.d.ts +24 -133
  316. package/dist/wire/call.d.ts.map +1 -1
  317. package/dist/wire/call.js +15 -41
  318. package/dist/wire/call.js.map +1 -1
  319. package/dist/wire/drift.d.ts +3 -28
  320. package/dist/wire/drift.d.ts.map +1 -1
  321. package/dist/wire/drift.js +4 -23
  322. package/dist/wire/drift.js.map +1 -1
  323. package/dist/wire/errors.d.ts +4 -24
  324. package/dist/wire/errors.d.ts.map +1 -1
  325. package/dist/wire/errors.js +4 -24
  326. package/dist/wire/errors.js.map +1 -1
  327. package/dist/wire/http-error.d.ts +2 -13
  328. package/dist/wire/http-error.d.ts.map +1 -1
  329. package/dist/wire/http-error.js +5 -19
  330. package/dist/wire/http-error.js.map +1 -1
  331. package/dist/wire/loggerMiddleware.d.ts +2 -8
  332. package/dist/wire/loggerMiddleware.d.ts.map +1 -1
  333. package/dist/wire/loggerMiddleware.js +1 -7
  334. package/dist/wire/loggerMiddleware.js.map +1 -1
  335. package/dist/wire/middleware.d.ts +3 -7
  336. package/dist/wire/middleware.d.ts.map +1 -1
  337. package/dist/wire/middleware.js +1 -5
  338. package/dist/wire/middleware.js.map +1 -1
  339. package/dist/wire/operation.d.ts +7 -43
  340. package/dist/wire/operation.d.ts.map +1 -1
  341. package/dist/wire/operation.js +4 -15
  342. package/dist/wire/operation.js.map +1 -1
  343. package/dist/wire/signature.d.ts +4 -25
  344. package/dist/wire/signature.d.ts.map +1 -1
  345. package/package.json +3 -3
  346. package/src/boot/AppLifecycle.ts +15 -2
  347. package/src/boot/Emissions.ts +21 -118
  348. package/src/boot/ambient-port.ts +3 -24
  349. package/src/boot/ambient.als.ts +7 -12
  350. package/src/boot/ambient.queue.ts +2 -5
  351. package/src/boot/apply.ts +9 -16
  352. package/src/boot/auth.ts +2 -12
  353. package/src/boot/boot.ts +6 -21
  354. package/src/boot/bootstrap.ts +95 -140
  355. package/src/boot/card.ts +4 -33
  356. package/src/boot/frame.ts +24 -64
  357. package/src/boot/hosted.ts +12 -34
  358. package/src/boot/ownership.ts +5 -39
  359. package/src/boot/ports.ts +1 -14
  360. package/src/boot/remote.ts +11 -58
  361. package/src/boot/runner.ts +5 -22
  362. package/src/boot/seed.ts +6 -37
  363. package/src/boot/statement-drift.ts +5 -24
  364. package/src/boot/together.ts +18 -51
  365. package/src/boot/types.ts +31 -173
  366. package/src/{builtins → builtin}/config.ts +1 -7
  367. package/src/{builtins → builtin}/logger.ts +6 -39
  368. package/src/config-loader.ts +12 -71
  369. package/src/contract.ts +19 -39
  370. package/src/criterion.ts +54 -0
  371. package/src/crypto/encoding.ts +2 -15
  372. package/src/crypto/node.ts +1 -7
  373. package/src/crypto/port.ts +2 -18
  374. package/src/crypto/webcrypto.ts +1 -12
  375. package/src/declare.ts +42 -41
  376. package/src/define.ts +2 -3
  377. package/src/descriptor/Fronds.ts +6 -31
  378. package/src/descriptor/frond.ts +26 -60
  379. package/src/dispatch/ArgumentResolver.ts +6 -6
  380. package/src/dispatch/DispatchEvent.ts +2 -2
  381. package/src/dispatch/DispatchLifecycle.ts +1 -7
  382. package/src/dispatch/DispatchPort.ts +1 -1
  383. package/src/dispatch/Dispatcher.ts +3 -3
  384. package/src/dispatch/HandlerFacade.ts +231 -0
  385. package/src/dispatch/LocalRoutePolicy.ts +4 -4
  386. package/src/dispatch/OperationRoute.ts +2 -2
  387. package/src/dispatch/OutputView.ts +24 -2
  388. package/src/dispatch/Route.ts +2 -2
  389. package/src/dispatch/RoutePolicy.ts +1 -1
  390. package/src/dispatch/RouteRegistry.ts +2 -2
  391. package/src/dispatch/RouteResolver.ts +2 -4
  392. package/src/dispatch/StorageGuard.ts +175 -19
  393. package/src/dispatch/presenterArguments.ts +25 -0
  394. package/src/dispatch/{RemoteRouteResolver.ts → remoteRoutes.ts} +7 -9
  395. package/src/dispatch/routeNotFound.ts +33 -0
  396. package/src/dispatch/validateInput.ts +28 -0
  397. package/src/effective-operation.ts +21 -50
  398. package/src/emit.ts +5 -63
  399. package/src/entry/facade.ts +44 -0
  400. package/src/entry/transport.ts +16 -0
  401. package/src/frond-config.ts +7 -70
  402. package/src/identity-keys.ts +3 -16
  403. package/src/identity.ts +12 -80
  404. package/src/imports.ts +2 -31
  405. package/src/index.ts +17 -24
  406. package/src/loader.ts +2 -16
  407. package/src/node.ts +2 -11
  408. package/src/prefab/collector.ts +1 -22
  409. package/src/prefab/crud.ts +37 -76
  410. package/src/prefab/mirror.ts +4 -44
  411. package/src/prefab/prefab.ts +2 -21
  412. package/src/prefab/presenter.ts +2 -36
  413. package/src/prefab/repository.ts +7 -83
  414. package/src/scan/adapters.ts +32 -0
  415. package/src/scan/bundling.ts +1 -12
  416. package/src/scan/contract.ts +80 -0
  417. package/src/scan/conventions.ts +6 -40
  418. package/src/scan/emit.ts +11 -80
  419. package/src/scan/handler-parser.ts +27 -96
  420. package/src/scan/result.ts +3 -16
  421. package/src/scan/scanner.ts +46 -132
  422. package/src/scan/statement.ts +73 -41
  423. package/src/source.ts +63 -0
  424. package/src/storage.ts +14 -234
  425. package/src/store.ts +191 -0
  426. package/src/verify.ts +16 -57
  427. package/src/wire/CallLog.ts +30 -0
  428. package/src/{contract → wire}/Invocation.ts +24 -17
  429. package/src/{contract → wire}/RouteAddress.ts +7 -0
  430. package/src/wire/binding.ts +9 -25
  431. package/src/wire/call.ts +30 -133
  432. package/src/wire/drift.ts +5 -30
  433. package/src/wire/errors.ts +4 -24
  434. package/src/wire/http-error.ts +5 -19
  435. package/src/wire/loggerMiddleware.ts +2 -8
  436. package/src/wire/middleware.ts +3 -7
  437. package/src/wire/operation.ts +8 -48
  438. package/src/wire/signature.ts +4 -25
  439. package/dist/boot/HandlerFacade.d.ts.map +0 -1
  440. package/dist/boot/HandlerFacade.js.map +0 -1
  441. package/dist/builtins/config.d.ts +0 -13
  442. package/dist/builtins/config.d.ts.map +0 -1
  443. package/dist/builtins/config.js +0 -21
  444. package/dist/builtins/config.js.map +0 -1
  445. package/dist/builtins/logger.d.ts.map +0 -1
  446. package/dist/builtins/logger.js.map +0 -1
  447. package/dist/contract/Call.d.ts +0 -10
  448. package/dist/contract/Call.d.ts.map +0 -1
  449. package/dist/contract/Call.js +0 -15
  450. package/dist/contract/Call.js.map +0 -1
  451. package/dist/contract/CallLog.d.ts +0 -57
  452. package/dist/contract/CallLog.d.ts.map +0 -1
  453. package/dist/contract/Invocation.d.ts +0 -27
  454. package/dist/contract/Invocation.d.ts.map +0 -1
  455. package/dist/contract/Invocation.js +0 -59
  456. package/dist/contract/Invocation.js.map +0 -1
  457. package/dist/contract/RouteAddress.d.ts.map +0 -1
  458. package/dist/contract/RouteAddress.js.map +0 -1
  459. package/dist/dispatch/InputValidator.d.ts +0 -7
  460. package/dist/dispatch/InputValidator.d.ts.map +0 -1
  461. package/dist/dispatch/InputValidator.js +0 -22
  462. package/dist/dispatch/InputValidator.js.map +0 -1
  463. package/dist/dispatch/OperationExecutor.d.ts +0 -25
  464. package/dist/dispatch/OperationExecutor.d.ts.map +0 -1
  465. package/dist/dispatch/OperationExecutor.js +0 -32
  466. package/dist/dispatch/OperationExecutor.js.map +0 -1
  467. package/dist/dispatch/OutputProjector.d.ts +0 -12
  468. package/dist/dispatch/OutputProjector.d.ts.map +0 -1
  469. package/dist/dispatch/OutputProjector.js +0 -30
  470. package/dist/dispatch/OutputProjector.js.map +0 -1
  471. package/dist/dispatch/PresenterArgumentResolver.d.ts +0 -12
  472. package/dist/dispatch/PresenterArgumentResolver.d.ts.map +0 -1
  473. package/dist/dispatch/PresenterArgumentResolver.js +0 -20
  474. package/dist/dispatch/PresenterArgumentResolver.js.map +0 -1
  475. package/dist/dispatch/RemoteRouteResolver.d.ts +0 -13
  476. package/dist/dispatch/RemoteRouteResolver.d.ts.map +0 -1
  477. package/dist/dispatch/RemoteRouteResolver.js.map +0 -1
  478. package/dist/dispatch/RouteNotFoundError.d.ts +0 -10
  479. package/dist/dispatch/RouteNotFoundError.d.ts.map +0 -1
  480. package/dist/dispatch/RouteNotFoundError.js +0 -24
  481. package/dist/dispatch/RouteNotFoundError.js.map +0 -1
  482. package/dist/entry/DynamicFacade.d.ts +0 -10
  483. package/dist/entry/DynamicFacade.d.ts.map +0 -1
  484. package/dist/entry/DynamicFacade.js +0 -27
  485. package/dist/entry/DynamicFacade.js.map +0 -1
  486. package/dist/entry/FacadeEntry.d.ts +0 -11
  487. package/dist/entry/FacadeEntry.d.ts.map +0 -1
  488. package/dist/entry/FacadeEntry.js +0 -26
  489. package/dist/entry/FacadeEntry.js.map +0 -1
  490. package/dist/entry/TransportEntry.d.ts +0 -13
  491. package/dist/entry/TransportEntry.d.ts.map +0 -1
  492. package/dist/entry/TransportEntry.js +0 -24
  493. package/dist/entry/TransportEntry.js.map +0 -1
  494. package/dist/rows.d.ts +0 -40
  495. package/dist/rows.d.ts.map +0 -1
  496. package/dist/rows.js +0 -146
  497. package/dist/rows.js.map +0 -1
  498. package/src/boot/HandlerFacade.ts +0 -242
  499. package/src/contract/Call.ts +0 -18
  500. package/src/contract/CallLog.ts +0 -55
  501. package/src/dispatch/InputValidator.ts +0 -28
  502. package/src/dispatch/OperationExecutor.ts +0 -60
  503. package/src/dispatch/OutputProjector.ts +0 -32
  504. package/src/dispatch/PresenterArgumentResolver.ts +0 -25
  505. package/src/dispatch/RouteNotFoundError.ts +0 -29
  506. package/src/entry/DynamicFacade.ts +0 -28
  507. package/src/entry/FacadeEntry.ts +0 -32
  508. package/src/entry/TransportEntry.ts +0 -30
  509. package/src/rows.ts +0 -155
  510. /package/dist/{contract → wire}/CallLog.js +0 -0
package/src/contract.ts CHANGED
@@ -1,61 +1,43 @@
1
1
  /**
2
- * Contract surface — what a sender needs to speak to a receiver, and
3
- * nothing that assumes a runtime: the error vocabulary, the invocation
4
- * shape, the call value, the naming convention.
5
- *
6
- * Browser-safe by design: no node builtin may enter this module's import
7
- * graph. Published as the `@fougere/core/contract` subpath so client
8
- * bundles never touch the full index (scanner, config loader). `@fougere/schema`
9
- * is allowed in — measured, it imports no node builtin either.
2
+ * Contract surface — what a sender needs to speak to a receiver, and nothing that assumes a
3
+ * runtime: the error vocabulary, the invocation shape, the call value, the naming convention.
10
4
  */
11
5
  import { lowerFirst } from '@fougere/schema';
12
- import { canonicalInvocation, type InvocationContext } from './contract/Invocation.js';
6
+ import { canonicalInvocation, type InvocationContext } from './wire/Invocation.js';
13
7
  import type { FrondCall } from './wire/call.js';
14
8
 
15
9
  export { FougereError, ErrorCode, validationErrorsOf } from './wire/errors.js';
10
+ // What a read may ask about one field. Here rather than on the main entry because an
11
+ // adapter reads it to compile a query, and an adapter carries no boot.
12
+ export { comparisonOf, comparisonsIn, unknownIn, COMPARISONS } from './criterion.js';
13
+ export type { Comparison, ComparisonName } from './criterion.js';
16
14
  // A receiver turns a refusal into what may cross a process boundary, and it is not
17
15
  // core's boot — reaching it through the main entry dragged the scanner into a bundle.
18
16
  export { toPublicError } from './wire/http-error.js';
19
17
  export type { FougereErrorOptions } from './wire/errors.js';
20
- export { canonicalInvocation, EMPTY_INVOCATION } from './contract/Invocation.js';
21
- export type { InvocationContext } from './contract/Invocation.js';
22
- export { Invocation } from './contract/Invocation.js';
23
- export type { InvocationInput } from './contract/Invocation.js';
24
- export { Call } from './contract/Call.js';
25
- export { RouteAddress } from './contract/RouteAddress.js';
26
- export type { RouteAddressInput } from './contract/RouteAddress.js';
18
+ export { canonicalInvocation, EMPTY_INVOCATION } from './wire/Invocation.js';
19
+ export type { InvocationContext } from './wire/Invocation.js';
20
+ export { Invocation } from './wire/Invocation.js';
21
+ export type { PartialInvocation } from './wire/Invocation.js';
22
+ export { Call } from './wire/call.js';
23
+ export { RouteAddress } from './wire/RouteAddress.js';
24
+ export type { RouteAddressInput } from './wire/RouteAddress.js';
27
25
  export type { FrondCall, Transport, SignedCall } from './wire/call.js';
28
26
  export { MAX_BODY_BYTES } from './wire/call.js';
29
27
  // The reserved entity, VALUE and not type: a consumer that wants to leave it alone — a
30
28
  // call log ignoring its own reader — has to be able to name it.
31
29
  export { RPC_ENTITY } from './wire/call.js';
32
- export type { CallPage, CallRecord } from './contract/CallLog.js';
30
+ export type { CallPage, CallRecord } from './wire/CallLog.js';
33
31
  // The comparison of two cards, which a consumer runs about a producer — browser-safe on
34
32
  // purpose: a panel showing the drift holds only the two cards, never the app.
35
33
  export { driftOf, agrees, explain } from './wire/drift.js';
36
34
  export type { CardDrift } from './wire/drift.js';
37
35
 
38
- /**
39
- * What `rpc.discover` answers. It belongs here and not to the runtime: the
40
- * reserved op travels on the same wire as every other call, so a consumer that
41
- * only sends — a browser bundle, a frond written elsewhere — needs its shape and
42
- * nothing else. Type-only, so `call.js` never enters the runtime graph.
43
- *
44
- * Stated once, on purpose: two private copies of this interface have already gone
45
- * stale (the CLI's, then the Rust demo's) the day an op stopped being a bare name.
46
- */
36
+ /** What `rpc.discover` answers. */
47
37
  export type { IdentityCard, CardOp, TopologyReport, FrondPlacement, Edge } from './wire/call.js';
48
38
  export { assertIdentityCard } from './wire/call.js';
49
39
 
50
- /**
51
- * The key a class name is filed under — 'Post' → 'post'. Re-exported rather than
52
- * respelled: a card writes it and a foreign key derives from it, so the convention
53
- * belongs to the schema, and a second copy here is a second opinion. It travels
54
- * through this subpath because a consumer of the wire (a browser bundle) may hold no
55
- * schema dependency of its own — that audience only. Inside the package it is read from
56
- * `@fougere/schema` directly: routing four modules through here bought nothing and put
57
- * this file inside a cycle.
58
- */
40
+ /** The key a class name is filed under — 'Post' → 'post'. */
59
41
  export { lowerFirst } from '@fougere/schema';
60
42
 
61
43
  /** A call, fully fabricated: the designation and its completed invocation. */
@@ -65,10 +47,8 @@ export interface CallValue {
65
47
  }
66
48
 
67
49
  /**
68
- * Fabricate the call value — one designation, two spellings:
69
- * `callValueOf(Post, 'list', { query })` (class + verb) or
70
- * `callValueOf({ entity, op }, input)` (raw, for dynamic bridges).
71
- * Missing invocation fields complete to the empty invocation.
50
+ * Fabricate the call value — one designation, two spellings: `callValueOf(Post, 'list', { query
51
+ * })` (class + verb) or `callValueOf({ entity, op }, input)` (raw, for dynamic bridges).
72
52
  */
73
53
  export function callValueOf(
74
54
  target: { name: string } | FrondCall,
@@ -0,0 +1,54 @@
1
+ /** What a read may ask about one field, and how a storage tells the two forms apart. */
2
+ import { type Field, Shapes } from '@fougere/schema';
3
+
4
+ /**
5
+ * The comparisons a criterion may name.
6
+ *
7
+ * `eq` and `in` are not here: a bare value already means equality and an array already
8
+ * means membership, and giving them a second spelling would make one criterion sayable
9
+ * two ways. What is added is what those two could not say at all.
10
+ */
11
+ export interface Comparison {
12
+ gte?: unknown;
13
+ lte?: unknown;
14
+ gt?: unknown;
15
+ lt?: unknown;
16
+ ne?: unknown;
17
+ /** Both bounds, inclusive — `between: [1500, 4000]`. */
18
+ between?: [unknown, unknown];
19
+ contains?: string;
20
+ notIn?: readonly unknown[];
21
+ isNull?: boolean;
22
+ }
23
+
24
+ export const COMPARISONS = ['gte', 'lte', 'gt', 'lt', 'ne', 'between', 'contains', 'notIn', 'isNull'] as const;
25
+
26
+ export type ComparisonName = (typeof COMPARISONS)[number];
27
+
28
+ /**
29
+ * Is this criterion a comparison, or a value that happens to be an object?
30
+ *
31
+ * Read off the FIELD, never off the value. `json()` admits any shape, so `{ gte: … }` is
32
+ * a legal thing to store — telling the two apart by looking at the criterion would make a
33
+ * stored object unfilterable the day its keys happened to spell an operator. The shape
34
+ * knows, and it is the only thing that does.
35
+ */
36
+ export function comparisonOf(field: Field | undefined, asked: unknown): Comparison | undefined {
37
+ if (asked === null || typeof asked !== 'object' || Array.isArray(asked)) return undefined;
38
+ // `Shapes.of` answers with `null` already taken out — `optional(json())` is an object.
39
+ if (!field || Shapes.of(field.shape).base?.type === 'object') return undefined;
40
+
41
+ return asked as Comparison;
42
+ }
43
+
44
+ /** The comparisons a criterion names, in the order the caller wrote them. */
45
+ export function comparisonsIn(comparison: Comparison): [ComparisonName, unknown][] {
46
+ return Object.entries(comparison).filter(
47
+ (entry): entry is [ComparisonName, unknown] => (COMPARISONS as readonly string[]).includes(entry[0]),
48
+ );
49
+ }
50
+
51
+ /** What a comparison names that this vocabulary does not — a typo, said as one. */
52
+ export function unknownIn(comparison: Comparison): string[] {
53
+ return Object.keys(comparison).filter((name) => !(COMPARISONS as readonly string[]).includes(name));
54
+ }
@@ -1,11 +1,4 @@
1
- /**
2
- * What both realizations spell identically — bytes in, bytes out, no platform.
3
- *
4
- * `Buffer` did all of this and does not exist on a Worker; `atob`/`btoa` exist on both.
5
- * Nothing here is a policy decision, which is why it sits beside the port rather than
6
- * inside either half: two copies of a base64url would be two chances to disagree on the
7
- * padding, and the disagreement would show up as a bad signature.
8
- */
1
+ /** What both realizations spell identically — bytes in, bytes out, no platform. */
9
2
 
10
3
  const encoder = new TextEncoder();
11
4
  const decoder = new TextDecoder();
@@ -45,13 +38,7 @@ export const unb64 = (input: string): Uint8Array => {
45
38
  return bytes;
46
39
  };
47
40
 
48
- /**
49
- * The DER a PEM wraps. WebCrypto imports DER and knows nothing about the armour.
50
- *
51
- * The label is not checked: a caller asking for a private key and handed a public one
52
- * fails at `importKey` with a message about the key, which is the truer error than one
53
- * about a header line.
54
- */
41
+ /** The DER a PEM wraps. */
55
42
  export function derOf(pem: string): Uint8Array {
56
43
  const body = pem.replace(/-----(BEGIN|END)[^-]+-----/g, '').replace(/\s+/g, '');
57
44
  if (body.length === 0) throw new Error('Not a PEM: no base64 body between the armour');
@@ -1,10 +1,4 @@
1
- /**
2
- * Ed25519 through `node:crypto` — the default realization, and the fast one.
3
- *
4
- * `sign`/`verify` are synchronous here and stay synchronous: the promise is put around
5
- * the answer, never around the work. That is the whole reason this file exists rather
6
- * than everyone sharing the WebCrypto half.
7
- */
1
+ /** Ed25519 through `node:crypto` — the default realization, and the fast one. */
8
2
  import { createHash, createPrivateKey, createPublicKey, sign, verify } from 'node:crypto';
9
3
  import type { CryptoPort, PublicJwk, Signer, Verifier } from './port.js';
10
4
 
@@ -1,20 +1,4 @@
1
- /**
2
- * The two Ed25519 gestures a signed call needs, and the one hash that binds it.
3
- *
4
- * Node signs 59% faster than WebCrypto on the same curve (measured 2026-08-23: 14.30 µs
5
- * against 22.72 µs per signature, 34.42 against 41.81 to verify), so this is a PORT with
6
- * two realizations and not one implementation at the lowest common denominator. `#crypto`
7
- * resolves to `crypto/node.ts` everywhere except under the `workerd` condition — the
8
- * bundler picks at build time, and neither half ever appears in the other's output.
9
- *
10
- * The shape is async because WebCrypto is. On Node that costs one microtask, which the
11
- * same measurement puts inside the noise of the signature itself (14.30 sync against
12
- * 14.28 awaited) — awaiting is free, converting is not.
13
- *
14
- * A KEY IS PARSED ONCE. `crypto.subtle.importKey` is async and per-key, so an interface
15
- * shaped `sign(key, data)` would import on every call; `signerOf(pem)` hands back
16
- * something that holds the parsed key, and a boot builds it once.
17
- */
1
+ /** The two Ed25519 gestures a signed call needs, and the one hash that binds it. */
18
2
 
19
3
  /** A parsed private key. */
20
4
  export interface Signer {
@@ -36,7 +20,7 @@ export interface PublicJwk {
36
20
  }
37
21
 
38
22
  export interface CryptoPort {
39
- /** SHA-256. What binds a body to an envelope without carrying the body. */
23
+ /** SHA-256. What binds an input to an envelope without carrying the input. */
40
24
  sha256(data: Uint8Array): Promise<Uint8Array>;
41
25
  /** From a PKCS#8 PEM — what `fougere keys` writes. */
42
26
  signerOf(privateKeyPem: string): Promise<Signer>;
@@ -1,15 +1,4 @@
1
- /**
2
- * Ed25519 through WebCrypto — what a runtime with no `node:` builtin has.
3
- *
4
- * Verified in real workerd with no compatibility flag (2026-08-23): sign, verify, a JWK
5
- * import, an SPKI import and SHA-256 all answer. `Ed25519` is the algorithm name; the
6
- * older `NODE-ED25519` spelling is not used, and a runtime that only knows that one will
7
- * refuse at `importKey` rather than silently signing with something else.
8
- *
9
- * The four gestures are declared here rather than pulled from `lib.dom`: this package
10
- * compiles with `lib: ["ESNext"]` and naming DOM would make every consumer carry a
11
- * browser's globals to read a server type. What the file needs IS the declaration.
12
- */
1
+ /** Ed25519 through WebCrypto — what a runtime with no `node:` builtin has. */
13
2
  import { derOf } from './encoding.js';
14
3
  import type { CryptoPort, PublicJwk, Signer, Verifier } from './port.js';
15
4
 
package/src/declare.ts CHANGED
@@ -1,20 +1,4 @@
1
- /**
2
- * A frond stated by its author, for an app that will not scan.
3
- *
4
- * The scan reads the type checker because a signature IS a declaration — and that reading
5
- * has to happen while the types still exist, which is build time. An app that wants
6
- * neither a build step nor `typescript` at runtime says the same thing here instead, and
7
- * `createApp` cannot tell the difference: it consumes a `ScanResult`, never a scanner.
8
- *
9
- * What it does NOT ask for is the point. Every name the scan derives from a class is
10
- * derived here the same way — `PostHandler` answers at `post`, `Post` is stored as `post`
11
- * — so a declaration states classes and nothing else. `filePath` is empty because there is
12
- * no file to point at, and a diagnostic that would have quoted one says so plainly.
13
- *
14
- * Measured on `demos/nuxt-blog`: 23 of its 29 operations need no word here at all, because
15
- * `Crud.__ops` declares them at runtime. Only the six the author wrote by hand cost
16
- * anything, and they cost `frond.config.ts` — where what is not derivable is stated.
17
- */
1
+ /** A frond stated by its author, for an app that will not scan. */
18
2
  import { lowerFirst, type SchemaView } from '@fougere/schema';
19
3
  import type {
20
4
  CollectorEntry, EntityEntry, FrondDescriptor, HandlerEntry,
@@ -22,17 +6,12 @@ import type {
22
6
  } from './descriptor/frond.js';
23
7
  import { DEFAULT_CONVENTIONS } from './scan/conventions.js';
24
8
  import { getPresenterFields } from './prefab/presenter.js';
9
+ import type { OperationContract } from './wire/operation.js';
25
10
 
26
11
  /** A class, as a declaration hands it over: the constructor itself. */
27
12
  type Ctor = new (...args: never[]) => unknown;
28
13
 
29
- /**
30
- * What a subject needs beyond its class, when its constructor names a frame or a port.
31
- *
32
- * `deps` is the one thing no runtime can recover: TypeScript erases the parameter types,
33
- * and `registerFrames` reads them to know which frames to build — asking for one IS
34
- * declaring it. A handler that takes only its own entity's storage needs nothing here.
35
- */
14
+ /** What a subject needs beyond its class, when its constructor names a frame or a port. */
36
15
  export interface DeclaredSubject {
37
16
  ctor: Ctor;
38
17
  deps?: string[];
@@ -41,23 +20,31 @@ export interface DeclaredSubject {
41
20
  /** A handler, and the surface it answers on when it is not the default one. */
42
21
  export interface DeclaredHandler extends DeclaredSubject {
43
22
  /**
44
- * The scan reads this from the directory (`handlers/public/`), so a statement has to
45
- * say it: two handlers over one entity collide on their address otherwise, and the
46
- * refusal names the same route twice.
23
+ * The scan reads this from the directory (`handlers/public/`), so a statement has to say it: two
24
+ * handlers over one entity collide on their address otherwise, and the refusal names the same
25
+ * route twice.
47
26
  */
48
27
  surface?: string;
28
+ /**
29
+ * What each method takes and answers — read from SOURCE by the scan, and unreachable
30
+ * from a class at runtime. A prefab declares its own (`Crud.__ops`) and needs nothing
31
+ * here; a method someone wrote does, or the route it should serve does not exist.
32
+ */
33
+ operations?: ReadonlyMap<string, OperationContract> | Record<string, OperationContract>;
49
34
  }
50
35
 
51
36
  /** A class on its own, or a class with what it asks for. */
52
- export type Declared = Ctor | DeclaredSubject;
37
+ export type Declared = Ctor | (DeclaredSubject & {
38
+ /** The container key, when the class's own name cannot be trusted to survive a build. */
39
+ name?: string;
40
+ });
53
41
 
54
42
  const ctorOf = (d: Declared): Ctor => (typeof d === 'function' ? d : d.ctor);
55
43
 
56
44
  /**
57
45
  * What a prefab was BUILT ON — `Presenter(Post)` and `Collector(User)` both keep it under
58
- * `__entity`, which is the only place it survives: nothing in the FORM of `PostPresenter`
59
- * says `Post`. Absent, the class did not come through the prefab, and the refusal says so
60
- * rather than yielding a frond whose presenter belongs to no entity.
46
+ * `__entity`, which is the only place it survives: nothing in the FORM of `PostPresenter` says
47
+ * `Post`.
61
48
  */
62
49
  function subjectOf(ctor: Ctor, kind: string): { name: string } {
63
50
  const subject = (ctor as unknown as { __entity?: { name: string } }).__entity;
@@ -72,6 +59,22 @@ function subjectOf(ctor: Ctor, kind: string): { name: string } {
72
59
  }
73
60
  const depsOf = (d: Declared): string[] => (typeof d === 'function' ? [] : d.deps ?? []);
74
61
 
62
+ /**
63
+ * A Map either way — a statement is read as code, and an object literal is what code
64
+ * looks like there. What a prefab declares of itself is merged BELOW: a method the author
65
+ * wrote over `create` is the one that runs, so its contract is the one that answers.
66
+ */
67
+ function statedOperations(h: Ctor | DeclaredHandler): Map<string, OperationContract> {
68
+ const declared = typeof h === 'function' ? undefined : h.operations;
69
+ const own = (ctorOf(h) as { __ops?: Record<string, OperationContract> }).__ops ?? {};
70
+ const merged = new Map<string, OperationContract>(Object.entries(own));
71
+ for (const [op, contract] of declared instanceof Map ? declared : Object.entries(declared ?? {})) {
72
+ merged.set(op, contract as OperationContract);
73
+ }
74
+
75
+ return merged;
76
+ }
77
+
75
78
  /** `PostHandler` answers at `post` — the same rule the scan applies to a file it found. */
76
79
  function addressOf(className: string): string {
77
80
  const base = className.endsWith('Handler') ? className.slice(0, -7) : className;
@@ -91,17 +94,11 @@ export interface FrondDeclaration {
91
94
  surfaces?: Record<string, string[]>;
92
95
  /** The import scope this frond answers under. Defaults to the conventional one. */
93
96
  scope?: string;
97
+ /** What `frond.config.ts` states — the third producer of an operation contract. */
98
+ operationsOverrides?: FrondDescriptor['operationsOverrides'];
94
99
  }
95
100
 
96
- /**
97
- * State a frond without reading a disk.
98
- *
99
- * ```ts
100
- * createApp({
101
- * scan: { fronds: Fronds.hosting([frond('blog', { entities: [Post], handlers: [PostHandler] })]), diagnostics: [] },
102
- * })
103
- * ```
104
- */
101
+ /** State a frond without reading a disk. */
105
102
  export function frond(name: string, declared: FrondDeclaration = {}): FrondDescriptor {
106
103
  const scope = declared.scope ?? DEFAULT_CONVENTIONS.scope;
107
104
 
@@ -124,7 +121,7 @@ export function frond(name: string, declared: FrondDeclaration = {}): FrondDescr
124
121
  // A handler about no stored row is ordinary — the address is not a promise that an
125
122
  // entity carries it, which is why this is not looked up.
126
123
  entityName: address,
127
- operations: new Map(),
124
+ operations: statedOperations(h),
128
125
  deps: depsOf(h),
129
126
  filePath: '',
130
127
  exposed: true,
@@ -163,6 +160,9 @@ export function frond(name: string, declared: FrondDeclaration = {}): FrondDescr
163
160
  });
164
161
 
165
162
  const providers: ProviderEntry[] = (declared.providers ?? []).map((p) => ({
163
+ // Written down where a statement says it, read off the class otherwise — the class's
164
+ // own name is what a bundler is free to rewrite.
165
+ ...(typeof p === 'function' || !p.name ? {} : { name: p.name }),
166
166
  ctor: ctorOf(p),
167
167
  deps: depsOf(p),
168
168
  filePath: '',
@@ -177,6 +177,7 @@ export function frond(name: string, declared: FrondDeclaration = {}): FrondDescr
177
177
  return {
178
178
  name,
179
179
  source: { path: '', package: `${scope}/${name}` },
180
+ ...(declared.operationsOverrides ? { operationsOverrides: declared.operationsOverrides } : {}),
180
181
  providers,
181
182
  entities,
182
183
  handlers,
package/src/define.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import type { FougereConfig } from './config-loader.js';
2
2
 
3
3
  /**
4
- * Identity helper for fougere.config.ts — preserves literal types for autocomplete
5
- * while validating against FougereConfig. Equivalent to `satisfies FougereConfig`
6
- * but more explicit and aligned with defineFrond().
4
+ * Identity helper for fougere.config.ts — preserves literal types for autocomplete while
5
+ * validating against FougereConfig.
7
6
  */
8
7
  export function defineFougere<T extends FougereConfig>(config: T): T {
9
8
  return config;
@@ -1,19 +1,7 @@
1
1
  import type { SchemaView } from '@fougere/schema';
2
2
  import type { EntityEntry, FrondDescriptor } from './frond.js';
3
3
 
4
- /**
5
- * What this app hosts, with the questions everyone was asking it by hand.
6
- *
7
- * The list was a bare array, so every reader re-walked it: "which frond owns this
8
- * entity" was spelled four times, "every entity by name" three times as three literal
9
- * copies of the same `Map`, and the two inside the boot even carried comments saying so.
10
- * A concept nobody can question is a concept everyone rebuilds.
11
- *
12
- * It IS an array — the same reason `ListResult` is one: twenty call sites iterate,
13
- * filter and spread it, and none of them is wrong to. `Symbol.species` is `Array` so a
14
- * `.map()` over it answers a plain array rather than something that claims to be a
15
- * hosting table and holds strings.
16
- */
4
+ /** What this app hosts, with the questions everyone was asking it by hand. */
17
5
  export class Fronds extends Array<FrondDescriptor> {
18
6
  static override get [Symbol.species](): ArrayConstructor {
19
7
  return Array;
@@ -21,9 +9,9 @@ export class Fronds extends Array<FrondDescriptor> {
21
9
 
22
10
  /** The fronds an app hosts, scanned or stated. The only gate in — `Array.of` is taken. */
23
11
  static hosting(fronds: readonly FrondDescriptor[]): Fronds {
24
- const held = new Fronds();
25
- held.push(...fronds);
26
- return held;
12
+ const all = new Fronds();
13
+ all.push(...fronds);
14
+ return all;
27
15
  }
28
16
 
29
17
  /** The frond that hosts an entity — `undefined` when no loaded frond does. */
@@ -40,13 +28,7 @@ export class Fronds extends Array<FrondDescriptor> {
40
28
  return undefined;
41
29
  }
42
30
 
43
- /**
44
- * Every entity class, by name — across all fronds and never per-frond.
45
- *
46
- * A fact is announced in one frond and heard in another, so the subscriber's own
47
- * frond does not hold the shape it must judge; a `reads:` clause names entities
48
- * that belong to neighbours by definition.
49
- */
31
+ /** Every entity class, by name — across all fronds and never per-frond. */
50
32
  schemas(): Map<string, SchemaView> {
51
33
  return new Map(this.flatMap((frond) => frond.entities.map((e) => [e.name, e.entityClass] as const)));
52
34
  }
@@ -56,14 +38,7 @@ export class Fronds extends Array<FrondDescriptor> {
56
38
  return this.flatMap((frond) => frond.entities.map((e) => e.name)).sort();
57
39
  }
58
40
 
59
- /**
60
- * The names a call may address, sorted — what a NOT_FOUND must print.
61
- *
62
- * Not `entityNames()`, which is what the scan found: an entity with no handler is
63
- * scanned and serves nothing, so the refusal read *"Entity 'indexed' is not hosted
64
- * here. Hosted here: indexed."* — naming the very thing it had just refused. A façade
65
- * is keyed on a HANDLER's address, and that is what this lists.
66
- */
41
+ /** The names a call may address, sorted — what a NOT_FOUND must print. */
67
42
  servedNames(surface?: string): string[] {
68
43
  return this.flatMap((frond) => frond.handlers
69
44
  .filter((handler) => (handler.surface ?? undefined) === surface)
@@ -1,33 +1,21 @@
1
- /**
2
- * What a frond is made of — one interface per convention directory.
3
- *
4
- * Produced two ways and indistinguishable once here: the scan DERIVES it from a
5
- * directory tree, `frond()` STATES it outright. `frond-config.ts` is the declared
6
- * side; they meet at `FrondDescriptor.operationsOverrides`.
7
- */
1
+ /** What a frond is made of — one interface per convention directory. */
8
2
  import type { SchemaView } from '@fougere/schema';
9
3
  import type { Param, OperationContract, OperationsMap } from '../wire/operation.js';
10
4
  import type { PresenterViews } from '../prefab/presenter.js';
11
5
  import type { Fronds } from './Fronds.js';
12
6
 
13
- /**
14
- * A discovered provider — a class under `services/` or `repositories/`, injected by type.
15
- *
16
- * Which of the two directories it came from is deliberately not recorded. The scan used
17
- * to tag it `kind: 'service' | 'repository'`, a field it filled on every provider and
18
- * that **no consumer ever read** — the two directories are two spellings of the same
19
- * thing, and DI resolves by type either way.
20
- */
7
+ /** A discovered provider — a class under `services/` or `repositories/`, injected by type. */
21
8
  export interface ProviderEntry {
22
9
  /**
23
- * The class constructor (default export of the file).
10
+ * The container key — the class name as the SOURCE spells it.
24
11
  *
25
- * `never[]` and not `unknown[]`: the arguments are the CONTAINER's to supply, so the
26
- * slot must accept any constructor — and with `unknown[]` a real class is refused,
27
- * because assigning it would need `unknown` to be one of its declared parameters.
28
- * Invisible on the scan path, where the value arrives as `unknown` and is cast; the
29
- * module `fougere build` writes states the class by name, and that is where it showed.
12
+ * Read at boot off `ctor.name` for a decade of no consequence, until a bundler lowered
13
+ * a `static readonly` field and renamed the declaration doing it: the provider
14
+ * registered as `_Communes` and the handler asking for `Communes` got a container miss.
15
+ * A name a tool may rewrite is written down, for the same reason `deps` is.
30
16
  */
17
+ name?: string;
18
+ /** The class constructor (default export of the file). */
31
19
  ctor: new (...args: never[]) => unknown;
32
20
  /** Constructor dependency type names (from AST scan). */
33
21
  deps: string[];
@@ -35,6 +23,12 @@ export interface ProviderEntry {
35
23
  filePath: string;
36
24
  }
37
25
 
26
+ /**
27
+ * The key a provider answers under. What the source said, and the class's own name only
28
+ * where nobody wrote it down — a statement is read as code, and code can say it.
29
+ */
30
+ export const nameOf = (provider: ProviderEntry): string => provider.name ?? provider.ctor.name;
31
+
38
32
  /** A discovered entity (Entity subclass in entities/ dir). */
39
33
  export interface EntityEntry {
40
34
  /** Registration key: class name lowercased first char (e.g. 'product'). */
@@ -52,16 +46,8 @@ export interface HandlerEntry {
52
46
  /** Registration key (e.g. 'postHandler'). */
53
47
  name: string;
54
48
  /**
55
- * The name this handler answers to — its class name minus `Handler`, lowercased
56
- * (`PostHandler` → `post`). It is what `facadeKeyOf` builds its key from and what
57
- * travels as `FrondCall.entity` on the wire.
58
- *
59
- * **It is NOT an entity name**, and it was called `entityName` for long enough to
60
- * mislead: `toEntityName` (`scanner.ts`) strips the suffix without checking that any
61
- * entity carries the result, and the boot states the consequence — *pointing at
62
- * nothing is legal*. A health check, a search across several shapes, a pure
63
- * computation: ordinary handlers that own no row. `PresenterEntry`/`CollectorEntry`
64
- * keep `entityName` because those really do target a declared entity.
49
+ * The name this handler answers to — its class name minus `Handler`, lowercased (`PostHandler` →
50
+ * `post`).
65
51
  */
66
52
  address: string;
67
53
  /** The handler class. */
@@ -85,25 +71,11 @@ export interface PresenterFieldMeta {
85
71
  name: string;
86
72
  /** Inferred return type name: 'string', 'number', 'boolean', or a class name. */
87
73
  returnType?: string;
88
- /**
89
- * The field emits a LIST per row — `tags(posts: Post[]): string[][]`.
90
- *
91
- * The method answers one value per row, so the outer array level of its return type is
92
- * the page, not the field: what remains after removing it is the field's own arity.
93
- * Nothing measured that remainder, so a computed list and a computed scalar looked
94
- * identical and every projection announced the scalar.
95
- */
74
+ /** The field emits a LIST per row — `tags(posts: Post[]): string[][]`. */
96
75
  list?: boolean;
97
76
  /** Whether the return is nullable. */
98
77
  nullable?: boolean;
99
- /**
100
- * The declared parameters AFTER the rows. Kept raw rather than resolved: the scan
101
- * meets presenters before collectors, so the plan is computed at boot where the
102
- * collector names are known — exactly as a handler op's is.
103
- *
104
- * A computed field that declares `user?: User` is then fed by the collector
105
- * that resolves one. A presenter is not a second mechanism.
106
- */
78
+ /** The declared parameters AFTER the rows. */
107
79
  params?: Param[];
108
80
  }
109
81
 
@@ -118,10 +90,8 @@ export interface PresenterEntry {
118
90
  /** Per-field type metadata (inferred from source via parser). */
119
91
  fieldMeta: PresenterFieldMeta[];
120
92
  /**
121
- * The view each computed field emits, when the presenter declares one
122
- * (`Presenter(Order, { items: [OrderItemView] })`). Stated rather than inferred: the
123
- * parser reads a scalar off a return type and nothing more, so an object-valued field
124
- * has no derivable shape without this.
93
+ * The view each computed field emits, when the presenter declares one (`Presenter(Order, {
94
+ * items: [OrderItemView] })`).
125
95
  */
126
96
  views?: PresenterViews;
127
97
  /** Constructor dependency type names (from AST scan). */
@@ -172,18 +142,14 @@ export interface FrondDescriptor {
172
142
  presenters: PresenterEntry[];
173
143
  collectors: CollectorEntry[];
174
144
  seeds: SeedEntry[];
175
- /** Per-surface entity lists from frond.config.ts (e.g. { graphql: ['Post'], rest: ['Post', 'Author'] }). */
145
+ /**
146
+ * Per-surface entity lists from frond.config.ts (e.g. { graphql: ['Post'], rest: ['Post',
147
+ * 'Author'] }).
148
+ */
176
149
  surfaces?: Record<string, string[]>;
177
150
  /** Entities this frond may read across sources — see `FrondConfig.reads`. */
178
151
  reads?: string[];
179
- /**
180
- * Per-operation overrides from frond.config.ts. Key = operation name.
181
- *
182
- * Two depths, as declared on {@link OperationOverride}: the surface keys travel to the
183
- * transport adapters, the contract keys (`input`/`output`/`binding`) travel to the
184
- * façade — where config is the third producer of an operation's contract, alongside a
185
- * prefab's `__ops` and the scan.
186
- */
152
+ /** Per-operation overrides from frond.config.ts. */
187
153
  operationsOverrides?: Record<string, OperationContract & {
188
154
  kind?: 'query' | 'command';
189
155
  /** Class name to resolve from DI (overrides default `{Entity}Handler` lookup). */
@@ -1,4 +1,4 @@
1
- import type { InvocationContext } from '../contract/Invocation.js';
1
+ import type { InvocationContext } from '../wire/Invocation.js';
2
2
  import type { BindingPlan } from '../wire/binding.js';
3
3
 
4
4
  export interface CollectorResolver {
@@ -40,15 +40,15 @@ export class ArgumentResolver {
40
40
  }
41
41
  case 'fact': {
42
42
  // A fact IS the payload — the whole of what happened, never a piece of it.
43
- // Identical to `body` today, and deliberately not sharing its branch: the two
44
- // agree by coincidence, not by rule, and the day `body` learns to look up a
43
+ // Identical to `input` today, and deliberately not sharing its branch: the two
44
+ // agree by coincidence, not by rule, and the day `input` learns to look up a
45
45
  // value by parameter name a subscriber would receive ONE FIELD of the fact it
46
46
  // subscribed to. Splitting it costs nothing and removes that trap.
47
- args.push(ctx.body);
47
+ args.push(ctx.input);
48
48
  break;
49
49
  }
50
- case 'body': {
51
- args.push(ctx.body);
50
+ case 'input': {
51
+ args.push(ctx.input);
52
52
  break;
53
53
  }
54
54
  case 'query': {
@@ -1,5 +1,5 @@
1
- import type { Call } from '../contract/Call.js';
2
- import type { RouteKind } from '../contract/RouteAddress.js';
1
+ import type { Call } from '../wire/call.js';
2
+ import type { RouteKind } from '../wire/RouteAddress.js';
3
3
 
4
4
  export type DispatchStage = 'received' | 'resolved' | 'completed' | 'failed' | 'settled';
5
5