@selvajs/server 0.2.0-beta.2 → 0.2.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +32 -0
  3. package/dist/compute/client-cache.d.ts +12 -0
  4. package/dist/compute/client-cache.d.ts.map +1 -1
  5. package/dist/compute/client-cache.js +18 -3
  6. package/dist/compute/client-cache.js.map +1 -1
  7. package/dist/compute/definition-byte-cache.d.ts +85 -0
  8. package/dist/compute/definition-byte-cache.d.ts.map +1 -0
  9. package/dist/compute/definition-byte-cache.js +110 -0
  10. package/dist/compute/definition-byte-cache.js.map +1 -0
  11. package/dist/compute/index.d.ts +7 -2
  12. package/dist/compute/index.d.ts.map +1 -1
  13. package/dist/compute/index.js +6 -1
  14. package/dist/compute/index.js.map +1 -1
  15. package/dist/compute/limits.d.ts +52 -0
  16. package/dist/compute/limits.d.ts.map +1 -1
  17. package/dist/compute/limits.js +33 -1
  18. package/dist/compute/limits.js.map +1 -1
  19. package/dist/compute/memory-solve-cache.d.ts +58 -0
  20. package/dist/compute/memory-solve-cache.d.ts.map +1 -0
  21. package/dist/compute/memory-solve-cache.js +0 -0
  22. package/dist/compute/memory-solve-cache.js.map +1 -0
  23. package/dist/compute/safe-url.d.ts.map +1 -1
  24. package/dist/compute/safe-url.js +16 -0
  25. package/dist/compute/safe-url.js.map +1 -1
  26. package/dist/compute/solve-cache-envelope.d.ts +53 -0
  27. package/dist/compute/solve-cache-envelope.d.ts.map +1 -0
  28. package/dist/compute/solve-cache-envelope.js +66 -0
  29. package/dist/compute/solve-cache-envelope.js.map +1 -0
  30. package/dist/compute/solve-cache-key.d.ts +65 -0
  31. package/dist/compute/solve-cache-key.d.ts.map +1 -0
  32. package/dist/compute/solve-cache-key.js +50 -0
  33. package/dist/compute/solve-cache-key.js.map +1 -0
  34. package/dist/compute/solve-cache-single-flight.d.ts +42 -0
  35. package/dist/compute/solve-cache-single-flight.d.ts.map +1 -0
  36. package/dist/compute/solve-cache-single-flight.js +50 -0
  37. package/dist/compute/solve-cache-single-flight.js.map +1 -0
  38. package/dist/compute/solve-pipeline.d.ts +71 -8
  39. package/dist/compute/solve-pipeline.d.ts.map +1 -1
  40. package/dist/compute/solve-pipeline.js +180 -8
  41. package/dist/compute/solve-pipeline.js.map +1 -1
  42. package/dist/definitions/definition-service.d.ts +1 -1
  43. package/dist/definitions/definition-service.d.ts.map +1 -1
  44. package/dist/definitions/definition-service.js +8 -4
  45. package/dist/definitions/definition-service.js.map +1 -1
  46. package/package.json +14 -18
  47. package/dist/access/__tests__/project-access-input.test.d.ts +0 -2
  48. package/dist/access/__tests__/project-access-input.test.d.ts.map +0 -1
  49. package/dist/access/__tests__/project-access-input.test.js +0 -146
  50. package/dist/access/__tests__/project-access-input.test.js.map +0 -1
  51. package/dist/compute/__tests__/client-cache.test.d.ts +0 -11
  52. package/dist/compute/__tests__/client-cache.test.d.ts.map +0 -1
  53. package/dist/compute/__tests__/client-cache.test.js +0 -200
  54. package/dist/compute/__tests__/client-cache.test.js.map +0 -1
  55. package/dist/compute/__tests__/rate-limit.test.d.ts +0 -2
  56. package/dist/compute/__tests__/rate-limit.test.d.ts.map +0 -1
  57. package/dist/compute/__tests__/rate-limit.test.js +0 -98
  58. package/dist/compute/__tests__/rate-limit.test.js.map +0 -1
  59. package/dist/compute/__tests__/remote-definition.test.d.ts +0 -11
  60. package/dist/compute/__tests__/remote-definition.test.d.ts.map +0 -1
  61. package/dist/compute/__tests__/remote-definition.test.js +0 -114
  62. package/dist/compute/__tests__/remote-definition.test.js.map +0 -1
  63. package/dist/compute/__tests__/safe-url.test.d.ts +0 -2
  64. package/dist/compute/__tests__/safe-url.test.d.ts.map +0 -1
  65. package/dist/compute/__tests__/safe-url.test.js +0 -71
  66. package/dist/compute/__tests__/safe-url.test.js.map +0 -1
  67. package/dist/compute/__tests__/solve-pipeline.test.d.ts +0 -11
  68. package/dist/compute/__tests__/solve-pipeline.test.d.ts.map +0 -1
  69. package/dist/compute/__tests__/solve-pipeline.test.js +0 -292
  70. package/dist/compute/__tests__/solve-pipeline.test.js.map +0 -1
  71. package/dist/compute/__tests__/transform-input.test.d.ts +0 -14
  72. package/dist/compute/__tests__/transform-input.test.d.ts.map +0 -1
  73. package/dist/compute/__tests__/transform-input.test.js +0 -120
  74. package/dist/compute/__tests__/transform-input.test.js.map +0 -1
  75. package/dist/definitions/__tests__/load-for-render.test.d.ts +0 -8
  76. package/dist/definitions/__tests__/load-for-render.test.d.ts.map +0 -1
  77. package/dist/definitions/__tests__/load-for-render.test.js +0 -196
  78. package/dist/definitions/__tests__/load-for-render.test.js.map +0 -1
  79. package/dist/definitions/__tests__/schema-extraction.test.d.ts +0 -11
  80. package/dist/definitions/__tests__/schema-extraction.test.d.ts.map +0 -1
  81. package/dist/definitions/__tests__/schema-extraction.test.js +0 -115
  82. package/dist/definitions/__tests__/schema-extraction.test.js.map +0 -1
  83. package/dist/http/__tests__/body-size.test.d.ts +0 -2
  84. package/dist/http/__tests__/body-size.test.d.ts.map +0 -1
  85. package/dist/http/__tests__/body-size.test.js +0 -24
  86. package/dist/http/__tests__/body-size.test.js.map +0 -1
  87. package/dist/http/__tests__/route-classifier.test.d.ts +0 -2
  88. package/dist/http/__tests__/route-classifier.test.d.ts.map +0 -1
  89. package/dist/http/__tests__/route-classifier.test.js +0 -54
  90. package/dist/http/__tests__/route-classifier.test.js.map +0 -1
  91. package/dist/http/__tests__/safe-redirect.test.d.ts +0 -2
  92. package/dist/http/__tests__/safe-redirect.test.d.ts.map +0 -1
  93. package/dist/http/__tests__/safe-redirect.test.js +0 -44
  94. package/dist/http/__tests__/safe-redirect.test.js.map +0 -1
  95. package/dist/http/__tests__/security-headers.test.d.ts +0 -2
  96. package/dist/http/__tests__/security-headers.test.d.ts.map +0 -1
  97. package/dist/http/__tests__/security-headers.test.js +0 -24
  98. package/dist/http/__tests__/security-headers.test.js.map +0 -1
  99. package/dist/ops/__tests__/semver.test.d.ts +0 -2
  100. package/dist/ops/__tests__/semver.test.d.ts.map +0 -1
  101. package/dist/ops/__tests__/semver.test.js +0 -38
  102. package/dist/ops/__tests__/semver.test.js.map +0 -1
  103. package/dist/providers/__tests__/create-selva-providers.test.d.ts +0 -7
  104. package/dist/providers/__tests__/create-selva-providers.test.d.ts.map +0 -1
  105. package/dist/providers/__tests__/create-selva-providers.test.js +0 -135
  106. package/dist/providers/__tests__/create-selva-providers.test.js.map +0 -1
  107. package/dist/tokens/__tests__/token-codec.test.d.ts +0 -2
  108. package/dist/tokens/__tests__/token-codec.test.d.ts.map +0 -1
  109. package/dist/tokens/__tests__/token-codec.test.js +0 -50
  110. package/dist/tokens/__tests__/token-codec.test.js.map +0 -1
  111. package/src/access/__tests__/project-access-input.test.ts +0 -175
  112. package/src/access/index.ts +0 -9
  113. package/src/access/project-access-input.ts +0 -145
  114. package/src/compute/__tests__/client-cache.test.ts +0 -224
  115. package/src/compute/__tests__/rate-limit.test.ts +0 -106
  116. package/src/compute/__tests__/remote-definition.test.ts +0 -140
  117. package/src/compute/__tests__/safe-url.test.ts +0 -72
  118. package/src/compute/__tests__/solve-pipeline.test.ts +0 -341
  119. package/src/compute/__tests__/transform-input.test.ts +0 -162
  120. package/src/compute/client-cache.ts +0 -300
  121. package/src/compute/index.ts +0 -48
  122. package/src/compute/limits.ts +0 -159
  123. package/src/compute/rate-limit.ts +0 -110
  124. package/src/compute/remote-definition.ts +0 -149
  125. package/src/compute/safe-url.ts +0 -186
  126. package/src/compute/solve-pipeline.ts +0 -339
  127. package/src/compute/transform-input.ts +0 -66
  128. package/src/definitions/__tests__/load-for-render.test.ts +0 -244
  129. package/src/definitions/__tests__/schema-extraction.test.ts +0 -137
  130. package/src/definitions/definition-service.ts +0 -243
  131. package/src/definitions/index.ts +0 -22
  132. package/src/definitions/load-for-render.ts +0 -272
  133. package/src/definitions/schema-extraction.ts +0 -117
  134. package/src/errors/SentryErrorReporter.ts +0 -88
  135. package/src/errors/index.ts +0 -3
  136. package/src/http/__tests__/body-size.test.ts +0 -27
  137. package/src/http/__tests__/route-classifier.test.ts +0 -60
  138. package/src/http/__tests__/safe-redirect.test.ts +0 -47
  139. package/src/http/__tests__/security-headers.test.ts +0 -29
  140. package/src/http/body-size.ts +0 -24
  141. package/src/http/index.ts +0 -10
  142. package/src/http/redirect.ts +0 -16
  143. package/src/http/route-classifier.ts +0 -74
  144. package/src/http/security-headers.ts +0 -42
  145. package/src/index.ts +0 -27
  146. package/src/ops/__tests__/semver.test.ts +0 -42
  147. package/src/ops/index.ts +0 -3
  148. package/src/ops/semver.ts +0 -60
  149. package/src/providers/__tests__/create-selva-providers.test.ts +0 -172
  150. package/src/providers/__tests__/fixtures/override-config.mjs +0 -8
  151. package/src/providers/create-selva-providers.ts +0 -241
  152. package/src/providers/index.ts +0 -12
  153. package/src/tokens/__tests__/token-codec.test.ts +0 -63
  154. package/src/tokens/index.ts +0 -8
  155. package/src/tokens/token-codec.ts +0 -86
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-solve-cache.js","sourceRoot":"","sources":["../../src/compute/memory-solve-cache.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"safe-url.d.ts","sourceRoot":"","sources":["../../src/compute/safe-url.ts"],"names":[],"mappings":"AA4HA;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA2B9D;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBhF"}
1
+ {"version":3,"file":"safe-url.d.ts","sourceRoot":"","sources":["../../src/compute/safe-url.ts"],"names":[],"mappings":"AA4HA;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA2B9D;AAED;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6BhF"}
@@ -173,7 +173,11 @@ export function isSafeRemoteDefinitionUrl(raw) {
173
173
  * any rejection.
174
174
  */
175
175
  export async function assertSafeRemoteDefinitionUrl(raw) {
176
+ // Security-relevant event: the thrown message is deliberately generic (no
177
+ // oracle for the caller), so log the specifics server-side instead — which
178
+ // host was blocked and by which layer.
176
179
  if (!isSafeRemoteDefinitionUrl(raw)) {
180
+ console.warn(`[Compute/ssrf] blocked remote definition URL (literal filter): ${hostOf(raw)}`);
177
181
  throw new Error('Remote definition URL is not allowed');
178
182
  }
179
183
  const host = new URL(raw).hostname.toLowerCase().replace(/^\[|\]$/g, '');
@@ -185,11 +189,23 @@ export async function assertSafeRemoteDefinitionUrl(raw) {
185
189
  resolved = await lookup(host, { all: true });
186
190
  }
187
191
  catch {
192
+ console.warn(`[Compute/ssrf] blocked remote definition URL (DNS lookup failed): ${host}`);
188
193
  throw new Error('Remote definition URL is not allowed');
189
194
  }
190
195
  if (resolved.length === 0 || resolved.some((r) => isBlockedIp(r.address))) {
196
+ const blocked = resolved.filter((r) => isBlockedIp(r.address)).map((r) => r.address);
197
+ console.warn(`[Compute/ssrf] blocked remote definition URL (resolves to blocked IP ${blocked.join(', ') || 'none'}): ${host}`);
191
198
  throw new Error('Remote definition URL is not allowed');
192
199
  }
193
200
  return raw;
194
201
  }
202
+ /** Best-effort hostname for logging; falls back to a truncated raw string. */
203
+ function hostOf(raw) {
204
+ try {
205
+ return new URL(raw).hostname;
206
+ }
207
+ catch {
208
+ return raw.slice(0, 120);
209
+ }
210
+ }
195
211
  //# sourceMappingURL=safe-url.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-url.js","sourceRoot":"","sources":["../../src/compute/safe-url.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"safe-url.js","sourceRoot":"","sources":["../../src/compute/safe-url.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * L2 cache entry format (R6). An entry is the gzipped response body plus a tiny
3
+ * metadata header, so a hit is near-CPU-free: no `JSON.stringify`, no re-solve —
4
+ * gzip clients get the stored bytes verbatim, and the header carries just enough
5
+ * to rebuild the `ok` outcome (error/warning counts for the metric, uncompressed
6
+ * length for the `Content-Length` on a gunzip fallback).
7
+ *
8
+ * Wire layout (opaque to the `ISolveResultCache` backend, which sees only bytes):
9
+ *
10
+ * [ 4 bytes: header length N, big-endian uint32 ]
11
+ * [ N bytes: UTF-8 JSON EnvelopeHeader ]
12
+ * [ rest: gzipped JSON response body ]
13
+ *
14
+ * The `algo` echo (M3) is already stripped at the source in the package's
15
+ * `runSolve`, so the body never carries the base64 definition — entries stay
16
+ * small without a strip step here.
17
+ */
18
+ /** Metadata stored beside the gzipped body. Small; parsed on every hit. */
19
+ export interface EnvelopeHeader {
20
+ /** Grasshopper runtime error count, for the solve metric. */
21
+ errorCount: number;
22
+ /** Grasshopper runtime warning count, for the solve metric. */
23
+ warningCount: number;
24
+ /** Uncompressed JSON body length in bytes (Content-Length for a gunzip fallback). */
25
+ serializedBytes: number;
26
+ /**
27
+ * SHA-256 hex of the canonical input preimage (H2 defense-in-depth). A hit
28
+ * verifies this equals the requesting key's hash before serving — a wide-hash
29
+ * collision that produced the same storage key still can't serve the wrong
30
+ * geometry.
31
+ */
32
+ inputHash: string;
33
+ }
34
+ /**
35
+ * Encode a cache entry from the gzipped body + header. The body MUST already be
36
+ * gzipped (the pipeline gzips before storing so every hit serves compressed
37
+ * bytes; a rare non-gzip client gunzips on read).
38
+ */
39
+ export declare function encodeSolveCacheEntry(header: EnvelopeHeader, gzippedBody: Uint8Array): Uint8Array;
40
+ /** A decoded entry: the parsed header + the still-gzipped body slice. */
41
+ export interface DecodedSolveCacheEntry {
42
+ header: EnvelopeHeader;
43
+ gzippedBody: Uint8Array;
44
+ }
45
+ /**
46
+ * Decode a cache entry. Returns `null` on any malformed input (truncated, bad
47
+ * length prefix, non-JSON header) — a corrupt entry is treated as a miss, never
48
+ * an error, matching the best-effort cache contract.
49
+ */
50
+ export declare function decodeSolveCacheEntry(bytes: Uint8Array): DecodedSolveCacheEntry | null;
51
+ /** Gunzip a stored body back to the JSON string, for a non-gzip client (rare). */
52
+ export declare function gunzipEntryBody(gzippedBody: Uint8Array): string;
53
+ //# sourceMappingURL=solve-cache-envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-cache-envelope.d.ts","sourceRoot":"","sources":["../../src/compute/solve-cache-envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC9B,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,eAAe,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,GAAG,UAAU,CAUjG;AAED,yEAAyE;AACzE,MAAM,WAAW,sBAAsB;IACtC,MAAM,EAAE,cAAc,CAAC;IACvB,WAAW,EAAE,UAAU,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,sBAAsB,GAAG,IAAI,CA2BtF;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,WAAW,EAAE,UAAU,GAAG,MAAM,CAE/D"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * L2 cache entry format (R6). An entry is the gzipped response body plus a tiny
3
+ * metadata header, so a hit is near-CPU-free: no `JSON.stringify`, no re-solve —
4
+ * gzip clients get the stored bytes verbatim, and the header carries just enough
5
+ * to rebuild the `ok` outcome (error/warning counts for the metric, uncompressed
6
+ * length for the `Content-Length` on a gunzip fallback).
7
+ *
8
+ * Wire layout (opaque to the `ISolveResultCache` backend, which sees only bytes):
9
+ *
10
+ * [ 4 bytes: header length N, big-endian uint32 ]
11
+ * [ N bytes: UTF-8 JSON EnvelopeHeader ]
12
+ * [ rest: gzipped JSON response body ]
13
+ *
14
+ * The `algo` echo (M3) is already stripped at the source in the package's
15
+ * `runSolve`, so the body never carries the base64 definition — entries stay
16
+ * small without a strip step here.
17
+ */
18
+ import { gunzipSync } from 'node:zlib';
19
+ /**
20
+ * Encode a cache entry from the gzipped body + header. The body MUST already be
21
+ * gzipped (the pipeline gzips before storing so every hit serves compressed
22
+ * bytes; a rare non-gzip client gunzips on read).
23
+ */
24
+ export function encodeSolveCacheEntry(header, gzippedBody) {
25
+ const headerJson = Buffer.from(JSON.stringify(header), 'utf8');
26
+ const out = Buffer.allocUnsafe(4 + headerJson.byteLength + gzippedBody.byteLength);
27
+ out.writeUInt32BE(headerJson.byteLength, 0);
28
+ headerJson.copy(out, 4);
29
+ Buffer.from(gzippedBody.buffer, gzippedBody.byteOffset, gzippedBody.byteLength).copy(out, 4 + headerJson.byteLength);
30
+ return out;
31
+ }
32
+ /**
33
+ * Decode a cache entry. Returns `null` on any malformed input (truncated, bad
34
+ * length prefix, non-JSON header) — a corrupt entry is treated as a miss, never
35
+ * an error, matching the best-effort cache contract.
36
+ */
37
+ export function decodeSolveCacheEntry(bytes) {
38
+ if (bytes.byteLength < 4)
39
+ return null;
40
+ const buf = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
41
+ const headerLen = buf.readUInt32BE(0);
42
+ const headerEnd = 4 + headerLen;
43
+ if (headerEnd > buf.byteLength)
44
+ return null;
45
+ let header;
46
+ try {
47
+ header = JSON.parse(buf.toString('utf8', 4, headerEnd));
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ if (typeof header?.errorCount !== 'number' ||
53
+ typeof header?.warningCount !== 'number' ||
54
+ typeof header?.serializedBytes !== 'number' ||
55
+ typeof header?.inputHash !== 'string') {
56
+ return null;
57
+ }
58
+ // Slice (view, no copy) of the gzipped remainder.
59
+ const gzippedBody = new Uint8Array(bytes.buffer, bytes.byteOffset + headerEnd, bytes.byteLength - headerEnd);
60
+ return { header, gzippedBody };
61
+ }
62
+ /** Gunzip a stored body back to the JSON string, for a non-gzip client (rare). */
63
+ export function gunzipEntryBody(gzippedBody) {
64
+ return gunzipSync(gzippedBody).toString('utf8');
65
+ }
66
+ //# sourceMappingURL=solve-cache-envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-cache-envelope.js","sourceRoot":"","sources":["../../src/compute/solve-cache-envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAmBvC;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAsB,EAAE,WAAuB;IACpF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,UAAU,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACnF,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC5C,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACxB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC,IAAI,CACnF,GAAG,EACH,CAAC,GAAG,UAAU,CAAC,UAAU,CACzB,CAAC;IACF,OAAO,GAAG,CAAC;AACZ,CAAC;AAQD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiB;IACtD,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;IAChC,IAAI,SAAS,GAAG,GAAG,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,SAAS,CAAC,CAAmB,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;IACD,IACC,OAAO,MAAM,EAAE,UAAU,KAAK,QAAQ;QACtC,OAAO,MAAM,EAAE,YAAY,KAAK,QAAQ;QACxC,OAAO,MAAM,EAAE,eAAe,KAAK,QAAQ;QAC3C,OAAO,MAAM,EAAE,SAAS,KAAK,QAAQ,EACpC,CAAC;QACF,OAAO,IAAI,CAAC;IACb,CAAC;IACD,kDAAkD;IAClD,MAAM,WAAW,GAAG,IAAI,UAAU,CACjC,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,UAAU,GAAG,SAAS,EAC5B,KAAK,CAAC,UAAU,GAAG,SAAS,CAC5B,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAChC,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,WAAuB;IACtD,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Durable L2 cache-key derivation (H2 / R8 / R13).
3
+ *
4
+ * The in-process L1 cache keys on a 32-bit FNV hash — fine for a 20-entry Map,
5
+ * unsafe for a durable, cross-user cache where a collision serves user A's
6
+ * geometry to user B (CONTEXT.md L92–97 records exactly this bug shipping once).
7
+ * So the L2 key is a wide SHA-256 hash, and the entry stores the canonical
8
+ * preimage so a hit can compare it byte-for-byte (defense-in-depth).
9
+ *
10
+ * What goes into the key:
11
+ * - The **transformed** input tree (R13) — the exact tree handed to the
12
+ * scheduler, canonicalized with the package's exported `stableStringify` so
13
+ * the L2 key parity-matches the L1 canonicalization path.
14
+ * - A **config subset** (R8): everything OTHER than definition+inputs that
15
+ * changes a solve's result — model units, tolerances, `dataversion`, the
16
+ * compute contract version, and (when known) the Rhino server identity. A
17
+ * durable key of `(versionId, inputHash)` alone would collide across
18
+ * differing server configs or Rhino versions.
19
+ *
20
+ * `versionId`, `definitionId`, and `orgId` are NOT hashed in here — they're
21
+ * separate parts of the {@link SolveCacheKey} tuple so the backend can scope its
22
+ * keyspace (per-definition quota, per-org isolation) without unpacking the hash.
23
+ */
24
+ /**
25
+ * Solve-affecting configuration folded into the key alongside the input tree.
26
+ * Every field here is something that, if it changed, would legitimately change
27
+ * the solve output for the SAME definition + inputs. Assemble it from the app's
28
+ * resolved solve config; unset fields are simply absent from the canonical form.
29
+ */
30
+ export interface SolveCacheConfigSubset {
31
+ /** Rhino model unit system, if the app pins one (else the definition/server default). */
32
+ modelUnits?: string;
33
+ /** Absolute tolerance, if pinned. */
34
+ absoluteTolerance?: number;
35
+ /** Angle tolerance, if pinned. */
36
+ angleTolerance?: number;
37
+ /** Grasshopper `dataversion` / data-tree schema version, if pinned. */
38
+ dataVersion?: number | string;
39
+ /**
40
+ * Compute-server identity (id or URL). Folds in because two servers can run
41
+ * different Rhino/plugin versions that yield different geometry for the same
42
+ * inputs. Optional — omit for a single-pool deployment where it's constant.
43
+ */
44
+ computeServerId?: string;
45
+ }
46
+ /** The canonical preimage + its SHA-256 digest. Store both in the L2 entry header. */
47
+ export interface SolveCacheInputKey {
48
+ /** The canonical string that was hashed (for hit-time byte comparison). */
49
+ canonical: string;
50
+ /** SHA-256 hex of {@link canonical} — the `inputKey` part of the storage key. */
51
+ hash: string;
52
+ }
53
+ /**
54
+ * Derive the durable `inputKey` from the transformed input tree and the solve
55
+ * config subset. Deterministic and stable across processes/instances: the same
56
+ * tree + config always produce the same hash, which is what lets a shared cache
57
+ * hit across app instances.
58
+ *
59
+ * @param transformedTree the tree AFTER `transformInputParameter`/`TreeBuilder`
60
+ * (R13) — the exact object handed to `scheduler.solve`.
61
+ * @param config solve-affecting config (R8); `COMPUTE_CONTRACT_VERSION` is folded
62
+ * in automatically so a wire-contract bump invalidates old entries for free.
63
+ */
64
+ export declare function deriveSolveCacheInputKey(transformedTree: unknown, config: SolveCacheConfigSubset): SolveCacheInputKey;
65
+ //# sourceMappingURL=solve-cache-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-cache-key.d.ts","sourceRoot":"","sources":["../../src/compute/solve-cache-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACtC,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kCAAkC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,sFAAsF;AACtF,MAAM,WAAW,kBAAkB;IAClC,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACvC,eAAe,EAAE,OAAO,EACxB,MAAM,EAAE,sBAAsB,GAC5B,kBAAkB,CAWpB"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Durable L2 cache-key derivation (H2 / R8 / R13).
3
+ *
4
+ * The in-process L1 cache keys on a 32-bit FNV hash — fine for a 20-entry Map,
5
+ * unsafe for a durable, cross-user cache where a collision serves user A's
6
+ * geometry to user B (CONTEXT.md L92–97 records exactly this bug shipping once).
7
+ * So the L2 key is a wide SHA-256 hash, and the entry stores the canonical
8
+ * preimage so a hit can compare it byte-for-byte (defense-in-depth).
9
+ *
10
+ * What goes into the key:
11
+ * - The **transformed** input tree (R13) — the exact tree handed to the
12
+ * scheduler, canonicalized with the package's exported `stableStringify` so
13
+ * the L2 key parity-matches the L1 canonicalization path.
14
+ * - A **config subset** (R8): everything OTHER than definition+inputs that
15
+ * changes a solve's result — model units, tolerances, `dataversion`, the
16
+ * compute contract version, and (when known) the Rhino server identity. A
17
+ * durable key of `(versionId, inputHash)` alone would collide across
18
+ * differing server configs or Rhino versions.
19
+ *
20
+ * `versionId`, `definitionId`, and `orgId` are NOT hashed in here — they're
21
+ * separate parts of the {@link SolveCacheKey} tuple so the backend can scope its
22
+ * keyspace (per-definition quota, per-org isolation) without unpacking the hash.
23
+ */
24
+ import { createHash } from 'node:crypto';
25
+ import { stableStringify } from '@selvajs/compute';
26
+ import { COMPUTE_CONTRACT_VERSION } from './solve-pipeline.js';
27
+ /**
28
+ * Derive the durable `inputKey` from the transformed input tree and the solve
29
+ * config subset. Deterministic and stable across processes/instances: the same
30
+ * tree + config always produce the same hash, which is what lets a shared cache
31
+ * hit across app instances.
32
+ *
33
+ * @param transformedTree the tree AFTER `transformInputParameter`/`TreeBuilder`
34
+ * (R13) — the exact object handed to `scheduler.solve`.
35
+ * @param config solve-affecting config (R8); `COMPUTE_CONTRACT_VERSION` is folded
36
+ * in automatically so a wire-contract bump invalidates old entries for free.
37
+ */
38
+ export function deriveSolveCacheInputKey(transformedTree, config) {
39
+ // stableStringify sorts keys deterministically — same content, same string,
40
+ // regardless of property insertion order. Tag each part so a value can't shift
41
+ // across the tree/config boundary and collide (e.g. tree "]" meeting config "[").
42
+ const canonical = stableStringify({
43
+ v: COMPUTE_CONTRACT_VERSION,
44
+ tree: transformedTree,
45
+ config
46
+ });
47
+ const hash = createHash('sha256').update(canonical).digest('hex');
48
+ return { canonical, hash };
49
+ }
50
+ //# sourceMappingURL=solve-cache-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-cache-key.js","sourceRoot":"","sources":["../../src/compute/solve-cache-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAiC/D;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wBAAwB,CACvC,eAAwB,EACxB,MAA8B;IAE9B,4EAA4E;IAC5E,+EAA+E;IAC/E,kFAAkF;IAClF,MAAM,SAAS,GAAG,eAAe,CAAC;QACjC,CAAC,EAAE,wBAAwB;QAC3B,IAAI,EAAE,eAAe;QACrB,MAAM;KACN,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * In-process single-flight (R4) — dogpile protection above the L2 cache.
3
+ *
4
+ * N identical live solves arriving while the first is still running would each
5
+ * enqueue and each hit Rhino (the scheduler has no in-flight coalescing, and
6
+ * Rhino's `cachesolve` still costs a round trip per repeat). The classic cold-key
7
+ * stampede: a hot public definition + a deploy = a thundering herd onto compute.
8
+ *
9
+ * This coalesces them: the first caller for a key runs the work; concurrent
10
+ * callers for the SAME key await the same promise and share its result. Once the
11
+ * work settles (resolve OR reject), the key is released so the next request runs
12
+ * fresh — the map never retains a settled entry, so it can't serve a stale
13
+ * result or leak memory.
14
+ *
15
+ * It sits ABOVE the `ISolveResultCache` interface (in-process, per app instance).
16
+ * A cross-instance lease (Redis `SET NX`) is a later backend capability; this is
17
+ * the free first slice that covers the common same-instance burst.
18
+ *
19
+ * Correctness note: the shared promise resolves to ONE value for all waiters, so
20
+ * the wrapped work must return an immutable / independently-serializable result
21
+ * (the solve pipeline returns a fresh envelope object — safe to share by
22
+ * reference here because the app serializes it per response).
23
+ */
24
+ export interface SolveCacheSingleFlight {
25
+ /**
26
+ * Run `work` under `key`, coalescing concurrent identical calls. The first
27
+ * caller executes; overlapping callers for the same key await the same promise.
28
+ * The key is freed as soon as the promise settles (success or failure).
29
+ */
30
+ run<T>(key: string, work: () => Promise<T>): Promise<T>;
31
+ /** Number of keys currently in flight (observability / tests). */
32
+ inFlight(): number;
33
+ }
34
+ export interface SolveCacheSingleFlightOptions {
35
+ /**
36
+ * Fired when a caller joins an already-in-flight key instead of running its
37
+ * own work — the coalescing win this module exists for, otherwise invisible.
38
+ */
39
+ onJoin?: (key: string) => void;
40
+ }
41
+ export declare function createSolveCacheSingleFlight(options?: SolveCacheSingleFlightOptions): SolveCacheSingleFlight;
42
+ //# sourceMappingURL=solve-cache-single-flight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-cache-single-flight.d.ts","sourceRoot":"","sources":["../../src/compute/solve-cache-single-flight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,WAAW,sBAAsB;IACtC;;;;OAIG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACxD,kEAAkE;IAClE,QAAQ,IAAI,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,6BAA6B;IAC7C;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,4BAA4B,CAC3C,OAAO,GAAE,6BAAkC,GACzC,sBAAsB,CA0BxB"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * In-process single-flight (R4) — dogpile protection above the L2 cache.
3
+ *
4
+ * N identical live solves arriving while the first is still running would each
5
+ * enqueue and each hit Rhino (the scheduler has no in-flight coalescing, and
6
+ * Rhino's `cachesolve` still costs a round trip per repeat). The classic cold-key
7
+ * stampede: a hot public definition + a deploy = a thundering herd onto compute.
8
+ *
9
+ * This coalesces them: the first caller for a key runs the work; concurrent
10
+ * callers for the SAME key await the same promise and share its result. Once the
11
+ * work settles (resolve OR reject), the key is released so the next request runs
12
+ * fresh — the map never retains a settled entry, so it can't serve a stale
13
+ * result or leak memory.
14
+ *
15
+ * It sits ABOVE the `ISolveResultCache` interface (in-process, per app instance).
16
+ * A cross-instance lease (Redis `SET NX`) is a later backend capability; this is
17
+ * the free first slice that covers the common same-instance burst.
18
+ *
19
+ * Correctness note: the shared promise resolves to ONE value for all waiters, so
20
+ * the wrapped work must return an immutable / independently-serializable result
21
+ * (the solve pipeline returns a fresh envelope object — safe to share by
22
+ * reference here because the app serializes it per response).
23
+ */
24
+ export function createSolveCacheSingleFlight(options = {}) {
25
+ const inflight = new Map();
26
+ return {
27
+ run(key, work) {
28
+ const existing = inflight.get(key);
29
+ if (existing) {
30
+ options.onJoin?.(key);
31
+ return existing;
32
+ }
33
+ // `.finally` releases the key on both settle paths. Start the work inside
34
+ // the promise chain so a synchronous throw in `work` still rejects the
35
+ // shared promise (and still frees the key) rather than escaping.
36
+ const p = (async () => work())().finally(() => {
37
+ // Only delete if it's still OUR promise — a key freed and re-taken by a
38
+ // later caller must not be clobbered.
39
+ if (inflight.get(key) === p)
40
+ inflight.delete(key);
41
+ });
42
+ inflight.set(key, p);
43
+ return p;
44
+ },
45
+ inFlight() {
46
+ return inflight.size;
47
+ }
48
+ };
49
+ }
50
+ //# sourceMappingURL=solve-cache-single-flight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-cache-single-flight.js","sourceRoot":"","sources":["../../src/compute/solve-cache-single-flight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAqBH,MAAM,UAAU,4BAA4B,CAC3C,UAAyC,EAAE;IAE3C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA4B,CAAC;IAErD,OAAO;QACN,GAAG,CAAI,GAAW,EAAE,IAAsB;YACzC,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,QAAQ,EAAE,CAAC;gBACd,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;gBACtB,OAAO,QAAsB,CAAC;YAC/B,CAAC;YAED,0EAA0E;YAC1E,uEAAuE;YACvE,iEAAiE;YACjE,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE;gBAC7C,wEAAwE;gBACxE,sCAAsC;gBACtC,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;oBAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;YACH,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACrB,OAAO,CAAC,CAAC;QACV,CAAC;QACD,QAAQ;YACP,OAAO,QAAQ,CAAC,IAAI,CAAC;QACtB,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -19,9 +19,11 @@
19
19
  * The Server-Timing string it emits IS the versioned wire contract (audit D5):
20
20
  * see {@link COMPUTE_CONTRACT_VERSION} and {@link COMPUTE_VERSION_HEADER}.
21
21
  */
22
- import { type GrasshopperComputeResponse } from '@selvajs/compute';
22
+ import { type GrasshopperComputeResponse, type SolveDefinition } from '@selvajs/compute';
23
23
  import type { SchemaInput } from '@selvajs/schemas';
24
24
  import type { CachedClient } from './client-cache.js';
25
+ import type { ByteRefOutcome } from './definition-byte-cache.js';
26
+ import { type SolveCacheConfigSubset } from './solve-cache-key.js';
25
27
  /** Current compute-response contract version. Additive header; bump on shape change. */
26
28
  export declare const COMPUTE_CONTRACT_VERSION: 1;
27
29
  /** Response header carrying {@link COMPUTE_CONTRACT_VERSION}. */
@@ -33,8 +35,20 @@ export type PipelineInput = SchemaInput & {
33
35
  stepSize?: number;
34
36
  };
35
37
  export interface SolvePipelineArgs {
36
- /** The `.gh` bytes to solve (stored blob or remote fetch — resolved by the caller). */
37
- definitionSource: Uint8Array;
38
+ /**
39
+ * The definition to solve. Either raw `.gh` bytes (remote fetch, or a caller
40
+ * that resolved them eagerly) or a `DefinitionRef` — an identity-keyed lazy
41
+ * loader (from the definition-byte cache) whose bytes the scheduler
42
+ * materializes ONLY when an upload is unavoidable. A pointer-known solve of a
43
+ * `DefinitionRef` moves zero bytes.
44
+ */
45
+ definitionSource: SolveDefinition;
46
+ /**
47
+ * When `definitionSource` is a byte-cache `DefinitionRef`, its mutable outcome
48
+ * so the pipeline can emit the `def_bytes` Server-Timing verdict (skipped =
49
+ * `load` never ran, hit = warm cache, miss = loader). Omit for raw-bytes solves.
50
+ */
51
+ byteRefOutcome?: ByteRefOutcome;
38
52
  /** Persisted input params; only those with a `paramType` are sent to the solve. */
39
53
  inputs: PipelineInput[];
40
54
  /** User-chosen values keyed by input id; missing keys fall back to the schema default. */
@@ -66,6 +80,30 @@ export interface SolvePipelineArgs {
66
80
  * Server-Timing entries. The caller assembles these; the pipeline only echoes.
67
81
  */
68
82
  prepMarks?: [string, number][];
83
+ /**
84
+ * Optional durable L2 solve cache (H1). Present ONLY for live-channel solves
85
+ * whose definition has a caching quota > 0 — its presence IS the channel gate
86
+ * (zero policy conditionals in the pipeline). When set, the pipeline derives
87
+ * the wide input key from the transformed tree + `configSubset`, checks
88
+ * `lookup` before solving (a hit skips compute entirely, returning the stored
89
+ * gzipped envelope), and write-throughs `store` on a successful solve.
90
+ */
91
+ solveCache?: SolvePipelineCacheHook;
92
+ }
93
+ /**
94
+ * The app-supplied L2 hook. The app binds `lookup`/`store` to the org/definition/
95
+ * version scope and the definition's quota; the pipeline supplies the SHA-256
96
+ * `inputKey` (derived from the transformed tree + `configSubset`) and the opaque
97
+ * encoded entry bytes. Both are best-effort — `lookup` may miss/throw (treated as
98
+ * a miss), `store` is fire-and-forget.
99
+ */
100
+ export interface SolvePipelineCacheHook {
101
+ /** Solve-affecting config folded into the key (R8) — model units, tolerances, server id. */
102
+ configSubset: SolveCacheConfigSubset;
103
+ /** Fetch a stored entry for `inputKey`, or `null` on miss. Must not reject fatally. */
104
+ lookup(inputKey: string): Promise<Uint8Array | null>;
105
+ /** Store the encoded entry for `inputKey`. Fire-and-forget; best-effort. */
106
+ store(inputKey: string, entry: Uint8Array): void;
69
107
  }
70
108
  /** Phase timings the pipeline measured; the caller uses them for debug logging. */
71
109
  export interface SolvePhaseMetrics {
@@ -78,6 +116,12 @@ export interface SolvePhaseMetrics {
78
116
  serializedBytes: number;
79
117
  /** Gzipped length in bytes, or null when compression was skipped. */
80
118
  compressedBytes: number | null;
119
+ /**
120
+ * L2 durable-cache verdict: `true` = served from L2 (no solve ran), `false` =
121
+ * L2 consulted and missed (solved), `null` = L2 not consulted (no hook — draft
122
+ * or caching off). Drives the `l2_cache` Server-Timing entry.
123
+ */
124
+ l2CacheHit: boolean | null;
81
125
  }
82
126
  /** A ready-to-send response: body + headers + the solve result + phase metrics. */
83
127
  export interface SolveEnvelope {
@@ -87,17 +131,23 @@ export interface SolveEnvelope {
87
131
  encoding?: 'gzip';
88
132
  /** Fully-assembled response headers (Content-Type/-Length/-Encoding, Vary, Server-Timing, version). */
89
133
  headers: Record<string, string>;
90
- /** The solved definition — the caller reads `errors`/`warnings` for its metric record. */
91
- result: GrasshopperComputeResponse;
134
+ /**
135
+ * The solved definition object, present only on a fresh (non-L2) solve. Absent
136
+ * on an L2 hit — the pipeline serves the stored gzipped body without ever
137
+ * materializing the object. The caller reads `errorCount`/`warningCount` off
138
+ * the `ok` outcome for its metric record, not this field.
139
+ */
140
+ result?: GrasshopperComputeResponse;
92
141
  /** Phase timings, for the caller's optional debug breakdown. */
93
142
  metrics: SolvePhaseMetrics;
94
143
  }
95
144
  /**
96
145
  * Discriminated result. `ok` carries the envelope; every other variant names an
97
146
  * expected failure the transport maps to a status code (the app route maps
98
- * timeout→504, client_abort→499, too_large→413; `compute_error` re-surfaces the
99
- * original error for the generic 500/503 path). `durationMs` on the error
100
- * variants is the solve wall time up to the failure, for the metric record.
147
+ * timeout→504, client_abort→499, too_large→413, shed→503+Retry-After;
148
+ * `compute_error` re-surfaces the original error for the generic 500/503 path).
149
+ * `durationMs` on the error variants is the solve wall time up to the failure,
150
+ * for the metric record.
101
151
  */
102
152
  export type SolveOutcome = {
103
153
  kind: 'ok';
@@ -114,6 +164,19 @@ export type SolveOutcome = {
114
164
  durationMs: number;
115
165
  } | {
116
166
  kind: 'too_large';
167
+ }
168
+ /**
169
+ * Scheduler backpressure shed the solve before it executed — the per-server
170
+ * queue was full (`QUEUE_FULL`) or it sat queued past the wait deadline
171
+ * (`QUEUE_TIMEOUT`). Retryable: the route maps this to 503 + `Retry-After`.
172
+ * `retryAfterSeconds` is a suggested backoff hint for the client.
173
+ */
174
+ | {
175
+ kind: 'shed';
176
+ durationMs: number;
177
+ reason: 'queue_full' | 'queue_timeout';
178
+ retryAfterSeconds: number;
179
+ message: string;
117
180
  } | {
118
181
  kind: 'compute_error';
119
182
  durationMs: number;
@@ -1 +1 @@
1
- {"version":3,"file":"solve-pipeline.d.ts","sourceRoot":"","sources":["../../src/compute/solve-pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"solve-pipeline.d.ts","sourceRoot":"","sources":["../../src/compute/solve-pipeline.ts"],"names":[],"mappings":"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"}