@rainbow-robotics/muscat-plugin-kit 1.10.1-dev.1 → 1.10.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/README.md +282 -282
- package/cli/README.md +274 -274
- package/cli/bin/create-muscat-plugin.mjs +8 -8
- package/cli/bin/muscat-pk.mjs +155 -155
- package/cli/bundle-templates.mjs +31 -31
- package/cli/docker/Dockerfile.cpp +28 -28
- package/cli/docker/Dockerfile.dev +30 -30
- package/cli/docker/Dockerfile.python +21 -21
- package/cli/m5-e2e.mjs +69 -69
- package/cli/prepack.mjs +10 -10
- package/cli/src/ai-rules.mjs +70 -70
- package/cli/src/build.mjs +447 -447
- package/cli/src/check-package.mjs +13 -13
- package/cli/src/completion.mjs +166 -166
- package/cli/src/cpp.mjs +78 -78
- package/cli/src/cppIde.mjs +75 -75
- package/cli/src/dev.mjs +165 -165
- package/cli/src/devBack.mjs +734 -727
- package/cli/src/devUi.mjs +247 -243
- package/cli/src/esbuild.mjs +56 -56
- package/cli/src/host_agent.py +223 -223
- package/cli/src/manifest.mjs +287 -287
- package/cli/src/mcp.mjs +1071 -1071
- package/cli/src/muscatLocal.mjs +209 -209
- package/cli/src/new.mjs +343 -343
- package/cli/src/pluginDevServer.mjs +111 -111
- package/cli/src/ports.mjs +193 -193
- package/cli/src/python.mjs +112 -112
- package/cli/src/ros2.mjs +109 -109
- package/cli/src/sdk.mjs +117 -117
- package/cli/src/storybook.mjs +168 -168
- package/cli/src/type.mjs +141 -141
- package/cli/src/uninstall.mjs +81 -81
- package/cli/src/update.mjs +295 -295
- package/cli/src/util.mjs +441 -441
- package/cli/src/zenohDev.mjs +83 -81
- package/cli/storybook-dist/_design-tokens.css +4957 -4957
- package/cli/storybook-dist/_stories-src/NxAvatar.stories.tsx +27 -27
- package/cli/storybook-dist/_stories-src/NxPagination.stories.tsx +28 -28
- package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordion.stories.tsx +46 -46
- package/cli/storybook-dist/_stories-src/RBAccordion/RBAccordionGroup.stories.tsx +73 -73
- package/cli/storybook-dist/_stories-src/RBBadge/RBBadge.stories.tsx +93 -93
- package/cli/storybook-dist/_stories-src/RBBattery/RBBattery.stories.tsx +74 -74
- package/cli/storybook-dist/_stories-src/RBButton/RBCheckIconButton.stories.tsx +28 -28
- package/cli/storybook-dist/_stories-src/RBButton/RBCheckLabelButton.stories.tsx +84 -84
- package/cli/storybook-dist/_stories-src/RBButton/RBIconButton.stories.tsx +57 -57
- package/cli/storybook-dist/_stories-src/RBButton/RBInlineLabelButton.stories.tsx +41 -41
- package/cli/storybook-dist/_stories-src/RBButton/RBLabelButton.stories.tsx +60 -60
- package/cli/storybook-dist/_stories-src/RBDatePicker/RBDateInput.stories.tsx +44 -44
- package/cli/storybook-dist/_stories-src/RBDatePicker/RBRangeDateInput.stories.tsx +56 -56
- package/cli/storybook-dist/_stories-src/RBDialog/RBAlert.stories.tsx +51 -51
- package/cli/storybook-dist/_stories-src/RBDialog/RBConfirm.stories.tsx +55 -55
- package/cli/storybook-dist/_stories-src/RBDialog/RBPrompt.stories.tsx +52 -52
- package/cli/storybook-dist/_stories-src/RBDivider/RBDivider.stories.tsx +93 -93
- package/cli/storybook-dist/_stories-src/RBEmptyView/RBEmptyView.stories.tsx +49 -49
- package/cli/storybook-dist/_stories-src/RBIcons/RBColorIcons.stories.tsx +108 -108
- package/cli/storybook-dist/_stories-src/RBIcons/RBIcons.stories.tsx +106 -106
- package/cli/storybook-dist/_stories-src/RBInput/RBCheckBox.stories.tsx +89 -89
- package/cli/storybook-dist/_stories-src/RBInput/RBMultiRangeInput.stories.tsx +64 -64
- package/cli/storybook-dist/_stories-src/RBInput/RBRadioBox.stories.tsx +65 -65
- package/cli/storybook-dist/_stories-src/RBInput/RBRadioButton.stories.tsx +68 -68
- package/cli/storybook-dist/_stories-src/RBInput/RBSelectBox.stories.tsx +216 -216
- package/cli/storybook-dist/_stories-src/RBInput/RBSideNumberInput.stories.tsx +90 -90
- package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextArea.stories.tsx +45 -45
- package/cli/storybook-dist/_stories-src/RBInput/RBText/RBTextInput.stories.tsx +50 -50
- package/cli/storybook-dist/_stories-src/RBInput/RBTextField.stories.tsx +102 -102
- package/cli/storybook-dist/_stories-src/RBJoyStick/RBJoyStick.stories.tsx +31 -31
- package/cli/storybook-dist/_stories-src/RBLight/RBLight.stories.tsx +36 -36
- package/cli/storybook-dist/_stories-src/RBPagination/RBPagination.stories.tsx +49 -49
- package/cli/storybook-dist/_stories-src/RBShadcn/RBCard/RBCard.stories.tsx +89 -89
- package/cli/storybook-dist/_stories-src/RBShadcn/RBCommand/RBCommand.stories.tsx +116 -116
- package/cli/storybook-dist/_stories-src/RBShadcn/RBDialog/RBDialog.stories.tsx +74 -74
- package/cli/storybook-dist/_stories-src/RBShadcn/RBDrawer/RBDrawer.stories.tsx +99 -99
- package/cli/storybook-dist/_stories-src/RBShadcn/RBDropdownMenu/RBDropdownMenu.stories.tsx +123 -123
- package/cli/storybook-dist/_stories-src/RBShadcn/RBMenubar/RBMenubar.stories.tsx +135 -135
- package/cli/storybook-dist/_stories-src/RBShadcn/RBPopover/RBPopover.stories.tsx +69 -69
- package/cli/storybook-dist/_stories-src/RBShadcn/RBResizable/RBResizable.stories.tsx +49 -49
- package/cli/storybook-dist/_stories-src/RBShadcn/RBSheet/RBSheet.stories.tsx +91 -91
- package/cli/storybook-dist/_stories-src/RBShadcn/RBSlider/RBSlider.stories.tsx +38 -38
- package/cli/storybook-dist/_stories-src/RBShadcn/RBSwitch/RBSwitch.stories.tsx +112 -112
- package/cli/storybook-dist/_stories-src/RBShadcn/RBTabs/RBTabs.stories.tsx +75 -75
- package/cli/storybook-dist/_stories-src/RBShadcn/RBToggle/RBToggle.stories.tsx +51 -51
- package/cli/storybook-dist/_stories-src/RBShadcn/RBToggleGroup/RBToggleGroup.stories.tsx +84 -84
- package/cli/storybook-dist/_stories-src/RBTab/RBChipTab.stories.tsx +102 -102
- package/cli/storybook-dist/_stories-src/RBTab/RBChipsBoxTab.stories.tsx +78 -78
- package/cli/storybook-dist/_stories-src/RBTab/RBTab.stories.tsx +57 -57
- package/cli/storybook-dist/_stories-src/RBTable/RBTable.stories.tsx +177 -177
- package/cli/storybook-dist/_stories-src/RBTable/RBTableRow.stories.tsx +64 -64
- package/cli/storybook-dist/_stories-src/RBToast/RBToast.stories.tsx +117 -117
- package/cli/storybook-dist/_stories-src/RBTooltip/RBTooltip.stories.tsx +50 -50
- package/cli/storybook-dist/_stories-src/loading/RBSpinner.stories.tsx +30 -30
- package/cli/storybook-dist/_stories-src/nx-button/NxButton.stories.tsx +54 -54
- package/cli/storybook-dist/_stories-src/nx-button/NxPointerHoldButton.stories.tsx +57 -57
- package/cli/storybook-dist/_stories-src/nx-icons/NxIcons.stories.tsx +48 -48
- package/cli/storybook-dist/_stories-src/nx-inputs/NxNumberInput.stories.tsx +103 -103
- package/cli/storybook-dist/_stories-src/nx-inputs/NxRangeInput.stories.tsx +27 -27
- package/cli/storybook-dist/_stories-src/nx-inputs/NxSelectBox.stories.tsx +67 -67
- package/cli/storybook-dist/_stories-src/nx-inputs/NxSlideRange.stories.tsx +45 -45
- package/cli/storybook-dist/_stories-src/nx-inputs/NxSwitch.stories.tsx +27 -27
- package/cli/storybook-dist/_stories-src/nx-inputs/NxTextArea.stories.tsx +48 -48
- package/cli/storybook-dist/_stories-src/nx-inputs/NxTextInput.stories.tsx +46 -46
- package/cli/storybook-dist/assets/{Color-YHDXOIA2-D6JqZzDJ.js → Color-YHDXOIA2-B4IER17l.js} +1 -1
- package/cli/storybook-dist/assets/{Docs-ESb7JAHg.js → Docs-C8GCHFtK.js} +3 -3
- package/cli/storybook-dist/assets/{Docs-6gD2kUo1.js → Docs-CgdEMPQP.js} +2 -2
- package/cli/storybook-dist/assets/{Docs-B9wd8Ok7.js → Docs-Ck3WHvk6.js} +3 -3
- package/cli/storybook-dist/assets/{Docs-CgFbWWXM.js → Docs-D9NHsoeZ.js} +2 -2
- package/cli/storybook-dist/assets/{Docs-DBQup8Bu.js → Docs-DNYQC7nl.js} +3 -3
- package/cli/storybook-dist/assets/{Docs-CMjovnSY.js → Docs-DUfeiM4I.js} +4 -4
- package/cli/storybook-dist/assets/{DocsRenderer-CFRXHY34-BOUI1AHi.js → DocsRenderer-CFRXHY34-C0WhyDoR.js} +1 -1
- package/cli/storybook-dist/assets/{NxAvatar.stories-DsYFMUh3.js → NxAvatar.stories-CwnK8AUF.js} +1 -1
- package/cli/storybook-dist/assets/{NxButton.stories-CHfNcqsc.js → NxButton.stories-ueYdosfQ.js} +8 -8
- package/cli/storybook-dist/assets/{NxNumberInput.stories-BFw_4vFE.js → NxNumberInput.stories-M5ZCLbrK.js} +1 -1
- package/cli/storybook-dist/assets/{NxPagination.stories-DVfxyw4M.js → NxPagination.stories-bxxUnHEL.js} +1 -1
- package/cli/storybook-dist/assets/{NxPointerHoldButton.stories-BzyxUWoZ.js → NxPointerHoldButton.stories-BHxB2kr5.js} +1 -1
- package/cli/storybook-dist/assets/{NxRangeInput.stories-DmRdzBc1.js → NxRangeInput.stories-BKfr-fp4.js} +6 -6
- package/cli/storybook-dist/assets/{NxSelectBox.stories-B1KkNUOf.js → NxSelectBox.stories-CG8FuTBq.js} +1 -1
- package/cli/storybook-dist/assets/{NxSlideRange.stories-CyOdvfQ6.js → NxSlideRange.stories-BRTFtMTL.js} +1 -1
- package/cli/storybook-dist/assets/{NxSwitch.stories-DrDBw0qp.js → NxSwitch.stories-Bwuyzn-R.js} +1 -1
- package/cli/storybook-dist/assets/{NxTextArea.stories-DTB2aqNS.js → NxTextArea.stories-COq2sGqu.js} +1 -1
- package/cli/storybook-dist/assets/{NxTextInput.stories-DU0rucmM.js → NxTextInput.stories-CjsBLz05.js} +1 -1
- package/cli/storybook-dist/assets/{RBAccordion.stories-DTfOtXtp.js → RBAccordion.stories-BARwuZ0Q.js} +3 -3
- package/cli/storybook-dist/assets/{RBAccordionGroup.stories-9y9BjrUe.js → RBAccordionGroup.stories-COrPxETW.js} +10 -10
- package/cli/storybook-dist/assets/{RBAlert.stories-DLTAv9fT.js → RBAlert.stories-BQrkjZPt.js} +3 -3
- package/cli/storybook-dist/assets/{RBBadge.stories-BNMACewA.js → RBBadge.stories-BTsLL-lK.js} +1 -1
- package/cli/storybook-dist/assets/{RBBattery.stories-B3kXMAt5.js → RBBattery.stories-DAeQdJbc.js} +1 -1
- package/cli/storybook-dist/assets/{RBCard.stories-Y-s8R2n7.js → RBCard.stories-HyhOE80R.js} +39 -39
- package/cli/storybook-dist/assets/{RBCheckBox.stories-DBuT9tL4.js → RBCheckBox.stories-KFk0WqX_.js} +1 -1
- package/cli/storybook-dist/assets/{RBCheckIconButton.stories-CWu1TL56.js → RBCheckIconButton.stories-CXbbktF5.js} +1 -1
- package/cli/storybook-dist/assets/{RBCheckLabelButton.stories-sCu2MGCX.js → RBCheckLabelButton.stories-DWfYz_9Z.js} +17 -17
- package/cli/storybook-dist/assets/{RBChipTab.stories-BX9qLJkR.js → RBChipTab.stories-JPEgVFAS.js} +5 -5
- package/cli/storybook-dist/assets/{RBChipsBoxTab.stories-35u1aJ-P.js → RBChipsBoxTab.stories-CTPuWXrQ.js} +1 -1
- package/cli/storybook-dist/assets/{RBColorIcons.stories-DAOZ5Ies.js → RBColorIcons.stories-DiFRZ5jk.js} +1 -1
- package/cli/storybook-dist/assets/RBCommand.stories-Pf1HAVIR.js +73 -0
- package/cli/storybook-dist/assets/{RBConfirm.stories-iMXcUh7Z.js → RBConfirm.stories-D1cEPUXk.js} +3 -3
- package/cli/storybook-dist/assets/{RBDateInput.stories-hK5rXECf.js → RBDateInput.stories-RPYpCjig.js} +1 -1
- package/cli/storybook-dist/assets/RBDialog.stories-DJH-0XSR.js +38 -0
- package/cli/storybook-dist/assets/{RBDivider.stories-BAK-iZ1Z.js → RBDivider.stories-uEj1vOgK.js} +1 -1
- package/cli/storybook-dist/assets/{RBDrawer.stories-B2nqf2Nh.js → RBDrawer.stories-BiMzElb2.js} +12 -12
- package/cli/storybook-dist/assets/RBDropdownMenu.stories-Da_TBkla.js +86 -0
- package/cli/storybook-dist/assets/{RBEmptyView.stories-nCenrgBh.js → RBEmptyView.stories-BHeKGfPS.js} +1 -1
- package/cli/storybook-dist/assets/{RBIconButton.stories-DRH7O3sp.js → RBIconButton.stories-NEsRFoYp.js} +1 -1
- package/cli/storybook-dist/assets/{RBIcons.stories-D3PyJXG8.js → RBIcons.stories-CcZ-TTLS.js} +1 -1
- package/cli/storybook-dist/assets/{RBInlineLabelButton.stories-modQbt10.js → RBInlineLabelButton.stories-B0wpdQyR.js} +1 -1
- package/cli/storybook-dist/assets/{RBJoyStick.stories-BY14qVgR.js → RBJoyStick.stories-DEgBou3K.js} +1 -1
- package/cli/storybook-dist/assets/{RBLabelButton.stories-DzF7vGwm.js → RBLabelButton.stories-DT8drIsF.js} +1 -1
- package/cli/storybook-dist/assets/{RBLight.stories-lF4FRmVh.js → RBLight.stories-Dh-aoeyG.js} +1 -1
- package/cli/storybook-dist/assets/{RBMenubar.stories-XhrI7bsV.js → RBMenubar.stories-D-H7UqVh.js} +1 -1
- package/cli/storybook-dist/assets/{RBMultiRangeInput.stories-DprllQDl.js → RBMultiRangeInput.stories-hlclv6jI.js} +1 -1
- package/cli/storybook-dist/assets/{RBPagination.stories-2v2gBJfC.js → RBPagination.stories-DWCeoZ_S.js} +1 -1
- package/cli/storybook-dist/assets/{RBPopover.stories-C8iLIZpv.js → RBPopover.stories-C514M09_.js} +1 -1
- package/cli/storybook-dist/assets/{RBPrompt.stories-Th_HrWHI.js → RBPrompt.stories-BSItvfiT.js} +1 -1
- package/cli/storybook-dist/assets/{RBRadioBox.stories-CoHuLaN3.js → RBRadioBox.stories-BBb4YbFU.js} +1 -1
- package/cli/storybook-dist/assets/{RBRadioButton.stories-DULxE_ff.js → RBRadioButton.stories-CXyOGJCv.js} +1 -1
- package/cli/storybook-dist/assets/{RBRangeDateInput.stories-D8A9KBSS.js → RBRangeDateInput.stories-qvhubu0e.js} +1 -1
- package/cli/storybook-dist/assets/{RBResizable.stories-C41QfrQ3.js → RBResizable.stories-CZKeyGjH.js} +14 -14
- package/cli/storybook-dist/assets/{RBSelectBox.stories-C1gNmwzw.js → RBSelectBox.stories-CRKP3ybf.js} +1 -1
- package/cli/storybook-dist/assets/RBSheet.stories-sCM3ZJUa.js +39 -0
- package/cli/storybook-dist/assets/{RBSideNumberInput.stories-9LlgQ8nh.js → RBSideNumberInput.stories-Bb7gw8RF.js} +3 -3
- package/cli/storybook-dist/assets/{RBSlider.stories-oUgo5K9d.js → RBSlider.stories-23OAQU5z.js} +3 -3
- package/cli/storybook-dist/assets/{RBSpinner.stories-DDpohbY2.js → RBSpinner.stories-2xcQdcmt.js} +1 -1
- package/cli/storybook-dist/assets/{RBSwitch.stories-gW-GN7QO.js → RBSwitch.stories-BACUaJm_.js} +7 -7
- package/cli/storybook-dist/assets/{RBTab.stories-CN-PV3HH.js → RBTab.stories-CDHE3sVs.js} +1 -1
- package/cli/storybook-dist/assets/{RBTable.stories-BAZLpxtM.js → RBTable.stories-C0Cfhfl7.js} +29 -29
- package/cli/storybook-dist/assets/{RBTableRow.stories-CwjVrszB.js → RBTableRow.stories-BF8kIkpp.js} +1 -1
- package/cli/storybook-dist/assets/{RBTabs.stories-JuEo2sUL.js → RBTabs.stories-BdJWRq1o.js} +7 -7
- package/cli/storybook-dist/assets/{RBTextArea.stories-D0_Pv4qZ.js → RBTextArea.stories-CGy2xeYH.js} +3 -3
- package/cli/storybook-dist/assets/{RBTextField.stories-CCsOvZqV.js → RBTextField.stories-IfUOzxCM.js} +15 -15
- package/cli/storybook-dist/assets/{RBTextInput.stories-Cccn3VNm.js → RBTextInput.stories-VjXNFo4R.js} +3 -3
- package/cli/storybook-dist/assets/{RBToast.stories-I5617t0K.js → RBToast.stories-BzcobblV.js} +1 -1
- package/cli/storybook-dist/assets/{RBToggle.stories-DsgKjGsJ.js → RBToggle.stories-DuLE5mKv.js} +4 -4
- package/cli/storybook-dist/assets/{RBToggleGroup.stories-BZEzSDuz.js → RBToggleGroup.stories-CuR0N0GJ.js} +5 -5
- package/cli/storybook-dist/assets/{RBTooltip.stories-4oSyAWsA.js → RBTooltip.stories--aAgNC8_.js} +1 -1
- package/cli/storybook-dist/assets/{SideNumberInput-DSKbd0bG.js → SideNumberInput-DyWQxYUj.js} +743 -743
- package/cli/storybook-dist/assets/{entry-preview-B35XREGs.js → entry-preview-D7IHsza_.js} +1 -1
- package/cli/storybook-dist/assets/{iframe-BB797lmL.js → iframe-CbaIp5I-.js} +2 -2
- package/cli/storybook-dist/assets/{index-BU2567EP.js → index-C6CBgMuG.js} +3 -3
- package/cli/storybook-dist/assets/{preview-C7DaSWyc.js → preview-B-iYLDuW.js} +2 -2
- package/cli/storybook-dist/assets/{preview-CbuRHit4.js → preview-CRWqc9DH.js} +1 -1
- package/cli/storybook-dist/assets/{react-resizable-panels.browser-ChIvlwo7.js → react-resizable-panels.browser-8hC8dr-6.js} +8 -8
- package/cli/storybook-dist/iframe.html +2 -2
- package/cli/storybook-dist/index.html +1 -1
- package/cli/storybook-dist/project.json +1 -1
- package/cli/templates/common/.mcp.json +8 -8
- package/cli/templates/common/README.md +1231 -1231
- package/cli/templates/common/assets/icon.svg +45 -45
- package/cli/templates/common/manifest.json +26 -26
- package/cli/templates/common/package.json +22 -22
- package/cli/templates/common/py/main.py +125 -125
- package/cli/templates/common/tsconfig.json +13 -13
- package/cli/templates/common/ui/content.tsx +216 -216
- package/cli/templates/common/ui/style.css +6 -6
- package/cli/templates/common/vite.config.ts +10 -10
- package/cli/templates/cpp/cpp/main.cpp +73 -73
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/__PLUGIN_SLUG__/node.py +25 -25
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/package.xml +10 -10
- package/cli/templates/ros2/ros2_ws/src/__PLUGIN_SLUG__/setup.py +18 -18
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/package.xml +11 -11
- package/cli/templates/ros2-cpp/ros2_ws/src/__PLUGIN_SLUG__/src/node.cpp +23 -23
- package/cli/vite.d.mts +25 -25
- package/cli/vite.mjs +292 -292
- package/package.json +3 -3
- package/cli/storybook-dist/assets/RBCommand.stories-BSqXDkKw.js +0 -73
- package/cli/storybook-dist/assets/RBDialog.stories-BAktz-ku.js +0 -38
- package/cli/storybook-dist/assets/RBDropdownMenu.stories-DbW2fWAj.js +0 -86
- package/cli/storybook-dist/assets/RBSheet.stories-_6VH-RUm.js +0 -39
package/cli/src/devUi.mjs
CHANGED
|
@@ -1,243 +1,247 @@
|
|
|
1
|
-
|
|
2
|
-
import { spawn, spawnSync } from "node:child_process";
|
|
3
|
-
import { createServer as createNetServer } from "node:net";
|
|
4
|
-
import { createRequire } from "node:module";
|
|
5
|
-
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, rmSync, watch } from "node:fs";
|
|
6
|
-
import { homedir } from "node:os";
|
|
7
|
-
import { dirname, resolve } from "node:path";
|
|
8
|
-
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { checkKitUpdate, findPluginRoot, hasBin, kitRoot, log, parseArgs, prompt } from "./util.mjs";
|
|
10
|
-
import { ensureLocalMuscat, GATEWAY_PORT, robotHasMuscat } from "./muscatLocal.mjs";
|
|
11
|
-
import { isRemoteRobot } from "./zenohDev.mjs";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const DEV_PLUGIN_PORT = 4181;
|
|
15
|
-
|
|
16
|
-
function getFreePort(preferred) {
|
|
17
|
-
return new Promise((res) => {
|
|
18
|
-
const srv = createNetServer();
|
|
19
|
-
srv.once("error", () => {
|
|
20
|
-
const s2 = createNetServer();
|
|
21
|
-
s2.listen(0, () => {
|
|
22
|
-
const { port } = s2.address();
|
|
23
|
-
s2.close(() => res(port));
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
srv.listen(preferred, () => srv.close(() => res(preferred)));
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const PREVIEW_PKG = "@rainbow-robotics/preview-host";
|
|
31
|
-
const CACHE_DIR = resolve(homedir(), ".muscat-pk");
|
|
32
|
-
const CACHE_ROOT = resolve(CACHE_DIR, "node_modules", "@rainbow-robotics", "preview-host");
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const DEV_OUT = ".muscat-dev";
|
|
36
|
-
|
|
37
|
-
function findNodeBin() {
|
|
38
|
-
if (typeof Bun === "undefined") return process.execPath;
|
|
39
|
-
for (const c of ["node", "node20", "node18"]) {
|
|
40
|
-
if (hasBin(c)) return c;
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function findPreviewHostRoot() {
|
|
46
|
-
try {
|
|
47
|
-
const req = createRequire(import.meta.url);
|
|
48
|
-
return dirname(req.resolve(`${PREVIEW_PKG}/package.json`));
|
|
49
|
-
} catch {
|
|
50
|
-
console.log("Try the sibling and cached package locations below.")
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const sibling = resolve(kitRoot, "../preview-host");
|
|
54
|
-
if (existsSync(resolve(sibling, "package.json"))) return sibling;
|
|
55
|
-
|
|
56
|
-
if (existsSync(resolve(CACHE_ROOT, "package.json"))) return CACHE_ROOT;
|
|
57
|
-
|
|
58
|
-
if (!hasBin("npm")) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
`preview-host를 찾을 수 없습니다.\n` +
|
|
61
|
-
`Node.js 20+ 를 설치하면 자동으로 준비됩니다: https://nodejs.org`,
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
log.step(`preview-host 설치 중 (~/.muscat-pk) — 첫 실행 시 한 번만 수행됩니다…`);
|
|
65
|
-
mkdirSync(CACHE_DIR, { recursive: true });
|
|
66
|
-
const r = spawnSync(
|
|
67
|
-
"npm",
|
|
68
|
-
["install", "--prefix", CACHE_DIR, "--save", PREVIEW_PKG],
|
|
69
|
-
{ stdio: "inherit" },
|
|
70
|
-
);
|
|
71
|
-
if (r.status !== 0) throw new Error("preview-host 설치 실패.");
|
|
72
|
-
if (!existsSync(resolve(CACHE_ROOT, "package.json"))) {
|
|
73
|
-
throw new Error("preview-host 설치 후에도 패키지를 찾을 수 없습니다.");
|
|
74
|
-
}
|
|
75
|
-
return CACHE_ROOT;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function syncAssets(pluginRoot, outDir) {
|
|
79
|
-
const assetsSrc = resolve(pluginRoot, "assets");
|
|
80
|
-
if (existsSync(assetsSrc)) cpSync(assetsSrc, resolve(outDir, "assets"), { recursive: true });
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
function stageDevAssets(pluginRoot) {
|
|
85
|
-
const outDir = resolve(pluginRoot, DEV_OUT);
|
|
86
|
-
mkdirSync(outDir, { recursive: true });
|
|
87
|
-
const manifestSrc = resolve(pluginRoot, "manifest.json");
|
|
88
|
-
if (existsSync(manifestSrc)) copyFileSync(manifestSrc, resolve(outDir, "manifest.json"));
|
|
89
|
-
syncAssets(pluginRoot, outDir);
|
|
90
|
-
return outDir;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function watchAssets(pluginRoot, outDir) {
|
|
94
|
-
const assetsSrc = resolve(pluginRoot, "assets");
|
|
95
|
-
if (!existsSync(assetsSrc)) return;
|
|
96
|
-
watch(assetsSrc, { recursive: true }, () => syncAssets(pluginRoot, outDir));
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
function findViteBin(pluginRoot) {
|
|
101
|
-
try {
|
|
102
|
-
const req = createRequire(resolve(pluginRoot, "package.json"));
|
|
103
|
-
const vitePkg = req.resolve("vite/package.json");
|
|
104
|
-
return resolve(dirname(vitePkg), "bin", "vite.js");
|
|
105
|
-
} catch {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function spawnPluginDevServer(pluginRoot, node, port, readyFile, sharedRuntimeBase) {
|
|
112
|
-
if (!node || !findViteBin(pluginRoot)) return null;
|
|
113
|
-
const runner = fileURLToPath(new URL("./pluginDevServer.mjs", import.meta.url));
|
|
114
|
-
|
|
115
|
-
rmSync(resolve(pluginRoot, "node_modules", ".vite"), { recursive: true, force: true });
|
|
116
|
-
|
|
117
|
-
return spawn(node, [runner, pluginRoot, String(port), readyFile], {
|
|
118
|
-
cwd: pluginRoot,
|
|
119
|
-
stdio: "inherit",
|
|
120
|
-
env: {
|
|
121
|
-
...process.env,
|
|
122
|
-
VITE_PLUGIN_PREVIEW: "true",
|
|
123
|
-
MUSCAT_PLUGIN_SHARED_RUNTIME_BASE: sharedRuntimeBase,
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
p
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
let
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
1
|
+
|
|
2
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
3
|
+
import { createServer as createNetServer } from "node:net";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, readFileSync, rmSync, watch } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { dirname, resolve } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { checkKitUpdate, findPluginRoot, hasBin, kitRoot, log, parseArgs, prompt } from "./util.mjs";
|
|
10
|
+
import { ensureLocalMuscat, GATEWAY_PORT, robotHasMuscat } from "./muscatLocal.mjs";
|
|
11
|
+
import { isRemoteRobot } from "./zenohDev.mjs";
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
const DEV_PLUGIN_PORT = 4181;
|
|
15
|
+
|
|
16
|
+
function getFreePort(preferred) {
|
|
17
|
+
return new Promise((res) => {
|
|
18
|
+
const srv = createNetServer();
|
|
19
|
+
srv.once("error", () => {
|
|
20
|
+
const s2 = createNetServer();
|
|
21
|
+
s2.listen(0, () => {
|
|
22
|
+
const { port } = s2.address();
|
|
23
|
+
s2.close(() => res(port));
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
srv.listen(preferred, () => srv.close(() => res(preferred)));
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const PREVIEW_PKG = "@rainbow-robotics/preview-host";
|
|
31
|
+
const CACHE_DIR = resolve(homedir(), ".muscat-pk");
|
|
32
|
+
const CACHE_ROOT = resolve(CACHE_DIR, "node_modules", "@rainbow-robotics", "preview-host");
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
const DEV_OUT = ".muscat-dev";
|
|
36
|
+
|
|
37
|
+
function findNodeBin() {
|
|
38
|
+
if (typeof Bun === "undefined") return process.execPath;
|
|
39
|
+
for (const c of ["node", "node20", "node18"]) {
|
|
40
|
+
if (hasBin(c)) return c;
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function findPreviewHostRoot() {
|
|
46
|
+
try {
|
|
47
|
+
const req = createRequire(import.meta.url);
|
|
48
|
+
return dirname(req.resolve(`${PREVIEW_PKG}/package.json`));
|
|
49
|
+
} catch {
|
|
50
|
+
console.log("Try the sibling and cached package locations below.")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const sibling = resolve(kitRoot, "../preview-host");
|
|
54
|
+
if (existsSync(resolve(sibling, "package.json"))) return sibling;
|
|
55
|
+
|
|
56
|
+
if (existsSync(resolve(CACHE_ROOT, "package.json"))) return CACHE_ROOT;
|
|
57
|
+
|
|
58
|
+
if (!hasBin("npm")) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`preview-host를 찾을 수 없습니다.\n` +
|
|
61
|
+
`Node.js 20+ 를 설치하면 자동으로 준비됩니다: https://nodejs.org`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
log.step(`preview-host 설치 중 (~/.muscat-pk) — 첫 실행 시 한 번만 수행됩니다…`);
|
|
65
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
66
|
+
const r = spawnSync(
|
|
67
|
+
"npm",
|
|
68
|
+
["install", "--prefix", CACHE_DIR, "--save", PREVIEW_PKG],
|
|
69
|
+
{ stdio: "inherit" },
|
|
70
|
+
);
|
|
71
|
+
if (r.status !== 0) throw new Error("preview-host 설치 실패.");
|
|
72
|
+
if (!existsSync(resolve(CACHE_ROOT, "package.json"))) {
|
|
73
|
+
throw new Error("preview-host 설치 후에도 패키지를 찾을 수 없습니다.");
|
|
74
|
+
}
|
|
75
|
+
return CACHE_ROOT;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function syncAssets(pluginRoot, outDir) {
|
|
79
|
+
const assetsSrc = resolve(pluginRoot, "assets");
|
|
80
|
+
if (existsSync(assetsSrc)) cpSync(assetsSrc, resolve(outDir, "assets"), { recursive: true });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
function stageDevAssets(pluginRoot) {
|
|
85
|
+
const outDir = resolve(pluginRoot, DEV_OUT);
|
|
86
|
+
mkdirSync(outDir, { recursive: true });
|
|
87
|
+
const manifestSrc = resolve(pluginRoot, "manifest.json");
|
|
88
|
+
if (existsSync(manifestSrc)) copyFileSync(manifestSrc, resolve(outDir, "manifest.json"));
|
|
89
|
+
syncAssets(pluginRoot, outDir);
|
|
90
|
+
return outDir;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function watchAssets(pluginRoot, outDir) {
|
|
94
|
+
const assetsSrc = resolve(pluginRoot, "assets");
|
|
95
|
+
if (!existsSync(assetsSrc)) return;
|
|
96
|
+
watch(assetsSrc, { recursive: true }, () => syncAssets(pluginRoot, outDir));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
function findViteBin(pluginRoot) {
|
|
101
|
+
try {
|
|
102
|
+
const req = createRequire(resolve(pluginRoot, "package.json"));
|
|
103
|
+
const vitePkg = req.resolve("vite/package.json");
|
|
104
|
+
return resolve(dirname(vitePkg), "bin", "vite.js");
|
|
105
|
+
} catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
function spawnPluginDevServer(pluginRoot, node, port, readyFile, sharedRuntimeBase) {
|
|
112
|
+
if (!node || !findViteBin(pluginRoot)) return null;
|
|
113
|
+
const runner = fileURLToPath(new URL("./pluginDevServer.mjs", import.meta.url));
|
|
114
|
+
|
|
115
|
+
rmSync(resolve(pluginRoot, "node_modules", ".vite"), { recursive: true, force: true });
|
|
116
|
+
|
|
117
|
+
return spawn(node, [runner, pluginRoot, String(port), readyFile], {
|
|
118
|
+
cwd: pluginRoot,
|
|
119
|
+
stdio: "inherit",
|
|
120
|
+
env: {
|
|
121
|
+
...process.env,
|
|
122
|
+
VITE_PLUGIN_PREVIEW: "true",
|
|
123
|
+
MUSCAT_PLUGIN_SHARED_RUNTIME_BASE: sharedRuntimeBase,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// The ready file is the signal and an exit the failure; the timeout only guards a hang. A cold vite start
|
|
129
|
+
// takes ~11s on Windows and more while `dev`'s first docker build loads the machine, so a tight limit
|
|
130
|
+
// stopped a healthy `dev`.
|
|
131
|
+
function waitForPluginDevPort(readyFile, proc, timeoutMs = 120_000) {
|
|
132
|
+
const start = Date.now();
|
|
133
|
+
const slow = setTimeout(() => log.info("plugin dev server (vite) is still starting…"), 15_000);
|
|
134
|
+
return new Promise((res, rej) => {
|
|
135
|
+
let exited = false;
|
|
136
|
+
proc.once("exit", (code) => {
|
|
137
|
+
exited = true;
|
|
138
|
+
rej(new Error(`plugin dev server exited before ready (code ${code ?? 0})`));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const tick = () => {
|
|
142
|
+
if (existsSync(readyFile)) {
|
|
143
|
+
try {
|
|
144
|
+
const { port } = JSON.parse(readFileSync(readyFile, "utf8"));
|
|
145
|
+
if (Number.isInteger(port)) return res(port);
|
|
146
|
+
} catch {
|
|
147
|
+
console.log("Keep polling until the ready file contains valid JSON.")
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (Date.now() - start > timeoutMs)
|
|
151
|
+
return rej(new Error("plugin dev server did not become ready in time"));
|
|
152
|
+
if (!exited) setTimeout(tick, 100);
|
|
153
|
+
};
|
|
154
|
+
tick();
|
|
155
|
+
}).finally(() => clearTimeout(slow));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export async function runDevUi(args = []) {
|
|
159
|
+
const parsed = parseArgs(args);
|
|
160
|
+
const requestedPort = Number(parsed.port ?? "4180");
|
|
161
|
+
const robotIp = parsed["robot-ip"] ?? process.env.MUSCAT_ROBOT_HOST ?? await prompt(" Robot IP (skip if no robot): ");
|
|
162
|
+
|
|
163
|
+
await checkKitUpdate();
|
|
164
|
+
const pluginRoot = findPluginRoot();
|
|
165
|
+
const outDir = stageDevAssets(pluginRoot);
|
|
166
|
+
const port = await getFreePort(requestedPort);
|
|
167
|
+
|
|
168
|
+
// No robot: the bundle talks to localhost:3000, so put a Muscat there (`dev` already did).
|
|
169
|
+
if (!isRemoteRobot(robotIp) && process.env.MUSCAT_PK_MANAGED_DEV !== "1") {
|
|
170
|
+
await ensureLocalMuscat().catch((e) => log.warn(`local Muscat: ${e.message}`));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
watchAssets(pluginRoot, outDir);
|
|
174
|
+
|
|
175
|
+
const node = findNodeBin();
|
|
176
|
+
const readyFile = resolve(outDir, "plugin-dev-port.json");
|
|
177
|
+
rmSync(readyFile, { force: true });
|
|
178
|
+
const sharedRuntimeBase = `http://localhost:${port}/plugin-shared`;
|
|
179
|
+
const viteProc = spawnPluginDevServer(
|
|
180
|
+
pluginRoot,
|
|
181
|
+
node,
|
|
182
|
+
DEV_PLUGIN_PORT,
|
|
183
|
+
readyFile,
|
|
184
|
+
sharedRuntimeBase,
|
|
185
|
+
);
|
|
186
|
+
let devPort = DEV_PLUGIN_PORT;
|
|
187
|
+
|
|
188
|
+
if (!viteProc) {
|
|
189
|
+
log.warn("vite not found — UI will not load. Run `npm install` in the plugin project.");
|
|
190
|
+
} else {
|
|
191
|
+
devPort = await waitForPluginDevPort(readyFile, viteProc);
|
|
192
|
+
viteProc.on("exit", (code) => {
|
|
193
|
+
if (code) log.warn(`plugin dev server exited (code ${code}) — UI won't load (is :${devPort} free?).`);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const previewRoot = findPreviewHostRoot();
|
|
198
|
+
const serveEntry = resolve(previewRoot, "serve.mjs");
|
|
199
|
+
if (!existsSync(resolve(previewRoot, "dist", "index.html"))) {
|
|
200
|
+
log.step("building preview-host bundle (first run)…");
|
|
201
|
+
await new Promise((res, rej) => {
|
|
202
|
+
const p = spawn(node ?? process.execPath, [resolve(previewRoot, "build.mjs")], {
|
|
203
|
+
stdio: "inherit",
|
|
204
|
+
env: { ...process.env, VITE_PLUGIN_PREVIEW: "true" },
|
|
205
|
+
});
|
|
206
|
+
p.on("exit", (c) => (c === 0 ? res() : rej(new Error("preview-host build failed"))));
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const child = spawn(
|
|
211
|
+
node ?? process.execPath,
|
|
212
|
+
[
|
|
213
|
+
serveEntry,
|
|
214
|
+
"--plugin", outDir,
|
|
215
|
+
"--port", String(port),
|
|
216
|
+
"--dev-server-url", `http://localhost:${devPort}`,
|
|
217
|
+
// A remote robot turns the bundle into that robot's Muscat UI; localhost stays the mock preview.
|
|
218
|
+
...(isRemoteRobot(robotIp) ? ["--robot-host", robotIp] : []),
|
|
219
|
+
// The dev plugin's socket goes to the robot's gateway when the robot runs Muscat (the UI is
|
|
220
|
+
// that robot's Muscat then); otherwise to the local runtime.
|
|
221
|
+
...((await robotHasMuscat(robotIp)) ? ["--socket-url", `ws://${robotIp}:${GATEWAY_PORT}`] : []),
|
|
222
|
+
],
|
|
223
|
+
// preview-host only prints its address and paths; the "UI →" line below says what matters.
|
|
224
|
+
{ stdio: ["inherit", "ignore", "inherit"] },
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
for (let i = 0; i < 50 && !(await fetch(`http://localhost:${port}/`).then(() => true, () => false)); i++)
|
|
228
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
229
|
+
log.ok(`UI → http://localhost:${port}`);
|
|
230
|
+
|
|
231
|
+
let cleaned = false;
|
|
232
|
+
const cleanup = () => {
|
|
233
|
+
if (cleaned) return;
|
|
234
|
+
cleaned = true;
|
|
235
|
+
if (viteProc && !viteProc.killed && viteProc.exitCode === null) viteProc.kill();
|
|
236
|
+
if (!child.killed && child.exitCode === null) child.kill();
|
|
237
|
+
};
|
|
238
|
+
process.once("SIGINT", cleanup);
|
|
239
|
+
process.once("SIGTERM", cleanup);
|
|
240
|
+
process.once("SIGHUP", cleanup);
|
|
241
|
+
child.on("exit", (code) => {
|
|
242
|
+
cleanup();
|
|
243
|
+
process.exit(code ?? 0);
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export { findPluginRoot, findPreviewHostRoot };
|
package/cli/src/esbuild.mjs
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
// When compiled with `bun --compile`, esbuild's native subprocess binary is
|
|
2
|
-
// not bundled. Use Bun's built-in bundler instead.
|
|
3
|
-
async function buildWithBun(options) {
|
|
4
|
-
const { entryPoints, outfile, format, minify, loader, define, external } = options;
|
|
5
|
-
const { dirname } = await import("node:path");
|
|
6
|
-
const result = await Bun.build({
|
|
7
|
-
entrypoints: entryPoints,
|
|
8
|
-
outdir: dirname(outfile),
|
|
9
|
-
format: format ?? "esm",
|
|
10
|
-
minify: minify ?? false,
|
|
11
|
-
loader,
|
|
12
|
-
define,
|
|
13
|
-
external,
|
|
14
|
-
target: "node",
|
|
15
|
-
throw: false,
|
|
16
|
-
});
|
|
17
|
-
if (!result.success) {
|
|
18
|
-
for (const log of result.logs) console.error(log.message);
|
|
19
|
-
throw new Error("Bun.build() failed");
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
async function buildWithWasm(options) {
|
|
24
|
-
const wasm = await import("esbuild-wasm");
|
|
25
|
-
return wasm.build(options);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function isNativeMissing(err) {
|
|
29
|
-
const msg = String(err?.message || err?.code || err || "");
|
|
30
|
-
return (
|
|
31
|
-
msg.includes("another platform") ||
|
|
32
|
-
msg.includes("Cannot find module") ||
|
|
33
|
-
msg.includes("Cannot find package") ||
|
|
34
|
-
msg.includes("not found") ||
|
|
35
|
-
msg.includes("No such file") ||
|
|
36
|
-
msg.includes("ENOENT") ||
|
|
37
|
-
msg.includes("MODULE_NOT_FOUND")
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export async function buildWithFallback(options) {
|
|
42
|
-
if (typeof Bun !== "undefined") return buildWithBun(options);
|
|
43
|
-
|
|
44
|
-
// Try native esbuild (faster, no extra setup). Falls back to wasm when:
|
|
45
|
-
// - esbuild was not installed (removed from hard dependencies to avoid
|
|
46
|
-
// postinstall script blocking npm i -g on Windows)
|
|
47
|
-
// - binary was built for a different platform
|
|
48
|
-
try {
|
|
49
|
-
const native = await import("esbuild");
|
|
50
|
-
return await native.build(options);
|
|
51
|
-
} catch (err) {
|
|
52
|
-
if (!isNativeMissing(err)) throw err;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return buildWithWasm(options);
|
|
56
|
-
}
|
|
1
|
+
// When compiled with `bun --compile`, esbuild's native subprocess binary is
|
|
2
|
+
// not bundled. Use Bun's built-in bundler instead.
|
|
3
|
+
async function buildWithBun(options) {
|
|
4
|
+
const { entryPoints, outfile, format, minify, loader, define, external } = options;
|
|
5
|
+
const { dirname } = await import("node:path");
|
|
6
|
+
const result = await Bun.build({
|
|
7
|
+
entrypoints: entryPoints,
|
|
8
|
+
outdir: dirname(outfile),
|
|
9
|
+
format: format ?? "esm",
|
|
10
|
+
minify: minify ?? false,
|
|
11
|
+
loader,
|
|
12
|
+
define,
|
|
13
|
+
external,
|
|
14
|
+
target: "node",
|
|
15
|
+
throw: false,
|
|
16
|
+
});
|
|
17
|
+
if (!result.success) {
|
|
18
|
+
for (const log of result.logs) console.error(log.message);
|
|
19
|
+
throw new Error("Bun.build() failed");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function buildWithWasm(options) {
|
|
24
|
+
const wasm = await import("esbuild-wasm");
|
|
25
|
+
return wasm.build(options);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isNativeMissing(err) {
|
|
29
|
+
const msg = String(err?.message || err?.code || err || "");
|
|
30
|
+
return (
|
|
31
|
+
msg.includes("another platform") ||
|
|
32
|
+
msg.includes("Cannot find module") ||
|
|
33
|
+
msg.includes("Cannot find package") ||
|
|
34
|
+
msg.includes("not found") ||
|
|
35
|
+
msg.includes("No such file") ||
|
|
36
|
+
msg.includes("ENOENT") ||
|
|
37
|
+
msg.includes("MODULE_NOT_FOUND")
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function buildWithFallback(options) {
|
|
42
|
+
if (typeof Bun !== "undefined") return buildWithBun(options);
|
|
43
|
+
|
|
44
|
+
// Try native esbuild (faster, no extra setup). Falls back to wasm when:
|
|
45
|
+
// - esbuild was not installed (removed from hard dependencies to avoid
|
|
46
|
+
// postinstall script blocking npm i -g on Windows)
|
|
47
|
+
// - binary was built for a different platform
|
|
48
|
+
try {
|
|
49
|
+
const native = await import("esbuild");
|
|
50
|
+
return await native.build(options);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
if (!isNativeMissing(err)) throw err;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return buildWithWasm(options);
|
|
56
|
+
}
|