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.
- package/README.en.md +177 -0
- package/README.md +85 -69
- package/assets/ptc-plus-bindings-en.png +0 -0
- package/assets/ptc-plus-bindings-zh.png +0 -0
- package/assets/ptc-plus-repair-en.png +0 -0
- package/assets/ptc-plus-settings-en.png +0 -0
- package/assets/ptc-plus-settings-zh.png +0 -0
- package/client.js +1168 -144
- package/docs/adr/0006-rewrite-module-syntax-with-an-ast.md +1 -1
- package/docs/adr/0007-separate-worker-transport-from-session-semantics.md +15 -3
- package/docs/adr/0013-isolate-repl-redeclaration-convenience.md +7 -3
- package/docs/adr/0014-persist-cell-rewrite-policy.md +7 -5
- package/docs/adr/0019-plugin-settings-and-kill-switch.md +19 -4
- package/docs/adr/0020-optional-cordis-tools-in-ptc-mode.md +2 -2
- package/docs/adr/0021-separate-host-bootstrap-from-session-runtime.md +5 -3
- package/docs/adr/0022-stage-npm-releases-with-oidc.md +2 -2
- package/docs/architecture.md +23 -14
- package/docs/client-ui.md +29 -11
- package/docs/durability-design.md +42 -20
- package/docs/installation.md +11 -3
- package/docs/program-data-plane.md +6 -0
- package/docs/runtime-reference.md +27 -14
- package/docs/value-wire.md +1 -1
- package/index.js +38 -4
- package/internal/cell-analysis.js +89 -12
- package/internal/cell-rewriter.js +162 -4
- package/internal/config-spec.js +192 -117
- package/internal/direct-surface-owner.js +56 -5
- package/internal/edit-transport-owner.js +11 -2
- package/internal/failure-reporting.js +15 -0
- package/internal/kernel-worker.js +11 -0
- package/internal/rejected-cell-editor.js +21 -12
- package/internal/repl-convenience.js +94 -6
- package/internal/repl-memory-projection.js +277 -0
- package/internal/repl-rewrite-contract.js +15 -0
- package/internal/run-code-description.js +34 -0
- package/internal/runtime-bridge-owner.js +63 -15
- package/internal/runtime-config.js +3 -0
- package/internal/session-cell-executor.js +74 -14
- package/internal/session-events.js +7 -0
- package/internal/session-journal.js +331 -63
- package/internal/session-log-view.js +2 -1
- package/internal/session-runtime.js +110 -9
- package/internal/session-state.js +116 -4
- package/package.json +10 -7
- package/src/client-activity.js +501 -0
- package/src/client.js +456 -20
- package/README.zh.md +0 -161
- /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 {
|
|
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
|
-
|
|
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,
|
|
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'
|
|
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
|
-
...
|
|
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)
|
|
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 =
|
|
493
|
+
const convenience = rewriteReplRedeclarations({
|
|
431
494
|
code,
|
|
432
495
|
sourceMap,
|
|
433
|
-
body:
|
|
496
|
+
body: outer?.type === 'FunctionDeclaration' ? outer.body.body : undefined,
|
|
434
497
|
offset: STRIP_PREFIX.length,
|
|
435
|
-
knownBindings
|
|
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(
|
|
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
|
|
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
|
-
|
|
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
|
}
|