239
									
								
								lib/co/co.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								lib/co/co.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,239 @@ | |||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * slice() reference. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | var slice = Array.prototype.slice; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Expose `co`. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | module.exports = co['default'] = co.co = co; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Wrap the given generator `fn` into a | ||||||
|  |  * function that returns a promise. | ||||||
|  |  * This is a separate function so that | ||||||
|  |  * every `co()` call doesn't create a new, | ||||||
|  |  * unnecessary closure. | ||||||
|  |  * | ||||||
|  |  * @param {GeneratorFunction} fn | ||||||
|  |  * @return {Function} | ||||||
|  |  * @api public | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | co.wrap = function (fn) { | ||||||
|  |   createPromise.__generatorFunction__ = fn; | ||||||
|  |   return createPromise; | ||||||
|  |   function createPromise() { | ||||||
|  |     return co.call(this, fn.apply(this, arguments)); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Execute the generator function or a generator | ||||||
|  |  * and return a promise. | ||||||
|  |  * | ||||||
|  |  * @param {Function} fn | ||||||
|  |  * @return {Promise} | ||||||
|  |  * @api public | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function co(gen) { | ||||||
|  |   var ctx = this; | ||||||
|  |   var args = slice.call(arguments, 1); | ||||||
|  |  | ||||||
|  |   // we wrap everything in a promise to avoid promise chaining, | ||||||
|  |   // which leads to memory leak errors. | ||||||
|  |   // see https://github.com/tj/co/issues/180 | ||||||
|  |   return new Promise(function(resolve, reject) { | ||||||
|  |     if (typeof gen === 'function') gen = gen.apply(ctx, args); | ||||||
|  |     if (!gen || typeof gen.next !== 'function') return resolve(gen); | ||||||
|  |  | ||||||
|  |     onFulfilled(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param {Mixed} res | ||||||
|  |      * @return {Promise} | ||||||
|  |      * @api private | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     function onFulfilled(res) { | ||||||
|  |       var ret; | ||||||
|  |       try { | ||||||
|  |         ret = gen.next(res); | ||||||
|  |       } catch (e) { | ||||||
|  |         return reject(e); | ||||||
|  |       } | ||||||
|  |       next(ret); | ||||||
|  |       return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @param {Error} err | ||||||
|  |      * @return {Promise} | ||||||
|  |      * @api private | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     function onRejected(err) { | ||||||
|  |       var ret; | ||||||
|  |       try { | ||||||
|  |         ret = gen.throw(err); | ||||||
|  |       } catch (e) { | ||||||
|  |         return reject(e); | ||||||
|  |       } | ||||||
|  |       next(ret); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the next value in the generator, | ||||||
|  |      * return a promise. | ||||||
|  |      * | ||||||
|  |      * @param {Object} ret | ||||||
|  |      * @return {Promise} | ||||||
|  |      * @api private | ||||||
|  |      */ | ||||||
|  |  | ||||||
|  |     function next(ret) { | ||||||
|  |       if (ret.done) return resolve(ret.value); | ||||||
|  |       var value = toPromise.call(ctx, ret.value); | ||||||
|  |       if (value && isPromise(value)) return value.then(onFulfilled, onRejected); | ||||||
|  |       return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' | ||||||
|  |         + 'but the following object was passed: "' + String(ret.value) + '"')); | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Convert a `yield`ed value into a promise. | ||||||
|  |  * | ||||||
|  |  * @param {Mixed} obj | ||||||
|  |  * @return {Promise} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function toPromise(obj) { | ||||||
|  |   if (!obj) return obj; | ||||||
|  |   if (isPromise(obj)) return obj; | ||||||
|  |   if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); | ||||||
|  |   if ('function' == typeof obj) return thunkToPromise.call(this, obj); | ||||||
|  |   if (Array.isArray(obj)) return arrayToPromise.call(this, obj); | ||||||
|  |   if (isObject(obj)) return objectToPromise.call(this, obj); | ||||||
|  |   return obj; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Convert a thunk to a promise. | ||||||
|  |  * | ||||||
|  |  * @param {Function} | ||||||
|  |  * @return {Promise} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function thunkToPromise(fn) { | ||||||
|  |   var ctx = this; | ||||||
|  |   return new Promise(function (resolve, reject) { | ||||||
|  |     fn.call(ctx, function (err, res) { | ||||||
|  |       if (err) return reject(err); | ||||||
|  |       if (arguments.length > 2) res = slice.call(arguments, 1); | ||||||
|  |       resolve(res); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Convert an array of "yieldables" to a promise. | ||||||
|  |  * Uses `Promise.all()` internally. | ||||||
|  |  * | ||||||
|  |  * @param {Array} obj | ||||||
|  |  * @return {Promise} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function arrayToPromise(obj) { | ||||||
|  |   return Promise.all(obj.map(toPromise, this)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Convert an object of "yieldables" to a promise. | ||||||
|  |  * Uses `Promise.all()` internally. | ||||||
|  |  * | ||||||
|  |  * @param {Object} obj | ||||||
|  |  * @return {Promise} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function objectToPromise(obj){ | ||||||
|  |   var results = new obj.constructor(); | ||||||
|  |   var keys = Object.keys(obj); | ||||||
|  |   var promises = []; | ||||||
|  |   for (var i = 0; i < keys.length; i++) { | ||||||
|  |     var key = keys[i]; | ||||||
|  |     var promise = toPromise.call(this, obj[key]); | ||||||
|  |     if (promise && isPromise(promise)) defer(promise, key); | ||||||
|  |     else results[key] = obj[key]; | ||||||
|  |   } | ||||||
|  |   return Promise.all(promises).then(function () { | ||||||
|  |     return results; | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   function defer(promise, key) { | ||||||
|  |     // predefine the key in the result | ||||||
|  |     results[key] = undefined; | ||||||
|  |     promises.push(promise.then(function (res) { | ||||||
|  |       results[key] = res; | ||||||
|  |     })); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Check if `obj` is a promise. | ||||||
|  |  * | ||||||
|  |  * @param {Object} obj | ||||||
|  |  * @return {Boolean} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function isPromise(obj) { | ||||||
|  |   return 'function' == typeof obj.then; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Check if `obj` is a generator. | ||||||
|  |  * | ||||||
|  |  * @param {Mixed} obj | ||||||
|  |  * @return {Boolean} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function isGenerator(obj) { | ||||||
|  |   return 'function' == typeof obj.next && 'function' == typeof obj.throw; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Check if `obj` is a generator function. | ||||||
|  |  * | ||||||
|  |  * @param {Mixed} obj | ||||||
|  |  * @return {Boolean} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |   | ||||||
|  | function isGeneratorFunction(obj) { | ||||||
|  |   var constructor = obj.constructor; | ||||||
|  |   if (!constructor) return false; | ||||||
|  |   if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true; | ||||||
|  |   return isGenerator(constructor.prototype); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Check for plain object. | ||||||
|  |  * | ||||||
|  |  * @param {Mixed} val | ||||||
|  |  * @return {Boolean} | ||||||
|  |  * @api private | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | function isObject(val) { | ||||||
|  |   return Object == val.constructor; | ||||||
|  | } | ||||||
							
								
								
									
										4
									
								
								lib/co/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								lib/co/index.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  |  | ||||||
|  | declare function co(g: () => Generator<any, void, undefined>): any; | ||||||
|  |  | ||||||
|  | export = co; | ||||||
							
								
								
									
										240
									
								
								lib/co/index.js
									
									
									
									
									
								
							
							
						
						
									
										240
									
								
								lib/co/index.js
									
									
									
									
									
								
							| @@ -1,239 +1 @@ | |||||||
|  | module.exports = require('./co') | ||||||
| /** |  | ||||||
|  * slice() reference. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| var slice = Array.prototype.slice; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Expose `co`. |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| module.exports = co['default'] = co.co = co; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Wrap the given generator `fn` into a |  | ||||||
|  * function that returns a promise. |  | ||||||
|  * This is a separate function so that |  | ||||||
|  * every `co()` call doesn't create a new, |  | ||||||
|  * unnecessary closure. |  | ||||||
|  * |  | ||||||
|  * @param {GeneratorFunction} fn |  | ||||||
|  * @return {Function} |  | ||||||
|  * @api public |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| co.wrap = function (fn) { |  | ||||||
|   createPromise.__generatorFunction__ = fn; |  | ||||||
|   return createPromise; |  | ||||||
|   function createPromise() { |  | ||||||
|     return co.call(this, fn.apply(this, arguments)); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Execute the generator function or a generator |  | ||||||
|  * and return a promise. |  | ||||||
|  * |  | ||||||
|  * @param {Function} fn |  | ||||||
|  * @return {Promise} |  | ||||||
|  * @api public |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function co(gen) { |  | ||||||
|   var ctx = this; |  | ||||||
|   var args = slice.call(arguments, 1); |  | ||||||
|  |  | ||||||
|   // we wrap everything in a promise to avoid promise chaining, |  | ||||||
|   // which leads to memory leak errors. |  | ||||||
|   // see https://github.com/tj/co/issues/180 |  | ||||||
|   return new Promise(function(resolve, reject) { |  | ||||||
|     if (typeof gen === 'function') gen = gen.apply(ctx, args); |  | ||||||
|     if (!gen || typeof gen.next !== 'function') return resolve(gen); |  | ||||||
|  |  | ||||||
|     onFulfilled(); |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @param {Mixed} res |  | ||||||
|      * @return {Promise} |  | ||||||
|      * @api private |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     function onFulfilled(res) { |  | ||||||
|       var ret; |  | ||||||
|       try { |  | ||||||
|         ret = gen.next(res); |  | ||||||
|       } catch (e) { |  | ||||||
|         return reject(e); |  | ||||||
|       } |  | ||||||
|       next(ret); |  | ||||||
|       return null; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * @param {Error} err |  | ||||||
|      * @return {Promise} |  | ||||||
|      * @api private |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     function onRejected(err) { |  | ||||||
|       var ret; |  | ||||||
|       try { |  | ||||||
|         ret = gen.throw(err); |  | ||||||
|       } catch (e) { |  | ||||||
|         return reject(e); |  | ||||||
|       } |  | ||||||
|       next(ret); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Get the next value in the generator, |  | ||||||
|      * return a promise. |  | ||||||
|      * |  | ||||||
|      * @param {Object} ret |  | ||||||
|      * @return {Promise} |  | ||||||
|      * @api private |  | ||||||
|      */ |  | ||||||
|  |  | ||||||
|     function next(ret) { |  | ||||||
|       if (ret.done) return resolve(ret.value); |  | ||||||
|       var value = toPromise.call(ctx, ret.value); |  | ||||||
|       if (value && isPromise(value)) return value.then(onFulfilled, onRejected); |  | ||||||
|       return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' |  | ||||||
|         + 'but the following object was passed: "' + String(ret.value) + '"')); |  | ||||||
|     } |  | ||||||
|   }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Convert a `yield`ed value into a promise. |  | ||||||
|  * |  | ||||||
|  * @param {Mixed} obj |  | ||||||
|  * @return {Promise} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function toPromise(obj) { |  | ||||||
|   if (!obj) return obj; |  | ||||||
|   if (isPromise(obj)) return obj; |  | ||||||
|   if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); |  | ||||||
|   if ('function' == typeof obj) return thunkToPromise.call(this, obj); |  | ||||||
|   if (Array.isArray(obj)) return arrayToPromise.call(this, obj); |  | ||||||
|   if (isObject(obj)) return objectToPromise.call(this, obj); |  | ||||||
|   return obj; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Convert a thunk to a promise. |  | ||||||
|  * |  | ||||||
|  * @param {Function} |  | ||||||
|  * @return {Promise} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function thunkToPromise(fn) { |  | ||||||
|   var ctx = this; |  | ||||||
|   return new Promise(function (resolve, reject) { |  | ||||||
|     fn.call(ctx, function (err, res) { |  | ||||||
|       if (err) return reject(err); |  | ||||||
|       if (arguments.length > 2) res = slice.call(arguments, 1); |  | ||||||
|       resolve(res); |  | ||||||
|     }); |  | ||||||
|   }); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Convert an array of "yieldables" to a promise. |  | ||||||
|  * Uses `Promise.all()` internally. |  | ||||||
|  * |  | ||||||
|  * @param {Array} obj |  | ||||||
|  * @return {Promise} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function arrayToPromise(obj) { |  | ||||||
|   return Promise.all(obj.map(toPromise, this)); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Convert an object of "yieldables" to a promise. |  | ||||||
|  * Uses `Promise.all()` internally. |  | ||||||
|  * |  | ||||||
|  * @param {Object} obj |  | ||||||
|  * @return {Promise} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function objectToPromise(obj){ |  | ||||||
|   var results = new obj.constructor(); |  | ||||||
|   var keys = Object.keys(obj); |  | ||||||
|   var promises = []; |  | ||||||
|   for (var i = 0; i < keys.length; i++) { |  | ||||||
|     var key = keys[i]; |  | ||||||
|     var promise = toPromise.call(this, obj[key]); |  | ||||||
|     if (promise && isPromise(promise)) defer(promise, key); |  | ||||||
|     else results[key] = obj[key]; |  | ||||||
|   } |  | ||||||
|   return Promise.all(promises).then(function () { |  | ||||||
|     return results; |  | ||||||
|   }); |  | ||||||
|  |  | ||||||
|   function defer(promise, key) { |  | ||||||
|     // predefine the key in the result |  | ||||||
|     results[key] = undefined; |  | ||||||
|     promises.push(promise.then(function (res) { |  | ||||||
|       results[key] = res; |  | ||||||
|     })); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Check if `obj` is a promise. |  | ||||||
|  * |  | ||||||
|  * @param {Object} obj |  | ||||||
|  * @return {Boolean} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function isPromise(obj) { |  | ||||||
|   return 'function' == typeof obj.then; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Check if `obj` is a generator. |  | ||||||
|  * |  | ||||||
|  * @param {Mixed} obj |  | ||||||
|  * @return {Boolean} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function isGenerator(obj) { |  | ||||||
|   return 'function' == typeof obj.next && 'function' == typeof obj.throw; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Check if `obj` is a generator function. |  | ||||||
|  * |  | ||||||
|  * @param {Mixed} obj |  | ||||||
|  * @return {Boolean} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|   |  | ||||||
| function isGeneratorFunction(obj) { |  | ||||||
|   var constructor = obj.constructor; |  | ||||||
|   if (!constructor) return false; |  | ||||||
|   if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true; |  | ||||||
|   return isGenerator(constructor.prototype); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * Check for plain object. |  | ||||||
|  * |  | ||||||
|  * @param {Mixed} val |  | ||||||
|  * @return {Boolean} |  | ||||||
|  * @api private |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
| function isObject(val) { |  | ||||||
|   return Object == val.constructor; |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -3,7 +3,8 @@ import { Terminal } from '@xterm/xterm'; | |||||||
| import { FitAddon } from '@xterm/addon-fit'; | import { FitAddon } from '@xterm/addon-fit'; | ||||||
| import { SerializeAddon } from '@xterm/addon-serialize'; | import { SerializeAddon } from '@xterm/addon-serialize'; | ||||||
| import JSZM from "../../lib/zork"; | import JSZM from "../../lib/zork"; | ||||||
| var co = require("../../lib/co/index.js"); | // var co = require("../../lib/co/index.js"); | ||||||
|  | import co from "../../lib/co"; | ||||||
|  |  | ||||||
| export class DebugWidget implements FarpatchWidget { | export class DebugWidget implements FarpatchWidget { | ||||||
|     name: string; |     name: string; | ||||||
| @@ -79,15 +80,15 @@ export class DebugWidget implements FarpatchWidget { | |||||||
|             var debugWidget = this; |             var debugWidget = this; | ||||||
|             fetch("/zork1.z3").then((response) => { |             fetch("/zork1.z3").then((response) => { | ||||||
|                 response.arrayBuffer().then((buffer) => { |                 response.arrayBuffer().then((buffer) => { | ||||||
|                     this.zork = co.co(function* () { |                     this.zork = co(function* () { | ||||||
|                         var zork = new JSZM(new Uint8Array(buffer)); |                         var zork = new JSZM(new Uint8Array(buffer)); | ||||||
|                         zork.print = function* (str: string) { |                         zork.print = function* (str: string) { | ||||||
|                             str = str.replace("\n", "\r\n"); |                             str = str.replace("\n", "\r\n"); | ||||||
|                             zorkTerminal.write(str); |                             zorkTerminal.write(str); | ||||||
|                         }; |                         }; | ||||||
|                         zork.read =  function* (maxlen: number): Generator  { |                         zork.read = function* (_maxlen: number): Generator { | ||||||
|                             // console.log("Zork: read " + maxlen); |                             // console.log("Zork: read " + maxlen); | ||||||
|                             var val = yield new Promise((resolve, reject) => { |                             var val = yield new Promise((resolve, _reject) => { | ||||||
|                                 debugWidget.zorkCallback = resolve; |                                 debugWidget.zorkCallback = resolve; | ||||||
|                             }); |                             }); | ||||||
|                             return val; |                             return val; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user