MCPcopy Index your code
hub / github.com/simstudioai/sim / deriveExecClearsForDataPatch

Function deriveExecClearsForDataPatch

apps/sim/lib/table/rows/executions.ts:126–193  ·  view source on GitHub ↗
(
  dataPatch: RowData,
  schema: TableSchema,
  existingExecutions: RowExecutions,
  callerPatch: Record<string, RowExecutionMetadata | null> | undefined,
  mergedData: RowData
)

Source from the content-addressed store, hash-verified

124 * this would silently miss the propagation.
125 */
126export function deriveExecClearsForDataPatch(
127 dataPatch: RowData,
128 schema: TableSchema,
129 existingExecutions: RowExecutions,
130 callerPatch: Record<string, RowExecutionMetadata | null> | undefined,
131 mergedData: RowData
132): {
133 executionsPatch: Record<string, RowExecutionMetadata | null> | undefined
134 inFlightDownstreamGroups: string[]
135} {
136 const dirtied = new Set(Object.keys(dataPatch))
137 const groupsToClear = new Set<string>()
138 const inFlightDownstreamGroups: string[] = []
139
140 // Own-output clears: when the user wipes a workflow output column, drop
141 // that group's exec entry so the auto-fire reactor re-arms the cell.
142 // Also flags the cleared output column as dirty so transitive downstream
143 // groups see it.
144 for (const [columnId, value] of Object.entries(dataPatch)) {
145 const cleared = value === null || value === undefined || value === ''
146 if (!cleared) continue
147 const col = schema.columns.find((c) => getColumnId(c) === columnId)
148 if (col?.workflowGroupId) groupsToClear.add(col.workflowGroupId)
149 }
150
151 // Left-to-right walk, propagating dirty columns forward.
152 const groups = schema.workflowGroups ?? []
153 const afterRow = { data: mergedData } as TableRow
154 for (const group of groups) {
155 const deps = group.dependencies?.columns ?? []
156 const depMatched = deps.some((d) => dirtied.has(d))
157 if (!depMatched) continue
158
159 // A dep column changed, but if the group's deps are no longer satisfied
160 // after the patch — a checkbox was unchecked or a text dep cleared — there's
161 // nothing to recompute. Leave the prior result alone instead of re-arming or
162 // cancelling it; only checking a box / filling a dep drives downstream work.
163 if (!areGroupDepsSatisfied(group, afterRow)) continue
164
165 const exec = existingExecutions[group.id]
166 if (exec) {
167 const status = exec.status
168 if (status === 'completed' || status === 'error' || status === 'cancelled') {
169 groupsToClear.add(group.id)
170 } else if (status === 'queued' || status === 'running' || status === 'pending') {
171 inFlightDownstreamGroups.push(group.id)
172 }
173 } else {
174 // No exec entry yet — `mode: 'new'` already covers this group. We
175 // still propagate the dirty signal forward so later groups in the
176 // chain see this group's outputs as dirty too.
177 groupsToClear.add(group.id)
178 }
179
180 // Propagate: this group is about to be re-computed, so groups whose
181 // deps reference its output columns are also dirty.
182 for (const out of group.outputs) dirtied.add(out.columnName)
183 }

Callers 2

updateRowFunction · 0.90
batchUpdateRowsFunction · 0.90

Calls 4

getColumnIdFunction · 0.90
areGroupDepsSatisfiedFunction · 0.90
addMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected