requires a firebase.config.js
and a mongo.config.js
in the project root directory
- cd functions
- firebase serve
- client bundle
- _common
window.__PROPS__
window.__STATE__
window.__METHODS__
- dialogs
- [logic](#dialogs logic)
<DialogModal/>
component,dialog
prop object specificationwindow.__METHODS__.openDialog(type[, id])
window.__STATE__.dialogs
- mongo aggregations
- server apps (content & api)
- routing [router factory](# router-factory)
refer to the PERMADATA trello board
- client bundle rework with :
- window variables
__PROPS__: { (page) id, lang }
and__STATE__: { bundle, user: { .., data }}
- execution steps,
- steps' common and page-specific _transitions agregation
- window variables
- dialog rework
- city component (& dom cards)
- trighbs gameplay mechanisms
directories to progressively move and delete
- patterns, move to their higher level context folder
- apps/provisioners, move to apps/aggregations
functions/modules/bundles/_common/_common.js
run through the application lifecycle for the [page bundle app] launch
app lives on the [page bundle], and cannot be instanciated before bundle reception
[page bundle] hasn't be received
this state is for SSR only : it cannot be accessed by the application
- bundle received
the [page bundle] has been received, and app started to execute
- bundle error
- bundle data fetch
- put a listener on user authentication : user authenticated
base bundle execution encountered an error
- it brokes the app (think about dismissig dynamic components)
- firebase initialization
- error in _transitions.bundleReceived
- error in _transitions.bundleDataFetch
- error in _transitions.unauthApp
app started fetching the [page bundle] data (like translations, base modules inputs ..)
- bundle error (client-side error)
- bundle data error (server-side error)
- bundle data provisioned + unauth app
fetching encountered an error
- it brokes the app (think about dismissig dynamic components)
[page bundle] data has been sucessfully fetched, and base modules can be rendered
- bundle error
- unauth app
- auth app (only if : user has authenticated and its data has already been fetched)
app is listening for user authenticated, and its changes can now be rendered too
- user can connect
- bundle error
- user authenticated (manual)
authentication provider received a non-null user
- user authenticated error
- user data fetch
user modules execution encountered an error
- app keeps runing, but user features are broken (think about dismissing them)
- user can disonnect
- error in _transitions.userAuthenticated
- error in _transitions.userDataFetch (client-side)
- error in _transitions.userDataProvisioned
- error in _transitions.authApp
- unauth app (manual)
app started fetching user-related data (like dialogs, doms ...)
- user authenticated error (client-side error)
- user data error (server-side error)
- user data provisioned
fetching encountered an error
- app keeps runing, but user features are broken (think about dismissing them)
- user can disonnect
- unauth app
user data has been succesfully fetched, but components aren't rendered here, as we need to check both { bundle } and { user } data availabilities before
- user authenticated error
- auth app (only if : bundle data has already been fetched, else, wait for its resolution)
auth app is accessed only if both { bundle } and { user } data has been successfully fetched
user data has been received, and user's module can be rendered
user can disconnect
- user authenticated error
- unauth app (manual)
- name.{ lang }
- light
- moisture
- hardiness.zone
- foliage
- title
- status (code)
- message
two apps, taking the shape of a router node (see below), are imported in the functions/index.js
file :
- api (from
./apps/api
), for client-side queries - content (from
./apps/content
), for page server-side rendering
access to these [app]s is set in the firebase.json
file such as :
"rewrites": [
{
// url starts with 'api' keyword
"source": "/api/**",
"function": "api"
},
{
// default fallback
"source": "**",
"function": "content"
}
]
P_RCL is to move outside of the pattern directory
routerFactory = ({ _current, _params, _methods, _lowers = {} }, isApi)
to calculate the route tree, the router factory consumes a router node as its main param
isApi
, is used by the api [server] app* to enable special routing behaviour (like : light-weighted provisioning; or JSON-formated error, instead of HTML error page)
the router factory returns a route tree, featuring :
- static url routes (_lowers)
- dynamic parameters url routes (_params) [only last url component can be handled as a parameter in the current version !]
the _params' keys describe a /:key
url component, which can then be accessed in the endpoint callback with ``
preferably, all routes should implement at least one endoint
endpoints return a specific interface depending either the request is handled by the content app or the api one
exposes an object with the following properties :
- id, used to provides specific page provisioning and rendering behaviours
- _provisionner, return a
props => new Promise((resolve, reject) => {})
interface to handle the request
if no endpoint is provided, an 404 html page will be returned
exposes a req => new Promise((resolve, reject) => {})
interface to handle the request
if no endpoint is provided, a JSON error description will be returned with its status code to 404
the router node can have some of these properties :
- a leaf (_current),
- a bunch of leaves (methods),
- a bunch of branches (with :
- _lowers
- _params)
following file organization is enforced by the pattern
{ node-folder }
+-- _current
| +-- _provisioner
| | +-- _provisioner.js
| +-- _current.js
+-- _lowers
| +-- 'key': < node-folder >..*
| +-- index.js
+-- _params
| +-- 'key': ..*
| | +-- _provisioner
| | | +-- _provisioner.js
| | +-- 'key'.js
| +-- index.js
+-- _methods
| +-- 'key': ..*
| | +-- 'key'.js
| +-- index.js
+-- < node-file > (index)
information shown below can be OBSOLETE
group the current provider
const _current = require('./_current')
const _lowers = require('./_lowers')
module.exports = {
_current,
_lowers
}
module.exports = props => {
const { id, lang, url } = props
return props
}
see P_RTP
pattern details
const nodeA = require('./{ nodeA-folder }/{ nodeA-file }')
const nodeB = require('./{ nodeB-folder }/{ nodeB-file }')
// node..N
module.exports = {
nodeA,
nodeB
}
where you should have associate a new router, use the P_RCL method
const target = app || router
target.use(P_RCL(root))
the root object is a router node file
from the root of a P_RCL arborescence, crawl node tree
- content:
apps/content/langRouter/root/root.js
- api:
apps/api/root/root.js
find or create a _current repository & file at the target level
- keywords: provision, render, html, req, page
- used by: P_RCL
at every content route endpoint (_current from [P_RCL]), encapsultate provision & rendering
see P_RCL
_current folder structure for context
module.exports = props => {
const { id, lang, url } = props
return Object.assign({}, props)
}
a dialog is a succession of scenes
scenes display content and can output server-side actions. They usually can be browsed through the Back & Next buttons
each given dialog get its own temporary state variables :
- scope, UI or form validation data,
- form, data to be sent at some point in the dialog
these variables are historized
these variables also can be used in the _eval
methods: evalStatic and evalClick, in addition to the contextual given props
user change re-initializes dialog history
dialog is opened by calling the global function window.__METHODS__.openDialog(type[, id[, options]])
given the function's parameters, the <DialogModal/>
will be rendered with a processed dialog variable
obtaining this processed variable is achieved through the following two steps :
- _sourceGetters, where dialog data is provisioned
- _dialogBuilders, where data is processed in order to meet the
<DialogModal/>
's dialog property requirements
specific step behaviour is arranged according to the type
param, which accepts the following value :
- 'main'
- 'previous'
- 'extract', requires the
id
param - 'event', requires the
id
param - 'dom', requires the
id
param
whenever a dialog is opened, it creates an entry in the history
changing scene, scope or form is saved in the history entry
what's expected from the inputed <DialogModal/>
's dialog prop
target format can be obtained through the _dialogBuilders
step
const dialog = {
_id: 'string',
extracts: ['<extractId>: ObjectId'], // optional, used in introduction, when the KOLO-SEED shell isn't available
scenes: {
first: '<sceneId>: string',
pages: [ // index gives the current page displayed in the dialog title
['<sceneId>: string'] ], // matching scene ids
list: {
['<sceneId>: string']: '<scene>'
}
},
'<lang>': {
dialog: {
title
},
scenes: {
'<sceneId>: string': '<langScene>'
}
},
main: false || true // if true, dialog will be opened when the user auth
}
const scene = {
extracts: ['<extractId>: string'], // extracts has to be required through dialog.extracts property
menu: {
order: ['<optionId>: string'],
list: {
['<optionIdd>: string']: '<menuItem>'
},
back: '<menuItem>',
back2: '<menuItem>', // requires 'back' to be first set in order to be displayed
next: '<menuItem>',
next2: '<menuItem>' // requires 'next' to be first set in order to be displayed
}
const menuItem = {
hidden: false || true || 'evaluable code for exposed dialog API',
disabled: false || true || 'evaluable code ...',
valid: false || true || 'evaluable code ...',
click: 'evaluable code'
}
const langScene = {
content: '<markdown>: string',
summary: 'evaluable code , for templating',
menu: {
label: 'evaluable code ...'
},
back: {
label: 'evaluable code ...'
},
next: {
label: 'evaluable code ...'
}
}
restricted to the 'maturing kolo-seed'
dialog
- [empty rooms].quantity > 0, no interaction
- [empty rooms].quantity === 0, displays the "release" button
- if confirmed, go to the next
'wandering kolo-seed'
dialog
- if confirmed, go to the next
restricted to the 'wandering kolo-seed'
& 'installed kolo-seed'
dialogs
'wandering kolo-seed'
, no interaction'installed kolo-seed'
, displays the "start" button- if confirmed, go to the next
'starting ong-cite'
dialog
- if confirmed, go to the next
restricted to the 'maturing kolo-seed'
dialog
-
dialogs
- "fill room", choose TRIGHBS or access presentation event dialog
-
quantity (number of empty rooms)
- initialized with 3
- in the
'maturing kolo-seed'
step, choosing a TRIGHB RAYÖN will reduce the quantity by 1 - at 0, removes the DOMS from
user.data.home
and allows the ong-cite embryo to be released
- displays the "fill room" button which open the "fill room" dialog
- "fill room" dialog allows:
- direct TRIGHB selection
- TRIGHB-related event dialog opening
- extracts, contains extract references
- when validating user (first user data provisioning), randomly pick up 2 extracts about each of the 5 following concepts: "FRAST", "HOL-ONG", "ZUMS", "TRIGHBS", "KOLO-SEED"
- at the
'introduction'
dialog validation, when the kolo-seed shell is added, these random extracts are bound to it