feat(node): move to node 20 (#4594)

This commit is contained in:
Alireza 2024-12-11 15:26:26 -05:00 committed by GitHub
parent ab41183ce5
commit 1f04d6c1be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 173 additions and 135 deletions

View File

@ -6,7 +6,7 @@ orbs:
defaults: &defaults defaults: &defaults
docker: docker:
- image: cimg/node:18.18 - image: cimg/node:20.18.1
environment: environment:
TERM: xterm TERM: xterm
QUICK_BUILD: true QUICK_BUILD: true

View File

@ -64,7 +64,7 @@ body:
attributes: attributes:
label: 'Node version' label: 'Node version'
description: 'Your Node.js version.' description: 'Your Node.js version.'
placeholder: 'e.g., 18.16.1' placeholder: 'e.g., 20.18.1'
validations: validations:
required: true required: true
- type: input - type: input

View File

@ -22,7 +22,7 @@ jobs:
- uses: oven-sh/setup-bun@v2 - uses: oven-sh/setup-bun@v2
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- name: Install dependencies - name: Install dependencies
run: bun install --frozen-lockfile run: bun install --frozen-lockfile
- name: Set up Git safe directory - name: Set up Git safe directory
@ -53,7 +53,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- name: Install dependencies - name: Install dependencies
run: bun install --frozen-lockfile run: bun install --frozen-lockfile
- name: Set up Git safe directory - name: Set up Git safe directory

View File

@ -1 +1 @@
18.16.1 20.9.0

View File

@ -21,7 +21,7 @@
# Stage 1: Build the application # Stage 1: Build the application
# docker build -t ohif/viewer:latest . # docker build -t ohif/viewer:latest .
FROM node:18.16.1-slim as json-copier FROM node:20.18.1-slim as json-copier
RUN mkdir /usr/src/app RUN mkdir /usr/src/app
WORKDIR /usr/src/app WORKDIR /usr/src/app
@ -37,7 +37,7 @@ COPY platform /usr/src/app/platform
#RUN find platform \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf #RUN find platform \! -name "package.json" -mindepth 2 -maxdepth 2 -print | xargs rm -rf
# Copy Files # Copy Files
FROM node:18.16.1-slim as builder FROM node:20.18.1-slim as builder
RUN apt-get update && apt-get install -y build-essential python3 RUN apt-get update && apt-get install -y build-essential python3
RUN mkdir /usr/src/app RUN mkdir /usr/src/app
WORKDIR /usr/src/app WORKDIR /usr/src/app

BIN
bun.lockb

Binary file not shown.

View File

@ -46,8 +46,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.7.3", "@cornerstonejs/adapters": "^2.11.2",
"@cornerstonejs/core": "^2.7.3", "@cornerstonejs/core": "^2.11.2",
"@kitware/vtk.js": "32.1.1", "@kitware/vtk.js": "32.1.1",
"react-color": "^2.19.3" "react-color": "^2.19.3"
} }

View File

@ -46,8 +46,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.7.3", "@cornerstonejs/adapters": "^2.11.2",
"@cornerstonejs/core": "^2.7.3", "@cornerstonejs/core": "^2.11.2",
"@kitware/vtk.js": "32.1.1", "@kitware/vtk.js": "32.1.1",
"react-color": "^2.19.3" "react-color": "^2.19.3"
} }

View File

@ -46,9 +46,9 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.7.3", "@cornerstonejs/adapters": "^2.11.2",
"@cornerstonejs/core": "^2.7.3", "@cornerstonejs/core": "^2.11.2",
"@cornerstonejs/tools": "^2.7.3", "@cornerstonejs/tools": "^2.11.2",
"classnames": "^2.3.2" "classnames": "^2.3.2"
} }
} }

View File

@ -42,8 +42,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/core": "^2.7.3", "@cornerstonejs/core": "^2.11.2",
"@cornerstonejs/tools": "^2.7.3", "@cornerstonejs/tools": "^2.11.2",
"classnames": "^2.3.2" "classnames": "^2.3.2"
} }
} }

View File

@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5", "@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.7.3", "@cornerstonejs/dicom-image-loader": "^2.11.2",
"@icr/polyseg-wasm": "^0.4.0", "@icr/polyseg-wasm": "^0.4.0",
"@ohif/core": "3.10.0-beta.20", "@ohif/core": "3.10.0-beta.20",
"@ohif/ui": "3.10.0-beta.20", "@ohif/ui": "3.10.0-beta.20",
@ -55,9 +55,9 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.7.3", "@cornerstonejs/adapters": "^2.11.2",
"@cornerstonejs/core": "^2.7.3", "@cornerstonejs/core": "^2.11.2",
"@cornerstonejs/tools": "^2.7.3", "@cornerstonejs/tools": "^2.11.2",
"@icr/polyseg-wasm": "^0.4.0", "@icr/polyseg-wasm": "^0.4.0",
"@kitware/vtk.js": "32.1.1", "@kitware/vtk.js": "32.1.1",
"html2canvas": "^1.4.1", "html2canvas": "^1.4.1",

View File

@ -171,51 +171,61 @@ export default function PanelSegmentation({
onSegmentationDownload, onSegmentationDownload,
onSegmentationDownloadRTSS, onSegmentationDownloadRTSS,
t, t,
}) => ( }) => {
<DropdownMenuContent align="start"> return (
<DropdownMenuItem onClick={() => onSegmentationAdd(activeSegmentation.id)}> <DropdownMenuContent align="start">
<Icons.Add className="text-foreground" /> <DropdownMenuItem onClick={() => onSegmentationAdd(activeSegmentation.segmentationId)}>
<span className="pl-2">{t('Create New Segmentation')}</span> <Icons.Add className="text-foreground" />
</DropdownMenuItem> <span className="pl-2">{t('Create New Segmentation')}</span>
<DropdownMenuSeparator /> </DropdownMenuItem>
<DropdownMenuLabel>{t('Manage Current Segmentation')}</DropdownMenuLabel> <DropdownMenuSeparator />
<DropdownMenuItem onClick={() => onSegmentationRemoveFromViewport(activeSegmentation.id)}> <DropdownMenuLabel>{t('Manage Current Segmentation')}</DropdownMenuLabel>
<Icons.Series className="text-foreground" /> <DropdownMenuItem
<span className="pl-2">{t('Remove from Viewport')}</span> onClick={() => onSegmentationRemoveFromViewport(activeSegmentation.segmentationId)}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => onSegmentationEdit(activeSegmentation.id)}>
<Icons.Rename className="text-foreground" />
<span className="pl-2">{t('Rename')}</span>
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger
disabled={!allowExport}
className="pl-1"
> >
<Icons.Export className="text-foreground" /> <Icons.Series className="text-foreground" />
<span className="pl-2">{t('Export & Download')}</span> <span className="pl-2">{t('Remove from Viewport')}</span>
</DropdownMenuSubTrigger> </DropdownMenuItem>
<DropdownMenuPortal> <DropdownMenuItem onClick={() => onSegmentationEdit(activeSegmentation.segmentationId)}>
<DropdownMenuSubContent> <Icons.Rename className="text-foreground" />
<DropdownMenuItem onClick={() => storeSegmentation(activeSegmentation.id)}> <span className="pl-2">{t('Rename')}</span>
{t('Export DICOM SEG')} </DropdownMenuItem>
</DropdownMenuItem> <DropdownMenuSub>
<DropdownMenuItem onClick={() => onSegmentationDownload(activeSegmentation.id)}> <DropdownMenuSubTrigger
{t('Download DICOM SEG')} disabled={!allowExport}
</DropdownMenuItem> className="pl-1"
<DropdownMenuItem onClick={() => onSegmentationDownloadRTSS(activeSegmentation.id)}> >
{t('Download DICOM RTSTRUCT')} <Icons.Export className="text-foreground" />
</DropdownMenuItem> <span className="pl-2">{t('Export & Download')}</span>
</DropdownMenuSubContent> </DropdownMenuSubTrigger>
</DropdownMenuPortal> <DropdownMenuPortal>
</DropdownMenuSub> <DropdownMenuSubContent>
<DropdownMenuSeparator /> <DropdownMenuItem
<DropdownMenuItem onClick={() => onSegmentationDelete(activeSegmentation.id)}> onClick={() => storeSegmentation(activeSegmentation.segmentationId)}
<Icons.Delete className="text-red-600" /> >
<span className="pl-2 text-red-600">{t('Delete')}</span> {t('Export DICOM SEG')}
</DropdownMenuItem> </DropdownMenuItem>
</DropdownMenuContent> <DropdownMenuItem
) onClick={() => onSegmentationDownload(activeSegmentation.segmentationId)}
>
{t('Download DICOM SEG')}
</DropdownMenuItem>
{/* <DropdownMenuItem
onClick={() => onSegmentationDownloadRTSS(activeSegmentation.segmentationId)}
>
{t('Download DICOM RTSTRUCT')}
</DropdownMenuItem> */}
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => onSegmentationDelete(activeSegmentation.segmentationId)}>
<Icons.Delete className="text-red-600" />
<span className="pl-2 text-red-600">{t('Delete')}</span>
</DropdownMenuItem>
</DropdownMenuContent>
);
}
); );
const exportOptions = segmentationsWithRepresentations.map(({ segmentation }) => { const exportOptions = segmentationsWithRepresentations.map(({ segmentation }) => {

View File

@ -32,8 +32,8 @@
"start": "yarn run dev" "start": "yarn run dev"
}, },
"peerDependencies": { "peerDependencies": {
"@cornerstonejs/core": "^2.7.3", "@cornerstonejs/core": "^2.11.2",
"@cornerstonejs/tools": "^2.7.3", "@cornerstonejs/tools": "^2.11.2",
"@ohif/core": "3.10.0-beta.20", "@ohif/core": "3.10.0-beta.20",
"@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.20", "@ohif/extension-cornerstone-dicom-sr": "3.10.0-beta.20",
"@ohif/extension-default": "3.10.0-beta.20", "@ohif/extension-default": "3.10.0-beta.20",

View File

@ -1,5 +1,5 @@
# Stage 1: Build the application # Stage 1: Build the application
FROM node:18.16.1-slim as builder FROM node:20.18.1-slim as builder
# Setup the working directory # Setup the working directory
RUN mkdir /usr/src/app RUN mkdir /usr/src/app

View File

@ -1,5 +1,5 @@
# Stage 1: Build the application # Stage 1: Build the application
FROM node:18.16.1-slim as builder FROM node:20.18.1-slim as builder
# Setup the working directory # Setup the working directory
RUN mkdir /usr/src/app RUN mkdir /usr/src/app

View File

@ -1,5 +1,5 @@
# Stage 1: Build the application # Stage 1: Build the application
FROM node:18.16.1-slim as builder FROM node:20.18.1-slim as builder
# Setup the working directory # Setup the working directory
RUN mkdir /usr/src/app RUN mkdir /usr/src/app

View File

@ -1,5 +1,5 @@
# Stage 1: Build the application # Stage 1: Build the application
FROM node:18.16.1-slim as builder FROM node:20.18.1-slim as builder
# Setup the working directory # Setup the working directory
RUN mkdir /usr/src/app RUN mkdir /usr/src/app

View File

@ -19,7 +19,7 @@
[build.environment] [build.environment]
# If 'production', `yarn install` does not install devDependencies # If 'production', `yarn install` does not install devDependencies
NODE_ENV = "development" NODE_ENV = "development"
NODE_VERSION = "18.16.1" NODE_VERSION = "20.18.1"
YARN_VERSION = "1.22.5" YARN_VERSION = "1.22.5"
RUBY_VERSION = "2.6.2" RUBY_VERSION = "2.6.2"
YARN_FLAGS = "--no-ignore-optional --pure-lockfile" YARN_FLAGS = "--no-ignore-optional --pure-lockfile"

View File

@ -53,7 +53,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5", "@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.7.3", "@cornerstonejs/dicom-image-loader": "^2.11.2",
"@emotion/serialize": "^1.1.3", "@emotion/serialize": "^1.1.3",
"@ohif/core": "3.10.0-beta.20", "@ohif/core": "3.10.0-beta.20",
"@ohif/extension-cornerstone": "3.10.0-beta.20", "@ohif/extension-cornerstone": "3.10.0-beta.20",

View File

@ -12,41 +12,16 @@ window.config = {
showLoadingIndicator: true, showLoadingIndicator: true,
strictZSpacingForVolumeViewport: true, strictZSpacingForVolumeViewport: true,
// filterQueryParam: false, // filterQueryParam: false,
defaultDataSourceName: 'dicomweb', defaultDataSourceName: 'local',
dataSources: [ dataSources: [
{
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'e2e',
configuration: {
friendlyName: 'StaticWado test data',
// The most important field to set for static WADO
staticWado: true,
name: 'StaticWADO',
wadoUriRoot: '/viewer-testdata',
qidoRoot: '/viewer-testdata',
wadoRoot: '/viewer-testdata',
qidoSupportsIncludeField: false,
imageRendering: 'wadors',
thumbnailRendering: 'wadors',
enableStudyLazyLoad: true,
supportsFuzzyMatching: false,
supportsWildcard: true,
singlepart: 'video,thumbnail,pdf',
omitQuotationForMultipartRequest: true,
bulkDataURI: {
enabled: true,
relativeResolution: 'studies',
},
},
},
{ {
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb', namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'local', sourceName: 'local',
configuration: { configuration: {
friendlyName: 'Static WADO Local Data', friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE', name: 'DCM4CHEE',
qidoRoot: 'http://localhost:5000/dicomweb', qidoRoot: 'http://localhost:3001/dicomweb',
wadoRoot: 'http://localhost:5000/dicomweb', wadoRoot: 'http://localhost:3001/dicomweb',
qidoSupportsIncludeField: false, qidoSupportsIncludeField: false,
supportsReject: true, supportsReject: true,
supportsStow: true, supportsStow: true,

View File

@ -37,7 +37,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2", "@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4", "@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5", "@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.7.3", "@cornerstonejs/dicom-image-loader": "^2.11.2",
"@ohif/ui": "3.10.0-beta.20", "@ohif/ui": "3.10.0-beta.20",
"cornerstone-math": "0.1.9", "cornerstone-math": "0.1.9",
"dicom-parser": "^1.8.21" "dicom-parser": "^1.8.21"

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -3,45 +3,98 @@ sidebar_position: 5
sidebar_label: Static Files sidebar_label: Static Files
--- ---
# Static Files
There is a binary DICOM to static file generator, which provides easily served # Static DICOMweb Files for Enhanced Performance
binary files. The files are all compressed in order to reduce space
significantly, and are pre-computed for the files required for OHIF, so that the
performance of serving the files is just the read from disk/write to http stream
time, without any extra processing time.
The project for the static wado files is located here: [static-wado]: This section describes how to generate and serve static DICOMweb files, significantly improving the performance of your OHIF Viewer setup. These files are pre-processed and compressed, minimizing storage space and reducing serving time to the bare minimum (disk read and HTTP stream write).
https://github.com/OHIF/static-wado
It can be compiled with Java and Gradle, and then run against a set of dicom, in ## Static-DICOMWeb Project
the example located in /dicom/study1 outputting to /dicomweb, and then a server
run against that data, like this:
```bash The core tool for this process is the `static-wado` project, available on GitHub:
git clone https://github.com/OHIF/static-wado
cd static-wado
./gradlew installDist
StaticWado/build/install/StaticWado/bin/StaticWado -d /dicomweb /dicom/study1
cd /dicomweb
npx http-server -p 5000 --cors -g
# you can use npx serve ./dist -l 8080 -c ../public/serve.json as an alternative to http-server [static-wado]: https://github.com/RadicalImaging/Static-DICOMWeb
```
There is then a dev environment in the platform/app directory which can be This project contains two main components:
run against those files, like this:
``` * **`static-wado-creator`:** Converts raw DICOM files into a DICOMweb-compliant directory structure, optimizing them for efficient serving.
cd platform/app * **`static-wado-webserver`:** A simple web server specifically designed to serve the generated static DICOMweb files.
yarn dev:static
```
Additional studies can be added to the dicomweb by re-running the StaticWado ## Prerequisites
command. It will create a single studies.gz index file (JSON DICOM file,
compressed) containing an index of all studies created. There is then a small
extension to OHIF which performs client side indexing.
The StaticWado command also knows how to deploy a client and dicomweb directory - Node.js and npm (or yarn) installed on your system.
to Amazon s3, which can then server files up directly. There is another build
setup build:aws in the viewer package.json to create such a deployment. ## Installation
1. **Clone the Repository:**
```bash
git clone https://github.com/RadicalImaging/Static-DICOMWeb
cd Static-DICOMWeb
```
2. **Install Dependencies:**
```bash
yarn install
```
## Generating Static DICOMweb Files
1. **Prepare your DICOM data:** Organize your DICOM files into a directory. For example `/Users/alireza/dicom/test-static-script/ACRIN-CT`.
2. **Convert to DICOMweb Structure:**
Use the `mkdicomweb.js` script from the `static-wado-creator` package to create the DICOMweb directory:
```bash
node packages/static-wado-creator/bin/mkdicomweb.js '/Users/alireza/dicom/test-static-script/ACRIN-CT' -o '/Users/alireza/dicom/test-static-script/output'
```
* **Replace:**
* `/Users/alireza/dicom/test-static-script/ACRIN-CT` with the path to your directory of DICOM files.
* `/Users/alireza/dicom/test-static-script/output` with your desired output directory for the DICOMweb structure.
This command will generate a directory structure similar to this in your output location:
![alt text](../../assets/img/static-dicom-web.png)
## Serving Static Files with the Web Server
1. **Start the Server:**
Run the `dicomwebserver.mjs` script from the `static-wado-webserver` package, specifying the port and the DICOMweb directory:
```bash
node packages/static-wado-webserver/bin/dicomwebserver.mjs -p 3001 -o /Users/alireza/dicom/test-static-script/output
```
* **`-p 3001`:** Sets the server to listen on port 3001. You can change this if needed.
* **`-o /Users/alireza/dicom/test-static-script/output`:** Specifies the path to your generated DICOMweb directory.
:::info
The `-p` (port) and `-o` (output directory) flags are used to configure the server.
:::
## Running OHIF Viewer with Static Data
1. **Use the `local_static.js` Configuration:**
Start the OHIF Viewer in development mode using the provided `local_static.js` configuration file:
```bash
yarn dev:static
```
2. **Configuration Details:**
The `local_static.js` configuration file is pre-configured to point to:
```js
qidoRoot: 'http://localhost:3001/dicomweb',
wadoRoot: 'http://localhost:3001/dicomweb',
```
This matches the default port (3001) used by the `static-wado-webserver`.
:::info
If you change the port or output directory when running the `static-wado-webserver`, you **must** also update the `qidoRoot` and `wadoRoot` values in your `local_static.js` configuration file accordingly to ensure the OHIF Viewer can access the data.
:::

View File

@ -16,7 +16,7 @@
[build.environment] [build.environment]
# If 'production', `yarn install` does not install devDependencies # If 'production', `yarn install` does not install devDependencies
NODE_ENV = "development" NODE_ENV = "development"
NODE_VERSION = "18.16.1" NODE_VERSION = "20.18.1"
YARN_VERSION = "1.22.5" YARN_VERSION = "1.22.5"
RUBY_VERSION = "2.6.2" RUBY_VERSION = "2.6.2"
YARN_FLAGS = "--no-ignore-optional --pure-lockfile" YARN_FLAGS = "--no-ignore-optional --pure-lockfile"