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.
Files changed (46) hide show
  1. package/cmd/ttscgraph/serve.go +264 -48
  2. package/cmd/ttscgraph/serve_early_error_encode_failure_is_observable_test.go +40 -0
  3. package/cmd/ttscgraph/serve_graph_snapshot_version_matches_typescript_client_test.go +32 -0
  4. package/cmd/ttscgraph/serve_phase_trace_accounts_for_load_failure_test.go +45 -0
  5. package/cmd/ttscgraph/serve_phase_trace_is_opt_in_and_payload_free_test.go +52 -0
  6. package/cmd/ttscgraph/serve_protocol_negotiates_incremental_shards_test.go +44 -0
  7. package/cmd/ttscgraph/serve_session_reloads_commonjs_package_entry_for_esm_test.go +2 -2
  8. package/cmd/ttscgraph/serve_session_reloads_superseding_module_candidates_test.go +46 -20
  9. package/cmd/ttscgraph/serve_session_retries_failed_dump_test.go +9 -9
  10. package/cmd/ttscgraph/serve_shards.go +1390 -0
  11. package/cmd/ttscgraph/serve_shards_abandoned_generation_converges_on_retry_test.go +92 -0
  12. package/cmd/ttscgraph/serve_shards_delete_removed_source_test.go +57 -0
  13. package/cmd/ttscgraph/serve_shards_external_endpoints_test.go +53 -0
  14. package/cmd/ttscgraph/serve_shards_keep_source_distributed_dependencies_at_the_boundary_test.go +108 -0
  15. package/cmd/ttscgraph/serve_shards_match_full_dump_oracle_test.go +88 -0
  16. package/cmd/ttscgraph/serve_shards_merge_pending_and_new_edits_test.go +50 -0
  17. package/cmd/ttscgraph/serve_shards_prune_unreferenced_external_endpoints_test.go +65 -0
  18. package/cmd/ttscgraph/serve_shards_publish_created_source_test.go +92 -0
  19. package/cmd/ttscgraph/serve_shards_rebuild_declaration_edit_test.go +43 -0
  20. package/cmd/ttscgraph/serve_shards_refresh_cross_file_implementation_test.go +63 -0
  21. package/cmd/ttscgraph/serve_shards_refresh_dependent_diagnostics_test.go +80 -0
  22. package/cmd/ttscgraph/serve_shards_rename_moves_source_identity_test.go +95 -0
  23. package/cmd/ttscgraph/serve_shards_retry_preserves_committed_generation_test.go +48 -0
  24. package/cmd/ttscgraph/serve_shards_reuse_unaffected_sources_test.go +121 -0
  25. package/driver/declaration_shape.go +85 -0
  26. package/driver/program.go +39 -10
  27. package/internal/graph/build.go +62 -10
  28. package/internal/graph/build_files_reuses_committed_cross_file_endpoints_test.go +87 -0
  29. package/internal/graph/build_keeps_source_distributed_dependencies_at_the_external_boundary_test.go +74 -0
  30. package/internal/graph/dump.go +84 -43
  31. package/internal/graph/dump_path_mapper_caches_alias_resolution_test.go +29 -0
  32. package/internal/graph/dump_paths.go +134 -11
  33. package/internal/graph/dump_paths_canonicalize_windows_short_root_test.go +39 -0
  34. package/internal/graph/dump_rejects_provenance_only_path_errors_test.go +32 -0
  35. package/internal/graph/dump_serializes_the_full_graph_test.go +2 -2
  36. package/internal/graph/dump_symlink_project_publishes_matching_base_test.go +82 -0
  37. package/internal/graph/edges.go +58 -16
  38. package/internal/graph/exports.go +9 -2
  39. package/internal/graph/graph.go +47 -7
  40. package/internal/graph/graph_kind_contracts_match_their_producers_test.go +121 -0
  41. package/internal/graph/node_modifiers_emit_union_strings_test.go +1 -1
  42. package/internal/graph/provenance.go +11 -1
  43. package/internal/graph/resolve.go +1 -4
  44. package/internal/graph/source.go +23 -0
  45. package/internal/graph/wire_node_ids_share_alias_resolution_test.go +29 -0
  46. 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 exposes the new target when one
19
- // carries a distinguishing declaration.
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 string
23
- setup func(*testing.T, string) string
24
- add func(*testing.T, string)
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 "typescriptWinner"
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 {}\nexport function typescriptWinner(): void {}\n")
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 "firstPathsWinner"
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 {}\nexport function firstPathsWinner(): void {}\n")
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 "rootDirsWinner"
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 {}\nexport function rootDirsWinner(): void {}\n")
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 "nearerNodeModulesWinner"
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 {}\nexport function nearerNodeModulesWinner(): void {}\n")
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() {}\nexport function exportsWinner() {}\n")
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 "fileWinner"
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() {}\nexport function fileWinner() {}\n")
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 || (want != "" && !hasDumpNode(*dump, want)) {
212
- t.Fatalf("superseding candidate = dump:%v mode:%q changed:%v want-node:%q", dump != nil, mode, changed, want)
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.pendingDumpMode != serveModeInitial {
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.pendingDumpMode,
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: root,
75
- tsconfig: "tsconfig.json",
76
- compiler: compiler,
77
- initialized: true,
78
- pendingDumpMode: serveModeReload,
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.pendingDumpMode != "" {
93
- t.Fatalf("successful retry left pending mode %q", session.pendingDumpMode)
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()