New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

yog-bigpipe

Package Overview
Dependencies
Maintainers
4
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

yog-bigpipe - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

4

index.js

@@ -26,3 +26,5 @@ var BigPipe = require('./lib/bigpipe.js');

// res.locals 肯定是一个对象,不信可以去查看 express/middleware/init
res.locals.isQuickingMode = bigpipe.isQuickingMode();
res.locals.isQuicklingMode = bigpipe.isQuicklingMode();
// 拼写兼容
res.locals.isQuickingMode = res.locals.isQuicklingMode;

@@ -29,0 +31,0 @@ res.on('finish', destroy);

@@ -17,2 +17,3 @@ var Pagelet = require('./pagelet.js');

this.quicklings = [];
this.parentQuicklings = [];

@@ -65,14 +66,21 @@ this.on('pagelet:after', this._onPageletDone);

BigPipe.prototype.addQuicklingPagelets = function (pagelets) {
var arr = this.quicklings;
arr && arr.push.apply(arr, pagelets);
var me = this;
pagelets.forEach(function (id) {
var pageletIDSplit = id.split('@');
var pageletID = pageletIDSplit.shift()
me.quicklings.push(pageletID);
me.parentQuicklings.push.apply(me.parentQuicklings, pageletIDSplit);
});
};
// 判断是否是 quickling 模式。
BigPipe.prototype.isQuickingMode = function () {
BigPipe.prototype.isQuicklingMode = function () {
return !!(this.quicklings && this.quicklings.length);
};
// 拼写兼容
BigPipe.prototype.isQuickingMode = BigPipe.prototype.isQuicklingMode;
// 添加 pagelet.
BigPipe.prototype.addPagelet = function (obj) {
// 已经晚了了,不处理。

@@ -87,25 +95,37 @@ if (this.state === status.fulfilled) {

// todo 如果某个 quickling widget 里面再包含一个非 quickling 的 pagelet, 则不会渲染。
// 应该需要渲染才对。
// 注意: 如果 quickling 的 widget 藏在某些异步 widget 里面,岂不是找不到?
if (!this.isQuickingMode() && obj.mode !== mode.pipeline && obj.mode !== mode.async) {
if (!this.isQuicklingMode() && obj.mode !== mode.pipeline && obj.mode !== mode.async) {
// 非 quickling 请求,只接收 pipeline 和 async 模式的 pagelet.
return false;
}
else if (this.isQuickingMode()) {
var parent = obj;
else if (this.isQuicklingMode() && !~this.quicklings.indexOf(obj.id)) {
// 以下几种情况均需要继续执行
// 1. 被声明为父Pagelet
// 2. 先祖Pagelet被请求了
// 找到最近的一个 quickling 父亲节点。
while (parent && parent.parentId) {
if (parent.mode === mode.quickling) {
break;
if (!~this.parentQuicklings.indexOf(obj.id)) {
var parent, founded;
// 如果没有被声明为父Pagelet,则检查是否属于先祖Pagelet被请求了的情况
// 如果是lazy模式,则不寻找先祖Pagelet
if (obj.lazy) {
return false;
}
parent = this.map[parent.parentId];
// 支持嵌套pagelet时,一次性返回所有pagelet
parent = obj;
founded = false;
// 如果指定的pagelet不在quicklings列表中,检查先祖节点,查看先祖节点是否在列表中,如果在则加载
// 以此实现Pagelet A contain Pagelet B时,会用一个请求同时返回A与B
while (parent && parent.parentId) {
parent = this.map[parent.parentId];
if (parent.mode === mode.quickling && !!~this.quicklings.indexOf(parent.id)) {
founded = true;
// 插入为需要输出的Pagelet
this.quicklings.push(obj.id);
break;
}
}
if (!founded) {
return false;
}
}
if (parent.mode !== mode.quickling || !~this.quicklings.indexOf(parent.id)) {
return false;
}
}

@@ -211,3 +231,5 @@

var content = this.format(pagelet);
content && this.push(content);
if (!this.isQuicklingMode() || !!~this.quicklings.indexOf(pagelet.id)) {
content && this.push(content);
}
this._markPageletRendered(pagelet);

@@ -218,3 +240,3 @@ };

var tpl = this.options.tpl;
var type = this.isQuickingMode() ? 'quickling' : '_default';
var type = this.isQuicklingMode() ? 'quickling' : '_default';
var json = pagelet.toJson();

@@ -221,0 +243,0 @@ var obj = {};

{
"name": "yog-bigpipe",
"version": "0.1.0",
"version": "0.2.0",
"description": "An express.js middleware for fis widget pipline output.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -1,126 +0,289 @@

(function() {
var Util = (function() {
var d = document;
var head = d.getElementsByTagName('head')[0];
(function (root) {
// BigPipe 依赖的各种处理器
// 可以通过此部分换成 [lazyrender](https://github.com/rgrove/lazyload/),
// 以达到更好的 js 并发下载性能。
// get broswer info
var browser = (function() {
var ua = navigator.userAgent.toLowerCase();
var match = /(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) || !/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) ||
[];
return match[1];
})();
var d = document;
var head = d.getElementsByTagName('head')[0];
var loadedRes = {};
var loadingRes = {};
var loadJs = function(url, cb) {
var script = d.createElement('script');
var loaded = false;
var wrap = function() {
if (loaded) {
// get broswer info
var browser = (function () {
var ua = navigator.userAgent.toLowerCase();
var match = /(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) || !/compatible/.test(ua) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec(ua) ||
[];
return match[1];
})();
// load Js and excute it.
// 加载 JS 并执行它。
function loadJs(url, ignoreDuplicate, cb) {
if (ignoreDuplicate && loadedRes[url]) {
cb && cb();
return;
}
if (ignoreDuplicate && loadingRes[url]) {
loadingRes[url].push(cb);
return;
}
loadingRes[url] = loadingRes[url] || [];
var script = d.createElement('script');
var loaded = false;
var wrap = function () {
if (loaded) {
return;
}
loaded = true;
loadedRes[url] = true;
if (ignoreDuplicate) {
for (var i = 0; i < loadingRes[url].length; i++) {
loadingRes[url][i] && loadingRes[url][i]();
}
loadingRes[url] = null;
}
cb && cb();
};
script.setAttribute('src', url);
script.setAttribute('type', 'text/javascript');
script.onload = script.onerror = wrap;
script.onreadystatechange = wrap;
head.appendChild(script);
}
// load css and apply it.
// 加载 css, 并应用该样式。
function loadCss(url, ignoreDuplicate, cb) {
if (ignoreDuplicate && loadedRes[url]) {
cb && cb();
return;
}
if (ignoreDuplicate && loadingRes[url]) {
loadingRes[url].push(cb);
return;
}
loadingRes[url] = loadingRes[url] || [];
var link = d.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
if (browser === 'msie') {
link.onreadystatechange = function () {
/loaded|complete/.test(link.readyState) && cb();
}
}
else if (browser === 'opera') {
link.onload = cb;
}
else {
// FF, Safari, Chrome
(function () {
try {
link.sheet.cssRule;
}
catch (e) {
setTimeout(arguments.callee, 20);
return;
}
loadedRes[url] = true;
if (ignoreDuplicate) {
for (var i = 0; i < loadingRes[url].length; i++) {
loadingRes[url][i] && loadingRes[url][i]();
}
loadingRes[url] = null;
}
cb();
})();
}
loaded = true;
cb && cb();
};
head.appendChild(link);
}
script.setAttribute('src', url);
script.setAttribute('type', 'text/javascript');
script.onload = wrap;
script.onreadystatechange = wrap;
head.appendChild(script);
};
var loadCss = function(url, cb) {
var link = d.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
// eval js code.
// 直接执行 js 代码。
function globalEval(code) {
var script;
if (browser === 'msie') {
link.onreadystatechange = function() {
/loaded|complete/.test(link.readyState) && cb();
}
} else if (browser == 'opera') {
link.onload = cb;
} else {
//FF, Safari, Chrome
(function() {
try {
link.sheet.cssRule;
} catch (e) {
setTimeout(arguments.callee, 20);
return;
};
cb();
})();
code = code.replace(/^\s+/, '').replace(/\s+$/, '');
if (code) {
if (code.indexOf('use strict') === 1) {
script = document.createElement('script');
script.text = code;
head.appendChild(script).parentNode.removeChild(script);
}
else {
eval(code);
}
}
}
head.appendChild(link);
};
// append style cod to dom.
// 直接应用样式代码到页面。
function appendStyle(code) {
var dom = document.createElement('style');
dom.innerHTML = code;
head.appendChild(dom);
}
var appendStyle = function(code) {
var dom = document.createElement('style');
dom.innerHTML = code;
head.appendChild(dom);
// ajax 请求,简单实现,可以修改成使用 jQuery.ajax 如果已经依赖了的话。
function ajax(url, cb, data) {
var xhr = new(window.XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP');
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
cb(this.responseText);
}
};
xhr.open(data ? 'POST' : 'GET', url + '&t=' + (new Date()).getTime(), true);
var globalEval = function(code) {
var script;
if (data) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.send(data);
}
code = code.replace(/^\s+/, '').replace(/\s+$/, '');
if (code) {
if (code.indexOf('use strict') === 1) {
script = document.createElement('script');
script.text = code;
head.appendChild(script).parentNode.removeChild(script);
} else {
eval(code);
// 可以换成 jQuery.extend
function mixin(a, b) {
if (a && b) {
for (var k in b) {
if (b.hasOwnProperty(k)) {
a[k] = b[k];
}
}
};
}
return a;
}
var ajax = function(url, cb, data) {
var xhr = new (window.XMLHttpRequest || ActiveXObject)('Microsoft.XMLHTTP');
var Util = {
loadJs: loadJs,
loadCss: loadCss,
appendStyle: appendStyle,
globalEval: globalEval,
ajax: ajax,
mixin: mixin
};
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
cb(this.responseText);
}
// expose it.
root.BigPipeUtil = Util;
})(this);
(function (root) {
// Event
var Util = root.BigPipeUtil,
slice = [].slice,
protos;
protos = {
on: function (name, callback) {
var me = this,
set, handler;
set = this._events || (this._events = []);
set.push({
e: name,
cb: callback,
id: set.length,
ctx: this
});
return this;
},
once: function (name, callback) {
var me = this,
once;
once = function () {
me.off(name, once);
return callback.apply(me, arguments);
};
xhr.open(data?'POST':'GET', url + '&t=' + ~~(Math.random() * 1e6), true);
if (data) {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
once._cb = callback;
return me.on(name, once);
},
off: function (name, cb) {
var events = this._events;
if (!name && !cb) {
this._events = [];
return this;
}
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.send(data);
};
var mixin = function(a, b) {
if (a && b) {
for (var k in b) {
if (b.hasOwnProperty(k)) {
a[k] = b[k];
}
}
each(findHandlers(events, name, cb), function (item) {
delete events[item.id];
});
return this;
},
trigger: function (type) {
var args, events, allEvents;
if (!this._events || !type) {
return this;
}
return a;
};
return {
loadCss: loadCss,
loadJs: loadJs,
appendStyle: appendStyle,
globalEval: globalEval,
ajax: ajax,
mixin: mixin
};
})();
args = slice.call(arguments, 1);
events = findHandlers(this._events, type);
return triggerHanders(events, args);
}
};
// 根据条件过滤出事件handlers.
function findHandlers(arr, name, callback) {
var ret = [];
var BigPipe = function() {
each(arr, function (handler) {
if (handler &&
(!name || handler.e === name) &&
(!callback || handler.cb === callback || handler.cb._cb === callback)) {
ret.push(handler);
}
});
return ret;
}
function each(arr, iterator) {
for (var i = 0, len = arr.length, item; i < len; i++) {
item = arr[i];
iterator.call(item, item, i);
}
}
function triggerHanders(events, args) {
var i = -1,
len = events.length,
handler;
while (++i < len) {
handler = events[i];
if (handler.cb.apply(handler.ctx, args) === false) {
break;
}
}
}
root.BigPipeEvent = Util.mixin({
mixto: function (obj) {
return Util.mixin(obj, protos);
}
}, protos);
})(this);
(function (root) {
var Util = root.BigPipeUtil;
var Event = root.BigPipeEvent;
var BigPipe = function () {
// The order of render pagelet.

@@ -146,3 +309,3 @@ // - load css

var loadCss = function() {
var loadCss = function () {
// load css

@@ -152,17 +315,18 @@ if (data.css && data.css.length) {

for (var i = 0, len = remaining; i < len; i++) {
Util.loadCss(data.css[i], function() {
Util.loadCss(data.css[i], BigPipe.ignoreDuplicate, function () {
--remaining || insertDom();
});
}
} else {
}
else {
insertDom();
}
}
};
var insertDom = function() {
var i, len, dom, node, text, scriptText;
var insertDom = function () {
var i, len, dom, node, text, scriptText, temp;
// insert style code
if(data.styles && data.styles.length) {
for(i = 0, len = data.styles.length; i < len; i++) {
if (data.styles && data.styles.length) {
for (i = 0, len = data.styles.length; i < len; i++) {
Util.appendStyle(data.styles[i]);

@@ -173,21 +337,32 @@ }

dom = data.container && typeof data.container === 'string' ?
document.getElementById(data.container) :
(data.container || document.getElementById(data.id));
document.getElementById(data.container) :
(data.container || document.getElementById(data.id));
dom.innerHTML = data.html;
if (data.extend) {
temp = document.createElement('div');
temp.innerHTML = data.html;
while (temp.firstChild) {
dom.appendChild(temp.firstChild);
}
}
else {
dom.innerHTML = data.html;
}
setTimeout(function () {
onDomInserted(data);
}, 0);
};
onDomInserted();
}
var loadJs = function() {
var loadJs = function (callback) {
var len = data.js && data.js.length;
var remaining = len, i;
var remaining = len,
i;
// exec data.scripts
var next = function() {
var next = function () {
var i, len;
// eval scripts.
if(data.scripts && data.scripts.length) {
for(i = 0, len = data.scripts.length; i < len; i++) {
if (data.scripts && data.scripts.length) {
for (i = 0, len = data.scripts.length; i < len; i++) {
Util.globalEval(data.scripts[i]);

@@ -197,3 +372,3 @@ }

data.done && data.done(data.id);
callback && callback(data);
};

@@ -208,7 +383,7 @@

for (i = 0; i < len; i++) {
Util.loadJs(data.js[i], next && function() {
Util.loadJs(data.js[i], BigPipe.ignoreDuplicate, next && function () {
--remaining || next();
});
}
}
};

@@ -221,6 +396,9 @@ return {

var d = document,
config = {},
count = 0,
pagelets = []; /* registered pagelets */
var count = 0,
pagelets = [],
/* registered pagelets */
currentPagelet = null,
currReqID = null,
cache = {},
globalBigPipeLoadIndex = 0;

@@ -233,15 +411,24 @@ return {

// - after async load quickling pagelet.
onPageletArrive: function(obj) {
config[obj.id] && (obj = Util.mixin(obj, config[obj.id]));
onPageletArrive: function (obj) {
currReqID = obj.reqID;
// console.log('arrive', obj.id);
this.trigger('pageletarrive', obj);
var pagelet = PageLet(obj, function() {
var pagelet = PageLet(obj, function () {
// console.log('dom ready', obj.id);
var item;
count--;
// enforce js executed after dom inserted.
if (!--count) {
if (count === 0) {
while ((item = pagelets.shift())) {
item.loadJs();
BigPipe.trigger('pageletinsert', pagelet, item.pageletData);
// console.log('pagelet exec js', item.pageletData.id);
item.loadJs(function () {
// console.log('pagelet exec done', item.pageletData.id);
BigPipe.trigger('pageletdone', pagelet, item.pageletData);
});
}
}
});
pagelet.pageletData = obj;
pagelets.push(pagelet);

@@ -276,7 +463,10 @@ count++;

// specified document node.
// - cb done callback.
load: function(pagelets) {
// - extend
load: function (pagelets) {
var args = [];
var currentPageUrl = location.href;
var obj, i, id, cb, remaining, search, url, param;
var containers = {};
var pageletRequestID = globalBigPipeLoadIndex++;
var obj, i, id, cb, remaining = 0,
search, url, param, container;

@@ -293,8 +483,9 @@ // convert arguments.

pagelets: pagelets
}
} else {
};
}
else {
obj = typeof pagelets === 'string' ? {
pagelets: pagelets
}: pagelets;
pagelets = obj.pagelets;
} : pagelets;
pagelets = obj.pagelet || obj.pagelets;
typeof pagelets === 'string' &&

@@ -304,32 +495,66 @@ (pagelets = pagelets.split(/\s*,\s*/));

remaining = pagelets.length;
cb = obj.cb && function(pageletId) {
delete config[pageletId];
--remaining || obj.cb();
};
for(i = remaining - 1; i >= 0; i--) {
for (i = pagelets.length - 1; i >= 0; i--) {
id = pagelets[i];
args.push('pagelets[]=' + id);
config[id] = {
container: obj.container && obj.container[id] ||
obj.container,
done: cb
container = obj.container && obj.container[id] || obj.container;
containers[id] = container;
}
args.push('reqID=' + pageletRequestID);
function onPageArrive(data) {
// !data.reqID 用于兼容老版本未返回reqID的情况
if (data.reqID === undefined || data.reqID === pageletRequestID) {
var id = data.id;
// console.log('req', data.reqID, 'pagelet', data.id, 'arrive');
remaining++;
containers[id] && (data.container = containers[id]);
data.extend = obj.extend;
}
}
param = obj.param ? '&' + obj.param : '';
search = location.search;
search = search ? (search + '&') : '?';
url = search + args.join('&') + param;
BigPipe.on('pageletarrive', onPageArrive);
obj.search && args.push(obj.search);
if (obj.url) {
url = obj.url + (obj.url.indexOf('?') === -1 ? '?' : '&') + args.join('&');
}
else {
url = (location.search ? location.search + '&' : '?') + args.join('&');
}
BigPipe.on('pageletdone', function (pagelet, res) {
// !res.reqID 用于兼容老版本未返回reqID的情况
if (res.reqID === undefined || res.reqID === pageletRequestID) {
remaining--;
// console.log('req', res.reqID, 'pagelet', res.id, 'done');
if (remaining === 0) {
// console.log('req', res.reqID, 'done');
BigPipe.off('pageletdone', arguments.callee);
BigPipe.off('pageletarrive', onPageArrive);
obj.cb && obj.cb();
}
}
});
Util.ajax(url, function(res) {
// console.log('req', pageletRequestID, url, 'start');
// if the page url has been moved.
if(currentPageUrl !== location.href) {
return;
}
Util.globalEval(res);
});
if (cache[obj.cacheID]) {
var requestCache = cache[obj.cacheID];
// 同步requestID
pageletRequestID = requestCache.reqID;
Util.globalEval(requestCache.content);
}
else {
Util.ajax(url, function (res) {
// if the page url has been moved.
if (currentPageUrl !== location.href) {
return;
}
Util.globalEval(res);
if (obj.cacheID) {
cache[obj.cacheID] = {
content: res,
reqID: currReqID
};
}
});
}
}

@@ -339,3 +564,5 @@ };

Event.mixto(BigPipe);
BigPipe.ignoreDuplicate = true;
window.BigPipe = BigPipe;
})();
})(this);
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc