Skip to content

Set up dcmjs-template repo and a dcmjs-dictionary package generated from the DICOM standard DocBook #515

Description

@pieper

Context

dcmjs 1.0 is planned as a set of standalone TypeScript repositories that can be combined, instead of one large package or a monorepo (see the 1.0 architecture RFC). Two pieces are needed first:

  1. A template repository so every dcmjs-org package shares the same tooling, without the coupling a monorepo would bring.
  2. A dictionary package generated from the DICOM standard, which everything else depends on.

Part 1: dcmjs-org/dcmjs-template

  • TypeScript (strict), ESM, a package.json exports map with subpath exports, .d.ts output
  • Runs in browsers, Node (22/24) and Deno; no Node-only APIs in library code unless isolated
  • Test runner (vitest), lint and format, and a TypeDoc API docs build
  • CI: test on Node 22 and 24, build, lint, audit, docs; semantic-release with npm provenance; dependabot config
  • Publish as @dcmjs-org/<name> to npm (publishConfig.access: public, npm trusted publishing from Actions) and to JSR (jsr.json, package linked to its GitHub repo, npx jsr publish using OIDC with id-token: write)
  • A test-data harness that downloads pinned fixtures (such as dcmjs-org/data releases) and checks them by sha256
  • CONTRIBUTING, including a policy for AI-assisted contributions:
    • disclose AI involvement
    • one topic per PR, with a size limit on hand-written code
    • generated code must be reproducible and is never edited by hand
    • no agent process files committed
    • a human reviews every PR

Part 2: dcmjs-org/dcmjs-dictionary

A data- and types-only package with no runtime dependencies, generated from the NEMA DocBook source.

Inputs

  • A pinned DICOM edition (e.g. 2026c), with the downloaded DocBook XML checksummed and cached
  • A generator that is deterministic: the same edition always produces byte-identical output

Outputs (first milestone)

  • The PS3.6 data dictionary: tag, keyword, name, VR (or allowed VRs), VM, and retired status as a separate flag, not a RETIRED_ keyword prefix. Includes repeating groups (50xx, 60xx).
  • PS3.7 command fields
  • The PS3.6 UID registry, with transfer syntax properties: explicit/implicit, endianness, encapsulated, deflated, lossy
  • The PS3.5 VR table: max length, padding character, 16- vs 32-bit length, whether SpecificCharacterSet applies, binary vs. string
  • SpecificCharacterSet defined terms and their encodings
  • TypeScript types: keyword and tag literal types, and per-keyword value types derived from VR and VM
  • A compact, lazily loaded data representation so the bundle stays small (building on the packed dictionary from feat: Add a packed/fast loading dictionary.js  #470)

Later milestones

  • PS3.16 context groups (CIDs)
  • The PS3.15 Table E.1-1 de-identification profile
  • PS3.3 IOD → module → attribute tables, with Type 1/2/3 and conditions
  • A private dictionary (from the DCMTK/GDCM dictionaries, checking licenses)

Checks

  • Cross-check the output against pydicom's generated dictionary and the innolitics/dicom-standard JSON in tests; flag differences for review instead of failing silently
  • A scheduled workflow that notices a new DICOM edition and opens a PR with the regenerated output and a readable diff

Why

A shared, generated package fixes this for all of them.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions