From 7623a7c9d553535a55a88cbf6b3a535df9432daa Mon Sep 17 00:00:00 2001
From: Edward Silverton <e.silverton@gmail.com>
Date: Tue, 28 Nov 2023 00:24:03 +0000
Subject: [PATCH] build docs to dist

---
 package-lock.json                 | 210 +++++++++++++++++++++++++++++-
 package.json                      |   7 +-
 src/content-handlers/iiif/Docs.ts |  19 +++
 tsconfig.json                     |   4 +-
 typedoc.json                      |   4 +
 webpack.dev-server.js             |  10 +-
 6 files changed, 240 insertions(+), 14 deletions(-)
 create mode 100644 src/content-handlers/iiif/Docs.ts
 create mode 100644 typedoc.json

diff --git a/package-lock.json b/package-lock.json
index c52ab6ea7..0443138eb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -75,7 +75,9 @@
         "ts-jest": "22.4.2",
         "ts-loader": "9.2.6",
         "tslint-config-prettier": "^1.18.0",
-        "typescript": "4.4.3",
+        "typedoc": "^0.25.4",
+        "typedoc-plugin-missing-exports": "^2.1.0",
+        "typescript": "4.6.2",
         "typescript-tslint-plugin": "^0.5.5",
         "url-loader": "4.1.1",
         "webpack": "^5.59.1",
@@ -1247,6 +1249,12 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/ansi-sequence-parser": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+      "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
+      "dev": true
+    },
     "node_modules/ansi-styles": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
@@ -9986,6 +9994,12 @@
         "json5": "lib/cli.js"
       }
     },
+    "node_modules/jsonc-parser": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+      "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+      "dev": true
+    },
     "node_modules/jsonfile": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -10375,6 +10389,12 @@
         "node": ">=10"
       }
     },
+    "node_modules/lunr": {
+      "version": "2.3.9",
+      "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+      "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+      "dev": true
+    },
     "node_modules/make-dir": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@@ -10454,6 +10474,18 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/marked": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+      "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+      "dev": true,
+      "bin": {
+        "marked": "bin/marked.js"
+      },
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/marks-pane": {
       "version": "1.0.9",
       "resolved": "https://registry.npmjs.org/marks-pane/-/marks-pane-1.0.9.tgz",
@@ -14004,6 +14036,18 @@
       "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
       "dev": true
     },
+    "node_modules/shiki": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz",
+      "integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==",
+      "dev": true,
+      "dependencies": {
+        "ansi-sequence-parser": "^1.1.0",
+        "jsonc-parser": "^3.2.0",
+        "vscode-oniguruma": "^1.7.0",
+        "vscode-textmate": "^8.0.0"
+      }
+    },
     "node_modules/side-channel": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -16288,10 +16332,64 @@
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
     },
+    "node_modules/typedoc": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.4.tgz",
+      "integrity": "sha512-Du9ImmpBCw54bX275yJrxPVnjdIyJO/84co0/L9mwe0R3G4FSR6rQ09AlXVRvZEGMUg09+z/usc8mgygQ1aidA==",
+      "dev": true,
+      "dependencies": {
+        "lunr": "^2.3.9",
+        "marked": "^4.3.0",
+        "minimatch": "^9.0.3",
+        "shiki": "^0.14.1"
+      },
+      "bin": {
+        "typedoc": "bin/typedoc"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "peerDependencies": {
+        "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x"
+      }
+    },
+    "node_modules/typedoc-plugin-missing-exports": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-2.1.0.tgz",
+      "integrity": "sha512-+1DhqZCEu7Vu5APnrqpPwl31D+hXpt1fV0Le9ycCRL1eLVdatdl6KVt4SEVwPxnEpKwgOn2dNX6I9+0F1aO2aA==",
+      "dev": true,
+      "peerDependencies": {
+        "typedoc": "0.24.x || 0.25.x"
+      }
+    },
+    "node_modules/typedoc/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/typedoc/node_modules/minimatch": {
+      "version": "9.0.3",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
     "node_modules/typescript": {
-      "version": "4.4.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
-      "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
@@ -16685,6 +16783,18 @@
       "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==",
       "dev": true
     },
+    "node_modules/vscode-oniguruma": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
+      "dev": true
+    },
+    "node_modules/vscode-textmate": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+      "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
+      "dev": true
+    },
     "node_modules/vscode-uri": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
@@ -19028,6 +19138,12 @@
       "integrity": "sha512-sGwIGMjhYdW26/IhwK2gkWWI8DRCVO6uj3hYgHT+zD+QL1pa37tM3ujhyfcJIYSbsxp7Gxhy7zrRW/1AHm4BmA==",
       "dev": true
     },
+    "ansi-sequence-parser": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+      "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
+      "dev": true
+    },
     "ansi-styles": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
@@ -26012,6 +26128,12 @@
       "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==",
       "dev": true
     },
+    "jsonc-parser": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+      "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+      "dev": true
+    },
     "jsonfile": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -26326,6 +26448,12 @@
         "yallist": "^4.0.0"
       }
     },
+    "lunr": {
+      "version": "2.3.9",
+      "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
+      "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+      "dev": true
+    },
     "make-dir": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@@ -26388,6 +26516,12 @@
         "object-visit": "^1.0.0"
       }
     },
+    "marked": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
+      "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+      "dev": true
+    },
     "marks-pane": {
       "version": "1.0.9",
       "resolved": "https://registry.npmjs.org/marks-pane/-/marks-pane-1.0.9.tgz",
@@ -29208,6 +29342,18 @@
       "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
       "dev": true
     },
+    "shiki": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz",
+      "integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==",
+      "dev": true,
+      "requires": {
+        "ansi-sequence-parser": "^1.1.0",
+        "jsonc-parser": "^3.2.0",
+        "vscode-oniguruma": "^1.7.0",
+        "vscode-textmate": "^8.0.0"
+      }
+    },
     "side-channel": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
@@ -31073,10 +31219,48 @@
       "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
     },
+    "typedoc": {
+      "version": "0.25.4",
+      "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.4.tgz",
+      "integrity": "sha512-Du9ImmpBCw54bX275yJrxPVnjdIyJO/84co0/L9mwe0R3G4FSR6rQ09AlXVRvZEGMUg09+z/usc8mgygQ1aidA==",
+      "dev": true,
+      "requires": {
+        "lunr": "^2.3.9",
+        "marked": "^4.3.0",
+        "minimatch": "^9.0.3",
+        "shiki": "^0.14.1"
+      },
+      "dependencies": {
+        "brace-expansion": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0"
+          }
+        },
+        "minimatch": {
+          "version": "9.0.3",
+          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+          "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^2.0.1"
+          }
+        }
+      }
+    },
+    "typedoc-plugin-missing-exports": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/typedoc-plugin-missing-exports/-/typedoc-plugin-missing-exports-2.1.0.tgz",
+      "integrity": "sha512-+1DhqZCEu7Vu5APnrqpPwl31D+hXpt1fV0Le9ycCRL1eLVdatdl6KVt4SEVwPxnEpKwgOn2dNX6I9+0F1aO2aA==",
+      "dev": true
+    },
     "typescript": {
-      "version": "4.4.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz",
-      "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==",
+      "version": "4.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
+      "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==",
       "dev": true
     },
     "typescript-tslint-plugin": {
@@ -31377,6 +31561,18 @@
       "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==",
       "dev": true
     },
+    "vscode-oniguruma": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+      "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
+      "dev": true
+    },
+    "vscode-textmate": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+      "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
+      "dev": true
+    },
     "vscode-uri": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
diff --git a/package.json b/package.json
index 64841f5f5..2f7ad761a 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
     "build-es": "node ./esbuild.mjs",
     "build-tsc": "tsc --skipLibCheck --module CommonJS --esModuleInterop --declarationDir ./dist/cjs --declaration --outDir ./dist/cjs -p . && npm run copy-files",
     "copy-files": "copyfiles -u 1 src/**/*.svg dist/cjs && copyfiles -u 1 src/**/*.gif dist/cjs && copyfiles -u 1 src/**/*.less dist/cjs && copyfiles -u 1 src/extensions/**/*.less dist/cjs && copyfiles -u 1 src/**/*.css dist/cjs",
+    "docs": "typedoc --plugin typedoc-plugin-missing-exports",
     "test": "jest",
     "prepublishOnly": "npm run build && npm run build-tsc && npm run build-es"
   },
@@ -73,7 +74,9 @@
     "ts-jest": "22.4.2",
     "ts-loader": "9.2.6",
     "tslint-config-prettier": "^1.18.0",
-    "typescript": "4.4.3",
+    "typedoc": "^0.25.4",
+    "typedoc-plugin-missing-exports": "^2.1.0",
+    "typescript": "4.6.2",
     "typescript-tslint-plugin": "^0.5.5",
     "url-loader": "4.1.1",
     "webpack": "^5.59.1",
@@ -116,8 +119,8 @@
     "react": "^18.0.0",
     "react-dom": "^18.0.0",
     "react-intersection-observer": "^8.34.0",
-    "xss": "1.0.3",
     "waveform-panel": "^1.2.0",
+    "xss": "1.0.3",
     "zustand": "^4.0.0-rc.0"
   },
   "collective": {
diff --git a/src/content-handlers/iiif/Docs.ts b/src/content-handlers/iiif/Docs.ts
new file mode 100644
index 000000000..59051f193
--- /dev/null
+++ b/src/content-handlers/iiif/Docs.ts
@@ -0,0 +1,19 @@
+import { Config as ModelViewerExtensionConfig } from "@/content-handlers/iiif/extensions/uv-model-viewer-extension/config/Config";
+import { Config as AlephExtensionConfig } from "@/content-handlers/iiif/extensions/uv-aleph-extension/config/Config";
+import { Config as AVExtensionConfig } from "@/content-handlers/iiif/extensions/uv-av-extension/config/Config";
+import { Config as EbookExtensionConfig } from "@/content-handlers/iiif/extensions/uv-ebook-extension/config/Config";
+import { Config as MediaElementExtensionConfig } from "@/content-handlers/iiif/extensions/uv-mediaelement-extension/config/Config";
+import { Config as OSDExtensionConfig } from "@/content-handlers/iiif/extensions/uv-openseadragon-extension/config/Config";
+import { Config as DefaultExtensionConfig } from "@/content-handlers/iiif/extensions/uv-default-extension/config/Config";
+import { Config as PDFExtensionConfig } from "@/content-handlers/iiif/extensions/uv-pdf-extension/config/Config";
+
+export type IIIFContentHandlerConfig = {
+  aleph: AlephExtensionConfig;
+  av: AVExtensionConfig;
+  default: DefaultExtensionConfig;
+  ebook: EbookExtensionConfig;
+  mediaelement: MediaElementExtensionConfig;
+  modelViewer: ModelViewerExtensionConfig;
+  osd: OSDExtensionConfig;
+  pdf: PDFExtensionConfig;
+};
diff --git a/tsconfig.json b/tsconfig.json
index a449b19c9..c4dc3be0b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,10 +21,10 @@
     "sourceMap": true,
     "strictNullChecks": true,
     "esModuleInterop": true,
-    "suppressImplicitAnyIndexErrors": true,
     "target": "ES5",
     "tsBuildInfoFile": "./buildcache/front-end",
-    "types": ["@iiif/base-component", "jest", "jquery", "node"]
+    "types": ["@iiif/base-component", "jest", "jquery", "node"],
+    "skipLibCheck": true
   },
   "exclude": ["node_modules", "src/**/*.test.ts", "src/**/*.spec.ts"],
   "include": ["src"]
diff --git a/typedoc.json b/typedoc.json
new file mode 100644
index 000000000..f5f82d953
--- /dev/null
+++ b/typedoc.json
@@ -0,0 +1,4 @@
+{
+  "entryPoints": ["src/content-handlers/iiif/Docs.ts"],
+  "out": "dist/docs"
+}
diff --git a/webpack.dev-server.js b/webpack.dev-server.js
index 7e994adf2..9b24815f2 100644
--- a/webpack.dev-server.js
+++ b/webpack.dev-server.js
@@ -9,7 +9,7 @@ const config = {
     UV: ["./src/index.ts"],
   },
   mode: "development",
-  devtool: 'eval-source-map',
+  devtool: "eval-source-map",
   output: {
     libraryTarget: "umd",
     library: "UV",
@@ -19,7 +19,7 @@ const config = {
   },
   resolve: {
     alias: {
-      'jquery': require.resolve('jquery/dist/jquery.js'),
+      jquery: require.resolve("jquery/dist/jquery.js"),
     },
     extensions: [".ts", ".tsx", ".js"],
     fallback: {
@@ -29,7 +29,7 @@ const config = {
   },
   module: {
     rules: [
-      { test: /\.js$/, loader: 'source-map-loader', enforce: 'pre' },
+      { test: /\.js$/, loader: "source-map-loader", enforce: "pre" },
       {
         test: /\.ts$/,
         use: [{ loader: "ts-loader" }],
@@ -84,6 +84,10 @@ const config = {
     compress: true,
     port: 8080,
     onListening(devServer) {
+      devServer.app.use(
+        "/docs",
+        express.static(path.join(__dirname, "dist/docs"))
+      );
       devServer.app.use(
         "/iiif-collection.json",
         express.static(path.join(__dirname, "src", "iiif-collection.json"))