@holochain/hc-spin 0.400.0-dev.3 → 0.400.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.
- package/CHANGELOG.md +13 -0
- package/README.md +8 -15
- package/dist/main/index.js +171 -117
- package/package.json +4 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
4
|
+
|
|
5
|
+
## \[Unreleased\]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
### Removed
|
package/README.md
CHANGED
|
@@ -4,31 +4,23 @@ CLI to run Holochain apps in development mode.
|
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
To install the latest version compatible with **holochain 0.
|
|
8
|
-
|
|
9
|
-
⚠️ Requires `@holochain/client 0.12.6` or newer ⚠️
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
npm install --save-dev @holochain/hc-spin@">=0.100.0 <0.200.0"
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
To install the latest version compatible with **holochain 0.2.x**:
|
|
7
|
+
To install the latest version compatible with **holochain 0.3.x**:
|
|
16
8
|
|
|
17
|
-
⚠️ Requires `@holochain/client 0.
|
|
9
|
+
⚠️ Requires `@holochain/client 0.17.0-dev.5` or newer ⚠️
|
|
18
10
|
|
|
19
11
|
```
|
|
20
|
-
npm install --save-dev @holochain/hc-spin@">=0.
|
|
12
|
+
npm install --save-dev @holochain/hc-spin@">=0.300.0 <0.400.0"
|
|
21
13
|
```
|
|
22
14
|
|
|
23
|
-
To install the latest version compatible with **holochain 0.
|
|
15
|
+
To install the latest version compatible with **holochain 0.4.x**:
|
|
24
16
|
|
|
25
|
-
⚠️ Requires `@holochain/client 0.
|
|
17
|
+
⚠️ Requires `@holochain/client 0.18.0-rc.1` or newer ⚠️
|
|
26
18
|
|
|
27
19
|
```
|
|
28
|
-
npm install --save-dev @holochain/hc-spin@">=0.
|
|
20
|
+
npm install --save-dev @holochain/hc-spin@">=0.400.0 <0.500.0"
|
|
29
21
|
```
|
|
30
22
|
|
|
31
|
-
## Usage (holochain 0.
|
|
23
|
+
## Usage (holochain 0.4)
|
|
32
24
|
|
|
33
25
|
```
|
|
34
26
|
Usage: hc-spin [options] <path>
|
|
@@ -52,6 +44,7 @@ Options:
|
|
|
52
44
|
--ui-port <number> Port pointing to a localhost dev server that serves your UI assets.
|
|
53
45
|
--signaling-url <url> Url of the signaling server to use. By default, hc spin spins up a local development signaling server for you
|
|
54
46
|
but this argument allows you to specify a custom one.
|
|
47
|
+
--open-devtools Automatically open the devtools on startup.
|
|
55
48
|
-h, --help display help for command
|
|
56
49
|
```
|
|
57
50
|
|
package/dist/main/index.js
CHANGED
|
@@ -786,18 +786,18 @@ var CapAccessType;
|
|
|
786
786
|
CapAccessType2["Transferable"] = "Transferable";
|
|
787
787
|
CapAccessType2["Assigned"] = "Assigned";
|
|
788
788
|
})(CapAccessType || (CapAccessType = {}));
|
|
789
|
-
var
|
|
790
|
-
(function(
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
})(
|
|
789
|
+
var ChainOpType;
|
|
790
|
+
(function(ChainOpType2) {
|
|
791
|
+
ChainOpType2["StoreRecord"] = "StoreRecord";
|
|
792
|
+
ChainOpType2["StoreEntry"] = "StoreEntry";
|
|
793
|
+
ChainOpType2["RegisterAgentActivity"] = "RegisterAgentActivity";
|
|
794
|
+
ChainOpType2["RegisterUpdatedContent"] = "RegisterUpdatedContent";
|
|
795
|
+
ChainOpType2["RegisterUpdatedRecord"] = "RegisterUpdatedRecord";
|
|
796
|
+
ChainOpType2["RegisterDeletedBy"] = "RegisterDeletedBy";
|
|
797
|
+
ChainOpType2["RegisterDeletedEntryAction"] = "RegisterDeletedEntryAction";
|
|
798
|
+
ChainOpType2["RegisterAddLink"] = "RegisterAddLink";
|
|
799
|
+
ChainOpType2["RegisterRemoveLink"] = "RegisterRemoveLink";
|
|
800
|
+
})(ChainOpType || (ChainOpType = {}));
|
|
801
801
|
const anyMap = /* @__PURE__ */ new WeakMap();
|
|
802
802
|
const eventsMap = /* @__PURE__ */ new WeakMap();
|
|
803
803
|
const producersMap = /* @__PURE__ */ new WeakMap();
|
|
@@ -5026,6 +5026,7 @@ const promiseTimeout = (promise2, tag, ms) => {
|
|
|
5026
5026
|
clearTimeout(id);
|
|
5027
5027
|
return res(a);
|
|
5028
5028
|
}).catch((e) => {
|
|
5029
|
+
clearTimeout(id);
|
|
5029
5030
|
return rej(e);
|
|
5030
5031
|
}));
|
|
5031
5032
|
};
|
|
@@ -12333,23 +12334,33 @@ b2wasm.ready(function(err) {
|
|
|
12333
12334
|
class AppWebsocket {
|
|
12334
12335
|
client;
|
|
12335
12336
|
myPubKey;
|
|
12337
|
+
installedAppId;
|
|
12336
12338
|
defaultTimeout;
|
|
12337
12339
|
emitter;
|
|
12340
|
+
callZomeTransform;
|
|
12341
|
+
appAuthenticationToken;
|
|
12338
12342
|
cachedAppInfo;
|
|
12339
12343
|
appInfoRequester;
|
|
12340
12344
|
callZomeRequester;
|
|
12345
|
+
provideMemproofRequester;
|
|
12346
|
+
enableAppRequester;
|
|
12341
12347
|
createCloneCellRequester;
|
|
12342
12348
|
enableCloneCellRequester;
|
|
12343
12349
|
disableCloneCellRequester;
|
|
12344
12350
|
networkInfoRequester;
|
|
12345
|
-
constructor(client, appInfo, defaultTimeout) {
|
|
12351
|
+
constructor(client, appInfo, token, callZomeTransform, defaultTimeout) {
|
|
12346
12352
|
this.client = client;
|
|
12347
12353
|
this.myPubKey = appInfo.agent_pub_key;
|
|
12354
|
+
this.installedAppId = appInfo.installed_app_id;
|
|
12348
12355
|
this.defaultTimeout = defaultTimeout ?? DEFAULT_TIMEOUT;
|
|
12356
|
+
this.callZomeTransform = callZomeTransform ?? defaultCallZomeTransform;
|
|
12357
|
+
this.appAuthenticationToken = token;
|
|
12349
12358
|
this.emitter = new Emittery();
|
|
12350
12359
|
this.cachedAppInfo = appInfo;
|
|
12351
12360
|
this.appInfoRequester = AppWebsocket.requester(this.client, "app_info", this.defaultTimeout);
|
|
12352
|
-
this.callZomeRequester = AppWebsocket.requester(this.client, "call_zome", this.defaultTimeout, callZomeTransform);
|
|
12361
|
+
this.callZomeRequester = AppWebsocket.requester(this.client, "call_zome", this.defaultTimeout, this.callZomeTransform);
|
|
12362
|
+
this.provideMemproofRequester = AppWebsocket.requester(this.client, "provide_memproofs", this.defaultTimeout);
|
|
12363
|
+
this.enableAppRequester = AppWebsocket.requester(this.client, "enable_app", this.defaultTimeout);
|
|
12353
12364
|
this.createCloneCellRequester = AppWebsocket.requester(this.client, "create_clone_cell", this.defaultTimeout);
|
|
12354
12365
|
this.enableCloneCellRequester = AppWebsocket.requester(this.client, "enable_clone_cell", this.defaultTimeout);
|
|
12355
12366
|
this.disableCloneCellRequester = AppWebsocket.requester(this.client, "disable_clone_cell", this.defaultTimeout);
|
|
@@ -12361,9 +12372,7 @@ class AppWebsocket {
|
|
|
12361
12372
|
}
|
|
12362
12373
|
});
|
|
12363
12374
|
this.client.on("signal", (signal) => {
|
|
12364
|
-
|
|
12365
|
-
this.emitter.emit("signal", signal).catch(console.error);
|
|
12366
|
-
}
|
|
12375
|
+
this.emitter.emit("signal", signal).catch(console.error);
|
|
12367
12376
|
});
|
|
12368
12377
|
}
|
|
12369
12378
|
/**
|
|
@@ -12382,19 +12391,15 @@ class AppWebsocket {
|
|
|
12382
12391
|
throw new HolochainError("ConnectionUrlMissing", `unable to connect to Conductor API - no url provided and not in a launcher environment.`);
|
|
12383
12392
|
}
|
|
12384
12393
|
const client = await WsClient.connect(options.url, options.wsClientOptions);
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
}
|
|
12391
|
-
await client.authenticate({ token: options.token });
|
|
12392
|
-
}
|
|
12393
|
-
const appInfo = await this.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
|
|
12394
|
+
const token = options.token ?? env?.APP_INTERFACE_TOKEN;
|
|
12395
|
+
if (!token)
|
|
12396
|
+
throw new HolochainError("AppAuthenticationTokenMissing", `unable to connect to Conductor API - no app authentication token provided.`);
|
|
12397
|
+
await client.authenticate({ token });
|
|
12398
|
+
const appInfo = await AppWebsocket.requester(client, "app_info", DEFAULT_TIMEOUT)(null);
|
|
12394
12399
|
if (!appInfo) {
|
|
12395
12400
|
throw new HolochainError("AppNotFound", `The app your connection token was issued for was not found. The app needs to be installed and enabled.`);
|
|
12396
12401
|
}
|
|
12397
|
-
return new AppWebsocket(client, appInfo, options.defaultTimeout);
|
|
12402
|
+
return new AppWebsocket(client, appInfo, token, options.callZomeTransform, options.defaultTimeout);
|
|
12398
12403
|
}
|
|
12399
12404
|
/**
|
|
12400
12405
|
* Request the app's info, including all cell infos.
|
|
@@ -12410,6 +12415,21 @@ class AppWebsocket {
|
|
|
12410
12415
|
this.cachedAppInfo = appInfo;
|
|
12411
12416
|
return appInfo;
|
|
12412
12417
|
}
|
|
12418
|
+
/**
|
|
12419
|
+
* Provide membrane proofs for the app.
|
|
12420
|
+
*
|
|
12421
|
+
* @param memproofs - A map of {@link MembraneProof}s.
|
|
12422
|
+
*/
|
|
12423
|
+
async provideMemproofs(memproofs) {
|
|
12424
|
+
await this.provideMemproofRequester(memproofs);
|
|
12425
|
+
}
|
|
12426
|
+
/**
|
|
12427
|
+
* Enablie an app only if the app is in the `AppStatus::Disabled(DisabledAppReason::NotStartedAfterProvidingMemproofs)`
|
|
12428
|
+
* state. Attempting to enable the app from other states (other than Running) will fail.
|
|
12429
|
+
*/
|
|
12430
|
+
async enableApp() {
|
|
12431
|
+
await this.enableAppRequester();
|
|
12432
|
+
}
|
|
12413
12433
|
/**
|
|
12414
12434
|
* Get a cell id by its role name or clone id.
|
|
12415
12435
|
*
|
|
@@ -12524,23 +12544,8 @@ class AppWebsocket {
|
|
|
12524
12544
|
static requester(client, tag, defaultTimeout, transformer) {
|
|
12525
12545
|
return requesterTransformer((req, timeout2) => promiseTimeout(client.request(req), tag, timeout2 || defaultTimeout).then(catchError), tag, transformer);
|
|
12526
12546
|
}
|
|
12527
|
-
containsCell(cellId) {
|
|
12528
|
-
const appInfo = this.cachedAppInfo;
|
|
12529
|
-
if (!appInfo) {
|
|
12530
|
-
return false;
|
|
12531
|
-
}
|
|
12532
|
-
for (const roleName of Object.keys(appInfo.cell_info)) {
|
|
12533
|
-
for (const cellInfo of appInfo.cell_info[roleName]) {
|
|
12534
|
-
const currentCellId = CellType.Provisioned in cellInfo ? cellInfo[CellType.Provisioned].cell_id : CellType.Cloned in cellInfo ? cellInfo[CellType.Cloned].cell_id : void 0;
|
|
12535
|
-
if (currentCellId && isSameCell(currentCellId, cellId)) {
|
|
12536
|
-
return true;
|
|
12537
|
-
}
|
|
12538
|
-
}
|
|
12539
|
-
}
|
|
12540
|
-
return false;
|
|
12541
|
-
}
|
|
12542
12547
|
}
|
|
12543
|
-
const
|
|
12548
|
+
const defaultCallZomeTransform = {
|
|
12544
12549
|
input: async (request) => {
|
|
12545
12550
|
if ("signature" in request) {
|
|
12546
12551
|
return request;
|
|
@@ -12554,7 +12559,6 @@ const callZomeTransform = {
|
|
|
12554
12559
|
},
|
|
12555
12560
|
output: (response) => msgpack.decode(response)
|
|
12556
12561
|
};
|
|
12557
|
-
const isSameCell = (cellId1, cellId2) => cellId1[0].every((byte, index) => byte === cellId2[0][index]) && cellId1[1].every((byte, index) => byte === cellId2[1][index]);
|
|
12558
12562
|
const signZomeCall = async (request) => {
|
|
12559
12563
|
const signingCredentialsForCell = getSigningCredentials(request.cell_id);
|
|
12560
12564
|
if (!signingCredentialsForCell) {
|
|
@@ -12586,62 +12590,16 @@ class WsClient extends Emittery {
|
|
|
12586
12590
|
options;
|
|
12587
12591
|
pendingRequests;
|
|
12588
12592
|
index;
|
|
12593
|
+
authenticationToken;
|
|
12589
12594
|
constructor(socket, url2, options) {
|
|
12590
12595
|
super();
|
|
12596
|
+
this.registerMessageListener(socket);
|
|
12597
|
+
this.registerCloseListener(socket);
|
|
12591
12598
|
this.socket = socket;
|
|
12592
12599
|
this.url = url2;
|
|
12593
12600
|
this.options = options || {};
|
|
12594
12601
|
this.pendingRequests = {};
|
|
12595
12602
|
this.index = 0;
|
|
12596
|
-
this.setupSocket();
|
|
12597
|
-
}
|
|
12598
|
-
setupSocket() {
|
|
12599
|
-
this.socket.onmessage = async (serializedMessage) => {
|
|
12600
|
-
let deserializedData;
|
|
12601
|
-
if (globalThis.window && serializedMessage.data instanceof globalThis.window.Blob) {
|
|
12602
|
-
deserializedData = await serializedMessage.data.arrayBuffer();
|
|
12603
|
-
} else {
|
|
12604
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(serializedMessage.data)) {
|
|
12605
|
-
deserializedData = serializedMessage.data;
|
|
12606
|
-
} else {
|
|
12607
|
-
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format - ${deserializedData}`);
|
|
12608
|
-
}
|
|
12609
|
-
}
|
|
12610
|
-
const message = msgpack.decode(deserializedData);
|
|
12611
|
-
assertHolochainMessage(message);
|
|
12612
|
-
if (message.type === "signal") {
|
|
12613
|
-
if (message.data === null) {
|
|
12614
|
-
throw new HolochainError("UnknownSignalFormat", "incoming signal has no data");
|
|
12615
|
-
}
|
|
12616
|
-
const deserializedSignal = msgpack.decode(message.data);
|
|
12617
|
-
assertHolochainSignal(deserializedSignal);
|
|
12618
|
-
if (SignalType.System in deserializedSignal) {
|
|
12619
|
-
return;
|
|
12620
|
-
}
|
|
12621
|
-
const encodedAppSignal = deserializedSignal[SignalType.App];
|
|
12622
|
-
const payload = msgpack.decode(encodedAppSignal.signal);
|
|
12623
|
-
const signal = {
|
|
12624
|
-
cell_id: encodedAppSignal.cell_id,
|
|
12625
|
-
zome_name: encodedAppSignal.zome_name,
|
|
12626
|
-
payload
|
|
12627
|
-
};
|
|
12628
|
-
this.emit("signal", signal);
|
|
12629
|
-
} else if (message.type === "response") {
|
|
12630
|
-
this.handleResponse(message);
|
|
12631
|
-
} else {
|
|
12632
|
-
throw new HolochainError("UnknownMessageType", `incoming message has unknown type - ${message.type}`);
|
|
12633
|
-
}
|
|
12634
|
-
};
|
|
12635
|
-
this.socket.onclose = (event) => {
|
|
12636
|
-
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id));
|
|
12637
|
-
if (pendingRequestIds.length) {
|
|
12638
|
-
pendingRequestIds.forEach((id) => {
|
|
12639
|
-
const error = new HolochainError("ClientClosedWithPendingRequests", `client closed with pending requests - close event code: ${event.code}, request id: ${id}`);
|
|
12640
|
-
this.pendingRequests[id].reject(error);
|
|
12641
|
-
delete this.pendingRequests[id];
|
|
12642
|
-
});
|
|
12643
|
-
}
|
|
12644
|
-
};
|
|
12645
12603
|
}
|
|
12646
12604
|
/**
|
|
12647
12605
|
* Instance factory for creating WsClients.
|
|
@@ -12653,13 +12611,13 @@ class WsClient extends Emittery {
|
|
|
12653
12611
|
static connect(url2, options) {
|
|
12654
12612
|
return new Promise((resolve, reject) => {
|
|
12655
12613
|
const socket = new IsoWebSocket(url2, options);
|
|
12656
|
-
socket.
|
|
12614
|
+
socket.addEventListener("error", (errorEvent) => {
|
|
12657
12615
|
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url2} - ${errorEvent.error}`));
|
|
12658
|
-
};
|
|
12659
|
-
socket.
|
|
12616
|
+
});
|
|
12617
|
+
socket.addEventListener("open", (_) => {
|
|
12660
12618
|
const client = new WsClient(socket, url2, options);
|
|
12661
12619
|
resolve(client);
|
|
12662
|
-
};
|
|
12620
|
+
}, { once: true });
|
|
12663
12621
|
});
|
|
12664
12622
|
}
|
|
12665
12623
|
/**
|
|
@@ -12682,15 +12640,34 @@ class WsClient extends Emittery {
|
|
|
12682
12640
|
* @param request - The authentication request, containing an app authentication token.
|
|
12683
12641
|
*/
|
|
12684
12642
|
async authenticate(request) {
|
|
12685
|
-
|
|
12643
|
+
this.authenticationToken = request.token;
|
|
12644
|
+
return this.exchange(request, (request2, resolve, reject) => {
|
|
12645
|
+
const invalidTokenCloseListener = (closeEvent) => {
|
|
12646
|
+
this.authenticationToken = void 0;
|
|
12647
|
+
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
12648
|
+
};
|
|
12649
|
+
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
12650
|
+
once: true
|
|
12651
|
+
});
|
|
12686
12652
|
const encodedMsg = msgpack.encode({
|
|
12687
12653
|
type: "authenticate",
|
|
12688
12654
|
data: msgpack.encode(request2)
|
|
12689
12655
|
});
|
|
12690
12656
|
this.socket.send(encodedMsg);
|
|
12691
|
-
|
|
12657
|
+
setTimeout(() => {
|
|
12658
|
+
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
12659
|
+
resolve(null);
|
|
12660
|
+
}, 10);
|
|
12692
12661
|
});
|
|
12693
12662
|
}
|
|
12663
|
+
/**
|
|
12664
|
+
* Close the websocket connection.
|
|
12665
|
+
*/
|
|
12666
|
+
close(code = 1e3) {
|
|
12667
|
+
const closedPromise = new Promise((resolve) => this.socket.addEventListener("close", (closeEvent) => resolve(closeEvent), { once: true }));
|
|
12668
|
+
this.socket.close(code);
|
|
12669
|
+
return closedPromise;
|
|
12670
|
+
}
|
|
12694
12671
|
/**
|
|
12695
12672
|
* Send requests to the connected websocket.
|
|
12696
12673
|
*
|
|
@@ -12700,14 +12677,20 @@ class WsClient extends Emittery {
|
|
|
12700
12677
|
async request(request) {
|
|
12701
12678
|
return this.exchange(request, this.sendMessage.bind(this));
|
|
12702
12679
|
}
|
|
12703
|
-
exchange(request, sendHandler) {
|
|
12680
|
+
async exchange(request, sendHandler) {
|
|
12704
12681
|
if (this.socket.readyState === this.socket.OPEN) {
|
|
12705
12682
|
const promise2 = new Promise((resolve, reject) => {
|
|
12706
12683
|
sendHandler(request, resolve, reject);
|
|
12707
12684
|
});
|
|
12708
12685
|
return promise2;
|
|
12686
|
+
} else if (this.url && this.authenticationToken) {
|
|
12687
|
+
await this.reconnectWebsocket(this.url, this.authenticationToken);
|
|
12688
|
+
this.registerMessageListener(this.socket);
|
|
12689
|
+
this.registerCloseListener(this.socket);
|
|
12690
|
+
const promise2 = new Promise((resolve, reject) => sendHandler(request, resolve, reject));
|
|
12691
|
+
return promise2;
|
|
12709
12692
|
} else {
|
|
12710
|
-
return Promise.reject(new
|
|
12693
|
+
return Promise.reject(new HolochainError("WebsocketClosedError", "Websocket is not open"));
|
|
12711
12694
|
}
|
|
12712
12695
|
}
|
|
12713
12696
|
sendMessage(request, resolve, reject) {
|
|
@@ -12721,6 +12704,86 @@ class WsClient extends Emittery {
|
|
|
12721
12704
|
this.pendingRequests[id] = { resolve, reject };
|
|
12722
12705
|
this.index += 1;
|
|
12723
12706
|
}
|
|
12707
|
+
registerMessageListener(socket) {
|
|
12708
|
+
socket.onmessage = async (serializedMessage) => {
|
|
12709
|
+
let deserializedData;
|
|
12710
|
+
if (globalThis.window && serializedMessage.data instanceof globalThis.window.Blob) {
|
|
12711
|
+
deserializedData = await serializedMessage.data.arrayBuffer();
|
|
12712
|
+
} else {
|
|
12713
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(serializedMessage.data)) {
|
|
12714
|
+
deserializedData = serializedMessage.data;
|
|
12715
|
+
} else {
|
|
12716
|
+
throw new HolochainError("UnknownMessageFormat", `incoming message has unknown message format - ${deserializedData}`);
|
|
12717
|
+
}
|
|
12718
|
+
}
|
|
12719
|
+
const message = msgpack.decode(deserializedData);
|
|
12720
|
+
assertHolochainMessage(message);
|
|
12721
|
+
if (message.type === "signal") {
|
|
12722
|
+
if (message.data === null) {
|
|
12723
|
+
throw new HolochainError("UnknownSignalFormat", "incoming signal has no data");
|
|
12724
|
+
}
|
|
12725
|
+
const deserializedSignal = msgpack.decode(message.data);
|
|
12726
|
+
assertHolochainSignal(deserializedSignal);
|
|
12727
|
+
if (SignalType.System in deserializedSignal) {
|
|
12728
|
+
this.emit("signal", {
|
|
12729
|
+
System: deserializedSignal[SignalType.System]
|
|
12730
|
+
});
|
|
12731
|
+
} else {
|
|
12732
|
+
const encodedAppSignal = deserializedSignal[SignalType.App];
|
|
12733
|
+
const payload = msgpack.decode(encodedAppSignal.signal);
|
|
12734
|
+
const signal = {
|
|
12735
|
+
cell_id: encodedAppSignal.cell_id,
|
|
12736
|
+
zome_name: encodedAppSignal.zome_name,
|
|
12737
|
+
payload
|
|
12738
|
+
};
|
|
12739
|
+
this.emit("signal", { App: signal });
|
|
12740
|
+
}
|
|
12741
|
+
} else if (message.type === "response") {
|
|
12742
|
+
this.handleResponse(message);
|
|
12743
|
+
} else {
|
|
12744
|
+
throw new HolochainError("UnknownMessageType", `incoming message has unknown type - ${message.type}`);
|
|
12745
|
+
}
|
|
12746
|
+
};
|
|
12747
|
+
}
|
|
12748
|
+
registerCloseListener(socket) {
|
|
12749
|
+
socket.addEventListener("close", (closeEvent) => {
|
|
12750
|
+
const pendingRequestIds = Object.keys(this.pendingRequests).map((id) => parseInt(id));
|
|
12751
|
+
if (pendingRequestIds.length) {
|
|
12752
|
+
pendingRequestIds.forEach((id) => {
|
|
12753
|
+
const error = new HolochainError("ClientClosedWithPendingRequests", `client closed with pending requests - close event code: ${closeEvent.code}, request id: ${id}`);
|
|
12754
|
+
this.pendingRequests[id].reject(error);
|
|
12755
|
+
delete this.pendingRequests[id];
|
|
12756
|
+
});
|
|
12757
|
+
}
|
|
12758
|
+
}, { once: true });
|
|
12759
|
+
}
|
|
12760
|
+
async reconnectWebsocket(url2, token) {
|
|
12761
|
+
return new Promise((resolve, reject) => {
|
|
12762
|
+
this.socket = new IsoWebSocket(url2, this.options);
|
|
12763
|
+
this.socket.addEventListener("error", (errorEvent) => {
|
|
12764
|
+
this.authenticationToken = void 0;
|
|
12765
|
+
reject(new HolochainError("ConnectionError", `could not connect to Holochain Conductor API at ${url2} - ${errorEvent.message}`));
|
|
12766
|
+
}, { once: true });
|
|
12767
|
+
const invalidTokenCloseListener = (closeEvent) => {
|
|
12768
|
+
this.authenticationToken = void 0;
|
|
12769
|
+
reject(new HolochainError("InvalidTokenError", `could not connect to ${this.url} due to an invalid app authentication token - close code ${closeEvent.code}`));
|
|
12770
|
+
};
|
|
12771
|
+
this.socket.addEventListener("close", invalidTokenCloseListener, {
|
|
12772
|
+
once: true
|
|
12773
|
+
});
|
|
12774
|
+
this.socket.addEventListener("open", async (_) => {
|
|
12775
|
+
const encodedMsg = msgpack.encode({
|
|
12776
|
+
type: "authenticate",
|
|
12777
|
+
data: msgpack.encode({ token })
|
|
12778
|
+
});
|
|
12779
|
+
this.socket.send(encodedMsg);
|
|
12780
|
+
setTimeout(() => {
|
|
12781
|
+
this.socket.removeEventListener("close", invalidTokenCloseListener);
|
|
12782
|
+
resolve();
|
|
12783
|
+
}, 10);
|
|
12784
|
+
}, { once: true });
|
|
12785
|
+
});
|
|
12786
|
+
}
|
|
12724
12787
|
handleResponse(msg) {
|
|
12725
12788
|
const id = msg.id;
|
|
12726
12789
|
if (this.pendingRequests[id]) {
|
|
@@ -12734,22 +12797,6 @@ class WsClient extends Emittery {
|
|
|
12734
12797
|
console.error(`got response with no matching request. id = ${id} msg = ${msg}`);
|
|
12735
12798
|
}
|
|
12736
12799
|
}
|
|
12737
|
-
/**
|
|
12738
|
-
* Close the websocket connection.
|
|
12739
|
-
*/
|
|
12740
|
-
close(code = 1e3) {
|
|
12741
|
-
const closedPromise = new Promise(
|
|
12742
|
-
(resolve) => (
|
|
12743
|
-
// for an unknown reason "addEventListener" is seen as a non-callable
|
|
12744
|
-
// property and gives a ts2349 error
|
|
12745
|
-
// type assertion as workaround
|
|
12746
|
-
this.socket.addEventListener("close", (event) => resolve(event))
|
|
12747
|
-
)
|
|
12748
|
-
// }
|
|
12749
|
-
);
|
|
12750
|
-
this.socket.close(code);
|
|
12751
|
-
return closedPromise;
|
|
12752
|
-
}
|
|
12753
12800
|
}
|
|
12754
12801
|
function assertHolochainMessage(message) {
|
|
12755
12802
|
if (typeof message === "object" && message !== null && "type" in message && "data" in message) {
|
|
@@ -12821,6 +12868,10 @@ class AdminWebsocket {
|
|
|
12821
12868
|
* Generate a new agent pub key.
|
|
12822
12869
|
*/
|
|
12823
12870
|
generateAgentPubKey = this._requester("generate_agent_pub_key");
|
|
12871
|
+
/**
|
|
12872
|
+
* Generate a new agent pub key.
|
|
12873
|
+
*/
|
|
12874
|
+
revokeAgentKey = this._requester("revoke_agent_key");
|
|
12824
12875
|
/**
|
|
12825
12876
|
* Register a DNA for later app installation.
|
|
12826
12877
|
*
|
|
@@ -12831,6 +12882,9 @@ class AdminWebsocket {
|
|
|
12831
12882
|
* Get the DNA definition for the specified DNA hash.
|
|
12832
12883
|
*/
|
|
12833
12884
|
getDnaDefinition = this._requester("get_dna_definition");
|
|
12885
|
+
/// Find installed cells which use a DNA that's forward-compatible with the given DNA hash.
|
|
12886
|
+
/// Namely, this finds cells with DNAs whose manifest lists the given DNA hash in its `lineage` field.
|
|
12887
|
+
getCompatibleCells = this._requester("get_compatible_cells");
|
|
12834
12888
|
/**
|
|
12835
12889
|
* Uninstall the specified app from Holochain.
|
|
12836
12890
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@holochain/hc-spin",
|
|
3
|
-
"version": "0.400.0
|
|
4
|
-
"holochainVersion": "0.4.0-
|
|
3
|
+
"version": "0.400.0",
|
|
4
|
+
"holochainVersion": "0.4.0-rc.2",
|
|
5
5
|
"description": "CLI to run Holochain aps during development.",
|
|
6
6
|
"author": "matthme",
|
|
7
7
|
"homepage": "https://developer.holochain.org",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@electron-toolkit/preload": "^3.0.0",
|
|
37
37
|
"@electron-toolkit/utils": "^3.0.0",
|
|
38
|
-
"@holochain/client": "0.18.0
|
|
39
|
-
"@holochain/hc-spin-rust-utils": "
|
|
38
|
+
"@holochain/client": "0.18.0",
|
|
39
|
+
"@holochain/hc-spin-rust-utils": "0.400.0",
|
|
40
40
|
"@msgpack/msgpack": "^2.8.0",
|
|
41
41
|
"bufferutil": "4.0.8",
|
|
42
42
|
"commander": "11.1.0",
|