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 @@ | ||||
|  | ||||
| /** | ||||
|  * 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; | ||||
| } | ||||
| module.exports = require('./co') | ||||
|   | ||||
| @@ -3,7 +3,8 @@ import { Terminal } from '@xterm/xterm'; | ||||
| import { FitAddon } from '@xterm/addon-fit'; | ||||
| import { SerializeAddon } from '@xterm/addon-serialize'; | ||||
| 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 { | ||||
|     name: string; | ||||
| @@ -79,15 +80,15 @@ export class DebugWidget implements FarpatchWidget { | ||||
|             var debugWidget = this; | ||||
|             fetch("/zork1.z3").then((response) => { | ||||
|                 response.arrayBuffer().then((buffer) => { | ||||
|                     this.zork = co.co(function* () { | ||||
|                     this.zork = co(function* () { | ||||
|                         var zork = new JSZM(new Uint8Array(buffer)); | ||||
|                         zork.print = function* (str: string) { | ||||
|                             str = str.replace("\n", "\r\n"); | ||||
|                             zorkTerminal.write(str); | ||||
|                         }; | ||||
|                         zork.read =  function* (maxlen: number): Generator  { | ||||
|                         zork.read = function* (_maxlen: number): Generator { | ||||
|                             // console.log("Zork: read " + maxlen); | ||||
|                             var val = yield new Promise((resolve, reject) => { | ||||
|                             var val = yield new Promise((resolve, _reject) => { | ||||
|                                 debugWidget.zorkCallback = resolve; | ||||
|                             }); | ||||
|                             return val; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user