Skip to content

Instantly share code, notes, and snippets.

@marcioj
Created December 2, 2014 04:09
Show Gist options
  • Save marcioj/f32d833a702a49230afb to your computer and use it in GitHub Desktop.
Save marcioj/f32d833a702a49230afb to your computer and use it in GitHub Desktop.
Regenerator
// app/routes/users/index.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
remove: function(model) {
if(confirm('Are you sure?')) {
model.destroyRecord();
}
}
},
model: async function() {
var users = await this.store.find('user');
console.log(users.get('firstObject.name'));
}
});
// becomes
define("esnext-test/routes/users/index",
["ember","exports"],
function(__dependency1__, __exports__) {
"use strict";
(function(
// Reliable reference to the global object (i.e. window in browsers).
global,
// Dummy constructor that we use as the .constructor property for
// functions that return Generator objects.
GeneratorFunction
) {
var hasOwn = Object.prototype.hasOwnProperty;
var undefined; // More compressible than void 0.
var iteratorSymbol =
typeof Symbol === "function" && Symbol.iterator || "@@iterator";
try {
// Make a reasonable attempt to provide a Promise polyfill.
var Promise = global.Promise || (global.Promise = require("promise"));
} catch (ignored) {}
if (global.regeneratorRuntime) {
return;
}
var runtime = global.regeneratorRuntime =
typeof exports === "undefined" ? {} : exports;
function wrap(innerFn, outerFn, self, tryList) {
return new Generator(innerFn, outerFn, self || null, tryList || []);
}
runtime.wrap = wrap;
var GenStateSuspendedStart = "suspendedStart";
var GenStateSuspendedYield = "suspendedYield";
var GenStateExecuting = "executing";
var GenStateCompleted = "completed";
// Returning this object from the innerFn has the same effect as
// breaking out of the dispatch switch statement.
var ContinueSentinel = {};
var Gp = Generator.prototype;
var GFp = GeneratorFunction.prototype = Object.create(Function.prototype);
GFp.constructor = GeneratorFunction;
GFp.prototype = Gp;
Gp.constructor = GFp;
runtime.mark = function(genFun) {
genFun.__proto__ = GFp;
genFun.prototype = Object.create(Gp);
return genFun;
};
runtime.async = function(innerFn, outerFn, self, tryList) {
return new Promise(function(resolve, reject) {
var generator = wrap(innerFn, outerFn, self, tryList);
var callNext = step.bind(generator.next);
var callThrow = step.bind(generator.throw);
function step(arg) {
try {
var info = this(arg);
var value = info.value;
} catch (error) {
return reject(error);
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(callNext, callThrow);
}
}
callNext();
});
};
// Ensure isGeneratorFunction works when Function#name not supported.
if (GeneratorFunction.name !== "GeneratorFunction") {
GeneratorFunction.name = "GeneratorFunction";
}
runtime.isGeneratorFunction = function(genFun) {
var ctor = genFun && genFun.constructor;
return ctor ? GeneratorFunction.name === ctor.name : false;
};
function Generator(innerFn, outerFn, self, tryList) {
var generator = outerFn ? Object.create(outerFn.prototype) : this;
var context = new Context(tryList);
var state = GenStateSuspendedStart;
function invoke(method, arg) {
if (state === GenStateExecuting) {
throw new Error("Generator is already running");
}
if (state === GenStateCompleted) {
throw new Error("Generator has already finished");
}
while (true) {
var delegate = context.delegate;
if (delegate) {
try {
var info = delegate.iterator[method](arg);
// Delegate generator ran and handled its own exceptions so
// regardless of what the method was, we continue as if it is
// "next" with an undefined arg.
method = "next";
arg = undefined;
} catch (uncaught) {
context.delegate = null;
// Like returning generator.throw(uncaught), but without the
// overhead of an extra function call.
method = "throw";
arg = uncaught;
continue;
}
if (info.done) {
context[delegate.resultName] = info.value;
context.next = delegate.nextLoc;
} else {
state = GenStateSuspendedYield;
return info;
}
context.delegate = null;
}
if (method === "next") {
if (state === GenStateSuspendedStart &&
typeof arg !== "undefined") {
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
throw new TypeError(
"attempt to send " + JSON.stringify(arg) + " to newborn generator"
);
}
if (state === GenStateSuspendedYield) {
context.sent = arg;
} else {
delete context.sent;
}
} else if (method === "throw") {
if (state === GenStateSuspendedStart) {
state = GenStateCompleted;
throw arg;
}
if (context.dispatchException(arg)) {
// If the dispatched exception was caught by a catch block,
// then let that catch block handle the exception normally.
method = "next";
arg = undefined;
}
} else if (method === "return") {
context.abrupt("return", arg);
}
state = GenStateExecuting;
try {
var value = innerFn.call(self, context);
// If an exception is thrown from innerFn, we leave state ===
// GenStateExecuting and loop back for another invocation.
state = context.done
? GenStateCompleted
: GenStateSuspendedYield;
var info = {
value: value,
done: context.done
};
if (value === ContinueSentinel) {
if (context.delegate && method === "next") {
// Deliberately forget the last sent value so that we don't
// accidentally pass it on to the delegate.
arg = undefined;
}
} else {
return info;
}
} catch (thrown) {
state = GenStateCompleted;
if (method === "next") {
context.dispatchException(thrown);
} else {
arg = thrown;
}
}
}
}
generator.next = invoke.bind(generator, "next");
generator.throw = invoke.bind(generator, "throw");
generator.return = invoke.bind(generator, "return");
return generator;
}
Gp[iteratorSymbol] = function() {
return this;
};
Gp.toString = function() {
return "[object Generator]";
};
function pushTryEntry(triple) {
var entry = { tryLoc: triple[0] };
if (1 in triple) {
entry.catchLoc = triple[1];
}
if (2 in triple) {
entry.finallyLoc = triple[2];
}
this.tryEntries.push(entry);
}
function resetTryEntry(entry, i) {
var record = entry.completion || {};
record.type = i === 0 ? "normal" : "return";
delete record.arg;
entry.completion = record;
}
function Context(tryList) {
// The root entry object (effectively a try statement without a catch
// or a finally block) gives us a place to store values thrown from
// locations where there is no enclosing try statement.
this.tryEntries = [{ tryLoc: "root" }];
tryList.forEach(pushTryEntry, this);
this.reset();
}
runtime.keys = function(object) {
var keys = [];
for (var key in object) {
keys.push(key);
}
keys.reverse();
// Rather than returning an object with a next method, we keep
// things simple and return the next function itself.
return function next() {
while (keys.length) {
var key = keys.pop();
if (key in object) {
next.value = key;
next.done = false;
return next;
}
}
// To avoid creating an additional object, we just hang the .value
// and .done properties off the next function object itself. This
// also ensures that the minifier will not anonymize the function.
next.done = true;
return next;
};
};
function values(iterable) {
var iterator = iterable;
if (iteratorSymbol in iterable) {
iterator = iterable[iteratorSymbol]();
} else if (!isNaN(iterable.length)) {
var i = -1;
iterator = function next() {
while (++i < iterable.length) {
if (i in iterable) {
next.value = iterable[i];
next.done = false;
return next;
}
};
next.done = true;
return next;
};
iterator.next = iterator;
}
return iterator;
}
runtime.values = values;
Context.prototype = {
constructor: Context,
reset: function() {
this.prev = 0;
this.next = 0;
this.sent = undefined;
this.done = false;
this.delegate = null;
this.tryEntries.forEach(resetTryEntry);
// Pre-initialize at least 20 temporary variables to enable hidden
// class optimizations for simple generators.
for (var tempIndex = 0, tempName;
hasOwn.call(this, tempName = "t" + tempIndex) || tempIndex < 20;
++tempIndex) {
this[tempName] = null;
}
},
stop: function() {
this.done = true;
var rootEntry = this.tryEntries[0];
var rootRecord = rootEntry.completion;
if (rootRecord.type === "throw") {
throw rootRecord.arg;
}
return this.rval;
},
dispatchException: function(exception) {
if (this.done) {
throw exception;
}
var context = this;
function handle(loc, caught) {
record.type = "throw";
record.arg = exception;
context.next = loc;
return !!caught;
}
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
var record = entry.completion;
if (entry.tryLoc === "root") {
// Exception thrown outside of any try block that could handle
// it, so set the completion value of the entire function to
// throw the exception.
return handle("end");
}
if (entry.tryLoc <= this.prev) {
var hasCatch = hasOwn.call(entry, "catchLoc");
var hasFinally = hasOwn.call(entry, "finallyLoc");
if (hasCatch && hasFinally) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
} else if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else if (hasCatch) {
if (this.prev < entry.catchLoc) {
return handle(entry.catchLoc, true);
}
} else if (hasFinally) {
if (this.prev < entry.finallyLoc) {
return handle(entry.finallyLoc);
}
} else {
throw new Error("try statement without catch or finally");
}
}
}
},
_findFinallyEntry: function(finallyLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc <= this.prev &&
hasOwn.call(entry, "finallyLoc") && (
entry.finallyLoc === finallyLoc ||
this.prev < entry.finallyLoc)) {
return entry;
}
}
},
abrupt: function(type, arg) {
var entry = this._findFinallyEntry();
var record = entry ? entry.completion : {};
record.type = type;
record.arg = arg;
if (entry) {
this.next = entry.finallyLoc;
} else {
this.complete(record);
}
return ContinueSentinel;
},
complete: function(record) {
if (record.type === "throw") {
throw record.arg;
}
if (record.type === "break" ||
record.type === "continue") {
this.next = record.arg;
} else if (record.type === "return") {
this.rval = record.arg;
this.next = "end";
}
return ContinueSentinel;
},
finish: function(finallyLoc) {
var entry = this._findFinallyEntry(finallyLoc);
return this.complete(entry.completion);
},
"catch": function(tryLoc) {
for (var i = this.tryEntries.length - 1; i >= 0; --i) {
var entry = this.tryEntries[i];
if (entry.tryLoc === tryLoc) {
var record = entry.completion;
if (record.type === "throw") {
var thrown = record.arg;
resetTryEntry(entry, i);
}
return thrown;
}
}
// The context.catch method must only be called with a location
// argument that corresponds to a known catch block.
throw new Error("illegal catch attempt");
},
delegateYield: function(iterable, resultName, nextLoc) {
this.delegate = {
iterator: values(iterable),
resultName: resultName,
nextLoc: nextLoc
};
return ContinueSentinel;
}
};
}).apply(this, Function("return [this, function GeneratorFunction(){}]")());
var Ember = __dependency1__["default"];
__exports__["default"] = Ember.Route.extend({
actions: {
remove: function(model) {
if(confirm('Are you sure?')) {
model.destroyRecord();
}
}
},
model: function callee$0$0() {
var users;
return regeneratorRuntime.async(function callee$0$0$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
context$1$0.next = 2;
return this.store.find('user');
case 2:
users = context$1$0.sent;
console.log(users.get('firstObject.name'));
case 4:
case "end":
return context$1$0.stop();
}
}, null, this);
}
});
});//# sourceURL=esnext-test/routes/users/index.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment