ttsc 0.23.0 → 0.24.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/cmd/ttscgraph/serve.go +264 -48
- package/cmd/ttscgraph/serve_early_error_encode_failure_is_observable_test.go +40 -0
- package/cmd/ttscgraph/serve_graph_snapshot_version_matches_typescript_client_test.go +32 -0
- package/cmd/ttscgraph/serve_phase_trace_accounts_for_load_failure_test.go +45 -0
- package/cmd/ttscgraph/serve_phase_trace_is_opt_in_and_payload_free_test.go +52 -0
- package/cmd/ttscgraph/serve_protocol_negotiates_incremental_shards_test.go +44 -0
- package/cmd/ttscgraph/serve_session_reloads_commonjs_package_entry_for_esm_test.go +2 -2
- package/cmd/ttscgraph/serve_session_reloads_superseding_module_candidates_test.go +46 -20
- package/cmd/ttscgraph/serve_session_retries_failed_dump_test.go +9 -9
- package/cmd/ttscgraph/serve_shards.go +1390 -0
- package/cmd/ttscgraph/serve_shards_abandoned_generation_converges_on_retry_test.go +92 -0
- package/cmd/ttscgraph/serve_shards_delete_removed_source_test.go +57 -0
- package/cmd/ttscgraph/serve_shards_external_endpoints_test.go +53 -0
- package/cmd/ttscgraph/serve_shards_keep_source_distributed_dependencies_at_the_boundary_test.go +108 -0
- package/cmd/ttscgraph/serve_shards_match_full_dump_oracle_test.go +88 -0
- package/cmd/ttscgraph/serve_shards_merge_pending_and_new_edits_test.go +50 -0
- package/cmd/ttscgraph/serve_shards_prune_unreferenced_external_endpoints_test.go +65 -0
- package/cmd/ttscgraph/serve_shards_publish_created_source_test.go +92 -0
- package/cmd/ttscgraph/serve_shards_rebuild_declaration_edit_test.go +43 -0
- package/cmd/ttscgraph/serve_shards_refresh_cross_file_implementation_test.go +63 -0
- package/cmd/ttscgraph/serve_shards_refresh_dependent_diagnostics_test.go +80 -0
- package/cmd/ttscgraph/serve_shards_rename_moves_source_identity_test.go +95 -0
- package/cmd/ttscgraph/serve_shards_retry_preserves_committed_generation_test.go +48 -0
- package/cmd/ttscgraph/serve_shards_reuse_unaffected_sources_test.go +121 -0
- package/driver/declaration_shape.go +85 -0
- package/driver/program.go +39 -10
- package/internal/graph/build.go +62 -10
- package/internal/graph/build_files_reuses_committed_cross_file_endpoints_test.go +87 -0
- package/internal/graph/build_keeps_source_distributed_dependencies_at_the_external_boundary_test.go +74 -0
- package/internal/graph/dump.go +84 -43
- package/internal/graph/dump_path_mapper_caches_alias_resolution_test.go +29 -0
- package/internal/graph/dump_paths.go +134 -11
- package/internal/graph/dump_paths_canonicalize_windows_short_root_test.go +39 -0
- package/internal/graph/dump_rejects_provenance_only_path_errors_test.go +32 -0
- package/internal/graph/dump_serializes_the_full_graph_test.go +2 -2
- package/internal/graph/dump_symlink_project_publishes_matching_base_test.go +82 -0
- package/internal/graph/edges.go +58 -16
- package/internal/graph/exports.go +9 -2
- package/internal/graph/graph.go +47 -7
- package/internal/graph/graph_kind_contracts_match_their_producers_test.go +121 -0
- package/internal/graph/node_modifiers_emit_union_strings_test.go +1 -1
- package/internal/graph/provenance.go +11 -1
- package/internal/graph/resolve.go +1 -4
- package/internal/graph/source.go +23 -0
- package/internal/graph/wire_node_ids_share_alias_resolution_test.go +29 -0
- package/package.json +8 -8
|
@@ -2,7 +2,10 @@ package main
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"path/filepath"
|
|
5
|
+
"strings"
|
|
5
6
|
"testing"
|
|
7
|
+
|
|
8
|
+
"github.com/samchon/ttsc/packages/ttsc/internal/graph"
|
|
6
9
|
)
|
|
7
10
|
|
|
8
11
|
// TestServeSessionReloadsSupersedingModuleCandidates verifies a resident
|
|
@@ -15,13 +18,14 @@ import (
|
|
|
15
18
|
//
|
|
16
19
|
// 1. Load a project whose specifier resolves to the lower-priority target.
|
|
17
20
|
// 2. Create only the absent target that precedes it in that resolver's search.
|
|
18
|
-
// 3. Assert the resident snapshot reloads and
|
|
19
|
-
//
|
|
21
|
+
// 3. Assert the resident snapshot reloads and the imported symbol resolves to
|
|
22
|
+
// the newly preferred file. Package internals remain external boundaries.
|
|
20
23
|
func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
21
24
|
cases := []struct {
|
|
22
|
-
name
|
|
23
|
-
setup
|
|
24
|
-
add
|
|
25
|
+
name string
|
|
26
|
+
setup func(*testing.T, string) string
|
|
27
|
+
add func(*testing.T, string)
|
|
28
|
+
wantDiagnostic string
|
|
25
29
|
}{
|
|
26
30
|
{
|
|
27
31
|
name: "relative_extension",
|
|
@@ -32,10 +36,10 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
32
36
|
}`)
|
|
33
37
|
writeGraphFile(t, filepath.Join(root, "src", "main.ts"), "import { winner } from './value';\nexport function main(): void { winner(); }\n")
|
|
34
38
|
writeGraphFile(t, filepath.Join(root, "src", "value.js"), "export function winner() {}\n")
|
|
35
|
-
return "
|
|
39
|
+
return "src/value.ts"
|
|
36
40
|
},
|
|
37
41
|
add: func(t *testing.T, root string) {
|
|
38
|
-
writeGraphFile(t, filepath.Join(root, "src", "value.ts"), "export function winner(): void {}\
|
|
42
|
+
writeGraphFile(t, filepath.Join(root, "src", "value.ts"), "export function winner(): void {}\n")
|
|
39
43
|
},
|
|
40
44
|
},
|
|
41
45
|
{
|
|
@@ -52,10 +56,10 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
52
56
|
}`)
|
|
53
57
|
writeGraphFile(t, filepath.Join(root, "src", "main.ts"), "import { winner } from '@generated/value';\nexport function main(): void { winner(); }\n")
|
|
54
58
|
writeGraphFile(t, filepath.Join(root, "fallback", "value.ts"), "export function winner(): void {}\n")
|
|
55
|
-
return "
|
|
59
|
+
return "first/value.ts"
|
|
56
60
|
},
|
|
57
61
|
add: func(t *testing.T, root string) {
|
|
58
|
-
writeGraphFile(t, filepath.Join(root, "first", "value.ts"), "export function winner(): void {}\
|
|
62
|
+
writeGraphFile(t, filepath.Join(root, "first", "value.ts"), "export function winner(): void {}\n")
|
|
59
63
|
},
|
|
60
64
|
},
|
|
61
65
|
{
|
|
@@ -71,10 +75,10 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
71
75
|
}`)
|
|
72
76
|
writeGraphFile(t, filepath.Join(root, "src", "views", "main.ts"), "import { winner } from './template';\nexport function main(): void { winner(); }\n")
|
|
73
77
|
writeGraphFile(t, filepath.Join(root, "generated", "views", "template.ts"), "export function winner(): void {}\n")
|
|
74
|
-
return "
|
|
78
|
+
return "src/views/template.ts"
|
|
75
79
|
},
|
|
76
80
|
add: func(t *testing.T, root string) {
|
|
77
|
-
writeGraphFile(t, filepath.Join(root, "src", "views", "template.ts"), "export function winner(): void {}\
|
|
81
|
+
writeGraphFile(t, filepath.Join(root, "src", "views", "template.ts"), "export function winner(): void {}\n")
|
|
78
82
|
},
|
|
79
83
|
},
|
|
80
84
|
{
|
|
@@ -86,10 +90,10 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
86
90
|
}`)
|
|
87
91
|
writeGraphFile(t, filepath.Join(root, "src", "deep", "main.ts"), "import { winner } from 'fixture-package';\nexport function main(): void { winner(); }\n")
|
|
88
92
|
writeGraphFile(t, filepath.Join(root, "node_modules", "fixture-package", "index.js"), "export function winner() {}\n")
|
|
89
|
-
return "
|
|
93
|
+
return "src/node_modules/fixture-package/index.ts"
|
|
90
94
|
},
|
|
91
95
|
add: func(t *testing.T, root string) {
|
|
92
|
-
writeGraphFile(t, filepath.Join(root, "src", "node_modules", "fixture-package", "index.ts"), "export function winner(): void {}\
|
|
96
|
+
writeGraphFile(t, filepath.Join(root, "src", "node_modules", "fixture-package", "index.ts"), "export function winner(): void {}\n")
|
|
93
97
|
},
|
|
94
98
|
},
|
|
95
99
|
{
|
|
@@ -113,8 +117,9 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
113
117
|
return ""
|
|
114
118
|
},
|
|
115
119
|
add: func(t *testing.T, root string) {
|
|
116
|
-
writeGraphFile(t, filepath.Join(root, "node_modules", "fixture-package", "dist", "first.js"), "export function winner() {}\
|
|
120
|
+
writeGraphFile(t, filepath.Join(root, "node_modules", "fixture-package", "dist", "first.js"), "export function winner() {}\n")
|
|
117
121
|
},
|
|
122
|
+
wantDiagnostic: "node_modules/fixture-package/dist/first.js",
|
|
118
123
|
},
|
|
119
124
|
{
|
|
120
125
|
name: "conditional_package_exports",
|
|
@@ -139,7 +144,7 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
139
144
|
}
|
|
140
145
|
}`)
|
|
141
146
|
writeGraphFile(t, filepath.Join(root, "node_modules", "fixture-package", "dist", "fallback.js"), "export function winner() {}\n")
|
|
142
|
-
return ""
|
|
147
|
+
return "node_modules/fixture-package/dist/types.d.ts"
|
|
143
148
|
},
|
|
144
149
|
add: func(t *testing.T, root string) {
|
|
145
150
|
writeGraphFile(t, filepath.Join(root, "node_modules", "fixture-package", "dist", "types.d.ts"), "export declare function winner(): void;\n")
|
|
@@ -168,7 +173,7 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
168
173
|
}`)
|
|
169
174
|
writeGraphFile(t, filepath.Join(root, "src", "main.ts"), "import { winner } from '#feature';\nexport function main(): void { winner(); }\n")
|
|
170
175
|
writeGraphFile(t, filepath.Join(root, "generated", "fallback.js"), "export function winner() {}\n")
|
|
171
|
-
return ""
|
|
176
|
+
return "generated/types.d.ts"
|
|
172
177
|
},
|
|
173
178
|
add: func(t *testing.T, root string) {
|
|
174
179
|
writeGraphFile(t, filepath.Join(root, "generated", "types.d.ts"), "export declare function winner(): void;\n")
|
|
@@ -183,10 +188,10 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
183
188
|
}`)
|
|
184
189
|
writeGraphFile(t, filepath.Join(root, "src", "main.ts"), "import { winner } from './feature';\nexport function main(): void { winner(); }\n")
|
|
185
190
|
writeGraphFile(t, filepath.Join(root, "src", "feature", "index.js"), "export function winner() {}\n")
|
|
186
|
-
return "
|
|
191
|
+
return "src/feature.js"
|
|
187
192
|
},
|
|
188
193
|
add: func(t *testing.T, root string) {
|
|
189
|
-
writeGraphFile(t, filepath.Join(root, "src", "feature.js"), "export function winner() {}\
|
|
194
|
+
writeGraphFile(t, filepath.Join(root, "src", "feature.js"), "export function winner() {}\n")
|
|
190
195
|
},
|
|
191
196
|
},
|
|
192
197
|
}
|
|
@@ -208,9 +213,30 @@ func TestServeSessionReloadsSupersedingModuleCandidates(t *testing.T) {
|
|
|
208
213
|
if err != nil {
|
|
209
214
|
t.Fatal(err)
|
|
210
215
|
}
|
|
211
|
-
if dump == nil || mode != serveModeReload || !changed ||
|
|
212
|
-
|
|
216
|
+
if dump == nil || mode != serveModeReload || !changed ||
|
|
217
|
+
(want != "" && !hasDumpNodeAt(*dump, "winner", want)) ||
|
|
218
|
+
(test.wantDiagnostic != "" && !hasDumpDiagnosticContaining(*dump, test.wantDiagnostic)) {
|
|
219
|
+
t.Fatalf("superseding candidate = dump:%v mode:%q changed:%v want-file:%q want-diagnostic:%q", dump != nil, mode, changed, want, test.wantDiagnostic)
|
|
213
220
|
}
|
|
214
221
|
})
|
|
215
222
|
}
|
|
216
223
|
}
|
|
224
|
+
|
|
225
|
+
func hasDumpNodeAt(dump graph.Dump, name, fileSuffix string) bool {
|
|
226
|
+
suffix := filepath.ToSlash(fileSuffix)
|
|
227
|
+
for _, node := range dump.Nodes {
|
|
228
|
+
if node.Name == name && strings.HasSuffix(filepath.ToSlash(node.File), suffix) {
|
|
229
|
+
return true
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return false
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
func hasDumpDiagnosticContaining(dump graph.Dump, fragment string) bool {
|
|
236
|
+
for _, diagnostic := range dump.Diagnostics {
|
|
237
|
+
if strings.Contains(filepath.ToSlash(diagnostic.Message), filepath.ToSlash(fragment)) {
|
|
238
|
+
return true
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return false
|
|
242
|
+
}
|
|
@@ -36,13 +36,13 @@ func TestServeSessionKeepsChangeDetectionLiveAfterInitialDumpError(t *testing.T)
|
|
|
36
36
|
if err == nil || !strings.Contains(err.Error(), "project root") {
|
|
37
37
|
t.Fatalf("initial dump error = %v, want absolute-root rejection", err)
|
|
38
38
|
}
|
|
39
|
-
if dump != nil || changed || !session.initialized || session.
|
|
39
|
+
if dump != nil || changed || !session.initialized || session.pending == nil || session.pending.mode != serveModeInitial {
|
|
40
40
|
t.Fatalf(
|
|
41
41
|
"failed initial state = dump:%v changed:%v initialized:%v pending:%q",
|
|
42
42
|
dump != nil,
|
|
43
43
|
changed,
|
|
44
44
|
session.initialized,
|
|
45
|
-
session.
|
|
45
|
+
session.pending.mode,
|
|
46
46
|
)
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -71,11 +71,11 @@ func TestServeSessionRetriesAPendingDumpBeforeUnchanged(t *testing.T) {
|
|
|
71
71
|
t.Fatalf("NewSession returned nil session (diagnostics: %v)", diags)
|
|
72
72
|
}
|
|
73
73
|
session := &graphSession{
|
|
74
|
-
cwd:
|
|
75
|
-
tsconfig:
|
|
76
|
-
compiler:
|
|
77
|
-
initialized:
|
|
78
|
-
|
|
74
|
+
cwd: root,
|
|
75
|
+
tsconfig: "tsconfig.json",
|
|
76
|
+
compiler: compiler,
|
|
77
|
+
initialized: true,
|
|
78
|
+
pending: &graphChange{mode: serveModeReload, full: true},
|
|
79
79
|
}
|
|
80
80
|
defer session.Close()
|
|
81
81
|
if err := session.captureState(); err != nil {
|
|
@@ -89,8 +89,8 @@ func TestServeSessionRetriesAPendingDumpBeforeUnchanged(t *testing.T) {
|
|
|
89
89
|
if dump == nil || mode != serveModeReload || !changed {
|
|
90
90
|
t.Fatalf("pending dump retry = dump:%v mode:%q changed:%v", dump != nil, mode, changed)
|
|
91
91
|
}
|
|
92
|
-
if session.
|
|
93
|
-
t.Fatalf("successful retry left pending
|
|
92
|
+
if session.pending != nil {
|
|
93
|
+
t.Fatalf("successful retry left pending change %#v", session.pending)
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
dump, mode, changed, err = session.Snapshot()
|