UNPKG

zp-bee

Version:

zp-bee,是一款基于 Dumi,由 React + TypeScript 开发的组件库 🎉。

260 lines (198 loc) 7.85 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.atom = atom; exports.selector = selector; exports.useCoiledValue = useCoiledValue; exports.useCoiledState = useCoiledState; exports.setCoiledState = setCoiledState; exports.Selector = exports.Atom = exports.Stateful = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _react = require("react"); // 判断是否为对象 function isObject(value) { return Object.prototype.toString.call(value) === "[object Object]"; } // 浅比较 function shadowEqual(objA, objB) { if (!isObject(objA)) return objA === objB; var keysA = Object.keys(objA); var keysB = Object.keys(objB); if (keysA.length !== keysB.length) return false; for (var i = 0, len = keysA.length; i < len; i++) { if (objB[keysA[i]] !== objA[keysA[i]]) return false; } return true; } // `Stateful`是管理状态和订阅的基类。 // 原子和选择器都是从它派生出来的。 var Stateful = /*#__PURE__*/function () { // 值属性受保护,因为需要手动 // 在构造函数中赋值(因为继承的特殊性) function Stateful(value) { (0, _classCallCheck2.default)(this, Stateful); this.value = value; // 这是一组独特的回调 this.listeners = new Set(); this.queue = 0; } // 返回状态的简单方法。这可能会导致严重后果 // 如果你想格外小心的话,就抄吧。 (0, _createClass2.default)(Stateful, [{ key: "snapshot", value: function snapshot() { return this.value; } // emit方法是用新状态更新所有侦听器的方法 // 更新值后,让所有侦听器都知道新值 }, { key: "emit", value: function emit() { for (var _i = 0, _Array$from = Array.from(this.listeners); _i < _Array$from.length; _i++) { var listener = _Array$from[_i]; listener(this.snapshot()); } } }, { key: "flush", value: function flush() { var _this = this; var cb = function cb() { _this.queue = 0; _this.emit(); }; if ((typeof MessageChannel === "undefined" ? "undefined" : (0, _typeof2.default)(MessageChannel)) !== undefined) { var _MessageChannel = new MessageChannel(), port1 = _MessageChannel.port1, port2 = _MessageChannel.port2; port1.onmessage = cb; port2.postMessage(null); } else { setTimeout(cb); } } // update方法是设置state的规范方法。它使用对象 // 平等,以防止不必要的渲染。一个深刻的比较可能是 // 为经常重新创建但相同的复杂对象执行 }, { key: "update", value: function update(value) { if (!shadowEqual(this.value, value)) { this.value = value; this.queue += 1; // 批量更新值,防止同时进行多个更新 this.queue === 1 && this.flush(); } } // subscribe方法允许使用者监听状态更新。调用“disconnect”方法将阻止将来调用回调 }, { key: "subscribe", value: function subscribe(callback) { var _this2 = this; this.listeners.add(callback); return { disconnect: function disconnect() { _this2.listeners.delete(callback); } }; } }]); return Stateful; }(); // atom是围绕“Stateful”基类的薄包装。它有一个更新状态的单一方法。 exports.Stateful = Stateful; var Atom = /*#__PURE__*/function (_Stateful) { (0, _inherits2.default)(Atom, _Stateful); var _super = (0, _createSuper2.default)(Atom); function Atom() { (0, _classCallCheck2.default)(this, Atom); return _super.apply(this, arguments); } (0, _createClass2.default)(Atom, [{ key: "setState", value: function setState(value) { (0, _get2.default)((0, _getPrototypeOf2.default)(Atom.prototype), "update", this).call(this, value); } }]); return Atom; }(Stateful); // 它扩展了“Stateful”,以便可以像atoms一样用作值 exports.Atom = Atom; var Selector = /*#__PURE__*/function (_Stateful2) { (0, _inherits2.default)(Selector, _Stateful2); var _super2 = (0, _createSuper2.default)(Selector); function Selector(generate) { var _this3; (0, _classCallCheck2.default)(this, Selector); // 由于Typescript的继承规则,最初需要对其进行未定义 // 它实际上是“初始化记忆” _this3 = _super2.call(this, undefined); _this3.generate = generate; // 跟踪所有已注册的依赖项。我们要确保在它们更改时只重新渲染一次。 _this3.registeredDeps = new Set(); _this3.value = generate({ get: function get(dep) { return _this3.addDep(dep); } }); return _this3; } // 当调用get函数时,它允许使用者订阅状态更改。此方法订阅依赖项(如果尚未订阅) (0, _createClass2.default)(Selector, [{ key: "addDep", value: function addDep(dep) { var _this4 = this; if (!this.registeredDeps.has(dep)) { dep.subscribe(function () { return _this4.updateSelector(); }); this.registeredDeps.add(dep); } return dep.snapshot(); } // 一个助手方法,用于运行内部生成器方法、更新依赖项、返回计算状态和更新所有侦听器。 }, { key: "updateSelector", value: function updateSelector() { var _this5 = this; this.update(this.generate({ get: function get(dep) { return _this5.addDep(dep); } })); } }]); return Selector; }(Stateful); // 用于创建新原子的辅助函数 // "key"成员当前未使用。我只是把它放在身边,以保持一个类似的API来Recoil。 exports.Selector = Selector; function atom(value) { return new Atom(value.default); } // 用于创建新选择器的助手方法 // 同样,“key”方法只是为了看起来像Recoil function selector(value) { return new Selector(value.get); } // 每当提供的“Stateful”值更改时,此钩子将重新呈现 // 它可以与“Selector”或“Atom”一起使用。 function useCoiledValue(value) { var _useState = (0, _react.useState)({}), _useState2 = (0, _slicedToArray2.default)(_useState, 2), updateState = _useState2[1]; (0, _react.useEffect)(function () { var _value$subscribe = value.subscribe(function () { return updateState({}); }), disconnect = _value$subscribe.disconnect; return function () { return disconnect(); }; }, [value]); return value.snapshot(); } // 与"useCoiledValue"类似,但它也允许您在hooks中设置状态。 function useCoiledState(atom) { var value = useCoiledValue(atom); return [value, (0, _react.useCallback)(function (value) { return atom.setState(value); }, [atom])]; } // 与"useCoiledState"类似,但它也允许您在全局设置状态。 function setCoiledState(atom) { return function (value) { return atom.setState(Object.assign(Object.assign({}, atom.snapshot()), value)); }; }