Skip to content

Commit

Permalink
feat: pass scope as this in withLock (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
ido-pluto authored Feb 23, 2024
1 parent f93fbd0 commit d2351db
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ const res = await Promise.all([
console.log(res); // [42, 42, 42]
```


The given `scope` is used as the callback's `this`, so you can use its value in a `function`:

```typescript
import {withLock} from "lifecycle-utils";

const scope = {userName: "Joe"}; // can be a reference to any object you like

const res = await withLock(scope, "myKey", async function () {
await new Promise(resolve => setTimeout(resolve, 1000));
return `Hello ${this.userName}`;
});

console.log(res); // Hello Joe
```

### `isLockActive`
Check whether a lock is currently active for the given `scope` and `key`.

Expand Down
16 changes: 9 additions & 7 deletions src/withLock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ const locks = new Map<any, Map<string, Promise<any>>>();
/**
* Only allow one instance of the callback to run at a time for a given `scope` and `key`.
*/
export async function withLock<ReturnType>(scope: any, key: string, callback: () => Promise<ReturnType>): Promise<ReturnType>;
export async function withLock<ReturnType>(
scope: any, key: string, acquireLockSignal: AbortSignal | undefined, callback: () => Promise<ReturnType>
export async function withLock<ReturnType, const ScopeType = any>(
scope: ScopeType, key: string, callback: (this: ScopeType) => Promise<ReturnType>
): Promise<ReturnType>;
export async function withLock<ReturnType>(
scope: any,
export async function withLock<ReturnType, const ScopeType = any>(
scope: ScopeType, key: string, acquireLockSignal: AbortSignal | undefined, callback: (this: ScopeType) => Promise<ReturnType>
): Promise<ReturnType>;
export async function withLock<ReturnType, const ScopeType = any>(
scope: ScopeType,
key: string,
acquireLockSignalOrCallback: AbortSignal | undefined | (() => Promise<ReturnType>),
acquireLockSignalOrCallback: AbortSignal | undefined | ((this: ScopeType) => Promise<ReturnType>),
callback?: () => Promise<ReturnType>
): Promise<ReturnType> {
let acquireLockSignal: AbortSignal | undefined = undefined;
Expand Down Expand Up @@ -47,7 +49,7 @@ export async function withLock<ReturnType>(
throw acquireLockSignal.reason;
}

const promise = callback();
const promise = callback.call(scope);

if (!locks.has(scope))
locks.set(scope, new Map());
Expand Down
12 changes: 12 additions & 0 deletions test/withLock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,18 @@ describe("withLock", () => {
// do nothing
}
});

test("this scope works", async () => {
const scope = {data: 1};
const key = "key";

let calls = 0;
await withLock(scope, key, async function (){
expect(this).toBe(scope);
calls++;
});
expect(calls).toBe(1);
});
});


Expand Down

0 comments on commit d2351db

Please sign in to comment.