ttsc 0.22.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 (91) 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/go.mod +1 -1
  28. package/internal/graph/build.go +62 -10
  29. package/internal/graph/build_files_reuses_committed_cross_file_endpoints_test.go +87 -0
  30. package/internal/graph/build_keeps_source_distributed_dependencies_at_the_external_boundary_test.go +74 -0
  31. package/internal/graph/dump.go +84 -43
  32. package/internal/graph/dump_path_mapper_caches_alias_resolution_test.go +29 -0
  33. package/internal/graph/dump_paths.go +134 -11
  34. package/internal/graph/dump_paths_canonicalize_windows_short_root_test.go +39 -0
  35. package/internal/graph/dump_rejects_provenance_only_path_errors_test.go +32 -0
  36. package/internal/graph/dump_serializes_the_full_graph_test.go +2 -2
  37. package/internal/graph/dump_symlink_project_publishes_matching_base_test.go +82 -0
  38. package/internal/graph/edges.go +58 -16
  39. package/internal/graph/exports.go +9 -2
  40. package/internal/graph/graph.go +47 -7
  41. package/internal/graph/graph_kind_contracts_match_their_producers_test.go +121 -0
  42. package/internal/graph/node_modifiers_emit_union_strings_test.go +1 -1
  43. package/internal/graph/provenance.go +11 -1
  44. package/internal/graph/resolve.go +1 -4
  45. package/internal/graph/source.go +23 -0
  46. package/internal/graph/wire_node_ids_share_alias_resolution_test.go +29 -0
  47. package/internal/lspserver/lsp_launcher_reload_directory_fingerprint_parity_windows_test.go +94 -0
  48. package/internal/lspserver/lsp_project_input_glob_path_other.go +16 -0
  49. package/internal/lspserver/lsp_project_input_glob_path_windows.go +36 -0
  50. package/internal/lspserver/lsp_project_input_path_key_other.go +17 -0
  51. package/internal/lspserver/lsp_project_input_path_key_windows.go +228 -0
  52. package/internal/lspserver/lsp_project_input_path_key_windows_test.go +460 -0
  53. package/internal/lspserver/lsp_project_inputs.go +117 -49
  54. package/internal/lspserver/lsp_reload_directories_separate_glob_territory_test.go +181 -0
  55. package/lib/flags/schema.js +1 -1
  56. package/lib/flags/schema.js.map +1 -1
  57. package/lib/internal/projectInputPathIdentity.d.ts +13 -5
  58. package/lib/internal/projectInputPathIdentity.js +95 -41
  59. package/lib/internal/projectInputPathIdentity.js.map +1 -1
  60. package/lib/internal/windowsDirectoryCaseSensitivity.d.ts +10 -0
  61. package/lib/internal/windowsDirectoryCaseSensitivity.js +34 -0
  62. package/lib/internal/windowsDirectoryCaseSensitivity.js.map +1 -0
  63. package/lib/launcher/internal/runTtsc.js +5 -0
  64. package/lib/launcher/internal/runTtsc.js.map +1 -1
  65. package/lib/launcher/internal/runTtscserver.js +59 -8
  66. package/lib/launcher/internal/runTtscserver.js.map +1 -1
  67. package/lib/launcher/internal/runTtsx.js +61 -7
  68. package/lib/launcher/internal/runTtsx.js.map +1 -1
  69. package/lib/launcher/internal/runtimeHooks.d.ts +6 -5
  70. package/lib/launcher/internal/runtimeHooks.js +7 -15
  71. package/lib/launcher/internal/runtimeHooks.js.map +1 -1
  72. package/lib/launcher/internal/watchTopology.d.ts +82 -8
  73. package/lib/launcher/internal/watchTopology.js +535 -187
  74. package/lib/launcher/internal/watchTopology.js.map +1 -1
  75. package/lib/plugin/internal/descriptorProcessFailure.d.ts +32 -0
  76. package/lib/plugin/internal/descriptorProcessFailure.js +73 -0
  77. package/lib/plugin/internal/descriptorProcessFailure.js.map +1 -0
  78. package/lib/plugin/internal/loadProjectPlugins.js +29 -8
  79. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  80. package/package.json +12 -8
  81. package/src/flags/schema.ts +2 -1
  82. package/src/internal/projectInputPathIdentity.ts +150 -46
  83. package/src/internal/windowsDirectoryCaseSensitivity.ts +33 -0
  84. package/src/launcher/internal/runTtsc.ts +7 -0
  85. package/src/launcher/internal/runTtscserver.ts +81 -11
  86. package/src/launcher/internal/runTtsx.ts +87 -10
  87. package/src/launcher/internal/runtimeHooks.ts +16 -16
  88. package/src/launcher/internal/watchTopology.ts +679 -208
  89. package/src/plugin/internal/descriptorProcessFailure.ts +100 -0
  90. package/src/plugin/internal/loadProjectPlugins.ts +41 -8
  91. package/tools/shim_audit/baseline.json +0 -9
@@ -8,6 +8,7 @@ type WatchTopologyOptions = Pick<TtscBuildOptions, "binary" | "emit" | "env" | "
8
8
  type WatchTopologyCallbacks = {
9
9
  onError(location: string, error: unknown): void;
10
10
  onInputChange(change: WatchInputChange): void;
11
+ onProjectInputWatchUnavailable?(roots: readonly string[]): void;
11
12
  onProjectInputWatchRoots?(roots: readonly string[]): void;
12
13
  onTopologyChange(): void;
13
14
  };
@@ -35,11 +36,14 @@ export declare class WatchTopology {
35
36
  private readonly callbacks;
36
37
  private analysisOnly;
37
38
  private closed;
39
+ private compilerPostRegistrationMembershipRefresh;
40
+ private compilerPostRegistrationReconciliationScheduled;
41
+ private compilerPostRegistrationSkipUnobservedProjectInputWatchRoots;
38
42
  private directories;
39
43
  private directoryWatchers;
40
44
  private extraInputs;
41
45
  private extraWatchers;
42
- private compilerFileStamps;
46
+ private compilerFileSnapshots;
43
47
  private files;
44
48
  private fileWatchers;
45
49
  private observedDirectories;
@@ -49,14 +53,35 @@ export declare class WatchTopology {
49
53
  private projectInputMatches;
50
54
  private projectInputs;
51
55
  private declaredProjectInputs;
56
+ private projectInputRecoveryScheduled;
57
+ private projectInputPostRegistrationReconciliationScheduled;
52
58
  private projectInputRejectedWatchRoots;
59
+ private projectInputRequiredWatchRoots;
60
+ private projectInputUnobservedWatchRoots;
53
61
  private projectInputWatchRoots;
54
62
  private projectInputWatchers;
55
63
  private projectInputLinkWatchers;
64
+ private projectInputCompilerOutputOverlaps;
65
+ private projectInputCompilerAcknowledgements;
56
66
  private reloadFiles;
57
67
  constructor(options: WatchTopologyOptions, callbacks: WatchTopologyCallbacks);
58
68
  /** Re-resolve compiler inputs and notify only when their membership changed. */
59
69
  refresh(notify: boolean): void;
70
+ private refreshCompilerInputs;
71
+ /**
72
+ * Hand one Program-membership transition from the compiler lane to the
73
+ * overlapping project-input lane.
74
+ *
75
+ * Windows can deliver the compiler membership refresh before the recursive
76
+ * project watcher names the same creation. The rebuild scheduled here already
77
+ * consumes the current project bytes, so publishing their strong fingerprints
78
+ * keeps the later parent event from rediscovering the same population delta.
79
+ * A newly tracked compiler file also remembers that fingerprint until its
80
+ * first named content delivery; identical bytes are the delayed creation,
81
+ * while different bytes are a real later edit and remain observable even
82
+ * inside filesystem timestamp resolution.
83
+ */
84
+ private acknowledgeProjectInputCompilerMembership;
60
85
  /** Add Go plugin source trees discovered by the real build lane. */
61
86
  setExtraInputs(inputs: readonly string[]): void;
62
87
  /**
@@ -67,9 +92,19 @@ export declare class WatchTopology {
67
92
  /** Close every watcher so SIGINT/SIGTERM can drain the event loop. */
68
93
  close(): void;
69
94
  private syncFileWatchers;
70
- /** Whether a tracked file's bytes differ from the last stamp taken. */
71
- private compilerFileMoved;
95
+ /** Compare a tracked file's content and physical owner with its snapshot. */
96
+ private compilerFileMovement;
72
97
  private syncDirectoryWatchers;
98
+ /**
99
+ * Reconcile tracked compiler files after a newly registered watcher returns.
100
+ *
101
+ * A file or directory watcher can be returned before its backend is ready to
102
+ * deliver the first event. The compiler-file stamps were captured before
103
+ * registration, so one coalesced microtask can recover a change in that
104
+ * handoff window. A real event updates the same stamp first and makes this
105
+ * bounded scan a no-op.
106
+ */
107
+ private scheduleCompilerPostRegistrationReconciliation;
73
108
  /**
74
109
  * Narrow a plan's changes to the tracked files that actually moved.
75
110
  *
@@ -83,7 +118,7 @@ export declare class WatchTopology {
83
118
  * decided from the bytes, which is the question neither of them answered.
84
119
  */
85
120
  private compilerChangesToReport;
86
- private recordCompilerFileStamp;
121
+ private recordCompilerFileSnapshot;
87
122
  private rearmFileWatchers;
88
123
  private syncExtraWatchers;
89
124
  private syncProjectInputWatchers;
@@ -103,6 +138,44 @@ export declare class WatchTopology {
103
138
  /** Drop the watcher that just reported a directory replacement. */
104
139
  private retireProjectInputWatcher;
105
140
  private retainProjectInputWatchRoot;
141
+ /**
142
+ * Retry a failed root on the next reconciliation instead of retiring it for
143
+ * the session.
144
+ *
145
+ * This immediate recovery pass still honors the rejected root so it can
146
+ * install a safe ancestor where one exists. Only the recovery fixpoint
147
+ * reports a genuinely uncovered lane; transient gaps between fallback
148
+ * candidates are not user-visible. The rejection then expires. A later
149
+ * compiler refresh or an unchanged project-input republication can retry the
150
+ * original root, while a permanently failing backend costs at most one
151
+ * attempt per sync.
152
+ */
153
+ private scheduleProjectInputWatcherRecovery;
154
+ /**
155
+ * Reconcile the snapshot-to-watcher handoff after the caller's current turn.
156
+ *
157
+ * A recursive watcher can return before its backend is ready to deliver the
158
+ * first event. The publication baseline is necessarily captured before that
159
+ * watcher exists, so an input materialized synchronously after
160
+ * `setProjectInputs()` would otherwise depend entirely on that startup event.
161
+ * The ordinary fingerprint update makes this scan and a real backend event
162
+ * race safely: whichever arrives first records the new population and the
163
+ * other becomes a no-op.
164
+ */
165
+ private scheduleProjectInputPostRegistrationReconciliation;
166
+ /**
167
+ * Re-resolve declarations after watcher registration.
168
+ *
169
+ * A missing path can become a symlink before the handoff scan. The retained
170
+ * normalized snapshot still names the pre-link spelling in that case, so a
171
+ * scan can find the first target file without installing the physical owner
172
+ * that must observe later target changes.
173
+ */
174
+ private refreshPublishedProjectInputIdentities;
175
+ /** Drop retained owner choices for declarations no longer published. */
176
+ private pruneProjectInputWatchRoots;
177
+ /** Report only newly uncovered project-input roots as an observation loss. */
178
+ private reportUnobservedProjectInputWatchRoots;
106
179
  /**
107
180
  * One snapshot holding every spelling of every declaration.
108
181
  *
@@ -143,7 +216,7 @@ type SynchronizedWatcher = {
143
216
  close(): void;
144
217
  on(event: "error", listener: (error: Error) => void): unknown;
145
218
  };
146
- export declare function syncWatchers<T extends SynchronizedWatcher>(watchers: Map<string, T>, desired: ReadonlyMap<string, string>, create: (location: string, key: string) => T, onError: (location: string, error: unknown) => void): boolean;
219
+ export declare function syncWatchers<T extends SynchronizedWatcher>(watchers: Map<string, T>, desired: ReadonlyMap<string, string>, create: (location: string, key: string) => T, onError: (location: string, error: unknown) => void, shouldContinue?: () => boolean): boolean;
147
220
  export declare function literalGlobRoot(pattern: string): string;
148
221
  /**
149
222
  * Chooses the one stable recursive watcher root owned by a project-input
@@ -164,7 +237,7 @@ export declare function projectInputWatchDirectories(target: string, projectRoot
164
237
  * Removes recursive roots already covered by an ancestor without rewriting the
165
238
  * declaration-specific roots retained by WatchTopology.
166
239
  */
167
- export declare function projectInputActiveWatchDirectories(directories: Iterable<string>, identities?: ProjectInputPathIdentityContext): string[];
240
+ export declare function projectInputActiveWatchDirectories(directories: Iterable<string>, identities?: import("../../internal/projectInputPathIdentity").FilesystemPathIdentityContext): string[];
168
241
  export declare function projectInputAvailableWatchDirectory(location: string, rejected: ReadonlySet<string>, identities?: ProjectInputPathIdentityContext, projectRoot?: string): string | undefined;
169
242
  /**
170
243
  * Whether a replacement at this path leaves a recursive watcher bound to the
@@ -186,7 +259,7 @@ export declare function projectInputAvailableWatchDirectory(location: string, re
186
259
  * since its fingerprint is a digest of its own immediate entries and nothing
187
260
  * below it can reach the declared corpus.
188
261
  */
189
- export declare function projectInputReplacementStrandsWatchers(snapshot: ITtscProjectInputSnapshot, location: string, identities?: ProjectInputPathIdentityContext, platform?: NodeJS.Platform): boolean;
262
+ export declare function projectInputReplacementStrandsWatchers(snapshot: ITtscProjectInputSnapshot, location: string, identities?: import("../../internal/projectInputPathIdentity").FilesystemPathIdentityContext, platform?: NodeJS.Platform): boolean;
190
263
  /**
191
264
  * Decide whether an event that named no declared input can still have moved
192
265
  * one.
@@ -198,7 +271,7 @@ export declare function projectInputReplacementStrandsWatchers(snapshot: ITtscPr
198
271
  * inferred from a rebuild that a silent rescan and a skipped rescan produce
199
272
  * identically.
200
273
  */
201
- export declare function projectInputTopologyMayAffect(snapshot: ITtscProjectInputSnapshot, location: string, previous: ReadonlyMap<string, string>, identities?: ProjectInputPathIdentityContext): boolean;
274
+ export declare function projectInputTopologyMayAffect(snapshot: ITtscProjectInputSnapshot, location: string, previous: ReadonlyMap<string, string>, identities?: import("../../internal/projectInputPathIdentity").FilesystemPathIdentityContext): boolean;
202
275
  export declare function projectInputEventShouldNotify(input: {
203
276
  contentChanged: boolean;
204
277
  directlyMatched: boolean;
@@ -213,6 +286,7 @@ export declare function projectInputEventShouldNotify(input: {
213
286
  * bytes remain quiet before this classifier is observed.
214
287
  */
215
288
  export declare function projectInputReloadEventShouldNotify(input: {
289
+ causedBy?: readonly string[];
216
290
  changed?: string;
217
291
  changedInputs: readonly string[];
218
292
  reloadDirectories?: readonly string[];