Socket
Socket
Sign inDemoInstall

scheduler-polyfill

Package Overview
Dependencies
0
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.2.1 to 1.3.0-beta.0

2

dist/scheduler-polyfill.js

@@ -1,2 +0,2 @@

!function(){var e=["user-blocking","user-visible","background"];class t{constructor(){this.channel_=new MessageChannel,this.sendPort_=this.channel_.port2,this.messages_={},this.nextMessageHandle_=1,this.channel_.port1.onmessage=e=>this.onMessageReceived_(e)}queueCallback(e){var t=this.nextMessageHandle_++;return this.messages_[t]=e,this.sendPort_.postMessage(t),t}cancelCallback(e){delete this.messages_[e]}onMessageReceived_(e){var t=e.data;if(t in this.messages_){var i=this.messages_[t];delete this.messages_[t],i()}}}function i(){return i.instance_||(i.instance_=new t),i.instance_}class s{constructor(e,t,i){void 0===i&&(i=0),this.callback_=e,this.callbackType_=null,this.handle_=null,this.canceled_=!1,this.schedule_(t,i)}isIdleCallback(){return 0===this.callbackType_}isMessageChannelCallback(){return 2===this.callbackType_}cancel(){if(!this.canceled_)switch(this.canceled_=!0,this.callbackType_){case 0:cancelIdleCallback(this.handle_);break;case 1:clearTimeout(this.handle_);break;case 2:i().cancelCallback(this.handle_);break;default:throw new TypeError("Unknown CallbackType")}}schedule_(t,s){if(s&&s>0)return this.callbackType_=1,void(this.handle_=setTimeout(()=>{this.runCallback_()},s));if(!e.includes(t))throw new TypeError("Invalid task priority : "+t);return"background"===t&&"function"==typeof requestIdleCallback?(this.callbackType_=0,void(this.handle_=requestIdleCallback(()=>{this.runCallback_()}))):"function"==typeof MessageChannel?(this.callbackType_=2,void(this.handle_=i().queueCallback(()=>{this.runCallback_()}))):(this.callbackType_=1,void(this.handle_=setTimeout(()=>{this.runCallback_()})))}runCallback_(){this.canceled_||this.callback_()}}var r=0;class a{constructor(){this.head_=null,this.tail_=null}isEmpty(){return null==this.head_}push(e){if("object"!=typeof e)throw new TypeError("Task must be an Object");e.tq_sequence_=r++,this.isEmpty()?(e.tq_prev_=null,this.head_=e):(e.tq_prev_=this.tail_,this.tail_.tq_next_=e),e.tq_next_=null,this.tail_=e}takeNextTask(){if(this.isEmpty())return null;var e=this.head_;return this.remove_(e),e}merge(e,t){if("function"!=typeof t)throw new TypeError("Must provide a selector function.");if(null==e)throw new Error("sourceQueue cannot be null");for(var i=this.head_,s=null,r=e.head_;r;){var a=r;if(r=r.tq_next_,t(a)){for(e.remove_(a);i&&i.tq_sequence_<a.tq_sequence_;)s=i,i=i.tq_next_;this.insert_(a,s),s=a}}}toArray(){for(var e=this.head_,t=[];null!==e;)t.push(e),e=e.tq_next_;return t}insert_(e,t){if(t!=this.tail_){var i=t?t.tq_next_:this.head_;e.tq_next_=i,i.tq_prev_=e,e.tq_prev_=t,null!=t?t.tq_next_=e:this.head_=e}else this.push(e)}remove_(e){if(null==e)throw new Error("Expected task to be non-null");e===this.head_&&(this.head_=e.tq_next_),e===this.tail_&&(this.tail_=this.tail_.tq_prev_),e.tq_next_&&(e.tq_next_.tq_prev_=e.tq_prev_),e.tq_prev_&&(e.tq_prev_.tq_next_=e.tq_next_)}}class n extends Event{constructor(t,i){if(!i||!e.includes(i.previousPriority))throw new TypeError("Invalid task priority: '"+i.previousPriority+"'");super(t),this.previousPriority=i.previousPriority}}class l extends AbortController{constructor(t){if(void 0===t&&(t={}),super(),null==t&&(t={}),"object"!=typeof t)throw new TypeError("'init' is not an object");var i,s,r=void 0===t.priority?"user-visible":t.priority;if(!e.includes(r))throw new TypeError("Invalid task priority: '"+r+"'");this.priority_=r,this.isPriorityChanging_=!1,s=(i=this).signal,Object.defineProperties(s,{priority:{get:function(){return i.priority_},enumerable:!0},onprioritychange:{value:null,writable:!0,enumerable:!0}}),s.addEventListener("prioritychange",e=>{s.onprioritychange&&s.onprioritychange(e)})}setPriority(t){if(!e.includes(t))throw new TypeError("Invalid task priority: "+t);if(this.isPriorityChanging_)throw new DOMException("","NotAllowedError");if(this.signal.priority!==t){this.isPriorityChanging_=!0;var i=this.priority_;this.priority_=t;var s=new n("prioritychange",{previousPriority:i});this.signal.dispatchEvent(s),this.isPriorityChanging_=!1}}}void 0===self.scheduler&&(self.scheduler=new class{constructor(){this.queues_={},e.forEach(e=>{this.queues_[e]=new a}),this.pendingHostCallback_=null,this.signals_=new WeakMap}postTask(t,i){if(void 0!==(i=Object.assign({},i)).signal){if(null===i.signal||!("aborted"in i.signal)||"function"!=typeof i.signal.addEventListener)return Promise.reject(new TypeError("'signal' is not a valid 'AbortSignal'"));if(i.signal&&i.signal.priority&&!e.includes(i.signal.priority))return Promise.reject(new TypeError("Invalid task priority: '"+i.signal.priority+"'"))}if(void 0!==i.priority&&(null===i.priority||!e.includes(i.priority)))return Promise.reject(new TypeError("Invalid task priority: '"+i.priority+"'"));if(void 0===i.delay&&(i.delay=0),i.delay=Number(i.delay),i.delay<0)return Promise.reject(new TypeError("'delay' must be a positive number."));var s={callback:t,options:i,resolve:null,reject:null,hostCallback:null,abortCallback:null,onTaskCompleted:function(){this.options.signal&&this.abortCallback&&(this.options.signal.removeEventListener("abort",this.abortCallback),this.abortCallback=null)},onTaskAborted:function(){this.hostCallback&&(this.hostCallback.cancel(),this.hostCallback=null),this.options.signal.removeEventListener("abort",this.abortCallback),this.abortCallback=null,this.reject(this.options.signal.reason)},isAborted:function(){return this.options.signal&&this.options.signal.aborted}},r=new Promise((e,t)=>{s.resolve=e,s.reject=t});return this.schedule_(s),r}schedule_(e){var t=e.options.signal;if(t){if(t.aborted)return void e.reject(t.reason);e.abortCallback=()=>{e.onTaskAborted()},t.addEventListener("abort",e.abortCallback)}e.options.delay>0?e.hostCallback=new s(()=>{e.hostCallback=null,this.onTaskDelayExpired_(e)},null,e.options.delay):(this.pushTask_(e),this.scheduleHostCallbackIfNeeded_())}onTaskDelayExpired_(e){this.pushTask_(e),this.pendingHostCallback_&&(this.pendingHostCallback_.cancel(),this.pendingHostCallback_=null),this.schedulerEntryCallback_()}onPriorityChange_(e){var t=this.signals_.get(e);if(void 0===t)throw new Error("Attempting to change priority on an unregistered signal");t!==e.priority&&(this.queues_[e.priority].merge(this.queues_[t],t=>t.options.signal===e),this.signals_.set(e,e.priority))}schedulerEntryCallback_(){this.pendingHostCallback_=null,this.runNextTask_(),this.scheduleHostCallbackIfNeeded_()}scheduleHostCallbackIfNeeded_(){var e=this.nextTaskPriority_();null!=e&&("background"!==e&&this.pendingHostCallback_&&this.pendingHostCallback_.isIdleCallback()&&(this.pendingHostCallback_.cancel(),this.pendingHostCallback_=null),this.pendingHostCallback_||(this.pendingHostCallback_=new s(()=>{this.schedulerEntryCallback_()},e,0)))}pushTask_(t){var i;if(!e.includes(i=t.options.priority?t.options.priority:t.options.signal&&t.options.signal.priority?t.options.signal.priority:"user-visible"))throw new TypeError("Invalid task priority: "+i);if(t.options.signal&&t.options.signal.priority){var s=t.options.signal;this.signals_.has(s)||(s.addEventListener("prioritychange",()=>{this.onPriorityChange_(s)}),this.signals_.set(s,s.priority))}this.queues_[i].push(t)}runNextTask_(){var e=null;do{var t=this.nextTaskPriority_();if(null==t)return;e=this.queues_[t].takeNextTask()}while(e.isAborted());try{var i=e.callback();e.resolve(i)}catch(t){e.reject(t)}finally{e.onTaskCompleted()}}nextTaskPriority_(){for(var t=0;t<e.length;t++){var i=e[t];if(!this.queues_[i].isEmpty())return i}return null}},self.TaskController=l,self.TaskPriorityChangeEvent=n)}();
!function(){var i=["user-blocking","user-visible","background"];class t{constructor(){this.channel_=new MessageChannel,this.sendPort_=this.channel_.port2,this.messages_={},this.nextMessageHandle_=1,this.channel_.port1.onmessage=i=>this.onMessageReceived_(i)}queueCallback(i){var t=this.nextMessageHandle_++;return this.messages_[t]=i,this.sendPort_.postMessage(t),t}cancelCallback(i){delete this.messages_[i]}onMessageReceived_(i){var t=i.data;if(t in this.messages_){var e=this.messages_[t];delete this.messages_[t],e()}}}function e(){return e.instance_||(e.instance_=new t),e.instance_}class r{constructor(i,t,e){void 0===e&&(e=0),this.callback_=i,this.callbackType_=null,this.handle_=null,this.canceled_=!1,this.schedule_(t,e)}isIdleCallback(){return 0===this.callbackType_}isMessageChannelCallback(){return 2===this.callbackType_}cancel(){if(!this.canceled_)switch(this.canceled_=!0,this.callbackType_){case 0:cancelIdleCallback(this.handle_);break;case 1:clearTimeout(this.handle_);break;case 2:e().cancelCallback(this.handle_);break;default:throw new TypeError("Unknown CallbackType")}}schedule_(t,r){if(r&&r>0)return this.callbackType_=1,void(this.handle_=setTimeout(()=>{this.runCallback_()},r));if(!i.includes(t))throw new TypeError("Invalid task priority : "+t);return"background"===t&&"function"==typeof requestIdleCallback?(this.callbackType_=0,void(this.handle_=requestIdleCallback(()=>{this.runCallback_()}))):"function"==typeof MessageChannel?(this.callbackType_=2,void(this.handle_=e().queueCallback(()=>{this.runCallback_()}))):(this.callbackType_=1,void(this.handle_=setTimeout(()=>{this.runCallback_()})))}runCallback_(){this.canceled_||this.callback_()}}var s=0;class n{constructor(){this.head_=null,this.tail_=null}isEmpty(){return null==this.head_}push(i){if("object"!=typeof i)throw new TypeError("Task must be an Object");i.tq_sequence_=s++,this.isEmpty()?(i.tq_prev_=null,this.head_=i):(i.tq_prev_=this.tail_,this.tail_.tq_next_=i),i.tq_next_=null,this.tail_=i}takeNextTask(){if(this.isEmpty())return null;var i=this.head_;return this.remove_(i),i}merge(i,t){if("function"!=typeof t)throw new TypeError("Must provide a selector function.");if(null==i)throw new Error("sourceQueue cannot be null");for(var e=this.head_,r=null,s=i.head_;s;){var n=s;if(s=s.tq_next_,t(n)){for(i.remove_(n);e&&e.tq_sequence_<n.tq_sequence_;)r=e,e=e.tq_next_;this.insert_(n,r),r=n}}}toArray(){for(var i=this.head_,t=[];null!==i;)t.push(i),i=i.tq_next_;return t}insert_(i,t){if(t!=this.tail_){var e=t?t.tq_next_:this.head_;i.tq_next_=e,e.tq_prev_=i,i.tq_prev_=t,null!=t?t.tq_next_=i:this.head_=i}else this.push(i)}remove_(i){if(null==i)throw new Error("Expected task to be non-null");i===this.head_&&(this.head_=i.tq_next_),i===this.tail_&&(this.tail_=this.tail_.tq_prev_),i.tq_next_&&(i.tq_next_.tq_prev_=i.tq_prev_),i.tq_prev_&&(i.tq_prev_.tq_next_=i.tq_next_)}}class a extends Event{constructor(t,e){if(!e||!i.includes(e.previousPriority))throw new TypeError("Invalid task priority: '"+e.previousPriority+"'");super(t),this.previousPriority=e.previousPriority}}class l extends AbortController{constructor(t){if(void 0===t&&(t={}),super(),null==t&&(t={}),"object"!=typeof t)throw new TypeError("'init' is not an object");var e,r,s=void 0===t.priority?"user-visible":t.priority;if(!i.includes(s))throw new TypeError("Invalid task priority: '"+s+"'");this.priority_=s,this.isPriorityChanging_=!1,r=(e=this).signal,Object.defineProperties(r,{priority:{get:function(){return e.priority_},enumerable:!0},onprioritychange:{value:null,writable:!0,enumerable:!0}}),r.addEventListener("prioritychange",i=>{r.onprioritychange&&r.onprioritychange(i)})}setPriority(t){if(!i.includes(t))throw new TypeError("Invalid task priority: "+t);if(this.isPriorityChanging_)throw new DOMException("","NotAllowedError");if(this.signal.priority!==t){this.isPriorityChanging_=!0;var e=this.priority_;this.priority_=t;var r=new a("prioritychange",{previousPriority:e});this.signal.dispatchEvent(r),this.isPriorityChanging_=!1}}}void 0===self.scheduler?(self.scheduler=new class{constructor(){this.queues_={},i.forEach(i=>{this.queues_[i]=[new n,new n]}),this.pendingHostCallback_=null,this.signals_=new WeakMap}yield(i){return(i=Object.assign({},i)).signal&&"inherit"==i.signal&&delete i.signal,i.priority&&"inherit"==i.priority&&(i.priority="user-visible"),this.postTaskOrContinuation_(()=>{},i,!0)}postTask(i,t){return this.postTaskOrContinuation_(i,t,!1)}postTaskOrContinuation_(t,e,r){if(void 0!==(e=Object.assign({},e)).signal){if(null===e.signal||!("aborted"in e.signal)||"function"!=typeof e.signal.addEventListener)return Promise.reject(new TypeError("'signal' is not a valid 'AbortSignal'"));if(e.signal&&e.signal.priority&&!i.includes(e.signal.priority))return Promise.reject(new TypeError("Invalid task priority: '"+e.signal.priority+"'"))}if(void 0!==e.priority&&(null===e.priority||!i.includes(e.priority)))return Promise.reject(new TypeError("Invalid task priority: '"+e.priority+"'"));if(void 0===e.delay&&(e.delay=0),e.delay=Number(e.delay),e.delay<0)return Promise.reject(new TypeError("'delay' must be a positive number."));var s={callback:t,options:e,resolve:null,reject:null,hostCallback:null,abortCallback:null,onTaskCompleted:function(){this.options.signal&&this.abortCallback&&(this.options.signal.removeEventListener("abort",this.abortCallback),this.abortCallback=null)},onTaskAborted:function(){this.hostCallback&&(this.hostCallback.cancel(),this.hostCallback=null),this.options.signal.removeEventListener("abort",this.abortCallback),this.abortCallback=null,this.reject(this.options.signal.reason)},isAborted:function(){return this.options.signal&&this.options.signal.aborted},isContinuation:r},n=new Promise((i,t)=>{s.resolve=i,s.reject=t});return this.schedule_(s),n}schedule_(i){var t=i.options.signal;if(t){if(t.aborted)return void i.reject(t.reason);i.abortCallback=()=>{i.onTaskAborted()},t.addEventListener("abort",i.abortCallback)}i.options.delay>0?i.hostCallback=new r(()=>{i.hostCallback=null,this.onTaskDelayExpired_(i)},null,i.options.delay):(this.pushTask_(i),this.scheduleHostCallbackIfNeeded_())}onTaskDelayExpired_(i){this.pushTask_(i),this.pendingHostCallback_&&(this.pendingHostCallback_.cancel(),this.pendingHostCallback_=null),this.schedulerEntryCallback_()}onPriorityChange_(i){var t=this.signals_.get(i);if(void 0===t)throw new Error("Attempting to change priority on an unregistered signal");if(t!==i.priority){for(var e=0;e<2;e++)this.queues_[i.priority][e].merge(this.queues_[t][e],t=>t.options.signal===i);this.signals_.set(i,i.priority)}}schedulerEntryCallback_(){this.pendingHostCallback_=null,this.runNextTask_(),this.scheduleHostCallbackIfNeeded_()}scheduleHostCallbackIfNeeded_(){var{priority:i}=this.nextTaskPriority_();null!=i&&("background"!==i&&this.pendingHostCallback_&&this.pendingHostCallback_.isIdleCallback()&&(this.pendingHostCallback_.cancel(),this.pendingHostCallback_=null),this.pendingHostCallback_||(this.pendingHostCallback_=new r(()=>{this.schedulerEntryCallback_()},i,0)))}pushTask_(t){var e;if(!i.includes(e=t.options.priority?t.options.priority:t.options.signal&&t.options.signal.priority?t.options.signal.priority:"user-visible"))throw new TypeError("Invalid task priority: "+e);if(t.options.signal&&t.options.signal.priority){var r=t.options.signal;this.signals_.has(r)||(r.addEventListener("prioritychange",()=>{this.onPriorityChange_(r)}),this.signals_.set(r,r.priority))}this.queues_[e][t.isContinuation?0:1].push(t)}runNextTask_(){var i=null;do{var{priority:t,type:e}=this.nextTaskPriority_();if(null==t)return;i=this.queues_[t][e].takeNextTask()}while(i.isAborted());try{var r=i.callback();i.resolve(r)}catch(t){i.reject(t)}finally{i.onTaskCompleted()}}nextTaskPriority_(){for(var t=0;t<i.length;t++)for(var e=i[t],r=0;r<2;r++)if(!this.queues_[e][r].isEmpty())return{priority:e,type:r};return{priority:null,type:0}}},self.TaskController=l,self.TaskPriorityChangeEvent=a):self.scheduler.yield||(self.scheduler.yield=function(i){var t=i=>i&&"user-visible"!=i?i:"user-blocking";if((i=Object.assign({},i)).signal&&"inherit"==i.signal&&delete i.signal,i.priority&&"inherit"==i.priority&&delete i.priority,i.signal&&i.signal.aborted)return Promise.reject(i.signal.reason);var e=i.priority;!e&&i.signal&&i.signal.priority&&(e=i.signal.priority),e=t(e);var r={inputSignal:i.signal,controller:new self.TaskController({priority:e}),abortCallback:null,priorityCallback:null,onTaskAborted:function(){this.controller.abort(this.inputSignal.reason),this.abortCallback=null},onPriorityChange:function(){this.controller.setPriority(t(this.inputSignal.priority))},onTaskCompleted:function(){this.abortCallback&&(this.inputSignal.removeEventListener("abort",this.abortCallback),this.abortCallback=null),this.priorityCallback&&(this.inputSignal.removeEventListener("prioritychange",this.priorityCallback),this.priorityCallback=null)}};i.signal&&(r.abortCallback=()=>{r.onTaskAborted()},i.signal.addEventListener("abort",r.abortCallback)),i.signal&&i.signal.priority&&!i.priority&&(r.priorityCallback=()=>{r.onPriorityChange()},i.signal.addEventListener("prioritychange",r.priorityCallback));var s=self.scheduler.postTask(()=>{},{signal:r.controller.signal});return s.then(()=>{r.onTaskCompleted()}).catch(i=>{throw r.onTaskCompleted(),i}),s})}();
//# sourceMappingURL=scheduler-polyfill.js.map
{
"name": "scheduler-polyfill",
"version": "1.2.1",
"version": "1.3.0-beta.0",
"description": "Polyfill of self.scheduler API",

@@ -5,0 +5,0 @@ "main": "./dist/scheduler-polyfill.js",

@@ -12,2 +12,4 @@ # Scheduler Polyfill

## `scheduler.postTask()`
The implementation uses a combination of `setTimeout`, `MessageChannel`, and

@@ -17,2 +19,49 @@ `requestIdleCallback` to implement task scheduling, falling back to `setTimeout`

The polyfill, like the native implementation, runs `scheduler` tasks in
descending priority order (`'user-blocking'` > `'user-visible'` >
`'background'`). But there are some differences in the relative order of
non-`scheduler` tasks:
- `"background"` tasks are scheduled using `requestIdleCallback` on browsers
that support it, which provides similar scheduling as `scheduler`. For
browsers that don't support it, these tasks do not have low/idle event loop
priority.
- `"user-blocking"` tasks have the same event loop scheduling prioritization as
`"user-visible"` (similar to `setTimeout()`), meaning these tasks do not have
a higher event loop priority.
## `scheduler.yield()`
> `scheduler.yield()` is available in version 1.3 of the polyfill, published
under the `next` tag on npm. See the [Usage section](#usage) for installation
instructions.
The polyfill supports [`scheduler.yield()`](https://chromestatus.com/feature/6266249336586240),
which is currently in [Origin Trial in
Chrome](https://developer.chrome.com/origintrials/#/view_trial/836543630784069633).
[Signal and priority
inheritance](https://github.com/WICG/scheduling-apis/blob/main/explainers/yield-and-continuation.md#controlling-continuation-priority-and-abort-behavior)
is not currently supported in the polyfill, and using the `"inherit"` option
will result in the default behavior, i.e. the continuation will not be aborted
and will run at default priority.
The scheduling behavior of the polyfill depends on whether the browser supports
`scheduler.postTask()` (i.e. older Chrome versions). If it does, then `yield()`
is polyfilled with `postTask()`, with the following behavior:
- `"user-visible"` continuations run as `"user-blocking"` `scheduler` tasks.
This means they typically have a higher event loop priority than other tasks
(consistent with `yield()`), but they can be interleaved with other
`"user-blocking"` tasks. The same goes for `"user-blocking"` continuations.
- `"background"` continuations are scheduled as `"background"` tasks, which
means they have lowered event loop priority but don't go ahead of other
`"background"` tasks, so they can be interleaved.
On browsers that don't support `scheduler.postTask()`, the same event loop
prioritization as the `postTask()` polyfill applies (see above), but
continuations have higher priority than tasks of the same priority, e.g.
`"background"` continuations run before `"background"` tasks.
## Requirements

@@ -24,14 +73,29 @@

**Include via unpkg:**
### Include via unpkg
**Use the next version of the polyfill, which includes `scheduler.yield()`:**
```html
<script src="https://unpkg.com/scheduler-polyfill@next"></script>
```
**or use the current stable release of the polyfill:**
```html
<script src="https://unpkg.com/scheduler-polyfill"></script>
```
**Using with npm and a bundler**:
### Include via npm and a bundler
```console
npm install scheduler-polyfill@next
```
**Or use the stable release (without `scheduler.yield()`):**
```sh
npm install scheduler-polyfill
```
Import to populate the task scheduling global variables, if not already
available in the executing browser:
```js

@@ -41,3 +105,3 @@ import 'scheduler-polyfill';

**Building from source:**
### Building from source

@@ -44,0 +108,0 @@ ```console

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc