search-client
Version:
Javascript library for executing searches in the Haive search-index via the SearchManager REST interface.
321 lines • 13 kB
JavaScript
import { __awaiter, __generator } from "tslib";
import fetch from 'cross-fetch';
import { QueryChangeSpecifications } from './QueryChangeSpecifications';
/**
* A common service base-class for the descending Autocomplete, Categorize and Find classes.
*
* @param TDataType Defines the data-type that the descendant service-class needs to return on lookups.
*/
var BaseCall = /** @class */ (function () {
function BaseCall() {
this.requested = 0;
this.aborted = 0;
this.cancelled = 0;
this.failed = 0;
this.completed = 0;
}
Object.defineProperty(BaseCall.prototype, "numRequested", {
/**
* The number of times this service-instance has started a request.
*/
get: function () {
return this.requested;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseCall.prototype, "numAborted", {
/**
* The number of times this service-instance has aborted a request (typically as a result to starting a new request while the previous is still running and needs to be aborted).
*/
get: function () {
return this.aborted;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseCall.prototype, "numCancelled", {
/**
* The number of times this service-instance has cancelled a request (as directed from a user cbRequest rejection).
*/
get: function () {
return this.cancelled;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseCall.prototype, "numFailed", {
/**
* The number of times this service-instance has failed during a request (not counting aborted or cancelled requests).
*/
get: function () {
return this.failed;
},
enumerable: false,
configurable: true
});
Object.defineProperty(BaseCall.prototype, "numCompleted", {
/**
* The number of times this service-instance has completed a request (not counting aborted or cancelled requests).
*/
get: function () {
return this.completed;
},
enumerable: false,
configurable: true
});
/**
* Decides whether an update should be executed or not. Typically used to temporarily turn off update-execution.
* When turned back on the second param can be used to indicate whether pending updates should be executed or not.
* @param state Turns on or off deferring of updates.
* @param skipPending Used to indicate if a pending update is to be executed or skipped when deferring is turned off. The param is ignored for state=true.
*/
BaseCall.prototype.deferUpdates = function (state, skipPending) {
if (skipPending === void 0) { skipPending = false; }
this.deferUpdate = state;
if (!state && this.deferredQuery) {
var query = this.deferredQuery;
var useMatchPage = this.deferredUseMatchPage;
this.deferredQuery = null;
this.deferredUseMatchPage = null;
if (!skipPending && this.shouldUpdate()) {
this.update(query, null, useMatchPage);
}
}
};
Object.defineProperty(BaseCall.prototype, "deferUpdateState", {
/**
* Can be used to check the state of deferUpdates.
*/
get: function () {
return this.deferUpdate;
},
enumerable: false,
configurable: true
});
/**
* Fetches the results from the server.
* @param query - The query-object that controls which results that are to be returned.
* @param suppressCallbacks - Set to true if you have defined callbacks, but somehow don't want them to be called.
* @returns a promise that when resolved returns the data.
*/
BaseCall.prototype.fetch = function (query, suppressCallbacks) {
return __awaiter(this, void 0, void 0, function () {
var data, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, 3, 4]);
return [4 /*yield*/, this.fetchInternal(query, suppressCallbacks)];
case 1:
data = _a.sent();
this.completed++;
return [2 /*return*/, data];
case 2:
err_1 = _a.sent();
if ((err_1 === null || err_1 === void 0 ? void 0 : err_1.name) === 'AbortError') {
this.aborted++;
}
else if ((err_1 === null || err_1 === void 0 ? void 0 : err_1.name) === 'cbRequestCancelled') {
this.cancelled++;
}
else {
this.failed++;
console.error(err_1);
}
return [2 /*return*/, null];
case 3:
this.abortController = null;
return [7 /*endfinally*/];
case 4: return [2 /*return*/];
}
});
});
};
/**
* Sets up the Request that is to be executed, with headers and auth as needed.
*
* @param includeAuthorizationHeader Set to false to not include the auth jwt token in the request headers. Default=true
*/
BaseCall.prototype.requestObject = function (includeAuthorizationHeader) {
if (includeAuthorizationHeader === void 0) { includeAuthorizationHeader = true; }
var headers = {
'Content-Type': 'application/json',
};
if (includeAuthorizationHeader &&
this.auth &&
this.auth.authenticationToken) {
headers.Authorization = "Bearer " + this.auth.authenticationToken;
}
if (this.abortController && !this.abortController.signal.aborted) {
// If the abortController exists, then the previous call is not completed yet. So, we should abort the current process
this.abortController.abort();
}
// Setup new abort-controller (to reset for each request)
this.abortController = new AbortController();
this.requested++;
return {
cache: 'default',
credentials: 'include',
headers: headers,
method: 'GET',
mode: 'cors',
signal: this.abortController.signal,
};
};
/**
* Call the service, but take into account deferredUpdates.
*
* @param query The query object to create the fetch for.
* @param delay A delay for when to execute the update, in milliseconds. Defaults to undefined.
* @param useQueryMatchPage If true then the query match-page number will not be reset to 1. Otherwise it is by default always 1.
*/
BaseCall.prototype.update = function (query, delay, useQueryMatchPage) {
var _this = this;
if (!useQueryMatchPage) {
query.matchPage = 1;
}
if (this.deferUpdate) {
// Save the query, so that when the deferUpdate is again false we can then execute it.
this.deferredQuery = query;
this.deferredUseMatchPage = useQueryMatchPage;
}
else {
// In case this action is triggered when a delayed execution is already pending, clear that pending timeout.
clearTimeout(this.delay);
if (delay > 0) {
// Set up the delay
this.delay = setTimeout(function () {
var fetchPromise = _this.fetch(query);
if (fetchPromise) {
fetchPromise.catch(function (error) { return Promise.resolve(null); });
}
}, delay);
}
else {
var fetchPromise = this.fetch(query);
if (fetchPromise) {
fetchPromise.catch(function (error) { return Promise.resolve(null); });
}
}
}
};
BaseCall.prototype.shouldUpdate = function (fieldName, query) {
if (this.settings.cbSuccess &&
this.settings.enabled &&
fieldName &&
query) {
this.outdatedWarning(fieldName, query);
}
return this.settings.cbSuccess && this.settings.enabled;
};
BaseCall.prototype.clientIdChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.categorizationTypeChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.dateFromChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.dateToChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.filtersChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.matchGenerateContentChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.matchGenerateContentHighlightsChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.matchGroupingChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.matchOrderByChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.matchPageChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.matchPageSizeChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.maxSuggestionsChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.queryTextChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.searchTypeChanged = function (oldValue, query) {
/* Default no implementation*/
};
BaseCall.prototype.uiLanguageCodeChanged = function (oldValue, query) {
/* Default no implementation*/
};
/**
* Sets up a the common base handling for services, such as checking that the url is valid and handling the authentication.
*
* @param settings - The base url for the service to be setup.
* @param auth - The auth-object that controls authentication for the service.
*/
BaseCall.prototype.init = function (settings, auth, fetchMethod) {
this.settings = settings;
this.auth = auth;
this.fetchMethod = fetchMethod || fetch;
this.abortController = null;
};
BaseCall.prototype.cbRequest = function (suppressCallbacks, url, reqInit) {
if (!this.settings) {
throw new Error('Settings cannot be empty.');
}
var shouldFetch = this.settings.cbRequest && !suppressCallbacks
? this.settings.cbRequest(url, reqInit) !== false
: true;
if (!shouldFetch) {
this.abortController = null;
}
return shouldFetch;
};
BaseCall.prototype.cbError = function (suppressCallbacks, error, url, reqInit) {
if (!this.settings) {
throw new Error('Settings cannot be empty.');
}
if (this.settings.cbError && !suppressCallbacks) {
this.settings.cbError(error);
}
};
BaseCall.prototype.cbWarning = function (suppressCallbacks, warning, url, reqInit) {
if (!this.settings) {
throw new Error('Settings cannot be empty.');
}
if (this.settings.cbWarning && !suppressCallbacks) {
this.settings.cbWarning(warning);
}
};
BaseCall.prototype.cbSuccess = function (suppressCallbacks, data, url, reqInit) {
if (!this.settings) {
throw new Error('Settings cannot be empty.');
}
if (this.settings.cbSuccess && !suppressCallbacks) {
this.settings.cbSuccess(data);
}
};
/**
* Checks whether or not to notify that the results are invalidated (no longer representative for the query).
*/
BaseCall.prototype.outdatedWarning = function (fieldName, query) {
if (this.settings.cbResultState &&
this.settings.queryChangeSpecs &
QueryChangeSpecifications[fieldName]) {
var invalid = this.fetchQuery
? !this.fetchQuery.equals(query, this.settings.queryChangeSpecs)
: false;
this.settings.cbResultState(invalid, this.fetchQuery, query);
}
};
return BaseCall;
}());
export { BaseCall };
//# sourceMappingURL=BaseCall.js.map