@statewalker/cellb 0.8.0 → 0.8.1
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/project/browser-modules.js +14 -4
- package/dist/project/browser-modules.js.map +1 -1
- package/dist/project/lower-await.js +22 -2
- package/dist/project/lower-await.js.map +1 -1
- package/dist/project/module-specifiers.d.ts +14 -0
- package/dist/project/module-specifiers.js +302 -0
- package/dist/project/module-specifiers.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { moduleText, outboundFetch, } from "../bindings/worker-loader.js";
|
|
2
2
|
import { ctxExports } from "../core/handles.js";
|
|
3
|
+
import { rewriteModuleSpecifiers } from "./module-specifiers.js";
|
|
3
4
|
import { workerScope } from "./worker-scope.js";
|
|
4
5
|
const WORKERS_CLASSES = "const m = globalThis.__cellsWorkersModule; export const DurableObject = m.DurableObject, WorkerEntrypoint = m.WorkerEntrypoint, WorkflowEntrypoint = m.WorkflowEntrypoint, RpcTarget = m.RpcTarget; export default m;";
|
|
5
6
|
/**
|
|
@@ -59,6 +60,9 @@ export function browserModuleLoader(workersModuleShim) {
|
|
|
59
60
|
consolePrelude += `const fetch = globalThis.__cellsOutbound[${JSON.stringify(key)}];\n`;
|
|
60
61
|
}
|
|
61
62
|
const urls = new Map();
|
|
63
|
+
// Modules whose Blob URL is being made: a Blob URL exists only once its text (with its
|
|
64
|
+
// imports' URLs) does, so modules that import each other cannot be loaded this way.
|
|
65
|
+
const making = [];
|
|
62
66
|
const source = (name) => {
|
|
63
67
|
const m = code.modules[name];
|
|
64
68
|
if (m === undefined)
|
|
@@ -69,16 +73,22 @@ export function browserModuleLoader(workersModuleShim) {
|
|
|
69
73
|
const known = urls.get(name);
|
|
70
74
|
if (known)
|
|
71
75
|
return known;
|
|
76
|
+
if (making.includes(name))
|
|
77
|
+
throw new Error(`Worker Loader: modules import each other (${[...making.slice(making.indexOf(name)), name].join(" → ")}); a browser realm loads each module from a Blob URL, which cannot form a cycle`);
|
|
78
|
+
making.push(name);
|
|
72
79
|
const base = name.includes("/") ? name.slice(0, name.lastIndexOf("/") + 1) : "";
|
|
73
|
-
|
|
80
|
+
// Only the module's own imports: the same words in a string, a template or a comment are
|
|
81
|
+
// not imports (a code generator's template may well contain `from "cloudflare:workers"`).
|
|
82
|
+
const text = rewriteModuleSpecifiers(source(name), (spec) => {
|
|
74
83
|
if (spec === "cloudflare:workers")
|
|
75
|
-
return
|
|
84
|
+
return shimUrl;
|
|
76
85
|
if (spec.startsWith("./") || spec.startsWith("../"))
|
|
77
|
-
return
|
|
78
|
-
return
|
|
86
|
+
return urlOf(new URL(spec, `file:///${base}`).pathname.slice(1));
|
|
87
|
+
return undefined;
|
|
79
88
|
});
|
|
80
89
|
const url = URL.createObjectURL(new Blob([consolePrelude + text], { type: "text/javascript" }));
|
|
81
90
|
urls.set(name, url);
|
|
91
|
+
making.pop();
|
|
82
92
|
return url;
|
|
83
93
|
};
|
|
84
94
|
const module = (await import(/* @vite-ignore */ urlOf(code.mainModule)));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-modules.js","sourceRoot":"","sources":["../../src/project/browser-modules.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"browser-modules.js","sourceRoot":"","sources":["../../src/project/browser-modules.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type LogSink,\n type ModuleLoader,\n moduleText,\n outboundFetch,\n type WorkerCode,\n} from \"../bindings/worker-loader.js\";\nimport { ctxExports } from \"../core/handles.js\";\nimport { rewriteModuleSpecifiers } from \"./module-specifiers.js\";\nimport { workerScope } from \"./worker-scope.js\";\n\nconst WORKERS_CLASSES =\n \"const m = globalThis.__cellsWorkersModule; export const DurableObject = m.DurableObject, WorkerEntrypoint = m.WorkerEntrypoint, WorkflowEntrypoint = m.WorkflowEntrypoint, RpcTarget = m.RpcTarget; export default m;\";\n\n/**\n * `cloudflare:workers` for a project's own bundle: the classes, and the project's `env` and\n * `exports` from `globalThis.__cellsProjectScope` (set by `browserProjectRuntime`, and by\n * `serveIsolate` for the loaded Worker an isolate runs). The shim is\n * bundled with the Worker, so it declares no names beyond its exports: esbuild would rename the\n * Worker's own variables of the same name, and those names show in error messages.\n */\nexport const PROJECT_WORKERS_MODULE_SHIM = `${WORKERS_CLASSES} export const env = globalThis.__cellsProjectScope?.env ?? {}, exports = globalThis.__cellsProjectScope?.exports ?? {}, waitUntil = (p) => globalThis.__cellsProjectScope?.waitUntil(p);`;\n\n/**\n * Worker Loader in a browser realm: each module of a WorkerCode becomes a Blob-URL ES\n * module. `cloudflare:workers` resolves to a shim reading the runtime's own classes from\n * `globalThis.__cellsWorkersModule` and the loaded code's own `env` and `exports` (or to\n * `workersModuleShim`, the same for every load); relative imports resolve to the Blob URLs of\n * sibling modules; with a log sink the module gets a module-scoped `console` (Tail Workers).\n */\nexport function browserModuleLoader(workersModuleShim?: string): ModuleLoader {\n const blob = (text: string) => URL.createObjectURL(new Blob([text], { type: \"text/javascript\" }));\n const fixedShimUrl = workersModuleShim && blob(workersModuleShim);\n return async (_id: string, code: WorkerCode, logs?: LogSink) => {\n const env = code.env ?? {};\n const scope = fixedShimUrl ? undefined : workerScope(env);\n let shimUrl = fixedShimUrl;\n if (scope) {\n const key = `s${Math.random().toString(36).slice(2)}`;\n const g = globalThis as Record<string, unknown>;\n g.__cellsWorkerScopes ??= {};\n (g.__cellsWorkerScopes as Record<string, unknown>)[key] = scope;\n shimUrl = blob(\n `${WORKERS_CLASSES} const s = globalThis.__cellsWorkerScopes[${JSON.stringify(key)}]; export const env = s.env, exports = s.exports, waitUntil = s.waitUntil;`,\n );\n }\n let consolePrelude = \"\";\n if (logs) {\n const key = `c${Math.random().toString(36).slice(2)}`;\n const g = globalThis as Record<string, unknown>;\n g.__cellsConsoles ??= {};\n const real = globalThis.console;\n const wrap =\n (level: \"log\" | \"info\" | \"warn\" | \"error\" | \"debug\") =>\n (...args: unknown[]) => {\n logs(level, args);\n real[level](...args);\n };\n (g.__cellsConsoles as Record<string, unknown>)[key] = Object.assign(Object.create(real), {\n log: wrap(\"log\"),\n info: wrap(\"info\"),\n warn: wrap(\"warn\"),\n error: wrap(\"error\"),\n debug: wrap(\"debug\"),\n });\n consolePrelude = `const console = globalThis.__cellsConsoles[${JSON.stringify(key)}];\\n`;\n }\n const outbound = outboundFetch(code);\n if (outbound) {\n const key = `o${Math.random().toString(36).slice(2)}`;\n const g = globalThis as Record<string, unknown>;\n g.__cellsOutbound ??= {};\n (g.__cellsOutbound as Record<string, unknown>)[key] = outbound;\n consolePrelude += `const fetch = globalThis.__cellsOutbound[${JSON.stringify(key)}];\\n`;\n }\n const urls = new Map<string, string>();\n // Modules whose Blob URL is being made: a Blob URL exists only once its text (with its\n // imports' URLs) does, so modules that import each other cannot be loaded this way.\n const making: string[] = [];\n const source = (name: string) => {\n const m = code.modules[name];\n if (m === undefined) throw new Error(`Worker Loader: module \"${name}\" not found`);\n return moduleText(m);\n };\n const urlOf = (name: string): string => {\n const known = urls.get(name);\n if (known) return known;\n if (making.includes(name))\n throw new Error(\n `Worker Loader: modules import each other (${[...making.slice(making.indexOf(name)), name].join(\" → \")}); a browser realm loads each module from a Blob URL, which cannot form a cycle`,\n );\n making.push(name);\n const base = name.includes(\"/\") ? name.slice(0, name.lastIndexOf(\"/\") + 1) : \"\";\n // Only the module's own imports: the same words in a string, a template or a comment are\n // not imports (a code generator's template may well contain `from \"cloudflare:workers\"`).\n const text = rewriteModuleSpecifiers(source(name), (spec) => {\n if (spec === \"cloudflare:workers\") return shimUrl;\n if (spec.startsWith(\"./\") || spec.startsWith(\"../\"))\n return urlOf(new URL(spec, `file:///${base}`).pathname.slice(1));\n return undefined;\n });\n const url = URL.createObjectURL(\n new Blob([consolePrelude + text], { type: \"text/javascript\" }),\n );\n urls.set(name, url);\n making.pop();\n return url;\n };\n const module = (await import(/* @vite-ignore */ urlOf(code.mainModule))) as Record<\n string,\n unknown\n >;\n scope?.bind({ env, exports: ctxExports(module, env) });\n return module;\n };\n}\n"]}
|
|
@@ -52,6 +52,26 @@ function usesSuperOrNewTarget(fn) {
|
|
|
52
52
|
visit(fn.body);
|
|
53
53
|
return found;
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Whether an arrow reads `arguments` itself: an `arguments` identifier in its body, not in a
|
|
57
|
+
* function of its own (which has its own `arguments`). A word in a string or a comment is not.
|
|
58
|
+
*/
|
|
59
|
+
function readsArguments(fn) {
|
|
60
|
+
let found = false;
|
|
61
|
+
const visit = (n) => {
|
|
62
|
+
if (found)
|
|
63
|
+
return;
|
|
64
|
+
if (n.type === "Identifier" && n.name === "arguments") {
|
|
65
|
+
found = true;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
for (const c of childrenOf(n))
|
|
69
|
+
if (!(isFunction(c) && c.type !== "ArrowFunctionExpression"))
|
|
70
|
+
visit(c);
|
|
71
|
+
};
|
|
72
|
+
visit(fn.body);
|
|
73
|
+
return found;
|
|
74
|
+
}
|
|
55
75
|
const lowered = (n) => isFunction(n) && n.async && !n.generator && !usesSuperOrNewTarget(n);
|
|
56
76
|
/** `code` with its async functions lowered; `code` itself when it has none or does not parse. */
|
|
57
77
|
export function lowerAwait(code) {
|
|
@@ -121,8 +141,8 @@ export function lowerAwait(code) {
|
|
|
121
141
|
if (child !== fn.body)
|
|
122
142
|
return body;
|
|
123
143
|
// An arrow's `arguments` is its enclosing function's: pass them on only when it reads them
|
|
124
|
-
// (a module has none).
|
|
125
|
-
const call = !arrow ||
|
|
144
|
+
// (a module, a class field or a static block has none, and naming it there is an error).
|
|
145
|
+
const call = !arrow || readsArguments(fn) ? ".apply(this, arguments)" : ".call(this)";
|
|
126
146
|
if (fn.expression)
|
|
127
147
|
return `__cellbAsync(function* () { return ${body}; }${call})`;
|
|
128
148
|
return `{ return __cellbAsync(function* () ${body}${call}); }`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lower-await.js","sourceRoot":"","sources":["../../src/project/lower-await.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `async`/`await` lowered to generators, for the modules an in-browser site serves (what\n * esbuild's `supported: { \"async-await\": false }` does for `bundleWorkerForBrowser`): each `await`\n * then resumes through `Promise.prototype.then`, which cellb's `node:async_hooks` polyfill makes\n * carry the AsyncLocalStorage stores (see `installAsyncContext`).\n *\n * async function f(a) { BODY } → function f(a) { return __cellbAsync(function* () { BODY }.apply(this, arguments)); }\n * async (a) => EXPR → (a) => __cellbAsync(function* () { return EXPR; }.call(this))\n * await X → (yield X)\n * for await (L of R) BODY → a loop over `yield it.next()`, closing the iterator on exit\n *\n * Left as they are: async generators (their awaits stay native, as their bodies), functions that\n * use `super` or `new.target` (a generator nested in them cannot), and top-level await. Their\n * awaits resume in the polyfill's root frame: they see no store rather than another event's.\n */\nimport { type Node, parse } from \"acorn\";\n\n// biome-ignore lint/suspicious/noExplicitAny: walking acorn's ESTree nodes by their properties\ntype AnyNode = Node & Record<string, any>;\n\nconst ASYNC_RUNNER =\n 'function __cellbAsync(g){return new Promise(function(res,rej){function step(m,v){var r;try{r=g[m](v)}catch(e){rej(e);return}if(r.done)res(r.value);else Promise.resolve(r.value).then(function(x){step(\"next\",x)},function(e){step(\"throw\",e)})}step(\"next\")})}';\nconst ASYNC_ITERATOR =\n \"function __cellbIter(o){var m=o[Symbol.asyncIterator];if(m)return m.call(o);var it=o[Symbol.iterator](),w=function(r){return Promise.resolve(r.value).then(function(x){return{value:x,done:r.done}})};return{next:function(v){return w(it.next(v))},return:it.return&&function(v){return w(it.return(v))}}}\";\n\nconst isFunction = (n: AnyNode) =>\n n.type === \"FunctionDeclaration\" ||\n n.type === \"FunctionExpression\" ||\n n.type === \"ArrowFunctionExpression\";\n\nfunction childrenOf(node: AnyNode): AnyNode[] {\n const out: AnyNode[] = [];\n for (const key in node) {\n if (key === \"type\" || key === \"start\" || key === \"end\" || key === \"loc\" || key === \"range\")\n continue;\n const v = node[key];\n if (Array.isArray(v)) {\n for (const c of v) if (c && typeof c.type === \"string\") out.push(c);\n } else if (v && typeof v.type === \"string\") out.push(v);\n }\n return out.sort((a, b) => a.start - b.start);\n}\n\n/** `super` or `new.target` in `fn`'s own body (not in the functions it declares). */\nfunction usesSuperOrNewTarget(fn: AnyNode): boolean {\n let found = false;\n const visit = (n: AnyNode) => {\n if (found) return;\n if (n.type === \"Super\" || n.type === \"MetaProperty\") {\n found = true;\n return;\n }\n for (const c of childrenOf(n))\n if (!(isFunction(c) && c.type !== \"ArrowFunctionExpression\") && c.type !== \"ClassBody\")\n visit(c);\n };\n visit(fn.body);\n return found;\n}\n\nconst lowered = (n: AnyNode) =>\n isFunction(n) && n.async && !n.generator && !usesSuperOrNewTarget(n);\n\n/** `code` with its async functions lowered; `code` itself when it has none or does not parse. */\nexport function lowerAwait(code: string): string {\n if (!/\\basync\\b/.test(code)) return code;\n let program: AnyNode;\n try {\n program = parse(code, {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n allowHashBang: true,\n }) as AnyNode;\n } catch {\n return code;\n }\n let changed = false;\n let iterUsed = false;\n let temp = 0;\n\n // `inLowered`: whether `await` here belongs to a function being lowered.\n const render = (node: AnyNode, inLowered: boolean): string => {\n if (isFunction(node)) return renderFunction(node);\n if (inLowered && node.type === \"AwaitExpression\")\n return `(yield ${render(node.argument, inLowered)})`;\n if (inLowered && node.type === \"ForOfStatement\" && node.await)\n return renderForAwait(node, \"\", inLowered);\n if (inLowered && node.type === \"LabeledStatement\") {\n let labels = \"\";\n let body = node;\n while (body.type === \"LabeledStatement\") {\n labels += `${body.label.name}: `;\n body = body.body;\n }\n if (body.type === \"ForOfStatement\" && body.await)\n return renderForAwait(body, labels, inLowered);\n }\n let text = generic(node, inLowered);\n // `async` of a lowered method sits before its key (`static async [k]() {}`).\n if (\n (node.type === \"MethodDefinition\" || (node.type === \"Property\" && node.method)) &&\n lowered(node.value)\n ) {\n const head = node.key.start - node.start - (node.computed ? 1 : 0);\n const prefix = text.slice(0, head).replace(/\\basync\\b\\s*/, \"\");\n text = prefix + text.slice(head);\n }\n return text;\n };\n\n const generic = (\n node: AnyNode,\n inLowered: boolean,\n wrap?: (child: AnyNode, text: string) => string,\n ): string => {\n let out = \"\";\n let at = node.start;\n for (const c of childrenOf(node)) {\n if (c.start < at) continue; // the same node twice (a shorthand property's key and value)\n out += code.slice(at, c.start);\n const text = render(c, inLowered);\n out += wrap ? wrap(c, text) : text;\n at = c.end;\n }\n return out + code.slice(at, node.end);\n };\n\n const renderFunction = (fn: AnyNode): string => {\n if (!lowered(fn)) return generic(fn, false);\n changed = true;\n const arrow = fn.type === \"ArrowFunctionExpression\";\n const text = generic(fn, true, (child, body) => {\n if (child !== fn.body) return body;\n // An arrow's `arguments` is its enclosing function's: pass them on only when it reads them\n // (a module has none).\n const call = !arrow || /\\barguments\\b/.test(body) ? \".apply(this, arguments)\" : \".call(this)\";\n if (fn.expression) return `__cellbAsync(function* () { return ${body}; }${call})`;\n return `{ return __cellbAsync(function* () ${body}${call}); }`;\n });\n return text.replace(/^async\\b\\s*/, \"\");\n };\n\n const renderForAwait = (loop: AnyNode, labels: string, inLowered: boolean): string => {\n iterUsed = true;\n const n = temp++;\n const it = `__cellbIt${n}`;\n const step = `__cellbStep${n}`;\n const left = render(loop.left, inLowered);\n const assign =\n loop.left.type === \"VariableDeclaration\"\n ? `${left} = ${step}.value;`\n : `(${left} = ${step}.value);`;\n return (\n `{ const ${it} = __cellbIter(${render(loop.right, inLowered)}); let ${step}; ` +\n `try { ${labels}for (;;) { ${step} = undefined; ${step} = yield ${it}.next(); ` +\n `if (${step}.done) break; { ${assign} ${render(loop.body, inLowered)} } } } ` +\n `finally { if (${step} && !${step}.done && ${it}.return) yield ${it}.return(); } }`\n );\n };\n\n const out = render(program, false);\n if (!changed) return code;\n return `${out}\\n${ASYNC_RUNNER}\\n${iterUsed ? `${ASYNC_ITERATOR}\\n` : \"\"}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lower-await.js","sourceRoot":"","sources":["../../src/project/lower-await.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `async`/`await` lowered to generators, for the modules an in-browser site serves (what\n * esbuild's `supported: { \"async-await\": false }` does for `bundleWorkerForBrowser`): each `await`\n * then resumes through `Promise.prototype.then`, which cellb's `node:async_hooks` polyfill makes\n * carry the AsyncLocalStorage stores (see `installAsyncContext`).\n *\n * async function f(a) { BODY } → function f(a) { return __cellbAsync(function* () { BODY }.apply(this, arguments)); }\n * async (a) => EXPR → (a) => __cellbAsync(function* () { return EXPR; }.call(this))\n * await X → (yield X)\n * for await (L of R) BODY → a loop over `yield it.next()`, closing the iterator on exit\n *\n * Left as they are: async generators (their awaits stay native, as their bodies), functions that\n * use `super` or `new.target` (a generator nested in them cannot), and top-level await. Their\n * awaits resume in the polyfill's root frame: they see no store rather than another event's.\n */\nimport { type Node, parse } from \"acorn\";\n\n// biome-ignore lint/suspicious/noExplicitAny: walking acorn's ESTree nodes by their properties\ntype AnyNode = Node & Record<string, any>;\n\nconst ASYNC_RUNNER =\n 'function __cellbAsync(g){return new Promise(function(res,rej){function step(m,v){var r;try{r=g[m](v)}catch(e){rej(e);return}if(r.done)res(r.value);else Promise.resolve(r.value).then(function(x){step(\"next\",x)},function(e){step(\"throw\",e)})}step(\"next\")})}';\nconst ASYNC_ITERATOR =\n \"function __cellbIter(o){var m=o[Symbol.asyncIterator];if(m)return m.call(o);var it=o[Symbol.iterator](),w=function(r){return Promise.resolve(r.value).then(function(x){return{value:x,done:r.done}})};return{next:function(v){return w(it.next(v))},return:it.return&&function(v){return w(it.return(v))}}}\";\n\nconst isFunction = (n: AnyNode) =>\n n.type === \"FunctionDeclaration\" ||\n n.type === \"FunctionExpression\" ||\n n.type === \"ArrowFunctionExpression\";\n\nfunction childrenOf(node: AnyNode): AnyNode[] {\n const out: AnyNode[] = [];\n for (const key in node) {\n if (key === \"type\" || key === \"start\" || key === \"end\" || key === \"loc\" || key === \"range\")\n continue;\n const v = node[key];\n if (Array.isArray(v)) {\n for (const c of v) if (c && typeof c.type === \"string\") out.push(c);\n } else if (v && typeof v.type === \"string\") out.push(v);\n }\n return out.sort((a, b) => a.start - b.start);\n}\n\n/** `super` or `new.target` in `fn`'s own body (not in the functions it declares). */\nfunction usesSuperOrNewTarget(fn: AnyNode): boolean {\n let found = false;\n const visit = (n: AnyNode) => {\n if (found) return;\n if (n.type === \"Super\" || n.type === \"MetaProperty\") {\n found = true;\n return;\n }\n for (const c of childrenOf(n))\n if (!(isFunction(c) && c.type !== \"ArrowFunctionExpression\") && c.type !== \"ClassBody\")\n visit(c);\n };\n visit(fn.body);\n return found;\n}\n\n/**\n * Whether an arrow reads `arguments` itself: an `arguments` identifier in its body, not in a\n * function of its own (which has its own `arguments`). A word in a string or a comment is not.\n */\nfunction readsArguments(fn: AnyNode): boolean {\n let found = false;\n const visit = (n: AnyNode) => {\n if (found) return;\n if (n.type === \"Identifier\" && n.name === \"arguments\") {\n found = true;\n return;\n }\n for (const c of childrenOf(n))\n if (!(isFunction(c) && c.type !== \"ArrowFunctionExpression\")) visit(c);\n };\n visit(fn.body);\n return found;\n}\n\nconst lowered = (n: AnyNode) =>\n isFunction(n) && n.async && !n.generator && !usesSuperOrNewTarget(n);\n\n/** `code` with its async functions lowered; `code` itself when it has none or does not parse. */\nexport function lowerAwait(code: string): string {\n if (!/\\basync\\b/.test(code)) return code;\n let program: AnyNode;\n try {\n program = parse(code, {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n allowHashBang: true,\n }) as AnyNode;\n } catch {\n return code;\n }\n let changed = false;\n let iterUsed = false;\n let temp = 0;\n\n // `inLowered`: whether `await` here belongs to a function being lowered.\n const render = (node: AnyNode, inLowered: boolean): string => {\n if (isFunction(node)) return renderFunction(node);\n if (inLowered && node.type === \"AwaitExpression\")\n return `(yield ${render(node.argument, inLowered)})`;\n if (inLowered && node.type === \"ForOfStatement\" && node.await)\n return renderForAwait(node, \"\", inLowered);\n if (inLowered && node.type === \"LabeledStatement\") {\n let labels = \"\";\n let body = node;\n while (body.type === \"LabeledStatement\") {\n labels += `${body.label.name}: `;\n body = body.body;\n }\n if (body.type === \"ForOfStatement\" && body.await)\n return renderForAwait(body, labels, inLowered);\n }\n let text = generic(node, inLowered);\n // `async` of a lowered method sits before its key (`static async [k]() {}`).\n if (\n (node.type === \"MethodDefinition\" || (node.type === \"Property\" && node.method)) &&\n lowered(node.value)\n ) {\n const head = node.key.start - node.start - (node.computed ? 1 : 0);\n const prefix = text.slice(0, head).replace(/\\basync\\b\\s*/, \"\");\n text = prefix + text.slice(head);\n }\n return text;\n };\n\n const generic = (\n node: AnyNode,\n inLowered: boolean,\n wrap?: (child: AnyNode, text: string) => string,\n ): string => {\n let out = \"\";\n let at = node.start;\n for (const c of childrenOf(node)) {\n if (c.start < at) continue; // the same node twice (a shorthand property's key and value)\n out += code.slice(at, c.start);\n const text = render(c, inLowered);\n out += wrap ? wrap(c, text) : text;\n at = c.end;\n }\n return out + code.slice(at, node.end);\n };\n\n const renderFunction = (fn: AnyNode): string => {\n if (!lowered(fn)) return generic(fn, false);\n changed = true;\n const arrow = fn.type === \"ArrowFunctionExpression\";\n const text = generic(fn, true, (child, body) => {\n if (child !== fn.body) return body;\n // An arrow's `arguments` is its enclosing function's: pass them on only when it reads them\n // (a module, a class field or a static block has none, and naming it there is an error).\n const call = !arrow || readsArguments(fn) ? \".apply(this, arguments)\" : \".call(this)\";\n if (fn.expression) return `__cellbAsync(function* () { return ${body}; }${call})`;\n return `{ return __cellbAsync(function* () ${body}${call}); }`;\n });\n return text.replace(/^async\\b\\s*/, \"\");\n };\n\n const renderForAwait = (loop: AnyNode, labels: string, inLowered: boolean): string => {\n iterUsed = true;\n const n = temp++;\n const it = `__cellbIt${n}`;\n const step = `__cellbStep${n}`;\n const left = render(loop.left, inLowered);\n const assign =\n loop.left.type === \"VariableDeclaration\"\n ? `${left} = ${step}.value;`\n : `(${left} = ${step}.value);`;\n return (\n `{ const ${it} = __cellbIter(${render(loop.right, inLowered)}); let ${step}; ` +\n `try { ${labels}for (;;) { ${step} = undefined; ${step} = yield ${it}.next(); ` +\n `if (${step}.done) break; { ${assign} ${render(loop.body, inLowered)} } } } ` +\n `finally { if (${step} && !${step}.done && ${it}.return) yield ${it}.return(); } }`\n );\n };\n\n const out = render(program, false);\n if (!changed) return code;\n return `${out}\\n${ASYNC_RUNNER}\\n${iterUsed ? `${ASYNC_ITERATOR}\\n` : \"\"}`;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrites the module specifiers of an ES module's own imports: `import … from "x"`,
|
|
3
|
+
* `import "x"`, `export … from "x"` and `import("x")`, and only those. The text is scanned as
|
|
4
|
+
* code, so the same words inside a string, a template literal's text, a comment or a regular
|
|
5
|
+
* expression are left alone (a regex over the whole text would rewrite them, e.g. a code
|
|
6
|
+
* generator's template that contains `from "cloudflare:workers"`).
|
|
7
|
+
*
|
|
8
|
+
* A small scanner rather than a parser: the browser module loader runs in every isolate and
|
|
9
|
+
* shard worker, where a full JS parser would add its whole size.
|
|
10
|
+
*
|
|
11
|
+
* `resolve(spec)` returns the replacement specifier, or undefined to keep it. A dynamic import
|
|
12
|
+
* is rewritten only when its argument is one literal (a string, or a template without `${`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function rewriteModuleSpecifiers(code: string, resolve: (spec: string) => string | undefined): string;
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rewrites the module specifiers of an ES module's own imports: `import … from "x"`,
|
|
3
|
+
* `import "x"`, `export … from "x"` and `import("x")`, and only those. The text is scanned as
|
|
4
|
+
* code, so the same words inside a string, a template literal's text, a comment or a regular
|
|
5
|
+
* expression are left alone (a regex over the whole text would rewrite them, e.g. a code
|
|
6
|
+
* generator's template that contains `from "cloudflare:workers"`).
|
|
7
|
+
*
|
|
8
|
+
* A small scanner rather than a parser: the browser module loader runs in every isolate and
|
|
9
|
+
* shard worker, where a full JS parser would add its whole size.
|
|
10
|
+
*
|
|
11
|
+
* `resolve(spec)` returns the replacement specifier, or undefined to keep it. A dynamic import
|
|
12
|
+
* is rewritten only when its argument is one literal (a string, or a template without `${`).
|
|
13
|
+
*/
|
|
14
|
+
export function rewriteModuleSpecifiers(code, resolve) {
|
|
15
|
+
const edits = [];
|
|
16
|
+
const n = code.length;
|
|
17
|
+
// The last significant token, to tell a regular expression from a division: a punctuator
|
|
18
|
+
// (`(`, `=`, …), "id" (an identifier or a keyword not in REGEX_AFTER_WORD), "num", "str",
|
|
19
|
+
// "re", "++"/"--", or ")" / "]" / "}" (a division follows, unless the `)` closed the head of
|
|
20
|
+
// `if`/`while`/`for`/`with`, which a statement, and so a regex, may follow).
|
|
21
|
+
let prev = "";
|
|
22
|
+
let prevWord = ""; // the identifier `prev` stands for, when it is "id"
|
|
23
|
+
// Template literals being scanned: for each `${`, the brace depth it opened at.
|
|
24
|
+
const templates = [];
|
|
25
|
+
let depth = 0;
|
|
26
|
+
// For each open `(`: whether it is the head of if/while/for/with.
|
|
27
|
+
const parens = [];
|
|
28
|
+
const WORD_START = new Uint8Array(128);
|
|
29
|
+
const WORD = new Uint8Array(128);
|
|
30
|
+
for (let c = 0; c < 128; c++) {
|
|
31
|
+
const ch = String.fromCharCode(c);
|
|
32
|
+
WORD_START[c] = /[A-Za-z_$]/.test(ch) ? 1 : 0;
|
|
33
|
+
WORD[c] = /[A-Za-z0-9_$]/.test(ch) ? 1 : 0;
|
|
34
|
+
}
|
|
35
|
+
const isIdStart = (c) => (c < 128 ? WORD_START[c] === 1 : c > 0xa0 || c === 0x5c);
|
|
36
|
+
const isId = (c) => (c < 128 ? WORD[c] === 1 : c > 0xa0 || c === 0x5c);
|
|
37
|
+
const isSpace = (c) => c === 32 || (c >= 9 && c <= 13) || c === 0xa0 || c === 0xfeff || c === 0x2028 || c === 0x2029;
|
|
38
|
+
const REGEX_AFTER_WORD = new Set([
|
|
39
|
+
"return",
|
|
40
|
+
"typeof",
|
|
41
|
+
"instanceof",
|
|
42
|
+
"in",
|
|
43
|
+
"of",
|
|
44
|
+
"new",
|
|
45
|
+
"delete",
|
|
46
|
+
"void",
|
|
47
|
+
"throw",
|
|
48
|
+
"case",
|
|
49
|
+
"do",
|
|
50
|
+
"else",
|
|
51
|
+
"yield",
|
|
52
|
+
"await",
|
|
53
|
+
"default",
|
|
54
|
+
"extends",
|
|
55
|
+
]);
|
|
56
|
+
const HEADS = new Set(["if", "while", "for", "with"]);
|
|
57
|
+
const regexAllowed = () => {
|
|
58
|
+
if (prev === "id")
|
|
59
|
+
return REGEX_AFTER_WORD.has(prevWord);
|
|
60
|
+
if (prev === "" || prev === "head)")
|
|
61
|
+
return true;
|
|
62
|
+
return /^[(,=:[!&|?{};+\-*%<>~^]$/.test(prev);
|
|
63
|
+
};
|
|
64
|
+
const skipSpace = (from) => {
|
|
65
|
+
let j = from;
|
|
66
|
+
for (;;) {
|
|
67
|
+
while (j < n && isSpace(code.charCodeAt(j)))
|
|
68
|
+
j++;
|
|
69
|
+
if (code.startsWith("//", j)) {
|
|
70
|
+
while (j < n && code[j] !== "\n" && code[j] !== "\r")
|
|
71
|
+
j++;
|
|
72
|
+
}
|
|
73
|
+
else if (code.startsWith("/*", j)) {
|
|
74
|
+
const end = code.indexOf("*/", j + 2);
|
|
75
|
+
j = end < 0 ? n : end + 2;
|
|
76
|
+
}
|
|
77
|
+
else
|
|
78
|
+
return j;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
/** The end (exclusive) of the quoted string starting at `from`. */
|
|
82
|
+
const stringEnd = (from) => {
|
|
83
|
+
const q = code[from];
|
|
84
|
+
let j = from + 1;
|
|
85
|
+
while (j < n && code[j] !== q) {
|
|
86
|
+
if (code[j] === "\\") {
|
|
87
|
+
j++;
|
|
88
|
+
if (code[j] === "\r" && code[j + 1] === "\n")
|
|
89
|
+
j++; // a CRLF line continuation
|
|
90
|
+
}
|
|
91
|
+
else if (code[j] === "\n" || code[j] === "\r")
|
|
92
|
+
break;
|
|
93
|
+
j++;
|
|
94
|
+
}
|
|
95
|
+
return j + 1;
|
|
96
|
+
};
|
|
97
|
+
/** The string's value, decoding the simple escapes; undefined for anything else. */
|
|
98
|
+
const decode = (raw) => {
|
|
99
|
+
let out = "";
|
|
100
|
+
for (let j = 0; j < raw.length; j++) {
|
|
101
|
+
const c = raw[j];
|
|
102
|
+
if (c !== "\\") {
|
|
103
|
+
out += c;
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
const e = raw[++j];
|
|
107
|
+
const hex = (len) => {
|
|
108
|
+
const h = raw.slice(j + 1, j + 1 + len);
|
|
109
|
+
if (!new RegExp(`^[0-9a-fA-F]{${len}}$`).test(h))
|
|
110
|
+
return undefined;
|
|
111
|
+
j += len;
|
|
112
|
+
return String.fromCharCode(Number.parseInt(h, 16));
|
|
113
|
+
};
|
|
114
|
+
const d = e === "x"
|
|
115
|
+
? hex(2)
|
|
116
|
+
: e === "u"
|
|
117
|
+
? hex(4)
|
|
118
|
+
: e === "'" || e === '"' || e === "\\" || e === "/"
|
|
119
|
+
? e
|
|
120
|
+
: undefined;
|
|
121
|
+
if (d === undefined)
|
|
122
|
+
return undefined;
|
|
123
|
+
out += d;
|
|
124
|
+
}
|
|
125
|
+
return out;
|
|
126
|
+
};
|
|
127
|
+
/** A string literal (or, for import(), a template without `${`) at `from`, after spaces. */
|
|
128
|
+
const literalAt = (from, template) => {
|
|
129
|
+
const j = skipSpace(from);
|
|
130
|
+
const q = code[j];
|
|
131
|
+
if (q === '"' || q === "'")
|
|
132
|
+
return { start: j, end: stringEnd(j) };
|
|
133
|
+
if (template && q === "`") {
|
|
134
|
+
const end = code.indexOf("`", j + 1);
|
|
135
|
+
if (end < 0)
|
|
136
|
+
return undefined;
|
|
137
|
+
const raw = code.slice(j + 1, end);
|
|
138
|
+
if (raw.includes("${") || raw.includes("\\"))
|
|
139
|
+
return undefined;
|
|
140
|
+
return { start: j, end: end + 1 };
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
};
|
|
144
|
+
const take = (s) => {
|
|
145
|
+
if (!s)
|
|
146
|
+
return;
|
|
147
|
+
const spec = decode(code.slice(s.start + 1, s.end - 1));
|
|
148
|
+
if (spec === undefined)
|
|
149
|
+
return;
|
|
150
|
+
const to = resolve(spec);
|
|
151
|
+
if (to !== undefined)
|
|
152
|
+
edits.push({ start: s.start, end: s.end, text: JSON.stringify(to) });
|
|
153
|
+
};
|
|
154
|
+
/** Scans template text from `from` (just after a backtick, or a `}` closing `${…}`). */
|
|
155
|
+
const templateText = (from) => {
|
|
156
|
+
let j = from;
|
|
157
|
+
while (j < n) {
|
|
158
|
+
const c = code[j];
|
|
159
|
+
if (c === "\\")
|
|
160
|
+
j += 2;
|
|
161
|
+
else if (c === "`")
|
|
162
|
+
return j + 1;
|
|
163
|
+
else if (c === "$" && code[j + 1] === "{") {
|
|
164
|
+
templates.push(depth);
|
|
165
|
+
depth++;
|
|
166
|
+
return j + 2;
|
|
167
|
+
}
|
|
168
|
+
else
|
|
169
|
+
j++;
|
|
170
|
+
}
|
|
171
|
+
return n;
|
|
172
|
+
};
|
|
173
|
+
let i = 0;
|
|
174
|
+
if (code.startsWith("#!"))
|
|
175
|
+
while (i < n && code[i] !== "\n")
|
|
176
|
+
i++; // a hashbang line
|
|
177
|
+
while (i < n) {
|
|
178
|
+
const cc = code.charCodeAt(i);
|
|
179
|
+
const c = code[i];
|
|
180
|
+
if (isSpace(cc)) {
|
|
181
|
+
i++;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
if (c === "/" && (code[i + 1] === "/" || code[i + 1] === "*")) {
|
|
185
|
+
i = skipSpace(i);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (c === '"' || c === "'") {
|
|
189
|
+
i = stringEnd(i);
|
|
190
|
+
prev = "str";
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (c === "`") {
|
|
194
|
+
i = templateText(i + 1);
|
|
195
|
+
prev = "str";
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (c === "/" && regexAllowed()) {
|
|
199
|
+
let j = i + 1;
|
|
200
|
+
let inClass = false;
|
|
201
|
+
let closed = false;
|
|
202
|
+
while (j < n && code[j] !== "\n" && code[j] !== "\r") {
|
|
203
|
+
const d = code[j];
|
|
204
|
+
if (d === "\\")
|
|
205
|
+
j++;
|
|
206
|
+
else if (d === "[")
|
|
207
|
+
inClass = true;
|
|
208
|
+
else if (d === "]")
|
|
209
|
+
inClass = false;
|
|
210
|
+
else if (d === "/" && !inClass) {
|
|
211
|
+
closed = true;
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
j++;
|
|
215
|
+
}
|
|
216
|
+
if (closed) {
|
|
217
|
+
j++;
|
|
218
|
+
while (j < n && isId(code.charCodeAt(j)))
|
|
219
|
+
j++; // flags
|
|
220
|
+
}
|
|
221
|
+
i = j;
|
|
222
|
+
prev = "re";
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (isIdStart(cc)) {
|
|
226
|
+
let j = i + 1;
|
|
227
|
+
while (j < n && isId(code.charCodeAt(j)))
|
|
228
|
+
j++;
|
|
229
|
+
const word = code.slice(i, j);
|
|
230
|
+
const member = prev === "." || prev === "?.";
|
|
231
|
+
if (!member && word === "from" && (prev === "}" || prev === "*" || prev === "id"))
|
|
232
|
+
take(literalAt(j, false));
|
|
233
|
+
else if (!member && word === "import") {
|
|
234
|
+
const k = skipSpace(j);
|
|
235
|
+
if (code[k] === "(") {
|
|
236
|
+
// import(x): only a whole literal argument (not "./a/" + b).
|
|
237
|
+
const s = literalAt(k + 1, true);
|
|
238
|
+
const after = s && code[skipSpace(s.end)];
|
|
239
|
+
if (after === ")" || after === ",")
|
|
240
|
+
take(s);
|
|
241
|
+
}
|
|
242
|
+
else
|
|
243
|
+
take(literalAt(j, false)); // a side-effect import of a bare string
|
|
244
|
+
}
|
|
245
|
+
i = j;
|
|
246
|
+
prev = "id";
|
|
247
|
+
prevWord = word;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (cc >= 48 && cc <= 57) {
|
|
251
|
+
let j = i + 1;
|
|
252
|
+
while (j < n && (isId(code.charCodeAt(j)) || code[j] === "."))
|
|
253
|
+
j++;
|
|
254
|
+
i = j;
|
|
255
|
+
prev = "num";
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if ((c === "+" || c === "-") && code[i + 1] === c) {
|
|
259
|
+
// `a++ / b` divides; `x = ++a` has the operator before an operand, which then sets prev.
|
|
260
|
+
prev = c + c;
|
|
261
|
+
i += 2;
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (c === "?" && code[i + 1] === "." && !/[0-9]/.test(code[i + 2] ?? "")) {
|
|
265
|
+
prev = "?.";
|
|
266
|
+
i += 2;
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (c === "(") {
|
|
270
|
+
parens.push(prev === "id" && HEADS.has(prevWord));
|
|
271
|
+
prev = "(";
|
|
272
|
+
i++;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (c === ")") {
|
|
276
|
+
prev = parens.pop() ? "head)" : ")";
|
|
277
|
+
i++;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (c === "{")
|
|
281
|
+
depth++;
|
|
282
|
+
else if (c === "}") {
|
|
283
|
+
depth--;
|
|
284
|
+
if (templates.length && templates[templates.length - 1] === depth) {
|
|
285
|
+
templates.pop();
|
|
286
|
+
i = templateText(i + 1);
|
|
287
|
+
prev = "str";
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
prev = c;
|
|
292
|
+
i++;
|
|
293
|
+
}
|
|
294
|
+
let out = "";
|
|
295
|
+
let at = 0;
|
|
296
|
+
for (const e of edits) {
|
|
297
|
+
out += code.slice(at, e.start) + e.text;
|
|
298
|
+
at = e.end;
|
|
299
|
+
}
|
|
300
|
+
return out + code.slice(at);
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=module-specifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-specifiers.js","sourceRoot":"","sources":["../../src/project/module-specifiers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Rewrites the module specifiers of an ES module's own imports: `import … from \"x\"`,\n * `import \"x\"`, `export … from \"x\"` and `import(\"x\")`, and only those. The text is scanned as\n * code, so the same words inside a string, a template literal's text, a comment or a regular\n * expression are left alone (a regex over the whole text would rewrite them, e.g. a code\n * generator's template that contains `from \"cloudflare:workers\"`).\n *\n * A small scanner rather than a parser: the browser module loader runs in every isolate and\n * shard worker, where a full JS parser would add its whole size.\n *\n * `resolve(spec)` returns the replacement specifier, or undefined to keep it. A dynamic import\n * is rewritten only when its argument is one literal (a string, or a template without `${`).\n */\nexport function rewriteModuleSpecifiers(\n code: string,\n resolve: (spec: string) => string | undefined,\n): string {\n const edits: { start: number; end: number; text: string }[] = [];\n const n = code.length;\n // The last significant token, to tell a regular expression from a division: a punctuator\n // (`(`, `=`, …), \"id\" (an identifier or a keyword not in REGEX_AFTER_WORD), \"num\", \"str\",\n // \"re\", \"++\"/\"--\", or \")\" / \"]\" / \"}\" (a division follows, unless the `)` closed the head of\n // `if`/`while`/`for`/`with`, which a statement, and so a regex, may follow).\n let prev = \"\";\n let prevWord = \"\"; // the identifier `prev` stands for, when it is \"id\"\n // Template literals being scanned: for each `${`, the brace depth it opened at.\n const templates: number[] = [];\n let depth = 0;\n // For each open `(`: whether it is the head of if/while/for/with.\n const parens: boolean[] = [];\n\n const WORD_START = new Uint8Array(128);\n const WORD = new Uint8Array(128);\n for (let c = 0; c < 128; c++) {\n const ch = String.fromCharCode(c);\n WORD_START[c] = /[A-Za-z_$]/.test(ch) ? 1 : 0;\n WORD[c] = /[A-Za-z0-9_$]/.test(ch) ? 1 : 0;\n }\n const isIdStart = (c: number) => (c < 128 ? WORD_START[c] === 1 : c > 0xa0 || c === 0x5c);\n const isId = (c: number) => (c < 128 ? WORD[c] === 1 : c > 0xa0 || c === 0x5c);\n const isSpace = (c: number) =>\n c === 32 || (c >= 9 && c <= 13) || c === 0xa0 || c === 0xfeff || c === 0x2028 || c === 0x2029;\n\n const REGEX_AFTER_WORD = new Set([\n \"return\",\n \"typeof\",\n \"instanceof\",\n \"in\",\n \"of\",\n \"new\",\n \"delete\",\n \"void\",\n \"throw\",\n \"case\",\n \"do\",\n \"else\",\n \"yield\",\n \"await\",\n \"default\",\n \"extends\",\n ]);\n const HEADS = new Set([\"if\", \"while\", \"for\", \"with\"]);\n const regexAllowed = () => {\n if (prev === \"id\") return REGEX_AFTER_WORD.has(prevWord);\n if (prev === \"\" || prev === \"head)\") return true;\n return /^[(,=:[!&|?{};+\\-*%<>~^]$/.test(prev);\n };\n\n const skipSpace = (from: number): number => {\n let j = from;\n for (;;) {\n while (j < n && isSpace(code.charCodeAt(j))) j++;\n if (code.startsWith(\"//\", j)) {\n while (j < n && code[j] !== \"\\n\" && code[j] !== \"\\r\") j++;\n } else if (code.startsWith(\"/*\", j)) {\n const end = code.indexOf(\"*/\", j + 2);\n j = end < 0 ? n : end + 2;\n } else return j;\n }\n };\n /** The end (exclusive) of the quoted string starting at `from`. */\n const stringEnd = (from: number): number => {\n const q = code[from];\n let j = from + 1;\n while (j < n && code[j] !== q) {\n if (code[j] === \"\\\\\") {\n j++;\n if (code[j] === \"\\r\" && code[j + 1] === \"\\n\") j++; // a CRLF line continuation\n } else if (code[j] === \"\\n\" || code[j] === \"\\r\") break;\n j++;\n }\n return j + 1;\n };\n /** The string's value, decoding the simple escapes; undefined for anything else. */\n const decode = (raw: string): string | undefined => {\n let out = \"\";\n for (let j = 0; j < raw.length; j++) {\n const c = raw[j] as string;\n if (c !== \"\\\\\") {\n out += c;\n continue;\n }\n const e = raw[++j];\n const hex = (len: number) => {\n const h = raw.slice(j + 1, j + 1 + len);\n if (!new RegExp(`^[0-9a-fA-F]{${len}}$`).test(h)) return undefined;\n j += len;\n return String.fromCharCode(Number.parseInt(h, 16));\n };\n const d =\n e === \"x\"\n ? hex(2)\n : e === \"u\"\n ? hex(4)\n : e === \"'\" || e === '\"' || e === \"\\\\\" || e === \"/\"\n ? e\n : undefined;\n if (d === undefined) return undefined;\n out += d;\n }\n return out;\n };\n /** A string literal (or, for import(), a template without `${`) at `from`, after spaces. */\n const literalAt = (from: number, template: boolean) => {\n const j = skipSpace(from);\n const q = code[j];\n if (q === '\"' || q === \"'\") return { start: j, end: stringEnd(j) };\n if (template && q === \"`\") {\n const end = code.indexOf(\"`\", j + 1);\n if (end < 0) return undefined;\n const raw = code.slice(j + 1, end);\n if (raw.includes(\"${\") || raw.includes(\"\\\\\")) return undefined;\n return { start: j, end: end + 1 };\n }\n return undefined;\n };\n const take = (s: { start: number; end: number } | undefined) => {\n if (!s) return;\n const spec = decode(code.slice(s.start + 1, s.end - 1));\n if (spec === undefined) return;\n const to = resolve(spec);\n if (to !== undefined) edits.push({ start: s.start, end: s.end, text: JSON.stringify(to) });\n };\n /** Scans template text from `from` (just after a backtick, or a `}` closing `${…}`). */\n const templateText = (from: number): number => {\n let j = from;\n while (j < n) {\n const c = code[j];\n if (c === \"\\\\\") j += 2;\n else if (c === \"`\") return j + 1;\n else if (c === \"$\" && code[j + 1] === \"{\") {\n templates.push(depth);\n depth++;\n return j + 2;\n } else j++;\n }\n return n;\n };\n\n let i = 0;\n if (code.startsWith(\"#!\")) while (i < n && code[i] !== \"\\n\") i++; // a hashbang line\n while (i < n) {\n const cc = code.charCodeAt(i);\n const c = code[i] as string;\n if (isSpace(cc)) {\n i++;\n continue;\n }\n if (c === \"/\" && (code[i + 1] === \"/\" || code[i + 1] === \"*\")) {\n i = skipSpace(i);\n continue;\n }\n if (c === '\"' || c === \"'\") {\n i = stringEnd(i);\n prev = \"str\";\n continue;\n }\n if (c === \"`\") {\n i = templateText(i + 1);\n prev = \"str\";\n continue;\n }\n if (c === \"/\" && regexAllowed()) {\n let j = i + 1;\n let inClass = false;\n let closed = false;\n while (j < n && code[j] !== \"\\n\" && code[j] !== \"\\r\") {\n const d = code[j];\n if (d === \"\\\\\") j++;\n else if (d === \"[\") inClass = true;\n else if (d === \"]\") inClass = false;\n else if (d === \"/\" && !inClass) {\n closed = true;\n break;\n }\n j++;\n }\n if (closed) {\n j++;\n while (j < n && isId(code.charCodeAt(j))) j++; // flags\n }\n i = j;\n prev = \"re\";\n continue;\n }\n if (isIdStart(cc)) {\n let j = i + 1;\n while (j < n && isId(code.charCodeAt(j))) j++;\n const word = code.slice(i, j);\n const member = prev === \".\" || prev === \"?.\";\n if (!member && word === \"from\" && (prev === \"}\" || prev === \"*\" || prev === \"id\"))\n take(literalAt(j, false));\n else if (!member && word === \"import\") {\n const k = skipSpace(j);\n if (code[k] === \"(\") {\n // import(x): only a whole literal argument (not \"./a/\" + b).\n const s = literalAt(k + 1, true);\n const after = s && code[skipSpace(s.end)];\n if (after === \")\" || after === \",\") take(s);\n } else take(literalAt(j, false)); // a side-effect import of a bare string\n }\n i = j;\n prev = \"id\";\n prevWord = word;\n continue;\n }\n if (cc >= 48 && cc <= 57) {\n let j = i + 1;\n while (j < n && (isId(code.charCodeAt(j)) || code[j] === \".\")) j++;\n i = j;\n prev = \"num\";\n continue;\n }\n if ((c === \"+\" || c === \"-\") && code[i + 1] === c) {\n // `a++ / b` divides; `x = ++a` has the operator before an operand, which then sets prev.\n prev = c + c;\n i += 2;\n continue;\n }\n if (c === \"?\" && code[i + 1] === \".\" && !/[0-9]/.test(code[i + 2] ?? \"\")) {\n prev = \"?.\";\n i += 2;\n continue;\n }\n if (c === \"(\") {\n parens.push(prev === \"id\" && HEADS.has(prevWord));\n prev = \"(\";\n i++;\n continue;\n }\n if (c === \")\") {\n prev = parens.pop() ? \"head)\" : \")\";\n i++;\n continue;\n }\n if (c === \"{\") depth++;\n else if (c === \"}\") {\n depth--;\n if (templates.length && templates[templates.length - 1] === depth) {\n templates.pop();\n i = templateText(i + 1);\n prev = \"str\";\n continue;\n }\n }\n prev = c;\n i++;\n }\n\n let out = \"\";\n let at = 0;\n for (const e of edits) {\n out += code.slice(at, e.start) + e.text;\n at = e.end;\n }\n return out + code.slice(at);\n}\n"]}
|
package/package.json
CHANGED