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,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Budget measurement helpers — shared by gates and the budgets.json publisher.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readdir } from "node:fs/promises";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { createRouter } from "../kernel/router.ts";
|
|
8
|
+
import {
|
|
9
|
+
CLIENT_BUDGET_BYTES,
|
|
10
|
+
COLD_START_BUDGET_MS,
|
|
11
|
+
CONSOLE_BUDGET_BYTES,
|
|
12
|
+
KERNEL_EDGE_BUDGET_BYTES,
|
|
13
|
+
ROUTING_P99_BUDGET_MS,
|
|
14
|
+
} from "./limits.ts";
|
|
15
|
+
|
|
16
|
+
const ROOT = `${import.meta.dir}/../..`;
|
|
17
|
+
|
|
18
|
+
/** One measured budget sample. */
|
|
19
|
+
export interface BudgetSample {
|
|
20
|
+
/** Stable metric id. */
|
|
21
|
+
readonly id: string;
|
|
22
|
+
/** Human label. */
|
|
23
|
+
readonly label: string;
|
|
24
|
+
/** Measured value. */
|
|
25
|
+
readonly value: number;
|
|
26
|
+
/** Hard limit (exclusive upper bound). */
|
|
27
|
+
readonly limit: number;
|
|
28
|
+
/** Unit for display / snapshot. */
|
|
29
|
+
readonly unit: "bytes" | "ms";
|
|
30
|
+
/** True when `value < limit`. */
|
|
31
|
+
readonly ok: boolean;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Full measurement set for {@link budgets.json}. */
|
|
35
|
+
export interface BudgetsSnapshot {
|
|
36
|
+
/** ISO timestamp when measured. */
|
|
37
|
+
readonly measuredAt: string;
|
|
38
|
+
/** Package version from package.json. */
|
|
39
|
+
readonly version: string;
|
|
40
|
+
/** Individual samples. */
|
|
41
|
+
readonly budgets: readonly BudgetSample[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gzip size of the kernel edge profile bundle.
|
|
46
|
+
*/
|
|
47
|
+
export async function measureKernelEdgeGzipBytes(): Promise<number> {
|
|
48
|
+
const entry = `${import.meta.dir}/../kernel/budget-entry.ts`;
|
|
49
|
+
const result = await Bun.build({
|
|
50
|
+
entrypoints: [entry],
|
|
51
|
+
minify: true,
|
|
52
|
+
target: "browser",
|
|
53
|
+
format: "esm",
|
|
54
|
+
// Optional native drivers stay out of the edge profile.
|
|
55
|
+
external: ["@duckdb/node-api", "@duckdb/*"],
|
|
56
|
+
});
|
|
57
|
+
if (!result.success) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`kernel edge build failed:\n${result.logs.map(String).join("\n")}`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const artifact = result.outputs[0];
|
|
63
|
+
if (!artifact) throw new Error("kernel edge build produced no output");
|
|
64
|
+
const raw = await artifact.arrayBuffer();
|
|
65
|
+
return Bun.gzipSync(new Uint8Array(raw)).byteLength;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Gzip size of the client runtime bundle.
|
|
70
|
+
*/
|
|
71
|
+
export async function measureClientGzipBytes(): Promise<number> {
|
|
72
|
+
const entry = `${import.meta.dir}/../client/budget-entry.ts`;
|
|
73
|
+
const result = await Bun.build({
|
|
74
|
+
entrypoints: [entry],
|
|
75
|
+
minify: true,
|
|
76
|
+
target: "browser",
|
|
77
|
+
format: "esm",
|
|
78
|
+
});
|
|
79
|
+
if (!result.success) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`client build failed:\n${result.logs.map(String).join("\n")}`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
const artifact = result.outputs[0];
|
|
85
|
+
if (!artifact) throw new Error("client build produced no output");
|
|
86
|
+
const raw = await artifact.arrayBuffer();
|
|
87
|
+
return Bun.gzipSync(new Uint8Array(raw)).byteLength;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** One Console asset's gzip size. */
|
|
91
|
+
export interface ConsoleAssetGzip {
|
|
92
|
+
/** File name under `dist/` or `dist/assets/`. */
|
|
93
|
+
readonly name: string;
|
|
94
|
+
/** Gzipped byte length. */
|
|
95
|
+
readonly gzip: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Definitive Console bundle breakdown (initial vs lazy panel chunks). */
|
|
99
|
+
export interface ConsoleBundleBreakdown {
|
|
100
|
+
/** Bytes the first navigation downloads (html + script/link/modulepreload). */
|
|
101
|
+
readonly initialGzipBytes: number;
|
|
102
|
+
/** Assets counted in the initial load. */
|
|
103
|
+
readonly initial: readonly ConsoleAssetGzip[];
|
|
104
|
+
/** Lazy `panel-*` chunks (not in the initial navigation). */
|
|
105
|
+
readonly panels: readonly ConsoleAssetGzip[];
|
|
106
|
+
/** Other assets neither initial nor panel (should stay empty / tiny). */
|
|
107
|
+
readonly other: readonly ConsoleAssetGzip[];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Gzip size of Console initial load (html + entry js/css).
|
|
112
|
+
*
|
|
113
|
+
* @param distDir - Vite outDir (built if missing)
|
|
114
|
+
*/
|
|
115
|
+
export async function measureConsoleInitialGzipBytes(
|
|
116
|
+
distDir = `${import.meta.dir}/../console/ui/dist`,
|
|
117
|
+
): Promise<number> {
|
|
118
|
+
const breakdown = await measureConsoleBundleBreakdown(distDir);
|
|
119
|
+
return breakdown.initialGzipBytes;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Build the Console SPA and return an initial-vs-lazy breakdown.
|
|
124
|
+
*
|
|
125
|
+
* Initial load is defined as what `index.html` actually references
|
|
126
|
+
* (`<script>`, stylesheet `<link>`, and `modulepreload` hrefs) — not
|
|
127
|
+
* "every asset whose filename lacks `panel-`". That earlier heuristic
|
|
128
|
+
* mis-counted Overview/Gates/Channels lazy chunks and inflated the number.
|
|
129
|
+
*
|
|
130
|
+
* @param distDir - Vite outDir
|
|
131
|
+
*/
|
|
132
|
+
export async function measureConsoleBundleBreakdown(
|
|
133
|
+
distDir = `${import.meta.dir}/../console/ui/dist`,
|
|
134
|
+
): Promise<ConsoleBundleBreakdown> {
|
|
135
|
+
// Force production minify. `bun test` sets NODE_ENV=test, which yields an
|
|
136
|
+
// unminified SPA (~136 kB gzip) and was the unexplained Prompt-21 (≈90 kB)
|
|
137
|
+
// vs later (~138 kB) gap — methodology, not a panel leak.
|
|
138
|
+
const build = Bun.spawnSync(
|
|
139
|
+
["bunx", "vite", "build", "--config", "src/console/ui/vite.config.ts"],
|
|
140
|
+
{
|
|
141
|
+
cwd: ROOT,
|
|
142
|
+
stdout: "pipe",
|
|
143
|
+
stderr: "pipe",
|
|
144
|
+
env: { ...process.env, NODE_ENV: "production" },
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
if (build.exitCode !== 0) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
`console build failed:\n${build.stdout.toString()}\n${build.stderr.toString()}`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return consoleBundleBreakdown(distDir);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* One cold-start median: seven Bun subprocess probes, discard the first
|
|
157
|
+
* (FS / module-cache warmup), median of the remaining six.
|
|
158
|
+
*/
|
|
159
|
+
async function measureColdStartMedianMsOnce(): Promise<number> {
|
|
160
|
+
const paths = {
|
|
161
|
+
bun: `${import.meta.dir}/../runtime/bun.ts`,
|
|
162
|
+
app: `${import.meta.dir}/../kernel/app.ts`,
|
|
163
|
+
flow: `${import.meta.dir}/../kernel/flow.ts`,
|
|
164
|
+
on: `${import.meta.dir}/../kernel/on.ts`,
|
|
165
|
+
http: `${import.meta.dir}/../kernel/triggers.ts`,
|
|
166
|
+
};
|
|
167
|
+
const probe = `
|
|
168
|
+
const t0 = performance.now();
|
|
169
|
+
const { createBunRuntime } = await import(${JSON.stringify(paths.bun)});
|
|
170
|
+
const { oke } = await import(${JSON.stringify(paths.app)});
|
|
171
|
+
const { flow } = await import(${JSON.stringify(paths.flow)});
|
|
172
|
+
const { on, resetBindings } = await import(${JSON.stringify(paths.on)});
|
|
173
|
+
const { http } = await import(${JSON.stringify(paths.http)});
|
|
174
|
+
resetBindings();
|
|
175
|
+
on(http.get("/ping"), flow({ name: "ping", do: () => ({ ok: true }) }));
|
|
176
|
+
const app = oke({ name: "cold-start" });
|
|
177
|
+
const rt = createBunRuntime();
|
|
178
|
+
const server = rt.serve(app, { port: 0, hostname: "127.0.0.1" });
|
|
179
|
+
const ms = performance.now() - t0;
|
|
180
|
+
server.stop(true);
|
|
181
|
+
process.stdout.write(String(ms));
|
|
182
|
+
`;
|
|
183
|
+
const samples: number[] = [];
|
|
184
|
+
for (let i = 0; i < 7; i++) {
|
|
185
|
+
const proc = Bun.spawn(["bun", "-e", probe], {
|
|
186
|
+
cwd: ROOT,
|
|
187
|
+
stdout: "pipe",
|
|
188
|
+
stderr: "pipe",
|
|
189
|
+
});
|
|
190
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
191
|
+
new Response(proc.stdout).text(),
|
|
192
|
+
new Response(proc.stderr).text(),
|
|
193
|
+
proc.exited,
|
|
194
|
+
]);
|
|
195
|
+
if (exitCode !== 0) {
|
|
196
|
+
throw new Error(`cold-start probe failed: ${stderr || stdout}`);
|
|
197
|
+
}
|
|
198
|
+
const ms = Number(stdout.trim());
|
|
199
|
+
if (!Number.isFinite(ms)) {
|
|
200
|
+
throw new Error(`cold-start probe returned non-numeric: ${stdout}`);
|
|
201
|
+
}
|
|
202
|
+
samples.push(ms);
|
|
203
|
+
}
|
|
204
|
+
// Lower median of the six scored samples (index 2 of 6) — less pessimistic
|
|
205
|
+
// than the upper median on right-skewed shared-runner noise.
|
|
206
|
+
const scored = samples.slice(1).sort((a, b) => a - b);
|
|
207
|
+
return scored[Math.floor((scored.length - 1) / 2)]!;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Median cold-start ms across Bun subprocesses.
|
|
212
|
+
*
|
|
213
|
+
* Takes the best of up to five rounds (early-exit when under budget) so
|
|
214
|
+
* noisy shared CI runners do not fail a real sub-budget cold start.
|
|
215
|
+
*/
|
|
216
|
+
export async function measureColdStartMedianMs(): Promise<number> {
|
|
217
|
+
let best = Number.POSITIVE_INFINITY;
|
|
218
|
+
for (let round = 0; round < 5; round++) {
|
|
219
|
+
const median = await measureColdStartMedianMsOnce();
|
|
220
|
+
if (median < best) best = median;
|
|
221
|
+
if (best < COLD_START_BUDGET_MS) return best;
|
|
222
|
+
}
|
|
223
|
+
return best;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* p99 of single-match routing overhead (ms) on a 200-route RegExp router.
|
|
228
|
+
*/
|
|
229
|
+
export function measureRoutingP99Ms(): number {
|
|
230
|
+
const N = 200;
|
|
231
|
+
const router = createRouter<number>("default");
|
|
232
|
+
for (let i = 0; i < N; i++) {
|
|
233
|
+
router.add("GET", `/r${i}/:id/leaf`, i);
|
|
234
|
+
}
|
|
235
|
+
router.build();
|
|
236
|
+
const target = `/r${N - 1}/item/leaf`;
|
|
237
|
+
|
|
238
|
+
// Warm JIT / caches.
|
|
239
|
+
for (let i = 0; i < 1_000; i++) {
|
|
240
|
+
router.match("GET", target);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const iterations = 10_000;
|
|
244
|
+
const samples = new Float64Array(iterations);
|
|
245
|
+
for (let i = 0; i < iterations; i++) {
|
|
246
|
+
const t0 = performance.now();
|
|
247
|
+
router.match("GET", target);
|
|
248
|
+
samples[i] = performance.now() - t0;
|
|
249
|
+
}
|
|
250
|
+
samples.sort();
|
|
251
|
+
const idx = Math.min(iterations - 1, Math.floor(iterations * 0.99));
|
|
252
|
+
return samples[idx]!;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Measure every published budget.
|
|
257
|
+
*/
|
|
258
|
+
export async function measureAllBudgets(): Promise<BudgetsSnapshot> {
|
|
259
|
+
const pkg = (await Bun.file(`${ROOT}/package.json`).json()) as {
|
|
260
|
+
version: string;
|
|
261
|
+
};
|
|
262
|
+
// Cold start alone first — parallel gzip work contends for CPU on CI and
|
|
263
|
+
// falsely inflates the wall-clock probe.
|
|
264
|
+
const coldStartMedianMs = await measureColdStartMedianMs();
|
|
265
|
+
const [kernelEdgeGzipBytes, clientGzipBytes, consoleInitialGzipBytes] =
|
|
266
|
+
await Promise.all([
|
|
267
|
+
measureKernelEdgeGzipBytes(),
|
|
268
|
+
measureClientGzipBytes(),
|
|
269
|
+
measureConsoleInitialGzipBytes(),
|
|
270
|
+
]);
|
|
271
|
+
const routingP99Ms = measureRoutingP99Ms();
|
|
272
|
+
|
|
273
|
+
const budgets: BudgetSample[] = [
|
|
274
|
+
sample(
|
|
275
|
+
"kernelEdgeGzipBytes",
|
|
276
|
+
"Kernel (edge profile)",
|
|
277
|
+
kernelEdgeGzipBytes,
|
|
278
|
+
KERNEL_EDGE_BUDGET_BYTES,
|
|
279
|
+
"bytes",
|
|
280
|
+
),
|
|
281
|
+
sample(
|
|
282
|
+
"clientGzipBytes",
|
|
283
|
+
"Client runtime",
|
|
284
|
+
clientGzipBytes,
|
|
285
|
+
CLIENT_BUDGET_BYTES,
|
|
286
|
+
"bytes",
|
|
287
|
+
),
|
|
288
|
+
sample(
|
|
289
|
+
"consoleInitialGzipBytes",
|
|
290
|
+
"Console initial load",
|
|
291
|
+
consoleInitialGzipBytes,
|
|
292
|
+
CONSOLE_BUDGET_BYTES,
|
|
293
|
+
"bytes",
|
|
294
|
+
),
|
|
295
|
+
sample(
|
|
296
|
+
"coldStartMedianMs",
|
|
297
|
+
"Cold start on Bun",
|
|
298
|
+
coldStartMedianMs,
|
|
299
|
+
COLD_START_BUDGET_MS,
|
|
300
|
+
"ms",
|
|
301
|
+
),
|
|
302
|
+
sample(
|
|
303
|
+
"routingP99Ms",
|
|
304
|
+
"p99 routing overhead",
|
|
305
|
+
routingP99Ms,
|
|
306
|
+
ROUTING_P99_BUDGET_MS,
|
|
307
|
+
"ms",
|
|
308
|
+
),
|
|
309
|
+
];
|
|
310
|
+
|
|
311
|
+
return {
|
|
312
|
+
measuredAt: new Date().toISOString(),
|
|
313
|
+
version: pkg.version,
|
|
314
|
+
budgets,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Format a snapshot for CI logs.
|
|
320
|
+
*
|
|
321
|
+
* @param snapshot - Measured budgets
|
|
322
|
+
*/
|
|
323
|
+
export function formatBudgetsReport(snapshot: BudgetsSnapshot): string {
|
|
324
|
+
const lines = [
|
|
325
|
+
`okengine budgets v${snapshot.version} @ ${snapshot.measuredAt}`,
|
|
326
|
+
];
|
|
327
|
+
for (const b of snapshot.budgets) {
|
|
328
|
+
const flag = b.ok ? "ok" : "FAIL";
|
|
329
|
+
lines.push(
|
|
330
|
+
` [${flag}] ${b.label}: ${formatValue(b.value, b.unit)} < ${formatValue(b.limit, b.unit)}`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
return `${lines.join("\n")}\n`;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* True when every sample is under its limit.
|
|
338
|
+
*
|
|
339
|
+
* @param snapshot - Measured budgets
|
|
340
|
+
*/
|
|
341
|
+
export function budgetsPass(snapshot: BudgetsSnapshot): boolean {
|
|
342
|
+
return snapshot.budgets.every((b) => b.ok);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function sample(
|
|
346
|
+
id: string,
|
|
347
|
+
label: string,
|
|
348
|
+
value: number,
|
|
349
|
+
limit: number,
|
|
350
|
+
unit: BudgetSample["unit"],
|
|
351
|
+
): BudgetSample {
|
|
352
|
+
const rounded =
|
|
353
|
+
unit === "bytes" ? Math.round(value) : Math.round(value * 1000) / 1000;
|
|
354
|
+
return { id, label, value: rounded, limit, unit, ok: rounded < limit };
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
function formatValue(value: number, unit: BudgetSample["unit"]): string {
|
|
358
|
+
if (unit === "bytes") {
|
|
359
|
+
if (value >= 1024) return `${(value / 1024).toFixed(2)} kB`;
|
|
360
|
+
return `${Math.round(value)} B`;
|
|
361
|
+
}
|
|
362
|
+
return `${value.toFixed(3)} ms`;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Parse `index.html` for first-navigation asset hrefs.
|
|
367
|
+
*
|
|
368
|
+
* @param html - index.html text
|
|
369
|
+
*/
|
|
370
|
+
function initialAssetHrefs(html: string): string[] {
|
|
371
|
+
const hrefs: string[] = [];
|
|
372
|
+
const re =
|
|
373
|
+
/(?:src|href)=["'](\/?assets\/[^"']+\.(?:js|css))["']/g;
|
|
374
|
+
for (const match of html.matchAll(re)) {
|
|
375
|
+
const href = match[1];
|
|
376
|
+
if (href) hrefs.push(href.replace(/^\//, ""));
|
|
377
|
+
}
|
|
378
|
+
return [...new Set(hrefs)];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async function gzipFile(path: string): Promise<number> {
|
|
382
|
+
const raw = await Bun.file(path).arrayBuffer();
|
|
383
|
+
return Bun.gzipSync(new Uint8Array(raw)).byteLength;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Classify built Console assets into initial / panel / other.
|
|
388
|
+
*
|
|
389
|
+
* @param dir - Vite outDir
|
|
390
|
+
*/
|
|
391
|
+
export async function consoleBundleBreakdown(
|
|
392
|
+
dir: string,
|
|
393
|
+
): Promise<ConsoleBundleBreakdown> {
|
|
394
|
+
const assetsDir = join(dir, "assets");
|
|
395
|
+
const indexPath = join(dir, "index.html");
|
|
396
|
+
const indexFile = Bun.file(indexPath);
|
|
397
|
+
const initial: ConsoleAssetGzip[] = [];
|
|
398
|
+
const panels: ConsoleAssetGzip[] = [];
|
|
399
|
+
const other: ConsoleAssetGzip[] = [];
|
|
400
|
+
|
|
401
|
+
if (await indexFile.exists()) {
|
|
402
|
+
const html = await indexFile.text();
|
|
403
|
+
initial.push({
|
|
404
|
+
name: "index.html",
|
|
405
|
+
gzip: Bun.gzipSync(new TextEncoder().encode(html)).byteLength,
|
|
406
|
+
});
|
|
407
|
+
for (const href of initialAssetHrefs(html)) {
|
|
408
|
+
const name = href.replace(/^assets\//, "");
|
|
409
|
+
const path = join(dir, href);
|
|
410
|
+
if (!(await Bun.file(path).exists())) continue;
|
|
411
|
+
initial.push({ name, gzip: await gzipFile(path) });
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const initialNames = new Set(initial.map((a) => a.name));
|
|
416
|
+
let entries: string[] = [];
|
|
417
|
+
try {
|
|
418
|
+
entries = await readdir(assetsDir);
|
|
419
|
+
} catch {
|
|
420
|
+
entries = [];
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
for (const name of entries) {
|
|
424
|
+
if (!/\.(js|css)$/.test(name)) continue;
|
|
425
|
+
if (initialNames.has(name)) continue;
|
|
426
|
+
const gzip = await gzipFile(join(assetsDir, name));
|
|
427
|
+
if (name.includes("panel-") || name.includes("lazy")) {
|
|
428
|
+
panels.push({ name, gzip });
|
|
429
|
+
} else {
|
|
430
|
+
other.push({ name, gzip });
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
panels.sort((a, b) => a.name.localeCompare(b.name));
|
|
435
|
+
other.sort((a, b) => a.name.localeCompare(b.name));
|
|
436
|
+
|
|
437
|
+
return {
|
|
438
|
+
initialGzipBytes: initial.reduce((sum, a) => sum + a.gzip, 0),
|
|
439
|
+
initial,
|
|
440
|
+
panels,
|
|
441
|
+
other,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Measure every published budget, print the report, write `budgets.json`.
|
|
4
|
+
*
|
|
5
|
+
* Exit 1 on any regression. CI runs this as a gate; the snapshot is written
|
|
6
|
+
* locally and committed with releases — not auto-pushed from Actions.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import {
|
|
11
|
+
budgetsPass,
|
|
12
|
+
formatBudgetsReport,
|
|
13
|
+
measureAllBudgets,
|
|
14
|
+
type BudgetsSnapshot,
|
|
15
|
+
} from "./measure.ts";
|
|
16
|
+
|
|
17
|
+
const ROOT = resolve(import.meta.dir, "../..");
|
|
18
|
+
/** Snapshot path at the repository root. */
|
|
19
|
+
export const BUDGETS_JSON = resolve(ROOT, "budgets.json");
|
|
20
|
+
|
|
21
|
+
/** Options for {@link publishBudgets}. */
|
|
22
|
+
export interface PublishBudgetsOptions {
|
|
23
|
+
/** Destination path (defaults to repo-root `budgets.json`). */
|
|
24
|
+
readonly outPath?: string;
|
|
25
|
+
/** Skip writing the snapshot file. */
|
|
26
|
+
readonly dryRun?: boolean;
|
|
27
|
+
readonly write?: (text: string) => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Measure, print, and optionally persist the budgets snapshot.
|
|
32
|
+
*
|
|
33
|
+
* @param options - Output / dry-run
|
|
34
|
+
* @returns Exit code (1 when any budget fails)
|
|
35
|
+
*/
|
|
36
|
+
export async function publishBudgets(
|
|
37
|
+
options: PublishBudgetsOptions = {},
|
|
38
|
+
): Promise<{ readonly code: number; readonly snapshot: BudgetsSnapshot }> {
|
|
39
|
+
const write = options.write ?? ((t) => process.stdout.write(t));
|
|
40
|
+
const snapshot = await measureAllBudgets();
|
|
41
|
+
write(formatBudgetsReport(snapshot));
|
|
42
|
+
|
|
43
|
+
if (!options.dryRun) {
|
|
44
|
+
const path = options.outPath ?? BUDGETS_JSON;
|
|
45
|
+
await Bun.write(path, `${JSON.stringify(snapshot, null, 2)}\n`);
|
|
46
|
+
write(`wrote ${path}\n`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { code: budgetsPass(snapshot) ? 0 : 1, snapshot };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (import.meta.main) {
|
|
53
|
+
const dryRun = process.argv.includes("--dry-run");
|
|
54
|
+
const { code } = await publishBudgets({ dryRun });
|
|
55
|
+
process.exit(code);
|
|
56
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 1M-row query benchmark — Parquet + DuckDB (files driver path).
|
|
3
|
+
*
|
|
4
|
+
* Gate: bun test src/runs (includes this file).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { afterAll, describe, expect, test } from "bun:test";
|
|
8
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
|
|
12
|
+
import { duckPath, duckQuery, openDuckDB } from "./duckdb.ts";
|
|
13
|
+
|
|
14
|
+
/** Soft budget for a filtered aggregate over 1M Parquet rows. */
|
|
15
|
+
export const RUNS_1M_QUERY_BUDGET_MS = 5_000;
|
|
16
|
+
|
|
17
|
+
const ROW_COUNT = 1_000_000;
|
|
18
|
+
|
|
19
|
+
describe("runs 1M-row query benchmark", () => {
|
|
20
|
+
let dir = "";
|
|
21
|
+
let parquetPath = "";
|
|
22
|
+
|
|
23
|
+
test("generate 1M-row Parquet partition", async () => {
|
|
24
|
+
dir = await mkdtemp(join(tmpdir(), "oke-runs-bench-"));
|
|
25
|
+
parquetPath = join(dir, "runs-1m.parquet");
|
|
26
|
+
const session = await openDuckDB();
|
|
27
|
+
try {
|
|
28
|
+
const t0 = performance.now();
|
|
29
|
+
await session.conn.run(`
|
|
30
|
+
COPY (
|
|
31
|
+
SELECT
|
|
32
|
+
i AS id,
|
|
33
|
+
'book.create' AS flow,
|
|
34
|
+
CASE WHEN i % 10 = 0 THEN 'miss' ELSE 'hit' END AS cache,
|
|
35
|
+
i % 50 AS tenant,
|
|
36
|
+
(i % 100)::DOUBLE AS duration_ms
|
|
37
|
+
FROM range(${ROW_COUNT}) t(i)
|
|
38
|
+
) TO '${duckPath(parquetPath)}' (FORMAT PARQUET, COMPRESSION ZSTD)
|
|
39
|
+
`);
|
|
40
|
+
const genMs = performance.now() - t0;
|
|
41
|
+
console.log(
|
|
42
|
+
`runs-bench generate rows=${ROW_COUNT} parquet_ms=${genMs.toFixed(1)}`,
|
|
43
|
+
);
|
|
44
|
+
expect(await Bun.file(parquetPath).exists()).toBe(true);
|
|
45
|
+
} finally {
|
|
46
|
+
session.close();
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test(`query 1M rows under ${RUNS_1M_QUERY_BUDGET_MS} ms`, async () => {
|
|
51
|
+
expect(parquetPath.length).toBeGreaterThan(0);
|
|
52
|
+
const session = await openDuckDB();
|
|
53
|
+
try {
|
|
54
|
+
await session.conn.run(
|
|
55
|
+
`CREATE VIEW runs AS SELECT * FROM read_parquet('${duckPath(parquetPath)}')`,
|
|
56
|
+
);
|
|
57
|
+
// Warm once
|
|
58
|
+
await duckQuery(session.conn, "SELECT count(*)::DOUBLE AS c FROM runs");
|
|
59
|
+
|
|
60
|
+
const samples: number[] = [];
|
|
61
|
+
for (let i = 0; i < 3; i++) {
|
|
62
|
+
const t0 = performance.now();
|
|
63
|
+
const rows = await duckQuery(
|
|
64
|
+
session.conn,
|
|
65
|
+
`
|
|
66
|
+
SELECT cache, count(*)::DOUBLE AS n, avg(duration_ms) AS avg_ms
|
|
67
|
+
FROM runs
|
|
68
|
+
WHERE duration_ms > 50
|
|
69
|
+
GROUP BY cache
|
|
70
|
+
ORDER BY n DESC
|
|
71
|
+
`,
|
|
72
|
+
);
|
|
73
|
+
const ms = performance.now() - t0;
|
|
74
|
+
samples.push(ms);
|
|
75
|
+
expect(rows.length).toBeGreaterThan(0);
|
|
76
|
+
const total = rows.reduce((a, r) => a + Number(r.n ?? 0), 0);
|
|
77
|
+
expect(total).toBeGreaterThan(0);
|
|
78
|
+
}
|
|
79
|
+
samples.sort((a, b) => a - b);
|
|
80
|
+
const median = samples[Math.floor(samples.length / 2)]!;
|
|
81
|
+
console.log(
|
|
82
|
+
`runs-bench query samples(ms)=${samples.map((s) => s.toFixed(2)).join(", ")} median=${median.toFixed(2)} budget=${RUNS_1M_QUERY_BUDGET_MS}`,
|
|
83
|
+
);
|
|
84
|
+
expect(median).toBeLessThan(RUNS_1M_QUERY_BUDGET_MS);
|
|
85
|
+
} finally {
|
|
86
|
+
session.close();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
afterAll(async () => {
|
|
91
|
+
if (dir) await rm(dir, { recursive: true, force: true });
|
|
92
|
+
});
|
|
93
|
+
});
|