@holochain/client 0.19.0-dev.0 → 0.19.0-dev.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/README.md +3 -2
- package/lib/api/admin/types.d.ts +1 -0
- package/lib/api/app/websocket.d.ts +1 -1
- package/lib/api/app/websocket.js +9 -32
- package/lib/api/client.d.ts +8 -5
- package/lib/api/client.js +129 -84
- package/lib/api/common.js +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -179,8 +179,9 @@ You need `holochain` and `hc` on your path, best to get them from nix with `nix-
|
|
|
179
179
|
|
|
180
180
|
To perform the pre-requisite DNA compilation steps, and run the Nodejs test, run:
|
|
181
181
|
```bash
|
|
182
|
-
nix
|
|
183
|
-
./
|
|
182
|
+
nix develop
|
|
183
|
+
./build-fixture.sh
|
|
184
|
+
npm run test
|
|
184
185
|
```
|
|
185
186
|
|
|
186
187
|
## Contribute
|
package/lib/api/admin/types.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare class AppWebsocket implements AppClient {
|
|
|
16
16
|
private readonly defaultTimeout;
|
|
17
17
|
private readonly emitter;
|
|
18
18
|
private readonly callZomeTransform;
|
|
19
|
+
private readonly appAuthenticationToken;
|
|
19
20
|
cachedAppInfo?: AppInfo | null;
|
|
20
21
|
private readonly appInfoRequester;
|
|
21
22
|
private readonly callZomeRequester;
|
|
@@ -103,7 +104,6 @@ export declare class AppWebsocket implements AppClient {
|
|
|
103
104
|
*/
|
|
104
105
|
on<Name extends keyof AppEvents>(eventName: Name | readonly Name[], listener: SignalCb): UnsubscribeFunction;
|
|
105
106
|
private static requester;
|
|
106
|
-
private containsCell;
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
109
|
* @public
|
package/lib/api/app/websocket.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Emittery from "emittery";
|
|
2
2
|
import { omit } from "lodash-es";
|
|
3
|
-
import { CellType } from "../admin/index.js";
|
|
3
|
+
import { CellType, } from "../admin/index.js";
|
|
4
4
|
import { catchError, DEFAULT_TIMEOUT, getBaseRoleNameFromCloneId, HolochainError, isCloneId, promiseTimeout, requesterTransformer, } from "../common.js";
|
|
5
5
|
import { getHostZomeCallSigner, getLauncherEnvironment, } from "../../environments/launcher.js";
|
|
6
6
|
import { decode, encode } from "@msgpack/msgpack";
|
|
@@ -22,6 +22,7 @@ export class AppWebsocket {
|
|
|
22
22
|
defaultTimeout;
|
|
23
23
|
emitter;
|
|
24
24
|
callZomeTransform;
|
|
25
|
+
appAuthenticationToken;
|
|
25
26
|
cachedAppInfo;
|
|
26
27
|
appInfoRequester;
|
|
27
28
|
callZomeRequester;
|
|
@@ -31,12 +32,13 @@ export class AppWebsocket {
|
|
|
31
32
|
enableCloneCellRequester;
|
|
32
33
|
disableCloneCellRequester;
|
|
33
34
|
networkInfoRequester;
|
|
34
|
-
constructor(client, appInfo, callZomeTransform, defaultTimeout) {
|
|
35
|
+
constructor(client, appInfo, token, callZomeTransform, defaultTimeout) {
|
|
35
36
|
this.client = client;
|
|
36
37
|
this.myPubKey = appInfo.agent_pub_key;
|
|
37
38
|
this.installedAppId = appInfo.installed_app_id;
|
|
38
39
|
this.defaultTimeout = defaultTimeout ?? DEFAULT_TIMEOUT;
|
|
39
40
|
this.callZomeTransform = callZomeTransform ?? defaultCallZomeTransform;
|
|
41
|
+
this.appAuthenticationToken = token;
|
|
40
42
|
this.emitter = new Emittery();
|
|
41
43
|
this.cachedAppInfo = appInfo;
|
|
42
44
|
this.appInfoRequester = AppWebsocket.requester(this.client, "app_info", this.defaultTimeout);
|
|
@@ -77,21 +79,15 @@ export class AppWebsocket {
|
|
|
77
79
|
throw new HolochainError("ConnectionUrlMissing", `unable to connect to Conductor API - no url provided and not in a launcher environment.`);
|
|
78
80
|
}
|
|
79
81
|
const client = await WsClient.connect(options.url, options.wsClientOptions);
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
if (!options.token) {
|
|
86
|
-
throw new HolochainError("AppAuthenticationTokenMissing", `unable to connect to Conductor API - no app authentication token provided.`);
|
|
87
|
-
}
|
|
88
|
-
await client.authenticate({ token: options.token });
|
|
89
|
-
}
|
|
82
|
+
const token = options.token ?? env?.APP_INTERFACE_TOKEN;
|
|
83
|
+
if (!token)
|
|
84
|
+
throw new HolochainError("AppAuthenticationTokenMissing", `unable to connect to Conductor API - no app authentication token provided.`);
|
|
85
|
+
await client.authenticate({ token });
|
|
90
86
|
const appInfo = await AppWebsocket.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
|
|
91
87
|
if (!appInfo) {
|
|
92
88
|
throw new HolochainError("AppNotFound", `The app your connection token was issued for was not found. The app needs to be installed and enabled.`);
|
|
93
89
|
}
|
|
94
|
-
return new AppWebsocket(client, appInfo, options.callZomeTransform, options.defaultTimeout);
|
|
90
|
+
return new AppWebsocket(client, appInfo, token, options.callZomeTransform, options.defaultTimeout);
|
|
95
91
|
}
|
|
96
92
|
/**
|
|
97
93
|
* Request the app's info, including all cell infos.
|
|
@@ -237,25 +233,6 @@ export class AppWebsocket {
|
|
|
237
233
|
static requester(client, tag, defaultTimeout, transformer) {
|
|
238
234
|
return requesterTransformer((req, timeout) => promiseTimeout(client.request(req), tag, timeout || defaultTimeout).then(catchError), tag, transformer);
|
|
239
235
|
}
|
|
240
|
-
containsCell(cellId) {
|
|
241
|
-
const appInfo = this.cachedAppInfo;
|
|
242
|
-
if (!appInfo) {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
for (const roleName of Object.keys(appInfo.cell_info)) {
|
|
246
|
-
for (const cellInfo of appInfo.cell_info[roleName]) {
|
|
247
|
-
const currentCellId = CellType.Provisioned in cellInfo
|
|
248
|
-
? cellInfo[CellType.Provisioned].cell_id
|
|
249
|
-
: CellType.Cloned in cellInfo
|
|
250
|
-
? cellInfo[CellType.Cloned].cell_id
|
|
251
|
-
: undefined;
|
|
252
|
-
if (currentCellId && isSameCell(currentCellId, cellId)) {
|
|
253
|
-
return true;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return false;
|
|
258
|
-
}
|
|
259
236
|
}
|
|
260
237
|
const defaultCallZomeTransform = {
|
|
261
238
|
input: async (request) => {
|
package/lib/api/client.d.ts
CHANGED
|
@@ -23,8 +23,8 @@ export declare class WsClient extends Emittery {
|
|
|
23
23
|
options: WsClientOptions;
|
|
24
24
|
private pendingRequests;
|
|
25
25
|
private index;
|
|
26
|
+
private authenticationToken;
|
|
26
27
|
constructor(socket: IsoWebSocket, url?: URL, options?: WsClientOptions);
|
|
27
|
-
private setupSocket;
|
|
28
28
|
/**
|
|
29
29
|
* Instance factory for creating WsClients.
|
|
30
30
|
*
|
|
@@ -47,6 +47,10 @@ export declare class WsClient extends Emittery {
|
|
|
47
47
|
* @param request - The authentication request, containing an app authentication token.
|
|
48
48
|
*/
|
|
49
49
|
authenticate(request: AppAuthenticationRequest): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Close the websocket connection.
|
|
52
|
+
*/
|
|
53
|
+
close(code?: number): Promise<IsoWebSocket.CloseEvent>;
|
|
50
54
|
/**
|
|
51
55
|
* Send requests to the connected websocket.
|
|
52
56
|
*
|
|
@@ -56,10 +60,9 @@ export declare class WsClient extends Emittery {
|
|
|
56
60
|
request<Response>(request: unknown): Promise<Response>;
|
|
57
61
|
private exchange;
|
|
58
62
|
private sendMessage;
|
|
63
|
+
private registerMessageListener;
|
|
64
|
+
private registerCloseListener;
|
|
65
|
+
private reconnectWebsocket;
|
|
59
66
|
private handleResponse;
|
|
60
|
-
/**
|
|
61
|
-
* Close the websocket connection.
|
|
62
|
-
*/
|
|
63
|
-
close(code?: number): Promise<CloseEvent>;
|
|
64
67
|
}
|
|
65
68
|
export { IsoWebSocket };
|
package/lib/api/client.js
CHANGED
|
@@ -17,74 +17,16 @@ export class WsClient extends Emittery {
|
|
|
17
17
|
options;
|
|
18
18
|
pendingRequests;
|
|
19
19
|
index;
|
|
20
|
+
authenticationToken;
|
|
20
21
|
constructor(socket, url, options) {
|
|
21
22
|
super();
|
|
23
|
+
this.registerMessageListener(socket);
|
|
24
|
+
this.registerCloseListener(socket);
|
|
22
25
|
this.socket = socket;
|
|
23
26
|
this.url = url;
|
|
24
27
|
this.options = options || {};
|
|
25
28
|
this.pendingRequests = {};
|
|
26
29
|
this.index = 0;
|
|
27
|
-
this.setupSocket();
|
|
28
|
-
}
|
|
29
|
-
setupSocket() {
|
|
30
|
-
this.socket.onmessage = async (serializedMessage) => {
|
|
31
|
-
// If data is not a buffer (nodejs), it will be a blob (browser)
|
|
32
|
-
let deserializedData;
|
|
33
|
-
if (globalThis.window &&
|
|
34
|
-
serializedMessage.data instanceof globalThis.window.Blob) {
|
|
35
|
-
deserializedData = await serializedMessage.data.arrayBuffer();
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
if (typeof Buffer !== "undefined" &&
|
|
39
|
-
Buffer.isBuffer(serializedMessage.data)) {
|
|
40
|
-
deserializedData = serializedMessage.data;
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format - ${deserializedData}`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
const message = decode(deserializedData);
|
|
47
|
-
assertHolochainMessage(message);
|
|
48
|
-
if (message.type === "signal") {
|
|
49
|
-
if (message.data === null) {
|
|
50
|
-
throw new HolochainError("UnknownSignalFormat", "incoming signal has no data");
|
|
51
|
-
}
|
|
52
|
-
const deserializedSignal = decode(message.data);
|
|
53
|
-
assertHolochainSignal(deserializedSignal);
|
|
54
|
-
if (SignalType.System in deserializedSignal) {
|
|
55
|
-
this.emit("signal", {
|
|
56
|
-
System: deserializedSignal[SignalType.System],
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
const encodedAppSignal = deserializedSignal[SignalType.App];
|
|
61
|
-
// In order to return readable content to the UI, the signal payload must also be deserialized.
|
|
62
|
-
const payload = decode(encodedAppSignal.signal);
|
|
63
|
-
const signal = {
|
|
64
|
-
cell_id: encodedAppSignal.cell_id,
|
|
65
|
-
zome_name: encodedAppSignal.zome_name,
|
|
66
|
-
payload,
|
|
67
|
-
};
|
|
68
|
-
this.emit("signal", { App: signal });
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
else if (message.type === "response") {
|
|
72
|
-
this.handleResponse(message);
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
throw new HolochainError("UnknownMessageType", `incoming message has unknown type - ${message.type}`);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
this.socket.onclose = (event) => {
|
|
79
|
-
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id));
|
|
80
|
-
if (pendingRequestIds.length) {
|
|
81
|
-
pendingRequestIds.forEach((id) => {
|
|
82
|
-
const error = new HolochainError("ClientClosedWithPendingRequests", `client closed with pending requests - close event code: ${event.code}, request id: ${id}`);
|
|
83
|
-
this.pendingRequests[id].reject(error);
|
|
84
|
-
delete this.pendingRequests[id];
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
30
|
}
|
|
89
31
|
/**
|
|
90
32
|
* Instance factory for creating WsClients.
|
|
@@ -96,13 +38,13 @@ export class WsClient extends Emittery {
|
|
|
96
38
|
static connect(url, options) {
|
|
97
39
|
return new Promise((resolve, reject) => {
|
|
98
40
|
const socket = new IsoWebSocket(url, options);
|
|
99
|
-
socket.
|
|
41
|
+
socket.addEventListener("error", (errorEvent) => {
|
|
100
42
|
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url} - ${errorEvent.error}`));
|
|
101
|
-
};
|
|
102
|
-
socket.
|
|
43
|
+
});
|
|
44
|
+
socket.addEventListener("open", (_) => {
|
|
103
45
|
const client = new WsClient(socket, url, options);
|
|
104
46
|
resolve(client);
|
|
105
|
-
};
|
|
47
|
+
}, { once: true });
|
|
106
48
|
});
|
|
107
49
|
}
|
|
108
50
|
/**
|
|
@@ -125,16 +67,35 @@ export class WsClient extends Emittery {
|
|
|
125
67
|
* @param request - The authentication request, containing an app authentication token.
|
|
126
68
|
*/
|
|
127
69
|
async authenticate(request) {
|
|
128
|
-
|
|
70
|
+
this.authenticationToken = request.token;
|
|
71
|
+
return this.exchange(request, (request, resolve, reject) => {
|
|
72
|
+
const invalidTokenCloseListener = (closeEvent) => {
|
|
73
|
+
this.authenticationToken = undefined;
|
|
74
|
+
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
75
|
+
};
|
|
76
|
+
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
77
|
+
once: true,
|
|
78
|
+
});
|
|
129
79
|
const encodedMsg = encode({
|
|
130
80
|
type: "authenticate",
|
|
131
81
|
data: encode(request),
|
|
132
82
|
});
|
|
133
83
|
this.socket.send(encodedMsg);
|
|
134
|
-
//
|
|
135
|
-
|
|
84
|
+
// Wait before resolving in case authentication fails.
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
87
|
+
resolve(null);
|
|
88
|
+
}, 10);
|
|
136
89
|
});
|
|
137
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Close the websocket connection.
|
|
93
|
+
*/
|
|
94
|
+
close(code = 1000) {
|
|
95
|
+
const closedPromise = new Promise((resolve) => this.socket.addEventListener("close", (closeEvent) => resolve(closeEvent), { once: true }));
|
|
96
|
+
this.socket.close(code);
|
|
97
|
+
return closedPromise;
|
|
98
|
+
}
|
|
138
99
|
/**
|
|
139
100
|
* Send requests to the connected websocket.
|
|
140
101
|
*
|
|
@@ -144,15 +105,22 @@ export class WsClient extends Emittery {
|
|
|
144
105
|
async request(request) {
|
|
145
106
|
return this.exchange(request, this.sendMessage.bind(this));
|
|
146
107
|
}
|
|
147
|
-
exchange(request, sendHandler) {
|
|
108
|
+
async exchange(request, sendHandler) {
|
|
148
109
|
if (this.socket.readyState === this.socket.OPEN) {
|
|
149
110
|
const promise = new Promise((resolve, reject) => {
|
|
150
111
|
sendHandler(request, resolve, reject);
|
|
151
112
|
});
|
|
152
113
|
return promise;
|
|
153
114
|
}
|
|
115
|
+
else if (this.url && this.authenticationToken) {
|
|
116
|
+
await this.reconnectWebsocket(this.url, this.authenticationToken);
|
|
117
|
+
this.registerMessageListener(this.socket);
|
|
118
|
+
this.registerCloseListener(this.socket);
|
|
119
|
+
const promise = new Promise((resolve, reject) => sendHandler(request, resolve, reject));
|
|
120
|
+
return promise;
|
|
121
|
+
}
|
|
154
122
|
else {
|
|
155
|
-
return Promise.reject(new
|
|
123
|
+
return Promise.reject(new HolochainError("WebsocketClosedError", "Websocket is not open"));
|
|
156
124
|
}
|
|
157
125
|
}
|
|
158
126
|
sendMessage(request, resolve, reject) {
|
|
@@ -166,6 +134,97 @@ export class WsClient extends Emittery {
|
|
|
166
134
|
this.pendingRequests[id] = { resolve, reject };
|
|
167
135
|
this.index += 1;
|
|
168
136
|
}
|
|
137
|
+
registerMessageListener(socket) {
|
|
138
|
+
socket.onmessage = async (serializedMessage) => {
|
|
139
|
+
// If data is not a buffer (nodejs), it will be a blob (browser)
|
|
140
|
+
let deserializedData;
|
|
141
|
+
if (globalThis.window &&
|
|
142
|
+
serializedMessage.data instanceof globalThis.window.Blob) {
|
|
143
|
+
deserializedData = await serializedMessage.data.arrayBuffer();
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
if (typeof Buffer !== "undefined" &&
|
|
147
|
+
Buffer.isBuffer(serializedMessage.data)) {
|
|
148
|
+
deserializedData = serializedMessage.data;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format - ${deserializedData}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const message = decode(deserializedData);
|
|
155
|
+
assertHolochainMessage(message);
|
|
156
|
+
if (message.type === "signal") {
|
|
157
|
+
if (message.data === null) {
|
|
158
|
+
throw new HolochainError("UnknownSignalFormat", "incoming signal has no data");
|
|
159
|
+
}
|
|
160
|
+
const deserializedSignal = decode(message.data);
|
|
161
|
+
assertHolochainSignal(deserializedSignal);
|
|
162
|
+
if (SignalType.System in deserializedSignal) {
|
|
163
|
+
this.emit("signal", {
|
|
164
|
+
System: deserializedSignal[SignalType.System],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const encodedAppSignal = deserializedSignal[SignalType.App];
|
|
169
|
+
// In order to return readable content to the UI, the signal payload must also be deserialized.
|
|
170
|
+
const payload = decode(encodedAppSignal.signal);
|
|
171
|
+
const signal = {
|
|
172
|
+
cell_id: encodedAppSignal.cell_id,
|
|
173
|
+
zome_name: encodedAppSignal.zome_name,
|
|
174
|
+
payload,
|
|
175
|
+
};
|
|
176
|
+
this.emit("signal", { App: signal });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else if (message.type === "response") {
|
|
180
|
+
this.handleResponse(message);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
throw new HolochainError("UnknownMessageType", `incoming message has unknown type - ${message.type}`);
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
registerCloseListener(socket) {
|
|
188
|
+
socket.addEventListener("close", (closeEvent) => {
|
|
189
|
+
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id));
|
|
190
|
+
if (pendingRequestIds.length) {
|
|
191
|
+
pendingRequestIds.forEach((id) => {
|
|
192
|
+
const error = new HolochainError("ClientClosedWithPendingRequests", `client closed with pending requests - close event code: ${closeEvent.code}, request id: ${id}`);
|
|
193
|
+
this.pendingRequests[id].reject(error);
|
|
194
|
+
delete this.pendingRequests[id];
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}, { once: true });
|
|
198
|
+
}
|
|
199
|
+
async reconnectWebsocket(url, token) {
|
|
200
|
+
return new Promise((resolve, reject) => {
|
|
201
|
+
this.socket = new IsoWebSocket(url, this.options);
|
|
202
|
+
// This error event never occurs in tests. Could be removed?
|
|
203
|
+
this.socket.addEventListener("error", (errorEvent) => {
|
|
204
|
+
this.authenticationToken = undefined;
|
|
205
|
+
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url} - ${errorEvent.message}`));
|
|
206
|
+
}, { once: true });
|
|
207
|
+
const invalidTokenCloseListener = (closeEvent) => {
|
|
208
|
+
this.authenticationToken = undefined;
|
|
209
|
+
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
210
|
+
};
|
|
211
|
+
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
212
|
+
once: true,
|
|
213
|
+
});
|
|
214
|
+
this.socket.addEventListener("open", async (_) => {
|
|
215
|
+
const encodedMsg = encode({
|
|
216
|
+
type: "authenticate",
|
|
217
|
+
data: encode({ token }),
|
|
218
|
+
});
|
|
219
|
+
this.socket.send(encodedMsg);
|
|
220
|
+
// Wait in case authentication fails.
|
|
221
|
+
setTimeout(() => {
|
|
222
|
+
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
223
|
+
resolve();
|
|
224
|
+
}, 10);
|
|
225
|
+
}, { once: true });
|
|
226
|
+
});
|
|
227
|
+
}
|
|
169
228
|
handleResponse(msg) {
|
|
170
229
|
const id = msg.id;
|
|
171
230
|
if (this.pendingRequests[id]) {
|
|
@@ -181,20 +240,6 @@ export class WsClient extends Emittery {
|
|
|
181
240
|
console.error(`got response with no matching request. id = ${id} msg = ${msg}`);
|
|
182
241
|
}
|
|
183
242
|
}
|
|
184
|
-
/**
|
|
185
|
-
* Close the websocket connection.
|
|
186
|
-
*/
|
|
187
|
-
close(code = 1000) {
|
|
188
|
-
const closedPromise = new Promise((resolve) =>
|
|
189
|
-
// for an unknown reason "addEventListener" is seen as a non-callable
|
|
190
|
-
// property and gives a ts2349 error
|
|
191
|
-
// type assertion as workaround
|
|
192
|
-
this.socket.addEventListener("close", (event) => resolve(event))
|
|
193
|
-
// }
|
|
194
|
-
);
|
|
195
|
-
this.socket.close(code);
|
|
196
|
-
return closedPromise;
|
|
197
|
-
}
|
|
198
243
|
}
|
|
199
244
|
function assertHolochainMessage(message) {
|
|
200
245
|
if (typeof message === "object" &&
|
package/lib/api/common.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holochain/client",
|
|
3
|
-
"version": "0.19.0-dev.
|
|
3
|
+
"version": "0.19.0-dev.1",
|
|
4
4
|
"description": "A JavaScript client for the Holochain Conductor API",
|
|
5
5
|
"author": "Holochain Foundation <info@holochain.org> (https://holochain.org)",
|
|
6
6
|
"license": "CAL-1.0",
|
|
@@ -72,4 +72,4 @@
|
|
|
72
72
|
"tsx": "^4.7.2",
|
|
73
73
|
"typescript": "^4.9.5"
|
|
74
74
|
}
|
|
75
|
-
}
|
|
75
|
+
}
|