@ddd-qc/cell-proxy 0.9.8 → 0.10.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.
@@ -1,297 +1,339 @@
1
- import { AppWebsocket, } from "@holochain/client";
2
- import { CellProxy } from "./CellProxy";
3
- import { CellIdStr, destructureRoleInstanceId } from "./types";
4
- import { prettyDate } from "./utils";
5
- import { HCL } from "./hcl";
6
- /**
7
- * Creates, connects and holds a appWebsocket.
8
- * Creates and holds Cell proxies for this appWebsocket.
9
- * Maintains a mapping between CellIds and HCLs
10
- * Handles SignalHandlers per HCL
11
- * Stores appSignal logs
12
- * TODO Implement Singleton per App port?
13
- */
14
- export class ConductorAppProxy {
15
- /** -- Getters -- */
16
- /** */
17
- getAppCells(appId) {
18
- return this._installedCellsByApp[appId];
19
- }
20
- /** */
21
- getLocations(cellId) {
22
- return this._hclMap[CellIdStr(cellId)];
23
- }
24
- /** */
25
- getCell(hcl) {
26
- const roleCellsMap = this._installedCellsByApp[hcl.appId];
27
- if (!roleCellsMap)
28
- throw Error(`getCell() failed. No hApp with ID "${hcl.appId}" found.`);
29
- const roleCells = roleCellsMap[hcl.baseRoleName];
30
- if (!roleCells)
31
- throw Error(`getCell() failed: BaseRoleName "${hcl.baseRoleName}" not found in happ "${hcl.appId}"`);
32
- let installedCell = roleCells.original;
33
- if (hcl.cloneName !== undefined) {
34
- installedCell = roleCells.clones[hcl.cloneName];
35
- if (!installedCell) {
36
- throw Error(`getCell() failed: clone "${hcl.cloneName}" not found for role "${hcl.appId}/${hcl.baseRoleName}"`);
37
- }
38
- }
39
- else {
40
- if (hcl.cloneIndex !== undefined) {
41
- installedCell = roleCells.clones[String(hcl.cloneIndex)];
42
- if (!installedCell) {
43
- throw Error(`getCell() failed: clone "${hcl.cloneIndex}" not found for role "${hcl.appId}/${hcl.baseRoleName}"`);
44
- }
45
- }
46
- }
47
- return installedCell;
48
- }
49
- /** Get stored CellProxy or attempt to create it */
50
- getCellProxy(cellIdOrLoc) {
51
- if (cellIdOrLoc instanceof HCL) {
52
- const installedCell = this.getCell(cellIdOrLoc);
53
- const maybeProxy = this.getCellProxy(installedCell.cell_id);
54
- if (!maybeProxy)
55
- throw Error("getCellProxy() failed. Proxy not found for cell " + CellIdStr(installedCell.cell_id));
56
- return maybeProxy;
57
- }
58
- const sId = CellIdStr(cellIdOrLoc);
59
- const maybeProxy = this._cellProxies[sId];
60
- if (maybeProxy === undefined)
61
- throw Error("getCellProxy() failed. Proxy not found for cell " + sId);
62
- return maybeProxy;
63
- }
64
- /** */
65
- getAppRoleInstanceIds(installedAppId) {
66
- if (!this._installedCellsByApp[installedAppId])
67
- return undefined;
68
- return Object.values(this._installedCellsByApp[installedAppId]).map((roleCells) => {
69
- return roleCells.original.role_id;
70
- });
71
- }
72
- /** */
73
- getClones(appId, baseRoleName) {
74
- const maybeApp = this._installedCellsByApp[appId];
75
- if (!maybeApp)
76
- return [];
77
- const roleInstalledCells = maybeApp[baseRoleName];
78
- if (!roleInstalledCells)
79
- return [];
80
- return Object.values(roleInstalledCells.clones);
81
- }
82
- /** -- AppApi (Passthrough to appWebsocket) -- */
83
- async createCloneCell(request) {
84
- //console.log("createCloneCell() called:", request)
85
- return this._appWs.createCloneCell(request);
86
- }
87
- async archiveCloneCell(request) {
88
- //console.log("archiveCloneCell() called:", request)
89
- this._appWs.archiveCloneCell(request);
90
- }
91
- async appInfo(args) {
92
- return this._appWs.appInfo(args);
93
- }
94
- async callZome(req, timeout) {
95
- timeout = timeout ? timeout : this.defaultTimeout;
96
- return this._appWs.callZome(req, timeout);
97
- }
98
- /** -- Creation -- */
99
- /** async Factory */
100
- static async new(port_or_socket, defaultTimeout) {
101
- if (typeof port_or_socket == 'object') {
102
- return ConductorAppProxy.fromSocket(port_or_socket);
103
- }
104
- else {
105
- const timeout = defaultTimeout ? defaultTimeout : 10 * 1000;
106
- let wsUrl = `ws://localhost:${port_or_socket}`;
107
- try {
108
- let conductor = new ConductorAppProxy(timeout);
109
- conductor._appWs = await AppWebsocket.connect(wsUrl, timeout, (sig) => { conductor.onSignal(sig); });
110
- return conductor;
111
- }
112
- catch (e) {
113
- console.error("ConductorAppProxy initialization failed", e);
114
- return Promise.reject("ConductorAppProxy initialization failed");
115
- }
116
- }
117
- }
118
- /** */
119
- static async fromSocket(appWebsocket) {
120
- try {
121
- let conductor = new ConductorAppProxy(appWebsocket.defaultTimeout);
122
- conductor._appWs = appWebsocket;
123
- console.warn("Using pre-existing AppWebsocket. ConductorAppProxy's 'onSignal()' SignalHandler needs to be set by the provider of the AppWebsocket.");
124
- return conductor;
125
- }
126
- catch (e) {
127
- console.error("ConductorAppProxy initialization failed", e);
128
- return Promise.reject("ConductorAppProxy initialization failed");
129
- }
130
- }
131
- /** Ctor */
132
- constructor(defaultTimeout) {
133
- this.defaultTimeout = defaultTimeout;
134
- /** [Timestamp, CellIdStr, Signal] */
135
- this._signalLogs = [];
136
- /** InstalledAppId -> (BaseRoleName -> RoleInstalledCells) */
137
- this._installedCellsByApp = {};
138
- /** CellIdStr -> HCL[] */
139
- this._hclMap = {};
140
- /** HCLString -> AppSignalCb */
141
- this._signalHandlers = {};
142
- /** CellIdStr -> CellProxy */
143
- this._cellProxies = {};
144
- const _unsub = this.addSignalHandler((sig) => this.logSignal(sig));
145
- }
146
- /** -- Methods -- */
147
- async fetchCells(appId, baseRoleName) {
148
- /** Make sure hApp exists */
149
- const installedAppInfo = await this.appInfo({ installed_app_id: appId });
150
- if (installedAppInfo == null) {
151
- Promise.reject(`fetchCells() failed. App "${appId}" not found on AppWebsocket "${this._appWs.client.socket.url}"`);
152
- }
153
- //console.log("fetchCells() installedAppInfo:\n", printAppInfo(installedAppInfo));
154
- /** Make sure app Object exists */
155
- if (!this._installedCellsByApp[appId]) {
156
- this._installedCellsByApp[appId] = {};
157
- }
158
- /** Get all cells with that baseRoleName */
159
- let original;
160
- let clones = {};
161
- for (const curCell of installedAppInfo.cell_data) {
162
- //console.log(`CreateCellProxy(): Found cell "${installedCell.role_id}":`, CellIdStr(installedCell.cell_id));
163
- const maybePair = destructureRoleInstanceId(curCell.role_id);
164
- const curBaseName = maybePair ? maybePair[0] : curCell.role_id;
165
- if (curBaseName !== baseRoleName) {
166
- continue;
167
- }
168
- if (maybePair) {
169
- if (clones["" + maybePair[1]]) {
170
- console.error(`fetchCells() Proxy already exist for clone: "${maybePair[0]}/${maybePair[1]}"`);
171
- }
172
- clones["" + maybePair[1]] = curCell;
173
- }
174
- else {
175
- original = curCell;
176
- }
177
- }
178
- if (!original) {
179
- Promise.reject("Original cell not found for role " + baseRoleName);
180
- }
181
- let roleInstalledCells = { original, clones };
182
- /** Store it*/
183
- this._installedCellsByApp[appId][baseRoleName] = roleInstalledCells;
184
- return roleInstalledCells;
185
- }
186
- /** */
187
- addClone(hcl, cloneCell) {
188
- if (!this._installedCellsByApp[hcl.appId])
189
- throw Error("addCloneInstalledCell() failed. no appId. " + hcl.toString());
190
- if (!this._installedCellsByApp[hcl.appId][hcl.baseRoleName])
191
- throw Error("addCloneInstalledCell() failed. no baseRoleName. " + hcl.toString());
192
- if (hcl.cloneName !== undefined) {
193
- this._installedCellsByApp[hcl.appId][hcl.baseRoleName].clones[hcl.cloneName] = cloneCell;
194
- return;
195
- }
196
- if (hcl.cloneIndex === undefined)
197
- throw Error("addCloneInstalledCell() failed. Missing cloneIndex " + hcl.toString());
198
- this._installedCellsByApp[hcl.appId][hcl.baseRoleName].clones[String(hcl.cloneIndex)] = cloneCell;
199
- // const sCellId = CellIdStr(cloneCell.cell_id);
200
- // console.log("CreateCellProxy() adding to hclMap", sCellId, cellLoc.asHcl())
201
- // if (this._hclMap[sCellId]) {
202
- // this._hclMap[sCellId].push(cellLoc.asHcl());
203
- // } else {
204
- // this._hclMap[sCellId] = [cellLoc.asHcl()];
205
- // }
206
- }
207
- /** */
208
- createCellProxy(hcl) {
209
- //console.log("createCellProxy() for", hcl.toString());
210
- /** Make sure cell exists */
211
- const installedCell = this.getCell(hcl);
212
- const sCellId = CellIdStr(installedCell.cell_id);
213
- /** Create proxy for this cell if none exist yet, otherwise reuse */
214
- let cellProxy = this._cellProxies[sCellId];
215
- if (!cellProxy) {
216
- /** Create and store Proxy */
217
- cellProxy = new CellProxy(this, installedCell, this.defaultTimeout);
218
- this._cellProxies[sCellId] = cellProxy;
219
- }
220
- /** Create CellId -> HCL mapping */
221
- //console.log("CreateCellProxy() adding to hclMap", sCellId, hcl.toString())
222
- if (this._hclMap[sCellId]) {
223
- this._hclMap[sCellId].push(hcl);
224
- }
225
- else {
226
- this._hclMap[sCellId] = [hcl];
227
- }
228
- //console.log("createCellProxy() Currently stored hclMap:", this._hclMap);
229
- /** Done */
230
- return cellProxy;
231
- }
232
- /** */
233
- onSignal(signal) {
234
- /** Grabe cell specific handlers */
235
- const hcls = this.getLocations(signal.data.cellId);
236
- const handlers = hcls ? hcls.map((hcl) => this._signalHandlers[hcl.toString()]) : [];
237
- /** Grab common handler */
238
- const allHandler = this._signalHandlers["__all"];
239
- if (allHandler)
240
- handlers.push(allHandler);
241
- /** Send to all handlers */
242
- for (const handler of handlers) {
243
- handler(signal);
244
- }
245
- }
246
- /** Store signalHandler to internal handler array */
247
- addSignalHandler(handler, hcl) {
248
- hcl = hcl ? hcl : "__all";
249
- //console.log("addSignalHandler()", hcl, Object.keys(this._signalHandlers));
250
- //const maybeHandler = this._signalHandlers[cellIdStr]
251
- if (hcl != "__all") {
252
- const maybeHandler = Object.getOwnPropertyDescriptor(this._signalHandlers, hcl);
253
- if (maybeHandler && maybeHandler.value) {
254
- throw new Error(`SignalHandler already added for "${hcl}"`);
255
- }
256
- }
257
- this._signalHandlers[hcl] = handler;
258
- /* return tailored unsubscribe function to the caller */
259
- return {
260
- unsubscribe: () => {
261
- const maybeHandler = this._signalHandlers[hcl];
262
- if (!maybeHandler) {
263
- console.warn("unsubscribe failed: Couldn't find signalHandler for", hcl);
264
- return;
265
- }
266
- delete this._signalHandlers[hcl];
267
- }
268
- };
269
- }
270
- /** Log all signals received */
271
- logSignal(signal) {
272
- this._signalLogs.push([Date.now(), CellIdStr(signal.data.cellId), signal]);
273
- //console.log("signal logged", this._signalLogs)
274
- }
275
- /** */
276
- dumpSignals(cellId) {
277
- if (cellId) {
278
- const cellStr = CellIdStr(cellId);
279
- console.warn(`Dumping signal logs for cell "${this._hclMap[cellStr]}"`);
280
- const logs = this._signalLogs
281
- .filter((log) => log[1] == cellStr)
282
- .map((log) => {
283
- return { timestamp: prettyDate(new Date(log[0])), payload: log[2].data.payload };
284
- });
285
- console.table(logs);
286
- }
287
- else {
288
- console.warn("Dumping all signal logs");
289
- const logs = this._signalLogs
290
- .map((log) => {
291
- return { timestamp: prettyDate(new Date(log[0])), cell: this._hclMap[log[1]], payload: log[2].data.payload };
292
- });
293
- console.table(logs);
294
- }
295
- }
296
- }
1
+ import { __awaiter } from "tslib";
2
+ import { AppWebsocket, } from "@holochain/client";
3
+ import { CellProxy } from "./CellProxy";
4
+ import { CellIdStr, destructureCloneName, createCloneName } from "./types";
5
+ import { areCellsEqual, intoCell, prettyDate } from "./utils";
6
+ import { HCL } from "./hcl";
7
+ /**
8
+ * Creates, connects and holds a appWebsocket.
9
+ * Creates and holds Cell proxies for this appWebsocket.
10
+ * Maintains a mapping between CellIds and HCLs
11
+ * Handles SignalHandlers per HCL
12
+ * Stores appSignal logs
13
+ * TODO Implement Singleton per App port?
14
+ */
15
+ export class ConductorAppProxy {
16
+ /** -- Getters -- */
17
+ /** */
18
+ getAppCells(appId) {
19
+ return this._cellsByApp[appId];
20
+ }
21
+ /** */
22
+ getLocations(cellId) {
23
+ return this._hclMap[CellIdStr(cellId)];
24
+ }
25
+ /** */
26
+ getCell(hcl) {
27
+ const roleCellsMap = this._cellsByApp[hcl.appId];
28
+ if (!roleCellsMap)
29
+ throw Error(`getCell() failed. No hApp with ID "${hcl.appId}" found.`);
30
+ const roleCells = roleCellsMap[hcl.baseRoleName];
31
+ if (!roleCells)
32
+ throw Error(`getCell() failed: BaseRoleName "${hcl.baseRoleName}" not found in happ "${hcl.appId}"`);
33
+ let cell = roleCells.provisioned;
34
+ if (hcl.cloneId !== undefined) {
35
+ cell = roleCells.clones[hcl.cloneId];
36
+ if (!cell) {
37
+ throw Error(`getCell() failed: clone "${hcl.cloneId}" not found for role "${hcl.appId}/${hcl.baseRoleName}"`);
38
+ }
39
+ }
40
+ return cell;
41
+ }
42
+ /** Get stored CellProxy or attempt to create it */
43
+ getCellProxy(cellIdOrLoc) {
44
+ if (cellIdOrLoc instanceof HCL) {
45
+ const installedCell = this.getCell(cellIdOrLoc);
46
+ const maybeProxy = this.getCellProxy(installedCell.cell_id);
47
+ if (!maybeProxy)
48
+ throw Error("getCellProxy() failed. Proxy not found for cell " + CellIdStr(installedCell.cell_id));
49
+ return maybeProxy;
50
+ }
51
+ const sId = CellIdStr(cellIdOrLoc);
52
+ const maybeProxy = this._cellProxies[sId];
53
+ if (maybeProxy === undefined)
54
+ throw Error("getCellProxy() failed. Proxy not found for cell " + sId);
55
+ return maybeProxy;
56
+ }
57
+ /** */
58
+ getAppRoles(installedAppId) {
59
+ if (!this._cellsByApp[installedAppId])
60
+ return undefined;
61
+ return Object.values(this._cellsByApp[installedAppId]).map((roleCells) => {
62
+ return roleCells.provisioned.name;
63
+ });
64
+ }
65
+ /** */
66
+ getClones(appId, baseRoleName) {
67
+ const maybeApp = this._cellsByApp[appId];
68
+ if (!maybeApp)
69
+ return [];
70
+ const roleInstalledCells = maybeApp[baseRoleName];
71
+ if (!roleInstalledCells)
72
+ return [];
73
+ return Object.values(roleInstalledCells.clones);
74
+ }
75
+ createCloneCell(request) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ //console.log("createCloneCell() called:", request)
78
+ return this._appWs.createCloneCell(request);
79
+ });
80
+ }
81
+ /** -- AppApi (Passthrough to appWebsocket) -- */
82
+ enableCloneCell(request) {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ //console.log("enableCloneCell() called:", request)
85
+ return this._appWs.enableCloneCell(request);
86
+ });
87
+ }
88
+ disableCloneCell(request) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ //console.log("disableCloneCell() called:", request)
91
+ this._appWs.disableCloneCell(request);
92
+ });
93
+ }
94
+ appInfo(args) {
95
+ return __awaiter(this, void 0, void 0, function* () {
96
+ return this._appWs.appInfo(args);
97
+ });
98
+ }
99
+ callZome(req, timeout) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ timeout = timeout ? timeout : this.defaultTimeout;
102
+ return this._appWs.callZome(req, timeout);
103
+ });
104
+ }
105
+ /** -- Creation -- */
106
+ /** async Factory */
107
+ static new(port_or_socket, defaultTimeout) {
108
+ return __awaiter(this, void 0, void 0, function* () {
109
+ if (typeof port_or_socket == 'object') {
110
+ return ConductorAppProxy.fromSocket(port_or_socket);
111
+ }
112
+ else {
113
+ const timeout = defaultTimeout ? defaultTimeout : 10 * 1000;
114
+ let wsUrl = `ws://localhost:${port_or_socket}`;
115
+ try {
116
+ let conductor = new ConductorAppProxy(timeout);
117
+ conductor._appWs = yield AppWebsocket.connect(wsUrl, timeout);
118
+ conductor._appWs.on('signal', (sig) => { conductor.onSignal(sig); });
119
+ return conductor;
120
+ }
121
+ catch (e) {
122
+ console.error("ConductorAppProxy initialization failed", e);
123
+ return Promise.reject("ConductorAppProxy initialization failed");
124
+ }
125
+ }
126
+ });
127
+ }
128
+ /** */
129
+ static fromSocket(appWebsocket) {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ try {
132
+ let conductor = new ConductorAppProxy(appWebsocket.defaultTimeout);
133
+ conductor._appWs = appWebsocket;
134
+ conductor._appWs.on('signal', (sig) => { conductor.onSignal(sig); });
135
+ return conductor;
136
+ }
137
+ catch (e) {
138
+ console.error("ConductorAppProxy initialization failed", e);
139
+ return Promise.reject("ConductorAppProxy initialization failed");
140
+ }
141
+ });
142
+ }
143
+ /** Ctor */
144
+ constructor(defaultTimeout) {
145
+ this.defaultTimeout = defaultTimeout;
146
+ /** Signal log: [Timestamp, CellIdStr, Signal] */
147
+ this._signalLogs = [];
148
+ /** Map cells per App: InstalledAppId -> (BaseRoleName -> RoleInstalledCells) */
149
+ this._cellsByApp = {};
150
+ /** Map cell locations: CellIdStr -> HCL[] */
151
+ this._hclMap = {};
152
+ /** Store handlers per cell locaiton: HCLString -> AppSignalCb */
153
+ this._signalHandlers = {};
154
+ /** Store cell proxies per cell: CellIdStr -> CellProxy */
155
+ this._cellProxies = {};
156
+ const _unsub = this.addSignalHandler((sig) => this.logSignal(sig));
157
+ }
158
+ /** -- Methods -- */
159
+ /** */
160
+ fetchCell(appId, cellId) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ const appInfo = yield this.appInfo({ installed_app_id: appId });
163
+ //console.log("fetchCell", appInfo);
164
+ if (appInfo == null) {
165
+ Promise.reject(`getCell() failed. App "${appId}" not found on AppWebsocket "${this._appWs.client.socket.url}"`);
166
+ }
167
+ for (const cellInfos of Object.values(appInfo.cell_info)) {
168
+ for (const cellInfo of Object.values(cellInfos)) {
169
+ const cell = intoCell(cellInfo);
170
+ if (cell === undefined) {
171
+ continue;
172
+ }
173
+ if (areCellsEqual(cell.cell_id, cellId)) {
174
+ return cell;
175
+ }
176
+ }
177
+ }
178
+ Promise.reject("getCell() failed. Cell not found for app.");
179
+ });
180
+ }
181
+ /** */
182
+ fetchCells(appId, baseRoleName) {
183
+ return __awaiter(this, void 0, void 0, function* () {
184
+ /** Make sure hApp exists */
185
+ const appInfo = yield this.appInfo({ installed_app_id: appId });
186
+ if (appInfo == null) {
187
+ Promise.reject(`fetchCells() failed. App "${appId}" not found on AppWebsocket "${this._appWs.client.socket.url}"`);
188
+ }
189
+ //console.log("fetchCells() installedAppInfo:\n", printAppInfo(installedAppInfo));
190
+ /** Make sure app Object exists */
191
+ if (!this._cellsByApp[appId]) {
192
+ this._cellsByApp[appId] = {};
193
+ }
194
+ /** Get all cells with that baseRoleName */
195
+ let provisioned;
196
+ let clones = {};
197
+ for (const [roleName, cellInfos] of Object.entries(appInfo.cell_info)) {
198
+ for (const cellInfo of Object.values(cellInfos)) {
199
+ const cell = intoCell(cellInfo);
200
+ if (cell === undefined) {
201
+ continue;
202
+ }
203
+ //console.log(`CreateCellProxy(): Found cell "${installedCell.role_id}":`, CellIdStr(installedCell.cell_id));
204
+ const maybePair = destructureCloneName(roleName);
205
+ const curBaseName = maybePair ? maybePair[0] : roleName;
206
+ if (curBaseName !== baseRoleName) {
207
+ continue;
208
+ }
209
+ if (maybePair) {
210
+ if (clones["" + maybePair[1]]) {
211
+ console.error(`fetchCells() Proxy already exist for clone: "${maybePair[0]}/${maybePair[1]}"`);
212
+ }
213
+ clones["" + maybePair[1]] = cell;
214
+ }
215
+ else {
216
+ provisioned = cell;
217
+ }
218
+ }
219
+ }
220
+ if (typeof provisioned === 'undefined') {
221
+ Promise.reject("Provisioned cell not found for role " + baseRoleName);
222
+ }
223
+ let roleInstalledCells = { provisioned: provisioned, clones };
224
+ /** Store it*/
225
+ this._cellsByApp[appId][baseRoleName] = roleInstalledCells;
226
+ return roleInstalledCells;
227
+ });
228
+ }
229
+ /** */
230
+ addClone(hcl, cloneCell) {
231
+ if (!this._cellsByApp[hcl.appId])
232
+ throw Error("addCloneInstalledCell() failed. no appId. " + hcl.toString());
233
+ if (!this._cellsByApp[hcl.appId][hcl.baseRoleName])
234
+ throw Error("addCloneInstalledCell() failed. no baseRoleName. " + hcl.toString());
235
+ let cloneName = hcl.cloneId;
236
+ if (hcl.cloneId === undefined) {
237
+ const cloneIndex = Object.keys(this._cellsByApp[hcl.appId][hcl.baseRoleName].clones).length;
238
+ cloneName = createCloneName(hcl.baseRoleName, cloneIndex);
239
+ }
240
+ this._cellsByApp[hcl.appId][hcl.baseRoleName].clones[cloneName] = cloneCell;
241
+ // const sCellId = CellIdStr(cloneCell.cell_id);
242
+ // console.log("CreateCellProxy() adding to hclMap", sCellId, cellLoc.asHcl())
243
+ // if (this._hclMap[sCellId]) {
244
+ // this._hclMap[sCellId].push(cellLoc.asHcl());
245
+ // } else {
246
+ // this._hclMap[sCellId] = [cellLoc.asHcl()];
247
+ // }
248
+ }
249
+ /** */
250
+ createCellProxy(hcl) {
251
+ //console.log("createCellProxy() for", hcl.toString());
252
+ /** Make sure cell exists */
253
+ const cell = this.getCell(hcl);
254
+ const sCellId = CellIdStr(cell.cell_id);
255
+ /** Create proxy for this cell if none exist yet, otherwise reuse */
256
+ let cellProxy = this._cellProxies[sCellId];
257
+ if (!cellProxy) {
258
+ /** Create and store Proxy */
259
+ cellProxy = new CellProxy(this, cell, this.defaultTimeout);
260
+ this._cellProxies[sCellId] = cellProxy;
261
+ }
262
+ /** Create CellId -> HCL mapping */
263
+ //console.log("CreateCellProxy() adding to hclMap", sCellId, hcl.toString())
264
+ if (this._hclMap[sCellId]) {
265
+ this._hclMap[sCellId].push(hcl);
266
+ }
267
+ else {
268
+ this._hclMap[sCellId] = [hcl];
269
+ }
270
+ //console.log("createCellProxy() Currently stored hclMap:", this._hclMap);
271
+ /** Done */
272
+ return cellProxy;
273
+ }
274
+ /** */
275
+ onSignal(signal) {
276
+ /** Grabe cell specific handlers */
277
+ const hcls = this.getLocations(signal.data.cellId);
278
+ const handlers = hcls ? hcls.map((hcl) => this._signalHandlers[hcl.toString()]) : [];
279
+ /** Grab common handler */
280
+ const allHandler = this._signalHandlers["__all"];
281
+ if (allHandler)
282
+ handlers.push(allHandler);
283
+ /** Send to all handlers */
284
+ for (const handler of handlers) {
285
+ handler(signal);
286
+ }
287
+ }
288
+ /** Store signalHandler to internal handler array */
289
+ addSignalHandler(handler, hcl) {
290
+ hcl = hcl ? hcl : "__all";
291
+ //console.log("addSignalHandler()", hcl, Object.keys(this._signalHandlers));
292
+ //const maybeHandler = this._signalHandlers[cellIdStr]
293
+ if (hcl != "__all") {
294
+ const maybeHandler = Object.getOwnPropertyDescriptor(this._signalHandlers, hcl);
295
+ if (maybeHandler && maybeHandler.value) {
296
+ throw new Error(`SignalHandler already added for "${hcl}"`);
297
+ }
298
+ }
299
+ this._signalHandlers[hcl] = handler;
300
+ /* return tailored unsubscribe function to the caller */
301
+ return {
302
+ unsubscribe: () => {
303
+ const maybeHandler = this._signalHandlers[hcl];
304
+ if (!maybeHandler) {
305
+ console.warn("unsubscribe failed: Couldn't find signalHandler for", hcl);
306
+ return;
307
+ }
308
+ delete this._signalHandlers[hcl];
309
+ }
310
+ };
311
+ }
312
+ /** Log all signals received */
313
+ logSignal(signal) {
314
+ this._signalLogs.push([Date.now(), CellIdStr(signal.data.cellId), signal]);
315
+ //console.log("signal logged", this._signalLogs)
316
+ }
317
+ /** */
318
+ dumpSignals(cellId) {
319
+ if (cellId) {
320
+ const cellStr = CellIdStr(cellId);
321
+ console.warn(`Dumping signal logs for cell "${this._hclMap[cellStr]}"`);
322
+ const logs = this._signalLogs
323
+ .filter((log) => log[1] == cellStr)
324
+ .map((log) => {
325
+ return { timestamp: prettyDate(new Date(log[0])), payload: log[2].data.payload };
326
+ });
327
+ console.table(logs);
328
+ }
329
+ else {
330
+ console.warn("Dumping all signal logs");
331
+ const logs = this._signalLogs
332
+ .map((log) => {
333
+ return { timestamp: prettyDate(new Date(log[0])), cell: this._hclMap[log[1]], payload: log[2].data.payload };
334
+ });
335
+ console.table(logs);
336
+ }
337
+ }
338
+ }
297
339
  //# sourceMappingURL=ConductorAppProxy.js.map