target-supabase-sdk 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -18
- package/dist/browser.d.ts +11 -4
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +3 -3
- package/dist/chunks/{enable-log-persist-BH-tbKEj.js → enable-log-persist-B8rg_wXG.js} +41 -8
- package/dist/chunks/enable-log-persist-B8rg_wXG.js.map +1 -0
- package/dist/chunks/{create-logger-DyH3mZ8p.js → list.api-Ab9v8yOg.js} +66 -57
- package/dist/chunks/list.api-Ab9v8yOg.js.map +1 -0
- package/dist/chunks/{word.interface-DLgRobKV.js → word.interface-B_fbVFOW.js} +1078 -97
- package/dist/chunks/word.interface-B_fbVFOW.js.map +1 -0
- package/dist/extraction/extraction.api.d.ts +117 -0
- package/dist/extraction/extraction.api.d.ts.map +1 -0
- package/dist/extraction/extraction.interface.d.ts +43 -0
- package/dist/extraction/extraction.interface.d.ts.map +1 -0
- package/dist/list/list.interface.d.ts +2 -2
- package/dist/list/list.interface.d.ts.map +1 -1
- package/dist/node/env/index.d.ts +2 -2
- package/dist/node/env/index.d.ts.map +1 -1
- package/dist/node/env/init-supabase-from-env.d.ts +1 -1
- package/dist/node/env/init-supabase-from-env.d.ts.map +1 -1
- package/dist/node/env/load-env.d.ts +15 -1
- package/dist/node/env/load-env.d.ts.map +1 -1
- package/dist/node/node-runtime.base.d.ts +13 -1
- package/dist/node/node-runtime.base.d.ts.map +1 -1
- package/dist/node/preload/run-service-preload.d.ts +1 -1
- package/dist/node/preload/run-service-preload.d.ts.map +1 -1
- package/dist/node/process/create-managed-child-processes.d.ts +12 -0
- package/dist/node/process/create-managed-child-processes.d.ts.map +1 -0
- package/dist/node/process/index.d.ts +3 -1
- package/dist/node/process/index.d.ts.map +1 -1
- package/dist/node/process/managed-child-processes.d.ts +15 -2
- package/dist/node/process/managed-child-processes.d.ts.map +1 -1
- package/dist/node/runtime-state/create-service-runtime-state-store.d.ts +23 -0
- package/dist/node/runtime-state/create-service-runtime-state-store.d.ts.map +1 -0
- package/dist/node/runtime-state/index.d.ts +4 -0
- package/dist/node/runtime-state/index.d.ts.map +1 -0
- package/dist/node/runtime-state/service-runtime-state.types.d.ts +57 -0
- package/dist/node/runtime-state/service-runtime-state.types.d.ts.map +1 -0
- package/dist/node/service-guard/index.d.ts +9 -0
- package/dist/node/service-guard/index.d.ts.map +1 -0
- package/dist/node/service-guard/register-service-guard-runner.d.ts +9 -0
- package/dist/node/service-guard/register-service-guard-runner.d.ts.map +1 -0
- package/dist/node/service-guard/run-readiness-gate.d.ts +11 -0
- package/dist/node/service-guard/run-readiness-gate.d.ts.map +1 -0
- package/dist/node/service-guard/run-service-guard-tick.d.ts +7 -0
- package/dist/node/service-guard/run-service-guard-tick.d.ts.map +1 -0
- package/dist/node/service-guard/service-guard-node.d.ts +18 -0
- package/dist/node/service-guard/service-guard-node.d.ts.map +1 -0
- package/dist/node/service-guard/service-guard.interface.d.ts +58 -0
- package/dist/node/service-guard/service-guard.interface.d.ts.map +1 -0
- package/dist/node/service-guard/worker-spawn-cooldown.d.ts +4 -0
- package/dist/node/service-guard/worker-spawn-cooldown.d.ts.map +1 -0
- package/dist/node/service-host/index.d.ts +9 -0
- package/dist/node/service-host/index.d.ts.map +1 -0
- package/dist/node/service-host/registry-slot-guard-step.d.ts +21 -0
- package/dist/node/service-host/registry-slot-guard-step.d.ts.map +1 -0
- package/dist/node/service-host/service-host.d.ts +36 -0
- package/dist/node/service-host/service-host.d.ts.map +1 -0
- package/dist/node/service-host/single-process-service.d.ts +21 -0
- package/dist/node/service-host/single-process-service.d.ts.map +1 -0
- package/dist/node.d.ts +17 -4
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +2088 -1495
- package/dist/node.js.map +1 -1
- package/dist/preload.js +5 -4
- package/dist/preload.js.map +1 -1
- package/dist/service/config.api.d.ts +143 -0
- package/dist/service/config.api.d.ts.map +1 -0
- package/dist/service/config.interface.d.ts +22 -0
- package/dist/service/config.interface.d.ts.map +1 -0
- package/dist/service/index.d.ts +16 -17
- package/dist/service/index.d.ts.map +1 -1
- package/dist/service/registry-lifecycle.d.ts +43 -0
- package/dist/service/registry-lifecycle.d.ts.map +1 -0
- package/dist/service/registry.service.d.ts +94 -0
- package/dist/service/registry.service.d.ts.map +1 -0
- package/dist/service/service-bootstrap.d.ts +28 -0
- package/dist/service/service-bootstrap.d.ts.map +1 -0
- package/dist/service/service.api.d.ts +160 -0
- package/dist/service/service.api.d.ts.map +1 -1
- package/dist/service/service.interface.d.ts +32 -1
- package/dist/service/service.interface.d.ts.map +1 -1
- package/dist/shared/log/index.d.ts +4 -0
- package/dist/shared/log/index.d.ts.map +1 -1
- package/dist/shared/log/log-batch.d.ts +44 -0
- package/dist/shared/log/log-batch.d.ts.map +1 -0
- package/dist/shared/log/log-persist-coordinator.d.ts +37 -0
- package/dist/shared/log/log-persist-coordinator.d.ts.map +1 -0
- package/dist/shared/log/log-persist-flush.d.ts.map +1 -1
- package/dist/shared/log/log-persist.config.d.ts +0 -1
- package/dist/shared/log/log-persist.config.d.ts.map +1 -1
- package/dist/shared/log/log-persist.interface.d.ts +8 -0
- package/dist/shared/log/log-persist.interface.d.ts.map +1 -1
- package/dist/shared/utils/config-path.utils.d.ts +21 -0
- package/dist/shared/utils/config-path.utils.d.ts.map +1 -1
- package/dist/shared/utils/get-value-at-path.d.ts +3 -0
- package/dist/shared/utils/get-value-at-path.d.ts.map +1 -0
- package/dist/task/index.d.ts +2 -0
- package/dist/task/index.d.ts.map +1 -1
- package/dist/task/task-manager.d.ts +1 -1
- package/dist/task/task-manager.d.ts.map +1 -1
- package/dist/task/task-post-retry.api.d.ts +24 -0
- package/dist/task/task-post-retry.api.d.ts.map +1 -0
- package/dist/task/task-repo-context.d.ts +7 -1
- package/dist/task/task-repo-context.d.ts.map +1 -1
- package/dist/trigger/trigger-manager.d.ts +1 -1
- package/dist/trigger/trigger-manager.d.ts.map +1 -1
- package/dist/trigger/trigger-node.d.ts +1 -0
- package/dist/trigger/trigger-node.d.ts.map +1 -1
- package/dist/trigger/trigger.constant.d.ts +1 -1
- package/dist/trigger/trigger.constant.d.ts.map +1 -1
- package/dist/trigger/trigger.interface.d.ts +10 -0
- package/dist/trigger/trigger.interface.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/browser.ts +98 -4
- package/src/extraction/extraction.api.ts +232 -0
- package/src/extraction/extraction.interface.ts +45 -0
- package/src/list/list.interface.ts +2 -2
- package/src/node/env/index.ts +13 -2
- package/src/node/env/init-supabase-from-env.ts +1 -1
- package/src/node/env/load-env.ts +48 -2
- package/src/node/node-runtime.base.ts +37 -6
- package/src/node/preload/run-service-preload.ts +3 -2
- package/src/node/process/create-managed-child-processes.ts +27 -0
- package/src/node/process/index.ts +4 -0
- package/src/node/process/managed-child-processes.ts +48 -15
- package/src/node/runtime-state/create-service-runtime-state-store.ts +125 -0
- package/src/node/runtime-state/index.ts +17 -0
- package/src/node/runtime-state/service-runtime-state.types.ts +64 -0
- package/src/node/service-guard/index.ts +17 -0
- package/src/node/service-guard/register-service-guard-runner.ts +64 -0
- package/src/node/service-guard/run-readiness-gate.ts +34 -0
- package/src/node/service-guard/run-service-guard-tick.ts +106 -0
- package/src/node/service-guard/service-guard-node.ts +52 -0
- package/src/node/service-guard/service-guard.interface.ts +64 -0
- package/src/node/service-guard/worker-spawn-cooldown.ts +13 -0
- package/src/node/service-host/index.ts +30 -0
- package/src/node/service-host/registry-slot-guard-step.ts +57 -0
- package/src/node/service-host/service-host.ts +168 -0
- package/src/node/service-host/single-process-service.ts +58 -0
- package/src/node.ts +76 -0
- package/src/service/config.api.ts +224 -0
- package/src/service/config.interface.ts +25 -0
- package/src/service/index.ts +74 -149
- package/src/service/registry-lifecycle.ts +144 -0
- package/src/service/registry.service.ts +564 -0
- package/src/service/service-bootstrap.ts +74 -0
- package/src/service/service.api.ts +13 -0
- package/src/service/service.interface.ts +36 -1
- package/src/shared/log/index.ts +13 -0
- package/src/shared/log/log-batch.ts +156 -0
- package/src/shared/log/log-persist-coordinator.ts +107 -0
- package/src/shared/log/log-persist-flush.ts +3 -3
- package/src/shared/log/log-persist.config.ts +0 -2
- package/src/shared/log/log-persist.interface.ts +10 -0
- package/src/shared/utils/config-path.utils.ts +35 -0
- package/src/shared/utils/get-value-at-path.ts +17 -0
- package/src/task/index.ts +2 -0
- package/src/task/task-manager.ts +10 -4
- package/src/task/task-post-retry.api.ts +61 -0
- package/src/task/task-repo-context.ts +8 -1
- package/src/trigger/trigger-manager.ts +4 -2
- package/src/trigger/trigger-node.ts +10 -4
- package/src/trigger/trigger.constant.ts +1 -1
- package/src/trigger/trigger.interface.ts +10 -0
- package/dist/chunks/create-logger-DyH3mZ8p.js.map +0 -1
- package/dist/chunks/enable-log-persist-BH-tbKEj.js.map +0 -1
- package/dist/chunks/word.interface-DLgRobKV.js.map +0 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { CategoryNode, evaluateBusyNodeLiveness, type Node, patchServiceRuntime, scanTargetList } from "../../browser";
|
|
2
|
+
import { applyRegistrySlotGuardStep } from "../service-host/registry-slot-guard-step";
|
|
3
|
+
import type { ServiceGuardTickInput, ServiceGuardTickResult } from "./service-guard.interface";
|
|
4
|
+
import { getWorkerSpawnCooldownLastAt, markWorkerSpawned } from "./worker-spawn-cooldown";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* One guard-runner tick: registry slot check, TaskNode liveness, optional worker
|
|
8
|
+
* respawn, Service runtime heartbeat rollup.
|
|
9
|
+
*/
|
|
10
|
+
export async function runServiceGuardTick(input: ServiceGuardTickInput): Promise<ServiceGuardTickResult> {
|
|
11
|
+
const {
|
|
12
|
+
serviceValue,
|
|
13
|
+
serviceId,
|
|
14
|
+
nodeId,
|
|
15
|
+
loopTraceId,
|
|
16
|
+
logger,
|
|
17
|
+
logTopic = "guard",
|
|
18
|
+
checkedAt,
|
|
19
|
+
nowMs,
|
|
20
|
+
taskNodeStaleMs,
|
|
21
|
+
workerSpawnCooldownMs,
|
|
22
|
+
maxNodes = 200,
|
|
23
|
+
spawnWorker,
|
|
24
|
+
getLastWorkerSpawnAt = getWorkerSpawnCooldownLastAt,
|
|
25
|
+
markWorkerSpawned: markWorkerSpawnedAt = markWorkerSpawned,
|
|
26
|
+
} = input;
|
|
27
|
+
|
|
28
|
+
const continueTick = true;
|
|
29
|
+
let registryPatch: ServiceGuardTickResult["registryPatch"];
|
|
30
|
+
let decision = "idle";
|
|
31
|
+
|
|
32
|
+
if (serviceId != null) {
|
|
33
|
+
const guard = await applyRegistrySlotGuardStep({
|
|
34
|
+
serviceValue,
|
|
35
|
+
serviceId,
|
|
36
|
+
checkedAt,
|
|
37
|
+
logger,
|
|
38
|
+
logTopic,
|
|
39
|
+
traceId: loopTraceId,
|
|
40
|
+
});
|
|
41
|
+
registryPatch = guard.registryPatch;
|
|
42
|
+
if (!guard.continueTick) {
|
|
43
|
+
return { continueTick: false, decision: "slot_lost", nodes: [], registryPatch };
|
|
44
|
+
}
|
|
45
|
+
decision = "slot_ok";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { data: nodes = [] } = await scanTargetList<Node>({
|
|
49
|
+
category: CategoryNode.NODE,
|
|
50
|
+
maxRows: maxNodes,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const liveness = evaluateBusyNodeLiveness(nodes, {
|
|
54
|
+
staleMs: taskNodeStaleMs,
|
|
55
|
+
now: nowMs,
|
|
56
|
+
excludeNodeId: nodeId,
|
|
57
|
+
onlyFreshCandidates: true,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const ageMs = liveness.freshest?.ageMs ?? Number.POSITIVE_INFINITY;
|
|
61
|
+
|
|
62
|
+
if (liveness.healthy) {
|
|
63
|
+
decision = "healthy";
|
|
64
|
+
} else if (nowMs - getLastWorkerSpawnAt() < workerSpawnCooldownMs) {
|
|
65
|
+
decision = "spawn_cooldown";
|
|
66
|
+
logger.warn("TaskNode unavailable but spawn cooldown active", {
|
|
67
|
+
topic: logTopic,
|
|
68
|
+
data: {
|
|
69
|
+
traceId: loopTraceId,
|
|
70
|
+
ageMs,
|
|
71
|
+
staleMs: taskNodeStaleMs,
|
|
72
|
+
cooldownMs: workerSpawnCooldownMs,
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
} else {
|
|
76
|
+
decision = "spawn_worker";
|
|
77
|
+
logger.warn("TaskNode stale — restarting worker", {
|
|
78
|
+
topic: logTopic,
|
|
79
|
+
data: {
|
|
80
|
+
traceId: loopTraceId,
|
|
81
|
+
peerWorkerCount: liveness.busyWorkerCount,
|
|
82
|
+
freshPeerCount: liveness.freshWorkerCount,
|
|
83
|
+
staleMs: taskNodeStaleMs,
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
await spawnWorker("guard:restart-unhealthy-tasknode");
|
|
87
|
+
markWorkerSpawnedAt(nowMs);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
await patchServiceRuntime({
|
|
92
|
+
serviceValue,
|
|
93
|
+
serviceId: serviceId ?? undefined,
|
|
94
|
+
nodes,
|
|
95
|
+
lastHeartBeat: nowMs,
|
|
96
|
+
});
|
|
97
|
+
} catch (error) {
|
|
98
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
99
|
+
logger.warn("Failed to patch Service runtime rollup", {
|
|
100
|
+
topic: logTopic,
|
|
101
|
+
data: { traceId: loopTraceId, message },
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return { continueTick, decision, nodes, registryPatch };
|
|
106
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { LoggerWithScope } from "../../shared/log";
|
|
2
|
+
import { TriggerNode } from "../../trigger/trigger-node";
|
|
3
|
+
import { registerServiceGuardRunner } from "./register-service-guard-runner";
|
|
4
|
+
import { runReadinessGate } from "./run-readiness-gate";
|
|
5
|
+
import type { ServiceGuardNodeOptions } from "./service-guard.interface";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* L3 guard process TriggerNode: readiness gate, TaskNode worker spawn owner,
|
|
9
|
+
* and {@link registerServiceGuardRunner} tick (registry slot + liveness + runtime).
|
|
10
|
+
*
|
|
11
|
+
* Use {@link ServiceGuardNode.create} so the guard runner is registered before `start()`.
|
|
12
|
+
*/
|
|
13
|
+
class ServiceGuardNode extends TriggerNode {
|
|
14
|
+
private readonly options: ServiceGuardNodeOptions;
|
|
15
|
+
|
|
16
|
+
private constructor(options: ServiceGuardNodeOptions) {
|
|
17
|
+
super({
|
|
18
|
+
requireRunners: true,
|
|
19
|
+
beforeProcessExit: options.beforeProcessExit,
|
|
20
|
+
});
|
|
21
|
+
this.options = options;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Register the guard runner and return a ready-to-start node. */
|
|
25
|
+
static create(options: ServiceGuardNodeOptions): ServiceGuardNode {
|
|
26
|
+
registerServiceGuardRunner({
|
|
27
|
+
serviceValue: options.serviceValue,
|
|
28
|
+
logTopic: options.logTopic,
|
|
29
|
+
...options.guardRunner,
|
|
30
|
+
});
|
|
31
|
+
return new ServiceGuardNode(options);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected async onBeforeRegisterNode(nodeLogger: LoggerWithScope): Promise<void> {
|
|
35
|
+
await runReadinessGate({
|
|
36
|
+
checks: this.options.readinessChecks,
|
|
37
|
+
onReport: this.options.onReadinessReport,
|
|
38
|
+
logger: nodeLogger,
|
|
39
|
+
logTopic: this.options.logTopic,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await super.onBeforeRegisterNode(nodeLogger);
|
|
43
|
+
|
|
44
|
+
nodeLogger.info("Spawning TaskNode worker (single spawn owner)", {
|
|
45
|
+
topic: this.options.logTopic ?? "guard",
|
|
46
|
+
});
|
|
47
|
+
await this.options.spawnWorker("guard:readiness-passed");
|
|
48
|
+
this.options.onWorkerSpawned?.();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { ServiceGuardNode };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Node } from "../../node/node.interface";
|
|
2
|
+
import type { RegistrySlotRuntimeState } from "../../service/registry-lifecycle";
|
|
3
|
+
import type { LoggerWithScope } from "../../shared/log";
|
|
4
|
+
import type { TriggerNodeOptions } from "../../trigger/trigger.interface";
|
|
5
|
+
import type { ReadinessCheck, ReadinessReport } from "../readiness/readiness.types";
|
|
6
|
+
|
|
7
|
+
/** Default TriggerManager runner key for {@link registerServiceGuardRunner}. */
|
|
8
|
+
export const SERVICE_GUARD_RUNNER_KEY = "service-guard";
|
|
9
|
+
|
|
10
|
+
export interface ServiceGuardTickInput {
|
|
11
|
+
serviceValue: string;
|
|
12
|
+
serviceId: string | null;
|
|
13
|
+
nodeId: string;
|
|
14
|
+
loopTraceId: string;
|
|
15
|
+
logger: LoggerWithScope;
|
|
16
|
+
logTopic?: string;
|
|
17
|
+
checkedAt: string;
|
|
18
|
+
nowMs: number;
|
|
19
|
+
taskNodeStaleMs: number;
|
|
20
|
+
workerSpawnCooldownMs: number;
|
|
21
|
+
maxNodes?: number;
|
|
22
|
+
spawnWorker: (reason: string) => Promise<void>;
|
|
23
|
+
getLastWorkerSpawnAt?: () => number;
|
|
24
|
+
markWorkerSpawned?: (at: number) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ServiceGuardTickResult {
|
|
28
|
+
continueTick: boolean;
|
|
29
|
+
decision: string;
|
|
30
|
+
nodes: Node[];
|
|
31
|
+
registryPatch?: Pick<RegistrySlotRuntimeState, "slotOwned" | "lastSlotCheckAt" | "lastSlotCheckError">;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface RegisterServiceGuardRunnerOptions {
|
|
35
|
+
serviceValue: string;
|
|
36
|
+
getServiceId: () => Promise<string | null>;
|
|
37
|
+
logTopic?: string;
|
|
38
|
+
runnerKey?: string;
|
|
39
|
+
intervalMs: number;
|
|
40
|
+
initialDelayMs?: number;
|
|
41
|
+
taskNodeStaleMs: number;
|
|
42
|
+
workerSpawnCooldownMs: number;
|
|
43
|
+
maxNodes?: number;
|
|
44
|
+
spawnWorker: (reason: string) => Promise<void>;
|
|
45
|
+
onRegistryPatch: (
|
|
46
|
+
patch: Pick<RegistrySlotRuntimeState, "slotOwned" | "lastSlotCheckAt" | "lastSlotCheckError">,
|
|
47
|
+
) => Promise<void>;
|
|
48
|
+
onGuardPatch: (patch: { nodeId: string; lastCheckAt: string; lastDecision?: string }) => Promise<void>;
|
|
49
|
+
onDecision?: (decision: string) => Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ServiceGuardNodeOptions extends TriggerNodeOptions {
|
|
53
|
+
serviceValue: string;
|
|
54
|
+
logTopic?: string;
|
|
55
|
+
readinessChecks: ReadinessCheck[];
|
|
56
|
+
onReadinessReport: (report: ReadinessReport) => Promise<void>;
|
|
57
|
+
guardRunner: Omit<
|
|
58
|
+
RegisterServiceGuardRunnerOptions,
|
|
59
|
+
"serviceValue" | "logTopic" | "runnerKey" | "intervalMs" | "initialDelayMs"
|
|
60
|
+
> &
|
|
61
|
+
Pick<RegisterServiceGuardRunnerOptions, "intervalMs" | "initialDelayMs">;
|
|
62
|
+
spawnWorker: (reason: string) => Promise<void>;
|
|
63
|
+
onWorkerSpawned?: () => void;
|
|
64
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
let lastWorkerSpawnAt = 0;
|
|
2
|
+
|
|
3
|
+
export function getWorkerSpawnCooldownLastAt(): number {
|
|
4
|
+
return lastWorkerSpawnAt;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function markWorkerSpawned(at = Date.now()): void {
|
|
8
|
+
lastWorkerSpawnAt = at;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function resetWorkerSpawnCooldownForTests(): void {
|
|
12
|
+
lastWorkerSpawnAt = 0;
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
RegisterServiceGuardRunnerOptions,
|
|
3
|
+
RunReadinessGateInput,
|
|
4
|
+
ServiceGuardNodeOptions,
|
|
5
|
+
ServiceGuardTickInput,
|
|
6
|
+
ServiceGuardTickResult,
|
|
7
|
+
} from "../service-guard";
|
|
8
|
+
export {
|
|
9
|
+
getWorkerSpawnCooldownLastAt,
|
|
10
|
+
markWorkerSpawned,
|
|
11
|
+
registerServiceGuardRunner,
|
|
12
|
+
runReadinessGate,
|
|
13
|
+
runServiceGuardTick,
|
|
14
|
+
SERVICE_GUARD_RUNNER_KEY,
|
|
15
|
+
ServiceGuardNode,
|
|
16
|
+
} from "../service-guard";
|
|
17
|
+
export type {
|
|
18
|
+
ApplyRegistrySlotGuardInput,
|
|
19
|
+
ApplyRegistrySlotGuardResult,
|
|
20
|
+
} from "./registry-slot-guard-step";
|
|
21
|
+
export { applyRegistrySlotGuardStep } from "./registry-slot-guard-step";
|
|
22
|
+
export type {
|
|
23
|
+
ServiceHost,
|
|
24
|
+
ServiceHostClosable,
|
|
25
|
+
ServiceHostContext,
|
|
26
|
+
ServiceHostOptions,
|
|
27
|
+
} from "./service-host";
|
|
28
|
+
export { createServiceHost } from "./service-host";
|
|
29
|
+
export type { SingleProcessServiceContext, SingleProcessServiceOptions } from "./single-process-service";
|
|
30
|
+
export { runSingleProcessService } from "./single-process-service";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { registrySlotRuntimePatchFromGuardResult, runRegistrySlotGuardCheck } from "../../service/registry-lifecycle";
|
|
2
|
+
import type { LoggerWithScope } from "../../shared/log";
|
|
3
|
+
|
|
4
|
+
export interface ApplyRegistrySlotGuardInput {
|
|
5
|
+
serviceValue: string;
|
|
6
|
+
serviceId: string;
|
|
7
|
+
checkedAt: string;
|
|
8
|
+
logger: Pick<LoggerWithScope, "critical" | "warn">;
|
|
9
|
+
logTopic?: string;
|
|
10
|
+
traceId?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface ApplyRegistrySlotGuardResult {
|
|
14
|
+
/** When false, caller should abort the supervisor tick (slot lost shutdown initiated). */
|
|
15
|
+
continueTick: boolean;
|
|
16
|
+
registryPatch: ReturnType<typeof registrySlotRuntimePatchFromGuardResult>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Run registry slot ownership check and optionally SIGTERM the parent main process.
|
|
21
|
+
* Used by guard / supervisor TriggerNode runners across L3 services.
|
|
22
|
+
*/
|
|
23
|
+
export async function applyRegistrySlotGuardStep(
|
|
24
|
+
input: ApplyRegistrySlotGuardInput,
|
|
25
|
+
): Promise<ApplyRegistrySlotGuardResult> {
|
|
26
|
+
const result = await runRegistrySlotGuardCheck({
|
|
27
|
+
serviceValue: input.serviceValue,
|
|
28
|
+
serviceId: input.serviceId,
|
|
29
|
+
});
|
|
30
|
+
const registryPatch = registrySlotRuntimePatchFromGuardResult(result, input.checkedAt);
|
|
31
|
+
|
|
32
|
+
if (result.shouldShutdown) {
|
|
33
|
+
input.logger.critical("Registry slot lost — shutting down service", {
|
|
34
|
+
topic: input.logTopic ?? "guard",
|
|
35
|
+
data: {
|
|
36
|
+
traceId: input.traceId,
|
|
37
|
+
serviceId: input.serviceId,
|
|
38
|
+
serviceValue: input.serviceValue,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
process.kill(process.ppid, "SIGTERM");
|
|
42
|
+
return { continueTick: false, registryPatch };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (result.error != null) {
|
|
46
|
+
input.logger.warn("Registry slot check failed (transient) — skipping enforcement this tick", {
|
|
47
|
+
topic: input.logTopic ?? "guard",
|
|
48
|
+
data: {
|
|
49
|
+
traceId: input.traceId,
|
|
50
|
+
serviceId: input.serviceId,
|
|
51
|
+
message: result.error,
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return { continueTick: true, registryPatch };
|
|
57
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { createLogger, type Service, ServiceRegistryError } from "../../browser";
|
|
2
|
+
import { claimServiceRegistrySlot, type ServiceRegistrySession } from "../../service/registry-lifecycle";
|
|
3
|
+
import type { LoggerWithScope } from "../../shared/log";
|
|
4
|
+
import type { ManagedChildProcesses } from "../process/managed-child-processes";
|
|
5
|
+
|
|
6
|
+
export interface ServiceHostClosable {
|
|
7
|
+
close: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ServiceHostContext {
|
|
11
|
+
service: Service;
|
|
12
|
+
session: ServiceRegistrySession;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface ServiceHostOptions {
|
|
16
|
+
serviceValue: string;
|
|
17
|
+
logger?: LoggerWithScope;
|
|
18
|
+
logTopic?: string;
|
|
19
|
+
childProcesses?: ManagedChildProcesses;
|
|
20
|
+
/** Labels that trigger host shutdown when the child exits unexpectedly. */
|
|
21
|
+
criticalSupervisors?: readonly string[];
|
|
22
|
+
|
|
23
|
+
prepare?: () => Promise<void>;
|
|
24
|
+
createInstance: () => Promise<Service | { service: Service; baseUrl?: string }>;
|
|
25
|
+
onRegistryClaimed?: (ctx: ServiceHostContext) => Promise<void>;
|
|
26
|
+
startSupervisors?: () => void | Promise<void>;
|
|
27
|
+
waitUntilReady?: () => Promise<void>;
|
|
28
|
+
startServer?: () => Promise<ServiceHostClosable>;
|
|
29
|
+
/** Stop child processes and other local resources (not registry release). */
|
|
30
|
+
onShutdown?: (signal: string) => Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const DEFAULT_CRITICAL_SUPERVISORS = ["guard", "supervisor"] as const;
|
|
34
|
+
|
|
35
|
+
export interface ServiceHost {
|
|
36
|
+
run: () => Promise<void>;
|
|
37
|
+
requestShutdown: (signal: string, exitCode?: number) => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function unwrapService(created: Service | { service: Service; baseUrl?: string }): Service {
|
|
41
|
+
return typeof created === "object" && created != null && "service" in created ? created.service : created;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function createServiceHost(options: ServiceHostOptions): ServiceHost {
|
|
45
|
+
const logger = options.logger ?? createLogger({ module: "service-host" });
|
|
46
|
+
const logTopic = options.logTopic ?? "startup";
|
|
47
|
+
const criticalSupervisors = options.criticalSupervisors ?? DEFAULT_CRITICAL_SUPERVISORS;
|
|
48
|
+
|
|
49
|
+
let session: ServiceRegistrySession | null = null;
|
|
50
|
+
let httpServer: ServiceHostClosable | null = null;
|
|
51
|
+
let shuttingDown = false;
|
|
52
|
+
|
|
53
|
+
async function shutdown(signal: string, exitCode = 0): Promise<void> {
|
|
54
|
+
if (shuttingDown) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
shuttingDown = true;
|
|
58
|
+
|
|
59
|
+
logger.info("shutting down", { topic: logTopic, data: { signal, exitCode } });
|
|
60
|
+
|
|
61
|
+
if (httpServer != null) {
|
|
62
|
+
await httpServer.close().catch(() => undefined);
|
|
63
|
+
httpServer = null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (options.onShutdown != null) {
|
|
67
|
+
await options.onShutdown(signal).catch(() => undefined);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (session != null) {
|
|
71
|
+
await session.release();
|
|
72
|
+
session = null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
process.exit(exitCode);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function requestShutdown(signal: string, exitCode = 0): void {
|
|
79
|
+
void shutdown(signal, exitCode);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function installProcessHandlers(): void {
|
|
83
|
+
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
84
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
85
|
+
|
|
86
|
+
options.childProcesses?.setCriticalExitHandler({
|
|
87
|
+
labels: criticalSupervisors,
|
|
88
|
+
onCriticalExit: (label, code, signal) => {
|
|
89
|
+
if (shuttingDown) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
logger.critical("Critical supervisor exited — shutting down service", {
|
|
93
|
+
topic: logTopic,
|
|
94
|
+
data: { label, code, signal },
|
|
95
|
+
});
|
|
96
|
+
void shutdown("supervisor-exit", 1);
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function run(): Promise<void> {
|
|
102
|
+
installProcessHandlers();
|
|
103
|
+
|
|
104
|
+
if (options.prepare != null) {
|
|
105
|
+
await options.prepare();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
session = await claimServiceRegistrySlot({
|
|
110
|
+
serviceValue: options.serviceValue,
|
|
111
|
+
createInstance: async () => unwrapService(await options.createInstance()),
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
if (error instanceof ServiceRegistryError && error.code === "SERVICE_SLOTS_FULL") {
|
|
115
|
+
logger.critical("No EMPTY registry slot — refusing to start", {
|
|
116
|
+
topic: logTopic,
|
|
117
|
+
data: { serviceValue: options.serviceValue, code: error.code },
|
|
118
|
+
});
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (options.onRegistryClaimed != null) {
|
|
125
|
+
await options.onRegistryClaimed({ service: session.service, session });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (options.startSupervisors != null) {
|
|
129
|
+
await options.startSupervisors();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (options.waitUntilReady != null) {
|
|
133
|
+
await options.waitUntilReady();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (options.startServer != null) {
|
|
137
|
+
httpServer = await options.startServer();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function runWithFatalHandling(): Promise<void> {
|
|
142
|
+
try {
|
|
143
|
+
await run();
|
|
144
|
+
} catch (error: unknown) {
|
|
145
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
146
|
+
const code = error instanceof ServiceRegistryError ? error.code : undefined;
|
|
147
|
+
logger.error("fatal", { topic: logTopic, data: { message, code } });
|
|
148
|
+
|
|
149
|
+
if (httpServer != null) {
|
|
150
|
+
await httpServer.close().catch(() => undefined);
|
|
151
|
+
httpServer = null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (options.onShutdown != null) {
|
|
155
|
+
await options.onShutdown("fatal").catch(() => undefined);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (session != null) {
|
|
159
|
+
await session.release().catch(() => undefined);
|
|
160
|
+
session = null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return { run: runWithFatalHandling, requestShutdown };
|
|
168
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createLogger, type Service, ServiceRegistryError } from "../../browser";
|
|
2
|
+
import { claimServiceRegistrySlot, type ServiceRegistrySession } from "../../service/registry-lifecycle";
|
|
3
|
+
import type { LoggerWithScope } from "../../shared/log";
|
|
4
|
+
|
|
5
|
+
export interface SingleProcessServiceContext {
|
|
6
|
+
service: Service;
|
|
7
|
+
session: ServiceRegistrySession;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface SingleProcessServiceOptions {
|
|
11
|
+
serviceValue: string;
|
|
12
|
+
logger?: LoggerWithScope;
|
|
13
|
+
logTopic?: string;
|
|
14
|
+
|
|
15
|
+
prepare?: () => Promise<void>;
|
|
16
|
+
createInstance: () => Promise<Service>;
|
|
17
|
+
run: (ctx: SingleProcessServiceContext) => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Single-process L3 entry (e.g. log-service): claim registry slot then run the service body.
|
|
22
|
+
* Registry release is the caller's responsibility inside `run` (e.g. TriggerNode `beforeProcessExit`).
|
|
23
|
+
*/
|
|
24
|
+
export async function runSingleProcessService(options: SingleProcessServiceOptions): Promise<void> {
|
|
25
|
+
const logger = options.logger ?? createLogger({ module: "single-process-service" });
|
|
26
|
+
const logTopic = options.logTopic ?? "startup";
|
|
27
|
+
|
|
28
|
+
if (options.prepare != null) {
|
|
29
|
+
await options.prepare();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let session: ServiceRegistrySession | null = null;
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
session = await claimServiceRegistrySlot({
|
|
36
|
+
serviceValue: options.serviceValue,
|
|
37
|
+
createInstance: options.createInstance,
|
|
38
|
+
});
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (error instanceof ServiceRegistryError && error.code === "SERVICE_SLOTS_FULL") {
|
|
41
|
+
logger.critical("No EMPTY registry slot — refusing to start", {
|
|
42
|
+
topic: logTopic,
|
|
43
|
+
data: { serviceValue: options.serviceValue, code: error.code },
|
|
44
|
+
});
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
try {
|
|
51
|
+
await options.run({ service: session.service, session });
|
|
52
|
+
} catch (error: unknown) {
|
|
53
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
54
|
+
logger.error("fatal", { topic: logTopic, data: { message } });
|
|
55
|
+
await session.release().catch(() => undefined);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/node.ts
CHANGED
|
@@ -10,25 +10,32 @@ export * from "./command/command.interface";
|
|
|
10
10
|
export type {
|
|
11
11
|
EnvIntOptions,
|
|
12
12
|
EnvNumberOptions,
|
|
13
|
+
EnvProfileFromProcessOptions,
|
|
13
14
|
InitSupabaseFromStandardEnvOptions,
|
|
14
15
|
LoadEnvFilesOptions,
|
|
15
16
|
PublicBaseUrlFromEnvOptions,
|
|
16
17
|
} from "./node/env";
|
|
17
18
|
export {
|
|
19
|
+
CLI_PROD_FLAG,
|
|
18
20
|
envBool,
|
|
19
21
|
envInt,
|
|
20
22
|
envMs,
|
|
21
23
|
envNumber,
|
|
22
24
|
envPort,
|
|
25
|
+
envProfileFromProcess,
|
|
23
26
|
initSupabaseFromStandardEnv,
|
|
24
27
|
loadEnvFiles,
|
|
25
28
|
parseEnvFile,
|
|
26
29
|
parseEnvLine,
|
|
30
|
+
pinEnvProfileFromArgv,
|
|
27
31
|
publicBaseUrlFromEnv,
|
|
28
32
|
readEnv,
|
|
29
33
|
requireEnv,
|
|
34
|
+
resolveDefaultEnvFiles,
|
|
30
35
|
resolveProjectRootByPackageName,
|
|
31
36
|
resolveProjectRootFromModule,
|
|
37
|
+
SERVICE_ENV_PROFILE_ENV_KEY,
|
|
38
|
+
SERVICE_ENV_PROFILE_PROD,
|
|
32
39
|
} from "./node/env";
|
|
33
40
|
export type {
|
|
34
41
|
CreateJsonFileStateStoreOptions,
|
|
@@ -44,16 +51,21 @@ export {
|
|
|
44
51
|
nodeBufferToArrayBuffer,
|
|
45
52
|
readAndVerifySourceFile,
|
|
46
53
|
} from "./node/fs/read-source-file";
|
|
54
|
+
export type { BaseNodeRuntimeOptions, NodeLoopContext } from "./node/node-runtime.base";
|
|
47
55
|
export { BaseNodeRuntime } from "./node/node-runtime.base";
|
|
48
56
|
export type {
|
|
49
57
|
BuildNodeImportArgsInput,
|
|
58
|
+
CreateManagedChildProcessesOptions,
|
|
59
|
+
CriticalExitHandler,
|
|
50
60
|
ManagedChildProcessesOptions,
|
|
61
|
+
SpawnChildOptions,
|
|
51
62
|
SpawnChildResult,
|
|
52
63
|
SpawnTsxChildOptions,
|
|
53
64
|
StopAllChildrenOptions,
|
|
54
65
|
} from "./node/process";
|
|
55
66
|
export {
|
|
56
67
|
buildNodeImportArgs,
|
|
68
|
+
createManagedChildProcesses,
|
|
57
69
|
isChildProcessRunning,
|
|
58
70
|
ManagedChildProcesses,
|
|
59
71
|
spawnTsxChild,
|
|
@@ -78,6 +90,48 @@ export {
|
|
|
78
90
|
runReadinessChecks,
|
|
79
91
|
waitForServiceReady,
|
|
80
92
|
} from "./node/readiness";
|
|
93
|
+
export type {
|
|
94
|
+
CreateServiceRuntimeStateStoreOptions,
|
|
95
|
+
FinishRunnerTickOptions,
|
|
96
|
+
GuardRuntimeSlice,
|
|
97
|
+
ReadinessRuntimeSlice,
|
|
98
|
+
ReadinessStatus,
|
|
99
|
+
SchedulerRuntimeSlice,
|
|
100
|
+
ServiceRuntimeCoreNestedKey,
|
|
101
|
+
ServiceRuntimeExtraSlicePatch,
|
|
102
|
+
ServiceRuntimeNestedKeys,
|
|
103
|
+
ServiceRuntimeState,
|
|
104
|
+
ServiceRuntimeStateStore,
|
|
105
|
+
WorkerRuntimeSlice,
|
|
106
|
+
} from "./node/runtime-state";
|
|
107
|
+
export { createServiceRuntimeStateStore } from "./node/runtime-state";
|
|
108
|
+
export type {
|
|
109
|
+
ApplyRegistrySlotGuardInput,
|
|
110
|
+
ApplyRegistrySlotGuardResult,
|
|
111
|
+
RegisterServiceGuardRunnerOptions,
|
|
112
|
+
RunReadinessGateInput,
|
|
113
|
+
ServiceGuardNodeOptions,
|
|
114
|
+
ServiceGuardTickInput,
|
|
115
|
+
ServiceGuardTickResult,
|
|
116
|
+
ServiceHost,
|
|
117
|
+
ServiceHostClosable,
|
|
118
|
+
ServiceHostContext,
|
|
119
|
+
ServiceHostOptions,
|
|
120
|
+
SingleProcessServiceContext,
|
|
121
|
+
SingleProcessServiceOptions,
|
|
122
|
+
} from "./node/service-host";
|
|
123
|
+
export {
|
|
124
|
+
applyRegistrySlotGuardStep,
|
|
125
|
+
createServiceHost,
|
|
126
|
+
getWorkerSpawnCooldownLastAt,
|
|
127
|
+
markWorkerSpawned,
|
|
128
|
+
registerServiceGuardRunner,
|
|
129
|
+
runReadinessGate,
|
|
130
|
+
runServiceGuardTick,
|
|
131
|
+
runSingleProcessService,
|
|
132
|
+
SERVICE_GUARD_RUNNER_KEY,
|
|
133
|
+
ServiceGuardNode,
|
|
134
|
+
} from "./node/service-host";
|
|
81
135
|
export { RepoManager } from "./repo/repo-manager";
|
|
82
136
|
export {
|
|
83
137
|
disableLogPersist,
|
|
@@ -98,6 +152,25 @@ export type {
|
|
|
98
152
|
LogPersistStats,
|
|
99
153
|
WaitForLogPersistReadyOptions,
|
|
100
154
|
} from "./shared/log/log-persist.interface";
|
|
155
|
+
export type { LogPersistCoordinator, LogPersistCoordinatorOptions } from "./shared/log/log-persist-coordinator";
|
|
156
|
+
export { createLogPersistCoordinator } from "./shared/log/log-persist-coordinator";
|
|
157
|
+
export type {
|
|
158
|
+
ConfigSchema,
|
|
159
|
+
LoadCachedJsConfigOptions,
|
|
160
|
+
ResolveFirstExistingPathOptions,
|
|
161
|
+
} from "./shared/utils/config-path.utils";
|
|
162
|
+
export {
|
|
163
|
+
getConfigFileDir,
|
|
164
|
+
importJsConfigModule,
|
|
165
|
+
loadCachedJsConfigModule,
|
|
166
|
+
pathExists,
|
|
167
|
+
resolveFirstExistingPath,
|
|
168
|
+
resolvePathFromBaseDir,
|
|
169
|
+
resolvePathFromConfigFile,
|
|
170
|
+
resolvePathFromCwd,
|
|
171
|
+
toFileImportHref,
|
|
172
|
+
} from "./shared/utils/config-path.utils";
|
|
173
|
+
export { getValueAtPath } from "./shared/utils/get-value-at-path";
|
|
101
174
|
export type {
|
|
102
175
|
BootstrapLocalTasksResult,
|
|
103
176
|
BootstrapLocalTasksStatus,
|
|
@@ -125,6 +198,9 @@ export {
|
|
|
125
198
|
} from "./task/task-manager";
|
|
126
199
|
export { TaskNode } from "./task/task-node";
|
|
127
200
|
export type { PostTaskPayload } from "./task/task-post.api";
|
|
201
|
+
export { postTask, postTaskSchema } from "./task/task-post.api";
|
|
202
|
+
export type { PostTaskWithRetryOptions, PostTaskWithRetryResult } from "./task/task-post-retry.api";
|
|
203
|
+
export { POST_TASK_DEFAULT_MAX_ATTEMPTS, postTaskWithRetry } from "./task/task-post-retry.api";
|
|
128
204
|
export { postTaskWithValidation } from "./task/task-post-validated.api";
|
|
129
205
|
export type {
|
|
130
206
|
TaskRepoValidationFailureReason,
|