Skip to content

Commit

Permalink
Ability to update SyncOptions for an identity (#895)
Browse files Browse the repository at this point in the history
Added the ability to get/update the sync options for a given identity.

Additionally calling `registerIdentity` will fail if an identity is already registered instead of over-writing the options.
Ability to `unregister` an identity, which will stop it from syncing further the next interval.
  • Loading branch information
LiranCohen committed Sep 9, 2024
1 parent 43a5078 commit 57803fa
Show file tree
Hide file tree
Showing 5 changed files with 1,679 additions and 1,490 deletions.
8 changes: 8 additions & 0 deletions .changeset/lovely-eyes-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@web5/agent": patch
"@web5/identity-agent": patch
"@web5/proxy-agent": patch
"@web5/user-agent": patch
---

Add additionaly Sync Identity Management capabilities
12 changes: 12 additions & 0 deletions packages/agent/src/sync-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ export class AgentSyncApi implements SyncEngine {
await this._syncEngine.registerIdentity(params);
}

public async unregisterIdentity(did: string): Promise<void> {
await this._syncEngine.unregisterIdentity(did);
}

public async getIdentityOptions(did: string): Promise<SyncIdentityOptions | undefined> {
return await this._syncEngine.getIdentityOptions(did);
}

public async updateIdentityOptions(params: { did: string, options: SyncIdentityOptions }): Promise<void> {
await this._syncEngine.updateIdentityOptions(params);
}

public sync(direction?: 'push' | 'pull'): Promise<void> {
return this._syncEngine.sync(direction);
}
Expand Down
43 changes: 43 additions & 0 deletions packages/agent/src/sync-engine-level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,56 @@ export class SyncEngineLevel implements SyncEngine {
// Get a reference to the `registeredIdentities` sublevel.
const registeredIdentities = this._db.sublevel('registeredIdentities');

const existing = await this.getIdentityOptions(did);
if (existing) {
throw new Error(`SyncEngineLevel: Identity with DID ${did} is already registered.`);
}

// if no options are provided, we default to no delegateDid and all protocols (empty array)
options ??= { protocols: [] };

// Add (or overwrite, if present) the Identity's DID as a registered identity.
await registeredIdentities.put(did, JSON.stringify(options));
}

public async unregisterIdentity(did: string): Promise<void> {
const registeredIdentities = this._db.sublevel('registeredIdentities');
const existing = await this.getIdentityOptions(did);
if (!existing) {
throw new Error(`SyncEngineLevel: Identity with DID ${did} is not registered.`);
}

await registeredIdentities.del(did);
}

public async getIdentityOptions(did: string): Promise<SyncIdentityOptions | undefined> {
const registeredIdentities = this._db.sublevel('registeredIdentities');
try {
const options = await registeredIdentities.get(did);
if (options) {
return JSON.parse(options) as SyncIdentityOptions;
}
} catch(error) {
const e = error as { code: string };
// `Level`` throws an error if the key is not present. Return `undefined` in this case.
if (e.code === 'LEVEL_NOT_FOUND') {
return;
} else {
throw new Error(`SyncEngineLevel: Error reading level: ${e.code}.`);
}
}
}

public async updateIdentityOptions({ did, options }: { did: string, options: SyncIdentityOptions }): Promise<void> {
const registeredIdentities = this._db.sublevel('registeredIdentities');
const existingOptions = await this.getIdentityOptions(did);
if (!existingOptions) {
throw new Error(`SyncEngineLevel: Identity with DID ${did} is not registered.`);
}

await registeredIdentities.put(did, JSON.stringify(options));
}

public async sync(direction?: 'push' | 'pull'): Promise<void> {
if (this._syncLock) {
throw new Error('SyncEngineLevel: Sync operation is already in progress.');
Expand Down
12 changes: 12 additions & 0 deletions packages/agent/src/types/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ export interface SyncEngine {
* The options can define specific protocols that should only be synced, or a delegate DID that should be used to sign the sync messages.
*/
registerIdentity(params: { did: string, options?: SyncIdentityOptions }): Promise<void>;
/**
* Unregister an identity from the SyncEngine, this will stop syncing messages for this identity.
*/
unregisterIdentity(did: string): Promise<void>;
/**
* Get the Sync Options for a specific identity.
*/
getIdentityOptions(did: string): Promise<SyncIdentityOptions | undefined>;
/**
* Update the Sync Options for a specific identity, replaces the existing options.
*/
updateIdentityOptions(params: { did: string, options: SyncIdentityOptions }): Promise<void>;
/**
* Preforms a one-shot sync operation. If no direction is provided, it will perform both push and pull.
* @param direction which direction you'd like to perform the sync operation.
Expand Down
Loading

0 comments on commit 57803fa

Please sign in to comment.