npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@radicalimaging/static-wado-webserver

v1.5.0

Published

Webserver to serve a static-wado repo

Downloads

172

Readme

@radicalimaging/static-wado-webserver

The static wado webserver demonstrates how to serve up the files generated by static-wado-creator to provide a DICOMweb set of services, while allowing certain services to be modified by adding a custom extension.

Pre-requisites

View root pre-requisites section pre-requisites

Development

View root development section development. Additionally, this component is developed using ecmascript modules, so be aware that most of the code uses the .mjs module extension for javascript.

Installation

The component can be installed as a global module via:

npm install -g

Usage

There is a command line tool, installed as above, that provides an extendible web service. That is run installed, or uninstalled as:

dicomwebserver
or
node bin/dicomwebserver.mjs

This will serve up the files in ~/ohif and ~/dicomweb in the following way:

  1. Files in ohif are served according to their extension, using a .gz extension version of it when present, served to http://localhost:5000 by default.
  2. For the OHIF files, if the URL doesn't match a dicomweb url, and is otherwise not found, serve up ~/ohif/index.html
  3. For the DICOMweb files, serve it up as follows:
  • For studies, series and instances queries, serve up the index.json.gz file by default
  • For metadata, serve up the metadata.gz file as 'application/json'
  • For frames retrieval, serve up the raw file name directly, but if not found, fallback to the frame number.gz, as a GZIP file
  1. Provide a studyQuery result that reads the studies/index.json.gz file and filters it according to the search criteria

Default Configuration Files

The tool looks for a JSON5 configuration file (which is JSON + comments basically), located either in ./static-wado.json5 or else in ~/static-wado.json5. This configuration file can override settings such as the directory that stores the client, or the port number on the web service etc. These configuration values are then further modified by command-line settings.

Alternatively, the settings file to use can be specified with the -c or --configuration setting, passing it a file name to read as a JSON5 file (it will add the extension if not present). The format of the file looks like this:

{
  // Defaults that apply to static wado generally
  staticWadoConfig {
    rootDir: '/data/dicomweb',
  },
  // Defaults that apply to the DICOMweb server
  dicomWebServerConfig: {
    studyQuery: "exampleCustomPlugin",
    clientDir: "~/ohif",
    port: 8080,
  },
  // plugin locations, used to load custom plugins
  plugins: {
    // Where to load the custom plugin from.
    // This is COMPLETELY code injection, so require access control both to the static-wado.json5 file and the specified file
    exampleCustomPlugin: "/src/exampleCustomPlugin/dist/dist.js",
  },
}

Configuration Values

  • The rootDir parameter sets the default root directory for storing the DICOMweb data, or for serving it from.
  • clientDir specifies the location of the client files
  • port specifies the default port for the web server to run on (do NOT specify this in staticcWadoConfig, as the SCP uses the same name)
  • studyQuery specifies the name of a plugin to use that provides study level query capabilities
  • accessCheck specifies the name of a plugin that checks to see if the study is available in the dicomweb dir
  • stowCommands is an array of command lines that will be passed a set of filenames to store.
  • corsOptions specifies an object with options to set up cors. CORS is not applied when this property is not present or if there is no origin (inner property) defined.

stowCommands to store to DICOM

Assuming you have dcm4che installed, then you can configure stowCommands like this:

stowComands: ["mkdicomweb", "dcmsnd -L SCUNAME SCPName@hostname:104"],

to configure to store to the local mkdicomweb plugin, plus SCPName on host hostname on port 104.

Configure external viewer

Webserver can also be integrated with external viewer server. In order to achieve that configuration file must contain:

 {
    ...
    corsOptions: {
      enabled: true,
      origin: ['http://viewer-origin:port]
      ...other configs
    }

 }

This will ensure webserver accepts cross origins requests. @see {@link https://www.npmjs.com/package/cors#configuration-options} for more options properties.

Plugins

There are several plugins currently defined:

  • studyQueryReadIndex reads the studies/index.json.gz file and sub-selects it to generate the query response.

  • studiesQueryToScp queries a remote DIMSE service to find the response for the study level data.

    The following plugins are planned:

  • retrieveCMove will check if the study is locally available, and if not, will perform a c-move to the specified scp destination

  • studyQueryDb does a query for studies against a database. Also, it stores to the given destination.

Additional external plugins can be defined to extend the base router by defining a webserverPlugins array in the configuration file - ex:

    clientGroup { plugins: [
      {
        pluginModule: 'my-plugins',
        pluginName: 'aPlugin',
        pluginRoute: '/endpoint1/:myParam',
      },
      {
        pluginModule: 'my-plugins',
        pluginName: 'bPlugin',
        pluginRoute: '/endpoint2',
      },
    ]}

The plugin is imported dynamically using the pluginModule and pluginModuleName, and must define a setRoute method that registers the pluginRoute with the express router - ex:

  aPlugin: {
    setRoute: (routerExpress, pluginItem) => {
      routerExpress.get(pluginItem.pluginRoute, async (req, res) => {
          res.status(200).send(`Invoked with ${req.params.myParam}`);
      });
    },
  },

Design

The basic design of the dicomwebserver is just a configuration script that uses expressjs to configure the default handling of the responses, plus add the plugin handling for the responses on top of that. All of the interesting logic is actually within the various plugins, and those are intentionally kept fairly small. The intent of this is to allow the same plugins to eventually be re-used for serving data from other sources such as an AWS s3 bucket via cloudfront.