@voltro/protocol 0.86.0 → 0.88.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 (78) hide show
  1. package/CHANGELOG.md +5484 -0
  2. package/THIRD-PARTY-NOTICES.md +3 -227
  3. package/dist/apiRoleEndpoints.js +107 -0
  4. package/dist/apiRoleObservation.js +67 -0
  5. package/dist/apikey.d.ts +10 -0
  6. package/dist/apikey.js +1 -2
  7. package/dist/approval.js +1 -2
  8. package/dist/approvalDescriptors.js +1 -2
  9. package/dist/auth.js +40 -21
  10. package/dist/boundedRing.js +1 -2
  11. package/dist/businessRule.js +1 -2
  12. package/dist/canonicalJson.js +13 -0
  13. package/dist/connection.js +1 -2
  14. package/dist/devActivity.js +1 -2
  15. package/dist/errorSchema.js +23 -0
  16. package/dist/errorValue.js +1 -2
  17. package/dist/event.js +52 -47
  18. package/dist/formCapture.js +11 -0
  19. package/dist/httpStreamMaxDuration.js +8 -0
  20. package/dist/idempotency.js +89 -35
  21. package/dist/idempotencyInput.js +122 -0
  22. package/dist/identity.js +1 -2
  23. package/dist/index.d.ts +876 -124
  24. package/dist/index.js +51 -40
  25. package/dist/inspect.d.ts +1 -1
  26. package/dist/inspect.js +1 -2
  27. package/dist/inspectBackfill.js +1 -2
  28. package/dist/inspectCommandRejection.js +1 -2
  29. package/dist/inspectProjection.js +1 -2
  30. package/dist/inspectStorageProjection.js +1 -2
  31. package/dist/inspectValueIdentity.js +1 -2
  32. package/dist/inspectWorkflowExecution.js +1 -2
  33. package/dist/inspectWorkflowQueuedStart.js +1 -2
  34. package/dist/jsonSchema.js +1 -2
  35. package/dist/jwt.d.ts +10 -0
  36. package/dist/jwt.js +2 -3
  37. package/dist/outbox.js +1 -2
  38. package/dist/pairing.js +1 -2
  39. package/dist/plugin.js +44 -19
  40. package/dist/pluginAccountMerge.js +87 -0
  41. package/dist/pluginNaming.js +1 -2
  42. package/dist/pluginPrivacy.js +165 -0
  43. package/dist/procedure.js +115 -98
  44. package/dist/publicApi.js +191 -211
  45. package/dist/queryOptionalSources.js +13 -0
  46. package/dist/reactivityChannel.js +1 -2
  47. package/dist/rest.d.ts +227 -64
  48. package/dist/rest.js +296 -194
  49. package/dist/restFormat.js +1 -2
  50. package/dist/restReceipt.js +42 -0
  51. package/dist/revalidate.js +12 -0
  52. package/dist/rowEquality.js +1 -2
  53. package/dist/rowPatch.js +1 -2
  54. package/dist/schemaShape.js +1 -2
  55. package/dist/scopes.js +72 -40
  56. package/dist/secretWindows.js +70 -0
  57. package/dist/serverErrorBus.js +1 -2
  58. package/dist/serviceCall.js +1 -2
  59. package/dist/session.d.ts +89 -6
  60. package/dist/session.js +56 -56
  61. package/dist/sessionHeader.js +1 -2
  62. package/dist/ssrfPolicy.js +29 -0
  63. package/dist/storageAccess.js +1 -2
  64. package/dist/storeErrors.js +1 -2
  65. package/dist/storeScreenshots.js +1 -2
  66. package/dist/strictInput.js +1 -2
  67. package/dist/subscriptionEvent.js +1 -2
  68. package/dist/tenantSelection.js +1 -2
  69. package/dist/time.js +1 -2
  70. package/dist/undo.js +1 -2
  71. package/dist/validation.js +1 -2
  72. package/dist/webSocketGateway.js +8 -3
  73. package/dist/workflow.js +1 -2
  74. package/dist/workflowAccess.js +1 -2
  75. package/dist/workflowRestart.js +1 -2
  76. package/dist/workflowRetry.js +1 -2
  77. package/dist/workflowStartOutcome.js +1 -2
  78. package/package.json +7 -5
@@ -1,4 +1,4 @@
1
- //#region src/boundedRing.ts
1
+ // src/boundedRing.ts
2
2
  var e = class {
3
3
  slots = [];
4
4
  head = 0;
@@ -23,5 +23,4 @@ var e = class {
23
23
  for (let e = 0; e < this.size; e++) yield this.get(e);
24
24
  }
25
25
  };
26
- //#endregion
27
26
  export { e as BoundedRing };
@@ -1,5 +1,5 @@
1
1
  import { Schema as e } from "effect";
2
- //#region src/businessRule.ts
2
+ // src/businessRule.ts
3
3
  var t = class extends e.TaggedError()("BusinessRuleViolation", {
4
4
  rule: e.String,
5
5
  params: e.optional(e.Record(e.String, e.Unknown)),
@@ -7,5 +7,4 @@ var t = class extends e.TaggedError()("BusinessRuleViolation", {
7
7
  message: e.optional(e.String),
8
8
  severity: e.Literals(["error", "warning"])
9
9
  }) {};
10
- //#endregion
11
10
  export { t as BusinessRuleViolation };
@@ -0,0 +1,13 @@
1
+ // src/canonicalJson.ts
2
+ var e = (e) => {
3
+ let t = (e) => {
4
+ if (Array.isArray(e)) return e.map(t);
5
+ if (typeof e == "object" && e) {
6
+ let n = e;
7
+ return Object.fromEntries(Object.keys(n).sort().map((e) => [e, t(n[e])]));
8
+ }
9
+ return e;
10
+ };
11
+ return JSON.stringify(t(e) ?? null);
12
+ };
13
+ export { e as canonicalJson };
@@ -1,6 +1,6 @@
1
1
  import { defineAction as e, defineMutation as t, defineQuery as n } from "./procedure.js";
2
2
  import { Schema as r } from "effect";
3
- //#region src/connection.ts
3
+ // src/connection.ts
4
4
  var i = "__voltro.connections.list", a = "__voltro.connections.start", o = "__voltro.connections.submitToken", s = "__voltro.connections.disconnect", c = r.Literals(["oauth2", "pat"]), l = r.Literals([
5
5
  "disconnected",
6
6
  "connected",
@@ -69,5 +69,4 @@ var i = "__voltro.connections.list", a = "__voltro.connections.start", o = "__vo
69
69
  error: h,
70
70
  openAccess: "self-service: deletes only the calling subject's own credential row for this connection"
71
71
  });
72
- //#endregion
73
72
  export { i as CONNECTIONS_LIST_TAG, s as CONNECTION_DISCONNECT_TAG, a as CONNECTION_START_TAG, o as CONNECTION_SUBMIT_TOKEN_TAG, m as ConnectionHandshakeFailed, c as ConnectionKind, p as ConnectionKindMismatch, d as ConnectionNotDeclared, u as ConnectionState, l as ConnectionStatus, f as ConnectionSubjectRequired, y as connectionDisconnectDescriptor, _ as connectionStartDescriptor, v as connectionSubmitTokenDescriptor, g as connectionsListQueryDescriptor };
@@ -1,4 +1,3 @@
1
- //#region src/devActivity.ts
1
+ // src/devActivity.ts
2
2
  var e = "voltro:dev-activity";
3
- //#endregion
4
3
  export { e as DEV_ACTIVITY_EVENT };
@@ -0,0 +1,23 @@
1
+ import { Schema as e } from "effect";
2
+ import * as t from "effect/SchemaAST";
3
+ // src/errorSchema.ts
4
+ var n = (e) => {
5
+ let n = /* @__PURE__ */ new Set();
6
+ if (e === void 0) return n;
7
+ let r = (e) => {
8
+ if (t.isUnion(e)) for (let t of e.types) r(t);
9
+ else if (e.encoding !== void 0 && r(t.toEncoded(e)), t.isObjects(e)) {
10
+ let r = e.propertySignatures.find((e) => e.name === "_tag");
11
+ r !== void 0 && t.isLiteral(r.type) && typeof r.type.literal == "string" && n.add(r.type.literal);
12
+ }
13
+ };
14
+ return r(e.ast), n;
15
+ }, r = (r, i) => {
16
+ if (r === void 0) return;
17
+ let a = t.isUnion(r.ast) ? r.ast.types : [r.ast];
18
+ for (let t of a) {
19
+ let r = e.make(t);
20
+ if (n(r).has(i)) return r;
21
+ }
22
+ };
23
+ export { n as declaredErrorTags, r as errorMemberSchema };
@@ -1,4 +1,4 @@
1
- //#region src/errorValue.ts
1
+ // src/errorValue.ts
2
2
  var e = (e) => {
3
3
  if (typeof e != "object" || !e) return;
4
4
  let t = e._tag;
@@ -17,5 +17,4 @@ var e = (e) => {
17
17
  let r = Error(t(n), { cause: n });
18
18
  return r.name = e(n) ?? "NonErrorThrown", r;
19
19
  };
20
- //#endregion
21
20
  export { t as errorMessage, e as errorTag, n as reportableError };
package/dist/event.js CHANGED
@@ -3,10 +3,15 @@ import { Unauthenticated as t } from "./auth.js";
3
3
  import { NoSuchResource as n, ScopeError as r, declaresResourceGuard as i, isOpenAccess as a, openAccessSpec as o } from "./scopes.js";
4
4
  import { strictInput as s } from "./strictInput.js";
5
5
  import { hasEnforcedGuard as c } from "./procedure.js";
6
- import { Schema as l } from "effect";
7
- import { Rpc as u } from "effect/rpc";
8
- //#region src/event.ts
9
- var d = 7500, f = (e) => typeof e == "object" && !!e && e.kind === "event", p = (e) => {
6
+ import { Context as l, Schema as u } from "effect";
7
+ import { Rpc as d } from "effect/rpc";
8
+ // src/event.ts
9
+ var f = 7500, p = (e) => typeof e == "object" && !!e && e.kind === "event", m = (e) => {
10
+ if (e.clientPolicy !== void 0) {
11
+ if (!/^[A-Za-z][A-Za-z0-9_.:-]{0,255}$/.test(e.clientPolicy)) throw Error("defineEvent: invalid client policy ID");
12
+ if (e.openAccess !== void 0 || !c(e.guards)) throw Error("defineEvent: a client policy requires explicit enforced guards");
13
+ if (e.webhook !== void 0) throw Error("defineEvent: private client policies do not authorize webhook recipients");
14
+ }
10
15
  if (e.name.length === 0) throw Error("defineEvent: `name` must not be empty");
11
16
  if (/\s/.test(e.name)) throw Error(`defineEvent("${e.name}"): \`name\` must not contain whitespace.\n The name is used as a broker subject segment. NATS refuses a subject with
12
17
  whitespace and delivers nothing — silently, and only on that broker, so an
@@ -39,66 +44,66 @@ var d = 7500, f = (e) => typeof e == "object" && !!e && e.kind === "event", p =
39
44
  openAccess: e.openAccess,
40
45
  rewind: e.rewind,
41
46
  webhook: e.webhook,
42
- delivery: e.delivery
47
+ delivery: e.delivery,
48
+ ...e.clientPolicy === void 0 ? {} : { clientPolicy: e.clientPolicy }
43
49
  };
44
- }, m = (e) => l.Struct({
45
- _tag: l.Literal("event"),
46
- origin: l.String,
47
- n: l.Number,
48
- emittedAt: l.Number,
50
+ }, h = (e) => u.Struct({
51
+ _tag: u.Literal("event"),
52
+ origin: u.String,
53
+ n: u.Number,
54
+ emittedAt: u.Number,
49
55
  payload: e
50
- }), h = l.Struct({
51
- _tag: l.Literal("gap"),
52
- missed: l.Number,
53
- reason: l.Literals(["buffer", "resume"])
54
- }), g = l.Struct({ _tag: l.Literal("attached") }), _ = (e) => l.Union([
55
- g,
56
- m(e),
57
- h
58
- ]), v = l.Struct({
59
- origin: l.String,
60
- n: l.Number
61
- }), y = (e) => l.Struct({
56
+ }), g = u.Struct({
57
+ _tag: u.Literal("gap"),
58
+ missed: u.Number,
59
+ reason: u.Literals(["buffer", "resume"])
60
+ }), _ = u.Struct({ _tag: u.Literal("attached") }), v = (e) => u.Union([
61
+ _,
62
+ h(e),
63
+ g
64
+ ]), y = u.Struct({
65
+ origin: u.String,
66
+ n: u.Number
67
+ }), b = (e) => u.Struct({
62
68
  key: e,
63
- resume: l.optional(l.Array(v))
64
- }), b = (o, d) => {
65
- let f = o.guards !== void 0 && o.guards.some((e) => !a(e)) ? l.Union([
69
+ resume: u.optional(u.Array(y))
70
+ }), x = l.Service("@voltro/protocol/EventRpcWorkload"), S = (o, l) => {
71
+ let f = o.guards !== void 0 && o.guards.some((e) => !a(e)) ? u.Union([
66
72
  r,
67
73
  t,
68
74
  e
69
- ]) : l.Union([t, e]), p = i(o.guards) ? l.Union([f, n]) : f, m = d && d.length > 0 ? l.Union([p, ...d]) : p;
70
- return u.make(o.name, {
71
- payload: s(y(o.key), o.name, c(o.guards)),
72
- success: _(o.payload),
75
+ ]) : u.Union([t, e]), p = i(o.guards) ? u.Union([f, n]) : f, m = l && l.length > 0 ? u.Union([p, ...l]) : p;
76
+ return d.make(o.name, {
77
+ payload: s(b(o.key), o.name, c(o.guards)),
78
+ success: v(o.payload),
73
79
  error: m,
74
80
  stream: !0
75
- });
76
- }, x = class extends l.TaggedError()("EventPayloadInvalid", {
77
- event: l.String,
78
- message: l.String
79
- }) {}, S = class extends l.TaggedError()("EventKeyInvalid", {
80
- event: l.String,
81
- message: l.String
82
- }) {}, C = class extends l.TaggedError()("EventPayloadTooLarge", {
83
- event: l.String,
84
- bytes: l.Number,
85
- limit: l.Number
86
- }) {}, w = (e) => {
81
+ }).annotate(x, !0);
82
+ }, C = class extends u.TaggedError()("EventPayloadInvalid", {
83
+ event: u.String,
84
+ message: u.String
85
+ }) {}, w = class extends u.TaggedError()("EventKeyInvalid", {
86
+ event: u.String,
87
+ message: u.String
88
+ }) {}, T = class extends u.TaggedError()("EventPayloadTooLarge", {
89
+ event: u.String,
90
+ bytes: u.Number,
91
+ limit: u.Number
92
+ }) {}, E = (e) => {
87
93
  if (typeof e != "object" || !e) return JSON.stringify(e) ?? "null";
88
94
  let t = Object.entries(e), n = 0;
89
95
  for (let e of t) e[1] !== void 0 && (t[n++] = e);
90
96
  return t.length = n, t.sort(([e], [t]) => e < t ? -1 : +(e > t)), JSON.stringify(t);
91
- }, T = "\0", E = (e, t, n) => [
97
+ }, D = "\0", O = (e, t, n) => [
92
98
  e ?? "~",
93
99
  t,
94
- w(n)
95
- ].join("\0"), D = (e) => {
100
+ E(n)
101
+ ].join("\0"), k = (e) => {
96
102
  let [t = "~", n = "", r = ""] = e.split("\0");
97
103
  return {
98
104
  tenantId: t === "~" ? null : t,
99
105
  event: n,
100
106
  key: r
101
107
  };
102
- }, O = (e) => e.split("\0").join(" · ");
103
- //#endregion
104
- export { T as EVENT_ROUTE_SEP, S as EventKeyInvalid, x as EventPayloadInvalid, C as EventPayloadTooLarge, d as MAX_EVENT_ENVELOPE_BYTES, p as defineEvent, w as encodeEventKey, g as eventAttached, m as eventEnvelope, h as eventGap, v as eventResumePoint, E as eventRoute, _ as eventStreamEvent, y as eventSubscribeInput, b as eventToRpc, O as formatEventRoute, f as isEventDescriptor, D as parseEventRoute };
108
+ }, A = (e) => e.split("\0").join(" · ");
109
+ export { D as EVENT_ROUTE_SEP, w as EventKeyInvalid, C as EventPayloadInvalid, T as EventPayloadTooLarge, x as EventRpcWorkload, f as MAX_EVENT_ENVELOPE_BYTES, m as defineEvent, E as encodeEventKey, _ as eventAttached, h as eventEnvelope, g as eventGap, y as eventResumePoint, O as eventRoute, v as eventStreamEvent, b as eventSubscribeInput, S as eventToRpc, A as formatEventRoute, p as isEventDescriptor, k as parseEventRoute };
@@ -0,0 +1,11 @@
1
+ // src/formCapture.ts
2
+ var e = "__voltro_capture", t = "voltro:form-source", n = (e) => typeof e == "string" && e.length === 261 && /^1(?:\.[a-f0-9]{64}){4}$/.test(e) ? e : void 0, r = (e, t) => {
3
+ let r = n(e + "." + t);
4
+ if (r === void 0) throw Error("Native form source unavailable");
5
+ return r;
6
+ }, i = (e = globalThis.document) => {
7
+ if (e === void 0) return;
8
+ let r = e.querySelectorAll(`meta[name="${t}"]`);
9
+ return r.length === 1 ? n(r[0].getAttribute("content")) : void 0;
10
+ };
11
+ export { e as FORM_CAPTURE_FIELD, t as FORM_CAPTURE_META_NAME, r as encodeNativeFormCapture, n as formCaptureSource, i as readFormCaptureSource };
@@ -0,0 +1,8 @@
1
+ // src/httpStreamMaxDuration.ts
2
+ var e = (e) => {
3
+ if (e !== void 0) {
4
+ if (typeof e != "number" || !Number.isSafeInteger(e) || e < 1 || e > 2147483647) throw RangeError("SSE maxDurationMs must be an integer between 1 and 2147483647.");
5
+ return e;
6
+ }
7
+ };
8
+ export { e as validateHttpStreamMaxDuration };
@@ -1,5 +1,5 @@
1
1
  import { Schema as e } from "effect";
2
- //#region src/idempotency.ts
2
+ // src/idempotency.ts
3
3
  var t = (e, t, n) => `${e ?? "(global)"}|${t.toUpperCase()}|${n}`, n = (e, t, n, r) => r === void 0 ? `${e ?? "(global)"}|${t ?? "(anon)"}|WS|${n}` : `WS-connection:${JSON.stringify([
4
4
  e ?? null,
5
5
  t ?? null,
@@ -9,58 +9,112 @@ var t = (e, t, n) => `${e ?? "(global)"}|${t.toUpperCase()}|${n}`, n = (e, t, n,
9
9
  get message() {
10
10
  return "this mutation requires a live native WebSocket connection";
11
11
  }
12
- }, i = async (e, t, n, r, i, o = a) => {
13
- let s = await e.claim(t, n, i, r, o);
14
- return s === "claimed" ? { kind: "fresh" } : s.status === "completed" && s.response ? {
15
- kind: "replay",
16
- response: s.response
17
- } : { kind: "conflict" };
18
- }, a = 3e4, o = (e, t, n, r = a, i = Date.now) => {
19
- let o = setInterval(() => {
20
- e.renew(t, n, i()).catch(() => {});
21
- }, Math.max(1, Math.floor(r / 3)));
22
- return o.unref?.(), () => clearInterval(o);
23
- }, s = (e, t, n, r, i) => e.complete(t, n, r, i), c = (e, t, n) => e.release(t, n), l = () => {
24
- let e = /* @__PURE__ */ new Map(), t = (e, t) => `${e}\u0000${t}`;
12
+ }, i = async (e, t, n, r, i, o, s = a) => {
13
+ if (!/^[0-9a-f]{64}$/.test(r)) throw Error("Invalid idempotency input fingerprint");
14
+ let c = await e.claim(t, n, r, o, i, s);
15
+ if (c.kind === "claimed") {
16
+ let e = c.claim;
17
+ if (typeof e.id != "string" || e.id.length === 0 || e.scope !== t || e.key !== n || e.inputHash !== r) throw Error("Idempotency store returned an invalid claim identity");
18
+ return {
19
+ kind: "fresh",
20
+ claim: Object.freeze({
21
+ scope: t,
22
+ key: n,
23
+ id: e.id,
24
+ inputHash: r
25
+ })
26
+ };
27
+ }
28
+ if (c.kind === "existing") {
29
+ if (c.record.scope !== t || c.record.key !== n) throw Error("Idempotency store returned an invalid receipt identity");
30
+ return typeof c.record.inputHash == "string" ? c.record.inputHash === r ? c.record.status === "completed" && c.record.response ? {
31
+ kind: "replay",
32
+ response: c.record.response
33
+ } : { kind: "conflict" } : { kind: "input-conflict" } : { kind: "input-unbound" };
34
+ }
35
+ if (c.kind === "conflict") return { kind: "conflict" };
36
+ throw Error("Idempotency store returned an invalid acquisition result");
37
+ }, a = 3e4, o = (e, t, n = a, r = Date.now) => {
38
+ let i = Object.freeze({
39
+ scope: t.scope,
40
+ key: t.key,
41
+ id: t.id,
42
+ inputHash: t.inputHash
43
+ }), o = !1, s = setInterval(() => {
44
+ o || (o = !0, e.renew(i, r()).then((e) => {
45
+ e || clearInterval(s);
46
+ }, () => {}).finally(() => {
47
+ o = !1;
48
+ }));
49
+ }, Math.max(1, Math.floor(n / 3)));
50
+ return s.unref?.(), () => clearInterval(s);
51
+ }, s = (e, t, n, r) => e.complete(t, n, r), c = (e, t) => e.release(t), l = 0n, u = () => {
52
+ let e = /* @__PURE__ */ new Map(), t = (e, t) => JSON.stringify([e, t]), n = (n) => {
53
+ let r = e.get(t(n.scope, n.key));
54
+ return r?.status === "in_flight" && r.id === n.id && r.inputHash === n.inputHash ? r : void 0;
55
+ };
25
56
  return {
26
57
  get: async (n, r) => e.get(t(n, r)) ?? null,
27
- claim: async (n, r, i, a, o) => {
28
- let s = e.get(t(n, r));
29
- return s && i - s.createdAt < u(s.status, a, o) ? s : (e.set(t(n, r), {
58
+ claim: async (n, r, i, a, o, s) => {
59
+ let c = e.get(t(n, r));
60
+ if (c && c.inputHash !== i || c && a - c.createdAt < d(c.status, o, s)) return {
61
+ kind: "existing",
62
+ record: c
63
+ };
64
+ let u = `memory:${(++l).toString(36)}`;
65
+ return e.set(t(n, r), {
66
+ id: u,
30
67
  scope: n,
31
68
  key: r,
69
+ inputHash: i,
32
70
  status: "in_flight",
33
71
  response: null,
34
- createdAt: i
35
- }), "claimed");
72
+ createdAt: a
73
+ }), {
74
+ kind: "claimed",
75
+ claim: Object.freeze({
76
+ id: u,
77
+ scope: n,
78
+ key: r,
79
+ inputHash: i
80
+ })
81
+ };
36
82
  },
37
- complete: async (n, r, i, a) => {
38
- e.set(t(n, r), {
39
- scope: n,
40
- key: r,
83
+ complete: async (r, i, a) => {
84
+ let o = n(r);
85
+ return o ? (e.set(t(r.scope, r.key), {
86
+ ...o,
41
87
  status: "completed",
42
88
  response: i,
43
89
  createdAt: a
44
- });
45
- },
46
- release: async (n, r) => {
47
- e.delete(t(n, r));
90
+ }), !0) : !1;
48
91
  },
49
- renew: async (n, r, i) => {
50
- let a = e.get(t(n, r));
51
- a?.status === "in_flight" && e.set(t(n, r), {
92
+ release: async (r) => n(r) ? e.delete(t(r.scope, r.key)) : !1,
93
+ renew: async (r, i) => {
94
+ let a = n(r);
95
+ return a ? (e.set(t(r.scope, r.key), {
52
96
  ...a,
53
97
  createdAt: i
54
- });
98
+ }), !0) : !1;
55
99
  }
56
100
  };
57
- }, u = (e, t, n) => e === "completed" ? t : Math.min(t, n), d = class extends e.TaggedError()("MutationInFlight", {
101
+ }, d = (e, t, n) => e === "completed" ? t : Math.min(t, n), f = class extends e.TaggedError()("MutationInFlight", {
58
102
  traceId: e.String,
59
103
  retryAfterMs: e.Number
60
104
  }) {
61
105
  get message() {
62
106
  return `a request with this idempotency key is still in flight — replay the same key after ${this.retryAfterMs}ms`;
63
107
  }
64
- }, f = 1e3;
65
- //#endregion
66
- export { a as DEFAULT_IN_FLIGHT_LEASE_MS, f as MUTATION_IN_FLIGHT_RETRY_AFTER_MS, r as MutationConnectionRequired, d as MutationInFlight, i as beginIdempotent, c as failIdempotent, s as finishIdempotent, u as freshFor, o as holdIdempotentClaim, t as idempotencyScope, l as memoryIdempotencyStore, n as wsMutationIdempotencyScope };
108
+ }, p = 1e3, m = class extends e.TaggedError()("MutationIdempotencyRefused", {
109
+ traceId: e.String,
110
+ reason: e.Literals([
111
+ "input-conflict",
112
+ "input-unbound",
113
+ "input-unavailable"
114
+ ])
115
+ }) {
116
+ get message() {
117
+ return this.reason === "input-unavailable" ? "This request input could not be captured safely. This attempt was stopped before execution." : "This request cannot be safely matched to the original operation. Check its current state before starting another action.";
118
+ }
119
+ };
120
+ export { a as DEFAULT_IN_FLIGHT_LEASE_MS, p as MUTATION_IN_FLIGHT_RETRY_AFTER_MS, r as MutationConnectionRequired, m as MutationIdempotencyRefused, f as MutationInFlight, i as beginIdempotent, c as failIdempotent, s as finishIdempotent, d as freshFor, o as holdIdempotentClaim, t as idempotencyScope, u as memoryIdempotencyStore, n as wsMutationIdempotencyScope };
@@ -0,0 +1,122 @@
1
+ import { canonicalJson as e } from "./canonicalJson.js";
2
+ import { Schema as t } from "effect";
3
+ // src/idempotencyInput.ts
4
+ var n = (t) => {
5
+ let n = /* @__PURE__ */ new WeakMap(), r = 0, i = (e, t = () => !1) => {
6
+ if (Object.getOwnPropertySymbols(e).length) throw Error("Unsupported wire fields");
7
+ return Object.getOwnPropertyNames(e).sort().filter((e) => !t(e)).map((t) => {
8
+ let n = Object.getOwnPropertyDescriptor(e, t);
9
+ if (!("value" in n)) throw Error("Unsupported wire accessor");
10
+ return [t, o(n.value)];
11
+ });
12
+ }, a = (e, t = 0, n = e.byteLength) => {
13
+ let r = "";
14
+ for (let i of new Uint8Array(e, t, n)) r += i.toString(16).padStart(2, "0");
15
+ return r;
16
+ }, o = (e) => {
17
+ if (e === null) return ["null"];
18
+ if (e === void 0) return ["undefined"];
19
+ if (typeof e == "string" || typeof e == "boolean") return [typeof e, e];
20
+ if (typeof e == "number") return ["number", Object.is(e, -0) ? "-0" : String(e)];
21
+ if (typeof e == "bigint") return ["bigint", String(e)];
22
+ if (typeof e != "object") throw Error("Unsupported wire value");
23
+ let t = n.get(e);
24
+ if (t !== void 0) return ["reference", t];
25
+ let s = r++;
26
+ if (n.set(e, s), Array.isArray(e)) {
27
+ if (Object.getPrototypeOf(e) !== Array.prototype) throw Error("Unsupported wire array prototype");
28
+ return [
29
+ "array",
30
+ s,
31
+ e.length,
32
+ i(e, (e) => e === "length")
33
+ ];
34
+ }
35
+ if (Object.getPrototypeOf(e) === Date.prototype) return [
36
+ "date",
37
+ s,
38
+ String(Date.prototype.getTime.call(e)),
39
+ i(e)
40
+ ];
41
+ if (Object.getPrototypeOf(e) === Map.prototype) return [
42
+ "map",
43
+ s,
44
+ Array.from(Map.prototype.entries.call(e), ([e, t]) => [o(e), o(t)]),
45
+ i(e)
46
+ ];
47
+ if (Object.getPrototypeOf(e) === Set.prototype) return [
48
+ "set",
49
+ s,
50
+ Array.from(Set.prototype.values.call(e), o),
51
+ i(e)
52
+ ];
53
+ if (Object.getPrototypeOf(e) === ArrayBuffer.prototype) return [
54
+ "buffer",
55
+ s,
56
+ a(e),
57
+ i(e)
58
+ ];
59
+ if (ArrayBuffer.isView(e)) {
60
+ if (!(e.buffer instanceof ArrayBuffer)) throw Error("Shared wire memory is not a snapshot");
61
+ let t = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(e), "constructor")?.value;
62
+ if (typeof t != "function" || ![
63
+ "DataView",
64
+ "Int8Array",
65
+ "Uint8Array",
66
+ "Uint8ClampedArray",
67
+ "Int16Array",
68
+ "Uint16Array",
69
+ "Int32Array",
70
+ "Uint32Array",
71
+ "Float16Array",
72
+ "Float32Array",
73
+ "Float64Array",
74
+ "BigInt64Array",
75
+ "BigUint64Array"
76
+ ].includes(t.name) || globalThis[t.name] !== t) throw Error("Unsupported wire view prototype");
77
+ return [
78
+ "view",
79
+ s,
80
+ t.name,
81
+ o(e.buffer),
82
+ e.byteOffset,
83
+ e.byteLength,
84
+ i(e, (t) => !(e instanceof DataView) && /^(0|[1-9]\d*)$/.test(t))
85
+ ];
86
+ }
87
+ let c = Object.getPrototypeOf(e);
88
+ if (c !== null && c !== Object.prototype) throw Error("Unsupported wire object");
89
+ return [
90
+ "object",
91
+ s,
92
+ i(e)
93
+ ];
94
+ };
95
+ return e(o(t));
96
+ }, r = async (r, i, a, o = void 0) => {
97
+ try {
98
+ let s = t.encodeUnknownSync(r), c = t.decodeUnknownSync(r), l = s(i), u = n(l), d = c(structuredClone(l));
99
+ if (n(s(d)) !== u) throw Error("Input does not round trip");
100
+ let f = e({
101
+ protocol: "voltro-idempotency-input-v1",
102
+ principal: {
103
+ type: a.type,
104
+ id: a.id,
105
+ tenantId: a.tenantId,
106
+ kind: a.type === "user" ? a.kind ?? null : null,
107
+ service: a.type === "service" ? a.service : null,
108
+ auditActor: a.type === "serviceAccount" ? a.auditActorId === void 0 ? ["implicit"] : ["explicit", a.auditActorId] : null
109
+ },
110
+ wire: u,
111
+ transport: n(o)
112
+ }), p = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(f)), m = "";
113
+ for (let e of new Uint8Array(p)) m += e.toString(16).padStart(2, "0");
114
+ return Object.freeze({
115
+ input: d,
116
+ fingerprint: m
117
+ });
118
+ } catch {
119
+ throw Error("Mutation input cannot be captured for idempotent execution");
120
+ }
121
+ };
122
+ export { r as prepareIdempotentInput };
package/dist/identity.js CHANGED
@@ -2,7 +2,7 @@ import { createLogger as e } from "@voltro/logger";
2
2
  import { readFileSync as t } from "node:fs";
3
3
  import { dirname as n, join as r } from "node:path";
4
4
  import { fileURLToPath as i } from "node:url";
5
- //#region src/processIdentity.ts
5
+ // src/processIdentity.ts
6
6
  var a = e({ scope: "voltro:identity" }), o = Symbol.for("@voltro/runtime/processIdentity"), s = globalThis, c = () => Math.random().toString(36).slice(2, 8), l = s[o] ?? (s[o] = {
7
7
  bootPath: "cli",
8
8
  startedAt: Date.now(),
@@ -98,5 +98,4 @@ var a = e({ scope: "voltro:identity" }), o = Symbol.for("@voltro/runtime/process
98
98
  let e = y().bootPath;
99
99
  return e === "dev" || e === "serve" || e === "start" ? e : "cli";
100
100
  };
101
- //#endregion
102
101
  export { T as appMode, w as frameworkVersion, x as instanceId, y as processIdentity, S as replicaEvidence, b as replicaId, C as resetProcessIdentityForTest, v as resolveAdvertisedHost, g as setProcessAdvertisedAddress, h as setProcessAppVersion, m as setProcessBootPath };