Web viewer for Datasworn content — browse rulesets, roll on oracles, and follow entity links across expansions.
- Deployed: https://datasworn-community.github.io/viewer/
- Consumes:
@datasworn-community/corefor types + every published@datasworn-community/*content package (seepackage.json) via ES module imports. Each ruleset is loaded on-demand via a dynamic import, so the initial page load stays small.
bun install
bun run dev # http://localhost:3000
bun run build # production bundle in dist/
bun run test # vitest with jsdom
bun run preview # serve the production bundle locally- Ruleset picker for Ironsworn / Delve / Lodestar / Starforged / Sundered Isles + community expansions (Starsmith, Ironsmith, and more as they publish)
- Full-tree navigation of moves, oracles, assets, delve sites, atlas entries, truths, and NPCs
- Interactive oracle rolls with match detection and roll history
- Follows
datasworn:cross-entity links (moves → oracles → assets, etc.) - Markdown safely rendered via DOMPurify — arbitrary HTML in oracle text can't XSS the page
The viewer pins to one Datasworn schema line at a time. The version bundled here matches @datasworn-community/core's current schema version; content packages that ship for a different schema line aren't loaded.
Why: rulesets on different schema lines have different validated shapes. Loading them side-by-side would need per-package version-branching in every renderer — not worth it unless there's real cross-line-playset demand (there isn't yet).
Recommended flow when core bumps its schema line:
- Bump the viewer's
@datasworn-community/coredependency to the new line. - Bump every
@datasworn-community/<ruleset>dependency to a version on the same line. Content packages that haven't caught up get dropped fromRULESETSinsrc/utils/loader.tswith aTODOcomment until they publish. - Release a new viewer version. Users who need to browse content on the old schema line install the previous viewer release.
Practical note: the loader tolerates missing packages gracefully (dynamic import failure → console.warn, ruleset omitted from the picker). So the "bump the line even if some rulesets lag" case degrades to "some rulesets temporarily not shown" rather than a broken build.
When a new content package publishes to npm, add it to two places:
package.json— as adependenciesentry. Note that community package names on npm are hyphenated (e.g.@datasworn-community/fe-runners,@datasworn-community/ancient-wonders) even though the ruleset ids inRULESETSuse underscores (fe_runners,ancient_wonders) to match the JSON_id.src/utils/loader.ts— a new entry in theRULESETSarray with the package's dynamic import.
Vite's route-based code splitting will handle the rest.
Ported from tbsvttr/datasworn tools/viewer/ as part of the fork's deprecation. Original data-loading path (fetch from a co-located datasworn/ directory) replaced with published-package ES imports so the app is fully standalone and doesn't rely on a monorepo layout.