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
docker:
- image: cimg/node:18.18
- image: cimg/node:20.18.1
environment:
TERM: xterm
QUICK_BUILD: true

View File

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

View File

@ -22,7 +22,7 @@ jobs:
- uses: oven-sh/setup-bun@v2
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Set up Git safe directory
@ -53,7 +53,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
- name: Install dependencies
run: bun install --frozen-lockfile
- 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
# 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
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
# 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 mkdir /usr/src/app
WORKDIR /usr/src/app

BIN
bun.lockb

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
# 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
RUN mkdir /usr/src/app

View File

@ -1,5 +1,5 @@
# 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
RUN mkdir /usr/src/app

View File

@ -1,5 +1,5 @@
# 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
RUN mkdir /usr/src/app

View File

@ -1,5 +1,5 @@
# 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
RUN mkdir /usr/src/app

View File

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

View File

@ -53,7 +53,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@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",
"@ohif/core": "3.10.0-beta.20",
"@ohif/extension-cornerstone": "3.10.0-beta.20",

View File

@ -12,41 +12,16 @@ window.config = {
showLoadingIndicator: true,
strictZSpacingForVolumeViewport: true,
// filterQueryParam: false,
defaultDataSourceName: 'dicomweb',
defaultDataSourceName: 'local',
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',
sourceName: 'local',
configuration: {
friendlyName: 'Static WADO Local Data',
name: 'DCM4CHEE',
qidoRoot: 'http://localhost:5000/dicomweb',
wadoRoot: 'http://localhost:5000/dicomweb',
qidoRoot: 'http://localhost:3001/dicomweb',
wadoRoot: 'http://localhost:3001/dicomweb',
qidoSupportsIncludeField: false,
supportsReject: true,
supportsStow: true,

View File

@ -37,7 +37,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@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",
"cornerstone-math": "0.1.9",
"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
---
# Static Files
There is a binary DICOM to static file generator, which provides easily served
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.
# Static DICOMweb Files for Enhanced Performance
The project for the static wado files is located here: [static-wado]:
https://github.com/OHIF/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).
It can be compiled with Java and Gradle, and then run against a set of dicom, in
the example located in /dicom/study1 outputting to /dicomweb, and then a server
run against that data, like this:
## Static-DICOMWeb Project
```bash
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
The core tool for this process is the `static-wado` project, available on GitHub:
# 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
run against those files, like this:
This project contains two main components:
```
cd platform/app
yarn dev:static
```
* **`static-wado-creator`:** Converts raw DICOM files into a DICOMweb-compliant directory structure, optimizing them for efficient serving.
* **`static-wado-webserver`:** A simple web server specifically designed to serve the generated static DICOMweb files.
Additional studies can be added to the dicomweb by re-running the StaticWado
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.
## Prerequisites
The StaticWado command also knows how to deploy a client and dicomweb directory
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.
- Node.js and npm (or yarn) installed on your system.
## 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]
# If 'production', `yarn install` does not install devDependencies
NODE_ENV = "development"
NODE_VERSION = "18.16.1"
NODE_VERSION = "20.18.1"
YARN_VERSION = "1.22.5"
RUBY_VERSION = "2.6.2"
YARN_FLAGS = "--no-ignore-optional --pure-lockfile"