Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/nodeDefExpressionEvaluator/node/identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class NodeDefIdentifierEvaluator extends IdentifierEvaluator<NodeDefExpre
try {
const identifierAsGlobalObject = await super.evaluate(expressionNode)
return identifierAsGlobalObject
} catch (e) {
} catch {
// ignore it
}

Expand Down Expand Up @@ -131,8 +131,9 @@ export class NodeDefIdentifierEvaluator extends IdentifierEvaluator<NodeDefExpre
while (!queue.isEmpty()) {
const entityDefCurrent = queue.dequeue()
const entityDefCurrentChildren = getNodeDefChildren({ survey, nodeDef: entityDefCurrent, includeAnalysis })
entityDefCurrentChildren.forEach((childDef) => (reachableNodeDefsByUuid[childDef.uuid] = childDef))

for (const childDef of entityDefCurrentChildren) {
reachableNodeDefsByUuid[childDef.uuid] = childDef
}
// visit nodes inside single entities
queue.enqueueItems(entityDefCurrentChildren.filter(NodeDefs.isSingleEntity))

Expand Down
33 changes: 6 additions & 27 deletions src/record/recordExpressionEvaluator/node/identifier/identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,7 @@ const evaluateIdentifierOnNode = (params: {
return nodeObject
}
if (Surveys.isNodeDefAncestor({ nodeDefAncestor: nodeDefReferenced, nodeDefDescendant: nodeDefObject })) {
// if the rerenced node is an ancestor of the context node, return it following the hierarchy
try {
return Records.getAncestor({ record, node: nodeObject, ancestorDefUuid: nodeDefReferenced.uuid })
} catch (e) {
throw new SystemError('expression.ancestorNotFound', {
ancestorDefName: NodeDefs.getName(nodeDefReferenced),
descendantDefName: NodeDefs.getName(nodeDefObject),
})
}
return Records.getAncestor({ record, node: nodeObject, ancestorDefUuid: nodeDefReferenced.uuid })
}
// the referenced nodes can be siblings of the current node
const referencedNodes = NodesFinder.findDescendants({ survey, record, nodeContext: nodeObject, nodeDefReferenced })
Expand All @@ -110,12 +102,12 @@ export class RecordIdentifierEvaluator extends IdentifierEvaluator<RecordExpress
try {
const result = await super.evaluate(expressionNode)
return result
} catch (e) {
} catch {
// ignore it
}

// identifier not found among global or native properties
// idenfifier should be a node or a node value property
// identifier should be a node or a node value property
const { survey, record, evaluateToNode, object: contextObject, item } = this.context

if (item && item === contextObject) {
Expand All @@ -124,30 +116,17 @@ export class RecordIdentifierEvaluator extends IdentifierEvaluator<RecordExpress
}

if (Array.isArray(contextObject)) {
const result = contextObject.reduce((acc, contextNode) => {
return contextObject.flatMap((contextNode) => {
const evaluationResult = evaluateIdentifierOnNode({
survey,
record,
nodeObject: contextNode,
evaluateToNode,
propName,
})
if (Array.isArray(evaluationResult)) {
evaluationResult.forEach((item) => acc.push(item))
} else {
acc.push(evaluationResult)
}
return acc
}, [])
return result
} else {
return evaluateIdentifierOnNode({
survey,
record,
nodeObject: contextObject,
evaluateToNode,
propName,
return Array.isArray(evaluationResult) ? evaluationResult : [evaluationResult]
})
}
return evaluateIdentifierOnNode({ survey, record, nodeObject: contextObject, evaluateToNode, propName })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ const getCommonAncestor = (params: {
return Records.getRoot(record)
}
const nodeDefReferencedH = nodeDefReferenced.meta.h
const nodeDefCtxH = nodeDefCtx.meta.h
const nodeDefCommonH = Arrays.intersection(nodeDefReferencedH, nodeDefCtxH)
// meta.h contains only ancestors (excluding the node itself); include nodeDefCtx.uuid so that
// the context nodeDef can be treated as the common ancestor when nodeDefReferenced is a descendant of nodeDefCtx
const nodeDefCtxHierarchyToConsider = [...nodeDefCtx.meta.h, nodeDefCtx.uuid]
const nodeDefCommonH = Arrays.intersection(nodeDefReferencedH, nodeDefCtxHierarchyToConsider)
if (nodeDefCommonH.length === 1) {
return Records.getRoot(record)
}
Expand Down
8 changes: 4 additions & 4 deletions src/record/recordNodesUpdater/recordNodesUpdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ export const updateNodesDependents = async (
// include onUpdate dependents (always included in every record update)
const onUpdateDependentDefs = Surveys.getOnUpdateDependents({ survey })
if (onUpdateDependentDefs.length > 0) {
onUpdateDependentDefs.forEach((dependentDef) => {
for (const dependentDef of onUpdateDependentDefs) {
const dependentNodes = getNodesByDefUuid(dependentDef.uuid)(record)
dependentNodes.forEach((node) => {
for (const node of dependentNodes) {
initialNodesToVisit[node.uuid] = node
})
})
}
}
}

const updateResult = new RecordUpdateResult({ record, nodes: initialNodesToVisit })
Expand Down