@selvajs/server 0.2.1 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +23 -16
  2. package/dist/compute/index.d.ts +0 -8
  3. package/dist/compute/index.d.ts.map +1 -1
  4. package/dist/compute/index.js +12 -9
  5. package/dist/compute/index.js.map +1 -1
  6. package/dist/compute/limits.d.ts +27 -35
  7. package/dist/compute/limits.d.ts.map +1 -1
  8. package/dist/compute/limits.js +34 -12
  9. package/dist/compute/limits.js.map +1 -1
  10. package/package.json +6 -12
  11. package/dist/compute/client-cache.d.ts +0 -135
  12. package/dist/compute/client-cache.d.ts.map +0 -1
  13. package/dist/compute/client-cache.js +0 -176
  14. package/dist/compute/client-cache.js.map +0 -1
  15. package/dist/compute/definition-byte-cache.d.ts +0 -85
  16. package/dist/compute/definition-byte-cache.d.ts.map +0 -1
  17. package/dist/compute/definition-byte-cache.js +0 -110
  18. package/dist/compute/definition-byte-cache.js.map +0 -1
  19. package/dist/compute/memory-solve-cache.d.ts +0 -58
  20. package/dist/compute/memory-solve-cache.d.ts.map +0 -1
  21. package/dist/compute/memory-solve-cache.js +0 -0
  22. package/dist/compute/memory-solve-cache.js.map +0 -1
  23. package/dist/compute/solve-cache-envelope.d.ts +0 -53
  24. package/dist/compute/solve-cache-envelope.d.ts.map +0 -1
  25. package/dist/compute/solve-cache-envelope.js +0 -66
  26. package/dist/compute/solve-cache-envelope.js.map +0 -1
  27. package/dist/compute/solve-cache-key.d.ts +0 -64
  28. package/dist/compute/solve-cache-key.d.ts.map +0 -1
  29. package/dist/compute/solve-cache-key.js +0 -51
  30. package/dist/compute/solve-cache-key.js.map +0 -1
  31. package/dist/compute/solve-cache-single-flight.d.ts +0 -42
  32. package/dist/compute/solve-cache-single-flight.d.ts.map +0 -1
  33. package/dist/compute/solve-cache-single-flight.js +0 -50
  34. package/dist/compute/solve-cache-single-flight.js.map +0 -1
  35. package/dist/compute/solve-pipeline.d.ts +0 -221
  36. package/dist/compute/solve-pipeline.d.ts.map +0 -1
  37. package/dist/compute/solve-pipeline.js +0 -419
  38. package/dist/compute/solve-pipeline.js.map +0 -1
  39. package/dist/compute/transform-input.d.ts +0 -20
  40. package/dist/compute/transform-input.d.ts.map +0 -1
  41. package/dist/compute/transform-input.js +0 -62
  42. package/dist/compute/transform-input.js.map +0 -1
  43. package/dist/index.d.ts +0 -27
  44. package/dist/index.d.ts.map +0 -1
  45. package/dist/index.js +0 -27
  46. package/dist/index.js.map +0 -1
@@ -1,419 +0,0 @@
1
- /**
2
- * Transport-agnostic solve pipeline — the callable core lifted out of the app's
3
- * `/api/compute` route (embeddable-server-layer plan, K3).
4
- *
5
- * Given an already-resolved solve context — the `.gh` bytes, the input params +
6
- * user values, and a warm `SolveScheduler` (from `createClientCache`) — this
7
- * runs the framework-free half of a solve:
8
- *
9
- * input tree build → scheduler.solve (with abort/timeout classification) →
10
- * JSON serialize (size-guarded) → optional gzip → Server-Timing envelope.
11
- *
12
- * It returns a discriminated {@link SolveOutcome}: `ok` carries the ready-to-send
13
- * {@link SolveEnvelope} (body + headers + phase metrics), while the error
14
- * variants (`timeout`, `client_abort`, `too_large`, `compute_error`) name a
15
- * failure the transport maps to its own status code. Nothing here throws for an
16
- * expected failure and nothing here touches auth, the database, share tokens,
17
- * rate limits, or metric sinks — those stay app policy in the route.
18
- *
19
- * The Server-Timing string it emits IS the versioned wire contract (audit D5):
20
- * see {@link COMPUTE_CONTRACT_VERSION} and {@link COMPUTE_VERSION_HEADER}.
21
- */
22
- import { ErrorCodes, RhinoComputeError, TreeBuilder } from '@selvajs/compute';
23
- import { NoopLogger } from '@selvajs/platform';
24
- import { gzip } from 'node:zlib';
25
- import { promisify } from 'node:util';
26
- import { transformInputParameter } from './transform-input.js';
27
- import { deriveSolveCacheInputKey } from './solve-cache-key.js';
28
- import { decodeSolveCacheEntry, encodeSolveCacheEntry, gunzipEntryBody } from './solve-cache-envelope.js';
29
- import { gunzipSync } from 'node:zlib';
30
- /** Async gzip (audit B8) — off the event loop, unlike the old `gzipSync`. */
31
- const gzipAsync = promisify(gzip);
32
- // ============================================================================
33
- // Wire contract version (audit D5)
34
- // ============================================================================
35
- //
36
- // The /api/compute response shape (JSON body + Server-Timing phases) is now an
37
- // explicit, versioned artifact rather than ad-hoc route output. The version
38
- // rides an additive response header so a client can branch on it without any
39
- // change to the existing body — bump this (and document the change) whenever the
40
- // envelope's shape changes in a way a consumer could observe.
41
- /** Current compute-response contract version. Additive header; bump on shape change. */
42
- export const COMPUTE_CONTRACT_VERSION = 1;
43
- /** Response header carrying {@link COMPUTE_CONTRACT_VERSION}. */
44
- export const COMPUTE_VERSION_HEADER = 'X-Selva-Compute-Version';
45
- // ============================================================================
46
- // Pipeline
47
- // ============================================================================
48
- /**
49
- * Run the framework-free half of a solve and produce a typed outcome. See the
50
- * module doc for the phase sequence and the app/library boundary.
51
- */
52
- export async function runSolvePipeline(args) {
53
- const { client, signal } = args;
54
- // --- input tree build ---------------------------------------------------
55
- const treeBuildStart = performance.now();
56
- const inputTree = TreeBuilder.fromInputParams(args.inputs
57
- .filter((input) => input.paramType)
58
- .map((input) => transformInputParameter(input, args.values[input.id])));
59
- const treeBuildMs = performance.now() - treeBuildStart;
60
- // --- L2 durable cache lookup (H1) ---------------------------------------
61
- // Derive the wide key from the TRANSFORMED tree (R13) + config subset (R8),
62
- // then check the injected hook. Present only for cacheable live solves — its
63
- // presence is the channel gate. A hit skips the solve entirely and serves the
64
- // stored gzipped envelope; the derived key is reused for the write-through on
65
- // a miss. Lookup is best-effort: any rejection is swallowed to a miss.
66
- let inputKey = null;
67
- if (args.solveCache) {
68
- inputKey = deriveSolveCacheInputKey(inputTree, args.solveCache.configSubset).hash;
69
- let stored = null;
70
- try {
71
- stored = await args.solveCache.lookup(inputKey);
72
- }
73
- catch {
74
- stored = null;
75
- }
76
- if (stored) {
77
- const hit = buildEnvelopeFromCacheEntry(stored, inputKey, args);
78
- if (hit)
79
- return hit;
80
- // Corrupt/tampered entry → fall through and solve as a miss. Warn: a
81
- // silently-poisoned cache would otherwise look like an eternal cold key.
82
- (args.logger ?? new NoopLogger()).warn('Discarding corrupt or hash-mismatched L2 cache entry, solving fresh', { component: 'Compute/l2-cache', inputKeyPrefix: inputKey.slice(0, 16) });
83
- }
84
- }
85
- // --- solve --------------------------------------------------------------
86
- // Snapshot the shared telemetry sequence counters. The holders live on the
87
- // warm client and are written by every request on this server; with
88
- // maxConcurrentSolves > 1 another request can write them mid-flight. After
89
- // the solve, a slot is attributed to THIS request only when exactly one
90
- // write happened since this snapshot — for solveMeta that single settle is
91
- // necessarily ours (onSettle fires before scheduler.solve() resolves).
92
- // Anything ambiguous is dropped from Server-Timing, never misattributed.
93
- const settleSeqBefore = client.solveMeta.seq;
94
- const rhinoSeqBefore = client.rhinoTiming.seq;
95
- let result;
96
- const solveStart = performance.now();
97
- try {
98
- result = await client.scheduler.solve(args.definitionSource, inputTree, { signal });
99
- }
100
- catch (err) {
101
- const durationMs = performance.now() - solveStart;
102
- // Distinguish timeout (scheduler deadline timer) from client disconnect
103
- // (request signal). AbortError with the request signal NOT aborted means
104
- // the scheduler's own timeout fired — the solve genuinely timed out.
105
- const isAbort = err instanceof Error && err.name === 'AbortError';
106
- if (isAbort) {
107
- if (signal.aborted)
108
- return { kind: 'client_abort', durationMs };
109
- return {
110
- kind: 'timeout',
111
- durationMs,
112
- message: `Solve exceeded the ${Math.round(args.maxSolveDurationMs / 1000)}s deadline.`
113
- };
114
- }
115
- // Scheduler backpressure (audit B7): a full queue or an over-deadline queue
116
- // wait sheds the solve BEFORE compute runs. Classify these as `shed` (503 +
117
- // Retry-After) rather than the generic 500 `compute_error` path — they're
118
- // load signals, not failures, and the client should back off and retry.
119
- if (err instanceof RhinoComputeError) {
120
- if (err.code === ErrorCodes.QUEUE_FULL) {
121
- return {
122
- kind: 'shed',
123
- durationMs,
124
- reason: 'queue_full',
125
- retryAfterSeconds: 1,
126
- message: 'Compute server is at capacity. Retry shortly.'
127
- };
128
- }
129
- if (err.code === ErrorCodes.QUEUE_TIMEOUT) {
130
- return {
131
- kind: 'shed',
132
- durationMs,
133
- reason: 'queue_timeout',
134
- retryAfterSeconds: 1,
135
- message: 'Compute request waited too long in the queue. Retry shortly.'
136
- };
137
- }
138
- }
139
- return { kind: 'compute_error', durationMs, error: err };
140
- }
141
- const solveMs = performance.now() - solveStart;
142
- // --- serialize (size-guarded) ------------------------------------------
143
- const serializeStart = performance.now();
144
- let serialized;
145
- try {
146
- serialized = JSON.stringify(result);
147
- }
148
- catch (err) {
149
- // V8 caps a single string at ~512 MB; an oversized `file` output trips a
150
- // RangeError here. Surface it as the same too-large outcome as the byte cap.
151
- if (err instanceof RangeError)
152
- return { kind: 'too_large' };
153
- throw err;
154
- }
155
- if (serialized.length > args.responseMaxBytes)
156
- return { kind: 'too_large' };
157
- const serializeMs = performance.now() - serializeStart;
158
- // --- gzip ---------------------------------------------------------------
159
- // Compress BEFORE the timing snapshot so its cost is a measured phase (`gzip`
160
- // in Server-Timing, included in `total`). Buffered (not streamed) so
161
- // Content-Length is known and a connection cut mid-transfer fails hard
162
- // instead of truncating the JSON.
163
- // gzip is async (audit B8) — a multi-MB `gzipSync` blocked the event loop for
164
- // every other request on this instance. Two independent reasons to compress:
165
- // - the client advertised gzip AND the body clears the 1 KB break-even (tiny
166
- // bodies aren't worth compressing for the wire);
167
- // - an L2 write-through is pending — the entry stores compressed bytes so
168
- // every future hit is near-CPU-free, so we compress even a small body (it
169
- // will be cached), just not for the wire below the threshold.
170
- const clientWantsGzip = /\bgzip\b/i.test(args.acceptEncoding);
171
- const worthSendingGzip = clientWantsGzip && serialized.length > 1024;
172
- const willCache = args.solveCache != null;
173
- let compressed = null;
174
- let gzipMs = 0;
175
- if (worthSendingGzip || willCache) {
176
- const gzipStart = performance.now();
177
- compressed = await gzipAsync(Buffer.from(serialized));
178
- gzipMs = performance.now() - gzipStart;
179
- }
180
- // --- L2 write-through (H1) ----------------------------------------------
181
- // On a cacheable solve with a compressed body, store the gzipped envelope so
182
- // future hits are near-CPU-free. Fire-and-forget through the hook; the store
183
- // itself is best-effort (may silently drop under quota/byte pressure).
184
- if (args.solveCache && inputKey && compressed) {
185
- const entry = encodeSolveCacheEntry({
186
- errorCount: result.errors?.length ?? 0,
187
- warningCount: result.warnings?.length ?? 0,
188
- serializedBytes: serialized.length,
189
- inputHash: inputKey
190
- }, new Uint8Array(compressed));
191
- args.solveCache.store(inputKey, entry);
192
- }
193
- const serverTotalMs = performance.now() - args.loadStartMs;
194
- // --- per-request telemetry attribution (see snapshot above) -------------
195
- // settle: ours iff exactly one settle happened since the snapshot. rhino:
196
- // only meaningful when the settle is ours AND it was a real compute call
197
- // (a Selva-cache hit never reaches the server), and only unambiguous when
198
- // exactly one Server-Timing callback fired in the window.
199
- const settle = client.solveMeta.seq === settleSeqBefore + 1 ? client.solveMeta.last : null;
200
- const rhino = settle && !settle.fromCache && client.rhinoTiming.seq === rhinoSeqBefore + 1
201
- ? client.rhinoTiming.last
202
- : null;
203
- // Send gzip to the client only when it's worth it for the wire — a body
204
- // compressed solely to feed the L2 write-through (or one below the 1 KB
205
- // break-even) goes out uncompressed.
206
- const sendCompressed = compressed && worthSendingGzip ? compressed : null;
207
- // --- Server-Timing envelope (the versioned wire contract) ---------------
208
- const serverTiming = buildServerTiming({
209
- defLoadMs: args.defLoadMs,
210
- treeBuildMs,
211
- solveMs,
212
- serializeMs,
213
- gzipMs,
214
- serverTotalMs,
215
- rhino,
216
- settle,
217
- byteRefOutcome: args.byteRefOutcome,
218
- // L2 was consulted (hook present) and missed — otherwise not consulted.
219
- l2CacheHit: args.solveCache ? false : null,
220
- prepMarks: args.prepMarks ?? []
221
- });
222
- const headers = {
223
- 'Content-Type': 'application/json',
224
- 'Server-Timing': serverTiming,
225
- [COMPUTE_VERSION_HEADER]: String(COMPUTE_CONTRACT_VERSION),
226
- Vary: 'Accept-Encoding'
227
- };
228
- const metrics = {
229
- treeBuildMs,
230
- solveMs,
231
- serializeMs,
232
- gzipMs,
233
- serverTotalMs,
234
- serializedBytes: serialized.length,
235
- compressedBytes: sendCompressed?.byteLength ?? null,
236
- l2CacheHit: args.solveCache ? false : null
237
- };
238
- let envelope;
239
- if (sendCompressed) {
240
- // A downstream proxy's `encode gzip` skips already-encoded responses, so
241
- // this never double-compresses. Vary is set on both branches.
242
- headers['Content-Encoding'] = 'gzip';
243
- headers['Content-Length'] = String(sendCompressed.byteLength);
244
- envelope = {
245
- body: new Uint8Array(sendCompressed),
246
- encoding: 'gzip',
247
- headers,
248
- result,
249
- metrics
250
- };
251
- }
252
- else {
253
- headers['Content-Length'] = String(Buffer.byteLength(serialized));
254
- envelope = { body: serialized, headers, result, metrics };
255
- }
256
- return {
257
- kind: 'ok',
258
- envelope,
259
- solveMs,
260
- errorCount: result.errors?.length ?? 0,
261
- warningCount: result.warnings?.length ?? 0
262
- };
263
- }
264
- // ============================================================================
265
- // Per-waiter encoding adaptation (audit C5)
266
- // ============================================================================
267
- /**
268
- * Re-key a coalesced envelope to a single waiter's `Accept-Encoding` (audit C5).
269
- *
270
- * The single-flight coalescer (R4) runs ONE pipeline execution for N identical
271
- * concurrent solves and hands every waiter the same {@link SolveEnvelope}. That
272
- * envelope's wire form — gzip body + `Content-Encoding: gzip`, or the plain JSON
273
- * string — is baked from the FIRST caller's `Accept-Encoding`. A later waiter
274
- * with a different `Accept-Encoding` would otherwise receive a body labelled with
275
- * the wrong encoding: a non-gzip client joining a gzip flight gets gzip bytes it
276
- * cannot decode (`Vary` can't help — this is one object shared across waiters,
277
- * not a cache lookup). Encoding is not in the coalesce key by design, so mixed
278
- * clients still coalesce; this adapts the shared result to each waiter instead.
279
- *
280
- * Returns the body + headers to send THIS waiter. Only the correctness-critical
281
- * direction is adapted — a gzip envelope served to a non-gzip waiter is gunzipped
282
- * back to JSON. The reverse (a plain-JSON envelope to a gzip-capable waiter) is
283
- * left uncompressed: gzip is an optimisation the client advertises, never a
284
- * requirement, so sending it plain is correct, just not maximally small. The
285
- * common all-gzip case returns the envelope's own body/headers untouched.
286
- */
287
- export function adaptEnvelopeToEncoding(envelope, acceptEncoding) {
288
- const waiterWantsGzip = /\bgzip\b/i.test(acceptEncoding);
289
- // The only mismatch that corrupts the response: a gzip body handed to a waiter
290
- // that did not advertise gzip. Gunzip it back to the JSON string and drop the
291
- // encoding headers. Every other combination is already wire-correct.
292
- if (envelope.encoding === 'gzip' && !waiterWantsGzip) {
293
- const json = gunzipSync(envelope.body instanceof Uint8Array ? envelope.body : Buffer.from(envelope.body)).toString('utf8');
294
- const headers = { ...envelope.headers };
295
- delete headers['Content-Encoding'];
296
- headers['Content-Length'] = String(Buffer.byteLength(json));
297
- return { body: json, headers };
298
- }
299
- return { body: envelope.body, headers: envelope.headers };
300
- }
301
- // ============================================================================
302
- // L2 cache-hit envelope
303
- // ============================================================================
304
- /**
305
- * Build the `ok` outcome from a stored L2 entry — the near-CPU-free hit path (no
306
- * solve, no `JSON.stringify`, no gzip). Returns `null` when the entry is corrupt
307
- * or its stored `inputHash` doesn't match the requesting key (defense-in-depth
308
- * against a wide-hash collision), so the caller falls through and solves.
309
- */
310
- function buildEnvelopeFromCacheEntry(entryBytes, inputKey, args) {
311
- const decoded = decodeSolveCacheEntry(entryBytes);
312
- // A collision that produced the same storage key still can't serve the wrong
313
- // geometry: the stored hash must match the requesting key's hash.
314
- if (!decoded || decoded.header.inputHash !== inputKey)
315
- return null;
316
- const { header, gzippedBody } = decoded;
317
- const clientWantsGzip = /\bgzip\b/i.test(args.acceptEncoding);
318
- const serverTotalMs = performance.now() - args.loadStartMs;
319
- const serverTiming = buildServerTiming({
320
- defLoadMs: args.defLoadMs,
321
- treeBuildMs: 0,
322
- solveMs: 0,
323
- serializeMs: 0,
324
- gzipMs: 0,
325
- serverTotalMs,
326
- rhino: null,
327
- settle: null,
328
- byteRefOutcome: args.byteRefOutcome,
329
- l2CacheHit: true,
330
- prepMarks: args.prepMarks ?? []
331
- });
332
- const headers = {
333
- 'Content-Type': 'application/json',
334
- 'Server-Timing': serverTiming,
335
- [COMPUTE_VERSION_HEADER]: String(COMPUTE_CONTRACT_VERSION),
336
- Vary: 'Accept-Encoding'
337
- };
338
- const metrics = {
339
- treeBuildMs: 0,
340
- solveMs: 0,
341
- serializeMs: 0,
342
- gzipMs: 0,
343
- serverTotalMs,
344
- serializedBytes: header.serializedBytes,
345
- compressedBytes: clientWantsGzip ? gzippedBody.byteLength : null,
346
- l2CacheHit: true
347
- };
348
- let envelope;
349
- if (clientWantsGzip) {
350
- // Serve the stored compressed bytes verbatim — the whole point of R6.
351
- headers['Content-Encoding'] = 'gzip';
352
- headers['Content-Length'] = String(gzippedBody.byteLength);
353
- envelope = { body: new Uint8Array(gzippedBody), encoding: 'gzip', headers, metrics };
354
- }
355
- else {
356
- // Rare non-gzip client: gunzip back to the JSON string for the response.
357
- const json = gunzipEntryBody(gzippedBody);
358
- headers['Content-Length'] = String(Buffer.byteLength(json));
359
- envelope = { body: json, headers, metrics };
360
- }
361
- return {
362
- kind: 'ok',
363
- envelope,
364
- solveMs: 0,
365
- errorCount: header.errorCount,
366
- warningCount: header.warningCount
367
- };
368
- }
369
- /**
370
- * Assemble the `Server-Timing` header. The browser reads these to attribute its
371
- * round-trip: `total` here == the server's headers-to-out wall time, so browser
372
- * `ttfb − total` ≈ network+send latency. When the compute server reported its
373
- * own decode/solve/encode (VektorNode fork), `rhino_*` is time ON the compute
374
- * server and `compute_link` is everything between (network + queue wait). Prep
375
- * sub-phases ride as `p_*`; cache verdicts as 0/1 `selva_cache`/`def_reupload`.
376
- */
377
- function buildServerTiming(parts) {
378
- let header = `load;dur=${parts.defLoadMs.toFixed(1)}, ` +
379
- `tree;dur=${parts.treeBuildMs.toFixed(1)}, ` +
380
- `solve;dur=${parts.solveMs.toFixed(1)}, ` +
381
- `serialize;dur=${parts.serializeMs.toFixed(1)}, ` +
382
- `gzip;dur=${parts.gzipMs.toFixed(1)}, ` +
383
- `total;dur=${parts.serverTotalMs.toFixed(1)}`;
384
- const rhino = parts.rhino;
385
- if (rhino) {
386
- const onRhinoMs = rhino.decode + rhino.solve + rhino.encode;
387
- const computeLinkMs = Math.max(0, parts.solveMs - onRhinoMs);
388
- header +=
389
- `, rhino_decode;dur=${rhino.decode.toFixed(1)}` +
390
- `, rhino_solve;dur=${rhino.solve.toFixed(1)}` +
391
- `, rhino_encode;dur=${rhino.encode.toFixed(1)}` +
392
- `, compute_link;dur=${computeLinkMs.toFixed(1)}`;
393
- }
394
- for (const [label, ms] of parts.prepMarks) {
395
- header += `, p_${label};dur=${ms.toFixed(1)}`;
396
- }
397
- const settle = parts.settle;
398
- if (settle) {
399
- header += `, selva_cache;dur=${settle.fromCache ? 1 : 0}`;
400
- if (settle.definitionReuploaded !== undefined) {
401
- header += `, def_reupload;dur=${settle.definitionReuploaded ? 1 : 0}`;
402
- }
403
- }
404
- // Byte-cache verdict for `DefinitionRef` solves: skipped = the scheduler never
405
- // materialized bytes (pointer-known solve — the whole point of this path), hit
406
- // = warm byte cache, miss = fell through to storage. Absent for raw-bytes solves.
407
- const byteRef = parts.byteRefOutcome;
408
- if (byteRef) {
409
- const verdict = !byteRef.loaded ? 'skipped' : byteRef.fromCache ? 'hit' : 'miss';
410
- header += `, def_bytes;desc=${verdict}`;
411
- }
412
- // Durable L2 verdict (H1): 1 = hit (no solve ran), 0 = miss (consulted then
413
- // solved). Absent when the L2 wasn't consulted (draft channel / caching off).
414
- if (parts.l2CacheHit !== null) {
415
- header += `, l2_cache;dur=${parts.l2CacheHit ? 1 : 0}`;
416
- }
417
- return header;
418
- }
419
- //# sourceMappingURL=solve-pipeline.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"solve-pipeline.js","sourceRoot":"","sources":["../../src/compute/solve-pipeline.ts"],"names":[],"mappings":"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"}
@@ -1,20 +0,0 @@
1
- import { type InputParam } from '@selvajs/compute';
2
- import type { SchemaInput } from '@selvajs/schemas';
3
- /**
4
- * Adapt a persisted `SchemaInput` (plus the user's chosen value) into the package's
5
- * raw `InputParamSchema`, then let `@selvajs/compute`'s own `processInput` produce the
6
- * typed `InputParam`. The package handles every paramType (Number/Integer/Text/Boolean/
7
- * ValueList/Geometry/File/Color), normalizes the lowercase UI paramType to its
8
- * PascalCase form, and falls back gracefully on underspecified inputs — so we no longer
9
- * maintain a parallel hand-rolled transform that silently coerced valueList/file/color
10
- * to Text and drifted from the package (whose consumers already delegate here).
11
- * `values`/`acceptedFormats` are absent on `SchemaInput` (they live on the layout
12
- * item's config), so valueList/file inputs fall back to carrying the selected value with
13
- * no option list — the same value that reaches Grasshopper.
14
- */
15
- export declare function transformInputParameter(input: SchemaInput & {
16
- minimum?: number;
17
- maximum?: number;
18
- stepSize?: number;
19
- }, value: unknown): InputParam;
20
- //# sourceMappingURL=transform-input.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transform-input.d.ts","sourceRoot":"","sources":["../../src/compute/transform-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAuC,MAAM,kBAAkB,CAAC;AACxF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,WAAW,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAC9E,KAAK,EAAE,OAAO,GACZ,UAAU,CA+CZ"}
@@ -1,62 +0,0 @@
1
- import { processInput } from '@selvajs/compute';
2
- /**
3
- * Adapt a persisted `SchemaInput` (plus the user's chosen value) into the package's
4
- * raw `InputParamSchema`, then let `@selvajs/compute`'s own `processInput` produce the
5
- * typed `InputParam`. The package handles every paramType (Number/Integer/Text/Boolean/
6
- * ValueList/Geometry/File/Color), normalizes the lowercase UI paramType to its
7
- * PascalCase form, and falls back gracefully on underspecified inputs — so we no longer
8
- * maintain a parallel hand-rolled transform that silently coerced valueList/file/color
9
- * to Text and drifted from the package (whose consumers already delegate here).
10
- * `values`/`acceptedFormats` are absent on `SchemaInput` (they live on the layout
11
- * item's config), so valueList/file inputs fall back to carrying the selected value with
12
- * no option list — the same value that reaches Grasshopper.
13
- */
14
- export function transformInputParameter(input, value) {
15
- const raw = {
16
- id: input.id,
17
- name: input.nickname,
18
- nickname: input.nickname || null,
19
- description: input.description || '',
20
- // Dynamic value lists ride the ValueList contract on the wire — the plugin's
21
- // GetDynamicValueListParameter deliberately reuses TypeName "ValueList" so the
22
- // compute fork's existing ValueList input case assigns it. processInput has no
23
- // dynamicValueList handler; without this mapping it falls back to Geometry with
24
- // a null default and TreeBuilder DROPS the input, so the user's selection never
25
- // reaches the definition (the param then solves on its own stale fallback).
26
- paramType: input.paramType === 'dynamicValueList' ? 'valueList' : input.paramType,
27
- treeAccess: input.inputStructure === 'tree',
28
- minimum: input.minimum ?? null,
29
- maximum: input.maximum ?? null,
30
- atLeast: 1,
31
- atMost: 1,
32
- stepSize: input.stepSize,
33
- // The user's selection wins; otherwise the schema default.
34
- default: value ?? input.default
35
- };
36
- const processed = processInput(raw);
37
- // Two cases where processInput drops a default we must carry anyway (the
38
- // default IS what TreeBuilder puts on the wire; a dropped default means the
39
- // input is omitted from the solve and the user's selection never reaches
40
- // Grasshopper):
41
- // - a plain array default (multi-select widgets, e.g. a dynamic value list
42
- // checklist) is dropped as "malformed"; TreeBuilder.appendFlat handles
43
- // arrays natively.
44
- // - since @selvajs/compute 3.1.0-beta.5, the ValueList fallback drops a
45
- // scalar default it can't validate against a `values` map — and
46
- // `SchemaInput` never carries the option map (it lives on the layout
47
- // item's config), so every app value-list selection lands here.
48
- const effective = value ?? input.default;
49
- if (processed.default == null && effective != null) {
50
- if (Array.isArray(effective)) {
51
- processed.default = effective;
52
- }
53
- else if (processed.paramType === 'ValueList' && typeof effective !== 'object') {
54
- // Scoped to ValueList: for other types a dropped scalar default means
55
- // the package rejected it as unparseable — restoring it would ship
56
- // garbage to Grasshopper.
57
- processed.default = effective;
58
- }
59
- }
60
- return processed;
61
- }
62
- //# sourceMappingURL=transform-input.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transform-input.js","sourceRoot":"","sources":["../../src/compute/transform-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGxF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CACtC,KAA8E,EAC9E,KAAc;IAEd,MAAM,GAAG,GAAqB;QAC7B,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,KAAK,CAAC,QAAQ;QACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;QAChC,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;QACpC,6EAA6E;QAC7E,+EAA+E;QAC/E,+EAA+E;QAC/E,gFAAgF;QAChF,gFAAgF;QAChF,4EAA4E;QAC5E,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,kBAAkB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS;QACjF,UAAU,EAAE,KAAK,CAAC,cAAc,KAAK,MAAM;QAC3C,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,2DAA2D;QAC3D,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO;KAC/B,CAAC;IAEF,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,yEAAyE;IACzE,4EAA4E;IAC5E,yEAAyE;IACzE,gBAAgB;IAChB,4EAA4E;IAC5E,0EAA0E;IAC1E,sBAAsB;IACtB,yEAAyE;IACzE,mEAAmE;IACnE,wEAAwE;IACxE,mEAAmE;IACnE,MAAM,SAAS,GAAG,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC;IACzC,IAAI,SAAS,CAAC,OAAO,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACpD,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,SAAkC,CAAC,OAAO,GAAG,SAAS,CAAC;QACzD,CAAC;aAAM,IAAI,SAAS,CAAC,SAAS,KAAK,WAAW,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YACjF,sEAAsE;YACtE,mEAAmE;YACnE,0BAA0B;YACzB,SAAkC,CAAC,OAAO,GAAG,SAAS,CAAC;QACzD,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC"}
package/dist/index.d.ts DELETED
@@ -1,27 +0,0 @@
1
- /**
2
- * `@selvajs/server` — transport-agnostic compute/solve server building blocks
3
- * for apps built on the Selva engine.
4
- *
5
- * The compute stack (limits, per-key rate limiting, SSRF guard, input
6
- * transform) that used to live inside the `@selvajs/selva` app, extracted so a
7
- * consuming app can reuse it instead of copying it. Everything here is
8
- * env-injected (no ambient `$env` / `process.env`) and framework-agnostic.
9
- *
10
- * The full compute subsurface is also available at `@selvajs/server/compute`,
11
- * the definitions slice (DefinitionService, schema extraction/validation,
12
- * render loader) at `@selvajs/server/definitions`, the provider wiring
13
- * (registry-driven `createSelvaProviders`) at `@selvajs/server/providers`,
14
- * the HMAC token codec at `@selvajs/server/tokens`, error reporting at
15
- * `@selvajs/server/errors`, HTTP hardening helpers at `@selvajs/server/http`,
16
- * access-rule input assembly at `@selvajs/server/access`, and deployment/ops
17
- * helpers at `@selvajs/server/ops`.
18
- */
19
- export * from './compute/index.js';
20
- export * from './definitions/index.js';
21
- export * from './providers/index.js';
22
- export * from './tokens/index.js';
23
- export * from './errors/index.js';
24
- export * from './http/index.js';
25
- export * from './access/index.js';
26
- export * from './ops/index.js';
27
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}
package/dist/index.js DELETED
@@ -1,27 +0,0 @@
1
- /**
2
- * `@selvajs/server` — transport-agnostic compute/solve server building blocks
3
- * for apps built on the Selva engine.
4
- *
5
- * The compute stack (limits, per-key rate limiting, SSRF guard, input
6
- * transform) that used to live inside the `@selvajs/selva` app, extracted so a
7
- * consuming app can reuse it instead of copying it. Everything here is
8
- * env-injected (no ambient `$env` / `process.env`) and framework-agnostic.
9
- *
10
- * The full compute subsurface is also available at `@selvajs/server/compute`,
11
- * the definitions slice (DefinitionService, schema extraction/validation,
12
- * render loader) at `@selvajs/server/definitions`, the provider wiring
13
- * (registry-driven `createSelvaProviders`) at `@selvajs/server/providers`,
14
- * the HMAC token codec at `@selvajs/server/tokens`, error reporting at
15
- * `@selvajs/server/errors`, HTTP hardening helpers at `@selvajs/server/http`,
16
- * access-rule input assembly at `@selvajs/server/access`, and deployment/ops
17
- * helpers at `@selvajs/server/ops`.
18
- */
19
- export * from './compute/index.js';
20
- export * from './definitions/index.js';
21
- export * from './providers/index.js';
22
- export * from './tokens/index.js';
23
- export * from './errors/index.js';
24
- export * from './http/index.js';
25
- export * from './access/index.js';
26
- export * from './ops/index.js';
27
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC"}