Skip to content

Commit 9d6582f

Browse files
committed
feat: enhance SourceTransformTracker with deduplication logic and improve ModuleTSX for circular import handling
1 parent e80f3a7 commit 9d6582f

3 files changed

Lines changed: 14 additions & 2 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"typescript": "^5.9.3"
1616
},
1717
"devDependencies": {
18-
"tsdown": "^0.21.5"
18+
"tsdown": "^0.20.3"
1919
},
2020
"author": "YieldRay",
2121
"license": "MIT",

src/module-tsx.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@ export class ModuleTSX extends EventTarget implements IModuleTSX {
204204
// so we just return the original full URL
205205
return targetUrl.href;
206206
} else {
207+
// If this URL is already being transformed (circular import), return the raw URL.
208+
// The browser handles circular ESM natively; we just need to avoid deadlocking.
209+
if (this.sourceTracker.isInFlight("esm", targetUrl.href)) {
210+
return targetUrl.href;
211+
}
207212
const blobUrl = await this.transformSourceModule("esm", targetUrl.href, await this.fetchText(targetUrl.href));
208213
//! ^ transformSourceModule is recursive ^
209214
return blobUrl;

src/source-tracker.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,15 @@ export class SourceTransformTracker<TSourceType extends string> {
1212
this.blobMap.set(blobUrl, sourceUrl);
1313
}
1414

15+
public isInFlight(sourceType: TSourceType, sourceUrl: string): boolean {
16+
return this.inFlightSourceMap.has(this.getSourceKey(sourceType, sourceUrl));
17+
}
18+
1519
public getSourceUrlByBlob(blobUrl: string): string | undefined {
1620
return this.blobMap.get(blobUrl);
1721
}
1822

23+
/** Deduplicates concurrent transforms for the same URL. */
1924
public runWithDedup(
2025
sourceType: TSourceType,
2126
sourceUrl: string,
@@ -30,9 +35,11 @@ export class SourceTransformTracker<TSourceType extends string> {
3035
const task = run();
3136
this.inFlightSourceMap.set(sourceKey, task);
3237

33-
return task.finally(() => {
38+
task.finally(() => {
3439
this.inFlightSourceMap.delete(sourceKey);
3540
});
41+
42+
return task;
3643
}
3744

3845
private getSourceKey(sourceType: TSourceType, sourceUrl: string): string {

0 commit comments

Comments
 (0)