@revisium/orchestrator 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +20 -0
- package/bin/revo.js +2 -0
- package/control-plane/bootstrap.config.json +931 -0
- package/dist/app.module.js +28 -0
- package/dist/app.module.js.map +1 -0
- package/dist/cli/commands/bootstrap.js +39 -0
- package/dist/cli/commands/bootstrap.js.map +1 -0
- package/dist/cli/commands/dev.js +143 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/inbox.js +288 -0
- package/dist/cli/commands/inbox.js.map +1 -0
- package/dist/cli/commands/mcp.js +16 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/playbook.js +74 -0
- package/dist/cli/commands/playbook.js.map +1 -0
- package/dist/cli/commands/poll-workflow-state.js +144 -0
- package/dist/cli/commands/poll-workflow-state.js.map +1 -0
- package/dist/cli/commands/revisium-context.js +23 -0
- package/dist/cli/commands/revisium-context.js.map +1 -0
- package/dist/cli/commands/revisium-helpers.js +61 -0
- package/dist/cli/commands/revisium-helpers.js.map +1 -0
- package/dist/cli/commands/revisium.js +89 -0
- package/dist/cli/commands/revisium.js.map +1 -0
- package/dist/cli/commands/run.js +426 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/work.js +149 -0
- package/dist/cli/commands/work.js.map +1 -0
- package/dist/cli/config.js +2 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.js +32 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/live-guard.js +49 -0
- package/dist/cli/live-guard.js.map +1 -0
- package/dist/cli/needs-host.js +78 -0
- package/dist/cli/needs-host.js.map +1 -0
- package/dist/cli/program.js +37 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/config.js +102 -0
- package/dist/config.js.map +1 -0
- package/dist/control-plane/client-transport.js +146 -0
- package/dist/control-plane/client-transport.js.map +1 -0
- package/dist/control-plane/data-access.js +99 -0
- package/dist/control-plane/data-access.js.map +1 -0
- package/dist/control-plane/definitions.js +120 -0
- package/dist/control-plane/definitions.js.map +1 -0
- package/dist/control-plane/errors.js +13 -0
- package/dist/control-plane/errors.js.map +1 -0
- package/dist/control-plane/inbox.js +261 -0
- package/dist/control-plane/inbox.js.map +1 -0
- package/dist/control-plane/index.js +6 -0
- package/dist/control-plane/index.js.map +1 -0
- package/dist/control-plane/json-fields.js +68 -0
- package/dist/control-plane/json-fields.js.map +1 -0
- package/dist/control-plane/resolve-cwd.js +75 -0
- package/dist/control-plane/resolve-cwd.js.map +1 -0
- package/dist/control-plane/steps.js +381 -0
- package/dist/control-plane/steps.js.map +1 -0
- package/dist/control-plane/tables.js +13 -0
- package/dist/control-plane/tables.js.map +1 -0
- package/dist/control-plane/versioned-meaning.js +53 -0
- package/dist/control-plane/versioned-meaning.js.map +1 -0
- package/dist/engine/dbos.module.js +18 -0
- package/dist/engine/dbos.module.js.map +1 -0
- package/dist/engine/dbos.service.js +296 -0
- package/dist/engine/dbos.service.js.map +1 -0
- package/dist/engine/ensure-postgres.js +80 -0
- package/dist/engine/ensure-postgres.js.map +1 -0
- package/dist/engine/types.js +2 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/host/ensure-revisium.js +269 -0
- package/dist/host/ensure-revisium.js.map +1 -0
- package/dist/host/host.lifecycle.js +75 -0
- package/dist/host/host.lifecycle.js.map +1 -0
- package/dist/mcp/mcp-capabilities.js +47 -0
- package/dist/mcp/mcp-capabilities.js.map +1 -0
- package/dist/mcp/mcp-facade.service.js +130 -0
- package/dist/mcp/mcp-facade.service.js.map +1 -0
- package/dist/mcp/mcp-stdio.service.js +48 -0
- package/dist/mcp/mcp-stdio.service.js.map +1 -0
- package/dist/mcp/mcp-tools.js +264 -0
- package/dist/mcp/mcp-tools.js.map +1 -0
- package/dist/mcp/mcp.module.js +21 -0
- package/dist/mcp/mcp.module.js.map +1 -0
- package/dist/package-info.js +10 -0
- package/dist/package-info.js.map +1 -0
- package/dist/pipeline/await-human.js +62 -0
- package/dist/pipeline/await-human.js.map +1 -0
- package/dist/pipeline/develop-task.workflow.js +497 -0
- package/dist/pipeline/develop-task.workflow.js.map +1 -0
- package/dist/pipeline/pipeline.module.js +34 -0
- package/dist/pipeline/pipeline.module.js.map +1 -0
- package/dist/playbook/catalog-loader.js +145 -0
- package/dist/playbook/catalog-loader.js.map +1 -0
- package/dist/playbook/errors.js +14 -0
- package/dist/playbook/errors.js.map +1 -0
- package/dist/playbook/import-mapper.js +186 -0
- package/dist/playbook/import-mapper.js.map +1 -0
- package/dist/playbook/manifest.js +60 -0
- package/dist/playbook/manifest.js.map +1 -0
- package/dist/playbook/playbook-installer.js +51 -0
- package/dist/playbook/playbook-installer.js.map +1 -0
- package/dist/playbook/prompt-composer.js +34 -0
- package/dist/playbook/prompt-composer.js.map +1 -0
- package/dist/playbook/source-resolver.js +105 -0
- package/dist/playbook/source-resolver.js.map +1 -0
- package/dist/poller/pr-readiness-core.js +656 -0
- package/dist/poller/pr-readiness-core.js.map +1 -0
- package/dist/poller/pr-readiness.js +91 -0
- package/dist/poller/pr-readiness.js.map +1 -0
- package/dist/revisium/inbox.service.js +67 -0
- package/dist/revisium/inbox.service.js.map +1 -0
- package/dist/revisium/playbooks.service.js +99 -0
- package/dist/revisium/playbooks.service.js.map +1 -0
- package/dist/revisium/revisium.module.js +55 -0
- package/dist/revisium/revisium.module.js.map +1 -0
- package/dist/revisium/roles.service.js +79 -0
- package/dist/revisium/roles.service.js.map +1 -0
- package/dist/revisium/run.service.js +182 -0
- package/dist/revisium/run.service.js.map +1 -0
- package/dist/revisium/tokens.js +7 -0
- package/dist/revisium/tokens.js.map +1 -0
- package/dist/run/append-event.js +112 -0
- package/dist/run/append-event.js.map +1 -0
- package/dist/run/cancel-run.js +47 -0
- package/dist/run/cancel-run.js.map +1 -0
- package/dist/run/create-run.js +208 -0
- package/dist/run/create-run.js.map +1 -0
- package/dist/run/fail-run.js +20 -0
- package/dist/run/fail-run.js.map +1 -0
- package/dist/run/inspect-run.js +287 -0
- package/dist/run/inspect-run.js.map +1 -0
- package/dist/run/terminal-run-status.js +45 -0
- package/dist/run/terminal-run-status.js.map +1 -0
- package/dist/runners/claude-code.service.js +48 -0
- package/dist/runners/claude-code.service.js.map +1 -0
- package/dist/runners/gh-identity.js +108 -0
- package/dist/runners/gh-identity.js.map +1 -0
- package/dist/runners/integrator.js +417 -0
- package/dist/runners/integrator.js.map +1 -0
- package/dist/runners/runner.module.js +40 -0
- package/dist/runners/runner.module.js.map +1 -0
- package/dist/runners/tokens.js +7 -0
- package/dist/runners/tokens.js.map +1 -0
- package/dist/task-control-plane/pr-readiness.service.js +33 -0
- package/dist/task-control-plane/pr-readiness.service.js.map +1 -0
- package/dist/task-control-plane/task-control-plane-api.service.js +440 -0
- package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -0
- package/dist/task-control-plane/task-control-plane.module.js +23 -0
- package/dist/task-control-plane/task-control-plane.module.js.map +1 -0
- package/dist/worker/build-context.js +39 -0
- package/dist/worker/build-context.js.map +1 -0
- package/dist/worker/claude-code-runner.js +135 -0
- package/dist/worker/claude-code-runner.js.map +1 -0
- package/dist/worker/git-worktree-manager.js +84 -0
- package/dist/worker/git-worktree-manager.js.map +1 -0
- package/dist/worker/loop.js +122 -0
- package/dist/worker/loop.js.map +1 -0
- package/dist/worker/process-executor.js +62 -0
- package/dist/worker/process-executor.js.map +1 -0
- package/dist/worker/result-envelope.js +134 -0
- package/dist/worker/result-envelope.js.map +1 -0
- package/dist/worker/runner-dispatch.js +20 -0
- package/dist/worker/runner-dispatch.js.map +1 -0
- package/dist/worker/runner.js +2 -0
- package/dist/worker/runner.js.map +1 -0
- package/dist/worker/script-runner.js +28 -0
- package/dist/worker/script-runner.js.map +1 -0
- package/dist/worker/stub-runner.js +59 -0
- package/dist/worker/stub-runner.js.map +1 -0
- package/dist/worker/worker-id.js +18 -0
- package/dist/worker/worker-id.js.map +1 -0
- package/dist/worker/worktree-manager.js +7 -0
- package/dist/worker/worktree-manager.js.map +1 -0
- package/package.json +66 -0
- package/revisium.config.json +10 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DbosService — the engine layer owns all @dbos-inc/dbos-sdk imports.
|
|
3
|
+
*
|
|
4
|
+
* This file (`dbos.service.ts`) is the primary importer; `engine/types.ts` re-exports
|
|
5
|
+
* type-only symbols (`WorkflowHandle`) so pipeline callers can annotate return types
|
|
6
|
+
* without importing from @dbos-inc directly. `src/pipeline/*` must import ZERO @dbos-inc.
|
|
7
|
+
*
|
|
8
|
+
* Owns DBOS lifecycle (setConfig / launch / shutdown) and thin verbs
|
|
9
|
+
* (startPingWorkflow / getWorkflowStatus / waitForWorkflow).
|
|
10
|
+
*
|
|
11
|
+
* Seam pattern: `dev:ping` is a two-step workflow registered as instance methods
|
|
12
|
+
* via DBOS.registerWorkflow / DBOS.registerStep (programmatic, decorator-free).
|
|
13
|
+
* Registration happens in the constructor, BEFORE DBOS.launch() — required by DBOS
|
|
14
|
+
* (workflows not registered before launch() are not eligible for recovery).
|
|
15
|
+
*
|
|
16
|
+
* ── Confirmed SDK symbols (Task 0, @dbos-inc/dbos-sdk@4.19.8) ──────────────
|
|
17
|
+
* DBOSConfig.systemDatabaseUrl ✓ (ТЗ expected systemDatabaseUrl — CONFIRMED)
|
|
18
|
+
* DBOS.setConfig(config) ✓
|
|
19
|
+
* DBOS.launch() ✓
|
|
20
|
+
* DBOS.shutdown() ✓
|
|
21
|
+
* DBOS.registerWorkflow(fn, cfg) ✓ returns wrapped fn with same signature
|
|
22
|
+
* DBOS.registerStep(fn, cfg) ✓ returns wrapped fn with same signature
|
|
23
|
+
* DBOS.startWorkflow(fn, params) ✓ params.workflowID ✓; returns fn(args)=>handle
|
|
24
|
+
* DBOS.getWorkflowStatus(id) ✓ returns WorkflowStatus | null
|
|
25
|
+
* DBOS.retrieveWorkflow(id) ✓ returns WorkflowHandle<T>; handle.getResult() ✓
|
|
26
|
+
* DBOS.sleep(ms) ✓
|
|
27
|
+
* ConfiguredInstance ✓ (fallback path — not used; registerWorkflow used instead)
|
|
28
|
+
*
|
|
29
|
+
* ── Recovery seam ───────────────────────────────────────────────────────────
|
|
30
|
+
* On restart, DBOS.launch() auto-recovers in-flight workflows by name+className.
|
|
31
|
+
* registerWorkflow(boundFn, { name, className }) supplies stable names so DBOS
|
|
32
|
+
* can bind back to the freshly-DI-constructed DbosService singleton.
|
|
33
|
+
* If M3 (kill-mid-step test) shows recovery fails to re-bind, switch to
|
|
34
|
+
* ConfiguredInstance (documented fallback; both paths concrete — OQ-1b).
|
|
35
|
+
*/
|
|
36
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
37
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
38
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
39
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
40
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
41
|
+
};
|
|
42
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
43
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
44
|
+
};
|
|
45
|
+
import { Injectable } from '@nestjs/common';
|
|
46
|
+
import { DBOS, WorkflowQueue } from '@dbos-inc/dbos-sdk';
|
|
47
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
48
|
+
import { dirname } from 'node:path';
|
|
49
|
+
/**
|
|
50
|
+
* Far-future absolute deadline (year 2100 epoch ms). Fixed constant ⇒ deterministic on replay (G5).
|
|
51
|
+
* DBOS recv with no timeout/deadline defaults to 60 s; we pass this so human gates wait indefinitely.
|
|
52
|
+
* Never use Date.now()+X — that differs per replay and breaks DBOS replay-safety.
|
|
53
|
+
*/
|
|
54
|
+
export const GATE_DEADLINE_EPOCH_MS = 4102444800000; // 2100-01-01T00:00:00Z
|
|
55
|
+
/**
|
|
56
|
+
* Bound on how long DBOS.shutdown() may block before the host detaches anyway (0008 #3).
|
|
57
|
+
* DBOS.shutdown() drains "pending workflows" — but a workflow PARKED at a human gate
|
|
58
|
+
* (DBOS.recv) never drains, so app.close() hangs forever after `run start --wait` detaches.
|
|
59
|
+
* The durable state lives in Postgres and is recovered on the next launch(), so abandoning
|
|
60
|
+
* the in-memory drain after this bound loses no durability — it only lets the CLI exit 0.
|
|
61
|
+
*/
|
|
62
|
+
export const SHUTDOWN_DRAIN_TIMEOUT_MS = 8_000;
|
|
63
|
+
let DbosService = class DbosService {
|
|
64
|
+
launched = false;
|
|
65
|
+
/** Registered WorkflowQueues — guarded map to ensure idempotent registration. */
|
|
66
|
+
queues = new Map();
|
|
67
|
+
// Registered DBOS functions — assigned in constructor before launch().
|
|
68
|
+
pingWorkflow;
|
|
69
|
+
markStep;
|
|
70
|
+
sleepStep;
|
|
71
|
+
constructor() {
|
|
72
|
+
// Register steps first (workflows may call them; all must be registered before launch).
|
|
73
|
+
this.markStep = DBOS.registerStep(async function markStepImpl(workflowID, markerFile) {
|
|
74
|
+
// Idempotent marker (F12): write exactly-once per workflowID by using 'wx' (exclusive
|
|
75
|
+
// create). If the file already exists (step re-executed after a crash-before-checkpoint),
|
|
76
|
+
// writeFileSync throws with EEXIST — we catch that and skip the write, ensuring the
|
|
77
|
+
// marker count is always 1 for a given workflow id regardless of how many times the
|
|
78
|
+
// step body runs.
|
|
79
|
+
mkdirSync(dirname(markerFile), { recursive: true });
|
|
80
|
+
try {
|
|
81
|
+
writeFileSync(markerFile, `${workflowID}\t${new Date().toISOString()}\n`, { flag: 'wx' });
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (err.code !== 'EEXIST')
|
|
85
|
+
throw err;
|
|
86
|
+
// EEXIST: marker already written by a prior execution — skip (idempotent).
|
|
87
|
+
}
|
|
88
|
+
const content = existsSync(markerFile) ? readFileSync(markerFile, 'utf8') : '';
|
|
89
|
+
return content.split('\n').filter((l) => l.trim() !== '').length;
|
|
90
|
+
}, { name: 'markStep', className: 'DbosService' });
|
|
91
|
+
this.sleepStep = DBOS.registerStep(async function sleepStepImpl(ms) {
|
|
92
|
+
await DBOS.sleep(ms);
|
|
93
|
+
}, { name: 'sleepStep', className: 'DbosService' });
|
|
94
|
+
// Register the workflow (uses bound steps).
|
|
95
|
+
// Capture step references via .bind(this) so DBOS sees stable registered functions,
|
|
96
|
+
// not closures that close over `this` directly (avoids S7740 "do not assign this to self").
|
|
97
|
+
const markStepBound = this.markStep.bind(this);
|
|
98
|
+
const sleepStepBound = this.sleepStep.bind(this);
|
|
99
|
+
this.pingWorkflow = DBOS.registerWorkflow(async function pingImpl(workflowID, sleepMs, markerFile) {
|
|
100
|
+
const markerCount = await markStepBound(workflowID, markerFile);
|
|
101
|
+
await sleepStepBound(sleepMs);
|
|
102
|
+
return { workflowID, markerCount };
|
|
103
|
+
}, { name: 'pingImpl', className: 'DbosService' });
|
|
104
|
+
}
|
|
105
|
+
// ── Generic engine verbs (M1 — DBOS seal, TASK 0003) ───────────────────────
|
|
106
|
+
//
|
|
107
|
+
// `src/pipeline/*` imports NO `@dbos-inc/dbos-sdk`. These verbs expose the minimal
|
|
108
|
+
// surface needed for the pipeline module: register a step/workflow (returns the
|
|
109
|
+
// DBOS-wrapped fn with the same signature), register a queue (idempotent), and enqueue
|
|
110
|
+
// a workflow by ID + queue name.
|
|
111
|
+
//
|
|
112
|
+
// `name` format: 'ClassName.methodName' — split on the LAST dot to fill DBOS's
|
|
113
|
+
// { name, className } (matching how dev:ping uses { name:'pingImpl', className:'DbosService' }).
|
|
114
|
+
// Stable across releases — the recovery seam binds on name+className.
|
|
115
|
+
/**
|
|
116
|
+
* Register a plain async function as a DBOS step.
|
|
117
|
+
* Returns the DBOS-wrapped function with the same call signature.
|
|
118
|
+
* Call in the consumer's constructor, BEFORE DBOS.launch().
|
|
119
|
+
*/
|
|
120
|
+
registerStep(name, fn) {
|
|
121
|
+
const lastDot = name.lastIndexOf('.');
|
|
122
|
+
const className = lastDot >= 0 ? name.slice(0, lastDot) : 'Pipeline';
|
|
123
|
+
const methodName = lastDot >= 0 ? name.slice(lastDot + 1) : name;
|
|
124
|
+
return DBOS.registerStep(fn, { name: methodName, className });
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Register a plain async function as a DBOS workflow.
|
|
128
|
+
* Returns the DBOS-wrapped function with the same call signature.
|
|
129
|
+
* Call in the consumer's constructor, BEFORE DBOS.launch().
|
|
130
|
+
*/
|
|
131
|
+
registerWorkflow(name, fn) {
|
|
132
|
+
const lastDot = name.lastIndexOf('.');
|
|
133
|
+
const className = lastDot >= 0 ? name.slice(0, lastDot) : 'Pipeline';
|
|
134
|
+
const methodName = lastDot >= 0 ? name.slice(lastDot + 1) : name;
|
|
135
|
+
return DBOS.registerWorkflow(fn, { name: methodName, className });
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Construct and register a WorkflowQueue (idempotent — Map-guarded).
|
|
139
|
+
* The ONLY place `new WorkflowQueue(...)` is called, keeping @dbos-inc inside this file.
|
|
140
|
+
* Call before DBOS.launch().
|
|
141
|
+
*/
|
|
142
|
+
registerQueue(name, opts) {
|
|
143
|
+
if (!this.queues.has(name)) {
|
|
144
|
+
this.queues.set(name, new WorkflowQueue(name, opts));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Enqueue a registered workflow with a stable workflowID and queue name.
|
|
149
|
+
* Idempotent by workflowID: if a workflow with the same id already exists, DBOS returns
|
|
150
|
+
* a handle to the existing workflow and does NOT start a second run.
|
|
151
|
+
*
|
|
152
|
+
* Generic over the workflow's arg tuple A so it accepts any registered fn signature.
|
|
153
|
+
*
|
|
154
|
+
* @param fn - The DBOS-wrapped workflow function (returned by registerWorkflow).
|
|
155
|
+
* @param workflowID - Stable dedup key (e.g. the runId).
|
|
156
|
+
* @param queueName - Name of the queue to enqueue on.
|
|
157
|
+
* @param args - Arguments forwarded to the workflow (persisted as durable input).
|
|
158
|
+
*/
|
|
159
|
+
startWorkflowOn(fn, workflowID, queueName, ...args) {
|
|
160
|
+
return DBOS.startWorkflow(fn, { workflowID, queueName })(...args);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Signal a parked workflow's awaitDecision. Wraps DBOS.send; exactly-once via idempotencyKey.
|
|
164
|
+
*
|
|
165
|
+
* CANONICAL wrapper arg order: signal(workflowId, topic, payload, idempotencyKey).
|
|
166
|
+
* The wrapper REORDERS to DBOS's raw order INSIDE:
|
|
167
|
+
* wrapper (workflowId, topic, payload) → DBOS.send(workflowId, payload, topic, idempotencyKey).
|
|
168
|
+
* Every call site MUST use the wrapper order (topic BEFORE payload); the raw DBOS swap lives
|
|
169
|
+
* ONLY here so it cannot be reintroduced at a call site (G9).
|
|
170
|
+
*/
|
|
171
|
+
signal(workflowId, topic, payload, idempotencyKey) {
|
|
172
|
+
// REORDER: wrapper (workflowId, topic, payload) → raw send(destinationID, message, topic, idempotencyKey).
|
|
173
|
+
return DBOS.send(workflowId, payload, topic, idempotencyKey);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Durable human wait — MUST be called from inside a registered workflow body.
|
|
177
|
+
* Default DBOS recv timeout is 60 s; pass a far-future deadline so the gate waits indefinitely.
|
|
178
|
+
* The deadline is a fixed constant (GATE_DEADLINE_EPOCH_MS), never Date.now()+X — that would
|
|
179
|
+
* differ per replay and break DBOS replay-safety (G5).
|
|
180
|
+
*/
|
|
181
|
+
awaitDecision(topic, opts) {
|
|
182
|
+
return DBOS.recv(topic, { deadlineEpochMS: opts?.deadlineEpochMS ?? GATE_DEADLINE_EPOCH_MS });
|
|
183
|
+
}
|
|
184
|
+
// ── end generic engine verbs ────────────────────────────────────────────────
|
|
185
|
+
/**
|
|
186
|
+
* Configure DBOS with the pid-proven system database URL.
|
|
187
|
+
* Must be called before launch().
|
|
188
|
+
*/
|
|
189
|
+
setConfig(systemDatabaseUrl, options = {}) {
|
|
190
|
+
DBOS.setConfig({
|
|
191
|
+
name: 'agent-orchestrator',
|
|
192
|
+
systemDatabaseUrl,
|
|
193
|
+
...(options.logLevel ? { logLevel: options.logLevel } : {}),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Launch DBOS (idempotent — guarded by `launched` flag).
|
|
198
|
+
* Auto-recovers in-flight workflows.
|
|
199
|
+
*/
|
|
200
|
+
async launch() {
|
|
201
|
+
if (this.launched)
|
|
202
|
+
return;
|
|
203
|
+
await DBOS.launch();
|
|
204
|
+
this.launched = true;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Shut down DBOS (no-op if never launched — E9).
|
|
208
|
+
*
|
|
209
|
+
* 0008 #3 (shutdown-hang): DBOS.shutdown() awaits in-flight workflows to drain. A workflow
|
|
210
|
+
* PARKED at a human gate (DBOS.recv) never drains, so after `run start --wait` detaches at a
|
|
211
|
+
* gate, app.close() → this → DBOS.shutdown() blocks indefinitely and the CLI never exits.
|
|
212
|
+
* We race the drain against SHUTDOWN_DRAIN_TIMEOUT_MS: on timeout we stop awaiting and let the
|
|
213
|
+
* host detach. Durability is preserved — the parked workflow's state is checkpointed in
|
|
214
|
+
* Postgres and is recovered on the next launch(); abandoning the in-memory drain loses nothing.
|
|
215
|
+
*
|
|
216
|
+
* @param timeoutMs - drain bound (default SHUTDOWN_DRAIN_TIMEOUT_MS); pass 0/Infinity to disable.
|
|
217
|
+
*/
|
|
218
|
+
async shutdown(timeoutMs = SHUTDOWN_DRAIN_TIMEOUT_MS) {
|
|
219
|
+
if (!this.launched)
|
|
220
|
+
return;
|
|
221
|
+
// Mark not-launched up front so a timed-out drain cannot leave a re-entrant launch confused.
|
|
222
|
+
this.launched = false;
|
|
223
|
+
const drain = DBOS.shutdown();
|
|
224
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
225
|
+
await drain;
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
// Swallow a late drain rejection so a post-detach failure never crashes the exiting host.
|
|
229
|
+
void drain.catch(() => undefined);
|
|
230
|
+
let timer;
|
|
231
|
+
const drained = await Promise.race([
|
|
232
|
+
drain.then(() => true).catch(() => true),
|
|
233
|
+
new Promise((resolve) => {
|
|
234
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
235
|
+
}),
|
|
236
|
+
]);
|
|
237
|
+
if (timer)
|
|
238
|
+
clearTimeout(timer);
|
|
239
|
+
if (!drained) {
|
|
240
|
+
console.warn(`[dbos] shutdown drain exceeded ${timeoutMs}ms (likely a workflow parked at a human gate); ` +
|
|
241
|
+
'detaching — durable state is preserved and recovered on next launch.');
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Start the dev:ping durable workflow.
|
|
246
|
+
*
|
|
247
|
+
* CR3: The effective workflow ID is decided in ONE place (the CLI layer — dev.ts) and
|
|
248
|
+
* must always be non-empty before calling this method. This keeps StartWorkflowParams
|
|
249
|
+
* and the workflow args consistent: both see the same stable, non-empty id, so
|
|
250
|
+
* PingResult.workflowID and marker identity are never empty.
|
|
251
|
+
*
|
|
252
|
+
* @param workflowID - Stable, non-empty id (sanitized by the caller — CR1/CR3).
|
|
253
|
+
* @param sleepMs - Duration of step2 sleep (default 15 000 ms).
|
|
254
|
+
* @param markerFile - Path to the durable marker file written by step1.
|
|
255
|
+
*/
|
|
256
|
+
async startPingWorkflow(workflowID, sleepMs, markerFile) {
|
|
257
|
+
return DBOS.startWorkflow(this.pingWorkflow, { workflowID })(workflowID, sleepMs, markerFile);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Get the current status of a workflow by id.
|
|
261
|
+
*/
|
|
262
|
+
getWorkflowStatus(id) {
|
|
263
|
+
return DBOS.getWorkflowStatus(id);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Recover-and-wait: retrieve an existing workflow handle and await its result.
|
|
267
|
+
* Used by `dev:status <id>` — the resume-test command (E10, F2).
|
|
268
|
+
* `DBOS.retrieveWorkflow()` always returns a handle even if the workflow does not exist yet.
|
|
269
|
+
*
|
|
270
|
+
* @deprecated Use `waitForWorkflowResult<T>` for typed workflows. Kept for ping backward compat.
|
|
271
|
+
*/
|
|
272
|
+
async waitForWorkflow(id) {
|
|
273
|
+
const handle = DBOS.retrieveWorkflow(id);
|
|
274
|
+
return handle.getResult();
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Generic recover-and-wait: retrieve a workflow handle by id and await its typed result.
|
|
278
|
+
* Used by `run start` to await workflow completion (C2 fix — so the CLI process does not
|
|
279
|
+
* close before the workflow finishes). Also used for crash-resume: re-running `run start <id>`
|
|
280
|
+
* re-attaches to the existing handle and waits for it to finish — not a double-enqueue.
|
|
281
|
+
*
|
|
282
|
+
* `DBOS.retrieveWorkflow()` always returns a handle (even for a workflow that does not exist yet),
|
|
283
|
+
* so callers should confirm the workflow exists (via `getWorkflowStatus`) before calling this if
|
|
284
|
+
* they want to distinguish "not found" from "in progress".
|
|
285
|
+
*/
|
|
286
|
+
async waitForWorkflowResult(id) {
|
|
287
|
+
const handle = DBOS.retrieveWorkflow(id);
|
|
288
|
+
return handle.getResult();
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
DbosService = __decorate([
|
|
292
|
+
Injectable(),
|
|
293
|
+
__metadata("design:paramtypes", [])
|
|
294
|
+
], DbosService);
|
|
295
|
+
export { DbosService };
|
|
296
|
+
//# sourceMappingURL=dbos.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dbos.service.js","sourceRoot":"","sources":["../../src/engine/dbos.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;;;;;;;;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,aAAa,EAAuB,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAa,CAAC,CAAC,uBAAuB;AAE5E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAkBxC,IAAM,WAAW,GAAjB,MAAM,WAAW;IACd,QAAQ,GAAG,KAAK,CAAC;IAEzB,iFAAiF;IAChE,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE3D,uEAAuE;IACtD,YAAY,CAAiB;IAC7B,QAAQ,CAAa;IACrB,SAAS,CAAc;IAExC;QACE,wFAAwF;QACxF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,YAAY,CAC/B,KAAK,UAAU,YAAY,CAAC,UAAkB,EAAE,UAAkB;YAChE,sFAAsF;YACtF,0FAA0F;YAC1F,oFAAoF;YACpF,oFAAoF;YACpF,kBAAkB;YAClB,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,IAAI,CAAC;gBACH,aAAa,CAAC,UAAU,EAAE,GAAG,UAAU,KAAK,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5F,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACtB,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;oBAAE,MAAM,GAAG,CAAC;gBAChE,2EAA2E;YAC7E,CAAC;YACD,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACnE,CAAC,EACD,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,CAC/C,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,YAAY,CAChC,KAAK,UAAU,aAAa,CAAC,EAAU;YACrC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC,EACD,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,CAChD,CAAC;QAEF,4CAA4C;QAC5C,oFAAoF;QACpF,4FAA4F;QAC5F,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CACvC,KAAK,UAAU,QAAQ,CACrB,UAAkB,EAClB,OAAe,EACf,UAAkB;YAElB,MAAM,WAAW,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAChE,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;YAC9B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;QACrC,CAAC,EACD,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,CAC/C,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,EAAE;IACF,mFAAmF;IACnF,gFAAgF;IAChF,uFAAuF;IACvF,iCAAiC;IACjC,EAAE;IACF,+EAA+E;IAC/E,iGAAiG;IACjG,sEAAsE;IAEtE;;;;OAIG;IACH,YAAY,CACV,IAAY,EACZ,EAA2B;QAE3B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QACrE,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,OAAO,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;;;OAIG;IACH,gBAAgB,CACd,IAAY,EACZ,EAA2B;QAE3B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QACrE,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACjE,OAAO,IAAI,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IACpE,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,IAAY,EAAE,IAA0D;QACpF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,eAAe,CACb,EAA8B,EAC9B,UAAkB,EAClB,SAAiB,EACjB,GAAG,IAAO;QAEV,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpE,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,UAAkB,EAAE,KAAa,EAAE,OAAgB,EAAE,cAAuB;QACjF,2GAA2G;QAC3G,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;IAC/D,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAI,KAAa,EAAE,IAAmC;QACjE,OAAO,IAAI,CAAC,IAAI,CAAI,KAAK,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,eAAe,IAAI,sBAAsB,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,+EAA+E;IAE/E;;;OAGG;IACH,SAAS,CAAC,iBAAyB,EAAE,UAA6B,EAAE;QAClE,IAAI,CAAC,SAAS,CAAC;YACb,IAAI,EAAE,oBAAoB;YAC1B,iBAAiB;YACjB,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5D,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM;QACV,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;IACvB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,QAAQ,CAAC,YAAoB,yBAAyB;QAC1D,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC3B,6FAA6F;QAC7F,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;YAClD,MAAM,KAAK,CAAC;YACZ,OAAO;QACT,CAAC;QACD,0FAA0F;QAC1F,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,KAAgD,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAU;YAC1C,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;YACxC,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;gBAC/B,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;YACtD,CAAC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,KAAK;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACV,kCAAkC,SAAS,iDAAiD;gBAC1F,sEAAsE,CACzE,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,iBAAiB,CACrB,UAAkB,EAClB,OAAe,EACf,UAAkB;QAElB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAChG,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,EAAU;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe,CAAC,EAAU;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAa,EAAE,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC,SAAS,EAAE,CAAC;IAC5B,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,qBAAqB,CAAI,EAAU;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAI,EAAE,CAAC,CAAC;QAC5C,OAAO,MAAM,CAAC,SAAS,EAAE,CAAC;IAC5B,CAAC;CACF,CAAA;AAhRY,WAAW;IADvB,UAAU,EAAE;;GACA,WAAW,CAgRvB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ensurePostgres() — creates the `dbos` database in Revisium's embedded Postgres if absent.
|
|
3
|
+
*
|
|
4
|
+
* Idempotent: checks pg_database first; only issues CREATE DATABASE when absent.
|
|
5
|
+
* Uses the pid-proven pg port from runtime.json (never hardcodes it — ADR-0001 #4).
|
|
6
|
+
*
|
|
7
|
+
* PG creds default: `revisium`/`password` — confirmed from @revisium/standalone 2.8.2 (F5).
|
|
8
|
+
* Kept parameterized so a future config change is one line.
|
|
9
|
+
*
|
|
10
|
+
* Race safety (F17): Two concurrent first-run hosts may both observe count=0 and both issue
|
|
11
|
+
* CREATE DATABASE. PostgreSQL raises SQLSTATE 42P04 (duplicate_database) for the loser.
|
|
12
|
+
* We catch 42P04 and treat it as success — the database now exists, which is the desired
|
|
13
|
+
* postcondition. All other errors are re-thrown verbatim.
|
|
14
|
+
*
|
|
15
|
+
* Testability (F20): ensurePostgres accepts an optional `deps.createClient` factory so tests
|
|
16
|
+
* can inject a fake client that exercises the real 42P04 catch / SELECT fast-path without a
|
|
17
|
+
* live Postgres. The production default constructs a real `pg.Client`.
|
|
18
|
+
*/
|
|
19
|
+
import pg from 'pg';
|
|
20
|
+
const DBOS_DB_NAME = 'dbos';
|
|
21
|
+
const MAINTENANCE_DB = 'postgres';
|
|
22
|
+
/** PostgreSQL SQLSTATE for "database already exists" (duplicate_database). */
|
|
23
|
+
const PG_SQLSTATE_DUPLICATE_DATABASE = '42P04';
|
|
24
|
+
const DEFAULT_CREDS = {
|
|
25
|
+
user: 'revisium',
|
|
26
|
+
password: 'password',
|
|
27
|
+
adminDb: MAINTENANCE_DB,
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Ensure the `dbos` database exists on the Revisium embedded Postgres.
|
|
31
|
+
* @param pgPort - The pid-proven pg port from runtime.json.
|
|
32
|
+
* @param opts - Optional credential overrides (default: revisium/password).
|
|
33
|
+
* @param deps - Optional injectable dependencies for testing (F20).
|
|
34
|
+
*/
|
|
35
|
+
export async function ensurePostgres(pgPort, opts = {}, deps = {}) {
|
|
36
|
+
const { user, password, adminDb } = { ...DEFAULT_CREDS, ...opts };
|
|
37
|
+
// pg.Client.connect() returns Promise<Client> while ClientLike.connect() returns
|
|
38
|
+
// Promise<void>; they are structurally compatible at the call sites used here, but
|
|
39
|
+
// TypeScript requires an explicit cast via unknown to bridge the return-type difference.
|
|
40
|
+
const pgClientFactory = () => new pg.Client({ host: 'localhost', port: pgPort, user, password, database: adminDb });
|
|
41
|
+
const createClient = deps.createClient ?? pgClientFactory;
|
|
42
|
+
const client = createClient();
|
|
43
|
+
try {
|
|
44
|
+
await client.connect();
|
|
45
|
+
const result = await client.query(`SELECT count(*)::text AS count FROM pg_database WHERE datname = $1`, [DBOS_DB_NAME]);
|
|
46
|
+
const exists = result.rows[0]?.count !== '0';
|
|
47
|
+
if (!exists) {
|
|
48
|
+
// CREATE DATABASE cannot be parameterized; `dbos` is a fixed literal with no injection surface.
|
|
49
|
+
// Race backstop (F17): if two hosts both observed count=0 and both issue CREATE DATABASE,
|
|
50
|
+
// PostgreSQL raises 42P04 (duplicate_database) for the loser. Treat it as success
|
|
51
|
+
// (idempotent — the database now exists). Re-throw any other error.
|
|
52
|
+
try {
|
|
53
|
+
await client.query(`CREATE DATABASE ${DBOS_DB_NAME}`);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
if (err.code === PG_SQLSTATE_DUPLICATE_DATABASE) {
|
|
57
|
+
// Another concurrent host already created it — this is fine.
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
await client.end();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build the DBOS system database URL from the pid-proven pg port.
|
|
70
|
+
* Single place; never hardcodes the port.
|
|
71
|
+
*
|
|
72
|
+
* CR4: user and password are percent-encoded via encodeURIComponent so that
|
|
73
|
+
* reserved characters (e.g. '@', ':', '/', '%') do not break the URI.
|
|
74
|
+
* The default credentials ('revisium'/'password') contain no reserved chars
|
|
75
|
+
* and encode to themselves, so existing behaviour is unchanged.
|
|
76
|
+
*/
|
|
77
|
+
export function dbosSystemDatabaseUrl(pgPort, user = 'revisium', password = 'password') {
|
|
78
|
+
return `postgresql://${encodeURIComponent(user)}:${encodeURIComponent(password)}@localhost:${pgPort}/${DBOS_DB_NAME}`;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=ensure-postgres.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-postgres.js","sourceRoot":"","sources":["../../src/engine/ensure-postgres.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,MAAM,cAAc,GAAG,UAAU,CAAC;AAElC,8EAA8E;AAC9E,MAAM,8BAA8B,GAAG,OAAO,CAAC;AAQ/C,MAAM,aAAa,GAAwB;IACzC,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,UAAU;IACpB,OAAO,EAAE,cAAc;CACxB,CAAC;AAkBF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAc,EACd,OAAqC,EAAE,EACvC,OAA2B,EAAE;IAE7B,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,aAAa,EAAE,GAAG,IAAI,EAAE,CAAC;IAClE,iFAAiF;IACjF,mFAAmF;IACnF,yFAAyF;IACzF,MAAM,eAAe,GAAG,GAAe,EAAE,CACvC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAA0B,CAAC;IACjH,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,eAAe,CAAC;IAE1D,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,CAC/B,oEAAoE,EACpE,CAAC,YAAY,CAAC,CACf,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,GAAG,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,gGAAgG;YAChG,0FAA0F;YAC1F,kFAAkF;YAClF,oEAAoE;YACpE,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAK,GAAyB,CAAC,IAAI,KAAK,8BAA8B,EAAE,CAAC;oBACvE,6DAA6D;oBAC7D,OAAO;gBACT,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAc,EACd,IAAI,GAAG,UAAU,EACjB,QAAQ,GAAG,UAAU;IAErB,OAAO,gBAAgB,kBAAkB,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,cAAc,MAAM,IAAI,YAAY,EAAE,CAAC;AACxH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":""}
|