Skip to content

Commit 3e5feb1

Browse files
committed
feat(itk-dicom): Node.js bundling and interface
1 parent 2be8d37 commit 3e5feb1

12 files changed

+444
-228
lines changed

dist/dicom/test/app.js renamed to dist/dicom/dist/demo-app.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const demoAppMachine = XState.createMachine({
5959
onError: {
6060
actions: [
6161
(c, event) => {
62+
console.log(event)
6263
const message = `Could not process file: ${event.data.toString()}`
6364
console.error(message)
6465
alert(message)

dist/dicom/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@
3838

3939
<!-- Javascript -->
4040
<script type="module" src="./dist/itk-dicom.js"></script>
41-
<script type="module" src="./test/app.js"></script>
41+
<script type="module" src="./dist/demo-app.js"></script>
4242
</body>
4343
</html>

dist/dicom/package.json

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,29 @@
33
"version": "0.0.1",
44
"description": "DICOM IO from itk-wasm",
55
"type": "module",
6-
"main": "./dist/itk-dicom.umd.cjs",
76
"module": "./dist/itk-dicom.js",
87
"types": "./dist/index.d.ts",
98
"exports": {
109
".": {
11-
"import": "./dist/itk-dicom.js",
12-
"require": "./dist/itk-dicom.umd.cjs"
10+
"browser": "./dist/itk-dicom.js",
11+
"node": "./dist/itk-dicom.node.js",
12+
"umd": "./dist/itk-dicom.umd.js",
13+
"default": "./dist/itk-dicom.js"
1314
}
1415
},
1516
"scripts": {
1617
"dev": "vite --port 8173",
17-
"build": "tsc && vite build --sourcemap",
18-
"build:watch": "tsc && vite build --minify false --mode development --watch",
18+
"build": "npm run build:browser && npm run build:node",
19+
"build:node": "rollup -c ./rollup.node.config.js",
20+
"build:browser": "tsc && vite build --sourcemap",
21+
"build:browser:watch": "tsc && vite build --minify false --mode development --watch",
1922
"cypress:open": "npx cypress open",
2023
"cypress:run": "npx cypress run",
2124
"cypress:runChrome": "npx cypress run --browser chrome",
2225
"cypress:runFirefox": "npx cypress run --browser firefox",
2326
"test:debug": "start-server-and-test dev http-get://localhost:8173 cypress:open",
24-
"test": "start-server-and-test dev http-get://localhost:8173 cypress:run",
27+
"test": "npm run test:node && start-server-and-test dev http-get://localhost:8173 cypress:run",
28+
"test:node": "ava",
2529
"test:chrome": "start-server-and-test dev http-get://localhost:8173 cypress:runChrome",
2630
"test:firefox": "start-server-and-test dev http-get://localhost:8173 cypress:runFirefox"
2731
},
@@ -40,10 +44,16 @@
4044
},
4145
"homepage": "https://wasm.itk.org",
4246
"dependencies": {
43-
"itk-wasm": "^1.0.0-b.21"
47+
"itk-wasm": "^1.0.0-b.27"
4448
},
4549
"devDependencies": {
50+
"@rollup/plugin-commonjs": "^22.0.2",
51+
"@rollup/plugin-json": "^4.1.0",
52+
"@rollup/plugin-node-resolve": "^14.0.1",
53+
"@rollup/plugin-typescript": "^8.5.0",
54+
"ava": "^4.3.3",
4655
"cypress": "^10.7.0",
56+
"rollup": "^2.79.0",
4757
"rollup-plugin-copy": "^3.4.0",
4858
"start-server-and-test": "^1.14.0",
4959
"typescript": "^4.7.4",

dist/dicom/rollup.node.config.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { nodeResolve } from '@rollup/plugin-node-resolve'
2+
import typescript from '@rollup/plugin-typescript'
3+
import commonjs from '@rollup/plugin-commonjs'
4+
import json from '@rollup/plugin-json'
5+
import { terser } from 'rollup-plugin-terser'
6+
7+
export default {
8+
input: './src/indexNode.ts',
9+
output: [
10+
{
11+
file: './dist/itk-dicom.node.js',
12+
format: 'es',
13+
sourcemap: true,
14+
plugins: [terser(),],
15+
},
16+
],
17+
plugins: [
18+
commonjs({
19+
transformMixedEsModules: true
20+
}),
21+
nodeResolve({
22+
preferBuiltins: true,
23+
browser: false,
24+
}),
25+
typescript(),
26+
json(),
27+
],
28+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
interface StructuredReportToTextNodeResult {
2+
/** Output text file */
3+
outputText: string
4+
5+
}
6+
7+
export default StructuredReportToTextNodeResult

dist/dicom/src/indexNode.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
3+
import StructuredReportToTextNodeResult from './StructuredReportToTextNodeResult.js'
4+
export type { StructuredReportToTextNodeResult }
5+
6+
import StructuredReportToTextOptions from './StructuredReportToTextOptions.js'
7+
export type { StructuredReportToTextOptions }
8+
9+
import structuredReportToTextNode from './structuredReportToTextNode.js'
10+
export { structuredReportToTextNode }

dist/dicom/src/structuredReportToText.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import StructuredReportToTextResult from './StructuredReportToTextResult.js'
99

1010
/**
1111
* Read a DICOM structured report file and generate a plain text representation
12+
*
1213
* @param {Uint8Array} dicomFile - Input DICOM file
14+
*
1315
* @returns {Promise<StructuredReportToTextResult>} - result object
1416
*/
1517
async function structuredReportToText(
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import {
2+
TextStream,
3+
InterfaceTypes,
4+
runPipelineNode
5+
} from 'itk-wasm'
6+
7+
import StructuredReportToTextOptions from './StructuredReportToTextOptions.js'
8+
import StructuredReportToTextNodeResult from './StructuredReportToTextNodeResult.js'
9+
10+
11+
import path from 'path'
12+
13+
/**
14+
* Read a DICOM structured report file and generate a plain text representation
15+
*
16+
* @param {Uint8Array} dicomFile - Input DICOM file
17+
*
18+
* @returns {Promise<StructuredReportToTextNodeResult>} - result object
19+
*/
20+
async function structuredReportToTextNode( dicomFile: Uint8Array,
21+
options: StructuredReportToTextOptions = {})
22+
: Promise<StructuredReportToTextNodeResult> {
23+
24+
const desiredOutputs = [
25+
{ type: InterfaceTypes.TextStream },
26+
]
27+
const inputs = [
28+
{ type: InterfaceTypes.BinaryFile, data: { data: dicomFile, path: "file0" } },
29+
]
30+
31+
const args = []
32+
// Inputs
33+
args.push('file0')
34+
// Outputs
35+
args.push('0')
36+
// Options
37+
args.push('--memory-io')
38+
if (options.unknownRelationship) {
39+
args.push('--unknown-relationship')
40+
}
41+
if (options.invalidItemValue) {
42+
args.push('--invalid-item-value')
43+
}
44+
if (options.ignoreConstraints) {
45+
args.push('--ignore-constraints')
46+
}
47+
if (options.ignoreItemErrors) {
48+
args.push('--ignore-item-errors')
49+
}
50+
if (options.skipInvalidItems) {
51+
args.push('--skip-invalid-items')
52+
}
53+
if (options.noDocumentHeader) {
54+
args.push('--no-document-header')
55+
}
56+
if (options.numberNestedItems) {
57+
args.push('--number-nested-items')
58+
}
59+
if (options.shortenLongValues) {
60+
args.push('--shorten-long-values')
61+
}
62+
if (options.printInstanceUid) {
63+
args.push('--print-instance-uid')
64+
}
65+
if (options.printSopclassShort) {
66+
args.push('--print-sopclass-short')
67+
}
68+
if (options.printSopclassLong) {
69+
args.push('--print-sopclass-long')
70+
}
71+
if (options.printSopclassUid) {
72+
args.push('--print-sopclass-uid')
73+
}
74+
if (options.printAllCodes) {
75+
args.push('--print-all-codes')
76+
}
77+
if (options.printInvalidCodes) {
78+
args.push('--print-invalid-codes')
79+
}
80+
if (options.printTemplateId) {
81+
args.push('--print-template-id')
82+
}
83+
if (options.indicateEnhanced) {
84+
args.push('--indicate-enhanced')
85+
}
86+
if (options.printColor) {
87+
args.push('--print-color')
88+
}
89+
90+
const pipelinePath = path.join(path.dirname(import.meta.url.substring(7)), 'pipelines', 'structured-report-to-text')
91+
92+
const {
93+
returnValue,
94+
stderr,
95+
outputs
96+
} = await runPipelineNode(pipelinePath, args, desiredOutputs, inputs)
97+
if (returnValue !== 0) {
98+
throw new Error(stderr)
99+
}
100+
101+
const result = {
102+
outputText: (outputs[0].data as TextStream).data,
103+
}
104+
return result
105+
}
106+
107+
export default structuredReportToTextNode

dist/dicom/test/node.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import fs from 'fs'
2+
import test from 'ava'
3+
import { structuredReportToTextNode } from '../dist/itk-dicom.node.js'
4+
5+
test('structuredReportToText', async t => {
6+
7+
const fileName = '88.33-comprehensive-SR.dcm'
8+
const testFilePath = `../../build-emscripten/ExternalData/test/Input/${fileName}`
9+
10+
const dicomFileBuffer = fs.readFileSync(testFilePath)
11+
const dicomFile = new Uint8Array(dicomFileBuffer)
12+
13+
const { outputText } = await structuredReportToTextNode(dicomFile)
14+
15+
t.assert(outputText.includes('Comprehensive SR Document'))
16+
17+
const { outputText: outputTextNoHeader } = await structuredReportToTextNode(dicomFile, { noDocumentHeader: true })
18+
t.assert(!outputTextNoHeader.includes('Comprehensive SR Document'))
19+
t.assert(outputTextNoHeader.includes('Breast Imaging Report'))
20+
})

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)