Development / API
Shadow Atlas consists of two projects in one shared workspace:
| Project | Role | Build |
|---|---|---|
| cow-shadow-atlas-viewer | Vanilla-JS/Three.js map engine providing the <map-viewer> custom element. |
None — consumed as source. |
| cow-shadow-atlas | TypeScript Obsidian plugin, bundles the engine with esbuild and adds the local share server. | esbuild |
By default the plugin expects the engine as a sibling folder (../cow-shadow-atlas-viewer, relative to the plugin folder); override it with the MAPVIEWER_SRC environment variable.
Building the plugin
Section titled “Building the plugin”npm installnpm run buildThe script first type-checks (tsc -noEmit -skipLibCheck) and then bundles with esbuild. Output: main.js (CommonJS, the Obsidian plugin) and www/mapviewer.bundle.js (ESM, the standalone table view page).
The bundle step can also be invoked without the type check, e.g. through the wrapper scripts scripts/build.ps1 / scripts/build.sh:
node esbuild.config.mjs productionWatch mode (no minification, inline source maps):
node esbuild.config.mjs<map-viewer> custom element
Section titled “<map-viewer> custom element”Defined in the engine’s src/map-viewer-element.js.
Attributes: src, storage-key, lang, player, media-type, logs, theme.
Public API: setStorageAdapter(adapter), setLinkProvider(provider), setPinShapes(defs), loadMap(url), save() / load(), getData() / setData(data), addImage(x, y, opts), showToast(text, opts), engine (direct access to the MapViewer instance).
Events: map-ready, map-changed, map-saved, map-loaded, view-changed, object-transform, video-state, livecursor-change, livecursor-move, map-image-change, map-perf.
Data layout
Section titled “Data layout”Every .samap file is readable JSON with a unique id. Its resources sit next to it under .cow-shadow-atlas/<id>/:
.cow-shadow-atlas/<id>/├── objects.json # object layer graph (pins, images, videos, layer definitions)├── fog.bin # fog mask└── <base image> # the configured map image/videoEngine tests
Section titled “Engine tests”cd testsnpm installnpm test # node --testnpm run lint # eslint src testsContributing
Section titled “Contributing”- Check the existing issues in the relevant repository under Chronicle-of-Whispers.
- Keep changes small and focused on one topic.
- Document visible behaviour and new configuration.
- Add tests where the repository provides a test harness.
New documentation pages are added as Markdown under src/content/docs/docs/ (English) and src/content/docs/de/docs/ (German), then registered in the sidebar in astro.config.mjs.