@reckona/mreact-compiler 0.0.66 → 0.0.67

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reckona/mreact-compiler",
3
- "version": "0.0.66",
3
+ "version": "0.0.67",
4
4
  "description": "Compiler passes and OXC-backed JSX analysis for mreact.",
5
5
  "keywords": [
6
6
  "compiler",
@@ -24,7 +24,8 @@
24
24
  "dist/**/*.js",
25
25
  "dist/**/*.js.map",
26
26
  "dist/**/*.d.ts",
27
- "dist/**/*.d.ts.map"
27
+ "dist/**/*.d.ts.map",
28
+ "src/**/*"
28
29
  ],
29
30
  "type": "module",
30
31
  "sideEffects": false,
@@ -49,6 +50,6 @@
49
50
  "dependencies": {
50
51
  "oxc-parser": "0.129.0",
51
52
  "oxc-transform": "0.129.0",
52
- "@reckona/mreact-shared": "0.0.66"
53
+ "@reckona/mreact-shared": "0.0.67"
53
54
  }
54
55
  }
@@ -0,0 +1,31 @@
1
+ import { parseSync } from "oxc-parser";
2
+
3
+ export interface CompilerModuleContext {
4
+ code: string;
5
+ filename: string;
6
+ parseErrors: readonly unknown[];
7
+ program: unknown;
8
+ }
9
+
10
+ export function createCompilerModuleContextWithOxc(input: {
11
+ code: string;
12
+ filename?: string | undefined;
13
+ }): CompilerModuleContext {
14
+ const filename = input.filename ?? "module.tsx";
15
+ const parsed = parseSync(filename, input.code, {
16
+ astType: "ts",
17
+ lang: compilerModuleContextLanguage(filename),
18
+ sourceType: "module",
19
+ });
20
+
21
+ return {
22
+ code: input.code,
23
+ filename,
24
+ parseErrors: parsed.errors,
25
+ program: parsed.program,
26
+ };
27
+ }
28
+
29
+ function compilerModuleContextLanguage(filename: string): "ts" | "tsx" {
30
+ return /\.(?:cts|mts|ts)$/i.test(filename) ? "ts" : "tsx";
31
+ }
@@ -0,0 +1,184 @@
1
+ import type { Diagnostic, SourceLocation } from "./types.js";
2
+
3
+ export function formatDiagnostic(
4
+ filename: string,
5
+ diagnostic: Diagnostic,
6
+ ): string {
7
+ const loc =
8
+ diagnostic.loc === undefined
9
+ ? ""
10
+ : `:${diagnostic.loc.line}:${diagnostic.loc.column}`;
11
+ const suggestion =
12
+ diagnostic.suggestion === undefined
13
+ ? ""
14
+ : [
15
+ ` Suggestion: ${diagnostic.suggestion.title}`,
16
+ diagnostic.suggestion.replacement === undefined
17
+ ? ""
18
+ : ` Replacement: ${diagnostic.suggestion.replacement}`,
19
+ diagnostic.suggestion.link === undefined ? "" : ` See: ${diagnostic.suggestion.link}`,
20
+ ].join("");
21
+
22
+ return `${filename}${loc} [${diagnostic.code}] ${diagnostic.message}${suggestion}`;
23
+ }
24
+
25
+ export function unsupportedComponentReferenceDiagnostic(
26
+ name: string,
27
+ loc?: SourceLocation,
28
+ ): Diagnostic {
29
+ return {
30
+ level: "error",
31
+ code: "MR_UNSUPPORTED_COMPONENT_REFERENCE",
32
+ message: `Component reference '${name}' is not a supported same-module component.`,
33
+ ...(loc === undefined ? {} : { loc }),
34
+ };
35
+ }
36
+
37
+ export function unsupportedServerEventHandlerDiagnostic(
38
+ name: string,
39
+ loc?: SourceLocation,
40
+ ): Diagnostic {
41
+ return {
42
+ level: "error",
43
+ code: "MR_UNSUPPORTED_SERVER_EVENT_HANDLER",
44
+ message: `Event handler '${name}' cannot be emitted by the server target.`,
45
+ ...(loc === undefined ? {} : { loc }),
46
+ };
47
+ }
48
+
49
+ export function unsupportedServerDynamicAttributeDiagnostic(
50
+ name: string,
51
+ loc?: SourceLocation,
52
+ ): Diagnostic {
53
+ return {
54
+ level: "error",
55
+ code: "MR_UNSUPPORTED_SERVER_DYNAMIC_ATTRIBUTE",
56
+ message: `Dynamic attribute '${name}' cannot be emitted by the server target.`,
57
+ ...(loc === undefined ? {} : { loc }),
58
+ };
59
+ }
60
+
61
+ export function unsupportedRefAttributeDiagnostic(loc?: SourceLocation): Diagnostic {
62
+ return {
63
+ level: "error",
64
+ code: "MR_UNSUPPORTED_REF_ATTRIBUTE",
65
+ message:
66
+ "JSX ref attributes are only supported by compat client output. Server and reactive output cannot attach React-style refs yet.",
67
+ ...(loc === undefined ? {} : { loc }),
68
+ };
69
+ }
70
+
71
+ export function unsupportedCompatServerTargetDiagnostic(): Diagnostic {
72
+ return {
73
+ level: "error",
74
+ code: "MR_UNSUPPORTED_COMPAT_SERVER_TARGET",
75
+ message:
76
+ "Compat mode does not support server output yet. Use the reactive server output for server-rendered routes, or compile compat components for the client boundary.",
77
+ };
78
+ }
79
+
80
+ export function unsupportedAwaitInnerComponentDiagnostic(
81
+ name: string,
82
+ loc?: SourceLocation,
83
+ ): Diagnostic {
84
+ return {
85
+ level: "error",
86
+ code: "MR_UNSUPPORTED_AWAIT_INNER_COMPONENT",
87
+ message: `Component reference '${name}' cannot be emitted inside an <Await> renderer until compat boundary hydration lowering is implemented.`,
88
+ ...(loc === undefined ? {} : { loc }),
89
+ };
90
+ }
91
+
92
+ export function unsupportedNestedAwaitDiagnostic(loc?: SourceLocation): Diagnostic {
93
+ return {
94
+ level: "error",
95
+ code: "MR_UNSUPPORTED_NESTED_AWAIT",
96
+ message:
97
+ "Nested <Await> renderers are not supported by the server stream target yet. Move the inner <Await> outside the outer renderer or resolve the nested value before rendering.",
98
+ ...(loc === undefined ? {} : { loc }),
99
+ };
100
+ }
101
+
102
+ export function unserializableAwaitValueDiagnostic(
103
+ reason: string,
104
+ loc?: SourceLocation,
105
+ ): Diagnostic {
106
+ return {
107
+ level: "warn",
108
+ code: "MR_UNSERIALIZABLE_AWAIT_VALUE",
109
+ message:
110
+ `<Await value={...}> contains a non-JSON-serializable value (${reason}). ` +
111
+ `The wire format uses JSON.stringify, so the client-side renderer will receive a different shape ` +
112
+ `after the round-trip. Pass JSON-compatible data or serialize the value before it reaches <Await>. ` +
113
+ `See https://github.com/t-k/mreact#streaming-loading-and-await.`,
114
+ ...(loc === undefined ? {} : { loc }),
115
+ };
116
+ }
117
+
118
+ export function unsupportedBodyStatementJsxDiagnostic(
119
+ loc?: SourceLocation,
120
+ ): Diagnostic {
121
+ return {
122
+ level: "error",
123
+ code: "MR_UNSUPPORTED_BODY_STATEMENT_JSX",
124
+ message:
125
+ "JSX inside component body statements is not lowered yet. Move the JSX into the return tree or create it with runtime helpers.",
126
+ ...(loc === undefined ? {} : { loc }),
127
+ };
128
+ }
129
+
130
+ export function unsupportedTopLevelJsxInitializerDiagnostic(
131
+ loc?: SourceLocation,
132
+ ): Diagnostic {
133
+ return {
134
+ level: "error",
135
+ code: "MR_UNSUPPORTED_TOP_LEVEL_JSX_INITIALIZER",
136
+ message:
137
+ "Top-level variable initializers that contain JSX are not lowered yet. Move the JSX into a function component declaration or a component body statement.",
138
+ ...(loc === undefined ? {} : { loc }),
139
+ };
140
+ }
141
+
142
+ export function invalidJsxExpressionDiagnostic(
143
+ loc?: SourceLocation,
144
+ context: "text" | "attribute" | "unknown" = "unknown",
145
+ ): Diagnostic {
146
+ if (context === "text") {
147
+ return {
148
+ level: "error",
149
+ code: "MR_INVALID_JSX_EXPRESSION",
150
+ message:
151
+ "JSX text contains an empty or unparseable expression. To include literal braces in text, use &#123; / &#125; or {'{'} / {'}'} escapes.",
152
+ suggestion: {
153
+ title: "Escape literal braces in text as HTML entities or JSX string expressions.",
154
+ replacement: "&#123; / &#125;",
155
+ },
156
+ ...(loc === undefined ? {} : { loc }),
157
+ };
158
+ }
159
+
160
+ if (context === "attribute") {
161
+ return {
162
+ level: "error",
163
+ code: "MR_INVALID_JSX_EXPRESSION",
164
+ message:
165
+ "JSX attribute expression is empty or unparseable. Attribute braces must contain a valid JavaScript expression.",
166
+ suggestion: {
167
+ title: "Use a valid JavaScript expression in braces, or quote literal attribute text.",
168
+ replacement: 'title="literal text"',
169
+ },
170
+ ...(loc === undefined ? {} : { loc }),
171
+ };
172
+ }
173
+
174
+ return {
175
+ level: "error",
176
+ code: "MR_INVALID_JSX_EXPRESSION",
177
+ message:
178
+ "JSX expression is empty or unparseable. To include literal braces in text, use &#123; / &#125; or {'{'} / {'}'} escapes.",
179
+ suggestion: {
180
+ title: "Check the JSX expression syntax at this location.",
181
+ },
182
+ ...(loc === undefined ? {} : { loc }),
183
+ };
184
+ }