module-tsx 0.0.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.
@@ -0,0 +1,8 @@
1
+ //#region src/op.d.ts
2
+ /**
3
+ * Given a source URL and source code, transform the module and return a blob URL,
4
+ * where the blob URL's content is the transformed module code.
5
+ */
6
+ declare function transformSourceModule(sourceUrl: string, sourceCode: string): Promise<string>;
7
+ //#endregion
8
+ export { transformSourceModule };
package/dist/index.mjs ADDED
@@ -0,0 +1,282 @@
1
+ import ts from "typescript";
2
+
3
+ //#region \0@oxc-project+runtime@0.110.0/helpers/asyncToGenerator.js
4
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
5
+ try {
6
+ var i = n[a](c), u = i.value;
7
+ } catch (n) {
8
+ e(n);
9
+ return;
10
+ }
11
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
12
+ }
13
+ function _asyncToGenerator(n) {
14
+ return function() {
15
+ var t = this, e = arguments;
16
+ return new Promise(function(r, o) {
17
+ var a = n.apply(t, e);
18
+ function _next(n) {
19
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
20
+ }
21
+ function _throw(n) {
22
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
23
+ }
24
+ _next(void 0);
25
+ });
26
+ };
27
+ }
28
+
29
+ //#endregion
30
+ //#region src/network.ts
31
+ function fetchModule(_x, _x2) {
32
+ return _fetchModule.apply(this, arguments);
33
+ }
34
+ function _fetchModule() {
35
+ _fetchModule = _asyncToGenerator(function* (input, init) {
36
+ const res = yield fetch(input, init);
37
+ if (!res.ok) throw new Error(`Failed to fetch module ${res.url}: ${res.status}`);
38
+ return res.text();
39
+ });
40
+ return _fetchModule.apply(this, arguments);
41
+ }
42
+
43
+ //#endregion
44
+ //#region src/ts.ts
45
+ const FILE_NAME = "temp.tsx";
46
+ function createSourceFile(code, fileName = FILE_NAME) {
47
+ return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
48
+ }
49
+ function printSourceFile(sourceFile) {
50
+ const code = ts.createPrinter({
51
+ newLine: ts.NewLineKind.LineFeed,
52
+ removeComments: false
53
+ }).printFile(sourceFile);
54
+ return ts.transpile(code, {
55
+ target: ts.ScriptTarget.Latest,
56
+ module: ts.ModuleKind.ESNext,
57
+ noCheck: true,
58
+ declaration: false,
59
+ jsx: ts.JsxEmit.React
60
+ });
61
+ }
62
+ function transform(sourceFile, transformers) {
63
+ const result = ts.transform(sourceFile, transformers);
64
+ const transformedFile = result.transformed[0];
65
+ result.dispose();
66
+ return transformedFile;
67
+ }
68
+
69
+ //#endregion
70
+ //#region src/react.ts
71
+ /**
72
+ * Check if code uses JSX but missing React import
73
+ */
74
+ function needsReactImport(sourceFile) {
75
+ let hasJSX = false;
76
+ let hasReactVariable = false;
77
+ function visitNode(node) {
78
+ if (ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node) || ts.isJsxFragment(node)) hasJSX = true;
79
+ if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
80
+ if (node.importClause) {
81
+ var _node$importClause$na;
82
+ if (((_node$importClause$na = node.importClause.name) === null || _node$importClause$na === void 0 ? void 0 : _node$importClause$na.text) === "React") hasReactVariable = true;
83
+ if (node.importClause.namedBindings && ts.isNamespaceImport(node.importClause.namedBindings)) {
84
+ if (node.importClause.namedBindings.name.text === "React") hasReactVariable = true;
85
+ }
86
+ }
87
+ }
88
+ if (ts.isVariableDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
89
+ if (node.name.text === "React") hasReactVariable = true;
90
+ }
91
+ ts.forEachChild(node, visitNode);
92
+ }
93
+ visitNode(sourceFile);
94
+ return hasJSX && !hasReactVariable;
95
+ }
96
+ /**
97
+ * Add React import statement at the top if missing
98
+ */
99
+ function addReactImport(sourceFile) {
100
+ let reactSpecifier = "react";
101
+ function findReactSpecifier(node) {
102
+ if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
103
+ const specifier = node.moduleSpecifier.text;
104
+ if (specifier === "react" || /^react@/.test(specifier) || specifier.endsWith("/react") || /\/react@/.test(specifier)) {
105
+ reactSpecifier = specifier;
106
+ return;
107
+ }
108
+ }
109
+ ts.forEachChild(node, findReactSpecifier);
110
+ }
111
+ findReactSpecifier(sourceFile);
112
+ const statements = [ts.factory.createImportDeclaration(void 0, ts.factory.createImportClause(false, ts.factory.createIdentifier("React"), void 0), ts.factory.createStringLiteral(reactSpecifier), void 0), ...sourceFile.statements];
113
+ return ts.factory.updateSourceFile(sourceFile, statements, sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, sourceFile.hasNoDefaultLib, sourceFile.libReferenceDirectives);
114
+ }
115
+
116
+ //#endregion
117
+ //#region src/op.ts
118
+ /**
119
+ * track blob URLs to their original source URLs
120
+ */
121
+ const blobMap = /* @__PURE__ */ new Map();
122
+ /**
123
+ * track original source URLs to their transformed blob URLs
124
+ */
125
+ const sourceMap = /* @__PURE__ */ new Map();
126
+ function track(sourceUrl, blobUrl) {
127
+ sourceMap.set(sourceUrl, blobUrl);
128
+ blobMap.set(blobUrl, sourceUrl);
129
+ }
130
+ /**
131
+ * Given a source URL and source code, transform the module and return a blob URL,
132
+ * where the blob URL's content is the transformed module code.
133
+ */
134
+ function transformSourceModule(_x, _x2) {
135
+ return _transformSourceModule.apply(this, arguments);
136
+ }
137
+ function _transformSourceModule() {
138
+ _transformSourceModule = _asyncToGenerator(function* (sourceUrl, sourceCode) {
139
+ if (sourceMap.has(sourceUrl)) return sourceMap.get(sourceUrl);
140
+ const code = `import.meta.url=${JSON.stringify(sourceUrl)};\n` + (yield rewriteModuleImport(sourceUrl, sourceCode));
141
+ const blob = new Blob([code], { type: "text/javascript" });
142
+ const blobUrl = URL.createObjectURL(blob);
143
+ track(sourceUrl, blobUrl);
144
+ return blobUrl;
145
+ });
146
+ return _transformSourceModule.apply(this, arguments);
147
+ }
148
+ function getFileName(sourceUrl) {
149
+ try {
150
+ return new URL(sourceUrl).pathname;
151
+ } catch (_unused) {
152
+ return "temp.tsx";
153
+ }
154
+ }
155
+ function rewriteModuleImport(_x3, _x4) {
156
+ return _rewriteModuleImport.apply(this, arguments);
157
+ }
158
+ function _rewriteModuleImport() {
159
+ _rewriteModuleImport = _asyncToGenerator(function* (sourceUrl, sourceCode) {
160
+ const sourceFile = createSourceFile(sourceCode, getFileName(sourceUrl));
161
+ const rewrittenSpecifiers = yield resolveRelativeSpecifiers(collectRelativeSpecifiers(sourceFile), sourceUrl);
162
+ let workingSourceFile = sourceFile;
163
+ if (needsReactImport(workingSourceFile)) workingSourceFile = addReactImport(workingSourceFile);
164
+ const transformers = [createRewriteImportTransformer(rewrittenSpecifiers)];
165
+ return printSourceFile(transform(workingSourceFile, transformers));
166
+ });
167
+ return _rewriteModuleImport.apply(this, arguments);
168
+ }
169
+ function isBareSpecifier(specifier) {
170
+ if (specifier.match(/^\.*\//)) return false;
171
+ try {
172
+ new URL(specifier);
173
+ return false;
174
+ } catch (_unused2) {
175
+ return true;
176
+ }
177
+ }
178
+ function isRelativeSpecifier(specifier) {
179
+ return specifier.startsWith(".") || specifier.startsWith("/");
180
+ }
181
+ function collectRelativeSpecifiers(sourceFile) {
182
+ const set = /* @__PURE__ */ new Set();
183
+ const visit = (node) => {
184
+ const addIfRelative = (literal) => {
185
+ if (literal && isRelativeSpecifier(literal.text)) set.add(literal.text);
186
+ };
187
+ if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) addIfRelative(node.moduleSpecifier);
188
+ if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
189
+ const arg = node.arguments[0];
190
+ if (arg && ts.isStringLiteral(arg)) addIfRelative(arg);
191
+ }
192
+ if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) addIfRelative(node.moduleSpecifier);
193
+ ts.forEachChild(node, visit);
194
+ };
195
+ visit(sourceFile);
196
+ return set;
197
+ }
198
+ function resolveRelativeSpecifiers(_x6, _x7) {
199
+ return _resolveRelativeSpecifiers.apply(this, arguments);
200
+ }
201
+ function _resolveRelativeSpecifiers() {
202
+ _resolveRelativeSpecifiers = _asyncToGenerator(function* (specifiers, sourceUrl) {
203
+ const resolved = /* @__PURE__ */ new Map();
204
+ const tasks = Array.from(specifiers).map(function() {
205
+ var _ref = _asyncToGenerator(function* (specifier) {
206
+ const targetUrl = new URL(specifier, sourceUrl).toString();
207
+ const blobUrl = yield transformSourceModule(targetUrl, yield fetchModule(targetUrl));
208
+ resolved.set(specifier, blobUrl);
209
+ });
210
+ return function(_x5) {
211
+ return _ref.apply(this, arguments);
212
+ };
213
+ }());
214
+ yield Promise.all(tasks);
215
+ return resolved;
216
+ });
217
+ return _resolveRelativeSpecifiers.apply(this, arguments);
218
+ }
219
+ function createRewriteImportTransformer(replacements) {
220
+ const rewriteSpecifier = (specifier) => {
221
+ if (replacements.has(specifier)) return replacements.get(specifier);
222
+ if (specifier.startsWith("npm:")) return specifier.replace(/^npm:/, "https://esm.sh/");
223
+ if (specifier.startsWith("node:")) return `https://raw.esm.sh/@jspm/core/nodelibs/browser/${specifier.slice(5)}.js`;
224
+ if (isBareSpecifier(specifier)) return new URL(specifier, "https://esm.sh/").toString();
225
+ if (isRelativeSpecifier(specifier)) throw new Error("Unreachable");
226
+ return specifier;
227
+ };
228
+ const transformer = (context) => {
229
+ const visitNode = (node) => {
230
+ if (ts.isImportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
231
+ const next = rewriteSpecifier(node.moduleSpecifier.text);
232
+ if (next !== node.moduleSpecifier.text) return ts.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts.factory.createStringLiteral(next), node.assertClause);
233
+ }
234
+ if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
235
+ const arg = node.arguments[0];
236
+ if (arg && ts.isStringLiteral(arg)) {
237
+ const next = rewriteSpecifier(arg.text);
238
+ if (next !== arg.text) return ts.factory.updateCallExpression(node, node.expression, node.typeArguments, [ts.factory.createStringLiteral(next), ...node.arguments.slice(1)]);
239
+ }
240
+ }
241
+ if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
242
+ const next = rewriteSpecifier(node.moduleSpecifier.text);
243
+ if (next !== node.moduleSpecifier.text) return ts.factory.updateExportDeclaration(node, node.modifiers, node.isTypeOnly, node.exportClause, ts.factory.createStringLiteral(next), node.assertClause);
244
+ }
245
+ return ts.visitEachChild(node, visitNode, context);
246
+ };
247
+ return (sf) => ts.visitNode(sf, visitNode);
248
+ };
249
+ return transformer;
250
+ }
251
+
252
+ //#endregion
253
+ //#region src/index.ts
254
+ const TYPE_ATTRIBUTE_VALUE = "module-tsx";
255
+ function runScript(_x) {
256
+ return _runScript.apply(this, arguments);
257
+ }
258
+ function _runScript() {
259
+ _runScript = _asyncToGenerator(function* (script) {
260
+ return script.src ? import(yield transformSourceModule(script.src, yield fetchModule(script.src, { priority: script.fetchPriority }))) : import(yield transformSourceModule(location.href, script.innerHTML));
261
+ });
262
+ return _runScript.apply(this, arguments);
263
+ }
264
+ function sideEffect() {
265
+ return _sideEffect.apply(this, arguments);
266
+ }
267
+ function _sideEffect() {
268
+ _sideEffect = _asyncToGenerator(function* () {
269
+ for (const s of Array.from(document.querySelectorAll(`script[type="${TYPE_ATTRIBUTE_VALUE}"]`))) {
270
+ const script = s;
271
+ if (!script.async && script.defer) console.warn(`script with type="${TYPE_ATTRIBUTE_VALUE}" does not support defer attribute. Use async or no attribute instead.`);
272
+ for (const key in ["integrity", "crossorigin"]) if (script[key]) console.warn(`script with type="${TYPE_ATTRIBUTE_VALUE}" does not support ${key} attribute.`);
273
+ if (script.async) runScript(script);
274
+ else yield runScript(script);
275
+ }
276
+ });
277
+ return _sideEffect.apply(this, arguments);
278
+ }
279
+ document.addEventListener("DOMContentLoaded", sideEffect);
280
+
281
+ //#endregion
282
+ export { transformSourceModule };