tosijs-ui 1.6.13 → 1.6.15

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 CHANGED
@@ -1,5 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.15
4
+
5
+ Live-example fixes from tosijs-3d adoption. All fixes to the doc-system's
6
+ editing surface; no API changes.
7
+
8
+ ### Fixed
9
+
10
+ - **Save to source works when the doc comment is indented.** A `/*# … */` doc
11
+ comment is often indented in the source; the extractor dedents its fenced blocks
12
+ (so examples render with correct ordinals), but the raw scan required the closing
13
+ ` ``` ` right after a newline, so an indented file matched **zero** blocks and
14
+ every save failed with "no matching block". The scan is now indentation-aware,
15
+ and edits compare dedented / write re-indented so a block keeps its place. The
16
+ failure alert is also split into a precise message (page↔source ordinal mismatch
17
+ vs. a genuine no-op).
18
+ - **The pop-out editor window ("view/edit code in a new window") now has the full
19
+ menu.** It previously opened as a bare instance, so View changes, Save changes
20
+ (local), and Save to source were hidden; the source↔doc key and the pristine
21
+ snapshot are now passed through, so the pop-out offers — and can execute — the
22
+ same actions as the main window.
23
+ - **Opening the editor in a new window closes the inline code view** in the main
24
+ window if it was open (the pop-out owns editing).
25
+ - **The doc extractor now only treats a `/*#` block as a doc when it starts a
26
+ line** (whitespace-only before the slash), so a `/*#` inside a `//` comment, a
27
+ string, or mid-line can't be scraped as a spurious doc page.
28
+
29
+ ## 1.6.14
30
+
31
+ Lighter live-example transpilation. Additive; affects only how the live-example
32
+ runner loads its (optional, lazy) transpiler.
33
+
34
+ ### Changed
35
+
36
+ - **Live examples now use tjs-lang 0.8.5's self-contained browser bundles**
37
+ (`tjs-lang/browser` + `tjs-lang/browser/from-ts`). The transpiler is a single
38
+ self-contained chunk, and the TypeScript compiler is **lazy-loaded from a CDN at
39
+ runtime** only when a `ts` example actually transpiles — so `typescript` (~MB)
40
+ and the transpiler's own deps are never in a consumer's dependency graph. This
41
+ also fixes the `ts` example path, which previously tried to load the TypeScript
42
+ compiler through a CDN transform that timed out on its size.
43
+ - **Robust transpiler loading.** The doc-site build now ships the tjs-lang browser
44
+ bundles **same-origin** (copied next to the iife under `/tjs/`, with a global
45
+ pointing the loader at them), so live examples never depend on a third-party
46
+ CDN's propagation timing or uptime. The loader prefers the same-origin copy,
47
+ then falls back through a multi-CDN chain (jsdelivr → unpkg → esm.sh). Installed
48
+ ESM consumers resolve the peer locally as before.
49
+ - `tjs-lang` optional peer bumped to `^0.8.6`.
50
+
51
+ ### Fixed
52
+
53
+ - A garbled character in the first `example` doc snippet that made it throw.
54
+ - Live examples could all break for the propagation window after a tjs-lang
55
+ release, when the single pinned CDN 404'd the just-published version (now
56
+ served same-origin + multi-CDN).
57
+
3
58
  ## 1.6.13
4
59
 
5
60
  The documentation system becomes a real publishing pipeline: every doc site can
@@ -99,8 +99,9 @@ import { pinnedSort } from '../nav-tree';
99
99
  const TRIM_REGEX = /^#+ |`/g;
100
100
  function metadata(content, filePath) {
101
101
  // Ignore metadata-style comments INSIDE /*# ... */ doc blocks — those are
102
- // documentation examples, not real directives.
103
- const scannable = content.replace(/\/\*#[\s\S]*?\*\//g, '');
102
+ // documentation examples, not real directives. Only line-starting blocks count
103
+ // as docs (see findMarkdownFiles), so strip exactly those.
104
+ const scannable = content.replace(/^[ \t]*\/\*#[\s\S]*?\*\//gm, '');
104
105
  const source = scannable.match(/<!--(\{.*\})-->|\/\*(\{.*\})\*\//);
105
106
  let data = {};
106
107
  if (source) {
@@ -151,7 +152,11 @@ function findMarkdownFiles(paths, ignore) {
151
152
  }
152
153
  else if (['.ts', '.js', '.css'].includes(path.extname(file))) {
153
154
  const content = fs.readFileSync(filePath, 'utf8');
154
- const docs = content.match(/\/\*#[\s\S]+?\*\//g) || [];
155
+ // A /*# … */ block is only a doc when it STARTS a line (whitespace-only
156
+ // before the slash). This keeps a `/*#` that appears inside a // comment,
157
+ // a string, or otherwise mid-line from being scraped as a spurious doc.
158
+ // m[1] is the block without its leading indentation.
159
+ const docs = [...content.matchAll(/^[ \t]*(\/\*#[\s\S]+?\*\/)/gm)].map((m) => m[1]);
155
160
  if (docs.length) {
156
161
  const markdown = docs.map((s) => s.substring(3, s.length - 2).trim());
157
162
  const text = markdown.join('\n\n');
@@ -113,7 +113,12 @@ export async function buildSite(config) {
113
113
  naming: scriptName,
114
114
  // tjs-lang transpiles live examples; it's dynamically import()'d at
115
115
  // runtime (falling back to CDN), so keep it out of the bundle.
116
- external: ['tjs-lang', 'tjs-lang/lang', ...(config.bundleExternals ?? [])],
116
+ external: [
117
+ 'tjs-lang',
118
+ 'tjs-lang/browser',
119
+ 'tjs-lang/browser/from-ts',
120
+ ...(config.bundleExternals ?? []),
121
+ ],
117
122
  });
118
123
  if (!result.success) {
119
124
  console.error('bundle build failed');
@@ -170,6 +175,27 @@ export async function buildSite(config) {
170
175
  // root copy stays for the npm package's `files`).
171
176
  await $ `cp llms.txt ${PUBLIC}/llms.txt`.text();
172
177
  }
178
+ // Serve the tjs-lang browser bundles SAME-ORIGIN so live examples never depend
179
+ // on a third-party CDN's propagation timing — a freshly-published tjs-lang
180
+ // version 404s on a CDN until it caches it (minutes–hours), which would break
181
+ // every example. We ship the exact bundles the build resolved, and a global
182
+ // tells the loader to prefer them (it falls back to the CDN chain if absent).
183
+ // Optional: skipped if tjs-lang isn't installed.
184
+ let tjsHead = '';
185
+ try {
186
+ const browser = Bun.resolveSync('tjs-lang/browser', PROJECT_ROOT);
187
+ const fromTs = Bun.resolveSync('tjs-lang/browser/from-ts', PROJECT_ROOT);
188
+ await $ `mkdir -p ${PUBLIC}/tjs`.text();
189
+ await $ `cp ${browser} ${PUBLIC}/tjs/tjs-browser.js`.text();
190
+ await $ `cp ${fromTs} ${PUBLIC}/tjs/tjs-browser-from-ts.js`.text();
191
+ const bp = config.basePath;
192
+ const base = !bp || bp === '/' ? '/tjs/' : bp.replace(/\/$/, '') + '/tjs/';
193
+ tjsHead = `<script>globalThis.__TJS_LOCAL_BASE=${JSON.stringify(base)}</script>`;
194
+ console.log(`tjs-lang bundles served same-origin at ${base}`);
195
+ }
196
+ catch {
197
+ // tjs-lang not installed — live examples fall back to the CDN chain
198
+ }
173
199
  // Generate the static, pre-rendered doc site (one /slug/index.html per doc).
174
200
  // Runs after the static-asset copy so the generated index.html (README) wins,
175
201
  // and after the bundle copy so every page's <script src> resolves.
@@ -186,7 +212,7 @@ export async function buildSite(config) {
186
212
  localizedStrings: config.localizedStrings,
187
213
  favicon: config.favicon,
188
214
  ogImage: config.ogImage,
189
- headExtra: config.headExtra,
215
+ headExtra: [config.headExtra, tjsHead].filter(Boolean).join('') || undefined,
190
216
  scriptUrl: config.scriptUrl,
191
217
  basePath: config.basePath,
192
218
  });