diff --git a/.circleci/config.yml b/.circleci/config.yml index 13ef4756d..51724a800 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -37,7 +37,7 @@ jobs: - checkout - run: name: Install Dependencies - command: pnpm install --no-frozen-lockfile + command: pnpm install --frozen-lockfile # RUN TESTS - run: name: 'JavaScript Test Suite' @@ -78,7 +78,7 @@ jobs: - install_pnpm - run: name: Install Dependencies - command: pnpm install --no-frozen-lockfile + command: pnpm install --frozen-lockfile # Build & Test - run: name: 'Perform the versioning before build' @@ -197,7 +197,7 @@ jobs: at: ~/repo - run: name: Install Dependencies - command: pnpm install --no-frozen-lockfile + command: pnpm install --frozen-lockfile - run: name: Avoid hosts unknown for github command: | diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index e999c8e81..97e82cd17 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -36,13 +36,14 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Install dependencies - # Use --no-frozen-lockfile to match every CircleCI job. The release flow - # (publish-version.mjs) rewrites @ohif/* workspace deps from "workspace:*" - # to the concrete version and commits that bump to master, which leaves - # pnpm-lock.yaml out of sync with the manifests. pnpm-workspace.yaml sets - # frozenLockfile:true, so a master-triggered install must opt out or it - # fails with ERR_PNPM_OUTDATED_LOCKFILE. - run: pnpm install --no-frozen-lockfile + # Internal @ohif/* deps are workspace:* in the committed manifests and the + # lockfile records them as links, so pnpm-lock.yaml stays in sync across + # version bumps and a frozen install passes. Frozen is the right choice + # for a deploy job: it fails fast if a PR ever changed a real dependency + # without committing the lockfile update, instead of silently reconciling. + # (Exact versions appear only in published tarballs, where pnpm publish + # rewrites workspace:* at pack time -- not publish-version.mjs.) + run: pnpm install --frozen-lockfile # Removed Playwright tests and coverage generation steps diff --git a/Dockerfile b/Dockerfile index a6eb01f5e..a8c321b9d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,8 +40,10 @@ ENV PATH=/usr/src/app/node_modules/.bin:$PATH # script file must already be present or install fails with MODULE_NOT_FOUND. COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc preinstall.js ./ COPY --parents ./extensions/*/package.json ./modes/*/package.json ./platform/*/package.json ./ -# Run the install before copying the rest of the files - +# Run the install before copying the rest of the files. +# Keep --no-frozen-lockfile here (unlike CI): .dockerignore excludes +# platform/docs, so the lockfile's docs importer has no manifest in the build +# context and a frozen install would fail. pnpm reconciles (drops docs) instead. RUN pnpm install --no-frozen-lockfile # Copy the local directory COPY --link --exclude=pnpm-lock.yaml --exclude=package.json --exclude=Dockerfile . . diff --git a/extensions/cornerstone-dicom-pmap/package.json b/extensions/cornerstone-dicom-pmap/package.json index 379d84c95..92932b07e 100644 --- a/extensions/cornerstone-dicom-pmap/package.json +++ b/extensions/cornerstone-dicom-pmap/package.json @@ -28,10 +28,10 @@ "start": "pnpm run dev" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/i18n": "workspace:*", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", diff --git a/extensions/cornerstone-dicom-rt/package.json b/extensions/cornerstone-dicom-rt/package.json index a3f5c093d..28cf077b2 100644 --- a/extensions/cornerstone-dicom-rt/package.json +++ b/extensions/cornerstone-dicom-rt/package.json @@ -28,10 +28,10 @@ "start": "pnpm run dev" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/i18n": "workspace:*", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", diff --git a/extensions/cornerstone-dicom-seg/package.json b/extensions/cornerstone-dicom-seg/package.json index 2169ada13..2aab79efa 100644 --- a/extensions/cornerstone-dicom-seg/package.json +++ b/extensions/cornerstone-dicom-seg/package.json @@ -28,10 +28,10 @@ "start": "pnpm run dev" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/i18n": "workspace:*", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", diff --git a/extensions/cornerstone-dicom-sr/package.json b/extensions/cornerstone-dicom-sr/package.json index c2f5925c2..efa7e1376 100644 --- a/extensions/cornerstone-dicom-sr/package.json +++ b/extensions/cornerstone-dicom-sr/package.json @@ -29,9 +29,9 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/cornerstone-dynamic-volume/package.json b/extensions/cornerstone-dynamic-volume/package.json index d23f0d1d6..8c0fd9f34 100644 --- a/extensions/cornerstone-dynamic-volume/package.json +++ b/extensions/cornerstone-dynamic-volume/package.json @@ -32,11 +32,11 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/i18n": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/cornerstone/package.json b/extensions/cornerstone/package.json index e54b5aaca..387763d0d 100644 --- a/extensions/cornerstone/package.json +++ b/extensions/cornerstone/package.json @@ -39,9 +39,9 @@ "@cornerstonejs/codec-openjpeg": "1.3.0", "@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/dicom-image-loader": "5.0.2", - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/default/package.json b/extensions/default/package.json index afdfa074a..9174c96d7 100644 --- a/extensions/default/package.json +++ b/extensions/default/package.json @@ -29,8 +29,8 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/i18n": "workspace:*", "dcmjs": "0.49.4", "dicomweb-client": "0.10.4", "prop-types": "15.8.1", diff --git a/extensions/dicom-microscopy/package.json b/extensions/dicom-microscopy/package.json index 611778c68..44da3e138 100644 --- a/extensions/dicom-microscopy/package.json +++ b/extensions/dicom-microscopy/package.json @@ -25,10 +25,10 @@ "start": "pnpm run dev" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/i18n": "workspace:*", + "@ohif/ui": "workspace:*", "prop-types": "15.8.1", "react": "18.3.1", "react-dom": "18.3.1", diff --git a/extensions/dicom-pdf/package.json b/extensions/dicom-pdf/package.json index 56ae0e782..fe1235175 100644 --- a/extensions/dicom-pdf/package.json +++ b/extensions/dicom-pdf/package.json @@ -28,8 +28,8 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/dicom-video/package.json b/extensions/dicom-video/package.json index 2a101eec4..3a3b3ac43 100644 --- a/extensions/dicom-video/package.json +++ b/extensions/dicom-video/package.json @@ -28,8 +28,8 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/measurement-tracking/package.json b/extensions/measurement-tracking/package.json index 992056447..2321df09b 100644 --- a/extensions/measurement-tracking/package.json +++ b/extensions/measurement-tracking/package.json @@ -29,10 +29,10 @@ "peerDependencies": { "@cornerstonejs/core": "5.0.2", "@cornerstonejs/tools": "5.0.2", - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/ui": "workspace:*", "classnames": "2.5.1", "dcmjs": "0.49.4", "lodash.debounce": "4.0.8", @@ -43,7 +43,7 @@ }, "dependencies": { "@babel/runtime": "7.29.7", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/ui": "workspace:*", "@xstate/react": "3.2.2", "xstate": "4.38.3" }, diff --git a/extensions/test-extension/package.json b/extensions/test-extension/package.json index 1184012dd..2d504a7f1 100644 --- a/extensions/test-extension/package.json +++ b/extensions/test-extension/package.json @@ -28,8 +28,8 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/tmtv/package.json b/extensions/tmtv/package.json index c2c54d554..9d31a9f99 100644 --- a/extensions/tmtv/package.json +++ b/extensions/tmtv/package.json @@ -28,8 +28,8 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/ui": "workspace:*", "dcmjs": "0.49.4", "dicom-parser": "1.8.21", "hammerjs": "2.0.8", diff --git a/extensions/usAnnotation/package.json b/extensions/usAnnotation/package.json index c0e3756cb..e778935af 100644 --- a/extensions/usAnnotation/package.json +++ b/extensions/usAnnotation/package.json @@ -38,11 +38,11 @@ "@babel/runtime": "7.29.7", "@cornerstonejs/core": "5.0.2", "@cornerstonejs/tools": "5.0.2", - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", - "@ohif/ui-next": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/i18n": "workspace:*", + "@ohif/ui-next": "workspace:*" }, "devDependencies": { "@babel/core": "7.29.7", diff --git a/modes/basic-dev-mode/package.json b/modes/basic-dev-mode/package.json index 447fc04c4..c5b0a9fba 100644 --- a/modes/basic-dev-mode/package.json +++ b/modes/basic-dev-mode/package.json @@ -29,12 +29,12 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-dicom-pdf": "3.13.0-beta.92", - "@ohif/extension-dicom-video": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-dicom-pdf": "workspace:*", + "@ohif/extension-dicom-video": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7", diff --git a/modes/basic-test-mode/package.json b/modes/basic-test-mode/package.json index 99e6ddb9e..9247b8e08 100644 --- a/modes/basic-test-mode/package.json +++ b/modes/basic-test-mode/package.json @@ -29,14 +29,14 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-dicom-pdf": "3.13.0-beta.92", - "@ohif/extension-dicom-video": "3.13.0-beta.92", - "@ohif/extension-measurement-tracking": "3.13.0-beta.92", - "@ohif/extension-test": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-dicom-pdf": "workspace:*", + "@ohif/extension-dicom-video": "workspace:*", + "@ohif/extension-measurement-tracking": "workspace:*", + "@ohif/extension-test": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7", diff --git a/modes/basic/package.json b/modes/basic/package.json index 779279809..161205ff2 100644 --- a/modes/basic/package.json +++ b/modes/basic/package.json @@ -25,14 +25,14 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-dicom-pdf": "3.13.0-beta.92", - "@ohif/extension-dicom-video": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-rt": "workspace:*", + "@ohif/extension-cornerstone-dicom-seg": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-dicom-pdf": "workspace:*", + "@ohif/extension-dicom-video": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7" diff --git a/modes/longitudinal/package.json b/modes/longitudinal/package.json index 4a3df8882..e9d936714 100644 --- a/modes/longitudinal/package.json +++ b/modes/longitudinal/package.json @@ -29,16 +29,16 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-dicom-pdf": "3.13.0-beta.92", - "@ohif/extension-dicom-video": "3.13.0-beta.92", - "@ohif/extension-measurement-tracking": "3.13.0-beta.92", - "@ohif/mode-basic": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-rt": "workspace:*", + "@ohif/extension-cornerstone-dicom-seg": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-dicom-pdf": "workspace:*", + "@ohif/extension-dicom-video": "workspace:*", + "@ohif/extension-measurement-tracking": "workspace:*", + "@ohif/mode-basic": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7", diff --git a/modes/microscopy/package.json b/modes/microscopy/package.json index e7dc77b35..8161341cc 100644 --- a/modes/microscopy/package.json +++ b/modes/microscopy/package.json @@ -30,8 +30,8 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-dicom-microscopy": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-dicom-microscopy": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7", diff --git a/modes/preclinical-4d/package.json b/modes/preclinical-4d/package.json index bf93e06f2..03fd6121b 100644 --- a/modes/preclinical-4d/package.json +++ b/modes/preclinical-4d/package.json @@ -28,12 +28,12 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dynamic-volume": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-tmtv": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-seg": "workspace:*", + "@ohif/extension-cornerstone-dynamic-volume": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-tmtv": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7" diff --git a/modes/segmentation/package.json b/modes/segmentation/package.json index 158455eea..e34a917c9 100644 --- a/modes/segmentation/package.json +++ b/modes/segmentation/package.json @@ -30,15 +30,15 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-rt": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-seg": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-dicom-pdf": "3.13.0-beta.92", - "@ohif/extension-dicom-video": "3.13.0-beta.92", - "@ohif/mode-basic": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-rt": "workspace:*", + "@ohif/extension-cornerstone-dicom-seg": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-dicom-pdf": "workspace:*", + "@ohif/extension-dicom-video": "workspace:*", + "@ohif/mode-basic": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7", diff --git a/modes/tmtv/package.json b/modes/tmtv/package.json index 79f477e77..6eae6cbb1 100644 --- a/modes/tmtv/package.json +++ b/modes/tmtv/package.json @@ -29,13 +29,13 @@ "test:unit:ci": "jest --ci --runInBand --collectCoverage --passWithNoTests" }, "peerDependencies": { - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-default": "3.13.0-beta.92", - "@ohif/extension-dicom-pdf": "3.13.0-beta.92", - "@ohif/extension-dicom-video": "3.13.0-beta.92", - "@ohif/extension-measurement-tracking": "3.13.0-beta.92" + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-default": "workspace:*", + "@ohif/extension-dicom-pdf": "workspace:*", + "@ohif/extension-dicom-video": "workspace:*", + "@ohif/extension-measurement-tracking": "workspace:*" }, "dependencies": { "@babel/runtime": "7.29.7", diff --git a/modes/usAnnotation/package.json b/modes/usAnnotation/package.json index f39118f96..3f05c499b 100644 --- a/modes/usAnnotation/package.json +++ b/modes/usAnnotation/package.json @@ -31,9 +31,9 @@ "@babel/runtime": "7.29.7", "@cornerstonejs/core": "5.0.2", "@cornerstonejs/tools": "5.0.2", - "@ohif/core": "3.13.0-beta.92", - "@ohif/extension-cornerstone-dicom-sr": "3.13.0-beta.92", - "@ohif/extension-ultrasound-pleura-bline": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/extension-cornerstone-dicom-sr": "workspace:*", + "@ohif/extension-ultrasound-pleura-bline": "workspace:*", "i18next": "17.3.1" }, "devDependencies": { diff --git a/platform/app/package.json b/platform/app/package.json index b5ae713bc..9dbcb9773 100644 --- a/platform/app/package.json +++ b/platform/app/package.json @@ -53,10 +53,10 @@ "@cornerstonejs/codec-openjph": "2.4.7", "@cornerstonejs/dicom-image-loader": "5.0.2", "@emotion/serialize": "1.3.3", - "@ohif/core": "3.13.0-beta.92", - "@ohif/i18n": "3.13.0-beta.92", - "@ohif/ui": "3.13.0-beta.92", - "@ohif/ui-next": "3.13.0-beta.92", + "@ohif/core": "workspace:*", + "@ohif/i18n": "workspace:*", + "@ohif/ui": "workspace:*", + "@ohif/ui-next": "workspace:*", "@svgr/webpack": "8.1.0", "@types/react": "18.3.23", "classnames": "2.5.1", diff --git a/platform/core/package.json b/platform/core/package.json index 55ed5a03f..32ecfe508 100644 --- a/platform/core/package.json +++ b/platform/core/package.json @@ -38,7 +38,7 @@ "@cornerstonejs/core": "5.0.2", "@cornerstonejs/dicom-image-loader": "5.0.2", "@cornerstonejs/metadata": "5.0.2", - "@ohif/ui": "3.13.0-beta.92", + "@ohif/ui": "workspace:*", "cornerstone-math": "0.1.10", "dicom-parser": "1.8.21" }, diff --git a/platform/docs/docs/migration-guide/3p12-to-3p13/build-tooling.md b/platform/docs/docs/migration-guide/3p12-to-3p13/build-tooling.md index 1b78d3652..aefedf2c1 100644 --- a/platform/docs/docs/migration-guide/3p12-to-3p13/build-tooling.md +++ b/platform/docs/docs/migration-guide/3p12-to-3p13/build-tooling.md @@ -399,5 +399,3 @@ template, do the following: it is kept on for normal local dev. - The `dev:no:cache` script is now identical to `dev` — keep it as an alias if external scripts call it, or delete it. - - diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c8ab0eb45..38584f4ea 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -16,6 +16,9 @@ minimumReleaseAgeExclude: - '@cornerstonejs/*' frozenLockfile: true +# Skip the pre-`pnpm run` frozen deps-check; installs set freshness explicitly. +verifyDepsBeforeRun: false + # Equivalent of the bun `audit --ignore=...` flags. These GHSAs are accepted # risk: minimatch/picomatch advisories reached only via build/CI tooling, never # fed user-supplied expressions. Kept in sync with the .circleci SECURITY_AUDIT diff --git a/publish-package.mjs b/publish-package.mjs index e4e198b54..c87297c6a 100644 --- a/publish-package.mjs +++ b/publish-package.mjs @@ -37,13 +37,18 @@ async function run() { while (retries < MAX_RETRIES) { try { console.log(`Tying to publishing package at ${packageDirectory}`); - const publishArgs = ['publish']; + // Use `pnpm publish` (not npm) so the workspace:* specifiers on our + // internal @ohif/* deps are rewritten to the exact version in the + // published tarball. npm would publish the literal "workspace:*", + // which npm/yarn consumers cannot resolve. --no-git-checks because + // the bump commit/tag is created in CI on a possibly-detached ref. + const publishArgs = ['publish', '--no-git-checks']; if (branchName === 'master') { publishArgs.push('--tag', 'beta'); } - await execa('npm', publishArgs); + await execa('pnpm', publishArgs); console.log(`Successfully published package at ${packageDirectory}`); break; } catch (error) { diff --git a/publish-version.mjs b/publish-version.mjs index f8493e307..0b33882ce 100644 --- a/publish-version.mjs +++ b/publish-version.mjs @@ -30,27 +30,13 @@ async function run() { try { const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); - // Update the package version + // Bump only the package's own version. Internal @ohif/* references stay + // as workspace:* in the committed manifests (and therefore the lockfile, + // which records them as links), so pnpm-lock.yaml never drifts on a + // version bump and frozen installs keep working. pnpm publish rewrites + // workspace:* to the exact version in the published tarball only. packageJson.version = nextVersion; - // Update peerDependencies - if (packageJson.peerDependencies) { - for (const dep of Object.keys(packageJson.peerDependencies)) { - if (dep.startsWith('@ohif/')) { - packageJson.peerDependencies[dep] = nextVersion; - } - } - } - - // Update dependencies - if (packageJson.dependencies) { - for (const dep of Object.keys(packageJson.dependencies)) { - if (dep.startsWith('@ohif/')) { - packageJson.dependencies[dep] = nextVersion; - } - } - } - await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); updatedFiles.push(packageJsonPath); diff --git a/tests/SEGHydrationFromMPR.spec.ts b/tests/SEGHydrationFromMPR.spec.ts index 1d6e391b8..a5c780c77 100644 --- a/tests/SEGHydrationFromMPR.spec.ts +++ b/tests/SEGHydrationFromMPR.spec.ts @@ -3,7 +3,6 @@ import { screenShotPaths, test, visitStudy, - waitForPaintToSettle, waitForViewportRenderCycle, waitForViewportsRendered, } from './utils'; @@ -36,11 +35,11 @@ test('should properly display MPR for MR', async ({ await leftPanelPageObject.loadSeriesByDescription('SEG'); + // SEG load triggers a progressive labelmap volume upload. waitForViewportsRendered + // (waitVolumeLoad defaults to true) polls the viewport volume actors until the + // labelmap reports loadStatus.loaded, then settles, so the screenshot captures the + // finished upload rather than a mid-stream frame. await waitForViewportsRendered(page); - // SEG load triggers an additional progressive labelmap upload after the - // viewports first report 'rendered'; let that finish before screenshotting. - await page.waitForTimeout(1500); - await waitForPaintToSettle(page); await checkForScreenshot( page, @@ -54,11 +53,11 @@ test('should properly display MPR for MR', async ({ await DOMOverlayPageObject.viewport.segmentationHydration.yes.click(); await viewportRenderCycle; - // Hydration propagates the labelmap volume to the sagittal/coronal MPR - // viewports asynchronously; wait for that propagation to render before - // capturing. - await page.waitForTimeout(1500); - await waitForPaintToSettle(page); + // Hydration propagates the labelmap volume to the sagittal/coronal MPR viewports + // asynchronously, adding new volume actors after the first render cycle resolves. + // waitForViewportsRendered re-polls every viewport's volume actors until those + // propagated labelmaps report loadStatus.loaded, then settles. + await waitForViewportsRendered(page); await checkForScreenshot( page, @@ -71,8 +70,9 @@ test('should properly display MPR for MR', async ({ await mainToolbarPageObject.layoutSelection.axialPrimary.click(); await viewportRenderAfterLayoutChange; - await page.waitForTimeout(1000); - await waitForPaintToSettle(page); + // The layout change rebuilds the viewports; wait for their volume actors (image + // + labelmap) to report loaded before settling and capturing. + await waitForViewportsRendered(page); await checkForScreenshot( page, diff --git a/tests/pages/ViewportPageObject.ts b/tests/pages/ViewportPageObject.ts index 8637b0388..4e8a2861f 100644 --- a/tests/pages/ViewportPageObject.ts +++ b/tests/pages/ViewportPageObject.ts @@ -1,6 +1,5 @@ import { Locator, Page } from '@playwright/test'; import { - getMousePosition, simulateClicksOnElement, simulateDoubleClickOnElement, simulateNormalizedClicksOnElement, @@ -362,6 +361,28 @@ export class ViewportPageObject { throw new Error('Could not find slab thickness handle for crosshairs interaction'); } + // Drive the drag from the handle's own bounding-box center rather than the + // async window.mouseX/Y tracker: the tracker can lag behind the hover, which + // makes the drag start from a stale point and rotate/resize nothing. Stepped + // moves emit intermediate mousemove events so cornerstone registers a real + // drag instead of a single teleport (which can be dropped or mis-deltad). + const DRAG_DISTANCE = 100; + const DRAG_STEPS = 10; + + async function dragHandleFromCenter(handle: Locator, dx: number, dy: number) { + const box = await handle.boundingBox(); + if (!box) { + throw new Error('Could not resolve crosshairs handle bounding box for drag'); + } + const cx = box.x + box.width / 2; + const cy = box.y + box.height / 2; + + await page.mouse.move(cx, cy); + await page.mouse.down(); + await page.mouse.move(cx + dx, cy + dy, { steps: DRAG_STEPS }); + await page.mouse.up(); + } + async function increaseSlabThickness(locator: Locator, lineNumber: number, axis: string) { const lineLocator = locator.locator('line').nth(lineNumber); await lineLocator.click({ force: true }); @@ -370,18 +391,9 @@ export class ViewportPageObject { const slabHandleLocator = await getSlabHandleLocator(locator); await slabHandleLocator.hover({ force: true, timeout: crosshairHoverTimeout }); - await page.mouse.down(); - - const position = await getMousePosition(page); - switch (axis) { - case 'x': - await page.mouse.move(position.x + 100, position.y); - break; - case 'y': - await page.mouse.move(position.x, position.y + 100); - break; - } - await page.mouse.up(); + const dx = axis === 'x' ? DRAG_DISTANCE : 0; + const dy = axis === 'y' ? DRAG_DISTANCE : 0; + await dragHandleFromCenter(slabHandleLocator, dx, dy); } async function rotateCrosshairs(locator: Locator, lineNumber: number) { @@ -393,11 +405,7 @@ export class ViewportPageObject { await circleLocator.waitFor({ state: 'attached', timeout: crosshairHoverTimeout }); await circleLocator.hover({ force: true, timeout: crosshairHoverTimeout }); - await page.mouse.down(); - - const position = await getMousePosition(page); - await page.mouse.move(position.x, position.y + 100); - await page.mouse.up(); + await dragHandleFromCenter(circleLocator, 0, DRAG_DISTANCE); } function crosshairsFactory(