@snap/camera-kit
Version:
Camera Kit Web
96 lines • 4.82 kB
JavaScript
import { __awaiter } from "tslib";
import { Subject, filter } from "rxjs";
import { Injectable } from "@snap/ts-inject";
import { pageVisibilityFactory } from "../common/pageVisibility";
import { ServerEventBatch } from "../generated-proto/blizzard/cameraKitEvents";
import { MetricsDefinition } from "../generated-proto/pb_schema/camera_kit/v3/service";
import { HandlerChainBuilder } from "../handlers/HandlerChainBuilder";
import { createBatchingHandler } from "../handlers/batchingHandler";
import { createMappingHandler } from "../handlers/mappingHandler";
import { createRateLimitingHandler } from "../handlers/rateLimitingHandler";
import { isCountMetric } from "../metrics/operational/Count";
import { createTsProtoClient } from "./createTsProtoClient";
import { grpcHandlerFactory } from "./grpcHandler";
const METRIC_REQUEST_RATE_LIMIT_MS = 1000;
const BUSINESS_EVENT_BATCH_MAX_SIZE = 10;
const BUSINESS_EVENT_BATCH_MAX_AGE_MS = 5000;
const METRIC_BATCH_MAX_SIZE = 100;
const METRIC_BATCH_MAX_AGE_MS = 5000;
export class MetricsClient {
constructor(grpcClient, pageVisibility) {
this.grpcClient = grpcClient;
const rateLimitingHandler = createRateLimitingHandler(METRIC_REQUEST_RATE_LIMIT_MS, pageVisibility);
this.businessEventsHandler = new HandlerChainBuilder((request) => __awaiter(this, void 0, void 0, function* () {
yield this.grpcClient.setBusinessEvents(request);
}))
.map(rateLimitingHandler)
.map(createMappingHandler((serverEvents) => {
const batch = ServerEventBatch.fromPartial({ serverEvents });
const request = {
batchEvents: {
typeUrl: "com.snapchat.analytics.blizzard.ServerEventBatch",
value: ServerEventBatch.encode(batch).finish(),
},
};
return request;
}, pageVisibility))
.map(createBatchingHandler({
batchReduce: (previous, event) => {
const batch = previous !== null && previous !== void 0 ? previous : [];
batch.push(event);
return batch;
},
isBatchComplete: (batch) => batch.length >= BUSINESS_EVENT_BATCH_MAX_SIZE,
maxBatchAge: BUSINESS_EVENT_BATCH_MAX_AGE_MS,
pageVisibility,
})).handler;
this.operationalMetricsHandler = new HandlerChainBuilder((metrics) => __awaiter(this, void 0, void 0, function* () {
yield this.grpcClient.setOperationalMetrics({ metrics });
}))
.map(rateLimitingHandler)
.map(createBatchingHandler({
batchReduce: (previous, metric) => {
var _a;
const batch = { metrics: (_a = previous === null || previous === void 0 ? void 0 : previous.metrics) !== null && _a !== void 0 ? _a : [] };
if (isCountMetric(metric)) {
const priorCount = batch.metrics.find((m) => {
return isCountMetric(m) && m.name === metric.name;
});
if (priorCount && isCountMetric(priorCount)) {
priorCount.metric.count = `${Number(priorCount.metric.count) + Number(metric.metric.count)}`;
return batch;
}
}
batch.metrics.push(metric);
return batch;
},
isBatchComplete: (bundle) => bundle.metrics.length >= METRIC_BATCH_MAX_SIZE,
maxBatchAge: METRIC_BATCH_MAX_AGE_MS,
pageVisibility,
})).handler;
}
setBusinessEvents(event) {
return __awaiter(this, void 0, void 0, function* () {
yield this.businessEventsHandler(event);
});
}
setOperationalMetrics(metric) {
return __awaiter(this, void 0, void 0, function* () {
yield Promise.all(metric.toOperationalMetric().map((metric) => {
return this.operationalMetricsHandler(metric);
}));
});
}
}
const validExternalMetrics = /^push2web_/;
export const externalMetricsSubjectFactory = Injectable("externalMetricsSubject", () => new Subject());
export const metricsClientFactory = Injectable("metricsClient", [externalMetricsSubjectFactory.token, grpcHandlerFactory.token, pageVisibilityFactory.token], (externalMetricsSubjectFactory, grpcHandler, pageVisibility) => {
const metrics = new MetricsClient(createTsProtoClient(MetricsDefinition, grpcHandler), pageVisibility);
externalMetricsSubjectFactory.pipe(filter((metric) => validExternalMetrics.test(metric.name))).subscribe({
next: (metric) => {
metrics.setOperationalMetrics(metric);
},
});
return metrics;
});
//# sourceMappingURL=metricsClient.js.map