subapp-web
Version:
Electrode subapp web support
270 lines (264 loc) • 7.44 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getBrowserHistory = getBrowserHistory;
exports.getSubAppComponent = getSubAppComponent;
exports.hotReloadSubApp = hotReloadSubApp;
exports.isLoaded = isLoaded;
exports.dynamicLoadSubApp = exports.lazyLoadSubApp = lazyLoadSubApp;
exports.loadSubApp = loadSubApp;
Object.defineProperty(exports, "makeSubAppSpec", {
enumerable: true,
get: function () {
return _makeSubappSpec.default;
}
});
exports.setupFramework = setupFramework;
exports.waitForSubApp = waitForSubApp;
Object.defineProperty(exports, "xarc", {
enumerable: true,
get: function () {
return _xarc.default;
}
});
var _history = require("history");
var _makeSubappSpec = _interopRequireDefault(require("./make-subapp-spec"));
var _xarc = _interopRequireDefault(require("./xarc"));
let FrameworkLib;
function setupFramework(frameworkLib) {
FrameworkLib = frameworkLib;
}
function loadSubApp(info, renderStart, options) {
setTimeout(() => _xarc.default.watchSubAppOnLoad(), 0);
info = (0, _makeSubappSpec.default)(info);
const name = info.name;
const ns = info.ns;
let subApp = _xarc.default.getSubApp(name) || {
info
};
// mark the subapp's webpack bundle as loaded
if (!_xarc.default.getBundle(name, ns)) {
_xarc.default.setBundle(name, 1, ns);
}
// subapp already loaded, do nothing and return the info
if (subApp._started) {
// console.error("SubApp", name, "already loaded");
return info;
}
subApp._started = [];
_xarc.default.setSubApp(name, subApp);
subApp._renderStart = renderStart || ((options, element) => {
const lib = new FrameworkLib({
subApp,
element,
options
});
return lib.renderStart();
});
subApp.getInstance = options => {
let element;
let id = options.id || options.elementId;
if (!id) {
id = options._genId;
} else {
element = document.getElementById(id);
}
let instance = subApp._started.find(x => x.id === id);
if (!instance) {
instance = Object.assign({}, options, {
id,
element
});
subApp._started.push(instance);
} else if (instance.element !== element) {
// document has changed
instance.element = element;
}
if (element) {
console.debug("rendering subapp", name, "into", element);
}
return instance;
};
subApp.preStart = (instance, options, info) => {
instance = instance || subApp.getInstance(options);
info = info || subApp.info;
if (!instance._prepared) {
if (info.prepare) {
instance._prepared = info.prepare(instance, options, info);
} else {
instance._prepared = options.initialState || {};
}
}
return instance;
};
subApp.preRender = info.__preRender;
subApp.signalReady = info.__signalReady;
subApp.start = (instance, options, info) => {
instance = instance || subApp.preStart(instance, options, info);
info = info || subApp.info;
if (instance && !instance.props && options) {
instance.props = options.props;
}
// if user provided a start function, then user is expected to
// have reference to info
const callStart = () => {
if (info.start) {
return info.start(instance, instance.element);
}
return subApp._renderStart(instance, instance.element);
};
if (instance._prepared && instance._prepared.then) {
return instance._prepared.then(r => {
instance._prepared = r;
return callStart();
});
} else {
return callStart();
}
};
const findInstanceInGroup = (groupInfo, group, name) => {
return groupInfo.queue.find(x => {
if (x.options.name === name && x.options.group === group && x.options.inline) {
return x.instance;
}
return undefined;
});
};
const findFirstGroup = ({
name
}) => {
for (let k in _xarc.default.rt.groups) {
const groupInfo = _xarc.default.rt.groups[k];
return findInstanceInGroup(groupInfo, groupInfo.group, name);
}
};
subApp.inline = ({
group,
props
}) => {
const fail = msg => {
console.error(msg);
return `<!--
****** ${msg}
-->`;
};
let found;
if (group) {
const groupInfo = _xarc.default.rt.groups[group];
if (!groupInfo) {
return fail(`subApp inline unable to find group ${group}`);
}
found = findInstanceInGroup(groupInfo, group, subApp.info.name);
if (!found) {
return fail(`subApp inline unable to find instance in group ${group} \
for subapp ${subApp.info.name}`);
}
} else {
found = findFirstGroup(props);
if (!found) {
return fail(`subApp inline unable to find a group with instance for subApp ${name}`);
}
}
return subApp.start(found.instance, Object.assign({}, found.options, {
props
}), found.info);
};
// xarc.addOnLoadStart(name, options);
// getOnLoadStart(name)
// .forEach(options => setTimeout(() => subApp.start(options), 0));
return info;
}
function getSubAppComponent({
name,
timeout = 15000,
onReady,
onError,
fallback
}) {
//
}
function waitForSubApp(name, timeout = 15000) {
return new Promise((resolve, reject) => {
lazyLoadSubApp({
name,
onLoad: () => resolve(),
onError: () => reject(),
timeout
});
});
}
function isLoaded(name) {
return Boolean(_xarc.default.getSubApp(name));
}
function lazyLoadSubApp({
name,
id,
timeout = 15000,
onLoad,
onError,
fallback,
ns,
props
}) {
// TODO: timeout and callback
const lname = name.toLowerCase();
const renderToDomId = (instance, subApp) => {
if (!id) {
return onLoad && onLoad();
} else {
const element = document.getElementById(id);
if (element && subApp.start) {
return subApp.start(instance, {
id,
props
});
}
}
};
const renderInline = () => {
const subApp = _xarc.default.getSubApp(name);
if (subApp) {
return subApp.start(null, {});
}
return false;
};
if (_xarc.default.getBundle(name, ns) === undefined) {
_xarc.default.loadSubAppBundles(lname, null, ns);
} else if (!id && !onLoad) {
const inlined = renderInline();
if (inlined) {
return inlined;
}
}
const startTime = Date.now();
const load = delay => {
setTimeout(() => {
const subApp = _xarc.default.getSubApp(name);
if (subApp) {
return _xarc.default.startSubApp(subApp, {
id
}, true).then(() => renderToDomId(null, subApp));
}
if (timeout > 50 && Date.now() - startTime > timeout) {
const msg = "lazyLoadSubApp Timeout: " + name;
return onError ? onError(new Error(msg)) : console.error(msg);
}
return load(50);
}, delay);
};
load(0);
return fallback;
}
function getBrowserHistory() {
if (!_xarc.default.rt.history) _xarc.default.rt.history = (0, _history.createBrowserHistory)();
return _xarc.default.rt.history;
}
function hotReloadSubApp(info) {
info = info.default || info; // check for es6 module
const subApp = _xarc.default.getSubApp(info.name);
subApp.info = info;
subApp._started.forEach(instance => setTimeout(() => subApp.start(instance), 0));
}
//# sourceMappingURL=index.js.map