Skip to content

Commit

Permalink
feat(itk-dicom): Node.js bundling and interface
Browse files Browse the repository at this point in the history
  • Loading branch information
thewtex committed Sep 8, 2022
1 parent 2be8d37 commit 3e5feb1
Show file tree
Hide file tree
Showing 12 changed files with 444 additions and 228 deletions.
1 change: 1 addition & 0 deletions dist/dicom/test/app.js → dist/dicom/dist/demo-app.js
Expand Up @@ -59,6 +59,7 @@ const demoAppMachine = XState.createMachine({
onError: {
actions: [
(c, event) => {
console.log(event)
const message = `Could not process file: ${event.data.toString()}`
console.error(message)
alert(message)
Expand Down
2 changes: 1 addition & 1 deletion dist/dicom/index.html
Expand Up @@ -38,6 +38,6 @@

<!-- Javascript -->
<script type="module" src="./dist/itk-dicom.js"></script>
<script type="module" src="./test/app.js"></script>
<script type="module" src="./dist/demo-app.js"></script>
</body>
</html>
24 changes: 17 additions & 7 deletions dist/dicom/package.json
Expand Up @@ -3,25 +3,29 @@
"version": "0.0.1",
"description": "DICOM IO from itk-wasm",
"type": "module",
"main": "./dist/itk-dicom.umd.cjs",
"module": "./dist/itk-dicom.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/itk-dicom.js",
"require": "./dist/itk-dicom.umd.cjs"
"browser": "./dist/itk-dicom.js",
"node": "./dist/itk-dicom.node.js",
"umd": "./dist/itk-dicom.umd.js",
"default": "./dist/itk-dicom.js"
}
},
"scripts": {
"dev": "vite --port 8173",
"build": "tsc && vite build --sourcemap",
"build:watch": "tsc && vite build --minify false --mode development --watch",
"build": "npm run build:browser && npm run build:node",
"build:node": "rollup -c ./rollup.node.config.js",
"build:browser": "tsc && vite build --sourcemap",
"build:browser:watch": "tsc && vite build --minify false --mode development --watch",
"cypress:open": "npx cypress open",
"cypress:run": "npx cypress run",
"cypress:runChrome": "npx cypress run --browser chrome",
"cypress:runFirefox": "npx cypress run --browser firefox",
"test:debug": "start-server-and-test dev http-get://localhost:8173 cypress:open",
"test": "start-server-and-test dev http-get://localhost:8173 cypress:run",
"test": "npm run test:node && start-server-and-test dev http-get://localhost:8173 cypress:run",
"test:node": "ava",
"test:chrome": "start-server-and-test dev http-get://localhost:8173 cypress:runChrome",
"test:firefox": "start-server-and-test dev http-get://localhost:8173 cypress:runFirefox"
},
Expand All @@ -40,10 +44,16 @@
},
"homepage": "https://wasm.itk.org",
"dependencies": {
"itk-wasm": "^1.0.0-b.21"
"itk-wasm": "^1.0.0-b.27"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^22.0.2",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^14.0.1",
"@rollup/plugin-typescript": "^8.5.0",
"ava": "^4.3.3",
"cypress": "^10.7.0",
"rollup": "^2.79.0",
"rollup-plugin-copy": "^3.4.0",
"start-server-and-test": "^1.14.0",
"typescript": "^4.7.4",
Expand Down
28 changes: 28 additions & 0 deletions dist/dicom/rollup.node.config.js
@@ -0,0 +1,28 @@
import { nodeResolve } from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
import commonjs from '@rollup/plugin-commonjs'
import json from '@rollup/plugin-json'
import { terser } from 'rollup-plugin-terser'

export default {
input: './src/indexNode.ts',
output: [
{
file: './dist/itk-dicom.node.js',
format: 'es',
sourcemap: true,
plugins: [terser(),],
},
],
plugins: [
commonjs({
transformMixedEsModules: true
}),
nodeResolve({
preferBuiltins: true,
browser: false,
}),
typescript(),
json(),
],
}
7 changes: 7 additions & 0 deletions dist/dicom/src/StructuredReportToTextNodeResult.ts
@@ -0,0 +1,7 @@
interface StructuredReportToTextNodeResult {
/** Output text file */
outputText: string

}

export default StructuredReportToTextNodeResult
10 changes: 10 additions & 0 deletions dist/dicom/src/indexNode.ts
@@ -0,0 +1,10 @@


import StructuredReportToTextNodeResult from './StructuredReportToTextNodeResult.js'
export type { StructuredReportToTextNodeResult }

import StructuredReportToTextOptions from './StructuredReportToTextOptions.js'
export type { StructuredReportToTextOptions }

import structuredReportToTextNode from './structuredReportToTextNode.js'
export { structuredReportToTextNode }
2 changes: 2 additions & 0 deletions dist/dicom/src/structuredReportToText.ts
Expand Up @@ -9,7 +9,9 @@ import StructuredReportToTextResult from './StructuredReportToTextResult.js'

/**
* Read a DICOM structured report file and generate a plain text representation
*
* @param {Uint8Array} dicomFile - Input DICOM file
*
* @returns {Promise<StructuredReportToTextResult>} - result object
*/
async function structuredReportToText(
Expand Down
107 changes: 107 additions & 0 deletions dist/dicom/src/structuredReportToTextNode.ts
@@ -0,0 +1,107 @@
import {
TextStream,
InterfaceTypes,
runPipelineNode
} from 'itk-wasm'

import StructuredReportToTextOptions from './StructuredReportToTextOptions.js'
import StructuredReportToTextNodeResult from './StructuredReportToTextNodeResult.js'


import path from 'path'

/**
* Read a DICOM structured report file and generate a plain text representation
*
* @param {Uint8Array} dicomFile - Input DICOM file
*
* @returns {Promise<StructuredReportToTextNodeResult>} - result object
*/
async function structuredReportToTextNode( dicomFile: Uint8Array,
options: StructuredReportToTextOptions = {})
: Promise<StructuredReportToTextNodeResult> {

const desiredOutputs = [
{ type: InterfaceTypes.TextStream },
]
const inputs = [
{ type: InterfaceTypes.BinaryFile, data: { data: dicomFile, path: "file0" } },
]

const args = []
// Inputs
args.push('file0')
// Outputs
args.push('0')
// Options
args.push('--memory-io')
if (options.unknownRelationship) {
args.push('--unknown-relationship')
}
if (options.invalidItemValue) {
args.push('--invalid-item-value')
}
if (options.ignoreConstraints) {
args.push('--ignore-constraints')
}
if (options.ignoreItemErrors) {
args.push('--ignore-item-errors')
}
if (options.skipInvalidItems) {
args.push('--skip-invalid-items')
}
if (options.noDocumentHeader) {
args.push('--no-document-header')
}
if (options.numberNestedItems) {
args.push('--number-nested-items')
}
if (options.shortenLongValues) {
args.push('--shorten-long-values')
}
if (options.printInstanceUid) {
args.push('--print-instance-uid')
}
if (options.printSopclassShort) {
args.push('--print-sopclass-short')
}
if (options.printSopclassLong) {
args.push('--print-sopclass-long')
}
if (options.printSopclassUid) {
args.push('--print-sopclass-uid')
}
if (options.printAllCodes) {
args.push('--print-all-codes')
}
if (options.printInvalidCodes) {
args.push('--print-invalid-codes')
}
if (options.printTemplateId) {
args.push('--print-template-id')
}
if (options.indicateEnhanced) {
args.push('--indicate-enhanced')
}
if (options.printColor) {
args.push('--print-color')
}

const pipelinePath = path.join(path.dirname(import.meta.url.substring(7)), 'pipelines', 'structured-report-to-text')

const {
returnValue,
stderr,
outputs
} = await runPipelineNode(pipelinePath, args, desiredOutputs, inputs)
if (returnValue !== 0) {
throw new Error(stderr)
}

const result = {
outputText: (outputs[0].data as TextStream).data,
}
return result
}

export default structuredReportToTextNode
20 changes: 20 additions & 0 deletions dist/dicom/test/node.js
@@ -0,0 +1,20 @@
import fs from 'fs'
import test from 'ava'
import { structuredReportToTextNode } from '../dist/itk-dicom.node.js'

test('structuredReportToText', async t => {

const fileName = '88.33-comprehensive-SR.dcm'
const testFilePath = `../../build-emscripten/ExternalData/test/Input/${fileName}`

const dicomFileBuffer = fs.readFileSync(testFilePath)
const dicomFile = new Uint8Array(dicomFileBuffer)

const { outputText } = await structuredReportToTextNode(dicomFile)

t.assert(outputText.includes('Comprehensive SR Document'))

const { outputText: outputTextNoHeader } = await structuredReportToTextNode(dicomFile, { noDocumentHeader: true })
t.assert(!outputTextNoHeader.includes('Comprehensive SR Document'))
t.assert(outputTextNoHeader.includes('Breast Imaging Report'))
})
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Expand Up @@ -121,7 +121,7 @@
"puppeteer": "^10.4.0",
"readable-stream": "^3.6.0",
"resolve-typescript-plugin": "^1.2.0",
"rollup": "^2.58.0",
"rollup": "^2.79.0",
"rollup-plugin-terser": "^7.0.2",
"semantic-release": "^19.0.2",
"shx": "^0.3.4",
Expand All @@ -144,7 +144,7 @@
"axios": "^0.23.0",
"commander": "^9.4.0",
"fs-extra": "^10.0.0",
"mime-types": "^2.1.33",
"mime-types": "^2.1.35",
"promise-file-reader": "^1.0.3",
"webworker-promise": "^0.4.2"
},
Expand Down

0 comments on commit 3e5feb1

Please sign in to comment.