@typerighter/rpc-client 0.24.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.
@@ -0,0 +1,260 @@
1
+ /**
2
+ * JSON-RPC 2.0 client with Content-Length framing
3
+ * Simplified from vscode-jsonrpc (MIT, Microsoft Corporation)
4
+ * Ref: https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L506-L591
5
+ */
6
+
7
+ import { createConnection } from 'node:net';
8
+ import type { Readable, Writable } from 'node:stream';
9
+ import type { Message, RequestMessage, NotificationMessage, ResponseMessage } from './types.js';
10
+ import { Message as MessageGuards, ErrorCodes, ResponseError } from './types.js';
11
+
12
+ type PendingRequest = {
13
+ resolve: (value: unknown) => void;
14
+ reject: (error: ResponseError) => void;
15
+ };
16
+
17
+ // A Disposable interface to undo a previous side-effectful step
18
+ interface Disposable {
19
+ dispose (): void;
20
+ }
21
+
22
+ const HEADER_SEPARATOR = Buffer.from('\r\n\r\n', 'ascii');
23
+ const HEADER_SEPARATOR_LENGTH = 4; // \r\n\r\n
24
+
25
+ /**
26
+ * Simplified MessageConnection interface
27
+ * https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L506-L591
28
+ */
29
+ export interface MessageConnection extends Disposable {
30
+ /** Send a JSON-RPC request and wait for the response */
31
+ sendRequest<R> (method: string, params?: any[] | object): Promise<R>;
32
+ /** Send a one-way JSON-RPC notification (no response expected) */
33
+ sendNotification (method: string, params?: any[] | object): void;
34
+ /** Register a handler for server-sent notifications, returns an unsubscribe handle */
35
+ onNotification (method: string, handler: (params: any) => void): Disposable;
36
+ /** Register a listener for connection close, returns an unsubscribe handle */
37
+ onClose (listener: () => void): Disposable;
38
+ /** Reject all pending requests and stop listening */
39
+ dispose (): void;
40
+ }
41
+
42
+ export class JsonRpcClient implements MessageConnection {
43
+ // Transport
44
+ private reader: Readable;
45
+ private writer: Writable;
46
+
47
+ // Request/response matching
48
+ private sequenceNumber = 1;
49
+ private responsePromises = new Map<number, PendingRequest>();
50
+ private notificationHandlers = new Map<string, (params: unknown) => void>();
51
+
52
+ // Inbound buffer, raw chunks to avoid corrupting multi-byte UTF-8
53
+ private chunks: Buffer[] = [];
54
+ private chunksLength = 0;
55
+ private contentLength = -1; // -1 = waiting for header
56
+
57
+ // Lifecycle
58
+ private disposed = false;
59
+ private closeHandlers: Array<() => void> = [];
60
+
61
+ constructor (reader: Readable, writer: Writable) {
62
+ this.reader = reader;
63
+ this.writer = writer;
64
+
65
+ this.reader.on('data', (chunk: Buffer) => this.onData(chunk));
66
+ this.reader.on('end', () => this.handleStreamClose());
67
+ this.reader.on('close', () => this.handleStreamClose());
68
+ }
69
+
70
+ static connectTcp (host: string, port: number): Promise<JsonRpcClient> {
71
+ return new Promise((resolve, reject) => {
72
+ const socket = createConnection({ host, port }, () => {
73
+ resolve(new JsonRpcClient(socket, socket));
74
+ });
75
+ socket.on('error', reject);
76
+ });
77
+ }
78
+
79
+ static connectStdio (stdin: Readable, stdout: Writable): JsonRpcClient {
80
+ return new JsonRpcClient(stdin, stdout);
81
+ }
82
+
83
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L1563-L1590
84
+ dispose (): void {
85
+ if (this.disposed) return;
86
+ this.disposed = true;
87
+
88
+ this.rejectAllPending('Connection disposed');
89
+ }
90
+
91
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L565
92
+ onClose (listener: () => void): Disposable {
93
+ this.closeHandlers.push(listener);
94
+ return {
95
+ dispose: () => {
96
+ const index = this.closeHandlers.indexOf(listener);
97
+ if (index >= 0) this.closeHandlers.splice(index, 1);
98
+ },
99
+ };
100
+ }
101
+
102
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L537
103
+ sendRequest<R> (method: string, params?: any[] | object): Promise<R> {
104
+ const id = this.sequenceNumber++;
105
+ const message: RequestMessage = { jsonrpc: '2.0', id, method, params };
106
+
107
+ return new Promise<R>((resolve, reject) => {
108
+ this.responsePromises.set(id, { resolve: resolve as (v: unknown) => void, reject });
109
+ this.writeMessage(message);
110
+ });
111
+ }
112
+
113
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L549
114
+ sendNotification (method: string, params?: any[] | object): void {
115
+ const message: NotificationMessage = { jsonrpc: '2.0', method, params };
116
+ this.writeMessage(message);
117
+ }
118
+
119
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L557
120
+ onNotification (method: string, handler: (params: any) => void): Disposable {
121
+ this.notificationHandlers.set(method, handler);
122
+ return {
123
+ dispose: () => this.notificationHandlers.delete(method),
124
+ };
125
+ }
126
+
127
+ // Accumulate chunk and parse as many complete messages as possible
128
+ // A single chunk can contain multiple messages
129
+ // Ref: vscode-jsonrpc ReadableStreamMessageReader.nextMessage
130
+ private onData (chunk: Buffer): void {
131
+ this.chunks.push(chunk);
132
+ this.chunksLength += chunk.length;
133
+
134
+ while (true) {
135
+ if (this.contentLength < 0) {
136
+ const buffer = this.compact();
137
+ const separatorIndex = buffer.indexOf(HEADER_SEPARATOR);
138
+
139
+ if (separatorIndex < 0) return;
140
+
141
+ const header = buffer.subarray(0, separatorIndex).toString('ascii');
142
+ const match = header.match(/Content-Length:\s*(\d+)/i);
143
+
144
+ if (!match) {
145
+ this.consume(separatorIndex + HEADER_SEPARATOR_LENGTH);
146
+ continue;
147
+ }
148
+
149
+ this.contentLength = Number(match[1]);
150
+ this.consume(separatorIndex + HEADER_SEPARATOR_LENGTH);
151
+ }
152
+
153
+ if (this.chunksLength < this.contentLength) return;
154
+
155
+ const buffer = this.compact();
156
+ const body = buffer.subarray(0, this.contentLength).toString('utf-8');
157
+
158
+ this.consume(this.contentLength);
159
+ this.contentLength = -1;
160
+
161
+ try {
162
+ const message = JSON.parse(body);
163
+
164
+ if (MessageGuards.isResponse(message)) {
165
+ this.handleResponse(message);
166
+ } else if (MessageGuards.isNotification(message)) {
167
+ this.handleNotification(message);
168
+ }
169
+ } catch (error) {
170
+ console.error('[jsonrpc] Failed to parse message:', error);
171
+ }
172
+ }
173
+ }
174
+
175
+ // Ref: vscode-jsonrpc connection.ts
176
+
177
+ private handleResponse (response: ResponseMessage): void {
178
+ if (typeof response.id !== 'number') return;
179
+
180
+ const pending = this.responsePromises.get(response.id);
181
+
182
+ if (!pending) return;
183
+ this.responsePromises.delete(response.id);
184
+
185
+ if (response.error) {
186
+ pending.reject(new ResponseError(response.error.code, response.error.message, response.error.data));
187
+ } else if (response.result !== undefined) {
188
+ pending.resolve(response.result);
189
+ }
190
+ }
191
+
192
+ private handleNotification (notification: NotificationMessage): void {
193
+ const handler = this.notificationHandlers.get(notification.method);
194
+
195
+ if (!handler) return;
196
+
197
+ try {
198
+ handler(notification.params);
199
+ } catch (error) {
200
+ console.error(`[jsonrpc] Notification handler for '${notification.method}' threw:`, error);
201
+ }
202
+ }
203
+
204
+ // Cleanup
205
+
206
+ private rejectAllPending (reason: string): void {
207
+ for (const [, pending] of this.responsePromises) {
208
+ pending.reject(new ResponseError(ErrorCodes.PendingResponseRejected, reason));
209
+ }
210
+ this.responsePromises.clear();
211
+ }
212
+
213
+ // Fires once on stream end/close
214
+ private handleStreamClose (): void {
215
+ if (this.disposed) return;
216
+ this.disposed = true;
217
+
218
+ this.rejectAllPending('Server disconnected');
219
+
220
+ for (const handler of this.closeHandlers) {
221
+ handler();
222
+ }
223
+ }
224
+
225
+ /* Helpers */
226
+
227
+ // Single buffer write to prevent interleaving under concurrent requests
228
+ private writeMessage (message: Message): void {
229
+ const body = Buffer.from(JSON.stringify(message), 'utf-8');
230
+ const header = Buffer.from(`Content-Length: ${body.length}\r\n\r\n`, 'ascii');
231
+
232
+ this.writer.write(Buffer.concat([header, body]));
233
+ }
234
+
235
+ // Concat all chunks into 1 buffer
236
+ private compact (): Buffer {
237
+ if (this.chunks.length === 1) return this.chunks[0];
238
+
239
+ const buffer = Buffer.concat(this.chunks);
240
+
241
+ this.chunks = [buffer];
242
+ this.chunksLength = buffer.length;
243
+
244
+ return buffer;
245
+ }
246
+
247
+ // Consume n bytes from buffer
248
+ private consume (bytes: number): void {
249
+ const buffer = this.compact();
250
+ const remaining = buffer.subarray(bytes);
251
+
252
+ if (remaining.length > 0) {
253
+ this.chunks = [remaining];
254
+ this.chunksLength = remaining.length;
255
+ } else {
256
+ this.chunks = [];
257
+ this.chunksLength = 0;
258
+ }
259
+ }
260
+ }
@@ -0,0 +1,10 @@
1
+ export { JsonRpcClient, type MessageConnection } from './client.js';
2
+ export {
3
+ type RequestMessage,
4
+ type ResponseMessage,
5
+ type NotificationMessage,
6
+ type ResponseErrorLiteral,
7
+ Message,
8
+ ErrorCodes,
9
+ ResponseError,
10
+ } from './types.js';
@@ -0,0 +1,104 @@
1
+ /**
2
+ * JSON-RPC 2.0 message types and error codes
3
+ * Copied from vscode-jsonrpc (MIT, Microsoft Corporation)
4
+ * Ref: https://github.com/microsoft/vscode-languageserver-node/tree/main/jsonrpc/src/common/messages
5
+ */
6
+
7
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L11
8
+ export interface Message {
9
+ jsonrpc: string;
10
+ }
11
+
12
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L18
13
+ export interface RequestMessage extends Message {
14
+ id: number | string | null;
15
+ method: string;
16
+ params?: any[] | object;
17
+ }
18
+
19
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L150-L165
20
+ export interface ResponseMessage extends Message {
21
+ id: number | string | null;
22
+ result?: string | number | boolean | object | any[] | null;
23
+ error?: ResponseErrorLiteral<any>;
24
+ }
25
+
26
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L283-L292
27
+ export interface NotificationMessage extends Message {
28
+ method: string;
29
+ params?: any[] | object;
30
+ }
31
+
32
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L105-L122
33
+ export interface ResponseErrorLiteral<D = void> {
34
+ code: number;
35
+ message: string;
36
+ data?: D;
37
+ }
38
+
39
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L298-L323
40
+ export namespace Message {
41
+ export function isRequest (message: Message | undefined): message is RequestMessage {
42
+ const candidate = message as RequestMessage;
43
+ return candidate !== undefined && typeof candidate.method === 'string'
44
+ && (typeof candidate.id === 'string' || typeof candidate.id === 'number');
45
+ }
46
+
47
+ export function isNotification (message: Message | undefined): message is NotificationMessage {
48
+ const candidate = message as NotificationMessage;
49
+ return candidate !== undefined && typeof candidate.method === 'string'
50
+ && (candidate as any).id === undefined;
51
+ }
52
+
53
+ export function isResponse (message: Message | undefined): message is ResponseMessage {
54
+ const candidate = message as ResponseMessage;
55
+ return candidate !== undefined
56
+ && (candidate.result !== undefined || !!candidate.error)
57
+ && (typeof candidate.id === 'string' || typeof candidate.id === 'number' || candidate.id === null);
58
+ }
59
+ }
60
+
61
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L32-L83
62
+ export namespace ErrorCodes {
63
+ export const ParseError: -32700 = -32700;
64
+ export const InvalidRequest: -32600 = -32600;
65
+ export const MethodNotFound: -32601 = -32601;
66
+ export const InvalidParams: -32602 = -32602;
67
+ export const InternalError: -32603 = -32603;
68
+
69
+ // JSON-RPC reserved error range (-32099 to -32000)
70
+ export const jsonrpcReservedErrorRangeStart: -32099 = -32099;
71
+ export const MessageWriteError: -32099 = -32099;
72
+ export const MessageReadError: -32098 = -32098;
73
+ export const PendingResponseRejected: -32097 = -32097;
74
+ export const ConnectionInactive: -32096 = -32096;
75
+ export const ServerNotInitialized: -32002 = -32002;
76
+ export const UnknownErrorCode: -32001 = -32001;
77
+ export const jsonrpcReservedErrorRangeEnd: -32000 = -32000;
78
+ }
79
+
80
+ // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/messages.ts#L128-L148
81
+ export class ResponseError<D = void> extends Error {
82
+ readonly code: number;
83
+ readonly data: D | undefined;
84
+
85
+ constructor (code: number, message: string, data?: D) {
86
+ super(message);
87
+ this.code = typeof code === 'number' ? code : ErrorCodes.UnknownErrorCode;
88
+ this.data = data;
89
+ Object.setPrototypeOf(this, ResponseError.prototype);
90
+ }
91
+
92
+ toJson (): ResponseErrorLiteral<D> {
93
+ const result: ResponseErrorLiteral<D> = {
94
+ code: this.code,
95
+ message: this.message,
96
+ };
97
+
98
+ if (this.data !== undefined) {
99
+ result.data = this.data;
100
+ }
101
+
102
+ return result;
103
+ }
104
+ }
package/src/index.ts ADDED
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Typedown RPC client
3
+ *
4
+ * Thin wrapper over JsonRpcClient that provides typed methods
5
+ * matching the Rust RPC server's contract (rpc/contract.rs)
6
+ *
7
+ * The server (typedown-rpc binary) sends notifications for FS changes;
8
+ * register handlers via onContentChanged/onSchemaChanged/onConfigChanged
9
+ */
10
+
11
+ import type { Readable, Writable } from 'node:stream';
12
+ import { JsonRpcClient } from './core/index.js';
13
+
14
+ export { JsonRpcClient, Message, ResponseError, ErrorCodes } from './core/index.js';
15
+ export type { RequestMessage, ResponseMessage, NotificationMessage, ResponseErrorLiteral } from './core/index.js';
16
+
17
+ /* Types contract
18
+ * WARNING: must match the Rust contract in rpc/contract.rs */
19
+
20
+ export interface TdDiagnosticItem {
21
+ filepath: string;
22
+ line: number;
23
+ column: number;
24
+ severity: string;
25
+ code: string;
26
+ message: string;
27
+ }
28
+
29
+ export interface TdContentNotification {
30
+ content: string;
31
+ }
32
+
33
+ export interface TdFileMetadata {
34
+ mtime: number;
35
+ ctime: number;
36
+ }
37
+
38
+ export interface TdHeading {
39
+ level: number;
40
+ title: string;
41
+ slug: string;
42
+ }
43
+
44
+ export interface TdSidebarItem {
45
+ filepath: string;
46
+ schema?: string;
47
+ schemaLabel?: string;
48
+ label?: string;
49
+ icon?: TdIcon;
50
+ metadata: TdFileMetadata;
51
+ }
52
+
53
+ export interface TdContentSummary {
54
+ filepath: string;
55
+ schema?: string;
56
+ schemaLabel?: string;
57
+ label?: string;
58
+ icon?: TdIcon;
59
+ header: Record<string, any>;
60
+ excerpt?: string;
61
+ metadata: TdFileMetadata;
62
+ }
63
+
64
+ export interface TdNavItem {
65
+ title: string;
66
+ link: string;
67
+ icon?: string;
68
+ }
69
+
70
+ export interface TdIcon {
71
+ name: string;
72
+ }
73
+
74
+ export interface TdDiagnosticReport {
75
+ diagnostics: TdDiagnosticItem[];
76
+ fileCount: number;
77
+ errorCount: number;
78
+ warningCount: number;
79
+ }
80
+
81
+ export interface TdFormatResult {
82
+ content: string;
83
+ changed: boolean;
84
+ }
85
+
86
+ export interface TdSchemaNotification {
87
+ schema: string;
88
+ }
89
+
90
+ export interface TdSchemaInfo {
91
+ schema: string;
92
+ label: string;
93
+ properties: Record<string, any>;
94
+ }
95
+
96
+ export interface TdSiteConfig {
97
+ version: string;
98
+ basePath: string;
99
+ rootDir: string;
100
+ siteTitle: string;
101
+ siteDescription: string;
102
+ repo: string | undefined;
103
+ author: string | undefined;
104
+ license: string | undefined;
105
+ publicDir: string;
106
+ nav: TdNavItem[];
107
+ }
108
+
109
+ export interface TdBuiltResource {
110
+ schema?: string;
111
+ schemaLabel?: string;
112
+ label?: string;
113
+ icon?: TdIcon;
114
+ header: Record<string, any>;
115
+ content: string;
116
+ headings: TdHeading[];
117
+ title?: string;
118
+ metadata: TdFileMetadata;
119
+ }
120
+
121
+ // Server-reserved JSON-RPC error code for cancelled queries (-32000 to -32099)
122
+ export const RPC_CANCELLED_CODE = -32002;
123
+
124
+ /* Method names
125
+ * WARNING: must match Rust contract constants in rpc/contract.rs */
126
+
127
+ const METHOD_REQUEST_FILE = 'typedown_build.request_file';
128
+ const METHOD_REQUEST_FILES = 'typedown_build.request_files';
129
+ const METHOD_LIST_VAULT = 'typedown_build.list_vault';
130
+ const METHOD_LIST_FILES_GROUPED_BY_SCHEMA = 'typedown_build.list_files_grouped_by_schema';
131
+ const METHOD_LIST_SIDEBAR = 'typedown_build.list_sidebar';
132
+ const METHOD_LIST_SCHEMAS = 'typedown_build.list_schemas';
133
+ const METHOD_GET_SCHEMA = 'typedown_build.get_schema';
134
+ const METHOD_GET_VERSION = 'typedown_build.get_version';
135
+ const METHOD_GET_CONFIG = 'typedown_build.get_config';
136
+ const METHOD_CHECK_VAULT = 'typedown_build.check_vault';
137
+ const METHOD_FORMAT_FILE = 'typedown_build.format_file';
138
+
139
+ const NOTIF_CONTENT_CHANGED = 'typedown_build.content_changed';
140
+ const NOTIF_CONTENT_CREATED = 'typedown_build.content_created';
141
+ const NOTIF_CONTENT_DELETED = 'typedown_build.content_deleted';
142
+ const NOTIF_SCHEMA_CHANGED = 'typedown_build.schema_changed';
143
+ const NOTIF_SCHEMA_CREATED = 'typedown_build.schema_created';
144
+ const NOTIF_SCHEMA_DELETED = 'typedown_build.schema_deleted';
145
+ const NOTIF_CONFIG_CHANGED = 'typedown_build.config_changed';
146
+
147
+ /**
148
+ * Typed RPC client for the Typedown build server
149
+ *
150
+ * Wraps a generic JsonRpcClient with typed request methods
151
+ * and notification handlers matching the Rust RPC contract
152
+ */
153
+ export class RpcClient {
154
+ private rpc: JsonRpcClient;
155
+
156
+ private constructor (rpc: JsonRpcClient) {
157
+ this.rpc = rpc;
158
+ }
159
+
160
+ static async connectTcp (host: string, port: number): Promise<RpcClient> {
161
+ const rpc = await JsonRpcClient.connectTcp(host, port);
162
+ return new RpcClient(rpc);
163
+ }
164
+
165
+ static connectStdio (stdin: Readable, stdout: Writable): RpcClient {
166
+ return new RpcClient(JsonRpcClient.connectStdio(stdin, stdout));
167
+ }
168
+
169
+ dispose (): void {
170
+ this.rpc.dispose();
171
+ }
172
+
173
+ onClose (callback: () => void): { dispose: () => void } {
174
+ return this.rpc.onClose(callback);
175
+ }
176
+
177
+ /* Request methods */
178
+
179
+ requestFile (path: string): Promise<TdBuiltResource> {
180
+ return this.rpc.sendRequest(METHOD_REQUEST_FILE, { filePath: path });
181
+ }
182
+
183
+ requestFiles (paths: string[]): Promise<TdBuiltResource[]> {
184
+ return this.rpc.sendRequest(METHOD_REQUEST_FILES, { filePaths: paths });
185
+ }
186
+
187
+ listVault (): Promise<string[]> {
188
+ return this.rpc.sendRequest(METHOD_LIST_VAULT, {});
189
+ }
190
+
191
+ listFilesGroupedBySchema (): Promise<Record<string, TdContentSummary[]>> {
192
+ return this.rpc.sendRequest(METHOD_LIST_FILES_GROUPED_BY_SCHEMA, {});
193
+ }
194
+
195
+ listSidebar (): Promise<TdSidebarItem[]> {
196
+ return this.rpc.sendRequest(METHOD_LIST_SIDEBAR, {});
197
+ }
198
+
199
+ listSchemas (): Promise<string[]> {
200
+ return this.rpc.sendRequest(METHOD_LIST_SCHEMAS, {});
201
+ }
202
+
203
+ getSchema (schema: string): Promise<TdSchemaInfo> {
204
+ return this.rpc.sendRequest(METHOD_GET_SCHEMA, { schema });
205
+ }
206
+
207
+ getVersion (): Promise<string> {
208
+ return this.rpc.sendRequest(METHOD_GET_VERSION, {});
209
+ }
210
+
211
+ getConfig (): Promise<TdSiteConfig> {
212
+ return this.rpc.sendRequest(METHOD_GET_CONFIG, {});
213
+ }
214
+
215
+ checkVault (): Promise<TdDiagnosticReport> {
216
+ return this.rpc.sendRequest(METHOD_CHECK_VAULT, {});
217
+ }
218
+
219
+ formatFile (path: string): Promise<TdFormatResult> {
220
+ return this.rpc.sendRequest(METHOD_FORMAT_FILE, { filePath: path });
221
+ }
222
+
223
+ /* Notification handlers, server pushes these when FS changes are detected */
224
+
225
+ onContentChanged (callback: (notification: TdContentNotification) => void): void {
226
+ this.rpc.onNotification(NOTIF_CONTENT_CHANGED, callback);
227
+ }
228
+
229
+ onContentCreated (callback: (notification: TdContentNotification) => void): void {
230
+ this.rpc.onNotification(NOTIF_CONTENT_CREATED, callback);
231
+ }
232
+
233
+ onContentDeleted (callback: (notification: TdContentNotification) => void): void {
234
+ this.rpc.onNotification(NOTIF_CONTENT_DELETED, callback);
235
+ }
236
+
237
+ onSchemaChanged (callback: (notification: TdSchemaNotification) => void): void {
238
+ this.rpc.onNotification(NOTIF_SCHEMA_CHANGED, callback);
239
+ }
240
+
241
+ onSchemaCreated (callback: (notification: TdSchemaNotification) => void): void {
242
+ this.rpc.onNotification(NOTIF_SCHEMA_CREATED, callback);
243
+ }
244
+
245
+ onSchemaDeleted (callback: (notification: TdSchemaNotification) => void): void {
246
+ this.rpc.onNotification(NOTIF_SCHEMA_DELETED, callback);
247
+ }
248
+
249
+ onConfigChanged (callback: (config: TdSiteConfig) => void): void {
250
+ this.rpc.onNotification(NOTIF_CONFIG_CHANGED, callback);
251
+ }
252
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "NodeNext",
4
+ "moduleResolution": "NodeNext",
5
+ "target": "ES2022",
6
+ "lib": ["ES2022"],
7
+ "types": ["node"],
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "declaration": true,
11
+ "outDir": "./dist",
12
+ "rootDir": "./src"
13
+ },
14
+ "include": ["src"]
15
+ }