stitchkit 0.70.1 → 0.70.3

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 (53) hide show
  1. package/dist/agent-runtime/harness-control.d.ts +2 -0
  2. package/dist/agent-runtime/harness-control.d.ts.map +1 -1
  3. package/dist/agent-runtime/history-chronology.d.ts +19 -0
  4. package/dist/agent-runtime/history-chronology.d.ts.map +1 -0
  5. package/dist/agent-runtime/history.d.ts.map +1 -1
  6. package/dist/agent-runtime/run-execution.d.ts.map +1 -1
  7. package/dist/agent-runtime/terminal-status.d.ts.map +1 -1
  8. package/dist/agent-runtime-browser.js +51 -51
  9. package/dist/agent-runtime-coding-tools.js +2 -2
  10. package/dist/agent-runtime-harness.js +60 -16
  11. package/dist/agent-runtime-openrouter.js +2 -2
  12. package/dist/agent-runtime-sqlite-bun.js +5 -5
  13. package/dist/agent-runtime-sqlite-node.js +5 -5
  14. package/dist/agent-runtime.js +110 -110
  15. package/dist/application-grammy.js +2 -2
  16. package/dist/application.js +63 -63
  17. package/dist/browser/live-state.d.ts +126 -0
  18. package/dist/browser/live-state.d.ts.map +1 -0
  19. package/dist/cli.js +5 -5
  20. package/dist/contract/index.js +20 -20
  21. package/dist/declaration.d.ts +4 -0
  22. package/dist/declaration.d.ts.map +1 -1
  23. package/dist/declaration.js +22 -22
  24. package/dist/files.js +3 -3
  25. package/dist/{index-4g196jmf.js → index-1zxf9x2z.js} +112 -20
  26. package/dist/{index-vy5bjy07.js → index-4qfqy0m6.js} +21 -31
  27. package/dist/{index-10gbbbaa.js → index-9sx8tbz2.js} +1 -1
  28. package/dist/{index-hsabxjz0.js → index-jw81xr75.js} +1 -1
  29. package/dist/index-y2s6h5bf.js +83 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +667 -56
  33. package/dist/node.js +26 -26
  34. package/dist/observability/index.js +22 -22
  35. package/dist/react.js +2 -2
  36. package/dist/realtime/contract.d.ts +30 -11
  37. package/dist/realtime/contract.d.ts.map +1 -1
  38. package/dist/realtime/index.d.ts +1 -1
  39. package/dist/realtime/index.d.ts.map +1 -1
  40. package/dist/server/create.d.ts.map +1 -1
  41. package/dist/server/error-dispatch.d.ts +13 -0
  42. package/dist/server/error-dispatch.d.ts.map +1 -0
  43. package/dist/server/index.js +79 -79
  44. package/dist/server/multipart.d.ts.map +1 -1
  45. package/dist/server/types.d.ts +6 -0
  46. package/dist/server/types.d.ts.map +1 -1
  47. package/dist/testing/surface-conformance.d.ts +4 -2
  48. package/dist/testing/surface-conformance.d.ts.map +1 -1
  49. package/dist/testing.js +122 -111
  50. package/dist/tools.js +57 -57
  51. package/llms-full.txt +237 -9
  52. package/package.json +1 -1
  53. package/dist/index-es0h4w26.js +0 -63
package/dist/index.js CHANGED
@@ -1089,6 +1089,597 @@ function createUrlBuilders(contracts, source, contractConfig) {
1089
1089
  function createScopedUrlBuilders(contracts, source, scopeConfigs) {
1090
1090
  return buildScopedRegistry(contracts, scopeConfigs, "URL builder", (contract, config) => createUrlBuilder(contract, source, config));
1091
1091
  }
1092
+ // src/browser/live-state.ts
1093
+ import { z as z3 } from "zod";
1094
+
1095
+ // src/application/channel.ts
1096
+ import { z as z2 } from "zod";
1097
+ var PositiveSafeIntegerSchema = z2.number().int().positive().safe();
1098
+ var BoundedChannelPolicySchema = z2.enum(["ordered", "latest"]);
1099
+ var BoundedChannelStateSchema = z2.enum(["open", "draining", "closed", "failed"]);
1100
+ var BoundedChannelSnapshotSchema = z2.object({
1101
+ state: BoundedChannelStateSchema,
1102
+ policy: BoundedChannelPolicySchema,
1103
+ queuedItems: z2.number().int().nonnegative(),
1104
+ queuedBytes: z2.number().int().nonnegative(),
1105
+ waitingReader: z2.boolean(),
1106
+ offered: z2.number().int().nonnegative(),
1107
+ delivered: z2.number().int().nonnegative(),
1108
+ queued: z2.number().int().nonnegative(),
1109
+ coalesced: z2.number().int().nonnegative(),
1110
+ refused: z2.number().int().nonnegative(),
1111
+ discarded: z2.number().int().nonnegative()
1112
+ }).strict().readonly();
1113
+
1114
+ class BoundedChannelReaderError extends Error {
1115
+ constructor() {
1116
+ super("A bounded channel permits only one pending next() call");
1117
+ this.name = "BoundedChannelReaderError";
1118
+ }
1119
+ }
1120
+ function createBoundedChannel(config) {
1121
+ const policy = BoundedChannelPolicySchema.parse(config.policy);
1122
+ const maxItems = PositiveSafeIntegerSchema.parse(config.maxItems);
1123
+ const maxBytes = PositiveSafeIntegerSchema.parse(config.maxBytes);
1124
+ const queue = [];
1125
+ let state = "open";
1126
+ let queuedBytes = 0;
1127
+ let waiting;
1128
+ let failure;
1129
+ let hasFailure = false;
1130
+ let offered = 0;
1131
+ let delivered = 0;
1132
+ let queued = 0;
1133
+ let coalesced = 0;
1134
+ let refused = 0;
1135
+ let discarded = 0;
1136
+ const removeAbortListener = () => {
1137
+ config.signal?.removeEventListener("abort", abortChannel);
1138
+ };
1139
+ const snapshot = () => BoundedChannelSnapshotSchema.parse({
1140
+ state,
1141
+ policy,
1142
+ queuedItems: queue.length,
1143
+ queuedBytes,
1144
+ waitingReader: waiting !== undefined,
1145
+ offered,
1146
+ delivered,
1147
+ queued,
1148
+ coalesced,
1149
+ refused,
1150
+ discarded
1151
+ });
1152
+ const clearQueue = () => {
1153
+ discarded += queue.length;
1154
+ queue.length = 0;
1155
+ queuedBytes = 0;
1156
+ };
1157
+ const settleClosed = () => {
1158
+ if (state !== "draining" || queue.length > 0)
1159
+ return;
1160
+ state = "closed";
1161
+ removeAbortListener();
1162
+ const reader = waiting;
1163
+ waiting = undefined;
1164
+ reader?.resolve({ done: true, value: undefined });
1165
+ };
1166
+ const close = (options = {}) => {
1167
+ if (state === "closed" || state === "failed")
1168
+ return snapshot();
1169
+ const mode = options.mode ?? "drain";
1170
+ if (mode !== "drain" && mode !== "discard") {
1171
+ throw new TypeError("Bounded channel close mode must be drain or discard");
1172
+ }
1173
+ if (mode === "discard") {
1174
+ clearQueue();
1175
+ state = "closed";
1176
+ removeAbortListener();
1177
+ const reader = waiting;
1178
+ waiting = undefined;
1179
+ reader?.resolve({ done: true, value: undefined });
1180
+ return snapshot();
1181
+ }
1182
+ state = "draining";
1183
+ settleClosed();
1184
+ return snapshot();
1185
+ };
1186
+ function abortChannel() {
1187
+ close({ mode: "discard" });
1188
+ }
1189
+ const channel = {
1190
+ [Symbol.asyncIterator]() {
1191
+ return channel;
1192
+ },
1193
+ offer(value) {
1194
+ offered += 1;
1195
+ if (state !== "open") {
1196
+ refused += 1;
1197
+ return { outcome: "refused", reason: "not-open" };
1198
+ }
1199
+ const bytes = config.sizeOf(value);
1200
+ if (!Number.isSafeInteger(bytes) || bytes < 0) {
1201
+ throw new TypeError("Bounded channel sizeOf() must return a non-negative safe integer");
1202
+ }
1203
+ if (bytes > maxBytes) {
1204
+ refused += 1;
1205
+ return { outcome: "refused", reason: "item-too-large" };
1206
+ }
1207
+ const reader = waiting;
1208
+ if (reader) {
1209
+ waiting = undefined;
1210
+ delivered += 1;
1211
+ reader.resolve({ done: false, value });
1212
+ return { outcome: "delivered" };
1213
+ }
1214
+ if (policy === "latest" && queue.length > 0) {
1215
+ const previous = queue[0];
1216
+ if (!previous)
1217
+ throw new Error("Bounded latest channel lost its pending value");
1218
+ queue[0] = { value, bytes };
1219
+ queuedBytes += bytes - previous.bytes;
1220
+ coalesced += 1;
1221
+ return { outcome: "coalesced", replaced: 1 };
1222
+ }
1223
+ if (queue.length >= maxItems) {
1224
+ refused += 1;
1225
+ return { outcome: "refused", reason: "item-capacity" };
1226
+ }
1227
+ if (queuedBytes + bytes > maxBytes) {
1228
+ refused += 1;
1229
+ return { outcome: "refused", reason: "byte-capacity" };
1230
+ }
1231
+ queue.push({ value, bytes });
1232
+ queuedBytes += bytes;
1233
+ queued += 1;
1234
+ return { outcome: "queued" };
1235
+ },
1236
+ next() {
1237
+ if (hasFailure)
1238
+ return Promise.reject(failure);
1239
+ const next = queue.shift();
1240
+ if (next) {
1241
+ queuedBytes -= next.bytes;
1242
+ delivered += 1;
1243
+ settleClosed();
1244
+ return Promise.resolve({ done: false, value: next.value });
1245
+ }
1246
+ if (state === "closed" || state === "draining") {
1247
+ settleClosed();
1248
+ return Promise.resolve({ done: true, value: undefined });
1249
+ }
1250
+ if (waiting)
1251
+ return Promise.reject(new BoundedChannelReaderError);
1252
+ return new Promise((resolve, reject) => {
1253
+ waiting = { resolve, reject };
1254
+ });
1255
+ },
1256
+ return() {
1257
+ close({ mode: "discard" });
1258
+ return Promise.resolve({ done: true, value: undefined });
1259
+ },
1260
+ throw(error) {
1261
+ channel.fail(error);
1262
+ return Promise.reject(error);
1263
+ },
1264
+ close,
1265
+ fail(error) {
1266
+ if (state === "closed" || state === "failed")
1267
+ return snapshot();
1268
+ failure = error;
1269
+ hasFailure = true;
1270
+ state = "failed";
1271
+ clearQueue();
1272
+ removeAbortListener();
1273
+ const reader = waiting;
1274
+ waiting = undefined;
1275
+ reader?.reject(error);
1276
+ return snapshot();
1277
+ },
1278
+ getSnapshot: snapshot
1279
+ };
1280
+ if (config.signal?.aborted)
1281
+ abortChannel();
1282
+ else
1283
+ config.signal?.addEventListener("abort", abortChannel, { once: true });
1284
+ return channel;
1285
+ }
1286
+ var CreditWindowSnapshotSchema = z2.object({
1287
+ state: z2.enum(["open", "closed"]),
1288
+ capacityBytes: PositiveSafeIntegerSchema,
1289
+ availableBytes: z2.number().int().nonnegative(),
1290
+ leasedBytes: z2.number().int().nonnegative(),
1291
+ acquired: z2.number().int().nonnegative(),
1292
+ refused: z2.number().int().nonnegative(),
1293
+ replenishedBytes: z2.number().int().nonnegative()
1294
+ }).strict().readonly();
1295
+
1296
+ // src/browser/live-state.ts
1297
+ var PositiveSafeIntegerSchema2 = z3.number().int().positive().safe();
1298
+ var LiveStatePhaseSchema = z3.enum([
1299
+ "idle",
1300
+ "opening",
1301
+ "live",
1302
+ "resync-required",
1303
+ "unavailable",
1304
+ "closed"
1305
+ ]);
1306
+ var LiveStateStopReasonSchema = z3.enum([
1307
+ "gap",
1308
+ "buffer-overflow",
1309
+ "source-unavailable",
1310
+ "source-error",
1311
+ "controller-error",
1312
+ "controller-capacity"
1313
+ ]);
1314
+ var LiveStateControllerStatusSchema = z3.object({
1315
+ phase: LiveStatePhaseSchema,
1316
+ generation: z3.number().int().nonnegative(),
1317
+ hasValue: z3.boolean(),
1318
+ bufferedEvents: z3.number().int().nonnegative(),
1319
+ bufferedBytes: z3.number().int().nonnegative(),
1320
+ receivedEvents: z3.number().int().nonnegative(),
1321
+ appliedEvents: z3.number().int().nonnegative(),
1322
+ duplicateEvents: z3.number().int().nonnegative(),
1323
+ gapEvents: z3.number().int().nonnegative(),
1324
+ refusedEvents: z3.number().int().nonnegative(),
1325
+ reason: LiveStateStopReasonSchema.optional()
1326
+ }).strict().readonly();
1327
+ function createLiveStateController(config) {
1328
+ const maxBufferedEvents = PositiveSafeIntegerSchema2.parse(config.maxBufferedEvents);
1329
+ const maxBufferedBytes = PositiveSafeIntegerSchema2.parse(config.maxBufferedBytes);
1330
+ const subscribers = new Set;
1331
+ let phase = "idle";
1332
+ let reason;
1333
+ let generation = 0;
1334
+ let stored = { hasValue: false };
1335
+ let receivedEvents = 0;
1336
+ let appliedEvents = 0;
1337
+ let duplicateEvents = 0;
1338
+ let gapEvents = 0;
1339
+ let refusedEvents = 0;
1340
+ let current;
1341
+ let opening;
1342
+ let unsettledSourceOpens = 0;
1343
+ let unsettledSourceCloses = 0;
1344
+ let publishDepth = 0;
1345
+ let controllerErrorObserverEnabled = true;
1346
+ let subscriberErrorObserverEnabled = true;
1347
+ const isPromiseLike = (value) => (typeof value === "object" || typeof value === "function") && value !== null && ("then" in value) && typeof value.then === "function";
1348
+ const status = () => {
1349
+ const buffered = current?.buffer.getSnapshot();
1350
+ return LiveStateControllerStatusSchema.parse({
1351
+ phase,
1352
+ generation,
1353
+ hasValue: stored.hasValue,
1354
+ bufferedEvents: buffered?.queuedItems ?? 0,
1355
+ bufferedBytes: buffered?.queuedBytes ?? 0,
1356
+ receivedEvents,
1357
+ appliedEvents,
1358
+ duplicateEvents,
1359
+ gapEvents,
1360
+ refusedEvents,
1361
+ ...reason && { reason }
1362
+ });
1363
+ };
1364
+ const buildSnapshot = () => {
1365
+ const metadata = status();
1366
+ return stored.hasValue ? Object.freeze({ ...metadata, value: stored.value }) : metadata;
1367
+ };
1368
+ let published = buildSnapshot();
1369
+ const reportControllerError = (error, at, atGeneration) => {
1370
+ if (!config.onControllerError || !controllerErrorObserverEnabled)
1371
+ return;
1372
+ try {
1373
+ const returned = config.onControllerError({
1374
+ error,
1375
+ generation: atGeneration,
1376
+ phase: at
1377
+ });
1378
+ if (isPromiseLike(returned)) {
1379
+ controllerErrorObserverEnabled = false;
1380
+ Promise.resolve(returned).catch(() => {
1381
+ return;
1382
+ });
1383
+ }
1384
+ } catch {}
1385
+ };
1386
+ const reportSubscriberError = (error, snapshot) => {
1387
+ if (!config.onSubscriberError || !subscriberErrorObserverEnabled)
1388
+ return;
1389
+ try {
1390
+ const returned = config.onSubscriberError({ error, snapshot });
1391
+ if (isPromiseLike(returned)) {
1392
+ subscriberErrorObserverEnabled = false;
1393
+ Promise.resolve(returned).catch(() => {
1394
+ return;
1395
+ });
1396
+ }
1397
+ } catch {}
1398
+ };
1399
+ const publish = () => {
1400
+ const snapshot = buildSnapshot();
1401
+ published = snapshot;
1402
+ publishDepth += 1;
1403
+ try {
1404
+ for (const listener of subscribers) {
1405
+ try {
1406
+ const returned = listener(snapshot);
1407
+ if (isPromiseLike(returned)) {
1408
+ subscribers.delete(listener);
1409
+ reportSubscriberError(new TypeError("Live-state subscribers must settle synchronously"), snapshot);
1410
+ Promise.resolve(returned).catch(() => {
1411
+ return;
1412
+ });
1413
+ }
1414
+ } catch (error) {
1415
+ reportSubscriberError(error, snapshot);
1416
+ }
1417
+ }
1418
+ } finally {
1419
+ publishDepth -= 1;
1420
+ }
1421
+ return published;
1422
+ };
1423
+ const publishAvailableCapacity = () => {
1424
+ if (phase !== "unavailable" || reason !== "controller-capacity" || unsettledSourceOpens + unsettledSourceCloses >= 2)
1425
+ return;
1426
+ phase = "resync-required";
1427
+ publish();
1428
+ };
1429
+ const closeSource = (active) => {
1430
+ if (active.closePromise)
1431
+ return active.closePromise;
1432
+ if (!active.closeSource)
1433
+ return Promise.resolve();
1434
+ const at = phase;
1435
+ unsettledSourceCloses += 1;
1436
+ active.closePromise = Promise.resolve().then(() => active.closeSource?.()).then(() => {
1437
+ return;
1438
+ }).catch((error) => {
1439
+ reportControllerError(error, at, active.id);
1440
+ }).finally(() => {
1441
+ unsettledSourceCloses -= 1;
1442
+ publishAvailableCapacity();
1443
+ });
1444
+ return active.closePromise;
1445
+ };
1446
+ const retire = (active) => {
1447
+ if (!active.retired) {
1448
+ active.retired = true;
1449
+ active.settleRetired();
1450
+ active.abort.abort();
1451
+ active.buffer.close({ mode: "discard" });
1452
+ }
1453
+ return closeSource(active);
1454
+ };
1455
+ const stopGeneration = (active, nextPhase, nextReason) => {
1456
+ if (current !== active || active.retired || phase === "closed")
1457
+ return;
1458
+ phase = nextPhase;
1459
+ reason = nextReason;
1460
+ retire(active);
1461
+ publish();
1462
+ };
1463
+ const apply = (active, event) => {
1464
+ if (current !== active || active.retired || !stored.hasValue || phase !== "opening" && phase !== "live")
1465
+ return;
1466
+ let decision;
1467
+ try {
1468
+ decision = config.applyEvent(stored.value, event);
1469
+ } catch (error) {
1470
+ reportControllerError(error, phase, active.id);
1471
+ stopGeneration(active, "unavailable", "controller-error");
1472
+ return;
1473
+ }
1474
+ if (current !== active || active.retired || phase !== "opening" && phase !== "live")
1475
+ return;
1476
+ if (!decision || !["applied", "duplicate", "gap"].includes(decision.outcome) || decision.outcome === "applied" && !("state" in decision)) {
1477
+ reportControllerError(new Error("applyEvent returned an invalid decision"), phase, active.id);
1478
+ stopGeneration(active, "unavailable", "controller-error");
1479
+ return;
1480
+ }
1481
+ if (decision.outcome === "duplicate") {
1482
+ duplicateEvents += 1;
1483
+ publish();
1484
+ return;
1485
+ }
1486
+ if (decision.outcome === "gap") {
1487
+ gapEvents += 1;
1488
+ stopGeneration(active, "resync-required", "gap");
1489
+ return;
1490
+ }
1491
+ stored = { hasValue: true, value: decision.state };
1492
+ appliedEvents += 1;
1493
+ publish();
1494
+ };
1495
+ const onEvent = (active, event) => {
1496
+ if (current !== active || active.retired || phase === "closed")
1497
+ return;
1498
+ receivedEvents += 1;
1499
+ if (phase === "opening") {
1500
+ try {
1501
+ const offered = active.buffer.offer(event);
1502
+ if (offered.outcome === "refused") {
1503
+ refusedEvents += 1;
1504
+ stopGeneration(active, "resync-required", "buffer-overflow");
1505
+ } else {
1506
+ publish();
1507
+ }
1508
+ } catch (error) {
1509
+ refusedEvents += 1;
1510
+ reportControllerError(error, phase, active.id);
1511
+ stopGeneration(active, "unavailable", "controller-error");
1512
+ }
1513
+ return;
1514
+ }
1515
+ if (phase === "live")
1516
+ apply(active, event);
1517
+ };
1518
+ const openGeneration = async (active) => {
1519
+ try {
1520
+ if (active.retired || current !== active || phase === "closed")
1521
+ return published;
1522
+ unsettledSourceOpens += 1;
1523
+ let sourceOpening;
1524
+ try {
1525
+ sourceOpening = config.source.open({
1526
+ signal: active.abort.signal,
1527
+ onEvent: (event) => onEvent(active, event),
1528
+ onUnavailable: () => stopGeneration(active, "unavailable", "source-unavailable")
1529
+ });
1530
+ } catch (error) {
1531
+ unsettledSourceOpens -= 1;
1532
+ publishAvailableCapacity();
1533
+ throw error;
1534
+ }
1535
+ sourceOpening = sourceOpening.then((opened2) => {
1536
+ active.closeSource = () => opened2.close();
1537
+ unsettledSourceOpens -= 1;
1538
+ if (active.retired || current !== active || phase === "closed") {
1539
+ closeSource(active);
1540
+ }
1541
+ publishAvailableCapacity();
1542
+ return opened2;
1543
+ }, (error) => {
1544
+ unsettledSourceOpens -= 1;
1545
+ publishAvailableCapacity();
1546
+ throw error;
1547
+ });
1548
+ const outcome = await Promise.race([
1549
+ sourceOpening.then((opened2) => ({ outcome: "opened", opened: opened2 })),
1550
+ active.retiredPromise.then(() => ({ outcome: "retired" }))
1551
+ ]);
1552
+ if (outcome.outcome === "retired") {
1553
+ return published;
1554
+ }
1555
+ const { opened } = outcome;
1556
+ if (current !== active || active.retired || phase !== "opening") {
1557
+ closeSource(active);
1558
+ return published;
1559
+ }
1560
+ stored = { hasValue: true, value: opened.snapshot };
1561
+ publish();
1562
+ while (current === active && !active.retired && phase === "opening") {
1563
+ if (active.buffer.getSnapshot().queuedItems === 0) {
1564
+ active.buffer.close({ mode: "discard" });
1565
+ phase = "live";
1566
+ reason = undefined;
1567
+ return publish();
1568
+ }
1569
+ const next = await active.buffer.next();
1570
+ if (next.done)
1571
+ break;
1572
+ apply(active, next.value);
1573
+ }
1574
+ if (current && current !== active && opening)
1575
+ return opening;
1576
+ return published;
1577
+ } catch (error) {
1578
+ if (current === active && !active.retired && phase !== "closed") {
1579
+ reportControllerError(error, phase, active.id);
1580
+ stopGeneration(active, "unavailable", "source-error");
1581
+ }
1582
+ publishAvailableCapacity();
1583
+ return published;
1584
+ }
1585
+ };
1586
+ const begin = (startedByResync) => {
1587
+ generation += 1;
1588
+ phase = "opening";
1589
+ reason = undefined;
1590
+ let settleRetired = () => {
1591
+ return;
1592
+ };
1593
+ const retiredPromise = new Promise((resolve) => {
1594
+ settleRetired = resolve;
1595
+ });
1596
+ const active = {
1597
+ id: generation,
1598
+ startedByResync,
1599
+ abort: new AbortController,
1600
+ buffer: createBoundedChannel({
1601
+ policy: "ordered",
1602
+ maxItems: maxBufferedEvents,
1603
+ maxBytes: maxBufferedBytes,
1604
+ sizeOf: config.sizeOfEvent
1605
+ }),
1606
+ retiredPromise,
1607
+ settleRetired,
1608
+ retired: false,
1609
+ sourceOpenStarted: false
1610
+ };
1611
+ current = active;
1612
+ publish();
1613
+ if (current !== active || active.retired || phase !== "opening") {
1614
+ return opening ?? Promise.resolve(published);
1615
+ }
1616
+ active.sourceOpenStarted = true;
1617
+ const operation = openGeneration(active);
1618
+ opening = operation;
1619
+ operation.finally(() => {
1620
+ if (opening === operation)
1621
+ opening = undefined;
1622
+ });
1623
+ return operation;
1624
+ };
1625
+ const close = () => {
1626
+ if (phase === "closed")
1627
+ return Promise.resolve(published);
1628
+ const active = current;
1629
+ current = undefined;
1630
+ phase = "closed";
1631
+ reason = undefined;
1632
+ const snapshot = publish();
1633
+ if (active)
1634
+ retire(active);
1635
+ config.signal?.removeEventListener("abort", abortFromConfig);
1636
+ subscribers.clear();
1637
+ return Promise.resolve(snapshot);
1638
+ };
1639
+ function abortFromConfig() {
1640
+ close();
1641
+ }
1642
+ if (config.signal?.aborted) {
1643
+ phase = "closed";
1644
+ published = buildSnapshot();
1645
+ } else {
1646
+ config.signal?.addEventListener("abort", abortFromConfig, { once: true });
1647
+ }
1648
+ return {
1649
+ start() {
1650
+ if (phase === "idle")
1651
+ return begin(false);
1652
+ return opening ?? Promise.resolve(published);
1653
+ },
1654
+ resync() {
1655
+ if (phase === "closed")
1656
+ return Promise.resolve(published);
1657
+ const active = current;
1658
+ if (active?.startedByResync && !active.sourceOpenStarted && phase === "opening" && publishDepth > 0) {
1659
+ return opening ?? Promise.resolve(published);
1660
+ }
1661
+ if (active) {
1662
+ retire(active);
1663
+ if (unsettledSourceOpens + unsettledSourceCloses >= 2) {
1664
+ phase = "unavailable";
1665
+ reason = "controller-capacity";
1666
+ return Promise.resolve(publish());
1667
+ }
1668
+ }
1669
+ return begin(true);
1670
+ },
1671
+ getSnapshot: () => published,
1672
+ subscribe(listener) {
1673
+ if (phase === "closed")
1674
+ return () => {
1675
+ return;
1676
+ };
1677
+ subscribers.add(listener);
1678
+ return () => subscribers.delete(listener);
1679
+ },
1680
+ close
1681
+ };
1682
+ }
1092
1683
  // src/internal/optional-peer.ts
1093
1684
  function isModuleNotFound(error) {
1094
1685
  if (typeof error !== "object" || error === null)
@@ -1099,19 +1690,19 @@ function isModuleNotFound(error) {
1099
1690
  }
1100
1691
 
1101
1692
  // src/realtime/request.ts
1102
- import { z as z2 } from "zod";
1103
- var RealtimeRequestPhaseSchema = z2.enum([
1693
+ import { z as z4 } from "zod";
1694
+ var RealtimeRequestPhaseSchema = z4.enum([
1104
1695
  "engine-handoff",
1105
1696
  "engine-ack-received",
1106
1697
  "settled",
1107
1698
  "timeout",
1108
1699
  "disconnected"
1109
1700
  ]);
1110
- var RealtimeRequestPhaseEventSchema = z2.object({
1111
- requestId: z2.string().min(1),
1112
- event: z2.string().min(1),
1701
+ var RealtimeRequestPhaseEventSchema = z4.object({
1702
+ requestId: z4.string().min(1),
1703
+ event: z4.string().min(1),
1113
1704
  phase: RealtimeRequestPhaseSchema,
1114
- elapsedMs: z2.number().finite().nonnegative()
1705
+ elapsedMs: z4.number().finite().nonnegative()
1115
1706
  }).strict();
1116
1707
 
1117
1708
  class RealtimeRequestTimeoutError extends Error {
@@ -1201,9 +1792,9 @@ function parseIssues(value) {
1201
1792
  }
1202
1793
 
1203
1794
  // src/realtime/rejection.ts
1204
- import { z as z3 } from "zod";
1795
+ import { z as z5 } from "zod";
1205
1796
  function realtimeContractViolation(options) {
1206
- const issues = options.cause instanceof z3.ZodError ? zodIssues(options.cause) : undefined;
1797
+ const issues = options.cause instanceof z5.ZodError ? zodIssues(options.cause) : undefined;
1207
1798
  const reason = options.reason.replaceAll("-", " ");
1208
1799
  const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
1209
1800
  event: options.event,
@@ -1939,57 +2530,77 @@ function createSocketIOClientInternal(config, onRequestPhase) {
1939
2530
  };
1940
2531
  }
1941
2532
  // src/realtime/contract.ts
2533
+ import { z as z6 } from "zod";
1942
2534
  function defineRealtimeContract(contract) {
1943
2535
  return contract;
1944
2536
  }
2537
+ var RealtimeRejectDirectionSchema = z6.enum([
2538
+ "client-inbound",
2539
+ "client-outbound",
2540
+ "server-inbound",
2541
+ "server-outbound"
2542
+ ]);
2543
+ var RealtimeRejectPhaseSchema = z6.enum(["arguments", "acknowledgement"]);
2544
+ var RealtimeRejectReasonSchema = z6.enum([
2545
+ "unknown-event",
2546
+ "invalid-arguments",
2547
+ "invalid-acknowledgement-value",
2548
+ "missing-acknowledgement",
2549
+ "rejected-by-peer"
2550
+ ]);
2551
+ var RealtimeRejectFaultSchema = z6.enum(["peer", "local"]);
1945
2552
  export {
1946
- ALL_TRANSPORTS,
1947
- ApiError,
1948
- AppError,
1949
- ContractStreamFrameSchema,
1950
- DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
1951
- ManagedFilePathSchema,
1952
- ManagedFileRefSchema,
1953
- REALTIME_REJECTION_KEY,
1954
- RealtimeRequestDisconnectedError,
1955
- RealtimeRequestInvalidAcknowledgementError,
1956
- RealtimeRequestPhaseEventSchema,
1957
- RealtimeRequestPhaseSchema,
1958
- RealtimeRequestRejectedError,
1959
- RealtimeRequestTimeoutError,
1960
- STITCH_ERROR_STATUS,
1961
- appError,
1962
- asRealtimeRejection,
1963
- badRequest,
1964
- bindRealtimeClient,
1965
- childSpan,
1966
- conflict,
1967
- contractEndpointMatchers,
1968
- createClient,
1969
- createClients,
1970
- createContractFactory,
1971
- createHttpClient,
1972
- createRealtimeClient,
1973
- createRetainedTopics,
1974
- createScopedClients,
1975
- createScopedUrlBuilders,
1976
- createSocketIOClient,
1977
- createTraceContext,
1978
- createUrlBuilder,
1979
- createUrlBuilders,
1980
- decodeCursor,
1981
- defineContract,
1982
- defineErrors,
1983
- defineRealtimeContract,
1984
- encodeCursor,
1985
- forbidden,
1986
- formatTraceparent,
1987
- isStitchErrorCode,
1988
- notFound,
1989
- paginatedSchema,
1990
- parseNDJSON,
1991
- parseSSE,
1992
- parseTraceparent,
2553
+ unauthorized,
1993
2554
  rateLimited,
1994
- unauthorized
2555
+ parseTraceparent,
2556
+ parseSSE,
2557
+ parseNDJSON,
2558
+ paginatedSchema,
2559
+ notFound,
2560
+ isStitchErrorCode,
2561
+ formatTraceparent,
2562
+ forbidden,
2563
+ encodeCursor,
2564
+ defineRealtimeContract,
2565
+ defineErrors,
2566
+ defineContract,
2567
+ decodeCursor,
2568
+ createUrlBuilders,
2569
+ createUrlBuilder,
2570
+ createTraceContext,
2571
+ createSocketIOClient,
2572
+ createScopedUrlBuilders,
2573
+ createScopedClients,
2574
+ createRetainedTopics,
2575
+ createRealtimeClient,
2576
+ createLiveStateController,
2577
+ createHttpClient,
2578
+ createContractFactory,
2579
+ createClients,
2580
+ createClient,
2581
+ contractEndpointMatchers,
2582
+ conflict,
2583
+ childSpan,
2584
+ bindRealtimeClient,
2585
+ badRequest,
2586
+ asRealtimeRejection,
2587
+ appError,
2588
+ STITCH_ERROR_STATUS,
2589
+ RealtimeRequestTimeoutError,
2590
+ RealtimeRequestRejectedError,
2591
+ RealtimeRequestPhaseSchema,
2592
+ RealtimeRequestPhaseEventSchema,
2593
+ RealtimeRequestInvalidAcknowledgementError,
2594
+ RealtimeRequestDisconnectedError,
2595
+ REALTIME_REJECTION_KEY,
2596
+ ManagedFileRefSchema,
2597
+ ManagedFilePathSchema,
2598
+ LiveStateStopReasonSchema,
2599
+ LiveStatePhaseSchema,
2600
+ LiveStateControllerStatusSchema,
2601
+ DEFAULT_CONTRACT_STREAM_FRAME_BYTES,
2602
+ ContractStreamFrameSchema,
2603
+ AppError,
2604
+ ApiError,
2605
+ ALL_TRANSPORTS
1995
2606
  };