UNPKG

@adpt/core

Version:
115 lines 4.73 kB
"use strict"; /* * Copyright 2018-2019 Unbounded Systems, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const dom_parser_1 = require("@adpt/dom-parser"); const utils_1 = require("@adpt/utils"); const ld = tslib_1.__importStar(require("lodash")); const util = tslib_1.__importStar(require("util")); const error_1 = require("../error"); const handle_1 = require("../handle"); const jsx_1 = require("../jsx"); const reanimate_1 = require("./reanimate"); async function reanimateDom(xmlString, deployID, deployOpID) { const domNodesRoot = await dom_parser_1.domFromString(xmlString); if (domNodesRoot === null) return null; const handleReg = { handles: [], nodes: new Map(), }; const dom = await reanimateNode(domNodesRoot, [], handleReg, deployID, deployOpID); resolveHandles(handleReg); return dom; } exports.reanimateDom = reanimateDom; function updateLifecycle(domNode, elem, deployID, deployOpID) { if (!domNode.lifecycleInfo) return; if (!jsx_1.isElementImpl(elem)) throw new error_1.InternalError("Element is not ElementImpl"); const info = domNode.lifecycleInfo; if (elem.props.key !== ld.last(info.stateNamespace)) { throw new Error(`Invalid DOM XML. Element key does not match stateNamespace: ${util.inspect(domNode)}`); } elem.mount(domNode.lifecycleInfo.stateNamespace.slice(0, -1), domNode.lifecycleInfo.path, domNode.lifecycleInfo.keyPath, deployID, deployOpID); elem.reanimated = true; } async function makeHandle(val, handleReg) { const ctor = await reanimate_1.reanimateUrn(val.urn); const handle = new ctor(val); if (handle_1.isHandleInternal(handle) && handle.unresolvedTarget !== null) { handleReg.handles.push(handle); } return handle; } //val must be a pod, prototpyes are not preserved async function convertHandles(val, handleReg) { if (!(utils_1.isObject(val) || ld.isArray(val))) return val; if (utils_1.isObject(val) && handle_1.isHandleObj(val)) return makeHandle(val, handleReg); if (ld.isArray(val)) { const retP = val.map(async (v) => convertHandles(v, handleReg)); const ret = Promise.all(retP); return ret; } if (utils_1.isObject(val)) { const ret = {}; for (const key of Object.keys(val)) { ret[key] = await convertHandles(val[key], handleReg); } return ret; } throw new error_1.InternalError(`should be unreachable: ${util.inspect(val)}`); } async function reanimateNode(domNode, parentPath, handleReg, deployID, deployOpID) { const nodeKey = domNode.props.key; if (typeof nodeKey !== "string") throw new Error(`Invalid DOM XML. Element with no key: ${util.inspect(domNode)}`); const keyPath = parentPath.concat([nodeKey]); const component = await reanimate_1.reanimateUrn(domNode.uri); const pChildren = jsx_1.childrenToArray(domNode.props.children).map(async (c) => { if (!dom_parser_1.isDOMNode(c)) return convertHandles(c, handleReg); return reanimateNode(c, keyPath, handleReg, deployID, deployOpID); }); const children = await Promise.all(pChildren); // Reanimate any DOMObjects const props = {}; for (const k of Object.keys(domNode.props)) { if (k === "children") continue; props[k] = await convertHandles(domNode.props[k], handleReg); } const node = jsx_1.createElement(component, props, ...children); updateLifecycle(domNode, node, deployID, deployOpID); handleReg.nodes.set(JSON.stringify(keyPath), node); return node; } function resolveHandles(handleReg) { for (const hand of handleReg.handles) { const target = hand.unresolvedTarget; if (target == null) throw new error_1.InternalError(`target is null`); const node = handleReg.nodes.get(JSON.stringify(target)); if (node == null) throw new Error(`DOM reanimation error: cannot find DOM node path '${target}'`); hand.associate(node); } } //# sourceMappingURL=reanimate_dom.js.map