@voltro/protocol 0.69.0 → 0.70.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.
@@ -0,0 +1,232 @@
1
+ import { Schema as e } from "effect";
2
+ import * as t from "effect/SchemaAST";
3
+ import * as n from "effect/Option";
4
+ //#region src/idempotency.ts
5
+ var r = (e, t, n) => `${e ?? "(global)"}|${t.toUpperCase()}|${n}`, i = (e, t, n, r) => r === void 0 ? `${e ?? "(global)"}|${t ?? "(anon)"}|WS|${n}` : `WS-connection:${JSON.stringify([
6
+ e ?? null,
7
+ t ?? null,
8
+ n,
9
+ r
10
+ ])}`, a = class extends e.TaggedError()("MutationConnectionRequired", { traceId: e.String }) {
11
+ get message() {
12
+ return "this mutation requires a live native WebSocket connection";
13
+ }
14
+ }, o = async (e, t, n, r, i) => {
15
+ let a = await e.claim(t, n, i, r);
16
+ return a === "claimed" ? { kind: "fresh" } : a.status === "completed" && a.response ? {
17
+ kind: "replay",
18
+ response: a.response
19
+ } : { kind: "conflict" };
20
+ }, s = (e, t, n, r, i) => e.complete(t, n, r, i), c = (e, t, n) => e.release(t, n), l = () => {
21
+ let e = /* @__PURE__ */ new Map(), t = (e, t) => `${e}\u0000${t}`;
22
+ return {
23
+ get: async (n, r) => e.get(t(n, r)) ?? null,
24
+ claim: async (n, r, i, a) => {
25
+ let o = e.get(t(n, r));
26
+ return o && i - o.createdAt < a ? o : (e.set(t(n, r), {
27
+ scope: n,
28
+ key: r,
29
+ status: "in_flight",
30
+ response: null,
31
+ createdAt: i
32
+ }), "claimed");
33
+ },
34
+ complete: async (n, r, i, a) => {
35
+ e.set(t(n, r), {
36
+ scope: n,
37
+ key: r,
38
+ status: "completed",
39
+ response: i,
40
+ createdAt: a
41
+ });
42
+ },
43
+ release: async (n, r) => {
44
+ e.delete(t(n, r));
45
+ }
46
+ };
47
+ }, u = class extends e.TaggedError()("MutationInFlight", {
48
+ traceId: e.String,
49
+ retryAfterMs: e.Number
50
+ }) {
51
+ get message() {
52
+ return `a request with this idempotency key is still in flight — replay the same key after ${this.retryAfterMs}ms`;
53
+ }
54
+ }, d = 1e3, f = /* @__PURE__ */ new Set(), p = (e) => {
55
+ for (let t of f) try {
56
+ t(e);
57
+ } catch {}
58
+ }, m = (e) => (f.add(e), () => {
59
+ f.delete(e);
60
+ }), h = {
61
+ rpc: {
62
+ name: "rpc",
63
+ dates: "epoch-ms",
64
+ errors: "tagged",
65
+ envelope: "none",
66
+ pagination: "body-cursor",
67
+ cursorField: "nextCursor",
68
+ cursorParam: "cursor",
69
+ naming: "camelCase",
70
+ etag: !1
71
+ },
72
+ standard: {
73
+ name: "standard",
74
+ dates: "iso",
75
+ errors: "problem-details",
76
+ envelope: "none",
77
+ pagination: "link-header",
78
+ cursorField: "nextCursor",
79
+ cursorParam: "cursor",
80
+ naming: "camelCase",
81
+ etag: !0
82
+ },
83
+ jsonapi: {
84
+ name: "jsonapi",
85
+ dates: "iso",
86
+ errors: "problem-details",
87
+ envelope: "jsonapi",
88
+ pagination: "link-header",
89
+ cursorField: "nextCursor",
90
+ cursorParam: "cursor",
91
+ naming: "camelCase",
92
+ etag: !0
93
+ }
94
+ }, g = [
95
+ "rpc",
96
+ "standard",
97
+ "jsonapi"
98
+ ], _ = (e, t = void 0) => {
99
+ let n = (e) => {
100
+ if (e?.profile !== void 0) {
101
+ if (typeof e.profile == "string") {
102
+ let t = h[e.profile];
103
+ if (t === void 0) throw Error(`publicApi.profile: unknown profile '${String(e.profile)}' — one of ${g.join(", ")}, or a RestFormat object`);
104
+ return t;
105
+ }
106
+ return e.profile;
107
+ }
108
+ }, r = (e, t) => t === void 0 ? e : {
109
+ ...e,
110
+ ...t.dates === void 0 ? {} : { dates: t.dates },
111
+ ...t.errors === void 0 ? {} : { errors: t.errors },
112
+ ...t.envelope === void 0 ? {} : { envelope: t.envelope },
113
+ ...t.pagination === void 0 ? {} : { pagination: t.pagination },
114
+ ...t.cursorField === void 0 ? {} : { cursorField: t.cursorField },
115
+ ...t.cursorParam === void 0 ? {} : { cursorParam: t.cursorParam },
116
+ ...t.naming === void 0 ? {} : { naming: t.naming },
117
+ ...t.etag === void 0 ? {} : { etag: t.etag }
118
+ }, i = r(n(e) ?? h.rpc, e);
119
+ return r(n(t) ?? i, t);
120
+ }, v = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z])([A-Z][a-z])/g, "$1_$2").toLowerCase(), y = (e, t) => {
121
+ if (typeof e != "object" || !e || Array.isArray(e)) return e;
122
+ let n = {};
123
+ for (let [r, i] of Object.entries(e)) n[t(r)] = i;
124
+ return n;
125
+ }, b = (e) => n.getOrUndefined(t.getIdentifierAnnotation(e)), x = (n, r) => {
126
+ if (r.dates === "epoch-ms" && r.naming === "camelCase") return n;
127
+ let i = /* @__PURE__ */ new Map(), a = (e) => {
128
+ let t = i.get(e);
129
+ if (t !== void 0) return t;
130
+ let n = o(e);
131
+ return i.set(e, n), n;
132
+ }, o = (n) => {
133
+ switch (n._tag) {
134
+ case "Transformation":
135
+ if (r.dates === "iso" && b(n) === "DateFromNumber") {
136
+ let r = e.DateFromString.ast;
137
+ return new t.Transformation(r.from, r.to, r.transformation, {
138
+ ...r.annotations,
139
+ ...n.annotations,
140
+ [t.IdentifierAnnotationId]: "DateFromString",
141
+ [t.JSONSchemaAnnotationId]: {
142
+ type: "string",
143
+ format: "date-time"
144
+ }
145
+ });
146
+ }
147
+ return n;
148
+ case "Refinement": return new t.Refinement(a(n.from), n.filter, n.annotations);
149
+ case "Union": return t.Union.make(n.types.map(a), n.annotations);
150
+ case "TupleType": return new t.TupleType(n.elements.map((e) => new t.OptionalType(a(e.type), e.isOptional, e.annotations)), n.rest.map((e) => new t.Type(a(e.type), e.annotations)), n.isReadonly, n.annotations);
151
+ case "Suspend": return new t.Suspend(() => a(n.f()), n.annotations);
152
+ case "TypeLiteral": {
153
+ let i = n.propertySignatures.map((e) => new t.PropertySignature(e.name, a(e.type), e.isOptional, e.isReadonly, e.annotations)), o = new t.TypeLiteral(i, n.indexSignatures, n.annotations);
154
+ if (r.naming !== "snake_case") return o;
155
+ let s = i.map((e) => typeof e.name == "string" ? v(e.name) : e.name);
156
+ if (s.every((e, t) => e === i[t].name)) return o;
157
+ let c = new t.TypeLiteral(i.map((e, n) => new t.PropertySignature(s[n], t.encodedAST(e.type), e.isOptional, e.isReadonly, e.annotations)), n.indexSignatures, n.annotations), l = new Map(i.map((e, t) => [String(s[t]), String(e.name)])), u = new Map(i.map((e, t) => [String(e.name), String(s[t])]));
158
+ return e.transform(e.make(c), e.make(o), {
159
+ strict: !1,
160
+ decode: (e) => y(e, (e) => l.get(e) ?? e),
161
+ encode: (e) => y(e, (e) => u.get(e) ?? e)
162
+ }).ast;
163
+ }
164
+ default: return n;
165
+ }
166
+ };
167
+ return e.make(a(n.ast));
168
+ }, S = (e) => `urn:voltro:error:${e}`, C = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z])([A-Z][a-z])/g, "$1 $2"), w = (e) => ({
169
+ type: S(e.tag),
170
+ title: C(e.tag),
171
+ status: e.status,
172
+ ...e.message.length > 0 ? { detail: e.message } : {},
173
+ ...e.fields
174
+ }), T = "application/problem+json; charset=utf-8", E = "application/vnd.api+json; charset=utf-8", D = (e, t, n) => e.encodeError === void 0 ? e.errors === "problem-details" ? e.envelope === "jsonapi" ? {
175
+ body: { errors: [{
176
+ status: String(t.status),
177
+ code: t.tag,
178
+ title: C(t.tag),
179
+ ...t.message.length > 0 ? { detail: t.message } : {},
180
+ ...Object.keys(t.fields).length > 0 ? { meta: t.fields } : {}
181
+ }] },
182
+ contentType: E
183
+ } : {
184
+ body: w(t),
185
+ contentType: T
186
+ } : { body: {
187
+ error: t.tag === "InvalidRequest" || t.tag === "InternalServerError" || t.tag === "Unauthorized" || t.tag === "Forbidden" || t.tag === "Gone" || t.tag === "MethodNotAllowed" || t.tag === "Conflict" ? t.message : t.tag,
188
+ ...t.fields
189
+ } } : e.encodeError(t, n), O = (e, t) => {
190
+ if (typeof e != "object" || !e || Array.isArray(e)) return {
191
+ cursor: void 0,
192
+ rest: e
193
+ };
194
+ let n = e[t];
195
+ return typeof n != "string" && typeof n != "number" ? {
196
+ cursor: void 0,
197
+ rest: e
198
+ } : {
199
+ cursor: String(n),
200
+ rest: e
201
+ };
202
+ }, k = (e, t, n) => {
203
+ let r = new URLSearchParams(e.query);
204
+ return r.set(n, t), `<${e.path}?${r.toString()}>; rel="next"`;
205
+ }, A = (e, t) => {
206
+ if (typeof e != "object" || !e || Array.isArray(e)) return e;
207
+ let { id: n, ...r } = e;
208
+ return {
209
+ type: t,
210
+ ...n === void 0 ? {} : { id: String(n) },
211
+ attributes: r
212
+ };
213
+ }, j = (e, t, n) => {
214
+ if (e.encodeSuccess !== void 0) return e.encodeSuccess(t, n);
215
+ let { cursor: r } = O(t, e.cursorField), i = e.pagination === "link-header" && r !== void 0 ? { Link: k(n, r, e.cursorParam) } : void 0, a = (e, t) => ({
216
+ body: e,
217
+ ...i ? { headers: i } : {},
218
+ ...t ? { contentType: t } : {}
219
+ });
220
+ if (e.envelope === "none") return a(t);
221
+ if (e.envelope === "data") return a({
222
+ data: t,
223
+ ...r !== void 0 && e.pagination === "link-header" ? { next: r } : {}
224
+ });
225
+ let o = n.source ?? n.tag.split(".")[0] ?? "resource", s = Array.isArray(t) ? t : typeof t == "object" && t && Array.isArray(t.items) ? t.items : void 0;
226
+ return a({
227
+ data: s === void 0 ? A(t, o) : s.map((e) => A(e, o)),
228
+ ...r === void 0 ? {} : { links: { next: k(n, r, e.cursorParam).replace(/^<|>; rel="next"$/g, "") } }
229
+ }, E);
230
+ };
231
+ //#endregion
232
+ export { i as S, o as _, j as a, r as b, S as c, v as d, p as f, u as g, a as h, D as i, _ as l, d as m, T as n, k as o, m as p, g as r, w as s, E as t, x as u, c as v, l as x, s as y };
package/dist/session.d.ts CHANGED
@@ -162,18 +162,18 @@ declare const SessionPayload_2: Schema.Struct<{
162
162
  v: Schema.Literal<[2]>;
163
163
  /** WHO, never WHAT-THEY-MAY-DO. `SubjectIdentity` has no `scopes` field. */
164
164
  subject: Schema.Union<[Schema.Struct<{
165
- id: typeof Schema.String;
166
165
  type: Schema.Literal<["user"]>;
166
+ id: typeof Schema.String;
167
167
  tenantId: typeof Schema.String;
168
168
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
169
169
  }>, Schema.Struct<{
170
- id: typeof Schema.String;
171
170
  type: Schema.Literal<["apiKey"]>;
171
+ id: typeof Schema.String;
172
172
  tenantId: typeof Schema.String;
173
173
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
174
174
  }>, Schema.Struct<{
175
- id: typeof Schema.String;
176
175
  type: Schema.Literal<["serviceAccount"]>;
176
+ id: typeof Schema.String;
177
177
  tenantId: typeof Schema.String;
178
178
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
179
179
  }>, Schema.Struct<{
@@ -182,8 +182,8 @@ declare const SessionPayload_2: Schema.Struct<{
182
182
  tenantId: Schema.NullOr<typeof Schema.String>;
183
183
  credentialRejected: Schema.optional<typeof Schema.String>;
184
184
  }>, Schema.Struct<{
185
- id: typeof Schema.String;
186
185
  type: Schema.Literal<["system"]>;
186
+ id: typeof Schema.String;
187
187
  tenantId: typeof Schema.Null;
188
188
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
189
189
  }>]>;
@@ -308,18 +308,18 @@ declare const Subject: Schema.Union<[Schema.Struct<{
308
308
  declare type Subject = typeof Subject.Type;
309
309
 
310
310
  declare const SubjectIdentity: Schema.Union<[Schema.Struct<{
311
- id: typeof Schema.String;
312
311
  type: Schema.Literal<["user"]>;
312
+ id: typeof Schema.String;
313
313
  tenantId: typeof Schema.String;
314
314
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
315
315
  }>, Schema.Struct<{
316
- id: typeof Schema.String;
317
316
  type: Schema.Literal<["apiKey"]>;
317
+ id: typeof Schema.String;
318
318
  tenantId: typeof Schema.String;
319
319
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
320
320
  }>, Schema.Struct<{
321
- id: typeof Schema.String;
322
321
  type: Schema.Literal<["serviceAccount"]>;
322
+ id: typeof Schema.String;
323
323
  tenantId: typeof Schema.String;
324
324
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
325
325
  }>, Schema.Struct<{
@@ -344,8 +344,8 @@ declare const SubjectIdentity: Schema.Union<[Schema.Struct<{
344
344
  */
345
345
  credentialRejected: Schema.optional<typeof Schema.String>;
346
346
  }>, Schema.Struct<{
347
- id: typeof Schema.String;
348
347
  type: Schema.Literal<["system"]>;
348
+ id: typeof Schema.String;
349
349
  tenantId: typeof Schema.Null;
350
350
  metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
351
351
  }>]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voltro/protocol",
3
- "version": "0.69.0",
3
+ "version": "0.70.0",
4
4
  "description": "The Voltro wire + plugin contract — defineQuery/Mutation/Action/Stream, definePlugin, sessions / JWT / API-keys, and the RPC protocol.",
5
5
  "keywords": [
6
6
  "voltro",
@@ -59,8 +59,8 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@effect/sql": "^0.52.1",
62
- "@voltro/database": "0.69.0",
63
- "@voltro/logger": "0.69.0",
62
+ "@voltro/database": "0.70.0",
63
+ "@voltro/logger": "0.70.0",
64
64
  "jose": "^6.2.10"
65
65
  },
66
66
  "peerDependencies": {
@@ -1,60 +0,0 @@
1
- import { Schema as e } from "effect";
2
- //#region src/idempotency.ts
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
- e ?? null,
5
- t ?? null,
6
- n,
7
- r
8
- ])}`, r = class extends e.TaggedError()("MutationConnectionRequired", { traceId: e.String }) {
9
- get message() {
10
- return "this mutation requires a live native WebSocket connection";
11
- }
12
- }, i = async (e, t, n, r, i) => {
13
- let a = await e.claim(t, n, i, r);
14
- return a === "claimed" ? { kind: "fresh" } : a.status === "completed" && a.response ? {
15
- kind: "replay",
16
- response: a.response
17
- } : { kind: "conflict" };
18
- }, a = (e, t, n, r, i) => e.complete(t, n, r, i), o = (e, t, n) => e.release(t, n), s = () => {
19
- let e = /* @__PURE__ */ new Map(), t = (e, t) => `${e}\u0000${t}`;
20
- return {
21
- get: async (n, r) => e.get(t(n, r)) ?? null,
22
- claim: async (n, r, i, a) => {
23
- let o = e.get(t(n, r));
24
- return o && i - o.createdAt < a ? o : (e.set(t(n, r), {
25
- scope: n,
26
- key: r,
27
- status: "in_flight",
28
- response: null,
29
- createdAt: i
30
- }), "claimed");
31
- },
32
- complete: async (n, r, i, a) => {
33
- e.set(t(n, r), {
34
- scope: n,
35
- key: r,
36
- status: "completed",
37
- response: i,
38
- createdAt: a
39
- });
40
- },
41
- release: async (n, r) => {
42
- e.delete(t(n, r));
43
- }
44
- };
45
- }, c = class extends e.TaggedError()("MutationInFlight", {
46
- traceId: e.String,
47
- retryAfterMs: e.Number
48
- }) {
49
- get message() {
50
- return `a request with this idempotency key is still in flight — replay the same key after ${this.retryAfterMs}ms`;
51
- }
52
- }, l = 1e3, u = /* @__PURE__ */ new Set(), d = (e) => {
53
- for (let t of u) try {
54
- t(e);
55
- } catch {}
56
- }, f = (e) => (u.add(e), () => {
57
- u.delete(e);
58
- });
59
- //#endregion
60
- export { c as a, a as c, n as d, r as i, t as l, f as n, i as o, l as r, o as s, d as t, s as u };