Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,32 @@ updates:
# pako 3 changes Inflate err/msg semantics used by the DICOM deflated-study
# path and needs a licence ledger refresh, so its majors stay deferred.

# The cold consumer is outside the workspace. Framework and compiler peers
# must move together rather than producing individually incompatible PRs.
- package-ecosystem: npm
directory: /apps/component-demo/test/angular-pptx
schedule:
interval: weekly
day: monday
time: '03:10'
timezone: Asia/Shanghai
open-pull-requests-limit: 3
groups:
angular-version-cohort:
applies-to: version-updates
patterns:
- '@angular/*'
angular-security-cohort:
applies-to: security-updates
patterns:
- '@angular/*'
commit-message:
prefix: chore(deps)
ignore:
- dependency-name: '@angular/*'
update-types:
- version-update:semver-major

- package-ecosystem: github-actions
directory: /
schedule:
Expand Down
49 changes: 49 additions & 0 deletions .github/scripts/dependency-cohort.test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import { test } from 'node:test'
const read = (path) => readFileSync(new URL(`../../${path}`, import.meta.url), 'utf8')
function angularCohort(manifest) {
const dependencies = { ...manifest.dependencies, ...manifest.devDependencies }
for (const name of [
'common',
'compiler',
'core',
'platform-browser',
'build',
'cli',
'compiler-cli'
])
assert.ok(dependencies[`@angular/${name}`], `Missing Angular cohort member: ${name}`)
const versions = Object.entries(dependencies)
.filter(([name]) => name.startsWith('@angular/'))
.map(([, version]) => version)
assert.equal(new Set(versions).size, 1, 'Angular framework and tooling must use one exact cohort')
assert.match(versions[0], /^\d+\.\d+\.\d+$/, 'Angular fixture must pin stable exact versions')
}
const fixture = JSON.parse(read('apps/component-demo/test/angular-pptx/package.json'))
test('cold Angular consumer pins a complete aligned cohort', () => angularCohort(fixture))
test('a single-package Angular bump fails before installation', () => {
const changed = structuredClone(fixture)
changed.dependencies['@angular/core'] = '0.0.0'
assert.throws(() => angularCohort(changed), /one exact cohort/)
})
test('thumbnail manifest agrees with workspace Vitest security override', () => {
const thumbnail = JSON.parse(read('packages/thumbnail/package.json'))
const override = read('pnpm-workspace.yaml').match(/^ vitest: (\S+)$/m)?.[1]
assert.ok(override)
assert.equal(thumbnail.devDependencies.vitest, override)
})
test('Dependabot groups version and security Angular updates in the nested fixture', () => {
const entry = read('.github/dependabot.yml')
.split(' - package-ecosystem: npm')
.find((part) => part.includes('directory: /apps/component-demo/test/angular-pptx'))
assert.ok(entry)
assert.match(
entry,
/angular-version-cohort:\s+applies-to: version-updates\s+patterns:\s+- '@angular\/\*'/
)
assert.match(
entry,
/angular-security-cohort:\s+applies-to: security-updates\s+patterns:\s+- '@angular\/\*'/
)
})
14 changes: 7 additions & 7 deletions apps/component-demo/test/angular-pptx/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
"build": "ng build"
},
"dependencies": {
"@angular/common": "22.0.7",
"@angular/compiler": "22.0.7",
"@angular/core": "22.0.7",
"@angular/platform-browser": "22.0.7",
"@angular/common": "22.1.6",
"@angular/compiler": "22.1.6",
"@angular/core": "22.1.6",
"@angular/platform-browser": "22.1.6",
"@file-viewer/web": "3.0.3",
"@file-viewer/preset-office": "3.0.3",
"file-viewer-copy-assets": "3.0.3",
"rxjs": "7.8.2",
"tslib": "2.8.1"
},
"devDependencies": {
"@angular/build": "22.0.7",
"@angular/cli": "22.0.7",
"@angular/compiler-cli": "22.0.7",
"@angular/build": "22.1.6",
"@angular/cli": "22.1.6",
"@angular/compiler-cli": "22.1.6",
"typescript": "6.0.3"
}
}
70 changes: 70 additions & 0 deletions docs/maintenance/pr-issue-review-20260912.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# PR and issue review — 2026-09-12

Scope: all six open PRs and seven open issues in `flyfish-dev/file-viewer`, plus
related DOCX/CAD/spreadsheet upstreams. Source maintenance only: no npm release,
version bump, release tag or automatic issue closure.

## PR disposition

| PR | Decision |
| --- | --- |
| #276 | Merged as `db73a732e4978f2e4d0d573cd0ed7333690fe461`. Exact-head Public CI `34625940086`, Security `34625940222` and corrected PR evidence gate `34679546125` passed. No governance rules were weakened. |
| #275 | Incorporate @p4535992's advanced-configuration direction (comment `5638194837`) on #276's stronger owned-Worker foundation. This change adds data-only importer/Fragments settings and a pre-model runtime hook. Do not merge the separate draft capability/assets packages or duplicate runtime. |
| #270 / #271 / #274 | Combine upgrade intent into the complete **Angular 22.1.6** framework/tooling cohort: common, compiler, core, platform-browser, build, CLI and compiler-cli. Registry metadata confirms matching published versions and exact framework peers. Individual 22.1.0/22.1.1 PRs are superseded by this coordinated change. |
| #261 | Synchronize the thumbnail manifest to **Vitest 4.1.11**, already selected by the workspace security override. Real thumbnail tests verify the result; the runtime was not actually on Vitest 3 before this manifest correction. |

Qualification `34679652404` passed real lock generation, frozen installation,
core/thumbnail builds, thumbnail tests, governance and public-release facts. A
clean Angular consumer passed npm installation, peer-tree validation and `ng build`.
The lockfile required no byte change because Vitest was already overridden and the
Angular fixture is outside the workspace. The full consolidated CI additionally
runs packed Angular browser consumers and all existing rendering/framework gates.

Prevent recurrence: group nested `@angular/*` version and security updates;
deterministic tests reject split framework/tooling versions and thumbnail pin drift.
The IFC gate verifies actual Worker settings effects, original IFC4/IFC4.3 geometry,
picking, reverse-order cleanup and cancellation, rather than only checking types.

## Issue follow-up

All seven issue bodies and available comments were re-read. The table distinguishes
source inclusion, publication and original-report acceptance. No missing sample is
silently replaced by a synthetic fixture, and issues stay open pending acceptance.

| Issue | Evidence / next acceptance condition |
| --- | --- |
| #227 — XLS undefined name | Original sensitive XLS remains unavailable in the thread. WPS re-saving is a workaround, not root-cause proof. Require a sanitized failing file or dated private receipt; MiniFAT fixtures alone do not prove this report fixed. |
| #248 — Vue CLI DOCX/XLS | Latest comment supplies an XLS screenshot, not a project/file. Existing cold Vue CLI tests do not prove the reporter's exact integration. Require lockfile, minimal project, original bytes and failing console/Worker requests. |
| #266 — Word/OFD fidelity | Original-sample repairs are in #273/#276 and upstream docxjs#10. Diagonal source is merged, but npm `@file-viewer/docx` was still **0.3.31** at review. Pending upstream publication and downstream dependency/Worker/lock synchronization. |
| #267 — IFC | Optional viewer foundation is merged; this change incorporates the advanced configuration request. Scope is local visualization/inspection, not full BIM authoring or a promise of arbitrary large-model performance. Preserve self-hosted assets and license notices. |
| #268 — PPTX charts/tables | Reporter supplied `default.pptx` in comment `5628266590`; original-file repairs/evidence are in merged #272. Pending delivery of a new File Viewer package and reporter confirmation, not a claim that the public package is already updated. |
| #269 — CAD Chinese text | Thread still lacks original CAD file, font resources and usable environment/version details. Need original DWG/DXF, SHX/TTF mapping and failing font/network requests. Screenshot alone cannot distinguish encoding from missing fonts. |
| #277 — binary inspector | Separately scoped optional read-only feature proposal, not implemented in this release. Acceptance should require virtual hex/ASCII, bounded terminable parsing, allowlisted build-time templates with per-template license review, and explicit routing that cannot steal dedicated renderers. Editing/arbitrary executable templates are out of initial scope. |

Related upstreams: `flyfish-dev/docxjs` had no open PRs/issues; #10 is merged as
`6dbe15e347459f3707116d531fc9064f2d4c2a95`. The live CAD and styled-exceljs upstream
snapshots likewise had no open items.

## Release handoff

After the maintainer publishes the reviewed upstream DOCX version, run:

```sh
pnpm release:prepare-docx <exact-published-version>
pnpm release:verify
git diff --check
```

Review and commit synchronized dependency, runtime/Worker and lockfile metadata.
The actual-installed-engine behavioral gate must pass before File Viewer release.
Do not publish with the old DOCX dependency simply because source CI is green.

## Lifecycle defect caught during integration

The first real-browser advanced-hook qualification (`34680017521`) passed both
original models and actual importer settings, then failed because a pre-model
cancellation left a Worker alive. Upstream `abort(id)` creates a connection for an
unknown model ID. The adapter now calls it only for a registered model; disposal
before model loading must not create a new Worker. Regression coverage includes
late asynchronous runtime hooks, invalid Fragments settings before load, and a
throwing host cleanup without suppressing remaining hook/Worker/WebGL disposal.
58 changes: 58 additions & 0 deletions docs/regressions/issue-267/advanced/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Advanced IFC regression evidence

This directory records the real-browser qualification of PR #278's combined
advanced configuration and lifecycle work. Source fixes are in
`0b84e9d5dec5344b990511558c07013d2e1e98e0`; this evidence note does not change runtime
or dependency bytes. No package was published by these qualifications.

## Qualified scenarios

- Official, checksum-pinned IFC4 and IFC4.3 Building-Architecture samples still
render 13 geometric items and 1,143 triangles in the tested scene.
- Data-only importer settings cross the real Worker boundary: excluding `Name`
changes the actual selected model data rather than merely a configuration mock.
- Fragments settings are applied to the real instance. The pre-model hook runs
before any model is registered; the existing post-model hook is preserved.
- Invalid importer settings fail before file copying/Worker allocation. Unknown
importer and Fragments fields fail explicitly and clean up their resources.
- A late asynchronous runtime hook cleans up once after cancellation. Cleanup
functions execute in reverse registration order, and a throwing cleanup does
not prevent remaining hooks, Workers or WebGL resources from being released.
- Reentrant `unmount()` calls from both an abort listener and a cleanup callback
return the exact same Promise. Once it resolves, zero tracked Workers remain.

## Failure-before-fix evidence

The initial advanced integration run `34680017521` caught an orphan Worker on
pre-model cancellation. Upstream `abort(id)` creates a connection for an unknown
model ID, so the adapter now calls it only for an already registered model. The
corrected integration run `34680261413` passed without weakening the assertions.

The reentrant teardown qualification `34680829005` first ran the new regression
against source `5fbbf5bb575c94fc7c15ce4698ae9f5ebfc46026` and required failure on the
promise-identity assertion. It then assigned the shared disposal Promise before
notifying abort/cleanup callbacks, rebuilt the actual renderer, and passed the
same real-browser assertions plus all preceding advanced/original-model checks.
The corrected source was pushed only after those checks and governance passed.

`report.json` is the resulting browser measurement record. Run IDs identify the
GitHub Actions evidence; the initial failed runs are not counted as passing gates.
The current PR's full CI and Security remain separate required merge gates.

## Reproduce

```sh
pnpm install --frozen-lockfile
pnpm --filter @file-viewer/core build
pnpm --filter @file-viewer/geometry-engine build
pnpm --filter @file-viewer/renderer-3d build
pnpm --filter @file-viewer/renderer-3d verify:ifc
pnpm exec playwright install chromium
node packages/renderers/3d/scripts/download-ifc-fixtures.mjs /tmp/ifc-samples
pnpm --filter @file-viewer/renderer-3d verify:ifc-browser /tmp/ifc-samples
```

Fixture provenance and CC BY 4.0 attribution are in the downloader and
`packages/renderers/3d/IFC.md`. The tests do not claim arbitrary-model fidelity,
full BIM authoring, or performance on every device. Advanced settings remain
upstream-version-coupled application configuration, not executable document data.
Loading