diff --git a/src/Locks.test.ts b/src/Locks.test.ts index 5c1023d3..1db845be 100644 --- a/src/Locks.test.ts +++ b/src/Locks.test.ts @@ -343,8 +343,8 @@ describe('Locks (mockClient)', () => { }); }); - describe('getAll', () => { - it('returns all locks in the LOCKED state', async ({ space }) => { + describe('get*', () => { + beforeEach(async ({ space }) => { await space.locks.processPresenceMessage( Realtime.PresenceMessage.fromValues({ action: 'update', @@ -381,31 +381,79 @@ describe('Locks (mockClient)', () => { }, }), ); + }); - const member1 = await space.members.getByConnectionId('1')!; - const member2 = await space.members.getByConnectionId('2')!; + it('correctly sets up locks', ({ space }) => { const lock1 = space.locks.get('lock1'); expect(lock1).toBeDefined(); + const lock2 = space.locks.get('lock2'); expect(lock2).toBeDefined(); + const lock3 = space.locks.get('lock3'); expect(lock3).toBeDefined(); + }); - const locks = space.locks.getAll(); - expect(locks.length).toEqual(3); - for (const lock of locks) { - switch (lock.id) { - case 'lock1': - case 'lock2': - expect(lock.member).toEqual(member1); - break; - case 'lock3': - expect(lock.member).toEqual(member2); - break; - default: - throw new Error(`unexpected lock id: ${lock.id}`); + describe('getSelf', () => { + it('returns all locks in the LOCKED state that belong to self', async ({ space }) => { + const member1 = await space.members.getByConnectionId('1')!; + + const locks = await space.locks.getSelf(); + expect(locks.length).toEqual(2); + + for (const lock of locks) { + switch (lock.id) { + case 'lock1': + case 'lock2': + expect(lock.member).toEqual(member1); + break; + default: + throw new Error(`unexpected lock id: ${lock.id}`); + } } - } + }); + }); + + describe('getOthers', () => { + it('returns all locks in the LOCKED state for every member but self', async ({ space }) => { + const member2 = await space.members.getByConnectionId('2')!; + + const locks = await space.locks.getOthers(); + expect(locks.length).toEqual(1); + + for (const lock of locks) { + switch (lock.id) { + case 'lock3': + expect(lock.member).toEqual(member2); + break; + default: + throw new Error(`unexpected lock id: ${lock.id}`); + } + } + }); + }); + + describe('getAll', () => { + it('returns all locks in the LOCKED state', async ({ space }) => { + const member1 = await space.members.getByConnectionId('1')!; + const member2 = await space.members.getByConnectionId('2')!; + + const locks = await space.locks.getAll(); + expect(locks.length).toEqual(3); + for (const lock of locks) { + switch (lock.id) { + case 'lock1': + case 'lock2': + expect(lock.member).toEqual(member1); + break; + case 'lock3': + expect(lock.member).toEqual(member2); + break; + default: + throw new Error(`unexpected lock id: ${lock.id}`); + } + } + }); }); }); }); diff --git a/src/Locks.ts b/src/Locks.ts index feb20e3f..0b08b2d7 100644 --- a/src/Locks.ts +++ b/src/Locks.ts @@ -58,7 +58,9 @@ export default class Locks extends EventEmitter { } } - getAll(): Lock[] { + // This will be async in the future, when pending requests are no longer processed + // in the library. + async getAll(): Promise { const allLocks: Lock[] = []; for (const locks of this.locks.values()) { @@ -72,6 +74,23 @@ export default class Locks extends EventEmitter { return allLocks; } + async getSelf(): Promise { + const self = await this.space.members.getSelf(); + + if (!self) return []; + + return this.getLocksForConnectionId(self.connectionId).filter((lock) => lock.status === 'locked'); + } + + async getOthers(): Promise { + const self = await this.space.members.getSelf(); + const allLocks = await this.getAll(); + + if (!self) return allLocks; + + return allLocks.filter((lock) => lock.member.connectionId !== self.connectionId); + } + async acquire(id: string, opts?: LockOptions): Promise { const self = await this.space.members.getSelf(); if (!self) {