/**
* @file Helper class for constructing {@link Tinode.GetQuery}.
*
* @copyright 2015-2022 Tinode LLC.
*/
'use strict';
/**
* Helper class for constructing {@link Tinode.GetQuery}.
*
* @class MetaGetBuilder
* @memberof Tinode
*
* @param {Tinode.Topic} parent topic which instantiated this builder.
*/
export default class MetaGetBuilder {
constructor(parent) {
this.topic = parent;
this.what = {};
}
// Get timestamp of the most recent desc update.
#get_desc_ims() {
return this.topic.updated;
}
// Get timestamp of the most recent subs update.
#get_subs_ims() {
if (this.topic.isP2PType()) {
return this.#get_desc_ims();
}
return this.topic._lastSubsUpdate;
}
/**
* Add query parameters to fetch messages within explicit limits.
* @memberof Tinode.MetaGetBuilder#
*
* @param {number=} since - messages newer than this (inclusive);
* @param {number=} before - older than this (exclusive)
* @param {number=} limit - number of messages to fetch
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withData(since, before, limit) {
this.what['data'] = {
since: since,
before: before,
limit: limit
};
return this;
}
/**
* Add query parameters to fetch messages newer than the latest saved message.
* @memberof Tinode.MetaGetBuilder#
*
* @param {number=} limit - number of messages to fetch
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withLaterData(limit) {
return this.withData(this.topic._maxSeq > 0 ? this.topic._maxSeq + 1 : undefined, undefined, limit);
}
/**
* Add query parameters to fetch messages older than the earliest saved message.
* @memberof Tinode.MetaGetBuilder#
*
* @param {number=} limit - maximum number of messages to fetch.
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withEarlierData(limit) {
return this.withData(undefined, this.topic._minSeq > 0 ? this.topic._minSeq : undefined, limit);
}
/**
* Add query parameters to fetch topic description if it's newer than the given timestamp.
* @memberof Tinode.MetaGetBuilder#
*
* @param {Date=} ims - fetch messages newer than this timestamp.
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withDesc(ims) {
this.what['desc'] = {
ims: ims
};
return this;
}
/**
* Add query parameters to fetch topic description if it's newer than the last update.
* @memberof Tinode.MetaGetBuilder#
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withLaterDesc() {
return this.withDesc(this.#get_desc_ims());
}
/**
* Add query parameters to fetch subscriptions.
* @memberof Tinode.MetaGetBuilder#
*
* @param {Date=} ims - fetch subscriptions modified more recently than this timestamp
* @param {number=} limit - maximum number of subscriptions to fetch.
* @param {string=} userOrTopic - user ID or topic name to fetch for fetching one subscription.
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withSub(ims, limit, userOrTopic) {
const opts = {
ims: ims,
limit: limit
};
if (this.topic.getType() == 'me') {
opts.topic = userOrTopic;
} else {
opts.user = userOrTopic;
}
this.what['sub'] = opts;
return this;
}
/**
* Add query parameters to fetch a single subscription.
* @memberof Tinode.MetaGetBuilder#
*
* @param {Date=} ims - fetch subscriptions modified more recently than this timestamp
* @param {string=} userOrTopic - user ID or topic name to fetch for fetching one subscription.
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withOneSub(ims, userOrTopic) {
return this.withSub(ims, undefined, userOrTopic);
}
/**
* Add query parameters to fetch a single subscription if it's been updated since the last update.
* @memberof Tinode.MetaGetBuilder#
*
* @param {string=} userOrTopic - user ID or topic name to fetch for fetching one subscription.
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withLaterOneSub(userOrTopic) {
return this.withOneSub(this.topic._lastSubsUpdate, userOrTopic);
}
/**
* Add query parameters to fetch subscriptions updated since the last update.
* @memberof Tinode.MetaGetBuilder#
*
* @param {number=} limit - maximum number of subscriptions to fetch.
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withLaterSub(limit) {
return this.withSub(this.#get_subs_ims(), limit);
}
/**
* Add query parameters to fetch topic tags.
* @memberof Tinode.MetaGetBuilder#
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withTags() {
this.what['tags'] = true;
return this;
}
/**
* Add query parameters to fetch user's credentials. <code>'me'</code> topic only.
* @memberof Tinode.MetaGetBuilder#
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withCred() {
if (this.topic.getType() == 'me') {
this.what['cred'] = true;
} else {
this.topic._tinode.logger("ERROR: Invalid topic type for MetaGetBuilder:withCreds", this.topic.getType());
}
return this;
}
/**
* Add query parameters to fetch deleted messages within explicit limits. Any/all parameters can be null.
* @memberof Tinode.MetaGetBuilder#
*
* @param {number=} since - ids of messages deleted since this 'del' id (inclusive)
* @param {number=} limit - number of deleted message ids to fetch
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withDel(since, limit) {
if (since || limit) {
this.what['del'] = {
since: since,
limit: limit
};
}
return this;
}
/**
* Add query parameters to fetch messages deleted after the saved <code>'del'</code> id.
* @memberof Tinode.MetaGetBuilder#
*
* @param {number=} limit - number of deleted message ids to fetch
*
* @returns {Tinode.MetaGetBuilder} <code>this</code> object.
*/
withLaterDel(limit) {
// Specify 'since' only if we have already received some messages. If
// we have no locally cached messages then we don't care if any messages were deleted.
return this.withDel(this.topic._maxSeq > 0 ? this.topic._maxDel + 1 : undefined, limit);
}
/**
* Extract subquery: get an object that contains specified subquery.
* @memberof Tinode.MetaGetBuilder#
* @param {string} what - subquery to return: one of 'data', 'sub', 'desc', 'tags', 'cred', 'del'.
* @returns {Object} requested subquery or <code>undefined</code>.
*/
extract(what) {
return this.what[what];
}
/**
* Construct parameters.
* @memberof Tinode.MetaGetBuilder#
*
* @returns {Tinode.GetQuery} Get query
*/
build() {
const what = [];
let params = {};
['data', 'sub', 'desc', 'tags', 'cred', 'del'].forEach((key) => {
if (this.what.hasOwnProperty(key)) {
what.push(key);
if (Object.getOwnPropertyNames(this.what[key]).length > 0) {
params[key] = this.what[key];
}
}
});
if (what.length > 0) {
params.what = what.join(' ');
} else {
params = undefined;
}
return params;
}
}