@fougere/core 0.2.0-alpha.2 → 0.3.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 (414) hide show
  1. package/README.md +2 -1
  2. package/dist/boot/AppLifecycle.d.ts +18 -0
  3. package/dist/boot/AppLifecycle.d.ts.map +1 -0
  4. package/dist/boot/AppLifecycle.js +42 -0
  5. package/dist/boot/AppLifecycle.js.map +1 -0
  6. package/dist/boot/Emissions.d.ts +126 -0
  7. package/dist/boot/Emissions.d.ts.map +1 -0
  8. package/dist/boot/Emissions.js +233 -0
  9. package/dist/boot/Emissions.js.map +1 -0
  10. package/dist/boot/HandlerFacade.d.ts +72 -0
  11. package/dist/boot/HandlerFacade.d.ts.map +1 -0
  12. package/dist/boot/HandlerFacade.js +174 -0
  13. package/dist/boot/HandlerFacade.js.map +1 -0
  14. package/dist/boot/Lifecycle.d.ts +4 -0
  15. package/dist/boot/Lifecycle.d.ts.map +1 -0
  16. package/dist/boot/Lifecycle.js +3 -0
  17. package/dist/boot/Lifecycle.js.map +1 -0
  18. package/dist/boot/ambient-port.d.ts +38 -0
  19. package/dist/boot/ambient-port.d.ts.map +1 -0
  20. package/dist/boot/ambient-port.js +2 -0
  21. package/dist/boot/ambient-port.js.map +1 -0
  22. package/dist/boot/ambient.als.d.ts +3 -0
  23. package/dist/boot/ambient.als.d.ts.map +1 -0
  24. package/dist/boot/ambient.als.js +34 -0
  25. package/dist/boot/ambient.als.js.map +1 -0
  26. package/dist/boot/ambient.queue.d.ts +10 -0
  27. package/dist/boot/ambient.queue.d.ts.map +1 -0
  28. package/dist/boot/ambient.queue.js +60 -0
  29. package/dist/boot/ambient.queue.js.map +1 -0
  30. package/dist/boot/apply.d.ts +22 -0
  31. package/dist/boot/apply.d.ts.map +1 -0
  32. package/dist/boot/apply.js +48 -0
  33. package/dist/boot/apply.js.map +1 -0
  34. package/dist/boot/auth.d.ts +53 -0
  35. package/dist/boot/auth.d.ts.map +1 -0
  36. package/dist/boot/auth.js +2 -0
  37. package/dist/boot/auth.js.map +1 -0
  38. package/dist/{binding.d.ts → boot/binding.d.ts} +14 -17
  39. package/dist/boot/binding.d.ts.map +1 -0
  40. package/dist/{binding.js → boot/binding.js} +19 -10
  41. package/dist/boot/binding.js.map +1 -0
  42. package/dist/{boot.d.ts → boot/boot.d.ts} +25 -5
  43. package/dist/boot/boot.d.ts.map +1 -0
  44. package/dist/boot/boot.js +70 -0
  45. package/dist/boot/boot.js.map +1 -0
  46. package/dist/boot/bootstrap.d.ts.map +1 -0
  47. package/dist/boot/bootstrap.js +721 -0
  48. package/dist/boot/bootstrap.js.map +1 -0
  49. package/dist/boot/egress.d.ts +8 -0
  50. package/dist/boot/egress.d.ts.map +1 -0
  51. package/dist/boot/egress.js +11 -0
  52. package/dist/boot/egress.js.map +1 -0
  53. package/dist/boot/frame.d.ts +44 -0
  54. package/dist/boot/frame.d.ts.map +1 -0
  55. package/dist/boot/frame.js +181 -0
  56. package/dist/boot/frame.js.map +1 -0
  57. package/dist/boot/ownership.d.ts +42 -0
  58. package/dist/boot/ownership.d.ts.map +1 -0
  59. package/dist/boot/ownership.js +127 -0
  60. package/dist/boot/ownership.js.map +1 -0
  61. package/dist/boot/ports.d.ts +17 -0
  62. package/dist/boot/ports.d.ts.map +1 -0
  63. package/dist/boot/ports.js +57 -0
  64. package/dist/boot/ports.js.map +1 -0
  65. package/dist/{remote.d.ts → boot/remote.d.ts} +11 -3
  66. package/dist/boot/remote.d.ts.map +1 -0
  67. package/dist/{remote.js → boot/remote.js} +24 -26
  68. package/dist/boot/remote.js.map +1 -0
  69. package/dist/{seed.d.ts → boot/seed.d.ts} +13 -1
  70. package/dist/boot/seed.d.ts.map +1 -0
  71. package/dist/{seed.js → boot/seed.js} +24 -3
  72. package/dist/boot/seed.js.map +1 -0
  73. package/dist/boot/together.d.ts +26 -0
  74. package/dist/boot/together.d.ts.map +1 -0
  75. package/dist/boot/together.js +163 -0
  76. package/dist/boot/together.js.map +1 -0
  77. package/dist/boot/types.d.ts +260 -0
  78. package/dist/boot/types.d.ts.map +1 -0
  79. package/dist/boot/types.js.map +1 -0
  80. package/dist/builtins/config.d.ts +9 -0
  81. package/dist/builtins/config.d.ts.map +1 -1
  82. package/dist/builtins/config.js +16 -1
  83. package/dist/builtins/config.js.map +1 -1
  84. package/dist/builtins/logger.d.ts +37 -4
  85. package/dist/builtins/logger.d.ts.map +1 -1
  86. package/dist/builtins/logger.js +66 -7
  87. package/dist/builtins/logger.js.map +1 -1
  88. package/dist/config-loader.d.ts +39 -35
  89. package/dist/config-loader.d.ts.map +1 -1
  90. package/dist/config-loader.js +15 -54
  91. package/dist/config-loader.js.map +1 -1
  92. package/dist/contract/Call.d.ts +10 -0
  93. package/dist/contract/Call.d.ts.map +1 -0
  94. package/dist/contract/Call.js +15 -0
  95. package/dist/contract/Call.js.map +1 -0
  96. package/dist/contract/Invocation.d.ts +27 -0
  97. package/dist/contract/Invocation.d.ts.map +1 -0
  98. package/dist/contract/Invocation.js +59 -0
  99. package/dist/contract/Invocation.js.map +1 -0
  100. package/dist/contract/RouteAddress.d.ts +17 -0
  101. package/dist/contract/RouteAddress.d.ts.map +1 -0
  102. package/dist/contract/RouteAddress.js +38 -0
  103. package/dist/contract/RouteAddress.js.map +1 -0
  104. package/dist/contract.d.ts +25 -19
  105. package/dist/contract.d.ts.map +1 -1
  106. package/dist/contract.js +25 -10
  107. package/dist/contract.js.map +1 -1
  108. package/dist/crypto/encoding.d.ts +25 -0
  109. package/dist/crypto/encoding.d.ts.map +1 -0
  110. package/dist/crypto/encoding.js +58 -0
  111. package/dist/crypto/encoding.js.map +1 -0
  112. package/dist/crypto/node.d.ts +4 -0
  113. package/dist/crypto/node.d.ts.map +1 -0
  114. package/dist/crypto/node.js +25 -0
  115. package/dist/crypto/node.js.map +1 -0
  116. package/dist/crypto/port.d.ts +42 -0
  117. package/dist/crypto/port.d.ts.map +1 -0
  118. package/dist/crypto/port.js +19 -0
  119. package/dist/crypto/port.js.map +1 -0
  120. package/dist/crypto/webcrypto.d.ts +4 -0
  121. package/dist/crypto/webcrypto.d.ts.map +1 -0
  122. package/dist/crypto/webcrypto.js +34 -0
  123. package/dist/crypto/webcrypto.js.map +1 -0
  124. package/dist/dispatch/ArgumentResolver.d.ts +10 -0
  125. package/dist/dispatch/ArgumentResolver.d.ts.map +1 -0
  126. package/dist/dispatch/ArgumentResolver.js +12 -0
  127. package/dist/dispatch/ArgumentResolver.js.map +1 -0
  128. package/dist/dispatch/ArrayResult.d.ts +3 -0
  129. package/dist/dispatch/ArrayResult.d.ts.map +1 -0
  130. package/dist/dispatch/ArrayResult.js +11 -0
  131. package/dist/dispatch/ArrayResult.js.map +1 -0
  132. package/dist/dispatch/DispatchEvent.d.ts +18 -0
  133. package/dist/dispatch/DispatchEvent.d.ts.map +1 -0
  134. package/dist/dispatch/DispatchEvent.js +30 -0
  135. package/dist/dispatch/DispatchEvent.js.map +1 -0
  136. package/dist/dispatch/DispatchLifecycle.d.ts +9 -0
  137. package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -0
  138. package/dist/dispatch/DispatchLifecycle.js +25 -0
  139. package/dist/dispatch/DispatchLifecycle.js.map +1 -0
  140. package/dist/dispatch/DispatchPort.d.ts +6 -0
  141. package/dist/dispatch/DispatchPort.d.ts.map +1 -0
  142. package/dist/dispatch/DispatchPort.js +2 -0
  143. package/dist/dispatch/DispatchPort.js.map +1 -0
  144. package/dist/dispatch/Dispatcher.d.ts +16 -0
  145. package/dist/dispatch/Dispatcher.d.ts.map +1 -0
  146. package/dist/dispatch/Dispatcher.js +44 -0
  147. package/dist/dispatch/Dispatcher.js.map +1 -0
  148. package/dist/dispatch/InFlight.d.ts +12 -0
  149. package/dist/dispatch/InFlight.d.ts.map +1 -0
  150. package/dist/dispatch/InFlight.js +46 -0
  151. package/dist/dispatch/InFlight.js.map +1 -0
  152. package/dist/dispatch/InputValidator.d.ts +7 -0
  153. package/dist/dispatch/InputValidator.d.ts.map +1 -0
  154. package/dist/dispatch/InputValidator.js +21 -0
  155. package/dist/dispatch/InputValidator.js.map +1 -0
  156. package/dist/dispatch/LocalRoutePolicy.d.ts +11 -0
  157. package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -0
  158. package/dist/dispatch/LocalRoutePolicy.js +32 -0
  159. package/dist/dispatch/LocalRoutePolicy.js.map +1 -0
  160. package/dist/dispatch/OperationExecutor.d.ts +25 -0
  161. package/dist/dispatch/OperationExecutor.d.ts.map +1 -0
  162. package/dist/dispatch/OperationExecutor.js +32 -0
  163. package/dist/dispatch/OperationExecutor.js.map +1 -0
  164. package/dist/dispatch/OperationRoute.d.ts +13 -0
  165. package/dist/dispatch/OperationRoute.d.ts.map +1 -0
  166. package/dist/dispatch/OperationRoute.js +15 -0
  167. package/dist/dispatch/OperationRoute.js.map +1 -0
  168. package/dist/dispatch/OutputProjector.d.ts +12 -0
  169. package/dist/dispatch/OutputProjector.d.ts.map +1 -0
  170. package/dist/dispatch/OutputProjector.js +30 -0
  171. package/dist/dispatch/OutputProjector.js.map +1 -0
  172. package/dist/dispatch/OutputView.d.ts +8 -0
  173. package/dist/dispatch/OutputView.d.ts.map +1 -0
  174. package/dist/dispatch/OutputView.js +10 -0
  175. package/dist/dispatch/OutputView.js.map +1 -0
  176. package/dist/dispatch/PresenterArgumentResolver.d.ts +12 -0
  177. package/dist/dispatch/PresenterArgumentResolver.d.ts.map +1 -0
  178. package/dist/dispatch/PresenterArgumentResolver.js +20 -0
  179. package/dist/dispatch/PresenterArgumentResolver.js.map +1 -0
  180. package/dist/dispatch/PresenterExecutor.d.ts +11 -0
  181. package/dist/dispatch/PresenterExecutor.d.ts.map +1 -0
  182. package/dist/dispatch/PresenterExecutor.js +56 -0
  183. package/dist/dispatch/PresenterExecutor.js.map +1 -0
  184. package/dist/dispatch/RemoteRouteResolver.d.ts +13 -0
  185. package/dist/dispatch/RemoteRouteResolver.d.ts.map +1 -0
  186. package/dist/dispatch/RemoteRouteResolver.js +18 -0
  187. package/dist/dispatch/RemoteRouteResolver.js.map +1 -0
  188. package/dist/dispatch/Route.d.ts +10 -0
  189. package/dist/dispatch/Route.d.ts.map +1 -0
  190. package/dist/dispatch/Route.js +2 -0
  191. package/dist/dispatch/Route.js.map +1 -0
  192. package/dist/dispatch/RouteNotFoundError.d.ts +10 -0
  193. package/dist/dispatch/RouteNotFoundError.d.ts.map +1 -0
  194. package/dist/dispatch/RouteNotFoundError.js +24 -0
  195. package/dist/dispatch/RouteNotFoundError.js.map +1 -0
  196. package/dist/dispatch/RoutePolicy.d.ts +8 -0
  197. package/dist/dispatch/RoutePolicy.d.ts.map +1 -0
  198. package/dist/dispatch/RoutePolicy.js +2 -0
  199. package/dist/dispatch/RoutePolicy.js.map +1 -0
  200. package/dist/dispatch/RouteRegistry.d.ts +18 -0
  201. package/dist/dispatch/RouteRegistry.d.ts.map +1 -0
  202. package/dist/dispatch/RouteRegistry.js +62 -0
  203. package/dist/dispatch/RouteRegistry.js.map +1 -0
  204. package/dist/dispatch/RouteResolver.d.ts +7 -0
  205. package/dist/dispatch/RouteResolver.d.ts.map +1 -0
  206. package/dist/dispatch/RouteResolver.js +2 -0
  207. package/dist/dispatch/RouteResolver.js.map +1 -0
  208. package/dist/dispatch/StorageGuard.d.ts +15 -0
  209. package/dist/dispatch/StorageGuard.d.ts.map +1 -0
  210. package/dist/dispatch/StorageGuard.js +63 -0
  211. package/dist/dispatch/StorageGuard.js.map +1 -0
  212. package/dist/effective-operation.d.ts +90 -0
  213. package/dist/effective-operation.d.ts.map +1 -0
  214. package/dist/effective-operation.js +450 -0
  215. package/dist/effective-operation.js.map +1 -0
  216. package/dist/emit.js +2 -2
  217. package/dist/emit.js.map +1 -1
  218. package/dist/entry/DynamicFacade.d.ts +10 -0
  219. package/dist/entry/DynamicFacade.d.ts.map +1 -0
  220. package/dist/entry/DynamicFacade.js +27 -0
  221. package/dist/entry/DynamicFacade.js.map +1 -0
  222. package/dist/entry/FacadeEntry.d.ts +11 -0
  223. package/dist/entry/FacadeEntry.d.ts.map +1 -0
  224. package/dist/entry/FacadeEntry.js +26 -0
  225. package/dist/entry/FacadeEntry.js.map +1 -0
  226. package/dist/entry/TransportEntry.d.ts +13 -0
  227. package/dist/entry/TransportEntry.d.ts.map +1 -0
  228. package/dist/entry/TransportEntry.js +24 -0
  229. package/dist/entry/TransportEntry.js.map +1 -0
  230. package/dist/frond-config.d.ts +24 -7
  231. package/dist/frond-config.d.ts.map +1 -1
  232. package/dist/frond-config.js.map +1 -1
  233. package/dist/graph.d.ts +1 -1
  234. package/dist/graph.d.ts.map +1 -1
  235. package/dist/graph.js +3 -2
  236. package/dist/graph.js.map +1 -1
  237. package/dist/identity-keys.d.ts +14 -0
  238. package/dist/identity-keys.d.ts.map +1 -0
  239. package/dist/identity-keys.js +37 -0
  240. package/dist/identity-keys.js.map +1 -0
  241. package/dist/identity.d.ts +58 -0
  242. package/dist/identity.d.ts.map +1 -0
  243. package/dist/identity.js +182 -0
  244. package/dist/identity.js.map +1 -0
  245. package/dist/imports.d.ts +1 -1
  246. package/dist/imports.d.ts.map +1 -1
  247. package/dist/imports.js +7 -3
  248. package/dist/imports.js.map +1 -1
  249. package/dist/index.d.ts +57 -38
  250. package/dist/index.d.ts.map +1 -1
  251. package/dist/index.js +38 -32
  252. package/dist/index.js.map +1 -1
  253. package/dist/loader.d.ts +16 -0
  254. package/dist/loader.d.ts.map +1 -0
  255. package/dist/loader.js +25 -0
  256. package/dist/loader.js.map +1 -0
  257. package/dist/node.d.ts +21 -0
  258. package/dist/node.d.ts.map +1 -0
  259. package/dist/node.js +24 -0
  260. package/dist/node.js.map +1 -0
  261. package/dist/orm.d.ts +69 -8
  262. package/dist/orm.d.ts.map +1 -1
  263. package/dist/orm.js +35 -2
  264. package/dist/orm.js.map +1 -1
  265. package/dist/prefab/collector.d.ts +29 -0
  266. package/dist/prefab/collector.d.ts.map +1 -0
  267. package/dist/prefab/collector.js +34 -0
  268. package/dist/prefab/collector.js.map +1 -0
  269. package/dist/{crud.d.ts → prefab/crud.d.ts} +7 -8
  270. package/dist/prefab/crud.d.ts.map +1 -0
  271. package/dist/{crud.js → prefab/crud.js} +39 -5
  272. package/dist/prefab/crud.js.map +1 -0
  273. package/dist/prefab/mirror.d.ts +52 -0
  274. package/dist/prefab/mirror.d.ts.map +1 -0
  275. package/dist/prefab/mirror.js +66 -0
  276. package/dist/prefab/mirror.js.map +1 -0
  277. package/dist/prefab/prefab.d.ts +15 -0
  278. package/dist/prefab/prefab.d.ts.map +1 -0
  279. package/dist/prefab/prefab.js +19 -0
  280. package/dist/prefab/prefab.js.map +1 -0
  281. package/dist/{presenter.d.ts → prefab/presenter.d.ts} +6 -17
  282. package/dist/prefab/presenter.d.ts.map +1 -0
  283. package/dist/{presenter.js → prefab/presenter.js} +5 -23
  284. package/dist/prefab/presenter.js.map +1 -0
  285. package/dist/prefab/repository.d.ts +104 -0
  286. package/dist/prefab/repository.d.ts.map +1 -0
  287. package/dist/prefab/repository.js +62 -0
  288. package/dist/prefab/repository.js.map +1 -0
  289. package/dist/scan/Fronds.d.ts +45 -0
  290. package/dist/scan/Fronds.d.ts.map +1 -0
  291. package/dist/scan/Fronds.js +66 -0
  292. package/dist/scan/Fronds.js.map +1 -0
  293. package/dist/scan/conventions.d.ts +74 -0
  294. package/dist/scan/conventions.d.ts.map +1 -0
  295. package/dist/scan/conventions.js +82 -0
  296. package/dist/scan/conventions.js.map +1 -0
  297. package/dist/scan/emit.d.ts +14 -0
  298. package/dist/scan/emit.d.ts.map +1 -0
  299. package/dist/scan/emit.js +211 -0
  300. package/dist/scan/emit.js.map +1 -0
  301. package/dist/scan/frond.d.ts +224 -0
  302. package/dist/scan/frond.d.ts.map +1 -0
  303. package/dist/scan/frond.js +2 -0
  304. package/dist/scan/frond.js.map +1 -0
  305. package/dist/{handler-parser.d.ts → scan/handler-parser.d.ts} +18 -9
  306. package/dist/scan/handler-parser.d.ts.map +1 -0
  307. package/dist/scan/handler-parser.js +625 -0
  308. package/dist/scan/handler-parser.js.map +1 -0
  309. package/dist/scan/scan-cache.d.ts +16 -0
  310. package/dist/scan/scan-cache.d.ts.map +1 -0
  311. package/dist/{scan-cache.js → scan/scan-cache.js} +27 -20
  312. package/dist/scan/scan-cache.js.map +1 -0
  313. package/dist/scan/scanner.d.ts +20 -0
  314. package/dist/scan/scanner.d.ts.map +1 -0
  315. package/dist/{scanner.js → scan/scanner.js} +185 -167
  316. package/dist/scan/scanner.js.map +1 -0
  317. package/dist/verify.d.ts +16 -3
  318. package/dist/verify.d.ts.map +1 -1
  319. package/dist/verify.js +21 -18
  320. package/dist/verify.js.map +1 -1
  321. package/dist/{call.d.ts → wire/call.d.ts} +70 -1
  322. package/dist/wire/call.d.ts.map +1 -0
  323. package/dist/{call.js → wire/call.js} +48 -75
  324. package/dist/wire/call.js.map +1 -0
  325. package/dist/{middleware.d.ts → wire/errors.d.ts} +18 -19
  326. package/dist/wire/errors.d.ts.map +1 -0
  327. package/dist/{middleware.js → wire/errors.js} +26 -14
  328. package/dist/wire/errors.js.map +1 -0
  329. package/dist/{errors.d.ts → wire/http-error.d.ts} +5 -6
  330. package/dist/wire/http-error.d.ts.map +1 -0
  331. package/dist/{errors.js → wire/http-error.js} +7 -6
  332. package/dist/wire/http-error.js.map +1 -0
  333. package/dist/wire/invocation.d.ts +4 -0
  334. package/dist/wire/invocation.d.ts.map +1 -0
  335. package/dist/wire/invocation.js +3 -0
  336. package/dist/wire/invocation.js.map +1 -0
  337. package/dist/{middleware/logger.d.ts → wire/loggerMiddleware.d.ts} +3 -3
  338. package/dist/wire/loggerMiddleware.d.ts.map +1 -0
  339. package/dist/{middleware/logger.js → wire/loggerMiddleware.js} +2 -2
  340. package/dist/wire/loggerMiddleware.js.map +1 -0
  341. package/dist/wire/middleware.d.ts +29 -0
  342. package/dist/wire/middleware.d.ts.map +1 -0
  343. package/dist/wire/middleware.js +20 -0
  344. package/dist/wire/middleware.js.map +1 -0
  345. package/dist/{operation.d.ts → wire/operation.d.ts} +39 -10
  346. package/dist/wire/operation.d.ts.map +1 -0
  347. package/dist/wire/operation.js +167 -0
  348. package/dist/wire/operation.js.map +1 -0
  349. package/package.json +24 -7
  350. package/dist/binding.d.ts.map +0 -1
  351. package/dist/binding.js.map +0 -1
  352. package/dist/boot.d.ts.map +0 -1
  353. package/dist/boot.js +0 -53
  354. package/dist/boot.js.map +0 -1
  355. package/dist/bootstrap.d.ts.map +0 -1
  356. package/dist/bootstrap.js +0 -879
  357. package/dist/bootstrap.js.map +0 -1
  358. package/dist/call.d.ts.map +0 -1
  359. package/dist/call.js.map +0 -1
  360. package/dist/collector.d.ts +0 -28
  361. package/dist/collector.d.ts.map +0 -1
  362. package/dist/collector.js +0 -32
  363. package/dist/collector.js.map +0 -1
  364. package/dist/crud.d.ts.map +0 -1
  365. package/dist/crud.js.map +0 -1
  366. package/dist/egress.d.ts +0 -52
  367. package/dist/egress.d.ts.map +0 -1
  368. package/dist/egress.js +0 -186
  369. package/dist/egress.js.map +0 -1
  370. package/dist/errors.d.ts.map +0 -1
  371. package/dist/errors.js.map +0 -1
  372. package/dist/handler-parser.d.ts.map +0 -1
  373. package/dist/handler-parser.js +0 -505
  374. package/dist/handler-parser.js.map +0 -1
  375. package/dist/invocation.d.ts +0 -20
  376. package/dist/invocation.d.ts.map +0 -1
  377. package/dist/invocation.js +0 -15
  378. package/dist/invocation.js.map +0 -1
  379. package/dist/middleware/error-handler.d.ts +0 -15
  380. package/dist/middleware/error-handler.d.ts.map +0 -1
  381. package/dist/middleware/error-handler.js +0 -29
  382. package/dist/middleware/error-handler.js.map +0 -1
  383. package/dist/middleware/logger.d.ts.map +0 -1
  384. package/dist/middleware/logger.js.map +0 -1
  385. package/dist/middleware.d.ts.map +0 -1
  386. package/dist/middleware.js.map +0 -1
  387. package/dist/mirror.d.ts +0 -93
  388. package/dist/mirror.d.ts.map +0 -1
  389. package/dist/mirror.js +0 -96
  390. package/dist/mirror.js.map +0 -1
  391. package/dist/operation.d.ts.map +0 -1
  392. package/dist/operation.js +0 -95
  393. package/dist/operation.js.map +0 -1
  394. package/dist/presenter.d.ts.map +0 -1
  395. package/dist/presenter.js.map +0 -1
  396. package/dist/remote.d.ts.map +0 -1
  397. package/dist/remote.js.map +0 -1
  398. package/dist/repository.d.ts +0 -55
  399. package/dist/repository.d.ts.map +0 -1
  400. package/dist/repository.js +0 -26
  401. package/dist/repository.js.map +0 -1
  402. package/dist/scan-cache.d.ts +0 -10
  403. package/dist/scan-cache.d.ts.map +0 -1
  404. package/dist/scan-cache.js.map +0 -1
  405. package/dist/scanner.d.ts +0 -34
  406. package/dist/scanner.d.ts.map +0 -1
  407. package/dist/scanner.js.map +0 -1
  408. package/dist/seed.d.ts.map +0 -1
  409. package/dist/seed.js.map +0 -1
  410. package/dist/types.d.ts +0 -421
  411. package/dist/types.d.ts.map +0 -1
  412. package/dist/types.js.map +0 -1
  413. /package/dist/{bootstrap.d.ts → boot/bootstrap.d.ts} +0 -0
  414. /package/dist/{types.js → boot/types.js} +0 -0
@@ -1,11 +1,10 @@
1
- import type { EntityOrm, ListOptions, ListResult } from './orm.js';
2
- import type { OperationContract } from './operation.js';
3
- /** Anything the derivation algebra produces — an entity class or one of its views. */
4
- type SchemaCtor = abstract new (...args: any[]) => any;
1
+ import type { EntityOrm, ListOptions, ListResult } from '../orm.js';
2
+ import type { OperationContract } from '../wire/operation.js';
3
+ import type { EntityConstructor } from '@fougere/schema';
5
4
  /** The five ops the mixin fabricates. */
6
5
  export type CrudOpName = 'list' | 'findById' | 'create' | 'update' | 'delete';
7
6
  /** Which view each op speaks — omitted ops speak the entity, the trivial view. */
8
- export type CrudViews = Partial<Record<CrudOpName, SchemaCtor>>;
7
+ export type CrudViews = Partial<Record<CrudOpName, EntityConstructor>>;
9
8
  /**
10
9
  * The view an op emits, fabricated: the one declared for it, the single view when the
11
10
  * whole handler declares one, the entity otherwise. `PostCard` is not a hand-written
@@ -14,14 +13,14 @@ export type CrudViews = Partial<Record<CrudOpName, SchemaCtor>>;
14
13
  */
15
14
  type OutOf<V, K extends CrudOpName, T> = [
16
15
  V
17
- ] extends [SchemaCtor] ? InstanceType<V & SchemaCtor> : K extends keyof V ? (V[K] extends SchemaCtor ? InstanceType<V[K]> : T) : T;
16
+ ] extends [EntityConstructor] ? InstanceType<V & EntityConstructor> : K extends keyof V ? (V[K] extends EntityConstructor ? InstanceType<V[K]> : T) : T;
18
17
  /**
19
18
  * The five ops, typed from the entity and its views.
20
19
  *
21
20
  * Two things the mixin declares but does not own. The **output** is the view the
22
21
  * handler names (`Crud(Post, { list: PostCard })`) — fabricated, so a redefinition
23
22
  * that returns cards stays assignable. The **trailing parameters** are resolved by
24
- * type from the container (`delete(id, user: User | null)` gets its user from a
23
+ * type from the container (`delete(id, user?: User)` gets its user from a
25
24
  * collector): the mixin cannot know them, they belong to the app, so it declares that
26
25
  * a tail exists and that it supplies none — which is what `never` says, and what keeps
27
26
  * a judged redefinition assignable.
@@ -56,6 +55,6 @@ export interface CrudConstructor<T, V = {}> {
56
55
  * scopes the injected ORM via .output(PostPublic) —
57
56
  * the whole handler speaks the restricted view.
58
57
  */
59
- export declare function Crud<E extends abstract new (...args: any[]) => any, V extends CrudViews | SchemaCtor = {}>(entity: E, output?: V): CrudConstructor<InstanceType<E>, V>;
58
+ export declare function Crud<E extends EntityConstructor, V extends CrudViews | EntityConstructor = {}>(entity: E, output?: V): CrudConstructor<InstanceType<E>, V>;
60
59
  export {};
61
60
  //# sourceMappingURL=crud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../src/prefab/crud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAc,MAAM,iBAAiB,CAAC;AAyFrE,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE9E,kFAAkF;AAClF,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAEvE;;;;;GAKG;AACH,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC,SAAS,UAAU,EAAE,CAAC,IAInC;IAAC,CAAC;CAAC,SAAS,CAAC,iBAAiB,CAAC,GAAG,YAAY,CAAC,CAAC,GAAG,iBAAiB,CAAC,GACnE,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,iBAAiB,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAC7E,CAAC,CAAC;AAEN;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE;IAChC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAClB,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC;IAC1F,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7F,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7D;AAED,4FAA4F;AAC5F,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE;IAIxC,KAAK,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,iBAAiB,EAAE,CAAC,SAAS,SAAS,GAAG,iBAAiB,GAAG,EAAE,EAC5F,MAAM,EAAE,CAAC,EACT,MAAM,CAAC,EAAE,CAAC,GACT,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CA2BrC"}
@@ -1,6 +1,19 @@
1
1
  /** The id of the row an op acts on — a route segment, or a query fallback. */
2
2
  const byId = { name: 'id', source: { kind: 'param', name: 'id' }, optional: false };
3
3
  const fromBody = { name: 'input', source: { kind: 'body' }, optional: false };
4
+ /**
5
+ * The same five, written as the scan would have written them.
6
+ *
7
+ * `binding` says WHERE an argument is read from; it never says of what type, and a
8
+ * GraphQL argument needs the type. So a producer that fills only `binding` leaves
9
+ * `adapter/graphql` with nothing to declare — it drops the op (`registerOperations`,
10
+ * `if (!sig) continue`) and four of the five CRUD ops vanish from the schema while
11
+ * the façade and REST still serve them. Measured on an installed app: 16 handlers,
12
+ * 14 with unresolvable heritage, zero `createX` in the schema.
13
+ */
14
+ const idParam = { name: 'id', type: { raw: 'string', name: 'string' } };
15
+ const inputParam = (entity) => ({ name: 'input', type: { raw: `Partial<${entity}>`, name: entity } });
16
+ const returns = (raw, name, extra) => ({ raw, name, ...extra });
4
17
  /**
5
18
  * The five ops a Crud handler brings, declared rather than discovered.
6
19
  *
@@ -24,14 +37,35 @@ const fromBody = { name: 'input', source: { kind: 'body' }, optional: false };
24
37
  * out. `delete` names none — a boolean is not a shape.
25
38
  */
26
39
  function crudOps(entity) {
40
+ const name = entity.name ?? 'Entity';
41
+ const input = inputParam(name);
27
42
  return {
28
- list: { output: entity, cardinality: 'page', binding: [{ name: 'options', source: { kind: 'query' }, optional: true }] },
29
- findById: { output: entity, cardinality: 'maybe', binding: [byId] },
30
- create: { input: entity, output: entity, cardinality: 'one', binding: [fromBody] },
43
+ list: {
44
+ output: entity, cardinality: 'page',
45
+ binding: [{ name: 'options', source: { kind: 'query' }, optional: true }],
46
+ signature: {
47
+ name: 'list', returnType: returns(`ListResult<${name}>`, 'ListResult'),
48
+ params: [{ name: 'options', type: { raw: 'ListOptions', name: 'ListOptions' }, optional: true }],
49
+ },
50
+ },
51
+ findById: {
52
+ output: entity, cardinality: 'maybe', binding: [byId],
53
+ signature: { name: 'findById', returnType: returns(`${name} | undefined`, name, { nullable: true }), params: [idParam] },
54
+ },
55
+ create: {
56
+ input: entity, output: entity, cardinality: 'one', binding: [fromBody],
57
+ signature: { name: 'create', returnType: returns(name, name), params: [input] },
58
+ },
31
59
  // The patch view carries its own mode: an absent field is untouched, an
32
60
  // immutable one re-supplied is refused.
33
- update: { input: entity.partial?.(), output: entity, cardinality: 'one', binding: [byId, fromBody] },
34
- delete: { cardinality: 'none', binding: [byId] },
61
+ update: {
62
+ input: entity.partial?.(), output: entity, cardinality: 'one', binding: [byId, fromBody],
63
+ signature: { name: 'update', returnType: returns(name, name), params: [idParam, input] },
64
+ },
65
+ delete: {
66
+ cardinality: 'none', binding: [byId],
67
+ signature: { name: 'delete', returnType: returns('boolean', 'boolean'), params: [idParam] },
68
+ },
35
69
  };
36
70
  }
37
71
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.js","sourceRoot":"","sources":["../../src/prefab/crud.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { type EntityConstructor } from '@fougere/schema';
2
+ import type { EntityOrm } from '../orm.js';
3
+ /**
4
+ * A paginated local copy of a source that cannot be queried directly.
5
+ *
6
+ * The shape must contain an `updated()` field used as a high-water mark. Subclasses
7
+ * implement `pull`; `refresh` validates and upserts each returned page.
8
+ *
9
+ * ```ts
10
+ * export default class PartnerCatalog extends Mirror(BookCard) {
11
+ * constructor(orm: EntityOrm<BookCard>, private catalog: Facade<CatalogHandler>) {
12
+ * super(orm);
13
+ * }
14
+ *
15
+ * async *pull(since?: Date) {
16
+ * for (let page = 0; page !== null;) {
17
+ * const body = await fetch(`${api}?page=${page}&since=${since?.toISOString() ?? ''}`);
18
+ * const { items, next } = await body.json();
19
+ * yield items.map(toCard);
20
+ * page = next;
21
+ * }
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+ /** What one refresh did — enough to log it, and to decide whether to run again. */
27
+ export interface Refreshed {
28
+ /** Rows written, counting a replaced row once. */
29
+ written: number;
30
+ /** The age the pull was asked to start from — absent on the first ever run. */
31
+ since?: Date;
32
+ /** How long the whole pass took, pull included. */
33
+ ms: number;
34
+ }
35
+ export interface MirrorOf<T> {
36
+ /** The copy's own storage — where a page lands, and where its age is read. */
37
+ orm: EntityOrm<T>;
38
+ /** Pages of rows to write. The one thing a mirror's author supplies. */
39
+ pull(since?: Date): AsyncIterable<Partial<T>[]>;
40
+ /** Run one pass: read the high-water mark, pull from there, write each page. */
41
+ refresh(): Promise<Refreshed>;
42
+ /** When the freshest row here was written — `undefined` while the copy is empty. */
43
+ freshness(): Promise<Date | undefined>;
44
+ }
45
+ export interface MirrorConstructor<T> {
46
+ new (orm: EntityOrm<T>): MirrorOf<T>;
47
+ readonly __entity: unknown;
48
+ }
49
+ export declare function Mirror<E extends EntityConstructor>(shape: E): MirrorConstructor<InstanceType<E>>;
50
+ /** The field whose lifecycle stamps every update. */
51
+ export declare function ageFieldOf(shape: unknown): string | undefined;
52
+ //# sourceMappingURL=mirror.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../src/prefab/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,iBAAiB,EAAsC,MAAM,iBAAiB,CAAC;AACxH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,8EAA8E;IAC9E,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAClB,wEAAwE;IACxE,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAChD,gFAAgF;IAChF,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IAC9B,oFAAoF;IACpF,SAAS,IAAI,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,iBAAiB,EAAE,KAAK,EAAE,CAAC,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAyChG;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAO7D"}
@@ -0,0 +1,66 @@
1
+ import { Lifecycle, primaryFieldOf } from '@fougere/schema';
2
+ export function Mirror(shape) {
3
+ // Refuse an undated copy before it can be used as if it held live rows.
4
+ const declared = ageFieldOf(shape);
5
+ if (declared === undefined) {
6
+ throw new Error(`Mirror(${shape.name ?? '?'}): the shape carries no \`updated()\` field — ` +
7
+ `a copy has to be able to say when it was pulled, and \`refresh\` reads its high-water mark from it.`);
8
+ }
9
+ const age = declared;
10
+ class MirrorBase {
11
+ orm;
12
+ static __entity = shape;
13
+ constructor(orm) {
14
+ this.orm = orm;
15
+ }
16
+ /** The freshest persisted stamp; no process-local freshness state is kept. */
17
+ async freshness() {
18
+ const [newest] = await this.orm.list({ orderBy: age, order: 'desc', limit: 1 });
19
+ const value = newest?.[age];
20
+ return value instanceof Date ? value : undefined;
21
+ }
22
+ async refresh() {
23
+ const started = Date.now();
24
+ const since = await this.freshness();
25
+ let written = 0;
26
+ // Preserve the source's page boundaries: one page becomes one upsert.
27
+ for await (const page of this.pull(since)) {
28
+ if (page.length === 0)
29
+ continue;
30
+ written += await this.orm.upsertAll(judgePage(shape, page));
31
+ }
32
+ return { written, since, ms: Date.now() - started };
33
+ }
34
+ }
35
+ return MirrorBase;
36
+ }
37
+ /** The field whose lifecycle stamps every update. */
38
+ export function ageFieldOf(shape) {
39
+ const fields = shape.getFields?.();
40
+ if (!fields)
41
+ return undefined;
42
+ for (const [name, field] of Object.entries(fields)) {
43
+ if (Lifecycle.of(field).stampedOnUpdate)
44
+ return name;
45
+ }
46
+ return undefined;
47
+ }
48
+ /** Validate and decode a page, naming a refused row by its declared primary field. */
49
+ function judgePage(shape, page) {
50
+ const judge = shape.validate;
51
+ if (typeof judge !== 'function')
52
+ return page;
53
+ const name = shape.name ?? 'mirror';
54
+ const fields = shape.getFields?.();
55
+ const primary = fields ? primaryFieldOf(fields) : undefined;
56
+ return page.map((row, index) => {
57
+ const verdict = judge.call(shape, row);
58
+ if (verdict.success)
59
+ return verdict.data;
60
+ const key = primary === undefined ? undefined : row[primary];
61
+ const where = key !== undefined ? `row ${primary} ${JSON.stringify(key)}` : `row ${index} of this page`;
62
+ const why = verdict.errors.map((e) => `${e.path}: ${e.message}`).join(', ');
63
+ throw new Error(`${name} mirror refused ${where} — ${why}`);
64
+ });
65
+ }
66
+ //# sourceMappingURL=mirror.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/prefab/mirror.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { EntityConstructor } from '@fougere/schema';
2
+ import type { PresenterViews } from './presenter.js';
3
+ /**
4
+ * The shape a prefab was built on, or `undefined` when the class is not one.
5
+ *
6
+ * A plain property read: JavaScript walks a constructor's own prototype chain, so a
7
+ * subclass of a prefab answers what its base recorded. Three of the five accessors this
8
+ * replaces walked that chain by hand, and two did not — one question, two mechanisms.
9
+ */
10
+ export declare function targetOf(ctor: unknown): EntityConstructor | undefined;
11
+ /** The views a prefab declares, same rule. */
12
+ export declare function viewsOf(ctor: unknown): PresenterViews | undefined;
13
+ /** The handler-wide view a prefab declares, same rule. */
14
+ export declare function outputOf(ctor: unknown): EntityConstructor | undefined;
15
+ //# sourceMappingURL=prefab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefab.d.ts","sourceRoot":"","sources":["../../src/prefab/prefab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAyBrD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAErE;AAED,8CAA8C;AAC9C,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAEjE;AAED,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAErE"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The shape a prefab was built on, or `undefined` when the class is not one.
3
+ *
4
+ * A plain property read: JavaScript walks a constructor's own prototype chain, so a
5
+ * subclass of a prefab answers what its base recorded. Three of the five accessors this
6
+ * replaces walked that chain by hand, and two did not — one question, two mechanisms.
7
+ */
8
+ export function targetOf(ctor) {
9
+ return ctor?.__entity;
10
+ }
11
+ /** The views a prefab declares, same rule. */
12
+ export function viewsOf(ctor) {
13
+ return ctor?.__views;
14
+ }
15
+ /** The handler-wide view a prefab declares, same rule. */
16
+ export function outputOf(ctor) {
17
+ return ctor?.__output;
18
+ }
19
+ //# sourceMappingURL=prefab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefab.js","sourceRoot":"","sources":["../../src/prefab/prefab.ts"],"names":[],"mappings":"AA0BA;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAQ,IAA2B,EAAE,QAAQ,CAAC;AAChD,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,OAAO,CAAC,IAAa;IACnC,OAAQ,IAA2B,EAAE,OAAO,CAAC;AAC/C,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,QAAQ,CAAC,IAAa;IACpC,OAAQ,IAA2B,EAAE,QAAQ,CAAC;AAChD,CAAC"}
@@ -21,19 +21,17 @@
21
21
  * }
22
22
  * ```
23
23
  */
24
- type EntityClass = abstract new (...args: any[]) => any;
25
- declare const PRESENTER_TARGET: unique symbol;
26
- declare const PRESENTER_VIEWS: unique symbol;
24
+ import { type EntityConstructor } from '@fougere/schema';
27
25
  /**
28
26
  * The view a computed field emits — `OrderItemView` for one, `[OrderItemView]` for many.
29
27
  * A view is a schema, so it derives: `Order.pick('id', 'status')`, never a hand-written type.
30
28
  */
31
- export type PresenterViews = Record<string, EntityClass | [EntityClass]>;
29
+ export type PresenterViews = Record<string, EntityConstructor | [EntityConstructor]>;
32
30
  /**
33
31
  * `Presenter(Order, { items: [OrderItemView], user: UserCard })` — the second argument names
34
32
  * the view each computed field emits, exactly as `Crud(Post, { list: PostCard })` names an
35
33
  * op's. What fabricates a field declares its contract, and it declares it **once**: the
36
- * façade applies the presenter (see `egress.ts`), and every surface reads the same statement
34
+ * façade applies the presenter (see `PresenterExecutor`), and every surface reads the same statement
37
35
  * instead of guessing.
38
36
  *
39
37
  * Guessing was the cost of not stating it. The scan can read a scalar off a return type and
@@ -42,22 +40,13 @@ export type PresenterViews = Record<string, EntityClass | [EntityClass]>;
42
40
  * error on a field REST served whole. Declaring is optional — a scalar field needs nothing,
43
41
  * and an undeclared object keeps the old behaviour.
44
42
  */
45
- export declare function Presenter<E extends EntityClass>(entity: E, views?: PresenterViews): {
43
+ export declare function Presenter<E extends EntityConstructor>(entity: E, views?: PresenterViews): {
46
44
  new (): {};
47
- [PRESENTER_TARGET]: E;
48
- [PRESENTER_VIEWS]: PresenterViews | undefined;
45
+ readonly __entity: E;
46
+ readonly __views: PresenterViews | undefined;
49
47
  };
50
- /** Get the entity class a presenter targets. */
51
- export declare function getPresenterTarget(ctor: Function): EntityClass | undefined;
52
- /**
53
- * The views a presenter declares, walked up the prototype chain so a subclass of a
54
- * presenter keeps what its base stated. Runtime, like `Crud.__ops`: an installed app whose
55
- * source the scan cannot read still carries its contract.
56
- */
57
- export declare function getPresenterViews(ctor: Function): PresenterViews | undefined;
58
48
  /** List computed field names from a presenter class (own methods minus constructor). */
59
49
  export declare function getPresenterFields(ctor: Function): string[];
60
50
  /** Container key of an entity's presenter — 'post' → 'PostPresenter'. */
61
51
  export declare function presenterKeyOf(entity: string): string;
62
- export {};
63
52
  //# sourceMappingURL=presenter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.d.ts","sourceRoot":"","sources":["../../src/prefab/presenter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEtE;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;AAErF;;;;;;;;;;;;GAYG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,cAAc;;;;EAMvF;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAG3D;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD"}
@@ -21,13 +21,12 @@
21
21
  * }
22
22
  * ```
23
23
  */
24
- const PRESENTER_TARGET = Symbol.for('fougere:presenter_target');
25
- const PRESENTER_VIEWS = Symbol.for('fougere:presenter_views');
24
+ import { classNameOf } from '@fougere/schema';
26
25
  /**
27
26
  * `Presenter(Order, { items: [OrderItemView], user: UserCard })` — the second argument names
28
27
  * the view each computed field emits, exactly as `Crud(Post, { list: PostCard })` names an
29
28
  * op's. What fabricates a field declares its contract, and it declares it **once**: the
30
- * façade applies the presenter (see `egress.ts`), and every surface reads the same statement
29
+ * façade applies the presenter (see `PresenterExecutor`), and every surface reads the same statement
31
30
  * instead of guessing.
32
31
  *
33
32
  * Guessing was the cost of not stating it. The scan can read a scalar off a return type and
@@ -38,28 +37,11 @@ const PRESENTER_VIEWS = Symbol.for('fougere:presenter_views');
38
37
  */
39
38
  export function Presenter(entity, views) {
40
39
  class PresenterBase {
41
- static [PRESENTER_TARGET] = entity;
42
- static [PRESENTER_VIEWS] = views;
40
+ static __entity = entity;
41
+ static __views = views;
43
42
  }
44
43
  return PresenterBase;
45
44
  }
46
- /** Get the entity class a presenter targets. */
47
- export function getPresenterTarget(ctor) {
48
- return ctor[PRESENTER_TARGET];
49
- }
50
- /**
51
- * The views a presenter declares, walked up the prototype chain so a subclass of a
52
- * presenter keeps what its base stated. Runtime, like `Crud.__ops`: an installed app whose
53
- * source the scan cannot read still carries its contract.
54
- */
55
- export function getPresenterViews(ctor) {
56
- for (let cur = ctor; cur; cur = Object.getPrototypeOf(cur)) {
57
- const views = cur[PRESENTER_VIEWS];
58
- if (views)
59
- return views;
60
- }
61
- return undefined;
62
- }
63
45
  /** List computed field names from a presenter class (own methods minus constructor). */
64
46
  export function getPresenterFields(ctor) {
65
47
  return Object.getOwnPropertyNames(ctor.prototype)
@@ -67,6 +49,6 @@ export function getPresenterFields(ctor) {
67
49
  }
68
50
  /** Container key of an entity's presenter — 'post' → 'PostPresenter'. */
69
51
  export function presenterKeyOf(entity) {
70
- return `${entity[0].toUpperCase()}${entity.slice(1)}Presenter`;
52
+ return `${classNameOf(entity)}Presenter`;
71
53
  }
72
54
  //# sourceMappingURL=presenter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter.js","sourceRoot":"","sources":["../../src/prefab/presenter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,WAAW,EAA0B,MAAM,iBAAiB,CAAC;AAQtE;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAA8B,MAAS,EAAE,KAAsB;IACtF,MAAM,aAAa;QACjB,MAAM,CAAU,QAAQ,GAAG,MAAM,CAAC;QAClC,MAAM,CAAU,OAAO,GAAG,KAAK,CAAC;;IAElC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC/C,OAAO,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC;SAC9C,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,aAAa,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC;AAC5F,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,104 @@
1
+ import { type EntityConstructor } from '@fougere/schema';
2
+ import type { EntityOrm } from '../orm.js';
3
+ /**
4
+ * Repository(…entities) — who owns an entity's storage, and where its questions are named.
5
+ *
6
+ * **The arity decides**, which is the second reading of what `orm.ts` already states for
7
+ * `EntityOrm` against `Together`: the arity of the unit is the whole distinction.
8
+ *
9
+ * ONE entity — the repository IS that entity's storage, with your methods added. The port's
10
+ * thirteen gestures are forwarded, so a handler reads `this.posts.list()` whether or not
11
+ * anyone wrote the file, and a named question sits beside them:
12
+ *
13
+ * ```ts
14
+ * // repositories/PostRepository.ts
15
+ * export default class PostRepository extends Repository(Post) {
16
+ * published() {
17
+ * return this.list({ where: { status: 'published' }, orderBy: 'publishedAt', order: 'desc' });
18
+ * }
19
+ * }
20
+ * ```
21
+ *
22
+ * TWO OR MORE — an aggregate. It owns them: nothing else in the app is handed their
23
+ * storage, and no gesture is forwarded (which entity would `create` write to?), so the only
24
+ * way in is a method this class names. That is what lets a rule spanning two tables exist:
25
+ * it is ordinary TypeScript inside the method that does the writing.
26
+ *
27
+ * ```ts
28
+ * // repositories/CommandeRepository.ts
29
+ * export default class CommandeRepository extends Repository(Commande, Stock) {
30
+ * avecLignes(id: string) {
31
+ * const [commandes, stock] = this.orms;
32
+ * …
33
+ * }
34
+ * }
35
+ * ```
36
+ *
37
+ * `this.orms` is protected, because the whole point is that the storage stops at this file.
38
+ * `protected` is erased at runtime, like `abstract` on a port: a compile-time guarantee, not
39
+ * a barrier. The same bargain, already accepted.
40
+ *
41
+ * **The boundary is not the unit of work.** An aggregate says the rules of these entities
42
+ * hold together; a frame says these writes land together, and the two lists coincide only
43
+ * often. Deriving the frame from the membership would make a read-only aggregate carry one
44
+ * — refusals included, and `registerFrames` refuses without storage or over `remotes:` —
45
+ * and would put `Together<[Commande, Stock], [StockMirror]>` out of reach forever. So a
46
+ * frame is ASKED FOR here as anywhere else, which is what makes it declared:
47
+ *
48
+ * ```ts
49
+ * constructor(commandes: CommandeOrm, stock: StockOrm, private frame: Together<[Commande, Stock]>) {
50
+ * super(commandes, stock);
51
+ * }
52
+ * ```
53
+ *
54
+ * The ORM words come back in that line, and only there: this class IS the holder, which is
55
+ * the one case `boot/ownership.ts` lets name the storage it was built on.
56
+ *
57
+ * A repository is NOT a door: it has no façade, so nothing here is reachable from the wire.
58
+ */
59
+ /**
60
+ * The shape a repository of ONE entity has — the port itself, plus whatever the subclass
61
+ * names on top. Written by an author who has not written the file: `RepositoryOf<Post>` is
62
+ * to `PostRepository` what `EntityOrm<Post>` is to `PostOrm`, one spelling of one key, and
63
+ * `depKeyOf` reads both.
64
+ */
65
+ export type RepositoryOf<T> = EntityOrm<T>;
66
+ /** The single-entity form: the port, plus whatever the subclass names. */
67
+ export interface RepositoryConstructor<T> {
68
+ new (orm: EntityOrm<T>): EntityOrm<T>;
69
+ readonly __entity: unknown;
70
+ }
71
+ /**
72
+ * What an aggregate's subclass sees: the storage of the members it owns, in declared order,
73
+ * and `protected` — the storage stops at that file, which is the whole mechanism.
74
+ *
75
+ * A class and not an interface, because `protected` cannot be spelled in one. Ambient: the
76
+ * value it describes is fabricated by `many()` for an arity only known at the call.
77
+ */
78
+ declare abstract class AggregateShape<E extends readonly EntityConstructor[]> {
79
+ protected orms: {
80
+ [K in keyof E]: EntityOrm<InstanceType<E[K]>>;
81
+ };
82
+ }
83
+ /** The tuple an aggregate holds — the readable form of {@link AggregateShape}'s member. */
84
+ export type AggregateOf<E extends readonly EntityConstructor[]> = {
85
+ [K in keyof E]: EntityOrm<InstanceType<E[K]>>;
86
+ };
87
+ export type AggregateConstructor<E extends readonly EntityConstructor[]> = (new (...orms: unknown[]) => AggregateShape<E>) & {
88
+ readonly __entity: unknown;
89
+ /** The entities this class owns. Present from two on — an owner of one owns nothing. */
90
+ readonly __owns: E;
91
+ };
92
+ export declare function Repository<E extends EntityConstructor>(entity: E): RepositoryConstructor<InstanceType<E>>;
93
+ export declare function Repository<E extends readonly [EntityConstructor, EntityConstructor, ...EntityConstructor[]]>(...entities: E): AggregateConstructor<E>;
94
+ /** Container key of an entity's repository — 'reading' → 'ReadingRepository'. */
95
+ export declare function repositoryKeyOf(entity: string): string;
96
+ /**
97
+ * The entities a class owns — empty for anything that is not an aggregate.
98
+ *
99
+ * Read from the mark rather than from the constructor, for the reason `Crud.__ops` exists:
100
+ * the AST scan is workspace-only, so an installed prefab resolves to nothing.
101
+ */
102
+ export declare function ownedBy(ctor: unknown): readonly EntityConstructor[];
103
+ export {};
104
+ //# sourceMappingURL=repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/prefab/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAyC,MAAM,WAAW,CAAC;AAGlF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC;AAE3C,0EAA0E;AAC1E,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,KAAK,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,OAAO,CAAC,QAAQ,OAAO,cAAc,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE;IAC1E,SAAS,CAAC,IAAI,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;KAAE,CAAC;CACnE;AAED,2FAA2F;AAC3F,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,IAC5D;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC;AAEpD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,SAAS,iBAAiB,EAAE,IACrE,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG;IAChD,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;CACpB,CAAC;AAEJ,wBAAgB,UAAU,CAAC,CAAC,SAAS,iBAAiB,EAAE,MAAM,EAAE,CAAC,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3G,wBAAgB,UAAU,CAAC,CAAC,SAAS,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CAAC,EAC1G,GAAG,QAAQ,EAAE,CAAC,GACb,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAwD3B,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,iBAAiB,EAAE,CAEnE"}
@@ -0,0 +1,62 @@
1
+ import { classNameOf } from '@fougere/schema';
2
+ export function Repository(...entities) {
3
+ return entities.length === 1 ? one(entities[0]) : many(entities);
4
+ }
5
+ /**
6
+ * The port forwarded, member by member. Written out rather than proxied: a Proxy would
7
+ * answer every name including the ones the port does not have, and this file would then
8
+ * state the surface nowhere. Thirteen lines against one declaration that can be read.
9
+ */
10
+ function one(entity) {
11
+ class RepositoryBase {
12
+ orm;
13
+ static __entity = entity;
14
+ constructor(orm) {
15
+ this.orm = orm;
16
+ }
17
+ list(options) { return this.orm.list(options); }
18
+ findById(id, options) { return this.orm.findById(id, options); }
19
+ findBy(criteria, options) { return this.orm.findBy(criteria, options); }
20
+ findAllBy(criteria, options) { return this.orm.findAllBy(criteria, options); }
21
+ findByKeys(ids, options) { return this.orm.findByKeys(ids, options); }
22
+ findAllByKeys(field, keys, options) { return this.orm.findAllByKeys(field, keys, options); }
23
+ create(input, options) { return this.orm.create(input, options); }
24
+ upsert(input, options) { return this.orm.upsert(input, options); }
25
+ upsertAll(inputs, options) { return this.orm.upsertAll(inputs, options); }
26
+ update(id, input, options) { return this.orm.update(id, input, options); }
27
+ delete(id) { return this.orm.delete(id); }
28
+ output(schema) { return this.orm.output(schema); }
29
+ get client() { return this.orm.client; }
30
+ }
31
+ return RepositoryBase;
32
+ }
33
+ /**
34
+ * The aggregate. Its constructor takes the members' storage in the DECLARED order — the
35
+ * order `toProvider` fills its `deps` with, and the order a subclass hands back to `super()`
36
+ * when it declares a constructor of its own.
37
+ */
38
+ function many(entities) {
39
+ class AggregateBase {
40
+ static __entity = entities[0];
41
+ static __owns = entities;
42
+ orms;
43
+ constructor(...orms) {
44
+ this.orms = orms.slice(0, entities.length);
45
+ }
46
+ }
47
+ return AggregateBase;
48
+ }
49
+ /** Container key of an entity's repository — 'reading' → 'ReadingRepository'. */
50
+ export function repositoryKeyOf(entity) {
51
+ return `${classNameOf(entity)}Repository`;
52
+ }
53
+ /**
54
+ * The entities a class owns — empty for anything that is not an aggregate.
55
+ *
56
+ * Read from the mark rather than from the constructor, for the reason `Crud.__ops` exists:
57
+ * the AST scan is workspace-only, so an installed prefab resolves to nothing.
58
+ */
59
+ export function ownedBy(ctor) {
60
+ return ctor?.__owns ?? [];
61
+ }
62
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/prefab/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { SchemaView } from '@fougere/schema';
2
+ import type { EntityEntry, FrondDescriptor } from './frond.js';
3
+ /**
4
+ * What this app hosts — the scan's answer, with the questions everyone was asking it
5
+ * 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
+ */
17
+ export declare class Fronds extends Array<FrondDescriptor> {
18
+ static get [Symbol.species](): ArrayConstructor;
19
+ /** What one scan run found. The only gate in — `Array.of` is taken, and named. */
20
+ static scanned(fronds: readonly FrondDescriptor[]): Fronds;
21
+ /** The frond that hosts an entity — `undefined` when no loaded frond does. */
22
+ owner(entity: string): FrondDescriptor | undefined;
23
+ /** The entity of that name, wherever it was scanned. */
24
+ entity(name: string): EntityEntry | undefined;
25
+ /**
26
+ * Every scanned entity class, by name — across all fronds and never per-frond.
27
+ *
28
+ * A fact is announced in one frond and heard in another, so the subscriber's own
29
+ * frond does not hold the shape it must judge; a `reads:` clause names entities
30
+ * that belong to neighbours by definition.
31
+ */
32
+ schemas(): Map<string, SchemaView>;
33
+ /** Every scanned entity, sorted. What was FOUND, not what answers. */
34
+ entityNames(): string[];
35
+ /**
36
+ * The names a call may address, sorted — what a NOT_FOUND must print.
37
+ *
38
+ * Not `entityNames()`, which is what the scan found: an entity with no handler is
39
+ * scanned and serves nothing, so the refusal read *"Entity 'indexed' is not hosted
40
+ * here. Hosted here: indexed."* — naming the very thing it had just refused. A façade
41
+ * is keyed on a HANDLER's address, and that is what this lists.
42
+ */
43
+ servedNames(surface?: string): string[];
44
+ }
45
+ //# sourceMappingURL=Fronds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Fronds.d.ts","sourceRoot":"","sources":["../../src/scan/Fronds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE/D;;;;;;;;;;;;;GAaG;AACH,qBAAa,MAAO,SAAQ,KAAK,CAAC,eAAe,CAAC;IAChD,WAAoB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,gBAAgB,CAEvD;IAED,kFAAkF;IAClF,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,GAAG,MAAM;IAM1D,8EAA8E;IAC9E,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIlD,wDAAwD;IACxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAQ7C;;;;;;OAMG;IACH,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;IAIlC,sEAAsE;IACtE,WAAW,IAAI,MAAM,EAAE;IAIvB;;;;;;;OAOG;IACH,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;CAKxC"}