@hydranium/protocol 1.0.0-next.214 → 1.0.0-next.215
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.
|
@@ -34,6 +34,7 @@ import type { DataPort } from '../client/data-port';
|
|
|
34
34
|
import type { DataClientProtocol } from '../data/data-server-protocol';
|
|
35
35
|
import type { ProjectsChangedEvent, TransferDocumentDeletedEvent, TransferDocumentDirtyChangedEvent, TransferDocumentSavedEvent, TransferDocumentsBuiltEvent, TransferDocumentUpdatedEvent } from '../data/events';
|
|
36
36
|
import type { ResolvedMessage } from '../messages/primitives';
|
|
37
|
+
import type { RpcProxyLifecycle } from '../rpc/create-rpc-proxy';
|
|
37
38
|
import type { Project } from '../project';
|
|
38
39
|
import type { TransferDiagnostic } from '../transfer-diagnostic';
|
|
39
40
|
import type { TransferElement } from '../transfer-element';
|
|
@@ -88,10 +89,18 @@ export interface FakeDataPort extends DataPort {
|
|
|
88
89
|
* connection with no server behind it, a different one per generation.
|
|
89
90
|
*/
|
|
90
91
|
export declare function makeFakeDataPort(options: FakeDataPortOptions): FakeDataPort;
|
|
92
|
+
type UpperLetter = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
|
|
93
|
+
/**
|
|
94
|
+
* A notification name `TClient` adds to {@link DataClientProtocol}. Limited to
|
|
95
|
+
* `on` plus a letter A–Z, the names the proxy sends as notifications; any other
|
|
96
|
+
* name would be bound as a request. The {@link RpcProxyLifecycle} names are
|
|
97
|
+
* excluded too: the proxy returns its own events for them and sends nothing.
|
|
98
|
+
*/
|
|
99
|
+
export type AdditionalClientMethod<TClient> = Exclude<keyof TClient, keyof DataClientProtocol<TransferElement> | keyof RpcProxyLifecycle> & `on${UpperLetter}${string}`;
|
|
91
100
|
/** A {@link DataClientProtocol} plus the arrays it records into. */
|
|
92
|
-
export interface CapturingDataClient<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic, TProject extends Project = Project> {
|
|
101
|
+
export interface CapturingDataClient<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic, TProject extends Project = Project, TClient extends DataClientProtocol<TTransfer, TDiagnostic, TProject> = DataClientProtocol<TTransfer, TDiagnostic, TProject>> {
|
|
93
102
|
/** The client to hand to a `DataSession` or bind as an RPC `localTarget`. */
|
|
94
|
-
readonly client:
|
|
103
|
+
readonly client: TClient;
|
|
95
104
|
/** Every `onDocumentUpdated` event, in arrival order. */
|
|
96
105
|
readonly updates: TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>[];
|
|
97
106
|
/** Every `onDocumentSaved` event, in arrival order. */
|
|
@@ -104,6 +113,14 @@ export interface CapturingDataClient<TTransfer extends TransferElement, TDiagnos
|
|
|
104
113
|
readonly builds: TransferDocumentsBuiltEvent[];
|
|
105
114
|
/** Every `onProjectsChanged` event, in arrival order. */
|
|
106
115
|
readonly projectsChanges: ProjectsChangedEvent<TProject>[];
|
|
116
|
+
/**
|
|
117
|
+
* Every event of each additional client method, keyed by method, in arrival
|
|
118
|
+
* order. A method of `TClient` left out of `additionalClientMethods` has no
|
|
119
|
+
* entry.
|
|
120
|
+
*/
|
|
121
|
+
readonly additionalNotifications: {
|
|
122
|
+
readonly [K in AdditionalClientMethod<TClient>]: TClient[K] extends (event: infer TEvent) => void ? TEvent[] : never;
|
|
123
|
+
};
|
|
107
124
|
}
|
|
108
125
|
/**
|
|
109
126
|
* A {@link DataClientProtocol} that records every notification it receives.
|
|
@@ -117,6 +134,12 @@ export interface CapturingDataClient<TTransfer extends TransferElement, TDiagnos
|
|
|
117
134
|
* the corresponding array stays empty — that is what makes an override usable
|
|
118
135
|
* as a barrier (rejecting, counting differently, throwing) rather than only as
|
|
119
136
|
* a spy.
|
|
137
|
+
*
|
|
138
|
+
* `additionalClientMethods` names the notifications `TClient` adds to
|
|
139
|
+
* {@link DataClientProtocol}. Each is recorded and overridable the same way;
|
|
140
|
+
* one left out is not on the client at all, and overriding it throws, since
|
|
141
|
+
* nothing would call the override.
|
|
120
142
|
*/
|
|
121
|
-
export declare function makeCapturingDataClient<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic, TProject extends Project = Project>
|
|
143
|
+
export declare function makeCapturingDataClient<TTransfer extends TransferElement, TDiagnostic extends TransferDiagnostic = TransferDiagnostic, TProject extends Project = Project, TClient extends DataClientProtocol<TTransfer, TDiagnostic, TProject> = DataClientProtocol<TTransfer, TDiagnostic, TProject>>(overrides?: Partial<TClient>, additionalClientMethods?: readonly AdditionalClientMethod<TClient>[]): CapturingDataClient<TTransfer, TDiagnostic, TProject, TClient>;
|
|
144
|
+
export {};
|
|
122
145
|
//# sourceMappingURL=data-doubles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-doubles.d.ts","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAW,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"data-doubles.d.ts","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,7 @@ exports.makeCapturingDataClient = makeCapturingDataClient;
|
|
|
34
34
|
* which `sourceClientId`, which version, which reason.
|
|
35
35
|
*/
|
|
36
36
|
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
|
|
37
|
+
const data_protocol_methods_1 = require("../data/data-protocol-methods");
|
|
37
38
|
/**
|
|
38
39
|
* A {@link DataPort} over a transport the caller supplies.
|
|
39
40
|
*
|
|
@@ -77,40 +78,72 @@ function makeFakeDataPort(options) {
|
|
|
77
78
|
* the corresponding array stays empty — that is what makes an override usable
|
|
78
79
|
* as a barrier (rejecting, counting differently, throwing) rather than only as
|
|
79
80
|
* a spy.
|
|
81
|
+
*
|
|
82
|
+
* `additionalClientMethods` names the notifications `TClient` adds to
|
|
83
|
+
* {@link DataClientProtocol}. Each is recorded and overridable the same way;
|
|
84
|
+
* one left out is not on the client at all, and overriding it throws, since
|
|
85
|
+
* nothing would call the override.
|
|
80
86
|
*/
|
|
81
|
-
function makeCapturingDataClient(overrides = {}) {
|
|
87
|
+
function makeCapturingDataClient(overrides = {}, additionalClientMethods = []) {
|
|
88
|
+
const bound = new Set([...data_protocol_methods_1.DATA_CLIENT_PROTOCOL_METHODS, ...additionalClientMethods]);
|
|
89
|
+
for (const name of Object.keys(overrides)) {
|
|
90
|
+
if (!bound.has(name)) {
|
|
91
|
+
throw new Error(`Override '${name}' is neither a DataClientProtocol method nor listed in additionalClientMethods, so nothing would call it.`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const frameworkOverrides = overrides;
|
|
82
95
|
const updates = [];
|
|
83
96
|
const saves = [];
|
|
84
97
|
const dirtyChanges = [];
|
|
85
98
|
const deletions = [];
|
|
86
99
|
const builds = [];
|
|
87
100
|
const projectsChanges = [];
|
|
88
|
-
const
|
|
89
|
-
onDocumentUpdated:
|
|
101
|
+
const frameworkClient = {
|
|
102
|
+
onDocumentUpdated: frameworkOverrides.onDocumentUpdated ??
|
|
90
103
|
(event => {
|
|
91
104
|
updates.push(event);
|
|
92
105
|
}),
|
|
93
|
-
onDocumentSaved:
|
|
106
|
+
onDocumentSaved: frameworkOverrides.onDocumentSaved ??
|
|
94
107
|
(event => {
|
|
95
108
|
saves.push(event);
|
|
96
109
|
}),
|
|
97
|
-
onDocumentDirtyChanged:
|
|
110
|
+
onDocumentDirtyChanged: frameworkOverrides.onDocumentDirtyChanged ??
|
|
98
111
|
(event => {
|
|
99
112
|
dirtyChanges.push(event);
|
|
100
113
|
}),
|
|
101
|
-
onDocumentDeleted:
|
|
114
|
+
onDocumentDeleted: frameworkOverrides.onDocumentDeleted ??
|
|
102
115
|
(event => {
|
|
103
116
|
deletions.push(event);
|
|
104
117
|
}),
|
|
105
|
-
onDocumentsBuilt:
|
|
118
|
+
onDocumentsBuilt: frameworkOverrides.onDocumentsBuilt ??
|
|
106
119
|
(event => {
|
|
107
120
|
builds.push(event);
|
|
108
121
|
}),
|
|
109
|
-
onProjectsChanged:
|
|
122
|
+
onProjectsChanged: frameworkOverrides.onProjectsChanged ??
|
|
110
123
|
(event => {
|
|
111
124
|
projectsChanges.push(event);
|
|
112
125
|
})
|
|
113
126
|
};
|
|
114
|
-
|
|
127
|
+
const additionalNotifications = {};
|
|
128
|
+
const additionalHandlers = {};
|
|
129
|
+
for (const method of additionalClientMethods) {
|
|
130
|
+
const events = [];
|
|
131
|
+
additionalNotifications[method] = events;
|
|
132
|
+
additionalHandlers[method] =
|
|
133
|
+
overrides[method] ??
|
|
134
|
+
((event) => {
|
|
135
|
+
events.push(event);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
client: { ...frameworkClient, ...additionalHandlers },
|
|
140
|
+
updates,
|
|
141
|
+
saves,
|
|
142
|
+
dirtyChanges,
|
|
143
|
+
deletions,
|
|
144
|
+
builds,
|
|
145
|
+
projectsChanges,
|
|
146
|
+
additionalNotifications: additionalNotifications
|
|
147
|
+
};
|
|
115
148
|
}
|
|
116
149
|
//# sourceMappingURL=data-doubles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-doubles.js","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":";AAAA;;;;;;;kFAOkF;;;;AAElF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,mDAAiE;
|
|
1
|
+
{"version":3,"file":"data-doubles.js","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
|
|
34
34
|
import { Emitter, type MessageConnection } from 'vscode-jsonrpc';
|
|
35
35
|
import type { DataPort } from '../client/data-port';
|
|
36
|
+
import { DATA_CLIENT_PROTOCOL_METHODS } from '../data/data-protocol-methods';
|
|
36
37
|
import type { DataClientProtocol } from '../data/data-server-protocol';
|
|
37
38
|
import type {
|
|
38
39
|
ProjectsChangedEvent,
|
|
@@ -43,6 +44,7 @@ import type {
|
|
|
43
44
|
TransferDocumentUpdatedEvent
|
|
44
45
|
} from '../data/events';
|
|
45
46
|
import type { ResolvedMessage } from '../messages/primitives';
|
|
47
|
+
import type { RpcProxyLifecycle } from '../rpc/create-rpc-proxy';
|
|
46
48
|
import type { Project } from '../project';
|
|
47
49
|
import type { TransferDiagnostic } from '../transfer-diagnostic';
|
|
48
50
|
import type { TransferElement } from '../transfer-element';
|
|
@@ -121,14 +123,52 @@ export function makeFakeDataPort(options: FakeDataPortOptions): FakeDataPort {
|
|
|
121
123
|
};
|
|
122
124
|
}
|
|
123
125
|
|
|
126
|
+
type UpperLetter =
|
|
127
|
+
| 'A'
|
|
128
|
+
| 'B'
|
|
129
|
+
| 'C'
|
|
130
|
+
| 'D'
|
|
131
|
+
| 'E'
|
|
132
|
+
| 'F'
|
|
133
|
+
| 'G'
|
|
134
|
+
| 'H'
|
|
135
|
+
| 'I'
|
|
136
|
+
| 'J'
|
|
137
|
+
| 'K'
|
|
138
|
+
| 'L'
|
|
139
|
+
| 'M'
|
|
140
|
+
| 'N'
|
|
141
|
+
| 'O'
|
|
142
|
+
| 'P'
|
|
143
|
+
| 'Q'
|
|
144
|
+
| 'R'
|
|
145
|
+
| 'S'
|
|
146
|
+
| 'T'
|
|
147
|
+
| 'U'
|
|
148
|
+
| 'V'
|
|
149
|
+
| 'W'
|
|
150
|
+
| 'X'
|
|
151
|
+
| 'Y'
|
|
152
|
+
| 'Z';
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* A notification name `TClient` adds to {@link DataClientProtocol}. Limited to
|
|
156
|
+
* `on` plus a letter A–Z, the names the proxy sends as notifications; any other
|
|
157
|
+
* name would be bound as a request. The {@link RpcProxyLifecycle} names are
|
|
158
|
+
* excluded too: the proxy returns its own events for them and sends nothing.
|
|
159
|
+
*/
|
|
160
|
+
export type AdditionalClientMethod<TClient> = Exclude<keyof TClient, keyof DataClientProtocol<TransferElement> | keyof RpcProxyLifecycle> &
|
|
161
|
+
`on${UpperLetter}${string}`;
|
|
162
|
+
|
|
124
163
|
/** A {@link DataClientProtocol} plus the arrays it records into. */
|
|
125
164
|
export interface CapturingDataClient<
|
|
126
165
|
TTransfer extends TransferElement,
|
|
127
166
|
TDiagnostic extends TransferDiagnostic = TransferDiagnostic,
|
|
128
|
-
TProject extends Project = Project
|
|
167
|
+
TProject extends Project = Project,
|
|
168
|
+
TClient extends DataClientProtocol<TTransfer, TDiagnostic, TProject> = DataClientProtocol<TTransfer, TDiagnostic, TProject>
|
|
129
169
|
> {
|
|
130
170
|
/** The client to hand to a `DataSession` or bind as an RPC `localTarget`. */
|
|
131
|
-
readonly client:
|
|
171
|
+
readonly client: TClient;
|
|
132
172
|
/** Every `onDocumentUpdated` event, in arrival order. */
|
|
133
173
|
readonly updates: TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>[];
|
|
134
174
|
/** Every `onDocumentSaved` event, in arrival order. */
|
|
@@ -141,6 +181,14 @@ export interface CapturingDataClient<
|
|
|
141
181
|
readonly builds: TransferDocumentsBuiltEvent[];
|
|
142
182
|
/** Every `onProjectsChanged` event, in arrival order. */
|
|
143
183
|
readonly projectsChanges: ProjectsChangedEvent<TProject>[];
|
|
184
|
+
/**
|
|
185
|
+
* Every event of each additional client method, keyed by method, in arrival
|
|
186
|
+
* order. A method of `TClient` left out of `additionalClientMethods` has no
|
|
187
|
+
* entry.
|
|
188
|
+
*/
|
|
189
|
+
readonly additionalNotifications: {
|
|
190
|
+
readonly [K in AdditionalClientMethod<TClient>]: TClient[K] extends (event: infer TEvent) => void ? TEvent[] : never;
|
|
191
|
+
};
|
|
144
192
|
}
|
|
145
193
|
|
|
146
194
|
/**
|
|
@@ -155,49 +203,92 @@ export interface CapturingDataClient<
|
|
|
155
203
|
* the corresponding array stays empty — that is what makes an override usable
|
|
156
204
|
* as a barrier (rejecting, counting differently, throwing) rather than only as
|
|
157
205
|
* a spy.
|
|
206
|
+
*
|
|
207
|
+
* `additionalClientMethods` names the notifications `TClient` adds to
|
|
208
|
+
* {@link DataClientProtocol}. Each is recorded and overridable the same way;
|
|
209
|
+
* one left out is not on the client at all, and overriding it throws, since
|
|
210
|
+
* nothing would call the override.
|
|
158
211
|
*/
|
|
159
212
|
export function makeCapturingDataClient<
|
|
160
213
|
TTransfer extends TransferElement,
|
|
161
214
|
TDiagnostic extends TransferDiagnostic = TransferDiagnostic,
|
|
162
|
-
TProject extends Project = Project
|
|
163
|
-
|
|
215
|
+
TProject extends Project = Project,
|
|
216
|
+
TClient extends DataClientProtocol<TTransfer, TDiagnostic, TProject> = DataClientProtocol<TTransfer, TDiagnostic, TProject>
|
|
217
|
+
>(
|
|
218
|
+
overrides: Partial<TClient> = {},
|
|
219
|
+
additionalClientMethods: readonly AdditionalClientMethod<TClient>[] = []
|
|
220
|
+
): CapturingDataClient<TTransfer, TDiagnostic, TProject, TClient> {
|
|
221
|
+
const bound = new Set<string>([...DATA_CLIENT_PROTOCOL_METHODS, ...additionalClientMethods]);
|
|
222
|
+
for (const name of Object.keys(overrides)) {
|
|
223
|
+
if (!bound.has(name)) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`Override '${name}' is neither a DataClientProtocol method nor listed in additionalClientMethods, so nothing would call it.`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const frameworkOverrides: Partial<DataClientProtocol<TTransfer, TDiagnostic, TProject>> = overrides;
|
|
164
230
|
const updates: TransferDocumentUpdatedEvent<TTransfer, TDiagnostic>[] = [];
|
|
165
231
|
const saves: TransferDocumentSavedEvent<TTransfer, TDiagnostic>[] = [];
|
|
166
232
|
const dirtyChanges: TransferDocumentDirtyChangedEvent[] = [];
|
|
167
233
|
const deletions: TransferDocumentDeletedEvent[] = [];
|
|
168
234
|
const builds: TransferDocumentsBuiltEvent[] = [];
|
|
169
235
|
const projectsChanges: ProjectsChangedEvent<TProject>[] = [];
|
|
170
|
-
const
|
|
236
|
+
const frameworkClient: DataClientProtocol<TTransfer, TDiagnostic, TProject> = {
|
|
171
237
|
onDocumentUpdated:
|
|
172
|
-
|
|
238
|
+
frameworkOverrides.onDocumentUpdated ??
|
|
173
239
|
(event => {
|
|
174
240
|
updates.push(event);
|
|
175
241
|
}),
|
|
176
242
|
onDocumentSaved:
|
|
177
|
-
|
|
243
|
+
frameworkOverrides.onDocumentSaved ??
|
|
178
244
|
(event => {
|
|
179
245
|
saves.push(event);
|
|
180
246
|
}),
|
|
181
247
|
onDocumentDirtyChanged:
|
|
182
|
-
|
|
248
|
+
frameworkOverrides.onDocumentDirtyChanged ??
|
|
183
249
|
(event => {
|
|
184
250
|
dirtyChanges.push(event);
|
|
185
251
|
}),
|
|
186
252
|
onDocumentDeleted:
|
|
187
|
-
|
|
253
|
+
frameworkOverrides.onDocumentDeleted ??
|
|
188
254
|
(event => {
|
|
189
255
|
deletions.push(event);
|
|
190
256
|
}),
|
|
191
257
|
onDocumentsBuilt:
|
|
192
|
-
|
|
258
|
+
frameworkOverrides.onDocumentsBuilt ??
|
|
193
259
|
(event => {
|
|
194
260
|
builds.push(event);
|
|
195
261
|
}),
|
|
196
262
|
onProjectsChanged:
|
|
197
|
-
|
|
263
|
+
frameworkOverrides.onProjectsChanged ??
|
|
198
264
|
(event => {
|
|
199
265
|
projectsChanges.push(event);
|
|
200
266
|
})
|
|
201
267
|
};
|
|
202
|
-
|
|
268
|
+
const additionalNotifications: Record<string, unknown[]> = {};
|
|
269
|
+
const additionalHandlers: Record<string, unknown> = {};
|
|
270
|
+
for (const method of additionalClientMethods) {
|
|
271
|
+
const events: unknown[] = [];
|
|
272
|
+
additionalNotifications[method] = events;
|
|
273
|
+
additionalHandlers[method] =
|
|
274
|
+
overrides[method] ??
|
|
275
|
+
((event: unknown) => {
|
|
276
|
+
events.push(event);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
client: { ...frameworkClient, ...additionalHandlers } as unknown as TClient,
|
|
281
|
+
updates,
|
|
282
|
+
saves,
|
|
283
|
+
dirtyChanges,
|
|
284
|
+
deletions,
|
|
285
|
+
builds,
|
|
286
|
+
projectsChanges,
|
|
287
|
+
additionalNotifications: additionalNotifications as CapturingDataClient<
|
|
288
|
+
TTransfer,
|
|
289
|
+
TDiagnostic,
|
|
290
|
+
TProject,
|
|
291
|
+
TClient
|
|
292
|
+
>['additionalNotifications']
|
|
293
|
+
};
|
|
203
294
|
}
|