@hydranium/protocol 1.0.0-next.214 → 1.0.0-next.216

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: DataClientProtocol<TTransfer, TDiagnostic, TProject>;
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>(overrides?: Partial<DataClientProtocol<TTransfer, TDiagnostic, TProject>>): CapturingDataClient<TTransfer, TDiagnostic, TProject>;
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;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,KAAK,EACT,oBAAoB,EACpB,4BAA4B,EAC5B,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,0CAA0C;AAC1C,MAAM,WAAW,mBAAmB;IACjC;;;;;;;;OAQG;IACH,OAAO,IAAI,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC5D;AAED,8DAA8D;AAC9D,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;KAAE,EAAE,CAAC;IAC7F;;;;OAIG;IACH,WAAW,IAAI,IAAI,CAAC;IACpB,4FAA4F;IAC5F,OAAO,IAAI,IAAI,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAuB3E;AAED,oEAAoE;AACpE,MAAM,WAAW,mBAAmB,CACjC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,QAAQ,SAAS,OAAO,GAAG,OAAO;IAElC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;IACtE,yDAAyD;IACzD,QAAQ,CAAC,OAAO,EAAE,4BAA4B,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;IACzE,uDAAuD;IACvD,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,CAAC;IACrE,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,iCAAiC,EAAE,CAAC;IAC3D,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,4BAA4B,EAAE,CAAC;IACnD,wDAAwD;IACxD,QAAQ,CAAC,MAAM,EAAE,2BAA2B,EAAE,CAAC;IAC/C,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;CAC7D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACpC,SAAS,SAAS,eAAe,EACjC,WAAW,SAAS,kBAAkB,GAAG,kBAAkB,EAC3D,QAAQ,SAAS,OAAO,GAAG,OAAO,EACnC,SAAS,GAAE,OAAO,CAAC,kBAAkB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAM,GAAG,mBAAmB,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAwCtI"}
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 client = {
89
- onDocumentUpdated: overrides.onDocumentUpdated ??
101
+ const frameworkClient = {
102
+ onDocumentUpdated: frameworkOverrides.onDocumentUpdated ??
90
103
  (event => {
91
104
  updates.push(event);
92
105
  }),
93
- onDocumentSaved: overrides.onDocumentSaved ??
106
+ onDocumentSaved: frameworkOverrides.onDocumentSaved ??
94
107
  (event => {
95
108
  saves.push(event);
96
109
  }),
97
- onDocumentDirtyChanged: overrides.onDocumentDirtyChanged ??
110
+ onDocumentDirtyChanged: frameworkOverrides.onDocumentDirtyChanged ??
98
111
  (event => {
99
112
  dirtyChanges.push(event);
100
113
  }),
101
- onDocumentDeleted: overrides.onDocumentDeleted ??
114
+ onDocumentDeleted: frameworkOverrides.onDocumentDeleted ??
102
115
  (event => {
103
116
  deletions.push(event);
104
117
  }),
105
- onDocumentsBuilt: overrides.onDocumentsBuilt ??
118
+ onDocumentsBuilt: frameworkOverrides.onDocumentsBuilt ??
106
119
  (event => {
107
120
  builds.push(event);
108
121
  }),
109
- onProjectsChanged: overrides.onProjectsChanged ??
122
+ onProjectsChanged: frameworkOverrides.onProjectsChanged ??
110
123
  (event => {
111
124
  projectsChanges.push(event);
112
125
  })
113
126
  };
114
- return { client, updates, saves, dirtyChanges, deletions, builds, projectsChanges };
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;AA0DjE;;;;;;GAMG;AACH,0BAAiC,OAA4B;IAC1D,MAAM,WAAW,GAAwB,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAmD,EAAE,CAAC;IACpE,MAAM,cAAc,GAAG,IAAI,wBAAO,EAAQ,CAAC;IAC3C,OAAO;QACJ,WAAW;QACX,QAAQ;QACR,SAAS,EAAE,cAAc,CAAC,KAAK;QAC/B,KAAK,CAAC,OAAO;YACV,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAC3C,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7B,OAAO,UAAU,CAAC;QACrB,CAAC;QACD,WAAW,CAAC,KAAc,EAAE,OAAwB;YACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC;QACD,WAAW;YACR,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,OAAO;YACJ,cAAc,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;KACH,CAAC;AACL,CAAC;AAwBD;;;;;;;;;;;;GAYG;AACH,iCAIE,SAAS,GAAkE,EAAE;IAC5E,MAAM,OAAO,GAA2D,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAyD,EAAE,CAAC;IACvE,MAAM,YAAY,GAAwC,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAmC,EAAE,CAAC;IACrD,MAAM,MAAM,GAAkC,EAAE,CAAC;IACjD,MAAM,eAAe,GAAqC,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAyD;QAClE,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC,CAAC;QACL,eAAe,EACZ,SAAS,CAAC,eAAe;YACzB,CAAC,KAAK,CAAC,EAAE;gBACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC,CAAC;QACL,sBAAsB,EACnB,SAAS,CAAC,sBAAsB;YAChC,CAAC,KAAK,CAAC,EAAE;gBACN,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC,CAAC;QACL,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,CAAC,CAAC;QACL,gBAAgB,EACb,SAAS,CAAC,gBAAgB;YAC1B,CAAC,KAAK,CAAC,EAAE;gBACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,CAAC;QACL,iBAAiB,EACd,SAAS,CAAC,iBAAiB;YAC3B,CAAC,KAAK,CAAC,EAAE;gBACN,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC,CAAC;KACP,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AACvF,CAAC"}
1
+ {"version":3,"file":"data-doubles.js","sourceRoot":"","sources":["../../src/testing/data-doubles.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/protocol",
3
- "version": "1.0.0-next.214",
3
+ "version": "1.0.0-next.216",
4
4
  "description": "Generic, language-agnostic types, constants, and pure utilities for the hydranium framework.",
5
5
  "keywords": [
6
6
  "hydranium",
@@ -40,10 +40,6 @@
40
40
  "types": "./lib/client/index.d.ts",
41
41
  "default": "./lib/client/index.js"
42
42
  },
43
- "./lib/client": {
44
- "types": "./lib/client/index.d.ts",
45
- "default": "./lib/client/index.js"
46
- },
47
43
  "./data": {
48
44
  "types": "./lib/data/index.d.ts",
49
45
  "default": "./lib/data/index.js"
@@ -52,18 +48,10 @@
52
48
  "types": "./lib/messages/index.d.ts",
53
49
  "default": "./lib/messages/index.js"
54
50
  },
55
- "./lib/messages": {
56
- "types": "./lib/messages/index.d.ts",
57
- "default": "./lib/messages/index.js"
58
- },
59
51
  "./node": {
60
52
  "types": "./lib/node/index.d.ts",
61
53
  "default": "./lib/node/index.js"
62
54
  },
63
- "./lib/node": {
64
- "types": "./lib/node/index.d.ts",
65
- "default": "./lib/node/index.js"
66
- },
67
55
  "./testing": {
68
56
  "types": "./lib/testing/index.d.ts",
69
57
  "default": "./lib/testing/index.js"
@@ -71,18 +59,6 @@
71
59
  "./testing/node": {
72
60
  "types": "./lib/testing/node/index.d.ts",
73
61
  "default": "./lib/testing/node/index.js"
74
- },
75
- "./lib/data": {
76
- "types": "./lib/data/index.d.ts",
77
- "default": "./lib/data/index.js"
78
- },
79
- "./lib/testing": {
80
- "types": "./lib/testing/index.d.ts",
81
- "default": "./lib/testing/index.js"
82
- },
83
- "./lib/testing/node": {
84
- "types": "./lib/testing/node/index.d.ts",
85
- "default": "./lib/testing/node/index.js"
86
62
  }
87
63
  },
88
64
  "publishConfig": {
package/src/rpc/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # JSON-RPC primitives
2
2
 
3
3
  Exported from the package root, `@hydranium/protocol`. There is no
4
- `@hydranium/protocol/rpc` subpath: the package's `exports` map publishes `.`,
5
- `./client`, `./data` and `./testing` (plus their `./lib/*` twins), so importing
6
- this directory by path fails with `ERR_PACKAGE_PATH_NOT_EXPORTED`.
4
+ `@hydranium/protocol/rpc` subpath: the package's `exports` map declares none,
5
+ so importing this directory by path fails with `ERR_PACKAGE_PATH_NOT_EXPORTED`.
7
6
 
8
7
  Generic JSON-RPC primitives for typed protocol heads over a vscode-jsonrpc
9
8
  `MessageConnection`. This page is the reference; the shape of the pattern and
@@ -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: DataClientProtocol<TTransfer, TDiagnostic, TProject>;
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
- >(overrides: Partial<DataClientProtocol<TTransfer, TDiagnostic, TProject>> = {}): CapturingDataClient<TTransfer, TDiagnostic, TProject> {
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 client: DataClientProtocol<TTransfer, TDiagnostic, TProject> = {
236
+ const frameworkClient: DataClientProtocol<TTransfer, TDiagnostic, TProject> = {
171
237
  onDocumentUpdated:
172
- overrides.onDocumentUpdated ??
238
+ frameworkOverrides.onDocumentUpdated ??
173
239
  (event => {
174
240
  updates.push(event);
175
241
  }),
176
242
  onDocumentSaved:
177
- overrides.onDocumentSaved ??
243
+ frameworkOverrides.onDocumentSaved ??
178
244
  (event => {
179
245
  saves.push(event);
180
246
  }),
181
247
  onDocumentDirtyChanged:
182
- overrides.onDocumentDirtyChanged ??
248
+ frameworkOverrides.onDocumentDirtyChanged ??
183
249
  (event => {
184
250
  dirtyChanges.push(event);
185
251
  }),
186
252
  onDocumentDeleted:
187
- overrides.onDocumentDeleted ??
253
+ frameworkOverrides.onDocumentDeleted ??
188
254
  (event => {
189
255
  deletions.push(event);
190
256
  }),
191
257
  onDocumentsBuilt:
192
- overrides.onDocumentsBuilt ??
258
+ frameworkOverrides.onDocumentsBuilt ??
193
259
  (event => {
194
260
  builds.push(event);
195
261
  }),
196
262
  onProjectsChanged:
197
- overrides.onProjectsChanged ??
263
+ frameworkOverrides.onProjectsChanged ??
198
264
  (event => {
199
265
  projectsChanges.push(event);
200
266
  })
201
267
  };
202
- return { client, updates, saves, dirtyChanges, deletions, builds, projectsChanges };
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
  }