stitchkit 0.48.0 → 0.49.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/README.md +1 -2
- package/dist/browser/client.d.ts +3 -0
- package/dist/browser/client.d.ts.map +1 -1
- package/dist/browser/http.d.ts +7 -4
- package/dist/browser/http.d.ts.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/{index-nrytvb30.js → index-03j2t778.js} +5 -8
- package/dist/{index-kp8xamqp.js → index-0hj37z43.js} +4 -2
- package/dist/index-48ffdxgk.js +6 -0
- package/dist/{index-44xysy8r.js → index-fjfzsq6y.js} +383 -26
- package/dist/index-h05ygjqx.js +149 -0
- package/dist/{index-ee621cmy.js → index-jewp9r0a.js} +5 -139
- package/dist/index-p9d4cxt5.js +436 -0
- package/dist/{index-8ekq6res.js → index-v58mwa19.js} +4 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -3
- package/dist/node.d.ts +4 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +109 -14
- package/dist/observability/audit.d.ts +4 -1
- package/dist/observability/audit.d.ts.map +1 -1
- package/dist/observability/index.d.ts +1 -0
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +150 -16
- package/dist/observability/status.d.ts +105 -0
- package/dist/observability/status.d.ts.map +1 -0
- package/dist/server/bun.d.ts +7 -8
- package/dist/server/bun.d.ts.map +1 -1
- package/dist/server/implement.d.ts +16 -6
- package/dist/server/implement.d.ts.map +1 -1
- package/dist/server/index.d.ts +4 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +132 -11
- package/dist/server/node.d.ts +12 -13
- package/dist/server/node.d.ts.map +1 -1
- package/dist/server/router.d.ts +4 -1
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/shutdown.d.ts +76 -0
- package/dist/server/shutdown.d.ts.map +1 -0
- package/dist/server/socket-io-config.d.ts +5 -1
- package/dist/server/socket-io-config.d.ts.map +1 -1
- package/dist/server/socket-io-node.d.ts +4 -1
- package/dist/server/socket-io-node.d.ts.map +1 -1
- package/dist/server/socket-io.d.ts +12 -4
- package/dist/server/socket-io.d.ts.map +1 -1
- package/dist/testing.d.ts +34 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +36 -0
- package/dist/tools/mcp.d.ts +1 -0
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools.js +21 -428
- package/llms-full.txt +290 -43
- package/package.json +8 -3
package/dist/index.js
CHANGED
|
@@ -295,7 +295,11 @@ function joinClientBaseUrl(baseUrl, relativeUrl) {
|
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
// src/browser/http.ts
|
|
298
|
-
import ky, {
|
|
298
|
+
import ky, {
|
|
299
|
+
isHTTPError,
|
|
300
|
+
isNetworkError,
|
|
301
|
+
isTimeoutError
|
|
302
|
+
} from "ky";
|
|
299
303
|
|
|
300
304
|
// src/observability/trace.ts
|
|
301
305
|
var TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})(.*)$/i;
|
|
@@ -371,6 +375,15 @@ class ApiError extends Error {
|
|
|
371
375
|
return error instanceof ApiError;
|
|
372
376
|
}
|
|
373
377
|
}
|
|
378
|
+
function shouldRetryBunNetworkError(error) {
|
|
379
|
+
if (ApiError.is(error) || isHTTPError(error) || isNetworkError(error) || isTimeoutError(error) || error instanceof RequestCancellationError || error instanceof DOMException && (error.name === "AbortError" || error.name === "TimeoutError")) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if (!(error instanceof Error))
|
|
383
|
+
return;
|
|
384
|
+
const code = Object.getOwnPropertyDescriptor(error, "code");
|
|
385
|
+
return code && "value" in code && code.value === "ConnectionRefused" ? true : undefined;
|
|
386
|
+
}
|
|
374
387
|
function parseApiErrorBody(body) {
|
|
375
388
|
if (!isRecord(body) || !isRecord(body.error))
|
|
376
389
|
return null;
|
|
@@ -384,6 +397,34 @@ function parseApiErrorBody(body) {
|
|
|
384
397
|
hint: typeof error.hint === "string" ? error.hint : undefined
|
|
385
398
|
};
|
|
386
399
|
}
|
|
400
|
+
function createRetryAwareFetch() {
|
|
401
|
+
const runtimeFetch = globalThis.fetch.bind(globalThis);
|
|
402
|
+
let attempt = 0;
|
|
403
|
+
return (input, init) => {
|
|
404
|
+
attempt += 1;
|
|
405
|
+
if (attempt === 1) {
|
|
406
|
+
return runtimeFetch(input, init);
|
|
407
|
+
}
|
|
408
|
+
if (!(input instanceof Request))
|
|
409
|
+
return runtimeFetch(input, init);
|
|
410
|
+
const streamedBody = input.body ? { body: input.body, duplex: "half" } : {};
|
|
411
|
+
return runtimeFetch(input.url, {
|
|
412
|
+
...init,
|
|
413
|
+
method: input.method,
|
|
414
|
+
headers: input.headers,
|
|
415
|
+
...streamedBody,
|
|
416
|
+
cache: input.cache,
|
|
417
|
+
credentials: input.credentials,
|
|
418
|
+
integrity: input.integrity,
|
|
419
|
+
keepalive: input.keepalive,
|
|
420
|
+
mode: input.mode,
|
|
421
|
+
redirect: input.redirect,
|
|
422
|
+
referrer: input.referrer,
|
|
423
|
+
referrerPolicy: input.referrerPolicy,
|
|
424
|
+
signal: input.signal
|
|
425
|
+
});
|
|
426
|
+
};
|
|
427
|
+
}
|
|
387
428
|
function createHttpClient(config) {
|
|
388
429
|
let ssrCookies = null;
|
|
389
430
|
let isLoggedOut = false;
|
|
@@ -404,7 +445,8 @@ function createHttpClient(config) {
|
|
|
404
445
|
retry: {
|
|
405
446
|
limit: config.retry?.limit ?? 2,
|
|
406
447
|
methods: config.retry?.methods ?? ["get"],
|
|
407
|
-
statusCodes: config.retry?.statusCodes ?? []
|
|
448
|
+
statusCodes: config.retry?.statusCodes ?? [],
|
|
449
|
+
shouldRetry: ({ error }) => shouldRetryBunNetworkError(error)
|
|
408
450
|
},
|
|
409
451
|
hooks: {
|
|
410
452
|
beforeRequest: [
|
|
@@ -448,6 +490,7 @@ function createHttpClient(config) {
|
|
|
448
490
|
async function request(method, url, data, options = {}) {
|
|
449
491
|
const cancellation = createRequestCancellation(options.signal, options.timeout ?? config.timeout ?? 30000);
|
|
450
492
|
const kyOptions = {
|
|
493
|
+
fetch: createRetryAwareFetch(),
|
|
451
494
|
timeout: false,
|
|
452
495
|
signal: cancellation.signal
|
|
453
496
|
};
|
|
@@ -657,6 +700,7 @@ function createHttpExecutor(endpoint, prefix, client, config) {
|
|
|
657
700
|
};
|
|
658
701
|
}
|
|
659
702
|
function createFetchExecutor(endpoint, prefix, config, contractConfig) {
|
|
703
|
+
const executeFetch = config.fetch ?? globalThis.fetch;
|
|
660
704
|
return async (requestArgs, options) => {
|
|
661
705
|
const plan = planClientRequest(endpoint, prefix, requestArgs, contractConfig);
|
|
662
706
|
const url = joinClientBaseUrl(config.baseUrl, plan.relativeUrl);
|
|
@@ -671,7 +715,7 @@ function createFetchExecutor(endpoint, prefix, config, contractConfig) {
|
|
|
671
715
|
try {
|
|
672
716
|
return await cancellation.run(async (signal) => {
|
|
673
717
|
const body = endpoint.multipart ? buildMultipartForm(endpoint.multipart, plan.remainingArgs) : hasBody ? JSON.stringify(plan.remainingArgs) : undefined;
|
|
674
|
-
const res = await
|
|
718
|
+
const res = await executeFetch(url, {
|
|
675
719
|
method: endpoint.method,
|
|
676
720
|
headers,
|
|
677
721
|
credentials: config.credentials,
|
package/dist/node.d.ts
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { AppError, appError, badRequest, conflict, forbidden, notFound, rateLimited, unauthorized, } from './contract';
|
|
8
8
|
export { createHandler } from './server/create';
|
|
9
|
-
export { createImplement, implement } from './server/implement';
|
|
9
|
+
export { createImplement, createImplementRegistry, type ExactRegistryHandlers, type ImplementationRegistry, implement, implementRegistry, type RegistryHandlers, } from './server/implement';
|
|
10
10
|
export type { LogFormat } from './server/logger';
|
|
11
|
-
export { type NodeServerConfig, type NodeServerHandle, serveNode } from './server/node';
|
|
11
|
+
export { type NodeRuntimeServer, type NodeServerConfig, type NodeServerHandle, type NodeSocketLifecycle, serveNode, } from './server/node';
|
|
12
12
|
export { bindRealtimeServer, type RealtimeServer, type RealtimeServerConnection, type RealtimeServerHandle, } from './server/realtime';
|
|
13
|
-
export {
|
|
13
|
+
export { type ManagedServerHandle, type ShutdownOptions, ShutdownOptionsSchema, type ShutdownResult, ShutdownResultSchema, type ShutdownState, ShutdownStateSchema, type ShutdownStatus, ShutdownStatusSchema, } from './server/shutdown';
|
|
14
|
+
export { createNodeSocketIOServer as createSocketIOServer, type NodeSocketIOServerHandle as SocketIOServerHandle, type SocketIORequestPolicy, type SocketIOServerConfig, } from './server/socket-io-node';
|
|
14
15
|
export type { FetchComposition, FetchHandler, HandlerConfig, LoggingConfig, LogOutcome, RawRoute, RawRouteContext, ServiceDef, } from './server/types';
|
|
15
16
|
//# sourceMappingURL=node.d.ts.map
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,WAAW,EACX,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,SAAS,EACT,iBAAiB,EACjB,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,qBAAqB,EACrB,KAAK,cAAc,EACnB,oBAAoB,EACpB,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,cAAc,EACnB,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,wBAAwB,IAAI,oBAAoB,EAChD,KAAK,wBAAwB,IAAI,oBAAoB,EACrD,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,UAAU,EACV,QAAQ,EACR,eAAe,EACf,UAAU,GACX,MAAM,gBAAgB,CAAC"}
|
package/dist/node.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ShutdownOptionsSchema,
|
|
3
|
+
ShutdownResultSchema,
|
|
4
|
+
ShutdownStateSchema,
|
|
5
|
+
ShutdownStatusSchema,
|
|
2
6
|
bindRealtimeServer,
|
|
3
7
|
createHandler,
|
|
4
8
|
createImplement,
|
|
9
|
+
createImplementRegistry,
|
|
10
|
+
createServerLifecycle,
|
|
5
11
|
createSocketIOServer,
|
|
6
|
-
implement
|
|
7
|
-
|
|
12
|
+
implement,
|
|
13
|
+
implementRegistry
|
|
14
|
+
} from "./index-fjfzsq6y.js";
|
|
8
15
|
import"./index-r1qp4rve.js";
|
|
9
16
|
import {
|
|
10
17
|
AppError,
|
|
@@ -15,29 +22,111 @@ import {
|
|
|
15
22
|
notFound,
|
|
16
23
|
rateLimited,
|
|
17
24
|
unauthorized
|
|
18
|
-
} from "./index-
|
|
25
|
+
} from "./index-jewp9r0a.js";
|
|
26
|
+
import"./index-h05ygjqx.js";
|
|
19
27
|
// src/server/node.ts
|
|
20
|
-
import { serve } from "srvx";
|
|
28
|
+
import { serve } from "srvx/node";
|
|
21
29
|
async function serveNode(config) {
|
|
22
30
|
const { port = 3000, hostname, socket, wrapFetch, ...handlerConfig } = config;
|
|
23
31
|
const handler = createHandler(handlerConfig);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
let runtime;
|
|
33
|
+
let nodeServer;
|
|
34
|
+
const sockets = new Set;
|
|
35
|
+
const upgradedSockets = new Set;
|
|
36
|
+
const responses = new Set;
|
|
37
|
+
const socketDrainWaiters = new Set;
|
|
38
|
+
const resolveSocketDrain = () => {
|
|
39
|
+
if (sockets.size !== 0)
|
|
40
|
+
return;
|
|
41
|
+
for (const resolve of socketDrainWaiters)
|
|
42
|
+
resolve();
|
|
43
|
+
socketDrainWaiters.clear();
|
|
44
|
+
};
|
|
45
|
+
const waitForSocketDrain = () => {
|
|
46
|
+
if (sockets.size === 0)
|
|
47
|
+
return Promise.resolve();
|
|
48
|
+
return new Promise((resolve) => socketDrainWaiters.add(resolve));
|
|
49
|
+
};
|
|
50
|
+
const requireRuntime = () => {
|
|
51
|
+
if (!runtime)
|
|
52
|
+
throw new Error("[stitchkit] Node server lifecycle started before srvx");
|
|
53
|
+
return runtime;
|
|
54
|
+
};
|
|
55
|
+
const requireNodeServer = () => {
|
|
56
|
+
if (!nodeServer)
|
|
57
|
+
throw new Error("[stitchkit] Node HTTP server is unavailable");
|
|
58
|
+
return nodeServer;
|
|
59
|
+
};
|
|
60
|
+
const adapter = {
|
|
61
|
+
beginShutdown: () => socket?.beginShutdown(),
|
|
62
|
+
pendingRequests: () => responses.size,
|
|
63
|
+
pendingWebSockets: () => upgradedSockets.size,
|
|
64
|
+
closeRealtime: () => socket?.close() ?? Promise.resolve(),
|
|
65
|
+
async stopGracefully() {
|
|
66
|
+
const runtimeClose = socket ? Promise.resolve() : requireRuntime().close(false);
|
|
67
|
+
requireNodeServer().closeIdleConnections?.();
|
|
68
|
+
await runtimeClose;
|
|
69
|
+
await waitForSocketDrain();
|
|
70
|
+
},
|
|
71
|
+
async forceStop() {
|
|
72
|
+
const activeServer = requireNodeServer();
|
|
73
|
+
const logicalClose = socket?.close();
|
|
74
|
+
const physicalClosures = [...sockets].map((activeSocket) => new Promise((resolve) => {
|
|
75
|
+
if (activeSocket.closed)
|
|
76
|
+
resolve();
|
|
77
|
+
else
|
|
78
|
+
activeSocket.once("close", () => resolve());
|
|
79
|
+
}));
|
|
80
|
+
activeServer.closeAllConnections?.();
|
|
81
|
+
for (const activeSocket of sockets)
|
|
82
|
+
activeSocket.destroy();
|
|
83
|
+
if (logicalClose)
|
|
84
|
+
await logicalClose;
|
|
85
|
+
else
|
|
86
|
+
await requireRuntime().close(true);
|
|
87
|
+
await Promise.all(physicalClosures);
|
|
88
|
+
responses.clear();
|
|
31
89
|
}
|
|
32
|
-
|
|
90
|
+
};
|
|
91
|
+
const lifecycle = createServerLifecycle(() => adapter);
|
|
92
|
+
const consumerFetch = wrapFetch ? wrapFetch(handler) : handler;
|
|
93
|
+
const fetch = lifecycle.wrapFetch(consumerFetch);
|
|
94
|
+
runtime = serve({ port, hostname, fetch, gracefulShutdown: false });
|
|
95
|
+
await runtime.ready();
|
|
96
|
+
const candidate = runtime.node?.server;
|
|
97
|
+
if (!candidate || !("maxRequestsPerSocket" in candidate)) {
|
|
98
|
+
await runtime.close(true);
|
|
99
|
+
throw new Error("[stitchkit] serveNode: expected a node:http.Server for the managed lifecycle.");
|
|
33
100
|
}
|
|
34
|
-
|
|
101
|
+
nodeServer = candidate;
|
|
102
|
+
nodeServer.on("connection", (activeSocket) => {
|
|
103
|
+
sockets.add(activeSocket);
|
|
104
|
+
activeSocket.once("close", () => {
|
|
105
|
+
sockets.delete(activeSocket);
|
|
106
|
+
upgradedSockets.delete(activeSocket);
|
|
107
|
+
resolveSocketDrain();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
nodeServer.on("upgrade", (request) => upgradedSockets.add(request.socket));
|
|
111
|
+
nodeServer.prependListener("request", (_request, response) => {
|
|
112
|
+
responses.add(response);
|
|
113
|
+
const complete = () => responses.delete(response);
|
|
114
|
+
response.once("finish", complete);
|
|
115
|
+
response.once("close", complete);
|
|
116
|
+
});
|
|
117
|
+
socket?.attach(nodeServer);
|
|
118
|
+
const listenUrl = runtime.url ?? `http://${hostname ?? "localhost"}:${port}`;
|
|
35
119
|
const resolvedPort = Number(new URL(listenUrl).port) || port;
|
|
36
120
|
const resolvedHost = hostname ?? "localhost";
|
|
121
|
+
const server = runtime;
|
|
37
122
|
return {
|
|
38
123
|
url: `http://${resolvedHost}:${resolvedPort}`,
|
|
39
124
|
port: resolvedPort,
|
|
40
|
-
|
|
125
|
+
runtime: server,
|
|
126
|
+
get status() {
|
|
127
|
+
return lifecycle.status;
|
|
128
|
+
},
|
|
129
|
+
shutdown: lifecycle.shutdown
|
|
41
130
|
};
|
|
42
131
|
}
|
|
43
132
|
// src/server/socket-io-node.ts
|
|
@@ -49,14 +138,20 @@ export {
|
|
|
49
138
|
serveNode,
|
|
50
139
|
rateLimited,
|
|
51
140
|
notFound,
|
|
141
|
+
implementRegistry,
|
|
52
142
|
implement,
|
|
53
143
|
forbidden,
|
|
54
144
|
createNodeSocketIOServer as createSocketIOServer,
|
|
145
|
+
createImplementRegistry,
|
|
55
146
|
createImplement,
|
|
56
147
|
createHandler,
|
|
57
148
|
conflict,
|
|
58
149
|
bindRealtimeServer,
|
|
59
150
|
badRequest,
|
|
60
151
|
appError,
|
|
152
|
+
ShutdownStatusSchema,
|
|
153
|
+
ShutdownStateSchema,
|
|
154
|
+
ShutdownResultSchema,
|
|
155
|
+
ShutdownOptionsSchema,
|
|
61
156
|
AppError
|
|
62
157
|
};
|
|
@@ -2,6 +2,7 @@ import type { ToolCallHooks } from '../tools/execute';
|
|
|
2
2
|
import { type RequestContext } from './context';
|
|
3
3
|
import type { RequestEvent } from './event';
|
|
4
4
|
import { type SanitizeOptions } from './sanitize';
|
|
5
|
+
import { type ObservabilityDrainReport, type ObservabilityStatus } from './status';
|
|
5
6
|
/** One isolated RequestEvent sink and its sanitisation policy. */
|
|
6
7
|
export interface RequestEventSinkConfig {
|
|
7
8
|
/**
|
|
@@ -56,8 +57,10 @@ export interface Observability {
|
|
|
56
57
|
toolCall: ToolCallHooks;
|
|
57
58
|
/** Wait for events admitted before this call. */
|
|
58
59
|
flush(): Promise<void>;
|
|
60
|
+
/** Read an immutable snapshot of each enabled sink and their aggregate. */
|
|
61
|
+
getStatus(): ObservabilityStatus;
|
|
59
62
|
/** Stop admission and drain every previously accepted event. Idempotent. */
|
|
60
|
-
close(): Promise<
|
|
63
|
+
close(): Promise<ObservabilityDrainReport>;
|
|
61
64
|
}
|
|
62
65
|
export declare function createObservability(config: ObservabilityConfig): Observability;
|
|
63
66
|
//# sourceMappingURL=audit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/observability/audit.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAe,KAAK,eAAe,EAAmB,MAAM,YAAY,CAAC;AAChF,OAAO,EAEL,KAAK,wBAAwB,EAI7B,KAAK,mBAAmB,EAEzB,MAAM,UAAU,CAAC;AAGlB,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,KAAK,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,iFAAiF;IACjF,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;IAC1C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,8DAA8D;IAC9D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD;AAED,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA2B,SAAQ,sBAAsB;IACxE,2DAA2D;IAC3D,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAED,gEAAgE;AAChE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,cAAc,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5B;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACnD;AAED,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,QAAQ,EAAE,aAAa,CAAC;IACxB,iDAAiD;IACjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,2EAA2E;IAC3E,SAAS,IAAI,mBAAmB,CAAC;IACjC,4EAA4E;IAC5E,KAAK,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAAC;CAC5C;AAkOD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAyJ9E"}
|
|
@@ -10,5 +10,6 @@ export { createObservability, type HttpRequestCompletion, type HttpRequestObserv
|
|
|
10
10
|
export { getRequestContext, getTraceId, getUserId, type RequestContext, runWithRequestContext, setRequestDimensions, setRequestEndpoint, setRequestError, setRequestUser, type WrapRequestContextOptions, wrapInRequestContext, } from './context';
|
|
11
11
|
export type { RequestEvent } from './event';
|
|
12
12
|
export { type JsonValue, measureSize, redact, type SanitizeOptions, type SizeMeasure, sanitizePayload, truncatePreview, } from './sanitize';
|
|
13
|
+
export { type ObservabilityDrainReport, ObservabilityDrainReportSchema, type ObservabilitySinkStatus, ObservabilitySinkStatusSchema, type ObservabilityStatus, ObservabilityStatusSchema, } from './status';
|
|
13
14
|
export { childSpan, createTraceContext, formatTraceparent, parseTraceparent, resolvePropagationContext, resolveTraceContext, type TraceContext, } from './trace';
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,SAAS,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,KAAK,cAAc,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,KAAK,yBAAyB,EAC9B,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,KAAK,SAAS,EACd,WAAW,EACX,MAAM,EACN,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/observability/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,mBAAmB,EACnB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,SAAS,GACf,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,KAAK,cAAc,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,KAAK,yBAAyB,EAC9B,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EACL,KAAK,SAAS,EACd,WAAW,EACX,MAAM,EACN,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,wBAAwB,EAC7B,8BAA8B,EAC9B,KAAK,uBAAuB,EAC5B,6BAA6B,EAC7B,KAAK,mBAAmB,EACxB,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,SAAS,CAAC"}
|
|
@@ -3,26 +3,85 @@ import {
|
|
|
3
3
|
redact,
|
|
4
4
|
sanitizePayload,
|
|
5
5
|
truncatePreview
|
|
6
|
-
} from "../index-
|
|
6
|
+
} from "../index-v58mwa19.js";
|
|
7
7
|
import {
|
|
8
|
-
childSpan,
|
|
9
|
-
createTraceContext,
|
|
10
|
-
formatTraceparent,
|
|
11
8
|
getRequestContext,
|
|
12
9
|
getTraceId,
|
|
13
10
|
getUserId,
|
|
14
|
-
isRecord,
|
|
15
|
-
parseTraceparent,
|
|
16
11
|
recordedErrorMessage,
|
|
17
|
-
resolvePropagationContext,
|
|
18
|
-
resolveTraceContext,
|
|
19
12
|
runWithRequestContext,
|
|
20
13
|
setRequestDimensions,
|
|
21
14
|
setRequestEndpoint,
|
|
22
15
|
setRequestError,
|
|
23
16
|
setRequestUser,
|
|
24
17
|
wrapInRequestContext
|
|
25
|
-
} from "../index-
|
|
18
|
+
} from "../index-jewp9r0a.js";
|
|
19
|
+
import {
|
|
20
|
+
childSpan,
|
|
21
|
+
createTraceContext,
|
|
22
|
+
formatTraceparent,
|
|
23
|
+
isRecord,
|
|
24
|
+
parseTraceparent,
|
|
25
|
+
resolvePropagationContext,
|
|
26
|
+
resolveTraceContext
|
|
27
|
+
} from "../index-h05ygjqx.js";
|
|
28
|
+
|
|
29
|
+
// src/observability/status.ts
|
|
30
|
+
import { z } from "zod";
|
|
31
|
+
var NonNegativeIntegerSchema = z.number().int().nonnegative();
|
|
32
|
+
var ObservabilitySinkStatusSchema = z.object({
|
|
33
|
+
capacity: NonNegativeIntegerSchema,
|
|
34
|
+
received: NonNegativeIntegerSchema,
|
|
35
|
+
accepted: NonNegativeIntegerSchema,
|
|
36
|
+
filtered: NonNegativeIntegerSchema,
|
|
37
|
+
completed: NonNegativeIntegerSchema,
|
|
38
|
+
dropped: NonNegativeIntegerSchema,
|
|
39
|
+
failed: NonNegativeIntegerSchema,
|
|
40
|
+
preparationFailed: NonNegativeIntegerSchema,
|
|
41
|
+
preparing: NonNegativeIntegerSchema,
|
|
42
|
+
pending: NonNegativeIntegerSchema,
|
|
43
|
+
closed: z.boolean()
|
|
44
|
+
}).readonly();
|
|
45
|
+
var ObservabilityStatusObjectSchema = z.object({
|
|
46
|
+
request: ObservabilitySinkStatusSchema.optional(),
|
|
47
|
+
tools: ObservabilitySinkStatusSchema.optional(),
|
|
48
|
+
total: ObservabilitySinkStatusSchema
|
|
49
|
+
});
|
|
50
|
+
var ObservabilityStatusSchema = ObservabilityStatusObjectSchema.readonly();
|
|
51
|
+
var ObservabilityDrainReportSchema = ObservabilityStatusObjectSchema.extend({
|
|
52
|
+
durationMs: z.number().nonnegative()
|
|
53
|
+
}).readonly();
|
|
54
|
+
var SUMMED_STATUS_KEYS = [
|
|
55
|
+
"capacity",
|
|
56
|
+
"received",
|
|
57
|
+
"accepted",
|
|
58
|
+
"filtered",
|
|
59
|
+
"completed",
|
|
60
|
+
"dropped",
|
|
61
|
+
"failed",
|
|
62
|
+
"preparationFailed",
|
|
63
|
+
"preparing",
|
|
64
|
+
"pending"
|
|
65
|
+
];
|
|
66
|
+
function aggregateObservabilityStatus(surfaces, closed) {
|
|
67
|
+
const totals = {
|
|
68
|
+
capacity: 0,
|
|
69
|
+
received: 0,
|
|
70
|
+
accepted: 0,
|
|
71
|
+
filtered: 0,
|
|
72
|
+
completed: 0,
|
|
73
|
+
dropped: 0,
|
|
74
|
+
failed: 0,
|
|
75
|
+
preparationFailed: 0,
|
|
76
|
+
preparing: 0,
|
|
77
|
+
pending: 0
|
|
78
|
+
};
|
|
79
|
+
for (const surface of surfaces) {
|
|
80
|
+
for (const key of SUMMED_STATUS_KEYS)
|
|
81
|
+
totals[key] += surface[key];
|
|
82
|
+
}
|
|
83
|
+
return ObservabilitySinkStatusSchema.parse({ ...totals, closed });
|
|
84
|
+
}
|
|
26
85
|
|
|
27
86
|
// src/observability/audit.ts
|
|
28
87
|
function toolErrorMessage(result) {
|
|
@@ -76,6 +135,13 @@ function createSinkManager(config) {
|
|
|
76
135
|
}
|
|
77
136
|
let sequence = 0;
|
|
78
137
|
let closed = false;
|
|
138
|
+
let received = 0;
|
|
139
|
+
let accepted = 0;
|
|
140
|
+
let filtered = 0;
|
|
141
|
+
let completed = 0;
|
|
142
|
+
let dropped = 0;
|
|
143
|
+
let failed = 0;
|
|
144
|
+
let preparationFailed = 0;
|
|
79
145
|
let closePromise;
|
|
80
146
|
const preparing = new Map;
|
|
81
147
|
const writes = new Map;
|
|
@@ -87,17 +153,27 @@ function createSinkManager(config) {
|
|
|
87
153
|
};
|
|
88
154
|
const admit = (id, event) => {
|
|
89
155
|
try {
|
|
90
|
-
if (config.filter && !config.filter(event))
|
|
156
|
+
if (config.filter && !config.filter(event)) {
|
|
157
|
+
filtered += 1;
|
|
91
158
|
return;
|
|
159
|
+
}
|
|
92
160
|
} catch (error) {
|
|
161
|
+
preparationFailed += 1;
|
|
93
162
|
reportError(error, event);
|
|
94
163
|
return;
|
|
95
164
|
}
|
|
96
165
|
if (writes.size >= maxPending) {
|
|
166
|
+
dropped += 1;
|
|
97
167
|
reportDrop("capacity", event);
|
|
98
168
|
return;
|
|
99
169
|
}
|
|
100
|
-
|
|
170
|
+
accepted += 1;
|
|
171
|
+
const write = Promise.resolve().then(() => config.write(event)).then(() => {
|
|
172
|
+
completed += 1;
|
|
173
|
+
}).catch((error) => {
|
|
174
|
+
failed += 1;
|
|
175
|
+
reportError(error, event);
|
|
176
|
+
}).finally(() => writes.delete(id));
|
|
101
177
|
writes.set(id, write);
|
|
102
178
|
};
|
|
103
179
|
const awaitGeneration = async (boundary) => {
|
|
@@ -107,22 +183,59 @@ function createSinkManager(config) {
|
|
|
107
183
|
};
|
|
108
184
|
return {
|
|
109
185
|
submit(produce) {
|
|
186
|
+
received += 1;
|
|
110
187
|
const id = ++sequence;
|
|
111
188
|
if (closed) {
|
|
112
|
-
Promise.resolve().then(produce).then((event) =>
|
|
189
|
+
Promise.resolve().then(produce).then((event) => {
|
|
190
|
+
dropped += 1;
|
|
191
|
+
reportDrop("closed", event);
|
|
192
|
+
}).catch((error) => {
|
|
193
|
+
preparationFailed += 1;
|
|
194
|
+
reportError(error);
|
|
195
|
+
});
|
|
113
196
|
return;
|
|
114
197
|
}
|
|
115
|
-
const preparation = Promise.resolve().then(produce).then((event) => admit(id, event)).catch((error) =>
|
|
198
|
+
const preparation = Promise.resolve().then(produce).then((event) => admit(id, event)).catch((error) => {
|
|
199
|
+
preparationFailed += 1;
|
|
200
|
+
reportError(error);
|
|
201
|
+
}).finally(() => preparing.delete(id));
|
|
116
202
|
preparing.set(id, preparation);
|
|
117
203
|
},
|
|
118
204
|
flush() {
|
|
119
205
|
return awaitGeneration(sequence);
|
|
120
206
|
},
|
|
207
|
+
getStatus() {
|
|
208
|
+
return ObservabilitySinkStatusSchema.parse({
|
|
209
|
+
capacity: maxPending,
|
|
210
|
+
received,
|
|
211
|
+
accepted,
|
|
212
|
+
filtered,
|
|
213
|
+
completed,
|
|
214
|
+
dropped,
|
|
215
|
+
failed,
|
|
216
|
+
preparationFailed,
|
|
217
|
+
preparing: preparing.size,
|
|
218
|
+
pending: writes.size,
|
|
219
|
+
closed
|
|
220
|
+
});
|
|
221
|
+
},
|
|
121
222
|
close() {
|
|
122
223
|
if (closePromise)
|
|
123
224
|
return closePromise;
|
|
124
225
|
closed = true;
|
|
125
|
-
closePromise = awaitGeneration(sequence)
|
|
226
|
+
closePromise = awaitGeneration(sequence).then(() => ObservabilitySinkStatusSchema.parse({
|
|
227
|
+
capacity: maxPending,
|
|
228
|
+
received,
|
|
229
|
+
accepted,
|
|
230
|
+
filtered,
|
|
231
|
+
completed,
|
|
232
|
+
dropped,
|
|
233
|
+
failed,
|
|
234
|
+
preparationFailed,
|
|
235
|
+
preparing: preparing.size,
|
|
236
|
+
pending: writes.size,
|
|
237
|
+
closed
|
|
238
|
+
}));
|
|
126
239
|
return closePromise;
|
|
127
240
|
}
|
|
128
241
|
};
|
|
@@ -130,6 +243,7 @@ function createSinkManager(config) {
|
|
|
130
243
|
function createObservability(config) {
|
|
131
244
|
const requestManager = config.request ? createSinkManager(config.request) : undefined;
|
|
132
245
|
const toolManager = config.tools ? createSinkManager(config.tools) : undefined;
|
|
246
|
+
let closed = false;
|
|
133
247
|
let closePromise;
|
|
134
248
|
const request = config.request ? {
|
|
135
249
|
includePayload: config.request.includePayload ?? false,
|
|
@@ -228,16 +342,33 @@ function createObservability(config) {
|
|
|
228
342
|
} catch {}
|
|
229
343
|
}
|
|
230
344
|
} : undefined;
|
|
345
|
+
const getStatus = () => {
|
|
346
|
+
const requestStatus = requestManager?.getStatus();
|
|
347
|
+
const toolsStatus = toolManager?.getStatus();
|
|
348
|
+
const surfaces = [requestStatus, toolsStatus].filter((status) => status !== undefined);
|
|
349
|
+
return ObservabilityStatusSchema.parse({
|
|
350
|
+
...requestStatus && { request: requestStatus },
|
|
351
|
+
...toolsStatus && { tools: toolsStatus },
|
|
352
|
+
total: aggregateObservabilityStatus(surfaces, closed)
|
|
353
|
+
});
|
|
354
|
+
};
|
|
231
355
|
return {
|
|
232
356
|
...request && { request },
|
|
233
357
|
toolCall: toolCall ?? {},
|
|
234
358
|
async flush() {
|
|
235
359
|
await Promise.all([requestManager?.flush(), toolManager?.flush()]);
|
|
236
360
|
},
|
|
361
|
+
getStatus,
|
|
237
362
|
close() {
|
|
238
363
|
if (!closePromise) {
|
|
364
|
+
closed = true;
|
|
365
|
+
const startedAt = performance.now();
|
|
239
366
|
closePromise = Promise.all([requestManager?.close(), toolManager?.close()]).then(() => {
|
|
240
|
-
|
|
367
|
+
const status = getStatus();
|
|
368
|
+
return ObservabilityDrainReportSchema.parse({
|
|
369
|
+
...status,
|
|
370
|
+
durationMs: performance.now() - startedAt
|
|
371
|
+
});
|
|
241
372
|
});
|
|
242
373
|
}
|
|
243
374
|
return closePromise;
|
|
@@ -264,5 +395,8 @@ export {
|
|
|
264
395
|
formatTraceparent,
|
|
265
396
|
createTraceContext,
|
|
266
397
|
createObservability,
|
|
267
|
-
childSpan
|
|
398
|
+
childSpan,
|
|
399
|
+
ObservabilityStatusSchema,
|
|
400
|
+
ObservabilitySinkStatusSchema,
|
|
401
|
+
ObservabilityDrainReportSchema
|
|
268
402
|
};
|