typeOf check the actual value - derp
This commit is contained in:
parent
7e8dbcbb35
commit
79bfc7ce09
26
lib/constants.js
Normal file
26
lib/constants.js
Normal file
@ -0,0 +1,26 @@
|
||||
import { reverseKeyValues } from './utils';
|
||||
|
||||
export const ConnectionResult = {
|
||||
SUCCESS: 0,
|
||||
SERVICE_MISSING: 1,
|
||||
SERVICE_VERSION_UPDATE_REQUIRED: 2,
|
||||
SERVICE_DISABLED: 3,
|
||||
SIGN_IN_REQUIRED: 4,
|
||||
INVALID_ACCOUNT: 5,
|
||||
RESOLUTION_REQUIRED: 6,
|
||||
NETWORK_ERROR: 7,
|
||||
INTERNAL_ERROR: 8,
|
||||
SERVICE_INVALID: 9,
|
||||
DEVELOPER_ERROR: 10,
|
||||
LICENSE_CHECK_FAILED: 11,
|
||||
CANCELED: 13,
|
||||
TIMEOUT: 14,
|
||||
INTERRUPTED: 15,
|
||||
API_UNAVAILABLE: 16,
|
||||
SIGN_IN_FAILED: 17,
|
||||
SERVICE_UPDATING: 18,
|
||||
SERVICE_MISSING_PERMISSION: 19,
|
||||
RESTRICTED_PROFILE: 20,
|
||||
};
|
||||
|
||||
export const ConnectionResultReverse = reverseKeyValues(ConnectionResult);
|
225
lib/firebase.js
Normal file
225
lib/firebase.js
Normal file
@ -0,0 +1,225 @@
|
||||
/**
|
||||
* @providesModule Firebase
|
||||
* @flow
|
||||
*/
|
||||
import { NativeModules, NativeEventEmitter } from 'react-native';
|
||||
|
||||
import Log from './utils/log';
|
||||
import { promisify } from './utils';
|
||||
import Singleton from './utils/singleton';
|
||||
|
||||
// modules
|
||||
import Auth from './modules/auth';
|
||||
import Storage from './modules/storage';
|
||||
import Database from './modules/database';
|
||||
import Messaging from './modules/messaging';
|
||||
import Analytics from './modules/analytics';
|
||||
|
||||
let log;
|
||||
const instances = { default: null };
|
||||
const FirebaseModule = NativeModules.RNFirebase;
|
||||
const FirebaseModuleEvt = new NativeEventEmitter(FirebaseModule);
|
||||
|
||||
/**
|
||||
* @class Firebase
|
||||
*/
|
||||
export default class Firebase extends Singleton {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
constructor(options: Object = {}) {
|
||||
const instance = super(options);
|
||||
|
||||
instance.options = Object.assign({ errorOnMissingPlayServices: true }, options);
|
||||
instance._debug = instance.options.debug || false;
|
||||
|
||||
Log.enable(instance._debug);
|
||||
log = instance._log = new Log('firebase');
|
||||
|
||||
log.info('Creating new firebase instance');
|
||||
|
||||
instance._remoteConfig = instance.options.remoteConfig || {};
|
||||
delete instance.options.remoteConfig;
|
||||
|
||||
instance.configured = instance.options.configure || false;
|
||||
|
||||
instance.eventHandlers = {};
|
||||
|
||||
log.info('Calling configure with options', instance.options);
|
||||
instance.configurePromise = instance.configure(instance.options);
|
||||
|
||||
instance._auth = new Auth(instance, instance.options);
|
||||
|
||||
if (instance.options.errorOnMissingPlayServices && !this.googleApiAvailability.isAvailable) {
|
||||
throw new Error(`Google Play Services is required to run this application but no valid installation was found (Code ${this.googleApiAvailability.status}).`);
|
||||
}
|
||||
}
|
||||
|
||||
_db: ?Object;
|
||||
_log: ?Object;
|
||||
_auth: ?Object;
|
||||
_store: ?Object;
|
||||
_storage: ?Object;
|
||||
_presence: ?Object;
|
||||
_analytics: ?Object;
|
||||
_constants: ?Object;
|
||||
_messaging: ?Object;
|
||||
_remoteConfig: ?Object;
|
||||
|
||||
/**
|
||||
* Support web version of initApp.
|
||||
* @param options
|
||||
* @param name
|
||||
* @returns {*}
|
||||
*/
|
||||
static initializeApp(options: Object = {}, name: string = 'default') {
|
||||
if (!instances[name]) instances[name] = new Firebase(options);
|
||||
return instances[name];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param opts
|
||||
* @returns {Promise.<TResult>|*|Promise.<T>}
|
||||
*/
|
||||
configure(opts: Object = {}) {
|
||||
if (!this.configurePromise) {
|
||||
const firebaseOptions = Object.assign({}, this.options, opts);
|
||||
|
||||
this.configurePromise = promisify('configureWithOptions', FirebaseModule)(firebaseOptions)
|
||||
.then((configuredProperties) => {
|
||||
log.info('Native configureWithOptions success', configuredProperties);
|
||||
this.configured = true;
|
||||
this.firebaseOptions = configuredProperties;
|
||||
return configuredProperties;
|
||||
}).catch((err) => {
|
||||
log.info('Native error occurred while calling configure', err);
|
||||
});
|
||||
}
|
||||
return this.configurePromise;
|
||||
}
|
||||
|
||||
onReady(cb: Function) {
|
||||
// TODO wut o.O
|
||||
return this.configurePromise = this.configurePromise.then(cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrappers
|
||||
* We add methods from each wrapper to this instance
|
||||
* when they are needed. Not sure if this is a good
|
||||
* idea or not (imperative vs. direct manipulation/proxy)
|
||||
*/
|
||||
auth() {
|
||||
return this._auth;
|
||||
}
|
||||
|
||||
|
||||
database() {
|
||||
if (!this._db) {
|
||||
this._db = new Database(this);
|
||||
}
|
||||
return this._db;
|
||||
}
|
||||
|
||||
|
||||
analytics() {
|
||||
if (!this._analytics) {
|
||||
this._analytics = new Analytics(this);
|
||||
}
|
||||
return this._analytics;
|
||||
}
|
||||
|
||||
// storage
|
||||
storage() {
|
||||
if (!this._storage) {
|
||||
this._storage = new Storage(this);
|
||||
}
|
||||
return this._storage;
|
||||
}
|
||||
|
||||
messaging() {
|
||||
if (!this._messaging) {
|
||||
this._messaging = new Messaging(this);
|
||||
}
|
||||
return this._messaging;
|
||||
}
|
||||
|
||||
remoteConfig() {
|
||||
if (!this._remoteConfig) {
|
||||
this._remoteConfig = new RemoteConfig(this);
|
||||
}
|
||||
return this._remoteConfig;
|
||||
}
|
||||
|
||||
get ServerValue(): Promise<*> {
|
||||
return promisify('serverValue', FirebaseModule)();
|
||||
}
|
||||
|
||||
get apps(): Array<string> {
|
||||
return Object.keys(instances);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns androids GoogleApiAvailability status and message if available.
|
||||
* @returns {GoogleApiAvailabilityType|{isAvailable: boolean, status: number}}
|
||||
*/
|
||||
get googleApiAvailability(): GoogleApiAvailabilityType {
|
||||
// if not available then return a fake object for ios - saves doing platform specific logic.
|
||||
return FirebaseModule.googleApiAvailability || { isAvailable: true, status: 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
get log(): Log {
|
||||
return this._log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redux store
|
||||
**/
|
||||
get store(): ?Object {
|
||||
return this._store;
|
||||
}
|
||||
|
||||
get constants(): Object {
|
||||
if (!this._constants) {
|
||||
this._constants = Object.assign({}, Storage.constants);
|
||||
}
|
||||
return this._constants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the redux store helper
|
||||
*/
|
||||
setStore(store: Object) {
|
||||
if (store) {
|
||||
this.log.info('Setting the store for Firebase instance');
|
||||
this._store = store;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Global event handlers for the single Firebase instance
|
||||
*/
|
||||
on(name: string, cb: Function, nativeModule: Object = FirebaseModuleEvt) {
|
||||
if (!this.eventHandlers[name]) {
|
||||
this.eventHandlers[name] = [];
|
||||
}
|
||||
|
||||
const sub = nativeModule.addListener(name, cb);
|
||||
this.eventHandlers[name].push(sub);
|
||||
return sub;
|
||||
}
|
||||
|
||||
off(name: string) {
|
||||
if (this.eventHandlers[name]) {
|
||||
this.eventHandlers[name]
|
||||
.forEach(subscription => subscription.remove());
|
||||
}
|
||||
}
|
||||
}
|
23
lib/flow.js
Normal file
23
lib/flow.js
Normal file
@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
declare module 'react-native' {
|
||||
// noinspection ES6ConvertVarToLetConst
|
||||
declare var exports: any;
|
||||
}
|
||||
|
||||
declare type AuthResultType = {
|
||||
authenticated: boolean,
|
||||
user: Object|null
|
||||
};
|
||||
|
||||
declare type CredentialType = {
|
||||
provider: string,
|
||||
token: string,
|
||||
secret: string
|
||||
};
|
||||
|
||||
declare type GoogleApiAvailabilityType = {
|
||||
status: number,
|
||||
isAvailable: boolean,
|
||||
isUserResolvableError?: boolean,
|
||||
error?: string
|
||||
};
|
79
lib/modules/base.js
Normal file
79
lib/modules/base.js
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
import { NativeModules, NativeEventEmitter } from 'react-native';
|
||||
|
||||
import Log from '../utils/log';
|
||||
import EventEmitter from './../utils/eventEmitter';
|
||||
|
||||
const FirebaseModule = NativeModules.RNFirebase;
|
||||
const FirebaseModuleEvt = new NativeEventEmitter(FirebaseModule);
|
||||
|
||||
const logs = {};
|
||||
|
||||
type FirebaseOptions = {};
|
||||
|
||||
// TODO cleanup
|
||||
export class Base extends EventEmitter {
|
||||
constructor(firebase: Object, options: FirebaseOptions = {}) {
|
||||
super();
|
||||
this.firebase = firebase;
|
||||
this.eventHandlers = {};
|
||||
this.options = Object.assign({}, firebase.options, options);
|
||||
}
|
||||
|
||||
// Logger
|
||||
get log(): Log {
|
||||
if (!logs[this.namespace]) logs[this.namespace] = new Log(this.namespace, this.firebase._debug);
|
||||
return logs[this.namespace];
|
||||
}
|
||||
|
||||
/**
|
||||
* app instance
|
||||
**/
|
||||
get app(): Object {
|
||||
return this.firebase.app;
|
||||
}
|
||||
|
||||
whenReady(promise: Promise<*>): Promise<*> {
|
||||
return this.firebase.configurePromise.then(() => promise);
|
||||
}
|
||||
|
||||
// Event handlers
|
||||
// proxy to firebase instance
|
||||
_on(name, cb, nativeModule) {
|
||||
return new Promise((resolve) => {
|
||||
// if (!this.eventHandlers[name]) {
|
||||
// this.eventHandlers[name] = {};
|
||||
// }
|
||||
if (!nativeModule) {
|
||||
nativeModule = FirebaseModuleEvt;
|
||||
}
|
||||
const sub = nativeModule.addListener(name, cb);
|
||||
this.eventHandlers[name] = sub;
|
||||
resolve(sub);
|
||||
});
|
||||
}
|
||||
|
||||
_off(name) {
|
||||
return new Promise((resolve) => {
|
||||
if (this.eventHandlers[name]) {
|
||||
const subscription = this.eventHandlers[name];
|
||||
subscription.remove(); // Remove subscription
|
||||
delete this.eventHandlers[name];
|
||||
resolve(subscription);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class ReferenceBase extends Base {
|
||||
constructor(firebase: Object, path: string) {
|
||||
super(firebase);
|
||||
this.path = path || '/';
|
||||
}
|
||||
|
||||
get key(): string|null {
|
||||
return this.path === '/' ? null : this.path.substring(this.path.lastIndexOf('/') + 1);
|
||||
}
|
||||
}
|
313
lib/utils/eventEmitter.js
Normal file
313
lib/utils/eventEmitter.js
Normal file
@ -0,0 +1,313 @@
|
||||
// TODO - this is just a raw copy of eventEmitter3 - until i can implement a lightweight version
|
||||
|
||||
'use strict';
|
||||
|
||||
var has = Object.prototype.hasOwnProperty
|
||||
, prefix = '~';
|
||||
|
||||
/**
|
||||
* Constructor to create a storage for our `EE` objects.
|
||||
* An `Events` instance is a plain object whose properties are event names.
|
||||
*
|
||||
* @constructor
|
||||
* @api private
|
||||
*/
|
||||
function Events() {}
|
||||
|
||||
//
|
||||
// We try to not inherit from `Object.prototype`. In some engines creating an
|
||||
// instance in this way is faster than calling `Object.create(null)` directly.
|
||||
// If `Object.create(null)` is not supported we prefix the event names with a
|
||||
// character to make sure that the built-in object properties are not
|
||||
// overridden or used as an attack vector.
|
||||
//
|
||||
if (Object.create) {
|
||||
Events.prototype = Object.create(null);
|
||||
|
||||
//
|
||||
// This hack is needed because the `__proto__` property is still inherited in
|
||||
// some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
|
||||
//
|
||||
if (!new Events().__proto__) prefix = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of a single event listener.
|
||||
*
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {Mixed} context The context to invoke the listener with.
|
||||
* @param {Boolean} [once=false] Specify if the listener is a one-time listener.
|
||||
* @constructor
|
||||
* @api private
|
||||
*/
|
||||
function EE(fn, context, once) {
|
||||
this.fn = fn;
|
||||
this.context = context;
|
||||
this.once = once || false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimal `EventEmitter` interface that is molded against the Node.js
|
||||
* `EventEmitter` interface.
|
||||
*
|
||||
* @constructor
|
||||
* @api public
|
||||
*/
|
||||
function EventEmitter() {
|
||||
this._events = new Events();
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array listing the events for which the emitter has registered
|
||||
* listeners.
|
||||
*
|
||||
* @returns {Array}
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.eventNames = function eventNames() {
|
||||
var names = []
|
||||
, events
|
||||
, name;
|
||||
|
||||
if (this._eventsCount === 0) return names;
|
||||
|
||||
for (name in (events = this._events)) {
|
||||
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertySymbols) {
|
||||
return names.concat(Object.getOwnPropertySymbols(events));
|
||||
}
|
||||
|
||||
return names;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the listeners registered for a given event.
|
||||
*
|
||||
* @param {String|Symbol} event The event name.
|
||||
* @param {Boolean} exists Only check if there are listeners.
|
||||
* @returns {Array|Boolean}
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.listeners = function listeners(event, exists) {
|
||||
var evt = prefix ? prefix + event : event
|
||||
, available = this._events[evt];
|
||||
|
||||
if (exists) return !!available;
|
||||
if (!available) return [];
|
||||
if (available.fn) return [available.fn];
|
||||
|
||||
for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
|
||||
ee[i] = available[i].fn;
|
||||
}
|
||||
|
||||
return ee;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls each of the listeners registered for a given event.
|
||||
*
|
||||
* @param {String|Symbol} event The event name.
|
||||
* @returns {Boolean} `true` if the event had listeners, else `false`.
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
|
||||
var evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) return false;
|
||||
|
||||
var listeners = this._events[evt]
|
||||
, len = arguments.length
|
||||
, args
|
||||
, i;
|
||||
|
||||
if (listeners.fn) {
|
||||
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
|
||||
|
||||
switch (len) {
|
||||
case 1: return listeners.fn.call(listeners.context), true;
|
||||
case 2: return listeners.fn.call(listeners.context, a1), true;
|
||||
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
|
||||
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
|
||||
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
|
||||
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
|
||||
}
|
||||
|
||||
for (i = 1, args = new Array(len -1); i < len; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
|
||||
listeners.fn.apply(listeners.context, args);
|
||||
} else {
|
||||
var length = listeners.length
|
||||
, j;
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
|
||||
|
||||
switch (len) {
|
||||
case 1: listeners[i].fn.call(listeners[i].context); break;
|
||||
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
|
||||
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
|
||||
case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
|
||||
default:
|
||||
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
|
||||
args[j - 1] = arguments[j];
|
||||
}
|
||||
|
||||
listeners[i].fn.apply(listeners[i].context, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a listener for a given event.
|
||||
*
|
||||
* @param {String|Symbol} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {Mixed} [context=this] The context to invoke the listener with.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.on = function on(event, fn, context) {
|
||||
var listener = new EE(fn, context || this)
|
||||
, evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;
|
||||
else if (!this._events[evt].fn) this._events[evt].push(listener);
|
||||
else this._events[evt] = [this._events[evt], listener];
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a one-time listener for a given event.
|
||||
*
|
||||
* @param {String|Symbol} event The event name.
|
||||
* @param {Function} fn The listener function.
|
||||
* @param {Mixed} [context=this] The context to invoke the listener with.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.once = function once(event, fn, context) {
|
||||
var listener = new EE(fn, context || this, true)
|
||||
, evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;
|
||||
else if (!this._events[evt].fn) this._events[evt].push(listener);
|
||||
else this._events[evt] = [this._events[evt], listener];
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the listeners of a given event.
|
||||
*
|
||||
* @param {String|Symbol} event The event name.
|
||||
* @param {Function} fn Only remove the listeners that match this function.
|
||||
* @param {Mixed} context Only remove the listeners that have this context.
|
||||
* @param {Boolean} once Only remove one-time listeners.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
|
||||
var evt = prefix ? prefix + event : event;
|
||||
|
||||
if (!this._events[evt]) return this;
|
||||
if (!fn) {
|
||||
if (--this._eventsCount === 0) this._events = new Events();
|
||||
else delete this._events[evt];
|
||||
return this;
|
||||
}
|
||||
|
||||
var listeners = this._events[evt];
|
||||
|
||||
if (listeners.fn) {
|
||||
if (
|
||||
listeners.fn === fn
|
||||
&& (!once || listeners.once)
|
||||
&& (!context || listeners.context === context)
|
||||
) {
|
||||
if (--this._eventsCount === 0) this._events = new Events();
|
||||
else delete this._events[evt];
|
||||
}
|
||||
} else {
|
||||
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
|
||||
if (
|
||||
listeners[i].fn !== fn
|
||||
|| (once && !listeners[i].once)
|
||||
|| (context && listeners[i].context !== context)
|
||||
) {
|
||||
events.push(listeners[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Reset the array, or remove it completely if we have no more listeners.
|
||||
//
|
||||
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
|
||||
else if (--this._eventsCount === 0) this._events = new Events();
|
||||
else delete this._events[evt];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all listeners, or those of the specified event.
|
||||
*
|
||||
* @param {String|Symbol} [event] The event name.
|
||||
* @returns {EventEmitter} `this`.
|
||||
* @api public
|
||||
*/
|
||||
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
|
||||
var evt;
|
||||
|
||||
if (event) {
|
||||
evt = prefix ? prefix + event : event;
|
||||
if (this._events[evt]) {
|
||||
if (--this._eventsCount === 0) this._events = new Events();
|
||||
else delete this._events[evt];
|
||||
}
|
||||
} else {
|
||||
this._events = new Events();
|
||||
this._eventsCount = 0;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// Alias methods names because people roll like that.
|
||||
//
|
||||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||||
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
|
||||
|
||||
//
|
||||
// This function doesn't apply anymore.
|
||||
//
|
||||
EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
|
||||
return this;
|
||||
};
|
||||
|
||||
//
|
||||
// Expose the prefix.
|
||||
//
|
||||
EventEmitter.prefixed = prefix;
|
||||
|
||||
//
|
||||
// Allow `EventEmitter` to be imported as module namespace.
|
||||
//
|
||||
EventEmitter.EventEmitter = EventEmitter;
|
||||
|
||||
//
|
||||
// Expose the module.
|
||||
//
|
||||
if ('undefined' !== typeof module) {
|
||||
module.exports = EventEmitter;
|
||||
}
|
40
lib/utils/log.js
Normal file
40
lib/utils/log.js
Normal file
@ -0,0 +1,40 @@
|
||||
import { windowOrGlobal } from './';
|
||||
|
||||
((base) => {
|
||||
window = base || window;
|
||||
if (!window.localStorage) window.localStorage = {};
|
||||
})(windowOrGlobal);
|
||||
|
||||
export default class Log {
|
||||
constructor(namespace) {
|
||||
this._namespace = namespace || 'RNFirebase';
|
||||
require('bows').config({ padLength: 20 });
|
||||
this.loggers = {};
|
||||
}
|
||||
|
||||
get warn() {
|
||||
return this._createOrGetLogger('warn');
|
||||
}
|
||||
|
||||
get info() {
|
||||
return this._createOrGetLogger('info');
|
||||
}
|
||||
|
||||
get error() {
|
||||
return this._createOrGetLogger('error');
|
||||
}
|
||||
|
||||
get debug() {
|
||||
return this._createOrGetLogger('debug');
|
||||
}
|
||||
|
||||
static enable(booleanOrStringDebug) {
|
||||
window.localStorage.debug = booleanOrStringDebug;
|
||||
window.localStorage.debugColors = !!window.localStorage.debug;
|
||||
}
|
||||
|
||||
_createOrGetLogger(level) {
|
||||
if (!this.loggers[level]) this.loggers[level] = require('bows')(this._namespace, `[${level}]`);
|
||||
return this.loggers[level];
|
||||
}
|
||||
}
|
35
lib/utils/singleton.js
Normal file
35
lib/utils/singleton.js
Normal file
@ -0,0 +1,35 @@
|
||||
const Symbol = require('es6-symbol');
|
||||
|
||||
class Singleton {
|
||||
constructor() {
|
||||
const Class = this.constructor;
|
||||
if (!Class[this.singleton]) {
|
||||
Class[this.singleton] = this;
|
||||
}
|
||||
|
||||
return Class[this.singleton];
|
||||
}
|
||||
|
||||
static get instance() {
|
||||
if (!this[this.singleton]) {
|
||||
this[this.singleton] = new this();
|
||||
}
|
||||
|
||||
return this[this.singleton];
|
||||
}
|
||||
|
||||
static set instance(instance) {
|
||||
this[this.singleton] = instance;
|
||||
return this[this.singleton];
|
||||
}
|
||||
|
||||
static get singleton() {
|
||||
return Symbol(this.namespace);
|
||||
}
|
||||
|
||||
static reset() {
|
||||
delete this[this.singleton];
|
||||
}
|
||||
}
|
||||
|
||||
export default Singleton;
|
Loading…
x
Reference in New Issue
Block a user