@voltro/runtime 0.87.0 → 0.89.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 (179) hide show
  1. package/CHANGELOG.md +272 -6
  2. package/THIRD-PARTY-NOTICES.md +644 -48
  3. package/dist/aggregate.js +1 -2
  4. package/dist/aggregateExtrema.js +1 -2
  5. package/dist/aggregateIvm.js +1 -2
  6. package/dist/analyticsMirror.js +1 -2
  7. package/dist/analyticsSink.js +1 -2
  8. package/dist/apiKeyUsage.js +1 -2
  9. package/dist/apiKeys.js +1 -2
  10. package/dist/apiKeysWiring.js +1 -2
  11. package/dist/apiRoleBucketSampler.js +1 -2
  12. package/dist/apiRoleWorkloadHistory.js +1 -2
  13. package/dist/apiRoleWorkloadMetrics.js +1 -2
  14. package/dist/apiRoleWorkloadStorage.js +1 -2
  15. package/dist/approvalBuiltins.js +1 -2
  16. package/dist/approvals.js +1 -2
  17. package/dist/authMiddlewareLayer.js +1 -2
  18. package/dist/bindEvent.js +1 -2
  19. package/dist/boot-refusal.d.ts +10 -0
  20. package/dist/{bootRefusal.js → boot-refusal.js} +1 -2
  21. package/dist/bootListener.js +154 -65
  22. package/dist/bootStoreCodec.js +1 -2
  23. package/dist/businessRules.js +1 -2
  24. package/dist/changeClaimsTable.js +1 -2
  25. package/dist/columnOnUpdate.js +1 -2
  26. package/dist/composeAnalytics.js +1 -2
  27. package/dist/computedQuery.js +1 -2
  28. package/dist/computedQueryCache.js +136 -78
  29. package/dist/connectionBuiltins.js +1 -2
  30. package/dist/connectionCredentials.js +1 -2
  31. package/dist/connectionState.js +1 -2
  32. package/dist/connectionVault.js +1 -2
  33. package/dist/connectionsFacade.js +1 -2
  34. package/dist/coordinatedSchedule.js +1 -2
  35. package/dist/crdtHistory.js +1 -2
  36. package/dist/crdtMerge.js +1 -2
  37. package/dist/crdtVersionsTable.js +1 -2
  38. package/dist/credentialBound.js +1 -2
  39. package/dist/crud.js +1 -2
  40. package/dist/dataStore.js +1 -2
  41. package/dist/dataloader.js +1 -2
  42. package/dist/declaredTablesGuard.js +1 -2
  43. package/dist/defineExecutor.js +1 -2
  44. package/dist/dependencyGraph.js +1 -2
  45. package/dist/devices.js +1 -2
  46. package/dist/devicesWiring.js +1 -2
  47. package/dist/dialectReplicationAdapter.js +1 -2
  48. package/dist/dispatcher.js +1 -2
  49. package/dist/effectStore.js +1 -2
  50. package/dist/engineClients.js +1 -2
  51. package/dist/eventBus.js +1 -2
  52. package/dist/eventPublish.js +1 -2
  53. package/dist/events.js +1 -2
  54. package/dist/expectation.js +1 -2
  55. package/dist/expectationEvaluator.js +2 -3
  56. package/dist/experiment.js +1 -2
  57. package/dist/experimentEvaluator.js +1 -2
  58. package/dist/externalizedTasks.js +1 -2
  59. package/dist/fieldCipher.js +1 -2
  60. package/dist/fieldKeyRegistry.js +1 -2
  61. package/dist/fieldKeyRekey.js +1 -2
  62. package/dist/fieldKeyScan.js +1 -2
  63. package/dist/fieldKeyring.js +1 -2
  64. package/dist/fingerprint.js +1 -2
  65. package/dist/finops.js +1 -2
  66. package/dist/finopsAccountant.js +1 -2
  67. package/dist/handlerBody.js +1 -2
  68. package/dist/healthProbes.js +1 -2
  69. package/dist/hotDataStore.js +1 -2
  70. package/dist/hotDataStoreSnapshot.js +1 -2
  71. package/dist/hotDataStoreTables.js +1 -2
  72. package/dist/http-range.js +1 -2
  73. package/dist/httpClientSsrf.js +1 -2
  74. package/dist/httpClientTracing.js +1 -2
  75. package/dist/httpCompression.js +1 -2
  76. package/dist/httpInputStream.js +1 -2
  77. package/dist/httpKeepAlive.js +1 -2
  78. package/dist/httpRouteMounts.js +1 -2
  79. package/dist/idempotencyStore.js +1 -2
  80. package/dist/idleDetector.js +1 -2
  81. package/dist/index.d.ts +22 -2
  82. package/dist/index.js +109 -110
  83. package/dist/insertRequiredColumns.js +1 -2
  84. package/dist/instanceMembership.js +1 -2
  85. package/dist/ivm.js +1 -2
  86. package/dist/kvDataStore.js +1 -2
  87. package/dist/kvFacade.js +1 -2
  88. package/dist/matcher.js +1 -2
  89. package/dist/memoryColumnDefaults.js +1 -2
  90. package/dist/memoryQueryJoins.js +1 -2
  91. package/dist/memorySetOperations.js +1 -2
  92. package/dist/metrics.js +1 -2
  93. package/dist/observability.js +2 -3
  94. package/dist/observedGraph.js +1 -2
  95. package/dist/originGuard.js +1 -2
  96. package/dist/outbox.js +1 -2
  97. package/dist/pluginRefRules.js +1 -2
  98. package/dist/policyGuardResolver.js +1 -2
  99. package/dist/preview.js +1 -2
  100. package/dist/projectedRows.js +1 -2
  101. package/dist/provenance.js +1 -2
  102. package/dist/rangeIndex.js +1 -2
  103. package/dist/rawReadScope.js +2 -3
  104. package/dist/reaction.js +1 -2
  105. package/dist/reactiveConfig.js +1 -2
  106. package/dist/readClassification.js +1 -2
  107. package/dist/readRecorder.js +1 -2
  108. package/dist/readScopePredicate.js +1 -2
  109. package/dist/rebac.js +1 -2
  110. package/dist/rebacInterceptor.js +1 -2
  111. package/dist/registry.js +1 -2
  112. package/dist/relevantFields.js +1 -2
  113. package/dist/replicaHealth.js +1 -2
  114. package/dist/replicaLocality.js +1 -2
  115. package/dist/replicaObservations.js +1 -2
  116. package/dist/replicaSelection.js +1 -2
  117. package/dist/replicatedDataStore.js +1 -2
  118. package/dist/requestLoader.js +1 -2
  119. package/dist/resumeCensus.js +1 -2
  120. package/dist/revalidation.js +1 -2
  121. package/dist/rowFilter.js +1 -2
  122. package/dist/rowStateBytes.js +1 -2
  123. package/dist/rpcBodyCap.js +1 -2
  124. package/dist/rpcConnections.js +1 -2
  125. package/dist/rpcDefectDiagnostics.js +1 -2
  126. package/dist/rpcServer.js +1 -2
  127. package/dist/rpcWorkloadAdmission.js +1 -2
  128. package/dist/runAsSystem.js +1 -2
  129. package/dist/rywPositionStore.js +1 -2
  130. package/dist/schedule.js +1 -2
  131. package/dist/scheduleBackfillRequests.js +1 -2
  132. package/dist/scheduleClaimsTable.js +1 -2
  133. package/dist/scheduleRunsTable.js +1 -2
  134. package/dist/scheduler.js +4 -4
  135. package/dist/schemaRegistry.js +1 -2
  136. package/dist/secretsResolver.js +1 -2
  137. package/dist/securityHeaders.js +1 -2
  138. package/dist/servePipeline.js +198 -183
  139. package/dist/serverOnlyAudit.js +1 -2
  140. package/dist/serverTracer.js +1 -2
  141. package/dist/serviceCredentials.js +1 -2
  142. package/dist/setReadScopes.js +1 -2
  143. package/dist/singleNodeOrchestrator.js +1 -2
  144. package/dist/snapshotValueCodec.js +1 -2
  145. package/dist/sourceResolution.js +1 -2
  146. package/dist/storeMiddleware.js +3 -4
  147. package/dist/storeQuery.js +1 -2
  148. package/dist/storeRead.js +1 -2
  149. package/dist/subscriber.js +1 -2
  150. package/dist/subscriptionOutbox.js +1 -2
  151. package/dist/subscriptionRegistry.js +1 -2
  152. package/dist/subscriptionResume.js +1 -2
  153. package/dist/subscriptionSocketMetrics.js +1 -2
  154. package/dist/systemSubject.js +1 -2
  155. package/dist/tenantScope.js +1 -2
  156. package/dist/tenantSelection.js +1 -2
  157. package/dist/timeline.js +1 -2
  158. package/dist/traceContext.js +1 -2
  159. package/dist/traceSink.js +1 -2
  160. package/dist/traceSpansTable.js +1 -2
  161. package/dist/traceparent.js +1 -2
  162. package/dist/transactionSubject.js +1 -2
  163. package/dist/trustedProxy.js +2 -3
  164. package/dist/undo.js +1 -2
  165. package/dist/undoBuiltins.js +1 -2
  166. package/dist/undoCapture.js +1 -2
  167. package/dist/undoLogTable.js +1 -2
  168. package/dist/upsertBinding.js +1 -2
  169. package/dist/wakeOrchestrator.js +1 -2
  170. package/dist/wakeRegistry.js +1 -2
  171. package/dist/wakeRouter.js +1 -2
  172. package/dist/wakeSupervisor.js +1 -2
  173. package/dist/wakeupsTable.js +1 -2
  174. package/dist/webSocketGatewayRuntime.js +1 -2
  175. package/dist/webhookVerification.js +1 -2
  176. package/dist/wireColumnStrip.js +1 -2
  177. package/dist/workflowReadBuiltins.js +1 -2
  178. package/dist/workflowRuntime.js +1 -2
  179. package/package.json +26 -19
package/dist/aggregate.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { classifyShape as e } from "./ivm.js";
2
2
  import { Context as t, Effect as n, Schema as r } from "effect";
3
- //#region src/aggregate.ts
3
+ // src/aggregate.ts
4
4
  var i = (t) => {
5
5
  let n = typeof t.refresh == "string" ? { interval: t.refresh } : t.refresh, r = t.strategy ?? "replace";
6
6
  if (r === "merge" && (t.mergeKey === void 0 || t.mergeKey.length === 0)) throw Error(`defineAggregate("${t.name}"): strategy: 'merge' requires mergeKey — the property on each row to upsert by`);
@@ -38,5 +38,4 @@ var i = (t) => {
38
38
  }) {}, l = class extends t.Service()("@voltro/AggregateRegistry") {}, u = (e) => n.gen(function* () {
39
39
  return (yield* l).getHandle(e);
40
40
  });
41
- //#endregion
42
41
  export { c as AggregateError, s as AggregateNotFound, l as AggregateRegistry, o as AggregateStale, i as defineAggregate, a as isAggregateDefinition, u as useAggregate };
@@ -1,6 +1,6 @@
1
1
  import { RangeIndex as e } from "./rangeIndex.js";
2
2
  import { groupKeyOf as t } from "./ivm.js";
3
- //#region src/aggregateExtrema.ts
3
+ // src/aggregateExtrema.ts
4
4
  var n = Symbol("unavailable"), r = (e, r) => {
5
5
  let i = Object.getPrototypeOf(r);
6
6
  if (i !== Object.prototype && i !== null) return;
@@ -76,5 +76,4 @@ var n = Symbol("unavailable"), r = (e, r) => {
76
76
  return this.groups.get(e)?.numericExtreme(this.shape.op);
77
77
  }
78
78
  };
79
- //#endregion
80
79
  export { i as AggregateExtrema };
@@ -1,6 +1,6 @@
1
1
  import { applyDeltaInto as e, buildIvmState as t, groupKeyOf as n, ivmValue as r, materializeIvm as i, resolveRescanInto as a } from "./ivm.js";
2
2
  import { AggregateExtrema as o } from "./aggregateExtrema.js";
3
- //#region src/aggregateIvm.ts
3
+ // src/aggregateIvm.ts
4
4
  var s = class {
5
5
  shape;
6
6
  state = /* @__PURE__ */ new Map();
@@ -111,5 +111,4 @@ var s = class {
111
111
  return n;
112
112
  }
113
113
  };
114
- //#endregion
115
114
  export { s as AggregateMaintainer };
@@ -1,6 +1,6 @@
1
1
  import { Cause as e, Duration as t, Effect as n, Metric as r, Schedule as i } from "effect";
2
2
  import { eq as a } from "@voltro/database";
3
- //#region src/analyticsMirror.ts
3
+ // src/analyticsMirror.ts
4
4
  var o = r.counter("voltro_analytics_mirror_forwarded_total", { description: "Reactive-table changes successfully applied to the analytics mirror." }), s = r.counter("voltro_analytics_mirror_retries_total", { description: "Analytics-mirror write attempts that failed (each is retried until the budget runs out)." }), c = r.counter("voltro_analytics_mirror_repair_queued_total", { description: "Analytics-mirror changes whose retries were exhausted and were queued for repair." }), l = r.counter("voltro_analytics_mirror_dropped_total", { description: "Analytics-mirror changes provably lost (repair queue overflow)." }), u = (e) => {
5
5
  n.runSync(r.update(e, 1));
6
6
  }, d = (t) => e.pretty(t), f = {
@@ -224,5 +224,4 @@ var o = r.counter("voltro_analytics_mirror_forwarded_total", { description: "Rea
224
224
  })
225
225
  };
226
226
  };
227
- //#endregion
228
227
  export { f as DEFAULT_ANALYTICS_MIRROR_TUNABLES, _ as attachAnalyticsMirror };
@@ -1,7 +1,7 @@
1
1
  import { Context as e, Effect as t, Option as n } from "effect";
2
2
  import { SubjectService as r } from "@voltro/protocol";
3
3
  import { AnalyticsCapabilityNotSupported as i, AnalyticsError as a } from "@voltro/kv/analytics";
4
- //#region src/analyticsSink.ts
4
+ // src/analyticsSink.ts
5
5
  var o = class extends e.Service()("@voltro/AnalyticsSink") {}, s = (e, t) => ({
6
6
  info: e.info,
7
7
  track: (n) => e.track(n.tenantId === void 0 ? {
@@ -28,5 +28,4 @@ var o = class extends e.Service()("@voltro/AnalyticsSink") {}, s = (e, t) => ({
28
28
  });
29
29
  return a === null ? e : s(e, a);
30
30
  });
31
- //#endregion
32
31
  export { i as AnalyticsCapabilityNotSupported, a as AnalyticsError, o as AnalyticsSink, c as useAnalytics };
@@ -1,4 +1,4 @@
1
- //#region src/apiKeyUsage.ts
1
+ // src/apiKeyUsage.ts
2
2
  var e = (e) => {
3
3
  let t = e.now ?? Date.now, n = e.intervalMs ?? 3e4, r = e.maxPending ?? 500, i = /* @__PURE__ */ new Map(), a = !1, o = async () => {
4
4
  if (i.size === 0) return;
@@ -29,5 +29,4 @@ var e = (e) => {
29
29
  pending: () => i.size
30
30
  };
31
31
  };
32
- //#endregion
33
32
  export { e as makeApiKeyUsageBuffer };
package/dist/apiKeys.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { and as e, eq as t, generateId as n, inSet as r } from "@voltro/database";
2
2
  import { createHash as i, randomBytes as a } from "node:crypto";
3
- //#region src/apiKeys.ts
3
+ // src/apiKeys.ts
4
4
  var o = "_voltro_api_keys", s = "actors", c = (e) => i("sha256").update(e, "utf8").digest("hex"), l = (e = "voltro_") => `${e}${a(30).toString("base64url")}`, u = (e) => ({
5
5
  id: e.id,
6
6
  name: e.name,
@@ -223,5 +223,4 @@ var o = "_voltro_api_keys", s = "actors", c = (e) => i("sha256").update(e, "utf8
223
223
  }
224
224
  };
225
225
  };
226
- //#endregion
227
226
  export { s as ACTORS_TABLE, o as API_KEYS_TABLE, b as dataStoreApiKeyStore, l as generateApiKeyToken, _ as lockApiKeyById, f as makeApiKeyService, y as makeApiKeyUsageFlusher, p as memoryApiKeyStore, v as plantMissingApiKeyActors, c as sha256Hex };
@@ -2,7 +2,7 @@ import { Schema as e } from "effect";
2
2
  import { ADMIN_SCOPE as t, APIKEY_ISSUE_ORG_SCOPE as n, APIKEY_ISSUE_OTHER_SCOPE as r, APIKEY_ISSUE_SELF_SCOPE as i, ScopeError as a } from "@voltro/protocol";
3
3
  import { defineRestRoute as o, requireAnyScope as s, requireScope as c } from "@voltro/protocol/rest";
4
4
  import { apiKeyStrategy as l } from "@voltro/protocol/apikey";
5
- //#region src/apiKeysWiring.ts
5
+ // src/apiKeysWiring.ts
6
6
  var u = (e, t = {}) => l({
7
7
  id: "voltro-apikey",
8
8
  ...t.prefix ? { prefix: t.prefix } : {},
@@ -110,5 +110,4 @@ var u = (e, t = {}) => l({
110
110
  })
111
111
  ];
112
112
  };
113
- //#endregion
114
113
  export { f as apiKeyManagementRoutes, u as frameworkApiKeyStrategy };
@@ -1,6 +1,6 @@
1
1
  import { API_ROLE_BUCKET_MS as e } from "./apiRoleWorkloadHistory.js";
2
2
  import { API_WORKLOADS as t } from "@voltro/protocol";
3
- //#region src/apiRoleBucketSampler.ts
3
+ // src/apiRoleBucketSampler.ts
4
4
  var n = (n) => {
5
5
  let r = [...new Set(n.workloads)];
6
6
  if (!n.replicaId || n.replicaId.length > 191 || !n.role || n.role.length > 2080 || n.startedAt < 0 || n.epochNow < 0 || n.monotonicNow < 0 || !r.length || r.some((e) => !t.includes(e)) || !Number.isFinite(n.monotonicNow) || !Number.isSafeInteger(n.epochNow) || !Number.isSafeInteger(n.startedAt) || n.startedAt > n.epochNow) throw Error("Invalid role sampler configuration");
@@ -60,5 +60,4 @@ var n = (n) => {
60
60
  })
61
61
  };
62
62
  };
63
- //#endregion
64
63
  export { n as makeApiRoleBucketSampler };
@@ -1,5 +1,5 @@
1
1
  import { API_WORKLOADS as e } from "@voltro/protocol";
2
- //#region src/apiRoleWorkloadHistory.ts
2
+ // src/apiRoleWorkloadHistory.ts
3
3
  var t = 3e5, n = 864e5, r = (r) => {
4
4
  if (!Number.isSafeInteger(r.startedAt) || r.startedAt < 0 || r.startedAt > r.now || !r.replicaId || !r.role || !Number.isSafeInteger(r.now) || r.now < 864e5) throw Error("Invalid role observation time");
5
5
  let i = Math.floor(r.now / t) * t, a = i - n, o = n / t, s = [...new Set(r.requiredWorkloads)];
@@ -52,5 +52,4 @@ var t = 3e5, n = 864e5, r = (r) => {
52
52
  splitCandidates: h.length >= 2 ? h : []
53
53
  };
54
54
  };
55
- //#endregion
56
55
  export { t as API_ROLE_BUCKET_MS, n as API_ROLE_WINDOW_MS, r as assessApiRoleWorkloadWindow };
@@ -1,6 +1,6 @@
1
1
  import { Effect as e, Metric as t, Tracer as n } from "effect";
2
2
  import { API_WORKLOADS as r } from "@voltro/protocol";
3
- //#region src/apiRoleWorkloadMetrics.ts
3
+ // src/apiRoleWorkloadMetrics.ts
4
4
  var i = t.counter("api_role_workload_seconds_total", { description: "Measured active synchronous loop seconds by selected API role set and workload; excludes asynchronous waits." }), a = (e) => {
5
5
  if (e.length === 0 || e.length > 32 || e.some((e) => !/^[a-z][a-z0-9-]{0,63}$/.test(e))) throw Error("Invalid API metric roles");
6
6
  return [...new Set(e)].sort().join(",");
@@ -74,5 +74,4 @@ var i = t.counter("api_role_workload_seconds_total", { description: "Measured ac
74
74
  }
75
75
  };
76
76
  }, s = (e, t, n) => t.observeEffect(e, n);
77
- //#endregion
78
77
  export { a as apiRoleMetricLabel, o as makeApiRoleWorkloadMetrics, s as observeApiRoleEffect };
@@ -1,5 +1,5 @@
1
1
  import { API_ROLE_BUCKET_MS as e, API_ROLE_WINDOW_MS as t, assessApiRoleWorkloadWindow as n } from "./apiRoleWorkloadHistory.js";
2
- //#region src/apiRoleWorkloadStorage.ts
2
+ // src/apiRoleWorkloadStorage.ts
3
3
  var r = "_voltro_api_role_workload_buckets", i = 16384, a = (e) => e instanceof Date ? e.getTime() : typeof e == "number" ? e : NaN, o = async (e, t) => {
4
4
  let a = Object.keys(t.workloads);
5
5
  if (n({
@@ -91,5 +91,4 @@ var r = "_voltro_api_role_workload_buckets", i = 16384, a = (e) => e instanceof
91
91
  assessment: u
92
92
  };
93
93
  };
94
- //#endregion
95
94
  export { r as API_ROLE_WORKLOAD_BUCKETS_TABLE, s as readApiRoleWorkloadWindow, o as writeApiRoleWorkloadBucket };
@@ -1,10 +1,9 @@
1
1
  import { decideApproval as e, pendingApprovalsFor as t } from "./approvals.js";
2
- //#region src/approvalBuiltins.ts
2
+ // src/approvalBuiltins.ts
3
3
  var n = (e) => e.request?.subject ?? null, r = async (e, r) => t(r.store, n(r), { limit: e.limit ?? 50 }), i = async (t, r) => e(r.store, {
4
4
  approvalId: t.approvalId,
5
5
  decision: t.decision,
6
6
  approver: n(r),
7
7
  ...t.note === void 0 ? {} : { note: t.note }
8
8
  });
9
- //#endregion
10
9
  export { r as approvalsPendingExecutor, i as decideApprovalInvocation };
package/dist/approvals.js CHANGED
@@ -2,7 +2,7 @@ import { Effect as e } from "effect";
2
2
  import { and as t, eq as n, generateId as r, id as i, inSet as a, registerRetention as o, retentionTtlMsFromEnv as s, table as c, text as l, timestamp as u } from "@voltro/database";
3
3
  import { createHash as d, randomUUID as f } from "node:crypto";
4
4
  import { ApprovalExpired as p, ApprovalForbidden as m, ApprovalNotFound as h, ApprovalNotPending as g, ApprovalRejected as _, ApprovalRequired as v, ApprovalSelfApproval as y, ApprovalUnavailable as b, canonicalJson as x, checkGuardsEffect as S, isAuthenticatedGuard as C, isPolicyGuard as w, isUpgradedGuard as T, resolvePolicyAction as E, upgradedGuardShapeError as D } from "@voltro/protocol";
5
- //#region src/approvals.ts
5
+ // src/approvals.ts
6
6
  var O = "_voltro_approvals", k = 864e5, A = c(O, {
7
7
  id: i({ prefix: "apv" }),
8
8
  intentKey: l().maxLength(191),
@@ -258,5 +258,4 @@ var O = "_voltro_approvals", k = 864e5, A = c(O, {
258
258
  }
259
259
  return c.sort((e, t) => t.requestedAt.localeCompare(e.requestedAt)).slice(0, r?.limit ?? 50);
260
260
  }, Z = () => f();
261
- //#endregion
262
261
  export { O as APPROVALS_TABLE, k as DEFAULT_APPROVAL_EXPIRY_MS, A as _voltroApprovalsTable, F as approvalIntentKey, Z as approvalNonce, x as canonicalJson, q as clearApprovalGate, Y as decideApproval, J as enforceApproval, K as getApprovalGate, G as installApprovalGate, U as makeApprovalGate, H as parseApprovalInterval, X as pendingApprovalsFor, N as rehydrateGuards, P as scopeStringsOf, M as serializeGuards };
@@ -3,7 +3,7 @@ import { Context as r, Effect as i, Layer as a, Option as o, Schema as s } from
3
3
  import { AuthMiddleware as c, ConnectionInfo as l, ConnectionInfoMiddleware as u, RequestedTenantRefused as d, SubjectService as f, Unauthenticated as p } from "@voltro/protocol";
4
4
  import { Rpc as m } from "effect/rpc";
5
5
  import { sessionExpiryFromHeaders as h } from "@voltro/protocol/session";
6
- //#region src/authMiddlewareLayer.ts
6
+ // src/authMiddlewareLayer.ts
7
7
  var g = class extends r.Service()("@voltro/runtime/VerifiedCredentialLifetime") {}, _ = (e) => {
8
8
  for (let t of e.requests.values()) if (m.isRpc(t) && [...t.middlewares].some((e) => e.key === c.key || e.key === u.key)) throw Error("withRpcAuthMiddleware requires a group without AuthMiddleware or ConnectionInfoMiddleware; apply the shared pair once");
9
9
  return e.middleware(u).middleware(c);
@@ -44,5 +44,4 @@ var g = class extends r.Service()("@voltro/runtime/VerifiedCredentialLifetime")
44
44
  };
45
45
  }).pipe(i.flatMap((e) => i.provideService(n, l, e))))));
46
46
  }, y = (e) => a.succeed(u, u.of((t, { headers: n, client: r }) => i.sync(() => (e(n, r.id), { clientId: r.id })).pipe(i.flatMap((e) => i.provideService(t, l, e)))));
47
- //#endregion
48
47
  export { v as makeAuthMiddlewareLayers, y as observeConnectionHeaders, _ as withRpcAuthMiddleware };
package/dist/bindEvent.js CHANGED
@@ -3,7 +3,7 @@ import { registerConnectionStream as n } from "./connectionCredentials.js";
3
3
  import { boundByCredential as r } from "./credentialBound.js";
4
4
  import { Effect as i, Queue as a, Stream as o } from "effect";
5
5
  import { ConnectionInfo as s, ScopeError as c, SubjectService as l, checkGuardsEffect as u, isOpenAccess as d, recheckGuardsEffect as f } from "@voltro/protocol";
6
- //#region src/bindEvent.ts
6
+ // src/bindEvent.ts
7
7
  var p = 64, m = 1, h = (e) => e.kind === "gap" ? {
8
8
  _tag: "gap",
9
9
  missed: e.missed,
@@ -88,5 +88,4 @@ var p = 64, m = 1, h = (e) => e.kind === "gap" ? {
88
88
  let P = { _tag: "attached" }, F = o.concat(o.fromIterable([P]), j), I = w === void 0 ? F : F.pipe(o.interruptWhen(w.pipe(i.catch(() => i.void), i.catchDefect(() => i.void), i.flatMap(() => i.fail(x())))));
89
89
  return r(I, _.credentialExpiresAt, o.fromIterable([P]));
90
90
  }));
91
- //#endregion
92
91
  export { p as EVENT_CLIENT_QUEUE_SIZE, m as EVENT_LATEST_QUEUE_SIZE, _ as bindEvent, g as makeBufferGapDetector };
@@ -0,0 +1,10 @@
1
+ export declare const BOOT_REFUSAL_NAME = "VoltroBootRefusal";
2
+
3
+ /** An error the boot path raised on purpose. The launcher prints its message
4
+ * once and exits 1 instead of degrading to a fallback path or printing a
5
+ * stack. */
6
+ export declare const bootRefusal: (message: string) => Error;
7
+
8
+ export declare const isBootRefusal: (error: unknown) => boolean;
9
+
10
+ export { }
@@ -1,7 +1,6 @@
1
- //#region src/bootRefusal.ts
1
+ // src/bootRefusal.ts
2
2
  var e = "VoltroBootRefusal", t = (t) => {
3
3
  let n = Error(t);
4
4
  return n.name = e, n;
5
5
  }, n = (e) => typeof e == "object" && !!e && e.name === "VoltroBootRefusal";
6
- //#endregion
7
6
  export { e as BOOT_REFUSAL_NAME, t as bootRefusal, n as isBootRefusal };
@@ -1,39 +1,66 @@
1
1
  import { answerProbe as e, probeFor as t, resolveHealth as n } from "./healthProbes.js";
2
2
  import { trackEngineClient as r } from "./engineClients.js";
3
3
  import { createServer as i } from "node:http";
4
- //#region src/bootListener.ts
5
- var a = "no-store", o = "1", s = /* @__PURE__ */ new Set(["ready", "draining"]), c = async (c) => {
6
- let l = c.now ?? Date.now, u = {
4
+ // src/bootListener.ts
5
+ var a = "no-store", o = "1", s = 3e4, c = 3e5, l = 512, u = () => {
6
+ let e = process.env.VOLTRO_BOOT_HOLD_MS;
7
+ if (e === void 0 || e.trim() === "") return s;
8
+ let t = Number(e);
9
+ return !Number.isFinite(t) || t < 0 ? s : Math.min(c, Math.trunc(t));
10
+ }, d = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="light dark"><meta http-equiv="refresh" content="${o}"><title>Starting…</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;font:16px/1.5 system-ui,sans-serif}</style></head><body><p role="status">Starting… this page reloads by itself.</p></body></html>`, f = (e) => (e.method === "GET" || e.method === "HEAD") && /\btext\/html\b/i.test(e.headers.accept ?? ""), p = (e, t) => {
11
+ if (t.headersSent || t.destroyed) return;
12
+ let n = f(e);
13
+ t.writeHead(503, {
14
+ "content-type": n ? "text/html; charset=utf-8" : "text/plain",
15
+ "cache-control": a,
16
+ "retry-after": o
17
+ }), t.end(e.method === "HEAD" ? void 0 : n ? d : "starting");
18
+ }, m = (e) => {
19
+ e.destroyed || e.end(`HTTP/1.1 503 Service Unavailable\r
20
+ Retry-After: ${o}\r\nCache-Control: no-store\r
21
+ Connection: close\r
22
+ Content-Length: 0\r
23
+ \r
24
+ `);
25
+ }, h = (e, t, n, i) => {
26
+ e !== void 0 && (r(t, n), e.upgrade(t, n, i));
27
+ }, g = /* @__PURE__ */ new Set(["ready", "draining"]), _ = /* @__PURE__ */ new Set([
28
+ "booting",
29
+ "migrating",
30
+ "ready"
31
+ ]), v = async (r) => {
32
+ let o = r.now ?? Date.now, s = {
7
33
  phase: "booting",
8
- startedAt: l()
9
- }, d, f, p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), h, g = () => u.phase === "ready", _ = () => s.has(u.phase), v = n(c.health, () => g()), y = c.health?.readiness === void 0 ? async () => g() && (f === void 0 || await f()) : v.readiness, b = () => {
10
- if ((p.size > 0 || h !== void 0) && !g()) return !1;
11
- for (let e of p.values()) try {
34
+ startedAt: o()
35
+ }, c, d, f = /* @__PURE__ */ new Map(), v = /* @__PURE__ */ new Map(), y, b = Math.max(0, r.holdMs ?? u()), x = Math.max(0, r.maxHeld ?? l), S = /* @__PURE__ */ new Set(), C = !1, w = !1, T = () => s.phase === "ready", E = () => g.has(s.phase), D = () => c !== void 0 && E(), O = () => _.has(s.phase) || D(), k = n(r.health, () => T()), A = r.health?.readiness === void 0 ? async () => T() && (d === void 0 || await d()) : k.readiness, j = () => {
36
+ if ((f.size > 0 || y !== void 0) && !T()) return !1;
37
+ for (let e of f.values()) try {
12
38
  if (e() !== !0) return !1;
13
39
  } catch {
14
40
  return !1;
15
41
  }
16
42
  return !0;
17
- }, x = () => {
18
- for (let e of m.values()) try {
43
+ }, M = () => {
44
+ for (let e of v.values()) try {
19
45
  if (e() !== !0) return !1;
20
46
  } catch {
21
47
  return !1;
22
48
  }
23
49
  return !0;
24
- }, S = {
25
- ...v,
26
- readiness: async () => b() && await y() && b(),
27
- liveness: async () => x() && await v.liveness() && x()
28
- }, C = () => ({
29
- phase: u.phase,
30
- ready: g(),
31
- elapsedMs: l() - u.startedAt,
32
- ...u.tablesTotal === void 0 ? {} : { tablesTotal: u.tablesTotal },
33
- ...u.error === void 0 ? {} : { error: u.error }
34
- }), w = i((n, r) => {
35
- let i = n.url ?? "/", s = i.indexOf("?"), c = s === -1 ? i : i.slice(0, s);
36
- if (c === "/_voltro/health" && (h !== void 0 || p.size > 0)) {
50
+ }, N = {
51
+ ...k,
52
+ readiness: async () => j() && await A() && j(),
53
+ liveness: async () => M() && await k.liveness() && M()
54
+ }, P = () => ({
55
+ phase: s.phase,
56
+ ready: T(),
57
+ elapsedMs: o() - s.startedAt,
58
+ ...s.tablesTotal === void 0 ? {} : { tablesTotal: s.tablesTotal },
59
+ ...s.error === void 0 ? {} : { error: s.error },
60
+ ...S.size > 0 ? { held: S.size } : {}
61
+ }), F = i((n, r) => {
62
+ let i = n.url ?? "/", o = i.indexOf("?"), l = o === -1 ? i : i.slice(0, o);
63
+ if (l === "/_voltro/health" && (y !== void 0 || f.size > 0)) {
37
64
  if (n.method !== "GET" && n.method !== "HEAD") {
38
65
  r.writeHead(405, {
39
66
  allow: "GET, HEAD",
@@ -41,103 +68,165 @@ var a = "no-store", o = "1", s = /* @__PURE__ */ new Set(["ready", "draining"]),
41
68
  }), r.end();
42
69
  return;
43
70
  }
44
- e(S, "readiness", C).then((e) => {
45
- let t = e.status === 200 && g() && b();
71
+ e(N, "readiness", P).then((e) => {
72
+ let t = e.status === 200 && T() && j();
46
73
  r.writeHead(t ? 200 : 503, {
47
74
  "content-type": "application/json",
48
75
  "cache-control": a
49
76
  }), r.end(n.method === "HEAD" ? void 0 : JSON.stringify({
50
- ...h,
51
- phase: u.phase,
77
+ ...y,
78
+ phase: s.phase,
52
79
  ready: t
53
80
  }));
54
81
  });
55
82
  return;
56
83
  }
57
- let l = t(S, c);
58
- l === void 0 ? d !== void 0 && _() ? d.request(n, r) : (r.writeHead(503, {
59
- "content-type": "text/plain",
60
- "cache-control": a,
61
- "retry-after": o
62
- }), r.end("starting")) : e(S, l, C).then((e) => {
84
+ let u = t(N, l);
85
+ u === void 0 ? D() && S.size === 0 ? c?.request(n, r) : I({
86
+ attach: (e) => {
87
+ r.once("close", e);
88
+ },
89
+ detach: (e) => {
90
+ r.removeListener("close", e);
91
+ },
92
+ forward: (e) => {
93
+ e.request(n, r);
94
+ },
95
+ refuse: () => {
96
+ p(n, r);
97
+ }
98
+ }) : e(N, u, P).then((e) => {
63
99
  r.writeHead(e.status, {
64
100
  "content-type": e.contentType,
65
101
  "cache-control": a
66
102
  }), r.end(e.body);
67
103
  });
68
104
  });
69
- w.on("upgrade", (e, t, n) => {
70
- d !== void 0 && _() ? (r(e, t), d.upgrade(e, t, n)) : t.end(`HTTP/1.1 503 Service Unavailable\r
71
- Retry-After: ${o}\r\nCache-Control: no-store\r
72
- Connection: close\r
73
- Content-Length: 0\r
74
- \r
75
- `);
76
- }), await new Promise((e, t) => {
105
+ F.on("upgrade", (e, t, n) => {
106
+ if (D() && S.size === 0) {
107
+ h(c, e, t, n);
108
+ return;
109
+ }
110
+ let r = () => {};
111
+ I({
112
+ attach: (e) => {
113
+ t.on("error", r), t.once("close", e);
114
+ },
115
+ detach: (e) => {
116
+ t.removeListener("error", r), t.removeListener("close", e);
117
+ },
118
+ forward: (r) => {
119
+ h(r, e, t, n);
120
+ },
121
+ refuse: () => {
122
+ m(t);
123
+ }
124
+ });
125
+ });
126
+ function I(e) {
127
+ let t = D();
128
+ if (!t && (!O() || b === 0 || S.size >= x)) {
129
+ e.refuse();
130
+ return;
131
+ }
132
+ let n, i = () => {
133
+ a();
134
+ }, a = () => {
135
+ n !== void 0 && clearTimeout(n), e.detach(i), S.delete(o);
136
+ }, o = {
137
+ forward: e.forward,
138
+ refuse: e.refuse,
139
+ release: a
140
+ };
141
+ t || (n = setTimeout(() => {
142
+ a(), C || (C = !0, r.log?.info("boot still running after the hold window — answering 503 to waiting requests", {
143
+ holdMs: b,
144
+ phase: s.phase
145
+ })), e.refuse();
146
+ }, b), n.unref()), e.attach(i), S.add(o), t && L();
147
+ }
148
+ function L() {
149
+ w || S.size === 0 || (w = !0, setImmediate(() => {
150
+ w = !1, R();
151
+ }));
152
+ }
153
+ function R() {
154
+ if (D()) {
155
+ let e = c;
156
+ if (e === void 0) return;
157
+ let t = S.size;
158
+ for (let t of [...S]) t.release(), t.forward(e);
159
+ t > 0 && r.log?.info("handed requests held during boot to the app", { count: t });
160
+ } else if (!O()) for (let e of [...S]) e.release(), e.refuse();
161
+ }
162
+ await new Promise((e, t) => {
77
163
  let n = (e) => {
78
164
  t(e);
79
165
  };
80
- w.once("error", n), w.listen(c.host === void 0 ? { port: c.port } : {
81
- port: c.port,
82
- host: c.host
166
+ F.once("error", n), F.listen(r.host === void 0 ? { port: r.port } : {
167
+ port: r.port,
168
+ host: r.host
83
169
  }, () => {
84
- w.removeListener("error", n), e();
170
+ F.removeListener("error", n), e();
85
171
  });
86
172
  });
87
- let T = w.address()?.port ?? c.port;
88
- return c.log?.info("listening early — probes answer on the app port from here on", { port: T }), {
89
- server: w,
90
- port: T,
173
+ let z = F.address()?.port ?? r.port;
174
+ return r.log?.info("listening early — probes answer on the app port from here on", { port: z }), {
175
+ server: F,
176
+ port: z,
91
177
  get state() {
92
- return u;
178
+ return s;
179
+ },
180
+ get held() {
181
+ return S.size;
93
182
  },
94
183
  set: (e) => {
95
- u = {
96
- ...u,
184
+ s = {
185
+ ...s,
97
186
  ...e
98
- };
187
+ }, L();
99
188
  },
100
- isReady: g,
189
+ isReady: T,
101
190
  delegate: (e) => {
102
- d = e;
191
+ c = e, L();
103
192
  },
104
193
  setDependencyPing: (e) => {
105
- f = e;
194
+ d = e;
106
195
  },
107
196
  setRoleHealth: (e) => {
108
197
  let t = (e) => {
109
198
  if (!Array.isArray(e) || e.length === 0 || e.length > 64 || e.some((e) => typeof e != "string" || !/^[a-z][a-z0-9._-]{0,63}$/.test(e)) || new Set(e).size !== e.length) throw Error("Invalid role health identity");
110
199
  return Object.freeze([...e]);
111
200
  };
112
- h = Object.freeze({
201
+ y = Object.freeze({
113
202
  roles: t(e.roles),
114
203
  workloads: t(e.workloads)
115
204
  });
116
205
  },
117
206
  addReadinessGate: (e, t) => {
118
207
  if (!/^[a-z][a-z0-9._-]{0,63}$/.test(e) || typeof t != "function") throw Error("Invalid readiness gate");
119
- if (p.has(e)) throw Error("Readiness gate is already registered");
120
- p.set(e, t);
208
+ if (f.has(e)) throw Error("Readiness gate is already registered");
209
+ f.set(e, t);
121
210
  let n = !1;
122
211
  return () => {
123
- n || (n = !0, p.get(e) === t && p.delete(e));
212
+ n || (n = !0, f.get(e) === t && f.delete(e));
124
213
  };
125
214
  },
126
215
  addLivenessGate: (e, t) => {
127
216
  if (!/^[a-z][a-z0-9._-]{0,63}$/.test(e) || typeof t != "function") throw Error("Invalid liveness gate");
128
- if (m.has(e)) throw Error("Liveness gate is already registered");
129
- m.set(e, t);
217
+ if (v.has(e)) throw Error("Liveness gate is already registered");
218
+ v.set(e, t);
130
219
  let n = !1;
131
220
  return () => {
132
- n || (n = !0, m.get(e) === t && m.delete(e));
221
+ n || (n = !0, v.get(e) === t && v.delete(e));
133
222
  };
134
223
  },
135
224
  close: () => new Promise((e) => {
136
- w.listening ? (w.closeAllConnections(), w.close(() => {
225
+ for (let e of [...S]) e.release(), e.refuse();
226
+ F.listening ? (F.closeAllConnections(), F.close(() => {
137
227
  e();
138
228
  })) : e();
139
229
  })
140
230
  };
141
231
  };
142
- //#endregion
143
- export { c as bindBootListener };
232
+ export { v as bindBootListener, u as bootHoldMsFromEnv };
@@ -2,7 +2,7 @@ import { getFieldCipher as e } from "./fieldCipher.js";
2
2
  import { upsertDestinationId as t } from "./upsertBinding.js";
3
3
  import { decryptFieldsOnRead as n, deserializeArraysOnRead as r, encryptFieldsForWrite as i, encryptFieldsForWriteBatch as a, encryptedColumnsOf as o, getTable as s, jsonPatchAssignments as c, refuseIdChangeOfSealedRow as l, serializeArraysForWrite as u, upsertUpdateValues as d } from "@voltro/database";
4
4
  import { createLogger as f } from "@voltro/logger";
5
- //#region src/bootStoreCodec.ts
5
+ // src/bootStoreCodec.ts
6
6
  var p = f({ scope: "store.fieldEncryption" }), m = (f, h) => {
7
7
  let g = h, _ = process.env.VOLTRO_FIELD_DECRYPT_ON_ERROR === "null" ? "null" : "throw", v = /* @__PURE__ */ new Set(), y = (e) => {
8
8
  let t = `${e.table}.${e.column}`;
@@ -67,5 +67,4 @@ var p = f({ scope: "store.fieldEncryption" }), m = (f, h) => {
67
67
  transactional: (e) => f.transactional((t) => e(m(t, h)))
68
68
  };
69
69
  };
70
- //#endregion
71
70
  export { m as wrapStoreWithBootCodec };
@@ -1,7 +1,7 @@
1
1
  import { getTable as e } from "@voltro/database";
2
2
  import { BusinessRuleViolation as t } from "@voltro/protocol";
3
3
  import { log as n } from "@voltro/logger";
4
- //#region src/businessRules.ts
4
+ // src/businessRules.ts
5
5
  var r = (e) => e.startsWith("_voltro"), i = (e) => {
6
6
  let t = e?.id;
7
7
  return typeof t == "string" ? t : void 0;
@@ -63,5 +63,4 @@ var r = (e) => e.startsWith("_voltro"), i = (e) => {
63
63
  }
64
64
  }
65
65
  };
66
- //#endregion
67
66
  export { s as evaluateTouchedRules, a as makeRuleCapture };
@@ -1,5 +1,5 @@
1
1
  import { id as e, integer as t, table as n, text as r, timestamp as i } from "@voltro/database";
2
- //#region src/changeClaimsTable.ts
2
+ // src/changeClaimsTable.ts
3
3
  var a = n("_voltro_change_claims", {
4
4
  id: e({ prefix: "chclaim" }),
5
5
  scope: r(),
@@ -8,5 +8,4 @@ var a = n("_voltro_change_claims", {
8
8
  claimedAt: i(),
9
9
  nextSlot: t().default(0)
10
10
  }).unique(["scope", "key"]).index(["claimedAt"]);
11
- //#endregion
12
11
  export { a as _voltroChangeClaimsTable };
@@ -1,4 +1,4 @@
1
- //#region src/columnOnUpdate.ts
1
+ // src/columnOnUpdate.ts
2
2
  var e = (e) => {
3
3
  if (!(e.length < 32 || Object.getPrototypeOf(e) !== Array.prototype || Object.getOwnPropertySymbols(e).length > 0 || Object.hasOwn(e, "includes"))) {
4
4
  for (let t = 0; t < e.length; t++) {
@@ -19,5 +19,4 @@ var e = (e) => {
19
19
  }
20
20
  return o;
21
21
  };
22
- //#endregion
23
22
  export { t as applyColumnOnUpdate };
@@ -1,6 +1,6 @@
1
1
  import { AnalyticsCapabilityNotSupported as e } from "./analyticsSink.js";
2
2
  import { Effect as t } from "effect";
3
- //#region src/composeAnalytics.ts
3
+ // src/composeAnalytics.ts
4
4
  var n = "noop", r = () => {
5
5
  let r = (r) => t.fail(new e({
6
6
  provider: n,
@@ -125,5 +125,4 @@ var n = "noop", r = () => {
125
125
  sql: "none",
126
126
  build: () => r()
127
127
  };
128
- //#endregion
129
128
  export { n as NOOP_ANALYTICS_PROVIDER, a as composeAnalytics, i as composeAnalyticsSinks, r as noopAnalytics, o as noopAnalyticsSpec };
@@ -1,4 +1,3 @@
1
- //#region src/computedQuery.ts
1
+ // src/computedQuery.ts
2
2
  var e = (e) => typeof e == "object" && !!e && e.__voltroComputed === !0;
3
- //#endregion
4
3
  export { e as isComputedQuery };