@tsrx/core 0.0.22 → 0.0.24

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.
@@ -380,6 +380,37 @@ export function convert_source_map_to_mappings(
380
380
  css_element_info,
381
381
  });
382
382
 
383
+ /** @type {Map<string, number>} */
384
+ const generated_position_indexes = new Map();
385
+
386
+ /**
387
+ * When a transform expands one source identifier into multiple generated
388
+ * identifiers (e.g. `import { foo } from server` -> `const foo =
389
+ * _$_server_$_.foo`), esrap records multiple generated positions for the
390
+ * same source location. Keep token mappings in generated-order by consuming
391
+ * the next matching generated token instead of always using the first one.
392
+ * @param {Token} token
393
+ * @returns {{ line: number; column: number }}
394
+ */
395
+ function get_generated_position_for_token(token) {
396
+ const key = `${token.loc.start.line}:${token.loc.start.column}`;
397
+ const positions = src_to_gen_map.get(key);
398
+ if (!positions || positions.length === 0) {
399
+ throw new Error(`No source map entry for position "${key}"`);
400
+ }
401
+
402
+ const matching_positions = positions.filter((position) => {
403
+ const offset = loc_to_offset(position.line, position.column, gen_line_offsets);
404
+ return generated_code.startsWith(token.generated, offset);
405
+ });
406
+ const candidates = matching_positions.length > 0 ? matching_positions : positions;
407
+ const index_key = `${key}:${token.generated}`;
408
+ const index = generated_position_indexes.get(index_key) ?? 0;
409
+ generated_position_indexes.set(index_key, index + 1);
410
+
411
+ return candidates[Math.min(index, candidates.length - 1)];
412
+ }
413
+
383
414
  /**
384
415
  * Needed for a mapping that includes the computed brackets for diagnostics
385
416
  * @param {AST.MethodDefinition | AST.Property} node
@@ -2182,11 +2213,7 @@ export function convert_source_map_to_mappings(
2182
2213
  const gen_length = gen_text.length;
2183
2214
  let gen_line_col;
2184
2215
  try {
2185
- gen_line_col = get_generated_position(
2186
- token.loc.start.line,
2187
- token.loc.start.column,
2188
- src_to_gen_map,
2189
- );
2216
+ gen_line_col = get_generated_position_for_token(token);
2190
2217
  } catch {
2191
2218
  continue;
2192
2219
  }
@@ -1343,6 +1343,15 @@ export const break_statement = {
1343
1343
  metadata: { path: [] },
1344
1344
  };
1345
1345
 
1346
+ /**
1347
+ * @type {AST.ContinueStatement}
1348
+ */
1349
+ export const continue_statement = {
1350
+ type: 'ContinueStatement',
1351
+ label: null,
1352
+ metadata: { path: [] },
1353
+ };
1354
+
1346
1355
  export {
1347
1356
  await_builder as await,
1348
1357
  let_builder as let,
@@ -1352,6 +1361,7 @@ export {
1352
1361
  true_instance as true,
1353
1362
  false_instance as false,
1354
1363
  break_statement as break,
1364
+ continue_statement as continue,
1355
1365
  for_builder as for,
1356
1366
  switch_builder as switch,
1357
1367
  function_builder as function,
package/types/index.d.ts CHANGED
@@ -64,8 +64,9 @@ interface BaseNodeMetaData {
64
64
  scoped?: boolean;
65
65
  path: AST.Node[];
66
66
  has_template?: boolean;
67
- source_name?: string | '#server' | '#style';
67
+ source_name?: string;
68
68
  source_length?: number;
69
+ module_keyword?: 'module' | 'namespace';
69
70
  is_capitalized?: boolean;
70
71
  commentContainerId?: number;
71
72
  parenthesized?: boolean;
@@ -73,6 +74,7 @@ interface BaseNodeMetaData {
73
74
  returns?: AST.ReturnStatement[];
74
75
  has_return?: boolean;
75
76
  has_throw?: boolean;
77
+ has_continue?: boolean;
76
78
  is_reactive?: boolean;
77
79
  lone_return?: boolean;
78
80
  forceMapping?: boolean;
@@ -206,12 +208,9 @@ declare module 'estree' {
206
208
  TsxCompat: TsxCompat;
207
209
  TSRXExpression: TSRXExpression;
208
210
  Html: Html;
211
+ Style: Style;
209
212
  Element: Element;
210
213
  Text: TextNode;
211
- ServerBlock: ServerBlock;
212
- ServerBlockStatement: ServerBlockStatement;
213
- ServerIdentifier: ServerIdentifier;
214
- StyleIdentifier: StyleIdentifier;
215
214
  Attribute: Attribute;
216
215
  RefAttribute: RefAttribute;
217
216
  SpreadAttribute: SpreadAttribute;
@@ -220,8 +219,7 @@ declare module 'estree' {
220
219
  }
221
220
 
222
221
  interface ExpressionMap {
223
- StyleIdentifier: StyleIdentifier;
224
- ServerIdentifier: ServerIdentifier;
222
+ Style: Style;
225
223
  Text: TextNode;
226
224
  JSXEmptyExpression: ESTreeJSX.JSXEmptyExpression;
227
225
  ParenthesizedExpression: ParenthesizedExpression;
@@ -268,14 +266,6 @@ declare module 'estree' {
268
266
  key?: AST.Expression | null;
269
267
  }
270
268
 
271
- interface ServerIdentifier extends AST.BaseExpression {
272
- type: 'ServerIdentifier';
273
- }
274
-
275
- interface StyleIdentifier extends AST.BaseExpression {
276
- type: 'StyleIdentifier';
277
- }
278
-
279
269
  interface ImportDeclaration {
280
270
  importKind: TSESTree.ImportDeclaration['importKind'];
281
271
  }
@@ -338,7 +328,6 @@ declare module 'estree' {
338
328
  metadata: BaseNodeMetaData & {
339
329
  topScopedClasses?: TopScopedClasses;
340
330
  styleClasses?: StyleClasses;
341
- styleIdentifierPresent?: boolean;
342
331
  };
343
332
  default: boolean;
344
333
  typeParameters?: AST.TSTypeParameterDeclaration;
@@ -370,6 +359,12 @@ declare module 'estree' {
370
359
  expression: AST.Expression;
371
360
  }
372
361
 
362
+ interface Style extends AST.BaseExpression {
363
+ type: 'Style';
364
+ value: AST.Literal;
365
+ loc?: AST.SourceLocation;
366
+ }
367
+
373
368
  export interface TSRXExpression extends AST.BaseExpression {
374
369
  type: 'TSRXExpression';
375
370
  expression: AST.Expression;
@@ -416,18 +411,6 @@ declare module 'estree' {
416
411
  loc?: AST.SourceLocation;
417
412
  }
418
413
 
419
- interface ServerBlockStatement extends Omit<BlockStatement, 'body'> {
420
- body: (AST.Statement | AST.ExportNamedDeclaration)[];
421
- }
422
-
423
- interface ServerBlock extends AST.BaseNode {
424
- type: 'ServerBlock';
425
- body: ServerBlockStatement;
426
- metadata: BaseNodeMetaData & {
427
- exports: Set<string>;
428
- };
429
- }
430
-
431
414
  interface ScriptContent extends Omit<AST.Element, 'type'> {
432
415
  type: 'ScriptContent';
433
416
  content: string;
@@ -694,6 +677,7 @@ declare module 'estree-jsx' {
694
677
  interface JSXExpressionContainer {
695
678
  html?: boolean;
696
679
  text?: boolean;
680
+ style?: boolean;
697
681
  }
698
682
 
699
683
  interface JSXMemberExpression {
@@ -977,6 +961,9 @@ declare module 'estree' {
977
961
  > {
978
962
  body: TSModuleBlock;
979
963
  id: AST.Identifier;
964
+ metadata: BaseNodeMetaData & {
965
+ exports?: Set<string>;
966
+ };
980
967
  }
981
968
  interface TSNamedTupleMember extends Omit<
982
969
  AcornTSNode<TSESTree.TSNamedTupleMember>,
@@ -1184,7 +1171,9 @@ export interface AnalysisResult {
1184
1171
  scope: ScopeInterface;
1185
1172
  component_metadata: Array<{ id: string }>;
1186
1173
  metadata: {
1187
- serverIdentifierPresent: boolean;
1174
+ serverImportsPresent: boolean;
1175
+ serverImportDeclarations: AST.ImportDeclaration[];
1176
+ serverModule: AST.TSModuleDeclaration | null;
1188
1177
  };
1189
1178
  errors: CompileError[];
1190
1179
  comments: AST.CommentWithLocation[];
@@ -1209,6 +1198,7 @@ export type DeclarationKind =
1209
1198
  | 'rest_param'
1210
1199
  | 'component'
1211
1200
  | 'import'
1201
+ | 'module'
1212
1202
  | 'using'
1213
1203
  | 'await using';
1214
1204
 
@@ -1239,7 +1229,8 @@ export interface Binding {
1239
1229
  | AST.Expression
1240
1230
  | AST.FunctionDeclaration
1241
1231
  | AST.ClassDeclaration
1242
- | AST.ImportDeclaration;
1232
+ | AST.ImportDeclaration
1233
+ | AST.TSModuleDeclaration;
1243
1234
  /** Whether this binding has been reassigned */
1244
1235
  reassigned: boolean;
1245
1236
  /** Whether this binding has been mutated (property access) */
@@ -1331,7 +1322,8 @@ export interface ScopeInterface {
1331
1322
  | AST.Expression
1332
1323
  | AST.FunctionDeclaration
1333
1324
  | AST.ClassDeclaration
1334
- | AST.ImportDeclaration,
1325
+ | AST.ImportDeclaration
1326
+ | AST.TSModuleDeclaration,
1335
1327
  ): Binding;
1336
1328
  /** Get binding by name */
1337
1329
  get(name: string): Binding | null;
@@ -1357,8 +1349,7 @@ export interface BaseState {
1357
1349
  /** For utils */
1358
1350
  scope: ScopeInterface;
1359
1351
  scopes: Map<AST.Node | AST.Node[], ScopeInterface>;
1360
- serverIdentifierPresent: boolean;
1361
- ancestor_server_block: AST.ServerBlock | undefined;
1352
+ ancestor_server_block: AST.TSModuleDeclaration | undefined;
1362
1353
  inside_head?: boolean;
1363
1354
  keep_component_style?: boolean;
1364
1355
 
@@ -29,6 +29,7 @@ export interface JsxTransformContext {
29
29
  needs_error_boundary: boolean;
30
30
  needs_suspense: boolean;
31
31
  needs_merge_refs: boolean;
32
+ needs_fragment: boolean;
32
33
  helper_state: {
33
34
  base_name: string;
34
35
  next_id: number;
@@ -239,6 +240,11 @@ export interface JsxPlatform {
239
240
  name: string;
240
241
 
241
242
  imports: {
243
+ /**
244
+ * Module to import `Fragment` from when a keyed fragment is required
245
+ * for a multi-child loop body. React: `'react'`. Preact: `'preact'`.
246
+ */
247
+ fragment?: string;
242
248
  /**
243
249
  * Module to import `Suspense` from when a `try { ... } pending { ... }`
244
250
  * block appears. React: `'react'`. Preact: `'preact/compat'`.
package/types/parse.d.ts CHANGED
@@ -930,7 +930,7 @@ export namespace Parse {
930
930
  refDestructuringErrors?: DestructuringErrors,
931
931
  forInit?: ForInit,
932
932
  forNew?: boolean,
933
- ): AST.ServerIdentifier | AST.StyleIdentifier | AST.Component | AST.Identifier | AST.Literal;
933
+ ): AST.Component | AST.Identifier | AST.Literal;
934
934
 
935
935
  /** Default handler for parseExprAtom when no other case matches */
936
936
  parseExprAtomDefault(): AST.Expression;
@@ -1172,8 +1172,6 @@ export namespace Parse {
1172
1172
  */
1173
1173
  parseTopLevel(node: AST.Program): AST.Program;
1174
1174
 
1175
- parseServerBlock(): AST.ServerBlock;
1176
-
1177
1175
  parseElement(): AST.Element | AST.Tsx | AST.TsxCompat;
1178
1176
 
1179
1177
  parseDoubleQuotedTextChild(): AST.TextNode;
@@ -1210,7 +1208,6 @@ export namespace Parse {
1210
1208
  | AST.TextNode
1211
1209
  | ESTreeJSX.JSXEmptyExpression
1212
1210
  | ESTreeJSX.JSXExpressionContainer
1213
- | AST.ServerBlock
1214
1211
  | AST.Component
1215
1212
  | AST.ExpressionStatement
1216
1213
  | ReturnType<Parser['parseElement']>
@@ -1543,7 +1540,7 @@ export namespace Parse {
1543
1540
  /**
1544
1541
  * Check if a local export refers to a defined variable.
1545
1542
  * Acorn's default implementation only checks the top-level module scope,
1546
- * but Ripple overrides this to check all scopes (for server blocks).
1543
+ * but Ripple overrides this to check all scopes (for submodules).
1547
1544
  * @param id The identifier being exported
1548
1545
  */
1549
1546
  checkLocalExport(id: AST.Identifier): void;