@deepraxis/sdk 0.1.1-dev.d775f1e → 0.1.1-dev.da4893e

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,121 @@
1
+ export interface TemplateBuildLog {
2
+ timestamp: string;
3
+ level: 'debug' | 'info' | 'warn' | 'error';
4
+ message: string;
5
+ step?: string;
6
+ }
7
+ export interface TemplateBuildReason {
8
+ message: string;
9
+ step?: string;
10
+ logEntries?: TemplateBuildLog[];
11
+ }
12
+ export interface TemplateBuildStatus {
13
+ templateID: string;
14
+ buildID: string;
15
+ status: 'waiting' | 'building' | 'ready' | 'error';
16
+ logEntries: TemplateBuildLog[];
17
+ logs: string[];
18
+ reason?: TemplateBuildReason;
19
+ }
20
+ export type SandboxTemplateBuildInput = {
21
+ /** Organization-local name. Reusing it reserves another build of the same template. */
22
+ name: string;
23
+ /** Optional resource counts; defaults to 2 vCPUs and 1024 MiB. */
24
+ cpuCount?: number;
25
+ memoryMB?: number;
26
+ /** Disk size in GiB, a positive integer; default 10. */
27
+ diskGb?: number;
28
+ /** Labels assigned only after a successful build. */
29
+ tags?: string[];
30
+ /** Structured build steps; COPY is rejected. Mutually exclusive with dockerfile. */
31
+ steps?: {
32
+ type: 'RUN' | 'ENV' | 'WORKDIR' | 'USER';
33
+ args: string[];
34
+ }[];
35
+ /** Called sequentially for newly read log entries. */
36
+ onLog?: (entry: TemplateBuildLog) => void | Promise<void>;
37
+ /** Stops requests and polling; the remote build continues. */
38
+ signal?: AbortSignal;
39
+ /** Nonnegative polling delay in milliseconds; default 1000. */
40
+ pollIntervalMs?: number;
41
+ } & ({
42
+ dockerfile: string;
43
+ fromTemplate?: never;
44
+ fromImage?: never;
45
+ steps?: never;
46
+ } | {
47
+ dockerfile?: never;
48
+ fromTemplate: string;
49
+ fromImage?: never;
50
+ } | {
51
+ dockerfile?: never;
52
+ fromTemplate?: never;
53
+ fromImage: string;
54
+ });
55
+ export interface SandboxTemplateBuildResult extends TemplateBuildStatus {
56
+ status: 'ready';
57
+ }
58
+ export declare class SandboxTemplateBuildError extends Error {
59
+ readonly templateID: string;
60
+ readonly buildID: string;
61
+ readonly reason: TemplateBuildReason | undefined;
62
+ readonly logEntries: readonly TemplateBuildLog[];
63
+ readonly name = "SandboxTemplateBuildError";
64
+ constructor(templateID: string, buildID: string, reason: TemplateBuildReason | undefined, logEntries: readonly TemplateBuildLog[]);
65
+ }
66
+ /** Structural port keeps the helper independent of the client that attaches it. */
67
+ export interface SandboxTemplateBuildClient {
68
+ sandbox: {
69
+ templates: {
70
+ create(input: {
71
+ body: {
72
+ name: string;
73
+ cpuCount?: number;
74
+ memoryMB?: number;
75
+ diskGb?: number;
76
+ tags?: string[];
77
+ };
78
+ signal: AbortSignal;
79
+ }): Promise<{
80
+ templateID: string;
81
+ buildID: string;
82
+ }>;
83
+ builds: {
84
+ update(input: {
85
+ path: {
86
+ templateID: string;
87
+ buildID: string;
88
+ };
89
+ body: {
90
+ dockerfile?: string;
91
+ fromTemplate?: string;
92
+ fromImage?: string;
93
+ steps?: {
94
+ type: string;
95
+ args: string[];
96
+ }[];
97
+ };
98
+ signal: AbortSignal;
99
+ }): Promise<unknown>;
100
+ status: {
101
+ list(input: {
102
+ path: {
103
+ templateID: string;
104
+ buildID: string;
105
+ };
106
+ query: {
107
+ logsOffset: number;
108
+ };
109
+ signal: AbortSignal;
110
+ }): Promise<TemplateBuildStatus>;
111
+ };
112
+ };
113
+ };
114
+ };
115
+ }
116
+ /** Build an organization-local template and wait until it is ready, streaming logs in order.
117
+ * Uses create, source submission and status polling. COPY is unavailable; use RUN curl or git clone.
118
+ * fromTemplate accepts official catalog names only. Abort stops the client; it does not cancel the build.
119
+ * Terminal errors include the provider reason and the final twenty bounded log entries.
120
+ */
121
+ export declare function buildSandboxTemplate(client: SandboxTemplateBuildClient, input: SandboxTemplateBuildInput): Promise<SandboxTemplateBuildResult>;
@@ -0,0 +1,60 @@
1
+ import { sleep } from "../core/retry.js";
2
+ export class SandboxTemplateBuildError extends Error {
3
+ templateID;
4
+ buildID;
5
+ reason;
6
+ logEntries;
7
+ name = 'SandboxTemplateBuildError';
8
+ constructor(templateID, buildID, reason, logEntries) {
9
+ super(`Template build failed: ${reason?.message ?? 'Unknown build error'}${logEntries.length ? `\n${logEntries.map(log => log.message).join('\n')}` : ''}`);
10
+ this.templateID = templateID;
11
+ this.buildID = buildID;
12
+ this.reason = reason;
13
+ this.logEntries = logEntries;
14
+ }
15
+ }
16
+ /** Build an organization-local template and wait until it is ready, streaming logs in order.
17
+ * Uses create, source submission and status polling. COPY is unavailable; use RUN curl or git clone.
18
+ * fromTemplate accepts official catalog names only. Abort stops the client; it does not cancel the build.
19
+ * Terminal errors include the provider reason and the final twenty bounded log entries.
20
+ */
21
+ export async function buildSandboxTemplate(client, input) {
22
+ const signal = input.signal ?? new AbortController().signal;
23
+ signal.throwIfAborted();
24
+ const interval = input.pollIntervalMs ?? 1000;
25
+ if (!Number.isSafeInteger(interval) || interval < 0)
26
+ throw new RangeError('pollIntervalMs must be a nonnegative integer');
27
+ if ([input.dockerfile, input.fromTemplate, input.fromImage].filter(value => value !== undefined).length !== 1
28
+ || (input.dockerfile !== undefined && input.steps !== undefined))
29
+ throw new TypeError('Supply dockerfile, fromTemplate or fromImage; dockerfile cannot include steps');
30
+ const created = await client.sandbox.templates.create({ body: {
31
+ name: input.name, cpuCount: input.cpuCount, memoryMB: input.memoryMB, diskGb: input.diskGb, tags: input.tags,
32
+ }, signal });
33
+ const path = { templateID: created.templateID, buildID: created.buildID };
34
+ await client.sandbox.templates.builds.update({ path, body: input.dockerfile !== undefined ? { dockerfile: input.dockerfile }
35
+ : { fromTemplate: input.fromTemplate, fromImage: input.fromImage, steps: input.steps }, signal });
36
+ let logsOffset = 0;
37
+ const tail = [];
38
+ let terminal;
39
+ while (true) {
40
+ signal.throwIfAborted();
41
+ const result = await client.sandbox.templates.builds.status.list({ path, query: { logsOffset }, signal });
42
+ for (const entry of result.logEntries) {
43
+ signal.throwIfAborted();
44
+ await input.onLog?.(entry);
45
+ // Bound retained diagnostics even when one provider log message is enormous.
46
+ tail.push({ ...entry, message: entry.message.slice(-4096) });
47
+ if (tail.length > 20)
48
+ tail.shift();
49
+ }
50
+ logsOffset += result.logEntries.length;
51
+ if (!terminal && (result.status === 'ready' || result.status === 'error'))
52
+ terminal = result;
53
+ if (terminal && result.logEntries.length === 0) {
54
+ if (terminal.status === 'error')
55
+ throw new SandboxTemplateBuildError(path.templateID, path.buildID, terminal.reason, tail);
56
+ return { ...terminal, status: 'ready', logEntries: [] };
57
+ }
58
+ await sleep(interval, signal);
59
+ }
60
+ }
package/dist/index.d.ts CHANGED
@@ -7,7 +7,13 @@ export { parseSSE } from './core/sse.js';
7
7
  export type { SSEEvent, SSEOptions } from './core/sse.js';
8
8
  export { publish } from './helpers/application-publish.js';
9
9
  export type { PublishInput, PublishResult, AssetsConfig } from './helpers/application-publish.js';
10
+ export { publishInputFromBuild } from './helpers/application-build.js';
11
+ export type { BuildOutput } from './helpers/application-build.js';
10
12
  export { count } from './helpers/database-count.js';
11
13
  export type { CountInput, CountResult } from './helpers/database-count.js';
12
14
  export { uploadFile } from './helpers/file-upload.js';
13
15
  export type { UploadFileOptions, UploadedFile } from './helpers/file-upload.js';
16
+ export { connectBrowser } from './helpers/browser-connect.js';
17
+ export type { PraxisBrowser, BrowserTab, BrowserConnectOptions } from './helpers/browser-connect.js';
18
+ export { buildSandboxTemplate, SandboxTemplateBuildError } from './helpers/sandbox-templates.js';
19
+ export type { SandboxTemplateBuildInput, SandboxTemplateBuildResult, TemplateBuildLog, TemplateBuildReason } from './helpers/sandbox-templates.js';
package/dist/index.js CHANGED
@@ -3,5 +3,8 @@ export { PraxisError, PraxisConnectionError, PraxisTimeoutError } from "./core/e
3
3
  export { Page } from "./core/pagination.js";
4
4
  export { parseSSE } from "./core/sse.js";
5
5
  export { publish } from "./helpers/application-publish.js";
6
+ export { publishInputFromBuild } from "./helpers/application-build.js";
6
7
  export { count } from "./helpers/database-count.js";
7
8
  export { uploadFile } from "./helpers/file-upload.js";
9
+ export { connectBrowser } from "./helpers/browser-connect.js";
10
+ export { buildSandboxTemplate, SandboxTemplateBuildError } from "./helpers/sandbox-templates.js";