@nmshd/app-runtime 2.0.0-alpha.6 → 2.0.0-beta.11

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.
Files changed (32) hide show
  1. package/dist/AppRuntime.d.ts +13 -22
  2. package/dist/AppRuntime.js +68 -122
  3. package/dist/AppRuntime.js.map +1 -1
  4. package/dist/AppRuntimeErrors.d.ts +0 -1
  5. package/dist/AppRuntimeErrors.js +0 -3
  6. package/dist/AppRuntimeErrors.js.map +1 -1
  7. package/dist/SessionStorage.d.ts +10 -0
  8. package/dist/SessionStorage.js +31 -0
  9. package/dist/SessionStorage.js.map +1 -0
  10. package/dist/buildInformation.js +5 -5
  11. package/dist/events/index.d.ts +0 -1
  12. package/dist/events/index.js +0 -1
  13. package/dist/events/index.js.map +1 -1
  14. package/dist/modules/appEvents/MailReceivedModule.js +1 -5
  15. package/dist/modules/appEvents/MailReceivedModule.js.map +1 -1
  16. package/dist/modules/appEvents/OnboardingChangeReceivedModule.js +1 -5
  17. package/dist/modules/appEvents/OnboardingChangeReceivedModule.js.map +1 -1
  18. package/dist/modules/appSync/AppSyncModule.js +1 -2
  19. package/dist/modules/appSync/AppSyncModule.js.map +1 -1
  20. package/dist/modules/pushNotifications/PushNotificationModule.d.ts +1 -1
  21. package/dist/modules/pushNotifications/PushNotificationModule.js +18 -34
  22. package/dist/modules/pushNotifications/PushNotificationModule.js.map +1 -1
  23. package/dist/modules/runtimeEvents/MessageReceivedModule.js +2 -10
  24. package/dist/modules/runtimeEvents/MessageReceivedModule.js.map +1 -1
  25. package/dist/modules/runtimeEvents/RelationshipChangedModule.js +12 -14
  26. package/dist/modules/runtimeEvents/RelationshipChangedModule.js.map +1 -1
  27. package/lib-web/nmshd.app-runtime.js +181 -232
  28. package/lib-web/nmshd.app-runtime.min.js +1 -1
  29. package/package.json +13 -14
  30. package/dist/events/RequestReceivedEvent.d.ts +0 -8
  31. package/dist/events/RequestReceivedEvent.js +0 -15
  32. package/dist/events/RequestReceivedEvent.js.map +0 -1
@@ -100,48 +100,38 @@ const events_1 = __webpack_require__(/*! ./events */ "./dist/events/index.js");
100
100
  const extensibility_1 = __webpack_require__(/*! ./extensibility */ "./dist/extensibility/index.js");
101
101
  const modules_1 = __webpack_require__(/*! ./modules */ "./dist/modules/index.js");
102
102
  const multiAccount_1 = __webpack_require__(/*! ./multiAccount */ "./dist/multiAccount/index.js");
103
+ const SessionStorage_1 = __webpack_require__(/*! ./SessionStorage */ "./dist/SessionStorage.js");
103
104
  const UserfriendlyResult_1 = __webpack_require__(/*! ./UserfriendlyResult */ "./dist/UserfriendlyResult.js");
104
105
  class AppRuntime extends runtime_1.Runtime {
105
- constructor(nativeBootstrapper, appConfig) {
106
- super(appConfig);
107
- this.nativeBootstrapper = nativeBootstrapper;
108
- this._availableSessions = [];
106
+ constructor(_nativeEnvironment, appConfig) {
107
+ super(appConfig, _nativeEnvironment.loggerFactory);
108
+ this._nativeEnvironment = _nativeEnvironment;
109
+ this.sessionStorage = new SessionStorage_1.SessionStorage();
109
110
  this.translationProvider = {
110
111
  translate: (key) => Promise.resolve(ts_utils_1.Result.ok(key))
111
112
  };
112
- if (!nativeBootstrapper.isInitialized) {
113
- throw AppRuntimeErrors_1.AppRuntimeErrors.startup.bootstrapperNotInitialized();
114
- }
115
- this._nativeEnvironment = nativeBootstrapper.nativeEnvironment;
116
113
  }
117
- uiBridge() {
114
+ async uiBridge() {
118
115
  if (this._uiBridge)
119
- return Promise.resolve(this._uiBridge);
120
- if (this._uiBridgePromise)
121
- return this._uiBridgePromise;
122
- this._uiBridgePromise = new Promise((resolve) => {
123
- this._uiBridgeResolveFunction = resolve;
124
- });
125
- this._uiBridgePromise
126
- .then(() => {
127
- this._uiBridgePromise = undefined;
128
- this._uiBridgeResolveFunction = undefined;
129
- })
130
- .catch((e) => {
131
- this._uiBridgePromise = undefined;
132
- this._uiBridgeResolveFunction = undefined;
133
- this.logger.error(e);
134
- });
135
- return this._uiBridgePromise;
116
+ return this._uiBridge;
117
+ if (this._uiBridgeResolver)
118
+ return await this._uiBridgeResolver.promise;
119
+ let resolve = () => "";
120
+ const promise = new Promise((r) => (resolve = r));
121
+ this._uiBridgeResolver = { promise, resolve };
122
+ try {
123
+ return await this._uiBridgeResolver.promise;
124
+ }
125
+ finally {
126
+ this._uiBridgeResolver = undefined;
127
+ }
136
128
  }
137
129
  registerUIBridge(uiBridge) {
138
- if (this._uiBridge) {
130
+ var _a;
131
+ if (this._uiBridge)
139
132
  return UserfriendlyResult_1.UserfriendlyResult.fail(AppRuntimeErrors_1.AppRuntimeErrors.startup.uiBridgeAlreadyRegistered());
140
- }
141
133
  this._uiBridge = uiBridge;
142
- if (this._uiBridgePromise && this._uiBridgeResolveFunction) {
143
- this._uiBridgeResolveFunction();
144
- }
134
+ (_a = this._uiBridgeResolver) === null || _a === void 0 ? void 0 : _a.resolve(uiBridge);
145
135
  return UserfriendlyResult_1.UserfriendlyResult.ok(undefined);
146
136
  }
147
137
  get multiAccountController() {
@@ -154,28 +144,22 @@ class AppRuntime extends runtime_1.Runtime {
154
144
  return this._nativeEnvironment;
155
145
  }
156
146
  get currentAccount() {
157
- if (!this._currentSession) {
158
- throw AppRuntimeErrors_1.AppRuntimeErrors.general.currentSessionUnavailable();
159
- }
160
- return this._currentSession.account;
147
+ return this.sessionStorage.currentSession.account;
148
+ }
149
+ get currentSession() {
150
+ return this.sessionStorage.currentSession;
151
+ }
152
+ getSessions() {
153
+ return this.sessionStorage.getSessions();
161
154
  }
162
155
  async login(accountController, consumptionController) {
163
156
  const services = await super.login(accountController, consumptionController);
164
157
  const appServices = new extensibility_1.AppServices(this, services.transportServices, services.consumptionServices, services.dataViewExpander);
165
158
  return { ...services, appServices };
166
159
  }
167
- get currentSession() {
168
- if (!this._currentSession) {
169
- throw AppRuntimeErrors_1.AppRuntimeErrors.general.currentSessionUnavailable();
170
- }
171
- return this._currentSession;
172
- }
173
- getServices(address) {
160
+ async getServices(address) {
174
161
  const addressString = typeof address === "string" ? address : address.toString();
175
- const session = this._availableSessions.find((session) => session.address === addressString);
176
- if (!session) {
177
- throw new Error(`Account ${addressString} not logged in.`);
178
- }
162
+ const session = await this.getOrCreateSession(addressString);
179
163
  return {
180
164
  transportServices: session.transportServices,
181
165
  consumptionServices: session.consumptionServices,
@@ -183,70 +167,43 @@ class AppRuntime extends runtime_1.Runtime {
183
167
  dataViewExpander: session.expander
184
168
  };
185
169
  }
186
- getSessions() {
187
- return this._availableSessions.map((session) => session.account);
188
- }
189
- getSession(accountId) {
190
- const session = this.findSession(accountId);
191
- if (session)
192
- return session.account;
193
- return undefined;
194
- }
195
- findSession(accountId) {
196
- return this._availableSessions.find((item) => item.account.id === accountId);
197
- }
198
- findSessionByAddress(address) {
199
- return this._availableSessions.find((item) => item.address === address);
170
+ async selectAccount(accountAddress, _password) {
171
+ const session = await this.getOrCreateSession(accountAddress);
172
+ this.sessionStorage.currentSession = session;
173
+ this.eventBus.publish(new events_1.AccountSelectedEvent(session.address, session.account.id));
174
+ return session;
200
175
  }
201
- async selectAccountByAddress(address, password) {
202
- if (this._currentSession && this._currentSession.address === address) {
203
- return this._currentSession.account;
204
- }
205
- const availableSession = this.findSessionByAddress(address);
206
- let accountId = availableSession === null || availableSession === void 0 ? void 0 : availableSession.account.id;
207
- if (!accountId) {
208
- accountId = (await this.multiAccountController.getAccountByAddress(address)).id.toString();
176
+ async getOrCreateSession(accountReference) {
177
+ const existingSession = this.sessionStorage.findSession(accountReference);
178
+ if (existingSession) {
179
+ return existingSession;
209
180
  }
210
- return await this.selectAccount(accountId, password);
181
+ return await this.createSession(accountReference);
211
182
  }
212
- async selectAccount(accountId, password) {
213
- if (this._currentSession && this._currentSession.account.id === accountId) {
214
- return this._currentSession.account;
215
- }
216
- const availableSession = this.findSession(accountId);
217
- // If there is any select promise, we have to await it, even before returning an available session
218
- if (this._accountIdToPromise && this._accountIdToPromise !== accountId) {
219
- if (!availableSession) {
220
- // Another account is currently logging in and we also need to log in -> error
221
- throw AppRuntimeErrors_1.AppRuntimeErrors.multiAccount.concurrentLoginOfDifferentAccounts();
222
- }
223
- else {
224
- // Another account is currently logging in and we already have an open session -> await login of the other account but do not return
225
- await this._selectAccountPromise;
226
- }
227
- }
228
- else if (this._selectAccountPromise) {
229
- // Same account is currently logging in -> await login and return
230
- return await this._selectAccountPromise;
231
- }
232
- if (availableSession) {
233
- await this.login(availableSession.accountController, availableSession.consumptionController);
234
- this._currentSession = availableSession;
235
- this.eventBus.publish(new events_1.AccountSelectedEvent(availableSession.address, availableSession.account.id));
236
- return availableSession.account;
183
+ async createSession(accountReference, masterPassword = "") {
184
+ var _a;
185
+ const accountId = accountReference.length === 20
186
+ ? accountReference
187
+ : (await this.multiAccountController.getAccountByAddress(accountReference)).id.toString();
188
+ if (((_a = this.currentSessionPromise) === null || _a === void 0 ? void 0 : _a.accountId) === accountId) {
189
+ return await this.currentSessionPromise.promise;
190
+ }
191
+ if (this.currentSessionPromise) {
192
+ await this.currentSessionPromise.promise.catch(() => {
193
+ // ignore
194
+ });
195
+ return await this.createSession(accountId, masterPassword);
237
196
  }
238
- this._selectAccountPromise = this._selectAccount(accountId, password);
197
+ this.currentSessionPromise = { promise: this._createSession(accountId, masterPassword), accountId };
239
198
  try {
240
- return await this._selectAccountPromise;
199
+ return await this.currentSessionPromise.promise;
241
200
  }
242
201
  finally {
243
- this._selectAccountPromise = undefined;
244
- this._accountIdToPromise = undefined;
202
+ this.currentSessionPromise = undefined;
245
203
  }
246
204
  }
247
- async _selectAccount(accountId, password) {
248
- this._accountIdToPromise = accountId;
249
- const [localAccount, accountController] = await this._multiAccountController.selectAccount(transport_1.CoreId.from(accountId), password);
205
+ async _createSession(accountId, masterPassword) {
206
+ const [localAccount, accountController] = await this._multiAccountController.selectAccount(transport_1.CoreId.from(accountId), masterPassword);
250
207
  if (!localAccount.address) {
251
208
  throw AppRuntimeErrors_1.AppRuntimeErrors.general.addressUnavailable().logWith(this.logger);
252
209
  }
@@ -263,10 +220,8 @@ class AppRuntime extends runtime_1.Runtime {
263
220
  accountController,
264
221
  consumptionController
265
222
  };
266
- this._availableSessions.push(session);
267
- this._currentSession = session;
268
- this.eventBus.publish(new events_1.AccountSelectedEvent(session.address, session.account.id));
269
- return session.account;
223
+ this.sessionStorage.addSession(session);
224
+ return session;
270
225
  }
271
226
  async queryAccount(title = "i18n://uibridge.accountSelection.title", description = "i18n://uibridge.accountSelection.description") {
272
227
  let selectedAccount;
@@ -288,20 +243,16 @@ class AppRuntime extends runtime_1.Runtime {
288
243
  return UserfriendlyResult_1.UserfriendlyResult.ok(selectedAccount);
289
244
  }
290
245
  async selectRelationship(id) {
291
- if (!this._currentSession) {
292
- throw AppRuntimeErrors_1.AppRuntimeErrors.general.currentSessionUnavailable().logWith(this.logger);
293
- }
294
246
  if (!id) {
295
- this._currentSession.selectedRelationship = undefined;
247
+ this.currentSession.selectedRelationship = undefined;
296
248
  return;
297
249
  }
298
250
  const result = await this.currentSession.appServices.relationships.renderRelationship(id);
299
- if (result.isError) {
251
+ if (result.isError)
300
252
  throw result.error;
301
- }
302
253
  const relationship = result.value;
303
- this._currentSession.selectedRelationship = relationship;
304
- this.eventBus.publish(new events_1.RelationshipSelectedEvent(this._currentSession.address, relationship));
254
+ this.currentSession.selectedRelationship = relationship;
255
+ this.eventBus.publish(new events_1.RelationshipSelectedEvent(this.currentSession.address, relationship));
305
256
  }
306
257
  getHealth() {
307
258
  const health = {
@@ -331,7 +282,7 @@ class AppRuntime extends runtime_1.Runtime {
331
282
  : (0, AppConfig_1.createAppConfig)({
332
283
  transportLibrary: transportConfig
333
284
  });
334
- const runtime = new AppRuntime(nativeBootstrapper, mergedConfig);
285
+ const runtime = new AppRuntime(nativeBootstrapper.nativeEnvironment, mergedConfig);
335
286
  await runtime.init();
336
287
  runtime.logger.trace("Runtime initialized");
337
288
  return runtime;
@@ -342,11 +293,6 @@ class AppRuntime extends runtime_1.Runtime {
342
293
  runtime.logger.trace("Runtime started");
343
294
  return runtime;
344
295
  }
345
- createLoggerFactory() {
346
- const loggerFactory = this.nativeEnvironment.loggerFactory;
347
- this.logger = loggerFactory.getLogger(runtime_1.Runtime);
348
- return loggerFactory;
349
- }
350
296
  createDatabaseConnection() {
351
297
  this.logger.trace("Creating DatabaseConnection to LokiJS");
352
298
  this.lokiConnection = new docdb_access_loki_1.LokiJsConnection("./data", this.nativeEnvironment.databaseFactory);
@@ -475,9 +421,6 @@ class MultiAccount {
475
421
  wrongRealm() {
476
422
  return new UserfriendlyApplicationError_1.UserfriendlyApplicationError("error.runtime.MultiAccount.WrongRealm", "The given realm is invalid.");
477
423
  }
478
- concurrentLoginOfDifferentAccounts() {
479
- return new UserfriendlyApplicationError_1.UserfriendlyApplicationError("error.runtime.MultiAccount.ParallelLoginOfDifferentAccounts", "You cannot login different accounts concurrently. Please wait until the login is completed.");
480
- }
481
424
  }
482
425
  class Modules {
483
426
  constructor() {
@@ -495,6 +438,47 @@ AppRuntimeErrors.multiAccount = new MultiAccount();
495
438
 
496
439
  /***/ }),
497
440
 
441
+ /***/ "./dist/SessionStorage.js":
442
+ /*!********************************!*\
443
+ !*** ./dist/SessionStorage.js ***!
444
+ \********************************/
445
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
446
+
447
+ "use strict";
448
+
449
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
450
+ exports.SessionStorage = void 0;
451
+ const AppRuntimeErrors_1 = __webpack_require__(/*! ./AppRuntimeErrors */ "./dist/AppRuntimeErrors.js");
452
+ class SessionStorage {
453
+ constructor() {
454
+ this._availableSessions = [];
455
+ }
456
+ set currentSession(session) {
457
+ this._currentSession = session;
458
+ }
459
+ get currentSession() {
460
+ if (!this._currentSession) {
461
+ throw AppRuntimeErrors_1.AppRuntimeErrors.general.currentSessionUnavailable();
462
+ }
463
+ return this._currentSession;
464
+ }
465
+ getSessions() {
466
+ return this._availableSessions;
467
+ }
468
+ findSession(accountReference) {
469
+ return this._availableSessions.find((item) => item.account.address === accountReference || item.account.id === accountReference);
470
+ }
471
+ addSession(session) {
472
+ if (this.findSession(session.account.id))
473
+ throw new Error("Session already exists");
474
+ this._availableSessions.push(session);
475
+ }
476
+ }
477
+ exports.SessionStorage = SessionStorage;
478
+ //# sourceMappingURL=SessionStorage.js.map
479
+
480
+ /***/ }),
481
+
498
482
  /***/ "./dist/UserfriendlyApplicationError.js":
499
483
  /*!**********************************************!*\
500
484
  !*** ./dist/UserfriendlyApplicationError.js ***!
@@ -558,11 +542,11 @@ const crypto_1 = __webpack_require__(/*! @nmshd/crypto */ "@nmshd/crypto");
558
542
  const runtime_1 = __webpack_require__(/*! @nmshd/runtime */ "@nmshd/runtime");
559
543
  const transport_1 = __webpack_require__(/*! @nmshd/transport */ "@nmshd/transport");
560
544
  exports.buildInformation = {
561
- version: "2.0.0-alpha.6",
562
- build: "17",
563
- date: "2022-07-19T13:27:53+00:00",
564
- commit: "6fac45e109bc1f82f4cb7010552b612291f3c297",
565
- dependencies: {"@js-soft/docdb-access-loki":"^1.0.3","@js-soft/native-abstractions":"^1.2.0","@nmshd/runtime":"2.0.0-alpha.37","lodash":"^4.17.21"},
545
+ version: "2.0.0-beta.11",
546
+ build: "28",
547
+ date: "2022-09-09T14:47:37+00:00",
548
+ commit: "861d4e422457cb2833f700ee4753a7dd8390de8b",
549
+ dependencies: {"@js-soft/docdb-access-loki":"^1.0.3","@js-soft/native-abstractions":"^1.2.0","@nmshd/runtime":"2.0.0-beta.23","lodash":"^4.17.21"},
566
550
  libraries: {
567
551
  serval: ts_serval_1.buildInformation,
568
552
  crypto: crypto_1.buildInformation,
@@ -719,31 +703,6 @@ RelationshipSelectedEvent.namespace = "app.relationshipSelected";
719
703
 
720
704
  /***/ }),
721
705
 
722
- /***/ "./dist/events/RequestReceivedEvent.js":
723
- /*!*********************************************!*\
724
- !*** ./dist/events/RequestReceivedEvent.js ***!
725
- \*********************************************/
726
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
727
-
728
- "use strict";
729
-
730
- Object.defineProperty(exports, "__esModule", ({ value: true }));
731
- exports.RequestReceivedEvent = void 0;
732
- const runtime_1 = __webpack_require__(/*! @nmshd/runtime */ "@nmshd/runtime");
733
- class RequestReceivedEvent extends runtime_1.DataEvent {
734
- constructor(address, request, message) {
735
- super(RequestReceivedEvent.namespace, address, {
736
- request,
737
- message
738
- });
739
- }
740
- }
741
- exports.RequestReceivedEvent = RequestReceivedEvent;
742
- RequestReceivedEvent.namespace = "app.requestReceived";
743
- //# sourceMappingURL=RequestReceivedEvent.js.map
744
-
745
- /***/ }),
746
-
747
706
  /***/ "./dist/events/index.js":
748
707
  /*!******************************!*\
749
708
  !*** ./dist/events/index.js ***!
@@ -773,7 +732,6 @@ __exportStar(__webpack_require__(/*! ./ExternalEventReceivedEvent */ "./dist/eve
773
732
  __exportStar(__webpack_require__(/*! ./MailReceivedEvent */ "./dist/events/MailReceivedEvent.js"), exports);
774
733
  __exportStar(__webpack_require__(/*! ./OnboardingChangeReceivedEvent */ "./dist/events/OnboardingChangeReceivedEvent.js"), exports);
775
734
  __exportStar(__webpack_require__(/*! ./RelationshipSelectedEvent */ "./dist/events/RelationshipSelectedEvent.js"), exports);
776
- __exportStar(__webpack_require__(/*! ./RequestReceivedEvent */ "./dist/events/RequestReceivedEvent.js"), exports);
777
735
  //# sourceMappingURL=index.js.map
778
736
 
779
737
  /***/ }),
@@ -1223,12 +1181,8 @@ class MailReceivedModule extends AppRuntimeModule_1.AppRuntimeModule {
1223
1181
  this.subscribeToEvent(events_1.MailReceivedEvent, this.handleMailReceived.bind(this));
1224
1182
  }
1225
1183
  async handleMailReceived(event) {
1184
+ const session = await this.runtime.getOrCreateSession(event.eventTargetAddress);
1226
1185
  const mail = event.data;
1227
- const session = this.runtime.findSessionByAddress(event.eventTargetAddress);
1228
- if (!session) {
1229
- this.logger.error(`No session found for address ${event.eventTargetAddress}`);
1230
- return;
1231
- }
1232
1186
  const sender = mail.createdBy;
1233
1187
  await this.runtime.nativeEnvironment.notificationAccess.schedule(mail.name, mail.createdBy.name, {
1234
1188
  callback: async () => {
@@ -1274,11 +1228,7 @@ class OnboardingChangeReceivedModule extends AppRuntimeModule_1.AppRuntimeModule
1274
1228
  const identity = event.data.identity;
1275
1229
  let title = "";
1276
1230
  let text = "";
1277
- const session = this.runtime.findSessionByAddress(event.eventTargetAddress);
1278
- if (!session) {
1279
- this.logger.error(`No session found for address ${event.eventTargetAddress}`);
1280
- return;
1281
- }
1231
+ const session = await this.runtime.getOrCreateSession(event.eventTargetAddress);
1282
1232
  switch (change.status) {
1283
1233
  case runtime_1.RelationshipChangeStatus.Accepted:
1284
1234
  title = "Kontaktanfrage genehmigt";
@@ -1372,8 +1322,7 @@ class AppSyncModule extends AppRuntimeModule_1.AppRuntimeModule {
1372
1322
  }
1373
1323
  async sync() {
1374
1324
  for (const session of this.runtime.getSessions()) {
1375
- const services = this.runtime.getServices(session.address);
1376
- const result = await services.transportServices.account.syncEverything();
1325
+ const result = await session.transportServices.account.syncEverything();
1377
1326
  if (result.isError) {
1378
1327
  this.logger.error(result.error);
1379
1328
  }
@@ -1501,28 +1450,23 @@ class PushNotificationModule extends AppRuntimeModule_1.AppRuntimeModule {
1501
1450
  const notification = event.notification;
1502
1451
  const content = notification.content;
1503
1452
  try {
1504
- const account = await this.runtime.selectAccountByAddress(content.accRef, "");
1505
- const session = this.runtime.findSession(account.id.toString());
1506
- if (!session) {
1507
- this.logger.error(`No session found for account ref ${content.accRef}`);
1508
- return;
1509
- }
1453
+ const services = await this.runtime.getServices(content.accRef);
1510
1454
  switch (content.eventName) {
1511
1455
  case IBackboneEventContent_1.BackboneEventName.DatawalletModificationsCreated:
1512
- const walletResult = await session.transportServices.account.syncDatawallet();
1456
+ const walletResult = await services.transportServices.account.syncDatawallet();
1513
1457
  if (walletResult.isError) {
1514
1458
  this.logger.error(walletResult);
1515
1459
  return;
1516
1460
  }
1517
- this.runtime.eventBus.publish(new events_1.DatawalletSynchronizedEvent(session.address));
1461
+ this.runtime.eventBus.publish(new events_1.DatawalletSynchronizedEvent(content.accRef));
1518
1462
  break;
1519
1463
  case IBackboneEventContent_1.BackboneEventName.ExternalEventCreated:
1520
- const syncResult = await session.transportServices.account.syncEverything();
1464
+ const syncResult = await services.transportServices.account.syncEverything();
1521
1465
  if (syncResult.isError) {
1522
1466
  this.logger.error(syncResult);
1523
1467
  return;
1524
1468
  }
1525
- this.runtime.eventBus.publish(new events_1.ExternalEventReceivedEvent(session.address, syncResult.value.messages, syncResult.value.relationships));
1469
+ this.runtime.eventBus.publish(new events_1.ExternalEventReceivedEvent(content.accRef, syncResult.value.messages, syncResult.value.relationships));
1526
1470
  break;
1527
1471
  default:
1528
1472
  break;
@@ -1535,8 +1479,8 @@ class PushNotificationModule extends AppRuntimeModule_1.AppRuntimeModule {
1535
1479
  async handleTokenRegistration(event) {
1536
1480
  try {
1537
1481
  this.logger.trace("PushNotificationModule.handleTokenRegistration", event);
1538
- for (const account of this.runtime.getSessions()) {
1539
- await this.registerPushTokenForLocalAccount(account.id, event.token);
1482
+ for (const session of this.runtime.getSessions()) {
1483
+ await this.registerPushTokenForLocalAccount(session.account.address, event.token);
1540
1484
  }
1541
1485
  }
1542
1486
  catch (e) {
@@ -1544,33 +1488,22 @@ class PushNotificationModule extends AppRuntimeModule_1.AppRuntimeModule {
1544
1488
  }
1545
1489
  }
1546
1490
  async handleAccountSelected(event) {
1547
- try {
1548
- this.logger.trace("PushNotificationModule.handleAccountSelected", event);
1549
- const tokenResult = this.getNotificationTokenFromConfig();
1550
- if (tokenResult.isSuccess) {
1551
- await this.registerPushTokenForLocalAccount(event.data.localAccountId, tokenResult.value);
1552
- }
1553
- else {
1554
- this.logger.error(tokenResult.error);
1555
- }
1556
- }
1557
- catch (e) {
1558
- this.logger.error(e);
1491
+ this.logger.trace("PushNotificationModule.handleAccountSelected", event);
1492
+ const tokenResult = this.getNotificationTokenFromConfig();
1493
+ if (tokenResult.isError) {
1494
+ this.logger.error(tokenResult.error);
1495
+ return;
1559
1496
  }
1497
+ await this.registerPushTokenForLocalAccount(event.data.address, tokenResult.value);
1560
1498
  }
1561
- async registerPushTokenForLocalAccount(id, token) {
1499
+ async registerPushTokenForLocalAccount(address, token) {
1562
1500
  if (!token) {
1563
1501
  throw AppRuntimeErrors_1.AppRuntimeErrors.modules.pushNotificationModule
1564
1502
  .tokenRegistrationNotPossible("The registered token was empty. This might be the case if you did not allow push notifications.")
1565
1503
  .logWith(this.logger);
1566
1504
  }
1567
- const session = this.runtime.findSession(id);
1568
- if (!session) {
1569
- throw AppRuntimeErrors_1.AppRuntimeErrors.modules.pushNotificationModule
1570
- .tokenRegistrationNotPossible("No session for this account found")
1571
- .logWith(this.logger);
1572
- }
1573
- const deviceResult = await session.transportServices.account.getDeviceInfo();
1505
+ const services = await this.runtime.getServices(address);
1506
+ const deviceResult = await services.transportServices.account.getDeviceInfo();
1574
1507
  if (deviceResult.isError) {
1575
1508
  throw AppRuntimeErrors_1.AppRuntimeErrors.modules.pushNotificationModule
1576
1509
  .tokenRegistrationNotPossible("No device for this account found", deviceResult.error)
@@ -1580,7 +1513,7 @@ class PushNotificationModule extends AppRuntimeModule_1.AppRuntimeModule {
1580
1513
  const platform = this.runtime.nativeEnvironment.deviceInfoAccess.deviceInfo.pushService;
1581
1514
  const handle = token;
1582
1515
  const installationId = device.id;
1583
- const result = await session.transportServices.account.registerPushNotificationToken({
1516
+ const result = await services.transportServices.account.registerPushNotificationToken({
1584
1517
  platform,
1585
1518
  handle,
1586
1519
  installationId
@@ -1591,7 +1524,7 @@ class PushNotificationModule extends AppRuntimeModule_1.AppRuntimeModule {
1591
1524
  .logWith(this.logger);
1592
1525
  }
1593
1526
  else {
1594
- this.logger.trace(`PushNotificationModule.registerPushTokenForLocalAccount: Token ${handle} registered for account ${id} on platform ${platform} and installationId ${installationId}`);
1527
+ this.logger.trace(`PushNotificationModule.registerPushTokenForLocalAccount: Token ${handle} registered for account ${address} on platform ${platform} and installationId ${installationId}`);
1595
1528
  }
1596
1529
  }
1597
1530
  getNotificationTokenFromConfig() {
@@ -1664,17 +1597,9 @@ class MessageReceivedModule extends AppRuntimeModule_1.AppRuntimeModule {
1664
1597
  this.subscribeToEvent(runtime_1.MessageReceivedEvent, this.handleMessageReceived.bind(this));
1665
1598
  }
1666
1599
  async handleMessageReceived(event) {
1667
- const message = event.data;
1668
- const session = this.runtime.findSessionByAddress(event.eventTargetAddress);
1669
- if (!session) {
1670
- this.logger.error(`No session found for address ${event.eventTargetAddress}`);
1671
- return;
1672
- }
1673
- const messageDVO = await session.expander.expandMessageDTO(message);
1600
+ const services = await this.runtime.getServices(event.eventTargetAddress);
1601
+ const messageDVO = await services.dataViewExpander.expandMessageDTO(event.data);
1674
1602
  switch (messageDVO.type) {
1675
- case "RequestMessageDVO":
1676
- this.runtime.eventBus.publish(new events_1.RequestReceivedEvent(event.eventTargetAddress, messageDVO.request, messageDVO));
1677
- break;
1678
1603
  case "MailDVO":
1679
1604
  const mail = messageDVO;
1680
1605
  this.runtime.eventBus.publish(new events_1.MailReceivedEvent(event.eventTargetAddress, mail));
@@ -1718,21 +1643,19 @@ class RelationshipChangedModule extends AppRuntimeModule_1.AppRuntimeModule {
1718
1643
  }
1719
1644
  async handleRelationshipChanged(event) {
1720
1645
  const relationship = event.data;
1721
- const session = this.runtime.findSessionByAddress(event.eventTargetAddress);
1722
- if (!session) {
1723
- this.logger.error(`No session found for address ${event.eventTargetAddress}`);
1646
+ // Only listen for the creation change (the first one)
1647
+ if (relationship.changes.length !== 1)
1724
1648
  return;
1725
- }
1726
- // The very first change is the onboarding change
1727
- if (relationship.changes.length === 1) {
1728
- const change = relationship.changes[0];
1729
- // Only fire received events if the current session did not create it
1730
- if ((!change.response && change.request.createdBy !== session.address) ||
1731
- (change.response && change.response.createdBy !== session.address)) {
1732
- const relationshipDVO = await session.expander.expandRelationshipDTO(relationship);
1733
- this.runtime.eventBus.publish(new events_1.OnboardingChangeReceivedEvent(session.address, relationship.changes[0], relationship, relationshipDVO));
1734
- }
1735
- }
1649
+ const change = relationship.changes[0];
1650
+ // response exits and created by the current identity
1651
+ if (!change.response && change.request.createdBy === event.eventTargetAddress)
1652
+ return;
1653
+ // response exits and created by the current identity
1654
+ if (change.response && change.response.createdBy === event.eventTargetAddress)
1655
+ return;
1656
+ const services = await this.runtime.getServices(event.eventTargetAddress);
1657
+ const relationshipDVO = await services.dataViewExpander.expandRelationshipDTO(relationship);
1658
+ this.runtime.eventBus.publish(new events_1.OnboardingChangeReceivedEvent(event.eventTargetAddress, change, relationship, relationshipDVO));
1736
1659
  }
1737
1660
  stop() {
1738
1661
  this.unsubscribeFromAllEvents();
@@ -3215,12 +3138,19 @@ __webpack_require__(/*! reflect-metadata */ "./node_modules/reflect-metadata/Ref
3215
3138
  const EventBus_1 = __webpack_require__(/*! ../EventBus */ "./node_modules/@js-soft/ts-utils/dist/eventBus/EventBus.js");
3216
3139
  const SubscriptionTargetInfo_1 = __webpack_require__(/*! ../SubscriptionTargetInfo */ "./node_modules/@js-soft/ts-utils/dist/eventBus/SubscriptionTargetInfo.js");
3217
3140
  class EventEmitter2EventBus {
3141
+ errorCallback;
3218
3142
  emitter;
3219
3143
  listeners = new Map();
3220
3144
  nextId = 0;
3221
3145
  invocationPromises = [];
3222
- constructor(options) {
3223
- this.emitter = new eventemitter2_1.EventEmitter2({ ...options, wildcard: true, maxListeners: 50, verboseMemoryLeak: true });
3146
+ constructor(errorCallback, eventEmitter2Options) {
3147
+ this.errorCallback = errorCallback;
3148
+ this.emitter = new eventemitter2_1.EventEmitter2({
3149
+ maxListeners: 50,
3150
+ verboseMemoryLeak: true,
3151
+ ...eventEmitter2Options,
3152
+ wildcard: true
3153
+ });
3224
3154
  }
3225
3155
  subscribe(subscriptionTarget, handler) {
3226
3156
  return this.registerHandler(subscriptionTarget, handler);
@@ -3240,7 +3170,7 @@ class EventEmitter2EventBus {
3240
3170
  }
3241
3171
  const invocationPromise = (async () => await handler(event))();
3242
3172
  this.invocationPromises.push(invocationPromise);
3243
- await invocationPromise;
3173
+ await invocationPromise.catch((e) => this.errorCallback(e, subscriptionTargetInfo.namespace));
3244
3174
  this.invocationPromises = this.invocationPromises.filter((p) => p !== invocationPromise);
3245
3175
  if (isOneTimeHandler)
3246
3176
  this.listeners.delete(listenerId);
@@ -3304,7 +3234,11 @@ exports.EventEmitter2EventBus = EventEmitter2EventBus;
3304
3234
 
3305
3235
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3306
3236
  if (k2 === undefined) k2 = k;
3307
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
3237
+ var desc = Object.getOwnPropertyDescriptor(m, k);
3238
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
3239
+ desc = { enumerable: true, get: function() { return m[k]; } };
3240
+ }
3241
+ Object.defineProperty(o, k2, desc);
3308
3242
  }) : (function(o, m, k, k2) {
3309
3243
  if (k2 === undefined) k2 = k;
3310
3244
  o[k2] = m[k];
@@ -3373,7 +3307,11 @@ exports.Event = Event;
3373
3307
 
3374
3308
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3375
3309
  if (k2 === undefined) k2 = k;
3376
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
3310
+ var desc = Object.getOwnPropertyDescriptor(m, k);
3311
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
3312
+ desc = { enumerable: true, get: function() { return m[k]; } };
3313
+ }
3314
+ Object.defineProperty(o, k2, desc);
3377
3315
  }) : (function(o, m, k, k2) {
3378
3316
  if (k2 === undefined) k2 = k;
3379
3317
  o[k2] = m[k];
@@ -3398,7 +3336,11 @@ __exportStar(__webpack_require__(/*! ./Event */ "./node_modules/@js-soft/ts-util
3398
3336
 
3399
3337
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3400
3338
  if (k2 === undefined) k2 = k;
3401
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
3339
+ var desc = Object.getOwnPropertyDescriptor(m, k);
3340
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
3341
+ desc = { enumerable: true, get: function() { return m[k]; } };
3342
+ }
3343
+ Object.defineProperty(o, k2, desc);
3402
3344
  }) : (function(o, m, k, k2) {
3403
3345
  if (k2 === undefined) k2 = k;
3404
3346
  o[k2] = m[k];
@@ -3523,6 +3465,9 @@ class ApplicationError extends Error {
3523
3465
  equals(error) {
3524
3466
  return this.code === error.code;
3525
3467
  }
3468
+ toString() {
3469
+ return JSON.stringify({ code: this.code, message: this.message, data: this.data }, undefined, 2);
3470
+ }
3526
3471
  }
3527
3472
  exports.ApplicationError = ApplicationError;
3528
3473
  //# sourceMappingURL=ApplicationError.js.map
@@ -3568,7 +3513,7 @@ class Result {
3568
3513
  }
3569
3514
  get value() {
3570
3515
  if (!this.isSuccess) {
3571
- throw new Error("Can't get the value of an error result. Use 'error' instead.");
3516
+ throw new Error(`Can't get the value of an error result. Use 'error' instead. Root error: \r\n${this.error}`);
3572
3517
  }
3573
3518
  return this._value;
3574
3519
  }
@@ -3594,7 +3539,11 @@ exports.Result = Result;
3594
3539
 
3595
3540
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3596
3541
  if (k2 === undefined) k2 = k;
3597
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
3542
+ var desc = Object.getOwnPropertyDescriptor(m, k);
3543
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
3544
+ desc = { enumerable: true, get: function() { return m[k]; } };
3545
+ }
3546
+ Object.defineProperty(o, k2, desc);
3598
3547
  }) : (function(o, m, k, k2) {
3599
3548
  if (k2 === undefined) k2 = k;
3600
3549
  o[k2] = m[k];
@@ -3736,7 +3685,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/*!
3736
3685
  var obj = {};
3737
3686
  var key;
3738
3687
  var len = keys.length;
3739
- var valuesCount = values ? value.length : 0;
3688
+ var valuesCount = values ? values.length : 0;
3740
3689
  for (var i = 0; i < len; i++) {
3741
3690
  key = keys[i];
3742
3691
  obj[key] = i < valuesCount ? values[i] : undefined;