From 6d8fe82b5386af536ca96eb1d89150e201c603e9 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Thu, 25 May 2023 13:23:04 -0300 Subject: content: sprawl & transformContent Sprawling basically means tying a component to objects which aren't directly passed to it. This is necessary for functions like transformContent, which was *mostly* implemented here (the multiline/lyrics modes are stubs, and a number of links haven't been implemented yet). --- src/content-function.js | 78 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 27 deletions(-) (limited to 'src/content-function.js') diff --git a/src/content-function.js b/src/content-function.js index bdf9cd29..921b5bcd 100644 --- a/src/content-function.js +++ b/src/content-function.js @@ -4,14 +4,16 @@ export default function contentFunction({ contentDependencies = [], extraDependencies = [], + sprawl, + relations, data, generate, - relations, }) { return expectDependencies({ + sprawl, + relations, data, generate, - relations, expectedContentDependencyKeys: contentDependencies, expectedExtraDependencyKeys: extraDependencies, @@ -22,9 +24,10 @@ export default function contentFunction({ contentFunction.identifyingSymbol = Symbol(`Is a content function?`); export function expectDependencies({ + sprawl, + relations, data, generate, - relations, expectedContentDependencyKeys, expectedExtraDependencyKeys, @@ -34,8 +37,13 @@ export function expectDependencies({ throw new Error(`Expected generate function`); } - const hasDataFunction = !!data; + const hasSprawlFunction = !!sprawl; const hasRelationsFunction = !!relations; + const hasDataFunction = !!data; + + if (hasSprawlFunction && !expectedExtraDependencyKeys.includes('wikiData')) { + throw new Error(`Content functions which sprawl must specify wikiData in extraDependencies`); + } const fulfilledDependencyKeys = Object.keys(fulfilledDependencies); @@ -98,27 +106,24 @@ export function expectDependencies({ wrappedGenerate[contentFunction.identifyingSymbol] = true; - if (hasDataFunction) { - if (empty(missingContentDependencyKeys)) { - wrappedGenerate.data = data; - } else { - wrappedGenerate.data = function() { - throw new Error(`Dependencies still needed: ${missingContentDependencyKeys.join(', ')}`); - }; - - annotateFunction(wrappedGenerate.data, {name: data, trait: 'unfulfilled'}); - } + if (hasSprawlFunction) { + wrappedGenerate.sprawl = sprawl; } if (hasRelationsFunction) { wrappedGenerate.relations = relations; } + if (hasDataFunction) { + wrappedGenerate.data = data; + } + wrappedGenerate.fulfill ??= function fulfill(dependencies) { return expectDependencies({ + sprawl, + relations, data, generate, - relations, expectedContentDependencyKeys, expectedExtraDependencyKeys, @@ -201,19 +206,25 @@ export function fulfillDependencies({ return newFulfilledDependencies; } -export function getRelationsTree(dependencies, contentFunctionName, ...args) { +export function getRelationsTree(dependencies, contentFunctionName, wikiData, ...args) { const relationIdentifier = Symbol('Relation'); function recursive(contentFunctionName, ...args) { const contentFunction = dependencies[contentFunctionName]; - if (!contentFunctionName) { + if (!contentFunction) { throw new Error(`Couldn't find dependency ${contentFunctionName}`); } - if (!contentFunction?.relations) { + if (!contentFunction.relations) { return null; } + // TODO: Evaluating a sprawl might belong somewhere better than here, lol... + const sprawl = + (contentFunction.sprawl + ? contentFunction.sprawl(wikiData, ...args) + : null) + const relationSlots = {}; const relationSymbolMessage = (() => { @@ -227,7 +238,10 @@ export function getRelationsTree(dependencies, contentFunctionName, ...args) { return {[relationIdentifier]: relationSymbol}; }; - const relationsLayout = contentFunction.relations(relationFunction, ...args); + const relationsLayout = + (sprawl + ? contentFunction.relations(relationFunction, sprawl, ...args) + : contentFunction.relations(relationFunction, ...args)) const relationsTree = Object.fromEntries( Object.getOwnPropertySymbols(relationSlots) @@ -354,7 +368,7 @@ export function quickEvaluate({ })); } - const treeInfo = getRelationsTree(allContentDependencies, name, ...args); + const treeInfo = getRelationsTree(allContentDependencies, name, allExtraDependencies.wikiData ?? {}, ...args); const flatTreeInfo = flattenRelationsTree(treeInfo); const {root, relationIdentifier, flatRelationSlots} = flatTreeInfo; @@ -421,15 +435,25 @@ export function quickEvaluate({ const slotResults = {}; - function runContentFunction({name, args, relations}) { + function runContentFunction({name, args, relations: flatRelations}) { const contentFunction = fulfilledContentDependencies[name]; - const filledRelations = - fillRelationsLayoutFromSlotResults(relationIdentifier, slotResults, relations); - const generateArgs = [ - contentFunction.data?.(...args), - filledRelations, - ].filter(Boolean); + if (!contentFunction) { + throw new Error(`Content function ${name} unfulfilled or not listed`); + } + + const sprawl = + contentFunction.sprawl?.(allExtraDependencies.wikiData, ...args); + + const relations = + fillRelationsLayoutFromSlotResults(relationIdentifier, slotResults, flatRelations); + + const data = + (sprawl + ? contentFunction.data?.(sprawl, ...args) + : contentFunction.data?.(...args)); + + const generateArgs = [data, relations].filter(Boolean); return contentFunction(...generateArgs); } -- cgit 1.3.0-6-gf8a5