2019-09-19 15:35:40 +12:00
|
|
|
import {writable} from "svelte/store";
|
2019-09-23 17:08:06 +12:00
|
|
|
import { createCoreApi } from "./core";
|
2019-09-28 04:03:31 +12:00
|
|
|
import { getStateOrValue } from "./state/getState";
|
2019-10-10 18:18:02 +13:00
|
|
|
import { setState, setStateFromBinding } from "./state/setState";
|
2019-09-29 18:40:06 +13:00
|
|
|
import { trimSlash } from "./common/trimSlash";
|
2019-10-10 18:18:02 +13:00
|
|
|
import { isBound } from "./state/isState";
|
2020-01-25 19:24:48 +13:00
|
|
|
import { _initialiseChildren } from "./render/initialiseChildren";
|
2019-09-28 04:03:31 +12:00
|
|
|
|
2020-01-27 11:56:36 +13:00
|
|
|
export const createApp = (componentLibraries, appDefinition, user, uiFunctions) => {
|
2020-01-18 12:06:42 +13:00
|
|
|
|
2019-09-23 17:08:06 +12:00
|
|
|
const coreApi = createCoreApi(appDefinition, user);
|
2019-10-19 05:32:03 +13:00
|
|
|
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
|
2019-09-26 16:40:58 +12:00
|
|
|
const store = writable({
|
|
|
|
_bbuser: user
|
|
|
|
});
|
2019-09-19 15:35:40 +12:00
|
|
|
|
2019-09-28 04:03:31 +12:00
|
|
|
|
|
|
|
let globalState = null;
|
|
|
|
store.subscribe(s => {
|
|
|
|
globalState = s;
|
|
|
|
});
|
|
|
|
|
2019-09-29 18:40:06 +13:00
|
|
|
const relativeUrl = (url) =>
|
|
|
|
appDefinition.appRootPath
|
|
|
|
? appDefinition.appRootPath + "/" + trimSlash(url)
|
|
|
|
: url;
|
|
|
|
|
|
|
|
|
|
|
|
const apiCall = (method) => (url, body) =>
|
|
|
|
fetch(relativeUrl(url), {
|
|
|
|
method: method,
|
|
|
|
headers: {
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
},
|
|
|
|
body: body && JSON.stringify(body),
|
|
|
|
});
|
|
|
|
|
|
|
|
const api = {
|
2020-01-27 11:56:36 +13:00
|
|
|
post: apiCall("POST"),
|
|
|
|
get: apiCall("GET"),
|
|
|
|
patch: apiCall("PATCH"),
|
|
|
|
delete: apiCall("DELETE")
|
2019-09-29 18:40:06 +13:00
|
|
|
};
|
|
|
|
|
2019-10-07 18:03:41 +13:00
|
|
|
const safeCallEvent = (event, context) => {
|
|
|
|
|
|
|
|
const isFunction = (obj) =>
|
|
|
|
!!(obj && obj.constructor && obj.call && obj.apply);
|
|
|
|
|
|
|
|
if(isFunction(event)) event(context);
|
|
|
|
}
|
|
|
|
|
2020-01-25 19:24:48 +13:00
|
|
|
const initialiseChildrenParams = (parentContext, hydrate) => ({
|
|
|
|
bb, coreApi, store,
|
|
|
|
componentLibraries, appDefinition,
|
2020-01-27 11:56:36 +13:00
|
|
|
parentContext, hydrate, uiFunctions
|
2020-01-25 19:24:48 +13:00
|
|
|
});
|
|
|
|
|
2019-10-19 19:24:20 +13:00
|
|
|
const bb = (context, props) => ({
|
2020-01-25 19:24:48 +13:00
|
|
|
hydrateChildren: _initialiseChildren(initialiseChildrenParams(context, true)),
|
|
|
|
appendChildren: _initialiseChildren(initialiseChildrenParams(context, false)),
|
2020-01-18 12:06:42 +13:00
|
|
|
insertChildren: (props, htmlElement, anchor, context) =>
|
2020-01-25 19:24:48 +13:00
|
|
|
_initialiseChildren(initialiseChildrenParams(context, false))
|
|
|
|
(props, htmlElement, context, anchor),
|
2019-09-28 04:03:31 +12:00
|
|
|
store,
|
2019-09-29 18:40:06 +13:00
|
|
|
relativeUrl,
|
|
|
|
api,
|
2019-10-07 18:03:41 +13:00
|
|
|
call:safeCallEvent,
|
2019-10-10 18:18:02 +13:00
|
|
|
isBound,
|
|
|
|
setStateFromBinding: (binding, value) => setStateFromBinding(store, binding, value),
|
|
|
|
setState: (path, value) => setState(store, path, value),
|
2019-09-28 04:03:31 +12:00
|
|
|
getStateOrValue: (prop, currentContext) =>
|
2019-10-10 18:18:02 +13:00
|
|
|
getStateOrValue(globalState, prop, currentContext),
|
2019-10-19 05:32:03 +13:00
|
|
|
context,
|
|
|
|
props
|
2019-10-01 17:57:45 +13:00
|
|
|
});
|
|
|
|
|
2019-10-10 18:18:02 +13:00
|
|
|
return bb();
|
2019-09-19 15:35:40 +12:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-10-19 05:32:03 +13:00
|
|
|
const buildBindings = (boundProps, boundArrays, contextBoundProps) => {
|
|
|
|
const bindings = {};
|
|
|
|
if(boundProps && boundProps.length > 0) {
|
|
|
|
for(let p of boundProps) {
|
|
|
|
bindings[p.propName] = {
|
|
|
|
path: p.path,
|
|
|
|
fallback: p.fallback,
|
|
|
|
source: p.source
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(contextBoundProps && contextBoundProps.length > 0) {
|
|
|
|
for(let p of contextBoundProps) {
|
|
|
|
bindings[p.propName] = {
|
|
|
|
path: p.path,
|
|
|
|
fallback: p.fallback,
|
|
|
|
source: p.source
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(boundArrays && boundArrays.length > 0) {
|
|
|
|
for(let a of boundArrays) {
|
|
|
|
const arrayOfBindings = [];
|
|
|
|
|
|
|
|
for(let b of a.arrayOfBindings) {
|
|
|
|
arrayOfBindings.push(
|
|
|
|
buildBindings(
|
|
|
|
b.boundProps,
|
|
|
|
b.boundArrays,
|
|
|
|
b.contextBoundProps)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
bindings[a.propName] = arrayOfBindings;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return bindings;
|
|
|
|
}
|
|
|
|
|