[Pkg-javascript-commits] [node-set-immediate] 01/02: Imported Upstream version 1.0.4
Thorsten Alteholz
alteholz at moszumanska.debian.org
Sat Feb 27 14:06:34 UTC 2016
This is an automated email from the git hooks/post-receive script.
alteholz pushed a commit to branch master
in repository node-set-immediate.
commit 0042a0b811413783e15d9a2f5ed4dac060f8c066
Author: Thorsten Alteholz <debian at alteholz.de>
Date: Sat Feb 27 15:06:27 2016 +0100
Imported Upstream version 1.0.4
---
LICENSE.txt | 20 +++++++
README.md | 92 +++++++++++++++++++++++++++++
package.json | 27 +++++++++
setImmediate.js | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 314 insertions(+)
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..32b20de
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic Denicola
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ad0f68d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,92 @@
+# setImmediate.js
+**A YuzuJS production**
+
+## Introduction
+
+**setImmediate.js** is a highly cross-browser implementation of the `setImmediate` and `clearImmediate` APIs, [proposed][spec] by Microsoft to the Web Performance Working Group. `setImmediate` allows scripts to yield to the browser, executing a given operation asynchronously, in a manner that is typically more efficient and consumes less power than the usual `setTimeout(..., 0)` pattern.
+
+setImmediate.js runs at “full speed” in the following browsers and environments, using various clever tricks:
+
+ * Internet Explorer 6+
+ * Firefox 3+
+ * WebKit
+ * Opera 9.5+
+ * Node.js
+ * Web workers in browsers that support `MessageChannel`, which I can't find solid info on.
+
+In all other browsers we fall back to using `setTimeout`, so it's always safe to use.
+
+## Macrotasks and Microtasks
+
+The `setImmediate` API, as specified, gives you access to the environment's [task queue][], sometimes known as its "macrotask" queue. This is crucially different from the [microtask queue][] used by web features such as `MutationObserver`, language features such as promises and `Object.observe`, and Node.js features such as `process.nextTick`. Each go-around of the macrotask queue yields back to the event loop once all queued tasks have been processed, even if the macrotask itself queued [...]
+
+In practice, what this means is that if you call `setImmediate` inside of another task queued with `setImmediate`, you will yield back to the event loop and any I/O or rendering tasks that need to take place between those calls, instead of executing the queued task as soon as possible.
+
+If you are looking specifically to yield as part of a render loop, consider using [`requestAnimationFrame`][raf]; if you are looking solely for the control-flow ordering effects, use a microtask solution such as [asap][].
+
+## The Tricks
+
+### `process.nextTick`
+
+In Node.js versions below 0.9, `setImmediate` is not available, but [`process.nextTick`][nextTick] is—and in those versions, `process.nextTick` uses macrotask semantics. So, we use it to shim support for a global `setImmediate`.
+
+In Node.js 0.9 and above, `process.nextTick` moved to microtask semantics, but `setImmediate` was introduced with macrotask semantics, so there's no need to polyfill anything.
+
+Note that we check for *actual* Node.js environments, not emulated ones like those produced by browserify or similar. Such emulated environments often already include a `process.nextTick` shim that's not as browser-compatible as setImmediate.js.
+
+### `postMessage`
+
+In Firefox 3+, Internet Explorer 9+, all modern WebKit browsers, and Opera 9.5+, [`postMessage`][postMessage] is available and provides a good way to queue tasks on the event loop. It's quite the abuse, using a cross-document messaging protocol within the same document simply to get access to the event loop task queue, but until there are native implementations, this is the best option.
+
+Note that Internet Explorer 8 includes a synchronous version of `postMessage`. We detect this, or any other such synchronous implementation, and fall back to another trick.
+
+### `MessageChannel`
+
+Unfortunately, `postMessage` has completely different semantics inside web workers, and so cannot be used there. So we turn to [`MessageChannel`][MessageChannel], which has worse browser support, but does work inside a web worker.
+
+### `<script> onreadystatechange`
+
+For our last trick, we pull something out to make things fast in Internet Explorer versions 6 through 8: namely, creating a `<script>` element and firing our calls in its `onreadystatechange` event. This does execute in a future turn of the event loop, and is also faster than `setTimeout(…, 0)`, so hey, why not?
+
+## Usage
+
+In the browser, include it with a `<script>` tag; pretty simple.
+
+In Node.js, do
+
+```
+npm install setimmediate
+```
+
+then
+
+```js
+require("setimmediate");
+```
+
+somewhere early in your app; it attaches to the global.
+
+## Demo
+
+* [Quick sort demo][cross-browser-demo]
+
+## Reference and Reading
+
+ * [Efficient Script Yielding W3C Editor's Draft][spec]
+ * [W3C mailing list post introducing the specification][list-post]
+ * [IE Test Drive demo][ie-demo]
+ * [Introductory blog post by Nicholas C. Zakas][ncz]
+
+
+[spec]: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
+[task queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#task-queue
+[microtask queue]: http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#perform-a-microtask-checkpoint
+[raf]: https://html.spec.whatwg.org/multipage/webappapis.html#dom-window-requestanimationframe
+[asap]: https://github.com/kriskowal/asap
+[list-post]: http://lists.w3.org/Archives/Public/public-web-perf/2011Jun/0100.html
+[ie-demo]: http://ie.microsoft.com/testdrive/Performance/setImmediateSorting/Default.html
+[ncz]: http://www.nczonline.net/blog/2011/09/19/script-yielding-with-setimmediate/
+[nextTick]: http://nodejs.org/docs/v0.8.16/api/process.html#process_process_nexttick_callback
+[postMessage]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#posting-messages
+[MessageChannel]: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html#channel-messaging
+[cross-browser-demo]: http://jphpsf.github.com/setImmediate-shim-demo
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..e5dd50c
--- /dev/null
+++ b/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "setimmediate",
+ "description": "A shim for the setImmediate efficient script yielding API",
+ "version": "1.0.4",
+ "author": "YuzuJS",
+ "contributors": [
+ "Domenic Denicola <d at domenic.me> (https://domenic.me)",
+ "Donavon West <github at donavon.com> (http://donavon.com)",
+ "Yaffle"
+ ],
+ "license": "MIT",
+ "repository": "YuzuJS/setImmediate",
+ "main": "setImmediate.js",
+ "scripts": {
+ "lint": "jshint setImmediate.js",
+ "test": "mocha test/tests.js",
+ "test-browser": "opener http://localhost:9008/__zuul && zuul test/tests.js --ui mocha-bdd --local 9008",
+ "test-browser-only": "opener http://localhost:9007/test/browserOnly/index.html && http-server . -p 9007"
+ },
+ "devDependencies": {
+ "jshint": "^2.5.0",
+ "mocha": "~1.18.2",
+ "http-server": "~0.6.1",
+ "opener": "^1.3",
+ "zuul": "^1.6.4"
+ }
+}
diff --git a/setImmediate.js b/setImmediate.js
new file mode 100644
index 0000000..5abe55c
--- /dev/null
+++ b/setImmediate.js
@@ -0,0 +1,175 @@
+(function (global, undefined) {
+ "use strict";
+
+ if (global.setImmediate) {
+ return;
+ }
+
+ var nextHandle = 1; // Spec says greater than zero
+ var tasksByHandle = {};
+ var currentlyRunningATask = false;
+ var doc = global.document;
+ var setImmediate;
+
+ function addFromSetImmediateArguments(args) {
+ tasksByHandle[nextHandle] = partiallyApplied.apply(undefined, args);
+ return nextHandle++;
+ }
+
+ // This function accepts the same arguments as setImmediate, but
+ // returns a function that requires no arguments.
+ function partiallyApplied(handler) {
+ var args = [].slice.call(arguments, 1);
+ return function() {
+ if (typeof handler === "function") {
+ handler.apply(undefined, args);
+ } else {
+ (new Function("" + handler))();
+ }
+ };
+ }
+
+ function runIfPresent(handle) {
+ // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
+ // So if we're currently running a task, we'll need to delay this invocation.
+ if (currentlyRunningATask) {
+ // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
+ // "too much recursion" error.
+ setTimeout(partiallyApplied(runIfPresent, handle), 0);
+ } else {
+ var task = tasksByHandle[handle];
+ if (task) {
+ currentlyRunningATask = true;
+ try {
+ task();
+ } finally {
+ clearImmediate(handle);
+ currentlyRunningATask = false;
+ }
+ }
+ }
+ }
+
+ function clearImmediate(handle) {
+ delete tasksByHandle[handle];
+ }
+
+ function installNextTickImplementation() {
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ process.nextTick(partiallyApplied(runIfPresent, handle));
+ return handle;
+ };
+ }
+
+ function canUsePostMessage() {
+ // The test against `importScripts` prevents this implementation from being installed inside a web worker,
+ // where `global.postMessage` means something completely different and can't be used for this purpose.
+ if (global.postMessage && !global.importScripts) {
+ var postMessageIsAsynchronous = true;
+ var oldOnMessage = global.onmessage;
+ global.onmessage = function() {
+ postMessageIsAsynchronous = false;
+ };
+ global.postMessage("", "*");
+ global.onmessage = oldOnMessage;
+ return postMessageIsAsynchronous;
+ }
+ }
+
+ function installPostMessageImplementation() {
+ // Installs an event handler on `global` for the `message` event: see
+ // * https://developer.mozilla.org/en/DOM/window.postMessage
+ // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
+
+ var messagePrefix = "setImmediate$" + Math.random() + "$";
+ var onGlobalMessage = function(event) {
+ if (event.source === global &&
+ typeof event.data === "string" &&
+ event.data.indexOf(messagePrefix) === 0) {
+ runIfPresent(+event.data.slice(messagePrefix.length));
+ }
+ };
+
+ if (global.addEventListener) {
+ global.addEventListener("message", onGlobalMessage, false);
+ } else {
+ global.attachEvent("onmessage", onGlobalMessage);
+ }
+
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ global.postMessage(messagePrefix + handle, "*");
+ return handle;
+ };
+ }
+
+ function installMessageChannelImplementation() {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(event) {
+ var handle = event.data;
+ runIfPresent(handle);
+ };
+
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ channel.port2.postMessage(handle);
+ return handle;
+ };
+ }
+
+ function installReadyStateChangeImplementation() {
+ var html = doc.documentElement;
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
+ // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
+ var script = doc.createElement("script");
+ script.onreadystatechange = function () {
+ runIfPresent(handle);
+ script.onreadystatechange = null;
+ html.removeChild(script);
+ script = null;
+ };
+ html.appendChild(script);
+ return handle;
+ };
+ }
+
+ function installSetTimeoutImplementation() {
+ setImmediate = function() {
+ var handle = addFromSetImmediateArguments(arguments);
+ setTimeout(partiallyApplied(runIfPresent, handle), 0);
+ return handle;
+ };
+ }
+
+ // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
+ var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
+ attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
+
+ // Don't get fooled by e.g. browserify environments.
+ if ({}.toString.call(global.process) === "[object process]") {
+ // For Node.js before 0.9
+ installNextTickImplementation();
+
+ } else if (canUsePostMessage()) {
+ // For non-IE10 modern browsers
+ installPostMessageImplementation();
+
+ } else if (global.MessageChannel) {
+ // For web workers, where supported
+ installMessageChannelImplementation();
+
+ } else if (doc && "onreadystatechange" in doc.createElement("script")) {
+ // For IE 6–8
+ installReadyStateChangeImplementation();
+
+ } else {
+ // For older browsers
+ installSetTimeoutImplementation();
+ }
+
+ attachTo.setImmediate = setImmediate;
+ attachTo.clearImmediate = clearImmediate;
+}(typeof self === "undefined" ? typeof global === "undefined" ? this : global : self));
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-set-immediate.git
More information about the Pkg-javascript-commits
mailing list