@selvajs/server 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compute/idempotency.d.ts +63 -0
- package/dist/compute/idempotency.d.ts.map +1 -0
- package/dist/compute/idempotency.js +97 -0
- package/dist/compute/idempotency.js.map +1 -0
- package/dist/compute/index.d.ts +1 -0
- package/dist/compute/index.d.ts.map +1 -1
- package/dist/compute/index.js +1 -0
- package/dist/compute/index.js.map +1 -1
- package/dist/compute/limits.d.ts +12 -20
- package/dist/compute/limits.d.ts.map +1 -1
- package/dist/compute/limits.js +5 -4
- package/dist/compute/limits.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotency store for the solve endpoint: a repeat of the same request within
|
|
3
|
+
* the TTL replays the first response instead of re-solving.
|
|
4
|
+
*
|
|
5
|
+
* **This absorbs client retries; it is not a result cache.** The TTL is short
|
|
6
|
+
* and the store is process-local, so a retry that lands on another instance
|
|
7
|
+
* (or after the TTL) re-solves. That is acceptable — a duplicate solve costs
|
|
8
|
+
* compute, not correctness. What it must never do is return one caller's result
|
|
9
|
+
* to another, hence the caller identity in the key.
|
|
10
|
+
*
|
|
11
|
+
* Concurrency matters more than the hit rate. A client that retries on timeout
|
|
12
|
+
* usually retries *while the first solve is still running*, so the store holds a
|
|
13
|
+
* **promise**, reserved before the work starts: the second request awaits the
|
|
14
|
+
* first rather than starting a second solve. A reservation that rejects is
|
|
15
|
+
* dropped, so a failed solve is retryable rather than a cached error.
|
|
16
|
+
*
|
|
17
|
+
* Bounded the same way as the rate limiter: amortized sweep plus a hard cap, both
|
|
18
|
+
* driven by `run` rather than a timer — a timer would keep the event loop alive
|
|
19
|
+
* and give this module a lifecycle its callers don't have.
|
|
20
|
+
*/
|
|
21
|
+
export interface IdempotencyStoreConfig {
|
|
22
|
+
/** How long a completed response stays replayable, in ms. */
|
|
23
|
+
ttlMs: number;
|
|
24
|
+
/**
|
|
25
|
+
* Max retained entries. Once live entries exceed this, the ones nearest
|
|
26
|
+
* expiry are evicted. Evicting only costs a re-solve on a retry, so size this
|
|
27
|
+
* above the plausible number of in-flight + recent keys.
|
|
28
|
+
*/
|
|
29
|
+
maxKeys?: number;
|
|
30
|
+
/**
|
|
31
|
+
* How often (ms) to sweep expired entries, amortized onto `run`. Defaults to
|
|
32
|
+
* `ttlMs`. `0` disables the sweep, leaving only the cap (test seam).
|
|
33
|
+
*/
|
|
34
|
+
sweepIntervalMs?: number;
|
|
35
|
+
}
|
|
36
|
+
/** Default {@link IdempotencyStoreConfig.maxKeys}. */
|
|
37
|
+
export declare const DEFAULT_IDEMPOTENCY_MAX_KEYS = 10000;
|
|
38
|
+
export interface IdempotencyOutcome<T> {
|
|
39
|
+
value: T;
|
|
40
|
+
/** True when this call awaited an existing entry rather than running `fn`. */
|
|
41
|
+
replayed: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface IdempotencyStore<T> {
|
|
44
|
+
/**
|
|
45
|
+
* Run `fn` under `key`, or join/replay the entry already stored there.
|
|
46
|
+
*
|
|
47
|
+
* The entry is reserved before `fn` starts, so a concurrent retry awaits the
|
|
48
|
+
* first run instead of starting its own. A rejection drops the reservation.
|
|
49
|
+
*/
|
|
50
|
+
run(key: string, fn: () => Promise<T>): Promise<IdempotencyOutcome<T>>;
|
|
51
|
+
/** Test seam — wipes in-memory state. Production code never calls this. */
|
|
52
|
+
reset(): void;
|
|
53
|
+
/** Retained entry count, including any not yet swept. For tests/observability. */
|
|
54
|
+
size(): number;
|
|
55
|
+
readonly config: Readonly<IdempotencyStoreConfig>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build a process-local idempotency store. `T` is whatever the caller replays;
|
|
59
|
+
* the solve route stores a serialized response snapshot rather than a `Response`,
|
|
60
|
+
* because a `Response` body can only be read once.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createIdempotencyStore<T>(config: IdempotencyStoreConfig): IdempotencyStore<T>;
|
|
63
|
+
//# sourceMappingURL=idempotency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/compute/idempotency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,sBAAsB;IACtC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,QAAS,CAAC;AAEnD,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC;IACT,8EAA8E;IAC9E,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC;;;;;OAKG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACvE,2EAA2E;IAC3E,KAAK,IAAI,IAAI,CAAC;IACd,kFAAkF;IAClF,IAAI,IAAI,MAAM,CAAC;IACf,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC;CAClD;AAYD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,MAAM,EAAE,sBAAsB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAwE7F"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotency store for the solve endpoint: a repeat of the same request within
|
|
3
|
+
* the TTL replays the first response instead of re-solving.
|
|
4
|
+
*
|
|
5
|
+
* **This absorbs client retries; it is not a result cache.** The TTL is short
|
|
6
|
+
* and the store is process-local, so a retry that lands on another instance
|
|
7
|
+
* (or after the TTL) re-solves. That is acceptable — a duplicate solve costs
|
|
8
|
+
* compute, not correctness. What it must never do is return one caller's result
|
|
9
|
+
* to another, hence the caller identity in the key.
|
|
10
|
+
*
|
|
11
|
+
* Concurrency matters more than the hit rate. A client that retries on timeout
|
|
12
|
+
* usually retries *while the first solve is still running*, so the store holds a
|
|
13
|
+
* **promise**, reserved before the work starts: the second request awaits the
|
|
14
|
+
* first rather than starting a second solve. A reservation that rejects is
|
|
15
|
+
* dropped, so a failed solve is retryable rather than a cached error.
|
|
16
|
+
*
|
|
17
|
+
* Bounded the same way as the rate limiter: amortized sweep plus a hard cap, both
|
|
18
|
+
* driven by `run` rather than a timer — a timer would keep the event loop alive
|
|
19
|
+
* and give this module a lifecycle its callers don't have.
|
|
20
|
+
*/
|
|
21
|
+
/** Default {@link IdempotencyStoreConfig.maxKeys}. */
|
|
22
|
+
export const DEFAULT_IDEMPOTENCY_MAX_KEYS = 10_000;
|
|
23
|
+
/**
|
|
24
|
+
* Build a process-local idempotency store. `T` is whatever the caller replays;
|
|
25
|
+
* the solve route stores a serialized response snapshot rather than a `Response`,
|
|
26
|
+
* because a `Response` body can only be read once.
|
|
27
|
+
*/
|
|
28
|
+
export function createIdempotencyStore(config) {
|
|
29
|
+
const ttlMs = Math.max(0, Math.floor(config.ttlMs));
|
|
30
|
+
const maxKeys = Math.max(1, Math.floor(config.maxKeys ?? DEFAULT_IDEMPOTENCY_MAX_KEYS));
|
|
31
|
+
const sweepIntervalMs = Math.max(0, Math.floor(config.sweepIntervalMs ?? ttlMs));
|
|
32
|
+
const resolvedConfig = Object.freeze({
|
|
33
|
+
...config,
|
|
34
|
+
ttlMs,
|
|
35
|
+
maxKeys,
|
|
36
|
+
sweepIntervalMs
|
|
37
|
+
});
|
|
38
|
+
const entries = new Map();
|
|
39
|
+
let nextSweepAt = Number.POSITIVE_INFINITY;
|
|
40
|
+
function maybeSweep(now, headroom = 0) {
|
|
41
|
+
const budget = Math.max(0, maxKeys - headroom);
|
|
42
|
+
const dueForSweep = sweepIntervalMs > 0 && now >= nextSweepAt;
|
|
43
|
+
if (!dueForSweep && entries.size <= budget)
|
|
44
|
+
return;
|
|
45
|
+
for (const [key, entry] of entries) {
|
|
46
|
+
if (entry.expiresAt !== null && now > entry.expiresAt)
|
|
47
|
+
entries.delete(key);
|
|
48
|
+
}
|
|
49
|
+
if (sweepIntervalMs > 0)
|
|
50
|
+
nextSweepAt = now + sweepIntervalMs;
|
|
51
|
+
if (entries.size > budget) {
|
|
52
|
+
// In-flight entries sort last: evicting one would orphan the retries
|
|
53
|
+
// awaiting it, so they are given up only when nothing else is left.
|
|
54
|
+
const byExpiryAsc = [...entries.entries()].sort((a, b) => (a[1].expiresAt ?? Infinity) - (b[1].expiresAt ?? Infinity));
|
|
55
|
+
for (let i = 0; i < byExpiryAsc.length - budget; i++)
|
|
56
|
+
entries.delete(byExpiryAsc[i][0]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
config: resolvedConfig,
|
|
61
|
+
async run(key, fn) {
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
const existing = entries.get(key);
|
|
64
|
+
if (existing && (existing.expiresAt === null || now <= existing.expiresAt)) {
|
|
65
|
+
return { value: await existing.promise, replayed: true };
|
|
66
|
+
}
|
|
67
|
+
maybeSweep(now, entries.has(key) ? 0 : 1);
|
|
68
|
+
const promise = fn();
|
|
69
|
+
const entry = { promise, expiresAt: null };
|
|
70
|
+
entries.set(key, entry);
|
|
71
|
+
if (sweepIntervalMs > 0 && nextSweepAt === Number.POSITIVE_INFINITY) {
|
|
72
|
+
nextSweepAt = now + sweepIntervalMs;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const value = await promise;
|
|
76
|
+
entry.expiresAt = Date.now() + ttlMs;
|
|
77
|
+
return { value, replayed: false };
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
// A failed solve is retryable — drop the reservation rather than
|
|
81
|
+
// replaying the error to every retry for the whole TTL. Only drop our
|
|
82
|
+
// own entry: a later `run` may already have replaced it.
|
|
83
|
+
if (entries.get(key) === entry)
|
|
84
|
+
entries.delete(key);
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
reset() {
|
|
89
|
+
entries.clear();
|
|
90
|
+
nextSweepAt = Number.POSITIVE_INFINITY;
|
|
91
|
+
},
|
|
92
|
+
size() {
|
|
93
|
+
return entries.size;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=idempotency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency.js","sourceRoot":"","sources":["../../src/compute/idempotency.ts"],"names":[],"mappings":"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"}
|
package/dist/compute/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { resolveComputeLimits, readPositiveInt, readNonNegativeInt, readBool, type ComputeLimits, type EnvRecord } from './limits.js';
|
|
2
2
|
export { createComputeRateLimiter, DEFAULT_MAX_KEYS, type ComputeRateLimiter, type ComputeRateLimiterConfig, type RateLimitResult } from './rate-limit.js';
|
|
3
|
+
export { createIdempotencyStore, DEFAULT_IDEMPOTENCY_MAX_KEYS, type IdempotencyStore, type IdempotencyStoreConfig, type IdempotencyOutcome } from './idempotency.js';
|
|
3
4
|
export { isSafeRemoteDefinitionUrl, assertSafeRemoteDefinitionUrl } from './safe-url.js';
|
|
4
5
|
export { createRemoteDefinitionFetcher, readBodyWithCap, type RemoteDefinitionFetcher, type RemoteDefinitionConfig } from './remote-definition.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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
|
+
{"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,EACN,sBAAsB,EACtB,4BAA4B,EAC5B,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,MAAM,kBAAkB,CAAC;AAE1B,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"}
|
package/dist/compute/index.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// depend on `@selvajs/solve`.
|
|
13
13
|
export { resolveComputeLimits, readPositiveInt, readNonNegativeInt, readBool } from './limits.js';
|
|
14
14
|
export { createComputeRateLimiter, DEFAULT_MAX_KEYS } from './rate-limit.js';
|
|
15
|
+
export { createIdempotencyStore, DEFAULT_IDEMPOTENCY_MAX_KEYS } from './idempotency.js';
|
|
15
16
|
export { isSafeRemoteDefinitionUrl, assertSafeRemoteDefinitionUrl } from './safe-url.js';
|
|
16
17
|
export { createRemoteDefinitionFetcher, readBodyWithCap } from './remote-definition.js';
|
|
17
18
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
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"}
|
|
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,EACN,sBAAsB,EACtB,4BAA4B,EAI5B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AAEzF,OAAO,EACN,6BAA6B,EAC7B,eAAe,EAGf,MAAM,wBAAwB,CAAC"}
|
package/dist/compute/limits.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface ComputeLimits {
|
|
|
49
49
|
* serverless platform cap may shoot the request sooner; bumping past those
|
|
50
50
|
* caps produces 502s, not longer solves.
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
solveDeadlineMs: number;
|
|
53
53
|
/** Fixed-window cap on /api/compute: window length + max requests per window. */
|
|
54
54
|
rateLimitWindowMs: number;
|
|
55
55
|
rateLimitMaxRequests: number;
|
|
@@ -116,33 +116,25 @@ export interface ComputeLimits {
|
|
|
116
116
|
* honoring the flag. Conservative default off.
|
|
117
117
|
*/
|
|
118
118
|
computeCacheErroredSolves: boolean;
|
|
119
|
-
/**
|
|
120
|
-
* Max in-flight solves this app instance sends to ONE compute server
|
|
121
|
-
* (forwarded as the SolveScheduler's `maxConcurrent`; excess solves FIFO-queue).
|
|
122
|
-
* Size it to the server's `compute.geometry` child count — Rhino.Compute
|
|
123
|
-
* spawns N children per VM precisely to run N solves concurrently, and a
|
|
124
|
-
* lower value idles that capacity while users queue (audit B6: the scheduler's
|
|
125
|
-
* queue-mode default is 1, which serialized ALL solves per server). Multiple
|
|
126
|
-
* app instances each apply their own cap.
|
|
127
|
-
*/
|
|
128
|
-
computeMaxConcurrentSolves: number;
|
|
129
119
|
/**
|
|
130
120
|
* Backpressure — max solves allowed to WAIT in the per-server FIFO queue (i.e.
|
|
131
|
-
* excluding the
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
121
|
+
* excluding the in-flight solves, capped at the scheduler's `maxConcurrent`,
|
|
122
|
+
* itself auto-detected from the compute server's active child count). A solve
|
|
123
|
+
* that arrives to a full queue is rejected immediately (scheduler `QUEUE_FULL`,
|
|
124
|
+
* mapped to HTTP 503 + `Retry-After`) instead of piling up unbounded. `0` =
|
|
125
|
+
* unbounded (the pre-backpressure default): the queue grows without limit,
|
|
126
|
+
* matching prior behavior. Size it to roughly 2–3× the compute server's
|
|
127
|
+
* child count once the Rhino pool's real capacity is known — rejecting fast
|
|
128
|
+
* beats a hung request.
|
|
137
129
|
*/
|
|
138
130
|
computeMaxQueueDepth: number;
|
|
139
131
|
/**
|
|
140
132
|
* Backpressure — longest (ms) a solve may sit QUEUED before it starts
|
|
141
|
-
* executing; still-waiting past this it's
|
|
133
|
+
* executing; still-waiting past this it's rejected (scheduler `QUEUE_TIMEOUT` →
|
|
142
134
|
* HTTP 503 + `Retry-After`) rather than burning compute on a stale request.
|
|
143
135
|
* Bounds tail latency: the scheduler's `timeoutMs` clock starts at execution,
|
|
144
136
|
* so without this a solve's total wait is unbounded and invisible. `0` = no
|
|
145
|
-
* queue deadline (the default). A sensible tuned value is ≈ `
|
|
137
|
+
* queue deadline (the default). A sensible tuned value is ≈ `solveDeadlineMs`.
|
|
146
138
|
*/
|
|
147
139
|
computeQueueWaitMs: number;
|
|
148
140
|
/**
|
|
@@ -161,7 +153,7 @@ export interface ComputeLimits {
|
|
|
161
153
|
* disables it (every solve goes to compute). Env value is MB.
|
|
162
154
|
*
|
|
163
155
|
* **This is per warm client, so the worst case multiplies.** Selva keeps up to
|
|
164
|
-
* `
|
|
156
|
+
* `maxWarmComputeServers` (default 16) distinct compute servers warm, so the true
|
|
165
157
|
* ceiling is this × 16 — 4 GB at the default. Real deployments run 1–2 servers,
|
|
166
158
|
* which is why the default is comfortable, but a deployment that fans out
|
|
167
159
|
* across many servers on a small VPS is exactly the case this knob exists for.
|
|
@@ -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;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,
|
|
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,eAAe,EAAE,MAAM,CAAC;IACxB,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;;;;;;;;;;OAUG;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,CAoD1F"}
|
package/dist/compute/limits.js
CHANGED
|
@@ -121,9 +121,12 @@ export function resolveComputeLimits(env, logger = noop) {
|
|
|
121
121
|
env = readRenamed(env, 'COMPUTE_DEFINITION_CACHE_MB', 'COMPUTE_DEFINITION_BYTE_CACHE_MB', logger);
|
|
122
122
|
env = readRenamed(env, 'COMPUTE_SOLVE_CACHE_MB', 'COMPUTE_RESPONSE_CACHE_MB', logger);
|
|
123
123
|
env = readRenamed(env, 'REMOTE_DEFINITION_CACHE_TTL_MS', 'DEFINITION_CACHE_TTL_MS', logger);
|
|
124
|
+
// Renamed 2026-08 into the COMPUTE_* namespace it belongs to, and to say what it
|
|
125
|
+
// bounds — one solve — rather than a vague "duration".
|
|
126
|
+
env = readRenamed(env, 'COMPUTE_SOLVE_DEADLINE_MS', 'MAX_SOLVE_DURATION_MS', logger);
|
|
124
127
|
const maxGhFileSize = readPositiveInt(env, 'MAX_GH_FILE_SIZE_BYTES', 50 * MB, logger);
|
|
125
128
|
return {
|
|
126
|
-
|
|
129
|
+
solveDeadlineMs: readPositiveInt(env, 'COMPUTE_SOLVE_DEADLINE_MS', 100_000, logger),
|
|
127
130
|
rateLimitWindowMs: readPositiveInt(env, 'COMPUTE_RATE_LIMIT_WINDOW_MS', 100_000, logger),
|
|
128
131
|
rateLimitMaxRequests: readPositiveInt(env, 'COMPUTE_RATE_LIMIT_MAX', 120, logger),
|
|
129
132
|
maxGhFileSize,
|
|
@@ -137,9 +140,7 @@ export function resolveComputeLimits(env, logger = noop) {
|
|
|
137
140
|
computeReuseDefinitionCache: readBool(env, 'COMPUTE_REUSE_DEFINITION_CACHE', true, logger),
|
|
138
141
|
computeServerCachesolve: readBool(env, 'COMPUTE_SERVER_CACHESOLVE', true, logger),
|
|
139
142
|
computeCacheErroredSolves: readBool(env, 'COMPUTE_CACHE_ERRORED_SOLVES', false, logger),
|
|
140
|
-
//
|
|
141
|
-
computeMaxConcurrentSolves: readPositiveInt(env, 'COMPUTE_MAX_CONCURRENT', 4, logger),
|
|
142
|
-
// Both 0 (unbounded / no deadline) by default — nothing sheds until an
|
|
143
|
+
// Both 0 (unbounded / no deadline) by default — nothing is rejected until an
|
|
143
144
|
// operator who's measured their pool opts in. readNonNegativeInt so `0` is a
|
|
144
145
|
// valid "disabled" value, not treated as invalid.
|
|
145
146
|
computeMaxQueueDepth: readNonNegativeInt(env, 'COMPUTE_MAX_QUEUE_DEPTH', 0, logger),
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@selvajs/server",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.2",
|
|
4
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",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
"!**/*.spec.*"
|
|
71
71
|
],
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@selvajs/compute": "^4.0.0-beta.
|
|
73
|
+
"@selvajs/compute": "^4.0.0-beta.1",
|
|
74
74
|
"@selvajs/platform": "^0.16.0",
|
|
75
75
|
"@selvajs/schemas": "^4.7.0"
|
|
76
76
|
},
|