ttsc 0.23.0 → 0.25.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/LICENSE +21 -21
- package/README.md +66 -63
- package/cmd/ttscgraph/serve.go +264 -48
- package/cmd/ttscgraph/serve_answers_a_project_that_implements_its_own_ambient_declaration_test.go +69 -0
- 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/go.sum +22 -22
- package/internal/graph/assigned_implementations_of_declaration_file_symbols_leave_no_edge_source_test.go +84 -0
- package/internal/graph/assigned_implementations_of_node_modules_symbols_leave_no_edge_source_test.go +85 -0
- 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 +73 -17
- 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/internal/lspserver/lsp_native_plugin_source.go +5 -6
- package/internal/lspserver/lsp_native_resident.go +17 -24
- package/lib/TtscService.d.ts +1 -6
- package/lib/TtscService.js +2 -2
- package/lib/TtscService.js.map +1 -1
- package/lib/compiler/internal/captureProcessOutput.d.ts +26 -0
- package/lib/compiler/internal/captureProcessOutput.js +92 -0
- package/lib/compiler/internal/captureProcessOutput.js.map +1 -0
- package/lib/compiler/internal/compileProjectInMemory.js +4 -7
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/residentCheckProcess.d.ts +0 -2
- package/lib/compiler/internal/residentCheckProcess.js +1 -15
- package/lib/compiler/internal/residentCheckProcess.js.map +1 -1
- package/lib/compiler/internal/residentTransformProcess.d.ts +0 -6
- package/lib/compiler/internal/residentTransformProcess.js +0 -25
- package/lib/compiler/internal/residentTransformProcess.js.map +1 -1
- package/lib/compiler/internal/spawnNative.d.ts +14 -6
- package/lib/compiler/internal/spawnNative.js +32 -11
- package/lib/compiler/internal/spawnNative.js.map +1 -1
- package/lib/compiler/internal/startResidentTransform.d.ts +1 -5
- package/lib/compiler/internal/startResidentTransform.js +1 -3
- package/lib/compiler/internal/startResidentTransform.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.d.ts +2 -1
- package/lib/launcher/internal/prepareExecution.js +269 -23
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/registerRuntimeHooks.js +6 -1
- package/lib/launcher/internal/registerRuntimeHooks.js.map +1 -1
- package/lib/launcher/internal/runTtscserver.js +4 -9
- package/lib/launcher/internal/runTtscserver.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +2 -55
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/launcher/internal/runtimeHooks.d.ts +25 -2
- package/lib/launcher/internal/runtimeHooks.js +344 -69
- package/lib/launcher/internal/runtimeHooks.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.js +31 -3
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/descriptorProcessFailure.d.ts +23 -19
- package/lib/plugin/internal/descriptorProcessFailure.js +40 -51
- package/lib/plugin/internal/descriptorProcessFailure.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +12 -0
- package/lib/plugin/internal/loadProjectPlugins.js +77 -28
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/package.json +8 -8
- package/shim/ast/extra-shim.json +4 -4
- package/shim/ast/go.mod +14 -14
- package/shim/ast/go.sum +20 -20
- package/shim/astnav/go.mod +14 -14
- package/shim/astnav/go.sum +20 -20
- package/shim/bundled/extra-shim.json +1 -1
- package/shim/bundled/go.mod +5 -5
- package/shim/checker/extra-shim.json +31 -31
- package/shim/checker/go.mod +5 -5
- package/shim/compiler/extra-shim.json +4 -4
- package/shim/compiler/go.mod +14 -14
- package/shim/compiler/go.sum +22 -22
- package/shim/core/extra-shim.json +4 -4
- package/shim/core/go.mod +5 -5
- package/shim/diagnosticwriter/go.mod +5 -5
- package/shim/lsp/extra-shim.json +4 -4
- package/shim/lsp/go.mod +16 -16
- package/shim/lsp/go.sum +26 -26
- package/shim/parser/extra-shim.json +4 -4
- package/shim/parser/go.mod +5 -5
- package/shim/printer/go.mod +14 -14
- package/shim/printer/go.sum +22 -22
- package/shim/scanner/extra-shim.json +4 -4
- package/shim/scanner/go.mod +5 -5
- package/shim/transformers/go.mod +14 -14
- package/shim/transformers/go.sum +20 -20
- package/shim/tsoptions/extra-shim.json +4 -4
- package/shim/tsoptions/go.mod +5 -5
- package/shim/tspath/extra-shim.json +4 -4
- package/shim/tspath/go.mod +5 -5
- package/shim/vfs/cachedvfs/extra-shim.json +4 -4
- package/shim/vfs/cachedvfs/go.mod +5 -5
- package/shim/vfs/extra-shim.json +4 -4
- package/shim/vfs/go.mod +5 -5
- package/shim/vfs/osvfs/extra-shim.json +4 -4
- package/shim/vfs/osvfs/go.mod +5 -5
- package/src/TtscService.ts +8 -20
- package/src/compiler/internal/captureProcessOutput.ts +96 -0
- package/src/compiler/internal/compileProjectInMemory.ts +7 -7
- package/src/compiler/internal/residentCheckProcess.ts +1 -21
- package/src/compiler/internal/residentTransformProcess.ts +0 -42
- package/src/compiler/internal/spawnNative.ts +39 -18
- package/src/compiler/internal/startResidentTransform.ts +1 -12
- package/src/launcher/internal/prepareExecution.ts +297 -26
- package/src/launcher/internal/registerRuntimeHooks.ts +11 -2
- package/src/launcher/internal/runTtscserver.ts +4 -9
- package/src/launcher/internal/runTtsx.ts +2 -78
- package/src/launcher/internal/runtimeHooks.ts +385 -82
- package/src/plugin/internal/buildSourcePlugin.ts +36 -3
- package/src/plugin/internal/descriptorProcessFailure.ts +34 -65
- package/src/plugin/internal/loadProjectPlugins.ts +78 -39
- package/tools/gen_shims/go.mod +14 -14
- package/tools/gen_shims/go.sum +12 -12
- package/tools/shim_audit/go.mod +10 -10
- package/tools/shim_audit/go.sum +8 -8
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
package graph
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"regexp"
|
|
7
|
+
"sort"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
// TestGraphKindContractsMatchTheirProducers keeps the hand-authored TypeScript
|
|
12
|
+
// unions exact: raw dump kinds equal the Go producer, general kinds add only the
|
|
13
|
+
// TypeScript memory/trace synthesis, and modifiers equal the emitted flag table.
|
|
14
|
+
//
|
|
15
|
+
// 1. Read every published graph-kind and modifier union.
|
|
16
|
+
// 2. Derive raw dump values from the native constants and wire mapping.
|
|
17
|
+
// 3. Apply the memory layer's module fold and synthetic kinds.
|
|
18
|
+
// 4. Assert every published union equals its producer set exactly.
|
|
19
|
+
func TestGraphKindContractsMatchTheirProducers(t *testing.T) {
|
|
20
|
+
structures := filepath.Join("..", "..", "..", "graph", "src", "structures")
|
|
21
|
+
rawNodes := stringUnion(t, filepath.Join(structures, "TtscGraphDumpNodeKind.ts"), "TtscGraphDumpNodeKind")
|
|
22
|
+
rawEdges := stringUnion(t, filepath.Join(structures, "TtscGraphDumpEdgeKind.ts"), "TtscGraphDumpEdgeKind")
|
|
23
|
+
nodes := stringUnion(t, filepath.Join(structures, "TtscGraphNodeKind.ts"), "TtscGraphNodeKind")
|
|
24
|
+
edges := stringUnion(t, filepath.Join(structures, "TtscGraphEdgeKind.ts"), "TtscGraphEdgeKind")
|
|
25
|
+
modifiers := stringUnion(t, filepath.Join(structures, "TtscGraphNodeModifier.ts"), "TtscGraphNodeModifier")
|
|
26
|
+
|
|
27
|
+
source, err := os.ReadFile("graph.go")
|
|
28
|
+
if err != nil {
|
|
29
|
+
t.Fatalf("read graph.go: %v", err)
|
|
30
|
+
}
|
|
31
|
+
nodeConstants := sourceConstants(t, source, `(?m)^\s*Node[A-Za-z0-9_]*\s+NodeKind\s*=\s*"([^"]+)"`)
|
|
32
|
+
edgeConstants := sourceConstants(t, source, `(?m)^\s*Edge[A-Za-z0-9_]*\s+EdgeKind\s*=\s*"([^"]+)"`)
|
|
33
|
+
|
|
34
|
+
assertStringSet(t, "raw dump node kinds", rawNodes, nodeConstants)
|
|
35
|
+
assertStringSet(t, "raw dump edge kinds", rawEdges, producedWireEdgeKinds(edgeConstants))
|
|
36
|
+
memoryNodeKinds := withoutString(nodeConstants, "module")
|
|
37
|
+
assertStringSet(t, "general graph node kinds", nodes, append(memoryNodeKinds, "file", "property"))
|
|
38
|
+
assertStringSet(t, "general graph edge kinds", edges, append(append([]string{}, producedWireEdgeKinds(edgeConstants)...), "contains", "dispatches"))
|
|
39
|
+
|
|
40
|
+
emittedModifiers := make([]string, 0, len(modifierFlagStrings))
|
|
41
|
+
for _, modifier := range modifierFlagStrings {
|
|
42
|
+
emittedModifiers = append(emittedModifiers, modifier.text)
|
|
43
|
+
}
|
|
44
|
+
assertStringSet(t, "graph node modifiers", modifiers, emittedModifiers)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func withoutString(values []string, excluded string) []string {
|
|
48
|
+
out := make([]string, 0, len(values))
|
|
49
|
+
for _, value := range values {
|
|
50
|
+
if value != excluded {
|
|
51
|
+
out = append(out, value)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return out
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
func stringUnion(t *testing.T, path, name string) []string {
|
|
58
|
+
t.Helper()
|
|
59
|
+
source, err := os.ReadFile(path)
|
|
60
|
+
if err != nil {
|
|
61
|
+
t.Fatalf("read %s: %v", path, err)
|
|
62
|
+
}
|
|
63
|
+
declaration := regexp.MustCompile(`(?s)export type ` + regexp.QuoteMeta(name) + `\s*=\s*(.*?);`).FindSubmatch(source)
|
|
64
|
+
if declaration == nil {
|
|
65
|
+
t.Fatalf("find exported union %s in %s", name, path)
|
|
66
|
+
}
|
|
67
|
+
return sourceConstants(t, declaration[1], `"([^"]+)"`)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func sourceConstants(t *testing.T, source []byte, pattern string) []string {
|
|
71
|
+
t.Helper()
|
|
72
|
+
matches := regexp.MustCompile(pattern).FindAllSubmatch(source, -1)
|
|
73
|
+
if len(matches) == 0 {
|
|
74
|
+
t.Fatalf("no string constants matched %q", pattern)
|
|
75
|
+
}
|
|
76
|
+
values := make([]string, 0, len(matches))
|
|
77
|
+
for _, match := range matches {
|
|
78
|
+
values = append(values, string(match[1]))
|
|
79
|
+
}
|
|
80
|
+
return values
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func producedWireEdgeKinds(constants []string) []string {
|
|
84
|
+
values := map[string]bool{}
|
|
85
|
+
for _, constant := range constants {
|
|
86
|
+
kind := EdgeKind(constant)
|
|
87
|
+
origins := []string{""}
|
|
88
|
+
switch kind {
|
|
89
|
+
case EdgeValueCall:
|
|
90
|
+
origins = []string{"call", "new", "jsx", "tagged"}
|
|
91
|
+
case EdgeHeritage:
|
|
92
|
+
origins = []string{"extends", "implements"}
|
|
93
|
+
case EdgeMemberRelation:
|
|
94
|
+
origins = []string{"implements", "overrides"}
|
|
95
|
+
}
|
|
96
|
+
for _, origin := range origins {
|
|
97
|
+
values[wireEdgeKind(kind, origin)] = true
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
out := make([]string, 0, len(values))
|
|
101
|
+
for value := range values {
|
|
102
|
+
out = append(out, value)
|
|
103
|
+
}
|
|
104
|
+
return out
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
func assertStringSet(t *testing.T, name string, got, want []string) {
|
|
108
|
+
t.Helper()
|
|
109
|
+
got = append([]string{}, got...)
|
|
110
|
+
want = append([]string{}, want...)
|
|
111
|
+
sort.Strings(got)
|
|
112
|
+
sort.Strings(want)
|
|
113
|
+
if len(got) != len(want) {
|
|
114
|
+
t.Fatalf("%s = %v, want %v", name, got, want)
|
|
115
|
+
}
|
|
116
|
+
for i := range got {
|
|
117
|
+
if got[i] != want[i] {
|
|
118
|
+
t.Fatalf("%s = %v, want %v", name, got, want)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -87,7 +87,7 @@ export const enum Mode {
|
|
|
87
87
|
union := map[string]bool{
|
|
88
88
|
"export": true, "default": true, "declare": true, "abstract": true,
|
|
89
89
|
"static": true, "readonly": true, "async": true, "const": true,
|
|
90
|
-
"public": true, "private": true, "protected": true,
|
|
90
|
+
"public": true, "private": true, "protected": true,
|
|
91
91
|
}
|
|
92
92
|
for _, n := range dump.Nodes {
|
|
93
93
|
for _, m := range n.Modifiers {
|
|
@@ -5,6 +5,7 @@ import (
|
|
|
5
5
|
"encoding/hex"
|
|
6
6
|
"sort"
|
|
7
7
|
|
|
8
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
8
9
|
shimcore "github.com/microsoft/typescript-go/shim/core"
|
|
9
10
|
|
|
10
11
|
"github.com/samchon/ttsc/packages/ttsc/driver"
|
|
@@ -273,7 +274,16 @@ func NewProvenance(
|
|
|
273
274
|
// every file the graph would otherwise only have bound. Callers that do not
|
|
274
275
|
// publish diagnostics should not call it.
|
|
275
276
|
func NewDiagnostics(prog *driver.Program) []Diagnostic {
|
|
276
|
-
|
|
277
|
+
return newDiagnostics(prog.Diagnostics())
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// NewDiagnosticsForFiles projects compiler findings for one invalidated source
|
|
281
|
+
// closure without forcing semantic diagnostics for every unchanged file.
|
|
282
|
+
func NewDiagnosticsForFiles(prog *driver.Program, files []*shimast.SourceFile) []Diagnostic {
|
|
283
|
+
return newDiagnostics(prog.DiagnosticsForFiles(files))
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
func newDiagnostics(raw []driver.Diagnostic) []Diagnostic {
|
|
277
287
|
out := make([]Diagnostic, 0, len(raw))
|
|
278
288
|
for _, diagnostic := range raw {
|
|
279
289
|
out = append(out, Diagnostic{
|
|
@@ -18,8 +18,6 @@
|
|
|
18
18
|
package graph
|
|
19
19
|
|
|
20
20
|
import (
|
|
21
|
-
"strings"
|
|
22
|
-
|
|
23
21
|
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
24
22
|
shimchecker "github.com/microsoft/typescript-go/shim/checker"
|
|
25
23
|
)
|
|
@@ -80,8 +78,7 @@ func Resolve(checker *shimchecker.Checker, ref *shimast.Node) *Target {
|
|
|
80
78
|
target.End = declaration.End()
|
|
81
79
|
if file := shimast.GetSourceFileOfNode(declaration); file != nil {
|
|
82
80
|
target.File = file.FileName()
|
|
83
|
-
target.External = file
|
|
84
|
-
strings.Contains(target.File, "/node_modules/")
|
|
81
|
+
target.External = !IsWorkspaceSourceFile(file)
|
|
85
82
|
}
|
|
86
83
|
}
|
|
87
84
|
return target
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package graph
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"strings"
|
|
5
|
+
|
|
6
|
+
shimast "github.com/microsoft/typescript-go/shim/ast"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// IsWorkspaceSourceFile reports whether file owns declarations and outgoing
|
|
10
|
+
// facts in the project graph. Declaration files and sources physically resident
|
|
11
|
+
// under node_modules are external boundary inputs even when the checker loads a
|
|
12
|
+
// package's raw TypeScript entry for type checking.
|
|
13
|
+
//
|
|
14
|
+
// Symlinked workspace packages remain authored source: the checker resolves the
|
|
15
|
+
// default preserveSymlinks=false path to their real workspace location before
|
|
16
|
+
// this predicate sees it.
|
|
17
|
+
func IsWorkspaceSourceFile(file *shimast.SourceFile) bool {
|
|
18
|
+
if file == nil || file.IsDeclarationFile {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
normalized := strings.ReplaceAll(file.FileName(), "\\", "/")
|
|
22
|
+
return !strings.Contains("/"+strings.TrimPrefix(normalized, "/"), "/node_modules/")
|
|
23
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package graph
|
|
2
|
+
|
|
3
|
+
import "testing"
|
|
4
|
+
|
|
5
|
+
// TestWireNodeIDsShareAliasResolution verifies the public resident shard
|
|
6
|
+
// helper keeps declarations from one physical source distinct and stable.
|
|
7
|
+
//
|
|
8
|
+
// External declarations commonly share a package source file. Mapping the IDs
|
|
9
|
+
// as one batch must preserve the shared source coordinate without collisions.
|
|
10
|
+
//
|
|
11
|
+
// 1. Build two declaration IDs owned by one physical dependency source.
|
|
12
|
+
// 2. Map both IDs through the public batch helper.
|
|
13
|
+
// 3. Require distinct IDs with the same portable source coordinate.
|
|
14
|
+
func TestWireNodeIDsShareAliasResolution(t *testing.T) {
|
|
15
|
+
source := "C:/checkout/app/node_modules/pkg/index.d.ts"
|
|
16
|
+
first := nodeID(source, "First", NodeClass)
|
|
17
|
+
second := nodeID(source, "Second", NodeClass)
|
|
18
|
+
wire, err := WireNodeIDs("C:/checkout/app", []string{first, second})
|
|
19
|
+
if err != nil {
|
|
20
|
+
t.Fatal(err)
|
|
21
|
+
}
|
|
22
|
+
if wire[first] == wire[second] {
|
|
23
|
+
t.Fatalf("wire IDs collide: %q", wire[first])
|
|
24
|
+
}
|
|
25
|
+
expectedSource := "node_modules/pkg/index.d.ts"
|
|
26
|
+
if nodeFile(wire[first]) != expectedSource || nodeFile(wire[second]) != expectedSource {
|
|
27
|
+
t.Fatalf("wire source coordinates = %q and %q, want %q", nodeFile(wire[first]), nodeFile(wire[second]), expectedSource)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -11,10 +11,8 @@ import (
|
|
|
11
11
|
"strings"
|
|
12
12
|
"sync"
|
|
13
13
|
"sync/atomic"
|
|
14
|
-
"time"
|
|
15
14
|
)
|
|
16
15
|
|
|
17
|
-
const nativePluginCommandTimeout = 30 * time.Second
|
|
18
16
|
const nativePluginCommandStdoutLimit = 4 * 1024 * 1024
|
|
19
17
|
const nativePluginCommandStderrLimit = 1024 * 1024
|
|
20
18
|
|
|
@@ -825,7 +823,11 @@ func (s *NativePluginSource) runWithStdin(plugin NativeLSPPluginEntry, command s
|
|
|
825
823
|
if strings.TrimSpace(plugin.Binary) == "" {
|
|
826
824
|
return nil, fmt.Errorf("ttscserver: %s has no binary", pluginLabel(plugin))
|
|
827
825
|
}
|
|
828
|
-
|
|
826
|
+
// No deadline: the command is running the user's own rules, and how long
|
|
827
|
+
// that takes is not this process's call. The context stays so that a future
|
|
828
|
+
// early return cannot leave the child running — cancelling it kills the
|
|
829
|
+
// process rather than abandoning it.
|
|
830
|
+
ctx, cancel := context.WithCancel(context.Background())
|
|
829
831
|
defer cancel()
|
|
830
832
|
allArgs := []string{
|
|
831
833
|
command,
|
|
@@ -848,9 +850,6 @@ func (s *NativePluginSource) runWithStdin(plugin NativeLSPPluginEntry, command s
|
|
|
848
850
|
cmd.Stdout = &stdout
|
|
849
851
|
cmd.Stderr = &stderr
|
|
850
852
|
err := cmd.Run()
|
|
851
|
-
if ctx.Err() != nil {
|
|
852
|
-
return nil, fmt.Errorf("ttscserver: %s %s timed out", pluginLabel(plugin), command)
|
|
853
|
-
}
|
|
854
853
|
if err != nil {
|
|
855
854
|
msg := strings.TrimSpace(stderr.String())
|
|
856
855
|
if msg == "" {
|
|
@@ -9,15 +9,8 @@ import (
|
|
|
9
9
|
"os/exec"
|
|
10
10
|
"strings"
|
|
11
11
|
"sync"
|
|
12
|
-
"time"
|
|
13
12
|
)
|
|
14
13
|
|
|
15
|
-
// residentRequestTimeout bounds one resident verb round trip, mirroring the
|
|
16
|
-
// spawn-per-verb path's nativePluginCommandTimeout. A rule that hangs must not
|
|
17
|
-
// wedge the daemon's request mutex forever; on timeout the sidecar is killed and
|
|
18
|
-
// the caller falls back to a fresh spawn.
|
|
19
|
-
const residentRequestTimeout = nativePluginCommandTimeout
|
|
20
|
-
|
|
21
14
|
// The serve verbs below are routed to the resident daemon because they load a
|
|
22
15
|
// Program.
|
|
23
16
|
// lsp-command-ids / lsp-code-action-kinds run once at startup and never load one
|
|
@@ -121,8 +114,10 @@ func (s *NativePluginSource) serveRun(plugin NativeLSPPluginEntry, verb string,
|
|
|
121
114
|
}
|
|
122
115
|
|
|
123
116
|
// call sends one request to the daemon and reads its reply, serializing access
|
|
124
|
-
// to the single pipe. It spawns the child on first use or after a death
|
|
125
|
-
//
|
|
117
|
+
// to the single pipe. It spawns the child on first use or after a death. The
|
|
118
|
+
// read is unbounded — the rule is the user's own code — and the mutex is held
|
|
119
|
+
// only as long as the sidecar is alive, because its death closes stdout and
|
|
120
|
+
// ends the read.
|
|
126
121
|
func (sc *residentSidecar) call(s *NativePluginSource, plugin NativeLSPPluginEntry, req serveClientRequest) ([]byte, int, error) {
|
|
127
122
|
sc.mu.Lock()
|
|
128
123
|
defer sc.mu.Unlock()
|
|
@@ -162,23 +157,21 @@ func (sc *residentSidecar) call(s *NativePluginSource, plugin NativeLSPPluginEnt
|
|
|
162
157
|
raw, err := sc.stdout.ReadBytes('\n')
|
|
163
158
|
done <- readResult{line: raw, err: err}
|
|
164
159
|
}()
|
|
165
|
-
|
|
166
|
-
|
|
160
|
+
// No deadline: a rule that takes a long time is the user's own code running,
|
|
161
|
+
// and the read still ends the moment the sidecar dies, because closing its
|
|
162
|
+
// stdout surfaces here as a read error.
|
|
163
|
+
res := <-done
|
|
164
|
+
if res.err != nil {
|
|
167
165
|
sc.kill()
|
|
168
|
-
return nil, 0,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
var resp serveClientResponse
|
|
175
|
-
if err := json.Unmarshal(res.line, &resp); err != nil {
|
|
176
|
-
sc.kill()
|
|
177
|
-
return nil, 0, err
|
|
178
|
-
}
|
|
179
|
-
sc.everServed = true
|
|
180
|
-
return resp.Result, resp.Code, nil
|
|
166
|
+
return nil, 0, res.err
|
|
167
|
+
}
|
|
168
|
+
var resp serveClientResponse
|
|
169
|
+
if err := json.Unmarshal(res.line, &resp); err != nil {
|
|
170
|
+
sc.kill()
|
|
171
|
+
return nil, 0, err
|
|
181
172
|
}
|
|
173
|
+
sc.everServed = true
|
|
174
|
+
return resp.Result, resp.Code, nil
|
|
182
175
|
}
|
|
183
176
|
|
|
184
177
|
// spawn starts the resident child with the base project args and the lsp-serve
|
package/lib/TtscService.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import type { ITtscCompilerContext } from "./structures/ITtscCompilerContext";
|
|
2
|
-
/** Construction controls for the resident transform request lifecycle. */
|
|
3
|
-
export interface TtscServiceOptions {
|
|
4
|
-
/** Maximum time one transform or update request may await the host's reply. */
|
|
5
|
-
requestTimeoutMs?: number;
|
|
6
|
-
}
|
|
7
2
|
/** Per-call controls for a resident transform or update request. */
|
|
8
3
|
export interface TtscServiceRequestOptions {
|
|
9
4
|
/** Abort this call before it receives a reply. */
|
|
@@ -41,7 +36,7 @@ export declare class TtscService {
|
|
|
41
36
|
* host. The context is the same shape {@link TtscCompiler} accepts; it is not
|
|
42
37
|
* replaceable per call.
|
|
43
38
|
*/
|
|
44
|
-
constructor(context?: ITtscCompilerContext
|
|
39
|
+
constructor(context?: ITtscCompilerContext);
|
|
45
40
|
/**
|
|
46
41
|
* Return the transformed TypeScript source for one file, or `undefined` when
|
|
47
42
|
* the resident program does not contain it (for example a file excluded from
|
package/lib/TtscService.js
CHANGED
|
@@ -38,14 +38,14 @@ class TtscService {
|
|
|
38
38
|
* host. The context is the same shape {@link TtscCompiler} accepts; it is not
|
|
39
39
|
* replaceable per call.
|
|
40
40
|
*/
|
|
41
|
-
constructor(context = {}
|
|
41
|
+
constructor(context = {}) {
|
|
42
42
|
const started = (0, startResidentTransform_1.startResidentTransform)({
|
|
43
43
|
...context,
|
|
44
44
|
env: context.env ? { ...context.env } : undefined,
|
|
45
45
|
plugins: Array.isArray(context.plugins)
|
|
46
46
|
? [...context.plugins]
|
|
47
47
|
: context.plugins,
|
|
48
|
-
}
|
|
48
|
+
});
|
|
49
49
|
this.resident = started.process;
|
|
50
50
|
this.projectRoot = started.projectRoot;
|
|
51
51
|
}
|
package/lib/TtscService.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtscService.js","sourceRoot":"","sources":["../src/TtscService.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAG7B,uFAAoF;
|
|
1
|
+
{"version":3,"file":"TtscService.js","sourceRoot":"","sources":["../src/TtscService.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAG7B,uFAAoF;AASpF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;IACmB,QAAQ,CAA2B;IACnC,WAAW,CAAS;IAErC;;;;OAIG;IACH,YAAmB,OAAO,GAAyB,EAAE;QACnD,MAAM,OAAO,GAAG,IAAA,+CAAsB,EAAC;YACrC,GAAG,OAAO;YACV,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;YACjD,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;gBACrC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;gBACtB,CAAC,CAAC,OAAO,CAAC,OAAO;SACpB,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,aAAa,CACxB,QAAgB,EAChB,OAAO,GAA8B,EAAE;QAEvC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CACvC,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,EACrC,WAAW,EACX,OAAO,CACR,CAAC;QACF,0EAA0E;QAC1E,uEAAuE;QACvE,wEAAwE;QACxE,uEAAuE;QACvE,OAAO,KAAK,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ;YACjE,CAAC,CAAC,KAAK,CAAC,UAAU;YAClB,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,UAAU,CACrB,QAAgB,EAChB,OAAe,EACf,OAAO,GAA8B,EAAE;QAEvC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CACvC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,EAChD,QAAQ,EACR,OAAO,CACR,CAAC;QACF,4EAA4E;QAC5E,4EAA4E;QAC5E,yDAAyD;QACzD,OAAO,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC;IAChC,CAAC;IAED,qEAAqE;IAC9D,OAAO;QACZ,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAEO,YAAY,CAAC,QAAgB;QACnC,OAAO,mBAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAC9B,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,mBAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface CapturedProcessOutput {
|
|
2
|
+
/** Close the descriptors and remove the backing files. */
|
|
3
|
+
dispose(): void;
|
|
4
|
+
/** Read one stream's bytes, decoded unless `"buffer"` is asked for. */
|
|
5
|
+
read(stream: "stdout" | "stderr", encoding: BufferEncoding | "buffer" | undefined): string | Buffer;
|
|
6
|
+
stderrFd: number;
|
|
7
|
+
stdoutFd: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A pair of temporary files standing in for a child process's pipes.
|
|
11
|
+
*
|
|
12
|
+
* `spawnSync` holds a _piped_ stream in this process's memory and refuses to
|
|
13
|
+
* keep more than `maxBuffer` bytes, so any piped capture has to name a ceiling
|
|
14
|
+
* — and a ceiling is a number nobody chose for this machine, deciding on the
|
|
15
|
+
* user's behalf that a large but legitimate build said too much. Handing the
|
|
16
|
+
* child a file descriptor instead means the bytes never pass through this heap
|
|
17
|
+
* on their way out of the child: how much a process may write is the
|
|
18
|
+
* filesystem's business, and that is the same answer on every machine. Reading
|
|
19
|
+
* the result back still materializes a string, so V8's own maximum string
|
|
20
|
+
* length remains the outer bound — but that is a property of the runtime rather
|
|
21
|
+
* than a budget chosen here, and it is identical everywhere this runs.
|
|
22
|
+
*
|
|
23
|
+
* The directory is per-call, so two concurrent spawns cannot read each other's
|
|
24
|
+
* bytes.
|
|
25
|
+
*/
|
|
26
|
+
export declare function captureProcessOutput(): CapturedProcessOutput;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.captureProcessOutput = captureProcessOutput;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
/**
|
|
11
|
+
* A pair of temporary files standing in for a child process's pipes.
|
|
12
|
+
*
|
|
13
|
+
* `spawnSync` holds a _piped_ stream in this process's memory and refuses to
|
|
14
|
+
* keep more than `maxBuffer` bytes, so any piped capture has to name a ceiling
|
|
15
|
+
* — and a ceiling is a number nobody chose for this machine, deciding on the
|
|
16
|
+
* user's behalf that a large but legitimate build said too much. Handing the
|
|
17
|
+
* child a file descriptor instead means the bytes never pass through this heap
|
|
18
|
+
* on their way out of the child: how much a process may write is the
|
|
19
|
+
* filesystem's business, and that is the same answer on every machine. Reading
|
|
20
|
+
* the result back still materializes a string, so V8's own maximum string
|
|
21
|
+
* length remains the outer bound — but that is a property of the runtime rather
|
|
22
|
+
* than a budget chosen here, and it is identical everywhere this runs.
|
|
23
|
+
*
|
|
24
|
+
* The directory is per-call, so two concurrent spawns cannot read each other's
|
|
25
|
+
* bytes.
|
|
26
|
+
*/
|
|
27
|
+
function captureProcessOutput() {
|
|
28
|
+
const directory = node_fs_1.default.mkdtempSync(node_path_1.default.join(node_os_1.default.tmpdir(), "ttsc-spawn-"));
|
|
29
|
+
const stdoutPath = node_path_1.default.join(directory, "stdout");
|
|
30
|
+
const stderrPath = node_path_1.default.join(directory, "stderr");
|
|
31
|
+
const stdoutFd = node_fs_1.default.openSync(stdoutPath, "w+");
|
|
32
|
+
let stderrFd;
|
|
33
|
+
try {
|
|
34
|
+
stderrFd = node_fs_1.default.openSync(stderrPath, "w+");
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
// The first descriptor and the directory are already live. Nothing else
|
|
38
|
+
// will ever hold them, so they are released here rather than left for a
|
|
39
|
+
// caller that never received a handle to dispose.
|
|
40
|
+
closeQuietly(stdoutFd);
|
|
41
|
+
removeQuietly(directory);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
dispose() {
|
|
46
|
+
closeQuietly(stdoutFd);
|
|
47
|
+
closeQuietly(stderrFd);
|
|
48
|
+
removeQuietly(directory);
|
|
49
|
+
},
|
|
50
|
+
read(stream, encoding) {
|
|
51
|
+
const location = stream === "stdout" ? stdoutPath : stderrPath;
|
|
52
|
+
let raw;
|
|
53
|
+
try {
|
|
54
|
+
raw = node_fs_1.default.readFileSync(location);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// A spawn that never launched leaves nothing behind. Report the same
|
|
58
|
+
// empty output a failed piped capture would have.
|
|
59
|
+
raw = Buffer.alloc(0);
|
|
60
|
+
}
|
|
61
|
+
return encoding === "buffer" ? raw : raw.toString(encoding ?? "utf8");
|
|
62
|
+
},
|
|
63
|
+
stderrFd,
|
|
64
|
+
stdoutFd,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** Close a descriptor, ignoring one that is already closed. */
|
|
68
|
+
function closeQuietly(fd) {
|
|
69
|
+
try {
|
|
70
|
+
node_fs_1.default.closeSync(fd);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
// Already closed; removing the directory is what reclaims the space.
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Remove the capture directory without letting cleanup replace a result.
|
|
78
|
+
*
|
|
79
|
+
* `dispose` runs from a `finally`, so a throw here would surface instead of the
|
|
80
|
+
* spawn's own outcome — and on Windows a grandchild that inherited the handle
|
|
81
|
+
* can hold the file long enough to make removal fail. Leaving bytes in the
|
|
82
|
+
* system temp directory is the lesser outcome by far.
|
|
83
|
+
*/
|
|
84
|
+
function removeQuietly(directory) {
|
|
85
|
+
try {
|
|
86
|
+
node_fs_1.default.rmSync(directory, { force: true, recursive: true });
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Best effort.
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=captureProcessOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captureProcessOutput.js","sourceRoot":"","sources":["../../../src/compiler/internal/captureProcessOutput.ts"],"names":[],"mappings":";;;;;;AAAA,sDAAyB;AACzB,sDAAyB;AACzB,0DAA6B;AAc7B;;;;;;;;;;;;;;;;GAgBG;AACH;IACE,MAAM,SAAS,GAAG,iBAAE,CAAC,WAAW,CAAC,mBAAI,CAAC,IAAI,CAAC,iBAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;IACxE,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,UAAU,GAAG,mBAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,iBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC/C,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,iBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,wEAAwE;QACxE,wEAAwE;QACxE,kDAAkD;QAClD,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,aAAa,CAAC,SAAS,CAAC,CAAC;QACzB,MAAM,KAAK,CAAC;IACd,CAAC;IACD,OAAO;QACL,OAAO;YACL,YAAY,CAAC,QAAQ,CAAC,CAAC;YACvB,YAAY,CAAC,QAAQ,CAAC,CAAC;YACvB,aAAa,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,QAAQ;YACnB,MAAM,QAAQ,GAAG,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC;YAC/D,IAAI,GAAW,CAAC;YAChB,IAAI,CAAC;gBACH,GAAG,GAAG,iBAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,qEAAqE;gBACrE,kDAAkD;gBAClD,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACxB,CAAC;YACD,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC;QACxE,CAAC;QACD,QAAQ;QACR,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,SAAS,YAAY,CAAC,EAAU;IAC9B,IAAI,CAAC;QACH,iBAAE,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;IACvE,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,SAAiB;IACtC,IAAI,CAAC;QACH,iBAAE,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.compileProjectInMemory = compileProjectInMemory;
|
|
7
|
-
const node_child_process_1 = require("node:child_process");
|
|
8
7
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
8
|
const node_os_1 = __importDefault(require("node:os"));
|
|
10
9
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -13,6 +12,7 @@ const buildNativeCompiler_1 = require("./buildNativeCompiler");
|
|
|
13
12
|
const paths_1 = require("./paths");
|
|
14
13
|
const readProjectConfig_1 = require("./project/readProjectConfig");
|
|
15
14
|
const runBuild_1 = require("./runBuild");
|
|
15
|
+
const spawnNative_1 = require("./spawnNative");
|
|
16
16
|
/**
|
|
17
17
|
* Compile a project and capture emitted files without writing to the project
|
|
18
18
|
* tree.
|
|
@@ -42,24 +42,21 @@ function compileProjectInMemory(options) {
|
|
|
42
42
|
cacheDir: options.cacheDir ?? options.env?.TTSC_CACHE_DIR,
|
|
43
43
|
packageRoot: (0, paths_1.packageRootDir)(),
|
|
44
44
|
});
|
|
45
|
-
const res = (0,
|
|
45
|
+
const res = (0, spawnNative_1.spawnNative)(binary, ["api-compile", "--cwd", project.root, "--tsconfig", tsconfig], {
|
|
46
46
|
cwd: project.root,
|
|
47
|
-
encoding: "utf8",
|
|
48
47
|
env: { ...process.env, ...options.env },
|
|
49
|
-
maxBuffer: 1024 * 1024 * 256,
|
|
50
|
-
windowsHide: true,
|
|
51
48
|
});
|
|
52
49
|
if (res.error) {
|
|
53
50
|
throw new Error(`ttsc: failed to spawn native compiler host ${binary}: ${res.error.message}`);
|
|
54
51
|
}
|
|
55
|
-
const output = parseNativeCompileOutput(res.stdout, res.stderr);
|
|
52
|
+
const output = parseNativeCompileOutput((0, spawnNative_1.outputText)(res.stdout), (0, spawnNative_1.outputText)(res.stderr));
|
|
56
53
|
return {
|
|
57
54
|
output: output.output,
|
|
58
55
|
result: {
|
|
59
56
|
diagnostics: output.diagnostics,
|
|
60
57
|
status: res.status ?? 1,
|
|
61
58
|
stdout: "",
|
|
62
|
-
stderr: res.stderr,
|
|
59
|
+
stderr: (0, spawnNative_1.outputText)(res.stderr),
|
|
63
60
|
},
|
|
64
61
|
};
|
|
65
62
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compileProjectInMemory.js","sourceRoot":"","sources":["../../../src/compiler/internal/compileProjectInMemory.ts"],"names":[],"mappings":";;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"compileProjectInMemory.js","sourceRoot":"","sources":["../../../src/compiler/internal/compileProjectInMemory.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,6 @@ export interface ResidentCheckProcessOptions {
|
|
|
4
4
|
binary: string;
|
|
5
5
|
cwd: string;
|
|
6
6
|
env: NodeJS.ProcessEnv;
|
|
7
|
-
requestTimeoutMs?: number;
|
|
8
7
|
}
|
|
9
8
|
export interface ResidentCheckRequest {
|
|
10
9
|
changed?: readonly string[];
|
|
@@ -32,7 +31,6 @@ export declare class ResidentCheckProcess {
|
|
|
32
31
|
private readonly child;
|
|
33
32
|
private readonly pending;
|
|
34
33
|
private readonly reader;
|
|
35
|
-
private readonly requestTimeoutMs;
|
|
36
34
|
private failure;
|
|
37
35
|
private stderr;
|
|
38
36
|
constructor(options: ResidentCheckProcessOptions);
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ResidentCheckProcess = void 0;
|
|
4
4
|
const node_child_process_1 = require("node:child_process");
|
|
5
5
|
const node_readline_1 = require("node:readline");
|
|
6
|
-
const residentTransformProcess_1 = require("./residentTransformProcess");
|
|
7
6
|
const STDERR_TAIL_LIMIT = 64 * 1024;
|
|
8
7
|
const REPLY_ECHO_LIMIT = 200;
|
|
9
8
|
const TERMINATION_GRACE_MS = 1_000;
|
|
@@ -19,11 +18,9 @@ class ResidentCheckProcess {
|
|
|
19
18
|
child;
|
|
20
19
|
pending = [];
|
|
21
20
|
reader;
|
|
22
|
-
requestTimeoutMs;
|
|
23
21
|
failure;
|
|
24
22
|
stderr = "";
|
|
25
23
|
constructor(options) {
|
|
26
|
-
this.requestTimeoutMs = (0, residentTransformProcess_1.normalizeRequestTimeoutMs)(options.requestTimeoutMs);
|
|
27
24
|
this.child = (0, node_child_process_1.spawn)(options.binary, [...options.args], {
|
|
28
25
|
cwd: options.cwd,
|
|
29
26
|
env: options.env,
|
|
@@ -65,17 +62,7 @@ class ResidentCheckProcess {
|
|
|
65
62
|
return Promise.reject(asError(error));
|
|
66
63
|
}
|
|
67
64
|
return new Promise((resolve, reject) => {
|
|
68
|
-
const pending = {
|
|
69
|
-
reject,
|
|
70
|
-
resolve,
|
|
71
|
-
timer: setTimeout(() => {
|
|
72
|
-
const detail = stderrSuffix(this.stderr);
|
|
73
|
-
const timeout = new Error(`ttsc: resident check request timed out after ${String(this.requestTimeoutMs)} ms${detail}`);
|
|
74
|
-
this.settle(pending, timeout);
|
|
75
|
-
this.fail(timeout);
|
|
76
|
-
}, this.requestTimeoutMs),
|
|
77
|
-
};
|
|
78
|
-
pending.timer.unref();
|
|
65
|
+
const pending = { reject, resolve };
|
|
79
66
|
this.pending.push(pending);
|
|
80
67
|
try {
|
|
81
68
|
stdin.write(line, (error) => {
|
|
@@ -119,7 +106,6 @@ class ResidentCheckProcess {
|
|
|
119
106
|
if (index === -1)
|
|
120
107
|
return;
|
|
121
108
|
this.pending.splice(index, 1);
|
|
122
|
-
clearTimeout(pending.timer);
|
|
123
109
|
if (result instanceof Error)
|
|
124
110
|
pending.reject(result);
|
|
125
111
|
else
|