From efe4971cccc3806a17429dd928fb20484048617a Mon Sep 17 00:00:00 2001 From: kitsunecafe Date: Sat, 23 Nov 2024 14:21:49 -0600 Subject: [PATCH] unterrible it --- src/fn.js | 2 +- src/query.js | 83 ++++++++++++++++++++++------------------------------ 2 files changed, 36 insertions(+), 49 deletions(-) diff --git a/src/fn.js b/src/fn.js index b561082..ebaa050 100644 --- a/src/fn.js +++ b/src/fn.js @@ -130,7 +130,7 @@ export const fromEntries = Object.fromEntries // lenses export const lens = curry((get, set) => ({ get, set })) -export const lensPath = path => lens(path(path), assocPath(path)) +export const lensPath = value => lens(path(value), assocPath(value)) export const lensIndex = index => lens(nth(index), update(index)) export const view = curry(({ get }, obj) => get(obj)) export const set = curry((l, value, obj) => over(l, always(value), obj)) diff --git a/src/query.js b/src/query.js index 81876d8..7387f9f 100644 --- a/src/query.js +++ b/src/query.js @@ -33,20 +33,12 @@ const matches = (world, type, query, set = new Set()) => entity => { } } -const propFrom = flip(prop) -const getNode = when(prop('relationship'), prop('from')) -const queryLens = lens(prop('query'), assoc('results')) -const getQueryResults = curry((world, node) => over(queryLens, applyTo(world), node)) - const queryRelationship = (query, world) => { - const [from, edge, to] = map( - pipe( - propFrom(query), - getNode, - getQueryResults(world) - ), - ['from', 'edge', 'to'] - ) + const [from, edge, to] = ['from', 'edge', 'to'].map(name => { + let node = query[name] + node = node.relationship ? node.from : node + return { ...node, results: node.query(world) } + }) const matchesFrom = matches(world, from.type, from.results) const matchesTo = matches(world, to.type, to.results) @@ -65,7 +57,7 @@ const queryRelationship = (query, world) => { return result } -const assembleQuery = curry((query, entities) => map(entity => of({ entity, query }), entities)) +const assembleQuery = (query, entities) => entities.map(entity => ([{ entity, query }])) const executeQuery = curry((query, world) => { if (!query.relationship) { @@ -75,27 +67,23 @@ const executeQuery = curry((query, world) => { const edges = queryRelationship(query, world) if (query.to.relationship) { - return reduce((acc, eid) => { + return edges.reduce((acc, eid) => { const next = assocPath( 'from.query', always(of(query.edge.type.to[eid])), query.to ) - return pipe( - executeQuery(next), - map(prepend(eid)), - map(([l, r]) => ([{ entity: l, query }, r])), - concat(acc) - )(world) - }, [], edges) + return executeQuery(next, world) + .map(child => [eid, ...child]) + .map(([l, r]) => [{ entity: l, query }, r]) + .concat(acc) + }, []) } else { return assembleQuery(query, edges) } }) -const returnValues = pipe(path('query.schema.returnValues.values'), map(prop('value'))) -const nodeName = path('query.schema.match.name.value.value') const includes = curry((val, arr) => !isNil(val) && arr.includes(val)) const maybeAssoc = curry((pred, key, value, obj) => @@ -103,8 +91,8 @@ const maybeAssoc = curry((pred, key, value, obj) => ) const resolveNode = curry((node, obj) => { - const name = nodeName(node) - const returns = returnValues(node) + const name = path('query.schema.match.name.value.value', node) + const returns = path('query.schema.returnValues.values', node).map(r => r.value) return maybeAssoc(always(includes(name, returns)), name, node.entity, obj) }) @@ -119,27 +107,26 @@ const resolveRelationship = edges => { )({}) } -const resolveReturns = map( - pipe( - map(ifElse( - path('query.relationship'), - resolveRelationship, - flip(resolveNode)({}) - )), - reduce(mergeLeft, {}) - ) -) +const resolveReturns = query => { + return query.map(edges => { + const returns = edges.map(edge => { + if (edge.query.relationship) { + return resolveRelationship(edge) + } else { + return resolveNode(edge, {}) + } + }) -export const query = curry((input, { world, component }) => - map(({ use, ...rest }) => - pipe( - prop('value'), - orDefault('default'), - flip(prop)(world), - executeQuery(prepareQuery(rest, component)), - resolveReturns - )(use), - parseAll(q, input) - ) -) + return Object.assign({}, ...returns) + }) +} + +export const query = curry((input, { world, component }) => { + return parseAll(q, input).map(({ use, ...rest }) => { + const useWorld = world[use?.value ?? 'default'] + const preparedQuery = prepareQuery(rest, component) + const results = executeQuery(preparedQuery, useWorld) + return resolveReturns(results) + }) +})