dsh-db-tool 1.5.2 → 1.5.3

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.
Files changed (2) hide show
  1. package/client/client.js +45 -4
  2. package/package.json +3 -2
package/client/client.js CHANGED
@@ -463,10 +463,37 @@ window.__ModuleLoader__.load({
463
463
  }
464
464
 
465
465
  // --- 弹窗挂载:优先 createPortal 挂 document.body(避免侧栏容器裁剪);宿主未提供 react-dom 时回退 Panel 内 fixed overlay(DangerDialog 同模式) ---
466
- let createPortal = null;
467
- try { createPortal = require("react-dom").createPortal; } catch (e) { /* 留 null,走回退 */ }
466
+ // 三重降级解析(模块级缓存,全模块一次):①模块加载时同步 require(dsh.client.inject 声明 react-dom 后应成功)
467
+ // ②宿主模块系统异步 import(ctx.modules,宿主 rc.8+ 提供)③均不可用则保持 Panel 内回退渲染。
468
+ let portalImpl = null; // 解析成功的 createPortal(缓存,全模块一次)
469
+ let portalTried = false; // 是否已尝试解析(异步 import 只发起一次)
470
+ let portalPending = null; // 订阅解析成功的回调列表
471
+ try {
472
+ var rd = require("react-dom");
473
+ if (rd && typeof rd.createPortal === "function") { portalImpl = rd.createPortal.bind(rd); portalTried = true; }
474
+ } catch (e) { /* 留 null,等异步解析 */ }
475
+ function resolvePortalAsync(ctx) {
476
+ if (portalTried) return;
477
+ portalTried = true;
478
+ if (portalImpl) return;
479
+ var mods = ctx && ctx.modules;
480
+ var p = mods && typeof mods.import === "function" ? mods.import("react-dom") : null;
481
+ if (p && typeof p.then === "function") {
482
+ p.then(function (m) {
483
+ if (m && typeof m.createPortal === "function") {
484
+ portalImpl = m.createPortal.bind(m);
485
+ var waiters = portalPending || []; portalPending = null;
486
+ for (var i = 0; i < waiters.length; i++) waiters[i]();
487
+ }
488
+ }).catch(function () { /* 解析失败保持回退渲染 */ });
489
+ }
490
+ }
491
+ function onPortalReady(cb) {
492
+ if (portalImpl) { cb(); return; }
493
+ (portalPending = portalPending || []).push(cb);
494
+ }
468
495
  function mountDialog(children) {
469
- return createPortal ? createPortal(children, document.body) : children;
496
+ return portalImpl ? portalImpl(children, document.body) : children;
470
497
  }
471
498
 
472
499
  /* ---------------- 连接管理 ---------------- */
@@ -1306,8 +1333,20 @@ window.__ModuleLoader__.load({
1306
1333
  }
1307
1334
 
1308
1335
  function BrowseDialog(props) {
1309
- const { conns, projectPath, grants, askConfirm, onClose } = props;
1336
+ const { conns, projectPath, grants, askConfirm, onClose, ctx } = props;
1310
1337
  // grants / askConfirm:预留给后续单元格编辑的危险操作确认通道,本任务先接住不使用
1338
+ // portal 异步解析接入:portalReady 仅用于触发重渲染(mountDialog 内部读 portalImpl)。
1339
+ // createPortal 不换组件实例——portalReady 切换前后是同一 DOM 节点,pos state 保持,居中定位不受 portal 重挂影响。
1340
+ const [portalReady, setPortalReady] = React.useState(!!portalImpl);
1341
+ React.useEffect(() => {
1342
+ resolvePortalAsync(ctx);
1343
+ onPortalReady(function () { setPortalReady(true); });
1344
+ // 诊断:一次性输出(帮助真机排查 iframe 隔离与 portal 解析结果)
1345
+ if (!window.__dbtPortalDiag) {
1346
+ window.__dbtPortalDiag = true;
1347
+ console.info("[dbt] portal:", portalImpl ? "sync/async ok" : "unavailable", "sameDoc:", window.top === window.self);
1348
+ }
1349
+ }, []);
1311
1350
  const [sel, setSel] = React.useState(null); // 弹窗内当前选中(null=未选表,右栏显示引导空态)
1312
1351
  const [view, setView] = React.useState("structure"); // structure | preview(纯视图切换,不影响数据加载)
1313
1352
  const [schema, setSchema] = React.useState([]);
@@ -1742,6 +1781,7 @@ window.__ModuleLoader__.load({
1742
1781
  // 浮窗常驻:portal 到 body 且在 dbt-view 外,切 tab 时不消失
1743
1782
  browseOpen ? React.createElement(BrowseDialog, {
1744
1783
  conns, projectPath, grants, askConfirm,
1784
+ ctx: props.ctx, // 宿主 ctx 透传给浮窗,供 portal 异步解析(ctx.modules.import)
1745
1785
  onClose: () => setBrowseOpen(false),
1746
1786
  }) : null,
1747
1787
  );
@@ -1766,6 +1806,7 @@ window.__ModuleLoader__.load({
1766
1806
  key: "db-tool-" + String(localeKey || "zh"),
1767
1807
  visible: props.visible,
1768
1808
  scope: props.scope,
1809
+ ctx: ctx, // 宿主 ctx 下传,Panel 透传给 BrowseDialog 供 portal 解析
1769
1810
  });
1770
1811
  }
1771
1812
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-db-tool",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "DSH community plugin: chat-operated multi-database admin tool with sidebar management, project-scoped grants, ro/rw modes and dangerous-operation confirmation",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -38,7 +38,8 @@
38
38
  },
39
39
  "client": {
40
40
  "inject": [
41
- "@deepseek-ai/dsh-client-locale"
41
+ "@deepseek-ai/dsh-client-locale",
42
+ "react-dom"
42
43
  ],
43
44
  "platform": "web"
44
45
  }