@voltro/runtime 0.85.0 → 0.87.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 (184) hide show
  1. package/CHANGELOG.md +5987 -0
  2. package/README.md +43 -0
  3. package/THIRD-PARTY-NOTICES.md +864 -253
  4. package/dist/aggregate.js +42 -0
  5. package/dist/aggregateExtrema.js +80 -0
  6. package/dist/aggregateIvm.js +115 -0
  7. package/dist/analyticsMirror.js +228 -0
  8. package/dist/analyticsSink.js +32 -0
  9. package/dist/apiKeyUsage.js +33 -0
  10. package/dist/apiKeys.js +227 -0
  11. package/dist/apiKeysWiring.js +114 -0
  12. package/dist/apiRoleBucketSampler.js +64 -0
  13. package/dist/apiRoleWorkloadHistory.js +56 -0
  14. package/dist/apiRoleWorkloadMetrics.js +78 -0
  15. package/dist/apiRoleWorkloadStorage.js +95 -0
  16. package/dist/approvalBuiltins.js +10 -0
  17. package/dist/approvals.js +262 -0
  18. package/dist/authMiddlewareLayer.js +48 -0
  19. package/dist/bindEvent.js +92 -0
  20. package/dist/bootListener.js +143 -0
  21. package/dist/bootRefusal.js +7 -0
  22. package/dist/bootStoreCodec.js +71 -0
  23. package/dist/businessRules.js +67 -0
  24. package/dist/changeClaimsTable.js +12 -0
  25. package/dist/circuitBreaker.js +1 -0
  26. package/dist/columnOnUpdate.js +23 -0
  27. package/dist/composeAnalytics.js +129 -0
  28. package/dist/computedQuery.js +4 -0
  29. package/dist/computedQueryCache.js +231 -0
  30. package/dist/connectionBuiltins.js +81 -0
  31. package/dist/connectionCredentials.js +66 -0
  32. package/dist/connectionState.js +34 -0
  33. package/dist/connectionVault.js +410 -0
  34. package/dist/connectionsFacade.js +56 -0
  35. package/dist/coordinatedSchedule.js +145 -0
  36. package/dist/crdtHistory.js +138 -0
  37. package/dist/crdtMerge.js +179 -0
  38. package/dist/crdtVersionsTable.js +25 -0
  39. package/dist/credentialBound.js +12 -0
  40. package/dist/crud.js +72 -0
  41. package/dist/dataStore.js +712 -0
  42. package/dist/dataloader.js +61 -0
  43. package/dist/declaredTablesGuard.js +49 -0
  44. package/dist/defineExecutor.js +4 -0
  45. package/dist/dependencyGraph.js +32 -0
  46. package/dist/devices.js +228 -0
  47. package/dist/devicesWiring.js +168 -0
  48. package/dist/dialectReplicationAdapter.js +29 -0
  49. package/dist/dispatcher.js +522 -0
  50. package/dist/effectStore.js +71 -0
  51. package/dist/engineClients.js +24 -0
  52. package/dist/eventBus.js +260 -0
  53. package/dist/eventPublish.js +49 -0
  54. package/dist/events.js +193 -0
  55. package/dist/expectation.js +52 -0
  56. package/dist/expectationEvaluator.js +308 -0
  57. package/dist/experiment.js +96 -0
  58. package/dist/experimentEvaluator.js +245 -0
  59. package/dist/externalizedTasks.js +38 -0
  60. package/dist/fieldCipher.js +130 -0
  61. package/dist/fieldKeyRegistry.js +295 -0
  62. package/dist/fieldKeyRekey.js +286 -0
  63. package/dist/fieldKeyScan.js +136 -0
  64. package/dist/fieldKeyring.js +77 -0
  65. package/dist/fingerprint.js +21 -0
  66. package/dist/finops.js +42 -0
  67. package/dist/finopsAccountant.js +216 -0
  68. package/dist/handlerBody.js +8 -0
  69. package/dist/healthProbes.js +55 -0
  70. package/dist/hot.d.ts +56 -0
  71. package/dist/hot.js +3 -0
  72. package/dist/hotDataStore.js +148 -0
  73. package/dist/hotDataStoreSnapshot.js +98 -0
  74. package/dist/hotDataStoreTables.js +18 -0
  75. package/dist/http-range.d.ts +53 -0
  76. package/dist/http-range.js +52 -0
  77. package/dist/httpClientSsrf.js +24 -0
  78. package/dist/httpClientTracing.js +14 -0
  79. package/dist/httpCompression.js +76 -0
  80. package/dist/httpInputStream.js +82 -0
  81. package/dist/httpKeepAlive.js +12 -0
  82. package/dist/httpRouteMounts.js +48 -0
  83. package/dist/idempotencyStore.js +110 -0
  84. package/dist/idleDetector.js +21 -0
  85. package/dist/index.d.ts +1249 -517
  86. package/dist/index.js +155 -15292
  87. package/dist/insertRequiredColumns.js +19 -0
  88. package/dist/inspectWorkflow.js +1 -0
  89. package/dist/instanceMembership.js +98 -0
  90. package/dist/ivm.js +125 -0
  91. package/dist/kvDataStore.js +86 -0
  92. package/dist/kvFacade.js +38 -0
  93. package/dist/matcher.js +304 -0
  94. package/dist/memoryColumnDefaults.js +11 -0
  95. package/dist/memoryQueryJoins.js +114 -0
  96. package/dist/memorySetOperations.js +43 -0
  97. package/dist/metrics.js +175 -0
  98. package/dist/observability.js +123 -0
  99. package/dist/observedGraph.js +52 -0
  100. package/dist/originGuard.js +116 -0
  101. package/dist/outbox.js +352 -0
  102. package/dist/pluginRefRules.js +65 -0
  103. package/dist/policyGuardResolver.js +55 -0
  104. package/dist/preview.js +62 -0
  105. package/dist/projectedRows.js +12 -0
  106. package/dist/provenance.js +63 -0
  107. package/dist/rangeIndex.js +89 -0
  108. package/dist/rawReadScope.js +17 -0
  109. package/dist/reaction.js +85 -0
  110. package/dist/reactiveConfig.js +11 -0
  111. package/dist/readClassification.js +57 -0
  112. package/dist/readRecorder.js +67 -0
  113. package/dist/readScopePredicate.js +12 -0
  114. package/dist/rebac.js +104 -0
  115. package/dist/rebacInterceptor.js +81 -0
  116. package/dist/registry.js +29 -0
  117. package/dist/relevantFields.js +65 -0
  118. package/dist/replicaHealth.js +42 -0
  119. package/dist/replicaLocality.js +44 -0
  120. package/dist/replicaObservations.js +121 -0
  121. package/dist/replicaSelection.js +32 -0
  122. package/dist/replicatedDataStore.js +257 -0
  123. package/dist/requestLoader.js +7 -0
  124. package/dist/resumeCensus.js +28 -0
  125. package/dist/revalidation.js +22 -0
  126. package/dist/rowFilter.js +82 -0
  127. package/dist/rowStateBytes.js +45 -0
  128. package/dist/rpcBodyCap.js +63 -0
  129. package/dist/rpcConnections.js +83 -0
  130. package/dist/rpcDefectDiagnostics.js +15 -0
  131. package/dist/rpcServer.js +1065 -0
  132. package/dist/rpcWorkloadAdmission.js +50 -0
  133. package/dist/runAsSystem.js +23 -0
  134. package/dist/rywPositionStore.js +119 -0
  135. package/dist/schedule.js +23 -0
  136. package/dist/scheduleBackfillRequests.js +151 -0
  137. package/dist/scheduleClaimsTable.js +11 -0
  138. package/dist/scheduleRunsTable.js +37 -0
  139. package/dist/scheduler.js +840 -0
  140. package/dist/schemaRegistry.js +65 -0
  141. package/dist/secretsResolver.js +35 -0
  142. package/dist/securityHeaders.js +33 -0
  143. package/dist/servePipeline.js +374 -0
  144. package/dist/serverOnlyAudit.js +66 -0
  145. package/dist/serverTracer.js +15 -0
  146. package/dist/serviceCredentials.js +40 -0
  147. package/dist/setReadScopes.js +28 -0
  148. package/dist/singleNodeOrchestrator.js +91 -0
  149. package/dist/snapshotValueCodec.js +46 -0
  150. package/dist/sourceResolution.js +52 -0
  151. package/dist/storeMiddleware.js +882 -0
  152. package/dist/storeQuery.js +204 -0
  153. package/dist/storeRead.js +10 -0
  154. package/dist/subscriber.js +8 -0
  155. package/dist/subscriptionOutbox.js +139 -0
  156. package/dist/subscriptionRegistry.js +82 -0
  157. package/dist/subscriptionResume.js +132 -0
  158. package/dist/subscriptionSocketMetrics.js +65 -0
  159. package/dist/systemSubject.js +5 -0
  160. package/dist/tenantScope.js +11 -0
  161. package/dist/tenantSelection.js +27 -0
  162. package/dist/timeline.js +105 -0
  163. package/dist/traceContext.js +5 -0
  164. package/dist/traceSink.js +63 -0
  165. package/dist/traceSpansTable.js +29 -0
  166. package/dist/traceparent.js +23 -0
  167. package/dist/transactionSubject.js +12 -0
  168. package/dist/trustedProxy.js +155 -0
  169. package/dist/undo.js +129 -0
  170. package/dist/undoBuiltins.js +69 -0
  171. package/dist/undoCapture.js +74 -0
  172. package/dist/undoLogTable.js +16 -0
  173. package/dist/upsertBinding.js +20 -0
  174. package/dist/wakeOrchestrator.js +34 -0
  175. package/dist/wakeRegistry.js +71 -0
  176. package/dist/wakeRouter.js +63 -0
  177. package/dist/wakeSupervisor.js +62 -0
  178. package/dist/wakeupsTable.js +12 -0
  179. package/dist/webSocketGatewayRuntime.js +154 -0
  180. package/dist/webhookVerification.js +18 -0
  181. package/dist/wireColumnStrip.js +84 -0
  182. package/dist/workflowReadBuiltins.js +87 -0
  183. package/dist/workflowRuntime.js +708 -0
  184. package/package.json +19 -7
@@ -0,0 +1,52 @@
1
+ //#region src/httpRange.ts
2
+ var e = { _tag: "ignored" }, t = { _tag: "unsatisfiable" }, n = /^([!#$%&'*+.^_`|~0-9A-Za-z-]+)=(.*)$/s, r = /^(\d*)-(\d*)$/, i = (e) => {
3
+ let t = e.replace(/^0+(?=\d)/, "");
4
+ if (t.length > 16) return;
5
+ let n = Number(t);
6
+ return Number.isSafeInteger(n) ? n : void 0;
7
+ }, a = (e, t) => {
8
+ let n = e.replace(/^0+(?=\d)/, ""), r = t.replace(/^0+(?=\d)/, "");
9
+ return n.length === r.length ? n < r : n.length < r.length;
10
+ }, o = (o, s) => {
11
+ if (o === void 0) return e;
12
+ let c = n.exec(o.trim());
13
+ if (c === null || c[1].toLowerCase() !== "bytes") return e;
14
+ let l = c[2].split(",").map((e) => e.trim()).filter((e) => e !== "");
15
+ if (l.length !== 1) return e;
16
+ let u = r.exec(l[0]);
17
+ if (u === null) return e;
18
+ let [, d = "", f = ""] = u;
19
+ if (d === "") {
20
+ if (f === "") return e;
21
+ let n = i(f);
22
+ return n === 0 || s === 0 ? t : {
23
+ _tag: "satisfiable",
24
+ start: n === void 0 ? 0 : Math.max(0, s - n),
25
+ end: s - 1
26
+ };
27
+ }
28
+ if (f !== "" && a(f, d)) return e;
29
+ let p = i(d);
30
+ if (p === void 0 || p >= s) return t;
31
+ let m = f === "" ? void 0 : i(f);
32
+ return {
33
+ _tag: "satisfiable",
34
+ start: p,
35
+ end: m === void 0 ? s - 1 : Math.min(m, s - 1)
36
+ };
37
+ }, s = /^(W\/)?"[\x21\x23-\x7e\x80-\xff]*"$/, c = /^[A-Za-z]{3}/, l = (e) => {
38
+ let t = e.trim();
39
+ if (!c.test(t)) return;
40
+ let n = Date.parse(/(?:GMT|UTC)$/i.test(t) ? t : `${t} GMT`);
41
+ return Number.isNaN(n) ? void 0 : n;
42
+ }, u = (e, t, n = Date.now()) => {
43
+ if (e === void 0) return !0;
44
+ let r = e.trim();
45
+ if (r.startsWith("\"") || r.startsWith("W/")) return !s.test(r) || r.startsWith("W/") ? !1 : t.etag !== void 0 && !t.etag.startsWith("W/") && t.etag === r;
46
+ let i = l(r);
47
+ if (i === void 0 || t.lastModifiedMs === void 0) return !1;
48
+ let a = Math.floor(t.lastModifiedMs / 1e3);
49
+ return a * 1e3 === i && Math.floor(n / 1e3) > a;
50
+ };
51
+ //#endregion
52
+ export { u as ifRangeAllowsRange, o as parseByteRange, l as parseHttpDate };
@@ -0,0 +1,24 @@
1
+ import { Effect as e, Layer as t } from "effect";
2
+ import { ssrfReason as n, ssrfReason as r } from "@voltro/protocol";
3
+ import { HttpClient as i, HttpClientError as a } from "effect/http";
4
+ //#region src/httpClientSsrf.ts
5
+ var o = class extends Error {
6
+ url;
7
+ reason;
8
+ _tag = "SsrfBlockedError";
9
+ constructor(e, t) {
10
+ super(`SSRF: blocked outbound request to ${e} — ${t}. If this target is intentional, add its host to \`http.allowHosts\` in app.config.ts.`), this.url = e, this.reason = t, this.name = "SsrfBlockedError";
11
+ }
12
+ }, s = (r = {}) => t.effect(i.HttpClient, e.map(i.HttpClient, (t) => {
13
+ let s = i.transform(t, (t, i) => e.suspend(() => {
14
+ let s = n(i.url, r);
15
+ return s === null ? t : e.fail(new a.HttpClientError({ reason: new a.TransportError({
16
+ request: i,
17
+ cause: new o(i.url, s),
18
+ description: `SSRF policy: ${s}`
19
+ }) }));
20
+ }));
21
+ return i.followRedirects(s, r.maxRedirects ?? 5);
22
+ }));
23
+ //#endregion
24
+ export { o as SsrfBlockedError, s as ssrfGuardHttpClientLayer, r as ssrfReason };
@@ -0,0 +1,14 @@
1
+ import { noteCacheVolatile as e } from "./computedQueryCache.js";
2
+ import { formatTraceparent as t } from "./traceparent.js";
3
+ import { Effect as n, Layer as r } from "effect";
4
+ import { HttpClient as i, HttpClientRequest as a } from "effect/http";
5
+ //#region src/httpClientTracing.ts
6
+ var o = r.effect(i.HttpClient, n.map(i.HttpClient, (r) => r.pipe(i.mapRequestEffect((r) => n.sync(() => {
7
+ e("HttpClient");
8
+ }).pipe(n.andThen(n.currentSpan), n.map((e) => r.headers.traceparent === void 0 ? a.setHeader(r, "traceparent", t({
9
+ traceId: e.traceId,
10
+ spanId: e.spanId,
11
+ sampled: e.sampled
12
+ })) : r), n.catch(() => n.succeed(r)))))));
13
+ //#endregion
14
+ export { o as tracingHttpClientLayer };
@@ -0,0 +1,76 @@
1
+ import { brotliCompressSync as e, constants as t, gzipSync as n } from "node:zlib";
2
+ //#region src/httpCompression.ts
3
+ var r = 1024, i = [
4
+ "text/",
5
+ "application/json",
6
+ "application/javascript",
7
+ "application/xml",
8
+ "image/svg+xml",
9
+ "application/rss+xml"
10
+ ], a = (e) => {
11
+ if (e === void 0) return !1;
12
+ let t = e.split(";")[0].trim().toLowerCase();
13
+ return i.some((e) => t === e || t.startsWith(e));
14
+ }, o = (e) => {
15
+ if (e === void 0 || e === "") return;
16
+ let t = /* @__PURE__ */ new Map();
17
+ for (let n of e.split(",")) {
18
+ let [e, ...r] = n.trim().split(";");
19
+ if (e === void 0 || e === "") continue;
20
+ let i = 1;
21
+ for (let e of r) {
22
+ let [t, n] = e.trim().split("=");
23
+ t === "q" && n !== void 0 && (i = Number(n));
24
+ }
25
+ t.set(e.trim().toLowerCase(), Number.isFinite(i) ? i : 1);
26
+ }
27
+ let n = (e) => {
28
+ let n = t.get(e);
29
+ if (n !== void 0) return n > 0;
30
+ let r = t.get("*");
31
+ return r !== void 0 && r > 0;
32
+ };
33
+ if (n("br")) return "br";
34
+ if (n("gzip")) return "gzip";
35
+ }, s = (r, i) => i === "br" ? new Uint8Array(e(r, { params: {
36
+ [t.BROTLI_PARAM_QUALITY]: 4,
37
+ [t.BROTLI_PARAM_SIZE_HINT]: r.length
38
+ } })) : new Uint8Array(n(r, { level: 6 })), c = (e) => {
39
+ let t = e.options?.enabled ?? !0, n = e.options?.minBytes ?? 1024;
40
+ if (!(!t || !a(e.contentType) || e.size < n)) return o(e.acceptEncoding);
41
+ }, l = (e) => {
42
+ let t = a(e.contentType) ? { vary: "Accept-Encoding" } : {}, n = c({
43
+ ...e,
44
+ size: e.body.length
45
+ });
46
+ if (n === void 0) return {
47
+ bytes: e.body,
48
+ headers: t,
49
+ compressed: !1
50
+ };
51
+ let r = s(e.body, n);
52
+ return r.length >= e.body.length ? {
53
+ bytes: e.body,
54
+ headers: t,
55
+ compressed: !1
56
+ } : {
57
+ bytes: r,
58
+ headers: {
59
+ ...t,
60
+ "content-encoding": n
61
+ },
62
+ compressed: !0
63
+ };
64
+ }, u = (e, t) => {
65
+ let n = {}, r = [], i = (e) => {
66
+ for (let t of String(e).split(",")) {
67
+ let e = t.trim();
68
+ e !== "" && !r.some((t) => t.toLowerCase() === e.toLowerCase()) && r.push(e);
69
+ }
70
+ };
71
+ for (let [t, r] of Object.entries(e)) t.toLowerCase() === "vary" ? i(Array.isArray(r) ? r.join(",") : r) : n[t] = r;
72
+ for (let [e, r] of Object.entries(t)) e.toLowerCase() === "vary" ? i(r) : n[e] = r;
73
+ return r.length > 0 && (n.vary = r.join(", ")), n;
74
+ };
75
+ //#endregion
76
+ export { r as DEFAULT_COMPRESSION_MIN_BYTES, a as isCompressibleContentType, l as maybeCompress, u as mergeCompressionHeaders, o as negotiateEncoding, c as negotiatedCompression };
@@ -0,0 +1,82 @@
1
+ //#region src/httpInputStream.ts
2
+ var e = async (e, t, n, r, i) => {
3
+ let a = new AbortController(), o, s = !1, c = e.readableEnded, l = e.destroyed && !c, u = !1, d = 0, f = !1, p = !1, m = () => {
4
+ o?.();
5
+ }, h = () => {
6
+ l = !0, a.abort(), m();
7
+ }, g = () => {
8
+ c = !0, m();
9
+ }, _ = () => {
10
+ e.complete || h();
11
+ };
12
+ e.once("end", g), e.once("error", h), e.once("aborted", h), e.once("close", _), i.addEventListener("abort", h, { once: !0 }), (i.aborted || l) && h();
13
+ let v = { [Symbol.asyncIterator]() {
14
+ if (f) throw Error("HTTP input can only be consumed once");
15
+ return f = !0, {
16
+ async next() {
17
+ if (p) throw Error("Concurrent HTTP input reads are not supported");
18
+ p = !0;
19
+ try {
20
+ for (;;) {
21
+ if (l || a.signal.aborted) throw Error("HTTP input aborted");
22
+ if (u) throw Error("HTTP input exceeds its byte limit");
23
+ if (s) return {
24
+ done: !0,
25
+ value: void 0
26
+ };
27
+ let n = e.read();
28
+ if (n !== null) {
29
+ if (d += n.byteLength, d > t) throw u = !0, Error("HTTP input exceeds its byte limit");
30
+ return {
31
+ done: !1,
32
+ value: n
33
+ };
34
+ }
35
+ if (c) return {
36
+ done: !0,
37
+ value: void 0
38
+ };
39
+ await new Promise((t) => {
40
+ let n = () => {
41
+ e.off("readable", n), o = void 0, t();
42
+ };
43
+ o = n, e.once("readable", n);
44
+ });
45
+ }
46
+ } finally {
47
+ p = !1;
48
+ }
49
+ },
50
+ async return() {
51
+ return s = !0, m(), {
52
+ done: !0,
53
+ value: void 0
54
+ };
55
+ }
56
+ };
57
+ } }, y = () => ({
58
+ status: 413,
59
+ body: "payload too large",
60
+ contentType: "text/plain"
61
+ }), b;
62
+ try {
63
+ let e = new Promise((e, t) => {
64
+ b = () => t(/* @__PURE__ */ Error("HTTP input aborted")), a.signal.addEventListener("abort", b, { once: !0 }), a.signal.aborted && b();
65
+ }), t = await Promise.race([e, Promise.resolve().then(() => {
66
+ if (a.signal.aborted) throw Error("HTTP input aborted");
67
+ return r({
68
+ ...n,
69
+ body: v,
70
+ signal: a.signal
71
+ });
72
+ })]);
73
+ return u ? y() : t;
74
+ } catch (e) {
75
+ if (u) return y();
76
+ throw e;
77
+ } finally {
78
+ s = !0, b !== void 0 && a.signal.removeEventListener("abort", b), a.abort(), m(), e.off("end", g), e.off("error", h), e.off("aborted", h), e.off("close", _), i.removeEventListener("abort", h), !e.destroyed && !e.readableEnded && e.resume();
79
+ }
80
+ };
81
+ //#endregion
82
+ export { e as dispatchHttpInputStream };
@@ -0,0 +1,12 @@
1
+ //#region src/httpKeepAlive.ts
2
+ var e = 72e3, t = 5e3, n = (e) => typeof e == "number" && Number.isFinite(e) && e > 0 ? Math.floor(e) : void 0, r = (e) => {
3
+ let r = n(e?.http?.keepAliveTimeoutMs) ?? 72e3, i = n(e?.http?.headersTimeoutMs);
4
+ return {
5
+ keepAliveTimeoutMs: r,
6
+ headersTimeoutMs: i !== void 0 && i > r ? i : r + t
7
+ };
8
+ }, i = (e, t) => {
9
+ e.keepAliveTimeout = t.keepAliveTimeoutMs, e.headersTimeout = t.headersTimeoutMs;
10
+ };
11
+ //#endregion
12
+ export { e as DEFAULT_KEEP_ALIVE_MS, t as HEADERS_TIMEOUT_MARGIN_MS, i as applyKeepAlive, r as resolveKeepAlive };
@@ -0,0 +1,48 @@
1
+ import { FindMyWay as e } from "effect/http";
2
+ import { routeAcceptsPath as t } from "@voltro/protocol/rest";
3
+ //#region src/httpRouteMounts.ts
4
+ var n = (e) => e.split("/").map((e) => e.startsWith(":") ? ":param" : e).join("/"), r = (e) => {
5
+ if (e.some((e) => e.method === "*")) return ["*"];
6
+ let t = /* @__PURE__ */ new Set();
7
+ for (let n of e) t.add(n.method === "HEAD" ? "GET" : n.method);
8
+ return [...t];
9
+ }, i = (e) => {
10
+ let t = /* @__PURE__ */ new Map();
11
+ for (let r of e) {
12
+ let e = n(r.path), i = t.get(e);
13
+ i ? i.push(r) : t.set(e, [r]);
14
+ }
15
+ let i = [];
16
+ t.forEach((e, t) => {
17
+ if (e.some((e) => e.handleStream !== void 0) && (e.length !== 1 || e[0].match !== "exact" || e[0].path.endsWith("/*"))) throw Error("A streamed HTTP input requires an exclusive exact route path");
18
+ i.push({
19
+ mountPath: t,
20
+ routes: e,
21
+ methods: r(e)
22
+ });
23
+ });
24
+ let a = /* @__PURE__ */ new Set();
25
+ for (let e of i) e.methods.includes("*") && e.routes.some((e) => e.method === "*" && e.match !== "exact") && a.add(e.mountPath);
26
+ let o = (e) => {
27
+ if (e !== "/" && a.has("/")) return !0;
28
+ for (let t = e.indexOf("/"); t !== -1; t = e.indexOf("/", t + 1)) if (a.has(e.slice(0, t))) return !0;
29
+ return !1;
30
+ };
31
+ for (let e = 0; e < i.length; e++) {
32
+ let t = i[e];
33
+ !t.methods.includes("*") && o(t.mountPath) && (i[e] = {
34
+ ...t,
35
+ methods: ["*"]
36
+ });
37
+ }
38
+ return i;
39
+ }, a = (n) => {
40
+ let r = e.make(), i = /* @__PURE__ */ new Set();
41
+ for (let e of n) for (let t of [e.mountPath, `${e.mountPath}/*`]) i.has(t.toLowerCase()) || (i.add(t.toLowerCase()), r.on("GET", t, e));
42
+ return (e) => {
43
+ let n = r.find("GET", e)?.handler;
44
+ return n !== void 0 && n.routes.some((n) => t(n, e)) ? n : void 0;
45
+ };
46
+ }, o = (e) => a(e.filter((e) => !e.methods.includes("*") && (e.routes.length > 1 || e.routes[0]?.answersOtherMethods === !0)));
47
+ //#endregion
48
+ export { a as makeHttpRouteGroupFinder, o as makeUnmatchedGroupFinder, i as planHttpRouteMounts };
@@ -0,0 +1,110 @@
1
+ import { and as e, eq as t, generateId as n, lte as r } from "@voltro/database";
2
+ import { freshFor as i } from "@voltro/protocol";
3
+ //#region src/idempotencyStore.ts
4
+ var a = "_voltro_idempotency", o = () => /* @__PURE__ */ Error("Stored idempotency receipt is invalid"), s = (e) => {
5
+ if (e === null) return null;
6
+ try {
7
+ let t = typeof e == "string" ? JSON.parse(e) : e;
8
+ if (t === null) return null;
9
+ if (typeof t != "object") throw o();
10
+ let n = Object.getPrototypeOf(t);
11
+ if (n !== Object.prototype && n !== null) throw o();
12
+ let r = Object.getOwnPropertyDescriptor(t, "status"), i = r && "value" in r ? r.value : void 0;
13
+ if (typeof i != "number" || !Number.isInteger(i) || i < 100 || i > 999) throw o();
14
+ let a = Object.getOwnPropertyDescriptor(t, "body");
15
+ if (a && !("value" in a)) throw o();
16
+ let s = a?.value, c = Object.getOwnPropertyDescriptor(t, "rest");
17
+ if (c && !("value" in c)) throw o();
18
+ return {
19
+ status: i,
20
+ body: s,
21
+ ...c ? { rest: c.value } : {}
22
+ };
23
+ } catch {
24
+ throw o();
25
+ }
26
+ }, c = (e) => {
27
+ try {
28
+ let t = e instanceof Date ? Date.prototype.getTime.call(e) : typeof e == "number" || typeof e == "string" ? new Date(e).getTime() : NaN;
29
+ if (!Number.isFinite(t) || typeof e == "number" && t !== e) throw o();
30
+ return t;
31
+ } catch {
32
+ throw o();
33
+ }
34
+ }, l = (e) => {
35
+ if (typeof e.id != "string" || e.id.length === 0 || typeof e.scope != "string" || typeof e.key != "string" || e.status !== "in_flight" && e.status !== "completed" || e.inputHash != null && (typeof e.inputHash != "string" || !/^[0-9a-f]{64}$/.test(e.inputHash))) throw o();
36
+ let t = c(e.createdAt), n = s(e.response);
37
+ if (e.status === "in_flight" != (n === null)) throw o();
38
+ return {
39
+ scope: e.scope,
40
+ key: e.key,
41
+ inputHash: e.inputHash ?? null,
42
+ status: e.status,
43
+ response: n,
44
+ createdAt: t
45
+ };
46
+ }, u = async (n, r, i) => (await n.query({
47
+ table: a,
48
+ predicate: e(t("scope", r), t("key", i)),
49
+ order: [],
50
+ take: 1,
51
+ skip: void 0,
52
+ projection: void 0
53
+ }))[0] ?? null, d = (n) => e(t("id", n.id), t("scope", n.scope), t("key", n.key), t("inputHash", n.inputHash), t("status", "in_flight")), f = (o) => ({
54
+ get: async (e, t) => {
55
+ let n = await u(o, e, t);
56
+ return n ? l(n) : null;
57
+ },
58
+ claim: async (s, c, d, f, p, m) => {
59
+ for (let u = 0; u < 2; u++) {
60
+ let u = n({
61
+ kind: "typeid",
62
+ prefix: "idem"
63
+ }, a), h = await o.insertIgnore(a, {
64
+ id: u,
65
+ scope: s,
66
+ key: c,
67
+ inputHash: d,
68
+ status: "in_flight",
69
+ response: null,
70
+ createdAt: new Date(f)
71
+ }, { conflictColumns: ["scope", "key"] }), g = l(h);
72
+ if (h.id === u) {
73
+ if (g.scope !== s || g.key !== c || g.inputHash !== d || g.status !== "in_flight" || g.response !== null) throw Error("Idempotency acquisition did not retain the expected input witness");
74
+ return {
75
+ kind: "claimed",
76
+ claim: Object.freeze({
77
+ scope: s,
78
+ key: c,
79
+ id: u,
80
+ inputHash: d
81
+ })
82
+ };
83
+ }
84
+ if (g.inputHash !== d) return {
85
+ kind: "existing",
86
+ record: g
87
+ };
88
+ let _ = i(g.status, p, m);
89
+ if (f - g.createdAt < _) return {
90
+ kind: "existing",
91
+ record: g
92
+ };
93
+ await o.deleteMany(a, { where: e(t("id", h.id), t("scope", s), t("key", c), t("inputHash", d), t("status", h.status), r("createdAt", new Date(f - _))) });
94
+ }
95
+ let h = await u(o, s, c);
96
+ return h ? {
97
+ kind: "existing",
98
+ record: l(h)
99
+ } : { kind: "conflict" };
100
+ },
101
+ complete: async (e, t, n) => await o.updateMany(a, {
102
+ status: "completed",
103
+ response: t,
104
+ createdAt: new Date(n)
105
+ }, { where: d(e) }) === 1,
106
+ renew: async (e, t) => await o.updateMany(a, { createdAt: new Date(t) }, { where: d(e) }) === 1,
107
+ release: async (e) => await o.deleteMany(a, { where: d(e) }) === 1
108
+ });
109
+ //#endregion
110
+ export { f as dataStoreIdempotencyStore };
@@ -0,0 +1,21 @@
1
+ import { nextWakeup as e } from "./wakeRegistry.js";
2
+ //#region src/idleDetector.ts
3
+ var t = async (t) => {
4
+ if (t.signals.connectedClients() > 0 || t.signals.inFlightRequests() > 0 || t.signals.activeWorkflowExecutions() > 0) return !1;
5
+ let n = (t.now?.() ?? /* @__PURE__ */ new Date()).getTime() + (t.wakeLookaheadMs ?? 3e4), r = await e(t.store);
6
+ return !(r !== null && r.wakeAt.getTime() <= n);
7
+ }, n = (e, t = Date.now) => {
8
+ let n;
9
+ return {
10
+ update: (r) => {
11
+ if (!r) return n = void 0, !1;
12
+ let i = t();
13
+ return n === void 0 && (n = i), i - n >= e;
14
+ },
15
+ reset: () => {
16
+ n = void 0;
17
+ }
18
+ };
19
+ };
20
+ //#endregion
21
+ export { t as isIdleNow, n as makeIdleGate };