@huaqiu/dsh-eda-host 0.3.20 → 0.3.21
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/lib/index.d.mts +18 -4
- package/lib/index.mjs +23 -21
- package/package.json +2 -2
- package/src/client.ts +24 -1
- package/src/index.ts +28 -40
package/lib/index.d.mts
CHANGED
|
@@ -94,15 +94,29 @@ declare const inject: readonly ["tools"];
|
|
|
94
94
|
declare module '@deepseek-ai/cordis' {
|
|
95
95
|
interface Context {
|
|
96
96
|
edaHost: EdaHostClient;
|
|
97
|
+
/**
|
|
98
|
+
* Provided by the hq-edge `edge-bridge` plugin (the HOST). `baseUrl` is the
|
|
99
|
+
* loopback HQ Edge endpoint, e.g. "http://localhost:18080". We read it
|
|
100
|
+
* lazily so this plugin does not hard-depend on the bridge and still works
|
|
101
|
+
* in standalone DSH installs (where the service is absent).
|
|
102
|
+
*/
|
|
103
|
+
hqEdge?: {
|
|
104
|
+
baseUrl?: string;
|
|
105
|
+
};
|
|
97
106
|
}
|
|
98
107
|
}
|
|
99
108
|
/**
|
|
100
109
|
* Host plugin body — provide `edaHost` and register the three netlist tools.
|
|
101
110
|
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
111
|
+
* The HQ Edge endpoint is resolved **lazily at request time** (see
|
|
112
|
+
* `getHqEdgeBaseUrl`): the edge-bridge plugin provides `ctx.hqEdge.baseUrl`,
|
|
113
|
+
* which wins over the static `config.hqEdgeBaseUrl` / `HQ_EDGE_BASE_URL` env
|
|
114
|
+
* fallback. This matches how `@huaqiu/dsh-artifacts` and `@huaqiu/dsh-tool-
|
|
115
|
+
* symbol-footprint` reach hq-edge, and means the URL is correct even when this
|
|
116
|
+
* plugin is applied before the bridge. When no host URL is available at call
|
|
117
|
+
* time, the tools degrade to a clear FAILED_PRECONDITION instead of throwing at
|
|
118
|
+
* load time — so the plugin still installs in standalone DSH where hq-edge is
|
|
119
|
+
* absent.
|
|
106
120
|
*
|
|
107
121
|
* @param ctx - real cordis context (node side).
|
|
108
122
|
* @returns disposer — unregisters the tools on plugin dispose.
|
package/lib/index.mjs
CHANGED
|
@@ -51,7 +51,12 @@ function statusToKind(status) {
|
|
|
51
51
|
function createEdaHostClient(config, deps = {}) {
|
|
52
52
|
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
53
53
|
async function fetchScope(scope) {
|
|
54
|
-
const
|
|
54
|
+
const baseUrl = deps.baseUrlResolver?.()?.trim() ?? config.hqEdgeBaseUrl?.trim() ?? "";
|
|
55
|
+
if (baseUrl.length === 0) throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
56
|
+
const url = netlistUrlOf({
|
|
57
|
+
...config,
|
|
58
|
+
hqEdgeBaseUrl: baseUrl
|
|
59
|
+
}, scope);
|
|
55
60
|
let response;
|
|
56
61
|
try {
|
|
57
62
|
response = await fetchImpl(url, {
|
|
@@ -165,10 +170,15 @@ const log = getLogger("dsh-eda-host");
|
|
|
165
170
|
/**
|
|
166
171
|
* Host plugin body — provide `edaHost` and register the three netlist tools.
|
|
167
172
|
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
173
|
+
* The HQ Edge endpoint is resolved **lazily at request time** (see
|
|
174
|
+
* `getHqEdgeBaseUrl`): the edge-bridge plugin provides `ctx.hqEdge.baseUrl`,
|
|
175
|
+
* which wins over the static `config.hqEdgeBaseUrl` / `HQ_EDGE_BASE_URL` env
|
|
176
|
+
* fallback. This matches how `@huaqiu/dsh-artifacts` and `@huaqiu/dsh-tool-
|
|
177
|
+
* symbol-footprint` reach hq-edge, and means the URL is correct even when this
|
|
178
|
+
* plugin is applied before the bridge. When no host URL is available at call
|
|
179
|
+
* time, the tools degrade to a clear FAILED_PRECONDITION instead of throwing at
|
|
180
|
+
* load time — so the plugin still installs in standalone DSH where hq-edge is
|
|
181
|
+
* absent.
|
|
172
182
|
*
|
|
173
183
|
* @param ctx - real cordis context (node side).
|
|
174
184
|
* @returns disposer — unregisters the tools on plugin dispose.
|
|
@@ -176,31 +186,23 @@ const log = getLogger("dsh-eda-host");
|
|
|
176
186
|
function apply(ctx, config = {}) {
|
|
177
187
|
if (!ctx.tools || typeof ctx.tools.register !== "function") throw new Error("@huaqiu/dsh-eda-host requires the DSH `tools` service (ctx.tools.register).");
|
|
178
188
|
const resolved = resolveEdaHostConfig(config);
|
|
189
|
+
const getHqEdgeBaseUrl = () => {
|
|
190
|
+
const hq = ctx.hqEdge;
|
|
191
|
+
return hq?.baseUrl && hq.baseUrl.trim().length > 0 ? hq.baseUrl : void 0;
|
|
192
|
+
};
|
|
179
193
|
log.info("applying dsh-eda-host node half", {
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
hasConfigHost: hasHost(resolved),
|
|
195
|
+
hqEdgeBaseUrlFromConfig: resolved.hqEdgeBaseUrl ?? null,
|
|
182
196
|
netlistPathPrefix: resolved.netlistPathPrefix
|
|
183
197
|
});
|
|
184
|
-
|
|
185
|
-
if (hasHost(resolved)) client = createEdaHostClient(resolved);
|
|
186
|
-
else client = {
|
|
187
|
-
getProjectNetlist: async () => {
|
|
188
|
-
throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
189
|
-
},
|
|
190
|
-
getSelectionNetlist: async () => {
|
|
191
|
-
throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
192
|
-
},
|
|
193
|
-
getActivePageNetlist: async () => {
|
|
194
|
-
throw new NetlistError("FAILED_PRECONDITION", "eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — netlist tools require the hq-edge EDA host bridge.");
|
|
195
|
-
}
|
|
196
|
-
};
|
|
198
|
+
const client = createEdaHostClient(resolved, { baseUrlResolver: getHqEdgeBaseUrl });
|
|
197
199
|
ctx.effect(() => ctx.provide("edaHost", client));
|
|
198
200
|
const tools = createNetListTools({ client });
|
|
199
201
|
const disposers = [];
|
|
200
202
|
for (const tool of tools) disposers.push(ctx.tools.register(tool));
|
|
201
203
|
log.info("dsh-eda-host node half ready", {
|
|
202
204
|
tools: 3,
|
|
203
|
-
|
|
205
|
+
configHostMode: hasHost(resolved)
|
|
204
206
|
});
|
|
205
207
|
return () => {
|
|
206
208
|
for (const dispose of disposers) try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@huaqiu/dsh-eda-host",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.mjs",
|
|
6
6
|
"types": "./lib/index.d.mts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@deepseek-ai/dsh-tools": "^0.1.0-rc.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@huaqiu/dsh-plugin-log": "0.3.
|
|
25
|
+
"@huaqiu/dsh-plugin-log": "0.3.21"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
28
|
"lib",
|
package/src/client.ts
CHANGED
|
@@ -17,6 +17,16 @@ import {
|
|
|
17
17
|
|
|
18
18
|
export interface EdaHostClientDeps {
|
|
19
19
|
fetchImpl?: typeof fetch
|
|
20
|
+
/**
|
|
21
|
+
* Optional late-bound resolver for the HQ Edge base URL. When supplied it is
|
|
22
|
+
* consulted on EVERY request and takes priority over the static `config`
|
|
23
|
+
* value. This lets the node half read the endpoint from the `ctx.hqEdge`
|
|
24
|
+
* service the edge-bridge plugin provides — the same pattern `@huaqiu/
|
|
25
|
+
* dsh-artifacts` and `@huaqiu/dsh-tool-symbol-footprint` use — so the URL is
|
|
26
|
+
* picked up even if this plugin is applied before the bridge, and stays
|
|
27
|
+
* correct in standalone installs where no host is present.
|
|
28
|
+
*/
|
|
29
|
+
baseUrlResolver?: () => string | undefined
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
export interface EdaHostClient {
|
|
@@ -43,7 +53,20 @@ export function createEdaHostClient(
|
|
|
43
53
|
const fetchImpl = deps.fetchImpl ?? globalThis.fetch
|
|
44
54
|
|
|
45
55
|
async function fetchScope(scope: NetlistScope): Promise<SchematicNetlist> {
|
|
46
|
-
|
|
56
|
+
// Resolve the host endpoint per request. A resolver (ctx.hqEdge) wins over
|
|
57
|
+
// the static config/env value; if neither yields a URL we degrade to the
|
|
58
|
+
// same clear FAILED_PRECONDITION the standalone install path uses.
|
|
59
|
+
const baseUrl = deps.baseUrlResolver?.()?.trim()
|
|
60
|
+
?? config.hqEdgeBaseUrl?.trim()
|
|
61
|
+
?? ''
|
|
62
|
+
if (baseUrl.length === 0) {
|
|
63
|
+
throw new NetlistError(
|
|
64
|
+
'FAILED_PRECONDITION',
|
|
65
|
+
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
66
|
+
'netlist tools require the hq-edge EDA host bridge.',
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
const url = netlistUrlOf({ ...config, hqEdgeBaseUrl: baseUrl }, scope)
|
|
47
70
|
|
|
48
71
|
let response: Response
|
|
49
72
|
try {
|
package/src/index.ts
CHANGED
|
@@ -24,7 +24,6 @@ import { getLogger } from '@huaqiu/dsh-plugin-log'
|
|
|
24
24
|
import { createEdaHostClient, type EdaHostClient } from './client.js'
|
|
25
25
|
import { hasHost, resolveEdaHostConfig, type EdaHostConfig } from './config.js'
|
|
26
26
|
import { createNetListTools } from './tools.js'
|
|
27
|
-
import { NetlistError } from './types.js'
|
|
28
27
|
|
|
29
28
|
/** Plugin id — matches package.json. */
|
|
30
29
|
export const name = '@huaqiu/dsh-eda-host'
|
|
@@ -48,6 +47,13 @@ export { NetlistError } from './types.js'
|
|
|
48
47
|
declare module '@deepseek-ai/cordis' {
|
|
49
48
|
interface Context {
|
|
50
49
|
edaHost: EdaHostClient
|
|
50
|
+
/**
|
|
51
|
+
* Provided by the hq-edge `edge-bridge` plugin (the HOST). `baseUrl` is the
|
|
52
|
+
* loopback HQ Edge endpoint, e.g. "http://localhost:18080". We read it
|
|
53
|
+
* lazily so this plugin does not hard-depend on the bridge and still works
|
|
54
|
+
* in standalone DSH installs (where the service is absent).
|
|
55
|
+
*/
|
|
56
|
+
hqEdge?: { baseUrl?: string }
|
|
51
57
|
}
|
|
52
58
|
}
|
|
53
59
|
|
|
@@ -58,10 +64,15 @@ const log = getLogger(COMPONENT)
|
|
|
58
64
|
/**
|
|
59
65
|
* Host plugin body — provide `edaHost` and register the three netlist tools.
|
|
60
66
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
67
|
+
* The HQ Edge endpoint is resolved **lazily at request time** (see
|
|
68
|
+
* `getHqEdgeBaseUrl`): the edge-bridge plugin provides `ctx.hqEdge.baseUrl`,
|
|
69
|
+
* which wins over the static `config.hqEdgeBaseUrl` / `HQ_EDGE_BASE_URL` env
|
|
70
|
+
* fallback. This matches how `@huaqiu/dsh-artifacts` and `@huaqiu/dsh-tool-
|
|
71
|
+
* symbol-footprint` reach hq-edge, and means the URL is correct even when this
|
|
72
|
+
* plugin is applied before the bridge. When no host URL is available at call
|
|
73
|
+
* time, the tools degrade to a clear FAILED_PRECONDITION instead of throwing at
|
|
74
|
+
* load time — so the plugin still installs in standalone DSH where hq-edge is
|
|
75
|
+
* absent.
|
|
65
76
|
*
|
|
66
77
|
* @param ctx - real cordis context (node side).
|
|
67
78
|
* @returns disposer — unregisters the tools on plugin dispose.
|
|
@@ -74,44 +85,21 @@ export function apply(ctx: Context, config: Partial<EdaHostConfig> = {}): () =>
|
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
const resolved = resolveEdaHostConfig(config)
|
|
88
|
+
|
|
89
|
+
// Late-bound host endpoint: prefer the edge-bridge service, then the overlay
|
|
90
|
+
// config / env value. Consulted on every request (see client.ts).
|
|
91
|
+
const getHqEdgeBaseUrl = (): string | undefined => {
|
|
92
|
+
const hq = ctx.hqEdge
|
|
93
|
+
return hq?.baseUrl && hq.baseUrl.trim().length > 0 ? hq.baseUrl : undefined
|
|
94
|
+
}
|
|
95
|
+
|
|
77
96
|
log.info('applying dsh-eda-host node half', {
|
|
78
|
-
|
|
79
|
-
|
|
97
|
+
hasConfigHost: hasHost(resolved),
|
|
98
|
+
hqEdgeBaseUrlFromConfig: resolved.hqEdgeBaseUrl ?? null,
|
|
80
99
|
netlistPathPrefix: resolved.netlistPathPrefix,
|
|
81
100
|
})
|
|
82
101
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (hasHost(resolved)) {
|
|
86
|
-
client = createEdaHostClient(resolved)
|
|
87
|
-
} else {
|
|
88
|
-
// Standalone install (no hq-edge supervisor): every scope degrades to
|
|
89
|
-
// FAILED_PRECONDITION with a clear message.
|
|
90
|
-
const unavailable: EdaHostClient = {
|
|
91
|
-
getProjectNetlist: async () => {
|
|
92
|
-
throw new NetlistError(
|
|
93
|
-
'FAILED_PRECONDITION',
|
|
94
|
-
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
95
|
-
'netlist tools require the hq-edge EDA host bridge.',
|
|
96
|
-
)
|
|
97
|
-
},
|
|
98
|
-
getSelectionNetlist: async () => {
|
|
99
|
-
throw new NetlistError(
|
|
100
|
-
'FAILED_PRECONDITION',
|
|
101
|
-
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
102
|
-
'netlist tools require the hq-edge EDA host bridge.',
|
|
103
|
-
)
|
|
104
|
-
},
|
|
105
|
-
getActivePageNetlist: async () => {
|
|
106
|
-
throw new NetlistError(
|
|
107
|
-
'FAILED_PRECONDITION',
|
|
108
|
-
'eda-host: no hq-edge base URL configured (hqEdgeBaseUrl / HQ_EDGE_BASE_URL) — ' +
|
|
109
|
-
'netlist tools require the hq-edge EDA host bridge.',
|
|
110
|
-
)
|
|
111
|
-
},
|
|
112
|
-
}
|
|
113
|
-
client = unavailable
|
|
114
|
-
}
|
|
102
|
+
const client = createEdaHostClient(resolved, { baseUrlResolver: getHqEdgeBaseUrl })
|
|
115
103
|
|
|
116
104
|
ctx.effect(() => ctx.provide('edaHost', client))
|
|
117
105
|
|
|
@@ -121,7 +109,7 @@ export function apply(ctx: Context, config: Partial<EdaHostConfig> = {}): () =>
|
|
|
121
109
|
disposers.push(ctx.tools.register(tool))
|
|
122
110
|
}
|
|
123
111
|
|
|
124
|
-
log.info('dsh-eda-host node half ready', { tools: 3,
|
|
112
|
+
log.info('dsh-eda-host node half ready', { tools: 3, configHostMode: hasHost(resolved) })
|
|
125
113
|
|
|
126
114
|
return () => {
|
|
127
115
|
for (const dispose of disposers) {
|