worker-timers-broker
Advanced tools
Comparing version 7.1.9 to 8.0.0
@@ -1,7 +0,6 @@ | ||
export declare const load: (url: string) => { | ||
clearInterval: (timerId: number) => void; | ||
clearTimeout: (timerId: number) => void; | ||
setInterval: (func: Function, delay?: number, ...args: any[]) => number; | ||
setTimeout: (func: Function, delay?: number, ...args: any[]) => number; | ||
}; | ||
import { TWorkerTimersBrokerLoader, TWorkerTimersBrokerWrapper } from './types'; | ||
export * from './interfaces/index'; | ||
export * from './types/index'; | ||
export declare const wrap: TWorkerTimersBrokerWrapper; | ||
export declare const load: TWorkerTimersBrokerLoader; | ||
//# sourceMappingURL=module.d.ts.map |
@@ -0,116 +1,39 @@ | ||
import { createBroker } from 'broker-factory'; | ||
import { generateUniqueNumber } from 'fast-unique-numbers'; | ||
import { isCallNotification } from './guards/call-notification'; | ||
import { isClearResponse } from './guards/clear-response'; | ||
export const load = (url) => { | ||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. | ||
const scheduledIntervalFunctions = new Map([[0, () => { }]]); // tslint:disable-line no-empty | ||
const scheduledTimeoutFunctions = new Map([[0, () => { }]]); // tslint:disable-line no-empty | ||
const unrespondedRequests = new Map(); | ||
const worker = new Worker(url); | ||
worker.addEventListener('message', ({ data }) => { | ||
if (isCallNotification(data)) { | ||
const { params: { timerId, timerType } } = data; | ||
if (timerType === 'interval') { | ||
const idOrFunc = scheduledIntervalFunctions.get(timerId); | ||
if (typeof idOrFunc === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (typeof idOrFunc === 'number') { | ||
const timerIdAndTimerType = unrespondedRequests.get(idOrFunc); | ||
if (timerIdAndTimerType === undefined || | ||
timerIdAndTimerType.timerId !== timerId || | ||
timerIdAndTimerType.timerType !== timerType) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
} | ||
else if (typeof idOrFunc === 'function') { | ||
idOrFunc(); | ||
} | ||
/* | ||
* @todo Explicitly referencing the barrel file seems to be necessary when enabling the | ||
* isolatedModules compiler option. | ||
*/ | ||
export * from './interfaces/index'; | ||
export * from './types/index'; | ||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. | ||
const scheduledIntervalsState = new Map([[0, null]]); // tslint:disable-line no-empty | ||
const scheduledTimeoutsState = new Map([[0, null]]); // tslint:disable-line no-empty | ||
export const wrap = createBroker({ | ||
clearInterval: ({ call }) => { | ||
return (timerId) => { | ||
if (typeof scheduledIntervalsState.get(timerId) === 'symbol') { | ||
scheduledIntervalsState.set(timerId, null); | ||
call('clear', { timerId, timerType: 'interval' }).then(() => { | ||
scheduledIntervalsState.delete(timerId); | ||
}); | ||
} | ||
else if (timerType === 'timeout') { | ||
const idOrFunc = scheduledTimeoutFunctions.get(timerId); | ||
if (typeof idOrFunc === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (typeof idOrFunc === 'number') { | ||
const timerIdAndTimerType = unrespondedRequests.get(idOrFunc); | ||
if (timerIdAndTimerType === undefined || | ||
timerIdAndTimerType.timerId !== timerId || | ||
timerIdAndTimerType.timerType !== timerType) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
} | ||
else if (typeof idOrFunc === 'function') { | ||
idOrFunc(); | ||
// A timeout can be savely deleted because it is only called once. | ||
scheduledTimeoutFunctions.delete(timerId); | ||
} | ||
} | ||
} | ||
else if (isClearResponse(data)) { | ||
const { id } = data; | ||
const timerIdAndTimerType = unrespondedRequests.get(id); | ||
if (timerIdAndTimerType === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
const { timerId, timerType } = timerIdAndTimerType; | ||
unrespondedRequests.delete(id); | ||
if (timerType === 'interval') { | ||
scheduledIntervalFunctions.delete(timerId); | ||
} | ||
else { | ||
scheduledTimeoutFunctions.delete(timerId); | ||
} | ||
} | ||
else { | ||
const { error: { message } } = data; | ||
throw new Error(message); | ||
} | ||
}); | ||
const clearInterval = (timerId) => { | ||
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') { | ||
const id = generateUniqueNumber(unrespondedRequests); | ||
unrespondedRequests.set(id, { timerId, timerType: 'interval' }); | ||
scheduledIntervalFunctions.set(timerId, id); | ||
worker.postMessage({ | ||
id, | ||
method: 'clear', | ||
params: { timerId, timerType: 'interval' } | ||
}); | ||
} | ||
}; | ||
const clearTimeout = (timerId) => { | ||
if (typeof scheduledTimeoutFunctions.get(timerId) === 'function') { | ||
const id = generateUniqueNumber(unrespondedRequests); | ||
unrespondedRequests.set(id, { timerId, timerType: 'timeout' }); | ||
scheduledTimeoutFunctions.set(timerId, id); | ||
worker.postMessage({ | ||
id, | ||
method: 'clear', | ||
params: { timerId, timerType: 'timeout' } | ||
}); | ||
} | ||
}; | ||
const setInterval = (func, delay = 0, ...args) => { | ||
const timerId = generateUniqueNumber(scheduledIntervalFunctions); | ||
scheduledIntervalFunctions.set(timerId, () => { | ||
func(...args); | ||
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). | ||
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') { | ||
worker.postMessage({ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId, | ||
timerType: 'interval' | ||
} | ||
}; | ||
}, | ||
clearTimeout: ({ call }) => { | ||
return (timerId) => { | ||
if (typeof scheduledTimeoutsState.get(timerId) === 'symbol') { | ||
scheduledTimeoutsState.set(timerId, null); | ||
call('clear', { timerId, timerType: 'timeout' }).then(() => { | ||
scheduledTimeoutsState.delete(timerId); | ||
}); | ||
} | ||
}); | ||
worker.postMessage({ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
}; | ||
}, | ||
setInterval: ({ call }) => { | ||
return (func, delay = 0, ...args) => { | ||
const symbol = Symbol(); | ||
const timerId = generateUniqueNumber(scheduledIntervalsState); | ||
scheduledIntervalsState.set(timerId, symbol); | ||
const schedule = () => call('set', { | ||
delay, | ||
@@ -120,13 +43,25 @@ now: performance.timeOrigin + performance.now(), | ||
timerType: 'interval' | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
const setTimeout = (func, delay = 0, ...args) => { | ||
const timerId = generateUniqueNumber(scheduledTimeoutFunctions); | ||
scheduledTimeoutFunctions.set(timerId, () => func(...args)); | ||
worker.postMessage({ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
}).then(() => { | ||
const state = scheduledIntervalsState.get(timerId); | ||
if (typeof state === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (state === symbol) { | ||
func(...args); | ||
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). | ||
if (scheduledIntervalsState.get(timerId) === symbol) { | ||
schedule(); | ||
} | ||
} | ||
}); | ||
schedule(); | ||
return timerId; | ||
}; | ||
}, | ||
setTimeout: ({ call }) => { | ||
return (func, delay = 0, ...args) => { | ||
const symbol = Symbol(); | ||
const timerId = generateUniqueNumber(scheduledTimeoutsState); | ||
scheduledTimeoutsState.set(timerId, symbol); | ||
call('set', { | ||
delay, | ||
@@ -136,13 +71,21 @@ now: performance.timeOrigin + performance.now(), | ||
timerType: 'timeout' | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
return { | ||
clearInterval, | ||
clearTimeout, | ||
setInterval, | ||
setTimeout | ||
}; | ||
}).then(() => { | ||
const state = scheduledTimeoutsState.get(timerId); | ||
if (typeof state === 'undefined') { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (state === symbol) { | ||
// A timeout can be savely deleted because it is only called once. | ||
scheduledTimeoutsState.delete(timerId); | ||
func(...args); | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
} | ||
}); | ||
export const load = (url) => { | ||
const worker = new Worker(url); | ||
return wrap(worker); | ||
}; | ||
//# sourceMappingURL=module.js.map |
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime/helpers/typeof'), require('fast-unique-numbers')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime/helpers/typeof', 'fast-unique-numbers'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.workerTimersBroker = {}, global._typeof, global.fastUniqueNumbers)); | ||
})(this, (function (exports, _typeof, fastUniqueNumbers) { 'use strict'; | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@babel/runtime/helpers/typeof'), require('broker-factory'), require('fast-unique-numbers')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@babel/runtime/helpers/typeof', 'broker-factory', 'fast-unique-numbers'], factory) : | ||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.workerTimersBroker = {}, global._typeof, global.brokerFactory, global.fastUniqueNumbers)); | ||
})(this, (function (exports, _typeof, brokerFactory, fastUniqueNumbers) { 'use strict'; | ||
var isCallNotification = function isCallNotification(message) { | ||
return message.method !== undefined && message.method === 'call'; | ||
}; | ||
var isClearResponse = function isClearResponse(message) { | ||
return typeof message.id === 'number' && typeof message.result === 'boolean'; | ||
}; | ||
var load = function load(url) { | ||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. | ||
var scheduledIntervalFunctions = new Map([[0, function () {}]]); // tslint:disable-line no-empty | ||
var scheduledTimeoutFunctions = new Map([[0, function () {}]]); // tslint:disable-line no-empty | ||
var unrespondedRequests = new Map(); | ||
var worker = new Worker(url); | ||
worker.addEventListener('message', function (_ref) { | ||
var data = _ref.data; | ||
if (isCallNotification(data)) { | ||
var _data$params = data.params, | ||
timerId = _data$params.timerId, | ||
timerType = _data$params.timerType; | ||
if (timerType === 'interval') { | ||
var idOrFunc = scheduledIntervalFunctions.get(timerId); | ||
if (_typeof(idOrFunc) === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (typeof idOrFunc === 'number') { | ||
var timerIdAndTimerType = unrespondedRequests.get(idOrFunc); | ||
if (timerIdAndTimerType === undefined || timerIdAndTimerType.timerId !== timerId || timerIdAndTimerType.timerType !== timerType) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
} else if (typeof idOrFunc === 'function') { | ||
idOrFunc(); | ||
} | ||
} else if (timerType === 'timeout') { | ||
var _idOrFunc = scheduledTimeoutFunctions.get(timerId); | ||
if (_typeof(_idOrFunc) === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (typeof _idOrFunc === 'number') { | ||
var _timerIdAndTimerType = unrespondedRequests.get(_idOrFunc); | ||
if (_timerIdAndTimerType === undefined || _timerIdAndTimerType.timerId !== timerId || _timerIdAndTimerType.timerType !== timerType) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
} else if (typeof _idOrFunc === 'function') { | ||
_idOrFunc(); | ||
// A timeout can be savely deleted because it is only called once. | ||
scheduledTimeoutFunctions["delete"](timerId); | ||
} | ||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. | ||
var scheduledIntervalsState = new Map([[0, null]]); // tslint:disable-line no-empty | ||
var scheduledTimeoutsState = new Map([[0, null]]); // tslint:disable-line no-empty | ||
var wrap = brokerFactory.createBroker({ | ||
clearInterval: function clearInterval(_ref) { | ||
var call = _ref.call; | ||
return function (timerId) { | ||
if (_typeof(scheduledIntervalsState.get(timerId)) === 'symbol') { | ||
scheduledIntervalsState.set(timerId, null); | ||
call('clear', { | ||
timerId: timerId, | ||
timerType: 'interval' | ||
}).then(function () { | ||
scheduledIntervalsState["delete"](timerId); | ||
}); | ||
} | ||
} else if (isClearResponse(data)) { | ||
var id = data.id; | ||
var _timerIdAndTimerType2 = unrespondedRequests.get(id); | ||
if (_timerIdAndTimerType2 === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
}; | ||
}, | ||
clearTimeout: function clearTimeout(_ref2) { | ||
var call = _ref2.call; | ||
return function (timerId) { | ||
if (_typeof(scheduledTimeoutsState.get(timerId)) === 'symbol') { | ||
scheduledTimeoutsState.set(timerId, null); | ||
call('clear', { | ||
timerId: timerId, | ||
timerType: 'timeout' | ||
}).then(function () { | ||
scheduledTimeoutsState["delete"](timerId); | ||
}); | ||
} | ||
var _timerId = _timerIdAndTimerType2.timerId, | ||
_timerType = _timerIdAndTimerType2.timerType; | ||
unrespondedRequests["delete"](id); | ||
if (_timerType === 'interval') { | ||
scheduledIntervalFunctions["delete"](_timerId); | ||
} else { | ||
scheduledTimeoutFunctions["delete"](_timerId); | ||
}; | ||
}, | ||
setInterval: function setInterval(_ref3) { | ||
var call = _ref3.call; | ||
return function (func) { | ||
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
} else { | ||
var message = data.error.message; | ||
throw new Error(message); | ||
} | ||
}); | ||
var clearInterval = function clearInterval(timerId) { | ||
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') { | ||
var id = fastUniqueNumbers.generateUniqueNumber(unrespondedRequests); | ||
unrespondedRequests.set(id, { | ||
timerId: timerId, | ||
timerType: 'interval' | ||
}); | ||
scheduledIntervalFunctions.set(timerId, id); | ||
worker.postMessage({ | ||
id: id, | ||
method: 'clear', | ||
params: { | ||
var symbol = Symbol(); | ||
var timerId = fastUniqueNumbers.generateUniqueNumber(scheduledIntervalsState); | ||
scheduledIntervalsState.set(timerId, symbol); | ||
var _schedule = function schedule() { | ||
return call('set', { | ||
delay: delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId: timerId, | ||
timerType: 'interval' | ||
} | ||
}); | ||
} | ||
}; | ||
var clearTimeout = function clearTimeout(timerId) { | ||
if (typeof scheduledTimeoutFunctions.get(timerId) === 'function') { | ||
var id = fastUniqueNumbers.generateUniqueNumber(unrespondedRequests); | ||
unrespondedRequests.set(id, { | ||
timerId: timerId, | ||
timerType: 'timeout' | ||
}); | ||
scheduledTimeoutFunctions.set(timerId, id); | ||
worker.postMessage({ | ||
id: id, | ||
method: 'clear', | ||
params: { | ||
timerId: timerId, | ||
timerType: 'timeout' | ||
} | ||
}); | ||
} | ||
}; | ||
var setInterval = function setInterval(func) { | ||
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { | ||
args[_key - 2] = arguments[_key]; | ||
} | ||
var timerId = fastUniqueNumbers.generateUniqueNumber(scheduledIntervalFunctions); | ||
scheduledIntervalFunctions.set(timerId, function () { | ||
func.apply(undefined, args); | ||
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). | ||
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') { | ||
worker.postMessage({ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
delay: delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId: timerId, | ||
timerType: 'interval' | ||
}).then(function () { | ||
var state = scheduledIntervalsState.get(timerId); | ||
if (_typeof(state) === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (state === symbol) { | ||
func.apply(void 0, args); | ||
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). | ||
if (scheduledIntervalsState.get(timerId) === symbol) { | ||
_schedule(); | ||
} | ||
} | ||
}); | ||
}; | ||
_schedule(); | ||
return timerId; | ||
}; | ||
}, | ||
setTimeout: function setTimeout(_ref4) { | ||
var call = _ref4.call; | ||
return function (func) { | ||
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { | ||
args[_key2 - 2] = arguments[_key2]; | ||
} | ||
}); | ||
worker.postMessage({ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
var symbol = Symbol(); | ||
var timerId = fastUniqueNumbers.generateUniqueNumber(scheduledTimeoutsState); | ||
scheduledTimeoutsState.set(timerId, symbol); | ||
call('set', { | ||
delay: delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId: timerId, | ||
timerType: 'interval' | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
var setTimeout = function setTimeout(func) { | ||
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { | ||
args[_key2 - 2] = arguments[_key2]; | ||
} | ||
var timerId = fastUniqueNumbers.generateUniqueNumber(scheduledTimeoutFunctions); | ||
scheduledTimeoutFunctions.set(timerId, function () { | ||
return func.apply(undefined, args); | ||
}); | ||
worker.postMessage({ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
delay: delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId: timerId, | ||
timerType: 'timeout' | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
return { | ||
clearInterval: clearInterval, | ||
clearTimeout: clearTimeout, | ||
setInterval: setInterval, | ||
setTimeout: setTimeout | ||
}; | ||
}).then(function () { | ||
var state = scheduledTimeoutsState.get(timerId); | ||
if (typeof state === 'undefined') { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (state === symbol) { | ||
// A timeout can be savely deleted because it is only called once. | ||
scheduledTimeoutsState["delete"](timerId); | ||
func.apply(void 0, args); | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
} | ||
}); | ||
var load = function load(url) { | ||
var worker = new Worker(url); | ||
return wrap(worker); | ||
}; | ||
exports.load = load; | ||
exports.wrap = wrap; | ||
})); |
@@ -12,15 +12,16 @@ { | ||
"dependencies": { | ||
"@babel/runtime": "^7.26.0", | ||
"@babel/runtime": "^7.26.7", | ||
"broker-factory": "^3.1.0", | ||
"fast-unique-numbers": "^9.0.15", | ||
"tslib": "^2.8.1", | ||
"worker-timers-worker": "^8.0.10" | ||
"worker-timers-worker": "^9.0.0" | ||
}, | ||
"description": "The broker which is used by the worker-timers package.", | ||
"devDependencies": { | ||
"@babel/core": "^7.26.0", | ||
"@babel/core": "^7.26.8", | ||
"@babel/plugin-external-helpers": "^7.25.9", | ||
"@babel/plugin-transform-runtime": "^7.25.9", | ||
"@babel/preset-env": "^7.26.0", | ||
"@commitlint/cli": "^19.6.1", | ||
"@commitlint/config-angular": "^19.7.0", | ||
"@babel/plugin-transform-runtime": "^7.26.8", | ||
"@babel/preset-env": "^7.26.8", | ||
"@commitlint/cli": "^19.7.1", | ||
"@commitlint/config-angular": "^19.7.1", | ||
"@rollup/plugin-babel": "^6.0.4", | ||
@@ -44,15 +45,15 @@ "chai": "^4.3.10", | ||
"karma-webpack": "^5.0.1", | ||
"lint-staged": "^15.3.0", | ||
"lint-staged": "^15.4.3", | ||
"load-grunt-config": "^4.0.1", | ||
"mocha": "^10.8.2", | ||
"prettier": "^3.4.2", | ||
"prettier": "^3.5.0", | ||
"rimraf": "^6.0.1", | ||
"rollup": "^4.30.0", | ||
"rollup": "^4.34.6", | ||
"sinon": "^17.0.2", | ||
"sinon-chai": "^3.7.0", | ||
"ts-loader": "^9.5.1", | ||
"ts-loader": "^9.5.2", | ||
"tsconfig-holy-grail": "^15.0.2", | ||
"tslint": "^6.1.3", | ||
"tslint-config-holy-grail": "^56.0.6", | ||
"typescript": "^5.7.2", | ||
"typescript": "^5.7.3", | ||
"webpack": "^5.97.1" | ||
@@ -85,3 +86,3 @@ }, | ||
"types": "build/es2019/module.d.ts", | ||
"version": "7.1.9" | ||
"version": "8.0.0" | ||
} |
@@ -0,181 +1,112 @@ | ||
import { createBroker } from 'broker-factory'; | ||
import { generateUniqueNumber } from 'fast-unique-numbers'; | ||
import { IClearRequest, ISetNotification, IWorkerEvent, TTimerType } from 'worker-timers-worker'; | ||
import { isCallNotification } from './guards/call-notification'; | ||
import { isClearResponse } from './guards/clear-response'; | ||
import { TWorkerTimersWorkerDefinition } from 'worker-timers-worker'; | ||
import { IWorkerTimersBrokerDefinition } from './interfaces'; | ||
import { TWorkerTimersBrokerLoader, TWorkerTimersBrokerWrapper } from './types'; | ||
export const load = (url: string) => { | ||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. | ||
const scheduledIntervalFunctions: Map<number, number | Function> = new Map([[0, () => {}]]); // tslint:disable-line no-empty | ||
const scheduledTimeoutFunctions: Map<number, number | Function> = new Map([[0, () => {}]]); // tslint:disable-line no-empty | ||
const unrespondedRequests: Map<number, { timerId: number; timerType: TTimerType }> = new Map(); | ||
/* | ||
* @todo Explicitly referencing the barrel file seems to be necessary when enabling the | ||
* isolatedModules compiler option. | ||
*/ | ||
export * from './interfaces/index'; | ||
export * from './types/index'; | ||
const worker = new Worker(url); | ||
// Prefilling the Maps with a function indexed by zero is necessary to be compliant with the specification. | ||
const scheduledIntervalsState: Map<number, null | symbol> = new Map([[0, null]]); // tslint:disable-line no-empty | ||
const scheduledTimeoutsState: Map<number, null | symbol> = new Map([[0, null]]); // tslint:disable-line no-empty | ||
worker.addEventListener('message', ({ data }: IWorkerEvent) => { | ||
if (isCallNotification(data)) { | ||
const { | ||
params: { timerId, timerType } | ||
} = data; | ||
export const wrap: TWorkerTimersBrokerWrapper = createBroker<IWorkerTimersBrokerDefinition, TWorkerTimersWorkerDefinition>({ | ||
clearInterval: ({ call }) => { | ||
return (timerId) => { | ||
if (typeof scheduledIntervalsState.get(timerId) === 'symbol') { | ||
scheduledIntervalsState.set(timerId, null); | ||
if (timerType === 'interval') { | ||
const idOrFunc = scheduledIntervalFunctions.get(timerId); | ||
call('clear', { timerId, timerType: 'interval' }).then(() => { | ||
scheduledIntervalsState.delete(timerId); | ||
}); | ||
} | ||
}; | ||
}, | ||
clearTimeout: ({ call }) => { | ||
return (timerId) => { | ||
if (typeof scheduledTimeoutsState.get(timerId) === 'symbol') { | ||
scheduledTimeoutsState.set(timerId, null); | ||
if (typeof idOrFunc === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
call('clear', { timerId, timerType: 'timeout' }).then(() => { | ||
scheduledTimeoutsState.delete(timerId); | ||
}); | ||
} | ||
}; | ||
}, | ||
setInterval: ({ call }) => { | ||
return (func: Function, delay = 0, ...args: any[]) => { | ||
const symbol = Symbol(); | ||
const timerId = generateUniqueNumber(scheduledIntervalsState); | ||
if (typeof idOrFunc === 'number') { | ||
const timerIdAndTimerType = unrespondedRequests.get(idOrFunc); | ||
scheduledIntervalsState.set(timerId, symbol); | ||
if ( | ||
timerIdAndTimerType === undefined || | ||
timerIdAndTimerType.timerId !== timerId || | ||
timerIdAndTimerType.timerType !== timerType | ||
) { | ||
const schedule = () => | ||
call('set', { | ||
delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId, | ||
timerType: 'interval' | ||
}).then(() => { | ||
const state = scheduledIntervalsState.get(timerId); | ||
if (typeof state === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
} else if (typeof idOrFunc === 'function') { | ||
idOrFunc(); | ||
} | ||
} else if (timerType === 'timeout') { | ||
const idOrFunc = scheduledTimeoutFunctions.get(timerId); | ||
if (typeof idOrFunc === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
if (state === symbol) { | ||
func(...args); | ||
if (typeof idOrFunc === 'number') { | ||
const timerIdAndTimerType = unrespondedRequests.get(idOrFunc); | ||
if ( | ||
timerIdAndTimerType === undefined || | ||
timerIdAndTimerType.timerId !== timerId || | ||
timerIdAndTimerType.timerType !== timerType | ||
) { | ||
throw new Error('The timer is in an undefined state.'); | ||
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). | ||
if (scheduledIntervalsState.get(timerId) === symbol) { | ||
schedule(); | ||
} | ||
} | ||
} else if (typeof idOrFunc === 'function') { | ||
idOrFunc(); | ||
}); | ||
// A timeout can be savely deleted because it is only called once. | ||
scheduledTimeoutFunctions.delete(timerId); | ||
} | ||
} | ||
} else if (isClearResponse(data)) { | ||
const { id } = data; | ||
schedule(); | ||
const timerIdAndTimerType = unrespondedRequests.get(id); | ||
return timerId; | ||
}; | ||
}, | ||
setTimeout: ({ call }) => { | ||
return (func: Function, delay = 0, ...args: any[]) => { | ||
const symbol = Symbol(); | ||
const timerId = generateUniqueNumber(scheduledTimeoutsState); | ||
if (timerIdAndTimerType === undefined) { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
scheduledTimeoutsState.set(timerId, symbol); | ||
const { timerId, timerType } = timerIdAndTimerType; | ||
unrespondedRequests.delete(id); | ||
if (timerType === 'interval') { | ||
scheduledIntervalFunctions.delete(timerId); | ||
} else { | ||
scheduledTimeoutFunctions.delete(timerId); | ||
} | ||
} else { | ||
const { | ||
error: { message } | ||
} = data; | ||
throw new Error(message); | ||
} | ||
}); | ||
const clearInterval = (timerId: number) => { | ||
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') { | ||
const id = generateUniqueNumber(unrespondedRequests); | ||
unrespondedRequests.set(id, { timerId, timerType: 'interval' }); | ||
scheduledIntervalFunctions.set(timerId, id); | ||
worker.postMessage(<IClearRequest>{ | ||
id, | ||
method: 'clear', | ||
params: { timerId, timerType: 'interval' } | ||
}); | ||
} | ||
}; | ||
const clearTimeout = (timerId: number) => { | ||
if (typeof scheduledTimeoutFunctions.get(timerId) === 'function') { | ||
const id = generateUniqueNumber(unrespondedRequests); | ||
unrespondedRequests.set(id, { timerId, timerType: 'timeout' }); | ||
scheduledTimeoutFunctions.set(timerId, id); | ||
worker.postMessage(<IClearRequest>{ | ||
id, | ||
method: 'clear', | ||
params: { timerId, timerType: 'timeout' } | ||
}); | ||
} | ||
}; | ||
const setInterval = (func: Function, delay = 0, ...args: any[]) => { | ||
const timerId = generateUniqueNumber(scheduledIntervalFunctions); | ||
scheduledIntervalFunctions.set(timerId, () => { | ||
func(...args); | ||
// Doublecheck if the interval should still be rescheduled because it could have been cleared inside of func(). | ||
if (typeof scheduledIntervalFunctions.get(timerId) === 'function') { | ||
worker.postMessage(<ISetNotification>{ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId, | ||
timerType: 'interval' | ||
} | ||
}); | ||
} | ||
}); | ||
worker.postMessage(<ISetNotification>{ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
call('set', { | ||
delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId, | ||
timerType: 'interval' | ||
} | ||
}); | ||
timerType: 'timeout' | ||
}).then(() => { | ||
const state = scheduledTimeoutsState.get(timerId); | ||
return timerId; | ||
}; | ||
if (typeof state === 'undefined') { | ||
throw new Error('The timer is in an undefined state.'); | ||
} | ||
const setTimeout = (func: Function, delay = 0, ...args: any[]) => { | ||
const timerId = generateUniqueNumber(scheduledTimeoutFunctions); | ||
if (state === symbol) { | ||
// A timeout can be savely deleted because it is only called once. | ||
scheduledTimeoutsState.delete(timerId); | ||
scheduledTimeoutFunctions.set(timerId, () => func(...args)); | ||
func(...args); | ||
} | ||
}); | ||
worker.postMessage(<ISetNotification>{ | ||
id: null, | ||
method: 'set', | ||
params: { | ||
delay, | ||
now: performance.timeOrigin + performance.now(), | ||
timerId, | ||
timerType: 'timeout' | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
} | ||
}); | ||
return timerId; | ||
}; | ||
export const load: TWorkerTimersBrokerLoader = (url: string) => { | ||
const worker = new Worker(url); | ||
return { | ||
clearInterval, | ||
clearTimeout, | ||
setInterval, | ||
setTimeout | ||
}; | ||
return wrap(worker); | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
35
25958
5
337
1
+ Addedbroker-factory@^3.1.0
+ Added@babel/runtime@7.26.9(transitive)
+ Addedbroker-factory@3.1.0(transitive)
+ Addedworker-factory@7.0.36(transitive)
+ Addedworker-timers-worker@9.0.0(transitive)
- Removed@babel/runtime@7.26.7(transitive)
- Removedworker-timers-worker@8.0.10(transitive)
Updated@babel/runtime@^7.26.7
Updatedworker-timers-worker@^9.0.0