@fougere/core 0.6.0-alpha.0 → 0.7.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 (493) hide show
  1. package/README.md +1 -1
  2. package/dist/boot/Emissions.d.ts +13 -90
  3. package/dist/boot/Emissions.d.ts.map +1 -1
  4. package/dist/boot/Emissions.js +21 -118
  5. package/dist/boot/Emissions.js.map +1 -1
  6. package/dist/boot/ambient-port.d.ts +3 -24
  7. package/dist/boot/ambient-port.d.ts.map +1 -1
  8. package/dist/boot/ambient.als.d.ts.map +1 -1
  9. package/dist/boot/ambient.als.js +7 -12
  10. package/dist/boot/ambient.als.js.map +1 -1
  11. package/dist/boot/ambient.queue.d.ts +2 -5
  12. package/dist/boot/ambient.queue.d.ts.map +1 -1
  13. package/dist/boot/ambient.queue.js.map +1 -1
  14. package/dist/boot/apply.d.ts +1 -13
  15. package/dist/boot/apply.d.ts.map +1 -1
  16. package/dist/boot/apply.js +3 -15
  17. package/dist/boot/apply.js.map +1 -1
  18. package/dist/boot/auth.d.ts +2 -12
  19. package/dist/boot/auth.d.ts.map +1 -1
  20. package/dist/boot/boot.d.ts +3 -16
  21. package/dist/boot/boot.d.ts.map +1 -1
  22. package/dist/boot/boot.js +3 -10
  23. package/dist/boot/boot.js.map +1 -1
  24. package/dist/boot/bootstrap.d.ts.map +1 -1
  25. package/dist/boot/bootstrap.js +61 -127
  26. package/dist/boot/bootstrap.js.map +1 -1
  27. package/dist/boot/card.d.ts +1 -17
  28. package/dist/boot/card.d.ts.map +1 -1
  29. package/dist/boot/card.js +3 -32
  30. package/dist/boot/card.js.map +1 -1
  31. package/dist/boot/frame.d.ts +8 -32
  32. package/dist/boot/frame.d.ts.map +1 -1
  33. package/dist/boot/frame.js +20 -54
  34. package/dist/boot/frame.js.map +1 -1
  35. package/dist/boot/hosted.d.ts +2 -24
  36. package/dist/boot/hosted.d.ts.map +1 -1
  37. package/dist/boot/hosted.js +10 -15
  38. package/dist/boot/hosted.js.map +1 -1
  39. package/dist/boot/ownership.d.ts +3 -36
  40. package/dist/boot/ownership.d.ts.map +1 -1
  41. package/dist/boot/ownership.js +5 -40
  42. package/dist/boot/ownership.js.map +1 -1
  43. package/dist/boot/ports.d.ts +1 -14
  44. package/dist/boot/ports.d.ts.map +1 -1
  45. package/dist/boot/ports.js +1 -14
  46. package/dist/boot/ports.js.map +1 -1
  47. package/dist/boot/remote.d.ts +5 -38
  48. package/dist/boot/remote.d.ts.map +1 -1
  49. package/dist/boot/remote.js +8 -41
  50. package/dist/boot/remote.js.map +1 -1
  51. package/dist/boot/runner.d.ts +4 -21
  52. package/dist/boot/runner.d.ts.map +1 -1
  53. package/dist/boot/runner.js +4 -17
  54. package/dist/boot/runner.js.map +1 -1
  55. package/dist/boot/seed.d.ts +4 -31
  56. package/dist/boot/seed.d.ts.map +1 -1
  57. package/dist/boot/seed.js +6 -37
  58. package/dist/boot/seed.js.map +1 -1
  59. package/dist/boot/statement-drift.d.ts +2 -21
  60. package/dist/boot/statement-drift.d.ts.map +1 -1
  61. package/dist/boot/statement-drift.js +4 -9
  62. package/dist/boot/statement-drift.js.map +1 -1
  63. package/dist/boot/together.d.ts +4 -8
  64. package/dist/boot/together.d.ts.map +1 -1
  65. package/dist/boot/together.js +15 -50
  66. package/dist/boot/together.js.map +1 -1
  67. package/dist/boot/types.d.ts +28 -173
  68. package/dist/boot/types.d.ts.map +1 -1
  69. package/dist/builtin/config.d.ts +7 -0
  70. package/dist/builtin/config.d.ts.map +1 -0
  71. package/dist/builtin/config.js +15 -0
  72. package/dist/builtin/config.js.map +1 -0
  73. package/dist/{builtins → builtin}/logger.d.ts +4 -25
  74. package/dist/builtin/logger.d.ts.map +1 -0
  75. package/dist/{builtins → builtin}/logger.js +5 -32
  76. package/dist/builtin/logger.js.map +1 -0
  77. package/dist/config-loader.d.ts +9 -67
  78. package/dist/config-loader.d.ts.map +1 -1
  79. package/dist/config-loader.js +5 -18
  80. package/dist/config-loader.js.map +1 -1
  81. package/dist/contract.d.ts +13 -31
  82. package/dist/contract.d.ts.map +1 -1
  83. package/dist/contract.js +10 -26
  84. package/dist/contract.js.map +1 -1
  85. package/dist/crypto/encoding.d.ts +2 -15
  86. package/dist/crypto/encoding.d.ts.map +1 -1
  87. package/dist/crypto/encoding.js +2 -15
  88. package/dist/crypto/encoding.js.map +1 -1
  89. package/dist/crypto/node.d.ts.map +1 -1
  90. package/dist/crypto/node.js +1 -7
  91. package/dist/crypto/node.js.map +1 -1
  92. package/dist/crypto/port.d.ts +2 -18
  93. package/dist/crypto/port.d.ts.map +1 -1
  94. package/dist/crypto/port.js +1 -17
  95. package/dist/crypto/port.js.map +1 -1
  96. package/dist/crypto/webcrypto.d.ts.map +1 -1
  97. package/dist/crypto/webcrypto.js +1 -12
  98. package/dist/crypto/webcrypto.js.map +1 -1
  99. package/dist/declare.d.ts +6 -36
  100. package/dist/declare.d.ts.map +1 -1
  101. package/dist/declare.js +4 -29
  102. package/dist/declare.js.map +1 -1
  103. package/dist/define.d.ts +2 -3
  104. package/dist/define.d.ts.map +1 -1
  105. package/dist/define.js +2 -3
  106. package/dist/define.js.map +1 -1
  107. package/dist/descriptor/Fronds.d.ts +3 -28
  108. package/dist/descriptor/Fronds.d.ts.map +1 -1
  109. package/dist/descriptor/Fronds.js +6 -31
  110. package/dist/descriptor/Fronds.js.map +1 -1
  111. package/dist/descriptor/frond.d.ts +14 -63
  112. package/dist/descriptor/frond.d.ts.map +1 -1
  113. package/dist/dispatch/ArgumentResolver.d.ts +1 -1
  114. package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
  115. package/dist/dispatch/ArgumentResolver.js +5 -5
  116. package/dist/dispatch/ArgumentResolver.js.map +1 -1
  117. package/dist/dispatch/DispatchEvent.d.ts +2 -2
  118. package/dist/dispatch/DispatchEvent.d.ts.map +1 -1
  119. package/dist/dispatch/DispatchLifecycle.d.ts +1 -7
  120. package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -1
  121. package/dist/dispatch/DispatchLifecycle.js +1 -7
  122. package/dist/dispatch/DispatchLifecycle.js.map +1 -1
  123. package/dist/dispatch/DispatchPort.d.ts +1 -1
  124. package/dist/dispatch/DispatchPort.d.ts.map +1 -1
  125. package/dist/dispatch/Dispatcher.d.ts +1 -1
  126. package/dist/dispatch/Dispatcher.d.ts.map +1 -1
  127. package/dist/dispatch/Dispatcher.js +2 -2
  128. package/dist/dispatch/Dispatcher.js.map +1 -1
  129. package/dist/{boot → dispatch}/HandlerFacade.d.ts +25 -38
  130. package/dist/dispatch/HandlerFacade.d.ts.map +1 -0
  131. package/dist/{boot → dispatch}/HandlerFacade.js +65 -74
  132. package/dist/dispatch/HandlerFacade.js.map +1 -0
  133. package/dist/dispatch/LocalRoutePolicy.d.ts +1 -1
  134. package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -1
  135. package/dist/dispatch/LocalRoutePolicy.js +4 -4
  136. package/dist/dispatch/LocalRoutePolicy.js.map +1 -1
  137. package/dist/dispatch/OperationRoute.d.ts +2 -2
  138. package/dist/dispatch/OperationRoute.d.ts.map +1 -1
  139. package/dist/dispatch/OutputView.d.ts +3 -2
  140. package/dist/dispatch/OutputView.d.ts.map +1 -1
  141. package/dist/dispatch/OutputView.js +19 -1
  142. package/dist/dispatch/OutputView.js.map +1 -1
  143. package/dist/dispatch/Route.d.ts +2 -2
  144. package/dist/dispatch/Route.d.ts.map +1 -1
  145. package/dist/dispatch/RoutePolicy.d.ts +1 -1
  146. package/dist/dispatch/RoutePolicy.d.ts.map +1 -1
  147. package/dist/dispatch/RouteRegistry.d.ts +1 -1
  148. package/dist/dispatch/RouteRegistry.d.ts.map +1 -1
  149. package/dist/dispatch/RouteRegistry.js +2 -2
  150. package/dist/dispatch/RouteRegistry.js.map +1 -1
  151. package/dist/dispatch/RouteResolver.d.ts +2 -4
  152. package/dist/dispatch/RouteResolver.d.ts.map +1 -1
  153. package/dist/dispatch/StorageGuard.d.ts +8 -7
  154. package/dist/dispatch/StorageGuard.d.ts.map +1 -1
  155. package/dist/dispatch/StorageGuard.js +61 -18
  156. package/dist/dispatch/StorageGuard.js.map +1 -1
  157. package/dist/dispatch/presenterArguments.d.ts +7 -0
  158. package/dist/dispatch/presenterArguments.d.ts.map +1 -0
  159. package/dist/dispatch/presenterArguments.js +12 -0
  160. package/dist/dispatch/presenterArguments.js.map +1 -0
  161. package/dist/dispatch/remoteRoutes.d.ts +7 -0
  162. package/dist/dispatch/remoteRoutes.d.ts.map +1 -0
  163. package/dist/dispatch/{RemoteRouteResolver.js → remoteRoutes.js} +6 -10
  164. package/dist/dispatch/remoteRoutes.js.map +1 -0
  165. package/dist/dispatch/routeNotFound.d.ts +9 -0
  166. package/dist/dispatch/routeNotFound.d.ts.map +1 -0
  167. package/dist/dispatch/routeNotFound.js +21 -0
  168. package/dist/dispatch/routeNotFound.js.map +1 -0
  169. package/dist/dispatch/validateInput.d.ts +5 -0
  170. package/dist/dispatch/validateInput.d.ts.map +1 -0
  171. package/dist/dispatch/validateInput.js +20 -0
  172. package/dist/dispatch/validateInput.js.map +1 -0
  173. package/dist/effective-operation.d.ts +1 -24
  174. package/dist/effective-operation.d.ts.map +1 -1
  175. package/dist/effective-operation.js +21 -50
  176. package/dist/effective-operation.js.map +1 -1
  177. package/dist/emit.d.ts +4 -42
  178. package/dist/emit.d.ts.map +1 -1
  179. package/dist/emit.js +3 -39
  180. package/dist/emit.js.map +1 -1
  181. package/dist/entry/facade.d.ts +8 -0
  182. package/dist/entry/facade.d.ts.map +1 -0
  183. package/dist/entry/facade.js +28 -0
  184. package/dist/entry/facade.js.map +1 -0
  185. package/dist/entry/transport.d.ts +5 -0
  186. package/dist/entry/transport.d.ts.map +1 -0
  187. package/dist/entry/transport.js +11 -0
  188. package/dist/entry/transport.js.map +1 -0
  189. package/dist/frond-config.d.ts +7 -70
  190. package/dist/frond-config.d.ts.map +1 -1
  191. package/dist/frond-config.js +1 -9
  192. package/dist/frond-config.js.map +1 -1
  193. package/dist/identity-keys.d.ts +2 -5
  194. package/dist/identity-keys.d.ts.map +1 -1
  195. package/dist/identity-keys.js +3 -16
  196. package/dist/identity-keys.js.map +1 -1
  197. package/dist/identity.d.ts +4 -30
  198. package/dist/identity.d.ts.map +1 -1
  199. package/dist/identity.js +11 -73
  200. package/dist/identity.js.map +1 -1
  201. package/dist/imports.d.ts +1 -7
  202. package/dist/imports.d.ts.map +1 -1
  203. package/dist/imports.js +1 -7
  204. package/dist/imports.js.map +1 -1
  205. package/dist/index.d.ts +17 -24
  206. package/dist/index.d.ts.map +1 -1
  207. package/dist/index.js +10 -18
  208. package/dist/index.js.map +1 -1
  209. package/dist/loader.d.ts +1 -8
  210. package/dist/loader.d.ts.map +1 -1
  211. package/dist/loader.js +1 -8
  212. package/dist/loader.js.map +1 -1
  213. package/dist/node.d.ts +2 -11
  214. package/dist/node.d.ts.map +1 -1
  215. package/dist/node.js +2 -11
  216. package/dist/node.js.map +1 -1
  217. package/dist/prefab/collector.d.ts +1 -22
  218. package/dist/prefab/collector.d.ts.map +1 -1
  219. package/dist/prefab/collector.js +1 -22
  220. package/dist/prefab/collector.js.map +1 -1
  221. package/dist/prefab/crud.d.ts +16 -32
  222. package/dist/prefab/crud.d.ts.map +1 -1
  223. package/dist/prefab/crud.js +31 -58
  224. package/dist/prefab/crud.js.map +1 -1
  225. package/dist/prefab/mirror.d.ts +2 -24
  226. package/dist/prefab/mirror.d.ts.map +1 -1
  227. package/dist/prefab/mirror.js +2 -20
  228. package/dist/prefab/mirror.js.map +1 -1
  229. package/dist/prefab/prefab.d.ts +1 -7
  230. package/dist/prefab/prefab.d.ts.map +1 -1
  231. package/dist/prefab/prefab.js +1 -7
  232. package/dist/prefab/prefab.js.map +1 -1
  233. package/dist/prefab/presenter.d.ts +2 -36
  234. package/dist/prefab/presenter.d.ts.map +1 -1
  235. package/dist/prefab/presenter.js +2 -36
  236. package/dist/prefab/presenter.js.map +1 -1
  237. package/dist/prefab/repository.d.ts +5 -73
  238. package/dist/prefab/repository.d.ts.map +1 -1
  239. package/dist/prefab/repository.js +3 -16
  240. package/dist/prefab/repository.js.map +1 -1
  241. package/dist/scan/adapters.d.ts +3 -0
  242. package/dist/scan/adapters.d.ts.map +1 -0
  243. package/dist/scan/adapters.js +25 -0
  244. package/dist/scan/adapters.js.map +1 -0
  245. package/dist/scan/bundling.d.ts +1 -12
  246. package/dist/scan/bundling.d.ts.map +1 -1
  247. package/dist/scan/bundling.js +1 -12
  248. package/dist/scan/bundling.js.map +1 -1
  249. package/dist/scan/conventions.d.ts +6 -40
  250. package/dist/scan/conventions.d.ts.map +1 -1
  251. package/dist/scan/conventions.js +5 -34
  252. package/dist/scan/conventions.js.map +1 -1
  253. package/dist/scan/emit.d.ts +1 -5
  254. package/dist/scan/emit.d.ts.map +1 -1
  255. package/dist/scan/emit.js +4 -38
  256. package/dist/scan/emit.js.map +1 -1
  257. package/dist/scan/handler-parser.d.ts +4 -26
  258. package/dist/scan/handler-parser.d.ts.map +1 -1
  259. package/dist/scan/handler-parser.js +26 -83
  260. package/dist/scan/handler-parser.js.map +1 -1
  261. package/dist/scan/result.d.ts +3 -16
  262. package/dist/scan/result.d.ts.map +1 -1
  263. package/dist/scan/scanner.d.ts +2 -27
  264. package/dist/scan/scanner.d.ts.map +1 -1
  265. package/dist/scan/scanner.js +28 -127
  266. package/dist/scan/scanner.js.map +1 -1
  267. package/dist/scan/statement.d.ts.map +1 -1
  268. package/dist/scan/statement.js +4 -30
  269. package/dist/scan/statement.js.map +1 -1
  270. package/dist/source.d.ts +41 -0
  271. package/dist/source.d.ts.map +1 -0
  272. package/dist/source.js +10 -0
  273. package/dist/source.js.map +1 -0
  274. package/dist/storage.d.ts +13 -210
  275. package/dist/storage.d.ts.map +1 -1
  276. package/dist/storage.js +4 -68
  277. package/dist/storage.js.map +1 -1
  278. package/dist/store.d.ts +18 -0
  279. package/dist/store.d.ts.map +1 -0
  280. package/dist/store.js +146 -0
  281. package/dist/store.js.map +1 -0
  282. package/dist/verify.d.ts +5 -38
  283. package/dist/verify.d.ts.map +1 -1
  284. package/dist/verify.js +17 -37
  285. package/dist/verify.js.map +1 -1
  286. package/dist/wire/CallLog.d.ts +32 -0
  287. package/dist/wire/CallLog.d.ts.map +1 -0
  288. package/dist/{contract → wire}/CallLog.js.map +1 -1
  289. package/dist/wire/Invocation.d.ts +32 -0
  290. package/dist/wire/Invocation.d.ts.map +1 -0
  291. package/dist/wire/Invocation.js +66 -0
  292. package/dist/wire/Invocation.js.map +1 -0
  293. package/dist/{contract → wire}/RouteAddress.d.ts +5 -0
  294. package/dist/wire/RouteAddress.d.ts.map +1 -0
  295. package/dist/{contract → wire}/RouteAddress.js +7 -0
  296. package/dist/wire/RouteAddress.js.map +1 -0
  297. package/dist/wire/binding.d.ts +5 -21
  298. package/dist/wire/binding.d.ts.map +1 -1
  299. package/dist/wire/binding.js +5 -10
  300. package/dist/wire/binding.js.map +1 -1
  301. package/dist/wire/call.d.ts +24 -133
  302. package/dist/wire/call.d.ts.map +1 -1
  303. package/dist/wire/call.js +15 -41
  304. package/dist/wire/call.js.map +1 -1
  305. package/dist/wire/drift.d.ts +3 -28
  306. package/dist/wire/drift.d.ts.map +1 -1
  307. package/dist/wire/drift.js +4 -23
  308. package/dist/wire/drift.js.map +1 -1
  309. package/dist/wire/errors.d.ts +4 -24
  310. package/dist/wire/errors.d.ts.map +1 -1
  311. package/dist/wire/errors.js +4 -24
  312. package/dist/wire/errors.js.map +1 -1
  313. package/dist/wire/http-error.d.ts +2 -13
  314. package/dist/wire/http-error.d.ts.map +1 -1
  315. package/dist/wire/http-error.js +5 -19
  316. package/dist/wire/http-error.js.map +1 -1
  317. package/dist/wire/loggerMiddleware.d.ts +2 -8
  318. package/dist/wire/loggerMiddleware.d.ts.map +1 -1
  319. package/dist/wire/loggerMiddleware.js +1 -7
  320. package/dist/wire/loggerMiddleware.js.map +1 -1
  321. package/dist/wire/middleware.d.ts +3 -7
  322. package/dist/wire/middleware.d.ts.map +1 -1
  323. package/dist/wire/middleware.js +1 -5
  324. package/dist/wire/middleware.js.map +1 -1
  325. package/dist/wire/operation.d.ts +7 -43
  326. package/dist/wire/operation.d.ts.map +1 -1
  327. package/dist/wire/operation.js +4 -15
  328. package/dist/wire/operation.js.map +1 -1
  329. package/dist/wire/signature.d.ts +4 -25
  330. package/dist/wire/signature.d.ts.map +1 -1
  331. package/package.json +3 -3
  332. package/src/boot/Emissions.ts +21 -118
  333. package/src/boot/ambient-port.ts +3 -24
  334. package/src/boot/ambient.als.ts +7 -12
  335. package/src/boot/ambient.queue.ts +2 -5
  336. package/src/boot/apply.ts +3 -15
  337. package/src/boot/auth.ts +2 -12
  338. package/src/boot/boot.ts +5 -20
  339. package/src/boot/bootstrap.ts +69 -136
  340. package/src/boot/card.ts +4 -33
  341. package/src/boot/frame.ts +28 -62
  342. package/src/boot/hosted.ts +12 -34
  343. package/src/boot/ownership.ts +5 -39
  344. package/src/boot/ports.ts +1 -14
  345. package/src/boot/remote.ts +11 -58
  346. package/src/boot/runner.ts +5 -22
  347. package/src/boot/seed.ts +6 -37
  348. package/src/boot/statement-drift.ts +5 -24
  349. package/src/boot/together.ts +18 -51
  350. package/src/boot/types.ts +28 -173
  351. package/src/{builtins → builtin}/config.ts +1 -7
  352. package/src/{builtins → builtin}/logger.ts +6 -39
  353. package/src/config-loader.ts +12 -71
  354. package/src/contract.ts +15 -39
  355. package/src/crypto/encoding.ts +2 -15
  356. package/src/crypto/node.ts +1 -7
  357. package/src/crypto/port.ts +2 -18
  358. package/src/crypto/webcrypto.ts +1 -12
  359. package/src/declare.ts +8 -39
  360. package/src/define.ts +2 -3
  361. package/src/descriptor/Fronds.ts +6 -31
  362. package/src/descriptor/frond.ts +14 -63
  363. package/src/dispatch/ArgumentResolver.ts +6 -6
  364. package/src/dispatch/DispatchEvent.ts +2 -2
  365. package/src/dispatch/DispatchLifecycle.ts +1 -7
  366. package/src/dispatch/DispatchPort.ts +1 -1
  367. package/src/dispatch/Dispatcher.ts +3 -3
  368. package/src/dispatch/HandlerFacade.ts +231 -0
  369. package/src/dispatch/LocalRoutePolicy.ts +4 -4
  370. package/src/dispatch/OperationRoute.ts +2 -2
  371. package/src/dispatch/OutputView.ts +24 -2
  372. package/src/dispatch/Route.ts +2 -2
  373. package/src/dispatch/RoutePolicy.ts +1 -1
  374. package/src/dispatch/RouteRegistry.ts +2 -2
  375. package/src/dispatch/RouteResolver.ts +2 -4
  376. package/src/dispatch/StorageGuard.ts +70 -18
  377. package/src/dispatch/presenterArguments.ts +25 -0
  378. package/src/dispatch/{RemoteRouteResolver.ts → remoteRoutes.ts} +7 -9
  379. package/src/dispatch/routeNotFound.ts +33 -0
  380. package/src/dispatch/validateInput.ts +28 -0
  381. package/src/effective-operation.ts +21 -50
  382. package/src/emit.ts +5 -63
  383. package/src/entry/facade.ts +44 -0
  384. package/src/entry/transport.ts +16 -0
  385. package/src/frond-config.ts +7 -70
  386. package/src/identity-keys.ts +3 -16
  387. package/src/identity.ts +12 -80
  388. package/src/imports.ts +2 -31
  389. package/src/index.ts +17 -24
  390. package/src/loader.ts +2 -16
  391. package/src/node.ts +2 -11
  392. package/src/prefab/collector.ts +1 -22
  393. package/src/prefab/crud.ts +37 -76
  394. package/src/prefab/mirror.ts +4 -44
  395. package/src/prefab/prefab.ts +2 -21
  396. package/src/prefab/presenter.ts +2 -36
  397. package/src/prefab/repository.ts +7 -83
  398. package/src/scan/adapters.ts +32 -0
  399. package/src/scan/bundling.ts +1 -12
  400. package/src/scan/conventions.ts +6 -40
  401. package/src/scan/emit.ts +4 -38
  402. package/src/scan/handler-parser.ts +27 -96
  403. package/src/scan/result.ts +3 -16
  404. package/src/scan/scanner.ts +27 -126
  405. package/src/scan/statement.ts +4 -30
  406. package/src/source.ts +44 -0
  407. package/src/storage.ts +14 -234
  408. package/src/store.ts +152 -0
  409. package/src/verify.ts +16 -57
  410. package/src/wire/CallLog.ts +30 -0
  411. package/src/{contract → wire}/Invocation.ts +24 -17
  412. package/src/{contract → wire}/RouteAddress.ts +7 -0
  413. package/src/wire/binding.ts +9 -25
  414. package/src/wire/call.ts +30 -133
  415. package/src/wire/drift.ts +5 -30
  416. package/src/wire/errors.ts +4 -24
  417. package/src/wire/http-error.ts +5 -19
  418. package/src/wire/loggerMiddleware.ts +2 -8
  419. package/src/wire/middleware.ts +3 -7
  420. package/src/wire/operation.ts +8 -48
  421. package/src/wire/signature.ts +4 -25
  422. package/dist/boot/HandlerFacade.d.ts.map +0 -1
  423. package/dist/boot/HandlerFacade.js.map +0 -1
  424. package/dist/builtins/config.d.ts +0 -13
  425. package/dist/builtins/config.d.ts.map +0 -1
  426. package/dist/builtins/config.js +0 -21
  427. package/dist/builtins/config.js.map +0 -1
  428. package/dist/builtins/logger.d.ts.map +0 -1
  429. package/dist/builtins/logger.js.map +0 -1
  430. package/dist/contract/Call.d.ts +0 -10
  431. package/dist/contract/Call.d.ts.map +0 -1
  432. package/dist/contract/Call.js +0 -15
  433. package/dist/contract/Call.js.map +0 -1
  434. package/dist/contract/CallLog.d.ts +0 -57
  435. package/dist/contract/CallLog.d.ts.map +0 -1
  436. package/dist/contract/Invocation.d.ts +0 -27
  437. package/dist/contract/Invocation.d.ts.map +0 -1
  438. package/dist/contract/Invocation.js +0 -59
  439. package/dist/contract/Invocation.js.map +0 -1
  440. package/dist/contract/RouteAddress.d.ts.map +0 -1
  441. package/dist/contract/RouteAddress.js.map +0 -1
  442. package/dist/dispatch/InputValidator.d.ts +0 -7
  443. package/dist/dispatch/InputValidator.d.ts.map +0 -1
  444. package/dist/dispatch/InputValidator.js +0 -22
  445. package/dist/dispatch/InputValidator.js.map +0 -1
  446. package/dist/dispatch/OperationExecutor.d.ts +0 -25
  447. package/dist/dispatch/OperationExecutor.d.ts.map +0 -1
  448. package/dist/dispatch/OperationExecutor.js +0 -32
  449. package/dist/dispatch/OperationExecutor.js.map +0 -1
  450. package/dist/dispatch/OutputProjector.d.ts +0 -12
  451. package/dist/dispatch/OutputProjector.d.ts.map +0 -1
  452. package/dist/dispatch/OutputProjector.js +0 -30
  453. package/dist/dispatch/OutputProjector.js.map +0 -1
  454. package/dist/dispatch/PresenterArgumentResolver.d.ts +0 -12
  455. package/dist/dispatch/PresenterArgumentResolver.d.ts.map +0 -1
  456. package/dist/dispatch/PresenterArgumentResolver.js +0 -20
  457. package/dist/dispatch/PresenterArgumentResolver.js.map +0 -1
  458. package/dist/dispatch/RemoteRouteResolver.d.ts +0 -13
  459. package/dist/dispatch/RemoteRouteResolver.d.ts.map +0 -1
  460. package/dist/dispatch/RemoteRouteResolver.js.map +0 -1
  461. package/dist/dispatch/RouteNotFoundError.d.ts +0 -10
  462. package/dist/dispatch/RouteNotFoundError.d.ts.map +0 -1
  463. package/dist/dispatch/RouteNotFoundError.js +0 -24
  464. package/dist/dispatch/RouteNotFoundError.js.map +0 -1
  465. package/dist/entry/DynamicFacade.d.ts +0 -10
  466. package/dist/entry/DynamicFacade.d.ts.map +0 -1
  467. package/dist/entry/DynamicFacade.js +0 -27
  468. package/dist/entry/DynamicFacade.js.map +0 -1
  469. package/dist/entry/FacadeEntry.d.ts +0 -11
  470. package/dist/entry/FacadeEntry.d.ts.map +0 -1
  471. package/dist/entry/FacadeEntry.js +0 -26
  472. package/dist/entry/FacadeEntry.js.map +0 -1
  473. package/dist/entry/TransportEntry.d.ts +0 -13
  474. package/dist/entry/TransportEntry.d.ts.map +0 -1
  475. package/dist/entry/TransportEntry.js +0 -24
  476. package/dist/entry/TransportEntry.js.map +0 -1
  477. package/dist/rows.d.ts +0 -40
  478. package/dist/rows.d.ts.map +0 -1
  479. package/dist/rows.js +0 -146
  480. package/dist/rows.js.map +0 -1
  481. package/src/boot/HandlerFacade.ts +0 -242
  482. package/src/contract/Call.ts +0 -18
  483. package/src/contract/CallLog.ts +0 -55
  484. package/src/dispatch/InputValidator.ts +0 -28
  485. package/src/dispatch/OperationExecutor.ts +0 -60
  486. package/src/dispatch/OutputProjector.ts +0 -32
  487. package/src/dispatch/PresenterArgumentResolver.ts +0 -25
  488. package/src/dispatch/RouteNotFoundError.ts +0 -29
  489. package/src/entry/DynamicFacade.ts +0 -28
  490. package/src/entry/FacadeEntry.ts +0 -32
  491. package/src/entry/TransportEntry.ts +0 -30
  492. package/src/rows.ts +0 -155
  493. /package/dist/{contract → wire}/CallLog.js +0 -0
package/src/index.ts CHANGED
@@ -1,16 +1,7 @@
1
- /**
2
- * What a consumer writes, and nothing else.
3
- *
4
- * `exports` publishes this barrel and `./contract`, so an import that is not here
5
- * cannot be reached from outside the package at all — which is what makes this file
6
- * the contract rather than a convenience. The machinery the boot uses to keep its own
7
- * promises stays inside: container keys, the binding plan, the mixin's runtime
8
- * accessors, the config merge. Measured on 2026-08-16, none of them had a single
9
- * importer anywhere in the workspace.
10
- */
1
+ /** What a consumer writes, and nothing else. */
11
2
  export { createApp } from './boot/bootstrap.js';
12
3
  export { orderSeeds, runSeeds, seeding } from './boot/seed.js';
13
- export { AppLifecycle, AppLifecycle as Lifecycle, migrating } from './boot/AppLifecycle.js';
4
+ export { AppLifecycle, migrating } from './boot/AppLifecycle.js';
14
5
  export type { Extension } from './boot/AppLifecycle.js';
15
6
  export { defineFougere } from './define.js';
16
7
  export type { AdapterConfig, FougereConfig } from './config-loader.js';
@@ -24,17 +15,17 @@ export { Presenter } from './prefab/presenter.js';
24
15
  export type { PresenterViews } from './prefab/presenter.js';
25
16
  export { Collector } from './prefab/collector.js';
26
17
  export { Repository, type RepositoryOf, type RepositoryConstructor, type AggregateOf, type AggregateConstructor } from './prefab/repository.js';
27
- export { Invocation, canonicalInvocation, EMPTY_INVOCATION } from './contract/Invocation.js';
28
- export type { InvocationContext, InvocationInput } from './contract/Invocation.js';
29
- export { Call } from './contract/Call.js';
30
- export { RouteAddress } from './contract/RouteAddress.js';
31
- export type { RouteAddressInput } from './contract/RouteAddress.js';
18
+ export { Invocation, canonicalInvocation, EMPTY_INVOCATION } from './wire/Invocation.js';
19
+ export type { InvocationContext, PartialInvocation } from './wire/Invocation.js';
20
+ export { Call } from './wire/call.js';
21
+ export { RouteAddress } from './wire/RouteAddress.js';
22
+ export type { RouteAddressInput } from './wire/RouteAddress.js';
32
23
  export { DispatchLifecycle } from './dispatch/DispatchLifecycle.js';
33
24
  export { Dispatcher } from './dispatch/Dispatcher.js';
34
25
  // The class and not only its type: an observer RECEIVES these, so a package that folds
35
26
  // them — or a test of one — has to be able to make one through the door.
36
27
  export { DispatchEvent } from './dispatch/DispatchEvent.js';
37
- export type { CallPage, CallRecord } from './contract/CallLog.js';
28
+ export type { CallPage, CallRecord } from './wire/CallLog.js';
38
29
  export { driftOf, agrees, explain, type CardDrift } from './wire/drift.js';
39
30
  export type { DispatchObserver } from './dispatch/DispatchEvent.js';
40
31
  export type { DispatchPort } from './dispatch/DispatchPort.js';
@@ -87,15 +78,17 @@ export { callValueOf } from './contract.js';
87
78
  export type { CallValue } from './contract.js';
88
79
  export { toHttpError, toPublicError } from './wire/http-error.js';
89
80
  export { loggerMiddleware } from './wire/loggerMiddleware.js';
90
- export { Logger, setLogLevel, logLevel, envLevel, onLog } from './builtins/logger.js';
91
- export type { LogLevel, LogRecord, LogSink } from './builtins/logger.js';
81
+ export { Logger, setLogLevel, logLevel, envLevel, onLog } from './builtin/logger.js';
82
+ export type { LogLevel, LogRecord, LogSink } from './builtin/logger.js';
92
83
  // What a re-read config changes in a running process — and what it cannot.
93
84
  export { applyConfig, type ConfigApplication } from './boot/apply.js';
94
- export { Config } from './builtins/config.js';
95
- export type { Storage, StorageFactory, Source, SourceConfig, SourceView, ListOptions, ListResult, Together } from './storage.js';
96
- export { Sources, togetherKeyOf, membersOfTogetherKey } from './storage.js';
97
- export { storageOver } from './rows.js';
98
- export type { Rows, Row } from './rows.js';
85
+ export { Config } from './builtin/config.js';
86
+ export type { Storage, StorageFactory, ListOptions, ListResult, Together } from './storage.js';
87
+ export { togetherKeyOf, membersOfTogetherKey } from './storage.js';
88
+ export type { Source, SourceConfig, SourceView } from './source.js';
89
+ export { Sources } from './source.js';
90
+ export { storageOver } from './store.js';
91
+ export type { Store, Values } from './store.js';
99
92
  export type { App, CreateAppOptions } from './boot/types.js';
100
93
  export type { ScanResult, ScanDiagnostic } from './scan/result.js';
101
94
  export type {
package/src/loader.ts CHANGED
@@ -1,21 +1,7 @@
1
- /**
2
- * How a source file becomes a module — one registry, two readers.
3
- *
4
- * The scanner loads fronds and `config-loader` loads a config, and both must use the
5
- * loader the host installed: a TS file needs jiti under Nuxt and plain `import` under
6
- * tsx. It lived in `scan/scanner.ts`, so reading a config dragged the scanner, its AST
7
- * parser and the TypeScript compiler behind it.
8
- */
1
+ /** How a source file becomes a module — one registry, two readers. */
9
2
  import { pathToFileURL } from 'node:url';
10
3
 
11
- /**
12
- * Module loader — can be swapped (e.g. jiti for TS files in Nuxt context).
13
- *
14
- * `fresh` asks for a file that may have changed since it was last read. Every loader
15
- * caches, so without it a second read of an EDITED file hands back the first one —
16
- * which is what re-reading a config is for. A loader that cannot honour it may ignore
17
- * the flag; it then answers with what it already had.
18
- */
4
+ /** Module loader — can be swapped (e.g. */
19
5
  export type ModuleLoader = (
20
6
  filePath: string,
21
7
  options?: { fresh?: boolean },
package/src/node.ts CHANGED
@@ -1,14 +1,4 @@
1
- /**
2
- * What Fougere does with a filesystem — the half of core that a Worker cannot run.
3
- *
4
- * The line is not "build vs runtime": `boot()` and `loadConfig` run in production, on a
5
- * server, every time. It is whether the thing reaches for a disk. Everything here does,
6
- * transitively, and nothing on the main entry does — which is what lets a bundler for a
7
- * runtime without `node:fs` trace the main entry and find no builtin at all.
8
- *
9
- * The third entry, `@fougere/core/contract`, answers a different question: what crosses a
10
- * process boundary. A foreign frond reads it without reading our boot.
11
- */
1
+ /** What Fougere does with a filesystem — the half of core that a Worker cannot run. */
12
2
  export { boot } from './boot/boot.js';
13
3
 
14
4
  export { scanProject, frondAliases, watchPathsOf } from './scan/scanner.js';
@@ -23,6 +13,7 @@ export { setModuleLoader, getModuleLoader } from './loader.js';
23
13
  export { loadConfig, loadCascadedConfig } from './config-loader.js';
24
14
  export { defineFrond } from './frond-config.js';
25
15
  export { crossFrondImports } from './imports.js';
16
+ export { adaptersOf } from './scan/adapters.js';
26
17
 
27
18
  // Making a key and binding a name to it happen once, at a deployment, on a machine with
28
19
  // a filesystem — the CLI speaking. Verifying happens per call, everywhere, and stays on
@@ -1,25 +1,4 @@
1
- /**
2
- * Collector(Type) — resolves one handler input parameter from the invocation context.
3
- *
4
- * The target is a NAME matched against the parameter's type, never a schema: nothing
5
- * here nor in the scan reads its fields. So `Ability`, built per call from state, sits
6
- * beside `User`, loaded from a row.
7
- *
8
- * The dual of Presenter only in direction. A presenter's subject is a ROW — it adds
9
- * computed fields to one, so its target must be an entity. A collector's subject is a
10
- * PARAMETER.
11
- *
12
- * Usage:
13
- * ```ts
14
- * export default class UserCollector extends Collector(User) {
15
- * constructor(private userStorage: UserStorage) { super(); }
16
- *
17
- * async collect(ctx: InvocationContext) {
18
- * return this.userStorage.findById(ctx.state.userId as string);
19
- * }
20
- * }
21
- * ```
22
- */
1
+ /** Collector(Type) — resolves one handler input parameter from the invocation context. */
23
2
 
24
3
  import { upperFirst } from '@fougere/schema';
25
4
 
@@ -1,48 +1,42 @@
1
+ import { lowerFirst, type EntityConstructor, type SchemaView } from '@fougere/schema';
1
2
  import type { Storage, ListOptions, ListResult } from '../storage.js';
2
3
  import type { OperationContract } from '../wire/operation.js';
3
- import type { EntityConstructor, SchemaView } from '@fougere/schema';
4
+ import { targetOf } from './prefab.js';
4
5
 
5
- /** The id of the row an op acts on — a route segment, or a query fallback. */
6
- const byId = { name: 'id', source: { kind: 'param' as const, name: 'id' }, optional: false };
7
- const fromBody = { name: 'input', source: { kind: 'body' as const }, optional: false };
6
+ /**
7
+ * So a class is recognized by what it ANSWERS, since the mixin leaves no other trace.
8
+ * FR : pour qu'une classe se reconnaisse à ce qu'elle répond, le mixin ne laissant rien d'autre.
9
+ * `inheritsCrud(class PostHandler extends Crud(Post) {})` → `true`
10
+ */
11
+ export function inheritsCrud(ctor: unknown): boolean {
12
+ const proto = (ctor as { prototype?: Record<string, unknown> } | undefined)?.prototype;
13
+
14
+ return typeof proto?.list === 'function' && typeof proto?.findById === 'function';
15
+ }
8
16
 
9
17
  /**
10
- * The same five, written as the scan would have written them.
11
- *
12
- * `binding` says WHERE an argument is read from; it never says of what type, and a
13
- * GraphQL argument needs the type. So a producer that fills only `binding` leaves
14
- * `adapter/graphql` with nothing to declare — it drops the op (`registerOperations`,
15
- * `if (!sig) continue`) and four of the five CRUD ops vanish from the schema while
16
- * the façade and REST still serve them. Measured on an installed app: 16 handlers,
17
- * 14 with unresolvable heritage, zero `createX` in the schema.
18
+ * So storage follows the shape the handler was built on, which may differ from its address.
19
+ * FR : pour que le stockage suive la forme sur laquelle le handler est bâti.
20
+ * `subjectOf(class Draft extends Crud(Post) {}, 'draft')` `'post'`
18
21
  */
22
+ export function subjectOf(ctor: unknown, address: string): string {
23
+ const target = targetOf(ctor);
24
+
25
+ return target?.name ? lowerFirst(target.name) : address;
26
+ }
27
+
28
+ /** The id of the row an op acts on — a route segment, or a query fallback. */
29
+ const byId = { name: 'id', source: { kind: 'param' as const, name: 'id' }, optional: false };
30
+ const fromBody = { name: 'input', source: { kind: 'input' as const }, optional: false };
31
+
32
+ /** The same five, written as the scan would have written them. */
19
33
  const idParam = { name: 'id', type: { raw: 'string', name: 'string' } };
20
34
  const inputParam = (entity: string) => ({ name: 'input', type: { raw: `Partial<${entity}>`, name: entity } });
21
35
  const returns = (raw: string, name: string, extra?: { array?: boolean; nullable?: boolean }) =>
22
36
  ({ raw, name, ...extra });
23
37
 
24
- /**
25
- * The five ops a Crud handler brings, declared rather than discovered.
26
- *
27
- * The mixin built them, so it alone knows their contract in full: what judges
28
- * their input, where each argument comes from. It says so on the class, at
29
- * runtime — which is what makes the guarantee independent of the AST scan (an
30
- * installed app cannot resolve this file, and never needs to).
31
- */
32
- /**
33
- * `output` says the entity, and saying it costs nothing at runtime.
34
- *
35
- * The façade already projected onto the entity when nothing else was named, so this
36
- * changes no result: `outputFieldsFor` reads `contractOutput` and falls back to the
37
- * entity, and both are the same shape here. What changes is that the sentence now
38
- * EXISTS — the identity card publishes `output` per op, and a card was measured
39
- * carrying none at all (2026-08-06, ten ops, zero outputs), which typed every remote
40
- * return as `unknown` for anyone building on it.
41
- *
42
- * It does not close the view: only an explicit `__opOutputs` does (`closed: perOp !==
43
- * undefined`), so a named view still wins and a presenter's computed fields still ride
44
- * out. `delete` names none — a boolean is not a shape.
45
- */
38
+ /** The five ops a Crud handler brings, declared rather than discovered. */
39
+ /** `output` says the entity, and saying it costs nothing at runtime. */
46
40
  function crudOps(entity: SchemaView & { partial?: () => SchemaView }): Record<string, OperationContract> {
47
41
  const name = (entity as { name?: string }).name ?? 'Entity';
48
42
  const input = inputParam(name);
@@ -76,15 +70,7 @@ function crudOps(entity: SchemaView & { partial?: () => SchemaView }): Record<st
76
70
  };
77
71
  }
78
72
 
79
- /**
80
- * The mixin's single "trust me" point — the twin of `asSchemaConstructor` in @fougere/schema.
81
- *
82
- * The implementation returns whatever the storage hands back; the declaration names the view
83
- * each op emits at the port. TypeScript cannot connect the two (the view is a runtime
84
- * argument, the type is a generic), so one assertion states that the mixin honours what it
85
- * declared — and the façade makes it true, projecting each op's result onto its view
86
- * (`outputFieldsFor` in `bootstrap.ts`).
87
- */
73
+ /** The mixin's single "trust me" point — the twin of `asSchemaConstructor` in @fougere/schema. */
88
74
  function asCrudConstructor<T, V>(impl: object): CrudConstructor<T, V> {
89
75
  return impl as CrudConstructor<T, V>;
90
76
  }
@@ -95,12 +81,7 @@ export type CrudOpName = 'list' | 'findById' | 'create' | 'update' | 'delete';
95
81
  /** Which view each op speaks — omitted ops speak the entity, the trivial view. */
96
82
  export type CrudViews = Partial<Record<CrudOpName, EntityConstructor>>;
97
83
 
98
- /**
99
- * The view an op emits, fabricated: the one declared for it, the single view when the
100
- * whole handler declares one, the entity otherwise. `PostCard` is not a hand-written
101
- * type — `Post.pick(...)` derives it field by field, so an op's return is a projection
102
- * of the entity exactly like the entity is the projection that keeps everything.
103
- */
84
+ /** The view an op emits, fabricated. */
104
85
  type OutOf<V, K extends CrudOpName, T> =
105
86
  // Bracketed on purpose: a naked `V extends …` DISTRIBUTES, and the no-view default
106
87
  // is the empty map, whose `keyof` is `never` — distribution would then collapse
@@ -109,17 +90,7 @@ type OutOf<V, K extends CrudOpName, T> =
109
90
  : K extends keyof V ? (V[K] extends EntityConstructor ? InstanceType<V[K]> : T)
110
91
  : T;
111
92
 
112
- /**
113
- * The five ops, typed from the entity and its views.
114
- *
115
- * Two things the mixin declares but does not own. The **output** is the view the
116
- * handler names (`Crud(Post, { list: PostCard })`) — fabricated, so a redefinition
117
- * that returns cards stays assignable. The **trailing parameters** are resolved by
118
- * type from the container (`delete(id, user?: User)` gets its user from a
119
- * collector): the mixin cannot know them, they belong to the app, so it declares that
120
- * a tail exists and that it supplies none — which is what `never` says, and what keeps
121
- * a judged redefinition assignable.
122
- */
93
+ /** The five ops, typed from the entity and its views. */
123
94
  export interface CrudOps<T, V = {}> {
124
95
  storage: Storage<T>;
125
96
  list(options?: ListOptions, ...collected: never[]): Promise<ListResult<OutOf<V, 'list', T>>>;
@@ -141,20 +112,7 @@ export interface CrudConstructor<T, V = {}> {
141
112
  readonly __ops: Record<string, OperationContract>;
142
113
  }
143
114
 
144
- /**
145
- * Mixin — extends Crud(Entity) to get all 5 typed CRUD methods.
146
- *
147
- * The second argument (optional) names the view the ops emit, and comes in two
148
- * spellings of one idea — a view per op, or one view for all five:
149
- *
150
- * Crud(Post) → every op emits Post
151
- * Crud(Post, { list: PostCard }) → list emits cards, the rest emit Post. Declaration
152
- * only: the handler keeps its full-row storage, so a
153
- * judge can still read `body`.
154
- * Crud(Post, PostPublic) → every op emits PostPublic, and the bootstrap
155
- * scopes the injected storage via .output(PostPublic) —
156
- * the whole handler speaks the restricted view.
157
- */
115
+ /** Mixin — extends Crud(Entity) to get all 5 typed CRUD methods. */
158
116
  export function Crud<E extends EntityConstructor, V extends CrudViews | EntityConstructor = {}>(
159
117
  entity: E,
160
118
  output?: V,
@@ -168,10 +126,13 @@ export function Crud<E extends EntityConstructor, V extends CrudViews | EntityCo
168
126
 
169
127
  return asCrudConstructor<T, V>(class CrudHandler {
170
128
  static __entity = entity;
171
- /** Handler-wide view only — a per-op map must NOT scope the storage the judges read. */
129
+ /** Handler-wide view only — a per-op map must NOT scope the storage the validators read. */
172
130
  static __output = wholeHandler ?? entity;
173
131
  static __opOutputs = perOp;
174
- /** What this prefab handler declares — read by the façade, merged under the author's own methods. */
132
+ /**
133
+ * What this prefab handler declares — read by the façade, merged under the author's own
134
+ * methods.
135
+ */
175
136
  static __ops: Record<string, OperationContract> = crudOps(entity as unknown as SchemaView & { partial?: () => SchemaView });
176
137
 
177
138
  storage: Storage<T>;
@@ -1,32 +1,10 @@
1
- import { FieldSet, Lifecycle, type EntityConstructor, type Fields, type ValidationResult } from '@fougere/schema';
1
+ import { Lifecycle, type EntityConstructor, type Fields } from '@fougere/schema';
2
2
  import type { Storage } from '../storage.js';
3
3
 
4
- /**
5
- * A paginated local copy of a source that cannot be queried directly.
6
- *
7
- * The shape must contain an `updated()` field used as a high-water mark. Subclasses
8
- * implement `pull`; `refresh` validates and upserts each returned page.
9
- *
10
- * ```ts
11
- * export default class PartnerCatalog extends Mirror(BookCard) {
12
- * constructor(storage: Storage<BookCard>, private catalog: Facade<CatalogHandler>) {
13
- * super(storage);
14
- * }
15
- *
16
- * async *pull(since?: Date) {
17
- * for (let page = 0; page !== null;) {
18
- * const body = await fetch(`${api}?page=${page}&since=${since?.toISOString() ?? ''}`);
19
- * const { items, next } = await body.json();
20
- * yield items.map(toCard);
21
- * page = next;
22
- * }
23
- * }
24
- * }
25
- * ```
26
- */
4
+ /** A paginated local copy of a source that cannot be queried directly. */
27
5
  /** What one refresh did — enough to log it, and to decide whether to run again. */
28
6
  export interface Refreshed {
29
- /** Rows written, counting a replaced row once. */
7
+ /** Instances written, counting a replaced one once. */
30
8
  written: number;
31
9
  /** The age the pull was asked to start from — absent on the first ever run. */
32
10
  since?: Date;
@@ -84,7 +62,7 @@ export function Mirror<E extends EntityConstructor>(shape: E): MirrorConstructor
84
62
  // Preserve the source's page boundaries: one page becomes one upsert.
85
63
  for await (const page of this.pull(since)) {
86
64
  if (page.length === 0) continue;
87
- written += await this.storage.upsertAll(judgePage(shape, page) as Partial<T>[]);
65
+ written += await this.storage.upsertAll(page);
88
66
  }
89
67
  return { written, since, ms: Date.now() - started };
90
68
  }
@@ -102,21 +80,3 @@ export function ageFieldOf(shape: unknown): string | undefined {
102
80
  }
103
81
  return undefined;
104
82
  }
105
-
106
- /** Validate and decode a page, naming a refused row by its declared primary field. */
107
- function judgePage<T>(shape: unknown, page: Partial<T>[]): Record<string, unknown>[] {
108
- const judge = (shape as { validate?: (input: unknown) => ValidationResult<unknown> }).validate;
109
- if (typeof judge !== 'function') return page as Record<string, unknown>[];
110
-
111
- const name = (shape as { name?: string }).name ?? 'mirror';
112
- const fields = (shape as { getFields?: () => Fields }).getFields?.();
113
- const primary = fields ? FieldSet.of(fields).primary : undefined;
114
- return page.map((row, index) => {
115
- const verdict = judge.call(shape, row);
116
- if (verdict.success) return verdict.data as Record<string, unknown>;
117
- const key = primary === undefined ? undefined : (row as Record<string, unknown>)[primary];
118
- const where = key !== undefined ? `row ${primary} ${JSON.stringify(key)}` : `row ${index} of this page`;
119
- const why = verdict.errors.map((e) => `${e.path}: ${e.message}`).join(', ');
120
- throw new Error(`${name} mirror refused ${where} — ${why}`);
121
- });
122
- }
@@ -1,20 +1,7 @@
1
1
  import type { EntityConstructor } from '@fougere/schema';
2
2
  import type { PresenterViews } from './presenter.js';
3
3
 
4
- /**
5
- * What a prefab class declares about ITSELF, at runtime.
6
- *
7
- * `Crud(Post)`, `Presenter(Post)`, `Repository(Post)`, `Collector(User)` and
8
- * `Mirror(BookCard)` all fabricate a class, and only the fabricator knows what it was
9
- * built on: the AST scan is workspace-only, so an INSTALLED prefab resolves to nothing
10
- * and a statement written in source would be lost. Hence a runtime marker — the same
11
- * reason `__ops` exists.
12
- *
13
- * It was three spellings for one statement: `static __entity` on three of the five, a
14
- * private `Symbol.for('fougere:x_target')` on the other two, and BOTH on `Repository`
15
- * and `Mirror` — the same class recording its subject twice, under two names, with two
16
- * readers that could disagree. A mark that answers one question answers it once.
17
- */
4
+ /** What a prefab class declares about ITSELF, at runtime. */
18
5
  interface Prefab {
19
6
  /** The shape this class was built on. `Mirror` calls it a shape; it is the same slot. */
20
7
  readonly __entity?: EntityConstructor;
@@ -24,13 +11,7 @@ interface Prefab {
24
11
  readonly __output?: EntityConstructor;
25
12
  }
26
13
 
27
- /**
28
- * The shape a prefab was built on, or `undefined` when the class is not one.
29
- *
30
- * A plain property read: JavaScript walks a constructor's own prototype chain, so a
31
- * subclass of a prefab answers what its base recorded. Three of the five accessors this
32
- * replaces walked that chain by hand, and two did not — one question, two mechanisms.
33
- */
14
+ /** The shape a prefab was built on, or `undefined` when the class is not one. */
34
15
  export function targetOf(ctor: unknown): EntityConstructor | undefined {
35
16
  return (ctor as Prefab | undefined)?.__entity;
36
17
  }
@@ -1,26 +1,4 @@
1
- /**
2
- * Presenter(Entity) — enriches an entity's output with computed fields.
3
- *
4
- * Each method on the presenter is a computed field resolver:
5
- * - Receives the entity record as first argument
6
- * - Can be sync or async
7
- * - Injected via DI (constructor params resolved by the container)
8
- *
9
- * Usage:
10
- * ```ts
11
- * export default class PostPresenter extends Presenter(Post) {
12
- * constructor(private commentStorage: CommentStorage) { super(); }
13
- *
14
- * excerpt(post: Post) {
15
- * return post.body.slice(0, 200);
16
- * }
17
- *
18
- * async commentCount(post: Post) {
19
- * return this.commentStorage.countFor(post.id);
20
- * }
21
- * }
22
- * ```
23
- */
1
+ /** Presenter(Entity) — enriches an entity's output with computed fields. */
24
2
 
25
3
  import { upperFirst, type EntityConstructor } from '@fougere/schema';
26
4
 
@@ -30,19 +8,7 @@ import { upperFirst, type EntityConstructor } from '@fougere/schema';
30
8
  */
31
9
  export type PresenterViews = Record<string, EntityConstructor | [EntityConstructor]>;
32
10
 
33
- /**
34
- * `Presenter(Order, { items: [OrderItemView], user: UserCard })` — the second argument names
35
- * the view each computed field emits, exactly as `Crud(Post, { list: PostCard })` names an
36
- * op's. What fabricates a field declares its contract, and it declares it **once**: the
37
- * façade applies the presenter (see `PresenterExecutor`), and every surface reads the same statement
38
- * instead of guessing.
39
- *
40
- * Guessing was the cost of not stating it. The scan can read a scalar off a return type and
41
- * nothing more, so a field returning an object had no derivable shape: the GraphQL projection
42
- * fell back to a serialized `String`, and a client asking `items { quantity }` got a schema
43
- * error on a field REST served whole. Declaring is optional — a scalar field needs nothing,
44
- * and an undeclared object keeps the old behaviour.
45
- */
11
+ /** `Presenter(Order, { items. */
46
12
  export function Presenter<E extends EntityConstructor>(entity: E, views?: PresenterViews) {
47
13
  class PresenterBase {
48
14
  static readonly __entity = entity;
@@ -2,68 +2,11 @@ import { upperFirst, type EntityConstructor } from '@fougere/schema';
2
2
  import type { Storage, ListOptions, ListResult, SelectOption } from '../storage.js';
3
3
  import type { SchemaView } from '@fougere/schema';
4
4
 
5
- /**
6
- * Repository(…entities) — who owns an entity's storage, and where its questions are named.
7
- *
8
- * **The arity decides**, which is the second reading of what `storage.ts` already states for
9
- * `Storage` against `Together`: the arity of the unit is the whole distinction.
10
- *
11
- * ONE entity — the repository IS that entity's storage, with your methods added. The port's
12
- * thirteen gestures are forwarded, so a handler reads `this.posts.list()` whether or not
13
- * anyone wrote the file, and a named question sits beside them:
14
- *
15
- * ```ts
16
- * // repositories/PostRepository.ts
17
- * export default class PostRepository extends Repository(Post) {
18
- * published() {
19
- * return this.list({ where: { status: 'published' }, orderBy: 'publishedAt', order: 'desc' });
20
- * }
21
- * }
22
- * ```
23
- *
24
- * TWO OR MORE — an aggregate. It owns them: nothing else in the app is handed their
25
- * storage, and no gesture is forwarded (which entity would `create` write to?), so the only
26
- * way in is a method this class names. That is what lets a rule spanning two tables exist:
27
- * it is ordinary TypeScript inside the method that does the writing.
28
- *
29
- * ```ts
30
- * // repositories/CommandeRepository.ts
31
- * export default class CommandeRepository extends Repository(Commande, Stock) {
32
- * avecLignes(id: string) {
33
- * const [commandes, stock] = this.storages;
34
- * …
35
- * }
36
- * }
37
- * ```
38
- *
39
- * `this.storages` is protected, because the whole point is that the storage stops at this file.
40
- * `protected` is erased at runtime, like `abstract` on a port: a compile-time guarantee, not
41
- * a barrier. The same bargain, already accepted.
42
- *
43
- * **The boundary is not the unit of work.** An aggregate says the rules of these entities
44
- * hold together; a frame says these writes land together, and the two lists coincide only
45
- * often. Deriving the frame from the membership would make a read-only aggregate carry one
46
- * — refusals included, and `registerFrames` refuses without storage or over `remotes:` —
47
- * and would put `Together<[Commande, Stock], [StockMirror]>` out of reach forever. So a
48
- * frame is ASKED FOR here as anywhere else, which is what makes it declared:
49
- *
50
- * ```ts
51
- * constructor(commandes: CommandeStorage, stock: StockStorage, private frame: Together<[Commande, Stock]>) {
52
- * super(commandes, stock);
53
- * }
54
- * ```
55
- *
56
- * The storage words come back in that line, and only there: this class IS the holder, which is
57
- * the one case `boot/ownership.ts` lets name the storage it was built on.
58
- *
59
- * A repository is NOT a door: it has no façade, so nothing here is reachable from the wire.
60
- */
5
+ /** Repository(…entities) — who owns an entity's storage, and where its questions are named. */
61
6
 
62
7
  /**
63
- * The shape a repository of ONE entity has — the port itself, plus whatever the subclass
64
- * names on top. Written by an author who has not written the file: `RepositoryOf<Post>` is
65
- * to `PostRepository` what `Storage<Post>` is to `PostStorage`, one spelling of one key, and
66
- * `depKeyOf` reads both.
8
+ * The shape a repository of ONE entity has — the port itself, plus whatever the subclass names on
9
+ * top.
67
10
  */
68
11
  export type RepositoryOf<T> = Storage<T>;
69
12
 
@@ -73,13 +16,7 @@ export interface RepositoryConstructor<T> {
73
16
  readonly __entity: unknown;
74
17
  }
75
18
 
76
- /**
77
- * What an aggregate's subclass sees: the storage of the members it owns, in declared order,
78
- * and `protected` — the storage stops at that file, which is the whole mechanism.
79
- *
80
- * A class and not an interface, because `protected` cannot be spelled in one. Ambient: the
81
- * value it describes is fabricated by `many()` for an arity only known at the call.
82
- */
19
+ /** What an aggregate's subclass sees. */
83
20
  declare abstract class AggregateShape<E extends readonly EntityConstructor[]> {
84
21
  protected storages: { [K in keyof E]: Storage<InstanceType<E[K]>> };
85
22
  }
@@ -103,11 +40,7 @@ export function Repository(...entities: EntityConstructor[]): unknown {
103
40
  return entities.length === 1 ? one(entities[0]) : many(entities);
104
41
  }
105
42
 
106
- /**
107
- * The port forwarded, member by member. Written out rather than proxied: a Proxy would
108
- * answer every name including the ones the port does not have, and this file would then
109
- * state the surface nowhere. Thirteen lines against one declaration that can be read.
110
- */
43
+ /** The port forwarded, member by member. */
111
44
  function one<E extends EntityConstructor>(entity: E): RepositoryConstructor<InstanceType<E>> {
112
45
  type T = InstanceType<E>;
113
46
 
@@ -134,11 +67,7 @@ function one<E extends EntityConstructor>(entity: E): RepositoryConstructor<Inst
134
67
  return RepositoryBase as unknown as RepositoryConstructor<T>;
135
68
  }
136
69
 
137
- /**
138
- * The aggregate. Its constructor takes the members' storage in the DECLARED order — the
139
- * order `toProvider` fills its `deps` with, and the order a subclass hands back to `super()`
140
- * when it declares a constructor of its own.
141
- */
70
+ /** The aggregate. */
142
71
  function many<E extends readonly EntityConstructor[]>(entities: E): AggregateConstructor<E> {
143
72
  class AggregateBase {
144
73
  static readonly __entity = entities[0];
@@ -159,12 +88,7 @@ export function repositoryKeyOf(entity: string): string {
159
88
  return `${upperFirst(entity)}Repository`;
160
89
  }
161
90
 
162
- /**
163
- * The entities a class owns — empty for anything that is not an aggregate.
164
- *
165
- * Read from the mark rather than from the constructor, for the reason `Crud.__ops` exists:
166
- * the AST scan is workspace-only, so an installed prefab resolves to nothing.
167
- */
91
+ /** The entities a class owns — empty for anything that is not an aggregate. */
168
92
  export function ownedBy(ctor: unknown): readonly EntityConstructor[] {
169
93
  return (ctor as { __owns?: readonly EntityConstructor[] } | undefined)?.__owns ?? [];
170
94
  }
@@ -0,0 +1,32 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+
4
+ /** Which adapters a PROJECT could load, read off its dependencies. */
5
+ const ADAPTER_PACKAGE = /^@fougere\/adapter-(.+)$/;
6
+
7
+ /** The adapter names this project depends on — empty when it has no package.json to read. */
8
+ export async function adaptersOf(root: string): Promise<string[]> {
9
+ const manifest = await read(join(root, 'package.json'));
10
+ if (!manifest) return [];
11
+
12
+ const declared = { ...manifest.dependencies, ...manifest.devDependencies };
13
+
14
+ return Object.keys(declared)
15
+ .map((name) => ADAPTER_PACKAGE.exec(name)?.[1])
16
+ .filter((name): name is string => name !== undefined);
17
+ }
18
+
19
+ async function read(path: string): Promise<Manifest | undefined> {
20
+ try {
21
+ return JSON.parse(await readFile(path, 'utf8')) as Manifest;
22
+ } catch {
23
+ // No manifest, or one that is not JSON. Either way this cannot validate a name, and
24
+ // reporting every `adapters:` key as unknown would be worse than saying nothing.
25
+ return undefined;
26
+ }
27
+ }
28
+
29
+ interface Manifest {
30
+ dependencies?: Record<string, string>;
31
+ devDependencies?: Record<string, string>;
32
+ }
@@ -1,15 +1,4 @@
1
- /**
2
- * What a Fougere boot loads at RUNTIME, so a bundler must leave it alone.
3
- *
4
- * Stated once because it was stated twice and the two had already drifted: the Vite plugin
5
- * listed `@fougere/schema`, `@fougere/adapter-graphql` and `@fougere/auth-better`, the Next
6
- * one did not, and BOTH omitted the two packages `@fougere/app`'s boot actually imports
7
- * dynamically — `@fougere/defaults` and `@fougere/transport-http`. A list a bundler reads
8
- * has no way to notice it is wrong: nothing fails at build time, the app fails at boot.
9
- *
10
- * It sits here rather than beside the dynamic imports because both readers are BUILD-TIME
11
- * plugins that already depend on core, and neither may pull the boot into a bundler config.
12
- */
1
+ /** What a Fougere boot loads at RUNTIME, so a bundler must leave it alone. */
13
2
  export const RUNTIME_PACKAGES: readonly string[] = [
14
3
  '@fougere/app',
15
4
  '@fougere/core',