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

@cicada/render

Package Overview
Dependencies
Maintainers
7
Versions
107
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cicada/render - npm Package Compare versions

Comparing version 1.1.22-alpha1 to 1.1.22-alpha10

5

lib/common.js

@@ -45,2 +45,3 @@ 'use strict';

exports.checkPlainValue = checkPlainValue;
exports.isDebug = isDebug;

@@ -336,2 +337,6 @@ var _isPlainObject = require('lodash/isPlainObject');

return true;
}
function isDebug() {
return typeof window !== 'undefined' && window.cicadaEnv === 'DEBUG';
}

@@ -283,2 +283,7 @@ 'use strict';

}
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('DidMount: ' + displayName + '(' + this.getResolvedRootPath() + ')');
/* eslint-enable no-console */
}
}

@@ -311,4 +316,30 @@ }, {

}
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('UnMount: ' + displayName + '(' + this.getResolvedRootPath() + ')');
/* eslint-enable no-console */
}
}
// for debug
}, {
key: 'componentWillUpdate',
value: function componentWillUpdate() {
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('Will Update: ' + displayName + '(' + this.getResolvedRootPath() + ')');
/* eslint-enable no-console */
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('Update: ' + displayName + '(' + this.getResolvedRootPath() + ')');
/* eslint-enable no-console */
}
}
}, {
key: 'convertToControlledListener',

@@ -315,0 +346,0 @@ value: function convertToControlledListener(injectedComponentArg) {

47

lib/convertFragment.js

@@ -45,24 +45,26 @@ 'use strict';

var _common = require('./common');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function noop() {} /**
* convertFragment 负责将 config 片段转换为金蝉组件。
* 这里的重点问题有两个:
*
* 1. 由于金蝉组件都是受控,所以我们转换出的组件也必须是受控的。由于之前
* Render 的设计已经考虑了受控形式,所以这里只要遵照 Render 的规则给其传入
* onChange 函数即可变为受控。
*
* 2. 转换为受控形式之后, 组件的渲染都是由外部传入新数据来控制的。如果包装后
* 的组件也采取这种获取新值后重新渲染的方式,那么在内部结构变大后,可能会产
* 生性能问题。例如组件中的某一个 input 一直输入,每次都要从外部全部刷新,会
* 感觉卡顿。为了解决这个问题,首先,转换后的组件声明了 shouldComponentUpdate
* 为 false,永远不重新渲染。然后,我们让内部 Render 在发生变化先用 stateTree 的
* cache 缓存住变化,不通知组件更新,仍然往外跑一遍流程,然后在外部通知要重渲染时
* flush 内部的 stateTree,继续使用 Render 内部的精确更新。
*/
/**
* convertFragment 负责将 config 片段转换为金蝉组件。
* 这里的重点问题有两个:
*
* 1. 由于金蝉组件都是受控,所以我们转换出的组件也必须是受控的。由于之前
* Render 的设计已经考虑了受控形式,所以这里只要遵照 Render 的规则给其传入
* onChange 函数即可变为受控。
*
* 2. 转换为受控形式之后, 组件的渲染都是由外部传入新数据来控制的。如果包装后
* 的组件也采取这种获取新值后重新渲染的方式,那么在内部结构变大后,可能会产
* 生性能问题。例如组件中的某一个 input 一直输入,每次都要从外部全部刷新,会
* 感觉卡顿。为了解决这个问题,首先,转换后的组件声明了 shouldComponentUpdate
* 为 false,永远不重新渲染。然后,我们让内部 Render 在发生变化先用 stateTree 的
* cache 缓存住变化,不通知组件更新,仍然往外跑一遍流程,然后在外部通知要重渲染时
* flush 内部的 stateTree,继续使用 Render 内部的精确更新。
*/
/* eslint-disable no-nested-ternary */
function noop() {}
function computeFrom(linkState, utilInstances, _ref) {

@@ -260,2 +262,7 @@ var state = _ref.state;

instance.stateTree.flush();
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('Fragment stateTree flush');
/* eslint-enable no-console */
}
}

@@ -346,2 +353,8 @@

if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('Fragment render');
/* eslint-enable no-console */
}
return _react2.default.createElement(_Render2.default, {

@@ -348,0 +361,0 @@ stateTree: instance.stateTree,

@@ -82,3 +82,3 @@ 'use strict';

// 避免state数据传入到react开发版props属性被设置为frozen导致无法set
function simpleCloneWithoutfrozen(state) {
function simpleCloneWithoutFrozen(state) {
if (!isObject(state)) return state;

@@ -164,4 +164,6 @@ return (0, _util.mapValues)(state, function (v) {

if (!visible) {
if (!lastStyleList.includes(DISPLAY_NONE)) {
ref.setAttribute('data-cicada-' + DISPLAY_NONE, '');
var displayNoneAttr = 'data-cicada-' + DISPLAY_NONE;
// CAUTION 这里要拿实际的 ref 去检验,因为有可能真实的 ref 被外部更改了。
if (ref.attributes[displayNoneAttr] === undefined) {
ref.setAttribute(displayNoneAttr, '');
}

@@ -171,4 +173,5 @@ addedStyleList.push(DISPLAY_NONE);

styleList.forEach(function (cls) {
if (!lastStyleList.includes(cls)) {
ref.setAttribute('data-cicada-' + cls, '');
var clsAttr = 'data-cicada-' + cls;
if (ref.attributes[clsAttr] === undefined) {
ref.setAttribute(clsAttr, '');
}

@@ -234,3 +237,3 @@ addedStyleList.push(cls);

componentArg.props = (0, _extends3.default)({}, componentArg.props, injectedExternalProps);
componentArg.state = _constant.isDebug ? simpleCloneWithoutfrozen(componentArg.state) : componentArg.state;
componentArg.state = _constant.isDebug ? simpleCloneWithoutFrozen(componentArg.state) : componentArg.state;
var styleList = appearance[id].styleList;

@@ -237,0 +240,0 @@

@@ -11,2 +11,14 @@ 'use strict';

var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
var _toArray2 = require('babel-runtime/helpers/toArray');
var _toArray3 = _interopRequireDefault(_toArray2);
exports.default = createDynamicRender;

@@ -22,6 +34,2 @@

var _cloneDeep = require('lodash/cloneDeep');
var _cloneDeep2 = _interopRequireDefault(_cloneDeep);
var _Render = require('./Render');

@@ -37,2 +45,4 @@

var _common = require('./common');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

@@ -45,2 +55,26 @@

function consumeStateTreeBuffer(stateTree, buffer) {
buffer.forEach(function (_ref) {
var _ref2 = (0, _toArray3.default)(_ref),
path = _ref2[0],
value = _ref2[1],
arg = _ref2.slice(2);
return stateTree.set.apply(stateTree, [path, value].concat((0, _toConsumableArray3.default)(arg)));
});
}
function constructInitialStateTree(buffer) {
var output = {};
// CAUTION 当重新创建时,没有 merge,要求用户提供完整的数据
buffer.forEach(function (_ref3) {
var _ref4 = (0, _slicedToArray3.default)(_ref3, 2),
path = _ref4[0],
value = _ref4[1];
return _exist2.default.set(output, path, value, true);
});
return output;
}
function createDynamicRender(createStateTree, createAppearance, createBackground, backgroundDef) {

@@ -60,6 +94,6 @@ var getDefaultState = function getDefaultState() {

var defaultListeners = {
onChange: function onChange(_ref, changeFn, name, path) {
var instance = _ref.instance,
state = _ref.state,
statePath = _ref.statePath;
onChange: function onChange(_ref5, changeFn, name, path) {
var instance = _ref5.instance,
state = _ref5.state,
statePath = _ref5.statePath;

@@ -90,4 +124,4 @@ if (changeFn === undefined) return;

// state 的 proxy 模式,可以接管 stateTree 的变化
var getStateProxy = function getStateProxy(_ref2) {
var instance = _ref2.instance;
var getStateProxy = function getStateProxy(_ref6) {
var instance = _ref6.instance;
var initialValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

@@ -97,49 +131,80 @@

instance.config = initialValue.config ? (0, _extends3.default)({}, initialValue.config) : {};
return {
get: function get(statePath) {
var _instance$stateTree;
// 所有的对 stateTree 的改动都先存到这里,只有真正受到通知的时候才真正的 flush
// 这样设计的原因是,有可能改动了 config,有可能没改。
// 1 在改动了 config 的时候,这些 value 是当做初始 value。
// 2 如果没改动,那么这些 value 直接 flush 到 stateTree 中。
instance.stateTreeBuffer = [];
instance.stateProxy = {};
for (var _len2 = arguments.length, arg = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
arg[_key2 - 1] = arguments[_key2];
}
function setStateValue(statePath, value) {
for (var _len2 = arguments.length, arg = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
arg[_key2 - 2] = arguments[_key2];
}
if (/^value/.test(statePath)) return (_instance$stateTree = instance.stateTree).get.apply(_instance$stateTree, [removePathHeader(statePath, 'value')].concat(arg));
if (/^config/.test(statePath)) return _exist2.default.get.apply(_exist2.default, [instance.config, removePathHeader(statePath, 'config')].concat(arg));
throw new Error('get unknown state name: ' + statePath);
},
set: function set(statePath, value) {
for (var _len3 = arguments.length, arg = Array(_len3 > 2 ? _len3 - 2 : 0), _key3 = 2; _key3 < _len3; _key3++) {
arg[_key3 - 2] = arguments[_key3];
if (/^value/.test(statePath)) {
var path = removePathHeader(statePath, 'value');
if (path) {
instance.stateTreeBuffer.push([path, value].concat(arg));
} else {
(0, _util.each)(value, function (v, k) {
instance.stateTreeBuffer.push([k, v].concat(arg));
});
}
return;
}
// 注意,config 没有 merge,只是创建不存在的路径
if (/^config/.test(statePath)) {
// 对于外界的 set,记录一下,之后要用。
instance.isConfigChanged = true;
var _path = removePathHeader(statePath, 'config');
if (!_path) {
instance.config = value;
} else {
_exist2.default.set(instance.config, removePathHeader(statePath, 'config'), value, true);
}
return;
}
throw new Error('set unknown state name: ' + statePath);
}
if (/^value/.test(statePath)) {
var path = removePathHeader(statePath, 'value');
if (path) {
var _instance$stateTree2;
function getStateValue(statePath) {
var _instance$stateTree;
(_instance$stateTree2 = instance.stateTree).set.apply(_instance$stateTree2, [removePathHeader(statePath, 'value'), value].concat(arg));
} else {
(0, _util.each)(value, function (v, k) {
var _instance$stateTree3;
for (var _len3 = arguments.length, arg = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
arg[_key3 - 1] = arguments[_key3];
}
(_instance$stateTree3 = instance.stateTree).set.apply(_instance$stateTree3, [k, v].concat(arg));
});
}
return;
if (/^value/.test(statePath)) return (_instance$stateTree = instance.stateTree).get.apply(_instance$stateTree, [removePathHeader(statePath, 'value')].concat(arg));
if (/^config/.test(statePath)) return _exist2.default.get.apply(_exist2.default, [instance.config, removePathHeader(statePath, 'config')].concat(arg));
if (statePath === '') {
return {
config: instance.config,
value: instance.stateTree.get('')
};
}
throw new Error('get unknown state name: ' + statePath);
}
Object.defineProperty(instance.stateProxy, 'get', {
value: getStateValue
});
Object.defineProperty(instance.stateProxy, 'set', {
value: function set(statePath, value) {
for (var _len4 = arguments.length, arg = Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
arg[_key4 - 2] = arguments[_key4];
}
// 注意,config 没有 merge,只是创建不存在的路径
if (/^config/.test(statePath)) {
// 对于外界的 set,记录一下,之后要用。
instance.isConfigChanged = true;
var _path = removePathHeader(statePath, 'config');
if (!_path) {
instance.config = value;
} else {
_exist2.default.set(instance.config, removePathHeader(statePath, 'config'), value, true);
}
return;
// 这里跟真正的 stateTree 不一样,这里能接受 statePath 为 '' 的形式。
if (statePath === '') {
(0, _util.each)(value, function (stateValue, stateName) {
setStateValue.apply(undefined, [stateName, stateValue].concat(arg));
});
} else {
setStateValue.apply(undefined, [statePath, value].concat(arg));
}
throw new Error('set unknown state name: ' + statePath);
}
};
});
return instance.stateProxy;
};

@@ -149,4 +214,4 @@

// 当只有 stateTree 变化时,使用内部的机制更新。
var shouldComponentUpdate = function shouldComponentUpdate(_ref3) {
var instance = _ref3.instance;
var shouldComponentUpdate = function shouldComponentUpdate(_ref7) {
var instance = _ref7.instance;

@@ -156,4 +221,4 @@ return instance.isConfigChanged;

var componentWillReceiveState = function componentWillReceiveState(_ref4) {
var instance = _ref4.instance;
var componentWillReceiveState = function componentWillReceiveState(_ref8) {
var instance = _ref8.instance;

@@ -173,3 +238,10 @@ // 不管是外部的 set,还是内部的变化,都会走到这里来。

// 无论哪种情况,这个时候都应该准确地通知到界面更新了,因此不需要再做其他操作。
consumeStateTreeBuffer(instance.stateTree, instance.stateTreeBuffer);
instance.stateTreeBuffer = [];
instance.stateTree.flush();
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('DynamicRender stateTree flush');
/* eslint-enable no-console */
}
};

@@ -184,5 +256,5 @@

defaultListeners: defaultListeners,
render: function render(_ref5) {
var instance = _ref5.instance,
listeners = _ref5.listeners;
render: function render(_ref9) {
var instance = _ref9.instance,
listeners = _ref9.listeners;

@@ -192,9 +264,16 @@ var config = instance.config;

if (instance.isConfigChanged) {
// 如果是二次渲染,stateTree 要重做,否则的 getProxy 的时候已经创建了,不用管
instance.isConfigChanged = false;
instance.stateTree = createStateTree((0, _cloneDeep2.default)(instance.stateTree.get('')));
}
// 不管是第一次还是第二次渲染,只要动态组件重新渲染,那么就要重建 stateTree。
instance.stateTree = createStateTree(constructInitialStateTree(instance.stateTreeBuffer));
instance.stateTreeBuffer = [];
instance.appearance = createAppearance();
instance.background = createBackground(backgroundDef, instance.stateTree, instance.appearance);
if ((0, _common.isDebug)()) {
/* eslint-disable no-console */
console.info('DynamicRender render');
/* eslint-enable no-console */
}
return _react2.default.createElement(_Render2.default, {

@@ -201,0 +280,0 @@ config: config,

@@ -39,3 +39,2 @@ 'use strict';

/* eslint-disable no-use-before-define */
/**

@@ -53,2 +52,15 @@ * stateTree 是配合 Render 一起使用的数据结构,它的核心功能有两个:

*/
function complete(stateTree, statePath, inputState) {
// CAUTION,这里 exist.set 第四个参数 createMissing 非常重要
if (statePath !== '' && _exist2.default.detect(stateTree, statePath) !== true) {
return _exist2.default.set(stateTree, statePath, inputState, true);
}
if ((typeof inputState === 'undefined' ? 'undefined' : (0, _typeof3.default)(inputState)) === 'object') {
(0, _util.each)(inputState, function (inputSubState, key) {
return complete(stateTree, (0, _common.joinPath)([statePath, key]), inputSubState);
});
}
}
/* eslint-disable no-use-before-define */
function createStateTree(initialStateTree) {

@@ -70,3 +82,3 @@ var stateTree = (0, _cloneDeep2.default)(initialStateTree) || {};

if (_constant.isDebug && _exist2.default.detect(stateTree, statePath) !== true) {
if (_constant.isDebug && statePath !== '' && _exist2.default.detect(stateTree, statePath) !== true) {
var detectArr = _exist2.default.detect(stateTree, statePath);

@@ -102,14 +114,2 @@ // 只检测跳级搜索, 如搜a.b.c,但a.b不存在

function complete(statePath, inputState) {
// CAUTION,这里 exist.set 第四个参数 createMissing 非常重要
if (_exist2.default.detect(stateTree, statePath) !== true) {
return _exist2.default.set(stateTree, statePath, inputState, true);
}
if ((typeof inputState === 'undefined' ? 'undefined' : (0, _typeof3.default)(inputState)) === 'object') {
(0, _util.each)(inputState, function (inputSubState, key) {
return complete((0, _common.joinPath)([statePath, key]), inputSubState);
});
}
}
function defineState(state, id) {

@@ -139,7 +139,10 @@ var pathGetters = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

function registerToStateTree(statePath, getInitialState, pathGetters, getStateProxy) {
var initialState = getInitialState();
if (getStateProxy !== undefined) {
// 有 stateProxy 的情况下,就用这个 Proxy
_exist2.default.set(stateTree, statePath, getStateProxy(_exist2.default.get(stateTree, statePath)));
var proxyInitialState = _exist2.default.get(stateTree, statePath, {});
complete(proxyInitialState, '', initialState);
_exist2.default.set(stateTree, statePath, getStateProxy(proxyInitialState));
} else {
complete(statePath, getInitialState());
complete(stateTree, statePath, initialState);
}

@@ -146,0 +149,0 @@

{
"name": "@cicada/render",
"version": "1.1.22-alpha1",
"version": "1.1.22-alpha10",
"main": "./lib/index.js",

@@ -5,0 +5,0 @@ "scripts": {

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