@reckona/mreact-compiler 0.0.138 → 0.0.140
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/emit-server-stream.d.ts.map +1 -1
- package/dist/emit-server-stream.js +2 -1
- package/dist/emit-server-stream.js.map +1 -1
- package/dist/emit-server.d.ts.map +1 -1
- package/dist/emit-server.js +2 -1
- package/dist/emit-server.js.map +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +19 -1
- package/dist/internal.js.map +1 -1
- package/dist/oxc-node-utils.d.ts.map +1 -1
- package/dist/oxc-node-utils.js +41 -7
- package/dist/oxc-node-utils.js.map +1 -1
- package/dist/oxc-runtime-emit.d.ts +1 -0
- package/dist/oxc-runtime-emit.d.ts.map +1 -1
- package/dist/oxc-runtime-emit.js +41 -5
- package/dist/oxc-runtime-emit.js.map +1 -1
- package/dist/oxc-transform.d.ts.map +1 -1
- package/dist/oxc-transform.js +17 -3
- package/dist/oxc-transform.js.map +1 -1
- package/package.json +2 -2
- package/src/emit-server-stream.ts +2 -0
- package/src/emit-server.ts +2 -0
- package/src/internal.ts +26 -1
- package/src/oxc-node-utils.ts +54 -7
- package/src/oxc-runtime-emit.ts +59 -5
- package/src/oxc-transform.ts +24 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxc-node-utils.d.ts","sourceRoot":"","sources":["../src/oxc-node-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"oxc-node-utils.d.ts","sourceRoot":"","sources":["../src/oxc-node-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAKjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAElE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CAEnD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAK9D;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAQtF;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,cAAc,GAAG,SAAS,CAY5B;AAoDD,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAEtF"}
|
package/dist/oxc-node-utils.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const lineStartCache = new Map();
|
|
2
|
+
const lineStartCacheLimit = 128;
|
|
1
3
|
export function readObject(value) {
|
|
2
4
|
return typeof value === "object" && value !== null ? value : {};
|
|
3
5
|
}
|
|
@@ -28,18 +30,50 @@ export function getOxcLocationFromOffset(code, start) {
|
|
|
28
30
|
if (!Number.isInteger(start) || start < 0 || start > code.length) {
|
|
29
31
|
return undefined;
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
const lineStarts = getLineStarts(code);
|
|
34
|
+
const lineIndex = findLineStartIndex(lineStarts, start);
|
|
35
|
+
return {
|
|
36
|
+
line: lineIndex + 1,
|
|
37
|
+
column: start - (lineStarts[lineIndex] ?? 0) + 1,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function getLineStarts(code) {
|
|
41
|
+
const cached = lineStartCache.get(code);
|
|
42
|
+
if (cached !== undefined) {
|
|
43
|
+
return cached;
|
|
44
|
+
}
|
|
45
|
+
const starts = [0];
|
|
46
|
+
for (let index = 0; index < code.length; index += 1) {
|
|
34
47
|
if (code[index] === "\n") {
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
starts.push(index + 1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
rememberLineStarts(code, starts);
|
|
52
|
+
return starts;
|
|
53
|
+
}
|
|
54
|
+
function rememberLineStarts(code, starts) {
|
|
55
|
+
if (lineStartCache.size >= lineStartCacheLimit) {
|
|
56
|
+
const first = lineStartCache.keys().next().value;
|
|
57
|
+
if (first !== undefined) {
|
|
58
|
+
lineStartCache.delete(first);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
lineStartCache.set(code, starts);
|
|
62
|
+
}
|
|
63
|
+
function findLineStartIndex(lineStarts, offset) {
|
|
64
|
+
let low = 0;
|
|
65
|
+
let high = lineStarts.length - 1;
|
|
66
|
+
while (low <= high) {
|
|
67
|
+
const middle = Math.floor((low + high) / 2);
|
|
68
|
+
const lineStart = lineStarts[middle] ?? 0;
|
|
69
|
+
if (lineStart <= offset) {
|
|
70
|
+
low = middle + 1;
|
|
37
71
|
}
|
|
38
72
|
else {
|
|
39
|
-
|
|
73
|
+
high = middle - 1;
|
|
40
74
|
}
|
|
41
75
|
}
|
|
42
|
-
return
|
|
76
|
+
return Math.max(0, low - 1);
|
|
43
77
|
}
|
|
44
78
|
export function arraysEqual(left, right) {
|
|
45
79
|
return left.length === right.length && left.every((value, index) => value === right[index]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxc-node-utils.js","sourceRoot":"","sources":["../src/oxc-node-utils.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAE,KAAiC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAa;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;QACvE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;QACtC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,UAAmC;IAEnC,IAAI,OAAO,GAAG,UAAU,CAAC;IAEzB,OAAO,OAAO,CAAC,IAAI,KAAK,yBAAyB,EAAE,CAAC;QAClD,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,IAAa;IACxD,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;IAErC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,wBAAwB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,IAAY,EACZ,KAAa;IAEb,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACjE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"oxc-node-utils.js","sourceRoot":"","sources":["../src/oxc-node-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SourceLocation } from \"./types.js\";\n\nconst lineStartCache = new Map<string, readonly number[]>();\nconst lineStartCacheLimit = 128;\n\nexport function readObject(value: unknown): Record<string, unknown> {\n return typeof value === \"object\" && value !== null ? (value as Record<string, unknown>) : {};\n}\n\nexport function readArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nexport function readSource(code: string, node: unknown): string {\n const object = readObject(node);\n return typeof object.start === \"number\" && typeof object.end === \"number\"\n ? code.slice(object.start, object.end)\n : \"\";\n}\n\nexport function unwrapOxcParentheses(\n expression: Record<string, unknown>,\n): Record<string, unknown> {\n let current = expression;\n\n while (current.type === \"ParenthesizedExpression\") {\n current = readObject(current.expression);\n }\n\n return current;\n}\n\nexport function getOxcLocation(code: string, node: unknown): SourceLocation | undefined {\n const start = readObject(node).start;\n\n if (typeof start !== \"number\") {\n return undefined;\n }\n\n return getOxcLocationFromOffset(code, start);\n}\n\nexport function getOxcLocationFromOffset(\n code: string,\n start: number,\n): SourceLocation | undefined {\n if (!Number.isInteger(start) || start < 0 || start > code.length) {\n return undefined;\n }\n\n const lineStarts = getLineStarts(code);\n const lineIndex = findLineStartIndex(lineStarts, start);\n\n return {\n line: lineIndex + 1,\n column: start - (lineStarts[lineIndex] ?? 0) + 1,\n };\n}\n\nfunction getLineStarts(code: string): readonly number[] {\n const cached = lineStartCache.get(code);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const starts = [0];\n\n for (let index = 0; index < code.length; index += 1) {\n if (code[index] === \"\\n\") {\n starts.push(index + 1);\n }\n }\n\n rememberLineStarts(code, starts);\n\n return starts;\n}\n\nfunction rememberLineStarts(code: string, starts: readonly number[]): void {\n if (lineStartCache.size >= lineStartCacheLimit) {\n const first = lineStartCache.keys().next().value;\n\n if (first !== undefined) {\n lineStartCache.delete(first);\n }\n }\n\n lineStartCache.set(code, starts);\n}\n\nfunction findLineStartIndex(lineStarts: readonly number[], offset: number): number {\n let low = 0;\n let high = lineStarts.length - 1;\n\n while (low <= high) {\n const middle = Math.floor((low + high) / 2);\n const lineStart = lineStarts[middle] ?? 0;\n\n if (lineStart <= offset) {\n low = middle + 1;\n } else {\n high = middle - 1;\n }\n }\n\n return Math.max(0, low - 1);\n}\n\nexport function arraysEqual(left: readonly string[], right: readonly string[]): boolean {\n return left.length === right.length && left.every((value, index) => value === right[index]);\n}\n"]}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { JsxNodeIr } from "./ir.js";
|
|
2
2
|
export declare const oxcServerStringReactNodeRenderHelperPlaceholder = "__mreactRenderReactNodeToString";
|
|
3
|
+
export declare function setOxcServerStringUrlSafeHelperName(name: string): void;
|
|
3
4
|
export declare function emitOxcServerStringChildren(children: readonly JsxNodeIr[]): string;
|
|
4
5
|
export declare function emitOxcCompatObjectChildren(children: readonly JsxNodeIr[]): string;
|
|
5
6
|
//# sourceMappingURL=oxc-runtime-emit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxc-runtime-emit.d.ts","sourceRoot":"","sources":["../src/oxc-runtime-emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgC,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"oxc-runtime-emit.d.ts","sourceRoot":"","sources":["../src/oxc-runtime-emit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgC,SAAS,EAAE,MAAM,SAAS,CAAC;AAUvE,eAAO,MAAM,+CAA+C,oCACzB,CAAC;AAIpC,wBAAgB,mCAAmC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEtE;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAMlF;AAkLD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAUlF"}
|
package/dist/oxc-runtime-emit.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { isVoidHtmlElement } from "./emit-server-shared.js";
|
|
1
|
+
import { htmlAttributeName, isDangerousHtmlAttribute, isStaticUrlValueUnsafe, isUrlAttribute, isVoidHtmlElement, } from "./emit-server-shared.js";
|
|
2
2
|
import { escapeHtmlAttribute } from "@reckona/mreact-shared/html-escape";
|
|
3
3
|
export const oxcServerStringReactNodeRenderHelperPlaceholder = "__mreactRenderReactNodeToString";
|
|
4
|
+
let currentOxcServerStringUrlSafeHelperName = "_urlAttrSafe";
|
|
5
|
+
export function setOxcServerStringUrlSafeHelperName(name) {
|
|
6
|
+
currentOxcServerStringUrlSafeHelperName = name;
|
|
7
|
+
}
|
|
4
8
|
export function emitOxcServerStringChildren(children) {
|
|
5
9
|
if (children.length === 0) {
|
|
6
10
|
return '""';
|
|
@@ -38,7 +42,9 @@ function emitOxcServerStringNode(node) {
|
|
|
38
42
|
if (node.kind === "async-boundary") {
|
|
39
43
|
return '""';
|
|
40
44
|
}
|
|
41
|
-
const attrs = node.attributes
|
|
45
|
+
const attrs = node.attributes
|
|
46
|
+
.map((attr) => emitOxcServerAttribute(node.tagName, attr))
|
|
47
|
+
.join(" + ");
|
|
42
48
|
const open = attrs === ""
|
|
43
49
|
? JSON.stringify(`<${node.tagName}>`)
|
|
44
50
|
: `${JSON.stringify(`<${node.tagName}`)} + ${attrs} + ">"`;
|
|
@@ -62,15 +68,45 @@ function emitOxcServerComponentProps(props, children) {
|
|
|
62
68
|
}
|
|
63
69
|
return `{ ${entries.join(", ")} }`;
|
|
64
70
|
}
|
|
65
|
-
function emitOxcServerAttribute(attr) {
|
|
71
|
+
function emitOxcServerAttribute(tagName, attr) {
|
|
72
|
+
if (attr.kind === "spread-attr" || attr.kind === "event") {
|
|
73
|
+
return '""';
|
|
74
|
+
}
|
|
75
|
+
if (attr.name === "key" || attr.name === "dangerouslySetInnerHTML") {
|
|
76
|
+
return '""';
|
|
77
|
+
}
|
|
78
|
+
const htmlName = htmlAttributeNameForElement(tagName, attr.name);
|
|
66
79
|
if (attr.kind === "static-attr") {
|
|
67
|
-
|
|
80
|
+
if (isUrlAttribute(htmlName) && isStaticUrlValueUnsafe(htmlName, attr.value)) {
|
|
81
|
+
return '""';
|
|
82
|
+
}
|
|
83
|
+
if (isDangerousHtmlAttribute(htmlName)) {
|
|
84
|
+
return '""';
|
|
85
|
+
}
|
|
86
|
+
return JSON.stringify(` ${htmlName}="${escapeHtmlAttribute(attr.value)}"`);
|
|
68
87
|
}
|
|
69
88
|
if (attr.kind === "dynamic-attr") {
|
|
70
|
-
|
|
89
|
+
if (isDangerousHtmlAttribute(htmlName)) {
|
|
90
|
+
return `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return ""; if (typeof _value === "object" && _value !== null && typeof _value.__html === "string") return ${JSON.stringify(` ${htmlName}="`)} + _escapeHtml(_value.__html) + ${JSON.stringify('"')}; return ""; })()`;
|
|
91
|
+
}
|
|
92
|
+
if (isUrlAttribute(htmlName)) {
|
|
93
|
+
return `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return ""; const _checked = ${currentOxcServerStringUrlSafeHelperName}(${JSON.stringify(htmlName)}, _value === true ? "" : _value); return _checked === undefined ? "" : ${JSON.stringify(` ${htmlName}="`)} + _escapeHtml(_checked) + ${JSON.stringify('"')}; })()`;
|
|
94
|
+
}
|
|
95
|
+
return `${JSON.stringify(` ${htmlName}="`)} + _escapeHtml(${attr.code}) + ${JSON.stringify('"')}`;
|
|
71
96
|
}
|
|
72
97
|
return '""';
|
|
73
98
|
}
|
|
99
|
+
function htmlAttributeNameForElement(tagName, name) {
|
|
100
|
+
if (tagName === "input") {
|
|
101
|
+
if (name === "defaultValue") {
|
|
102
|
+
return "value";
|
|
103
|
+
}
|
|
104
|
+
if (name === "defaultChecked") {
|
|
105
|
+
return "checked";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return htmlAttributeName(name);
|
|
109
|
+
}
|
|
74
110
|
function emitOxcCompatObjectNode(node) {
|
|
75
111
|
if (node.kind === "text") {
|
|
76
112
|
return JSON.stringify(node.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxc-runtime-emit.js","sourceRoot":"","sources":["../src/oxc-runtime-emit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AttributeIr, ComponentPropIr, JsxNodeIr } from \"./ir.js\";\nimport { isVoidHtmlElement } from \"./emit-server-shared.js\";\nimport { escapeHtmlAttribute } from \"@reckona/mreact-shared/html-escape\";\n\nexport const oxcServerStringReactNodeRenderHelperPlaceholder =\n \"__mreactRenderReactNodeToString\";\n\nexport function emitOxcServerStringChildren(children: readonly JsxNodeIr[]): string {\n if (children.length === 0) {\n return '\"\"';\n }\n\n return children.map(emitOxcServerStringNode).join(\" + \");\n}\n\nfunction emitOxcServerStringNode(node: JsxNodeIr): string {\n if (node.kind === \"text\") {\n return JSON.stringify(node.value);\n }\n\n if (node.kind === \"expr\") {\n return `_escapeHtml(${node.code})`;\n }\n\n if (node.kind === \"conditional\") {\n const whenTrue = emitOxcServerStringChildren(node.whenTrue);\n const whenFalse = emitOxcServerStringChildren(node.whenFalse);\n\n return node.conditionValueName === undefined\n ? `((${node.conditionCode}) ? ${whenTrue} : ${whenFalse})`\n : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;\n }\n\n if (node.kind === \"list\") {\n const parameters = emitOxcListParameters(node);\n return `(${node.itemsCode}).map((${parameters}) => ${emitOxcServerStringChildren(node.children)}).join(\"\")`;\n }\n\n if (node.kind === \"fragment\") {\n return emitOxcServerStringChildren(node.children);\n }\n\n if (node.kind === \"component\") {\n const props = emitOxcServerComponentProps(node.props, node.children);\n if (node.runtime === \"compat\") {\n return `${oxcServerStringReactNodeRenderHelperPlaceholder}(${node.name}, ${props})`;\n }\n return `${node.name}(${props})`;\n }\n\n if (node.kind === \"async-boundary\") {\n return '\"\"';\n }\n\n const attrs = node.attributes.map(emitOxcServerAttribute).join(\" + \");\n const open =\n attrs === \"\"\n ? JSON.stringify(`<${node.tagName}>`)\n : `${JSON.stringify(`<${node.tagName}`)} + ${attrs} + \">\"`;\n if (isVoidHtmlElement(node.tagName)) {\n return open;\n }\n\n return `${open} + ${emitOxcServerStringChildren(node.children)} + ${JSON.stringify(`</${node.tagName}>`)}`;\n}\n\nfunction emitOxcServerComponentProps(\n props: readonly ComponentPropIr[],\n children: readonly JsxNodeIr[],\n): string {\n const entries = props.map((prop) => {\n if (prop.kind === \"spread-prop\") {\n return `...(${prop.code})`;\n }\n\n if (prop.kind === \"render-prop\") {\n return `${emitOxcCompatObjectPropName(prop.name)}: ${emitOxcServerStringChildren(prop.children)}`;\n }\n\n return `${emitOxcCompatObjectPropName(prop.name)}: (${prop.code})`;\n });\n\n if (children.length > 0) {\n entries.push(`children: ${emitOxcServerStringChildren(children)}`);\n }\n\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction emitOxcServerAttribute(attr: AttributeIr): string {\n if (attr.kind === \"static-attr\") {\n return JSON.stringify(` ${attr.name}=\"${escapeHtmlAttribute(attr.value)}\"`);\n }\n\n if (attr.kind === \"dynamic-attr\") {\n return `${JSON.stringify(` ${attr.name}=\"`)} + _escapeHtml(${attr.code}) + ${JSON.stringify('\"')}`;\n }\n\n return '\"\"';\n}\n\nfunction emitOxcCompatObjectNode(node: JsxNodeIr): string {\n if (node.kind === \"text\") {\n return JSON.stringify(node.value);\n }\n\n if (node.kind === \"expr\") {\n return `(${node.code})`;\n }\n\n if (node.kind === \"conditional\") {\n const whenTrue = emitOxcCompatObjectChildren(node.whenTrue);\n const whenFalse = emitOxcCompatObjectChildren(node.whenFalse);\n\n return node.conditionValueName === undefined\n ? `(${node.conditionCode}) ? ${whenTrue} : ${whenFalse}`\n : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;\n }\n\n if (node.kind === \"list\") {\n const parameters = emitOxcListParameters(node);\n return `(${node.itemsCode}).map((${parameters}) => ${emitOxcCompatObjectChildren(node.children)})`;\n }\n\n if (node.kind === \"fragment\") {\n return emitOxcCompatObjectElement('Symbol.for(\"react.fragment\")', [], node.children);\n }\n\n if (node.kind === \"component\") {\n return emitOxcCompatObjectElement(\n node.name,\n node.props.map(emitOxcCompatObjectComponentProp),\n node.children,\n node.keyCode,\n );\n }\n\n if (node.kind === \"async-boundary\") {\n return \"null\";\n }\n\n return emitOxcCompatObjectElement(\n JSON.stringify(node.tagName),\n node.attributes.map(emitOxcCompatObjectAttribute),\n node.children,\n node.keyCode,\n );\n}\n\nexport function emitOxcCompatObjectChildren(children: readonly JsxNodeIr[]): string {\n if (children.length === 0) {\n return \"null\";\n }\n\n if (children.length === 1) {\n return emitOxcCompatObjectNode(children[0] as JsxNodeIr);\n }\n\n return `[${children.map(emitOxcCompatObjectNode).join(\", \")}]`;\n}\n\nfunction emitOxcCompatObjectElement(\n typeCode: string,\n propEntries: readonly string[],\n children: readonly JsxNodeIr[],\n explicitKeyCode?: string,\n): string {\n const entries = [...propEntries];\n\n if (children.length > 0) {\n entries.push(`children: ${emitOxcCompatObjectChildren(children)}`);\n }\n\n const keyExpression =\n explicitKeyCode === undefined\n ? \"_props.key === undefined ? null : String(_props.key)\"\n : `String(${explicitKeyCode})`;\n\n return [\n \"(() => {\",\n ` const _props = { ${entries.join(\", \")} };`,\n ` const _key = ${keyExpression};`,\n \" const _ref = _props.ref ?? null;\",\n \" delete _props.key;\",\n \" delete _props.ref;\",\n ' return { $$typeof: Symbol.for(\"react.transitional.element\"),',\n ` type: ${typeCode},`,\n \" key: _key,\",\n \" ref: _ref,\",\n \" props: _props };\",\n \"})()\",\n ].join(\"\\n\");\n}\n\nfunction emitOxcListParameters(node: Extract<JsxNodeIr, { kind: \"list\" }>): string {\n return [node.itemName, node.indexName, node.arrayName]\n .filter((name): name is string => name !== undefined)\n .join(\", \");\n}\n\nfunction emitOxcCompatObjectAttribute(attr: AttributeIr): string {\n if (attr.kind === \"spread-attr\") {\n return `...(${attr.code})`;\n }\n\n if (attr.kind === \"static-attr\") {\n return `${emitOxcCompatObjectPropName(attr.name)}: ${JSON.stringify(attr.value)}`;\n }\n\n if (attr.kind === \"dynamic-attr\") {\n return `${emitOxcCompatObjectPropName(attr.name)}: (${attr.code})`;\n }\n\n return `${emitOxcCompatObjectPropName(attr.name)}: ${attr.code}`;\n}\n\nfunction emitOxcCompatObjectComponentProp(prop: ComponentPropIr): string {\n if (prop.kind === \"spread-prop\") {\n return `...(${prop.code})`;\n }\n\n if (prop.kind === \"render-prop\") {\n return `${emitOxcCompatObjectPropName(prop.name)}: ${emitOxcCompatObjectChildren(prop.children)}`;\n }\n\n return `${emitOxcCompatObjectPropName(prop.name)}: (${prop.code})`;\n}\n\nfunction emitOxcCompatObjectPropName(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"oxc-runtime-emit.js","sourceRoot":"","sources":["../src/oxc-runtime-emit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AttributeIr, ComponentPropIr, JsxNodeIr } from \"./ir.js\";\nimport {\n htmlAttributeName,\n isDangerousHtmlAttribute,\n isStaticUrlValueUnsafe,\n isUrlAttribute,\n isVoidHtmlElement,\n} from \"./emit-server-shared.js\";\nimport { escapeHtmlAttribute } from \"@reckona/mreact-shared/html-escape\";\n\nexport const oxcServerStringReactNodeRenderHelperPlaceholder =\n \"__mreactRenderReactNodeToString\";\n\nlet currentOxcServerStringUrlSafeHelperName = \"_urlAttrSafe\";\n\nexport function setOxcServerStringUrlSafeHelperName(name: string): void {\n currentOxcServerStringUrlSafeHelperName = name;\n}\n\nexport function emitOxcServerStringChildren(children: readonly JsxNodeIr[]): string {\n if (children.length === 0) {\n return '\"\"';\n }\n\n return children.map(emitOxcServerStringNode).join(\" + \");\n}\n\nfunction emitOxcServerStringNode(node: JsxNodeIr): string {\n if (node.kind === \"text\") {\n return JSON.stringify(node.value);\n }\n\n if (node.kind === \"expr\") {\n return `_escapeHtml(${node.code})`;\n }\n\n if (node.kind === \"conditional\") {\n const whenTrue = emitOxcServerStringChildren(node.whenTrue);\n const whenFalse = emitOxcServerStringChildren(node.whenFalse);\n\n return node.conditionValueName === undefined\n ? `((${node.conditionCode}) ? ${whenTrue} : ${whenFalse})`\n : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;\n }\n\n if (node.kind === \"list\") {\n const parameters = emitOxcListParameters(node);\n return `(${node.itemsCode}).map((${parameters}) => ${emitOxcServerStringChildren(node.children)}).join(\"\")`;\n }\n\n if (node.kind === \"fragment\") {\n return emitOxcServerStringChildren(node.children);\n }\n\n if (node.kind === \"component\") {\n const props = emitOxcServerComponentProps(node.props, node.children);\n if (node.runtime === \"compat\") {\n return `${oxcServerStringReactNodeRenderHelperPlaceholder}(${node.name}, ${props})`;\n }\n return `${node.name}(${props})`;\n }\n\n if (node.kind === \"async-boundary\") {\n return '\"\"';\n }\n\n const attrs = node.attributes\n .map((attr) => emitOxcServerAttribute(node.tagName, attr))\n .join(\" + \");\n const open =\n attrs === \"\"\n ? JSON.stringify(`<${node.tagName}>`)\n : `${JSON.stringify(`<${node.tagName}`)} + ${attrs} + \">\"`;\n if (isVoidHtmlElement(node.tagName)) {\n return open;\n }\n\n return `${open} + ${emitOxcServerStringChildren(node.children)} + ${JSON.stringify(`</${node.tagName}>`)}`;\n}\n\nfunction emitOxcServerComponentProps(\n props: readonly ComponentPropIr[],\n children: readonly JsxNodeIr[],\n): string {\n const entries = props.map((prop) => {\n if (prop.kind === \"spread-prop\") {\n return `...(${prop.code})`;\n }\n\n if (prop.kind === \"render-prop\") {\n return `${emitOxcCompatObjectPropName(prop.name)}: ${emitOxcServerStringChildren(prop.children)}`;\n }\n\n return `${emitOxcCompatObjectPropName(prop.name)}: (${prop.code})`;\n });\n\n if (children.length > 0) {\n entries.push(`children: ${emitOxcServerStringChildren(children)}`);\n }\n\n return `{ ${entries.join(\", \")} }`;\n}\n\nfunction emitOxcServerAttribute(tagName: string, attr: AttributeIr): string {\n if (attr.kind === \"spread-attr\" || attr.kind === \"event\") {\n return '\"\"';\n }\n\n if (attr.name === \"key\" || attr.name === \"dangerouslySetInnerHTML\") {\n return '\"\"';\n }\n\n const htmlName = htmlAttributeNameForElement(tagName, attr.name);\n\n if (attr.kind === \"static-attr\") {\n if (isUrlAttribute(htmlName) && isStaticUrlValueUnsafe(htmlName, attr.value)) {\n return '\"\"';\n }\n\n if (isDangerousHtmlAttribute(htmlName)) {\n return '\"\"';\n }\n\n return JSON.stringify(` ${htmlName}=\"${escapeHtmlAttribute(attr.value)}\"`);\n }\n\n if (attr.kind === \"dynamic-attr\") {\n if (isDangerousHtmlAttribute(htmlName)) {\n return `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return \"\"; if (typeof _value === \"object\" && _value !== null && typeof _value.__html === \"string\") return ${JSON.stringify(` ${htmlName}=\"`)} + _escapeHtml(_value.__html) + ${JSON.stringify('\"')}; return \"\"; })()`;\n }\n\n if (isUrlAttribute(htmlName)) {\n return `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return \"\"; const _checked = ${currentOxcServerStringUrlSafeHelperName}(${JSON.stringify(htmlName)}, _value === true ? \"\" : _value); return _checked === undefined ? \"\" : ${JSON.stringify(` ${htmlName}=\"`)} + _escapeHtml(_checked) + ${JSON.stringify('\"')}; })()`;\n }\n\n return `${JSON.stringify(` ${htmlName}=\"`)} + _escapeHtml(${attr.code}) + ${JSON.stringify('\"')}`;\n }\n\n return '\"\"';\n}\n\nfunction htmlAttributeNameForElement(tagName: string, name: string): string {\n if (tagName === \"input\") {\n if (name === \"defaultValue\") {\n return \"value\";\n }\n\n if (name === \"defaultChecked\") {\n return \"checked\";\n }\n }\n\n return htmlAttributeName(name);\n}\n\nfunction emitOxcCompatObjectNode(node: JsxNodeIr): string {\n if (node.kind === \"text\") {\n return JSON.stringify(node.value);\n }\n\n if (node.kind === \"expr\") {\n return `(${node.code})`;\n }\n\n if (node.kind === \"conditional\") {\n const whenTrue = emitOxcCompatObjectChildren(node.whenTrue);\n const whenFalse = emitOxcCompatObjectChildren(node.whenFalse);\n\n return node.conditionValueName === undefined\n ? `(${node.conditionCode}) ? ${whenTrue} : ${whenFalse}`\n : `(() => { const ${node.conditionValueName} = (${node.conditionCode}); return ${node.conditionValueName} ? ${whenTrue} : ${whenFalse}; })()`;\n }\n\n if (node.kind === \"list\") {\n const parameters = emitOxcListParameters(node);\n return `(${node.itemsCode}).map((${parameters}) => ${emitOxcCompatObjectChildren(node.children)})`;\n }\n\n if (node.kind === \"fragment\") {\n return emitOxcCompatObjectElement('Symbol.for(\"react.fragment\")', [], node.children);\n }\n\n if (node.kind === \"component\") {\n return emitOxcCompatObjectElement(\n node.name,\n node.props.map(emitOxcCompatObjectComponentProp),\n node.children,\n node.keyCode,\n );\n }\n\n if (node.kind === \"async-boundary\") {\n return \"null\";\n }\n\n return emitOxcCompatObjectElement(\n JSON.stringify(node.tagName),\n node.attributes.map(emitOxcCompatObjectAttribute),\n node.children,\n node.keyCode,\n );\n}\n\nexport function emitOxcCompatObjectChildren(children: readonly JsxNodeIr[]): string {\n if (children.length === 0) {\n return \"null\";\n }\n\n if (children.length === 1) {\n return emitOxcCompatObjectNode(children[0] as JsxNodeIr);\n }\n\n return `[${children.map(emitOxcCompatObjectNode).join(\", \")}]`;\n}\n\nfunction emitOxcCompatObjectElement(\n typeCode: string,\n propEntries: readonly string[],\n children: readonly JsxNodeIr[],\n explicitKeyCode?: string,\n): string {\n const entries = [...propEntries];\n\n if (children.length > 0) {\n entries.push(`children: ${emitOxcCompatObjectChildren(children)}`);\n }\n\n const keyExpression =\n explicitKeyCode === undefined\n ? \"_props.key === undefined ? null : String(_props.key)\"\n : `String(${explicitKeyCode})`;\n\n return [\n \"(() => {\",\n ` const _props = { ${entries.join(\", \")} };`,\n ` const _key = ${keyExpression};`,\n \" const _ref = _props.ref ?? null;\",\n \" delete _props.key;\",\n \" delete _props.ref;\",\n ' return { $$typeof: Symbol.for(\"react.transitional.element\"),',\n ` type: ${typeCode},`,\n \" key: _key,\",\n \" ref: _ref,\",\n \" props: _props };\",\n \"})()\",\n ].join(\"\\n\");\n}\n\nfunction emitOxcListParameters(node: Extract<JsxNodeIr, { kind: \"list\" }>): string {\n return [node.itemName, node.indexName, node.arrayName]\n .filter((name): name is string => name !== undefined)\n .join(\", \");\n}\n\nfunction emitOxcCompatObjectAttribute(attr: AttributeIr): string {\n if (attr.kind === \"spread-attr\") {\n return `...(${attr.code})`;\n }\n\n if (attr.kind === \"static-attr\") {\n return `${emitOxcCompatObjectPropName(attr.name)}: ${JSON.stringify(attr.value)}`;\n }\n\n if (attr.kind === \"dynamic-attr\") {\n return `${emitOxcCompatObjectPropName(attr.name)}: (${attr.code})`;\n }\n\n return `${emitOxcCompatObjectPropName(attr.name)}: ${attr.code}`;\n}\n\nfunction emitOxcCompatObjectComponentProp(prop: ComponentPropIr): string {\n if (prop.kind === \"spread-prop\") {\n return `...(${prop.code})`;\n }\n\n if (prop.kind === \"render-prop\") {\n return `${emitOxcCompatObjectPropName(prop.name)}: ${emitOxcCompatObjectChildren(prop.children)}`;\n }\n\n return `${emitOxcCompatObjectPropName(prop.name)}: (${prop.code})`;\n}\n\nfunction emitOxcCompatObjectPropName(name: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(name) ? name : JSON.stringify(name);\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxc-transform.d.ts","sourceRoot":"","sources":["../src/oxc-transform.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"oxc-transform.d.ts","sourceRoot":"","sources":["../src/oxc-transform.ts"],"names":[],"mappings":"AAKA,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0B7D;AAyBD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmB1D;AAED,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBzE"}
|
package/dist/oxc-transform.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { transformSync } from "oxc-transform";
|
|
2
|
+
const stripTypeScriptCache = new Map();
|
|
3
|
+
const stripTypeScriptCacheLimit = 512;
|
|
2
4
|
export function stripTypeScriptWithOxc(source) {
|
|
3
5
|
if (!needsTypeScriptStripping(source)) {
|
|
4
6
|
return source.trimEnd();
|
|
5
7
|
}
|
|
8
|
+
const cached = stripTypeScriptCache.get(source);
|
|
9
|
+
if (cached !== undefined) {
|
|
10
|
+
return cached;
|
|
11
|
+
}
|
|
6
12
|
const result = transformSync("snippet.tsx", source, {
|
|
7
13
|
lang: "tsx",
|
|
8
14
|
sourceType: "module",
|
|
@@ -12,10 +18,18 @@ export function stripTypeScriptWithOxc(source) {
|
|
|
12
18
|
onlyRemoveTypeImports: true,
|
|
13
19
|
},
|
|
14
20
|
});
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
const stripped = result.errors.length > 0 ? source.trimEnd() : result.code.trimEnd();
|
|
22
|
+
rememberStrippedTypeScript(source, stripped);
|
|
23
|
+
return stripped;
|
|
24
|
+
}
|
|
25
|
+
function rememberStrippedTypeScript(source, stripped) {
|
|
26
|
+
if (stripTypeScriptCache.size >= stripTypeScriptCacheLimit) {
|
|
27
|
+
const first = stripTypeScriptCache.keys().next().value;
|
|
28
|
+
if (first !== undefined) {
|
|
29
|
+
stripTypeScriptCache.delete(first);
|
|
30
|
+
}
|
|
17
31
|
}
|
|
18
|
-
|
|
32
|
+
stripTypeScriptCache.set(source, stripped);
|
|
19
33
|
}
|
|
20
34
|
function needsTypeScriptStripping(source) {
|
|
21
35
|
return (/\bimport\s+type\b/.test(source) ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oxc-transform.js","sourceRoot":"","sources":["../src/oxc-transform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,UAAU,sBAAsB,CAAC,MAAc;IACnD,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE;QAClD,IAAI,EAAE,KAAK;QACX,UAAU,EAAE,QAAQ;QACpB,MAAM,EAAE,QAAQ;QAChB,GAAG,EAAE,UAAU;QACf,UAAU,EAAE;YACV,qBAAqB,EAAE,IAAI;SAC5B;KACF,CAAC,CAAC;IAEH,
|
|
1
|
+
{"version":3,"file":"oxc-transform.js","sourceRoot":"","sources":["../src/oxc-transform.ts"],"names":[],"mappings":"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","sourcesContent":["import { transformSync } from \"oxc-transform\";\n\nconst stripTypeScriptCache = new Map<string, string>();\nconst stripTypeScriptCacheLimit = 512;\n\nexport function stripTypeScriptWithOxc(source: string): string {\n if (!needsTypeScriptStripping(source)) {\n return source.trimEnd();\n }\n\n const cached = stripTypeScriptCache.get(source);\n\n if (cached !== undefined) {\n return cached;\n }\n\n const result = transformSync(\"snippet.tsx\", source, {\n lang: \"tsx\",\n sourceType: \"module\",\n target: \"es2022\",\n jsx: \"preserve\",\n typescript: {\n onlyRemoveTypeImports: true,\n },\n });\n\n const stripped = result.errors.length > 0 ? source.trimEnd() : result.code.trimEnd();\n\n rememberStrippedTypeScript(source, stripped);\n\n return stripped;\n}\n\nfunction rememberStrippedTypeScript(source: string, stripped: string): void {\n if (stripTypeScriptCache.size >= stripTypeScriptCacheLimit) {\n const first = stripTypeScriptCache.keys().next().value;\n\n if (first !== undefined) {\n stripTypeScriptCache.delete(first);\n }\n }\n\n stripTypeScriptCache.set(source, stripped);\n}\n\nfunction needsTypeScriptStripping(source: string): boolean {\n return (\n /\\bimport\\s+type\\b/.test(source) ||\n /\\btype\\s+[A-Za-z_$][\\w$]*\\b/.test(source) ||\n /\\binterface\\s+[A-Za-z_$][\\w$]*\\b/.test(source) ||\n /\\b[A-Za-z_$][\\w$.]*\\s*<[^>\\n]+>\\s*\\(/.test(source) ||\n /\\bas\\s+(?:const|[A-Za-z_$][\\w$]*)\\b/.test(source) ||\n /:\\s*[A-Za-z_$][\\w$<>,\\s|&.[\\]?]*(?=[,)=;{])/.test(source)\n );\n}\n\nexport function transformJsxWithOxc(source: string): string {\n const result = transformSync(\"snippet.tsx\", source, {\n lang: \"tsx\",\n sourceType: \"module\",\n target: \"es2022\",\n jsx: {\n runtime: \"automatic\",\n importSource: \"@reckona/mreact-compat\",\n },\n typescript: {\n onlyRemoveTypeImports: true,\n },\n });\n\n if (result.errors.length > 0 && result.code === \"\") {\n return stripTypeScriptWithOxc(source);\n }\n\n return result.code.trimEnd();\n}\n\nexport function transformJsxToCreateElementWithOxc(source: string): string {\n const result = transformSync(\"snippet.tsx\", source, {\n lang: \"tsx\",\n sourceType: \"module\",\n target: \"es2022\",\n jsx: {\n runtime: \"classic\",\n pragma: \"createElement\",\n pragmaFrag: \"Fragment\",\n },\n typescript: {\n onlyRemoveTypeImports: true,\n },\n });\n\n if (result.errors.length > 0 && result.code === \"\") {\n return stripTypeScriptWithOxc(source);\n }\n\n return result.code.trimEnd();\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reckona/mreact-compiler",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.140",
|
|
4
4
|
"description": "Compiler passes and OXC-backed JSX analysis for mreact.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"compiler",
|
|
@@ -50,6 +50,6 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"oxc-parser": "0.129.0",
|
|
52
52
|
"oxc-transform": "0.129.0",
|
|
53
|
-
"@reckona/mreact-shared": "0.0.
|
|
53
|
+
"@reckona/mreact-shared": "0.0.140"
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
import {
|
|
31
31
|
emitOxcCompatObjectChildren,
|
|
32
32
|
oxcServerStringReactNodeRenderHelperPlaceholder,
|
|
33
|
+
setOxcServerStringUrlSafeHelperName,
|
|
33
34
|
} from "./oxc-runtime-emit.js";
|
|
34
35
|
|
|
35
36
|
export interface EmitServerStreamResult {
|
|
@@ -84,6 +85,7 @@ export function emitServerStream(
|
|
|
84
85
|
const spreadAttributesHelperName = allocateHelperName(ir, "_renderSpreadAttributes");
|
|
85
86
|
const urlSafeHelperName = allocateHelperName(ir, "_urlAttrSafe");
|
|
86
87
|
currentUrlSafeHelperName = urlSafeHelperName;
|
|
88
|
+
setOxcServerStringUrlSafeHelperName(urlSafeHelperName);
|
|
87
89
|
currentClientBoundaryHelperName = clientBoundaryHelperName;
|
|
88
90
|
currentSpreadAttributesHelperName = spreadAttributesHelperName;
|
|
89
91
|
currentStreamNodeHelperName = streamNodeHelperName;
|
package/src/emit-server.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
emitOxcCompatObjectChildren,
|
|
19
19
|
oxcServerStringReactNodeRenderHelperPlaceholder,
|
|
20
|
+
setOxcServerStringUrlSafeHelperName,
|
|
20
21
|
} from "./oxc-runtime-emit.js";
|
|
21
22
|
|
|
22
23
|
export interface EmitResult {
|
|
@@ -57,6 +58,7 @@ export function emitServer(ir: ModuleIr, options: EmitServerOptions = {}): EmitR
|
|
|
57
58
|
const outAccumulatorName = allocateHelperName(ir, "_out");
|
|
58
59
|
const urlSafeHelperName = allocateHelperName(ir, "_urlAttrSafe");
|
|
59
60
|
currentUrlSafeHelperName = urlSafeHelperName;
|
|
61
|
+
setOxcServerStringUrlSafeHelperName(urlSafeHelperName);
|
|
60
62
|
currentClientBoundaryHelperName = clientBoundaryHelperName;
|
|
61
63
|
currentSpreadAttributesHelperName = spreadAttributesHelperName;
|
|
62
64
|
const helper = emitEscapeHtmlHelper(escapeHelperName);
|
package/src/internal.ts
CHANGED
|
@@ -1060,8 +1060,33 @@ interface Replacement {
|
|
|
1060
1060
|
text: string;
|
|
1061
1061
|
}
|
|
1062
1062
|
|
|
1063
|
+
const parseModuleCache = new Map<string, CompilerModuleContext>();
|
|
1064
|
+
const parseModuleCacheLimit = 128;
|
|
1065
|
+
|
|
1063
1066
|
function parseModule(code: string, filename: string | undefined) {
|
|
1064
|
-
|
|
1067
|
+
const cacheKey = `${filename ?? ""}\0${code}`;
|
|
1068
|
+
const cached = parseModuleCache.get(cacheKey);
|
|
1069
|
+
|
|
1070
|
+
if (cached !== undefined) {
|
|
1071
|
+
return parseModuleContext(cached);
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
const parsed = createCompilerModuleContext({ code, filename });
|
|
1075
|
+
rememberParsedModule(cacheKey, parsed);
|
|
1076
|
+
|
|
1077
|
+
return parseModuleContext(parsed);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
function rememberParsedModule(cacheKey: string, context: CompilerModuleContext): void {
|
|
1081
|
+
if (parseModuleCache.size >= parseModuleCacheLimit) {
|
|
1082
|
+
const first = parseModuleCache.keys().next().value;
|
|
1083
|
+
|
|
1084
|
+
if (first !== undefined) {
|
|
1085
|
+
parseModuleCache.delete(first);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
parseModuleCache.set(cacheKey, context);
|
|
1065
1090
|
}
|
|
1066
1091
|
|
|
1067
1092
|
function parseModuleContext(context: CompilerModuleContext): CompilerModuleContext {
|
package/src/oxc-node-utils.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { SourceLocation } from "./types.js";
|
|
2
2
|
|
|
3
|
+
const lineStartCache = new Map<string, readonly number[]>();
|
|
4
|
+
const lineStartCacheLimit = 128;
|
|
5
|
+
|
|
3
6
|
export function readObject(value: unknown): Record<string, unknown> {
|
|
4
7
|
return typeof value === "object" && value !== null ? (value as Record<string, unknown>) : {};
|
|
5
8
|
}
|
|
@@ -45,19 +48,63 @@ export function getOxcLocationFromOffset(
|
|
|
45
48
|
return undefined;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const lineStarts = getLineStarts(code);
|
|
52
|
+
const lineIndex = findLineStartIndex(lineStarts, start);
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
line: lineIndex + 1,
|
|
56
|
+
column: start - (lineStarts[lineIndex] ?? 0) + 1,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function getLineStarts(code: string): readonly number[] {
|
|
61
|
+
const cached = lineStartCache.get(code);
|
|
62
|
+
|
|
63
|
+
if (cached !== undefined) {
|
|
64
|
+
return cached;
|
|
65
|
+
}
|
|
50
66
|
|
|
51
|
-
|
|
67
|
+
const starts = [0];
|
|
68
|
+
|
|
69
|
+
for (let index = 0; index < code.length; index += 1) {
|
|
52
70
|
if (code[index] === "\n") {
|
|
53
|
-
|
|
54
|
-
|
|
71
|
+
starts.push(index + 1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
rememberLineStarts(code, starts);
|
|
76
|
+
|
|
77
|
+
return starts;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function rememberLineStarts(code: string, starts: readonly number[]): void {
|
|
81
|
+
if (lineStartCache.size >= lineStartCacheLimit) {
|
|
82
|
+
const first = lineStartCache.keys().next().value;
|
|
83
|
+
|
|
84
|
+
if (first !== undefined) {
|
|
85
|
+
lineStartCache.delete(first);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
lineStartCache.set(code, starts);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function findLineStartIndex(lineStarts: readonly number[], offset: number): number {
|
|
93
|
+
let low = 0;
|
|
94
|
+
let high = lineStarts.length - 1;
|
|
95
|
+
|
|
96
|
+
while (low <= high) {
|
|
97
|
+
const middle = Math.floor((low + high) / 2);
|
|
98
|
+
const lineStart = lineStarts[middle] ?? 0;
|
|
99
|
+
|
|
100
|
+
if (lineStart <= offset) {
|
|
101
|
+
low = middle + 1;
|
|
55
102
|
} else {
|
|
56
|
-
|
|
103
|
+
high = middle - 1;
|
|
57
104
|
}
|
|
58
105
|
}
|
|
59
106
|
|
|
60
|
-
return
|
|
107
|
+
return Math.max(0, low - 1);
|
|
61
108
|
}
|
|
62
109
|
|
|
63
110
|
export function arraysEqual(left: readonly string[], right: readonly string[]): boolean {
|
package/src/oxc-runtime-emit.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import type { AttributeIr, ComponentPropIr, JsxNodeIr } from "./ir.js";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
htmlAttributeName,
|
|
4
|
+
isDangerousHtmlAttribute,
|
|
5
|
+
isStaticUrlValueUnsafe,
|
|
6
|
+
isUrlAttribute,
|
|
7
|
+
isVoidHtmlElement,
|
|
8
|
+
} from "./emit-server-shared.js";
|
|
3
9
|
import { escapeHtmlAttribute } from "@reckona/mreact-shared/html-escape";
|
|
4
10
|
|
|
5
11
|
export const oxcServerStringReactNodeRenderHelperPlaceholder =
|
|
6
12
|
"__mreactRenderReactNodeToString";
|
|
7
13
|
|
|
14
|
+
let currentOxcServerStringUrlSafeHelperName = "_urlAttrSafe";
|
|
15
|
+
|
|
16
|
+
export function setOxcServerStringUrlSafeHelperName(name: string): void {
|
|
17
|
+
currentOxcServerStringUrlSafeHelperName = name;
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
export function emitOxcServerStringChildren(children: readonly JsxNodeIr[]): string {
|
|
9
21
|
if (children.length === 0) {
|
|
10
22
|
return '""';
|
|
@@ -52,7 +64,9 @@ function emitOxcServerStringNode(node: JsxNodeIr): string {
|
|
|
52
64
|
return '""';
|
|
53
65
|
}
|
|
54
66
|
|
|
55
|
-
const attrs = node.attributes
|
|
67
|
+
const attrs = node.attributes
|
|
68
|
+
.map((attr) => emitOxcServerAttribute(node.tagName, attr))
|
|
69
|
+
.join(" + ");
|
|
56
70
|
const open =
|
|
57
71
|
attrs === ""
|
|
58
72
|
? JSON.stringify(`<${node.tagName}>`)
|
|
@@ -87,18 +101,58 @@ function emitOxcServerComponentProps(
|
|
|
87
101
|
return `{ ${entries.join(", ")} }`;
|
|
88
102
|
}
|
|
89
103
|
|
|
90
|
-
function emitOxcServerAttribute(attr: AttributeIr): string {
|
|
104
|
+
function emitOxcServerAttribute(tagName: string, attr: AttributeIr): string {
|
|
105
|
+
if (attr.kind === "spread-attr" || attr.kind === "event") {
|
|
106
|
+
return '""';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (attr.name === "key" || attr.name === "dangerouslySetInnerHTML") {
|
|
110
|
+
return '""';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const htmlName = htmlAttributeNameForElement(tagName, attr.name);
|
|
114
|
+
|
|
91
115
|
if (attr.kind === "static-attr") {
|
|
92
|
-
|
|
116
|
+
if (isUrlAttribute(htmlName) && isStaticUrlValueUnsafe(htmlName, attr.value)) {
|
|
117
|
+
return '""';
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (isDangerousHtmlAttribute(htmlName)) {
|
|
121
|
+
return '""';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return JSON.stringify(` ${htmlName}="${escapeHtmlAttribute(attr.value)}"`);
|
|
93
125
|
}
|
|
94
126
|
|
|
95
127
|
if (attr.kind === "dynamic-attr") {
|
|
96
|
-
|
|
128
|
+
if (isDangerousHtmlAttribute(htmlName)) {
|
|
129
|
+
return `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return ""; if (typeof _value === "object" && _value !== null && typeof _value.__html === "string") return ${JSON.stringify(` ${htmlName}="`)} + _escapeHtml(_value.__html) + ${JSON.stringify('"')}; return ""; })()`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (isUrlAttribute(htmlName)) {
|
|
133
|
+
return `(() => { const _value = (${attr.code}); if (_value == null || _value === false) return ""; const _checked = ${currentOxcServerStringUrlSafeHelperName}(${JSON.stringify(htmlName)}, _value === true ? "" : _value); return _checked === undefined ? "" : ${JSON.stringify(` ${htmlName}="`)} + _escapeHtml(_checked) + ${JSON.stringify('"')}; })()`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return `${JSON.stringify(` ${htmlName}="`)} + _escapeHtml(${attr.code}) + ${JSON.stringify('"')}`;
|
|
97
137
|
}
|
|
98
138
|
|
|
99
139
|
return '""';
|
|
100
140
|
}
|
|
101
141
|
|
|
142
|
+
function htmlAttributeNameForElement(tagName: string, name: string): string {
|
|
143
|
+
if (tagName === "input") {
|
|
144
|
+
if (name === "defaultValue") {
|
|
145
|
+
return "value";
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (name === "defaultChecked") {
|
|
149
|
+
return "checked";
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return htmlAttributeName(name);
|
|
154
|
+
}
|
|
155
|
+
|
|
102
156
|
function emitOxcCompatObjectNode(node: JsxNodeIr): string {
|
|
103
157
|
if (node.kind === "text") {
|
|
104
158
|
return JSON.stringify(node.value);
|
package/src/oxc-transform.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { transformSync } from "oxc-transform";
|
|
2
2
|
|
|
3
|
+
const stripTypeScriptCache = new Map<string, string>();
|
|
4
|
+
const stripTypeScriptCacheLimit = 512;
|
|
5
|
+
|
|
3
6
|
export function stripTypeScriptWithOxc(source: string): string {
|
|
4
7
|
if (!needsTypeScriptStripping(source)) {
|
|
5
8
|
return source.trimEnd();
|
|
6
9
|
}
|
|
7
10
|
|
|
11
|
+
const cached = stripTypeScriptCache.get(source);
|
|
12
|
+
|
|
13
|
+
if (cached !== undefined) {
|
|
14
|
+
return cached;
|
|
15
|
+
}
|
|
16
|
+
|
|
8
17
|
const result = transformSync("snippet.tsx", source, {
|
|
9
18
|
lang: "tsx",
|
|
10
19
|
sourceType: "module",
|
|
@@ -15,11 +24,23 @@ export function stripTypeScriptWithOxc(source: string): string {
|
|
|
15
24
|
},
|
|
16
25
|
});
|
|
17
26
|
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
const stripped = result.errors.length > 0 ? source.trimEnd() : result.code.trimEnd();
|
|
28
|
+
|
|
29
|
+
rememberStrippedTypeScript(source, stripped);
|
|
30
|
+
|
|
31
|
+
return stripped;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function rememberStrippedTypeScript(source: string, stripped: string): void {
|
|
35
|
+
if (stripTypeScriptCache.size >= stripTypeScriptCacheLimit) {
|
|
36
|
+
const first = stripTypeScriptCache.keys().next().value;
|
|
37
|
+
|
|
38
|
+
if (first !== undefined) {
|
|
39
|
+
stripTypeScriptCache.delete(first);
|
|
40
|
+
}
|
|
20
41
|
}
|
|
21
42
|
|
|
22
|
-
|
|
43
|
+
stripTypeScriptCache.set(source, stripped);
|
|
23
44
|
}
|
|
24
45
|
|
|
25
46
|
function needsTypeScriptStripping(source: string): boolean {
|