2019-09-19 05:35:40 +02:00
|
|
|
import {
|
|
|
|
split,
|
|
|
|
last
|
|
|
|
} from "lodash/fp";
|
|
|
|
import {writable} from "svelte/store";
|
|
|
|
import { $ } from "./core/common";
|
2019-09-27 18:03:31 +02:00
|
|
|
import {
|
|
|
|
setupBinding
|
|
|
|
} from "./state/stateBinding";
|
2019-09-23 07:08:06 +02:00
|
|
|
import { createCoreApi } from "./core";
|
2019-09-27 18:03:31 +02:00
|
|
|
import { getStateOrValue } from "./state/getState";
|
2019-09-29 07:40:06 +02:00
|
|
|
import { trimSlash } from "./common/trimSlash";
|
2019-09-27 18:03:31 +02:00
|
|
|
|
2019-09-19 05:35:40 +02:00
|
|
|
|
2019-09-23 07:08:06 +02:00
|
|
|
export const createApp = (componentLibraries, appDefinition, user) => {
|
2019-09-19 05:35:40 +02:00
|
|
|
|
2019-10-01 06:57:45 +02:00
|
|
|
const initialiseComponent = (parentContext) => (props, htmlElement, context) => {
|
2019-09-19 05:35:40 +02:00
|
|
|
|
|
|
|
const {componentName, libName} = splitName(props._component);
|
|
|
|
|
2019-09-22 06:02:33 +02:00
|
|
|
if(!componentName || !libName) return;
|
|
|
|
|
2019-10-03 07:12:13 +02:00
|
|
|
const {initialProps, bind} = setupBinding(store, props, coreApi, context, appDefinition.appRootPath);
|
2019-09-22 06:02:33 +02:00
|
|
|
|
2019-09-19 05:35:40 +02:00
|
|
|
const component = new (componentLibraries[libName][componentName])({
|
|
|
|
target: htmlElement,
|
2019-10-01 06:57:45 +02:00
|
|
|
props: {...initialProps, _bb:bbInContext(context || parentContext)},
|
2019-09-26 06:40:58 +02:00
|
|
|
hydrate:true
|
2019-09-19 05:35:40 +02:00
|
|
|
});
|
|
|
|
|
2019-09-22 06:02:33 +02:00
|
|
|
bind(component);
|
2019-09-19 05:35:40 +02:00
|
|
|
|
2019-10-01 06:57:45 +02:00
|
|
|
return component;
|
2019-09-19 05:35:40 +02:00
|
|
|
}
|
|
|
|
|
2019-09-23 07:08:06 +02:00
|
|
|
const coreApi = createCoreApi(appDefinition, user);
|
2019-09-26 06:40:58 +02:00
|
|
|
const store = writable({
|
|
|
|
_bbuser: user
|
|
|
|
});
|
2019-09-19 05:35:40 +02:00
|
|
|
|
2019-09-27 18:03:31 +02:00
|
|
|
|
|
|
|
let globalState = null;
|
|
|
|
store.subscribe(s => {
|
|
|
|
globalState = s;
|
|
|
|
});
|
|
|
|
|
2019-09-29 07:40:06 +02: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 = {
|
|
|
|
post: apiCall("POST"),
|
|
|
|
get: apiCall("GET"),
|
|
|
|
patch: apiCall("PATCH"),
|
|
|
|
delete:apiCall("DELETE")
|
|
|
|
};
|
|
|
|
|
2019-10-01 06:57:45 +02:00
|
|
|
const bb = () => ({
|
|
|
|
initialiseComponent: initialiseComponent(),
|
2019-09-27 18:03:31 +02:00
|
|
|
store,
|
2019-09-29 07:40:06 +02:00
|
|
|
relativeUrl,
|
|
|
|
api,
|
2019-09-27 18:03:31 +02:00
|
|
|
getStateOrValue: (prop, currentContext) =>
|
|
|
|
getStateOrValue(globalState, prop, currentContext)
|
2019-10-01 06:57:45 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
const bbRoot = bb();
|
|
|
|
|
|
|
|
const bbInContext = (context) => {
|
|
|
|
if(!context) return bbRoot;
|
|
|
|
const bbCxt = bb();
|
|
|
|
bbCxt.context = context;
|
|
|
|
bbCxt.initialiseComponent=initialiseComponent(context);
|
|
|
|
return bbCxt;
|
|
|
|
}
|
2019-09-19 05:35:40 +02:00
|
|
|
|
2019-10-01 06:57:45 +02:00
|
|
|
return bbRoot;
|
2019-09-19 05:35:40 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const splitName = fullname => {
|
|
|
|
const componentName = $(fullname, [
|
|
|
|
split("/"),
|
|
|
|
last
|
|
|
|
]);
|
|
|
|
|
|
|
|
const libName =fullname.substring(
|
|
|
|
0, fullname.length - componentName.length - 1);
|
|
|
|
|
|
|
|
return {libName, componentName};
|
2019-09-29 07:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|