@snap/camera-kit
Version:
Camera Kit Web
147 lines • 8.52 kB
JavaScript
import { __awaiter, __esDecorate, __runInitializers } from "tslib";
import { Injectable } from "@snap/ts-inject";
import { validate } from "../common/validate";
import { isArrayOfType, isSafeString, isSafeStringArray, isString, isUndefined } from "../common/typeguards";
import { defaultFetchHandlerFactory } from "../handlers/defaultFetchHandler";
import { createRequestStateEmittingHandler, requestStateEventTargetFactory, } from "../handlers/requestStateEmittingHandler";
import { HandlerChainBuilder } from "../handlers/HandlerChainBuilder";
import { createArrayBufferParsingHandler } from "../handlers/arrayBufferParsingHandler";
import { LensAssetManifestItem_RequestTiming } from "../generated-proto/pb_schema/camera_kit/v3/lens";
import { getLogger } from "../logger/logger";
import { errorLoggingDecorator } from "../logger/errorLoggingDecorator";
import { ensureError } from "../common/errorHelpers";
import { withRequestPriority } from "../handlers/utils";
import { isLensArray, toPublicLens } from "./Lens";
import { lensAssetRepositoryFactory } from "./assets/LensAssetRepository";
import { loadLensesFromSources, lensSourcesFactory } from "./LensSource";
const logger = getLogger("LensRepository");
const assetTimingMap = {
required: LensAssetManifestItem_RequestTiming.REQUIRED,
onDemand: LensAssetManifestItem_RequestTiming.ON_DEMAND,
};
function isAssetTiming(value) {
return isString(value) && assetTimingMap.hasOwnProperty(value);
}
function isAssetTimingArrayOrUndefined(value) {
return isUndefined(value) || isArrayOfType(isAssetTiming, value);
}
let LensRepository = (() => {
var _a;
let _instanceExtraInitializers = [];
let _loadLens_decorators;
let _loadLensGroups_decorators;
let _cacheLensContent_decorators;
return _a = class LensRepository {
constructor(lensFetchHandler, lensSources, lensAssetRepository) {
this.lensFetchHandler = (__runInitializers(this, _instanceExtraInitializers), lensFetchHandler);
this.lensSources = lensSources;
this.lensAssetRepository = lensAssetRepository;
this.metadataCache = new Map();
this.binariesCache = new Map();
}
loadLens(lensId, groupId) {
return __awaiter(this, void 0, void 0, function* () {
const lens = (yield loadLensesFromSources(this.lensSources, groupId, lensId))[0];
if (!lens) {
throw new Error(`Cannot load lens. No lens with id ${lensId} was found in lens group ${groupId}.`);
}
const lensWithGroup = Object.assign(Object.assign({}, lens), { groupId });
this.metadataCache.set(lens.id, lensWithGroup);
return toPublicLens(lensWithGroup);
});
}
loadLensGroups(groupIds) {
return __awaiter(this, void 0, void 0, function* () {
const responses = yield Promise.all(groupIds.map((groupId) => __awaiter(this, void 0, void 0, function* () {
try {
return (yield loadLensesFromSources(this.lensSources, groupId)).map((lens) => {
const lensWithGroup = Object.assign(Object.assign({}, lens), { groupId });
this.metadataCache.set(lens.id, lensWithGroup);
return toPublicLens(lensWithGroup);
});
}
catch (e) {
const error = ensureError(e);
logger.error(new Error(`Failed to load lens group ${groupId}.`, { cause: error }));
return error;
}
})));
return responses.reduce((result, response) => {
if (response instanceof Error)
result.errors.push(response);
else
result.lenses.push(...response);
return result;
}, { errors: [], lenses: [] });
});
}
cacheLensContent(lenses, assetTimingsToCache = ["required", "onDemand"]) {
return __awaiter(this, void 0, void 0, function* () {
const assetTimingsToLoad = assetTimingsToCache.map((timing) => assetTimingMap[timing]);
yield Promise.all(lenses.map((lens) => __awaiter(this, void 0, void 0, function* () {
try {
const { lensBuffer } = yield this.getLensContent(lens, true);
const { content } = this.metadataCache.get(lens.id);
this.binariesCache.set(lens.id, lensBuffer);
yield this.lensAssetRepository.cacheAssets(content.assetManifest, lens, assetTimingsToLoad, true);
}
catch (error) {
logger.warn(`Failed to cache lens ${lens.id}.`, error);
}
})));
});
}
getLensMetadata(lensId) {
return this.metadataCache.get(lensId);
}
removeCachedLenses(lenses) {
lenses.forEach((lens) => this.binariesCache.delete(lens.id));
}
getLensContent(lens, lowPriority = false) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
const { content } = (_a = this.metadataCache.get(lens.id)) !== null && _a !== void 0 ? _a : {};
if (!content) {
throw new Error(`Cannot find metadata for lens ${lens.id}.`);
}
const cachedLensBuffer = this.binariesCache.get(lens.id);
if (cachedLensBuffer) {
return {
lensBuffer: cachedLensBuffer,
lensChecksum: content.lnsSha256,
};
}
const [lensBuffer] = yield this.lensFetchHandler([
new Request(content.lnsUrlBolt, withRequestPriority({ cache: "force-cache" }, lowPriority)),
{
requestType: "lens_content",
lensId: lens.id,
},
]);
return { lensBuffer, lensChecksum: content.lnsSha256 };
});
}
},
(() => {
_loadLens_decorators = [validate(isSafeString, isSafeString), errorLoggingDecorator(logger)];
_loadLensGroups_decorators = [validate(isSafeStringArray), errorLoggingDecorator(logger)];
_cacheLensContent_decorators = [validate(isLensArray, isAssetTimingArrayOrUndefined), errorLoggingDecorator(logger)];
__esDecorate(_a, null, _loadLens_decorators, { kind: "method", name: "loadLens", static: false, private: false, access: { has: obj => "loadLens" in obj, get: obj => obj.loadLens } }, null, _instanceExtraInitializers);
__esDecorate(_a, null, _loadLensGroups_decorators, { kind: "method", name: "loadLensGroups", static: false, private: false, access: { has: obj => "loadLensGroups" in obj, get: obj => obj.loadLensGroups } }, null, _instanceExtraInitializers);
__esDecorate(_a, null, _cacheLensContent_decorators, { kind: "method", name: "cacheLensContent", static: false, private: false, access: { has: obj => "cacheLensContent" in obj, get: obj => obj.cacheLensContent } }, null, _instanceExtraInitializers);
})(),
_a;
})();
export { LensRepository };
export const lensRepositoryFactory = Injectable("LensRepository", [
requestStateEventTargetFactory.token,
defaultFetchHandlerFactory.token,
lensSourcesFactory.token,
lensAssetRepositoryFactory.token,
], (requestStateEventTarget, defaultFetchHandler, lensSources, lensAssetRepository) => {
const lensFetchHandler = new HandlerChainBuilder(defaultFetchHandler)
.map(createRequestStateEmittingHandler(requestStateEventTarget))
.map(createArrayBufferParsingHandler()).handler;
return new LensRepository(lensFetchHandler, lensSources, lensAssetRepository);
});
//# sourceMappingURL=LensRepository.js.map