Skip to content

Commit

Permalink
fix: Support parameters in setTimeout and setInterval (#2513)
Browse files Browse the repository at this point in the history
Tiny fix to support parameters in `setTimeout` and `setInterval`. This
increases compatibility with ecosystem code that may use this
functionality and was an oversight to not support initially.
  • Loading branch information
FrederikBolding authored Jun 24, 2024
1 parent 8ab64ec commit 62dbfb6
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ describe('Interval endowments', () => {
expect(await promise).toBeUndefined();
});

it('should be able to use parameters', async () => {
const { setInterval: _setInterval } = interval.factory();

const promise = new Promise((resolve) => {
_setInterval(resolve, 200, 'foo');
});

jest.advanceTimersByTime(300);

expect(await promise).toBe('foo');
});

it('teardownFunction should clear intervals', async () => {
const { setInterval: _setInterval, teardownFunction } = interval.factory();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ const MINIMUM_INTERVAL = 10;
const createInterval = () => {
const registeredHandles = new Map<unknown, unknown>();

const _setInterval = (handler: TimerHandler, timeout?: number): unknown => {
const _setInterval = (
handler: TimerHandler,
timeout?: number,
...args: any[]
): unknown => {
if (typeof handler !== 'function') {
throw rpcErrors.invalidInput(
`The interval handler must be a function. Received: ${typeof handler}.`,
Expand All @@ -26,6 +30,7 @@ const createInterval = () => {
const platformHandle = setInterval(
handler,
Math.max(MINIMUM_INTERVAL, timeout ?? 0),
...args,
);
registeredHandles.set(handle, platformHandle);
return handle;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ describe('Timeout endowments', () => {
).toBeUndefined();
}, 300);

it('should be able to use parameters', async () => {
const { setTimeout: _setTimeout } = timeout.factory();

expect(
await new Promise((resolve) => {
_setTimeout(resolve, 200, 'foo');
}),
).toBe('foo');
}, 300);

it('teardownFunction should clear timeouts', async () => {
const { setTimeout: _setTimeout, teardownFunction } = timeout.factory();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,26 @@ const MINIMUM_TIMEOUT = 10;
*/
const createTimeout = () => {
const registeredHandles = new Map<unknown, unknown>();
const _setTimeout = (handler: TimerHandler, timeout?: number): unknown => {
const _setTimeout = (
handler: TimerHandler,
timeout?: number,
...args: any[]
): unknown => {
if (typeof handler !== 'function') {
throw rpcErrors.internal(
`The timeout handler must be a function. Received: ${typeof handler}.`,
);
}
harden(handler);
const handle = Object.freeze(Object.create(null));
const platformHandle = setTimeout(() => {
registeredHandles.delete(handle);
handler();
}, Math.max(MINIMUM_TIMEOUT, timeout ?? 0));
const platformHandle = setTimeout(
(...passedArgs) => {
registeredHandles.delete(handle);
handler(...passedArgs);
},
Math.max(MINIMUM_TIMEOUT, timeout ?? 0),
...args,
);

registeredHandles.set(handle, platformHandle);
return handle;
Expand Down

0 comments on commit 62dbfb6

Please sign in to comment.