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

@cut-workbench/workbench

v0.5.0

Published

Cut Workbench 的 UI 组件库:素材库、预览、时间轴、属性面板与导出对话框。

Readme

@cut-workbench/workbench

可嵌入的浏览器端剪辑台 UI:素材库、预览、时间轴、属性面板与导出对话框。 基于 React 19 + Tailwind CSS v4 + Radix,样式已作用域化,嵌进任何宿主都不污染。

安装

只需要装这一个包:

npm i @cut-workbench/workbench

@cut-workbench/core、@cut-workbench/react 以及引擎依赖 @webav/av-cliper、@webav/av-canvas、@webav/av-recorder 都是它的 dependencies,会一起装上 —— 不需要你再显式安装,也不需要知道有这些东西。

选装(按需):

| 想要什么 | 装什么 | |---|---| | 只取纯逻辑,不渲染 UI | npm i @cut-workbench/core | | 只要 React hooks,自己写 UI | npm i @cut-workbench/core @cut-workbench/react | | Electron 宿主桥(「下载」→「保存到指定路径」) | npm i @cut-workbench/host-electron | | 需要控制 React 实例 | 宿主自己提供 react / react-dom / zustand(见下) |

关于 react / react-dom / zustand

这三个是 peer 依赖,由宿主提供,库不会替你装 —— 一旦出现两份 React, 宿主会碰到 Cannot read properties of null (reading 'useContext')。项目已有 React 时无需任何额外操作。

zustand 同理:@cut-workbench/react 直接 import 它,两份实例会让订阅错乱, 所以必须由宿主提供(React 项目通常已有)。

为什么 WebAV 是 dependencies 而不是 peer

@webav/* 是运行时必需的:没有 av-cliper / av-canvas 就没有预览和 导出,功能直接不可用。所以这个包选择把它们带上,让「装一个包就能用」成立。

@cut-workbench/core 则相反 —— 它的定位是「只取纯逻辑」,有人只要 timeline 模型和工程序列化,不该被迫装 WebAV,所以 core 那边是 optional peer。

⚠️ 0.1.0 的 WebAV 是 peer,只靠 npm 7+ 自动安装 peer 的隐式行为碰巧能跑; pnpm / yarn 不会自动装 peer,在它们下面构建会报 [MISSING_EXPORT] "Combinator" is not exported by "__vite-optional-peer-dep:…"。 0.2.0 起改为 dependencies,与包管理器无关。

React 项目

推荐:用 /auto 子入口,一行自带样式:

import { createEditor } from '@cut-workbench/core/engine'
import { CutEditorProvider } from '@cut-workbench/react'
import { CutWorkbench, CutWorkbenchProvider } from '@cut-workbench/workbench/auto'

const editor = createEditor()

createRoot(el).render(
  <CutEditorProvider editor={editor}>
    <CutWorkbenchProvider theme="dark">
      <CutWorkbench className="h-screen" onSaveProject={save} onOpenProject={open} />
    </CutWorkbenchProvider>
  </CutEditorProvider>,
)

根入口不自带样式 —— 给已经有自己的构建流程、需要控制 CSS 顺序 (例如要压过某条全局重置)的场景:

import { CutWorkbench, CutWorkbenchProvider } from '@cut-workbench/workbench'
import '@cut-workbench/workbench/style.css'   // ← 必须自己引,忘了就是无样式

两者的 API 完全一致,/auto 只是多了一行 import './cut-workbench.css'。 不要同时引两个入口 —— 样式会被引入两次(作用域化之后是幂等的,但没必要)。

布局

┌───────────────────────────────────────────┐
│ 顶栏                                      │
├──────────┬──────────────┬─────────────────┤
│ 素材库   │ 预览         │ 属性            │  ← 上半区,可纵向滚动
├──────────┴──────────────┴─────────────────┤
│ 时间轴(横跨整行)                        │  ← 下栏
└───────────────────────────────────────────┘

时间轴通栏占满底部一行,不随左右面板宽度变化。左上「素材」、中「预览」、 右「属性」三栏可拖拽调整,面板内的内容各自滚动。

0.2.0 之前时间轴被塞在中间列里,左右面板一拉宽就把它挤窄,工具条按钮会 溢出到属性面板上;窄列下播放控制条的时间码也会被裁掉。现在布局与控件都有 容器级自适应(按容器宽度分档收起次要控件,而不是按视口宽度), scripts/layout-test.mjs 守着这两条。

顶栏定制

内置顶栏分三层可定制,由浅到深:

1. 改文案 —— labels:

<CutWorkbench toolbar={{ labels: { export: '导出成片', untitledProject: '新建项目' } }} />

2. 改局部 —— brand / title / status / actions:

<CutWorkbench
  toolbar={{
    brand: <MyLogo />,                      // 默认**没有**品牌区,避免露出本库名字
    title: null,                            // 不要工程名区
    status: <AutoSaveBadge />,              // 默认「空工程 · 16:9」
    actions: <MyShareButton />,             // 追加在右侧按钮组末尾
    editableTitle: true,                    // 双击工程名重命名(走撤销栈)
    showCapabilityBadge: false,             // 隐藏引擎能力徽标
  }}
/>

3. 整条替换 —— slots.topBar(优先级最高):

<CutWorkbench slots={{ topBar: <MyHeader /> }} />   // 传 null 表示完全不要顶栏

slots.topBar 会替换整条顶栏,撤销/导出等内置动作一并由宿主负责; toolbar 只换其中一块,其余保留。可运行示例见 playground 的 /toolbar-demo.html。

非 React 项目

import { initCutWorkbench } from '@cut-workbench/workbench/auto'

const wb = initCutWorkbench('#app', { theme: 'dark', namespace: 'my-project' })
await wb.whenReady()
wb.on('export:done', ({ blob, filename }) => upload(blob, filename))

script 标签 / 微前端

UMD 单文件已把 React、WebAV、Worker 与样式全部内联,暴露 window.CutWorkbench:

<script src="https://unpkg.com/@cut-workbench/workbench/dist/umd/cut-workbench.umd.js"></script>
<script>
  const wb = CutWorkbench.initCutWorkbench('#app', { theme: 'dark' })
</script>

⚠️ React 19 不再发布 UMD 产物,因此 UMD 版本内置了一份 React。有任何构建工具时 都优先选 ESM。

类型与依赖缺失

如果引擎依赖没解析到(例如被 npm 的 hoisting 拔掉、或在 pnpm 下版本冲突), 工作台不会白屏:能力探测会把「缺依赖」和「浏览器不支持」分开报告, 阻断页直接给出可执行的安装命令:

缺少 @webav/av-cliper,请执行 npm i @webav/av-cliper @webav/av-canvas @webav/av-recorder

注意缺失依赖只在构建期解析 —— 装完必须重新跑一次构建,刷新浏览器没用。

关掉能力实验室(可选)

config.features.lab 是运行时开关,默认 false。lab 本体是独立子入口 @cut-workbench/workbench/lab,主包对它做动态 import —— 所以默认配置下 lab 的代码(含 @webav/av-recorder)不会加载,但打包器仍会产出一个约 33 KB 的 lab chunk。

要在产物里彻底删掉它,在宿主的构建配置里把子入口指到空实现:

// vite.config.ts
export default {
  resolve: {
    alias: [
      {
        find: /^@cut-workbench\/workbench\/lab$/,
        replacement: '@cut-workbench/workbench/lab-disabled',
      },
    ],
  },
}

验证方式:

grep -c "FrameCounterClip" dist/assets/*.js   # 应为 0

为什么不是 define: { __CUT_WORKBENCH_LAB__: 'false' }:实测(Vite 8 / Rolldown)动态 import 只要出现在模块图里,chunk 就会被写进 dist,即便所在 分支已被折成死代码。只有把模块解析本身换掉才真正生效。

宿主桥(Electron / 自定义文件来源)

宿主想接管「导出保存到哪」和「素材从哪来」时,用 @cut-workbench/host-electron:

const editor = createEditor({
  bridge: createElectronBridge(window.cutHost),   // ← 传给 createEditor 即可
})

<CutEditorProvider editor={editor}>
  <CutWorkbenchProvider theme="dark">
    <CutWorkbench className="h-full w-full" />
  </CutWorkbenchProvider>
</CutEditorProvider>

CutWorkbenchProvider 不传 bridge 时会回落到编辑器自己的 bridge, 所以不用传两遍。若想给 UI 层单独换一套桥,再显式传 bridge 覆盖。

⚠️ 只把桥传给 createEditor 却期待 UI 也生效,在 0.2.0 之前是不成立的: Provider 会另建一个浏览器内置桥,于是「导出走宿主、素材导入走内置 <input>」的半接管状态静默存在 —— 界面完全正常,宿主自己的素材库永远 弹不出来。0.2.0 起已改为回落。scripts/bridge-host-test.mjs 守着这条, 可运行验收页见 playground 的 /bridge-host.html。

主题定制

<CutWorkbenchProvider theme="inherit" />        // 跟随宿主 <html class="dark">
<CutWorkbenchProvider tokens={{ primary: '#4d6bfe', radius: '8px' }} />

token 通过根节点 inline style 应用,优先级高于样式表,不依赖引入顺序;变量都带 --cw- 前缀且挂在 .cw-root 上,不污染宿主 :root。

样式隔离

  • 不引 preflight,宿主 h1 / button 默认样式不变;
  • 每条 utility 前置 .cw-root,宿主的 .flex 与工作台的互不干扰;
  • 不使用 @layer,避免被宿主未分层样式压过。

导出与 Worker

导出默认在 Web Worker 中执行,产物里的 assets/export.worker-*.js 由 @cut-workbench/workbench 自身携带。若宿主有严格 CSP,可用 HostBridge.createExportWorker 完全接管 Worker 的创建。

含文字片段的工程会自动回退主线程渲染(文字依赖 DOM)。

浏览器要求

仅支持 Chromium 内核(Chrome / Edge):WebAV 依赖 WebCodecs 与 OPFS。

License

MIT