@hot-updater/plugin-insights 1.0.0-rc.30 → 1.0.0-rc.31
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.
- package/dist/server/contract.cjs +13 -32
- package/dist/server/contract.mjs +13 -32
- package/dist/server/index.cjs +3 -29
- package/dist/server/index.d.cts +6 -72
- package/dist/server/index.d.mts +6 -72
- package/dist/server/index.mjs +4 -30
- package/dist/server/model.cjs +2 -2
- package/dist/server/model.mjs +2 -2
- package/dist/server/modelTypes.d.cts +28 -51
- package/dist/server/modelTypes.d.mts +28 -51
- package/dist/server/overview.cjs +6 -10
- package/dist/server/overview.mjs +6 -10
- package/dist/server/reads.cjs +34 -104
- package/dist/server/reads.mjs +34 -104
- package/dist/server/recordEvent.cjs +9 -60
- package/dist/server/recordEvent.mjs +9 -60
- package/dist/server/schema.cjs +9 -87
- package/dist/server/schema.d.cts +4 -136
- package/dist/server/schema.d.mts +4 -136
- package/dist/server/schema.mjs +9 -87
- package/package.json +2 -2
package/dist/server/contract.cjs
CHANGED
|
@@ -150,42 +150,23 @@ const createValidatedInsightsModel = (model) => ({
|
|
|
150
150
|
]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();
|
|
151
151
|
return validateCount(await model.countEvents(input));
|
|
152
152
|
},
|
|
153
|
-
async
|
|
153
|
+
async countEventSeries(input) {
|
|
154
154
|
if (!require_eventRow.isRecord(input) || !hasOnlyKeys(input, [
|
|
155
|
-
"
|
|
156
|
-
"scope",
|
|
155
|
+
"filter",
|
|
157
156
|
"timeRange",
|
|
158
157
|
"intervalMs"
|
|
159
|
-
])) invalidQuery();
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (!releaseQuery && !scopeQuery) invalidQuery();
|
|
167
|
-
const result = await model.getReleaseActivity(input);
|
|
168
|
-
validateAggregateResult(result);
|
|
169
|
-
if (!Array.isArray(result.data)) invalidResult();
|
|
170
|
-
return result;
|
|
158
|
+
]) || !isBundleFilter(input.filter) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs)) invalidQuery();
|
|
159
|
+
const { start, end } = input.timeRange;
|
|
160
|
+
const { intervalMs } = input;
|
|
161
|
+
if (intervalMs === 0 || intervalMs % 36e5 !== 0 || start % 36e5 !== 0 || (end - start) % intervalMs !== 0 || end - start > 7776e6) invalidQuery();
|
|
162
|
+
const points = await model.countEventSeries(input);
|
|
163
|
+
if (!Array.isArray(points) || points.length !== (end - start) / intervalMs || points.some((point, index) => !require_eventRow.isRecord(point) || !hasOnlyKeys(point, ["startMs", "events"]) || point.startMs !== start + index * intervalMs || !isTimestamp(point.events))) invalidResult();
|
|
164
|
+
return points;
|
|
171
165
|
},
|
|
172
|
-
async
|
|
173
|
-
if (!require_eventRow.isRecord(input) || !hasOnlyKeys(input, [
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
"timeRange"
|
|
177
|
-
]) || !hasScope(input) || !isTimeRange(input.timeRange) || input.timeRange.start % 864e5 !== 0 || input.timeRange.end % 864e5 !== 0 || input.timeRange.end - input.timeRange.start > 26784e5) invalidQuery();
|
|
178
|
-
const result = await model.getDistributionHistory(input);
|
|
179
|
-
validateAggregateResult(result);
|
|
180
|
-
if (!Array.isArray(result.points)) invalidResult();
|
|
181
|
-
for (const point of result.points) {
|
|
182
|
-
if (!isTimestamp(point.startMs) || !Array.isArray(point.bundles)) invalidResult();
|
|
183
|
-
for (const bundle of point.bundles) if (!isText(bundle.appVersion) || bundle.releaseId !== null && !isText(bundle.releaseId) || ![
|
|
184
|
-
"release",
|
|
185
|
-
"builtin",
|
|
186
|
-
"unknown"
|
|
187
|
-
].includes(bundle.bundleKind) || !isTimestamp(bundle.installations)) invalidResult();
|
|
188
|
-
}
|
|
166
|
+
async getReleaseActivity(input) {
|
|
167
|
+
if (!require_eventRow.isRecord(input) || !hasOnlyKeys(input, ["releases"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();
|
|
168
|
+
const result = await model.getReleaseActivity(input);
|
|
169
|
+
if (!require_eventRow.isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !require_eventRow.isRecord(item) || !isReleaseReference(item.release) || !require_eventRow.isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.launches) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
|
|
189
170
|
return result;
|
|
190
171
|
},
|
|
191
172
|
async getAppUsage(input) {
|
package/dist/server/contract.mjs
CHANGED
|
@@ -150,42 +150,23 @@ const createValidatedInsightsModel = (model) => ({
|
|
|
150
150
|
]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();
|
|
151
151
|
return validateCount(await model.countEvents(input));
|
|
152
152
|
},
|
|
153
|
-
async
|
|
153
|
+
async countEventSeries(input) {
|
|
154
154
|
if (!isRecord(input) || !hasOnlyKeys(input, [
|
|
155
|
-
"
|
|
156
|
-
"scope",
|
|
155
|
+
"filter",
|
|
157
156
|
"timeRange",
|
|
158
157
|
"intervalMs"
|
|
159
|
-
])) invalidQuery();
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (!releaseQuery && !scopeQuery) invalidQuery();
|
|
167
|
-
const result = await model.getReleaseActivity(input);
|
|
168
|
-
validateAggregateResult(result);
|
|
169
|
-
if (!Array.isArray(result.data)) invalidResult();
|
|
170
|
-
return result;
|
|
158
|
+
]) || !isBundleFilter(input.filter) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs)) invalidQuery();
|
|
159
|
+
const { start, end } = input.timeRange;
|
|
160
|
+
const { intervalMs } = input;
|
|
161
|
+
if (intervalMs === 0 || intervalMs % 36e5 !== 0 || start % 36e5 !== 0 || (end - start) % intervalMs !== 0 || end - start > 7776e6) invalidQuery();
|
|
162
|
+
const points = await model.countEventSeries(input);
|
|
163
|
+
if (!Array.isArray(points) || points.length !== (end - start) / intervalMs || points.some((point, index) => !isRecord(point) || !hasOnlyKeys(point, ["startMs", "events"]) || point.startMs !== start + index * intervalMs || !isTimestamp(point.events))) invalidResult();
|
|
164
|
+
return points;
|
|
171
165
|
},
|
|
172
|
-
async
|
|
173
|
-
if (!isRecord(input) || !hasOnlyKeys(input, [
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
"timeRange"
|
|
177
|
-
]) || !hasScope(input) || !isTimeRange(input.timeRange) || input.timeRange.start % 864e5 !== 0 || input.timeRange.end % 864e5 !== 0 || input.timeRange.end - input.timeRange.start > 26784e5) invalidQuery();
|
|
178
|
-
const result = await model.getDistributionHistory(input);
|
|
179
|
-
validateAggregateResult(result);
|
|
180
|
-
if (!Array.isArray(result.points)) invalidResult();
|
|
181
|
-
for (const point of result.points) {
|
|
182
|
-
if (!isTimestamp(point.startMs) || !Array.isArray(point.bundles)) invalidResult();
|
|
183
|
-
for (const bundle of point.bundles) if (!isText(bundle.appVersion) || bundle.releaseId !== null && !isText(bundle.releaseId) || ![
|
|
184
|
-
"release",
|
|
185
|
-
"builtin",
|
|
186
|
-
"unknown"
|
|
187
|
-
].includes(bundle.bundleKind) || !isTimestamp(bundle.installations)) invalidResult();
|
|
188
|
-
}
|
|
166
|
+
async getReleaseActivity(input) {
|
|
167
|
+
if (!isRecord(input) || !hasOnlyKeys(input, ["releases"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();
|
|
168
|
+
const result = await model.getReleaseActivity(input);
|
|
169
|
+
if (!isRecord(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !isRecord(item) || !isReleaseReference(item.release) || !isRecord(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.launches) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
|
|
189
170
|
return result;
|
|
190
171
|
},
|
|
191
172
|
async getAppUsage(input) {
|
package/dist/server/index.cjs
CHANGED
|
@@ -18,8 +18,8 @@ const createInsightsApi = (db, now, retention) => ({
|
|
|
18
18
|
findLatestEvents: (input) => require_reads.findLatestEvents(db, input),
|
|
19
19
|
countLatestEvents: (input) => require_reads.countLatestEvents(db, input),
|
|
20
20
|
countEvents: (input) => require_reads.countEvents(db, input),
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
countEventSeries: (input) => require_reads.countEventSeries(db, input),
|
|
22
|
+
getReleaseActivity: (input) => require_reads.getReleaseActivity(db, input, now),
|
|
23
23
|
getAppUsage: (input) => require_reads.getAppUsage(db, input, now, retention),
|
|
24
24
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
25
25
|
getUpdateFailures: (input) => require_reads.getUpdateFailures(db, input, now, retention)
|
|
@@ -88,7 +88,7 @@ const insights = (options = {}) => {
|
|
|
88
88
|
const plugin = (0, _hot_updater_plugin_core.definePlugin)({
|
|
89
89
|
id: "insights",
|
|
90
90
|
namespace: false,
|
|
91
|
-
schemaVersion: "1.
|
|
91
|
+
schemaVersion: "1.2.0",
|
|
92
92
|
schema: require_schema.createInsightsSchema(retention),
|
|
93
93
|
init: ({ db, now }) => {
|
|
94
94
|
const api = createInsightsApi(db, now, retention);
|
|
@@ -103,32 +103,6 @@ const insights = (options = {}) => {
|
|
|
103
103
|
handler: (request, params) => routes[handler](params, request)
|
|
104
104
|
})),
|
|
105
105
|
failuresEndpoint(api),
|
|
106
|
-
{
|
|
107
|
-
access: "admin",
|
|
108
|
-
method: "GET",
|
|
109
|
-
path: "/distribution-history",
|
|
110
|
-
handler: async (request) => {
|
|
111
|
-
const query = new URL(request.url).searchParams;
|
|
112
|
-
try {
|
|
113
|
-
const result = await require_model.createInsightsModel(api).getDistributionHistory({
|
|
114
|
-
platform: query.get("platform"),
|
|
115
|
-
channel: query.get("channel") ?? "",
|
|
116
|
-
timeRange: {
|
|
117
|
-
start: Number(query.get("start") ?? NaN),
|
|
118
|
-
end: Number(query.get("end") ?? NaN)
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
return Response.json(result, { headers: { "cache-control": "private, no-store" } });
|
|
122
|
-
} catch (error) {
|
|
123
|
-
if (error instanceof _hot_updater_plugin_core.DatabaseAdapterInputError) return Response.json({ error: "Choose a platform, channel, and up to 31 whole UTC days." }, { status: 400 });
|
|
124
|
-
if (!(0, _hot_updater_plugin_core.isDatabaseBusyError)(error)) throw error;
|
|
125
|
-
return Response.json({ error: "Service unavailable" }, {
|
|
126
|
-
status: 503,
|
|
127
|
-
headers: { "retry-after": "5" }
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
106
|
{
|
|
133
107
|
access: "admin",
|
|
134
108
|
method: "GET",
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata } from "./eventRow.cjs";
|
|
2
|
-
import { InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult,
|
|
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
5
|
import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.cjs";
|
|
@@ -19,8 +19,8 @@ declare const createInsightsApi: (db: HotUpdaterDatabase<InsightsSchema>, now: (
|
|
|
19
19
|
findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
|
|
20
20
|
countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
|
|
21
21
|
countEvents: (input: InsightsCountEventsInput) => Promise<number>;
|
|
22
|
+
countEventSeries: (input: InsightsCountEventSeriesInput) => Promise<readonly InsightsEventSeriesPoint[]>;
|
|
22
23
|
getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
|
|
23
|
-
getDistributionHistory: (input: InsightsGetDistributionHistoryInput) => Promise<InsightsGetDistributionHistoryResult>;
|
|
24
24
|
getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
|
|
25
25
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
26
26
|
getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
|
|
@@ -100,10 +100,6 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
100
100
|
movement_install_id: "string";
|
|
101
101
|
bundle_ref: "string";
|
|
102
102
|
}, {
|
|
103
|
-
readonly recent: {
|
|
104
|
-
readonly eq: readonly ["channel", "platform", "day"];
|
|
105
|
-
readonly sort: readonly ["received_at_ms"];
|
|
106
|
-
};
|
|
107
103
|
readonly movementsByInstall: {
|
|
108
104
|
readonly eq: readonly ["movement_install_id"];
|
|
109
105
|
readonly sort: readonly ["received_at_ms"];
|
|
@@ -203,7 +199,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
203
199
|
readonly eq: readonly ["identity"];
|
|
204
200
|
readonly sort: readonly ["bucket_start_ms"];
|
|
205
201
|
};
|
|
206
|
-
}, "
|
|
202
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
207
203
|
readonly insights_overview_daily: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
208
204
|
readonly identity: {
|
|
209
205
|
readonly type: "string";
|
|
@@ -231,7 +227,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
231
227
|
readonly eq: readonly ["identity"];
|
|
232
228
|
readonly sort: readonly ["bucket_start_ms"];
|
|
233
229
|
};
|
|
234
|
-
}, "
|
|
230
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
235
231
|
readonly insights_overview_lifetime: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
236
232
|
readonly identity: {
|
|
237
233
|
readonly type: "string";
|
|
@@ -288,68 +284,6 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
288
284
|
readonly sort: readonly ["bucket_start_ms"];
|
|
289
285
|
};
|
|
290
286
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
291
|
-
readonly bundle_daily_heads: import("@hot-updater/plugin-core").TableDefinition<{
|
|
292
|
-
readonly install_id: {
|
|
293
|
-
readonly type: "string";
|
|
294
|
-
readonly maxLength: 255;
|
|
295
|
-
};
|
|
296
|
-
readonly bucket_start_ms: {
|
|
297
|
-
readonly type: "integer";
|
|
298
|
-
};
|
|
299
|
-
readonly id: {
|
|
300
|
-
readonly type: "string";
|
|
301
|
-
readonly maxLength: 36;
|
|
302
|
-
};
|
|
303
|
-
readonly received_at_ms: {
|
|
304
|
-
readonly type: "integer";
|
|
305
|
-
};
|
|
306
|
-
readonly channel: {
|
|
307
|
-
readonly type: "string";
|
|
308
|
-
};
|
|
309
|
-
readonly platform: {
|
|
310
|
-
readonly type: "string";
|
|
311
|
-
readonly maxLength: 16;
|
|
312
|
-
};
|
|
313
|
-
readonly app_version: {
|
|
314
|
-
readonly type: "string";
|
|
315
|
-
};
|
|
316
|
-
readonly release_id: {
|
|
317
|
-
readonly type: "string";
|
|
318
|
-
readonly maxLength: 36;
|
|
319
|
-
};
|
|
320
|
-
readonly bundle_kind: {
|
|
321
|
-
readonly type: "string";
|
|
322
|
-
readonly maxLength: 16;
|
|
323
|
-
};
|
|
324
|
-
}, Readonly<Record<string, import("@hot-updater/plugin-core").FieldType>>, {}, readonly ["install_id", "bucket_start_ms"]>;
|
|
325
|
-
readonly insights_distribution_history: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
326
|
-
readonly channel: {
|
|
327
|
-
readonly type: "string";
|
|
328
|
-
};
|
|
329
|
-
readonly platform: {
|
|
330
|
-
readonly type: "string";
|
|
331
|
-
readonly maxLength: 16;
|
|
332
|
-
};
|
|
333
|
-
readonly app_version: {
|
|
334
|
-
readonly type: "string";
|
|
335
|
-
};
|
|
336
|
-
readonly release_id: {
|
|
337
|
-
readonly type: "string";
|
|
338
|
-
readonly maxLength: 36;
|
|
339
|
-
};
|
|
340
|
-
readonly bundle_kind: {
|
|
341
|
-
readonly type: "string";
|
|
342
|
-
readonly maxLength: 16;
|
|
343
|
-
};
|
|
344
|
-
readonly bucket_start_ms: {
|
|
345
|
-
readonly type: "integer";
|
|
346
|
-
};
|
|
347
|
-
}, "installations", {
|
|
348
|
-
readonly byScope: {
|
|
349
|
-
readonly eq: readonly ["channel", "platform"];
|
|
350
|
-
readonly sort: readonly ["bucket_start_ms"];
|
|
351
|
-
};
|
|
352
|
-
}, never, readonly ["channel", "platform", "app_version", "release_id", "bundle_kind", "bucket_start_ms"]>;
|
|
353
287
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
354
288
|
readonly platform: {
|
|
355
289
|
readonly type: "string";
|
|
@@ -447,8 +381,8 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
447
381
|
findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
|
|
448
382
|
countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
|
|
449
383
|
countEvents: (input: InsightsCountEventsInput) => Promise<number>;
|
|
384
|
+
countEventSeries: (input: InsightsCountEventSeriesInput) => Promise<readonly InsightsEventSeriesPoint[]>;
|
|
450
385
|
getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
|
|
451
|
-
getDistributionHistory: (input: InsightsGetDistributionHistoryInput) => Promise<InsightsGetDistributionHistoryResult>;
|
|
452
386
|
getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
|
|
453
387
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
454
388
|
getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
|
|
@@ -456,4 +390,4 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
456
390
|
endpoints: PluginEndpoint[];
|
|
457
391
|
}, {}>;
|
|
458
392
|
//#endregion
|
|
459
|
-
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 InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type
|
|
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 };
|
package/dist/server/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BundleEventFailure, BundleEventFailureReason, BundleEventFailureStage, BundleEventRow, BundleEventRowBase, DatabaseBundleEventMetadata } from "./eventRow.mjs";
|
|
2
|
-
import { InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult,
|
|
2
|
+
import { InsightsBundleEventFilter, InsightsCountEventSeriesInput, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsEventSeriesPoint, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult, InsightsGetReleaseActivityInput, InsightsGetReleaseActivityResult, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, InsightsTimeRange, ReleaseActivityMetrics, ReleaseReference } from "./modelTypes.mjs";
|
|
3
3
|
import { DEFAULT_INSIGHTS_RETENTION, InsightsRetention, InsightsSchema, createInsightsSchema, insightsSchema } from "./schema.mjs";
|
|
4
4
|
import { InsightsFailureBreakdown, InsightsUpdateFailures, InsightsUpdateFailuresInput } from "./reads.mjs";
|
|
5
5
|
import { ActiveInstallationWindow, BundleEventFailureInput, CreateBundleEventRequest, CreateBundleEventRequestBase, CursorPage, EventCursorPage, EventHistoryRow, InsightsBundleSelection, InsightsCountMeasurement, InsightsHttpResponse, InstallationHistoryRow, InstallationRow, ReportingOverview } from "./domain.mjs";
|
|
@@ -19,8 +19,8 @@ declare const createInsightsApi: (db: HotUpdaterDatabase<InsightsSchema>, now: (
|
|
|
19
19
|
findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
|
|
20
20
|
countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
|
|
21
21
|
countEvents: (input: InsightsCountEventsInput) => Promise<number>;
|
|
22
|
+
countEventSeries: (input: InsightsCountEventSeriesInput) => Promise<readonly InsightsEventSeriesPoint[]>;
|
|
22
23
|
getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
|
|
23
|
-
getDistributionHistory: (input: InsightsGetDistributionHistoryInput) => Promise<InsightsGetDistributionHistoryResult>;
|
|
24
24
|
getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
|
|
25
25
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
26
26
|
getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
|
|
@@ -100,10 +100,6 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
100
100
|
movement_install_id: "string";
|
|
101
101
|
bundle_ref: "string";
|
|
102
102
|
}, {
|
|
103
|
-
readonly recent: {
|
|
104
|
-
readonly eq: readonly ["channel", "platform", "day"];
|
|
105
|
-
readonly sort: readonly ["received_at_ms"];
|
|
106
|
-
};
|
|
107
103
|
readonly movementsByInstall: {
|
|
108
104
|
readonly eq: readonly ["movement_install_id"];
|
|
109
105
|
readonly sort: readonly ["received_at_ms"];
|
|
@@ -203,7 +199,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
203
199
|
readonly eq: readonly ["identity"];
|
|
204
200
|
readonly sort: readonly ["bucket_start_ms"];
|
|
205
201
|
};
|
|
206
|
-
}, "
|
|
202
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
207
203
|
readonly insights_overview_daily: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
208
204
|
readonly identity: {
|
|
209
205
|
readonly type: "string";
|
|
@@ -231,7 +227,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
231
227
|
readonly eq: readonly ["identity"];
|
|
232
228
|
readonly sort: readonly ["bucket_start_ms"];
|
|
233
229
|
};
|
|
234
|
-
}, "
|
|
230
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
235
231
|
readonly insights_overview_lifetime: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
236
232
|
readonly identity: {
|
|
237
233
|
readonly type: "string";
|
|
@@ -288,68 +284,6 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
288
284
|
readonly sort: readonly ["bucket_start_ms"];
|
|
289
285
|
};
|
|
290
286
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
291
|
-
readonly bundle_daily_heads: import("@hot-updater/plugin-core").TableDefinition<{
|
|
292
|
-
readonly install_id: {
|
|
293
|
-
readonly type: "string";
|
|
294
|
-
readonly maxLength: 255;
|
|
295
|
-
};
|
|
296
|
-
readonly bucket_start_ms: {
|
|
297
|
-
readonly type: "integer";
|
|
298
|
-
};
|
|
299
|
-
readonly id: {
|
|
300
|
-
readonly type: "string";
|
|
301
|
-
readonly maxLength: 36;
|
|
302
|
-
};
|
|
303
|
-
readonly received_at_ms: {
|
|
304
|
-
readonly type: "integer";
|
|
305
|
-
};
|
|
306
|
-
readonly channel: {
|
|
307
|
-
readonly type: "string";
|
|
308
|
-
};
|
|
309
|
-
readonly platform: {
|
|
310
|
-
readonly type: "string";
|
|
311
|
-
readonly maxLength: 16;
|
|
312
|
-
};
|
|
313
|
-
readonly app_version: {
|
|
314
|
-
readonly type: "string";
|
|
315
|
-
};
|
|
316
|
-
readonly release_id: {
|
|
317
|
-
readonly type: "string";
|
|
318
|
-
readonly maxLength: 36;
|
|
319
|
-
};
|
|
320
|
-
readonly bundle_kind: {
|
|
321
|
-
readonly type: "string";
|
|
322
|
-
readonly maxLength: 16;
|
|
323
|
-
};
|
|
324
|
-
}, Readonly<Record<string, import("@hot-updater/plugin-core").FieldType>>, {}, readonly ["install_id", "bucket_start_ms"]>;
|
|
325
|
-
readonly insights_distribution_history: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
326
|
-
readonly channel: {
|
|
327
|
-
readonly type: "string";
|
|
328
|
-
};
|
|
329
|
-
readonly platform: {
|
|
330
|
-
readonly type: "string";
|
|
331
|
-
readonly maxLength: 16;
|
|
332
|
-
};
|
|
333
|
-
readonly app_version: {
|
|
334
|
-
readonly type: "string";
|
|
335
|
-
};
|
|
336
|
-
readonly release_id: {
|
|
337
|
-
readonly type: "string";
|
|
338
|
-
readonly maxLength: 36;
|
|
339
|
-
};
|
|
340
|
-
readonly bundle_kind: {
|
|
341
|
-
readonly type: "string";
|
|
342
|
-
readonly maxLength: 16;
|
|
343
|
-
};
|
|
344
|
-
readonly bucket_start_ms: {
|
|
345
|
-
readonly type: "integer";
|
|
346
|
-
};
|
|
347
|
-
}, "installations", {
|
|
348
|
-
readonly byScope: {
|
|
349
|
-
readonly eq: readonly ["channel", "platform"];
|
|
350
|
-
readonly sort: readonly ["bucket_start_ms"];
|
|
351
|
-
};
|
|
352
|
-
}, never, readonly ["channel", "platform", "app_version", "release_id", "bundle_kind", "bucket_start_ms"]>;
|
|
353
287
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
354
288
|
readonly platform: {
|
|
355
289
|
readonly type: "string";
|
|
@@ -447,8 +381,8 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
447
381
|
findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
|
|
448
382
|
countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
|
|
449
383
|
countEvents: (input: InsightsCountEventsInput) => Promise<number>;
|
|
384
|
+
countEventSeries: (input: InsightsCountEventSeriesInput) => Promise<readonly InsightsEventSeriesPoint[]>;
|
|
450
385
|
getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
|
|
451
|
-
getDistributionHistory: (input: InsightsGetDistributionHistoryInput) => Promise<InsightsGetDistributionHistoryResult>;
|
|
452
386
|
getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
|
|
453
387
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
454
388
|
getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
|
|
@@ -456,4 +390,4 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
456
390
|
endpoints: PluginEndpoint[];
|
|
457
391
|
}, {}>;
|
|
458
392
|
//#endregion
|
|
459
|
-
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 InsightsCountEventsInput, type InsightsCountLatestEventsInput, type InsightsCountMeasurement, type InsightsCoverage, type InsightsEventCursor, type InsightsEventFilter, type InsightsEventPageInput, type InsightsFailureBreakdown, type InsightsFindLatestEventsInput, type InsightsGetAppUsageInput, type InsightsGetAppUsageResult, type
|
|
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 };
|
package/dist/server/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { InsightsBadRequestError } from "./errors.mjs";
|
|
|
4
4
|
import { createInsightsProvider } from "./provider.mjs";
|
|
5
5
|
import { DEFAULT_INSIGHTS_RETENTION, createInsightsSchema, insightsSchema } from "./schema.mjs";
|
|
6
6
|
import { insightsIdentity, recordEvent } from "./recordEvent.mjs";
|
|
7
|
-
import { countEvents, countLatestEvents, findLatestEvents, getAppUsage,
|
|
7
|
+
import { countEventSeries, countEvents, countLatestEvents, findLatestEvents, getAppUsage, getReleaseActivity, getUpdateFailures, listEvents } from "./reads.mjs";
|
|
8
8
|
import { INSIGHTS_ROUTES, createInsightsRouteHandlers } from "./routes.mjs";
|
|
9
9
|
import { DatabaseAdapterInputError, HotUpdaterConfigError, definePlugin, isDatabaseBusyError } from "@hot-updater/plugin-core";
|
|
10
10
|
//#region src/server/index.ts
|
|
@@ -17,8 +17,8 @@ const createInsightsApi = (db, now, retention) => ({
|
|
|
17
17
|
findLatestEvents: (input) => findLatestEvents(db, input),
|
|
18
18
|
countLatestEvents: (input) => countLatestEvents(db, input),
|
|
19
19
|
countEvents: (input) => countEvents(db, input),
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
countEventSeries: (input) => countEventSeries(db, input),
|
|
21
|
+
getReleaseActivity: (input) => getReleaseActivity(db, input, now),
|
|
22
22
|
getAppUsage: (input) => getAppUsage(db, input, now, retention),
|
|
23
23
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
24
24
|
getUpdateFailures: (input) => getUpdateFailures(db, input, now, retention)
|
|
@@ -87,7 +87,7 @@ const insights = (options = {}) => {
|
|
|
87
87
|
const plugin = definePlugin({
|
|
88
88
|
id: "insights",
|
|
89
89
|
namespace: false,
|
|
90
|
-
schemaVersion: "1.
|
|
90
|
+
schemaVersion: "1.2.0",
|
|
91
91
|
schema: createInsightsSchema(retention),
|
|
92
92
|
init: ({ db, now }) => {
|
|
93
93
|
const api = createInsightsApi(db, now, retention);
|
|
@@ -102,32 +102,6 @@ const insights = (options = {}) => {
|
|
|
102
102
|
handler: (request, params) => routes[handler](params, request)
|
|
103
103
|
})),
|
|
104
104
|
failuresEndpoint(api),
|
|
105
|
-
{
|
|
106
|
-
access: "admin",
|
|
107
|
-
method: "GET",
|
|
108
|
-
path: "/distribution-history",
|
|
109
|
-
handler: async (request) => {
|
|
110
|
-
const query = new URL(request.url).searchParams;
|
|
111
|
-
try {
|
|
112
|
-
const result = await createInsightsModel(api).getDistributionHistory({
|
|
113
|
-
platform: query.get("platform"),
|
|
114
|
-
channel: query.get("channel") ?? "",
|
|
115
|
-
timeRange: {
|
|
116
|
-
start: Number(query.get("start") ?? NaN),
|
|
117
|
-
end: Number(query.get("end") ?? NaN)
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
return Response.json(result, { headers: { "cache-control": "private, no-store" } });
|
|
121
|
-
} catch (error) {
|
|
122
|
-
if (error instanceof DatabaseAdapterInputError) return Response.json({ error: "Choose a platform, channel, and up to 31 whole UTC days." }, { status: 400 });
|
|
123
|
-
if (!isDatabaseBusyError(error)) throw error;
|
|
124
|
-
return Response.json({ error: "Service unavailable" }, {
|
|
125
|
-
status: 503,
|
|
126
|
-
headers: { "retry-after": "5" }
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
105
|
{
|
|
132
106
|
access: "admin",
|
|
133
107
|
method: "GET",
|
package/dist/server/model.cjs
CHANGED
|
@@ -10,9 +10,9 @@ const createInsightsModel = (api) => require_contract.createValidatedInsightsMod
|
|
|
10
10
|
findLatestEvents: api.findLatestEvents,
|
|
11
11
|
countLatestEvents: api.countLatestEvents,
|
|
12
12
|
countEvents: api.countEvents,
|
|
13
|
+
countEventSeries: api.countEventSeries,
|
|
13
14
|
getReleaseActivity: api.getReleaseActivity,
|
|
14
|
-
getAppUsage: api.getAppUsage
|
|
15
|
-
getDistributionHistory: api.getDistributionHistory
|
|
15
|
+
getAppUsage: api.getAppUsage
|
|
16
16
|
});
|
|
17
17
|
//#endregion
|
|
18
18
|
exports.createInsightsModel = createInsightsModel;
|
package/dist/server/model.mjs
CHANGED
|
@@ -10,9 +10,9 @@ const createInsightsModel = (api) => createValidatedInsightsModel({
|
|
|
10
10
|
findLatestEvents: api.findLatestEvents,
|
|
11
11
|
countLatestEvents: api.countLatestEvents,
|
|
12
12
|
countEvents: api.countEvents,
|
|
13
|
+
countEventSeries: api.countEventSeries,
|
|
13
14
|
getReleaseActivity: api.getReleaseActivity,
|
|
14
|
-
getAppUsage: api.getAppUsage
|
|
15
|
-
getDistributionHistory: api.getDistributionHistory
|
|
15
|
+
getAppUsage: api.getAppUsage
|
|
16
16
|
});
|
|
17
17
|
//#endregion
|
|
18
18
|
export { createInsightsModel };
|
|
@@ -59,6 +59,19 @@ interface InsightsCountEventsInput {
|
|
|
59
59
|
readonly sinceMs: number;
|
|
60
60
|
readonly beforeReceivedAtMs: number;
|
|
61
61
|
}
|
|
62
|
+
/** One bundle filter's stored events in each interval of a time range. */
|
|
63
|
+
interface InsightsCountEventSeriesInput {
|
|
64
|
+
readonly filter: InsightsBundleEventFilter;
|
|
65
|
+
/** Whole UTC hours, at most 90 days, that a whole number of intervals fill. */
|
|
66
|
+
readonly timeRange: InsightsTimeRange;
|
|
67
|
+
/** Whole hours each point spans, from `timeRange.start`. */
|
|
68
|
+
readonly intervalMs: number;
|
|
69
|
+
}
|
|
70
|
+
/** Stored events in [startMs, startMs + intervalMs). */
|
|
71
|
+
interface InsightsEventSeriesPoint {
|
|
72
|
+
readonly startMs: number;
|
|
73
|
+
readonly events: number;
|
|
74
|
+
}
|
|
62
75
|
interface ReleaseReference {
|
|
63
76
|
readonly releaseId: string;
|
|
64
77
|
readonly platform: "ios" | "android";
|
|
@@ -77,44 +90,22 @@ type InsightsCoverage = {
|
|
|
77
90
|
readonly kind: "partial";
|
|
78
91
|
readonly sinceMs: number | null;
|
|
79
92
|
};
|
|
93
|
+
/**
|
|
94
|
+
* A release's counts since its first report, from its lifetime counters,
|
|
95
|
+
* which are kept.
|
|
96
|
+
*/
|
|
80
97
|
interface ReleaseActivityMetrics {
|
|
81
98
|
readonly downloads: number;
|
|
82
99
|
readonly launches: number;
|
|
83
100
|
readonly failedLaunches: number;
|
|
84
|
-
/** Omitted for lifetime-only bundle-row reads. */
|
|
85
|
-
readonly uniqueUsers?: number;
|
|
86
|
-
/**
|
|
87
|
-
* Points of each UTC day, or of each `intervalMs` from the period's start
|
|
88
|
-
* on a release read that asks for one; present only for period reads.
|
|
89
|
-
*/
|
|
90
|
-
readonly series?: readonly {
|
|
91
|
-
readonly startMs: number;
|
|
92
|
-
readonly downloads: number;
|
|
93
|
-
readonly launches: number;
|
|
94
|
-
readonly failedLaunches: number;
|
|
95
|
-
}[];
|
|
96
101
|
}
|
|
97
|
-
|
|
102
|
+
interface InsightsGetReleaseActivityInput {
|
|
103
|
+
/** 1 to 100 releases. */
|
|
98
104
|
readonly releases: readonly ReleaseReference[];
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Whole hours each series point spans, from `timeRange.start`, with
|
|
102
|
-
* every point present; omitted, the series has a point per UTC day
|
|
103
|
-
* with reports. Only with a `timeRange`.
|
|
104
|
-
*/
|
|
105
|
-
readonly intervalMs?: number;
|
|
106
|
-
readonly scope?: never;
|
|
107
|
-
} | {
|
|
108
|
-
readonly scope: InsightsScope;
|
|
109
|
-
readonly timeRange: InsightsTimeRange;
|
|
110
|
-
readonly intervalMs?: never;
|
|
111
|
-
readonly releases?: never;
|
|
112
|
-
};
|
|
105
|
+
}
|
|
113
106
|
interface InsightsGetReleaseActivityResult {
|
|
114
|
-
readonly coverage: InsightsCoverage;
|
|
115
107
|
readonly data: readonly {
|
|
116
|
-
readonly release
|
|
117
|
-
readonly scope?: InsightsScope;
|
|
108
|
+
readonly release: ReleaseReference;
|
|
118
109
|
readonly metrics: ReleaseActivityMetrics;
|
|
119
110
|
}[];
|
|
120
111
|
readonly measuredAtMs: number;
|
|
@@ -150,23 +141,6 @@ interface InsightsGetAppUsageResult {
|
|
|
150
141
|
}[];
|
|
151
142
|
readonly measuredAtMs: number;
|
|
152
143
|
}
|
|
153
|
-
/** Whole UTC days, at most 31, including the current unfinished day. */
|
|
154
|
-
interface InsightsGetDistributionHistoryInput extends InsightsScope {
|
|
155
|
-
readonly timeRange: InsightsTimeRange;
|
|
156
|
-
}
|
|
157
|
-
interface InsightsGetDistributionHistoryResult {
|
|
158
|
-
readonly coverage: InsightsCoverage;
|
|
159
|
-
readonly measuredAtMs: number;
|
|
160
|
-
readonly points: readonly {
|
|
161
|
-
readonly startMs: number;
|
|
162
|
-
readonly bundles: readonly {
|
|
163
|
-
readonly appVersion: string;
|
|
164
|
-
readonly releaseId: string | null;
|
|
165
|
-
readonly bundleKind: "release" | "builtin" | "unknown";
|
|
166
|
-
readonly installations: number;
|
|
167
|
-
}[];
|
|
168
|
-
}[];
|
|
169
|
-
}
|
|
170
144
|
interface InsightsModel {
|
|
171
145
|
/**
|
|
172
146
|
* Persist the immutable event once. A private latest-event index, if used,
|
|
@@ -195,12 +169,15 @@ interface InsightsModel {
|
|
|
195
169
|
countLatestEvents(input: InsightsCountLatestEventsInput): Promise<number>;
|
|
196
170
|
/** Count accepted reports in [sinceMs, beforeReceivedAtMs), across all pages. */
|
|
197
171
|
countEvents(input: InsightsCountEventsInput): Promise<number>;
|
|
198
|
-
/**
|
|
172
|
+
/**
|
|
173
|
+
* A bundle filter's stored events in each interval, every interval
|
|
174
|
+
* present in order, from the hourly counts that `countEvents` reads.
|
|
175
|
+
*/
|
|
176
|
+
countEventSeries(input: InsightsCountEventSeriesInput): Promise<readonly InsightsEventSeriesPoint[]>;
|
|
177
|
+
/** Releases' lifetime counters, without scanning raw events. */
|
|
199
178
|
getReleaseActivity(input: InsightsGetReleaseActivityInput): Promise<InsightsGetReleaseActivityResult>;
|
|
200
|
-
/** Daily last-observed running bundles, one per reporting installation. No historical backfill. */
|
|
201
|
-
getDistributionHistory(input: InsightsGetDistributionHistoryInput): Promise<InsightsGetDistributionHistoryResult>;
|
|
202
179
|
/** Read maintained App usage summaries and latest-report distribution. */
|
|
203
180
|
getAppUsage(input: InsightsGetAppUsageInput): Promise<InsightsGetAppUsageResult>;
|
|
204
181
|
}
|
|
205
182
|
//#endregion
|
|
206
|
-
export { InsightsBundleEventFilter, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult,
|
|
183
|
+
export { InsightsBundleEventFilter, InsightsCountEventSeriesInput, InsightsCountEventsInput, InsightsCountLatestEventsInput, InsightsCoverage, InsightsEventCursor, InsightsEventFilter, InsightsEventSeriesPoint, InsightsFindLatestEventsInput, InsightsGetAppUsageInput, InsightsGetAppUsageResult, InsightsGetReleaseActivityInput, InsightsGetReleaseActivityResult, InsightsListEventsInput, InsightsModel, InsightsRecordEventInput, InsightsScope, InsightsTimeRange, ReleaseActivityMetrics, ReleaseReference };
|