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

mflows

v1.22.7

Published

A visual workflow editor library for Vue 3 with drag-and-drop interface

Readme

mflows

轻量的 Vue 3 可视化工作流引擎与编辑器。开箱即用,支持自定义节点扩展。

  • 适配 Vue 3 + Vite
  • 内置流程编辑器组件与主题系统
  • 简洁的 BaseNode 抽象,快速编写自定义节点
  • ESM 与 UMD 双格式,支持 CDN 引入

安装

  • npm i mflows
  • pnpm add mflows
  • yarn add mflows

全局样式(必须):

  • import 'mflows/style.css'

快速上手(最简单用法)

在你的组件中直接使用编辑器:

<template>
  <MFlowEditor style="height: 600px" />
</template>

<script setup lang="ts">
import { MFlowEditor } from 'mflows'
import 'mflows/style.css'
</script>

这会渲染一个可拖拽的流程编辑器画布,并加载内置节点。


使用 MFlowEditor

在你的组件中直接使用编辑器(无需传入数据或管理器):

<template>
  <MFlowEditor style="height: 600px" />
</template>

<script setup lang="ts">
import { MFlowEditor } from 'mflows'
import 'mflows/style.css'
</script>

通过 ref 获取实例,调用常用 API:

<template>
  <MFlowEditor ref="editor" style="height: 600px" />
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { MFlowEditor, BaseNode } from 'mflows'

const editor = ref<any>(null)

class MyNode extends BaseNode<any, any> {
  static NodeType = 'MyNode'
  protected async initialize() {
    this.inputPoints = [{ id: 'execute', name: '执行', dataType: 'flow' }]
    this.outputPoints = [{ id: 'next', name: '下一步', dataType: 'flow' }]
  }
}

onMounted(() => {
  // 注册自定义节点
  editor.value.registerNode('MyNode', { name: '我的节点', logic: MyNode })

  // 切换主题(默认已为 dark)
  editor.value.switchTheme('dark')

  // 通过内部 store 操作数据
  const store = editor.value.getStore()
  store.addNode({ id: 'n1', type: 'MyNode', position: { x: 200, y: 120 }, data: {} })
})
</script>

常用 API(实例方法):

  • getStore():获取内部工作流 store
  • getNodeManager() / getThemeManager()
  • registerNode(type, config) / unregisterNode(type)
  • registerTheme(theme) / switchTheme(name)
  • addNode(node) / removeNode(id) / moveNode(id, pos)
  • addEdge(edge) / removeEdge(id)
  • updateNode(id, patch) / updateNodeData(id, data)
  • setActiveNodeId(id) / findNode(id)
  • importWorkflow(json) / exportWorkflow() / clearWorkflow()
  • saveSnapshot() / undo() / redo()

自定义一个最小节点(示例)

import { BaseNode, registerNode } from 'mflows'

class MyNode extends BaseNode<{ times: number }, { result: number }> {
  static NodeType = 'MyNode'

  protected async initialize() {
    this.inputPoints = [
      { id: 'execute', name: '执行', dataType: 'flow' },
      { id: 'number',  name: '数字', dataType: 'number' }
    ]
    this.outputPoints = [
      { id: 'result', name: '结果', dataType: 'object' },
      { id: 'next',   name: '下一步', dataType: 'flow' }
    ]
  }

  protected receiveData() {
    this.executeConfigUpdate()
  }

  protected checkConfig() {
    return typeof this.settings.times === 'number'
  }

  protected async processConfigUpdate() {
    const value = Number((this as any).nodeData?.value ?? 1)
    return { result: value * (this.settings.times ?? 1) }
  }
}

registerNode('MyNode', {
  name: '我的节点',
  logic: MyNode
})

注册后,你可以在编辑器里拖拽并连接该节点,或按你的业务方式创建与使用。


通过 CDN 使用

<link rel="stylesheet" href="https://unpkg.com/mflows@latest/dist/assets/mflows.css" />
<script src="https://unpkg.com/mflows@latest/dist/mflows.umd.js"></script>
<script type="module">
  const { Mflows } = window
  const app = Vue.createApp({
    template: '<MFlowEditor style="height:600px" />',
    components: { MFlowEditor: Mflows.MFlowEditor }
  })
  app.mount('#app')
</script>

API(含示例)

  • 入口导出(常用):
    • 组件:MFlowEditor、MContainer
    • 核心:BaseNode
    • 注入与依赖:useMFlow、MFlowInjectionKey
    • 主题:themeManager、darkTheme、lightTheme、ThemeManager
    • 管理器:NodeManager(单例见 useMFlow().nodeManager)
    • 初始化:setupMFlow、setupMFlowDefaults
    • 无头运行:FlowRunner、runWorkflow
import {
  MFlowEditor, MContainer, BaseNode,
  useMFlow, MFlowInjectionKey,
  themeManager, darkTheme, lightTheme,
  NodeManager, setupMFlow, setupMFlowDefaults,
  FlowRunner, runWorkflow
} from 'mflows'
  • 类型声明路径:dist/index.d.ts(构建时自动复制)

注入 API:useMFlow(推荐)

在任意组件中直接获取完整能力:

import { useMFlow } from 'mflows'

const api = useMFlow()
const { workflow, dependencies, variables, resources, ui, nodeManager, themeManager } = api

// 依赖管理示例
await dependencies.addDependency({ name: 'lodash', version: '4.17.21', type: 'umd', source: 'cdn', url: 'https://cdn.jsdelivr.net/npm/lodash/lodash.min.js' })
await dependencies.loadDependency('[email protected]')
const _ = dependencies.getLoadedDependency('[email protected]')

// 变量管理示例
variables.addGlobalVariable({ key: 'token', type: 'string', value: 'xxx' })

// 资源管理示例
const jsonRes = resources.createJsonResource('config.json')

// UI 折叠/展开
ui.toggleLeft(); ui.toggleRight(); ui.toggleBottom()

初始化:setupMFlow 与默认节点

  • setupMFlow(options?):配置额外节点与分类,或重置默认注册表
  • setupMFlowDefaults():注册内置节点并构建默认分类

可在应用启动或编辑器挂载前执行:

import { setupMFlow, setupMFlowDefaults } from 'mflows'

// 仅使用默认内置节点与分类
setupMFlowDefaults()

// 或者:叠加私有节点与自定义分类
setupMFlow({
  extraNodes: {
    MyNode: { name: '我的节点', component: MyVueComp, logic: MyNodeLogic, category: 'process' }
  },
  categories: [
    { code: 'custom', label: '自定义', color: '#222', items: ['MyNode'] }
  ],
  reset: false, // 在现有注册基础上叠加
  includeDefaultNodes: true
})

Options 说明:

  • extraNodes:按类型注册节点(与 NodeManager.register 相同形状)
  • categories:构建左侧分类面板;仅展示已注册且启用的节点
  • reset:是否先清空默认注册(默认 true)
  • includeDefaultNodes:是否包含内置节点(默认 true)

NodeManager(核心注册中心)

常用方法:

  • register(type, registry) / unregister(type)
  • registerMultiple(map) / unregisterMultiple(types)
  • updateNodes(map)(批量更新 name、icon、enabled 等)
  • getAllNodes() / getEnabledNodes() / getNodeConfig(type)
  • getNodesByCategory('input' | 'process' | 'output' | 'custom')
  • setNodeEnabled(type, enabled) / setNodesEnabled(types, enabled)
  • getComponent(type) / getLogicClass(type) / getPropertyPanel(type) / getIcon(type)
  • getNodeCategories() / getNodeCategoriesAsArray() / getNodeCategory(code) / addNodeCategory(code, group)
  • setDebug(true | false)
  • 动态加载:loadNodeLogicDynamic(category, nodeName) / loadNodeComponentDynamic(category, nodeName)
    • category ∈ 'triggers' | 'inputs' | 'processing' | 'http'

示例:

const { nodeManager } = useMFlow()

nodeManager.register('MyNode', { name: '我的节点', component: MyComp, logic: MyNodeLogic, category: 'process' })
nodeManager.updateNodes({ MyNode: { enabled: true, description: '业务说明' } })

const groups = nodeManager.getNodeCategoriesAsArray()
console.log(groups.map(g => ({ code: g.code, items: g.items.length })))

FlowRunner(无头运行器)

无需 UI,直接在内存中按图执行:

import { runWorkflow } from 'mflows'
import type { FlowNode } from 'mflows'

const nodes: FlowNode[] = [
  { id: 'n1', type: 'InitialNode', data: {} },
  { id: 'n2', type: 'DebugNode',   data: {} }
]
const edges = [
  { id: 'e1', source: 'n1', target: 'n2', sourceHandle: 'next', targetHandle: 'execute' }
]

const runner = await runWorkflow({ nodes, edges }, {
  onNodeEvent(id, t, e) {
    if (t === 'success') console.log(`[${id}]`, e.value)
  },
  entryIds: ['n1']
})

// 也可以:await runner.run(['n1'])
// 调试:const n2 = runner.getNodeInstance('n2')
// 停止:runner.stop()

说明:

  • FlowNode = @vue-flow/core 的 Node 扩展,需提供 id 与 type(节点类型需已注册)
  • onNodeEvent 可监听节点 dataChange、success、error、processing、initialized
  • entryIds 未提供时,默认从“无入边”的根节点启动

变量 / 资源 / 依赖 管理(store 快捷能力)

const { variables, resources, dependencies } = useMFlow()

// 变量
variables.addGlobalVariable({ key: 'env', type: 'json', value: { api: '/v1' } })
variables.updateGlobalVariable({ key: 'env', type: 'json', value: { api: '/v2' } })

// 资源
const item = resources.createJsonResource('payload.json')
const list = resources.getResources('all')
resources.removeResource(item.id)

// 依赖(UMD/CDN)
await dependencies.addDependency({ name: 'dayjs', version: '1.11.10', type: 'umd', source: 'cdn', url: 'https://cdn.jsdelivr.net/npm/dayjs/dayjs.min.js' })
await dependencies.loadDependency('[email protected]')
const dayjs = dependencies.getLoadedDependency('[email protected]')

更完整的类型声明与导出请参见 dist/index.d.ts(发布包已内置)。


版本与兼容

  • ESM:dist/mflows.es.js
  • UMD:window.Mflows
  • 样式:import 'mflows/style.css'

常见问题(FAQ)

  • 样式不生效?
    • 请确保在应用入口或使用组件前引入:import 'mflows/style.css'。
    • 如使用 UMD/CDN,请添加:
  • 提示找不到组件/类型?
    • 请确认已安装 peerDependencies:vue ^3.3.x、element-plus ^2.3.x(仅在示例/编辑器使用到)。
    • 确保你的打包器支持 ESM(Vite、Webpack5+、Rspack、Nuxt3 等)。
  • UMD 全局名是什么?
    • window.Mflows(组件如 MFlowEditor 位于 Mflows.MFlowEditor)。
  • 入口解析失败(CJS/ESM)?
    • 升级到 mflows >= 1.0.0,main/module/exports 已与产物对齐;CDN 使用无需额外配置。

鸣谢

感谢以下为本项目作出贡献的团队与个人(基于提交记录,持续更新):


许可

MIT

文档网站

我们正在将文档系统化,使用 VitePress 构建:

  • 本地开发:npm run docs:dev
  • 构建:npm run docs:build
  • 预览:npm run docs:preview

文档入口位于 docs/,包含指南、API 参考与示例。