@selvajs/compute 4.0.0-beta.0 → 4.0.0-beta.3
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 +7 -3
- package/dist/chunk-AYH5O3VG.js +4 -0
- package/dist/chunk-AYH5O3VG.js.map +1 -0
- package/dist/chunk-MLPWPV6F.cjs +4 -0
- package/dist/chunk-MLPWPV6F.cjs.map +1 -0
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +81 -56
- package/dist/core.d.ts +81 -56
- package/dist/core.js +1 -1
- package/dist/grasshopper.cjs +1 -1
- package/dist/grasshopper.cjs.map +1 -1
- package/dist/grasshopper.d.cts +400 -81
- package/dist/grasshopper.d.ts +400 -81
- package/dist/grasshopper.js +1 -1
- package/dist/grasshopper.js.map +1 -1
- package/dist/handle-files-DMK9bCOW.d.cts +231 -0
- package/dist/handle-files-DMK9bCOW.d.ts +231 -0
- package/dist/index.cjs +1 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +0 -1
- package/package.json +1 -1
- package/dist/chunk-G7NVQAK5.cjs +0 -2
- package/dist/chunk-G7NVQAK5.cjs.map +0 -1
- package/dist/chunk-LLUNR66G.cjs +0 -4
- package/dist/chunk-LLUNR66G.cjs.map +0 -1
- package/dist/chunk-RFFCVRKM.js +0 -2
- package/dist/chunk-RFFCVRKM.js.map +0 -1
- package/dist/chunk-XT3XWDDV.js +0 -4
- package/dist/chunk-XT3XWDDV.js.map +0 -1
- package/dist/handle-files-DcA24IkS.d.cts +0 -478
- package/dist/handle-files-DcA24IkS.d.ts +0 -478
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
declare const ErrorCodes: {
|
|
2
|
+
readonly NETWORK_ERROR: "NETWORK_ERROR";
|
|
3
|
+
readonly AUTH_ERROR: "AUTH_ERROR";
|
|
4
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
5
|
+
readonly COMPUTATION_ERROR: "COMPUTATION_ERROR";
|
|
6
|
+
readonly TIMEOUT_ERROR: "TIMEOUT_ERROR";
|
|
7
|
+
readonly CORS_ERROR: "CORS_ERROR";
|
|
8
|
+
/** HTTP 404 — the endpoint path does not exist on the server (usually a typo'd route or wrong server). Never retried. */
|
|
9
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
10
|
+
/** HTTP 429 — the server is rate-limiting requests. Retried by default (honors `Retry-After`); see `RetryPolicy.retryOn429`. */
|
|
11
|
+
readonly RATE_LIMIT: "RATE_LIMIT";
|
|
12
|
+
/**
|
|
13
|
+
* The server answered 2xx but the body is deterministically not JSON (the
|
|
14
|
+
* response declared a non-JSON `Content-Type`, e.g. an HTML captive-portal or
|
|
15
|
+
* proxy login page, or a misconfigured endpoint). Never retried — refetching
|
|
16
|
+
* returns the same page.
|
|
17
|
+
*/
|
|
18
|
+
readonly INVALID_RESPONSE: "INVALID_RESPONSE";
|
|
19
|
+
readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
|
|
20
|
+
readonly INVALID_STATE: "INVALID_STATE";
|
|
21
|
+
readonly INVALID_INPUT: "INVALID_INPUT";
|
|
22
|
+
readonly INVALID_CONFIG: "INVALID_CONFIG";
|
|
23
|
+
readonly BROWSER_ONLY: "BROWSER_ONLY";
|
|
24
|
+
readonly ENVIRONMENT_ERROR: "ENVIRONMENT_ERROR";
|
|
25
|
+
readonly ENCODING_ERROR: "ENCODING_ERROR";
|
|
26
|
+
/** An input's `default` had a shape the normalizer didn't recognize (no innerTree key). */
|
|
27
|
+
readonly MALFORMED_DEFAULT: "MALFORMED_DEFAULT";
|
|
28
|
+
/** Scheduler latest-wins: this call was replaced by a newer one. */
|
|
29
|
+
readonly SUPERSEDED: "SUPERSEDED";
|
|
30
|
+
/** Scheduler / caller-supplied AbortSignal: this call was aborted. */
|
|
31
|
+
readonly ABORTED: "ABORTED";
|
|
32
|
+
/**
|
|
33
|
+
* Scheduler backpressure: the queue was already at `maxQueueDepth` when this
|
|
34
|
+
* call arrived, so it was rejected immediately rather than queued. Retryable — the
|
|
35
|
+
* caller (or an HTTP layer, as 503 + Retry-After) should back off and retry.
|
|
36
|
+
* The error `context` carries `{ queueDepth, maxQueueDepth }`.
|
|
37
|
+
*/
|
|
38
|
+
readonly QUEUE_FULL: "QUEUE_FULL";
|
|
39
|
+
/**
|
|
40
|
+
* Scheduler backpressure: this call sat queued longer than `queueWaitMs`
|
|
41
|
+
* without starting, so it was rejected before wasting compute on a stale request.
|
|
42
|
+
* Retryable. The error `context` carries `{ waitedMs, queueWaitMs }`.
|
|
43
|
+
*/
|
|
44
|
+
readonly QUEUE_TIMEOUT: "QUEUE_TIMEOUT";
|
|
45
|
+
/**
|
|
46
|
+
* A solve referenced a definition by `pointer` (server-side cache key), but the
|
|
47
|
+
* server no longer holds that definition (evicted / GC'd / a different child in
|
|
48
|
+
* the pool / server restarted). The caller should retry with the full
|
|
49
|
+
* definition. Surfaced when the server tags its error body with
|
|
50
|
+
* `code: "definition_not_cached"`, so it survives production message-scrubbing.
|
|
51
|
+
*/
|
|
52
|
+
readonly DEFINITION_NOT_CACHED: "DEFINITION_NOT_CACHED";
|
|
53
|
+
};
|
|
54
|
+
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
55
|
+
/**
|
|
56
|
+
* Simplified error for Rhino Compute operations
|
|
57
|
+
*
|
|
58
|
+
* @public Use this for error handling with error codes and context.
|
|
59
|
+
*/
|
|
60
|
+
declare class ComputeError extends Error {
|
|
61
|
+
readonly code: ErrorCode;
|
|
62
|
+
readonly statusCode?: number;
|
|
63
|
+
readonly context?: Record<string, unknown>;
|
|
64
|
+
readonly originalError?: Error;
|
|
65
|
+
constructor(message: string, code?: ErrorCode, options?: {
|
|
66
|
+
statusCode?: number;
|
|
67
|
+
context?: Record<string, unknown>;
|
|
68
|
+
originalError?: Error;
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Create an error for missing/empty values
|
|
72
|
+
*/
|
|
73
|
+
static missingValues(inputName: string, expectedType?: string, context?: Record<string, unknown>): ComputeError;
|
|
74
|
+
/**
|
|
75
|
+
* Create an error for unknown parameter type
|
|
76
|
+
*/
|
|
77
|
+
static unknownParamType(paramType: string, paramName?: string, context?: Record<string, unknown>): ComputeError;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Backend wire code (the JSON error body's `code` field) → one of our
|
|
82
|
+
* {@link ErrorCodes}. An unlisted code falls back to the status-based mapping.
|
|
83
|
+
*/
|
|
84
|
+
type ServerErrorCodeMap = Record<string, ErrorCode>;
|
|
85
|
+
interface RetryPolicy {
|
|
86
|
+
/** Maximum number of retry attempts after the initial request (default: 0). */
|
|
87
|
+
attempts?: number;
|
|
88
|
+
/** Base delay in milliseconds for exponential backoff (default: 500). */
|
|
89
|
+
baseDelayMs?: number;
|
|
90
|
+
/** Upper bound for backoff delay (default: 30_000). */
|
|
91
|
+
maxDelayMs?: number;
|
|
92
|
+
/** Whether to retry on 429 responses (default: true — honors Retry-After). */
|
|
93
|
+
retryOn429?: boolean;
|
|
94
|
+
}
|
|
95
|
+
interface ComputeConfig {
|
|
96
|
+
serverUrl: string;
|
|
97
|
+
/** Optional API key for authenticating with the server. Sent as {@link apiKeyHeader}. */
|
|
98
|
+
apiKey?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Header name carrying `apiKey`. Defaults to `'RhinoComputeKey'` — the name
|
|
101
|
+
* rhino.compute expects. A different backend sets its own.
|
|
102
|
+
*/
|
|
103
|
+
apiKeyHeader?: string;
|
|
104
|
+
/** Optional Bearer token for authentication (e.g., when behind a proxy or API gateway) */
|
|
105
|
+
authToken?: string;
|
|
106
|
+
headers?: Record<string, string>;
|
|
107
|
+
/** Enable debug logging to the console */
|
|
108
|
+
debug?: boolean;
|
|
109
|
+
/** Suppress browser security warnings in the console */
|
|
110
|
+
suppressBrowserWarning?: boolean;
|
|
111
|
+
timeoutMs?: number;
|
|
112
|
+
/**
|
|
113
|
+
* Retry policy for transient errors. Default: no retries.
|
|
114
|
+
*/
|
|
115
|
+
retry?: RetryPolicy;
|
|
116
|
+
/**
|
|
117
|
+
* Optional caller-supplied AbortSignal. Composes with the internal timeout —
|
|
118
|
+
* whichever fires first wins. Lets callers cancel in-flight requests
|
|
119
|
+
* (e.g. on component unmount or when superseding a stale solve).
|
|
120
|
+
*/
|
|
121
|
+
signal?: AbortSignal;
|
|
122
|
+
/**
|
|
123
|
+
* Machine-readable error codes this backend tags onto its error bodies, mapped
|
|
124
|
+
* to our {@link ErrorCodes}. A code here outranks the status-based mapping.
|
|
125
|
+
* Core knows no backend's codes — the client supplies its own table.
|
|
126
|
+
*/
|
|
127
|
+
serverErrorCodes?: ServerErrorCodeMap;
|
|
128
|
+
onServerTiming?: (timing: ServerTiming, requestId: string) => void;
|
|
129
|
+
}
|
|
130
|
+
interface ServerTiming {
|
|
131
|
+
decode?: number;
|
|
132
|
+
solve?: number;
|
|
133
|
+
encode?: number;
|
|
134
|
+
raw: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* By-reference definition form for solves.
|
|
139
|
+
*
|
|
140
|
+
* Lets a caller that already knows a definition's identity (e.g. a stored
|
|
141
|
+
* version's UUID) schedule solves without materializing the multi-MB bytes:
|
|
142
|
+
* cache keys and the server-pointer map are derived from `key` alone, and
|
|
143
|
+
* `load()` is only called when an upload is genuinely unavoidable (first solve
|
|
144
|
+
* of a definition, or a server-side pointer miss).
|
|
145
|
+
*/
|
|
146
|
+
/**
|
|
147
|
+
* A definition identified by a stable key, with bytes materialized on demand.
|
|
148
|
+
*
|
|
149
|
+
* **Immutability contract — read this before constructing one.** `key` must
|
|
150
|
+
* identify IMMUTABLE bytes: every `load()` for a given `key` must return the
|
|
151
|
+
* same content, forever. All caching (the scheduler's result cache, the
|
|
152
|
+
* server-pointer map, and any durable cache built on these keys) trusts the
|
|
153
|
+
* key as the definition's identity WITHOUT looking at the bytes. If two
|
|
154
|
+
* different byte contents ever share a key, cached solves from one are served
|
|
155
|
+
* for the other — silent cache poisoning with no diagnostic. Use an identity
|
|
156
|
+
* that can never be reused for different content (e.g. a version UUID), never
|
|
157
|
+
* a mutable name or path.
|
|
158
|
+
*/
|
|
159
|
+
interface DefinitionRef {
|
|
160
|
+
/**
|
|
161
|
+
* Identity of immutable bytes (e.g. a version UUID). Two different byte
|
|
162
|
+
* contents must never share a key — cache poisoning otherwise.
|
|
163
|
+
*/
|
|
164
|
+
key: string;
|
|
165
|
+
/**
|
|
166
|
+
* Materialize the bytes. Called ONLY when an upload is unavoidable — inside
|
|
167
|
+
* the solve execution, so it counts toward the solve's abort semantics.
|
|
168
|
+
*/
|
|
169
|
+
load: () => Promise<Uint8Array>;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Every definition form accepted by the solve entry points:
|
|
173
|
+
* - a URL, base64 string, or plain string (content-hashed for caching)
|
|
174
|
+
* - raw `.gh` bytes (content-hashed)
|
|
175
|
+
* - a {@link DefinitionRef} (identity-keyed; bytes loaded lazily)
|
|
176
|
+
*/
|
|
177
|
+
type SolveDefinition = string | Uint8Array | DefinitionRef;
|
|
178
|
+
/** Narrow a {@link SolveDefinition} to the by-reference form. */
|
|
179
|
+
declare function isDefinitionRef(definition: SolveDefinition): definition is DefinitionRef;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Raw file data from Grasshopper/Rhino Compute response, with metadata for processing.
|
|
183
|
+
* Files are typically combined with additional files and packaged into a ZIP archive.
|
|
184
|
+
* @see {@link extractFilesFromComputeResponse} for extraction from compute responses
|
|
185
|
+
*/
|
|
186
|
+
type FileData = {
|
|
187
|
+
/** Base filename without extension (e.g., "model") */
|
|
188
|
+
fileName: string;
|
|
189
|
+
/** File content, base64-encoded or plain string depending on isBase64Encoded flag */
|
|
190
|
+
data: string;
|
|
191
|
+
/** File extension including the dot (e.g., ".3dm", ".json"). Appended to fileName to create the full filename */
|
|
192
|
+
fileType: string;
|
|
193
|
+
/** Whether data is base64-encoded. If true, must be decoded to binary before use */
|
|
194
|
+
isBase64Encoded: boolean;
|
|
195
|
+
/** Directory path for archive organization (e.g., "subfolder/nested"). Empty string for root-level files */
|
|
196
|
+
subFolder: string;
|
|
197
|
+
/** Arbitrary metadata attached in Grasshopper. Not interpreted by compute; passed through for downstream consumers. May be absent on older payloads */
|
|
198
|
+
metadata?: Record<string, string>;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Normalized file ready for consumption or archival.
|
|
202
|
+
* Unified intermediate format from FileData or FileBaseInfo, ready to be packaged into archives or returned to callers.
|
|
203
|
+
*/
|
|
204
|
+
type ProcessedFile = {
|
|
205
|
+
/** Full filename including extension (e.g., "model.3dm") */
|
|
206
|
+
fileName: string;
|
|
207
|
+
/** File content as binary data (Uint8Array for decoded base64 or fetched binary) or text */
|
|
208
|
+
content: Uint8Array | string;
|
|
209
|
+
/** File path for archive organization (e.g., "subfolder/model.3dm") */
|
|
210
|
+
path: string;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Reference to an external file to be fetched and included in file operations.
|
|
214
|
+
* Specifies additional files (beyond compute response files) to fetch and process as ProcessedFile.
|
|
215
|
+
* @see {@link fetchRemoteFiles} for how FileBaseInfo is fetched and converted
|
|
216
|
+
*/
|
|
217
|
+
type FileBaseInfo = {
|
|
218
|
+
/** Destination filename for the file in the archive or result set (e.g., "additional-data.json") */
|
|
219
|
+
fileName: string;
|
|
220
|
+
/** URL to fetch the file from. Must be accessible from the runtime environment */
|
|
221
|
+
filePath: string;
|
|
222
|
+
/** Optional directory path for archive organization (e.g., "extras/docs"). When omitted, file lands at archive root */
|
|
223
|
+
subFolder?: string;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/** Extracts and processes files from compute response data without downloading them. */
|
|
227
|
+
declare const extractFilesFromComputeResponse: (downloadableFiles: FileData[], additionalFiles?: FileBaseInfo[] | FileBaseInfo | null) => Promise<ProcessedFile[]>;
|
|
228
|
+
/** Downloads files from a compute response as a ZIP archive. */
|
|
229
|
+
declare const downloadFileData: (downloadableFiles: FileData[], fileFoldername: string, additionalFiles?: FileBaseInfo[] | FileBaseInfo | null) => Promise<void>;
|
|
230
|
+
|
|
231
|
+
export { type ComputeConfig as C, type DefinitionRef as D, type ErrorCode as E, type FileBaseInfo as F, type ProcessedFile as P, type RetryPolicy as R, type ServerErrorCodeMap as S, ComputeError as a, ErrorCodes as b, type FileData as c, type ServerTiming as d, type SolveDefinition as e, downloadFileData as f, extractFilesFromComputeResponse as g, isDefinitionRef as i };
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
declare const ErrorCodes: {
|
|
2
|
+
readonly NETWORK_ERROR: "NETWORK_ERROR";
|
|
3
|
+
readonly AUTH_ERROR: "AUTH_ERROR";
|
|
4
|
+
readonly VALIDATION_ERROR: "VALIDATION_ERROR";
|
|
5
|
+
readonly COMPUTATION_ERROR: "COMPUTATION_ERROR";
|
|
6
|
+
readonly TIMEOUT_ERROR: "TIMEOUT_ERROR";
|
|
7
|
+
readonly CORS_ERROR: "CORS_ERROR";
|
|
8
|
+
/** HTTP 404 — the endpoint path does not exist on the server (usually a typo'd route or wrong server). Never retried. */
|
|
9
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
10
|
+
/** HTTP 429 — the server is rate-limiting requests. Retried by default (honors `Retry-After`); see `RetryPolicy.retryOn429`. */
|
|
11
|
+
readonly RATE_LIMIT: "RATE_LIMIT";
|
|
12
|
+
/**
|
|
13
|
+
* The server answered 2xx but the body is deterministically not JSON (the
|
|
14
|
+
* response declared a non-JSON `Content-Type`, e.g. an HTML captive-portal or
|
|
15
|
+
* proxy login page, or a misconfigured endpoint). Never retried — refetching
|
|
16
|
+
* returns the same page.
|
|
17
|
+
*/
|
|
18
|
+
readonly INVALID_RESPONSE: "INVALID_RESPONSE";
|
|
19
|
+
readonly UNKNOWN_ERROR: "UNKNOWN_ERROR";
|
|
20
|
+
readonly INVALID_STATE: "INVALID_STATE";
|
|
21
|
+
readonly INVALID_INPUT: "INVALID_INPUT";
|
|
22
|
+
readonly INVALID_CONFIG: "INVALID_CONFIG";
|
|
23
|
+
readonly BROWSER_ONLY: "BROWSER_ONLY";
|
|
24
|
+
readonly ENVIRONMENT_ERROR: "ENVIRONMENT_ERROR";
|
|
25
|
+
readonly ENCODING_ERROR: "ENCODING_ERROR";
|
|
26
|
+
/** An input's `default` had a shape the normalizer didn't recognize (no innerTree key). */
|
|
27
|
+
readonly MALFORMED_DEFAULT: "MALFORMED_DEFAULT";
|
|
28
|
+
/** Scheduler latest-wins: this call was replaced by a newer one. */
|
|
29
|
+
readonly SUPERSEDED: "SUPERSEDED";
|
|
30
|
+
/** Scheduler / caller-supplied AbortSignal: this call was aborted. */
|
|
31
|
+
readonly ABORTED: "ABORTED";
|
|
32
|
+
/**
|
|
33
|
+
* Scheduler backpressure: the queue was already at `maxQueueDepth` when this
|
|
34
|
+
* call arrived, so it was rejected immediately rather than queued. Retryable — the
|
|
35
|
+
* caller (or an HTTP layer, as 503 + Retry-After) should back off and retry.
|
|
36
|
+
* The error `context` carries `{ queueDepth, maxQueueDepth }`.
|
|
37
|
+
*/
|
|
38
|
+
readonly QUEUE_FULL: "QUEUE_FULL";
|
|
39
|
+
/**
|
|
40
|
+
* Scheduler backpressure: this call sat queued longer than `queueWaitMs`
|
|
41
|
+
* without starting, so it was rejected before wasting compute on a stale request.
|
|
42
|
+
* Retryable. The error `context` carries `{ waitedMs, queueWaitMs }`.
|
|
43
|
+
*/
|
|
44
|
+
readonly QUEUE_TIMEOUT: "QUEUE_TIMEOUT";
|
|
45
|
+
/**
|
|
46
|
+
* A solve referenced a definition by `pointer` (server-side cache key), but the
|
|
47
|
+
* server no longer holds that definition (evicted / GC'd / a different child in
|
|
48
|
+
* the pool / server restarted). The caller should retry with the full
|
|
49
|
+
* definition. Surfaced when the server tags its error body with
|
|
50
|
+
* `code: "definition_not_cached"`, so it survives production message-scrubbing.
|
|
51
|
+
*/
|
|
52
|
+
readonly DEFINITION_NOT_CACHED: "DEFINITION_NOT_CACHED";
|
|
53
|
+
};
|
|
54
|
+
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
55
|
+
/**
|
|
56
|
+
* Simplified error for Rhino Compute operations
|
|
57
|
+
*
|
|
58
|
+
* @public Use this for error handling with error codes and context.
|
|
59
|
+
*/
|
|
60
|
+
declare class ComputeError extends Error {
|
|
61
|
+
readonly code: ErrorCode;
|
|
62
|
+
readonly statusCode?: number;
|
|
63
|
+
readonly context?: Record<string, unknown>;
|
|
64
|
+
readonly originalError?: Error;
|
|
65
|
+
constructor(message: string, code?: ErrorCode, options?: {
|
|
66
|
+
statusCode?: number;
|
|
67
|
+
context?: Record<string, unknown>;
|
|
68
|
+
originalError?: Error;
|
|
69
|
+
});
|
|
70
|
+
/**
|
|
71
|
+
* Create an error for missing/empty values
|
|
72
|
+
*/
|
|
73
|
+
static missingValues(inputName: string, expectedType?: string, context?: Record<string, unknown>): ComputeError;
|
|
74
|
+
/**
|
|
75
|
+
* Create an error for unknown parameter type
|
|
76
|
+
*/
|
|
77
|
+
static unknownParamType(paramType: string, paramName?: string, context?: Record<string, unknown>): ComputeError;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Backend wire code (the JSON error body's `code` field) → one of our
|
|
82
|
+
* {@link ErrorCodes}. An unlisted code falls back to the status-based mapping.
|
|
83
|
+
*/
|
|
84
|
+
type ServerErrorCodeMap = Record<string, ErrorCode>;
|
|
85
|
+
interface RetryPolicy {
|
|
86
|
+
/** Maximum number of retry attempts after the initial request (default: 0). */
|
|
87
|
+
attempts?: number;
|
|
88
|
+
/** Base delay in milliseconds for exponential backoff (default: 500). */
|
|
89
|
+
baseDelayMs?: number;
|
|
90
|
+
/** Upper bound for backoff delay (default: 30_000). */
|
|
91
|
+
maxDelayMs?: number;
|
|
92
|
+
/** Whether to retry on 429 responses (default: true — honors Retry-After). */
|
|
93
|
+
retryOn429?: boolean;
|
|
94
|
+
}
|
|
95
|
+
interface ComputeConfig {
|
|
96
|
+
serverUrl: string;
|
|
97
|
+
/** Optional API key for authenticating with the server. Sent as {@link apiKeyHeader}. */
|
|
98
|
+
apiKey?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Header name carrying `apiKey`. Defaults to `'RhinoComputeKey'` — the name
|
|
101
|
+
* rhino.compute expects. A different backend sets its own.
|
|
102
|
+
*/
|
|
103
|
+
apiKeyHeader?: string;
|
|
104
|
+
/** Optional Bearer token for authentication (e.g., when behind a proxy or API gateway) */
|
|
105
|
+
authToken?: string;
|
|
106
|
+
headers?: Record<string, string>;
|
|
107
|
+
/** Enable debug logging to the console */
|
|
108
|
+
debug?: boolean;
|
|
109
|
+
/** Suppress browser security warnings in the console */
|
|
110
|
+
suppressBrowserWarning?: boolean;
|
|
111
|
+
timeoutMs?: number;
|
|
112
|
+
/**
|
|
113
|
+
* Retry policy for transient errors. Default: no retries.
|
|
114
|
+
*/
|
|
115
|
+
retry?: RetryPolicy;
|
|
116
|
+
/**
|
|
117
|
+
* Optional caller-supplied AbortSignal. Composes with the internal timeout —
|
|
118
|
+
* whichever fires first wins. Lets callers cancel in-flight requests
|
|
119
|
+
* (e.g. on component unmount or when superseding a stale solve).
|
|
120
|
+
*/
|
|
121
|
+
signal?: AbortSignal;
|
|
122
|
+
/**
|
|
123
|
+
* Machine-readable error codes this backend tags onto its error bodies, mapped
|
|
124
|
+
* to our {@link ErrorCodes}. A code here outranks the status-based mapping.
|
|
125
|
+
* Core knows no backend's codes — the client supplies its own table.
|
|
126
|
+
*/
|
|
127
|
+
serverErrorCodes?: ServerErrorCodeMap;
|
|
128
|
+
onServerTiming?: (timing: ServerTiming, requestId: string) => void;
|
|
129
|
+
}
|
|
130
|
+
interface ServerTiming {
|
|
131
|
+
decode?: number;
|
|
132
|
+
solve?: number;
|
|
133
|
+
encode?: number;
|
|
134
|
+
raw: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* By-reference definition form for solves.
|
|
139
|
+
*
|
|
140
|
+
* Lets a caller that already knows a definition's identity (e.g. a stored
|
|
141
|
+
* version's UUID) schedule solves without materializing the multi-MB bytes:
|
|
142
|
+
* cache keys and the server-pointer map are derived from `key` alone, and
|
|
143
|
+
* `load()` is only called when an upload is genuinely unavoidable (first solve
|
|
144
|
+
* of a definition, or a server-side pointer miss).
|
|
145
|
+
*/
|
|
146
|
+
/**
|
|
147
|
+
* A definition identified by a stable key, with bytes materialized on demand.
|
|
148
|
+
*
|
|
149
|
+
* **Immutability contract — read this before constructing one.** `key` must
|
|
150
|
+
* identify IMMUTABLE bytes: every `load()` for a given `key` must return the
|
|
151
|
+
* same content, forever. All caching (the scheduler's result cache, the
|
|
152
|
+
* server-pointer map, and any durable cache built on these keys) trusts the
|
|
153
|
+
* key as the definition's identity WITHOUT looking at the bytes. If two
|
|
154
|
+
* different byte contents ever share a key, cached solves from one are served
|
|
155
|
+
* for the other — silent cache poisoning with no diagnostic. Use an identity
|
|
156
|
+
* that can never be reused for different content (e.g. a version UUID), never
|
|
157
|
+
* a mutable name or path.
|
|
158
|
+
*/
|
|
159
|
+
interface DefinitionRef {
|
|
160
|
+
/**
|
|
161
|
+
* Identity of immutable bytes (e.g. a version UUID). Two different byte
|
|
162
|
+
* contents must never share a key — cache poisoning otherwise.
|
|
163
|
+
*/
|
|
164
|
+
key: string;
|
|
165
|
+
/**
|
|
166
|
+
* Materialize the bytes. Called ONLY when an upload is unavoidable — inside
|
|
167
|
+
* the solve execution, so it counts toward the solve's abort semantics.
|
|
168
|
+
*/
|
|
169
|
+
load: () => Promise<Uint8Array>;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Every definition form accepted by the solve entry points:
|
|
173
|
+
* - a URL, base64 string, or plain string (content-hashed for caching)
|
|
174
|
+
* - raw `.gh` bytes (content-hashed)
|
|
175
|
+
* - a {@link DefinitionRef} (identity-keyed; bytes loaded lazily)
|
|
176
|
+
*/
|
|
177
|
+
type SolveDefinition = string | Uint8Array | DefinitionRef;
|
|
178
|
+
/** Narrow a {@link SolveDefinition} to the by-reference form. */
|
|
179
|
+
declare function isDefinitionRef(definition: SolveDefinition): definition is DefinitionRef;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Raw file data from Grasshopper/Rhino Compute response, with metadata for processing.
|
|
183
|
+
* Files are typically combined with additional files and packaged into a ZIP archive.
|
|
184
|
+
* @see {@link extractFilesFromComputeResponse} for extraction from compute responses
|
|
185
|
+
*/
|
|
186
|
+
type FileData = {
|
|
187
|
+
/** Base filename without extension (e.g., "model") */
|
|
188
|
+
fileName: string;
|
|
189
|
+
/** File content, base64-encoded or plain string depending on isBase64Encoded flag */
|
|
190
|
+
data: string;
|
|
191
|
+
/** File extension including the dot (e.g., ".3dm", ".json"). Appended to fileName to create the full filename */
|
|
192
|
+
fileType: string;
|
|
193
|
+
/** Whether data is base64-encoded. If true, must be decoded to binary before use */
|
|
194
|
+
isBase64Encoded: boolean;
|
|
195
|
+
/** Directory path for archive organization (e.g., "subfolder/nested"). Empty string for root-level files */
|
|
196
|
+
subFolder: string;
|
|
197
|
+
/** Arbitrary metadata attached in Grasshopper. Not interpreted by compute; passed through for downstream consumers. May be absent on older payloads */
|
|
198
|
+
metadata?: Record<string, string>;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Normalized file ready for consumption or archival.
|
|
202
|
+
* Unified intermediate format from FileData or FileBaseInfo, ready to be packaged into archives or returned to callers.
|
|
203
|
+
*/
|
|
204
|
+
type ProcessedFile = {
|
|
205
|
+
/** Full filename including extension (e.g., "model.3dm") */
|
|
206
|
+
fileName: string;
|
|
207
|
+
/** File content as binary data (Uint8Array for decoded base64 or fetched binary) or text */
|
|
208
|
+
content: Uint8Array | string;
|
|
209
|
+
/** File path for archive organization (e.g., "subfolder/model.3dm") */
|
|
210
|
+
path: string;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Reference to an external file to be fetched and included in file operations.
|
|
214
|
+
* Specifies additional files (beyond compute response files) to fetch and process as ProcessedFile.
|
|
215
|
+
* @see {@link fetchRemoteFiles} for how FileBaseInfo is fetched and converted
|
|
216
|
+
*/
|
|
217
|
+
type FileBaseInfo = {
|
|
218
|
+
/** Destination filename for the file in the archive or result set (e.g., "additional-data.json") */
|
|
219
|
+
fileName: string;
|
|
220
|
+
/** URL to fetch the file from. Must be accessible from the runtime environment */
|
|
221
|
+
filePath: string;
|
|
222
|
+
/** Optional directory path for archive organization (e.g., "extras/docs"). When omitted, file lands at archive root */
|
|
223
|
+
subFolder?: string;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/** Extracts and processes files from compute response data without downloading them. */
|
|
227
|
+
declare const extractFilesFromComputeResponse: (downloadableFiles: FileData[], additionalFiles?: FileBaseInfo[] | FileBaseInfo | null) => Promise<ProcessedFile[]>;
|
|
228
|
+
/** Downloads files from a compute response as a ZIP archive. */
|
|
229
|
+
declare const downloadFileData: (downloadableFiles: FileData[], fileFoldername: string, additionalFiles?: FileBaseInfo[] | FileBaseInfo | null) => Promise<void>;
|
|
230
|
+
|
|
231
|
+
export { type ComputeConfig as C, type DefinitionRef as D, type ErrorCode as E, type FileBaseInfo as F, type ProcessedFile as P, type RetryPolicy as R, type ServerErrorCodeMap as S, ComputeError as a, ErrorCodes as b, type FileData as c, type ServerTiming as d, type SolveDefinition as e, downloadFileData as f, extractFilesFromComputeResponse as g, isDefinitionRef as i };
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
//# sourceMappingURL=index.cjs.map
|
|
1
|
+
"use strict";//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/selva/selva/packages/compute/dist/index.cjs"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/selva/selva/packages/compute/dist/index.cjs"],"names":[],"mappings":"AAAA","file":"/home/runner/work/selva/selva/packages/compute/dist/index.cjs"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export { BooleanInputType, CacheOptions, DataItem, DataTree, DataTreeDefault, DataTreePath, DataTreeValue, DefaultValue, DefinitionRef, FileInputType, GeometryInputType, GetValuesOptions, GetValuesResult, GrasshopperClient, GrasshopperComputeConfig, GrasshopperComputeResponse, GrasshopperParsedIO, GrasshopperParsedIORaw, GrasshopperRequestSchema, GrasshopperResponseProcessor, InnerTreeData, InputParam, InputParamSchema, NumericInputType, OutputParamSchema, OutputType, ParsedContext, SchedulerMode, SolveContext, SolveDefinition, SolveOptions, SolveResult, SolveScheduler, SolveSchedulerOptions, TextInputType, TreeBuilder, ValueListInputType, fetchDefinitionIO, fetchParsedDefinitionIO, hashDefinition, hashSolveInput, isDefinitionRef, processInput, solveGrasshopperDefinition, stableStringify } from './grasshopper.cjs';
|
|
1
|
+
|
|
2
|
+
export { }
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export { BooleanInputType, CacheOptions, DataItem, DataTree, DataTreeDefault, DataTreePath, DataTreeValue, DefaultValue, DefinitionRef, FileInputType, GeometryInputType, GetValuesOptions, GetValuesResult, GrasshopperClient, GrasshopperComputeConfig, GrasshopperComputeResponse, GrasshopperParsedIO, GrasshopperParsedIORaw, GrasshopperRequestSchema, GrasshopperResponseProcessor, InnerTreeData, InputParam, InputParamSchema, NumericInputType, OutputParamSchema, OutputType, ParsedContext, SchedulerMode, SolveContext, SolveDefinition, SolveOptions, SolveResult, SolveScheduler, SolveSchedulerOptions, TextInputType, TreeBuilder, ValueListInputType, fetchDefinitionIO, fetchParsedDefinitionIO, hashDefinition, hashSolveInput, isDefinitionRef, processInput, solveGrasshopperDefinition, stableStringify } from './grasshopper.js';
|
|
1
|
+
|
|
2
|
+
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{a as i,b as j,c as k,d as l,e as n,f as q,g as s,h as u,i as v,j as w,k as y,l as z}from"./chunk-RFFCVRKM.js";import{b as o,c as r,f as e,h as f,i as m,j as p,k as t,l as x,m as a,o as b,p as c,q as d,t as g,u as h}from"./chunk-XT3XWDDV.js";export{b as ComputeServerStats,o as ErrorCodes,s as GrasshopperClient,u as GrasshopperResponseProcessor,r as RhinoComputeError,q as SolveScheduler,z as TreeBuilder,d as camelcaseKeys,e as decodeBase64ToBinary,h as downloadFileData,p as enableDebugLogging,g as extractFilesFromComputeResponse,w as fetchDefinitionIO,y as fetchParsedDefinitionIO,a as fetchRhinoCompute,f as getLogger,x as getResponseWireSize,n as hashDefinition,l as hashSolveInput,i as isDefinitionRef,v as processInput,m as setLogger,t as setResponseWireSize,j as solveGrasshopperDefinition,k as stableStringify,c as toCamelCase};
|
|
2
1
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
package/dist/chunk-G7NVQAK5.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkLLUNR66Gcjs = require('./chunk-LLUNR66G.cjs');var ie=new Set;function Ve(){if(typeof window>"u"||_optionalChain([globalThis, 'access', _2 => _2.process, 'optionalAccess', _3 => _3.versions, 'optionalAccess', _4 => _4.node])!=null)return!1;let e=globalThis.navigator,r=typeof _optionalChain([e, 'optionalAccess', _5 => _5.userAgent])=="string"?e.userAgent:"";return!/jsdom/i.test(r)}function x(t,e){e||Ve()&&!ie.has(t)&&(ie.add(t),_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`Warning: ${t} is running on the client side. For better performance and security, consider running this on the server side.`))}function T(t){return typeof t=="object"&&!(t instanceof Uint8Array)&&typeof t.key=="string"&&typeof t.load=="function"}var Ge="Unable to load grasshopper definition";function We(t){return t instanceof _chunkLLUNR66Gcjs.c?t.code===_chunkLLUNR66Gcjs.b.DEFINITION_NOT_CACHED||t.message.includes(Ge):!1}function je(t,e){if(!e)return;let r=_chunkLLUNR66Gcjs.r.call(void 0, t,"values");if(!Array.isArray(r)||r.length===0)return;let n=[];for(let o of r){let i=_chunkLLUNR66Gcjs.r.call(void 0, o,"innerTree");(!i||Object.keys(i).length===0)&&n.push(_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, o,"paramName"), () => ("<unnamed>")))}if(n.length===0)return;let s=n.length===r.length?"all":`${n.length}/${r.length}`;_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`Solve returned empty output(s) (${s}): ${n.join(", ")}. These parameters produced no data \u2014 check the definition's inputs and the branch feeding each.`)}async function k(t,e,r){x("solveGrasshopperDefinition",_nullishCoalesce(r.suppressBrowserWarning, () => (r.suppressClientSideWarning)));let n=await j(e),{response:s}=await P(w(n,t),r);return s}async function ae(t,e,r){x("solveGrasshopperDefinitionWithCacheKey",_nullishCoalesce(r.suppressBrowserWarning, () => (r.suppressClientSideWarning)));let n=await j(e);return P(w(n,t),r)}async function ue(t,e,r,n){x("solveByCacheKey",_nullishCoalesce(n.suppressBrowserWarning, () => (n.suppressClientSideWarning)));let s={algo:null,pointer:e,values:t};try{return{...await P(s,n),missed:!1}}catch(o){if(!We(o))throw o;let i=await j(r);return{...await P(w(i,t),n),missed:!0}}}async function j(t){if(!T(t))return t;try{return await t.load()}catch(e){throw new (0, _chunkLLUNR66Gcjs.c)(`Failed to load definition bytes for ref '${t.key}'`,_chunkLLUNR66Gcjs.b.INVALID_INPUT,{context:{definitionKey:t.key},originalError:e instanceof Error?e:new Error(String(e))})}}async function P(t,e){Be(t,e);let r=await _chunkLLUNR66Gcjs.m.call(void 0, "grasshopper",t,e),{pointer:n,algo:s,...o}=r,i=o,a=_chunkLLUNR66Gcjs.l.call(void 0, r);if(a!==void 0){let u=typeof s=="string"?s.length:0;_chunkLLUNR66Gcjs.k.call(void 0, i,Math.max(0,a-u))}return je(i,e.debug),{response:i,cacheKey:typeof n=="string"?n:null}}function w(t,e){let r={algo:null,pointer:null,values:e};return t instanceof Uint8Array?r.algo=_chunkLLUNR66Gcjs.g.call(void 0, t):/^https?:\/\//i.test(t)?r.pointer=t:r.algo=_nullishCoalesce(_chunkLLUNR66Gcjs.e.call(void 0, t), () => (_chunkLLUNR66Gcjs.d.call(void 0, t))),r}function Be(t,e){e.cachesolve!=null&&(t.cachesolve=e.cachesolve),e.cacheerroredsolves!=null&&(t.cacheerroredsolves=e.cacheerroredsolves),e.modelunits!=null&&(t.modelunits=e.modelunits),e.angletolerance!=null&&(t.angletolerance=e.angletolerance),e.absolutetolerance!=null&&(t.absolutetolerance=e.absolutetolerance),e.dataversion!=null&&(t.dataversion=e.dataversion)}function le(t){let e=new WeakSet,r=n=>{if(n===void 0)return"undefined";if(n===null)return"null";if(typeof n=="number")return Number.isFinite(n)?String(n):"null";if(typeof n=="string"||typeof n=="boolean")return JSON.stringify(n);if(typeof n=="bigint")return`${n}n`;if(n instanceof Uint8Array)return`{"__u8":${n.length},"hash":"${fe(n)}"}`;if(Array.isArray(n)){if(e.has(n))return'"[Circular]"';e.add(n);let s=[];for(let o=0;o<n.length;o++)s.push(r(n[o]));return e.delete(n),`[${s.join(",")}]`}if(typeof n=="object"){if(e.has(n))return'"[Circular]"';e.add(n);let s;return typeof n.toJSON=="function"?s=r(n.toJSON()):n instanceof Map?s=`{"__map":[${[...n.entries()].map(([i,a])=>`[${r(i)},${r(a)}]`).sort().join(",")}]}`:n instanceof Set?s=`{"__set":[${[...n.values()].map(r).sort().join(",")}]}`:s=`{${Object.keys(n).sort().map(a=>`${JSON.stringify(a)}:${r(n[a])}`).join(",")}}`,e.delete(n),s}return"null"};return r(t)}function pe(t,e){let r=2166136261;for(let n=0;n<t;n++)r^=e(n),r=r+((r<<1)+(r<<4)+(r<<7)+(r<<8)+(r<<24))>>>0;return r.toString(16).padStart(8,"0")}function ce(t){return pe(t.length,e=>t.charCodeAt(e))}function fe(t){return pe(t.length,e=>t[e])}function $e(t,e){return B(N(t),e)}function B(t,e){let r=le(e);return`${t}|t:${r.length}:${ce(r)}`}function N(t){return T(t)?`r:${t.key}`:typeof t=="string"?`s:${t.length}:${ce(t)}`:`u8:${t.length}:${fe(t)}`}var ze=100;function Ue(t){return typeof t!="string"?!0:!/^https?:\/\//i.test(t)}function _e(t){try{return _nullishCoalesce(_optionalChain([JSON, 'access', _6 => _6.stringify, 'call', _7 => _7(t), 'optionalAccess', _8 => _8.length]), () => (0))}catch (e2){return 0}}var E=class{constructor(e,r,n={},s){_chunkLLUNR66Gcjs.a.call(void 0, this,"executor");_chunkLLUNR66Gcjs.a.call(void 0, this,"baseConfig");_chunkLLUNR66Gcjs.a.call(void 0, this,"mode");_chunkLLUNR66Gcjs.a.call(void 0, this,"maxConcurrent");_chunkLLUNR66Gcjs.a.call(void 0, this,"maxQueueDepth");_chunkLLUNR66Gcjs.a.call(void 0, this,"queueWaitMs");_chunkLLUNR66Gcjs.a.call(void 0, this,"timeoutMs");_chunkLLUNR66Gcjs.a.call(void 0, this,"retry");_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheEnabled");_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheMax");_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheMaxBytes");_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheTtl");_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheErroredSolves");_chunkLLUNR66Gcjs.a.call(void 0, this,"cache",new Map);_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheBytes",0);_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheHits",0);_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheMisses",0);_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheEvictions",0);_chunkLLUNR66Gcjs.a.call(void 0, this,"cacheKeyExecutor");_chunkLLUNR66Gcjs.a.call(void 0, this,"reuseServerDefinitionCache");_chunkLLUNR66Gcjs.a.call(void 0, this,"serverCacheKeys",new Map);_chunkLLUNR66Gcjs.a.call(void 0, this,"onStart");_chunkLLUNR66Gcjs.a.call(void 0, this,"onSettle");_chunkLLUNR66Gcjs.a.call(void 0, this,"onSuperseded");_chunkLLUNR66Gcjs.a.call(void 0, this,"subscribers",new Set);_chunkLLUNR66Gcjs.a.call(void 0, this,"inFlight",new Set);_chunkLLUNR66Gcjs.a.call(void 0, this,"pendingForLatestWins",null);_chunkLLUNR66Gcjs.a.call(void 0, this,"fifoQueue",[]);_chunkLLUNR66Gcjs.a.call(void 0, this,"_lastResult",null);_chunkLLUNR66Gcjs.a.call(void 0, this,"_lastError",null);_chunkLLUNR66Gcjs.a.call(void 0, this,"_lastDurationMs",null);_chunkLLUNR66Gcjs.a.call(void 0, this,"solveSeq",0);_chunkLLUNR66Gcjs.a.call(void 0, this,"lastStateSeq",0);_chunkLLUNR66Gcjs.a.call(void 0, this,"disposed",!1);this.executor=e,this.cacheKeyExecutor=s,this.baseConfig=r,this.mode=_nullishCoalesce(n.mode, () => ("latest-wins")),this.maxConcurrent=Math.max(1,_nullishCoalesce(n.maxConcurrent, () => ((this.mode==="parallel"?4:1)))),this.maxQueueDepth=n.maxQueueDepth!==void 0&&n.maxQueueDepth>0?Math.floor(n.maxQueueDepth):void 0,this.queueWaitMs=n.queueWaitMs!==void 0&&n.queueWaitMs>0?n.queueWaitMs:void 0,this.timeoutMs=n.timeoutMs,this.retry=n.retry;let o=n.cache;this.cacheEnabled=o!==void 0&&o!==!1;let i=typeof o=="object"?o:{};this.cacheMax=_nullishCoalesce(i.maxEntries, () => (50)),this.cacheMaxBytes=Math.max(0,_nullishCoalesce(i.maxBytes, () => (0))),this.cacheTtl=_nullishCoalesce(i.ttlMs, () => (0)),this.cacheErroredSolves=_nullishCoalesce(i.cacheErroredSolves, () => (!0)),this.reuseServerDefinitionCache=!!s&&(_nullishCoalesce(n.reuseServerDefinitionCache, () => (!0))),this.onStart=n.onStart,this.onSettle=n.onSettle,this.onSuperseded=n.onSuperseded}get isSolving(){return this.inFlight.size>0}get hasPending(){return this.pendingForLatestWins!==null||this.fifoQueue.length>0}get inFlightCount(){return this.inFlight.size}get queueDepth(){return this.fifoQueue.length+(this.pendingForLatestWins?1:0)}get lastResult(){return this._lastResult}get lastError(){return this._lastError}get lastDurationMs(){return this._lastDurationMs}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(){for(let e of this.subscribers)try{e()}catch(r){_chunkLLUNR66Gcjs.h.call(void 0, ).error("[SolveScheduler] subscriber threw:",r)}}solve(e,r,n){if(this.disposed)return Promise.reject(new (0, _chunkLLUNR66Gcjs.c)("SolveScheduler has been disposed and cannot be used",_chunkLLUNR66Gcjs.b.INVALID_STATE));let s=N(e),o=B(s,r),i=++this.solveSeq,a={key:o,enqueuedAt:Date.now(),startedAt:null};if(_optionalChain([n, 'optionalAccess', _9 => _9.signal, 'optionalAccess', _10 => _10.aborted]))return Promise.reject(this.makeAbortError(a));if(this.cacheEnabled){let u=this.readCache(o);if(u){this.mode==="latest-wins"&&this.supersedeCurrent();let f={status:"success",response:u,durationMs:0,fromCache:!0};return this.writeLastState(i,{result:u,durationMs:0}),this.runHook(this.onStart,a),this.runHook(this.onSettle,a,f),this.notify(),Promise.resolve(u)}}return new Promise((u,f)=>{let c={definition:e,dataTree:r,definitionHash:s,ctx:a,seq:i,resolve:u,reject:f,externalSignal:_optionalChain([n, 'optionalAccess', _11 => _11.signal])};c.externalSignal&&(c.queuedAbortHandler=()=>this.abortQueuedItem(c),c.externalSignal.addEventListener("abort",c.queuedAbortHandler,{once:!0})),this.enqueue(c)})}writeLastState(e,r){return e<this.lastStateSeq?!1:(this.lastStateSeq=e,"result"in r?(this._lastResult=r.result,this._lastError=null):this._lastError=r.error,this._lastDurationMs=r.durationMs,!0)}supersedeCurrent(){this.pendingForLatestWins&&(this.supersede(this.pendingForLatestWins),this.pendingForLatestWins=null);for(let e of this.inFlight)this.supersede(e),e.controller.abort()}abortQueuedItem(e){this.pendingForLatestWins===e&&(this.pendingForLatestWins=null);let r=this.fifoQueue.indexOf(e);r>=0&&this.fifoQueue.splice(r,1),this.rejectAsAborted(e),this.notify()}shedAsQueueFull(e){let r=new (0, _chunkLLUNR66Gcjs.c)("Solve queue is full; request shed (backpressure)",_chunkLLUNR66Gcjs.b.QUEUE_FULL,{statusCode:503,context:{key:e.ctx.key,queueDepth:this.fifoQueue.length,maxQueueDepth:this.maxQueueDepth}});this.settleError(e,r)&&this.runHook(this.onSettle,e.ctx,{status:"error",error:r,durationMs:0}),this.notify()}armQueueWaitTimer(e){if(this.queueWaitMs===void 0)return;let r=this.queueWaitMs;e.queueWaitTimer=setTimeout(()=>{if(e.settled)return;let n=this.fifoQueue.indexOf(e);n>=0&&this.fifoQueue.splice(n,1);let s=new (0, _chunkLLUNR66Gcjs.c)(`Solve waited longer than ${r}ms in queue; shed (backpressure)`,_chunkLLUNR66Gcjs.b.QUEUE_TIMEOUT,{statusCode:503,context:{key:e.ctx.key,waitedMs:Date.now()-e.ctx.enqueuedAt,queueWaitMs:r}});this.settleError(e,s)&&this.runHook(this.onSettle,e.ctx,{status:"error",error:s,durationMs:0}),this.notify()},r)}clearQueueWaitTimer(e){e.queueWaitTimer!==void 0&&(clearTimeout(e.queueWaitTimer),e.queueWaitTimer=void 0)}enqueue(e){switch(this.mode){case"latest-wins":{this.supersedeCurrent(),this.inFlight.size===0?this.execute(e):this.pendingForLatestWins=e;break}case"queue":case"parallel":{this.inFlight.size<this.maxConcurrent?this.execute(e):this.maxQueueDepth!==void 0&&this.fifoQueue.length>=this.maxQueueDepth?this.shedAsQueueFull(e):(this.armQueueWaitTimer(e),this.fifoQueue.push(e));break}}this.notify()}async execute(e){let r=new AbortController,n=e;n.controller=r,this.inFlight.add(n),e.ctx.startedAt=Date.now(),this.clearQueueWaitTimer(e),this.removeQueuedAbortHandler(e);let s=()=>r.abort();_optionalChain([e, 'access', _12 => _12.externalSignal, 'optionalAccess', _13 => _13.addEventListener, 'call', _14 => _14("abort",s,{once:!0})]),this.runHook(this.onStart,e.ctx),this.notify();let o=performance.now();try{let i={...this.baseConfig,signal:r.signal,...this.timeoutMs!==void 0&&{timeoutMs:this.timeoutMs},...this.retry!==void 0&&{retry:this.retry}},{response:a,definitionReuploaded:u}=await this.runExecutor(e.definition,e.dataTree,e.definitionHash,i),f=performance.now()-o;if(this.cacheEnabled&&this.writeCache(e.ctx.key,a),!this.settleSuccess(e,a))return;this.writeLastState(e.seq,{result:a,durationMs:f}),this.runHook(this.onSettle,e.ctx,{status:"success",response:a,durationMs:f,fromCache:!1,definitionReuploaded:u})}catch(i){let a=performance.now()-o,u=this.normalizeExecutionError(i,n);this.writeLastState(e.seq,{error:u,durationMs:a}),this.settleError(e,u)&&this.runHook(this.onSettle,e.ctx,{status:"error",error:u,durationMs:a})}finally{_optionalChain([e, 'access', _15 => _15.externalSignal, 'optionalAccess', _16 => _16.removeEventListener, 'call', _17 => _17("abort",s)]),this.inFlight.delete(n),this.drainNext(),this.notify()}}async runExecutor(e,r,n,s){if(!this.cacheKeyExecutor||!this.reuseServerDefinitionCache||!Ue(e))return{response:await this.executor(e,r,s)};let o=n,i=_nullishCoalesce(this.serverCacheKeys.get(o), () => (null)),a=await this.cacheKeyExecutor(e,r,i,s);if(a.cacheKey)for(this.serverCacheKeys.delete(o),this.serverCacheKeys.set(o,a.cacheKey);this.serverCacheKeys.size>ze;){let u=this.serverCacheKeys.keys().next().value;if(u===void 0)break;this.serverCacheKeys.delete(u)}else this.serverCacheKeys.delete(o);return{response:a.response,definitionReuploaded:a.missed}}drainNext(){if(!this.disposed){if(this.mode==="latest-wins"){if(this.pendingForLatestWins&&this.inFlight.size===0){let e=this.pendingForLatestWins;this.pendingForLatestWins=null,this.execute(e)}return}for(;this.fifoQueue.length>0&&this.inFlight.size<this.maxConcurrent;){let e=this.fifoQueue.shift();this.execute(e)}}}supersede(e){let r=new (0, _chunkLLUNR66Gcjs.c)("Superseded by newer solve",_chunkLLUNR66Gcjs.b.SUPERSEDED,{context:{key:e.ctx.key,enqueuedAt:e.ctx.enqueuedAt}});this.settleError(e,r)&&this.runHook(this.onSuperseded,e.ctx)}makeAbortError(e){return new (0, _chunkLLUNR66Gcjs.c)("Request aborted by caller",_chunkLLUNR66Gcjs.b.ABORTED,{context:{key:e.key,enqueuedAt:e.enqueuedAt}})}settleError(e,r){return e.settled?!1:(e.settled={error:r},this.clearQueueWaitTimer(e),this.removeQueuedAbortHandler(e),e.reject(r),!0)}settleSuccess(e,r){return e.settled?!1:(e.settled={ok:!0},this.clearQueueWaitTimer(e),this.removeQueuedAbortHandler(e),e.resolve(r),!0)}removeQueuedAbortHandler(e){e.queuedAbortHandler&&e.externalSignal&&e.externalSignal.removeEventListener("abort",e.queuedAbortHandler),e.queuedAbortHandler=void 0}isAbortLikeError(e){if(e instanceof Error){if(e.name==="AbortError")return!0;if(typeof DOMException<"u"&&e instanceof DOMException)return e.name==="AbortError"}return!1}normalizeExecutionError(e,r){return r.settled&&"error"in r.settled?r.settled.error:e instanceof _chunkLLUNR66Gcjs.c?e:this.isAbortLikeError(e)?this.makeAbortError(r.ctx):new (0, _chunkLLUNR66Gcjs.c)(e instanceof Error?e.message:String(e),_chunkLLUNR66Gcjs.b.UNKNOWN_ERROR,{originalError:e instanceof Error?e:new Error(String(e))})}cancelAll(){for(this.pendingForLatestWins&&(this.rejectAsAborted(this.pendingForLatestWins),this.pendingForLatestWins=null);this.fifoQueue.length>0;){let e=this.fifoQueue.shift();this.rejectAsAborted(e)}for(let e of this.inFlight){let r=this.makeAbortError(e.ctx);this.settleError(e,r)&&this.runHook(this.onSettle,e.ctx,{status:"error",error:r,durationMs:e.ctx.startedAt?Date.now()-e.ctx.startedAt:0}),e.controller.abort()}this.notify()}rejectAsAborted(e){let r=this.makeAbortError(e.ctx);this.settleError(e,r)&&this.runHook(this.onSettle,e.ctx,{status:"error",error:r,durationMs:0})}readCache(e){if(!this.cacheEnabled)return null;let r=this.cache.get(e);return r?this.cacheTtl>0&&Date.now()-r.insertedAt>this.cacheTtl?(this.dropCacheEntry(e),this.cacheMisses+=1,null):(this.cache.delete(e),this.cache.set(e,r),this.cacheHits+=1,r.response):(this.cacheMisses+=1,null)}writeCache(e,r){if(!this.cacheEnabled||!this.cacheErroredSolves&&r.errors&&r.errors.length>0)return;let n=_nullishCoalesce(_chunkLLUNR66Gcjs.l.call(void 0, r), () => (_e(r)));if(!(this.cacheMaxBytes>0&&n>this.cacheMaxBytes))for(this.dropCacheEntry(e),this.cache.set(e,{response:r,insertedAt:Date.now(),sizeBytes:n}),this.cacheBytes+=n;(this.cache.size>this.cacheMax||this.cacheMaxBytes>0&&this.cacheBytes>this.cacheMaxBytes)&&this.cache.size>0;){let s=this.cache.keys().next().value;if(s===void 0)break;this.dropCacheEntry(s),this.cacheEvictions+=1}}dropCacheEntry(e){let r=this.cache.get(e);r&&(this.cache.delete(e),this.cacheBytes-=r.sizeBytes)}clearCache(){this.cache.clear(),this.cacheBytes=0}cacheStats(){return{entries:this.cache.size,bytes:this.cacheBytes,hits:this.cacheHits,misses:this.cacheMisses,evictions:this.cacheEvictions}}dispose(){this.disposed||(this.disposed=!0,this.cancelAll(),this.subscribers.clear(),this.clearCache())}runHook(e,...r){if(e)try{e(...r)}catch(n){_chunkLLUNR66Gcjs.h.call(void 0, ).error("[SolveScheduler] hook threw:",n)}}};function de(t){return T(t)?`ref:${t.key}`:typeof t=="string"&&t.length<200?t:"...content..."}function me(t){return Array.isArray(t)?t.map(e=>{let r=0,n=0,s=_chunkLLUNR66Gcjs.r.call(void 0, e,"innerTree");if(s&&typeof s=="object"){for(let o of Object.values(s))if(Array.isArray(o)){r+=o.length;for(let i of o){let a=_optionalChain([i, 'optionalAccess', _18 => _18.data]);typeof a=="string"&&(n+=a.length)}}}return{param:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, e,"paramName"), () => ("<unnamed>")),items:r,bytes:n}}):[]}var O=class t{constructor(e){_chunkLLUNR66Gcjs.a.call(void 0, this,"config");_chunkLLUNR66Gcjs.a.call(void 0, this,"serverStats");_chunkLLUNR66Gcjs.a.call(void 0, this,"disposed",!1);this.config=this.normalizeComputeConfig(e),this.serverStats=new (0, _chunkLLUNR66Gcjs.o)(this.config.serverUrl,this.config.apiKey)}static async create(e){let r=new t(e),n=Math.max(1,(_nullishCoalesce(_optionalChain([e, 'access', _19 => _19.retry, 'optionalAccess', _20 => _20.attempts]), () => (2)))+1),s=_nullishCoalesce(_optionalChain([e, 'access', _21 => _21.retry, 'optionalAccess', _22 => _22.baseDelayMs]), () => (250)),o=_nullishCoalesce(_optionalChain([e, 'access', _23 => _23.retry, 'optionalAccess', _24 => _24.maxDelayMs]), () => (1e3));for(let i=0;i<n;i++){if(await r.serverStats.isServerOnline())return r;if(i<n-1){let a=Math.min(s*2**i,o);await new Promise(u=>setTimeout(u,a))}}throw await r.dispose(),new (0, _chunkLLUNR66Gcjs.c)("Rhino Compute server is not online",_chunkLLUNR66Gcjs.b.NETWORK_ERROR,{context:{serverUrl:r.config.serverUrl,attempts:n}})}getConfig(){return this.ensureNotDisposed(),{...this.config}}async getIO(e){return this.ensureNotDisposed(),$(e,this.config)}async getRawIO(e){return this.ensureNotDisposed(),M(e,this.config)}async solve(e,r,n){this.ensureNotDisposed();try{if(typeof e=="string"&&!_optionalChain([e, 'optionalAccess', _25 => _25.trim, 'call', _26 => _26()]))throw new (0, _chunkLLUNR66Gcjs.c)("Definition URL/content is required",_chunkLLUNR66Gcjs.b.INVALID_INPUT,{context:{receivedUrl:e}});if(e instanceof Uint8Array&&e.length===0)throw new (0, _chunkLLUNR66Gcjs.c)("Definition content is empty",_chunkLLUNR66Gcjs.b.INVALID_INPUT);if(T(e)&&!e.key.trim())throw new (0, _chunkLLUNR66Gcjs.c)("DefinitionRef key is empty",_chunkLLUNR66Gcjs.b.INVALID_INPUT);let s={...this.config,..._optionalChain([n, 'optionalAccess', _27 => _27.signal])!==void 0&&{signal:n.signal},..._optionalChain([n, 'optionalAccess', _28 => _28.timeoutMs])!==void 0&&{timeoutMs:n.timeoutMs},..._optionalChain([n, 'optionalAccess', _29 => _29.retry])!==void 0&&{retry:n.retry}},o=await k(r,e,s);if(_optionalChain([o, 'optionalAccess', _30 => _30.errors])&&o.errors.length>0)throw new (0, _chunkLLUNR66Gcjs.c)(o.errors.join("; ")||"Computation failed",_chunkLLUNR66Gcjs.b.COMPUTATION_ERROR,{context:{definition:de(e),inputSummary:me(r),errors:o.errors,warnings:o.warnings,values:o.values}});return o}catch(s){throw this.config.debug&&_chunkLLUNR66Gcjs.h.call(void 0, ).error("Compute failed:",s),s instanceof _chunkLLUNR66Gcjs.c?s:new (0, _chunkLLUNR66Gcjs.c)(s instanceof Error?s.message:String(s),_chunkLLUNR66Gcjs.b.COMPUTATION_ERROR,{context:{definition:de(e),inputSummary:me(r)},originalError:s instanceof Error?s:new Error(String(s))})}}createScheduler(e){this.ensureNotDisposed();let r=(s,o,i)=>k(o,s,i),n=(s,o,i,a)=>i===null?ae(o,s,a).then(u=>({...u,missed:!1})):ue(o,i,s,a);return new E(r,this.config,e,n)}async dispose(){this.disposed||(this.disposed=!0,await this.serverStats.dispose())}ensureNotDisposed(){if(this.disposed)throw new (0, _chunkLLUNR66Gcjs.c)("GrasshopperClient has been disposed and cannot be used",_chunkLLUNR66Gcjs.b.INVALID_STATE)}normalizeComputeConfig(e){return{...e,serverUrl:_chunkLLUNR66Gcjs.n.call(void 0, e.serverUrl),apiKey:e.apiKey,authToken:e.authToken,debug:_nullishCoalesce(e.debug, () => (!1)),suppressBrowserWarning:_nullishCoalesce(e.suppressBrowserWarning, () => (e.suppressClientSideWarning))}}};var F=new Map;function ye(t,e){F.set(t,e)}ye("Rhino.Geometry.Point3d",(t,e)=>{let r=e;return!r||typeof r.X!="number"?null:new t.Point([r.X,r.Y,r.Z])});ye("Rhino.Geometry.Line",(t,e)=>{let r=e;return!r||!r.From||!r.To?null:new t.Line([r.From.X,r.From.Y,r.From.Z],[r.To.X,r.To.Y,r.To.Z])});function qe(t){if(F.has(t))return F.get(t);for(let[e,r]of F)if(t.startsWith(e))return r}function Ke(t){return!!(t&&typeof t=="object"&&typeof t.data=="string")}function he(t,e){return{__decodeError:!0,type:t,raw:e}}function ge(t,e,r){let n=qe(e),s=!1;if(n)try{let o=n(r,t);if(o!=null)return o}catch(o){_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`Failed to decode Rhino type ${e}:`,o),s=!0}try{if(Ke(t))return r.CommonObject.decode(t)}catch(o){return _chunkLLUNR66Gcjs.h.call(void 0, ).warn(`Failed to decode ${e} with CommonObject:`,o),he(e,t)}return s?he(e,t):t}function be(t){let e=new WeakSet,r=n=>{if(!n||typeof n!="object"||e.has(n))return;e.add(n);let s=n.delete;if(typeof s=="function"){let i=n.isDeleted;(typeof i!="function"||!i.call(n))&&s.call(n);return}if(Array.isArray(n)){for(let i of n)r(i);return}let o=Object.getPrototypeOf(n);if(o===Object.prototype||o===null)for(let i of Object.values(n))r(i)};r(t)}var I={STRING:"System.String",INT:"System.Int32",DOUBLE:"System.Double",BOOL:"System.Boolean"},Qe="Rhino.Geometry.",He=["WebDisplay"],Je="FileData";function Te(t){return He.some(e=>t.includes(e))}function Ye(t){if(typeof t!="string")return t;let e=t.trim();if(!(e.startsWith("{")||e.startsWith("[")||e.startsWith('"')))return t;try{let n=JSON.parse(e);if(typeof n=="string")try{return JSON.parse(n)}catch (e3){return n}return n}catch (e4){return t}}function Xe(t,e,r){switch(e){case I.STRING:return typeof t!="string"?t:t.replace(/^"(.*)"$/,"$1");case I.INT:return Number.parseInt(t,10);case I.DOUBLE:return Number.parseFloat(t);case I.BOOL:return String(t).toLowerCase()==="true";default:return r&&e.startsWith(Qe)?ge(t,e,r):t}}var z=new WeakMap;function Se(t){if(z.has(t))return z.get(t);let e=Ye(t.data);return z.set(t,e),e}function De(t,e,r,n){if(typeof t.data!="string")return t.data;let s=r?Se(t):t.data;return Xe(s,e,n)}function Ze(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.fileName=="string"&&typeof e.fileType=="string"&&"data"in e&&typeof e.isBase64Encoded=="boolean"&&typeof e.subFolder=="string"}function U(t){let e=_chunkLLUNR66Gcjs.r.call(void 0, t,"values");return Array.isArray(e)?e:[]}function _(t){return typeof t.type=="string"?t.type:""}function q(t,e){if(!(!t||typeof t!="object")){for(let r of Object.values(t))if(Array.isArray(r))for(let n of r)n&&typeof n=="object"&&e(n)}}function xe(t,e=!1,r={}){let{parseValues:n=!0,rhino:s,stringOnly:o=!1}=r,i={},a=new Set;for(let u of U(t)){let f=_chunkLLUNR66Gcjs.r.call(void 0, u,"paramName");q(_chunkLLUNR66Gcjs.r.call(void 0, u,"innerTree"),c=>{let d=_(c);if(Te(d)||o&&d!==I.STRING)return;let g=e?c.id:f;if(!g)return;let b=De(c,d,n,s);g in i?a.has(g)?i[g].push(b):(i[g]=[i[g],b],a.add(g)):i[g]=b})}return{values:i,dispose:()=>be(i)}}function Ie(t){let e=[];for(let r of U(t))q(_chunkLLUNR66Gcjs.r.call(void 0, r,"innerTree"),n=>{if(!_(n).includes(Je))return;let s=Se(n);Ze(s)&&e.push(s)});return e}function Ce(t,e,r={}){let{parseValues:n=!0,rhino:s,stringOnly:o=!1}=r;for(let i of U(t)){let a=_chunkLLUNR66Gcjs.r.call(void 0, i,"innerTree"),u=!1;if("byName"in e){if(_chunkLLUNR66Gcjs.r.call(void 0, i,"paramName")!==e.byName)continue;u=!0}let f=[];if(q(a,c=>{if("byId"in e){if(c.id!==e.byId)return;u=!0}let d=_(c);Te(d)||o&&d!==I.STRING||f.push(De(c,d,n,s))}),u)return f.length===0?void 0:f.length===1?f[0]:f}}var L=class{constructor(e,r=!1){_chunkLLUNR66Gcjs.a.call(void 0, this,"response",e);_chunkLLUNR66Gcjs.a.call(void 0, this,"debug",r)}getValues(e=!1,r={}){return xe(this.response,e,r)}getValue(e,r){return Ce(this.response,e,r)}getFileData(){return Ie(this.response)}async getAndDownloadFiles(e,r){let n=this.getFileData();await _chunkLLUNR66Gcjs.u.call(void 0, n,e,r)}};var K=/^\{(-?\d+(?:;-?\d+)*)?\}$/;function C(t){if(typeof t!="object"||t===null||Array.isArray(t))return!1;let e=Object.entries(t);return e.length>0&&e.every(([r,n])=>K.test(r)&&Array.isArray(n))}function Q(t,e,r){let n=Number(t.toFixed(e));return Math.abs(t-n)<r?n:t}function we(t,e){if(!Number.isFinite(t)||t===0)return .1;let r=Math.abs(t);if(r>=1){let g=String(t).split(".")[1];if(g&&g.length>0){let b=Math.min(g.length,12),D=Math.pow(10,-b),Z=Number(D.toFixed(b));return Math.abs(Z-D)<e?Z:D}return 1}let n=String(t),s=n.toLowerCase().match(/e(-?\d+)/);if(s){let d=Number(s[1]);if(d<0||n.toLowerCase().includes("e-")){let g=Math.abs(d),b=Math.pow(10,-g),D=Number(b.toFixed(g));return Math.abs(D-b)<e?D:b}return .1}let o=12,a=r.toFixed(o).replace(/0+$/,""),u=Math.min((a.split(".")[1]||"").length,o);if(u===0)return .1;let f=Math.pow(10,-u),c=Number(f.toFixed(u));return Math.abs(c-f)<e?c:f}function H(t){return typeof t.stepSize=="number"&&Number.isFinite(t.stepSize)&&t.stepSize>0?t.stepSize:void 0}function S(t,e,r){if(t==null)return t;if(Array.isArray(t)){let s=t.map(e).filter(o=>o!==null);return s.length>0?s:void 0}let n=e(t);return n!==null?n:r?void 0:t}var v=t=>{if(typeof t=="number")return Number.isFinite(t)?t:null;if(typeof t=="string"){let e=t.trim();if(e===""||/^[+-]?0[xbo]/i.test(e))return null;let r=Number(e);return Number.isFinite(r)?r:null}return null},V=t=>{if(typeof t=="boolean")return t;if(typeof t=="string"){let e=t.trim().toLowerCase();if(e==="true")return!0;if(e==="false")return!1}return null},Ee=t=>typeof t=="string"?t.length>=2&&t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1):t.startsWith('"')?t.slice(1):t:null,ve=t=>{if(typeof t=="string"){let e=t.trim();return e.startsWith('"')&&e.endsWith('"')&&(e=e.slice(1,-1).trim()),e}return null};function J(t){return e=>{if(typeof e=="object"&&e!==null)return e;if(typeof e=="string"&&e.trim()!=="")try{let r=JSON.parse(e);return typeof r=="object"&&r!==null?r:(_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`Parsed value for input ${t} is not an object`),null)}catch(r){return _chunkLLUNR66Gcjs.h.call(void 0, ).warn(`Failed to parse object value "${e}" for input ${t}`,r),null}return null}}function et(t,e=1e-8){let r=t.paramType==="Integer",n=H(t);if(C(t.default))return{default:t.default,stepSize:_nullishCoalesce(n, () => ((r?1:.1)))};if(typeof t.default=="string"&&t.default.trim()!==""&&v(t.default)===null)throw new (0, _chunkLLUNR66Gcjs.c)(`Invalid numeric default "${t.default}" for input "${t.name||"unknown"}"`,_chunkLLUNR66Gcjs.b.VALIDATION_ERROR,{context:{inputName:t.name,default:t.default}});let s=S(t.default,v,!0);if(r)return Array.isArray(s)?s=s.map(d=>typeof d=="number"?Math.round(d):d):typeof s=="number"&&(s=Math.round(s)),{default:s,stepSize:_nullishCoalesce(n, () => (1))};let o=Array.isArray(s)?s[0]:s,i;typeof o=="number"&&Number.isFinite(o)&&o!==0?i=o:typeof t.minimum=="number"&&Number.isFinite(t.minimum)&&t.minimum!==0?i=t.minimum:typeof t.maximum=="number"&&Number.isFinite(t.maximum)&&t.maximum!==0&&(i=t.maximum);let a=_nullishCoalesce(n, () => ((i!==void 0?we(i,e):.1))),u=0,f=String(a),c=f.toLowerCase().match(/e(-?\d+)/);if(c?u=Math.abs(Number(c[1])):u=_nullishCoalesce(_optionalChain([f, 'access', _31 => _31.split, 'call', _32 => _32("."), 'access', _33 => _33[1], 'optionalAccess', _34 => _34.length]), () => (0)),u===0&&typeof o=="number"&&o!==0&&Math.abs(o)<1){let d=Math.ceil(-Math.log10(Math.abs(o)));Number.isFinite(d)&&d>0&&(u=d)}return u=Math.min(Math.max(u,0),12),Array.isArray(s)?s=s.map(d=>typeof d=="number"?Q(d,u,e):d):typeof s=="number"&&(s=Q(s,u,e)),{default:s,stepSize:a}}var tt={types:["Number","Integer"],parse(t,e){let{default:r,stepSize:n}=et(t);return{...e,paramType:t.paramType,minimum:t.minimum,maximum:t.maximum,atLeast:t.atLeast,atMost:t.atMost,stepSize:n,default:r}},fallback(t,e){let r=(_nullishCoalesce(t.atMost, () => (1)))>1,n=typeof t.minimum=="number"&&Number.isFinite(t.minimum)&&t.minimum>0?t.minimum:0;return{...e,paramType:t.paramType,minimum:t.minimum,maximum:t.maximum,atLeast:t.atLeast,atMost:t.atMost,stepSize:_nullishCoalesce(H(t), () => ((t.paramType==="Integer"?1:.1))),default:r?[n]:n}}},rt={types:["Boolean"],parse(t,e){if(C(t.default))return{...e,paramType:"Boolean",default:t.default};let r=S(t.default,V,!1);if(r!=null&&typeof r!="boolean"&&!Array.isArray(r))throw new (0, _chunkLLUNR66Gcjs.c)(`Invalid boolean default "${String(r)}" for input "${t.name||"unknown"}"`,_chunkLLUNR66Gcjs.b.VALIDATION_ERROR,{context:{inputName:t.name,default:t.default}});return{...e,paramType:"Boolean",default:r}},fallback(t,e){let r=(_nullishCoalesce(t.atMost, () => (1)))>1;return{...e,paramType:"Boolean",default:r?[!1]:!1}}},nt={types:["Text"],parse(t,e){let r=S(t.default,Ee,!1);return{...e,paramType:"Text",default:r}},fallback(t,e){let r=(_nullishCoalesce(t.atMost, () => (1)))>1;return{...e,paramType:"Text",default:r?[""]:""}}},st={types:["ValueList"],parse(t,e){if(!t.values||typeof t.values!="object"||Object.keys(t.values).length===0)throw _chunkLLUNR66Gcjs.c.missingValues(t.nickname||"unnamed","ValueList");let r=t.default;if(t.default!==void 0&&t.default!==null){if(typeof t.default=="object")throw new (0, _chunkLLUNR66Gcjs.c)(`ValueList input "${t.nickname||"unnamed"}" default is not a string-able value`,_chunkLLUNR66Gcjs.b.VALIDATION_ERROR,{context:{inputName:t.name,default:t.default}});let n=String(t.default).toLowerCase(),s=Object.keys(t.values).find(o=>o.toLowerCase()===n);s!==void 0?r=s:_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`ValueList input "${t.nickname||"unnamed"}" default value "${t.default}" is not in available values`)}return{...e,paramType:"ValueList",values:t.values,default:r}},fallback(t,e){return{...e,paramType:"ValueList",values:t.values&&typeof t.values=="object"?t.values:{},default:void 0}}},Ae={types:["Geometry"],parse(t,e){let r=S(t.default,J(t.nickname||"unnamed"),!0);return{...e,paramType:"Geometry",default:r}},fallback(t,e){let r=(_nullishCoalesce(t.atMost, () => (1)))>1;return{...e,paramType:"Geometry",default:r?[null]:null}}},ot={types:["File"],parse(t,e){let r=S(t.default,J(t.nickname||"unnamed"),!0);return{...e,paramType:"File",acceptedFormats:t.acceptedFormats,default:r}},fallback(t,e){let r=(_nullishCoalesce(t.atMost, () => (1)))>1;return{...e,paramType:"File",default:r?[null]:null}}},it={types:["Color"],parse(t,e){let r=S(t.default,ve,!1);return{...e,paramType:"Color",default:r}},fallback(t,e){let r=(_nullishCoalesce(t.atMost, () => (1)))>1;return{...e,paramType:"Color",default:r?["0, 0, 0"]:"0, 0, 0"}}},at=[tt,rt,nt,st,Ae,ot,it],Y=new Map(at.flatMap(t=>t.types.map(e=>[e,t]))),Re=Ae;function Pe(t){return _chunkLLUNR66Gcjs.r.call(void 0, t,"data")}function ut(t){return _chunkLLUNR66Gcjs.r.call(void 0, t,"type")}var lt=new Set(["System.Double","System.Single","System.Decimal","System.Int32","System.Int64"]),pt=new Set(["System.Int32","System.Int64"]);function ke(t){if(typeof t.default!="object"||t.default===null)return{schema:t};if(Array.isArray(t.default))return{schema:t};if(!_chunkLLUNR66Gcjs.s.call(void 0, t.default,"innerTree")){let n=`Input "${_nullishCoalesce(t.name, () => ("unknown"))}" default had an unrecognized shape (no innerTree key); the default was dropped.`;return _chunkLLUNR66Gcjs.h.call(void 0, ).warn("Unexpected structure in input.default:",t.default),{schema:{...t,default:null},warning:{code:"MALFORMED_DEFAULT",message:n}}}let e=_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t.default,"innerTree"), () => ({}));if(Object.keys(e).length===0)return{schema:{...t,default:void 0}};if(t.treeAccess||t.atMost&&t.atMost>1){let n={},s=[];for(let[i,a]of Object.entries(e)){if(!Array.isArray(a)){let f=`Input "${_nullishCoalesce(t.name, () => ("unknown"))}" default had a non-array innerTree branch ("${i}"); the default was dropped.`;return _chunkLLUNR66Gcjs.h.call(void 0, ).warn("Unexpected structure in input.default innerTree:",t.default),{schema:{...t,default:null},warning:{code:"MALFORMED_DEFAULT",message:f}}}let u=[];for(let f of a){let c=Pe(f),d=ut(f);if(d&<.has(d)){if(typeof c=="string"&&c.trim()==="")continue;let g=v(c);if(g===null){s.push(`"${String(c)}" (${d})`);continue}u.push(pt.has(d)?Math.round(g):g);continue}if(d==="System.Boolean"){let g=V(c);if(g===null){s.push(`"${String(c)}" (${d})`);continue}u.push(g);continue}if(typeof c=="string"&&_optionalChain([d, 'optionalAccess', _35 => _35.startsWith, 'call', _36 => _36("Rhino.Geometry")])){try{u.push(JSON.parse(c))}catch (e5){u.push(c)}continue}u.push(c)}n[i]=u}let o;if(s.length>0){let i=`Input "${_nullishCoalesce(t.name, () => ("unknown"))}" default contained ${s.length} tree value(s) that could not be parsed and were dropped: ${s.join(", ")}.`;_chunkLLUNR66Gcjs.h.call(void 0, ).warn(i),o={code:"MALFORMED_DEFAULT",message:i}}return{schema:{...t,default:n},...o&&{warning:o}}}let r=[];for(let n of Object.values(e))Array.isArray(n)&&n.forEach(s=>{s&&typeof s=="object"&&_chunkLLUNR66Gcjs.s.call(void 0, s,"data")&&r.push(Pe(s))});return r.length===0?{schema:{...t,default:void 0}}:r.length===1?{schema:{...t,default:r[0]}}:{schema:{...t,default:r}}}var ct=new Map([...Y.keys()].map(t=>[t.toLowerCase(),t]));function ft(t){return _nullishCoalesce(ct.get(_optionalChain([t, 'optionalAccess', _37 => _37.toLowerCase, 'call', _38 => _38()])), () => (t))}function dt(t){return Ne(t).input}function Ne(t){let e={description:t.description,name:t.name,nickname:t.nickname,treeAccess:t.treeAccess,groupName:_nullishCoalesce(t.groupName, () => (void 0)),id:t.id},r=ft(t.paramType),n={...t,paramType:r},s;try{let{schema:i,warning:a}=ke(n);n=i,s=a&&{inputName:t.name||"unknown",paramType:t.paramType,message:a.message,code:a.code}}catch(i){n={...n,default:null},s={inputName:t.name||"unknown",paramType:t.paramType,message:`Input "${_nullishCoalesce(t.name, () => ("unknown"))}" default could not be normalized and was dropped: ${i instanceof Error?i.message:String(i)}`,code:"MALFORMED_DEFAULT"}}let o=Y.get(r);try{if(!o)throw _chunkLLUNR66Gcjs.c.unknownParamType(r,t.name);return{input:o.parse(n,e),error:s,...s&&{errors:[s]}}}catch(i){if(i instanceof _chunkLLUNR66Gcjs.c){_chunkLLUNR66Gcjs.h.call(void 0, ).error(`Validation error for input ${t.name||"unknown"}:`,i.message);let a={inputName:t.name||"unknown",paramType:t.paramType,message:i.message,code:i.code};return{input:(_nullishCoalesce(o, () => (Re))).fallback(n,e),error:a,errors:s?[s,a]:[a]}}throw new (0, _chunkLLUNR66Gcjs.c)(i instanceof Error?i.message:String(i),"VALIDATION_ERROR",{context:{paramName:t.name,paramType:r},originalError:i instanceof Error?i:new Error(String(i))})}}function Oe(t){let e=[],r=[];for(let n of t){let{input:s,errors:o}=Ne(n);e.push(s),o&&r.push(...o)}return{inputs:e,parseErrors:r}}function Me(t){let e=_chunkLLUNR66Gcjs.r.call(void 0, t,"stepSize");return{id:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"id"), () => ("")),name:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"name"), () => ("")),nickname:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"nickname"), () => (null)),description:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"description"), () => ("")),paramType:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"paramType"), () => ("")),treeAccess:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"treeAccess"), () => (!1)),minimum:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"minimum"), () => (null)),maximum:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"maximum"), () => (null)),atLeast:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"atLeast"), () => (1)),atMost:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"atMost"), () => (1)),stepSize:typeof e=="number"&&Number.isFinite(e)?e:void 0,default:_chunkLLUNR66Gcjs.r.call(void 0, t,"default"),values:_chunkLLUNR66Gcjs.r.call(void 0, t,"values"),acceptedFormats:_chunkLLUNR66Gcjs.r.call(void 0, t,"acceptedFormats"),groupName:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"groupName"), () => (null))}}function Fe(t){return{name:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"name"), () => ("")),nickname:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"nickname"), () => (null)),paramType:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"paramType"), () => ("")),id:_nullishCoalesce(_chunkLLUNR66Gcjs.r.call(void 0, t,"id"), () => (""))}}async function M(t,e){let r=w(t,[]),n={};if(r.algo&&(n.algo=r.algo),r.pointer&&(n.pointer=r.pointer),!n.algo&&!n.pointer)throw new (0, _chunkLLUNR66Gcjs.c)("Definition must resolve to either a URL pointer or base64 algo",_chunkLLUNR66Gcjs.b.INVALID_INPUT,{context:{definition:t}});let s=await _chunkLLUNR66Gcjs.m.call(void 0, "io",n,e);if(!s||typeof s!="object")throw new (0, _chunkLLUNR66Gcjs.c)("Invalid IO response structure",_chunkLLUNR66Gcjs.b.INVALID_INPUT,{context:{response:s,definition:t}});let o=Le(_chunkLLUNR66Gcjs.r.call(void 0, s,"warnings")),i=Le(_chunkLLUNR66Gcjs.r.call(void 0, s,"errors")),a=_chunkLLUNR66Gcjs.r.call(void 0, s,"inputs"),u=_chunkLLUNR66Gcjs.r.call(void 0, s,"outputs");return{inputs:Array.isArray(a)?a.map(Me):[],outputs:Array.isArray(u)?u.map(Fe):[],...o&&{loadWarnings:o},...i&&{loadErrors:i}}}function Le(t){if(!Array.isArray(t))return;let e=t.map(mt).filter(r=>r!==void 0);return e.length>0?e:void 0}function mt(t){if(t==null)return;let e;if(typeof t=="string")e=t;else if(typeof t=="object"){let r=_chunkLLUNR66Gcjs.r.call(void 0, t,"message");if(typeof r=="string"&&r.trim().length>0)e=r;else try{e=_nullishCoalesce(JSON.stringify(t), () => (String(t)))}catch (e6){e=String(t)}}else e=String(t);return e.trim().length>0?e:void 0}async function $(t,e){x("fetchParsedDefinitionIO",_nullishCoalesce(e.suppressBrowserWarning, () => (e.suppressClientSideWarning)));let{inputs:r,outputs:n,loadWarnings:s,loadErrors:o}=await M(t,e),{inputs:i,parseErrors:a}=Oe(r);return{inputs:i,outputs:n,...a.length>0&&{parseErrors:a},...s&&{loadWarnings:s},...o&&{loadErrors:o}}}var X=class t{constructor(e){_chunkLLUNR66Gcjs.a.call(void 0, this,"innerTree");_chunkLLUNR66Gcjs.a.call(void 0, this,"paramName");this.paramName=e,this.innerTree={}}append(e,r){let n=t.formatPathString(e);this.innerTree[n]||(this.innerTree[n]=[]);let s=r.map(o=>({data:t.serializeValue(o)}));return this.innerTree[n].push(...s),this}appendSingle(e,r){return this.append(e,[r])}fromDataTreeDefault(e){this.innerTree={};for(let[r,n]of Object.entries(e)){if(!Array.isArray(n))continue;let s=t.parsePathString(r);this.append(s,n)}return this}appendFlat(e){let r=Array.isArray(e)?e:[e];return this.append([0],r)}flatten(){let e=[];for(let r of Object.values(this.innerTree))if(Array.isArray(r))for(let n of r)e.push(t.deserializeValue(n.data));return e}getPaths(){return Object.keys(this.innerTree)}getPath(e){let r=t.formatPathString(e),n=this.innerTree[r];if(n)return n.map(s=>t.deserializeValue(s.data))}toComputeFormat(){return{ParamName:this.paramName,InnerTree:this.innerTree}}getInnerTree(){return this.innerTree}getParamName(){return this.paramName}static fromInputParams(e){return e.filter(r=>t.hasValidValue(r.default)).map(r=>{let n=new t(r.nickname||"unnamed"),s=r.default;if(r.treeAccess&&C(s))n.fromDataTreeDefault(s),t.isNumericInput(r)&&n.applyNumericConstraints(r.minimum,r.maximum,r.nickname||"unnamed");else{let o=Array.isArray(s)?s:[s],i=t.processValues(o,r);n.appendFlat(i)}return n.toComputeFormat()})}static fromInputParam(e){return t.hasValidValue(e.default)?t.fromInputParams([e])[0]:void 0}static replaceTreeValue(e,r,n){let s=e.length>0&&e[0]instanceof t,o=t.buildFromValue(r,n);if(s){let f=e.slice(),c=f.findIndex(d=>d.getParamName()===r);return c!==-1?f[c]=o:f.push(o),f}let i=e.slice(),a=o.toComputeFormat(),u=i.findIndex(f=>f.ParamName===r);return u!==-1?i[u]=a:i.push(a),i}static buildFromValue(e,r){let n=new t(e);return C(r)?n.fromDataTreeDefault(r):n.appendFlat(r),n}static getTreeValue(e,r){let s=e.length>0&&e[0]instanceof t?t.readFromBuilders(e,r):t.readFromDataTrees(e,r);return s===null||s.length===0?null:s.length===1?s[0]:s}static readFromBuilders(e,r){let n=e.find(s=>s.getParamName()===r);return n?n.flatten():null}static readFromDataTrees(e,r){let n=e.find(i=>i.ParamName===r);if(!_optionalChain([n, 'optionalAccess', _39 => _39.InnerTree]))return null;let s=Object.keys(n.InnerTree)[0];if(!s)return null;let o=n.InnerTree[s];return Array.isArray(o)?o.map(i=>_optionalChain([i, 'optionalAccess', _40 => _40.data])!==void 0?t.deserializeValue(i.data):null):_optionalChain([o, 'optionalAccess', _41 => _41.data])!==void 0?[t.deserializeValue(o.data)]:o!==void 0?[o]:null}static parsePathString(e){let r=e.match(K);if(!r)throw new Error(`Invalid Grasshopper tree path: "${e}". Expected "{}", "{0}", or "{0;1;2}" (negative indices allowed, no empty segments).`);return r[1]?r[1].split(";").map(Number):[]}static formatPathString(e){return`{${e.join(";")}}`}applyNumericConstraints(e,r,n){for(let s of Object.values(this.innerTree))if(Array.isArray(s))for(let o of s){let i=t.deserializeValue(o.data);if(typeof i=="number"){let a=t.clampValue(i,e,r,n);o.data=t.serializeValue(a)}}}static serializeValue(e){return typeof e=="boolean"||typeof e=="number"||typeof e=="string"?e:typeof e=="object"&&e!==null?JSON.stringify(e):String(e)}static deserializeValue(e){if(typeof e=="boolean"||typeof e=="number"||typeof e!="string")return e;if(e.startsWith("{")||e.startsWith("["))try{return JSON.parse(e)}catch (e7){return e}let r=Number(e);return Number.isFinite(r)&&String(r)===e?r:e==="true"?!0:e==="false"?!1:e}static hasValidValue(e){return e==null?!1:typeof e=="string"?!0:!(Array.isArray(e)&&e.length===0||typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0)}static isNumericInput(e){return e.paramType==="Number"||e.paramType==="Integer"}static processValues(e,r){return e.map(n=>t.isNumericInput(r)&&typeof n=="number"?t.clampValue(n,r.minimum,r.maximum,r.nickname||"unnamed"):n).filter(n=>n!=null)}static clampValue(e,r,n,s){let o=e;return r!=null&&o<r&&(_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`${s}: ${e} below min ${r}, clamping`),o=r),n!=null&&o>n&&(_chunkLLUNR66Gcjs.h.call(void 0, ).warn(`${s}: ${e} above max ${n}, clamping`),o=n),o}};exports.a = T; exports.b = k; exports.c = le; exports.d = $e; exports.e = N; exports.f = E; exports.g = O; exports.h = L; exports.i = dt; exports.j = M; exports.k = $; exports.l = X;
|
|
2
|
-
//# sourceMappingURL=chunk-G7NVQAK5.cjs.map
|