dominds 0.1.0
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/LICENSE +157 -0
- package/README.md +250 -0
- package/README.zh.md +161 -0
- package/dist/access-control.js +253 -0
- package/dist/cli/create.js +263 -0
- package/dist/cli/read.js +84 -0
- package/dist/cli/tui.js +199 -0
- package/dist/cli/webui.js +169 -0
- package/dist/cli.js +227 -0
- package/dist/dialog-factory.js +53 -0
- package/dist/dialog-global-registry.js +68 -0
- package/dist/dialog-instance-registry.js +78 -0
- package/dist/dialog-run-state.js +198 -0
- package/dist/dialog.js +1024 -0
- package/dist/evt-registry.js +103 -0
- package/dist/index.js +8 -0
- package/dist/llm/client.js +69 -0
- package/dist/llm/defaults.yaml +386 -0
- package/dist/llm/driver.js +3214 -0
- package/dist/llm/gen/anthropic.js +611 -0
- package/dist/llm/gen/codex.js +375 -0
- package/dist/llm/gen/mock.js +326 -0
- package/dist/llm/gen/openai.js +470 -0
- package/dist/llm/gen/registry.js +26 -0
- package/dist/llm/gen.js +2 -0
- package/dist/llm/tools-projection.js +37 -0
- package/dist/log.js +228 -0
- package/dist/mcp/config.js +230 -0
- package/dist/mcp/sdk-client.js +129 -0
- package/dist/mcp/server-runtime.js +57 -0
- package/dist/mcp/stdio-client.js +280 -0
- package/dist/mcp/supervisor.js +979 -0
- package/dist/mcp/tool-names.js +109 -0
- package/dist/minds/builtin/cmdr/persona.md +3 -0
- package/dist/minds/builtin/dijiang/knowledge.md +287 -0
- package/dist/minds/builtin/dijiang/persona.md +7 -0
- package/dist/minds/builtin/fuxi/persona.en.md +59 -0
- package/dist/minds/builtin/fuxi/persona.zh.md +49 -0
- package/dist/minds/builtin/pangu/persona.en.md +78 -0
- package/dist/minds/builtin/pangu/persona.zh.md +71 -0
- package/dist/minds/load.js +617 -0
- package/dist/minds/minds-i18n.js +131 -0
- package/dist/minds/system-prompt.js +281 -0
- package/dist/persistence.js +3128 -0
- package/dist/problems.js +109 -0
- package/dist/server/api-routes.js +1031 -0
- package/dist/server/auth.js +180 -0
- package/dist/server/mime-types.js +32 -0
- package/dist/server/prompts-routes.js +543 -0
- package/dist/server/server-core.js +235 -0
- package/dist/server/setup-routes.js +697 -0
- package/dist/server/static-server.js +132 -0
- package/dist/server/websocket-handler.js +1011 -0
- package/dist/server.js +164 -0
- package/dist/shared/async-fifo-mutex.js +36 -0
- package/dist/shared/diligence.js +20 -0
- package/dist/shared/dotenv.js +144 -0
- package/dist/shared/evt.js +195 -0
- package/dist/shared/i18n/driver-messages.js +267 -0
- package/dist/shared/i18n/text.js +9 -0
- package/dist/shared/i18n/tool-result-messages.js +51 -0
- package/dist/shared/rtws-cli.js +73 -0
- package/dist/shared/runtime-language.js +47 -0
- package/dist/shared/team-mgmt-manual.js +116 -0
- package/dist/shared/types/context-health.js +2 -0
- package/dist/shared/types/dialog.js +11 -0
- package/dist/shared/types/i18n.js +2 -0
- package/dist/shared/types/index.js +26 -0
- package/dist/shared/types/language.js +40 -0
- package/dist/shared/types/problems.js +2 -0
- package/dist/shared/types/prompts.js +2 -0
- package/dist/shared/types/q4h.js +7 -0
- package/dist/shared/types/run-state.js +8 -0
- package/dist/shared/types/setup.js +2 -0
- package/dist/shared/types/storage.js +10 -0
- package/dist/shared/types/tellask.js +8 -0
- package/dist/shared/types/tools-registry.js +2 -0
- package/dist/shared/types/wire.js +12 -0
- package/dist/shared/utils/fmt.js +9 -0
- package/dist/shared/utils/html.js +20 -0
- package/dist/shared/utils/id.js +18 -0
- package/dist/shared/utils/inter-dialog-format.js +101 -0
- package/dist/shared/utils/time.js +13 -0
- package/dist/static/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/static/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/dist/static/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/static/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/static/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/dist/static/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/static/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/dist/static/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/dist/static/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/static/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/dist/static/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/static/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/dist/static/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/dist/static/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/dist/static/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/static/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/dist/static/assets/_baseUniq-Crfl3d5Y.js +661 -0
- package/dist/static/assets/_baseUniq-Crfl3d5Y.js.map +1 -0
- package/dist/static/assets/arc-CbA_x9GD.js +132 -0
- package/dist/static/assets/arc-CbA_x9GD.js.map +1 -0
- package/dist/static/assets/architectureDiagram-VXUJARFQ-lcFS8ZQJ.js +8685 -0
- package/dist/static/assets/architectureDiagram-VXUJARFQ-lcFS8ZQJ.js.map +1 -0
- package/dist/static/assets/blockDiagram-VD42YOAC-B3Q36qRc.js +3608 -0
- package/dist/static/assets/blockDiagram-VD42YOAC-B3Q36qRc.js.map +1 -0
- package/dist/static/assets/c4Diagram-YG6GDRKO-Mt-aq3VH.js +2482 -0
- package/dist/static/assets/c4Diagram-YG6GDRKO-Mt-aq3VH.js.map +1 -0
- package/dist/static/assets/channel-BVr1Yke-.js +8 -0
- package/dist/static/assets/channel-BVr1Yke-.js.map +1 -0
- package/dist/static/assets/chunk-4BX2VUAB-qCIn5Iic.js +17 -0
- package/dist/static/assets/chunk-4BX2VUAB-qCIn5Iic.js.map +1 -0
- package/dist/static/assets/chunk-55IACEB6-q172NeCV.js +14 -0
- package/dist/static/assets/chunk-55IACEB6-q172NeCV.js.map +1 -0
- package/dist/static/assets/chunk-B4BG7PRW-CMJmtYzq.js +1827 -0
- package/dist/static/assets/chunk-B4BG7PRW-CMJmtYzq.js.map +1 -0
- package/dist/static/assets/chunk-DI55MBZ5-DiuwwZPL.js +1916 -0
- package/dist/static/assets/chunk-DI55MBZ5-DiuwwZPL.js.map +1 -0
- package/dist/static/assets/chunk-FMBD7UC4-06sqZTTn.js +20 -0
- package/dist/static/assets/chunk-FMBD7UC4-06sqZTTn.js.map +1 -0
- package/dist/static/assets/chunk-QN33PNHL-CnpBNkpP.js +25 -0
- package/dist/static/assets/chunk-QN33PNHL-CnpBNkpP.js.map +1 -0
- package/dist/static/assets/chunk-QZHKN3VN-CNgjMR-e.js +18 -0
- package/dist/static/assets/chunk-QZHKN3VN-CNgjMR-e.js.map +1 -0
- package/dist/static/assets/chunk-TZMSLE5B-BxtzW6--.js +109 -0
- package/dist/static/assets/chunk-TZMSLE5B-BxtzW6--.js.map +1 -0
- package/dist/static/assets/classDiagram-2ON5EDUG-29huvmn-.js +23 -0
- package/dist/static/assets/classDiagram-2ON5EDUG-29huvmn-.js.map +1 -0
- package/dist/static/assets/classDiagram-v2-WZHVMYZB-29huvmn-.js +23 -0
- package/dist/static/assets/classDiagram-v2-WZHVMYZB-29huvmn-.js.map +1 -0
- package/dist/static/assets/clone-D2OgLSSn.js +9 -0
- package/dist/static/assets/clone-D2OgLSSn.js.map +1 -0
- package/dist/static/assets/cose-bilkent-S5V4N54A-BNegDCxl.js +4943 -0
- package/dist/static/assets/cose-bilkent-S5V4N54A-BNegDCxl.js.map +1 -0
- package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js +30240 -0
- package/dist/static/assets/cytoscape.esm-Bm8DJGmZ.js.map +1 -0
- package/dist/static/assets/dagre-6UL2VRFP-f1XrTRSn.js +695 -0
- package/dist/static/assets/dagre-6UL2VRFP-f1XrTRSn.js.map +1 -0
- package/dist/static/assets/defaultLocale-DVr69WTU.js +207 -0
- package/dist/static/assets/defaultLocale-DVr69WTU.js.map +1 -0
- package/dist/static/assets/diagram-PSM6KHXK-8w1WbeDi.js +849 -0
- package/dist/static/assets/diagram-PSM6KHXK-8w1WbeDi.js.map +1 -0
- package/dist/static/assets/diagram-QEK2KX5R-CF4wtMmR.js +303 -0
- package/dist/static/assets/diagram-QEK2KX5R-CF4wtMmR.js.map +1 -0
- package/dist/static/assets/diagram-S2PKOQOG-8p3Avgn2.js +213 -0
- package/dist/static/assets/diagram-S2PKOQOG-8p3Avgn2.js.map +1 -0
- package/dist/static/assets/erDiagram-Q2GNP2WA-BMKLxlM9.js +1159 -0
- package/dist/static/assets/erDiagram-Q2GNP2WA-BMKLxlM9.js.map +1 -0
- package/dist/static/assets/favicon-Cmg5RbCj.svg +8 -0
- package/dist/static/assets/flowDiagram-NV44I4VS-CgEuPNK2.js +2332 -0
- package/dist/static/assets/flowDiagram-NV44I4VS-CgEuPNK2.js.map +1 -0
- package/dist/static/assets/ganttDiagram-JELNMOA3-bJkDCf-9.js +3681 -0
- package/dist/static/assets/ganttDiagram-JELNMOA3-bJkDCf-9.js.map +1 -0
- package/dist/static/assets/gitGraphDiagram-NY62KEGX-4QE9kesp.js +1206 -0
- package/dist/static/assets/gitGraphDiagram-NY62KEGX-4QE9kesp.js.map +1 -0
- package/dist/static/assets/graph-CS0Pmm7c.js +597 -0
- package/dist/static/assets/graph-CS0Pmm7c.js.map +1 -0
- package/dist/static/assets/index-BS6HnGzC.js +112303 -0
- package/dist/static/assets/index-BS6HnGzC.js.map +1 -0
- package/dist/static/assets/index-DaIsSzC_.css +483 -0
- package/dist/static/assets/infoDiagram-WHAUD3N6-ypBcKfUs.js +34 -0
- package/dist/static/assets/infoDiagram-WHAUD3N6-ypBcKfUs.js.map +1 -0
- package/dist/static/assets/init-ZxktEp_H.js +17 -0
- package/dist/static/assets/init-ZxktEp_H.js.map +1 -0
- package/dist/static/assets/journeyDiagram-XKPGCS4Q-QnrxDowJ.js +1255 -0
- package/dist/static/assets/journeyDiagram-XKPGCS4Q-QnrxDowJ.js.map +1 -0
- package/dist/static/assets/kanban-definition-3W4ZIXB7-CfvEc4z5.js +1048 -0
- package/dist/static/assets/kanban-definition-3W4ZIXB7-CfvEc4z5.js.map +1 -0
- package/dist/static/assets/layout-8TGxpm23.js +2218 -0
- package/dist/static/assets/layout-8TGxpm23.js.map +1 -0
- package/dist/static/assets/linear-BATBPQQv.js +341 -0
- package/dist/static/assets/linear-BATBPQQv.js.map +1 -0
- package/dist/static/assets/min-B3oVH3AC.js +42 -0
- package/dist/static/assets/min-B3oVH3AC.js.map +1 -0
- package/dist/static/assets/mindmap-definition-VGOIOE7T-L7VLwwF8.js +1127 -0
- package/dist/static/assets/mindmap-definition-VGOIOE7T-L7VLwwF8.js.map +1 -0
- package/dist/static/assets/ordinal-CxptdPJm.js +77 -0
- package/dist/static/assets/ordinal-CxptdPJm.js.map +1 -0
- package/dist/static/assets/pieDiagram-ADFJNKIX-CFW3zIhM.js +241 -0
- package/dist/static/assets/pieDiagram-ADFJNKIX-CFW3zIhM.js.map +1 -0
- package/dist/static/assets/quadrantDiagram-AYHSOK5B-B7ssen3E.js +1338 -0
- package/dist/static/assets/quadrantDiagram-AYHSOK5B-B7ssen3E.js.map +1 -0
- package/dist/static/assets/requirementDiagram-UZGBJVZJ-D0v5BArv.js +1162 -0
- package/dist/static/assets/requirementDiagram-UZGBJVZJ-D0v5BArv.js.map +1 -0
- package/dist/static/assets/sankeyDiagram-TZEHDZUN-B7slncJe.js +1195 -0
- package/dist/static/assets/sankeyDiagram-TZEHDZUN-B7slncJe.js.map +1 -0
- package/dist/static/assets/sequenceDiagram-WL72ISMW-oXU2lRh_.js +3875 -0
- package/dist/static/assets/sequenceDiagram-WL72ISMW-oXU2lRh_.js.map +1 -0
- package/dist/static/assets/stateDiagram-FKZM4ZOC-CFYsEd0x.js +452 -0
- package/dist/static/assets/stateDiagram-FKZM4ZOC-CFYsEd0x.js.map +1 -0
- package/dist/static/assets/stateDiagram-v2-4FDKWEC3-C0UWaNA7.js +22 -0
- package/dist/static/assets/stateDiagram-v2-4FDKWEC3-C0UWaNA7.js.map +1 -0
- package/dist/static/assets/timeline-definition-IT6M3QCI-C3KODUrh.js +1223 -0
- package/dist/static/assets/timeline-definition-IT6M3QCI-C3KODUrh.js.map +1 -0
- package/dist/static/assets/treemap-KMMF4GRG-DAGDLhj2.js +18753 -0
- package/dist/static/assets/treemap-KMMF4GRG-DAGDLhj2.js.map +1 -0
- package/dist/static/assets/xychartDiagram-PRI3JC2R-C0J9iwTO.js +1888 -0
- package/dist/static/assets/xychartDiagram-PRI3JC2R-C0J9iwTO.js.map +1 -0
- package/dist/static/index.html +71 -0
- package/dist/static/testing/dom-observation-utils.js +425 -0
- package/dist/static/testing/e2e-test-helper.js +3119 -0
- package/dist/team.js +1160 -0
- package/dist/tellask.js +431 -0
- package/dist/tool.js +150 -0
- package/dist/tools/apply-patch.js +542 -0
- package/dist/tools/builtins.js +196 -0
- package/dist/tools/context-health.js +177 -0
- package/dist/tools/ctrl.js +478 -0
- package/dist/tools/diag.js +583 -0
- package/dist/tools/env.js +184 -0
- package/dist/tools/fs.js +818 -0
- package/dist/tools/mcp.js +138 -0
- package/dist/tools/mem.js +349 -0
- package/dist/tools/os.js +751 -0
- package/dist/tools/prompts/team_mgmt.en.md +70 -0
- package/dist/tools/prompts/team_mgmt.zh.md +70 -0
- package/dist/tools/prompts/ws_mod.en.md +86 -0
- package/dist/tools/prompts/ws_mod.zh.md +87 -0
- package/dist/tools/registry-snapshot.js +31 -0
- package/dist/tools/registry.js +121 -0
- package/dist/tools/ripgrep.js +678 -0
- package/dist/tools/team-mgmt.js +3300 -0
- package/dist/tools/txt.js +3178 -0
- package/dist/utils/id.js +72 -0
- package/dist/utils/task-doc.js +236 -0
- package/dist/utils/task-package.js +522 -0
- package/dist/utils/taskdoc-search.js +280 -0
- package/dist/utils/taskdoc.js +400 -0
- package/package.json +69 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM Observation Utilities for E2E Testing
|
|
3
|
+
*
|
|
4
|
+
* Provides MutationObserver-based wait utilities that respond immediately
|
|
5
|
+
* when DOM changes occur, replacing inefficient polling with event-driven waits.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Core wait function that uses MutationObserver to detect DOM changes.
|
|
10
|
+
*
|
|
11
|
+
* @param {Function} conditionFn - Function that returns truthy when condition is met
|
|
12
|
+
* @param {Object} options - Configuration options
|
|
13
|
+
* @param {number} options.timeoutMs - Maximum wait time (default: 10000)
|
|
14
|
+
* @param {MutationObserverInit} options.observeOptions - What to observe (default: { childList: true, subtree: true })
|
|
15
|
+
* @param {Node} options.root - Root node to observe (default: document.body)
|
|
16
|
+
* @returns {Promise<any>} The truthy value from conditionFn, or throws on timeout
|
|
17
|
+
*/
|
|
18
|
+
async function waitForDomChange(conditionFn, options = {}) {
|
|
19
|
+
const {
|
|
20
|
+
timeoutMs = 10000,
|
|
21
|
+
observeOptions = { childList: true, subtree: true },
|
|
22
|
+
root = document.body,
|
|
23
|
+
} = options;
|
|
24
|
+
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
|
|
27
|
+
return new Promise((resolve, reject) => {
|
|
28
|
+
// Check immediately first - avoids observer overhead if already satisfied
|
|
29
|
+
try {
|
|
30
|
+
const result = conditionFn();
|
|
31
|
+
if (result) {
|
|
32
|
+
resolve(result);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
} catch (err) {
|
|
36
|
+
// Condition function may throw while DOM is unstable
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const observer = new MutationObserver(() => {
|
|
40
|
+
try {
|
|
41
|
+
const result = conditionFn();
|
|
42
|
+
if (result) {
|
|
43
|
+
observer.disconnect();
|
|
44
|
+
resolve(result);
|
|
45
|
+
}
|
|
46
|
+
} catch (err) {
|
|
47
|
+
// Ignore errors during mutation checking
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
observer.observe(root, observeOptions);
|
|
52
|
+
|
|
53
|
+
// Fallback timeout to prevent hanging
|
|
54
|
+
const timeoutId = setTimeout(() => {
|
|
55
|
+
observer.disconnect();
|
|
56
|
+
try {
|
|
57
|
+
const result = conditionFn();
|
|
58
|
+
if (result) {
|
|
59
|
+
resolve(result);
|
|
60
|
+
} else {
|
|
61
|
+
reject(new Error(`waitForDomChange timed out after ${timeoutMs}ms`));
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
reject(new Error(`waitForDomChange timed out after ${timeoutMs}ms`));
|
|
65
|
+
}
|
|
66
|
+
}, timeoutMs);
|
|
67
|
+
|
|
68
|
+
// Clean up timeout if observer resolves first
|
|
69
|
+
observer.callback = () => {
|
|
70
|
+
// This is a no-op; actual logic is in the observer callback above
|
|
71
|
+
// The real cleanup happens in the resolve/reject paths
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Wait for an element to appear in the DOM.
|
|
78
|
+
*
|
|
79
|
+
* @param {string} selector - CSS selector for the element
|
|
80
|
+
* @param {Object} options - waitForDomChange options
|
|
81
|
+
* @returns {Promise<Element|null>} The found element, or null if timeout
|
|
82
|
+
*/
|
|
83
|
+
async function waitForElement(selector, options = {}) {
|
|
84
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
85
|
+
try {
|
|
86
|
+
return await waitForDomChange(() => document.querySelector(selector), {
|
|
87
|
+
...options,
|
|
88
|
+
timeoutMs,
|
|
89
|
+
});
|
|
90
|
+
} catch (err) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Wait for an element to be added to the DOM (throws on timeout).
|
|
97
|
+
*
|
|
98
|
+
* @param {string} selector - CSS selector for the element
|
|
99
|
+
* @param {Object} options - waitForDomChange options
|
|
100
|
+
* @returns {Promise<Element>} The found element
|
|
101
|
+
* @throws {Error} If element not found within timeout
|
|
102
|
+
*/
|
|
103
|
+
async function waitForElementAdded(selector, options = {}) {
|
|
104
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
105
|
+
return waitForDomChange(
|
|
106
|
+
() => {
|
|
107
|
+
const el = document.querySelector(selector);
|
|
108
|
+
if (!el) return false;
|
|
109
|
+
// Element exists and is connected to DOM
|
|
110
|
+
return el.isConnected ? el : false;
|
|
111
|
+
},
|
|
112
|
+
{ ...options, timeoutMs },
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Wait for an element to be removed from the DOM.
|
|
118
|
+
*
|
|
119
|
+
* @param {string} selector - CSS selector for the element
|
|
120
|
+
* @param {Object} options - waitForDomChange options
|
|
121
|
+
* @returns {Promise<boolean>} True when element is gone
|
|
122
|
+
*/
|
|
123
|
+
async function waitForElementGone(selector, options = {}) {
|
|
124
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
125
|
+
return waitForDomChange(() => !document.querySelector(selector), { ...options, timeoutMs });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Wait for an element's attribute to have a specific value.
|
|
130
|
+
*
|
|
131
|
+
* @param {string} selector - CSS selector for the element
|
|
132
|
+
* @param {string} attributeName - Attribute to watch
|
|
133
|
+
* @param {string|Function} expectedValue - Expected value or predicate function
|
|
134
|
+
* @param {Object} options - waitForDomChange options
|
|
135
|
+
* @returns {Promise<string>} The attribute value when matched
|
|
136
|
+
*/
|
|
137
|
+
async function waitForAttribute(selector, attributeName, expectedValue, options = {}) {
|
|
138
|
+
const isFunc = typeof expectedValue === 'function';
|
|
139
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
140
|
+
|
|
141
|
+
return waitForDomChange(
|
|
142
|
+
() => {
|
|
143
|
+
const el = document.querySelector(selector);
|
|
144
|
+
if (!el) return false;
|
|
145
|
+
|
|
146
|
+
const value = el.getAttribute(attributeName);
|
|
147
|
+
if (isFunc) {
|
|
148
|
+
return expectedValue(value) ? value : false;
|
|
149
|
+
}
|
|
150
|
+
return value === expectedValue ? value : false;
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
...options,
|
|
154
|
+
timeoutMs,
|
|
155
|
+
observeOptions: { attributes: true, subtree: true },
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Wait for an element to have a specific class.
|
|
162
|
+
*
|
|
163
|
+
* @param {string} selector - CSS selector for the element
|
|
164
|
+
* @param {string} className - Class name to wait for
|
|
165
|
+
* @param {Object} options - waitForDomChange options
|
|
166
|
+
* @returns {Promise<boolean>} True when class is present
|
|
167
|
+
*/
|
|
168
|
+
async function waitForClass(selector, className, options = {}) {
|
|
169
|
+
return waitForAttribute(selector, 'class', (cls) => cls && cls.includes(className), options);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Wait for an element to be visible (has dimensions and not display:none).
|
|
174
|
+
*
|
|
175
|
+
* @param {string} selector - CSS selector for the element
|
|
176
|
+
* @param {Object} options - waitForDomChange options
|
|
177
|
+
* @returns {Promise<Element>} The visible element
|
|
178
|
+
*/
|
|
179
|
+
async function waitForVisible(selector, options = {}) {
|
|
180
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
181
|
+
return waitForDomChange(
|
|
182
|
+
() => {
|
|
183
|
+
const el = document.querySelector(selector);
|
|
184
|
+
if (!el) return false;
|
|
185
|
+
|
|
186
|
+
const style = window.getComputedStyle(el);
|
|
187
|
+
const isVisible =
|
|
188
|
+
style.display !== 'none' &&
|
|
189
|
+
style.visibility !== 'hidden' &&
|
|
190
|
+
style.opacity !== '0' &&
|
|
191
|
+
el.offsetWidth > 0 &&
|
|
192
|
+
el.offsetHeight > 0;
|
|
193
|
+
|
|
194
|
+
return isVisible ? el : false;
|
|
195
|
+
},
|
|
196
|
+
{ ...options, timeoutMs, observeOptions: { attributes: true, childList: true, subtree: true } },
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Wait for an element to be hidden (display:none or visibility:hidden).
|
|
202
|
+
*
|
|
203
|
+
* @param {string} selector - CSS selector for the element
|
|
204
|
+
* @param {Object} options - waitForDomChange options
|
|
205
|
+
* @returns {Promise<boolean>} True when element is hidden
|
|
206
|
+
*/
|
|
207
|
+
async function waitForHidden(selector, options = {}) {
|
|
208
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
209
|
+
return waitForDomChange(
|
|
210
|
+
() => {
|
|
211
|
+
const el = document.querySelector(selector);
|
|
212
|
+
if (!el) return true; // Element is gone = hidden
|
|
213
|
+
|
|
214
|
+
const style = window.getComputedStyle(el);
|
|
215
|
+
const isHidden =
|
|
216
|
+
style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0';
|
|
217
|
+
|
|
218
|
+
return isHidden;
|
|
219
|
+
},
|
|
220
|
+
{ ...options, timeoutMs, observeOptions: { attributes: true, childList: true, subtree: true } },
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Wait for text content to appear in an element.
|
|
226
|
+
*
|
|
227
|
+
* @param {string} selector - CSS selector for the element
|
|
228
|
+
* @param {string|RegExp|Function} text - Text to wait for
|
|
229
|
+
* @param {Object} options - waitForDomChange options
|
|
230
|
+
* @returns {Promise<string>} The matched text
|
|
231
|
+
*/
|
|
232
|
+
async function waitForText(selector, text, options = {}) {
|
|
233
|
+
const isFunction = typeof text === 'function';
|
|
234
|
+
const isRegex = text instanceof RegExp;
|
|
235
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
236
|
+
|
|
237
|
+
return waitForDomChange(
|
|
238
|
+
() => {
|
|
239
|
+
const el = document.querySelector(selector);
|
|
240
|
+
if (!el) return false;
|
|
241
|
+
|
|
242
|
+
const content = el.textContent || '';
|
|
243
|
+
if (isFunction) {
|
|
244
|
+
return text(content) ? content : false;
|
|
245
|
+
}
|
|
246
|
+
if (isRegex) {
|
|
247
|
+
return text.test(content) ? content : false;
|
|
248
|
+
}
|
|
249
|
+
return content.includes(text) ? content : false;
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
...options,
|
|
253
|
+
timeoutMs,
|
|
254
|
+
observeOptions: { characterData: true, childList: true, subtree: true },
|
|
255
|
+
},
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// ============================================
|
|
260
|
+
// Modal-Specific Utilities
|
|
261
|
+
// ============================================
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Wait for a modal dialog to open (appear in DOM).
|
|
265
|
+
*
|
|
266
|
+
* @param {string} modalSelector - CSS selector for the modal
|
|
267
|
+
* @param {Object} options - waitForDomChange options
|
|
268
|
+
* @returns {Promise<Element>} The opened modal element
|
|
269
|
+
*/
|
|
270
|
+
async function waitForModalOpen(modalSelector, options = {}) {
|
|
271
|
+
return waitForElementAdded(modalSelector, options);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Wait for a modal dialog to close (removed from DOM or hidden).
|
|
276
|
+
*
|
|
277
|
+
* @param {string} modalSelector - CSS selector for the modal
|
|
278
|
+
* @param {Object} options - waitForDomChange options
|
|
279
|
+
* @returns {Promise<boolean>} True when modal is closed
|
|
280
|
+
*/
|
|
281
|
+
async function waitForModalClose(modalSelector, options = {}) {
|
|
282
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
283
|
+
|
|
284
|
+
// First try: check if element is gone
|
|
285
|
+
const elementGone = await waitForElementGone(modalSelector, {
|
|
286
|
+
...options,
|
|
287
|
+
timeoutMs: Math.min(timeoutMs, 2000),
|
|
288
|
+
});
|
|
289
|
+
if (elementGone) return true;
|
|
290
|
+
|
|
291
|
+
// Second try: check if element is hidden
|
|
292
|
+
return waitForHidden(modalSelector, { ...options, timeoutMs: timeoutMs - 2000 });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Wait for a select element's value to change to the expected value.
|
|
297
|
+
*
|
|
298
|
+
* @param {string} selectSelector - CSS selector for the select element
|
|
299
|
+
* @param {string} expectedValue - Expected option value
|
|
300
|
+
* @param {Object} options - waitForDomChange options
|
|
301
|
+
* @returns {Promise<string>} The selected value
|
|
302
|
+
*/
|
|
303
|
+
async function waitForSelectValue(selectSelector, expectedValue, options = {}) {
|
|
304
|
+
return waitForAttribute(selectSelector, 'value', expectedValue, options);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ============================================
|
|
308
|
+
// Shadow DOM Utilities
|
|
309
|
+
// ============================================
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Wait for an element in Shadow DOM to appear.
|
|
313
|
+
*
|
|
314
|
+
* @param {string} hostSelector - CSS selector for the shadow host
|
|
315
|
+
* @param {string} shadowSelector - CSS selector within shadow DOM
|
|
316
|
+
* @param {Object} options - waitForDomChange options
|
|
317
|
+
* @returns {Promise<Element|null>} The found element in shadow DOM
|
|
318
|
+
*/
|
|
319
|
+
async function waitForShadowElement(hostSelector, shadowSelector, options = {}) {
|
|
320
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
321
|
+
try {
|
|
322
|
+
return await waitForDomChange(
|
|
323
|
+
() => {
|
|
324
|
+
const host = document.querySelector(hostSelector);
|
|
325
|
+
if (!host || !host.shadowRoot) return false;
|
|
326
|
+
return host.shadowRoot.querySelector(shadowSelector);
|
|
327
|
+
},
|
|
328
|
+
{ ...options, timeoutMs },
|
|
329
|
+
);
|
|
330
|
+
} catch (err) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Wait for an element in nested Shadow DOM (double-shadow).
|
|
337
|
+
*
|
|
338
|
+
* @param {string[]} hostSelectors - Array of selectors for each shadow host level
|
|
339
|
+
* @param {string} targetSelector - Final selector within deepest shadow DOM
|
|
340
|
+
* @param {Object} options - waitForDomChange options
|
|
341
|
+
* @returns {Promise<Element|null>} The found element
|
|
342
|
+
*/
|
|
343
|
+
async function waitForNestedShadowElement(hostSelectors, targetSelector, options = {}) {
|
|
344
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
345
|
+
|
|
346
|
+
return waitForDomChange(
|
|
347
|
+
() => {
|
|
348
|
+
let current = document;
|
|
349
|
+
|
|
350
|
+
for (const selector of hostSelectors) {
|
|
351
|
+
if (current instanceof Document) {
|
|
352
|
+
current = current.querySelector(selector);
|
|
353
|
+
} else if (current instanceof HTMLElement && current.shadowRoot) {
|
|
354
|
+
current = current.shadowRoot.querySelector(selector);
|
|
355
|
+
}
|
|
356
|
+
if (!current) return false;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (current instanceof HTMLElement && current.shadowRoot) {
|
|
360
|
+
return current.shadowRoot.querySelector(targetSelector);
|
|
361
|
+
}
|
|
362
|
+
return false;
|
|
363
|
+
},
|
|
364
|
+
{ ...options, timeoutMs },
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Wait for an element in Shadow DOM to be hidden (not found or display:none).
|
|
370
|
+
*
|
|
371
|
+
* @param {string} hostSelector - CSS selector for the shadow host
|
|
372
|
+
* @param {string} shadowSelector - CSS selector within shadow DOM
|
|
373
|
+
* @param {Object} options - waitForDomChange options
|
|
374
|
+
* @returns {Promise<boolean>} True when element is hidden/not found
|
|
375
|
+
*/
|
|
376
|
+
async function waitForShadowElementHidden(hostSelector, shadowSelector, options = {}) {
|
|
377
|
+
const timeoutMs = options.timeoutMs ?? 5000;
|
|
378
|
+
return waitForDomChange(
|
|
379
|
+
() => {
|
|
380
|
+
const host = document.querySelector(hostSelector);
|
|
381
|
+
if (!host || !host.shadowRoot) return true; // Host gone = hidden
|
|
382
|
+
const el = host.shadowRoot.querySelector(shadowSelector);
|
|
383
|
+
if (!el) return true; // Element not found = hidden
|
|
384
|
+
|
|
385
|
+
// Check if element is hidden via styles
|
|
386
|
+
const style = window.getComputedStyle(el);
|
|
387
|
+
const isHidden =
|
|
388
|
+
style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0';
|
|
389
|
+
return isHidden;
|
|
390
|
+
},
|
|
391
|
+
{ ...options, timeoutMs },
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ============================================
|
|
396
|
+
// Export
|
|
397
|
+
// ============================================
|
|
398
|
+
|
|
399
|
+
const domObservationUtils = {
|
|
400
|
+
waitForDomChange,
|
|
401
|
+
waitForElement,
|
|
402
|
+
waitForElementAdded,
|
|
403
|
+
waitForElementGone,
|
|
404
|
+
waitForAttribute,
|
|
405
|
+
waitForClass,
|
|
406
|
+
waitForVisible,
|
|
407
|
+
waitForHidden,
|
|
408
|
+
waitForText,
|
|
409
|
+
waitForModalOpen,
|
|
410
|
+
waitForModalClose,
|
|
411
|
+
waitForSelectValue,
|
|
412
|
+
waitForShadowElement,
|
|
413
|
+
waitForNestedShadowElement,
|
|
414
|
+
waitForShadowElementHidden,
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// Export to window for E2E testing
|
|
418
|
+
if (typeof window !== 'undefined') {
|
|
419
|
+
window.__domObservation__ = domObservationUtils;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// Also export as module for bundlers
|
|
423
|
+
if (typeof module !== 'undefined' && module.exports) {
|
|
424
|
+
module.exports = domObservationUtils;
|
|
425
|
+
}
|