@linxin666/dsh-remote-web-ui 0.2.6 → 0.2.8
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.i18n.yaml +2 -2
- package/README.md +8 -1
- package/README.zh.md +2 -1
- package/lib/client.js +55 -10
- package/lib/client.js.map +1 -1
- package/lib/index.js +12 -8
- package/lib/mobile.js +37 -18
- package/lib/mobile.js.map +1 -1
- package/lib/types/client/FenceNotice.d.ts +3 -2
- package/lib/types/client/FenceNotice.d.ts.map +1 -1
- package/lib/types/client/FooterRemoteEntry.js +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
- package/lib/types/client/RemoteEntry.js +8 -8
- package/lib/types/client/RemotePanel.js +3 -3
- package/lib/types/client/RemoteSettingsCard.d.ts.map +1 -1
- package/lib/types/client/RemoteSettingsCard.js +2 -2
- package/lib/types/client/UpdateEntry.d.ts.map +1 -1
- package/lib/types/client/UpdateEntry.js +2 -2
- package/lib/types/client/UpdatePanel.js +1 -1
- package/lib/types/client/deep-link.js +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +45 -23
- package/lib/types/client/pair-api.d.ts +6 -0
- package/lib/types/client/pair-api.d.ts.map +1 -1
- package/lib/types/client/pair-api.js +11 -0
- package/lib/types/client/remote-channel.d.ts +25 -0
- package/lib/types/client/remote-channel.d.ts.map +1 -1
- package/lib/types/client/remote-channel.js +24 -0
- package/lib/types/client/settings-form.d.ts.map +1 -1
- package/lib/types/client/update-api.d.ts.map +1 -1
- package/lib/types/gate.js +1 -1
- package/lib/types/index.js +15 -15
- package/lib/types/invariant.d.ts.map +1 -1
- package/lib/types/loopback-proxy.js +1 -1
- package/lib/types/mobile/PairRequiredView.js +1 -1
- package/lib/types/mobile/PairRequiredView.test.js +1 -1
- package/lib/types/mobile/api.js +1 -1
- package/lib/types/mobile/index.js +5 -5
- package/lib/types/mobile/markdown.test.js +1 -1
- package/lib/types/mobile/messages.d.ts.map +1 -1
- package/lib/types/mobile/messages.js +5 -3
- package/lib/types/mobile/messages.test.js +21 -1
- package/lib/types/mobile/mobile-theme.test.js +2 -2
- package/lib/types/mobile/mux.d.ts +7 -4
- package/lib/types/mobile/mux.d.ts.map +1 -1
- package/lib/types/mobile/mux.js +44 -16
- package/lib/types/mobile/mux.test.js +58 -1
- package/lib/types/mobile/rpc.d.ts.map +1 -1
- package/lib/types/mobile/theme-toggle.js +1 -1
- package/lib/types/mobile/views/App.js +7 -7
- package/lib/types/mobile/views/App.test.js +2 -2
- package/lib/types/mobile/views/ChatView.js +6 -6
- package/lib/types/mobile/views/ChatView.test.js +3 -3
- package/lib/types/mobile/views/SessionListView.js +3 -3
- package/lib/types/mobile/views/SessionListView.test.js +2 -2
- package/lib/types/mobile/views/WorkspaceView.js +3 -3
- package/lib/types/mobile/views/WorkspaceView.test.js +3 -3
- package/lib/types/mobile-api.d.ts +1 -1
- package/lib/types/mobile-api.d.ts.map +1 -1
- package/lib/types/mobile-api.js +2 -2
- package/lib/types/pairing-access.d.ts.map +1 -1
- package/lib/types/pairing.d.ts.map +1 -1
- package/lib/types/pairing.persist.test.js +2 -2
- package/lib/types/remote-api.js +6 -6
- package/lib/types/remote-methods.d.ts.map +1 -1
- package/lib/types/routes.d.ts +9 -7
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +8 -5
- package/lib/types/tunnel.d.ts.map +1 -1
- package/lib/types/update-routes.d.ts +2 -2
- package/lib/types/update-routes.d.ts.map +1 -1
- package/lib/types/update-routes.js +1 -1
- package/package.json +15 -12
- package/src/client/FenceNotice.tsx +3 -2
- package/src/client/RemoteEntry.tsx +3 -2
- package/src/client/UpdateEntry.tsx +1 -0
- package/src/client/index.ts +40 -15
- package/src/client/pair-api.ts +16 -0
- package/src/client/remote-channel.ts +42 -0
- package/src/index.ts +1 -1
- package/src/mobile/messages.test.ts +23 -0
- package/src/mobile/messages.ts +5 -3
- package/src/mobile/mux.test.ts +64 -0
- package/src/mobile/mux.ts +44 -17
- package/src/routes.ts +7 -2
package/lib/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import http, { request } from "node:http";
|
|
|
14
14
|
import { connect } from "node:net";
|
|
15
15
|
import { Tunnel, bin, install } from "cloudflared";
|
|
16
16
|
import { spawn } from "node:child_process";
|
|
17
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-settings@0.1.
|
|
17
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-settings@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-brand@0_02aaf429ec98c58247037e2222c17a8f/node_modules/@deepseek-ai/dsh-settings/lib/index.js
|
|
18
18
|
/**
|
|
19
19
|
* Structural secret redaction for settings values. `role('secret')` fields are
|
|
20
20
|
* removed from a value before it crosses a wire boundary; a sidecar records
|
|
@@ -975,7 +975,8 @@ var PairingEventsStream = class {
|
|
|
975
975
|
* @returns the exact routes to register on webServer.
|
|
976
976
|
*/
|
|
977
977
|
function makeRoutes(deps) {
|
|
978
|
-
const { service, lanAddresses } = deps;
|
|
978
|
+
const { service, lanAddresses, requirePairingForLan = true } = deps;
|
|
979
|
+
const pairingRequired = () => typeof requirePairingForLan === "function" ? requirePairingForLan() : requirePairingForLan;
|
|
979
980
|
const events = new PairingEventsStream(service);
|
|
980
981
|
/** Loopback-only fence: the desktop panel's control endpoints. */
|
|
981
982
|
const loopbackFence = (req) => isTrustedApiRequest(req, []);
|
|
@@ -1182,14 +1183,16 @@ function makeRoutes(deps) {
|
|
|
1182
1183
|
const paired = deviceId !== void 0 && service.hasDevice(deviceId);
|
|
1183
1184
|
const snapshot = service.snapshot();
|
|
1184
1185
|
const { devices: _devices, ...rest } = snapshot;
|
|
1186
|
+
const visible = paired ? rest : {
|
|
1187
|
+
phase: snapshot.phase,
|
|
1188
|
+
lanAvailable: snapshot.lanAvailable,
|
|
1189
|
+
lanAddresses: snapshot.lanAddresses
|
|
1190
|
+
};
|
|
1185
1191
|
writeJson(res, 200, {
|
|
1186
1192
|
ok: true,
|
|
1187
1193
|
paired,
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
lanAvailable: snapshot.lanAvailable,
|
|
1191
|
-
lanAddresses: snapshot.lanAddresses
|
|
1192
|
-
}
|
|
1194
|
+
requirePairingForLan: pairingRequired(),
|
|
1195
|
+
...visible
|
|
1193
1196
|
});
|
|
1194
1197
|
};
|
|
1195
1198
|
const handleEvents = (req, res) => {
|
|
@@ -3184,7 +3187,8 @@ function applyImpl(ctx, config) {
|
|
|
3184
3187
|
const routes = [
|
|
3185
3188
|
...makeRoutes({
|
|
3186
3189
|
service,
|
|
3187
|
-
lanAddresses
|
|
3190
|
+
lanAddresses,
|
|
3191
|
+
requirePairingForLan: () => resolve().requirePairingForLan
|
|
3188
3192
|
}),
|
|
3189
3193
|
...makeMobileRoutes(),
|
|
3190
3194
|
...apiProxy !== void 0 ? makeMobileApiRoutes({
|
package/lib/mobile.js
CHANGED
|
@@ -11962,7 +11962,7 @@ function superRefine(fn, params) {
|
|
|
11962
11962
|
return /* @__PURE__ */ _superRefine(fn, params);
|
|
11963
11963
|
}
|
|
11964
11964
|
//#endregion
|
|
11965
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.
|
|
11965
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.1-rc.2_73bb34f881f3291b26a2607af4c34648/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/types/api/rpc.schema.js
|
|
11966
11966
|
/**
|
|
11967
11967
|
* Message-layer zod schemas: the four wire full forms + error body +
|
|
11968
11968
|
* carrier receipt. The payload slot is unknown in the full-form schemas — business payloads
|
|
@@ -12271,7 +12271,7 @@ union([object({ accepted: literal(true) }), object({
|
|
|
12271
12271
|
reason: union([literal("not-pending"), literal("bad-response")])
|
|
12272
12272
|
})]);
|
|
12273
12273
|
//#endregion
|
|
12274
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.
|
|
12274
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.1-rc.2_73bb34f881f3291b26a2607af4c34648/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/types/api/session-search.js
|
|
12275
12275
|
/**
|
|
12276
12276
|
* Return the longest prefix containing at most `maximum` Unicode code points.
|
|
12277
12277
|
* @param value - text to bound.
|
|
@@ -12289,7 +12289,7 @@ function truncateUnicodeCodePoints(value, maximum) {
|
|
|
12289
12289
|
return value;
|
|
12290
12290
|
}
|
|
12291
12291
|
//#endregion
|
|
12292
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.
|
|
12292
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.1-rc.2_73bb34f881f3291b26a2607af4c34648/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/types/api/sessions.schema.js
|
|
12293
12293
|
/**
|
|
12294
12294
|
* sessions domain zod schemas (names derived from map keys: sessionListRequestSchema /
|
|
12295
12295
|
* sessionListValueSchema). SessionEvent passthrough = strict envelope (type/seq/time) + wide
|
|
@@ -12526,7 +12526,7 @@ object({ accepted: literal(true) });
|
|
|
12526
12526
|
object({ sessionId: sessionIdSchema });
|
|
12527
12527
|
object({ accepted: literal(true) });
|
|
12528
12528
|
//#endregion
|
|
12529
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.
|
|
12529
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.1-rc.2_73bb34f881f3291b26a2607af4c34648/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/types/api/approvals.schema.js
|
|
12530
12530
|
/**
|
|
12531
12531
|
* approvals domain zod schemas (respond is a client-response; the payload schema serves
|
|
12532
12532
|
* the /api/respond endpoint's second parse after routing via the pending table).
|
|
@@ -12560,7 +12560,7 @@ const taskViewSchema = object({
|
|
|
12560
12560
|
finishedAt: number().int().nonnegative().optional()
|
|
12561
12561
|
});
|
|
12562
12562
|
//#endregion
|
|
12563
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.
|
|
12563
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.1-rc.2_73bb34f881f3291b26a2607af4c34648/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/types/api/workspace.schema.js
|
|
12564
12564
|
/**
|
|
12565
12565
|
* workspace domain zod schemas (names derived from map keys). The
|
|
12566
12566
|
* WorkspaceId brand cast lives in sessions.schema (see the note there) and
|
|
@@ -12606,7 +12606,7 @@ object({ workspace: workspaceViewSchema });
|
|
|
12606
12606
|
object({ sessionId: sessionIdSchema });
|
|
12607
12607
|
object({ archivedSessionIds: array(sessionIdSchema) });
|
|
12608
12608
|
//#endregion
|
|
12609
|
-
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.
|
|
12609
|
+
//#region ../../node_modules/.pnpm/@deepseek-ai+dsh-host-apiproxy@0.1.1-rc.2_73bb34f881f3291b26a2607af4c34648/node_modules/@deepseek-ai/dsh-host-apiproxy/lib/types/api/events.schema.js
|
|
12610
12610
|
/**
|
|
12611
12611
|
* events domain zod schemas: MuxFrame / HostFrame unions (discriminatedUnion('type')).
|
|
12612
12612
|
* A frame is the payload slot of the ServerRequest full form; the SessionEvent inside
|
|
@@ -12770,6 +12770,8 @@ function browserSource(url) {
|
|
|
12770
12770
|
}
|
|
12771
12771
|
const DEFAULT_POLL_INTERVAL_MS = 3e3;
|
|
12772
12772
|
const DEFAULT_STALL_THRESHOLD_MS = 12e3;
|
|
12773
|
+
const LIVE_SSE_STALL_MULTIPLIER = 3;
|
|
12774
|
+
const MAX_POLL_BACKOFF_MS = 6e4;
|
|
12773
12775
|
/**
|
|
12774
12776
|
* Stall-check granularity: the single scheduler tick runs at least this
|
|
12775
12777
|
* often so fallback arms within a second of the stall threshold passing,
|
|
@@ -12800,8 +12802,8 @@ var MuxClient = class {
|
|
|
12800
12802
|
lastDataAt = 0;
|
|
12801
12803
|
/**
|
|
12802
12804
|
* Whether the SSE channel has ever delivered a frame in this stream (a
|
|
12803
|
-
* delivered frame proves the tunnel
|
|
12804
|
-
*
|
|
12805
|
+
* delivered frame proves the tunnel can forward SSE; sustained silence may
|
|
12806
|
+
* still mean a suspended mobile tunnel, so polling re-arms after 3 windows).
|
|
12805
12807
|
*/
|
|
12806
12808
|
sseAlive = false;
|
|
12807
12809
|
/** Per-session highest event seq already emitted, for poll dedup. */
|
|
@@ -12811,6 +12813,8 @@ var MuxClient = class {
|
|
|
12811
12813
|
polling = false;
|
|
12812
12814
|
/** Epoch ms of the next due poll while polling (kept on the same tick timer). */
|
|
12813
12815
|
nextPollAt = 0;
|
|
12816
|
+
/** Adaptive delay: productive polls reset it; empty/error polls add one base interval up to one minute. */
|
|
12817
|
+
pollDelayMs;
|
|
12814
12818
|
/**
|
|
12815
12819
|
* @param url - the mobile events endpoint (browser-relative).
|
|
12816
12820
|
* @param options - seams.
|
|
@@ -12820,6 +12824,7 @@ var MuxClient = class {
|
|
|
12820
12824
|
this.sourceFactory = options.sourceFactory ?? browserSource;
|
|
12821
12825
|
this.pollLatest = options.pollLatest ?? ((sessionId) => history(sessionId, void 0, DEFAULT_POLL_PAGE_SIZE));
|
|
12822
12826
|
this.pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
12827
|
+
this.pollDelayMs = this.pollIntervalMs;
|
|
12823
12828
|
this.stallThresholdMs = options.stallThresholdMs ?? DEFAULT_STALL_THRESHOLD_MS;
|
|
12824
12829
|
this.now = options.now ?? (() => Date.now());
|
|
12825
12830
|
}
|
|
@@ -12857,7 +12862,7 @@ var MuxClient = class {
|
|
|
12857
12862
|
this.stopPolling();
|
|
12858
12863
|
return;
|
|
12859
12864
|
}
|
|
12860
|
-
if (!this.polling && !this.stopped &&
|
|
12865
|
+
if (!this.polling && !this.stopped && this.isSseStalled()) this.startPolling();
|
|
12861
12866
|
}
|
|
12862
12867
|
connect() {
|
|
12863
12868
|
this.sseAlive = false;
|
|
@@ -12899,22 +12904,28 @@ var MuxClient = class {
|
|
|
12899
12904
|
if (this.observeSessionId === void 0) return;
|
|
12900
12905
|
if (this.polling) {
|
|
12901
12906
|
if (this.now() >= this.nextPollAt) {
|
|
12902
|
-
this.nextPollAt =
|
|
12907
|
+
this.nextPollAt = Number.POSITIVE_INFINITY;
|
|
12903
12908
|
this.pollTick();
|
|
12904
12909
|
}
|
|
12905
12910
|
return;
|
|
12906
12911
|
}
|
|
12907
|
-
if (this.
|
|
12908
|
-
|
|
12912
|
+
if (this.isSseStalled()) this.startPolling();
|
|
12913
|
+
}
|
|
12914
|
+
isSseStalled() {
|
|
12915
|
+
const windowMs = this.sseAlive ? this.stallThresholdMs * LIVE_SSE_STALL_MULTIPLIER : this.stallThresholdMs;
|
|
12916
|
+
return this.now() - this.lastDataAt > windowMs;
|
|
12909
12917
|
}
|
|
12910
12918
|
startPolling() {
|
|
12911
12919
|
if (this.polling || this.stopped) return;
|
|
12912
12920
|
this.polling = true;
|
|
12913
|
-
this.
|
|
12921
|
+
this.pollDelayMs = this.pollIntervalMs;
|
|
12922
|
+
this.nextPollAt = Number.POSITIVE_INFINITY;
|
|
12914
12923
|
this.pollTick();
|
|
12915
12924
|
}
|
|
12916
12925
|
stopPolling() {
|
|
12917
12926
|
this.polling = false;
|
|
12927
|
+
this.pollDelayMs = this.pollIntervalMs;
|
|
12928
|
+
this.nextPollAt = 0;
|
|
12918
12929
|
}
|
|
12919
12930
|
/**
|
|
12920
12931
|
* Fetch the latest history page for the observed session and re-emit any
|
|
@@ -12927,14 +12938,19 @@ var MuxClient = class {
|
|
|
12927
12938
|
this.stopPolling();
|
|
12928
12939
|
return;
|
|
12929
12940
|
}
|
|
12941
|
+
let emitted = 0;
|
|
12930
12942
|
try {
|
|
12931
12943
|
const page = await this.pollLatest(sessionId);
|
|
12932
12944
|
let maxSeq = this.pollWatermark.get(sessionId) ?? -1;
|
|
12933
|
-
|
|
12945
|
+
const ordered = [...page.events].sort((left, right) => {
|
|
12946
|
+
return (typeof left.event?.seq === "number" ? left.event.seq : -1) - (typeof right.event?.seq === "number" ? right.event.seq : -1);
|
|
12947
|
+
});
|
|
12948
|
+
for (const entry of ordered) {
|
|
12934
12949
|
const event = entry.event;
|
|
12935
12950
|
const seq = typeof event?.seq === "number" ? event.seq : -1;
|
|
12936
12951
|
if (seq <= maxSeq) continue;
|
|
12937
12952
|
maxSeq = seq;
|
|
12953
|
+
emitted += 1;
|
|
12938
12954
|
this.emit({
|
|
12939
12955
|
type: "session/event",
|
|
12940
12956
|
sessionId,
|
|
@@ -12942,7 +12958,11 @@ var MuxClient = class {
|
|
|
12942
12958
|
});
|
|
12943
12959
|
}
|
|
12944
12960
|
this.pollWatermark.set(sessionId, maxSeq);
|
|
12945
|
-
} catch {}
|
|
12961
|
+
} catch {} finally {
|
|
12962
|
+
if (emitted > 0) this.pollDelayMs = this.pollIntervalMs;
|
|
12963
|
+
else this.pollDelayMs = Math.min(MAX_POLL_BACKOFF_MS, this.pollDelayMs + this.pollIntervalMs);
|
|
12964
|
+
if (this.polling && this.observeSessionId === sessionId) this.nextPollAt = this.now() + this.pollDelayMs;
|
|
12965
|
+
}
|
|
12946
12966
|
}
|
|
12947
12967
|
handleMessage(data) {
|
|
12948
12968
|
if (typeof data !== "string" || data === "") return;
|
|
@@ -13405,7 +13425,6 @@ function applyTurnEnd(state, event) {
|
|
|
13405
13425
|
...message,
|
|
13406
13426
|
...wasPending ? { pending: false } : {},
|
|
13407
13427
|
...failed ? { failed: true } : {},
|
|
13408
|
-
seq: Math.max(message.seq, event.seq),
|
|
13409
13428
|
time: event.time
|
|
13410
13429
|
});
|
|
13411
13430
|
}
|
|
@@ -13474,12 +13493,12 @@ function snapshotOf(state) {
|
|
|
13474
13493
|
for (let index = 1; index < out.length; index += 1) {
|
|
13475
13494
|
const prev = out[index - 1];
|
|
13476
13495
|
const current = out[index];
|
|
13477
|
-
if (prev.seq > current.seq
|
|
13496
|
+
if (prev.seq > current.seq) {
|
|
13478
13497
|
ordered = false;
|
|
13479
13498
|
break;
|
|
13480
13499
|
}
|
|
13481
13500
|
}
|
|
13482
|
-
return ordered ? out : out.sort((a, b) => a.seq - b.seq
|
|
13501
|
+
return ordered ? out : out.sort((a, b) => a.seq - b.seq);
|
|
13483
13502
|
}
|
|
13484
13503
|
//#endregion
|
|
13485
13504
|
//#region src/mobile/markdown.ts
|