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

xie-cn

v1.0.7

Published

贤主之用人也,犹巧工之制木也,大者以为舟航、柱梁,小者以为楫、楔。

Downloads

12

Readme

物联网应用模块的最小化平台支撑(基于KOA实现)

1 概要说明

本框架意在实现为最小化的物联网应用模块提供容器,并提供简单易用的网络交互方式与高性能的实时数据更新

2 方法及使用

(1) skyframe

说明:窗体,我们将符合物联网平台规范的应用模块包含于独立的窗体,这个窗体提供最大化/最小化/关闭/重叠/透明/拖拽等常用功能

使用:


    var frame = new skyframe(); //获取对象
    frame.init({ //初始化
        id:"headFrame",
        container:$("#headDiv"),
        engine:"login"
    });

其中:init方法接受一个option参数,配置如下:

    var option = {
        id:"",  //为窗体设置一个ID
        container:$("body"),  //设置窗体的容器(jquery对象)
        engine:"",  //指定模块(规定:每个模块名称在项目中唯一) 
        closeable:false,  //设置窗体是否可关闭,默认为false
        maximizeable:false,  //设置窗体是否可最大化,默认为false
        minimizeable:false,  //设置窗体是否可以最小化,默认为false
        moveable:false,  //设置窗体是否可以拖拽,默认为false
        resizeable:false  //设置窗体是否可以改变大小,默认为false(如果设置为true,则鼠标可以拖动边框来改变窗体大小并触发窗体的resize事件)
        
    }

公共方法:

frame.flush();//刷新模块
frame.bind(evname,callback); //绑定事件,支持click,close,max,min,move,reset事件
frame.close(callback);  //关闭窗体
frame.maximize(callback);  //最大化窗体
frame.minimize(callback);  //最小化窗体
frame.resetFrame(callback); //恢复最初的大小和位置
/**
     * 移动到
     * @param top 绝对定位
     * @param left 绝对定位
     * @param callback 回调函数
     */
frame.moveTo(top,left,callback);  
/**
     * 设置宽高
     * @param width 宽度
     * @param height 高度
     * @param callback 回调函数
     */
frame.chengeTo(width,height,callback); 
frame.setStyle(key,style);  //设置窗口的样式
frame.setStyleObj(obj);  //设置窗口的样式

(2) netclient

说明:通讯模块,对于每一个符合物联网平台规范的应用模块,前端页面都会有此内置 net 对象,此对象提供非常灵活的前后台交互方法与实时的数据推送功能等,同样的在server端有一个net的global对象与其配合使用

数据链(dataline): netclient对象内置一个data属性,此属性具有前后台实时数据同步的能力,对此属性进行赋值或者修改等操作时,前后台都能够获取data的最新结果

例如,web端有如下操作:

net.data.a={"name":"小明"};

则后台可以获取这个属性,代码如下:

console.dir(net.data.a); //{"name":"小明"}

同理,后台也可以如上赋值被web端直接读取

公共方法: on(eventname,callback):绑定侦听事件,对应服务器端的emit方法,这里需要注意call dataline initserver connect disconnect这几个事件为内置事件,禁止侦听

web端写法

net.on("myevent",function(data){
    console.dir(data);
});

这样当对应的服务端有如下代码执行时,将打印data数据

var data = {a:12};
net.emit("myevent",data); //触发前台的myevent事件

emit(eventname,data,callback):触发服务器端绑定的事件,对应于服务器端的on方法,同样注意 call dataline initserver connect disconnect这几个事件为内置事件,禁止侦听

web端写法

net.emit("testEmit",{a:1},function(res){
    console.dir(res);
});

这样当对应的服务端有如下代码时,则触发执行并触发前台的callback

var data = {a:12};
//由前台的emit方法触发
net.on("testEmit",function(obj,callback){
    console.dir(obj);  //前台传过来的数据对象
    callback&callback(data);  //前台的callback会打印出{a:12}
}); 

call(funcname,data,callback):调用服务端的方法

web端写法

net.call("test",{a:1},function(data){
    console.dir(data);
});

当对应的服务端有如下方法,将会执行并触发前台的callback

this.test = function(data,callback){
    console.dir(data);
    callback&callback(1);  //前台将打印1
}

getAjaxURL();获取Ajax的路径给第三方的插件用,需要配合getAjaxData方法使用,才能正常发起一个Ajax请求

var url = net.getAjaxURL();

getAjaxData(method,parms);由于后台过滤,发起Ajax必须要带一些参数,配合getAjaxURL才能正常的发起一个Ajax;method对应后台的方法名称,parms为传入后台的参数

var data = net.getAjaxData("testmethod",parms);//这样 后台的testmethod方法就可以被ajax调用,并且穿过去parms参数供业务使用

getView(method, parms, callback):经对应的服务器端method得到ejs,注意:如果method等于getEjs的话,则parms参数必须为有效的ejs路径字符串,此种情况直接返回parms指定的模版

web端写法

net.getView("testRender",'',function(res){
    $("body").html(res);
});

对应的服务器端写法

this.testRender = async function(ctx,parms){
    console.dir(parms);
    return ctx.render("engine/example/web/sonejs/student.ejs",{});
}

getData(method, parms, callback):向后台请求获取数据,方法使用同getView相同,只是对应的后台写法res.render应改为res.body

我们可能是后台自启动的服务推送给前台数据,为了适应这样的场景,添加如下两个方法:

/**
 * 根据服务名称获取所有已经开启的socketIO客户端信息
 * @param service
 * @returns [{"key":"socketid","value":{net:{},service:""}},{}......]
 */
var clients = net.getSockets(service);

getSockets方法会获得对应service的模块的所有打开着的客户端,返回一个形如[{"key":"socketid","value":{net:{},service:""}},{}......]的一个数组对象 通过遍历这个对象可以获取每一个net,然后就可以向指定的前台推送数据了

第二个方法如下:

//获取所有的socket信息
var property = net.getAllSocket();

这个方法用一个特定的数据结构进行存储,结构如下:

{
    service:[
        {"key":"socketid","value":{net:{},service:""}},
        {"key":"socketid","value":{net:{},service:""}},
        ...
    ],
    ...
}

它会获取所有的客户端,也就意味着它可以向其他任何一个模块推送数据,这将会增加模块的耦合,导致业务的混乱,增加代码的复杂度,增加维护难度.总之,不推荐使用

(3) 数据联动

说明:借助于数据链(dataline),应用Vue.js使数据变动绑定到dom元素上,实现数据链对页面元素的实时控制,包括文本、样式、显示/隐藏、元素填充等

公共方法: datachange(id,option);初始化数据绑定 示例:

例如存在如下HTML片段:

<div id="realData">

<span>{{message}}</span> <span v-bind:title="title">

绑定title属性

</span>

<p v-if="seen">显示与隐藏</p>

</div>

使用datachange方法初始化数据绑定,如下:


var vue = net.datachange("realData"); //"realData"为需要数据绑定的元素ID,此方法返回一个Vue实例

当数据链(dataline)的message、title、seen属性值发生变动时,页面元素则同时发生变化(显示message的值、title属性被动态赋值、显示与隐藏)

比如:

当net.data.message="hello world"时,页面`<span>{{message}}</span>`则相应的变为`<span>hello world</span>`
当net.data.title = "测试标题"时,页面`<span v-bind:title="title">绑定title属性</span>`则相应的变为`<span v-bind:title="测试标题">绑定title属性</span>`
当net.data.seen = true时,`<p v-if="seen">显示与隐藏</p>`会显示
当net.data.seen = false时,`<p v-if="seen">显示与隐藏</p>`会隐藏掉

更多功能与效果请参见 Vue.js官网:https://cn.vuejs.org/

(4) 规范

(1) 所有独立业务模块必须放在 /engine 文件夹下;模块名称为文件夹名称,文件夹包含 src与web两个文件夹,src存放服务端代码,web存放页面、js、css、图片等前端静态文件,web下的文件都能够被浏览器直接访问到

--src文件夹下必须包含service.js(必须叫这个名字)文件作为后台逻辑的统一入口,结构如下:
--业务模块必须包含README.MD文件,说明模块的用途与注意事项等

service.js


const jwt = require('jsonwebtoken');
function service(){ 
    //内置方法,实现此方法,则当模块调用时先执行此方法的逻辑
    this.init = function(ctx,parms){
        return ctx.render("engine/login/web/login/login.ejs",{});
    }

    //可被前台getView调用的方法
    //ctx为KOA2框架的上下文
    //parms为前台传送的参数
    this.login = async function(ctx,parms){
        var data = JSON.parse(parms); 
        const token = jwt.sign({user: data.username}, sysconfig.jwt.option.secret); 
        var res = {flag:"success",data:token};
        return ctx.body=JSON.stringify(res);
    }

}
module.exports = service;

(2) 所有的后台模块必须发布成独立的nodejs模块,放在node_modules下,可使用npm install命令安装

(3) 所有的前端模板必须放在其被引用的独立业务模块的web下,不允许多个独立业务模块公用一个前端模板,哪怕使用的模板一模一样

(4) 以上规范对架构重构者或资深nodejs开发者无效