okengine 0.2.6 → 0.3.2
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 +33 -30
- package/README.md +74 -340
- package/{spec/manifest.v1.schema.json → manifest.v1.schema.json} +40 -9
- package/package.json +47 -44
- package/site/content/docs/ai/llms-txt.mdx +54 -0
- package/site/content/docs/ai/mcp.mdx +123 -0
- package/site/content/docs/ai/meta.json +5 -0
- package/site/content/docs/ai/skills.mdx +53 -0
- package/site/content/docs/console/access.mdx +29 -0
- package/site/content/docs/console/ai.mdx +35 -0
- package/site/content/docs/console/architecture.mdx +35 -0
- package/site/content/docs/console/channels.mdx +37 -0
- package/site/content/docs/console/clock.mdx +31 -0
- package/site/content/docs/console/flows.mdx +31 -0
- package/site/content/docs/console/gates.mdx +35 -0
- package/site/content/docs/console/manifest-diff.mdx +34 -0
- package/site/content/docs/console/meta.json +23 -0
- package/site/content/docs/console/overview.mdx +40 -0
- package/site/content/docs/console/plugins.mdx +41 -0
- package/site/content/docs/console/privacy.mdx +32 -0
- package/site/content/docs/console/runs.mdx +40 -0
- package/site/content/docs/console/signals.mdx +31 -0
- package/site/content/docs/console/store.mdx +32 -0
- package/site/content/docs/console/tenancy.mdx +32 -0
- package/site/content/docs/console/traces.mdx +34 -0
- package/site/content/docs/console/vault.mdx +37 -0
- package/site/content/docs/elements/ai.mdx +180 -0
- package/site/content/docs/elements/channel.mdx +167 -0
- package/site/content/docs/elements/clock.mdx +182 -0
- package/site/content/docs/elements/flow.mdx +288 -0
- package/site/content/docs/elements/gate.mdx +171 -0
- package/site/content/docs/elements/meta.json +5 -0
- package/site/content/docs/elements/signal.mdx +171 -0
- package/site/content/docs/elements/store.mdx +320 -0
- package/site/content/docs/elements/vault.mdx +263 -0
- package/site/content/docs/get-started/basic-usage.mdx +124 -0
- package/site/content/docs/get-started/comparison.mdx +65 -0
- package/site/content/docs/get-started/installation.mdx +113 -0
- package/site/content/docs/get-started/introduction.mdx +123 -0
- package/site/content/docs/get-started/meta.json +5 -0
- package/site/content/docs/index.mdx +63 -0
- package/site/content/docs/meta.json +5 -0
- package/site/content/docs/plugins/compression.mdx +60 -0
- package/site/content/docs/plugins/cors.mdx +92 -0
- package/site/content/docs/plugins/csrf.mdx +96 -0
- package/site/content/docs/plugins/ip-allowlist.mdx +92 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +101 -0
- package/site/content/docs/plugins/meta.json +15 -0
- package/site/content/docs/plugins/security-headers.mdx +136 -0
- package/site/content/docs/reference/cli.md +101 -0
- package/site/content/docs/reference/configuration.mdx +159 -0
- package/site/content/docs/reference/environment-variables.mdx +87 -0
- package/site/content/docs/reference/errors.mdx +80 -0
- package/site/content/docs/reference/fx.mdx +117 -0
- package/site/content/docs/reference/meta.json +5 -0
- package/site/content/docs/reference/plugins.mdx +249 -0
- package/site/content/docs/reference/security.md +63 -0
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +56 -31
- package/src/auth/invoke-as.ts +1 -3
- package/src/auth/operator.ts +8 -26
- package/src/auth/planes.ts +2 -7
- package/src/auth/plugin.ts +4 -7
- package/src/auth/roles.ts +1 -5
- package/src/auth/sessions.ts +10 -39
- package/src/cli/args.ts +1 -5
- package/src/cli/ask-dev-mode.ts +40 -0
- package/src/cli/build.ts +1 -2
- package/src/cli/client-add.test.ts +8 -15
- package/src/cli/client-add.ts +5 -14
- package/src/cli/completion.test.ts +1 -5
- package/src/cli/completion.ts +4 -17
- package/src/cli/db-auto-push.test.ts +64 -0
- package/src/cli/db-auto-push.ts +72 -0
- package/src/cli/db.test.ts +189 -0
- package/src/cli/db.ts +456 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +193 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev-schema-sync.test.ts +66 -0
- package/src/cli/dev-schema-sync.ts +139 -0
- package/src/cli/dev.test.ts +264 -15
- package/src/cli/dev.ts +355 -139
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +27 -8
- package/src/cli/docker.ts +11 -3
- package/src/cli/doctor-diff.test.ts +1 -5
- package/src/cli/doctor-diff.ts +17 -46
- package/src/cli/doctor-pii.ts +2 -7
- package/src/cli/doctor.test.ts +26 -4
- package/src/cli/doctor.ts +35 -11
- package/src/cli/drizzle-env.test.ts +67 -0
- package/src/cli/drizzle-env.ts +78 -0
- package/src/cli/ensure-drizzle-config.ts +50 -0
- package/src/cli/eval.ts +4 -14
- package/src/cli/gates-list.ts +1 -4
- package/src/cli/hero-meta.test.ts +17 -19
- package/src/cli/hero-meta.ts +20 -30
- package/src/cli/images.ts +3 -8
- package/src/cli/index.ts +11 -2
- package/src/cli/load-config.images.test.ts +14 -14
- package/src/cli/load-config.ts +47 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +65 -0
- package/src/cli/openbao-bootstrap.test.ts +147 -0
- package/src/cli/openbao-bootstrap.ts +280 -0
- package/src/cli/openbao-restart.integration.test.ts +136 -0
- package/src/cli/ports.test.ts +7 -14
- package/src/cli/ports.ts +7 -5
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/resolve-dev-sql-env.test.ts +48 -0
- package/src/cli/resolve-dev-sql-env.ts +42 -0
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +8 -10
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- package/src/cli/vault-cmd.ts +63 -0
- package/src/client/budget-entry.ts +1 -6
- package/src/client/create.test.ts +6 -12
- package/src/client/create.ts +2 -8
- package/src/client/errors.ts +1 -4
- package/src/client/index.ts +1 -6
- package/src/client/notes-contract.test.ts +4 -13
- package/src/client/transport.ts +9 -30
- package/src/client/types.ts +15 -30
- package/src/compiler/aot.test.ts +2 -9
- package/src/compiler/aot.ts +1 -4
- package/src/compiler/differential.test.ts +3 -11
- package/src/compiler/dynamic.ts +1 -4
- package/src/compiler/effects-infer.ts +8 -34
- package/src/compiler/emit.ts +1 -3
- package/src/compiler/extract.test.ts +136 -30
- package/src/compiler/extract.ts +485 -157
- package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
- package/src/compiler/fixtures/skyport.expected.json +24 -83
- package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
- package/src/compiler/http-parse.ts +2 -9
- package/src/compiler/index.ts +1 -5
- package/src/compiler/response.ts +16 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +55 -34
- package/src/config/index.ts +177 -46
- package/src/config/resolve-driver.test.ts +28 -17
- package/src/console/budget.test.ts +1 -4
- package/src/console/index.ts +1 -4
- package/src/console/server/access.test.ts +15 -43
- package/src/console/server/access.ts +19 -49
- package/src/console/server/ai.test.ts +3 -11
- package/src/console/server/ai.ts +23 -46
- package/src/console/server/app.ts +16 -45
- package/src/console/server/auth-rate.test.ts +4 -12
- package/src/console/server/bind.ts +1 -5
- package/src/console/server/channels.test.ts +2 -6
- package/src/console/server/channels.ts +10 -35
- package/src/console/server/claim.ts +2 -8
- package/src/console/server/clock.test.ts +2 -6
- package/src/console/server/clock.ts +8 -26
- package/src/console/server/console.test.ts +1 -3
- package/src/console/server/diff.test.ts +5 -17
- package/src/console/server/diff.ts +10 -31
- package/src/console/server/dry-run.audit.test.ts +2 -8
- package/src/console/server/flows.ts +64 -233
- package/src/console/server/gates.test.ts +14 -50
- package/src/console/server/gates.ts +13 -48
- package/src/console/server/index.ts +2 -9
- package/src/console/server/live.ts +3 -12
- package/src/console/server/operator-db.test.ts +4 -15
- package/src/console/server/operator-db.ts +13 -32
- package/src/console/server/plugin.ts +50 -53
- package/src/console/server/plugins.test.ts +2 -6
- package/src/console/server/plugins.ts +17 -56
- package/src/console/server/runs-pii.ts +2 -7
- package/src/console/server/security.gate.test.ts +18 -40
- package/src/console/server/serve.ts +10 -25
- package/src/console/server/signals.test.ts +1 -3
- package/src/console/server/signals.ts +17 -40
- package/src/console/server/state.ts +21 -59
- package/src/console/server/store.test.ts +20 -22
- package/src/console/server/store.ts +31 -76
- package/src/console/server/vault.test.ts +12 -29
- package/src/console/server/vault.ts +44 -66
- package/src/console/ui/access/AccessA11yView.tsx +6 -21
- package/src/console/ui/access/a11y.test.tsx +3 -12
- package/src/console/ui/access/acknowledgement.test.ts +1 -4
- package/src/console/ui/access/acknowledgement.ts +1 -3
- package/src/console/ui/access/blast-radius.ts +1 -3
- package/src/console/ui/access/confirmation.test.ts +1 -5
- package/src/console/ui/access/confirmation.ts +1 -4
- package/src/console/ui/access/fixture.ts +1 -5
- package/src/console/ui/access/grantable.test.ts +1 -3
- package/src/console/ui/access/grantable.ts +2 -7
- package/src/console/ui/access/index.ts +2 -9
- package/src/console/ui/access/provenance.test.ts +1 -3
- package/src/console/ui/access/provenance.ts +2 -6
- package/src/console/ui/access/search.test.ts +1 -5
- package/src/console/ui/access/search.ts +2 -6
- package/src/console/ui/ai/AiA11yView.tsx +6 -17
- package/src/console/ui/ai/a11y.test.tsx +2 -5
- package/src/console/ui/ai/fixture.ts +2 -7
- package/src/console/ui/ai/format.ts +1 -3
- package/src/console/ui/ai/group.test.ts +1 -3
- package/src/console/ui/ai/group.ts +4 -12
- package/src/console/ui/ai/index.ts +2 -9
- package/src/console/ui/ai/promotion.test.ts +2 -7
- package/src/console/ui/ai/promotion.ts +4 -13
- package/src/console/ui/ai/search.test.ts +2 -11
- package/src/console/ui/ai/search.ts +3 -13
- package/src/console/ui/ai/types.ts +1 -8
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
- package/src/console/ui/architecture/a11y.test.tsx +1 -2
- package/src/console/ui/architecture/declared.ts +1 -5
- package/src/console/ui/architecture/index.ts +7 -35
- package/src/console/ui/architecture/layout.ts +1 -3
- package/src/console/ui/architecture/pathologies.ts +10 -19
- package/src/console/ui/architecture/search.ts +6 -15
- package/src/console/ui/architecture/traffic.ts +4 -14
- package/src/console/ui/architecture/types.ts +2 -10
- package/src/console/ui/architecture/view.test.ts +7 -19
- package/src/console/ui/architecture/view.ts +9 -36
- package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
- package/src/console/ui/channels/a11y.test.tsx +1 -2
- package/src/console/ui/channels/confirmation.test.ts +1 -4
- package/src/console/ui/channels/confirmation.ts +1 -4
- package/src/console/ui/channels/findings.ts +1 -5
- package/src/console/ui/channels/index.ts +2 -8
- package/src/console/ui/channels/locale.test.ts +1 -3
- package/src/console/ui/channels/locale.ts +2 -8
- package/src/console/ui/channels/search.ts +4 -13
- package/src/console/ui/channels/taxonomy.ts +1 -3
- package/src/console/ui/clock/ClockA11yView.tsx +9 -26
- package/src/console/ui/clock/a11y.test.tsx +2 -5
- package/src/console/ui/clock/confirmation.test.ts +1 -3
- package/src/console/ui/clock/confirmation.ts +1 -4
- package/src/console/ui/clock/findings.ts +1 -4
- package/src/console/ui/clock/health.ts +2 -7
- package/src/console/ui/clock/index.ts +2 -10
- package/src/console/ui/clock/search.test.ts +1 -3
- package/src/console/ui/clock/search.ts +2 -6
- package/src/console/ui/clock/timeline.test.ts +1 -3
- package/src/console/ui/clock/waiting-on.test.ts +1 -5
- package/src/console/ui/clock/waiting-on.ts +2 -7
- package/src/console/ui/diff/DiffA11yView.tsx +8 -17
- package/src/console/ui/diff/a11y.test.tsx +2 -5
- package/src/console/ui/diff/group.test.ts +3 -13
- package/src/console/ui/diff/group.ts +2 -8
- package/src/console/ui/diff/index.ts +2 -8
- package/src/console/ui/diff/search.test.ts +1 -5
- package/src/console/ui/diff/search.ts +4 -16
- package/src/console/ui/diff/summary.ts +1 -2
- package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
- package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
- package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
- package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
- package/src/console/ui/flows/a11y.test.tsx +2 -8
- package/src/console/ui/flows/buffer.test.ts +3 -11
- package/src/console/ui/flows/buffer.ts +4 -11
- package/src/console/ui/flows/confirmation.ts +1 -3
- package/src/console/ui/flows/contract.test.ts +3 -7
- package/src/console/ui/flows/contract.ts +12 -36
- package/src/console/ui/flows/graph.test.ts +3 -11
- package/src/console/ui/flows/graph.ts +5 -15
- package/src/console/ui/flows/index.ts +1 -6
- package/src/console/ui/flows/save-as-test.ts +1 -3
- package/src/console/ui/flows/search.ts +8 -25
- package/src/console/ui/flows/tiers.ts +2 -9
- package/src/console/ui/gates/GatesA11yView.tsx +4 -13
- package/src/console/ui/gates/a11y.test.tsx +2 -5
- package/src/console/ui/gates/audit.ts +1 -3
- package/src/console/ui/gates/denial.test.ts +1 -3
- package/src/console/ui/gates/denial.ts +4 -12
- package/src/console/ui/gates/findings.ts +1 -3
- package/src/console/ui/gates/group.test.ts +3 -3
- package/src/console/ui/gates/group.ts +3 -11
- package/src/console/ui/gates/index.ts +2 -10
- package/src/console/ui/gates/search.ts +3 -10
- package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
- package/src/console/ui/overview/a11y.test.tsx +1 -2
- package/src/console/ui/overview/busiest.ts +1 -3
- package/src/console/ui/overview/compose.ts +1 -13
- package/src/console/ui/overview/cost.ts +34 -38
- package/src/console/ui/overview/fixture.ts +21 -26
- package/src/console/ui/overview/golden.ts +4 -14
- package/src/console/ui/overview/index.ts +2 -9
- package/src/console/ui/overview/rank.test.ts +3 -10
- package/src/console/ui/overview/rank.ts +2 -7
- package/src/console/ui/overview/slo.test.ts +5 -9
- package/src/console/ui/overview/slo.ts +6 -23
- package/src/console/ui/overview/verdict.ts +3 -10
- package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
- package/src/console/ui/plugins/a11y.test.tsx +1 -2
- package/src/console/ui/plugins/fixture.ts +2 -4
- package/src/console/ui/plugins/group.test.ts +1 -3
- package/src/console/ui/plugins/group.ts +1 -6
- package/src/console/ui/plugins/index.ts +3 -13
- package/src/console/ui/plugins/search.ts +7 -19
- package/src/console/ui/runs/RunsA11yView.tsx +5 -20
- package/src/console/ui/runs/a11y.test.tsx +2 -5
- package/src/console/ui/runs/explain.ts +2 -6
- package/src/console/ui/runs/group.ts +3 -12
- package/src/console/ui/runs/histogram.test.ts +2 -11
- package/src/console/ui/runs/histogram.ts +1 -4
- package/src/console/ui/runs/index.ts +4 -18
- package/src/console/ui/runs/project.ts +2 -6
- package/src/console/ui/runs/query.test.ts +1 -3
- package/src/console/ui/runs/query.ts +12 -35
- package/src/console/ui/runs/search.ts +5 -19
- package/src/console/ui/runs/trace-link.test.ts +2 -6
- package/src/console/ui/runs/trace-link.ts +4 -16
- package/src/console/ui/runs/types.ts +1 -3
- package/src/console/ui/shell/App.tsx +2 -10
- package/src/console/ui/shell/client.ts +22 -115
- package/src/console/ui/shell/components/ui.tsx +1 -4
- package/src/console/ui/shell/layout/Shell.tsx +2 -4
- package/src/console/ui/shell/main.tsx +31 -96
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
- package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
- package/src/console/ui/shell/setup/Wizard.tsx +3 -5
- package/src/console/ui/shell/styles.css +1 -2
- package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
- package/src/console/ui/signals/a11y.test.tsx +2 -5
- package/src/console/ui/signals/confirmation.test.ts +1 -5
- package/src/console/ui/signals/confirmation.ts +2 -6
- package/src/console/ui/signals/dry-run.ts +1 -3
- package/src/console/ui/signals/durable.ts +1 -3
- package/src/console/ui/signals/findings.ts +1 -3
- package/src/console/ui/signals/group.test.ts +2 -8
- package/src/console/ui/signals/group.ts +2 -10
- package/src/console/ui/signals/index.ts +1 -4
- package/src/console/ui/signals/monitor.ts +2 -7
- package/src/console/ui/signals/schema-form.test.ts +3 -14
- package/src/console/ui/signals/schema-form.ts +1 -4
- package/src/console/ui/signals/search.ts +4 -13
- package/src/console/ui/store/StoreA11yView.tsx +3 -9
- package/src/console/ui/store/a11y.test.tsx +2 -5
- package/src/console/ui/store/confirmation.test.ts +1 -3
- package/src/console/ui/store/confirmation.ts +1 -4
- package/src/console/ui/store/dry-run.ts +2 -5
- package/src/console/ui/store/fixture.ts +1 -2
- package/src/console/ui/store/group.test.ts +1 -6
- package/src/console/ui/store/group.ts +1 -4
- package/src/console/ui/store/index.ts +1 -5
- package/src/console/ui/store/search.ts +2 -6
- package/src/console/ui/store/will-not-fire.ts +1 -2
- package/src/console/ui/traces/TracesA11yView.tsx +10 -29
- package/src/console/ui/traces/a11y.test.tsx +1 -2
- package/src/console/ui/traces/chain.test.ts +5 -19
- package/src/console/ui/traces/chain.ts +1 -3
- package/src/console/ui/traces/critical-path.test.ts +1 -3
- package/src/console/ui/traces/critical-path.ts +2 -6
- package/src/console/ui/traces/filter.test.ts +2 -6
- package/src/console/ui/traces/filter.ts +5 -13
- package/src/console/ui/traces/fold.test.ts +4 -12
- package/src/console/ui/traces/fold.ts +1 -3
- package/src/console/ui/traces/mini.ts +1 -3
- package/src/console/ui/traces/replay.test.ts +1 -3
- package/src/console/ui/traces/replay.ts +1 -3
- package/src/console/ui/traces/sampling.ts +1 -4
- package/src/console/ui/traces/search.ts +4 -17
- package/src/console/ui/traces/tier.ts +1 -3
- package/src/console/ui/vault/VaultA11yView.tsx +5 -17
- package/src/console/ui/vault/a11y.test.tsx +1 -2
- package/src/console/ui/vault/blast-radius.ts +1 -3
- package/src/console/ui/vault/confirmation.test.ts +1 -5
- package/src/console/ui/vault/confirmation.ts +1 -4
- package/src/console/ui/vault/dormant.test.ts +1 -4
- package/src/console/ui/vault/export-safe.test.ts +1 -5
- package/src/console/ui/vault/export-safe.ts +1 -4
- package/src/console/ui/vault/fixture.ts +3 -3
- package/src/console/ui/vault/group.ts +1 -2
- package/src/console/ui/vault/index.ts +2 -10
- package/src/console/ui/vault/search.ts +2 -6
- package/src/console/ui/vault/types.ts +1 -1
- package/src/console/xss.gate.test.ts +1 -3
- package/src/docker/compose.ts +215 -27
- package/src/docker/derive.ts +6 -14
- package/src/docker/docker.test.ts +118 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +9 -6
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +6 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/openbao.ts +47 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +11 -2
- package/src/docker/recipes/rustfs.ts +32 -0
- package/src/docker/stack-id.test.ts +73 -5
- package/src/docker/stack-id.ts +124 -33
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/stack.ts +36 -4
- package/src/docker/types.ts +16 -4
- package/src/docs-origin.ts +4 -4
- package/src/drivers/ai-anthropic.ts +5 -14
- package/src/drivers/ai-mock.ts +2 -5
- package/src/drivers/ai-openai-compatible.ts +4 -10
- package/src/drivers/ai-providers.test.ts +6 -13
- package/src/drivers/bun-native-completeness.test.ts +6 -15
- package/src/drivers/channel-console.ts +6 -7
- package/src/drivers/channel-fcm.ts +20 -30
- package/src/drivers/channel-resend.ts +1 -3
- package/src/drivers/channel-smtp.ts +2 -6
- package/src/drivers/channel-types.ts +2 -12
- package/src/drivers/channel-unifonic.ts +2 -6
- package/src/drivers/channel-wa-cloud.ts +2 -6
- package/src/drivers/channel-webpush.ts +21 -60
- package/src/drivers/conformance.test.ts +2 -10
- package/src/drivers/conformance.ts +8 -21
- package/src/drivers/drizzle-dialect.test.ts +20 -0
- package/src/drivers/drizzle-dialect.ts +37 -0
- package/src/drivers/fs.ts +2 -8
- package/src/drivers/index.ts +12 -57
- package/src/drivers/memory.ts +287 -75
- package/src/drivers/pgvector.ts +7 -11
- package/src/drivers/postgres.ts +7 -13
- package/src/drivers/redis.ts +13 -37
- package/src/drivers/s3.ts +15 -18
- package/src/drivers/signal-engine.ts +12 -49
- package/src/drivers/signal-memory.ts +2 -8
- package/src/drivers/signal-nats.ts +4 -9
- package/src/drivers/signal-postgres.ts +62 -129
- package/src/drivers/signal-redis.ts +7 -21
- package/src/drivers/signal-types.ts +1 -4
- package/src/drivers/sqlite.ts +3 -12
- package/src/drivers/types.ts +4 -23
- package/src/drivers/vault-driver-removal.test.ts +55 -0
- package/src/drivers/vault-env.ts +2 -6
- package/src/drivers/vault-infisical.ts +1 -5
- package/src/drivers/vault-managed.ts +1 -5
- package/src/drivers/vault-memory.ts +1 -5
- package/src/drivers/vault-openbao.test.ts +97 -0
- package/src/drivers/vault-openbao.ts +103 -40
- package/src/drivers/vault-types.ts +3 -16
- package/src/elements/ai/declare.ts +4 -14
- package/src/elements/ai/eval.ts +2 -6
- package/src/elements/ai/pii.ts +1 -3
- package/src/elements/ai/runtime.ts +12 -50
- package/src/elements/ai/schema.ts +4 -15
- package/src/elements/ai.test.ts +13 -24
- package/src/elements/ai.ts +1 -5
- package/src/elements/channel/consent.ts +3 -12
- package/src/elements/channel/costs.ts +4 -15
- package/src/elements/channel/declare.ts +1 -4
- package/src/elements/channel/email-auth.ts +1 -4
- package/src/elements/channel/locale.ts +2 -10
- package/src/elements/channel/mask.ts +1 -3
- package/src/elements/channel/mime.ts +2 -12
- package/src/elements/channel/outcomes.test.ts +1 -5
- package/src/elements/channel/outcomes.ts +5 -15
- package/src/elements/channel/receipts.ts +2 -7
- package/src/elements/channel/runtime.ts +28 -74
- package/src/elements/channel/suppression.ts +8 -14
- package/src/elements/channel.test.ts +8 -31
- package/src/elements/channel.ts +3 -14
- package/src/elements/clock/actions.ts +6 -18
- package/src/elements/clock/declare.ts +1 -3
- package/src/elements/clock/dst.ts +1 -5
- package/src/elements/clock/durable.ts +4 -16
- package/src/elements/clock/health.ts +2 -7
- package/src/elements/clock/leader.ts +2 -9
- package/src/elements/clock/reconcile.ts +4 -15
- package/src/elements/clock/runtime.ts +2 -5
- package/src/elements/clock/schedule.ts +4 -20
- package/src/elements/clock.test.ts +2 -7
- package/src/elements/clock.ts +5 -23
- package/src/elements/gate/permissions.ts +1 -4
- package/src/elements/gate/runtime.ts +7 -28
- package/src/elements/gate.ts +1 -5
- package/src/elements/index.ts +9 -7
- package/src/elements/signal/declare.ts +2 -7
- package/src/elements/signal/reconcile.test.ts +1 -4
- package/src/elements/signal/runtime.ts +1 -3
- package/src/elements/signal.test.ts +3 -15
- package/src/elements/signal.ts +2 -8
- package/src/elements/store/cache.test.ts +46 -0
- package/src/elements/store/cache.ts +3 -11
- package/src/elements/store/classify.ts +5 -22
- package/src/elements/store/declare.ts +11 -17
- package/src/elements/store/domain-ddl.test.ts +86 -0
- package/src/elements/store/emit-drizzle.ts +363 -0
- package/src/elements/store/files-policy.test.ts +1 -5
- package/src/elements/store/files-policy.ts +4 -12
- package/src/elements/store/load-plugin-tables.ts +103 -0
- package/src/elements/store/missing-relation.test.ts +83 -0
- package/src/elements/store/missing-relation.ts +38 -0
- package/src/elements/store/replica.ts +1 -4
- package/src/elements/store/resource-list-docs.fixture.ts +56 -0
- package/src/elements/store/resource-list-docs.test.ts +79 -0
- package/src/elements/store/resource.test.ts +253 -0
- package/src/elements/store/resource.ts +786 -0
- package/src/elements/store/runtime.ts +25 -28
- package/src/elements/store/schema-decl.test.ts +227 -0
- package/src/elements/store/schema-decl.ts +516 -0
- package/src/elements/store/sql-condition.test.ts +132 -0
- package/src/elements/store/sql-condition.ts +293 -65
- package/src/elements/store/sql-session.test.ts +135 -0
- package/src/elements/store/sql-session.ts +241 -84
- package/src/elements/store/table.ts +69 -23
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +53 -31
- package/src/elements/vault/chain.ts +34 -0
- package/src/elements/vault/declare.ts +22 -32
- package/src/elements/vault/fingerprint.ts +2 -7
- package/src/elements/vault/redact.ts +2 -6
- package/src/elements/vault/runtime.ts +19 -33
- package/src/elements/vault.test.ts +12 -55
- package/src/elements/vault.ts +9 -13
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +92 -118
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.test.ts +60 -0
- package/src/kernel/boot-bind/channel.ts +61 -5
- package/src/kernel/boot-bind/clock.ts +2 -6
- package/src/kernel/boot-bind/gate.ts +2 -8
- package/src/kernel/boot-bind/runs.ts +1 -3
- package/src/kernel/boot-bind/signal.ts +3 -10
- package/src/kernel/boot-bind/store.test.ts +27 -18
- package/src/kernel/boot-bind/store.ts +93 -52
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -10
- package/src/kernel/boot.ts +30 -77
- package/src/kernel/budget.test.ts +1 -3
- package/src/kernel/capability.ts +3 -10
- package/src/kernel/dry-run.test.ts +1 -4
- package/src/kernel/dry-run.ts +3 -11
- package/src/kernel/edge.test.ts +68 -0
- package/src/kernel/effects.test.ts +1 -5
- package/src/kernel/effects.ts +4 -11
- package/src/kernel/errors.registry.test.ts +2 -8
- package/src/kernel/errors.ts +23 -32
- package/src/kernel/flow.test.ts +12 -25
- package/src/kernel/flow.ts +13 -25
- package/src/kernel/fx.test.ts +31 -40
- package/src/kernel/fx.ts +135 -90
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +43 -10
- package/src/kernel/hooks.ts +25 -12
- package/src/kernel/index.ts +11 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +45 -9
- package/src/kernel/pipeline.test.ts +10 -19
- package/src/kernel/pipeline.ts +5 -17
- package/src/kernel/plug.ts +4 -11
- package/src/kernel/plugin/conflicts.test.ts +13 -25
- package/src/kernel/plugin/decorate.test.ts +8 -13
- package/src/kernel/plugin/scoping.test.ts +4 -11
- package/src/kernel/plugin.ts +81 -27
- package/src/kernel/registry-isolation.test.ts +74 -0
- package/src/kernel/registry.ts +102 -30
- package/src/kernel/router.test.ts +15 -13
- package/src/kernel/router.ts +9 -29
- package/src/kernel/routing-budget.test.ts +1 -3
- package/src/kernel/run-telemetry.ts +1 -3
- package/src/kernel/triggers.ts +63 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/fixtures/skyport.manifest.json +1 -1
- package/src/manifest/index.ts +3 -10
- package/src/manifest/types.ts +30 -6
- package/src/manifest/undeclared.test.ts +4 -12
- package/src/manifest/undeclared.ts +1 -2
- package/src/manifest/validate.test.ts +2 -6
- package/src/manifest/validate.ts +5 -15
- package/src/mcp/authorization.ts +8 -27
- package/src/mcp/confirmation.ts +3 -10
- package/src/mcp/data.ts +2 -6
- package/src/mcp/docs-index.ts +4 -7
- package/src/mcp/docs-mcp.test.ts +3 -12
- package/src/mcp/docs-server.ts +7 -27
- package/src/mcp/docs-tools.ts +2 -6
- package/src/mcp/index.ts +1 -6
- package/src/mcp/injection.gate.test.ts +4 -18
- package/src/mcp/mcp.test.ts +18 -49
- package/src/mcp/protocol.ts +3 -10
- package/src/mcp/server.ts +11 -52
- package/src/mcp/session.ts +4 -14
- package/src/mcp/tools.ts +14 -50
- package/src/plugins/catalogue.test.ts +3 -7
- package/src/plugins/catalogue.ts +1 -3
- package/src/plugins/compression.test.ts +127 -0
- package/src/plugins/compression.ts +94 -0
- package/src/plugins/config-source.test.ts +204 -0
- package/src/plugins/config-source.ts +209 -0
- package/src/plugins/cors.test.ts +138 -0
- package/src/plugins/cors.ts +129 -0
- package/src/plugins/csrf.test.ts +102 -0
- package/src/plugins/csrf.ts +86 -0
- package/src/plugins/headers.ts +54 -0
- package/src/plugins/index.ts +26 -0
- package/src/plugins/ip-allowlist.test.ts +105 -0
- package/src/plugins/ip-allowlist.ts +76 -0
- package/src/plugins/maintenance-mode.test.ts +91 -0
- package/src/plugins/maintenance-mode.ts +85 -0
- package/src/plugins/node-import-scan.ts +2 -5
- package/src/plugins/security-headers.test.ts +243 -0
- package/src/plugins/security-headers.ts +255 -0
- package/src/plugins/supply-chain.ts +5 -17
- package/src/release/exports.ts +3 -8
- package/src/release/measure.exports.test.ts +1 -3
- package/src/release/measure.ts +16 -45
- package/src/runs/bench.test.ts +1 -3
- package/src/runs/collect.ts +8 -25
- package/src/runs/drivers/clickhouse.ts +2 -9
- package/src/runs/drivers/files.ts +9 -31
- package/src/runs/drivers/memory.ts +5 -22
- package/src/runs/drivers/postgres.ts +8 -20
- package/src/runs/duckdb.ts +2 -8
- package/src/runs/index.ts +3 -14
- package/src/runs/outlier.ts +3 -10
- package/src/runs/parquet.ts +8 -26
- package/src/runs/privacy.ts +2 -8
- package/src/runs/runs.test.ts +3 -9
- package/src/runs/runtime.ts +7 -32
- package/src/runs/shred.ts +10 -29
- package/src/runs/types.ts +1 -4
- package/src/runtime/bun.ts +4 -15
- package/src/runtime/cold-start.bench.ts +1 -3
- package/src/runtime/dev-request-log.test.ts +1 -4
- package/src/runtime/dev-request-log.ts +1 -4
- package/src/runtime/index.ts +1 -6
- package/src/runtime/primitives.ts +5 -4
- package/src/runtime/security.ts +3 -13
- package/src/runtime/serve.test.ts +4 -7
- package/src/runtime/types.ts +1 -4
- package/src/runtime/web-standard.ts +3 -15
- package/src/term.test.ts +4 -6
- package/src/term.ts +49 -98
- package/src/test/create-test-app.test.ts +4 -14
- package/src/test/create-test-app.ts +27 -33
- package/src/test/provisions.integration.test.ts +3 -11
- package/src/upgrade/codemods.test.ts +25 -6
- package/src/upgrade/codemods.ts +116 -3
- package/src/validation/standard-schema.test.ts +2 -5
- package/src/validation/standard-schema.ts +13 -33
- package/docs/spec/console.md +0 -739
- package/docs/spec/example.md +0 -1196
- package/docs/spec/four-applications.md +0 -1195
- package/docs/spec/unified-theory.md +0 -489
- package/src/cli/doc-drift.test.ts +0 -146
- package/src/cli/doc-drift.ts +0 -430
- package/src/cli/doctor-diff-examples.ts +0 -92
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
- package/src/drivers/vault-sops.ts +0 -271
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
* error hierarchy via sently). Fallback chains record every attempt.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
FallbackTransport,
|
|
10
|
-
type FallbackAttempt,
|
|
11
|
-
type Transport,
|
|
12
|
-
} from "sently";
|
|
8
|
+
import { FallbackTransport, type FallbackAttempt, type Transport } from "sently";
|
|
13
9
|
import { RetryTransport } from "sently/transports/retry";
|
|
14
10
|
import type {
|
|
15
11
|
ChannelAttempt,
|
|
@@ -20,14 +16,8 @@ import type {
|
|
|
20
16
|
import type { ChannelMedium } from "../../manifest/types.ts";
|
|
21
17
|
import type { ConsentStore } from "./consent.ts";
|
|
22
18
|
import type { ChannelTemplateDecl } from "./declare.ts";
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
type MediumCosts,
|
|
26
|
-
} from "./costs.ts";
|
|
27
|
-
import {
|
|
28
|
-
resolveLocale,
|
|
29
|
-
type LocaleChainStep,
|
|
30
|
-
} from "./locale.ts";
|
|
19
|
+
import { DEFAULT_MEDIUM_COSTS, type MediumCosts } from "./costs.ts";
|
|
20
|
+
import { resolveLocale, type LocaleChainStep } from "./locale.ts";
|
|
31
21
|
import type { DeliveryOutcomeState } from "./outcomes.ts";
|
|
32
22
|
import {
|
|
33
23
|
createReceiptLedger,
|
|
@@ -36,20 +26,14 @@ import {
|
|
|
36
26
|
type IngestOutcomeInput,
|
|
37
27
|
type ReceiptLedger,
|
|
38
28
|
} from "./receipts.ts";
|
|
39
|
-
import {
|
|
40
|
-
createSuppressionStore,
|
|
41
|
-
type SuppressionStore,
|
|
42
|
-
} from "./suppression.ts";
|
|
29
|
+
import { createSuppressionStore, type SuppressionStore } from "./suppression.ts";
|
|
43
30
|
|
|
44
31
|
/** Locale catalog: template → locale → rendered body. */
|
|
45
32
|
export type TemplateCatalog = Readonly<
|
|
46
33
|
Record<
|
|
47
34
|
string,
|
|
48
35
|
Readonly<
|
|
49
|
-
Record<
|
|
50
|
-
string,
|
|
51
|
-
{ readonly subject?: string; readonly text?: string; readonly html?: string }
|
|
52
|
-
>
|
|
36
|
+
Record<string, { readonly subject?: string; readonly text?: string; readonly html?: string }>
|
|
53
37
|
>
|
|
54
38
|
>
|
|
55
39
|
>;
|
|
@@ -107,10 +91,7 @@ export interface ChannelRuntime {
|
|
|
107
91
|
* @param template - Template name
|
|
108
92
|
* @param options - Recipient / data / locale / via
|
|
109
93
|
*/
|
|
110
|
-
send(
|
|
111
|
-
template: string,
|
|
112
|
-
options: ChannelSendOptions,
|
|
113
|
-
): Promise<ChannelSendResult>;
|
|
94
|
+
send(template: string, options: ChannelSendOptions): Promise<ChannelSendResult>;
|
|
114
95
|
/**
|
|
115
96
|
* Ingest a post-send provider outcome (bounce / complaint / …).
|
|
116
97
|
* Hard bounce auto-adds suppression. Console projects the ledger — never
|
|
@@ -126,18 +107,14 @@ export interface ChannelRuntime {
|
|
|
126
107
|
*
|
|
127
108
|
* @param options - Templates + drivers + catalog
|
|
128
109
|
*/
|
|
129
|
-
export function createChannelRuntime(
|
|
130
|
-
options: CreateChannelRuntimeOptions = {},
|
|
131
|
-
): ChannelRuntime {
|
|
110
|
+
export function createChannelRuntime(options: CreateChannelRuntimeOptions = {}): ChannelRuntime {
|
|
132
111
|
const templates = new Map<string, ChannelTemplateDecl>();
|
|
133
112
|
for (const t of options.templates ?? []) {
|
|
134
113
|
templates.set(t.name, t);
|
|
135
114
|
}
|
|
136
115
|
const suppression =
|
|
137
116
|
options.suppression ??
|
|
138
|
-
createSuppressionStore(
|
|
139
|
-
options.consent ? { consent: options.consent } : {},
|
|
140
|
-
);
|
|
117
|
+
createSuppressionStore(options.consent ? { consent: options.consent } : {});
|
|
141
118
|
const receipts = options.receipts ?? createReceiptLedger();
|
|
142
119
|
const costs = options.costs ?? { ...DEFAULT_MEDIUM_COSTS };
|
|
143
120
|
const catalog = options.catalog ?? {};
|
|
@@ -151,8 +128,7 @@ export function createChannelRuntime(
|
|
|
151
128
|
data: Readonly<Record<string, unknown>>,
|
|
152
129
|
): { subject?: string; text?: string; html?: string } {
|
|
153
130
|
const byLocale = catalog[template];
|
|
154
|
-
const entry =
|
|
155
|
-
byLocale?.[locale] ?? byLocale?.[defaultLocale] ?? byLocale?.en;
|
|
131
|
+
const entry = byLocale?.[locale] ?? byLocale?.[defaultLocale] ?? byLocale?.en;
|
|
156
132
|
if (!entry) {
|
|
157
133
|
return {
|
|
158
134
|
subject: template,
|
|
@@ -161,9 +137,7 @@ export function createChannelRuntime(
|
|
|
161
137
|
}
|
|
162
138
|
const interpolate = (s: string | undefined): string | undefined => {
|
|
163
139
|
if (s === undefined) return undefined;
|
|
164
|
-
return s.replace(/\{\{(\w+)\}\}/g, (_, key: string) =>
|
|
165
|
-
String(data[key] ?? ""),
|
|
166
|
-
);
|
|
140
|
+
return s.replace(/\{\{(\w+)\}\}/g, (_, key: string) => String(data[key] ?? ""));
|
|
167
141
|
};
|
|
168
142
|
return {
|
|
169
143
|
subject: interpolate(entry.subject),
|
|
@@ -172,10 +146,7 @@ export function createChannelRuntime(
|
|
|
172
146
|
};
|
|
173
147
|
}
|
|
174
148
|
|
|
175
|
-
function driversFor(
|
|
176
|
-
medium: ChannelMedium,
|
|
177
|
-
via?: readonly string[],
|
|
178
|
-
): ChannelDriver[] {
|
|
149
|
+
function driversFor(medium: ChannelMedium, via?: readonly string[]): ChannelDriver[] {
|
|
179
150
|
let list = drivers;
|
|
180
151
|
if (via && via.length > 0) {
|
|
181
152
|
list = via
|
|
@@ -184,13 +155,11 @@ export function createChannelRuntime(
|
|
|
184
155
|
}
|
|
185
156
|
return list.filter((d) => {
|
|
186
157
|
if (medium === "email" || medium === "any") {
|
|
187
|
-
return
|
|
188
|
-
d.channel?.mediums.includes("any")
|
|
158
|
+
return (
|
|
159
|
+
!!d.transport || d.channel?.mediums.includes(medium) || d.channel?.mediums.includes("any")
|
|
160
|
+
);
|
|
189
161
|
}
|
|
190
|
-
return (
|
|
191
|
-
d.channel?.mediums.includes(medium) ||
|
|
192
|
-
d.channel?.mediums.includes("any")
|
|
193
|
-
);
|
|
162
|
+
return d.channel?.mediums.includes(medium) || d.channel?.mediums.includes("any");
|
|
194
163
|
});
|
|
195
164
|
}
|
|
196
165
|
|
|
@@ -202,9 +171,7 @@ export function createChannelRuntime(
|
|
|
202
171
|
const transports: Transport[] = [];
|
|
203
172
|
for (const d of chain) {
|
|
204
173
|
if (!d.transport) continue;
|
|
205
|
-
const t = options.retry
|
|
206
|
-
? new RetryTransport(d.transport)
|
|
207
|
-
: d.transport;
|
|
174
|
+
const t = options.retry ? new RetryTransport(d.transport) : d.transport;
|
|
208
175
|
transports.push(t);
|
|
209
176
|
}
|
|
210
177
|
if (transports.length === 0) {
|
|
@@ -215,9 +182,7 @@ export function createChannelRuntime(
|
|
|
215
182
|
const fallback = new FallbackTransport(transports, {
|
|
216
183
|
onFallback(failedIndex, error) {
|
|
217
184
|
const provider =
|
|
218
|
-
transports[failedIndex]?.provider ??
|
|
219
|
-
chain[failedIndex]?.id ??
|
|
220
|
-
`driver-${failedIndex}`;
|
|
185
|
+
transports[failedIndex]?.provider ?? chain[failedIndex]?.id ?? `driver-${failedIndex}`;
|
|
221
186
|
recorded.push({ provider, error });
|
|
222
187
|
attempts.push({
|
|
223
188
|
driverId: provider,
|
|
@@ -317,9 +282,7 @@ export function createChannelRuntime(
|
|
|
317
282
|
};
|
|
318
283
|
}
|
|
319
284
|
|
|
320
|
-
function classifySendFailure(
|
|
321
|
-
attempts: readonly ChannelAttempt[],
|
|
322
|
-
): DeliveryOutcomeState {
|
|
285
|
+
function classifySendFailure(attempts: readonly ChannelAttempt[]): DeliveryOutcomeState {
|
|
323
286
|
const err = attempts
|
|
324
287
|
.map((a) => a.error ?? "")
|
|
325
288
|
.join(" ")
|
|
@@ -344,14 +307,9 @@ export function createChannelRuntime(
|
|
|
344
307
|
const existing = receipts.byMessageId(input.messageId);
|
|
345
308
|
if (input.state === "hard-bounce") {
|
|
346
309
|
const subject = input.to ?? existing?.to;
|
|
347
|
-
const medium = (input.medium ??
|
|
348
|
-
existing?.medium ??
|
|
349
|
-
"email") as ChannelMedium;
|
|
310
|
+
const medium = (input.medium ?? existing?.medium ?? "email") as ChannelMedium;
|
|
350
311
|
if (subject) {
|
|
351
|
-
suppression.addPriorBounce(
|
|
352
|
-
subject,
|
|
353
|
-
medium === "any" ? "email" : medium,
|
|
354
|
-
);
|
|
312
|
+
suppression.addPriorBounce(subject, medium === "any" ? "email" : medium);
|
|
355
313
|
}
|
|
356
314
|
}
|
|
357
315
|
|
|
@@ -384,15 +342,12 @@ export function createChannelRuntime(
|
|
|
384
342
|
throw new Error(`channel: unknown template "${template}"`);
|
|
385
343
|
}
|
|
386
344
|
const medium = decl.medium;
|
|
387
|
-
const checkMedium: ChannelMedium =
|
|
388
|
-
medium === "any" ? "email" : medium;
|
|
345
|
+
const checkMedium: ChannelMedium = medium === "any" ? "email" : medium;
|
|
389
346
|
|
|
390
347
|
const suppressed = suppression.isSuppressed(opts.to, checkMedium);
|
|
391
348
|
if (suppressed.suppressed) {
|
|
392
349
|
const status: DeliveryStatus =
|
|
393
|
-
suppressed.reason === "opted-out"
|
|
394
|
-
? "suppressed/opted-out"
|
|
395
|
-
: "suppressed/prior-bounce";
|
|
350
|
+
suppressed.reason === "opted-out" ? "suppressed/opted-out" : "suppressed/prior-bounce";
|
|
396
351
|
const resolved = resolveLocale({
|
|
397
352
|
locale: opts.locale,
|
|
398
353
|
profileLocale: opts.profileLocale,
|
|
@@ -409,10 +364,7 @@ export function createChannelRuntime(
|
|
|
409
364
|
status,
|
|
410
365
|
attempts: [],
|
|
411
366
|
at: now(),
|
|
412
|
-
error:
|
|
413
|
-
suppressed.reason === "opted-out"
|
|
414
|
-
? "opted out"
|
|
415
|
-
: "prior hard bounce",
|
|
367
|
+
error: suppressed.reason === "opted-out" ? "opted out" : "prior hard bounce",
|
|
416
368
|
};
|
|
417
369
|
receipts.record(receipt);
|
|
418
370
|
return {
|
|
@@ -469,8 +421,7 @@ export function createChannelRuntime(
|
|
|
469
421
|
|
|
470
422
|
let status: DeliveryStatus;
|
|
471
423
|
if (result.ok) {
|
|
472
|
-
status =
|
|
473
|
-
attempts.filter((a) => !a.ok).length > 0 ? "fallback" : "sent";
|
|
424
|
+
status = attempts.filter((a) => !a.ok).length > 0 ? "fallback" : "sent";
|
|
474
425
|
} else {
|
|
475
426
|
status = classifySendFailure(attempts);
|
|
476
427
|
}
|
|
@@ -490,7 +441,10 @@ export function createChannelRuntime(
|
|
|
490
441
|
...(result.ok
|
|
491
442
|
? {}
|
|
492
443
|
: {
|
|
493
|
-
error: attempts
|
|
444
|
+
error: attempts
|
|
445
|
+
.map((a) => a.error)
|
|
446
|
+
.filter(Boolean)
|
|
447
|
+
.join("; "),
|
|
494
448
|
}),
|
|
495
449
|
});
|
|
496
450
|
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { ChannelMedium } from "../../manifest/types.ts";
|
|
8
|
-
import {
|
|
9
|
-
createConsentStore,
|
|
10
|
-
type ConsentStore,
|
|
11
|
-
type OptOut,
|
|
12
|
-
} from "./consent.ts";
|
|
8
|
+
import { createConsentStore, type ConsentStore, type OptOut } from "./consent.ts";
|
|
13
9
|
|
|
14
10
|
/** Why an address is suppressed. */
|
|
15
11
|
export type SuppressionReason = "opted-out" | "prior-bounce";
|
|
@@ -35,9 +31,11 @@ export interface SuppressionStore {
|
|
|
35
31
|
isSuppressed(
|
|
36
32
|
subject: string,
|
|
37
33
|
medium: ChannelMedium,
|
|
38
|
-
):
|
|
39
|
-
readonly suppressed:
|
|
40
|
-
|
|
34
|
+
):
|
|
35
|
+
| { readonly suppressed: true; readonly reason: SuppressionReason }
|
|
36
|
+
| {
|
|
37
|
+
readonly suppressed: false;
|
|
38
|
+
};
|
|
41
39
|
/**
|
|
42
40
|
* Record an opt-out.
|
|
43
41
|
*
|
|
@@ -76,9 +74,7 @@ export function createSuppressionStore(
|
|
|
76
74
|
|
|
77
75
|
function bounceMatches(subject: string, medium: ChannelMedium): boolean {
|
|
78
76
|
return bounces.some(
|
|
79
|
-
(r) =>
|
|
80
|
-
r.subject === subject &&
|
|
81
|
-
(r.medium === "all" || r.medium === medium),
|
|
77
|
+
(r) => r.subject === subject && (r.medium === "all" || r.medium === medium),
|
|
82
78
|
);
|
|
83
79
|
}
|
|
84
80
|
|
|
@@ -97,9 +93,7 @@ export function createSuppressionStore(
|
|
|
97
93
|
consent.optOut(subject, medium);
|
|
98
94
|
},
|
|
99
95
|
addPriorBounce(subject, medium) {
|
|
100
|
-
if (
|
|
101
|
-
!bounces.some((r) => r.subject === subject && r.medium === medium)
|
|
102
|
-
) {
|
|
96
|
+
if (!bounces.some((r) => r.subject === subject && r.medium === medium)) {
|
|
103
97
|
bounces.push({ subject, medium, at: Date.now() });
|
|
104
98
|
}
|
|
105
99
|
},
|
|
@@ -9,17 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, expect, test } from "bun:test";
|
|
11
11
|
import type { MailOptions, SendResult, Transport } from "sently";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
openConsoleChannel,
|
|
15
|
-
type ChannelDriver,
|
|
16
|
-
} from "../drivers/index.ts";
|
|
17
|
-
import {
|
|
18
|
-
channel,
|
|
19
|
-
createChannelRuntime,
|
|
20
|
-
createConsentStore,
|
|
21
|
-
FallbackTransport,
|
|
22
|
-
} from "./channel.ts";
|
|
12
|
+
import { createChannelInbox, openConsoleChannel, type ChannelDriver } from "../drivers/index.ts";
|
|
13
|
+
import { channel, createChannelRuntime, createConsentStore, FallbackTransport } from "./channel.ts";
|
|
23
14
|
|
|
24
15
|
/** Create a sently-compatible transport that always fails. */
|
|
25
16
|
function failingTransport(provider: string): Transport {
|
|
@@ -56,10 +47,7 @@ function addressToString(input: MailOptions["to"]): string {
|
|
|
56
47
|
return input.address;
|
|
57
48
|
}
|
|
58
49
|
|
|
59
|
-
function driverFromTransport(
|
|
60
|
-
id: ChannelDriver["id"],
|
|
61
|
-
transport: Transport,
|
|
62
|
-
): ChannelDriver {
|
|
50
|
+
function driverFromTransport(id: ChannelDriver["id"], transport: Transport): ChannelDriver {
|
|
63
51
|
return { id, transport };
|
|
64
52
|
}
|
|
65
53
|
|
|
@@ -113,9 +101,7 @@ describe("fallback chain records both attempts", () => {
|
|
|
113
101
|
|
|
114
102
|
expect(result.ok).toBe(true);
|
|
115
103
|
expect(result.attempts.length).toBeGreaterThanOrEqual(2);
|
|
116
|
-
expect(result.attempts.some((a) => a.driverId === "smtp" && !a.ok)).toBe(
|
|
117
|
-
true,
|
|
118
|
-
);
|
|
104
|
+
expect(result.attempts.some((a) => a.driverId === "smtp" && !a.ok)).toBe(true);
|
|
119
105
|
expect(result.attempts.some((a) => a.ok)).toBe(true);
|
|
120
106
|
|
|
121
107
|
const receipts = runtime.receipts.forTemplate("booking-confirmed");
|
|
@@ -125,10 +111,7 @@ describe("fallback chain records both attempts", () => {
|
|
|
125
111
|
});
|
|
126
112
|
|
|
127
113
|
test("sently FallbackTransport is the same interface", async () => {
|
|
128
|
-
const fb = new FallbackTransport([
|
|
129
|
-
failingTransport("a"),
|
|
130
|
-
okTransport("b"),
|
|
131
|
-
]);
|
|
114
|
+
const fb = new FallbackTransport([failingTransport("a"), okTransport("b")]);
|
|
132
115
|
const r = await fb.send({
|
|
133
116
|
from: "a@b.c",
|
|
134
117
|
to: "d@e.f",
|
|
@@ -168,9 +151,7 @@ describe("consent and i18n", () => {
|
|
|
168
151
|
});
|
|
169
152
|
const blocked = await runtime.send("news", { to: "bounce@example.com" });
|
|
170
153
|
expect(blocked.ok).toBe(false);
|
|
171
|
-
expect(runtime.receipts.all().at(-1)!.status).toBe(
|
|
172
|
-
"suppressed/prior-bounce",
|
|
173
|
-
);
|
|
154
|
+
expect(runtime.receipts.all().at(-1)!.status).toBe("suppressed/prior-bounce");
|
|
174
155
|
});
|
|
175
156
|
|
|
176
157
|
test("locale chain is recorded on the receipt", async () => {
|
|
@@ -192,9 +173,7 @@ describe("consent and i18n", () => {
|
|
|
192
173
|
test("locale selects catalog body", async () => {
|
|
193
174
|
const inbox = createChannelInbox();
|
|
194
175
|
const runtime = createChannelRuntime({
|
|
195
|
-
templates: [
|
|
196
|
-
channel.template("hello", { medium: "email", locales: ["en", "ar"] }),
|
|
197
|
-
],
|
|
176
|
+
templates: [channel.template("hello", { medium: "email", locales: ["en", "ar"] })],
|
|
198
177
|
drivers: [openConsoleChannel({ inbox })],
|
|
199
178
|
catalog: {
|
|
200
179
|
hello: {
|
|
@@ -213,9 +192,7 @@ describe("console driver", () => {
|
|
|
213
192
|
test("dev inbox captures every medium", async () => {
|
|
214
193
|
const inbox = createChannelInbox();
|
|
215
194
|
const runtime = createChannelRuntime({
|
|
216
|
-
templates: [
|
|
217
|
-
channel.template("sms-otp", { medium: "sms" }),
|
|
218
|
-
],
|
|
195
|
+
templates: [channel.template("sms-otp", { medium: "sms" })],
|
|
219
196
|
drivers: [openConsoleChannel({ inbox })],
|
|
220
197
|
catalog: {
|
|
221
198
|
"sms-otp": { en: { text: "code {{code}}" } },
|
package/src/elements/channel.ts
CHANGED
|
@@ -19,9 +19,7 @@ export type {
|
|
|
19
19
|
ChannelTemplateOptions,
|
|
20
20
|
} from "./channel/declare.ts";
|
|
21
21
|
|
|
22
|
-
export {
|
|
23
|
-
createChannelRuntime,
|
|
24
|
-
} from "./channel/runtime.ts";
|
|
22
|
+
export { createChannelRuntime } from "./channel/runtime.ts";
|
|
25
23
|
export type {
|
|
26
24
|
ChannelRuntime,
|
|
27
25
|
ChannelSendOptions,
|
|
@@ -29,11 +27,7 @@ export type {
|
|
|
29
27
|
TemplateCatalog,
|
|
30
28
|
} from "./channel/runtime.ts";
|
|
31
29
|
|
|
32
|
-
export {
|
|
33
|
-
createConsentStore,
|
|
34
|
-
type ConsentStore,
|
|
35
|
-
type OptOut,
|
|
36
|
-
} from "./channel/consent.ts";
|
|
30
|
+
export { createConsentStore, type ConsentStore, type OptOut } from "./channel/consent.ts";
|
|
37
31
|
|
|
38
32
|
export {
|
|
39
33
|
createSuppressionStore,
|
|
@@ -81,12 +75,7 @@ export {
|
|
|
81
75
|
type MediumCosts,
|
|
82
76
|
} from "./channel/costs.ts";
|
|
83
77
|
|
|
84
|
-
export {
|
|
85
|
-
CHANNEL_PII_MASK,
|
|
86
|
-
maskEmail,
|
|
87
|
-
maskPhone,
|
|
88
|
-
maskRecipient,
|
|
89
|
-
} from "./channel/mask.ts";
|
|
78
|
+
export { CHANNEL_PII_MASK, maskEmail, maskPhone, maskRecipient } from "./channel/mask.ts";
|
|
90
79
|
|
|
91
80
|
export {
|
|
92
81
|
domainFromFrom,
|
|
@@ -50,10 +50,7 @@ export class ClockResourceNotFoundError extends Error {
|
|
|
50
50
|
* @param store - Cron store
|
|
51
51
|
* @param name - Cron name
|
|
52
52
|
*/
|
|
53
|
-
export async function pauseCron(
|
|
54
|
-
store: CronStore,
|
|
55
|
-
name: string,
|
|
56
|
-
): Promise<CronRow> {
|
|
53
|
+
export async function pauseCron(store: CronStore, name: string): Promise<CronRow> {
|
|
57
54
|
const row = await store.get(name);
|
|
58
55
|
if (!row) throw new ClockResourceNotFoundError("cron", name);
|
|
59
56
|
const next: CronRow = { ...row, status: "paused" };
|
|
@@ -74,19 +71,14 @@ export interface EditScheduleInput {
|
|
|
74
71
|
* @param store - Cron store
|
|
75
72
|
* @param input - Name + override cron and/or every
|
|
76
73
|
*/
|
|
77
|
-
export async function editSchedule(
|
|
78
|
-
store: CronStore,
|
|
79
|
-
input: EditScheduleInput,
|
|
80
|
-
): Promise<CronRow> {
|
|
74
|
+
export async function editSchedule(store: CronStore, input: EditScheduleInput): Promise<CronRow> {
|
|
81
75
|
const row = await store.get(input.name);
|
|
82
76
|
if (!row) throw new ClockResourceNotFoundError("cron", input.name);
|
|
83
77
|
if (!row.overridable) {
|
|
84
78
|
throw new ScheduleNotOverridableError(input.name);
|
|
85
79
|
}
|
|
86
|
-
const overrideCron =
|
|
87
|
-
|
|
88
|
-
const overrideEvery =
|
|
89
|
-
input.every !== undefined ? input.every : row.overrideEvery;
|
|
80
|
+
const overrideCron = input.cron !== undefined ? input.cron : row.overrideCron;
|
|
81
|
+
const overrideEvery = input.every !== undefined ? input.every : row.overrideEvery;
|
|
90
82
|
const next: CronRow = {
|
|
91
83
|
...row,
|
|
92
84
|
overrideCron,
|
|
@@ -125,9 +117,7 @@ export interface WakeEarlyResult {
|
|
|
125
117
|
*
|
|
126
118
|
* @param options - Journal, run id, optional flow resolver
|
|
127
119
|
*/
|
|
128
|
-
export async function wakeEarly(
|
|
129
|
-
options: WakeEarlyOptions,
|
|
130
|
-
): Promise<WakeEarlyResult> {
|
|
120
|
+
export async function wakeEarly(options: WakeEarlyOptions): Promise<WakeEarlyResult> {
|
|
131
121
|
const now = options.now ?? (() => Date.now());
|
|
132
122
|
const t = now();
|
|
133
123
|
const run = await options.journal.get(options.runId);
|
|
@@ -136,9 +126,7 @@ export async function wakeEarly(
|
|
|
136
126
|
}
|
|
137
127
|
|
|
138
128
|
const entries = run.entries.map((e) =>
|
|
139
|
-
e.kind === "sleep" && e.wakeAt === run.wakeAt
|
|
140
|
-
? { ...e, wakeAt: t }
|
|
141
|
-
: e,
|
|
129
|
+
e.kind === "sleep" && e.wakeAt === run.wakeAt ? { ...e, wakeAt: t } : e,
|
|
142
130
|
);
|
|
143
131
|
await options.journal.put({
|
|
144
132
|
...run,
|
|
@@ -44,9 +44,7 @@ export interface ClockDecl {
|
|
|
44
44
|
*/
|
|
45
45
|
export function clock(name: string, options: ClockOptions = {}): ClockDecl {
|
|
46
46
|
if (!options.cron && !options.every) {
|
|
47
|
-
throw new TypeError(
|
|
48
|
-
`clock("${name}"): require cron or every`,
|
|
49
|
-
);
|
|
47
|
+
throw new TypeError(`clock("${name}"): require cron or every`);
|
|
50
48
|
}
|
|
51
49
|
return {
|
|
52
50
|
name,
|
|
@@ -134,11 +134,7 @@ function classifyLocalInstant(
|
|
|
134
134
|
for (let offsetMin = -14 * 60; offsetMin <= 14 * 60; offsetMin += 15) {
|
|
135
135
|
const utc = base + hour * 3_600_000 + minute * 60_000 - offsetMin * 60_000;
|
|
136
136
|
const local = formatInZone(utc, timezone);
|
|
137
|
-
if (
|
|
138
|
-
local.date === dateStr &&
|
|
139
|
-
local.hour === hour &&
|
|
140
|
-
local.minute === minute
|
|
141
|
-
) {
|
|
137
|
+
if (local.date === dateStr && local.hour === hour && local.minute === minute) {
|
|
142
138
|
if (!matches.includes(utc)) matches.push(utc);
|
|
143
139
|
}
|
|
144
140
|
}
|
|
@@ -7,11 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { AnyFlowDef } from "../../kernel/flow.ts";
|
|
10
|
-
import {
|
|
11
|
-
createFxContext,
|
|
12
|
-
type CreateFxOptions,
|
|
13
|
-
type Fx,
|
|
14
|
-
} from "../../kernel/fx.ts";
|
|
10
|
+
import { createFxContext, type CreateFxOptions, type Fx } from "../../kernel/fx.ts";
|
|
15
11
|
import {
|
|
16
12
|
createJournal,
|
|
17
13
|
isJournalSuspend,
|
|
@@ -51,10 +47,7 @@ export interface RunDurableOptions {
|
|
|
51
47
|
/** Injectable clock. */
|
|
52
48
|
readonly now?: () => number;
|
|
53
49
|
/** Extra fx options (secrets, store runtime, …). */
|
|
54
|
-
readonly fx?: Omit<
|
|
55
|
-
CreateFxOptions,
|
|
56
|
-
"flow" | "effects" | "capability" | "now" | "journal"
|
|
57
|
-
>;
|
|
50
|
+
readonly fx?: Omit<CreateFxOptions, "flow" | "effects" | "capability" | "now" | "journal">;
|
|
58
51
|
}
|
|
59
52
|
|
|
60
53
|
/**
|
|
@@ -73,13 +66,8 @@ export async function runDurable<O = unknown>(
|
|
|
73
66
|
|
|
74
67
|
if (options.runId) {
|
|
75
68
|
const existing = await options.journalStore.get(options.runId);
|
|
76
|
-
if (
|
|
77
|
-
existing
|
|
78
|
-
now() < existing.wakeAt
|
|
79
|
-
) {
|
|
80
|
-
const sleepEntry = [...existing.entries]
|
|
81
|
-
.reverse()
|
|
82
|
-
.find((e) => e.kind === "sleep");
|
|
69
|
+
if (existing?.wakeAt !== undefined && now() < existing.wakeAt) {
|
|
70
|
+
const sleepEntry = [...existing.entries].reverse().find((e) => e.kind === "sleep");
|
|
83
71
|
return {
|
|
84
72
|
status: "sleeping",
|
|
85
73
|
runId: existing.id,
|
|
@@ -7,10 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { parseDurationMs } from "./duration.ts";
|
|
9
9
|
import { effectiveSchedule, type CronRow } from "./reconcile.ts";
|
|
10
|
-
import {
|
|
11
|
-
countMissedOccurrences,
|
|
12
|
-
previousOccurrence,
|
|
13
|
-
} from "./schedule.ts";
|
|
10
|
+
import { countMissedOccurrences, previousOccurrence } from "./schedule.ts";
|
|
14
11
|
|
|
15
12
|
/** Catch-up policy matching ClockRuntime physics. */
|
|
16
13
|
export type CatchUpPolicy = "one";
|
|
@@ -39,9 +36,7 @@ export interface CronHealth {
|
|
|
39
36
|
*/
|
|
40
37
|
export function cronHealth(row: CronRow, now: number): CronHealth {
|
|
41
38
|
const overdue = isOverdue(row, now);
|
|
42
|
-
const missedRuns = overdue
|
|
43
|
-
? countMissedFromRow(row, now)
|
|
44
|
-
: 0;
|
|
39
|
+
const missedRuns = overdue ? countMissedFromRow(row, now) : 0;
|
|
45
40
|
const driftMs = computeDrift(row, now);
|
|
46
41
|
|
|
47
42
|
return {
|
|
@@ -33,12 +33,7 @@ export interface LeaseStore {
|
|
|
33
33
|
* @param now - Current epoch-ms
|
|
34
34
|
* @param leaseMs - Lease TTL
|
|
35
35
|
*/
|
|
36
|
-
acquireLease?(
|
|
37
|
-
name: string,
|
|
38
|
-
instanceId: string,
|
|
39
|
-
now: number,
|
|
40
|
-
leaseMs: number,
|
|
41
|
-
): Promise<boolean>;
|
|
36
|
+
acquireLease?(name: string, instanceId: string, now: number, leaseMs: number): Promise<boolean>;
|
|
42
37
|
}
|
|
43
38
|
|
|
44
39
|
/** Options for {@link tryAcquireLease}. */
|
|
@@ -63,9 +58,7 @@ export interface AcquireLeaseOptions {
|
|
|
63
58
|
*
|
|
64
59
|
* @param options - Name, instance, clock, store
|
|
65
60
|
*/
|
|
66
|
-
export async function tryAcquireLease(
|
|
67
|
-
options: AcquireLeaseOptions,
|
|
68
|
-
): Promise<boolean> {
|
|
61
|
+
export async function tryAcquireLease(options: AcquireLeaseOptions): Promise<boolean> {
|
|
69
62
|
if (options.store.acquireLease) {
|
|
70
63
|
return options.store.acquireLease(
|
|
71
64
|
options.name,
|
|
@@ -68,12 +68,7 @@ export interface CronStore {
|
|
|
68
68
|
* @param now - Current epoch-ms
|
|
69
69
|
* @param leaseMs - Lease TTL
|
|
70
70
|
*/
|
|
71
|
-
acquireLease(
|
|
72
|
-
name: string,
|
|
73
|
-
instanceId: string,
|
|
74
|
-
now: number,
|
|
75
|
-
leaseMs: number,
|
|
76
|
-
): Promise<boolean>;
|
|
71
|
+
acquireLease(name: string, instanceId: string, now: number, leaseMs: number): Promise<boolean>;
|
|
77
72
|
}
|
|
78
73
|
|
|
79
74
|
/** Result of one reconciliation pass. */
|
|
@@ -107,13 +102,9 @@ export async function reconcileClocks(
|
|
|
107
102
|
for (const decl of declared) {
|
|
108
103
|
const prev = await store.get(decl.name);
|
|
109
104
|
const overrideCron =
|
|
110
|
-
decl.overridable && prev?.overrideCron !== undefined
|
|
111
|
-
? prev.overrideCron
|
|
112
|
-
: undefined;
|
|
105
|
+
decl.overridable && prev?.overrideCron !== undefined ? prev.overrideCron : undefined;
|
|
113
106
|
const overrideEvery =
|
|
114
|
-
decl.overridable && prev?.overrideEvery !== undefined
|
|
115
|
-
? prev.overrideEvery
|
|
116
|
-
: undefined;
|
|
107
|
+
decl.overridable && prev?.overrideEvery !== undefined ? prev.overrideEvery : undefined;
|
|
117
108
|
|
|
118
109
|
const row: CronRow = {
|
|
119
110
|
name: decl.name,
|
|
@@ -179,9 +170,7 @@ export function effectiveSchedule(row: CronRow): {
|
|
|
179
170
|
*
|
|
180
171
|
* @param seed - Optional initial rows
|
|
181
172
|
*/
|
|
182
|
-
export function createMemoryCronStore(
|
|
183
|
-
seed?: readonly CronRow[],
|
|
184
|
-
): CronStore {
|
|
173
|
+
export function createMemoryCronStore(seed?: readonly CronRow[]): CronStore {
|
|
185
174
|
const rows = new Map<string, CronRow>();
|
|
186
175
|
for (const r of seed ?? []) {
|
|
187
176
|
rows.set(r.name, structuredClone(r));
|
|
@@ -99,12 +99,9 @@ export interface ClockRuntime {
|
|
|
99
99
|
*
|
|
100
100
|
* @param options - Instance id, store, clock
|
|
101
101
|
*/
|
|
102
|
-
export function createClockRuntime(
|
|
103
|
-
options: CreateClockRuntimeOptions = {},
|
|
104
|
-
): ClockRuntime {
|
|
102
|
+
export function createClockRuntime(options: CreateClockRuntimeOptions = {}): ClockRuntime {
|
|
105
103
|
const timeTravel = options.timeTravel;
|
|
106
|
-
const now = (): number =>
|
|
107
|
-
timeTravel ? timeTravel.now() : (options.now ?? (() => Date.now()))();
|
|
104
|
+
const now = (): number => (timeTravel ? timeTravel.now() : (options.now ?? (() => Date.now()))());
|
|
108
105
|
const store = options.store ?? createMemoryCronStore();
|
|
109
106
|
const instanceId = options.instanceId ?? crypto.randomUUID();
|
|
110
107
|
const leaseMs = options.leaseMs ?? 30_000;
|