Skip to content

Commit 777a4aa

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(design-diff): bound parser retention and preserve historical capability resolution
1 parent a44d1a4 commit 777a4aa

5 files changed

Lines changed: 18 additions & 29 deletions

File tree

design-diff.config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
"export": "wireServerFallback",
9898
"environmentModule": "apps/sim/lib/core/config/env.ts",
9999
"environmentExport": "env",
100-
"implementationModule": "packages/deployment-config/src/env-capabilities.ts",
100+
"implementationModule": "apps/sim/lib/core/config/env-capabilities.ts",
101101
"implementationExport": "wireFallback"
102102
}
103103
]

scripts/design-diff/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ JSON inputs are compared semantically, retaining array order and attributing cha
180180
the spec and configured renderer. Malformed/missing configured inputs flag with a limitation.
181181

182182
The graph reuses up to 10,000 import/export snapshots keyed by source blob, resolving their
183-
paths again for each revision. The resolver retains at most 128 parsed modules per revision,
183+
paths again for each revision. The resolver retains at most 32 parsed modules per revision,
184184
and requests Bun garbage collection between parser batches. These resource controls do
185185
not change evidence or decisions. The Node-based test runner uses its own garbage collector.
186186

scripts/design-diff/refactors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ export function normalizeLiteralAliases(ast: t.File, visit: typeof traverse): vo
133133
visit(ast, {
134134
Expression(path) {
135135
if (path.parentPath.isExportSpecifier()) return
136+
if (path.findParent((parent) => parent.isTSType())) return
136137
if (!(path.isReferencedIdentifier() || path.isObjectExpression() || path.isArrayExpression()))
137138
return
138139
const value = literal(path)

scripts/design-diff/resolve.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ interface Module {
3232
/** A bounded interpreter for data expressions. It never invokes a source function. */
3333
export class Resolver {
3434
private readonly modules = new Map<string, Module>()
35-
private readonly values = new WeakMap<t.Node, Map<string, Evidence & { cost: number }>>()
3635
private readonly evaluations = new WeakMap<t.Node, Evidence>()
3736
private readonly unknowns = new WeakMap<t.Node, Map<string, Evidence>>()
3837
private readonly opaqueValues = new Map<string, Evidence>()
@@ -77,7 +76,7 @@ export class Resolver {
7776
},
7877
})
7978
const result = { ast, exports, stars }
80-
if (this.modules.size >= 128) this.modules.delete(this.modules.keys().next().value!)
79+
if (this.modules.size >= 32) this.modules.delete(this.modules.keys().next().value!)
8180
this.modules.set(file, result)
8281
return result
8382
}
@@ -729,15 +728,6 @@ export class Resolver {
729728

730729
private value(path: NodePath, file: string, depth: number): Data {
731730
if (!path?.node) return null
732-
const started = this.steps
733-
const cacheKey = `${depth}:${this.tree.config.limits.resolutionSteps - started}`
734-
const cached = this.values.get(path.node)?.get(cacheKey)
735-
if (cached && !this.active.has(path.node)) {
736-
this.steps += cached.cost
737-
for (const file of cached.dependencies) this.dependencies.add(file)
738-
for (const reason of cached.unresolved) this.unresolved.add(reason)
739-
return cached.value
740-
}
741731
if (
742732
++this.steps > this.tree.config.limits.resolutionSteps ||
743733
depth > this.tree.config.limits.resolutionDepth
@@ -752,21 +742,7 @@ export class Resolver {
752742
this.dependencies = new Set([file])
753743
this.unresolved = new Set()
754744
try {
755-
const value = this.inner(path, file, depth)
756-
if (![...this.unresolved].some((reason) => /cycle/i.test(reason))) {
757-
const entries = this.values.get(path.node) ?? new Map()
758-
// Bound per-node cache variants; budget/depth are part of the key so warming
759-
// a cache cannot change evidence in a later evaluation.
760-
if (entries.size < 8)
761-
entries.set(cacheKey, {
762-
value,
763-
cost: this.steps - started,
764-
dependencies: [...this.dependencies],
765-
unresolved: [...this.unresolved],
766-
})
767-
this.values.set(path.node, entries)
768-
}
769-
return value
745+
return this.inner(path, file, depth)
770746
} finally {
771747
for (const file of this.dependencies) dependencies.add(file)
772748
for (const reason of this.unresolved) unresolved.add(reason)

scripts/design-diff/tests/precision.test.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ it('projects configured capability environment fields and retains helper changes
237237
...settings,
238238
aliases: [
239239
...settings.aliases,
240-
{ from: 'apps/sim/', prefix: '@capability/', target: 'packages/deployment-config/src/' },
240+
{ from: 'apps/sim/', prefix: '@capability/', target: 'apps/sim/lib/core/config/' },
241241
],
242242
}
243243
const environment = (batch: number, email: boolean) =>
@@ -272,3 +272,15 @@ it('projects configured capability environment fields and retains helper changes
272272
).flagged
273273
).toBe(true)
274274
})
275+
276+
it('leaves type queries over literal constants erased and parseable', async () => {
277+
const source = (kind: string) =>
278+
`const KINDS=['one','two'] as const;type Kind = typeof KINDS[number];export const Page=()=> <span>${kind}</span>`
279+
const report = await compareFiles({ [view]: source('a') }, { [view]: source('b') }, settings)
280+
expect(report.flagged).toBe(true)
281+
expect(
282+
report.findings
283+
.flatMap((finding) => finding.limitations)
284+
.some((reason) => /parser|extraction failed/i.test(reason))
285+
).toBe(false)
286+
})

0 commit comments

Comments
 (0)