diff --git a/dist/MeteorObservable.d.ts b/dist/MeteorObservable.d.ts new file mode 100644 index 00000000..6f9eca4b --- /dev/null +++ b/dist/MeteorObservable.d.ts @@ -0,0 +1,6 @@ +import { Observable } from 'rxjs'; +export declare class MeteorObservable { + static call(name: string, ...args: any[]): Observable; + static subscribe(name: string, ...args: any[]): Observable; + static autorun(): Observable; +} diff --git a/dist/MeteorObservable.js b/dist/MeteorObservable.js new file mode 100644 index 00000000..b14a1ff9 --- /dev/null +++ b/dist/MeteorObservable.js @@ -0,0 +1,93 @@ +'use strict'; +import { Observable } from 'rxjs'; +import { isMeteorCallbacks, forkZone, removeObserver } from './utils'; +function throwInvalidCallback(method) { + throw new Error("Invalid " + method + " arguments:\n your last param can't be a callback function, \n please remove it and use \".subscribe\" of the Observable!"); +} +export var MeteorObservable = (function () { + function MeteorObservable() { + } + MeteorObservable.call = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var lastParam = args[args.length - 1]; + if (isMeteorCallbacks(lastParam)) { + throwInvalidCallback('MeteorObservable.call'); + } + var zone = forkZone(); + return Observable.create(function (observer) { + Meteor.call.apply(Meteor, [name].concat(args.concat([ + function (error, result) { + zone.run(function () { + error ? observer.error(error) : + observer.next(result); + observer.complete(); + }); + } + ]))); + }); + }; + MeteorObservable.subscribe = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var lastParam = args[args.length - 1]; + if (isMeteorCallbacks(lastParam)) { + throwInvalidCallback('MeteorObservable.subscribe'); + } + var zone = forkZone(); + var observers = []; + var subscribe = function () { + return Meteor.subscribe.apply(Meteor, [name].concat(args.concat([{ + onError: function (error) { + zone.run(function () { + observers.forEach(function (observer) { return observer.error(error); }); + }); + }, + onReady: function () { + zone.run(function () { + observers.forEach(function (observer) { return observer.next(); }); + }); + } + } + ]))); + }; + var subHandler = null; + return Observable.create(function (observer) { + observers.push(observer); + // Execute subscribe lazily. + if (subHandler === null) { + subHandler = subscribe(); + } + return function () { + removeObserver(observers, observer, function () { return subHandler.stop(); }); + }; + }); + }; + MeteorObservable.autorun = function () { + var zone = forkZone(); + var observers = []; + var autorun = function () { + return Tracker.autorun(function (computation) { + zone.run(function () { + observers.forEach(function (observer) { return observer.next(computation); }); + }); + }); + }; + var handler = null; + return Observable.create(function (observer) { + observers.push(observer); + // Execute autorun lazily. + if (handler === null) { + handler = autorun(); + } + return function () { + removeObserver(observers, observer, function () { return handler.stop(); }); + }; + }); + }; + return MeteorObservable; +}()); diff --git a/dist/ObservableCollection.d.ts b/dist/ObservableCollection.d.ts new file mode 100644 index 00000000..1d3f0133 --- /dev/null +++ b/dist/ObservableCollection.d.ts @@ -0,0 +1,56 @@ +import { Observable } from 'rxjs'; +import { ObservableCursor } from './ObservableCursor'; +import Selector = Mongo.Selector; +import ObjectID = Mongo.ObjectID; +import SortSpecifier = Mongo.SortSpecifier; +import FieldSpecifier = Mongo.FieldSpecifier; +import Modifier = Mongo.Modifier; +export declare module MongoObservable { + interface ConstructorOptions { + connection?: Object; + idGeneration?: string; + transform?: Function; + } + interface AllowDenyOptionsObject { + insert?: (userId: string, doc: T) => boolean; + update?: (userId: string, doc: T, fieldNames: string[], modifier: any) => boolean; + remove?: (userId: string, doc: T) => boolean; + fetch?: string[]; + transform?: Function; + } + function fromExisting(collection: Mongo.Collection): Collection; + class Collection { + private _collection; + constructor(nameOrExisting: string | Mongo.Collection, options?: ConstructorOptions); + readonly collection: Mongo.Collection; + allow(options: AllowDenyOptionsObject): boolean; + deny(options: AllowDenyOptionsObject): boolean; + rawCollection(): any; + rawDatabase(): any; + insert(doc: T): Observable; + remove(selector: Selector | ObjectID | string): Observable; + update(selector: Selector | ObjectID | string, modifier: Modifier, options?: { + multi?: boolean; + upsert?: boolean; + }): Observable; + upsert(selector: Selector | ObjectID | string, modifier: Modifier, options?: { + multi?: boolean; + }): Observable; + find(selector?: Selector | ObjectID | string, options?: { + sort?: SortSpecifier; + skip?: number; + limit?: number; + fields?: FieldSpecifier; + reactive?: boolean; + transform?: Function; + }): ObservableCursor; + findOne(selector?: Selector | ObjectID | string, options?: { + sort?: SortSpecifier; + skip?: number; + fields?: FieldSpecifier; + reactive?: boolean; + transform?: Function; + }): T; + private _createObservable(observers); + } +} diff --git a/dist/ObservableCollection.js b/dist/ObservableCollection.js new file mode 100644 index 00000000..08d45f55 --- /dev/null +++ b/dist/ObservableCollection.js @@ -0,0 +1,105 @@ +import { Observable } from 'rxjs'; +import { ObservableCursor } from './ObservableCursor'; +import { removeObserver } from './utils'; +export var MongoObservable; +(function (MongoObservable) { + 'use strict'; + function fromExisting(collection) { + return new MongoObservable.Collection(collection); + } + MongoObservable.fromExisting = fromExisting; + var Collection = (function () { + function Collection(nameOrExisting, options) { + if (nameOrExisting instanceof Mongo.Collection) { + this._collection = nameOrExisting; + } + else { + this._collection = new Mongo.Collection(nameOrExisting, options); + } + } + Object.defineProperty(Collection.prototype, "collection", { + get: function () { + return this._collection; + }, + enumerable: true, + configurable: true + }); + Collection.prototype.allow = function (options) { + return this._collection.allow(options); + }; + Collection.prototype.deny = function (options) { + return this._collection.deny(options); + }; + Collection.prototype.rawCollection = function () { + return this._collection.rawCollection(); + }; + Collection.prototype.rawDatabase = function () { + return this._collection.rawDatabase(); + }; + Collection.prototype.insert = function (doc) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.insert(doc, function (error, docId) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(docId); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.remove = function (selector) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.remove(selector, function (error, removed) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(removed); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.update = function (selector, modifier, options) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.update(selector, modifier, options, function (error, updated) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(updated); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.upsert = function (selector, modifier, options) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.upsert(selector, modifier, options, function (error, affected) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(affected); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.find = function (selector, options) { + var cursor = this._collection.find.apply(this._collection, arguments); + return ObservableCursor.create(cursor); + }; + Collection.prototype.findOne = function (selector, options) { + return this._collection.findOne.apply(this._collection, arguments); + }; + Collection.prototype._createObservable = function (observers) { + return Observable.create(function (observer) { + observers.push(observer); + return function () { + removeObserver(observers, observer); + }; + }); + }; + return Collection; + }()); + MongoObservable.Collection = Collection; +})(MongoObservable || (MongoObservable = {})); diff --git a/dist/ObservableCursor.d.ts b/dist/ObservableCursor.d.ts new file mode 100644 index 00000000..e2df266e --- /dev/null +++ b/dist/ObservableCursor.d.ts @@ -0,0 +1,23 @@ +import { Observable } from 'rxjs'; +export declare class ObservableCursor extends Observable { + private _zone; + private _data; + private _cursor; + private _hCursor; + private _observers; + static create(cursor: Mongo.Cursor): ObservableCursor; + constructor(cursor: Mongo.Cursor); + readonly cursor: Mongo.Cursor; + stop(): void; + dispose(): void; + fetch(): Array; + observe(callbacks: Mongo.ObserveCallbacks): Meteor.LiveQueryHandle; + observeChanges(callbacks: Mongo.ObserveChangesCallbacks): Meteor.LiveQueryHandle; + _runComplete(): void; + _runNext(data: Array): void; + _addedAt(doc: any, at: any, before: any): void; + _changedAt(doc: any, old: any, at: any): void; + _removedAt(doc: any, at: any): void; + _handleChange(): void; + _observeCursor(cursor: Mongo.Cursor): any; +} diff --git a/dist/ObservableCursor.js b/dist/ObservableCursor.js new file mode 100644 index 00000000..403cec92 --- /dev/null +++ b/dist/ObservableCursor.js @@ -0,0 +1,96 @@ +'use strict'; +import { Observable } from 'rxjs'; +import { gZone, forkZone, removeObserver } from './utils'; +export var ObservableCursor = (function (_super) { + __extends(ObservableCursor, _super); + function ObservableCursor(cursor) { + var _this = this; + _super.call(this, function (observer) { + _this._observers.push(observer); + if (!_this._hCursor) { + _this._hCursor = _this._observeCursor(cursor); + } + return function () { + removeObserver(_this._observers, observer, function () { return _this.stop(); }); + }; + }); + this._data = []; + this._observers = []; + _.extend(this, _.omit(cursor, 'count', 'map')); + this._cursor = cursor; + this._zone = forkZone(); + } + ObservableCursor.create = function (cursor) { + return new ObservableCursor(cursor); + }; + Object.defineProperty(ObservableCursor.prototype, "cursor", { + get: function () { + return this._cursor; + }, + enumerable: true, + configurable: true + }); + ObservableCursor.prototype.stop = function () { + var _this = this; + this._zone.run(function () { + _this._runComplete(); + }); + if (this._hCursor) { + this._hCursor.stop(); + } + this._hCursor = null; + }; + ObservableCursor.prototype.dispose = function () { + this._observers = null; + this._cursor = null; + }; + ObservableCursor.prototype.fetch = function () { + return this._cursor.fetch(); + }; + ObservableCursor.prototype.observe = function (callbacks) { + return this._cursor.observe(callbacks); + }; + ObservableCursor.prototype.observeChanges = function (callbacks) { + return this._cursor.observeChanges(callbacks); + }; + ObservableCursor.prototype._runComplete = function () { + this._observers.forEach(function (observer) { + observer.complete(); + }); + }; + ObservableCursor.prototype._runNext = function (data) { + this._observers.forEach(function (observer) { + observer.next(data); + }); + }; + ObservableCursor.prototype._addedAt = function (doc, at, before) { + this._data.splice(at, 0, doc); + this._handleChange(); + }; + ObservableCursor.prototype._changedAt = function (doc, old, at) { + this._data[at] = doc; + this._handleChange(); + }; + ; + ObservableCursor.prototype._removedAt = function (doc, at) { + this._data.splice(at, 1); + this._handleChange(); + }; + ; + ObservableCursor.prototype._handleChange = function () { + var _this = this; + this._zone.run(function () { + _this._runNext(_this._data); + }); + }; + ; + ObservableCursor.prototype._observeCursor = function (cursor) { + var _this = this; + return gZone.run(function () { return cursor.observe({ + addedAt: _this._addedAt.bind(_this), + changedAt: _this._changedAt.bind(_this), + removedAt: _this._removedAt.bind(_this) + }); }); + }; + return ObservableCursor; +}(Observable)); diff --git a/dist/bundles/index.umd.js b/dist/bundles/index.umd.js new file mode 100644 index 00000000..9e91580c --- /dev/null +++ b/dist/bundles/index.umd.js @@ -0,0 +1,392 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('rxjs')) : + typeof define === 'function' && define.amd ? define(['exports', 'rxjs'], factory) : + (factory((global.meteor = global.meteor || {}, global.meteor.rxjs = global.meteor.rxjs || {}),global.rxjs)); +}(this, (function (exports,rxjs) { 'use strict'; + +var subscribeEvents = ['onReady', 'onError', 'onStop']; +function isMeteorCallbacks(callbacks) { + return _.isFunction(callbacks) || isCallbacksObject(callbacks); +} +// Checks if callbacks of {@link CallbacksObject} type. +function isCallbacksObject(callbacks) { + return callbacks && subscribeEvents.some(function (event) { + return _.isFunction(callbacks[event]); + }); +} + +var g = typeof global === 'object' ? global : + typeof window === 'object' ? window : + typeof self === 'object' ? self : undefined; +var METEOR_RXJS_ZONE = 'meteor-rxjs-zone'; +var fakeZone = { + name: METEOR_RXJS_ZONE, + run: function (func) { + return func(); + }, + fork: function (spec) { + return fakeZone; + } +}; +function forkZone() { + if (g.Zone) { + var zone = g.Zone.current; + if (zone.name === METEOR_RXJS_ZONE) { + zone = zone.parent || fakeZone; + } + return zone.fork({ name: METEOR_RXJS_ZONE }); + } + return fakeZone; +} +function getZone() { + if (g.Zone) { + var zone = g.Zone.current; + if (zone.name === METEOR_RXJS_ZONE) { + return zone.parent; + } + return zone; + } +} +function removeObserver(observers, observer, onEmpty) { + var index = observers.indexOf(observer); + observers.splice(index, 1); + if (observers.length === 0 && onEmpty) { + onEmpty(); + } +} +var gZone = g.Zone ? g.Zone.current : fakeZone; + +var ObservableCursor = (function (_super) { + __extends(ObservableCursor, _super); + function ObservableCursor(cursor) { + var _this = this; + _super.call(this, function (observer) { + _this._observers.push(observer); + if (!_this._hCursor) { + _this._hCursor = _this._observeCursor(cursor); + } + return function () { + removeObserver(_this._observers, observer, function () { return _this.stop(); }); + }; + }); + this._data = []; + this._observers = []; + _.extend(this, _.omit(cursor, 'count', 'map')); + this._cursor = cursor; + this._zone = forkZone(); + } + ObservableCursor.create = function (cursor) { + return new ObservableCursor(cursor); + }; + Object.defineProperty(ObservableCursor.prototype, "cursor", { + get: function () { + return this._cursor; + }, + enumerable: true, + configurable: true + }); + ObservableCursor.prototype.stop = function () { + var _this = this; + this._zone.run(function () { + _this._runComplete(); + }); + if (this._hCursor) { + this._hCursor.stop(); + } + this._hCursor = null; + }; + ObservableCursor.prototype.dispose = function () { + this._observers = null; + this._cursor = null; + }; + ObservableCursor.prototype.fetch = function () { + return this._cursor.fetch(); + }; + ObservableCursor.prototype.observe = function (callbacks) { + return this._cursor.observe(callbacks); + }; + ObservableCursor.prototype.observeChanges = function (callbacks) { + return this._cursor.observeChanges(callbacks); + }; + ObservableCursor.prototype._runComplete = function () { + this._observers.forEach(function (observer) { + observer.complete(); + }); + }; + ObservableCursor.prototype._runNext = function (data) { + this._observers.forEach(function (observer) { + observer.next(data); + }); + }; + ObservableCursor.prototype._addedAt = function (doc, at, before) { + this._data.splice(at, 0, doc); + this._handleChange(); + }; + ObservableCursor.prototype._changedAt = function (doc, old, at) { + this._data[at] = doc; + this._handleChange(); + }; + + ObservableCursor.prototype._removedAt = function (doc, at) { + this._data.splice(at, 1); + this._handleChange(); + }; + + ObservableCursor.prototype._handleChange = function () { + var _this = this; + this._zone.run(function () { + _this._runNext(_this._data); + }); + }; + + ObservableCursor.prototype._observeCursor = function (cursor) { + var _this = this; + return gZone.run(function () { return cursor.observe({ + addedAt: _this._addedAt.bind(_this), + changedAt: _this._changedAt.bind(_this), + removedAt: _this._removedAt.bind(_this) + }); }); + }; + return ObservableCursor; +}(rxjs.Observable)); + +(function (MongoObservable) { + 'use strict'; + function fromExisting(collection) { + return new MongoObservable.Collection(collection); + } + MongoObservable.fromExisting = fromExisting; + var Collection = (function () { + function Collection(nameOrExisting, options) { + if (nameOrExisting instanceof Mongo.Collection) { + this._collection = nameOrExisting; + } + else { + this._collection = new Mongo.Collection(nameOrExisting, options); + } + } + Object.defineProperty(Collection.prototype, "collection", { + get: function () { + return this._collection; + }, + enumerable: true, + configurable: true + }); + Collection.prototype.allow = function (options) { + return this._collection.allow(options); + }; + Collection.prototype.deny = function (options) { + return this._collection.deny(options); + }; + Collection.prototype.rawCollection = function () { + return this._collection.rawCollection(); + }; + Collection.prototype.rawDatabase = function () { + return this._collection.rawDatabase(); + }; + Collection.prototype.insert = function (doc) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.insert(doc, function (error, docId) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(docId); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.remove = function (selector) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.remove(selector, function (error, removed) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(removed); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.update = function (selector, modifier, options) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.update(selector, modifier, options, function (error, updated) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(updated); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.upsert = function (selector, modifier, options) { + var observers = []; + var obs = this._createObservable(observers); + this._collection.upsert(selector, modifier, options, function (error, affected) { + observers.forEach(function (observer) { + error ? observer.error(error) : + observer.next(affected); + observer.complete(); + }); + }); + return obs; + }; + Collection.prototype.find = function (selector, options) { + var cursor = this._collection.find.apply(this._collection, arguments); + return ObservableCursor.create(cursor); + }; + Collection.prototype.findOne = function (selector, options) { + return this._collection.findOne.apply(this._collection, arguments); + }; + Collection.prototype._createObservable = function (observers) { + return rxjs.Observable.create(function (observer) { + observers.push(observer); + return function () { + removeObserver(observers, observer); + }; + }); + }; + return Collection; + }()); + MongoObservable.Collection = Collection; +})(exports.MongoObservable || (exports.MongoObservable = {})); + +function throwInvalidCallback(method) { + throw new Error("Invalid " + method + " arguments:\n your last param can't be a callback function, \n please remove it and use \".subscribe\" of the Observable!"); +} +var MeteorObservable = (function () { + function MeteorObservable() { + } + MeteorObservable.call = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var lastParam = args[args.length - 1]; + if (isMeteorCallbacks(lastParam)) { + throwInvalidCallback('MeteorObservable.call'); + } + var zone = forkZone(); + return rxjs.Observable.create(function (observer) { + Meteor.call.apply(Meteor, [name].concat(args.concat([ + function (error, result) { + zone.run(function () { + error ? observer.error(error) : + observer.next(result); + observer.complete(); + }); + } + ]))); + }); + }; + MeteorObservable.subscribe = function (name) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + var lastParam = args[args.length - 1]; + if (isMeteorCallbacks(lastParam)) { + throwInvalidCallback('MeteorObservable.subscribe'); + } + var zone = forkZone(); + var observers = []; + var subscribe = function () { + return Meteor.subscribe.apply(Meteor, [name].concat(args.concat([{ + onError: function (error) { + zone.run(function () { + observers.forEach(function (observer) { return observer.error(error); }); + }); + }, + onReady: function () { + zone.run(function () { + observers.forEach(function (observer) { return observer.next(); }); + }); + } + } + ]))); + }; + var subHandler = null; + return rxjs.Observable.create(function (observer) { + observers.push(observer); + // Execute subscribe lazily. + if (subHandler === null) { + subHandler = subscribe(); + } + return function () { + removeObserver(observers, observer, function () { return subHandler.stop(); }); + }; + }); + }; + MeteorObservable.autorun = function () { + var zone = forkZone(); + var observers = []; + var autorun = function () { + return Tracker.autorun(function (computation) { + zone.run(function () { + observers.forEach(function (observer) { return observer.next(computation); }); + }); + }); + }; + var handler = null; + return rxjs.Observable.create(function (observer) { + observers.push(observer); + // Execute autorun lazily. + if (handler === null) { + handler = autorun(); + } + return function () { + removeObserver(observers, observer, function () { return handler.stop(); }); + }; + }); + }; + return MeteorObservable; +}()); + +function zone(zone) { + return this.lift(new ZoneOperator(zone || getZone())); +} +var ZoneOperator = (function () { + function ZoneOperator(zone) { + this.zone = zone; + } + ZoneOperator.prototype.call = function (subscriber, source) { + return source._subscribe(new ZoneSubscriber(subscriber, this.zone)); + }; + return ZoneOperator; +}()); +var ZoneSubscriber = (function (_super) { + __extends(ZoneSubscriber, _super); + function ZoneSubscriber(destination, zone) { + _super.call(this, destination); + this.zone = zone; + } + ZoneSubscriber.prototype._next = function (value) { + var _this = this; + this.zone.run(function () { + _this.destination.next(value); + }); + }; + ZoneSubscriber.prototype._complete = function () { + var _this = this; + this.zone.run(function () { + _this.destination.complete(); + }); + }; + ZoneSubscriber.prototype._error = function (err) { + var _this = this; + this.zone.run(function () { + _this.destination.error(err); + }); + }; + return ZoneSubscriber; +}(rxjs.Subscriber)); +rxjs.Observable.prototype.zone = zone; + +exports.MeteorObservable = MeteorObservable; +exports.ObservableCursor = ObservableCursor; +exports.zone = zone; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 00000000..1ade70f9 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,4 @@ +export * from './ObservableCollection'; +export * from './MeteorObservable'; +export * from './ObservableCursor'; +export * from './zone'; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..1ade70f9 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,4 @@ +export * from './ObservableCollection'; +export * from './MeteorObservable'; +export * from './ObservableCursor'; +export * from './zone'; diff --git a/dist/utils.d.ts b/dist/utils.d.ts new file mode 100644 index 00000000..56922e09 --- /dev/null +++ b/dist/utils.d.ts @@ -0,0 +1,15 @@ +import { Subscriber } from 'rxjs'; +export declare type CallbacksObject = { + onReady?: Function; + onError?: Function; + onStop?: Function; +}; +export declare type MeteorCallbacks = ((...args) => any) | CallbacksObject; +export declare const subscribeEvents: string[]; +export declare function isMeteorCallbacks(callbacks: any): boolean; +export declare function isCallbacksObject(callbacks: any): boolean; +export declare const g: any; +export declare function forkZone(): any; +export declare function getZone(): any; +export declare function removeObserver(observers: Subscriber[], observer: Subscriber, onEmpty?: Function): void; +export declare const gZone: any; diff --git a/dist/utils.js b/dist/utils.js new file mode 100644 index 00000000..babecb06 --- /dev/null +++ b/dist/utils.js @@ -0,0 +1,52 @@ +'use strict'; +export var subscribeEvents = ['onReady', 'onError', 'onStop']; +export function isMeteorCallbacks(callbacks) { + return _.isFunction(callbacks) || isCallbacksObject(callbacks); +} +// Checks if callbacks of {@link CallbacksObject} type. +export function isCallbacksObject(callbacks) { + return callbacks && subscribeEvents.some(function (event) { + return _.isFunction(callbacks[event]); + }); +} +; +export var g = typeof global === 'object' ? global : + typeof window === 'object' ? window : + typeof self === 'object' ? self : this; +var METEOR_RXJS_ZONE = 'meteor-rxjs-zone'; +var fakeZone = { + name: METEOR_RXJS_ZONE, + run: function (func) { + return func(); + }, + fork: function (spec) { + return fakeZone; + } +}; +export function forkZone() { + if (g.Zone) { + var zone = g.Zone.current; + if (zone.name === METEOR_RXJS_ZONE) { + zone = zone.parent || fakeZone; + } + return zone.fork({ name: METEOR_RXJS_ZONE }); + } + return fakeZone; +} +export function getZone() { + if (g.Zone) { + var zone = g.Zone.current; + if (zone.name === METEOR_RXJS_ZONE) { + return zone.parent; + } + return zone; + } +} +export function removeObserver(observers, observer, onEmpty) { + var index = observers.indexOf(observer); + observers.splice(index, 1); + if (observers.length === 0 && onEmpty) { + onEmpty(); + } +} +export var gZone = g.Zone ? g.Zone.current : fakeZone; diff --git a/dist/zone.d.ts b/dist/zone.d.ts new file mode 100644 index 00000000..731de149 --- /dev/null +++ b/dist/zone.d.ts @@ -0,0 +1,10 @@ +import { Observable } from 'rxjs'; +export declare function zone(zone?: Zone): Observable; +export interface ZoneSignature { + (zone?: Zone): Observable; +} +declare module 'rxjs/Observable' { + interface Observable { + zone: ZoneSignature; + } +} diff --git a/dist/zone.js b/dist/zone.js new file mode 100644 index 00000000..aedfb5a2 --- /dev/null +++ b/dist/zone.js @@ -0,0 +1,42 @@ +'use strict'; +import { Observable, Subscriber } from 'rxjs'; +import { getZone } from './utils'; +export function zone(zone) { + return this.lift(new ZoneOperator(zone || getZone())); +} +var ZoneOperator = (function () { + function ZoneOperator(zone) { + this.zone = zone; + } + ZoneOperator.prototype.call = function (subscriber, source) { + return source._subscribe(new ZoneSubscriber(subscriber, this.zone)); + }; + return ZoneOperator; +}()); +var ZoneSubscriber = (function (_super) { + __extends(ZoneSubscriber, _super); + function ZoneSubscriber(destination, zone) { + _super.call(this, destination); + this.zone = zone; + } + ZoneSubscriber.prototype._next = function (value) { + var _this = this; + this.zone.run(function () { + _this.destination.next(value); + }); + }; + ZoneSubscriber.prototype._complete = function () { + var _this = this; + this.zone.run(function () { + _this.destination.complete(); + }); + }; + ZoneSubscriber.prototype._error = function (err) { + var _this = this; + this.zone.run(function () { + _this.destination.error(err); + }); + }; + return ZoneSubscriber; +}(Subscriber)); +Observable.prototype.zone = zone; diff --git a/package.json b/package.json index 013406f5..1f4d9fad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meteor-rxjs", - "version": "0.2.3", + "version": "0.3.0", "description": "Use Meteor API in RxJS style", "keywords": [ "rxjs",