@twinsearth/dsh-2xray 0.2.0 → 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/CHANGELOG.md +7 -0
- package/index.js +1 -0
- package/lib/client.js +8 -6
- package/lib/schema.js +21 -10
- package/lib/supervisor.js +4 -0
- package/package.json +1 -1
- package/test/client.test.js +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1 — 2026-10-29
|
|
4
|
+
|
|
5
|
+
### 修复
|
|
6
|
+
|
|
7
|
+
- **设置页仍不显示**:Schemastery 改为优先通过 `createRequire(import.meta.url)` / profile 锚点解析文件后动态 import,绕开宿主模块加载器对裸 specifier 的受限解析;加载结果写入 `xray_status.settingsSchema`,可远程确认表单是否具备渲染条件。
|
|
8
|
+
- **侧边栏入口优先注册**:先注册 `sidebar.panellist`,再注册主面板;主面板失败不再连带隐藏入口。
|
|
9
|
+
|
|
3
10
|
## 0.2.0 — 2026-10-29
|
|
4
11
|
|
|
5
12
|
### 新增
|
package/index.js
CHANGED
package/lib/client.js
CHANGED
|
@@ -246,19 +246,21 @@ window.__ModuleLoader__.load({
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
function apply(ctx) {
|
|
249
|
+
// Register the sidebar entry first: a failure in the main-panel
|
|
250
|
+
// registration must not hide the entry.
|
|
249
251
|
ctx.effect(
|
|
250
252
|
() =>
|
|
251
|
-
ctx.slots.inject('
|
|
252
|
-
ctx.slots.register({ name: '
|
|
253
|
+
ctx.slots.inject('sidebar.panellist', () =>
|
|
254
|
+
ctx.slots.register({ name: 'sidebar.panellist', id: PANEL_ID, order: 1, label: () => '2Xray' }, GlobeIcon),
|
|
253
255
|
),
|
|
254
|
-
'dsh-2xray:
|
|
256
|
+
'dsh-2xray: sidebar entry',
|
|
255
257
|
)
|
|
256
258
|
ctx.effect(
|
|
257
259
|
() =>
|
|
258
|
-
ctx.slots.inject('
|
|
259
|
-
ctx.slots.register({ name: '
|
|
260
|
+
ctx.slots.inject('main', () =>
|
|
261
|
+
ctx.slots.register({ name: 'main', key: PANEL_ID }, XrayPage),
|
|
260
262
|
),
|
|
261
|
-
'dsh-2xray:
|
|
263
|
+
'dsh-2xray: main panel',
|
|
262
264
|
)
|
|
263
265
|
}
|
|
264
266
|
|
package/lib/schema.js
CHANGED
|
@@ -19,11 +19,6 @@ import { join } from 'node:path'
|
|
|
19
19
|
import { pathToFileURL } from 'node:url'
|
|
20
20
|
|
|
21
21
|
async function loadSchema() {
|
|
22
|
-
try {
|
|
23
|
-
return (await import('@deepseek-ai/schemastery')).default
|
|
24
|
-
} catch {
|
|
25
|
-
// local checkout / test: borrow the profile's copy
|
|
26
|
-
}
|
|
27
22
|
const home = process.env.USERPROFILE ?? process.env.HOME
|
|
28
23
|
const anchors = home
|
|
29
24
|
? [
|
|
@@ -31,13 +26,29 @@ async function loadSchema() {
|
|
|
31
26
|
join(home, '.dsh', 'profiles', 'web', 'package.json'),
|
|
32
27
|
]
|
|
33
28
|
: []
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
|
|
30
|
+
// Prefer Node's own resolver: a bare `import()` inside a plugin may be served
|
|
31
|
+
// by the harness module loader, whose table does not necessarily contain a
|
|
32
|
+
// peer package such as Schemastery even though it sits in node_modules.
|
|
33
|
+
const attempts = [
|
|
34
|
+
() => {
|
|
35
|
+
const file = createRequire(import.meta.url).resolve('@deepseek-ai/schemastery')
|
|
36
|
+
return import(pathToFileURL(file).href)
|
|
37
|
+
},
|
|
38
|
+
...anchors.map((anchor) => () => {
|
|
36
39
|
const file = createRequire(anchor).resolve('@deepseek-ai/schemastery')
|
|
37
|
-
|
|
38
|
-
|
|
40
|
+
return import(pathToFileURL(file).href)
|
|
41
|
+
}),
|
|
42
|
+
() => import('@deepseek-ai/schemastery'),
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
for (const attempt of attempts) {
|
|
46
|
+
try {
|
|
47
|
+
const module = await attempt()
|
|
48
|
+
const candidate = module?.default ?? module
|
|
49
|
+
if (typeof candidate === 'function' && typeof candidate.object === 'function') return candidate
|
|
39
50
|
} catch {
|
|
40
|
-
// try the next
|
|
51
|
+
// try the next resolution route
|
|
41
52
|
}
|
|
42
53
|
}
|
|
43
54
|
throw new Error('@deepseek-ai/schemastery is not resolvable')
|
package/lib/supervisor.js
CHANGED
|
@@ -86,6 +86,7 @@ export class Supervisor {
|
|
|
86
86
|
#resolveBinaryFn
|
|
87
87
|
#control
|
|
88
88
|
#activeNode
|
|
89
|
+
#schemaLoaded = false
|
|
89
90
|
#now
|
|
90
91
|
|
|
91
92
|
constructor({
|
|
@@ -100,6 +101,7 @@ export class Supervisor {
|
|
|
100
101
|
probes = {},
|
|
101
102
|
resolveBinaryFn = resolveBinary,
|
|
102
103
|
control,
|
|
104
|
+
schemaLoaded = false,
|
|
103
105
|
now = () => Date.now(),
|
|
104
106
|
}) {
|
|
105
107
|
this.config = config
|
|
@@ -108,6 +110,7 @@ export class Supervisor {
|
|
|
108
110
|
this.#launcher = launcher
|
|
109
111
|
this.#route = route
|
|
110
112
|
this.#control = control
|
|
113
|
+
this.#schemaLoaded = schemaLoaded
|
|
111
114
|
this.#activeNode = config.activeNode
|
|
112
115
|
this.#logger = logger
|
|
113
116
|
this.dataDir = dataDir
|
|
@@ -646,6 +649,7 @@ export class Supervisor {
|
|
|
646
649
|
detail: this.#detail ?? null,
|
|
647
650
|
enabled: this.config.enabled,
|
|
648
651
|
takeover: this.config.takeover,
|
|
652
|
+
settingsSchema: this.#schemaLoaded,
|
|
649
653
|
nodes: this.config.nodes.map((node) => ({ id: node.id, tag: node.tag, address: node.address, port: node.port })),
|
|
650
654
|
activeNode: this.#activeNode,
|
|
651
655
|
control: this.#control ? { enabled: true, ...this.#control.snapshot() } : { enabled: false },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twinsearth/dsh-2xray",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "DSH-2Xray: supervises xray-core and routes DSH process-wide HTTP(S) traffic through its local inbound, with optional multi-node gRPC control plane",
|
|
6
6
|
"type": "module",
|
package/test/client.test.js
CHANGED
|
@@ -45,12 +45,12 @@ test('the client bundle registers a main panel and a sidebar entry', async () =>
|
|
|
45
45
|
|
|
46
46
|
assert.deepEqual(
|
|
47
47
|
registrations.map((entry) => entry.definition.name),
|
|
48
|
-
['
|
|
48
|
+
['sidebar.panellist', 'main'],
|
|
49
49
|
)
|
|
50
|
-
assert.equal(registrations[0].definition.
|
|
51
|
-
assert.equal(registrations[
|
|
52
|
-
assert.equal(registrations[
|
|
53
|
-
|
|
54
|
-
const icon = registrations[1].component()
|
|
50
|
+
assert.equal(registrations[0].definition.id, 'xray')
|
|
51
|
+
assert.equal(registrations[0].definition.order, 1)
|
|
52
|
+
assert.equal(registrations[0].definition.label(), '2Xray')
|
|
53
|
+
const icon = registrations[0].component()
|
|
55
54
|
assert.equal(icon.type, 'svg')
|
|
55
|
+
assert.equal(registrations[1].definition.key, 'xray')
|
|
56
56
|
})
|