okengine 0.1.4
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/AGENTS.md +91 -0
- package/README.md +327 -0
- package/docs/spec/complete-example.md +1188 -0
- package/docs/spec/console.md +739 -0
- package/docs/spec/four-applications.md +1188 -0
- package/docs/spec/unified-theory.md +489 -0
- package/package.json +152 -0
- package/spec/manifest.v1.schema.json +624 -0
- package/src/auth/api-keys.ts +168 -0
- package/src/auth/attenuation.ts +116 -0
- package/src/auth/auth.test.ts +273 -0
- package/src/auth/cross-plane.ts +98 -0
- package/src/auth/index.ts +112 -0
- package/src/auth/invites.ts +66 -0
- package/src/auth/invoke-as.ts +49 -0
- package/src/auth/operator.ts +178 -0
- package/src/auth/planes.ts +102 -0
- package/src/auth/plugin.ts +44 -0
- package/src/auth/roles.ts +84 -0
- package/src/auth/sessions.ts +418 -0
- package/src/auth/tables.ts +131 -0
- package/src/cli/args.ts +50 -0
- package/src/cli/branch.ts +75 -0
- package/src/cli/build.ts +86 -0
- package/src/cli/client-add.test.ts +140 -0
- package/src/cli/client-add.ts +164 -0
- package/src/cli/completion.test.ts +58 -0
- package/src/cli/completion.ts +296 -0
- package/src/cli/dev-app-runner.ts +77 -0
- package/src/cli/dev.test.ts +435 -0
- package/src/cli/dev.ts +594 -0
- package/src/cli/doc-drift.test.ts +146 -0
- package/src/cli/doc-drift.ts +397 -0
- package/src/cli/docker-cli.test.ts +221 -0
- package/src/cli/docker.ts +127 -0
- package/src/cli/doctor-diff-examples.ts +92 -0
- package/src/cli/doctor-diff.test.ts +91 -0
- package/src/cli/doctor-diff.ts +274 -0
- package/src/cli/doctor-pii.test.ts +98 -0
- package/src/cli/doctor-pii.ts +151 -0
- package/src/cli/doctor.test.ts +150 -0
- package/src/cli/doctor.ts +223 -0
- package/src/cli/eval.ts +122 -0
- package/src/cli/exit.ts +19 -0
- package/src/cli/gates-list.test.ts +47 -0
- package/src/cli/gates-list.ts +84 -0
- package/src/cli/images.ts +277 -0
- package/src/cli/index.ts +99 -0
- package/src/cli/json-out.test.ts +129 -0
- package/src/cli/load-config.ts +71 -0
- package/src/cli/mcp-from-console.ts +50 -0
- package/src/cli/privacy-erase.ts +73 -0
- package/src/cli/registry.ts +455 -0
- package/src/cli/safe-defaults.test.ts +92 -0
- package/src/cli/schema.ts +196 -0
- package/src/cli/stack.ts +82 -0
- package/src/cli/start.ts +106 -0
- package/src/cli/upgrade.ts +105 -0
- package/src/cli/vault-cmd.ts +140 -0
- package/src/client/budget-entry.ts +34 -0
- package/src/client/budget.test.ts +17 -0
- package/src/client/create.test.ts +159 -0
- package/src/client/create.ts +152 -0
- package/src/client/errors.ts +60 -0
- package/src/client/index.ts +35 -0
- package/src/client/notes-contract.test.ts +289 -0
- package/src/client/transport.test.ts +123 -0
- package/src/client/transport.ts +254 -0
- package/src/client/types.ts +282 -0
- package/src/compiler/aot.test.ts +248 -0
- package/src/compiler/aot.ts +182 -0
- package/src/compiler/differential.test.ts +241 -0
- package/src/compiler/dynamic.ts +54 -0
- package/src/compiler/effects-infer.ts +541 -0
- package/src/compiler/emit.ts +40 -0
- package/src/compiler/extract.test.ts +177 -0
- package/src/compiler/extract.ts +1368 -0
- package/src/compiler/fixtures/raw/raw-unannotated.ts +28 -0
- package/src/compiler/fixtures/skyport/oke.config.ts +24 -0
- package/src/compiler/fixtures/skyport/src/ai.ts +15 -0
- package/src/compiler/fixtures/skyport/src/app.ts +10 -0
- package/src/compiler/fixtures/skyport/src/channels.ts +6 -0
- package/src/compiler/fixtures/skyport/src/core.ts +3 -0
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +57 -0
- package/src/compiler/fixtures/skyport/src/flows/bookings/signals.ts +11 -0
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +14 -0
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +20 -0
- package/src/compiler/fixtures/skyport/src/gates.ts +14 -0
- package/src/compiler/fixtures/skyport/src/journeys.ts +9 -0
- package/src/compiler/fixtures/skyport/src/schema.ts +3 -0
- package/src/compiler/fixtures/skyport/src/vault.ts +6 -0
- package/src/compiler/fixtures/skyport.expected.json +241 -0
- package/src/compiler/fixtures/triggers/five-triggers.ts +69 -0
- package/src/compiler/http-parse.ts +214 -0
- package/src/compiler/index.ts +67 -0
- package/src/compiler/response.ts +89 -0
- package/src/compiler/sucrose.ts +238 -0
- package/src/config/index.ts +167 -0
- package/src/console/budget.test.ts +73 -0
- package/src/console/index.ts +30 -0
- package/src/console/server/access.test.ts +370 -0
- package/src/console/server/access.ts +777 -0
- package/src/console/server/ai.test.ts +172 -0
- package/src/console/server/ai.ts +632 -0
- package/src/console/server/app.ts +294 -0
- package/src/console/server/auth-rate.test.ts +81 -0
- package/src/console/server/auth-rate.ts +72 -0
- package/src/console/server/bind.ts +25 -0
- package/src/console/server/channels.test.ts +179 -0
- package/src/console/server/channels.ts +469 -0
- package/src/console/server/claim.test.ts +66 -0
- package/src/console/server/claim.ts +134 -0
- package/src/console/server/clock.test.ts +239 -0
- package/src/console/server/clock.ts +390 -0
- package/src/console/server/console.test.ts +338 -0
- package/src/console/server/diff.test.ts +299 -0
- package/src/console/server/diff.ts +352 -0
- package/src/console/server/dry-run.audit.test.ts +118 -0
- package/src/console/server/flows-invoke.test.ts +148 -0
- package/src/console/server/flows.ts +3633 -0
- package/src/console/server/gates.test.ts +360 -0
- package/src/console/server/gates.ts +869 -0
- package/src/console/server/index.ts +141 -0
- package/src/console/server/live.test.ts +30 -0
- package/src/console/server/live.ts +109 -0
- package/src/console/server/plugin.ts +50 -0
- package/src/console/server/plugins.test.ts +131 -0
- package/src/console/server/plugins.ts +429 -0
- package/src/console/server/runs-pii.ts +98 -0
- package/src/console/server/security-headers.ts +97 -0
- package/src/console/server/security.gate.test.ts +286 -0
- package/src/console/server/serve.ts +319 -0
- package/src/console/server/signals.test.ts +88 -0
- package/src/console/server/signals.ts +282 -0
- package/src/console/server/state.ts +982 -0
- package/src/console/server/store.test.ts +233 -0
- package/src/console/server/store.ts +861 -0
- package/src/console/server/structural.ts +95 -0
- package/src/console/server/vault.test.ts +251 -0
- package/src/console/server/vault.ts +430 -0
- package/src/console/ui/access/AccessA11yView.tsx +237 -0
- package/src/console/ui/access/a11y.test.tsx +122 -0
- package/src/console/ui/access/acknowledgement.test.ts +13 -0
- package/src/console/ui/access/acknowledgement.ts +35 -0
- package/src/console/ui/access/blast-radius.test.ts +26 -0
- package/src/console/ui/access/blast-radius.ts +40 -0
- package/src/console/ui/access/confirmation.test.ts +38 -0
- package/src/console/ui/access/confirmation.ts +36 -0
- package/src/console/ui/access/fixture.ts +203 -0
- package/src/console/ui/access/grantable.test.ts +17 -0
- package/src/console/ui/access/grantable.ts +36 -0
- package/src/console/ui/access/hygiene.test.ts +12 -0
- package/src/console/ui/access/hygiene.ts +39 -0
- package/src/console/ui/access/index.ts +54 -0
- package/src/console/ui/access/provenance.test.ts +12 -0
- package/src/console/ui/access/provenance.ts +29 -0
- package/src/console/ui/access/search.test.ts +17 -0
- package/src/console/ui/access/search.ts +72 -0
- package/src/console/ui/access/types.ts +111 -0
- package/src/console/ui/ai/AiA11yView.tsx +265 -0
- package/src/console/ui/ai/a11y.test.tsx +99 -0
- package/src/console/ui/ai/findings.ts +41 -0
- package/src/console/ui/ai/fixture.ts +182 -0
- package/src/console/ui/ai/format.ts +90 -0
- package/src/console/ui/ai/group.test.ts +37 -0
- package/src/console/ui/ai/group.ts +88 -0
- package/src/console/ui/ai/index.ts +66 -0
- package/src/console/ui/ai/promotion.test.ts +77 -0
- package/src/console/ui/ai/promotion.ts +150 -0
- package/src/console/ui/ai/search.test.ts +40 -0
- package/src/console/ui/ai/search.ts +89 -0
- package/src/console/ui/ai/types.ts +139 -0
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +163 -0
- package/src/console/ui/architecture/a11y.test.tsx +97 -0
- package/src/console/ui/architecture/boundary.ts +42 -0
- package/src/console/ui/architecture/declared.ts +165 -0
- package/src/console/ui/architecture/fixture.ts +74 -0
- package/src/console/ui/architecture/index.ts +84 -0
- package/src/console/ui/architecture/layers.ts +64 -0
- package/src/console/ui/architecture/layout.ts +68 -0
- package/src/console/ui/architecture/pathologies.ts +260 -0
- package/src/console/ui/architecture/search.ts +145 -0
- package/src/console/ui/architecture/traffic.ts +102 -0
- package/src/console/ui/architecture/types.ts +144 -0
- package/src/console/ui/architecture/view.test.ts +165 -0
- package/src/console/ui/architecture/view.ts +516 -0
- package/src/console/ui/channels/ChannelsA11yView.tsx +180 -0
- package/src/console/ui/channels/a11y.test.tsx +96 -0
- package/src/console/ui/channels/confirmation.test.ts +37 -0
- package/src/console/ui/channels/confirmation.ts +27 -0
- package/src/console/ui/channels/fallback.test.ts +15 -0
- package/src/console/ui/channels/fallback.ts +20 -0
- package/src/console/ui/channels/findings.ts +38 -0
- package/src/console/ui/channels/fixture.ts +134 -0
- package/src/console/ui/channels/group.ts +25 -0
- package/src/console/ui/channels/index.ts +57 -0
- package/src/console/ui/channels/locale.test.ts +17 -0
- package/src/console/ui/channels/locale.ts +31 -0
- package/src/console/ui/channels/mask.test.ts +14 -0
- package/src/console/ui/channels/mask.ts +12 -0
- package/src/console/ui/channels/search.ts +58 -0
- package/src/console/ui/channels/taxonomy.test.ts +17 -0
- package/src/console/ui/channels/taxonomy.ts +49 -0
- package/src/console/ui/channels/types.ts +117 -0
- package/src/console/ui/clock/ClockA11yView.tsx +182 -0
- package/src/console/ui/clock/a11y.test.tsx +99 -0
- package/src/console/ui/clock/confirmation.test.ts +32 -0
- package/src/console/ui/clock/confirmation.ts +34 -0
- package/src/console/ui/clock/findings.ts +40 -0
- package/src/console/ui/clock/fixture.ts +111 -0
- package/src/console/ui/clock/health.test.ts +25 -0
- package/src/console/ui/clock/health.ts +61 -0
- package/src/console/ui/clock/index.ts +49 -0
- package/src/console/ui/clock/search.test.ts +39 -0
- package/src/console/ui/clock/search.ts +76 -0
- package/src/console/ui/clock/timeline.test.ts +44 -0
- package/src/console/ui/clock/timeline.ts +41 -0
- package/src/console/ui/clock/types.ts +78 -0
- package/src/console/ui/clock/waiting-on.test.ts +34 -0
- package/src/console/ui/clock/waiting-on.ts +83 -0
- package/src/console/ui/confirmation.unify.test.ts +92 -0
- package/src/console/ui/diff/DiffA11yView.tsx +85 -0
- package/src/console/ui/diff/a11y.test.tsx +99 -0
- package/src/console/ui/diff/fixture.ts +85 -0
- package/src/console/ui/diff/group.test.ts +58 -0
- package/src/console/ui/diff/group.ts +97 -0
- package/src/console/ui/diff/index.ts +38 -0
- package/src/console/ui/diff/search.test.ts +32 -0
- package/src/console/ui/diff/search.ts +75 -0
- package/src/console/ui/diff/summary.ts +74 -0
- package/src/console/ui/diff/types.ts +48 -0
- package/src/console/ui/dist/assets/index-B71Yl_SS.js +10 -0
- package/src/console/ui/dist/assets/panel-access-Dd37LU2c.js +64 -0
- package/src/console/ui/dist/assets/panel-ai-CC7LR6-J.js +1 -0
- package/src/console/ui/dist/assets/panel-architecture-B5b3iKCz.js +1 -0
- package/src/console/ui/dist/assets/panel-channels-CeNjTKXp.js +1 -0
- package/src/console/ui/dist/assets/panel-clock-DgFTLoHV.js +1 -0
- package/src/console/ui/dist/assets/panel-diff-DxehccqB.js +1 -0
- package/src/console/ui/dist/assets/panel-flows-BtrVn-Eg.js +45 -0
- package/src/console/ui/dist/assets/panel-gates-Z9MKRGdH.js +1 -0
- package/src/console/ui/dist/assets/panel-overview-Bd48d9km.js +1 -0
- package/src/console/ui/dist/assets/panel-plugins-DWd0TowH.js +1 -0
- package/src/console/ui/dist/assets/panel-runs-BwsWqKeB.js +1 -0
- package/src/console/ui/dist/assets/panel-signals-9najbZY2.js +1 -0
- package/src/console/ui/dist/assets/panel-store-OHkP2pDp.js +1 -0
- package/src/console/ui/dist/assets/panel-traces-tn2JoY8U.js +1 -0
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +1 -0
- package/src/console/ui/dist/assets/rolldown-runtime-CNC7AqOf.js +1 -0
- package/src/console/ui/dist/assets/style-Cnl7WLya.css +3 -0
- package/src/console/ui/dist/index.html +14 -0
- package/src/console/ui/flows/FlowsA11yView.tsx +155 -0
- package/src/console/ui/flows/a11y.test.tsx +105 -0
- package/src/console/ui/flows/buffer.test.ts +91 -0
- package/src/console/ui/flows/buffer.ts +118 -0
- package/src/console/ui/flows/confirmation.ts +131 -0
- package/src/console/ui/flows/contract.test.ts +89 -0
- package/src/console/ui/flows/contract.ts +353 -0
- package/src/console/ui/flows/fixture.ts +81 -0
- package/src/console/ui/flows/graph.test.ts +101 -0
- package/src/console/ui/flows/graph.ts +549 -0
- package/src/console/ui/flows/index.ts +87 -0
- package/src/console/ui/flows/save-as-test.test.ts +47 -0
- package/src/console/ui/flows/save-as-test.ts +99 -0
- package/src/console/ui/flows/search.ts +255 -0
- package/src/console/ui/flows/tiers.ts +140 -0
- package/src/console/ui/gates/GatesA11yView.tsx +192 -0
- package/src/console/ui/gates/a11y.test.tsx +116 -0
- package/src/console/ui/gates/audit.test.ts +40 -0
- package/src/console/ui/gates/audit.ts +63 -0
- package/src/console/ui/gates/denial.test.ts +36 -0
- package/src/console/ui/gates/denial.ts +51 -0
- package/src/console/ui/gates/findings.ts +19 -0
- package/src/console/ui/gates/fixture.ts +189 -0
- package/src/console/ui/gates/group.test.ts +30 -0
- package/src/console/ui/gates/group.ts +102 -0
- package/src/console/ui/gates/index.ts +47 -0
- package/src/console/ui/gates/search.test.ts +49 -0
- package/src/console/ui/gates/search.ts +115 -0
- package/src/console/ui/gates/types.ts +121 -0
- package/src/console/ui/overview/OverviewA11yView.tsx +152 -0
- package/src/console/ui/overview/a11y.test.tsx +113 -0
- package/src/console/ui/overview/busiest.ts +26 -0
- package/src/console/ui/overview/compose.ts +133 -0
- package/src/console/ui/overview/cost.test.ts +39 -0
- package/src/console/ui/overview/cost.ts +138 -0
- package/src/console/ui/overview/fixture.ts +161 -0
- package/src/console/ui/overview/golden.ts +57 -0
- package/src/console/ui/overview/index.ts +59 -0
- package/src/console/ui/overview/rank.test.ts +136 -0
- package/src/console/ui/overview/rank.ts +210 -0
- package/src/console/ui/overview/slo.test.ts +73 -0
- package/src/console/ui/overview/slo.ts +229 -0
- package/src/console/ui/overview/types.ts +121 -0
- package/src/console/ui/overview/verdict.ts +131 -0
- package/src/console/ui/plugins/PluginsA11yView.tsx +227 -0
- package/src/console/ui/plugins/a11y.test.tsx +97 -0
- package/src/console/ui/plugins/command.test.ts +22 -0
- package/src/console/ui/plugins/command.ts +27 -0
- package/src/console/ui/plugins/findings.ts +39 -0
- package/src/console/ui/plugins/fixture.ts +233 -0
- package/src/console/ui/plugins/group.test.ts +38 -0
- package/src/console/ui/plugins/group.ts +67 -0
- package/src/console/ui/plugins/index.ts +40 -0
- package/src/console/ui/plugins/search.ts +67 -0
- package/src/console/ui/plugins/types.ts +115 -0
- package/src/console/ui/runs/RunsA11yView.tsx +267 -0
- package/src/console/ui/runs/a11y.test.tsx +99 -0
- package/src/console/ui/runs/explain.test.ts +23 -0
- package/src/console/ui/runs/explain.ts +32 -0
- package/src/console/ui/runs/fixture.ts +189 -0
- package/src/console/ui/runs/group.test.ts +24 -0
- package/src/console/ui/runs/group.ts +85 -0
- package/src/console/ui/runs/histogram.test.ts +31 -0
- package/src/console/ui/runs/histogram.ts +85 -0
- package/src/console/ui/runs/index.ts +75 -0
- package/src/console/ui/runs/project.ts +122 -0
- package/src/console/ui/runs/query.test.ts +50 -0
- package/src/console/ui/runs/query.ts +283 -0
- package/src/console/ui/runs/search.test.ts +45 -0
- package/src/console/ui/runs/search.ts +141 -0
- package/src/console/ui/runs/trace-link.test.ts +30 -0
- package/src/console/ui/runs/trace-link.ts +99 -0
- package/src/console/ui/runs/types.ts +137 -0
- package/src/console/ui/shell/App.tsx +56 -0
- package/src/console/ui/shell/client.ts +1715 -0
- package/src/console/ui/shell/components/ui.tsx +110 -0
- package/src/console/ui/shell/index.html +12 -0
- package/src/console/ui/shell/layout/Shell.tsx +95 -0
- package/src/console/ui/shell/main.tsx +281 -0
- package/src/console/ui/shell/panels/Access.tsx +5 -0
- package/src/console/ui/shell/panels/Ai.tsx +5 -0
- package/src/console/ui/shell/panels/Architecture.tsx +5 -0
- package/src/console/ui/shell/panels/Channels.tsx +5 -0
- package/src/console/ui/shell/panels/Clock.tsx +5 -0
- package/src/console/ui/shell/panels/Diff.tsx +5 -0
- package/src/console/ui/shell/panels/Flows.tsx +5 -0
- package/src/console/ui/shell/panels/Gates.tsx +5 -0
- package/src/console/ui/shell/panels/Overview.tsx +6 -0
- package/src/console/ui/shell/panels/Plugins.tsx +5 -0
- package/src/console/ui/shell/panels/Runs.tsx +5 -0
- package/src/console/ui/shell/panels/Signals.tsx +5 -0
- package/src/console/ui/shell/panels/Store.tsx +5 -0
- package/src/console/ui/shell/panels/Traces.tsx +5 -0
- package/src/console/ui/shell/panels/Vault.tsx +5 -0
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +813 -0
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +563 -0
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +377 -0
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +454 -0
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +479 -0
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +275 -0
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +301 -0
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +350 -0
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +502 -0
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +482 -0
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +428 -0
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +413 -0
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +649 -0
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +840 -0
- package/src/console/ui/shell/panels/store/StorePanel.tsx +787 -0
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +539 -0
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +449 -0
- package/src/console/ui/shell/plugin/Sandbox.tsx +29 -0
- package/src/console/ui/shell/setup/Wizard.tsx +189 -0
- package/src/console/ui/shell/styles.css +75 -0
- package/src/console/ui/signals/SignalsA11yView.tsx +276 -0
- package/src/console/ui/signals/a11y.test.tsx +99 -0
- package/src/console/ui/signals/confirmation.test.ts +39 -0
- package/src/console/ui/signals/confirmation.ts +63 -0
- package/src/console/ui/signals/dry-run.test.ts +18 -0
- package/src/console/ui/signals/dry-run.ts +36 -0
- package/src/console/ui/signals/durable.test.ts +22 -0
- package/src/console/ui/signals/durable.ts +41 -0
- package/src/console/ui/signals/findings.ts +33 -0
- package/src/console/ui/signals/fixture.ts +242 -0
- package/src/console/ui/signals/group.test.ts +32 -0
- package/src/console/ui/signals/group.ts +49 -0
- package/src/console/ui/signals/index.ts +52 -0
- package/src/console/ui/signals/monitor.test.ts +30 -0
- package/src/console/ui/signals/monitor.ts +79 -0
- package/src/console/ui/signals/schema-form.test.ts +34 -0
- package/src/console/ui/signals/schema-form.ts +112 -0
- package/src/console/ui/signals/search.ts +102 -0
- package/src/console/ui/signals/types.ts +71 -0
- package/src/console/ui/store/StoreA11yView.tsx +199 -0
- package/src/console/ui/store/a11y.test.tsx +99 -0
- package/src/console/ui/store/cache-view.test.ts +13 -0
- package/src/console/ui/store/cache-view.ts +36 -0
- package/src/console/ui/store/confirmation.test.ts +38 -0
- package/src/console/ui/store/confirmation.ts +55 -0
- package/src/console/ui/store/dry-run.test.ts +15 -0
- package/src/console/ui/store/dry-run.ts +29 -0
- package/src/console/ui/store/fixture.ts +163 -0
- package/src/console/ui/store/group.test.ts +21 -0
- package/src/console/ui/store/group.ts +41 -0
- package/src/console/ui/store/index.ts +40 -0
- package/src/console/ui/store/search.ts +78 -0
- package/src/console/ui/store/types.ts +65 -0
- package/src/console/ui/store/will-not-fire.test.ts +19 -0
- package/src/console/ui/store/will-not-fire.ts +40 -0
- package/src/console/ui/traces/TracesA11yView.tsx +200 -0
- package/src/console/ui/traces/a11y.test.tsx +97 -0
- package/src/console/ui/traces/chain.test.ts +61 -0
- package/src/console/ui/traces/chain.ts +144 -0
- package/src/console/ui/traces/critical-path.test.ts +24 -0
- package/src/console/ui/traces/critical-path.ts +59 -0
- package/src/console/ui/traces/filter.test.ts +78 -0
- package/src/console/ui/traces/filter.ts +112 -0
- package/src/console/ui/traces/fixture.ts +126 -0
- package/src/console/ui/traces/fold.test.ts +67 -0
- package/src/console/ui/traces/fold.ts +170 -0
- package/src/console/ui/traces/index.ts +64 -0
- package/src/console/ui/traces/mini.ts +65 -0
- package/src/console/ui/traces/replay.test.ts +24 -0
- package/src/console/ui/traces/replay.ts +35 -0
- package/src/console/ui/traces/sampling.test.ts +26 -0
- package/src/console/ui/traces/sampling.ts +66 -0
- package/src/console/ui/traces/search.ts +148 -0
- package/src/console/ui/traces/tier.ts +72 -0
- package/src/console/ui/traces/types.ts +125 -0
- package/src/console/ui/tsconfig.json +20 -0
- package/src/console/ui/vault/VaultA11yView.tsx +177 -0
- package/src/console/ui/vault/a11y.test.tsx +97 -0
- package/src/console/ui/vault/blast-radius.test.ts +35 -0
- package/src/console/ui/vault/blast-radius.ts +55 -0
- package/src/console/ui/vault/confirmation.test.ts +41 -0
- package/src/console/ui/vault/confirmation.ts +39 -0
- package/src/console/ui/vault/dormant.test.ts +37 -0
- package/src/console/ui/vault/dormant.ts +28 -0
- package/src/console/ui/vault/export-safe.test.ts +30 -0
- package/src/console/ui/vault/export-safe.ts +65 -0
- package/src/console/ui/vault/fixture.ts +75 -0
- package/src/console/ui/vault/group.test.ts +25 -0
- package/src/console/ui/vault/group.ts +50 -0
- package/src/console/ui/vault/index.ts +45 -0
- package/src/console/ui/vault/search.ts +62 -0
- package/src/console/ui/vault/types.ts +57 -0
- package/src/console/ui/vite.config.ts +84 -0
- package/src/console/xss.gate.test.ts +118 -0
- package/src/docker/compose.ts +226 -0
- package/src/docker/credentials.ts +25 -0
- package/src/docker/derive.ts +83 -0
- package/src/docker/docker.test.ts +185 -0
- package/src/docker/dockerfile.integration.test.ts +170 -0
- package/src/docker/dockerfile.ts +39 -0
- package/src/docker/helpers.ts +103 -0
- package/src/docker/index.ts +52 -0
- package/src/docker/pin.ts +90 -0
- package/src/docker/recipes/index.ts +33 -0
- package/src/docker/recipes/postgres.ts +18 -0
- package/src/docker/recipes/redis.ts +18 -0
- package/src/docker/stack.integration.test.ts +140 -0
- package/src/docker/stack.ts +62 -0
- package/src/docker/types.ts +134 -0
- package/src/drivers/ai-anthropic.ts +128 -0
- package/src/drivers/ai-mock.ts +82 -0
- package/src/drivers/ai-openai-compatible.ts +139 -0
- package/src/drivers/ai-providers.test.ts +163 -0
- package/src/drivers/ai-types.ts +83 -0
- package/src/drivers/bun-native-completeness.test.ts +155 -0
- package/src/drivers/channel-console.ts +118 -0
- package/src/drivers/channel-fcm.ts +96 -0
- package/src/drivers/channel-resend.ts +27 -0
- package/src/drivers/channel-smtp.ts +33 -0
- package/src/drivers/channel-types.ts +160 -0
- package/src/drivers/channel-unifonic.ts +79 -0
- package/src/drivers/channel-wa-cloud.ts +84 -0
- package/src/drivers/channel-webpush.ts +317 -0
- package/src/drivers/conformance.test.ts +89 -0
- package/src/drivers/conformance.ts +162 -0
- package/src/drivers/fs.ts +73 -0
- package/src/drivers/index.ts +194 -0
- package/src/drivers/kv-lua.ts +222 -0
- package/src/drivers/memory.ts +472 -0
- package/src/drivers/pgvector.ts +130 -0
- package/src/drivers/postgres.ts +221 -0
- package/src/drivers/redis.ts +254 -0
- package/src/drivers/s3.ts +129 -0
- package/src/drivers/signal-engine.ts +690 -0
- package/src/drivers/signal-memory.ts +27 -0
- package/src/drivers/signal-nats.ts +131 -0
- package/src/drivers/signal-postgres.ts +1089 -0
- package/src/drivers/signal-redis.ts +275 -0
- package/src/drivers/signal-types.ts +328 -0
- package/src/drivers/sqlite.ts +53 -0
- package/src/drivers/types.ts +334 -0
- package/src/drivers/vault-dotenv-parse.ts +56 -0
- package/src/drivers/vault-env.ts +101 -0
- package/src/drivers/vault-infisical.ts +61 -0
- package/src/drivers/vault-managed.ts +42 -0
- package/src/drivers/vault-memory.ts +38 -0
- package/src/drivers/vault-openbao.ts +80 -0
- package/src/drivers/vault-sops.ts +252 -0
- package/src/drivers/vault-types.ts +84 -0
- package/src/elements/ai/declare.ts +206 -0
- package/src/elements/ai/eval.ts +113 -0
- package/src/elements/ai/pii.ts +108 -0
- package/src/elements/ai/runtime.ts +540 -0
- package/src/elements/ai/schema.ts +194 -0
- package/src/elements/ai.test.ts +393 -0
- package/src/elements/ai.ts +56 -0
- package/src/elements/channel/consent.ts +81 -0
- package/src/elements/channel/costs.test.ts +62 -0
- package/src/elements/channel/costs.ts +130 -0
- package/src/elements/channel/declare.ts +141 -0
- package/src/elements/channel/email-auth.test.ts +47 -0
- package/src/elements/channel/email-auth.ts +109 -0
- package/src/elements/channel/locale.ts +97 -0
- package/src/elements/channel/mask.test.ts +19 -0
- package/src/elements/channel/mask.ts +60 -0
- package/src/elements/channel/mime.ts +23 -0
- package/src/elements/channel/outcomes.test.ts +40 -0
- package/src/elements/channel/outcomes.ts +126 -0
- package/src/elements/channel/receipts.ts +121 -0
- package/src/elements/channel/runtime.ts +500 -0
- package/src/elements/channel/suppression.ts +136 -0
- package/src/elements/channel.test.ts +232 -0
- package/src/elements/channel.ts +109 -0
- package/src/elements/clock/actions.ts +170 -0
- package/src/elements/clock/declare.ts +58 -0
- package/src/elements/clock/dst.ts +197 -0
- package/src/elements/clock/durable.ts +140 -0
- package/src/elements/clock/duration.ts +29 -0
- package/src/elements/clock/health.test.ts +103 -0
- package/src/elements/clock/health.ts +112 -0
- package/src/elements/clock/leader.ts +127 -0
- package/src/elements/clock/reconcile.ts +241 -0
- package/src/elements/clock/runtime.ts +243 -0
- package/src/elements/clock/schedule.ts +262 -0
- package/src/elements/clock/time-travel.ts +53 -0
- package/src/elements/clock.test.ts +365 -0
- package/src/elements/clock.ts +80 -0
- package/src/elements/gate/declare.ts +134 -0
- package/src/elements/gate/permissions.ts +104 -0
- package/src/elements/gate/runtime.ts +177 -0
- package/src/elements/gate/strategies.ts +388 -0
- package/src/elements/gate.test.ts +145 -0
- package/src/elements/gate.ts +41 -0
- package/src/elements/index.ts +169 -0
- package/src/elements/signal/chaos-child.ts +47 -0
- package/src/elements/signal/declare.ts +77 -0
- package/src/elements/signal/dry-run-replay.test.ts +95 -0
- package/src/elements/signal/dry-run-write-isolation.test.ts +94 -0
- package/src/elements/signal/reconcile.test.ts +23 -0
- package/src/elements/signal/reconcile.ts +122 -0
- package/src/elements/signal/runtime.ts +94 -0
- package/src/elements/signal.test.ts +457 -0
- package/src/elements/signal.ts +26 -0
- package/src/elements/store/cache.ts +197 -0
- package/src/elements/store/classify.ts +125 -0
- package/src/elements/store/declare.ts +200 -0
- package/src/elements/store/files-policy.test.ts +31 -0
- package/src/elements/store/files-policy.ts +70 -0
- package/src/elements/store/replica.ts +68 -0
- package/src/elements/store/runtime.ts +393 -0
- package/src/elements/store/sql-condition.ts +205 -0
- package/src/elements/store/sql-session.ts +579 -0
- package/src/elements/store/table.ts +282 -0
- package/src/elements/store.test.ts +370 -0
- package/src/elements/store.ts +99 -0
- package/src/elements/vault/declare.ts +143 -0
- package/src/elements/vault/fingerprint.ts +30 -0
- package/src/elements/vault/redact.ts +52 -0
- package/src/elements/vault/runtime.ts +461 -0
- package/src/elements/vault.test.ts +296 -0
- package/src/elements/vault.ts +44 -0
- package/src/index.ts +183 -0
- package/src/kernel/adopt-routes.ts +194 -0
- package/src/kernel/app.ts +1068 -0
- package/src/kernel/auth-resolve.ts +93 -0
- package/src/kernel/boot.test.ts +173 -0
- package/src/kernel/boot.ts +439 -0
- package/src/kernel/budget-entry.ts +55 -0
- package/src/kernel/budget.test.ts +19 -0
- package/src/kernel/call.test.ts +83 -0
- package/src/kernel/capability.ts +113 -0
- package/src/kernel/dry-run.test.ts +64 -0
- package/src/kernel/dry-run.ts +171 -0
- package/src/kernel/effects.test.ts +89 -0
- package/src/kernel/effects.ts +140 -0
- package/src/kernel/errors.registry.test.ts +39 -0
- package/src/kernel/errors.ts +225 -0
- package/src/kernel/flow.test.ts +154 -0
- package/src/kernel/flow.ts +290 -0
- package/src/kernel/fx.test.ts +245 -0
- package/src/kernel/fx.ts +996 -0
- package/src/kernel/hook-timing.test.ts +72 -0
- package/src/kernel/hook-timing.ts +190 -0
- package/src/kernel/hooks.test.ts +181 -0
- package/src/kernel/hooks.ts +275 -0
- package/src/kernel/index.ts +278 -0
- package/src/kernel/journal.ts +405 -0
- package/src/kernel/journey.ts +75 -0
- package/src/kernel/on.ts +74 -0
- package/src/kernel/pipeline.test.ts +349 -0
- package/src/kernel/pipeline.ts +245 -0
- package/src/kernel/plug.ts +82 -0
- package/src/kernel/plugin/capabilities.test.ts +84 -0
- package/src/kernel/plugin/conflicts.test.ts +106 -0
- package/src/kernel/plugin/decorate.test.ts +111 -0
- package/src/kernel/plugin/scoping.test.ts +138 -0
- package/src/kernel/plugin.ts +485 -0
- package/src/kernel/rate-limit.ts +25 -0
- package/src/kernel/registry.ts +398 -0
- package/src/kernel/router.test.ts +114 -0
- package/src/kernel/router.ts +556 -0
- package/src/kernel/routing-budget.test.ts +19 -0
- package/src/kernel/run-telemetry.ts +70 -0
- package/src/kernel/triggers.ts +324 -0
- package/src/kernel/unit.ts +88 -0
- package/src/manifest/diff.test.ts +866 -0
- package/src/manifest/diff.ts +1670 -0
- package/src/manifest/fixtures/base.manifest.json +112 -0
- package/src/manifest/fixtures/skyport.excerpt.json +51 -0
- package/src/manifest/fixtures/skyport.manifest.json +153 -0
- package/src/manifest/index.ts +27 -0
- package/src/manifest/types.ts +358 -0
- package/src/manifest/undeclared.test.ts +82 -0
- package/src/manifest/undeclared.ts +65 -0
- package/src/manifest/validate.test.ts +105 -0
- package/src/manifest/validate.ts +174 -0
- package/src/mcp/authorization.ts +340 -0
- package/src/mcp/confirmation.ts +174 -0
- package/src/mcp/data.ts +90 -0
- package/src/mcp/index.ts +80 -0
- package/src/mcp/injection.gate.test.ts +176 -0
- package/src/mcp/mcp.test.ts +348 -0
- package/src/mcp/protocol.ts +172 -0
- package/src/mcp/server.ts +283 -0
- package/src/mcp/session.ts +139 -0
- package/src/mcp/tools.ts +391 -0
- package/src/plugins/catalogue.test.ts +48 -0
- package/src/plugins/catalogue.ts +113 -0
- package/src/plugins/node-import-scan.test.ts +28 -0
- package/src/plugins/node-import-scan.ts +98 -0
- package/src/plugins/supply-chain.test.ts +48 -0
- package/src/plugins/supply-chain.ts +460 -0
- package/src/release/index.ts +30 -0
- package/src/release/limits.ts +20 -0
- package/src/release/measure.ts +443 -0
- package/src/release/publish.ts +56 -0
- package/src/runs/bench.test.ts +93 -0
- package/src/runs/collect.ts +144 -0
- package/src/runs/drivers/clickhouse.ts +108 -0
- package/src/runs/drivers/files.ts +201 -0
- package/src/runs/drivers/memory.ts +94 -0
- package/src/runs/drivers/postgres.ts +110 -0
- package/src/runs/duckdb.ts +99 -0
- package/src/runs/index.ts +82 -0
- package/src/runs/outlier.ts +180 -0
- package/src/runs/parquet.ts +210 -0
- package/src/runs/privacy.ts +49 -0
- package/src/runs/runs.test.ts +324 -0
- package/src/runs/runtime.ts +229 -0
- package/src/runs/shred.ts +243 -0
- package/src/runs/telemetry.ts +10 -0
- package/src/runs/types.ts +179 -0
- package/src/runtime/bun.ts +140 -0
- package/src/runtime/cold-start.bench.ts +20 -0
- package/src/runtime/index.ts +46 -0
- package/src/runtime/primitives.ts +242 -0
- package/src/runtime/security.test.ts +170 -0
- package/src/runtime/security.ts +168 -0
- package/src/runtime/serve.test.ts +223 -0
- package/src/runtime/types.ts +217 -0
- package/src/runtime/web-standard.ts +77 -0
- package/src/test/create-test-app.test.ts +161 -0
- package/src/test/create-test-app.ts +533 -0
- package/src/test/index.ts +21 -0
- package/src/test/provisions.integration.test.ts +174 -0
- package/src/upgrade/codemods.test.ts +58 -0
- package/src/upgrade/codemods.ts +83 -0
- package/src/validation/index.ts +23 -0
- package/src/validation/standard-schema.test.ts +96 -0
- package/src/validation/standard-schema.ts +316 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `redis` signal driver — throughput path with internal outbox relay.
|
|
3
|
+
*
|
|
4
|
+
* Emit still enrols in a transactional outbox (semantics never regress).
|
|
5
|
+
* After commit, a relay pushes to Redis Streams (`once`) or pub/sub
|
|
6
|
+
* (`broadcast` / `live`). Consumer delivery is driven from the outbox so
|
|
7
|
+
* exactly-once / fan-out physics stay correct under `drain()`.
|
|
8
|
+
*
|
|
9
|
+
* Production bind: {@link createBunSignalRedisClient} (typed `publish` /
|
|
10
|
+
* `subscribe`; Streams via `send` — Bun 1.3.14 has no typed `xadd` yet).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { createSignalEngine } from "./signal-engine.ts";
|
|
14
|
+
import type {
|
|
15
|
+
SignalBus,
|
|
16
|
+
SignalDriver,
|
|
17
|
+
SignalOpenOptions,
|
|
18
|
+
SignalRedisClientLike,
|
|
19
|
+
} from "./signal-types.ts";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Bind {@link Bun.RedisClient} to {@link SignalRedisClientLike}.
|
|
23
|
+
*
|
|
24
|
+
* Streams (`XADD` / `XGROUP` / `XREADGROUP` / `XACK`) use `send` because
|
|
25
|
+
* Bun 1.3.14 still lacks typed stream helpers — that is a Bun limitation.
|
|
26
|
+
* Pub/sub uses typed `publish` / `subscribe` (gap closed vs earlier fake-only).
|
|
27
|
+
*
|
|
28
|
+
* @param url - Optional Redis URL
|
|
29
|
+
*/
|
|
30
|
+
export function createBunSignalRedisClient(
|
|
31
|
+
url?: string,
|
|
32
|
+
): SignalRedisClientLike {
|
|
33
|
+
const redis =
|
|
34
|
+
url !== undefined ? new Bun.RedisClient(url) : Bun.redis;
|
|
35
|
+
/** Subscribe blocks a connection — keep a dedicated client. */
|
|
36
|
+
let sub:
|
|
37
|
+
| InstanceType<typeof Bun.RedisClient>
|
|
38
|
+
| undefined;
|
|
39
|
+
|
|
40
|
+
function subClient(): InstanceType<typeof Bun.RedisClient> {
|
|
41
|
+
if (!sub) {
|
|
42
|
+
sub = url !== undefined ? new Bun.RedisClient(url) : new Bun.RedisClient();
|
|
43
|
+
}
|
|
44
|
+
return sub;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
async xadd(key, id, fields) {
|
|
49
|
+
const args: string[] = [key, id];
|
|
50
|
+
for (const [k, v] of Object.entries(fields)) {
|
|
51
|
+
args.push(k, v);
|
|
52
|
+
}
|
|
53
|
+
return String(await redis.send("XADD", args));
|
|
54
|
+
},
|
|
55
|
+
async xgroupCreate(key, group, id, opts) {
|
|
56
|
+
const args = ["CREATE", key, group, id];
|
|
57
|
+
if (opts?.mkstream) args.push("MKSTREAM");
|
|
58
|
+
try {
|
|
59
|
+
await redis.send("XGROUP", args);
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
if (!/BUSYGROUP/i.test(msg)) throw err;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
async xreadgroup(group, consumer, key, count) {
|
|
66
|
+
const reply = await redis.send("XREADGROUP", [
|
|
67
|
+
"GROUP",
|
|
68
|
+
group,
|
|
69
|
+
consumer,
|
|
70
|
+
"COUNT",
|
|
71
|
+
String(count),
|
|
72
|
+
"STREAMS",
|
|
73
|
+
key,
|
|
74
|
+
">",
|
|
75
|
+
]);
|
|
76
|
+
return parseXreadgroupReply(reply);
|
|
77
|
+
},
|
|
78
|
+
async xack(key, group, id) {
|
|
79
|
+
return Number(await redis.send("XACK", [key, group, id]));
|
|
80
|
+
},
|
|
81
|
+
async publish(channel, message) {
|
|
82
|
+
return redis.publish(channel, message);
|
|
83
|
+
},
|
|
84
|
+
async subscribe(channel, listener) {
|
|
85
|
+
const client = subClient();
|
|
86
|
+
await client.subscribe(channel, (message) => {
|
|
87
|
+
listener(message);
|
|
88
|
+
});
|
|
89
|
+
return () => {
|
|
90
|
+
void client.unsubscribe(channel);
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parse Redis `XREADGROUP` nested-array reply into field maps.
|
|
98
|
+
*
|
|
99
|
+
* @param reply - Raw `send` result
|
|
100
|
+
*/
|
|
101
|
+
export function parseXreadgroupReply(
|
|
102
|
+
reply: unknown,
|
|
103
|
+
): Array<{ id: string; fields: Record<string, string> }> {
|
|
104
|
+
if (reply == null || !Array.isArray(reply)) return [];
|
|
105
|
+
const out: Array<{ id: string; fields: Record<string, string> }> = [];
|
|
106
|
+
for (const stream of reply) {
|
|
107
|
+
if (!Array.isArray(stream) || stream.length < 2) continue;
|
|
108
|
+
const entries = stream[1];
|
|
109
|
+
if (!Array.isArray(entries)) continue;
|
|
110
|
+
for (const entry of entries) {
|
|
111
|
+
if (!Array.isArray(entry) || entry.length < 2) continue;
|
|
112
|
+
const id = String(entry[0]);
|
|
113
|
+
const flat = entry[1];
|
|
114
|
+
const fields: Record<string, string> = {};
|
|
115
|
+
if (Array.isArray(flat)) {
|
|
116
|
+
for (let i = 0; i + 1 < flat.length; i += 2) {
|
|
117
|
+
fields[String(flat[i])] = String(flat[i + 1]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
out.push({ id, fields });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* In-memory redis-protocol fake for signal streams + pub/sub.
|
|
128
|
+
*/
|
|
129
|
+
export function createSignalRedisFake(): SignalRedisClientLike & {
|
|
130
|
+
readonly streams: Map<
|
|
131
|
+
string,
|
|
132
|
+
Array<{ id: string; fields: Record<string, string> }>
|
|
133
|
+
>;
|
|
134
|
+
readonly published: Array<{ channel: string; message: string }>;
|
|
135
|
+
} {
|
|
136
|
+
const streams = new Map<
|
|
137
|
+
string,
|
|
138
|
+
Array<{ id: string; fields: Record<string, string> }>
|
|
139
|
+
>();
|
|
140
|
+
const groups = new Map<string, Set<string>>();
|
|
141
|
+
const claimed = new Map<string, Set<string>>();
|
|
142
|
+
const subs = new Map<string, Set<(message: string) => void>>();
|
|
143
|
+
const published: Array<{ channel: string; message: string }> = [];
|
|
144
|
+
let seq = 0;
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
streams,
|
|
148
|
+
published,
|
|
149
|
+
async xadd(key, id, fields) {
|
|
150
|
+
let list = streams.get(key);
|
|
151
|
+
if (!list) {
|
|
152
|
+
list = [];
|
|
153
|
+
streams.set(key, list);
|
|
154
|
+
}
|
|
155
|
+
const realId = id === "*" ? `${Date.now()}-${seq++}` : id;
|
|
156
|
+
list.push({ id: realId, fields: { ...fields } });
|
|
157
|
+
return realId;
|
|
158
|
+
},
|
|
159
|
+
async xgroupCreate(key, group, _id, opts) {
|
|
160
|
+
if (opts?.mkstream && !streams.has(key)) streams.set(key, []);
|
|
161
|
+
const gkey = `${key}::${group}`;
|
|
162
|
+
if (!groups.has(gkey)) groups.set(gkey, new Set());
|
|
163
|
+
if (!claimed.has(gkey)) claimed.set(gkey, new Set());
|
|
164
|
+
},
|
|
165
|
+
async xreadgroup(group, consumer, key, count) {
|
|
166
|
+
const gkey = `${key}::${group}`;
|
|
167
|
+
if (!groups.has(gkey)) {
|
|
168
|
+
await this.xgroupCreate(key, group, "0", { mkstream: true });
|
|
169
|
+
}
|
|
170
|
+
const seen = claimed.get(gkey)!;
|
|
171
|
+
const list = streams.get(key) ?? [];
|
|
172
|
+
const out: Array<{ id: string; fields: Record<string, string> }> = [];
|
|
173
|
+
for (const entry of list) {
|
|
174
|
+
if (seen.has(entry.id)) continue;
|
|
175
|
+
seen.add(entry.id);
|
|
176
|
+
out.push({
|
|
177
|
+
id: entry.id,
|
|
178
|
+
fields: { ...entry.fields, _consumer: consumer },
|
|
179
|
+
});
|
|
180
|
+
if (out.length >= count) break;
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
183
|
+
},
|
|
184
|
+
async xack() {
|
|
185
|
+
return 1;
|
|
186
|
+
},
|
|
187
|
+
async publish(channel, message) {
|
|
188
|
+
published.push({ channel, message });
|
|
189
|
+
const set = subs.get(channel);
|
|
190
|
+
if (!set) return 0;
|
|
191
|
+
for (const fn of set) fn(message);
|
|
192
|
+
return set.size;
|
|
193
|
+
},
|
|
194
|
+
async subscribe(channel, listener) {
|
|
195
|
+
let set = subs.get(channel);
|
|
196
|
+
if (!set) {
|
|
197
|
+
set = new Set();
|
|
198
|
+
subs.set(channel, set);
|
|
199
|
+
}
|
|
200
|
+
set.add(listener);
|
|
201
|
+
return () => {
|
|
202
|
+
set!.delete(listener);
|
|
203
|
+
};
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Open a redis signal bus (outbox + relay).
|
|
210
|
+
*
|
|
211
|
+
* @param options - Declarations / redis client / durable outbox path
|
|
212
|
+
*/
|
|
213
|
+
export async function openRedisSignal(
|
|
214
|
+
options: SignalOpenOptions,
|
|
215
|
+
): Promise<SignalBus> {
|
|
216
|
+
// Same DI shape as postgres/redis/s3: inject a client in tests; production
|
|
217
|
+
// binds Bun.redis (Streams via send until Bun ships typed xadd).
|
|
218
|
+
const redis = options.redis ?? createBunSignalRedisClient();
|
|
219
|
+
const outbox = await createSignalEngine("redis", options);
|
|
220
|
+
|
|
221
|
+
async function relayToRedis(signal: string, payload: unknown): Promise<void> {
|
|
222
|
+
const decl = options.signals.get(signal);
|
|
223
|
+
if (!decl) return;
|
|
224
|
+
const body = JSON.stringify(payload ?? null);
|
|
225
|
+
if (decl.delivery === "once") {
|
|
226
|
+
const key = `oke:signal:${signal}`;
|
|
227
|
+
await redis.xgroupCreate(key, "oke", "0", { mkstream: true });
|
|
228
|
+
await redis.xadd(key, "*", { payload: body, signal });
|
|
229
|
+
} else if (decl.delivery === "broadcast") {
|
|
230
|
+
await redis.publish(`oke:signal:bcast:${signal}`, body);
|
|
231
|
+
} else {
|
|
232
|
+
await redis.publish(`oke:signal:live:${signal}`, body);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
driverId: "redis",
|
|
238
|
+
async emit(signal, payload) {
|
|
239
|
+
await outbox.emit(signal, payload);
|
|
240
|
+
await relayToRedis(signal, payload);
|
|
241
|
+
},
|
|
242
|
+
async begin() {
|
|
243
|
+
const staged: Array<{ signal: string; payload: unknown }> = [];
|
|
244
|
+
const tx = await outbox.begin();
|
|
245
|
+
return {
|
|
246
|
+
write: (k, v) => tx.write(k, v),
|
|
247
|
+
async emit(signal, payload) {
|
|
248
|
+
staged.push({ signal, payload });
|
|
249
|
+
await tx.emit(signal, payload);
|
|
250
|
+
},
|
|
251
|
+
async commit() {
|
|
252
|
+
await tx.commit();
|
|
253
|
+
for (const e of staged) await relayToRedis(e.signal, e.payload);
|
|
254
|
+
},
|
|
255
|
+
rollback: () => tx.rollback(),
|
|
256
|
+
};
|
|
257
|
+
},
|
|
258
|
+
subscribe: (signal, subscriberId, handler) =>
|
|
259
|
+
outbox.subscribe(signal, subscriberId, handler),
|
|
260
|
+
live: (signal, handler) => outbox.live(signal, handler),
|
|
261
|
+
drain: () => outbox.drain(),
|
|
262
|
+
deadLetters: (s) => outbox.deadLetters(s),
|
|
263
|
+
inspect: (s) => outbox.inspect(s),
|
|
264
|
+
replay: (opts) => outbox.replay(opts),
|
|
265
|
+
discard: (opts) => outbox.discard(opts),
|
|
266
|
+
getWrite: (k) => outbox.getWrite(k),
|
|
267
|
+
close: () => outbox.close(),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Protocol-named redis signal driver. */
|
|
272
|
+
export const redisSignalDriver: SignalDriver = {
|
|
273
|
+
id: "redis",
|
|
274
|
+
open: openRedisSignal,
|
|
275
|
+
};
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Signal driver contracts — protocol-named (`memory` · `postgres` · `redis` · `nats`).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { SignalDelivery } from "../manifest/types.ts";
|
|
6
|
+
import type { SignalDecl } from "../elements/signal/declare.ts";
|
|
7
|
+
|
|
8
|
+
/** Protocol ids for signal drivers. */
|
|
9
|
+
export type SignalDriverId = "memory" | "postgres" | "redis" | "nats";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Typed failure reason preserved on every delivery attempt.
|
|
13
|
+
*
|
|
14
|
+
* Survives into the DLQ so operators can see the full attempt history.
|
|
15
|
+
*/
|
|
16
|
+
export interface SignalFailureReason {
|
|
17
|
+
/** Machine-readable failure code. */
|
|
18
|
+
readonly code: string;
|
|
19
|
+
/** Human-readable detail. */
|
|
20
|
+
readonly message: string;
|
|
21
|
+
/** Epoch-ms when the attempt failed. */
|
|
22
|
+
readonly at: number;
|
|
23
|
+
/** 1-based attempt number that failed. */
|
|
24
|
+
readonly attempt: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** A durable signal message. */
|
|
28
|
+
export interface SignalMessage {
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly signal: string;
|
|
31
|
+
readonly payload: unknown;
|
|
32
|
+
readonly delivery: SignalDelivery;
|
|
33
|
+
readonly attempts: number;
|
|
34
|
+
readonly failures: readonly SignalFailureReason[];
|
|
35
|
+
readonly createdAt: number;
|
|
36
|
+
/** Available for claim (once); null while locked / delivered. */
|
|
37
|
+
readonly availableAt: number;
|
|
38
|
+
readonly status: "pending" | "inflight" | "delivered" | "dead";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Dead-letter entry with full attempt history. */
|
|
42
|
+
export interface DeadLetter extends SignalMessage {
|
|
43
|
+
readonly status: "dead";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Per-subscriber lag / errors (broadcast physics). */
|
|
47
|
+
export interface SignalSubscriberStats {
|
|
48
|
+
/** Stable subscriber id. */
|
|
49
|
+
readonly id: string;
|
|
50
|
+
/** Undelivered message count for this subscriber. */
|
|
51
|
+
readonly lag: number;
|
|
52
|
+
/** Handler failures attributed to this subscriber. */
|
|
53
|
+
readonly errorCount: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Operator-plane snapshot of one signal's live queue state.
|
|
58
|
+
*
|
|
59
|
+
* Reads the real bus — the Console must not reimplement delivery physics.
|
|
60
|
+
*/
|
|
61
|
+
export interface SignalStats {
|
|
62
|
+
/** Signal name. */
|
|
63
|
+
readonly signal: string;
|
|
64
|
+
/** Delivery physics. */
|
|
65
|
+
readonly delivery: SignalDelivery;
|
|
66
|
+
/** Competing / fan-out pending count. */
|
|
67
|
+
readonly pending: number;
|
|
68
|
+
/** Claimed but not yet acked (`once`). */
|
|
69
|
+
readonly inflight: number;
|
|
70
|
+
/** Dead-letter count. */
|
|
71
|
+
readonly dead: number;
|
|
72
|
+
/** Successfully delivered count. */
|
|
73
|
+
readonly delivered: number;
|
|
74
|
+
/** Declared retry budget. */
|
|
75
|
+
readonly retries: number;
|
|
76
|
+
/** Whether exhausted messages enter the DLQ. */
|
|
77
|
+
readonly deadLetterEnabled: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Age (ms) of the oldest committed-but-not-yet-relayed/consumed message.
|
|
80
|
+
* Surfaces transactional outbox lag (postgres-default case).
|
|
81
|
+
*/
|
|
82
|
+
readonly outboxLagMs: number | null;
|
|
83
|
+
/** Broadcast subscriber rows. */
|
|
84
|
+
readonly subscribers: readonly SignalSubscriberStats[];
|
|
85
|
+
/** Live connection count (`delivery: "live"`). */
|
|
86
|
+
readonly connections: number;
|
|
87
|
+
/** Deliveries completed in the last trailing second. */
|
|
88
|
+
readonly throughputPerSec: number;
|
|
89
|
+
/** Declared payload schema when present. */
|
|
90
|
+
readonly schema: unknown;
|
|
91
|
+
/** Recent live payloads (newest last) for the payload monitor. */
|
|
92
|
+
readonly recentLive: readonly unknown[];
|
|
93
|
+
/** Dead-letter entries with typed per-attempt failures. */
|
|
94
|
+
readonly deadLetters: readonly DeadLetter[];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Options for {@link SignalBus.replay}. */
|
|
98
|
+
export interface SignalReplayOptions {
|
|
99
|
+
/** Signal name. */
|
|
100
|
+
readonly signal: string;
|
|
101
|
+
/** Dead-letter message ids to replay (empty = all dead for the signal). */
|
|
102
|
+
readonly messageIds?: readonly string[];
|
|
103
|
+
/** Broadcast: target a single subscriber. */
|
|
104
|
+
readonly subscriberId?: string;
|
|
105
|
+
/** Max replays per second — never an unthrottled flood. */
|
|
106
|
+
readonly ratePerSec: number;
|
|
107
|
+
/** When true, invoke handlers but leave DLQ rows untouched. */
|
|
108
|
+
readonly dryRun: boolean;
|
|
109
|
+
/** Optional payload overrides keyed by message id (schema form edits). */
|
|
110
|
+
readonly payloads?: Readonly<Record<string, unknown>>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** Per-message result from a replay / dry-run pass. */
|
|
114
|
+
export interface SignalReplayMessageResult {
|
|
115
|
+
readonly id: string;
|
|
116
|
+
readonly ok: boolean;
|
|
117
|
+
readonly error?: { readonly code: string; readonly message: string };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Irreversible effect intercepted during a dry-run replay. */
|
|
121
|
+
export interface SignalDryRunStub {
|
|
122
|
+
readonly kind: "send" | "ask";
|
|
123
|
+
readonly resource: string;
|
|
124
|
+
readonly messageId?: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Aggregate result of {@link SignalBus.replay}. */
|
|
128
|
+
export interface SignalReplayResult {
|
|
129
|
+
readonly attempted: number;
|
|
130
|
+
readonly succeeded: number;
|
|
131
|
+
readonly failed: number;
|
|
132
|
+
readonly dryRun: boolean;
|
|
133
|
+
readonly results: readonly SignalReplayMessageResult[];
|
|
134
|
+
/**
|
|
135
|
+
* Irreversible effects recorded as "would have fired" during dry-run.
|
|
136
|
+
* Empty for live replay.
|
|
137
|
+
*/
|
|
138
|
+
readonly wouldHaveFired: readonly SignalDryRunStub[];
|
|
139
|
+
/**
|
|
140
|
+
* When set, dry-run was refused because a safe stubbed run is impossible
|
|
141
|
+
* for this consumer shape (same refusal spirit as Traces).
|
|
142
|
+
*/
|
|
143
|
+
readonly refused?: {
|
|
144
|
+
readonly code: "dry_run_unsafe";
|
|
145
|
+
readonly reason: string;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Options for {@link SignalBus.discard}. */
|
|
150
|
+
export interface SignalDiscardOptions {
|
|
151
|
+
readonly signal: string;
|
|
152
|
+
readonly messageIds: readonly string[];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Unsubscribe handle. */
|
|
156
|
+
export type SignalUnsubscribe = () => void | Promise<void>;
|
|
157
|
+
|
|
158
|
+
/** Consumer handler for once / broadcast. */
|
|
159
|
+
export type SignalHandler = (message: SignalMessage) => void | Promise<void>;
|
|
160
|
+
|
|
161
|
+
/** Live client handler (payload only). */
|
|
162
|
+
export type LiveHandler = (payload: unknown) => void | Promise<void>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Transaction that enrols store writes and signal emits atomically.
|
|
166
|
+
*
|
|
167
|
+
* Postgres: emit inserts into the outbox on the caller's connection.
|
|
168
|
+
* Redis / NATS: emit still writes the outbox first; relay runs after commit.
|
|
169
|
+
*/
|
|
170
|
+
export interface SignalTransaction {
|
|
171
|
+
/**
|
|
172
|
+
* Stage a durable paired write (dual-write proof / chaos tests).
|
|
173
|
+
*
|
|
174
|
+
* @param key - Logical key
|
|
175
|
+
* @param value - Value
|
|
176
|
+
*/
|
|
177
|
+
write(key: string, value: unknown): Promise<void>;
|
|
178
|
+
/**
|
|
179
|
+
* Stage an emit into the same transaction.
|
|
180
|
+
*
|
|
181
|
+
* @param signal - Signal name
|
|
182
|
+
* @param payload - Payload
|
|
183
|
+
*/
|
|
184
|
+
emit(signal: string, payload?: unknown): Promise<void>;
|
|
185
|
+
/** Commit writes + emits together. */
|
|
186
|
+
commit(): Promise<void>;
|
|
187
|
+
/** Discard the transaction — nothing is visible. */
|
|
188
|
+
rollback(): Promise<void>;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Options when opening a signal bus. */
|
|
192
|
+
export interface SignalOpenOptions {
|
|
193
|
+
/** Registered signal declarations (name → decl). */
|
|
194
|
+
readonly signals: ReadonlyMap<string, SignalDecl>;
|
|
195
|
+
/** Clock. */
|
|
196
|
+
readonly now?: () => number;
|
|
197
|
+
/**
|
|
198
|
+
* Durable path for chaos / crash recovery tests.
|
|
199
|
+
* When set, committed state survives process death.
|
|
200
|
+
*/
|
|
201
|
+
readonly durablePath?: string;
|
|
202
|
+
/** Injected SQL client / connection for postgres outbox. */
|
|
203
|
+
readonly sql?: unknown;
|
|
204
|
+
/** Injected redis-protocol client (streams + pub/sub). */
|
|
205
|
+
readonly redis?: SignalRedisClientLike;
|
|
206
|
+
/** Injected NATS / JetStream-like client. */
|
|
207
|
+
readonly nats?: SignalNatsClientLike;
|
|
208
|
+
/** Outbox SQL for redis/nats relay (defaults to in-process). */
|
|
209
|
+
readonly outboxSql?: unknown;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Minimal Redis surface used by the signal redis driver.
|
|
214
|
+
* Streams for `once`, pub/sub for `broadcast` / `live`.
|
|
215
|
+
*/
|
|
216
|
+
export interface SignalRedisClientLike {
|
|
217
|
+
xadd(key: string, id: string, fields: Record<string, string>): Promise<string>;
|
|
218
|
+
xgroupCreate(
|
|
219
|
+
key: string,
|
|
220
|
+
group: string,
|
|
221
|
+
id: string,
|
|
222
|
+
opts?: { mkstream?: boolean },
|
|
223
|
+
): Promise<void>;
|
|
224
|
+
xreadgroup(
|
|
225
|
+
group: string,
|
|
226
|
+
consumer: string,
|
|
227
|
+
key: string,
|
|
228
|
+
count: number,
|
|
229
|
+
): Promise<Array<{ id: string; fields: Record<string, string> }>>;
|
|
230
|
+
xack(key: string, group: string, id: string): Promise<number>;
|
|
231
|
+
publish(channel: string, message: string): Promise<number>;
|
|
232
|
+
subscribe(
|
|
233
|
+
channel: string,
|
|
234
|
+
listener: (message: string) => void,
|
|
235
|
+
): Promise<() => void>;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** Minimal NATS / JetStream surface. */
|
|
239
|
+
export interface SignalNatsClientLike {
|
|
240
|
+
publish(subject: string, data: Uint8Array | string): Promise<void>;
|
|
241
|
+
subscribe(
|
|
242
|
+
subject: string,
|
|
243
|
+
opts: {
|
|
244
|
+
queue?: string;
|
|
245
|
+
callback: (data: Uint8Array) => void | Promise<void>;
|
|
246
|
+
},
|
|
247
|
+
): Promise<() => void>;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Open signal bus from a driver. */
|
|
251
|
+
export interface SignalBus {
|
|
252
|
+
readonly driverId: SignalDriverId;
|
|
253
|
+
/**
|
|
254
|
+
* Emit outside a transaction (auto-commits a one-shot txn).
|
|
255
|
+
*
|
|
256
|
+
* @param signal - Signal name
|
|
257
|
+
* @param payload - Payload
|
|
258
|
+
*/
|
|
259
|
+
emit(signal: string, payload?: unknown): Promise<void>;
|
|
260
|
+
/** Begin a transaction that enrols writes + emits. */
|
|
261
|
+
begin(): Promise<SignalTransaction>;
|
|
262
|
+
/**
|
|
263
|
+
* Subscribe a competing / fan-out consumer.
|
|
264
|
+
*
|
|
265
|
+
* @param signal - Signal name
|
|
266
|
+
* @param subscriberId - Stable subscriber id (exactly-once per id for once)
|
|
267
|
+
* @param handler - Message handler
|
|
268
|
+
*/
|
|
269
|
+
subscribe(
|
|
270
|
+
signal: string,
|
|
271
|
+
subscriberId: string,
|
|
272
|
+
handler: SignalHandler,
|
|
273
|
+
): Promise<SignalUnsubscribe>;
|
|
274
|
+
/**
|
|
275
|
+
* Client-subscribable live feed.
|
|
276
|
+
*
|
|
277
|
+
* @param signal - Signal name (`delivery: "live"`)
|
|
278
|
+
* @param handler - Payload handler
|
|
279
|
+
*/
|
|
280
|
+
live(signal: string, handler: LiveHandler): Promise<SignalUnsubscribe>;
|
|
281
|
+
/**
|
|
282
|
+
* Process pending work until idle (deterministic tests).
|
|
283
|
+
*/
|
|
284
|
+
drain(): Promise<void>;
|
|
285
|
+
/**
|
|
286
|
+
* Inspect dead-letter queue for a signal.
|
|
287
|
+
*
|
|
288
|
+
* @param signal - Signal name
|
|
289
|
+
*/
|
|
290
|
+
deadLetters(signal: string): Promise<readonly DeadLetter[]>;
|
|
291
|
+
/**
|
|
292
|
+
* Operator inspect — queue depths, subscribers, outbox lag, DLQ.
|
|
293
|
+
*
|
|
294
|
+
* @param signal - Optional name; omit for every registered signal
|
|
295
|
+
*/
|
|
296
|
+
inspect(signal?: string): Promise<readonly SignalStats[]>;
|
|
297
|
+
/**
|
|
298
|
+
* Replay dead letters at a controlled rate (or dry-run without mutating).
|
|
299
|
+
*
|
|
300
|
+
* @param options - Target messages, rate, dry-run, payload overrides
|
|
301
|
+
*/
|
|
302
|
+
replay(options: SignalReplayOptions): Promise<SignalReplayResult>;
|
|
303
|
+
/**
|
|
304
|
+
* Permanently discard dead-letter messages.
|
|
305
|
+
*
|
|
306
|
+
* @param options - Signal + message ids
|
|
307
|
+
*/
|
|
308
|
+
discard(options: SignalDiscardOptions): Promise<{ readonly discarded: number }>;
|
|
309
|
+
/**
|
|
310
|
+
* Read a durable paired write (post-commit / post-recovery).
|
|
311
|
+
*
|
|
312
|
+
* @param key - Key written via {@link SignalTransaction.write}
|
|
313
|
+
*/
|
|
314
|
+
getWrite(key: string): Promise<unknown>;
|
|
315
|
+
/** Close the bus. */
|
|
316
|
+
close(): Promise<void>;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** Signal driver factory. */
|
|
320
|
+
export interface SignalDriver {
|
|
321
|
+
readonly id: SignalDriverId;
|
|
322
|
+
/**
|
|
323
|
+
* Open a bus.
|
|
324
|
+
*
|
|
325
|
+
* @param options - Declarations and injected clients
|
|
326
|
+
*/
|
|
327
|
+
open(options: SignalOpenOptions): Promise<SignalBus>;
|
|
328
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sqlite` driver — binds `bun:sqlite` (never better-sqlite3).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Database, type SQLQueryBindings } from "bun:sqlite";
|
|
6
|
+
import type {
|
|
7
|
+
SqlConnectOptions,
|
|
8
|
+
SqlConnection,
|
|
9
|
+
SqlDriver,
|
|
10
|
+
SqlRow,
|
|
11
|
+
} from "./types.ts";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Open a bun:sqlite connection implementing {@link SqlConnection}.
|
|
15
|
+
*
|
|
16
|
+
* @param options - URL (`:memory:` / path) or injected Database
|
|
17
|
+
*/
|
|
18
|
+
export async function connectSqlite(
|
|
19
|
+
options: SqlConnectOptions = {},
|
|
20
|
+
): Promise<SqlConnection> {
|
|
21
|
+
const role = options.role ?? "primary";
|
|
22
|
+
const db =
|
|
23
|
+
options.client instanceof Database
|
|
24
|
+
? options.client
|
|
25
|
+
: new Database(options.url ?? ":memory:");
|
|
26
|
+
|
|
27
|
+
function asBindings(params: readonly unknown[]): SQLQueryBindings[] {
|
|
28
|
+
return params as SQLQueryBindings[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
driverId: "sqlite",
|
|
33
|
+
role,
|
|
34
|
+
async query(sql, params = []) {
|
|
35
|
+
const stmt = db.query(sql);
|
|
36
|
+
return stmt.all(...(asBindings(params) as never[])) as SqlRow[];
|
|
37
|
+
},
|
|
38
|
+
async exec(sql, params = []) {
|
|
39
|
+
const result = db.run(sql, ...(asBindings(params) as never[]));
|
|
40
|
+
return { changes: result.changes };
|
|
41
|
+
},
|
|
42
|
+
async close() {
|
|
43
|
+
db.close();
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Protocol-named sqlite driver. */
|
|
49
|
+
export const sqliteDriver: SqlDriver = {
|
|
50
|
+
id: "sqlite",
|
|
51
|
+
facet: "sql",
|
|
52
|
+
connect: connectSqlite,
|
|
53
|
+
};
|