Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ permissions:

jobs:
publish:
uses: WJSoftware/cicd/.github/workflows/npm-publish.yml@v0.4
uses: WJSoftware/cicd/.github/workflows/npm-publish.yml@main
with:
node-version: 24
build-script: build
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ on:

jobs:
test:
uses: WJSoftware/cicd/.github/workflows/npm-test.yml@v0.4
uses: WJSoftware/cicd/.github/workflows/npm-test.yml@main
with:
node-version: 24
node-version: 26
build-script: build
test-script: test
build: true
4 changes: 2 additions & 2 deletions src/sync/AutoResetEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class AutoResetEvent extends Event {
* @returns `'ok'` when the waiting is over because the token signaled while waiting on it, `'timed-out'` when the
* specified timeout elapsed and the token did not signal, or `'not-equal'` if no wait took place.
*/
static wait(token: Token, timeout?: number) {
static waitSync(token: Token, timeout?: number) {
checkToken(token, ...autoResetEventIdentityData);
// Performance optimization: Blind attempt.
if (Atomics.compareExchange(token, 0, 1, 0) === 1) {
Expand All @@ -57,7 +57,7 @@ export class AutoResetEvent extends Event {
* @returns `'ok'` when the waiting is over because the token signaled while waiting on it, `'timed-out'` when the
* specified timeout elapsed and the token did not signal, or `'not-equal'` if no wait took place.
*/
static async waitAsync(token: Token, timeout?: number) {
static async wait(token: Token, timeout?: number) {
checkToken(token, ...autoResetEventIdentityData);
// Performance optimization: Blind attempt.
if (Atomics.compareExchange(token, 0, 1, 0) === 1) {
Expand Down
12 changes: 6 additions & 6 deletions src/sync/ManualResetEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export function isSignaled(identifierData: IdentifierData, token: Token) {
return Atomics.load(token, 0) === 1;
}

export function wait(identifierData: IdentifierData, token: Token, timeout?: number) {
export function waitSync(identifierData: IdentifierData, token: Token, timeout?: number) {
checkToken(token, ...identifierData);
return Atomics.wait(token, 0, 0, timeout);
}

export async function waitAsync(identifierData: IdentifierData, token: Token, timeout?: number) {
export async function wait(identifierData: IdentifierData, token: Token, timeout?: number) {
checkToken(token, ...identifierData);
const result = Atomics.waitAsync(token, 0, 0, timeout);
return result.async ? await result.value : result.value;
Expand Down Expand Up @@ -52,8 +52,8 @@ export class ManualResetEvent extends Event {
* @returns `'ok'` when the waiting is over because the token signaled while waiting on it, `'timed-out'` when the
* specified timeout elapsed and the token did not signal, or `'not-equal'` if no wait took place.
*/
static wait(token: Token, timeout?: number) {
return wait(manualResetEventIdentityData, token, timeout);
static waitSync(token: Token, timeout?: number) {
return waitSync(manualResetEventIdentityData, token, timeout);
}
/**
* Asynchronously waits on the specified manually-resettable token to be signaled.
Expand All @@ -64,7 +64,7 @@ export class ManualResetEvent extends Event {
* @returns `'ok'` when the waiting is over because the token signaled while waiting on it, `'timed-out'` when the
* specified timeout elapsed and the token did not signal, or `'not-equal'` if no wait took place.
*/
static waitAsync(token: Token, timeout?: number) {
return waitAsync(manualResetEventIdentityData, token, timeout);
static wait(token: Token, timeout?: number) {
return wait(manualResetEventIdentityData, token, timeout);
}
};
16 changes: 8 additions & 8 deletions src/sync/Mutex.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Token } from "../types.js";
import { mutexIdentityData } from "./identifiers.js";
import { acquire, acquireAsync, SemaphoreInternal, type Releaser } from "./Semaphore.js";
import { acquireSync, acquire, SemaphoreInternal, type Releaser } from "./Semaphore.js";

/**
* Synchronization object that can be used to grant a single thread exclusive access to a resource or critical section.
Expand All @@ -19,7 +19,7 @@ export class Mutex extends SemaphoreInternal {
*
* @example
* ```typescript
* const releaser = await Mutex.acquireAsync(myMutexToken);
* const releaser = await Mutex.acquire(myMutexToken);
* try {
* ...
* }
Expand All @@ -30,7 +30,7 @@ export class Mutex extends SemaphoreInternal {
* @param token Mutex token to be acquired.
* @returns A releaser object that can and should be used for releasing the mutex.
*/
static acquire(token: Token): Releaser;
static acquireSync(token: Token): Releaser;
/**
* Acquires exclusivity from the specified mutex's token.
*
Expand All @@ -40,7 +40,7 @@ export class Mutex extends SemaphoreInternal {
*
* @example
* ```typescript
* const releaser = await Mutex.acquireAsync(myMutexToken);
* const releaser = await Mutex.acquireSync(myMutexToken);
* try {
* ...
* }
Expand All @@ -53,11 +53,11 @@ export class Mutex extends SemaphoreInternal {
* @returns A releaser object that can and should be used for releasing the mutex, or the value `'timed-out'` if
* the mutex could not be acquired before the specified timeout time elapsed.
*/
static acquire(token: Token, timeout: number): Releaser | "timed-out";
static acquireSync(token: Token, timeout: number): Releaser | "timed-out";
static acquireSync(token: Token, timeout?: number) {
return acquireSync(mutexIdentityData, token, timeout);
}
static acquire(token: Token, timeout?: number) {
return acquire(mutexIdentityData, token, timeout);
}
static acquireAsync(token: Token, timeout?: number) {
return acquireAsync(mutexIdentityData, token, timeout);
}
};
28 changes: 14 additions & 14 deletions src/sync/Semaphore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function buildReleaser(token: Token) {
}) as Releaser;
}

export function acquire(identifierData: IdentifierData, token: Token, timeout?: number) {
export function acquireSync(identifierData: IdentifierData, token: Token, timeout?: number) {
checkToken(token, ...identifierData);
while (true) {
const available = Atomics.load(token, 0);
Expand All @@ -64,7 +64,7 @@ export function acquire(identifierData: IdentifierData, token: Token, timeout?:
}
}

export async function acquireAsync(identifierData: IdentifierData, token: Token, timeout?: number) {
export async function acquire(identifierData: IdentifierData, token: Token, timeout?: number) {
checkToken(token, ...identifierData);
while (true) {
const available = Atomics.load(token, 0);
Expand Down Expand Up @@ -101,7 +101,7 @@ export class Semaphore extends SemaphoreInternal {
*
* @example
* ```typescript
* const releaser = Semaphore.acquire(mySemaphoreToken);
* const releaser = Semaphore.acquireSync(mySemaphoreToken);
* try {
* ...
* }
Expand All @@ -112,7 +112,7 @@ export class Semaphore extends SemaphoreInternal {
* @param token Semaphore token to be acquired.
* @returns A releaser object that can and should be used for releasing the semaphore.
*/
static acquire(token: Token): Releaser;
static acquireSync(token: Token): Releaser;
/**
* Acquires a slot from the specified semaphore's token.
*
Expand All @@ -122,7 +122,7 @@ export class Semaphore extends SemaphoreInternal {
*
* @example
* ```typescript
* const releaser = Semaphore.acquire(mySemaphoreToken);
* const releaser = Semaphore.acquireSync(mySemaphoreToken);
* try {
* ...
* }
Expand All @@ -135,9 +135,9 @@ export class Semaphore extends SemaphoreInternal {
* @returns A releaser object that can and should be used for releasing the semaphore, or the value `'timed-out'`
* if the sempahore could not be acquired before the specified timeout time elapsed.
*/
static acquire(token: Token, timeout: number): 'timed-out' | Releaser;
static acquire(token: Token, timeout?: number) {
return acquire(semaphoreIdentityData, token, timeout);
static acquireSync(token: Token, timeout: number): 'timed-out' | Releaser;
static acquireSync(token: Token, timeout?: number) {
return acquireSync(semaphoreIdentityData, token, timeout);
}

/**
Expand All @@ -149,7 +149,7 @@ export class Semaphore extends SemaphoreInternal {
*
* @example
* ```typescript
* const releaser = await Semaphore.acquireAsync(mySemaphoreToken);
* const releaser = await Semaphore.acquire(mySemaphoreToken);
* try {
* ...
* }
Expand All @@ -160,7 +160,7 @@ export class Semaphore extends SemaphoreInternal {
* @param token Semaphore token to be acquired.
* @returns A releaser object that can and should be used for releasing the semaphore.
*/
static acquireAsync(token: Token): Promise<Releaser>;
static acquire(token: Token): Promise<Releaser>;
/**
* Asynchronously acquires a slot from the specified semaphore's token.
*
Expand All @@ -170,7 +170,7 @@ export class Semaphore extends SemaphoreInternal {
*
* @example
* ```typescript
* const releaser = await Semaphore.acquireAsync(mySemaphoreToken);
* const releaser = await Semaphore.acquire(mySemaphoreToken);
* try {
* ...
* }
Expand All @@ -183,8 +183,8 @@ export class Semaphore extends SemaphoreInternal {
* @returns A releaser object that can and should be used for releasing the semaphore, or the value `'timed-out'`
* if the sempahore could not be acquired before the specified timeout time elapsed.
*/
static acquireAsync(token: Token, timeout: number): Promise<"timed-out" | Releaser>;
static acquireAsync(token: Token, timeout?: number) {
return acquireAsync(semaphoreIdentityData, token, timeout);
static acquire(token: Token, timeout: number): Promise<"timed-out" | Releaser>;
static acquire(token: Token, timeout?: number) {
return acquire(semaphoreIdentityData, token, timeout);
}
}
22 changes: 11 additions & 11 deletions tests/ut/sync/AutoResetEvent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,22 @@ describe('AutoResetEvent', () => {
});
});

describe('static wait', () => {
describe('static waitSync', () => {
it('Should throw when the given token is not the token of an AutoResetEvent object.', () => {
const foreignEvent = new ManualResetEvent();

expect(() => AutoResetEvent.wait(foreignEvent.token)).toThrow();
expect(() => AutoResetEvent.waitSync(foreignEvent.token)).toThrow();
});

it('Should handle timeout.', () => {
const result = AutoResetEvent.wait(eventObj.token, 10);
const result = AutoResetEvent.waitSync(eventObj.token, 10);

expect(result).toBe('timed-out');
});

it('Should handle immediate success when already signaled.', () => {
eventObj.signal();
const result = AutoResetEvent.wait(eventObj.token);
const result = AutoResetEvent.waitSync(eventObj.token);

expect(result).toBe('not-equal');
// Verify the event auto-reset (signal was consumed)
Expand All @@ -102,37 +102,37 @@ describe('AutoResetEvent', () => {
});
});

describe('static waitAsync', () => {
it('Should throw when the given token is not the token of an AutoResetEvent object.', () => {
describe('static wait', () => {
it('Should throw when the given token is not the token of an AutoResetEvent object.', async () => {
const foreignEvent = new ManualResetEvent();

expect(() => AutoResetEvent.wait(foreignEvent.token)).toThrow();
await expect(AutoResetEvent.wait(foreignEvent.token)).rejects.toThrow();
});
it('Should handle async wait result.', async () => {
// Signal the event after a short delay to test async wait
setTimeout(() => {
eventObj.signal();
}, 0);

const result = await AutoResetEvent.waitAsync(eventObj.token, 1000);
const result = await AutoResetEvent.wait(eventObj.token, 1000);

expect(result).toBe('ok');
expect(Atomics.load(eventObj.token, 0)).toBe(0);
});

it('Should handle sync wait result.', async () => {
// Pre-signal the event so waitAsync returns immediately
// Pre-signal the event so wait returns immediately
eventObj.signal();

const result = await AutoResetEvent.waitAsync(eventObj.token);
const result = await AutoResetEvent.wait(eventObj.token);

expect(result).toBe('not-equal');
// Verify the event auto-reset (signal was consumed)
expect(Atomics.load(eventObj.token, 0)).toBe(0);
});

it('Should handle timeout in async wait.', async () => {
const result = await AutoResetEvent.waitAsync(eventObj.token, 10);
const result = await AutoResetEvent.wait(eventObj.token, 10);

expect(result).toBe('timed-out');
});
Expand Down
20 changes: 10 additions & 10 deletions tests/ut/sync/ManualResetEvent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,18 @@ describe('ManualResetEvent', () => {
tokenTypeTest(AutoResetEvent, ManualResetEvent.isSignaled, ManualResetEvent);
});

describe('static wait', () => {
tokenTypeTest(AutoResetEvent, ManualResetEvent.wait, ManualResetEvent);
describe('static waitSync', () => {
tokenTypeTest(AutoResetEvent, ManualResetEvent.waitSync, ManualResetEvent);

it('Should handle timeout.', () => {
const result = ManualResetEvent.wait(eventObj.token, 10);
const result = ManualResetEvent.waitSync(eventObj.token, 10);

expect(result).toBe('timed-out');
});

it('Should handle immediate success when already signaled.', () => {
eventObj.signal();
const result = ManualResetEvent.wait(eventObj.token);
const result = ManualResetEvent.waitSync(eventObj.token);
expect(result).toBe('not-equal');
});

Expand All @@ -94,30 +94,30 @@ describe('ManualResetEvent', () => {
});
});

describe('static waitAsync', () => {
tokenTypeTest(AutoResetEvent, ManualResetEvent.waitAsync, ManualResetEvent);
describe('static wait', () => {
tokenTypeTest(AutoResetEvent, ManualResetEvent.wait, ManualResetEvent);
it('Should handle async wait result.', async () => {
// Signal the event after a short delay to test async wait
setTimeout(() => {
eventObj.signal();
}, 0);

const result = await ManualResetEvent.waitAsync(eventObj.token, 10);
const result = await ManualResetEvent.wait(eventObj.token, 10);

expect(result).toBe('ok');
});

it('Should handle sync wait result.', async () => {
// Pre-signal the event so waitAsync returns immediately
// Pre-signal the event so wait returns immediately
eventObj.signal();

const result = await ManualResetEvent.waitAsync(eventObj.token);
const result = await ManualResetEvent.wait(eventObj.token);

expect(result).toBe('not-equal');
});

it('Should handle timeout in async wait.', async () => {
const result = await ManualResetEvent.waitAsync(eventObj.token, 10);
const result = await ManualResetEvent.wait(eventObj.token, 10);

expect(result).toBe('timed-out');
});
Expand Down
Loading
Loading