Skip to content
Draft
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
2 changes: 1 addition & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
@openforis:registry=https://npm.pkg.github.com
always-auth = true
# always-auth = true
4 changes: 3 additions & 1 deletion src/job/JobBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ export abstract class JobBase<C extends JobContext, R = undefined> extends Event
}

this.emitSummaryUpdateEvent = throttle(() => this.emit(JobMessageOutType.summaryUpdate, this.summary), 500)
this.jobs.forEach((job) => job.on(JobMessageOutType.summaryUpdate, this.onInnerJobSummaryUpdate.bind(this)))
for (const job of jobs) {
job.on(JobMessageOutType.summaryUpdate, this.onInnerJobSummaryUpdate.bind(this))
}
}

async cancel(): Promise<void> {
Expand Down
27 changes: 18 additions & 9 deletions src/node/factory.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
import { Factory } from '../common'
import { Dates, UUIDs } from '../utils'
import { Record } from '../record'
import { Dates } from '../utils'
import { Node } from './node'

export type NodeFactoryParams = {
record: Record
nodeDefUuid: string
recordUuid: string
parentNode?: Node
surveyUuid?: string
value?: any
}

export const NodeFactory: Factory<Node, NodeFactoryParams> = {
createInstance: (params: NodeFactoryParams): Node => {
const { nodeDefUuid, recordUuid, parentNode, surveyUuid, value } = params
const { nodeDefUuid, record, parentNode, surveyUuid, value } = params

const iId = (record.lastInternalId ?? 0) + 1

const now = Dates.nowFormattedForStorage()

const { iId: pId, meta: pMeta } = parentNode ?? {}

const h = [...(pMeta?.h ?? [])]
if (pId) {
h.push(pId)
}

return {
created: true,
dateCreated: now,
dateModified: now,
meta: {
h: [...(parentNode?.meta?.h ?? []), ...(parentNode?.uuid ? [parentNode?.uuid] : [])],
},
iId,
meta: { h },
nodeDefUuid,
parentUuid: parentNode?.uuid,
recordUuid,
pIId: parentNode?.iId,
recordUuid: record.uuid,
surveyUuid,
value,
uuid: UUIDs.v4(),
}
},
}
Expand Down
31 changes: 19 additions & 12 deletions src/node/node.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { RecordFactory } from '../record'
import { NodeFactory, NodeFactoryParams, NodePlaceholderFactory } from './factory'
import { Node } from './node'
import { createTestAdminUser } from '../tests/data'

const user = createTestAdminUser()

const checkNode = (node: Node, nodeParams: NodeFactoryParams) => {
expect(node).toHaveProperty('uuid')
expect(node).toHaveProperty('iId')
expect(node).toHaveProperty('nodeDefUuid')
expect(node.nodeDefUuid).toBe(nodeParams.nodeDefUuid)
expect(node).toHaveProperty('recordUuid')
expect(node.recordUuid).toBe(nodeParams.recordUuid)
expect(node).toHaveProperty('parentUuid')
expect(node.parentUuid).toBe(nodeParams.parentNode?.uuid)
expect(node.recordUuid).toBe(nodeParams.record.uuid)
expect(node).toHaveProperty('pIId')
expect(node.pIId).toBe(nodeParams.parentNode?.iId)

expect(node).toHaveProperty('value')
expect(node.value).toBe(nodeParams.value)
Expand All @@ -21,7 +25,7 @@ const checkNode = (node: Node, nodeParams: NodeFactoryParams) => {

const expectedHierarchy = [
...(nodeParams.parentNode?.meta?.h ?? []),
...(nodeParams.parentNode?.uuid ? [nodeParams.parentNode?.uuid] : []),
...(nodeParams.parentNode?.iId ? [nodeParams.parentNode.iId] : []),
]
const nodeHierarchy = [...(node.meta?.h ?? [])]
expect(nodeHierarchy.length).toBe(expectedHierarchy.length)
Expand All @@ -30,15 +34,16 @@ const checkNode = (node: Node, nodeParams: NodeFactoryParams) => {

describe('NodeFactory', () => {
test('createInstence - node', () => {
const record = RecordFactory.createInstance({ surveyUuid: 'survey-uuid', user })
const nodeParams: NodeFactoryParams = {
nodeDefUuid: 'nodedef-uuid-0001-test',
recordUuid: 'record-uuid-0001-test',
record,
parentNode: {
uuid: 'parent-node-uuid',
iId: 2,
nodeDefUuid: 'nodeDefUuid',
recordUuid: 'nodeDefUuid',
meta: {
h: ['uuid-prev'],
h: [1],
},
},
value: 'VALUE',
Expand All @@ -49,9 +54,10 @@ describe('NodeFactory', () => {
})

test('createInstence - parent node', () => {
const record = RecordFactory.createInstance({ surveyUuid: 'survey-uuid', user })
const nodeParams: NodeFactoryParams = {
nodeDefUuid: 'nodedef-uuid-0001-test',
recordUuid: 'record-uuid-0001-test',
record,
value: 'VALUE',
}

Expand All @@ -60,15 +66,16 @@ describe('NodeFactory', () => {
})

test('createInstence - placeholder', () => {
const record = RecordFactory.createInstance({ surveyUuid: 'survey-uuid', user })
const nodeParams: NodeFactoryParams = {
nodeDefUuid: 'nodedef-uuid-0001-test',
recordUuid: 'record-uuid-0001-test',
record,
parentNode: {
uuid: 'parent-node-uuid',
iId: 3,
nodeDefUuid: 'nodeDefUuid',
recordUuid: 'nodeDefUuid',
meta: {
h: ['uuid-prev'],
h: [2],
},
},
value: 'VALUE',
Expand Down
25 changes: 17 additions & 8 deletions src/node/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ export enum NodeMetaKeys {
}

export interface NodeMeta {
childApplicability?: { [uuid: string]: boolean }
childrenMaxCount?: { [uuid: string]: number }
childrenMinCount?: { [uuid: string]: number }
h?: string[]
hCode?: string[]
childApplicability?: { [nodeDefUuid: string]: boolean }
childrenMaxCount?: { [nodeDefUuid: string]: number }
childrenMinCount?: { [nodeDefUuid: string]: number }
h?: number[]
hCode?: number[]
defaultValueApplied?: boolean
}

Expand All @@ -27,13 +27,22 @@ export interface NodeRefData {
export interface Node {
dateCreated?: string
dateModified?: string
/**
* ID used when node is stored (unique relatively to the entire survey; e.g. DB table PK).
*/
id?: number
/**
* Internal ID (unique relatively to the record).
*/
iId: number
meta?: NodeMeta
nodeDefUuid: string
parentUuid?: string
/**
* Parent node internal ID.
*/
pIId?: number
recordUuid: string
refData?: NodeRefData
uuid: string
value?: any
placeholder?: boolean
surveyUuid?: string
Expand All @@ -54,5 +63,5 @@ export interface Node {
}

export interface NodesMap {
[key: string]: Node
[internalId: number]: Node
}
8 changes: 4 additions & 4 deletions src/node/nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { NodeDef, NodeDefCountType, NodeDefs } from '../nodeDef'
import { Dates, Objects } from '../utils'
import { Node } from './node'

const isRoot = (node: Node): boolean => !node.parentUuid
const isRoot = (node: Node): boolean => !node.pIId

const areEqual = (nodeA: Node, nodeB: Node): boolean => nodeA.uuid === nodeB.uuid
const areEqual = (nodeA: Node, nodeB: Node): boolean => nodeA.iId === nodeB.iId

const isChildApplicable = (node: Node, nodeDefUuid: string): boolean => {
// if child applicability is not defined for a node definition, consider it applicable
Expand Down Expand Up @@ -34,9 +34,9 @@ const getChildrenMaxCount = (params: { parentNode: Node; nodeDef: NodeDef<any> }
const getChildrenMinCount = (params: { parentNode: Node; nodeDef: NodeDef<any> }): number =>
getChildrenMinOrMaxCount({ ...params, countType: NodeDefCountType.min })

const getHierarchy = (node: Node): string[] => [...(node.meta?.h ?? [])]
const getHierarchy = (node: Node): number[] => [...(node.meta?.h ?? [])]

const getHierarchyCode = (node: Node): string[] => [...(node.meta?.hCode ?? [])]
const getHierarchyCode = (node: Node): number[] => [...(node.meta?.hCode ?? [])]

const mergeNodes = (target: Node, ...sources: Node[] | object[]): Node =>
Objects.deepMerge(target, ...sources) as unknown as Node
Expand Down
4 changes: 2 additions & 2 deletions src/node/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ export interface NodeService extends ArenaService {
create(options: { filePath?: string; node: Node; socketId: string; surveyId: number; user: User }): Promise<Node>

// ==== READ
get(options: { surveyId: number; nodeUuid: string }): Promise<Node>
get(options: { surveyId: number; nodeInternalId: number }): Promise<Node>

// ==== UPDATE
update(options: { filePath?: string; node: Node; socketId: string; surveyId: number; user: User }): Promise<Node>

// ==== DELETE
delete(options: {
nodeUuid: string
nodeInternalId: number
recordUuid: string
socketId: string
surveyId: number
Expand Down
5 changes: 3 additions & 2 deletions src/nodeDefExpressionEvaluator/node/identifier.ts
Original file line number Diff line number Diff line change
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
Loading