@devframes/hub 0.9.0 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import { _ as DevframeCommandsHost, a as hubMessagesAdd, c as hubMessagesUpdate, d as hubTerminalsRestart, f as hubTerminalsTerminate, g as DevframeDocksHost, h as DevframeMessagesHost, i as hubDocksActivate, l as hubTerminalsRemove, m as DevframeTerminalsHost, n as builtinHubRpcDeclarations, o as hubMessagesClear, p as hubTerminalsWrite, r as hubCommandsExecute, s as hubMessagesRemove, t as createHubContext, u as hubTerminalsResize } from "../context-DzqMQ2mI.mjs";
1
+ import { _ as DevframeCommandsHost, a as hubMessagesAdd, c as hubMessagesUpdate, d as hubTerminalsRestart, f as hubTerminalsTerminate, g as DevframeDocksHost, h as DevframeMessagesHost, i as hubDocksActivate, l as hubTerminalsRemove, m as DevframeTerminalsHost, n as builtinHubRpcDeclarations, o as hubMessagesClear, p as hubTerminalsWrite, r as hubCommandsExecute, s as hubMessagesRemove, t as createHubContext, u as hubTerminalsResize } from "../context-90I4t0S3.mjs";
2
2
  import "ufo";
3
3
  import "pathe";
4
4
  import "node:process";
@@ -1753,9 +1753,11 @@ pp$8.parseForStatement = function(node) {
1753
1753
  };
1754
1754
  pp$8.parseForAfterInit = function(node, init, awaitAt) {
1755
1755
  if ((this.type === types$1._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && init.declarations.length === 1) {
1756
- if (this.options.ecmaVersion >= 9) if (this.type === types$1._in) {
1757
- if (awaitAt > -1) this.unexpected(awaitAt);
1758
- } else node.await = awaitAt > -1;
1756
+ if (this.options.ecmaVersion >= 9) {
1757
+ if (this.type === types$1._in) {
1758
+ if (awaitAt > -1) this.unexpected(awaitAt);
1759
+ } else node.await = awaitAt > -1;
1760
+ }
1759
1761
  return this.parseForIn(node, init);
1760
1762
  }
1761
1763
  if (awaitAt > -1) this.unexpected(awaitAt);
@@ -2036,13 +2038,17 @@ pp$8.parseClassElement = function(constructorAllowsSuper) {
2036
2038
  else keyName = "static";
2037
2039
  }
2038
2040
  node.static = isStatic;
2039
- if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) isAsync = true;
2040
- else keyName = "async";
2041
+ if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
2042
+ if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) isAsync = true;
2043
+ else keyName = "async";
2044
+ }
2041
2045
  if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) isGenerator = true;
2042
2046
  if (!keyName && !isAsync && !isGenerator) {
2043
2047
  var lastValue = this.value;
2044
- if (this.eatContextual("get") || this.eatContextual("set")) if (this.isClassElementNameStart()) kind = lastValue;
2045
- else keyName = lastValue;
2048
+ if (this.eatContextual("get") || this.eatContextual("set")) {
2049
+ if (this.isClassElementNameStart()) kind = lastValue;
2050
+ else keyName = lastValue;
2051
+ }
2046
2052
  }
2047
2053
  if (keyName) {
2048
2054
  node.computed = false;
@@ -2135,8 +2141,10 @@ pp$8.exitClassBody = function() {
2135
2141
  var parent = len === 0 ? null : this.privateNameStack[len - 1];
2136
2142
  for (var i = 0; i < used.length; ++i) {
2137
2143
  var id = used[i];
2138
- if (!hasOwn(declared, id.name)) if (parent) parent.used.push(id);
2139
- else this.raiseRecoverable(id.start, "Private field '#" + id.name + "' must be declared in an enclosing class");
2144
+ if (!hasOwn(declared, id.name)) {
2145
+ if (parent) parent.used.push(id);
2146
+ else this.raiseRecoverable(id.start, "Private field '#" + id.name + "' must be declared in an enclosing class");
2147
+ }
2140
2148
  }
2141
2149
  };
2142
2150
  function isPrivateNameConflicted(privateNameMap, element) {
@@ -2158,10 +2166,12 @@ function checkKeyName(node, name) {
2158
2166
  return !computed && (key.type === "Identifier" && key.name === name || key.type === "Literal" && key.value === name);
2159
2167
  }
2160
2168
  pp$8.parseExportAllDeclaration = function(node, exports) {
2161
- if (this.options.ecmaVersion >= 11) if (this.eatContextual("as")) {
2162
- node.exported = this.parseModuleExportName();
2163
- this.checkExport(exports, node.exported, this.lastTokStart);
2164
- } else node.exported = null;
2169
+ if (this.options.ecmaVersion >= 11) {
2170
+ if (this.eatContextual("as")) {
2171
+ node.exported = this.parseModuleExportName();
2172
+ this.checkExport(exports, node.exported, this.lastTokStart);
2173
+ } else node.exported = null;
2174
+ }
2165
2175
  this.expectContextual("from");
2166
2176
  if (this.type !== types$1.string) this.unexpected();
2167
2177
  node.source = this.parseExprAtom();
@@ -2679,9 +2689,11 @@ pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {
2679
2689
  var kind = prop.kind;
2680
2690
  if (this.options.ecmaVersion >= 6) {
2681
2691
  if (name === "__proto__" && kind === "init") {
2682
- if (propHash.proto) if (refDestructuringErrors) {
2683
- if (refDestructuringErrors.doubleProto < 0) refDestructuringErrors.doubleProto = key.start;
2684
- } else this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
2692
+ if (propHash.proto) {
2693
+ if (refDestructuringErrors) {
2694
+ if (refDestructuringErrors.doubleProto < 0) refDestructuringErrors.doubleProto = key.start;
2695
+ } else this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
2696
+ }
2685
2697
  propHash.proto = true;
2686
2698
  }
2687
2699
  return;
@@ -2712,8 +2724,10 @@ pp$5.parseExpression = function(forInit, refDestructuringErrors) {
2712
2724
  return expr;
2713
2725
  };
2714
2726
  pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
2715
- if (this.isContextual("yield")) if (this.inGenerator) return this.parseYield(forInit);
2716
- else this.exprAllowed = false;
2727
+ if (this.isContextual("yield")) {
2728
+ if (this.inGenerator) return this.parseYield(forInit);
2729
+ else this.exprAllowed = false;
2730
+ }
2717
2731
  var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;
2718
2732
  if (refDestructuringErrors) {
2719
2733
  oldParenAssign = refDestructuringErrors.parenthesizedAssign;
@@ -2829,9 +2843,10 @@ pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forIni
2829
2843
  expr = this.finishNode(node$1, "UpdateExpression");
2830
2844
  }
2831
2845
  }
2832
- if (!incDec && this.eat(types$1.starstar)) if (sawUnary) this.unexpected(this.lastTokStart);
2833
- else return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false);
2834
- else return expr;
2846
+ if (!incDec && this.eat(types$1.starstar)) {
2847
+ if (sawUnary) this.unexpected(this.lastTokStart);
2848
+ else return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false);
2849
+ } else return expr;
2835
2850
  };
2836
2851
  function isLocalVariableAccess(node) {
2837
2852
  return node.type === "Identifier" || node.type === "ParenthesizedExpression" && isLocalVariableAccess(node.expression);
@@ -3017,17 +3032,18 @@ pp$5.parseExprImport = function(forNew) {
3017
3032
  pp$5.parseDynamicImport = function(node) {
3018
3033
  this.next();
3019
3034
  node.source = this.parseMaybeAssign();
3020
- if (this.options.ecmaVersion >= 16) if (!this.eat(types$1.parenR)) {
3021
- this.expect(types$1.comma);
3022
- if (!this.afterTrailingComma(types$1.parenR)) {
3023
- node.options = this.parseMaybeAssign();
3024
- if (!this.eat(types$1.parenR)) {
3025
- this.expect(types$1.comma);
3026
- if (!this.afterTrailingComma(types$1.parenR)) this.unexpected();
3027
- }
3035
+ if (this.options.ecmaVersion >= 16) {
3036
+ if (!this.eat(types$1.parenR)) {
3037
+ this.expect(types$1.comma);
3038
+ if (!this.afterTrailingComma(types$1.parenR)) {
3039
+ node.options = this.parseMaybeAssign();
3040
+ if (!this.eat(types$1.parenR)) {
3041
+ this.expect(types$1.comma);
3042
+ if (!this.afterTrailingComma(types$1.parenR)) this.unexpected();
3043
+ }
3044
+ } else node.options = null;
3028
3045
  } else node.options = null;
3029
- } else node.options = null;
3030
- else if (!this.eat(types$1.parenR)) {
3046
+ } else if (!this.eat(types$1.parenR)) {
3031
3047
  var errorPos = this.start;
3032
3048
  if (this.eat(types$1.comma) && this.eat(types$1.parenR)) this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
3033
3049
  else this.unexpected(errorPos);
@@ -3260,12 +3276,14 @@ pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startP
3260
3276
  } else this.unexpected();
3261
3277
  };
3262
3278
  pp$5.parsePropertyName = function(prop) {
3263
- if (this.options.ecmaVersion >= 6) if (this.eat(types$1.bracketL)) {
3264
- prop.computed = true;
3265
- prop.key = this.parseMaybeAssign();
3266
- this.expect(types$1.bracketR);
3267
- return prop.key;
3268
- } else prop.computed = false;
3279
+ if (this.options.ecmaVersion >= 6) {
3280
+ if (this.eat(types$1.bracketL)) {
3281
+ prop.computed = true;
3282
+ prop.key = this.parseMaybeAssign();
3283
+ this.expect(types$1.bracketR);
3284
+ return prop.key;
3285
+ } else prop.computed = false;
3286
+ }
3269
3287
  return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never");
3270
3288
  };
3271
3289
  pp$5.initFunction = function(node) {
@@ -3400,8 +3418,10 @@ pp$5.parsePrivateIdent = function() {
3400
3418
  else this.unexpected();
3401
3419
  this.next();
3402
3420
  this.finishNode(node, "PrivateIdentifier");
3403
- if (this.options.checkPrivateFields) if (this.privateNameStack.length === 0) this.raise(node.start, "Private field '#" + node.name + "' must be declared in an enclosing class");
3404
- else this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
3421
+ if (this.options.checkPrivateFields) {
3422
+ if (this.privateNameStack.length === 0) this.raise(node.start, "Private field '#" + node.name + "' must be declared in an enclosing class");
3423
+ else this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
3424
+ }
3405
3425
  return node;
3406
3426
  };
3407
3427
  pp$5.parseYield = function(forInit) {
@@ -3936,9 +3956,11 @@ pp$1.regexp_groupSpecifier = function(state) {
3936
3956
  if (!this.regexp_eatGroupName(state)) state.raise("Invalid group");
3937
3957
  var trackDisjunction = this.options.ecmaVersion >= 16;
3938
3958
  var known = state.groupNames[state.lastStringValue];
3939
- if (known) if (trackDisjunction) {
3940
- for (var i = 0, list = known; i < list.length; i += 1) if (!list[i].separatedFrom(state.branchID)) state.raise("Duplicate capture group name");
3941
- } else state.raise("Duplicate capture group name");
3959
+ if (known) {
3960
+ if (trackDisjunction) {
3961
+ for (var i = 0, list = known; i < list.length; i += 1) if (!list[i].separatedFrom(state.branchID)) state.raise("Duplicate capture group name");
3962
+ } else state.raise("Duplicate capture group name");
3963
+ }
3942
3964
  if (trackDisjunction) (known || (state.groupNames[state.lastStringValue] = [])).push(state.branchID);
3943
3965
  else state.groupNames[state.lastStringValue] = true;
3944
3966
  }
@@ -4952,12 +4974,14 @@ pp.readTmplToken = function() {
4952
4974
  if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
4953
4975
  var ch = this.input.charCodeAt(this.pos);
4954
4976
  if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
4955
- if (this.pos === this.start && (this.type === types$1.template || this.type === types$1.invalidTemplate)) if (ch === 36) {
4956
- this.pos += 2;
4957
- return this.finishToken(types$1.dollarBraceL);
4958
- } else {
4959
- ++this.pos;
4960
- return this.finishToken(types$1.backQuote);
4977
+ if (this.pos === this.start && (this.type === types$1.template || this.type === types$1.invalidTemplate)) {
4978
+ if (ch === 36) {
4979
+ this.pos += 2;
4980
+ return this.finishToken(types$1.dollarBraceL);
4981
+ } else {
4982
+ ++this.pos;
4983
+ return this.finishToken(types$1.backQuote);
4984
+ }
4961
4985
  }
4962
4986
  out += this.input.slice(chunkStart, this.pos);
4963
4987
  return this.finishToken(types$1.template, out);
@@ -4974,9 +4998,7 @@ pp.readTmplToken = function() {
4974
4998
  case 10:
4975
4999
  out += "\n";
4976
5000
  break;
4977
- default:
4978
- out += String.fromCharCode(ch);
4979
- break;
5001
+ default: out += String.fromCharCode(ch);
4980
5002
  }
4981
5003
  if (this.options.locations) {
4982
5004
  ++this.curLine;
@@ -4999,7 +5021,6 @@ pp.readInvalidTemplateToken = function() {
4999
5021
  case "\u2029":
5000
5022
  ++this.curLine;
5001
5023
  this.lineStart = this.pos + 1;
5002
- break;
5003
5024
  }
5004
5025
  this.raise(this.start, "Unterminated template");
5005
5026
  };
@@ -5197,10 +5218,12 @@ codes.ERR_INVALID_ARG_TYPE = createError(
5197
5218
  message += `an instance of ${formatList(instances, "or")}`;
5198
5219
  if (other.length > 0) message += " or ";
5199
5220
  }
5200
- if (other.length > 0) if (other.length > 1) message += `one of ${formatList(other, "or")}`;
5201
- else {
5202
- if (other[0].toLowerCase() !== other[0]) message += "an ";
5203
- message += `${other[0]}`;
5221
+ if (other.length > 0) {
5222
+ if (other.length > 1) message += `one of ${formatList(other, "or")}`;
5223
+ else {
5224
+ if (other[0].toLowerCase() !== other[0]) message += "an ";
5225
+ message += `${other[0]}`;
5226
+ }
5204
5227
  }
5205
5228
  message += `. Received ${determineSpecificType(actual)}`;
5206
5229
  return message;
@@ -1,5 +1,5 @@
1
- import { i as InstallDevframeOptions, n as DevframeHubContext, t as CreateHubContextOptions } from "../context-D5TJIHwp.mjs";
2
- import { DEVFRAMES_HUB_BASE } from "../constants.mjs";
1
+ import { i as InstallDevframeOptions, n as DevframeHubContext, t as CreateHubContextOptions } from "../context-BVkxwz5k.mjs";
2
+ import { r as DEVFRAMES_HUB_BASE } from "../constants-CmESZCBq.mjs";
3
3
  import { DevframeInstanceRecord } from "devframe/internal";
4
4
  import { ConnectionMeta, DevframeDefinition, DevframeSseOptions, DevframeStorageScope, DevframeWsOptions, McpRouteOptions } from "devframe/types";
5
5
  import { DevframeAuthHandler } from "devframe/node/auth";
@@ -207,6 +207,19 @@ interface InitHubOptions {
207
207
  * (`id`, `name`, `basePath`, …).
208
208
  */
209
209
  register?: boolean | Partial<DevframeInstanceRecord>;
210
+ /**
211
+ * Advertise that this host runtime resolves **bare-specifier** client
212
+ * scripts (`ClientScriptEntry.importFrom` naming an npm module) — a URL
213
+ * template whose `{specifier}` token is replaced with the specifier,
214
+ * published as `ConnectionMeta.configs.dock.clientModuleResolution` and
215
+ * applied by every client-script loader. Declare it only when the host can
216
+ * actually serve npm modules to the browser — a Vite host passes
217
+ * `'/@id/{specifier}'` to route imports through its own module graph
218
+ * (`@devframes/vite/hub` does). Left undeclared, registering a
219
+ * bare-specifier client script warns `DF8111` — ship a self-contained
220
+ * bundle and pass its URL instead.
221
+ */
222
+ clientModuleResolution?: string;
210
223
  /** Working directory for the hub context. Default: `process.cwd()`. */
211
224
  cwd?: string;
212
225
  /** Override where persisted devframe state lives. */
@@ -1,5 +1,6 @@
1
- import { DEVFRAMES_HUB_BASE, DOCK_RENDERERS_STATE_KEY, normalizeHubBase } from "../constants.mjs";
2
- import { t as createHubContext, v as diagnostics } from "../context-DzqMQ2mI.mjs";
1
+ import { a as normalizeHubBase, i as DOCK_RENDERERS_STATE_KEY, r as DEVFRAMES_HUB_BASE } from "../constants-C2b2cACy.mjs";
2
+ import { a as resolveClientModuleSpecifier } from "../remote-url-Bgc7gtsP.mjs";
3
+ import { t as createHubContext, v as diagnostics } from "../context-90I4t0S3.mjs";
3
4
  import { joinURL, withTrailingSlash, withoutLeadingSlash } from "ufo";
4
5
  import { DEVFRAME_CONNECTION_META_FILENAME, DEVFRAME_DOCK_IMPORTS_FILENAME, DEVFRAME_MCP_ROUTE, DEVFRAME_WS_ROUTE } from "devframe/constants";
5
6
  import { createH3DevframeHost, createInstanceShell, resolveInstanceRegister } from "devframe/internal";
@@ -70,9 +71,11 @@ function resolveRendererRegistrations(registrations) {
70
71
  * import thunk per dock that carries a client script (`clientScript` on
71
72
  * iframe docks, `action`, `renderer`). External viewers import this module
72
73
  * from `<base>__client-imports.js` to load per-dock client code into the
73
- * host page; `importFrom` values must be URL paths the host serves.
74
+ * host page; `importFrom` values are URL paths the host serves, or bare npm
75
+ * specifiers resolved through the host's `clientModuleResolution` template.
74
76
  */
75
77
  function renderClientImportsModule(ctx) {
78
+ const template = ctx.staticConfig.dock?.clientModuleResolution;
76
79
  const entries = [];
77
80
  for (const [id, view] of ctx.docks.views) {
78
81
  const scripts = [];
@@ -81,7 +84,7 @@ function renderClientImportsModule(ctx) {
81
84
  if (anyView.action) scripts.push(anyView.action);
82
85
  if (anyView.renderer) scripts.push(anyView.renderer);
83
86
  if (scripts.length === 0) continue;
84
- const thunks = scripts.map((script) => `() => import(${JSON.stringify(script.importFrom)})`);
87
+ const thunks = scripts.map((script) => `() => import(${JSON.stringify(resolveClientModuleSpecifier(script.importFrom, { template }))})`);
85
88
  entries.push(` ${JSON.stringify(id)}: [${thunks.join(", ")}],`);
86
89
  }
87
90
  return `// Generated by @devframes/hub — dock client-script import map.\nexport const clientImports = {\n${entries.join("\n")}\n}\nexport default clientImports\n`;
@@ -163,6 +166,10 @@ function initHub(options) {
163
166
  ...options.rpcDeclarations ? { builtinRpcDeclarations: options.rpcDeclarations } : {}
164
167
  });
165
168
  }
169
+ if (options.clientModuleResolution) ctx.staticConfig.dock = {
170
+ ...ctx.staticConfig.dock,
171
+ clientModuleResolution: options.clientModuleResolution
172
+ };
166
173
  const devframes = await resolveDevframesInput(options.devframes ?? []);
167
174
  for (const { devframe: def, dock } of devframes) {
168
175
  if (RESERVED_HUB_PATHS.includes(def.id)) throw diagnostics.DF8000({ id: def.id });
@@ -180,6 +187,7 @@ function initHub(options) {
180
187
  }
181
188
  await options.configure?.(ctx);
182
189
  await options.ui?.setup?.(ctx);
190
+ await ctx.services.ready();
183
191
  if (rendererRegistrations.length > 0) {
184
192
  const manifest = {};
185
193
  for (const registration of rendererRegistrations) manifest[registration.type] = {
@@ -1,4 +1,49 @@
1
1
  import { REMOTE_CONNECTION_KEY } from "devframe/constants";
2
+ //#region src/client-modules.ts
3
+ const URL_SCHEME_RE = /^[a-z][a-z\d+.-]*:/i;
4
+ /**
5
+ * Whether a client-script `importFrom` is a **bare module specifier** — an
6
+ * npm-style name (`vite-plugin-vue-tracer/client/vite-devtools`) rather than
7
+ * a URL the browser can resolve natively.
8
+ */
9
+ function isBareModuleSpecifier(specifier) {
10
+ const value = specifier.trim();
11
+ return !!value && !value.startsWith("/") && !value.startsWith("./") && !value.startsWith("../") && !URL_SCHEME_RE.test(value);
12
+ }
13
+ /**
14
+ * Resolve a dock client script's `importFrom` to the URL to import. URL
15
+ * specifiers pass through untouched; a **bare** specifier resolves through
16
+ * the explicit `resolveClientModule` callback (a viewer's own policy), then
17
+ * the host-advertised `template` (`ConnectionMeta.configs.dock.clientModuleResolution`,
18
+ * its `{specifier}` token replaced — e.g. Vite's `'/@id/{specifier}'`),
19
+ * resolved against `metaBaseUrl` so it targets the host's origin from any
20
+ * viewer. With neither, it stays unchanged — a page import map may still
21
+ * cover it.
22
+ */
23
+ function resolveClientModuleSpecifier(specifier, options = {}) {
24
+ if (!isBareModuleSpecifier(specifier)) return specifier;
25
+ const custom = options.resolveClientModule?.(specifier);
26
+ if (custom) return custom;
27
+ if (!options.template) return specifier;
28
+ const applied = options.template.includes("{specifier}") ? options.template.replaceAll("{specifier}", specifier) : options.template + specifier;
29
+ try {
30
+ return new URL(applied, options.metaBaseUrl).href;
31
+ } catch {
32
+ return applied;
33
+ }
34
+ }
35
+ /**
36
+ * Diagnose a failed client-script import: name the likely cause instead of
37
+ * leaving only the browser's opaque `TypeError`. `importFrom` is the entry's
38
+ * declared specifier, `specifier` what was actually imported (after
39
+ * {@link resolveClientModuleSpecifier}).
40
+ */
41
+ function clientScriptFailureHint(importFrom, specifier) {
42
+ if (!isBareModuleSpecifier(importFrom)) return "";
43
+ if (specifier === importFrom) return " — the specifier is a bare npm specifier and this host advertises no client-module resolution (`ConnectionMeta.configs.dock.clientModuleResolution`). Serve the script as a self-contained bundle by URL, pass `resolveClientModule` to this client host, or run under a host that resolves bare specifiers (e.g. Vite: `/@id/{specifier}`).";
44
+ return ` — the host resolved the bare specifier "${importFrom}" to this URL but could not serve the module. Check the package is installed and resolvable from the host project's root (and built, if its exports point at build output).`;
45
+ }
46
+ //#endregion
2
47
  //#region src/remote-url.ts
3
48
  function base64UrlEncode(value) {
4
49
  const bytes = new TextEncoder().encode(value);
@@ -15,7 +60,8 @@ function setRemoteConnectionParam(value, param) {
15
60
  }
16
61
  /** Encode a remote connection descriptor into an external viewer URL. */
17
62
  function buildRemoteConnectionUrl(baseUrl, payload, transport = "fragment") {
18
- const param = `${REMOTE_CONNECTION_KEY}=${base64UrlEncode(JSON.stringify(payload))}`;
63
+ const encoded = base64UrlEncode(JSON.stringify(payload));
64
+ const param = `${REMOTE_CONNECTION_KEY}=${encoded}`;
19
65
  if (transport === "fragment") {
20
66
  const hashIdx = baseUrl.indexOf("#");
21
67
  if (hashIdx === -1) return `${baseUrl}#${param}`;
@@ -70,4 +116,4 @@ function stripRemoteConnectionFromUrl(input) {
70
116
  return hash ? `${beforeHash}#${hash}` : beforeHash;
71
117
  }
72
118
  //#endregion
73
- export { stripRemoteConnectionFromUrl as n, buildRemoteConnectionUrl as t };
119
+ export { resolveClientModuleSpecifier as a, isBareModuleSpecifier as i, stripRemoteConnectionFromUrl as n, clientScriptFailureHint as r, buildRemoteConnectionUrl as t };
@@ -4,8 +4,8 @@ import { StandardSchemaV1 } from "@standard-schema/spec";
4
4
  interface DevframeDocksHost {
5
5
  readonly views: Map<string, DevframeDockUserEntry>;
6
6
  readonly events: EventEmitter<{
7
- 'dock:entry:updated': (entry: DevframeDockUserEntry) => void;
8
- 'dock:activate': (activation: DevframeDockActivation) => void;
7
+ 'docks:entry:updated': (entry: DevframeDockUserEntry) => void;
8
+ 'docks:activate': (activation: DevframeDockActivation) => void;
9
9
  }>;
10
10
  register: <T extends DevframeDockUserEntry>(entry: T, force?: boolean) => {
11
11
  update: (patch: Partial<T>) => void;
@@ -143,7 +143,14 @@ interface DevframeDockEntryBase {
143
143
  }
144
144
  interface ClientScriptEntry {
145
145
  /**
146
- * The filepath or module name to import from
146
+ * What to import — either a **URL the host serves** (a self-contained ES
147
+ * module, e.g. `/@fs/<abs path>` under Vite or a statically-mounted bundle
148
+ * path), or a **bare npm specifier** (e.g.
149
+ * `'vite-plugin-vue-tracer/client/vite-devtools'`), a host-runtime
150
+ * capability resolved through the host-advertised
151
+ * `ConnectionMeta.configs.dock.clientModuleResolution` template. On a host
152
+ * that declares no template, ship a self-contained bundle and pass its URL
153
+ * instead (see `DF8111`).
147
154
  */
148
155
  importFrom: string;
149
156
  /**
@@ -153,6 +160,23 @@ interface ClientScriptEntry {
153
160
  */
154
161
  importName?: string;
155
162
  }
163
+ declare module 'devframe/types' {
164
+ interface DevframeConnectionConfigsRegistry {
165
+ /** Static dock-layer config a hub host publishes through the connection handshake (`initHub({ clientModuleResolution })` → `ctx.staticConfig.dock`). */
166
+ dock: {
167
+ /**
168
+ * URL template resolving a **bare-specifier** client script to an
169
+ * importable URL on this host — `{specifier}` replaced with the bare
170
+ * specifier (a token-less template is used as a prefix). Declaring it
171
+ * advertises the host runtime can serve npm modules to the browser:
172
+ * Vite hosts declare `'/@id/{specifier}'`, routing the import (and its
173
+ * transitive bare imports) through the app's own module graph. Hosts
174
+ * without such a runtime (e.g. Next.js) leave it undeclared.
175
+ */
176
+ clientModuleResolution?: string;
177
+ };
178
+ }
179
+ }
156
180
  interface DevframeViewIframe extends DevframeDockEntryBase {
157
181
  type: 'iframe';
158
182
  url: string;
@@ -543,8 +567,8 @@ interface DevframeCommandHandle {
543
567
  unregister: () => void;
544
568
  }
545
569
  interface DevframeCommandsHostEvents {
546
- 'command:registered': (command: DevframeServerCommandEntry) => void;
547
- 'command:unregistered': (id: string) => void;
570
+ 'commands:registered': (command: DevframeServerCommandEntry) => void;
571
+ 'commands:unregistered': (id: string) => void;
548
572
  }
549
573
  interface DevframeCommandsHost {
550
574
  readonly commands: Map<string, DevframeServerCommandInput>;
@@ -1,4 +1,4 @@
1
- import { C as DevframeMessageHandle, D as DevframeMessagesHost, E as DevframeMessagesClient, O as DevframeMessagesLevelShortcuts, S as DevframeMessageFilePosition, T as DevframeMessageShortcutInput, _ as DevframeMessageCommandAction, a as DevframeChildProcessExecuteOptions, b as DevframeMessageEntryFrom, c as DevframeChildProcessTerminalSession, d as DevframeTerminalSession, f as DevframeTerminalSessionBase, g as DevframeMessageActivateAction, h as DevframeMessageAction, k as DevframeMessagesListDelta, l as DevframePtyExecuteOptions, m as DevframeTerminalsHost, n as DevframeHubContext, o as DevframeChildProcessOutput, p as DevframeTerminalStatus, s as DevframeChildProcessResult, t as CreateHubContextOptions, u as DevframePtyTerminalSession, v as DevframeMessageElementPosition, w as DevframeMessageLevel, x as DevframeMessageEntryInput, y as DevframeMessageEntry } from "../context-D5TJIHwp.mjs";
2
- import { A as DevframeViewLauncher, C as DevframeDocksActiveState, D as DevframeViewCustomRender, E as DevframeViewBuiltin, F as RemoteDockOptions, M as FrameSubTabsConfig, N as NavTarget, O as DevframeViewGroup, P as RemoteConnectionInfo, S as DevframeDockUserEntry, T as DevframeViewAction, _ as DevframeDockEntry, a as DevframeCommandEntry, b as DevframeDockEntryIcon, c as DevframeCommandShortcutOverrides, d as DevframeServerCommandEntry, f as DevframeServerCommandInput, g as DevframeDockEntriesGrouped, h as DevframeDockBadgeVariant, i as DevframeCommandBase, j as DevframeViewLauncherStatus, k as DevframeViewIframe, l as DevframeCommandsHost, m as DevframeDockActivation, n as DevframeClientCommand, o as DevframeCommandHandle, p as ClientScriptEntry, r as DevframeCommandAgentOptions, s as DevframeCommandKeybinding, t as DevframeDocksUserSettings, u as DevframeCommandsHostEvents, v as DevframeDockEntryBase, w as DevframeDocksHost, x as DevframeDockEntryRegistry, y as DevframeDockEntryCategory } from "../settings-DfrRa9Wf.mjs";
3
- import { S as RpcStreamingHost, _ as RpcFunctionsHost, a as DevframeHost, b as RpcStreamingChannel, c as DevframeRpcServerFunctions, d as EventEmitter, f as EventUnsubscribe, g as RpcDefinitionsToFunctions, h as RpcDefinitionsFilter, i as DevframeDiagnosticsLogger, l as DevframeRpcSharedStates, m as RpcBroadcastOptions, n as DevframeCapabilities, o as DevframeNodeRpcSession, p as EventsMap, r as DevframeDiagnosticsHost, s as DevframeRpcClientFunctions, t as ConnectionMeta, u as DevframeViewHost, v as RpcSharedStateGetOptions, x as RpcStreamingChannelOptions, y as RpcSharedStateHost } from "../index-coDmWngQ.mjs";
1
+ import { C as DevframeMessageHandle, D as DevframeMessagesHost, E as DevframeMessagesClient, O as DevframeMessagesLevelShortcuts, S as DevframeMessageFilePosition, T as DevframeMessageShortcutInput, _ as DevframeMessageCommandAction, a as DevframeChildProcessExecuteOptions, b as DevframeMessageEntryFrom, c as DevframeChildProcessTerminalSession, d as DevframeTerminalSession, f as DevframeTerminalSessionBase, g as DevframeMessageActivateAction, h as DevframeMessageAction, k as DevframeMessagesListDelta, l as DevframePtyExecuteOptions, m as DevframeTerminalsHost, n as DevframeHubContext, o as DevframeChildProcessOutput, p as DevframeTerminalStatus, s as DevframeChildProcessResult, t as CreateHubContextOptions, u as DevframePtyTerminalSession, v as DevframeMessageElementPosition, w as DevframeMessageLevel, x as DevframeMessageEntryInput, y as DevframeMessageEntry } from "../context-BVkxwz5k.mjs";
2
+ import { A as DevframeViewLauncher, C as DevframeDocksActiveState, D as DevframeViewCustomRender, E as DevframeViewBuiltin, F as RemoteDockOptions, M as FrameSubTabsConfig, N as NavTarget, O as DevframeViewGroup, P as RemoteConnectionInfo, S as DevframeDockUserEntry, T as DevframeViewAction, _ as DevframeDockEntry, a as DevframeCommandEntry, b as DevframeDockEntryIcon, c as DevframeCommandShortcutOverrides, d as DevframeServerCommandEntry, f as DevframeServerCommandInput, g as DevframeDockEntriesGrouped, h as DevframeDockBadgeVariant, i as DevframeCommandBase, j as DevframeViewLauncherStatus, k as DevframeViewIframe, l as DevframeCommandsHost, m as DevframeDockActivation, n as DevframeClientCommand, o as DevframeCommandHandle, p as ClientScriptEntry, r as DevframeCommandAgentOptions, s as DevframeCommandKeybinding, t as DevframeDocksUserSettings, u as DevframeCommandsHostEvents, v as DevframeDockEntryBase, w as DevframeDocksHost, x as DevframeDockEntryRegistry, y as DevframeDockEntryCategory } from "../settings-D7whfcx2.mjs";
3
+ import { S as RpcStreamingHost, _ as RpcFunctionsHost, a as DevframeHost, b as RpcStreamingChannel, c as DevframeRpcServerFunctions, d as EventEmitter, f as EventUnsubscribe, g as RpcDefinitionsToFunctions, h as RpcDefinitionsFilter, i as DevframeDiagnosticsLogger, l as DevframeRpcSharedStates, m as RpcBroadcastOptions, n as DevframeCapabilities, o as DevframeNodeRpcSession, p as EventsMap, r as DevframeDiagnosticsHost, s as DevframeRpcClientFunctions, t as ConnectionMeta, u as DevframeViewHost, v as RpcSharedStateGetOptions, x as RpcStreamingChannelOptions, y as RpcSharedStateHost } from "../index-CyEyZHB3.mjs";
4
4
  export { ClientScriptEntry, type ConnectionMeta, type CreateHubContextOptions, type DevframeCapabilities, DevframeChildProcessExecuteOptions, DevframeChildProcessOutput, DevframeChildProcessResult, DevframeChildProcessTerminalSession, DevframeClientCommand, DevframeCommandAgentOptions, DevframeCommandBase, DevframeCommandEntry, DevframeCommandHandle, DevframeCommandKeybinding, DevframeCommandShortcutOverrides, DevframeCommandsHost, DevframeCommandsHostEvents, type DevframeDiagnosticsHost, type DevframeDiagnosticsLogger, DevframeDockActivation, DevframeDockBadgeVariant, DevframeDockEntriesGrouped, DevframeDockEntry, DevframeDockEntryBase, DevframeDockEntryCategory, DevframeDockEntryIcon, DevframeDockEntryRegistry, DevframeDockUserEntry, DevframeDocksActiveState, DevframeDocksHost, DevframeDocksUserSettings, type DevframeHost, type DevframeHubContext, DevframeMessageAction, DevframeMessageActivateAction, DevframeMessageCommandAction, DevframeMessageElementPosition, DevframeMessageEntry, DevframeMessageEntryFrom, DevframeMessageEntryInput, DevframeMessageFilePosition, DevframeMessageHandle, DevframeMessageLevel, DevframeMessageShortcutInput, DevframeMessagesClient, DevframeMessagesHost, DevframeMessagesLevelShortcuts, DevframeMessagesListDelta, type DevframeNodeRpcSession, DevframePtyExecuteOptions, DevframePtyTerminalSession, type DevframeRpcClientFunctions, type DevframeRpcServerFunctions, type DevframeRpcSharedStates, DevframeServerCommandEntry, DevframeServerCommandInput, DevframeTerminalSession, DevframeTerminalSessionBase, DevframeTerminalStatus, DevframeTerminalsHost, DevframeViewAction, DevframeViewBuiltin, DevframeViewCustomRender, DevframeViewGroup, type DevframeViewHost, DevframeViewIframe, DevframeViewLauncher, DevframeViewLauncherStatus, type EventEmitter, type EventUnsubscribe, type EventsMap, FrameSubTabsConfig, NavTarget, RemoteConnectionInfo, RemoteDockOptions, type RpcBroadcastOptions, type RpcDefinitionsFilter, type RpcDefinitionsToFunctions, type RpcFunctionsHost, type RpcSharedStateGetOptions, type RpcSharedStateHost, type RpcStreamingChannel, type RpcStreamingChannelOptions, type RpcStreamingHost };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@devframes/hub",
3
3
  "type": "module",
4
- "version": "0.9.0",
4
+ "version": "0.9.1",
5
5
  "description": "Hub layer that orchestrates devframe docks, terminals, messages, and commands on any host.",
6
6
  "author": "Anthony Fu <anthonyfu117@hotmail.com>",
7
7
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  "dist"
35
35
  ],
36
36
  "peerDependencies": {
37
- "devframe": "0.9.0"
37
+ "devframe": "0.9.1"
38
38
  },
39
39
  "dependencies": {
40
40
  "@standard-schema/spec": "^1.1.0",
@@ -52,7 +52,7 @@
52
52
  "mlly": "^1.8.2",
53
53
  "tsdown": "^0.22.14",
54
54
  "valibot": "^1.4.2",
55
- "devframe": "0.9.0"
55
+ "devframe": "0.9.1"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsdown",