@womp/spark-agent 5.6.0 → 5.7.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.
Files changed (45) hide show
  1. package/README.md +436 -437
  2. package/dist/agent-run.d.ts +1 -1
  3. package/dist/agent.d.ts +2 -0
  4. package/dist/agent.js +3 -1
  5. package/dist/capabilities/geometry.js +14 -14
  6. package/dist/capabilities/materials.js +14 -14
  7. package/dist/capabilities/openscad-instructions.js +77 -77
  8. package/dist/capabilities/operations.js +28 -28
  9. package/dist/capabilities/scene.js +81 -81
  10. package/dist/capabilities/wompify.js +10 -10
  11. package/dist/client.d.ts +7 -0
  12. package/dist/client.js +14 -0
  13. package/dist/geometry/schemas/backend-schema.json +3393 -3393
  14. package/dist/geometry/schemas/flowir-dialect.json +1023 -1023
  15. package/dist/geometry.js +6 -6
  16. package/dist/goals.d.ts +43 -0
  17. package/dist/goals.js +37 -0
  18. package/dist/materials/recipes.js +266 -266
  19. package/dist/materials/reference.js +94 -94
  20. package/dist/materials/structure.js +10 -10
  21. package/dist/materials/surface-recipes.js +6 -6
  22. package/dist/prompt.js +74 -74
  23. package/dist/server/executor.d.ts +1 -1
  24. package/dist/server/executor.js +2 -0
  25. package/dist/server/express.js +18 -0
  26. package/dist/server/fixtures/materials/matte-blue.json +14 -14
  27. package/dist/server/fixtures/materials/polished-copper.json +14 -14
  28. package/dist/server/goal-evaluator.d.ts +29 -0
  29. package/dist/server/goal-evaluator.js +55 -0
  30. package/dist/server/index.d.ts +4 -0
  31. package/dist/server/index.js +4 -0
  32. package/dist/server/service.d.ts +17 -0
  33. package/dist/server/service.js +204 -5
  34. package/dist/server/sqlite-store.d.ts +2 -0
  35. package/dist/server/sqlite-store.js +45 -38
  36. package/dist/server/store.d.ts +2 -0
  37. package/dist/server/store.js +12 -3
  38. package/dist/server/types.d.ts +6 -0
  39. package/dist/ui.d.ts +7 -3
  40. package/dist/ui.js +3 -1
  41. package/dist/wompify.d.ts +11 -0
  42. package/dist/wompify.js +11 -2
  43. package/package.json +140 -139
  44. package/dist/sdk-openscad-renderer.d.ts +0 -11
  45. package/dist/sdk-openscad-renderer.js +0 -71
package/dist/ui.d.ts CHANGED
@@ -3,6 +3,7 @@ export { sparkErrorDiagnostics, sparkErrorDiagnosticsSchema, type SparkErrorDiag
3
3
  import type { InferUIMessageChunk, UIMessage } from "ai";
4
4
  import type { SceneScreenshotOptions } from "./capabilities/scene.js";
5
5
  import { z } from "zod";
6
+ export type { SparkGoal, SparkGoalCommand } from "./goals.js";
6
7
  import type { ExecutionReceipt, SparkSkill } from "./capabilities.js";
7
8
  export { DEFAULT_MODEL_ID, getSparkModel, REASONING_EFFORT_LABELS, resolveReasoningEffort, SPARK_MODELS, } from "./models.js";
8
9
  export type { ModelProvider, ReasoningEffort, SparkModel } from "./models.js";
@@ -19,6 +20,7 @@ export type SparkArtifact = {
19
20
  };
20
21
  export type SparkMessageMetadata = {
21
22
  createdAt: string;
23
+ goalContinuation?: boolean;
22
24
  completedAt?: string;
23
25
  durationMs?: number;
24
26
  runId?: string;
@@ -154,14 +156,15 @@ export declare const sparkArtifactSchema: z.ZodObject<{
154
156
  }, z.core.$strip>;
155
157
  export declare const sparkMessageMetadataSchema: z.ZodObject<{
156
158
  createdAt: z.ZodString;
159
+ goalContinuation: z.ZodOptional<z.ZodBoolean>;
157
160
  completedAt: z.ZodOptional<z.ZodString>;
158
161
  durationMs: z.ZodOptional<z.ZodNumber>;
159
162
  runId: z.ZodOptional<z.ZodString>;
160
163
  runStatus: z.ZodOptional<z.ZodEnum<{
164
+ completed: "completed";
161
165
  queued: "queued";
162
166
  running: "running";
163
167
  requires_action: "requires_action";
164
- completed: "completed";
165
168
  failed: "failed";
166
169
  cancelled: "cancelled";
167
170
  incomplete: "incomplete";
@@ -253,10 +256,10 @@ export declare const sparkDataPartSchemas: {
253
256
  readonly "run-status": z.ZodObject<{
254
257
  runId: z.ZodString;
255
258
  status: z.ZodEnum<{
259
+ completed: "completed";
256
260
  queued: "queued";
257
261
  running: "running";
258
262
  requires_action: "requires_action";
259
- completed: "completed";
260
263
  failed: "failed";
261
264
  cancelled: "cancelled";
262
265
  incomplete: "incomplete";
@@ -323,4 +326,5 @@ export declare const sparkDataPartSchemas: {
323
326
  usage: z.ZodOptional<z.ZodUnknown>;
324
327
  }, z.core.$strip>;
325
328
  };
326
- export { parseWompifyCommand, WOMPIFY_PRESETS, wompifyPrompt, type WompifyRequest } from "./wompify.js";
329
+ export { parseWompifyCommand, WOMPIFY_PRESETS, wompifyPrompt, wompifyContext, wompifyContextSchema, type WompifyRequest, type WompifyContext } from "./wompify.js";
330
+ export { parseSparkGoalCommand, DEFAULT_GOAL_CREDITS } from "./goals.js";
package/dist/ui.js CHANGED
@@ -43,6 +43,7 @@ export const sparkArtifactSchema = z.object({
43
43
  });
44
44
  export const sparkMessageMetadataSchema = z.object({
45
45
  createdAt: z.string().datetime(),
46
+ goalContinuation: z.boolean().optional(),
46
47
  completedAt: z.string().datetime().optional(),
47
48
  durationMs: z.number().nonnegative().optional(),
48
49
  runId: z.string().optional(),
@@ -79,4 +80,5 @@ export const sparkDataPartSchemas = {
79
80
  usage: z.unknown().optional(),
80
81
  }),
81
82
  };
82
- export { parseWompifyCommand, WOMPIFY_PRESETS, wompifyPrompt } from "./wompify.js";
83
+ export { parseWompifyCommand, WOMPIFY_PRESETS, wompifyPrompt, wompifyContext, wompifyContextSchema } from "./wompify.js";
84
+ export { parseSparkGoalCommand, DEFAULT_GOAL_CREDITS } from "./goals.js";
package/dist/wompify.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  export declare const WOMPIFY_PRESETS: {
2
3
  readonly simple: {
3
4
  readonly label: "Simple";
@@ -15,6 +16,16 @@ export declare const WOMPIFY_PRESETS: {
15
16
  export type WompifyRequest = {
16
17
  preset: keyof typeof WOMPIFY_PRESETS;
17
18
  };
19
+ export declare const wompifyContextSchema: z.ZodObject<{
20
+ referenceNamePrefix: z.ZodString;
21
+ preset: z.ZodEnum<{
22
+ simple: "simple";
23
+ high: "high";
24
+ ultra: "ultra";
25
+ }>;
26
+ }, z.core.$strip>;
27
+ export type WompifyContext = z.infer<typeof wompifyContextSchema>;
28
+ export declare function wompifyContext(context?: WompifyContext): string | undefined;
18
29
  export declare function wompifyPrompt(preset: WompifyRequest["preset"], referenceName: string, note?: string): string;
19
30
  export declare function parseWompifyCommand(text: string): {
20
31
  preset: WompifyRequest["preset"];
package/dist/wompify.js CHANGED
@@ -1,11 +1,20 @@
1
+ import { z } from "zod";
1
2
  export const WOMPIFY_PRESETS = {
2
3
  simple: { label: "Simple", instructions: "Prioritize the main forms, proportions, silhouettes and colors, with a compact editable construction." },
3
4
  high: { label: "High res", instructions: "Refine both the main forms and smaller characteristic shapes, checking each region from multiple views." },
4
5
  ultra: { label: "Ultra", instructions: "Target the closest practical geometric match, including subtle contours and small modeled details, with thorough close-up comparisons." },
5
6
  };
7
+ export const wompifyContextSchema = z.object({
8
+ referenceNamePrefix: z.string().trim().min(1).max(200),
9
+ preset: z.enum(["simple", "high", "ultra"]),
10
+ });
11
+ export function wompifyContext(context) {
12
+ if (!context)
13
+ return undefined;
14
+ return `Use the mesh-wompify skill for reference name prefix ${JSON.stringify(context.referenceNamePrefix)} at tier ${WOMPIFY_PRESETS[context.preset].label}. Stop if that skill is unavailable.`;
15
+ }
6
16
  export function wompifyPrompt(preset, referenceName, note = "") {
7
- return `Wompify ${JSON.stringify(referenceName)} using the mesh-wompify skill; stop if that skill is unavailable.
8
- Selected tier: ${WOMPIFY_PRESETS[preset].label}.${note.trim() ? `\nUser request: ${note.trim()}` : ""}`;
17
+ return `Wompify ${JSON.stringify(referenceName)} at tier ${WOMPIFY_PRESETS[preset].label}.${note.trim() ? `\n${note.trim()}` : ""}`;
9
18
  }
10
19
  export function parseWompifyCommand(text) {
11
20
  const match = /^\/wompify (simple|high|ultra)(?:\n([\s\S]*))?$/u.exec(text.trim());
package/package.json CHANGED
@@ -1,139 +1,140 @@
1
- {
2
- "name": "@womp/spark-agent",
3
- "version": "5.6.0",
4
- "description": "Portable skills-based AI agent with local and durable chat transports for Womp",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "bin": {
9
- "spark-agent": "dist/cli.js",
10
- "simple-bench": "dist/simple-bench-cli.js",
11
- "agent-run": "dist/agent-run-cli.js"
12
- },
13
- "exports": {
14
- "./browser": {
15
- "types": "./dist/browser.d.ts",
16
- "import": "./dist/browser.js",
17
- "default": "./dist/browser.js"
18
- },
19
- "./capabilities": {
20
- "types": "./dist/capabilities.d.ts",
21
- "import": "./dist/capabilities.js",
22
- "default": "./dist/capabilities.js"
23
- },
24
- "./kakapo": {
25
- "types": "./dist/kakapo.d.ts",
26
- "import": "./dist/kakapo.js",
27
- "default": "./dist/kakapo.js"
28
- },
29
- "./geometry": {
30
- "types": "./dist/geometry.d.ts",
31
- "import": "./dist/geometry.js",
32
- "default": "./dist/geometry.js"
33
- },
34
- "./openscad": {
35
- "types": "./dist/openscad.d.ts",
36
- "import": "./dist/openscad.js",
37
- "default": "./dist/openscad.js"
38
- },
39
- "./quickjs": {
40
- "types": "./dist/quickjs-executor.d.ts",
41
- "import": "./dist/quickjs-executor.js",
42
- "default": "./dist/quickjs-executor.js"
43
- },
44
- ".": {
45
- "types": "./dist/index.d.ts",
46
- "import": "./dist/index.js",
47
- "default": "./dist/index.js"
48
- },
49
- "./ui": {
50
- "types": "./dist/ui.d.ts",
51
- "import": "./dist/ui.js",
52
- "default": "./dist/ui.js"
53
- },
54
- "./client": {
55
- "types": "./dist/client.d.ts",
56
- "import": "./dist/client.js",
57
- "default": "./dist/client.js"
58
- },
59
- "./server": {
60
- "types": "./dist/server/index.d.ts",
61
- "import": "./dist/server/index.js",
62
- "default": "./dist/server/index.js"
63
- },
64
- "./express": {
65
- "types": "./dist/server/express.d.ts",
66
- "import": "./dist/server/express.js",
67
- "default": "./dist/server/express.js"
68
- },
69
- "./package.json": "./package.json"
70
- },
71
- "files": [
72
- "dist/**/*.js",
73
- "dist/**/*.d.ts",
74
- "dist/server/fixtures/**/*.json",
75
- "dist/geometry/schemas/**/*.json",
76
- "README.md"
77
- ],
78
- "sideEffects": false,
79
- "engines": {
80
- "node": ">=22.13"
81
- },
82
- "repository": {
83
- "type": "git",
84
- "url": "git+https://github.com/wompxyz/spark-agent.git"
85
- },
86
- "publishConfig": {
87
- "access": "public"
88
- },
89
- "license": "MIT",
90
- "scripts": {
91
- "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
92
- "build": "yarn clean && node scripts/generate-skill-declarations.mjs && tsc -p tsconfig.json && node scripts/copy-fixtures.mjs",
93
- "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p web/tsconfig.json",
94
- "lint": "yarn typecheck",
95
- "dev": "yarn build && concurrently --kill-others \"yarn dev:server\" \"yarn dev:web\"",
96
- "dev:server": "tsx src/cli.ts",
97
- "simple-bench": "tsx src/simple-bench-cli.ts",
98
- "agent-run": "tsx src/agent-run-cli.ts",
99
- "dev:demo-account": "yarn build && concurrently --kill-others \"yarn dev:server --profile demo-account\" \"yarn dev:web\"",
100
- "dev:web": "vite --config web/vite.config.ts",
101
- "start": "node dist/cli.js",
102
- "web:build": "yarn build && tsc --noEmit -p web/tsconfig.json && vite build --config web/vite.config.ts",
103
- "test": "yarn build && tsx --tsconfig tsconfig.json --test test/**/*.test.ts && node --input-type=module -e \"await Promise.all([import('@womp/spark-agent'), import('@womp/spark-agent/ui'), import('@womp/spark-agent/client'), import('@womp/spark-agent/server'), import('@womp/spark-agent/express'), import('@womp/spark-agent/kakapo'), import('@womp/spark-agent/geometry'), import('@womp/spark-agent/openscad')])\"",
104
- "test:live": "tsx --tsconfig tsconfig.json test/womp-scene-api.live.ts",
105
- "prepack": "yarn build"
106
- },
107
- "dependencies": {
108
- "@ai-sdk/anthropic": "4.0.50",
109
- "@ai-sdk/google": "4.0.69",
110
- "@ai-sdk/openai": "4.0.63",
111
- "@jitl/quickjs-wasmfile-release-sync": "0.32.0",
112
- "@womp/flowir": "0.3.0",
113
- "@womp/kakapo-sdk": "0.7.3",
114
- "ai": "7.0.95",
115
- "eventsource-parser": "^3.0.6",
116
- "express": "^5.2.1",
117
- "lodash": "4.18.1",
118
- "quickjs-emscripten-core": "0.32.0",
119
- "zod": "4.5.4"
120
- },
121
- "devDependencies": {
122
- "@ai-sdk/react": "^4.0.77",
123
- "@types/express": "^5.0.5",
124
- "@types/lodash": "4.17.24",
125
- "@types/node": "^24.0.0",
126
- "@types/react": "^19.2.17",
127
- "@types/react-dom": "^19.2.3",
128
- "@vitejs/plugin-react": "^6.0.4",
129
- "concurrently": "^9.2.1",
130
- "lucide-react": "^1.26.0",
131
- "react": "^19.2.8",
132
- "react-dom": "^19.2.8",
133
- "react-markdown": "^10.1.0",
134
- "remark-gfm": "^4.0.1",
135
- "tsx": "^4.23.1",
136
- "typescript": "^5.9.3",
137
- "vite": "^8.1.5"
138
- }
139
- }
1
+ {
2
+ "name": "@womp/spark-agent",
3
+ "version": "5.7.0",
4
+ "description": "Portable skills-based AI agent with local and durable chat transports for Womp",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "spark-agent": "dist/cli.js",
10
+ "simple-bench": "dist/simple-bench-cli.js",
11
+ "agent-run": "dist/agent-run-cli.js"
12
+ },
13
+ "exports": {
14
+ "./browser": {
15
+ "types": "./dist/browser.d.ts",
16
+ "import": "./dist/browser.js",
17
+ "default": "./dist/browser.js"
18
+ },
19
+ "./capabilities": {
20
+ "types": "./dist/capabilities.d.ts",
21
+ "import": "./dist/capabilities.js",
22
+ "default": "./dist/capabilities.js"
23
+ },
24
+ "./kakapo": {
25
+ "types": "./dist/kakapo.d.ts",
26
+ "import": "./dist/kakapo.js",
27
+ "default": "./dist/kakapo.js"
28
+ },
29
+ "./geometry": {
30
+ "types": "./dist/geometry.d.ts",
31
+ "import": "./dist/geometry.js",
32
+ "default": "./dist/geometry.js"
33
+ },
34
+ "./openscad": {
35
+ "types": "./dist/openscad.d.ts",
36
+ "import": "./dist/openscad.js",
37
+ "default": "./dist/openscad.js"
38
+ },
39
+ "./quickjs": {
40
+ "types": "./dist/quickjs-executor.d.ts",
41
+ "import": "./dist/quickjs-executor.js",
42
+ "default": "./dist/quickjs-executor.js"
43
+ },
44
+ ".": {
45
+ "types": "./dist/index.d.ts",
46
+ "import": "./dist/index.js",
47
+ "default": "./dist/index.js"
48
+ },
49
+ "./ui": {
50
+ "types": "./dist/ui.d.ts",
51
+ "import": "./dist/ui.js",
52
+ "default": "./dist/ui.js"
53
+ },
54
+ "./client": {
55
+ "types": "./dist/client.d.ts",
56
+ "import": "./dist/client.js",
57
+ "default": "./dist/client.js"
58
+ },
59
+ "./server": {
60
+ "types": "./dist/server/index.d.ts",
61
+ "import": "./dist/server/index.js",
62
+ "default": "./dist/server/index.js"
63
+ },
64
+ "./express": {
65
+ "types": "./dist/server/express.d.ts",
66
+ "import": "./dist/server/express.js",
67
+ "default": "./dist/server/express.js"
68
+ },
69
+ "./package.json": "./package.json"
70
+ },
71
+ "files": [
72
+ "dist/**/*.js",
73
+ "dist/**/*.d.ts",
74
+ "dist/server/fixtures/**/*.json",
75
+ "dist/geometry/schemas/**/*.json",
76
+ "README.md"
77
+ ],
78
+ "sideEffects": false,
79
+ "engines": {
80
+ "node": ">=22.13"
81
+ },
82
+ "repository": {
83
+ "type": "git",
84
+ "url": "git+https://github.com/wompxyz/spark-agent.git"
85
+ },
86
+ "publishConfig": {
87
+ "access": "public"
88
+ },
89
+ "license": "MIT",
90
+ "scripts": {
91
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
92
+ "build": "yarn clean && node scripts/generate-skill-declarations.mjs && tsc -p tsconfig.json && node scripts/copy-fixtures.mjs",
93
+ "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p web/tsconfig.json",
94
+ "lint": "yarn typecheck",
95
+ "dev": "yarn build && concurrently --kill-others \"yarn dev:server\" \"yarn dev:web\"",
96
+ "dev:server": "tsx src/cli.ts",
97
+ "simple-bench": "tsx src/simple-bench-cli.ts",
98
+ "agent-run": "tsx src/agent-run-cli.ts",
99
+ "dev:demo-account": "yarn build && concurrently --kill-others \"yarn dev:server --profile demo-account\" \"yarn dev:web\"",
100
+ "dev:web": "vite --config web/vite.config.ts",
101
+ "start": "node dist/cli.js",
102
+ "web:build": "yarn build && tsc --noEmit -p web/tsconfig.json && vite build --config web/vite.config.ts",
103
+ "test": "yarn build && tsx --tsconfig tsconfig.json --test test/**/*.test.ts && node --input-type=module -e \"await Promise.all([import('@womp/spark-agent'), import('@womp/spark-agent/ui'), import('@womp/spark-agent/client'), import('@womp/spark-agent/server'), import('@womp/spark-agent/express'), import('@womp/spark-agent/kakapo'), import('@womp/spark-agent/geometry'), import('@womp/spark-agent/openscad')])\"",
104
+ "test:live": "tsx --tsconfig tsconfig.json test/womp-scene-api.live.ts",
105
+ "prepack": "yarn build",
106
+ "release:pack": "node scripts/npm-release.mjs pack"
107
+ },
108
+ "dependencies": {
109
+ "@ai-sdk/anthropic": "4.0.50",
110
+ "@ai-sdk/google": "4.0.69",
111
+ "@ai-sdk/openai": "4.0.63",
112
+ "@jitl/quickjs-wasmfile-release-sync": "0.32.0",
113
+ "@womp/flowir": "0.3.0",
114
+ "@womp/kakapo-sdk": "0.7.3",
115
+ "ai": "7.0.95",
116
+ "eventsource-parser": "^3.0.6",
117
+ "express": "^5.2.1",
118
+ "lodash": "4.18.1",
119
+ "quickjs-emscripten-core": "0.32.0",
120
+ "zod": "4.5.4"
121
+ },
122
+ "devDependencies": {
123
+ "@ai-sdk/react": "^4.0.77",
124
+ "@types/express": "^5.0.5",
125
+ "@types/lodash": "4.17.24",
126
+ "@types/node": "^24.0.0",
127
+ "@types/react": "^19.2.17",
128
+ "@types/react-dom": "^19.2.3",
129
+ "@vitejs/plugin-react": "^6.0.4",
130
+ "concurrently": "^9.2.1",
131
+ "lucide-react": "^1.26.0",
132
+ "react": "^19.2.8",
133
+ "react-dom": "^19.2.8",
134
+ "react-markdown": "^10.1.0",
135
+ "remark-gfm": "^4.0.1",
136
+ "tsx": "^4.23.1",
137
+ "typescript": "^5.9.3",
138
+ "vite": "^8.1.5"
139
+ }
140
+ }
@@ -1,11 +0,0 @@
1
- import type { KakapoAPI } from "@womp/kakapo-sdk";
2
- import type { OpenScadBoundingBox } from "./openscad.js";
3
- export declare function waitForOpenScadRenderer(options: {
4
- api: KakapoAPI;
5
- objectId: number;
6
- expectedBounds: OpenScadBoundingBox;
7
- baselineBounds?: OpenScadBoundingBox;
8
- signal: AbortSignal;
9
- timeoutMs?: number;
10
- pollIntervalMs?: number;
11
- }): Promise<boolean>;
@@ -1,71 +0,0 @@
1
- const OPENSCAD_RENDERER_WAIT_MS = 15_000;
2
- const OPENSCAD_RENDERER_POLL_MS = 250;
3
- function boundsMatch(actual, expected) {
4
- const size = Math.max(expected.max.x - expected.min.x, expected.max.y - expected.min.y, expected.max.z - expected.min.z);
5
- const tolerance = Math.max(size * 0.0001, 0.001);
6
- return ["min", "max"].every((edge) => ["x", "y", "z"].every((axis) => Math.abs(actual[edge][axis] - expected[edge][axis]) <= tolerance));
7
- }
8
- function getBoundsBeforeDeadline(options) {
9
- const remaining = options.deadline - Date.now();
10
- if (remaining <= 0)
11
- return Promise.resolve(undefined);
12
- options.signal.throwIfAborted();
13
- return new Promise((resolve, reject) => {
14
- let settled = false;
15
- const finish = (action) => {
16
- if (settled)
17
- return;
18
- settled = true;
19
- clearTimeout(timeout);
20
- options.signal.removeEventListener("abort", onAbort);
21
- action();
22
- };
23
- const onAbort = () => finish(() => reject(options.signal.reason ?? new Error("The operation was aborted.")));
24
- const timeout = setTimeout(() => finish(() => resolve(undefined)), remaining);
25
- options.signal.addEventListener("abort", onAbort, { once: true });
26
- if (options.signal.aborted) {
27
- onAbort();
28
- return;
29
- }
30
- void options.api.getNodeBoundingBox(options.objectId).then((bounds) => finish(() => resolve(bounds)), () => finish(() => resolve(undefined)));
31
- });
32
- }
33
- function waitForPoll(signal, milliseconds) {
34
- signal.throwIfAborted();
35
- return new Promise((resolve, reject) => {
36
- const onAbort = () => {
37
- clearTimeout(timeout);
38
- reject(signal.reason ?? new Error("The operation was aborted."));
39
- };
40
- const timeout = setTimeout(() => {
41
- signal.removeEventListener("abort", onAbort);
42
- resolve();
43
- }, milliseconds);
44
- signal.addEventListener("abort", onAbort, { once: true });
45
- if (signal.aborted)
46
- onAbort();
47
- });
48
- }
49
- export async function waitForOpenScadRenderer(options) {
50
- const deadline = Date.now() + (options.timeoutMs ?? OPENSCAD_RENDERER_WAIT_MS);
51
- if (options.baselineBounds !== undefined &&
52
- boundsMatch(options.baselineBounds, options.expectedBounds))
53
- return false;
54
- do {
55
- const actual = await getBoundsBeforeDeadline({
56
- api: options.api,
57
- objectId: options.objectId,
58
- signal: options.signal,
59
- deadline,
60
- });
61
- options.signal.throwIfAborted();
62
- if (Date.now() >= deadline)
63
- return false;
64
- if (actual !== undefined && boundsMatch(actual, options.expectedBounds))
65
- return true;
66
- const remaining = deadline - Date.now();
67
- if (remaining <= 0)
68
- return false;
69
- await waitForPoll(options.signal, Math.min(options.pollIntervalMs ?? OPENSCAD_RENDERER_POLL_MS, remaining));
70
- } while (true);
71
- }