You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This RFC builds on #423 and sets out the core architecture for dcmjs 1.0. Please comment on the principles and the open questions below.
Decisions so far
A hard break from the 0.x API is acceptable. dcmjs has never left 0.x.
0.x stays maintained on a maintenance branch for OHIF/Cornerstone during the transition. Radical Imaging maintainers have offered to look after it.
TypeScript.
Standalone repositories that combine freely, not a monorepo. Each package should be reusable on its own and combinable in more than one way.
The core architecture comes first. Domain packages (volume reconstruction, pixel codecs, de-identification, SEG/SR, validation, indexing) follow once the core interfaces are stable.
AI-assisted implementation is welcome, within small, human-reviewed PRs (see "Process" below).
Principles
One shared data model. Packages exchange a typed DICOM JSON Model (PS3.18 Annex F) and a single event-stream interface. No package imports another package's internals. For example, a volume-reconstruction package should work the same on datasets parsed from Part 10 files and on metadata fetched with dicomweb-client.
Minimal dependencies. Most packages should depend only on the generated dictionary/types package, not on the parser.
One parser engine. Today there are two readers (DicomMessage._read and AsyncDicomReader); 1.0 has one event-based parser with synchronous and asynchronous drivers, and one writer.
Proposed scope of dcmjs core 1.0
Part 10 read and write for all VRs and all non-compressed transfer syntaxes, including big endian and deflate (both read and write)
Streaming: bounded memory, cancellation, untilTag/stop conditions that report byte offsets, errors propagated instead of hanging, streaming writes (header followed by bulk or pixel data taken from a Blob or stream)
Byte-preserving writes as an option, alongside normalized writes
Per-call validation modes (strict / warn / ignore) instead of global behavior
SpecificCharacterSet, including multiple values and ISO 2022 code extensions, in sequences as well as at the top level
Private tags preserved, including inside sequence items, with explicit options (this matters for de-identification)
A typed dataset API. The proxies go away, replaced with consistent value accessors (see the Release version 1.0 with API updates #423 proposal: array, first, typed getters, VM-aware singletons)
A logging API scoped to dcmjs
ESM with a package exports map; runs in browsers, Node and Deno
Not in core (separate packages later): volume reconstruction and clinical interpretation (dcmjs-normalizers), pixel frame and codec handling, PS3.15 de-identification, SEG/SR/PM, IOD validation, DICOMDIR, FHIR, and the Cornerstone/vtk.js adapters (already maintained in @cornerstonejs/adapters).
The backpatching writer, deflate-on-write, the ISO 2022 decoder, many targeted bug fixes, regression suites built from issues, and the event-stream design (to be discussed here, not merged as-is)
A pinned test corpus: dcmjs-org/data plus public sets such as pydicom-data, GDCM's malformed files, NEMA WG-04 and dclunie's charset samples, each recorded with hash, license and provenance
Automatic comparison against reference outputs (e.g. DCMTK dcm2json, pydicom)
Parity tests across synchronous, asynchronous and streaming reads, plus round-trip tests
Fast PR CI; the full matrix runs nightly
Process
Settle interfaces here before implementing them
Small PRs, one topic each, each with tests. AI-assisted PRs must disclose it, and every PR needs human review.
npm naming for the new packagesDecided: new packages are published as @dcmjs-org/<name> on both npm and JSR, matching the GitHub organization and repository paths (e.g. dcmjs-org/dcmjs-normalizers → @dcmjs-org/normalizers). The core package stays unscoped as dcmjs.
In-memory model: DICOM JSON Model with typed accessors as the primary form, with "naturalized" (keyword-keyed) objects as a view? Or the reverse?
Event-stream vocabulary: which events, how sequences and items are delimited, how bulk data is referenced (inline, BulkDataURI, lazy handles), how backpressure works.
Bulk data representation in the data model.
Runtime targets and minimum versions.
Timeline and naming for the 1.0 beta, and how long 0.x maintenance continues.
This RFC builds on #423 and sets out the core architecture for dcmjs 1.0. Please comment on the principles and the open questions below.
Decisions so far
Principles
dicomweb-client.dicom-companion(Create dcmjs-org/dicom-companion: a language-neutral guide to DICOM special cases and gotchas #514) and backed by test data.DicomMessage._readandAsyncDicomReader); 1.0 has one event-based parser with synchronous and asynchronous drivers, and one writer.Proposed scope of
dcmjscore 1.0untilTag/stop conditions that report byte offsets, errors propagated instead of hanging, streaming writes (header followed by bulk or pixel data taken from a Blob or stream)array,first, typed getters, VM-aware singletons)exportsmap; runs in browsers, Node and DenoNot in core (separate packages later): volume reconstruction and clinical interpretation (
dcmjs-normalizers), pixel frame and codec handling, PS3.15 de-identification, SEG/SR/PM, IOD validation, DICOMDIR, FHIR, and the Cornerstone/vtk.js adapters (already maintained in@cornerstonejs/adapters).Existing work to reconcile
Testing and validation
dcmjs-org/dataplus public sets such as pydicom-data, GDCM's malformed files, NEMA WG-04 and dclunie's charset samples, each recorded with hash, license and provenancedcm2json, pydicom)Process
dcmjs-template(Set up dcmjs-template repo and a dcmjs-dictionary package generated from the DICOM standard DocBook #515)Open questions
npm naming for the new packagesDecided: new packages are published as@dcmjs-org/<name>on both npm and JSR, matching the GitHub organization and repository paths (e.g.dcmjs-org/dcmjs-normalizers→@dcmjs-org/normalizers). The core package stays unscoped asdcmjs.Related