stitchkit 0.68.10 → 0.68.11
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/browser/socket-io.d.ts +8 -2
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/{index-557by2db.js → index-7b188kmz.js} +15 -0
- package/dist/index.js +169 -11
- package/dist/node.js +1 -1
- package/dist/realtime/index.d.ts +1 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/request.d.ts +25 -0
- package/dist/realtime/request.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/testing.js +1 -1
- package/llms-full.txt +47 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StitchLogger } from '../logger.js';
|
|
2
2
|
import type { RealtimeAcknowledgedEvent, RealtimeAcknowledgement, RealtimeContract, RealtimeEventRegistry, RealtimeRejectedEventHook, RealtimeRequestArguments } from '../realtime/contract.js';
|
|
3
|
-
import { type RealtimeRequestOptions } from '../realtime/request.js';
|
|
3
|
+
import { type RealtimeRequestOptions, type RealtimeRequestPhaseHook } from '../realtime/request.js';
|
|
4
4
|
import { type ValidatedRealtimeSocket } from '../realtime/socket.js';
|
|
5
5
|
/**
|
|
6
6
|
* How this project loads the optional Socket.IO **client** peer.
|
|
@@ -207,9 +207,15 @@ export interface BindRealtimeClientOptions {
|
|
|
207
207
|
export interface RealtimeClientOptions<TServerToClient extends RealtimeEventRegistry> extends BindRealtimeClientOptions, SocketIOClientConfig<{
|
|
208
208
|
[TEvent in keyof TServerToClient]: (...args: unknown[]) => void;
|
|
209
209
|
}> {
|
|
210
|
+
/**
|
|
211
|
+
* Observe bounded metadata-only phases of acknowledged requests. Engine.IO
|
|
212
|
+
* phases are local encoder/decoder boundaries, not remote send time or RTT.
|
|
213
|
+
* Observer failures are isolated from request lifecycle.
|
|
214
|
+
*/
|
|
215
|
+
onRequestPhase?: RealtimeRequestPhaseHook;
|
|
210
216
|
}
|
|
211
217
|
/** Add contract validation and typed acknowledgements without owning the transport lifecycle. */
|
|
212
218
|
export declare function bindRealtimeClient<const TServerToClient extends RealtimeEventRegistry, const TClientToServer extends RealtimeEventRegistry>(contract: RealtimeContract<TServerToClient, TClientToServer>, transport: RealtimeClientTransport, { onRejected, logger }?: BindRealtimeClientOptions): BoundRealtimeClient<TServerToClient, TClientToServer>;
|
|
213
|
-
export declare function createRealtimeClient<const TServerToClient extends RealtimeEventRegistry, const TClientToServer extends RealtimeEventRegistry>(contract: RealtimeContract<TServerToClient, TClientToServer>, { onRejected, logger, ...config }: RealtimeClientOptions<TServerToClient>): RealtimeClient<TServerToClient, TClientToServer>;
|
|
219
|
+
export declare function createRealtimeClient<const TServerToClient extends RealtimeEventRegistry, const TClientToServer extends RealtimeEventRegistry>(contract: RealtimeContract<TServerToClient, TClientToServer>, { onRejected, logger, onRequestPhase, ...config }: RealtimeClientOptions<TServerToClient>): RealtimeClient<TServerToClient, TClientToServer>;
|
|
214
220
|
export declare function createSocketIOClient<TServerEvents extends SocketEventMap, TClientEvents extends SocketEventMap>(config: SocketIOClientConfig<TServerEvents>): SocketIOClient<TServerEvents, TClientEvents>;
|
|
215
221
|
//# sourceMappingURL=socket-io.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/browser/socket-io.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EACvB,gBAAgB,EAChB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,sBAAsB,
|
|
1
|
+
{"version":3,"file":"socket-io.d.ts","sourceRoot":"","sources":["../../src/browser/socket-io.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
// src/realtime/request.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var RealtimeRequestPhaseSchema = z.enum([
|
|
4
|
+
"engine-handoff",
|
|
5
|
+
"engine-ack-received",
|
|
6
|
+
"settled",
|
|
7
|
+
"timeout",
|
|
8
|
+
"disconnected"
|
|
9
|
+
]);
|
|
10
|
+
var RealtimeRequestPhaseEventSchema = z.object({
|
|
11
|
+
requestId: z.string().min(1),
|
|
12
|
+
event: z.string().min(1),
|
|
13
|
+
phase: RealtimeRequestPhaseSchema,
|
|
14
|
+
elapsedMs: z.number().finite().nonnegative()
|
|
15
|
+
}).strict();
|
|
16
|
+
|
|
2
17
|
class RealtimeRequestTimeoutError extends Error {
|
|
3
18
|
code = "REALTIME_REQUEST_TIMEOUT";
|
|
4
19
|
event;
|
package/dist/index.js
CHANGED
|
@@ -1099,6 +1099,21 @@ function isModuleNotFound(error) {
|
|
|
1099
1099
|
}
|
|
1100
1100
|
|
|
1101
1101
|
// src/realtime/request.ts
|
|
1102
|
+
import { z as z2 } from "zod";
|
|
1103
|
+
var RealtimeRequestPhaseSchema = z2.enum([
|
|
1104
|
+
"engine-handoff",
|
|
1105
|
+
"engine-ack-received",
|
|
1106
|
+
"settled",
|
|
1107
|
+
"timeout",
|
|
1108
|
+
"disconnected"
|
|
1109
|
+
]);
|
|
1110
|
+
var RealtimeRequestPhaseEventSchema = z2.object({
|
|
1111
|
+
requestId: z2.string().min(1),
|
|
1112
|
+
event: z2.string().min(1),
|
|
1113
|
+
phase: RealtimeRequestPhaseSchema,
|
|
1114
|
+
elapsedMs: z2.number().finite().nonnegative()
|
|
1115
|
+
}).strict();
|
|
1116
|
+
|
|
1102
1117
|
class RealtimeRequestTimeoutError extends Error {
|
|
1103
1118
|
code = "REALTIME_REQUEST_TIMEOUT";
|
|
1104
1119
|
event;
|
|
@@ -1186,9 +1201,9 @@ function parseIssues(value) {
|
|
|
1186
1201
|
}
|
|
1187
1202
|
|
|
1188
1203
|
// src/realtime/rejection.ts
|
|
1189
|
-
import { z as
|
|
1204
|
+
import { z as z3 } from "zod";
|
|
1190
1205
|
function realtimeContractViolation(options) {
|
|
1191
|
-
const issues = options.cause instanceof
|
|
1206
|
+
const issues = options.cause instanceof z3.ZodError ? zodIssues(options.cause) : undefined;
|
|
1192
1207
|
const reason = options.reason.replaceAll("-", " ");
|
|
1193
1208
|
const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
|
|
1194
1209
|
event: options.event,
|
|
@@ -1469,6 +1484,63 @@ function createRetainedTopics() {
|
|
|
1469
1484
|
}
|
|
1470
1485
|
|
|
1471
1486
|
// src/browser/socket-io.ts
|
|
1487
|
+
var realtimeRequestTraces = new WeakMap;
|
|
1488
|
+
function observeRealtimeRequestPhase(trace, phase) {
|
|
1489
|
+
const observation = {
|
|
1490
|
+
requestId: trace.requestId,
|
|
1491
|
+
event: trace.event,
|
|
1492
|
+
phase,
|
|
1493
|
+
elapsedMs: performance.now() - trace.startedAt
|
|
1494
|
+
};
|
|
1495
|
+
try {
|
|
1496
|
+
const result = trace.observe(observation);
|
|
1497
|
+
if (result)
|
|
1498
|
+
Promise.resolve(result).catch(() => {
|
|
1499
|
+
return;
|
|
1500
|
+
});
|
|
1501
|
+
} catch {}
|
|
1502
|
+
}
|
|
1503
|
+
function socketIoPacketIdentity(data, expected) {
|
|
1504
|
+
if (typeof data !== "string")
|
|
1505
|
+
return null;
|
|
1506
|
+
const type = data.charAt(0);
|
|
1507
|
+
const binary = type === (expected === "event" ? "5" : "6");
|
|
1508
|
+
if (type !== (expected === "event" ? "2" : "3") && !binary)
|
|
1509
|
+
return null;
|
|
1510
|
+
let offset = 1;
|
|
1511
|
+
if (binary) {
|
|
1512
|
+
const separator = data.indexOf("-", offset);
|
|
1513
|
+
if (separator < 0)
|
|
1514
|
+
return null;
|
|
1515
|
+
for (let index = offset;index < separator; index += 1) {
|
|
1516
|
+
const code = data.charCodeAt(index);
|
|
1517
|
+
if (code < 48 || code > 57)
|
|
1518
|
+
return null;
|
|
1519
|
+
}
|
|
1520
|
+
offset = separator + 1;
|
|
1521
|
+
}
|
|
1522
|
+
let namespace = "/";
|
|
1523
|
+
if (data.charAt(offset) === "/") {
|
|
1524
|
+
const separator = data.indexOf(",", offset);
|
|
1525
|
+
if (separator < 0)
|
|
1526
|
+
return null;
|
|
1527
|
+
namespace = data.slice(offset, separator);
|
|
1528
|
+
offset = separator + 1;
|
|
1529
|
+
}
|
|
1530
|
+
const start = offset;
|
|
1531
|
+
while (offset < data.length) {
|
|
1532
|
+
const code = data.charCodeAt(offset);
|
|
1533
|
+
if (code < 48 || code > 57)
|
|
1534
|
+
break;
|
|
1535
|
+
offset += 1;
|
|
1536
|
+
}
|
|
1537
|
+
if (offset === start)
|
|
1538
|
+
return null;
|
|
1539
|
+
return { namespace, id: data.slice(start, offset) };
|
|
1540
|
+
}
|
|
1541
|
+
function packetIdentityKey(identity) {
|
|
1542
|
+
return `${identity.namespace}:${identity.id}`;
|
|
1543
|
+
}
|
|
1472
1544
|
var SOCKET_IO_CLIENT = "socket.io-client";
|
|
1473
1545
|
var ioLoader = null;
|
|
1474
1546
|
function loadIo() {
|
|
@@ -1564,8 +1636,20 @@ function bindRealtimeClient(contract, transport, { onRejected, logger } = {}) {
|
|
|
1564
1636
|
if (!definition?.ack) {
|
|
1565
1637
|
throw new Error(`Realtime request "${event}" has no acknowledgement schema`);
|
|
1566
1638
|
}
|
|
1567
|
-
const
|
|
1568
|
-
const
|
|
1639
|
+
const pending = transport.emitWithAck(event, parsedArgs, { timeoutMs });
|
|
1640
|
+
const trace = realtimeRequestTraces.get(pending);
|
|
1641
|
+
if (trace)
|
|
1642
|
+
realtimeRequestTraces.delete(pending);
|
|
1643
|
+
const value = await pending;
|
|
1644
|
+
let acknowledgement;
|
|
1645
|
+
try {
|
|
1646
|
+
acknowledgement = parseRealtimeRequestAcknowledgement(definition.ack, event, "client-inbound", value, onRejected, logger);
|
|
1647
|
+
} finally {
|
|
1648
|
+
if (trace && !trace.closed) {
|
|
1649
|
+
trace.closed = true;
|
|
1650
|
+
observeRealtimeRequestPhase(trace, "settled");
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1569
1653
|
return acknowledgement;
|
|
1570
1654
|
}
|
|
1571
1655
|
return {
|
|
@@ -1577,8 +1661,8 @@ function bindRealtimeClient(contract, transport, { onRejected, logger } = {}) {
|
|
|
1577
1661
|
onConnectionChange: (listener) => transport.onConnectionChange(listener)
|
|
1578
1662
|
};
|
|
1579
1663
|
}
|
|
1580
|
-
function createRealtimeClient(contract, { onRejected, logger, ...config }) {
|
|
1581
|
-
const transport =
|
|
1664
|
+
function createRealtimeClient(contract, { onRejected, logger, onRequestPhase, ...config }) {
|
|
1665
|
+
const transport = createSocketIOClientInternal(config, onRequestPhase);
|
|
1582
1666
|
const bound = bindRealtimeClient(contract, transport, { onRejected, logger });
|
|
1583
1667
|
return {
|
|
1584
1668
|
...bound,
|
|
@@ -1590,12 +1674,17 @@ function createRealtimeClient(contract, { onRejected, logger, ...config }) {
|
|
|
1590
1674
|
};
|
|
1591
1675
|
}
|
|
1592
1676
|
function createSocketIOClient(config) {
|
|
1677
|
+
return createSocketIOClientInternal(config);
|
|
1678
|
+
}
|
|
1679
|
+
function createSocketIOClientInternal(config, onRequestPhase) {
|
|
1593
1680
|
let socket = null;
|
|
1594
1681
|
const resolveIo = createIoResolver(config.peers?.client);
|
|
1595
1682
|
let desiredConnected = false;
|
|
1596
1683
|
let loadingPeer = false;
|
|
1597
1684
|
let reconnectTimer = null;
|
|
1598
1685
|
const pendingRequestDisconnects = new Set;
|
|
1686
|
+
const requestTracesByNativeKey = new Map;
|
|
1687
|
+
let startingRequestTrace = null;
|
|
1599
1688
|
const serverDisconnectDelay = config.reconnectOnServerDisconnect ?? 1000;
|
|
1600
1689
|
const connectionListeners = new Set;
|
|
1601
1690
|
const subscriptions = new Set;
|
|
@@ -1629,6 +1718,37 @@ function createSocketIOClient(config) {
|
|
|
1629
1718
|
reconnectionDelayMax: config.reconnectionDelayMax ?? 5000,
|
|
1630
1719
|
timeout: config.timeout ?? 20000
|
|
1631
1720
|
});
|
|
1721
|
+
if (onRequestPhase) {
|
|
1722
|
+
socket.io.on("open", () => {
|
|
1723
|
+
const engine = socket?.io.engine;
|
|
1724
|
+
if (!engine)
|
|
1725
|
+
return;
|
|
1726
|
+
engine.on("packetCreate", (packet) => {
|
|
1727
|
+
if (!startingRequestTrace || packet.type !== "message")
|
|
1728
|
+
return;
|
|
1729
|
+
const identity = socketIoPacketIdentity(packet.data, "event");
|
|
1730
|
+
if (!identity)
|
|
1731
|
+
return;
|
|
1732
|
+
const key = packetIdentityKey(identity);
|
|
1733
|
+
startingRequestTrace.nativeKey = key;
|
|
1734
|
+
requestTracesByNativeKey.set(key, startingRequestTrace);
|
|
1735
|
+
observeRealtimeRequestPhase(startingRequestTrace, "engine-handoff");
|
|
1736
|
+
});
|
|
1737
|
+
engine.on("packet", (packet) => {
|
|
1738
|
+
if (packet.type !== "message")
|
|
1739
|
+
return;
|
|
1740
|
+
const identity = socketIoPacketIdentity(packet.data, "ack");
|
|
1741
|
+
if (!identity)
|
|
1742
|
+
return;
|
|
1743
|
+
const key = packetIdentityKey(identity);
|
|
1744
|
+
const trace = requestTracesByNativeKey.get(key);
|
|
1745
|
+
if (!trace || trace.closed)
|
|
1746
|
+
return;
|
|
1747
|
+
observeRealtimeRequestPhase(trace, "engine-ack-received");
|
|
1748
|
+
requestTracesByNativeKey.delete(key);
|
|
1749
|
+
});
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1632
1752
|
socket.on("connect", () => notifyConnection(true));
|
|
1633
1753
|
socket.on("disconnect", (reason) => {
|
|
1634
1754
|
notifyConnection(false, reason);
|
|
@@ -1738,11 +1858,30 @@ function createSocketIOClient(config) {
|
|
|
1738
1858
|
return true;
|
|
1739
1859
|
},
|
|
1740
1860
|
emitWithAck(event, args, options) {
|
|
1861
|
+
const trace = onRequestPhase ? {
|
|
1862
|
+
requestId: crypto.randomUUID(),
|
|
1863
|
+
event,
|
|
1864
|
+
startedAt: performance.now(),
|
|
1865
|
+
observe: onRequestPhase,
|
|
1866
|
+
closed: false
|
|
1867
|
+
} : undefined;
|
|
1868
|
+
const closeTrace = (phase) => {
|
|
1869
|
+
if (!trace || trace.closed)
|
|
1870
|
+
return;
|
|
1871
|
+
trace.closed = true;
|
|
1872
|
+
if (trace.nativeKey)
|
|
1873
|
+
requestTracesByNativeKey.delete(trace.nativeKey);
|
|
1874
|
+
observeRealtimeRequestPhase(trace, phase);
|
|
1875
|
+
};
|
|
1741
1876
|
const active = socket;
|
|
1742
1877
|
if (!active?.connected) {
|
|
1743
|
-
|
|
1878
|
+
const pending2 = Promise.reject(new RealtimeRequestDisconnectedError(event));
|
|
1879
|
+
closeTrace("disconnected");
|
|
1880
|
+
if (trace)
|
|
1881
|
+
realtimeRequestTraces.set(pending2, trace);
|
|
1882
|
+
return pending2;
|
|
1744
1883
|
}
|
|
1745
|
-
|
|
1884
|
+
const pending = new Promise((resolve, reject) => {
|
|
1746
1885
|
let settled = false;
|
|
1747
1886
|
const finish = (result) => {
|
|
1748
1887
|
if (settled)
|
|
@@ -1753,14 +1892,31 @@ function createSocketIOClient(config) {
|
|
|
1753
1892
|
result();
|
|
1754
1893
|
};
|
|
1755
1894
|
const onDisconnect = () => {
|
|
1756
|
-
finish(() =>
|
|
1895
|
+
finish(() => {
|
|
1896
|
+
closeTrace("disconnected");
|
|
1897
|
+
reject(new RealtimeRequestDisconnectedError(event));
|
|
1898
|
+
});
|
|
1757
1899
|
};
|
|
1758
1900
|
pendingRequestDisconnects.add(onDisconnect);
|
|
1759
1901
|
active.on("disconnect", onDisconnect);
|
|
1760
|
-
|
|
1761
|
-
|
|
1902
|
+
let acknowledgement;
|
|
1903
|
+
startingRequestTrace = trace ?? null;
|
|
1904
|
+
try {
|
|
1905
|
+
acknowledgement = active.timeout(options.timeoutMs).emitWithAck(event, ...args);
|
|
1906
|
+
} finally {
|
|
1907
|
+
startingRequestTrace = null;
|
|
1908
|
+
}
|
|
1909
|
+
acknowledgement.then((value) => finish(() => resolve(value)), () => {
|
|
1910
|
+
finish(() => {
|
|
1911
|
+
const connected = active.connected;
|
|
1912
|
+
closeTrace(connected ? "timeout" : "disconnected");
|
|
1913
|
+
reject(connected ? new RealtimeRequestTimeoutError(event, options.timeoutMs) : new RealtimeRequestDisconnectedError(event));
|
|
1914
|
+
});
|
|
1762
1915
|
});
|
|
1763
1916
|
});
|
|
1917
|
+
if (trace)
|
|
1918
|
+
realtimeRequestTraces.set(pending, trace);
|
|
1919
|
+
return pending;
|
|
1764
1920
|
},
|
|
1765
1921
|
onConnectionChange(listener) {
|
|
1766
1922
|
connectionListeners.add(listener);
|
|
@@ -1783,6 +1939,8 @@ export {
|
|
|
1783
1939
|
REALTIME_REJECTION_KEY,
|
|
1784
1940
|
RealtimeRequestDisconnectedError,
|
|
1785
1941
|
RealtimeRequestInvalidAcknowledgementError,
|
|
1942
|
+
RealtimeRequestPhaseEventSchema,
|
|
1943
|
+
RealtimeRequestPhaseSchema,
|
|
1786
1944
|
RealtimeRequestRejectedError,
|
|
1787
1945
|
RealtimeRequestTimeoutError,
|
|
1788
1946
|
STITCH_ERROR_STATUS,
|
package/dist/node.js
CHANGED
package/dist/realtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { defineRealtimeContract, type InferRealtimeEventMap, type RealtimeAcknowledgedEvent, type RealtimeAcknowledgement, type RealtimeContract, type RealtimeEmitArguments, type RealtimeEventArguments, type RealtimeEventDefinition, type RealtimeEventHandler, type RealtimeEventRegistry, type RealtimeRejectDirection, type RealtimeRejectedEvent, type RealtimeRejectedEventHook, type RealtimeRequestArguments, } from './contract.js';
|
|
2
2
|
export { asRealtimeRejection, REALTIME_REJECTION_KEY, type RealtimeRejectionEnvelope, type RealtimeRejectionIssue, type RealtimeRejectionReport, } from './rejected-frame.js';
|
|
3
|
-
export { RealtimeRequestDisconnectedError, RealtimeRequestInvalidAcknowledgementError, type RealtimeRequestOptions, RealtimeRequestRejectedError, RealtimeRequestTimeoutError, } from './request.js';
|
|
3
|
+
export { RealtimeRequestDisconnectedError, RealtimeRequestInvalidAcknowledgementError, type RealtimeRequestOptions, type RealtimeRequestPhase, type RealtimeRequestPhaseEvent, RealtimeRequestPhaseEventSchema, type RealtimeRequestPhaseHook, RealtimeRequestPhaseSchema, RealtimeRequestRejectedError, RealtimeRequestTimeoutError, } from './request.js';
|
|
4
4
|
export type { ValidatedRealtimeSocket } from './socket.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,gCAAgC,EAChC,0CAA0C,EAC1C,KAAK,sBAAsB,EAC3B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,gCAAgC,EAChC,0CAA0C,EAC1C,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,+BAA+B,EAC/B,KAAK,wBAAwB,EAC7B,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,GAC5B,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1,4 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import type { RealtimeRejectionIssue } from './rejected-frame.js';
|
|
3
|
+
/** Closed lifecycle reported by an opt-in acknowledged-request observer. */
|
|
4
|
+
export declare const RealtimeRequestPhaseSchema: z.ZodEnum<{
|
|
5
|
+
disconnected: "disconnected";
|
|
6
|
+
"engine-ack-received": "engine-ack-received";
|
|
7
|
+
"engine-handoff": "engine-handoff";
|
|
8
|
+
settled: "settled";
|
|
9
|
+
timeout: "timeout";
|
|
10
|
+
}>;
|
|
11
|
+
/** Metadata-only observation: no arguments, acknowledgement or packet bytes. */
|
|
12
|
+
export declare const RealtimeRequestPhaseEventSchema: z.ZodObject<{
|
|
13
|
+
requestId: z.ZodString;
|
|
14
|
+
event: z.ZodString;
|
|
15
|
+
phase: z.ZodEnum<{
|
|
16
|
+
disconnected: "disconnected";
|
|
17
|
+
"engine-ack-received": "engine-ack-received";
|
|
18
|
+
"engine-handoff": "engine-handoff";
|
|
19
|
+
settled: "settled";
|
|
20
|
+
timeout: "timeout";
|
|
21
|
+
}>;
|
|
22
|
+
elapsedMs: z.ZodNumber;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
export type RealtimeRequestPhase = z.infer<typeof RealtimeRequestPhaseSchema>;
|
|
25
|
+
export type RealtimeRequestPhaseEvent = z.infer<typeof RealtimeRequestPhaseEventSchema>;
|
|
26
|
+
export type RealtimeRequestPhaseHook = (event: RealtimeRequestPhaseEvent) => void | Promise<void>;
|
|
2
27
|
export interface RealtimeRequestOptions {
|
|
3
28
|
/** Maximum acknowledgement wait in milliseconds. Must be finite and > 0. */
|
|
4
29
|
timeoutMs: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/realtime/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAK3C;CACF;AAED,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,mCAAmC;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAIxB;CACF;AAED,qBAAa,0CAA2C,SAAQ,KAAK;IACnE,QAAQ,CAAC,IAAI,8CAA8C;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAIxC;CACF;AAED;;;;;;;;;GASG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,sBAAsB,EAAE,GAAG,SAAS,CAAC;IAEtD,YACE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,sBAAsB,EAAE,EAOlC;CACF"}
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/realtime/request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,4EAA4E;AAC5E,eAAO,MAAM,0BAA0B;;;;;;EAMrC,CAAC;AAEH,gFAAgF;AAChF,eAAO,MAAM,+BAA+B;;;;;;;;;;;kBAOjC,CAAC;AAEZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAC;AACxF,MAAM,MAAM,wBAAwB,GAAG,CACrC,KAAK,EAAE,yBAAyB,KAC7B,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAK3C;CACF;AAED,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,QAAQ,CAAC,IAAI,mCAAmC;IAChD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAIxB;CACF;AAED,qBAAa,0CAA2C,SAAQ,KAAK;IACnE,QAAQ,CAAC,IAAI,8CAA8C;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,YAAY,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAIxC;CACF;AAED;;;;;;;;;GASG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,QAAQ,CAAC,IAAI,+BAA+B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,sBAAsB,EAAE,GAAG,SAAS,CAAC;IAEtD,YACE,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,sBAAsB,EAAE,EAOlC;CACF"}
|
package/dist/server/index.js
CHANGED
package/dist/testing.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
RealtimeRequestDisconnectedError,
|
|
12
12
|
RealtimeRequestInvalidAcknowledgementError,
|
|
13
13
|
RealtimeRequestTimeoutError
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-7b188kmz.js";
|
|
15
15
|
import"./index-dk6e56g0.js";
|
|
16
16
|
import {
|
|
17
17
|
mcpProjectionCandidate,
|
package/llms-full.txt
CHANGED
|
@@ -6161,6 +6161,7 @@ const socket = createRealtimeClient(realtimeContract, {
|
|
|
6161
6161
|
url: 'https://api.example.com',
|
|
6162
6162
|
retain: ['note:created'],
|
|
6163
6163
|
onRejected: (event) => reportClientError(event),
|
|
6164
|
+
onRequestPhase: (event) => metrics.realtimeRequestPhase(event),
|
|
6164
6165
|
})
|
|
6165
6166
|
|
|
6166
6167
|
socket.connect()
|
|
@@ -6215,6 +6216,48 @@ or resumable delivery should use separate correlated events or the async
|
|
|
6215
6216
|
operation protocol; keeping one acknowledgement open is not a durable RPC/job
|
|
6216
6217
|
transport.
|
|
6217
6218
|
|
|
6219
|
+
### Acknowledged-request phases
|
|
6220
|
+
|
|
6221
|
+
`createRealtimeClient` can expose the local boundary that a single Promise
|
|
6222
|
+
normally hides:
|
|
6223
|
+
|
|
6224
|
+
```ts
|
|
6225
|
+
const socket = createRealtimeClient(realtimeContract, {
|
|
6226
|
+
url,
|
|
6227
|
+
onRequestPhase: ({ requestId, event, phase, elapsedMs }) => {
|
|
6228
|
+
requestPhaseHistogram.record(elapsedMs, { requestId, event, phase })
|
|
6229
|
+
},
|
|
6230
|
+
})
|
|
6231
|
+
```
|
|
6232
|
+
|
|
6233
|
+
The hook is opt-in and each record has exactly four metadata fields: an opaque,
|
|
6234
|
+
Kit-owned `requestId`, the contract event name, monotonic `elapsedMs`, and one
|
|
6235
|
+
closed phase:
|
|
6236
|
+
|
|
6237
|
+
| Phase | Exact local boundary |
|
|
6238
|
+
|-------|----------------------|
|
|
6239
|
+
| `engine-handoff` | Engine.IO created the outbound message packet and accepted it into its write path |
|
|
6240
|
+
| `engine-ack-received` | Engine.IO decoded the inbound acknowledgement message, before Socket.IO invokes the acknowledgement callback |
|
|
6241
|
+
| `settled` | the acknowledgement callback ran and Stitchkit finished acknowledgement validation |
|
|
6242
|
+
| `timeout` | the existing native acknowledgement timeout won |
|
|
6243
|
+
| `disconnected` | the request began disconnected or an in-flight disconnect won |
|
|
6244
|
+
|
|
6245
|
+
Engine handoff is not proof of a physical network write. Engine acknowledgement
|
|
6246
|
+
receipt is not a remote clock, end-to-end RTT or proof that application
|
|
6247
|
+
validation has run. The useful interval is local and monotonic:
|
|
6248
|
+
`engine-ack-received → settled` isolates callback scheduling plus validation
|
|
6249
|
+
from transport waiting.
|
|
6250
|
+
|
|
6251
|
+
Records never contain request arguments, acknowledgement values, raw packets,
|
|
6252
|
+
credentials, URLs or query data. Concurrent requests are correlated internally
|
|
6253
|
+
with Socket.IO acknowledgement ids, but those ids are never exposed. A timeout
|
|
6254
|
+
or disconnect is terminal, a late packet cannot reopen the identity, and sync
|
|
6255
|
+
or async observer failures are ignored so telemetry cannot change request
|
|
6256
|
+
correctness. With no hook, no request identity, Engine.IO listener or correlation
|
|
6257
|
+
map entry is created. The low-level `createSocketIOClient` and non-owning
|
|
6258
|
+
`bindRealtimeClient` remain unchanged; this phase surface belongs to the
|
|
6259
|
+
canonical composed client that owns both transport and validation.
|
|
6260
|
+
|
|
6218
6261
|
## Low-level transport
|
|
6219
6262
|
|
|
6220
6263
|
`createSocketIOClient` remains the low-level Socket.IO transport wrapper for
|
|
@@ -11248,7 +11291,7 @@ The browser-and-server entrypoint. Re-exports everything from
|
|
|
11248
11291
|
| `SocketIOClientConfig` | _type_ | config for `createSocketIOClient` (incl. `retain`, `onConnectError`, `onDroppedEmit`) |
|
|
11249
11292
|
| `SocketEventMap` | _type_ | the shape of an event map |
|
|
11250
11293
|
| `RealtimeClient` | _type_ | validated client inferred from a realtime contract |
|
|
11251
|
-
| `RealtimeClientOptions` | _type_ | transport options
|
|
11294
|
+
| `RealtimeClientOptions` | _type_ | transport options plus rejected-event and metadata-only acknowledged-request phase hooks for `createRealtimeClient` |
|
|
11252
11295
|
| `BoundRealtimeClient` | _type_ | validated non-owning `on`/`emit`/`request` client with no `connect`/`disconnect` |
|
|
11253
11296
|
| `RealtimeClientTransport` | _type_ | minimal existing transport capability accepted by `bindRealtimeClient` |
|
|
11254
11297
|
| `BindRealtimeClientOptions` | _type_ | rejection/logger options for a bound existing transport |
|
|
@@ -11256,6 +11299,9 @@ The browser-and-server entrypoint. Re-exports everything from
|
|
|
11256
11299
|
| `RealtimeAcknowledgement` | _type_ | validated acknowledgement output inferred from an event definition |
|
|
11257
11300
|
| `RealtimeRequestArguments` | _type_ | request arguments inferred from an acknowledged event tuple |
|
|
11258
11301
|
| `RealtimeRequestOptions` | _type_ | finite positive native acknowledgement `timeoutMs` |
|
|
11302
|
+
| `RealtimeRequestPhaseSchema` / `RealtimeRequestPhase` | schema / _type_ | closed `engine-handoff` / `engine-ack-received` / `settled` / `timeout` / `disconnected` lifecycle |
|
|
11303
|
+
| `RealtimeRequestPhaseEventSchema` / `RealtimeRequestPhaseEvent` | schema / _type_ | strict metadata-only `{ requestId, event, phase, elapsedMs }` observation |
|
|
11304
|
+
| `RealtimeRequestPhaseHook` | _type_ | isolated sync/async observer accepted by `RealtimeClientOptions.onRequestPhase` |
|
|
11259
11305
|
| `RealtimeRequestTimeoutError` | class | stable `REALTIME_REQUEST_TIMEOUT` rejection |
|
|
11260
11306
|
| `RealtimeRequestDisconnectedError` | class | stable `REALTIME_REQUEST_DISCONNECTED` rejection, including an immediate disconnected call |
|
|
11261
11307
|
| `RealtimeRequestInvalidAcknowledgementError` | class | invalid ack was reported through `onRejected` and the request rejected |
|
package/package.json
CHANGED