jsmdcui 0.10.1 → 0.11.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/CHANGELOG.md +56 -0
- package/README.md +69 -29
- package/package.json +1 -1
- package/runmd.mjs +51 -7
- package/runtime/help/help.md +69 -29
- package/runtime/jsplugins/example/example.js +3 -1
- package/single-exe/README.md +82 -25
- package/single-exe/README.md-rpc.js +623 -0
- package/single-exe/README.md-server.js +127 -0
- package/single-exe/README.md.back.js +2 -0
- package/single-exe/README.md.front.js +27 -0
- package/single-exe/README.md.html +325 -0
- package/single-exe/compiled.js +52 -0
- package/src/index.js +227 -20
- package/src/plugins/js-bridge.js +5 -0
- package/tests/compiled-runtime.test.js +68 -1
- package/tests/demo.test.js +136 -1
- package/tests/js-plugin-prompts.test.js +30 -0
- package/tests/wui-responsive-images.test.js +21 -2
- package/tests/wui.test.js +31 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
All notable user-visible changes to jsmdcui are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.11.1] - 2026-07-26
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Accept a bare `global.MDCUI_MAIN` path in forwarded build arguments by
|
|
10
|
+
automatically encoding non-primitive define values as JavaScript strings.
|
|
11
|
+
|
|
12
|
+
## [0.11.0] - 2026-07-26
|
|
13
|
+
|
|
14
|
+
This release adds custom Markdown-app embedding for Bun single-file
|
|
15
|
+
executables, with explicit per-buffer selection between embedded and
|
|
16
|
+
filesystem modules in both TUI and WUI.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Add the build-time `global.MDCUI_MAIN` string define for embedding a custom
|
|
21
|
+
Markdown app together with its generated front, RPC, back, HTML, and server
|
|
22
|
+
modules. Build preparation resolves and validates the source, copies it into
|
|
23
|
+
the bundled demos, derives `global.MDCUI_MAIN_BASE`, and selects the app on a
|
|
24
|
+
no-argument launch.
|
|
25
|
+
- Add a bundling mode to `extractJs()` and `createWui()`. It emits a
|
|
26
|
+
browser-only `.tmpfs.js` front module and a `.tmpfi.js` installer that exposes
|
|
27
|
+
the front exports on `window`, then makes the bundled HTML load that entry.
|
|
28
|
+
- Add embedded WUI server startup and report whether WUI is starting an
|
|
29
|
+
embedded or external server before launch.
|
|
30
|
+
- Add `micro.CurPane().Buf.MdcuiModuleSource`, returning `embedded` or
|
|
31
|
+
`external`, and show the value in the bundled `showpath` example.
|
|
32
|
+
- Allow Unicode letters and numbers, including Chinese, in custom demo names
|
|
33
|
+
while continuing to reject whitespace and path separators.
|
|
34
|
+
- Show `global.MDCUI_MAIN` and the generated `global.MDCUI_MAIN_BASE` in
|
|
35
|
+
`--version` distribution settings.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- Track embedded-module selection per buffer. The configured demo uses
|
|
40
|
+
embedded TUI front/RPC and WUI server modules when its local byte length
|
|
41
|
+
matches the bundled Markdown. Missing or overwritten copies are written
|
|
42
|
+
first and then use embedded modules; other files and changed-size demos use
|
|
43
|
+
filesystem companions.
|
|
44
|
+
- Document presence-based `MDCUI_*` defines with `=1`, supported build-flag
|
|
45
|
+
combinations, and commands for switching a TUI-default build to WUI or a
|
|
46
|
+
WUI-default build to TUI.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- Bundle and load the configured app's front, RPC, back, server, and dependency
|
|
51
|
+
graph so custom apps with companion imports can run from a single
|
|
52
|
+
executable.
|
|
53
|
+
- Keep unrelated Markdown buffers on external modules instead of reusing the
|
|
54
|
+
embedded main app's front and RPC modules.
|
|
55
|
+
- Use the bundled file's byte length after `MDCUI_OVERWRITE_DEMO` replaces a
|
|
56
|
+
stale local demo, ensuring that the overwritten app selects embedded
|
|
57
|
+
modules.
|
|
58
|
+
- Install WUI front exports on `window` without relying on the generated front
|
|
59
|
+
module's process-dependent or self-import path.
|
|
60
|
+
|
|
5
61
|
## [0.10.1] - 2026-07-25
|
|
6
62
|
|
|
7
63
|
### Fixed
|
package/README.md
CHANGED
|
@@ -757,54 +757,94 @@ both are equivalent to `-encoding mdcui`.
|
|
|
757
757
|
|
|
758
758
|
### Build-time distribution constants
|
|
759
759
|
|
|
760
|
-
|
|
760
|
+
The following switch defines are presence-based: the program checks whether
|
|
761
|
+
they were passed, not whether their values are true. Consequently, `=0` and
|
|
762
|
+
`=false` still enable a switch. Omit a define entirely to disable it. Examples
|
|
763
|
+
use `=1` to make this explicit.
|
|
764
|
+
|
|
765
|
+
- `MDCUI_DEFAULT_EDIT=1`: open files as editable text by default.
|
|
766
|
+
- `MDCUI_DEFAULT_DEMO=1`: add `--demo` when launched without arguments.
|
|
767
|
+
- `MDCUI_DEFAULT_DEMO_WUI=1`: add `--wui` when launched without arguments.
|
|
768
|
+
- `MDCUI_OVERWRITE_DEMO=1`: add `--overwrite-demo`; this modifies a selected
|
|
769
|
+
demo but does not select one by itself.
|
|
770
|
+
- `global.MDCUI_MAIN=<path>.md`: embed a custom Markdown application and its
|
|
771
|
+
generated front, RPC, back, HTML, and server modules. When this define is
|
|
772
|
+
forwarded after `--build-exe` or `--build-for`, a non-primitive value such as
|
|
773
|
+
a bare path is automatically encoded as a JavaScript string. An explicitly
|
|
774
|
+
quoted string remains supported.
|
|
775
|
+
- `global.MDCUI_MAIN_BASE`: internal define generated automatically from
|
|
776
|
+
`global.MDCUI_MAIN`; do not pass it manually.
|
|
777
|
+
|
|
778
|
+
Place every build define after `--build-exe`, or after the target argument of
|
|
779
|
+
`--build-for`. Choose at most one of `MDCUI_DEFAULT_EDIT`,
|
|
780
|
+
`MDCUI_DEFAULT_DEMO`, and `MDCUI_DEFAULT_DEMO_WUI`.
|
|
781
|
+
|
|
782
|
+
| Build defines | No-argument launch | Open the same app in the other UI |
|
|
783
|
+
| --- | --- | --- |
|
|
784
|
+
| none | normal CLI/TUI | `./mdcui --wui app.md` |
|
|
785
|
+
| `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
|
|
786
|
+
| `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
|
|
787
|
+
| `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
|
|
788
|
+
| `global.MDCUI_MAIN=../中文工具.md` | embedded custom TUI | `./mdcui --wui --demo-中文工具` |
|
|
789
|
+
| MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | embedded custom WUI | `./mdcui --tui --demo-中文工具` |
|
|
761
790
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
791
|
+
Any explicit runtime argument suppresses the no-argument demo/WUI injection.
|
|
792
|
+
That is why the commands in the last column repeat `--demo` or
|
|
793
|
+
`--demo-中文工具`; `./mdcui --wui` by itself does not implicitly select a custom
|
|
794
|
+
main application.
|
|
765
795
|
|
|
766
|
-
|
|
767
|
-
`MDCUI_OVERWRITE_DEMO` is an optional modifier for the demo or WUI mode.
|
|
768
|
-
These are presence-based constants, so their build values do not require
|
|
769
|
-
shell-quoted strings:
|
|
796
|
+
To package `../中文工具.md` as a TUI by default:
|
|
770
797
|
|
|
771
798
|
```sh
|
|
772
|
-
bun src/index.js --build-exe
|
|
773
|
-
|
|
799
|
+
bun src/index.js --build-exe \
|
|
800
|
+
--define global.MDCUI_MAIN=../中文工具.md
|
|
774
801
|
|
|
775
|
-
|
|
802
|
+
./mdcui
|
|
803
|
+
./mdcui --wui --demo-中文工具
|
|
804
|
+
```
|
|
776
805
|
|
|
777
|
-
To
|
|
778
|
-
|
|
806
|
+
To package the same application as a WUI by default and explicitly switch back
|
|
807
|
+
to its TUI:
|
|
779
808
|
|
|
780
809
|
```sh
|
|
781
810
|
bun src/index.js --build-exe \
|
|
782
|
-
--define
|
|
783
|
-
--define
|
|
811
|
+
--define global.MDCUI_MAIN=../中文工具.md \
|
|
812
|
+
--define MDCUI_DEFAULT_DEMO_WUI=1
|
|
813
|
+
|
|
814
|
+
./mdcui
|
|
815
|
+
./mdcui --tui --demo-中文工具
|
|
784
816
|
```
|
|
785
817
|
|
|
786
|
-
The
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
and
|
|
790
|
-
|
|
791
|
-
|
|
818
|
+
The `MDCUI_MAIN` basename must end with lowercase `.md`. Its demo-name portion
|
|
819
|
+
must start with a Unicode letter or number and may contain Unicode
|
|
820
|
+
letters/numbers (including Chinese), combining marks, dots, underscores, and
|
|
821
|
+
hyphens. Whitespace and path separators are not allowed.
|
|
822
|
+
|
|
823
|
+
When the configured custom demo is selected and its local Markdown byte length
|
|
824
|
+
matches the embedded copy, TUI uses the embedded front/RPC modules and WUI uses
|
|
825
|
+
the embedded server. A missing demo, or one selected with
|
|
826
|
+
`MDCUI_OVERWRITE_DEMO=1`, is first written from the embedded copy and then uses
|
|
827
|
+
embedded modules. A different byte length prints a warning and uses filesystem
|
|
828
|
+
companion modules. Directly opening `./mdcui app.md` or
|
|
829
|
+
`./mdcui --wui app.md` has no demo provenance and therefore uses filesystem
|
|
830
|
+
modules even if the basename matches `MDCUI_MAIN`.
|
|
792
831
|
|
|
793
|
-
To
|
|
794
|
-
|
|
832
|
+
To retain the older repository-root `testapp.md` distribution instead, build a
|
|
833
|
+
TUI with:
|
|
795
834
|
|
|
796
835
|
```sh
|
|
797
836
|
bun src/index.js --build-exe \
|
|
798
|
-
--define
|
|
799
|
-
--define MDCUI_OVERWRITE_DEMO=
|
|
837
|
+
--define MDCUI_DEFAULT_DEMO=1 \
|
|
838
|
+
--define MDCUI_OVERWRITE_DEMO=1
|
|
800
839
|
```
|
|
801
840
|
|
|
802
|
-
|
|
841
|
+
For a default WUI, replace `MDCUI_DEFAULT_DEMO` with
|
|
842
|
+
`MDCUI_DEFAULT_DEMO_WUI`.
|
|
803
843
|
|
|
804
844
|
You can rename and distribute the resulting binary. It contains the Bun
|
|
805
|
-
runtime, jsmdcui, the packed runtime assets, and
|
|
806
|
-
directory must remain writable because launching
|
|
807
|
-
|
|
845
|
+
runtime, jsmdcui, the packed runtime assets, and the configured demo or custom
|
|
846
|
+
main application. The target directory must remain writable because launching
|
|
847
|
+
an application creates its Markdown file and generated companion files there.
|
|
808
848
|
|
|
809
849
|
## Development
|
|
810
850
|
|
package/package.json
CHANGED
package/runmd.mjs
CHANGED
|
@@ -54,6 +54,7 @@ export async function main(tuiWidth=30, {
|
|
|
54
54
|
mdpath: requestedMdpath = null,
|
|
55
55
|
overwriteDemo = process.argv.includes("--overwrite-demo"),
|
|
56
56
|
printUi = process.argv.includes("--print-ui"),
|
|
57
|
+
useBundledMdcuiServer = false,
|
|
57
58
|
} = {})
|
|
58
59
|
{
|
|
59
60
|
const explicitMdpath = process.argv.find(i=>i.endsWith('.md'))
|
|
@@ -99,7 +100,20 @@ export async function main(tuiWidth=30, {
|
|
|
99
100
|
|
|
100
101
|
|
|
101
102
|
const serverPath = mdpath + "-server.js"
|
|
102
|
-
const
|
|
103
|
+
const useEmbeddedMdcuiServer = Boolean(
|
|
104
|
+
global.MDCUI_MAIN && useBundledMdcuiServer
|
|
105
|
+
)
|
|
106
|
+
cse(
|
|
107
|
+
`[mdcui] Starting ${useEmbeddedMdcuiServer ? "embedded" : "external"} `
|
|
108
|
+
+ `WUI server: ${
|
|
109
|
+
useEmbeddedMdcuiServer
|
|
110
|
+
? String(global.MDCUI_MAIN)
|
|
111
|
+
: path.resolve(serverPath)
|
|
112
|
+
}`
|
|
113
|
+
)
|
|
114
|
+
const svmod = useEmbeddedMdcuiServer
|
|
115
|
+
? await import(global.MDCUI_MAIN + "-server.js")
|
|
116
|
+
: await import(pathToFileURL(path.resolve(serverPath)).href)
|
|
103
117
|
|
|
104
118
|
cse("\n\n"+mda('# Server'))
|
|
105
119
|
svmod.main();
|
|
@@ -109,7 +123,7 @@ export async function main(tuiWidth=30, {
|
|
|
109
123
|
// Exports
|
|
110
124
|
|
|
111
125
|
|
|
112
|
-
export async function extractJs(md,mdpath)
|
|
126
|
+
export async function extractJs(md,mdpath,{ bundling = false } = {})
|
|
113
127
|
{
|
|
114
128
|
const mdb = path.basename(mdpath)
|
|
115
129
|
|
|
@@ -128,16 +142,23 @@ export async function extractJs(md,mdpath)
|
|
|
128
142
|
}
|
|
129
143
|
)
|
|
130
144
|
|
|
145
|
+
const frontSource = sctags
|
|
131
146
|
sctags = "#!/usr/bin/env bun" + `
|
|
132
147
|
|
|
133
148
|
import { rpc as wuiRpcClient } from "./${mdb}-rpc.js";
|
|
134
|
-
let rpc =
|
|
149
|
+
let rpc = null
|
|
135
150
|
if(globalThis.process)
|
|
136
|
-
|
|
151
|
+
{
|
|
152
|
+
rpc = await import(
|
|
153
|
+
"./" +
|
|
154
|
+
(global.MDCUI_MAIN_BASE||"${mdb}") +
|
|
155
|
+
".back.js"
|
|
156
|
+
) ;
|
|
157
|
+
}
|
|
137
158
|
else
|
|
138
159
|
rpc = wuiRpcClient ;
|
|
139
160
|
|
|
140
|
-
` +
|
|
161
|
+
` + frontSource + `
|
|
141
162
|
|
|
142
163
|
if (typeof window !== "undefined")
|
|
143
164
|
{
|
|
@@ -152,6 +173,28 @@ export async function extractJs(md,mdpath)
|
|
|
152
173
|
|
|
153
174
|
await Bun.write(sctagsp,sctags);
|
|
154
175
|
logWroteFile("front", sctagsp)
|
|
176
|
+
|
|
177
|
+
if (bundling) {
|
|
178
|
+
const bundledFrontSource = "#!/usr/bin/env bun" + `
|
|
179
|
+
|
|
180
|
+
import { rpc as wuiRpcClient } from "./${mdb}-rpc.js";
|
|
181
|
+
const rpc = wuiRpcClient;
|
|
182
|
+
|
|
183
|
+
` + frontSource
|
|
184
|
+
const bundledFrontPath = mdpath + ".tmpfs.js"
|
|
185
|
+
await Bun.write(bundledFrontPath, bundledFrontSource)
|
|
186
|
+
logWroteFile("bundling front", bundledFrontPath)
|
|
187
|
+
|
|
188
|
+
const bundledImportPath = mdpath + ".tmpfi.js"
|
|
189
|
+
await Bun.write(
|
|
190
|
+
bundledImportPath,
|
|
191
|
+
`import * as frontMod from "./${mdb}.tmpfs.js";
|
|
192
|
+
|
|
193
|
+
Object.assign(window, frontMod);
|
|
194
|
+
`,
|
|
195
|
+
)
|
|
196
|
+
logWroteFile("bundling import", bundledImportPath)
|
|
197
|
+
}
|
|
155
198
|
|
|
156
199
|
sctagsp = mdpath + ".back.js"
|
|
157
200
|
sctags = "#!/usr/bin/env bun\n\n"
|
|
@@ -354,7 +397,7 @@ export function wrapWuiHeadingSections(html)
|
|
|
354
397
|
return output;
|
|
355
398
|
}
|
|
356
399
|
|
|
357
|
-
export async function createWui(md,mdpath) // HTML
|
|
400
|
+
export async function createWui(md,mdpath,{ bundling = false } = {}) // HTML
|
|
358
401
|
{
|
|
359
402
|
const eventsById = fenceEventMap(md)
|
|
360
403
|
|
|
@@ -397,7 +440,8 @@ img {
|
|
|
397
440
|
height: auto;
|
|
398
441
|
}
|
|
399
442
|
</style>`;
|
|
400
|
-
const
|
|
443
|
+
const moduleEntry = bundling ? `${mdb}.tmpfi.js` : `${mdb}.front.js`;
|
|
444
|
+
const moduleScript = `<scr`+`ipt type="module" src="./${moduleEntry}"></scr`+`ipt>`;
|
|
401
445
|
const isFullHtmlDocument = /^\s*<!doctype html>/i.test(md);
|
|
402
446
|
if (!isFullHtmlDocument) {
|
|
403
447
|
md = `<!doctype html>
|
package/runtime/help/help.md
CHANGED
|
@@ -757,54 +757,94 @@ both are equivalent to `-encoding mdcui`.
|
|
|
757
757
|
|
|
758
758
|
### Build-time distribution constants
|
|
759
759
|
|
|
760
|
-
|
|
760
|
+
The following switch defines are presence-based: the program checks whether
|
|
761
|
+
they were passed, not whether their values are true. Consequently, `=0` and
|
|
762
|
+
`=false` still enable a switch. Omit a define entirely to disable it. Examples
|
|
763
|
+
use `=1` to make this explicit.
|
|
764
|
+
|
|
765
|
+
- `MDCUI_DEFAULT_EDIT=1`: open files as editable text by default.
|
|
766
|
+
- `MDCUI_DEFAULT_DEMO=1`: add `--demo` when launched without arguments.
|
|
767
|
+
- `MDCUI_DEFAULT_DEMO_WUI=1`: add `--wui` when launched without arguments.
|
|
768
|
+
- `MDCUI_OVERWRITE_DEMO=1`: add `--overwrite-demo`; this modifies a selected
|
|
769
|
+
demo but does not select one by itself.
|
|
770
|
+
- `global.MDCUI_MAIN=<path>.md`: embed a custom Markdown application and its
|
|
771
|
+
generated front, RPC, back, HTML, and server modules. When this define is
|
|
772
|
+
forwarded after `--build-exe` or `--build-for`, a non-primitive value such as
|
|
773
|
+
a bare path is automatically encoded as a JavaScript string. An explicitly
|
|
774
|
+
quoted string remains supported.
|
|
775
|
+
- `global.MDCUI_MAIN_BASE`: internal define generated automatically from
|
|
776
|
+
`global.MDCUI_MAIN`; do not pass it manually.
|
|
777
|
+
|
|
778
|
+
Place every build define after `--build-exe`, or after the target argument of
|
|
779
|
+
`--build-for`. Choose at most one of `MDCUI_DEFAULT_EDIT`,
|
|
780
|
+
`MDCUI_DEFAULT_DEMO`, and `MDCUI_DEFAULT_DEMO_WUI`.
|
|
781
|
+
|
|
782
|
+
| Build defines | No-argument launch | Open the same app in the other UI |
|
|
783
|
+
| --- | --- | --- |
|
|
784
|
+
| none | normal CLI/TUI | `./mdcui --wui app.md` |
|
|
785
|
+
| `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
|
|
786
|
+
| `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
|
|
787
|
+
| `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
|
|
788
|
+
| `global.MDCUI_MAIN=../中文工具.md` | embedded custom TUI | `./mdcui --wui --demo-中文工具` |
|
|
789
|
+
| MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | embedded custom WUI | `./mdcui --tui --demo-中文工具` |
|
|
761
790
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
791
|
+
Any explicit runtime argument suppresses the no-argument demo/WUI injection.
|
|
792
|
+
That is why the commands in the last column repeat `--demo` or
|
|
793
|
+
`--demo-中文工具`; `./mdcui --wui` by itself does not implicitly select a custom
|
|
794
|
+
main application.
|
|
765
795
|
|
|
766
|
-
|
|
767
|
-
`MDCUI_OVERWRITE_DEMO` is an optional modifier for the demo or WUI mode.
|
|
768
|
-
These are presence-based constants, so their build values do not require
|
|
769
|
-
shell-quoted strings:
|
|
796
|
+
To package `../中文工具.md` as a TUI by default:
|
|
770
797
|
|
|
771
798
|
```sh
|
|
772
|
-
bun src/index.js --build-exe
|
|
773
|
-
|
|
799
|
+
bun src/index.js --build-exe \
|
|
800
|
+
--define global.MDCUI_MAIN=../中文工具.md
|
|
774
801
|
|
|
775
|
-
|
|
802
|
+
./mdcui
|
|
803
|
+
./mdcui --wui --demo-中文工具
|
|
804
|
+
```
|
|
776
805
|
|
|
777
|
-
To
|
|
778
|
-
|
|
806
|
+
To package the same application as a WUI by default and explicitly switch back
|
|
807
|
+
to its TUI:
|
|
779
808
|
|
|
780
809
|
```sh
|
|
781
810
|
bun src/index.js --build-exe \
|
|
782
|
-
--define
|
|
783
|
-
--define
|
|
811
|
+
--define global.MDCUI_MAIN=../中文工具.md \
|
|
812
|
+
--define MDCUI_DEFAULT_DEMO_WUI=1
|
|
813
|
+
|
|
814
|
+
./mdcui
|
|
815
|
+
./mdcui --tui --demo-中文工具
|
|
784
816
|
```
|
|
785
817
|
|
|
786
|
-
The
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
and
|
|
790
|
-
|
|
791
|
-
|
|
818
|
+
The `MDCUI_MAIN` basename must end with lowercase `.md`. Its demo-name portion
|
|
819
|
+
must start with a Unicode letter or number and may contain Unicode
|
|
820
|
+
letters/numbers (including Chinese), combining marks, dots, underscores, and
|
|
821
|
+
hyphens. Whitespace and path separators are not allowed.
|
|
822
|
+
|
|
823
|
+
When the configured custom demo is selected and its local Markdown byte length
|
|
824
|
+
matches the embedded copy, TUI uses the embedded front/RPC modules and WUI uses
|
|
825
|
+
the embedded server. A missing demo, or one selected with
|
|
826
|
+
`MDCUI_OVERWRITE_DEMO=1`, is first written from the embedded copy and then uses
|
|
827
|
+
embedded modules. A different byte length prints a warning and uses filesystem
|
|
828
|
+
companion modules. Directly opening `./mdcui app.md` or
|
|
829
|
+
`./mdcui --wui app.md` has no demo provenance and therefore uses filesystem
|
|
830
|
+
modules even if the basename matches `MDCUI_MAIN`.
|
|
792
831
|
|
|
793
|
-
To
|
|
794
|
-
|
|
832
|
+
To retain the older repository-root `testapp.md` distribution instead, build a
|
|
833
|
+
TUI with:
|
|
795
834
|
|
|
796
835
|
```sh
|
|
797
836
|
bun src/index.js --build-exe \
|
|
798
|
-
--define
|
|
799
|
-
--define MDCUI_OVERWRITE_DEMO=
|
|
837
|
+
--define MDCUI_DEFAULT_DEMO=1 \
|
|
838
|
+
--define MDCUI_OVERWRITE_DEMO=1
|
|
800
839
|
```
|
|
801
840
|
|
|
802
|
-
|
|
841
|
+
For a default WUI, replace `MDCUI_DEFAULT_DEMO` with
|
|
842
|
+
`MDCUI_DEFAULT_DEMO_WUI`.
|
|
803
843
|
|
|
804
844
|
You can rename and distribute the resulting binary. It contains the Bun
|
|
805
|
-
runtime, jsmdcui, the packed runtime assets, and
|
|
806
|
-
directory must remain writable because launching
|
|
807
|
-
|
|
845
|
+
runtime, jsmdcui, the packed runtime assets, and the configured demo or custom
|
|
846
|
+
main application. The target directory must remain writable because launching
|
|
847
|
+
an application creates its Markdown file and generated companion files there.
|
|
808
848
|
|
|
809
849
|
## Development
|
|
810
850
|
|
|
@@ -69,8 +69,10 @@ micro.on("init", () => {
|
|
|
69
69
|
|
|
70
70
|
//micro.alert(micro.getLine())
|
|
71
71
|
const path = bp?.Buf?.Path || "(no path)";
|
|
72
|
+
const moduleSource =
|
|
73
|
+
micro.CurPane()?.Buf?.MdcuiModuleSource || "external";
|
|
72
74
|
const loc = bp?.CursorLocation?.() || "+1.0:1";
|
|
73
|
-
micro.alert(`${path}\n${loc}`)
|
|
75
|
+
micro.alert(`${path}\nMdcuiModuleSource: ${moduleSource}\n${loc}`)
|
|
74
76
|
|
|
75
77
|
});
|
|
76
78
|
|
package/single-exe/README.md
CHANGED
|
@@ -39,42 +39,58 @@ bun ./src/index.js --build-exe --sourcemap
|
|
|
39
39
|
bun ./src/index.js --build-for <target> --sourcemap
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
Bun expects `--define` values to be JSON-style literals, so strings normally
|
|
43
|
+
need quotes. `stringifyNonPrimitiveDefineValues()` converts a bare value with
|
|
44
|
+
`JSON.stringify()` before it reaches Bun. jsmdcui uses it for
|
|
45
|
+
`global.MDCUI_MAIN`.
|
|
46
|
+
|
|
47
|
+
The switch defines below are presence-based: `=0` and `=false` still enable
|
|
48
|
+
them. Omit a switch define to disable it; examples consistently use `=1`.
|
|
49
|
+
|
|
50
|
+
- `MDCUI_DEFAULT_EDIT=1`: editable-text default.
|
|
51
|
+
- `MDCUI_DEFAULT_DEMO=1`: no-argument `testapp.md` TUI.
|
|
52
|
+
- `MDCUI_DEFAULT_DEMO_WUI=1`: no-argument `testapp.md` WUI.
|
|
53
|
+
- `MDCUI_OVERWRITE_DEMO=1`: overwrite modifier; it does not select a demo.
|
|
54
|
+
- `global.MDCUI_MAIN=<path>.md`: embed a custom Markdown app and its generated
|
|
55
|
+
front, RPC, back, HTML, and server modules.
|
|
56
|
+
- `global.MDCUI_MAIN_BASE`: generated internally from `MDCUI_MAIN`; do not pass
|
|
57
|
+
it manually.
|
|
58
|
+
|
|
59
|
+
Put defines after `--build-exe` (or after the `--build-for` target), and choose
|
|
60
|
+
at most one `MDCUI_DEFAULT_*` mode.
|
|
61
|
+
|
|
62
|
+
| Build defines | No-argument launch | Switch UI |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `MDCUI_DEFAULT_EDIT=1` | text editor | `./mdcui --tui app.md` |
|
|
65
|
+
| `MDCUI_DEFAULT_DEMO=1` | `testapp.md` TUI | `./mdcui --wui --demo` |
|
|
66
|
+
| `MDCUI_DEFAULT_DEMO_WUI=1` | `testapp.md` WUI | `./mdcui --tui --demo` |
|
|
67
|
+
| `global.MDCUI_MAIN=../中文工具.md` | custom TUI | `./mdcui --wui --demo-中文工具` |
|
|
68
|
+
| MAIN plus `MDCUI_DEFAULT_DEMO_WUI=1` | custom WUI | `./mdcui --tui --demo-中文工具` |
|
|
69
|
+
|
|
70
|
+
For a custom TUI-default executable:
|
|
52
71
|
|
|
53
72
|
```shell
|
|
54
73
|
bun ./src/index.js --build-exe \
|
|
55
|
-
--define
|
|
74
|
+
--define global.MDCUI_MAIN=../中文工具.md
|
|
56
75
|
```
|
|
57
76
|
|
|
58
|
-
|
|
77
|
+
For a custom WUI-default executable:
|
|
59
78
|
|
|
60
79
|
```shell
|
|
61
80
|
bun ./src/index.js --build-exe \
|
|
62
|
-
--define
|
|
63
|
-
--define
|
|
81
|
+
--define global.MDCUI_MAIN=../中文工具.md \
|
|
82
|
+
--define MDCUI_DEFAULT_DEMO_WUI=1
|
|
64
83
|
```
|
|
65
84
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
For a browser UI that automatically adds `--wui` when launched without
|
|
71
|
-
arguments, use `MDCUI_DEFAULT_DEMO_WUI` instead:
|
|
85
|
+
Explicit runtime arguments suppress automatic demo/WUI selection, so switching
|
|
86
|
+
UI must repeat `--demo` or `--demo-中文工具`. The main basename must end in
|
|
87
|
+
lowercase `.md`; its demo name allows Unicode letters/numbers (including
|
|
88
|
+
Chinese), dots, underscores, and hyphens, but no whitespace.
|
|
72
89
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
```
|
|
90
|
+
The custom demo uses embedded TUI front/RPC or the embedded WUI server when its
|
|
91
|
+
local Markdown byte length matches the embedded asset. Missing or overwritten
|
|
92
|
+
demos use embedded modules after the asset is written. A differing byte length
|
|
93
|
+
warns and selects filesystem companion modules.
|
|
78
94
|
|
|
79
95
|
To perform the same steps manually, run these commands from `single-exe/`:
|
|
80
96
|
|
|
@@ -221,6 +237,47 @@ bun ./packAssets.sh
|
|
|
221
237
|
bun build --format=esm --compile --minify --bytecode ./entry.mjs --outfile=my-bin
|
|
222
238
|
```
|
|
223
239
|
|
|
240
|
+
#### Passing --define to bun build
|
|
241
|
+
|
|
242
|
+
`buildEarlyExit()` forwards build arguments to Bun, whose define parser expects
|
|
243
|
+
strings to be quoted literals. To accept a bare value such as a path, call the below
|
|
244
|
+
helper to normalize it before `buildEarlyExit()`:
|
|
245
|
+
|
|
246
|
+
```js
|
|
247
|
+
import {
|
|
248
|
+
buildEarlyExit,
|
|
249
|
+
stringifyNonPrimitiveDefineValues,
|
|
250
|
+
} from "../single-exe/compiled.js";
|
|
251
|
+
|
|
252
|
+
stringifyNonPrimitiveDefineValues(process.argv, "MY_STRING_DEFINE");
|
|
253
|
+
await buildEarlyExit(process.argv, "my-bin");
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```shell
|
|
257
|
+
# Wrong: Bun parses the define before the helper runs.
|
|
258
|
+
bun --define MY_STRING_DEFINE=../app.md ./src/index.js --build-exe
|
|
259
|
+
|
|
260
|
+
# Correct
|
|
261
|
+
bun ./src/index.js --build-exe --define MY_STRING_DEFINE=../app.md
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Before normalization:
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
["--define", "MY_STRING_DEFINE=../app.md"]
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
After normalization:
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
["--define", 'MY_STRING_DEFINE="../app.md"']
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The inline form works too:
|
|
277
|
+
`--define=MY_STRING_DEFINE=../app.md` becomes
|
|
278
|
+
`--define=MY_STRING_DEFINE="../app.md"`.
|
|
279
|
+
|
|
280
|
+
|
|
224
281
|
### 6. Verify both execution paths
|
|
225
282
|
|
|
226
283
|
Verify the compiled asset archive and then run the program normally:
|