UNPKG

@ray-core/runtime

Version:

Ray 是一个全新的基于 React 的小程序开发框架

251 lines (250 loc) 11.1 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { RuntimeOptions } from '@ray-core/framework-shared'; import merge from 'lodash-es/merge'; import get from 'lodash-es/get'; import cloneDeep from 'lodash-es/cloneDeep'; import VNode from './VNode'; import nativeEffector from './nativeEffect'; import { unstable_batchedUpdates } from './index'; import { SLOT_PLACEHOLDER } from './constants'; import { gStore } from './gStore'; import { createCallbackProxy } from './SyntheticEvent/createCallbackProxy'; var Container = /** @class */ (function () { function Container(context, rootKey) { if (rootKey === void 0) { rootKey = 'root'; } this.updateQueue = []; this._slot = { idsCache: [], node: undefined }; this.pageInitialized = false; this.context = context; this.root = new VNode({ type: 'root', container: this, }); this.root.mounted = true; this.rootKey = rootKey; } Container.prototype.requestUpdate = function (update) { this.updateQueue.push(update); }; Container.prototype.normalizeUpdatePath = function (paths) { return __spreadArray([this.rootKey], __read(paths), false).join('.'); }; Container.prototype.handlePayload = function (pathPrefix) { var _this = this; return this.updateQueue.reduce(function (acc, update) { if (update.node.isDeleted()) { return acc; } var _path = update.path; if (update.type === 'splice') { acc[_this.normalizeUpdatePath(__spreadArray(__spreadArray(__spreadArray([], __read(pathPrefix), false), __read(_path), false), ['nodes', update.id.toString()], false))] = update.raw || null; if (update.children) { var path = __spreadArray(__spreadArray(__spreadArray([], __read(pathPrefix), false), __read(_path), false), ['children'], false); acc[_this.normalizeUpdatePath(path)] = (update.children || []).map(function (c) { return c.id; }); } } else { acc[_this.normalizeUpdatePath(__spreadArray(__spreadArray(__spreadArray([], __read(pathPrefix), false), __read(_path), false), [update.name], false))] = update.value; } return acc; }, {}); }; Container.prototype.applyUpdate = function (appContainer) { if (this.stopUpdate) { return; } if (!appContainer) { if (this.updateQueue.length === 0) { return; } } if (appContainer && appContainer.updateQueue.length === 0 && this.updateQueue.length === 0) { return; } var startTime = new Date().getTime(); var realParentPath = []; var appPayload; var pagePayload; // 从 app.js 中获取 ui 数据 // ray 构建的组件 不需要从 app.js 获取 ui 数据 // modal UI 仍然由各个页面控制 if (appContainer) { appPayload = appContainer.handlePayload(); var slotInfo = appContainer.getPageSlotParentInfo(); // 当app.js 中 未渲染页面时 slot 不存在 if (slotInfo) { var slotIndexAtParentChildren = slotInfo.slotIndexAtParentChildren; realParentPath = slotInfo.parentPath; pagePayload = this.handlePayload(realParentPath); var realParentChildrenPathStr = __spreadArray(__spreadArray([this.rootKey], __read(realParentPath), false), ['children'], false).join('.'); var childrenOfPage = this.root.children.map(function (c) { return c.id; }); if (!this.pageInitialized) { this.pageInitialized = true; // 页面初始化的时候,从app.js中获取全量的 ui 数据 appPayload = cloneDeep(appContainer.context.getData()); } var parentChildrenOfApp = get(appPayload, realParentChildrenPathStr); if (parentChildrenOfApp) { if (this.root.children.length) { parentChildrenOfApp.splice.apply(parentChildrenOfApp, __spreadArray([slotIndexAtParentChildren, 1], __read(childrenOfPage), false)); } else { parentChildrenOfApp.splice(slotIndexAtParentChildren, 1); } delete pagePayload[realParentChildrenPathStr]; appPayload[realParentChildrenPathStr] = parentChildrenOfApp; } } } else { pagePayload = this.handlePayload(realParentPath); } // fullPayload = appPayload + pagePayload if (RuntimeOptions.get('debug')) { console.log('>>>>>>>> applyUpdate appPayload', appPayload); console.log('>>>>>>>> applyUpdate pagePayload', pagePayload); } var fullPayload = merge({}, appPayload, pagePayload); if (RuntimeOptions.get('debug')) { console.log('>>>>>>>> applyUpdate fullPayload ', this.context.route, fullPayload); } this.context.setData(fullPayload, function () { nativeEffector.run(); /* istanbul ignore next */ if (RuntimeOptions.get('debug')) { console.log("setData => \u56DE\u8C03\u65F6\u95F4\uFF1A".concat(new Date().getTime() - startTime, "ms"), fullPayload); } }); this.updateQueue = []; }; Container.prototype.clearUpdate = function () { this.stopUpdate = true; }; Container.prototype.createCallback = function (id, propKey, node, fn) { var proxyHandle = createCallbackProxy(propKey, node, fn); function cbOrEventHandler() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return unstable_batchedUpdates(function (args) { return proxyHandle.apply(void 0, __spreadArray([], __read(args), false)); }, args); } cbOrEventHandler.__original = fn; // 微信端:除input事件需要挂在实例上外,其他事件都可以挂在原型上 if (/^(onInput|bindinput)$/.test(propKey)) { this.context[id] = cbOrEventHandler; } gStore.setCallback(id, cbOrEventHandler); }; Container.prototype.removeCallback = function (name) { gStore.unsetCallback(name); delete this.context[name]; }; Container.prototype.appendChild = function (child) { this.root.appendChild(child); }; Container.prototype.removeChild = function (child) { this.root.removeChild(child); }; Container.prototype.insertBefore = function (child, beforeChild) { this.root.insertBefore(child, beforeChild); }; Container.prototype.replaceSlot = function (parent, child, index) { var _a, _b; if ((_a = child.text) === null || _a === void 0 ? void 0 : _a.startsWith(SLOT_PLACEHOLDER)) { var slotChildren = ((_b = this._slot.node) === null || _b === void 0 ? void 0 : _b.children) || []; // 页面中Ray构建的原生自定义组件根节点 // 子节点 slotChildren = slotChildren.map(function (item) { return ((item.parent = parent), item); }); var curChildren = parent.children; if (typeof index === 'number') { // 首次插入中间位置 curChildren.splice.apply(curChildren, __spreadArray([index, 0], __read(slotChildren), false)); } else { var idsCache = this._slot.idsCache; if (idsCache.length === 0) { curChildren.push.apply(curChildren, __spreadArray([], __read(slotChildren), false)); // 首次追加到尾部 } else { // 更新 var start = -1; for (var i = 0; i < curChildren.length; i++) { var item = curChildren[i]; if (~idsCache.indexOf(item.id)) { curChildren.splice(i, 1); if (start < 0) start = i; i--; } } curChildren.splice.apply(curChildren, __spreadArray([start, 0], __read(slotChildren), false)); } } this._slot.idsCache = slotChildren.map(function (item) { return item.id; }); parent.children = curChildren; return slotChildren; } }; Container.prototype.removeSlot = function (parent, child) { var _a; if (!((_a = child.text) === null || _a === void 0 ? void 0 : _a.startsWith(SLOT_PLACEHOLDER))) { return; } if (this._slot.node) { this._slot.node.children.forEach(function (slot) { parent.children = parent.children.filter(function (child) { return child.id !== slot.id; }); }); this._slot.idsCache = []; this._slot.node = undefined; } }; Container.prototype.copyVNode = function (node, option) { var _this = this; var fn = function (node, opts) { var o = Object.create(Object.getPrototypeOf(node), Object.getOwnPropertyDescriptors(node)); o.children = o.children.map(function (c) { return fn(c, { parent: o, container: _this }); }); return Object.assign(o, opts); }; return fn(node, __assign(__assign({}, option), { container: this })); }; return Container; }()); export default Container;