significant client lib refactor
This commit is contained in:
parent
b4b90fcaeb
commit
c7b8220a62
|
@ -17,13 +17,14 @@
|
||||||
export let onChange
|
export let onChange
|
||||||
|
|
||||||
let isOpen = false
|
let isOpen = false
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="handler-option">
|
<div class="handler-option">
|
||||||
<span>{parameter.name}</span>
|
<span>{parameter.name}</span>
|
||||||
<div class="handler-input">
|
<div class="handler-input">
|
||||||
{#if parameter.name === 'workflow'}
|
{#if parameter.name === 'workflow'}
|
||||||
<select class="budibase__input" {onChange} value={parameter.value}>
|
<select class="budibase__input" on:change={onChange} bind:value={parameter.value}>
|
||||||
{#each $workflowStore.workflows as workflow}
|
{#each $workflowStore.workflows as workflow}
|
||||||
<option value={workflow._id}>{workflow.name}</option>
|
<option value={workflow._id}>{workflow.name}</option>
|
||||||
{/each}
|
{/each}
|
||||||
|
|
|
@ -12,6 +12,7 @@ const ACTION = {
|
||||||
},
|
},
|
||||||
NAVIGATE: {
|
NAVIGATE: {
|
||||||
name: "Navigate",
|
name: "Navigate",
|
||||||
|
tagline: "Navigate to <b>{{url}}</b>",
|
||||||
icon: "ri-navigation-line",
|
icon: "ri-navigation-line",
|
||||||
description: "Navigate to another page.",
|
description: "Navigate to another page.",
|
||||||
environment: "CLIENT",
|
environment: "CLIENT",
|
||||||
|
|
|
@ -44,7 +44,8 @@ export const clientStrategy = {
|
||||||
// Means that it's bound to state or workflow context
|
// Means that it's bound to state or workflow context
|
||||||
mappedArgs[arg] = mustache.render(argValue, {
|
mappedArgs[arg] = mustache.render(argValue, {
|
||||||
context: this.context,
|
context: this.context,
|
||||||
state: api.getState()
|
// TODO: map to the real state
|
||||||
|
state: {}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// if (argValue.startsWith("$")) {
|
// if (argValue.startsWith("$")) {
|
||||||
|
@ -88,6 +89,9 @@ export const clientStrategy = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (block.actionId === "NAVIGATE") {
|
||||||
|
}
|
||||||
|
|
||||||
if (block.actionId === "DELAY") {
|
if (block.actionId === "DELAY") {
|
||||||
await this.delay(block.args.time)
|
await this.delay(block.args.time)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
export const trimSlash = str => str.replace(/^\/+|\/+$/g, "")
|
|
|
@ -15,17 +15,17 @@ export const createApp = ({
|
||||||
let screenStateManager
|
let screenStateManager
|
||||||
|
|
||||||
const onScreenSlotRendered = screenSlotNode => {
|
const onScreenSlotRendered = screenSlotNode => {
|
||||||
const onScreenSelected = (screen, store, url) => {
|
const onScreenSelected = (screen, url) => {
|
||||||
const stateManager = createStateManager({
|
const stateManager = createStateManager({
|
||||||
store,
|
|
||||||
frontendDefinition,
|
frontendDefinition,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
onScreenSlotRendered: () => {},
|
onScreenSlotRendered: () => {},
|
||||||
routeTo,
|
routeTo,
|
||||||
appRootPath: frontendDefinition.appRootPath,
|
appRootPath: frontendDefinition.appRootPath,
|
||||||
})
|
})
|
||||||
|
const getAttachChildrenParams = attachChildrenParams(stateManager)
|
||||||
screenSlotNode.props._children = [screen.props]
|
screenSlotNode.props._children = [screen.props]
|
||||||
const initialiseChildParams = attachChildrenParams(stateManager, screenSlotNode)
|
const initialiseChildParams = getAttachChildrenParams(screenSlotNode)
|
||||||
attachChildren(initialiseChildParams)(screenSlotNode.rootElement, {
|
attachChildren(initialiseChildParams)(screenSlotNode.rootElement, {
|
||||||
hydrate: true,
|
hydrate: true,
|
||||||
force: true,
|
force: true,
|
||||||
|
@ -35,11 +35,11 @@ export const createApp = ({
|
||||||
currentUrl = url
|
currentUrl = url
|
||||||
}
|
}
|
||||||
|
|
||||||
routeTo = screenRouter(
|
routeTo = screenRouter({
|
||||||
frontendDefinition.screens,
|
screens: frontendDefinition.screens,
|
||||||
onScreenSelected,
|
onScreenSelected,
|
||||||
frontendDefinition.appRootPath
|
appRootPath: frontendDefinition.appRootPath
|
||||||
)
|
})
|
||||||
const fallbackPath = window.location.pathname.replace(
|
const fallbackPath = window.location.pathname.replace(
|
||||||
frontendDefinition.appRootPath,
|
frontendDefinition.appRootPath,
|
||||||
""
|
""
|
||||||
|
@ -47,17 +47,21 @@ export const createApp = ({
|
||||||
routeTo(currentUrl || fallbackPath)
|
routeTo(currentUrl || fallbackPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
const attachChildrenParams = (stateManager, treeNode) => ({
|
const attachChildrenParams = stateManager => {
|
||||||
componentLibraries,
|
const getInitialiseParams = treeNode => ({
|
||||||
treeNode,
|
componentLibraries,
|
||||||
onScreenSlotRendered,
|
treeNode,
|
||||||
setupState: stateManager.setup,
|
onScreenSlotRendered,
|
||||||
getCurrentState: stateManager.getCurrentState,
|
setupState: stateManager.setup,
|
||||||
});
|
getCurrentState: stateManager.getCurrentState,
|
||||||
|
})
|
||||||
|
|
||||||
|
return getInitialiseParams
|
||||||
|
}
|
||||||
|
|
||||||
let rootTreeNode
|
let rootTreeNode
|
||||||
const pageStateManager = createStateManager({
|
const pageStateManager = createStateManager({
|
||||||
store: writable({ _bbuser: user }),
|
// store: writable({ _bbuser: user }),
|
||||||
frontendDefinition,
|
frontendDefinition,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
onScreenSlotRendered,
|
onScreenSlotRendered,
|
||||||
|
@ -73,8 +77,8 @@ export const createApp = ({
|
||||||
rootTreeNode.props = {
|
rootTreeNode.props = {
|
||||||
_children: [page.props],
|
_children: [page.props],
|
||||||
}
|
}
|
||||||
rootTreeNode.rootElement = target
|
const getInitialiseParams = attachChildrenParams(pageStateManager)
|
||||||
const initChildParams = attachChildrenParams(pageStateManager, rootTreeNode)
|
const initChildParams = getInitialiseParams(rootTreeNode)
|
||||||
|
|
||||||
attachChildren(initChildParams)(target, {
|
attachChildren(initChildParams)(target, {
|
||||||
hydrate: true,
|
hydrate: true,
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
import { appStore } from "../state/store"
|
||||||
|
import mustache from "mustache";
|
||||||
|
|
||||||
export const prepareRenderComponent = ({
|
export const prepareRenderComponent = ({
|
||||||
ComponentConstructor,
|
ComponentConstructor,
|
||||||
htmlElement,
|
htmlElement,
|
||||||
anchor,
|
anchor,
|
||||||
props,
|
props,
|
||||||
parentNode,
|
parentNode
|
||||||
getCurrentState,
|
|
||||||
}) => {
|
}) => {
|
||||||
const parentContext = (parentNode && parentNode.context) || {}
|
const parentContext = (parentNode && parentNode.context) || {}
|
||||||
|
|
||||||
|
@ -36,6 +38,20 @@ export const prepareRenderComponent = ({
|
||||||
if (props._id && thisNode.rootElement) {
|
if (props._id && thisNode.rootElement) {
|
||||||
thisNode.rootElement.classList.add(`${componentName}-${props._id}`)
|
thisNode.rootElement.classList.add(`${componentName}-${props._id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// make this node listen to the store
|
||||||
|
if (thisNode.stateBound) {
|
||||||
|
const unsubscribe = appStore.subscribe(state => {
|
||||||
|
const storeBoundProps = { ...initialProps._bb.props };
|
||||||
|
for (let prop in storeBoundProps) {
|
||||||
|
if (typeof storeBoundProps[prop] === "string") {
|
||||||
|
storeBoundProps[prop] = mustache.render(storeBoundProps[prop], { state });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thisNode.component.$set(storeBoundProps);
|
||||||
|
});
|
||||||
|
thisNode.unsubscribe = unsubscribe
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import regexparam from "regexparam"
|
import regexparam from "regexparam"
|
||||||
import { writable } from "svelte/store"
|
import { routerStore } from "../state/store";
|
||||||
|
|
||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
export const screenRouter = (screens, onScreenSelected, appRootPath) => {
|
export const screenRouter = ({ screens, onScreenSelected, appRootPath }) => {
|
||||||
const makeRootedPath = url => {
|
const makeRootedPath = url => {
|
||||||
if (appRootPath) {
|
if (appRootPath) {
|
||||||
if (url) return `${appRootPath}${url.startsWith("/") ? "" : "/"}${url}`
|
if (url) return `${appRootPath}${url.startsWith("/") ? "" : "/"}${url}`
|
||||||
|
@ -41,13 +41,14 @@ export const screenRouter = (screens, onScreenSelected, appRootPath) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const storeInitial = {}
|
routerStore.update(state => {
|
||||||
storeInitial["##routeParams"] = params
|
state["##routeParams"] = params;
|
||||||
const store = writable(storeInitial)
|
return state;
|
||||||
|
})
|
||||||
|
|
||||||
const screenIndex = current !== -1 ? current : fallback
|
const screenIndex = current !== -1 ? current : fallback
|
||||||
|
|
||||||
onScreenSelected(screens[screenIndex], store, _url)
|
onScreenSelected(screens[screenIndex], _url)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
!url.state && history.pushState(_url, null, _url)
|
!url.state && history.pushState(_url, null, _url)
|
||||||
|
@ -56,29 +57,8 @@ export const screenRouter = (screens, onScreenSelected, appRootPath) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function click(e) {
|
|
||||||
const x = e.target.closest("a")
|
|
||||||
const y = x && x.getAttribute("href")
|
|
||||||
|
|
||||||
if (
|
|
||||||
e.ctrlKey ||
|
|
||||||
e.metaKey ||
|
|
||||||
e.altKey ||
|
|
||||||
e.shiftKey ||
|
|
||||||
e.button ||
|
|
||||||
e.defaultPrevented
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if (!y || x.target || x.host !== location.host) return
|
|
||||||
|
|
||||||
e.preventDefault()
|
|
||||||
route(y)
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener("popstate", route)
|
addEventListener("popstate", route)
|
||||||
addEventListener("pushstate", route)
|
addEventListener("pushstate", route)
|
||||||
addEventListener("click", click)
|
|
||||||
|
|
||||||
return route
|
return route
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import { isBound } from "./parseBinding"
|
||||||
import { attachChildren } from "../render/attachChildren"
|
import { attachChildren } from "../render/attachChildren"
|
||||||
import { getContext, setContext } from "./getSetContext"
|
import { getContext, setContext } from "./getSetContext"
|
||||||
|
|
||||||
|
export const trimSlash = str => str.replace(/^\/+|\/+$/g, "")
|
||||||
|
|
||||||
export const bbFactory = ({
|
export const bbFactory = ({
|
||||||
store,
|
store,
|
||||||
getCurrentState,
|
getCurrentState,
|
||||||
|
@ -61,11 +63,7 @@ export const bbFactory = ({
|
||||||
context: treeNode.context,
|
context: treeNode.context,
|
||||||
props: treeNode.props,
|
props: treeNode.props,
|
||||||
call: safeCallEvent,
|
call: safeCallEvent,
|
||||||
setStateFromBinding: (binding, value) =>
|
setState,
|
||||||
setStateFromBinding(store, binding, value),
|
|
||||||
setState: (path, value) => setState(store, path, value),
|
|
||||||
// getStateOrValue: (prop, currentContext) =>
|
|
||||||
// getStateOrValue(getCurrentState(), prop, currentContext),
|
|
||||||
getContext: getContext(treeNode),
|
getContext: getContext(treeNode),
|
||||||
setContext: setContext(treeNode),
|
setContext: setContext(treeNode),
|
||||||
store: store,
|
store: store,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { setState } from "./setState"
|
import { setState } from "./setState"
|
||||||
import { getState } from "./getState"
|
import { getState } from "./getState"
|
||||||
import { isArray, isUndefined } from "lodash/fp"
|
import { isArray, isUndefined } from "lodash/fp"
|
||||||
|
import { appStore } from "./store";
|
||||||
|
|
||||||
import { createApi } from "../api"
|
import { createApi } from "../api"
|
||||||
|
|
||||||
|
@ -12,8 +13,6 @@ export const eventHandlers = (store, rootPath, routeTo) => {
|
||||||
parameters,
|
parameters,
|
||||||
})
|
})
|
||||||
|
|
||||||
const setStateWithStore = (path, value) => setState(store, path, value)
|
|
||||||
|
|
||||||
let currentState
|
let currentState
|
||||||
store.subscribe(state => {
|
store.subscribe(state => {
|
||||||
currentState = state
|
currentState = state
|
||||||
|
@ -21,11 +20,11 @@ export const eventHandlers = (store, rootPath, routeTo) => {
|
||||||
|
|
||||||
const api = createApi({
|
const api = createApi({
|
||||||
rootPath,
|
rootPath,
|
||||||
setState: setStateWithStore,
|
setState,
|
||||||
getState: (path, fallback) => getState(currentState, path, fallback)
|
getState: (path, fallback) => getState(path, fallback)
|
||||||
})
|
})
|
||||||
|
|
||||||
const setStateHandler = ({ path, value }) => setState(store, path, value)
|
const setStateHandler = ({ path, value }) => setState(path, value)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"Set State": handler(["path", "value"], setStateHandler),
|
"Set State": handler(["path", "value"], setStateHandler),
|
||||||
|
|
|
@ -1,49 +1,10 @@
|
||||||
// import { isUndefined, isObject } from "lodash/fp"
|
// import { isUndefined, isObject } from "lodash/fp"
|
||||||
|
import { get } from "svelte/store";
|
||||||
import getOr from "lodash/fp/getOr";
|
import getOr from "lodash/fp/getOr";
|
||||||
// import { parseBinding, isStoreBinding } from "./parseBinding"
|
import { appStore } from "./store";
|
||||||
|
|
||||||
export const getState = (state, path, fallback) => {
|
export const getState = (path, fallback) => {
|
||||||
if (!state) return fallback
|
|
||||||
if (!path || path.length === 0) return fallback
|
if (!path || path.length === 0) return fallback
|
||||||
|
|
||||||
return getOr(fallback, path, state);
|
return getOr(fallback, path, get(appStore));
|
||||||
|
}
|
||||||
// if (path === "$") return state
|
|
||||||
|
|
||||||
// const pathParts = path.split(".")
|
|
||||||
// const safeGetPath = (obj, currentPartIndex = 0) => {
|
|
||||||
// const currentKey = pathParts[currentPartIndex]
|
|
||||||
|
|
||||||
// if (pathParts.length - 1 == currentPartIndex) {
|
|
||||||
// const value = obj[currentKey]
|
|
||||||
// if (isUndefined(value)) return fallback
|
|
||||||
// else return value
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (
|
|
||||||
// obj[currentKey] === null ||
|
|
||||||
// obj[currentKey] === undefined ||
|
|
||||||
// !isObject(obj[currentKey])
|
|
||||||
// ) {
|
|
||||||
// return fallback
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return safeGetPath(obj[currentKey], currentPartIndex + 1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return safeGetPath(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
// export const getStateOrValue = (globalState, prop, currentContext) => {
|
|
||||||
// if (!prop) return prop
|
|
||||||
|
|
||||||
// const binding = parseBinding(prop)
|
|
||||||
|
|
||||||
// if (binding) {
|
|
||||||
// const stateToUse = isStoreBinding(binding) ? globalState : currentContext
|
|
||||||
|
|
||||||
// return getState(stateToUse, binding.path, binding.fallback)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return prop
|
|
||||||
// }
|
|
|
@ -1,67 +1,67 @@
|
||||||
export const BB_STATE_BINDINGPATH = "##bbstate"
|
// export const BB_STATE_BINDINGPATH = "##bbstate"
|
||||||
export const BB_STATE_BINDINGSOURCE = "##bbsource"
|
// export const BB_STATE_BINDINGSOURCE = "##bbsource"
|
||||||
export const BB_STATE_FALLBACK = "##bbstatefallback"
|
// export const BB_STATE_FALLBACK = "##bbstatefallback"
|
||||||
|
|
||||||
export const isBound = prop => !!parseBinding(prop)
|
// export const isBound = prop => !!parseBinding(prop)
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
*
|
// *
|
||||||
* @param {object|string|number} prop - component property to parse for a dynamic state binding
|
// * @param {object|string|number} prop - component property to parse for a dynamic state binding
|
||||||
* @returns {object|boolean}
|
// * @returns {object|boolean}
|
||||||
*/
|
// */
|
||||||
export const parseBinding = prop => {
|
// export const parseBinding = prop => {
|
||||||
if (!prop) return false
|
// if (!prop) return false
|
||||||
|
|
||||||
if (isBindingExpression(prop)) {
|
// if (isBindingExpression(prop)) {
|
||||||
return parseBindingExpression(prop)
|
// return parseBindingExpression(prop)
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (isAlreadyBinding(prop)) {
|
// if (isAlreadyBinding(prop)) {
|
||||||
return {
|
// return {
|
||||||
path: prop.path,
|
// path: prop.path,
|
||||||
source: prop.source || "store",
|
// source: prop.source || "store",
|
||||||
fallback: prop.fallback,
|
// fallback: prop.fallback,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (hasBindingObject(prop)) {
|
// if (hasBindingObject(prop)) {
|
||||||
return {
|
// return {
|
||||||
path: prop[BB_STATE_BINDINGPATH],
|
// path: prop[BB_STATE_BINDINGPATH],
|
||||||
fallback: prop[BB_STATE_FALLBACK] || "",
|
// fallback: prop[BB_STATE_FALLBACK] || "",
|
||||||
source: prop[BB_STATE_BINDINGSOURCE] || "store",
|
// source: prop[BB_STATE_BINDINGSOURCE] || "store",
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
export const isStoreBinding = binding => binding && binding.source === "store"
|
// export const isStoreBinding = binding => binding && binding.source === "store"
|
||||||
export const isContextBinding = binding =>
|
// export const isContextBinding = binding =>
|
||||||
binding && binding.source === "context"
|
// binding && binding.source === "context"
|
||||||
// export const isEventBinding = binding => binding && binding.source === "event"
|
// // export const isEventBinding = binding => binding && binding.source === "event"
|
||||||
|
|
||||||
const hasBindingObject = prop =>
|
// const hasBindingObject = prop =>
|
||||||
typeof prop === "object" && prop[BB_STATE_BINDINGPATH] !== undefined
|
// typeof prop === "object" && prop[BB_STATE_BINDINGPATH] !== undefined
|
||||||
|
|
||||||
const isAlreadyBinding = prop => typeof prop === "object" && prop.path
|
// const isAlreadyBinding = prop => typeof prop === "object" && prop.path
|
||||||
|
|
||||||
const isBindingExpression = prop =>
|
// const isBindingExpression = prop =>
|
||||||
typeof prop === "string" &&
|
// typeof prop === "string" &&
|
||||||
(prop.startsWith("state.") ||
|
// (prop.startsWith("state.") ||
|
||||||
prop.startsWith("context.") ||
|
// prop.startsWith("context.") ||
|
||||||
prop.startsWith("event.") ||
|
// prop.startsWith("event.") ||
|
||||||
prop.startsWith("route."))
|
// prop.startsWith("route."))
|
||||||
|
|
||||||
const parseBindingExpression = prop => {
|
// const parseBindingExpression = prop => {
|
||||||
let [source, ...rest] = prop.split(".")
|
// let [source, ...rest] = prop.split(".")
|
||||||
let path = rest.join(".")
|
// let path = rest.join(".")
|
||||||
|
|
||||||
if (source === "route") {
|
// if (source === "route") {
|
||||||
source = "state"
|
// source = "state"
|
||||||
path = `##routeParams.${path}`
|
// path = `##routeParams.${path}`
|
||||||
}
|
// }
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
fallback: "", // TODO: provide fallback support
|
// fallback: "", // TODO: provide fallback support
|
||||||
source,
|
// source,
|
||||||
path,
|
// path,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,40 +1,17 @@
|
||||||
// import isObject from "lodash/fp/isObject"
|
|
||||||
import set from "lodash/fp/set";
|
import set from "lodash/fp/set";
|
||||||
import { parseBinding } from "./parseBinding"
|
import { appStore } from "./store";
|
||||||
|
|
||||||
export const setState = (store, path, value) => {
|
export const setState = (path, value) => {
|
||||||
if (!path || path.length === 0) return
|
if (!path || path.length === 0) return
|
||||||
|
|
||||||
// const pathParts = path.split(".")
|
appStore.update(state => {
|
||||||
|
|
||||||
// const safeSetPath = (state, currentPartIndex = 0) => {
|
|
||||||
// const currentKey = pathParts[currentPartIndex]
|
|
||||||
|
|
||||||
// if (pathParts.length - 1 == currentPartIndex) {
|
|
||||||
// state[currentKey] = value
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (
|
|
||||||
// state[currentKey] === null ||
|
|
||||||
// state[currentKey] === undefined ||
|
|
||||||
// !isObject(state[currentKey])
|
|
||||||
// ) {
|
|
||||||
// state[currentKey] = {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
// safeSetPath(state[currentKey], currentPartIndex + 1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
store.update(state => {
|
|
||||||
// safeSetPath(state)
|
|
||||||
state = set(path, value, state);
|
state = set(path, value, state);
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setStateFromBinding = (store, binding, value) => {
|
// export const setStateFromBinding = (store, binding, value) => {
|
||||||
const parsedBinding = parseBinding(binding)
|
// const parsedBinding = parseBinding(binding)
|
||||||
if (!parsedBinding) return
|
// if (!parsedBinding) return
|
||||||
return setState(store, parsedBinding.path, value)
|
// return setState(store, parsedBinding.path, value)
|
||||||
}
|
// }
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { createTreeNode } from "../render/prepareRenderComponent"
|
||||||
import { getState } from "./getState"
|
import { getState } from "./getState"
|
||||||
import { attachChildren } from "../render/attachChildren"
|
import { attachChildren } from "../render/attachChildren"
|
||||||
import mustache from "mustache"
|
import mustache from "mustache"
|
||||||
|
import { appStore } from "./store";
|
||||||
|
|
||||||
import { parseBinding } from "./parseBinding"
|
import { parseBinding } from "./parseBinding"
|
||||||
|
|
||||||
|
@ -24,14 +25,14 @@ const isMetaProp = propName =>
|
||||||
propName === "_styles"
|
propName === "_styles"
|
||||||
|
|
||||||
export const createStateManager = ({
|
export const createStateManager = ({
|
||||||
store,
|
// store,
|
||||||
appRootPath,
|
appRootPath,
|
||||||
frontendDefinition,
|
frontendDefinition,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
onScreenSlotRendered,
|
onScreenSlotRendered,
|
||||||
routeTo,
|
routeTo,
|
||||||
}) => {
|
}) => {
|
||||||
let handlerTypes = eventHandlers(store, appRootPath, routeTo)
|
let handlerTypes = eventHandlers(appStore, appRootPath, routeTo)
|
||||||
let currentState
|
let currentState
|
||||||
|
|
||||||
// any nodes that have props that are bound to the store
|
// any nodes that have props that are bound to the store
|
||||||
|
@ -45,33 +46,40 @@ export const createStateManager = ({
|
||||||
// nodesBoundByProps,
|
// nodesBoundByProps,
|
||||||
// nodesWithCodeBoundChildren
|
// nodesWithCodeBoundChildren
|
||||||
// )
|
// )
|
||||||
|
|
||||||
const bb = bbFactory({
|
const bb = bbFactory({
|
||||||
store,
|
store: appStore,
|
||||||
getCurrentState,
|
getCurrentState,
|
||||||
frontendDefinition,
|
frontendDefinition,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
onScreenSlotRendered,
|
onScreenSlotRendered,
|
||||||
})
|
})
|
||||||
|
|
||||||
const setup = _setup(handlerTypes, getCurrentState, bb)
|
const setup = _setup({ handlerTypes, getCurrentState, bb, store: appStore })
|
||||||
|
|
||||||
const unsubscribe = store.subscribe(
|
// TODO: remove
|
||||||
onStoreStateUpdated({
|
const unsubscribe = appStore.subscribe(state => {
|
||||||
setCurrentState: state => (currentState = state),
|
console.log("store updated", state);
|
||||||
getCurrentState,
|
return state;
|
||||||
// nodesWithCodeBoundChildren,
|
});
|
||||||
// nodesBoundByProps,
|
|
||||||
componentLibraries,
|
// const unsubscribe = store.subscribe(
|
||||||
onScreenSlotRendered,
|
// onStoreStateUpdated({
|
||||||
setupState: setup,
|
// setCurrentState: state => (currentState = state),
|
||||||
})
|
// getCurrentState,
|
||||||
)
|
// // nodesWithCodeBoundChildren,
|
||||||
|
// // nodesBoundByProps,
|
||||||
|
// componentLibraries,
|
||||||
|
// onScreenSlotRendered,
|
||||||
|
// setupState: setup,
|
||||||
|
// })
|
||||||
|
// )
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setup,
|
setup,
|
||||||
destroy: () => unsubscribe(),
|
destroy: () => unsubscribe(),
|
||||||
getCurrentState,
|
getCurrentState,
|
||||||
store,
|
store: appStore,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,16 +88,19 @@ const onStoreStateUpdated = ({
|
||||||
getCurrentState,
|
getCurrentState,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
onScreenSlotRendered,
|
onScreenSlotRendered,
|
||||||
setupState,
|
setupState
|
||||||
}) => state => {
|
}) => state => {
|
||||||
setCurrentState(state)
|
// fire the state update event to re-render anything bound to this
|
||||||
attachChildren({
|
// setCurrentState(state)
|
||||||
componentLibraries,
|
|
||||||
treeNode: createTreeNode(),
|
// setCurrentState(state)
|
||||||
onScreenSlotRendered,
|
// attachChildren({
|
||||||
setupState,
|
// componentLibraries,
|
||||||
getCurrentState,
|
// treeNode: createTreeNode(),
|
||||||
})(document.querySelector("#app"), { hydrate: true, force: true })
|
// onScreenSlotRendered,
|
||||||
|
// setupState,
|
||||||
|
// getCurrentState,
|
||||||
|
// })(document.querySelector("#app"), { hydrate: true, force: true })
|
||||||
|
|
||||||
// // the original array gets changed by components' destroy()
|
// // the original array gets changed by components' destroy()
|
||||||
// // so we make a clone and check if they are still in the original
|
// // so we make a clone and check if they are still in the original
|
||||||
|
@ -154,32 +165,41 @@ const onStoreStateUpdated = ({
|
||||||
// node.component.$set(newProps)
|
// node.component.$set(newProps)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
const _setup = (
|
const _setup = ({
|
||||||
handlerTypes,
|
handlerTypes,
|
||||||
getCurrentState,
|
getCurrentState,
|
||||||
bb
|
bb,
|
||||||
) => node => {
|
store
|
||||||
|
}) => node => {
|
||||||
console.log(node);
|
|
||||||
const props = node.props
|
const props = node.props
|
||||||
const context = node.context || {}
|
const context = node.context || {}
|
||||||
const initialProps = { ...props }
|
const initialProps = { ...props }
|
||||||
// const storeBoundProps = []
|
// const storeBoundProps = []
|
||||||
const currentStoreState = getCurrentState()
|
const currentStoreState = getCurrentState()
|
||||||
|
|
||||||
|
console.log("node", node);
|
||||||
|
|
||||||
|
// console.log("node", node);
|
||||||
|
// console.log("nodeComponent", node.component);
|
||||||
|
|
||||||
for (let propName in props) {
|
for (let propName in props) {
|
||||||
if (isMetaProp(propName)) continue
|
if (isMetaProp(propName)) continue
|
||||||
|
|
||||||
const propValue = props[propName]
|
const propValue = props[propName]
|
||||||
|
|
||||||
// const binding = parseBinding(propValue)
|
// const binding = parseBinding(propValue)
|
||||||
// const isBound = !!binding
|
// TODO: better binding stuff
|
||||||
|
const isBound = typeof propValue === "string" && propValue.startsWith("{{");
|
||||||
|
|
||||||
if (typeof propValue === "string") {
|
if (isBound) {
|
||||||
initialProps[propName] = mustache.render(propValue, {
|
initialProps[propName] = mustache.render(propValue, {
|
||||||
state: currentStoreState,
|
state: currentStoreState,
|
||||||
context
|
context
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (!node.stateBound) {
|
||||||
|
node.stateBound = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (isBound) binding.propName = propName
|
// if (isBound) binding.propName = propName
|
||||||
|
@ -254,7 +274,7 @@ const _setup = (
|
||||||
|
|
||||||
// registerBindings(node, storeBoundProps)
|
// registerBindings(node, storeBoundProps)
|
||||||
|
|
||||||
const setup = _setup(handlerTypes, getCurrentState, bb)
|
const setup = _setup({ handlerTypes, getCurrentState, bb, store })
|
||||||
initialProps._bb = bb(node, setup)
|
initialProps._bb = bb(node, setup)
|
||||||
|
|
||||||
return initialProps
|
return initialProps
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { writable } from "svelte/store";
|
||||||
|
|
||||||
|
const appStore = writable({});
|
||||||
|
appStore.actions = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const routerStore = writable({});
|
||||||
|
routerStore.actions = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
appStore,
|
||||||
|
routerStore
|
||||||
|
}
|
Loading…
Reference in New Issue