From a6e80fba64dc6d7f521c04e24d0f0dd9089d5328 Mon Sep 17 00:00:00 2001 From: Spencer Ofwiti Date: Tue, 13 Jul 2021 17:04:47 +0000 Subject: [PATCH] Move accounts query to a web worker. --- angular.json | 6 ++- src/app/_services/user.service.ts | 27 ++++++++++-- src/app/_workers/fetch-accounts.worker.ts | 50 +++++++++++++++++++++++ tsconfig.worker.json | 15 +++++++ 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 src/app/_workers/fetch-accounts.worker.ts create mode 100644 tsconfig.worker.json diff --git a/angular.json b/angular.json index 2b57cc7..e86534f 100644 --- a/angular.json +++ b/angular.json @@ -37,7 +37,8 @@ "scripts": [ "node_modules/jquery/dist/jquery.js", "node_modules/bootstrap/dist/js/bootstrap.js" - ] + ], + "webWorkerTsConfig": "tsconfig.worker.json" }, "configurations": { "production": { @@ -126,7 +127,8 @@ "tsConfig": [ "tsconfig.app.json", "tsconfig.spec.json", - "e2e/tsconfig.json" + "e2e/tsconfig.json", + "tsconfig.worker.json" ], "exclude": [ "**/node_modules/**" diff --git a/src/app/_services/user.service.ts b/src/app/_services/user.service.ts index d6d95a6..f8f258f 100644 --- a/src/app/_services/user.service.ts +++ b/src/app/_services/user.service.ts @@ -200,10 +200,31 @@ export class UserService { async loadAccounts(limit: number = 100, offset: number = 0): Promise { try { const accountRegistry = await RegistryService.getAccountRegistry(); - const accountAddresses: Array = await accountRegistry.last(limit); + const accountAddresses: Array = await accountRegistry.last(offset + limit); this.loggingService.sendInfoLevelMessage(accountAddresses); - for (const accountAddress of accountAddresses.slice(offset, offset + limit)) { - await this.getAccountByAddress(accountAddress, limit); + if (typeof Worker !== 'undefined') { + const worker = new Worker('@app/_workers/fetch-accounts.worker', { type: 'module' }); + worker.onmessage = ({ data }) => { + this.tokenService.load.subscribe(async (status: boolean) => { + if (status) { + data.balance = await this.tokenService.getTokenBalance( + data.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0] + ); + } + }); + this.addAccount(data, limit); + }; + worker.postMessage({ + addresses: accountAddresses.slice(offset, offset + limit), + url: environment.cicMetaUrl, + }); + } else { + this.loggingService.sendInfoLevelMessage( + 'Web workers are not supported in this environment' + ); + for (const accountAddress of accountAddresses.slice(offset, offset + limit)) { + await this.getAccountByAddress(accountAddress, limit); + } } } catch (error) { this.loggingService.sendErrorLevelMessage('Unable to load accounts.', 'user.service', error); diff --git a/src/app/_workers/fetch-accounts.worker.ts b/src/app/_workers/fetch-accounts.worker.ts new file mode 100644 index 0000000..519b760 --- /dev/null +++ b/src/app/_workers/fetch-accounts.worker.ts @@ -0,0 +1,50 @@ +/// + +import { Envelope, Syncable, User } from 'cic-client-meta'; +import { add0x } from '@src/assets/js/ethtx/dist/hex'; +import { personValidation, vcardValidation } from '@app/_helpers/schema-validation'; +import * as vCard from 'vcard-parser'; + +const headers = { + 'x-cic-automerge': 'client', +}; +const options = { + headers, +}; + +addEventListener('message', async ({ data }) => { + if (data.addresses instanceof Array) { + for (const accountAddress of data.addresses) { + try { + const account = await getAccountByAddress(accountAddress, data.url); + postMessage(account); + } catch (error) { + throw Error(error); + } + } + } +}); + +async function getAccountByAddress(accountAddress: string, metaUrl: string): Promise { + const userKey = await User.toKey(add0x(accountAddress)); + const response = await fetch(`${metaUrl}/${userKey}`, options) + .then((res) => { + if (res.ok) { + return res.json(); + } else { + return Promise.reject({ + status: res.status, + statusText: res.statusText, + }); + } + }) + .catch((error) => { + throw Error(`${error.status}: ${error.statusText}`); + }); + const account: Syncable = Envelope.fromJSON(JSON.stringify(response)).unwrap(); + const accountInfo = account.m.data; + await personValidation(accountInfo); + accountInfo.vcard = vCard.parse(atob(accountInfo.vcard)); + await vcardValidation(accountInfo.vcard); + return accountInfo; +} diff --git a/tsconfig.worker.json b/tsconfig.worker.json new file mode 100644 index 0000000..22dc454 --- /dev/null +++ b/tsconfig.worker.json @@ -0,0 +1,15 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/worker", + "lib": [ + "es2018", + "webworker" + ], + "types": [] + }, + "include": [ + "src/**/*.worker.ts" + ] +}