@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
- `CLOSE_RULES` / `closeRule(code)` / `isTerminalClose(code)` (`src/close-policy.ts`): the one table
|
|
6
|
+
of what a dialer does after each close — `reconnect_now`, `reconnect`, `reauth` (one retry with a
|
|
7
|
+
fresh token; a second refusal before any welcome is terminal, outcome `signed_out`), or `stop`
|
|
8
|
+
with an `outcome` (`not_owned` 4003, `removed` 4004, `replaced` 4009, `revoked` 4010,
|
|
9
|
+
`upgrade_required` 4426). A CloseCode without a rule fails to compile; unknown codes reconnect.
|
|
10
|
+
- The client reads that table (its private terminal list is gone) and reports
|
|
11
|
+
`DesktopClientState.outcome` when it stops; 4001/4008 no longer redial forever.
|
|
12
|
+
|
|
13
|
+
Consumer action: never keep a local list of terminal close codes; branch on `closeRule(code)` and
|
|
14
|
+
show `state.outcome`.
|
|
15
|
+
|
|
3
16
|
## 0.6.0
|
|
4
17
|
|
|
5
18
|
- `RelayDeviceStatusEvent.since_ms` is `null` for a device that has never connected (protocol 1.1;
|
package/dist/client.cjs
CHANGED
|
@@ -311,6 +311,29 @@ var CloseCode = {
|
|
|
311
311
|
};
|
|
312
312
|
var CloseCodeValue = import_zod3.z.literal([1e3, 1001, 1006, 1012, 1013, 4001, 4003, 4004, 4008, 4009, 4010, 4400, 4426]);
|
|
313
313
|
|
|
314
|
+
// src/close-policy.ts
|
|
315
|
+
var CLOSE_RULES = {
|
|
316
|
+
[CloseCode.NORMAL]: { action: "reconnect", error: ["DEVICE_OFFLINE", "Connection closed"] },
|
|
317
|
+
[CloseCode.GOING_AWAY]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Connection lost"] },
|
|
318
|
+
[CloseCode.ABNORMAL]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Connection lost"] },
|
|
319
|
+
[CloseCode.DEVICE_RECONNECTED]: { action: "reconnect_now", error: ["DEVICE_OFFLINE", "Device reconnected"] },
|
|
320
|
+
[CloseCode.TRY_AGAIN_LATER]: { action: "reconnect", error: ["DEVICE_OFFLINE", "Relay busy; retrying"] },
|
|
321
|
+
[CloseCode.AUTH_INVALID]: { action: "reauth", outcome: "signed_out", error: ["AUTH_INVALID", "Sign-in was not accepted"] },
|
|
322
|
+
[CloseCode.AUTH_FORBIDDEN]: { action: "stop", outcome: "not_owned", error: ["AUTH_FORBIDDEN", "Not this device's owner"] },
|
|
323
|
+
[CloseCode.DEVICE_NOT_FOUND]: { action: "stop", outcome: "removed", error: ["NOT_FOUND", "Device not found"] },
|
|
324
|
+
[CloseCode.AUTH_EXPIRED]: { action: "reauth", outcome: "signed_out", error: ["AUTH_EXPIRED", "Sign-in expired"] },
|
|
325
|
+
[CloseCode.REPLACED]: { action: "stop", outcome: "replaced", error: ["CONFLICT", "Replaced by a newer connection"] },
|
|
326
|
+
[CloseCode.DEVICE_REVOKED]: { action: "stop", outcome: "revoked", error: ["AUTH_DEVICE_REVOKED", "This device was revoked"] },
|
|
327
|
+
// A malformed message, or a connection the relay lost track of: a fresh socket starts clean.
|
|
328
|
+
[CloseCode.PROTOCOL_ERROR]: { action: "reconnect", error: ["PROTOCOL_ERROR", "Connection reset by the relay"] },
|
|
329
|
+
[CloseCode.UPGRADE_REQUIRED]: { action: "stop", outcome: "upgrade_required", error: ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"] }
|
|
330
|
+
};
|
|
331
|
+
var UNKNOWN = { action: "reconnect", error: ["DEVICE_OFFLINE", "Connection lost"] };
|
|
332
|
+
function closeRule(code) {
|
|
333
|
+
if (code === null || code === void 0) return CLOSE_RULES[CloseCode.ABNORMAL];
|
|
334
|
+
return CLOSE_RULES[code] ?? UNKNOWN;
|
|
335
|
+
}
|
|
336
|
+
|
|
314
337
|
// src/schema/frame.ts
|
|
315
338
|
var import_zod4 = require("zod");
|
|
316
339
|
var FrameHeader = import_zod4.z.strictObject({
|
|
@@ -732,13 +755,6 @@ var EVENTS = {
|
|
|
732
755
|
|
|
733
756
|
// src/client/client.ts
|
|
734
757
|
var WS_OPEN = 1;
|
|
735
|
-
var TERMINAL_CLOSE = /* @__PURE__ */ new Map([
|
|
736
|
-
[CloseCode.DEVICE_REVOKED, ["AUTH_DEVICE_REVOKED", "This device was revoked"]],
|
|
737
|
-
[CloseCode.AUTH_FORBIDDEN, ["AUTH_FORBIDDEN", "Not this device's owner"]],
|
|
738
|
-
[CloseCode.DEVICE_NOT_FOUND, ["NOT_FOUND", "Device not found"]],
|
|
739
|
-
[CloseCode.REPLACED, ["CONFLICT", "Replaced by a newer connection"]],
|
|
740
|
-
[CloseCode.UPGRADE_REQUIRED, ["PROTOCOL_VERSION_UNSUPPORTED", "Protocol upgrade required"]]
|
|
741
|
-
]);
|
|
742
758
|
var defaultTimers = {
|
|
743
759
|
setTimeout: (fn, ms) => globalThis.setTimeout(fn, ms),
|
|
744
760
|
clearTimeout: (handle) => globalThis.clearTimeout(handle),
|
|
@@ -781,8 +797,10 @@ function createDesktopClient(options) {
|
|
|
781
797
|
attempts: 0,
|
|
782
798
|
retryInMs: null,
|
|
783
799
|
lastError: null,
|
|
784
|
-
lastCloseCode: null
|
|
800
|
+
lastCloseCode: null,
|
|
801
|
+
outcome: null
|
|
785
802
|
};
|
|
803
|
+
let authRefusals = 0;
|
|
786
804
|
const listeners = /* @__PURE__ */ new Set();
|
|
787
805
|
const readyWaiters = /* @__PURE__ */ new Set();
|
|
788
806
|
const pending = /* @__PURE__ */ new Map();
|
|
@@ -817,6 +835,7 @@ function createDesktopClient(options) {
|
|
|
817
835
|
}
|
|
818
836
|
function connect() {
|
|
819
837
|
if (state.status === "connecting" || state.status === "handshaking" || state.status === "open") return;
|
|
838
|
+
if (state.status === "closed" || state.status === "idle") authRefusals = 0;
|
|
820
839
|
closedByUser = false;
|
|
821
840
|
if (reconnectTimer !== null) {
|
|
822
841
|
timers.clearTimeout(reconnectTimer);
|
|
@@ -898,8 +917,11 @@ function createDesktopClient(options) {
|
|
|
898
917
|
timers.clearTimeout(probeTimer);
|
|
899
918
|
probeTimer = null;
|
|
900
919
|
}
|
|
901
|
-
const
|
|
902
|
-
|
|
920
|
+
const rule = code === null ? null : closeRule(code);
|
|
921
|
+
if (rule?.action === "reauth") authRefusals++;
|
|
922
|
+
const stopped = rule !== null && (rule.action === "stop" || rule.action === "reauth" && authRefusals >= 2);
|
|
923
|
+
const terminal = stopped && rule ? rule : void 0;
|
|
924
|
+
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 }));
|
|
903
925
|
for (const [id, p] of pending) {
|
|
904
926
|
pending.delete(id);
|
|
905
927
|
p.cleanup();
|
|
@@ -916,7 +938,14 @@ function createDesktopClient(options) {
|
|
|
916
938
|
endStream(s, null, lost);
|
|
917
939
|
}
|
|
918
940
|
if (closedByUser || terminal) {
|
|
919
|
-
setState({
|
|
941
|
+
setState({
|
|
942
|
+
status: "closed",
|
|
943
|
+
welcome: null,
|
|
944
|
+
lastError: closedByUser ? state.lastError : lost,
|
|
945
|
+
lastCloseCode: code,
|
|
946
|
+
retryInMs: null,
|
|
947
|
+
outcome: closedByUser ? null : terminal?.outcome ?? null
|
|
948
|
+
});
|
|
920
949
|
rejectReadyWaiters(lost);
|
|
921
950
|
return;
|
|
922
951
|
}
|
|
@@ -1070,7 +1099,8 @@ function createDesktopClient(options) {
|
|
|
1070
1099
|
}
|
|
1071
1100
|
helloId = null;
|
|
1072
1101
|
backoff.markConnected();
|
|
1073
|
-
|
|
1102
|
+
authRefusals = 0;
|
|
1103
|
+
setState({ status: "open", welcome: welcome.data, attempts: 0, retryInMs: null, lastError: null, outcome: null });
|
|
1074
1104
|
for (const w of [...readyWaiters]) {
|
|
1075
1105
|
readyWaiters.delete(w);
|
|
1076
1106
|
w.resolve(welcome.data);
|