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

@kubohiroya/turbowarp-scene-graph

v0.5.0

Published

Scene graph planning primitives for TurboWarp 3D extensions: YAML documents, validation, normalization, and deterministic call plans.

Readme

turbowarp-scene-graph

English | 日本語

@kubohiroya/turbowarp-scene-graph turns small scene graph documents into deterministic TurboWarp extension call plans. It reads and writes them as YAML, validates and normalizes them, and expands the scene3d / ar fragment a Kamishibai scene can carry into the calls that set both extensions up.

It plans; it does not run. It never loads A-Frame, never opens a camera, and never parses a Kamishibai story. The caller supplies the document and dispatches the calls it gets back.

Scope

  • Parse and stringify scene graph documents as YAML.
  • Validate node, class, data, and attribute shapes, and reject duplicate ids.
  • Normalize ids and fill omitted options deterministically.
  • Convert typed values to A-Frame strings: arrays and {x,y,z,w} vectors become space-separated values; other scalar objects become sorted key: value pairs.
  • Plan turbowarp-aframe calls for a document, and turbowarp-ar calls for an AR fragment.

Layout

| Module | Owns | |---|---| | src/scene-graph.ts | The document model: types, validation, normalization, and the turbowarp-aframe plan. App-neutral. | | src/scene-yaml.ts | YAML in and out, over that model. | | src/kamishibai-extension.ts | The {scene3d, ar} envelope a Kamishibai scene carries, and the order the two extensions are set up in. The only app-specific part. | | schemas/ | JSON Schemas for editors and external tooling. |

AR scene control — its types, validation, and plan — belongs to @kubohiroya/turbowarp-ar/plan and is imported, not re-exported. Import it from there when you need it directly.

Errors keep the vocabulary of whichever package raised them. A malformed scene3d reports as a scene graph error and a malformed ar as a TurboWarp AR error, so a message points at the code that enforces the rule.

Documents

formatVersion: 1
root:
  children:
    - type: box
      class: card
      attributes:
        position: 0 1 -3
import {parseSceneGraphYaml, stringifySceneGraphYaml} from '@kubohiroya/turbowarp-scene-graph';

const scene = parseSceneGraphYaml(source);

scene.options; // { layer: 'above-stage', mode: '3d' }
scene.root.children?.[0]?.id; // 'scene-box-1'
stringifySceneGraphYaml(scene);

Normalization rules:

  • root.id is always scene.
  • options.layer defaults to above-stage and options.mode to 3d.
  • A child without an id gets a deterministic one such as scene-box-1.
  • Ids are trimmed, and anything outside ASCII letters, digits, _, and - becomes -.
  • Duplicate ids after normalization throw.

data and attributes values may be scalars, scalar arrays, or scalar objects. stringifySceneGraphValue renders them the way a TurboWarp argument needs.

Plans

import {createAFrameSceneGraphPlan} from '@kubohiroya/turbowarp-scene-graph';

const calls = createAFrameSceneGraphPlan({
  formatVersion: 1,
  root: {
    children: [{type: 'box', id: 'card', class: 'selected', attributes: {position: {x: 0, y: 1, z: -3}}}]
  }
});

Kamishibai fragments

import {createTurboWarpExtensionPlan} from '@kubohiroya/turbowarp-scene-graph';

const calls = createTurboWarpExtensionPlan({
  scene3d: {formatVersion: 1, root: {children: [{type: 'box', id: 'card'}]}},
  ar: {cameraId: 'front', targets: [{targetId: 'marker-1', selector: '#card'}]}
});

Both halves are optional, and an empty fragment plans nothing. The 3D scene is planned first, so the nodes an AR target binds to exist by the time attachSelectorToARTarget runs. AR defaults are cameraId: default, layer: above-stage, and no targets; layer accepts only above-stage and below-stage, the vocabulary turbowarp-ar and turbowarp-aframe share.

Schemas

The JSON Schemas under schemas/ describe the same shapes the TypeScript validators enforce, for editors and tools that cannot run this package. Because that is a second description of one contract, tests/schema-contract.test.ts runs a corpus of documents through both and fails if the two ever disagree.

Development

The shared data-editor is a development dependency for SchemaBundle types and schema contract tests. The ./editor-schema JavaScript entry exports schemas and pure owner validation without requiring an installed data-editor or Ajv. TypeScript consumers of its public editor types should add data-editor as their own development dependency. The upstream AR package must also keep editor engines out of its production dependencies.

npm install --global corepack@latest
corepack enable
pnpm install --frozen-lockfile
pnpm run check

License

Mozilla Public License 2.0. See LICENSE.