@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
package/README.md CHANGED
@@ -1,9 +1,13 @@
1
1
  # @selvajs/server
2
2
 
3
- Transport-agnostic compute/solve/definitions server building blocks for apps built on the
4
- Selva engine: limits, rate limiting, SSRF guard, input transform, solve pipeline, definition
5
- service, render loader, and structured logging. Consumed by `@selvajs/selva`; not tied to
6
- SvelteKit or any specific HTTP framework.
3
+ Transport-agnostic server building blocks for apps built on the Selva engine: limits, rate
4
+ limiting, SSRF guard, definition service, render loader, and structured logging. Consumed by
5
+ `@selvajs/selva`; not tied to SvelteKit or any specific HTTP framework.
6
+
7
+ **The solve core lives in [`@selvajs/solve/server`](../solve/README.md)** — pipeline, L2 result
8
+ cache, single-flight, client and definition-byte caches. This package does not re-export it and does
9
+ not depend on it. What stays here is HTTP _request policy_, which is a different job from running a
10
+ solve.
7
11
 
8
12
  Logging follows the same rule as the rest of the package: nothing here logs unless you wire
9
13
  it. Modules that emit diagnostics take an optional `logger?: ILogger` and default to
@@ -20,18 +24,21 @@ pnpm add @selvajs/server
20
24
 
21
25
  ## Subpath exports
22
26
 
23
- | Export | Contents |
24
- | ----------------------------- | ------------------------------------------------------- |
25
- | `@selvajs/server` | Root — package entry point |
26
- | `@selvajs/server/compute` | Solve pipeline, SSRF guard, Rhino.Compute client wiring |
27
- | `@selvajs/server/definitions` | Definition service + render loader |
28
- | `@selvajs/server/providers` | Provider composition helpers |
29
- | `@selvajs/server/tokens` | API token (PAT) codec |
30
- | `@selvajs/server/errors` | Shared error types |
31
- | `@selvajs/server/logging` | pino-backed `ILogger` + request-id correlation |
32
- | `@selvajs/server/http` | Rate limiting, security headers, request limits |
33
- | `@selvajs/server/access` | Access/permission checks |
34
- | `@selvajs/server/ops` | Operational utilities |
27
+ **There is no root export.** Import from a subpath — `import … from '@selvajs/server'` fails to
28
+ resolve, on purpose. A root barrel re-exporting all nine subpaths put 41 symbols in one namespace and
29
+ hid which slice a consumer actually depended on; nothing in this repo used it.
30
+
31
+ | Export | Contents |
32
+ | ----------------------------- | ------------------------------------------------------------------ |
33
+ | `@selvajs/server/compute` | Compute limits, rate limiting, SSRF guard, remote-definition fetch |
34
+ | `@selvajs/server/definitions` | Definition service + render loader |
35
+ | `@selvajs/server/providers` | Provider composition helpers |
36
+ | `@selvajs/server/tokens` | API token (PAT) codec |
37
+ | `@selvajs/server/errors` | Shared error types |
38
+ | `@selvajs/server/logging` | pino-backed `ILogger` + request-id correlation |
39
+ | `@selvajs/server/http` | Security headers, request limits, route classification |
40
+ | `@selvajs/server/access` | Access/permission checks |
41
+ | `@selvajs/server/ops` | Operational utilities |
35
42
 
36
43
  Requires a `@selvajs/platform` provider (e.g. `@selvajs/local-provider` or
37
44
  `@selvajs/supabase-provider`) for data/storage/auth.
@@ -1,13 +1,5 @@
1
1
  export { resolveComputeLimits, readPositiveInt, readNonNegativeInt, readBool, type ComputeLimits, type EnvRecord } from './limits.js';
2
- export { createDefinitionByteCache, type DefinitionByteCache, type ByteCacheRef, type ByteCacheStats } from './definition-byte-cache.js';
3
- export { createMemorySolveResultCache, type MemorySolveResultCache, type SolveCacheStats } from './memory-solve-cache.js';
4
- export { deriveSolveCacheInputKey, type SolveCacheConfigSubset, type SolveCacheInputKey } from './solve-cache-key.js';
5
- export { encodeSolveCacheEntry, decodeSolveCacheEntry, gunzipEntryBody, type EnvelopeHeader, type DecodedSolveCacheEntry } from './solve-cache-envelope.js';
6
- export { createSolveCacheSingleFlight, type SolveCacheSingleFlight } from './solve-cache-single-flight.js';
7
2
  export { createComputeRateLimiter, DEFAULT_MAX_KEYS, type ComputeRateLimiter, type ComputeRateLimiterConfig, type RateLimitResult } from './rate-limit.js';
8
3
  export { isSafeRemoteDefinitionUrl, assertSafeRemoteDefinitionUrl } from './safe-url.js';
9
- export { transformInputParameter } from './transform-input.js';
10
- export { createClientCache, serverIdentity, type ClientCache, type ClientCacheConfig, type CachedClient, type ResolvedServer, type ServerIdentity } from './client-cache.js';
11
4
  export { createRemoteDefinitionFetcher, readBodyWithCap, type RemoteDefinitionFetcher, type RemoteDefinitionConfig } from './remote-definition.js';
12
- export { runSolvePipeline, adaptEnvelopeToEncoding, COMPUTE_CONTRACT_VERSION, COMPUTE_VERSION_HEADER, type SolvePipelineArgs, type SolvePipelineCacheHook, type SolveOutcome, type SolveEnvelope, type SolvePhaseMetrics, type PipelineInput } from './solve-pipeline.js';
13
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compute/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACN,4BAA4B,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,wBAAwB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACN,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACN,4BAA4B,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACN,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,6BAA6B,EAC7B,eAAe,EACf,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/compute/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,wBAAwB,EACxB,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EACN,6BAA6B,EAC7B,eAAe,EACf,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,wBAAwB,CAAC"}
@@ -1,14 +1,17 @@
1
- // Compute/solve server building blocks — transport-agnostic, env-injected.
1
+ // HTTP request policy for the compute path — transport-agnostic, env-injected.
2
+ //
3
+ // Admission control (rate limiting), an SSRF guard on operator-supplied URLs, env-derived limits,
4
+ // and the remote-definition fetcher. This is the policy *around* a solve, which is a different job
5
+ // from running one.
6
+ //
7
+ // **The solve core is not here.** Pipeline, L2 result cache, single-flight, and the client /
8
+ // definition-byte caches live in `@selvajs/solve/server`, which owns the solve flow on both sides of
9
+ // the wire. This sub-path deliberately does NOT re-export them: a compat shim was built during the
10
+ // extraction and removed before release, because it left this barrel at 24 exports of which 14 were
11
+ // borrowed — a surface that no longer described what the package does. `@selvajs/server` does not
12
+ // depend on `@selvajs/solve`.
2
13
  export { resolveComputeLimits, readPositiveInt, readNonNegativeInt, readBool } from './limits.js';
3
- export { createDefinitionByteCache } from './definition-byte-cache.js';
4
- export { createMemorySolveResultCache } from './memory-solve-cache.js';
5
- export { deriveSolveCacheInputKey } from './solve-cache-key.js';
6
- export { encodeSolveCacheEntry, decodeSolveCacheEntry, gunzipEntryBody } from './solve-cache-envelope.js';
7
- export { createSolveCacheSingleFlight } from './solve-cache-single-flight.js';
8
14
  export { createComputeRateLimiter, DEFAULT_MAX_KEYS } from './rate-limit.js';
9
15
  export { isSafeRemoteDefinitionUrl, assertSafeRemoteDefinitionUrl } from './safe-url.js';
10
- export { transformInputParameter } from './transform-input.js';
11
- export { createClientCache, serverIdentity } from './client-cache.js';
12
16
  export { createRemoteDefinitionFetcher, readBodyWithCap } from './remote-definition.js';
13
- export { runSolvePipeline, adaptEnvelopeToEncoding, COMPUTE_CONTRACT_VERSION, COMPUTE_VERSION_HEADER } from './solve-pipeline.js';
14
17
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compute/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,QAAQ,EAGR,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,yBAAyB,EAIzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACN,4BAA4B,EAG5B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACN,wBAAwB,EAGxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACN,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EAGf,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACN,4BAA4B,EAE5B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACN,wBAAwB,EACxB,gBAAgB,EAIhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EACN,iBAAiB,EACjB,cAAc,EAMd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,6BAA6B,EAC7B,eAAe,EAGf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACN,gBAAgB,EAChB,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,EAOtB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/compute/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,kGAAkG;AAClG,mGAAmG;AACnG,oBAAoB;AACpB,EAAE;AACF,6FAA6F;AAC7F,qGAAqG;AACrG,mGAAmG;AACnG,oGAAoG;AACpG,kGAAkG;AAClG,8BAA8B;AAE9B,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,QAAQ,EAGR,MAAM,aAAa,CAAC;AAErB,OAAO,EACN,wBAAwB,EACxB,gBAAgB,EAIhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EACN,6BAA6B,EAC7B,eAAe,EAGf,MAAM,wBAAwB,CAAC"}
@@ -86,8 +86,15 @@ export interface ComputeLimits {
86
86
  remoteDefinitionMaxBytes: number;
87
87
  /** Deadline on fetching a remote definition (slow-loris protection). */
88
88
  remoteDefinitionFetchTimeoutMs: number;
89
- /** In-process cache TTL for remote-fetched .gh bytes. */
90
- definitionCacheTtlMs: number;
89
+ /**
90
+ * TTL for the in-process cache of .gh bytes fetched from a REMOTE URL.
91
+ *
92
+ * Only the remote path is TTL'd, and the name says so deliberately: the other
93
+ * definition cache is keyed on an immutable version id, where expiry would be a
94
+ * bug (it can only ever throw away valid work). A URL's owner can swap the file
95
+ * underneath us, so that one needs a freshness bound and this is it.
96
+ */
97
+ remoteDefinitionCacheTtlMs: number;
91
98
  /**
92
99
  * Reuse the server's cached definition via a pointer instead of re-uploading
93
100
  * the binary each solve. SAFE only on a compute server that signals a
@@ -139,42 +146,27 @@ export interface ComputeLimits {
139
146
  */
140
147
  computeQueueWaitMs: number;
141
148
  /**
142
- * Total-byte budget (bytes) for the in-process definition-byte cache keyed on
143
- * immutable version id. A warm entry lets a solve skip `storage.get` entirely,
144
- * and a pointer-known solve never loads bytes at all. `0` disables the cache
145
- * (every solve re-reads storage). Sized as a total-byte LRU because definitions
146
- * span KB→hundreds of MB; env value is MB, converted here.
147
- */
148
- computeDefinitionByteCacheBytes: number;
149
- /**
150
- * Total-byte budget (bytes) for EACH warm client's in-process solve-response
151
- * cache (the scheduler L1 — the `fromCache` layer in front of Rhino.Compute).
152
- * Responses range KB→100s of MB (`computeResponseMaxBytes` allows 300 MB), so
153
- * the L1's entry-count cap alone can't bound heap; this adds a byte LRU on
154
- * top. Applies PER warm client — worst-case heap is this × the number of
155
- * distinct compute servers kept warm (`maxCachedClients`, default 16), though
156
- * real deployments run 1–2 servers. `0` disables the L1 response cache
157
- * entirely (every solve goes to compute or the L2). Env value is MB.
158
- */
159
- computeResponseCacheBytes: number;
160
- /**
161
- * Default per-definition entry quota for the durable L2 solve cache (H1), used
162
- * when a definition's `solveCacheLimit` is absent (inherit). A definition may
163
- * override this; `0` on the definition turns caching off for it. This global
164
- * default `0` means the L2 is effectively off until an operator sets a quota —
165
- * safe because the memory backend also ships only under
166
- * `SOLVE_CACHE_PROVIDER=memory`. Counts, not bytes: authors think in "how many
167
- * solves to remember"; the byte backstop below is the operator's memory guard.
149
+ * **Definition cache** — total-byte budget (bytes) for the in-process cache of
150
+ * .gh bytes keyed on immutable version id. A warm entry lets a solve skip
151
+ * `storage.get` entirely, and a pointer-known solve never loads bytes at all.
152
+ * `0` disables it (every solve re-reads storage). A total-byte LRU rather than
153
+ * an entry count because definitions span KB→hundreds of MB. Env value is MB.
168
154
  */
169
- solveCacheDefaultMaxEntries: number;
155
+ computeDefinitionCacheBytes: number;
170
156
  /**
171
- * Global byte backstop (bytes) across ALL definitions' L2 entries, evicted
172
- * global-LRU regardless of per-definition counts. Entries range KB→100s of MB,
173
- * so a count quota alone can't bound memory. `0` disables the backstop (rely on
174
- * per-definition counts only — not recommended in the memory backend). Env value
175
- * is MB, converted here. On Redis this moves to `maxmemory allkeys-lru`.
157
+ * **Solve cache** — total-byte budget (bytes) for EACH warm client's in-process
158
+ * cache of solve results (the `fromCache` layer in front of Rhino.Compute).
159
+ * Results range KB→100s of MB (`computeResponseMaxBytes` allows 300 MB), so an
160
+ * entry-count cap alone can't bound heap; this adds a byte LRU on top. `0`
161
+ * disables it (every solve goes to compute). Env value is MB.
162
+ *
163
+ * **This is per warm client, so the worst case multiplies.** Selva keeps up to
164
+ * `maxCachedClients` (default 16) distinct compute servers warm, so the true
165
+ * ceiling is this × 16 — 4 GB at the default. Real deployments run 1–2 servers,
166
+ * which is why the default is comfortable, but a deployment that fans out
167
+ * across many servers on a small VPS is exactly the case this knob exists for.
176
168
  */
177
- solveCacheMaxTotalBytes: number;
169
+ computeSolveCacheBytes: number;
178
170
  }
179
171
  /**
180
172
  * Resolve every server-side compute limit from an env map. Pure: the same env
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAI7D,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAS3D;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACvB,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,OAAc,GACpB,OAAO,CAaT;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC7B;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC,yEAAyE;IACzE,wBAAwB,EAAE,MAAM,CAAC;IACjC,wEAAwE;IACxE,8BAA8B,EAAE,MAAM,CAAC;IACvC,yDAAyD;IACzD,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,2BAA2B,EAAE,OAAO,CAAC;IACrC;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,yBAAyB,EAAE,OAAO,CAAC;IACnC;;;;;;;;OAQG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;;;;;;;OAQG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,+BAA+B,EAAE,MAAM,CAAC;IACxC;;;;;;;;;OASG;IACH,yBAAyB,EAAE,MAAM,CAAC;IAClC;;;;;;;;OAQG;IACH,2BAA2B,EAAE,MAAM,CAAC;IACpC;;;;;;OAMG;IACH,uBAAuB,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,GAAE,OAAc,GAAG,aAAa,CAmD1F"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAI7D,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAS3D;;;GAGG;AACH,wBAAgB,eAAe,CAC9B,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,OAAc,GACpB,MAAM,CAcR;AAwBD;;;GAGG;AACH,wBAAgB,QAAQ,CACvB,GAAG,EAAE,SAAS,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,OAAc,GACpB,OAAO,CAaT;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC7B;;;;;;;;;OASG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;OASG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC,yEAAyE;IACzE,wBAAwB,EAAE,MAAM,CAAC;IACjC,wEAAwE;IACxE,8BAA8B,EAAE,MAAM,CAAC;IACvC;;;;;;;OAOG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,2BAA2B,EAAE,OAAO,CAAC;IACrC;;;;OAIG;IACH,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,yBAAyB,EAAE,OAAO,CAAC;IACnC;;;;;;;;OAQG;IACH,0BAA0B,EAAE,MAAM,CAAC;IACnC;;;;;;;;OAQG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;OAMG;IACH,2BAA2B,EAAE,MAAM,CAAC;IACpC;;;;;;;;;;;;OAYG;IACH,sBAAsB,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,GAAE,OAAc,GAAG,aAAa,CAmD1F"}
@@ -67,6 +67,28 @@ export function readNonNegativeInt(env, name, fallback, logger = noop) {
67
67
  }
68
68
  return Math.floor(parsed);
69
69
  }
70
+ /**
71
+ * Read a renamed variable, honouring its previous name for one minor version.
72
+ *
73
+ * Returns the env map's value under `name`, or — when that is unset and the old
74
+ * name is present — the old value plus a warning naming both. Setting both is not
75
+ * an error: the new name wins silently, which is what an operator mid-migration
76
+ * expects.
77
+ *
78
+ * This exists so a rename is never a silent behaviour change. A var that quietly
79
+ * stops being read looks exactly like a var that is working, and the failure only
80
+ * surfaces as a memory number nobody is watching.
81
+ */
82
+ function readRenamed(env, name, oldName, logger) {
83
+ if (env[name] !== undefined || env[oldName] === undefined)
84
+ return env;
85
+ logger.warn('Deprecated env var: rename it', {
86
+ component: 'selva',
87
+ envVar: oldName,
88
+ renamedTo: name
89
+ });
90
+ return { ...env, [name]: env[oldName] };
91
+ }
70
92
  /**
71
93
  * Parse a boolean env flag. Accepts `true/1/yes/on` (case-insensitive) as true
72
94
  * and `false/0/no/off` as false; any other / absent value falls back.
@@ -94,6 +116,11 @@ export function readBool(env, name, fallback, logger = noop) {
94
116
  * this once at its composition root with `$env/dynamic/private`.
95
117
  */
96
118
  export function resolveComputeLimits(env, logger = noop) {
119
+ // Renamed 2026-07 so each cache var says what it HOLDS. Old names still read,
120
+ // with a boot warning; drop this shim one minor version on.
121
+ env = readRenamed(env, 'COMPUTE_DEFINITION_CACHE_MB', 'COMPUTE_DEFINITION_BYTE_CACHE_MB', logger);
122
+ env = readRenamed(env, 'COMPUTE_SOLVE_CACHE_MB', 'COMPUTE_RESPONSE_CACHE_MB', logger);
123
+ env = readRenamed(env, 'REMOTE_DEFINITION_CACHE_TTL_MS', 'DEFINITION_CACHE_TTL_MS', logger);
97
124
  const maxGhFileSize = readPositiveInt(env, 'MAX_GH_FILE_SIZE_BYTES', 50 * MB, logger);
98
125
  return {
99
126
  maxSolveDurationMs: readPositiveInt(env, 'MAX_SOLVE_DURATION_MS', 100_000, logger),
@@ -106,7 +133,7 @@ export function resolveComputeLimits(env, logger = noop) {
106
133
  // Tracks the upload cap so a remote URL can't smuggle a larger file.
107
134
  remoteDefinitionMaxBytes: maxGhFileSize,
108
135
  remoteDefinitionFetchTimeoutMs: readPositiveInt(env, 'REMOTE_DEFINITION_FETCH_TIMEOUT_MS', 30_000, logger),
109
- definitionCacheTtlMs: readPositiveInt(env, 'DEFINITION_CACHE_TTL_MS', 5 * 60 * 1000, logger),
136
+ remoteDefinitionCacheTtlMs: readPositiveInt(env, 'REMOTE_DEFINITION_CACHE_TTL_MS', 5 * 60 * 1000, logger),
110
137
  computeReuseDefinitionCache: readBool(env, 'COMPUTE_REUSE_DEFINITION_CACHE', true, logger),
111
138
  computeServerCachesolve: readBool(env, 'COMPUTE_SERVER_CACHESOLVE', true, logger),
112
139
  computeCacheErroredSolves: readBool(env, 'COMPUTE_CACHE_ERRORED_SOLVES', false, logger),
@@ -120,17 +147,12 @@ export function resolveComputeLimits(env, logger = noop) {
120
147
  // Env is MB; 0 disables. Default 256 MB holds a handful of typical
121
148
  // definitions warm without pinning gigabytes. readNonNegativeInt so `0`
122
149
  // (disable) is honored rather than treated as invalid.
123
- computeDefinitionByteCacheBytes: readNonNegativeInt(env, 'COMPUTE_DEFINITION_BYTE_CACHE_MB', 256, logger) * MB,
124
- // Per-warm-client L1 response cache budget. Env is MB; 0 disables the L1.
125
- // Default 256 MB: enough to keep a scrub session's recent responses warm
126
- // without letting 20 × 300 MB worst-case entries pin gigabytes (audit C2).
127
- computeResponseCacheBytes: readNonNegativeInt(env, 'COMPUTE_RESPONSE_CACHE_MB', 256, logger) * MB,
128
- // L2 durable solve cache (H1). Default per-definition quota 0 = inherit-to-off
129
- // until an operator opts in; the memory backend also only mounts under
130
- // SOLVE_CACHE_PROVIDER=memory, so nothing caches by accident. Byte backstop
131
- // 512 MB caps total heap use across all definitions (env is MB).
132
- solveCacheDefaultMaxEntries: readNonNegativeInt(env, 'SOLVE_CACHE_DEFAULT_MAX_ENTRIES', 0, logger),
133
- solveCacheMaxTotalBytes: readNonNegativeInt(env, 'SOLVE_CACHE_MAX_TOTAL_MB', 512, logger) * MB
150
+ computeDefinitionCacheBytes: readNonNegativeInt(env, 'COMPUTE_DEFINITION_CACHE_MB', 256, logger) * MB,
151
+ // Per-warm-client solve cache budget. Env is MB; 0 disables it. Default
152
+ // 256 MB: enough to keep a scrub session's recent solves warm without
153
+ // letting worst-case entries pin gigabytes (audit C2). PER warm client —
154
+ // see the field doc for the ×16 worst case.
155
+ computeSolveCacheBytes: readNonNegativeInt(env, 'COMPUTE_SOLVE_CACHE_MB', 256, logger) * MB
134
156
  };
135
157
  }
136
158
  //# sourceMappingURL=limits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../src/compute/limits.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@selvajs/server",
3
- "version": "0.2.1",
4
- "description": "Transport-agnostic compute/solve/definitions server building blocks for apps built on the Selva engine (limits, rate limiting, SSRF guard, input transform, solve pipeline, definition service + render loader)",
3
+ "version": "1.0.0-beta.0",
4
+ "description": "Transport-agnostic server building blocks for apps built on the Selva engine (limits, rate limiting, SSRF guard, remote-definition fetch, definition service + render loader); the solve core lives in @selvajs/solve/server",
5
5
  "license": "MIT",
6
6
  "author": "VektorNode",
7
7
  "homepage": "https://github.com/VektorNode/selva#readme",
@@ -25,13 +25,7 @@
25
25
  "node": ">=22.0.0"
26
26
  },
27
27
  "type": "module",
28
- "main": "./dist/index.js",
29
- "types": "./dist/index.d.ts",
30
28
  "exports": {
31
- ".": {
32
- "types": "./dist/index.d.ts",
33
- "import": "./dist/index.js"
34
- },
35
29
  "./compute": {
36
30
  "types": "./dist/compute/index.d.ts",
37
31
  "import": "./dist/compute/index.js"
@@ -76,7 +70,7 @@
76
70
  "!**/*.spec.*"
77
71
  ],
78
72
  "dependencies": {
79
- "@selvajs/compute": "^3.1.0",
73
+ "@selvajs/compute": "^4.0.0-beta.0",
80
74
  "@selvajs/platform": "^0.16.0",
81
75
  "@selvajs/schemas": "^4.7.0"
82
76
  },
@@ -93,9 +87,9 @@
93
87
  }
94
88
  },
95
89
  "devDependencies": {
96
- "@types/node": "^22.20.1",
97
- "typescript": "^6.0.3",
98
- "vitest": "^3.2.7"
90
+ "@types/node": "^26.1.2",
91
+ "typescript": "~6.0.3",
92
+ "vitest": "^4.1.10"
99
93
  },
100
94
  "scripts": {
101
95
  "build": "tsc",
@@ -1,135 +0,0 @@
1
- import { GrasshopperClient, type SolveScheduler } from '@selvajs/compute';
2
- /**
3
- * Opaque identity of a compute server. Callers never construct the branded
4
- * string directly — they pass a resolved server config to `serverIdentity()`.
5
- * Keeping this opaque from day one (ADR 0004 D1) means "a server is now a pool
6
- * of URLs behind one id" stays an additive, non-breaking change.
7
- */
8
- export type ServerIdentity = string & {
9
- readonly __brand: 'ServerIdentity';
10
- };
11
- /** Minimal resolved-server shape the cache needs (a subset of the app's `ComputeServerConfig`). */
12
- export interface ResolvedServer {
13
- /** Stable identity — the cache key. */
14
- id: string;
15
- /** Base URL of the Rhino.Compute instance (a resolution detail of `id`). */
16
- serverUrl: string;
17
- /** Sent as `RhinoComputeKey`. */
18
- apiKey?: string;
19
- }
20
- /** Derive the opaque cache identity from a resolved server. Identity is the `id`. */
21
- export declare function serverIdentity(server: Pick<ResolvedServer, 'id'>): ServerIdentity;
22
- /**
23
- * Per-request telemetry holders read by the caller right after a solve resolves
24
- * to build a Server-Timing header. Populated by the client/scheduler callbacks.
25
- */
26
- export interface CachedClient {
27
- client: GrasshopperClient;
28
- scheduler: SolveScheduler;
29
- /**
30
- * Last decode/solve/encode reported by the compute server (Server-Timing),
31
- * written by onServerTiming. `seq` increments on every write. The scheduler
32
- * runs up to `maxConcurrentSolves` solves at once, so `last` alone can't be
33
- * trusted per-request: callers snapshot `seq` before their solve and
34
- * attribute `last` only when exactly one write happened since (necessarily
35
- * theirs — see the guard in `runSolvePipeline`), dropping the segment
36
- * otherwise instead of misattributing another request's timing.
37
- */
38
- rhinoTiming: {
39
- last: {
40
- decode: number;
41
- solve: number;
42
- encode: number;
43
- } | null;
44
- seq: number;
45
- };
46
- /**
47
- * Last solve's cache verdicts from the scheduler's onSettle: whether the
48
- * in-process response cache served it (no compute call) and whether the
49
- * definition had to be re-uploaded. `seq` increments on EVERY settle
50
- * (success or error); `last` is only written on success. Same
51
- * snapshot-and-attribute pattern as rhinoTiming — onSettle always fires
52
- * before the corresponding `scheduler.solve()` promise resolves, so at the
53
- * caller's read point its own settle is included in `seq`.
54
- */
55
- solveMeta: {
56
- last: {
57
- fromCache: boolean;
58
- definitionReuploaded?: boolean;
59
- } | null;
60
- seq: number;
61
- };
62
- }
63
- /**
64
- * Config injected by the consuming app. Everything that used to be read from
65
- * `$env` / `computeLimits` in the app module is passed in, so this module stays
66
- * env-agnostic and testable.
67
- */
68
- export interface ClientCacheConfig {
69
- /** Per-solve timeout forwarded to the scheduler (`ComputeLimits.maxSolveDurationMs`). */
70
- maxSolveDurationMs: number;
71
- /** Ask Rhino.Compute to cache solve results and return them on identical repeats. */
72
- cachesolve: boolean;
73
- /** Also cache solves that reported GH errors (only meaningful with `cachesolve`). */
74
- cacheerroredsolves: boolean;
75
- /** Reference large definitions by server cache key (pointer) instead of re-uploading. */
76
- reuseServerDefinitionCache: boolean;
77
- /**
78
- * Max in-flight solves per compute server (scheduler `maxConcurrent`; excess
79
- * FIFO-queues). Size to the server's `compute.geometry` child count
80
- * (`ComputeLimits.computeMaxConcurrentSolves`).
81
- */
82
- maxConcurrentSolves: number;
83
- /**
84
- * Backpressure — max solves that may WAIT in the FIFO queue (excludes the
85
- * in-flight `maxConcurrentSolves`). `0` = unbounded (`ComputeLimits.
86
- * computeMaxQueueDepth`); a full queue sheds new solves with `QUEUE_FULL`.
87
- */
88
- maxQueueDepth: number;
89
- /**
90
- * Backpressure — max ms a solve may sit queued before executing; `0` = no
91
- * deadline (`ComputeLimits.computeQueueWaitMs`). A too-long wait sheds with
92
- * `QUEUE_TIMEOUT`.
93
- */
94
- queueWaitMs: number;
95
- /**
96
- * Byte budget for this client's in-process solve-response cache (scheduler
97
- * L1), evicted LRU alongside its entry-count cap. Applies per warm client —
98
- * total worst-case heap is this × `maxCachedClients`. `0` disables the L1
99
- * response cache entirely (`ComputeLimits.computeResponseCacheBytes`).
100
- */
101
- responseCacheMaxBytes: number;
102
- /** Concise cache/timing logs. When false, `onDebugLog` is never invoked. */
103
- debug: boolean;
104
- /** VERBOSE lib-level logging (full solve request/response incl. geometry). */
105
- debugVerbose: boolean;
106
- /** Max distinct warm clients before the LRU evicts the oldest. Default 16. */
107
- maxCachedClients?: number;
108
- /** Sink for the concise debug lines (the app wires `console.log`). */
109
- onDebugLog?: (message: string) => void;
110
- }
111
- export interface ClientCache {
112
- /**
113
- * Get (or create) the warm client + scheduler for a resolved compute server,
114
- * keyed by its `id`. `definitionGuid`, when present, is stamped as the
115
- * `X-Selva-Definition` header on this client's outbound solve/IO requests —
116
- * inert routing/telemetry metadata until a pool router exists (ADR 0004 D2).
117
- */
118
- getClient(server: ResolvedServer, opts?: {
119
- definitionGuid?: string;
120
- }): Promise<CachedClient>;
121
- /**
122
- * Dispose and drop the warm client for `id` (or a `ServerIdentity`). Called by
123
- * the config-write path when a server's URL/key rotates so the next request
124
- * rebuilds against fresh connection details (ADR 0004 Consequences).
125
- */
126
- evict(id: string | ServerIdentity): void;
127
- /** Dispose every warm client. Test seam / shutdown hook. */
128
- disposeAll(): void;
129
- }
130
- /**
131
- * Build a per-server warm-client cache. Each cache owns its own LRU `Map` keyed
132
- * on server `id`.
133
- */
134
- export declare function createClientCache(config: ClientCacheConfig): ClientCache;
135
- //# sourceMappingURL=client-cache.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"client-cache.d.ts","sourceRoot":"","sources":["../../src/compute/client-cache.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EAGjB,KAAK,cAAc,EACnB,MAAM,kBAAkB,CAAC;AAyB1B;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE7E,mGAAmG;AACnG,MAAM,WAAW,cAAc;IAC9B,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG,cAAc,CAEjF;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;IAC1B;;;;;;;;OAQG;IACH,WAAW,EAAE;QAAE,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7F;;;;;;;;OAQG;IACH,SAAS,EAAE;QACV,IAAI,EAAE;YAAE,SAAS,EAAE,OAAO,CAAC;YAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;SAAE,GAAG,IAAI,CAAC;QACpE,GAAG,EAAE,MAAM,CAAC;KACZ,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IACjC,yFAAyF;IACzF,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qFAAqF;IACrF,UAAU,EAAE,OAAO,CAAC;IACpB,qFAAqF;IACrF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,yFAAyF;IACzF,0BAA0B,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,KAAK,EAAE,OAAO,CAAC;IACf,8EAA8E;IAC9E,YAAY,EAAE,OAAO,CAAC;IACtB,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,WAAW;IAC3B;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7F;;;;OAIG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAC;IACzC,4DAA4D;IAC5D,UAAU,IAAI,IAAI,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAuLxE"}