removed all uses of promises; remove promise library since it's not longer needed
This commit is contained in:
parent
291ef6bc94
commit
bb46fa34e8
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
823
lib/when.js
823
lib/when.js
|
@ -1,823 +0,0 @@
|
||||||
/** @license MIT License (c) copyright 2011-2013 original author or authors */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A lightweight CommonJS Promises/A and when() implementation
|
|
||||||
* when is part of the cujo.js family of libraries (http://cujojs.com/)
|
|
||||||
*
|
|
||||||
* Licensed under the MIT License at:
|
|
||||||
* http://www.opensource.org/licenses/mit-license.php
|
|
||||||
*
|
|
||||||
* @author Brian Cavalier
|
|
||||||
* @author John Hann
|
|
||||||
* @version 2.1.0
|
|
||||||
*/
|
|
||||||
(function(define, global) { 'use strict';
|
|
||||||
define(function () {
|
|
||||||
|
|
||||||
// Public API
|
|
||||||
|
|
||||||
when.defer = defer; // Create a deferred
|
|
||||||
when.resolve = resolve; // Create a resolved promise
|
|
||||||
when.reject = reject; // Create a rejected promise
|
|
||||||
|
|
||||||
when.join = join; // Join 2 or more promises
|
|
||||||
|
|
||||||
when.all = all; // Resolve a list of promises
|
|
||||||
when.map = map; // Array.map() for promises
|
|
||||||
when.reduce = reduce; // Array.reduce() for promises
|
|
||||||
when.settle = settle; // Settle a list of promises
|
|
||||||
|
|
||||||
when.any = any; // One-winner race
|
|
||||||
when.some = some; // Multi-winner race
|
|
||||||
|
|
||||||
when.isPromise = isPromise; // Determine if a thing is a promise
|
|
||||||
|
|
||||||
when.promise = promise; // EXPERIMENTAL: May change. Use at your own risk
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register an observer for a promise or immediate value.
|
|
||||||
*
|
|
||||||
* @param {*} promiseOrValue
|
|
||||||
* @param {function?} [onFulfilled] callback to be called when promiseOrValue is
|
|
||||||
* successfully fulfilled. If promiseOrValue is an immediate value, callback
|
|
||||||
* will be invoked immediately.
|
|
||||||
* @param {function?} [onRejected] callback to be called when promiseOrValue is
|
|
||||||
* rejected.
|
|
||||||
* @param {function?} [onProgress] callback to be called when progress updates
|
|
||||||
* are issued for promiseOrValue.
|
|
||||||
* @returns {Promise} a new {@link Promise} that will complete with the return
|
|
||||||
* value of callback or errback or the completion value of promiseOrValue if
|
|
||||||
* callback and/or errback is not supplied.
|
|
||||||
*/
|
|
||||||
function when(promiseOrValue, onFulfilled, onRejected, onProgress) {
|
|
||||||
// Get a trusted promise for the input promiseOrValue, and then
|
|
||||||
// register promise handlers
|
|
||||||
return resolve(promiseOrValue).then(onFulfilled, onRejected, onProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trusted Promise constructor. A Promise created from this constructor is
|
|
||||||
* a trusted when.js promise. Any other duck-typed promise is considered
|
|
||||||
* untrusted.
|
|
||||||
* @constructor
|
|
||||||
* @name Promise
|
|
||||||
*/
|
|
||||||
function Promise(then, inspect) {
|
|
||||||
this.then = then;
|
|
||||||
this.inspect = inspect;
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise.prototype = {
|
|
||||||
/**
|
|
||||||
* Register a rejection handler. Shortcut for .then(undefined, onRejected)
|
|
||||||
* @param {function?} onRejected
|
|
||||||
* @return {Promise}
|
|
||||||
*/
|
|
||||||
otherwise: function(onRejected) {
|
|
||||||
return this.then(undef, onRejected);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that onFulfilledOrRejected will be called regardless of whether
|
|
||||||
* this promise is fulfilled or rejected. onFulfilledOrRejected WILL NOT
|
|
||||||
* receive the promises' value or reason. Any returned value will be disregarded.
|
|
||||||
* onFulfilledOrRejected may throw or return a rejected promise to signal
|
|
||||||
* an additional error.
|
|
||||||
* @param {function} onFulfilledOrRejected handler to be called regardless of
|
|
||||||
* fulfillment or rejection
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
ensure: function(onFulfilledOrRejected) {
|
|
||||||
return this.then(injectHandler, injectHandler).yield(this);
|
|
||||||
|
|
||||||
function injectHandler() {
|
|
||||||
return resolve(onFulfilledOrRejected());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shortcut for .then(function() { return value; })
|
|
||||||
* @param {*} value
|
|
||||||
* @return {Promise} a promise that:
|
|
||||||
* - is fulfilled if value is not a promise, or
|
|
||||||
* - if value is a promise, will fulfill with its value, or reject
|
|
||||||
* with its reason.
|
|
||||||
*/
|
|
||||||
'yield': function(value) {
|
|
||||||
return this.then(function() {
|
|
||||||
return value;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assumes that this promise will fulfill with an array, and arranges
|
|
||||||
* for the onFulfilled to be called with the array as its argument list
|
|
||||||
* i.e. onFulfilled.apply(undefined, array).
|
|
||||||
* @param {function} onFulfilled function to receive spread arguments
|
|
||||||
* @return {Promise}
|
|
||||||
*/
|
|
||||||
spread: function(onFulfilled) {
|
|
||||||
return this.then(function(array) {
|
|
||||||
// array may contain promises, so resolve its contents.
|
|
||||||
return all(array, function(array) {
|
|
||||||
return onFulfilled.apply(undef, array);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected)
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
always: function(onFulfilledOrRejected, onProgress) {
|
|
||||||
return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a resolved promise. The returned promise will be
|
|
||||||
* - fulfilled with promiseOrValue if it is a value, or
|
|
||||||
* - if promiseOrValue is a promise
|
|
||||||
* - fulfilled with promiseOrValue's value after it is fulfilled
|
|
||||||
* - rejected with promiseOrValue's reason after it is rejected
|
|
||||||
* @param {*} value
|
|
||||||
* @return {Promise}
|
|
||||||
*/
|
|
||||||
function resolve(value) {
|
|
||||||
return promise(function(resolve) {
|
|
||||||
resolve(value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a rejected promise for the supplied promiseOrValue. The returned
|
|
||||||
* promise will be rejected with:
|
|
||||||
* - promiseOrValue, if it is a value, or
|
|
||||||
* - if promiseOrValue is a promise
|
|
||||||
* - promiseOrValue's value after it is fulfilled
|
|
||||||
* - promiseOrValue's reason after it is rejected
|
|
||||||
* @param {*} promiseOrValue the rejected value of the returned {@link Promise}
|
|
||||||
* @return {Promise} rejected {@link Promise}
|
|
||||||
*/
|
|
||||||
function reject(promiseOrValue) {
|
|
||||||
return when(promiseOrValue, rejected);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new Deferred with fully isolated resolver and promise parts,
|
|
||||||
* either or both of which may be given out safely to consumers.
|
|
||||||
* The resolver has resolve, reject, and progress. The promise
|
|
||||||
* only has then.
|
|
||||||
*
|
|
||||||
* @return {{
|
|
||||||
* promise: Promise,
|
|
||||||
* resolve: function:Promise,
|
|
||||||
* reject: function:Promise,
|
|
||||||
* notify: function:Promise
|
|
||||||
* resolver: {
|
|
||||||
* resolve: function:Promise,
|
|
||||||
* reject: function:Promise,
|
|
||||||
* notify: function:Promise
|
|
||||||
* }}}
|
|
||||||
*/
|
|
||||||
function defer() {
|
|
||||||
var deferred, pending, resolved;
|
|
||||||
|
|
||||||
// Optimize object shape
|
|
||||||
deferred = {
|
|
||||||
promise: undef, resolve: undef, reject: undef, notify: undef,
|
|
||||||
resolver: { resolve: undef, reject: undef, notify: undef }
|
|
||||||
};
|
|
||||||
|
|
||||||
deferred.promise = pending = promise(makeDeferred);
|
|
||||||
|
|
||||||
return deferred;
|
|
||||||
|
|
||||||
function makeDeferred(resolvePending, rejectPending, notifyPending) {
|
|
||||||
deferred.resolve = deferred.resolver.resolve = function(value) {
|
|
||||||
if(resolved) {
|
|
||||||
return resolve(value);
|
|
||||||
}
|
|
||||||
resolved = true;
|
|
||||||
resolvePending(value);
|
|
||||||
return pending;
|
|
||||||
};
|
|
||||||
|
|
||||||
deferred.reject = deferred.resolver.reject = function(reason) {
|
|
||||||
if(resolved) {
|
|
||||||
return resolve(rejected(reason));
|
|
||||||
}
|
|
||||||
resolved = true;
|
|
||||||
rejectPending(reason);
|
|
||||||
return pending;
|
|
||||||
};
|
|
||||||
|
|
||||||
deferred.notify = deferred.resolver.notify = function(update) {
|
|
||||||
notifyPending(update);
|
|
||||||
return update;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new promise whose fate is determined by resolver.
|
|
||||||
* @private (for now)
|
|
||||||
* @param {function} resolver function(resolve, reject, notify)
|
|
||||||
* @returns {Promise} promise whose fate is determine by resolver
|
|
||||||
*/
|
|
||||||
function promise(resolver) {
|
|
||||||
var value, handlers = [];
|
|
||||||
|
|
||||||
// Call the provider resolver to seal the promise's fate
|
|
||||||
try {
|
|
||||||
resolver(promiseResolve, promiseReject, promiseNotify);
|
|
||||||
} catch(e) {
|
|
||||||
promiseReject(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the promise
|
|
||||||
return new Promise(then, inspect);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register handlers for this promise.
|
|
||||||
* @param [onFulfilled] {Function} fulfillment handler
|
|
||||||
* @param [onRejected] {Function} rejection handler
|
|
||||||
* @param [onProgress] {Function} progress handler
|
|
||||||
* @return {Promise} new Promise
|
|
||||||
*/
|
|
||||||
function then(onFulfilled, onRejected, onProgress) {
|
|
||||||
return promise(function(resolve, reject, notify) {
|
|
||||||
handlers
|
|
||||||
// Call handlers later, after resolution
|
|
||||||
? handlers.push(function(value) {
|
|
||||||
value.then(onFulfilled, onRejected, onProgress)
|
|
||||||
.then(resolve, reject, notify);
|
|
||||||
})
|
|
||||||
// Call handlers soon, but not in the current stack
|
|
||||||
: enqueue(function() {
|
|
||||||
value.then(onFulfilled, onRejected, onProgress)
|
|
||||||
.then(resolve, reject, notify);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function inspect() {
|
|
||||||
return value ? value.inspect() : toPendingState();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transition from pre-resolution state to post-resolution state, notifying
|
|
||||||
* all listeners of the ultimate fulfillment or rejection
|
|
||||||
* @param {*|Promise} val resolution value
|
|
||||||
*/
|
|
||||||
function promiseResolve(val) {
|
|
||||||
if(!handlers) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
value = coerce(val);
|
|
||||||
scheduleHandlers(handlers, value);
|
|
||||||
|
|
||||||
handlers = undef;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reject this promise with the supplied reason, which will be used verbatim.
|
|
||||||
* @param {*} reason reason for the rejection
|
|
||||||
*/
|
|
||||||
function promiseReject(reason) {
|
|
||||||
promiseResolve(rejected(reason));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Issue a progress event, notifying all progress listeners
|
|
||||||
* @param {*} update progress event payload to pass to all listeners
|
|
||||||
*/
|
|
||||||
function promiseNotify(update) {
|
|
||||||
if(handlers) {
|
|
||||||
scheduleHandlers(handlers, progressing(update));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Coerces x to a trusted Promise
|
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param {*} x thing to coerce
|
|
||||||
* @returns {Promise} Guaranteed to return a trusted Promise. If x
|
|
||||||
* is trusted, returns x, otherwise, returns a new, trusted, already-resolved
|
|
||||||
* Promise whose resolution value is:
|
|
||||||
* * the resolution value of x if it's a foreign promise, or
|
|
||||||
* * x if it's a value
|
|
||||||
*/
|
|
||||||
function coerce(x) {
|
|
||||||
if(x instanceof Promise) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(x === Object(x) && 'then' in x)) {
|
|
||||||
return fulfilled(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise(function(resolve, reject, notify) {
|
|
||||||
enqueue(function() {
|
|
||||||
try {
|
|
||||||
// We must check and assimilate in the same tick, but not the
|
|
||||||
// current tick, careful only to access promiseOrValue.then once.
|
|
||||||
var untrustedThen = x.then;
|
|
||||||
|
|
||||||
if(typeof untrustedThen === 'function') {
|
|
||||||
fcall(untrustedThen, x, resolve, reject, notify);
|
|
||||||
} else {
|
|
||||||
// It's a value, create a fulfilled wrapper
|
|
||||||
resolve(fulfilled(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch(e) {
|
|
||||||
// Something went wrong, reject
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an already-fulfilled promise for the supplied value
|
|
||||||
* @private
|
|
||||||
* @param {*} value
|
|
||||||
* @return {Promise} fulfilled promise
|
|
||||||
*/
|
|
||||||
function fulfilled(value) {
|
|
||||||
var self = new Promise(function (onFulfilled) {
|
|
||||||
try {
|
|
||||||
return typeof onFulfilled == 'function'
|
|
||||||
? coerce(onFulfilled(value)) : self;
|
|
||||||
} catch (e) {
|
|
||||||
return rejected(e);
|
|
||||||
}
|
|
||||||
}, function() {
|
|
||||||
return toFulfilledState(value);
|
|
||||||
});
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an already-rejected promise with the supplied rejection reason.
|
|
||||||
* @private
|
|
||||||
* @param {*} reason
|
|
||||||
* @return {Promise} rejected promise
|
|
||||||
*/
|
|
||||||
function rejected(reason) {
|
|
||||||
var self = new Promise(function (_, onRejected) {
|
|
||||||
try {
|
|
||||||
return typeof onRejected == 'function'
|
|
||||||
? coerce(onRejected(reason)) : self;
|
|
||||||
} catch (e) {
|
|
||||||
return rejected(e);
|
|
||||||
}
|
|
||||||
}, function() {
|
|
||||||
return toRejectedState(reason);
|
|
||||||
});
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a progress promise with the supplied update.
|
|
||||||
* @private
|
|
||||||
* @param {*} update
|
|
||||||
* @return {Promise} progress promise
|
|
||||||
*/
|
|
||||||
function progressing(update) {
|
|
||||||
var self = new Promise(function (_, __, onProgress) {
|
|
||||||
try {
|
|
||||||
return typeof onProgress == 'function'
|
|
||||||
? progressing(onProgress(update)) : self;
|
|
||||||
} catch (e) {
|
|
||||||
return progressing(e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedule a task that will process a list of handlers
|
|
||||||
* in the next queue drain run.
|
|
||||||
* @private
|
|
||||||
* @param {Array} handlers queue of handlers to execute
|
|
||||||
* @param {*} value passed as the only arg to each handler
|
|
||||||
*/
|
|
||||||
function scheduleHandlers(handlers, value) {
|
|
||||||
enqueue(function() {
|
|
||||||
var handler, i = 0;
|
|
||||||
while (handler = handlers[i++]) {
|
|
||||||
handler(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if promiseOrValue is a promise or not
|
|
||||||
*
|
|
||||||
* @param {*} promiseOrValue anything
|
|
||||||
* @returns {boolean} true if promiseOrValue is a {@link Promise}
|
|
||||||
*/
|
|
||||||
function isPromise(promiseOrValue) {
|
|
||||||
return promiseOrValue && typeof promiseOrValue.then === 'function';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiates a competitive race, returning a promise that will resolve when
|
|
||||||
* howMany of the supplied promisesOrValues have resolved, or will reject when
|
|
||||||
* it becomes impossible for howMany to resolve, for example, when
|
|
||||||
* (promisesOrValues.length - howMany) + 1 input promises reject.
|
|
||||||
*
|
|
||||||
* @param {Array} promisesOrValues array of anything, may contain a mix
|
|
||||||
* of promises and values
|
|
||||||
* @param howMany {number} number of promisesOrValues to resolve
|
|
||||||
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @returns {Promise} promise that will resolve to an array of howMany values that
|
|
||||||
* resolved first, or will reject with an array of
|
|
||||||
* (promisesOrValues.length - howMany) + 1 rejection reasons.
|
|
||||||
*/
|
|
||||||
function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) {
|
|
||||||
|
|
||||||
return when(promisesOrValues, function(promisesOrValues) {
|
|
||||||
|
|
||||||
return promise(resolveSome).then(onFulfilled, onRejected, onProgress);
|
|
||||||
|
|
||||||
function resolveSome(resolve, reject, notify) {
|
|
||||||
var toResolve, toReject, values, reasons, fulfillOne, rejectOne, len, i;
|
|
||||||
|
|
||||||
len = promisesOrValues.length >>> 0;
|
|
||||||
|
|
||||||
toResolve = Math.max(0, Math.min(howMany, len));
|
|
||||||
values = [];
|
|
||||||
|
|
||||||
toReject = (len - toResolve) + 1;
|
|
||||||
reasons = [];
|
|
||||||
|
|
||||||
// No items in the input, resolve immediately
|
|
||||||
if (!toResolve) {
|
|
||||||
resolve(values);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
rejectOne = function(reason) {
|
|
||||||
reasons.push(reason);
|
|
||||||
if(!--toReject) {
|
|
||||||
fulfillOne = rejectOne = identity;
|
|
||||||
reject(reasons);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fulfillOne = function(val) {
|
|
||||||
// This orders the values based on promise resolution order
|
|
||||||
values.push(val);
|
|
||||||
if (!--toResolve) {
|
|
||||||
fulfillOne = rejectOne = identity;
|
|
||||||
resolve(values);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for(i = 0; i < len; ++i) {
|
|
||||||
if(i in promisesOrValues) {
|
|
||||||
when(promisesOrValues[i], fulfiller, rejecter, notify);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function rejecter(reason) {
|
|
||||||
rejectOne(reason);
|
|
||||||
}
|
|
||||||
|
|
||||||
function fulfiller(val) {
|
|
||||||
fulfillOne(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initiates a competitive race, returning a promise that will resolve when
|
|
||||||
* any one of the supplied promisesOrValues has resolved or will reject when
|
|
||||||
* *all* promisesOrValues have rejected.
|
|
||||||
*
|
|
||||||
* @param {Array|Promise} promisesOrValues array of anything, may contain a mix
|
|
||||||
* of {@link Promise}s and values
|
|
||||||
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @returns {Promise} promise that will resolve to the value that resolved first, or
|
|
||||||
* will reject with an array of all rejected inputs.
|
|
||||||
*/
|
|
||||||
function any(promisesOrValues, onFulfilled, onRejected, onProgress) {
|
|
||||||
|
|
||||||
function unwrapSingleResult(val) {
|
|
||||||
return onFulfilled ? onFulfilled(val[0]) : val[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a promise that will resolve only once all the supplied promisesOrValues
|
|
||||||
* have resolved. The resolution value of the returned promise will be an array
|
|
||||||
* containing the resolution values of each of the promisesOrValues.
|
|
||||||
* @memberOf when
|
|
||||||
*
|
|
||||||
* @param {Array|Promise} promisesOrValues array of anything, may contain a mix
|
|
||||||
* of {@link Promise}s and values
|
|
||||||
* @param {function?} [onFulfilled] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @param {function?} [onRejected] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @param {function?} [onProgress] DEPRECATED, use returnedPromise.then()
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
function all(promisesOrValues, onFulfilled, onRejected, onProgress) {
|
|
||||||
return _map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Joins multiple promises into a single returned promise.
|
|
||||||
* @return {Promise} a promise that will fulfill when *all* the input promises
|
|
||||||
* have fulfilled, or will reject when *any one* of the input promises rejects.
|
|
||||||
*/
|
|
||||||
function join(/* ...promises */) {
|
|
||||||
return _map(arguments, identity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Settles all input promises such that they are guaranteed not to
|
|
||||||
* be pending once the returned promise fulfills. The returned promise
|
|
||||||
* will always fulfill, except in the case where `array` is a promise
|
|
||||||
* that rejects.
|
|
||||||
* @param {Array|Promise} array or promise for array of promises to settle
|
|
||||||
* @returns {Promise} promise that always fulfills with an array of
|
|
||||||
* outcome snapshots for each input promise.
|
|
||||||
*/
|
|
||||||
function settle(array) {
|
|
||||||
return _map(array, toFulfilledState, toRejectedState);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Promise-aware array map function, similar to `Array.prototype.map()`,
|
|
||||||
* but input array may contain promises or values.
|
|
||||||
* @param {Array|Promise} array array of anything, may contain promises and values
|
|
||||||
* @param {function} mapFunc map function which may return a promise or value
|
|
||||||
* @returns {Promise} promise that will fulfill with an array of mapped values
|
|
||||||
* or reject if any input promise rejects.
|
|
||||||
*/
|
|
||||||
function map(array, mapFunc) {
|
|
||||||
return _map(array, mapFunc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal map that allows a fallback to handle rejections
|
|
||||||
* @param {Array|Promise} array array of anything, may contain promises and values
|
|
||||||
* @param {function} mapFunc map function which may return a promise or value
|
|
||||||
* @param {function?} fallback function to handle rejected promises
|
|
||||||
* @returns {Promise} promise that will fulfill with an array of mapped values
|
|
||||||
* or reject if any input promise rejects.
|
|
||||||
*/
|
|
||||||
function _map(array, mapFunc, fallback) {
|
|
||||||
return when(array, function(array) {
|
|
||||||
|
|
||||||
return promise(resolveMap);
|
|
||||||
|
|
||||||
function resolveMap(resolve, reject, notify) {
|
|
||||||
var results, len, toResolve, resolveOne, i;
|
|
||||||
|
|
||||||
// Since we know the resulting length, we can preallocate the results
|
|
||||||
// array to avoid array expansions.
|
|
||||||
toResolve = len = array.length >>> 0;
|
|
||||||
results = [];
|
|
||||||
|
|
||||||
if(!toResolve) {
|
|
||||||
resolve(results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resolveOne = function(item, i) {
|
|
||||||
when(item, mapFunc, fallback).then(function(mapped) {
|
|
||||||
results[i] = mapped;
|
|
||||||
|
|
||||||
if(!--toResolve) {
|
|
||||||
resolve(results);
|
|
||||||
}
|
|
||||||
}, reject, notify);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Since mapFunc may be async, get all invocations of it into flight
|
|
||||||
for(i = 0; i < len; i++) {
|
|
||||||
if(i in array) {
|
|
||||||
resolveOne(array[i], i);
|
|
||||||
} else {
|
|
||||||
--toResolve;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Traditional reduce function, similar to `Array.prototype.reduce()`, but
|
|
||||||
* input may contain promises and/or values, and reduceFunc
|
|
||||||
* may return either a value or a promise, *and* initialValue may
|
|
||||||
* be a promise for the starting value.
|
|
||||||
*
|
|
||||||
* @param {Array|Promise} promise array or promise for an array of anything,
|
|
||||||
* may contain a mix of promises and values.
|
|
||||||
* @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total),
|
|
||||||
* where total is the total number of items being reduced, and will be the same
|
|
||||||
* in each call to reduceFunc.
|
|
||||||
* @returns {Promise} that will resolve to the final reduced value
|
|
||||||
*/
|
|
||||||
function reduce(promise, reduceFunc /*, initialValue */) {
|
|
||||||
var args = fcall(slice, arguments, 1);
|
|
||||||
|
|
||||||
return when(promise, function(array) {
|
|
||||||
var total;
|
|
||||||
|
|
||||||
total = array.length;
|
|
||||||
|
|
||||||
// Wrap the supplied reduceFunc with one that handles promises and then
|
|
||||||
// delegates to the supplied.
|
|
||||||
args[0] = function (current, val, i) {
|
|
||||||
return when(current, function (c) {
|
|
||||||
return when(val, function (value) {
|
|
||||||
return reduceFunc(c, value, i, total);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return reduceArray.apply(array, args);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Snapshot states
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a fulfilled state snapshot
|
|
||||||
* @private
|
|
||||||
* @param {*} x any value
|
|
||||||
* @returns {{state:'fulfilled',value:*}}
|
|
||||||
*/
|
|
||||||
function toFulfilledState(x) {
|
|
||||||
return { state: 'fulfilled', value: x };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a rejected state snapshot
|
|
||||||
* @private
|
|
||||||
* @param {*} x any reason
|
|
||||||
* @returns {{state:'rejected',reason:*}}
|
|
||||||
*/
|
|
||||||
function toRejectedState(x) {
|
|
||||||
return { state: 'rejected', reason: x };
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a pending state snapshot
|
|
||||||
* @private
|
|
||||||
* @returns {{state:'pending'}}
|
|
||||||
*/
|
|
||||||
function toPendingState() {
|
|
||||||
return { state: 'pending' };
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Utilities, etc.
|
|
||||||
//
|
|
||||||
|
|
||||||
var reduceArray, slice, fcall, nextTick, handlerQueue,
|
|
||||||
setTimeout, funcProto, call, arrayProto, undef;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Shared handler queue processing
|
|
||||||
//
|
|
||||||
// Credit to Twisol (https://github.com/Twisol) for suggesting
|
|
||||||
// this type of extensible queue + trampoline approach for
|
|
||||||
// next-tick conflation.
|
|
||||||
|
|
||||||
handlerQueue = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enqueue a task. If the queue is not currently scheduled to be
|
|
||||||
* drained, schedule it.
|
|
||||||
* @param {function} task
|
|
||||||
*/
|
|
||||||
function enqueue(task) {
|
|
||||||
if(handlerQueue.push(task) === 1) {
|
|
||||||
scheduleDrainQueue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedule the queue to be drained after the stack has cleared.
|
|
||||||
*/
|
|
||||||
function scheduleDrainQueue() {
|
|
||||||
nextTick(drainQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Drain the handler queue entirely, being careful to allow the
|
|
||||||
* queue to be extended while it is being processed, and to continue
|
|
||||||
* processing until it is truly empty.
|
|
||||||
*/
|
|
||||||
function drainQueue() {
|
|
||||||
var task, i = 0;
|
|
||||||
|
|
||||||
while(task = handlerQueue[i++]) {
|
|
||||||
task();
|
|
||||||
}
|
|
||||||
|
|
||||||
handlerQueue = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Capture function and array utils
|
|
||||||
//
|
|
||||||
/*global setImmediate,process,vertx*/
|
|
||||||
|
|
||||||
// capture setTimeout to avoid being caught by fake timers used in time based tests
|
|
||||||
setTimeout = global.setTimeout;
|
|
||||||
// Prefer setImmediate, cascade to node, vertx and finally setTimeout
|
|
||||||
nextTick = typeof setImmediate === 'function' ? setImmediate.bind(global)
|
|
||||||
: typeof process === 'object' && process.nextTick ? process.nextTick
|
|
||||||
: typeof vertx === 'object' ? vertx.runOnLoop // vert.x
|
|
||||||
: function(task) { setTimeout(task, 0); }; // fallback
|
|
||||||
// nextTick = function(task) { task.call(); };
|
|
||||||
|
|
||||||
// Safe function calls
|
|
||||||
funcProto = Function.prototype;
|
|
||||||
call = funcProto.call;
|
|
||||||
fcall = funcProto.bind
|
|
||||||
? call.bind(call)
|
|
||||||
: function(f, context) {
|
|
||||||
return f.apply(context, slice.call(arguments, 2));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Safe array ops
|
|
||||||
arrayProto = [];
|
|
||||||
slice = arrayProto.slice;
|
|
||||||
|
|
||||||
// ES5 reduce implementation if native not available
|
|
||||||
// See: http://es5.github.com/#x15.4.4.21 as there are many
|
|
||||||
// specifics and edge cases. ES5 dictates that reduce.length === 1
|
|
||||||
// This implementation deviates from ES5 spec in the following ways:
|
|
||||||
// 1. It does not check if reduceFunc is a Callable
|
|
||||||
reduceArray = arrayProto.reduce ||
|
|
||||||
function(reduceFunc /*, initialValue */) {
|
|
||||||
/*jshint maxcomplexity: 7*/
|
|
||||||
var arr, args, reduced, len, i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
arr = Object(this);
|
|
||||||
len = arr.length >>> 0;
|
|
||||||
args = arguments;
|
|
||||||
|
|
||||||
// If no initialValue, use first item of array (we know length !== 0 here)
|
|
||||||
// and adjust i to start at second item
|
|
||||||
if(args.length <= 1) {
|
|
||||||
// Skip to the first real element in the array
|
|
||||||
for(;;) {
|
|
||||||
if(i in arr) {
|
|
||||||
reduced = arr[i++];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we reached the end of the array without finding any real
|
|
||||||
// elements, it's a TypeError
|
|
||||||
if(++i >= len) {
|
|
||||||
throw new TypeError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If initialValue provided, use it
|
|
||||||
reduced = args[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the actual reduce
|
|
||||||
for(;i < len; ++i) {
|
|
||||||
if(i in arr) {
|
|
||||||
reduced = reduceFunc(reduced, arr[i], i, arr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return reduced;
|
|
||||||
};
|
|
||||||
|
|
||||||
function identity(x) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return when;
|
|
||||||
});
|
|
||||||
})(
|
|
||||||
typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(); },
|
|
||||||
this
|
|
||||||
);
|
|
114
src/fs.js
114
src/fs.js
|
@ -3,7 +3,6 @@ define(function(require) {
|
||||||
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||||
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var when = require('when');
|
|
||||||
|
|
||||||
// TextEncoder and TextDecoder will either already be present, or use this shim.
|
// TextEncoder and TextDecoder will either already be present, or use this shim.
|
||||||
// Because of the way the spec is defined, we need to get them off the global.
|
// Because of the way the spec is defined, we need to get them off the global.
|
||||||
|
@ -775,6 +774,25 @@ define(function(require) {
|
||||||
FileSystem.prototype._release_descriptor = function _release_descriptor(fd) {
|
FileSystem.prototype._release_descriptor = function _release_descriptor(fd) {
|
||||||
delete this.openFiles[fd];
|
delete this.openFiles[fd];
|
||||||
};
|
};
|
||||||
|
FileSystem.prototype._queueOrRun = function _queueOrRun(operation) {
|
||||||
|
var error = undefined;
|
||||||
|
|
||||||
|
if(FS_READY == this.readyState) {
|
||||||
|
operation.call(this);
|
||||||
|
} else if(FS_ERROR == this.readyState) {
|
||||||
|
error = new EFileSystemError('unknown error');
|
||||||
|
} else {
|
||||||
|
this.queue.push(operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
};
|
||||||
|
FileSystem.prototype._runQueued = function _runQueued() {
|
||||||
|
this.queue.forEach(function(operation) {
|
||||||
|
operation.call(this);
|
||||||
|
}.bind(this));
|
||||||
|
this.queue = null;
|
||||||
|
};
|
||||||
FileSystem.prototype._open = function _open(context, path, flags, callback) {
|
FileSystem.prototype._open = function _open(context, path, flags, callback) {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
|
@ -1207,9 +1225,6 @@ define(function(require) {
|
||||||
var format = _(flags).contains(FS_FORMAT);
|
var format = _(flags).contains(FS_FORMAT);
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
var deferred = when.defer();
|
|
||||||
this.promise = deferred.promise;
|
|
||||||
|
|
||||||
var openRequest = indexedDB.open(name);
|
var openRequest = indexedDB.open(name);
|
||||||
openRequest.onupgradeneeded = function onupgradeneeded(event) {
|
openRequest.onupgradeneeded = function onupgradeneeded(event) {
|
||||||
var db = event.target.result;
|
var db = event.target.result;
|
||||||
|
@ -1236,10 +1251,9 @@ define(function(require) {
|
||||||
that.db = db;
|
that.db = db;
|
||||||
if(error) {
|
if(error) {
|
||||||
that.readyState = FS_ERROR;
|
that.readyState = FS_ERROR;
|
||||||
deferred.reject(error);
|
|
||||||
} else {
|
} else {
|
||||||
that.readyState = FS_READY;
|
that.readyState = FS_READY;
|
||||||
deferred.resolve();
|
that._runQueued();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,7 +1271,7 @@ define(function(require) {
|
||||||
};
|
};
|
||||||
openRequest.onerror = function onerror(error) {
|
openRequest.onerror = function onerror(error) {
|
||||||
this.readyState = FS_ERROR;
|
this.readyState = FS_ERROR;
|
||||||
deferred.reject(error);
|
this.error = error;
|
||||||
};
|
};
|
||||||
|
|
||||||
var nextDescriptor = 1;
|
var nextDescriptor = 1;
|
||||||
|
@ -1268,207 +1282,181 @@ define(function(require) {
|
||||||
this.nextDescriptor = nextDescriptor;
|
this.nextDescriptor = nextDescriptor;
|
||||||
this.openFiles = openFiles;
|
this.openFiles = openFiles;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.error = null;
|
||||||
|
this.queue = [];
|
||||||
}
|
}
|
||||||
IndexedDBFileSystem.prototype = new FileSystem();
|
IndexedDBFileSystem.prototype = new FileSystem();
|
||||||
IndexedDBFileSystem.prototype.constructor = IndexedDBFileSystem;
|
IndexedDBFileSystem.prototype.constructor = IndexedDBFileSystem;
|
||||||
IndexedDBFileSystem.prototype.open = function open(path, flags, callback) {
|
IndexedDBFileSystem.prototype.open = function open(path, flags, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._open(context, path, flags, callback);
|
fs._open(context, path, flags, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.close = function close(fd, callback) {
|
IndexedDBFileSystem.prototype.close = function close(fd, callback) {
|
||||||
this._close(fd, callback);
|
this._close(fd, callback);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.mkdir = function mkdir(path, callback) {
|
IndexedDBFileSystem.prototype.mkdir = function mkdir(path, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._mkdir(context, path, callback);
|
fs._mkdir(context, path, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.rmdir = function rmdir(path, callback) {
|
IndexedDBFileSystem.prototype.rmdir = function rmdir(path, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._rmdir(context, path, callback);
|
fs._rmdir(context, path, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.stat = function stat(path, callback) {
|
IndexedDBFileSystem.prototype.stat = function stat(path, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._stat(context, path, callback);
|
fs._stat(context, path, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.fstat = function fstat(fd, callback) {
|
IndexedDBFileSystem.prototype.fstat = function fstat(fd, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._fstat(context, fd, callback);
|
fs._fstat(context, fd, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.link = function link(oldpath, newpath, callback) {
|
IndexedDBFileSystem.prototype.link = function link(oldpath, newpath, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._link(context, oldpath, newpath, callback);
|
fs._link(context, oldpath, newpath, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.unlink = function unlink(path, callback) {
|
IndexedDBFileSystem.prototype.unlink = function unlink(path, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._unlink(context, path, callback);
|
fs._unlink(context, path, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.read = function read(fd, buffer, offset, length, position, callback) {
|
IndexedDBFileSystem.prototype.read = function read(fd, buffer, offset, length, position, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._read(context, fd, buffer, offset, length, position, callback);
|
fs._read(context, fd, buffer, offset, length, position, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.readFile = function readFile(path, options, callback) {
|
IndexedDBFileSystem.prototype.readFile = function readFile(path, options, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._readFile(context, path, options, callback);
|
fs._readFile(context, path, options, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
|
IndexedDBFileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._write(context, fd, buffer, offset, length, position, callback);
|
fs._write(context, fd, buffer, offset, length, position, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.writeFile = function writeFile(path, data, options, callback) {
|
IndexedDBFileSystem.prototype.writeFile = function writeFile(path, data, options, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._writeFile(context, path, data, options, callback);
|
fs._writeFile(context, path, data, options, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.lseek = function lseek(fd, offset, whence, callback) {
|
IndexedDBFileSystem.prototype.lseek = function lseek(fd, offset, whence, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._lseek(context, fd, offset, whence, callback);
|
fs._lseek(context, fd, offset, whence, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.readdir = function readdir(path, callback) {
|
IndexedDBFileSystem.prototype.readdir = function readdir(path, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._readdir(context, path, callback);
|
fs._readdir(context, path, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
IndexedDBFileSystem.prototype.rename = function rename(oldpath, newpath, callback) {
|
IndexedDBFileSystem.prototype.rename = function rename(oldpath, newpath, callback) {
|
||||||
var fs = this;
|
var fs = this;
|
||||||
this.promise.then(
|
var error = this._queueOrRun(
|
||||||
function() {
|
function() {
|
||||||
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = fs.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
var context = new IndexedDBContext(files);
|
var context = new IndexedDBContext(files);
|
||||||
fs._rename(context, oldpath, newpath, callback);
|
fs._rename(context, oldpath, newpath, callback);
|
||||||
},
|
|
||||||
function() {
|
|
||||||
callback(new EFileSystemError('unknown error'));
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: WebSQL stuff, this needs implementation
|
// FIXME: WebSQL stuff, this needs implementation
|
||||||
|
|
Loading…
Reference in New Issue