@ai-matrx/desktop-protocol 0.6.0 → 0.7.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/CHANGELOG.md +13 -0
- package/dist/client.cjs +42 -12
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +4 -2
- package/dist/client.d.ts +4 -2
- package/dist/client.js +42 -12
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +29 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/react.d.cts +19 -0
- package/dist/react.d.ts +19 -0
- package/dist/{registry-jTmq1CsI.d.cts → registry-Duc_VFN8.d.cts} +91 -1
- package/dist/{registry-jTmq1CsI.d.ts → registry-Duc_VFN8.d.ts} +91 -1
- package/package.json +1 -1
package/dist/client.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BackoffOptions } from '@ai-matrx/realtime';
|
|
2
2
|
export { RECONNECT_ALARM_ATTEMPTS } from '@ai-matrx/realtime';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { W as Welcome, D as DesktopProtocolError, O as OpName, a as OpParams, b as OpResult, c as OPS, S as StreamMeta, E as EndReason, d as EVENTS,
|
|
5
|
-
export { i as isDesktopProtocolError } from './registry-
|
|
4
|
+
import { W as Welcome, D as DesktopProtocolError, C as CloseOutcome, O as OpName, a as OpParams, b as OpResult, c as OPS, S as StreamMeta, E as EndReason, d as EVENTS, e as ClientType } from './registry-Duc_VFN8.cjs';
|
|
5
|
+
export { i as isDesktopProtocolError } from './registry-Duc_VFN8.cjs';
|
|
6
6
|
import { FrameHeader } from './frame.cjs';
|
|
7
7
|
|
|
8
8
|
/** The subset of the WHATWG WebSocket the client uses — browser, React Native, `ws` and Workers all fit. */
|
|
@@ -49,6 +49,8 @@ interface DesktopClientState {
|
|
|
49
49
|
retryInMs: number | null;
|
|
50
50
|
lastError: DesktopProtocolError | null;
|
|
51
51
|
lastCloseCode: number | null;
|
|
52
|
+
/** Why dialing stopped, when the far side refused us for good (CLOSE_RULES); null otherwise. */
|
|
53
|
+
outcome: CloseOutcome | null;
|
|
52
54
|
}
|
|
53
55
|
type DesktopClientDiagnostic = {
|
|
54
56
|
kind: "malformed_message";
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BackoffOptions } from '@ai-matrx/realtime';
|
|
2
2
|
export { RECONNECT_ALARM_ATTEMPTS } from '@ai-matrx/realtime';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { W as Welcome, D as DesktopProtocolError, O as OpName, a as OpParams, b as OpResult, c as OPS, S as StreamMeta, E as EndReason, d as EVENTS,
|
|
5
|
-
export { i as isDesktopProtocolError } from './registry-
|
|
4
|
+
import { W as Welcome, D as DesktopProtocolError, C as CloseOutcome, O as OpName, a as OpParams, b as OpResult, c as OPS, S as StreamMeta, E as EndReason, d as EVENTS, e as ClientType } from './registry-Duc_VFN8.js';
|
|
5
|
+
export { i as isDesktopProtocolError } from './registry-Duc_VFN8.js';
|
|
6
6
|
import { FrameHeader } from './frame.js';
|
|
7
7
|
|
|
8
8
|
/** The subset of the WHATWG WebSocket the client uses — browser, React Native, `ws` and Workers all fit. */
|
|
@@ -49,6 +49,8 @@ interface DesktopClientState {
|
|
|
49
49
|
retryInMs: number | null;
|
|
50
50
|
lastError: DesktopProtocolError | null;
|
|
51
51
|
lastCloseCode: number | null;
|
|
52
|
+
/** Why dialing stopped, when the far side refused us for good (CLOSE_RULES); null otherwise. */
|
|
53
|
+
outcome: CloseOutcome | null;
|
|
52
54
|
}
|
|
53
55
|
type DesktopClientDiagnostic = {
|
|
54
56
|
kind: "malformed_message";
|
package/dist/client.js
CHANGED
|
@@ -281,6 +281,29 @@ var CloseCode = {
|
|
|
281
281
|
};
|
|
282
282
|
var CloseCodeValue = z3.literal([1e3, 1001, 1006, 1012, 1013, 4001, 4003, 4004, 4008, 4009, 4010, 4400, 4426]);
|
|
283
283
|
|
|
284
|
+
// src/close-policy.ts
|
|
285
|
+
var CLOSE_RULES = {
|
|
286
|
+
[CloseCode.NORMAL]: { action: "reconnect", error: ["DEVICE_OFFLINE", "Connection closed"] },
|
|
287
|
+
[CloseCode.GOING_AWAY]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Connection lost"] },
|
|
288
|
+
[CloseCode.ABNORMAL]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Connection lost"] },
|
|
289
|
+
[CloseCode.DEVICE_RECONNECTED]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Device reconnected"] },
|
|
290
|
+
[CloseCode.TRY_AGAIN_LATER]: { action: "reconnect", error: ["DEVICE_OFFLINE", "Relay busy; retrying"] },
|
|
291
|
+
[CloseCode.AUTH_INVALID]: { action: "reauth", outcome: "signed_out", error: ["AUTH_INVALID", "Sign-in was not accepted"] },
|
|
292
|
+
[CloseCode.AUTH_FORBIDDEN]: { action: "stop", outcome: "not_owned", error: ["AUTH_FORBIDDEN", "Not this device's owner"] },
|
|
293
|
+
[CloseCode.DEVICE_NOT_FOUND]: { action: "stop", outcome: "removed", error: ["NOT_FOUND", "Device not found"] },
|
|
294
|
+
[CloseCode.AUTH_EXPIRED]: { action: "reauth", outcome: "signed_out", error: ["AUTH_EXPIRED", "Sign-in expired"] },
|
|
295
|
+
[CloseCode.REPLACED]: { action: "stop", outcome: "replaced", error: ["CONFLICT", "Replaced by a newer connection"] },
|
|
296
|
+
[CloseCode.DEVICE_REVOKED]: { action: "stop", outcome: "revoked", error: ["AUTH_DEVICE_REVOKED", "This device was revoked"] },
|
|
297
|
+
// A malformed message, or a connection the relay lost track of: a fresh socket starts clean.
|
|
298
|
+
[CloseCode.PROTOCOL_ERROR]: { action: "reconnect", error: ["PROTOCOL_ERROR", "Connection reset by the relay"] },
|
|
299
|
+
[CloseCode.UPGRADE_REQUIRED]: { action: "stop", outcome: "upgrade_required", error: ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"] }
|
|
300
|
+
};
|
|
301
|
+
var UNKNOWN = { action: "reconnect", error: ["DEVICE_OFFLINE", "Connection lost"] };
|
|
302
|
+
function closeRule(code) {
|
|
303
|
+
if (code === null || code === void 0) return CLOSE_RULES[CloseCode.ABNORMAL];
|
|
304
|
+
return CLOSE_RULES[code] ?? UNKNOWN;
|
|
305
|
+
}
|
|
306
|
+
|
|
284
307
|
// src/schema/frame.ts
|
|
285
308
|
import { z as z4 } from "zod";
|
|
286
309
|
var FrameHeader = z4.strictObject({
|
|
@@ -702,13 +725,6 @@ var EVENTS = {
|
|
|
702
725
|
|
|
703
726
|
// src/client/client.ts
|
|
704
727
|
var WS_OPEN = 1;
|
|
705
|
-
var TERMINAL_CLOSE = /* @__PURE__ */ new Map([
|
|
706
|
-
[CloseCode.DEVICE_REVOKED, ["AUTH_DEVICE_REVOKED", "This device was revoked"]],
|
|
707
|
-
[CloseCode.AUTH_FORBIDDEN, ["AUTH_FORBIDDEN", "Not this device's owner"]],
|
|
708
|
-
[CloseCode.DEVICE_NOT_FOUND, ["NOT_FOUND", "Device not found"]],
|
|
709
|
-
[CloseCode.REPLACED, ["CONFLICT", "Replaced by a newer connection"]],
|
|
710
|
-
[CloseCode.UPGRADE_REQUIRED, ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"]]
|
|
711
|
-
]);
|
|
712
728
|
var defaultTimers = {
|
|
713
729
|
setTimeout: (fn, ms) => globalThis.setTimeout(fn, ms),
|
|
714
730
|
clearTimeout: (handle) => globalThis.clearTimeout(handle),
|
|
@@ -751,8 +767,10 @@ function createDesktopClient(options) {
|
|
|
751
767
|
attempts: 0,
|
|
752
768
|
retryInMs: null,
|
|
753
769
|
lastError: null,
|
|
754
|
-
lastCloseCode: null
|
|
770
|
+
lastCloseCode: null,
|
|
771
|
+
outcome: null
|
|
755
772
|
};
|
|
773
|
+
let authRefusals = 0;
|
|
756
774
|
const listeners = /* @__PURE__ */ new Set();
|
|
757
775
|
const readyWaiters = /* @__PURE__ */ new Set();
|
|
758
776
|
const pending = /* @__PURE__ */ new Map();
|
|
@@ -787,6 +805,7 @@ function createDesktopClient(options) {
|
|
|
787
805
|
}
|
|
788
806
|
function connect() {
|
|
789
807
|
if (state.status === "connecting" || state.status === "handshaking" || state.status === "open") return;
|
|
808
|
+
if (state.status === "closed" || state.status === "idle") authRefusals = 0;
|
|
790
809
|
closedByUser = false;
|
|
791
810
|
if (reconnectTimer !== null) {
|
|
792
811
|
timers.clearTimeout(reconnectTimer);
|
|
@@ -868,8 +887,11 @@ function createDesktopClient(options) {
|
|
|
868
887
|
timers.clearTimeout(probeTimer);
|
|
869
888
|
probeTimer = null;
|
|
870
889
|
}
|
|
871
|
-
const
|
|
872
|
-
|
|
890
|
+
const rule = code === null ? null : closeRule(code);
|
|
891
|
+
if (rule?.action === "reauth") authRefusals++;
|
|
892
|
+
const stopped = rule !== null && (rule.action === "stop" || rule.action === "reauth" && authRefusals >= 2);
|
|
893
|
+
const terminal = stopped && rule ? rule : void 0;
|
|
894
|
+
const lost = error ?? (terminal ? new DesktopProtocolError(terminal.error[0], terminal.error[1]) : rule && rule.action === "reauth" ? new DesktopProtocolError(rule.error[0], rule.error[1], { retryable: true }) : new DesktopProtocolError("DEVICE_OFFLINE", "Connection lost", { retryable: true }));
|
|
873
895
|
for (const [id, p] of pending) {
|
|
874
896
|
pending.delete(id);
|
|
875
897
|
p.cleanup();
|
|
@@ -886,7 +908,14 @@ function createDesktopClient(options) {
|
|
|
886
908
|
endStream(s, null, lost);
|
|
887
909
|
}
|
|
888
910
|
if (closedByUser || terminal) {
|
|
889
|
-
setState({
|
|
911
|
+
setState({
|
|
912
|
+
status: "closed",
|
|
913
|
+
welcome: null,
|
|
914
|
+
lastError: closedByUser ? state.lastError : lost,
|
|
915
|
+
lastCloseCode: code,
|
|
916
|
+
retryInMs: null,
|
|
917
|
+
outcome: closedByUser ? null : terminal?.outcome ?? null
|
|
918
|
+
});
|
|
890
919
|
rejectReadyWaiters(lost);
|
|
891
920
|
return;
|
|
892
921
|
}
|
|
@@ -1040,7 +1069,8 @@ function createDesktopClient(options) {
|
|
|
1040
1069
|
}
|
|
1041
1070
|
helloId = null;
|
|
1042
1071
|
backoff.markConnected();
|
|
1043
|
-
|
|
1072
|
+
authRefusals = 0;
|
|
1073
|
+
setState({ status: "open", welcome: welcome.data, attempts: 0, retryInMs: null, lastError: null, outcome: null });
|
|
1044
1074
|
for (const w of [...readyWaiters]) {
|
|
1045
1075
|
readyWaiters.delete(w);
|
|
1046
1076
|
w.resolve(welcome.data);
|