Skip to content

Commit 611bb2e

Browse files
committed
fix(workflows): avoid repeated reference overlap scans
1 parent f2a6b36 commit 611bb2e

3 files changed

Lines changed: 33 additions & 1 deletion

File tree

‎apps/sim/lib/workflows/editing/code-syntax.test.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ describe('embedded Function syntax checks', () => {
7979
expect(report.issues[0].message).toContain('more than 10000 variable placeholders')
8080
})
8181

82+
it('checks reference-dense code within the supported body budget without repeated overlap scans', async () => {
83+
const code = `/*${'<a.b>'.repeat(200_000)}*/return 1`
84+
const started = performance.now()
85+
const report = await collectWorkflowCodeSyntax({ renderer: block(code) })
86+
87+
expect(report.issues).toEqual([])
88+
expect(report.check.detail).toContain('1 used placeholder values')
89+
expect(performance.now() - started).toBeLessThan(2_000)
90+
}, 60_000)
91+
8292
it('never evaluates side effects while checking code', async () => {
8393
const key = '__workflowLintExecuted'
8494
await collectWorkflowCodeSyntax({

‎packages/utils/src/workflow-references.test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ describe('workflow references', () => {
5252
])
5353
})
5454

55+
it.each([
56+
[
57+
'<before.x>{{<hidden.x><alsoHidden.y>}}<after.y>',
58+
['<before.x>', '{{<hidden.x><alsoHidden.y>}}', '<after.y>'],
59+
],
60+
['<before.x><{{ENV}}.value><after.y>', ['<before.x>', '{{ENV}}', '<after.y>']],
61+
['{{ONE}}{{TWO}}<after.y>', ['{{ONE}}', '{{TWO}}', '<after.y>']],
62+
['{{outer{{<hidden.x>}}}}<after.y>', ['{{<hidden.x>}}', '<after.y>']],
63+
['{{<first.x>\n<second.y>}}', ['<first.x>', '<second.y>']],
64+
['<broken\n{{ENV}}<= <after.y>', ['{{ENV}}', '<after.y>']],
65+
])('preserves environment overlap precedence and reference offsets in %s', (source, expected) => {
66+
const tokens = findWorkflowReferenceTokens(source)
67+
expect(tokens.map((token) => token.value)).toEqual(expected)
68+
for (const token of tokens) expect(source.slice(token.start, token.end)).toBe(token.value)
69+
})
70+
5571
it('scans long runs of opening brackets while preserving final reference offsets', () => {
5672
expect(findWorkflowReferenceTokens(`${'<'.repeat(10_000)}value>`)).toEqual([
5773
{

‎packages/utils/src/workflow-references.ts‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export function findWorkflowReferenceTokens(source: string): WorkflowReferenceTo
6666
tokens.push({ kind: 'environment', value: match[0], start, end: start + match[0].length })
6767
}
6868

69+
const environmentCount = tokens.length
70+
let environmentIndex = 0
6971
let candidateStart = -1
7072
for (let index = 0; index < source.length; index += 1) {
7173
const character = source[index]
@@ -84,7 +86,11 @@ export function findWorkflowReferenceTokens(source: string): WorkflowReferenceTo
8486
if (split && isLikelyWorkflowReferenceSegment(candidate)) {
8587
const start = candidateStart + split.leading.length
8688
const end = start + split.reference.length
87-
if (!tokens.some((token) => start < token.end && end > token.start)) {
89+
/** Both scans advance in source order; prior workflow candidates cannot overlap. */
90+
while (environmentIndex < environmentCount && tokens[environmentIndex].end <= start) {
91+
environmentIndex++
92+
}
93+
if (environmentIndex === environmentCount || end <= tokens[environmentIndex].start) {
8894
tokens.push({ kind: 'workflow', value: split.reference, start, end })
8995
}
9096
}

0 commit comments

Comments
 (0)