From 1e446a57096c506797e2750f9e9cb1a757ad54d8 Mon Sep 17 00:00:00 2001 From: cha0s Date: Mon, 22 Jun 2020 04:26:16 -0500 Subject: [PATCH] feat: type graphing --- packages/behavior/context/context.js | 55 ++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/packages/behavior/context/context.js b/packages/behavior/context/context.js index 2579042..eae49b3 100644 --- a/packages/behavior/context/context.js +++ b/packages/behavior/context/context.js @@ -1,3 +1,4 @@ +import {arrayUnique, flatten, mapObject} from '@avocado/core'; import D from 'debug'; import {invokeHookFlat} from 'scwp'; @@ -14,6 +15,27 @@ export class Context { this.addObjectMap(defaults); } + static allTypesDigraph() { + return Object.keys(this.types()) + .reduce((r, type) => ({...r, [type]: this.typeDigraph(type)}), {}); + } + + static allTypesInvertedDigraph() { + const digraph = this.allTypesDigraph(); + const inverted = {}; + const fromTypes = Object.keys(digraph); + for (let i = 0; i < fromTypes.length; i++) { + const fromType = fromTypes[i]; + const toTypes = digraph[fromType]; + for (let j = 0; j < toTypes.length; j++) { + const toType = toTypes[j]; + inverted[toType] = (inverted[toType] || {}); + inverted[toType][fromType] = true; + } + } + return mapObject(inverted, (types) => Object.keys(types)); + } + static describe(description, fn) { const {type} = description; fn.type = type; @@ -22,12 +44,32 @@ export class Context { static globals() { return invokeHookFlat('behaviorContextGlobals') - .reduce((r, globals) => ({...r, ...globals}), {}); + .reduce((r, results) => ({...r, ...results}), {}); + } + + static typeDigraph(type, marked = {}) { + const types = this.types(); + if (marked[type] || !types[type]) { + marked[type] = true; + return []; + } + const description = this.typeDescription(type, undefined); + const subtypes = Object.keys( + Object.values(description) + .reduce((r, spec) => ({...r, [spec.type]: true}), {}) + ); + subtypes.forEach((type) => marked[type] = true); + return arrayUnique( + flatten( + subtypes.map( + (type) => this.typeDigraph(type, marked), + ), + ).concat(subtypes), + ); } static typeDescription(type, variable) { - const types = invokeHookFlat('behaviorContextTypes') - .reduce((r, globals) => ({...r, ...globals}), {}); + const types = this.types(); if (!types[type]) { return {}; } @@ -37,9 +79,14 @@ export class Context { return types[type]; } + static types() { + return invokeHookFlat('behaviorContextTypes') + .reduce((r, results) => ({...r, ...results}), {}); + } + add(key, value, type) { this.typeMap.set(key, type); - this.variableMap.set(key, value, type); + this.variableMap.set(key, value); } addObjectMap(map) {