tosijs-ui 1.6.23 → 1.7.0-beta.5

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.
Files changed (68) hide show
  1. package/CHANGELOG.md +224 -62
  2. package/README.md +10 -4
  3. package/bin/make-icon-data.js +7 -3
  4. package/dist/babylon-3d.js +3 -1
  5. package/dist/code-editor-cm.d.ts +49 -0
  6. package/dist/code-editor-cm.js +268 -0
  7. package/dist/code-editor.d.ts +81 -9
  8. package/dist/code-editor.js +317 -75
  9. package/dist/doc-browser.d.ts +4 -0
  10. package/dist/doc-browser.js +50 -14
  11. package/dist/doc-system/book-html.js +7 -2
  12. package/dist/doc-system/book-manifest.js +1 -3
  13. package/dist/doc-system/doc-system-styles.d.ts +2 -0
  14. package/dist/doc-system/doc-system-styles.js +112 -0
  15. package/dist/doc-system/doc-system.js +20 -13
  16. package/dist/doc-system/nav-tree.js +0 -0
  17. package/dist/doc-system/render.d.ts +8 -1
  18. package/dist/doc-system/render.js +36 -17
  19. package/dist/doc-system/routing.js +5 -4
  20. package/dist/doc-system/site/bundle-guard.d.ts +59 -0
  21. package/dist/doc-system/site/bundle-guard.js +122 -0
  22. package/dist/doc-system/site/check-examples-cli.js +9 -2
  23. package/dist/doc-system/site/check-examples.d.ts +18 -2
  24. package/dist/doc-system/site/check-examples.js +30 -5
  25. package/dist/doc-system/site/dev-server.js +53 -61
  26. package/dist/doc-system/site/docs.d.ts +4 -0
  27. package/dist/doc-system/site/docs.js +1 -1
  28. package/dist/doc-system/site/epub.d.ts +9 -0
  29. package/dist/doc-system/site/epub.js +67 -11
  30. package/dist/doc-system/site/generate-css.js +7 -5
  31. package/dist/doc-system/site/generate-site.d.ts +18 -2
  32. package/dist/doc-system/site/generate-site.js +76 -21
  33. package/dist/doc-system/site/make-llms-txt.js +20 -2
  34. package/dist/doc-system/site/orchestrator.js +159 -34
  35. package/dist/doc-system/site/site-config.d.ts +4 -4
  36. package/dist/hydrate/ajs-language-h1x0ydap.js +11 -0
  37. package/dist/hydrate/ajs-language-h1x0ydap.js.map +10 -0
  38. package/dist/hydrate/code-editor-cm-2hgj9002.js +10 -0
  39. package/dist/hydrate/code-editor-cm-2hgj9002.js.map +20 -0
  40. package/dist/hydrate/hydrate.js +214 -0
  41. package/dist/hydrate/hydrate.js.map +74 -0
  42. package/dist/hydrate/index-iife-5wzyvyzm.js +27 -0
  43. package/dist/hydrate/index-iife-5wzyvyzm.js.map +22 -0
  44. package/dist/hydrate/index-iife-64z9yngn.js +5 -0
  45. package/dist/hydrate/index-iife-64z9yngn.js.map +9 -0
  46. package/dist/hydrate/index-iife-x2h4f6fc.js +14 -0
  47. package/dist/hydrate/index-iife-x2h4f6fc.js.map +12 -0
  48. package/dist/hydrate/index-nsmyq9mv.js +6 -0
  49. package/dist/hydrate/index-nsmyq9mv.js.map +10 -0
  50. package/dist/iife.js +155 -109
  51. package/dist/iife.js.map +64 -35
  52. package/dist/live-example/code-transform.js +45 -8
  53. package/dist/live-example/component.d.ts +15 -0
  54. package/dist/live-example/component.js +446 -48
  55. package/dist/live-example/example-store.d.ts +1 -0
  56. package/dist/live-example/execution.d.ts +29 -1
  57. package/dist/live-example/execution.js +51 -11
  58. package/dist/live-example/insert-examples.js +41 -1
  59. package/dist/localize.js +2 -1
  60. package/dist/mapbox.d.ts +1 -0
  61. package/dist/mapbox.js +24 -5
  62. package/dist/tooltip.js +3 -1
  63. package/dist/tsconfig.tsbuildinfo +1 -1
  64. package/dist/version.d.ts +1 -1
  65. package/dist/version.js +1 -1
  66. package/llms.txt +9 -2
  67. package/package.json +19 -4
  68. package/tls/create-dev-certs.sh +25 -9
package/CHANGELOG.md CHANGED
@@ -1,65 +1,215 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.7.0-beta.3
4
+
5
+ **Self-contained examples, and CodeMirror + the tjs transpiler are now edit-time only.** A
6
+ reader loading a doc page — directly or via client-side navigation — runs every example with
7
+ **neither the tjs transpiler nor CodeMirror on first paint**. Both load only when you open a
8
+ code panel to edit.
9
+
10
+ Still a beta under the `beta` tag (`latest` stays 1.6.x): `npm i tosijs-ui@beta`.
11
+
12
+ ### Examples run without the transpiler
13
+
14
+ Each `tjs` example is transpiled at build time and its JavaScript is baked into the page as a
15
+ hidden, non-executing `<script type="application/tosi-transpiled">`; the example runs from that
16
+ bake. Plain `js` examples need no transpiler at all (`loadTransform('js')` is now identity). The
17
+ bakes also ship per-doc in `docs.json`, so client-side navigation gets them too — at **zero
18
+ added bytes for prose/book sites** (only docs with code examples carry bakes). Editing an
19
+ example drops the stale bake and transpiles on demand; a saved local edit keeps its own
20
+ transpiled code so it reloads without the transpiler.
21
+
22
+ ### CodeMirror panels build lazily
23
+
24
+ `<tosi-example>` no longer constructs its `<tosi-code>` panels up front (this delivers the
25
+ beta.2 "Remaining" note above): the panel — and the CodeMirror chunk — is built on first
26
+ `showCode`. A page with examples now ships zero CodeMirror until a reader opens a panel.
27
+
28
+ ### tjs-lang 0.9.1 → 0.10.1
29
+
30
+ Bumped the transpiler, **skipping 0.10.0** (it triggered a memory storm rooted in a bun bug;
31
+ 0.10.1 carries the fix). 0.10.x closed four upstream issues, letting this release **delete ~272
32
+ lines** of hand-rolled scope-scanning and a hand-declared autocomplete-config type in favor of
33
+ tjs-lang's own exports. The inline-WASM guard was updated for 0.10.x's renamed compiled export.
34
+
35
+ - `tjs-lang` peer: `^0.9.1` → `^0.10.1` (and the `TJS_VERSION` CDN-fallback pin, in lockstep).
36
+
37
+ ## 1.7.0-beta.2
38
+
39
+ The code editor moved from **ACE to [CodeMirror 6](https://codemirror.net/)**, `tjs`
40
+ became a first-class editing mode with runtime-value autocomplete, the doc-site builder
41
+ gained the hooks that unblock the tosijs 2.0 TJS port — and generated doc pages are now
42
+ **readable before any JavaScript runs**.
43
+
44
+ **A beta, published under npm's `beta` tag** — `latest` stays on 1.6.x. A prerelease is not
45
+ matched by `^1.6.x` (or by `^1.7.0`), so nobody is auto-upgraded into the editor swap; you get
46
+ this only by asking for it:
47
+
48
+ ```
49
+ npm i tosijs-ui@beta # or tosijs-ui@1.7.0-beta.2
50
+ ```
51
+
52
+ ### Doc pages no longer wait for the bundle
53
+
54
+ Generated pages used to hide the body (`opacity: 0`, with a 4s safety-net timeout) until
55
+ hydration, because hydration injected the whole page chrome and the reflow would have been
56
+ ugly. **That gate is gone.** The chrome is pre-rendered, so the page is styled, readable and
57
+ navigable — real `<a>` links, real headings — before a byte of JS executes, and hydration is
58
+ purely additive: nothing moves.
59
+
60
+ Measured on the built site, gzipped, CPU-throttled — blank-screen duration:
61
+
62
+ | device | before | after |
63
+ | -------------------------- | -------------------------------- | ---------- |
64
+ | cheap phone / Pi4, slow 4G | 4532ms | **1635ms** |
65
+ | cheap phone / Pi4, 3G | 4837ms — _hit the 4s safety net_ | **1635ms** |
66
+
67
+ The bundle now gates **editing**, not **reading** — which was the point.
68
+
69
+ Two regressions against that promise were caught in review and fixed here: the nav was styled
70
+ by two hand-copied rule sets that had drifted (so it reflowed ~4px per row on hydration), and
71
+ the page `<title>` was derived twice (so the home page flipped from its real title to
72
+ `tosijs-ui — tosijs-ui`, [#6](https://github.com/tonioloewald/tosijs-ui/issues/6)). Both are
73
+ now single, shared rules, and `tests/hydration.pw.ts` asserts that a no-JS page and a hydrated
74
+ page agree — geometry, styling and title.
75
+
76
+ ### Doc pages no longer ship CodeMirror to readers who don't open an editor
77
+
78
+ `dist/iife.js` can't code-split (bun's IIFE format), so `<tosi-code>`'s lazy `import()` is
79
+ flattened in — CodeMirror + lezer + acorn on every page whether or not it has an editor
80
+ (121KB → 388KB gzip). The generated **doc pages now load an ESM `--splitting` hydration bundle**
81
+ (`<script type="module">`) instead: the always-loaded entry is **~123KB gzip** and CodeMirror
82
+ rides a lazy chunk pulled only when an editor mounts. The tjs CM extension stays bundled, and
83
+ splitting preserves the shared single `@codemirror/state`. **`dist/iife.js` is unchanged and
84
+ still shipped for the CDN `<script>` path.** So a **pure-docs / book site with no code
85
+ examples now ships zero CodeMirror** — the case that was hurt worst.
86
+
87
+ Remaining (tracked in `TODO.md`): a page that DOES have live examples still eager-loads the
88
+ editor chunk, because `<tosi-example>` builds its code panels up front even while hidden. The
89
+ next step defers that construction until the reader opens a panel; the example still runs (the
90
+ preview and inline tests don't need the editors) — only the code view waits. **(Delivered in
91
+ 1.7.0-beta.3 — see below.)**
92
+
93
+ ### Dev-server safety (also in 1.6.23)
94
+
95
+ A leaking dev server took a machine down twice. The guards, all in `tosijs-ui/site`:
96
+
97
+ - **Machine-health preflight** before every build and dev-server launch: refuses to add load to
98
+ a machine that is already dying, and names the offending PIDs, sizes, ages and project dirs.
99
+ `preflight: 'fail' | 'warn' | false` in the site config; `DEV_SKIP_PREFLIGHT=1` to skip. Warns
100
+ rather than refuses in CI.
101
+ - **`idleTimeoutHours` (default 8)** — ⚠️ **a behavior change**: your dev server now exits after
102
+ 8 idle hours (no request, no rebuild). A forgotten dev server is not inert — it is a days-old
103
+ process still running the code it loaded at launch. Set `idleTimeoutHours: 0` to disable.
104
+ - **RSS ceiling** (`memoryLimitMb`, default 4096) sampled every 60s, not just after a rebuild.
105
+ - **Rebuild-loop detector** — a build that writes a file it also watches now stops, and names
106
+ the file, instead of spawning a bundler forever.
107
+ - The example check, the ePub build, and the bundle gzip all moved into **child processes**;
108
+ `Bun.build()` strands ~30MB of native arena per call ([oven-sh/bun#34053](https://github.com/oven-sh/bun/issues/34053), still open).
109
+ - **`killStrayServer` no longer `kill -9`s every process _connected to_ the dev port** — it used
110
+ `lsof -ti:PORT`, which matches clients as well as the listener, so it could kill your browser.
111
+ - haltija is spawned as a **pinned range** (`haltija@^1.4.0`, override with `HALTIJA_VERSION`),
112
+ not a floating `@latest`, and its teardown kills only its own process tree. The 1.4.0 floor
113
+ is deliberate: it is the first haltija that routes `hj` by working directory, never overwrites
114
+ a newer machine-wide `hj`, and exits non-zero on a failed command — so a project's dev server
115
+ drives its own browser and can't silently downgrade another project's CLI.
116
+
117
+ ### Breaking
118
+
119
+ `<tosi-code>` (ACE → CodeMirror 6). Each removed member now **warns once and no-ops**
120
+ rather than failing silently, but they are gone:
121
+
122
+ | removed | replacement |
123
+ | --------------------------------- | -------------------------------------------------- |
124
+ | `theme` attribute | style the editor with `--code-bg` / `--text-color` |
125
+ | `options` property (ACE-shaped) | configure via `editor` (a CodeMirror `EditorView`) |
126
+ | `ace` getter | there is no ACE global; use `editor` |
127
+ | `editor.session.getUndoManager()` | `undo()` / `redo()` / `canUndo()` / `canRedo()` |
128
+
129
+ **`editor` changed type in place** — it was an ACE `Editor`, it is now a CodeMirror
130
+ [`EditorView`](https://codemirror.net/docs/ref/#view.EditorView). A grep for the removed
131
+ names will not catch this, and the warn-once shims above **cannot** catch it either: the
132
+ property still exists and still returns an object; it is simply a different object. So
133
+ **`editor` now warns once on first access**, naming what moved — one line in the console
134
+ beats a `TypeError` from inside a library you have never opened. TypeScript users get a
135
+ compile error instead (1.6 typed it `any`; 1.7 types it `EditorView | undefined`).
136
+
137
+ **`change` now means the _user_ changed it.** The event is new in 1.7, and it fires only
138
+ on user edits — a programmatic `el.value = doc` (loading a document) does not fire it, and
139
+ neither does writing into a `disabled` editor. Without that, every app that populates an
140
+ editor would record a spurious save/dirty-flag on open. Programmatic sets are also not
141
+ undoable: loading a document is not an edit to Ctrl+Z back out of.
142
+
143
+ Unchanged: `value`, `original` / `showDiff()`, `mode`, `disabled`.
144
+
145
+ **tosijs floor is now `^1.6.9`.** 1.6.9 fixes the `parts` proxy so a pre-hydration access no
146
+ longer poisons it, and adds public `hydrated` / `whenHydrated` seams
147
+ ([tosijs#13](https://github.com/tonioloewald/tosijs/issues/13)). Two internal hand-rolled
148
+ hydration guards (`<tosi-code>`, `<tosi-example>`) were deleted in favor of the official
149
+ `this.hydrated` — so any component that reaches into `parts` from a getter is safe against the
150
+ old "read it once and it's bricked forever" trap.
151
+
152
+ **Semver stance (deliberate, not an oversight).** This library breaks in minors before 2.0 —
153
+ **`2.0` is reserved for the tjs-native rewrite**, not for this. So `^1.6.x` resolves `1.7.0` and
154
+ existing consumers pick this up on their next install.
155
+
156
+ **If you use `<tosi-code>`, pin `~1.6` and upgrade deliberately.** Everything else in the library
157
+ is untouched, so a consumer of (say) `<tosi-rating>` can take 1.7 without changes — but note it
158
+ now installs 12 `@codemirror/*` runtime dependencies where the library previously had none.
159
+
3
160
  ## 1.6.23
4
161
 
5
- **The two biggest sources of ecosystem-wide friction — runaway dev servers and haltija
6
- conflicts — fixed in the version people actually run.** If you use `tosijs-ui/site`, update.
7
-
8
- ### Machine-safety guards (a leaking/forgotten dev server took a machine down twice)
9
-
10
- - **`killStrayServer` no longer `kill -9`s processes merely _connected_ to its port.** It freed
11
- its port with `lsof -ti:PORT | xargs kill -9`, and `lsof -i:PORT` matches sockets whose local
12
- **or remote** port is PORT — so it SIGKILLed every _client_ of that port, not just the
13
- listener: the browser reading your page, an editor's language server, anything with a
14
- connection. It now signals **only the process listening** on the port, only after confirming
15
- it is a JS runtime, SIGTERM first and SIGKILL only as a fallback.
16
-
17
- - **Machine-health preflight** before each build and at dev-server launch (and on a 60s tick):
18
- refuses to add load to a machine that is already dying — a runaway dev server, a VM stall.
19
- Names the offending PIDs, sizes, ages and project dirs. **Local LLM runtimes (LM Studio,
20
- ollama, llama.cpp, mlx_lm, vLLM, …) are exempt** — their memory shrinks the dev budget rather
21
- than tripping the guard, and a big _non-dev_ process (Docker, a JVM, a database) only warns,
22
- never fails. It never kills anything; it declines to _start_. `preflight: 'fail' | 'warn' |
23
- false` in the site config, or `DEV_SKIP_PREFLIGHT=1`; auto-downgraded to a warning in CI.
24
-
25
- - **`idleTimeoutHours` (default 8)** — ⚠️ **behavior change:** the dev server now exits after 8
26
- idle hours (no request, no rebuild). A forgotten dev server is not inert — it is a days-old
27
- process still running the code it loaded at launch (updating the package does nothing for it).
28
- `idleTimeoutHours: 0` disables it.
29
-
30
- - **RSS ceiling** (`memoryLimitMb`) sampled every 60s, and a **rebuild-loop detector** that
31
- stops a build which writes a file it also watches instead of spawning a bundler forever.
32
-
33
- ### haltija
34
-
35
- - Spawned as a **pinned range (`haltija@^1.4.0`)**, overridable with `HALTIJA_VERSION`, instead
36
- of a floating `@latest` fetched fresh on every adopter's machine. The 1.4.0 floor is
37
- deliberate: it routes `hj` by working directory (so a project's dev server drives its own
38
- browser, not whichever was focused), never overwrites a newer machine-wide `hj`, and exits
39
- non-zero on a failed command — which the doc-test lane now checks instead of racing to a
40
- timeout. Teardown kills only its own process tree, never a haltija you were already running.
41
-
42
- ### Also fixed
43
-
44
- - **Builds again against tosijs 1.6.9.** `<tosi-example>` detected hydration with a
45
- `try { this.parts.js } catch` probe, which before tosijs 1.6.9 permanently poisoned the
46
- `parts` proxy on the pre-hydration read it performed (it could blank the whole doc page), and
47
- whose `private get hydrated()` collided with 1.6.9's new public `hydrated` (a `tsc` error, so
48
- the package could not build against current tosijs). The probe is gone — it uses the base
49
- class's `this.hydrated` now — and the tosijs floor moves to **`^1.6.9`**
50
- ([tosijs#13](https://github.com/tonioloewald/tosijs/issues/13)).
51
-
52
- - **The doc-browser no longer double-suffixes the page `<title>`.** On path routing it re-derived
53
- the title on hydration, ignoring `headTitle` and re-appending the project name to a title that
54
- already contained it — so the home page flipped from its real title to `tosijs-ui — tosijs-ui`
55
- the moment the bundle loaded. The static generator and the runtime now share **one**
56
- `pageTitle` rule (case-insensitive, both-directions containment check; whitespace-only titles
57
- and project names handled). Fixes [#6](https://github.com/tonioloewald/tosijs-ui/issues/6).
58
-
59
- - **Two more per-rebuild build leaks moved to child processes** (the dev server lives for days):
60
- the live-example **check** (`new AsyncFunction` per block + a `Bun.Transpiler` per `ts` block)
61
- and the bundle **gzip** (native zlib). Both now run in a child whose memory the OS reclaims on
62
- exit; the gzip stays zlib-in-a-child (not the `gzip` CLI) so the reported size doesn't drift.
162
+ **Dev-server safety.** Everything under "Dev-server safety" above, backported — this is the
163
+ release every `tosijs-ui/site` consumer wants, and it needs no code changes.
164
+
165
+ The one to know about: **`killStrayServer` was `kill -9`ing every process _connected to_ the
166
+ dev port, not just the listener.** `lsof -i:PORT` matches sockets whose local _or remote_ port
167
+ is `PORT`, so `bun start` could SIGKILL the browser reading your page, Playwright's browsers,
168
+ or an editor's language server. Now it signals only the listening process, only if it is a JS
169
+ runtime, SIGTERM first.
170
+
171
+ ⚠️ **Behavior change:** the dev server now exits after **8 idle hours** (`idleTimeoutHours: 0`
172
+ to disable), and refuses to start on a machine that is already out of memory
173
+ (`DEV_SKIP_PREFLIGHT=1`, or `preflight: 'warn' | false`).
174
+
175
+ The trap to know about: **`editor` changed type in place** and no shim can catch it. The removed
176
+ `theme` / `options` / `ace` members warn once and no-op, but `el.editor` still exists — it is
177
+ simply a CodeMirror `EditorView` now, so `el.editor.session.*` is a runtime `TypeError`. A grep
178
+ for the removed names will not find it.
179
+
180
+ ### Added
181
+
182
+ - `<tosi-code>` gained a `change` event (`event.detail.value`), `undo()` / `redo()` /
183
+ `canUndo()` / `canRedo()`, and `tjs` / `ajs` modes.
184
+ - **Runtime-value autocomplete** in `tjs` mode: set `tjsAutocomplete` and completion
185
+ suggests the _real members of live values_ — including tosijs proxy members that no
186
+ static analysis can see. Live examples wire their own executed scope into it, so
187
+ `const { app } = tosi(…)` gives real `app.` / `app.items.` completions.
188
+ - Inline **WebAssembly** live examples (tjs `wasm {}` blocks).
189
+ - `buildSite`: `libraryBuild` and `generateCssPreload` hooks, for projects whose
190
+ library sources are native `.tjs` (this is what the tosijs 2.0 TJS port needs).
191
+ **These actually shipped in 1.6.21** — they are listed here only because they landed on this
192
+ branch first. Nothing needs 1.7 to use them.
193
+
194
+ ### Changed
195
+
196
+ - **`dist/iife.js` is ~384KB gzipped, up from ~120KB.** Bun's IIFE format cannot
197
+ code-split, so CodeMirror is inlined there. (Under a bundler/ESM it stays a lazy
198
+ chunk — a page with no `<tosi-code>` doesn't load it.) This is deliberate: the
199
+ in-page editor and its save-to-source flow are the point of the doc-system, so the
200
+ IIFE carries the editor.
201
+ - The library now has runtime `dependencies` (12 `@codemirror/*` packages) where it
202
+ previously had none. They can't be optional peers: the tjs CodeMirror extension must
203
+ share this exact `@codemirror/state` instance or it silently no-ops.
204
+ - `tjs-lang` peer: `^0.8.7` → `^0.9.1`.
205
+
206
+ ### Fixed
207
+
208
+ - `showDiff()` rendered nothing. Giving `<tosi-code>` its own `content` displaced the
209
+ default `<slot>` that used to project the light-DOM diff overlay, so the overlay was
210
+ invisible (0×0) while `showingDiff` still reported `true`. It now renders inside the
211
+ shadow root. This is the review step of the doc-system's edit-and-save-to-source
212
+ flow, so a blank diff meant saving changes you never saw.
63
213
 
64
214
  ## 1.6.22
65
215
 
@@ -94,8 +244,19 @@ conflicts — fixed in the version people actually run.** If you use `tosijs-ui/
94
244
 
95
245
  ## 1.6.21
96
246
 
97
- - Memory-routed nav-toggle fix; `buildSite` `.tjs` hooks (`libraryBuild`,
98
- `generateCssPreload` — see BUILD-TJS-HOOK.md); tjs-lang 0.9.0.
247
+ ### Fixed
248
+
249
+ - Doc-system nav-toggle in `routing: 'memory'` mode drove the _outer_ doc-browser
250
+ instance instead of its own (now scoped per-instance).
251
+
252
+ ### Added
253
+
254
+ - `buildSite` `libraryBuild` + `generateCssPreload` hooks (also in 1.7.0 above), so a
255
+ project whose library source is native `.tjs` can build through the doc-site pipeline.
256
+
257
+ ### Changed
258
+
259
+ - `tjs-lang` peer: `^0.8.7` → `^0.9.0`.
99
260
 
100
261
  ## 1.6.20
101
262
 
@@ -124,7 +285,7 @@ Doc-system tooling; no component API changes.
124
285
  - **Build-time example transpile check.** Every executable live-example block
125
286
  (`js` / `tjs` / `ts` / `test`) across the whole corpus is run through the front
126
287
  half of the runtime pipeline — `rewriteImports` → transform → `new
127
- AsyncFunction` — at build time, **without executing it**, so a block that can't
288
+ AsyncFunction` — at build time, **without executing it**, so a block that can't
128
289
  build (a syntax/import error, or illustrative code mistakenly tagged with an
129
290
  executable language instead of the display-only `typescript`) **fails the build**
130
291
  with the offending doc/block named, on every page — including fences hidden in
@@ -138,7 +299,7 @@ Doc-system tooling; no component API changes.
138
299
  ### Fixed
139
300
 
140
301
  - **A live example's build/exec failure is now a test failure whether or not it
141
- defines `test` blocks.** So on any page the browser test runner loads, *all* of
302
+ defines `test` blocks.** So on any page the browser test runner loads, _all_ of
142
303
  its examples are checked for explosions — a no-test example that throws is
143
304
  reported as a failed test — not just blocks with explicit assertions.
144
305
 
@@ -339,6 +500,7 @@ below.
339
500
 
340
501
  - **Subpath exports**, so an app can import only what it needs without the barrel
341
502
  dragging in dev tools:
503
+
342
504
  - curated: `tosijs-ui/icons`, `tosijs-ui/code-editor`, `tosijs-ui/live-example`,
343
505
  `tosijs-ui/doc-browser`, `tosijs-ui/diff`, `tosijs-ui/theme`
344
506
  - per-component wildcard: `import { tosiRating } from 'tosijs-ui/rating'`
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # tosijs-ui
2
2
 
3
- <!--{ "pin": "top", "headTitle": "tosijs-ui — robust, dependency-free web components", "description": "A small, fast library of standards-based web components (data tables, dialogs, forms, rich text, carousels, and more) built on tosijs — smaller and faster than a React app, with no virtual DOM.", "keywords": "web components, custom elements, tosijs, data table, dialog, form, rich text, no virtual dom" }-->
3
+ <!--{ "pin": "top", "headTitle": "tosijs-ui — robust, standards-based web components", "description": "A small, fast library of standards-based web components (data tables, dialogs, forms, rich text, carousels, and more) built on tosijs — smaller and faster than a React app, with no virtual DOM.", "keywords": "web components, custom elements, tosijs, data table, dialog, form, rich text, no virtual dom" }-->
4
4
 
5
5
  [ui.tosijs.net live demo](https://ui.tosijs.net) | [tosijs](https://tosijs.net) | [discord](https://discord.gg/ramJ9rgky5) | [github](https://github.com/tonioloewald/tosijs-ui#readme) | [npm](https://www.npmjs.com/package/tosijs-ui)
6
6
 
@@ -74,9 +74,15 @@ document.body.append(tosiTable())
74
74
 
75
75
  ### Using the iife via cdn
76
76
 
77
- The `tosijs-ui` iife build bundles `tosijs`, `tosijs-ui`, and `marked` into
78
- a single minified javascript source file. You can access `xinjs` and `xinjsui`
79
- as globals which contain all the things exported by `tosijs` and `tosijs-ui`.
77
+ The `tosijs-ui` iife build bundles `tosijs`, `tosijs-ui`, `marked` and — as of 1.7 —
78
+ **CodeMirror** into a single minified javascript source file. You can access `xinjs` and
79
+ `xinjsui` as globals which contain all the things exported by `tosijs` and `tosijs-ui`.
80
+
81
+ > **Size (1.7):** ~385KB gzip, up from ~120KB in 1.6. `bun build --format iife` cannot
82
+ > code-split, so `<tosi-code>`'s lazy CodeMirror import is flattened into this bundle
83
+ > whether or not the page uses an editor. **If you don't need `<tosi-code>`, use the ESM
84
+ > build** (`import 'tosijs-ui'` via a bundler), where CodeMirror stays a separate lazy
85
+ > chunk and a page with no editor never downloads it.
80
86
 
81
87
  ```
82
88
  <script src="https://ui.tosijs.net/iife.js"></script>
@@ -212,9 +212,13 @@ function findIcons(dirs, ignore = []) {
212
212
  } else if (path.extname(file) === '.svg') {
213
213
  const content = fs.readFileSync(filePath, 'utf8')
214
214
  const rawName = file.split('.')[0]
215
- const names = rawName.split(',').map((n) =>
216
- n.trim().replace(/-([a-z0-9])/g, (_, char) => char.toLocaleUpperCase())
217
- )
215
+ const names = rawName
216
+ .split(',')
217
+ .map((n) =>
218
+ n
219
+ .trim()
220
+ .replace(/-([a-z0-9])/g, (_, char) => char.toLocaleUpperCase())
221
+ )
218
222
  const name = names[0]
219
223
  let svgSource = content
220
224
  .replace(/(<\?xml.*?>|<!DOCTYPE.*?>)\s?/g, '')
@@ -345,7 +345,9 @@ export class B3d extends WebComponent {
345
345
  this.BABYLON = BABYLON;
346
346
  // A `transparent` (alpha < 1) clear-color needs an alpha WebGL context so
347
347
  // the canvas composites over the page.
348
- const clearColor = this.clearColor ? toColor4(BABYLON, this.clearColor) : null;
348
+ const clearColor = this.clearColor
349
+ ? toColor4(BABYLON, this.clearColor)
350
+ : null;
349
351
  this.engine = new BABYLON.Engine(canvas, true, clearColor && clearColor.a < 1
350
352
  ? { alpha: true, premultipliedAlpha: false }
351
353
  : undefined);
@@ -0,0 +1,49 @@
1
+ import { EditorView } from '@codemirror/view';
2
+ import { Extension } from '@codemirror/state';
3
+ /** Map a `<tosi-code mode>` value to a CodeMirror language extension. */
4
+ export declare function languageForMode(mode: string): Extension;
5
+ /**
6
+ * Runtime-introspection hooks for tjs autocomplete (all optional). tjs-lang 0.10.0+
7
+ * ships this type (tjs-lang#12 — we used to hand-declare it); aliased so the public
8
+ * `TjsAutocompleteConfig` name stays stable. `import type` is erased at build, so this
9
+ * adds nothing to the bundle.
10
+ */
11
+ import type { AutocompleteConfig } from 'tjs-lang/editors/codemirror';
12
+ export type TjsAutocompleteConfig = AutocompleteConfig;
13
+ /**
14
+ * Lazy-load tjs-lang's CodeMirror language + completion bundle. Returns a single
15
+ * CodeMirror `Extension` (tjs language, forbidden-keyword highlighting, theme, and
16
+ * `tjsCompletionSource`-driven autocomplete) suitable for `setLanguageExtension()`,
17
+ * or `null` when tjs-lang (an optional peer) isn't installed or its editor build
18
+ * lacks `tjsEditorExtension`. The dynamic import keeps it out of the bundle until a
19
+ * tjs editor actually mounts.
20
+ */
21
+ export declare function loadTjsExtension(autocomplete?: TjsAutocompleteConfig): Promise<Extension | null>;
22
+ export interface CmHandle {
23
+ view: EditorView;
24
+ getValue(): string;
25
+ setValue(text: string): void;
26
+ setMode(mode: string): void;
27
+ /** Swap the language compartment wholesale (e.g. an async-loaded tjs bundle). */
28
+ setLanguageExtension(ext: Extension): void;
29
+ setReadOnly(readOnly: boolean): void;
30
+ undo(): void;
31
+ redo(): void;
32
+ canUndo(): boolean;
33
+ canRedo(): boolean;
34
+ focus(): void;
35
+ refresh(): void;
36
+ destroy(): void;
37
+ }
38
+ export interface CmOptions {
39
+ value?: string;
40
+ mode?: string;
41
+ readOnly?: boolean;
42
+ /** additional language-adjacent extensions (e.g. a tjs language + autocomplete) */
43
+ languageExtension?: Extension;
44
+ onChange?: (value: string) => void;
45
+ /** style-injection root — pass the host's ShadowRoot when mounted in shadow DOM */
46
+ root?: Document | ShadowRoot;
47
+ }
48
+ /** Create a CodeMirror editor mounted in `parent`, returning an editor-agnostic handle. */
49
+ export declare function createCmEditor(parent: HTMLElement, opts?: CmOptions): CmHandle;