mirror of
https://github.com/zhigang1992/react-native-firebase.git
synced 2026-04-29 20:57:00 +08:00
RN 48 EE backwards compatible fix
This commit is contained in:
@@ -2,8 +2,8 @@
|
|||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import EventEmitter from 'react-native/Libraries/EventEmitter/EventEmitter';
|
|
||||||
import Log from '../utils/log';
|
import Log from '../utils/log';
|
||||||
|
import EventEmitter from './../utils/emitter/EventEmitter';
|
||||||
|
|
||||||
const logs = {};
|
const logs = {};
|
||||||
const SharedEventEmitter = new EventEmitter();
|
const SharedEventEmitter = new EventEmitter();
|
||||||
|
|||||||
61
lib/utils/emitter/EmitterSubscription.js
Normal file
61
lib/utils/emitter/EmitterSubscription.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @noflow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const EventSubscription = require('./EventSubscription');
|
||||||
|
|
||||||
|
import type EventEmitter from './EventEmitter';
|
||||||
|
import type EventSubscriptionVendor from './EventSubscriptionVendor';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EmitterSubscription represents a subscription with listener and context data.
|
||||||
|
*/
|
||||||
|
class EmitterSubscription extends EventSubscription {
|
||||||
|
|
||||||
|
emitter: EventEmitter;
|
||||||
|
listener: Function;
|
||||||
|
context: ?Object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {EventEmitter} emitter - The event emitter that registered this
|
||||||
|
* subscription
|
||||||
|
* @param {EventSubscriptionVendor} subscriber - The subscriber that controls
|
||||||
|
* this subscription
|
||||||
|
* @param {function} listener - Function to invoke when the specified event is
|
||||||
|
* emitted
|
||||||
|
* @param {*} context - Optional context object to use when invoking the
|
||||||
|
* listener
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
emitter: EventEmitter,
|
||||||
|
subscriber: EventSubscriptionVendor,
|
||||||
|
listener: Function,
|
||||||
|
context: ?Object
|
||||||
|
) {
|
||||||
|
super(subscriber);
|
||||||
|
this.emitter = emitter;
|
||||||
|
this.listener = listener;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes this subscription from the emitter that registered it.
|
||||||
|
* Note: we're overriding the `remove()` method of EventSubscription here
|
||||||
|
* but deliberately not calling `super.remove()` as the responsibility
|
||||||
|
* for removing the subscription lies with the EventEmitter.
|
||||||
|
*/
|
||||||
|
remove() {
|
||||||
|
this.emitter.removeSubscription(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = EmitterSubscription;
|
||||||
220
lib/utils/emitter/EventEmitter.js
Normal file
220
lib/utils/emitter/EventEmitter.js
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @noflow
|
||||||
|
* @typecheck
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const EmitterSubscription = require('./EmitterSubscription');
|
||||||
|
const EventSubscriptionVendor = require('./EventSubscriptionVendor');
|
||||||
|
|
||||||
|
const emptyFunction = require('fbjs/lib/emptyFunction');
|
||||||
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class EventEmitter
|
||||||
|
* @description
|
||||||
|
* An EventEmitter is responsible for managing a set of listeners and publishing
|
||||||
|
* events to them when it is told that such events happened. In addition to the
|
||||||
|
* data for the given event it also sends a event control object which allows
|
||||||
|
* the listeners/handlers to prevent the default behavior of the given event.
|
||||||
|
*
|
||||||
|
* The emitter is designed to be generic enough to support all the different
|
||||||
|
* contexts in which one might want to emit events. It is a simple multicast
|
||||||
|
* mechanism on top of which extra functionality can be composed. For example, a
|
||||||
|
* more advanced emitter may use an EventHolder and EventFactory.
|
||||||
|
*/
|
||||||
|
class EventEmitter {
|
||||||
|
|
||||||
|
_subscriber: EventSubscriptionVendor;
|
||||||
|
_currentSubscription: ?EmitterSubscription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
*
|
||||||
|
* @param {EventSubscriptionVendor} subscriber - Optional subscriber instance
|
||||||
|
* to use. If omitted, a new subscriber will be created for the emitter.
|
||||||
|
*/
|
||||||
|
constructor(subscriber: ?EventSubscriptionVendor) {
|
||||||
|
this._subscriber = subscriber || new EventSubscriptionVendor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a listener to be invoked when events of the specified type are
|
||||||
|
* emitted. An optional calling context may be provided. The data arguments
|
||||||
|
* emitted will be passed to the listener function.
|
||||||
|
*
|
||||||
|
* TODO: Annotate the listener arg's type. This is tricky because listeners
|
||||||
|
* can be invoked with varargs.
|
||||||
|
*
|
||||||
|
* @param {string} eventType - Name of the event to listen to
|
||||||
|
* @param {function} listener - Function to invoke when the specified event is
|
||||||
|
* emitted
|
||||||
|
* @param {*} context - Optional context object to use when invoking the
|
||||||
|
* listener
|
||||||
|
*/
|
||||||
|
addListener(
|
||||||
|
eventType: string, listener: Function, context: ?Object): EmitterSubscription {
|
||||||
|
|
||||||
|
return (this._subscriber.addSubscription(
|
||||||
|
eventType,
|
||||||
|
new EmitterSubscription(this, this._subscriber, listener, context)
|
||||||
|
) : any);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Similar to addListener, except that the listener is removed after it is
|
||||||
|
* invoked once.
|
||||||
|
*
|
||||||
|
* @param {string} eventType - Name of the event to listen to
|
||||||
|
* @param {function} listener - Function to invoke only once when the
|
||||||
|
* specified event is emitted
|
||||||
|
* @param {*} context - Optional context object to use when invoking the
|
||||||
|
* listener
|
||||||
|
*/
|
||||||
|
once(eventType: string, listener: Function, context: ?Object): EmitterSubscription {
|
||||||
|
return this.addListener(eventType, (...args) => {
|
||||||
|
this.removeCurrentListener();
|
||||||
|
listener.apply(context, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all of the registered listeners, including those registered as
|
||||||
|
* listener maps.
|
||||||
|
*
|
||||||
|
* @param {?string} eventType - Optional name of the event whose registered
|
||||||
|
* listeners to remove
|
||||||
|
*/
|
||||||
|
removeAllListeners(eventType: ?string) {
|
||||||
|
this._subscriber.removeAllSubscriptions(eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an API that can be called during an eventing cycle to remove the
|
||||||
|
* last listener that was invoked. This allows a developer to provide an event
|
||||||
|
* object that can remove the listener (or listener map) during the
|
||||||
|
* invocation.
|
||||||
|
*
|
||||||
|
* If it is called when not inside of an emitting cycle it will throw.
|
||||||
|
*
|
||||||
|
* @throws {Error} When called not during an eventing cycle
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* var subscription = emitter.addListenerMap({
|
||||||
|
* someEvent: function(data, event) {
|
||||||
|
* console.log(data);
|
||||||
|
* emitter.removeCurrentListener();
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* emitter.emit('someEvent', 'abc'); // logs 'abc'
|
||||||
|
* emitter.emit('someEvent', 'def'); // does not log anything
|
||||||
|
*/
|
||||||
|
removeCurrentListener() {
|
||||||
|
invariant(
|
||||||
|
!!this._currentSubscription,
|
||||||
|
'Not in an emitting cycle; there is no current subscription'
|
||||||
|
);
|
||||||
|
this.removeSubscription(this._currentSubscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a specific subscription. Called by the `remove()` method of the
|
||||||
|
* subscription itself to ensure any necessary cleanup is performed.
|
||||||
|
*/
|
||||||
|
removeSubscription(subscription: EmitterSubscription) {
|
||||||
|
invariant(
|
||||||
|
subscription.emitter === this,
|
||||||
|
'Subscription does not belong to this emitter.'
|
||||||
|
);
|
||||||
|
this._subscriber.removeSubscription(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of listeners that are currently registered for the given
|
||||||
|
* event.
|
||||||
|
*
|
||||||
|
* @param {string} eventType - Name of the event to query
|
||||||
|
* @returns {array}
|
||||||
|
*/
|
||||||
|
listeners(eventType: string): [EmitterSubscription] {
|
||||||
|
const subscriptions: ?[EmitterSubscription] = (this._subscriber.getSubscriptionsForType(eventType): any);
|
||||||
|
return subscriptions
|
||||||
|
? subscriptions.filter(emptyFunction.thatReturnsTrue).map(
|
||||||
|
function(subscription) {
|
||||||
|
return subscription.listener;
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emits an event of the given type with the given data. All handlers of that
|
||||||
|
* particular type will be notified.
|
||||||
|
*
|
||||||
|
* @param {string} eventType - Name of the event to emit
|
||||||
|
* @param {...*} Arbitrary arguments to be passed to each registered listener
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* emitter.addListener('someEvent', function(message) {
|
||||||
|
* console.log(message);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* emitter.emit('someEvent', 'abc'); // logs 'abc'
|
||||||
|
*/
|
||||||
|
emit(eventType: string) {
|
||||||
|
const subscriptions: ?[EmitterSubscription] = (this._subscriber.getSubscriptionsForType(eventType): any);
|
||||||
|
if (subscriptions) {
|
||||||
|
for (let i = 0, l = subscriptions.length; i < l; i++) {
|
||||||
|
const subscription = subscriptions[i];
|
||||||
|
|
||||||
|
// The subscription may have been removed during this event loop.
|
||||||
|
if (subscription) {
|
||||||
|
this._currentSubscription = subscription;
|
||||||
|
subscription.listener.apply(
|
||||||
|
subscription.context,
|
||||||
|
Array.prototype.slice.call(arguments, 1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._currentSubscription = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given listener for event of specific type.
|
||||||
|
*
|
||||||
|
* @param {string} eventType - Name of the event to emit
|
||||||
|
* @param {function} listener - Function to invoke when the specified event is
|
||||||
|
* emitted
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* emitter.removeListener('someEvent', function(message) {
|
||||||
|
* console.log(message);
|
||||||
|
* }); // removes the listener if already registered
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
removeListener(eventType: String, listener) {
|
||||||
|
const subscriptions: ?[EmitterSubscription] = (this._subscriber.getSubscriptionsForType(eventType): any);
|
||||||
|
if (subscriptions) {
|
||||||
|
for (let i = 0, l = subscriptions.length; i < l; i++) {
|
||||||
|
const subscription = subscriptions[i];
|
||||||
|
|
||||||
|
// The subscription may have been removed during this event loop.
|
||||||
|
// its listener matches the listener in method parameters
|
||||||
|
if (subscription && subscription.listener === listener) {
|
||||||
|
subscription.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = EventEmitter;
|
||||||
42
lib/utils/emitter/EventSubscription.js
Normal file
42
lib/utils/emitter/EventSubscription.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import type EventSubscriptionVendor from './EventSubscriptionVendor';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventSubscription represents a subscription to a particular event. It can
|
||||||
|
* remove its own subscription.
|
||||||
|
*/
|
||||||
|
class EventSubscription {
|
||||||
|
|
||||||
|
eventType: string;
|
||||||
|
key: number;
|
||||||
|
subscriber: EventSubscriptionVendor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {EventSubscriptionVendor} subscriber the subscriber that controls
|
||||||
|
* this subscription.
|
||||||
|
*/
|
||||||
|
constructor(subscriber: EventSubscriptionVendor) {
|
||||||
|
this.subscriber = subscriber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes this subscription from the subscriber that controls it.
|
||||||
|
*/
|
||||||
|
remove() {
|
||||||
|
this.subscriber.removeSubscription(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = EventSubscription;
|
||||||
100
lib/utils/emitter/EventSubscriptionVendor.js
Normal file
100
lib/utils/emitter/EventSubscriptionVendor.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2015-present, Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD-style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
|
||||||
|
import type EventSubscription from './EventSubscription';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EventSubscriptionVendor stores a set of EventSubscriptions that are
|
||||||
|
* subscribed to a particular event type.
|
||||||
|
*/
|
||||||
|
class EventSubscriptionVendor {
|
||||||
|
|
||||||
|
_subscriptionsForType: Object;
|
||||||
|
_currentSubscription: ?EventSubscription;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this._subscriptionsForType = {};
|
||||||
|
this._currentSubscription = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a subscription keyed by an event type.
|
||||||
|
*
|
||||||
|
* @param {string} eventType
|
||||||
|
* @param {EventSubscription} subscription
|
||||||
|
*/
|
||||||
|
addSubscription(
|
||||||
|
eventType: string, subscription: EventSubscription): EventSubscription {
|
||||||
|
invariant(
|
||||||
|
subscription.subscriber === this,
|
||||||
|
'The subscriber of the subscription is incorrectly set.');
|
||||||
|
if (!this._subscriptionsForType[eventType]) {
|
||||||
|
this._subscriptionsForType[eventType] = [];
|
||||||
|
}
|
||||||
|
const key = this._subscriptionsForType[eventType].length;
|
||||||
|
this._subscriptionsForType[eventType].push(subscription);
|
||||||
|
subscription.eventType = eventType;
|
||||||
|
subscription.key = key;
|
||||||
|
return subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a bulk set of the subscriptions.
|
||||||
|
*
|
||||||
|
* @param {?string} eventType - Optional name of the event type whose
|
||||||
|
* registered supscriptions to remove, if null remove all subscriptions.
|
||||||
|
*/
|
||||||
|
removeAllSubscriptions(eventType: ?string) {
|
||||||
|
if (eventType === undefined) {
|
||||||
|
this._subscriptionsForType = {};
|
||||||
|
} else {
|
||||||
|
delete this._subscriptionsForType[eventType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a specific subscription. Instead of calling this function, call
|
||||||
|
* `subscription.remove()` directly.
|
||||||
|
*
|
||||||
|
* @param {object} subscription
|
||||||
|
*/
|
||||||
|
removeSubscription(subscription: Object) {
|
||||||
|
const eventType = subscription.eventType;
|
||||||
|
const key = subscription.key;
|
||||||
|
|
||||||
|
const subscriptionsForType = this._subscriptionsForType[eventType];
|
||||||
|
if (subscriptionsForType) {
|
||||||
|
delete subscriptionsForType[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array of subscriptions that are currently registered for the
|
||||||
|
* given event type.
|
||||||
|
*
|
||||||
|
* Note: This array can be potentially sparse as subscriptions are deleted
|
||||||
|
* from it when they are removed.
|
||||||
|
*
|
||||||
|
* TODO: This returns a nullable array. wat?
|
||||||
|
*
|
||||||
|
* @param {string} eventType
|
||||||
|
* @returns {?array}
|
||||||
|
*/
|
||||||
|
getSubscriptionsForType(eventType: string): ?[EventSubscription] {
|
||||||
|
return this._subscriptionsForType[eventType];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = EventSubscriptionVendor;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-firebase",
|
"name": "react-native-firebase",
|
||||||
"version": "2.1.4",
|
"version": "2.2.0",
|
||||||
"author": "Invertase <contact@invertase.io> (http://invertase.io)",
|
"author": "Invertase <contact@invertase.io> (http://invertase.io)",
|
||||||
"description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Auth, Database, Messaging (FCM), Remote Config, Storage, Admob, Analytics, Crash Reporting, and Performance.",
|
"description": "A well tested, feature rich Firebase implementation for React Native, supporting iOS & Android. Individual module support for Auth, Database, Messaging (FCM), Remote Config, Storage, Admob, Analytics, Crash Reporting, and Performance.",
|
||||||
"main": "index",
|
"main": "index",
|
||||||
@@ -54,7 +54,8 @@
|
|||||||
],
|
],
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "*",
|
"react": "*",
|
||||||
"react-native": ">= 0.40.0"
|
"react-native": ">= 0.40.0",
|
||||||
|
"fbjs": "*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-eslint": "^7.0.0",
|
"babel-eslint": "^7.0.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user