@selvajs/solve 1.3.0-beta.2 → 2.0.0-beta.10

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/dist/server.d.cts CHANGED
@@ -1,9 +1,7 @@
1
- import { t as SolveInput } from "./solve-input-BDv_JdvS.cjs";
2
- import { SchemaInput } from "@selvajs/schemas";
3
- import { DataTree, DefinitionRef as DefinitionRef$1, GrasshopperClient, GrasshopperComputeResponse, InputParam, SelvaEventTarget, SolveScheduler } from "@selvajs/compute/grasshopper";
4
- import { DefinitionRef, SolveDefinition, SolveDefinition as SolveDefinition$1, isDefinitionRef } from "@selvajs/compute/core";
1
+ import { t as SolveInput } from "./solve-input-CUjVGYPC.cjs";
2
+ import { DataTree, GrasshopperClient, GrasshopperComputeResponse, SelvaEventTarget, SolveScheduler } from "@selvajs/compute/grasshopper";
3
+ import { DefinitionRef, DefinitionRef as DefinitionRef$1, SolveDefinition, SolveDefinition as SolveDefinition$1, isDefinitionRef } from "@selvajs/compute/core";
5
4
  import { ILogger } from "@selvajs/platform";
6
- //#region src/server/client-cache.d.ts
7
5
  /**
8
6
  * Opaque identity of a compute server — construct only via `serverIdentity()`.
9
7
  * Kept opaque so "a server is now a pool of URLs behind one id" stays additive.
@@ -22,34 +20,6 @@ export declare function serverIdentity(server: Pick<ResolvedServer, 'id'>): Serv
22
20
  interface CachedClient {
23
21
  client: GrasshopperClient;
24
22
  scheduler: SolveScheduler;
25
- /**
26
- * Last Server-Timing decode/solve/encode, written by `onServerTiming`. The
27
- * scheduler runs up to `maxConcurrent` solves at once, so `last` alone can't
28
- * be trusted per-request: callers snapshot `seq` before their solve and only
29
- * attribute `last` to themselves if exactly one write happened since (see
30
- * the guard in `runSolvePipeline`), dropping it otherwise rather than risk
31
- * misattributing another request's timing.
32
- */
33
- rhinoTiming: {
34
- last: {
35
- decode: number;
36
- solve: number;
37
- encode: number;
38
- } | null;
39
- seq: number;
40
- };
41
- /**
42
- * Same snapshot-and-attribute pattern as `rhinoTiming`, for the scheduler's
43
- * `onSettle` cache verdict. `seq` increments on every settle (success or
44
- * error); `last` is written only on success.
45
- */
46
- solveMeta: {
47
- last: {
48
- fromCache: boolean;
49
- definitionReuploaded?: boolean;
50
- } | null;
51
- seq: number;
52
- };
53
23
  }
54
24
  /**
55
25
  * Debug verbosity: `false` is silent, `true` gives concise cache/timing logs
@@ -62,8 +32,6 @@ interface ClientCacheConfig {
62
32
  /** Per-solve timeout forwarded to the scheduler (`ComputeLimits.solveDeadlineMs`). */
63
33
  solveDeadlineMs: number;
64
34
  cachesolve: boolean;
65
- /** Only meaningful with `cachesolve`. */
66
- cacheerroredsolves: boolean;
67
35
  /** Reference large definitions by server cache key instead of re-uploading. */
68
36
  reuseServerDefinitionCache: boolean;
69
37
  /**
@@ -85,6 +53,11 @@ interface ClientCacheConfig {
85
53
  * the cache (`ComputeLimits.computeSolveCacheBytes`, env `COMPUTE_SOLVE_CACHE_MB`).
86
54
  */
87
55
  responseCacheMaxBytes: number;
56
+ /**
57
+ * Largest compute response body read; past it the download is cancelled (`too_large`).
58
+ * Default: no limit.
59
+ */
60
+ maxResponseBytes?: number;
88
61
  debug: ClientCacheDebug;
89
62
  /** Max distinct warm compute servers before the LRU evicts the oldest. Default 16. */
90
63
  maxWarmComputeServers?: number;
@@ -126,8 +99,6 @@ interface SolveCacheStats {
126
99
  evictions: number;
127
100
  }
128
101
  export declare function createClientCache(config: ClientCacheConfig): ClientCache;
129
- //#endregion
130
- //#region src/server/definition-byte-cache.d.ts
131
102
  /**
132
103
  * In-process cache of `.gh` definition bytes, keyed by immutable **version id**.
133
104
  *
@@ -180,16 +151,10 @@ interface DefinitionByteCache {
180
151
  * entirely — every `load()` calls the loader and nothing is retained.
181
152
  */
182
153
  export declare function createDefinitionByteCache(maxBytes: number): DefinitionByteCache;
183
- //#endregion
184
- //#region src/server/solve-pipeline.d.ts
185
154
  /** Compute-response contract version. Bump (and document the change) whenever the envelope's shape changes in a way a consumer could observe. */
186
155
  export declare const COMPUTE_CONTRACT_VERSION: 1;
187
156
  export declare const COMPUTE_VERSION_HEADER = "X-Selva-Compute-Version";
188
- type PipelineInput = SchemaInput & {
189
- minimum?: number;
190
- maximum?: number;
191
- stepSize?: number;
192
- };
157
+ type PipelineInput = SolveInput;
193
158
  interface SolvePipelineArgs {
194
159
  /**
195
160
  * Raw `.gh` bytes, or a byte-cache `DefinitionRef` whose bytes the scheduler
@@ -288,8 +253,6 @@ type SolveOutcome = {
288
253
  durationMs: number;
289
254
  error: unknown;
290
255
  };
291
- /** The transformed input tree exactly as handed to the scheduler; `runSolvePipeline` calls this itself unless the caller supplies {@link SolvePipelineArgs.inputTree}. */
292
- export declare function buildSolveInputTree(inputs: PipelineInput[], values: Record<string, unknown>): DataTree[];
293
256
  export declare function runSolvePipeline(args: SolvePipelineArgs): Promise<SolveOutcome>;
294
257
  /**
295
258
  * Re-key a coalesced envelope to a single waiter's `Accept-Encoding`.
@@ -310,19 +273,8 @@ export declare function adaptEnvelopeToEncoding(envelope: SolveEnvelope, acceptE
310
273
  body: string | Uint8Array;
311
274
  headers: Record<string, string>;
312
275
  };
313
- //#endregion
314
- //#region src/server/transform-input.d.ts
315
- /**
316
- * `SchemaInput` has no `values`/`acceptedFormats` (those live on the layout item's config), so
317
- * valueList/file inputs here carry just the selected value with no option list.
318
- */
319
- export declare function transformInputParameter(input: SchemaInput & {
320
- minimum?: number;
321
- maximum?: number;
322
- stepSize?: number;
323
- }, value: unknown): InputParam;
324
- //#endregion
325
- //#region src/server/solve-cache-single-flight.d.ts
276
+ /** The input tree a solve sends: each input's value, or its schema default when it has none. */
277
+ export declare function buildSolveInputTree(inputs: SolveInput[], values: Record<string, unknown>): DataTree[];
326
278
  /**
327
279
  * In-process single-flight — dogpile protection for every solve.
328
280
  *
@@ -358,8 +310,6 @@ interface SolveCacheSingleFlightOptions {
358
310
  onJoin?: (key: string) => void;
359
311
  }
360
312
  export declare function createSolveCacheSingleFlight(options?: SolveCacheSingleFlightOptions): SolveCacheSingleFlight;
361
- //#endregion
362
- //#region src/server/solve-engine.d.ts
363
313
  /**
364
314
  * Subset of `ComputeLimits` (`@selvajs/server/compute`) the engine needs.
365
315
  * Pass the resolved object through as-is — extra fields are ignored.
@@ -369,7 +319,6 @@ interface SolveEngineLimits {
369
319
  computeResponseMaxBytes: number;
370
320
  computeReuseDefinitionCache: boolean;
371
321
  computeServerCachesolve: boolean;
372
- computeCacheErroredSolves: boolean;
373
322
  computeMaxQueueDepth: number;
374
323
  computeQueueWaitMs: number;
375
324
  computeDefinitionCacheBytes: number;
@@ -463,6 +412,5 @@ export declare class SolveEngine {
463
412
  toWebResponse(outcome: SolveOutcome): Response;
464
413
  private resolveDefinitionSource;
465
414
  }
466
- //#endregion
467
415
  export { type ByteCacheRef, type ByteCacheStats, type ByteRefOutcome, type CachedClient, type ClientCache, type ClientCacheConfig, type DefinitionByteCache, type DefinitionRef, type FrameworkAgnosticResponse, type PipelineInput, type ResolvedServer, type ServerIdentity, type SolveCacheSingleFlight, type SolveCacheSingleFlightOptions, type SolveCacheStats, type SolveDefinition, type SolveEngineDefinitionSource, type SolveEngineLimits, type SolveEngineOptions, type SolveEngineSolveArgs, type SolveEngineStats, type SolveEnvelope, type SolveInput, type SolveOutcome, type SolvePhaseMetrics, type SolvePipelineArgs, isDefinitionRef };
468
416
  //# sourceMappingURL=server.d.cts.map
package/dist/server.d.ts CHANGED
@@ -1,9 +1,7 @@
1
- import { t as SolveInput } from "./solve-input-BDv_JdvS.js";
2
- import { SchemaInput } from "@selvajs/schemas";
3
- import { DataTree, DefinitionRef as DefinitionRef$1, GrasshopperClient, GrasshopperComputeResponse, InputParam, SelvaEventTarget, SolveScheduler } from "@selvajs/compute/grasshopper";
4
- import { DefinitionRef, SolveDefinition, SolveDefinition as SolveDefinition$1, isDefinitionRef } from "@selvajs/compute/core";
1
+ import { t as SolveInput } from "./solve-input-CUjVGYPC.js";
2
+ import { DataTree, GrasshopperClient, GrasshopperComputeResponse, SelvaEventTarget, SolveScheduler } from "@selvajs/compute/grasshopper";
3
+ import { DefinitionRef, DefinitionRef as DefinitionRef$1, SolveDefinition, SolveDefinition as SolveDefinition$1, isDefinitionRef } from "@selvajs/compute/core";
5
4
  import { ILogger } from "@selvajs/platform";
6
- //#region src/server/client-cache.d.ts
7
5
  /**
8
6
  * Opaque identity of a compute server — construct only via `serverIdentity()`.
9
7
  * Kept opaque so "a server is now a pool of URLs behind one id" stays additive.
@@ -22,34 +20,6 @@ export declare function serverIdentity(server: Pick<ResolvedServer, 'id'>): Serv
22
20
  interface CachedClient {
23
21
  client: GrasshopperClient;
24
22
  scheduler: SolveScheduler;
25
- /**
26
- * Last Server-Timing decode/solve/encode, written by `onServerTiming`. The
27
- * scheduler runs up to `maxConcurrent` solves at once, so `last` alone can't
28
- * be trusted per-request: callers snapshot `seq` before their solve and only
29
- * attribute `last` to themselves if exactly one write happened since (see
30
- * the guard in `runSolvePipeline`), dropping it otherwise rather than risk
31
- * misattributing another request's timing.
32
- */
33
- rhinoTiming: {
34
- last: {
35
- decode: number;
36
- solve: number;
37
- encode: number;
38
- } | null;
39
- seq: number;
40
- };
41
- /**
42
- * Same snapshot-and-attribute pattern as `rhinoTiming`, for the scheduler's
43
- * `onSettle` cache verdict. `seq` increments on every settle (success or
44
- * error); `last` is written only on success.
45
- */
46
- solveMeta: {
47
- last: {
48
- fromCache: boolean;
49
- definitionReuploaded?: boolean;
50
- } | null;
51
- seq: number;
52
- };
53
23
  }
54
24
  /**
55
25
  * Debug verbosity: `false` is silent, `true` gives concise cache/timing logs
@@ -62,8 +32,6 @@ interface ClientCacheConfig {
62
32
  /** Per-solve timeout forwarded to the scheduler (`ComputeLimits.solveDeadlineMs`). */
63
33
  solveDeadlineMs: number;
64
34
  cachesolve: boolean;
65
- /** Only meaningful with `cachesolve`. */
66
- cacheerroredsolves: boolean;
67
35
  /** Reference large definitions by server cache key instead of re-uploading. */
68
36
  reuseServerDefinitionCache: boolean;
69
37
  /**
@@ -85,6 +53,11 @@ interface ClientCacheConfig {
85
53
  * the cache (`ComputeLimits.computeSolveCacheBytes`, env `COMPUTE_SOLVE_CACHE_MB`).
86
54
  */
87
55
  responseCacheMaxBytes: number;
56
+ /**
57
+ * Largest compute response body read; past it the download is cancelled (`too_large`).
58
+ * Default: no limit.
59
+ */
60
+ maxResponseBytes?: number;
88
61
  debug: ClientCacheDebug;
89
62
  /** Max distinct warm compute servers before the LRU evicts the oldest. Default 16. */
90
63
  maxWarmComputeServers?: number;
@@ -126,8 +99,6 @@ interface SolveCacheStats {
126
99
  evictions: number;
127
100
  }
128
101
  export declare function createClientCache(config: ClientCacheConfig): ClientCache;
129
- //#endregion
130
- //#region src/server/definition-byte-cache.d.ts
131
102
  /**
132
103
  * In-process cache of `.gh` definition bytes, keyed by immutable **version id**.
133
104
  *
@@ -180,16 +151,10 @@ interface DefinitionByteCache {
180
151
  * entirely — every `load()` calls the loader and nothing is retained.
181
152
  */
182
153
  export declare function createDefinitionByteCache(maxBytes: number): DefinitionByteCache;
183
- //#endregion
184
- //#region src/server/solve-pipeline.d.ts
185
154
  /** Compute-response contract version. Bump (and document the change) whenever the envelope's shape changes in a way a consumer could observe. */
186
155
  export declare const COMPUTE_CONTRACT_VERSION: 1;
187
156
  export declare const COMPUTE_VERSION_HEADER = "X-Selva-Compute-Version";
188
- type PipelineInput = SchemaInput & {
189
- minimum?: number;
190
- maximum?: number;
191
- stepSize?: number;
192
- };
157
+ type PipelineInput = SolveInput;
193
158
  interface SolvePipelineArgs {
194
159
  /**
195
160
  * Raw `.gh` bytes, or a byte-cache `DefinitionRef` whose bytes the scheduler
@@ -288,8 +253,6 @@ type SolveOutcome = {
288
253
  durationMs: number;
289
254
  error: unknown;
290
255
  };
291
- /** The transformed input tree exactly as handed to the scheduler; `runSolvePipeline` calls this itself unless the caller supplies {@link SolvePipelineArgs.inputTree}. */
292
- export declare function buildSolveInputTree(inputs: PipelineInput[], values: Record<string, unknown>): DataTree[];
293
256
  export declare function runSolvePipeline(args: SolvePipelineArgs): Promise<SolveOutcome>;
294
257
  /**
295
258
  * Re-key a coalesced envelope to a single waiter's `Accept-Encoding`.
@@ -310,19 +273,8 @@ export declare function adaptEnvelopeToEncoding(envelope: SolveEnvelope, acceptE
310
273
  body: string | Uint8Array;
311
274
  headers: Record<string, string>;
312
275
  };
313
- //#endregion
314
- //#region src/server/transform-input.d.ts
315
- /**
316
- * `SchemaInput` has no `values`/`acceptedFormats` (those live on the layout item's config), so
317
- * valueList/file inputs here carry just the selected value with no option list.
318
- */
319
- export declare function transformInputParameter(input: SchemaInput & {
320
- minimum?: number;
321
- maximum?: number;
322
- stepSize?: number;
323
- }, value: unknown): InputParam;
324
- //#endregion
325
- //#region src/server/solve-cache-single-flight.d.ts
276
+ /** The input tree a solve sends: each input's value, or its schema default when it has none. */
277
+ export declare function buildSolveInputTree(inputs: SolveInput[], values: Record<string, unknown>): DataTree[];
326
278
  /**
327
279
  * In-process single-flight — dogpile protection for every solve.
328
280
  *
@@ -358,8 +310,6 @@ interface SolveCacheSingleFlightOptions {
358
310
  onJoin?: (key: string) => void;
359
311
  }
360
312
  export declare function createSolveCacheSingleFlight(options?: SolveCacheSingleFlightOptions): SolveCacheSingleFlight;
361
- //#endregion
362
- //#region src/server/solve-engine.d.ts
363
313
  /**
364
314
  * Subset of `ComputeLimits` (`@selvajs/server/compute`) the engine needs.
365
315
  * Pass the resolved object through as-is — extra fields are ignored.
@@ -369,7 +319,6 @@ interface SolveEngineLimits {
369
319
  computeResponseMaxBytes: number;
370
320
  computeReuseDefinitionCache: boolean;
371
321
  computeServerCachesolve: boolean;
372
- computeCacheErroredSolves: boolean;
373
322
  computeMaxQueueDepth: number;
374
323
  computeQueueWaitMs: number;
375
324
  computeDefinitionCacheBytes: number;
@@ -463,6 +412,5 @@ export declare class SolveEngine {
463
412
  toWebResponse(outcome: SolveOutcome): Response;
464
413
  private resolveDefinitionSource;
465
414
  }
466
- //#endregion
467
415
  export { type ByteCacheRef, type ByteCacheStats, type ByteRefOutcome, type CachedClient, type ClientCache, type ClientCacheConfig, type DefinitionByteCache, type DefinitionRef, type FrameworkAgnosticResponse, type PipelineInput, type ResolvedServer, type ServerIdentity, type SolveCacheSingleFlight, type SolveCacheSingleFlightOptions, type SolveCacheStats, type SolveDefinition, type SolveEngineDefinitionSource, type SolveEngineLimits, type SolveEngineOptions, type SolveEngineSolveArgs, type SolveEngineStats, type SolveEnvelope, type SolveInput, type SolveOutcome, type SolvePhaseMetrics, type SolvePipelineArgs, isDefinitionRef };
468
416
  //# sourceMappingURL=server.d.ts.map
package/dist/server.js CHANGED
@@ -1,2 +1,2 @@
1
- import{GrasshopperClient as e,TreeBuilder as t,isDefinitionRef as n,processInput as r,stableStringify as i}from"@selvajs/compute/grasshopper";import{ComputeError as a,ErrorCodes as o,enableDebugLogging as s,isDefinitionRef as c}from"@selvajs/compute/core";import{gunzipSync as l,gzip as u}from"node:zlib";import{promisify as d}from"node:util";import{NoopLogger as f}from"@selvajs/platform";function p(e,t){let n={id:e.id,name:e.nickname,nickname:e.nickname||null,description:e.description||``,paramType:e.paramType===`dynamicValueList`?`valueList`:e.paramType,treeAccess:e.inputStructure===`tree`,minimum:e.minimum??null,maximum:e.maximum??null,atLeast:1,atMost:1,stepSize:e.stepSize,default:t??e.default},i=r(n),a=t??e.default;return i.default==null&&a!=null&&(Array.isArray(a)||i.paramType===`ValueList`&&typeof a!=`object`)&&(i.default=a),i}const m=d(u),h=1,g=`X-Selva-Compute-Version`;function _(e,n){return t.fromInputParams(e.filter(e=>e.paramType).map(e=>p(e,n[e.id])))}async function v(e){let{client:t,signal:n}=e,r=performance.now(),i=e.inputTree??_(e.inputs,e.values),s=performance.now()-r,c=t.solveMeta.seq,l=t.rhinoTiming.seq,u,d=performance.now();try{u=await t.scheduler.solve(e.definitionSource,i,{signal:n,selvaevents:e.selvaEvents})}catch(t){let r=performance.now()-d,i=t instanceof Error&&t.name===`AbortError`||t instanceof a&&t.code===o.ABORTED,s=t instanceof a&&t.code===o.TIMEOUT_ERROR;if(i||s)return i&&n.aborted?{kind:`client_abort`,durationMs:r}:{kind:`timeout`,durationMs:r,message:`Solve exceeded the ${Math.round(e.solveDeadlineMs/1e3)}s deadline.`};if(t instanceof a){if(t.code===o.QUEUE_FULL)return{kind:`shed`,durationMs:r,reason:`queue_full`,retryAfterSeconds:1,message:`Compute server is at capacity. Retry shortly.`};if(t.code===o.QUEUE_TIMEOUT)return{kind:`shed`,durationMs:r,reason:`queue_timeout`,retryAfterSeconds:1,message:`Compute request waited too long in the queue. Retry shortly.`}}return{kind:`compute_error`,durationMs:r,error:t}}let f=performance.now()-d,p=performance.now(),h;try{h=JSON.stringify(u)}catch(e){if(e instanceof RangeError)return{kind:`too_large`};throw e}if(h.length>e.responseMaxBytes)return{kind:`too_large`};let v=performance.now()-p,y=/\bgzip\b/i.test(e.acceptEncoding)&&h.length>1024,x=null,S=0;if(y){let e=performance.now();x=await m(Buffer.from(h)),S=performance.now()-e}let C=performance.now()-e.loadStartMs,w=t.solveMeta.seq===c+1?t.solveMeta.last:null,T=w&&!w.fromCache&&t.rhinoTiming.seq===l+1?t.rhinoTiming.last:null,E={"Content-Type":`application/json`,"Server-Timing":b({defLoadMs:e.defLoadMs,treeBuildMs:s,solveMs:f,serializeMs:v,gzipMs:S,serverTotalMs:C,rhino:T,settle:w,byteRefOutcome:e.byteRefOutcome,prepMarks:e.prepMarks??[]}),[g]:`1`,Vary:`Accept-Encoding`},D={treeBuildMs:s,solveMs:f,serializeMs:v,gzipMs:S,serverTotalMs:C,serializedBytes:h.length,compressedBytes:x?.byteLength??null},O;return x?(E[`Content-Encoding`]=`gzip`,E[`Content-Length`]=String(x.byteLength),O={body:new Uint8Array(x),encoding:`gzip`,headers:E,result:u,metrics:D}):(E[`Content-Length`]=String(Buffer.byteLength(h)),O={body:h,headers:E,result:u,metrics:D}),{kind:`ok`,envelope:O,solveMs:f,errorCount:u.errors?.length??0,warningCount:u.warnings?.length??0}}function y(e,t){let n=/\bgzip\b/i.test(t);if(e.encoding===`gzip`&&!n){let t=l(e.body instanceof Uint8Array?e.body:Buffer.from(e.body)).toString(`utf8`),n={...e.headers};return delete n[`Content-Encoding`],n[`Content-Length`]=String(Buffer.byteLength(t)),{body:t,headers:n}}return{body:e.body,headers:e.headers}}function b(e){let t=`load;dur=${e.defLoadMs.toFixed(1)}, tree;dur=${e.treeBuildMs.toFixed(1)}, solve;dur=${e.solveMs.toFixed(1)}, serialize;dur=${e.serializeMs.toFixed(1)}, gzip;dur=${e.gzipMs.toFixed(1)}, total;dur=${e.serverTotalMs.toFixed(1)}`,n=e.rhino;if(n){let r=n.decode+n.solve+n.encode,i=Math.max(0,e.solveMs-r);t+=`, rhino_decode;dur=${n.decode.toFixed(1)}, rhino_solve;dur=${n.solve.toFixed(1)}, rhino_encode;dur=${n.encode.toFixed(1)}, compute_link;dur=${i.toFixed(1)}`}for(let[n,r]of e.prepMarks)t+=`, p_${n};dur=${r.toFixed(1)}`;let r=e.settle;r&&(t+=`, selva_cache;dur=${+!!r.fromCache}`,r.definitionReuploaded!==void 0&&(t+=`, def_reupload;dur=${+!!r.definitionReuploaded}`));let i=e.byteRefOutcome;if(i){let e=i.loaded?i.fromCache?`hit`:`miss`:`skipped`;t+=`, def_bytes;desc=${e}`}return t}function x(e){return e.id}const S=5e3;function C(t){let n=t.maxWarmComputeServers??16,r=new Map,i=new Map,a=new Map;t.debug===`verbose`&&s();let o=e=>{t.debug&&t.onDebugLog?.(e)};async function c(n,r){let i={last:null,seq:0},a={last:null,seq:0},s=t.debug===`verbose`,c={serverUrl:n.serverUrl,apiKey:n.apiKey,debug:s,cachesolve:t.cachesolve,cacheerroredsolves:t.cacheerroredsolves,onServerTiming:e=>{let n=e.decode??0,r=e.solve??0,a=e.encode??0;if(i.seq+=1,i.last={decode:n,solve:r,encode:a},!t.debug)return;let s=n<=1?`HIT (definition reused, no re-upload/parse)`:`miss (full parse)`,c=t.cachesolve&&r<=1?`HIT (cached result, solve skipped)`:t.cachesolve?`miss (solved fresh)`:`off`;o(`[Compute/rhino-cache] decode=${n}ms solve=${r}ms encode=${a}ms | definition-cache: ${s} | solve-cache (cachesolve): ${c}`)}};r&&(c.headers={"X-Selva-Definition":r});let l=await e.create(c),u=1,d=0,f=!1;async function p(e){if(!f){f=!0;try{let t=await Promise.resolve(l.serverStats?.getActiveChildren({initialize:!1})).catch(()=>null);d=Date.now();let n=!t||t<=0?1:t;if(n===u)return;o(`[Compute/client-cache] concurrency ${u} → ${n} (server child count)`),u=n,e?.setMaxConcurrent(n)}finally{f=!1}}}await p();let m=l.createScheduler({mode:`queue`,maxConcurrent:u,maxQueueDepth:t.maxQueueDepth||void 0,queueWaitMs:t.queueWaitMs||void 0,timeoutMs:t.solveDeadlineMs,cache:t.responseCacheMaxBytes>0&&{maxBytes:t.responseCacheMaxBytes},reuseServerDefinitionCache:t.reuseServerDefinitionCache,onSettle:(e,n)=>{if(a.seq+=1,n.status===`success`&&(n.fromCache!==!0&&Date.now()-d>=3e5&&p(m),a.last={fromCache:n.fromCache===!0,definitionReuploaded:n.definitionReuploaded},t.debug&&(o(`[Compute/selva-cache] ${n.fromCache?`HIT — served from cache (no compute call)`:`miss — went to Rhino.Compute`} (${Math.round(n.durationMs)}ms)`),n.fromCache||o(n.definitionReuploaded===!0?`[Compute/def-cache] miss — definition RE-UPLOADED (pointer was cold/stale)`:n.definitionReuploaded===!1?`[Compute/def-cache] HIT — definition reused from server cache (no upload)`:`[Compute/def-cache] n/a — reuse disabled or non-reusable definition`),!n.fromCache))){let e=n.response?.errors,r=Array.isArray(e)?e.length:0;if(r>0){let n=t.cacheerroredsolves?`cached (cacheerroredsolves on)`:`not cached (cacheerroredsolves off) — re-run until fixed`;o(`[Compute/rhino-cache] ${r} GH error(s); ${n}. First: ${JSON.stringify(e[0])}`)}}}});return{client:l,scheduler:m,rhinoTiming:i,solveMeta:a}}return{async getClient(e,t){let s=e.id,l=r.get(s);if(l)return r.delete(s),r.set(s,l),l;let u=i.get(s);if(u)return u;let d=a.get(s);if(d){if(Date.now()-d.at<S)throw o(`[Compute/client-cache] server ${s} failed to build <${S}ms ago — replaying error`),d.error;a.delete(s)}o(`[Compute/client-cache] miss — building warm client for server ${s}`);let f=(async()=>{let i;try{i=await c(e,t?.definitionGuid)}catch(e){throw a.set(s,{error:e,at:Date.now()}),e}if(r.size>=n){let e=r.keys().next().value;e!==void 0&&(o(`[Compute/client-cache] LRU evicted warm client for server ${e} (cap ${n})`),r.get(e)?.scheduler.dispose(),r.delete(e))}return r.set(s,i),i})().finally(()=>i.delete(s));return i.set(s,f),f},evict(e){let t=e;a.delete(t);let n=r.get(t);n&&(o(`[Compute/client-cache] evicted warm client for server ${t} (config change)`),n.scheduler.dispose(),r.delete(t))},solveCacheStats(){let e={warmClients:r.size,entries:0,bytes:0,hits:0,misses:0,evictions:0};for(let t of r.values()){let n=t.scheduler.cacheStats();e.entries+=n.entries,e.bytes+=n.bytes,e.hits+=n.hits,e.misses+=n.misses,e.evictions+=n.evictions}return e},clearSolveCaches(){o(`[Compute/client-cache] cleared solve caches on ${r.size} warm client(s)`);for(let e of r.values())e.scheduler.clearCache()},disposeAll(){o(`[Compute/client-cache] disposing all ${r.size} warm client(s)`);for(let e of r.values())e.scheduler.dispose();r.clear(),a.clear()}}}function w(e){let t=Math.max(0,Math.floor(e)),n=new Map,r=0,i={hits:0,misses:0,evictions:0};function a(e,t){n.delete(e),n.set(e,t)}function o(){for(;r>t&&n.size>0;){let e=n.keys().next().value,t=n.get(e);n.delete(e),r-=t.bytes.byteLength,i.evictions+=1}}function s(e,i){if(t===0||i.byteLength>t)return;let a=n.get(e);a&&(r-=a.bytes.byteLength),n.set(e,{bytes:i}),r+=i.byteLength,o()}return{getOrLoad(e,t){let r={loaded:!1,fromCache:!1};return{key:e,outcome:r,load:async()=>{let o=n.get(e);if(o)return a(e,o),i.hits+=1,r.loaded=!0,r.fromCache=!0,o.bytes;i.misses+=1,r.loaded=!0,r.fromCache=!1;let c=await t();return s(e,c),c}}},stats(){return{hits:i.hits,misses:i.misses,evictions:i.evictions,entries:n.size,bytes:r}},clear(){n.clear(),r=0}}}function T(e={}){let t=new Map;return{run(n,r,i){let a=t.get(n);if(a)return e.onJoin?.(n),a.notifyOwner?.(),a.promise;let o={notifyOwner:i,promise:void 0},s=(async()=>r())().finally(()=>{o.notifyOwner=void 0,t.get(n)===o&&t.delete(n)});return o.promise=s,t.set(n,o),s},inFlight(){return t.size}}}function E(e){return typeof e==`object`&&!!e&&!(e instanceof Uint8Array)&&`outcome`in e}function D(e){return typeof e==`object`&&!!e&&!(e instanceof Uint8Array)&&!(`outcome`in e)&&!(`key`in e)&&`versionId`in e}var O=class{limits;clientCache;byteCache;singleFlight;constructor(e){this.limits=e.limits;let t=e.logger??new f;this.clientCache=C({solveDeadlineMs:this.limits.solveDeadlineMs,cachesolve:this.limits.computeServerCachesolve,cacheerroredsolves:this.limits.computeCacheErroredSolves,reuseServerDefinitionCache:this.limits.computeReuseDefinitionCache,maxQueueDepth:this.limits.computeMaxQueueDepth,queueWaitMs:this.limits.computeQueueWaitMs,responseCacheMaxBytes:this.limits.computeSolveCacheBytes,debug:e.debug??!1,maxWarmComputeServers:e.maxWarmComputeServers,onDebugLog:e.onDebugLog??(e=>t.debug(e,{component:`Compute/client-cache`}))}),this.byteCache=w(this.limits.computeDefinitionCacheBytes),this.singleFlight=T({onJoin:e.onSolveCoalesced})}getClient(e,t){return this.clientCache.getClient(e,t)}definitionRef(e,t){return this.byteCache.getOrLoad(e,t)}evictServer(e){this.clientCache.evict(e)}clearSolveCaches(){this.clientCache.clearSolveCaches()}clearDefinitionCache(){this.byteCache.clear()}stats(){return{client:this.clientCache.solveCacheStats(),definitionBytes:this.byteCache.stats(),coalescing:{inFlight:this.singleFlight.inFlight()}}}async solve(e){let{definitionSource:t,byteRefOutcome:n,identity:r}=this.resolveDefinitionSource(e),a=await this.clientCache.getClient(e.server,{definitionGuid:e.definitionGuid}),o=_(e.inputs,e.values),s=`${r}:${e.server.id}:${i(o)}`,c=new AbortController,l=!1,u=()=>{l||c.abort()};e.signal.addEventListener(`abort`,u,{once:!0});let d=e.acceptEncoding??``,f;try{f=await this.singleFlight.run(s,()=>v({definitionSource:t,byteRefOutcome:n,inputs:e.inputs,values:e.values,inputTree:o,client:a,responseMaxBytes:this.limits.computeResponseMaxBytes,solveDeadlineMs:this.limits.solveDeadlineMs,acceptEncoding:d,selvaEvents:e.selvaEvents,signal:c.signal,loadStartMs:e.loadStartMs??performance.now(),defLoadMs:e.defLoadMs??0,prepMarks:e.prepMarks}),()=>{l=!0})}finally{e.signal.removeEventListener(`abort`,u)}if(f.kind!==`ok`)return f;let p=y(f.envelope,d);return{...f,envelope:{...f.envelope,body:p.body,headers:p.headers}}}toResponse(e,t){let n=(e,n)=>{t?.onError&&t.onError(e,n);let r={"Content-Type":`application/json`};return n.retryAfter!==void 0&&(r[`Retry-After`]=String(n.retryAfter)),{status:e,headers:r,body:JSON.stringify(n)}};switch(e.kind){case`ok`:return{status:200,headers:e.envelope.headers,body:e.envelope.body};case`timeout`:return n(504,{message:e.message});case`client_abort`:return n(499,{message:`Client closed request`});case`too_large`:return n(413,{message:`Solve result is too large to return. This usually means a file output exceeds the supported size.`});case`shed`:return n(503,{message:e.message,retryAfter:e.retryAfterSeconds});case`compute_error`:throw e.error}}toWebResponse(e){let t=this.toResponse(e);return new Response(typeof t.body==`string`?t.body:new Uint8Array(t.body),{status:t.status,headers:t.headers})}resolveDefinitionSource(e){let t=e.definitionSource;if(D(t)){let e=this.byteCache.getOrLoad(t.versionId,t.load);return{definitionSource:e,byteRefOutcome:e.outcome,identity:e.key}}if(E(t))return{definitionSource:t,byteRefOutcome:t.outcome,identity:t.key};if(n(t))return{definitionSource:t,identity:t.key};if(!e.definitionKey)throw Error(`SolveEngine.solve(): definitionKey is required when definitionSource is raw bytes or a string.`);return{definitionSource:t,identity:e.definitionKey}}};export{h as COMPUTE_CONTRACT_VERSION,g as COMPUTE_VERSION_HEADER,O as SolveEngine,y as adaptEnvelopeToEncoding,_ as buildSolveInputTree,C as createClientCache,w as createDefinitionByteCache,T as createSolveCacheSingleFlight,c as isDefinitionRef,v as runSolvePipeline,x as serverIdentity,p as transformInputParameter};
1
+ import{GrasshopperClient as e,TreeBuilder as t,stableStringify as n}from"@selvajs/compute/grasshopper";import{ComputeError as r,ErrorCodes as i,enableDebugLogging as a,isDefinitionRef as o,isDefinitionRef as s}from"@selvajs/compute/core";import{gunzipSync as c,gzip as l}from"node:zlib";import{promisify as u}from"node:util";import{NoopLogger as d}from"@selvajs/platform";function f(e,n){return t.fromValues(e.filter(e=>e.paramType).map(e=>({paramName:e.nickname,paramType:e.paramType,value:n[e.id]??e.default,minimum:e.minimum,maximum:e.maximum})))}const p=u(l),m=1,h=`X-Selva-Compute-Version`;async function g(e){let{client:t,signal:n}=e,a=performance.now(),o=e.inputTree??f(e.inputs,e.values),s=performance.now()-a,c=null,l,u,d=performance.now();try{let r=await t.scheduler.solveDetailed(e.definitionSource,o,{signal:n,selvaevents:e.selvaEvents,onServerTiming:e=>{c=e}});l=r.response,u={fromCache:r.fromCache,definitionReuploaded:r.definitionReuploaded}}catch(t){let a=performance.now()-d,o=t instanceof Error&&t.name===`AbortError`||t instanceof r&&t.code===i.ABORTED,s=t instanceof r&&t.code===i.TIMEOUT_ERROR;if(o||s)return o&&n.aborted?{kind:`client_abort`,durationMs:a}:{kind:`timeout`,durationMs:a,message:`Solve exceeded the ${Math.round(e.solveDeadlineMs/1e3)}s deadline.`};if(t instanceof r){if(t.code===i.RESPONSE_TOO_LARGE)return{kind:`too_large`};if(t.code===i.QUEUE_FULL)return{kind:`shed`,durationMs:a,reason:`queue_full`,retryAfterSeconds:1,message:`Compute server is at capacity. Retry shortly.`};if(t.code===i.QUEUE_TIMEOUT)return{kind:`shed`,durationMs:a,reason:`queue_timeout`,retryAfterSeconds:1,message:`Compute request waited too long in the queue. Retry shortly.`}}return{kind:`compute_error`,durationMs:a,error:t}}let m=performance.now()-d,g=performance.now(),_;try{_=JSON.stringify(l)}catch(e){if(e instanceof RangeError)return{kind:`too_large`};throw e}if(_.length>e.responseMaxBytes)return{kind:`too_large`};let y=performance.now()-g,b=/\bgzip\b/i.test(e.acceptEncoding)&&_.length>1024,x=null,S=0;if(b){let e=performance.now();x=await p(Buffer.from(_)),S=performance.now()-e}let C=performance.now()-e.loadStartMs,w={"Content-Type":`application/json`,"Server-Timing":v({defLoadMs:e.defLoadMs,treeBuildMs:s,solveMs:m,serializeMs:y,gzipMs:S,serverTotalMs:C,rhino:c,settle:u,byteRefOutcome:e.byteRefOutcome,prepMarks:e.prepMarks??[]}),[h]:`1`,Vary:`Accept-Encoding`},T={treeBuildMs:s,solveMs:m,serializeMs:y,gzipMs:S,serverTotalMs:C,serializedBytes:_.length,compressedBytes:x?.byteLength??null},E;return x?(w[`Content-Encoding`]=`gzip`,w[`Content-Length`]=String(x.byteLength),E={body:new Uint8Array(x),encoding:`gzip`,headers:w,result:l,metrics:T}):(w[`Content-Length`]=String(Buffer.byteLength(_)),E={body:_,headers:w,result:l,metrics:T}),{kind:`ok`,envelope:E,solveMs:m,errorCount:l.errors?.length??0,warningCount:l.warnings?.length??0}}function _(e,t){let n=/\bgzip\b/i.test(t);if(e.encoding===`gzip`&&!n){let t=c(e.body instanceof Uint8Array?e.body:Buffer.from(e.body)).toString(`utf8`),n={...e.headers};return delete n[`Content-Encoding`],n[`Content-Length`]=String(Buffer.byteLength(t)),{body:t,headers:n}}return{body:e.body,headers:e.headers}}function v(e){let t=`load;dur=${e.defLoadMs.toFixed(1)}, tree;dur=${e.treeBuildMs.toFixed(1)}, solve;dur=${e.solveMs.toFixed(1)}, serialize;dur=${e.serializeMs.toFixed(1)}, gzip;dur=${e.gzipMs.toFixed(1)}, total;dur=${e.serverTotalMs.toFixed(1)}`,n=e.rhino;if(n){let r=n.decode??0,i=n.solve??0,a=n.encode??0,o=Math.max(0,e.solveMs-r-i-a);t+=`, rhino_decode;dur=${r.toFixed(1)}, rhino_solve;dur=${i.toFixed(1)}, rhino_encode;dur=${a.toFixed(1)}, compute_link;dur=${o.toFixed(1)}, rhino_cache;dur=${+!!n.cacheHit}`,n.gh!==void 0&&(t+=`, rhino_gh;dur=${n.gh.toFixed(1)}`),n.recomputed&&(t+=`, rhino_recomputed;desc="${n.recomputed.ran}/${n.recomputed.total}"`)}for(let[n,r]of e.prepMarks)t+=`, p_${n};dur=${r.toFixed(1)}`;let r=e.settle;t+=`, selva_cache;dur=${+!!r.fromCache}`,r.definitionReuploaded!==void 0&&(t+=`, def_reupload;dur=${+!!r.definitionReuploaded}`);let i=e.byteRefOutcome;if(i){let e=i.loaded?i.fromCache?`hit`:`miss`:`skipped`;t+=`, def_bytes;desc=${e}`}return t}function y(e){return e.id}const b=5e3;function x(t){let n=t.maxWarmComputeServers??16,r=/* @__PURE__ */ new Map,i=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Map;t.debug===`verbose`&&a();let s=e=>{t.debug&&t.onDebugLog?.(e)};async function c(n,r){let i=t.debug===`verbose`,a={serverUrl:n.serverUrl,apiKey:n.apiKey,debug:i,cachesolve:t.cachesolve,maxResponseBytes:t.maxResponseBytes};t.debug&&(a.onServerTiming=e=>{if(e.cacheHit){s(`[Compute/rhino-cache] solve-cache (cachesolve): HIT (cached result, solve skipped)`);return}let n=e.decode??0,r=e.solve??0,i=e.encode??0,a=n<=1?`HIT (definition reused, no re-upload/parse)`:`miss (full parse)`,o=t.cachesolve?`miss (solved fresh)`:`off`,c=e.recomputed?` | ran ${e.recomputed.ran}/${e.recomputed.total} objects`:``;s(`[Compute/rhino-cache] decode=${n}ms solve=${r}ms encode=${i}ms | definition-cache: ${a} | solve-cache (cachesolve): ${o}${c}`)}),r&&(a.headers={"X-Selva-Definition":r});let o=await e.create(a),c=1,l=0,u=!1;async function d(e){if(!u){u=!0;try{let t=await Promise.resolve(o.serverStats?.getActiveChildren({initialize:!1})).catch(()=>null);l=Date.now();let n=!t||t<=0?1:t;if(n===c)return;s(`[Compute/client-cache] concurrency ${c} → ${n} (server child count)`),c=n,e?.setMaxConcurrent(n)}finally{u=!1}}}await d();let f=o.createScheduler({mode:`queue`,maxConcurrent:c,maxQueueDepth:t.maxQueueDepth||void 0,queueWaitMs:t.queueWaitMs||void 0,timeoutMs:t.solveDeadlineMs,cache:t.responseCacheMaxBytes>0&&{maxBytes:t.responseCacheMaxBytes},reuseServerDefinitionCache:t.reuseServerDefinitionCache,onSettle:(e,n)=>{if(n.status===`success`&&(n.fromCache!==!0&&Date.now()-l>=3e5&&d(f),t.debug&&(s(`[Compute/selva-cache] ${n.fromCache?`HIT — served from cache (no compute call)`:`miss — went to Rhino.Compute`} (${Math.round(n.durationMs)}ms)`),n.fromCache||s(n.definitionReuploaded===!0?`[Compute/def-cache] miss — definition RE-UPLOADED (pointer was cold/stale)`:n.definitionReuploaded===!1?`[Compute/def-cache] HIT — definition reused from server cache (no upload)`:`[Compute/def-cache] n/a — reuse disabled or non-reusable definition`),!n.fromCache))){let e=n.response?.errors,t=Array.isArray(e)?e.length:0;t>0&&s(`[Compute/rhino-cache] ${t} GH error(s); not cached by Rhino.Compute. First: ${JSON.stringify(e[0])}`)}}});return{client:o,scheduler:f}}return{async getClient(e,t){let a=e.id,l=r.get(a);if(l)return r.delete(a),r.set(a,l),l;let u=i.get(a);if(u)return u;let d=o.get(a);if(d){if(Date.now()-d.at<b)throw s(`[Compute/client-cache] server ${a} failed to build <${b}ms ago — replaying error`),d.error;o.delete(a)}s(`[Compute/client-cache] miss — building warm client for server ${a}`);let f=(async()=>{let i;try{i=await c(e,t?.definitionGuid)}catch(e){throw o.set(a,{error:e,at:Date.now()}),e}if(r.size>=n){let e=r.keys().next().value;e!==void 0&&(s(`[Compute/client-cache] LRU evicted warm client for server ${e} (cap ${n})`),r.get(e)?.scheduler.dispose(),r.delete(e))}return r.set(a,i),i})().finally(()=>i.delete(a));return i.set(a,f),f},evict(e){let t=e;o.delete(t);let n=r.get(t);n&&(s(`[Compute/client-cache] evicted warm client for server ${t} (config change)`),n.scheduler.dispose(),r.delete(t))},solveCacheStats(){let e={warmClients:r.size,entries:0,bytes:0,hits:0,misses:0,evictions:0};for(let t of r.values()){let n=t.scheduler.cacheStats();e.entries+=n.entries,e.bytes+=n.bytes,e.hits+=n.hits,e.misses+=n.misses,e.evictions+=n.evictions}return e},clearSolveCaches(){s(`[Compute/client-cache] cleared solve caches on ${r.size} warm client(s)`);for(let e of r.values())e.scheduler.clearCache()},disposeAll(){s(`[Compute/client-cache] disposing all ${r.size} warm client(s)`);for(let e of r.values())e.scheduler.dispose();r.clear(),o.clear()}}}function S(e){let t=Math.max(0,Math.floor(e)),n=/* @__PURE__ */ new Map,r=0,i={hits:0,misses:0,evictions:0};function a(e,t){n.delete(e),n.set(e,t)}function o(){for(;r>t&&n.size>0;){let e=n.keys().next().value,t=n.get(e);n.delete(e),r-=t.bytes.byteLength,i.evictions+=1}}function s(e,i){if(t===0||i.byteLength>t)return;let a=n.get(e);a&&(r-=a.bytes.byteLength),n.set(e,{bytes:i}),r+=i.byteLength,o()}return{getOrLoad(e,t){let r={loaded:!1,fromCache:!1};return{key:e,outcome:r,load:async()=>{let o=n.get(e);if(o)return a(e,o),i.hits+=1,r.loaded=!0,r.fromCache=!0,o.bytes;i.misses+=1,r.loaded=!0,r.fromCache=!1;let c=await t();return s(e,c),c}}},stats(){return{hits:i.hits,misses:i.misses,evictions:i.evictions,entries:n.size,bytes:r}},clear(){n.clear(),r=0}}}function C(e={}){let t=/* @__PURE__ */ new Map;return{run(n,r,i){let a=t.get(n);if(a)return e.onJoin?.(n),a.notifyOwner?.(),a.promise;let o={notifyOwner:i,promise:void 0},s=(async()=>r())().finally(()=>{o.notifyOwner=void 0,t.get(n)===o&&t.delete(n)});return o.promise=s,t.set(n,o),s},inFlight(){return t.size}}}function w(e){return typeof e==`object`&&!!e&&!(e instanceof Uint8Array)&&`outcome`in e}function T(e){return typeof e==`object`&&!!e&&!(e instanceof Uint8Array)&&!(`outcome`in e)&&!(`key`in e)&&`versionId`in e}var E=class{limits;clientCache;byteCache;singleFlight;constructor(e){this.limits=e.limits;let t=e.logger??new d;this.clientCache=x({solveDeadlineMs:this.limits.solveDeadlineMs,cachesolve:this.limits.computeServerCachesolve,reuseServerDefinitionCache:this.limits.computeReuseDefinitionCache,maxQueueDepth:this.limits.computeMaxQueueDepth,queueWaitMs:this.limits.computeQueueWaitMs,responseCacheMaxBytes:this.limits.computeSolveCacheBytes,maxResponseBytes:this.limits.computeResponseMaxBytes,debug:e.debug??!1,maxWarmComputeServers:e.maxWarmComputeServers,onDebugLog:e.onDebugLog??(e=>t.debug(e,{component:`Compute/client-cache`}))}),this.byteCache=S(this.limits.computeDefinitionCacheBytes),this.singleFlight=C({onJoin:e.onSolveCoalesced})}getClient(e,t){return this.clientCache.getClient(e,t)}definitionRef(e,t){return this.byteCache.getOrLoad(e,t)}evictServer(e){this.clientCache.evict(e)}clearSolveCaches(){this.clientCache.clearSolveCaches()}clearDefinitionCache(){this.byteCache.clear()}stats(){return{client:this.clientCache.solveCacheStats(),definitionBytes:this.byteCache.stats(),coalescing:{inFlight:this.singleFlight.inFlight()}}}async solve(e){let{definitionSource:t,byteRefOutcome:r,identity:i}=this.resolveDefinitionSource(e),a=await this.clientCache.getClient(e.server,{definitionGuid:e.definitionGuid}),o=f(e.inputs,e.values),s=`${i}:${e.server.id}:${n(o)}`,c=new AbortController,l=!1,u=()=>{l||c.abort()};e.signal.addEventListener(`abort`,u,{once:!0});let d=e.acceptEncoding??``,p;try{p=await this.singleFlight.run(s,()=>g({definitionSource:t,byteRefOutcome:r,inputs:e.inputs,values:e.values,inputTree:o,client:a,responseMaxBytes:this.limits.computeResponseMaxBytes,solveDeadlineMs:this.limits.solveDeadlineMs,acceptEncoding:d,selvaEvents:e.selvaEvents,signal:c.signal,loadStartMs:e.loadStartMs??performance.now(),defLoadMs:e.defLoadMs??0,prepMarks:e.prepMarks}),()=>{l=!0})}finally{e.signal.removeEventListener(`abort`,u)}if(p.kind!==`ok`)return p;let m=_(p.envelope,d);return{...p,envelope:{...p.envelope,body:m.body,headers:m.headers}}}toResponse(e,t){let n=(e,n)=>{t?.onError&&t.onError(e,n);let r={"Content-Type":`application/json`};return n.retryAfter!==void 0&&(r[`Retry-After`]=String(n.retryAfter)),{status:e,headers:r,body:JSON.stringify(n)}};switch(e.kind){case`ok`:return{status:200,headers:e.envelope.headers,body:e.envelope.body};case`timeout`:return n(504,{message:e.message});case`client_abort`:return n(499,{message:`Client closed request`});case`too_large`:return n(413,{message:`Solve result is too large to return. This usually means a file output exceeds the supported size.`});case`shed`:return n(503,{message:e.message,retryAfter:e.retryAfterSeconds});case`compute_error`:throw e.error}}toWebResponse(e){let t=this.toResponse(e);return new Response(typeof t.body==`string`?t.body:new Uint8Array(t.body),{status:t.status,headers:t.headers})}resolveDefinitionSource(e){let t=e.definitionSource;if(T(t)){let e=this.byteCache.getOrLoad(t.versionId,t.load);return{definitionSource:e,byteRefOutcome:e.outcome,identity:e.key}}if(w(t))return{definitionSource:t,byteRefOutcome:t.outcome,identity:t.key};if(s(t))return{definitionSource:t,identity:t.key};if(!e.definitionKey)throw Error(`SolveEngine.solve(): definitionKey is required when definitionSource is raw bytes or a string.`);return{definitionSource:t,identity:e.definitionKey}}};export{m as COMPUTE_CONTRACT_VERSION,h as COMPUTE_VERSION_HEADER,E as SolveEngine,_ as adaptEnvelopeToEncoding,f as buildSolveInputTree,x as createClientCache,S as createDefinitionByteCache,C as createSolveCacheSingleFlight,o as isDefinitionRef,g as runSolvePipeline,y as serverIdentity};
2
2
  //# sourceMappingURL=server.js.map