@fougere/core 0.5.0-alpha.1 → 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.
- package/README.md +1 -1
- package/dist/boot/Emissions.d.ts +14 -91
- package/dist/boot/Emissions.d.ts.map +1 -1
- package/dist/boot/Emissions.js +21 -118
- package/dist/boot/Emissions.js.map +1 -1
- package/dist/boot/ambient-port.d.ts +3 -24
- package/dist/boot/ambient-port.d.ts.map +1 -1
- package/dist/boot/ambient.als.d.ts.map +1 -1
- package/dist/boot/ambient.als.js +7 -12
- package/dist/boot/ambient.als.js.map +1 -1
- package/dist/boot/ambient.queue.d.ts +2 -5
- package/dist/boot/ambient.queue.d.ts.map +1 -1
- package/dist/boot/ambient.queue.js.map +1 -1
- package/dist/boot/apply.d.ts +1 -13
- package/dist/boot/apply.d.ts.map +1 -1
- package/dist/boot/apply.js +3 -15
- package/dist/boot/apply.js.map +1 -1
- package/dist/boot/auth.d.ts +6 -16
- package/dist/boot/auth.d.ts.map +1 -1
- package/dist/boot/boot.d.ts +5 -18
- package/dist/boot/boot.d.ts.map +1 -1
- package/dist/boot/boot.js +4 -11
- package/dist/boot/boot.js.map +1 -1
- package/dist/boot/bootstrap.d.ts.map +1 -1
- package/dist/boot/bootstrap.js +106 -163
- package/dist/boot/bootstrap.js.map +1 -1
- package/dist/boot/card.d.ts +5 -0
- package/dist/boot/card.d.ts.map +1 -0
- package/dist/boot/card.js +71 -0
- package/dist/boot/card.js.map +1 -0
- package/dist/boot/frame.d.ts +8 -32
- package/dist/boot/frame.d.ts.map +1 -1
- package/dist/boot/frame.js +23 -57
- package/dist/boot/frame.js.map +1 -1
- package/dist/boot/hosted.d.ts +3 -19
- package/dist/boot/hosted.d.ts.map +1 -1
- package/dist/boot/hosted.js +12 -17
- package/dist/boot/hosted.js.map +1 -1
- package/dist/boot/ownership.d.ts +5 -36
- package/dist/boot/ownership.d.ts.map +1 -1
- package/dist/boot/ownership.js +9 -49
- package/dist/boot/ownership.js.map +1 -1
- package/dist/boot/ports.d.ts +2 -15
- package/dist/boot/ports.d.ts.map +1 -1
- package/dist/boot/ports.js +1 -14
- package/dist/boot/ports.js.map +1 -1
- package/dist/boot/remote.d.ts +5 -38
- package/dist/boot/remote.d.ts.map +1 -1
- package/dist/boot/remote.js +8 -41
- package/dist/boot/remote.js.map +1 -1
- package/dist/boot/runner.d.ts +11 -0
- package/dist/boot/runner.d.ts.map +1 -0
- package/dist/boot/runner.js +13 -0
- package/dist/boot/runner.js.map +1 -0
- package/dist/boot/seed.d.ts +5 -32
- package/dist/boot/seed.d.ts.map +1 -1
- package/dist/boot/seed.js +10 -41
- package/dist/boot/seed.js.map +1 -1
- package/dist/boot/statement-drift.d.ts +4 -22
- package/dist/boot/statement-drift.d.ts.map +1 -1
- package/dist/boot/statement-drift.js +4 -9
- package/dist/boot/statement-drift.js.map +1 -1
- package/dist/boot/together.d.ts +8 -12
- package/dist/boot/together.d.ts.map +1 -1
- package/dist/boot/together.js +28 -65
- package/dist/boot/together.js.map +1 -1
- package/dist/boot/types.d.ts +36 -180
- package/dist/boot/types.d.ts.map +1 -1
- package/dist/builtin/config.d.ts +7 -0
- package/dist/builtin/config.d.ts.map +1 -0
- package/dist/builtin/config.js +15 -0
- package/dist/builtin/config.js.map +1 -0
- package/dist/{builtins → builtin}/logger.d.ts +4 -25
- package/dist/builtin/logger.d.ts.map +1 -0
- package/dist/{builtins → builtin}/logger.js +5 -32
- package/dist/builtin/logger.js.map +1 -0
- package/dist/config-loader.d.ts +9 -67
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/config-loader.js +5 -18
- package/dist/config-loader.js.map +1 -1
- package/dist/contract.d.ts +13 -31
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +10 -26
- package/dist/contract.js.map +1 -1
- package/dist/crypto/encoding.d.ts +2 -15
- package/dist/crypto/encoding.d.ts.map +1 -1
- package/dist/crypto/encoding.js +2 -15
- package/dist/crypto/encoding.js.map +1 -1
- package/dist/crypto/node.d.ts.map +1 -1
- package/dist/crypto/node.js +1 -7
- package/dist/crypto/node.js.map +1 -1
- package/dist/crypto/port.d.ts +2 -18
- package/dist/crypto/port.d.ts.map +1 -1
- package/dist/crypto/port.js +1 -17
- package/dist/crypto/port.js.map +1 -1
- package/dist/crypto/webcrypto.d.ts.map +1 -1
- package/dist/crypto/webcrypto.js +1 -12
- package/dist/crypto/webcrypto.js.map +1 -1
- package/dist/declare.d.ts +41 -0
- package/dist/declare.d.ts.map +1 -0
- package/dist/{scan/declare.js → declare.js} +6 -31
- package/dist/declare.js.map +1 -0
- package/dist/define.d.ts +2 -3
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +2 -3
- package/dist/define.js.map +1 -1
- package/dist/descriptor/Fronds.d.ts +19 -0
- package/dist/descriptor/Fronds.d.ts.map +1 -0
- package/dist/descriptor/Fronds.js +40 -0
- package/dist/descriptor/Fronds.js.map +1 -0
- package/dist/descriptor/frond.d.ts +135 -0
- package/dist/descriptor/frond.d.ts.map +1 -0
- package/dist/{scan → descriptor}/frond.js.map +1 -1
- package/dist/dispatch/ArgumentResolver.d.ts +6 -3
- package/dist/dispatch/ArgumentResolver.d.ts.map +1 -1
- package/dist/dispatch/ArgumentResolver.js +48 -3
- package/dist/dispatch/ArgumentResolver.js.map +1 -1
- package/dist/dispatch/DispatchEvent.d.ts +2 -2
- package/dist/dispatch/DispatchEvent.d.ts.map +1 -1
- package/dist/dispatch/DispatchLifecycle.d.ts +1 -7
- package/dist/dispatch/DispatchLifecycle.d.ts.map +1 -1
- package/dist/dispatch/DispatchLifecycle.js +1 -7
- package/dist/dispatch/DispatchLifecycle.js.map +1 -1
- package/dist/dispatch/DispatchPort.d.ts +1 -1
- package/dist/dispatch/DispatchPort.d.ts.map +1 -1
- package/dist/dispatch/Dispatcher.d.ts +1 -1
- package/dist/dispatch/Dispatcher.d.ts.map +1 -1
- package/dist/dispatch/Dispatcher.js +2 -2
- package/dist/dispatch/Dispatcher.js.map +1 -1
- package/dist/{boot → dispatch}/HandlerFacade.d.ts +25 -38
- package/dist/dispatch/HandlerFacade.d.ts.map +1 -0
- package/dist/{boot → dispatch}/HandlerFacade.js +65 -74
- package/dist/dispatch/HandlerFacade.js.map +1 -0
- package/dist/dispatch/LocalRoutePolicy.d.ts +1 -1
- package/dist/dispatch/LocalRoutePolicy.d.ts.map +1 -1
- package/dist/dispatch/LocalRoutePolicy.js +4 -4
- package/dist/dispatch/LocalRoutePolicy.js.map +1 -1
- package/dist/dispatch/OperationRoute.d.ts +2 -2
- package/dist/dispatch/OperationRoute.d.ts.map +1 -1
- package/dist/dispatch/OutputView.d.ts +3 -2
- package/dist/dispatch/OutputView.d.ts.map +1 -1
- package/dist/dispatch/OutputView.js +19 -1
- package/dist/dispatch/OutputView.js.map +1 -1
- package/dist/dispatch/Route.d.ts +2 -3
- package/dist/dispatch/Route.d.ts.map +1 -1
- package/dist/dispatch/RoutePolicy.d.ts +1 -1
- package/dist/dispatch/RoutePolicy.d.ts.map +1 -1
- package/dist/dispatch/RouteRegistry.d.ts +1 -1
- package/dist/dispatch/RouteRegistry.d.ts.map +1 -1
- package/dist/dispatch/RouteRegistry.js +2 -2
- package/dist/dispatch/RouteRegistry.js.map +1 -1
- package/dist/dispatch/RouteResolver.d.ts +2 -4
- package/dist/dispatch/RouteResolver.d.ts.map +1 -1
- package/dist/dispatch/StorageGuard.d.ts +9 -8
- package/dist/dispatch/StorageGuard.d.ts.map +1 -1
- package/dist/dispatch/StorageGuard.js +66 -23
- package/dist/dispatch/StorageGuard.js.map +1 -1
- package/dist/dispatch/presenterArguments.d.ts +7 -0
- package/dist/dispatch/presenterArguments.d.ts.map +1 -0
- package/dist/dispatch/presenterArguments.js +12 -0
- package/dist/dispatch/presenterArguments.js.map +1 -0
- package/dist/dispatch/remoteRoutes.d.ts +7 -0
- package/dist/dispatch/remoteRoutes.d.ts.map +1 -0
- package/dist/dispatch/{RemoteRouteResolver.js → remoteRoutes.js} +6 -10
- package/dist/dispatch/remoteRoutes.js.map +1 -0
- package/dist/dispatch/routeNotFound.d.ts +9 -0
- package/dist/dispatch/routeNotFound.d.ts.map +1 -0
- package/dist/dispatch/routeNotFound.js +21 -0
- package/dist/dispatch/routeNotFound.js.map +1 -0
- package/dist/dispatch/validateInput.d.ts +5 -0
- package/dist/dispatch/validateInput.d.ts.map +1 -0
- package/dist/dispatch/validateInput.js +20 -0
- package/dist/dispatch/validateInput.js.map +1 -0
- package/dist/effective-operation.d.ts +6 -3
- package/dist/effective-operation.d.ts.map +1 -1
- package/dist/effective-operation.js +49 -27
- package/dist/effective-operation.js.map +1 -1
- package/dist/emit.d.ts +4 -42
- package/dist/emit.d.ts.map +1 -1
- package/dist/emit.js +3 -39
- package/dist/emit.js.map +1 -1
- package/dist/entry/facade.d.ts +8 -0
- package/dist/entry/facade.d.ts.map +1 -0
- package/dist/entry/facade.js +28 -0
- package/dist/entry/facade.js.map +1 -0
- package/dist/entry/transport.d.ts +5 -0
- package/dist/entry/transport.d.ts.map +1 -0
- package/dist/entry/transport.js +11 -0
- package/dist/entry/transport.js.map +1 -0
- package/dist/frond-config.d.ts +8 -71
- package/dist/frond-config.d.ts.map +1 -1
- package/dist/frond-config.js +1 -9
- package/dist/frond-config.js.map +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/graph.d.ts.map +1 -1
- package/dist/identity-keys.d.ts +2 -5
- package/dist/identity-keys.d.ts.map +1 -1
- package/dist/identity-keys.js +3 -16
- package/dist/identity-keys.js.map +1 -1
- package/dist/identity.d.ts +4 -30
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +11 -73
- package/dist/identity.js.map +1 -1
- package/dist/imports.d.ts +2 -8
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +1 -7
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +28 -30
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -22
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +1 -8
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +1 -8
- package/dist/loader.js.map +1 -1
- package/dist/node.d.ts +2 -11
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +2 -11
- package/dist/node.js.map +1 -1
- package/dist/prefab/collector.d.ts +1 -22
- package/dist/prefab/collector.d.ts.map +1 -1
- package/dist/prefab/collector.js +1 -22
- package/dist/prefab/collector.js.map +1 -1
- package/dist/prefab/crud.d.ts +19 -35
- package/dist/prefab/crud.d.ts.map +1 -1
- package/dist/prefab/crud.js +39 -66
- package/dist/prefab/crud.js.map +1 -1
- package/dist/prefab/mirror.d.ts +5 -27
- package/dist/prefab/mirror.d.ts.map +1 -1
- package/dist/prefab/mirror.js +6 -24
- package/dist/prefab/mirror.js.map +1 -1
- package/dist/prefab/prefab.d.ts +1 -7
- package/dist/prefab/prefab.d.ts.map +1 -1
- package/dist/prefab/prefab.js +1 -7
- package/dist/prefab/prefab.js.map +1 -1
- package/dist/prefab/presenter.d.ts +2 -36
- package/dist/prefab/presenter.d.ts.map +1 -1
- package/dist/prefab/presenter.js +2 -36
- package/dist/prefab/presenter.js.map +1 -1
- package/dist/prefab/repository.d.ts +12 -80
- package/dist/prefab/repository.d.ts.map +1 -1
- package/dist/prefab/repository.js +22 -35
- package/dist/prefab/repository.js.map +1 -1
- package/dist/scan/adapters.d.ts +3 -0
- package/dist/scan/adapters.d.ts.map +1 -0
- package/dist/scan/adapters.js +25 -0
- package/dist/scan/adapters.js.map +1 -0
- package/dist/scan/bundling.d.ts +1 -12
- package/dist/scan/bundling.d.ts.map +1 -1
- package/dist/scan/bundling.js +1 -12
- package/dist/scan/bundling.js.map +1 -1
- package/dist/scan/conventions.d.ts +6 -40
- package/dist/scan/conventions.d.ts.map +1 -1
- package/dist/scan/conventions.js +5 -34
- package/dist/scan/conventions.js.map +1 -1
- package/dist/scan/emit.d.ts +2 -6
- package/dist/scan/emit.d.ts.map +1 -1
- package/dist/scan/emit.js +5 -39
- package/dist/scan/emit.js.map +1 -1
- package/dist/scan/handler-parser.d.ts +9 -76
- package/dist/scan/handler-parser.d.ts.map +1 -1
- package/dist/scan/handler-parser.js +28 -85
- package/dist/scan/handler-parser.js.map +1 -1
- package/dist/scan/result.d.ts +28 -0
- package/dist/scan/result.d.ts.map +1 -0
- package/dist/scan/result.js +2 -0
- package/dist/scan/result.js.map +1 -0
- package/dist/scan/scanner.d.ts +3 -28
- package/dist/scan/scanner.d.ts.map +1 -1
- package/dist/scan/scanner.js +36 -135
- package/dist/scan/scanner.js.map +1 -1
- package/dist/scan/statement.d.ts +1 -1
- package/dist/scan/statement.d.ts.map +1 -1
- package/dist/scan/statement.js +4 -30
- package/dist/scan/statement.js.map +1 -1
- package/dist/source.d.ts +41 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/source.js +10 -0
- package/dist/source.js.map +1 -0
- package/dist/storage.d.ts +92 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +50 -0
- package/dist/storage.js.map +1 -0
- package/dist/store.d.ts +18 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +146 -0
- package/dist/store.js.map +1 -0
- package/dist/verify.d.ts +6 -39
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +19 -39
- package/dist/verify.js.map +1 -1
- package/dist/wire/CallLog.d.ts +32 -0
- package/dist/wire/CallLog.d.ts.map +1 -0
- package/dist/{contract → wire}/CallLog.js.map +1 -1
- package/dist/wire/Invocation.d.ts +32 -0
- package/dist/wire/Invocation.d.ts.map +1 -0
- package/dist/wire/Invocation.js +66 -0
- package/dist/wire/Invocation.js.map +1 -0
- package/dist/wire/RouteAddress.d.ts +24 -0
- package/dist/wire/RouteAddress.d.ts.map +1 -0
- package/dist/{contract → wire}/RouteAddress.js +7 -0
- package/dist/wire/RouteAddress.js.map +1 -0
- package/dist/wire/binding.d.ts +36 -0
- package/dist/wire/binding.d.ts.map +1 -0
- package/dist/{boot → wire}/binding.js +5 -62
- package/dist/wire/binding.js.map +1 -0
- package/dist/wire/call.d.ts +25 -172
- package/dist/wire/call.d.ts.map +1 -1
- package/dist/wire/call.js +15 -166
- package/dist/wire/call.js.map +1 -1
- package/dist/wire/drift.d.ts +3 -28
- package/dist/wire/drift.d.ts.map +1 -1
- package/dist/wire/drift.js +4 -23
- package/dist/wire/drift.js.map +1 -1
- package/dist/wire/errors.d.ts +4 -24
- package/dist/wire/errors.d.ts.map +1 -1
- package/dist/wire/errors.js +4 -24
- package/dist/wire/errors.js.map +1 -1
- package/dist/wire/http-error.d.ts +2 -13
- package/dist/wire/http-error.d.ts.map +1 -1
- package/dist/wire/http-error.js +5 -19
- package/dist/wire/http-error.js.map +1 -1
- package/dist/wire/loggerMiddleware.d.ts +2 -8
- package/dist/wire/loggerMiddleware.d.ts.map +1 -1
- package/dist/wire/loggerMiddleware.js +1 -7
- package/dist/wire/loggerMiddleware.js.map +1 -1
- package/dist/wire/middleware.d.ts +3 -7
- package/dist/wire/middleware.d.ts.map +1 -1
- package/dist/wire/middleware.js +1 -5
- package/dist/wire/middleware.js.map +1 -1
- package/dist/wire/operation.d.ts +12 -74
- package/dist/wire/operation.d.ts.map +1 -1
- package/dist/wire/operation.js +4 -66
- package/dist/wire/operation.js.map +1 -1
- package/dist/wire/signature.d.ts +37 -0
- package/dist/wire/signature.d.ts.map +1 -0
- package/dist/wire/signature.js +2 -0
- package/dist/wire/signature.js.map +1 -0
- package/package.json +3 -3
- package/src/boot/Emissions.ts +22 -119
- package/src/boot/ambient-port.ts +3 -24
- package/src/boot/ambient.als.ts +7 -12
- package/src/boot/ambient.queue.ts +2 -5
- package/src/boot/apply.ts +3 -15
- package/src/boot/auth.ts +6 -16
- package/src/boot/boot.ts +8 -23
- package/src/boot/bootstrap.ts +117 -173
- package/src/boot/card.ts +84 -0
- package/src/boot/frame.ts +31 -65
- package/src/boot/hosted.ts +15 -40
- package/src/boot/ownership.ts +14 -49
- package/src/boot/ports.ts +2 -15
- package/src/boot/remote.ts +11 -58
- package/src/boot/runner.ts +17 -0
- package/src/boot/seed.ts +11 -42
- package/src/boot/statement-drift.ts +10 -28
- package/src/boot/together.ts +38 -72
- package/src/boot/types.ts +36 -180
- package/src/{builtins → builtin}/config.ts +1 -7
- package/src/{builtins → builtin}/logger.ts +6 -39
- package/src/config-loader.ts +12 -71
- package/src/contract.ts +15 -39
- package/src/crypto/encoding.ts +2 -15
- package/src/crypto/node.ts +1 -7
- package/src/crypto/port.ts +2 -18
- package/src/crypto/webcrypto.ts +1 -12
- package/src/{scan/declare.ts → declare.ts} +11 -42
- package/src/define.ts +2 -3
- package/src/descriptor/Fronds.ts +47 -0
- package/src/descriptor/frond.ts +145 -0
- package/src/dispatch/ArgumentResolver.ts +54 -8
- package/src/dispatch/DispatchEvent.ts +2 -2
- package/src/dispatch/DispatchLifecycle.ts +1 -7
- package/src/dispatch/DispatchPort.ts +1 -1
- package/src/dispatch/Dispatcher.ts +3 -3
- package/src/dispatch/HandlerFacade.ts +231 -0
- package/src/dispatch/LocalRoutePolicy.ts +4 -4
- package/src/dispatch/OperationRoute.ts +2 -2
- package/src/dispatch/OutputView.ts +24 -2
- package/src/dispatch/Route.ts +2 -4
- package/src/dispatch/RoutePolicy.ts +1 -1
- package/src/dispatch/RouteRegistry.ts +2 -2
- package/src/dispatch/RouteResolver.ts +2 -4
- package/src/dispatch/StorageGuard.ts +75 -23
- package/src/dispatch/presenterArguments.ts +25 -0
- package/src/dispatch/{RemoteRouteResolver.ts → remoteRoutes.ts} +7 -9
- package/src/dispatch/routeNotFound.ts +33 -0
- package/src/dispatch/validateInput.ts +28 -0
- package/src/effective-operation.ts +60 -37
- package/src/emit.ts +5 -63
- package/src/entry/facade.ts +44 -0
- package/src/entry/transport.ts +16 -0
- package/src/frond-config.ts +8 -71
- package/src/graph.ts +1 -1
- package/src/identity-keys.ts +3 -16
- package/src/identity.ts +12 -80
- package/src/imports.ts +3 -32
- package/src/index.ts +28 -33
- package/src/loader.ts +2 -16
- package/src/node.ts +2 -11
- package/src/prefab/collector.ts +1 -22
- package/src/prefab/crud.ts +51 -90
- package/src/prefab/mirror.ts +9 -49
- package/src/prefab/prefab.ts +2 -21
- package/src/prefab/presenter.ts +2 -36
- package/src/prefab/repository.ts +32 -108
- package/src/scan/adapters.ts +32 -0
- package/src/scan/bundling.ts +1 -12
- package/src/scan/conventions.ts +6 -40
- package/src/scan/emit.ts +7 -43
- package/src/scan/handler-parser.ts +41 -163
- package/src/scan/result.ts +29 -0
- package/src/scan/scanner.ts +40 -138
- package/src/scan/statement.ts +6 -31
- package/src/source.ts +44 -0
- package/src/storage.ts +141 -0
- package/src/store.ts +152 -0
- package/src/verify.ts +19 -60
- package/src/wire/CallLog.ts +30 -0
- package/src/{contract → wire}/Invocation.ts +24 -17
- package/src/{contract → wire}/RouteAddress.ts +10 -0
- package/src/wire/binding.ts +102 -0
- package/src/wire/call.ts +30 -261
- package/src/wire/drift.ts +5 -30
- package/src/wire/errors.ts +4 -24
- package/src/wire/http-error.ts +5 -19
- package/src/wire/loggerMiddleware.ts +2 -8
- package/src/wire/middleware.ts +3 -7
- package/src/wire/operation.ts +13 -110
- package/src/wire/signature.ts +38 -0
- package/dist/boot/HandlerFacade.d.ts.map +0 -1
- package/dist/boot/HandlerFacade.js.map +0 -1
- package/dist/boot/binding.d.ts +0 -60
- package/dist/boot/binding.d.ts.map +0 -1
- package/dist/boot/binding.js.map +0 -1
- package/dist/builtins/config.d.ts +0 -13
- package/dist/builtins/config.d.ts.map +0 -1
- package/dist/builtins/config.js +0 -21
- package/dist/builtins/config.js.map +0 -1
- package/dist/builtins/logger.d.ts.map +0 -1
- package/dist/builtins/logger.js.map +0 -1
- package/dist/contract/Call.d.ts +0 -10
- package/dist/contract/Call.d.ts.map +0 -1
- package/dist/contract/Call.js +0 -15
- package/dist/contract/Call.js.map +0 -1
- package/dist/contract/CallLog.d.ts +0 -57
- package/dist/contract/CallLog.d.ts.map +0 -1
- package/dist/contract/Invocation.d.ts +0 -27
- package/dist/contract/Invocation.d.ts.map +0 -1
- package/dist/contract/Invocation.js +0 -59
- package/dist/contract/Invocation.js.map +0 -1
- package/dist/contract/RouteAddress.d.ts +0 -17
- package/dist/contract/RouteAddress.d.ts.map +0 -1
- package/dist/contract/RouteAddress.js.map +0 -1
- package/dist/dispatch/InputValidator.d.ts +0 -7
- package/dist/dispatch/InputValidator.d.ts.map +0 -1
- package/dist/dispatch/InputValidator.js +0 -22
- package/dist/dispatch/InputValidator.js.map +0 -1
- package/dist/dispatch/OperationExecutor.d.ts +0 -25
- package/dist/dispatch/OperationExecutor.d.ts.map +0 -1
- package/dist/dispatch/OperationExecutor.js +0 -32
- package/dist/dispatch/OperationExecutor.js.map +0 -1
- package/dist/dispatch/OutputProjector.d.ts +0 -12
- package/dist/dispatch/OutputProjector.d.ts.map +0 -1
- package/dist/dispatch/OutputProjector.js +0 -30
- package/dist/dispatch/OutputProjector.js.map +0 -1
- package/dist/dispatch/PresenterArgumentResolver.d.ts +0 -12
- package/dist/dispatch/PresenterArgumentResolver.d.ts.map +0 -1
- package/dist/dispatch/PresenterArgumentResolver.js +0 -20
- package/dist/dispatch/PresenterArgumentResolver.js.map +0 -1
- package/dist/dispatch/RemoteRouteResolver.d.ts +0 -13
- package/dist/dispatch/RemoteRouteResolver.d.ts.map +0 -1
- package/dist/dispatch/RemoteRouteResolver.js.map +0 -1
- package/dist/dispatch/RouteNotFoundError.d.ts +0 -10
- package/dist/dispatch/RouteNotFoundError.d.ts.map +0 -1
- package/dist/dispatch/RouteNotFoundError.js +0 -24
- package/dist/dispatch/RouteNotFoundError.js.map +0 -1
- package/dist/entry/DynamicFacade.d.ts +0 -10
- package/dist/entry/DynamicFacade.d.ts.map +0 -1
- package/dist/entry/DynamicFacade.js +0 -27
- package/dist/entry/DynamicFacade.js.map +0 -1
- package/dist/entry/FacadeEntry.d.ts +0 -11
- package/dist/entry/FacadeEntry.d.ts.map +0 -1
- package/dist/entry/FacadeEntry.js +0 -26
- package/dist/entry/FacadeEntry.js.map +0 -1
- package/dist/entry/TransportEntry.d.ts +0 -13
- package/dist/entry/TransportEntry.d.ts.map +0 -1
- package/dist/entry/TransportEntry.js +0 -24
- package/dist/entry/TransportEntry.js.map +0 -1
- package/dist/orm.d.ts +0 -207
- package/dist/orm.d.ts.map +0 -1
- package/dist/orm.js +0 -66
- package/dist/orm.js.map +0 -1
- package/dist/scan/Fronds.d.ts +0 -45
- package/dist/scan/Fronds.d.ts.map +0 -1
- package/dist/scan/Fronds.js +0 -66
- package/dist/scan/Fronds.js.map +0 -1
- package/dist/scan/declare.d.ts +0 -71
- package/dist/scan/declare.d.ts.map +0 -1
- package/dist/scan/declare.js.map +0 -1
- package/dist/scan/frond.d.ts +0 -224
- package/dist/scan/frond.d.ts.map +0 -1
- package/src/boot/HandlerFacade.ts +0 -242
- package/src/boot/binding.ts +0 -182
- package/src/contract/Call.ts +0 -18
- package/src/contract/CallLog.ts +0 -55
- package/src/dispatch/InputValidator.ts +0 -28
- package/src/dispatch/OperationExecutor.ts +0 -60
- package/src/dispatch/OutputProjector.ts +0 -32
- package/src/dispatch/PresenterArgumentResolver.ts +0 -25
- package/src/dispatch/RouteNotFoundError.ts +0 -29
- package/src/entry/DynamicFacade.ts +0 -28
- package/src/entry/FacadeEntry.ts +0 -32
- package/src/entry/TransportEntry.ts +0 -30
- package/src/orm.ts +0 -252
- package/src/scan/Fronds.ts +0 -73
- package/src/scan/frond.ts +0 -235
- /package/dist/{scan → descriptor}/frond.js +0 -0
- /package/dist/{contract → wire}/CallLog.js +0 -0
package/src/scan/scanner.ts
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import { readdir, readFile } from 'node:fs/promises';
|
|
2
2
|
import { existsSync, type Dirent } from 'node:fs';
|
|
3
3
|
import { join, dirname, basename, resolve as resolvePath } from 'node:path';
|
|
4
|
-
import type { FrondDescriptor, ProviderEntry, EntityEntry, HandlerEntry, PresenterEntry, CollectorEntry, SeedEntry
|
|
4
|
+
import type { FrondDescriptor, ProviderEntry, EntityEntry, HandlerEntry, PresenterEntry, CollectorEntry, SeedEntry } from '../descriptor/frond.js';
|
|
5
|
+
import type { ScanResult, ScanDiagnostic } from './result.js';
|
|
5
6
|
import { ANONYMOUS_SCHEMA_NAME, type SchemaView } from '@fougere/schema';
|
|
6
7
|
import type { OperationContract, OperationsMap } from '../wire/operation.js';
|
|
7
8
|
import { cardinalityOf } from '../wire/operation.js';
|
|
8
|
-
import { computeBindingPlan } from '../
|
|
9
|
+
import { computeBindingPlan } from '../wire/binding.js';
|
|
9
10
|
import {
|
|
10
11
|
parseAllHandlerMethods,
|
|
11
12
|
parsePresenterMethods,
|
|
12
13
|
parseConstructorParams,
|
|
13
14
|
resetTypePrograms,
|
|
14
15
|
seedTypeProgram,
|
|
15
|
-
type ParsedType,
|
|
16
16
|
} from './handler-parser.js';
|
|
17
|
+
import type { TypeRef } from '../wire/signature.js';
|
|
17
18
|
import { loadFrondConfig } from '../frond-config.js';
|
|
18
19
|
import { emitKeyOf } from '../emit.js';
|
|
19
20
|
import { getPresenterFields } from '../prefab/presenter.js';
|
|
20
|
-
import {
|
|
21
|
+
import { storageKeyOf, togetherKeyOf } from '../storage.js';
|
|
21
22
|
import { targetOf, viewsOf, outputOf } from '../prefab/prefab.js';
|
|
22
23
|
import { ownedBy, repositoryKeyOf } from '../prefab/repository.js';
|
|
23
24
|
import { lowerFirst } from '@fougere/schema';
|
|
24
|
-
import { Fronds } from '
|
|
25
|
+
import { Fronds } from '../descriptor/Fronds.js';
|
|
25
26
|
import { getModuleLoader } from '../loader.js';
|
|
26
27
|
import {
|
|
27
28
|
type Conventions, type ConventionsInput,
|
|
@@ -30,13 +31,7 @@ import {
|
|
|
30
31
|
|
|
31
32
|
// FS
|
|
32
33
|
|
|
33
|
-
/**
|
|
34
|
-
* What this scan run could not do. Reset by {@link scanProject}, which owns a run.
|
|
35
|
-
*
|
|
36
|
-
* Module-scoped like the loader and the cache root above: the scanner already has a
|
|
37
|
-
* notion of "the current run". Three sites record — measured — so a per-run object
|
|
38
|
-
* would carry twenty methods to spare one line of reset.
|
|
39
|
-
*/
|
|
34
|
+
/** What this scan run could not do. */
|
|
40
35
|
let diagnostics: ScanDiagnostic[] = [];
|
|
41
36
|
|
|
42
37
|
function record(d: ScanDiagnostic): void {
|
|
@@ -44,10 +39,8 @@ function record(d: ScanDiagnostic): void {
|
|
|
44
39
|
}
|
|
45
40
|
|
|
46
41
|
/**
|
|
47
|
-
* An absent convention directory is the ordinary case — a frond without
|
|
48
|
-
*
|
|
49
|
-
* that is not a directory) means the scan did not look, and answering `[]` says
|
|
50
|
-
* it did. One `catch` used to conflate the two.
|
|
42
|
+
* An absent convention directory is the ordinary case — a frond without `presenters/` is not a
|
|
43
|
+
* defect.
|
|
51
44
|
*/
|
|
52
45
|
async function readEntries(path: string): Promise<Dirent[]> {
|
|
53
46
|
try {
|
|
@@ -114,13 +107,7 @@ function findWorkspaceRoot(from: string): string {
|
|
|
114
107
|
return resolvePath(from); // fallback: use project root itself
|
|
115
108
|
}
|
|
116
109
|
|
|
117
|
-
/**
|
|
118
|
-
* Strip the 'Handler' suffix → the name the handler answers to. 'PostHandler' → 'post'.
|
|
119
|
-
*
|
|
120
|
-
* Nothing here checks that an entity carries the result, and nothing should: a handler
|
|
121
|
-
* about no stored row is ordinary. The old name of this function — `toEntityName` — is
|
|
122
|
-
* what let "one façade per entity" be repeated until it read as a rule.
|
|
123
|
-
*/
|
|
110
|
+
/** Strip the 'Handler' suffix → the name the handler answers to. */
|
|
124
111
|
function toAddress(className: string): string {
|
|
125
112
|
const base = className.endsWith('Handler') ? className.slice(0, -7) : className;
|
|
126
113
|
return lowerFirst(base);
|
|
@@ -129,20 +116,10 @@ function toAddress(className: string): string {
|
|
|
129
116
|
// Scan
|
|
130
117
|
|
|
131
118
|
/**
|
|
132
|
-
* The container key a constructor parameter asks for — derived from its TYPE, not from
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* `deps` used to be `p.type.name`, so the key WAS the alias's name: `type ListOrm =
|
|
136
|
-
* EntityOrm<List>` resolved only because someone had spelled it exactly like the
|
|
137
|
-
* registration key (`ListOrm`), while `type ListRepo = EntityOrm<List>` — the same type —
|
|
138
|
-
* typechecked and died at boot on `'ListRepo' is not registered`. And `EntityOrm<List>`
|
|
139
|
-
* written out in full asked for `'EntityOrm'`, which nothing registers.
|
|
140
|
-
*
|
|
141
|
-
* `EntityOrm<X>` names X's storage, so that is the key. The generic argument was already
|
|
142
|
-
* parsed (`ParsedType.generics`) and thrown away. Anything else keeps its own name: a
|
|
143
|
-
* plain service IS designated by its class name.
|
|
119
|
+
* The container key a constructor parameter asks for — derived from its TYPE, not from how the
|
|
120
|
+
* type was spelled.
|
|
144
121
|
*/
|
|
145
|
-
function depKeyOf(type:
|
|
122
|
+
function depKeyOf(type: TypeRef): string {
|
|
146
123
|
// `Facade<PostHandler>` — the second port, read exactly like the first. The type names
|
|
147
124
|
// what arrives: not the handler (its methods take positional arguments and it is never
|
|
148
125
|
// injected), but the door built in front of it. Same key whether that door is the local
|
|
@@ -165,32 +142,25 @@ function depKeyOf(type: ParsedType): string {
|
|
|
165
142
|
// `RepositoryOf<Post>` — what an author writes when no repository file exists. The dual
|
|
166
143
|
// of the line below: one names the port, the other the holder, and both resolve to a key
|
|
167
144
|
// rather than to a class the author would have to invent.
|
|
168
|
-
const
|
|
169
|
-
if (
|
|
145
|
+
const subject = type.name === 'RepositoryOf' ? type.generics?.[0]?.name : undefined;
|
|
146
|
+
if (subject) return repositoryKeyOf(subject);
|
|
170
147
|
|
|
171
|
-
|
|
148
|
+
// The GENERIC names the subject, so a prefix does not change the key — `MeiliStorage<Card>`
|
|
149
|
+
// is `Card`'s storage. A class named `FileStorage` is untouched: it carries no generic.
|
|
150
|
+
const target = type.name.endsWith('Storage') && type.generics?.length === 1
|
|
151
|
+
? type.generics[0]?.name
|
|
152
|
+
: undefined;
|
|
172
153
|
if (!target) return type.name;
|
|
173
154
|
|
|
174
|
-
return
|
|
155
|
+
return storageKeyOf(target);
|
|
175
156
|
}
|
|
176
157
|
|
|
177
|
-
/**
|
|
178
|
-
* `'[Account, Ledger]'` → `['Account', 'Ledger']`.
|
|
179
|
-
*
|
|
180
|
-
* The tuple was chosen over the variadic form the parser reads more cleanly, because the
|
|
181
|
-
* variadic one costs arities-with-defaults and a `never` filter on the TypeScript side
|
|
182
|
-
* while the tuple maps to `[EntityOrm<Account>, EntityOrm<Ledger>]` in one line. The
|
|
183
|
-
* parser does not get to decide alone; this split is what that choice costs.
|
|
184
|
-
*/
|
|
158
|
+
/** `'[Account, Ledger]'` → `['Account', 'Ledger']`. */
|
|
185
159
|
function tupleMembers(raw: string): string[] {
|
|
186
160
|
return raw.replace(/^\[|\]$/g, '').split(',').map((member) => member.trim()).filter(Boolean);
|
|
187
161
|
}
|
|
188
162
|
|
|
189
|
-
/**
|
|
190
|
-
* These readings are semantic: an unchanged file can mean something different after an
|
|
191
|
-
* imported alias changes. The parser's TypeScript Program is the cache for one scan; a
|
|
192
|
-
* cache keyed only by this file's bytes would be unsound.
|
|
193
|
-
*/
|
|
163
|
+
/** These readings are semantic. */
|
|
194
164
|
const ctorParamsOf = (filePath: string) =>
|
|
195
165
|
parseConstructorParams(filePath);
|
|
196
166
|
|
|
@@ -216,9 +186,9 @@ async function toProvider(filePath: string): Promise<ProviderEntry> {
|
|
|
216
186
|
const owned = ownedBy(ctor);
|
|
217
187
|
const target = targetOf(ctor);
|
|
218
188
|
if (owned.length > 1 && deps.length === 0) {
|
|
219
|
-
deps.push(...owned.map((entity) =>
|
|
189
|
+
deps.push(...owned.map((entity) => storageKeyOf(lowerFirst((entity as { name: string }).name))));
|
|
220
190
|
} else if (target && deps.length === 0) {
|
|
221
|
-
deps.push(
|
|
191
|
+
deps.push(storageKeyOf(lowerFirst((target as { name: string }).name)));
|
|
222
192
|
}
|
|
223
193
|
|
|
224
194
|
// No `name` beside `ctor`: a provider registers under `ctor.name`, which is what
|
|
@@ -243,10 +213,10 @@ async function toEntityEntry(filePath: string): Promise<EntityEntry | null> {
|
|
|
243
213
|
}
|
|
244
214
|
|
|
245
215
|
/**
|
|
246
|
-
* Resolve a
|
|
216
|
+
* Resolve a TypeRef to a runtime schema if available in module exports.
|
|
247
217
|
* Handles arrays, generics (uses base name), and simple references.
|
|
248
218
|
*/
|
|
249
|
-
function resolveSchema(type:
|
|
219
|
+
function resolveSchema(type: TypeRef, moduleExports: Record<string, unknown>): SchemaView | undefined {
|
|
250
220
|
// An array's element type IS `type.name` — the arity rides beside it, so nothing has
|
|
251
221
|
// to be unwrapped here.
|
|
252
222
|
// For generics like Pagination<Post>, also check inner types
|
|
@@ -271,12 +241,7 @@ function resolveSchema(type: ParsedType, moduleExports: Record<string, unknown>)
|
|
|
271
241
|
return undefined;
|
|
272
242
|
}
|
|
273
243
|
|
|
274
|
-
/**
|
|
275
|
-
* Parse ALL method signatures for unified binding.
|
|
276
|
-
*
|
|
277
|
-
* Resolves schemas for all params (not just the first) and stores
|
|
278
|
-
* full signatures for the binding algorithm.
|
|
279
|
-
*/
|
|
244
|
+
/** Parse ALL method signatures for unified binding. */
|
|
280
245
|
async function inferOperations(
|
|
281
246
|
filePath: string,
|
|
282
247
|
handlerName: string,
|
|
@@ -307,15 +272,8 @@ async function inferOperations(
|
|
|
307
272
|
}
|
|
308
273
|
|
|
309
274
|
/**
|
|
310
|
-
* A base class the parse could not open — an installed package, typically, whose
|
|
311
|
-
*
|
|
312
|
-
* the scan cannot tell whether there were any.
|
|
313
|
-
*
|
|
314
|
-
* A warning, not a refusal: an installed base class with no operation is perfectly
|
|
315
|
-
* ordinary, and the boot has no way to decide between the two. So it names the
|
|
316
|
-
* clause and stops there. Stating the contract in `frond.config.ts` is the answer
|
|
317
|
-
* — the third producer, which creates an op neither other producer found — and it
|
|
318
|
-
* silences this by making the op exist.
|
|
275
|
+
* A base class the parse could not open — an installed package, typically, whose source is not
|
|
276
|
+
* in the workspace.
|
|
319
277
|
*/
|
|
320
278
|
for (const base of parsed.unresolvedHeritage) {
|
|
321
279
|
record({
|
|
@@ -341,10 +299,10 @@ async function inferOperations(
|
|
|
341
299
|
// caller supplies through the body are candidates: a schema-typed collector, fact or
|
|
342
300
|
// context parameter is not input merely because it names an entity. The old loop
|
|
343
301
|
// ignored provenance and assigned the first schema it met, so swapping two parameters
|
|
344
|
-
// silently changed the contract the façade used to
|
|
302
|
+
// silently changed the contract the façade used to validate the request body.
|
|
345
303
|
const binding = computeBindingPlan(method.params, collectorTypeNames);
|
|
346
304
|
const candidates = method.params.flatMap((param, index) => {
|
|
347
|
-
if (binding[index]?.source.kind !== '
|
|
305
|
+
if (binding[index]?.source.kind !== 'input') return [];
|
|
348
306
|
const schema = resolveSchema(param.type, moduleExports);
|
|
349
307
|
return schema ? [{ param, schema }] : [];
|
|
350
308
|
});
|
|
@@ -521,13 +479,7 @@ async function scanFrond(frondPath: string, name: string, source: FrondDescripto
|
|
|
521
479
|
entities: entitiesDir, handlers: handlersDir,
|
|
522
480
|
presenters: presentersDir, collectors: collectorsDir, seeds: seedsDir,
|
|
523
481
|
} = conventions.dirs;
|
|
524
|
-
/**
|
|
525
|
-
* A convention directory, read by whoever knows the shape it holds.
|
|
526
|
-
*
|
|
527
|
-
* The same three lines were written six times — list, read in parallel, drop what the
|
|
528
|
-
* reader refused — which is what made `handlers/` quietly special: it grew a second
|
|
529
|
-
* pass for its surfaces and nothing else could.
|
|
530
|
-
*/
|
|
482
|
+
/** A convention directory, read by whoever knows the shape it holds. */
|
|
531
483
|
const collect = async <T extends object>(
|
|
532
484
|
dir: string,
|
|
533
485
|
read: (filePath: string) => Promise<T | null>,
|
|
@@ -614,15 +566,7 @@ async function scanFrond(frondPath: string, name: string, source: FrondDescripto
|
|
|
614
566
|
};
|
|
615
567
|
}
|
|
616
568
|
|
|
617
|
-
/**
|
|
618
|
-
* The frond's name — the directory, unless its `package.json` renames it. One rule for a
|
|
619
|
-
* frond under `fronds/` and for the root frond alike, so the root needs no second spelling.
|
|
620
|
-
*
|
|
621
|
-
* Carrying the convention is what makes a frond; the key never marked anything and
|
|
622
|
-
* nothing read it. It earns its keep as the one thing the directory cannot say: that
|
|
623
|
-
* `fronds/blog-v2/` serves the frond still called `blog` — so a rename on disk does not
|
|
624
|
-
* rename the entity keys, the `@fronds/*` import or a `remotes:` entry.
|
|
625
|
-
*/
|
|
569
|
+
/** The frond's name — the directory, unless its `package.json` renames it. */
|
|
626
570
|
async function frondNameOf(frondPath: string, dirName: string): Promise<string> {
|
|
627
571
|
try {
|
|
628
572
|
const pkg = JSON.parse(await readFile(join(frondPath, 'package.json'), 'utf8')) as {
|
|
@@ -636,15 +580,8 @@ async function frondNameOf(frondPath: string, dirName: string): Promise<string>
|
|
|
636
580
|
}
|
|
637
581
|
|
|
638
582
|
/**
|
|
639
|
-
* A frond is a directory carrying the convention, and the project root is one such
|
|
640
|
-
*
|
|
641
|
-
* anything. `fronds/` is not the definition, it is where the OTHERS live: the root frond
|
|
642
|
-
* stays put when a second domain appears, which is what makes flattening free instead of
|
|
643
|
-
* a deferred move.
|
|
644
|
-
*
|
|
645
|
-
* `entities/` is the test, not "any convention directory". `services/` and `repositories/`
|
|
646
|
-
* are ordinary top-level names in projects that never heard of Fougere, and a domain
|
|
647
|
-
* without a single entity is not a domain.
|
|
583
|
+
* A frond is a directory carrying the convention, and the project root is one such directory — so
|
|
584
|
+
* a single-domain app writes `entities/` next to `app/` and never names anything.
|
|
648
585
|
*/
|
|
649
586
|
async function rootFrondOf(root: string, workspaceRoot: string, conventions: Conventions): Promise<FrondDescriptor | null> {
|
|
650
587
|
if ((await files(join(root, conventions.dirs.entities))).length === 0) return null;
|
|
@@ -652,21 +589,7 @@ async function rootFrondOf(root: string, workspaceRoot: string, conventions: Con
|
|
|
652
589
|
return scanFrond(root, name, { path: root, package: frondPackage(name, conventions) }, conventions, workspaceRoot);
|
|
653
590
|
}
|
|
654
591
|
|
|
655
|
-
/**
|
|
656
|
-
* `@fronds/<name>` → the directory it names, for every frond of a project.
|
|
657
|
-
*
|
|
658
|
-
* The framework states this convention — `FrondSource.package` has always spelled it, and
|
|
659
|
-
* `fougere sync` writes it into a consumer's tsconfig — and until now its own reader could
|
|
660
|
-
* not resolve it. The Nuxt module registered a Vite alias, so a `.vue` page could import
|
|
661
|
-
* `@fronds/blog/entities/Post`, while the SCAN loaded sources through a bare jiti: a frond
|
|
662
|
-
* naming its neighbour got `Cannot find module '@fronds/user/entities/User.js'`. So the one
|
|
663
|
-
* form that survives a split was the one form that did not run.
|
|
664
|
-
*
|
|
665
|
-
* Hand it to the module loader — `createJiti(url, { alias: await frondAliases(root) })` —
|
|
666
|
-
* and the named form resolves everywhere the framework reads. A directory listing and a
|
|
667
|
-
* `package.json` read, no parsing: it is deliberately callable BEFORE the loader exists,
|
|
668
|
-
* which is what makes the chicken-and-egg go away.
|
|
669
|
-
*/
|
|
592
|
+
/** `@fronds/<name>` → the directory it names, for every frond of a project. */
|
|
670
593
|
export async function frondAliases(root: string, conventions: Conventions = DEFAULT_CONVENTIONS): Promise<Record<string, string>> {
|
|
671
594
|
const frondsDir = join(root, conventions.fronds);
|
|
672
595
|
const aliases: Record<string, string> = {};
|
|
@@ -680,17 +603,7 @@ export async function frondAliases(root: string, conventions: Conventions = DEFA
|
|
|
680
603
|
aliases[frondPackage(await frondNameOf(path, dir), conventions)] = resolvePath(path);
|
|
681
604
|
}
|
|
682
605
|
|
|
683
|
-
/**
|
|
684
|
-
* A SYNCED frond answers to the same name.
|
|
685
|
-
*
|
|
686
|
-
* `fougere sync` writes `.fougere/remotes/<name>/` and registers it in `remotes.json`,
|
|
687
|
-
* which the Nuxt module already reads to alias `@fronds/<name>`. Doing it here too is
|
|
688
|
-
* what makes the convention mean ONE thing: a consumer writes `@fronds/blog/entities/Post`
|
|
689
|
-
* and never learns whether that frond is on this disk or was fetched from a card.
|
|
690
|
-
*
|
|
691
|
-
* A local frond wins a name collision — its source is the truth, a synced copy is a
|
|
692
|
-
* mirror of somebody else's.
|
|
693
|
-
*/
|
|
606
|
+
/** A SYNCED frond answers to the same name. */
|
|
694
607
|
try {
|
|
695
608
|
const registry = JSON.parse(
|
|
696
609
|
await readFile(join(root, '.fougere', 'remotes.json'), 'utf8'),
|
|
@@ -751,23 +664,12 @@ export async function scanProject(
|
|
|
751
664
|
|
|
752
665
|
// The app's own domain first, then the ones it took in.
|
|
753
666
|
const all = rootFrond ? [rootFrond, ...under] : under;
|
|
754
|
-
const fronds = Fronds.
|
|
667
|
+
const fronds = Fronds.hosting(filter ? all.filter((f) => filter.includes(f.name)) : all);
|
|
755
668
|
|
|
756
669
|
return { fronds, diagnostics };
|
|
757
670
|
}
|
|
758
671
|
|
|
759
|
-
/**
|
|
760
|
-
* What changes when a frond's domain changes — the paths a dev loop watches.
|
|
761
|
-
*
|
|
762
|
-
* It lives beside the scan rather than beside the conventions it reads, because it turns
|
|
763
|
-
* names into DISK paths: `join` is `node:path`, and `conventions.ts` is reached from
|
|
764
|
-
* `index` through `frond()`, which an edge bundle imports. Measured — esbuild refused the
|
|
765
|
-
* Worker with `Could not resolve "node:path"`.
|
|
766
|
-
*
|
|
767
|
-
* The root frond IS the scan root, so watching its path would match every write in the
|
|
768
|
-
* project: `.nuxt/`, `node_modules/`, the build output. Its convention directories are
|
|
769
|
-
* the frond, and they are what a scan re-reads.
|
|
770
|
-
*/
|
|
672
|
+
/** What changes when a frond's domain changes — the paths a dev loop watches. */
|
|
771
673
|
export function watchPathsOf(
|
|
772
674
|
frond: { source: { path: string } },
|
|
773
675
|
scanRoot: string,
|
package/src/scan/statement.ts
CHANGED
|
@@ -1,39 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The scan, written as the STATEMENT an author would have written.
|
|
3
|
-
*
|
|
4
|
-
* A scan runs at build and the app runs elsewhere — two runtimes, no shared memory — so
|
|
5
|
-
* something has to cross. What used to cross was the scan RESULT: every operation's
|
|
6
|
-
* TypeScript signature re-serialized as JSON, beside the five CRUD ops `Crud.__ops`
|
|
7
|
-
* declares at runtime anyway. A second writing of what the classes carry, and one that
|
|
8
|
-
* drifts, since nothing compares the two.
|
|
9
|
-
*
|
|
10
|
-
* What crosses here is what `fronds.ts` holds: imports that bring the ORIGINAL classes
|
|
11
|
-
* back, and `frond()` calls. Everything else `frond()` derives — `Post` is stored as
|
|
12
|
-
* `post`, `PostHandler` answers at `post`, a computed field IS a method, and
|
|
13
|
-
* `Presenter(Post)` keeps its subject. Only what TypeScript erases is named: a
|
|
14
|
-
* constructor's parameter types (`deps`), and the surface a handler answers on, which the
|
|
15
|
-
* scan read from its directory.
|
|
16
|
-
*
|
|
17
|
-
* Measured on demos/nuxt-blog: 102 lines of scan against 31 of statement, and the same app
|
|
18
|
-
* — same rows, same computed fields, and no `typescript` loaded at boot.
|
|
19
|
-
*/
|
|
1
|
+
/** The scan, written as the STATEMENT an author would have written. */
|
|
20
2
|
import { relative } from 'node:path';
|
|
21
|
-
import type { FrondDescriptor
|
|
3
|
+
import type { FrondDescriptor } from '../descriptor/frond.js';
|
|
4
|
+
import type { ScanResult } from './result.js';
|
|
22
5
|
|
|
23
6
|
type Live = { name?: string };
|
|
24
7
|
|
|
25
8
|
/**
|
|
26
|
-
* A file becomes the specifier the PROJECT already uses for it: `@fronds/blog/…`, the
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* A relative path would name the same file by a second route, and two routes to one module
|
|
31
|
-
* are two modules — so `Post` would not equal `Post` and every identity check would fail
|
|
32
|
-
* quietly. It also puts the file outside what the alias resolves, which is what made Node,
|
|
33
|
-
* not the bundler, read the frond's `.ts` and answer 500 on `../entities/Post.js`.
|
|
34
|
-
*
|
|
35
|
-
* `.js`, because the source is `.ts` and the project spells a TypeScript source that way
|
|
36
|
-
* everywhere else — the alias resolves through the same rule as a hand-written import.
|
|
9
|
+
* A file becomes the specifier the PROJECT already uses for it: `@fronds/blog/…`, the import scope
|
|
10
|
+
* a handler names its neighbour by, and which the Nuxt module registers as an alias for every
|
|
11
|
+
* frond it found.
|
|
37
12
|
*/
|
|
38
13
|
function specifierOf(filePath: string, frond: FrondDescriptor): string {
|
|
39
14
|
const inside = relative(frond.source.path, filePath).replace(/\.tsx?$/, '.js');
|
package/src/source.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Registry, type SchemaView } from '@fougere/schema';
|
|
2
|
+
import type { StorageFactory } from './storage.js';
|
|
3
|
+
|
|
4
|
+
/** A place rows live, whatever realizes it. */
|
|
5
|
+
export interface Source {
|
|
6
|
+
storageFactory: StorageFactory;
|
|
7
|
+
/** Bring the shape of what lives here up to date. */
|
|
8
|
+
migrate?(view: SourceView): Promise<void>;
|
|
9
|
+
/** Run `fn` as ONE unit of work, with a factory bound to it. */
|
|
10
|
+
transacted?<R>(fn: (factory: StorageFactory) => Promise<R>): Promise<R>;
|
|
11
|
+
close?(): Promise<void>;
|
|
12
|
+
/** What distinguishes it when a query is reported. */
|
|
13
|
+
name?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The app as ONE source sees it. */
|
|
17
|
+
export interface SourceView {
|
|
18
|
+
fronds: readonly { readonly name: string; readonly entities: readonly { readonly name: string }[] }[];
|
|
19
|
+
/** The auth provider's own entities, when they ride with this source. */
|
|
20
|
+
auth?: unknown;
|
|
21
|
+
elsewhere: readonly string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** What a config file can carry about a source — values, never a live driver. */
|
|
25
|
+
export interface SourceConfig {
|
|
26
|
+
/** The adapter that realizes it. Absent means the conventional one. */
|
|
27
|
+
source?: string;
|
|
28
|
+
/** The entities whose rows live here. Absent on the default source: it holds the rest. */
|
|
29
|
+
entities?: string[];
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Which adapter answers a source name — one per process, no subject to hold. */
|
|
34
|
+
class SourceRegistry extends Registry<(conf: SourceConfig) => Source> {
|
|
35
|
+
/** The source this name stands for, built from the config entry that named it. */
|
|
36
|
+
open(name: string, conf: SourceConfig, path?: string): Source {
|
|
37
|
+
return this.resolve(name, path)(conf);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const Sources = new SourceRegistry(
|
|
42
|
+
'source',
|
|
43
|
+
'import the adapter that answers it, or call Sources.register(name, build)',
|
|
44
|
+
);
|
package/src/storage.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { upperFirst, lowerFirst, type SchemaView } from '@fougere/schema';
|
|
2
|
+
|
|
3
|
+
/** Options for list queries — pagination, sorting, counting. */
|
|
4
|
+
export interface ListOptions {
|
|
5
|
+
/** Number of records to return. */
|
|
6
|
+
limit?: number;
|
|
7
|
+
|
|
8
|
+
/** Offset-based: skip N records. */
|
|
9
|
+
offset?: number;
|
|
10
|
+
|
|
11
|
+
/** Page-based: 1-indexed page number (requires limit). */
|
|
12
|
+
page?: number;
|
|
13
|
+
|
|
14
|
+
/** Cursor-based: fetch records after this ID. */
|
|
15
|
+
after?: string;
|
|
16
|
+
|
|
17
|
+
/** Field name to order by. */
|
|
18
|
+
orderBy?: string;
|
|
19
|
+
|
|
20
|
+
/** Sort direction (default: 'asc'). */
|
|
21
|
+
order?: 'asc' | 'desc';
|
|
22
|
+
|
|
23
|
+
/** If true, also returns total count (for pagination UIs). */
|
|
24
|
+
count?: boolean;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Equality criteria, field by field — `{ orderId: '…' }`. Named rather than spread across the
|
|
28
|
+
* options so an unknown key stays ignored instead of silently becoming a filter.
|
|
29
|
+
*/
|
|
30
|
+
where?: Record<string, unknown>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Result of list() — extends Array so it's backward compatible. */
|
|
34
|
+
export interface ListResult<T> extends Array<T> {
|
|
35
|
+
/** Total number of matching records (only set when count: true). */
|
|
36
|
+
total?: number;
|
|
37
|
+
/** Cursor of the last item (for cursor-based pagination). */
|
|
38
|
+
endCursor?: string;
|
|
39
|
+
/** Whether more records exist after endCursor. */
|
|
40
|
+
hasMore?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The keys `list()` answers to. */
|
|
44
|
+
const LIST_OPTION_KEYS = [
|
|
45
|
+
'limit', 'offset', 'page', 'after', 'orderBy', 'order', 'count', 'where', 'select',
|
|
46
|
+
] as const;
|
|
47
|
+
|
|
48
|
+
/** Refuse an option the port does not answer to, naming it and what was expected. */
|
|
49
|
+
export function assertListOptions(options: object | undefined, entity: string): void {
|
|
50
|
+
if (!options) return;
|
|
51
|
+
const legal = new Set<string>(LIST_OPTION_KEYS);
|
|
52
|
+
const strangers = Object.keys(options).filter((key) => !legal.has(key));
|
|
53
|
+
if (strangers.length === 0) return;
|
|
54
|
+
throw new Error(
|
|
55
|
+
`${entity}.list(): unknown option ${strangers.map((s) => `\`${s}\``).join(', ')}. ` +
|
|
56
|
+
`Known options are ${LIST_OPTION_KEYS.join(', ')} — to filter, pass \`where: { ${strangers[0]}: … }\`.`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Select option — restrict returned fields to those of a SchemaView. */
|
|
61
|
+
export interface SelectOption {
|
|
62
|
+
select?: SchemaView;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Per-entity storage — scoped CRUD operations on a single entity type. */
|
|
66
|
+
export interface Storage<T = Record<string, unknown>> {
|
|
67
|
+
list(options?: ListOptions & SelectOption): Promise<ListResult<T>>;
|
|
68
|
+
findById(id: string, options?: SelectOption): Promise<T | undefined>;
|
|
69
|
+
/**
|
|
70
|
+
* Read by criteria — `findBy({ email })` for the one, `findAllBy({ orderId })` for the many,
|
|
71
|
+
* which is what a one-to-many relation *is*.
|
|
72
|
+
*/
|
|
73
|
+
findBy(criteria: Partial<T> | Record<string, unknown>, options?: SelectOption): Promise<T | undefined>;
|
|
74
|
+
findAllBy(criteria: Partial<T> | Record<string, unknown>, options?: SelectOption): Promise<T[]>;
|
|
75
|
+
/**
|
|
76
|
+
* Read a SET of rows by their key, in one go — the gesture every other one was being bent into.
|
|
77
|
+
*/
|
|
78
|
+
findByKeys(ids: readonly string[], options?: SelectOption): Promise<Map<string, T>>;
|
|
79
|
+
/** The dual of `findByKeys`: many rows per key, not one. */
|
|
80
|
+
findAllByKeys(field: string, keys: readonly string[], options?: SelectOption): Promise<Map<string, T[]>>;
|
|
81
|
+
create(input: Partial<T>, options?: SelectOption): Promise<T>;
|
|
82
|
+
/** Write the row, or make the existing one look like this — one statement. */
|
|
83
|
+
upsert(input: Partial<T>, options?: SelectOption): Promise<T>;
|
|
84
|
+
/** A whole page in one statement — what an import writes through. */
|
|
85
|
+
upsertAll(inputs: readonly Partial<T>[], options?: SelectOption): Promise<number>;
|
|
86
|
+
update(id: string, input: Partial<T>, options?: SelectOption): Promise<T>;
|
|
87
|
+
delete(id: string): Promise<boolean>;
|
|
88
|
+
/** Returns a scoped storage that restricts all read results to the fields of the given schema. */
|
|
89
|
+
output(schema: SchemaView): Storage<T>;
|
|
90
|
+
/** What this storage wraps — the Kysely instance for the SQL one, something else elsewhere. */
|
|
91
|
+
readonly client: unknown;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Factory that creates a Storage for a given entity.
|
|
96
|
+
* Called by bootstrap for every scanned entity.
|
|
97
|
+
*/
|
|
98
|
+
export type StorageFactory = (entity: SchemaView, name: string) => Storage;
|
|
99
|
+
|
|
100
|
+
/** Container key of an entity's storage — 'reading' → 'ReadingStorage'. */
|
|
101
|
+
export function storageKeyOf(entity: string): string {
|
|
102
|
+
return `${upperFirst(entity)}${HELD}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** The entity behind a storage key, or `undefined` when the key is not one. */
|
|
106
|
+
export function entityOfStorageKey(key: string, known: (entity: string) => boolean): string | undefined {
|
|
107
|
+
if (key.length <= HELD.length || !key.endsWith(HELD)) return undefined;
|
|
108
|
+
const entity = lowerFirst(key.slice(0, -HELD.length));
|
|
109
|
+
|
|
110
|
+
return storageKeyOf(entity) === key && known(entity) ? entity : undefined;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** What a holder keeps, said in the key it is registered under. */
|
|
114
|
+
const HELD = 'Storage';
|
|
115
|
+
|
|
116
|
+
/** `Together<[Account, Ledger]>` — writes that stand or fall as one. */
|
|
117
|
+
export interface Together<E extends readonly unknown[], P extends readonly unknown[] = []> {
|
|
118
|
+
run<R>(fn: (entities: { [K in keyof E]: Storage<E[K]> }, providers: P) => Promise<R>): Promise<R>;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* The container key of a frame — `[['Account', 'Ledger'], ['RateMirror']]` →
|
|
123
|
+
* 'Account+Ledger|RateMirrorTogether'.
|
|
124
|
+
*/
|
|
125
|
+
export function togetherKeyOf(entities: readonly string[], providers: readonly string[] = []): string {
|
|
126
|
+
const named = entities.map(upperFirst).join(SEPARATOR);
|
|
127
|
+
return `${named}${providers.length ? KINDS + providers.map(upperFirst).join(SEPARATOR) : ''}${FRAME}`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const FRAME = 'Together';
|
|
131
|
+
const SEPARATOR = '+';
|
|
132
|
+
/** Separates the two lists — what the unwind covers, and what is rebuilt to make it true. */
|
|
133
|
+
const KINDS = '|';
|
|
134
|
+
|
|
135
|
+
/** The members behind a frame key, or `undefined` when the key is not one. */
|
|
136
|
+
export function membersOfTogetherKey(key: string): { entities: string[]; providers: string[] } | undefined {
|
|
137
|
+
if (key.length <= FRAME.length || !key.endsWith(FRAME)) return undefined;
|
|
138
|
+
const [entities, providers = ''] = key.slice(0, -FRAME.length).split(KINDS);
|
|
139
|
+
const split = (list: string) => list.split(SEPARATOR).filter(Boolean);
|
|
140
|
+
return { entities: split(entities!), providers: split(providers) };
|
|
141
|
+
}
|