From 979fb16b4bb5719845dfa17443622a1f08cfb08a Mon Sep 17 00:00:00 2001 From: Frank Hinek Date: Thu, 31 Aug 2023 17:14:26 -0700 Subject: [PATCH] Add SyncManager to identity and proxy agent packages Signed-off-by: Frank Hinek --- package-lock.json | 93 ++++++++++++------- packages/agent/src/test-managed-agent.ts | 2 +- packages/agent/tests/dwn-manager.spec.ts | 2 +- packages/agent/tests/sync-manager.spec.ts | 1 - packages/agent/tests/utils/test-agent.ts | 16 +++- packages/identity-agent/src/identity-agent.ts | 20 +++- packages/proxy-agent/src/proxy-agent.ts | 20 +++- 7 files changed, 110 insertions(+), 44 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed7de8d09..6d5904378 100644 --- a/package-lock.json +++ b/package-lock.json @@ -846,19 +846,19 @@ } }, "node_modules/@npmcli/git": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.1.tgz", - "integrity": "sha512-9zUEqmRMZU5bmqWVu83wFVHH9kwLEQeMuDUDSYsBK/L4qbBl8Shdoc5EWfANzAdy5kFuPbBn7ToXTakbVdlCZg==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.3.tgz", + "integrity": "sha512-UZp9NwK+AynTrKvHn5k3KviW/hA5eENmFsu3iAPe7sWRt0lFUdsY/wXIYjpDFe7cdSNwOIzbObfwgt6eL5/2zw==", "dev": true, "dependencies": { - "@npmcli/promise-spawn": "^6.0.0", + "@npmcli/promise-spawn": "^7.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^9.0.0", "proc-log": "^3.0.0", "promise-inflight": "^1.0.1", "promise-retry": "^2.0.1", "semver": "^7.3.5", - "which": "^3.0.0" + "which": "^4.0.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" @@ -883,15 +883,15 @@ } }, "node_modules/@npmcli/promise-spawn": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz", - "integrity": "sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.0.tgz", + "integrity": "sha512-wBqcGsMELZna0jDblGd7UXgOby45TQaMWmbFwWX+SEotk4HV6zG2t6rT9siyLhPk4P6YYqgfL1UO8nMWDBVJXQ==", "dev": true, "dependencies": { - "which": "^3.0.0" + "which": "^4.0.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/@pkgjs/parseargs": { @@ -2368,9 +2368,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001524", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001524.tgz", - "integrity": "sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==", + "version": "1.0.30001525", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001525.tgz", + "integrity": "sha512-/3z+wB4icFt3r0USMwxujAqRvaD/B7rvGTsKhbhSQErVrJvkZCLhgNLJxU8MevahQVH6hCU9FsHdNUFbiwmE7Q==", "dev": true, "funding": [ { @@ -2837,6 +2837,12 @@ "node": ">= 8" } }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/cross-spawn/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3091,9 +3097,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.505", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.505.tgz", - "integrity": "sha512-0A50eL5BCCKdxig2SsCXhpuztnB9PfUgRMojj5tMvt8O54lbwz3t6wNgnpiTRosw5QjlJB7ixhVyeg8daLQwSQ==", + "version": "1.4.507", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.507.tgz", + "integrity": "sha512-brvPFnO1lu3UYBpBht2qWw9qqhdG4htTjT90/9oOJmxQ77VvTxL9+ghErFqQzgj7n8268ONAmlebqjBR/S+qgA==", "dev": true, "peer": true }, @@ -3526,7 +3532,8 @@ "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true }, "node_modules/events": { "version": "3.3.0", @@ -3895,9 +3902,9 @@ } }, "node_modules/glob": { - "version": "10.3.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.3.tgz", - "integrity": "sha512-92vPiMb/iqpmEgsOoIDvTjc50wf9CCCvMzsi6W0JLPeUKE8TWP1a73PgqSrqy7iAZxaSD1YdzU7QZR5LF51MJw==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", + "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", @@ -4658,10 +4665,13 @@ } }, "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } }, "node_modules/isomorphic-timers-promises": { "version": "1.0.1", @@ -4972,6 +4982,12 @@ "which": "^1.2.1" } }, + "node_modules/karma-chrome-launcher/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/karma-chrome-launcher/node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5007,6 +5023,12 @@ "which": "^2.0.1" } }, + "node_modules/karma-firefox-launcher/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/karma-firefox-launcher/node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6411,11 +6433,11 @@ } }, "node_modules/p-queue": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.3.4.tgz", - "integrity": "sha512-esox8CWt0j9EZECFvkFl2WNPat8LN4t7WWeXq73D9ha0V96qPRufApZi4ZhPwXAln1uVVal429HVVKPa2X0yQg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-7.4.0.tgz", + "integrity": "sha512-1FYFpop2WjLUfhSpKb0pi01JL+Z+H0Z8F2XPn2g04WxGynU/X8mx8s/66fb7jZ39pS2ZliAWCX97EoTSIdMmtw==", "dependencies": { - "eventemitter3": "^4.0.7", + "eventemitter3": "^5.0.1", "p-timeout": "^5.0.2" }, "engines": { @@ -6425,6 +6447,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, "node_modules/p-timeout": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-5.1.0.tgz", @@ -8380,18 +8407,18 @@ } }, "node_modules/which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/which/-/which-3.0.1.tgz", - "integrity": "sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.13.0 || >=18.0.0" } }, "node_modules/which-typed-array": { diff --git a/packages/agent/src/test-managed-agent.ts b/packages/agent/src/test-managed-agent.ts index 5d0a61ab1..9e50e783c 100644 --- a/packages/agent/src/test-managed-agent.ts +++ b/packages/agent/src/test-managed-agent.ts @@ -16,12 +16,12 @@ import { DwnManager } from './dwn-manager.js'; import { KeyManager } from './key-manager.js'; import { Web5RpcClient } from './rpc-client.js'; import { AppDataVault } from './app-data-store.js'; +import { SyncManagerLevel } from './sync-manager.js'; import { cryptoToPortableKeyPair } from './utils.js'; import { DidStoreDwn, DidStoreMemory } from './store-managed-did.js'; import { IdentityManager, ManagedIdentity } from './identity-manager.js'; import { IdentityStoreDwn, IdentityStoreMemory } from './store-managed-identity.js'; import { KeyStoreDwn, KeyStoreMemory, PrivateKeyStoreDwn, PrivateKeyStoreMemory } from './store-managed-key.js'; -import { SyncManagerLevel } from './sync-manager.js'; type CreateMethodOptions = { agentClass: new (options: any) => Web5ManagedAgent diff --git a/packages/agent/tests/dwn-manager.spec.ts b/packages/agent/tests/dwn-manager.spec.ts index ad72477bc..b491e2c30 100644 --- a/packages/agent/tests/dwn-manager.spec.ts +++ b/packages/agent/tests/dwn-manager.spec.ts @@ -7,6 +7,7 @@ import { RecordsRead, EventsGetReply, EventsGetMessage, + MessagesGetReply, RecordsReadReply, RecordsQueryReply, UnionMessageReply, @@ -14,7 +15,6 @@ import { RecordsQueryMessage, RecordsWriteMessage, RecordsDeleteMessage, - MessagesGetReply, ProtocolsConfigureMessage, } from '@tbd54566975/dwn-sdk-js'; diff --git a/packages/agent/tests/sync-manager.spec.ts b/packages/agent/tests/sync-manager.spec.ts index 1f5c829e9..b1145a00c 100644 --- a/packages/agent/tests/sync-manager.spec.ts +++ b/packages/agent/tests/sync-manager.spec.ts @@ -43,7 +43,6 @@ describe('SyncManagerLevel', () => { describe('with Web5ManagedAgent', () => { let alice: ManagedIdentity; let aliceDid: PortableDid; - // let syncManager: SyncManagerLevel; let testAgent: TestManagedAgent; before(async () => { diff --git a/packages/agent/tests/utils/test-agent.ts b/packages/agent/tests/utils/test-agent.ts index d22c5df33..aef599935 100644 --- a/packages/agent/tests/utils/test-agent.ts +++ b/packages/agent/tests/utils/test-agent.ts @@ -1,3 +1,4 @@ +import { Level } from 'level'; import { Dwn } from '@tbd54566975/dwn-sdk-js'; import { DidIonMethod, DidKeyMethod, DidResolver } from '@web5/dids'; import { MessageStoreLevel, DataStoreLevel, EventLogLevel } from '@tbd54566975/dwn-sdk-js/stores'; @@ -44,6 +45,7 @@ type TestAgentOptions = { dwnDataStore: DataStoreLevel; dwnEventLog: EventLogLevel; dwnMessageStore: MessageStoreLevel; + syncStore: Level; } export class TestAgent implements Web5ManagedAgent { @@ -58,12 +60,13 @@ export class TestAgent implements Web5ManagedAgent { syncManager: SyncManager; /** - * DWN-related properties. + * Store-related properties. */ dwn: Dwn; dwnDataStore: DataStoreLevel; dwnEventLog: EventLogLevel; dwnMessageStore: MessageStoreLevel; + syncStore: Level; constructor(options: TestAgentOptions) { this.appData = options.appData; @@ -87,6 +90,7 @@ export class TestAgent implements Web5ManagedAgent { this.dwnDataStore = options.dwnDataStore; this.dwnEventLog = options.dwnEventLog; this.dwnMessageStore = options.dwnMessageStore; + this.syncStore = options.syncStore; } async clearStorage(): Promise { @@ -94,12 +98,14 @@ export class TestAgent implements Web5ManagedAgent { await this.dwnDataStore.clear(); await this.dwnEventLog.clear(); await this.dwnMessageStore.clear(); + await this.syncStore.clear(); } async closeStorage(): Promise { await this.dwnDataStore.close(); await this.dwnEventLog.close(); await this.dwnMessageStore.close(); + await this.syncStore.close(); } static async create(options: CreateMethodOptions = {}): Promise { @@ -142,8 +148,9 @@ export class TestAgent implements Web5ManagedAgent { // Instantiate an RPC Client. const rpcClient = new Web5RpcClient(); - // Instantiate a SyncManager. - const syncManager = new SyncManagerLevel({ dataPath: testDataPath('SYNC_STORE') }); + // Instantiate a custom SyncManager and LevelDB-backed store. + const syncStore = new Level(testDataPath('SYNC_STORE')); + const syncManager = new SyncManagerLevel({ db: syncStore }); return new TestAgent({ appData, @@ -157,7 +164,8 @@ export class TestAgent implements Web5ManagedAgent { identityManager, keyManager, rpcClient, - syncManager + syncManager, + syncStore }); } diff --git a/packages/identity-agent/src/identity-agent.ts b/packages/identity-agent/src/identity-agent.ts index 15bfb6690..cb9220a14 100644 --- a/packages/identity-agent/src/identity-agent.ts +++ b/packages/identity-agent/src/identity-agent.ts @@ -3,6 +3,7 @@ import type { VcResponse, DidResponse, DwnResponse, + SyncManager, AppDataStore, SendVcRequest, SendDidRequest, @@ -27,6 +28,7 @@ import { Web5RpcClient, IdentityManager, IdentityStoreDwn, + SyncManagerLevel, PrivateKeyStoreDwn, cryptoToPortableKeyPair, } from '@web5/agent'; @@ -40,6 +42,7 @@ export type IdentityAgentOptions = { identityManager: IdentityManager; keyManager: KeyManager; rpcClient: DwnRpc; + syncManager: SyncManager; } export class IdentityAgent implements Web5ManagedAgent { @@ -51,6 +54,7 @@ export class IdentityAgent implements Web5ManagedAgent { identityManager: IdentityManager; keyManager: KeyManager; rpcClient: DwnRpc; + syncManager: SyncManager; constructor(options: IdentityAgentOptions) { this.agentDid = options.agentDid; @@ -61,16 +65,21 @@ export class IdentityAgent implements Web5ManagedAgent { this.identityManager = options.identityManager; this.keyManager = options.keyManager; this.rpcClient = options.rpcClient; + this.syncManager = options.syncManager; // Set this agent to be the default agent. this.didManager.agent = this; this.dwnManager.agent = this; this.identityManager.agent = this; this.keyManager.agent = this; + this.syncManager.agent = this; } static async create(options: Partial = {}): Promise { - let { agentDid, appData, didManager, didResolver, dwnManager, identityManager, keyManager, rpcClient } = options; + let { + agentDid, appData, didManager, didResolver, dwnManager, + identityManager, keyManager, rpcClient, syncManager + } = options; if (agentDid === undefined) { // An Agent DID was not specified, so set to empty string. @@ -140,6 +149,12 @@ export class IdentityAgent implements Web5ManagedAgent { rpcClient = new Web5RpcClient(); } + if (syncManager === undefined) { + // A custom SyncManager implementation was not specified, so + // instantiate a LevelDB-backed default. + syncManager = new SyncManagerLevel(); + } + // Instantiate the Identity Agent. const agent = new IdentityAgent({ agentDid, @@ -149,7 +164,8 @@ export class IdentityAgent implements Web5ManagedAgent { dwnManager, identityManager, keyManager, - rpcClient + rpcClient, + syncManager }); return agent; diff --git a/packages/proxy-agent/src/proxy-agent.ts b/packages/proxy-agent/src/proxy-agent.ts index 1ef699287..343b59d80 100644 --- a/packages/proxy-agent/src/proxy-agent.ts +++ b/packages/proxy-agent/src/proxy-agent.ts @@ -3,6 +3,7 @@ import type { VcResponse, DidResponse, DwnResponse, + SyncManager, AppDataStore, SendVcRequest, SendDidRequest, @@ -27,6 +28,7 @@ import { Web5RpcClient, IdentityManager, IdentityStoreDwn, + SyncManagerLevel, PrivateKeyStoreDwn, cryptoToPortableKeyPair, } from '@web5/agent'; @@ -40,6 +42,7 @@ export type Web5ProxyAgentOptions = { identityManager: IdentityManager; keyManager: KeyManager; rpcClient: DwnRpc; + syncManager: SyncManager; } export class Web5ProxyAgent implements Web5ManagedAgent { @@ -51,6 +54,7 @@ export class Web5ProxyAgent implements Web5ManagedAgent { identityManager: IdentityManager; keyManager: KeyManager; rpcClient: DwnRpc; + syncManager: SyncManager; constructor(options: Web5ProxyAgentOptions) { this.agentDid = options.agentDid; @@ -61,16 +65,21 @@ export class Web5ProxyAgent implements Web5ManagedAgent { this.dwnManager = options.dwnManager; this.identityManager = options.identityManager; this.rpcClient = options.rpcClient; + this.syncManager = options.syncManager; // Set this agent to be the default agent. this.didManager.agent = this; this.dwnManager.agent = this; this.identityManager.agent = this; this.keyManager.agent = this; + this.syncManager.agent = this; } static async create(options: Partial = {}): Promise { - let { agentDid, appData, didManager, didResolver, dwnManager, identityManager, keyManager, rpcClient } = options; + let { + agentDid, appData, didManager, didResolver, dwnManager, + identityManager, keyManager, rpcClient, syncManager + } = options; if (agentDid === undefined) { // An Agent DID was not specified, so set to empty string. @@ -140,6 +149,12 @@ export class Web5ProxyAgent implements Web5ManagedAgent { rpcClient = new Web5RpcClient(); } + if (syncManager === undefined) { + // A custom SyncManager implementation was not specified, so + // instantiate a LevelDB-backed default. + syncManager = new SyncManagerLevel(); + } + // Instantiate the Identity Agent. const agent = new Web5ProxyAgent({ agentDid, @@ -149,7 +164,8 @@ export class Web5ProxyAgent implements Web5ManagedAgent { dwnManager, keyManager, identityManager, - rpcClient + rpcClient, + syncManager }); return agent;