@inquir/compute 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -1
- package/dist/app-observability.d.ts +69 -0
- package/dist/app-observability.d.ts.map +1 -0
- package/dist/app-observability.js +65 -0
- package/dist/app-observability.js.map +1 -0
- package/dist/app-observability.types.d.ts +358 -0
- package/dist/app-observability.types.d.ts.map +1 -0
- package/dist/app-observability.types.js +2 -0
- package/dist/app-observability.types.js.map +1 -0
- package/dist/apps.d.ts +304 -6
- package/dist/apps.d.ts.map +1 -1
- package/dist/apps.js +89 -7
- package/dist/apps.js.map +1 -1
- package/dist/build-timeout-policy.d.ts +13 -0
- package/dist/build-timeout-policy.d.ts.map +1 -0
- package/dist/build-timeout-policy.js +11 -0
- package/dist/build-timeout-policy.js.map +1 -0
- package/dist/discovery.d.ts +9 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +74 -7
- package/dist/discovery.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/invocation-observation.d.ts +23 -0
- package/dist/invocation-observation.d.ts.map +1 -0
- package/dist/invocation-observation.js +79 -0
- package/dist/invocation-observation.js.map +1 -0
- package/dist/local-runner-harness.js +28 -6
- package/dist/local-runner-harness.js.map +1 -1
- package/dist/local-runner.d.ts.map +1 -1
- package/dist/local-runner.js +103 -6
- package/dist/local-runner.js.map +1 -1
- package/dist/projects.d.ts +147 -0
- package/dist/projects.d.ts.map +1 -0
- package/dist/projects.js +64 -0
- package/dist/projects.js.map +1 -0
- package/dist/release-commands.d.ts +80 -0
- package/dist/release-commands.d.ts.map +1 -0
- package/dist/release-commands.js +147 -0
- package/dist/release-commands.js.map +1 -0
- package/dist/source-command-http.d.ts +7 -0
- package/dist/source-command-http.d.ts.map +1 -0
- package/dist/source-command-http.js +87 -0
- package/dist/source-command-http.js.map +1 -0
- package/dist/source-command-protocol.d.ts +137 -0
- package/dist/source-command-protocol.d.ts.map +1 -0
- package/dist/source-command-protocol.js +311 -0
- package/dist/source-command-protocol.js.map +1 -0
- package/dist/source-commands.d.ts +33 -0
- package/dist/source-commands.d.ts.map +1 -0
- package/dist/source-commands.js +116 -0
- package/dist/source-commands.js.map +1 -0
- package/dist/transport.d.ts +63 -2
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +237 -14
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { ApiError, createClient, authHeaders, getMe, toApiError } from './transport.js';
|
|
3
|
+
import { boundedSourceCommandFetch } from './source-command-http.js';
|
|
4
|
+
export class ReleaseCommandObservationEndedError extends Error {
|
|
5
|
+
retained;
|
|
6
|
+
constructor(retained, options) {
|
|
7
|
+
super('Release command observation ended; resume this same request ID', options);
|
|
8
|
+
this.retained = retained;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const UUID = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/;
|
|
12
|
+
function identifier(value) {
|
|
13
|
+
if (typeof value !== 'string' || !value || value.length > 256 || Array.from(value).some(c => c.charCodeAt(0) < 32 || c.charCodeAt(0) === 127))
|
|
14
|
+
throw new Error('Invalid release command scope');
|
|
15
|
+
}
|
|
16
|
+
function object(value) { if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
17
|
+
throw new Error('Invalid release command protocol'); return value; }
|
|
18
|
+
function exact(value, keys) { if (Object.keys(value).sort().join(',') !== keys)
|
|
19
|
+
throw new Error('Release command fields differ'); }
|
|
20
|
+
function normalized(input) {
|
|
21
|
+
const value = structuredClone(input), env = value?.env ?? {}, timeoutMs = value?.timeoutMs ?? 60000;
|
|
22
|
+
const string = (v) => typeof v === 'string' && !v.includes('\0') && Buffer.from(v).toString('utf8') === v;
|
|
23
|
+
if (!value || Object.keys(value).some(k => !['command', 'timeoutMs', 'env'].includes(k)) || !string(value.command) || !value.command || value.command.length > 4000
|
|
24
|
+
|| !Number.isSafeInteger(timeoutMs) || timeoutMs < 1000 || timeoutMs > 900000 || !env || typeof env !== 'object' || Array.isArray(env)
|
|
25
|
+
|| !Object.entries(env).every(([key, item]) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(key) && string(item)))
|
|
26
|
+
throw new Error('Invalid release command input');
|
|
27
|
+
return { command: value.command, timeoutMs, env };
|
|
28
|
+
}
|
|
29
|
+
function binding(client) {
|
|
30
|
+
const url = new URL(client.baseUrl);
|
|
31
|
+
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash || !client.apiKey)
|
|
32
|
+
throw new Error('Release commands require a plain authenticated HTTP API');
|
|
33
|
+
return { apiUrl: url.toString().replace(/\/+$/, ''), credentialHash: createHash('sha256').update(client.apiKey).digest('hex') };
|
|
34
|
+
}
|
|
35
|
+
function operation(client, value) {
|
|
36
|
+
const retained = structuredClone(value), current = binding(client);
|
|
37
|
+
exact(object(retained), 'apiUrl,credentialHash,functionId,input,requestId,tenantId,version');
|
|
38
|
+
identifier(retained.tenantId);
|
|
39
|
+
identifier(retained.functionId);
|
|
40
|
+
if (retained.version !== 1 || !UUID.test(retained.requestId) || retained.apiUrl !== current.apiUrl || retained.credentialHash !== current.credentialHash
|
|
41
|
+
|| client.workspaceId !== undefined && client.workspaceId !== retained.tenantId || JSON.stringify(normalized(retained.input)) !== JSON.stringify(retained.input))
|
|
42
|
+
throw new Error('Retained release command binding differs');
|
|
43
|
+
// The platform captures at most 1 MiB of logs; JSON escapes may expand each
|
|
44
|
+
// byte sixfold. This response bound preserves the entire validated capture.
|
|
45
|
+
const pinned = createClient({ ...client, baseUrl: retained.apiUrl, workspaceId: retained.tenantId, fetchImpl: boundedSourceCommandFetch(client.fetchImpl, { responseLimitBytes: 8 * 1024 * 1024 }) });
|
|
46
|
+
const base = `/functions/${encodeURIComponent(retained.functionId)}/release-commands/${retained.requestId}`;
|
|
47
|
+
async function request(mode, signal) {
|
|
48
|
+
signal?.throwIfAborted();
|
|
49
|
+
const response = await pinned.fetchImpl(pinned.baseUrl + base + (mode === 'submit' ? '' : `/${mode}`), { method: 'POST', redirect: 'error', signal,
|
|
50
|
+
headers: { ...authHeaders(pinned), 'Content-Type': 'application/json' }, body: JSON.stringify(mode === 'submit' ? retained.input : {}) });
|
|
51
|
+
const payload = await response.json();
|
|
52
|
+
if (!response.ok)
|
|
53
|
+
throw toApiError(response, payload);
|
|
54
|
+
const row = object(payload);
|
|
55
|
+
if (row.requestId !== retained.requestId || row.functionId !== retained.functionId || row.kind !== 'EXEC_RELEASE')
|
|
56
|
+
throw new Error('Release command response scope differs');
|
|
57
|
+
if (mode === 'cancel') {
|
|
58
|
+
exact(row, 'functionId,kind,requestId,state');
|
|
59
|
+
if (response.status !== 202 || row.state !== 'CANCEL_REQUESTED')
|
|
60
|
+
throw new Error('Invalid cancellation intent');
|
|
61
|
+
return row;
|
|
62
|
+
}
|
|
63
|
+
if (row.state === 'PENDING' || row.state === 'RECOVERY_HELD') {
|
|
64
|
+
exact(row, 'functionId,kind,requestId,resumeUrl,state');
|
|
65
|
+
if (response.status !== 202 || row.resumeUrl !== base + '/resume')
|
|
66
|
+
throw new Error('Untrusted release recovery URL');
|
|
67
|
+
}
|
|
68
|
+
else if (row.state === 'CANCELLED_BEFORE_ADMISSION' || row.state === 'CANCELLED_WITHOUT_CONTAINER') {
|
|
69
|
+
exact(row, 'functionId,kind,requestId,result,state');
|
|
70
|
+
if (response.status !== 200 || row.result !== null)
|
|
71
|
+
throw new Error('Invalid pre-admission cancellation');
|
|
72
|
+
}
|
|
73
|
+
else if (row.state === 'REMOVED') {
|
|
74
|
+
exact(row, 'functionId,kind,requestId,result,state');
|
|
75
|
+
const result = object(row.result);
|
|
76
|
+
exact(result, 'durationMs,exitCode,logFailure,stderr,stdout,termination,timedOut,truncated');
|
|
77
|
+
if (response.status !== 200 || !['EXITED', 'TIMEOUT', 'CANCELLED', 'HOST_REBOOT'].includes(String(result.termination))
|
|
78
|
+
|| !(result.exitCode === null || Number.isSafeInteger(result.exitCode) && Number(result.exitCode) >= 0 && Number(result.exitCode) <= 255)
|
|
79
|
+
|| result.termination === 'EXITED' && result.exitCode === null || typeof result.stdout !== 'string' || typeof result.stderr !== 'string'
|
|
80
|
+
|| typeof result.durationMs !== 'number' || !Number.isFinite(result.durationMs) || result.durationMs < 0 || typeof result.truncated !== 'boolean'
|
|
81
|
+
|| result.timedOut !== (result.termination === 'TIMEOUT'))
|
|
82
|
+
throw new Error('Invalid removed command result');
|
|
83
|
+
if (result.logFailure !== null) {
|
|
84
|
+
const failure = object(result.logFailure);
|
|
85
|
+
exact(failure, 'code');
|
|
86
|
+
if (!['LOG_LAYOUT_INVALID', 'LOG_RECORD_INVALID', 'LOG_RECORD_INCOMPLETE', 'LOG_LIMIT_EXCEEDED'].includes(String(failure.code)) || result.stdout !== '' || result.stderr !== '' || result.truncated !== true)
|
|
87
|
+
throw new Error('Invalid log failure');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
else
|
|
91
|
+
throw new Error('Unknown release command state');
|
|
92
|
+
return row;
|
|
93
|
+
}
|
|
94
|
+
return { record: () => structuredClone(retained), submit: async (signal) => await request('submit', signal),
|
|
95
|
+
resume: async (signal) => await request('resume', signal),
|
|
96
|
+
cancel: async (signal) => await request('cancel', signal),
|
|
97
|
+
async observe(options = {}) {
|
|
98
|
+
const timeout = options.timeoutMs ?? 900000, poll = options.pollIntervalMs ?? 100, signal = options.signal;
|
|
99
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 900000 || !Number.isSafeInteger(poll) || poll < 1 || poll > 10000)
|
|
100
|
+
throw new Error('Invalid command observation limits');
|
|
101
|
+
const control = new AbortController(), abort = () => control.abort(signal?.reason), timer = setTimeout(() => control.abort(), timeout);
|
|
102
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
103
|
+
if (signal?.aborted)
|
|
104
|
+
abort();
|
|
105
|
+
try {
|
|
106
|
+
for (;;) {
|
|
107
|
+
control.signal.throwIfAborted();
|
|
108
|
+
const result = await request('resume', control.signal);
|
|
109
|
+
if (result.state === 'REMOVED' || result.state === 'CANCELLED_BEFORE_ADMISSION' || result.state === 'CANCELLED_WITHOUT_CONTAINER')
|
|
110
|
+
return result;
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
const ended = () => { clearTimeout(wait); control.signal.removeEventListener('abort', ended); reject(control.signal.reason); }, wait = setTimeout(() => { control.signal.removeEventListener('abort', ended); resolve(); }, poll);
|
|
113
|
+
control.signal.addEventListener('abort', ended, { once: true });
|
|
114
|
+
if (control.signal.aborted)
|
|
115
|
+
ended();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
// 404 (unknown request) and 409 (changed command, lost before start) are
|
|
121
|
+
// definite outcomes: resuming the same request ID cannot change them.
|
|
122
|
+
if (error instanceof ApiError && (error.status === 404 || error.status === 409))
|
|
123
|
+
throw error;
|
|
124
|
+
throw new ReleaseCommandObservationEndedError(structuredClone(retained), { cause: error });
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
clearTimeout(timer);
|
|
128
|
+
signal?.removeEventListener('abort', abort);
|
|
129
|
+
}
|
|
130
|
+
} };
|
|
131
|
+
}
|
|
132
|
+
/** The caller must persist the original UUID/request before the FIRST HTTP submission. */
|
|
133
|
+
export async function prepareReleaseCommand(client, options) {
|
|
134
|
+
const frozen = structuredClone({ functionId: options.functionId, requestId: options.requestId, input: normalized(options.input) }), retain = options.retain;
|
|
135
|
+
identifier(frozen.functionId);
|
|
136
|
+
if (!UUID.test(frozen.requestId) || typeof retain !== 'function')
|
|
137
|
+
throw new Error('A durable original release command identity is required');
|
|
138
|
+
const snapshot = createClient({ ...client }), current = binding(snapshot), me = snapshot.workspaceId ? null : await getMe(snapshot), tenantId = snapshot.workspaceId ?? me?.activeWorkspace?.id;
|
|
139
|
+
identifier(tenantId);
|
|
140
|
+
const record = { version: 1, ...current, tenantId, functionId: frozen.functionId, requestId: frozen.requestId, input: frozen.input };
|
|
141
|
+
const prepared = operation(snapshot, record);
|
|
142
|
+
await retain(prepared.record());
|
|
143
|
+
return prepared;
|
|
144
|
+
}
|
|
145
|
+
/** Recovery performs NO discovery and NO submit, even after admission is withdrawn. */
|
|
146
|
+
export function restoreReleaseCommand(client, record) { return operation(client, record); }
|
|
147
|
+
//# sourceMappingURL=release-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-commands.js","sourceRoot":"","sources":["../src/release-commands.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Binds every discovery/action request to a finite whole-body wait. Late replies
|
|
2
|
+
* are disposed without awaiting body cancellation or triggering another action.
|
|
3
|
+
*/
|
|
4
|
+
export declare function boundedSourceCommandFetch(fetchImpl: typeof fetch, options?: {
|
|
5
|
+
responseLimitBytes?: number;
|
|
6
|
+
}): typeof fetch;
|
|
7
|
+
//# sourceMappingURL=source-command-http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-command-http.d.ts","sourceRoot":"","sources":["../src/source-command-http.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAC,OAAO,KAAK,EAAC,OAAO,GAAC;IAAC,kBAAkB,CAAC,EAAC,MAAM,CAAA;CAAI,GAAE,OAAO,KAAK,CAoCrH"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const FINITE_BYTES = 2 * 1024 * 1024, DISCOVERY_BYTES = 4 * 1024 * 1024;
|
|
2
|
+
function dispose(body) {
|
|
3
|
+
try {
|
|
4
|
+
void body?.cancel().catch(() => undefined);
|
|
5
|
+
}
|
|
6
|
+
catch { /* Disposal cannot delay or reject observation. */ }
|
|
7
|
+
}
|
|
8
|
+
function abortable(pending, signal) {
|
|
9
|
+
if (signal.aborted) {
|
|
10
|
+
void pending.catch(() => undefined);
|
|
11
|
+
signal.throwIfAborted();
|
|
12
|
+
}
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
const abort = () => { signal.removeEventListener('abort', abort); reject(signal.reason); };
|
|
15
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
16
|
+
pending.then(value => { signal.removeEventListener('abort', abort); resolve(value); }, error => { signal.removeEventListener('abort', abort); reject(error); });
|
|
17
|
+
if (signal.aborted)
|
|
18
|
+
abort();
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** Binds every discovery/action request to a finite whole-body wait. Late replies
|
|
22
|
+
* are disposed without awaiting body cancellation or triggering another action.
|
|
23
|
+
*/
|
|
24
|
+
export function boundedSourceCommandFetch(fetchImpl, options = {}) {
|
|
25
|
+
const responseLimitBytes = options.responseLimitBytes;
|
|
26
|
+
if (responseLimitBytes !== undefined && (!Number.isSafeInteger(responseLimitBytes) || responseLimitBytes < 1 || responseLimitBytes > 64 * 1024 * 1024))
|
|
27
|
+
throw new Error('Invalid response byte limit');
|
|
28
|
+
return async (input, init) => {
|
|
29
|
+
const inherited = init?.signal ?? (input instanceof Request ? input.signal : undefined);
|
|
30
|
+
const signal = AbortSignal.any([AbortSignal.timeout(60_000), ...(inherited ? [inherited] : [])]);
|
|
31
|
+
const pending = Promise.resolve().then(() => { signal.throwIfAborted(); return fetchImpl(input, { ...init, signal, redirect: 'error' }); });
|
|
32
|
+
void pending.then(response => { if (signal.aborted)
|
|
33
|
+
dispose(response.body); }, () => undefined);
|
|
34
|
+
const response = await abortable(pending, signal);
|
|
35
|
+
const pathname = new URL(input instanceof Request ? input.url : String(input)).pathname;
|
|
36
|
+
const limit = responseLimitBytes ?? (pathname.includes('/source-commands') ? FINITE_BYTES : DISCOVERY_BYTES);
|
|
37
|
+
const length = response.headers.get('content-length');
|
|
38
|
+
if (length && /^\d+$/.test(length) && Number(length) > limit) {
|
|
39
|
+
dispose(response.body);
|
|
40
|
+
throw new Error('Source command response exceeds byte limit');
|
|
41
|
+
}
|
|
42
|
+
const reader = response.body?.getReader(), chunks = [];
|
|
43
|
+
let bytes = 0, slab, used = 0;
|
|
44
|
+
try {
|
|
45
|
+
if (reader)
|
|
46
|
+
for (;;) {
|
|
47
|
+
const chunk = await abortable(reader.read(), signal);
|
|
48
|
+
if (chunk.done)
|
|
49
|
+
break;
|
|
50
|
+
bytes += chunk.value.byteLength;
|
|
51
|
+
if (bytes > limit)
|
|
52
|
+
throw new Error('Source command response exceeds byte limit');
|
|
53
|
+
let offset = 0;
|
|
54
|
+
while (offset < chunk.value.length) {
|
|
55
|
+
slab ??= Buffer.allocUnsafe(16 * 1024);
|
|
56
|
+
const count = Math.min(slab.length - used, chunk.value.length - offset);
|
|
57
|
+
slab.set(chunk.value.subarray(offset, offset + count), used);
|
|
58
|
+
used += count;
|
|
59
|
+
offset += count;
|
|
60
|
+
if (used === slab.length) {
|
|
61
|
+
chunks.push(slab);
|
|
62
|
+
slab = undefined;
|
|
63
|
+
used = 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
signal.throwIfAborted();
|
|
68
|
+
if (slab)
|
|
69
|
+
chunks.push(slab.subarray(0, used));
|
|
70
|
+
const data = Buffer.concat(chunks, bytes);
|
|
71
|
+
// Refuse malformed UTF8 rather than silently changing signed identities.
|
|
72
|
+
new TextDecoder('utf-8', { fatal: true }).decode(data);
|
|
73
|
+
return new Response([204, 205, 304].includes(response.status) ? null : data, { status: response.status, statusText: response.statusText, headers: response.headers });
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
dispose(reader);
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
try {
|
|
81
|
+
reader?.releaseLock();
|
|
82
|
+
}
|
|
83
|
+
catch { /* A pending aborted read owns completion. */ }
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=source-command-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-command-http.js","sourceRoot":"","sources":["../src/source-command-http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
export interface SourceCommandScope {
|
|
2
|
+
tenantId: string;
|
|
3
|
+
functionId: string;
|
|
4
|
+
}
|
|
5
|
+
export interface SourceCommandInput {
|
|
6
|
+
command: string;
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
export interface SourceCommandRecord {
|
|
11
|
+
version: 1;
|
|
12
|
+
scope: SourceCommandScope;
|
|
13
|
+
requestId: string;
|
|
14
|
+
input: {
|
|
15
|
+
command: string;
|
|
16
|
+
timeoutMs: number;
|
|
17
|
+
env: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
/** Observed server identity. Persist record() after acceptance to retain it across reloads. */
|
|
20
|
+
acceptedManifestDigest?: string;
|
|
21
|
+
}
|
|
22
|
+
export type SourceCommandState = 'PREPARING' | 'CANCEL_REQUESTED' | 'RESERVED' | 'CREATE_INTENT' | 'CREATED' | 'START_INTENT' | 'RUNNING' | 'EXITED' | 'CLEANUP_PENDING' | 'REMOVED';
|
|
23
|
+
export interface SourceWorkspaceOutput {
|
|
24
|
+
baseSnapshotDigest: string;
|
|
25
|
+
snapshotDigest: string;
|
|
26
|
+
sizeBytes: number;
|
|
27
|
+
}
|
|
28
|
+
export interface SourceWorkspaceFailure {
|
|
29
|
+
baseSnapshotDigest: string;
|
|
30
|
+
code: 'UNSAFE_PATH' | 'UNSAFE_LINK' | 'UNSUPPORTED_ENTRY' | 'INVALID_METADATA' | 'TREE_LIMIT_EXCEEDED';
|
|
31
|
+
}
|
|
32
|
+
export interface SourceLogFailure {
|
|
33
|
+
code: 'LOG_LAYOUT_INVALID' | 'LOG_RECORD_INVALID' | 'LOG_RECORD_INCOMPLETE' | 'LOG_LIMIT_EXCEEDED';
|
|
34
|
+
}
|
|
35
|
+
export interface SourceCommandResult {
|
|
36
|
+
attemptId: string;
|
|
37
|
+
manifestDigest: string;
|
|
38
|
+
termination: 'EXITED' | 'TIMEOUT' | 'CANCELLED' | 'HOST_REBOOT';
|
|
39
|
+
exitCode: number | null;
|
|
40
|
+
durationMs: number;
|
|
41
|
+
stdoutBase64: string;
|
|
42
|
+
stderrBase64: string;
|
|
43
|
+
truncated: boolean;
|
|
44
|
+
outputSource: 'nerdctl-json-file';
|
|
45
|
+
workspaceOutput: SourceWorkspaceOutput | null;
|
|
46
|
+
workspaceFailure: SourceWorkspaceFailure | null;
|
|
47
|
+
/** Present only when terminal log capture failed; empty payloads are not captured output. */
|
|
48
|
+
logFailure?: SourceLogFailure;
|
|
49
|
+
}
|
|
50
|
+
export interface SourceCommandPublication {
|
|
51
|
+
id: string;
|
|
52
|
+
captureId: string;
|
|
53
|
+
status: 'APPLIED' | 'CONFLICT';
|
|
54
|
+
revision: string | null;
|
|
55
|
+
outputDigest: string;
|
|
56
|
+
baseSnapshotDigest: string;
|
|
57
|
+
sizeBytes: number;
|
|
58
|
+
}
|
|
59
|
+
export interface SourceCommandPublicationBinding {
|
|
60
|
+
/** The authenticated, scope-bound transport remains authority for these server journal values. */
|
|
61
|
+
tenantId: string;
|
|
62
|
+
functionId: string;
|
|
63
|
+
requestId: string;
|
|
64
|
+
manifestDigest: string;
|
|
65
|
+
baseSnapshotDigest: string;
|
|
66
|
+
}
|
|
67
|
+
export interface SourceCommandOutcome {
|
|
68
|
+
command: {
|
|
69
|
+
requestId: string;
|
|
70
|
+
functionId: string;
|
|
71
|
+
kind: 'EXEC_SOURCE';
|
|
72
|
+
state: SourceCommandState;
|
|
73
|
+
cancelled: boolean;
|
|
74
|
+
};
|
|
75
|
+
result: SourceCommandResult | null;
|
|
76
|
+
publication: SourceCommandPublication | null;
|
|
77
|
+
publicationBinding?: SourceCommandPublicationBinding | null;
|
|
78
|
+
}
|
|
79
|
+
export interface SourceCommandCancellation {
|
|
80
|
+
command: {
|
|
81
|
+
requestId: string;
|
|
82
|
+
functionId: string;
|
|
83
|
+
kind: 'EXEC_SOURCE';
|
|
84
|
+
};
|
|
85
|
+
state: 'CANCEL_REQUESTED' | 'PUBLICATION_COMMITTED';
|
|
86
|
+
publication: SourceCommandPublication | null;
|
|
87
|
+
}
|
|
88
|
+
/** The adapter must bind this scope to product auth/workspace headers, not a mutable current workspace. */
|
|
89
|
+
export type SourceCommandTransport = (scope: SourceCommandScope, path: string, init: RequestInit) => Promise<unknown>;
|
|
90
|
+
export declare class SourceCommandClientError extends Error {
|
|
91
|
+
readonly code: 'INVALID_RECORD' | 'PROTOCOL' | 'CONFLICT' | 'REJECTED' | 'UNCERTAIN' | 'WAIT_ENDED' | 'RETENTION';
|
|
92
|
+
readonly uncertain: boolean;
|
|
93
|
+
constructor(code: 'INVALID_RECORD' | 'PROTOCOL' | 'CONFLICT' | 'REJECTED' | 'UNCERTAIN' | 'WAIT_ENDED' | 'RETENTION', message: string, uncertain: boolean, cause?: unknown);
|
|
94
|
+
}
|
|
95
|
+
/** Execution and publication are separate: a nonzero exit alone does not describe source publication. */
|
|
96
|
+
export declare function sourcePublicationState(value: SourceCommandOutcome): 'APPLIED' | 'CONFLICT' | 'CAPTURE_FAILED' | 'OUTPUT_FAILED' | 'NOT_PUBLISHED';
|
|
97
|
+
export interface SourceCommandOperation {
|
|
98
|
+
record(): SourceCommandRecord;
|
|
99
|
+
/** Retry pending acceptance retention without making an HTTP request. */
|
|
100
|
+
persist(): Promise<void>;
|
|
101
|
+
submit(signal?: AbortSignal): Promise<{
|
|
102
|
+
command: {
|
|
103
|
+
requestId: string;
|
|
104
|
+
functionId: string;
|
|
105
|
+
kind: 'EXEC_SOURCE';
|
|
106
|
+
state: SourceCommandState;
|
|
107
|
+
cancelled: boolean;
|
|
108
|
+
attemptId: string;
|
|
109
|
+
manifestDigest: string;
|
|
110
|
+
};
|
|
111
|
+
}>;
|
|
112
|
+
status(signal?: AbortSignal): Promise<SourceCommandOutcome>;
|
|
113
|
+
reconcile(signal?: AbortSignal): Promise<SourceCommandOutcome>;
|
|
114
|
+
cancel(signal?: AbortSignal): Promise<SourceCommandCancellation>;
|
|
115
|
+
/** GET only. A wait deadline/abort stops observation, never execution or publication. */
|
|
116
|
+
poll(options?: {
|
|
117
|
+
signal?: AbortSignal;
|
|
118
|
+
maxWaitMs?: number;
|
|
119
|
+
intervalMs?: number;
|
|
120
|
+
}): Promise<SourceCommandOutcome>;
|
|
121
|
+
}
|
|
122
|
+
/** Retain must durably store the record (including secrets securely) before any HTTP call. */
|
|
123
|
+
export declare function prepareSourceCommand(options: {
|
|
124
|
+
scope: SourceCommandScope;
|
|
125
|
+
input: SourceCommandInput;
|
|
126
|
+
requestId?: string;
|
|
127
|
+
retain(record: SourceCommandRecord): Promise<void>;
|
|
128
|
+
retainAcceptance?(record: SourceCommandRecord): Promise<void>;
|
|
129
|
+
transport: SourceCommandTransport;
|
|
130
|
+
}): Promise<SourceCommandOperation>;
|
|
131
|
+
/** Restoring an operation never submits it; callers explicitly choose observe/retry/reconcile/cancel. */
|
|
132
|
+
export declare function restoreSourceCommand(value: unknown, options: {
|
|
133
|
+
scope: SourceCommandScope;
|
|
134
|
+
transport: SourceCommandTransport;
|
|
135
|
+
retainAcceptance?(record: SourceCommandRecord): Promise<void>;
|
|
136
|
+
}): SourceCommandOperation;
|
|
137
|
+
//# sourceMappingURL=source-command-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-command-protocol.d.ts","sourceRoot":"","sources":["../src/source-command-protocol.ts"],"names":[],"mappings":"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"}
|