rolldown-plugin-concurrent-top-level-await 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,11 +44,11 @@ export default defineConfig({
44
44
 
45
45
  ## Options
46
46
 
47
- | Option | Type | Default | Description |
48
- | ------------------------- | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
49
- | `include` | `RegExp | RegExp[]` | `undefined` | A RegExp specifying which files to include. See [below](#which-modules-to-include) to determine which modules to include. |
50
- | `exclude` | `RegExp | RegExp[]` | `[/\/node_modules\//, /\.html$/]` | A RegExp specifying which files to exclude. Must still follow the [same considerations](#which-modules-to-include) as `include`. |
51
- | `generatedVariablePrefix` | `string` | `"__tla"` | Prefix used for internal variables generated by the plugin. Change this if it conflicts with variable names in your code. |
47
+ | Option | Type | Default | Description |
48
+ | ------------------------- | ------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
49
+ | `include` | <code>RegExp \| RegExp[]</code> | `undefined` | A RegExp specifying which files to include. See [below](#which-modules-to-include) to determine which modules to include. |
50
+ | `exclude` | <code>RegExp \| RegExp[]</code> | `[/\/node_modules\//, /\.html$/]` | A RegExp specifying which files to exclude. Must still follow the [same considerations](#which-modules-to-include) as `include`. |
51
+ | `generatedVariablePrefix` | `string` | `"__tla"` | Prefix used for internal variables generated by the plugin. Change this if it conflicts with variable names in your code. |
52
52
 
53
53
  ### Which modules to include?
54
54
 
package/dist/index.mjs CHANGED
@@ -66,12 +66,16 @@ function awaitEntrypointsPlugin(options) {
66
66
  if (id.startsWith(proxyPrefix)) {
67
67
  const resolved = awaitedEntriesMap.get(id.slice(proxyPrefix.length));
68
68
  if (!resolved) throw new Error("Name collision in concurrent-tla plugin, please change the generatedVariablePrefix option");
69
- if ((await this.load(resolved)).meta[generatedVariablePrefix + "_async"]) return `import { ${generatedVariablePrefix}_access } from "${resolved.id}";
69
+ const module = await this.load(resolved);
70
+ let code = "";
71
+ if (module.meta[generatedVariablePrefix + "_async"]) code += `import { ${generatedVariablePrefix}_access } from "${resolved.id}";
70
72
  await new Promise(${generatedVariablePrefix}_access);
71
- export * from "${resolved.id}";
72
73
  `;
73
- return `export * from "${resolved.id}";
74
+ if (module.exports.includes("default")) code += `import ${generatedVariablePrefix}_default from "${resolved.id}";
75
+ export default ${generatedVariablePrefix}_default;
74
76
  `;
77
+ code += `export * from "${resolved.id}";\n`;
78
+ return code;
75
79
  }
76
80
  }
77
81
  }
@@ -79,88 +83,17 @@ export * from "${resolved.id}";
79
83
  }
80
84
 
81
85
  //#endregion
82
- //#region src/registerModulePlugin.ts
83
- const tlaModule = `export default function register(fn, evaluate_accesses) {
84
- let state = "ready";
85
- let whenDones = [];
86
- let whenErrors = [];
87
- let remaining = 1;
88
- let error = undefined;
89
- // evaluate eagerly
90
- evaluate();
91
-
92
- return evaluate;
86
+ //#region ../shared/src/registerSource.ts
87
+ var registerSource_default = {
88
+ "code": "export default function register(fn, evaluate_accesses) {\n let state = \"ready\";\n let whenDones = [];\n let whenErrors = [];\n let remaining = 1;\n let error = undefined;\n // evaluate eagerly\n evaluate();\n return evaluate;\n function evaluate(whenDone, onError) {\n if (state === \"done\") {\n if (whenDone) whenDone();\n return;\n }\n if (state === \"failed\") {\n if (onError) onError(error);\n return;\n }\n if (whenDone) whenDones.push(whenDone);\n if (onError) whenErrors.push(onError);\n if (state === \"busy\") {\n return;\n }\n state = \"busy\";\n let moduleDone = () => {\n state = \"done\";\n for (let x of whenDones) x();\n };\n let moduleError = (err) => {\n state = \"failed\";\n error = err;\n for (let x of whenErrors) x(err);\n };\n let importDone = () => {\n if (state !== \"busy\") return;\n if (--remaining !== 0) return;\n try {\n let result = fn();\n if (result) {\n result.then(moduleDone).catch(moduleError);\n } else {\n moduleDone();\n }\n } catch (err) {\n moduleError(err);\n }\n };\n for (const access of evaluate_accesses) {\n let evaluate;\n try {\n // Environment-dependent behavior:\n // - throws on cyclic dependencies in V8\n // - returns undefined in some environments (e.g., vitest)\n evaluate = access();\n if (evaluate == null) continue;\n } catch {\n continue;\n }\n remaining++;\n evaluate(importDone, moduleError);\n }\n importDone();\n }\n}\n",
89
+ "helpersUsed": {},
90
+ "errors": [],
91
+ "warnings": [],
92
+ "tsconfigFilePaths": []
93
+ }.code;
93
94
 
94
- function evaluate(whenDone, onError) {
95
- if (state === "done") {
96
- if (whenDone)
97
- whenDone();
98
- return;
99
- }
100
- if (state === "failed") {
101
- if (onError)
102
- onError(error);
103
- return;
104
- }
105
- if (whenDone)
106
- whenDones.push(whenDone);
107
- if (onError)
108
- whenErrors.push(onError);
109
- if (state === "busy") {
110
- return;
111
- }
112
- state = "busy";
113
- let moduleDone = () => {
114
- state = "done";
115
- for (let x of whenDones)
116
- x();
117
- };
118
- let moduleError = (err) => {
119
- state = "failed";
120
- error = err;
121
- for (let x of whenErrors)
122
- x(err);
123
- };
124
- let importDone = () => {
125
- if (state !== "busy")
126
- return;
127
- if (--remaining !== 0)
128
- return;
129
- try {
130
- let result = fn();
131
- if (result) {
132
- result
133
- .then(moduleDone)
134
- .catch(moduleError);
135
- }
136
- else {
137
- moduleDone();
138
- }
139
- }
140
- catch (err) {
141
- moduleError(err);
142
- }
143
- };
144
- for (const access of evaluate_accesses) {
145
- let evaluate;
146
- try {
147
- // Environment-dependent behavior:
148
- // - throws on cyclic dependencies in V8
149
- // - returns undefined in some environments (e.g., vitest)
150
- evaluate = access();
151
- if (evaluate == null)
152
- continue;
153
- }
154
- catch (_a) {
155
- continue;
156
- }
157
- remaining++;
158
- evaluate(importDone, moduleError);
159
- }
160
- importDone();
161
- }
162
- }
163
- `;
95
+ //#endregion
96
+ //#region src/registerModulePlugin.ts
164
97
  function registerModulePlugin(options) {
165
98
  options.generatedVariablePrefix;
166
99
  const registerModuleSource = options.registerModuleSource;
@@ -171,7 +104,7 @@ function registerModulePlugin(options) {
171
104
  if (source === registerModuleSource) return registerModuleSource;
172
105
  },
173
106
  load(id) {
174
- if (id === registerModuleSource) return tlaModule;
107
+ if (id === registerModuleSource) return registerSource_default;
175
108
  }
176
109
  };
177
110
  }
@@ -308,18 +241,24 @@ function transform$1(s, ast, registerModuleSource, asyncImports, hasAwait, varia
308
241
  const declarationsEnd = transformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variablePrefix);
309
242
  s.appendRight(declarationsEnd, `${hasAwait ? "async " : ""}function ${variablePrefix}_initModuleExports() {\n`);
310
243
  s.append("\n}\n");
311
- s.prepend(`import ${variablePrefix}_register from ${JSON.stringify(registerModuleSource)};\n`);
244
+ s.append(`import ${variablePrefix}_register from ${JSON.stringify(registerModuleSource)};\n`);
312
245
  const asyncDeps = `[${asyncImports.map((_, i) => `() => ${variablePrefix}${i}`).join(", ")}]`;
313
246
  s.append(`export const ${variablePrefix}_access = ${variablePrefix}_register(${variablePrefix}_initModuleExports, ${asyncDeps});\n`);
314
247
  }
315
248
  function transformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variablePrefix) {
316
249
  let moduleScopeEnd = 0;
317
- let i = 0;
250
+ let importDeclarationIndex = 0;
251
+ let inDirectivePrologue = true;
318
252
  for (const node of ast.body) {
253
+ if (inDirectivePrologue && node.type === "ExpressionStatement" && node.expression.type === "Literal") {
254
+ moduleScopeEnd = node.end;
255
+ continue;
256
+ }
257
+ inDirectivePrologue = false;
319
258
  if (asyncImports.includes(node)) {
320
- const tlaImport = `\nimport { ${variablePrefix}_access as ${variablePrefix}${i}} from '${node.source.value}';`;
259
+ const tlaImport = `\nimport { ${variablePrefix}_access as ${variablePrefix}${importDeclarationIndex}} from '${node.source.value}';`;
321
260
  s.appendLeft(node.end, tlaImport);
322
- i++;
261
+ importDeclarationIndex++;
323
262
  }
324
263
  if (node.type === "ClassDeclaration") {
325
264
  s.appendLeft(moduleScopeEnd, `let ${node.id.name};\n`);
@@ -362,6 +301,7 @@ function isFunctionDeclaration(type) {
362
301
  return type === "FunctionDeclaration";
363
302
  }
364
303
  function getClassDeclarationStart(node) {
304
+ if (!("decorators" in node)) return node.start;
365
305
  return node.decorators[0]?.start ?? node.start;
366
306
  }
367
307
  function moveVariableDeclarationToModuleScope(s, node, declarationsEnd) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rolldown-plugin-concurrent-top-level-await",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Rolldown (and Vite) plugin enabling concurrent execution of modules that contain top level await.",
5
5
  "keywords": [
6
6
  "rolldown-plugin",
@@ -55,7 +55,8 @@
55
55
  "@oxc-project/types": "^0.122.0",
56
56
  "@types/estree": "^1.0.8",
57
57
  "prettier": "3.7.4",
58
- "rolldown": "1.0.0-rc.9"
58
+ "rolldown": "1.0.0-rc.9",
59
+ "unplugin-macros": "^0.19.1"
59
60
  },
60
61
  "scripts": {
61
62
  "build": "tsdown --dts"