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 🙏

© 2024 – Pkg Stats / Ryan Hefner

flow-js

v0.6.7

Published

Flowjs ======

Downloads

35

Readme

Flowjs

一个开放的,面向业务流程的,可灵活扩展和定制的前端业务开发框架。

本次0.5.x的更新相比之前版本有巨大的变化。

  • 极大的简化了《流程》和《步骤》的定义。
  • 简化输入输出数据的校验,不做深度校验,提高执行效率(看未来是否有需要加深度校验)
  • 内部通过context的传递来避免多次调用时,步骤数据会互相覆盖的情况。
  • 开始编写测试用例。

框架思路

互联网产品的特点就是快速的迭代更新,这就对前端的响应速度提出了挑战。flowjs的思路,就是通过抽象变化的产品形态背后相对稳定的业务流程,来以不变应万变!

框架由《流程》和《步骤》两个部分组成。《流程》负责定义一个业务逻辑的流程,《步骤》负责定义流程中一个步骤的实现。

开发同学可以将一个产品,定义为Flowjs的一个《流程》。当产品细节发生变化时,开发同学可以在基于流程不变的情况下,通过快速修改对应的步骤,来快速响应产品变化。

并且一个产品流程可以开放出来,类似的产品可以复用该《流程》,用自己的《步骤》实现来迅速完成自己产品的开发。

Flowjs还可以帮助开发者提高自己代码的逻辑性和可读性。《流程》代码与流程图有异曲同工之处。能够让其他开发者更容易的读懂和维护你的代码。

注意事项

每一个步骤需要明确的定义本步骤的输入与输出数据,否则会获取不到需要的流程数据,本步骤对数据做出的修改也无法提交到流程里。

允许一个步骤不经过定义,就直接使用。流程在执行时会自动跳过该步骤。便于先跑通主要流程,再实现具体步骤。

步骤与步骤之间尽可能的减少依赖

每一个步骤只能调用一次callback通知框架步骤完成

最佳实践

把Flowjs包到你的类中,提供默认的《步骤》实现。

function YouClass(options){
    this._flow = new Flow();
    var steps = {
        'step1':require('./step1'),
        'step2':require('./step2'),
        'step3':require('./step3')
    };
    if(options && options.steps){
        Object.extend(steps,options.steps);
    }
    var flow = this._flow;
    for(var stepName in steps){
        if(steps.hasOwnProperty(stepName)){
            flow.implement(stepName,steps[stepName]);
        }
    }
}

对《步骤》的重写,可以通过引用新的步骤文件实现。例如:

var steps = {
    'step1':require('./step1'),
    'step2':require('./step2'),
    'step3':require('./step3')
};

要重写step1,可以新创建一个step1文件newstep1,然后引用新文件

var steps = {
    'step1':require('./newstep1'),
    'step2':require('./step2'),
    'step3':require('./step3')
};

测试

nodejs环境下

npm install -g mocha
mocha test/

《流程》定义

var Flow = require('flowjs');

var flow = new Flow();

//《步骤》定义
flow.addStep('step1',{
    type:'step',  //《步骤》类型。step/condition/event。可选
    input:{ //输入数据
        param1:{
            empty:false //是否允许为空,默认为true
        }
    },
    output:{ //输出数据,如果param1未定义为输出数据,那么步骤内对param1做出的修改,不会保存的《流程》中
        param1:{
            empty:false //是否允许为空,默认为true
        }
    }
});
flow.addStep('step2'); //也可以仅仅这样来定义一个《步骤》。这将会定义一个type为step,没有输入输出数据的《步骤》
flow.addStep('step3',{ //这样可以定义一个condition类型的《步骤》
    type:'condition'
});
flow.addStep('step4',{ //这样可以定义一个event类型的《步骤》
    type:'event'
});

//《步骤》的实现
flow.implement('step1', {
    /**
     * 《步骤》的go方法,会作为《步骤》的入口,《流程》在执行到该《步骤》时,会执行go方法
     * @param  {[object]}   data    如果定义了input,那么会传入需要输入的数据
     * @param  {Function} callback  《步骤》执行完成后,需要调用callback通知《流程》
     */
    go: function(data, callback) {
        callback();
    }
});
flow.implement('step2', {
    go: function(data, callback) {
        callback();
    }
});
/**
 * 这是一个condition类型的《步骤》
 * @param  {Function} callback  这个回调的原型是function(data,condition){}
 * 其中condition表示步骤选择的分支。例子中表示,执行该步骤后,选择case1分支作为后续的步骤继续执行
 */
flow.implement('step3', {
    go: function(data, callback) {
        callback(data,'case1');
    }
});
/**
 * 这是一个event类型的《步骤》
 * @param  {function} callback 这个是步骤结束后的回调,同step类型的回调
 * @param  {function} trigger 这个是有事件发生时,用于通知《流程》的方法
 */
flow.implement('step4', {
    go: function(data, callback, trigger) {
        $(document).on('click',function(){
            trigger(data,'docclick');
        });
        callback(data,'case1');
    }
});

/**
 * begin的原型为function(data){}
 * 其中data为传入到流程中的初始数据
 */
flow.begin();
flow.go('step1');
flow.go('step2');
flow.go('step3',{
    cases:{
        //定义case1条件分支
        case1:function(){
            flow.go('step4',{
                events:{
                    //定义docclick事件发生时的处理
                    docclick:function(){
                        flow.go('step5');
                    }
                }
            });
        }
    }
});
//一个流程的所有除event类型的步骤都执行完毕后,会触发end事件。
flow.on('end',function(){
    
});

API

Flow

implement:function(stepName,options){}

    public

    实现《流程》中的一个《步骤》。

    stepName

        《步骤》名

    options

        实现《步骤》的相关参数

destroy:function(){}

    public

    销毁流程,会调用每一个执行过的步骤的destroy方法,让每个步骤有机会去释放资源。

go:function(step,options){}

    public

    用于定义《流程》

    step

        步骤名

    options.events

        定义传入event类型《步骤》的事件集

    options.cases

        定义传入condition类型《步骤》的分支集

addStep:function(name,options){}

    public

    向流程注册步骤

    name

        《步骤》名

    options

        定义《步骤》的相关参数

升级指导

0.5.0开始,《流程》和《步骤》的定义方式全部发生变化,请老版本代码按照0.5.0的方式重新定义