dsh-ptc-plus 0.2.4 → 0.3.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.
Files changed (49) hide show
  1. package/README.en.md +177 -0
  2. package/README.md +85 -69
  3. package/assets/ptc-plus-bindings-en.png +0 -0
  4. package/assets/ptc-plus-bindings-zh.png +0 -0
  5. package/assets/ptc-plus-repair-en.png +0 -0
  6. package/assets/ptc-plus-settings-en.png +0 -0
  7. package/assets/ptc-plus-settings-zh.png +0 -0
  8. package/client.js +1168 -144
  9. package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +1 -1
  10. package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
  11. package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +7 -3
  12. package/docs/adr/0014-persist-cell-rewrite-policy.md +7 -5
  13. package/docs/adr/0019-plugin-settings-and-kill-switch.md +19 -4
  14. package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
  15. package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +5 -3
  16. package/docs/adr/0022-stage-npm-releases-with-oidc.md +2 -2
  17. package/docs/architecture.md +23 -14
  18. package/docs/client-ui.md +29 -11
  19. package/docs/durability-design.md +42 -20
  20. package/docs/installation.md +11 -3
  21. package/docs/program-data-plane.md +6 -0
  22. package/docs/runtime-reference.md +27 -14
  23. package/docs/value-wire.md +1 -1
  24. package/index.js +38 -4
  25. package/internal/cell-analysis.js +89 -12
  26. package/internal/cell-rewriter.js +162 -4
  27. package/internal/config-spec.js +192 -117
  28. package/internal/direct-surface-owner.js +56 -5
  29. package/internal/edit-transport-owner.js +11 -2
  30. package/internal/failure-reporting.js +15 -0
  31. package/internal/kernel-worker.js +11 -0
  32. package/internal/rejected-cell-editor.js +21 -12
  33. package/internal/repl-convenience.js +94 -6
  34. package/internal/repl-memory-projection.js +277 -0
  35. package/internal/repl-rewrite-contract.js +15 -0
  36. package/internal/run-code-description.js +34 -0
  37. package/internal/runtime-bridge-owner.js +63 -15
  38. package/internal/runtime-config.js +3 -0
  39. package/internal/session-cell-executor.js +74 -14
  40. package/internal/session-events.js +7 -0
  41. package/internal/session-journal.js +331 -63
  42. package/internal/session-log-view.js +2 -1
  43. package/internal/session-runtime.js +110 -9
  44. package/internal/session-state.js +116 -4
  45. package/package.json +10 -7
  46. package/src/client-activity.js +501 -0
  47. package/src/client.js +456 -20
  48. package/README.zh.md +0 -161
  49. /package/assets/{ptc-plus-repair.png → ptc-plus-repair-zh.png} +0 -0
@@ -5,6 +5,11 @@ import {
5
5
  STRIP_SUFFIX,
6
6
  rewriteModuleImportsExports,
7
7
  } from './cell-rewriter.js'
8
+ import {
9
+ LEGACY_DEFAULT_EXPORT_BINDING,
10
+ LIVE_DEFAULT_EXPORT_BINDING,
11
+ redeclarationCommitTarget,
12
+ } from './repl-rewrite-contract.js'
8
13
  import {
9
14
  bindingNodes,
10
15
  createGeneratedNameAllocator,
@@ -17,7 +22,7 @@ import {
17
22
  renderDurabilityReason,
18
23
  renderDurabilityReasons,
19
24
  } from './module-policy.js'
20
- import { rewriteLooseRedeclarations } from './repl-convenience.js'
25
+ import { rewriteReplRedeclarations } from './repl-convenience.js'
21
26
  import { applySourceEdits, mapSourceSpan } from './source-position-map.js'
22
27
  import { SKIP_AST_CHILDREN, walkAst } from './ast-traversal.js'
23
28
 
@@ -50,10 +55,13 @@ function addPatternBindings(pattern, names) {
50
55
  walkPattern(pattern, node => names.add(node.name))
51
56
  }
52
57
 
53
- function addPatternDeclarations(pattern, declarations) {
58
+ function addPatternDeclarations(pattern, declarations, kind = 'variable', definitionSpan = undefined, writable = false) {
54
59
  bindingNodes(pattern).forEach(node => declarations.push({
55
60
  name: node.name,
61
+ kind,
56
62
  span: declarationSpan(node),
63
+ definitionSpan,
64
+ writable,
57
65
  }))
58
66
  }
59
67
 
@@ -61,16 +69,29 @@ function topLevelBindings(body) {
61
69
  return new Set(topLevelDeclarations(body).map(declaration => declaration.name))
62
70
  }
63
71
 
64
- function topLevelDeclarations(body) {
72
+ function topLevelDeclarations(body, variableRedeclarations = false) {
65
73
  const declarations = []
66
74
  for (const statement of body) {
67
75
  if (statement.type === 'VariableDeclaration') {
68
- for (const declaration of statement.declarations) addPatternDeclarations(declaration.id, declarations)
76
+ const definitionSpan = declarationSpan(statement)
77
+ for (const declaration of statement.declarations) {
78
+ addPatternDeclarations(
79
+ declaration.id,
80
+ declarations,
81
+ 'variable',
82
+ definitionSpan,
83
+ statement.kind !== 'const' || variableRedeclarations,
84
+ )
85
+ }
69
86
  } else if ((statement.type === 'FunctionDeclaration' || statement.type === 'ClassDeclaration')
70
87
  && statement.id !== null) {
71
88
  declarations.push({
72
89
  name: statement.id.name,
90
+ kind: statement.type === 'ClassDeclaration' ? 'class' : 'function',
73
91
  span: declarationSpan(statement.id),
92
+ definitionSpan: declarationSpan(statement),
93
+ commitDependency: redeclarationCommitTarget(statement.id.name, statement.start),
94
+ writable: true,
74
95
  })
75
96
  }
76
97
  }
@@ -322,14 +343,31 @@ function rewriteCellReturns(code, sourceMap, unavailableNames) {
322
343
  return { ...applySourceEdits(code, sourceMap, edits), returnSignal }
323
344
  }
324
345
 
325
- export function prepareProgram(program, knownBindings, looseTopLevelRedeclarations, reservedBindings = new Set(), rewritesEnabled, importBindings = new Map(), importNamespaces = new Set()) {
346
+ export function prepareProgram(program, knownBindings, bindingPolicy, reservedBindings = new Set(), rewritesEnabled, importBindings = new Map(), importNamespaces = new Set(), writableBindings = undefined, moduleSemantics = { defaultExportBinding: LIVE_DEFAULT_EXPORT_BINDING }) {
326
347
  if (typeof program !== 'string') throw new TypeError('ptc-plus: program must be a string')
348
+ if (typeof bindingPolicy === 'boolean') {
349
+ bindingPolicy = {
350
+ variableRedeclarations: bindingPolicy,
351
+ functionClassRedeclarations: false,
352
+ }
353
+ }
354
+ if (bindingPolicy === null || typeof bindingPolicy !== 'object' || Array.isArray(bindingPolicy)
355
+ || typeof bindingPolicy.variableRedeclarations !== 'boolean'
356
+ || typeof bindingPolicy.functionClassRedeclarations !== 'boolean') {
357
+ throw new TypeError('ptc-plus: binding policy must define variableRedeclarations and functionClassRedeclarations booleans')
358
+ }
359
+ writableBindings ??= bindingPolicy.variableRedeclarations ? new Set(knownBindings) : new Set()
327
360
  if (rewritesEnabled === null || typeof rewritesEnabled !== 'object' || Array.isArray(rewritesEnabled)
328
361
  || typeof rewritesEnabled.autoRewriteImports !== 'boolean'
329
362
  || typeof rewritesEnabled.autoStripExports !== 'boolean'
330
363
  || typeof rewritesEnabled.autoSplitRedeclarations !== 'boolean') {
331
364
  throw new TypeError('ptc-plus: rewrite policy must define autoRewriteImports, autoStripExports, and autoSplitRedeclarations booleans')
332
365
  }
366
+ if (moduleSemantics === null || typeof moduleSemantics !== 'object' || Array.isArray(moduleSemantics)
367
+ || ![LEGACY_DEFAULT_EXPORT_BINDING, LIVE_DEFAULT_EXPORT_BINDING]
368
+ .includes(moduleSemantics.defaultExportBinding)) {
369
+ throw new TypeError('ptc-plus: module semantics must define a supported defaultExportBinding')
370
+ }
333
371
  const unavailableGeneratedNames = new Set([
334
372
  ...knownBindings,
335
373
  ...reservedBindings,
@@ -342,6 +380,7 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
342
380
  importBindings,
343
381
  importNamespaces,
344
382
  unavailableGeneratedNames,
383
+ moduleSemantics,
345
384
  )
346
385
  const staticModuleReasons = staticModuleClassification(moduleRewrite.moduleLoads)
347
386
  const wrapped = STRIP_PREFIX + moduleRewrite.code + STRIP_SUFFIX
@@ -360,8 +399,11 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
360
399
  const code = stripped.slice(STRIP_PREFIX.length, stripped.length - STRIP_SUFFIX.length)
361
400
  const sourceMap = moduleRewrite.sourceMap
362
401
  const outer = tree.body[0]
402
+ const commitSignal = moduleRewrite.commitSignal
363
403
  /* c8 ignore next */
364
- const generatedDeclarations = outer?.type === 'FunctionDeclaration' ? topLevelDeclarations(outer.body.body) : []
404
+ const generatedDeclarations = outer?.type === 'FunctionDeclaration'
405
+ ? topLevelDeclarations(outer.body.body, bindingPolicy.variableRedeclarations)
406
+ : []
365
407
  const collisionFor = (declaration) => {
366
408
  /* c8 ignore next */
367
409
  const mapped = declaration.original === true ? declaration.span : declaration.span === undefined
@@ -369,6 +411,12 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
369
411
  : mapSourceSpan(declaration.span, code, program, sourceMap)
370
412
  return {
371
413
  name: declaration.name,
414
+ kind: declaration.kind,
415
+ replaceableByVariableDeclaration: declaration.replaceableByVariableDeclaration === true,
416
+ ...(declaration.reason === undefined ? {} : { reason: declaration.reason }),
417
+ ...(declaration.commitDependency === undefined
418
+ ? {}
419
+ : { commitDependency: declaration.commitDependency }),
372
420
  start: { line: mapped.line, column: mapped.column },
373
421
  /* c8 ignore next */
374
422
  ...(mapped.end === undefined ? {} : { end: mapped.end }),
@@ -395,9 +443,22 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
395
443
  }
396
444
  }
397
445
  const importedNames = new Set(moduleRewrite.imports.keys())
446
+ const originalDeclarationNames = new Set(moduleRewrite.exportDeclarations.map(declaration => declaration.name))
398
447
  const declarations = [
399
- ...moduleRewrite.importDeclarations,
400
- ...generatedDeclarations.filter(declaration => !moduleRewrite.generatedNamespaces.has(declaration.name)),
448
+ ...moduleRewrite.importDeclarations.map(declaration => ({ ...declaration, writable: false })),
449
+ ...moduleRewrite.exportDeclarations.map(declaration => ({
450
+ ...declaration,
451
+ writable: bindingPolicy.variableRedeclarations,
452
+ })),
453
+ ...generatedDeclarations
454
+ .filter(declaration => !moduleRewrite.generatedNamespaces.has(declaration.name)
455
+ && !originalDeclarationNames.has(declaration.name))
456
+ .map(declaration => ({
457
+ ...declaration,
458
+ ...(declaration.definitionSpan === undefined ? {} : {
459
+ definitionSpan: mapSourceSpan(declaration.definitionSpan, code, program, sourceMap),
460
+ }),
461
+ })),
401
462
  ]
402
463
  const normalizeClassification = classification => {
403
464
  const imports = new Map(moduleRewrite.imports)
@@ -411,7 +472,9 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
411
472
  }
412
473
  }
413
474
  const reserved = declarations.filter(declaration => (
414
- reservedBindings.has(declaration.name) || moduleRewrite.importNamespaces.has(declaration.name)
475
+ reservedBindings.has(declaration.name)
476
+ || moduleRewrite.importNamespaces.has(declaration.name)
477
+ || (declaration.kind === 'import' && knownBindings.has(declaration.name))
415
478
  ))
416
479
  if (reserved.length > 0) {
417
480
  const classification = normalizeClassification(classifyPrepared(code, sourceMap))
@@ -427,18 +490,30 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
427
490
  moduleLoads: moduleRewrite.moduleLoads,
428
491
  }
429
492
  }
430
- const convenience = rewriteLooseRedeclarations({
493
+ const convenience = rewriteReplRedeclarations({
431
494
  code,
432
495
  sourceMap,
433
- body: looseTopLevelRedeclarations && outer?.type === 'FunctionDeclaration' ? outer.body.body : undefined,
496
+ body: outer?.type === 'FunctionDeclaration' ? outer.body.body : undefined,
434
497
  offset: STRIP_PREFIX.length,
435
- knownBindings: new Set([...knownBindings].filter(name => !importBindings.has(name))),
498
+ knownBindings,
499
+ variableRedeclarationBindings: bindingPolicy.variableRedeclarations
500
+ ? new Set([...knownBindings].filter(name => !importBindings.has(name)))
501
+ : new Set(knownBindings),
502
+ writableBindings: new Set([...writableBindings].filter(name => !importBindings.has(name))),
436
503
  declarations,
437
504
  declarationSpan,
438
505
  collisionFor,
506
+ bindingPolicy,
439
507
  autoSplitRedeclarations: rewritesEnabled.autoSplitRedeclarations,
508
+ commitSignal,
440
509
  })
441
510
  const { executableCode, executableSourceMap, collisions, redeclared, rewrites } = convenience
511
+ const commitTargets = new Set(moduleRewrite.commitTargets)
512
+ for (const declaration of redeclared) {
513
+ if (declaration.kind === 'function' || declaration.kind === 'class') {
514
+ commitTargets.add(declaration.commitDependency)
515
+ }
516
+ }
442
517
  // Classification sees the rewritten program so declared bindings reflect the
443
518
  // split form; it must never see the return rewrite, whose computed
444
519
  // globalThis access would mark every returning cell volatile.
@@ -463,5 +538,7 @@ export function prepareProgram(program, knownBindings, looseTopLevelRedeclaratio
463
538
  redeclared,
464
539
  rewrites: [...moduleRewrite.rewrites, ...rewrites],
465
540
  moduleLoads: moduleRewrite.moduleLoads,
541
+ commitSignal,
542
+ commitTargets,
466
543
  }
467
544
  }
@@ -3,6 +3,10 @@ import { parse } from '@babel/parser'
3
3
  import traverseModule, { Hub, NodePath } from '@babel/traverse'
4
4
  import { bindingNodes, createGeneratedNameAllocator } from './binding-pattern.js'
5
5
  import { applySourceEdits, createMappedTextBuilder, identitySourceMap } from './source-position-map.js'
6
+ import {
7
+ LEGACY_DEFAULT_EXPORT_BINDING,
8
+ LIVE_DEFAULT_EXPORT_BINDING,
9
+ } from './repl-rewrite-contract.js'
6
10
 
7
11
  export const STRIP_PREFIX = 'async function __ptc_cell__(){\n'
8
12
  export const STRIP_SUFFIX = '\n}'
@@ -183,6 +187,7 @@ function importEdits(
183
187
  if (imported !== undefined && !requiredExports.includes(imported)) requiredExports.push(imported)
184
188
  importDeclarations.push({
185
189
  name: localName(specifier),
190
+ kind: 'import',
186
191
  span: {
187
192
  line: specifier.local.loc.start.line,
188
193
  column: specifier.local.loc.start.column + 1,
@@ -191,6 +196,14 @@ function importEdits(
191
196
  column: specifier.local.loc.end.column + 1,
192
197
  },
193
198
  },
199
+ definitionSpan: {
200
+ line: node.loc.start.line,
201
+ column: node.loc.start.column + 1,
202
+ end: {
203
+ line: node.loc.end.line,
204
+ column: node.loc.end.column + 1,
205
+ },
206
+ },
194
207
  original: true,
195
208
  })
196
209
  }
@@ -420,7 +433,96 @@ function exportAllEdits(node, code, edits, rewrites, moduleLoads) {
420
433
  rewrites.push(record('export', `converted the re-export of ${JSON.stringify(source)} into a side-effect import`, node, source))
421
434
  }
422
435
 
423
- function exportDefaultEdits(node, code, edits, rewrites, defaultNameAvailable) {
436
+ function exportDefaultEdits({
437
+ node,
438
+ code,
439
+ edits,
440
+ rewrites,
441
+ defaultNameAvailable,
442
+ exportDeclarations,
443
+ imports,
444
+ allocateNamespace,
445
+ commitSignal,
446
+ commitTargets,
447
+ }) {
448
+ const declaration = node.declaration
449
+ if (declaration.type === 'TSInterfaceDeclaration') {
450
+ editNode(edits, node, code)
451
+ rewrites.push(record('export', 'removed a type-only export declaration', node, 'interface'))
452
+ return
453
+ }
454
+ if (!defaultNameAvailable) {
455
+ throw new ModuleRewriteError(
456
+ 'export default cannot be exposed as __default because that name is already declared',
457
+ { line: node.loc.start.line, column: node.loc.start.column + 1 },
458
+ )
459
+ }
460
+ const namedDeclaration = (declaration.type === 'FunctionDeclaration'
461
+ || declaration.type === 'ClassDeclaration') && declaration.id !== null
462
+ const retainedNamedDeclaration = namedDeclaration && declaration.id.name !== '__default'
463
+ const existingAlias = imports.get('__default')
464
+ const reuseAlias = existingAlias?.syntheticDefault === true
465
+ const namespace = reuseAlias ? existingAlias.namespace : allocateNamespace('default_namespace')
466
+ const member = importMember(namespace, 'default')
467
+ imports.set('__default', {
468
+ namespace,
469
+ imported: 'default',
470
+ syntheticDefault: true,
471
+ commitDependency: '__default',
472
+ })
473
+ commitTargets.add('__default')
474
+ if (declaration.type === 'ClassDeclaration' && declaration.id !== null) {
475
+ commitTargets.add(declaration.id.name)
476
+ }
477
+ exportDeclarations.push({
478
+ name: '__default',
479
+ kind: declaration.type === 'FunctionDeclaration'
480
+ ? 'function'
481
+ : declaration.type === 'ClassDeclaration' ? 'class' : 'variable',
482
+ commitDependency: '__default',
483
+ span: {
484
+ line: node.loc.start.line,
485
+ column: node.loc.start.column + 1,
486
+ end: {
487
+ line: node.loc.end.line,
488
+ column: node.loc.end.column + 1,
489
+ },
490
+ },
491
+ definitionSpan: {
492
+ line: node.loc.start.line,
493
+ column: node.loc.start.column + 1,
494
+ end: {
495
+ line: node.loc.end.line,
496
+ column: node.loc.end.column + 1,
497
+ },
498
+ },
499
+ original: true,
500
+ })
501
+ const rewrite = record('export', 'converted the default export into a local __default binding', node)
502
+ const commit = [...new Set([...(declaration.type === 'ClassDeclaration' && declaration.id !== null
503
+ ? [declaration.id.name]
504
+ : []), '__default'])]
505
+ .map(name => ` this[${JSON.stringify(commitSignal)}](${JSON.stringify(name)});`)
506
+ .join('')
507
+ const assignmentPrefix = reuseAlias ? `${member} = ` : `const ${namespace} = { default: `
508
+ const assignmentSuffix = reuseAlias ? '' : ' }'
509
+ if (retainedNamedDeclaration) {
510
+ edit(edits, node.start, declaration.start, preserveLines(code.slice(node.start, declaration.start)))
511
+ edit(edits, node.end, node.end,
512
+ `; ${assignmentPrefix}${declaration.id.name}${assignmentSuffix};${commit}`)
513
+ } else if (declaration.type === 'FunctionDeclaration' || declaration.type === 'ClassDeclaration') {
514
+ const prefix = code.slice(node.start, declaration.start)
515
+ edit(edits, node.start, declaration.start, preserveLines(prefix, assignmentPrefix))
516
+ edit(edits, node.end, node.end, `${assignmentSuffix};${commit}`)
517
+ } else {
518
+ const prefix = code.slice(node.start, declaration.start)
519
+ edit(edits, node.start, declaration.start, preserveLines(prefix, assignmentPrefix))
520
+ edit(edits, node.end, node.end, `${assignmentSuffix};${commit}`)
521
+ }
522
+ rewrites.push(rewrite)
523
+ }
524
+
525
+ function legacyExportDefaultEdits(node, code, edits, rewrites, defaultNameAvailable, exportDeclarations) {
424
526
  const declaration = node.declaration
425
527
  if (declaration.type === 'TSInterfaceDeclaration') {
426
528
  editNode(edits, node, code)
@@ -438,6 +540,29 @@ function exportDefaultEdits(node, code, edits, rewrites, defaultNameAvailable) {
438
540
  { line: node.loc.start.line, column: node.loc.start.column + 1 },
439
541
  )
440
542
  }
543
+ exportDeclarations.push({
544
+ name: '__default',
545
+ kind: declaration.type === 'FunctionDeclaration'
546
+ ? 'function'
547
+ : declaration.type === 'ClassDeclaration' ? 'class' : 'variable',
548
+ span: {
549
+ line: node.loc.start.line,
550
+ column: node.loc.start.column + 1,
551
+ end: {
552
+ line: node.loc.end.line,
553
+ column: node.loc.end.column + 1,
554
+ },
555
+ },
556
+ definitionSpan: {
557
+ line: node.loc.start.line,
558
+ column: node.loc.start.column + 1,
559
+ end: {
560
+ line: node.loc.end.line,
561
+ column: node.loc.end.column + 1,
562
+ },
563
+ },
564
+ original: true,
565
+ })
441
566
  const rewrite = record('export', 'converted the default export into a local __default binding', node)
442
567
  if (declaration.type === 'FunctionDeclaration' && declaration.id !== null) {
443
568
  const prefix = code.slice(node.start, declaration.start)
@@ -458,15 +583,21 @@ function exportDefaultEdits(node, code, edits, rewrites, defaultNameAvailable) {
458
583
 
459
584
  function ascending(left, right) { return left.at - right.at }
460
585
 
461
- export function rewriteModuleImportsExports(program, enabled, existingImports = new Map(), existingNamespaces = new Set(), unavailableNames = new Set()) {
586
+ export function rewriteModuleImportsExports(program, enabled, existingImports = new Map(), existingNamespaces = new Set(), unavailableNames = new Set(), moduleSemantics = { defaultExportBinding: LIVE_DEFAULT_EXPORT_BINDING }) {
587
+ if (![LEGACY_DEFAULT_EXPORT_BINDING, LIVE_DEFAULT_EXPORT_BINDING]
588
+ .includes(moduleSemantics?.defaultExportBinding)) {
589
+ throw new TypeError('ptc-plus: unsupported default export binding semantics')
590
+ }
462
591
  const tree = parseCell(program)
463
592
  const edits = []
464
593
  const rewrites = []
465
594
  const imports = new Map(existingImports)
466
595
  const importDeclarations = []
596
+ const exportDeclarations = []
467
597
  const moduleLoads = []
468
598
  const importNamespaces = new Set(existingNamespaces)
469
599
  const allocateName = createGeneratedNameAllocator(tree, [...unavailableNames, ...importNamespaces])
600
+ const commitSignal = allocateName('redeclaration_commit')
470
601
  const generatedNamespaces = new Set()
471
602
  const allocateImportName = purpose => {
472
603
  const name = allocateName(purpose)
@@ -475,7 +606,8 @@ export function rewriteModuleImportsExports(program, enabled, existingImports =
475
606
  return name
476
607
  }
477
608
  const namespaceCaptures = []
478
- const defaultNameAvailable = !tree.body.some((node) => {
609
+ const commitTargets = new Set()
610
+ const currentCellDefaultNameAvailable = !tree.body.some((node) => {
479
611
  const declaration = node.type === 'ExportNamedDeclaration' ? node.declaration : node
480
612
  if (declaration?.type === 'VariableDeclaration' && declaration.declare !== true) {
481
613
  return declaration.declarations.some(entry => bindingNodes(entry.id).some(binding => binding.name === '__default'))
@@ -487,6 +619,12 @@ export function rewriteModuleImportsExports(program, enabled, existingImports =
487
619
  specifier.importKind !== 'type' && specifier.local.name === '__default'
488
620
  ))
489
621
  })
622
+ const existingDefault = existingImports.get('__default')
623
+ const persistentDefaultNameAvailable = !unavailableNames.has('__default')
624
+ || existingDefault?.syntheticDefault === true
625
+ const defaultNameAvailable = currentCellDefaultNameAvailable
626
+ && (moduleSemantics.defaultExportBinding === LEGACY_DEFAULT_EXPORT_BINDING
627
+ || persistentDefaultNameAvailable)
490
628
  for (const node of tree.body) {
491
629
  if (node.type === 'ImportDeclaration' && enabled.autoRewriteImports) {
492
630
  importEdits(node, program, edits, rewrites, imports, importDeclarations,
@@ -499,7 +637,24 @@ export function rewriteModuleImportsExports(program, enabled, existingImports =
499
637
  exportAllEdits(node, program, edits, rewrites, moduleLoads)
500
638
  }
501
639
  else if (node.type === 'ExportDefaultDeclaration' && enabled.autoStripExports) {
502
- exportDefaultEdits(node, program, edits, rewrites, defaultNameAvailable)
640
+ if (moduleSemantics.defaultExportBinding === LEGACY_DEFAULT_EXPORT_BINDING) {
641
+ legacyExportDefaultEdits(
642
+ node, program, edits, rewrites, defaultNameAvailable, exportDeclarations,
643
+ )
644
+ } else {
645
+ exportDefaultEdits({
646
+ node,
647
+ code: program,
648
+ edits,
649
+ rewrites,
650
+ defaultNameAvailable,
651
+ exportDeclarations,
652
+ imports,
653
+ allocateNamespace: allocateImportName,
654
+ commitSignal,
655
+ commitTargets,
656
+ })
657
+ }
503
658
  }
504
659
  }
505
660
  assertNoDynamicImportResolution(tree, imports)
@@ -514,7 +669,10 @@ export function rewriteModuleImportsExports(program, enabled, existingImports =
514
669
  importNamespaces,
515
670
  generatedNamespaces,
516
671
  importDeclarations,
672
+ exportDeclarations,
517
673
  moduleLoads,
674
+ commitSignal,
675
+ commitTargets,
518
676
  rewrites: rewrites.map(({ at: _at, ...rest }) => rest),
519
677
  }
520
678
  }