bitwrench 2.0.32 → 2.1.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 +211 -125
- package/dist/bitwrench-bccl.cjs.js +349 -188
- package/dist/bitwrench-bccl.cjs.min.js +2 -39
- package/dist/bitwrench-bccl.cjs.min.js.gz +0 -0
- package/dist/bitwrench-bccl.esm.js +349 -188
- package/dist/bitwrench-bccl.esm.min.js +2 -39
- package/dist/bitwrench-bccl.esm.min.js.gz +0 -0
- package/dist/bitwrench-bccl.umd.js +349 -188
- package/dist/bitwrench-bccl.umd.min.js +2 -39
- package/dist/bitwrench-bccl.umd.min.js.gz +0 -0
- package/dist/bitwrench-code-edit.cjs.js +17 -6
- package/dist/bitwrench-code-edit.cjs.min.js +2 -20
- package/dist/bitwrench-code-edit.es5.js +8 -3
- package/dist/bitwrench-code-edit.es5.min.js +2 -19
- package/dist/bitwrench-code-edit.esm.js +17 -6
- package/dist/bitwrench-code-edit.esm.min.js +2 -19
- package/dist/bitwrench-code-edit.umd.js +17 -6
- package/dist/bitwrench-code-edit.umd.min.js +2 -19
- package/dist/bitwrench-code-edit.umd.min.js.gz +0 -0
- package/dist/bitwrench-debug.js +1 -1
- package/dist/bitwrench-debug.min.js +1 -1
- package/dist/bitwrench-lean.cjs.js +2492 -1628
- package/dist/bitwrench-lean.cjs.min.js +2 -80
- package/dist/bitwrench-lean.cjs.min.js.gz +0 -0
- package/dist/bitwrench-lean.es5.js +2740 -1838
- package/dist/bitwrench-lean.es5.min.js +2 -49
- package/dist/bitwrench-lean.es5.min.js.gz +0 -0
- package/dist/bitwrench-lean.esm.js +2492 -1628
- package/dist/bitwrench-lean.esm.min.js +2 -80
- package/dist/bitwrench-lean.esm.min.js.gz +0 -0
- package/dist/bitwrench-lean.umd.js +2492 -1628
- package/dist/bitwrench-lean.umd.min.js +2 -80
- package/dist/bitwrench-lean.umd.min.js.gz +0 -0
- package/dist/bitwrench-util-color.cjs.js +251 -0
- package/dist/bitwrench-util-color.cjs.min.js +3 -0
- package/dist/bitwrench-util-color.es5.js +256 -0
- package/dist/bitwrench-util-color.es5.min.js +3 -0
- package/dist/bitwrench-util-color.esm.js +241 -0
- package/dist/bitwrench-util-color.esm.min.js +3 -0
- package/dist/bitwrench-util-color.umd.js +257 -0
- package/dist/bitwrench-util-color.umd.min.js +3 -0
- package/dist/bitwrench-util-css.cjs.js +2 -1
- package/dist/bitwrench-util-css.cjs.min.js +2 -21
- package/dist/bitwrench-util-css.es5.js +2 -1
- package/dist/bitwrench-util-css.es5.min.js +2 -20
- package/dist/bitwrench-util-css.esm.js +2 -1
- package/dist/bitwrench-util-css.esm.min.js +1 -19
- package/dist/bitwrench-util-css.umd.js +2 -1
- package/dist/bitwrench-util-css.umd.min.js +2 -20
- package/dist/bitwrench-util-css.umd.min.js.gz +0 -0
- package/dist/bitwrench.cjs.js +2826 -1801
- package/dist/bitwrench.cjs.min.js +2 -99
- package/dist/bitwrench.cjs.min.js.gz +0 -0
- package/dist/bitwrench.css +403 -479
- package/dist/bitwrench.d.ts +70 -73
- package/dist/bitwrench.es5.js +3106 -2020
- package/dist/bitwrench.es5.min.js +2 -67
- package/dist/bitwrench.es5.min.js.gz +0 -0
- package/dist/bitwrench.esm.js +2826 -1801
- package/dist/bitwrench.esm.min.js +2 -99
- package/dist/bitwrench.esm.min.js.gz +0 -0
- package/dist/bitwrench.min.css +1 -1
- package/dist/bitwrench.umd.js +2826 -1801
- package/dist/bitwrench.umd.min.js +2 -99
- package/dist/bitwrench.umd.min.js.gz +0 -0
- package/dist/builds.json +222 -134
- package/dist/bwserve.cjs.js +289 -282
- package/dist/bwserve.d.ts +157 -0
- package/dist/bwserve.esm.js +290 -283
- package/dist/sri.json +54 -46
- package/docs/README.md +6 -3
- package/docs/app-patterns.md +7 -6
- package/docs/bitwrench-for-wasm.md +53 -54
- package/docs/bitwrench-mcp.md +2 -2
- package/docs/bitwrench-northstar-principles.md +406 -0
- package/docs/bitwrench-taco-schema-discussion.md +2 -2
- package/docs/bitwrench_api.md +191 -106
- package/docs/bitwrench_typescript_usage.md +5 -5
- package/docs/bw-attach.md +29 -75
- package/docs/bwserve.md +200 -168
- package/docs/cli.md +36 -12
- package/docs/component-cheatsheet.md +2 -2
- package/docs/component-library.md +4 -4
- package/docs/component-lifecycle.md +234 -0
- package/docs/drift-lint.md +268 -0
- package/docs/framework-translation-table.md +4 -4
- package/docs/llm-bitwrench-guide.md +60 -50
- package/docs/routing.md +11 -13
- package/docs/state-management.md +110 -109
- package/docs/taco-format.md +13 -14
- package/docs/theming.md +13 -3
- package/docs/thinking-in-bitwrench.md +858 -983
- package/docs/tutorial-bwserve.md +37 -36
- package/docs/tutorial-embedded.md +10 -21
- package/docs/tutorial-website.md +2 -2
- package/package.json +38 -7
- package/readme.html +262 -161
- package/src/bitwrench-bccl-entry.js +2 -2
- package/src/bitwrench-bccl.js +346 -185
- package/src/bitwrench-code-edit.js +16 -5
- package/src/bitwrench-color-utils.js +117 -181
- package/src/bitwrench-file-ops.js +2 -2
- package/src/bitwrench-lean.js +4 -3
- package/src/bitwrench-router.js +5 -2
- package/src/bitwrench-styles.js +420 -504
- package/src/bitwrench-util-color.js +240 -0
- package/src/bitwrench-util-css.js +1 -0
- package/src/bitwrench-utils.js +4 -0
- package/src/bitwrench.d.ts +70 -73
- package/src/bitwrench.h +5 -0
- package/src/bitwrench.js +1939 -933
- package/src/bwserve/attach.js +0 -1
- package/src/bwserve/bwclient.js +172 -32
- package/src/bwserve/bwshell.js +0 -4
- package/src/bwserve/client.js +59 -220
- package/src/bwserve/index.js +59 -26
- package/src/bwserve.d.ts +157 -0
- package/src/bwserve.h +5 -0
- package/src/cli/attach.js +12 -75
- package/src/cli/convert.js +2 -2
- package/src/cli/serve.js +37 -35
- package/src/generate-css.js +1 -1
- package/src/mcp/knowledge.js +4 -4
- package/src/mcp/live.js +21 -13
- package/src/mcp/tools.js +0 -1
- package/src/version.js +3 -7
package/dist/sri.json
CHANGED
|
@@ -1,51 +1,59 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.
|
|
2
|
+
"version": "2.1.1",
|
|
3
3
|
"algorithm": "sha384",
|
|
4
|
-
"generated": "2026-
|
|
4
|
+
"generated": "2026-07-15",
|
|
5
5
|
"files": {
|
|
6
|
-
"bitwrench-bccl.cjs.js": "sha384-
|
|
7
|
-
"bitwrench-bccl.cjs.min.js": "sha384-
|
|
8
|
-
"bitwrench-bccl.esm.js": "sha384-
|
|
9
|
-
"bitwrench-bccl.esm.min.js": "sha384
|
|
10
|
-
"bitwrench-bccl.umd.js": "sha384-
|
|
11
|
-
"bitwrench-bccl.umd.min.js": "sha384-
|
|
12
|
-
"bitwrench-code-edit.cjs.js": "sha384-
|
|
13
|
-
"bitwrench-code-edit.cjs.min.js": "sha384-
|
|
14
|
-
"bitwrench-code-edit.es5.js": "sha384-
|
|
15
|
-
"bitwrench-code-edit.es5.min.js": "sha384-
|
|
16
|
-
"bitwrench-code-edit.esm.js": "sha384-
|
|
17
|
-
"bitwrench-code-edit.esm.min.js": "sha384-
|
|
18
|
-
"bitwrench-code-edit.umd.js": "sha384-
|
|
19
|
-
"bitwrench-code-edit.umd.min.js": "sha384-
|
|
20
|
-
"bitwrench-debug.js": "sha384-
|
|
21
|
-
"bitwrench-debug.min.js": "sha384-
|
|
22
|
-
"bitwrench-lean.cjs.js": "sha384-
|
|
23
|
-
"bitwrench-lean.cjs.min.js": "sha384-
|
|
24
|
-
"bitwrench-lean.es5.js": "sha384-
|
|
25
|
-
"bitwrench-lean.es5.min.js": "sha384-
|
|
26
|
-
"bitwrench-lean.esm.js": "sha384-
|
|
27
|
-
"bitwrench-lean.esm.min.js": "sha384-
|
|
28
|
-
"bitwrench-lean.umd.js": "sha384-
|
|
29
|
-
"bitwrench-lean.umd.min.js": "sha384-
|
|
30
|
-
"bitwrench-util-
|
|
31
|
-
"bitwrench-util-
|
|
32
|
-
"bitwrench-util-
|
|
33
|
-
"bitwrench-util-
|
|
34
|
-
"bitwrench-util-
|
|
35
|
-
"bitwrench-util-
|
|
36
|
-
"bitwrench-util-
|
|
37
|
-
"bitwrench-util-
|
|
38
|
-
"bitwrench.cjs.js": "sha384-
|
|
39
|
-
"bitwrench.cjs.min.js": "sha384-
|
|
40
|
-
"bitwrench.
|
|
41
|
-
"bitwrench.es5.js": "sha384-
|
|
42
|
-
"bitwrench.
|
|
43
|
-
"bitwrench.esm.js": "sha384-
|
|
44
|
-
"bitwrench.
|
|
45
|
-
"bitwrench.min.
|
|
46
|
-
"bitwrench.
|
|
47
|
-
"bitwrench.
|
|
48
|
-
"
|
|
49
|
-
"
|
|
6
|
+
"bitwrench-bccl.cjs.js": "sha384-B0aQIxXhxcyrAlix+j4UC8K7oKG/dVwC0Oe1/wmqTEdn8b1KIfnl3b0uumIEguGc",
|
|
7
|
+
"bitwrench-bccl.cjs.min.js": "sha384-oE3RnWAqbgoD3hV8KMScq3IYNj8lhl5aqBgbPwqnSN18NygVuXxYgt4JgJ/P3a3a",
|
|
8
|
+
"bitwrench-bccl.esm.js": "sha384-Y4N70nFgy6szh6GDz5WakwlcFe1YdB0pm9qmhDT0vFgvEYK/AXtMeCkbRFZa4bKS",
|
|
9
|
+
"bitwrench-bccl.esm.min.js": "sha384-/u3kujGMJ2CgT0EiXEg3rs1PjIODUu0uP0pqxBpD9bjkFcgmd9uS/N3RpZ/Kl9eO",
|
|
10
|
+
"bitwrench-bccl.umd.js": "sha384-LwgwBffGNjOgw98QUogo1mvT+KIRkgfDchIBxm3cpObrFat8qXdw9vhk1fcLrYvd",
|
|
11
|
+
"bitwrench-bccl.umd.min.js": "sha384-RkYOxXKlcnZvfR1cqPK6dlszvtyIhJ0u4SKnjgdV7YmTmvEexVVrcHiYT+ZTJZ4o",
|
|
12
|
+
"bitwrench-code-edit.cjs.js": "sha384-5xtpD4Hdaxr2qBRbhFgwtBTPWQ9UGh1Vb9drHKMNmTs/HYYnEByhz+nf/Okv9ILi",
|
|
13
|
+
"bitwrench-code-edit.cjs.min.js": "sha384-jdom5FXkU52Y2dEZY+T6nghl403ARZDzJN5mrlwfcO88xTm3HIHohhb1GUfXV2py",
|
|
14
|
+
"bitwrench-code-edit.es5.js": "sha384-lZWGCR5cf7mDhoK1P+ZC8XdU7PBtg+ATnZ3FLCBqV1U8pi5KowozoXaUqlw5jHdb",
|
|
15
|
+
"bitwrench-code-edit.es5.min.js": "sha384-56hIGJN49aKfPphqK3jlHfLWiCk71nVTj3q82P3EOcmzvIS1ECGlD9e5CtaTCIIm",
|
|
16
|
+
"bitwrench-code-edit.esm.js": "sha384-MRKH7iiNKgtAA+QJPYppQpvIXnT8iU5jeD5+pOmcz9D9YC2UAMwNvi+tEmAKlD7S",
|
|
17
|
+
"bitwrench-code-edit.esm.min.js": "sha384-Oj5ZgB9aeUmKMGq4h+MqCvFpw6pyOTzzTaJXEZRQX1Z768fz8cweyjV68Fqtx9Xm",
|
|
18
|
+
"bitwrench-code-edit.umd.js": "sha384-JndphcsfDanAFd5WDfxm4Po/Y9Pe9iNoY4Bwiu2VcSHge1oWHkdCLxD9Q7IIy2U4",
|
|
19
|
+
"bitwrench-code-edit.umd.min.js": "sha384-R1LGH2VGWZFcnWN+HXrrGbJUUQOVvkoooeh9AqFyCbDVUBtbu/pSd2kbR/BMtFGW",
|
|
20
|
+
"bitwrench-debug.js": "sha384-tMsS8YNpnWx+t4DEZX6JoSoYFHA7SjlnjPROmOMQVn/CVFtQWl5yL66pF+bNLh/6",
|
|
21
|
+
"bitwrench-debug.min.js": "sha384-ClXhaom0UNWzEzMbq3oaahMjO87BNjFu+7rLEI/FRG7DZLtp2vzr2dINQXGEsuCz",
|
|
22
|
+
"bitwrench-lean.cjs.js": "sha384-cqGEqf6HhVCj042PoSCRWhcQdOkMN4livX/HwK8ChVHX6ub0WnWdKhcvvrajSabf",
|
|
23
|
+
"bitwrench-lean.cjs.min.js": "sha384-B7kFM0sE9tmkYGprcwG2j9/fy4j4RtsaTnXiulO0gY6dBm8GoEfniTITKNeVir60",
|
|
24
|
+
"bitwrench-lean.es5.js": "sha384-sN/rWICehichsCcBxMUwA2Crkuz4JcIu2hOIByXnNktG5dzeiwJTtHzcIo2GDFBe",
|
|
25
|
+
"bitwrench-lean.es5.min.js": "sha384-cupxyMkbBM35mP97l7v+65Pu9g1QxP6J7Hlh+7EsOsE+s0sJxuY4tnHD3zqs76GL",
|
|
26
|
+
"bitwrench-lean.esm.js": "sha384-meRyTgeHW04mZOTyWwHAo+PBgs2zYSQuxurJWUWBhNXRU7HHbmMT/d4aCo/ALWHj",
|
|
27
|
+
"bitwrench-lean.esm.min.js": "sha384-LIPDtrKXNP1FBwNwqyQWeLCJlvWkVbJDIsGqZqlVxwsGhidq64phTwKoXFrRv+Ad",
|
|
28
|
+
"bitwrench-lean.umd.js": "sha384-o6YpWpqHVxfqHlJ6snSDb9TgdynZoIfgG0C3+iaI1joZGe6JJGTkMkN5tEc1yGpH",
|
|
29
|
+
"bitwrench-lean.umd.min.js": "sha384-sZQ7rNCvzu6db3bFonVOkZRn3jQiIfSPBYh5nqrnZwf5sNYKiX4y/HCUg3uqXPPC",
|
|
30
|
+
"bitwrench-util-color.cjs.js": "sha384-xhNNGd3AcHdh93qURLsapQVDhkjvARGUCc7nyJ0w22g8exk48hQJaYkCaIz+D/to",
|
|
31
|
+
"bitwrench-util-color.cjs.min.js": "sha384-wV0yhsO7QMkeQ39yAacwRzaSJOELAbwKaYLyFUTSL94VBoNK1J5hcaK4kglabtdw",
|
|
32
|
+
"bitwrench-util-color.es5.js": "sha384-vr/EQBigtmIOxwXzEGmqUiMlMgGR7AlQySEgWuTFzW4X+0o1rAHBJb6+4J2BxrTN",
|
|
33
|
+
"bitwrench-util-color.es5.min.js": "sha384-jGAyJ7VONHCW5Mg002ehyDR9/7L84j5iDWj6HVXUTO1KZEUokY5pLAJgVP8Zd31u",
|
|
34
|
+
"bitwrench-util-color.esm.js": "sha384-veGQ0Sdn5YSUIGlcvJA5FCgzL5aRxLjYcNtWa1qe/8gJ0mg+AQrn4QRi9Ik2gLwG",
|
|
35
|
+
"bitwrench-util-color.esm.min.js": "sha384-z83iY/YxP+Vy4rh8b42lnI5VUcrRrypFEUnT0gfHLlqKZ0ecqa+liQfgTAjXR+c/",
|
|
36
|
+
"bitwrench-util-color.umd.js": "sha384-YIIeopsm4OKn6AIEelm10wEKsdQY4HRAzMT/QmYOg+j4BSHurT4mdClUGNpFgwPb",
|
|
37
|
+
"bitwrench-util-color.umd.min.js": "sha384-XTVxvWBmjZdZa+2jZPTqwTimVCahhHkUoe/7ek3P/v2dHhNqaIKlqDbctEJ38+u+",
|
|
38
|
+
"bitwrench-util-css.cjs.js": "sha384-JqkhxHMrnFcB2UvZp3XzO5d7V/6DJK8HYhAdMWIIcgHioKVbE6L4O8viVymCXwj8",
|
|
39
|
+
"bitwrench-util-css.cjs.min.js": "sha384-r35+UKdAKgJizYYRebm5g+7RVlNTSAbO9ikhRY1Nc7Kelc3JlZPJI1V0IYJWm51q",
|
|
40
|
+
"bitwrench-util-css.es5.js": "sha384-4camXftDKDboxTqDSi5sMCAIBLu1UbpsPYjxAYR9GghuY+iRAFJaq7En5OaQPyVM",
|
|
41
|
+
"bitwrench-util-css.es5.min.js": "sha384-qQ9eOtZu7mSAa2ItOPnHDk0M2En44Et9Rd7ndoNz1eFHNf7jqlEtBHBYw05ld/8E",
|
|
42
|
+
"bitwrench-util-css.esm.js": "sha384-m0Ws+mQPHrcrTo2xvfpAGbPrzECuGtcfU5VwpgtuVmgP/7v5/FEVIolWGEwL1XKe",
|
|
43
|
+
"bitwrench-util-css.esm.min.js": "sha384-J3h0/oEd2/KZOFT94+v34E/NEOUhzgk7tnNazCOguUYdz1zTJFxIC3tefejDW9Li",
|
|
44
|
+
"bitwrench-util-css.umd.js": "sha384-4njrao8h2lxvSNG1rwCnRjQnaN23FbqvNQuEe82H6Xao0L2KVI2AfLW5UJndlic6",
|
|
45
|
+
"bitwrench-util-css.umd.min.js": "sha384-V+0Jsx5PDdCkoay8w8durao03+LOtFfrR7tJvhX95h2YprM3Sh/yMmdouSymc2/N",
|
|
46
|
+
"bitwrench.cjs.js": "sha384-223vCHCMFpVn3ebcLzmDhmnjIqpaMe3AcISs02i4qGYbHmnMrnkQmfg95i+l1YSC",
|
|
47
|
+
"bitwrench.cjs.min.js": "sha384-PxbnuQGZgfdu9dtaP6BE1CVRMG8sfMm7rO5tZgFqhVBUDIfHAChGHcXkgB4U3w/N",
|
|
48
|
+
"bitwrench.css": "sha384-nVkVjZaSm8VMx6f0M+cVwaGdjADq/GCwvpO8i6459LBSzKVDb1ezutgwx29kGqd5",
|
|
49
|
+
"bitwrench.es5.js": "sha384-O/K7lCnuhPN4t2Eg2bK/1QRm6Yy3hV9MyaCmPullUzZCXs5LrYTIoLwJyxTUN86R",
|
|
50
|
+
"bitwrench.es5.min.js": "sha384-+nprbfrs5bAbX0e1wX0UhQTIV8c1uEUjN4GeW9aGknKOpSEjP7t+H8ATChzbJeBr",
|
|
51
|
+
"bitwrench.esm.js": "sha384-kESLl4JnEZ6sbx5cX1KkAvDZ4kZ7COx/qMT5RJ5MNc4Udq0zXhtRGigQEzi2fJmX",
|
|
52
|
+
"bitwrench.esm.min.js": "sha384-onhcbWZ1mZlwZHJhSAkU7sEiTvyA4bLFxK1zH7WJ7nquBZflmux1LBxTbZclE0XA",
|
|
53
|
+
"bitwrench.min.css": "sha384-V5byv/NexwbnyMfiTCjVcPPRQpGLP9Ui5DZDl7CnsMgjEpsWY1hG/5j0RpcyXtxS",
|
|
54
|
+
"bitwrench.umd.js": "sha384-d43Dw8mMBWUe3qKHTuIT8mE9Gch/LtTM+W7JtOT66+rx7MNfuwN/Bw1nWx1TDU7P",
|
|
55
|
+
"bitwrench.umd.min.js": "sha384-u/z67Z5XNXTdYWkiEdFZkzZ3MP2Y/irNuZiNDVCr64T1dw8htMANy9BibXaeZ3lR",
|
|
56
|
+
"bwserve.cjs.js": "sha384-0HhE53O4G/J631OQb+bpHNYKc4Th3tldIiXl/04IJhvzbX+ykaQMmujz+JpDrLjZ",
|
|
57
|
+
"bwserve.esm.js": "sha384-W7uLFtAgyaLhIpmC9mjWXQMQijvjoEhlKadxO6AxRwx7M16YKoVRH6f37kC8fxr3"
|
|
50
58
|
}
|
|
51
59
|
}
|
package/docs/README.md
CHANGED
|
@@ -10,6 +10,7 @@ These guides cover how to build UIs with bitwrench.
|
|
|
10
10
|
| How do I build a page? | [Building a Website tutorial](tutorial-website.md) |
|
|
11
11
|
| How does TACO work? | [TACO Format](taco-format.md) or [Thinking in Bitwrench](thinking-in-bitwrench.md) |
|
|
12
12
|
| How do I add interactivity? | [State Management](state-management.md) |
|
|
13
|
+
| How does a component actually work? | [Component Lifecycle Walkthrough](component-lifecycle.md) |
|
|
13
14
|
| How do I theme my app? | [Theming](theming.md) |
|
|
14
15
|
| I'm an LLM generating bitwrench code | [LLM Guide](llm-bitwrench-guide.md) |
|
|
15
16
|
| How do I use bwmcp with an AI agent? | [bwmcp MCP Server](bitwrench-mcp.md) |
|
|
@@ -18,7 +19,7 @@ These guides cover how to build UIs with bitwrench.
|
|
|
18
19
|
|
|
19
20
|
## Start Here
|
|
20
21
|
|
|
21
|
-
- **[Thinking in Bitwrench](thinking-in-bitwrench.md)** -- The complete guide to building with bitwrench. Covers TACO basics, styling (`bw.css`, `bw.s`, `bw.responsive`), composition, the
|
|
22
|
+
- **[Thinking in Bitwrench](thinking-in-bitwrench.md)** -- The complete guide to building with bitwrench. Covers TACO basics, styling (`bw.css`, `bw.s`, `bw.responsive`), composition, the component model, events (and why `onclick` goes in `a:`, not `o.mounted`), bwserve, and common patterns. **Read this first.**
|
|
22
23
|
- **[LLM Guide](llm-bitwrench-guide.md)** -- Compact single-file reference for AI-assisted development. All APIs, patterns, and rules in one document. Also useful as a quick-reference cheat sheet for humans.
|
|
23
24
|
|
|
24
25
|
## Guides
|
|
@@ -27,7 +28,7 @@ These guides cover how to build UIs with bitwrench.
|
|
|
27
28
|
|-------|-------------|
|
|
28
29
|
| [Thinking in Bitwrench](thinking-in-bitwrench.md) | Design philosophy: why TACO exists, component model vs. DOM templates |
|
|
29
30
|
| [TACO Format](taco-format.md) | The `{t, a, c, o}` object format that bitwrench uses for everything |
|
|
30
|
-
| [State Management](state-management.md) |
|
|
31
|
+
| [State Management](state-management.md) | Component model, explicit stateful components, cross-component communication |
|
|
31
32
|
| [Component Cheat Sheet](component-cheatsheet.md) | Scannable table of all components with capabilities and handles |
|
|
32
33
|
| [Component Library](component-library.md) | All `make*()` functions with full signatures and examples |
|
|
33
34
|
| [Routing](routing.md) | Client-side router: hash/history mode, route params, guards, pub/sub |
|
|
@@ -39,6 +40,7 @@ These guides cover how to build UIs with bitwrench.
|
|
|
39
40
|
| [LLM Guide](llm-bitwrench-guide.md) | Compact single-file reference for AI-assisted development |
|
|
40
41
|
| [TypeScript Usage Guide](bitwrench_typescript_usage.md) | Import patterns, typed configs, TACO types, tree-shaking |
|
|
41
42
|
| [bwmcp MCP Server](bitwrench-mcp.md) | MCP server for AI agents: tool catalog, live rendering, screenshots |
|
|
43
|
+
| [drift-lint](drift-lint.md) | Maintainer tool: keeps docs/examples consistent with the shipped API |
|
|
42
44
|
|
|
43
45
|
## Tutorials
|
|
44
46
|
|
|
@@ -47,6 +49,7 @@ These guides cover how to build UIs with bitwrench.
|
|
|
47
49
|
| [Building a Website](tutorial-website.md) | Build a complete landing page from scratch |
|
|
48
50
|
| [Server App with bwserve](tutorial-bwserve.md) | Build a Streamlit-style server-driven dashboard |
|
|
49
51
|
| [ESP32 Embedded](tutorial-embedded.md) | ESP32 IoT dashboard with C/C++ macros |
|
|
52
|
+
| [Component Lifecycle Walkthrough](component-lifecycle.md) | Stats card: define, create, mount, update, unmount — every phase of a v2.1 component |
|
|
50
53
|
|
|
51
54
|
## Interactive Docs
|
|
52
55
|
|
|
@@ -72,7 +75,7 @@ The library provides four things:
|
|
|
72
75
|
|
|
73
76
|
1. **A rendering engine** that turns objects into HTML or DOM
|
|
74
77
|
2. **A component library** of ready-made UI elements
|
|
75
|
-
3. **
|
|
78
|
+
3. **An explicit update model** — components live on the DOM element itself (`el.bw` methods, slots, `el._bw_state`), and updates happen when you call them (`el.bw.method()`, `bw.update()`, `bw.refresh()`)
|
|
76
79
|
4. **A client-side router** that maps URLs to views with guards and pub/sub
|
|
77
80
|
|
|
78
81
|
Everything else -- styling, theming, event handling, server communication -- builds on these pieces.
|
package/docs/app-patterns.md
CHANGED
|
@@ -139,24 +139,24 @@ var app = bwserve.create({ port: 7902 });
|
|
|
139
139
|
var count = 0;
|
|
140
140
|
|
|
141
141
|
app.page('/', function(client) {
|
|
142
|
-
client.
|
|
142
|
+
client.mount('#app', {
|
|
143
143
|
t: 'div', c: [
|
|
144
144
|
{ t: 'h1', c: 'Server Counter' },
|
|
145
145
|
{ t: 'span', a: { id: 'val' }, c: '0' },
|
|
146
|
-
{ t: 'button', a: {
|
|
146
|
+
{ t: 'button', a: { class: 'bw_act_inc' }, c: '+1' }
|
|
147
147
|
]
|
|
148
148
|
});
|
|
149
149
|
|
|
150
150
|
client.on('inc', function() {
|
|
151
151
|
count++;
|
|
152
|
-
client.patch('val', String(count));
|
|
152
|
+
client.patch('val', { text: String(count) });
|
|
153
153
|
});
|
|
154
154
|
});
|
|
155
155
|
|
|
156
156
|
app.listen();
|
|
157
157
|
```
|
|
158
158
|
|
|
159
|
-
**State flow:** Browser requests `/` => server returns HTML shell. Shell opens SSE => server sends TACO via `client.
|
|
159
|
+
**State flow:** Browser requests `/` => server returns HTML shell. Shell opens SSE => server sends TACO via `client.mount()`. User clicks a `bw_act_*` classed element => browser POSTs to server. Server calls `client.patch()` => browser updates. All state stays on the server. See [bwserve.md](bwserve.md).
|
|
160
160
|
|
|
161
161
|
---
|
|
162
162
|
|
|
@@ -189,7 +189,8 @@ bw.DOM('#app', { t: 'div', c: [
|
|
|
189
189
|
}})
|
|
190
190
|
]});
|
|
191
191
|
|
|
192
|
-
//
|
|
192
|
+
// Quick prototype: poll + full re-render. For production, use SSE
|
|
193
|
+
// with bw.patch() instead -- see tutorial-embedded.md for the SSE version.
|
|
193
194
|
setInterval(function() {
|
|
194
195
|
fetch('/api/sensors').then(function(r) { return r.json(); })
|
|
195
196
|
.then(function(data) {
|
|
@@ -244,7 +245,7 @@ Each output is self-contained with bitwrench embedded inline. No CDN, no toolcha
|
|
|
244
245
|
|----------|---------|---------|
|
|
245
246
|
| Monitoring dashboard, admin panel | Single-Page Dashboard | `bw.pub/sub`, `bw.DOM()`, `makeStatCard` |
|
|
246
247
|
| Multi-view app with URL navigation | Multi-Page SPA | `bw.router()`, `bw.navigate()` |
|
|
247
|
-
| Server owns all logic (internal tool, LLM UI) | bwserve Server-Driven | `client.
|
|
248
|
+
| Server owns all logic (internal tool, LLM UI) | bwserve Server-Driven | `client.mount()`, `client.patch()` |
|
|
248
249
|
| Microcontroller or constrained device | Embedded / IoT | `bw.DOM()`, `fetch()` polling or SSE |
|
|
249
250
|
| Documentation, blog, project pages | Static Site (bwcli) | `bwcli`, `--theme`, `--standalone` |
|
|
250
251
|
| Prototype or quick one-off | Single-Page Dashboard | One HTML file, no build step |
|
|
@@ -52,7 +52,7 @@ Each boundary crossing has overhead: type marshaling, memory copying, function d
|
|
|
52
52
|
|
|
53
53
|
### An alternative: batch the boundary
|
|
54
54
|
|
|
55
|
-
A different approach is to cross the boundary **once per render, not once per DOM operation.** The WASM module builds a TACO object (a JSON-serializable data structure) and sends it across the boundary as a single message. The JS-side library materializes the entire tree in one shot using `bw.
|
|
55
|
+
A different approach is to cross the boundary **once per render, not once per DOM operation.** The WASM module builds a TACO object (a JSON-serializable data structure) and sends it across the boundary as a single message. The JS-side library materializes the entire tree in one shot using `bw.create()` or `bw.DOM()`.
|
|
56
56
|
|
|
57
57
|
```
|
|
58
58
|
WASM side JS side (bitwrench)
|
|
@@ -72,7 +72,7 @@ Serialize to JSON string |
|
|
|
72
72
|
|
|
73
73
|
100 elements = 1 crossing, not 300+. The DOM operations happen inside JS where they're native function calls with zero marshaling overhead.
|
|
74
74
|
|
|
75
|
-
For incremental updates, the same principle applies. Instead of diffing an entire virtual tree across the boundary, the WASM module sends a targeted patch message: `{type: 'patch',
|
|
75
|
+
For incremental updates, the same principle applies. Instead of diffing an entire virtual tree across the boundary, the WASM module sends a targeted patch message: `{v: 1, type: 'patch', ref: '#counter', text: '42'}`. One crossing, one DOM mutation.
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
@@ -117,7 +117,7 @@ The fourth key, `o:`, contains JavaScript-specific concerns: lifecycle hooks (`m
|
|
|
117
117
|
|
|
118
118
|
For WASM, this split is a natural fit: the **specification** (what to render) crosses the boundary as data, while the **behavior** (DOM event handling, lifecycle management) stays in JS where DOM access is native.
|
|
119
119
|
|
|
120
|
-
For cases where the WASM module needs to
|
|
120
|
+
For cases where the WASM module needs to invoke client-side behavior, bwserve provides `call` -- invoke a named built-in function (e.g., `scrollTo`, `focus`, `download`). Code-bearing verbs (`register`, `exec`) were removed in v2.1; client-side logic should be pre-installed via the JS glue or BCCL component handles.
|
|
121
121
|
|
|
122
122
|
---
|
|
123
123
|
|
|
@@ -127,19 +127,18 @@ bwserve is bitwrench's server-driven UI protocol. It was originally designed for
|
|
|
127
127
|
|
|
128
128
|
### The protocol
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
All messages are stamped with `v: 1`. The v2.1 protocol has the following verb set (code-bearing verbs `exec`, `register`, and `query` were removed):
|
|
131
131
|
|
|
132
132
|
| Type | What it does | Example |
|
|
133
133
|
|------|-------------|---------|
|
|
134
|
-
| `
|
|
135
|
-
| `patch` | Update text or attributes | `{type:'patch',
|
|
136
|
-
| `append` | Add child element | `{type:'append',
|
|
137
|
-
| `remove` | Delete element | `{type:'remove',
|
|
138
|
-
| `batch` | Multiple operations | `{type:'batch', ops:[...]}` |
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `message` | Component dispatch | `{type:'message', target:'#card', action:'setTitle', data:'New'}` |
|
|
134
|
+
| `mount` | Mount TACO at selector | `{v:1, type:'mount', ref:'#app', taco:{t:'div', c:'Hello'}}` |
|
|
135
|
+
| `patch` | Update text or attributes (discriminated fields) | `{v:1, type:'patch', ref:'counter', text:'42'}` |
|
|
136
|
+
| `append` | Add child element | `{v:1, type:'append', ref:'#list', taco:{t:'li', c:'New'}}` |
|
|
137
|
+
| `remove` | Delete element | `{v:1, type:'remove', ref:'#old'}` |
|
|
138
|
+
| `batch` | Multiple operations | `{v:1, type:'batch', ops:[...]}` |
|
|
139
|
+
| `call` | Invoke a named built-in function | `{v:1, type:'call', name:'scrollTo', args:['#chat']}` |
|
|
140
|
+
| `message` | Component dispatch | `{v:1, type:'message', ref:'#card', action:'setTitle', data:'New'}` |
|
|
141
|
+
| `listen` | Subscribe to a pub/sub topic | `{v:1, type:'listen', topic:'bw:lifecycle'}` |
|
|
143
142
|
|
|
144
143
|
### The full loop
|
|
145
144
|
|
|
@@ -148,12 +147,12 @@ WASM Module (application) Browser (display server)
|
|
|
148
147
|
------------------------- -----------------------
|
|
149
148
|
State + logic bitwrench + bwserve client
|
|
150
149
|
| |
|
|
151
|
-
|--
|
|
150
|
+
|-- mount: full render ----------> bw.apply() -> bw.mount()
|
|
152
151
|
|-- patch: targeted update ------> bw.apply() -> bw.patch()
|
|
153
152
|
|-- call: scroll, focus, etc. ---> bw.apply() -> invoke function
|
|
154
153
|
|-- batch: multiple ops ---------> bw.apply() -> sequential
|
|
155
154
|
| |
|
|
156
|
-
<-- event: {
|
|
155
|
+
<-- event: {ref, type, data} ---- subscribed listener fires
|
|
157
156
|
<-- screenshot: PNG buffer ------- html2canvas -> POST-back
|
|
158
157
|
```
|
|
159
158
|
|
|
@@ -292,7 +291,7 @@ WASM server binary Browser
|
|
|
292
291
|
| |
|
|
293
292
|
|-- GET / -> HTML shell ---------->|
|
|
294
293
|
|-- GET /bw/events -> SSE -------->|
|
|
295
|
-
|-- SSE:
|
|
294
|
+
|-- SSE: mount/patch/etc -------->| bw.apply() -> DOM
|
|
296
295
|
|<-- POST /bw/return/action -------|
|
|
297
296
|
|<-- POST /bw/return/screenshot ---|
|
|
298
297
|
```
|
|
@@ -319,16 +318,16 @@ use serde_json::json;
|
|
|
319
318
|
|
|
320
319
|
fn render_dashboard(state: &AppState) -> String {
|
|
321
320
|
json!({
|
|
322
|
-
"t": "div", "a": {"class": "
|
|
321
|
+
"t": "div", "a": {"class": "bw_container"}, "c": [
|
|
323
322
|
{"t": "h1", "c": &state.title},
|
|
324
|
-
{"t": "div", "a": {"class": "
|
|
323
|
+
{"t": "div", "a": {"class": "bw_row"}, "c": [
|
|
325
324
|
stat_card("Users", &state.users.to_string(), "primary"),
|
|
326
325
|
stat_card("Revenue", &format!("${}", state.revenue), "success"),
|
|
327
326
|
stat_card("Orders", &state.orders.to_string(), "info")
|
|
328
327
|
]},
|
|
329
328
|
{"t": "button", "a": {
|
|
330
329
|
"id": "refresh-btn",
|
|
331
|
-
"class": "
|
|
330
|
+
"class": "bw_bccl_btn bw_primary"
|
|
332
331
|
}, "c": "Refresh"}
|
|
333
332
|
]
|
|
334
333
|
}).to_string()
|
|
@@ -336,9 +335,9 @@ fn render_dashboard(state: &AppState) -> String {
|
|
|
336
335
|
|
|
337
336
|
fn stat_card(label: &str, value: &str, variant: &str) -> serde_json::Value {
|
|
338
337
|
json!({
|
|
339
|
-
"t": "div", "a": {"class": format!("
|
|
340
|
-
{"t": "div", "a": {"class": "
|
|
341
|
-
{"t": "div", "a": {"class": "
|
|
338
|
+
"t": "div", "a": {"class": format!("bw_bccl_stat_card bw_{}", variant)}, "c": [
|
|
339
|
+
{"t": "div", "a": {"class": "bw_bccl_stat_card_value"}, "c": value},
|
|
340
|
+
{"t": "div", "a": {"class": "bw_bccl_stat_card_label"}, "c": label}
|
|
342
341
|
]
|
|
343
342
|
})
|
|
344
343
|
}
|
|
@@ -372,22 +371,22 @@ pub fn div(attrs: Value, children: Vec<Value>) -> Value {
|
|
|
372
371
|
pub fn button(label: &str, id: &str) -> Value {
|
|
373
372
|
json!({
|
|
374
373
|
"t": "button",
|
|
375
|
-
"a": {"id": id, "class": "
|
|
374
|
+
"a": {"id": id, "class": "bw_bccl_btn bw_primary"},
|
|
376
375
|
"c": label
|
|
377
376
|
})
|
|
378
377
|
}
|
|
379
378
|
|
|
380
|
-
// bwserve protocol messages
|
|
381
|
-
pub fn
|
|
382
|
-
json!({"type": "
|
|
379
|
+
// bwserve v2.1 protocol messages (all stamped v:1)
|
|
380
|
+
pub fn msg_mount(r: &str, taco: Value) -> Value {
|
|
381
|
+
json!({"v": 1, "type": "mount", "ref": r, "taco": taco})
|
|
383
382
|
}
|
|
384
383
|
|
|
385
|
-
pub fn msg_patch(
|
|
386
|
-
json!({"type": "patch", "
|
|
384
|
+
pub fn msg_patch(r: &str, text: &str) -> Value {
|
|
385
|
+
json!({"v": 1, "type": "patch", "ref": r, "text": text})
|
|
387
386
|
}
|
|
388
387
|
|
|
389
388
|
pub fn msg_batch(ops: Vec<Value>) -> Value {
|
|
390
|
-
json!({"type": "batch", "ops": ops})
|
|
389
|
+
json!({"v": 1, "type": "batch", "ops": ops})
|
|
391
390
|
}
|
|
392
391
|
```
|
|
393
392
|
|
|
@@ -397,7 +396,7 @@ With this helper:
|
|
|
397
396
|
use taco::*;
|
|
398
397
|
|
|
399
398
|
fn render(state: &AppState) -> String {
|
|
400
|
-
|
|
399
|
+
msg_mount("#app", div(
|
|
401
400
|
json!({"class": "container"}),
|
|
402
401
|
vec![
|
|
403
402
|
text("h1", &state.title),
|
|
@@ -487,14 +486,14 @@ Standard JSON in C requires escaping every double quote:
|
|
|
487
486
|
|
|
488
487
|
```c
|
|
489
488
|
// Standard JSON -- escape nightmare
|
|
490
|
-
char msg[] = "{\"type\":\"patch\",\"
|
|
489
|
+
char msg[] = "{\"v\":1,\"type\":\"patch\",\"ref\":\"temp\",\"text\":\"23.5 C\"}";
|
|
491
490
|
```
|
|
492
491
|
|
|
493
492
|
Bitwrench's r-prefix format uses single quotes:
|
|
494
493
|
|
|
495
494
|
```c
|
|
496
495
|
// r-prefix relaxed JSON -- natural C strings
|
|
497
|
-
char msg[] = "r{'type':'patch','
|
|
496
|
+
char msg[] = "r{'v':1,'type':'patch','ref':'temp','text':'23.5 C'}";
|
|
498
497
|
```
|
|
499
498
|
|
|
500
499
|
`bw.parseJSONFlex()` on the browser side converts single quotes to double quotes before parsing. The `r` prefix signals the format.
|
|
@@ -505,16 +504,16 @@ char msg[] = "r{'type':'patch','target':'temp','content':'23.5 C'}";
|
|
|
505
504
|
#include <stdio.h>
|
|
506
505
|
#include <string.h>
|
|
507
506
|
|
|
508
|
-
// Simple TACO builder macros for fixed-size buffers
|
|
509
|
-
#define BW_PATCH(buf,
|
|
507
|
+
// Simple TACO builder macros for fixed-size buffers (v2.1 wire protocol)
|
|
508
|
+
#define BW_PATCH(buf, ref, text) \
|
|
510
509
|
snprintf(buf, sizeof(buf), \
|
|
511
|
-
"r{'type':'patch','
|
|
512
|
-
|
|
510
|
+
"r{'v':1,'type':'patch','ref':'%s','text':'%s'}", \
|
|
511
|
+
ref, text)
|
|
513
512
|
|
|
514
|
-
#define
|
|
513
|
+
#define BW_MOUNT(buf, ref, taco) \
|
|
515
514
|
snprintf(buf, sizeof(buf), \
|
|
516
|
-
"r{'type':'
|
|
517
|
-
|
|
515
|
+
"r{'v':1,'type':'mount','ref':'%s','taco':%s}", \
|
|
516
|
+
ref, taco)
|
|
518
517
|
|
|
519
518
|
// TACO builders
|
|
520
519
|
#define TACO_TEXT(buf, tag, text) \
|
|
@@ -557,11 +556,11 @@ const char* render() {
|
|
|
557
556
|
float temp = read_sensor();
|
|
558
557
|
|
|
559
558
|
snprintf(buf, sizeof(buf),
|
|
560
|
-
"r{'type':'
|
|
559
|
+
"r{'v':1,'type':'mount','ref':'#app','taco':"
|
|
561
560
|
"{'t':'div','c':["
|
|
562
561
|
"{'t':'h1','c':'Sensor Dashboard'},"
|
|
563
562
|
"{'t':'p','a':{'id':'temp'},'c':'%.1f C'},"
|
|
564
|
-
"{'t':'button','a':{'id':'toggle-btn','class':'
|
|
563
|
+
"{'t':'button','a':{'id':'toggle-btn','class':'bw_bccl_btn'},"
|
|
565
564
|
"'c':'Toggle LED'}"
|
|
566
565
|
"]}}", temp);
|
|
567
566
|
|
|
@@ -601,7 +600,7 @@ AI models typically output structured data -- JSON, function calls, tool use. TA
|
|
|
601
600
|
{"t": "div", "c": [
|
|
602
601
|
{"t": "h2", "c": "Analysis Results"},
|
|
603
602
|
{"t": "p", "c": "Found 3 anomalies in the dataset."},
|
|
604
|
-
{"t": "div", "a": {"class": "
|
|
603
|
+
{"t": "div", "a": {"class": "bw_bccl_card"}, "c": [
|
|
605
604
|
{"t": "h3", "c": "Anomaly #1"},
|
|
606
605
|
{"t": "p", "c": "Temperature spike at 14:32 UTC"}
|
|
607
606
|
]},
|
|
@@ -619,7 +618,7 @@ bwserve's screenshot capability closes the loop. The AI generates UI, the browse
|
|
|
619
618
|
AI Model (WASM) Browser
|
|
620
619
|
----------- -------
|
|
621
620
|
Generate TACO spec |
|
|
622
|
-
|--
|
|
621
|
+
|-- mount: render UI ----------> bw.apply() -> visible page
|
|
623
622
|
| |
|
|
624
623
|
|-- screenshot request --------> html2canvas -> capture
|
|
625
624
|
<-- PNG image data -------------|
|
|
@@ -629,7 +628,7 @@ Evaluate screenshot |
|
|
|
629
628
|
text overflow? wrong layout?) |
|
|
630
629
|
| |
|
|
631
630
|
Generate refined TACO spec |
|
|
632
|
-
|--
|
|
631
|
+
|-- mount: updated UI ---------> bw.apply() -> improved page
|
|
633
632
|
```
|
|
634
633
|
|
|
635
634
|
bwserve implements `client.screenshot()` for this purpose -- it sends a `call` message that triggers `html2canvas` on the client, which captures the DOM to a canvas, converts to PNG, and POSTs the image data back to the server. The server resolves a Promise with the image buffer.
|
|
@@ -673,10 +672,10 @@ fn agent_step(state: &AgentState) -> Vec<Value> {
|
|
|
673
672
|
let mut messages = vec![];
|
|
674
673
|
|
|
675
674
|
// Main content area -- task-specific UI
|
|
676
|
-
messages.push(
|
|
675
|
+
messages.push(msg_mount("#main", render_task_ui(&state.current_task)));
|
|
677
676
|
|
|
678
677
|
// Sidebar -- agent's reasoning visible to user
|
|
679
|
-
messages.push(
|
|
678
|
+
messages.push(msg_mount("#sidebar", render_reasoning_log(&state.log)));
|
|
680
679
|
|
|
681
680
|
// Status bar -- progress and controls
|
|
682
681
|
messages.push(msg_patch("status", &format!(
|
|
@@ -730,7 +729,7 @@ One patch message, one DOM mutation. The WASM module communicates what it alread
|
|
|
730
729
|
|
|
731
730
|
Desktop UI toolkits (MFC, Swing, Qt, Cocoa) used targeted updates rather than tree diffing. In MFC, `SetWindowText("New Title")` repainted the control's title. In Swing, `label.setText("43")` updated one label. In Qt, signal-slot connections trigger specific updates. The application tracked what changed and told the framework directly.
|
|
732
731
|
|
|
733
|
-
bitwrench follows the same pattern: `el.bw.setTitle('New')` updates one component, `bw.patch('#counter', '43')` updates one element, `client.patch('counter', '43')` sends one message. The application (or the WASM module) is the source of truth about what changed.
|
|
732
|
+
bitwrench follows the same pattern: `el.bw.setTitle('New')` updates one component, `bw.patch('#counter', '43')` updates one element, `client.patch('counter', {text: '43'})` sends one message. The application (or the WASM module) is the source of truth about what changed.
|
|
734
733
|
|
|
735
734
|
React's diffing approach solved a real problem -- in large JS applications with shared mutable state, manually tracking dependencies is error-prone. Whether that tradeoff applies to a given WASM application depends on the application's complexity and state management approach.
|
|
736
735
|
|
|
@@ -740,7 +739,7 @@ If your WASM module genuinely doesn't know what changed -- for example, if it re
|
|
|
740
739
|
|
|
741
740
|
1. Diff the **data** in WASM (compare old state to new state)
|
|
742
741
|
2. Emit targeted patches for what changed
|
|
743
|
-
3. Or, for small enough UIs, just re-render with `
|
|
742
|
+
3. Or, for small enough UIs, just re-render with `mount` -- `bw.DOM()` is fast enough for most subtrees
|
|
744
743
|
|
|
745
744
|
Diffing data in WASM (where you have typed structs and linear memory) is cheaper than diffing virtual DOM trees in JS (where everything is heap-allocated objects with GC pressure).
|
|
746
745
|
|
|
@@ -762,7 +761,7 @@ These are the most direct alternatives. They run a component framework inside WA
|
|
|
762
761
|
| Accessibility | Manual | Browser-native (real HTML) |
|
|
763
762
|
| Server rendering | Framework-specific SSR | bw.html() or bwserve |
|
|
764
763
|
| Learning curve | Rust + framework | Rust + TACO (4 keys) |
|
|
765
|
-
| Bundle size | ~200KB+ (framework + app) | ~
|
|
764
|
+
| Bundle size | ~200KB+ (framework + app) | ~45KB (bitwrench) + app WASM |
|
|
766
765
|
|
|
767
766
|
The fundamental difference is where the component model lives. Yew/Leptos/Dioxus place it in WASM (Rust macros, reactive primitives, virtual DOM). The bitwrench approach places it in JS (TACO rendering, CSS generation, component handles) and uses JSON as the interface between the application language and the renderer.
|
|
768
767
|
|
|
@@ -770,7 +769,7 @@ The fundamental difference is where the component model lives. Yew/Leptos/Dioxus
|
|
|
770
769
|
|
|
771
770
|
| Concern | Blazor | bitwrench + WASM |
|
|
772
771
|
|---------|--------|------------------|
|
|
773
|
-
| Runtime payload | 2-5MB (.NET in WASM) | ~
|
|
772
|
+
| Runtime payload | 2-5MB (.NET in WASM) | ~45KB (bitwrench) |
|
|
774
773
|
| Component model | Razor templates (.NET) | TACO JSON |
|
|
775
774
|
| DOM access | JS interop bridge | Batched via bw.apply() |
|
|
776
775
|
| Language | C# only | Any (Rust, C, C++, Go, ...) |
|
|
@@ -786,7 +785,7 @@ Blazor bundles a language runtime in WASM. The bitwrench approach does not requi
|
|
|
786
785
|
| Backend | Native process (Rust/Node) | WASM (in-browser or server) |
|
|
787
786
|
| Frontend | You write JS/React/Vue | TACO from any language |
|
|
788
787
|
| Distribution | App store / download | Link sharing |
|
|
789
|
-
| Bundle size | 10-100MB+ | Page weight (~
|
|
788
|
+
| Bundle size | 10-100MB+ | Page weight (~45KB + WASM) |
|
|
790
789
|
|
|
791
790
|
Tauri and Electron are designed for desktop application distribution. If the UI can be served as a web page, the packaging and distribution step is not needed -- the tradeoff is losing native OS integration (system tray, menus, file system access without permissions).
|
|
792
791
|
|
|
@@ -811,8 +810,8 @@ Canvas-based approaches bypass the browser's built-in UI capabilities. Generatin
|
|
|
811
810
|
|
|
812
811
|
- Browser-native UI (real HTML/CSS) from any language that produces JSON
|
|
813
812
|
- Batched boundary crossing -- one message per render, not one per DOM op
|
|
814
|
-
-
|
|
815
|
-
- ~
|
|
813
|
+
- Structured protocol (bwserve, v:1 stamped) for remote UI control including screenshots
|
|
814
|
+
- ~45KB client library with 30+ components, CSS generation, theming
|
|
816
815
|
- No build step on the JS side
|
|
817
816
|
- Same application code can target in-page WASM, Worker, or native server
|
|
818
817
|
- Browser capabilities preserved: accessibility, text selection, CSS layout, forms
|
|
@@ -823,7 +822,7 @@ Canvas-based approaches bypass the browser's built-in UI capabilities. Generatin
|
|
|
823
822
|
|
|
824
823
|
- **No automatic change detection.** You must know what changed and say so. (This is usually trivial in WASM where you just ran the mutation.)
|
|
825
824
|
- **No type-safe TACO builder in Rust/C** -- you're building JSON. A helper crate/header can add convenience, but there's no compile-time guarantee that your TACO is valid. (bitwrench is lenient -- invalid fields are silently ignored.)
|
|
826
|
-
- **No client-side routing from WASM.** The browser-side `bw.router()` exists for JS, but a WASM server would manage navigation via bwserve's `
|
|
825
|
+
- **No client-side routing from WASM.** The browser-side `bw.router()` exists for JS, but a WASM server would manage navigation via bwserve's `mount` messages.
|
|
827
826
|
- **No two-way data binding.** User events come back as structured messages (element ID, event type, value). You update your state and send a patch. This is the expected pattern for a boundary architecture.
|
|
828
827
|
- **No animation primitives from WASM.** CSS animations and transitions work (they're in the browser), but you'd define them via `bw.css()` on the JS side or in a stylesheet, not from WASM.
|
|
829
828
|
|
package/docs/bitwrench-mcp.md
CHANGED
|
@@ -222,7 +222,7 @@ This costs about 200 tokens. Always call it first.
|
|
|
222
222
|
### Step 2: Learn (Optional but Recommended)
|
|
223
223
|
|
|
224
224
|
If you have not used bitwrench before, call `bitwrench_guide`. This is the
|
|
225
|
-
full tutorial (about 4000 tokens). It covers TACO nesting, the
|
|
225
|
+
full tutorial (about 4000 tokens). It covers TACO nesting, the
|
|
226
226
|
component model, events, CSS/theming, all component categories, debugging,
|
|
227
227
|
bwserve, routing, and API reference tables.
|
|
228
228
|
|
|
@@ -299,7 +299,7 @@ If using live rendering:
|
|
|
299
299
|
```
|
|
300
300
|
screenshot({}) // see what the browser shows
|
|
301
301
|
screenshot({selector: '.bw_stat_card:first-child'}) // zoom in on one element
|
|
302
|
-
query_dom({code: '
|
|
302
|
+
query_dom({code: 'bw.$(\'.bw_bccl_card\').length'}) // count cards
|
|
303
303
|
```
|
|
304
304
|
|
|
305
305
|
Evaluate the screenshot, decide what to change, and call `render_live` again.
|