@hot-updater/plugin-insights 1.0.0-rc.35 → 1.0.0-rc.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -60,7 +60,8 @@ const insights = (options = {}) => {
60
60
  appVersion,
61
61
  cohort: context.getCohort(),
62
62
  fingerprintHash: context.getFingerprintHash(),
63
- sdkVersion: context.sdkVersion
63
+ sdkVersion: context.sdkVersion,
64
+ minBundleId: context.minBundleId
64
65
  };
65
66
  const day = require_state.utcDay(now);
66
67
  return {
@@ -59,7 +59,8 @@ const insights = (options = {}) => {
59
59
  appVersion,
60
60
  cohort: context.getCohort(),
61
61
  fingerprintHash: context.getFingerprintHash(),
62
- sdkVersion: context.sdkVersion
62
+ sdkVersion: context.sdkVersion,
63
+ minBundleId: context.minBundleId
63
64
  };
64
65
  const day = utcDay(now);
65
66
  return {
@@ -1,4 +1,5 @@
1
1
  const require_eventRow = require("./eventRow.cjs");
2
+ const require_schema = require("./schema.cjs");
2
3
  let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
3
4
  //#region src/server/contract.ts
4
5
  const encoder = new TextEncoder();
@@ -30,7 +31,7 @@ const isBundleFilter = (value, withKind = false) => {
30
31
  "type",
31
32
  ...withKind ? ["kind"] : []
32
33
  ];
33
- return value.type === "RECOVERED" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, "fromBundleId"]) : (value.type === "UPDATE_DOWNLOADED" || value.type === "UPDATE_APPLIED" || value.type === "UPDATE_FAILED") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, "toBundleId"]);
34
+ return value.type === "RECOVERED" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, "fromBundleId"]) : (value.type === "UPDATE_DOWNLOADED" || value.type === "UPDATE_APPLIED" || value.type === "UPDATE_FAILED" || value.type === "UNCHANGED") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, "toBundleId"]);
34
35
  };
35
36
  const isEventFilter = (value) => {
36
37
  if (!require_eventRow.isRecord(value)) return false;
@@ -49,12 +50,15 @@ const validateRow = (model, row, result = false) => {
49
50
  };
50
51
  /** Throws `invalid-data` unless `row` is a complete, well-formed bundle event row. */
51
52
  const assertBundleEventRow = (row) => validateRow("bundle_events", row);
52
- /** Downloads, applies, recoveries, and failed updates belong in installation history. */
53
- const isInsightsMovementEvent = (event) => event.type === "UPDATE_DOWNLOADED" || event.type === "UPDATE_APPLIED" || event.type === "RECOVERED" || event.type === "UPDATE_FAILED";
53
+ /**
54
+ * Downloads, applies, recoveries, failed updates, and the UNCHANGED rows
55
+ * kept for a change belong in installation history.
56
+ */
57
+ const isInsightsMovementEvent = (event) => event.type === "UPDATE_DOWNLOADED" || event.type === "UPDATE_APPLIED" || event.type === "RECOVERED" || event.type === "UPDATE_FAILED" || event.type === "UNCHANGED";
54
58
  const matchesInsightsEventFilter = (event, filter) => {
55
59
  if (filter.kind === "all") return true;
56
60
  if (filter.kind === "installationMovement") return event.install_id === filter.installId && isInsightsMovementEvent(event);
57
- return event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && (filter.type === "RECOVERED" ? event.from_bundle_id === filter.fromBundleId : event.to_bundle_id === filter.toBundleId && event.metadata.failure?.stage !== "check");
61
+ return event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && require_schema.bundleRefsOf(event).includes(require_schema.bundleRefOfFilter(filter));
58
62
  };
59
63
  const invalidQuery = () => {
60
64
  throw new _hot_updater_plugin_core.DatabaseAdapterInputError("invalid-query");
@@ -1,4 +1,5 @@
1
1
  import { isRecord, validateBundleEventFields } from "./eventRow.mjs";
2
+ import { bundleRefOfFilter, bundleRefsOf } from "./schema.mjs";
2
3
  import { DatabaseAdapterInputError, isUUIDv7 } from "@hot-updater/plugin-core";
3
4
  //#region src/server/contract.ts
4
5
  const encoder = new TextEncoder();
@@ -30,7 +31,7 @@ const isBundleFilter = (value, withKind = false) => {
30
31
  "type",
31
32
  ...withKind ? ["kind"] : []
32
33
  ];
33
- return value.type === "RECOVERED" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, "fromBundleId"]) : (value.type === "UPDATE_DOWNLOADED" || value.type === "UPDATE_APPLIED" || value.type === "UPDATE_FAILED") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, "toBundleId"]);
34
+ return value.type === "RECOVERED" ? isText(value.fromBundleId) && hasOnlyKeys(value, [...keys, "fromBundleId"]) : (value.type === "UPDATE_DOWNLOADED" || value.type === "UPDATE_APPLIED" || value.type === "UPDATE_FAILED" || value.type === "UNCHANGED") && isText(value.toBundleId) && hasOnlyKeys(value, [...keys, "toBundleId"]);
34
35
  };
35
36
  const isEventFilter = (value) => {
36
37
  if (!isRecord(value)) return false;
@@ -49,12 +50,15 @@ const validateRow = (model, row, result = false) => {
49
50
  };
50
51
  /** Throws `invalid-data` unless `row` is a complete, well-formed bundle event row. */
51
52
  const assertBundleEventRow = (row) => validateRow("bundle_events", row);
52
- /** Downloads, applies, recoveries, and failed updates belong in installation history. */
53
- const isInsightsMovementEvent = (event) => event.type === "UPDATE_DOWNLOADED" || event.type === "UPDATE_APPLIED" || event.type === "RECOVERED" || event.type === "UPDATE_FAILED";
53
+ /**
54
+ * Downloads, applies, recoveries, failed updates, and the UNCHANGED rows
55
+ * kept for a change belong in installation history.
56
+ */
57
+ const isInsightsMovementEvent = (event) => event.type === "UPDATE_DOWNLOADED" || event.type === "UPDATE_APPLIED" || event.type === "RECOVERED" || event.type === "UPDATE_FAILED" || event.type === "UNCHANGED";
54
58
  const matchesInsightsEventFilter = (event, filter) => {
55
59
  if (filter.kind === "all") return true;
56
60
  if (filter.kind === "installationMovement") return event.install_id === filter.installId && isInsightsMovementEvent(event);
57
- return event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && (filter.type === "RECOVERED" ? event.from_bundle_id === filter.fromBundleId : event.to_bundle_id === filter.toBundleId && event.metadata.failure?.stage !== "check");
61
+ return event.type === filter.type && event.platform === filter.platform && event.channel === filter.channel && bundleRefsOf(event).includes(bundleRefOfFilter(filter));
58
62
  };
59
63
  const invalidQuery = () => {
60
64
  throw new DatabaseAdapterInputError("invalid-query");
@@ -1,4 +1,4 @@
1
- import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, DatabaseBundleEventMetadata } from "./eventRow.cjs";
1
+ import { BundleEventChangeKind, BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, DatabaseBundleEventMetadata } from "./eventRow.cjs";
2
2
  import { InsightsScope } from "./modelTypes.cjs";
3
3
  import { UpdateHttpResponse } from "@hot-updater/protocol";
4
4
  //#region src/server/domain.d.ts
@@ -44,6 +44,12 @@ type CreateBundleEventRequestBase = {
44
44
  readonly cohort: string;
45
45
  readonly fingerprintHash: string | null;
46
46
  readonly sdkVersion?: string | null;
47
+ /**
48
+ * The bundle ID the native build ships as its built-in bundle. A report
49
+ * whose running bundle is this one, with no Release, runs the built-in
50
+ * bundle. Older SDKs leave it out.
51
+ */
52
+ readonly minBundleId?: string | null;
47
53
  readonly fromReleaseId: string | null;
48
54
  readonly toReleaseId: string | null;
49
55
  };
@@ -76,9 +82,27 @@ type CreateBundleEventRequest = (Movement & {
76
82
  readonly updateStrategy: null;
77
83
  });
78
84
  type ActiveInstallationWindow = "24h" | "7d" | "30d";
85
+ /**
86
+ * What a kept UNCHANGED report changed against its installation's previous
87
+ * report: the running bundle or release, the app version, or the channel,
88
+ * with the previous values; `first_seen` alone for an installation's first
89
+ * report to this server.
90
+ */
91
+ type EventHistoryChange = {
92
+ readonly kinds: readonly BundleEventChangeKind[];
93
+ readonly previous?: {
94
+ readonly bundleId: string;
95
+ readonly releaseId: string | null;
96
+ readonly appVersion: string;
97
+ readonly channel: string;
98
+ readonly minBundleId?: string;
99
+ };
100
+ };
79
101
  type EventHistoryRow = {
80
102
  readonly toReleaseId?: string;
81
103
  readonly sdkVersion?: string;
104
+ /** The native build's built-in bundle ID, when the SDK reported it. */
105
+ readonly minBundleId?: string;
82
106
  readonly id: string;
83
107
  readonly installId: string;
84
108
  readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED" | "UNCHANGED";
@@ -97,16 +121,28 @@ type EventHistoryRow = {
97
121
  readonly delivery?: NonNullable<DatabaseBundleEventMetadata["delivery"]>;
98
122
  /** `UPDATE_DOWNLOADED`: a patch failed, and the files or the archive came instead. */
99
123
  readonly patchFallback?: true;
124
+ /** `UNCHANGED`: what the report changed, the reason it was kept. */
125
+ readonly change?: EventHistoryChange;
126
+ /** A download or apply that arrived after its target already ran: it counted nothing. */
127
+ readonly late?: true;
128
+ /** A launch or crash whose download report never arrived, counted with it. */
129
+ readonly impliedDownload?: true;
100
130
  };
101
- type InstallationHistoryRow = EventHistoryRow & {
131
+ type InstallationHistoryRow = EventHistoryRow & ({
102
132
  readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED";
103
133
  readonly fromBundleId: string;
104
- };
134
+ } | {
135
+ readonly type: "UNCHANGED";
136
+ readonly fromBundleId: null;
137
+ readonly change: EventHistoryChange;
138
+ });
105
139
  type InsightsHttpResponse = UpdateHttpResponse & {
106
140
  readonly receivedAtMs: number;
107
141
  };
108
142
  type InstallationRow = {
109
143
  readonly httpResponse?: InsightsHttpResponse;
144
+ /** The native build's built-in bundle ID, when the SDK reported it. */
145
+ readonly minBundleId?: string;
110
146
  readonly installId: string;
111
147
  readonly userId: string | null;
112
148
  readonly lastKnownBundleId: string;
@@ -150,4 +186,4 @@ type ReportingOverview = InsightsScope & {
150
186
  };
151
187
  };
152
188
  //#endregion
153
- export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview };
189
+ export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryChange, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview };
@@ -1,4 +1,4 @@
1
- import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, DatabaseBundleEventMetadata } from "./eventRow.mjs";
1
+ import { BundleEventChangeKind, BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, DatabaseBundleEventMetadata } from "./eventRow.mjs";
2
2
  import { InsightsScope } from "./modelTypes.mjs";
3
3
  import { UpdateHttpResponse } from "@hot-updater/protocol";
4
4
  //#region src/server/domain.d.ts
@@ -44,6 +44,12 @@ type CreateBundleEventRequestBase = {
44
44
  readonly cohort: string;
45
45
  readonly fingerprintHash: string | null;
46
46
  readonly sdkVersion?: string | null;
47
+ /**
48
+ * The bundle ID the native build ships as its built-in bundle. A report
49
+ * whose running bundle is this one, with no Release, runs the built-in
50
+ * bundle. Older SDKs leave it out.
51
+ */
52
+ readonly minBundleId?: string | null;
47
53
  readonly fromReleaseId: string | null;
48
54
  readonly toReleaseId: string | null;
49
55
  };
@@ -76,9 +82,27 @@ type CreateBundleEventRequest = (Movement & {
76
82
  readonly updateStrategy: null;
77
83
  });
78
84
  type ActiveInstallationWindow = "24h" | "7d" | "30d";
85
+ /**
86
+ * What a kept UNCHANGED report changed against its installation's previous
87
+ * report: the running bundle or release, the app version, or the channel,
88
+ * with the previous values; `first_seen` alone for an installation's first
89
+ * report to this server.
90
+ */
91
+ type EventHistoryChange = {
92
+ readonly kinds: readonly BundleEventChangeKind[];
93
+ readonly previous?: {
94
+ readonly bundleId: string;
95
+ readonly releaseId: string | null;
96
+ readonly appVersion: string;
97
+ readonly channel: string;
98
+ readonly minBundleId?: string;
99
+ };
100
+ };
79
101
  type EventHistoryRow = {
80
102
  readonly toReleaseId?: string;
81
103
  readonly sdkVersion?: string;
104
+ /** The native build's built-in bundle ID, when the SDK reported it. */
105
+ readonly minBundleId?: string;
82
106
  readonly id: string;
83
107
  readonly installId: string;
84
108
  readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED" | "UNCHANGED";
@@ -97,16 +121,28 @@ type EventHistoryRow = {
97
121
  readonly delivery?: NonNullable<DatabaseBundleEventMetadata["delivery"]>;
98
122
  /** `UPDATE_DOWNLOADED`: a patch failed, and the files or the archive came instead. */
99
123
  readonly patchFallback?: true;
124
+ /** `UNCHANGED`: what the report changed, the reason it was kept. */
125
+ readonly change?: EventHistoryChange;
126
+ /** A download or apply that arrived after its target already ran: it counted nothing. */
127
+ readonly late?: true;
128
+ /** A launch or crash whose download report never arrived, counted with it. */
129
+ readonly impliedDownload?: true;
100
130
  };
101
- type InstallationHistoryRow = EventHistoryRow & {
131
+ type InstallationHistoryRow = EventHistoryRow & ({
102
132
  readonly type: "UPDATE_DOWNLOADED" | "UPDATE_APPLIED" | "RECOVERED" | "UPDATE_FAILED";
103
133
  readonly fromBundleId: string;
104
- };
134
+ } | {
135
+ readonly type: "UNCHANGED";
136
+ readonly fromBundleId: null;
137
+ readonly change: EventHistoryChange;
138
+ });
105
139
  type InsightsHttpResponse = UpdateHttpResponse & {
106
140
  readonly receivedAtMs: number;
107
141
  };
108
142
  type InstallationRow = {
109
143
  readonly httpResponse?: InsightsHttpResponse;
144
+ /** The native build's built-in bundle ID, when the SDK reported it. */
145
+ readonly minBundleId?: string;
110
146
  readonly installId: string;
111
147
  readonly userId: string | null;
112
148
  readonly lastKnownBundleId: string;
@@ -150,4 +186,4 @@ type ReportingOverview = InsightsScope & {
150
186
  };
151
187
  };
152
188
  //#endregion
153
- export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview };
189
+ export { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryChange, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview };
@@ -31,6 +31,11 @@ function readEventId(payload) {
31
31
  if (!(0, _hot_updater_plugin_core.isUUIDv7)(value)) throw new require_errors.InsightsBadRequestError("Invalid event field: eventId");
32
32
  return value;
33
33
  }
34
+ /**
35
+ * The native build's built-in bundle ID: a bundle ID's length at most, and
36
+ * left out when it is missing or malformed, so the report still records.
37
+ */
38
+ const readMinBundleId = (value) => typeof value === "string" && value.length > 0 && value.length <= 36 ? value : null;
34
39
  /** One value of an open set: any other value reads as `unknown`. */
35
40
  const oneOf = (values, value) => values.includes(value) ? value : "unknown";
36
41
  const STAGES = [
@@ -156,6 +161,7 @@ function requireEvent(payload) {
156
161
  cohort: requireStringField(payload, "cohort"),
157
162
  fingerprintHash: requireNullableStringField(payload, "fingerprintHash"),
158
163
  sdkVersion: payload.sdkVersion === void 0 ? null : requireNullableStringField(payload, "sdkVersion"),
164
+ minBundleId: readMinBundleId(payload.minBundleId),
159
165
  fromReleaseId: requireNullableStringField(payload, "fromReleaseId"),
160
166
  toReleaseId: requireNullableStringField(payload, "toReleaseId")
161
167
  };
@@ -237,6 +243,7 @@ function createBundleEventRow(input) {
237
243
  cohort: input.cohort,
238
244
  fingerprint_hash: input.fingerprintHash,
239
245
  sdk_version: input.sdkVersion ?? null,
246
+ ...input.minBundleId ? { min_bundle_id: input.minBundleId } : {},
240
247
  update_strategy: input.updateStrategy
241
248
  };
242
249
  switch (input.type) {
@@ -31,6 +31,11 @@ function readEventId(payload) {
31
31
  if (!isUUIDv7(value)) throw new InsightsBadRequestError("Invalid event field: eventId");
32
32
  return value;
33
33
  }
34
+ /**
35
+ * The native build's built-in bundle ID: a bundle ID's length at most, and
36
+ * left out when it is missing or malformed, so the report still records.
37
+ */
38
+ const readMinBundleId = (value) => typeof value === "string" && value.length > 0 && value.length <= 36 ? value : null;
34
39
  /** One value of an open set: any other value reads as `unknown`. */
35
40
  const oneOf = (values, value) => values.includes(value) ? value : "unknown";
36
41
  const STAGES = [
@@ -156,6 +161,7 @@ function requireEvent(payload) {
156
161
  cohort: requireStringField(payload, "cohort"),
157
162
  fingerprintHash: requireNullableStringField(payload, "fingerprintHash"),
158
163
  sdkVersion: payload.sdkVersion === void 0 ? null : requireNullableStringField(payload, "sdkVersion"),
164
+ minBundleId: readMinBundleId(payload.minBundleId),
159
165
  fromReleaseId: requireNullableStringField(payload, "fromReleaseId"),
160
166
  toReleaseId: requireNullableStringField(payload, "toReleaseId")
161
167
  };
@@ -237,6 +243,7 @@ function createBundleEventRow(input) {
237
243
  cohort: input.cohort,
238
244
  fingerprint_hash: input.fingerprintHash,
239
245
  sdk_version: input.sdkVersion ?? null,
246
+ ...input.minBundleId ? { min_bundle_id: input.minBundleId } : {},
240
247
  update_strategy: input.updateStrategy
241
248
  };
242
249
  switch (input.type) {
@@ -1,12 +1,32 @@
1
1
  let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
2
2
  //#region src/server/eventRow.ts
3
+ const CHANGE_KINDS = /* @__PURE__ */ new Set([
4
+ "first_seen",
5
+ "bundle",
6
+ "release",
7
+ "app_version",
8
+ "channel",
9
+ "native_build"
10
+ ]);
11
+ const isBundleEventChange = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && Array.isArray(value.kinds) && value.kinds.length > 0 && value.kinds.every((kind) => CHANGE_KINDS.has(kind)) && (value.previous === null || (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value.previous) && typeof value.previous.bundle_id === "string" && (value.previous.release_id === null || typeof value.previous.release_id === "string") && typeof value.previous.app_version === "string" && typeof value.previous.channel === "string" && isOptional(value.previous, "min_bundle_id", isString));
3
12
  const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);
4
13
  const isString = (value) => typeof value === "string";
5
14
  const isDatabaseHttpResponse = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && (value.resource === "catalog" || value.resource === "artifact") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === "boolean" && Number.isSafeInteger(value.received_at_ms);
6
15
  /** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
7
16
  const isDatabaseBundleEventFailure = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString);
8
- const isDatabaseBundleEventMetadata = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean");
17
+ const isDatabaseBundleEventMetadata = (value) => (0, _hot_updater_plugin_core.isDatabaseJsonObject)(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "min_bundle_id", isString) && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "change", isBundleEventChange) && isOptional(value, "late", (flag) => flag === true) && isOptional(value, "implied_download", (flag) => flag === true);
9
18
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
19
+ /**
20
+ * The built-in bundle a report says its installation runs: the running
21
+ * bundle, which a download leaves at its source, when it is the native
22
+ * build's built-in bundle, whatever Release selected it. Null for any other
23
+ * bundle, and for a report without the build's built-in bundle ID.
24
+ */
25
+ const runningBuiltinBundleId = (row) => {
26
+ const running = row.type === "UPDATE_DOWNLOADED" ? row.from_bundle_id : row.to_bundle_id;
27
+ const builtin = isRecord(row.metadata) ? row.metadata.min_bundle_id : null;
28
+ return typeof builtin === "string" && running === builtin ? builtin : null;
29
+ };
10
30
  const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
11
31
  const isTextOrNull = (value) => value === null || typeof value === "string";
12
32
  /** Each bundle event field and what it holds. */
@@ -25,13 +45,14 @@ const BUNDLE_EVENT_FIELDS = {
25
45
  metadata: isDatabaseBundleEventMetadata,
26
46
  received_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0
27
47
  };
48
+ const hasMetadata = (row, key) => isRecord(row.metadata) && Object.hasOwn(row.metadata, key);
28
49
  const updateStrategyOf = (row) => isRecord(row.metadata) ? row.metadata.update_strategy : void 0;
29
50
  /**
30
51
  * A movement, or a failed update, names the bundle it left and how the
31
52
  * device updates, and a failed update says what failed; an unchanged report
32
53
  * names neither.
33
54
  */
34
- const hasEventInvariants = (row) => (row.type === "UPDATE_DOWNLOADED" || row.type === "UPDATE_APPLIED" || row.type === "RECOVERED" || row.type === "UPDATE_FAILED") && typeof row.from_bundle_id === "string" && (updateStrategyOf(row) === "fingerprint" || updateStrategyOf(row) === "appVersion") && (row.type !== "UPDATE_FAILED" || isRecord(row.metadata) && isRecord(row.metadata.failure)) || row.type === "UNCHANGED" && row.from_bundle_id === null && updateStrategyOf(row) === null;
55
+ const hasEventInvariants = (row) => (row.type === "UPDATE_DOWNLOADED" || row.type === "UPDATE_APPLIED" || row.type === "RECOVERED" || row.type === "UPDATE_FAILED") && typeof row.from_bundle_id === "string" && (updateStrategyOf(row) === "fingerprint" || updateStrategyOf(row) === "appVersion") && (row.type !== "UPDATE_FAILED" || isRecord(row.metadata) && isRecord(row.metadata.failure)) && !hasMetadata(row, "change") && (!hasMetadata(row, "late") || row.type === "UPDATE_DOWNLOADED" || row.type === "UPDATE_APPLIED") && (!hasMetadata(row, "implied_download") || row.type === "UPDATE_APPLIED" || row.type === "RECOVERED") || row.type === "UNCHANGED" && !hasMetadata(row, "late") && row.from_bundle_id === null && updateStrategyOf(row) === null;
35
56
  /**
36
57
  * Throws unless `row` has exactly the bundle event fields, each of its type,
37
58
  * and the invariants of its event type: `invalid-field` for an unknown field,
@@ -46,4 +67,5 @@ const validateBundleEventFields = (row) => {
46
67
  //#endregion
47
68
  exports.isDatabaseBundleEventMetadata = isDatabaseBundleEventMetadata;
48
69
  exports.isRecord = isRecord;
70
+ exports.runningBuiltinBundleId = runningBuiltinBundleId;
49
71
  exports.validateBundleEventFields = validateBundleEventFields;
@@ -25,12 +25,33 @@ type DatabaseHttpResponse = DatabaseJsonObject & {
25
25
  readonly body_truncated: boolean;
26
26
  readonly received_at_ms: number;
27
27
  };
28
+ /** What a kept UNCHANGED row changed against its installation's head. */
29
+ type BundleEventChangeKind = "first_seen" | "bundle" | "release" | "app_version" | "channel" | "native_build";
30
+ /**
31
+ * An UNCHANGED report the server keeps: what it changed against its
32
+ * installation's head, and the running values the head held before it. A
33
+ * report from an installation without a head is `first_seen` alone, with no
34
+ * previous values: the installation is new to this server, not necessarily
35
+ * to its device.
36
+ */
37
+ type BundleEventChange = DatabaseJsonObject & {
38
+ readonly kinds: BundleEventChangeKind[];
39
+ readonly previous: (DatabaseJsonObject & {
40
+ readonly bundle_id: string;
41
+ readonly release_id: string | null;
42
+ readonly app_version: string;
43
+ readonly channel: string;
44
+ readonly min_bundle_id?: string;
45
+ }) | null;
46
+ };
28
47
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
29
48
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
30
49
  readonly cohort: string;
31
50
  readonly update_strategy: "fingerprint" | "appVersion" | null;
32
51
  readonly fingerprint_hash: string | null;
33
52
  readonly sdk_version: string | null;
53
+ /** The native build's built-in bundle ID, when the SDK reports it. */
54
+ readonly min_bundle_id?: string;
34
55
  /** `UPDATE_FAILED`: what failed. */
35
56
  readonly failure?: BundleEventFailure;
36
57
  readonly http_response?: DatabaseHttpResponse;
@@ -38,6 +59,19 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
38
59
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
39
60
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
40
61
  readonly patch_fallback?: boolean;
62
+ /** A kept `UNCHANGED` row: what it changed, which the server sets. */
63
+ readonly change?: BundleEventChange;
64
+ /**
65
+ * A download or apply that arrived after its installation already ran its
66
+ * target, as when a reload cut the first runtime's report short: the
67
+ * server keeps it in history, but it moves and counts nothing.
68
+ */
69
+ readonly late?: true;
70
+ /**
71
+ * A launch or crash of a bundle whose download report never arrived: the
72
+ * server counted that download with it.
73
+ */
74
+ readonly implied_download?: true;
41
75
  };
42
76
  type BundleEventRowBase = {
43
77
  readonly id: string;
@@ -68,4 +102,4 @@ type BundleEventRow = BundleEventRowBase & ({
68
102
  readonly from_bundle_id: null;
69
103
  });
70
104
  //#endregion
71
- export { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata, DatabaseHttpResponse };
105
+ export { BundleEventChange, BundleEventChangeKind, BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata, DatabaseHttpResponse };
@@ -25,12 +25,33 @@ type DatabaseHttpResponse = DatabaseJsonObject & {
25
25
  readonly body_truncated: boolean;
26
26
  readonly received_at_ms: number;
27
27
  };
28
+ /** What a kept UNCHANGED row changed against its installation's head. */
29
+ type BundleEventChangeKind = "first_seen" | "bundle" | "release" | "app_version" | "channel" | "native_build";
30
+ /**
31
+ * An UNCHANGED report the server keeps: what it changed against its
32
+ * installation's head, and the running values the head held before it. A
33
+ * report from an installation without a head is `first_seen` alone, with no
34
+ * previous values: the installation is new to this server, not necessarily
35
+ * to its device.
36
+ */
37
+ type BundleEventChange = DatabaseJsonObject & {
38
+ readonly kinds: BundleEventChangeKind[];
39
+ readonly previous: (DatabaseJsonObject & {
40
+ readonly bundle_id: string;
41
+ readonly release_id: string | null;
42
+ readonly app_version: string;
43
+ readonly channel: string;
44
+ readonly min_bundle_id?: string;
45
+ }) | null;
46
+ };
28
47
  /** Ancillary report data; queryable identity and lifecycle fields stay on the row. */
29
48
  type DatabaseBundleEventMetadata = DatabaseJsonObject & {
30
49
  readonly cohort: string;
31
50
  readonly update_strategy: "fingerprint" | "appVersion" | null;
32
51
  readonly fingerprint_hash: string | null;
33
52
  readonly sdk_version: string | null;
53
+ /** The native build's built-in bundle ID, when the SDK reports it. */
54
+ readonly min_bundle_id?: string;
34
55
  /** `UPDATE_FAILED`: what failed. */
35
56
  readonly failure?: BundleEventFailure;
36
57
  readonly http_response?: DatabaseHttpResponse;
@@ -38,6 +59,19 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
38
59
  readonly delivery?: "patch" | "manifest" | "archive" | "unknown";
39
60
  /** `UPDATE_DOWNLOADED`: a patch failed and the full files came instead. */
40
61
  readonly patch_fallback?: boolean;
62
+ /** A kept `UNCHANGED` row: what it changed, which the server sets. */
63
+ readonly change?: BundleEventChange;
64
+ /**
65
+ * A download or apply that arrived after its installation already ran its
66
+ * target, as when a reload cut the first runtime's report short: the
67
+ * server keeps it in history, but it moves and counts nothing.
68
+ */
69
+ readonly late?: true;
70
+ /**
71
+ * A launch or crash of a bundle whose download report never arrived: the
72
+ * server counted that download with it.
73
+ */
74
+ readonly implied_download?: true;
41
75
  };
42
76
  type BundleEventRowBase = {
43
77
  readonly id: string;
@@ -68,4 +102,4 @@ type BundleEventRow = BundleEventRowBase & ({
68
102
  readonly from_bundle_id: null;
69
103
  });
70
104
  //#endregion
71
- export { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata, DatabaseHttpResponse };
105
+ export { BundleEventChange, BundleEventChangeKind, BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata, DatabaseHttpResponse };
@@ -1,12 +1,32 @@
1
1
  import { DatabaseAdapterInputError, isDatabaseJsonObject } from "@hot-updater/plugin-core";
2
2
  //#region src/server/eventRow.ts
3
+ const CHANGE_KINDS = /* @__PURE__ */ new Set([
4
+ "first_seen",
5
+ "bundle",
6
+ "release",
7
+ "app_version",
8
+ "channel",
9
+ "native_build"
10
+ ]);
11
+ const isBundleEventChange = (value) => isDatabaseJsonObject(value) && Array.isArray(value.kinds) && value.kinds.length > 0 && value.kinds.every((kind) => CHANGE_KINDS.has(kind)) && (value.previous === null || isDatabaseJsonObject(value.previous) && typeof value.previous.bundle_id === "string" && (value.previous.release_id === null || typeof value.previous.release_id === "string") && typeof value.previous.app_version === "string" && typeof value.previous.channel === "string" && isOptional(value.previous, "min_bundle_id", isString));
3
12
  const isOptional = (value, key, valid) => !Object.hasOwn(value, key) || valid(value[key]);
4
13
  const isString = (value) => typeof value === "string";
5
14
  const isDatabaseHttpResponse = (value) => isDatabaseJsonObject(value) && (value.resource === "catalog" || value.resource === "artifact") && isString(value.path) && Number.isSafeInteger(value.status) && (value.body === null || isString(value.body)) && typeof value.body_truncated === "boolean" && Number.isSafeInteger(value.received_at_ms);
6
15
  /** An `UPDATE_FAILED` report's stored failure: a stage and a reason, and what else the client knew. */
7
16
  const isDatabaseBundleEventFailure = (value) => isDatabaseJsonObject(value) && isString(value.stage) && isString(value.reason) && isOptional(value, "resource", isString) && isOptional(value, "http_status", (status) => Number.isSafeInteger(status)) && isOptional(value, "transport", isString) && isOptional(value, "origin_code", isString) && isOptional(value, "error_message", isString) && isOptional(value, "error_stack", isString);
8
- const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean");
17
+ const isDatabaseBundleEventMetadata = (value) => isDatabaseJsonObject(value) && typeof value.cohort === "string" && (value.update_strategy === null || value.update_strategy === "fingerprint" || value.update_strategy === "appVersion") && (value.fingerprint_hash === null || typeof value.fingerprint_hash === "string") && (value.sdk_version === null || typeof value.sdk_version === "string") && isOptional(value, "min_bundle_id", isString) && isOptional(value, "failure", isDatabaseBundleEventFailure) && isOptional(value, "http_response", isDatabaseHttpResponse) && isOptional(value, "delivery", isString) && isOptional(value, "patch_fallback", (flag) => typeof flag === "boolean") && isOptional(value, "change", isBundleEventChange) && isOptional(value, "late", (flag) => flag === true) && isOptional(value, "implied_download", (flag) => flag === true);
9
18
  const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
19
+ /**
20
+ * The built-in bundle a report says its installation runs: the running
21
+ * bundle, which a download leaves at its source, when it is the native
22
+ * build's built-in bundle, whatever Release selected it. Null for any other
23
+ * bundle, and for a report without the build's built-in bundle ID.
24
+ */
25
+ const runningBuiltinBundleId = (row) => {
26
+ const running = row.type === "UPDATE_DOWNLOADED" ? row.from_bundle_id : row.to_bundle_id;
27
+ const builtin = isRecord(row.metadata) ? row.metadata.min_bundle_id : null;
28
+ return typeof builtin === "string" && running === builtin ? builtin : null;
29
+ };
10
30
  const isIdentity = (value) => typeof value === "string" && value.length > 0 && value.length <= 255;
11
31
  const isTextOrNull = (value) => value === null || typeof value === "string";
12
32
  /** Each bundle event field and what it holds. */
@@ -25,13 +45,14 @@ const BUNDLE_EVENT_FIELDS = {
25
45
  metadata: isDatabaseBundleEventMetadata,
26
46
  received_at_ms: (value) => typeof value === "number" && Number.isSafeInteger(value) && value >= 0
27
47
  };
48
+ const hasMetadata = (row, key) => isRecord(row.metadata) && Object.hasOwn(row.metadata, key);
28
49
  const updateStrategyOf = (row) => isRecord(row.metadata) ? row.metadata.update_strategy : void 0;
29
50
  /**
30
51
  * A movement, or a failed update, names the bundle it left and how the
31
52
  * device updates, and a failed update says what failed; an unchanged report
32
53
  * names neither.
33
54
  */
34
- const hasEventInvariants = (row) => (row.type === "UPDATE_DOWNLOADED" || row.type === "UPDATE_APPLIED" || row.type === "RECOVERED" || row.type === "UPDATE_FAILED") && typeof row.from_bundle_id === "string" && (updateStrategyOf(row) === "fingerprint" || updateStrategyOf(row) === "appVersion") && (row.type !== "UPDATE_FAILED" || isRecord(row.metadata) && isRecord(row.metadata.failure)) || row.type === "UNCHANGED" && row.from_bundle_id === null && updateStrategyOf(row) === null;
55
+ const hasEventInvariants = (row) => (row.type === "UPDATE_DOWNLOADED" || row.type === "UPDATE_APPLIED" || row.type === "RECOVERED" || row.type === "UPDATE_FAILED") && typeof row.from_bundle_id === "string" && (updateStrategyOf(row) === "fingerprint" || updateStrategyOf(row) === "appVersion") && (row.type !== "UPDATE_FAILED" || isRecord(row.metadata) && isRecord(row.metadata.failure)) && !hasMetadata(row, "change") && (!hasMetadata(row, "late") || row.type === "UPDATE_DOWNLOADED" || row.type === "UPDATE_APPLIED") && (!hasMetadata(row, "implied_download") || row.type === "UPDATE_APPLIED" || row.type === "RECOVERED") || row.type === "UNCHANGED" && !hasMetadata(row, "late") && row.from_bundle_id === null && updateStrategyOf(row) === null;
35
56
  /**
36
57
  * Throws unless `row` has exactly the bundle event fields, each of its type,
37
58
  * and the invariants of its event type: `invalid-field` for an unknown field,
@@ -44,4 +65,4 @@ const validateBundleEventFields = (row) => {
44
65
  if (!hasEventInvariants(row)) throw new DatabaseAdapterInputError("invalid-data");
45
66
  };
46
67
  //#endregion
47
- export { isDatabaseBundleEventMetadata, isRecord, validateBundleEventFields };
68
+ export { isDatabaseBundleEventMetadata, isRecord, runningBuiltinBundleId, validateBundleEventFields };
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_schema = require("./schema.cjs");
2
3
  const require_model = require("./model.cjs");
3
4
  const require_official = require("./official.cjs");
4
5
  const require_errors = require("./errors.cjs");
5
6
  const require_provider = require("./provider.cjs");
6
- const require_schema = require("./schema.cjs");
7
7
  const require_recordEvent = require("./recordEvent.cjs");
8
8
  const require_reads = require("./reads.cjs");
9
9
  const require_routes = require("./routes.cjs");
@@ -2,7 +2,7 @@ import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage,
2
2
  import { InsightsBundleEventFilter, InsightsCountEventSeriesInput, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsEventSeriesPoint, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult, InsightsGetReleaseActivityInput, InsightsGetReleaseActivityResult, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, InsightsTimeRange, ReleaseActivityMetrics, ReleaseReference } from "./modelTypes.cjs";
3
3
  import { DEFAULT_INSIGHTS_RETENTION, InsightsRetention, InsightsSchema, createInsightsSchema, insightsSchema } from "./schema.cjs";
4
4
  import { InsightsFailureBreakdown, InsightsUpdateFailures, InsightsUpdateFailuresInput } from "./reads.cjs";
5
- import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.cjs";
5
+ import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryChange, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.cjs";
6
6
  import { InsightsBadRequestError } from "./errors.cjs";
7
7
  import { createInsightsModel } from "./model.cjs";
8
8
  import { InsightsEventPageInput, InsightsInstallationEventPageInput, InsightsProvider, InsightsUserInstallationPageInput } from "./types.cjs";
@@ -284,6 +284,38 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
284
284
  readonly sort: readonly ["bucket_start_ms"];
285
285
  };
286
286
  }, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
287
+ readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
288
+ readonly channel: {
289
+ readonly type: "string";
290
+ };
291
+ readonly platform: {
292
+ readonly type: "string";
293
+ readonly maxLength: 16;
294
+ };
295
+ readonly app_version: {
296
+ readonly type: "string";
297
+ };
298
+ readonly release_id: {
299
+ readonly type: "string";
300
+ readonly maxLength: 36;
301
+ };
302
+ readonly builtin_bundle_id: {
303
+ readonly type: "string";
304
+ readonly maxLength: 36;
305
+ };
306
+ readonly bucket_start_ms: {
307
+ readonly type: "integer";
308
+ };
309
+ }, "latest_installations", {
310
+ readonly byScope: {
311
+ readonly eq: readonly ["channel", "platform"];
312
+ readonly sort: readonly ["bucket_start_ms"];
313
+ };
314
+ readonly byVersion: {
315
+ readonly eq: readonly ["channel", "platform", "app_version"];
316
+ readonly sort: readonly ["bucket_start_ms"];
317
+ };
318
+ }, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
287
319
  readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
288
320
  readonly platform: {
289
321
  readonly type: "string";
@@ -390,4 +422,4 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
390
422
  endpoints: PluginEndpoint[];
391
423
  }, {}>;
392
424
  //#endregion
393
- export { type ActiveInstallationWindow, type BundleEventFailure, type BundleEventFailureInput, type BundleEventFailureReason, type BundleEventFailureStage, type BundleEventRow, type BundleEventRowBase, type CreateBundleEventRequest, type CreateBundleEventRequestBase, type CursorPage, DEFAULT_INSIGHTS_RETENTION, type DatabaseBundleEventMetadata, type EventCursorPage, type EventHistoryRow, InsightsApi, InsightsBadRequestError, type InsightsBundleEventFilter, type InsightsBundleSelection, type InsightsCountEventSeriesInput, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsEventSeriesPoint, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type InsightsGetReleaseActivityInput, type InsightsGetReleaseActivityResult, type InsightsHttpResponse, type InsightsIdentityParts, type InsightsInstallationEventPageInput, type InsightsListEventsInput, type InsightsModel, InsightsOptions, type InsightsProvider, type InsightsRecordEventInput, type InsightsRetention, type InsightsSchema, type InsightsScope, type InsightsTimeRange, type InsightsUpdateFailures, type InsightsUpdateFailuresInput, type InsightsUserInstallationPageInput, type InstallationHistoryRow, type InstallationRow, type ReleaseActivityMetrics, type ReleaseReference, type ReportingOverview, createInsightsModel, createInsightsProvider, createInsightsSchema, insights, insightsIdentity, insightsSchema };
425
+ export { type ActiveInstallationWindow, type BundleEventFailure, type BundleEventFailureInput, type BundleEventFailureReason, type BundleEventFailureStage, type BundleEventRow, type BundleEventRowBase, type CreateBundleEventRequest, type CreateBundleEventRequestBase, type CursorPage, DEFAULT_INSIGHTS_RETENTION, type DatabaseBundleEventMetadata, type EventCursorPage, type EventHistoryChange, type EventHistoryRow, InsightsApi, InsightsBadRequestError, type InsightsBundleEventFilter, type InsightsBundleSelection, type InsightsCountEventSeriesInput, type InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsEventSeriesPoint, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type InsightsGetReleaseActivityInput, type InsightsGetReleaseActivityResult, type InsightsHttpResponse, type InsightsIdentityParts, type InsightsInstallationEventPageInput, type InsightsListEventsInput, type InsightsModel, InsightsOptions, type InsightsProvider, type InsightsRecordEventInput, type InsightsRetention, type InsightsSchema, type InsightsScope, type InsightsTimeRange, type InsightsUpdateFailures, type InsightsUpdateFailuresInput, type InsightsUserInstallationPageInput, type InstallationHistoryRow, type InstallationRow, type ReleaseActivityMetrics, type ReleaseReference, type ReportingOverview, createInsightsModel, createInsightsProvider, createInsightsSchema, insights, insightsIdentity, insightsSchema };