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

dsh-harmony-react

v0.3.2

Published

React-aware source patch factories for dsh-harmony

Readme

dsh-harmony-react

English | 简体中文

面向 dsh-harmony 的 React 源码 Patch 工厂。

该包是运行在 Node 侧的 Harmony 扩展,不是 DSH 客户端运行时。它把 React Element 和 Component 操作转换为普通的 HarmonySourcePatch 声明;Patch 发现、排序、校验、事务和 WebUI 热更新仍由 Harmony 负责。

架构

下游包是唯一的 DSH 插件,包含 Harmony Patch Provider、立即预取并导出 React 组件的客户端 bundle,以及用于出现在 Loader Tree 中的最小 DSH 入口。

dsh-harmony-react 只是该 Provider 的依赖,不会注册第二个 DSH 插件。可选的 dsh-harmony-react/studio 浏览器 API 仅在 Studio Preview 中委托给注入的注册表,在普通 dsh web 会话中注册操作为空操作。Studio Host 使用独立的 dsh-harmony-react/studio-host 集成契约;Patch Provider 不应导入这个仅供 Host 使用的入口。

示例

const { element } = require('dsh-harmony-react')

module.exports = element({
  id: 'custom-sidebar-brand',
  description: '替换内置的侧栏品牌标识。',
  target: {
    package: '@deepseek-ai/dsh-client-ui-sidebar',
    version: '0.1.0-rc.8',
    file: 'lib/client.js',
  },
  select: { component: 'BrandWordmark' },
  expect: 1,
  operation: {
    kind: 'replace',
    with: { module: 'my-harmony-plugin', export: 'CustomBrand' },
  },
})

生成的 Patch 会替换现有 JSX 调用中的组件类型,并保留 props 和 key。由于注入的同步 require() 需要立即解析客户端模块,下游包必须声明客户端 bundle 为立即预取:

{
  "dsh": {
    "client": { "immediately": true, "platform": "web" },
    "harmony": { "patches": ["./patch.cjs"] }
  }
}

Element 与 Component Patch

element() 用于一个或多个明确的编译后 jsx/jsxs 调用点,支持 replace、wrap、insert-before、insert-after、transform-props 和 remove。变更只影响匹配的调用点。

component() 用于修改带初始化值的变量或具名函数声明所定义的组件 binding。decorate 使用浏览器侧高阶函数包装当前定义,replace 则替换定义;所有读取该 binding 的调用点都会看到结果。

const { component } = require('dsh-harmony-react')

module.exports = component({
  id: 'decorate-button',
  description: '装饰共享 Button 组件的所有调用。',
  target: {
    package: '@deepseek-ai/dsh-client-ui-buttons',
    version: '0.1.0-rc.8',
    file: 'lib/client.js',
  },
  select: { name: 'Button' },
  expect: 1,
  operation: {
    kind: 'decorate',
    with: { module: 'my-harmony-plugin', export: 'withFeature' },
  },
})

Component selector 必须直接匹配带初始化值的 VariableDeclaration,或带函数体的具名 FunctionDeclaration。函数声明会被重写为初始化的 const binding,因此被 Patch 的函数组件不得在声明前读取;如目标依赖函数提升,或需要修改函数体及其他声明形式,请使用核心 Source Patch。

Element selector 可指定局部组件、成员组件、原生标签或原始 TSQuery。原始 Element TSQuery 必须选中编译后的 jsx/jsxs CallExpression;原始 Component TSQuery 必须选中变量或具名函数声明。每个 Patch 都必须提供精确的 expect、目标版本和目标文件。若同一个 Patch 的嵌套匹配产生重叠编辑,操作会被拒绝;需要同时修改父子节点时,请拆成显式排序的 Patch。

React Patch 始终基于前序 Patch 产生的源码继续应用,因此兼容的 decorator 和 props 变换会按 Harmony 的最终 Patch 顺序组合。React 不引入第二套排序模型。

基于名称的 Component selector 会为引用该 binding 的 JSX 调用生成 Preview trace 元数据。原始 TSQuery 仍可正常应用,但不会生成调用路径追踪。客户端 props transformer 是普通函数,不能调用 Hook;需要 Hook 时应使用 wrapper 或 replacement 组件。

Studio Element

Studio 只显示 Draft 显式注册的子树与变量。通过相同的 surfaceId 和路径,把注册项关联到 dsh-ui-container 的 SurfaceHost 或 SurfaceBoundary:

import { registerStudioElement } from 'dsh-harmony-react/studio'

let accent = '#245fd6'
const listeners = new Set<() => void>()

const dispose = registerStudioElement({
  owner: 'my-harmony-plugin',
  element: {
    id: 'settings-card',
    label: 'Settings card',
    boundary: { surfaceId: 'settings', path: ['appearance', 'card'] },
    source: { file: 'src/SettingsCard.tsx', line: 12 },
    variables: [{
      kind: 'group',
      id: 'appearance',
      label: 'Appearance',
      children: [{ kind: 'variable', id: 'accent', label: 'Accent', control: 'color' }],
    }],
  },
  bindings: {
    accent: {
      get: () => accent,
      set(value) {
        accent = String(value)
        for (const listener of listeners) listener()
      },
      subscribe(listener) {
        listeners.add(listener)
        return () => listeners.delete(listener)
      },
    },
  },
})

请在客户端插件或组件生命周期结束时调用返回的 disposer。插件级控制项使用 registerStudioVariables。源码路径必须是相对于 Draft 的规范化 POSIX 路径。变量 binding 是唯一的实时写入界面:Studio 会串行化更新、调用 set,随后在注册表快照中发布 get() 的当前值。

variables 是树结构,group 可以包含变量或嵌套 group。同一次注册中的节点 ID 与变量 ID 必须唯一;binding 只对应 variable 节点,并以变量 ID 为键。

要让 Studio 持久化控制项默认值,请在变量定义中添加 defaultSource。before 和 after 必须在 Draft 文件中精确包围一个源码字面量;Studio 只替换锚点之间的文本,并拒绝含糊或非字面量匹配。它修改的是下次加载的默认值,不会替换响应式运行时 binding。

Element boundary 只证明 Draft 拥有所注册的子树契约。工厂生成的 Preview trace wrapper 可以为选中的 React 渲染路径补充候选 Patch 元数据,但不代表精确的节点归属;没有 trace 意图的原始 Source Patch 仍只能通过 Harmony 的目标级检查查看。