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

bom-viewer

v0.1.0

Published

Mechanical digital-twin exploded-view Viewer as a framework-agnostic Web Component (<explode-viewer>) + SDK — Three.js.

Readme

ExplodeViewer

机械装配体数字孪生·爆炸图 Viewer SDK(仅前端)。

  • 包名:bom-viewer
  • 技术栈:纯原生 JavaScript(无框架)+ Three.js (WebGL2) + Web Components;Vite 仅用于打包/本地 demo,Vitest 用于测试
    • 交付形态是浏览器原生自定义元素 <explode-viewer>;不依赖 React/Vue,也不用 TypeScript 写运行时逻辑
    • types/index.d.ts 为手写类型声明(仅供编辑器补全);运行时是 JS
  • 设计依据:
    • 《机械数字孪生爆炸图技术实现方案 v2.2》
    • 《Mechanical Viewer SDK 接口规范 v0.3》

这是什么

输入一个零件编号路径(occurrencePath),定位其 occurrence,进入直接父总成并执行单层爆炸, 高亮目标零件。固定产品契约为 Single-Level Explosion + Isolated Drill-down:

explode(parent) = explode(parent.directChildren)

查看子总成内部时不递归展开,而是显式 enterScope(child) 后再对该子总成执行一次单层 explode。

作为组件调用(Web Component)

对前端交付一个框架无关的自定义元素 <explode-viewer>。构建产两份产物(npm run build:lib):

| 产物 | three | 适用 | |---|---|---| | dist/explode-viewer.mjs | 外部化(peer) | 有构建工具的宿主(Vue/React/Vite/webpack),npm i three three-mesh-bvh 共用一份 three | | dist/explode-viewer.standalone.mjs | 内联 | <script type="module"> / 无构建页面,开箱即用 |

两者都注册同一个 <explode-viewer> 元素。

<!-- 无构建:引 standalone,three 已内联 -->
<script type="module" src="https://cdn.example/explode-viewer.standalone.mjs"></script>

<explode-viewer
   api-base="https://viewer.host/api"
   asset-base="https://viewer.host/assets"
   occurrence-path="SY215CPEBK_0/…/SY215CCM4KS_1_1_1_1_1-1">
</explode-viewer>
// 有构建:import ESM 产物即自动注册;宿主需自备 three
import 'bom-viewer';
const v = document.querySelector('explode-viewer');
const r = await v.showPart('SY215CPEBK_0/…/SY215CCM4KS_1_1_1_1_1-1');
if (!r.ok) toast(r.error.code, r.error.message);   // 边界返回结构化结果,不抛异常
v.addEventListener('viewer-error', (e) => log(e.detail)); // 异步失败也能收到

属性:api-base(REST 后端)、asset-base(可选,缺省=api-base)、occurrence-path(改变即定位)。 方法:showPart(path)、explode(ratio?)、collapseAll()、focus(id?)、enterScope(id)、exitScope()。 事件:viewer-ready、viewer-select、viewer-error(detail = {code, message, …})。

输入边界错误契约

showPart(occurrencePath) 对可预期边界返回 {ok:false, error}(不抛);成功返回 {ok:true, targetNodeIds:[…]}。 同一父总成下同名零件的多个实例会全部命中并高亮(targetNodeIds 为数组);仅当匹配跨不同父总成时才判为多义。

| code | 含义 | |---|---| | INVALID_INPUT | 空/格式非法的路径 | | NOT_FOUND(which:'device'/'part') | 整机根 / 叶子零件不存在(id 回显) | | PATH_MISMATCH | 零件存在但中间总成链/位置对不上(回显 expected/candidates) | | AMBIGUOUS | 匹配跨多个父总成(返回 candidates 供二选一) | | LOAD_FAILED / TIMEOUT | 资产/网络失败(并派发 viewer-error 事件) |

数据由 ExplodeViewerBackend 提供;examples/component.html 是最小示例(?api=<backend>/api)。

工程边界

本工程只做前端 Viewer SDK:

  • ✅ ViewerEngine 引擎契约(Cloud / Local 后端可互换的统一接口)
  • ✅ 引擎无关领域核心(PartTree / ExplosionSolver-runtime / Scope-Camera,禁止 import three)
  • ✅ Three.js 本地渲染后端(LocalViewerEngine)

不在本工程(由现有 SanyAssembly Python 仓库/后端提供,本工程通过 REST 契约消费):

  • ❌ 离线资产管线(OCCT/Python:STEP→结构树/三角化/去重/材质/ExplosionMeta 预计算/打包)
  • ❌ 后端 REST/API、鉴权、CDN、IoT 网关
  • ❌ Cloud 渲染后端(WebRTC + UE/Unity)——Phase 1 仅接口桩

Phase 1 验收重点

occurrence/PartTree → 按 Scope 几何加载 → 单层爆炸 → Drill-down → 相机 Fit → Picking 的最小闭环, 并保证上层 React 代码对 Cloud/Local 后端互换零改动。

Phase 1 明确不做:IoT、Snapshot、剖切、测量、多选、完整 Streaming、水印溯源、Session Broker。

v2.3 离线增强契约

  • ExplosionRuntime 可消费 collision solver 的 waypoints,按折线路径插值,避免两段式拆出路径被直线截弯穿模;旧的 direction × distance 数据不变。
  • 本地引擎从 manifest 的 geometries[].lods 读取 level 0 URI,仍兼容旧 geometry/<id>.glb。
  • 节点含离线 bestView.assembled/exploded 时,focus(node) 直接采用对应爆炸状态的相机;缺省时继续 bbox fit。
  • 多级运行时屏幕误差自动选级仍是独立后续工作;当前版本只确保多级资产契约和 LOD0 加载闭环。

选中与聚焦视觉

  • 有选中对象时,零件或总成的整个子树始终使用青蓝色呼吸发光,不显示包围框。Scope 处于爆炸态时,其他几何保持原始不透明材质;处于合拢态时,其他几何降为透明上下文。
  • 没有选中对象、点击视口空白处或切换 Scope 时,选中特效完全清除并恢复所有原始材质。
  • 树节点、三维拾取、搜索查看都会聚焦;“爆炸”会在动画完成后再聚焦,避免相机追丢目标。
  • 聚焦保留离线 bestView 的少遮挡观察方向,但按当前爆炸态的 Scope 真实包围盒取景,同时呈现当前模型全貌和选中对象所在位置。

规划(OpenSpec)

实现计划以 OpenSpec change 按模块组织,见 openspec/changes/。执行 openspec list 查看。

Wave 1(基础闭环,依赖顺序):

  1. bootstrap-explode-viewer — 工程脚手架 + viewer-engine-contract + viewer-data-contracts
  2. explode-viewer-domain-core — part-tree-store + explosion-runtime + scope-visibility-camera
  3. explode-viewer-local-engine — local-viewer-engine(Three.js 后端)

Wave 2+(后续):cloud-viewer-engine、viewer-interaction-ui、IoT / Streaming / 水印 / Session Broker。