2020-02-18 13:29:38 +01:00
|
|
|
import {
|
|
|
|
isEventType,
|
|
|
|
eventHandlers,
|
|
|
|
EVENT_TYPE_MEMBER_NAME,
|
|
|
|
} from "./eventHandlers"
|
|
|
|
import { bbFactory } from "./bbComponentApi"
|
2020-05-29 15:06:10 +02:00
|
|
|
import mustache from "mustache"
|
2020-06-01 11:41:28 +02:00
|
|
|
import { get } from "svelte/store"
|
|
|
|
import { appStore } from "./store"
|
2020-02-18 13:29:38 +01:00
|
|
|
|
|
|
|
const doNothing = () => {}
|
|
|
|
doNothing.isPlaceholder = true
|
|
|
|
|
|
|
|
const isMetaProp = propName =>
|
|
|
|
propName === "_component" ||
|
|
|
|
propName === "_children" ||
|
|
|
|
propName === "_id" ||
|
|
|
|
propName === "_style" ||
|
|
|
|
propName === "_code" ||
|
2020-05-29 15:06:10 +02:00
|
|
|
propName === "_codeMeta" ||
|
|
|
|
propName === "_styles"
|
2020-02-18 13:29:38 +01:00
|
|
|
|
|
|
|
export const createStateManager = ({
|
2020-02-24 12:15:08 +01:00
|
|
|
appRootPath,
|
2020-02-18 13:29:38 +01:00
|
|
|
frontendDefinition,
|
|
|
|
componentLibraries,
|
|
|
|
onScreenSlotRendered,
|
2020-02-21 15:44:48 +01:00
|
|
|
routeTo,
|
2020-02-18 13:29:38 +01:00
|
|
|
}) => {
|
2020-06-01 22:26:32 +02:00
|
|
|
let handlerTypes = eventHandlers(appRootPath, routeTo)
|
2020-02-18 13:29:38 +01:00
|
|
|
let currentState
|
|
|
|
|
|
|
|
const getCurrentState = () => currentState
|
2020-05-30 01:14:41 +02:00
|
|
|
|
2020-02-18 13:29:38 +01:00
|
|
|
const bb = bbFactory({
|
2020-05-30 01:14:41 +02:00
|
|
|
store: appStore,
|
2020-02-18 13:29:38 +01:00
|
|
|
getCurrentState,
|
|
|
|
frontendDefinition,
|
|
|
|
componentLibraries,
|
|
|
|
onScreenSlotRendered,
|
|
|
|
})
|
|
|
|
|
2020-05-30 01:14:41 +02:00
|
|
|
const setup = _setup({ handlerTypes, getCurrentState, bb, store: appStore })
|
|
|
|
|
2020-02-18 13:29:38 +01:00
|
|
|
return {
|
|
|
|
setup,
|
2020-06-01 22:26:32 +02:00
|
|
|
destroy: () => {},
|
2020-02-18 13:29:38 +01:00
|
|
|
getCurrentState,
|
2020-05-30 01:14:41 +02:00
|
|
|
store: appStore,
|
2020-02-18 13:29:38 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-01 11:41:28 +02:00
|
|
|
const _setup = ({ handlerTypes, getCurrentState, bb, store }) => node => {
|
2020-02-18 13:29:38 +01:00
|
|
|
const props = node.props
|
|
|
|
const context = node.context || {}
|
|
|
|
const initialProps = { ...props }
|
2020-05-30 01:40:33 +02:00
|
|
|
const currentStoreState = get(appStore)
|
2020-02-18 13:29:38 +01:00
|
|
|
|
|
|
|
for (let propName in props) {
|
|
|
|
if (isMetaProp(propName)) continue
|
|
|
|
|
2020-02-21 19:02:02 +01:00
|
|
|
const propValue = props[propName]
|
2020-02-18 13:29:38 +01:00
|
|
|
|
2020-06-01 22:26:32 +02:00
|
|
|
// A little bit of a hack - won't bind if the string doesn't start with {{
|
2020-06-01 11:41:28 +02:00
|
|
|
const isBound = typeof propValue === "string" && propValue.startsWith("{{")
|
2020-02-21 19:02:02 +01:00
|
|
|
|
2020-05-30 01:14:41 +02:00
|
|
|
if (isBound) {
|
2020-05-29 15:06:10 +02:00
|
|
|
initialProps[propName] = mustache.render(propValue, {
|
|
|
|
state: currentStoreState,
|
2020-06-01 11:41:28 +02:00
|
|
|
context,
|
2020-05-29 15:06:10 +02:00
|
|
|
})
|
2020-05-30 01:14:41 +02:00
|
|
|
|
|
|
|
if (!node.stateBound) {
|
|
|
|
node.stateBound = true
|
|
|
|
}
|
2020-05-29 15:06:10 +02:00
|
|
|
}
|
2020-02-18 13:29:38 +01:00
|
|
|
|
2020-02-21 19:02:02 +01:00
|
|
|
if (isEventType(propValue)) {
|
2020-02-18 13:29:38 +01:00
|
|
|
const handlersInfos = []
|
2020-02-21 19:02:02 +01:00
|
|
|
for (let event of propValue) {
|
2020-02-18 13:29:38 +01:00
|
|
|
const handlerInfo = {
|
2020-02-21 19:02:02 +01:00
|
|
|
handlerType: event[EVENT_TYPE_MEMBER_NAME],
|
|
|
|
parameters: event.parameters,
|
2020-02-18 13:29:38 +01:00
|
|
|
}
|
2020-05-29 15:06:10 +02:00
|
|
|
|
2020-02-18 13:29:38 +01:00
|
|
|
const resolvedParams = {}
|
|
|
|
for (let paramName in handlerInfo.parameters) {
|
|
|
|
const paramValue = handlerInfo.parameters[paramName]
|
2020-06-01 11:41:28 +02:00
|
|
|
resolvedParams[paramName] = () =>
|
|
|
|
mustache.render(paramValue, {
|
|
|
|
state: getCurrentState(),
|
|
|
|
context,
|
|
|
|
})
|
2020-02-18 13:29:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
handlerInfo.parameters = resolvedParams
|
|
|
|
handlersInfos.push(handlerInfo)
|
|
|
|
}
|
|
|
|
|
2020-05-29 15:06:10 +02:00
|
|
|
if (handlersInfos.length === 0) {
|
|
|
|
initialProps[propName] = doNothing
|
|
|
|
} else {
|
2020-02-18 13:29:38 +01:00
|
|
|
initialProps[propName] = async context => {
|
|
|
|
for (let handlerInfo of handlersInfos) {
|
|
|
|
const handler = makeHandler(handlerTypes, handlerInfo)
|
|
|
|
await handler(context)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-30 01:14:41 +02:00
|
|
|
const setup = _setup({ handlerTypes, getCurrentState, bb, store })
|
2020-02-18 13:29:38 +01:00
|
|
|
initialProps._bb = bb(node, setup)
|
|
|
|
|
|
|
|
return initialProps
|
|
|
|
}
|
|
|
|
|
|
|
|
const makeHandler = (handlerTypes, handlerInfo) => {
|
|
|
|
const handlerType = handlerTypes[handlerInfo.handlerType]
|
2020-02-24 17:04:13 +01:00
|
|
|
return async context => {
|
2020-02-18 13:29:38 +01:00
|
|
|
const parameters = {}
|
2020-02-21 19:02:02 +01:00
|
|
|
for (let paramName in handlerInfo.parameters) {
|
|
|
|
parameters[paramName] = handlerInfo.parameters[paramName](context)
|
2020-02-18 13:29:38 +01:00
|
|
|
}
|
2020-02-24 17:04:13 +01:00
|
|
|
await handlerType.execute(parameters)
|
2020-02-18 13:29:38 +01:00
|
|
|
}
|
2020-02-23 23:07:28 +01:00
|
|
|
}
|