Version 1
[yaffs-website] / node_modules / core-js / library / modules / es7.observable.js
1 'use strict';
2 // https://github.com/zenparsing/es-observable
3 var $export     = require('./_export')
4   , global      = require('./_global')
5   , core        = require('./_core')
6   , microtask   = require('./_microtask')()
7   , OBSERVABLE  = require('./_wks')('observable')
8   , aFunction   = require('./_a-function')
9   , anObject    = require('./_an-object')
10   , anInstance  = require('./_an-instance')
11   , redefineAll = require('./_redefine-all')
12   , hide        = require('./_hide')
13   , forOf       = require('./_for-of')
14   , RETURN      = forOf.RETURN;
15
16 var getMethod = function(fn){
17   return fn == null ? undefined : aFunction(fn);
18 };
19
20 var cleanupSubscription = function(subscription){
21   var cleanup = subscription._c;
22   if(cleanup){
23     subscription._c = undefined;
24     cleanup();
25   }
26 };
27
28 var subscriptionClosed = function(subscription){
29   return subscription._o === undefined;
30 };
31
32 var closeSubscription = function(subscription){
33   if(!subscriptionClosed(subscription)){
34     subscription._o = undefined;
35     cleanupSubscription(subscription);
36   }
37 };
38
39 var Subscription = function(observer, subscriber){
40   anObject(observer);
41   this._c = undefined;
42   this._o = observer;
43   observer = new SubscriptionObserver(this);
44   try {
45     var cleanup      = subscriber(observer)
46       , subscription = cleanup;
47     if(cleanup != null){
48       if(typeof cleanup.unsubscribe === 'function')cleanup = function(){ subscription.unsubscribe(); };
49       else aFunction(cleanup);
50       this._c = cleanup;
51     }
52   } catch(e){
53     observer.error(e);
54     return;
55   } if(subscriptionClosed(this))cleanupSubscription(this);
56 };
57
58 Subscription.prototype = redefineAll({}, {
59   unsubscribe: function unsubscribe(){ closeSubscription(this); }
60 });
61
62 var SubscriptionObserver = function(subscription){
63   this._s = subscription;
64 };
65
66 SubscriptionObserver.prototype = redefineAll({}, {
67   next: function next(value){
68     var subscription = this._s;
69     if(!subscriptionClosed(subscription)){
70       var observer = subscription._o;
71       try {
72         var m = getMethod(observer.next);
73         if(m)return m.call(observer, value);
74       } catch(e){
75         try {
76           closeSubscription(subscription);
77         } finally {
78           throw e;
79         }
80       }
81     }
82   },
83   error: function error(value){
84     var subscription = this._s;
85     if(subscriptionClosed(subscription))throw value;
86     var observer = subscription._o;
87     subscription._o = undefined;
88     try {
89       var m = getMethod(observer.error);
90       if(!m)throw value;
91       value = m.call(observer, value);
92     } catch(e){
93       try {
94         cleanupSubscription(subscription);
95       } finally {
96         throw e;
97       }
98     } cleanupSubscription(subscription);
99     return value;
100   },
101   complete: function complete(value){
102     var subscription = this._s;
103     if(!subscriptionClosed(subscription)){
104       var observer = subscription._o;
105       subscription._o = undefined;
106       try {
107         var m = getMethod(observer.complete);
108         value = m ? m.call(observer, value) : undefined;
109       } catch(e){
110         try {
111           cleanupSubscription(subscription);
112         } finally {
113           throw e;
114         }
115       } cleanupSubscription(subscription);
116       return value;
117     }
118   }
119 });
120
121 var $Observable = function Observable(subscriber){
122   anInstance(this, $Observable, 'Observable', '_f')._f = aFunction(subscriber);
123 };
124
125 redefineAll($Observable.prototype, {
126   subscribe: function subscribe(observer){
127     return new Subscription(observer, this._f);
128   },
129   forEach: function forEach(fn){
130     var that = this;
131     return new (core.Promise || global.Promise)(function(resolve, reject){
132       aFunction(fn);
133       var subscription = that.subscribe({
134         next : function(value){
135           try {
136             return fn(value);
137           } catch(e){
138             reject(e);
139             subscription.unsubscribe();
140           }
141         },
142         error: reject,
143         complete: resolve
144       });
145     });
146   }
147 });
148
149 redefineAll($Observable, {
150   from: function from(x){
151     var C = typeof this === 'function' ? this : $Observable;
152     var method = getMethod(anObject(x)[OBSERVABLE]);
153     if(method){
154       var observable = anObject(method.call(x));
155       return observable.constructor === C ? observable : new C(function(observer){
156         return observable.subscribe(observer);
157       });
158     }
159     return new C(function(observer){
160       var done = false;
161       microtask(function(){
162         if(!done){
163           try {
164             if(forOf(x, false, function(it){
165               observer.next(it);
166               if(done)return RETURN;
167             }) === RETURN)return;
168           } catch(e){
169             if(done)throw e;
170             observer.error(e);
171             return;
172           } observer.complete();
173         }
174       });
175       return function(){ done = true; };
176     });
177   },
178   of: function of(){
179     for(var i = 0, l = arguments.length, items = Array(l); i < l;)items[i] = arguments[i++];
180     return new (typeof this === 'function' ? this : $Observable)(function(observer){
181       var done = false;
182       microtask(function(){
183         if(!done){
184           for(var i = 0; i < items.length; ++i){
185             observer.next(items[i]);
186             if(done)return;
187           } observer.complete();
188         }
189       });
190       return function(){ done = true; };
191     });
192   }
193 });
194
195 hide($Observable.prototype, OBSERVABLE, function(){ return this; });
196
197 $export($export.G, {Observable: $Observable});
198
199 require('./_set-species')('Observable');