@knighted/jsx 1.9.1 → 1.9.2

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.
@@ -250,6 +250,7 @@ const collectRootJsxNodes = (root) => {
250
250
  walk(root, false);
251
251
  return nodes;
252
252
  };
253
+ const MAX_TYPESCRIPT_STRIP_PASSES = 5;
253
254
  const hasStringProperty = (value, key) => isObjectRecord(value) && typeof value[key] === 'string';
254
255
  const hasSourceAndExpressionRanges = (value) => isObjectRecord(value) &&
255
256
  typeof value.type === 'string' &&
@@ -356,6 +357,46 @@ const applyStripEdits = (magic, edits) => {
356
357
  });
357
358
  return changed;
358
359
  };
360
+ const stripTypeScriptSyntax = (source, sourceType) => {
361
+ let currentCode = source;
362
+ let changed = false;
363
+ let reachedStripPassLimit = true;
364
+ for (let pass = 0; pass < MAX_TYPESCRIPT_STRIP_PASSES; pass += 1) {
365
+ const parsed = (0, oxc_parser_1.parseSync)('transpile-jsx-source.tsx', currentCode, createModuleParserOptions(sourceType));
366
+ const error = parsed.errors[0];
367
+ if (error) {
368
+ throw new Error(formatParserError(error));
369
+ }
370
+ const edits = collectTypeScriptStripEdits(currentCode, parsed.program);
371
+ if (!edits.length) {
372
+ reachedStripPassLimit = false;
373
+ break;
374
+ }
375
+ const magic = new magic_string_1.default(currentCode);
376
+ const passChanged = applyStripEdits(magic, edits);
377
+ if (!passChanged) {
378
+ reachedStripPassLimit = false;
379
+ break;
380
+ }
381
+ currentCode = magic.toString();
382
+ changed = true;
383
+ }
384
+ if (reachedStripPassLimit) {
385
+ const parsed = (0, oxc_parser_1.parseSync)('transpile-jsx-source.tsx', currentCode, createModuleParserOptions(sourceType));
386
+ const error = parsed.errors[0];
387
+ if (error) {
388
+ throw new Error(formatParserError(error));
389
+ }
390
+ const remainingEdits = collectTypeScriptStripEdits(currentCode, parsed.program);
391
+ if (remainingEdits.length) {
392
+ throw new Error(`[jsx] TypeScript strip did not converge after ${MAX_TYPESCRIPT_STRIP_PASSES} passes (${remainingEdits.length} removable TypeScript nodes remain).`);
393
+ }
394
+ }
395
+ return {
396
+ code: currentCode,
397
+ changed,
398
+ };
399
+ };
359
400
  function transpileJsxSource(source, options = {}) {
360
401
  const sourceType = options.sourceType ?? 'module';
361
402
  const createElementRef = options.createElement ?? 'React.createElement';
@@ -366,23 +407,25 @@ function transpileJsxSource(source, options = {}) {
366
407
  if (firstError) {
367
408
  throw new Error(formatParserError(firstError));
368
409
  }
369
- const magic = new magic_string_1.default(source);
370
- const stripChanged = typescriptMode === 'strip'
371
- ? applyStripEdits(magic, collectTypeScriptStripEdits(source, parsed.program))
372
- : false;
373
410
  const jsxRoots = collectRootJsxNodes(parsed.program);
374
- if (!jsxRoots.length) {
411
+ const jsxMagic = new magic_string_1.default(source);
412
+ if (jsxRoots.length) {
413
+ const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef, typescriptMode === 'strip');
414
+ jsxRoots.sort(compareByRangeStartDesc).forEach(node => {
415
+ jsxMagic.overwrite(node.range[0], node.range[1], builder.compile(node));
416
+ });
417
+ }
418
+ const jsxCode = jsxRoots.length ? jsxMagic.toString() : source;
419
+ const jsxChanged = jsxRoots.length > 0;
420
+ if (typescriptMode !== 'strip') {
375
421
  return {
376
- code: stripChanged ? magic.toString() : source,
377
- changed: stripChanged,
422
+ code: jsxCode,
423
+ changed: jsxChanged,
378
424
  };
379
425
  }
380
- const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef, typescriptMode === 'strip');
381
- jsxRoots.sort(compareByRangeStartDesc).forEach(node => {
382
- magic.overwrite(node.range[0], node.range[1], builder.compile(node));
383
- });
426
+ const stripResult = stripTypeScriptSyntax(jsxCode, sourceType);
384
427
  return {
385
- code: magic.toString(),
386
- changed: true,
428
+ code: stripResult.code,
429
+ changed: jsxChanged || stripResult.changed,
387
430
  };
388
431
  }
package/dist/transpile.js CHANGED
@@ -244,6 +244,7 @@ const collectRootJsxNodes = (root) => {
244
244
  walk(root, false);
245
245
  return nodes;
246
246
  };
247
+ const MAX_TYPESCRIPT_STRIP_PASSES = 5;
247
248
  const hasStringProperty = (value, key) => isObjectRecord(value) && typeof value[key] === 'string';
248
249
  const hasSourceAndExpressionRanges = (value) => isObjectRecord(value) &&
249
250
  typeof value.type === 'string' &&
@@ -350,6 +351,46 @@ const applyStripEdits = (magic, edits) => {
350
351
  });
351
352
  return changed;
352
353
  };
354
+ const stripTypeScriptSyntax = (source, sourceType) => {
355
+ let currentCode = source;
356
+ let changed = false;
357
+ let reachedStripPassLimit = true;
358
+ for (let pass = 0; pass < MAX_TYPESCRIPT_STRIP_PASSES; pass += 1) {
359
+ const parsed = parseSync('transpile-jsx-source.tsx', currentCode, createModuleParserOptions(sourceType));
360
+ const error = parsed.errors[0];
361
+ if (error) {
362
+ throw new Error(formatParserError(error));
363
+ }
364
+ const edits = collectTypeScriptStripEdits(currentCode, parsed.program);
365
+ if (!edits.length) {
366
+ reachedStripPassLimit = false;
367
+ break;
368
+ }
369
+ const magic = new MagicString(currentCode);
370
+ const passChanged = applyStripEdits(magic, edits);
371
+ if (!passChanged) {
372
+ reachedStripPassLimit = false;
373
+ break;
374
+ }
375
+ currentCode = magic.toString();
376
+ changed = true;
377
+ }
378
+ if (reachedStripPassLimit) {
379
+ const parsed = parseSync('transpile-jsx-source.tsx', currentCode, createModuleParserOptions(sourceType));
380
+ const error = parsed.errors[0];
381
+ if (error) {
382
+ throw new Error(formatParserError(error));
383
+ }
384
+ const remainingEdits = collectTypeScriptStripEdits(currentCode, parsed.program);
385
+ if (remainingEdits.length) {
386
+ throw new Error(`[jsx] TypeScript strip did not converge after ${MAX_TYPESCRIPT_STRIP_PASSES} passes (${remainingEdits.length} removable TypeScript nodes remain).`);
387
+ }
388
+ }
389
+ return {
390
+ code: currentCode,
391
+ changed,
392
+ };
393
+ };
353
394
  export function transpileJsxSource(source, options = {}) {
354
395
  const sourceType = options.sourceType ?? 'module';
355
396
  const createElementRef = options.createElement ?? 'React.createElement';
@@ -360,23 +401,25 @@ export function transpileJsxSource(source, options = {}) {
360
401
  if (firstError) {
361
402
  throw new Error(formatParserError(firstError));
362
403
  }
363
- const magic = new MagicString(source);
364
- const stripChanged = typescriptMode === 'strip'
365
- ? applyStripEdits(magic, collectTypeScriptStripEdits(source, parsed.program))
366
- : false;
367
404
  const jsxRoots = collectRootJsxNodes(parsed.program);
368
- if (!jsxRoots.length) {
405
+ const jsxMagic = new MagicString(source);
406
+ if (jsxRoots.length) {
407
+ const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef, typescriptMode === 'strip');
408
+ jsxRoots.sort(compareByRangeStartDesc).forEach(node => {
409
+ jsxMagic.overwrite(node.range[0], node.range[1], builder.compile(node));
410
+ });
411
+ }
412
+ const jsxCode = jsxRoots.length ? jsxMagic.toString() : source;
413
+ const jsxChanged = jsxRoots.length > 0;
414
+ if (typescriptMode !== 'strip') {
369
415
  return {
370
- code: stripChanged ? magic.toString() : source,
371
- changed: stripChanged,
416
+ code: jsxCode,
417
+ changed: jsxChanged,
372
418
  };
373
419
  }
374
- const builder = new SourceJsxReactBuilder(source, createElementRef, fragmentRef, typescriptMode === 'strip');
375
- jsxRoots.sort(compareByRangeStartDesc).forEach(node => {
376
- magic.overwrite(node.range[0], node.range[1], builder.compile(node));
377
- });
420
+ const stripResult = stripTypeScriptSyntax(jsxCode, sourceType);
378
421
  return {
379
- code: magic.toString(),
380
- changed: true,
422
+ code: stripResult.code,
423
+ changed: jsxChanged || stripResult.changed,
381
424
  };
382
425
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knighted/jsx",
3
- "version": "1.9.1",
3
+ "version": "1.9.2",
4
4
  "description": "Runtime JSX tagged template that renders DOM or React trees anywhere with or without a build step.",
5
5
  "keywords": [
6
6
  "jsx runtime",