stitchkit 0.77.0 → 0.79.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 (99) hide show
  1. package/dist/agent-runtime-browser.js +53 -581
  2. package/dist/agent-runtime-coding-tools.js +6 -5
  3. package/dist/agent-runtime-harness.js +20 -93
  4. package/dist/agent-runtime-openrouter.js +1 -1
  5. package/dist/agent-runtime.js +65 -61
  6. package/dist/application/decisions.d.ts +28 -25
  7. package/dist/application/decisions.d.ts.map +1 -1
  8. package/dist/application/kernel.d.ts +2 -0
  9. package/dist/application/kernel.d.ts.map +1 -1
  10. package/dist/application/keyspace.d.ts +11 -1
  11. package/dist/application/keyspace.d.ts.map +1 -1
  12. package/dist/application/schedule.d.ts.map +1 -1
  13. package/dist/application/schemas.d.ts +2 -0
  14. package/dist/application/schemas.d.ts.map +1 -1
  15. package/dist/application/server-resource.d.ts.map +1 -1
  16. package/dist/application/watch-hub.d.ts.map +1 -1
  17. package/dist/application-diagnostic-journal.d.ts +21 -0
  18. package/dist/application-diagnostic-journal.d.ts.map +1 -0
  19. package/dist/application-diagnostic-journal.js +632 -0
  20. package/dist/application-opentelemetry.js +3 -2
  21. package/dist/application-schemas.js +14 -98
  22. package/dist/application.d.ts +1 -2
  23. package/dist/application.d.ts.map +1 -1
  24. package/dist/application.js +155 -882
  25. package/dist/cli.js +13 -11
  26. package/dist/contract/index.js +15 -10
  27. package/dist/files/boundary.d.ts.map +1 -1
  28. package/dist/files.js +1 -1
  29. package/dist/{index-7b188kmz.js → index-2qzskm8h.js} +15 -1
  30. package/dist/{index-k2zczx1g.js → index-2rwwmr7v.js} +3 -3
  31. package/dist/{index-8eywc9zv.js → index-3gye9wzb.js} +6 -3
  32. package/dist/index-4fpa9dy2.js +51 -0
  33. package/dist/{index-7qy2ex0m.js → index-5mtc969c.js} +2 -2
  34. package/dist/index-5s3zajp8.js +192 -0
  35. package/dist/{index-3cwck0rm.js → index-6s7n2v50.js} +60 -374
  36. package/dist/{index-s4c8wy8m.js → index-758zx2ha.js} +11 -90
  37. package/dist/{index-qyrqwr4c.js → index-77fekveh.js} +4 -1
  38. package/dist/{index-58jzmnn4.js → index-7ag81v2f.js} +355 -34
  39. package/dist/index-7gnkny4z.js +326 -0
  40. package/dist/index-7zbps32p.js +89 -0
  41. package/dist/index-85vfqd7m.js +135 -0
  42. package/dist/{index-m668wzyc.js → index-9s6z8vgf.js} +17 -141
  43. package/dist/{index-bfcpjw20.js → index-actkayzn.js} +7 -3
  44. package/dist/index-b9aefrqd.js +20 -0
  45. package/dist/index-dre2ywck.js +48 -0
  46. package/dist/{index-nemjkxjp.js → index-dwf1f2ap.js} +16 -12
  47. package/dist/{index-wwst0td5.js → index-dx9xehwt.js} +1 -1
  48. package/dist/{index-ezmn6ac6.js → index-dxesg10d.js} +4 -4
  49. package/dist/{index-aczggrty.js → index-dxjjv399.js} +2 -2
  50. package/dist/{index-jqtsc9mj.js → index-egaabxkz.js} +3 -3
  51. package/dist/{index-vc1b0b1b.js → index-evcnmsc3.js} +49 -8
  52. package/dist/{index-nt1mp8km.js → index-fxz0v7vg.js} +84 -84
  53. package/dist/index-h4pj6fta.js +87 -0
  54. package/dist/{index-1rxswfbv.js → index-hb5pf3s4.js} +1 -1
  55. package/dist/{index-t8qyvrvg.js → index-k9ay6v6d.js} +21 -272
  56. package/dist/index-kzfs85xp.js +9 -0
  57. package/dist/{index-vbf2p6me.js → index-m9kzax52.js} +91 -89
  58. package/dist/{index-22by16v6.js → index-mgtxfe6b.js} +1 -1
  59. package/dist/index-p7hgdyhb.js +22 -0
  60. package/dist/index-pq95qkbf.js +0 -0
  61. package/dist/index-t0z5p5w6.js +318 -0
  62. package/dist/{index-s2rchahr.js → index-vwp69871.js} +13 -11
  63. package/dist/index-wc4x00bn.js +103 -0
  64. package/dist/{index-da1aqnhb.js → index-xcetq6j3.js} +8 -6
  65. package/dist/{index-f6n5n7nz.js → index-y01f4223.js} +33 -126
  66. package/dist/{index-35z5h2ty.js → index-ywd0y6m1.js} +18 -218
  67. package/dist/index.js +65 -1588
  68. package/dist/internal/deadline.d.ts +17 -0
  69. package/dist/internal/deadline.d.ts.map +1 -0
  70. package/dist/live.js +15 -89
  71. package/dist/node.js +17 -15
  72. package/dist/observability/context.d.ts.map +1 -1
  73. package/dist/observability/index.js +7 -6
  74. package/dist/primitives.js +5 -2
  75. package/dist/react.js +1 -1
  76. package/dist/remote.js +7 -6
  77. package/dist/server/event-bus.d.ts.map +1 -1
  78. package/dist/server/index.js +26 -38
  79. package/dist/telegram.js +1 -1
  80. package/dist/testing.js +86 -97
  81. package/dist/tool-invoker.js +11 -9
  82. package/dist/tools/async-operation-contract.d.ts +61 -0
  83. package/dist/tools/async-operation-contract.d.ts.map +1 -0
  84. package/dist/tools/async-operation.d.ts +2 -47
  85. package/dist/tools/async-operation.d.ts.map +1 -1
  86. package/dist/tools/view-file-contract.d.ts +98 -0
  87. package/dist/tools/view-file-contract.d.ts.map +1 -0
  88. package/dist/tools/view-file.d.ts +4 -83
  89. package/dist/tools/view-file.d.ts.map +1 -1
  90. package/dist/tools-contract.d.ts +29 -0
  91. package/dist/tools-contract.d.ts.map +1 -0
  92. package/dist/tools-contract.js +24 -0
  93. package/dist/tools.d.ts +3 -3
  94. package/dist/tools.d.ts.map +1 -1
  95. package/dist/tools.js +59 -95
  96. package/llms-full.txt +146 -14
  97. package/package.json +14 -7
  98. package/dist/index-ksp6e2ye.js +0 -24
  99. package/dist/index-vj3vvpaa.js +0 -307
@@ -3,7 +3,89 @@ import {
3
3
  } from "./index-0w9abg87.js";
4
4
  import {
5
5
  isRecord
6
- } from "./index-qyrqwr4c.js";
6
+ } from "./index-77fekveh.js";
7
+
8
+ // src/internal/random-hex.ts
9
+ function randomHex(bytes) {
10
+ const arr = new Uint8Array(bytes);
11
+ crypto.getRandomValues(arr);
12
+ let hex = "";
13
+ for (const byte of arr)
14
+ hex += byte.toString(16).padStart(2, "0");
15
+ return hex;
16
+ }
17
+
18
+ // src/observability/trace.ts
19
+ var TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(.*)$/i;
20
+ function createTraceContext() {
21
+ return { traceId: randomHex(16), spanId: randomHex(8) };
22
+ }
23
+ function parseTraceparent(header) {
24
+ if (!header)
25
+ return null;
26
+ const match = TRACEPARENT_RE.exec(header.trim());
27
+ if (!match?.[1] || !match[2] || !match[3] || !match[4] || match[5] === undefined)
28
+ return null;
29
+ const version = match[1].toLowerCase();
30
+ if (version === "ff")
31
+ return null;
32
+ const suffix = match[5];
33
+ if (version === "00" ? suffix !== "" : suffix !== "" && !/^(?:-[0-9a-f]{2,})+$/i.test(suffix)) {
34
+ return null;
35
+ }
36
+ const traceId = match[2].toLowerCase();
37
+ const parentSpanId = match[3].toLowerCase();
38
+ const traceFlags = match[4].toLowerCase();
39
+ if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
40
+ return null;
41
+ return { traceId, spanId: randomHex(8), parentSpanId, traceFlags };
42
+ }
43
+ function formatTraceparent(ctx) {
44
+ return `00-${ctx.traceId}-${ctx.spanId}-${ctx.traceFlags ?? "01"}`;
45
+ }
46
+ function resolveTraceContext(req) {
47
+ return parseTraceparent(req.headers.get("traceparent")) ?? createTraceContext();
48
+ }
49
+ function childSpan(parent) {
50
+ return {
51
+ traceId: parent.traceId,
52
+ spanId: randomHex(8),
53
+ parentSpanId: parent.spanId,
54
+ ...parent.tracestate !== undefined && { tracestate: parent.tracestate },
55
+ ...parent.baggage !== undefined && { baggage: parent.baggage },
56
+ ...parent.traceFlags !== undefined && { traceFlags: parent.traceFlags }
57
+ };
58
+ }
59
+ var encoder = new TextEncoder;
60
+ function boundedPropagationValue(value, maxBytes, maxMembers) {
61
+ if (typeof value !== "string")
62
+ return;
63
+ const trimmed = value.trim();
64
+ if (!trimmed || encoder.encode(trimmed).byteLength > maxBytes)
65
+ return;
66
+ for (const character of trimmed) {
67
+ const code = character.charCodeAt(0);
68
+ if (code <= 31 || code === 127)
69
+ return;
70
+ }
71
+ const members = trimmed.split(",");
72
+ if (members.length > maxMembers || members.some((member) => !member.trim())) {
73
+ return;
74
+ }
75
+ return trimmed;
76
+ }
77
+ function resolvePropagationContext(metadata, fallback) {
78
+ const traceparent = metadata?.traceparent;
79
+ const parsed = typeof traceparent === "string" ? parseTraceparent(traceparent) : null;
80
+ const trace = traceparent === undefined ? fallback ?? createTraceContext() : parsed ?? createTraceContext();
81
+ const tracestate = parsed ? boundedPropagationValue(metadata?.tracestate, 512, 32) : undefined;
82
+ const baggage = boundedPropagationValue(metadata?.baggage, 8192, 180);
83
+ return {
84
+ ...trace,
85
+ ...tracestate !== undefined && { tracestate },
86
+ ...baggage !== undefined && { baggage }
87
+ };
88
+ }
7
89
 
8
90
  // src/internal/errors.ts
9
91
  import { z } from "zod";
@@ -109,86 +191,4 @@ function validateDeclaredOutput(schema, data, onStripped) {
109
191
  return validateHandlerOutput(schema, data, onStripped);
110
192
  }
111
193
 
112
- // src/internal/random-hex.ts
113
- function randomHex(bytes) {
114
- const arr = new Uint8Array(bytes);
115
- crypto.getRandomValues(arr);
116
- let hex = "";
117
- for (const byte of arr)
118
- hex += byte.toString(16).padStart(2, "0");
119
- return hex;
120
- }
121
-
122
- // src/observability/trace.ts
123
- var TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(.*)$/i;
124
- function createTraceContext() {
125
- return { traceId: randomHex(16), spanId: randomHex(8) };
126
- }
127
- function parseTraceparent(header) {
128
- if (!header)
129
- return null;
130
- const match = TRACEPARENT_RE.exec(header.trim());
131
- if (!match?.[1] || !match[2] || !match[3] || !match[4] || match[5] === undefined)
132
- return null;
133
- const version = match[1].toLowerCase();
134
- if (version === "ff")
135
- return null;
136
- const suffix = match[5];
137
- if (version === "00" ? suffix !== "" : suffix !== "" && !/^(?:-[0-9a-f]{2,})+$/i.test(suffix)) {
138
- return null;
139
- }
140
- const traceId = match[2].toLowerCase();
141
- const parentSpanId = match[3].toLowerCase();
142
- const traceFlags = match[4].toLowerCase();
143
- if (/^0+$/.test(traceId) || /^0+$/.test(parentSpanId))
144
- return null;
145
- return { traceId, spanId: randomHex(8), parentSpanId, traceFlags };
146
- }
147
- function formatTraceparent(ctx) {
148
- return `00-${ctx.traceId}-${ctx.spanId}-${ctx.traceFlags ?? "01"}`;
149
- }
150
- function resolveTraceContext(req) {
151
- return parseTraceparent(req.headers.get("traceparent")) ?? createTraceContext();
152
- }
153
- function childSpan(parent) {
154
- return {
155
- traceId: parent.traceId,
156
- spanId: randomHex(8),
157
- parentSpanId: parent.spanId,
158
- ...parent.tracestate !== undefined && { tracestate: parent.tracestate },
159
- ...parent.baggage !== undefined && { baggage: parent.baggage },
160
- ...parent.traceFlags !== undefined && { traceFlags: parent.traceFlags }
161
- };
162
- }
163
- var encoder = new TextEncoder;
164
- function boundedPropagationValue(value, maxBytes, maxMembers) {
165
- if (typeof value !== "string")
166
- return;
167
- const trimmed = value.trim();
168
- if (!trimmed || encoder.encode(trimmed).byteLength > maxBytes)
169
- return;
170
- for (const character of trimmed) {
171
- const code = character.charCodeAt(0);
172
- if (code <= 31 || code === 127)
173
- return;
174
- }
175
- const members = trimmed.split(",");
176
- if (members.length > maxMembers || members.some((member) => !member.trim())) {
177
- return;
178
- }
179
- return trimmed;
180
- }
181
- function resolvePropagationContext(metadata, fallback) {
182
- const traceparent = metadata?.traceparent;
183
- const parsed = typeof traceparent === "string" ? parseTraceparent(traceparent) : null;
184
- const trace = traceparent === undefined ? fallback ?? createTraceContext() : parsed ?? createTraceContext();
185
- const tracestate = parsed ? boundedPropagationValue(metadata?.tracestate, 512, 32) : undefined;
186
- const baggage = boundedPropagationValue(metadata?.baggage, 8192, 180);
187
- return {
188
- ...trace,
189
- ...tracestate !== undefined && { tracestate },
190
- ...baggage !== undefined && { baggage }
191
- };
192
- }
193
-
194
- export { formatZodError, zodIssues, errorCode, recordedErrorMessage, normalizeError, validateDeclaredOutput, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext };
194
+ export { randomHex, createTraceContext, parseTraceparent, formatTraceparent, resolveTraceContext, childSpan, resolvePropagationContext, formatZodError, zodIssues, errorCode, recordedErrorMessage, normalizeError, validateDeclaredOutput };
@@ -0,0 +1,87 @@
1
+ // src/browser/resumable.ts
2
+ import { z } from "zod";
3
+ var PositiveSafeIntegerSchema = z.number().int().positive().safe();
4
+ var BackoffPolicySchema = z.object({
5
+ minDelayMs: PositiveSafeIntegerSchema,
6
+ maxDelayMs: PositiveSafeIntegerSchema,
7
+ jitter: z.number().min(0).max(1)
8
+ }).strict().readonly().refine((policy) => policy.maxDelayMs >= policy.minDelayMs, {
9
+ message: "maxDelayMs must be at least minDelayMs"
10
+ });
11
+ function createBackoff(policy, random = Math.random) {
12
+ const { minDelayMs, maxDelayMs, jitter } = BackoffPolicySchema.parse(policy);
13
+ let attempt = 0;
14
+ return {
15
+ next() {
16
+ const exponential = Math.min(maxDelayMs, minDelayMs * 2 ** attempt);
17
+ attempt += 1;
18
+ const spread = exponential * jitter * random();
19
+ return Math.max(1, Math.round(exponential - spread));
20
+ },
21
+ reset() {
22
+ attempt = 0;
23
+ }
24
+ };
25
+ }
26
+ var DEFAULT_RETRY = { minDelayMs: 100, maxDelayMs: 30000, jitter: 0.5 };
27
+
28
+ class ResumableAbortError extends Error {
29
+ constructor() {
30
+ super("Resumable iterator was aborted");
31
+ this.name = "ResumableAbortError";
32
+ }
33
+ }
34
+ function sleep(ms, signal) {
35
+ return new Promise((resolve, reject) => {
36
+ const timer = setTimeout(() => {
37
+ signal?.removeEventListener("abort", onAbort);
38
+ resolve();
39
+ }, ms);
40
+ function onAbort() {
41
+ clearTimeout(timer);
42
+ reject(new ResumableAbortError);
43
+ }
44
+ if (signal?.aborted) {
45
+ clearTimeout(timer);
46
+ reject(new ResumableAbortError);
47
+ return;
48
+ }
49
+ signal?.addEventListener("abort", onAbort, { once: true });
50
+ });
51
+ }
52
+ async function* resumableIterator(config) {
53
+ const backoff = createBackoff(config.retry ?? DEFAULT_RETRY, config.random);
54
+ let cursor;
55
+ let attempt = 0;
56
+ for (;; ) {
57
+ if (config.signal?.aborted)
58
+ return;
59
+ try {
60
+ const source = await config.open(cursor);
61
+ for await (const item of source) {
62
+ if (config.signal?.aborted)
63
+ return;
64
+ attempt = 0;
65
+ backoff.reset();
66
+ cursor = config.advance(item, cursor);
67
+ yield item;
68
+ if (config.isTerminal?.(item))
69
+ return;
70
+ }
71
+ throw new Error("Resumable source ended without a terminal item");
72
+ } catch (error) {
73
+ if (config.signal?.aborted || error instanceof ResumableAbortError)
74
+ return;
75
+ attempt += 1;
76
+ const delayMs = backoff.next();
77
+ config.onAttempt?.({ number: attempt, delayMs, error });
78
+ try {
79
+ await sleep(delayMs, config.signal);
80
+ } catch {
81
+ return;
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ export { BackoffPolicySchema, createBackoff, resumableIterator };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  normalizeError
3
- } from "./index-nt1mp8km.js";
3
+ } from "./index-fxz0v7vg.js";
4
4
 
5
5
  // src/internal/bounded-lines.ts
6
6
  var DEFAULT_STREAM_LINE_BYTES = 1024 * 1024;
@@ -1,3 +1,13 @@
1
+ import {
2
+ ShutdownOptionsSchema,
3
+ isStreamCancellation,
4
+ ownHttpStream,
5
+ settleStreamCleanup
6
+ } from "./index-3z73fh2c.js";
7
+ import {
8
+ createValidatedRealtimeSocket,
9
+ isModuleNotFound
10
+ } from "./index-t0z5p5w6.js";
1
11
  import {
2
12
  DEFAULT_PROCESS_SIGNALS,
3
13
  RUNTIME_CONTEXT_RESERVED_KEYS,
@@ -7,7 +17,7 @@ import {
7
17
  defaultSignalSource,
8
18
  guardSignalCallback,
9
19
  reportSignalError
10
- } from "./index-vbf2p6me.js";
20
+ } from "./index-m9kzax52.js";
11
21
  import {
12
22
  extractIp,
13
23
  getClientInfo,
@@ -18,36 +28,31 @@ import {
18
28
  runWithRequestContext,
19
29
  setRequestEndpoint,
20
30
  setRequestError
21
- } from "./index-nemjkxjp.js";
22
- import {
23
- ShutdownOptionsSchema,
24
- isStreamCancellation,
25
- ownHttpStream,
26
- settleStreamCleanup
27
- } from "./index-3z73fh2c.js";
31
+ } from "./index-dwf1f2ap.js";
28
32
  import {
29
33
  errorCode,
30
34
  normalizeError,
31
35
  recordedErrorMessage,
32
36
  resolveTraceContext,
33
- validateDeclaredOutput,
34
- zodIssues
35
- } from "./index-nt1mp8km.js";
37
+ validateDeclaredOutput
38
+ } from "./index-fxz0v7vg.js";
36
39
  import {
37
40
  DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
38
- isUnsafeKey,
39
41
  joinRoutePath,
40
- parseTrailingWildcard,
41
- safeJsonParse
42
- } from "./index-vj3vvpaa.js";
42
+ parseTrailingWildcard
43
+ } from "./index-y01f4223.js";
43
44
  import {
44
45
  AppError,
45
46
  badRequest
46
47
  } from "./index-0w9abg87.js";
48
+ import {
49
+ isUnsafeKey,
50
+ safeJsonParse
51
+ } from "./index-kzfs85xp.js";
47
52
  import {
48
53
  isRecord,
49
54
  transportResult
50
- } from "./index-qyrqwr4c.js";
55
+ } from "./index-77fekveh.js";
51
56
 
52
57
  // src/server/multipart.ts
53
58
  var DEFAULT_MAX_REQUEST_BYTES = 25 * 1024 * 1024;
@@ -2049,253 +2054,6 @@ function bindProcessSignals(handle, options = {}) {
2049
2054
  return { promise, close };
2050
2055
  }
2051
2056
 
2052
- // src/realtime/rejected-frame.ts
2053
- var REALTIME_REJECTION_KEY = "@stitchkit/realtime-rejected";
2054
- var MAX_REJECTION_ISSUES = 20;
2055
- function realtimeRejectionEnvelope(report) {
2056
- return { [REALTIME_REJECTION_KEY]: report };
2057
- }
2058
- function asRealtimeRejection(value) {
2059
- if (typeof value !== "object" || value === null)
2060
- return null;
2061
- const report = Reflect.get(value, REALTIME_REJECTION_KEY);
2062
- if (typeof report !== "object" || report === null)
2063
- return null;
2064
- const event = Reflect.get(report, "event");
2065
- const reason = Reflect.get(report, "reason");
2066
- const message = Reflect.get(report, "message");
2067
- if (typeof event !== "string" || typeof reason !== "string" || typeof message !== "string") {
2068
- return null;
2069
- }
2070
- if (reason.length === 0)
2071
- return null;
2072
- const issues = parseIssues(Reflect.get(report, "issues"));
2073
- return { event, reason, message, ...issues !== undefined && { issues } };
2074
- }
2075
- function parseIssues(value) {
2076
- if (!Array.isArray(value))
2077
- return;
2078
- const issues = [];
2079
- for (const entry of value.slice(0, MAX_REJECTION_ISSUES)) {
2080
- if (typeof entry !== "object" || entry === null)
2081
- continue;
2082
- const path = Reflect.get(entry, "path");
2083
- const code = Reflect.get(entry, "code");
2084
- const message = Reflect.get(entry, "message");
2085
- if (typeof path === "string" && typeof code === "string" && typeof message === "string") {
2086
- issues.push({ path, code, message });
2087
- }
2088
- }
2089
- return issues.length > 0 ? issues : undefined;
2090
- }
2091
-
2092
- // src/realtime/rejection.ts
2093
- import { z } from "zod";
2094
- function realtimeContractViolation(options) {
2095
- const issues = options.cause instanceof z.ZodError ? zodIssues(options.cause) : undefined;
2096
- const reason = options.reason.replaceAll("-", " ");
2097
- const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
2098
- event: options.event,
2099
- direction: options.direction,
2100
- phase: options.phase,
2101
- reason: options.reason,
2102
- fault: options.fault,
2103
- ...issues !== undefined && { issues }
2104
- });
2105
- if (options.cause !== undefined)
2106
- error.cause = options.cause;
2107
- return { ...options, error };
2108
- }
2109
-
2110
- // src/realtime/socket.ts
2111
- function method(target, name) {
2112
- const value = Reflect.get(target, name);
2113
- if (typeof value !== "function") {
2114
- throw new Error(`Realtime target does not implement ${name}()`);
2115
- }
2116
- return (...args) => Reflect.apply(value, target, args);
2117
- }
2118
- function splitWireArguments(definition, args) {
2119
- const trailing = args.at(-1);
2120
- const replyTo = typeof trailing === "function" ? (...callbackArgs) => Reflect.apply(trailing, undefined, callbackArgs) : undefined;
2121
- if (!definition.ack || !replyTo)
2122
- return { values: args, ...replyTo && { replyTo } };
2123
- return { values: args.slice(0, -1), acknowledgement: replyTo, replyTo };
2124
- }
2125
- function eventDefinition(registry, event, direction) {
2126
- const definition = registry[event];
2127
- if (!definition) {
2128
- throw realtimeContractViolation({
2129
- event,
2130
- direction,
2131
- phase: "arguments",
2132
- reason: "unknown-event",
2133
- fault: "local"
2134
- }).error;
2135
- }
2136
- return definition;
2137
- }
2138
- function reportRejected(rejected, hook, logger) {
2139
- if (!hook) {
2140
- if (logger) {
2141
- logger.warn(rejected.error.message, rejected.error.details);
2142
- return;
2143
- }
2144
- console.warn(`[stitchkit] rejected realtime ${rejected.direction} event "${rejected.event}" (${rejected.phase})`, rejected.error);
2145
- return;
2146
- }
2147
- Promise.resolve(hook(rejected)).catch((error) => {
2148
- console.error("[stitchkit] realtime rejection hook failed", error);
2149
- });
2150
- }
2151
- function answerWithRejection(acknowledgement, report, logger) {
2152
- if (!acknowledgement)
2153
- return;
2154
- try {
2155
- acknowledgement(realtimeRejectionEnvelope(report));
2156
- } catch (error) {
2157
- const message = "[stitchkit] could not answer a rejected realtime frame";
2158
- if (logger)
2159
- logger.warn(message, { error });
2160
- else
2161
- console.warn(message, error);
2162
- }
2163
- }
2164
- function createValidatedRealtimeSocket({
2165
- target,
2166
- inbound,
2167
- outbound,
2168
- inboundDirection,
2169
- outboundDirection,
2170
- onRejected,
2171
- logger,
2172
- subscribe
2173
- }) {
2174
- const emitTarget = method(target, "emit");
2175
- return {
2176
- on: (event, handler) => {
2177
- const definition = eventDefinition(inbound, event, inboundDirection);
2178
- const wrapped = (...wireArgs) => {
2179
- const { values, acknowledgement, replyTo } = splitWireArguments(definition, wireArgs);
2180
- const parsed = definition.args.safeParse(values);
2181
- if (!parsed.success) {
2182
- const rejected = realtimeContractViolation({
2183
- event,
2184
- direction: inboundDirection,
2185
- phase: "arguments",
2186
- reason: "invalid-arguments",
2187
- fault: "peer",
2188
- cause: parsed.error
2189
- });
2190
- reportRejected(rejected, onRejected, logger);
2191
- answerWithRejection(replyTo, {
2192
- event,
2193
- reason: "invalid-arguments",
2194
- message: rejected.error.message,
2195
- issues: zodIssues(parsed.error).slice(0, MAX_REJECTION_ISSUES)
2196
- }, logger);
2197
- return;
2198
- }
2199
- if (definition.ack && !acknowledgement) {
2200
- reportRejected(realtimeContractViolation({
2201
- event,
2202
- direction: inboundDirection,
2203
- phase: "acknowledgement",
2204
- reason: "missing-acknowledgement",
2205
- fault: "peer"
2206
- }), onRejected, logger);
2207
- return;
2208
- }
2209
- const applicationArgs = [...parsed.data];
2210
- if (definition.ack) {
2211
- applicationArgs.push((value) => {
2212
- const ack = definition.ack?.safeParse(value);
2213
- if (!ack?.success) {
2214
- if (ack) {
2215
- reportRejected(realtimeContractViolation({
2216
- event,
2217
- direction: outboundDirection,
2218
- phase: "acknowledgement",
2219
- reason: "invalid-acknowledgement-value",
2220
- fault: "local",
2221
- cause: ack.error
2222
- }), onRejected, logger);
2223
- }
2224
- return;
2225
- }
2226
- acknowledgement?.(ack.data);
2227
- });
2228
- }
2229
- Reflect.apply(handler, undefined, applicationArgs);
2230
- };
2231
- if (subscribe)
2232
- return subscribe(event, wrapped);
2233
- const onTarget = method(target, "on");
2234
- const offTarget = method(target, "off");
2235
- onTarget(event, wrapped);
2236
- return () => {
2237
- offTarget(event, wrapped);
2238
- };
2239
- },
2240
- emit: (event, ...args) => {
2241
- const definition = eventDefinition(outbound, event, outboundDirection);
2242
- const { values, acknowledgement } = splitWireArguments(definition, args);
2243
- const parsed = definition.args.safeParse(values);
2244
- if (!parsed.success) {
2245
- throw realtimeContractViolation({
2246
- event,
2247
- direction: outboundDirection,
2248
- phase: "arguments",
2249
- reason: "invalid-arguments",
2250
- fault: "local",
2251
- cause: parsed.error
2252
- }).error;
2253
- }
2254
- if (definition.ack && !acknowledgement) {
2255
- throw realtimeContractViolation({
2256
- event,
2257
- direction: outboundDirection,
2258
- phase: "acknowledgement",
2259
- reason: "missing-acknowledgement",
2260
- fault: "local"
2261
- }).error;
2262
- }
2263
- const wireArgs = [...parsed.data];
2264
- if (definition.ack && acknowledgement) {
2265
- wireArgs.push((value) => {
2266
- const refusal = asRealtimeRejection(value);
2267
- if (refusal) {
2268
- reportRejected(realtimeContractViolation({
2269
- event,
2270
- direction: outboundDirection,
2271
- phase: "arguments",
2272
- reason: "rejected-by-peer",
2273
- fault: "local"
2274
- }), onRejected, logger);
2275
- return;
2276
- }
2277
- const ack = definition.ack?.safeParse(value);
2278
- if (!ack?.success) {
2279
- if (ack) {
2280
- reportRejected(realtimeContractViolation({
2281
- event,
2282
- direction: inboundDirection,
2283
- phase: "acknowledgement",
2284
- reason: "invalid-acknowledgement-value",
2285
- fault: "peer",
2286
- cause: ack.error
2287
- }), onRejected, logger);
2288
- }
2289
- return;
2290
- }
2291
- acknowledgement(ack.data);
2292
- });
2293
- }
2294
- return emitTarget(event, ...wireArgs) !== false;
2295
- }
2296
- };
2297
- }
2298
-
2299
2057
  // src/server/realtime.ts
2300
2058
  function bindRealtimeServer(contract, handle, options = {}) {
2301
2059
  const outbound = (target) => createValidatedRealtimeSocket({
@@ -2394,15 +2152,6 @@ function composeWebSocketHandlers(lanes, config) {
2394
2152
  };
2395
2153
  }
2396
2154
 
2397
- // src/internal/optional-peer.ts
2398
- function isModuleNotFound(error) {
2399
- if (typeof error !== "object" || error === null)
2400
- return false;
2401
- const code = "code" in error ? error.code : undefined;
2402
- const message = "message" in error && typeof error.message === "string" ? error.message : "";
2403
- return code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND" || message.includes("Cannot find module") || message.includes("Cannot find package");
2404
- }
2405
-
2406
2155
  // src/server/socket-io.ts
2407
2156
  var SOCKET_IO_SERVER = "socket.io";
2408
2157
  var SOCKET_IO_BUN_ENGINE = "@socket.io/bun-engine";
@@ -0,0 +1,9 @@
1
+ // src/internal/safe-json.ts
2
+ function isUnsafeKey(key) {
3
+ return key === "__proto__";
4
+ }
5
+ function safeJsonParse(text) {
6
+ return JSON.parse(text, (key, value) => isUnsafeKey(key) ? undefined : value);
7
+ }
8
+
9
+ export { isUnsafeKey, safeJsonParse };