UNPKG

vite-plugin-top-level-await

Version:

Transform code to support top-level await in normal browsers for Vite.

75 lines (74 loc) 2.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodePattern = void 0; exports.findHighestPattern = findHighestPattern; const Visitor_1 = require("@swc/core/Visitor"); // Throw an exception when found top-level await to exit earlier from AST traversal class FoundTopLevelAwaitError extends Error { } class FindPatternsVisitor extends Visitor_1.Visitor { // Hook class/function visiting functions so we can know the current level constructor() { super(); // Set the flag when a dynamic import is found this.foundDynamicImport = false; // Tell if one await is in top-level or not this.currentLevel = 0; const visitor = this; function hook(methodName) { const originalFunction = visitor[methodName]; visitor[methodName] = function () { /* istanbul ignore next */ // A optimize: if we have already found dynamic imports, don't go deeper if (visitor.foundDynamicImport) return arguments[0]; visitor.currentLevel++; const result = originalFunction.apply(this, arguments); visitor.currentLevel--; return result; }; } hook("visitClass"); hook("visitArrowFunctionExpression"); hook("visitFunction"); hook("visitMethodProperty"); } visitAwaitExpression(expr) { if (this.currentLevel === 0) throw new FoundTopLevelAwaitError(); return super.visitAwaitExpression(expr); } visitForOfStatement(stmt) { if (stmt.await && this.currentLevel === 0) { throw new FoundTopLevelAwaitError(); } return super.visitForOfStatement(stmt); } visitCallExpression(expr) { if (expr.callee.type === "Import") this.foundDynamicImport = true; return super.visitCallExpression(expr); } } var CodePattern; (function (CodePattern) { CodePattern["TopLevelAwait"] = "TopLevelAwait"; CodePattern["DynamicImport"] = "DynamicImport"; })(CodePattern || (exports.CodePattern = CodePattern = {})); // Return the "highest" pattern found in the code // i.e. if we found top-level await, we don't care if there're any dynamic imports then function findHighestPattern(ast) { try { const visitor = new FindPatternsVisitor(); visitor.visitModule(ast); if (visitor.foundDynamicImport) return CodePattern.DynamicImport; } catch (e) { if (e instanceof FoundTopLevelAwaitError) return CodePattern.TopLevelAwait; /* istanbul ignore next */ throw e; } return null; }