@surrealdb/ui 1.2.15 → 1.2.16
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/ui.js +19 -2
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/release-notes.md +39 -0
- package/tests/unit/Syntax/language.test.ts +63 -0
package/package.json
CHANGED
package/release-notes.md
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
Fenced code blocks tagged `tsx` or `jsx` rendered as plain, unhighlighted text in both the markdown viewer and the editor, and TypeScript blocks were silently parsed as plain JavaScript.
|
|
2
|
+
|
|
3
|
+
## Cause
|
|
4
|
+
|
|
5
|
+
`src/syntax/language.ts` mapped both `javascript` and `typescript` to the bare `@lezer/javascript` parser. That grammar exposes `dialects: {jsx, ts}`, but Lezer dialects are opt-in and nothing configured them.
|
|
6
|
+
|
|
7
|
+
Two consequences:
|
|
8
|
+
|
|
9
|
+
- `tsx` and `jsx` were not registered as languages or aliases. `findLanguageDefinition` returned `null`, so `MarkdownCodeLines` fell back to rendering each line as a bare fragment, `createMarkdownLanguage` skipped embedded highlighting in the editor, and neither appeared in the fence language picker.
|
|
10
|
+
- `ts` resolved, but to a JavaScript grammar. Type annotations and `interface` declarations parsed as errors.
|
|
11
|
+
|
|
12
|
+
Measured against the installed parser:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
### ts (interface + annotations)
|
|
16
|
+
bare parser (before) error nodes: 2
|
|
17
|
+
dialect: ts error nodes: 0
|
|
18
|
+
### tsx (JSX element)
|
|
19
|
+
bare parser (before) error nodes: 4
|
|
20
|
+
dialect: ts error nodes: 2
|
|
21
|
+
dialect: jsx ts error nodes: 0
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Change
|
|
25
|
+
|
|
26
|
+
- `javascript` now uses `dialect: "jsx"` and gains the `jsx` alias.
|
|
27
|
+
- `typescript` now uses `dialect: "jsx ts"` and gains the `tsx` alias.
|
|
28
|
+
|
|
29
|
+
Registering them as aliases rather than separate entries keeps the exported `Language` union and the fence language picker unchanged.
|
|
30
|
+
|
|
31
|
+
Enabling `jsx` on plain JavaScript is safe. The grammar only treats `<` as a tag start where an expression may begin, so comparisons, generic calls, and shift operators parse with zero errors before and after.
|
|
32
|
+
|
|
33
|
+
## Tests
|
|
34
|
+
|
|
35
|
+
Adds `tests/unit/Syntax/language.test.ts` covering registration, alias resolution, JSX and TypeScript parsing, and a regression guard that plain JavaScript comparison and shift operators are not read as JSX. Four of the five fail without the fix. Full unit suite passes at 274 tests, and the library builds.
|
|
36
|
+
|
|
37
|
+
## Impact
|
|
38
|
+
|
|
39
|
+
Consumers get highlighting for `tsx` and `jsx` blocks, and correct highlighting for the `ts` blocks they already have. On docs.surrealdb.com that is 23 `tsx` and 2 `jsx` blocks currently unhighlighted, plus roughly 1,150 `ts` blocks that were being parsed as JavaScript.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { getLanguageName, getLanguageParser } from "@src/syntax/language";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Counts the error nodes a registered language produces for a source snippet.
|
|
6
|
+
* A clean parse is the prerequisite for any highlighting at all, so this is
|
|
7
|
+
* the cheapest signal that a grammar is configured for the syntax it claims
|
|
8
|
+
* to support.
|
|
9
|
+
*/
|
|
10
|
+
function errorCount(language: string, source: string): number {
|
|
11
|
+
const parser = getLanguageParser(language);
|
|
12
|
+
|
|
13
|
+
if (!parser) {
|
|
14
|
+
throw new Error(`No parser registered for "${language}"`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let errors = 0;
|
|
18
|
+
|
|
19
|
+
parser.parse(source).iterate({
|
|
20
|
+
enter: (node) => {
|
|
21
|
+
if (node.type.isError) errors++;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return errors;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const TSX_SOURCE = `export function Greeting({ name }: { name: string }) {
|
|
29
|
+
return <View><Text>{name}</Text></View>;
|
|
30
|
+
}`;
|
|
31
|
+
|
|
32
|
+
const TS_SOURCE = `interface User { id: string; age?: number }
|
|
33
|
+
const user: User = { id: "a" };`;
|
|
34
|
+
|
|
35
|
+
const JS_SOURCE = `const ok = a < b && c > d;
|
|
36
|
+
const shifted = (n) => n << 2 > 1;`;
|
|
37
|
+
|
|
38
|
+
describe("language registry", () => {
|
|
39
|
+
it("registers tsx and jsx", () => {
|
|
40
|
+
expect(getLanguageParser("tsx")).toBeDefined();
|
|
41
|
+
expect(getLanguageParser("jsx")).toBeDefined();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("resolves tsx and jsx to their base language names", () => {
|
|
45
|
+
expect(getLanguageName("tsx")).toBe("TypeScript");
|
|
46
|
+
expect(getLanguageName("jsx")).toBe("JavaScript");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("parses JSX under jsx and tsx", () => {
|
|
50
|
+
expect(errorCount("jsx", "const a = <View><Text>hi</Text></View>;")).toBe(0);
|
|
51
|
+
expect(errorCount("tsx", TSX_SOURCE)).toBe(0);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("parses TypeScript syntax under ts and tsx", () => {
|
|
55
|
+
expect(errorCount("ts", TS_SOURCE)).toBe(0);
|
|
56
|
+
expect(errorCount("tsx", TS_SOURCE)).toBe(0);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("does not misread comparison operators as JSX in plain JavaScript", () => {
|
|
60
|
+
expect(errorCount("js", JS_SOURCE)).toBe(0);
|
|
61
|
+
expect(errorCount("ts", JS_SOURCE)).toBe(0);
|
|
62
|
+
});
|
|
63
|
+
});
|