@rest-vir/define-service 0.2.0 → 0.3.1
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/dist/frontend-connect/generate-api.d.ts +1 -1
- package/dist/frontend-connect/mock-client-web-socket.d.ts +3 -3
- package/dist/frontend-connect/mock-client-web-socket.js +8 -6
- package/dist/web-socket/overwrite-web-socket-methods.d.ts +29 -5
- package/dist/web-socket/overwrite-web-socket-methods.js +9 -4
- package/package.json +1 -1
|
@@ -24,7 +24,7 @@ export type RestVirApi<SpecificService extends ServiceDefinition> = {
|
|
|
24
24
|
webSockets: {
|
|
25
25
|
[WebSocketPath in keyof SpecificService['webSockets']]: SpecificService['webSockets'][WebSocketPath] extends WebSocketDefinition ? SpecificService['webSockets'][WebSocketPath] & {
|
|
26
26
|
/** Connect to this WebSocket. */
|
|
27
|
-
connect(...params: CollapsedConnectWebSocketParams<SpecificService['webSockets'][WebSocketPath], false
|
|
27
|
+
connect(...params: CollapsedConnectWebSocketParams<SpecificService['webSockets'][WebSocketPath], false>): Promise<ClientWebSocket<SpecificService['webSockets'][WebSocketPath]>>;
|
|
28
28
|
} : never;
|
|
29
29
|
};
|
|
30
30
|
};
|
|
@@ -78,7 +78,7 @@ export declare function createMockClientWebSocketConstructor<const WebSocketToCo
|
|
|
78
78
|
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
79
79
|
*/
|
|
80
80
|
export type MockClientWebSocketListeners = Partial<{
|
|
81
|
-
[EventName in keyof CommonWebSocketEventMap]: Set<(event: CommonWebSocketEventMap[EventName]) => void
|
|
81
|
+
[EventName in keyof CommonWebSocketEventMap]: Set<(event: CommonWebSocketEventMap[EventName]) => MaybePromise<void>>;
|
|
82
82
|
}>;
|
|
83
83
|
/**
|
|
84
84
|
* A mock WebSocket constructor for connections from the client side. This can be passed to
|
|
@@ -165,14 +165,14 @@ export declare class MockClientWebSocket<const WebSocketToConnect extends WebSoc
|
|
|
165
165
|
*
|
|
166
166
|
* @see https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener
|
|
167
167
|
*/
|
|
168
|
-
addEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: (event: CommonWebSocketEventMap[EventName]) => void): void;
|
|
168
|
+
addEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: (event: CommonWebSocketEventMap[EventName]) => MaybePromise<void>): void;
|
|
169
169
|
/**
|
|
170
170
|
* Implements and mocks the standard `WebSocket.removeEventListener` property but with message
|
|
171
171
|
* type safety.
|
|
172
172
|
*
|
|
173
173
|
* @see https://developer.mozilla.org/docs/Web/API/EventTarget/removeEventListener
|
|
174
174
|
*/
|
|
175
|
-
removeEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: (event: CommonWebSocketEventMap[EventName]) => void): void;
|
|
175
|
+
removeEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: (event: CommonWebSocketEventMap[EventName]) => MaybePromise<void>): void;
|
|
176
176
|
/**
|
|
177
177
|
* Implements and mocks the standard `WebSocket.send` property but with message type safety.
|
|
178
178
|
*
|
|
@@ -139,11 +139,13 @@ export class MockClientWebSocket {
|
|
|
139
139
|
* methods instead (which appropriately dispatch their events).
|
|
140
140
|
*/
|
|
141
141
|
dispatchEvent(eventName, event) {
|
|
142
|
-
this.listeners[eventName]?.forEach((listener) =>
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
this.listeners[eventName]?.forEach((listener) => {
|
|
143
|
+
void listener({
|
|
144
|
+
...event,
|
|
145
|
+
target: this,
|
|
146
|
+
type: eventName,
|
|
147
|
+
});
|
|
148
|
+
});
|
|
147
149
|
}
|
|
148
150
|
/**
|
|
149
151
|
* Implements and mocks the standard `WebSocket.addEventListener` property but with message type
|
|
@@ -187,7 +189,7 @@ export class MockClientWebSocket {
|
|
|
187
189
|
return;
|
|
188
190
|
}
|
|
189
191
|
this.dispatchEvent('message', {
|
|
190
|
-
data,
|
|
192
|
+
data: JSON.stringify(data),
|
|
191
193
|
});
|
|
192
194
|
void this.sendCallback?.({
|
|
193
195
|
messageData: data,
|
|
@@ -69,6 +69,13 @@ export type SendAndWaitForReplyParams<Location extends WebSocketLocation, WebSoc
|
|
|
69
69
|
* @default {seconds: 10}
|
|
70
70
|
*/
|
|
71
71
|
timeout?: Readonly<AnyDuration> | undefined;
|
|
72
|
+
/**
|
|
73
|
+
* An optional function to check if the current reply is the one you were waiting for.
|
|
74
|
+
*
|
|
75
|
+
* If this is set, `sendAndWaitForReply` will wait until a reply is received that matches this
|
|
76
|
+
* condition. If this not set, the first reply is used.
|
|
77
|
+
*/
|
|
78
|
+
replyCheck?: (messageFromHost: WebSocketToConnect extends NoParam ? any : Exclude<WebSocketToConnect, NoParam>['MessageFromHostType']) => MaybePromise<boolean>;
|
|
72
79
|
};
|
|
73
80
|
/**
|
|
74
81
|
* Collapsed version of {@link SendAndWaitForReplyParams} for the `sendAndWaitForReply` method that
|
|
@@ -82,6 +89,23 @@ export type CollapsedSendAndWaitForReplyParams<Location extends WebSocketLocatio
|
|
|
82
89
|
MessageFromClientType: true;
|
|
83
90
|
MessageFromHostType: true;
|
|
84
91
|
}>> | NoParam = NoParam> = HasRequiredKeys<SendAndWaitForReplyParams<Location, WebSocketToConnect>> extends true ? [SendAndWaitForReplyParams<Location, WebSocketToConnect>] : [SendAndWaitForReplyParams<Location, WebSocketToConnect>?];
|
|
92
|
+
/**
|
|
93
|
+
* Narrows a {@link WebSocketDefinition} for use within {@link OverwriteWebSocketMethods}.
|
|
94
|
+
*
|
|
95
|
+
* @category Internal
|
|
96
|
+
* @category Package : @rest-vir/define-service
|
|
97
|
+
* @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
|
|
98
|
+
*/
|
|
99
|
+
export type NarrowOriginalDefinition<OriginalWebSocketDefinition extends Readonly<SelectFrom<WebSocketDefinition, {
|
|
100
|
+
MessageFromClientType: true;
|
|
101
|
+
MessageFromHostType: true;
|
|
102
|
+
SearchParamsType: true;
|
|
103
|
+
}>> | NoParam = NoParam> = OriginalWebSocketDefinition extends NoParam ? NoParam : Omit<OriginalWebSocketDefinition,
|
|
104
|
+
/**
|
|
105
|
+
* Omit connect so this is compatible with API WebSocket objects (which have a `connect`
|
|
106
|
+
* method).
|
|
107
|
+
*/
|
|
108
|
+
'connect'>;
|
|
85
109
|
/**
|
|
86
110
|
* Takes any WebSocket class and overwrites it with some new rest vir methods and makes some
|
|
87
111
|
* existing WebSocket methods type safe.
|
|
@@ -104,7 +128,7 @@ export type OverwriteWebSocketMethods<WebSocketClass extends CommonWebSocket, Lo
|
|
|
104
128
|
* Adds an event listener that's wrapped in assertions to verify that message events have
|
|
105
129
|
* the expected contents.
|
|
106
130
|
*/
|
|
107
|
-
addEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: WebSocketListener<EventName, OriginalWebSocketDefinition
|
|
131
|
+
addEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: WebSocketListener<EventName, NarrowOriginalDefinition<OriginalWebSocketDefinition>, FlipWebSocketLocation<Location>, WebSocketClass>): void;
|
|
108
132
|
/**
|
|
109
133
|
* Sends a message to the other side of the WebSocket connection and waits that other side
|
|
110
134
|
* to send a message in response.
|
|
@@ -112,7 +136,7 @@ export type OverwriteWebSocketMethods<WebSocketClass extends CommonWebSocket, Lo
|
|
|
112
136
|
* This will catch messages that might not have been intended as a response for the original
|
|
113
137
|
* message as it will catch _any_ message sent from the other side.
|
|
114
138
|
*/
|
|
115
|
-
sendAndWaitForReply(...params: CollapsedSendAndWaitForReplyParams<Location, OriginalWebSocketDefinition
|
|
139
|
+
sendAndWaitForReply(...params: CollapsedSendAndWaitForReplyParams<Location, NarrowOriginalDefinition<OriginalWebSocketDefinition>>): Promise<NarrowOriginalDefinition<OriginalWebSocketDefinition> extends NoParam ? any : GetWebSocketMessageTypeFromLocation<Exclude<NarrowOriginalDefinition<OriginalWebSocketDefinition>, NoParam>, FlipWebSocketLocation<Location>>>;
|
|
116
140
|
/**
|
|
117
141
|
* Sends data through the WebSocket to the other side of the connection. This rest-vir
|
|
118
142
|
* wrapper ensures that all sent messages match expected types from the WebSocket
|
|
@@ -121,10 +145,10 @@ export type OverwriteWebSocketMethods<WebSocketClass extends CommonWebSocket, Lo
|
|
|
121
145
|
* See [MDN](https://developer.mozilla.org/docs/Web/API/WebSocket/send) for the original
|
|
122
146
|
* `WebSocket.send()` docs.
|
|
123
147
|
*/
|
|
124
|
-
send(...args: OriginalWebSocketDefinition extends NoParam ? [message?: any] : GetWebSocketMessageTypeFromLocation<Exclude<OriginalWebSocketDefinition
|
|
125
|
-
message?: GetWebSocketMessageTypeFromLocation<Exclude<OriginalWebSocketDefinition
|
|
148
|
+
send(...args: NarrowOriginalDefinition<OriginalWebSocketDefinition> extends NoParam ? [message?: any] : GetWebSocketMessageTypeFromLocation<Exclude<NarrowOriginalDefinition<OriginalWebSocketDefinition>, NoParam>, Location> extends undefined ? [
|
|
149
|
+
message?: GetWebSocketMessageTypeFromLocation<Exclude<NarrowOriginalDefinition<OriginalWebSocketDefinition>, NoParam>, Location>
|
|
126
150
|
] : [
|
|
127
|
-
message: GetWebSocketMessageTypeFromLocation<Exclude<OriginalWebSocketDefinition
|
|
151
|
+
message: GetWebSocketMessageTypeFromLocation<Exclude<NarrowOriginalDefinition<OriginalWebSocketDefinition>, NoParam>, Location>
|
|
128
152
|
]): void;
|
|
129
153
|
}>;
|
|
130
154
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { waitUntil } from '@augment-vir/assert';
|
|
2
|
-
import { callAsynchronously, DeferredPromise, ensureErrorAndPrependMessage, getOrSet, stringify, } from '@augment-vir/common';
|
|
2
|
+
import { callAsynchronously, DeferredPromise, ensureErrorAndPrependMessage, getOrSet, stringify, wrapInTry, } from '@augment-vir/common';
|
|
3
3
|
import { convertDuration } from 'date-vir';
|
|
4
4
|
import { assertValidShape } from 'object-shape-tester';
|
|
5
5
|
import { parseJsonWithUndefined } from '../augments/json.js';
|
|
@@ -103,11 +103,16 @@ export function overwriteWebSocketMethods(webSocketDefinition, rawWebSocket, web
|
|
|
103
103
|
originalRemoveEventListener.call(webSocket, eventName, existing);
|
|
104
104
|
}
|
|
105
105
|
},
|
|
106
|
-
async sendAndWaitForReply({ message, timeout = { seconds: 10 }, } = {}) {
|
|
106
|
+
async sendAndWaitForReply({ message, timeout = { seconds: 10 }, replyCheck, } = {}) {
|
|
107
107
|
const deferredReply = new DeferredPromise();
|
|
108
|
-
function listener({ message, }) {
|
|
108
|
+
async function listener({ message, }) {
|
|
109
109
|
if (!deferredReply.isSettled) {
|
|
110
|
-
|
|
110
|
+
const matchesChecker = replyCheck
|
|
111
|
+
? (await wrapInTry(() => replyCheck(message))) === true
|
|
112
|
+
: true;
|
|
113
|
+
if (matchesChecker) {
|
|
114
|
+
deferredReply.resolve(message);
|
|
115
|
+
}
|
|
111
116
|
}
|
|
112
117
|
}
|
|
113
118
|
setTimeout(() => {
|