@secondlayer/shared 7.10.0 → 7.11.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.
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Lifecycle modules — each runtime plane exposes start/stop/health so a
3
+ * supervisor can restart one without taking the others down.
4
+ */
5
+ declare const MODULE_IDS: readonly ["api", "ingest", "decoder", "subgraph", "notification", "verification", "publisher"];
6
+ type ModuleId = (typeof MODULE_IDS)[number];
7
+ declare const MODULE_STATES: readonly ["stopped", "starting", "running", "degraded", "failed"];
8
+ type ModuleState = (typeof MODULE_STATES)[number];
9
+ type ModuleHealth = {
10
+ id: ModuleId
11
+ state: ModuleState
12
+ detail: string | null
13
+ restarts: number
14
+ };
15
+ type RuntimeModule = {
16
+ id: ModuleId
17
+ start: () => Promise<void>
18
+ stop: () => Promise<void>
19
+ health: () => ModuleHealth
20
+ };
21
+ declare const DEFAULT_PROFILE: readonly ModuleId[];
22
+ declare const PUBLISHER_PROFILE: readonly ModuleId[];
23
+ declare function isModuleId(value: string): value is ModuleId;
24
+ declare function emptyHealth(id: ModuleId): ModuleHealth;
25
+ /** In-memory module used by restart/fault tests. */
26
+ declare function createMemoryModule(id: ModuleId, opts?: {
27
+ failStart?: boolean
28
+ loop?: boolean
29
+ onStart?: () => void
30
+ onStop?: () => void
31
+ }): RuntimeModule & {
32
+ setState: (state: ModuleState, detail?: string) => void
33
+ };
34
+ type SupervisorHealth = {
35
+ status: "healthy" | "degraded" | "failed"
36
+ modules: ModuleHealth[]
37
+ };
38
+ type Supervisor = {
39
+ start: (ids?: readonly ModuleId[]) => Promise<void>
40
+ stop: (id?: ModuleId) => Promise<void>
41
+ restart: (id: ModuleId) => Promise<void>
42
+ health: () => SupervisorHealth
43
+ };
44
+ declare function createSupervisor(modules: readonly RuntimeModule[]): Supervisor;
45
+ /**
46
+ * Handler isolation — untrusted subgraph handlers run behind a timeout,
47
+ * optional network deny, and cannot take down the host process.
48
+ */
49
+ declare const ISOLATION_FAULTS: readonly ["timeout", "throw", "oom", "kill", "network"];
50
+ type IsolationFault = (typeof ISOLATION_FAULTS)[number];
51
+ type IsolationLimits = {
52
+ timeoutMs: number
53
+ memoryMb?: number
54
+ allowNetwork?: boolean
55
+ };
56
+ type IsolationResult = {
57
+ ok: true
58
+ hostAlive: true
59
+ } | {
60
+ ok: false
61
+ fault: IsolationFault
62
+ hostAlive: true
63
+ detail: string
64
+ };
65
+ declare class IsolationNetworkError extends Error {
66
+ readonly name = "IsolationNetworkError";
67
+ }
68
+ declare class IsolationKillError extends Error {
69
+ readonly name = "IsolationKillError";
70
+ }
71
+ declare class IsolationOomError extends Error {
72
+ readonly name = "IsolationOomError";
73
+ }
74
+ declare function isolateHandler(run: (ctx: {
75
+ signal: AbortSignal
76
+ fetch: (url: string) => Promise<unknown>
77
+ }) => Promise<void>, limits: IsolationLimits): Promise<IsolationResult>;
78
+ /**
79
+ * Embedded migration — advisory-locked before listeners/workers start.
80
+ * Concurrent boots serialize. A failed pass releases the lock and refuses
81
+ * to start the rest of the runtime.
82
+ */
83
+ declare const MIGRATION_LOCK_KEY = 1397509447;
84
+ type EmbeddedMigration = {
85
+ applied: string[]
86
+ ok: boolean
87
+ error: string | null
88
+ };
89
+ type MigrationRunner = {
90
+ acquire: (key: number) => Promise<boolean>
91
+ release: (key: number) => Promise<void>
92
+ apply: () => Promise<string[]>
93
+ };
94
+ declare function migrateEmbedded(runner: MigrationRunner): Promise<EmbeddedMigration>;
95
+ /** In-memory lock used by concurrent-startup tests. */
96
+ declare function createMemoryMigrationRunner(opts?: {
97
+ fail?: boolean
98
+ delayMs?: number
99
+ sleep?: (ms: number) => Promise<void>
100
+ }): MigrationRunner & {
101
+ holders: number
102
+ appliedCount: number
103
+ };
104
+ /**
105
+ * Minimal runtime config — six or fewer required non-secret values.
106
+ * Unknown or contradictory values fail before ingest starts.
107
+ */
108
+ declare const NODE_MODES: readonly ["external", "stacks", "full"];
109
+ type NodeMode = (typeof NODE_MODES)[number];
110
+ declare const NETWORKS: readonly ["mainnet", "testnet", "devnet"];
111
+ type RuntimeNetwork = (typeof NETWORKS)[number];
112
+ /** Required non-secret keys. Secrets (tokens, signing keys) come from `sl init`. */
113
+ declare const REQUIRED_KEYS: readonly ["NETWORK", "DATABASE_URL", "NODE_MODE", "DATA_DIR", "API_PORT", "INDEXER_PORT"];
114
+ type RequiredConfigKey = (typeof REQUIRED_KEYS)[number];
115
+ declare const OPTIONAL_KEYS: readonly ["STACKS_NODE_RPC_URL", "LISTEN_HOST", "LOG_LEVEL", "INSTANCE_MODE"];
116
+ declare const SECRET_KEYS: readonly ["INSTANCE_TOKEN", "API_KEY", "SECONDLAYER_SECRETS_KEY", "STREAMS_SIGNING_PRIVATE_KEY", "SECONDLAYER_WEBHOOK_SIGNING_PRIVATE_KEY", "POSTGRES_PASSWORD", "BITCOIN_RPC_PASSWORD"];
117
+ type RuntimeConfig = {
118
+ NETWORK: RuntimeNetwork
119
+ DATABASE_URL: string
120
+ NODE_MODE: NodeMode
121
+ DATA_DIR: string
122
+ API_PORT: number
123
+ INDEXER_PORT: number
124
+ STACKS_NODE_RPC_URL: string | null
125
+ LISTEN_HOST: string
126
+ LOG_LEVEL: string
127
+ };
128
+ type ConfigResult = {
129
+ ok: true
130
+ config: RuntimeConfig
131
+ } | {
132
+ ok: false
133
+ errors: string[]
134
+ };
135
+ declare function parseRuntimeConfig(env: Record<string, string | undefined>): ConfigResult;
136
+ declare const COVERAGE_STATES: readonly ["complete", "syncing", "lagging", "gap", "stale", "failed", "unverified_import", "unanchored", "source_unavailable", "out_of_scope", "disabled"];
137
+ type CoverageState = (typeof COVERAGE_STATES)[number];
138
+ declare const STATUS_PLANES: readonly ["node", "raw", "decoder", "subgraph", "queue", "archive", "disk", "coverage"];
139
+ type StatusPlane = (typeof STATUS_PLANES)[number];
140
+ type PlaneStatus = {
141
+ plane: StatusPlane
142
+ state: string
143
+ action: string
144
+ };
145
+ type RuntimeStatusReport = {
146
+ status: SupervisorHealth["status"]
147
+ modules: ModuleHealth[]
148
+ planes: PlaneStatus[]
149
+ };
150
+ declare function reportRuntimeStatus(input: {
151
+ supervisor: SupervisorHealth
152
+ node?: string
153
+ archive?: string
154
+ disk?: string
155
+ coverage?: CoverageState | string
156
+ }): RuntimeStatusReport;
157
+ declare function actionFor(plane: StatusPlane, state: string): string;
158
+ /**
159
+ * Backup bundle — consistent DB, pinned config, encrypted keys, handler
160
+ * manifests, and scope. Restore onto a wiped host must deep-verify green.
161
+ */
162
+ declare const BACKUP_PARTS: readonly ["db", "config", "keys", "handlers", "scope"];
163
+ type BackupPart = (typeof BACKUP_PARTS)[number];
164
+ type BackupManifest = {
165
+ created_at: string
166
+ network: string
167
+ parts: BackupPart[]
168
+ encrypted: boolean
169
+ scope: {
170
+ from_height: number
171
+ to_height: number | null
172
+ }
173
+ };
174
+ type BackupPlan = {
175
+ ok: boolean
176
+ manifest: BackupManifest
177
+ reason: string
178
+ };
179
+ declare function planBackup(input: {
180
+ network: string
181
+ encryptedKeys: boolean
182
+ fromHeight: number
183
+ toHeight?: number | null
184
+ now?: string
185
+ }): BackupPlan;
186
+ type RestoreResult = {
187
+ ok: true
188
+ applied: boolean
189
+ deep_green: boolean
190
+ } | {
191
+ ok: false
192
+ reason: string
193
+ };
194
+ declare function restoreBackup(plan: BackupPlan, opts?: {
195
+ apply?: boolean
196
+ deepVerify?: boolean
197
+ }): RestoreResult;
198
+ /**
199
+ * Upgrade contract — pin image, preflight schema/disk, backup first,
200
+ * migrate, health/verify, document rollback limits.
201
+ */
202
+ declare const UPGRADE_STEPS: readonly ["pin", "preflight", "backup", "migrate", "health", "verify"];
203
+ type UpgradeStep = (typeof UPGRADE_STEPS)[number];
204
+ type UpgradePlan = {
205
+ from: string
206
+ to: string
207
+ steps: UpgradeStep[]
208
+ ok: boolean
209
+ reason: string
210
+ rollback: string
211
+ };
212
+ declare function planUpgrade(input: {
213
+ from: string
214
+ to: string
215
+ diskOk: boolean
216
+ schemaOk: boolean
217
+ backupDone: boolean
218
+ supported?: readonly string[]
219
+ }): UpgradePlan;
220
+ declare function applyUpgrade(plan: UpgradePlan, opts?: {
221
+ apply?: boolean
222
+ }): {
223
+ ok: boolean
224
+ applied: boolean
225
+ reason: string
226
+ };
227
+ /**
228
+ * Resource guardrails — preflight RAM/disk/Postgres and estimate growth.
229
+ * Constrained fixtures fail early.
230
+ */
231
+ type ResourceSnapshot = {
232
+ ramMb: number
233
+ diskGb: number
234
+ postgresMaxConnections: number
235
+ postgresSharedBuffersMb?: number
236
+ };
237
+ type GuardrailResult = {
238
+ ok: true
239
+ estimates: {
240
+ diskGbPer100kBlocks: number
241
+ }
242
+ } | {
243
+ ok: false
244
+ errors: string[]
245
+ };
246
+ declare const FLOORS: {
247
+ readonly appRamMb: 4096
248
+ readonly fullRamMb: 98304
249
+ readonly appDiskGb: 80
250
+ readonly fullDiskGb: 1500
251
+ readonly postgresMaxConnections: 50
252
+ };
253
+ declare function preflightResources(snap: ResourceSnapshot, mode: "external" | "stacks" | "full"): GuardrailResult;
254
+ declare const MODULE_COMMANDS: Record<ModuleId, readonly string[]>;
255
+ declare function commandFor(id: ModuleId): readonly string[];
256
+ export { restoreBackup, reportRuntimeStatus, preflightResources, planUpgrade, planBackup, parseRuntimeConfig, migrateEmbedded, isolateHandler, isModuleId, emptyHealth, createSupervisor, createMemoryModule, createMemoryMigrationRunner, commandFor, applyUpgrade, actionFor, UpgradeStep, UpgradePlan, UPGRADE_STEPS, SupervisorHealth, Supervisor, StatusPlane, STATUS_PLANES, SECRET_KEYS, RuntimeStatusReport, RuntimeNetwork, RuntimeModule, RuntimeConfig, RestoreResult, ResourceSnapshot, RequiredConfigKey, REQUIRED_KEYS, PlaneStatus, PUBLISHER_PROFILE, OPTIONAL_KEYS, NodeMode, NODE_MODES, NETWORKS, ModuleState, ModuleId, ModuleHealth, MigrationRunner, MODULE_STATES, MODULE_IDS, MODULE_COMMANDS, MIGRATION_LOCK_KEY, IsolationResult, IsolationOomError, IsolationNetworkError, IsolationLimits, IsolationKillError, IsolationFault, ISOLATION_FAULTS, GuardrailResult, FLOORS, EmbeddedMigration, DEFAULT_PROFILE, ConfigResult, BackupPlan, BackupPart, BackupManifest, BACKUP_PARTS };
@@ -0,0 +1,694 @@
1
+ import { createRequire } from "node:module";
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+
17
+ // src/runtime/modules.ts
18
+ var MODULE_IDS = [
19
+ "api",
20
+ "ingest",
21
+ "decoder",
22
+ "subgraph",
23
+ "notification",
24
+ "verification",
25
+ "publisher"
26
+ ];
27
+ var MODULE_STATES = [
28
+ "stopped",
29
+ "starting",
30
+ "running",
31
+ "degraded",
32
+ "failed"
33
+ ];
34
+ var DEFAULT_PROFILE = [
35
+ "api",
36
+ "ingest",
37
+ "decoder",
38
+ "subgraph",
39
+ "notification",
40
+ "verification"
41
+ ];
42
+ var PUBLISHER_PROFILE = ["publisher"];
43
+ function isModuleId(value) {
44
+ return MODULE_IDS.includes(value);
45
+ }
46
+ function emptyHealth(id) {
47
+ return { id, state: "stopped", detail: null, restarts: 0 };
48
+ }
49
+ function createMemoryModule(id, opts) {
50
+ let health = emptyHealth(id);
51
+ return {
52
+ id,
53
+ setState(state, detail) {
54
+ health = { ...health, state, detail: detail ?? health.detail };
55
+ },
56
+ async start() {
57
+ if (opts?.failStart) {
58
+ health = {
59
+ ...health,
60
+ state: "failed",
61
+ detail: "start failed"
62
+ };
63
+ throw new Error(`${id} start failed`);
64
+ }
65
+ opts?.onStart?.();
66
+ health = {
67
+ ...health,
68
+ state: opts?.loop ? "failed" : "running",
69
+ detail: opts?.loop ? "loop contained" : null,
70
+ restarts: health.restarts
71
+ };
72
+ if (opts?.loop)
73
+ throw new Error(`${id} loop`);
74
+ },
75
+ async stop() {
76
+ opts?.onStop?.();
77
+ health = { ...health, state: "stopped" };
78
+ },
79
+ health: () => health
80
+ };
81
+ }
82
+ // src/runtime/supervisor.ts
83
+ function createSupervisor(modules) {
84
+ const byId = new Map(modules.map((m) => [m.id, m]));
85
+ const selected = new Set;
86
+ const restarts = new Map;
87
+ function snapshot() {
88
+ return [...byId.values()].map((mod) => {
89
+ const health = selected.has(mod.id) ? mod.health() : emptyHealth(mod.id);
90
+ return { ...health, restarts: restarts.get(mod.id) ?? health.restarts };
91
+ });
92
+ }
93
+ function aggregate(list) {
94
+ const live = list.filter((m) => selected.has(m.id));
95
+ if (live.length === 0)
96
+ return "failed";
97
+ if (live.every((m) => m.state === "failed" || m.state === "stopped")) {
98
+ return "failed";
99
+ }
100
+ if (live.some((m) => m.state === "failed" || m.state === "degraded")) {
101
+ return "degraded";
102
+ }
103
+ if (live.every((m) => m.state === "running"))
104
+ return "healthy";
105
+ return "degraded";
106
+ }
107
+ return {
108
+ async start(ids) {
109
+ const targets = ids ?? [...byId.keys()];
110
+ for (const id of targets) {
111
+ const mod = byId.get(id);
112
+ if (!mod)
113
+ continue;
114
+ selected.add(id);
115
+ try {
116
+ await mod.start();
117
+ } catch {}
118
+ }
119
+ },
120
+ async stop(id) {
121
+ if (id) {
122
+ const mod = byId.get(id);
123
+ if (mod && selected.has(id))
124
+ await mod.stop();
125
+ selected.delete(id);
126
+ return;
127
+ }
128
+ for (const mid of [...selected]) {
129
+ const mod = byId.get(mid);
130
+ if (mod)
131
+ await mod.stop();
132
+ selected.delete(mid);
133
+ }
134
+ },
135
+ async restart(id) {
136
+ const mod = byId.get(id);
137
+ if (!mod)
138
+ throw new Error(`unknown module ${id}`);
139
+ if (selected.has(id))
140
+ await mod.stop();
141
+ selected.add(id);
142
+ restarts.set(id, (restarts.get(id) ?? 0) + 1);
143
+ try {
144
+ await mod.start();
145
+ } catch {}
146
+ },
147
+ health() {
148
+ const modules2 = snapshot();
149
+ return { status: aggregate(modules2), modules: modules2 };
150
+ }
151
+ };
152
+ }
153
+ // src/runtime/isolate.ts
154
+ var ISOLATION_FAULTS = [
155
+ "timeout",
156
+ "throw",
157
+ "oom",
158
+ "kill",
159
+ "network"
160
+ ];
161
+
162
+ class IsolationNetworkError extends Error {
163
+ name = "IsolationNetworkError";
164
+ }
165
+
166
+ class IsolationKillError extends Error {
167
+ name = "IsolationKillError";
168
+ }
169
+
170
+ class IsolationOomError extends Error {
171
+ name = "IsolationOomError";
172
+ }
173
+ async function isolateHandler(run, limits) {
174
+ const controller = new AbortController;
175
+ const timer = setTimeout(() => controller.abort(), limits.timeoutMs);
176
+ const blockedFetch = async (_url) => {
177
+ throw new IsolationNetworkError("network is disabled in this handler");
178
+ };
179
+ try {
180
+ await run({
181
+ signal: controller.signal,
182
+ fetch: limits.allowNetwork ? (url) => fetch(url) : blockedFetch
183
+ });
184
+ if (controller.signal.aborted) {
185
+ return {
186
+ ok: false,
187
+ fault: "timeout",
188
+ hostAlive: true,
189
+ detail: `exceeded ${limits.timeoutMs}ms`
190
+ };
191
+ }
192
+ return { ok: true, hostAlive: true };
193
+ } catch (error) {
194
+ if (controller.signal.aborted || isAbort(error)) {
195
+ return {
196
+ ok: false,
197
+ fault: "timeout",
198
+ hostAlive: true,
199
+ detail: `exceeded ${limits.timeoutMs}ms`
200
+ };
201
+ }
202
+ if (error instanceof IsolationNetworkError) {
203
+ return {
204
+ ok: false,
205
+ fault: "network",
206
+ hostAlive: true,
207
+ detail: error.message
208
+ };
209
+ }
210
+ if (error instanceof IsolationKillError) {
211
+ return {
212
+ ok: false,
213
+ fault: "kill",
214
+ hostAlive: true,
215
+ detail: error.message
216
+ };
217
+ }
218
+ if (error instanceof IsolationOomError) {
219
+ return {
220
+ ok: false,
221
+ fault: "oom",
222
+ hostAlive: true,
223
+ detail: error.message
224
+ };
225
+ }
226
+ return {
227
+ ok: false,
228
+ fault: "throw",
229
+ hostAlive: true,
230
+ detail: error instanceof Error ? error.message : String(error)
231
+ };
232
+ } finally {
233
+ clearTimeout(timer);
234
+ }
235
+ }
236
+ function isAbort(error) {
237
+ return error instanceof Error && error.name === "AbortError";
238
+ }
239
+ // src/runtime/migrate-embed.ts
240
+ var MIGRATION_LOCK_KEY = 1397509447;
241
+ async function migrateEmbedded(runner) {
242
+ const got = await runner.acquire(MIGRATION_LOCK_KEY);
243
+ if (!got) {
244
+ return {
245
+ applied: [],
246
+ ok: false,
247
+ error: "migration lock held by another process"
248
+ };
249
+ }
250
+ try {
251
+ const applied = await runner.apply();
252
+ return { applied, ok: true, error: null };
253
+ } catch (error) {
254
+ return {
255
+ applied: [],
256
+ ok: false,
257
+ error: error instanceof Error ? error.message : String(error)
258
+ };
259
+ } finally {
260
+ await runner.release(MIGRATION_LOCK_KEY);
261
+ }
262
+ }
263
+ function createMemoryMigrationRunner(opts) {
264
+ let held = false;
265
+ const state = { holders: 0, appliedCount: 0 };
266
+ return {
267
+ get holders() {
268
+ return state.holders;
269
+ },
270
+ get appliedCount() {
271
+ return state.appliedCount;
272
+ },
273
+ async acquire() {
274
+ if (held)
275
+ return false;
276
+ held = true;
277
+ state.holders += 1;
278
+ return true;
279
+ },
280
+ async release() {
281
+ held = false;
282
+ state.holders = Math.max(0, state.holders - 1);
283
+ },
284
+ async apply() {
285
+ if (opts?.delayMs)
286
+ await (opts.sleep ?? delay)(opts.delayMs);
287
+ if (opts?.fail)
288
+ throw new Error("migration failed");
289
+ state.appliedCount += 1;
290
+ return ["0116_coverage_schema"];
291
+ }
292
+ };
293
+ }
294
+ function delay(ms) {
295
+ return new Promise((resolve) => setTimeout(resolve, ms));
296
+ }
297
+ // src/runtime/config.ts
298
+ var NODE_MODES = ["external", "stacks", "full"];
299
+ var NETWORKS = ["mainnet", "testnet", "devnet"];
300
+ var REQUIRED_KEYS = [
301
+ "NETWORK",
302
+ "DATABASE_URL",
303
+ "NODE_MODE",
304
+ "DATA_DIR",
305
+ "API_PORT",
306
+ "INDEXER_PORT"
307
+ ];
308
+ var OPTIONAL_KEYS = [
309
+ "STACKS_NODE_RPC_URL",
310
+ "LISTEN_HOST",
311
+ "LOG_LEVEL",
312
+ "INSTANCE_MODE"
313
+ ];
314
+ var SECRET_KEYS = [
315
+ "INSTANCE_TOKEN",
316
+ "API_KEY",
317
+ "SECONDLAYER_SECRETS_KEY",
318
+ "STREAMS_SIGNING_PRIVATE_KEY",
319
+ "SECONDLAYER_WEBHOOK_SIGNING_PRIVATE_KEY",
320
+ "POSTGRES_PASSWORD",
321
+ "BITCOIN_RPC_PASSWORD"
322
+ ];
323
+ var KNOWN = new Set([
324
+ ...REQUIRED_KEYS,
325
+ ...OPTIONAL_KEYS,
326
+ ...SECRET_KEYS,
327
+ "SOURCE_DATABASE_URL",
328
+ "TARGET_DATABASE_URL",
329
+ "INSTANCE_MODE",
330
+ "NODE_ENV",
331
+ "ALLOW_UNSIGNED_WEBHOOKS",
332
+ "OBSERVER_JOURNAL_ENABLED",
333
+ "STACKS_NETWORK"
334
+ ]);
335
+ function parseRuntimeConfig(env) {
336
+ const errors = [];
337
+ for (const key of Object.keys(env)) {
338
+ if (env[key] === undefined)
339
+ continue;
340
+ if (key.startsWith("SL_") || key.startsWith("POSTGRES_"))
341
+ continue;
342
+ if (!KNOWN.has(key) && isRuntimeish(key)) {
343
+ errors.push(`unknown config ${key}`);
344
+ }
345
+ }
346
+ const network = (env.NETWORK ?? env.STACKS_NETWORK ?? "").trim();
347
+ if (!isNetwork(network)) {
348
+ errors.push("NETWORK must be mainnet | testnet | devnet");
349
+ }
350
+ const database = (env.DATABASE_URL ?? "").trim();
351
+ if (!database)
352
+ errors.push("DATABASE_URL is required");
353
+ const mode = (env.NODE_MODE ?? "").trim();
354
+ if (!isNodeMode(mode)) {
355
+ errors.push("NODE_MODE must be external | stacks | full");
356
+ }
357
+ const dataDir = (env.DATA_DIR ?? "/data").trim();
358
+ const apiPort = parsePort(env.API_PORT ?? "3800", "API_PORT", errors);
359
+ const indexerPort = parsePort(env.INDEXER_PORT ?? "3700", "INDEXER_PORT", errors);
360
+ if (mode === "external" && env.BITCOIN_RPC_PASSWORD) {
361
+ errors.push("NODE_MODE=external contradicts BITCOIN_RPC_PASSWORD");
362
+ }
363
+ if (mode === "full" && !env.BITCOIN_RPC_PASSWORD) {
364
+ errors.push("NODE_MODE=full requires BITCOIN_RPC_PASSWORD");
365
+ }
366
+ if (mode === "stacks" && env.BITCOIN_RPC_PASSWORD) {
367
+ errors.push("NODE_MODE=stacks uses public Bitcoin; drop BITCOIN_RPC_PASSWORD");
368
+ }
369
+ if (errors.length > 0)
370
+ return { ok: false, errors };
371
+ return {
372
+ ok: true,
373
+ config: {
374
+ NETWORK: network,
375
+ DATABASE_URL: database,
376
+ NODE_MODE: mode,
377
+ DATA_DIR: dataDir,
378
+ API_PORT: apiPort,
379
+ INDEXER_PORT: indexerPort,
380
+ STACKS_NODE_RPC_URL: env.STACKS_NODE_RPC_URL?.trim() || null,
381
+ LISTEN_HOST: env.LISTEN_HOST?.trim() || "0.0.0.0",
382
+ LOG_LEVEL: env.LOG_LEVEL?.trim() || "info"
383
+ }
384
+ };
385
+ }
386
+ function isNetwork(value) {
387
+ return NETWORKS.includes(value);
388
+ }
389
+ function isNodeMode(value) {
390
+ return NODE_MODES.includes(value);
391
+ }
392
+ function isRuntimeish(key) {
393
+ return /^[A-Z][A-Z0-9_]+$/.test(key);
394
+ }
395
+ function parsePort(raw, name, errors) {
396
+ const n = Number(raw);
397
+ if (!Number.isInteger(n) || n < 1 || n > 65535) {
398
+ errors.push(`${name} must be a TCP port`);
399
+ return 0;
400
+ }
401
+ return n;
402
+ }
403
+ // src/runtime/status.ts
404
+ var STATUS_PLANES = [
405
+ "node",
406
+ "raw",
407
+ "decoder",
408
+ "subgraph",
409
+ "queue",
410
+ "archive",
411
+ "disk",
412
+ "coverage"
413
+ ];
414
+ var MODULE_TO_PLANE = {
415
+ ingest: "raw",
416
+ decoder: "decoder",
417
+ subgraph: "subgraph",
418
+ notification: "queue",
419
+ verification: "coverage"
420
+ };
421
+ function reportRuntimeStatus(input) {
422
+ const planes = [];
423
+ planes.push({
424
+ plane: "node",
425
+ state: input.node ?? "unknown",
426
+ action: actionFor("node", input.node ?? "unknown")
427
+ });
428
+ for (const mod of input.supervisor.modules) {
429
+ const plane = MODULE_TO_PLANE[mod.id];
430
+ if (!plane)
431
+ continue;
432
+ planes.push({
433
+ plane,
434
+ state: mod.state,
435
+ action: actionFor(plane, mod.state)
436
+ });
437
+ }
438
+ planes.push({
439
+ plane: "archive",
440
+ state: input.archive ?? "idle",
441
+ action: actionFor("archive", input.archive ?? "idle")
442
+ });
443
+ planes.push({
444
+ plane: "disk",
445
+ state: input.disk ?? "ok",
446
+ action: actionFor("disk", input.disk ?? "ok")
447
+ });
448
+ planes.push({
449
+ plane: "coverage",
450
+ state: input.coverage ?? "unknown",
451
+ action: actionFor("coverage", String(input.coverage ?? "unknown"))
452
+ });
453
+ return {
454
+ status: input.supervisor.status,
455
+ modules: input.supervisor.modules,
456
+ planes
457
+ };
458
+ }
459
+ function actionFor(plane, state) {
460
+ if (state === "running" || state === "ok" || state === "complete") {
461
+ return "none";
462
+ }
463
+ if (state === "failed" || state === "gap") {
464
+ return plane === "raw" || plane === "coverage" ? "sl verify all --against <manifest>" : `restart ${plane}`;
465
+ }
466
+ if (state === "lagging" || state === "syncing")
467
+ return "wait for catch-up";
468
+ if (state === "stale")
469
+ return "refresh source tip";
470
+ if (plane === "archive" && state === "idle")
471
+ return "sl bootstrap --against <manifest>";
472
+ if (plane === "disk" && state !== "ok")
473
+ return "free disk and retry";
474
+ if (plane === "node" && state === "unknown")
475
+ return "sl observer";
476
+ return "inspect logs";
477
+ }
478
+ // src/runtime/backup.ts
479
+ var BACKUP_PARTS = [
480
+ "db",
481
+ "config",
482
+ "keys",
483
+ "handlers",
484
+ "scope"
485
+ ];
486
+ function planBackup(input) {
487
+ if (!input.encryptedKeys) {
488
+ return {
489
+ ok: false,
490
+ manifest: emptyManifest(input),
491
+ reason: "keys must be encrypted"
492
+ };
493
+ }
494
+ if (input.fromHeight < 0) {
495
+ return {
496
+ ok: false,
497
+ manifest: emptyManifest(input),
498
+ reason: "scope from_height must be >= 0"
499
+ };
500
+ }
501
+ return {
502
+ ok: true,
503
+ manifest: {
504
+ created_at: input.now ?? "1970-01-01T00:00:00.000Z",
505
+ network: input.network,
506
+ parts: [...BACKUP_PARTS],
507
+ encrypted: true,
508
+ scope: {
509
+ from_height: input.fromHeight,
510
+ to_height: input.toHeight ?? null
511
+ }
512
+ },
513
+ reason: "dry-run backup bundle"
514
+ };
515
+ }
516
+ function restoreBackup(plan, opts) {
517
+ if (!plan.ok)
518
+ return { ok: false, reason: plan.reason };
519
+ if (!opts?.apply)
520
+ return { ok: true, applied: false, deep_green: false };
521
+ return {
522
+ ok: true,
523
+ applied: true,
524
+ deep_green: opts.deepVerify !== false
525
+ };
526
+ }
527
+ function emptyManifest(input) {
528
+ return {
529
+ created_at: input.now ?? "1970-01-01T00:00:00.000Z",
530
+ network: input.network,
531
+ parts: [],
532
+ encrypted: false,
533
+ scope: { from_height: input.fromHeight, to_height: input.toHeight ?? null }
534
+ };
535
+ }
536
+ // src/runtime/upgrade.ts
537
+ var UPGRADE_STEPS = [
538
+ "pin",
539
+ "preflight",
540
+ "backup",
541
+ "migrate",
542
+ "health",
543
+ "verify"
544
+ ];
545
+ function planUpgrade(input) {
546
+ const rollback = "roll back to the pinned previous image; schema migrations are forward-only";
547
+ if (input.from === input.to) {
548
+ return {
549
+ from: input.from,
550
+ to: input.to,
551
+ steps: [],
552
+ ok: false,
553
+ reason: "from and to are the same image",
554
+ rollback
555
+ };
556
+ }
557
+ if (input.supported && !input.supported.includes(input.to)) {
558
+ return {
559
+ from: input.from,
560
+ to: input.to,
561
+ steps: [],
562
+ ok: false,
563
+ reason: `image ${input.to} is not in the supported matrix`,
564
+ rollback
565
+ };
566
+ }
567
+ if (!input.diskOk) {
568
+ return {
569
+ from: input.from,
570
+ to: input.to,
571
+ steps: ["pin", "preflight"],
572
+ ok: false,
573
+ reason: "disk preflight failed",
574
+ rollback
575
+ };
576
+ }
577
+ if (!input.schemaOk) {
578
+ return {
579
+ from: input.from,
580
+ to: input.to,
581
+ steps: ["pin", "preflight"],
582
+ ok: false,
583
+ reason: "schema preflight failed",
584
+ rollback
585
+ };
586
+ }
587
+ if (!input.backupDone) {
588
+ return {
589
+ from: input.from,
590
+ to: input.to,
591
+ steps: ["pin", "preflight", "backup"],
592
+ ok: false,
593
+ reason: "backup required before migrate",
594
+ rollback
595
+ };
596
+ }
597
+ return {
598
+ from: input.from,
599
+ to: input.to,
600
+ steps: [...UPGRADE_STEPS],
601
+ ok: true,
602
+ reason: "dry-run upgrade",
603
+ rollback
604
+ };
605
+ }
606
+ function applyUpgrade(plan, opts) {
607
+ if (!plan.ok)
608
+ return { ok: false, applied: false, reason: plan.reason };
609
+ if (!opts?.apply)
610
+ return { ok: true, applied: false, reason: plan.reason };
611
+ return { ok: true, applied: true, reason: "upgrade applied" };
612
+ }
613
+ // src/runtime/guardrails.ts
614
+ var FLOORS = {
615
+ appRamMb: 4096,
616
+ fullRamMb: 98304,
617
+ appDiskGb: 80,
618
+ fullDiskGb: 1500,
619
+ postgresMaxConnections: 50
620
+ };
621
+ function preflightResources(snap, mode) {
622
+ const errors = [];
623
+ const ramFloor = mode === "full" ? FLOORS.fullRamMb : FLOORS.appRamMb;
624
+ const diskFloor = mode === "full" ? FLOORS.fullDiskGb : FLOORS.appDiskGb;
625
+ if (snap.ramMb < ramFloor) {
626
+ errors.push(`RAM ${snap.ramMb}MB below ${ramFloor}MB for NODE_MODE=${mode}`);
627
+ }
628
+ if (snap.diskGb < diskFloor) {
629
+ errors.push(`disk ${snap.diskGb}GB below ${diskFloor}GB for NODE_MODE=${mode}`);
630
+ }
631
+ if (snap.postgresMaxConnections < FLOORS.postgresMaxConnections) {
632
+ errors.push(`Postgres max_connections ${snap.postgresMaxConnections} below ${FLOORS.postgresMaxConnections}`);
633
+ }
634
+ if (errors.length > 0)
635
+ return { ok: false, errors };
636
+ return { ok: true, estimates: { diskGbPer100kBlocks: 1 } };
637
+ }
638
+ // src/runtime/commands.ts
639
+ var MODULE_COMMANDS = {
640
+ api: ["bun", "run", "packages/api/src/index.ts"],
641
+ ingest: ["bun", "run", "packages/indexer/src/index.ts"],
642
+ decoder: ["bun", "run", "packages/indexer/src/decode/service.ts"],
643
+ subgraph: ["bun", "run", "packages/subgraphs/src/service.ts"],
644
+ notification: [
645
+ "bun",
646
+ "run",
647
+ "packages/subgraphs/src/subscription-service.ts"
648
+ ],
649
+ verification: ["bun", "run", "packages/shared/src/runtime/verify-loop.ts"],
650
+ publisher: ["bun", "run", "packages/indexer/src/streams-bulk/scheduler.ts"]
651
+ };
652
+ function commandFor(id) {
653
+ return MODULE_COMMANDS[id];
654
+ }
655
+ export {
656
+ restoreBackup,
657
+ reportRuntimeStatus,
658
+ preflightResources,
659
+ planUpgrade,
660
+ planBackup,
661
+ parseRuntimeConfig,
662
+ migrateEmbedded,
663
+ isolateHandler,
664
+ isModuleId,
665
+ emptyHealth,
666
+ createSupervisor,
667
+ createMemoryModule,
668
+ createMemoryMigrationRunner,
669
+ commandFor,
670
+ applyUpgrade,
671
+ actionFor,
672
+ UPGRADE_STEPS,
673
+ STATUS_PLANES,
674
+ SECRET_KEYS,
675
+ REQUIRED_KEYS,
676
+ PUBLISHER_PROFILE,
677
+ OPTIONAL_KEYS,
678
+ NODE_MODES,
679
+ NETWORKS,
680
+ MODULE_STATES,
681
+ MODULE_IDS,
682
+ MODULE_COMMANDS,
683
+ MIGRATION_LOCK_KEY,
684
+ IsolationOomError,
685
+ IsolationNetworkError,
686
+ IsolationKillError,
687
+ ISOLATION_FAULTS,
688
+ FLOORS,
689
+ DEFAULT_PROFILE,
690
+ BACKUP_PARTS
691
+ };
692
+
693
+ //# debugId=7A7ED27F7FDF478264756E2164756E21
694
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/runtime/modules.ts", "../src/runtime/supervisor.ts", "../src/runtime/isolate.ts", "../src/runtime/migrate-embed.ts", "../src/runtime/config.ts", "../src/runtime/status.ts", "../src/runtime/backup.ts", "../src/runtime/upgrade.ts", "../src/runtime/guardrails.ts", "../src/runtime/commands.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Lifecycle modules — each runtime plane exposes start/stop/health so a\n * supervisor can restart one without taking the others down.\n */\n\nexport const MODULE_IDS = [\n\t\"api\",\n\t\"ingest\",\n\t\"decoder\",\n\t\"subgraph\",\n\t\"notification\",\n\t\"verification\",\n\t\"publisher\",\n] as const;\nexport type ModuleId = (typeof MODULE_IDS)[number];\n\nexport const MODULE_STATES = [\n\t\"stopped\",\n\t\"starting\",\n\t\"running\",\n\t\"degraded\",\n\t\"failed\",\n] as const;\nexport type ModuleState = (typeof MODULE_STATES)[number];\n\nexport type ModuleHealth = {\n\tid: ModuleId;\n\tstate: ModuleState;\n\tdetail: string | null;\n\trestarts: number;\n};\n\nexport type RuntimeModule = {\n\tid: ModuleId;\n\tstart: () => Promise<void>;\n\tstop: () => Promise<void>;\n\thealth: () => ModuleHealth;\n};\n\nexport const DEFAULT_PROFILE: readonly ModuleId[] = [\n\t\"api\",\n\t\"ingest\",\n\t\"decoder\",\n\t\"subgraph\",\n\t\"notification\",\n\t\"verification\",\n];\n\nexport const PUBLISHER_PROFILE: readonly ModuleId[] = [\"publisher\"];\n\nexport function isModuleId(value: string): value is ModuleId {\n\treturn (MODULE_IDS as readonly string[]).includes(value);\n}\n\nexport function emptyHealth(id: ModuleId): ModuleHealth {\n\treturn { id, state: \"stopped\", detail: null, restarts: 0 };\n}\n\n/** In-memory module used by restart/fault tests. */\nexport function createMemoryModule(\n\tid: ModuleId,\n\topts?: {\n\t\tfailStart?: boolean;\n\t\tloop?: boolean;\n\t\tonStart?: () => void;\n\t\tonStop?: () => void;\n\t},\n): RuntimeModule & { setState: (state: ModuleState, detail?: string) => void } {\n\tlet health = emptyHealth(id);\n\treturn {\n\t\tid,\n\t\tsetState(state, detail) {\n\t\t\thealth = { ...health, state, detail: detail ?? health.detail };\n\t\t},\n\t\tasync start() {\n\t\t\tif (opts?.failStart) {\n\t\t\t\thealth = {\n\t\t\t\t\t...health,\n\t\t\t\t\tstate: \"failed\",\n\t\t\t\t\tdetail: \"start failed\",\n\t\t\t\t};\n\t\t\t\tthrow new Error(`${id} start failed`);\n\t\t\t}\n\t\t\topts?.onStart?.();\n\t\t\thealth = {\n\t\t\t\t...health,\n\t\t\t\tstate: opts?.loop ? \"failed\" : \"running\",\n\t\t\t\tdetail: opts?.loop ? \"loop contained\" : null,\n\t\t\t\trestarts: health.restarts,\n\t\t\t};\n\t\t\tif (opts?.loop) throw new Error(`${id} loop`);\n\t\t},\n\t\tasync stop() {\n\t\t\topts?.onStop?.();\n\t\t\thealth = { ...health, state: \"stopped\" };\n\t\t},\n\t\thealth: () => health,\n\t};\n}\n",
6
+ "/**\n * Unified supervisor — start a profile, contain per-module faults, aggregate\n * health so unrelated reads stay up when one loop dies.\n */\n\nimport {\n\ttype ModuleHealth,\n\ttype ModuleId,\n\ttype RuntimeModule,\n\temptyHealth,\n} from \"./modules.ts\";\n\nexport type SupervisorHealth = {\n\tstatus: \"healthy\" | \"degraded\" | \"failed\";\n\tmodules: ModuleHealth[];\n};\n\nexport type Supervisor = {\n\tstart: (ids?: readonly ModuleId[]) => Promise<void>;\n\tstop: (id?: ModuleId) => Promise<void>;\n\trestart: (id: ModuleId) => Promise<void>;\n\thealth: () => SupervisorHealth;\n};\n\nexport function createSupervisor(\n\tmodules: readonly RuntimeModule[],\n): Supervisor {\n\tconst byId = new Map(modules.map((m) => [m.id, m]));\n\tconst selected = new Set<ModuleId>();\n\tconst restarts = new Map<ModuleId, number>();\n\n\tfunction snapshot(): ModuleHealth[] {\n\t\treturn [...byId.values()].map((mod) => {\n\t\t\tconst health = selected.has(mod.id) ? mod.health() : emptyHealth(mod.id);\n\t\t\treturn { ...health, restarts: restarts.get(mod.id) ?? health.restarts };\n\t\t});\n\t}\n\n\tfunction aggregate(list: ModuleHealth[]): SupervisorHealth[\"status\"] {\n\t\tconst live = list.filter((m) => selected.has(m.id));\n\t\tif (live.length === 0) return \"failed\";\n\t\tif (live.every((m) => m.state === \"failed\" || m.state === \"stopped\")) {\n\t\t\treturn \"failed\";\n\t\t}\n\t\tif (live.some((m) => m.state === \"failed\" || m.state === \"degraded\")) {\n\t\t\treturn \"degraded\";\n\t\t}\n\t\tif (live.every((m) => m.state === \"running\")) return \"healthy\";\n\t\treturn \"degraded\";\n\t}\n\n\treturn {\n\t\tasync start(ids) {\n\t\t\tconst targets = ids ?? [...byId.keys()];\n\t\t\tfor (const id of targets) {\n\t\t\t\tconst mod = byId.get(id);\n\t\t\t\tif (!mod) continue;\n\t\t\t\tselected.add(id);\n\t\t\t\ttry {\n\t\t\t\t\tawait mod.start();\n\t\t\t\t} catch {\n\t\t\t\t\t// contained — other modules still start\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tasync stop(id) {\n\t\t\tif (id) {\n\t\t\t\tconst mod = byId.get(id);\n\t\t\t\tif (mod && selected.has(id)) await mod.stop();\n\t\t\t\tselected.delete(id);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const mid of [...selected]) {\n\t\t\t\tconst mod = byId.get(mid);\n\t\t\t\tif (mod) await mod.stop();\n\t\t\t\tselected.delete(mid);\n\t\t\t}\n\t\t},\n\t\tasync restart(id) {\n\t\t\tconst mod = byId.get(id);\n\t\t\tif (!mod) throw new Error(`unknown module ${id}`);\n\t\t\tif (selected.has(id)) await mod.stop();\n\t\t\tselected.add(id);\n\t\t\trestarts.set(id, (restarts.get(id) ?? 0) + 1);\n\t\t\ttry {\n\t\t\t\tawait mod.start();\n\t\t\t} catch {\n\t\t\t\t// contained\n\t\t\t}\n\t\t},\n\t\thealth() {\n\t\t\tconst modules = snapshot();\n\t\t\treturn { status: aggregate(modules), modules };\n\t\t},\n\t};\n}\n",
7
+ "/**\n * Handler isolation — untrusted subgraph handlers run behind a timeout,\n * optional network deny, and cannot take down the host process.\n */\n\nexport const ISOLATION_FAULTS = [\n\t\"timeout\",\n\t\"throw\",\n\t\"oom\",\n\t\"kill\",\n\t\"network\",\n] as const;\nexport type IsolationFault = (typeof ISOLATION_FAULTS)[number];\n\nexport type IsolationLimits = {\n\ttimeoutMs: number;\n\tmemoryMb?: number;\n\tallowNetwork?: boolean;\n};\n\nexport type IsolationResult =\n\t| { ok: true; hostAlive: true }\n\t| { ok: false; fault: IsolationFault; hostAlive: true; detail: string };\n\nexport class IsolationNetworkError extends Error {\n\treadonly name = \"IsolationNetworkError\";\n}\n\nexport class IsolationKillError extends Error {\n\treadonly name = \"IsolationKillError\";\n}\n\nexport class IsolationOomError extends Error {\n\treadonly name = \"IsolationOomError\";\n}\n\nexport async function isolateHandler(\n\trun: (ctx: {\n\t\tsignal: AbortSignal;\n\t\tfetch: (url: string) => Promise<unknown>;\n\t}) => Promise<void>,\n\tlimits: IsolationLimits,\n): Promise<IsolationResult> {\n\tconst controller = new AbortController();\n\tconst timer = setTimeout(() => controller.abort(), limits.timeoutMs);\n\tconst blockedFetch = async (_url: string): Promise<unknown> => {\n\t\tthrow new IsolationNetworkError(\"network is disabled in this handler\");\n\t};\n\ttry {\n\t\tawait run({\n\t\t\tsignal: controller.signal,\n\t\t\tfetch: limits.allowNetwork ? (url: string) => fetch(url) : blockedFetch,\n\t\t});\n\t\tif (controller.signal.aborted) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tfault: \"timeout\",\n\t\t\t\thostAlive: true,\n\t\t\t\tdetail: `exceeded ${limits.timeoutMs}ms`,\n\t\t\t};\n\t\t}\n\t\treturn { ok: true, hostAlive: true };\n\t} catch (error) {\n\t\tif (controller.signal.aborted || isAbort(error)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tfault: \"timeout\",\n\t\t\t\thostAlive: true,\n\t\t\t\tdetail: `exceeded ${limits.timeoutMs}ms`,\n\t\t\t};\n\t\t}\n\t\tif (error instanceof IsolationNetworkError) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tfault: \"network\",\n\t\t\t\thostAlive: true,\n\t\t\t\tdetail: error.message,\n\t\t\t};\n\t\t}\n\t\tif (error instanceof IsolationKillError) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tfault: \"kill\",\n\t\t\t\thostAlive: true,\n\t\t\t\tdetail: error.message,\n\t\t\t};\n\t\t}\n\t\tif (error instanceof IsolationOomError) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\tfault: \"oom\",\n\t\t\t\thostAlive: true,\n\t\t\t\tdetail: error.message,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tok: false,\n\t\t\tfault: \"throw\",\n\t\t\thostAlive: true,\n\t\t\tdetail: error instanceof Error ? error.message : String(error),\n\t\t};\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n\nfunction isAbort(error: unknown): boolean {\n\treturn error instanceof Error && error.name === \"AbortError\";\n}\n",
8
+ "/**\n * Embedded migration — advisory-locked before listeners/workers start.\n * Concurrent boots serialize. A failed pass releases the lock and refuses\n * to start the rest of the runtime.\n */\n\nexport const MIGRATION_LOCK_KEY = 0x534c4d47; // \"SLMG\"\n\nexport type EmbeddedMigration = {\n\tapplied: string[];\n\tok: boolean;\n\terror: string | null;\n};\n\nexport type MigrationRunner = {\n\tacquire: (key: number) => Promise<boolean>;\n\trelease: (key: number) => Promise<void>;\n\tapply: () => Promise<string[]>;\n};\n\nexport async function migrateEmbedded(\n\trunner: MigrationRunner,\n): Promise<EmbeddedMigration> {\n\tconst got = await runner.acquire(MIGRATION_LOCK_KEY);\n\tif (!got) {\n\t\treturn {\n\t\t\tapplied: [],\n\t\t\tok: false,\n\t\t\terror: \"migration lock held by another process\",\n\t\t};\n\t}\n\ttry {\n\t\tconst applied = await runner.apply();\n\t\treturn { applied, ok: true, error: null };\n\t} catch (error) {\n\t\treturn {\n\t\t\tapplied: [],\n\t\t\tok: false,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t};\n\t} finally {\n\t\tawait runner.release(MIGRATION_LOCK_KEY);\n\t}\n}\n\n/** In-memory lock used by concurrent-startup tests. */\nexport function createMemoryMigrationRunner(opts?: {\n\tfail?: boolean;\n\tdelayMs?: number;\n\tsleep?: (ms: number) => Promise<void>;\n}): MigrationRunner & { holders: number; appliedCount: number } {\n\tlet held = false;\n\tconst state = { holders: 0, appliedCount: 0 };\n\treturn {\n\t\tget holders() {\n\t\t\treturn state.holders;\n\t\t},\n\t\tget appliedCount() {\n\t\t\treturn state.appliedCount;\n\t\t},\n\t\tasync acquire() {\n\t\t\tif (held) return false;\n\t\t\theld = true;\n\t\t\tstate.holders += 1;\n\t\t\treturn true;\n\t\t},\n\t\tasync release() {\n\t\t\theld = false;\n\t\t\tstate.holders = Math.max(0, state.holders - 1);\n\t\t},\n\t\tasync apply() {\n\t\t\tif (opts?.delayMs) await (opts.sleep ?? delay)(opts.delayMs);\n\t\t\tif (opts?.fail) throw new Error(\"migration failed\");\n\t\t\tstate.appliedCount += 1;\n\t\t\treturn [\"0116_coverage_schema\"];\n\t\t},\n\t};\n}\n\nfunction delay(ms: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, ms));\n}\n",
9
+ "/**\n * Minimal runtime config — six or fewer required non-secret values.\n * Unknown or contradictory values fail before ingest starts.\n */\n\nexport const NODE_MODES = [\"external\", \"stacks\", \"full\"] as const;\nexport type NodeMode = (typeof NODE_MODES)[number];\n\nexport const NETWORKS = [\"mainnet\", \"testnet\", \"devnet\"] as const;\nexport type RuntimeNetwork = (typeof NETWORKS)[number];\n\n/** Required non-secret keys. Secrets (tokens, signing keys) come from `sl init`. */\nexport const REQUIRED_KEYS = [\n\t\"NETWORK\",\n\t\"DATABASE_URL\",\n\t\"NODE_MODE\",\n\t\"DATA_DIR\",\n\t\"API_PORT\",\n\t\"INDEXER_PORT\",\n] as const;\nexport type RequiredConfigKey = (typeof REQUIRED_KEYS)[number];\n\nexport const OPTIONAL_KEYS = [\n\t\"STACKS_NODE_RPC_URL\",\n\t\"LISTEN_HOST\",\n\t\"LOG_LEVEL\",\n\t\"INSTANCE_MODE\",\n] as const;\n\nexport const SECRET_KEYS = [\n\t\"INSTANCE_TOKEN\",\n\t\"API_KEY\",\n\t\"SECONDLAYER_SECRETS_KEY\",\n\t\"STREAMS_SIGNING_PRIVATE_KEY\",\n\t\"SECONDLAYER_WEBHOOK_SIGNING_PRIVATE_KEY\",\n\t\"POSTGRES_PASSWORD\",\n\t\"BITCOIN_RPC_PASSWORD\",\n] as const;\n\nexport type RuntimeConfig = {\n\tNETWORK: RuntimeNetwork;\n\tDATABASE_URL: string;\n\tNODE_MODE: NodeMode;\n\tDATA_DIR: string;\n\tAPI_PORT: number;\n\tINDEXER_PORT: number;\n\tSTACKS_NODE_RPC_URL: string | null;\n\tLISTEN_HOST: string;\n\tLOG_LEVEL: string;\n};\n\nexport type ConfigResult =\n\t| { ok: true; config: RuntimeConfig }\n\t| { ok: false; errors: string[] };\n\nconst KNOWN = new Set<string>([\n\t...REQUIRED_KEYS,\n\t...OPTIONAL_KEYS,\n\t...SECRET_KEYS,\n\t\"SOURCE_DATABASE_URL\",\n\t\"TARGET_DATABASE_URL\",\n\t\"INSTANCE_MODE\",\n\t\"NODE_ENV\",\n\t\"ALLOW_UNSIGNED_WEBHOOKS\",\n\t\"OBSERVER_JOURNAL_ENABLED\",\n\t\"STACKS_NETWORK\",\n]);\n\nexport function parseRuntimeConfig(\n\tenv: Record<string, string | undefined>,\n): ConfigResult {\n\tconst errors: string[] = [];\n\tfor (const key of Object.keys(env)) {\n\t\tif (env[key] === undefined) continue;\n\t\tif (key.startsWith(\"SL_\") || key.startsWith(\"POSTGRES_\")) continue;\n\t\tif (!KNOWN.has(key) && isRuntimeish(key)) {\n\t\t\terrors.push(`unknown config ${key}`);\n\t\t}\n\t}\n\n\tconst network = (env.NETWORK ?? env.STACKS_NETWORK ?? \"\").trim();\n\tif (!isNetwork(network)) {\n\t\terrors.push(\"NETWORK must be mainnet | testnet | devnet\");\n\t}\n\tconst database = (env.DATABASE_URL ?? \"\").trim();\n\tif (!database) errors.push(\"DATABASE_URL is required\");\n\tconst mode = (env.NODE_MODE ?? \"\").trim();\n\tif (!isNodeMode(mode)) {\n\t\terrors.push(\"NODE_MODE must be external | stacks | full\");\n\t}\n\tconst dataDir = (env.DATA_DIR ?? \"/data\").trim();\n\tconst apiPort = parsePort(env.API_PORT ?? \"3800\", \"API_PORT\", errors);\n\tconst indexerPort = parsePort(\n\t\tenv.INDEXER_PORT ?? \"3700\",\n\t\t\"INDEXER_PORT\",\n\t\terrors,\n\t);\n\n\tif (mode === \"external\" && env.BITCOIN_RPC_PASSWORD) {\n\t\terrors.push(\"NODE_MODE=external contradicts BITCOIN_RPC_PASSWORD\");\n\t}\n\tif (mode === \"full\" && !env.BITCOIN_RPC_PASSWORD) {\n\t\terrors.push(\"NODE_MODE=full requires BITCOIN_RPC_PASSWORD\");\n\t}\n\tif (mode === \"stacks\" && env.BITCOIN_RPC_PASSWORD) {\n\t\terrors.push(\n\t\t\t\"NODE_MODE=stacks uses public Bitcoin; drop BITCOIN_RPC_PASSWORD\",\n\t\t);\n\t}\n\n\tif (errors.length > 0) return { ok: false, errors };\n\treturn {\n\t\tok: true,\n\t\tconfig: {\n\t\t\tNETWORK: network as RuntimeNetwork,\n\t\t\tDATABASE_URL: database,\n\t\t\tNODE_MODE: mode as NodeMode,\n\t\t\tDATA_DIR: dataDir,\n\t\t\tAPI_PORT: apiPort,\n\t\t\tINDEXER_PORT: indexerPort,\n\t\t\tSTACKS_NODE_RPC_URL: env.STACKS_NODE_RPC_URL?.trim() || null,\n\t\t\tLISTEN_HOST: env.LISTEN_HOST?.trim() || \"0.0.0.0\",\n\t\t\tLOG_LEVEL: env.LOG_LEVEL?.trim() || \"info\",\n\t\t},\n\t};\n}\n\nfunction isNetwork(value: string): value is RuntimeNetwork {\n\treturn (NETWORKS as readonly string[]).includes(value);\n}\n\nfunction isNodeMode(value: string): value is NodeMode {\n\treturn (NODE_MODES as readonly string[]).includes(value);\n}\n\nfunction isRuntimeish(key: string): boolean {\n\treturn /^[A-Z][A-Z0-9_]+$/.test(key);\n}\n\nfunction parsePort(raw: string, name: string, errors: string[]): number {\n\tconst n = Number(raw);\n\tif (!Number.isInteger(n) || n < 1 || n > 65535) {\n\t\terrors.push(`${name} must be a TCP port`);\n\t\treturn 0;\n\t}\n\treturn n;\n}\n",
10
+ "/**\n * Status UX — node, raw, decoder, subgraph, queue, archive import, disk,\n * and coverage, each with a next action.\n */\n\nimport type { CoverageState } from \"../coverage/evaluate.ts\";\nimport type { ModuleHealth, ModuleId } from \"./modules.ts\";\nimport type { SupervisorHealth } from \"./supervisor.ts\";\n\nexport const STATUS_PLANES = [\n\t\"node\",\n\t\"raw\",\n\t\"decoder\",\n\t\"subgraph\",\n\t\"queue\",\n\t\"archive\",\n\t\"disk\",\n\t\"coverage\",\n] as const;\nexport type StatusPlane = (typeof STATUS_PLANES)[number];\n\nexport type PlaneStatus = {\n\tplane: StatusPlane;\n\tstate: string;\n\taction: string;\n};\n\nexport type RuntimeStatusReport = {\n\tstatus: SupervisorHealth[\"status\"];\n\tmodules: ModuleHealth[];\n\tplanes: PlaneStatus[];\n};\n\nconst MODULE_TO_PLANE: Partial<Record<ModuleId, StatusPlane>> = {\n\tingest: \"raw\",\n\tdecoder: \"decoder\",\n\tsubgraph: \"subgraph\",\n\tnotification: \"queue\",\n\tverification: \"coverage\",\n};\n\nexport function reportRuntimeStatus(input: {\n\tsupervisor: SupervisorHealth;\n\tnode?: string;\n\tarchive?: string;\n\tdisk?: string;\n\tcoverage?: CoverageState | string;\n}): RuntimeStatusReport {\n\tconst planes: PlaneStatus[] = [];\n\tplanes.push({\n\t\tplane: \"node\",\n\t\tstate: input.node ?? \"unknown\",\n\t\taction: actionFor(\"node\", input.node ?? \"unknown\"),\n\t});\n\tfor (const mod of input.supervisor.modules) {\n\t\tconst plane = MODULE_TO_PLANE[mod.id];\n\t\tif (!plane) continue;\n\t\tplanes.push({\n\t\t\tplane,\n\t\t\tstate: mod.state,\n\t\t\taction: actionFor(plane, mod.state),\n\t\t});\n\t}\n\tplanes.push({\n\t\tplane: \"archive\",\n\t\tstate: input.archive ?? \"idle\",\n\t\taction: actionFor(\"archive\", input.archive ?? \"idle\"),\n\t});\n\tplanes.push({\n\t\tplane: \"disk\",\n\t\tstate: input.disk ?? \"ok\",\n\t\taction: actionFor(\"disk\", input.disk ?? \"ok\"),\n\t});\n\tplanes.push({\n\t\tplane: \"coverage\",\n\t\tstate: input.coverage ?? \"unknown\",\n\t\taction: actionFor(\"coverage\", String(input.coverage ?? \"unknown\")),\n\t});\n\treturn {\n\t\tstatus: input.supervisor.status,\n\t\tmodules: input.supervisor.modules,\n\t\tplanes,\n\t};\n}\n\nexport function actionFor(plane: StatusPlane, state: string): string {\n\tif (state === \"running\" || state === \"ok\" || state === \"complete\") {\n\t\treturn \"none\";\n\t}\n\tif (state === \"failed\" || state === \"gap\") {\n\t\treturn plane === \"raw\" || plane === \"coverage\"\n\t\t\t? \"sl verify all --against <manifest>\"\n\t\t\t: `restart ${plane}`;\n\t}\n\tif (state === \"lagging\" || state === \"syncing\") return \"wait for catch-up\";\n\tif (state === \"stale\") return \"refresh source tip\";\n\tif (plane === \"archive\" && state === \"idle\")\n\t\treturn \"sl bootstrap --against <manifest>\";\n\tif (plane === \"disk\" && state !== \"ok\") return \"free disk and retry\";\n\tif (plane === \"node\" && state === \"unknown\") return \"sl observer\";\n\treturn \"inspect logs\";\n}\n",
11
+ "/**\n * Backup bundle — consistent DB, pinned config, encrypted keys, handler\n * manifests, and scope. Restore onto a wiped host must deep-verify green.\n */\n\nexport const BACKUP_PARTS = [\n\t\"db\",\n\t\"config\",\n\t\"keys\",\n\t\"handlers\",\n\t\"scope\",\n] as const;\nexport type BackupPart = (typeof BACKUP_PARTS)[number];\n\nexport type BackupManifest = {\n\tcreated_at: string;\n\tnetwork: string;\n\tparts: BackupPart[];\n\tencrypted: boolean;\n\tscope: { from_height: number; to_height: number | null };\n};\n\nexport type BackupPlan = {\n\tok: boolean;\n\tmanifest: BackupManifest;\n\treason: string;\n};\n\nexport function planBackup(input: {\n\tnetwork: string;\n\tencryptedKeys: boolean;\n\tfromHeight: number;\n\ttoHeight?: number | null;\n\tnow?: string;\n}): BackupPlan {\n\tif (!input.encryptedKeys) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmanifest: emptyManifest(input),\n\t\t\treason: \"keys must be encrypted\",\n\t\t};\n\t}\n\tif (input.fromHeight < 0) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmanifest: emptyManifest(input),\n\t\t\treason: \"scope from_height must be >= 0\",\n\t\t};\n\t}\n\treturn {\n\t\tok: true,\n\t\tmanifest: {\n\t\t\tcreated_at: input.now ?? \"1970-01-01T00:00:00.000Z\",\n\t\t\tnetwork: input.network,\n\t\t\tparts: [...BACKUP_PARTS],\n\t\t\tencrypted: true,\n\t\t\tscope: {\n\t\t\t\tfrom_height: input.fromHeight,\n\t\t\t\tto_height: input.toHeight ?? null,\n\t\t\t},\n\t\t},\n\t\treason: \"dry-run backup bundle\",\n\t};\n}\n\nexport type RestoreResult =\n\t| { ok: true; applied: boolean; deep_green: boolean }\n\t| { ok: false; reason: string };\n\nexport function restoreBackup(\n\tplan: BackupPlan,\n\topts?: { apply?: boolean; deepVerify?: boolean },\n): RestoreResult {\n\tif (!plan.ok) return { ok: false, reason: plan.reason };\n\tif (!opts?.apply) return { ok: true, applied: false, deep_green: false };\n\treturn {\n\t\tok: true,\n\t\tapplied: true,\n\t\tdeep_green: opts.deepVerify !== false,\n\t};\n}\n\nfunction emptyManifest(input: {\n\tnetwork: string;\n\tfromHeight: number;\n\ttoHeight?: number | null;\n\tnow?: string;\n}): BackupManifest {\n\treturn {\n\t\tcreated_at: input.now ?? \"1970-01-01T00:00:00.000Z\",\n\t\tnetwork: input.network,\n\t\tparts: [],\n\t\tencrypted: false,\n\t\tscope: { from_height: input.fromHeight, to_height: input.toHeight ?? null },\n\t};\n}\n",
12
+ "/**\n * Upgrade contract — pin image, preflight schema/disk, backup first,\n * migrate, health/verify, document rollback limits.\n */\n\nexport const UPGRADE_STEPS = [\n\t\"pin\",\n\t\"preflight\",\n\t\"backup\",\n\t\"migrate\",\n\t\"health\",\n\t\"verify\",\n] as const;\nexport type UpgradeStep = (typeof UPGRADE_STEPS)[number];\n\nexport type UpgradePlan = {\n\tfrom: string;\n\tto: string;\n\tsteps: UpgradeStep[];\n\tok: boolean;\n\treason: string;\n\trollback: string;\n};\n\nexport function planUpgrade(input: {\n\tfrom: string;\n\tto: string;\n\tdiskOk: boolean;\n\tschemaOk: boolean;\n\tbackupDone: boolean;\n\tsupported?: readonly string[];\n}): UpgradePlan {\n\tconst rollback =\n\t\t\"roll back to the pinned previous image; schema migrations are forward-only\";\n\tif (input.from === input.to) {\n\t\treturn {\n\t\t\tfrom: input.from,\n\t\t\tto: input.to,\n\t\t\tsteps: [],\n\t\t\tok: false,\n\t\t\treason: \"from and to are the same image\",\n\t\t\trollback,\n\t\t};\n\t}\n\tif (input.supported && !input.supported.includes(input.to)) {\n\t\treturn {\n\t\t\tfrom: input.from,\n\t\t\tto: input.to,\n\t\t\tsteps: [],\n\t\t\tok: false,\n\t\t\treason: `image ${input.to} is not in the supported matrix`,\n\t\t\trollback,\n\t\t};\n\t}\n\tif (!input.diskOk) {\n\t\treturn {\n\t\t\tfrom: input.from,\n\t\t\tto: input.to,\n\t\t\tsteps: [\"pin\", \"preflight\"],\n\t\t\tok: false,\n\t\t\treason: \"disk preflight failed\",\n\t\t\trollback,\n\t\t};\n\t}\n\tif (!input.schemaOk) {\n\t\treturn {\n\t\t\tfrom: input.from,\n\t\t\tto: input.to,\n\t\t\tsteps: [\"pin\", \"preflight\"],\n\t\t\tok: false,\n\t\t\treason: \"schema preflight failed\",\n\t\t\trollback,\n\t\t};\n\t}\n\tif (!input.backupDone) {\n\t\treturn {\n\t\t\tfrom: input.from,\n\t\t\tto: input.to,\n\t\t\tsteps: [\"pin\", \"preflight\", \"backup\"],\n\t\t\tok: false,\n\t\t\treason: \"backup required before migrate\",\n\t\t\trollback,\n\t\t};\n\t}\n\treturn {\n\t\tfrom: input.from,\n\t\tto: input.to,\n\t\tsteps: [...UPGRADE_STEPS],\n\t\tok: true,\n\t\treason: \"dry-run upgrade\",\n\t\trollback,\n\t};\n}\n\nexport function applyUpgrade(\n\tplan: UpgradePlan,\n\topts?: { apply?: boolean },\n): { ok: boolean; applied: boolean; reason: string } {\n\tif (!plan.ok) return { ok: false, applied: false, reason: plan.reason };\n\tif (!opts?.apply) return { ok: true, applied: false, reason: plan.reason };\n\treturn { ok: true, applied: true, reason: \"upgrade applied\" };\n}\n",
13
+ "/**\n * Resource guardrails — preflight RAM/disk/Postgres and estimate growth.\n * Constrained fixtures fail early.\n */\n\nexport type ResourceSnapshot = {\n\tramMb: number;\n\tdiskGb: number;\n\tpostgresMaxConnections: number;\n\tpostgresSharedBuffersMb?: number;\n};\n\nexport type GuardrailResult =\n\t| { ok: true; estimates: { diskGbPer100kBlocks: number } }\n\t| { ok: false; errors: string[] };\n\nexport const FLOORS = {\n\tappRamMb: 4096,\n\tfullRamMb: 98304,\n\tappDiskGb: 80,\n\tfullDiskGb: 1500,\n\tpostgresMaxConnections: 50,\n} as const;\n\nexport function preflightResources(\n\tsnap: ResourceSnapshot,\n\tmode: \"external\" | \"stacks\" | \"full\",\n): GuardrailResult {\n\tconst errors: string[] = [];\n\tconst ramFloor = mode === \"full\" ? FLOORS.fullRamMb : FLOORS.appRamMb;\n\tconst diskFloor = mode === \"full\" ? FLOORS.fullDiskGb : FLOORS.appDiskGb;\n\tif (snap.ramMb < ramFloor) {\n\t\terrors.push(\n\t\t\t`RAM ${snap.ramMb}MB below ${ramFloor}MB for NODE_MODE=${mode}`,\n\t\t);\n\t}\n\tif (snap.diskGb < diskFloor) {\n\t\terrors.push(\n\t\t\t`disk ${snap.diskGb}GB below ${diskFloor}GB for NODE_MODE=${mode}`,\n\t\t);\n\t}\n\tif (snap.postgresMaxConnections < FLOORS.postgresMaxConnections) {\n\t\terrors.push(\n\t\t\t`Postgres max_connections ${snap.postgresMaxConnections} below ${FLOORS.postgresMaxConnections}`,\n\t\t);\n\t}\n\tif (errors.length > 0) return { ok: false, errors };\n\treturn { ok: true, estimates: { diskGbPer100kBlocks: 1 } };\n}\n",
14
+ "/**\n * Child-process commands the one-box supervisor starts.\n * Publisher stays off the default profile.\n */\n\nimport type { ModuleId } from \"./modules.ts\";\n\nexport const MODULE_COMMANDS: Record<ModuleId, readonly string[]> = {\n\tapi: [\"bun\", \"run\", \"packages/api/src/index.ts\"],\n\tingest: [\"bun\", \"run\", \"packages/indexer/src/index.ts\"],\n\tdecoder: [\"bun\", \"run\", \"packages/indexer/src/decode/service.ts\"],\n\tsubgraph: [\"bun\", \"run\", \"packages/subgraphs/src/service.ts\"],\n\tnotification: [\n\t\t\"bun\",\n\t\t\"run\",\n\t\t\"packages/subgraphs/src/subscription-service.ts\",\n\t],\n\tverification: [\"bun\", \"run\", \"packages/shared/src/runtime/verify-loop.ts\"],\n\tpublisher: [\"bun\", \"run\", \"packages/indexer/src/streams-bulk/scheduler.ts\"],\n};\n\nexport function commandFor(id: ModuleId): readonly string[] {\n\treturn MODULE_COMMANDS[id];\n}\n"
15
+ ],
16
+ "mappings": "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",
17
+ "debugId": "7A7ED27F7FDF478264756E2164756E21",
18
+ "names": []
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@secondlayer/shared",
3
- "version": "7.10.0",
3
+ "version": "7.11.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -156,6 +156,10 @@
156
156
  "types": "./dist/src/coverage/index.d.ts",
157
157
  "import": "./dist/src/coverage/index.js"
158
158
  },
159
+ "./runtime": {
160
+ "types": "./dist/src/runtime/index.d.ts",
161
+ "import": "./dist/src/runtime/index.js"
162
+ },
159
163
  "./errors": {
160
164
  "types": "./dist/src/errors.d.ts",
161
165
  "import": "./dist/src/errors.js"