2
0
mirror of synced 2025-02-17 08:46:43 +00:00

[database][wip] update reference to support 'ThenableReference'

This commit is contained in:
Salakar 2017-07-31 18:25:31 +01:00
parent 7fc40a2740
commit c9efb0087f

View File

@ -52,19 +52,19 @@ const ReferenceEventTypes = {
*/ */
export default class Reference extends ReferenceBase { export default class Reference extends ReferenceBase {
refId: number; _refId: number;
refListeners: { [listenerId: number]: DatabaseListener }; _refListeners: { [listenerId: number]: DatabaseListener };
database: Object; _database: Object;
query: Query; _query: Query;
constructor(database: Object, path: string, existingModifiers?: Array<DatabaseModifier>) { constructor(database: Object, path: string, existingModifiers?: Array<DatabaseModifier>) {
super(path, database); super(path, database);
this.refId = refId++; this._promise = null;
this.refListeners = {}; this._refId = refId++;
this.database = database; this._refListeners = {};
this.namespace = 'firebase:db:ref'; this._database = database;
this.query = new Query(this, path, existingModifiers); this._query = new Query(this, path, existingModifiers);
// TODO this.log.debug('Created new Reference', this.refId, this.path); // TODO this.log.debug('Created new Reference', this._refId, this.path);
} }
/** /**
@ -73,7 +73,7 @@ export default class Reference extends ReferenceBase {
* @returns {*} * @returns {*}
*/ */
keepSynced(bool: boolean) { keepSynced(bool: boolean) {
return this.database._native.keepSynced(this.path, bool); return this._database._native.keepSynced(this.path, bool);
} }
/** /**
@ -82,7 +82,7 @@ export default class Reference extends ReferenceBase {
* @returns {*} * @returns {*}
*/ */
set(value: any) { set(value: any) {
return this.database._native.set(this.path, this._serializeAnyType(value)); return this._database._native.set(this.path, this._serializeAnyType(value));
} }
/** /**
@ -92,7 +92,7 @@ export default class Reference extends ReferenceBase {
*/ */
setPriority(priority: string | number | null) { setPriority(priority: string | number | null) {
const _priority = this._serializeAnyType(priority); const _priority = this._serializeAnyType(priority);
return this.database._native.setPriority(this.path, _priority); return this._database._native.setPriority(this.path, _priority);
} }
/** /**
@ -104,7 +104,7 @@ export default class Reference extends ReferenceBase {
setWithPriority(value: any, priority: string | number | null) { setWithPriority(value: any, priority: string | number | null) {
const _value = this._serializeAnyType(value); const _value = this._serializeAnyType(value);
const _priority = this._serializeAnyType(priority); const _priority = this._serializeAnyType(priority);
return this.database._native.setWithPriority(this.path, _value, _priority); return this._database._native.setWithPriority(this.path, _value, _priority);
} }
/** /**
@ -114,7 +114,7 @@ export default class Reference extends ReferenceBase {
*/ */
update(val: Object) { update(val: Object) {
const value = this._serializeObject(val); const value = this._serializeObject(val);
return this.database._native.update(this.path, value); return this._database._native.update(this.path, value);
} }
/** /**
@ -122,7 +122,7 @@ export default class Reference extends ReferenceBase {
* @returns {*} * @returns {*}
*/ */
remove() { remove() {
return this.database._native.remove(this.path); return this._database._native.remove(this.path);
} }
/** /**
@ -158,7 +158,7 @@ export default class Reference extends ReferenceBase {
return resolve({ committed, snapshot }); return resolve({ committed, snapshot });
}; };
this.database._transactionHandler.add(this, transactionUpdate, onCompleteWrapper, applyLocally); this._database._transactionHandler.add(this, transactionUpdate, onCompleteWrapper, applyLocally);
}); });
} }
@ -172,7 +172,7 @@ export default class Reference extends ReferenceBase {
* @returns {Promise.<any>} * @returns {Promise.<any>}
*/ */
once(eventName: string = 'value', successCallback: (snapshot: Object) => void, failureCallback: (error: FirebaseError) => void) { once(eventName: string = 'value', successCallback: (snapshot: Object) => void, failureCallback: (error: FirebaseError) => void) {
return this.database._native.once(this.refId, this.path, this.query.getModifiers(), eventName) return this._database._native.once(this._refId, this.path, this._query.getModifiers(), eventName)
.then(({ snapshot }) => new Snapshot(this, snapshot)) .then(({ snapshot }) => new Snapshot(this, snapshot))
.then((snapshot) => { .then((snapshot) => {
if (isFunction(successCallback)) successCallback(snapshot); if (isFunction(successCallback)) successCallback(snapshot);
@ -192,10 +192,10 @@ export default class Reference extends ReferenceBase {
*/ */
push(value: any, onComplete: Function) { push(value: any, onComplete: Function) {
if (value === null || value === undefined) { if (value === null || value === undefined) {
return new Reference(this.database, `${this.path}/${generatePushID(this.database.serverTimeOffset)}`); return new Reference(this._database, `${this.path}/${generatePushID(this._database.serverTimeOffset)}`);
} }
const newRef = new Reference(this.database, `${this.path}/${generatePushID(this.database.serverTimeOffset)}`); const newRef = new Reference(this._database, `${this.path}/${generatePushID(this._database.serverTimeOffset)}`);
const promise = newRef.set(value); const promise = newRef.set(value);
// todo 'ThenableReference' // todo 'ThenableReference'
@ -253,7 +253,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference} * @returns {Reference}
*/ */
orderBy(name: string, key?: string): Reference { orderBy(name: string, key?: string): Reference {
const newRef = new Reference(this.database, this.path, this.query.getModifiers()); const newRef = new Reference(this._database, this.path, this._query.getModifiers());
newRef.query.orderBy(name, key); newRef.query.orderBy(name, key);
return newRef; return newRef;
} }
@ -287,7 +287,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference} * @returns {Reference}
*/ */
limit(name: string, limit: number): Reference { limit(name: string, limit: number): Reference {
const newRef = new Reference(this.database, this.path, this.query.getModifiers()); const newRef = new Reference(this._database, this.path, this._query.getModifiers());
newRef.query.limit(name, limit); newRef.query.limit(name, limit);
return newRef; return newRef;
} }
@ -334,7 +334,7 @@ export default class Reference extends ReferenceBase {
* @returns {Reference} * @returns {Reference}
*/ */
filter(name: string, value: any, key?: string): Reference { filter(name: string, value: any, key?: string): Reference {
const newRef = new Reference(this.database, this.path, this.query.getModifiers()); const newRef = new Reference(this._database, this.path, this._query.getModifiers());
newRef.query.filter(name, value, key); newRef.query.filter(name, value, key);
return newRef; return newRef;
} }
@ -356,7 +356,7 @@ export default class Reference extends ReferenceBase {
* {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#child} * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#child}
*/ */
child(path: string) { child(path: string) {
return new Reference(this.database, `${this.path}/${path}`); return new Reference(this._database, `${this.path}/${path}`);
} }
/** /**
@ -391,7 +391,7 @@ export default class Reference extends ReferenceBase {
*/ */
get parent(): Reference | null { get parent(): Reference | null {
if (this.path === '/') return null; if (this.path === '/') return null;
return new Reference(this.database, this.path.substring(0, this.path.lastIndexOf('/'))); return new Reference(this._database, this.path.substring(0, this.path.lastIndexOf('/')));
} }
/** /**
@ -411,13 +411,50 @@ export default class Reference extends ReferenceBase {
* {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#root} * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#root}
*/ */
get root(): Reference { get root(): Reference {
return new Reference(this.database, '/'); return new Reference(this._database, '/');
}
/**
* Access then method of promise if set
* @return {*}
*/
get then() {
if (this._promise && this._promise.then) {
return this._promise.then.bind(this._promise);
}
return undefined;
}
/**
* Access catch method of promise if set
* @return {*}
*/
get catch() {
if (this._promise && this._promise.catch) {
return this._promise.catch.bind(this._promise);
}
return undefined;
} }
/** /**
* INTERNALS * INTERNALS
*/ */
get log() {
return this._database.log;
}
/**
* Set the promise this 'thenable' reference relates to
* @param promise
* @private
*/
_setThenable(promise) {
this._promise = promise;
}
/** /**
* *
@ -572,7 +609,7 @@ export default class Reference extends ReferenceBase {
if (!isFunction(successCallback)) throw new Error('Query.on failed: Second argument must be a valid function.'); if (!isFunction(successCallback)) throw new Error('Query.on failed: Second argument must be a valid function.');
if (arguments.length > 2 && !failureCallbackOrContext) throw new Error('Query.on failed: third argument must either be a cancel callback or a context object.'); if (arguments.length > 2 && !failureCallbackOrContext) throw new Error('Query.on failed: third argument must either be a cancel callback or a context object.');
// TODO this.log.debug('adding reference.on', this.refId, eventType); // TODO this.log.debug('adding reference.on', this._refId, eventType);
let _failureCallback; let _failureCallback;
let _context; let _context;
@ -605,14 +642,14 @@ export default class Reference extends ReferenceBase {
} }
const listener = { const listener = {
listenerId: Object.keys(this.refListeners).length + 1, listenerId: Object.keys(this._refListeners).length + 1,
eventName: eventType, eventName: eventType,
successCallback: _successCallback, successCallback: _successCallback,
failureCallback: _failureCallback, failureCallback: _failureCallback,
}; };
this.refListeners[listener.listenerId] = listener; this._refListeners[listener.listenerId] = listener;
this.database.on(this, listener); this._database.on(this, listener);
return successCallback; return successCallback;
} }
@ -643,9 +680,9 @@ export default class Reference extends ReferenceBase {
* {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#off} * {@link https://firebase.google.com/docs/reference/js/firebase.database.Reference#off}
*/ */
off(eventType?: string = '', originalCallback?: () => any) { off(eventType?: string = '', originalCallback?: () => any) {
// TODO this.log.debug('ref.off(): ', this.refId, eventType); // TODO this.log.debug('ref.off(): ', this._refId, eventType);
// $FlowFixMe // $FlowFixMe
const listeners: Array<DatabaseListener> = Object.values(this.refListeners); const listeners: Array<DatabaseListener> = Object.values(this._refListeners);
let listenersToRemove; let listenersToRemove;
if (eventType && originalCallback) { if (eventType && originalCallback) {
listenersToRemove = listeners.filter((listener) => { listenersToRemove = listeners.filter((listener) => {
@ -666,9 +703,9 @@ export default class Reference extends ReferenceBase {
} }
// Remove the listeners from the reference to prevent memory leaks // Remove the listeners from the reference to prevent memory leaks
listenersToRemove.forEach((listener) => { listenersToRemove.forEach((listener) => {
delete this.refListeners[listener.listenerId]; delete this._refListeners[listener.listenerId];
}); });
return this.database.off(this.refId, listenersToRemove, Object.keys(this.refListeners).length); return this._database.off(this._refId, listenersToRemove, Object.keys(this._refListeners).length);
} }