From 3d4eb6c057419bb4d63469391b3331f1091f4ac0 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Fri, 22 Sep 2023 20:06:38 -0400 Subject: [PATCH 1/4] feat(bindgen): output file demo support --- .../typescript/demo/input-parameters-demo-html.js | 2 ++ .../typescript/demo/input-parameters-demo-typescript.js | 9 ++++++++- .../typescript/demo/interface-functions-demo-html.js | 5 +++++ .../demo/interface-functions-demo-typescript.js | 6 ++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/bindgen/typescript/demo/input-parameters-demo-html.js b/src/bindgen/typescript/demo/input-parameters-demo-html.js index 9b8659ac6..13817cf06 100644 --- a/src/bindgen/typescript/demo/input-parameters-demo-html.js +++ b/src/bindgen/typescript/demo/input-parameters-demo-html.js @@ -26,6 +26,8 @@ function inputParametersDemoHtml (functionName, prefix, indent, parameter, requi } break case 'TEXT': + case 'OUTPUT_TEXT_FILE': + case 'OUTPUT_BINARY_FILE': result += `${prefix}${indent}\n` break case 'INT': diff --git a/src/bindgen/typescript/demo/input-parameters-demo-typescript.js b/src/bindgen/typescript/demo/input-parameters-demo-typescript.js index 91224982b..eeeaf7f3a 100644 --- a/src/bindgen/typescript/demo/input-parameters-demo-typescript.js +++ b/src/bindgen/typescript/demo/input-parameters-demo-typescript.js @@ -54,9 +54,16 @@ function inputParametersDemoTypeScript(functionName, indent, parameter, required result += `${indent}})\n\n` break case 'TEXT': + case 'OUTPUT_TEXT_FILE': + case 'OUTPUT_BINARY_FILE': result += `${indent}const ${inputIdentifier} = document.querySelector('#${functionName}Inputs sl-input[name=${parameter.name}]')\n` result += `${indent}${inputIdentifier}.addEventListener('sl-change', (event) => {\n` - result += `${indent}${indent}model.${modelProperty}.set("${parameterName}", ${inputIdentifier}.value)\n` + if (parameter.itemsExpectedMax > 1) { + result += `${indent}${indent}const values = ${inputIdentifier}.value.split(',').map(s => s.trim())\n` + result += `${indent}${indent}model.${modelProperty}.set("${parameterName}", values)\n` + } else { + result += `${indent}${indent}model.${modelProperty}.set("${parameterName}", ${inputIdentifier}.value)\n` + } result += `${indent}})\n\n` break case 'BOOL': diff --git a/src/bindgen/typescript/demo/interface-functions-demo-html.js b/src/bindgen/typescript/demo/interface-functions-demo-html.js index c48034685..55e2b41b2 100644 --- a/src/bindgen/typescript/demo/interface-functions-demo-html.js +++ b/src/bindgen/typescript/demo/interface-functions-demo-html.js @@ -31,6 +31,11 @@ function interfaceFunctionsDemoHtml(interfaceJson, functionName, useCamelCase) { result += inputParametersDemoHtml(functionName, prefix, indent, parameter, false, useCamelCase) }) } + interfaceJson.outputs.forEach((output) => { + if (output.type.includes('FILE')) { + result += inputParametersDemoHtml(functionName, prefix, indent, output, true, useCamelCase) + } + }) result += `${prefix}\n` const loadSampleInputsId = useCamelCase ? 'loadSampleInputs' : 'load-sample-inputs' diff --git a/src/bindgen/typescript/demo/interface-functions-demo-typescript.js b/src/bindgen/typescript/demo/interface-functions-demo-typescript.js index 24d42192c..e13c53fa5 100644 --- a/src/bindgen/typescript/demo/interface-functions-demo-typescript.js +++ b/src/bindgen/typescript/demo/interface-functions-demo-typescript.js @@ -128,6 +128,12 @@ class ${functionNamePascalCase}Model { }) } + interfaceJson.outputs.forEach((output) => { + if (output.type.includes('FILE')) { + result += inputParametersDemoTypeScript(functionName, indent, output, true, 'options') + } + }) + result += `${indent}// ----------------------------------------------\n${indent}// Outputs` interfaceJson.outputs.forEach((output) => { result += outputDemoTypeScript(functionName, '', indent, output) From 6771346383eb75b1633861cf21b3366a2ae8df18 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sat, 23 Sep 2023 17:52:26 -0400 Subject: [PATCH 2/4] fix(bindgen): demo preRun execution for production builds --- .../interface-functions-demo-typescript.js | 24 ++++++++++++++----- src/bindgen/typescript/typescript-bindings.js | 13 +++++----- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/bindgen/typescript/demo/interface-functions-demo-typescript.js b/src/bindgen/typescript/demo/interface-functions-demo-typescript.js index e13c53fa5..013591c0c 100644 --- a/src/bindgen/typescript/demo/interface-functions-demo-typescript.js +++ b/src/bindgen/typescript/demo/interface-functions-demo-typescript.js @@ -139,8 +139,14 @@ class ${functionNamePascalCase}Model { result += outputDemoTypeScript(functionName, '', indent, output) }) - result += `\n${indent}const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + result += `\n${indent}const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === '${functionName}-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== '${functionName}') { @@ -149,10 +155,16 @@ class ${functionNamePascalCase}Model { url.search = params window.history.replaceState({ functionName: '${functionName}' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === '${functionName}') { + preRun() } }) diff --git a/src/bindgen/typescript/typescript-bindings.js b/src/bindgen/typescript/typescript-bindings.js index 0c5994d79..c21f51bff 100644 --- a/src/bindgen/typescript/typescript-bindings.js +++ b/src/bindgen/typescript/typescript-bindings.js @@ -144,13 +144,12 @@ function typescriptBindings (outputDir, buildDir, wasmBinaries, options, forNode readmePipelines += readmeResult }) - demoFunctionsTypeScript += `\nconst tabGroup = document.querySelector('sl-tab-group') -const params = new URLSearchParams(window.location.search) -if (params.has('functionName')) { - const functionName = params.get('functionName') - tabGroup.show(functionName + '-panel') -} else { - tabGroup.show('${firstFunctionName}-panel') + demoFunctionsTypeScript += `\nconst params = new URLSearchParams(window.location.search) +if (!params.has('functionName')) { + params.set('functionName', '${firstFunctionName}') + const url = new URL(document.location) + url.search = params + window.history.replaceState({ functionName: '${firstFunctionName}' }, '', url) } ` From 0dd2551c4220c930556e2e63ec69f0dabc709791 Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sat, 23 Sep 2023 17:56:29 -0400 Subject: [PATCH 3/4] chore: package bindgen updates --- .../compare-double-images-controller.ts | 24 ++++++++++++++----- ...ompare-double-images-load-sample-inputs.ts | 4 ++-- .../demo-app/vector-magnitude-controller.ts | 24 ++++++++++++++----- .../vector-magnitude-load-sample-inputs.ts | 4 ++-- .../demo-app/compress-stringify-controller.ts | 24 ++++++++++++++----- .../typescript/test/browser/demo-app/index.ts | 11 ++++----- .../parse-string-decompress-controller.ts | 24 ++++++++++++++----- .../apply-presentation-state-to-image-node.ts | 4 ++-- .../src/read-dicom-encapsulated-pdf-node.ts | 2 +- .../src/read-image-dicom-file-series-node.ts | 2 -- .../src/structured-report-to-html-node.ts | 4 ++-- .../src/structured-report-to-text-node.ts | 2 +- ...-presentation-state-to-image-controller.ts | 24 ++++++++++++++----- .../typescript/test/browser/demo-app/index.ts | 11 ++++----- .../demo-app/read-dicom-tags-controller.ts | 24 ++++++++++++++----- .../structured-report-to-text-controller.ts | 24 ++++++++++++++----- 16 files changed, 146 insertions(+), 66 deletions(-) diff --git a/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-controller.ts b/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-controller.ts index 5e265a17f..dc3841ac5 100644 --- a/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-controller.ts +++ b/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-controller.ts @@ -132,8 +132,14 @@ class CompareDoubleImagesController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'compareDoubleImages-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'compareDoubleImages') { @@ -142,10 +148,16 @@ class CompareDoubleImagesController { url.search = params window.history.replaceState({ functionName: 'compareDoubleImages' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'compareDoubleImages') { + preRun() } }) diff --git a/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-load-sample-inputs.ts b/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-load-sample-inputs.ts index db0a3aeb3..795a18fae 100644 --- a/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-load-sample-inputs.ts +++ b/packages/compare-images/typescript/test/browser/demo-app/compare-double-images-load-sample-inputs.ts @@ -1,7 +1,7 @@ // Generated file. To retain edits, remove this comment. export default null -// export default async function compareDoubleImagesLoadSampleInputs (model) { +// export default async function compareDoubleImagesLoadSampleInputs (model, preRun=false) { // Load sample inputs for the compareDoubleImages function. // @@ -25,4 +25,4 @@ export default null // Use this function to run the pipeline when this tab group is select. // This will load the web worker if it is not already loaded, download the wasm module, and allocate memory in the wasm model. // Set this to `false` if sample inputs are very large or sample pipeline computation is long. -export usePreRun = true +export const usePreRun = true diff --git a/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-controller.ts b/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-controller.ts index 6cd6e571e..6c9a3c94b 100644 --- a/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-controller.ts +++ b/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-controller.ts @@ -73,8 +73,14 @@ class VectorMagnitudeController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'vectorMagnitude-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'vectorMagnitude') { @@ -83,10 +89,16 @@ class VectorMagnitudeController { url.search = params window.history.replaceState({ functionName: 'vectorMagnitude' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'vectorMagnitude') { + preRun() } }) diff --git a/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-load-sample-inputs.ts b/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-load-sample-inputs.ts index 1886663e3..9851da352 100644 --- a/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-load-sample-inputs.ts +++ b/packages/compare-images/typescript/test/browser/demo-app/vector-magnitude-load-sample-inputs.ts @@ -1,7 +1,7 @@ // Generated file. To retain edits, remove this comment. export default null -// export default async function vectorMagnitudeLoadSampleInputs (model) { +// export default async function vectorMagnitudeLoadSampleInputs (model, preRun=false) { // Load sample inputs for the vectorMagnitude function. // @@ -25,4 +25,4 @@ export default null // Use this function to run the pipeline when this tab group is select. // This will load the web worker if it is not already loaded, download the wasm module, and allocate memory in the wasm model. // Set this to `false` if sample inputs are very large or sample pipeline computation is long. -export usePreRun = true +export const usePreRun = true diff --git a/packages/compress-stringify/typescript/test/browser/demo-app/compress-stringify-controller.ts b/packages/compress-stringify/typescript/test/browser/demo-app/compress-stringify-controller.ts index 02fae44e0..fbf209c3f 100644 --- a/packages/compress-stringify/typescript/test/browser/demo-app/compress-stringify-controller.ts +++ b/packages/compress-stringify/typescript/test/browser/demo-app/compress-stringify-controller.ts @@ -79,8 +79,14 @@ class CompressStringifyController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'compressStringify-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'compressStringify') { @@ -89,10 +95,16 @@ class CompressStringifyController { url.search = params window.history.replaceState({ functionName: 'compressStringify' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'compressStringify') { + preRun() } }) diff --git a/packages/compress-stringify/typescript/test/browser/demo-app/index.ts b/packages/compress-stringify/typescript/test/browser/demo-app/index.ts index 53a88f11e..a539d23a6 100644 --- a/packages/compress-stringify/typescript/test/browser/demo-app/index.ts +++ b/packages/compress-stringify/typescript/test/browser/demo-app/index.ts @@ -11,11 +11,10 @@ compressStringify.setPipelineWorkerUrl(pipelineWorkerUrl) import './compress-stringify-controller.js' import './parse-string-decompress-controller.js' -const tabGroup = document.querySelector('sl-tab-group') const params = new URLSearchParams(window.location.search) -if (params.has('functionName')) { - const functionName = params.get('functionName') - tabGroup.show(functionName + '-panel') -} else { - tabGroup.show('compressStringify-panel') +if (!params.has('functionName')) { + params.set('functionName', 'compressStringify') + const url = new URL(document.location) + url.search = params + window.history.replaceState({ functionName: 'compressStringify' }, '', url) } diff --git a/packages/compress-stringify/typescript/test/browser/demo-app/parse-string-decompress-controller.ts b/packages/compress-stringify/typescript/test/browser/demo-app/parse-string-decompress-controller.ts index 4a6e97c74..88026ce20 100644 --- a/packages/compress-stringify/typescript/test/browser/demo-app/parse-string-decompress-controller.ts +++ b/packages/compress-stringify/typescript/test/browser/demo-app/parse-string-decompress-controller.ts @@ -69,8 +69,14 @@ class ParseStringDecompressController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'parseStringDecompress-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'parseStringDecompress') { @@ -79,10 +85,16 @@ class ParseStringDecompressController { url.search = params window.history.replaceState({ functionName: 'parseStringDecompress' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'parseStringDecompress') { + preRun() } }) diff --git a/packages/dicom/typescript/src/apply-presentation-state-to-image-node.ts b/packages/dicom/typescript/src/apply-presentation-state-to-image-node.ts index 2c4649c27..1ec54ea88 100644 --- a/packages/dicom/typescript/src/apply-presentation-state-to-image-node.ts +++ b/packages/dicom/typescript/src/apply-presentation-state-to-image-node.ts @@ -37,8 +37,8 @@ async function applyPresentationStateToImageNode( { type: InterfaceTypes.Image }, ] - mountDirs.add(path.dirname(imageIn as string)) - mountDirs.add(path.dirname(presentationStateFile as string)) + mountDirs.add(path.dirname(value as string)) + mountDirs.add(path.dirname(value as string)) const inputs: Array = [ ] diff --git a/packages/dicom/typescript/src/read-dicom-encapsulated-pdf-node.ts b/packages/dicom/typescript/src/read-dicom-encapsulated-pdf-node.ts index cbbf03508..34711c764 100644 --- a/packages/dicom/typescript/src/read-dicom-encapsulated-pdf-node.ts +++ b/packages/dicom/typescript/src/read-dicom-encapsulated-pdf-node.ts @@ -33,7 +33,7 @@ async function readDicomEncapsulatedPdfNode( { type: InterfaceTypes.BinaryStream }, ] - mountDirs.add(path.dirname(dicomFile as string)) + mountDirs.add(path.dirname(value as string)) const inputs: Array = [ ] diff --git a/packages/dicom/typescript/src/read-image-dicom-file-series-node.ts b/packages/dicom/typescript/src/read-image-dicom-file-series-node.ts index 04e549f51..29974fe86 100644 --- a/packages/dicom/typescript/src/read-image-dicom-file-series-node.ts +++ b/packages/dicom/typescript/src/read-image-dicom-file-series-node.ts @@ -54,10 +54,8 @@ async function readImageDicomFileSeriesNode( args.push('--input-images') options.inputImages.forEach((value) => { - mountDirs.add(path.dirname(value as string)) mountDirs.add(path.dirname(value as string)) args.push(value as string) - }) } if (typeof options.singleSortedSeries !== "undefined") { diff --git a/packages/dicom/typescript/src/structured-report-to-html-node.ts b/packages/dicom/typescript/src/structured-report-to-html-node.ts index 44603d164..b8598613c 100644 --- a/packages/dicom/typescript/src/structured-report-to-html-node.ts +++ b/packages/dicom/typescript/src/structured-report-to-html-node.ts @@ -33,7 +33,7 @@ async function structuredReportToHtmlNode( { type: InterfaceTypes.TextStream }, ] - mountDirs.add(path.dirname(dicomFile as string)) + mountDirs.add(path.dirname(value as string)) const inputs: Array = [ ] @@ -127,7 +127,7 @@ async function structuredReportToHtmlNode( } if (typeof options.cssFile !== "undefined") { const cssFile = options.cssFile - mountDirs.add(path.dirname(cssFile as string)) + mountDirs.add(path.dirname(value as string)) args.push('--css-file') const name = cssFile as string diff --git a/packages/dicom/typescript/src/structured-report-to-text-node.ts b/packages/dicom/typescript/src/structured-report-to-text-node.ts index a6e9c2cc9..2c93962c1 100644 --- a/packages/dicom/typescript/src/structured-report-to-text-node.ts +++ b/packages/dicom/typescript/src/structured-report-to-text-node.ts @@ -33,7 +33,7 @@ async function structuredReportToTextNode( { type: InterfaceTypes.TextStream }, ] - mountDirs.add(path.dirname(dicomFile as string)) + mountDirs.add(path.dirname(value as string)) const inputs: Array = [ ] diff --git a/packages/dicom/typescript/test/browser/demo-app/apply-presentation-state-to-image-controller.ts b/packages/dicom/typescript/test/browser/demo-app/apply-presentation-state-to-image-controller.ts index fde102e8e..3c3f8c7d1 100644 --- a/packages/dicom/typescript/test/browser/demo-app/apply-presentation-state-to-image-controller.ts +++ b/packages/dicom/typescript/test/browser/demo-app/apply-presentation-state-to-image-controller.ts @@ -118,8 +118,14 @@ class ApplyPresentationStateToImageController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'applyPresentationStateToImage-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'applyPresentationStateToImage') { @@ -128,10 +134,16 @@ class ApplyPresentationStateToImageController { url.search = params window.history.replaceState({ functionName: 'applyPresentationStateToImage' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'applyPresentationStateToImage') { + preRun() } }) diff --git a/packages/dicom/typescript/test/browser/demo-app/index.ts b/packages/dicom/typescript/test/browser/demo-app/index.ts index bdea1a24c..0a1459759 100644 --- a/packages/dicom/typescript/test/browser/demo-app/index.ts +++ b/packages/dicom/typescript/test/browser/demo-app/index.ts @@ -15,11 +15,10 @@ import './structured-report-to-text-controller.js' import './read-dicom-tags-controller.js' import './read-image-dicom-file-series-controller.js' -const tabGroup = document.querySelector('sl-tab-group') const params = new URLSearchParams(window.location.search) -if (params.has('functionName')) { - const functionName = params.get('functionName') - tabGroup.show(functionName + '-panel') -} else { - tabGroup.show('applyPresentationStateToImage-panel') +if (!params.has('functionName')) { + params.set('functionName', 'applyPresentationStateToImage') + const url = new URL(document.location) + url.search = params + window.history.replaceState({ functionName: 'applyPresentationStateToImage' }, '', url) } diff --git a/packages/dicom/typescript/test/browser/demo-app/read-dicom-tags-controller.ts b/packages/dicom/typescript/test/browser/demo-app/read-dicom-tags-controller.ts index 96c9446cb..d78dc360a 100644 --- a/packages/dicom/typescript/test/browser/demo-app/read-dicom-tags-controller.ts +++ b/packages/dicom/typescript/test/browser/demo-app/read-dicom-tags-controller.ts @@ -77,8 +77,14 @@ class ReadDicomTagsController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'readDicomTags-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'readDicomTags') { @@ -87,10 +93,16 @@ class ReadDicomTagsController { url.search = params window.history.replaceState({ functionName: 'readDicomTags' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'readDicomTags') { + preRun() } }) diff --git a/packages/dicom/typescript/test/browser/demo-app/structured-report-to-text-controller.ts b/packages/dicom/typescript/test/browser/demo-app/structured-report-to-text-controller.ts index f9d84ffab..28239d798 100644 --- a/packages/dicom/typescript/test/browser/demo-app/structured-report-to-text-controller.ts +++ b/packages/dicom/typescript/test/browser/demo-app/structured-report-to-text-controller.ts @@ -149,8 +149,14 @@ class StructuredReportToTextController { } }) - const tabGroup = document.querySelector('sl-tab-group') - tabGroup.addEventListener('sl-tab-show', async (event) => { + const preRun = async () => { + if (!this.webWorker && loadSampleInputs && usePreRun) { + await loadSampleInputs(model, true) + await this.run() + } + } + + const onSelectTab = async (event) => { if (event.detail.name === 'structuredReportToText-panel') { const params = new URLSearchParams(window.location.search) if (!params.has('functionName') || params.get('functionName') !== 'structuredReportToText') { @@ -159,10 +165,16 @@ class StructuredReportToTextController { url.search = params window.history.replaceState({ functionName: 'structuredReportToText' }, '', url) } - if (!this.webWorker && loadSampleInputs && usePreRun) { - await loadSampleInputs(model, true) - await this.run() - } + await preRun() + } + } + + const tabGroup = document.querySelector('sl-tab-group') + tabGroup.addEventListener('sl-tab-show', onSelectTab) + document.addEventListener('DOMContentLoaded', () => { + const params = new URLSearchParams(window.location.search) + if (params.has('functionName') && params.get('functionName') === 'structuredReportToText') { + preRun() } }) From 9dc3181921ffc021a121f06e740b424578b249de Mon Sep 17 00:00:00 2001 From: Matt McCormick Date: Sat, 23 Sep 2023 22:19:23 -0400 Subject: [PATCH 4/4] fix(bindgen): support for array outputs --- .../demo/output-demo-run-typescript.js | 12 +++- .../typescript/demo/output-demo-typescript.js | 18 ++++-- src/bindgen/typescript/function-module.js | 58 ++++++++++++++++--- src/bindgen/typescript/results-module.js | 6 +- 4 files changed, 78 insertions(+), 16 deletions(-) diff --git a/src/bindgen/typescript/demo/output-demo-run-typescript.js b/src/bindgen/typescript/demo/output-demo-run-typescript.js index 9d416331d..fd38837b5 100644 --- a/src/bindgen/typescript/demo/output-demo-run-typescript.js +++ b/src/bindgen/typescript/demo/output-demo-run-typescript.js @@ -12,7 +12,11 @@ function outputDemoRunTypeScript(functionName, prefix, indent, parameter) { result += `${prefix}${indent}${parameterName}OutputDownload.disabled = false\n` result += `${prefix}${indent}const ${parameterName}Output = document.getElementById("${functionName}-${parameter.name}-details")\n` const textDataProp = parameter.type.includes('FILE') ? '.data' : '' - result += `${prefix}${indent}${parameterName}Output.innerHTML = \`
$\{globalThis.escapeHtml(${parameterName}${textDataProp}.substring(0, 1024).toString() + ' ...')}
\`\n` + if (parameter.itemsExpectedMax > 1) { + result += `${prefix}${indent}${parameterName}Output.innerHTML = \`
$\{globalThis.escapeHtml(JSON.stringify(${parameterName}))}
\`\n` + } else { + result += `${prefix}${indent}${parameterName}Output.innerHTML = \`
$\{globalThis.escapeHtml(${parameterName}${textDataProp}.substring(0, 1024).toString() + ' ...')}
\`\n` + } result += `${prefix}${indent}${parameterName}Output.disabled = false\n` } break @@ -23,7 +27,11 @@ function outputDemoRunTypeScript(functionName, prefix, indent, parameter) { result += `${prefix}${indent}${parameterName}OutputDownload.disabled = false\n` result += `${prefix}${indent}const ${parameterName}Output = document.getElementById("${functionName}-${parameter.name}-details")\n` const binaryDataProp = parameter.type.includes('FILE') ? '.data' : '' - result += `${prefix}${indent}${parameterName}Output.innerHTML = \`
$\{globalThis.escapeHtml(${parameterName}${binaryDataProp}.subarray(0, 1024).toString() + ' ...')}
\`\n` + if (parameter.itemsExpectedMax > 1) { + result += `${prefix}${indent}${parameterName}Output.innerHTML = \`
$\{globalThis.escapeHtml(JSON.stringify(${parameterName})}
\`\n` + } else { + result += `${prefix}${indent}${parameterName}Output.innerHTML = \`
$\{globalThis.escapeHtml(${parameterName}${binaryDataProp}.subarray(0, 1024).toString() + ' ...')}
\`\n` + } result += `${prefix}${indent}${parameterName}Output.disabled = false\n` } break diff --git a/src/bindgen/typescript/demo/output-demo-typescript.js b/src/bindgen/typescript/demo/output-demo-typescript.js index 9da9e0bda..c2fbfcb15 100644 --- a/src/bindgen/typescript/demo/output-demo-typescript.js +++ b/src/bindgen/typescript/demo/output-demo-typescript.js @@ -14,8 +14,13 @@ function outputDemoTypeScript(functionName, prefix, indent, parameter) { result += `${prefix}${indent}${indent}event.stopPropagation()\n` result += `${prefix}${indent}${indent}if (model.outputs.has("${parameterName}")) {\n` const textDataProp = parameter.type.includes('FILE') ? '.data' : '' - const downloadFileName = parameter.type.includes('FILE') ? `model.outputs.get("${parameterName}").path`: `"${parameterName}.txt"` - result += `${prefix}${indent}${indent}${indent}globalThis.downloadFile(new TextEncoder().encode(model.outputs.get("${parameterName}")${textDataProp}), ${downloadFileName})\n` + if (parameter.itemsExpectedMax > 1) { + const downloadFileName = parameter.type.includes('FILE') ? `o.path`: `"${parameterName}.txt"` + result += `${prefix}${indent}${indent}${indent}model.outputs.get("${parameterName}").forEach((o) => globalThis.downloadFile(new TextEncoder().encode(o${textDataProp}), ${downloadFileName}))\n` + } else { + const downloadFileName = parameter.type.includes('FILE') ? `model.outputs.get("${parameterName}").path`: `"${parameterName}.txt"` + result += `${prefix}${indent}${indent}${indent}globalThis.downloadFile(new TextEncoder().encode(model.outputs.get("${parameterName}")${textDataProp}), ${downloadFileName})\n` + } result += `${prefix}${indent}${indent}}\n` result += `${prefix}${indent}})\n` } @@ -29,8 +34,13 @@ function outputDemoTypeScript(functionName, prefix, indent, parameter) { result += `${prefix}${indent}${indent}event.stopPropagation()\n` result += `${prefix}${indent}${indent}if (model.outputs.has("${parameterName}")) {\n` const binaryDataProp = parameter.type.includes('FILE') ? '.data' : '' - const downloadFileName = parameter.type.includes('FILE') ? `model.outputs.get("${parameterName}").path`: `"${parameterName}.bin"` - result += `${prefix}${indent}${indent}${indent}globalThis.downloadFile(model.outputs.get("${parameterName}")${binaryDataProp}, ${downloadFileName})\n` + if (parameter.itemsExpectedMax > 1) { + const downloadFileName = parameter.type.includes('FILE') ? `o.path`: `"${parameterName}.bin"` + result += `${prefix}${indent}${indent}${indent}model.outputs.get("${parameterName}").forEach((o) => globalThis.downloadFile(o${binaryDataProp}, ${downloadFileName}))\n` + } else { + const downloadFileName = parameter.type.includes('FILE') ? `model.outputs.get("${parameterName}").path`: `"${parameterName}.bin"` + result += `${prefix}${indent}${indent}${indent}globalThis.downloadFile(model.outputs.get("${parameterName}")${binaryDataProp}, ${downloadFileName})\n` + } result += `${prefix}${indent}${indent}}\n` result += `${prefix}${indent}})\n` } diff --git a/src/bindgen/typescript/function-module.js b/src/bindgen/typescript/function-module.js index 55b0497d7..f497bd6d6 100644 --- a/src/bindgen/typescript/function-module.js +++ b/src/bindgen/typescript/function-module.js @@ -195,6 +195,7 @@ function functionModule (srcOutputDir, forNode, interfaceJson, modulePascalCase, } }) } + let haveArray = false functionContent += ' const desiredOutputs: Array = [\n' interfaceJson.outputs.forEach((output) => { if (interfaceJsonTypeToInterfaceType.has(output.type)) { @@ -204,6 +205,7 @@ function functionModule (srcOutputDir, forNode, interfaceJson, modulePascalCase, const defaultData = interfaceType === 'BinaryFile' ? 'new Uint8Array()' : "''" const isArray = output.itemsExpectedMax > 1 if (isArray) { + haveArray = true functionContent += ` ...${camel}PipelineOutputs,\n` } else { functionContent += ` { type: InterfaceTypes.${interfaceType}, data: { path: ${camel}Path, data: ${defaultData} }},\n` @@ -214,6 +216,30 @@ function functionModule (srcOutputDir, forNode, interfaceJson, modulePascalCase, } }) functionContent += ' ]\n\n' + if (haveArray) { + functionContent += ` let outputIndex = 0\n` + interfaceJson.outputs.forEach((output) => { + if (interfaceJsonTypeToInterfaceType.has(output.type)) { + const interfaceType = interfaceJsonTypeToInterfaceType.get(output.type) + if (!forNode && interfaceType.includes('File')) { + const camel = camelCase(output.name) + const isArray = output.itemsExpectedMax > 1 + if (isArray) { + functionContent += ` const ${camel}Start = outputIndex\n` + functionContent += ` outputIndex += options.${camel}Path ? options.${camel}Path.length : 0\n` + functionContent += ` const ${camel}End = outputIndex\n` + } else { + functionContent += ` const ${camel}Index = outputIndex\n` + functionContent += ` ++outputIndex\n` + } + } else if (!interfaceType.includes('File')) { + functionContent += ` const ${camel}Index = outputIndex\n` + functionContent += ` ++outputIndex\n` + } + } + }) + functionContent += '\n' + } interfaceJson.inputs.forEach((input) => { if (interfaceJsonTypeToInterfaceType.has(input.type)) { const interfaceType = interfaceJsonTypeToInterfaceType.get(input.type) @@ -295,13 +321,12 @@ function functionModule (srcOutputDir, forNode, interfaceJson, modulePascalCase, functionContent += name if (isArray) { functionContent += ` options.${camel}Path?.forEach((p) => args.push(p))\n` + if (forNode && interfaceType.includes('File')) { + functionContent += ` options.${camel}Path?.forEach((p) => mountDirs.add(path.dirname(p)))\n` + } } else { functionContent += ` args.push(${camel}Name)\n` - } - if (forNode && interfaceType.includes('File')) { - if (isArray) { - functionContent += ` options.${camel}Path?.forEach((p) => mountDirs.add(path.dirname(p)))\n` - } else { + if (forNode && interfaceType.includes('File')) { functionContent += ` mountDirs.add(path.dirname(${camel}Name))\n` } } @@ -414,12 +439,31 @@ function functionModule (srcOutputDir, forNode, interfaceJson, modulePascalCase, interfaceJson.outputs.forEach((output, index) => { const camel = camelCase(output.name) const interfaceType = interfaceJsonTypeToInterfaceType.get(output.type) + const outputIndex = haveArray ? `${camel}Index` : index.toString() if (interfaceType.includes('TextStream') || interfaceType.includes('BinaryStream')) { - functionContent += ` ${camel}: (outputs[${index.toString()}].data as ${interfaceType}).data,\n` + if (haveArray) { + const isArray = output.itemsExpectedMax > 1 + if (isArray) { + functionContent += ` ${camel}: (outputs.slice(${camel}Start, ${camel}End).map(o => (o.data as ${interfaceType}).data)),\n` + } else { + functionContent += ` ${camel}: (outputs[${camel}Index].data as ${interfaceType}).data),\n` + } + } else { + functionContent += ` ${camel}: (outputs[${outputIndex}].data as ${interfaceType}).data,\n` + } } else if (forNode && interfaceType.includes('File')) { // Written to disk } else { - functionContent += ` ${camel}: outputs[${index.toString()}].data as ${interfaceType},\n` + if (haveArray) { + const isArray = output.itemsExpectedMax > 1 + if (isArray) { + functionContent += ` ${camel}: outputs.slice(${camel}Start, ${camel}End).map(o => (o.data as ${interfaceType})),\n` + } else { + functionContent += ` ${camel}: outputs[${camel}Index].data as ${interfaceType},\n` + } + } else { + functionContent += ` ${camel}: outputs[${outputIndex}].data as ${interfaceType},\n` + } } }) functionContent += ' }\n' diff --git a/src/bindgen/typescript/results-module.js b/src/bindgen/typescript/results-module.js index be66416b5..e920a8220 100644 --- a/src/bindgen/typescript/results-module.js +++ b/src/bindgen/typescript/results-module.js @@ -31,16 +31,16 @@ function resultsModule (srcOutputDir, interfaceJson, forNode, modulePascalCase, if (outputType === 'JsonCompatible') { resultsImportTypes.add('JsonCompatible') } + const outputArray = output.itemsExpectedMax > 1 ? '[]' : '' if (forNode && outputType.includes('File')) { // Written to disk } else { if (typesRequireImport.includes(outputType)) { resultsImportTypes.add(outputType) } - resultContent += ` ${camelCase(output.name)}: ${outputType}\n\n` + resultContent += ` ${camelCase(output.name)}: ${outputType}${outputArray}\n\n` } - const readmeOutputArray = output.itemsExpectedMax > 1 ? '[]' : '' - readmeResultTable.push([`\`${camelCase(output.name)}\``, `*${outputType}${readmeOutputArray}*`, output.description]) + readmeResultTable.push([`\`${camelCase(output.name)}\``, `*${outputType}${outputArray}*`, output.description]) }) readmeResult += markdownTable(readmeResultTable, { align: ['c', 'c', 'l'] }) + '\n'