tosijs-ui 1.7.0-beta.1 → 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.
- package/CHANGELOG.md +150 -23
- package/README.md +10 -4
- package/bin/make-icon-data.js +7 -3
- package/dist/babylon-3d.js +3 -1
- package/dist/code-editor-cm.d.ts +8 -7
- package/dist/code-editor-cm.js +28 -3
- package/dist/code-editor.d.ts +19 -3
- package/dist/code-editor.js +66 -19
- package/dist/doc-browser.d.ts +4 -0
- package/dist/doc-browser.js +54 -15
- package/dist/doc-system/book-html.js +7 -2
- package/dist/doc-system/book-manifest.js +1 -3
- package/dist/doc-system/doc-system-styles.d.ts +2 -0
- package/dist/doc-system/doc-system-styles.js +112 -0
- package/dist/doc-system/doc-system.js +20 -13
- package/dist/doc-system/doc-title.d.ts +19 -0
- package/dist/doc-system/doc-title.js +51 -0
- package/dist/doc-system/nav-tree.js +0 -0
- package/dist/doc-system/render.d.ts +8 -1
- package/dist/doc-system/render.js +36 -17
- package/dist/doc-system/routing.js +5 -4
- package/dist/doc-system/site/bundle-guard.d.ts +12 -3
- package/dist/doc-system/site/bundle-guard.js +15 -4
- package/dist/doc-system/site/check-examples-cli.d.ts +1 -0
- package/dist/doc-system/site/check-examples-cli.js +46 -0
- package/dist/doc-system/site/check-examples.d.ts +18 -2
- package/dist/doc-system/site/check-examples.js +27 -10
- package/dist/doc-system/site/dev-server.d.ts +26 -0
- package/dist/doc-system/site/dev-server.js +442 -115
- package/dist/doc-system/site/docs.d.ts +4 -0
- package/dist/doc-system/site/docs.js +1 -1
- package/dist/doc-system/site/epub.d.ts +9 -0
- package/dist/doc-system/site/epub.js +39 -2
- package/dist/doc-system/site/generate-css.js +7 -5
- package/dist/doc-system/site/generate-site.d.ts +18 -2
- package/dist/doc-system/site/generate-site.js +80 -27
- package/dist/doc-system/site/make-llms-txt.js +3 -1
- package/dist/doc-system/site/orchestrator.js +169 -6
- package/dist/doc-system/site/preflight.d.ts +152 -0
- package/dist/doc-system/site/preflight.js +401 -0
- package/dist/doc-system/site/site-config.d.ts +24 -0
- package/dist/hydrate/ajs-language-h1x0ydap.js +11 -0
- package/dist/hydrate/ajs-language-h1x0ydap.js.map +10 -0
- package/dist/hydrate/code-editor-cm-2hgj9002.js +10 -0
- package/dist/hydrate/code-editor-cm-2hgj9002.js.map +20 -0
- package/dist/hydrate/hydrate.js +214 -0
- package/dist/hydrate/hydrate.js.map +74 -0
- package/dist/hydrate/index-iife-5wzyvyzm.js +27 -0
- package/dist/hydrate/index-iife-5wzyvyzm.js.map +22 -0
- package/dist/hydrate/index-iife-64z9yngn.js +5 -0
- package/dist/hydrate/index-iife-64z9yngn.js.map +9 -0
- package/dist/hydrate/index-iife-x2h4f6fc.js +14 -0
- package/dist/hydrate/index-iife-x2h4f6fc.js.map +12 -0
- package/dist/hydrate/index-nsmyq9mv.js +6 -0
- package/dist/hydrate/index-nsmyq9mv.js.map +10 -0
- package/dist/iife.js +127 -132
- package/dist/iife.js.map +39 -37
- package/dist/live-example/code-transform.d.ts +0 -39
- package/dist/live-example/code-transform.js +37 -301
- package/dist/live-example/component.d.ts +5 -1
- package/dist/live-example/component.js +177 -41
- package/dist/live-example/example-store.d.ts +1 -0
- package/dist/live-example/execution.d.ts +15 -3
- package/dist/live-example/execution.js +30 -11
- package/dist/live-example/insert-examples.js +41 -1
- package/dist/localize.js +2 -1
- package/dist/mapbox.d.ts +1 -0
- package/dist/mapbox.js +24 -5
- package/dist/tooltip.js +3 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/llms.txt +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,43 +1,154 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 1.7.0-beta.
|
|
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**.
|
|
4
43
|
|
|
5
44
|
**A beta, published under npm's `beta` tag** — `latest` stays on 1.6.x. A prerelease is not
|
|
6
45
|
matched by `^1.6.x` (or by `^1.7.0`), so nobody is auto-upgraded into the editor swap; you get
|
|
7
46
|
this only by asking for it:
|
|
8
47
|
|
|
9
48
|
```
|
|
10
|
-
npm i tosijs-ui@beta # or tosijs-ui@1.7.0-beta.
|
|
49
|
+
npm i tosijs-ui@beta # or tosijs-ui@1.7.0-beta.2
|
|
11
50
|
```
|
|
12
51
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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.
|
|
22
116
|
|
|
23
117
|
### Breaking
|
|
24
118
|
|
|
25
119
|
`<tosi-code>` (ACE → CodeMirror 6). Each removed member now **warns once and no-ops**
|
|
26
120
|
rather than failing silently, but they are gone:
|
|
27
121
|
|
|
28
|
-
| removed
|
|
29
|
-
|
|
|
30
|
-
| `theme` attribute
|
|
31
|
-
| `options` property (ACE-shaped)
|
|
32
|
-
| `ace` getter
|
|
33
|
-
| `editor.session.getUndoManager()` | `undo()` / `redo()` / `canUndo()` / `canRedo()`
|
|
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()` |
|
|
34
128
|
|
|
35
129
|
**`editor` changed type in place** — it was an ACE `Editor`, it is now a CodeMirror
|
|
36
|
-
[`EditorView`](https://codemirror.net/docs/ref/#view.EditorView). A grep for the
|
|
37
|
-
|
|
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.
|
|
38
142
|
|
|
39
143
|
Unchanged: `value`, `original` / `showDiff()`, `mode`, `disabled`.
|
|
40
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
|
+
|
|
41
152
|
**Semver stance (deliberate, not an oversight).** This library breaks in minors before 2.0 —
|
|
42
153
|
**`2.0` is reserved for the tjs-native rewrite**, not for this. So `^1.6.x` resolves `1.7.0` and
|
|
43
154
|
existing consumers pick this up on their next install.
|
|
@@ -46,6 +157,21 @@ existing consumers pick this up on their next install.
|
|
|
46
157
|
is untouched, so a consumer of (say) `<tosi-rating>` can take 1.7 without changes — but note it
|
|
47
158
|
now installs 12 `@codemirror/*` runtime dependencies where the library previously had none.
|
|
48
159
|
|
|
160
|
+
## 1.6.23
|
|
161
|
+
|
|
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
|
+
|
|
49
175
|
The trap to know about: **`editor` changed type in place** and no shim can catch it. The removed
|
|
50
176
|
`theme` / `options` / `ace` members warn once and no-op, but `el.editor` still exists — it is
|
|
51
177
|
simply a CodeMirror `EditorView` now, so `el.editor.session.*` is a runtime `TypeError`. A grep
|
|
@@ -56,7 +182,7 @@ for the removed names will not find it.
|
|
|
56
182
|
- `<tosi-code>` gained a `change` event (`event.detail.value`), `undo()` / `redo()` /
|
|
57
183
|
`canUndo()` / `canRedo()`, and `tjs` / `ajs` modes.
|
|
58
184
|
- **Runtime-value autocomplete** in `tjs` mode: set `tjsAutocomplete` and completion
|
|
59
|
-
suggests the
|
|
185
|
+
suggests the _real members of live values_ — including tosijs proxy members that no
|
|
60
186
|
static analysis can see. Live examples wire their own executed scope into it, so
|
|
61
187
|
`const { app } = tosi(…)` gives real `app.` / `app.items.` completions.
|
|
62
188
|
- Inline **WebAssembly** live examples (tjs `wasm {}` blocks).
|
|
@@ -120,7 +246,7 @@ for the removed names will not find it.
|
|
|
120
246
|
|
|
121
247
|
### Fixed
|
|
122
248
|
|
|
123
|
-
- Doc-system nav-toggle in `routing: 'memory'` mode drove the
|
|
249
|
+
- Doc-system nav-toggle in `routing: 'memory'` mode drove the _outer_ doc-browser
|
|
124
250
|
instance instead of its own (now scoped per-instance).
|
|
125
251
|
|
|
126
252
|
### Added
|
|
@@ -159,7 +285,7 @@ Doc-system tooling; no component API changes.
|
|
|
159
285
|
- **Build-time example transpile check.** Every executable live-example block
|
|
160
286
|
(`js` / `tjs` / `ts` / `test`) across the whole corpus is run through the front
|
|
161
287
|
half of the runtime pipeline — `rewriteImports` → transform → `new
|
|
162
|
-
|
|
288
|
+
AsyncFunction` — at build time, **without executing it**, so a block that can't
|
|
163
289
|
build (a syntax/import error, or illustrative code mistakenly tagged with an
|
|
164
290
|
executable language instead of the display-only `typescript`) **fails the build**
|
|
165
291
|
with the offending doc/block named, on every page — including fences hidden in
|
|
@@ -173,7 +299,7 @@ Doc-system tooling; no component API changes.
|
|
|
173
299
|
### Fixed
|
|
174
300
|
|
|
175
301
|
- **A live example's build/exec failure is now a test failure whether or not it
|
|
176
|
-
defines `test` blocks.** So on any page the browser test runner loads,
|
|
302
|
+
defines `test` blocks.** So on any page the browser test runner loads, _all_ of
|
|
177
303
|
its examples are checked for explosions — a no-test example that throws is
|
|
178
304
|
reported as a failed test — not just blocks with explicit assertions.
|
|
179
305
|
|
|
@@ -374,6 +500,7 @@ below.
|
|
|
374
500
|
|
|
375
501
|
- **Subpath exports**, so an app can import only what it needs without the barrel
|
|
376
502
|
dragging in dev tools:
|
|
503
|
+
|
|
377
504
|
- curated: `tosijs-ui/icons`, `tosijs-ui/code-editor`, `tosijs-ui/live-example`,
|
|
378
505
|
`tosijs-ui/doc-browser`, `tosijs-ui/diff`, `tosijs-ui/theme`
|
|
379
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,
|
|
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`,
|
|
78
|
-
a single minified javascript source file. You can access `xinjs` and
|
|
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>
|
package/bin/make-icon-data.js
CHANGED
|
@@ -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
|
|
216
|
-
|
|
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, '')
|
package/dist/babylon-3d.js
CHANGED
|
@@ -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
|
|
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);
|
package/dist/code-editor-cm.d.ts
CHANGED
|
@@ -2,13 +2,14 @@ import { EditorView } from '@codemirror/view';
|
|
|
2
2
|
import { Extension } from '@codemirror/state';
|
|
3
3
|
/** Map a `<tosi-code mode>` value to a CodeMirror language extension. */
|
|
4
4
|
export declare function languageForMode(mode: string): Extension;
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
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;
|
|
12
13
|
/**
|
|
13
14
|
* Lazy-load tjs-lang's CodeMirror language + completion bundle. Returns a single
|
|
14
15
|
* CodeMirror `Extension` (tjs language, forbidden-keyword highlighting, theme, and
|
package/dist/code-editor-cm.js
CHANGED
|
@@ -11,7 +11,7 @@ tjs (highlighting + runtime-value autocomplete via tjs-lang's editors/codemirror
|
|
|
11
11
|
layered in separately and only when tjs-lang is installed.
|
|
12
12
|
*/
|
|
13
13
|
import { EditorView, keymap, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine, } from '@codemirror/view';
|
|
14
|
-
import { EditorState, Compartment } from '@codemirror/state';
|
|
14
|
+
import { EditorState, Compartment, Annotation, Transaction, } from '@codemirror/state';
|
|
15
15
|
import { indentWithTab, history, defaultKeymap, historyKeymap, undo, redo, undoDepth, redoDepth, } from '@codemirror/commands';
|
|
16
16
|
import { indentUnit, foldGutter, foldKeymap, indentOnInput, syntaxHighlighting, defaultHighlightStyle, bracketMatching, } from '@codemirror/language';
|
|
17
17
|
import { closeBrackets, closeBracketsKeymap, autocompletion, completionKeymap, } from '@codemirror/autocomplete';
|
|
@@ -29,6 +29,21 @@ import { oneDarkHighlightStyle } from '@codemirror/theme-one-dark';
|
|
|
29
29
|
const isDarkMode = () => typeof document !== 'undefined' &&
|
|
30
30
|
!!document.body &&
|
|
31
31
|
document.body.classList.contains('darkmode');
|
|
32
|
+
/**
|
|
33
|
+
* Marks a transaction as OURS — a programmatic `value` set, not a user edit.
|
|
34
|
+
*
|
|
35
|
+
* `change` is documented as "fires when the text changes", and consumers write
|
|
36
|
+
* `code.addEventListener('change', e => save(e.detail.value))`. Without this, `el.value
|
|
37
|
+
* = doc` — merely LOADING a document — dispatches a CM transaction, `docChanged` is
|
|
38
|
+
* true, and the app records a spurious save/dirty-flag every time it populates the
|
|
39
|
+
* editor. A `disabled` (read-only) editor fired it too: `EditorState.readOnly` gates
|
|
40
|
+
* user input, not `view.dispatch`. The library itself does this in five places,
|
|
41
|
+
* including writing results into a read-only *output* editor after every example run.
|
|
42
|
+
*
|
|
43
|
+
* The event is new in 1.7 (the ACE build dispatched nothing), so there is no prior
|
|
44
|
+
* semantic to preserve — and tightening it after 1.7 is on `latest` would be breaking.
|
|
45
|
+
*/
|
|
46
|
+
const programmatic = Annotation.define();
|
|
32
47
|
const highlightFor = (dark) => dark
|
|
33
48
|
? syntaxHighlighting(oneDarkHighlightStyle)
|
|
34
49
|
: syntaxHighlighting(defaultHighlightStyle, { fallback: true });
|
|
@@ -189,8 +204,12 @@ export function createCmEditor(parent, opts = {}) {
|
|
|
189
204
|
language.of(langExt),
|
|
190
205
|
readonly.of(EditorState.readOnly.of(!!opts.readOnly)),
|
|
191
206
|
EditorView.updateListener.of((u) => {
|
|
192
|
-
if (u.docChanged
|
|
193
|
-
|
|
207
|
+
if (!u.docChanged || !opts.onChange)
|
|
208
|
+
return;
|
|
209
|
+
// A programmatic `value` set is not a change the USER made. See `programmatic`.
|
|
210
|
+
if (u.transactions.some((t) => t.annotation(programmatic)))
|
|
211
|
+
return;
|
|
212
|
+
opts.onChange(u.state.doc.toString());
|
|
194
213
|
}),
|
|
195
214
|
],
|
|
196
215
|
}),
|
|
@@ -213,6 +232,12 @@ export function createCmEditor(parent, opts = {}) {
|
|
|
213
232
|
return;
|
|
214
233
|
view.dispatch({
|
|
215
234
|
changes: { from: 0, to: view.state.doc.length, insert: text },
|
|
235
|
+
annotations: [
|
|
236
|
+
programmatic.of(true),
|
|
237
|
+
// Loading a document is not an edit to undo back out of. (The ACE wrapper
|
|
238
|
+
// called `getUndoManager().reset()` at this point, for the same reason.)
|
|
239
|
+
Transaction.addToHistory.of(false),
|
|
240
|
+
],
|
|
216
241
|
});
|
|
217
242
|
},
|
|
218
243
|
setMode(mode) {
|
package/dist/code-editor.d.ts
CHANGED
|
@@ -28,9 +28,7 @@ export declare class CodeEditor extends WebComponent<CodeEditorParts> {
|
|
|
28
28
|
get original(): string;
|
|
29
29
|
set original(text: string);
|
|
30
30
|
private diffOverlay;
|
|
31
|
-
private _partsHydrated;
|
|
32
31
|
private _pendingDiff;
|
|
33
|
-
private get partsReady();
|
|
34
32
|
get showingDiff(): boolean;
|
|
35
33
|
showDiff(on: boolean): void;
|
|
36
34
|
static initAttributes: {
|
|
@@ -38,7 +36,22 @@ export declare class CodeEditor extends WebComponent<CodeEditorParts> {
|
|
|
38
36
|
disabled: boolean;
|
|
39
37
|
};
|
|
40
38
|
role: string;
|
|
41
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* The underlying CodeMirror `EditorView` (undefined until loaded).
|
|
41
|
+
*
|
|
42
|
+
* **Changed in 1.7 (ACE → CodeMirror 6).** In 1.6 this was an ACE editor, and
|
|
43
|
+
* `editor.session.getUndoManager()` was documented public API. `^1.6.x` resolves
|
|
44
|
+
* 1.7.0, so an app that never changed a line auto-upgrades into a `TypeError` on the
|
|
45
|
+
* next install — and this is the ONE break the warn-once shims below cannot catch,
|
|
46
|
+
* because the property still exists and still returns an object; it is simply a
|
|
47
|
+
* different object. TS consumers get a compile error (1.6 typed this `any`); vanilla
|
|
48
|
+
* JS and CDN consumers — the audience this component's own docs court — would get the
|
|
49
|
+
* bare TypeError with no explanation at all.
|
|
50
|
+
*
|
|
51
|
+
* So: say it once, on first access. One line in the console beats a stack trace in a
|
|
52
|
+
* library the reader has never opened. Use `undo()`/`redo()`/`canUndo()`/`canRedo()`
|
|
53
|
+
* for history — they are the supported surface and they survived the migration.
|
|
54
|
+
*/
|
|
42
55
|
get editor(): CmHandle['view'] | undefined;
|
|
43
56
|
/** @deprecated Removed in 1.7 — CodeMirror themes via `--code-bg`/`--text-color`. */
|
|
44
57
|
get theme(): string;
|
|
@@ -88,6 +101,9 @@ export declare class CodeEditor extends WebComponent<CodeEditorParts> {
|
|
|
88
101
|
* installed, or if the mode/handle changed before the async load resolved.
|
|
89
102
|
*/
|
|
90
103
|
private applyTjsExtension;
|
|
104
|
+
/** True once tjs-lang's CM language+autocomplete is actually live (test seam). */
|
|
105
|
+
get tjsExtensionApplied(): boolean;
|
|
106
|
+
private _tjsExtensionApplied;
|
|
91
107
|
render(): void;
|
|
92
108
|
}
|
|
93
109
|
export declare const codeEditor: ElementCreator<CodeEditor>;
|
package/dist/code-editor.js
CHANGED
|
@@ -76,6 +76,9 @@ const warnRemoved = (member, advice) => {
|
|
|
76
76
|
warned.add(member);
|
|
77
77
|
console.warn(`<tosi-code>.${member} was removed in tosijs-ui 1.7 (the editor is now CodeMirror 6, not ACE) — ${advice}. See CHANGELOG 1.7.0.`);
|
|
78
78
|
};
|
|
79
|
+
// One warning per page, not per element — see the `editor` getter.
|
|
80
|
+
let warnedEditor = false;
|
|
81
|
+
let warnedTjs = false;
|
|
79
82
|
export class CodeEditor extends WebComponent {
|
|
80
83
|
static preferredTagName = 'tosi-code';
|
|
81
84
|
source = '';
|
|
@@ -135,28 +138,24 @@ export class CodeEditor extends WebComponent {
|
|
|
135
138
|
// it. (Re-adding a slot is NOT the fix — it would also project the element's
|
|
136
139
|
// textContent, i.e. the initial code, and double-render it under the editor.)
|
|
137
140
|
diffOverlay;
|
|
138
|
-
//
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
//
|
|
148
|
-
// silently dropped, which is what used to happen).
|
|
141
|
+
// Hydration state comes from the base class (`this.hydrated`), as of tosijs 1.6.9.
|
|
142
|
+
// This used to be a hand-rolled `_partsHydrated` flag — because before 1.6.9 the
|
|
143
|
+
// `parts` proxy poisoned itself on any pre-hydration read (touching it once rooted
|
|
144
|
+
// the proxy at the light-DOM element forever, so the editor never mounted), and
|
|
145
|
+
// there was no public way to ask "am I hydrated yet?" without triggering exactly
|
|
146
|
+
// that. 1.6.9 fixed both — it invalidates the cached proxy at hydrate AND exposes
|
|
147
|
+
// `hydrated`/`whenHydrated` — so the flag is gone. (tonioloewald/tosijs#13.)
|
|
148
|
+
// A showDiff() call made before hydration, replayed once we're ready. Still needed:
|
|
149
|
+
// `parts` genuinely doesn't exist before hydration (content is injected at connect),
|
|
150
|
+
// so work that touches it is legitimately deferred — that is not the poisoning bug.
|
|
149
151
|
_pendingDiff;
|
|
150
|
-
get partsReady() {
|
|
151
|
-
return this._partsHydrated;
|
|
152
|
-
}
|
|
153
152
|
get showingDiff() {
|
|
154
|
-
if (!this.
|
|
153
|
+
if (!this.hydrated)
|
|
155
154
|
return this._pendingDiff ?? false;
|
|
156
155
|
return !this.parts.diffHost.hidden;
|
|
157
156
|
}
|
|
158
157
|
showDiff(on) {
|
|
159
|
-
if (!this.
|
|
158
|
+
if (!this.hydrated) {
|
|
160
159
|
this._pendingDiff = on;
|
|
161
160
|
return;
|
|
162
161
|
}
|
|
@@ -176,8 +175,30 @@ export class CodeEditor extends WebComponent {
|
|
|
176
175
|
disabled: false,
|
|
177
176
|
};
|
|
178
177
|
role = 'code editor';
|
|
179
|
-
/**
|
|
178
|
+
/**
|
|
179
|
+
* The underlying CodeMirror `EditorView` (undefined until loaded).
|
|
180
|
+
*
|
|
181
|
+
* **Changed in 1.7 (ACE → CodeMirror 6).** In 1.6 this was an ACE editor, and
|
|
182
|
+
* `editor.session.getUndoManager()` was documented public API. `^1.6.x` resolves
|
|
183
|
+
* 1.7.0, so an app that never changed a line auto-upgrades into a `TypeError` on the
|
|
184
|
+
* next install — and this is the ONE break the warn-once shims below cannot catch,
|
|
185
|
+
* because the property still exists and still returns an object; it is simply a
|
|
186
|
+
* different object. TS consumers get a compile error (1.6 typed this `any`); vanilla
|
|
187
|
+
* JS and CDN consumers — the audience this component's own docs court — would get the
|
|
188
|
+
* bare TypeError with no explanation at all.
|
|
189
|
+
*
|
|
190
|
+
* So: say it once, on first access. One line in the console beats a stack trace in a
|
|
191
|
+
* library the reader has never opened. Use `undo()`/`redo()`/`canUndo()`/`canRedo()`
|
|
192
|
+
* for history — they are the supported surface and they survived the migration.
|
|
193
|
+
*/
|
|
180
194
|
get editor() {
|
|
195
|
+
if (!warnedEditor) {
|
|
196
|
+
warnedEditor = true;
|
|
197
|
+
console.warn('<tosi-code>.editor is a CodeMirror EditorView as of 1.7 (it was an ACE editor ' +
|
|
198
|
+
'in 1.6) — `editor.session`, `editor.getSession()`, `editor.setOption()` and ' +
|
|
199
|
+
'`editor.session.getUndoManager()` no longer exist. Use undo()/redo()/' +
|
|
200
|
+
'canUndo()/canRedo() for history; see the CodeMirror 6 docs for the rest.');
|
|
201
|
+
}
|
|
181
202
|
return this._handle?.view;
|
|
182
203
|
}
|
|
183
204
|
// ── Removed in 1.7 (ACE → CodeMirror 6) ────────────────────────────────────
|
|
@@ -251,8 +272,8 @@ export class CodeEditor extends WebComponent {
|
|
|
251
272
|
}
|
|
252
273
|
connectedCallback() {
|
|
253
274
|
super.connectedCallback();
|
|
254
|
-
// super.connectedCallback()
|
|
255
|
-
this.
|
|
275
|
+
// super.connectedCallback() hydrated us, so `this.hydrated` is now true and
|
|
276
|
+
// `this.parts` is safe from here on.
|
|
256
277
|
if (this.source === '') {
|
|
257
278
|
this.value = this.textContent !== null ? this.textContent.trim() : '';
|
|
258
279
|
}
|
|
@@ -330,9 +351,35 @@ export class CodeEditor extends WebComponent {
|
|
|
330
351
|
.then((ext) => {
|
|
331
352
|
if (ext && this._handle === handle && this.isTjsMode()) {
|
|
332
353
|
handle.setLanguageExtension(ext);
|
|
354
|
+
this._tjsExtensionApplied = true;
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
// Degrade LOUDLY. `loadTjsExtension` swallows everything and returns null by
|
|
358
|
+
// design, and the guard is `typeof mod.tjsEditorExtension === 'function'` — so
|
|
359
|
+
// an upstream export rename returns null without even throwing, and every tjs
|
|
360
|
+
// editor on the page silently falls back to plain TypeScript highlighting with
|
|
361
|
+
// no autocomplete. Nothing goes red; the feature just quietly isn't there.
|
|
362
|
+
if (!ext && this._handle === handle && this.isTjsMode() && !warnedTjs) {
|
|
363
|
+
warnedTjs = true;
|
|
364
|
+
console.warn(`<tosi-code mode="${this.mode}">: tjs-lang's CodeMirror extension did not load — ` +
|
|
365
|
+
`falling back to TypeScript highlighting (no tjs autocomplete). Install the ` +
|
|
366
|
+
`optional peer \`tjs-lang\`, or check that tjs-lang/editors/codemirror still ` +
|
|
367
|
+
`exports \`tjsEditorExtension\`.`);
|
|
368
|
+
}
|
|
369
|
+
})
|
|
370
|
+
.catch((e) => {
|
|
371
|
+
// The chain had no .catch(), so any throw here was an unhandled rejection.
|
|
372
|
+
if (!warnedTjs) {
|
|
373
|
+
warnedTjs = true;
|
|
374
|
+
console.warn(`<tosi-code>: failed to apply the tjs extension —`, e);
|
|
333
375
|
}
|
|
334
376
|
});
|
|
335
377
|
}
|
|
378
|
+
/** True once tjs-lang's CM language+autocomplete is actually live (test seam). */
|
|
379
|
+
get tjsExtensionApplied() {
|
|
380
|
+
return this._tjsExtensionApplied;
|
|
381
|
+
}
|
|
382
|
+
_tjsExtensionApplied = false;
|
|
336
383
|
render() {
|
|
337
384
|
super.render();
|
|
338
385
|
if (this._handle) {
|
package/dist/doc-browser.d.ts
CHANGED