feat: context types

This commit is contained in:
cha0s 2020-06-19 17:59:37 -05:00
parent 35e2a36e58
commit faea819945
6 changed files with 40 additions and 46 deletions

View File

@ -14,7 +14,7 @@ const json = require('~/../fixtures/kitty.entity.json');
const EntityComponent = (props) => { const EntityComponent = (props) => {
const {context} = props; const {context} = props;
const entity = new Entity(json); const entity = new Entity(json);
context.add('entity', entity); context.add('entity', entity, 'entity');
const {traits} = json; const {traits} = json;
return ( return (
<div className="entity"> <div className="entity">

View File

@ -6,7 +6,7 @@
} }
.operator { .operator {
margin: 0.25em 0; margin: 0;
text-align: center; text-align: center;
text-align-last: center; text-align-last: center;
} }

View File

@ -1,35 +1,40 @@
import {flatten} from '@avocado/core'; import {flatten} from '@avocado/core';
import {Context} from '@avocado/behavior'
import {typeFits, typeFromV} from './typing'; import {typeFits} from './typing';
export const variableStepsList = (key, variable, description, type) => { export const variableStepsList = (key, variable, variableType, type) => {
const description = Context.typeDescription(variableType, variable);
const steps = []; const steps = [];
if (typeFits(type, description.type)) { if (typeFits(type, variableType)) {
steps.push({type: 'key', key}); steps.push({type: 'key', key});
if ('function' === typeof variable) { if ('function' === typeof variable) {
steps.push({type: 'invoke', args: []}); steps.push({type: 'invoke', args: []});
} }
} }
if (!variable || !variable.contextDescription) { if (!variable) {
return steps; return [steps];
} }
const {children} = variable.contextDescription(); const sublists = Object.entries(description)
const sublists = Object.entries(children)
.map(([key, description]) => ( .map(([key, description]) => (
flatten(variableStepsList(key, variable[key], description, type)) variableStepsList(key, variable[key], description.type, type)
)) ))
.map((childLists) => ( .map((childLists) => (
childLists.length > 0 ? [{type: 'key', key}].concat(childLists) : [] childLists.map((stepsList) => (
stepsList.length > 0
? [{type: 'key', key}].concat(stepsList)
: []
)) ))
.filter((lists) => lists.length > 0) ))
return sublists.length > 0 ? sublists : [steps]; return sublists.length > 0 ? flatten(sublists) : [steps];
}; };
export const contextStepsList = (context, type) => ( export const contextStepsList = (context, type) => (
flatten( flatten(
Object.entries(context.all()) Object.entries(context.all())
.map(([key, variable]) => ( .map(([key, [variable, variableType]]) => (
variableStepsList(key, variable, {type: typeFromV(variable)}, type) variableStepsList(key, variable, variableType, type)
)) ))
) )
.filter((stepsList) => stepsList.length > 0)
); );

View File

@ -3,7 +3,7 @@ import contempo from 'contempo';
import React, {useState} from 'react'; import React, {useState} from 'react';
import {contextStepsList} from './steps-lists'; import {contextStepsList} from './steps-lists';
import {typeFits, typeFromSteps, typeFromV} from './typing'; import {typeFits, typeFromSteps, typeFromLiteral} from './typing';
import Value from './value.type-renderer'; import Value from './value.type-renderer';
const decorate = compose( const decorate = compose(
@ -19,7 +19,7 @@ const Steps = (props) => {
else { else {
stepsList = contextStepsList( stepsList = contextStepsList(
context, context,
value.steps ? typeFromSteps(context, value.steps) : typeFromV(value.value), value.steps ? typeFromSteps(context, value.steps) : typeFromLiteral(value.value),
); );
} }
return ( return (
@ -64,7 +64,11 @@ const Steps = (props) => {
<div className="arg"> <div className="arg">
<Value.component <Value.component
context={context} context={context}
type={arg.steps ? typeFromSteps(context, arg.steps) : typeFromV(arg.value)} type={
arg.steps
? typeFromSteps(context, arg.steps)
: typeFromLiteral(arg.value)
}
value={arg} value={arg}
/> />
</div> </div>

View File

@ -1,4 +1,6 @@
export function typeFromV(v) { import {Context} from '@avocado/behavior'
export function typeFromLiteral(v) {
if ('undefined' === typeof v) { if ('undefined' === typeof v) {
return 'undefined'; return 'undefined';
} }
@ -17,43 +19,27 @@ export function typeFromV(v) {
if (v.length && 2 === v.length && v instanceof Array) { if (v.length && 2 === v.length && v instanceof Array) {
return 'vector'; return 'vector';
} }
if (!v.contextDescription) {
return 'object'; return 'object';
}
const {type} = v.contextDescription();
return type;
} }
export function typeFromSteps(context, steps) { export function typeFromSteps(context, steps) {
if (!steps || 0 === steps.length) { if (!steps || 0 === steps.length) {
return 'undefined'; return 'undefined';
} }
const first = context.map.get(steps[0].key); const [, finalType] = steps.slice(1).reduce(
const [, type] = steps.slice(1).reduce(
([v, type], step, i) => { ([v, type], step, i) => {
if (i === steps.length - 2) { const {key} = step;
if (v.contextDescription) { if (key) {
const {children} = v.contextDescription(); const description = Context.typeDescription(type, v);
return [undefined, step.key ? children[step.key].type : type]; return [v[key], description[key] ? description[key].type : type];
}
else {
return [undefined, type];
}
}
else {
if (step.key) {
const {children} = v.contextDescription();
return [v[step.key], children[step.key].type];
} }
else { else {
return [v, type]; return [v, type];
} }
}
step
}, },
[first, typeFromV(first)], context.get(steps[0].key),
); );
return type; return finalType;
} }
export function typeFits(reference, candidate) { export function typeFits(reference, candidate) {

View File

@ -8,7 +8,7 @@ import Bool from './bool.type-renderer';
import propertyPropTypes from './property-prop-types'; import propertyPropTypes from './property-prop-types';
import Steps from './steps'; import Steps from './steps';
import {contextStepsList} from './steps-lists'; import {contextStepsList} from './steps-lists';
import {typeFits, typeFromSteps, typeFromV} from './typing'; import {typeFits, typeFromSteps} from './typing';
const renderValue = (context, type, value) => { const renderValue = (context, type, value) => {
switch (value.type) { switch (value.type) {
@ -16,7 +16,6 @@ const renderValue = (context, type, value) => {
return <Steps context={context} steps={value.steps} type={type} value={value.value} />; return <Steps context={context} steps={value.steps} type={type} value={value.value} />;
} }
case 'literal': case 'literal':
// const type = typeFromV(value.value);
const stepsList = contextStepsList(context, type); const stepsList = contextStepsList(context, type);
const tierOptions = Object.keys(stepsList.reduce((r, optionSteps) => { const tierOptions = Object.keys(stepsList.reduce((r, optionSteps) => {
if (!optionSteps[0] || !optionSteps[0].key) { if (!optionSteps[0] || !optionSteps[0].key) {