stitchkit 0.74.1 → 0.75.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.
- package/dist/agent-runtime/sqlite-purge.d.ts +3 -3
- package/dist/agent-runtime/sqlite-purge.d.ts.map +1 -1
- package/dist/agent-runtime/sqlite.d.ts +5 -17
- package/dist/agent-runtime/sqlite.d.ts.map +1 -1
- package/dist/agent-runtime-coding-tools.js +2 -1
- package/dist/agent-runtime-harness.js +5 -4
- package/dist/agent-runtime-sqlite-bun.d.ts +1 -1
- package/dist/agent-runtime-sqlite-bun.d.ts.map +1 -1
- package/dist/agent-runtime-sqlite-node.d.ts +1 -1
- package/dist/agent-runtime-sqlite-node.d.ts.map +1 -1
- package/dist/agent-runtime.js +8 -7
- package/dist/application/keyspace-sqlite.d.ts +31 -0
- package/dist/application/keyspace-sqlite.d.ts.map +1 -0
- package/dist/application/keyspace.d.ts +142 -0
- package/dist/application/keyspace.d.ts.map +1 -0
- package/dist/application/watch-hub.d.ts +113 -0
- package/dist/application/watch-hub.d.ts.map +1 -0
- package/dist/application.d.ts +4 -0
- package/dist/application.d.ts.map +1 -1
- package/dist/application.js +455 -0
- package/dist/cli.js +7 -6
- package/dist/contract/index.js +2 -1
- package/dist/{index-aczggrty.js → index-28jsdwt1.js} +1 -1
- package/dist/index-35z5h2ty.js +594 -0
- package/dist/{index-f6n5n7nz.js → index-4kp4fxvp.js} +4 -18
- package/dist/{index-118v0z41.js → index-52400rdd.js} +8 -3
- package/dist/{index-da1aqnhb.js → index-65kathdm.js} +6 -4
- package/dist/{index-jqtsc9mj.js → index-6wr9f6qm.js} +2 -2
- package/dist/{index-7qy2ex0m.js → index-885chjxq.js} +1 -1
- package/dist/{index-k2zczx1g.js → index-9c5dbr5q.js} +1 -1
- package/dist/{index-s2rchahr.js → index-9my2n66s.js} +4 -4
- package/dist/{index-nemjkxjp.js → index-e0a57ymn.js} +1 -1
- package/dist/{index-vbf2p6me.js → index-endzd8sj.js} +1 -1
- package/dist/{index-vj3vvpaa.js → index-hsz2mmk0.js} +1 -17
- package/dist/{index-s4c8wy8m.js → index-k68e5jz0.js} +2 -2
- package/dist/index-rxfy4cq7.js +17 -0
- package/dist/{index-58jzmnn4.js → index-v5dm4bwq.js} +1 -1
- package/dist/{index-m668wzyc.js → index-v7xjfy10.js} +1 -1
- package/dist/index-vdvmcy7r.js +22 -0
- package/dist/{index-ezmn6ac6.js → index-xgahrwdf.js} +3 -3
- package/dist/index.js +26 -611
- package/dist/internal/sqlite.d.ts +27 -0
- package/dist/internal/sqlite.d.ts.map +1 -0
- package/dist/internal/stable-digest.d.ts +24 -0
- package/dist/internal/stable-digest.d.ts.map +1 -0
- package/dist/live/events.d.ts +155 -0
- package/dist/live/events.d.ts.map +1 -0
- package/dist/live/watch-client.d.ts +66 -0
- package/dist/live/watch-client.d.ts.map +1 -0
- package/dist/live/watch-contract.d.ts +157 -0
- package/dist/live/watch-contract.d.ts.map +1 -0
- package/dist/live.d.ts +18 -0
- package/dist/live.d.ts.map +1 -0
- package/dist/live.js +284 -0
- package/dist/node.js +5 -4
- package/dist/observability/index.js +4 -3
- package/dist/primitives.js +2 -1
- package/dist/remote.js +3 -2
- package/dist/server/create.d.ts.map +1 -1
- package/dist/server/event-bus.d.ts +49 -1
- package/dist/server/event-bus.d.ts.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +224 -12
- package/dist/server/middleware/trust-fence.d.ts +116 -0
- package/dist/server/middleware/trust-fence.d.ts.map +1 -0
- package/dist/server/types.d.ts +16 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/testing.js +3 -2
- package/dist/tool-invoker.js +6 -5
- package/dist/tools/mcp-round.d.ts.map +1 -1
- package/dist/tools.js +15 -30
- package/llms-full.txt +412 -4
- package/llms.txt +1 -0
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
LiveStateControllerStatusSchema,
|
|
3
|
+
LiveStatePhaseSchema,
|
|
4
|
+
LiveStateStopReasonSchema,
|
|
5
|
+
createLiveStateController
|
|
6
|
+
} from "./index-35z5h2ty.js";
|
|
1
7
|
import {
|
|
2
8
|
ALL_TRANSPORTS,
|
|
3
9
|
AppError,
|
|
@@ -21,7 +27,8 @@ import {
|
|
|
21
27
|
parseTrailingWildcard,
|
|
22
28
|
rateLimited,
|
|
23
29
|
unauthorized
|
|
24
|
-
} from "./index-
|
|
30
|
+
} from "./index-4kp4fxvp.js";
|
|
31
|
+
import"./index-rxfy4cq7.js";
|
|
25
32
|
import {
|
|
26
33
|
isRecord,
|
|
27
34
|
mapObject,
|
|
@@ -1126,605 +1133,13 @@ function createUrlBuilders(contracts, source, contractConfig) {
|
|
|
1126
1133
|
function createScopedUrlBuilders(contracts, source, scopeConfigs) {
|
|
1127
1134
|
return buildScopedRegistry(contracts, scopeConfigs, "URL builder", (contract, config) => createUrlBuilder(contract, source, config));
|
|
1128
1135
|
}
|
|
1129
|
-
// src/browser/
|
|
1130
|
-
import { z as z3 } from "zod";
|
|
1131
|
-
|
|
1132
|
-
// src/application/channel.ts
|
|
1136
|
+
// src/browser/resumable.ts
|
|
1133
1137
|
import { z as z2 } from "zod";
|
|
1134
1138
|
var PositiveSafeIntegerSchema = z2.number().int().positive().safe();
|
|
1135
|
-
var
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
policy: BoundedChannelPolicySchema,
|
|
1140
|
-
queuedItems: z2.number().int().nonnegative(),
|
|
1141
|
-
queuedBytes: z2.number().int().nonnegative(),
|
|
1142
|
-
waitingReader: z2.boolean(),
|
|
1143
|
-
offered: z2.number().int().nonnegative(),
|
|
1144
|
-
delivered: z2.number().int().nonnegative(),
|
|
1145
|
-
queued: z2.number().int().nonnegative(),
|
|
1146
|
-
coalesced: z2.number().int().nonnegative(),
|
|
1147
|
-
refused: z2.number().int().nonnegative(),
|
|
1148
|
-
discarded: z2.number().int().nonnegative()
|
|
1149
|
-
}).strict().readonly();
|
|
1150
|
-
|
|
1151
|
-
class BoundedChannelReaderError extends Error {
|
|
1152
|
-
constructor() {
|
|
1153
|
-
super("A bounded channel permits only one pending next() call");
|
|
1154
|
-
this.name = "BoundedChannelReaderError";
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
function createBoundedChannel(config) {
|
|
1158
|
-
const policy = BoundedChannelPolicySchema.parse(config.policy);
|
|
1159
|
-
const maxItems = PositiveSafeIntegerSchema.parse(config.maxItems);
|
|
1160
|
-
const maxBytes = PositiveSafeIntegerSchema.parse(config.maxBytes);
|
|
1161
|
-
const queue = [];
|
|
1162
|
-
let state = "open";
|
|
1163
|
-
let queuedBytes = 0;
|
|
1164
|
-
let waiting;
|
|
1165
|
-
let failure;
|
|
1166
|
-
let hasFailure = false;
|
|
1167
|
-
let offered = 0;
|
|
1168
|
-
let delivered = 0;
|
|
1169
|
-
let queued = 0;
|
|
1170
|
-
let coalesced = 0;
|
|
1171
|
-
let refused = 0;
|
|
1172
|
-
let discarded = 0;
|
|
1173
|
-
const removeAbortListener = () => {
|
|
1174
|
-
config.signal?.removeEventListener("abort", abortChannel);
|
|
1175
|
-
};
|
|
1176
|
-
const snapshot = () => BoundedChannelSnapshotSchema.parse({
|
|
1177
|
-
state,
|
|
1178
|
-
policy,
|
|
1179
|
-
queuedItems: queue.length,
|
|
1180
|
-
queuedBytes,
|
|
1181
|
-
waitingReader: waiting !== undefined,
|
|
1182
|
-
offered,
|
|
1183
|
-
delivered,
|
|
1184
|
-
queued,
|
|
1185
|
-
coalesced,
|
|
1186
|
-
refused,
|
|
1187
|
-
discarded
|
|
1188
|
-
});
|
|
1189
|
-
const clearQueue = () => {
|
|
1190
|
-
discarded += queue.length;
|
|
1191
|
-
queue.length = 0;
|
|
1192
|
-
queuedBytes = 0;
|
|
1193
|
-
};
|
|
1194
|
-
const settleClosed = () => {
|
|
1195
|
-
if (state !== "draining" || queue.length > 0)
|
|
1196
|
-
return;
|
|
1197
|
-
state = "closed";
|
|
1198
|
-
removeAbortListener();
|
|
1199
|
-
const reader = waiting;
|
|
1200
|
-
waiting = undefined;
|
|
1201
|
-
reader?.resolve({ done: true, value: undefined });
|
|
1202
|
-
};
|
|
1203
|
-
const close = (options = {}) => {
|
|
1204
|
-
if (state === "closed" || state === "failed")
|
|
1205
|
-
return snapshot();
|
|
1206
|
-
const mode = options.mode ?? "drain";
|
|
1207
|
-
if (mode !== "drain" && mode !== "discard") {
|
|
1208
|
-
throw new TypeError("Bounded channel close mode must be drain or discard");
|
|
1209
|
-
}
|
|
1210
|
-
if (mode === "discard") {
|
|
1211
|
-
clearQueue();
|
|
1212
|
-
state = "closed";
|
|
1213
|
-
removeAbortListener();
|
|
1214
|
-
const reader = waiting;
|
|
1215
|
-
waiting = undefined;
|
|
1216
|
-
reader?.resolve({ done: true, value: undefined });
|
|
1217
|
-
return snapshot();
|
|
1218
|
-
}
|
|
1219
|
-
state = "draining";
|
|
1220
|
-
settleClosed();
|
|
1221
|
-
return snapshot();
|
|
1222
|
-
};
|
|
1223
|
-
function abortChannel() {
|
|
1224
|
-
close({ mode: "discard" });
|
|
1225
|
-
}
|
|
1226
|
-
const channel = {
|
|
1227
|
-
[Symbol.asyncIterator]() {
|
|
1228
|
-
return channel;
|
|
1229
|
-
},
|
|
1230
|
-
offer(value) {
|
|
1231
|
-
offered += 1;
|
|
1232
|
-
if (state !== "open") {
|
|
1233
|
-
refused += 1;
|
|
1234
|
-
return { outcome: "refused", reason: "not-open" };
|
|
1235
|
-
}
|
|
1236
|
-
const bytes = config.sizeOf(value);
|
|
1237
|
-
if (!Number.isSafeInteger(bytes) || bytes < 0) {
|
|
1238
|
-
throw new TypeError("Bounded channel sizeOf() must return a non-negative safe integer");
|
|
1239
|
-
}
|
|
1240
|
-
if (bytes > maxBytes) {
|
|
1241
|
-
refused += 1;
|
|
1242
|
-
return { outcome: "refused", reason: "item-too-large" };
|
|
1243
|
-
}
|
|
1244
|
-
const reader = waiting;
|
|
1245
|
-
if (reader) {
|
|
1246
|
-
waiting = undefined;
|
|
1247
|
-
delivered += 1;
|
|
1248
|
-
reader.resolve({ done: false, value });
|
|
1249
|
-
return { outcome: "delivered" };
|
|
1250
|
-
}
|
|
1251
|
-
if (policy === "latest" && queue.length > 0) {
|
|
1252
|
-
const previous = queue[0];
|
|
1253
|
-
if (!previous)
|
|
1254
|
-
throw new Error("Bounded latest channel lost its pending value");
|
|
1255
|
-
queue[0] = { value, bytes };
|
|
1256
|
-
queuedBytes += bytes - previous.bytes;
|
|
1257
|
-
coalesced += 1;
|
|
1258
|
-
return { outcome: "coalesced", replaced: 1 };
|
|
1259
|
-
}
|
|
1260
|
-
if (queue.length >= maxItems) {
|
|
1261
|
-
refused += 1;
|
|
1262
|
-
return { outcome: "refused", reason: "item-capacity" };
|
|
1263
|
-
}
|
|
1264
|
-
if (queuedBytes + bytes > maxBytes) {
|
|
1265
|
-
refused += 1;
|
|
1266
|
-
return { outcome: "refused", reason: "byte-capacity" };
|
|
1267
|
-
}
|
|
1268
|
-
queue.push({ value, bytes });
|
|
1269
|
-
queuedBytes += bytes;
|
|
1270
|
-
queued += 1;
|
|
1271
|
-
return { outcome: "queued" };
|
|
1272
|
-
},
|
|
1273
|
-
next() {
|
|
1274
|
-
if (hasFailure)
|
|
1275
|
-
return Promise.reject(failure);
|
|
1276
|
-
const next = queue.shift();
|
|
1277
|
-
if (next) {
|
|
1278
|
-
queuedBytes -= next.bytes;
|
|
1279
|
-
delivered += 1;
|
|
1280
|
-
settleClosed();
|
|
1281
|
-
return Promise.resolve({ done: false, value: next.value });
|
|
1282
|
-
}
|
|
1283
|
-
if (state === "closed" || state === "draining") {
|
|
1284
|
-
settleClosed();
|
|
1285
|
-
return Promise.resolve({ done: true, value: undefined });
|
|
1286
|
-
}
|
|
1287
|
-
if (waiting)
|
|
1288
|
-
return Promise.reject(new BoundedChannelReaderError);
|
|
1289
|
-
return new Promise((resolve, reject) => {
|
|
1290
|
-
waiting = { resolve, reject };
|
|
1291
|
-
});
|
|
1292
|
-
},
|
|
1293
|
-
return() {
|
|
1294
|
-
close({ mode: "discard" });
|
|
1295
|
-
return Promise.resolve({ done: true, value: undefined });
|
|
1296
|
-
},
|
|
1297
|
-
throw(error) {
|
|
1298
|
-
channel.fail(error);
|
|
1299
|
-
return Promise.reject(error);
|
|
1300
|
-
},
|
|
1301
|
-
close,
|
|
1302
|
-
fail(error) {
|
|
1303
|
-
if (state === "closed" || state === "failed")
|
|
1304
|
-
return snapshot();
|
|
1305
|
-
failure = error;
|
|
1306
|
-
hasFailure = true;
|
|
1307
|
-
state = "failed";
|
|
1308
|
-
clearQueue();
|
|
1309
|
-
removeAbortListener();
|
|
1310
|
-
const reader = waiting;
|
|
1311
|
-
waiting = undefined;
|
|
1312
|
-
reader?.reject(error);
|
|
1313
|
-
return snapshot();
|
|
1314
|
-
},
|
|
1315
|
-
getSnapshot: snapshot
|
|
1316
|
-
};
|
|
1317
|
-
if (config.signal?.aborted)
|
|
1318
|
-
abortChannel();
|
|
1319
|
-
else
|
|
1320
|
-
config.signal?.addEventListener("abort", abortChannel, { once: true });
|
|
1321
|
-
return channel;
|
|
1322
|
-
}
|
|
1323
|
-
var CreditWindowSnapshotSchema = z2.object({
|
|
1324
|
-
state: z2.enum(["open", "closed"]),
|
|
1325
|
-
capacityBytes: PositiveSafeIntegerSchema,
|
|
1326
|
-
availableBytes: z2.number().int().nonnegative(),
|
|
1327
|
-
leasedBytes: z2.number().int().nonnegative(),
|
|
1328
|
-
acquired: z2.number().int().nonnegative(),
|
|
1329
|
-
refused: z2.number().int().nonnegative(),
|
|
1330
|
-
replenishedBytes: z2.number().int().nonnegative(),
|
|
1331
|
-
waiting: z2.number().int().nonnegative()
|
|
1332
|
-
}).strict().readonly();
|
|
1333
|
-
|
|
1334
|
-
// src/browser/live-state.ts
|
|
1335
|
-
var PositiveSafeIntegerSchema2 = z3.number().int().positive().safe();
|
|
1336
|
-
var LiveStatePhaseSchema = z3.enum([
|
|
1337
|
-
"idle",
|
|
1338
|
-
"opening",
|
|
1339
|
-
"live",
|
|
1340
|
-
"resync-required",
|
|
1341
|
-
"unavailable",
|
|
1342
|
-
"closed"
|
|
1343
|
-
]);
|
|
1344
|
-
var LiveStateStopReasonSchema = z3.enum([
|
|
1345
|
-
"gap",
|
|
1346
|
-
"buffer-overflow",
|
|
1347
|
-
"source-unavailable",
|
|
1348
|
-
"source-error",
|
|
1349
|
-
"controller-error",
|
|
1350
|
-
"controller-capacity"
|
|
1351
|
-
]);
|
|
1352
|
-
var LiveStateControllerStatusSchema = z3.object({
|
|
1353
|
-
phase: LiveStatePhaseSchema,
|
|
1354
|
-
generation: z3.number().int().nonnegative(),
|
|
1355
|
-
hasValue: z3.boolean(),
|
|
1356
|
-
bufferedEvents: z3.number().int().nonnegative(),
|
|
1357
|
-
bufferedBytes: z3.number().int().nonnegative(),
|
|
1358
|
-
receivedEvents: z3.number().int().nonnegative(),
|
|
1359
|
-
appliedEvents: z3.number().int().nonnegative(),
|
|
1360
|
-
duplicateEvents: z3.number().int().nonnegative(),
|
|
1361
|
-
gapEvents: z3.number().int().nonnegative(),
|
|
1362
|
-
refusedEvents: z3.number().int().nonnegative(),
|
|
1363
|
-
reason: LiveStateStopReasonSchema.optional()
|
|
1364
|
-
}).strict().readonly();
|
|
1365
|
-
function createLiveStateController(config) {
|
|
1366
|
-
const maxBufferedEvents = PositiveSafeIntegerSchema2.parse(config.maxBufferedEvents);
|
|
1367
|
-
const maxBufferedBytes = PositiveSafeIntegerSchema2.parse(config.maxBufferedBytes);
|
|
1368
|
-
const subscribers = new Set;
|
|
1369
|
-
let phase = "idle";
|
|
1370
|
-
let reason;
|
|
1371
|
-
let generation = 0;
|
|
1372
|
-
let stored = { hasValue: false };
|
|
1373
|
-
let receivedEvents = 0;
|
|
1374
|
-
let appliedEvents = 0;
|
|
1375
|
-
let duplicateEvents = 0;
|
|
1376
|
-
let gapEvents = 0;
|
|
1377
|
-
let refusedEvents = 0;
|
|
1378
|
-
let current;
|
|
1379
|
-
let opening;
|
|
1380
|
-
let unsettledSourceOpens = 0;
|
|
1381
|
-
let unsettledSourceCloses = 0;
|
|
1382
|
-
let publishDepth = 0;
|
|
1383
|
-
let controllerErrorObserverEnabled = true;
|
|
1384
|
-
let subscriberErrorObserverEnabled = true;
|
|
1385
|
-
const isPromiseLike = (value) => (typeof value === "object" || typeof value === "function") && value !== null && ("then" in value) && typeof value.then === "function";
|
|
1386
|
-
const status = () => {
|
|
1387
|
-
const buffered = current?.buffer.getSnapshot();
|
|
1388
|
-
return LiveStateControllerStatusSchema.parse({
|
|
1389
|
-
phase,
|
|
1390
|
-
generation,
|
|
1391
|
-
hasValue: stored.hasValue,
|
|
1392
|
-
bufferedEvents: buffered?.queuedItems ?? 0,
|
|
1393
|
-
bufferedBytes: buffered?.queuedBytes ?? 0,
|
|
1394
|
-
receivedEvents,
|
|
1395
|
-
appliedEvents,
|
|
1396
|
-
duplicateEvents,
|
|
1397
|
-
gapEvents,
|
|
1398
|
-
refusedEvents,
|
|
1399
|
-
...reason && { reason }
|
|
1400
|
-
});
|
|
1401
|
-
};
|
|
1402
|
-
const buildSnapshot = () => {
|
|
1403
|
-
const metadata = status();
|
|
1404
|
-
return stored.hasValue ? Object.freeze({ ...metadata, value: stored.value }) : metadata;
|
|
1405
|
-
};
|
|
1406
|
-
let published = buildSnapshot();
|
|
1407
|
-
const reportControllerError = (error, at, atGeneration) => {
|
|
1408
|
-
if (!config.onControllerError || !controllerErrorObserverEnabled)
|
|
1409
|
-
return;
|
|
1410
|
-
try {
|
|
1411
|
-
const returned = config.onControllerError({
|
|
1412
|
-
error,
|
|
1413
|
-
generation: atGeneration,
|
|
1414
|
-
phase: at
|
|
1415
|
-
});
|
|
1416
|
-
if (isPromiseLike(returned)) {
|
|
1417
|
-
controllerErrorObserverEnabled = false;
|
|
1418
|
-
Promise.resolve(returned).catch(() => {
|
|
1419
|
-
return;
|
|
1420
|
-
});
|
|
1421
|
-
}
|
|
1422
|
-
} catch {}
|
|
1423
|
-
};
|
|
1424
|
-
const reportSubscriberError = (error, snapshot) => {
|
|
1425
|
-
if (!config.onSubscriberError || !subscriberErrorObserverEnabled)
|
|
1426
|
-
return;
|
|
1427
|
-
try {
|
|
1428
|
-
const returned = config.onSubscriberError({ error, snapshot });
|
|
1429
|
-
if (isPromiseLike(returned)) {
|
|
1430
|
-
subscriberErrorObserverEnabled = false;
|
|
1431
|
-
Promise.resolve(returned).catch(() => {
|
|
1432
|
-
return;
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
} catch {}
|
|
1436
|
-
};
|
|
1437
|
-
const publish = () => {
|
|
1438
|
-
const snapshot = buildSnapshot();
|
|
1439
|
-
published = snapshot;
|
|
1440
|
-
publishDepth += 1;
|
|
1441
|
-
try {
|
|
1442
|
-
for (const listener of subscribers) {
|
|
1443
|
-
try {
|
|
1444
|
-
const returned = listener(snapshot);
|
|
1445
|
-
if (isPromiseLike(returned)) {
|
|
1446
|
-
subscribers.delete(listener);
|
|
1447
|
-
reportSubscriberError(new TypeError("Live-state subscribers must settle synchronously"), snapshot);
|
|
1448
|
-
Promise.resolve(returned).catch(() => {
|
|
1449
|
-
return;
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
} catch (error) {
|
|
1453
|
-
reportSubscriberError(error, snapshot);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
} finally {
|
|
1457
|
-
publishDepth -= 1;
|
|
1458
|
-
}
|
|
1459
|
-
return published;
|
|
1460
|
-
};
|
|
1461
|
-
const publishAvailableCapacity = () => {
|
|
1462
|
-
if (phase !== "unavailable" || reason !== "controller-capacity" || unsettledSourceOpens + unsettledSourceCloses >= 2)
|
|
1463
|
-
return;
|
|
1464
|
-
phase = "resync-required";
|
|
1465
|
-
publish();
|
|
1466
|
-
};
|
|
1467
|
-
const closeSource = (active) => {
|
|
1468
|
-
if (active.closePromise)
|
|
1469
|
-
return active.closePromise;
|
|
1470
|
-
if (!active.closeSource)
|
|
1471
|
-
return Promise.resolve();
|
|
1472
|
-
const at = phase;
|
|
1473
|
-
unsettledSourceCloses += 1;
|
|
1474
|
-
active.closePromise = Promise.resolve().then(() => active.closeSource?.()).then(() => {
|
|
1475
|
-
return;
|
|
1476
|
-
}).catch((error) => {
|
|
1477
|
-
reportControllerError(error, at, active.id);
|
|
1478
|
-
}).finally(() => {
|
|
1479
|
-
unsettledSourceCloses -= 1;
|
|
1480
|
-
publishAvailableCapacity();
|
|
1481
|
-
});
|
|
1482
|
-
return active.closePromise;
|
|
1483
|
-
};
|
|
1484
|
-
const retire = (active) => {
|
|
1485
|
-
if (!active.retired) {
|
|
1486
|
-
active.retired = true;
|
|
1487
|
-
active.settleRetired();
|
|
1488
|
-
active.abort.abort();
|
|
1489
|
-
active.buffer.close({ mode: "discard" });
|
|
1490
|
-
}
|
|
1491
|
-
return closeSource(active);
|
|
1492
|
-
};
|
|
1493
|
-
const stopGeneration = (active, nextPhase, nextReason) => {
|
|
1494
|
-
if (current !== active || active.retired || phase === "closed")
|
|
1495
|
-
return;
|
|
1496
|
-
phase = nextPhase;
|
|
1497
|
-
reason = nextReason;
|
|
1498
|
-
retire(active);
|
|
1499
|
-
publish();
|
|
1500
|
-
};
|
|
1501
|
-
const apply = (active, event) => {
|
|
1502
|
-
if (current !== active || active.retired || !stored.hasValue || phase !== "opening" && phase !== "live")
|
|
1503
|
-
return;
|
|
1504
|
-
let decision;
|
|
1505
|
-
try {
|
|
1506
|
-
decision = config.applyEvent(stored.value, event);
|
|
1507
|
-
} catch (error) {
|
|
1508
|
-
reportControllerError(error, phase, active.id);
|
|
1509
|
-
stopGeneration(active, "unavailable", "controller-error");
|
|
1510
|
-
return;
|
|
1511
|
-
}
|
|
1512
|
-
if (current !== active || active.retired || phase !== "opening" && phase !== "live")
|
|
1513
|
-
return;
|
|
1514
|
-
if (!decision || !["applied", "duplicate", "gap"].includes(decision.outcome) || decision.outcome === "applied" && !("state" in decision)) {
|
|
1515
|
-
reportControllerError(new Error("applyEvent returned an invalid decision"), phase, active.id);
|
|
1516
|
-
stopGeneration(active, "unavailable", "controller-error");
|
|
1517
|
-
return;
|
|
1518
|
-
}
|
|
1519
|
-
if (decision.outcome === "duplicate") {
|
|
1520
|
-
duplicateEvents += 1;
|
|
1521
|
-
publish();
|
|
1522
|
-
return;
|
|
1523
|
-
}
|
|
1524
|
-
if (decision.outcome === "gap") {
|
|
1525
|
-
gapEvents += 1;
|
|
1526
|
-
stopGeneration(active, "resync-required", "gap");
|
|
1527
|
-
return;
|
|
1528
|
-
}
|
|
1529
|
-
stored = { hasValue: true, value: decision.state };
|
|
1530
|
-
appliedEvents += 1;
|
|
1531
|
-
publish();
|
|
1532
|
-
};
|
|
1533
|
-
const onEvent = (active, event) => {
|
|
1534
|
-
if (current !== active || active.retired || phase === "closed")
|
|
1535
|
-
return;
|
|
1536
|
-
receivedEvents += 1;
|
|
1537
|
-
if (phase === "opening") {
|
|
1538
|
-
try {
|
|
1539
|
-
const offered = active.buffer.offer(event);
|
|
1540
|
-
if (offered.outcome === "refused") {
|
|
1541
|
-
refusedEvents += 1;
|
|
1542
|
-
stopGeneration(active, "resync-required", "buffer-overflow");
|
|
1543
|
-
} else {
|
|
1544
|
-
publish();
|
|
1545
|
-
}
|
|
1546
|
-
} catch (error) {
|
|
1547
|
-
refusedEvents += 1;
|
|
1548
|
-
reportControllerError(error, phase, active.id);
|
|
1549
|
-
stopGeneration(active, "unavailable", "controller-error");
|
|
1550
|
-
}
|
|
1551
|
-
return;
|
|
1552
|
-
}
|
|
1553
|
-
if (phase === "live")
|
|
1554
|
-
apply(active, event);
|
|
1555
|
-
};
|
|
1556
|
-
const openGeneration = async (active) => {
|
|
1557
|
-
try {
|
|
1558
|
-
if (active.retired || current !== active || phase === "closed")
|
|
1559
|
-
return published;
|
|
1560
|
-
unsettledSourceOpens += 1;
|
|
1561
|
-
let sourceOpening;
|
|
1562
|
-
try {
|
|
1563
|
-
sourceOpening = config.source.open({
|
|
1564
|
-
signal: active.abort.signal,
|
|
1565
|
-
onEvent: (event) => onEvent(active, event),
|
|
1566
|
-
onUnavailable: () => stopGeneration(active, "unavailable", "source-unavailable")
|
|
1567
|
-
});
|
|
1568
|
-
} catch (error) {
|
|
1569
|
-
unsettledSourceOpens -= 1;
|
|
1570
|
-
publishAvailableCapacity();
|
|
1571
|
-
throw error;
|
|
1572
|
-
}
|
|
1573
|
-
sourceOpening = sourceOpening.then((opened2) => {
|
|
1574
|
-
active.closeSource = () => opened2.close();
|
|
1575
|
-
unsettledSourceOpens -= 1;
|
|
1576
|
-
if (active.retired || current !== active || phase === "closed") {
|
|
1577
|
-
closeSource(active);
|
|
1578
|
-
}
|
|
1579
|
-
publishAvailableCapacity();
|
|
1580
|
-
return opened2;
|
|
1581
|
-
}, (error) => {
|
|
1582
|
-
unsettledSourceOpens -= 1;
|
|
1583
|
-
publishAvailableCapacity();
|
|
1584
|
-
throw error;
|
|
1585
|
-
});
|
|
1586
|
-
const outcome = await Promise.race([
|
|
1587
|
-
sourceOpening.then((opened2) => ({ outcome: "opened", opened: opened2 })),
|
|
1588
|
-
active.retiredPromise.then(() => ({ outcome: "retired" }))
|
|
1589
|
-
]);
|
|
1590
|
-
if (outcome.outcome === "retired") {
|
|
1591
|
-
return published;
|
|
1592
|
-
}
|
|
1593
|
-
const { opened } = outcome;
|
|
1594
|
-
if (current !== active || active.retired || phase !== "opening") {
|
|
1595
|
-
closeSource(active);
|
|
1596
|
-
return published;
|
|
1597
|
-
}
|
|
1598
|
-
stored = { hasValue: true, value: opened.snapshot };
|
|
1599
|
-
publish();
|
|
1600
|
-
while (current === active && !active.retired && phase === "opening") {
|
|
1601
|
-
if (active.buffer.getSnapshot().queuedItems === 0) {
|
|
1602
|
-
active.buffer.close({ mode: "discard" });
|
|
1603
|
-
phase = "live";
|
|
1604
|
-
reason = undefined;
|
|
1605
|
-
return publish();
|
|
1606
|
-
}
|
|
1607
|
-
const next = await active.buffer.next();
|
|
1608
|
-
if (next.done)
|
|
1609
|
-
break;
|
|
1610
|
-
apply(active, next.value);
|
|
1611
|
-
}
|
|
1612
|
-
if (current && current !== active && opening)
|
|
1613
|
-
return opening;
|
|
1614
|
-
return published;
|
|
1615
|
-
} catch (error) {
|
|
1616
|
-
if (current === active && !active.retired && phase !== "closed") {
|
|
1617
|
-
reportControllerError(error, phase, active.id);
|
|
1618
|
-
stopGeneration(active, "unavailable", "source-error");
|
|
1619
|
-
}
|
|
1620
|
-
publishAvailableCapacity();
|
|
1621
|
-
return published;
|
|
1622
|
-
}
|
|
1623
|
-
};
|
|
1624
|
-
const begin = (startedByResync) => {
|
|
1625
|
-
generation += 1;
|
|
1626
|
-
phase = "opening";
|
|
1627
|
-
reason = undefined;
|
|
1628
|
-
let settleRetired = () => {
|
|
1629
|
-
return;
|
|
1630
|
-
};
|
|
1631
|
-
const retiredPromise = new Promise((resolve) => {
|
|
1632
|
-
settleRetired = resolve;
|
|
1633
|
-
});
|
|
1634
|
-
const active = {
|
|
1635
|
-
id: generation,
|
|
1636
|
-
startedByResync,
|
|
1637
|
-
abort: new AbortController,
|
|
1638
|
-
buffer: createBoundedChannel({
|
|
1639
|
-
policy: "ordered",
|
|
1640
|
-
maxItems: maxBufferedEvents,
|
|
1641
|
-
maxBytes: maxBufferedBytes,
|
|
1642
|
-
sizeOf: config.sizeOfEvent
|
|
1643
|
-
}),
|
|
1644
|
-
retiredPromise,
|
|
1645
|
-
settleRetired,
|
|
1646
|
-
retired: false,
|
|
1647
|
-
sourceOpenStarted: false
|
|
1648
|
-
};
|
|
1649
|
-
current = active;
|
|
1650
|
-
publish();
|
|
1651
|
-
if (current !== active || active.retired || phase !== "opening") {
|
|
1652
|
-
return opening ?? Promise.resolve(published);
|
|
1653
|
-
}
|
|
1654
|
-
active.sourceOpenStarted = true;
|
|
1655
|
-
const operation = openGeneration(active);
|
|
1656
|
-
opening = operation;
|
|
1657
|
-
operation.finally(() => {
|
|
1658
|
-
if (opening === operation)
|
|
1659
|
-
opening = undefined;
|
|
1660
|
-
});
|
|
1661
|
-
return operation;
|
|
1662
|
-
};
|
|
1663
|
-
const close = () => {
|
|
1664
|
-
if (phase === "closed")
|
|
1665
|
-
return Promise.resolve(published);
|
|
1666
|
-
const active = current;
|
|
1667
|
-
current = undefined;
|
|
1668
|
-
phase = "closed";
|
|
1669
|
-
reason = undefined;
|
|
1670
|
-
const snapshot = publish();
|
|
1671
|
-
if (active)
|
|
1672
|
-
retire(active);
|
|
1673
|
-
config.signal?.removeEventListener("abort", abortFromConfig);
|
|
1674
|
-
subscribers.clear();
|
|
1675
|
-
return Promise.resolve(snapshot);
|
|
1676
|
-
};
|
|
1677
|
-
function abortFromConfig() {
|
|
1678
|
-
close();
|
|
1679
|
-
}
|
|
1680
|
-
if (config.signal?.aborted) {
|
|
1681
|
-
phase = "closed";
|
|
1682
|
-
published = buildSnapshot();
|
|
1683
|
-
} else {
|
|
1684
|
-
config.signal?.addEventListener("abort", abortFromConfig, { once: true });
|
|
1685
|
-
}
|
|
1686
|
-
return {
|
|
1687
|
-
start() {
|
|
1688
|
-
if (phase === "idle")
|
|
1689
|
-
return begin(false);
|
|
1690
|
-
return opening ?? Promise.resolve(published);
|
|
1691
|
-
},
|
|
1692
|
-
resync() {
|
|
1693
|
-
if (phase === "closed")
|
|
1694
|
-
return Promise.resolve(published);
|
|
1695
|
-
const active = current;
|
|
1696
|
-
if (active?.startedByResync && !active.sourceOpenStarted && phase === "opening" && publishDepth > 0) {
|
|
1697
|
-
return opening ?? Promise.resolve(published);
|
|
1698
|
-
}
|
|
1699
|
-
if (active) {
|
|
1700
|
-
retire(active);
|
|
1701
|
-
if (unsettledSourceOpens + unsettledSourceCloses >= 2) {
|
|
1702
|
-
phase = "unavailable";
|
|
1703
|
-
reason = "controller-capacity";
|
|
1704
|
-
return Promise.resolve(publish());
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
return begin(true);
|
|
1708
|
-
},
|
|
1709
|
-
getSnapshot: () => published,
|
|
1710
|
-
subscribe(listener) {
|
|
1711
|
-
if (phase === "closed")
|
|
1712
|
-
return () => {
|
|
1713
|
-
return;
|
|
1714
|
-
};
|
|
1715
|
-
subscribers.add(listener);
|
|
1716
|
-
return () => subscribers.delete(listener);
|
|
1717
|
-
},
|
|
1718
|
-
close
|
|
1719
|
-
};
|
|
1720
|
-
}
|
|
1721
|
-
// src/browser/resumable.ts
|
|
1722
|
-
import { z as z4 } from "zod";
|
|
1723
|
-
var PositiveSafeIntegerSchema3 = z4.number().int().positive().safe();
|
|
1724
|
-
var BackoffPolicySchema = z4.object({
|
|
1725
|
-
minDelayMs: PositiveSafeIntegerSchema3,
|
|
1726
|
-
maxDelayMs: PositiveSafeIntegerSchema3,
|
|
1727
|
-
jitter: z4.number().min(0).max(1)
|
|
1139
|
+
var BackoffPolicySchema = z2.object({
|
|
1140
|
+
minDelayMs: PositiveSafeIntegerSchema,
|
|
1141
|
+
maxDelayMs: PositiveSafeIntegerSchema,
|
|
1142
|
+
jitter: z2.number().min(0).max(1)
|
|
1728
1143
|
}).strict().readonly().refine((policy) => policy.maxDelayMs >= policy.minDelayMs, {
|
|
1729
1144
|
message: "maxDelayMs must be at least minDelayMs"
|
|
1730
1145
|
});
|
|
@@ -1813,19 +1228,19 @@ function isModuleNotFound(error) {
|
|
|
1813
1228
|
}
|
|
1814
1229
|
|
|
1815
1230
|
// src/realtime/request.ts
|
|
1816
|
-
import { z as
|
|
1817
|
-
var RealtimeRequestPhaseSchema =
|
|
1231
|
+
import { z as z3 } from "zod";
|
|
1232
|
+
var RealtimeRequestPhaseSchema = z3.enum([
|
|
1818
1233
|
"engine-handoff",
|
|
1819
1234
|
"engine-ack-received",
|
|
1820
1235
|
"settled",
|
|
1821
1236
|
"timeout",
|
|
1822
1237
|
"disconnected"
|
|
1823
1238
|
]);
|
|
1824
|
-
var RealtimeRequestPhaseEventSchema =
|
|
1825
|
-
requestId:
|
|
1826
|
-
event:
|
|
1239
|
+
var RealtimeRequestPhaseEventSchema = z3.object({
|
|
1240
|
+
requestId: z3.string().min(1),
|
|
1241
|
+
event: z3.string().min(1),
|
|
1827
1242
|
phase: RealtimeRequestPhaseSchema,
|
|
1828
|
-
elapsedMs:
|
|
1243
|
+
elapsedMs: z3.number().finite().nonnegative()
|
|
1829
1244
|
}).strict();
|
|
1830
1245
|
|
|
1831
1246
|
class RealtimeRequestTimeoutError extends Error {
|
|
@@ -1915,9 +1330,9 @@ function parseIssues(value) {
|
|
|
1915
1330
|
}
|
|
1916
1331
|
|
|
1917
1332
|
// src/realtime/rejection.ts
|
|
1918
|
-
import { z as
|
|
1333
|
+
import { z as z4 } from "zod";
|
|
1919
1334
|
function realtimeContractViolation(options) {
|
|
1920
|
-
const issues = options.cause instanceof
|
|
1335
|
+
const issues = options.cause instanceof z4.ZodError ? zodIssues(options.cause) : undefined;
|
|
1921
1336
|
const reason = options.reason.replaceAll("-", " ");
|
|
1922
1337
|
const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
|
|
1923
1338
|
event: options.event,
|
|
@@ -2653,25 +2068,25 @@ function createSocketIOClientInternal(config, onRequestPhase) {
|
|
|
2653
2068
|
};
|
|
2654
2069
|
}
|
|
2655
2070
|
// src/realtime/contract.ts
|
|
2656
|
-
import { z as
|
|
2071
|
+
import { z as z5 } from "zod";
|
|
2657
2072
|
function defineRealtimeContract(contract) {
|
|
2658
2073
|
return contract;
|
|
2659
2074
|
}
|
|
2660
|
-
var RealtimeRejectDirectionSchema =
|
|
2075
|
+
var RealtimeRejectDirectionSchema = z5.enum([
|
|
2661
2076
|
"client-inbound",
|
|
2662
2077
|
"client-outbound",
|
|
2663
2078
|
"server-inbound",
|
|
2664
2079
|
"server-outbound"
|
|
2665
2080
|
]);
|
|
2666
|
-
var RealtimeRejectPhaseSchema =
|
|
2667
|
-
var RealtimeRejectReasonSchema =
|
|
2081
|
+
var RealtimeRejectPhaseSchema = z5.enum(["arguments", "acknowledgement"]);
|
|
2082
|
+
var RealtimeRejectReasonSchema = z5.enum([
|
|
2668
2083
|
"unknown-event",
|
|
2669
2084
|
"invalid-arguments",
|
|
2670
2085
|
"invalid-acknowledgement-value",
|
|
2671
2086
|
"missing-acknowledgement",
|
|
2672
2087
|
"rejected-by-peer"
|
|
2673
2088
|
]);
|
|
2674
|
-
var RealtimeRejectFaultSchema =
|
|
2089
|
+
var RealtimeRejectFaultSchema = z5.enum(["peer", "local"]);
|
|
2675
2090
|
export {
|
|
2676
2091
|
zodIssues,
|
|
2677
2092
|
unauthorized,
|