@r4ai/typst-ast-web 0.2.1 → 0.3.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # typst-ast
2
2
 
3
- A WebAssembly library that parses [Typst](https://typst.app/) source code and returns its AST as a JSON-serializable object. Built with Rust and [`typst-syntax`](https://crates.io/crates/typst-syntax), distributed as npm packages via `wasm-pack`.
3
+ A WebAssembly library that parses [Typst](https://typst.app/) source code and returns its CST/AST as a JSON-serializable object. Built with Rust and [`typst-syntax`](https://crates.io/crates/typst-syntax), distributed as npm packages via `wasm-pack`.
4
4
 
5
5
  ## Packages
6
6
 
@@ -14,39 +14,50 @@ A WebAssembly library that parses [Typst](https://typst.app/) source code and re
14
14
  ### Browser
15
15
 
16
16
  ```ts
17
- import init, { parse } from "@r4ai/typst-ast-web";
17
+ import init, { parse, parseAst } from "@r4ai/typst-ast-web";
18
18
 
19
19
  await init();
20
20
 
21
- const result = parse("= Hello\n\nThis is *typst*.", { mode: "markup" });
22
- console.log(result);
21
+ // CST (Concrete Syntax Tree)
22
+ const cst = parse("= Hello\n\nThis is *typst*.", { mode: "markup" });
23
+ console.log(cst);
23
24
  // {
24
25
  // root: { kind: "Markup", range: [0, 25], children: [...] },
25
26
  // errors: []
26
27
  // }
28
+
29
+ // AST (Abstract Syntax Tree)
30
+ const ast = parseAst("= Hello\n\nThis is *typst*.", { mode: "markup" });
31
+ console.log(ast);
32
+ // {
33
+ // root: [
34
+ // { kind: "heading", ... },
35
+ // { kind: "parbreak", ... },
36
+ // ...
37
+ // ],
38
+ // errors: []
39
+ // }
27
40
  ```
28
41
 
29
42
  ### Node.js
30
43
 
31
44
  ```ts
32
- import { parse } from "@r4ai/typst-ast-node";
45
+ import { parse, parseAst } from "@r4ai/typst-ast-node";
33
46
 
34
- const result = parse("#let x = 1 + 2", { mode: "code" });
35
- console.log(result);
47
+ const cst = parse("#let x = 1 + 2", { mode: "code" });
48
+ const ast = parseAst("#let x = 1 + 2", { mode: "code" });
36
49
  ```
37
50
 
38
51
  ### API
39
52
 
40
- #### `parse(text, options?)`
41
-
42
- Parses Typst source text and returns the AST.
43
-
44
- **Parameters**
53
+ Both functions accept the same parameters:
45
54
 
46
55
  - `text: string` — Typst source code to parse
47
56
  - `options.mode?: "markup" | "code" | "math"` — Parse mode (default: `"markup"`)
48
57
 
49
- **Return value**
58
+ #### `parse(text, options?)`
59
+
60
+ Returns the CST (Concrete Syntax Tree) — a lossless syntax tree that preserves all tokens including whitespace and punctuation.
50
61
 
51
62
  ```ts
52
63
  interface ParseResult {
@@ -60,13 +71,31 @@ interface SyntaxNode {
60
71
  text?: string;
61
72
  children: SyntaxNode[];
62
73
  }
74
+ ```
63
75
 
64
- interface ParseError {
65
- message: string;
66
- range: [number, number];
76
+ #### `parseAst(text, options?)`
77
+
78
+ Returns the AST (Abstract Syntax Tree) — a typed, semantic tree where each node is a tagged union discriminated by `kind`. Unlike the CST, the AST extracts semantic information (e.g. heading depth, function callee, binary operator) into dedicated fields.
79
+
80
+ ```ts
81
+ interface ParseAstResult {
82
+ root: AstExpr[];
83
+ errors: ParseError[];
67
84
  }
85
+
86
+ // AstExpr is a discriminated union of 59 node types.
87
+ // Examples:
88
+ type AstExpr =
89
+ | { kind: "text"; range: [number, number] | null; text: string }
90
+ | { kind: "heading"; range: [number, number] | null; depth: number; body: AstExpr[] }
91
+ | { kind: "strong"; range: [number, number] | null; body: AstExpr[] }
92
+ | { kind: "funcCall"; range: [number, number] | null; callee: AstExpr; args: AstArg[] }
93
+ | { kind: "binary"; range: [number, number] | null; op: AstBinOp; lhs: AstExpr; rhs: AstExpr }
94
+ | // ... and 54 more variants
68
95
  ```
69
96
 
97
+ See [`src/types.ts`](./src/types.ts) for the full type definitions.
98
+
70
99
  ## Development
71
100
 
72
101
  ### Prerequisites
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "collaborators": [
5
5
  "r4ai"
6
6
  ],
7
- "version": "0.2.1",
7
+ "version": "0.3.0",
8
8
  "license": "MIT",
9
9
  "repository": {
10
10
  "type": "git",
package/typst_ast.d.ts CHANGED
@@ -28,6 +28,574 @@ text: string,
28
28
  options?: ParseOptions,
29
29
  ): ParseResult;
30
30
 
31
+ // --- AST types ---
32
+
33
+ export type Range = [number, number] | null;
34
+
35
+ export type AstExpr =
36
+ | AstText
37
+ | AstSpace
38
+ | AstLinebreak
39
+ | AstParbreak
40
+ | AstEscape
41
+ | AstShorthand
42
+ | AstSmartQuote
43
+ | AstStrong
44
+ | AstEmph
45
+ | AstRaw
46
+ | AstLink
47
+ | AstLabel
48
+ | AstRef
49
+ | AstHeading
50
+ | AstListItem
51
+ | AstEnumItem
52
+ | AstTermItem
53
+ | AstEquation
54
+ | AstMath
55
+ | AstMathText
56
+ | AstMathIdent
57
+ | AstMathShorthand
58
+ | AstMathAlignPoint
59
+ | AstMathDelimited
60
+ | AstMathAttach
61
+ | AstMathPrimes
62
+ | AstMathFrac
63
+ | AstMathRoot
64
+ | AstIdent
65
+ | AstNone
66
+ | AstAuto
67
+ | AstBool
68
+ | AstInt
69
+ | AstFloat
70
+ | AstNumeric
71
+ | AstStr
72
+ | AstCodeBlock
73
+ | AstContentBlock
74
+ | AstParenthesized
75
+ | AstArray
76
+ | AstDict
77
+ | AstUnary
78
+ | AstBinary
79
+ | AstFieldAccess
80
+ | AstFuncCall
81
+ | AstClosure
82
+ | AstLetBinding
83
+ | AstDestructAssignment
84
+ | AstSetRule
85
+ | AstShowRule
86
+ | AstContextual
87
+ | AstConditional
88
+ | AstWhileLoop
89
+ | AstForLoop
90
+ | AstModuleImport
91
+ | AstModuleInclude
92
+ | AstLoopBreak
93
+ | AstLoopContinue
94
+ | AstFuncReturn;
95
+
96
+ // Markup
97
+
98
+ export interface AstText {
99
+ kind: "text";
100
+ range: Range;
101
+ text: string;
102
+ }
103
+
104
+ export interface AstSpace {
105
+ kind: "space";
106
+ range: Range;
107
+ }
108
+
109
+ export interface AstLinebreak {
110
+ kind: "linebreak";
111
+ range: Range;
112
+ }
113
+
114
+ export interface AstParbreak {
115
+ kind: "parbreak";
116
+ range: Range;
117
+ }
118
+
119
+ export interface AstEscape {
120
+ kind: "escape";
121
+ range: Range;
122
+ character: string;
123
+ }
124
+
125
+ export interface AstShorthand {
126
+ kind: "shorthand";
127
+ range: Range;
128
+ character: string;
129
+ }
130
+
131
+ export interface AstSmartQuote {
132
+ kind: "smartQuote";
133
+ range: Range;
134
+ double: boolean;
135
+ }
136
+
137
+ export interface AstStrong {
138
+ kind: "strong";
139
+ range: Range;
140
+ body: AstExpr[];
141
+ }
142
+
143
+ export interface AstEmph {
144
+ kind: "emph";
145
+ range: Range;
146
+ body: AstExpr[];
147
+ }
148
+
149
+ export interface AstRaw {
150
+ kind: "raw";
151
+ range: Range;
152
+ lines: string[];
153
+ lang: string | null;
154
+ block: boolean;
155
+ }
156
+
157
+ export interface AstLink {
158
+ kind: "link";
159
+ range: Range;
160
+ url: string;
161
+ }
162
+
163
+ export interface AstLabel {
164
+ kind: "label";
165
+ range: Range;
166
+ name: string;
167
+ }
168
+
169
+ export interface AstRef {
170
+ kind: "ref";
171
+ range: Range;
172
+ target: string;
173
+ supplement: AstExpr[] | null;
174
+ }
175
+
176
+ export interface AstHeading {
177
+ kind: "heading";
178
+ range: Range;
179
+ depth: number;
180
+ body: AstExpr[];
181
+ }
182
+
183
+ export interface AstListItem {
184
+ kind: "listItem";
185
+ range: Range;
186
+ body: AstExpr[];
187
+ }
188
+
189
+ export interface AstEnumItem {
190
+ kind: "enumItem";
191
+ range: Range;
192
+ number: number | null;
193
+ body: AstExpr[];
194
+ }
195
+
196
+ export interface AstTermItem {
197
+ kind: "termItem";
198
+ range: Range;
199
+ term: AstExpr[];
200
+ description: AstExpr[];
201
+ }
202
+
203
+ export interface AstEquation {
204
+ kind: "equation";
205
+ range: Range;
206
+ body: AstExpr[];
207
+ block: boolean;
208
+ }
209
+
210
+ // Math
211
+
212
+ export interface AstMath {
213
+ kind: "math";
214
+ range: Range;
215
+ body: AstExpr[];
216
+ }
217
+
218
+ export type AstMathTextKind =
219
+ | { kind: "character"; value: string }
220
+ | { kind: "number"; value: string };
221
+
222
+ export interface AstMathText {
223
+ kind: "mathText";
224
+ range: Range;
225
+ text: AstMathTextKind;
226
+ }
227
+
228
+ export interface AstMathIdent {
229
+ kind: "mathIdent";
230
+ range: Range;
231
+ name: string;
232
+ }
233
+
234
+ export interface AstMathShorthand {
235
+ kind: "mathShorthand";
236
+ range: Range;
237
+ character: string;
238
+ }
239
+
240
+ export interface AstMathAlignPoint {
241
+ kind: "mathAlignPoint";
242
+ range: Range;
243
+ }
244
+
245
+ export interface AstMathDelimited {
246
+ kind: "mathDelimited";
247
+ range: Range;
248
+ open: AstExpr;
249
+ body: AstExpr[];
250
+ close: AstExpr;
251
+ }
252
+
253
+ export interface AstMathAttach {
254
+ kind: "mathAttach";
255
+ range: Range;
256
+ base: AstExpr;
257
+ bottom: AstExpr | null;
258
+ top: AstExpr | null;
259
+ primes: number | null;
260
+ }
261
+
262
+ export interface AstMathPrimes {
263
+ kind: "mathPrimes";
264
+ range: Range;
265
+ count: number;
266
+ }
267
+
268
+ export interface AstMathFrac {
269
+ kind: "mathFrac";
270
+ range: Range;
271
+ num: AstExpr;
272
+ denom: AstExpr;
273
+ }
274
+
275
+ export interface AstMathRoot {
276
+ kind: "mathRoot";
277
+ range: Range;
278
+ index: number | null;
279
+ radicand: AstExpr;
280
+ }
281
+
282
+ // Literals
283
+
284
+ export interface AstIdent {
285
+ kind: "ident";
286
+ range: Range;
287
+ name: string;
288
+ }
289
+
290
+ export interface AstNone {
291
+ kind: "none";
292
+ range: Range;
293
+ }
294
+
295
+ export interface AstAuto {
296
+ kind: "auto";
297
+ range: Range;
298
+ }
299
+
300
+ export interface AstBool {
301
+ kind: "bool";
302
+ range: Range;
303
+ value: boolean;
304
+ }
305
+
306
+ export interface AstInt {
307
+ kind: "int";
308
+ range: Range;
309
+ value: number;
310
+ }
311
+
312
+ export interface AstFloat {
313
+ kind: "float";
314
+ range: Range;
315
+ value: number;
316
+ }
317
+
318
+ export type AstUnit =
319
+ | "pt"
320
+ | "mm"
321
+ | "cm"
322
+ | "in"
323
+ | "rad"
324
+ | "deg"
325
+ | "em"
326
+ | "fr"
327
+ | "percent";
328
+
329
+ export interface AstNumeric {
330
+ kind: "numeric";
331
+ range: Range;
332
+ value: number;
333
+ unit: AstUnit;
334
+ }
335
+
336
+ export interface AstStr {
337
+ kind: "str";
338
+ range: Range;
339
+ value: string;
340
+ }
341
+
342
+ // Code structures
343
+
344
+ export interface AstCodeBlock {
345
+ kind: "codeBlock";
346
+ range: Range;
347
+ body: AstExpr[];
348
+ }
349
+
350
+ export interface AstContentBlock {
351
+ kind: "contentBlock";
352
+ range: Range;
353
+ body: AstExpr[];
354
+ }
355
+
356
+ export interface AstParenthesized {
357
+ kind: "parenthesized";
358
+ range: Range;
359
+ expr: AstExpr;
360
+ }
361
+
362
+ export type AstArrayItem =
363
+ | { kind: "pos"; expr: AstExpr }
364
+ | { kind: "spread"; expr: AstExpr; sinkIdent: string | null };
365
+
366
+ export interface AstArray {
367
+ kind: "array";
368
+ range: Range;
369
+ items: AstArrayItem[];
370
+ }
371
+
372
+ export type AstDictItem =
373
+ | { kind: "named"; name: string; expr: AstExpr }
374
+ | { kind: "keyed"; key: AstExpr; expr: AstExpr }
375
+ | { kind: "spread"; expr: AstExpr; sinkIdent: string | null };
376
+
377
+ export interface AstDict {
378
+ kind: "dict";
379
+ range: Range;
380
+ items: AstDictItem[];
381
+ }
382
+
383
+ // Operations
384
+
385
+ export type AstUnOp = "pos" | "neg" | "not";
386
+
387
+ export type AstBinOp =
388
+ | "add"
389
+ | "sub"
390
+ | "mul"
391
+ | "div"
392
+ | "and"
393
+ | "or"
394
+ | "eq"
395
+ | "neq"
396
+ | "lt"
397
+ | "leq"
398
+ | "gt"
399
+ | "geq"
400
+ | "assign"
401
+ | "in"
402
+ | "notIn"
403
+ | "addAssign"
404
+ | "subAssign"
405
+ | "mulAssign"
406
+ | "divAssign";
407
+
408
+ export interface AstUnary {
409
+ kind: "unary";
410
+ range: Range;
411
+ op: AstUnOp;
412
+ expr: AstExpr;
413
+ }
414
+
415
+ export interface AstBinary {
416
+ kind: "binary";
417
+ range: Range;
418
+ op: AstBinOp;
419
+ lhs: AstExpr;
420
+ rhs: AstExpr;
421
+ }
422
+
423
+ export interface AstFieldAccess {
424
+ kind: "fieldAccess";
425
+ range: Range;
426
+ target: AstExpr;
427
+ field: string;
428
+ }
429
+
430
+ export type AstArg =
431
+ | { kind: "pos"; expr: AstExpr }
432
+ | { kind: "named"; name: string; expr: AstExpr }
433
+ | { kind: "spread"; expr: AstExpr; sinkIdent: string | null };
434
+
435
+ export interface AstFuncCall {
436
+ kind: "funcCall";
437
+ range: Range;
438
+ callee: AstExpr;
439
+ args: AstArg[];
440
+ }
441
+
442
+ export type AstParam =
443
+ | { kind: "pos"; pattern: AstPattern }
444
+ | { kind: "named"; name: string; expr: AstExpr }
445
+ | { kind: "spread"; sinkIdent: string | null; sinkExpr: AstExpr | null };
446
+
447
+ export interface AstClosure {
448
+ kind: "closure";
449
+ range: Range;
450
+ name: string | null;
451
+ params: AstParam[];
452
+ body: AstExpr;
453
+ }
454
+
455
+ // Patterns
456
+
457
+ export type AstDestructuringItem =
458
+ | { kind: "pattern"; pattern: AstPattern }
459
+ | { kind: "named"; name: string; pattern: AstPattern }
460
+ | { kind: "spread"; sinkIdent: string | null };
461
+
462
+ export type AstPattern =
463
+ | { kind: "normal"; expr: AstExpr }
464
+ | { kind: "placeholder"; range: Range }
465
+ | { kind: "parenthesized"; expr: AstExpr }
466
+ | {
467
+ kind: "destructuring";
468
+ range: Range;
469
+ items: AstDestructuringItem[];
470
+ };
471
+
472
+ // Bindings
473
+
474
+ export type AstLetBindingKind =
475
+ | { kind: "normal"; pattern: AstPattern }
476
+ | { kind: "closure"; name: string };
477
+
478
+ export interface AstLetBinding {
479
+ kind: "letBinding";
480
+ range: Range;
481
+ bindingKind: AstLetBindingKind;
482
+ init: AstExpr | null;
483
+ }
484
+
485
+ export interface AstDestructAssignment {
486
+ kind: "destructAssignment";
487
+ range: Range;
488
+ pattern: AstPattern;
489
+ value: AstExpr;
490
+ }
491
+
492
+ // Rules
493
+
494
+ export interface AstSetRule {
495
+ kind: "setRule";
496
+ range: Range;
497
+ target: AstExpr;
498
+ args: AstArg[];
499
+ condition: AstExpr | null;
500
+ }
501
+
502
+ export interface AstShowRule {
503
+ kind: "showRule";
504
+ range: Range;
505
+ selector: AstExpr | null;
506
+ transform: AstExpr;
507
+ }
508
+
509
+ export interface AstContextual {
510
+ kind: "contextual";
511
+ range: Range;
512
+ body: AstExpr;
513
+ }
514
+
515
+ // Control flow
516
+
517
+ export interface AstConditional {
518
+ kind: "conditional";
519
+ range: Range;
520
+ condition: AstExpr;
521
+ ifBody: AstExpr;
522
+ elseBody: AstExpr | null;
523
+ }
524
+
525
+ export interface AstWhileLoop {
526
+ kind: "whileLoop";
527
+ range: Range;
528
+ condition: AstExpr;
529
+ body: AstExpr;
530
+ }
531
+
532
+ export interface AstForLoop {
533
+ kind: "forLoop";
534
+ range: Range;
535
+ pattern: AstPattern;
536
+ iterable: AstExpr;
537
+ body: AstExpr;
538
+ }
539
+
540
+ // Module
541
+
542
+ export type AstImportItem =
543
+ | { kind: "simple"; path: string[]; name: string }
544
+ | {
545
+ kind: "renamed";
546
+ path: string[];
547
+ originalName: string;
548
+ newName: string;
549
+ };
550
+
551
+ export type AstImports =
552
+ | { kind: "wildcard" }
553
+ | { kind: "items"; items: AstImportItem[] };
554
+
555
+ export interface AstModuleImport {
556
+ kind: "moduleImport";
557
+ range: Range;
558
+ source: AstExpr;
559
+ newName: string | null;
560
+ imports: AstImports | null;
561
+ }
562
+
563
+ export interface AstModuleInclude {
564
+ kind: "moduleInclude";
565
+ range: Range;
566
+ source: AstExpr;
567
+ }
568
+
569
+ // Jump
570
+
571
+ export interface AstLoopBreak {
572
+ kind: "loopBreak";
573
+ range: Range;
574
+ }
575
+
576
+ export interface AstLoopContinue {
577
+ kind: "loopContinue";
578
+ range: Range;
579
+ }
580
+
581
+ export interface AstFuncReturn {
582
+ kind: "funcReturn";
583
+ range: Range;
584
+ body: AstExpr | null;
585
+ }
586
+
587
+ // Parse AST result
588
+
589
+ export interface ParseAstResult {
590
+ root: AstExpr[];
591
+ errors: ParseError[];
592
+ }
593
+
594
+ export declare function parseAst(
595
+ text: string,
596
+ options?: ParseOptions,
597
+ ): ParseAstResult;
598
+
31
599
 
32
600
 
33
601
  export function start(): void;
@@ -37,9 +605,12 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
37
605
  export interface InitOutput {
38
606
  readonly memory: WebAssembly.Memory;
39
607
  readonly parse: (a: number, b: number, c: any) => [number, number, number];
608
+ readonly parseAst: (a: number, b: number, c: any) => [number, number, number];
40
609
  readonly start: () => void;
41
610
  readonly __wbindgen_malloc: (a: number, b: number) => number;
42
611
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
612
+ readonly __wbindgen_exn_store: (a: number) => void;
613
+ readonly __externref_table_alloc: () => number;
43
614
  readonly __wbindgen_externrefs: WebAssembly.Table;
44
615
  readonly __externref_table_dealloc: (a: number) => void;
45
616
  readonly __wbindgen_start: () => void;
package/typst_ast.js CHANGED
@@ -15,6 +15,21 @@ export function parse(text, options) {
15
15
  return takeFromExternrefTable0(ret[0]);
16
16
  }
17
17
 
18
+ /**
19
+ * @param {string} text
20
+ * @param {any} options
21
+ * @returns {any}
22
+ */
23
+ export function parseAst(text, options) {
24
+ const ptr0 = passStringToWasm0(text, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
25
+ const len0 = WASM_VECTOR_LEN;
26
+ const ret = wasm.parseAst(ptr0, len0, options);
27
+ if (ret[2]) {
28
+ throw takeFromExternrefTable0(ret[1]);
29
+ }
30
+ return takeFromExternrefTable0(ret[0]);
31
+ }
32
+
18
33
  export function start() {
19
34
  wasm.start();
20
35
  }
@@ -91,6 +106,10 @@ function __wbg_get_imports() {
91
106
  const ret = Object.entries(arg0);
92
107
  return ret;
93
108
  },
109
+ __wbg_fromCodePoint_22365db7b7d6ac39: function() { return handleError(function (arg0) {
110
+ const ret = String.fromCodePoint(arg0 >>> 0);
111
+ return ret;
112
+ }, arguments); },
94
113
  __wbg_get_9b94d73e6221f75c: function(arg0, arg1) {
95
114
  const ret = arg0[arg1 >>> 0];
96
115
  return ret;
@@ -153,12 +172,17 @@ function __wbg_get_imports() {
153
172
  const ret = arg0;
154
173
  return ret;
155
174
  },
156
- __wbindgen_cast_0000000000000002: function(arg0, arg1) {
175
+ __wbindgen_cast_0000000000000002: function(arg0) {
176
+ // Cast intrinsic for `I64 -> Externref`.
177
+ const ret = arg0;
178
+ return ret;
179
+ },
180
+ __wbindgen_cast_0000000000000003: function(arg0, arg1) {
157
181
  // Cast intrinsic for `Ref(String) -> Externref`.
158
182
  const ret = getStringFromWasm0(arg0, arg1);
159
183
  return ret;
160
184
  },
161
- __wbindgen_cast_0000000000000003: function(arg0) {
185
+ __wbindgen_cast_0000000000000004: function(arg0) {
162
186
  // Cast intrinsic for `U64 -> Externref`.
163
187
  const ret = BigInt.asUintN(64, arg0);
164
188
  return ret;
@@ -179,6 +203,12 @@ function __wbg_get_imports() {
179
203
  };
180
204
  }
181
205
 
206
+ function addToExternrefTable0(obj) {
207
+ const idx = wasm.__externref_table_alloc();
208
+ wasm.__wbindgen_externrefs.set(idx, obj);
209
+ return idx;
210
+ }
211
+
182
212
  function debugString(val) {
183
213
  // primitive types
184
214
  const type = typeof val;
@@ -270,6 +300,15 @@ function getUint8ArrayMemory0() {
270
300
  return cachedUint8ArrayMemory0;
271
301
  }
272
302
 
303
+ function handleError(f, args) {
304
+ try {
305
+ return f.apply(this, args);
306
+ } catch (e) {
307
+ const idx = addToExternrefTable0(e);
308
+ wasm.__wbindgen_exn_store(idx);
309
+ }
310
+ }
311
+
273
312
  function isLikeNone(x) {
274
313
  return x === undefined || x === null;
275
314
  }
package/typst_ast_bg.wasm CHANGED
Binary file