@twobirds/microcomponents 0.13.0 → 0.13.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 +3 -3
- package/dist/cli/index.js +4 -2
- package/dist/docs/cli.d.ts +16 -7
- package/dist/docs/cli.d.ts.map +1 -1
- package/dist/docs/installation.d.ts +7 -2
- package/dist/docs/installation.d.ts.map +1 -1
- package/dist/mcp/api.json +1 -1
- package/dist/mcp/concepts/custom-element-registry.md +8 -0
- package/dist/mcp/concepts/mc-types.md +5 -0
- package/dist/mcp/concepts/microcomponent-architecture.md +21 -1
- package/dist/mcp/concepts/project-layout.md +7 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -138,7 +138,7 @@ Once installed from npm the same command is available as `mc` (and as `microcomp
|
|
|
138
138
|
|
|
139
139
|
```bash
|
|
140
140
|
mc new my-card [--css] [--html] [--target-html] [--shadow-html] [--target-css] [--shadow-css] [--js] [--dir <path>] [--force] [--dry-run]
|
|
141
|
-
mc create --namespace <ns> [--dir <path>] [--force] [--dry-run]
|
|
141
|
+
mc create --namespace <ns> [--dir <path>] [--force] [--yes] [--dry-run]
|
|
142
142
|
mc dev [--port <n>] [--host <addr>]
|
|
143
143
|
mc bundle
|
|
144
144
|
mc preview [--port <n>] [--host <addr>]
|
|
@@ -165,7 +165,7 @@ npx -p @twobirds/microcomponents mc new my-card --target-html --target-css
|
|
|
165
165
|
npx -p @twobirds/microcomponents microcomponents-mcp
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
The scaffold derives the file path from the tag using the same rule the runtime autoload loader uses (`my-card` → `my/card.ts`), names companion assets after the runtime's asset descriptors (`targetHtml` → `card.target.html`), and wires them into a `static assets` declaration. `--js` emits a plain JavaScript file for the rapid-prototyping path.
|
|
168
|
+
The scaffold derives the file path from the tag using the same rule the runtime autoload loader uses (`my-card` → `my/card.ts`), names companion assets after the runtime's asset descriptors (`targetHtml` → `card.target.html`), and wires them into a `static assets` declaration. Every hyphen becomes a folder, so the tag's segments are the DOM containment chain — `<cart-container-articles>` sits inside `<cart-container>`, so it is `src/cart/container/articles.ts` — and the last segment names what the component does, not what shape it is: `panel`, `box`, `wrapper` are superfluous, because a folder level costs a segment that has to say something. `--js` emits a plain JavaScript file for the rapid-prototyping path.
|
|
169
169
|
|
|
170
170
|
## Examples
|
|
171
171
|
|
|
@@ -414,7 +414,7 @@ Feel free to contact me for any questions or inquiries:
|
|
|
414
414
|
|
|
415
415
|
email [Frank Thürigen](mailto:fthuerigen@gmail.com?subject=Micro%20Components)
|
|
416
416
|
|
|
417
|
-
You can [fund this](https://www.
|
|
417
|
+
You can [fund this](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=fthuerigen@gmail.com&item_name=Micro+Components¤cy_code=EUR).
|
|
418
418
|
|
|
419
419
|
## Disclaimer
|
|
420
420
|
|
package/dist/cli/index.js
CHANGED
|
@@ -267,7 +267,7 @@ function packageJson(namespace) {
|
|
|
267
267
|
typecheck: "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
|
|
268
268
|
test: "vitest run"
|
|
269
269
|
},
|
|
270
|
-
dependencies: { "@twobirds/microcomponents": "^0.13.
|
|
270
|
+
dependencies: { "@twobirds/microcomponents": "^0.13.1" },
|
|
271
271
|
devDependencies: {
|
|
272
272
|
typescript: "^6.0.3",
|
|
273
273
|
vitest: "^4.1.10",
|
|
@@ -400,7 +400,9 @@ Never write an import map. \`autoload()\` fetches a component by its tag (\`ns-n
|
|
|
400
400
|
npx mc new ${namespace}-name --target-html --target-css
|
|
401
401
|
\`\`\`
|
|
402
402
|
|
|
403
|
-
The tag must be kebab-case with at least one hyphen. \`ns-name\` becomes \`src/ns/name.ts
|
|
403
|
+
The tag must be kebab-case with at least one hyphen. Every hyphen becomes a folder, so \`ns-parent-name\` becomes \`src/ns/parent/name.ts\` — the same rule the autoloader uses, so the tag is the file path.
|
|
404
|
+
|
|
405
|
+
The segments are the DOM containment chain: the namespace, then the components the element sits inside, then the component's own name. \`<cart-container-articles>\` sits inside \`<cart-container>\`, so it is \`src/cart/container/articles.ts\`. The last segment names what the component does, not what shape it is: \`<${namespace}-header-search>\` → \`src/${namespace}/header/search.ts\`. Generic structural words (\`panel\`, \`box\`, \`wrapper\`, \`widget\`, \`view\`) are superfluous — \`<${namespace}-header-panel>\` → \`src/${namespace}/header/panel.js\` buys a folder level that says nothing.
|
|
404
406
|
|
|
405
407
|
\`--js\` writes \`src/ns/name.js\` instead of \`.ts\`. \`tsc\` compiles only \`.ts\`, so the dev server and \`mc bundle\` copy a plain \`.js\` component to \`build/\` verbatim — it autoloads and bundles like a compiled component, with no type checking and no \`.d.ts\`.
|
|
406
408
|
|
package/dist/docs/cli.d.ts
CHANGED
|
@@ -44,18 +44,25 @@ mc create --namespace shop
|
|
|
44
44
|
# project "shop" created in shop/ — run: cd shop && pnpm install && pnpm dev
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
Flags: `--namespace <ns>` (
|
|
48
|
-
the namespace), `--force`, `--
|
|
47
|
+
Flags: `--namespace <ns>` (lowercase letters and digits, starting with a letter, any
|
|
48
|
+
length, required), `--dir <path>` (default: the namespace), `--force`, `--yes` (`-y`,
|
|
49
|
+
skip the confirmation), `--dry-run`. The project owns its namespace, so length is the
|
|
50
|
+
user's call; past 5 characters `mc create` warns and asks the terminal to confirm before
|
|
51
|
+
anything is written, and `--dry-run` warns without prompting.
|
|
49
52
|
|
|
50
53
|
## mc dev
|
|
51
54
|
|
|
52
55
|
Runs `tsc -w` plus a `node:http` server that serves `build/`. The page loads components
|
|
53
56
|
on demand through `autoload()` — nothing is bundled, and a new component is picked up
|
|
54
|
-
without restarting.
|
|
57
|
+
without restarting. The server rewrites the `@twobirds/microcomponents` specifier in the
|
|
58
|
+
JS it serves to the `/microcomponents.min.js` it answers, so the page carries no import
|
|
59
|
+
map, and it mirrors the files `tsc` does not compile — companion assets and plain `.js`
|
|
60
|
+
components — into `build/` next to the compiled component.
|
|
55
61
|
|
|
56
62
|
```sh
|
|
57
|
-
mc dev
|
|
63
|
+
mc dev # dev server on port 5173, bound to 127.0.0.1
|
|
58
64
|
mc dev --port 3000
|
|
65
|
+
mc dev --host 0.0.0.0 # widen the bind to the LAN
|
|
59
66
|
```
|
|
60
67
|
|
|
61
68
|
## mc bundle
|
|
@@ -70,11 +77,13 @@ mc bundle
|
|
|
70
77
|
|
|
71
78
|
## mc preview
|
|
72
79
|
|
|
73
|
-
Serves the production site in `public/`.
|
|
80
|
+
Serves the production site in `public/`. Like `mc dev`, it binds to `127.0.0.1` by
|
|
81
|
+
default, so the served files are not reachable off the machine; `--host` widens the bind.
|
|
74
82
|
|
|
75
83
|
```sh
|
|
76
|
-
mc preview
|
|
84
|
+
mc preview # preview server on port 5174, bound to 127.0.0.1
|
|
77
85
|
mc preview --port 8080
|
|
86
|
+
mc preview --host 0.0.0.0 # widen the bind to the LAN
|
|
78
87
|
```
|
|
79
88
|
|
|
80
89
|
## mc clean
|
|
@@ -101,7 +110,7 @@ mc check
|
|
|
101
110
|
Reports the version of the installed library, not the version of the project it runs in.
|
|
102
111
|
|
|
103
112
|
```sh
|
|
104
|
-
mc --version # 0.13.
|
|
113
|
+
mc --version # 0.13.1
|
|
105
114
|
```
|
|
106
115
|
|
|
107
116
|
## mc --help
|
package/dist/docs/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/docs/cli.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/docs/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0HE"}
|
|
@@ -14,10 +14,11 @@ the prompt).
|
|
|
14
14
|
npx @twobirds/microcomponents create --namespace shop
|
|
15
15
|
# created shop/package.json
|
|
16
16
|
# created shop/opencode.jsonc
|
|
17
|
+
# created shop/src/bundle.json
|
|
17
18
|
# created shop/src/index.html
|
|
18
19
|
# created shop/src/index-dev.html
|
|
19
20
|
# created shop/src/shop/app.ts
|
|
20
|
-
# created shop/src/shop/app.
|
|
21
|
+
# created shop/src/shop/app.html
|
|
21
22
|
# created shop/src/shop/app.target.css
|
|
22
23
|
# created shop/src/shop/bundle.ts
|
|
23
24
|
# ...
|
|
@@ -36,7 +37,11 @@ the project.
|
|
|
36
37
|
`mc new` derives the file path from the tag using the same rule the runtime autoloader
|
|
37
38
|
uses (`shop-app` → `shop/app.ts`), names companion assets after the runtime's asset
|
|
38
39
|
descriptors (`targetHtml` → `app.target.html`), and wires them into a `static assets`
|
|
39
|
-
declaration.
|
|
40
|
+
declaration. Every hyphen becomes a folder, so the segments are the DOM containment
|
|
41
|
+
chain: a child of `<cart-container>` is `<cart-container-articles>` →
|
|
42
|
+
`src/cart/container/articles.ts`. The last segment names what the component does, not
|
|
43
|
+
what shape it is — `panel`, `box`, `wrapper` are superfluous, because a folder level
|
|
44
|
+
costs a segment that has to say something.
|
|
40
45
|
|
|
41
46
|
```sh
|
|
42
47
|
mc new shop-app --target-html --target-css
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../../src/docs/installation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"installation.d.ts","sourceRoot":"","sources":["../../src/docs/installation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BE;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkDE"}
|
package/dist/mcp/api.json
CHANGED
|
@@ -47,6 +47,14 @@ src/
|
|
|
47
47
|
|
|
48
48
|
The DOM hierarchy is therefore immediately visible in the file system.
|
|
49
49
|
|
|
50
|
+
The name is the shortest one that says what the component does. The leaf segment is the
|
|
51
|
+
component's function, not its shape: `<shop-header-search>` → `src/shop/header/search.js`
|
|
52
|
+
says what the child of the header does. `<shop-header-panel>` → `src/shop/header/panel.js`
|
|
53
|
+
is wrong — `panel` describes a shape, so the file carries no information about the
|
|
54
|
+
component, and the folder level the tag creates is paid for by a word that says nothing.
|
|
55
|
+
Generic structural words (`panel`, `box`, `wrapper`, `widget`, `view`) are superfluous:
|
|
56
|
+
the nesting a tag encodes costs a directory, so the segment must be worth it.
|
|
57
|
+
|
|
50
58
|
---
|
|
51
59
|
|
|
52
60
|
## General-Purpose Components in Side Folders
|
|
@@ -111,6 +111,11 @@ External design of the composed unit is driven by namespaced CSS custom properti
|
|
|
111
111
|
</cart-container>
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
+
A child's tag carries its parent's prefix, so its file lands in the parent's folder
|
|
115
|
+
(`<cart-container-articles>` → `src/cart/container/articles.ts`), and the last segment
|
|
116
|
+
names what the child does — `articles`, `checkout`, `pay`. A generic structural word
|
|
117
|
+
(`panel`, `box`, `wrapper`) makes the folder level it creates say nothing.
|
|
118
|
+
|
|
114
119
|
### 1d. Leaf Components
|
|
115
120
|
|
|
116
121
|
Self-contained visual units that project no child custom elements — a button, a badge,
|
|
@@ -16,7 +16,7 @@ Every `.ts` or `.js` file contains exactly **one class**, regardless of which ty
|
|
|
16
16
|
visual, logic-only, style-only, or pure logic. This applies to `DC` subclasses, `MC`
|
|
17
17
|
subclasses, and any other class defined in `src/`.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
For the classes the toolchain registers, three mechanisms make the rule loadable:
|
|
20
20
|
|
|
21
21
|
- **Autoload resolution** — `autoload()` maps a tag name to a single script path
|
|
22
22
|
(`<shop-header>` → `./shop/header.js`). One class per file keeps that mapping
|
|
@@ -27,5 +27,25 @@ Why:
|
|
|
27
27
|
- **Registry clarity** — `defineCE()` is called once per file, so file, class, and
|
|
28
28
|
registered tag stay in a 1:1 relationship.
|
|
29
29
|
|
|
30
|
+
The three logic types are where the rule is easiest to lose, because none of those three
|
|
31
|
+
mechanisms can catch a violation:
|
|
32
|
+
|
|
33
|
+
- **Logic-only `DC`** (`static tag = ''`) — the class is registered, so the 1:1 contract
|
|
34
|
+
holds, and the asset name is the host's tag name, which for a removed host is the
|
|
35
|
+
registered tag (`app-router` → `./app/router.css`). The class runs setup logic on a
|
|
36
|
+
host it is attached to with `DC.add(host, key, instance)`: one instance under one key,
|
|
37
|
+
so a second class in the file is a second attachable unit with no key of its own. Its
|
|
38
|
+
companions are `.css` and `.json` — the constructor removes the host after the assets
|
|
39
|
+
are applied, so a markup companion has nothing to inject into.
|
|
40
|
+
- **Style-only `DC`** (`static tag = ''`, `static assets = ['css']`) — the class is a
|
|
41
|
+
delivery vehicle for one stylesheet. File, class, registered tag, and the `.css`
|
|
42
|
+
companion are one thing under four names: `page-cockpit` in `src/page/cockpit.ts`
|
|
43
|
+
fetches `./page/cockpit.css`. A second class in the file would ship a second
|
|
44
|
+
stylesheet under a basename the first one owns.
|
|
45
|
+
- **Pure logic `MC`** — no tag, no `defineCE`, no autoload path, so nothing in the
|
|
46
|
+
toolchain sees the file at all. The rule holds for the reason a reusable unit gets its
|
|
47
|
+
own file: the import is by path, so one file is one capability and the file name is
|
|
48
|
+
the capability. A helper that is not a class is a utility function, not an `MC`.
|
|
49
|
+
|
|
30
50
|
Non-class entities that belong to the class — interfaces, types, constants, plain
|
|
31
51
|
functions — may live alongside it. A class that is reusable on its own gets its own file.
|
|
@@ -4,9 +4,11 @@ A Micro Components project keeps one folder per stage of the chain:
|
|
|
4
4
|
src/ → (tsc) → build/ → (bundle) → public/
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
- `src/` holds the authored sources: component `.ts` files,
|
|
8
|
-
`.target.html` / `.target.css` /
|
|
9
|
-
|
|
7
|
+
- `src/` holds the authored sources: component `.ts` files, plain `.js` components
|
|
8
|
+
written with `mc new --js`, the companion `.target.html` / `.target.css` /
|
|
9
|
+
`.shadow.css` assets, the bundle barrel `src/<namespace>/bundle.ts` with the
|
|
10
|
+
`src/bundle.json` that names it, the dev shell (`index-dev.html`) and the production
|
|
11
|
+
shell (`index.html`).
|
|
10
12
|
- `build/` is the `tsc` output: one `.js` per component at its own autoload path,
|
|
11
13
|
plus the files `tsc` does not compile — mirrored companion assets, plain `.js`
|
|
12
14
|
components, and the dev shell. `mc dev` serves it, so the page loads components
|
|
@@ -23,7 +25,8 @@ served from `public/` in production. Do not add a fourth tree for it.
|
|
|
23
25
|
|
|
24
26
|
A new component is picked up by the dev server automatically, because `autoload()`
|
|
25
27
|
resolves its tag to a file under `build/`. The bundle is not: the bundler walks a single
|
|
26
|
-
entry, so every component must be imported by the barrel
|
|
28
|
+
entry, the one `src/bundle.json` names, so every component must be imported by the barrel
|
|
29
|
+
`src/<namespace>/bundle.ts` that file points at.
|
|
27
30
|
|
|
28
31
|
## Shells
|
|
29
32
|
|