a zip code crypto-currency system good for red ONLY

Immediate.js 8.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /**
  2. Some credit for this helper goes to http://github.com/YuzuJS/setImmediate
  3. */
  4. import { root } from './root';
  5. export class ImmediateDefinition {
  6. constructor(root) {
  7. this.root = root;
  8. if (root.setImmediate && typeof root.setImmediate === 'function') {
  9. this.setImmediate = root.setImmediate.bind(root);
  10. this.clearImmediate = root.clearImmediate.bind(root);
  11. }
  12. else {
  13. this.nextHandle = 1;
  14. this.tasksByHandle = {};
  15. this.currentlyRunningATask = false;
  16. // Don't get fooled by e.g. browserify environments.
  17. if (this.canUseProcessNextTick()) {
  18. // For Node.js before 0.9
  19. this.setImmediate = this.createProcessNextTickSetImmediate();
  20. }
  21. else if (this.canUsePostMessage()) {
  22. // For non-IE10 modern browsers
  23. this.setImmediate = this.createPostMessageSetImmediate();
  24. }
  25. else if (this.canUseMessageChannel()) {
  26. // For web workers, where supported
  27. this.setImmediate = this.createMessageChannelSetImmediate();
  28. }
  29. else if (this.canUseReadyStateChange()) {
  30. // For IE 6–8
  31. this.setImmediate = this.createReadyStateChangeSetImmediate();
  32. }
  33. else {
  34. // For older browsers
  35. this.setImmediate = this.createSetTimeoutSetImmediate();
  36. }
  37. let ci = function clearImmediate(handle) {
  38. delete clearImmediate.instance.tasksByHandle[handle];
  39. };
  40. ci.instance = this;
  41. this.clearImmediate = ci;
  42. }
  43. }
  44. identify(o) {
  45. return this.root.Object.prototype.toString.call(o);
  46. }
  47. canUseProcessNextTick() {
  48. return this.identify(this.root.process) === '[object process]';
  49. }
  50. canUseMessageChannel() {
  51. return Boolean(this.root.MessageChannel);
  52. }
  53. canUseReadyStateChange() {
  54. const document = this.root.document;
  55. return Boolean(document && 'onreadystatechange' in document.createElement('script'));
  56. }
  57. canUsePostMessage() {
  58. const root = this.root;
  59. // The test against `importScripts` prevents this implementation from being installed inside a web worker,
  60. // where `root.postMessage` means something completely different and can't be used for this purpose.
  61. if (root.postMessage && !root.importScripts) {
  62. let postMessageIsAsynchronous = true;
  63. let oldOnMessage = root.onmessage;
  64. root.onmessage = function () {
  65. postMessageIsAsynchronous = false;
  66. };
  67. root.postMessage('', '*');
  68. root.onmessage = oldOnMessage;
  69. return postMessageIsAsynchronous;
  70. }
  71. return false;
  72. }
  73. // This function accepts the same arguments as setImmediate, but
  74. // returns a function that requires no arguments.
  75. partiallyApplied(handler, ...args) {
  76. let fn = function result() {
  77. const { handler, args } = result;
  78. if (typeof handler === 'function') {
  79. handler.apply(undefined, args);
  80. }
  81. else {
  82. (new Function('' + handler))();
  83. }
  84. };
  85. fn.handler = handler;
  86. fn.args = args;
  87. return fn;
  88. }
  89. addFromSetImmediateArguments(args) {
  90. this.tasksByHandle[this.nextHandle] = this.partiallyApplied.apply(undefined, args);
  91. return this.nextHandle++;
  92. }
  93. createProcessNextTickSetImmediate() {
  94. let fn = function setImmediate() {
  95. const { instance } = setImmediate;
  96. let handle = instance.addFromSetImmediateArguments(arguments);
  97. instance.root.process.nextTick(instance.partiallyApplied(instance.runIfPresent, handle));
  98. return handle;
  99. };
  100. fn.instance = this;
  101. return fn;
  102. }
  103. createPostMessageSetImmediate() {
  104. // Installs an event handler on `global` for the `message` event: see
  105. // * https://developer.mozilla.org/en/DOM/window.postMessage
  106. // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
  107. const root = this.root;
  108. let messagePrefix = 'setImmediate$' + root.Math.random() + '$';
  109. let onGlobalMessage = function globalMessageHandler(event) {
  110. const instance = globalMessageHandler.instance;
  111. if (event.source === root &&
  112. typeof event.data === 'string' &&
  113. event.data.indexOf(messagePrefix) === 0) {
  114. instance.runIfPresent(+event.data.slice(messagePrefix.length));
  115. }
  116. };
  117. onGlobalMessage.instance = this;
  118. root.addEventListener('message', onGlobalMessage, false);
  119. let fn = function setImmediate() {
  120. const { messagePrefix, instance } = setImmediate;
  121. let handle = instance.addFromSetImmediateArguments(arguments);
  122. instance.root.postMessage(messagePrefix + handle, '*');
  123. return handle;
  124. };
  125. fn.instance = this;
  126. fn.messagePrefix = messagePrefix;
  127. return fn;
  128. }
  129. runIfPresent(handle) {
  130. // From the spec: 'Wait until any invocations of this algorithm started before this one have completed.'
  131. // So if we're currently running a task, we'll need to delay this invocation.
  132. if (this.currentlyRunningATask) {
  133. // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
  134. // 'too much recursion' error.
  135. this.root.setTimeout(this.partiallyApplied(this.runIfPresent, handle), 0);
  136. }
  137. else {
  138. let task = this.tasksByHandle[handle];
  139. if (task) {
  140. this.currentlyRunningATask = true;
  141. try {
  142. task();
  143. }
  144. finally {
  145. this.clearImmediate(handle);
  146. this.currentlyRunningATask = false;
  147. }
  148. }
  149. }
  150. }
  151. createMessageChannelSetImmediate() {
  152. let channel = new this.root.MessageChannel();
  153. channel.port1.onmessage = (event) => {
  154. let handle = event.data;
  155. this.runIfPresent(handle);
  156. };
  157. let fn = function setImmediate() {
  158. const { channel, instance } = setImmediate;
  159. let handle = instance.addFromSetImmediateArguments(arguments);
  160. channel.port2.postMessage(handle);
  161. return handle;
  162. };
  163. fn.channel = channel;
  164. fn.instance = this;
  165. return fn;
  166. }
  167. createReadyStateChangeSetImmediate() {
  168. let fn = function setImmediate() {
  169. const instance = setImmediate.instance;
  170. const root = instance.root;
  171. const doc = root.document;
  172. const html = doc.documentElement;
  173. let handle = instance.addFromSetImmediateArguments(arguments);
  174. // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
  175. // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
  176. let script = doc.createElement('script');
  177. script.onreadystatechange = () => {
  178. instance.runIfPresent(handle);
  179. script.onreadystatechange = null;
  180. html.removeChild(script);
  181. script = null;
  182. };
  183. html.appendChild(script);
  184. return handle;
  185. };
  186. fn.instance = this;
  187. return fn;
  188. }
  189. createSetTimeoutSetImmediate() {
  190. let fn = function setImmediate() {
  191. const instance = setImmediate.instance;
  192. let handle = instance.addFromSetImmediateArguments(arguments);
  193. instance.root.setTimeout(instance.partiallyApplied(instance.runIfPresent, handle), 0);
  194. return handle;
  195. };
  196. fn.instance = this;
  197. return fn;
  198. }
  199. }
  200. export const Immediate = new ImmediateDefinition(root);
  201. //# sourceMappingURL=Immediate.js.map