@voltro/protocol 0.84.0 → 0.86.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 (65) hide show
  1. package/CHANGELOG.md +1215 -0
  2. package/README.md +14 -0
  3. package/THIRD-PARTY-NOTICES.md +5 -89
  4. package/dist/apikey.d.ts +32 -34
  5. package/dist/approval.js +64 -0
  6. package/dist/approvalDescriptors.js +26 -0
  7. package/dist/auth.js +369 -0
  8. package/dist/boundedRing.js +27 -0
  9. package/dist/businessRule.js +11 -0
  10. package/dist/connection.js +73 -0
  11. package/dist/devActivity.js +4 -0
  12. package/dist/errorValue.js +21 -0
  13. package/dist/event.js +104 -0
  14. package/dist/idempotency.js +66 -0
  15. package/dist/identity.js +5 -9
  16. package/dist/index.d.ts +1494 -1366
  17. package/dist/index.js +42 -1411
  18. package/dist/inspect.d.ts +88 -88
  19. package/dist/inspect.js +14 -190
  20. package/dist/inspectBackfill.js +52 -0
  21. package/dist/inspectCommandRejection.js +21 -0
  22. package/dist/inspectProjection.js +133 -0
  23. package/dist/inspectStorageProjection.js +86 -0
  24. package/dist/inspectValueIdentity.js +4 -0
  25. package/dist/inspectWorkflowExecution.js +34 -0
  26. package/dist/inspectWorkflowQueuedStart.js +31 -0
  27. package/dist/jsonSchema.js +54 -0
  28. package/dist/jwt.d.ts +32 -34
  29. package/dist/outbox.js +10 -0
  30. package/dist/pairing.js +75 -0
  31. package/dist/plugin.js +61 -0
  32. package/dist/pluginNaming.js +32 -0
  33. package/dist/procedure.js +262 -0
  34. package/dist/publicApi.js +344 -0
  35. package/dist/reactivityChannel.js +34 -0
  36. package/dist/rest.d.ts +105 -57
  37. package/dist/rest.js +259 -437
  38. package/dist/restFormat.js +163 -0
  39. package/dist/rowEquality.js +31 -0
  40. package/dist/rowPatch.js +182 -0
  41. package/dist/schemaShape.js +67 -0
  42. package/dist/scopes.js +240 -0
  43. package/dist/serverErrorBus.js +15 -0
  44. package/dist/serviceCall.js +14 -0
  45. package/dist/session.d.ts +90 -96
  46. package/dist/session.js +13 -15
  47. package/dist/{sessionHeader-DriTZhmv.js → sessionHeader.js} +1 -1
  48. package/dist/storageAccess.js +14 -0
  49. package/dist/storeErrors.js +66 -0
  50. package/dist/storeScreenshots.js +90 -0
  51. package/dist/strictInput.js +27 -0
  52. package/dist/subscriptionEvent.js +37 -0
  53. package/dist/tenantSelection.js +40 -0
  54. package/dist/time.js +7 -0
  55. package/dist/undo.js +38 -0
  56. package/dist/validation.js +39 -0
  57. package/dist/webSocketGateway.js +10 -0
  58. package/dist/workflow.js +297 -0
  59. package/dist/workflowAccess.js +61 -0
  60. package/dist/workflowRestart.js +45 -0
  61. package/dist/workflowRetry.js +44 -0
  62. package/dist/workflowStartOutcome.js +30 -0
  63. package/package.json +4 -8
  64. package/dist/restFormat-EZ8k9ZcQ.js +0 -304
  65. package/dist/scopes-Di756ENh.js +0 -518
@@ -0,0 +1,133 @@
1
+ import { canonicalInspectValue as e } from "./inspectValueIdentity.js";
2
+ import { projectStorageReplicaAnswers as t } from "./inspectStorageProjection.js";
3
+ //#region src/inspectProjection.ts
4
+ var n = (e) => typeof e == "object" && e && !Array.isArray(e) ? e : void 0, r = (e) => Array.isArray(e) && e.every((e) => n(e) !== void 0) ? e : void 0, i = (e) => typeof e == "number" && Number.isFinite(e) ? e : 0, a = /* @__PURE__ */ new Set([
5
+ "counter",
6
+ "gauge",
7
+ "histogram",
8
+ "summary",
9
+ "frequency"
10
+ ]), o = (e) => {
11
+ let t = r(e);
12
+ return t?.every((e) => typeof e.name == "string" && a.has(String(e.type))) ? t : void 0;
13
+ }, s = (a) => {
14
+ let s = n(a), c = n(s?.data), l = r(c?.results);
15
+ if (!s || !c?.selection || !l) return a;
16
+ let u = l.filter((e) => e.status === "answered").map((e) => ({
17
+ replicaId: String(e.replicaId),
18
+ observation: n(e.observation),
19
+ data: n(e.observation)?.data
20
+ }));
21
+ if (u.length === 0) throw Error("None of the selected replicas answered. Check replica availability and retry.");
22
+ let d = u.map((e) => ({
23
+ ...e,
24
+ object: n(e.data)
25
+ })), f = (e) => d.reduce((t, n) => t + i(n.object?.[e]), 0), p = -Infinity;
26
+ for (let e of u) p = Math.max(p, i(e.observation?.capturedAt));
27
+ let m = {
28
+ capturedAt: p,
29
+ bufferSize: f("bufferSize"),
30
+ bufferCapacity: f("bufferCapacity")
31
+ }, h, g = u.every((e) => n(e.data)) ? t(u.map((e) => ({
32
+ replicaId: e.replicaId,
33
+ capturedAt: i(e.observation?.capturedAt),
34
+ data: n(e.data)
35
+ }))) : void 0;
36
+ if (g !== void 0) return {
37
+ ...s,
38
+ data: g
39
+ };
40
+ if (d.every((e) => r(e.object?.plugins))) {
41
+ let t = d.map((e) => r(e.object.plugins)), n = t[0].filter((n) => t.every((t) => t.some((t) => e(t) === e(n)))), i = new Set(n.map(e)), a = [...new Set(t.flatMap((t) => t.filter((t) => !i.has(e(t))).map((e) => String(e.name))))].sort();
42
+ h = {
43
+ capturedAt: p,
44
+ plugins: n,
45
+ inventoryConflicts: a
46
+ };
47
+ } else if (d.every((e) => r(e.object?.records))) {
48
+ let e = d.flatMap((e) => r(e.object?.records).map((t) => ({
49
+ ...t,
50
+ fields: {
51
+ ...n(t.fields),
52
+ "voltro.replica": e.replicaId
53
+ }
54
+ }))).sort((e, t) => i(e.ts) - i(t.ts));
55
+ h = {
56
+ ...m,
57
+ returned: e.length,
58
+ records: e
59
+ };
60
+ } else if (d.every((e) => r(e.object?.traces))) {
61
+ let e = /* @__PURE__ */ new Map();
62
+ for (let t of d) for (let i of r(t.object?.traces)) {
63
+ let a = String(i.traceId), o = (r(i.spans) ?? []).map((e) => ({
64
+ ...e,
65
+ attributes: {
66
+ ...n(e.attributes),
67
+ "voltro.replica": t.replicaId
68
+ }
69
+ })), s = e.get(a) ?? [];
70
+ s.push({
71
+ ...i,
72
+ spans: o
73
+ }), e.set(a, s);
74
+ }
75
+ let t = [...e.values()].map((e) => {
76
+ let t = e.flatMap((e) => r(e.spans) ?? []).sort((e, t) => i(e.startMs) - i(t.startMs)), n = e[0], a = i(n.startMs);
77
+ for (let t = 1; t < e.length; t += 1) {
78
+ let r = e[t], o = i(r.startMs);
79
+ o < a && (n = r, a = o);
80
+ }
81
+ let o = -Infinity, s = -Infinity, c = 0, l = !1, u = !1, d = !1;
82
+ for (let t of e) o = Math.max(o, i(t.startMs) + i(t.durationMs)), l ||= t.hasError === !0, u ||= t.deliveryCount !== void 0, d ||= t.lastDeliveryMs !== void 0, c += i(t.deliveryCount), s = Math.max(s, i(t.lastDeliveryMs));
83
+ return {
84
+ ...n,
85
+ startMs: a,
86
+ durationMs: Math.max(0, o - a),
87
+ spanCount: t.length,
88
+ hasError: l,
89
+ spans: t,
90
+ ...u ? { deliveryCount: c } : {},
91
+ ...d ? { lastDeliveryMs: s } : {}
92
+ };
93
+ }).sort((e, t) => t.startMs - e.startMs);
94
+ h = {
95
+ ...m,
96
+ returned: t.length,
97
+ traces: t
98
+ };
99
+ } else if (d.every((e) => r(e.object?.buckets) && typeof e.object?.windowMs == "number")) {
100
+ let e = -Infinity;
101
+ for (let t of d) e = Math.max(e, i(t.object?.windowMs));
102
+ h = {
103
+ capturedAt: p,
104
+ windowMs: e,
105
+ totalSamples: f("totalSamples"),
106
+ buckets: d.flatMap((e) => r(e.object?.buckets).map((t) => ({
107
+ ...t,
108
+ tag: `${String(t.tag)} [${e.replicaId}]`
109
+ })))
110
+ };
111
+ } else if (u.every((e) => o(e.data))) h = u.flatMap((e) => o(e.data).map((t) => ({
112
+ ...t,
113
+ labels: {
114
+ ...n(t.labels),
115
+ voltro_replica: e.replicaId
116
+ }
117
+ })));
118
+ else if (d.every((e) => o(e.object?.samples))) h = { samples: d.flatMap((e) => o(e.object?.samples).map((t) => ({
119
+ ...t,
120
+ labels: {
121
+ ...n(t.labels),
122
+ voltro_replica: e.replicaId
123
+ }
124
+ }))) };
125
+ else if (l.length === 1 && u.length === 1) h = u[0].data;
126
+ else throw Error("This view must compare observations per replica; its values cannot be safely combined.");
127
+ return {
128
+ ...s,
129
+ data: h
130
+ };
131
+ };
132
+ //#endregion
133
+ export { s as projectReplicaObservation };
@@ -0,0 +1,86 @@
1
+ import { canonicalInspectValue as e } from "./inspectValueIdentity.js";
2
+ //#region src/inspectStorageProjection.ts
3
+ var t = (e) => typeof e == "object" && e && !Array.isArray(e) ? e : void 0, n = (e) => Array.isArray(e) && e.every((e) => t(e)) ? e : void 0, r = (e) => {
4
+ let n = t(e);
5
+ if (n && ["catalogueId", "objectNamespace"].every((e) => typeof n[e] == "string" && /^[a-f0-9]{64}$/.test(n[e])) && typeof n.storageInstance == "string" && n.storageInstance.trim()) return {
6
+ catalogueId: n.catalogueId,
7
+ objectNamespace: n.objectNamespace,
8
+ storageInstance: n.storageInstance
9
+ };
10
+ }, i = (e) => {
11
+ if (typeof e != "number" || !Number.isSafeInteger(e) || e < 0) throw Error("Storage observation contains an invalid counter.");
12
+ return e;
13
+ }, a = (e, t) => i(e + t), o = (o) => {
14
+ if (!o.length || !o.every((e) => r(e.data.source))) return;
15
+ let s = /* @__PURE__ */ new Map();
16
+ for (let t of o) {
17
+ let n = r(t.data.source), i = s.get(n.catalogueId);
18
+ if (i) {
19
+ if (e(i.source) !== e(n) || e(i.data) !== e(t.data)) throw Error("Replicas returned different snapshots for the same storage catalogue. Compare the replicas or retry the read; counters have not been combined.");
20
+ i.replicaIds.push(t.replicaId), i.capturedAt = Math.max(i.capturedAt, t.capturedAt);
21
+ } else s.set(n.catalogueId, {
22
+ source: n,
23
+ data: t.data,
24
+ replicaIds: [t.replicaId],
25
+ capturedAt: t.capturedAt
26
+ });
27
+ }
28
+ let c = [...s.values()].sort((e, t) => e.source.catalogueId.localeCompare(t.source.catalogueId)), l = c.map((e) => ({
29
+ ...e.source,
30
+ replicaIds: [...new Set(e.replicaIds)].sort(),
31
+ capturedAt: e.capturedAt
32
+ }));
33
+ if (c.every((e) => n(e.data.refs) && t(e.data.page))) {
34
+ let e = c.map((e) => t(e.data.page));
35
+ if (e.some((t) => t.search !== e[0].search || t.offset !== e[0].offset)) throw Error("Storage replica pages do not describe the same query.");
36
+ let r = i(e[0].offset), o = e.some((e) => e.nextOffset !== null) ? a(r, 50) : null;
37
+ if (e.some((e) => e.nextOffset !== null && e.nextOffset !== o)) throw Error("Storage replica pages contain an invalid continuation.");
38
+ return {
39
+ sources: l,
40
+ refs: c.flatMap((e) => n(e.data.refs).map((t) => ({
41
+ ...t,
42
+ source: {
43
+ ...e.source,
44
+ replicaIds: [...new Set(e.replicaIds)].sort()
45
+ }
46
+ }))).sort((e, t) => String(t.createdAt).localeCompare(String(e.createdAt)) || String(t.id).localeCompare(String(e.id)) || e.source.catalogueId.localeCompare(t.source.catalogueId)),
47
+ page: {
48
+ search: e[0].search,
49
+ offset: r,
50
+ nextOffset: o
51
+ }
52
+ };
53
+ }
54
+ if (c.every((e) => typeof e.data.provider == "string" && typeof e.data.bucket == "string" && t(e.data.byTenant) && t(e.data.visibility))) {
55
+ let e = /* @__PURE__ */ new Map(), n = 0, r = 0;
56
+ for (let o of c) {
57
+ for (let [n, r] of Object.entries(t(o.data.byTenant))) {
58
+ let o = t(r);
59
+ if (!o) throw Error("Storage tenant observation is unreadable.");
60
+ let s = e.get(n) ?? {
61
+ count: 0,
62
+ bytes: 0
63
+ };
64
+ e.set(n, {
65
+ count: a(s.count, i(o.count)),
66
+ bytes: a(s.bytes, i(o.bytes))
67
+ });
68
+ }
69
+ let s = t(o.data.visibility);
70
+ n = a(n, i(s.public)), r = a(r, i(s.private));
71
+ }
72
+ let o = [...new Set(c.map((e) => String(e.data.provider)))].sort(), s = [...new Set(c.map((e) => String(e.data.bucket)))].sort();
73
+ return {
74
+ sources: l,
75
+ provider: o.length === 1 ? o[0] : o.join(", "),
76
+ bucket: s.length === 1 ? s[0] : s.join(", "),
77
+ byTenant: Object.fromEntries(e),
78
+ visibility: {
79
+ public: n,
80
+ private: r
81
+ }
82
+ };
83
+ }
84
+ };
85
+ //#endregion
86
+ export { o as projectStorageReplicaAnswers };
@@ -0,0 +1,4 @@
1
+ //#region src/inspectValueIdentity.ts
2
+ var e = (e) => JSON.stringify(t(e)), t = (e) => Array.isArray(e) ? e.map(t) : typeof e == "object" && e ? Object.fromEntries(Object.entries(e).sort(([e], [t]) => e.localeCompare(t)).map(([e, n]) => [e, t(n)])) : e;
3
+ //#endregion
4
+ export { e as canonicalInspectValue };
@@ -0,0 +1,34 @@
1
+ import { Schema as e } from "effect";
2
+ //#region src/inspectWorkflowExecution.ts
3
+ var t = e.NonEmptyString.pipe(e.check(e.isMaxLength(1024)), e.check(e.makeFilter((e) => e.trim().length > 0 && !/[\u0000-\u001f\u007f]/.test(e)))), n = e.Struct({
4
+ workflowName: t,
5
+ executionId: t
6
+ }), r = n.fields, i = e.Union([
7
+ e.Struct({
8
+ ...r,
9
+ kind: e.Literal("not-observed")
10
+ }),
11
+ e.Struct({
12
+ ...r,
13
+ kind: e.Literal("pending")
14
+ }),
15
+ e.Struct({
16
+ ...r,
17
+ kind: e.Literal("delivery-failed")
18
+ }),
19
+ e.Struct({
20
+ ...r,
21
+ kind: e.Literal("suspended")
22
+ }),
23
+ e.Struct({
24
+ ...r,
25
+ kind: e.Literal("completed"),
26
+ outcome: e.Literals([
27
+ "succeeded",
28
+ "failed",
29
+ "cancelled"
30
+ ])
31
+ })
32
+ ]);
33
+ //#endregion
34
+ export { i as InspectWorkflowExecutionObservationSchema, n as InspectWorkflowExecutionTargetSchema };
@@ -0,0 +1,31 @@
1
+ import { Schema as e } from "effect";
2
+ //#region src/inspectWorkflowQueuedStart.ts
3
+ var t = e.NonEmptyString.pipe(e.check(e.isMaxLength(1024)), e.check(e.makeFilter((e) => e.trim().length > 0 && !/[\u0000-\u001f\u007f]/.test(e)))), n = e.Struct({
4
+ workflowName: t,
5
+ receiptId: t,
6
+ tenantId: e.NullOr(t)
7
+ }), r = n.fields, i = e.Union([
8
+ e.Struct({
9
+ ...r,
10
+ kind: e.Literal("pending")
11
+ }),
12
+ e.Struct({
13
+ ...r,
14
+ kind: e.Literal("accepted"),
15
+ executionId: t
16
+ }),
17
+ e.Struct({
18
+ ...r,
19
+ kind: e.Literal("not-executed"),
20
+ reason: e.Literals([
21
+ "dropped",
22
+ "skipped",
23
+ "superseded",
24
+ "cancelled",
25
+ "abandoned",
26
+ "rejected"
27
+ ])
28
+ })
29
+ ]);
30
+ //#endregion
31
+ export { i as InspectWorkflowQueuedStartObservationSchema, n as InspectWorkflowQueuedStartTargetSchema };
@@ -0,0 +1,54 @@
1
+ import { Schema as e, SchemaAST as t } from "effect";
2
+ //#region src/jsonSchema.ts
3
+ var n = (e) => typeof e == "object" && !!e && !Array.isArray(e), r = (e, t = /* @__PURE__ */ new Map()) => {
4
+ let n = t.get(e);
5
+ if (n !== void 0) return n;
6
+ let r = i(e, t);
7
+ return t.set(e, r), r;
8
+ }, i = (n, i) => n.encoding === void 0 ? t.isNumber(n) ? e.make(n).check(e.isFinite()).ast : t.isObjects(n) ? new t.Objects(n.propertySignatures.map((e) => new t.PropertySignature(e.name, r(e.type, i))), n.indexSignatures.map((e) => new t.IndexSignature(e.parameter, r(e.type, i))), n.annotations, n.checks, void 0, n.context) : t.isArrays(n) ? new t.Arrays(n.isMutable, n.elements.map((e) => r(e, i)), n.rest.map((e) => r(e, i)), n.annotations, n.checks, void 0, n.context) : t.isUnion(n) ? new t.Union(n.types.map((e) => r(e, i)), n.options, n.annotations, n.checks, void 0, n.context) : t.isSuspend(n) ? new t.Suspend(() => r(n.thunk(), i), n.annotations, n.checks, void 0, n.context) : n : n, a = (e) => {
9
+ if (Array.isArray(e)) return e.map(a);
10
+ if (!n(e)) return e;
11
+ let t = e.not;
12
+ if (n(t) && t.type === "null" && Object.keys(e).length === 1) return {
13
+ type: "object",
14
+ properties: {},
15
+ additionalProperties: !1
16
+ };
17
+ let r = e.anyOf;
18
+ if (Array.isArray(r)) {
19
+ if (r.length === 2) {
20
+ let t = r.find((e) => n(e) && e.type === "number"), i = r.find((e) => n(e) && e.type === "string" && Array.isArray(e.enum) && e.enum.includes("Infinity"));
21
+ if (n(t) && i !== void 0) {
22
+ let { anyOf: n, ...r } = e;
23
+ return a({
24
+ ...r,
25
+ ...t
26
+ });
27
+ }
28
+ }
29
+ if (r.length === 1 && n(r[0])) {
30
+ let { anyOf: t, ...n } = e;
31
+ return a({
32
+ ...n,
33
+ ...r[0]
34
+ });
35
+ }
36
+ }
37
+ let i = {};
38
+ for (let [t, n] of Object.entries(e)) i[t] = a(n);
39
+ return i;
40
+ }, o = (t, n = {}) => {
41
+ let i = e.make(r(t.ast)), o = e.toJsonSchemaDocument(i, n.closed === !1 ? {} : { onExcessProperty: "error" });
42
+ return {
43
+ schema: a(o.schema),
44
+ definitions: a(o.definitions)
45
+ };
46
+ }, s = (e, t = {}) => {
47
+ let { schema: n, definitions: r } = o(e, t);
48
+ return Object.keys(r).length === 0 ? n : {
49
+ ...n,
50
+ $defs: r
51
+ };
52
+ };
53
+ //#endregion
54
+ export { r as finiteNumberView, o as jsonSchemaDocumentOf, s as jsonSchemaOf, a as plainJsonSchema };
package/dist/jwt.d.ts CHANGED
@@ -289,33 +289,31 @@ declare type StrategyResolution = {
289
289
  readonly reason: string;
290
290
  };
291
291
 
292
- declare const Subject: Schema.Union<[Schema.Struct<{
293
- type: Schema.Literal<["user"]>;
294
- id: typeof Schema.String;
295
- tenantId: typeof Schema.String;
296
- scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
297
- metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
292
+ declare const Subject: Schema.Union<readonly [Schema.Struct<{
293
+ readonly type: Schema.Literal<"user">;
294
+ readonly id: Schema.String;
295
+ readonly tenantId: Schema.String;
296
+ readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
297
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
298
298
  }>, Schema.Struct<{
299
- type: Schema.Literal<["apiKey"]>;
300
- id: typeof Schema.String;
301
- tenantId: typeof Schema.String;
302
- scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
303
- metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
299
+ readonly type: Schema.Literal<"apiKey">;
300
+ readonly id: Schema.String;
301
+ readonly tenantId: Schema.String;
302
+ readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
303
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
304
304
  }>, Schema.Struct<{
305
- type: Schema.Literal<["serviceAccount"]>;
306
- id: typeof Schema.String;
307
- tenantId: typeof Schema.String;
305
+ readonly type: Schema.Literal<"serviceAccount">;
306
+ readonly id: Schema.String;
307
+ readonly tenantId: Schema.String;
308
308
  /** Application actor used for audit columns; null means machine work with
309
309
  * no application actor. Identity only, never a permission grant. */
310
- auditActorId: Schema.optionalWith<Schema.NullOr<typeof Schema.String>, {
311
- exact: true;
312
- }>;
313
- scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
314
- metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
310
+ readonly auditActorId: Schema.optionalKey<Schema.NullOr<Schema.String>>;
311
+ readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
312
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
315
313
  }>, Schema.Struct<{
316
- type: Schema.Literal<["anonymous"]>;
317
- id: typeof Schema.Null;
318
- tenantId: Schema.NullOr<typeof Schema.String>;
314
+ readonly type: Schema.Literal<"anonymous">;
315
+ readonly id: Schema.Null;
316
+ readonly tenantId: Schema.NullOr<Schema.String>;
319
317
  /**
320
318
  * Set when this caller PRESENTED a credential and it was rejected — an
321
319
  * expired token above all. Absent when they presented none.
@@ -332,21 +330,21 @@ declare const Subject: Schema.Union<[Schema.Struct<{
332
330
  * must not break an `openAccess` procedure that needs no session at all. The
333
331
  * fact travels, and only a guard that actually refuses spends it.
334
332
  */
335
- credentialRejected: Schema.optional<typeof Schema.String>;
333
+ readonly credentialRejected: Schema.optional<Schema.String>;
336
334
  }>, Schema.Struct<{
337
- type: Schema.Literal<["system"]>;
338
- id: typeof Schema.String;
339
- tenantId: typeof Schema.Null;
340
- scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
341
- metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
335
+ readonly type: Schema.Literal<"system">;
336
+ readonly id: Schema.String;
337
+ readonly tenantId: Schema.Null;
338
+ readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
339
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
342
340
  }>, Schema.Struct<{
343
- type: Schema.Literal<["service"]>;
344
- id: typeof Schema.String;
341
+ readonly type: Schema.Literal<"service">;
342
+ readonly id: Schema.String;
345
343
  /** The calling app's name, as the callee lists it in `serviceCallers`. */
346
- service: typeof Schema.String;
347
- tenantId: typeof Schema.Null;
348
- scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
349
- metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
344
+ readonly service: Schema.String;
345
+ readonly tenantId: Schema.Null;
346
+ readonly scopes: Schema.optional<Schema.$Array<Schema.String>>;
347
+ readonly metadata: Schema.optional<Schema.$Record<Schema.String, Schema.Unknown>>;
350
348
  }>]>;
351
349
 
352
350
  declare type Subject = typeof Subject.Type;
package/dist/outbox.js ADDED
@@ -0,0 +1,10 @@
1
+ //#region src/outbox.ts
2
+ function e(e, t) {
3
+ if (typeof e != "object" || !e) throw Error(`Outbox handler ${t}: definition must be an object`);
4
+ let n = e;
5
+ if (typeof n.effect != "string" || n.effect.trim() === "") throw Error(`Outbox handler ${t}: effect must be a non-empty string`);
6
+ if (typeof n.handler != "function") throw Error(`Outbox handler ${t}: handler must be a function`);
7
+ if (n.maxAttempts !== void 0 && (typeof n.maxAttempts != "number" || !Number.isSafeInteger(n.maxAttempts) || n.maxAttempts < 1)) throw Error(`Outbox handler ${t}: maxAttempts must be a positive safe integer`);
8
+ }
9
+ //#endregion
10
+ export { e as validateOutboxHandlerDefinition };
@@ -0,0 +1,75 @@
1
+ //#region src/pairing.ts
2
+ var e = "voltro-dev", t = "pair", n = "voltro:pairing", r = (e) => {
3
+ try {
4
+ let t = new URL(e);
5
+ return t.protocol === "http:" || t.protocol === "https:";
6
+ } catch {
7
+ return !1;
8
+ }
9
+ }, i = (e) => {
10
+ try {
11
+ let t = new URL(e).hostname;
12
+ return t === "localhost" || t === "127.0.0.1" || t === "::1" || t === "[::1]";
13
+ } catch {
14
+ return !1;
15
+ }
16
+ }, a = (n) => {
17
+ if (!r(n.api)) throw Error(`pairingLink: api must be an http(s) url, got ${JSON.stringify(n.api)}`);
18
+ if (i(n.api)) throw Error("pairingLink: api must be the LAN address — a device cannot reach localhost on this machine");
19
+ if (!/^[A-Za-z0-9_-]+$/.test(n.name)) throw Error(`pairingLink: name must be a plain identifier, got ${JSON.stringify(n.name)}`);
20
+ let a = new URLSearchParams({
21
+ api: n.api,
22
+ name: n.name
23
+ });
24
+ return n.token !== void 0 && n.token.length > 0 && a.set("token", n.token), `${e}://${t}?${a.toString()}`;
25
+ }, o = (e) => {
26
+ let t;
27
+ try {
28
+ t = new URL(e);
29
+ } catch {
30
+ return null;
31
+ }
32
+ if (t.protocol !== "voltro-dev:" || (t.host || t.pathname.replace(/^\/+/, "")) !== "pair") return null;
33
+ let n = t.searchParams.get("api") ?? "", a = t.searchParams.get("name") ?? "", o = t.searchParams.get("token");
34
+ return !r(n) || i(n) || !/^[A-Za-z0-9_-]+$/.test(a) ? null : {
35
+ api: n,
36
+ name: a,
37
+ ...o !== null && o.length > 0 ? { token: o } : {}
38
+ };
39
+ }, s = (e) => "getItem" in e ? {
40
+ get: async (t) => e.getItem(t),
41
+ set: async (t, n) => {
42
+ await e.setItem(t, n);
43
+ },
44
+ remove: e.removeItem ? async (t) => {
45
+ await e.removeItem(t);
46
+ } : null
47
+ } : {
48
+ get: async (t) => e.get(t),
49
+ set: async (t, n) => {
50
+ await e.set(t, n);
51
+ },
52
+ remove: e.remove ? async (t) => {
53
+ await e.remove(t);
54
+ } : null
55
+ }, c = async (e, t) => {
56
+ await s(e).set(n, JSON.stringify(t));
57
+ }, l = async (e) => {
58
+ let t = await s(e).get(n);
59
+ if (t === null || t === "") return null;
60
+ try {
61
+ let e = JSON.parse(t);
62
+ return typeof e.api != "string" || typeof e.name != "string" || !r(e.api) ? null : {
63
+ api: e.api,
64
+ name: e.name,
65
+ ...typeof e.token == "string" && e.token.length > 0 ? { token: e.token } : {}
66
+ };
67
+ } catch {
68
+ return null;
69
+ }
70
+ }, u = async (e) => {
71
+ let t = s(e);
72
+ t.remove ? await t.remove(n) : await t.set(n, "");
73
+ };
74
+ //#endregion
75
+ export { t as PAIRING_HOST, e as PAIRING_SCHEME, n as PAIRING_STORAGE_KEY, c as applyPairing, u as clearPairing, a as pairingLink, o as parsePairingLink, l as readPairing };
package/dist/plugin.js ADDED
@@ -0,0 +1,61 @@
1
+ import { Context as e, Layer as t } from "effect";
2
+ //#region src/plugin.ts
3
+ var n = (e) => e, r = (e) => e, i = (e) => {
4
+ let t = e.alias?.trim(), n = e.instance?.trim(), r = t !== void 0 && t !== "" ? t : e.base;
5
+ return n !== void 0 && n !== "" ? `${r}#${n}` : r;
6
+ }, a = (e) => {
7
+ if (e.length !== 0) return (t, n) => e.reduceRight((e, t) => t(e, n), t);
8
+ }, o = (n, r) => {
9
+ let i = e.Service(n);
10
+ return {
11
+ Tag: i,
12
+ Live: t.succeed(i, r)
13
+ };
14
+ }, s = (e, t, n) => {
15
+ if (!t) return { ok: !0 };
16
+ let r = n === void 0 ? null : c(n);
17
+ if (!r) return {
18
+ ok: !0,
19
+ unverified: `plugin "${e}" requires framework ${t}, but the running framework version is ${n === void 0 ? "unknown" : `unreadable ("${n}")`} — not checked.`
20
+ };
21
+ let i = t.trim();
22
+ if (i === "*" || i === "") return { ok: !0 };
23
+ let a = i.split(/\s+/);
24
+ for (let i of a) if (!u(i, r)) return {
25
+ ok: !1,
26
+ reason: `plugin "${e}" requires framework ${t}, running ${n}`
27
+ };
28
+ return { ok: !0 };
29
+ }, c = (e) => {
30
+ let t = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9a-zA-Z.-]+))?$/.exec(e.trim());
31
+ return t ? {
32
+ major: Number(t[1]),
33
+ minor: Number(t[2]),
34
+ patch: Number(t[3]),
35
+ pre: t[4] ?? ""
36
+ } : null;
37
+ }, l = (e, t) => e.major === t.major ? e.minor === t.minor ? e.patch === t.patch ? e.pre && !t.pre ? -1 : !e.pre && t.pre ? 1 : e.pre && t.pre ? e.pre < t.pre ? -1 : +(e.pre > t.pre) : 0 : e.patch - t.patch : e.minor - t.minor : e.major - t.major, u = (e, t) => {
38
+ if (e === "*") return !0;
39
+ if (e.startsWith("^")) {
40
+ let n = c(e.slice(1));
41
+ return !n || t.major !== n.major ? !1 : l(t, n) >= 0;
42
+ }
43
+ if (e.startsWith("~")) {
44
+ let n = c(e.slice(1));
45
+ return !n || t.major !== n.major || t.minor !== n.minor ? !1 : l(t, n) >= 0;
46
+ }
47
+ let n = /^(>=|<=|>|<)(.+)$/.exec(e);
48
+ if (n) {
49
+ let e = n[1], r = c(n[2]);
50
+ if (!r) return !1;
51
+ let i = l(t, r);
52
+ if (e === ">=") return i >= 0;
53
+ if (e === "<=") return i <= 0;
54
+ if (e === ">") return i > 0;
55
+ if (e === "<") return i < 0;
56
+ }
57
+ let r = c(e);
58
+ return r ? l(t, r) === 0 : !1;
59
+ };
60
+ //#endregion
61
+ export { s as checkFrameworkCompat, a as composeRpcInterceptors, n as definePlugin, r as definePluginRoute, o as definePluginService, i as pluginInstanceName };
@@ -0,0 +1,32 @@
1
+ //#region src/pluginNaming.ts
2
+ var e = (e) => {
3
+ let t = e.startsWith("@") ? e.replace(/^@[^/]+\//, "") : e;
4
+ return (t.startsWith("plugin-") ? t.slice(7) : t).replace(/-([a-zA-Z0-9])/g, (e, t) => t.toUpperCase());
5
+ }, t = (e) => {
6
+ let t = e.startsWith("@") ? e.replace(/^@[^/]+\//, "") : e;
7
+ return (t.startsWith("plugin-") ? t.slice(7) : t).replace(/#/g, "--").replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
8
+ }, n = Symbol.for("@voltro/protocol/pluginAliases"), r = () => {
9
+ let e = globalThis, t = e[n];
10
+ if (t instanceof Map) return t;
11
+ let r = /* @__PURE__ */ new Map();
12
+ return e[n] = r, r;
13
+ }, i = (e) => {
14
+ let t = r();
15
+ for (let [n, r] of Object.entries(e)) {
16
+ if (r === "") continue;
17
+ let e = t.get(n);
18
+ e === void 0 ? t.set(n, /* @__PURE__ */ new Set([r])) : e.add(r);
19
+ }
20
+ }, a = () => {
21
+ r().clear();
22
+ }, o = (t, n) => {
23
+ let i = r().get(t);
24
+ if (i === void 0 || i.size === 0) return `${e(t)}.${n}`;
25
+ if (i.size === 1) for (let e of i) return `${e}.${n}`;
26
+ let a, o = 0;
27
+ for (let e of i) e.includes("#") || (a = e, o++);
28
+ if (o === 1) return `${a}.${n}`;
29
+ throw Error(`[voltro] ${t} is installed more than once (${[...i].sort().join(", ")}) and no single install is the primary one, so a plugin hook cannot tell which of them it addresses. Call the route by its full tag instead — e.g. useSubscription(api, '${[...i].sort()[0]}.${n}').`);
30
+ };
31
+ //#endregion
32
+ export { e as pluginAlias, t as pluginSlug, o as pluginTag, i as registerPluginAliases, a as resetPluginAliases };