@linxin666/dsh-remote-web-ui 0.1.20 → 0.2.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/README.i18n.yaml +2 -2
- package/README.md +56 -26
- package/README.zh.md +20 -15
- package/assets/mobile-icon-192.png +0 -0
- package/assets/mobile-icon-512.png +0 -0
- package/assets/mobile-service-worker.js +64 -0
- package/lib/client.js +272 -47
- package/lib/client.js.map +1 -1
- package/lib/index.js +316 -60
- package/lib/mobile.js +487 -56
- package/lib/mobile.js.map +1 -1
- package/lib/types/client/PluginSettingsCard.d.ts +28 -0
- package/lib/types/client/PluginSettingsCard.d.ts.map +1 -1
- package/lib/types/client/PluginSettingsCard.js +147 -6
- package/lib/types/client/RemoteEntry.d.ts.map +1 -1
- package/lib/types/client/RemoteEntry.js +13 -2
- package/lib/types/client/RemoteSettingsCard.d.ts +2 -2
- package/lib/types/client/RemoteSettingsCard.d.ts.map +1 -1
- package/lib/types/client/RemoteSettingsCard.js +1 -1
- package/lib/types/client/UpdateEntry.d.ts.map +1 -1
- package/lib/types/client/UpdateEntry.js +36 -3
- package/lib/types/client/UpdatePanel.d.ts.map +1 -1
- package/lib/types/client/UpdatePanel.js +2 -2
- package/lib/types/client/deep-link.js +1 -1
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +4 -0
- package/lib/types/gate.d.ts +9 -0
- package/lib/types/gate.d.ts.map +1 -1
- package/lib/types/gate.js +17 -4
- package/lib/types/index.d.ts +25 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +30 -13
- package/lib/types/mobile/PairRequiredView.d.ts +7 -0
- package/lib/types/mobile/PairRequiredView.d.ts.map +1 -0
- package/lib/types/mobile/PairRequiredView.js +28 -0
- package/lib/types/mobile/PairRequiredView.test.d.ts +2 -0
- package/lib/types/mobile/PairRequiredView.test.d.ts.map +1 -0
- package/lib/types/mobile/PairRequiredView.test.js +24 -0
- package/lib/types/mobile/api.d.ts +10 -0
- package/lib/types/mobile/api.d.ts.map +1 -1
- package/lib/types/mobile/api.js +4 -0
- package/lib/types/mobile/index.js +14 -1
- package/lib/types/mobile/messages.d.ts +24 -0
- package/lib/types/mobile/messages.d.ts.map +1 -1
- package/lib/types/mobile/messages.js +60 -23
- package/lib/types/mobile/messages.test.js +49 -1
- package/lib/types/mobile/mobile-styles.d.ts +1 -1
- package/lib/types/mobile/mobile-styles.d.ts.map +1 -1
- package/lib/types/mobile/mobile-styles.js +86 -0
- package/lib/types/mobile/pairing.d.ts +31 -0
- package/lib/types/mobile/pairing.d.ts.map +1 -0
- package/lib/types/mobile/pairing.js +62 -0
- package/lib/types/mobile/views/App.d.ts +12 -5
- package/lib/types/mobile/views/App.d.ts.map +1 -1
- package/lib/types/mobile/views/App.js +34 -7
- package/lib/types/mobile/views/App.test.d.ts +2 -0
- package/lib/types/mobile/views/App.test.d.ts.map +1 -0
- package/lib/types/mobile/views/App.test.js +52 -0
- package/lib/types/mobile/views/ChatView.d.ts.map +1 -1
- package/lib/types/mobile/views/ChatView.js +34 -11
- package/lib/types/mobile/views/SessionListView.d.ts.map +1 -1
- package/lib/types/mobile/views/SessionListView.js +30 -4
- package/lib/types/mobile/views/SessionListView.test.js +58 -1
- package/lib/types/mobile/views/WorkspaceView.d.ts.map +1 -1
- package/lib/types/mobile/views/WorkspaceView.js +4 -2
- package/lib/types/mobile-api.d.ts.map +1 -1
- package/lib/types/mobile-api.js +10 -1
- package/lib/types/mobile-pwa.d.ts +6 -0
- package/lib/types/mobile-pwa.d.ts.map +1 -0
- package/lib/types/mobile-pwa.js +17 -0
- package/lib/types/mobile-routes.d.ts +5 -8
- package/lib/types/mobile-routes.d.ts.map +1 -1
- package/lib/types/mobile-routes.js +115 -30
- package/lib/types/pairing-access.d.ts +28 -0
- package/lib/types/pairing-access.d.ts.map +1 -0
- package/lib/types/pairing-access.js +26 -0
- package/lib/types/pairing.d.ts +27 -0
- package/lib/types/pairing.d.ts.map +1 -1
- package/lib/types/pairing.js +68 -0
- package/lib/types/pairing.persist.test.d.ts +2 -0
- package/lib/types/pairing.persist.test.d.ts.map +1 -0
- package/lib/types/pairing.persist.test.js +128 -0
- package/lib/types/routes.d.ts.map +1 -1
- package/lib/types/routes.js +23 -3
- package/lib/types/tunnel.d.ts +1 -0
- package/lib/types/tunnel.d.ts.map +1 -1
- package/lib/types/tunnel.js +7 -2
- package/lib/types/update.d.ts +4 -4
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +35 -12
- package/package.json +12 -12
- package/src/client/PluginSettingsCard.tsx +229 -18
- package/src/client/RemoteEntry.tsx +12 -2
- package/src/client/RemoteSettingsCard.tsx +3 -2
- package/src/client/UpdateEntry.tsx +36 -4
- package/src/client/UpdatePanel.tsx +2 -0
- package/src/client/deep-link.ts +1 -1
- package/src/client/locales.ts +4 -0
- package/src/client/remote.module.css +26 -0
- package/src/client/settings-card.module.css +90 -1
- package/src/gate.ts +17 -3
- package/src/index.ts +46 -15
- package/src/mobile/PairRequiredView.test.tsx +28 -0
- package/src/mobile/PairRequiredView.tsx +58 -0
- package/src/mobile/api.ts +14 -1
- package/src/mobile/index.tsx +15 -1
- package/src/mobile/messages.test.ts +52 -1
- package/src/mobile/messages.ts +65 -22
- package/src/mobile/mobile-styles.ts +86 -0
- package/src/mobile/pairing.ts +77 -0
- package/src/mobile/views/App.test.tsx +62 -0
- package/src/mobile/views/App.tsx +53 -6
- package/src/mobile/views/ChatView.tsx +33 -10
- package/src/mobile/views/SessionListView.test.tsx +69 -1
- package/src/mobile/views/SessionListView.tsx +58 -5
- package/src/mobile/views/WorkspaceView.tsx +4 -2
- package/src/mobile-api.ts +9 -1
- package/src/mobile-pwa.ts +19 -0
- package/src/mobile-routes.ts +123 -30
- package/src/pairing-access.ts +36 -0
- package/src/pairing.persist.test.ts +145 -0
- package/src/pairing.ts +70 -1
- package/src/routes.ts +23 -3
- package/src/tunnel.ts +7 -2
- package/src/update.ts +42 -14
package/src/update.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Remote update support for the dsh-web-ui family — host half. Detects the
|
|
3
|
-
* installed aggregate package (@linxin666/dsh-web-ui-all)
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* installed aggregate package (@linxin666/dsh-web-ui-all), or the directly
|
|
4
|
+
* installed family packages when the aggregate is absent, probes npm for newer
|
|
5
|
+
* releases, and runs `pnpm update --latest` inside the owning dsh profile.
|
|
6
6
|
*
|
|
7
7
|
* Pure logic with injected seams (manifest reading, registry fetches, process
|
|
8
8
|
* spawning) so the whole surface is unit-testable without touching disk,
|
|
@@ -235,10 +235,13 @@ export function resolveUpdateTarget(
|
|
|
235
235
|
const profileManifest = readManifest(join(profile.dir, 'package.json'))
|
|
236
236
|
const spec = (profileManifest?.dependencies as Record<string, DependencySpec> | undefined)?.[anchor]
|
|
237
237
|
if (isLinkedSpec(spec)) return { error: 'link' }
|
|
238
|
+
// Standalone installs carry no aggregate: the anchor's own dependency
|
|
239
|
+
// list misses every sibling @linxin666/* plugin installed directly into
|
|
240
|
+
// the profile, so union the profile's direct family deps (#377).
|
|
238
241
|
return {
|
|
239
242
|
profileName: profile.name,
|
|
240
243
|
profileDir: profile.dir,
|
|
241
|
-
packages:
|
|
244
|
+
packages: familyUpdatePackages(anchor, manifest, profileManifest),
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
|
|
@@ -253,6 +256,21 @@ export function familyChildren(anchorManifest: Record<string, unknown>): string[
|
|
|
253
256
|
return names
|
|
254
257
|
}
|
|
255
258
|
|
|
259
|
+
/** Registry-managed family packages covered by one update operation. */
|
|
260
|
+
function familyUpdatePackages(
|
|
261
|
+
anchor: string,
|
|
262
|
+
anchorManifest: Record<string, unknown>,
|
|
263
|
+
profileManifest: Record<string, unknown> | undefined,
|
|
264
|
+
): string[] {
|
|
265
|
+
const names = new Set([anchor, ...familyChildren(anchorManifest)])
|
|
266
|
+
const dependencies = profileManifest?.dependencies
|
|
267
|
+
if (typeof dependencies !== 'object' || dependencies === null) return [...names]
|
|
268
|
+
for (const [name, spec] of Object.entries(dependencies)) {
|
|
269
|
+
if (name.startsWith(FAMILY_SCOPE) && typeof spec === 'string' && !isLinkedSpec(spec)) names.add(name)
|
|
270
|
+
}
|
|
271
|
+
return [...names]
|
|
272
|
+
}
|
|
273
|
+
|
|
256
274
|
/**
|
|
257
275
|
* Probe the npm registry for one package's latest release.
|
|
258
276
|
* @param name - the package name (scope slash URL-encoded).
|
|
@@ -262,14 +280,14 @@ export function familyChildren(anchorManifest: Record<string, unknown>): string[
|
|
|
262
280
|
*/
|
|
263
281
|
export async function fetchLatestVersion(
|
|
264
282
|
name: string,
|
|
265
|
-
fetchImpl: (url: string) => Promise<{ ok: boolean; json(): Promise<unknown> }>,
|
|
283
|
+
fetchImpl: (url: string, init?: RequestInit) => Promise<{ ok: boolean; json(): Promise<unknown> }>,
|
|
266
284
|
timeoutMs = 10_000,
|
|
267
285
|
): Promise<string | undefined> {
|
|
268
286
|
try {
|
|
269
287
|
const controller = new AbortController()
|
|
270
288
|
const timer = setTimeout(() => { controller.abort() }, timeoutMs)
|
|
271
289
|
try {
|
|
272
|
-
const response = await fetchImpl(NPM_REGISTRY + '/' + name.replace('/', '%2F') + '/latest')
|
|
290
|
+
const response = await fetchImpl(NPM_REGISTRY + '/' + name.replace('/', '%2F') + '/latest', { signal: controller.signal })
|
|
273
291
|
if (!response.ok) return undefined
|
|
274
292
|
const body = await response.json()
|
|
275
293
|
if (typeof body !== 'object' || body === null) return undefined
|
|
@@ -292,14 +310,21 @@ export async function fetchLatestVersion(
|
|
|
292
310
|
const VERSION_UNKNOWN = '0.0.0'
|
|
293
311
|
|
|
294
312
|
/** The resolved current version of one family package (probe failure tolerated). */
|
|
295
|
-
function readInstalledVersion(
|
|
313
|
+
function readInstalledVersion(
|
|
314
|
+
resolve: (specifier: string) => string | undefined,
|
|
315
|
+
name: string,
|
|
316
|
+
profileDir?: string,
|
|
317
|
+
): string {
|
|
296
318
|
try {
|
|
297
319
|
const path = resolve(name + '/package.json')
|
|
298
320
|
const version = path === undefined ? undefined : readManifest(path)?.version
|
|
299
|
-
|
|
300
|
-
} catch {
|
|
301
|
-
|
|
302
|
-
|
|
321
|
+
if (typeof version === 'string') return version
|
|
322
|
+
} catch { /* fall through to the profile's direct dependency path */ }
|
|
323
|
+
// Names originate in the profile dependency map, but still validate the
|
|
324
|
+
// npm package shape before using one as path segments.
|
|
325
|
+
if (profileDir === undefined || !/^@linxin666\/[a-z0-9][a-z0-9._-]*$/.test(name)) return VERSION_UNKNOWN
|
|
326
|
+
const version = readManifest(join(profileDir, 'node_modules', ...name.split('/'), 'package.json'))?.version
|
|
327
|
+
return typeof version === 'string' ? version : VERSION_UNKNOWN
|
|
303
328
|
}
|
|
304
329
|
|
|
305
330
|
/**
|
|
@@ -331,7 +356,10 @@ export async function checkUpdates(deps: UpdateCheckDeps): Promise<UpdateStatus>
|
|
|
331
356
|
if (profile === undefined) {
|
|
332
357
|
return { mode: 'link', packages: [], outdated: false }
|
|
333
358
|
}
|
|
334
|
-
|
|
359
|
+
// Union the profile's direct family deps so standalone installs (no
|
|
360
|
+
// aggregate) still check every installed @linxin666/* plugin (#377);
|
|
361
|
+
// familyUpdatePackages skips link:/file: development dependencies.
|
|
362
|
+
const names = familyUpdatePackages(anchor, manifest, profileManifest)
|
|
335
363
|
// The registry probes are independent: run them together instead of
|
|
336
364
|
// serializing up to N x 10s of registry latency behind one status call.
|
|
337
365
|
const latestList = await Promise.all(names.map(name => deps.fetchLatest(name)))
|
|
@@ -340,7 +368,7 @@ export async function checkUpdates(deps: UpdateCheckDeps): Promise<UpdateStatus>
|
|
|
340
368
|
names.forEach((name, index) => {
|
|
341
369
|
const latest = latestList[index]
|
|
342
370
|
if (latest === undefined) probeFailures++
|
|
343
|
-
const current = readInstalledVersion(deps.resolve, name)
|
|
371
|
+
const current = readInstalledVersion(deps.resolve, name, profile.dir)
|
|
344
372
|
packages.push({
|
|
345
373
|
name,
|
|
346
374
|
current,
|
|
@@ -604,7 +632,7 @@ export async function runUpdateVerified(deps: UpdateRunVerifiedDeps): Promise<Up
|
|
|
604
632
|
// green exit that left everything in place could be mistaken for success.
|
|
605
633
|
const before = new Map<string, string>()
|
|
606
634
|
for (const name of deps.run.packages) {
|
|
607
|
-
const version = readInstalledVersion(deps.check.resolve, name)
|
|
635
|
+
const version = readInstalledVersion(deps.check.resolve, name, deps.run.profileDir)
|
|
608
636
|
if (version !== VERSION_UNKNOWN) before.set(name, version)
|
|
609
637
|
}
|
|
610
638
|
const result = await runUpdate(deps.run)
|