@snap/camera-kit
Version:
Camera Kit Web
83 lines • 5.17 kB
JavaScript
import { __awaiter, __rest } from "tslib";
import { BrowserHeaders } from "browser-headers";
import { Injectable } from "@snap/ts-inject";
import { getCameraKitUserAgent } from "../platform/cameraKitUserAgent";
import { ensureError } from "../common/errorHelpers";
import { unionBy } from "../common/unionBy";
import { CircumstancesServiceClientImpl, GrpcWebImpl } from "../generated-proto/pb_schema/cdp/cof/circumstance_service";
import { HandlerChainBuilder } from "../handlers/HandlerChainBuilder";
import { dispatchRequestCompleted, dispatchRequestErrored, dispatchRequestStarted, requestStateEventTargetFactory, } from "../handlers/requestStateEmittingHandler";
import { createResponseCachingHandler, staleWhileRevalidateStrategy } from "../handlers/responseCachingHandler";
import { createRetryingHandler } from "../handlers/retryingHandler";
import { createTimeoutHandler } from "../handlers/timeoutHandler";
import { IndexedDBPersistence } from "../persistence/IndexedDBPersistence";
import { configurationToken } from "../configuration";
import { getLogger } from "../logger/logger";
import { ExpiringPersistence } from "../persistence/ExpiringPersistence";
import { convertDaysToSeconds } from "../common/time";
import { metricsClientFactory } from "../clients/metricsClient";
import { Count } from "../metrics/operational/Count";
export const COF_REQUEST_TYPE = "cof";
const logger = getLogger("cofHandler");
export const cofHandlerFactory = Injectable("cofHandler", [configurationToken, requestStateEventTargetFactory.token, metricsClientFactory.token], (config, requestStateEventTarget, metrics) => {
const cofCache = new ExpiringPersistence(() => convertDaysToSeconds(365), new IndexedDBPersistence({ databaseName: "COFCache" }));
const getCacheKey = (r) => JSON.stringify(r);
return (new HandlerChainBuilder((request, _a) => __awaiter(void 0, void 0, void 0, function* () {
var { signal, isSideEffect: _ } = _a, metadata = __rest(_a, ["signal", "isSideEffect"]);
const rpc = new GrpcWebImpl(`https://${config.apiHostname}`, {});
const client = new CircumstancesServiceClientImpl(rpc);
return new Promise((resolve, reject) => __awaiter(void 0, void 0, void 0, function* () {
var _b;
if (signal) {
signal.addEventListener("abort", () => reject(new Error("COF request aborted by handler chain.")));
}
const cachedResponse = yield cofCache.retrieve(getCacheKey(request)).catch((e) => {
logger.warn("Unable to get COF response from cache.", e);
return {
configResultsEtag: undefined,
configResults: [],
};
});
const dimensions = {
requestType: COF_REQUEST_TYPE,
delta: `${!!(cachedResponse === null || cachedResponse === void 0 ? void 0 : cachedResponse.configResultsEtag)}`,
};
const { requestId } = dispatchRequestStarted(requestStateEventTarget, { dimensions });
try {
const response = yield client.targetingQuery(Object.assign(Object.assign({}, request), { configResultsEtag: cachedResponse === null || cachedResponse === void 0 ? void 0 : cachedResponse.configResultsEtag, deltaSync: !!(cachedResponse === null || cachedResponse === void 0 ? void 0 : cachedResponse.configResultsEtag) }), new BrowserHeaders(Object.assign({ authorization: `Bearer ${config.apiToken}`, "x-snap-client-user-agent": getCameraKitUserAgent() }, metadata)));
delete response.toObject;
const configResults = unionBy("configId", (_b = cachedResponse === null || cachedResponse === void 0 ? void 0 : cachedResponse.configResults) !== null && _b !== void 0 ? _b : [], response.configResults).filter((config) => !config.delete);
const status = 200;
let sizeByte = 0;
try {
sizeByte = new TextEncoder().encode(JSON.stringify(response)).byteLength;
}
finally {
dispatchRequestCompleted(requestStateEventTarget, {
requestId,
dimensions,
status,
sizeByte,
});
}
resolve(Object.assign(Object.assign({}, response), { configResults }));
}
catch (error) {
dispatchRequestErrored(requestStateEventTarget, {
requestId,
dimensions,
error: ensureError(error),
});
reject(error);
}
}));
}))
.map(createRetryingHandler({ retryPredicate: (r) => r instanceof Error }))
.map(createTimeoutHandler({ timeout: 20 * 1000 }))
.map(createResponseCachingHandler(cofCache, getCacheKey, staleWhileRevalidateStrategy({
onMiss: () => {
metrics.setOperationalMetrics(Count.count("cache_miss", 1, { request_type: COF_REQUEST_TYPE }));
},
}))).handler);
});
//# sourceMappingURL=cofHandler.js.map