rollup-plugin-concurrent-top-level-await 0.0.5 → 0.0.6
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/dist/index.d.mts +4 -5
- package/dist/index.mjs +78 -55
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import { FilterPattern } from "@rollup/pluginutils";
|
|
2
|
+
import * as magic_string0 from "magic-string";
|
|
2
3
|
import * as rollup0 from "rollup";
|
|
3
4
|
|
|
4
5
|
//#region src/index.d.ts
|
|
5
6
|
declare function concurrentTopLevelAwait(options?: {
|
|
6
7
|
include?: FilterPattern;
|
|
7
8
|
exclude?: FilterPattern;
|
|
9
|
+
sourceMap?: boolean;
|
|
8
10
|
}): {
|
|
9
11
|
name: string;
|
|
10
12
|
apply: "build";
|
|
11
13
|
transform: {
|
|
12
14
|
handler(this: rollup0.TransformPluginContext, code: string, id: string): Promise<{
|
|
13
15
|
code: string;
|
|
14
|
-
|
|
15
|
-
async: true;
|
|
16
|
-
};
|
|
16
|
+
map: magic_string0.SourceMap | null;
|
|
17
17
|
} | undefined>;
|
|
18
18
|
};
|
|
19
19
|
resolveImportMeta(this: rollup0.PluginContext, property: string | null, {
|
|
20
|
-
moduleId
|
|
21
|
-
chunkId
|
|
20
|
+
moduleId
|
|
22
21
|
}: {
|
|
23
22
|
chunkId: string;
|
|
24
23
|
format: rollup0.InternalModuleFormat;
|
package/dist/index.mjs
CHANGED
|
@@ -31,69 +31,92 @@ function withResolvers() {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
//#endregion
|
|
34
|
-
//#region src/
|
|
34
|
+
//#region src/AsyncModuleTracker.ts
|
|
35
35
|
var AwaitableCache = class {
|
|
36
36
|
#store = /* @__PURE__ */ new Map();
|
|
37
37
|
#getPromise(key) {
|
|
38
38
|
const entry = this.#store.get(key);
|
|
39
39
|
if (entry) return entry;
|
|
40
|
-
const { promise, resolve } = withResolvers();
|
|
41
|
-
this.#store.set(key, [
|
|
42
|
-
|
|
40
|
+
const { promise, resolve, reject } = withResolvers();
|
|
41
|
+
this.#store.set(key, [
|
|
42
|
+
promise,
|
|
43
|
+
resolve,
|
|
44
|
+
reject
|
|
45
|
+
]);
|
|
46
|
+
return [
|
|
47
|
+
promise,
|
|
48
|
+
resolve,
|
|
49
|
+
reject
|
|
50
|
+
];
|
|
43
51
|
}
|
|
44
|
-
|
|
52
|
+
resolve(key, value) {
|
|
45
53
|
const [_, resolve] = this.#getPromise(key);
|
|
46
54
|
resolve(value);
|
|
47
55
|
}
|
|
56
|
+
reject(key) {
|
|
57
|
+
const [_, __, reject] = this.#getPromise(key);
|
|
58
|
+
reject();
|
|
59
|
+
}
|
|
48
60
|
get(key) {
|
|
49
61
|
const [promise] = this.#getPromise(key);
|
|
50
62
|
return promise;
|
|
51
63
|
}
|
|
52
64
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
/**
|
|
66
|
+
* AsyncModuleTracker tracks whether modules must be treated as async due to
|
|
67
|
+
* containing top-level await or being an ancestor of an async module.
|
|
68
|
+
*/
|
|
69
|
+
var AsyncModuleTracker = class {
|
|
70
|
+
#entryCache = new AwaitableCache();
|
|
71
|
+
#subtreeCache = new AwaitableCache();
|
|
72
|
+
#resultCache = /* @__PURE__ */ new Map();
|
|
73
|
+
#seen = /* @__PURE__ */ new Set();
|
|
74
|
+
#resolved = /* @__PURE__ */ new Set();
|
|
75
|
+
#childrenSeen = /* @__PURE__ */ new Set();
|
|
76
|
+
#cycleResolver;
|
|
77
|
+
#resolveCycles;
|
|
78
|
+
constructor() {
|
|
79
|
+
this.#createCycleResolver();
|
|
60
80
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.#
|
|
64
|
-
this.#
|
|
65
|
-
this.#resultCache.set(key, true);
|
|
66
|
-
setTimeout(() => {
|
|
67
|
-
if (this.#unseen.size == 0) {
|
|
68
|
-
this.#unresolved.forEach((e) => this.#resultCache.set(e, false));
|
|
69
|
-
this.#all.forEach((e) => this.#resultCache.set(e, false));
|
|
70
|
-
this.#unresolved.clear();
|
|
71
|
-
}
|
|
72
|
-
}, 0);
|
|
81
|
+
#createCycleResolver() {
|
|
82
|
+
const { promise, resolve } = withResolvers();
|
|
83
|
+
this.#cycleResolver = promise;
|
|
84
|
+
this.#resolveCycles = () => resolve(false);
|
|
73
85
|
}
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
this.#
|
|
77
|
-
this.#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
children.forEach((children$1) => {
|
|
81
|
-
if (!this.#all.has(children$1)) {
|
|
82
|
-
this.#all.add(children$1);
|
|
83
|
-
this.#unresolved.add(key);
|
|
84
|
-
this.#unseen.add(children$1);
|
|
85
|
-
}
|
|
86
|
-
this.#resultCache.get(children$1).then((value) => {
|
|
87
|
-
if (value) this.setMarked(key, true);
|
|
86
|
+
#checkForCycles() {
|
|
87
|
+
if (this.#childrenSeen.size === this.#seen.size && this.#resolved.size === this.#seen.size) {
|
|
88
|
+
const resolveCycles = this.#resolveCycles;
|
|
89
|
+
this.#createCycleResolver();
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
resolveCycles();
|
|
88
92
|
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
#bindResultCache(key) {
|
|
96
|
+
if (!this.#resultCache.has(key)) this.#resultCache.set(key, this.#subtreeCache.get(key).then(() => false).catch(() => true));
|
|
97
|
+
}
|
|
98
|
+
isAsync(key) {
|
|
99
|
+
this.#bindResultCache(key);
|
|
100
|
+
return this.#resultCache.get(key);
|
|
101
|
+
}
|
|
102
|
+
setEntryAsync(key, value) {
|
|
103
|
+
this.#seen.add(key);
|
|
104
|
+
this.#resolved.add(key);
|
|
105
|
+
if (value) {
|
|
106
|
+
this.#entryCache.reject(key);
|
|
107
|
+
this.#entryCache.get(key).catch(() => {});
|
|
108
|
+
} else this.#entryCache.resolve(key, void 0);
|
|
109
|
+
this.#checkForCycles();
|
|
110
|
+
}
|
|
111
|
+
setDependencies(key, children) {
|
|
112
|
+
this.#seen.add(key);
|
|
113
|
+
this.#childrenSeen.add(key);
|
|
114
|
+
children.forEach((child) => {
|
|
115
|
+
this.#seen.add(child);
|
|
89
116
|
});
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this.#all.forEach((e) => this.#resultCache.set(e, false));
|
|
94
|
-
this.#unresolved.clear();
|
|
95
|
-
}
|
|
96
|
-
}, 0);
|
|
117
|
+
Promise.race([this.#cycleResolver, Promise.all([this.#entryCache.get(key), ...children.map((child) => this.#subtreeCache.get(child))])]).then(() => this.#subtreeCache.resolve(key, void 0)).catch(() => this.#subtreeCache.reject(key));
|
|
118
|
+
this.#bindResultCache(key);
|
|
119
|
+
this.#checkForCycles();
|
|
97
120
|
}
|
|
98
121
|
};
|
|
99
122
|
|
|
@@ -153,7 +176,7 @@ function isDeclaration(type) {
|
|
|
153
176
|
function moveVarDeclarationToModuleScope(s, node, declarationsEnd) {
|
|
154
177
|
const kind = replaceConstWithLet(node.kind);
|
|
155
178
|
const names = node.declarations.flatMap((decl) => getNames(decl.id)).join(", ");
|
|
156
|
-
s = s.appendRight(node.declarations[0].start, "(");
|
|
179
|
+
s = s.appendRight(node.declarations[0].start, ";(");
|
|
157
180
|
s = s.appendLeft(node.declarations[node.declarations.length - 1].end, ")");
|
|
158
181
|
s = s.appendLeft(declarationsEnd, `\n${kind} ${names};\n`);
|
|
159
182
|
s = s.remove(node.start, node.declarations[0].start);
|
|
@@ -183,41 +206,41 @@ function getNames(pattern) {
|
|
|
183
206
|
//#region src/index.ts
|
|
184
207
|
function concurrentTopLevelAwait(options = {}) {
|
|
185
208
|
const filter = createFilter(options.include, options.exclude);
|
|
186
|
-
const
|
|
209
|
+
const asyncTracker = new AsyncModuleTracker();
|
|
187
210
|
return {
|
|
188
211
|
name: "rollup-plugin-concurrent-tla-plugin",
|
|
189
212
|
apply: "build",
|
|
190
213
|
transform: { async handler(code, id) {
|
|
191
214
|
if (!filter(id)) return;
|
|
192
|
-
const ast = this.parse(code
|
|
215
|
+
const ast = this.parse(code);
|
|
193
216
|
const importDeclarations = ast.body.filter((a) => a.type === "ImportDeclaration");
|
|
194
217
|
const hasAwait = hasTopLevelAwait(ast);
|
|
195
|
-
|
|
218
|
+
asyncTracker.setEntryAsync(id, hasAwait);
|
|
219
|
+
if (hasAwait) asyncTracker.setDependencies(id, []);
|
|
196
220
|
else {
|
|
197
221
|
const childrenIds = (await Promise.all(importDeclarations.map(async (declaration) => {
|
|
198
222
|
const importId = await this.resolve(declaration.source.value, id);
|
|
199
223
|
if (!importId || !filter(importId.id)) return null;
|
|
200
224
|
return importId.id;
|
|
201
225
|
}))).filter((a) => a != null);
|
|
202
|
-
|
|
226
|
+
asyncTracker.setDependencies(id, childrenIds);
|
|
203
227
|
}
|
|
204
228
|
const asyncImports = (await Promise.all(importDeclarations.map(async (declaration) => {
|
|
205
229
|
const importId = await this.resolve(declaration.source.value, id);
|
|
206
230
|
if (!importId || !filter(importId.id)) return null;
|
|
207
231
|
this.load(importId);
|
|
208
|
-
if (!await
|
|
232
|
+
if (!await asyncTracker.isAsync(importId.id)) return null;
|
|
209
233
|
return declaration;
|
|
210
234
|
}))).filter(Boolean);
|
|
211
|
-
|
|
212
|
-
if (!isAsyncModule) return;
|
|
235
|
+
if (!(asyncImports.length > 0 || hasAwait)) return;
|
|
213
236
|
let s = new MagicString(code);
|
|
214
237
|
s = transform(s, ast, asyncImports, hasAwait);
|
|
215
238
|
return {
|
|
216
239
|
code: s.toString(),
|
|
217
|
-
|
|
240
|
+
map: options.sourceMap !== false ? s.generateMap({ hires: true }) : null
|
|
218
241
|
};
|
|
219
242
|
} },
|
|
220
|
-
resolveImportMeta(property, { moduleId
|
|
243
|
+
resolveImportMeta(property, { moduleId }) {
|
|
221
244
|
if (property !== "useTla") return;
|
|
222
245
|
const moduleInfo = this.getModuleInfo(moduleId);
|
|
223
246
|
const importers = moduleInfo?.importers;
|
package/package.json
CHANGED