@crouton-kit/tsym 0.1.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 -0
- package/README.md +51 -0
- package/bin/tsym.js +2 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +89 -0
- package/dist/commands/handlers/check.d.ts +3 -0
- package/dist/commands/handlers/check.js +94 -0
- package/dist/commands/handlers/find.d.ts +3 -0
- package/dist/commands/handlers/find.js +56 -0
- package/dist/commands/handlers/inspect.d.ts +3 -0
- package/dist/commands/handlers/inspect.js +81 -0
- package/dist/commands/handlers/outline.d.ts +3 -0
- package/dist/commands/handlers/outline.js +101 -0
- package/dist/commands/handlers/query.d.ts +3 -0
- package/dist/commands/handlers/query.js +196 -0
- package/dist/commands/handlers/rename.d.ts +3 -0
- package/dist/commands/handlers/rename.js +53 -0
- package/dist/commands/handlers/search.d.ts +5 -0
- package/dist/commands/handlers/search.js +32 -0
- package/dist/commands/handlers/server-reload.d.ts +3 -0
- package/dist/commands/handlers/server-reload.js +7 -0
- package/dist/commands/handlers/server-status.d.ts +3 -0
- package/dist/commands/handlers/server-status.js +7 -0
- package/dist/commands/handlers/server-stop.d.ts +3 -0
- package/dist/commands/handlers/server-stop.js +7 -0
- package/dist/commands/handlers/show.d.ts +3 -0
- package/dist/commands/handlers/show.js +63 -0
- package/dist/commands/handlers/type.d.ts +3 -0
- package/dist/commands/handlers/type.js +45 -0
- package/dist/commands/handlers.d.ts +12 -0
- package/dist/commands/handlers.js +44 -0
- package/dist/commands/help.d.ts +2 -0
- package/dist/commands/help.js +27 -0
- package/dist/commands/rename-apply.d.ts +37 -0
- package/dist/commands/rename-apply.js +115 -0
- package/dist/commands/tree.d.ts +9 -0
- package/dist/commands/tree.js +277 -0
- package/dist/commands/types.d.ts +80 -0
- package/dist/commands/types.js +1 -0
- package/dist/core/declarations.d.ts +48 -0
- package/dist/core/declarations.js +153 -0
- package/dist/core/receipt.d.ts +7 -0
- package/dist/core/receipt.js +9 -0
- package/dist/core/search.d.ts +29 -0
- package/dist/core/search.js +47 -0
- package/dist/core/source.d.ts +32 -0
- package/dist/core/source.js +96 -0
- package/dist/core/workspace.d.ts +28 -0
- package/dist/core/workspace.js +137 -0
- package/dist/index/build.d.ts +22 -0
- package/dist/index/build.js +79 -0
- package/dist/index/classify.d.ts +20 -0
- package/dist/index/classify.js +60 -0
- package/dist/index/commits.d.ts +15 -0
- package/dist/index/commits.js +201 -0
- package/dist/index/descriptor.d.ts +19 -0
- package/dist/index/descriptor.js +295 -0
- package/dist/index/graph.d.ts +82 -0
- package/dist/index/graph.js +1 -0
- package/dist/index/heritage.d.ts +15 -0
- package/dist/index/heritage.js +122 -0
- package/dist/index/refresh.d.ts +28 -0
- package/dist/index/refresh.js +110 -0
- package/dist/index/scope.d.ts +4 -0
- package/dist/index/scope.js +21 -0
- package/dist/index/state.d.ts +22 -0
- package/dist/index/state.js +63 -0
- package/dist/index/walk.d.ts +23 -0
- package/dist/index/walk.js +550 -0
- package/dist/index/watch.d.ts +18 -0
- package/dist/index/watch.js +175 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/dist/output.d.ts +12 -0
- package/dist/output.js +54 -0
- package/dist/read/read.d.ts +32 -0
- package/dist/read/read.js +89 -0
- package/dist/relations/graph.d.ts +23 -0
- package/dist/relations/graph.js +115 -0
- package/dist/relations/mermaid.d.ts +3 -0
- package/dist/relations/mermaid.js +37 -0
- package/dist/relations/store-relations.d.ts +20 -0
- package/dist/relations/store-relations.js +158 -0
- package/dist/relations/types.d.ts +58 -0
- package/dist/relations/types.js +12 -0
- package/dist/server/client.d.ts +5 -0
- package/dist/server/client.js +215 -0
- package/dist/server/context.d.ts +21 -0
- package/dist/server/context.js +12 -0
- package/dist/server/lifecycle.d.ts +28 -0
- package/dist/server/lifecycle.js +62 -0
- package/dist/server/main.d.ts +1 -0
- package/dist/server/main.js +541 -0
- package/dist/server/projects.d.ts +21 -0
- package/dist/server/projects.js +28 -0
- package/dist/server/wire.d.ts +39 -0
- package/dist/server/wire.js +19 -0
- package/dist/store/load.d.ts +67 -0
- package/dist/store/load.js +193 -0
- package/dist/store/meta.d.ts +28 -0
- package/dist/store/meta.js +137 -0
- package/dist/store/query.d.ts +5 -0
- package/dist/store/query.js +4 -0
- package/dist/store/schema.d.ts +4 -0
- package/dist/store/schema.js +19 -0
- package/dist/store/store.d.ts +36 -0
- package/dist/store/store.js +240 -0
- package/dist/ts7/api.d.ts +35 -0
- package/dist/ts7/api.js +164 -0
- package/dist/ts7/ast.d.ts +1 -0
- package/dist/ts7/ast.js +1 -0
- package/dist/ts7/checker.d.ts +55 -0
- package/dist/ts7/checker.js +383 -0
- package/dist/ts7/projects.d.ts +27 -0
- package/dist/ts7/projects.js +94 -0
- package/package.json +47 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { NODE_TABLES, RELATION_TABLES, SCHEMA_STATEMENTS } from './schema.js';
|
|
5
|
+
const ownedStores = new Set();
|
|
6
|
+
const DEFAULT_BOUNDED_QUERY_TIMEOUT_MS = 30_000;
|
|
7
|
+
const ENGINE_PLATFORMS = ['darwin-arm64', 'darwin-x64', 'linux-x64', 'linux-arm64', 'win32-x64'];
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
export class EngineBinaryError extends Error {
|
|
10
|
+
code = 'no-engine-binary';
|
|
11
|
+
platform;
|
|
12
|
+
constructor(platform = `${process.platform}-${process.arch}`) {
|
|
13
|
+
super(`LadybugDB has no prebuilt binary for ${platform}, and tsym does not compile it.\nPrebuilt platforms: ${ENGINE_PLATFORMS.join(', ')}.`);
|
|
14
|
+
this.platform = platform;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export class StoreOwnershipError extends Error {
|
|
18
|
+
storePath;
|
|
19
|
+
ownerPid;
|
|
20
|
+
constructor(storePath, ownerPid) {
|
|
21
|
+
super(ownerPid === undefined ? `The tsym store at ${storePath} is already open in this process.` : `The tsym store at ${storePath} is owned by process ${ownerPid}.`);
|
|
22
|
+
this.storePath = storePath;
|
|
23
|
+
this.ownerPid = ownerPid;
|
|
24
|
+
this.name = 'StoreOwnershipError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class StoreReadOnlyError extends Error {
|
|
28
|
+
constructor() {
|
|
29
|
+
super('Query statements must be read-only.');
|
|
30
|
+
this.name = 'StoreReadOnlyError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export class Store {
|
|
34
|
+
path;
|
|
35
|
+
ownerPath;
|
|
36
|
+
database;
|
|
37
|
+
connection;
|
|
38
|
+
boundedConnection;
|
|
39
|
+
closed = false;
|
|
40
|
+
boundedQueryTimeoutMs;
|
|
41
|
+
constructor(storePath, options = {}) {
|
|
42
|
+
this.path = path.resolve(storePath);
|
|
43
|
+
this.boundedQueryTimeoutMs = options.boundedQueryTimeoutMs ?? DEFAULT_BOUNDED_QUERY_TIMEOUT_MS;
|
|
44
|
+
this.ownerPath = path.join(this.path, '.tsym-owner');
|
|
45
|
+
mkdirSync(this.path, { recursive: true, mode: 0o700 });
|
|
46
|
+
acquireOwnership(this.path, this.ownerPath);
|
|
47
|
+
try {
|
|
48
|
+
const { Database, Connection } = loadEngine();
|
|
49
|
+
this.database = new Database(path.join(this.path, 'graph.lbug'));
|
|
50
|
+
this.database.initSync();
|
|
51
|
+
this.connection = new Connection(this.database);
|
|
52
|
+
this.connection.initSync();
|
|
53
|
+
const tables = new Set(this.execute('CALL SHOW_TABLES() RETURN *').map((row) => row.name));
|
|
54
|
+
const expected = [...NODE_TABLES, ...RELATION_TABLES].map(tableName);
|
|
55
|
+
if (tables.size === 0)
|
|
56
|
+
this.transaction(() => { for (const statement of SCHEMA_STATEMENTS)
|
|
57
|
+
this.execute(statement); });
|
|
58
|
+
else if (!expected.every((name) => tables.has(name)))
|
|
59
|
+
throw new Error(`Store schema is incomplete at ${this.path}.`);
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
try {
|
|
63
|
+
this.connection?.closeSync();
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
try {
|
|
67
|
+
this.database?.closeSync();
|
|
68
|
+
}
|
|
69
|
+
catch { }
|
|
70
|
+
releaseOwnership(this.path, this.ownerPath);
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
execute(statement, parameters) {
|
|
75
|
+
this.assertOpen();
|
|
76
|
+
const connection = this.connection;
|
|
77
|
+
if (connection === undefined)
|
|
78
|
+
throw new Error('Store did not finish opening.');
|
|
79
|
+
const result = parameters === undefined
|
|
80
|
+
? connection.querySync(statement)
|
|
81
|
+
: connection.executeSync(connection.prepareSync(statement), parameters);
|
|
82
|
+
return collect(result);
|
|
83
|
+
}
|
|
84
|
+
/** Executes a read query on a separate connection whose 30-second engine timeout never affects writes. */
|
|
85
|
+
executeBounded(statement, parameters) {
|
|
86
|
+
this.assertOpen();
|
|
87
|
+
const connection = this.bounded();
|
|
88
|
+
const prepared = connection.prepareSync(statement);
|
|
89
|
+
if (!prepared.isSuccess())
|
|
90
|
+
throw new Error(prepared.getErrorMessage());
|
|
91
|
+
if (!prepared.isReadOnly())
|
|
92
|
+
throw new StoreReadOnlyError();
|
|
93
|
+
return collect(connection.executeSync(prepared, parameters));
|
|
94
|
+
}
|
|
95
|
+
transaction(work) {
|
|
96
|
+
this.execute('BEGIN TRANSACTION');
|
|
97
|
+
try {
|
|
98
|
+
const value = work();
|
|
99
|
+
this.execute('COMMIT');
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
try {
|
|
104
|
+
this.execute('ROLLBACK');
|
|
105
|
+
}
|
|
106
|
+
catch { }
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
checkpoint() {
|
|
111
|
+
this.execute('CHECKPOINT');
|
|
112
|
+
}
|
|
113
|
+
close() {
|
|
114
|
+
if (this.closed)
|
|
115
|
+
return;
|
|
116
|
+
this.closed = true;
|
|
117
|
+
try {
|
|
118
|
+
this.boundedConnection?.closeSync();
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
try {
|
|
122
|
+
this.connection?.closeSync();
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
try {
|
|
126
|
+
this.database?.closeSync();
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
releaseOwnership(this.path, this.ownerPath);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
bounded() {
|
|
135
|
+
if (this.boundedConnection !== undefined)
|
|
136
|
+
return this.boundedConnection;
|
|
137
|
+
const database = this.database;
|
|
138
|
+
if (database === undefined)
|
|
139
|
+
throw new Error('Store did not finish opening.');
|
|
140
|
+
const connection = new (loadEngine().Connection)(database);
|
|
141
|
+
connection.initSync();
|
|
142
|
+
connection.setQueryTimeout(this.boundedQueryTimeoutMs);
|
|
143
|
+
this.boundedConnection = connection;
|
|
144
|
+
return connection;
|
|
145
|
+
}
|
|
146
|
+
assertOpen() {
|
|
147
|
+
if (this.closed)
|
|
148
|
+
throw new Error('Store is closed.');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function loadEngine() {
|
|
152
|
+
let entry;
|
|
153
|
+
try {
|
|
154
|
+
entry = require.resolve('@ladybugdb/core');
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
throw new EngineBinaryError();
|
|
158
|
+
}
|
|
159
|
+
if (!existsSync(path.join(path.dirname(entry), 'lbugjs.node')))
|
|
160
|
+
throw new EngineBinaryError();
|
|
161
|
+
return require('@ladybugdb/core');
|
|
162
|
+
}
|
|
163
|
+
function tableName(statement) {
|
|
164
|
+
const match = /CREATE (?:NODE|REL) TABLE ([A-Za-z_][A-Za-z_]*)/.exec(statement);
|
|
165
|
+
if (!match)
|
|
166
|
+
throw new Error(`Schema statement has no table name: ${statement}`);
|
|
167
|
+
return match[1];
|
|
168
|
+
}
|
|
169
|
+
function collect(result) {
|
|
170
|
+
const results = Array.isArray(result) ? result : [result];
|
|
171
|
+
const rows = [];
|
|
172
|
+
for (const item of results) {
|
|
173
|
+
try {
|
|
174
|
+
rows.push(...item.getAllSync());
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
item.close();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return rows;
|
|
181
|
+
}
|
|
182
|
+
function acquireOwnership(storePath, ownerPath) {
|
|
183
|
+
if (ownedStores.has(storePath))
|
|
184
|
+
throw new StoreOwnershipError(storePath);
|
|
185
|
+
for (;;) {
|
|
186
|
+
try {
|
|
187
|
+
const fd = openSync(ownerPath, 'wx', 0o600);
|
|
188
|
+
try {
|
|
189
|
+
writeFileSync(fd, `${process.pid}\n`);
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
closeSync(fd);
|
|
193
|
+
}
|
|
194
|
+
ownedStores.add(storePath);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
if (error.code !== 'EEXIST')
|
|
199
|
+
throw error;
|
|
200
|
+
const ownerPid = readOwnerPid(ownerPath);
|
|
201
|
+
if (ownerPid !== undefined && processAlive(ownerPid))
|
|
202
|
+
throw new StoreOwnershipError(storePath, ownerPid);
|
|
203
|
+
try {
|
|
204
|
+
unlinkSync(ownerPath);
|
|
205
|
+
}
|
|
206
|
+
catch (unlinkError) {
|
|
207
|
+
if (unlinkError.code !== 'ENOENT')
|
|
208
|
+
throw unlinkError;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function releaseOwnership(storePath, ownerPath) {
|
|
214
|
+
ownedStores.delete(storePath);
|
|
215
|
+
try {
|
|
216
|
+
unlinkSync(ownerPath);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
if (error.code !== 'ENOENT')
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function readOwnerPid(ownerPath) {
|
|
224
|
+
try {
|
|
225
|
+
const value = Number.parseInt(readFileSync(ownerPath, 'utf8').trim(), 10);
|
|
226
|
+
return Number.isSafeInteger(value) && value > 0 ? value : undefined;
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function processAlive(pid) {
|
|
233
|
+
try {
|
|
234
|
+
process.kill(pid, 0);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
return error.code === 'EPERM';
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Project, type Snapshot } from 'typescript/unstable/sync';
|
|
2
|
+
import type { UpdateSnapshotParams } from 'typescript/unstable/proto';
|
|
3
|
+
export declare class TypeScriptBinaryError extends Error {
|
|
4
|
+
readonly code = "no-typescript-binary";
|
|
5
|
+
readonly platform: string;
|
|
6
|
+
constructor(platform?: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class Ts7ServerDiedError extends Error {
|
|
9
|
+
constructor(cause: unknown);
|
|
10
|
+
}
|
|
11
|
+
/** Owns the one TypeScript 7 API client and its current snapshot for a resident. */
|
|
12
|
+
export declare class Ts7Host {
|
|
13
|
+
readonly root: string;
|
|
14
|
+
private api;
|
|
15
|
+
private snapshot;
|
|
16
|
+
private configs;
|
|
17
|
+
/** Paths named by the most recent update; only these are read from disk, so unchanged files keep the server's native reads. */
|
|
18
|
+
private changed;
|
|
19
|
+
constructor(root: string);
|
|
20
|
+
get pid(): number | undefined;
|
|
21
|
+
/** Opens newly discovered configs and closes vanished ones; project opens are ref-counted, so each open needs its close. */
|
|
22
|
+
load(configs: readonly string[]): readonly Project[];
|
|
23
|
+
update(params: UpdateSnapshotParams): readonly Project[];
|
|
24
|
+
withSnapshot<T>(operation: (snapshot: Snapshot) => T): T;
|
|
25
|
+
sourceFile(config: string | undefined, file: string): import("typescript/unstable/ast").SourceFile | undefined;
|
|
26
|
+
close(): void;
|
|
27
|
+
private replaceSnapshot;
|
|
28
|
+
private request;
|
|
29
|
+
private recover;
|
|
30
|
+
private createApi;
|
|
31
|
+
private requireSnapshot;
|
|
32
|
+
private disposeSnapshot;
|
|
33
|
+
}
|
|
34
|
+
export declare function bundledTypeScriptVersion(): string;
|
|
35
|
+
export declare function isBadFileDescriptor(error: unknown): boolean;
|
package/dist/ts7/api.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { API } from 'typescript/unstable/sync';
|
|
5
|
+
import { resolveFileName } from 'typescript/unstable/proto';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
export class TypeScriptBinaryError extends Error {
|
|
8
|
+
code = 'no-typescript-binary';
|
|
9
|
+
platform;
|
|
10
|
+
constructor(platform = `${process.platform}-${process.arch}`) {
|
|
11
|
+
super(`TypeScript has no prebuilt binary for ${platform}, and tsym does not compile it.`);
|
|
12
|
+
this.platform = platform;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class Ts7ServerDiedError extends Error {
|
|
16
|
+
constructor(cause) {
|
|
17
|
+
super('The bundled TypeScript 7 API stopped responding.', { cause });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Owns the one TypeScript 7 API client and its current snapshot for a resident. */
|
|
21
|
+
export class Ts7Host {
|
|
22
|
+
root;
|
|
23
|
+
api;
|
|
24
|
+
snapshot;
|
|
25
|
+
configs = [];
|
|
26
|
+
/** Paths named by the most recent update; only these are read from disk, so unchanged files keep the server's native reads. */
|
|
27
|
+
changed = new Set();
|
|
28
|
+
constructor(root) {
|
|
29
|
+
this.root = root;
|
|
30
|
+
this.api = this.createApi();
|
|
31
|
+
}
|
|
32
|
+
get pid() { return this.api.client.channel.child.pid; }
|
|
33
|
+
/** Opens newly discovered configs and closes vanished ones; project opens are ref-counted, so each open needs its close. */
|
|
34
|
+
load(configs) {
|
|
35
|
+
const open = new Set(this.configs);
|
|
36
|
+
const next = new Set(configs);
|
|
37
|
+
const openProjects = configs.filter((config) => !open.has(config));
|
|
38
|
+
const closeProjects = this.configs.filter((config) => !next.has(config));
|
|
39
|
+
this.configs = [...configs];
|
|
40
|
+
return this.replaceSnapshot({ openProjects, closeProjects }).getProjects();
|
|
41
|
+
}
|
|
42
|
+
update(params) {
|
|
43
|
+
this.changed = params.fileChanges && !('invalidateAll' in params.fileChanges)
|
|
44
|
+
? new Set([...params.fileChanges.changed ?? [], ...params.fileChanges.created ?? [], ...params.fileChanges.deleted ?? []].map((file) => path.resolve(resolveFileName(file))))
|
|
45
|
+
: new Set();
|
|
46
|
+
return this.replaceSnapshot(params).getProjects();
|
|
47
|
+
}
|
|
48
|
+
withSnapshot(operation) {
|
|
49
|
+
return this.request(() => operation(this.requireSnapshot()));
|
|
50
|
+
}
|
|
51
|
+
sourceFile(config, file) {
|
|
52
|
+
const source = this.withSnapshot((snapshot) => config ? snapshot.getProject(config)?.program.getSourceFile(file) : snapshot.getDefaultProjectForFile(file)?.program.getSourceFile(file));
|
|
53
|
+
if (source || config)
|
|
54
|
+
return source;
|
|
55
|
+
this.replaceSnapshot({ openFiles: [file] });
|
|
56
|
+
return this.withSnapshot((snapshot) => snapshot.getDefaultProjectForFile(file)?.program.getSourceFile(file));
|
|
57
|
+
}
|
|
58
|
+
close() {
|
|
59
|
+
this.disposeSnapshot();
|
|
60
|
+
try {
|
|
61
|
+
this.api.close();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (!isBadFileDescriptor(error))
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
replaceSnapshot(params) {
|
|
69
|
+
return this.request(() => {
|
|
70
|
+
const previous = this.snapshot;
|
|
71
|
+
const next = this.api.updateSnapshot(params);
|
|
72
|
+
this.snapshot = next;
|
|
73
|
+
if (previous) {
|
|
74
|
+
try {
|
|
75
|
+
previous.dispose();
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (!isBadFileDescriptor(error))
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return next;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
request(operation) {
|
|
86
|
+
try {
|
|
87
|
+
return operation();
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (!isBadFileDescriptor(error))
|
|
91
|
+
throw error;
|
|
92
|
+
this.recover();
|
|
93
|
+
try {
|
|
94
|
+
return operation();
|
|
95
|
+
}
|
|
96
|
+
catch (retryError) {
|
|
97
|
+
throw new Ts7ServerDiedError(retryError);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
recover() {
|
|
102
|
+
this.disposeSnapshot();
|
|
103
|
+
try {
|
|
104
|
+
this.api.close();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (!isBadFileDescriptor(error))
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
this.api = this.createApi();
|
|
111
|
+
if (this.configs.length > 0)
|
|
112
|
+
this.snapshot = this.api.updateSnapshot({ openProjects: [...this.configs] });
|
|
113
|
+
}
|
|
114
|
+
createApi() {
|
|
115
|
+
assertTypeScriptBinary();
|
|
116
|
+
return new API({ cwd: this.root, fs: { readFile: (file) => {
|
|
117
|
+
if (!this.changed.has(path.resolve(file)))
|
|
118
|
+
return undefined;
|
|
119
|
+
try {
|
|
120
|
+
return readFileSync(file, 'utf8');
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error.code === 'ENOENT')
|
|
124
|
+
return null;
|
|
125
|
+
throw error;
|
|
126
|
+
}
|
|
127
|
+
} } });
|
|
128
|
+
}
|
|
129
|
+
requireSnapshot() {
|
|
130
|
+
if (!this.snapshot)
|
|
131
|
+
throw new Error('TypeScript 7 projects have not been loaded.');
|
|
132
|
+
return this.snapshot;
|
|
133
|
+
}
|
|
134
|
+
disposeSnapshot() {
|
|
135
|
+
if (!this.snapshot)
|
|
136
|
+
return;
|
|
137
|
+
try {
|
|
138
|
+
this.snapshot.dispose();
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
if (!isBadFileDescriptor(error))
|
|
142
|
+
throw error;
|
|
143
|
+
}
|
|
144
|
+
this.snapshot = undefined;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
export function bundledTypeScriptVersion() {
|
|
148
|
+
return require('typescript/package.json').version;
|
|
149
|
+
}
|
|
150
|
+
function assertTypeScriptBinary() {
|
|
151
|
+
const packageName = `@typescript/typescript-${process.platform}-${process.arch}`;
|
|
152
|
+
try {
|
|
153
|
+
const packageJson = require.resolve(`${packageName}/package.json`);
|
|
154
|
+
const binary = path.join(path.dirname(packageJson), 'lib', process.platform === 'win32' ? 'tsc.exe' : 'tsc');
|
|
155
|
+
if (!existsSync(binary))
|
|
156
|
+
throw new Error('TypeScript native binary is absent.');
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
throw new TypeScriptBinaryError();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
export function isBadFileDescriptor(error) {
|
|
163
|
+
return error instanceof Error && (/\bEBADF\b|bad file descriptor|Unexpected EOF while reading from child process/i.test(error.message) || error.code === 'EPIPE');
|
|
164
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'typescript/unstable/ast';
|
package/dist/ts7/ast.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'typescript/unstable/ast';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Ts7Host } from './api.js';
|
|
2
|
+
import { ConfiguredProjects } from './projects.js';
|
|
3
|
+
export interface TypeAnswer {
|
|
4
|
+
kind: string;
|
|
5
|
+
modifiers: string | undefined;
|
|
6
|
+
signature: string;
|
|
7
|
+
documentation: string;
|
|
8
|
+
tags: readonly {
|
|
9
|
+
name: string;
|
|
10
|
+
text: string;
|
|
11
|
+
}[];
|
|
12
|
+
definitions: readonly string[];
|
|
13
|
+
}
|
|
14
|
+
export interface CheckerDiagnostic {
|
|
15
|
+
file: string;
|
|
16
|
+
line: number;
|
|
17
|
+
column: number;
|
|
18
|
+
severity: string;
|
|
19
|
+
code: number;
|
|
20
|
+
message: string;
|
|
21
|
+
}
|
|
22
|
+
export interface RenameOccurrence {
|
|
23
|
+
file: string;
|
|
24
|
+
line: number;
|
|
25
|
+
col: number;
|
|
26
|
+
}
|
|
27
|
+
export interface CheckerRenameEdit extends RenameOccurrence {
|
|
28
|
+
startUtf16: number;
|
|
29
|
+
endUtf16: number;
|
|
30
|
+
oldText: string;
|
|
31
|
+
replacement: string;
|
|
32
|
+
}
|
|
33
|
+
export declare class RenamePreflightError extends Error {
|
|
34
|
+
readonly code: 'rename-through-string-literal' | 'rename-through-computed-name' | 'rename-outside-workspace' | 'rename-conflict';
|
|
35
|
+
readonly site: string;
|
|
36
|
+
constructor(code: 'rename-through-string-literal' | 'rename-through-computed-name' | 'rename-outside-workspace' | 'rename-conflict', site: string, message: string);
|
|
37
|
+
}
|
|
38
|
+
export declare function typeAt(host: Ts7Host, root: string, config: string, file: string, position: number, fallback: {
|
|
39
|
+
kind: string;
|
|
40
|
+
name: string;
|
|
41
|
+
address: string;
|
|
42
|
+
}): TypeAnswer | null;
|
|
43
|
+
export declare function diagnosticsForFiles(host: Ts7Host, root: string, scopes: readonly {
|
|
44
|
+
config: string;
|
|
45
|
+
files: readonly string[];
|
|
46
|
+
}[]): CheckerDiagnostic[];
|
|
47
|
+
/** Builds rename edits from indexed reference sites and rejects shapes TS7 cannot rewrite safely. */
|
|
48
|
+
export declare function renameFromOccurrences(host: Ts7Host, root: string, projects: ConfiguredProjects, declaration: {
|
|
49
|
+
file: string;
|
|
50
|
+
nameSpan: {
|
|
51
|
+
start: number;
|
|
52
|
+
};
|
|
53
|
+
address: string;
|
|
54
|
+
name: string;
|
|
55
|
+
}, occurrences: readonly RenameOccurrence[], newName: string): CheckerRenameEdit[];
|