Skip to content

feat(scientific): add browser-native scientific application platform - #20

Open
a-r-d wants to merge 27 commits into
mainfrom
scientific-analysis
Open

feat(scientific): add browser-native scientific application platform#20
a-r-d wants to merge 27 commits into
mainfrom
scientific-analysis

Conversation

@a-r-d

@a-r-d a-r-d commented Aug 12, 2026

Copy link
Copy Markdown
Owner

This PR adds the alpha foundation for building browser and Node scientific-imaging applications on PureJsImage without replacing the existing codec pipeline.

The target use case is local or HTTP Range-backed analysis of large scientific files—especially AFM, detector, diffraction, hyperspectral, and volumetric data—where loading the complete source or converting it before first display is undesirable.

This is not an attempt to reposition PureJsImage as “ImageJ in the browser.” The ordinary codec-first workflow remains useful and unchanged:

await image.resize({ width: 1200 }).jpeg({ quality: 82 }).toUint8Array()

Architecture

```mermaid
flowchart TB
App["Applications, UI, scripts, plugins, future agents"]

App --> Core["Ordinary immutable image pipeline"]
Core --> Codecs["Image codecs"]
Codecs --> Source["ImageSource and platform adapters"]

App --> Analysis["Analysis controller, workspace, projects, ROIs, results and tile runtime"]
Analysis --> Operations["JSON-safe operation and value-type descriptors"]
Analysis --> Tiles["Native-endian NumericTile computation"]
Operations --> Providers["Explicit executable providers"]
Providers --> Tiles
Tiles --> Dataset["ScientificDataset descriptors and RasterBlock reads"]
Dataset --> Readers["Explicit scientific readers"]
Readers --> Source

Extensions["Trusted extension bundles"] -. explicit local composition .-> Readers
Extensions -. explicit local composition .-> Operations
Extensions -. explicit local composition .-> Providers
Entrypoint | Status | Purpose
-- | -- | --
purejsimage and purejsimage/browser | Existing stable path | Immutable codec, transform, and encode pipeline
purejsimage/scientific | Alpha | Labeled-axis datasets, readers, documents, identity, RasterBlocks and NumericTiles
purejsimage/scientific/browser | Alpha | Browser File and companion-resource contexts
purejsimage/scientific/node | Alpha | Node path and constrained companion-resource adapters
purejsimage/operations | Alpha | JSON-safe descriptors, schemas, registries and provider contracts
purejsimage/analysis | Alpha | ROIs, results, graphs, projects, commands, planning, execution and tile runtime
purejsimage/extensions | Experimental | Explicit trusted in-process extension composition

</div></div></div><h2>Tests and benchmarks</h2><p>Primary verification commands:</p><pre dir="ltr"><code>npm run check
npm run package:types
npm run platform:example:check
npm run browser:check
npm run docs:build
npm run lint
npm run format:check</code></pre><p>Relevant benchmarks:</p><pre dir="ltr"><code>npm run bench:analysis:tiles
npm run bench:analysis:gaussian-blur
npm run bench:application-platform</code></pre><p>The application benchmark validates output before reporting timing and records document detection, first tile, cache behavior, ROI statistics, line profiles, thresholding, Gaussian blur and provider planning.</p><p>Current branch results:</p><ul><li>package consumer, browser dependency graph, documentation build, typecheck, lint and formatting pass;</li><li>the compiled public-only application example executes successfully;</li><li>the standard suite reaches 95 passing files and 1,198 passing tests;</li><li>the hostile-source suite passes 95 files and 1,176 tests when the known AVIF oracle file is excluded;</li><li>four new application entrypoints have recorded minified baselines and enforced ceilings with approximately 30% headroom.</li></ul><h2>Known limitations and post-merge issues</h2><ul><li><div></div>Reconcile the three environment-specific expanded 12-bit AVIF Sharp-oracle hashes so the complete <code dir="ltr">npm run check</code> command, including its hostile-source phase, is green before release.</li><li><div></div>Converge built-in dataset operations and <code dir="ltr">DerivedTileSource</code> on one explicit tile-kernel acceleration path.</li><li><div></div>Add explicit operation-level pyramid resolution selection and per-level physical coordinate transforms.</li><li><div></div>Add explicitly registered WASM analysis providers.</li><li><div></div>Define WebGPU memory, transfer, readback and GPU-resident ownership contracts before adding WebGPU providers.</li><li><div></div>Design a permissioned Worker or iframe RPC boundary before accepting untrusted extensions.</li><li><div></div>Add bigint- or decimal-aware results, parameters and no-data metadata for exact uint64 analysis above <code dir="ltr">2^53 - 1</code>.</li><li><div></div>Expand materials support only alongside real readers, workflows and fixtures; do not claim mature SEM/TEM, EDS, FFT or particle/grain analysis prematurely.</li><li><div></div>Perform a fresh release-candidate audit on the final release commit. This PR does not change a version, create a tag or publish a release.</li></ul><p>Further documentation:</p><ul><li>[Application platform](docs/application-platform.md)</li><li>[Architecture](docs/architecture/application-platform.md)</li><li>[Scientific reader registry](docs/scientific-reader-registry.md)</li><li>[Built-in operations](docs/built-in-analysis-operations.md)</li><li>[Lifecycle and ownership](docs/contracts/lifecycle-and-ownership.md)</li><li>[Tile memory model](docs/contracts/tile-memory-model.md)</li><li>[Reproducibility](docs/contracts/reproducibility.md)</li><li><a href="https://purejsimage.com/scientific/platform/"><span><span>Scientific application platform website page</span></span></a></li></ul><hr></body></html>Paste everything between the horizontal rules as the PR body.

---

## Motivation

This PR adds the alpha foundation for building browser and Node scientific-imaging applications on PureJsImage without replacing the existing codec pipeline.

The target use case is local or HTTP Range-backed analysis of large scientific files—especially AFM, detector, diffraction, hyperspectral, and volumetric data—where loading the complete source or converting it before first display is undesirable.

This is not an attempt to reposition PureJsImage as “ImageJ in the browser.” The ordinary codec-first workflow remains useful and unchanged:

```ts
await image.resize({ width: 1200 }).jpeg({ quality: 82 }).toUint8Array()

Architecture

flowchart TB
    App["Applications, UI, scripts, plugins, future agents"]

    App --> Core["Ordinary immutable image pipeline"]
    Core --> Codecs["Image codecs"]
    Codecs --> Source["ImageSource and platform adapters"]

    App --> Analysis["Analysis controller, workspace, projects, ROIs, results and tile runtime"]
    Analysis --> Operations["JSON-safe operation and value-type descriptors"]
    Analysis --> Tiles["Native-endian NumericTile computation"]
    Operations --> Providers["Explicit executable providers"]
    Providers --> Tiles
    Tiles --> Dataset["ScientificDataset descriptors and RasterBlock reads"]
    Dataset --> Readers["Explicit scientific readers"]
    Readers --> Source

    Extensions["Trusted extension bundles"] -. explicit local composition .-> Readers
    Extensions -. explicit local composition .-> Operations
    Extensions -. explicit local composition .-> Providers

Dependency direction is strictly downward. Readers and codecs do not import graph, application, ROI, workspace, or extension code. Registries are application-owned; imports do not create global state or automatically select providers.

Public entrypoints

Entrypoint Status Purpose
purejsimage and purejsimage/browser Existing stable path Immutable codec, transform, and encode pipeline
purejsimage/scientific Alpha Labeled-axis datasets, readers, documents, identity, RasterBlocks and NumericTiles
purejsimage/scientific/browser Alpha Browser File and companion-resource contexts
purejsimage/scientific/node Alpha Node path and constrained companion-resource adapters
purejsimage/operations Alpha JSON-safe descriptors, schemas, registries and provider contracts
purejsimage/analysis Alpha ROIs, results, graphs, projects, commands, planning, execution and tile runtime
purejsimage/extensions Experimental Explicit trusted in-process extension composition

None of the application entries introduce runtime dependencies or pull Node built-ins into browser builds.

Deliberate breaking changes

These contracts were not previously released, so this PR deliberately cleans them up before publication:

  • ScientificDataset V2 is now the sole public scientific dataset model.
  • The unpublished fixed XYZCT interface is no longer public. Reads select arbitrary displayAxes and provide explicit fixedIndices.
  • Reader-opened datasets carry reader, dataset and resource identities.
  • Every workspace mutation requires expectedRevision; command batches apply atomically.
  • Execution outputs use a non-mutable lookup/iteration view rather than exposing a mutable Map.
  • Provider outputs must declare shared ownershipIdentity values when wrappers alias opaque storage.
  • Extension contributions must remain within the extension descriptor’s namespace:
    • readers use <extension-id>/...;
    • value types, operations, providers and migrations use <extension-id>....;
    • operation migrations may only target operations in the same namespace.
  • Scientific probing now requires exact admitted read lengths and shares bounded companion-resolution budgets.
  • Tile accounting charges the complete retained backing allocation, not only the visible typed-array view.

The existing root package, codec entrypoints and ordinary image behavior are preserved.

Scientific reader matrix

Readers are registered explicitly with createScientificLibrary().

Reader Resource model Current dataset scope
GSF Single file Gwyddion float32 XY surface
ENVI Header plus binary companion Labeled hyperspectral/general raster cubes and classifications
FITS Single document containing HDUs 1D, 2D and 3D image HDUs with labeled axes
MRC/CCP4 Single file Volumetric scientific raster data
CBF/imgCIF Single file Detector and diffraction frames
OME-TIFF Single TIFF document OME images exposed through the labeled-axis dataset contract

Filename extensions and media types are confidence hints only. Detection is byte-based, bounded, cancellable and protected by shared read and companion-resolution limits.

Local files, memory sources and HTTP Range-backed sources meet at the same portable ImageSource boundary.

Built-in operation matrix

Every built-in operation currently has semantic version 1.

Operation Output Reproducibility/numeric policy
Crop Lazy dataset Bit-exact; preserves samples, components, units and calibration
Resample Lazy selected-plane dataset Nearest or floating-point bilinear with explicit invalid policy
Arbitrary-axis slice Lazy dataset Bit-exact selection of any two labeled axes
Projection Lazy dataset Min, max or mean with explicit invalid/no-data policy
Threshold Lazy uint8 dataset Bit-exact 0/1 output
Gaussian blur Lazy Float32 dataset Bounded separable halo processing with declared tolerance
Statistics Result collection Counts, extrema, Welford mean/deviation and bounded percentiles
Histogram Histogram result Explicit one-pass range or cache-aware two-pass automatic range
Line profile Profile result Tile-grouped nearest/bilinear sampling with pixel or physical distance

Dataset transforms remain lazy. Descriptor inference does not read pixels, and generic operations do not materialize a full frame.

Lifecycle and memory model

Cleanup is explicit and garbage collection is not a substitute:

  1. Release every NumericTile.
  2. Release the AnalysisExecutionResult.
  3. Dispose the prepared analysis plan.
  4. Dispose the TileRuntime.
  5. Close the ScientificDocument.

Execution results retain lazy output datasets until released. Plan disposal waits for active execution-result leases, and runtime disposal permanently closes new acquisition paths before waiting for active work to drain.

The tile runtime separately accounts for:

  • cached bytes;
  • leased bytes;
  • source and derived output bytes;
  • in-flight peak working bytes;
  • operation scratch and halo storage;
  • retained auxiliary allocations.

Hard limits include maxTileBytes, maxCacheBytes, maxInFlightBytes, maxLeasedBytes, maxOperationWorkingBytes, maxTotalManagedBytes, queue size and concurrency.

Tile retention uses the complete tile.data.buffer.byteLength. Source/provider estimates are checked before allocation and validated against returned storage. These are managed-memory guarantees, not process RSS guarantees; allocator fragmentation, engine-retained pages and undeclared native/GPU memory remain outside the portable budget.

All reads, planning and execution support AbortSignal. Shared in-flight reads survive cancellation by one consumer while other leases remain.

Reproducibility model

Reproducibility is layered:

Record Meaning
graphHash Canonical identity of the reusable versioned recipe
bindingHash Identity of semantic external bindings
invocationHash Combined graph and binding identity
Execution provenance Invocation plus provider, implementation, library build, warnings and timing

Every operation is versioned. Semantic changes require a new operation version; implementation-only changes require a new implementation version or build fingerprint.

Graph migrations are explicit registered transforms. There is no silent semantic rewrite.

Source identity uses a ladder:

  • strong content hashes or strong remote validators;
  • weak local/remote metadata identities;
  • session-only identities where durable evidence is unavailable.

Hashing a multi-gigabyte source is therefore not required before first display. Weak identities remain explicitly weak and cannot justify durable content-equivalence claims.

Operations declare one of four reproducibility classes:

  • bit-exact;
  • backend-stable;
  • tolerance-based;
  • provider-pinned.

Provider selection records the chosen provider and implementation version. It requires exact semantic support and compares setup, transfer, compute, readback and memory cost; it does not use a hardcoded WebGPU-over-WASM-over-JavaScript ranking.

Security and trust boundary

The extension system is explicit and local:

  • no package-global mutable registry;
  • no hidden auto-registration;
  • no package scanning;
  • no data-driven dynamic imports;
  • no eval or Function construction;
  • no AI-only privileged API.

Trusted extension code executes with the authority of the host application. Namespace ownership prevents ecosystem ID collisions, but it is not a security sandbox.

Untrusted extensions require a future permissioned Worker or iframe RPC host with quotas, cancellation enforcement, structured-clone rules, transfer accounting and crash isolation.

The same descriptors, graph schema, validation, commands, planning and execution APIs are intended to drive UI, scripts, trusted plugins and future agents.

Explicit non-goals

This PR does not add:

  • a complete ImageJ-style scientific ecosystem;
  • mature segmentation, registration or morphology;
  • FFT or frequency-domain analysis;
  • particle or grain analysis;
  • DM3/DM4 or complete SEM/TEM workflows;
  • EDS overlay workflows;
  • 3D mesh editing or 3D ROI geometry;
  • mutable painting or brush masks;
  • collaboration, authentication or cloud workspace services;
  • automatically selected WASM or WebGPU providers;
  • a sandbox for untrusted extensions;
  • exact number-backed quantitative uint64 analysis above 2^53 - 1;
  • implicit workers or package-owned application state.

Recommended review order

The branch is based on origin/main at e708717.

Order Commit Review focus
1 8955459 Application-platform architecture and dependency boundaries
2 c1ece06 Labeled-axis ScientificDataset V2
3 86c5e34 Scientific reader/document registry
4 a5cad14 Native-endian NumericTile conversion
5 fae64ed Operation descriptors, providers and extensions
6 624857e Bounded quantitative result contracts
7 85f2adc Graphs, identity, planning, execution and provenance
8 40a4e87 ROI geometry and sampling
9 e05d5d5 Lazy tile scheduler and cache
10 a026b5e Initial built-in scientific operations
11 3c6d450 Package/application hardening and external-consumer integration
12 6171550 Nested tile dependencies and initial runtime feedback
777baa7 Merge of origin/main; codec synchronization rather than platform review
13 bd264c6 Memory, ownership, graph and provider contract feedback
14 c1fc5ca Results, line profiles, commands and provider feedback
15 e2e67fe Linear-time namespaced-ID validation and CodeQL fixes
16 673628c Contract-level runtime, identity and package hardening
17 b86ed95 Normative contracts, migration and release documentation
18 261a970 Single public scientific dataset model and website migration
19 93a3c69 Tile backing-memory, disposal, revisions and reader probe hardening
20 a354187 Website platform page, compiled example, extension namespaces and size gates

Tests and benchmarks

Primary verification commands:

npm run check
npm run package:types
npm run platform:example:check
npm run browser:check
npm run docs:build
npm run lint
npm run format:check

Relevant benchmarks:

npm run bench:analysis:tiles
npm run bench:analysis:gaussian-blur
npm run bench:application-platform

The application benchmark validates output before reporting timing and records document detection, first tile, cache behavior, ROI statistics, line profiles, thresholding, Gaussian blur and provider planning.

Current branch results:

  • package consumer, browser dependency graph, documentation build, typecheck, lint and formatting pass;
  • the compiled public-only application example executes successfully;
  • the standard suite reaches 95 passing files and 1,198 passing tests;
  • the hostile-source suite passes 95 files and 1,176 tests when the known AVIF oracle file is excluded;
  • four new application entrypoints have recorded minified baselines and enforced ceilings with approximately 30% headroom.

Known limitations and post-merge issues

  • Reconcile the three environment-specific expanded 12-bit AVIF Sharp-oracle hashes so the complete npm run check command, including its hostile-source phase, is green before release.
  • Converge built-in dataset operations and DerivedTileSource on one explicit tile-kernel acceleration path.
  • Add explicit operation-level pyramid resolution selection and per-level physical coordinate transforms.
  • Add explicitly registered WASM analysis providers.
  • Define WebGPU memory, transfer, readback and GPU-resident ownership contracts before adding WebGPU providers.
  • Design a permissioned Worker or iframe RPC boundary before accepting untrusted extensions.
  • Add bigint- or decimal-aware results, parameters and no-data metadata for exact uint64 analysis above 2^53 - 1.
  • Expand materials support only alongside real readers, workflows and fixtures; do not claim mature SEM/TEM, EDS, FFT or particle/grain analysis prematurely.
  • Perform a fresh release-candidate audit on the final release commit. This PR does not change a version, create a tag or publish a release.

Further documentation:


mermaid doc rendered:
Screenshot 2026-08-13 at 9 22 51 AM

Comment thread src/extensions/index.ts Fixed
Comment thread src/operations/descriptor.ts Fixed
@a-r-d a-r-d changed the title Scientific analysis feat(scientific): add browser-native scientific application platform Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants