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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@shuji-bonji/experiential-manual-model

v0.1.0

Published

Data model for experiential operation manuals (screens with hotspots, screen flows, procedures, troubleshooting): TypeScript types, JSON Schema, validator and a converter from the 2021 experience_based_operation_explanation JSON. Independent of S1000D.

Readme

@shuji-bonji/experiential-manual-model

English | 日本語

A common data model for "experiential operation manuals", which let you learn how to operate a screen or a device by trying it out. The authoring tool and the viewer read and write data in this form; conversion to S1000D® data modules is done by a separate package (s1000d-writer-mcp). This package itself does not depend on S1000D and does not use S1000D terminology.

What is included

| Content | Location | |---|---| | TypeScript types (Manual / Topic / Step / Screen / Hotspot / Transition / Asset / Scope / Admonition / Term) | src/types.ts | | JSON Schema (draft 2020-12) | schema/manual.schema.json (also readable as @shuji-bonji/experiential-manual-model/schema/manual.schema.json) | | Validation validateManual(json) — returns shape errors, broken references and duplicate ids in errors, and unreachable screens and unused assets in warnings. It has no runtime dependencies | src/validate.ts | | fromLegacyJson(json), which reads the JSON.json of the 2021 work experience_based_operation_explanation | src/legacy.ts | | numberSteps(steps), which builds procedure numbers (1, 1.1, …) | src/number.ts | | Ticket machine example | examples/kenbaiki.manual.json |

Model

classDiagram
  class Manual { id; title; version; language; scopes; topics; assets; glossary }
  class Topic { id; kind; title; summary; blocks; steps; screens; startScreenRef }
  class Step { id; text; targetRef; expected; admonitions; assetRefs; scopeRefs; next; question; answers; children }
  class Screen { id; caption; assetRef; description; admonitions; hotspots }
  class Hotspot { id; label; shape; coords; action; transition }
  class Transition { to; condition; when; label }
  class Asset { id; kind; source; display; alt }
  class Scope { id; property; values; displayText }
  Manual --> Topic
  Manual --> Asset
  Manual --> Scope
  Topic --> Step
  Topic --> Screen
  Screen --> Hotspot
  Hotspot --> Transition
  Step --> Transition
  • Topic.kind has 4 values: description (explanatory text), procedure (a procedure), screenFlow (screens and transitions) and troubleshooting (proceeds by question and answer).
  • Hotspot.coords uses the same notation as the HTML <area> element (rect is [x1, y1, x2, y2], circle is [cx, cy, r], poly is [x1, y1, x2, y2, …]).
  • Scope is a range of applicability such as "this model" or "outdoor installation". Topic / Step / Block / Screen refer to it through scopeRefs.
  • Asset.source is the original, and Asset.display is the derived form used for display (for example, an original JT 3D model and a glTF for display).
  • Procedure numbers are not stored. numberSteps builds them at display time.

Usage

import { readFileSync } from 'node:fs';
import { validateManual, fromLegacyJson, numberSteps, type Manual } from '@shuji-bonji/experiential-manual-model';

const manual = JSON.parse(readFileSync('kenbaiki.manual.json', 'utf8')) as Manual;
const result = validateManual(manual);
if (!result.ok) console.error(result.errors);   // [{ path: '/topics/1/screens/0/hotspots/0/transition/to', message: '…' }]
console.log(result.warnings);                   // unreachable screens, unused assets and scopes

// Read the 2021 JSON.json
const { manual: converted, warnings } = fromLegacyJson(JSON.parse(readFileSync('JSON.json', 'utf8')));

// Procedure numbers
for (const { number, step } of numberSteps(manual.topics[2].steps!)) console.log(number, step.text);

Mapping from the 2021 JSON

| 2021 JSON.json | This model | |---|---| | purchaseTypes[] (displayAreas[] in its README) | Topic (kind: "screenFlow") | | titleID / title / description | Topic.id / title / summary | | screenID (or screenId) / caption / description / imageUrl in screens[] | Screen.id (made unique by prefixing the topic id) / caption / description / assetRef | | supplementaryExplanation | Screen.admonitions[{ level: "note" }] | | name / shape / coords / destination (or screenTransitionDestination) in buttons[] | Hotspot.label / shape / coords / transition.to |

There are 2 buttons whose rect coords carry a fifth value. fromLegacyJson drops it and records it in warnings.

Development

npm install
npm test          # validation, conversion, JSON Schema (ajv is a dev-only dependency)
npm run build

License

MIT