Friday, 3 July 2026
Session summary: confirm-dialog fix, ES module refactor, shared library submodule, TypeScript project references.
The project delete confirm dialog was not working because npm run build
had not been run after the last code change, and the server had not been restarted.
The compiled .js in public/ was stale. No code change
was needed — the fix was running the build and restart. Established that debugging
frontend issues always requires a fresh build first.
The frontend was rewritten from module: none (global scripts) to
proper ES modules. tsconfig.client.json now uses
module: ESNext and moduleResolution: bundler.
All HTML pages switched from <script src> to
<script type="module" src>. Components now use
import / export and no longer rely on global scope.
The browser deduplicates shared module imports automatically.
EditorState was extracted from editor-shell.ts into its
own module at src/components/editor-state.ts. It exports
setEditorState() (called by editor-shell on init) and
getEditorState() (called by any component that needs it).
The window.editorState global is gone. Components import what they
need directly.
showConfirmDialog and ConfirmDialogOptions are now
properly exported from confirm-dialog.ts.
project-editor.ts imports showConfirmDialog directly
instead of using a /// <reference path> directive. The
redundant <script> tag for confirm-dialog.js in
projects.html was removed — the browser loads it via the import graph.
A personal TypeScript library was added as a git submodule at
src/library-ts/. The library has two parts:
browser/ (DOM-capable, usable with shims on Node) and
node/ (Node.js only). Placing the submodule inside src/
keeps rootDir: "src" intact so the output URL structure in
public/ is unchanged.
The library was written without strict: true, causing hundreds of
errors when compiled with Roject's strict settings. TypeScript project references
solve this: a new tsconfig.roject.json inside
src/library-ts/browser/ compiles the browser part separately with
strict: false, composite: true, and
declaration: true. Roject's tsconfig.client.json
excludes src/library-ts/**/* and references the library project.
Build now runs as tsc --build tsconfig.client.json.
The node part of the library caused the same strict errors when compiled by
ts-node. A dedicated tsconfig.ts-node.json extends the
server tsconfig but turns off strictNullChecks (the only check the
library violates) and adds src/library-ts/node/**/* to the include.
The start script now passes --project tsconfig.ts-node.json to
ts-node.
module: none was originally chosen to avoid a bundler, but it also
ruled out import / export and forced the
window.editorState workaround. Browsers support ES modules natively
via type="module" scripts — no bundler needed. The switch removes
all global-scope workarounds and makes the library integration straightforward.
src/, not at project root
Placing the submodule at src/library-ts/ keeps
rootDir: "src" in the client tsconfig unchanged. A submodule at the
project root would require either changing rootDir (breaking the
/components/... URL structure) or setting up path aliases.
Three tsconfigs now serve distinct purposes: tsconfig.json (server,
strict), tsconfig.client.json (frontend, strict, references library),
tsconfig.ts-node.json (runtime, relaxed for library compatibility).
This keeps strict checking on all first-party code without patching the library.
strictNullChecks turned off for ts-node
All three errors in the node library were strictNullChecks violations.
Rather than disabling all of strict, only that one flag is overridden
in tsconfig.ts-node.json. Server code retains
noImplicitAny, strictFunctionTypes,
strictPropertyInitialization, and all other strict checks.
src/components/editor-state.ts — EditorState module (getEditorState / setEditorState)
src/library-ts/browser/ — shared browser library (git submodule)
src/library-ts/node/ — shared node library (git submodule)
src/library-ts/browser/tsconfig.roject.json — library browser tsconfig (strict: false, composite)
tsconfig.client.json — frontend: ESNext modules, references library
tsconfig.ts-node.json — ts-node runtime: extends server tsconfig, strictNullChecks: false
public/library-ts/browser/ — compiled library output with .d.ts files