@ember-data/legacy-compat 4.12.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +11 -0
- package/README.md +26 -0
- package/addon/-private.js +1 -0
- package/addon/-private.js.map +1 -0
- package/addon/index.js +1797 -0
- package/addon/index.js.map +1 -0
- package/addon/snapshot-record-array-a4efeb60.js +169 -0
- package/addon/snapshot-record-array-a4efeb60.js.map +1 -0
- package/addon-main.js +90 -0
- package/package.json +69 -0
package/addon/index.js
ADDED
|
@@ -0,0 +1,1797 @@
|
|
|
1
|
+
import { macroCondition, isDevelopingApp, getOwnConfig } from '@embroider/macros';
|
|
2
|
+
import { deprecate, assert } from '@ember/debug';
|
|
3
|
+
import { S as SnapshotRecordArray } from "./snapshot-record-array-a4efeb60";
|
|
4
|
+
|
|
5
|
+
/*!
|
|
6
|
+
* @overview RSVP - a tiny implementation of Promises/A+.
|
|
7
|
+
* @copyright Copyright (c) 2016 Yehuda Katz, Tom Dale, Stefan Penner and contributors
|
|
8
|
+
* @license Licensed under MIT license
|
|
9
|
+
* See https://raw.githubusercontent.com/tildeio/rsvp.js/master/LICENSE
|
|
10
|
+
* @version 4.8.4+ff10049b
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
function callbacksFor(object) {
|
|
14
|
+
var callbacks = object._promiseCallbacks;
|
|
15
|
+
if (!callbacks) {
|
|
16
|
+
callbacks = object._promiseCallbacks = {};
|
|
17
|
+
}
|
|
18
|
+
return callbacks;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
@class EventTarget
|
|
23
|
+
@for rsvp
|
|
24
|
+
@public
|
|
25
|
+
*/
|
|
26
|
+
var EventTarget = {
|
|
27
|
+
/**
|
|
28
|
+
`EventTarget.mixin` extends an object with EventTarget methods. For
|
|
29
|
+
Example:
|
|
30
|
+
```javascript
|
|
31
|
+
import EventTarget from 'rsvp';
|
|
32
|
+
let object = {};
|
|
33
|
+
EventTarget.mixin(object);
|
|
34
|
+
object.on('finished', function(event) {
|
|
35
|
+
// handle event
|
|
36
|
+
});
|
|
37
|
+
object.trigger('finished', { detail: value });
|
|
38
|
+
```
|
|
39
|
+
`EventTarget.mixin` also works with prototypes:
|
|
40
|
+
```javascript
|
|
41
|
+
import EventTarget from 'rsvp';
|
|
42
|
+
let Person = function() {};
|
|
43
|
+
EventTarget.mixin(Person.prototype);
|
|
44
|
+
let yehuda = new Person();
|
|
45
|
+
let tom = new Person();
|
|
46
|
+
yehuda.on('poke', function(event) {
|
|
47
|
+
console.log('Yehuda says OW');
|
|
48
|
+
});
|
|
49
|
+
tom.on('poke', function(event) {
|
|
50
|
+
console.log('Tom says OW');
|
|
51
|
+
});
|
|
52
|
+
yehuda.trigger('poke');
|
|
53
|
+
tom.trigger('poke');
|
|
54
|
+
```
|
|
55
|
+
@method mixin
|
|
56
|
+
@for rsvp
|
|
57
|
+
@private
|
|
58
|
+
@param {Object} object object to extend with EventTarget methods
|
|
59
|
+
*/
|
|
60
|
+
mixin: function (object) {
|
|
61
|
+
object.on = this.on;
|
|
62
|
+
object.off = this.off;
|
|
63
|
+
object.trigger = this.trigger;
|
|
64
|
+
object._promiseCallbacks = undefined;
|
|
65
|
+
return object;
|
|
66
|
+
},
|
|
67
|
+
/**
|
|
68
|
+
Registers a callback to be executed when `eventName` is triggered
|
|
69
|
+
```javascript
|
|
70
|
+
object.on('event', function(eventInfo){
|
|
71
|
+
// handle the event
|
|
72
|
+
});
|
|
73
|
+
object.trigger('event');
|
|
74
|
+
```
|
|
75
|
+
@method on
|
|
76
|
+
@for EventTarget
|
|
77
|
+
@private
|
|
78
|
+
@param {String} eventName name of the event to listen for
|
|
79
|
+
@param {Function} callback function to be called when the event is triggered.
|
|
80
|
+
*/
|
|
81
|
+
on: function (eventName, callback) {
|
|
82
|
+
if (typeof callback !== 'function') {
|
|
83
|
+
throw new TypeError('Callback must be a function');
|
|
84
|
+
}
|
|
85
|
+
var allCallbacks = callbacksFor(this);
|
|
86
|
+
var callbacks = allCallbacks[eventName];
|
|
87
|
+
if (!callbacks) {
|
|
88
|
+
callbacks = allCallbacks[eventName] = [];
|
|
89
|
+
}
|
|
90
|
+
if (callbacks.indexOf(callback) === -1) {
|
|
91
|
+
callbacks.push(callback);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
/**
|
|
95
|
+
You can use `off` to stop firing a particular callback for an event:
|
|
96
|
+
```javascript
|
|
97
|
+
function doStuff() { // do stuff! }
|
|
98
|
+
object.on('stuff', doStuff);
|
|
99
|
+
object.trigger('stuff'); // doStuff will be called
|
|
100
|
+
// Unregister ONLY the doStuff callback
|
|
101
|
+
object.off('stuff', doStuff);
|
|
102
|
+
object.trigger('stuff'); // doStuff will NOT be called
|
|
103
|
+
```
|
|
104
|
+
If you don't pass a `callback` argument to `off`, ALL callbacks for the
|
|
105
|
+
event will not be executed when the event fires. For example:
|
|
106
|
+
```javascript
|
|
107
|
+
let callback1 = function(){};
|
|
108
|
+
let callback2 = function(){};
|
|
109
|
+
object.on('stuff', callback1);
|
|
110
|
+
object.on('stuff', callback2);
|
|
111
|
+
object.trigger('stuff'); // callback1 and callback2 will be executed.
|
|
112
|
+
object.off('stuff');
|
|
113
|
+
object.trigger('stuff'); // callback1 and callback2 will not be executed!
|
|
114
|
+
```
|
|
115
|
+
@method off
|
|
116
|
+
@for rsvp
|
|
117
|
+
@private
|
|
118
|
+
@param {String} eventName event to stop listening to
|
|
119
|
+
@param {Function} [callback] optional argument. If given, only the function
|
|
120
|
+
given will be removed from the event's callback queue. If no `callback`
|
|
121
|
+
argument is given, all callbacks will be removed from the event's callback
|
|
122
|
+
queue.
|
|
123
|
+
*/
|
|
124
|
+
off: function (eventName, callback) {
|
|
125
|
+
var allCallbacks = callbacksFor(this);
|
|
126
|
+
if (!callback) {
|
|
127
|
+
allCallbacks[eventName] = [];
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
var callbacks = allCallbacks[eventName];
|
|
131
|
+
var index = callbacks.indexOf(callback);
|
|
132
|
+
if (index !== -1) {
|
|
133
|
+
callbacks.splice(index, 1);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
/**
|
|
137
|
+
Use `trigger` to fire custom events. For example:
|
|
138
|
+
```javascript
|
|
139
|
+
object.on('foo', function(){
|
|
140
|
+
console.log('foo event happened!');
|
|
141
|
+
});
|
|
142
|
+
object.trigger('foo');
|
|
143
|
+
// 'foo event happened!' logged to the console
|
|
144
|
+
```
|
|
145
|
+
You can also pass a value as a second argument to `trigger` that will be
|
|
146
|
+
passed as an argument to all event listeners for the event:
|
|
147
|
+
```javascript
|
|
148
|
+
object.on('foo', function(value){
|
|
149
|
+
console.log(value.name);
|
|
150
|
+
});
|
|
151
|
+
object.trigger('foo', { name: 'bar' });
|
|
152
|
+
// 'bar' logged to the console
|
|
153
|
+
```
|
|
154
|
+
@method trigger
|
|
155
|
+
@for rsvp
|
|
156
|
+
@private
|
|
157
|
+
@param {String} eventName name of the event to be triggered
|
|
158
|
+
@param {*} [options] optional value to be passed to any event handlers for
|
|
159
|
+
the given `eventName`
|
|
160
|
+
*/
|
|
161
|
+
trigger: function (eventName, options, label) {
|
|
162
|
+
var allCallbacks = callbacksFor(this);
|
|
163
|
+
var callbacks = allCallbacks[eventName];
|
|
164
|
+
if (callbacks) {
|
|
165
|
+
// Don't cache the callbacks.length since it may grow
|
|
166
|
+
var callback = void 0;
|
|
167
|
+
for (var i = 0; i < callbacks.length; i++) {
|
|
168
|
+
callback = callbacks[i];
|
|
169
|
+
callback(options, label);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
var config = {
|
|
175
|
+
instrument: false
|
|
176
|
+
};
|
|
177
|
+
EventTarget['mixin'](config);
|
|
178
|
+
function configure(name, value) {
|
|
179
|
+
if (arguments.length === 2) {
|
|
180
|
+
config[name] = value;
|
|
181
|
+
} else {
|
|
182
|
+
return config[name];
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
var queue = [];
|
|
186
|
+
function scheduleFlush() {
|
|
187
|
+
setTimeout(function () {
|
|
188
|
+
for (var i = 0; i < queue.length; i++) {
|
|
189
|
+
var entry = queue[i];
|
|
190
|
+
var payload = entry.payload;
|
|
191
|
+
payload.guid = payload.key + payload.id;
|
|
192
|
+
payload.childGuid = payload.key + payload.childId;
|
|
193
|
+
if (payload.error) {
|
|
194
|
+
payload.stack = payload.error.stack;
|
|
195
|
+
}
|
|
196
|
+
config['trigger'](entry.name, entry.payload);
|
|
197
|
+
}
|
|
198
|
+
queue.length = 0;
|
|
199
|
+
}, 50);
|
|
200
|
+
}
|
|
201
|
+
function instrument(eventName, promise, child) {
|
|
202
|
+
if (1 === queue.push({
|
|
203
|
+
name: eventName,
|
|
204
|
+
payload: {
|
|
205
|
+
key: promise._guidKey,
|
|
206
|
+
id: promise._id,
|
|
207
|
+
eventName: eventName,
|
|
208
|
+
detail: promise._result,
|
|
209
|
+
childId: child && child._id,
|
|
210
|
+
label: promise._label,
|
|
211
|
+
timeStamp: Date.now(),
|
|
212
|
+
error: config["instrument-with-stack"] ? new Error(promise._label) : null
|
|
213
|
+
}
|
|
214
|
+
})) {
|
|
215
|
+
scheduleFlush();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
`Promise.resolve` returns a promise that will become resolved with the
|
|
221
|
+
passed `value`. It is shorthand for the following:
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
import Promise from 'rsvp';
|
|
225
|
+
|
|
226
|
+
let promise = new Promise(function(resolve, reject){
|
|
227
|
+
resolve(1);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
promise.then(function(value){
|
|
231
|
+
// value === 1
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Instead of writing the above, your code now simply becomes the following:
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
import Promise from 'rsvp';
|
|
239
|
+
|
|
240
|
+
let promise = RSVP.Promise.resolve(1);
|
|
241
|
+
|
|
242
|
+
promise.then(function(value){
|
|
243
|
+
// value === 1
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
@method resolve
|
|
248
|
+
@for Promise
|
|
249
|
+
@static
|
|
250
|
+
@param {*} object value that the returned promise will be resolved with
|
|
251
|
+
@param {String} [label] optional string for identifying the returned promise.
|
|
252
|
+
Useful for tooling.
|
|
253
|
+
@return {Promise} a promise that will become fulfilled with the given
|
|
254
|
+
`value`
|
|
255
|
+
*/
|
|
256
|
+
function resolve$$1(object, label) {
|
|
257
|
+
/*jshint validthis:true */
|
|
258
|
+
var Constructor = this;
|
|
259
|
+
if (object && typeof object === 'object' && object.constructor === Constructor) {
|
|
260
|
+
return object;
|
|
261
|
+
}
|
|
262
|
+
var promise = new Constructor(noop, label);
|
|
263
|
+
resolve$1(promise, object);
|
|
264
|
+
return promise;
|
|
265
|
+
}
|
|
266
|
+
function withOwnPromise() {
|
|
267
|
+
return new TypeError('A promises callback cannot return that same promise.');
|
|
268
|
+
}
|
|
269
|
+
function objectOrFunction(x) {
|
|
270
|
+
var type = typeof x;
|
|
271
|
+
return x !== null && (type === 'object' || type === 'function');
|
|
272
|
+
}
|
|
273
|
+
function noop() {}
|
|
274
|
+
var PENDING = void 0;
|
|
275
|
+
var FULFILLED = 1;
|
|
276
|
+
var REJECTED = 2;
|
|
277
|
+
var TRY_CATCH_ERROR = {
|
|
278
|
+
error: null
|
|
279
|
+
};
|
|
280
|
+
function getThen(promise) {
|
|
281
|
+
try {
|
|
282
|
+
return promise.then;
|
|
283
|
+
} catch (error) {
|
|
284
|
+
TRY_CATCH_ERROR.error = error;
|
|
285
|
+
return TRY_CATCH_ERROR;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
var tryCatchCallback = void 0;
|
|
289
|
+
function tryCatcher() {
|
|
290
|
+
try {
|
|
291
|
+
var target = tryCatchCallback;
|
|
292
|
+
tryCatchCallback = null;
|
|
293
|
+
return target.apply(this, arguments);
|
|
294
|
+
} catch (e) {
|
|
295
|
+
TRY_CATCH_ERROR.error = e;
|
|
296
|
+
return TRY_CATCH_ERROR;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function tryCatch(fn) {
|
|
300
|
+
tryCatchCallback = fn;
|
|
301
|
+
return tryCatcher;
|
|
302
|
+
}
|
|
303
|
+
function handleForeignThenable(promise, thenable, then$$1) {
|
|
304
|
+
config.async(function (promise) {
|
|
305
|
+
var sealed = false;
|
|
306
|
+
var result = tryCatch(then$$1).call(thenable, function (value) {
|
|
307
|
+
if (sealed) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
sealed = true;
|
|
311
|
+
if (thenable === value) {
|
|
312
|
+
fulfill(promise, value);
|
|
313
|
+
} else {
|
|
314
|
+
resolve$1(promise, value);
|
|
315
|
+
}
|
|
316
|
+
}, function (reason) {
|
|
317
|
+
if (sealed) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
sealed = true;
|
|
321
|
+
reject(promise, reason);
|
|
322
|
+
}, 'Settle: ' + (promise._label || ' unknown promise'));
|
|
323
|
+
if (!sealed && result === TRY_CATCH_ERROR) {
|
|
324
|
+
sealed = true;
|
|
325
|
+
var error = TRY_CATCH_ERROR.error;
|
|
326
|
+
TRY_CATCH_ERROR.error = null;
|
|
327
|
+
reject(promise, error);
|
|
328
|
+
}
|
|
329
|
+
}, promise);
|
|
330
|
+
}
|
|
331
|
+
function handleOwnThenable(promise, thenable) {
|
|
332
|
+
if (thenable._state === FULFILLED) {
|
|
333
|
+
fulfill(promise, thenable._result);
|
|
334
|
+
} else if (thenable._state === REJECTED) {
|
|
335
|
+
thenable._onError = null;
|
|
336
|
+
reject(promise, thenable._result);
|
|
337
|
+
} else {
|
|
338
|
+
subscribe(thenable, undefined, function (value) {
|
|
339
|
+
if (thenable === value) {
|
|
340
|
+
fulfill(promise, value);
|
|
341
|
+
} else {
|
|
342
|
+
resolve$1(promise, value);
|
|
343
|
+
}
|
|
344
|
+
}, function (reason) {
|
|
345
|
+
return reject(promise, reason);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
function handleMaybeThenable(promise, maybeThenable, then$$1) {
|
|
350
|
+
var isOwnThenable = maybeThenable.constructor === promise.constructor && then$$1 === then && promise.constructor.resolve === resolve$$1;
|
|
351
|
+
if (isOwnThenable) {
|
|
352
|
+
handleOwnThenable(promise, maybeThenable);
|
|
353
|
+
} else if (then$$1 === TRY_CATCH_ERROR) {
|
|
354
|
+
var error = TRY_CATCH_ERROR.error;
|
|
355
|
+
TRY_CATCH_ERROR.error = null;
|
|
356
|
+
reject(promise, error);
|
|
357
|
+
} else if (typeof then$$1 === 'function') {
|
|
358
|
+
handleForeignThenable(promise, maybeThenable, then$$1);
|
|
359
|
+
} else {
|
|
360
|
+
fulfill(promise, maybeThenable);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function resolve$1(promise, value) {
|
|
364
|
+
if (promise === value) {
|
|
365
|
+
fulfill(promise, value);
|
|
366
|
+
} else if (objectOrFunction(value)) {
|
|
367
|
+
handleMaybeThenable(promise, value, getThen(value));
|
|
368
|
+
} else {
|
|
369
|
+
fulfill(promise, value);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function publishRejection(promise) {
|
|
373
|
+
if (promise._onError) {
|
|
374
|
+
promise._onError(promise._result);
|
|
375
|
+
}
|
|
376
|
+
publish(promise);
|
|
377
|
+
}
|
|
378
|
+
function fulfill(promise, value) {
|
|
379
|
+
if (promise._state !== PENDING) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
promise._result = value;
|
|
383
|
+
promise._state = FULFILLED;
|
|
384
|
+
if (promise._subscribers.length === 0) {
|
|
385
|
+
if (config.instrument) {
|
|
386
|
+
instrument('fulfilled', promise);
|
|
387
|
+
}
|
|
388
|
+
} else {
|
|
389
|
+
config.async(publish, promise);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function reject(promise, reason) {
|
|
393
|
+
if (promise._state !== PENDING) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
promise._state = REJECTED;
|
|
397
|
+
promise._result = reason;
|
|
398
|
+
config.async(publishRejection, promise);
|
|
399
|
+
}
|
|
400
|
+
function subscribe(parent, child, onFulfillment, onRejection) {
|
|
401
|
+
var subscribers = parent._subscribers;
|
|
402
|
+
var length = subscribers.length;
|
|
403
|
+
parent._onError = null;
|
|
404
|
+
subscribers[length] = child;
|
|
405
|
+
subscribers[length + FULFILLED] = onFulfillment;
|
|
406
|
+
subscribers[length + REJECTED] = onRejection;
|
|
407
|
+
if (length === 0 && parent._state) {
|
|
408
|
+
config.async(publish, parent);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
function publish(promise) {
|
|
412
|
+
var subscribers = promise._subscribers;
|
|
413
|
+
var settled = promise._state;
|
|
414
|
+
if (config.instrument) {
|
|
415
|
+
instrument(settled === FULFILLED ? 'fulfilled' : 'rejected', promise);
|
|
416
|
+
}
|
|
417
|
+
if (subscribers.length === 0) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
var child = void 0,
|
|
421
|
+
callback = void 0,
|
|
422
|
+
result = promise._result;
|
|
423
|
+
for (var i = 0; i < subscribers.length; i += 3) {
|
|
424
|
+
child = subscribers[i];
|
|
425
|
+
callback = subscribers[i + settled];
|
|
426
|
+
if (child) {
|
|
427
|
+
invokeCallback(settled, child, callback, result);
|
|
428
|
+
} else {
|
|
429
|
+
callback(result);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
promise._subscribers.length = 0;
|
|
433
|
+
}
|
|
434
|
+
function invokeCallback(state, promise, callback, result) {
|
|
435
|
+
var hasCallback = typeof callback === 'function';
|
|
436
|
+
var value = void 0;
|
|
437
|
+
if (hasCallback) {
|
|
438
|
+
value = tryCatch(callback)(result);
|
|
439
|
+
} else {
|
|
440
|
+
value = result;
|
|
441
|
+
}
|
|
442
|
+
if (promise._state !== PENDING) ;else if (value === promise) {
|
|
443
|
+
reject(promise, withOwnPromise());
|
|
444
|
+
} else if (value === TRY_CATCH_ERROR) {
|
|
445
|
+
var error = TRY_CATCH_ERROR.error;
|
|
446
|
+
TRY_CATCH_ERROR.error = null; // release
|
|
447
|
+
reject(promise, error);
|
|
448
|
+
} else if (hasCallback) {
|
|
449
|
+
resolve$1(promise, value);
|
|
450
|
+
} else if (state === FULFILLED) {
|
|
451
|
+
fulfill(promise, value);
|
|
452
|
+
} else if (state === REJECTED) {
|
|
453
|
+
reject(promise, value);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function initializePromise(promise, resolver) {
|
|
457
|
+
var resolved = false;
|
|
458
|
+
try {
|
|
459
|
+
resolver(function (value) {
|
|
460
|
+
if (resolved) {
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
resolved = true;
|
|
464
|
+
resolve$1(promise, value);
|
|
465
|
+
}, function (reason) {
|
|
466
|
+
if (resolved) {
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
resolved = true;
|
|
470
|
+
reject(promise, reason);
|
|
471
|
+
});
|
|
472
|
+
} catch (e) {
|
|
473
|
+
reject(promise, e);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function then(onFulfillment, onRejection, label) {
|
|
477
|
+
var parent = this;
|
|
478
|
+
var state = parent._state;
|
|
479
|
+
if (state === FULFILLED && !onFulfillment || state === REJECTED && !onRejection) {
|
|
480
|
+
config.instrument && instrument('chained', parent, parent);
|
|
481
|
+
return parent;
|
|
482
|
+
}
|
|
483
|
+
parent._onError = null;
|
|
484
|
+
var child = new parent.constructor(noop, label);
|
|
485
|
+
var result = parent._result;
|
|
486
|
+
config.instrument && instrument('chained', parent, child);
|
|
487
|
+
if (state === PENDING) {
|
|
488
|
+
subscribe(parent, child, onFulfillment, onRejection);
|
|
489
|
+
} else {
|
|
490
|
+
var callback = state === FULFILLED ? onFulfillment : onRejection;
|
|
491
|
+
config.async(function () {
|
|
492
|
+
return invokeCallback(state, child, callback, result);
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
return child;
|
|
496
|
+
}
|
|
497
|
+
var Enumerator = function () {
|
|
498
|
+
function Enumerator(Constructor, input, abortOnReject, label) {
|
|
499
|
+
this._instanceConstructor = Constructor;
|
|
500
|
+
this.promise = new Constructor(noop, label);
|
|
501
|
+
this._abortOnReject = abortOnReject;
|
|
502
|
+
this._isUsingOwnPromise = Constructor === Promise$1;
|
|
503
|
+
this._isUsingOwnResolve = Constructor.resolve === resolve$$1;
|
|
504
|
+
this._init.apply(this, arguments);
|
|
505
|
+
}
|
|
506
|
+
Enumerator.prototype._init = function _init(Constructor, input) {
|
|
507
|
+
var len = input.length || 0;
|
|
508
|
+
this.length = len;
|
|
509
|
+
this._remaining = len;
|
|
510
|
+
this._result = new Array(len);
|
|
511
|
+
this._enumerate(input);
|
|
512
|
+
};
|
|
513
|
+
Enumerator.prototype._enumerate = function _enumerate(input) {
|
|
514
|
+
var length = this.length;
|
|
515
|
+
var promise = this.promise;
|
|
516
|
+
for (var i = 0; promise._state === PENDING && i < length; i++) {
|
|
517
|
+
this._eachEntry(input[i], i, true);
|
|
518
|
+
}
|
|
519
|
+
this._checkFullfillment();
|
|
520
|
+
};
|
|
521
|
+
Enumerator.prototype._checkFullfillment = function _checkFullfillment() {
|
|
522
|
+
if (this._remaining === 0) {
|
|
523
|
+
var result = this._result;
|
|
524
|
+
fulfill(this.promise, result);
|
|
525
|
+
this._result = null;
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
Enumerator.prototype._settleMaybeThenable = function _settleMaybeThenable(entry, i, firstPass) {
|
|
529
|
+
var c = this._instanceConstructor;
|
|
530
|
+
if (this._isUsingOwnResolve) {
|
|
531
|
+
var then$$1 = getThen(entry);
|
|
532
|
+
if (then$$1 === then && entry._state !== PENDING) {
|
|
533
|
+
entry._onError = null;
|
|
534
|
+
this._settledAt(entry._state, i, entry._result, firstPass);
|
|
535
|
+
} else if (typeof then$$1 !== 'function') {
|
|
536
|
+
this._settledAt(FULFILLED, i, entry, firstPass);
|
|
537
|
+
} else if (this._isUsingOwnPromise) {
|
|
538
|
+
var promise = new c(noop);
|
|
539
|
+
handleMaybeThenable(promise, entry, then$$1);
|
|
540
|
+
this._willSettleAt(promise, i, firstPass);
|
|
541
|
+
} else {
|
|
542
|
+
this._willSettleAt(new c(function (resolve) {
|
|
543
|
+
return resolve(entry);
|
|
544
|
+
}), i, firstPass);
|
|
545
|
+
}
|
|
546
|
+
} else {
|
|
547
|
+
this._willSettleAt(c.resolve(entry), i, firstPass);
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
Enumerator.prototype._eachEntry = function _eachEntry(entry, i, firstPass) {
|
|
551
|
+
if (entry !== null && typeof entry === 'object') {
|
|
552
|
+
this._settleMaybeThenable(entry, i, firstPass);
|
|
553
|
+
} else {
|
|
554
|
+
this._setResultAt(FULFILLED, i, entry, firstPass);
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
Enumerator.prototype._settledAt = function _settledAt(state, i, value, firstPass) {
|
|
558
|
+
var promise = this.promise;
|
|
559
|
+
if (promise._state === PENDING) {
|
|
560
|
+
if (this._abortOnReject && state === REJECTED) {
|
|
561
|
+
reject(promise, value);
|
|
562
|
+
} else {
|
|
563
|
+
this._setResultAt(state, i, value, firstPass);
|
|
564
|
+
this._checkFullfillment();
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
Enumerator.prototype._setResultAt = function _setResultAt(state, i, value, firstPass) {
|
|
569
|
+
this._remaining--;
|
|
570
|
+
this._result[i] = value;
|
|
571
|
+
};
|
|
572
|
+
Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i, firstPass) {
|
|
573
|
+
var _this = this;
|
|
574
|
+
subscribe(promise, undefined, function (value) {
|
|
575
|
+
return _this._settledAt(FULFILLED, i, value, firstPass);
|
|
576
|
+
}, function (reason) {
|
|
577
|
+
return _this._settledAt(REJECTED, i, reason, firstPass);
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
return Enumerator;
|
|
581
|
+
}();
|
|
582
|
+
function setSettledResult(state, i, value) {
|
|
583
|
+
this._remaining--;
|
|
584
|
+
if (state === FULFILLED) {
|
|
585
|
+
this._result[i] = {
|
|
586
|
+
state: 'fulfilled',
|
|
587
|
+
value: value
|
|
588
|
+
};
|
|
589
|
+
} else {
|
|
590
|
+
this._result[i] = {
|
|
591
|
+
state: 'rejected',
|
|
592
|
+
reason: value
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
`Promise.all` accepts an array of promises, and returns a new promise which
|
|
599
|
+
is fulfilled with an array of fulfillment values for the passed promises, or
|
|
600
|
+
rejected with the reason of the first passed promise to be rejected. It casts all
|
|
601
|
+
elements of the passed iterable to promises as it runs this algorithm.
|
|
602
|
+
|
|
603
|
+
Example:
|
|
604
|
+
|
|
605
|
+
```javascript
|
|
606
|
+
import Promise, { resolve } from 'rsvp';
|
|
607
|
+
|
|
608
|
+
let promise1 = resolve(1);
|
|
609
|
+
let promise2 = resolve(2);
|
|
610
|
+
let promise3 = resolve(3);
|
|
611
|
+
let promises = [ promise1, promise2, promise3 ];
|
|
612
|
+
|
|
613
|
+
Promise.all(promises).then(function(array){
|
|
614
|
+
// The array here would be [ 1, 2, 3 ];
|
|
615
|
+
});
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
If any of the `promises` given to `RSVP.all` are rejected, the first promise
|
|
619
|
+
that is rejected will be given as an argument to the returned promises's
|
|
620
|
+
rejection handler. For example:
|
|
621
|
+
|
|
622
|
+
Example:
|
|
623
|
+
|
|
624
|
+
```javascript
|
|
625
|
+
import Promise, { resolve, reject } from 'rsvp';
|
|
626
|
+
|
|
627
|
+
let promise1 = resolve(1);
|
|
628
|
+
let promise2 = reject(new Error("2"));
|
|
629
|
+
let promise3 = reject(new Error("3"));
|
|
630
|
+
let promises = [ promise1, promise2, promise3 ];
|
|
631
|
+
|
|
632
|
+
Promise.all(promises).then(function(array){
|
|
633
|
+
// Code here never runs because there are rejected promises!
|
|
634
|
+
}, function(error) {
|
|
635
|
+
// error.message === "2"
|
|
636
|
+
});
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
@method all
|
|
640
|
+
@for Promise
|
|
641
|
+
@param {Array} entries array of promises
|
|
642
|
+
@param {String} [label] optional string for labeling the promise.
|
|
643
|
+
Useful for tooling.
|
|
644
|
+
@return {Promise} promise that is fulfilled when all `promises` have been
|
|
645
|
+
fulfilled, or rejected if any of them become rejected.
|
|
646
|
+
@static
|
|
647
|
+
*/
|
|
648
|
+
function all(entries, label) {
|
|
649
|
+
if (!Array.isArray(entries)) {
|
|
650
|
+
return this.reject(new TypeError("Promise.all must be called with an array"), label);
|
|
651
|
+
}
|
|
652
|
+
return new Enumerator(this, entries, true /* abort on reject */, label).promise;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
`Promise.race` returns a new promise which is settled in the same way as the
|
|
657
|
+
first passed promise to settle.
|
|
658
|
+
|
|
659
|
+
Example:
|
|
660
|
+
|
|
661
|
+
```javascript
|
|
662
|
+
import Promise from 'rsvp';
|
|
663
|
+
|
|
664
|
+
let promise1 = new Promise(function(resolve, reject){
|
|
665
|
+
setTimeout(function(){
|
|
666
|
+
resolve('promise 1');
|
|
667
|
+
}, 200);
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
let promise2 = new Promise(function(resolve, reject){
|
|
671
|
+
setTimeout(function(){
|
|
672
|
+
resolve('promise 2');
|
|
673
|
+
}, 100);
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
Promise.race([promise1, promise2]).then(function(result){
|
|
677
|
+
// result === 'promise 2' because it was resolved before promise1
|
|
678
|
+
// was resolved.
|
|
679
|
+
});
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
`Promise.race` is deterministic in that only the state of the first
|
|
683
|
+
settled promise matters. For example, even if other promises given to the
|
|
684
|
+
`promises` array argument are resolved, but the first settled promise has
|
|
685
|
+
become rejected before the other promises became fulfilled, the returned
|
|
686
|
+
promise will become rejected:
|
|
687
|
+
|
|
688
|
+
```javascript
|
|
689
|
+
import Promise from 'rsvp';
|
|
690
|
+
|
|
691
|
+
let promise1 = new Promise(function(resolve, reject){
|
|
692
|
+
setTimeout(function(){
|
|
693
|
+
resolve('promise 1');
|
|
694
|
+
}, 200);
|
|
695
|
+
});
|
|
696
|
+
|
|
697
|
+
let promise2 = new Promise(function(resolve, reject){
|
|
698
|
+
setTimeout(function(){
|
|
699
|
+
reject(new Error('promise 2'));
|
|
700
|
+
}, 100);
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
Promise.race([promise1, promise2]).then(function(result){
|
|
704
|
+
// Code here never runs
|
|
705
|
+
}, function(reason){
|
|
706
|
+
// reason.message === 'promise 2' because promise 2 became rejected before
|
|
707
|
+
// promise 1 became fulfilled
|
|
708
|
+
});
|
|
709
|
+
```
|
|
710
|
+
|
|
711
|
+
An example real-world use case is implementing timeouts:
|
|
712
|
+
|
|
713
|
+
```javascript
|
|
714
|
+
import Promise from 'rsvp';
|
|
715
|
+
|
|
716
|
+
Promise.race([ajax('foo.json'), timeout(5000)])
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
@method race
|
|
720
|
+
@for Promise
|
|
721
|
+
@static
|
|
722
|
+
@param {Array} entries array of promises to observe
|
|
723
|
+
@param {String} [label] optional string for describing the promise returned.
|
|
724
|
+
Useful for tooling.
|
|
725
|
+
@return {Promise} a promise which settles in the same way as the first passed
|
|
726
|
+
promise to settle.
|
|
727
|
+
*/
|
|
728
|
+
function race(entries, label) {
|
|
729
|
+
/*jshint validthis:true */
|
|
730
|
+
var Constructor = this;
|
|
731
|
+
var promise = new Constructor(noop, label);
|
|
732
|
+
if (!Array.isArray(entries)) {
|
|
733
|
+
reject(promise, new TypeError('Promise.race must be called with an array'));
|
|
734
|
+
return promise;
|
|
735
|
+
}
|
|
736
|
+
for (var i = 0; promise._state === PENDING && i < entries.length; i++) {
|
|
737
|
+
subscribe(Constructor.resolve(entries[i]), undefined, function (value) {
|
|
738
|
+
return resolve$1(promise, value);
|
|
739
|
+
}, function (reason) {
|
|
740
|
+
return reject(promise, reason);
|
|
741
|
+
});
|
|
742
|
+
}
|
|
743
|
+
return promise;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
`Promise.reject` returns a promise rejected with the passed `reason`.
|
|
748
|
+
It is shorthand for the following:
|
|
749
|
+
|
|
750
|
+
```javascript
|
|
751
|
+
import Promise from 'rsvp';
|
|
752
|
+
|
|
753
|
+
let promise = new Promise(function(resolve, reject){
|
|
754
|
+
reject(new Error('WHOOPS'));
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
promise.then(function(value){
|
|
758
|
+
// Code here doesn't run because the promise is rejected!
|
|
759
|
+
}, function(reason){
|
|
760
|
+
// reason.message === 'WHOOPS'
|
|
761
|
+
});
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
Instead of writing the above, your code now simply becomes the following:
|
|
765
|
+
|
|
766
|
+
```javascript
|
|
767
|
+
import Promise from 'rsvp';
|
|
768
|
+
|
|
769
|
+
let promise = Promise.reject(new Error('WHOOPS'));
|
|
770
|
+
|
|
771
|
+
promise.then(function(value){
|
|
772
|
+
// Code here doesn't run because the promise is rejected!
|
|
773
|
+
}, function(reason){
|
|
774
|
+
// reason.message === 'WHOOPS'
|
|
775
|
+
});
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
@method reject
|
|
779
|
+
@for Promise
|
|
780
|
+
@static
|
|
781
|
+
@param {*} reason value that the returned promise will be rejected with.
|
|
782
|
+
@param {String} [label] optional string for identifying the returned promise.
|
|
783
|
+
Useful for tooling.
|
|
784
|
+
@return {Promise} a promise rejected with the given `reason`.
|
|
785
|
+
*/
|
|
786
|
+
function reject$1(reason, label) {
|
|
787
|
+
/*jshint validthis:true */
|
|
788
|
+
var Constructor = this;
|
|
789
|
+
var promise = new Constructor(noop, label);
|
|
790
|
+
reject(promise, reason);
|
|
791
|
+
return promise;
|
|
792
|
+
}
|
|
793
|
+
var guidKey = 'rsvp_' + Date.now() + '-';
|
|
794
|
+
var counter = 0;
|
|
795
|
+
function needsResolver() {
|
|
796
|
+
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
|
|
797
|
+
}
|
|
798
|
+
function needsNew() {
|
|
799
|
+
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
Promise objects represent the eventual result of an asynchronous operation. The
|
|
804
|
+
primary way of interacting with a promise is through its `then` method, which
|
|
805
|
+
registers callbacks to receive either a promise’s eventual value or the reason
|
|
806
|
+
why the promise cannot be fulfilled.
|
|
807
|
+
|
|
808
|
+
Terminology
|
|
809
|
+
-----------
|
|
810
|
+
|
|
811
|
+
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
|
|
812
|
+
- `thenable` is an object or function that defines a `then` method.
|
|
813
|
+
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
|
|
814
|
+
- `exception` is a value that is thrown using the throw statement.
|
|
815
|
+
- `reason` is a value that indicates why a promise was rejected.
|
|
816
|
+
- `settled` the final resting state of a promise, fulfilled or rejected.
|
|
817
|
+
|
|
818
|
+
A promise can be in one of three states: pending, fulfilled, or rejected.
|
|
819
|
+
|
|
820
|
+
Promises that are fulfilled have a fulfillment value and are in the fulfilled
|
|
821
|
+
state. Promises that are rejected have a rejection reason and are in the
|
|
822
|
+
rejected state. A fulfillment value is never a thenable.
|
|
823
|
+
|
|
824
|
+
Promises can also be said to *resolve* a value. If this value is also a
|
|
825
|
+
promise, then the original promise's settled state will match the value's
|
|
826
|
+
settled state. So a promise that *resolves* a promise that rejects will
|
|
827
|
+
itself reject, and a promise that *resolves* a promise that fulfills will
|
|
828
|
+
itself fulfill.
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
Basic Usage:
|
|
832
|
+
------------
|
|
833
|
+
|
|
834
|
+
```js
|
|
835
|
+
let promise = new Promise(function(resolve, reject) {
|
|
836
|
+
// on success
|
|
837
|
+
resolve(value);
|
|
838
|
+
|
|
839
|
+
// on failure
|
|
840
|
+
reject(reason);
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
promise.then(function(value) {
|
|
844
|
+
// on fulfillment
|
|
845
|
+
}, function(reason) {
|
|
846
|
+
// on rejection
|
|
847
|
+
});
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
Advanced Usage:
|
|
851
|
+
---------------
|
|
852
|
+
|
|
853
|
+
Promises shine when abstracting away asynchronous interactions such as
|
|
854
|
+
`XMLHttpRequest`s.
|
|
855
|
+
|
|
856
|
+
```js
|
|
857
|
+
function getJSON(url) {
|
|
858
|
+
return new Promise(function(resolve, reject){
|
|
859
|
+
let xhr = new XMLHttpRequest();
|
|
860
|
+
|
|
861
|
+
xhr.open('GET', url);
|
|
862
|
+
xhr.onreadystatechange = handler;
|
|
863
|
+
xhr.responseType = 'json';
|
|
864
|
+
xhr.setRequestHeader('Accept', 'application/json');
|
|
865
|
+
xhr.send();
|
|
866
|
+
|
|
867
|
+
function handler() {
|
|
868
|
+
if (this.readyState === this.DONE) {
|
|
869
|
+
if (this.status === 200) {
|
|
870
|
+
resolve(this.response);
|
|
871
|
+
} else {
|
|
872
|
+
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
getJSON('/posts.json').then(function(json) {
|
|
880
|
+
// on fulfillment
|
|
881
|
+
}, function(reason) {
|
|
882
|
+
// on rejection
|
|
883
|
+
});
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
Unlike callbacks, promises are great composable primitives.
|
|
887
|
+
|
|
888
|
+
```js
|
|
889
|
+
Promise.all([
|
|
890
|
+
getJSON('/posts'),
|
|
891
|
+
getJSON('/comments')
|
|
892
|
+
]).then(function(values){
|
|
893
|
+
values[0] // => postsJSON
|
|
894
|
+
values[1] // => commentsJSON
|
|
895
|
+
|
|
896
|
+
return values;
|
|
897
|
+
});
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
@class Promise
|
|
901
|
+
@public
|
|
902
|
+
@param {function} resolver
|
|
903
|
+
@param {String} [label] optional string for labeling the promise.
|
|
904
|
+
Useful for tooling.
|
|
905
|
+
@constructor
|
|
906
|
+
*/
|
|
907
|
+
|
|
908
|
+
var Promise$1 = function () {
|
|
909
|
+
function Promise(resolver, label) {
|
|
910
|
+
this._id = counter++;
|
|
911
|
+
this._label = label;
|
|
912
|
+
this._state = undefined;
|
|
913
|
+
this._result = undefined;
|
|
914
|
+
this._subscribers = [];
|
|
915
|
+
config.instrument && instrument('created', this);
|
|
916
|
+
if (noop !== resolver) {
|
|
917
|
+
typeof resolver !== 'function' && needsResolver();
|
|
918
|
+
this instanceof Promise ? initializePromise(this, resolver) : needsNew();
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
Promise.prototype._onError = function _onError(reason) {
|
|
922
|
+
var _this = this;
|
|
923
|
+
config.after(function () {
|
|
924
|
+
if (_this._onError) {
|
|
925
|
+
config.trigger('error', reason, _this._label);
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
|
|
932
|
+
as the catch block of a try/catch statement.
|
|
933
|
+
|
|
934
|
+
```js
|
|
935
|
+
function findAuthor(){
|
|
936
|
+
throw new Error('couldn\'t find that author');
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// synchronous
|
|
940
|
+
try {
|
|
941
|
+
findAuthor();
|
|
942
|
+
} catch(reason) {
|
|
943
|
+
// something went wrong
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// async with promises
|
|
947
|
+
findAuthor().catch(function(reason){
|
|
948
|
+
// something went wrong
|
|
949
|
+
});
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
@method catch
|
|
953
|
+
@param {Function} onRejection
|
|
954
|
+
@param {String} [label] optional string for labeling the promise.
|
|
955
|
+
Useful for tooling.
|
|
956
|
+
@return {Promise}
|
|
957
|
+
*/
|
|
958
|
+
|
|
959
|
+
Promise.prototype.catch = function _catch(onRejection, label) {
|
|
960
|
+
return this.then(undefined, onRejection, label);
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
`finally` will be invoked regardless of the promise's fate just as native
|
|
965
|
+
try/catch/finally behaves
|
|
966
|
+
|
|
967
|
+
Synchronous example:
|
|
968
|
+
|
|
969
|
+
```js
|
|
970
|
+
findAuthor() {
|
|
971
|
+
if (Math.random() > 0.5) {
|
|
972
|
+
throw new Error();
|
|
973
|
+
}
|
|
974
|
+
return new Author();
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
try {
|
|
978
|
+
return findAuthor(); // succeed or fail
|
|
979
|
+
} catch(error) {
|
|
980
|
+
return findOtherAuthor();
|
|
981
|
+
} finally {
|
|
982
|
+
// always runs
|
|
983
|
+
// doesn't affect the return value
|
|
984
|
+
}
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
Asynchronous example:
|
|
988
|
+
|
|
989
|
+
```js
|
|
990
|
+
findAuthor().catch(function(reason){
|
|
991
|
+
return findOtherAuthor();
|
|
992
|
+
}).finally(function(){
|
|
993
|
+
// author was either found, or not
|
|
994
|
+
});
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
@method finally
|
|
998
|
+
@param {Function} callback
|
|
999
|
+
@param {String} [label] optional string for labeling the promise.
|
|
1000
|
+
Useful for tooling.
|
|
1001
|
+
@return {Promise}
|
|
1002
|
+
*/
|
|
1003
|
+
|
|
1004
|
+
Promise.prototype.finally = function _finally(callback, label) {
|
|
1005
|
+
var promise = this;
|
|
1006
|
+
var constructor = promise.constructor;
|
|
1007
|
+
if (typeof callback === 'function') {
|
|
1008
|
+
return promise.then(function (value) {
|
|
1009
|
+
return constructor.resolve(callback()).then(function () {
|
|
1010
|
+
return value;
|
|
1011
|
+
});
|
|
1012
|
+
}, function (reason) {
|
|
1013
|
+
return constructor.resolve(callback()).then(function () {
|
|
1014
|
+
throw reason;
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
}
|
|
1018
|
+
return promise.then(callback, callback);
|
|
1019
|
+
};
|
|
1020
|
+
return Promise;
|
|
1021
|
+
}();
|
|
1022
|
+
Promise$1.cast = resolve$$1; // deprecated
|
|
1023
|
+
Promise$1.all = all;
|
|
1024
|
+
Promise$1.race = race;
|
|
1025
|
+
Promise$1.resolve = resolve$$1;
|
|
1026
|
+
Promise$1.reject = reject$1;
|
|
1027
|
+
Promise$1.prototype._guidKey = guidKey;
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
The primary way of interacting with a promise is through its `then` method,
|
|
1031
|
+
which registers callbacks to receive either a promise's eventual value or the
|
|
1032
|
+
reason why the promise cannot be fulfilled.
|
|
1033
|
+
|
|
1034
|
+
```js
|
|
1035
|
+
findUser().then(function(user){
|
|
1036
|
+
// user is available
|
|
1037
|
+
}, function(reason){
|
|
1038
|
+
// user is unavailable, and you are given the reason why
|
|
1039
|
+
});
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
Chaining
|
|
1043
|
+
--------
|
|
1044
|
+
|
|
1045
|
+
The return value of `then` is itself a promise. This second, 'downstream'
|
|
1046
|
+
promise is resolved with the return value of the first promise's fulfillment
|
|
1047
|
+
or rejection handler, or rejected if the handler throws an exception.
|
|
1048
|
+
|
|
1049
|
+
```js
|
|
1050
|
+
findUser().then(function (user) {
|
|
1051
|
+
return user.name;
|
|
1052
|
+
}, function (reason) {
|
|
1053
|
+
return 'default name';
|
|
1054
|
+
}).then(function (userName) {
|
|
1055
|
+
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
|
|
1056
|
+
// will be `'default name'`
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
findUser().then(function (user) {
|
|
1060
|
+
throw new Error('Found user, but still unhappy');
|
|
1061
|
+
}, function (reason) {
|
|
1062
|
+
throw new Error('`findUser` rejected and we\'re unhappy');
|
|
1063
|
+
}).then(function (value) {
|
|
1064
|
+
// never reached
|
|
1065
|
+
}, function (reason) {
|
|
1066
|
+
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
|
|
1067
|
+
// If `findUser` rejected, `reason` will be '`findUser` rejected and we\'re unhappy'.
|
|
1068
|
+
});
|
|
1069
|
+
```
|
|
1070
|
+
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
|
|
1071
|
+
|
|
1072
|
+
```js
|
|
1073
|
+
findUser().then(function (user) {
|
|
1074
|
+
throw new PedagogicalException('Upstream error');
|
|
1075
|
+
}).then(function (value) {
|
|
1076
|
+
// never reached
|
|
1077
|
+
}).then(function (value) {
|
|
1078
|
+
// never reached
|
|
1079
|
+
}, function (reason) {
|
|
1080
|
+
// The `PedgagocialException` is propagated all the way down to here
|
|
1081
|
+
});
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
Assimilation
|
|
1085
|
+
------------
|
|
1086
|
+
|
|
1087
|
+
Sometimes the value you want to propagate to a downstream promise can only be
|
|
1088
|
+
retrieved asynchronously. This can be achieved by returning a promise in the
|
|
1089
|
+
fulfillment or rejection handler. The downstream promise will then be pending
|
|
1090
|
+
until the returned promise is settled. This is called *assimilation*.
|
|
1091
|
+
|
|
1092
|
+
```js
|
|
1093
|
+
findUser().then(function (user) {
|
|
1094
|
+
return findCommentsByAuthor(user);
|
|
1095
|
+
}).then(function (comments) {
|
|
1096
|
+
// The user's comments are now available
|
|
1097
|
+
});
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
If the assimliated promise rejects, then the downstream promise will also reject.
|
|
1101
|
+
|
|
1102
|
+
```js
|
|
1103
|
+
findUser().then(function (user) {
|
|
1104
|
+
return findCommentsByAuthor(user);
|
|
1105
|
+
}).then(function (comments) {
|
|
1106
|
+
// If `findCommentsByAuthor` fulfills, we'll have the value here
|
|
1107
|
+
}, function (reason) {
|
|
1108
|
+
// If `findCommentsByAuthor` rejects, we'll have the reason here
|
|
1109
|
+
});
|
|
1110
|
+
```
|
|
1111
|
+
|
|
1112
|
+
Simple Example
|
|
1113
|
+
--------------
|
|
1114
|
+
|
|
1115
|
+
Synchronous Example
|
|
1116
|
+
|
|
1117
|
+
```javascript
|
|
1118
|
+
let result;
|
|
1119
|
+
|
|
1120
|
+
try {
|
|
1121
|
+
result = findResult();
|
|
1122
|
+
// success
|
|
1123
|
+
} catch(reason) {
|
|
1124
|
+
// failure
|
|
1125
|
+
}
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
Errback Example
|
|
1129
|
+
|
|
1130
|
+
```js
|
|
1131
|
+
findResult(function(result, err){
|
|
1132
|
+
if (err) {
|
|
1133
|
+
// failure
|
|
1134
|
+
} else {
|
|
1135
|
+
// success
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
Promise Example;
|
|
1141
|
+
|
|
1142
|
+
```javascript
|
|
1143
|
+
findResult().then(function(result){
|
|
1144
|
+
// success
|
|
1145
|
+
}, function(reason){
|
|
1146
|
+
// failure
|
|
1147
|
+
});
|
|
1148
|
+
```
|
|
1149
|
+
|
|
1150
|
+
Advanced Example
|
|
1151
|
+
--------------
|
|
1152
|
+
|
|
1153
|
+
Synchronous Example
|
|
1154
|
+
|
|
1155
|
+
```javascript
|
|
1156
|
+
let author, books;
|
|
1157
|
+
|
|
1158
|
+
try {
|
|
1159
|
+
author = findAuthor();
|
|
1160
|
+
books = findBooksByAuthor(author);
|
|
1161
|
+
// success
|
|
1162
|
+
} catch(reason) {
|
|
1163
|
+
// failure
|
|
1164
|
+
}
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
Errback Example
|
|
1168
|
+
|
|
1169
|
+
```js
|
|
1170
|
+
|
|
1171
|
+
function foundBooks(books) {
|
|
1172
|
+
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
function failure(reason) {
|
|
1176
|
+
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
findAuthor(function(author, err){
|
|
1180
|
+
if (err) {
|
|
1181
|
+
failure(err);
|
|
1182
|
+
// failure
|
|
1183
|
+
} else {
|
|
1184
|
+
try {
|
|
1185
|
+
findBoooksByAuthor(author, function(books, err) {
|
|
1186
|
+
if (err) {
|
|
1187
|
+
failure(err);
|
|
1188
|
+
} else {
|
|
1189
|
+
try {
|
|
1190
|
+
foundBooks(books);
|
|
1191
|
+
} catch(reason) {
|
|
1192
|
+
failure(reason);
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
});
|
|
1196
|
+
} catch(error) {
|
|
1197
|
+
failure(err);
|
|
1198
|
+
}
|
|
1199
|
+
// success
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
Promise Example;
|
|
1205
|
+
|
|
1206
|
+
```javascript
|
|
1207
|
+
findAuthor().
|
|
1208
|
+
then(findBooksByAuthor).
|
|
1209
|
+
then(function(books){
|
|
1210
|
+
// found books
|
|
1211
|
+
}).catch(function(reason){
|
|
1212
|
+
// something went wrong
|
|
1213
|
+
});
|
|
1214
|
+
```
|
|
1215
|
+
|
|
1216
|
+
@method then
|
|
1217
|
+
@param {Function} onFulfillment
|
|
1218
|
+
@param {Function} onRejection
|
|
1219
|
+
@param {String} [label] optional string for labeling the promise.
|
|
1220
|
+
Useful for tooling.
|
|
1221
|
+
@return {Promise}
|
|
1222
|
+
*/
|
|
1223
|
+
Promise$1.prototype.then = then;
|
|
1224
|
+
function _possibleConstructorReturn(self, call) {
|
|
1225
|
+
if (!self) {
|
|
1226
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
1227
|
+
}
|
|
1228
|
+
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|
1229
|
+
}
|
|
1230
|
+
function _inherits(subClass, superClass) {
|
|
1231
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
1232
|
+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|
1233
|
+
}
|
|
1234
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
1235
|
+
constructor: {
|
|
1236
|
+
value: subClass,
|
|
1237
|
+
enumerable: false,
|
|
1238
|
+
writable: true,
|
|
1239
|
+
configurable: true
|
|
1240
|
+
}
|
|
1241
|
+
});
|
|
1242
|
+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
@module rsvp
|
|
1247
|
+
@public
|
|
1248
|
+
**/
|
|
1249
|
+
|
|
1250
|
+
var AllSettled = function (_Enumerator) {
|
|
1251
|
+
_inherits(AllSettled, _Enumerator);
|
|
1252
|
+
function AllSettled(Constructor, entries, label) {
|
|
1253
|
+
return _possibleConstructorReturn(this, _Enumerator.call(this, Constructor, entries, false /* don't abort on reject */, label));
|
|
1254
|
+
}
|
|
1255
|
+
return AllSettled;
|
|
1256
|
+
}(Enumerator);
|
|
1257
|
+
AllSettled.prototype._setResultAt = setSettledResult;
|
|
1258
|
+
function _possibleConstructorReturn$1(self, call) {
|
|
1259
|
+
if (!self) {
|
|
1260
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
1261
|
+
}
|
|
1262
|
+
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|
1263
|
+
}
|
|
1264
|
+
function _inherits$1(subClass, superClass) {
|
|
1265
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
1266
|
+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|
1267
|
+
}
|
|
1268
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
1269
|
+
constructor: {
|
|
1270
|
+
value: subClass,
|
|
1271
|
+
enumerable: false,
|
|
1272
|
+
writable: true,
|
|
1273
|
+
configurable: true
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
1276
|
+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|
1277
|
+
}
|
|
1278
|
+
var PromiseHash = function (_Enumerator) {
|
|
1279
|
+
_inherits$1(PromiseHash, _Enumerator);
|
|
1280
|
+
function PromiseHash(Constructor, object) {
|
|
1281
|
+
var abortOnReject = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
1282
|
+
var label = arguments[3];
|
|
1283
|
+
return _possibleConstructorReturn$1(this, _Enumerator.call(this, Constructor, object, abortOnReject, label));
|
|
1284
|
+
}
|
|
1285
|
+
PromiseHash.prototype._init = function _init(Constructor, object) {
|
|
1286
|
+
this._result = {};
|
|
1287
|
+
this._enumerate(object);
|
|
1288
|
+
};
|
|
1289
|
+
PromiseHash.prototype._enumerate = function _enumerate(input) {
|
|
1290
|
+
var keys = Object.keys(input);
|
|
1291
|
+
var length = keys.length;
|
|
1292
|
+
var promise = this.promise;
|
|
1293
|
+
this._remaining = length;
|
|
1294
|
+
var key = void 0,
|
|
1295
|
+
val = void 0;
|
|
1296
|
+
for (var i = 0; promise._state === PENDING && i < length; i++) {
|
|
1297
|
+
key = keys[i];
|
|
1298
|
+
val = input[key];
|
|
1299
|
+
this._eachEntry(val, key, true);
|
|
1300
|
+
}
|
|
1301
|
+
this._checkFullfillment();
|
|
1302
|
+
};
|
|
1303
|
+
return PromiseHash;
|
|
1304
|
+
}(Enumerator);
|
|
1305
|
+
function _possibleConstructorReturn$2(self, call) {
|
|
1306
|
+
if (!self) {
|
|
1307
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
1308
|
+
}
|
|
1309
|
+
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|
1310
|
+
}
|
|
1311
|
+
function _inherits$2(subClass, superClass) {
|
|
1312
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
1313
|
+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|
1314
|
+
}
|
|
1315
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
1316
|
+
constructor: {
|
|
1317
|
+
value: subClass,
|
|
1318
|
+
enumerable: false,
|
|
1319
|
+
writable: true,
|
|
1320
|
+
configurable: true
|
|
1321
|
+
}
|
|
1322
|
+
});
|
|
1323
|
+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|
1324
|
+
}
|
|
1325
|
+
var HashSettled = function (_PromiseHash) {
|
|
1326
|
+
_inherits$2(HashSettled, _PromiseHash);
|
|
1327
|
+
function HashSettled(Constructor, object, label) {
|
|
1328
|
+
return _possibleConstructorReturn$2(this, _PromiseHash.call(this, Constructor, object, false, label));
|
|
1329
|
+
}
|
|
1330
|
+
return HashSettled;
|
|
1331
|
+
}(PromiseHash);
|
|
1332
|
+
HashSettled.prototype._setResultAt = setSettledResult;
|
|
1333
|
+
function _possibleConstructorReturn$3(self, call) {
|
|
1334
|
+
if (!self) {
|
|
1335
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
1336
|
+
}
|
|
1337
|
+
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|
1338
|
+
}
|
|
1339
|
+
function _inherits$3(subClass, superClass) {
|
|
1340
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
1341
|
+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|
1342
|
+
}
|
|
1343
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
1344
|
+
constructor: {
|
|
1345
|
+
value: subClass,
|
|
1346
|
+
enumerable: false,
|
|
1347
|
+
writable: true,
|
|
1348
|
+
configurable: true
|
|
1349
|
+
}
|
|
1350
|
+
});
|
|
1351
|
+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|
1352
|
+
}
|
|
1353
|
+
var MapEnumerator = function (_Enumerator) {
|
|
1354
|
+
_inherits$3(MapEnumerator, _Enumerator);
|
|
1355
|
+
function MapEnumerator(Constructor, entries, mapFn, label) {
|
|
1356
|
+
return _possibleConstructorReturn$3(this, _Enumerator.call(this, Constructor, entries, true, label, mapFn));
|
|
1357
|
+
}
|
|
1358
|
+
MapEnumerator.prototype._init = function _init(Constructor, input, bool, label, mapFn) {
|
|
1359
|
+
var len = input.length || 0;
|
|
1360
|
+
this.length = len;
|
|
1361
|
+
this._remaining = len;
|
|
1362
|
+
this._result = new Array(len);
|
|
1363
|
+
this._mapFn = mapFn;
|
|
1364
|
+
this._enumerate(input);
|
|
1365
|
+
};
|
|
1366
|
+
MapEnumerator.prototype._setResultAt = function _setResultAt(state, i, value, firstPass) {
|
|
1367
|
+
if (firstPass) {
|
|
1368
|
+
var val = tryCatch(this._mapFn)(value, i);
|
|
1369
|
+
if (val === TRY_CATCH_ERROR) {
|
|
1370
|
+
this._settledAt(REJECTED, i, val.error, false);
|
|
1371
|
+
} else {
|
|
1372
|
+
this._eachEntry(val, i, false);
|
|
1373
|
+
}
|
|
1374
|
+
} else {
|
|
1375
|
+
this._remaining--;
|
|
1376
|
+
this._result[i] = value;
|
|
1377
|
+
}
|
|
1378
|
+
};
|
|
1379
|
+
return MapEnumerator;
|
|
1380
|
+
}(Enumerator);
|
|
1381
|
+
|
|
1382
|
+
/**
|
|
1383
|
+
This is a convenient alias for `Promise.resolve`.
|
|
1384
|
+
|
|
1385
|
+
@method resolve
|
|
1386
|
+
@public
|
|
1387
|
+
@static
|
|
1388
|
+
@for rsvp
|
|
1389
|
+
@param {*} value value that the returned promise will be resolved with
|
|
1390
|
+
@param {String} [label] optional string for identifying the returned promise.
|
|
1391
|
+
Useful for tooling.
|
|
1392
|
+
@return {Promise} a promise that will become fulfilled with the given
|
|
1393
|
+
`value`
|
|
1394
|
+
*/
|
|
1395
|
+
function resolve$2(value, label) {
|
|
1396
|
+
return Promise$1.resolve(value, label);
|
|
1397
|
+
}
|
|
1398
|
+
function _possibleConstructorReturn$4(self, call) {
|
|
1399
|
+
if (!self) {
|
|
1400
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
1401
|
+
}
|
|
1402
|
+
return call && (typeof call === "object" || typeof call === "function") ? call : self;
|
|
1403
|
+
}
|
|
1404
|
+
function _inherits$4(subClass, superClass) {
|
|
1405
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
1406
|
+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
|
|
1407
|
+
}
|
|
1408
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
1409
|
+
constructor: {
|
|
1410
|
+
value: subClass,
|
|
1411
|
+
enumerable: false,
|
|
1412
|
+
writable: true,
|
|
1413
|
+
configurable: true
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
|
|
1417
|
+
}
|
|
1418
|
+
var EMPTY_OBJECT = {};
|
|
1419
|
+
(function (_MapEnumerator) {
|
|
1420
|
+
_inherits$4(FilterEnumerator, _MapEnumerator);
|
|
1421
|
+
function FilterEnumerator() {
|
|
1422
|
+
return _possibleConstructorReturn$4(this, _MapEnumerator.apply(this, arguments));
|
|
1423
|
+
}
|
|
1424
|
+
FilterEnumerator.prototype._checkFullfillment = function _checkFullfillment() {
|
|
1425
|
+
if (this._remaining === 0 && this._result !== null) {
|
|
1426
|
+
var result = this._result.filter(function (val) {
|
|
1427
|
+
return val !== EMPTY_OBJECT;
|
|
1428
|
+
});
|
|
1429
|
+
fulfill(this.promise, result);
|
|
1430
|
+
this._result = null;
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
1433
|
+
FilterEnumerator.prototype._setResultAt = function _setResultAt(state, i, value, firstPass) {
|
|
1434
|
+
if (firstPass) {
|
|
1435
|
+
this._result[i] = value;
|
|
1436
|
+
var val = tryCatch(this._mapFn)(value, i);
|
|
1437
|
+
if (val === TRY_CATCH_ERROR) {
|
|
1438
|
+
this._settledAt(REJECTED, i, val.error, false);
|
|
1439
|
+
} else {
|
|
1440
|
+
this._eachEntry(val, i, false);
|
|
1441
|
+
}
|
|
1442
|
+
} else {
|
|
1443
|
+
this._remaining--;
|
|
1444
|
+
if (!value) {
|
|
1445
|
+
this._result[i] = EMPTY_OBJECT;
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
};
|
|
1449
|
+
return FilterEnumerator;
|
|
1450
|
+
})(MapEnumerator);
|
|
1451
|
+
var len = 0;
|
|
1452
|
+
var vertxNext = void 0;
|
|
1453
|
+
function asap(callback, arg) {
|
|
1454
|
+
queue$1[len] = callback;
|
|
1455
|
+
queue$1[len + 1] = arg;
|
|
1456
|
+
len += 2;
|
|
1457
|
+
if (len === 2) {
|
|
1458
|
+
// If len is 1, that means that we need to schedule an async flush.
|
|
1459
|
+
// If additional callbacks are queued before the queue is flushed, they
|
|
1460
|
+
// will be processed by this flush that we are scheduling.
|
|
1461
|
+
scheduleFlush$1();
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
var browserWindow = typeof window !== 'undefined' ? window : undefined;
|
|
1465
|
+
var browserGlobal = browserWindow || {};
|
|
1466
|
+
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
|
|
1467
|
+
var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
|
|
1468
|
+
|
|
1469
|
+
// test for web worker but not in IE10
|
|
1470
|
+
var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
|
|
1471
|
+
|
|
1472
|
+
// node
|
|
1473
|
+
function useNextTick() {
|
|
1474
|
+
var nextTick = process.nextTick;
|
|
1475
|
+
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
|
|
1476
|
+
// setImmediate should be used instead instead
|
|
1477
|
+
var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
|
|
1478
|
+
if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
|
|
1479
|
+
nextTick = setImmediate;
|
|
1480
|
+
}
|
|
1481
|
+
return function () {
|
|
1482
|
+
return nextTick(flush);
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
// vertx
|
|
1487
|
+
function useVertxTimer() {
|
|
1488
|
+
if (typeof vertxNext !== 'undefined') {
|
|
1489
|
+
return function () {
|
|
1490
|
+
vertxNext(flush);
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
return useSetTimeout();
|
|
1494
|
+
}
|
|
1495
|
+
function useMutationObserver() {
|
|
1496
|
+
var iterations = 0;
|
|
1497
|
+
var observer = new BrowserMutationObserver(flush);
|
|
1498
|
+
var node = document.createTextNode('');
|
|
1499
|
+
observer.observe(node, {
|
|
1500
|
+
characterData: true
|
|
1501
|
+
});
|
|
1502
|
+
return function () {
|
|
1503
|
+
return node.data = iterations = ++iterations % 2;
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
// web worker
|
|
1508
|
+
function useMessageChannel() {
|
|
1509
|
+
var channel = new MessageChannel();
|
|
1510
|
+
channel.port1.onmessage = flush;
|
|
1511
|
+
return function () {
|
|
1512
|
+
return channel.port2.postMessage(0);
|
|
1513
|
+
};
|
|
1514
|
+
}
|
|
1515
|
+
function useSetTimeout() {
|
|
1516
|
+
return function () {
|
|
1517
|
+
return setTimeout(flush, 1);
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
var queue$1 = new Array(1000);
|
|
1521
|
+
function flush() {
|
|
1522
|
+
for (var i = 0; i < len; i += 2) {
|
|
1523
|
+
var callback = queue$1[i];
|
|
1524
|
+
var arg = queue$1[i + 1];
|
|
1525
|
+
callback(arg);
|
|
1526
|
+
queue$1[i] = undefined;
|
|
1527
|
+
queue$1[i + 1] = undefined;
|
|
1528
|
+
}
|
|
1529
|
+
len = 0;
|
|
1530
|
+
}
|
|
1531
|
+
function attemptVertex() {
|
|
1532
|
+
try {
|
|
1533
|
+
var vertx = Function('return this')().require('vertx');
|
|
1534
|
+
vertxNext = vertx.runOnLoop || vertx.runOnContext;
|
|
1535
|
+
return useVertxTimer();
|
|
1536
|
+
} catch (e) {
|
|
1537
|
+
return useSetTimeout();
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
var scheduleFlush$1 = void 0;
|
|
1541
|
+
// Decide what async method to use to triggering processing of queued callbacks:
|
|
1542
|
+
if (isNode) {
|
|
1543
|
+
scheduleFlush$1 = useNextTick();
|
|
1544
|
+
} else if (BrowserMutationObserver) {
|
|
1545
|
+
scheduleFlush$1 = useMutationObserver();
|
|
1546
|
+
} else if (isWorker) {
|
|
1547
|
+
scheduleFlush$1 = useMessageChannel();
|
|
1548
|
+
} else if (browserWindow === undefined && typeof require === 'function') {
|
|
1549
|
+
scheduleFlush$1 = attemptVertex();
|
|
1550
|
+
} else {
|
|
1551
|
+
scheduleFlush$1 = useSetTimeout();
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
// defaults
|
|
1555
|
+
config.async = asap;
|
|
1556
|
+
config.after = function (cb) {
|
|
1557
|
+
return setTimeout(cb, 0);
|
|
1558
|
+
};
|
|
1559
|
+
function on() {
|
|
1560
|
+
config.on.apply(config, arguments);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
// Set up instrumentation through `window.__PROMISE_INTRUMENTATION__`
|
|
1564
|
+
if (typeof window !== 'undefined' && typeof window['__PROMISE_INSTRUMENTATION__'] === 'object') {
|
|
1565
|
+
var callbacks = window['__PROMISE_INSTRUMENTATION__'];
|
|
1566
|
+
configure('instrument', true);
|
|
1567
|
+
for (var eventName in callbacks) {
|
|
1568
|
+
if (callbacks.hasOwnProperty(eventName)) {
|
|
1569
|
+
on(eventName, callbacks[eventName]);
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
function _guard(promise, test) {
|
|
1574
|
+
let guarded = promise.finally(() => {
|
|
1575
|
+
if (!test()) {
|
|
1576
|
+
guarded._subscribers.length = 0;
|
|
1577
|
+
}
|
|
1578
|
+
});
|
|
1579
|
+
return guarded;
|
|
1580
|
+
}
|
|
1581
|
+
function _objectIsAlive(object) {
|
|
1582
|
+
return !(object.isDestroyed || object.isDestroying);
|
|
1583
|
+
}
|
|
1584
|
+
function guardDestroyedStore(promise, store, label) {
|
|
1585
|
+
let wrapperPromise = resolve$2(promise, label).then(_v => {
|
|
1586
|
+
if (!_objectIsAlive(store)) {
|
|
1587
|
+
if (macroCondition(getOwnConfig().deprecations.DEPRECATE_RSVP_PROMISE)) {
|
|
1588
|
+
deprecate(`A Promise did not resolve by the time the store was destroyed. This will error in a future release.`, false, {
|
|
1589
|
+
id: 'ember-data:rsvp-unresolved-async',
|
|
1590
|
+
until: '5.0',
|
|
1591
|
+
for: '@ember-data/store',
|
|
1592
|
+
since: {
|
|
1593
|
+
available: '4.5',
|
|
1594
|
+
enabled: '4.5'
|
|
1595
|
+
}
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
return promise;
|
|
1600
|
+
});
|
|
1601
|
+
return _guard(wrapperPromise, () => {
|
|
1602
|
+
return _objectIsAlive(store);
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
/**
|
|
1607
|
+
This is a helper method that validates a JSON API top-level document
|
|
1608
|
+
|
|
1609
|
+
The format of a document is described here:
|
|
1610
|
+
http://jsonapi.org/format/#document-top-level
|
|
1611
|
+
|
|
1612
|
+
@internal
|
|
1613
|
+
*/
|
|
1614
|
+
function validateDocumentStructure(doc) {
|
|
1615
|
+
if (macroCondition(isDevelopingApp())) {
|
|
1616
|
+
let errors = [];
|
|
1617
|
+
if (!doc || typeof doc !== 'object') {
|
|
1618
|
+
errors.push('Top level of a JSON API document must be an object');
|
|
1619
|
+
} else {
|
|
1620
|
+
if (!('data' in doc) && !('errors' in doc) && !('meta' in doc)) {
|
|
1621
|
+
errors.push('One or more of the following keys must be present: "data", "errors", "meta".');
|
|
1622
|
+
} else {
|
|
1623
|
+
if ('data' in doc && 'errors' in doc) {
|
|
1624
|
+
errors.push('Top level keys "errors" and "data" cannot both be present in a JSON API document');
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
if ('data' in doc) {
|
|
1628
|
+
if (!(doc.data === null || Array.isArray(doc.data) || typeof doc.data === 'object')) {
|
|
1629
|
+
errors.push('data must be null, an object, or an array');
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
if ('meta' in doc) {
|
|
1633
|
+
if (typeof doc.meta !== 'object') {
|
|
1634
|
+
errors.push('meta must be an object');
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
if ('errors' in doc) {
|
|
1638
|
+
if (!Array.isArray(doc.errors)) {
|
|
1639
|
+
errors.push('errors must be an array');
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
if ('links' in doc) {
|
|
1643
|
+
if (typeof doc.links !== 'object') {
|
|
1644
|
+
errors.push('links must be an object');
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
if ('jsonapi' in doc) {
|
|
1648
|
+
if (typeof doc.jsonapi !== 'object') {
|
|
1649
|
+
errors.push('jsonapi must be an object');
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1652
|
+
if ('included' in doc) {
|
|
1653
|
+
if (typeof doc.included !== 'object') {
|
|
1654
|
+
errors.push('included must be an array');
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
assert(`Response must be normalized to a valid JSON API document:\n\t* ${errors.join('\n\t* ')}`, errors.length === 0);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
function normalizeResponseHelper(serializer, store, modelClass, payload, id, requestType) {
|
|
1662
|
+
let normalizedResponse = serializer ? serializer.normalizeResponse(store, modelClass, payload, id, requestType) : payload;
|
|
1663
|
+
validateDocumentStructure(normalizedResponse);
|
|
1664
|
+
return normalizedResponse;
|
|
1665
|
+
}
|
|
1666
|
+
const LegacyNetworkHandler = {
|
|
1667
|
+
request(context, next) {
|
|
1668
|
+
// if we are not a legacy request, move on
|
|
1669
|
+
if (context.request.url || !context.request.op) {
|
|
1670
|
+
return next(context.request);
|
|
1671
|
+
}
|
|
1672
|
+
switch (context.request.op) {
|
|
1673
|
+
case 'findAll':
|
|
1674
|
+
return findAll(context);
|
|
1675
|
+
case 'queryRecord':
|
|
1676
|
+
return queryRecord(context);
|
|
1677
|
+
case 'query':
|
|
1678
|
+
return query(context);
|
|
1679
|
+
default:
|
|
1680
|
+
return next(context.request);
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
};
|
|
1684
|
+
function findAll(context) {
|
|
1685
|
+
const {
|
|
1686
|
+
store,
|
|
1687
|
+
data
|
|
1688
|
+
} = context.request;
|
|
1689
|
+
const {
|
|
1690
|
+
type,
|
|
1691
|
+
options
|
|
1692
|
+
} = data;
|
|
1693
|
+
const adapter = store.adapterFor(type);
|
|
1694
|
+
assert(`You tried to load all records but you have no adapter (for ${type})`, adapter);
|
|
1695
|
+
assert(`You tried to load all records but your adapter does not implement 'findAll'`, typeof adapter.findAll === 'function');
|
|
1696
|
+
|
|
1697
|
+
// avoid initializing the liveArray just to set `isUpdating`
|
|
1698
|
+
const maybeRecordArray = store.recordArrayManager._live.get(type);
|
|
1699
|
+
const snapshotArray = new SnapshotRecordArray(store, type, options);
|
|
1700
|
+
const shouldReload = options.reload || options.reload !== false && (adapter.shouldReloadAll && adapter.shouldReloadAll(store, snapshotArray) || !adapter.shouldReloadAll && snapshotArray.length === 0);
|
|
1701
|
+
let fetch;
|
|
1702
|
+
if (shouldReload) {
|
|
1703
|
+
maybeRecordArray && (maybeRecordArray.isUpdating = true);
|
|
1704
|
+
fetch = _findAll(adapter, store, type, snapshotArray);
|
|
1705
|
+
} else {
|
|
1706
|
+
fetch = Promise$1.resolve(store.peekAll(type));
|
|
1707
|
+
if (options.backgroundReload || options.backgroundReload !== false && (!adapter.shouldBackgroundReloadAll || adapter.shouldBackgroundReloadAll(store, snapshotArray))) {
|
|
1708
|
+
maybeRecordArray && (maybeRecordArray.isUpdating = true);
|
|
1709
|
+
void _findAll(adapter, store, type, snapshotArray);
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
return fetch;
|
|
1713
|
+
}
|
|
1714
|
+
function payloadIsNotBlank(adapterPayload) {
|
|
1715
|
+
if (Array.isArray(adapterPayload)) {
|
|
1716
|
+
return true;
|
|
1717
|
+
} else {
|
|
1718
|
+
return Object.keys(adapterPayload || {}).length;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
function _findAll(adapter, store, type, snapshotArray) {
|
|
1722
|
+
const schema = store.modelFor(type);
|
|
1723
|
+
let promise = Promise$1.resolve().then(() => adapter.findAll(store, schema, null, snapshotArray));
|
|
1724
|
+
promise = guardDestroyedStore(promise, store, macroCondition(isDevelopingApp()) ? `DS: Handle Adapter#findAll of ${type}` : '');
|
|
1725
|
+
return promise.then(adapterPayload => {
|
|
1726
|
+
assert(`You made a 'findAll' request for '${type}' records, but the adapter's response did not have any data`, payloadIsNotBlank(adapterPayload));
|
|
1727
|
+
const serializer = store.serializerFor(type);
|
|
1728
|
+
const payload = normalizeResponseHelper(serializer, store, schema, adapterPayload, null, 'findAll');
|
|
1729
|
+
store._push(payload);
|
|
1730
|
+
snapshotArray._recordArray.isUpdating = false;
|
|
1731
|
+
return snapshotArray._recordArray;
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1734
|
+
function query(context) {
|
|
1735
|
+
const {
|
|
1736
|
+
store,
|
|
1737
|
+
data
|
|
1738
|
+
} = context.request;
|
|
1739
|
+
let {
|
|
1740
|
+
options
|
|
1741
|
+
} = data;
|
|
1742
|
+
const {
|
|
1743
|
+
type,
|
|
1744
|
+
query
|
|
1745
|
+
} = data;
|
|
1746
|
+
const adapter = store.adapterFor(type);
|
|
1747
|
+
assert(`You tried to make a query but you have no adapter (for ${type})`, adapter);
|
|
1748
|
+
assert(`You tried to make a query but your adapter does not implement 'query'`, typeof adapter.query === 'function');
|
|
1749
|
+
const recordArray = options._recordArray || store.recordArrayManager.createArray({
|
|
1750
|
+
type,
|
|
1751
|
+
query
|
|
1752
|
+
});
|
|
1753
|
+
if (macroCondition(isDevelopingApp())) {
|
|
1754
|
+
options = Object.assign({}, options);
|
|
1755
|
+
delete options._recordArray;
|
|
1756
|
+
} else {
|
|
1757
|
+
delete options._recordArray;
|
|
1758
|
+
}
|
|
1759
|
+
const schema = store.modelFor(type);
|
|
1760
|
+
let promise = Promise$1.resolve().then(() => adapter.query(store, schema, query, recordArray, options));
|
|
1761
|
+
promise = guardDestroyedStore(promise, store, macroCondition(isDevelopingApp()) ? `DS: Handle Adapter#query of ${type}` : ``);
|
|
1762
|
+
return promise.then(adapterPayload => {
|
|
1763
|
+
const serializer = store.serializerFor(type);
|
|
1764
|
+
const payload = normalizeResponseHelper(serializer, store, schema, adapterPayload, null, 'query');
|
|
1765
|
+
const identifiers = store._push(payload);
|
|
1766
|
+
assert('The response to store.query is expected to be an array but it was a single record. Please wrap your response in an array or use `store.queryRecord` to query for a single record.', Array.isArray(identifiers));
|
|
1767
|
+
store.recordArrayManager.populateManagedArray(recordArray, identifiers, payload);
|
|
1768
|
+
return recordArray;
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
function assertSingleResourceDocument(payload) {
|
|
1772
|
+
assert(`Expected the primary data returned by the serializer for a 'queryRecord' response to be a single object or null but instead it was an array.`, !Array.isArray(payload.data));
|
|
1773
|
+
}
|
|
1774
|
+
function queryRecord(context) {
|
|
1775
|
+
const {
|
|
1776
|
+
store,
|
|
1777
|
+
data
|
|
1778
|
+
} = context.request;
|
|
1779
|
+
const {
|
|
1780
|
+
type,
|
|
1781
|
+
query,
|
|
1782
|
+
options
|
|
1783
|
+
} = data;
|
|
1784
|
+
const adapter = store.adapterFor(type);
|
|
1785
|
+
assert(`You tried to make a query but you have no adapter (for ${type})`, adapter);
|
|
1786
|
+
assert(`You tried to make a query but your adapter does not implement 'queryRecord'`, typeof adapter.queryRecord === 'function');
|
|
1787
|
+
const schema = store.modelFor(type);
|
|
1788
|
+
let promise = Promise$1.resolve().then(() => adapter.queryRecord(store, schema, query, options));
|
|
1789
|
+
promise = guardDestroyedStore(promise, store, macroCondition(isDevelopingApp()) ? `DS: Handle Adapter#queryRecord of ${type}` : ``);
|
|
1790
|
+
return promise.then(adapterPayload => {
|
|
1791
|
+
const serializer = store.serializerFor(type);
|
|
1792
|
+
const payload = normalizeResponseHelper(serializer, store, schema, adapterPayload, null, 'queryRecord');
|
|
1793
|
+
assertSingleResourceDocument(payload);
|
|
1794
|
+
return store.push(payload);
|
|
1795
|
+
});
|
|
1796
|
+
}
|
|
1797
|
+
export { LegacyNetworkHandler };
|