@openclaw/gateway-client 2026.9.4 → 2026.9.6
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 +35 -0
- package/dist/browser.d.mts +13 -4
- package/dist/browser.mjs +3 -2
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +243 -127
- package/dist/{protocol-client-DbX7wQED.d.mts → protocol-client-D6mJuY1_.d.mts} +15 -6
- package/dist/{protocol-request-B5gBmLgq.d.mts → protocol-request-CtVhe3Bj.d.mts} +1 -1
- package/dist/{readiness-DabX0O0A.d.mts → readiness-ChxbBSMj.d.mts} +42 -26
- package/dist/readiness.d.mts +1 -1
- package/dist/scope-upgrade.d.mts +1 -1
- package/dist/{session-subscriptions-BSQIANvX.d.mts → session-subscriptions-C91CEXwY.d.mts} +15 -13
- package/dist/{session-subscriptions-DIcpqS8A.mjs → session-subscriptions-DUpRfWJb.mjs} +277 -85
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as resolveGatewayConnectScopes, C as GatewayProtocolRequestTimeoutError, D as gatewayOriginScope, E as gatewayCredentialScope, F as normalizeDeviceMetadataForAuth, M as shouldRetryGatewayWithDeviceToken, N as buildDeviceAuthPayload, O as GatewayBrowserDeviceAuthLifecycle, P as buildDeviceAuthPayloadV3, S as GatewayProtocolRequestError, T as resolveModelCatalogConnect, _ as readSessionMessageIdentity, a as createSessionProjection, b as shouldPauseGatewayReconnect, c as reduceSessionProjection, d as readSessionProjectionFinalMessageIdentity, f as isSessionProjectionErrorMessage, g as readAssistantStreamSegmentIdentity, h as normalizeSessionProjectionRunId, i as resetGatewaySessionMessageSubscriptionCoordinator, j as selectGatewayConnectAuth, k as buildGatewayConnectAuth, l as reduceSessionProjectionRunEvent, m as isLocallyOptimisticSessionMessage, n as getGatewaySessionMessageSubscriptionCoordinator, o as projectLiveSessionMessage, p as projectSessionTerminalReplyMessage, r as releaseGatewaySessionMessageSubscription, s as reconcileSessionProjectionSnapshot, t as GatewaySessionMessageSubscriptionCoordinator, u as hasSessionProjectionAcceptedFinal, v as readSessionMessageSequence, w as isGatewayProtocolResponseError, x as GatewayProtocolClient, y as isRecord } from "./session-subscriptions-DUpRfWJb.mjs";
|
|
2
2
|
import { DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, getConnectChallengeTimeoutMsFromEnv, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, startGatewayConnectTimeout } from "./timeouts.mjs";
|
|
3
3
|
import { rawDataToString } from "./websocket-data.mjs";
|
|
4
4
|
import { n as startGatewayClientWithReadinessWait, r as waitForEventLoopReady, t as startGatewayClientWhenEventLoopReady } from "./readiness-CrWxd4TI.mjs";
|
|
@@ -385,6 +385,13 @@ function normalizeGatewayErrorText(value) {
|
|
|
385
385
|
function isSensitiveUrlQueryParamName(key) {
|
|
386
386
|
return /(?:token|password|secret|key|auth|credential)/iu.test(key);
|
|
387
387
|
}
|
|
388
|
+
function isGatewayClientStoppedError(err) {
|
|
389
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
390
|
+
return message === "gateway client stopped" || message === "Error: gateway client stopped";
|
|
391
|
+
}
|
|
392
|
+
function formatGatewayClientErrorForLog(err) {
|
|
393
|
+
return String(err).replace(/\/\/([^@/?#\s]+)@/g, "//***:***@").replace(/(Authorization:\s*Bearer\s+)[^\s]+/giu, "$1***").replace(/([?&])([^=&\s]+)=([^&#\s"'<>)]*)/g, (match, prefix, key) => isSensitiveUrlQueryParamName(key) ? `${prefix}${key}=***` : match);
|
|
394
|
+
}
|
|
388
395
|
const SHA256_HEX_FINGERPRINT = /^[a-fA-F0-9]{64}$/u;
|
|
389
396
|
const SHA256_COLON_FINGERPRINT = /^(?:[a-fA-F0-9]{2}:){31}[a-fA-F0-9]{2}$/u;
|
|
390
397
|
function normalizeTlsFingerprint(fingerprint) {
|
|
@@ -410,6 +417,115 @@ function parseGatewayIpAddress(host) {
|
|
|
410
417
|
return normalized ? parseCanonicalIpAddress(normalized) : void 0;
|
|
411
418
|
}
|
|
412
419
|
//#endregion
|
|
420
|
+
//#region packages/gateway-client/src/client-device-auth.ts
|
|
421
|
+
/** Owns pending host storage work for one client across connection generations. */
|
|
422
|
+
var GatewayClientDeviceAuth = class {
|
|
423
|
+
constructor(storage) {
|
|
424
|
+
this.storage = storage;
|
|
425
|
+
this.operations = /* @__PURE__ */ new Set();
|
|
426
|
+
}
|
|
427
|
+
load(params) {
|
|
428
|
+
const load = () => {
|
|
429
|
+
params.signal?.throwIfAborted();
|
|
430
|
+
params.assertCurrent?.();
|
|
431
|
+
return this.track(this.storage.loadDeviceAuthToken(params));
|
|
432
|
+
};
|
|
433
|
+
return this.operations.size > 0 ? this.settle().then(load) : load();
|
|
434
|
+
}
|
|
435
|
+
store(params, onStored, onFailed) {
|
|
436
|
+
const failed = (error) => {
|
|
437
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
438
|
+
let reported = false;
|
|
439
|
+
try {
|
|
440
|
+
reported = onFailed(failure);
|
|
441
|
+
} catch {}
|
|
442
|
+
if (!reported) this.unreportedPersistenceFailure ??= failure;
|
|
443
|
+
throw failure;
|
|
444
|
+
};
|
|
445
|
+
params.signal?.throwIfAborted();
|
|
446
|
+
params.assertCurrent?.();
|
|
447
|
+
const stored = this.storage.storeDeviceAuthToken(params);
|
|
448
|
+
return stored instanceof Promise ? this.track(stored.then(onStored).catch(failed)) : onStored();
|
|
449
|
+
}
|
|
450
|
+
clear(params, observation, canClear) {
|
|
451
|
+
const clear = () => {
|
|
452
|
+
if (!canClear()) return;
|
|
453
|
+
const knownTokens = [observation.token, observation.receiptToken].filter((token) => typeof token === "string");
|
|
454
|
+
const expectedTokens = [...new Set(knownTokens)];
|
|
455
|
+
if (observation.token === void 0 && expectedTokens.length === 0) expectedTokens.push(void 0);
|
|
456
|
+
const clearToken = (expectedToken) => {
|
|
457
|
+
params.signal?.throwIfAborted();
|
|
458
|
+
params.assertCurrent?.();
|
|
459
|
+
const cleared = this.storage.clearDeviceAuthToken({
|
|
460
|
+
...params,
|
|
461
|
+
...expectedToken === void 0 ? {} : { expectedToken }
|
|
462
|
+
});
|
|
463
|
+
return cleared instanceof Promise ? cleared.then(() => {}) : void 0;
|
|
464
|
+
};
|
|
465
|
+
let pending;
|
|
466
|
+
for (const expectedToken of expectedTokens) pending = pending ? pending.then(() => clearToken(expectedToken)) : clearToken(expectedToken);
|
|
467
|
+
return pending;
|
|
468
|
+
};
|
|
469
|
+
return this.track(observation.persistence ? observation.persistence.then(clear, clear) : clear());
|
|
470
|
+
}
|
|
471
|
+
async settle() {
|
|
472
|
+
await Promise.allSettled(this.operations);
|
|
473
|
+
}
|
|
474
|
+
async drain() {
|
|
475
|
+
await this.settle();
|
|
476
|
+
const failure = this.unreportedPersistenceFailure;
|
|
477
|
+
this.unreportedPersistenceFailure = void 0;
|
|
478
|
+
if (failure) throw failure;
|
|
479
|
+
}
|
|
480
|
+
track(operation) {
|
|
481
|
+
if (!(operation instanceof Promise)) return operation;
|
|
482
|
+
this.operations.add(operation);
|
|
483
|
+
operation.then(() => this.operations.delete(operation), () => this.operations.delete(operation));
|
|
484
|
+
return operation;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
//#endregion
|
|
488
|
+
//#region packages/gateway-client/src/client-upgrade-error.ts
|
|
489
|
+
const MAX_UPGRADE_ERROR_BODY_BYTES = 2048;
|
|
490
|
+
const UPGRADE_ERROR_BODY_TIMEOUT_MS = 1e3;
|
|
491
|
+
async function readUpgradeErrorBody(response) {
|
|
492
|
+
return await new Promise((resolve) => {
|
|
493
|
+
const chunks = [];
|
|
494
|
+
let totalBytes = 0;
|
|
495
|
+
let settled = false;
|
|
496
|
+
const finish = () => {
|
|
497
|
+
if (settled) return;
|
|
498
|
+
settled = true;
|
|
499
|
+
clearTimeout(timer);
|
|
500
|
+
response.off("data", onData);
|
|
501
|
+
response.off("end", finish);
|
|
502
|
+
response.off("error", finish);
|
|
503
|
+
response.off("aborted", finish);
|
|
504
|
+
resolve(Buffer.concat(chunks, totalBytes).toString("utf8").replace(/\s+/gu, " ").trim());
|
|
505
|
+
};
|
|
506
|
+
const stop = () => {
|
|
507
|
+
finish();
|
|
508
|
+
response.destroy();
|
|
509
|
+
};
|
|
510
|
+
const onData = (chunk) => {
|
|
511
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
512
|
+
const remaining = MAX_UPGRADE_ERROR_BODY_BYTES - totalBytes;
|
|
513
|
+
if (remaining > 0) {
|
|
514
|
+
const prefix = buffer.subarray(0, remaining);
|
|
515
|
+
chunks.push(prefix);
|
|
516
|
+
totalBytes += prefix.byteLength;
|
|
517
|
+
}
|
|
518
|
+
if (buffer.byteLength >= remaining) stop();
|
|
519
|
+
};
|
|
520
|
+
const timer = setTimeout(stop, UPGRADE_ERROR_BODY_TIMEOUT_MS);
|
|
521
|
+
timer.unref?.();
|
|
522
|
+
response.on("data", onData);
|
|
523
|
+
response.once("end", finish);
|
|
524
|
+
response.once("error", finish);
|
|
525
|
+
response.once("aborted", finish);
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
//#endregion
|
|
413
529
|
//#region packages/gateway-client/src/request-error.ts
|
|
414
530
|
var GatewayClientRequestError = class extends GatewayProtocolRequestError {
|
|
415
531
|
constructor(error) {
|
|
@@ -423,6 +539,17 @@ var GatewayClientRequestError = class extends GatewayProtocolRequestError {
|
|
|
423
539
|
this.name = "GatewayClientRequestError";
|
|
424
540
|
}
|
|
425
541
|
};
|
|
542
|
+
const GATEWAY_CONNECT_ASSEMBLY_ERROR = Symbol("gateway.connectAssemblyError");
|
|
543
|
+
function markGatewayConnectAssemblyError(error) {
|
|
544
|
+
Object.defineProperty(error, GATEWAY_CONNECT_ASSEMBLY_ERROR, {
|
|
545
|
+
configurable: true,
|
|
546
|
+
value: true
|
|
547
|
+
});
|
|
548
|
+
return error;
|
|
549
|
+
}
|
|
550
|
+
function isGatewayConnectAssemblyError(value) {
|
|
551
|
+
return value instanceof Error && value[GATEWAY_CONNECT_ASSEMBLY_ERROR] === true;
|
|
552
|
+
}
|
|
426
553
|
//#endregion
|
|
427
554
|
//#region packages/net-policy/src/url-protocol.ts
|
|
428
555
|
function parseUrl(value) {
|
|
@@ -538,7 +665,10 @@ function applyGatewayWebSocketTlsPin(options, expectedFingerprint, normalize = n
|
|
|
538
665
|
//#endregion
|
|
539
666
|
//#region packages/gateway-client/src/websocket.ts
|
|
540
667
|
const require = createRequire(import.meta.url);
|
|
541
|
-
const
|
|
668
|
+
const wsPackageRoot = path.dirname(require.resolve("ws/package.json"));
|
|
669
|
+
const WebSocket = require(path.join(wsPackageRoot, "lib/websocket.js"));
|
|
670
|
+
require(path.join(wsPackageRoot, "lib/websocket-server.js"));
|
|
671
|
+
require(path.join(wsPackageRoot, "lib/stream.js"));
|
|
542
672
|
//#endregion
|
|
543
673
|
//#region packages/gateway-client/src/client.ts
|
|
544
674
|
const DEFAULT_HOST_DEPS = {
|
|
@@ -564,45 +694,6 @@ function resolveHostDeps(overrides) {
|
|
|
564
694
|
}
|
|
565
695
|
const DEFAULT_GATEWAY_CLIENT_URL = "ws://127.0.0.1:18789";
|
|
566
696
|
const DEFAULT_CLIENT_VERSION = "0.0.0";
|
|
567
|
-
const MAX_UPGRADE_ERROR_BODY_BYTES = 2048;
|
|
568
|
-
const UPGRADE_ERROR_BODY_TIMEOUT_MS = 1e3;
|
|
569
|
-
async function readUpgradeErrorBody(response) {
|
|
570
|
-
return await new Promise((resolve) => {
|
|
571
|
-
const chunks = [];
|
|
572
|
-
let totalBytes = 0;
|
|
573
|
-
let settled = false;
|
|
574
|
-
const finish = () => {
|
|
575
|
-
if (settled) return;
|
|
576
|
-
settled = true;
|
|
577
|
-
clearTimeout(timer);
|
|
578
|
-
response.off("data", onData);
|
|
579
|
-
response.off("end", finish);
|
|
580
|
-
response.off("error", finish);
|
|
581
|
-
response.off("aborted", finish);
|
|
582
|
-
resolve(Buffer.concat(chunks, totalBytes).toString("utf8").replace(/\s+/gu, " ").trim());
|
|
583
|
-
};
|
|
584
|
-
const stop = () => {
|
|
585
|
-
finish();
|
|
586
|
-
response.destroy();
|
|
587
|
-
};
|
|
588
|
-
const onData = (chunk) => {
|
|
589
|
-
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
590
|
-
const remaining = MAX_UPGRADE_ERROR_BODY_BYTES - totalBytes;
|
|
591
|
-
if (remaining > 0) {
|
|
592
|
-
const prefix = buffer.subarray(0, remaining);
|
|
593
|
-
chunks.push(prefix);
|
|
594
|
-
totalBytes += prefix.byteLength;
|
|
595
|
-
}
|
|
596
|
-
if (buffer.byteLength >= remaining) stop();
|
|
597
|
-
};
|
|
598
|
-
const timer = setTimeout(stop, UPGRADE_ERROR_BODY_TIMEOUT_MS);
|
|
599
|
-
timer.unref?.();
|
|
600
|
-
response.on("data", onData);
|
|
601
|
-
response.once("end", finish);
|
|
602
|
-
response.once("error", finish);
|
|
603
|
-
response.once("aborted", finish);
|
|
604
|
-
});
|
|
605
|
-
}
|
|
606
697
|
var GatewayClientRequestTimeoutError = class extends GatewayProtocolRequestTimeoutError {
|
|
607
698
|
constructor(params) {
|
|
608
699
|
super(params, `gateway request timeout for ${params.method}`);
|
|
@@ -610,24 +701,6 @@ var GatewayClientRequestTimeoutError = class extends GatewayProtocolRequestTimeo
|
|
|
610
701
|
}
|
|
611
702
|
};
|
|
612
703
|
var GatewayClientTransportPolicyError = class extends GatewayWebSocketTransportConfigurationError {};
|
|
613
|
-
const GATEWAY_CONNECT_ASSEMBLY_ERROR = Symbol("gateway.connectAssemblyError");
|
|
614
|
-
function markGatewayConnectAssemblyError(error) {
|
|
615
|
-
Object.defineProperty(error, GATEWAY_CONNECT_ASSEMBLY_ERROR, {
|
|
616
|
-
configurable: true,
|
|
617
|
-
value: true
|
|
618
|
-
});
|
|
619
|
-
return error;
|
|
620
|
-
}
|
|
621
|
-
function isGatewayConnectAssemblyError(value) {
|
|
622
|
-
return value instanceof Error && value[GATEWAY_CONNECT_ASSEMBLY_ERROR] === true;
|
|
623
|
-
}
|
|
624
|
-
function isGatewayClientStoppedError(err) {
|
|
625
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
626
|
-
return message === "gateway client stopped" || message === "Error: gateway client stopped";
|
|
627
|
-
}
|
|
628
|
-
function formatGatewayClientErrorForLog(err) {
|
|
629
|
-
return String(err).replace(/\/\/([^@/?#\s]+)@/g, "//***:***@").replace(/(Authorization:\s*Bearer\s+)[^\s]+/giu, "$1***").replace(/([?&])([^=&\s]+)=([^&#\s"'<>)]*)/g, (match, prefix, key) => isSensitiveUrlQueryParamName(key) ? `${prefix}${key}=***` : match);
|
|
630
|
-
}
|
|
631
704
|
const FORCE_STOP_TERMINATE_GRACE_MS = 250;
|
|
632
705
|
const STOP_AND_WAIT_TIMEOUT_MS = 1e3;
|
|
633
706
|
const MAX_SUPPRESSED_TRANSIENT_PRE_HELLO_CLEAN_CLOSES = 1;
|
|
@@ -644,7 +717,6 @@ var GatewayClient = class {
|
|
|
644
717
|
this.stopped = false;
|
|
645
718
|
this.useLegacyNodeProtocolEnvelope = false;
|
|
646
719
|
this.nodeProtocolTransitionPending = false;
|
|
647
|
-
this.suppressNextHelloCallback = false;
|
|
648
720
|
this.pendingDeviceTokenRetry = false;
|
|
649
721
|
this.deviceTokenRetryBudgetUsed = false;
|
|
650
722
|
this.approvalRuntimeTokenCompatibilityDisabled = false;
|
|
@@ -656,6 +728,7 @@ var GatewayClient = class {
|
|
|
656
728
|
this.transportValidated = false;
|
|
657
729
|
this.suppressedTransientPreHelloCleanCloses = 0;
|
|
658
730
|
this.deps = resolveHostDeps(opts.hostDeps);
|
|
731
|
+
this.deviceAuth = new GatewayClientDeviceAuth(this.deps);
|
|
659
732
|
this.opts = {
|
|
660
733
|
...opts,
|
|
661
734
|
deviceIdentity: opts.deviceIdentity === null ? void 0 : opts.deviceIdentity ?? this.deps.loadOrCreateDeviceIdentity()
|
|
@@ -675,14 +748,32 @@ var GatewayClient = class {
|
|
|
675
748
|
requestSent
|
|
676
749
|
}),
|
|
677
750
|
createRequestAbortError: createGatewayRequestAbortError,
|
|
678
|
-
buildConnectPlan: ({ nonce, challengeTs }) => {
|
|
751
|
+
buildConnectPlan: ({ nonce, challengeTs, serverCapabilities, generation, ...authority }) => {
|
|
679
752
|
if (!nonce) throw new Error("gateway connect challenge missing nonce");
|
|
680
753
|
if (this.opts.deviceIdentity && challengeTs == null) throw new Error("gateway connect challenge timestamp invalid");
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
754
|
+
const role = this.opts.role ?? "operator";
|
|
755
|
+
const assemble = (storedAuth) => {
|
|
756
|
+
authority.assertCurrent();
|
|
757
|
+
const assembled = this.assembleConnectParams({
|
|
758
|
+
role,
|
|
759
|
+
nonce,
|
|
760
|
+
signedAtMs: challengeTs ?? Date.now(),
|
|
761
|
+
serverCapabilities,
|
|
762
|
+
storedAuth
|
|
763
|
+
});
|
|
764
|
+
this.connectionStoredToken = {
|
|
765
|
+
generation,
|
|
766
|
+
token: assembled.storedToken ?? null
|
|
767
|
+
};
|
|
768
|
+
return assembled;
|
|
769
|
+
};
|
|
770
|
+
const storedAuth = this.opts.deviceIdentity ? this.deviceAuth.load({
|
|
771
|
+
deviceId: this.opts.deviceIdentity.deviceId,
|
|
772
|
+
role,
|
|
773
|
+
env: this.opts.env,
|
|
774
|
+
...authority
|
|
775
|
+
}) : null;
|
|
776
|
+
return storedAuth instanceof Promise ? storedAuth.then(assemble) : assemble(storedAuth);
|
|
686
777
|
},
|
|
687
778
|
buildConnectParams: (assembled) => assembled.params,
|
|
688
779
|
onConnectPlanError: (error) => {
|
|
@@ -698,12 +789,8 @@ var GatewayClient = class {
|
|
|
698
789
|
error: marked
|
|
699
790
|
};
|
|
700
791
|
},
|
|
701
|
-
onConnectHello: (hello, context) => this.handleConnectHello(hello, context.plan),
|
|
792
|
+
onConnectHello: (hello, context) => this.handleConnectHello(hello, context.plan, context),
|
|
702
793
|
onHello: (hello) => {
|
|
703
|
-
if (this.suppressNextHelloCallback) {
|
|
704
|
-
this.suppressNextHelloCallback = false;
|
|
705
|
-
return;
|
|
706
|
-
}
|
|
707
794
|
this.opts.onHelloOk?.(hello);
|
|
708
795
|
},
|
|
709
796
|
onConnectFailure: (error, context) => this.handleConnectRequestFailure(error, context.plan),
|
|
@@ -857,6 +944,7 @@ var GatewayClient = class {
|
|
|
857
944
|
});
|
|
858
945
|
ws.on("error", (err) => {
|
|
859
946
|
if (upgradeError) return;
|
|
947
|
+
if (err.message === "Opening handshake has timed out") Object.assign(err, { code: "ETIMEDOUT" });
|
|
860
948
|
this.logDebug(`gateway client error: ${formatGatewayClientErrorForLog(err)}`);
|
|
861
949
|
handlers.error(err instanceof Error ? err : new Error(String(err)));
|
|
862
950
|
});
|
|
@@ -871,7 +959,6 @@ var GatewayClient = class {
|
|
|
871
959
|
}
|
|
872
960
|
async stopAndWait(opts) {
|
|
873
961
|
const stopPromise = this.beginStop();
|
|
874
|
-
if (!stopPromise) return;
|
|
875
962
|
const timeoutMs = opts?.timeoutMs === void 0 ? STOP_AND_WAIT_TIMEOUT_MS : resolveSafeTimeoutDelayMs(opts.timeoutMs);
|
|
876
963
|
let timeout = null;
|
|
877
964
|
try {
|
|
@@ -883,6 +970,7 @@ var GatewayClient = class {
|
|
|
883
970
|
})]);
|
|
884
971
|
} finally {
|
|
885
972
|
if (timeout) clearTimeout(timeout);
|
|
973
|
+
await this.deviceAuth.drain();
|
|
886
974
|
}
|
|
887
975
|
}
|
|
888
976
|
beginStop() {
|
|
@@ -946,7 +1034,7 @@ var GatewayClient = class {
|
|
|
946
1034
|
}
|
|
947
1035
|
assembleConnectParams(params) {
|
|
948
1036
|
const { role, nonce, signedAtMs } = params;
|
|
949
|
-
const selectedAuth = this.selectConnectAuth(
|
|
1037
|
+
const selectedAuth = this.selectConnectAuth(params.storedAuth);
|
|
950
1038
|
const { authDeviceToken, authApprovalRuntimeToken, authAgentRuntimeIdentityToken, signatureToken, resolvedDeviceToken, storedToken, storedScopes, usingStoredDeviceToken } = selectedAuth;
|
|
951
1039
|
if (this.pendingDeviceTokenRetry && authDeviceToken) this.pendingDeviceTokenRetry = false;
|
|
952
1040
|
const auth = buildGatewayConnectAuth(selectedAuth);
|
|
@@ -981,7 +1069,11 @@ var GatewayClient = class {
|
|
|
981
1069
|
mode: clientMode,
|
|
982
1070
|
instanceId: this.opts.instanceId
|
|
983
1071
|
},
|
|
984
|
-
|
|
1072
|
+
...resolveModelCatalogConnect({
|
|
1073
|
+
caps: Array.isArray(this.opts.caps) ? this.opts.caps : [],
|
|
1074
|
+
modelCatalog: useLegacyNodeProtocolEnvelope ? void 0 : this.opts.modelCatalog,
|
|
1075
|
+
serverCapabilities: params.serverCapabilities
|
|
1076
|
+
}),
|
|
985
1077
|
commands: Array.isArray(this.opts.commands) ? this.opts.commands : void 0,
|
|
986
1078
|
computerUse: useLegacyNodeProtocolEnvelope ? void 0 : this.opts.computerUse,
|
|
987
1079
|
workerRuns: useLegacyNodeProtocolEnvelope ? void 0 : this.opts.workerRuns,
|
|
@@ -1047,35 +1139,56 @@ var GatewayClient = class {
|
|
|
1047
1139
|
nonce
|
|
1048
1140
|
};
|
|
1049
1141
|
}
|
|
1050
|
-
handleConnectHello(helloOk, assembled) {
|
|
1051
|
-
|
|
1052
|
-
if (reconnectWithCurrentNodeProtocol) this.useLegacyNodeProtocolEnvelope = false;
|
|
1053
|
-
this.nodeProtocolTransitionPending = false;
|
|
1054
|
-
this.pendingDeviceTokenRetry = false;
|
|
1055
|
-
this.deviceTokenRetryBudgetUsed = false;
|
|
1056
|
-
this.suppressedTransientPreHelloCleanCloses = 0;
|
|
1142
|
+
handleConnectHello(helloOk, assembled, authority) {
|
|
1143
|
+
authority.assertCurrent();
|
|
1057
1144
|
const role = this.opts.role ?? "operator";
|
|
1058
1145
|
const authInfo = helloOk.auth;
|
|
1146
|
+
const observation = this.connectionStoredToken;
|
|
1147
|
+
const persisted = () => {
|
|
1148
|
+
if (authInfo?.deviceToken && (authInfo.role ?? role) === role && observation) observation.token = authInfo.deviceToken;
|
|
1149
|
+
if (this.opts.preferBootstrapToken) {
|
|
1150
|
+
this.opts.token = void 0;
|
|
1151
|
+
this.opts.bootstrapToken = void 0;
|
|
1152
|
+
this.opts.password = void 0;
|
|
1153
|
+
this.opts.preferBootstrapToken = false;
|
|
1154
|
+
}
|
|
1155
|
+
};
|
|
1156
|
+
let stored = void 0;
|
|
1059
1157
|
if (authInfo?.deviceToken && this.opts.deviceIdentity) {
|
|
1060
1158
|
const tokenRole = authInfo.role ?? role;
|
|
1061
1159
|
const scopes = tokenRole === role && authInfo.deviceToken === assembled.storedToken ? assembled.storedScopes ?? authInfo.scopes ?? [] : authInfo.scopes ?? [];
|
|
1062
|
-
|
|
1160
|
+
if (tokenRole === role && observation) observation.receiptToken = authInfo.deviceToken;
|
|
1161
|
+
stored = this.deviceAuth.store({
|
|
1063
1162
|
deviceId: this.opts.deviceIdentity.deviceId,
|
|
1064
1163
|
role: tokenRole,
|
|
1065
1164
|
token: authInfo.deviceToken,
|
|
1066
1165
|
scopes,
|
|
1067
|
-
env: this.opts.env
|
|
1166
|
+
env: this.opts.env,
|
|
1167
|
+
...tokenRole === role ? { expectedToken: assembled.storedToken ?? null } : {}
|
|
1168
|
+
}, persisted, (error) => {
|
|
1169
|
+
assembled.persistenceFailed = true;
|
|
1170
|
+
const reported = this.notifyConnectError(error);
|
|
1171
|
+
this.logError(`gateway device token persistence failed: ${formatGatewayClientErrorForLog(error)}`);
|
|
1172
|
+
return reported;
|
|
1068
1173
|
});
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
this.
|
|
1075
|
-
}
|
|
1174
|
+
if (observation && stored instanceof Promise) observation.persistence = stored;
|
|
1175
|
+
} else persisted();
|
|
1176
|
+
const complete = () => {
|
|
1177
|
+
if (authority.signal.aborted || !this.protocol.connected) return;
|
|
1178
|
+
authority.assertCurrent();
|
|
1179
|
+
this.completeConnectHello(helloOk);
|
|
1180
|
+
};
|
|
1181
|
+
return stored instanceof Promise ? stored.then(complete) : complete();
|
|
1182
|
+
}
|
|
1183
|
+
completeConnectHello(helloOk) {
|
|
1184
|
+
const reconnectWithCurrentNodeProtocol = this.useLegacyNodeProtocolEnvelope && this.shouldNegotiateLegacyNodeProtocol() && helloOk.protocol > MIN_NODE_PROTOCOL_VERSION;
|
|
1185
|
+
if (reconnectWithCurrentNodeProtocol) this.useLegacyNodeProtocolEnvelope = false;
|
|
1186
|
+
this.nodeProtocolTransitionPending = false;
|
|
1187
|
+
this.pendingDeviceTokenRetry = false;
|
|
1188
|
+
this.deviceTokenRetryBudgetUsed = false;
|
|
1189
|
+
this.suppressedTransientPreHelloCleanCloses = 0;
|
|
1076
1190
|
this.tickIntervalMs = typeof helloOk.policy?.tickIntervalMs === "number" ? helloOk.policy.tickIntervalMs : 3e4;
|
|
1077
1191
|
if (reconnectWithCurrentNodeProtocol) {
|
|
1078
|
-
this.suppressNextHelloCallback = true;
|
|
1079
1192
|
this.protocol.resetReconnectBackoff(250);
|
|
1080
1193
|
this.protocol.closeSocket(1012, "gateway protocol upgraded");
|
|
1081
1194
|
return;
|
|
@@ -1084,6 +1197,16 @@ var GatewayClient = class {
|
|
|
1084
1197
|
this.startTickWatch();
|
|
1085
1198
|
}
|
|
1086
1199
|
handleConnectRequestFailure(error, assembled) {
|
|
1200
|
+
if (assembled.persistenceFailed) return {
|
|
1201
|
+
closeCode: 1008,
|
|
1202
|
+
closeReason: "connect failed"
|
|
1203
|
+
};
|
|
1204
|
+
const detailCode = error instanceof GatewayClientRequestError ? readConnectErrorDetailCode(error.details) : null;
|
|
1205
|
+
const cleared = this.opts.deviceIdentity && assembled.usingStoredDeviceToken && detailCode === ConnectErrorDetailCodes.AUTH_DEVICE_TOKEN_MISMATCH ? this.clearDeviceToken(this.opts.deviceIdentity.deviceId, { token: assembled.storedToken }) : void 0;
|
|
1206
|
+
const decision = this.resolveConnectRequestFailure(error, assembled);
|
|
1207
|
+
return cleared instanceof Promise ? cleared.then(() => decision) : decision;
|
|
1208
|
+
}
|
|
1209
|
+
resolveConnectRequestFailure(error, assembled) {
|
|
1087
1210
|
if (this.shouldRetryWithCurrentNodeProtocol(error)) {
|
|
1088
1211
|
const resetBackoff = !this.nodeProtocolTransitionPending;
|
|
1089
1212
|
this.useLegacyNodeProtocolEnvelope = false;
|
|
@@ -1107,30 +1230,15 @@ var GatewayClient = class {
|
|
|
1107
1230
|
};
|
|
1108
1231
|
}
|
|
1109
1232
|
this.nodeProtocolTransitionPending = false;
|
|
1110
|
-
const role = this.opts.role ?? "operator";
|
|
1111
1233
|
const detailCode = error instanceof GatewayClientRequestError ? readConnectErrorDetailCode(error.details) : null;
|
|
1112
|
-
|
|
1234
|
+
if (shouldRetryGatewayWithDeviceToken({
|
|
1113
1235
|
retryBudgetUsed: this.deviceTokenRetryBudgetUsed,
|
|
1114
1236
|
currentDeviceToken: assembled.resolvedDeviceToken,
|
|
1115
1237
|
explicitToken: this.opts.token?.trim() || void 0,
|
|
1116
1238
|
storedToken: assembled.storedToken,
|
|
1117
1239
|
trustedEndpoint: this.isTrustedDeviceRetryEndpoint(),
|
|
1118
1240
|
errorDetails: error instanceof GatewayClientRequestError ? error.details : void 0
|
|
1119
|
-
})
|
|
1120
|
-
if (this.opts.deviceIdentity && assembled.usingStoredDeviceToken && detailCode === ConnectErrorDetailCodes.AUTH_DEVICE_TOKEN_MISMATCH) {
|
|
1121
|
-
const deviceId = this.opts.deviceIdentity.deviceId;
|
|
1122
|
-
try {
|
|
1123
|
-
this.deps.clearDeviceAuthToken({
|
|
1124
|
-
deviceId,
|
|
1125
|
-
role,
|
|
1126
|
-
env: this.opts.env
|
|
1127
|
-
});
|
|
1128
|
-
this.logDebug(`cleared stale device-auth token for device ${deviceId}`);
|
|
1129
|
-
} catch (clearError) {
|
|
1130
|
-
this.logDebug(`failed clearing stale device-auth token for device ${deviceId}: ${String(clearError)}`);
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
if (shouldRetryWithDeviceToken) {
|
|
1241
|
+
})) {
|
|
1134
1242
|
this.pendingDeviceTokenRetry = true;
|
|
1135
1243
|
this.deviceTokenRetryBudgetUsed = true;
|
|
1136
1244
|
this.protocol.resetReconnectBackoff(250);
|
|
@@ -1202,7 +1310,7 @@ var GatewayClient = class {
|
|
|
1202
1310
|
this.notifyConnectError(error);
|
|
1203
1311
|
this.logError(`gateway connect failed: ${formatGatewayClientErrorForLog(error)}`);
|
|
1204
1312
|
}
|
|
1205
|
-
this.clearStaleDeviceTokenForClose(context
|
|
1313
|
+
this.clearStaleDeviceTokenForClose(context);
|
|
1206
1314
|
if (shouldPauseGatewayReconnect({
|
|
1207
1315
|
details,
|
|
1208
1316
|
deviceTokenRetryPending: this.pendingDeviceTokenRetry,
|
|
@@ -1236,26 +1344,39 @@ var GatewayClient = class {
|
|
|
1236
1344
|
...context.connectFailure?.error ? { connectError: context.connectFailure.error } : {}
|
|
1237
1345
|
};
|
|
1238
1346
|
}
|
|
1239
|
-
clearStaleDeviceTokenForClose(
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
const
|
|
1347
|
+
clearStaleDeviceTokenForClose(context) {
|
|
1348
|
+
const { code, reason, generation } = context;
|
|
1349
|
+
if (code !== 1008 || !normalizeGatewayErrorText(reason).includes("device token mismatch") || !this.opts.deviceIdentity) return;
|
|
1350
|
+
const observation = this.connectionStoredToken?.generation === generation ? this.connectionStoredToken : { token: void 0 };
|
|
1351
|
+
this.clearDeviceToken(this.opts.deviceIdentity.deviceId, observation, () => !this.opts.token && !this.opts.password);
|
|
1352
|
+
}
|
|
1353
|
+
clearDeviceToken(deviceId, observation, canClear = () => true) {
|
|
1354
|
+
const failed = (error) => {
|
|
1355
|
+
this.logDebug(`failed clearing stale device-auth token for device ${deviceId}: ${String(error)}`);
|
|
1356
|
+
};
|
|
1357
|
+
const cleared = () => this.logDebug(`cleared stale device-auth token for device ${deviceId}`);
|
|
1243
1358
|
try {
|
|
1244
|
-
this.
|
|
1359
|
+
const result = this.deviceAuth.clear({
|
|
1245
1360
|
deviceId,
|
|
1246
|
-
role,
|
|
1247
|
-
env: this.opts.env
|
|
1248
|
-
|
|
1249
|
-
|
|
1361
|
+
role: this.opts.role ?? "operator",
|
|
1362
|
+
env: this.opts.env,
|
|
1363
|
+
assertCurrent: () => {
|
|
1364
|
+
if (this.stopped) throw new Error("gateway client stopped");
|
|
1365
|
+
}
|
|
1366
|
+
}, observation, canClear);
|
|
1367
|
+
return result instanceof Promise ? result.then(cleared, failed) : cleared();
|
|
1250
1368
|
} catch (error) {
|
|
1251
|
-
|
|
1369
|
+
failed(error);
|
|
1252
1370
|
}
|
|
1253
1371
|
}
|
|
1254
1372
|
notifyConnectError(error) {
|
|
1373
|
+
if (!this.opts.onConnectError) return false;
|
|
1255
1374
|
try {
|
|
1256
|
-
this.opts.onConnectError
|
|
1375
|
+
this.opts.onConnectError(error);
|
|
1376
|
+
return true;
|
|
1257
1377
|
} catch (err) {
|
|
1258
1378
|
this.logDebug(`gateway client connect error handler error: ${formatGatewayClientErrorForLog(err)}`);
|
|
1379
|
+
return false;
|
|
1259
1380
|
}
|
|
1260
1381
|
}
|
|
1261
1382
|
notifyReconnectPaused(info) {
|
|
@@ -1291,12 +1412,7 @@ var GatewayClient = class {
|
|
|
1291
1412
|
return false;
|
|
1292
1413
|
}
|
|
1293
1414
|
}
|
|
1294
|
-
selectConnectAuth(
|
|
1295
|
-
const storedAuth = this.opts.deviceIdentity ? this.deps.loadDeviceAuthToken({
|
|
1296
|
-
deviceId: this.opts.deviceIdentity.deviceId,
|
|
1297
|
-
role,
|
|
1298
|
-
env: this.opts.env
|
|
1299
|
-
}) : null;
|
|
1415
|
+
selectConnectAuth(storedAuth) {
|
|
1300
1416
|
return selectGatewayConnectAuth({
|
|
1301
1417
|
token: this.opts.token,
|
|
1302
1418
|
bootstrapToken: this.opts.bootstrapToken,
|
|
@@ -1354,4 +1470,4 @@ function buildCloudflareAccessHeaders(credentials) {
|
|
|
1354
1470
|
};
|
|
1355
1471
|
}
|
|
1356
1472
|
//#endregion
|
|
1357
|
-
export { CF_ACCESS_CLIENT_ID_HEADER, CF_ACCESS_CLIENT_SECRET_HEADER, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayClient, GatewayClientRequestError, GatewayClientRequestTimeoutError, GatewayScopeUpgrade, GatewaySessionMessageSubscriptionCoordinator, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, buildCloudflareAccessHeaders, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isGatewayProtocolResponseError, isLocallyOptimisticSessionMessage, isSessionProjectionErrorMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, readAssistantStreamSegmentIdentity, readSessionMessageIdentity, readSessionMessageSequence, readSessionProjectionFinalMessageIdentity, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
|
|
1473
|
+
export { CF_ACCESS_CLIENT_ID_HEADER, CF_ACCESS_CLIENT_SECRET_HEADER, DEFAULT_GATEWAY_REQUEST_TIMEOUT_MS, DEFAULT_PREAUTH_HANDSHAKE_TIMEOUT_MS, GatewayBrowserDeviceAuthLifecycle, GatewayClient, GatewayClientRequestError, GatewayClientRequestTimeoutError, GatewayScopeUpgrade, GatewaySessionMessageSubscriptionCoordinator, MAX_CONNECT_CHALLENGE_TIMEOUT_MS, MAX_SAFE_TIMEOUT_DELAY_MS, MIN_CONNECT_CHALLENGE_TIMEOUT_MS, addSafeTimeoutDelayGraceMs, buildCloudflareAccessHeaders, buildDeviceAuthPayload, buildDeviceAuthPayloadV3, buildGatewayConnectAuth, clampConnectChallengeTimeoutMs, clearGatewayConnectTimeout, createSessionProjection, gatewayCredentialScope, gatewayOriginScope, getConnectChallengeTimeoutMsFromEnv, getGatewaySessionMessageSubscriptionCoordinator, hasSessionProjectionAcceptedFinal, isGatewayConnectAssemblyError, isGatewayProtocolResponseError, isLocallyOptimisticSessionMessage, isSessionProjectionErrorMessage, normalizeDeviceMetadataForAuth, normalizeSessionProjectionRunId, projectLiveSessionMessage, projectSessionTerminalReplyMessage, readAssistantStreamSegmentIdentity, readSessionMessageIdentity, readSessionMessageSequence, readSessionProjectionFinalMessageIdentity, reconcileSessionProjectionSnapshot, reduceSessionProjection, reduceSessionProjectionRunEvent, releaseGatewaySessionMessageSubscription, resetGatewaySessionMessageSubscriptionCoordinator, resolveConnectChallengeTimeoutMs, resolveFiniteTimeoutDelayMs, resolveGatewayConnectScopes, resolvePreauthHandshakeTimeoutMs, resolveSafeTimeoutDelayMs, selectGatewayConnectAuth, shouldRetryGatewayWithDeviceToken, startGatewayClientWhenEventLoopReady, startGatewayClientWithReadinessWait, startGatewayConnectTimeout, waitForEventLoopReady };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as GatewayProtocolRequestOptions, t as GatewayProtocolRequestError } from "./protocol-request-
|
|
1
|
+
import { n as GatewayProtocolRequestOptions, t as GatewayProtocolRequestError } from "./protocol-request-CtVhe3Bj.mjs";
|
|
2
2
|
import { ErrorShape, EventFrame, HelloOk } from "@openclaw/gateway-protocol";
|
|
3
3
|
//#region packages/gateway-client/src/pending-request.d.ts
|
|
4
4
|
type GatewayProtocolRequestTiming = {
|
|
@@ -23,7 +23,11 @@ type GatewayProtocolSocketHandlers = {
|
|
|
23
23
|
close: (code: number, reason: string) => void;
|
|
24
24
|
error: (error: Error) => void;
|
|
25
25
|
};
|
|
26
|
-
type
|
|
26
|
+
type GatewayProtocolConnectAuthority = {
|
|
27
|
+
signal: AbortSignal;
|
|
28
|
+
assertCurrent: () => void;
|
|
29
|
+
};
|
|
30
|
+
type GatewayProtocolConnectContext<TPlan> = GatewayProtocolConnectAuthority & {
|
|
27
31
|
generation: number;
|
|
28
32
|
nonce: string | null;
|
|
29
33
|
challengeTs: number | null | undefined;
|
|
@@ -70,16 +74,17 @@ type GatewayProtocolClientOptions<TPlan> = {
|
|
|
70
74
|
createRequestError?: (error: Partial<ErrorShape>) => GatewayProtocolRequestError;
|
|
71
75
|
createRequestTimeoutError?: (method: string, timeoutMs: number, requestSent: boolean) => Error;
|
|
72
76
|
createRequestAbortError?: (method: string) => Error;
|
|
73
|
-
buildConnectPlan: (params: {
|
|
77
|
+
buildConnectPlan: (params: GatewayProtocolConnectAuthority & {
|
|
74
78
|
nonce: string | null;
|
|
75
79
|
challengeTs: number | null | undefined;
|
|
80
|
+
serverCapabilities: readonly string[];
|
|
76
81
|
generation: number;
|
|
77
82
|
}) => TPlan | Promise<TPlan>;
|
|
78
83
|
buildConnectParams: (plan: TPlan) => unknown;
|
|
79
84
|
onConnectPlanError?: (error: Error) => GatewayProtocolConnectDecision;
|
|
80
|
-
onConnectHello?: (hello: HelloOk, context: GatewayProtocolConnectContext<TPlan>) =>
|
|
85
|
+
onConnectHello?: (hello: HelloOk, context: GatewayProtocolConnectContext<TPlan>) => unknown;
|
|
81
86
|
onHello?: (hello: HelloOk) => void;
|
|
82
|
-
onConnectFailure?: (error: GatewayProtocolRequestError, context: GatewayProtocolConnectContext<TPlan>) => GatewayProtocolConnectDecision
|
|
87
|
+
onConnectFailure?: (error: GatewayProtocolRequestError, context: GatewayProtocolConnectContext<TPlan>) => GatewayProtocolConnectDecision | Promise<GatewayProtocolConnectDecision>;
|
|
83
88
|
resolveClose: (context: GatewayProtocolCloseContext) => GatewayProtocolCloseDecision;
|
|
84
89
|
onClose?: (context: GatewayProtocolCloseContext, decision: GatewayProtocolCloseDecision) => void;
|
|
85
90
|
notifyStoppedClose?: boolean;
|
|
@@ -127,9 +132,11 @@ declare class GatewayProtocolClient<TPlan> {
|
|
|
127
132
|
private readonly listeners;
|
|
128
133
|
private stopped;
|
|
129
134
|
private generation;
|
|
135
|
+
private connectionAbort;
|
|
130
136
|
private lastSeq;
|
|
131
137
|
private connectNonce;
|
|
132
138
|
private connectChallengeTs;
|
|
139
|
+
private serverCapabilities;
|
|
133
140
|
private connectSent;
|
|
134
141
|
private connectRequestSent;
|
|
135
142
|
private handshakeTimer;
|
|
@@ -163,10 +170,12 @@ declare class GatewayProtocolClient<TPlan> {
|
|
|
163
170
|
private handleSocketError;
|
|
164
171
|
private scheduleReconnect;
|
|
165
172
|
private closeContext;
|
|
173
|
+
private isConnectCurrent;
|
|
174
|
+
private connectAuthority;
|
|
166
175
|
private isActive;
|
|
167
176
|
private nowMs;
|
|
168
177
|
private clearHandshakeTimer;
|
|
169
178
|
private invoke;
|
|
170
179
|
}
|
|
171
180
|
//#endregion
|
|
172
|
-
export {
|
|
181
|
+
export { GatewayProtocolSocketHandlers as a, GatewayProtocolSocket as i, GatewayProtocolCloseContext as n, GatewayProtocolTiming as o, GatewayProtocolConnectAuthority as r, GatewayProtocolRequestTiming as s, GatewayProtocolClient as t };
|
|
@@ -5,7 +5,7 @@ declare function isGatewayProtocolResponseError(error: unknown): error is Gatewa
|
|
|
5
5
|
type GatewayProtocolRequestOptions = {
|
|
6
6
|
timeoutMs?: number | null;
|
|
7
7
|
expectFinal?: boolean;
|
|
8
|
-
onSent?: () => void;
|
|
8
|
+
onSent?: (requestId: string) => void;
|
|
9
9
|
onAccepted?: (payload: unknown) => void;
|
|
10
10
|
signal?: AbortSignal;
|
|
11
11
|
};
|