mirror of
https://github.com/rxliuli/apps.apple.com.git
synced 2025-11-09 23:40:34 +00:00
init commit
This commit is contained in:
456
node_modules/@jet/environment/metrics/builder.js
generated
vendored
Normal file
456
node_modules/@jet/environment/metrics/builder.js
generated
vendored
Normal file
@@ -0,0 +1,456 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createMetricsMediaClickData = exports.createMetricsMediaData = exports.createMetricsImpressionsData = exports.createMetricsSearchData = exports.createMetricsPageData = exports.createMetricsBackClickData = exports.createMetricsClickData = exports.MediaClickEventBuilder = exports.MediaEventBuilder = exports.ImpressionsEventBuilder = exports.SearchEventBuilder = exports.PageEventBuilder = exports.BackClickEventBuilder = exports.ClickEventBuilder = exports.EventBuilder = void 0;
|
||||
const optional_1 = require("../types/optional");
|
||||
// region Builders
|
||||
/**
|
||||
* Base event builder.
|
||||
*/
|
||||
class EventBuilder {
|
||||
/**
|
||||
* Create base event builder with metrics configuration.
|
||||
*
|
||||
* @param configuration - Metrics configuration used to build metrics events.
|
||||
*/
|
||||
constructor(configuration) {
|
||||
this.configuration = configuration;
|
||||
this.eventFields = {};
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given event fields.
|
||||
* @param eventFields - The events fields to update in builder.
|
||||
* @returns Event builder with updated event fields.
|
||||
*/
|
||||
withEventFields(eventFields) {
|
||||
this.eventFields = eventFields;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given configuration.
|
||||
* @param configuration - The configuration to update in builder.
|
||||
* @returns Event builder with updated configuration.
|
||||
*/
|
||||
withConfiguration(configuration) {
|
||||
this.configuration = configuration;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given default topic.
|
||||
* @param topic - The default topic to update in builder.
|
||||
* @returns Event builder with updated default topic.
|
||||
*/
|
||||
withDefaultTopic(topic) {
|
||||
this.configuration = {
|
||||
...this.configuration,
|
||||
defaultTopic: topic,
|
||||
};
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given include fields requests.
|
||||
* @param includeRequests - The include fields requests to update in builder.
|
||||
* @returns Event builder with updated include fields requests.
|
||||
*/
|
||||
withDefaultIncludeRequests(includeRequests) {
|
||||
this.configuration = {
|
||||
...this.configuration,
|
||||
defaultIncludeRequests: includeRequests,
|
||||
};
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given exclude fields requests.
|
||||
* @param excludeRequests - The exclude fields requests to update in builder.
|
||||
* @returns Event builder with updated exclude fields requests.
|
||||
*/
|
||||
withDefaultExcludeRequests(excludeRequests) {
|
||||
this.configuration = {
|
||||
...this.configuration,
|
||||
defaultExcludeRequests: excludeRequests,
|
||||
};
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given flush behavior.
|
||||
* @param shouldFlush - The flush behavior to update in builder.
|
||||
* @returns Event builder with updated flush behavior.
|
||||
*/
|
||||
withShouldFlush(shouldFlush) {
|
||||
this.configuration = {
|
||||
...this.configuration,
|
||||
shouldFlush: shouldFlush,
|
||||
};
|
||||
return this;
|
||||
}
|
||||
}
|
||||
exports.EventBuilder = EventBuilder;
|
||||
/**
|
||||
* Builder for click events.
|
||||
*/
|
||||
class ClickEventBuilder extends EventBuilder {
|
||||
/**
|
||||
* Create click metrics event builder with all required properties.
|
||||
*
|
||||
* @param options - Object containing options required to create the builder.
|
||||
*
|
||||
* Options:
|
||||
* - targetId - Target ID used for building events.
|
||||
* - targetType - Target type used for building events.
|
||||
* - configuration - Metrics configuration used to build metrics events.
|
||||
*/
|
||||
constructor(options) {
|
||||
super(options.configuration);
|
||||
this.targetId = options.targetId;
|
||||
this.targetType = options.targetType;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given target ID.
|
||||
* @param targetId - The target ID to update in builder.
|
||||
* @returns Event builder with updated target ID.
|
||||
*/
|
||||
withTargetId(targetId) {
|
||||
this.targetId = targetId;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given target type.
|
||||
* @param targetType - The target type to update in builder.
|
||||
* @returns Event builder with updated target type.
|
||||
*/
|
||||
withTargetType(targetType) {
|
||||
this.targetType = targetType;
|
||||
return this;
|
||||
}
|
||||
build() {
|
||||
return createMetricsClickData(this.targetId, this.targetType, this.eventFields, this.configuration);
|
||||
}
|
||||
}
|
||||
exports.ClickEventBuilder = ClickEventBuilder;
|
||||
/**
|
||||
* Builder for back click events.
|
||||
*/
|
||||
class BackClickEventBuilder extends EventBuilder {
|
||||
build() {
|
||||
return createMetricsBackClickData(this.eventFields, this.configuration);
|
||||
}
|
||||
}
|
||||
exports.BackClickEventBuilder = BackClickEventBuilder;
|
||||
/**
|
||||
* Builder for page events.
|
||||
*/
|
||||
class PageEventBuilder extends EventBuilder {
|
||||
/**
|
||||
* Create page metrics event builder with all required properties.
|
||||
*
|
||||
* @param configuration - Metrics configuration used to build metrics events.
|
||||
*/
|
||||
constructor(configuration) {
|
||||
super(configuration);
|
||||
this.timingMetrics = {};
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given fetch timing metrics.
|
||||
* @param timingMetrics - The fetch timing metrics to update in builder.
|
||||
* @returns Event builder with updated fetch timing metrics.
|
||||
*/
|
||||
withTimingMetrics(timingMetrics) {
|
||||
this.timingMetrics = timingMetrics;
|
||||
return this;
|
||||
}
|
||||
build() {
|
||||
return createMetricsPageData(this.eventFields, this.timingMetrics, this.configuration);
|
||||
}
|
||||
}
|
||||
exports.PageEventBuilder = PageEventBuilder;
|
||||
/**
|
||||
* Builder for search metrics events.
|
||||
*/
|
||||
class SearchEventBuilder extends EventBuilder {
|
||||
/**
|
||||
* Create search metrics event builder with all required properties.
|
||||
*
|
||||
* @param options - Object containing options required to create the builder.
|
||||
*
|
||||
* Options:
|
||||
* - term - Search term used to build metrics events.
|
||||
* - targetType - Target type used to build metrics events.
|
||||
* - actionType - Action type used to build metrics events.
|
||||
* - configuration - Metrics configuration used to build metrics events.
|
||||
*/
|
||||
constructor(options) {
|
||||
super(options.configuration);
|
||||
this.term = options.term;
|
||||
this.targetType = options.targetType;
|
||||
this.actionType = options.actionType;
|
||||
this.actionUrl = null;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given search term.
|
||||
* @param term - The search term to update in builder.
|
||||
* @returns Event builder with updated search term.
|
||||
*/
|
||||
withTerm(term) {
|
||||
this.term = term;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given target type.
|
||||
* @param targetType - The target type to update in builder.
|
||||
* @returns Event builder with updated target type.
|
||||
*/
|
||||
withTargetType(targetType) {
|
||||
this.targetType = targetType;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given action type.
|
||||
* @param actionType - The action type to update in builder.
|
||||
* @returns Event builder with updated action type.
|
||||
*/
|
||||
withActionType(actionType) {
|
||||
this.actionType = actionType;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given action URL.
|
||||
* @param actionUrl - The action URL to update in builder.
|
||||
* @returns Event builder with updated action URL.
|
||||
*/
|
||||
withActionUrl(actionUrl) {
|
||||
this.actionUrl = actionUrl;
|
||||
return this;
|
||||
}
|
||||
build() {
|
||||
return createMetricsSearchData(this.term, this.targetType, this.actionType, this.actionUrl, this.eventFields, this.configuration);
|
||||
}
|
||||
}
|
||||
exports.SearchEventBuilder = SearchEventBuilder;
|
||||
/**
|
||||
* Builder for impressions events.
|
||||
*/
|
||||
class ImpressionsEventBuilder extends EventBuilder {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
/**
|
||||
* Impressions event version.
|
||||
*/
|
||||
this.impressionsEventVersion = 4;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given impressions event version.
|
||||
* @param version - The impressions event version to update in builder.
|
||||
* @returns Event builder with updated impressions event version.
|
||||
*/
|
||||
withImpressionsEventVersion(version) {
|
||||
this.impressionsEventVersion = version;
|
||||
return this;
|
||||
}
|
||||
build() {
|
||||
return createMetricsImpressionsData(this.eventFields, this.configuration, this.impressionsEventVersion);
|
||||
}
|
||||
}
|
||||
exports.ImpressionsEventBuilder = ImpressionsEventBuilder;
|
||||
/**
|
||||
* Builder for media events.
|
||||
*/
|
||||
class MediaEventBuilder extends EventBuilder {
|
||||
build() {
|
||||
return createMetricsMediaData(this.eventFields, this.configuration);
|
||||
}
|
||||
}
|
||||
exports.MediaEventBuilder = MediaEventBuilder;
|
||||
/**
|
||||
* Builder for media click events.
|
||||
*/
|
||||
class MediaClickEventBuilder extends EventBuilder {
|
||||
/**
|
||||
* Create media click event builder with all required properties.
|
||||
*
|
||||
* @param options - Object containing options required to create the builder.
|
||||
*
|
||||
* Options:
|
||||
* - targetId - Target ID used for building events.
|
||||
* - targetType - Target type used to build metrics events.
|
||||
* - configuration - Metrics configuration used to build metrics events.
|
||||
*/
|
||||
constructor(options) {
|
||||
super(options.configuration);
|
||||
this.targetId = options.targetId;
|
||||
this.targetType = options.targetType;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given target ID.
|
||||
* @param targetId - The target ID to update in builder.
|
||||
* @returns Event builder with updated target ID.
|
||||
*/
|
||||
withTargetId(targetId) {
|
||||
this.targetId = targetId;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Updates event builder with given target type.
|
||||
* @param targetType - The target type to update in builder.
|
||||
* @returns Event builder with updated target type.
|
||||
*/
|
||||
withTargetType(targetType) {
|
||||
this.targetType = targetType;
|
||||
return this;
|
||||
}
|
||||
build() {
|
||||
return createMetricsMediaClickData(this.targetId, this.targetType, this.eventFields, this.configuration);
|
||||
}
|
||||
}
|
||||
exports.MediaClickEventBuilder = MediaClickEventBuilder;
|
||||
// region Metrics Data
|
||||
/**
|
||||
* Create metrics data for the click event.
|
||||
*
|
||||
* @param targetId - The ID of the click event target.
|
||||
* @param targetType - The type of the click target.
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
*/
|
||||
function createMetricsClickData(targetId, targetType, eventFields, configuration) {
|
||||
const eventType = "click" /* MetricsEventType.click */;
|
||||
const fields = {
|
||||
...eventFields,
|
||||
eventType: eventType,
|
||||
targetType: targetType,
|
||||
targetId: targetId,
|
||||
};
|
||||
return createMetricsData(fields, configuration, eventType);
|
||||
}
|
||||
exports.createMetricsClickData = createMetricsClickData;
|
||||
/**
|
||||
* Create metrics data for the Back button click event.
|
||||
*
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
*/
|
||||
function createMetricsBackClickData(eventFields, configuration) {
|
||||
const fields = {
|
||||
...eventFields,
|
||||
actionType: "back",
|
||||
};
|
||||
return createMetricsClickData("back", "button" /* MetricsClickTargetType.button */, fields, configuration);
|
||||
}
|
||||
exports.createMetricsBackClickData = createMetricsBackClickData;
|
||||
/**
|
||||
* Create metrics data for the page event.
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param timingMetrics - The timing metrics for page data fetching.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
*/
|
||||
function createMetricsPageData(eventFields, timingMetrics, configuration) {
|
||||
const eventType = "page" /* MetricsEventType.page */;
|
||||
const fields = {
|
||||
...eventFields,
|
||||
eventType: eventType,
|
||||
...timingMetrics,
|
||||
};
|
||||
return createMetricsData(fields, configuration, eventType);
|
||||
}
|
||||
exports.createMetricsPageData = createMetricsPageData;
|
||||
/**
|
||||
* Create metrics data for search event.
|
||||
*
|
||||
* @param term - The search term.
|
||||
* @param target - The type of the acton target.
|
||||
* @param actionType - The type of the action.
|
||||
* @param actionUrl - An optional action URL.
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
*/
|
||||
function createMetricsSearchData(term, targetType, actionType, actionUrl, eventFields, configuration) {
|
||||
const eventType = "search" /* MetricsEventType.search */;
|
||||
const fields = {
|
||||
...eventFields,
|
||||
eventType: eventType,
|
||||
term: term,
|
||||
targetType: targetType,
|
||||
actionType: actionType,
|
||||
};
|
||||
if ((0, optional_1.isSome)(actionUrl)) {
|
||||
// actionUrl is defined for `hints` but not for searches fired from elsewhere.
|
||||
fields["actionUrl"] = actionUrl;
|
||||
}
|
||||
return createMetricsData(fields, configuration, eventType);
|
||||
}
|
||||
exports.createMetricsSearchData = createMetricsSearchData;
|
||||
/**
|
||||
* Create metrics data for impressions event.
|
||||
*
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
* @param impressionsEventVersion - The version of the impressions event.
|
||||
*/
|
||||
function createMetricsImpressionsData(eventFields, configuration, impressionsEventVersion = 4) {
|
||||
const eventType = "impressions" /* MetricsEventType.impressions */;
|
||||
const fields = {
|
||||
...eventFields,
|
||||
eventType: eventType,
|
||||
impressionQueue: "data-metrics",
|
||||
eventVersion: impressionsEventVersion,
|
||||
};
|
||||
return createMetricsData(fields, configuration, eventType);
|
||||
}
|
||||
exports.createMetricsImpressionsData = createMetricsImpressionsData;
|
||||
/**
|
||||
* Create metrics data for media event.
|
||||
*
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
*/
|
||||
function createMetricsMediaData(eventFields, configuration) {
|
||||
const eventType = "media" /* MetricsEventType.media */;
|
||||
const fields = {
|
||||
...eventFields,
|
||||
eventType: eventType,
|
||||
};
|
||||
return createMetricsData(fields, configuration, eventType);
|
||||
}
|
||||
exports.createMetricsMediaData = createMetricsMediaData;
|
||||
/**
|
||||
* Create metrics data for media event.
|
||||
*
|
||||
* @param targetId - The ID of the click target.
|
||||
* @param targetType - The type of the click target.
|
||||
* @param eventFields - Event fields to create metrics data from.
|
||||
* @param configuration - Metrics configuration used to create metrics data.
|
||||
*/
|
||||
function createMetricsMediaClickData(targetId, targetType, eventFields, configuration) {
|
||||
const eventType = "click" /* MetricsEventType.click */;
|
||||
const fields = {
|
||||
...eventFields,
|
||||
eventType: eventType,
|
||||
targetType: targetType,
|
||||
targetId: targetId,
|
||||
};
|
||||
return createMetricsData(fields, configuration, eventType);
|
||||
}
|
||||
exports.createMetricsMediaClickData = createMetricsMediaClickData;
|
||||
// endregion
|
||||
// region Helpers
|
||||
function createMetricsData(fields, configuration, eventType) {
|
||||
return {
|
||||
fields: fields,
|
||||
includingFields: configuration.defaultIncludeRequests[eventType],
|
||||
excludingFields: configuration.defaultExcludeRequests[eventType],
|
||||
topic: topicFromEventFields(fields, configuration.defaultTopic),
|
||||
shouldFlush: (0, optional_1.isSome)(configuration.shouldFlush) ? configuration.shouldFlush(fields) : false,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Returns event topic for the given event fields.
|
||||
* @param eventFields - Event fields.
|
||||
* @param defaultTopic - An optional default topic to use if event fields doesn't have one.
|
||||
*/
|
||||
function topicFromEventFields(eventFields, defaultTopic) {
|
||||
const topic = eventFields["topic"];
|
||||
if ((0, optional_1.isSome)(topic)) {
|
||||
return topic;
|
||||
}
|
||||
return defaultTopic;
|
||||
}
|
||||
// endregion
|
||||
//# sourceMappingURL=builder.js.map
|
||||
46
node_modules/@jet/environment/metrics/cookies.js
generated
vendored
Normal file
46
node_modules/@jet/environment/metrics/cookies.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.cookieValueForKey = exports.cookiesOf = void 0;
|
||||
const optional_1 = require("../types/optional");
|
||||
/**
|
||||
* Iterate the cookies contained in a string.
|
||||
*
|
||||
* @param cookie - A string containing zero or more cookies.
|
||||
*/
|
||||
function* cookiesOf(cookie) {
|
||||
if ((0, optional_1.isNothing)(cookie)) {
|
||||
return;
|
||||
}
|
||||
const rawEntries = cookie.split(";");
|
||||
for (const rawEntry of rawEntries) {
|
||||
const keyEndIndex = rawEntry.indexOf("=");
|
||||
if (keyEndIndex === -1) {
|
||||
// If there's no splitter, treat the whole raw
|
||||
// entry as the key and provide an empty value.
|
||||
const key = decodeURIComponent(rawEntry).trim();
|
||||
yield { key, value: "" };
|
||||
}
|
||||
else {
|
||||
const key = decodeURIComponent(rawEntry.substring(0, keyEndIndex)).trim();
|
||||
const value = decodeURIComponent(rawEntry.substring(keyEndIndex + 1)).trim();
|
||||
yield { key, value };
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.cookiesOf = cookiesOf;
|
||||
/**
|
||||
* Returns value of the cookie with the given key or `null` if there's no such cookie.
|
||||
*
|
||||
* @param cookies - Cookies.
|
||||
* @param key - The key to return cookie value for.
|
||||
*/
|
||||
function cookieValueForKey(cookies, key) {
|
||||
for (const cookie of cookies) {
|
||||
if (cookie.key === key) {
|
||||
return cookie.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
exports.cookieValueForKey = cookieValueForKey;
|
||||
//# sourceMappingURL=cookies.js.map
|
||||
155
node_modules/@jet/environment/metrics/event-linter.js
generated
vendored
Normal file
155
node_modules/@jet/environment/metrics/event-linter.js
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EventLinter = void 0;
|
||||
const object_reader_1 = require("../json/reader/object-reader");
|
||||
const optional_1 = require("../types/optional");
|
||||
const numerics = require("./helpers/numerics");
|
||||
/**
|
||||
* A type which applies common business rules to metrics fields
|
||||
* and generates events which are ready for posting to Figaro.
|
||||
*
|
||||
* The common business rules are:
|
||||
* - Add base event fields provided by linter configuration provider object
|
||||
* - Set clientBuiltType and resourceRevNum fields based on EventLinterEnvironment object values
|
||||
* - Set xpSendMethod field to "jet-js"
|
||||
* - Combine pageType and pageId using compound separator provided by linter configuration provider
|
||||
* and set result to "page" field.
|
||||
* - Apply event field de-resolution rules provided by linter configuration provider object
|
||||
* - Set the "position" field for events of "media" type.
|
||||
*/
|
||||
class EventLinter {
|
||||
/**
|
||||
* Create an event linter.
|
||||
*
|
||||
* @param options - The options which specify various behaviors of the new linter.
|
||||
* This object will be frozen.
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = Object.freeze(options);
|
||||
}
|
||||
// MARK: Public Properties
|
||||
/**
|
||||
* Topic to use if an event fields blob does not specify one.
|
||||
*/
|
||||
get defaultTopic() {
|
||||
return this.options.defaultTopic;
|
||||
}
|
||||
// MARK: Utilities
|
||||
/**
|
||||
* Reduce the accuracy of fields in a blob according to
|
||||
* a given array of rules provided by linter configuration object.
|
||||
*
|
||||
* @param eventFields - The fields of an event to reduce the accuracy of.
|
||||
* @param rules - An array of de-resolution rules to apply to event fields.
|
||||
*/
|
||||
applyDeResolutionRules(eventFields, rules) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
for (const rule of rules) {
|
||||
const value = eventFieldsReader.asNumber(rule.fieldName);
|
||||
if ((0, optional_1.isNothing)(value)) {
|
||||
continue;
|
||||
}
|
||||
let magnitude = rule.magnitude;
|
||||
if ((0, optional_1.isNothing)(magnitude)) {
|
||||
magnitude = 1024 * 1024;
|
||||
}
|
||||
let significantDigits = rule.significantDigits;
|
||||
if ((0, optional_1.isNothing)(significantDigits)) {
|
||||
significantDigits = 2;
|
||||
}
|
||||
if (magnitude <= 0.0 || significantDigits < 0.0) {
|
||||
// This is the failure mode from MetricsKit.
|
||||
eventFields[rule.fieldName] = Number.NaN;
|
||||
continue;
|
||||
}
|
||||
const scaledValue = value / magnitude;
|
||||
eventFields[rule.fieldName] = numerics.reduceSignificantDigits(scaledValue, significantDigits);
|
||||
}
|
||||
}
|
||||
// MARK: Rules
|
||||
/**
|
||||
* Apply the rules which are universal to all metrics events
|
||||
* to a given metrics fields linter.
|
||||
*
|
||||
* @param eventFields - The fields which will be used to construct a built event.
|
||||
* @param topic - The topic the built event will be submitted to.
|
||||
*/
|
||||
decorateCommonEventFields(eventFields, topic) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
const configurationProvider = this.options.configuration;
|
||||
// - Base metrics fields.
|
||||
const baseFields = configurationProvider.baseFields(topic);
|
||||
if ((0, optional_1.isSome)(baseFields)) {
|
||||
Object.assign(eventFields, baseFields);
|
||||
}
|
||||
// - Universal basic fields.
|
||||
eventFields["clientBuildType"] = this.options.environment.buildType;
|
||||
eventFields["resourceRevNum"] = this.options.environment.jsVersion;
|
||||
eventFields["xpSendMethod"] = "jet-js";
|
||||
// - Page.
|
||||
const pageType = eventFieldsReader.asString("pageType");
|
||||
const pageId = eventFieldsReader.asString("pageId");
|
||||
if ((0, optional_1.isSome)(pageType) && (0, optional_1.isSome)(pageId) && (0, optional_1.isNothing)(eventFields["page"])) {
|
||||
const bagValue = configurationProvider.compoundSeparator(topic);
|
||||
const separator = (0, optional_1.isSome)(bagValue) ? (0, optional_1.unwrapOptional)(bagValue) : "_";
|
||||
eventFields["page"] = `${pageType}${separator}${pageId}`;
|
||||
}
|
||||
// - Field value resolution reduction.
|
||||
const rules = configurationProvider.deResolutionRules(topic);
|
||||
this.applyDeResolutionRules(eventFields, rules);
|
||||
}
|
||||
/**
|
||||
* Apply the rules specific to the `media` event.
|
||||
*
|
||||
* @param eventFields - The fields which will be used to construct a built event.
|
||||
*/
|
||||
decorateMediaEventEvents(eventFields) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
const position = eventFieldsReader.asNumber("position");
|
||||
if ((0, optional_1.isSome)(position)) {
|
||||
eventFields["position"] = Math.round(position);
|
||||
}
|
||||
}
|
||||
// MARK: Decorating Event Fields
|
||||
/**
|
||||
* Lint metrics event fields by applying the common business rules to a given fields blob.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Note: A deep copy of event fields is created by linter using `JSON.parse(JSON.stringify(eventFields))`.
|
||||
* The original event fields are not modified.
|
||||
*
|
||||
* @param eventFields - The fields to decorate.
|
||||
* @param context - The additional event linter context to be passed to all
|
||||
* event linter rules. This is a free-form object so clients can pass custom
|
||||
* context information.
|
||||
* @returns Decorated fields ready for creating a metrics event.
|
||||
*/
|
||||
lint(eventFields, context = {}) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
const eventType = eventFieldsReader.asString("eventType");
|
||||
if (this.options.isLoggingEnabled) {
|
||||
console.log(`Building event for event type: ${eventType !== null && eventType !== void 0 ? eventType : "<null>"}`);
|
||||
}
|
||||
// Make sure we have a deep copy of an object.
|
||||
const decoratedEventFields = JSON.parse(JSON.stringify(eventFields));
|
||||
const value = eventFieldsReader.asString("topic");
|
||||
const topic = (0, optional_1.isSome)(value) ? (0, optional_1.unwrapOptional)(value) : this.options.defaultTopic;
|
||||
this.decorateCommonEventFields(decoratedEventFields, topic);
|
||||
switch (eventType) {
|
||||
case "media" /* MetricsEventType.media */:
|
||||
this.decorateMediaEventEvents(decoratedEventFields);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (const rule of this.options.rules) {
|
||||
rule.apply(decoratedEventFields, context);
|
||||
}
|
||||
return {
|
||||
fields: decoratedEventFields,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.EventLinter = EventLinter;
|
||||
//# sourceMappingURL=event-linter.js.map
|
||||
96
node_modules/@jet/environment/metrics/fetch-timing-metrics-builder.js
generated
vendored
Normal file
96
node_modules/@jet/environment/metrics/fetch-timing-metrics-builder.js
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.fetchTimingMetricsBuilderType = exports.FetchTimingMetricsBuilder = void 0;
|
||||
const optional_1 = require("../types/optional");
|
||||
const metatype_1 = require("../util/metatype");
|
||||
const promise_1 = require("../util/promise");
|
||||
/** Object to collect `FetchTimingMetrics`, in order to decorate a model object with these metrics. */
|
||||
class FetchTimingMetricsBuilder {
|
||||
constructor() {
|
||||
this.metrics = [];
|
||||
}
|
||||
/**
|
||||
* Collects the timing metrics from the response,
|
||||
* then execute code for parsing while capturing timing points around it,
|
||||
* adding those parse times to the first timing metrics.
|
||||
*/
|
||||
measureParsing(response, body) {
|
||||
const responseTimingMetrics = response.metrics.length > 0 ? [...response.metrics] : [];
|
||||
const parseStartTime = Date.now();
|
||||
const result = body(response);
|
||||
const parseEndTime = Date.now();
|
||||
// MAINTAINERS NOTE:
|
||||
// Follows app store approach to add additional timing points to the first item.
|
||||
// This may not be strictly correct, and we should revisit this later.
|
||||
if (responseTimingMetrics.length > 0) {
|
||||
responseTimingMetrics[0].parseStartTime = parseStartTime;
|
||||
responseTimingMetrics[0].parseEndTime = parseEndTime;
|
||||
}
|
||||
this.metrics.push(...responseTimingMetrics);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Execute code for model construction while capturing timing points around it,
|
||||
* adding those model construction times to the first timing metrics.
|
||||
*
|
||||
* Use this method when model construction is a synchronous operation.
|
||||
* Use `measureModelConstructionAsync()` when model construction is an asynchronous operation.
|
||||
*/
|
||||
measureModelConstruction(body) {
|
||||
const buildModelStartTime = Date.now();
|
||||
const result = body();
|
||||
const buildModelEndTime = Date.now();
|
||||
this.saveModelConstructionTimes(buildModelStartTime, buildModelEndTime);
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Execute and await code for an asynchronous model construction operation while capturing timing points around it,
|
||||
* adding those model construction times to the first timing metrics.
|
||||
*
|
||||
* Use this method when model construction is an asynchronous operation.
|
||||
* Use `measureModelConstruction()` when model construction is a synchronous operation.
|
||||
*/
|
||||
async measureModelConstructionAsync(body) {
|
||||
const buildModelStartTime = Date.now();
|
||||
const result = await body();
|
||||
const buildModelEndTime = Date.now();
|
||||
this.saveModelConstructionTimes(buildModelStartTime, buildModelEndTime);
|
||||
return result;
|
||||
}
|
||||
saveModelConstructionTimes(startTime, endTime) {
|
||||
// MAINTAINERS NOTE:
|
||||
// Follows app store approach to add additional timing points to the first item.
|
||||
// This may not be strictly correct, and we should revisit this later.
|
||||
if (this.metrics.length > 0) {
|
||||
this.metrics[0].modelConstructionStartTime = startTime;
|
||||
this.metrics[0].modelConstructionEndTime = endTime;
|
||||
}
|
||||
else {
|
||||
this.metrics.push({
|
||||
modelConstructionStartTime: startTime,
|
||||
modelConstructionEndTime: endTime,
|
||||
});
|
||||
}
|
||||
}
|
||||
/** Add the recorded `FetchTimingMetrics` as an additional property on the model. */
|
||||
decorate(model) {
|
||||
if ((0, optional_1.isNothing)(model)) {
|
||||
throw new Error("Cannot decorate null or undefined");
|
||||
}
|
||||
if (typeof model !== "object") {
|
||||
throw new Error("View model to decorate must be an object");
|
||||
}
|
||||
if ((0, promise_1.isPromise)(model)) {
|
||||
// TypeScript compiler may be able to enforce this at compile time.
|
||||
// A newer version of TypeScript which supports `Awaited` type may help.
|
||||
throw new Error("Cannot decorate a Promise object");
|
||||
}
|
||||
if (this.metrics.length > 0) {
|
||||
model["$networkPerformance"] = this.metrics;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.FetchTimingMetricsBuilder = FetchTimingMetricsBuilder;
|
||||
/** Metatype for the `FetchTimingMetricsBuilder`, for adding to an object graph. */
|
||||
exports.fetchTimingMetricsBuilderType = (0, metatype_1.makeMetatype)("jet-engine:fetchTimingMetricsBuilder");
|
||||
//# sourceMappingURL=fetch-timing-metrics-builder.js.map
|
||||
21
node_modules/@jet/environment/metrics/helpers/index.js
generated
vendored
Normal file
21
node_modules/@jet/environment/metrics/helpers/index.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./location"), exports);
|
||||
__exportStar(require("./models"), exports);
|
||||
__exportStar(require("./numerics"), exports);
|
||||
__exportStar(require("./util"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
213
node_modules/@jet/environment/metrics/helpers/location.js
generated
vendored
Normal file
213
node_modules/@jet/environment/metrics/helpers/location.js
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.MetricsLocationTracker = void 0;
|
||||
const validation = require("../../json/validation");
|
||||
const optional_1 = require("../../types/optional");
|
||||
const metricsUtil = require("./util");
|
||||
/**
|
||||
* A type describing metrics location tracker.
|
||||
*
|
||||
* The tracker manages stack of metrics location items.
|
||||
*/
|
||||
class MetricsLocationTracker {
|
||||
// endregion
|
||||
// region Initialization
|
||||
/**
|
||||
* Create new metrics location tracker with all required attributes.
|
||||
* @param rootPosition - Current root position of the tracker.
|
||||
* @param locations - Array of metrics location to track.
|
||||
*/
|
||||
constructor(rootPosition = 0, locations = []) {
|
||||
this.rootPosition = rootPosition;
|
||||
this.locationStack = locations.map((location) => new MetricsLocationStackItem(location));
|
||||
}
|
||||
// endregion
|
||||
// region Location Stack Management
|
||||
/**
|
||||
* Check whether location stack is empty or not.
|
||||
*/
|
||||
get isEmpty() {
|
||||
return this.locationStack.length === 0;
|
||||
}
|
||||
/**
|
||||
* Push new location to location tracker's stack.
|
||||
* @param location - Location to push to stack.
|
||||
*/
|
||||
pushLocation(location) {
|
||||
this.locationStack.push(new MetricsLocationStackItem(location));
|
||||
}
|
||||
/**
|
||||
* Pop location from location tracker's stack.
|
||||
*/
|
||||
popLocation() {
|
||||
var _a;
|
||||
if (this.locationStack.length === 0) {
|
||||
validation.unexpectedType("ignoredValue", "non-empty location stack", "empty location stack");
|
||||
return null;
|
||||
}
|
||||
return (_a = this.locationStack.pop()) === null || _a === void 0 ? void 0 : _a.location;
|
||||
}
|
||||
/**
|
||||
* Returns tracker's current position.
|
||||
*/
|
||||
get currentPosition() {
|
||||
const stackItem = this.lastStackItem;
|
||||
if ((0, optional_1.isSome)(stackItem)) {
|
||||
return stackItem.position;
|
||||
}
|
||||
else {
|
||||
return this.rootPosition;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set current position of tracker.
|
||||
* This is necessary when large today modules are broken apart into multipart shelves.
|
||||
* We need to preserve the position of content within server-response, not our logical shelves.
|
||||
* @param position - Position to set to.
|
||||
*/
|
||||
setCurrentPosition(position) {
|
||||
const stackItem = this.lastStackItem;
|
||||
if ((0, optional_1.isSome)(stackItem)) {
|
||||
stackItem.position = position;
|
||||
}
|
||||
else {
|
||||
this.rootPosition = position;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Advance tracker's position.
|
||||
*/
|
||||
nextPosition() {
|
||||
const stackItem = this.lastStackItem;
|
||||
if ((0, optional_1.isSome)(stackItem)) {
|
||||
stackItem.position += 1;
|
||||
}
|
||||
else {
|
||||
this.rootPosition += 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Convert location tracker's stack items to array of metric location objects.
|
||||
*/
|
||||
get stackItemsToLocations() {
|
||||
return this.locationStack.map((stackItem) => stackItem.location);
|
||||
}
|
||||
/**
|
||||
* Returns last stack item in location stack or `null` if stack is empty.
|
||||
*/
|
||||
get lastStackItem() {
|
||||
const length = this.locationStack.length;
|
||||
if (length === 0) {
|
||||
return null;
|
||||
}
|
||||
return this.locationStack[length - 1];
|
||||
}
|
||||
// endregion
|
||||
// region Adding Location
|
||||
/**
|
||||
* Create new basic location and add it to existing locations of the location tracker
|
||||
* and return resulting array of locations.
|
||||
* @param options - Base metrics options which include location tracker to get current locations from.
|
||||
* @param title - New location title.
|
||||
*/
|
||||
static locationsByAddingBasicLocation(options, title) {
|
||||
const locations = options.locationTracker.stackItemsToLocations;
|
||||
locations.push(MetricsLocationTracker.buildBasicLocation(options, title));
|
||||
return locations;
|
||||
}
|
||||
/**
|
||||
* Create new content location and add it to existing locations of the location tracker
|
||||
* and return resulting array of locations.
|
||||
* @param options - Content metrics options which include location tracker to get current locations from.
|
||||
* @param title - New location title.
|
||||
*/
|
||||
static locationsByAddingContentLocation(options, title) {
|
||||
const locations = options.locationTracker.stackItemsToLocations;
|
||||
locations.push(MetricsLocationTracker.buildContentLocation(options, title));
|
||||
return locations;
|
||||
}
|
||||
// endregion
|
||||
// region Metrics Options
|
||||
/**
|
||||
* Create new basic location from base metrics options
|
||||
* and push it to the stack of location tracker included into options.
|
||||
* @param options - Base metrics options which include location tracker to push new location to.
|
||||
* @param title - Location title.
|
||||
*/
|
||||
static pushBasicLocation(options, title) {
|
||||
options.locationTracker.pushLocation(MetricsLocationTracker.buildBasicLocation(options, title));
|
||||
}
|
||||
/**
|
||||
* Create new content location from content metrics options
|
||||
* and push it to the stack of location tracker included into options.
|
||||
* @param options - Content metrics options which include location tracker to push new location to.
|
||||
* @param title - Location title.
|
||||
*/
|
||||
static pushContentLocation(options, title) {
|
||||
options.locationTracker.pushLocation(MetricsLocationTracker.buildContentLocation(options, title));
|
||||
}
|
||||
/**
|
||||
* Pop last location from location tracker contained in metrics options.
|
||||
* @param options - Metrics options containing the location tracker.
|
||||
*/
|
||||
static popLocation(options) {
|
||||
return options.locationTracker.popLocation();
|
||||
}
|
||||
// endregion
|
||||
// region Location Builders
|
||||
static buildBasicLocation(options, title) {
|
||||
let name = title;
|
||||
if ((0, optional_1.isSome)(options.anonymizationOptions)) {
|
||||
name = options.anonymizationOptions.anonymizationString;
|
||||
}
|
||||
const location = {
|
||||
locationPosition: options.locationTracker.currentPosition,
|
||||
locationType: metricsUtil.targetTypeForMetricsOptions(options),
|
||||
name: name,
|
||||
};
|
||||
if ((0, optional_1.isSome)(options.recoMetricsData)) {
|
||||
Object.assign(location, options.recoMetricsData);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
static buildContentLocation(options, title) {
|
||||
const base = MetricsLocationTracker.buildBasicLocation(options, title);
|
||||
// Use the location tracker if there is no id override.
|
||||
if ((0, optional_1.isNothing)(options.id)) {
|
||||
base.idType = "sequential" /* MetricsIDType.sequential */;
|
||||
base.id = options.locationTracker.currentPosition.toString();
|
||||
}
|
||||
else {
|
||||
// If there is a id specified, use that.
|
||||
base.idType = metricsUtil.idTypeForMetricsOptions(options);
|
||||
let id = options.id;
|
||||
if ((0, optional_1.isSome)(options.anonymizationOptions)) {
|
||||
id = options.anonymizationOptions.anonymizationString;
|
||||
}
|
||||
base.id = id;
|
||||
}
|
||||
if ((0, optional_1.isSome)(options.fcKind)) {
|
||||
base.fcKind = options.fcKind;
|
||||
}
|
||||
if ((0, optional_1.isSome)(options.displayStyle)) {
|
||||
base.displayStyle = options.displayStyle;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
}
|
||||
exports.MetricsLocationTracker = MetricsLocationTracker;
|
||||
/**
|
||||
* A type describing a metrics location item in location tracking stack.
|
||||
*/
|
||||
class MetricsLocationStackItem {
|
||||
/**
|
||||
* Create new metrics location stack item with all required attributes.
|
||||
* @param location - The metrics location associated with this item.
|
||||
* @param position - The position of the item.
|
||||
*/
|
||||
constructor(location, position = 0) {
|
||||
this.location = location;
|
||||
this.position = position;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=location.js.map
|
||||
3
node_modules/@jet/environment/metrics/helpers/models.js
generated
vendored
Normal file
3
node_modules/@jet/environment/metrics/helpers/models.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=models.js.map
|
||||
23
node_modules/@jet/environment/metrics/helpers/numerics.js
generated
vendored
Normal file
23
node_modules/@jet/environment/metrics/helpers/numerics.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
/**
|
||||
* Number related helper functions for metrics.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.reduceSignificantDigits = void 0;
|
||||
/**
|
||||
* Reduce significant figures of `value` by `significantDigits`.
|
||||
* @param value - Value to reduce precision of.
|
||||
* @param significantDigits - Number of significant digits to reduce precision by.
|
||||
*
|
||||
* Examples:
|
||||
* value = 123.5, significantDigits = 0, result = 120 (no significant digit reduced)
|
||||
* value = 123.5, significantDigits = 1, result = 120 (1 significant digit reduced)
|
||||
* value = 123.5, significantDigits = 2, result = 100 (2 significant digit reduced)
|
||||
*/
|
||||
function reduceSignificantDigits(value, significantDigits) {
|
||||
const roundFactor = Math.pow(10.0, significantDigits);
|
||||
const roundingFunction = value > 0.0 ? Math.floor : Math.ceil;
|
||||
return roundingFunction(value / roundFactor) * roundFactor;
|
||||
}
|
||||
exports.reduceSignificantDigits = reduceSignificantDigits;
|
||||
//# sourceMappingURL=numerics.js.map
|
||||
76
node_modules/@jet/environment/metrics/helpers/util.js
generated
vendored
Normal file
76
node_modules/@jet/environment/metrics/helpers/util.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.searchTermFromRefURL = exports.extractSiriRefAppFromRefURL = exports.idTypeForMetricsOptions = exports.targetTypeForMetricsOptions = void 0;
|
||||
const optional_1 = require("../../types/optional");
|
||||
const urls = require("../../util/urls");
|
||||
/**
|
||||
* Returns click target type for given base metrics options.
|
||||
* @param options - Base metrics options to derive click target type for.
|
||||
*/
|
||||
function targetTypeForMetricsOptions(options) {
|
||||
let type = options.targetType;
|
||||
if ((0, optional_1.isNothing)(type)) {
|
||||
type = "lockup" /* MetricsClickTargetType.lockup */;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
exports.targetTypeForMetricsOptions = targetTypeForMetricsOptions;
|
||||
/**
|
||||
* Returns metrics ID type for given content metrics options.
|
||||
* @param options - Content metrics options to derive metrics ID type for.
|
||||
*/
|
||||
function idTypeForMetricsOptions(options) {
|
||||
let type = options.idType;
|
||||
if ((0, optional_1.isNothing)(type)) {
|
||||
type = "its_id" /* MetricsIDType.itsID */;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
exports.idTypeForMetricsOptions = idTypeForMetricsOptions;
|
||||
/**
|
||||
* Extract and return Siri reference app from URL string.
|
||||
* @param refUrlString - URL string.
|
||||
* @returns An optional Siri reference app string.
|
||||
*/
|
||||
function extractSiriRefAppFromRefURL(urlString) {
|
||||
const refUrl = new urls.URL(urlString);
|
||||
if ((0, optional_1.isNothing)(refUrl.query)) {
|
||||
return null;
|
||||
}
|
||||
let extractedRefApp = null;
|
||||
for (const key of Object.keys(refUrl.query)) {
|
||||
if (key === "referrer") {
|
||||
if (refUrl.query[key] === "siri") {
|
||||
extractedRefApp = "com.apple.siri";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return extractedRefApp;
|
||||
}
|
||||
exports.extractSiriRefAppFromRefURL = extractSiriRefAppFromRefURL;
|
||||
/**
|
||||
* Extract and return search term from reference URL string.
|
||||
* @param refUrlString - Reference URL string.
|
||||
* @returns An optional search term string.
|
||||
*/
|
||||
function searchTermFromRefURL(refUrlString) {
|
||||
const refUrl = new urls.URL(refUrlString);
|
||||
const queryItems = refUrl.query;
|
||||
if ((0, optional_1.isNothing)(queryItems)) {
|
||||
return null;
|
||||
}
|
||||
const searchTerm = queryItems["term"];
|
||||
const path = refUrl.pathname;
|
||||
if ((0, optional_1.isNothing)(searchTerm) || (0, optional_1.isNothing)(path)) {
|
||||
return null;
|
||||
}
|
||||
if (!path.endsWith("/search")) {
|
||||
return null;
|
||||
}
|
||||
// the url object has already url-decoded this query parameter
|
||||
const plainTerm = searchTerm;
|
||||
return plainTerm;
|
||||
}
|
||||
exports.searchTermFromRefURL = searchTermFromRefURL;
|
||||
//# sourceMappingURL=util.js.map
|
||||
23
node_modules/@jet/environment/metrics/index.js
generated
vendored
Normal file
23
node_modules/@jet/environment/metrics/index.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
||||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__exportStar(require("./builder"), exports);
|
||||
__exportStar(require("./cookies"), exports);
|
||||
__exportStar(require("./event-linter"), exports);
|
||||
__exportStar(require("./fetch-timing-metrics-builder"), exports);
|
||||
__exportStar(require("./helpers"), exports);
|
||||
__exportStar(require("./parse-and-build-model"), exports);
|
||||
//# sourceMappingURL=index.js.map
|
||||
116
node_modules/@jet/environment/metrics/parse-and-build-model.js
generated
vendored
Normal file
116
node_modules/@jet/environment/metrics/parse-and-build-model.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseAndBuildModel = exports.requestAndBuildModel = void 0;
|
||||
const dependencies_1 = require("../dependencies");
|
||||
const optional_1 = require("../types/optional");
|
||||
const fetch_timing_metrics_builder_1 = require("./fetch-timing-metrics-builder");
|
||||
/**
|
||||
* Returns an object graph guaranteed to have a `FetchTimingMetricsBuilder` object.
|
||||
*
|
||||
* If a `FetchTimingMetricsBuilder` already exists, the same object graph is returned.
|
||||
*
|
||||
* If it doesn't exist, a new object graph is returned, which has a new `FetchTimingMetricsBuilder` added to it.
|
||||
*/
|
||||
function ensureFetchTimingMetricsBuilderExists(objectGraph, errorIfNotFound) {
|
||||
const optionalBuilder = objectGraph.optional(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType);
|
||||
if ((0, optional_1.isSome)(optionalBuilder)) {
|
||||
return objectGraph;
|
||||
}
|
||||
else {
|
||||
if (errorIfNotFound) {
|
||||
throw new Error("Could not find FetchTimingMetricsBuilder in the object graph");
|
||||
}
|
||||
return objectGraph.adding(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType, new fetch_timing_metrics_builder_1.FetchTimingMetricsBuilder());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Orchestrates the flow to make a network request and then build the view model,
|
||||
* capturing timing points around the model building step, and then
|
||||
* adding performance metrics data to the final result.
|
||||
*
|
||||
* **Important**
|
||||
*
|
||||
* When using this method, it is the responsibility of the `requester` to instrument the network times and parsing times
|
||||
* using a `FetchTimingMetricsBuilder` which is in the object graph.
|
||||
*
|
||||
* A simplified implementation of a requester function might look like this:
|
||||
```
|
||||
import * as types from "@jet/environment/types/globals/types"
|
||||
import { fetchTimingMetricsBuilderType } from "@jet/environment/metrics";
|
||||
|
||||
export async function requestFromAPI(request: FetchRequest, objectGraph: ObjectGraph): Promise<MyParsedModel> {
|
||||
const net = inject(types.net, objectGraph);
|
||||
const fetchResponse = await net.fetch(request);
|
||||
const fetchTimingMetricsBuilder = inject(fetchTimingMetricsBuilderType, objectGraph);
|
||||
return fetchTimingMetricsBuilder.measureParsing(fetchResponse, (response) => {
|
||||
const parsedBody = JSON.parse(response.body);
|
||||
return new MyParsedModel(parsedBody);
|
||||
});
|
||||
}
|
||||
```
|
||||
* This approach supports a common pattern in our adopters in which the code that coordinates the fetch of the network request
|
||||
* is tightly coupled to the code which parses the response.
|
||||
*
|
||||
* For an alternative approach which includes orchestrating the parsing step, use `parseAndBuildModel()`.
|
||||
*
|
||||
* @param request - The request object to pass to the `requester` function.
|
||||
* @param objectGraph - Object graph that can be used to pass data to the `requester` and `modelBuilder` steps.
|
||||
* The object graph must contain a `FetchTimingMetricsBuilder` that the `requester` will use to collect network times and parsing times.
|
||||
* @param requester - A function which can make a network request, and return a `ResponseType` which can be used by the `modelBuilder`.
|
||||
* @param modelBuilder - A step that takes the output of the `requester` step, and builds the view model.
|
||||
* This parameter supports both synchronous and asynchronous functions.
|
||||
* @returns The view model.
|
||||
*/
|
||||
async function requestAndBuildModel(request, objectGraph, requester, modelBuilder) {
|
||||
const modifiedObjectGraph = ensureFetchTimingMetricsBuilderExists(objectGraph, true);
|
||||
const response = await requester(request, modifiedObjectGraph);
|
||||
return await constructAndDecorateModel(response, modifiedObjectGraph, modelBuilder);
|
||||
}
|
||||
exports.requestAndBuildModel = requestAndBuildModel;
|
||||
/**
|
||||
* Orchestrates the flow to parse a `FetchResponse` and then build the view model,
|
||||
* adding performance metrics data to the final result.
|
||||
*
|
||||
* Timing points are captured around the parsing and model building steps,
|
||||
* and this is added to the metrics which were returned from the `FetchResponse`.
|
||||
*
|
||||
* When using this method, it is the responsibility of the caller
|
||||
* to perform the network fetch in order to have a `FetchResponse` object.
|
||||
* The parsing logic which transforms the `FetchResponse` object into an intermediate model object
|
||||
* will need to be decoupled so that it can be implemented in the `parser` function.
|
||||
*
|
||||
* @param response - The response from a `Network.fetch()` call.
|
||||
* @param objectGraph - Object graph that can be used to pass data to the `parser` and `renderer` steps.
|
||||
* @param parser - A step that parses a `FetchResponse` to an intermediate model object.
|
||||
* @param modelBuilder - A step that takes the output of the `parser` step, and builds the view model.
|
||||
* This parameter supports both synchronous and asynchronous functions.
|
||||
* @returns The view model.
|
||||
*/
|
||||
async function parseAndBuildModel(response, objectGraph, parser, modelBuilder) {
|
||||
const modifiedObjectGraph = ensureFetchTimingMetricsBuilderExists(objectGraph, false);
|
||||
const fetchTimingMetricsBuilder = (0, dependencies_1.inject)(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType, modifiedObjectGraph);
|
||||
// Add metrics from FetchResponse, and run the parser, capturing timing points.
|
||||
const parsedObject = fetchTimingMetricsBuilder.measureParsing(response, () => {
|
||||
return parser(response, modifiedObjectGraph);
|
||||
});
|
||||
if ((0, optional_1.isNothing)(parsedObject)) {
|
||||
throw new Error("parser function returned null or undefined");
|
||||
}
|
||||
return await constructAndDecorateModel(parsedObject, modifiedObjectGraph, modelBuilder);
|
||||
}
|
||||
exports.parseAndBuildModel = parseAndBuildModel;
|
||||
async function constructAndDecorateModel(parsedObject, objectGraph, modelBuilder) {
|
||||
const fetchTimingMetricsBuilder = (0, dependencies_1.inject)(fetch_timing_metrics_builder_1.fetchTimingMetricsBuilderType, objectGraph);
|
||||
// Run the model builder, capturing timing points.
|
||||
const model = await fetchTimingMetricsBuilder.measureModelConstructionAsync(async () => {
|
||||
const maybePromise = modelBuilder(parsedObject, objectGraph); // The actual model, or a Promise of the model.
|
||||
return await Promise.resolve(maybePromise); // If it was promise, it will await until the promise is resolved.
|
||||
});
|
||||
if ((0, optional_1.isNothing)(model)) {
|
||||
throw new Error("model builder function returned null or undefined");
|
||||
}
|
||||
// Decorate the final output with the metrics data.
|
||||
fetchTimingMetricsBuilder.decorate(model);
|
||||
return model;
|
||||
}
|
||||
//# sourceMappingURL=parse-and-build-model.js.map
|
||||
Reference in New Issue
Block a user