@toolgrain/mcp 0.2.0 → 0.3.0-alpha.1
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/CHANGELOG.md +21 -0
- package/README.md +12 -5
- package/dist/abort.d.ts.map +1 -0
- package/dist/abort.js.map +1 -0
- package/dist/auth/authorization.js +1 -1
- package/dist/auth/authorization.js.map +1 -1
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +14 -2
- package/dist/connection.js.map +1 -1
- package/dist/dispatcher.d.ts +4 -2
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js.map +1 -1
- package/dist/execute-request.d.ts.map +1 -1
- package/dist/execute-request.js +9 -1
- package/dist/execute-request.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy/dispatcher.d.ts.map +1 -1
- package/dist/legacy/dispatcher.js +1 -1
- package/dist/legacy/dispatcher.js.map +1 -1
- package/dist/legacy/messages.d.ts +12 -4
- package/dist/legacy/messages.d.ts.map +1 -1
- package/dist/legacy/messages.js +2 -2
- package/dist/legacy/messages.js.map +1 -1
- package/dist/modern/dispatcher.d.ts.map +1 -1
- package/dist/modern/dispatcher.js +1 -1
- package/dist/modern/dispatcher.js.map +1 -1
- package/dist/modern/metadata.d.ts.map +1 -1
- package/dist/modern/metadata.js +1 -2
- package/dist/modern/metadata.js.map +1 -1
- package/dist/pending-requests.d.ts +2 -1
- package/dist/pending-requests.d.ts.map +1 -1
- package/dist/pending-requests.js +17 -0
- package/dist/pending-requests.js.map +1 -1
- package/dist/server.d.ts +8 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +49 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/context.d.ts +11 -1
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +2 -1
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/progress.d.ts +19 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +96 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/transport.d.ts +4 -4
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js.map +1 -1
- package/package.json +3 -3
- package/src/auth/authorization.ts +1 -1
- package/src/connection.ts +22 -2
- package/src/dispatcher.ts +4 -1
- package/src/execute-request.ts +16 -1
- package/src/index.ts +1 -0
- package/src/legacy/dispatcher.ts +1 -0
- package/src/legacy/messages.ts +2 -2
- package/src/modern/dispatcher.ts +1 -0
- package/src/modern/metadata.ts +1 -2
- package/src/pending-requests.ts +17 -1
- package/src/server.ts +76 -10
- package/src/tools/context.ts +12 -0
- package/src/tools/progress.ts +119 -0
- package/src/transport.ts +7 -4
- package/dist/auth/abort.d.ts.map +0 -1
- package/dist/auth/abort.js.map +0 -1
- /package/dist/{auth/abort.d.ts → abort.d.ts} +0 -0
- /package/dist/{auth/abort.js → abort.js} +0 -0
- /package/src/{auth/abort.ts → abort.ts} +0 -0
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/context.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { AuthIdentity } from "../auth/types.js";
|
|
|
4
4
|
import type { RegisteredContextProvider } from "../context/definition.js";
|
|
5
5
|
import { type ContextRegistry } from "../context/registry.js";
|
|
6
6
|
import type { DeepReadonly } from "./json-value.js";
|
|
7
|
+
import type { ToolProgress } from "./progress.js";
|
|
7
8
|
/** What the client reported about itself; unverified, so not a basis for security decisions. */
|
|
8
9
|
export interface ToolClient {
|
|
9
10
|
/** Copied, deeply frozen implementation details supplied by the client, when available. */
|
|
@@ -28,6 +29,15 @@ export interface ToolContext {
|
|
|
28
29
|
readonly signal: AbortSignal;
|
|
29
30
|
/** Frozen request metadata; contains no verified authorization identity. */
|
|
30
31
|
readonly request: ToolRequest;
|
|
32
|
+
/**
|
|
33
|
+
* Report request-scoped progress; safe to pass to helpers without binding.
|
|
34
|
+
* Await delivery/backpressure; updates are spaced at least 100 ms per invocation.
|
|
35
|
+
* Resolves without sending when no progress token or delivery channel exists,
|
|
36
|
+
* or after cancellation/completion. Active updates
|
|
37
|
+
* require finite values and strictly increasing progress; invalid updates reject.
|
|
38
|
+
* Delivery failure cancels the request and reaches transport diagnostics.
|
|
39
|
+
*/
|
|
40
|
+
readonly reportProgress: (update: ToolProgress) => Promise<void>;
|
|
31
41
|
}
|
|
32
42
|
/** Optional metadata, cancellation, and provider bindings for a direct-call context. */
|
|
33
43
|
export interface ToolContextOptions {
|
|
@@ -48,7 +58,7 @@ export interface ToolContextOptions {
|
|
|
48
58
|
*/
|
|
49
59
|
export declare function toolContext(options?: ToolContextOptions): ToolContext;
|
|
50
60
|
/** Each request gets its own deeply frozen copies, so handlers cannot affect one another. */
|
|
51
|
-
export declare function createToolContext(signal: AbortSignal, { client, ...request }: ToolRequest, auth?: AuthIdentity, providers?: ContextRegistry): ToolContext;
|
|
61
|
+
export declare function createToolContext(signal: AbortSignal, { client, ...request }: ToolRequest, auth?: AuthIdentity, providers?: ContextRegistry, reportProgress?: ToolContext["reportProgress"]): ToolContext;
|
|
52
62
|
/** Omit absent fields so the client matches its optional-property types. */
|
|
53
63
|
export declare function toolClient(info: ToolClient["info"], capabilities: ToolClient["capabilities"]): ToolClient;
|
|
54
64
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EAEnB,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,kBAAkB,IAAI,wBAAwB,EAC9C,cAAc,IAAI,oBAAoB,EACvC,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EAEnB,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,kBAAkB,IAAI,wBAAwB,EAC9C,cAAc,IAAI,oBAAoB,EACvC,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,gGAAgG;AAChG,MAAM,WAAW,UAAU;IACzB,2FAA2F;IAC3F,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,cAAc,GAAG,oBAAoB,CAAC,CAAC;IACpE,sFAAsF;IACtF,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAClC,kBAAkB,GAAG,wBAAwB,CAC9C,CAAC;CACH;AAED,+FAA+F;AAC/F,MAAM,WAAW,WAAW;IAC1B,oFAAoF;IACpF,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAC;IACvB,gEAAgE;IAChE,QAAQ,CAAC,eAAe,EAAE,wBAAwB,CAAC;IACnD,0FAA0F;IAC1F,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAED,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IAC1B,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED,wFAAwF;AACxF,MAAM,WAAW,kBAAkB;IACjC,iFAAiF;IACjF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gGAAgG;IAChG,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,8FAA8F;IAC9F,OAAO,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;CAChD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAmBzE;AAED,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,WAAW,EACnC,IAAI,CAAC,EAAE,YAAY,EACnB,SAAS,GAAE,eAAyC,EACpD,cAAc,GAAE,WAAW,CAAC,gBAAgB,CAA2B,GACtE,WAAW,CAkBb;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,EACxB,YAAY,EAAE,UAAU,CAAC,cAAc,CAAC,GACvC,UAAU,CAKZ"}
|
package/dist/tools/context.js
CHANGED
|
@@ -21,9 +21,10 @@ export function toolContext(options = {}) {
|
|
|
21
21
|
}, undefined, createContextRegistry(options.context));
|
|
22
22
|
}
|
|
23
23
|
/** Each request gets its own deeply frozen copies, so handlers cannot affect one another. */
|
|
24
|
-
export function createToolContext(signal, { client, ...request }, auth, providers = createContextRegistry()) {
|
|
24
|
+
export function createToolContext(signal, { client, ...request }, auth, providers = createContextRegistry(), reportProgress = () => Promise.resolve()) {
|
|
25
25
|
const ctx = attachAuth({
|
|
26
26
|
signal,
|
|
27
|
+
reportProgress,
|
|
27
28
|
request: Object.freeze({
|
|
28
29
|
...request,
|
|
29
30
|
...(client === undefined
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,gBAAgB,GAGjB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAEL,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,gBAAgB,GAGjB,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAEL,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAqDzD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,OAAO,GAAuB,EAAE;IAC1D,mFAAmF;IACnF,MAAM,EACJ,EAAE,GAAG,CAAC,EACN,eAAe,GAAG,gBAAgB,EAClC,MAAM,EACN,IAAI,GAAG,EAAE,GACV,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IAC1B,OAAO,iBAAiB,CACtB,OAAO,CAAC,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC,MAAM,EAC9C;QACE,EAAE;QACF,eAAe;QACf,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3C,IAAI;KACL,EACD,SAAS,EACT,qBAAqB,CAAC,OAAO,CAAC,OAAO,CAAC,CACvC,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,iBAAiB,CAC/B,MAAmB,EACnB,EAAE,MAAM,EAAE,GAAG,OAAO,EAAe,EACnC,IAAmB,EACnB,SAAS,GAAoB,qBAAqB,EAAE,EACpD,cAAc,GAAkC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;IAEvE,MAAM,GAAG,GAAG,UAAU,CACpB;QACE,MAAM;QACN,cAAc;QACd,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC;YACrB,GAAG,OAAO;YACV,GAAG,CAAC,MAAM,KAAK,SAAS;gBACtB,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC;oBACE,MAAM,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;iBACjE,CAAC;YACN,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC;SAC/B,CAAC;KACH,EACD,IAAI,CACL,CAAC;IACF,OAAO,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CACxB,IAAwB,EACxB,YAAwC;IAExC,OAAO;QACL,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,GAAG,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAI,KAAQ;IAC7B,OAAO,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,UAAU,CAAI,KAAQ;IAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,UAAU,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ProgressNotification, ProgressToken } from "@toolgrain/protocol";
|
|
2
|
+
/** One progress update; values are finite numbers and progress must strictly increase. */
|
|
3
|
+
export interface ToolProgress {
|
|
4
|
+
/** Work completed so far, in application-defined units; the first value may be zero. */
|
|
5
|
+
readonly progress: number;
|
|
6
|
+
/** Optional total work, in the same units; omit when unknown. */
|
|
7
|
+
readonly total?: number;
|
|
8
|
+
/** Optional public status message sent to the client. */
|
|
9
|
+
readonly message?: string;
|
|
10
|
+
}
|
|
11
|
+
/** Tokens share the request-ID wire format, but have a separate lifetime. */
|
|
12
|
+
export declare function isProgressToken(token: unknown): token is ProgressToken;
|
|
13
|
+
/** One invocation owns its reporter, ordering, and completion boundary. */
|
|
14
|
+
export declare function createProgressReporter(requestSignal: AbortSignal, token: unknown, send?: (message: ProgressNotification) => void | Promise<void>): {
|
|
15
|
+
report: (value: ToolProgress) => Promise<void>;
|
|
16
|
+
finish(): Promise<void>;
|
|
17
|
+
close(): void;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/tools/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAI/E,0FAA0F;AAC1F,MAAM,WAAW,YAAY;IAC3B,wFAAwF;IACxF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAQD,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAOtE;AAkBD,2EAA2E;AAC3E,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,WAAW,EAC1B,KAAK,EAAE,OAAO,EACd,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;oBASvC,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC;;;EA2DpD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { abortable } from "../abort.js";
|
|
3
|
+
const update = z.object({
|
|
4
|
+
progress: z.number().finite(),
|
|
5
|
+
total: z.number().finite().optional(),
|
|
6
|
+
message: z.string().optional(),
|
|
7
|
+
});
|
|
8
|
+
/** Tokens share the request-ID wire format, but have a separate lifetime. */
|
|
9
|
+
export function isProgressToken(token) {
|
|
10
|
+
return (typeof token === "string" ||
|
|
11
|
+
(typeof token === "number" &&
|
|
12
|
+
Number.isFinite(token) &&
|
|
13
|
+
Number.isInteger(token)));
|
|
14
|
+
}
|
|
15
|
+
/** Cancellation must release the timer as well as the awaiting handler. */
|
|
16
|
+
function waitForProgress(milliseconds, signal) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const abort = () => {
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
reject(signal.reason);
|
|
21
|
+
};
|
|
22
|
+
const timer = setTimeout(() => {
|
|
23
|
+
signal.removeEventListener("abort", abort);
|
|
24
|
+
resolve();
|
|
25
|
+
}, milliseconds);
|
|
26
|
+
if (signal.aborted)
|
|
27
|
+
abort();
|
|
28
|
+
else
|
|
29
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** One invocation owns its reporter, ordering, and completion boundary. */
|
|
33
|
+
export function createProgressReporter(requestSignal, token, send) {
|
|
34
|
+
const lifetime = new AbortController();
|
|
35
|
+
const signal = AbortSignal.any([requestSignal, lifetime.signal]);
|
|
36
|
+
const validToken = isProgressToken(token);
|
|
37
|
+
let open = true;
|
|
38
|
+
let previous = Number.NEGATIVE_INFINITY;
|
|
39
|
+
let writes = Promise.resolve();
|
|
40
|
+
let lastSent = Number.NEGATIVE_INFINITY;
|
|
41
|
+
const report = (value) => {
|
|
42
|
+
if (!open || signal.aborted || !validToken || !send)
|
|
43
|
+
return Promise.resolve();
|
|
44
|
+
const parsed = update.safeParse(value);
|
|
45
|
+
if (!parsed.success)
|
|
46
|
+
return Promise.reject(new TypeError("Invalid progress update"));
|
|
47
|
+
if (parsed.data.progress <= previous)
|
|
48
|
+
return Promise.reject(new TypeError("Progress must strictly increase"));
|
|
49
|
+
previous = parsed.data.progress;
|
|
50
|
+
const message = {
|
|
51
|
+
jsonrpc: "2.0",
|
|
52
|
+
method: "notifications/progress",
|
|
53
|
+
params: {
|
|
54
|
+
progress: parsed.data.progress,
|
|
55
|
+
...(parsed.data.total === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: { total: parsed.data.total }),
|
|
58
|
+
...(parsed.data.message === undefined
|
|
59
|
+
? {}
|
|
60
|
+
: { message: parsed.data.message }),
|
|
61
|
+
progressToken: token,
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
const write = writes.then(async () => {
|
|
65
|
+
if (!signal.aborted) {
|
|
66
|
+
// Pace each operation without dropping updates or bypassing backpressure.
|
|
67
|
+
let remaining = 100 - (performance.now() - lastSent);
|
|
68
|
+
while (remaining > 0) {
|
|
69
|
+
await waitForProgress(Math.ceil(remaining), signal);
|
|
70
|
+
remaining = 100 - (performance.now() - lastSent);
|
|
71
|
+
}
|
|
72
|
+
await abortable(Promise.resolve().then(() => {
|
|
73
|
+
if (!signal.aborted) {
|
|
74
|
+
lastSent = performance.now();
|
|
75
|
+
return send(message);
|
|
76
|
+
}
|
|
77
|
+
}), signal);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
// The awaiting handler observes failures; keep the queue usable for cleanup.
|
|
81
|
+
writes = write.catch(() => { });
|
|
82
|
+
return write;
|
|
83
|
+
};
|
|
84
|
+
return {
|
|
85
|
+
report,
|
|
86
|
+
async finish() {
|
|
87
|
+
open = false;
|
|
88
|
+
await writes;
|
|
89
|
+
},
|
|
90
|
+
close() {
|
|
91
|
+
open = false;
|
|
92
|
+
lifetime.abort(new DOMException("Progress reporting closed", "AbortError"));
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/tools/progress.ts"],"names":[],"mappings":"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"}
|
package/dist/transport.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ProtocolResponse } from "@toolgrain/protocol";
|
|
1
|
+
import type { ProgressNotification, ProtocolResponse } from "@toolgrain/protocol";
|
|
2
2
|
import type { Server } from "./server.js";
|
|
3
3
|
/** Callbacks are synchronous; message processing runs independently. */
|
|
4
4
|
export interface TransportCallbacks {
|
|
@@ -21,10 +21,10 @@ export interface Transport {
|
|
|
21
21
|
*/
|
|
22
22
|
start(callbacks: TransportCallbacks): Promise<void>;
|
|
23
23
|
/**
|
|
24
|
-
* Send one
|
|
25
|
-
* @param message -
|
|
24
|
+
* Send one response or progress notification, resolving after write/backpressure handling.
|
|
25
|
+
* @param message - Envelope already converted for the client's protocol revision.
|
|
26
26
|
*/
|
|
27
|
-
send(message: ProtocolResponse): Promise<void>;
|
|
27
|
+
send(message: ProtocolResponse | ProgressNotification): Promise<void>;
|
|
28
28
|
/** Release adapter-owned resources; closing is terminal and must tolerate repeated calls. */
|
|
29
29
|
close(): Promise<void>;
|
|
30
30
|
}
|
package/dist/transport.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,oFAAoF;IACpF,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,yFAAyF;IACzF,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,4FAA4F;IAC5F,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,mFAAmF;IACnF,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC;IAC1B;;;OAGG;IACH,KAAK,CAAC,SAAS,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,6FAA6F;IAC7F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB;;;;OAIG;IACH,KAAK,CACH,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,SAAS,CAAC,GACzD,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,0FAA0F;IAC1F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,GAAG,gBAAgB,GACtC,SAAS,IAAI,gBAAgB,CAE/B"}
|
package/dist/transport.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAqDA,MAAM,UAAU,kBAAkB,CAChC,SAAuC;IAEvC,OAAO,MAAM,IAAI,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC;AAC7D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toolgrain/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-alpha.1",
|
|
4
4
|
"description": "Define reusable, typed MCP tools and servers with Zod validation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public",
|
|
25
25
|
"registry": "https://registry.npmjs.org/",
|
|
26
|
-
"tag": "
|
|
26
|
+
"tag": "alpha"
|
|
27
27
|
},
|
|
28
28
|
"type": "module",
|
|
29
29
|
"exports": {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@toolgrain/repo-tools": "0.0.0"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@toolgrain/protocol": "0.
|
|
62
|
+
"@toolgrain/protocol": "0.3.0-alpha.1"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": "^24.20.0",
|
package/src/connection.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
+
INVALID_PARAMS,
|
|
2
3
|
INVALID_REQUEST,
|
|
3
4
|
PARSE_ERROR,
|
|
5
|
+
type ProgressNotification,
|
|
4
6
|
type ProtocolResponse,
|
|
5
7
|
} from "@toolgrain/protocol";
|
|
6
8
|
import { type ErrorHandler, reportError } from "./diagnostics.js";
|
|
@@ -12,6 +14,7 @@ import { decode } from "./protocol/decode.js";
|
|
|
12
14
|
import type { Request } from "./protocol/messages.js";
|
|
13
15
|
import { protocolError } from "./protocol/responses.js";
|
|
14
16
|
import type { Server } from "./server.js";
|
|
17
|
+
import { isProgressToken } from "./tools/progress.js";
|
|
15
18
|
import type {
|
|
16
19
|
RequestTransport,
|
|
17
20
|
Transport,
|
|
@@ -134,7 +137,7 @@ class Connection implements ConnectionLifecycle {
|
|
|
134
137
|
}
|
|
135
138
|
|
|
136
139
|
private send(
|
|
137
|
-
message: ProtocolResponse,
|
|
140
|
+
message: ProtocolResponse | ProgressNotification,
|
|
138
141
|
isActive: () => boolean = () => this.isOpen(),
|
|
139
142
|
): Promise<void> {
|
|
140
143
|
const write = this.writes.then(async () => {
|
|
@@ -188,12 +191,29 @@ class Connection implements ConnectionLifecycle {
|
|
|
188
191
|
);
|
|
189
192
|
return;
|
|
190
193
|
}
|
|
194
|
+
const token = (request.params?._meta as Record<string, unknown> | undefined)
|
|
195
|
+
?.progressToken;
|
|
196
|
+
if (isProgressToken(token) && !pending.claimProgress(token)) {
|
|
197
|
+
pending.finish();
|
|
198
|
+
await this.send(
|
|
199
|
+
protocolError(
|
|
200
|
+
INVALID_PARAMS,
|
|
201
|
+
"Progress token is already in use",
|
|
202
|
+
request.id,
|
|
203
|
+
),
|
|
204
|
+
);
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
191
207
|
const initialization = this.legacy.begin(request, prepared.protocolVersion);
|
|
192
208
|
try {
|
|
193
209
|
const response = await executeRequest(
|
|
194
210
|
this.dispatch,
|
|
195
211
|
request,
|
|
196
|
-
{
|
|
212
|
+
{
|
|
213
|
+
signal: pending.signal,
|
|
214
|
+
client: this.legacy.client(),
|
|
215
|
+
notify: (message) => this.send(message, pending.isActive),
|
|
216
|
+
},
|
|
197
217
|
(error) => this.report(error),
|
|
198
218
|
prepared.protocolVersion,
|
|
199
219
|
);
|
package/src/dispatcher.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
type Implementation,
|
|
3
3
|
type JSONRPCErrorResponse,
|
|
4
4
|
LEGACY_PROTOCOL_VERSION,
|
|
5
|
+
type ProgressNotification,
|
|
5
6
|
type ProtocolResponse,
|
|
6
7
|
type SupportedProtocolVersion,
|
|
7
8
|
} from "@toolgrain/protocol";
|
|
@@ -16,7 +17,7 @@ import { createModernDispatcher } from "./modern/dispatcher.js";
|
|
|
16
17
|
import type { Request } from "./protocol/messages.js";
|
|
17
18
|
import { validateVersionContext } from "./protocol/version-metadata.js";
|
|
18
19
|
import type { ToolAdapter } from "./tools/adapter.js";
|
|
19
|
-
import type { ToolClient } from "./tools/context.js";
|
|
20
|
+
import type { ToolClient, ToolContext } from "./tools/context.js";
|
|
20
21
|
|
|
21
22
|
/** Per-request execution state supplied by the connection or independent caller. */
|
|
22
23
|
export interface RequestScope {
|
|
@@ -24,6 +25,8 @@ export interface RequestScope {
|
|
|
24
25
|
/** Client details negotiated by legacy initialization, when the connection has them. */
|
|
25
26
|
client?: ToolClient | undefined;
|
|
26
27
|
auth?: AuthIdentity;
|
|
28
|
+
notify?: (message: ProgressNotification) => void | Promise<void>;
|
|
29
|
+
reportProgress?: ToolContext["reportProgress"];
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export type Dispatcher = (
|
package/src/execute-request.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { type ErrorHandler, reportError } from "./diagnostics.js";
|
|
|
7
7
|
import type { Dispatcher, RequestScope } from "./dispatcher.js";
|
|
8
8
|
import type { Request } from "./protocol/messages.js";
|
|
9
9
|
import { ProtocolError, protocolError } from "./protocol/responses.js";
|
|
10
|
+
import { createProgressReporter } from "./tools/progress.js";
|
|
10
11
|
|
|
11
12
|
/** Shared dispatch boundary for connection-scoped and independent requests. */
|
|
12
13
|
export async function executeRequest(
|
|
@@ -17,8 +18,20 @@ export async function executeRequest(
|
|
|
17
18
|
protocolVersion?: SupportedProtocolVersion,
|
|
18
19
|
): Promise<ProtocolResponse | undefined> {
|
|
19
20
|
const isActive = () => !scope.signal.aborted;
|
|
21
|
+
let progress: ReturnType<typeof createProgressReporter> | undefined;
|
|
20
22
|
try {
|
|
21
|
-
|
|
23
|
+
progress = createProgressReporter(
|
|
24
|
+
scope.signal,
|
|
25
|
+
(request.params?._meta as Record<string, unknown> | undefined)
|
|
26
|
+
?.progressToken,
|
|
27
|
+
scope.notify,
|
|
28
|
+
);
|
|
29
|
+
const response = await dispatch(
|
|
30
|
+
request,
|
|
31
|
+
{ ...scope, reportProgress: progress.report },
|
|
32
|
+
protocolVersion,
|
|
33
|
+
);
|
|
34
|
+
await progress.finish();
|
|
22
35
|
return isActive() ? response : undefined;
|
|
23
36
|
} catch (error) {
|
|
24
37
|
if (!isActive()) return;
|
|
@@ -31,5 +44,7 @@ export async function executeRequest(
|
|
|
31
44
|
request.id,
|
|
32
45
|
undefined,
|
|
33
46
|
);
|
|
47
|
+
} finally {
|
|
48
|
+
progress?.close();
|
|
34
49
|
}
|
|
35
50
|
}
|
package/src/index.ts
CHANGED
|
@@ -26,6 +26,7 @@ export { toolContext } from "./tools/context.js";
|
|
|
26
26
|
export type { Tool, ToolDefinition, ToolMetadata } from "./tools/definition.js";
|
|
27
27
|
export { tool } from "./tools/definition.js";
|
|
28
28
|
export { ToolNameError } from "./tools/name.js";
|
|
29
|
+
export type { ToolProgress } from "./tools/progress.js";
|
|
29
30
|
export type { ToolMap } from "./tools/registry.js";
|
|
30
31
|
export type {
|
|
31
32
|
McpErrorResult,
|
package/src/legacy/dispatcher.ts
CHANGED
package/src/legacy/messages.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { object } from "../protocol/messages.js";
|
|
2
|
+
import { object, requestId } from "../protocol/messages.js";
|
|
3
3
|
|
|
4
4
|
export const commonParams = z.looseObject({
|
|
5
|
-
_meta:
|
|
5
|
+
_meta: z.looseObject({ progressToken: requestId.optional() }).optional(),
|
|
6
6
|
});
|
|
7
7
|
export const initializeParams = commonParams.extend({
|
|
8
8
|
protocolVersion: z.string(),
|
package/src/modern/dispatcher.ts
CHANGED
package/src/modern/metadata.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { icon } from "../protocol/icon.js";
|
|
3
|
-
import { object } from "../protocol/messages.js";
|
|
3
|
+
import { object, requestId } from "../protocol/messages.js";
|
|
4
4
|
|
|
5
5
|
const capabilityObject = z.record(z.string(), z.json());
|
|
6
|
-
const requestId = z.union([z.string(), z.number().finite()]);
|
|
7
6
|
const capabilities = z.looseObject({
|
|
8
7
|
experimental: z.record(z.string(), capabilityObject).optional(),
|
|
9
8
|
roots: object.optional(),
|
package/src/pending-requests.ts
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
|
-
import type { RequestId } from "@toolgrain/protocol";
|
|
1
|
+
import type { ProgressToken, RequestId } from "@toolgrain/protocol";
|
|
2
2
|
|
|
3
3
|
/** Owns duplicate detection and cancellation signals for in-flight requests. */
|
|
4
4
|
export function createPendingRequests(isOpen: () => boolean) {
|
|
5
5
|
const pending = new Map<RequestId, AbortController>();
|
|
6
|
+
const progressTokens = new Set<ProgressToken>();
|
|
6
7
|
return {
|
|
7
8
|
begin(id: RequestId) {
|
|
8
9
|
if (pending.has(id)) return;
|
|
9
10
|
const controller = new AbortController();
|
|
10
11
|
pending.set(id, controller);
|
|
12
|
+
let releaseProgress: (() => void) | undefined;
|
|
11
13
|
return {
|
|
12
14
|
signal: controller.signal,
|
|
13
15
|
isActive: () => isOpen() && !controller.signal.aborted,
|
|
16
|
+
claimProgress(token: ProgressToken) {
|
|
17
|
+
if (progressTokens.has(token)) return false;
|
|
18
|
+
progressTokens.add(token);
|
|
19
|
+
releaseProgress = () => {
|
|
20
|
+
progressTokens.delete(token);
|
|
21
|
+
controller.signal.removeEventListener("abort", release);
|
|
22
|
+
releaseProgress = undefined;
|
|
23
|
+
};
|
|
24
|
+
// Aborting releases the token even if the cancelled handler keeps running.
|
|
25
|
+
const release = () => releaseProgress?.();
|
|
26
|
+
controller.signal.addEventListener("abort", release, { once: true });
|
|
27
|
+
return true;
|
|
28
|
+
},
|
|
14
29
|
finish: () => {
|
|
30
|
+
releaseProgress?.();
|
|
15
31
|
pending.delete(id);
|
|
16
32
|
},
|
|
17
33
|
};
|
package/src/server.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
ProgressNotification,
|
|
2
3
|
ProtocolResponse,
|
|
3
4
|
Tool as ProtocolTool,
|
|
4
5
|
SupportedProtocolVersion,
|
|
5
6
|
} from "@toolgrain/protocol";
|
|
7
|
+
import { abortable } from "./abort.js";
|
|
6
8
|
import { createAuthorization } from "./auth/authorization.js";
|
|
7
9
|
import { AuthError, isAuthError } from "./auth/errors.js";
|
|
8
10
|
import type { AuthMetadata, AuthProvider, AuthScope } from "./auth/types.js";
|
|
@@ -21,6 +23,13 @@ import {
|
|
|
21
23
|
type Transport,
|
|
22
24
|
} from "./transport.js";
|
|
23
25
|
|
|
26
|
+
// Internal adapter contract: final delivery remains part of the active request.
|
|
27
|
+
// A global symbol preserves the hook across compatible package copies.
|
|
28
|
+
const responseDelivery = Symbol.for("@toolgrain/mcp/response-delivery/v1");
|
|
29
|
+
interface ResponseDeliveryOptions {
|
|
30
|
+
[responseDelivery]?: (response: ProtocolResponse) => void | Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
/** Tool registrations, identity, and shared configuration for an MCP server. */
|
|
25
34
|
export interface ServerOptions<Tools extends ToolMap = ToolMap> {
|
|
26
35
|
/** Server implementation name advertised to clients. */
|
|
@@ -54,6 +63,13 @@ export interface HandleOptions {
|
|
|
54
63
|
protocolVersion?: SupportedProtocolVersion;
|
|
55
64
|
/** Single-use scope issued by this server's `authorize()`; dispose it in `finally`. */
|
|
56
65
|
auth?: AuthScope;
|
|
66
|
+
/**
|
|
67
|
+
* Deliver progress notifications for this request, honoring asynchronous
|
|
68
|
+
* backpressure. Omit for a one-response caller; progress then becomes a no-op.
|
|
69
|
+
* The caller owns framing and must abort `signal` when its response channel closes.
|
|
70
|
+
* Callback failure cancels this invocation and reaches `onError(error)` without tool details.
|
|
71
|
+
*/
|
|
72
|
+
onNotification?: (message: ProgressNotification) => void | Promise<void>;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
/** An MCP dispatcher with one optional transport attachment and terminal shutdown. */
|
|
@@ -147,6 +163,9 @@ export function createServer<const Tools extends ToolMap>(
|
|
|
147
163
|
running.add(controller);
|
|
148
164
|
return {
|
|
149
165
|
signal: controller.signal,
|
|
166
|
+
abort(reason: unknown) {
|
|
167
|
+
controller.abort(reason);
|
|
168
|
+
},
|
|
150
169
|
finish() {
|
|
151
170
|
signal?.removeEventListener("abort", abort);
|
|
152
171
|
running.delete(controller);
|
|
@@ -185,10 +204,8 @@ export function createServer<const Tools extends ToolMap>(
|
|
|
185
204
|
throw error;
|
|
186
205
|
}
|
|
187
206
|
},
|
|
188
|
-
async handle(
|
|
189
|
-
|
|
190
|
-
{ signal, protocolVersion, auth }: HandleOptions = {},
|
|
191
|
-
) {
|
|
207
|
+
async handle(message, handleOptions: HandleOptions = {}) {
|
|
208
|
+
const { signal, protocolVersion, auth, onNotification } = handleOptions;
|
|
192
209
|
if (closed) throw new Error("Server is closed");
|
|
193
210
|
const identity = authorization.consume(auth);
|
|
194
211
|
if (auth?.signal.aborted) return;
|
|
@@ -204,13 +221,62 @@ export function createServer<const Tools extends ToolMap>(
|
|
|
204
221
|
? AbortSignal.any([pending.signal, auth.signal])
|
|
205
222
|
: pending.signal;
|
|
206
223
|
try {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
224
|
+
const response = await abortable(
|
|
225
|
+
executeRequest(
|
|
226
|
+
dispatch,
|
|
227
|
+
incoming.request,
|
|
228
|
+
{
|
|
229
|
+
signal: combined,
|
|
230
|
+
...(identity ? { auth: identity } : {}),
|
|
231
|
+
...(onNotification
|
|
232
|
+
? {
|
|
233
|
+
notify: async (message: ProgressNotification) => {
|
|
234
|
+
try {
|
|
235
|
+
await onNotification(message);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
if (combined.aborted) return;
|
|
238
|
+
reportError(options.onError, error);
|
|
239
|
+
pending.abort(
|
|
240
|
+
new DOMException(
|
|
241
|
+
"Progress delivery failed",
|
|
242
|
+
"AbortError",
|
|
243
|
+
),
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
}
|
|
248
|
+
: {}),
|
|
249
|
+
},
|
|
250
|
+
options.onError,
|
|
251
|
+
protocolVersion,
|
|
252
|
+
),
|
|
253
|
+
combined,
|
|
213
254
|
);
|
|
255
|
+
const deliver = (handleOptions as ResponseDeliveryOptions)[
|
|
256
|
+
responseDelivery
|
|
257
|
+
];
|
|
258
|
+
if (response && deliver) {
|
|
259
|
+
try {
|
|
260
|
+
await abortable(
|
|
261
|
+
Promise.resolve().then(() => {
|
|
262
|
+
combined.throwIfAborted();
|
|
263
|
+
return deliver(response);
|
|
264
|
+
}),
|
|
265
|
+
combined,
|
|
266
|
+
);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (!combined.aborted) {
|
|
269
|
+
reportError(options.onError, error);
|
|
270
|
+
pending.abort(
|
|
271
|
+
new DOMException("Response delivery failed", "AbortError"),
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return response;
|
|
278
|
+
} catch (error) {
|
|
279
|
+
if (!combined.aborted) throw error;
|
|
214
280
|
} finally {
|
|
215
281
|
pending.finish();
|
|
216
282
|
}
|