@omrips/viewstl 2.0.0-rc.7 → 2.0.0-rc.9

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.
@@ -1,700 +1,745 @@
1
- # ViewSTL v2 verification
2
-
3
- This file records dated checks. Older sections describe the alpha at the time
4
- of each check; release-candidate results are recorded separately below.
5
-
6
- ## rc.7 release candidate verification — 2026-11-14
7
-
8
- The desktop app shortcuts and VSB binary MIME fix pass 147 unit tests, strict
9
- browser/Node type checks and the 37-file legacy integrity guard. Both staged
10
- package names pass browser and Node ESM/CommonJS import checks, package-content
11
- checks and the required first-line version/banner checks.
12
-
13
- The website candidate passed 43 shortcut checks in headless Windows Edge
14
- 157.0.4341.46: Open/Save, all seven camera presets, unchanged model transforms,
15
- single-click selection without camera movement, drag rejection, keyboard
16
- toggle/Escape, resize exit, persistent print results, disabled empty-scene
17
- actions, and desktop/narrow/touch-only layouts. Another 26 scene-save and 25
18
- scene-open checks passed. Scene URL fixtures use mocked relay responses.
19
- Screens/touch are emulation; no physical Android, Safari or Firefox validation
20
- is claimed. The previously requested banner is included in rc.7.
21
-
22
- Evidence: website `results/desktop-shortcuts-20261114/` and plugin
23
- `test-results/desktop-shortcuts-20261114/` / `test-results/vsb-mime-20261114/`.
24
- The VSB section below records the earlier local checkpoint, before rc.7 staging.
25
-
26
- ## VSB download MIME fix — 2026-11-14 (local, unpublished)
27
-
28
- The owner reported Android saving scenes as `name.vsb.zip`. Both the scene
29
- worker used by `export_scene` / `download_scene` and the compatibility
30
- `get_vsb_blob` / `download_vsb` path now return `application/octet-stream`
31
- instead of `application/zip`. The `.vsb` filename and ZIP container bytes are
32
- unchanged; existing VSB files remain compatible. Actual OBJ ZIP exports still
33
- use their ZIP MIME type.
34
-
35
- All 147 unit tests pass and the 37-file legacy integrity guard passes. A real
36
- worker/download check in headless Windows Edge 157.0.4341.46 verified binary
37
- MIME for both VSB APIs, reopened both two-model scenes with positions preserved,
38
- and downloaded `android-scene.vsb` without console errors. Evidence is in
39
- `test-results/vsb-mime-20261114/` and `test-results/vsb-mime-tests-20261114.log`.
40
- Android download behavior still requires a physical-device retest. A file
41
- manager that inspects the bytes may continue recognizing the ZIP container.
42
-
43
- The build is updated locally, including the previously approved author banner.
44
- The package version remains rc.6 for this unpublished working tree; do not
45
- overwrite the existing registry artifact. Production/preview still use the
46
- published rc.6 package and have not received this fix. A new plugin version
47
- and website deployment are needed to ship it.
48
-
49
- ## npm names and installation — 2026-11-07
50
-
51
- Published `viewstl@2.0.0-rc.5` and `@omrips/viewstl@2.0.0-rc.5` with `latest`
52
- pointing to rc.5. The existing scoped `next` tag was also advanced to rc.5.
53
- Both READMEs document `npm install viewstl` and retain the scoped alternative.
54
- All existing scoped versions remain available.
55
-
56
- All 136 unit tests, strict browser/Node type checks and 37 legacy integrity
57
- checks pass again. Both packed distributions pass Node ESM/CommonJS type checks
58
- and runtime checks for browser exports, worker/CAD assets and STL/OBJ/3MF/STEP/IGES
59
- analysis. Fresh public-registry installs without a version suffix pass those
60
- runtime checks for both package names. Public tarball bytes and SHA-512 integrity
61
- match the tested local archives; each package contains 40 files.
62
-
63
- All 31 files under `build/` match the previously tested GitHub rc.5 distribution
64
- byte for byte. No renderer changes were made and browser/device tests were not
65
- rerun for this packaging update. The GitHub browser evidence below still applies
66
- to those exact runtime bytes. Evidence: local `test-results/npm-stage.json` and
67
- its referenced staging directory. See [maintainer workflow](npm-releases.md).
68
-
69
- ## GitHub root-layout release 2.0.0-rc.5 — 2026-11-07
70
-
71
- The release worktree places the v2 sources/distribution in `src/` and `build/`.
72
- The complete pre-v2 GitHub tree is archived under `legacy/v1/`; its 23 original
73
- Git blobs and the 14-file local v1.14 snapshot pass SHA-256/size verification.
74
- Historical sections below retain the paths and versions used at the time.
75
-
76
- All **136 unit tests** pass, along with strict browser and Node TypeScript
77
- consumers. Actual desktop Chrome 156, without device emulation, passes **46
78
- browser checks**: 15 compatibility, 11 animation, 11 scene and 9 export checks.
79
- These exercise the relocated classic/ESM entries, module workers, legacy mesh
80
- bridge, STL/OBJ/3MF/STEP/IGES export/reimport, scene playback, cancellation,
81
- context restoration and a responsive million-triangle STL export.
82
-
83
- The packed `@omrips/viewstl@2.0.0-rc.5` tarball installs into a clean consumer
84
- project. Browser ESM/CommonJS exports, version reporting, worker/CAD asset paths,
85
- and server analysis of STL, OBJ, 3MF, STEP and IGES pass. Node analysis also
86
- passes through the CommonJS entry. Archive contents exclude development fixtures,
87
- legacy runtime copies and site/server files; license notices and lazy assets are included.
88
-
89
- The layout update also corrects old harness references to the legacy parser and
90
- worker directory. The compatibility animation assertion now waits for the public
91
- completion callback and checks the public completed state, rather than assuming
92
- the old private animation representation or a fixed wall-clock delay.
93
-
94
- Evidence is retained locally in the original plugin checkout under
95
- `test-results/github-v2-20261107/`. Physical mobile, Safari and Firefox validation
96
- remain pending. This release does not update the preview website or npm registry.
97
-
98
- ## Live animation save/open verification — 2026-11-02
99
-
100
- Verified the existing `20261102-f04f34e66b7c` release through the actual Save and
101
- Open controls on `https://preview.viewstl.com/`, in desktop in-app Chromium.
102
- No runtime changes or redeployment were needed. Two binary STL fixtures have
103
- offset geometry centers: one runs reverse X rotation at 3 seconds per turn and
104
- is paused; the other runs forward Z rotation at 7 seconds per turn.
105
-
106
- Both VSB and VSJ were downloaded, the page was freshly reloaded, and the downloaded
107
- files were opened and saved again. **40 checks pass** against the resulting files
108
- and visible controls: two models, camera, position/scale/appearance, animation
109
- definition, pivot/origin, pause state, exact paused time and pose, advancing running
110
- time and a pose consistent with that time. VSB mesh coordinates match both their
111
- original files and the re-saved archive. VSJ file references remain intact. The
112
- paused model's elapsed time stayed exactly `7400.434000000001` ms in both formats;
113
- the running model continued from each saved time instead of restarting.
114
-
115
- A second pair of files was saved with both models paused. PNGs downloaded before
116
- saving and after independently reopening each format are **byte-for-byte equal**.
117
- VSB opens alone; VSJ was opened together with its two referenced STL files. Paused
118
- models expose Resume with the restored axis, duration and direction. There were
119
- no console errors on the final restored page. This is desktop-browser evidence,
120
- not physical mobile or other-browser coverage.
121
-
122
- The website workspace retains actual downloads, UI-state records, PNGs and
123
- `verification.json` in `results/animation-roundtrip-20261102/`. Recheck those
124
- artifacts with `node site/qa/verify-animation-downloads.mjs --images`; regenerate
125
- the offset STL fixtures with `node site/qa/make-animation-fixtures.mjs`.
126
-
127
- ## Preview-site animation integration — 2026-11-02
128
-
129
- Deployed to preview as `20261102-f04f34e66b7c`. The optional animation app binding
130
- is bundled inside viewstl.js; the site's initializer is unchanged. The site adds
131
- static controls under Models → Animation: axis, seconds per turn, direction and
132
- Play/Pause/Resume/Stop. Off-center models spin about their center without moving
133
- their visible pose. Editing uses current transforms, and adding/selecting files
134
- preserves other models' animation. Print checks pause their targets and offer
135
- explicit Resume while keeping the results panel open. Reduced-motion preference
136
- pauses restored playback. Stopped animations also retain an equivalent static
137
- VSJ pose with the original referenced mesh.
138
-
139
- All **136 unit tests**, both strict type checks and the legacy guard pass.
140
- Actual desktop Chromium 156 passes **25 new integration checks** and **96 existing
141
- site checks**. New coverage includes invalid speed, concurrent models, live-pose
142
- manual editing, drag entry, print pause/resume, VSB phase/pause restoration,
143
- stopped off-center VSJ reopening with an identical PNG, callback composition,
144
- clear/dispose/remount and simulated reduced motion. Keyboard Enter playback was
145
- also exercised. 320px and 390px viewport checks show no horizontal overflow and
146
- 44px-high playback buttons; these are emulated widths, not physical touch tests.
147
-
148
- All 29 public HTTPS files match the local SHA-256 manifest. Live browser smoke
149
- checks cover loading, keyboard playback and print-check interaction. Nginx, relay
150
- and Certbot remain active; configuration/service/binary hashes match the previous
151
- release and SELinux remains enforcing. Initial gzip total is 57,897 bytes; the
152
- viewer entry is 42,150 bytes. No new million-triangle or total-memory benchmark
153
- was performed for the app controls; the earlier plugin measurement remains below.
154
- Physical mobile, Safari/Firefox and actual hidden-tab behavior remain unverified.
155
-
156
- Evidence: the site workspace's `results/animation-integration/` and
157
- `results/deploy-20261102-f04f34e66b7c/`. Reproduce the browser checks through the
158
- local-only `site/qa/animation.html` and `site/qa/index.html` pages. The QA harness
159
- is excluded from deployment. npm is unchanged (`2.0.0-rc.4`); no GitHub push.
160
-
161
- ## Model animation — unreleased development update, 2026-11-02
162
-
163
- The local plugin now has validated legacy delta/exact playback, per-model
164
- pause/resume/state queries and transition/completion callbacks. Animation uses
165
- elapsed frame time, retires finished tracks independently, stops on manual
166
- transform edits and suspends on document hiding or context loss. VSJ and both
167
- VSB APIs preserve animation phase, pause state, units and rotation pivot; animated
168
- VSB meshes retain scale in metadata to avoid applying it twice on reopening.
169
- The native WebGL2 renderer and existing worker architecture remain in use.
170
-
171
- - All **132 Node tests pass** on Node.js 24.19.0, Windows. Nine new tests cover
172
- mixed durations, frame cadence, pause/resume/suspension, manual changes,
173
- replacement and copied state, scale/statistics invalidation, invalid numeric
174
- inputs and overflow, scene validation, VSJ/VSB restoration and export snapshots.
175
- - Browser and server-only strict TypeScript checks pass. The legacy guard passes
176
- for tracked legacy files and all 14 archived files.
177
- - **11 animation browser checks pass** in actual desktop Chromium 156 on Windows,
178
- using workers and WebGL2. These cover constructor playback, concurrent models,
179
- idle behavior, pause/resume/stop, modern and legacy scene restoration, group
180
- starts, bad-scene rollback, print-check staleness, mesh/PNG snapshots, forced
181
- context loss/restoration and resource cleanup. Context loss is deliberately
182
- triggered with `WEBGL_lose_context`, not a hardware failure.
183
- - Existing browser compatibility (**15**) and scene/rendering (**11**) checks
184
- also pass: **37 passing browser checks** in total.
185
- - A generated **1,000,000-triangle** model animated over 120 measured frame
186
- intervals: median **16.7 ms**, p95 **16.8 ms**, maximum **16.9 ms**. Geometry
187
- objects and GPU resources retained identity, with two GPU buffers and
188
- 72,375,000 bytes of resident geometry typed arrays. These are frame intervals
189
- on one desktop, not GPU timings, allocation profiling or total process memory.
190
- - The interactive example at `examples/v2/animation.html` runs locally and exposes
191
- Play, Pause, Resume, Stop and Reset. No models or external assets are fetched.
192
-
193
- Actual hidden-tab behavior remains unverified: automation tab changes in the
194
- in-app browser and Chrome did not produce a document `visibilitychange` event.
195
- The suspension/resumption code is covered by unit tests and the real WebGL
196
- context-loss check. Firefox, Safari, physical phones/tablets, touch, reduced-motion
197
- site integration and a total-memory profile have not been tested in this update.
198
-
199
- Reproduce with `pnpm build`, `pnpm test`, `pnpm check:types`,
200
- `pnpm check:node-types`, `pnpm check:legacy`, then `pnpm start`. Open
201
- `tests/v2/animation-browser.html`, `tests/v2/browser.html` and
202
- `tests/v2/scene-browser.html` and run their checks. The million-triangle and
203
- background-tab checks have separate buttons on the animation page.
204
-
205
- Evidence is retained locally in ignored `test-results/animation-*` files. The
206
- package version is still `2.0.0-rc.4`; this development update has **not** been
207
- published to npm or deployed. The proposed site work is described in
208
- [the preview integration plan](v2-animation-site-plan.md).
209
-
210
- ## Runnable server example 2.0.0-rc.4 — 2026-10-20
211
-
212
- The npm README now contains a clearly labeled server-only example, including
213
- installation, the `analyze.mjs` filename, a three-line script that prints JSON,
214
- and the command to run it. This is a documentation update.
215
-
216
- The exact example was extracted from the packed README and run with a binary
217
- STL using the installed package on Node.js 24.19.0 on Windows. The resulting
218
- JSON contains the expected dimensions, surface area, validated volume and mesh
219
- checks. All 40 packaged files match the local release sources by SHA-256.
220
- All 31 existing browser/Node runtime, declaration and CAD assets match the
221
- public `2.0.0-rc.3` package apart from embedded version strings. The legacy
222
- guard passes for tracked files and all 14 archived files. No runtime logic was
223
- changed; the broader API verification below still describes the implementation.
224
-
225
- Evidence is retained locally in `test-results/npm-2.0.0-rc.4/` (ignored by Git).
226
-
227
- ## Node.js model analysis 2.0.0-rc.3 — 2026-10-20
228
-
229
- The new `@omrips/viewstl/node` export provides `analyzeFile`, `analyzeBuffer`
230
- and `createAnalyzer`. It reuses the browser's parsers and mesh checks in Node
231
- worker threads, loading CAD JavaScript/WASM from the installed package.
232
-
233
- - All 123 tests pass on Node.js 24.19.0 on Windows. New tests cover real workers,
234
- all five model formats, physical and unknown units, validated/invalid volume,
235
- malformed input and recovery, buffer offsets and ownership, file/archive/
236
- triangle/memory admission limits, bounded queues, cancellation, disposal,
237
- whole-job and partial-check deadlines, and progress callback failures.
238
- - A clean consumer installation of the packed tarball passes on actual Node.js
239
- 20.20.2 and 24.19.0 on Windows. ESM and CommonJS each analyze STL, OBJ, 3MF,
240
- STEP and IGES fixtures through the public export, including local CAD WASM.
241
- Buffer input, unknown units and recovery after malformed input also pass.
242
- - Strict TypeScript consumers pass for both module systems using Node types
243
- without the DOM library, including against the installed package. Existing
244
- browser TypeScript checks also pass.
245
- - The package contains 40 files and no runtime dependencies. Installed files
246
- match their release sources by SHA-256. The allowlist excludes test fixtures,
247
- local test servers, credentials and node_modules.
248
- - All 26 existing browser runtime/declaration/CAD assets match the public
249
- `2.0.0-rc.2` package apart from embedded version strings. Browser behavior was
250
- not changed; no new browser or physical-device test coverage is claimed.
251
- - The legacy guard passes for tracked legacy files and all 14 archived files.
252
-
253
- Linux/macOS execution, additional Node versions and large production workloads
254
- have not been exercised in this release check. Memory budgets are estimates,
255
- not a hard process RSS cap. STEP/IGES results describe the tessellated mesh,
256
- not exact CAD solids. Optional FDM estimates are not a printability guarantee.
257
-
258
- Reproduction scripts, packed/public-install verification, fixtures and terminal
259
- evidence are retained locally in `test-results/npm-2.0.0-rc.3/` (ignored by Git).
260
-
261
- ## Quick-start documentation update 2.0.0-rc.2 — 2026-10-20
262
-
263
- The README and usage guide now begin with the minimum installation step and
264
- a three-line HTML example. The example was extracted unchanged from the README,
265
- served with the complete distribution directory and a binary STL, and verified
266
- in the desktop Codex Chromium browser: the model rendered, the worker and model
267
- requests succeeded, and keyboard rotation responded without console errors.
268
-
269
- All 112 unit tests and the legacy preservation check passed. Every runtime asset
270
- was compared with the installed public `2.0.0-rc.1` package; only the embedded
271
- version string changed. This update does not add browser/device coverage beyond
272
- the release-candidate verification below. Evidence is in the ignored local
273
- `test-results/npm-2.0.0-rc.2/` folder.
274
-
275
- ## npm release candidate 2.0.0-rc.1 — 2026-10-19
276
-
277
- Prepared the first public npm package as `@omrips/viewstl`, with the release
278
- candidate on the `next` tag. The package version and `StlViewer.version` agree.
279
- The GitHub legacy paths and all archived legacy files remain unchanged.
280
-
281
- Validation against the packed tarball installed into a clean consumer:
282
-
283
- - 112 Node tests pass, with strict TypeScript source-consumer checks.
284
- - ESM imports and CommonJS requires work without a browser DOM. Both installed
285
- package TypeScript entry points pass strict NodeNext checks.
286
- - All 35 installed files match the release source by SHA-256. The allowlist
287
- includes the viewer, module worker, lazy chunks, CAD glue/WASM, declarations,
288
- documentation and license/source notices. No credentials, test data, local
289
- server scripts, node_modules or legacy runtime files are packaged.
290
- - Production builds succeed with Vite 8.3.4 and Webpack 5.112.0. Both follow the
291
- documented complete-static-directory copy and explicit `worker_url` setup.
292
- - 11 browser checks pass in each of four consumers: Vite, Webpack, direct ESM
293
- and classic script (44 total). These use the installed distribution and real
294
- WebGL 2/module workers for local binary STL, STL/OBJ/3MF/STEP/IGES exports and
295
- reimports, print checks, PNG export, VSB save/load and VSJ export.
296
- - Browser: desktop Codex in-app Chromium 155.0.0.0 on Windows, without device
297
- emulation. The local pages use a same-origin CSP without JavaScript eval;
298
- WebAssembly compilation is allowed. Parser/CAD assets are self-hosted.
299
- - The legacy guard verifies unchanged tracked legacy files and all 14 archived
300
- snapshot hashes.
301
-
302
- Reproduction scripts, build fixtures, tarball inventory, terminal results,
303
- browser output and screenshots are retained locally in the ignored
304
- `test-results/npm-2.0.0-rc.1/` folder. Firefox, Safari, physical touch/mobile
305
- devices and broader real-world large-CAD workloads remain unverified; this
306
- release is a candidate, not a claim that those checks have passed. The optional
307
- bundler `worker_factory` variant was not exercised by this release check.
308
-
309
- ## URL drops in the optional app controller — 2026-10-02
310
-
311
- `mountViewstlApp` routes dropped HTTP/HTTPS links through its configured relay and
312
- existing URL import queue. Six new unit cases bring the plugin suite to 93 passing
313
- tests; strict types and all 14 legacy integrity checks pass. The site's full
314
- 96-assertion browser harness and 15 app lifecycle checks pass with this build.
315
-
316
- Desktop headless Edge 154.0.4258.48 passes 15 local and 16 live URL-drop checks:
317
- URI/plain-text/Firefox payloads, signed query preservation, deduplication, local
318
- file precedence, untouched input behavior, unsupported schemes, failure recovery,
319
- cancellation and an actual anchor drag. Firefox data is emulated; Firefox/Safari
320
- and physical devices were not tested. Live preview also fetched and parsed a
321
- real public STEP URL through Go. Other deterministic URL-drop response fixtures
322
- are explicitly mocked in the browser runner. These changes and the preceding
323
- export API build ship on preview in release `20261002-8f91150b7782`; export controls
324
- are still not wired to the site. The legacy site was not changed.
325
-
326
- ## Plugin mesh exports — 2026-10-02
327
-
328
- The local v2 build adds `export_models` and `download_models` for binary STL,
329
- OBJ/MTL, 3MF, STEP/STP and IGES/IGS. These are plugin-only changes; the website
330
- and deployed preview assets have not been synchronized or changed for this work.
331
- All writers are JavaScript worker modules; CAD export does not use the Go relay
332
- or download a new CAD engine. The native WebGL2 renderer and legacy APIs remain.
333
-
334
- Validation:
335
-
336
- - 87 Node tests pass, including 14 export cases. The strict TypeScript consumer
337
- check passes. All 14 archived legacy files verify unchanged.
338
- - Open CASCADE independently reads generated STEP and IGES: open triangle
339
- surfaces, multiple models, nonuniform scale, rotation, translation, millimeter
340
- and inch units. Triangle counts, bounds and area match the expected mesh.
341
- Checking area exposed IGES numeric tokens crossing padded parameter records;
342
- writers now wrap at parameter boundaries and the regression covers this.
343
- - Official 3MF Core/Materials XSD appendix validation passes with lxml. The
344
- validation helper uses a stricter one-million occurrence cap because libxml2
345
- 2.11 rejects the published `2147483647` value, and trims the leading space in
346
- the Materials appendix's `type=" ST_Numbers"`. No geometry/schema rules are
347
- relaxed. ZIP/XML tests also verify object separation, shared vertices, units,
348
- per-vertex color gradients, safe names and material references.
349
- - Headless desktop Edge **154.0.4258.48** passes all 9 export browser scenarios
350
- and all 15 existing browser compatibility scenarios. The export page uses a
351
- same-origin CSP without JavaScript eval. Tests cover real workers, all-format
352
- reimport, preserved live buffers, selected export, OBJ ZIP, a real browser
353
- download, running/queued cancellation, callback exceptions, scene cleanup,
354
- memory rejection and subsequent recovery. No unexpected page/WebGL errors.
355
- - Export/reimport requests were same-origin GETs; the actual download used a
356
- local Blob. No file upload or external endpoint request occurred. Edge's
357
- internal `edge://` downloads-panel resources are excluded from web traffic.
358
- - A **1,000,000-triangle binary STL** produced **50,000,084 bytes** in **1,277 ms**
359
- with **75 animation frames** during export. This is one synthetic local desktop
360
- observation, not a performance guarantee or a measured process-memory peak.
361
-
362
- Evidence: `test-results/exports/browser.json`, `browser.png`, `compatibility.txt`,
363
- `assembly-mm.step`, `assembly-inch.step`, `assembly-mm.iges`, `assembly-inch.iges`
364
- and `colored-scene.3mf`. These generated files are ignored by Git. Reproduce the
365
- browser checks with a local plugin server and `scripts/check-export-browser.mjs`
366
- (Playwright module supplied by `VIEWSTL_PLAYWRIGHT`, URL by `VIEWSTL_QA_URL`).
367
-
368
- The optional `scripts/check-export-3mf-schema.py` reads the following downloaded
369
- source files from `test-results/exports` and validates the generated 3MF fixture:
370
-
371
- - `3mf-core-spec.txt`: https://raw.githubusercontent.com/3MFConsortium/spec_core/master/3MF%20Core%20Specification.md
372
- - `3mf-materials-spec.txt`: https://raw.githubusercontent.com/3MFConsortium/spec_materials/master/3MF%20Materials%20Extension.md
373
- - `xml.xsd`: https://www.w3.org/2001/xml.xsd
374
-
375
- Limits: STEP/IGES contain planar mesh surfaces, not recovered analytic CAD solids
376
- or feature history. No F3D is implemented. 3MF performs edge/winding/volume checks,
377
- not full solid repair or self-intersection testing. Physical phones/tablets,
378
- Safari/Firefox, commercial CAD applications and large STEP/IGES export workloads
379
- have not been validated in this change. Export options and omissions are listed
380
- in [usage](v2-usage.md#local-mesh-export).
381
-
382
- ## STEP/IGES addition — 2026-10-01
383
-
384
- The local build adds STEP/STP and IGES/IGS with lazy, self-hosted WASM in
385
- disposable workers. The 54 plugin tests and TypeScript checks pass. Six CAD
386
- tests also pass under Node's `--disallow-code-generation-from-strings` flag:
387
- format aliases, unit conversion, assembly geometry/colors, malformed input,
388
- recovery, index validation, input/output budgets and rejection of an allocation
389
- beyond a 32 MiB configured WASM heap. The 14 archived legacy files verify unchanged.
390
-
391
- The website's 16 unit tests and its complete browser harness pass in local
392
- headless Edge 154.0.4258.37. Additional browser checks verify no CAD downloads
393
- for the empty page or STL, cancellation during the reader download, subsequent
394
- CAD recovery and GET-only same-origin asset requests without file uploads.
395
- The browser harness exercises all four aliases, mm dimensions, colors, malformed
396
- CAD recovery and multiple CAD files, alongside existing STL/OBJ/3MF and view tests.
397
-
398
- These are desktop automated checks, with a 390px emulated viewport for layout.
399
- Physical mobile devices, Safari/Firefox and large real-world CAD assemblies have
400
- not been validated. No new browser-memory or large-CAD performance claim is made.
401
- After explicit deployment authorization, the synchronized site and viewer were
402
- deployed as preview release `20261001-f40c6b922ea5`. All 22 public file hashes
403
- matched. Live headless Edge verified all four CAD aliases, correct mm dimensions,
404
- assembly positions/colors, malformed-file recovery and existing STL/OBJ/3MF
405
- loading. Observed network requests were same-origin GETs with no uploaded file
406
- data. The WASM response used `application/wasm` and gzip; no CSP/page errors were
407
- reported. Deployment evidence is in the website workspace's
408
- `results/deploy-20261001-f40c6b922ea5/`. DNS and the legacy site were unchanged.
409
-
410
- Checked on 2026-09-30, version `2.0.0-alpha.1`, on Windows in the
411
- Codex in-app Chromium browser. These results describe this development
412
- release, not a claim of complete compatibility with every legacy integration.
413
-
414
- ## Completed checks
415
-
416
- Update 2026-10-01, additional views: the Node suite now has 43 passing cases.
417
- All 15 existing browser compatibility checks passed, plus 11 new appearance
418
- checks in `tests/v2/appearance-browser.html`. Those validate actual PNG pixels
419
- for mesh lines, studio shading, X-ray transparency, feature edges, wireframe,
420
- front/back orientation colors, half-model clipping and reversed clipping;
421
- all section axes/endpoints; independent smooth shading; VSJ/VSB persistence;
422
- graphics context restoration; and repeated switching/resource cleanup.
423
- Node cases cover section-aware picking, edge angles, budget rejection, worker
424
- failure and stale view completion. Strict consumer types and all 14 archived
425
- legacy hashes passed. The site passed 31 browser checks and 2 policy checks.
426
- Responsive controls were inspected at 320 × 740 and 390 × 844, with no
427
- horizontal overflow; these are desktop viewport simulations, not real touch
428
- hardware tests. Live preview loading, smooth/edge derivation, Studio and
429
- section controls passed with no browser warnings/errors. The new appearance
430
- tests use small fixtures; no additional large-model stress test was run.
431
-
432
- Update 2026-10-01: chunked local binary STL parsing, optional memory-budget checks,
433
- OBJ line iteration and GPU-allocation failure cleanup were added. The 36-test
434
- Node suite passed, followed by the additional GPU fault-injection test (37 total
435
- cases). TypeScript and legacy preservation checks passed. All 15 browser cases
436
- below passed again; the separate preview site passed 22 browser and 2 policy
437
- checks. A 300,758,484-byte binary STL with 6,015,168 triangles rendered locally
438
- and on preview.viewstl.com, exceeding the old byte and triangle limits. Its
439
- wireframe request was rejected by the configured memory budget before map
440
- allocation. The file stayed on the client. This is one desktop test, not a
441
- guarantee for every model/device; large OBJ/3MF and low-memory mobile stress
442
- tests remain outstanding. Existing package-tarball checks below are from the
443
- September verification; no new npm publication occurred.
444
-
445
- | Check | Result |
446
- | --- | --- |
447
- | Node automated tests | 30 passed, 0 failed |
448
- | Real browser integration checks | 15 passed, 0 failed; no unexpected callback errors |
449
- | TypeScript strict consumer checks | ESM and CommonJS package declarations checked |
450
- | Local npm tarball installation | ESM/CJS constructors, worker/browser exports and types resolve |
451
- | Legacy preservation | Original tracked source/build/dependencies unchanged; 14 local snapshot hashes match |
452
- | Responsive demo | Single-column layout at 390 × 844; no horizontal document overflow |
453
- | Local file picker | Keyboard-accessible picker loads a real cube STL; dimensions 2 × 2 × 2, 12 triangles |
454
- | Direct manipulation | Mouse drag visibly rotates the loaded model; grid keyboard control and wireframe/smooth selection checked |
455
-
456
- Automated coverage includes ASCII/binary STL, three color conventions,
457
- invalid/truncated/non-finite data, OBJ indices, bounds/area/volume,
458
- nonuniform scaling, matrix/picking calculations, transfer detachment,
459
- worker limits/cancellation/timeouts, ZIP integrity/expansion limits,
460
- real saved VSB archives, 3MF transforms/colors/relationships and invalid
461
- XML/component cycles.
462
-
463
- Browser coverage exercises classic-script and module entry points, actual
464
- module workers, callback order, IDs including zero, idle rendering,
465
- appearance/transforms/units, picking, disabled controls, animation,
466
- VSJ relative URLs, multiple models, VSB round trips, 3MF/OBJ loading,
467
- PNG capture, legacy API comparisons, the optional real Three.js mesh
468
- bridge, cancellation with ID reuse, clean/dispose, context restoration,
469
- and a visible initialization failure when WebGL2 is unavailable.
470
-
471
- The legacy comparison deliberately records one corrected bug: model
472
- dimensions now change after scaling. The legacy plugin returned stale
473
- dimensions while already reporting scaled area and volume.
474
-
475
- ## Performance observation
476
-
477
- A generated **1,000,000-triangle binary STL (50.0 MB)** loaded through the
478
- worker and reached the first rendered frames in **273 ms** in one desktop
479
- run. WebGL reported no error. It used two tracked geometry buffers; after
480
- `clean()`, there were **zero tracked GPU buffers and zero active workers**.
481
-
482
- The input was an in-memory File generated before timing. This does not
483
- measure network download, physical disk latency, peak memory, cold-browser
484
- startup, or mobile performance. It is a reproducible smoke benchmark, not
485
- a cross-device promise. Run it from `/tests/v2/browser.html`.
486
-
487
- ## Build sizes
488
-
489
- Sizes measured with Node gzip defaults; servers must enable compression
490
- to achieve compressed transfer sizes. Decimal kB below.
491
-
492
- | Asset | Raw | Gzip |
493
- | --- | ---: | ---: |
494
- | Classic minified viewer | 43.3 kB | 14.9 kB |
495
- | Module worker | 4.6 kB | 2.1 kB |
496
- | Shared worker geometry chunk | 3.8 kB | 1.9 kB |
497
- | Lazy archive/XML chunk | 47.2 kB | 16.4 kB |
498
- | Readable ESM viewer, alternative to classic | 69.0 kB | 18.5 kB |
499
-
500
- The classic viewer plus initial STL worker code totals 51.6 kB raw /
501
- 18.9 kB gzip. Archive/XML support loads only for archive operations.
502
- The rendering/STL core includes no third-party runtime library.
503
-
504
- ## Reproduction and remaining validation
505
-
506
- ```sh
507
- pnpm install --frozen-lockfile
508
- pnpm build
509
- pnpm test
510
- pnpm check:types
511
- pnpm check:legacy
512
- pnpm start
513
- pnpm pack
514
- ```
515
-
516
- The local tarball was installed into an isolated consumer directory with
517
- scripts disabled, then its ESM import, CommonJS require, asset exports and
518
- strict TypeScript consumers were checked. No npm package was published.
519
- The package remains `private: true`; `@omrips/viewstl` is a provisional name.
520
-
521
- Before a stable release or production replacement, test Firefox, Safari,
522
- real touch/mobile hardware, high-DPI devices, representative large customer
523
- models, peak memory, Vite/Webpack integration, and production-site callers.
524
- The legacy site's direct Three.js internals need migration. The supported
525
- 3MF/OBJ subsets and transparency limits are described in [usage](v2-usage.md).
526
-
527
- Raw local browser results and the test tarball are in the ignored
528
- `test-results/` directory. No production files, DNS, server configuration,
529
- GitHub branch or npm registry entry were changed by this implementation.
530
-
531
- ## Scene/grid verification — 2026-10-01
532
-
533
- 47 Node tests passed, including aggregate scene memory accounting, serialized
534
- budgeted parsing, reservation cleanup on allocation/dispatch failures and
535
- multi-model derived-work guards. Strict TypeScript and 14-file legacy checks passed.
536
- The Chromium browser passed 15 compatibility, 11 appearance and 8 new scene cases.
537
- The scene cases exercise original coordinates, tint/restore without GPU buffer
538
- reallocation, grid coverage beyond model bounds after pan/zoom, opaque depth
539
- occlusion, PNG background color, finite-grid compatibility, infinite-grid VSB
540
- round trip, context restoration/cleanup, aggregate budget rejection/recovery and
541
- cancellation of derived work on model removal. Real mobile GPUs, Safari and Firefox
542
- remain untested for these additions. The preview site was updated separately;
543
- legacy files and npm publishing remain unchanged.
544
-
545
- ## Editing frame and picking — 2026-10-01
546
-
547
- 48 Node tests, strict TypeScript checking and the 14-file legacy integrity check
548
- passed. Chromium passed 15 compatibility, 11 appearance and 11 scene browser
549
- cases. Additional scene coverage verifies editing-frame pixels, clean PNG exports,
550
- frame-buffer reuse during transforms, selection switching and cleanup, recovery
551
- after graphics-context loss, and nearest visible surface picking after transforms.
552
- Real mobile GPU, Safari and Firefox coverage remains outstanding.
553
-
554
- ## Plugin-owned app controller — 2026-10-02
555
-
556
- The website's application logic and four policy/transform helper modules now
557
- compile into `viewstl.js`. The ESM, CommonJS and classic-script builds expose
558
- `mountViewstlApp`; low-level `StlViewer` behavior is preserved. The suite now
559
- contains 70 Node tests, including the 16 tests moved from the site. All pass,
560
- along with strict TypeScript and the 14-file legacy integrity check.
561
-
562
- Automated Edge 154.0.4258.48 passed the site's 96 browser assertions and 15
563
- additional controller checks: lazy mounting, optional samples, duplicate-mount
564
- rejection, public file loading, detached state, cancellation, disposal during
565
- an active parser job, worker/canvas/listener cleanup, idempotent disposal,
566
- refusing calls after disposal, late-read isolation during remounting, separate
567
- embedded roots, radio groups and drop targets. CAD lazy loading, cancellation,
568
- recovery and a 390px viewport were also rechecked. No new real-mobile, Safari
569
- or Firefox coverage is claimed.
570
-
571
- Preview release `20261002-79c817751172` passed all 18 asset hashes and live
572
- HTTPS checks for STL, OBJ, 3MF and all four CAD aliases, malformed CAD recovery,
573
- millimetre dimensions and assembly colors. Observed requests were same-origin
574
- GETs without bodies; no CSP/page errors occurred. Evidence is in the sibling
575
- website workspace under `results/plugin-app-refactor/` and
576
- `results/deploy-20261002-79c817751172/`. No npm publication or GitHub push.
577
-
578
- ## Optional Save dialog — 2026-10-08
579
-
580
- The app controller binds an optional complete save-* control group. All behavior
581
- is packaged in viewstl.js and delegates to the existing download_models API;
582
- low-level writers are unchanged. The host supplies explanatory markup/styles.
583
-
584
- 93 Node tests, strict types and all 14 legacy integrity hashes pass. Desktop
585
- headless Edge 154.0.4258.62 passed 42 local and 42 deployed HTTPS Save checks:
586
- actual STL/OBJ/3MF/STEP/IGES downloads and reimports, OBJ ZIP materials, translated
587
- selected/all geometry, cancellation with actual stalled export workers, resource
588
- cleanup, validation-error recovery, PNG regression and keyboard focus. 320/390px
589
- layout and touch taps are emulation, not physical mobile tests. Twenty-four app
590
- lifecycle checks cover export cancellation on clear/remove/dispose, independent
591
- prefixed dialogs, optional-control omission and fail-fast incomplete groups.
592
- Fifteen URL-drop regression checks also passed. No large-file performance claim
593
- or Safari/Firefox coverage is added by these UI tests.
594
-
595
- Preview release 20261008-580a812896b6 passed all 24 public file hashes. Observed
596
- Save-test requests were same-origin GETs without uploads. Evidence and the
597
- reproducible browser runners are in the sibling website workspace under
598
- results/save-local, results/save-lifecycle, results/save-url-regression and
1
+ # ViewSTL v2 verification
2
+
3
+ This file records dated checks. Older sections describe the alpha at the time
4
+ of each check; release-candidate results are recorded separately below.
5
+
6
+ ## rc.9 website/plugin separation — 2026-11-14
7
+
8
+ The four browser/CJS/classic distributions contain no website controller,
9
+ required page-control IDs or `mountViewstlApp` export. `ViewerSession` was tested
10
+ in a bare page with only two containers: lazy initialization, independent state,
11
+ malformed-file recovery, detached snapshots, transforms, duplication, arrangement,
12
+ animation metadata, manipulation binding, VSB import/export, failed scene append,
13
+ cancellation and resource disposal all passed (17 checks).
14
+
15
+ 144 plugin unit tests, strict browser/Node TypeScript checks and 37 legacy-file
16
+ hashes passed. Seven UI input tests moved with their source to the website and
17
+ passed there. Native WebGL2, workers/CAD assets and Node analysis are retained.
18
+
19
+ The candidate-packed website passed 54 shortcut, 24 lifecycle, 42 save/PNG,
20
+ 26 scene-save, 25 scene-open, 39 persistent-print-panel, 25 animation, 25 model-tool,
21
+ 15 URL-drop and 578 supporting-page/navigation checks in Windows Edge 157.
22
+ Ten production layout assertions passed in Windows Chrome 157, including
23
+ footer/resize behavior. Viewports, touch and reduced motion were emulated;
24
+ physical Android/iOS, Safari/Firefox and broad large-CAD stress were not tested.
25
+ URL fixtures intercepted the relay; local save/check tests recorded no uploads.
26
+
27
+ The compressed ESM plugin entry is 44,926 bytes, and the separate minified site
28
+ controller is 14,591 bytes. Production's measured initial viewer/page assets
29
+ total 77,933 gzip bytes (excluding third-party ads/analytics and lazy assets).
30
+ These are artifact sizes, not download-time or memory benchmarks.
31
+
32
+ Evidence: plugin `test-results/separation-tests.txt` and the sibling website's
33
+ `results/separate-site-ui-20261114/final/`. Website sources and tests are not part
34
+ of the plugin package. Published rc.8/legacy builds retain their original APIs;
35
+ rc.9 documents the migration for consumers of the removed app helper.
36
+
37
+ ## rc.8 selection-tool verification — 2026-11-14
38
+
39
+ Selection mode opens the compact tool box with Move active. The website passed
40
+ 54 desktop-shortcut checks, including retargeting, Move/Rotate/Depth drags,
41
+ unchanged camera/unselected models, empty-space drags, fresh-session defaults,
42
+ Select-off/Done/Escape, cancellation during dragging and narrow-screen exit.
43
+ Existing animation (25), model tools (25) and app lifecycle (24) checks passed.
44
+ Tests used headless Windows Edge 157.0.4341.46; narrow/touch cases are emulation.
45
+ No physical mobile, Safari or Firefox validation is claimed for this change.
46
+
47
+ 147 unit tests, strict browser/Node type checks and all 37 legacy hashes pass.
48
+ Evidence: website `results/selection-tools-20261114/`, plugin
49
+ `test-results/rc8-tests.txt` and the staged rc.8 package verification artifacts.
50
+
51
+ ## rc.7 release candidate verification — 2026-11-14
52
+
53
+ The desktop app shortcuts and VSB binary MIME fix pass 147 unit tests, strict
54
+ browser/Node type checks and the 37-file legacy integrity guard. Both staged
55
+ package names pass browser and Node ESM/CommonJS import checks, package-content
56
+ checks and the required first-line version/banner checks.
57
+
58
+ The website candidate passed 43 shortcut checks in headless Windows Edge
59
+ 157.0.4341.46: Open/Save, all seven camera presets, unchanged model transforms,
60
+ single-click selection without camera movement, drag rejection, keyboard
61
+ toggle/Escape, resize exit, persistent print results, disabled empty-scene
62
+ actions, and desktop/narrow/touch-only layouts. Another 26 scene-save and 25
63
+ scene-open checks passed. Scene URL fixtures use mocked relay responses.
64
+ Screens/touch are emulation; no physical Android, Safari or Firefox validation
65
+ is claimed. The previously requested banner is included in rc.7.
66
+
67
+ Evidence: website `results/desktop-shortcuts-20261114/` and plugin
68
+ `test-results/desktop-shortcuts-20261114/` / `test-results/vsb-mime-20261114/`.
69
+ The VSB section below records the earlier local checkpoint, before rc.7 staging.
70
+
71
+ ## VSB download MIME fix — 2026-11-14 (local, unpublished)
72
+
73
+ The owner reported Android saving scenes as `name.vsb.zip`. Both the scene
74
+ worker used by `export_scene` / `download_scene` and the compatibility
75
+ `get_vsb_blob` / `download_vsb` path now return `application/octet-stream`
76
+ instead of `application/zip`. The `.vsb` filename and ZIP container bytes are
77
+ unchanged; existing VSB files remain compatible. Actual OBJ ZIP exports still
78
+ use their ZIP MIME type.
79
+
80
+ All 147 unit tests pass and the 37-file legacy integrity guard passes. A real
81
+ worker/download check in headless Windows Edge 157.0.4341.46 verified binary
82
+ MIME for both VSB APIs, reopened both two-model scenes with positions preserved,
83
+ and downloaded `android-scene.vsb` without console errors. Evidence is in
84
+ `test-results/vsb-mime-20261114/` and `test-results/vsb-mime-tests-20261114.log`.
85
+ Android download behavior still requires a physical-device retest. A file
86
+ manager that inspects the bytes may continue recognizing the ZIP container.
87
+
88
+ The build is updated locally, including the previously approved author banner.
89
+ The package version remains rc.6 for this unpublished working tree; do not
90
+ overwrite the existing registry artifact. Production/preview still use the
91
+ published rc.6 package and have not received this fix. A new plugin version
92
+ and website deployment are needed to ship it.
93
+
94
+ ## npm names and installation — 2026-11-07
95
+
96
+ Published `viewstl@2.0.0-rc.5` and `@omrips/viewstl@2.0.0-rc.5` with `latest`
97
+ pointing to rc.5. The existing scoped `next` tag was also advanced to rc.5.
98
+ Both READMEs document `npm install viewstl` and retain the scoped alternative.
99
+ All existing scoped versions remain available.
100
+
101
+ All 136 unit tests, strict browser/Node type checks and 37 legacy integrity
102
+ checks pass again. Both packed distributions pass Node ESM/CommonJS type checks
103
+ and runtime checks for browser exports, worker/CAD assets and STL/OBJ/3MF/STEP/IGES
104
+ analysis. Fresh public-registry installs without a version suffix pass those
105
+ runtime checks for both package names. Public tarball bytes and SHA-512 integrity
106
+ match the tested local archives; each package contains 40 files.
107
+
108
+ All 31 files under `build/` match the previously tested GitHub rc.5 distribution
109
+ byte for byte. No renderer changes were made and browser/device tests were not
110
+ rerun for this packaging update. The GitHub browser evidence below still applies
111
+ to those exact runtime bytes. Evidence: local `test-results/npm-stage.json` and
112
+ its referenced staging directory. See [maintainer workflow](npm-releases.md).
113
+
114
+ ## GitHub root-layout release 2.0.0-rc.5 — 2026-11-07
115
+
116
+ The release worktree places the v2 sources/distribution in `src/` and `build/`.
117
+ The complete pre-v2 GitHub tree is archived under `legacy/v1/`; its 23 original
118
+ Git blobs and the 14-file local v1.14 snapshot pass SHA-256/size verification.
119
+ Historical sections below retain the paths and versions used at the time.
120
+
121
+ All **136 unit tests** pass, along with strict browser and Node TypeScript
122
+ consumers. Actual desktop Chrome 156, without device emulation, passes **46
123
+ browser checks**: 15 compatibility, 11 animation, 11 scene and 9 export checks.
124
+ These exercise the relocated classic/ESM entries, module workers, legacy mesh
125
+ bridge, STL/OBJ/3MF/STEP/IGES export/reimport, scene playback, cancellation,
126
+ context restoration and a responsive million-triangle STL export.
127
+
128
+ The packed `@omrips/viewstl@2.0.0-rc.5` tarball installs into a clean consumer
129
+ project. Browser ESM/CommonJS exports, version reporting, worker/CAD asset paths,
130
+ and server analysis of STL, OBJ, 3MF, STEP and IGES pass. Node analysis also
131
+ passes through the CommonJS entry. Archive contents exclude development fixtures,
132
+ legacy runtime copies and site/server files; license notices and lazy assets are included.
133
+
134
+ The layout update also corrects old harness references to the legacy parser and
135
+ worker directory. The compatibility animation assertion now waits for the public
136
+ completion callback and checks the public completed state, rather than assuming
137
+ the old private animation representation or a fixed wall-clock delay.
138
+
139
+ Evidence is retained locally in the original plugin checkout under
140
+ `test-results/github-v2-20261107/`. Physical mobile, Safari and Firefox validation
141
+ remain pending. This release does not update the preview website or npm registry.
142
+
143
+ ## Live animation save/open verification — 2026-11-02
144
+
145
+ Verified the existing `20261102-f04f34e66b7c` release through the actual Save and
146
+ Open controls on `https://preview.viewstl.com/`, in desktop in-app Chromium.
147
+ No runtime changes or redeployment were needed. Two binary STL fixtures have
148
+ offset geometry centers: one runs reverse X rotation at 3 seconds per turn and
149
+ is paused; the other runs forward Z rotation at 7 seconds per turn.
150
+
151
+ Both VSB and VSJ were downloaded, the page was freshly reloaded, and the downloaded
152
+ files were opened and saved again. **40 checks pass** against the resulting files
153
+ and visible controls: two models, camera, position/scale/appearance, animation
154
+ definition, pivot/origin, pause state, exact paused time and pose, advancing running
155
+ time and a pose consistent with that time. VSB mesh coordinates match both their
156
+ original files and the re-saved archive. VSJ file references remain intact. The
157
+ paused model's elapsed time stayed exactly `7400.434000000001` ms in both formats;
158
+ the running model continued from each saved time instead of restarting.
159
+
160
+ A second pair of files was saved with both models paused. PNGs downloaded before
161
+ saving and after independently reopening each format are **byte-for-byte equal**.
162
+ VSB opens alone; VSJ was opened together with its two referenced STL files. Paused
163
+ models expose Resume with the restored axis, duration and direction. There were
164
+ no console errors on the final restored page. This is desktop-browser evidence,
165
+ not physical mobile or other-browser coverage.
166
+
167
+ The website workspace retains actual downloads, UI-state records, PNGs and
168
+ `verification.json` in `results/animation-roundtrip-20261102/`. Recheck those
169
+ artifacts with `node site/qa/verify-animation-downloads.mjs --images`; regenerate
170
+ the offset STL fixtures with `node site/qa/make-animation-fixtures.mjs`.
171
+
172
+ ## Preview-site animation integration — 2026-11-02
173
+
174
+ Deployed to preview as `20261102-f04f34e66b7c`. The optional animation app binding
175
+ is bundled inside viewstl.js; the site's initializer is unchanged. The site adds
176
+ static controls under Models → Animation: axis, seconds per turn, direction and
177
+ Play/Pause/Resume/Stop. Off-center models spin about their center without moving
178
+ their visible pose. Editing uses current transforms, and adding/selecting files
179
+ preserves other models' animation. Print checks pause their targets and offer
180
+ explicit Resume while keeping the results panel open. Reduced-motion preference
181
+ pauses restored playback. Stopped animations also retain an equivalent static
182
+ VSJ pose with the original referenced mesh.
183
+
184
+ All **136 unit tests**, both strict type checks and the legacy guard pass.
185
+ Actual desktop Chromium 156 passes **25 new integration checks** and **96 existing
186
+ site checks**. New coverage includes invalid speed, concurrent models, live-pose
187
+ manual editing, drag entry, print pause/resume, VSB phase/pause restoration,
188
+ stopped off-center VSJ reopening with an identical PNG, callback composition,
189
+ clear/dispose/remount and simulated reduced motion. Keyboard Enter playback was
190
+ also exercised. 320px and 390px viewport checks show no horizontal overflow and
191
+ 44px-high playback buttons; these are emulated widths, not physical touch tests.
192
+
193
+ All 29 public HTTPS files match the local SHA-256 manifest. Live browser smoke
194
+ checks cover loading, keyboard playback and print-check interaction. Nginx, relay
195
+ and Certbot remain active; configuration/service/binary hashes match the previous
196
+ release and SELinux remains enforcing. Initial gzip total is 57,897 bytes; the
197
+ viewer entry is 42,150 bytes. No new million-triangle or total-memory benchmark
198
+ was performed for the app controls; the earlier plugin measurement remains below.
199
+ Physical mobile, Safari/Firefox and actual hidden-tab behavior remain unverified.
200
+
201
+ Evidence: the site workspace's `results/animation-integration/` and
202
+ `results/deploy-20261102-f04f34e66b7c/`. Reproduce the browser checks through the
203
+ local-only `site/qa/animation.html` and `site/qa/index.html` pages. The QA harness
204
+ is excluded from deployment. npm is unchanged (`2.0.0-rc.4`); no GitHub push.
205
+
206
+ ## Model animation — unreleased development update, 2026-11-02
207
+
208
+ The local plugin now has validated legacy delta/exact playback, per-model
209
+ pause/resume/state queries and transition/completion callbacks. Animation uses
210
+ elapsed frame time, retires finished tracks independently, stops on manual
211
+ transform edits and suspends on document hiding or context loss. VSJ and both
212
+ VSB APIs preserve animation phase, pause state, units and rotation pivot; animated
213
+ VSB meshes retain scale in metadata to avoid applying it twice on reopening.
214
+ The native WebGL2 renderer and existing worker architecture remain in use.
215
+
216
+ - All **132 Node tests pass** on Node.js 24.19.0, Windows. Nine new tests cover
217
+ mixed durations, frame cadence, pause/resume/suspension, manual changes,
218
+ replacement and copied state, scale/statistics invalidation, invalid numeric
219
+ inputs and overflow, scene validation, VSJ/VSB restoration and export snapshots.
220
+ - Browser and server-only strict TypeScript checks pass. The legacy guard passes
221
+ for tracked legacy files and all 14 archived files.
222
+ - **11 animation browser checks pass** in actual desktop Chromium 156 on Windows,
223
+ using workers and WebGL2. These cover constructor playback, concurrent models,
224
+ idle behavior, pause/resume/stop, modern and legacy scene restoration, group
225
+ starts, bad-scene rollback, print-check staleness, mesh/PNG snapshots, forced
226
+ context loss/restoration and resource cleanup. Context loss is deliberately
227
+ triggered with `WEBGL_lose_context`, not a hardware failure.
228
+ - Existing browser compatibility (**15**) and scene/rendering (**11**) checks
229
+ also pass: **37 passing browser checks** in total.
230
+ - A generated **1,000,000-triangle** model animated over 120 measured frame
231
+ intervals: median **16.7 ms**, p95 **16.8 ms**, maximum **16.9 ms**. Geometry
232
+ objects and GPU resources retained identity, with two GPU buffers and
233
+ 72,375,000 bytes of resident geometry typed arrays. These are frame intervals
234
+ on one desktop, not GPU timings, allocation profiling or total process memory.
235
+ - The interactive example at `examples/v2/animation.html` runs locally and exposes
236
+ Play, Pause, Resume, Stop and Reset. No models or external assets are fetched.
237
+
238
+ Actual hidden-tab behavior remains unverified: automation tab changes in the
239
+ in-app browser and Chrome did not produce a document `visibilitychange` event.
240
+ The suspension/resumption code is covered by unit tests and the real WebGL
241
+ context-loss check. Firefox, Safari, physical phones/tablets, touch, reduced-motion
242
+ site integration and a total-memory profile have not been tested in this update.
243
+
244
+ Reproduce with `pnpm build`, `pnpm test`, `pnpm check:types`,
245
+ `pnpm check:node-types`, `pnpm check:legacy`, then `pnpm start`. Open
246
+ `tests/v2/animation-browser.html`, `tests/v2/browser.html` and
247
+ `tests/v2/scene-browser.html` and run their checks. The million-triangle and
248
+ background-tab checks have separate buttons on the animation page.
249
+
250
+ Evidence is retained locally in ignored `test-results/animation-*` files. The
251
+ package version is still `2.0.0-rc.4`; this development update has **not** been
252
+ published to npm or deployed. The proposed site work is described in
253
+ [the preview integration plan](v2-animation-site-plan.md).
254
+
255
+ ## Runnable server example 2.0.0-rc.4 — 2026-10-20
256
+
257
+ The npm README now contains a clearly labeled server-only example, including
258
+ installation, the `analyze.mjs` filename, a three-line script that prints JSON,
259
+ and the command to run it. This is a documentation update.
260
+
261
+ The exact example was extracted from the packed README and run with a binary
262
+ STL using the installed package on Node.js 24.19.0 on Windows. The resulting
263
+ JSON contains the expected dimensions, surface area, validated volume and mesh
264
+ checks. All 40 packaged files match the local release sources by SHA-256.
265
+ All 31 existing browser/Node runtime, declaration and CAD assets match the
266
+ public `2.0.0-rc.3` package apart from embedded version strings. The legacy
267
+ guard passes for tracked files and all 14 archived files. No runtime logic was
268
+ changed; the broader API verification below still describes the implementation.
269
+
270
+ Evidence is retained locally in `test-results/npm-2.0.0-rc.4/` (ignored by Git).
271
+
272
+ ## Node.js model analysis 2.0.0-rc.3 — 2026-10-20
273
+
274
+ The new `@omrips/viewstl/node` export provides `analyzeFile`, `analyzeBuffer`
275
+ and `createAnalyzer`. It reuses the browser's parsers and mesh checks in Node
276
+ worker threads, loading CAD JavaScript/WASM from the installed package.
277
+
278
+ - All 123 tests pass on Node.js 24.19.0 on Windows. New tests cover real workers,
279
+ all five model formats, physical and unknown units, validated/invalid volume,
280
+ malformed input and recovery, buffer offsets and ownership, file/archive/
281
+ triangle/memory admission limits, bounded queues, cancellation, disposal,
282
+ whole-job and partial-check deadlines, and progress callback failures.
283
+ - A clean consumer installation of the packed tarball passes on actual Node.js
284
+ 20.20.2 and 24.19.0 on Windows. ESM and CommonJS each analyze STL, OBJ, 3MF,
285
+ STEP and IGES fixtures through the public export, including local CAD WASM.
286
+ Buffer input, unknown units and recovery after malformed input also pass.
287
+ - Strict TypeScript consumers pass for both module systems using Node types
288
+ without the DOM library, including against the installed package. Existing
289
+ browser TypeScript checks also pass.
290
+ - The package contains 40 files and no runtime dependencies. Installed files
291
+ match their release sources by SHA-256. The allowlist excludes test fixtures,
292
+ local test servers, credentials and node_modules.
293
+ - All 26 existing browser runtime/declaration/CAD assets match the public
294
+ `2.0.0-rc.2` package apart from embedded version strings. Browser behavior was
295
+ not changed; no new browser or physical-device test coverage is claimed.
296
+ - The legacy guard passes for tracked legacy files and all 14 archived files.
297
+
298
+ Linux/macOS execution, additional Node versions and large production workloads
299
+ have not been exercised in this release check. Memory budgets are estimates,
300
+ not a hard process RSS cap. STEP/IGES results describe the tessellated mesh,
301
+ not exact CAD solids. Optional FDM estimates are not a printability guarantee.
302
+
303
+ Reproduction scripts, packed/public-install verification, fixtures and terminal
304
+ evidence are retained locally in `test-results/npm-2.0.0-rc.3/` (ignored by Git).
305
+
306
+ ## Quick-start documentation update 2.0.0-rc.2 — 2026-10-20
307
+
308
+ The README and usage guide now begin with the minimum installation step and
309
+ a three-line HTML example. The example was extracted unchanged from the README,
310
+ served with the complete distribution directory and a binary STL, and verified
311
+ in the desktop Codex Chromium browser: the model rendered, the worker and model
312
+ requests succeeded, and keyboard rotation responded without console errors.
313
+
314
+ All 112 unit tests and the legacy preservation check passed. Every runtime asset
315
+ was compared with the installed public `2.0.0-rc.1` package; only the embedded
316
+ version string changed. This update does not add browser/device coverage beyond
317
+ the release-candidate verification below. Evidence is in the ignored local
318
+ `test-results/npm-2.0.0-rc.2/` folder.
319
+
320
+ ## npm release candidate 2.0.0-rc.1 — 2026-10-19
321
+
322
+ Prepared the first public npm package as `@omrips/viewstl`, with the release
323
+ candidate on the `next` tag. The package version and `StlViewer.version` agree.
324
+ The GitHub legacy paths and all archived legacy files remain unchanged.
325
+
326
+ Validation against the packed tarball installed into a clean consumer:
327
+
328
+ - 112 Node tests pass, with strict TypeScript source-consumer checks.
329
+ - ESM imports and CommonJS requires work without a browser DOM. Both installed
330
+ package TypeScript entry points pass strict NodeNext checks.
331
+ - All 35 installed files match the release source by SHA-256. The allowlist
332
+ includes the viewer, module worker, lazy chunks, CAD glue/WASM, declarations,
333
+ documentation and license/source notices. No credentials, test data, local
334
+ server scripts, node_modules or legacy runtime files are packaged.
335
+ - Production builds succeed with Vite 8.3.4 and Webpack 5.112.0. Both follow the
336
+ documented complete-static-directory copy and explicit `worker_url` setup.
337
+ - 11 browser checks pass in each of four consumers: Vite, Webpack, direct ESM
338
+ and classic script (44 total). These use the installed distribution and real
339
+ WebGL 2/module workers for local binary STL, STL/OBJ/3MF/STEP/IGES exports and
340
+ reimports, print checks, PNG export, VSB save/load and VSJ export.
341
+ - Browser: desktop Codex in-app Chromium 155.0.0.0 on Windows, without device
342
+ emulation. The local pages use a same-origin CSP without JavaScript eval;
343
+ WebAssembly compilation is allowed. Parser/CAD assets are self-hosted.
344
+ - The legacy guard verifies unchanged tracked legacy files and all 14 archived
345
+ snapshot hashes.
346
+
347
+ Reproduction scripts, build fixtures, tarball inventory, terminal results,
348
+ browser output and screenshots are retained locally in the ignored
349
+ `test-results/npm-2.0.0-rc.1/` folder. Firefox, Safari, physical touch/mobile
350
+ devices and broader real-world large-CAD workloads remain unverified; this
351
+ release is a candidate, not a claim that those checks have passed. The optional
352
+ bundler `worker_factory` variant was not exercised by this release check.
353
+
354
+ ## URL drops in the optional app controller — 2026-10-02
355
+
356
+ `mountViewstlApp` routes dropped HTTP/HTTPS links through its configured relay and
357
+ existing URL import queue. Six new unit cases bring the plugin suite to 93 passing
358
+ tests; strict types and all 14 legacy integrity checks pass. The site's full
359
+ 96-assertion browser harness and 15 app lifecycle checks pass with this build.
360
+
361
+ Desktop headless Edge 154.0.4258.48 passes 15 local and 16 live URL-drop checks:
362
+ URI/plain-text/Firefox payloads, signed query preservation, deduplication, local
363
+ file precedence, untouched input behavior, unsupported schemes, failure recovery,
364
+ cancellation and an actual anchor drag. Firefox data is emulated; Firefox/Safari
365
+ and physical devices were not tested. Live preview also fetched and parsed a
366
+ real public STEP URL through Go. Other deterministic URL-drop response fixtures
367
+ are explicitly mocked in the browser runner. These changes and the preceding
368
+ export API build ship on preview in release `20261002-8f91150b7782`; export controls
369
+ are still not wired to the site. The legacy site was not changed.
370
+
371
+ ## Plugin mesh exports — 2026-10-02
372
+
373
+ The local v2 build adds `export_models` and `download_models` for binary STL,
374
+ OBJ/MTL, 3MF, STEP/STP and IGES/IGS. These are plugin-only changes; the website
375
+ and deployed preview assets have not been synchronized or changed for this work.
376
+ All writers are JavaScript worker modules; CAD export does not use the Go relay
377
+ or download a new CAD engine. The native WebGL2 renderer and legacy APIs remain.
378
+
379
+ Validation:
380
+
381
+ - 87 Node tests pass, including 14 export cases. The strict TypeScript consumer
382
+ check passes. All 14 archived legacy files verify unchanged.
383
+ - Open CASCADE independently reads generated STEP and IGES: open triangle
384
+ surfaces, multiple models, nonuniform scale, rotation, translation, millimeter
385
+ and inch units. Triangle counts, bounds and area match the expected mesh.
386
+ Checking area exposed IGES numeric tokens crossing padded parameter records;
387
+ writers now wrap at parameter boundaries and the regression covers this.
388
+ - Official 3MF Core/Materials XSD appendix validation passes with lxml. The
389
+ validation helper uses a stricter one-million occurrence cap because libxml2
390
+ 2.11 rejects the published `2147483647` value, and trims the leading space in
391
+ the Materials appendix's `type=" ST_Numbers"`. No geometry/schema rules are
392
+ relaxed. ZIP/XML tests also verify object separation, shared vertices, units,
393
+ per-vertex color gradients, safe names and material references.
394
+ - Headless desktop Edge **154.0.4258.48** passes all 9 export browser scenarios
395
+ and all 15 existing browser compatibility scenarios. The export page uses a
396
+ same-origin CSP without JavaScript eval. Tests cover real workers, all-format
397
+ reimport, preserved live buffers, selected export, OBJ ZIP, a real browser
398
+ download, running/queued cancellation, callback exceptions, scene cleanup,
399
+ memory rejection and subsequent recovery. No unexpected page/WebGL errors.
400
+ - Export/reimport requests were same-origin GETs; the actual download used a
401
+ local Blob. No file upload or external endpoint request occurred. Edge's
402
+ internal `edge://` downloads-panel resources are excluded from web traffic.
403
+ - A **1,000,000-triangle binary STL** produced **50,000,084 bytes** in **1,277 ms**
404
+ with **75 animation frames** during export. This is one synthetic local desktop
405
+ observation, not a performance guarantee or a measured process-memory peak.
406
+
407
+ Evidence: `test-results/exports/browser.json`, `browser.png`, `compatibility.txt`,
408
+ `assembly-mm.step`, `assembly-inch.step`, `assembly-mm.iges`, `assembly-inch.iges`
409
+ and `colored-scene.3mf`. These generated files are ignored by Git. Reproduce the
410
+ browser checks with a local plugin server and `scripts/check-export-browser.mjs`
411
+ (Playwright module supplied by `VIEWSTL_PLAYWRIGHT`, URL by `VIEWSTL_QA_URL`).
412
+
413
+ The optional `scripts/check-export-3mf-schema.py` reads the following downloaded
414
+ source files from `test-results/exports` and validates the generated 3MF fixture:
415
+
416
+ - `3mf-core-spec.txt`: https://raw.githubusercontent.com/3MFConsortium/spec_core/master/3MF%20Core%20Specification.md
417
+ - `3mf-materials-spec.txt`: https://raw.githubusercontent.com/3MFConsortium/spec_materials/master/3MF%20Materials%20Extension.md
418
+ - `xml.xsd`: https://www.w3.org/2001/xml.xsd
419
+
420
+ Limits: STEP/IGES contain planar mesh surfaces, not recovered analytic CAD solids
421
+ or feature history. No F3D is implemented. 3MF performs edge/winding/volume checks,
422
+ not full solid repair or self-intersection testing. Physical phones/tablets,
423
+ Safari/Firefox, commercial CAD applications and large STEP/IGES export workloads
424
+ have not been validated in this change. Export options and omissions are listed
425
+ in [usage](v2-usage.md#local-mesh-export).
426
+
427
+ ## STEP/IGES addition — 2026-10-01
428
+
429
+ The local build adds STEP/STP and IGES/IGS with lazy, self-hosted WASM in
430
+ disposable workers. The 54 plugin tests and TypeScript checks pass. Six CAD
431
+ tests also pass under Node's `--disallow-code-generation-from-strings` flag:
432
+ format aliases, unit conversion, assembly geometry/colors, malformed input,
433
+ recovery, index validation, input/output budgets and rejection of an allocation
434
+ beyond a 32 MiB configured WASM heap. The 14 archived legacy files verify unchanged.
435
+
436
+ The website's 16 unit tests and its complete browser harness pass in local
437
+ headless Edge 154.0.4258.37. Additional browser checks verify no CAD downloads
438
+ for the empty page or STL, cancellation during the reader download, subsequent
439
+ CAD recovery and GET-only same-origin asset requests without file uploads.
440
+ The browser harness exercises all four aliases, mm dimensions, colors, malformed
441
+ CAD recovery and multiple CAD files, alongside existing STL/OBJ/3MF and view tests.
442
+
443
+ These are desktop automated checks, with a 390px emulated viewport for layout.
444
+ Physical mobile devices, Safari/Firefox and large real-world CAD assemblies have
445
+ not been validated. No new browser-memory or large-CAD performance claim is made.
446
+ After explicit deployment authorization, the synchronized site and viewer were
447
+ deployed as preview release `20261001-f40c6b922ea5`. All 22 public file hashes
448
+ matched. Live headless Edge verified all four CAD aliases, correct mm dimensions,
449
+ assembly positions/colors, malformed-file recovery and existing STL/OBJ/3MF
450
+ loading. Observed network requests were same-origin GETs with no uploaded file
451
+ data. The WASM response used `application/wasm` and gzip; no CSP/page errors were
452
+ reported. Deployment evidence is in the website workspace's
453
+ `results/deploy-20261001-f40c6b922ea5/`. DNS and the legacy site were unchanged.
454
+
455
+ Checked on 2026-09-30, version `2.0.0-alpha.1`, on Windows in the
456
+ Codex in-app Chromium browser. These results describe this development
457
+ release, not a claim of complete compatibility with every legacy integration.
458
+
459
+ ## Completed checks
460
+
461
+ Update 2026-10-01, additional views: the Node suite now has 43 passing cases.
462
+ All 15 existing browser compatibility checks passed, plus 11 new appearance
463
+ checks in `tests/v2/appearance-browser.html`. Those validate actual PNG pixels
464
+ for mesh lines, studio shading, X-ray transparency, feature edges, wireframe,
465
+ front/back orientation colors, half-model clipping and reversed clipping;
466
+ all section axes/endpoints; independent smooth shading; VSJ/VSB persistence;
467
+ graphics context restoration; and repeated switching/resource cleanup.
468
+ Node cases cover section-aware picking, edge angles, budget rejection, worker
469
+ failure and stale view completion. Strict consumer types and all 14 archived
470
+ legacy hashes passed. The site passed 31 browser checks and 2 policy checks.
471
+ Responsive controls were inspected at 320 × 740 and 390 × 844, with no
472
+ horizontal overflow; these are desktop viewport simulations, not real touch
473
+ hardware tests. Live preview loading, smooth/edge derivation, Studio and
474
+ section controls passed with no browser warnings/errors. The new appearance
475
+ tests use small fixtures; no additional large-model stress test was run.
476
+
477
+ Update 2026-10-01: chunked local binary STL parsing, optional memory-budget checks,
478
+ OBJ line iteration and GPU-allocation failure cleanup were added. The 36-test
479
+ Node suite passed, followed by the additional GPU fault-injection test (37 total
480
+ cases). TypeScript and legacy preservation checks passed. All 15 browser cases
481
+ below passed again; the separate preview site passed 22 browser and 2 policy
482
+ checks. A 300,758,484-byte binary STL with 6,015,168 triangles rendered locally
483
+ and on preview.viewstl.com, exceeding the old byte and triangle limits. Its
484
+ wireframe request was rejected by the configured memory budget before map
485
+ allocation. The file stayed on the client. This is one desktop test, not a
486
+ guarantee for every model/device; large OBJ/3MF and low-memory mobile stress
487
+ tests remain outstanding. Existing package-tarball checks below are from the
488
+ September verification; no new npm publication occurred.
489
+
490
+ | Check | Result |
491
+ | --- | --- |
492
+ | Node automated tests | 30 passed, 0 failed |
493
+ | Real browser integration checks | 15 passed, 0 failed; no unexpected callback errors |
494
+ | TypeScript strict consumer checks | ESM and CommonJS package declarations checked |
495
+ | Local npm tarball installation | ESM/CJS constructors, worker/browser exports and types resolve |
496
+ | Legacy preservation | Original tracked source/build/dependencies unchanged; 14 local snapshot hashes match |
497
+ | Responsive demo | Single-column layout at 390 × 844; no horizontal document overflow |
498
+ | Local file picker | Keyboard-accessible picker loads a real cube STL; dimensions 2 × 2 × 2, 12 triangles |
499
+ | Direct manipulation | Mouse drag visibly rotates the loaded model; grid keyboard control and wireframe/smooth selection checked |
500
+
501
+ Automated coverage includes ASCII/binary STL, three color conventions,
502
+ invalid/truncated/non-finite data, OBJ indices, bounds/area/volume,
503
+ nonuniform scaling, matrix/picking calculations, transfer detachment,
504
+ worker limits/cancellation/timeouts, ZIP integrity/expansion limits,
505
+ real saved VSB archives, 3MF transforms/colors/relationships and invalid
506
+ XML/component cycles.
507
+
508
+ Browser coverage exercises classic-script and module entry points, actual
509
+ module workers, callback order, IDs including zero, idle rendering,
510
+ appearance/transforms/units, picking, disabled controls, animation,
511
+ VSJ relative URLs, multiple models, VSB round trips, 3MF/OBJ loading,
512
+ PNG capture, legacy API comparisons, the optional real Three.js mesh
513
+ bridge, cancellation with ID reuse, clean/dispose, context restoration,
514
+ and a visible initialization failure when WebGL2 is unavailable.
515
+
516
+ The legacy comparison deliberately records one corrected bug: model
517
+ dimensions now change after scaling. The legacy plugin returned stale
518
+ dimensions while already reporting scaled area and volume.
519
+
520
+ ## Performance observation
521
+
522
+ A generated **1,000,000-triangle binary STL (50.0 MB)** loaded through the
523
+ worker and reached the first rendered frames in **273 ms** in one desktop
524
+ run. WebGL reported no error. It used two tracked geometry buffers; after
525
+ `clean()`, there were **zero tracked GPU buffers and zero active workers**.
526
+
527
+ The input was an in-memory File generated before timing. This does not
528
+ measure network download, physical disk latency, peak memory, cold-browser
529
+ startup, or mobile performance. It is a reproducible smoke benchmark, not
530
+ a cross-device promise. Run it from `/tests/v2/browser.html`.
531
+
532
+ ## Build sizes
533
+
534
+ Sizes measured with Node gzip defaults; servers must enable compression
535
+ to achieve compressed transfer sizes. Decimal kB below.
536
+
537
+ | Asset | Raw | Gzip |
538
+ | --- | ---: | ---: |
539
+ | Classic minified viewer | 43.3 kB | 14.9 kB |
540
+ | Module worker | 4.6 kB | 2.1 kB |
541
+ | Shared worker geometry chunk | 3.8 kB | 1.9 kB |
542
+ | Lazy archive/XML chunk | 47.2 kB | 16.4 kB |
543
+ | Readable ESM viewer, alternative to classic | 69.0 kB | 18.5 kB |
544
+
545
+ The classic viewer plus initial STL worker code totals 51.6 kB raw /
546
+ 18.9 kB gzip. Archive/XML support loads only for archive operations.
547
+ The rendering/STL core includes no third-party runtime library.
548
+
549
+ ## Reproduction and remaining validation
550
+
551
+ ```sh
552
+ pnpm install --frozen-lockfile
553
+ pnpm build
554
+ pnpm test
555
+ pnpm check:types
556
+ pnpm check:legacy
557
+ pnpm start
558
+ pnpm pack
559
+ ```
560
+
561
+ The local tarball was installed into an isolated consumer directory with
562
+ scripts disabled, then its ESM import, CommonJS require, asset exports and
563
+ strict TypeScript consumers were checked. No npm package was published.
564
+ The package remains `private: true`; `@omrips/viewstl` is a provisional name.
565
+
566
+ Before a stable release or production replacement, test Firefox, Safari,
567
+ real touch/mobile hardware, high-DPI devices, representative large customer
568
+ models, peak memory, Vite/Webpack integration, and production-site callers.
569
+ The legacy site's direct Three.js internals need migration. The supported
570
+ 3MF/OBJ subsets and transparency limits are described in [usage](v2-usage.md).
571
+
572
+ Raw local browser results and the test tarball are in the ignored
573
+ `test-results/` directory. No production files, DNS, server configuration,
574
+ GitHub branch or npm registry entry were changed by this implementation.
575
+
576
+ ## Scene/grid verification — 2026-10-01
577
+
578
+ 47 Node tests passed, including aggregate scene memory accounting, serialized
579
+ budgeted parsing, reservation cleanup on allocation/dispatch failures and
580
+ multi-model derived-work guards. Strict TypeScript and 14-file legacy checks passed.
581
+ The Chromium browser passed 15 compatibility, 11 appearance and 8 new scene cases.
582
+ The scene cases exercise original coordinates, tint/restore without GPU buffer
583
+ reallocation, grid coverage beyond model bounds after pan/zoom, opaque depth
584
+ occlusion, PNG background color, finite-grid compatibility, infinite-grid VSB
585
+ round trip, context restoration/cleanup, aggregate budget rejection/recovery and
586
+ cancellation of derived work on model removal. Real mobile GPUs, Safari and Firefox
587
+ remain untested for these additions. The preview site was updated separately;
588
+ legacy files and npm publishing remain unchanged.
589
+
590
+ ## Editing frame and picking — 2026-10-01
591
+
592
+ 48 Node tests, strict TypeScript checking and the 14-file legacy integrity check
593
+ passed. Chromium passed 15 compatibility, 11 appearance and 11 scene browser
594
+ cases. Additional scene coverage verifies editing-frame pixels, clean PNG exports,
595
+ frame-buffer reuse during transforms, selection switching and cleanup, recovery
596
+ after graphics-context loss, and nearest visible surface picking after transforms.
597
+ Real mobile GPU, Safari and Firefox coverage remains outstanding.
598
+
599
+ ## Plugin-owned app controller — 2026-10-02
600
+
601
+ The website's application logic and four policy/transform helper modules now
602
+ compile into `viewstl.js`. The ESM, CommonJS and classic-script builds expose
603
+ `mountViewstlApp`; low-level `StlViewer` behavior is preserved. The suite now
604
+ contains 70 Node tests, including the 16 tests moved from the site. All pass,
605
+ along with strict TypeScript and the 14-file legacy integrity check.
606
+
607
+ Automated Edge 154.0.4258.48 passed the site's 96 browser assertions and 15
608
+ additional controller checks: lazy mounting, optional samples, duplicate-mount
609
+ rejection, public file loading, detached state, cancellation, disposal during
610
+ an active parser job, worker/canvas/listener cleanup, idempotent disposal,
611
+ refusing calls after disposal, late-read isolation during remounting, separate
612
+ embedded roots, radio groups and drop targets. CAD lazy loading, cancellation,
613
+ recovery and a 390px viewport were also rechecked. No new real-mobile, Safari
614
+ or Firefox coverage is claimed.
615
+
616
+ Preview release `20261002-79c817751172` passed all 18 asset hashes and live
617
+ HTTPS checks for STL, OBJ, 3MF and all four CAD aliases, malformed CAD recovery,
618
+ millimetre dimensions and assembly colors. Observed requests were same-origin
619
+ GETs without bodies; no CSP/page errors occurred. Evidence is in the sibling
620
+ website workspace under `results/plugin-app-refactor/` and
621
+ `results/deploy-20261002-79c817751172/`. No npm publication or GitHub push.
622
+
623
+ ## Optional Save dialog — 2026-10-08
624
+
625
+ The app controller binds an optional complete save-* control group. All behavior
626
+ is packaged in viewstl.js and delegates to the existing download_models API;
627
+ low-level writers are unchanged. The host supplies explanatory markup/styles.
628
+
629
+ 93 Node tests, strict types and all 14 legacy integrity hashes pass. Desktop
630
+ headless Edge 154.0.4258.62 passed 42 local and 42 deployed HTTPS Save checks:
631
+ actual STL/OBJ/3MF/STEP/IGES downloads and reimports, OBJ ZIP materials, translated
632
+ selected/all geometry, cancellation with actual stalled export workers, resource
633
+ cleanup, validation-error recovery, PNG regression and keyboard focus. 320/390px
634
+ layout and touch taps are emulation, not physical mobile tests. Twenty-four app
635
+ lifecycle checks cover export cancellation on clear/remove/dispose, independent
636
+ prefixed dialogs, optional-control omission and fail-fast incomplete groups.
637
+ Fifteen URL-drop regression checks also passed. No large-file performance claim
638
+ or Safari/Firefox coverage is added by these UI tests.
639
+
640
+ Preview release 20261008-580a812896b6 passed all 24 public file hashes. Observed
641
+ Save-test requests were same-origin GETs without uploads. Evidence and the
642
+ reproducible browser runners are in the sibling website workspace under
643
+ results/save-local, results/save-lifecycle, results/save-url-regression and
599
644
  results/deploy-20261008-580a812896b6. No npm publication or GitHub push.
600
-
601
- ## Scene saving — 2026-10-08
602
-
603
- Release 20261008-625337233d51 exposes VSB/VSJ whole-scene saving in the preview.
604
- The five regular mesh formats save only the selected model, per the owner's
605
- clarification. New export_scene/download_scene Promise APIs use get_vsj manifests
606
- and the existing VSB/STL archive layout, with worker-based VSB encoding,
607
- cancellation, progress, memory admission and output limits. Legacy scene getters
608
- and download methods retain their contracts.
609
-
610
- 96 Node tests, strict types and all 14 legacy integrity hashes pass. Edge
611
- 154.0.4258.62 passed 26 scene checks locally and live, including downloaded VSB
612
- round trips, VSJ round trips with explicitly supplied referenced fixture files,
613
- scene settings, source names, cancellation, memory/output/count limits and
614
- callback errors. 42 mesh/PNG/UI regression checks passed locally and live;
615
- 24 app lifecycle checks include cancellation of VSB workers on clear/remove/
616
- dispose. Same-origin GET-only network evidence shows no export uploads. Narrow
617
- and touch checks use emulation, not physical devices. Site scene reopening is
618
- not implemented; round trips explicitly use the plugin's public scene loaders.
619
- Evidence: sibling website results/scene-save-local, scene-save-mesh-regression,
620
- scene-save-lifecycle and deploy-20261008-625337233d51. All 26 public hashes match.
621
-
622
- ## Scene opening — 2026-10-08
623
-
624
- Preview release `20261008-2bc0de3fc7ab` opens VSB/VSJ through the plugin-owned file,
625
- drop and URL flows. The new `import_scene` API validates manifests/archives, stages
626
- models until success, remaps IDs, resolves local companions or relayed public URL
627
- references, and restores scene settings and editable model placement. Errors and
628
- cancellation preserve the existing scene. Legacy scene loaders are unchanged.
629
-
630
- 100 Node tests, strict types and all 14 legacy integrity hashes pass. Desktop
631
- headless Edge 154.0.4258.62 passed 25 local and 27 live scene-opening checks,
632
- including saved and legacy VSB files, local VSJ companions, editing/reset/re-saving,
633
- missing files, malformed second-model rollback, cancellation during reading and
634
- between models, recovery, URL routing and redirected VSJ base directories.
635
- Live checks include real public VSJ/STL and VSB downloads through the deployed
636
- Go relay; other remote fixtures are explicitly intercepted. Captured browser
637
- traffic remains same-origin; local scene files and companions are not uploaded.
638
- 42 mesh/PNG/save, 24 lifecycle and 15 URL-drop regression checks pass locally.
639
- Narrow layout is emulated; physical mobile hardware, Safari and Firefox remain
640
- unverified. These fixture tests do not establish large-scene peak memory or speed.
641
-
642
- The relay's 12 top-level Go tests pass, including both scene formats and final
643
- redirect-base metadata without query secrets. All 27 public asset hashes match.
644
- Nginx and relay service configuration hashes remain unchanged. Evidence is in the
645
- sibling website's `results/scene-open-local`, `scene-open-save-regression`,
646
- `scene-open-lifecycle`, `scene-open-url-regression` and
647
- `deploy-20261008-2bc0de3fc7ab/live-open`. No npm publication or GitHub push.
648
-
649
- ## Print checks — 2026-10-17
650
-
651
- 112 Node tests, strict TypeScript and 14 legacy integrity hashes pass. The new
652
- fixtures cover open meshes, duplicates, degeneracy, winding, vertex-only contacts,
653
- disconnected solids, nested cavities, intersecting shells, coplanar overlap,
654
- near-coplanar neighbors, small gaps, large translations, nonuniform scale, units,
655
- FDM estimates, time limits, memory rejection and bounded diagnostic samples.
656
- A 100,000-triangle curved fixture exposed a false coplanar-neighbor intersection;
657
- the shared-edge predicate was corrected and the case retained as a regression.
658
-
659
- Desktop headless Edge 155.0.4283.45 passes 27 print integration checks locally:
660
- lazy loading, basic/detailed coverage, cache isolation, native highlights,
661
- unchanged geometry/colors/PNG, stale reports, 390px layout, keyboard closing/focus,
662
- selected/all scope, cancellation/recovery, callback errors, memory accounting,
663
- removal/disposal, optional host controls and touch-emulated interaction. Additional
664
- regressions pass: 42 save/PNG, 25 scene-opening and 24 app-lifecycle checks. No
665
- physical mobile devices, Firefox or Safari were tested. Browser traffic captured
666
- by the print runner is same-origin GET; no analysis uploads occur.
667
-
668
- The browser's 100,000-triangle closed torus completed detailed checks in about
669
- 4.6 seconds with 279 animation frames and a maximum observed frame gap of 16.8 ms
670
- in the initial recorded run. Results vary by run/device. The Node benchmark
671
- `scripts/check-print-performance.mjs` measured about 0.6 s for 10,240 triangles
672
- and 5.4 s for 100,000 triangles. Sampled JS heap reached about 164 MB on the larger
673
- run; this is not a measurement of total/peak browser or GPU memory. Memory/time
674
- limits deliberately reject or mark incomplete larger/ambiguous workloads.
675
-
676
- Evidence: plugin `test-results/print-node.txt`, `print-performance.json`; sibling
677
- website `results/print-local`, `print-save-regression`, `print-scene-regression`
678
- and `print-lifecycle`. Reproduce browser checks with `site/qa/run-print-browser.mjs`.
679
-
680
- Preview release `20261017-b0d9d98b838b` also passed all 27 print checks over
681
- public HTTPS and all 29 public file hashes. Live evidence is in the sibling
682
- website's `results/deploy-20261017-b0d9d98b838b/live-print`. The relay binary and
683
- service/Nginx configuration hashes are unchanged; no npm publication or GitHub push.
684
-
685
- The persistent-panel follow-up release `20261017-5b21747c4c8f` passes 39 browser
686
- checks locally and over public HTTPS. Added coverage includes canvas focus,
687
- appearance controls, other dialogs, repeat launch, narrow-screen toolbar access,
688
- selection changes, loading/cancellation, adding/removing/clearing models and
689
- explicit close from an empty scene. The panel remains open throughout unrelated
690
- activity while stale reports and active jobs are handled safely. All 112 Node
691
- tests, strict types and 14 legacy hashes pass again. Evidence: sibling website
692
- `results/print-persistent/` and `results/deploy-20261017-5b21747c4c8f/`.
693
-
694
- ## 2026-11-07 — rc.6 model tools
695
-
696
- 146 unit tests pass, as do strict browser/Node TypeScript checks and the 37-file legacy hash guard. Actual Windows Chrome 156 runs against the site built from the candidate npm tarball: 25 new model-tools integration checks, 25 animation regressions and 96 existing site regressions pass. New coverage includes locked/nonuniform resize, invalid input recovery, mm/inch separation, copy animation isolation, source references, shared geometry/GPU cleanup, camera presets, bookmark validation/merge, static and animated VSB/VSJ round trips, reset baselines, explicit 3MF/CAD units, and malformed-scene rollback. Surface area and enclosed volume use known closed/open fixtures; source-unit corrections also survive untransformed mesh export.
697
-
698
- Manual desktop checks cover size inputs, keyboard Apply and on-demand measurements. Narrow widths are viewport emulation, not physical phone tests. No physical touch device, Safari/Firefox or broad large-CAD stress testing is claimed. The bounded detailed mesh checker may return an unavailable/inconclusive volume; source coordinates without units remain assumed mm until corrected.
699
-
645
+
646
+ ## Scene saving — 2026-10-08
647
+
648
+ Release 20261008-625337233d51 exposes VSB/VSJ whole-scene saving in the preview.
649
+ The five regular mesh formats save only the selected model, per the owner's
650
+ clarification. New export_scene/download_scene Promise APIs use get_vsj manifests
651
+ and the existing VSB/STL archive layout, with worker-based VSB encoding,
652
+ cancellation, progress, memory admission and output limits. Legacy scene getters
653
+ and download methods retain their contracts.
654
+
655
+ 96 Node tests, strict types and all 14 legacy integrity hashes pass. Edge
656
+ 154.0.4258.62 passed 26 scene checks locally and live, including downloaded VSB
657
+ round trips, VSJ round trips with explicitly supplied referenced fixture files,
658
+ scene settings, source names, cancellation, memory/output/count limits and
659
+ callback errors. 42 mesh/PNG/UI regression checks passed locally and live;
660
+ 24 app lifecycle checks include cancellation of VSB workers on clear/remove/
661
+ dispose. Same-origin GET-only network evidence shows no export uploads. Narrow
662
+ and touch checks use emulation, not physical devices. Site scene reopening is
663
+ not implemented; round trips explicitly use the plugin's public scene loaders.
664
+ Evidence: sibling website results/scene-save-local, scene-save-mesh-regression,
665
+ scene-save-lifecycle and deploy-20261008-625337233d51. All 26 public hashes match.
666
+
667
+ ## Scene opening — 2026-10-08
668
+
669
+ Preview release `20261008-2bc0de3fc7ab` opens VSB/VSJ through the plugin-owned file,
670
+ drop and URL flows. The new `import_scene` API validates manifests/archives, stages
671
+ models until success, remaps IDs, resolves local companions or relayed public URL
672
+ references, and restores scene settings and editable model placement. Errors and
673
+ cancellation preserve the existing scene. Legacy scene loaders are unchanged.
674
+
675
+ 100 Node tests, strict types and all 14 legacy integrity hashes pass. Desktop
676
+ headless Edge 154.0.4258.62 passed 25 local and 27 live scene-opening checks,
677
+ including saved and legacy VSB files, local VSJ companions, editing/reset/re-saving,
678
+ missing files, malformed second-model rollback, cancellation during reading and
679
+ between models, recovery, URL routing and redirected VSJ base directories.
680
+ Live checks include real public VSJ/STL and VSB downloads through the deployed
681
+ Go relay; other remote fixtures are explicitly intercepted. Captured browser
682
+ traffic remains same-origin; local scene files and companions are not uploaded.
683
+ 42 mesh/PNG/save, 24 lifecycle and 15 URL-drop regression checks pass locally.
684
+ Narrow layout is emulated; physical mobile hardware, Safari and Firefox remain
685
+ unverified. These fixture tests do not establish large-scene peak memory or speed.
686
+
687
+ The relay's 12 top-level Go tests pass, including both scene formats and final
688
+ redirect-base metadata without query secrets. All 27 public asset hashes match.
689
+ Nginx and relay service configuration hashes remain unchanged. Evidence is in the
690
+ sibling website's `results/scene-open-local`, `scene-open-save-regression`,
691
+ `scene-open-lifecycle`, `scene-open-url-regression` and
692
+ `deploy-20261008-2bc0de3fc7ab/live-open`. No npm publication or GitHub push.
693
+
694
+ ## Print checks — 2026-10-17
695
+
696
+ 112 Node tests, strict TypeScript and 14 legacy integrity hashes pass. The new
697
+ fixtures cover open meshes, duplicates, degeneracy, winding, vertex-only contacts,
698
+ disconnected solids, nested cavities, intersecting shells, coplanar overlap,
699
+ near-coplanar neighbors, small gaps, large translations, nonuniform scale, units,
700
+ FDM estimates, time limits, memory rejection and bounded diagnostic samples.
701
+ A 100,000-triangle curved fixture exposed a false coplanar-neighbor intersection;
702
+ the shared-edge predicate was corrected and the case retained as a regression.
703
+
704
+ Desktop headless Edge 155.0.4283.45 passes 27 print integration checks locally:
705
+ lazy loading, basic/detailed coverage, cache isolation, native highlights,
706
+ unchanged geometry/colors/PNG, stale reports, 390px layout, keyboard closing/focus,
707
+ selected/all scope, cancellation/recovery, callback errors, memory accounting,
708
+ removal/disposal, optional host controls and touch-emulated interaction. Additional
709
+ regressions pass: 42 save/PNG, 25 scene-opening and 24 app-lifecycle checks. No
710
+ physical mobile devices, Firefox or Safari were tested. Browser traffic captured
711
+ by the print runner is same-origin GET; no analysis uploads occur.
712
+
713
+ The browser's 100,000-triangle closed torus completed detailed checks in about
714
+ 4.6 seconds with 279 animation frames and a maximum observed frame gap of 16.8 ms
715
+ in the initial recorded run. Results vary by run/device. The Node benchmark
716
+ `scripts/check-print-performance.mjs` measured about 0.6 s for 10,240 triangles
717
+ and 5.4 s for 100,000 triangles. Sampled JS heap reached about 164 MB on the larger
718
+ run; this is not a measurement of total/peak browser or GPU memory. Memory/time
719
+ limits deliberately reject or mark incomplete larger/ambiguous workloads.
720
+
721
+ Evidence: plugin `test-results/print-node.txt`, `print-performance.json`; sibling
722
+ website `results/print-local`, `print-save-regression`, `print-scene-regression`
723
+ and `print-lifecycle`. Reproduce browser checks with `site/qa/run-print-browser.mjs`.
724
+
725
+ Preview release `20261017-b0d9d98b838b` also passed all 27 print checks over
726
+ public HTTPS and all 29 public file hashes. Live evidence is in the sibling
727
+ website's `results/deploy-20261017-b0d9d98b838b/live-print`. The relay binary and
728
+ service/Nginx configuration hashes are unchanged; no npm publication or GitHub push.
729
+
730
+ The persistent-panel follow-up release `20261017-5b21747c4c8f` passes 39 browser
731
+ checks locally and over public HTTPS. Added coverage includes canvas focus,
732
+ appearance controls, other dialogs, repeat launch, narrow-screen toolbar access,
733
+ selection changes, loading/cancellation, adding/removing/clearing models and
734
+ explicit close from an empty scene. The panel remains open throughout unrelated
735
+ activity while stale reports and active jobs are handled safely. All 112 Node
736
+ tests, strict types and 14 legacy hashes pass again. Evidence: sibling website
737
+ `results/print-persistent/` and `results/deploy-20261017-5b21747c4c8f/`.
738
+
739
+ ## 2026-11-07 — rc.6 model tools
740
+
741
+ 146 unit tests pass, as do strict browser/Node TypeScript checks and the 37-file legacy hash guard. Actual Windows Chrome 156 runs against the site built from the candidate npm tarball: 25 new model-tools integration checks, 25 animation regressions and 96 existing site regressions pass. New coverage includes locked/nonuniform resize, invalid input recovery, mm/inch separation, copy animation isolation, source references, shared geometry/GPU cleanup, camera presets, bookmark validation/merge, static and animated VSB/VSJ round trips, reset baselines, explicit 3MF/CAD units, and malformed-scene rollback. Surface area and enclosed volume use known closed/open fixtures; source-unit corrections also survive untransformed mesh export.
742
+
743
+ Manual desktop checks cover size inputs, keyboard Apply and on-demand measurements. Narrow widths are viewport emulation, not physical phone tests. No physical touch device, Safari/Firefox or broad large-CAD stress testing is claimed. The bounded detailed mesh checker may return an unavailable/inconclusive volume; source coordinates without units remain assumed mm until corrected.
744
+
700
745
  Website evidence is retained outside its public build in `Viewstl/results/rc6/`; local-only reproducible browser harnesses are `site/qa/model-tools.html`, `animation.html` and `index.html`. Generated assets and the whole npm distribution are packaged together.