bimba-cli 0.3.3 → 0.4.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/README.md +93 -69
- package/bun.lock +161 -0
- package/index.js +41 -7
- package/package.json +1 -1
- package/serve.js +180 -0
package/README.md
CHANGED
|
@@ -1,69 +1,93 @@
|
|
|
1
|
-
This tool helps to work with [Imba](https://imba.io) projects under [Bun](https://bun.sh). That is why it is called Bun+IMBA = BIMBA 😉
|
|
2
|
-
|
|
3
|
-
It includes the plugin for Bun to compile .imba files and also the CLI tool for
|
|
4
|
-
|
|
5
|
-
First of all install this tool like any other npm package:
|
|
6
|
-
```bash
|
|
7
|
-
bun add bimba-cli -d
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
bunx bimba src/index.imba --
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
`--
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
This tool helps to work with [Imba](https://imba.io) projects under [Bun](https://bun.sh). That is why it is called Bun+IMBA = BIMBA 😉
|
|
2
|
+
|
|
3
|
+
It includes the plugin for Bun to compile .imba files and also the CLI tool for building .imba files, since the plugins can't be passed to Bun via shell command `bun build`.
|
|
4
|
+
|
|
5
|
+
First of all install this tool like any other npm package:
|
|
6
|
+
```bash
|
|
7
|
+
bun add bimba-cli -d
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Backend development
|
|
13
|
+
|
|
14
|
+
To run an .imba file in Bun's environment, create a `bunfig.toml` file in the root folder of your project:
|
|
15
|
+
```toml
|
|
16
|
+
preload = ["bimba-cli/plugin.js"]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Then use the usual Bun syntax:
|
|
20
|
+
```bash
|
|
21
|
+
bun run src/index.imba
|
|
22
|
+
bun --watch run src/index.imba
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Frontend development
|
|
28
|
+
|
|
29
|
+
### Dev server (HMR)
|
|
30
|
+
|
|
31
|
+
bimba includes a dev server with Hot Module Replacement for Imba custom elements:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bunx bimba src/index.imba --serve --port 5200 --html public/index.html
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**How it works:**
|
|
38
|
+
- Serves your HTML file and compiles `.imba` files on demand (no bundling step)
|
|
39
|
+
- Watches `src/` for changes and pushes updates over WebSocket
|
|
40
|
+
- Injects an importmap built from your `package.json` dependencies
|
|
41
|
+
- Injects an HMR client that swaps component prototypes without a full page reload
|
|
42
|
+
|
|
43
|
+
**HTML setup:** add a `data-entrypoint` attribute to the script tag that loads your bundle. The dev server will replace it with your `.imba` entrypoint and inject the importmap above it:
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<script type='module' src="./js/index.js" data-entrypoint></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Dev server flags:**
|
|
50
|
+
|
|
51
|
+
`--serve` — start dev server instead of bundling
|
|
52
|
+
|
|
53
|
+
`--port <number>` — port to listen on (default: `5200`)
|
|
54
|
+
|
|
55
|
+
`--html <path>` — path to your HTML file (auto-detected from `./index.html`, `./public/index.html`, `./src/index.html` if omitted)
|
|
56
|
+
|
|
57
|
+
Static files are resolved relative to the HTML file's directory first, then from the project root (for `node_modules`, `src`, etc.).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### Production bundle
|
|
62
|
+
|
|
63
|
+
To compile and bundle your source code from .imba to .js:
|
|
64
|
+
```bash
|
|
65
|
+
bunx bimba src/index.imba --outdir public/js --minify
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
With watch:
|
|
69
|
+
```bash
|
|
70
|
+
bunx bimba src/index.imba --outdir public/js --watch --clearcache
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
### All CLI flags
|
|
76
|
+
|
|
77
|
+
`--outdir <path>` — output folder for compiled JS (required in bundle mode)
|
|
78
|
+
|
|
79
|
+
`--watch` — watch the entrypoint directory for changes and rebuild. Keep the entrypoint in a subfolder (e.g. `src/`), otherwise cache updates will trigger extra rebuilds.
|
|
80
|
+
|
|
81
|
+
`--clearcache` — delete the cache directory on exit (Ctrl+C). Works only in watch mode.
|
|
82
|
+
|
|
83
|
+
`--minify` — minify the output JS. Enabled by default in bundle mode.
|
|
84
|
+
|
|
85
|
+
`--sourcemap <inline|external|none>` — how to include source maps in the output (default: `none`).
|
|
86
|
+
|
|
87
|
+
`--target <browser|node>` — platform flag passed to the Imba compiler (default: `browser`). The `node` value does not work under Bun.
|
|
88
|
+
|
|
89
|
+
`--serve` — start dev server with HMR instead of bundling.
|
|
90
|
+
|
|
91
|
+
`--port <number>` — port for the dev server (default: `5200`). Used with `--serve`.
|
|
92
|
+
|
|
93
|
+
`--html <path>` — custom HTML file path. Used with `--serve`.
|
package/bun.lock
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "bimba-cli",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"imba": "latest",
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
"packages": {
|
|
13
|
+
"@antfu/install-pkg": ["@antfu/install-pkg@0.1.1", "", { "dependencies": { "execa": "^5.1.1", "find-up": "^5.0.0" } }, "sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ=="],
|
|
14
|
+
|
|
15
|
+
"@esbuild/android-arm": ["@esbuild/android-arm@0.15.18", "", { "os": "android", "cpu": "arm" }, "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw=="],
|
|
16
|
+
|
|
17
|
+
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.15.18", "", { "os": "linux", "cpu": "none" }, "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ=="],
|
|
18
|
+
|
|
19
|
+
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
|
|
20
|
+
|
|
21
|
+
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
|
|
22
|
+
|
|
23
|
+
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
|
24
|
+
|
|
25
|
+
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
|
|
26
|
+
|
|
27
|
+
"colord": ["colord@2.9.3", "", {}, "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw=="],
|
|
28
|
+
|
|
29
|
+
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
|
30
|
+
|
|
31
|
+
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
|
32
|
+
|
|
33
|
+
"dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
|
|
34
|
+
|
|
35
|
+
"envinfo": ["envinfo@7.21.0", "", { "bin": { "envinfo": "dist/cli.js" } }, "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow=="],
|
|
36
|
+
|
|
37
|
+
"esbuild": ["esbuild@0.15.18", "", { "optionalDependencies": { "@esbuild/android-arm": "0.15.18", "@esbuild/linux-loong64": "0.15.18", "esbuild-android-64": "0.15.18", "esbuild-android-arm64": "0.15.18", "esbuild-darwin-64": "0.15.18", "esbuild-darwin-arm64": "0.15.18", "esbuild-freebsd-64": "0.15.18", "esbuild-freebsd-arm64": "0.15.18", "esbuild-linux-32": "0.15.18", "esbuild-linux-64": "0.15.18", "esbuild-linux-arm": "0.15.18", "esbuild-linux-arm64": "0.15.18", "esbuild-linux-mips64le": "0.15.18", "esbuild-linux-ppc64le": "0.15.18", "esbuild-linux-riscv64": "0.15.18", "esbuild-linux-s390x": "0.15.18", "esbuild-netbsd-64": "0.15.18", "esbuild-openbsd-64": "0.15.18", "esbuild-sunos-64": "0.15.18", "esbuild-windows-32": "0.15.18", "esbuild-windows-64": "0.15.18", "esbuild-windows-arm64": "0.15.18" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q=="],
|
|
38
|
+
|
|
39
|
+
"esbuild-android-64": ["esbuild-android-64@0.15.18", "", { "os": "android", "cpu": "x64" }, "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA=="],
|
|
40
|
+
|
|
41
|
+
"esbuild-android-arm64": ["esbuild-android-arm64@0.15.18", "", { "os": "android", "cpu": "arm64" }, "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ=="],
|
|
42
|
+
|
|
43
|
+
"esbuild-darwin-64": ["esbuild-darwin-64@0.15.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg=="],
|
|
44
|
+
|
|
45
|
+
"esbuild-darwin-arm64": ["esbuild-darwin-arm64@0.15.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA=="],
|
|
46
|
+
|
|
47
|
+
"esbuild-freebsd-64": ["esbuild-freebsd-64@0.15.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA=="],
|
|
48
|
+
|
|
49
|
+
"esbuild-freebsd-arm64": ["esbuild-freebsd-arm64@0.15.18", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA=="],
|
|
50
|
+
|
|
51
|
+
"esbuild-linux-32": ["esbuild-linux-32@0.15.18", "", { "os": "linux", "cpu": "ia32" }, "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg=="],
|
|
52
|
+
|
|
53
|
+
"esbuild-linux-64": ["esbuild-linux-64@0.15.18", "", { "os": "linux", "cpu": "x64" }, "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw=="],
|
|
54
|
+
|
|
55
|
+
"esbuild-linux-arm": ["esbuild-linux-arm@0.15.18", "", { "os": "linux", "cpu": "arm" }, "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA=="],
|
|
56
|
+
|
|
57
|
+
"esbuild-linux-arm64": ["esbuild-linux-arm64@0.15.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug=="],
|
|
58
|
+
|
|
59
|
+
"esbuild-linux-mips64le": ["esbuild-linux-mips64le@0.15.18", "", { "os": "linux", "cpu": "none" }, "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ=="],
|
|
60
|
+
|
|
61
|
+
"esbuild-linux-ppc64le": ["esbuild-linux-ppc64le@0.15.18", "", { "os": "linux", "cpu": "ppc64" }, "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w=="],
|
|
62
|
+
|
|
63
|
+
"esbuild-linux-riscv64": ["esbuild-linux-riscv64@0.15.18", "", { "os": "linux", "cpu": "none" }, "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg=="],
|
|
64
|
+
|
|
65
|
+
"esbuild-linux-s390x": ["esbuild-linux-s390x@0.15.18", "", { "os": "linux", "cpu": "s390x" }, "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ=="],
|
|
66
|
+
|
|
67
|
+
"esbuild-netbsd-64": ["esbuild-netbsd-64@0.15.18", "", { "os": "none", "cpu": "x64" }, "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg=="],
|
|
68
|
+
|
|
69
|
+
"esbuild-openbsd-64": ["esbuild-openbsd-64@0.15.18", "", { "os": "openbsd", "cpu": "x64" }, "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ=="],
|
|
70
|
+
|
|
71
|
+
"esbuild-sunos-64": ["esbuild-sunos-64@0.15.18", "", { "os": "sunos", "cpu": "x64" }, "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw=="],
|
|
72
|
+
|
|
73
|
+
"esbuild-windows-32": ["esbuild-windows-32@0.15.18", "", { "os": "win32", "cpu": "ia32" }, "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ=="],
|
|
74
|
+
|
|
75
|
+
"esbuild-windows-64": ["esbuild-windows-64@0.15.18", "", { "os": "win32", "cpu": "x64" }, "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw=="],
|
|
76
|
+
|
|
77
|
+
"esbuild-windows-arm64": ["esbuild-windows-arm64@0.15.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ=="],
|
|
78
|
+
|
|
79
|
+
"execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
|
|
80
|
+
|
|
81
|
+
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
|
82
|
+
|
|
83
|
+
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
|
84
|
+
|
|
85
|
+
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
|
86
|
+
|
|
87
|
+
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
|
88
|
+
|
|
89
|
+
"get-port": ["get-port@5.1.1", "", {}, "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ=="],
|
|
90
|
+
|
|
91
|
+
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
|
|
92
|
+
|
|
93
|
+
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
|
94
|
+
|
|
95
|
+
"human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
|
|
96
|
+
|
|
97
|
+
"imba": ["imba@2.0.0-alpha.247", "", { "dependencies": { "@antfu/install-pkg": "^0.1.1", "chokidar": "^3.4.3", "colord": "^2.9.3", "cross-spawn": "^7.0.3", "debug": "^4.3.4", "dotenv": "^16.0.3", "envinfo": "^7.8.1", "esbuild": "^0.15.2", "fdir": "^6.1.0", "get-port": "^5.1.1", "local-pkg": "^0.4.2", "lodash.mergewith": "^4.6.2", "prompts": "^2.4.2" }, "peerDependencies": { "@testing-library/dom": "*", "@testing-library/jest-dom": "*", "vite": "*", "vite-node": "*", "vitest": "*" }, "optionalPeers": ["@testing-library/dom", "@testing-library/jest-dom", "vite", "vite-node", "vitest"], "bin": { "imba": "bin/imba", "imbac": "bin/imbac" } }, "sha512-wrM2yDk78nnXC5kS1Br0hcsLgHjoIRNEX0XIsDNNNqVOjwAe6L63I0UjiJlXvLukhAMRV07acBv9kE9lH95YnQ=="],
|
|
98
|
+
|
|
99
|
+
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
|
|
100
|
+
|
|
101
|
+
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
|
102
|
+
|
|
103
|
+
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
|
104
|
+
|
|
105
|
+
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
|
106
|
+
|
|
107
|
+
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
|
108
|
+
|
|
109
|
+
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
|
110
|
+
|
|
111
|
+
"kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
|
|
112
|
+
|
|
113
|
+
"local-pkg": ["local-pkg@0.4.3", "", {}, "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g=="],
|
|
114
|
+
|
|
115
|
+
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
|
116
|
+
|
|
117
|
+
"lodash.mergewith": ["lodash.mergewith@4.6.2", "", {}, "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="],
|
|
118
|
+
|
|
119
|
+
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
|
|
120
|
+
|
|
121
|
+
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
|
|
122
|
+
|
|
123
|
+
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
|
124
|
+
|
|
125
|
+
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
|
|
126
|
+
|
|
127
|
+
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
|
|
128
|
+
|
|
129
|
+
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
|
130
|
+
|
|
131
|
+
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
|
132
|
+
|
|
133
|
+
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
|
134
|
+
|
|
135
|
+
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
|
136
|
+
|
|
137
|
+
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
|
138
|
+
|
|
139
|
+
"picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
|
|
140
|
+
|
|
141
|
+
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
|
|
142
|
+
|
|
143
|
+
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
|
|
144
|
+
|
|
145
|
+
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
|
146
|
+
|
|
147
|
+
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
|
148
|
+
|
|
149
|
+
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
|
150
|
+
|
|
151
|
+
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
|
|
152
|
+
|
|
153
|
+
"strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
|
|
154
|
+
|
|
155
|
+
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
|
156
|
+
|
|
157
|
+
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
|
158
|
+
|
|
159
|
+
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
|
160
|
+
}
|
|
161
|
+
}
|
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import {theme} from './utils.js';
|
|
|
6
6
|
import fs from 'fs'
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { rmSync } from "node:fs";
|
|
9
|
+
import { serve } from './serve.js';
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
let flags = {}
|
|
@@ -22,6 +23,9 @@ try {
|
|
|
22
23
|
minify: { type: 'boolean' },
|
|
23
24
|
target: { type: 'string' },
|
|
24
25
|
sourcemap: { type: 'string' },
|
|
26
|
+
serve: { type: 'boolean' },
|
|
27
|
+
port: { type: 'string' },
|
|
28
|
+
html: { type: 'string' },
|
|
25
29
|
},
|
|
26
30
|
strict: true,
|
|
27
31
|
allowPositionals: true,
|
|
@@ -37,6 +41,18 @@ catch (error) {
|
|
|
37
41
|
process.exit(0);
|
|
38
42
|
}
|
|
39
43
|
|
|
44
|
+
// Ensure bunfig.toml exists and contains the required preload line
|
|
45
|
+
const bunfigPath = path.join(process.cwd(), 'bunfig.toml');
|
|
46
|
+
const preloadLine = 'preload = ["bimba-cli/plugin.js"]';
|
|
47
|
+
if (!fs.existsSync(bunfigPath)) {
|
|
48
|
+
fs.writeFileSync(bunfigPath, preloadLine + '\n');
|
|
49
|
+
} else {
|
|
50
|
+
const content = fs.readFileSync(bunfigPath, 'utf8');
|
|
51
|
+
if (!content.includes(preloadLine)) {
|
|
52
|
+
fs.appendFileSync(bunfigPath, (content.endsWith('\n') ? '' : '\n') + preloadLine + '\n');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
40
56
|
// help: more on bun building params here: https://bun.sh/docs/bundler
|
|
41
57
|
if(flags.help) {
|
|
42
58
|
console.log("");
|
|
@@ -50,23 +66,40 @@ if(flags.help) {
|
|
|
50
66
|
console.log(" "+theme.flags('--watch')+" Watch for changes in the entrypoint folder");
|
|
51
67
|
console.log(" "+theme.flags('--clearcache')+" Clear cache on exit, works only when in watch mode");
|
|
52
68
|
console.log("");
|
|
69
|
+
console.log("Dev server (HMR):");
|
|
70
|
+
console.log(" "+theme.flags('--serve')+" Start dev server with Hot Module Replacement");
|
|
71
|
+
console.log(" "+theme.flags('--port <number>')+" Port for the dev server (default: 5200)");
|
|
72
|
+
console.log(" "+theme.flags('--html <path>')+" Custom HTML file path (auto-detected if omitted)");
|
|
73
|
+
console.log("");
|
|
53
74
|
process.exit(0);
|
|
54
75
|
}
|
|
55
76
|
|
|
56
77
|
|
|
78
|
+
let bundling = false;
|
|
79
|
+
|
|
80
|
+
// serve mode
|
|
81
|
+
if (flags.serve) {
|
|
82
|
+
if (!entrypoint) {
|
|
83
|
+
console.log("");
|
|
84
|
+
console.log("You should provide entrypoint: "+theme.flags('bimba file.imba --serve'));
|
|
85
|
+
console.log("");
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
serve(entrypoint, { port: parseInt(flags.port) || 5200, html: flags.html });
|
|
89
|
+
}
|
|
57
90
|
// no entrypoint or outdir
|
|
58
|
-
if(!entrypoint || !flags.outdir) {
|
|
91
|
+
else if(!entrypoint || !flags.outdir) {
|
|
59
92
|
console.log("");
|
|
60
93
|
console.log("You should provide entrypoint and the output dir: "+theme.flags('bimba file.imba --outdir public'));
|
|
61
94
|
console.log("For more information: "+theme.flags('--help'));
|
|
62
95
|
console.log("");
|
|
63
96
|
process.exit(1);
|
|
64
97
|
}
|
|
65
|
-
|
|
66
98
|
// build
|
|
67
|
-
|
|
68
|
-
bundle();
|
|
69
|
-
watch(bundle);
|
|
99
|
+
else {
|
|
100
|
+
bundle();
|
|
101
|
+
watch(bundle);
|
|
102
|
+
}
|
|
70
103
|
|
|
71
104
|
function watch(callback) {
|
|
72
105
|
if (flags.watch) {
|
|
@@ -83,6 +116,7 @@ function watch(callback) {
|
|
|
83
116
|
}
|
|
84
117
|
}
|
|
85
118
|
|
|
119
|
+
|
|
86
120
|
async function bundle() {
|
|
87
121
|
if (bundling) return;
|
|
88
122
|
bundling = true;
|
|
@@ -101,7 +135,7 @@ async function bundle() {
|
|
|
101
135
|
|
|
102
136
|
console.log(theme.folder("──────────────────────────────────────────────────────────────────────"));
|
|
103
137
|
console.log(theme.start(`Start building the Imba entrypoint: ${theme.filedir(entrypoint)}`));
|
|
104
|
-
|
|
138
|
+
|
|
105
139
|
let result = undefined
|
|
106
140
|
try {
|
|
107
141
|
result = await Bun.build({
|
|
@@ -118,7 +152,7 @@ async function bundle() {
|
|
|
118
152
|
else
|
|
119
153
|
console.log(theme.start(theme.success("Success") +` It took ${theme.time(Date.now() - start)} ms to bundle ${theme.count(stats.bundled)} file${stats.bundled > 1 ? 's' : ''} to the folder: ${theme.filedir(flags.outdir)}`));
|
|
120
154
|
|
|
121
|
-
if(!result.success && !stats.errors){
|
|
155
|
+
if (!result.success && !stats.errors) {
|
|
122
156
|
for (const log of result.logs) {
|
|
123
157
|
console.log(log);
|
|
124
158
|
}
|
package/package.json
CHANGED
package/serve.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { serve as bunServe } from 'bun'
|
|
2
|
+
import * as compiler from 'imba/compiler'
|
|
3
|
+
import { watch, existsSync } from 'fs'
|
|
4
|
+
import path from 'path'
|
|
5
|
+
import { theme } from './utils.js'
|
|
6
|
+
|
|
7
|
+
const hmrClient = `
|
|
8
|
+
<script>
|
|
9
|
+
const _originalDefine = customElements.define.bind(customElements);
|
|
10
|
+
const _registry = new Map();
|
|
11
|
+
const _updated = new Set();
|
|
12
|
+
|
|
13
|
+
customElements.define = function(name, cls, opts) {
|
|
14
|
+
const existing = _registry.get(name);
|
|
15
|
+
if (existing) {
|
|
16
|
+
Object.getOwnPropertyNames(cls.prototype).forEach(key => {
|
|
17
|
+
if (key === 'constructor') return;
|
|
18
|
+
try { Object.defineProperty(existing.prototype, key, Object.getOwnPropertyDescriptor(cls.prototype, key)); } catch(e) {}
|
|
19
|
+
});
|
|
20
|
+
Object.getOwnPropertyNames(cls).forEach(key => {
|
|
21
|
+
if (['length','name','prototype','arguments','caller'].includes(key)) return;
|
|
22
|
+
try { Object.defineProperty(existing, key, Object.getOwnPropertyDescriptor(cls, key)); } catch(e) {}
|
|
23
|
+
});
|
|
24
|
+
_updated.add(name);
|
|
25
|
+
} else {
|
|
26
|
+
_registry.set(name, cls);
|
|
27
|
+
_originalDefine(name, cls, opts);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function resetElement(el) {
|
|
32
|
+
Object.getOwnPropertySymbols(el).forEach(s => {
|
|
33
|
+
try { if (el[s] instanceof Node) el[s] = undefined; } catch(e) {}
|
|
34
|
+
});
|
|
35
|
+
el.innerHTML = '';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const ws = new WebSocket('ws://' + location.host + '/__hmr__');
|
|
39
|
+
ws.onmessage = (e) => {
|
|
40
|
+
const data = JSON.parse(e.data);
|
|
41
|
+
if (data.type === 'update') {
|
|
42
|
+
_updated.clear();
|
|
43
|
+
import('/' + data.file + '?t=' + Date.now()).then(() => {
|
|
44
|
+
const updatedClasses = [..._updated].map(n => _registry.get(n)).filter(Boolean);
|
|
45
|
+
const found = [];
|
|
46
|
+
if (updatedClasses.length) {
|
|
47
|
+
document.querySelectorAll('*').forEach(el => {
|
|
48
|
+
for (const cls of updatedClasses) {
|
|
49
|
+
if (el instanceof cls) { found.push(el); break; }
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
found.forEach(resetElement);
|
|
54
|
+
_updated.clear();
|
|
55
|
+
imba.commit();
|
|
56
|
+
});
|
|
57
|
+
} else if (data.type === 'reload') {
|
|
58
|
+
location.reload();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
</script>`
|
|
62
|
+
|
|
63
|
+
async function compileFile(filepath) {
|
|
64
|
+
const code = await Bun.file(filepath).text()
|
|
65
|
+
return compiler.compile(code, { sourcePath: filepath, platform: 'browser' })
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function findHtml(flagHtml) {
|
|
69
|
+
if (flagHtml) return flagHtml;
|
|
70
|
+
const candidates = ['./index.html', './public/index.html', './src/index.html'];
|
|
71
|
+
return candidates.find(p => existsSync(p)) || './index.html';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Build importmap from package.json dependencies.
|
|
75
|
+
// Packages with an .imba entry point are served locally; others via esm.sh.
|
|
76
|
+
async function buildImportMap() {
|
|
77
|
+
const imports = {
|
|
78
|
+
"imba/runtime": "https://esm.sh/imba/runtime",
|
|
79
|
+
"imba": "https://esm.sh/imba"
|
|
80
|
+
};
|
|
81
|
+
try {
|
|
82
|
+
const pkg = JSON.parse(await Bun.file('./package.json').text());
|
|
83
|
+
for (const [name] of Object.entries(pkg.dependencies || {})) {
|
|
84
|
+
if (name === 'imba') continue;
|
|
85
|
+
try {
|
|
86
|
+
const depPkg = JSON.parse(await Bun.file(`./node_modules/${name}/package.json`).text());
|
|
87
|
+
const entry = depPkg.module || depPkg.main;
|
|
88
|
+
if (entry && entry.endsWith('.imba')) {
|
|
89
|
+
imports[name] = `/node_modules/${name}/${entry}`;
|
|
90
|
+
} else {
|
|
91
|
+
imports[name] = `https://esm.sh/${name}`;
|
|
92
|
+
}
|
|
93
|
+
} catch(e) {
|
|
94
|
+
imports[name] = `https://esm.sh/${name}`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} catch(e) { /* no package.json, use defaults */ }
|
|
98
|
+
|
|
99
|
+
const json = JSON.stringify({ imports }, null, '\t\t\t\t');
|
|
100
|
+
return `\t\t<script type="importmap">\n\t\t\t${json}\n\t\t</script>`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Transform production HTML for dev:
|
|
104
|
+
// - removes existing importmap block
|
|
105
|
+
// - removes <script data-bimba> from its position
|
|
106
|
+
// - injects importmap + entrypoint script + HMR client before </head>
|
|
107
|
+
function transformHtml(html, entrypoint, importMapTag) {
|
|
108
|
+
html = html.replace(/<script\s+type=["']importmap["'][^>]*>[\s\S]*?<\/script>/gi, '');
|
|
109
|
+
html = html.replace(/<script([^>]*)\bdata-entrypoint\b([^>]*)><\/script>/gi, '');
|
|
110
|
+
|
|
111
|
+
const entryUrl = '/' + entrypoint.replace(/^\.\//, '').replaceAll('\\', '/');
|
|
112
|
+
const entryScript = `\t\t<script type='module' src='${entryUrl}'></script>`;
|
|
113
|
+
|
|
114
|
+
html = html.replace('</head>', `${importMapTag}\n${entryScript}\n${hmrClient}\n\t</head>`);
|
|
115
|
+
return html;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function serve(entrypoint, flags) {
|
|
119
|
+
const port = flags.port || 5200
|
|
120
|
+
const htmlPath = findHtml(flags.html)
|
|
121
|
+
const htmlDir = path.dirname(htmlPath)
|
|
122
|
+
const srcDir = path.dirname(entrypoint)
|
|
123
|
+
const sockets = new Set()
|
|
124
|
+
let importMapTag = null
|
|
125
|
+
|
|
126
|
+
watch(srcDir, { recursive: true }, (_event, filename) => {
|
|
127
|
+
if (!filename || !filename.endsWith('.imba')) return
|
|
128
|
+
const rel = path.join(path.relative('.', srcDir), filename).replaceAll('\\', '/')
|
|
129
|
+
// console.log(theme.action('changed: ') + theme.filename(rel))
|
|
130
|
+
for (const socket of sockets)
|
|
131
|
+
socket.send(JSON.stringify({ type: 'update', file: rel }))
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
bunServe({
|
|
135
|
+
port,
|
|
136
|
+
development: true,
|
|
137
|
+
|
|
138
|
+
fetch: async (req, server) => {
|
|
139
|
+
const url = new URL(req.url)
|
|
140
|
+
const pathname = url.pathname
|
|
141
|
+
|
|
142
|
+
if (pathname === '/__hmr__') {
|
|
143
|
+
if (server.upgrade(req)) return undefined
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (pathname === '/' || pathname.endsWith('.html')) {
|
|
147
|
+
const htmlFile = pathname === '/' ? htmlPath : '.' + pathname
|
|
148
|
+
let html = await Bun.file(htmlFile).text()
|
|
149
|
+
if (!importMapTag) importMapTag = await buildImportMap()
|
|
150
|
+
html = transformHtml(html, entrypoint, importMapTag)
|
|
151
|
+
return new Response(html, { headers: { 'Content-Type': 'text/html' } })
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (pathname.endsWith('.imba')) {
|
|
155
|
+
try {
|
|
156
|
+
const out = await compileFile('.' + pathname)
|
|
157
|
+
return new Response(out.js, { headers: { 'Content-Type': 'application/javascript' } })
|
|
158
|
+
} catch (e) {
|
|
159
|
+
return new Response(e.message, { status: 500 })
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Static files: check htmlDir first (assets relative to HTML), then root (node_modules, src, etc.)
|
|
164
|
+
const htmlDirFile = Bun.file(path.join(htmlDir, pathname))
|
|
165
|
+
if (await htmlDirFile.exists()) return new Response(htmlDirFile)
|
|
166
|
+
const file = Bun.file('.' + pathname)
|
|
167
|
+
if (await file.exists()) return new Response(file)
|
|
168
|
+
return new Response('Not Found', { status: 404 })
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
websocket: {
|
|
172
|
+
open: (ws) => sockets.add(ws),
|
|
173
|
+
close: (ws) => sockets.delete(ws),
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
console.log(theme.folder('──────────────────────────────────────────────────────────────────────'))
|
|
178
|
+
console.log(theme.start(`Dev server running at `) + theme.success(`http://localhost:${port}`))
|
|
179
|
+
console.log(theme.folder('──────────────────────────────────────────────────────────────────────'))
|
|
180
|
+
}
|