@hot-updater/aws 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/index.d.cts +24 -116
- package/dist/index.d.mts +24 -116
- package/dist/lambda/index.cjs +76 -323
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -200,6 +200,19 @@ interface InsightsCountEventsInput {
|
|
|
200
200
|
readonly sinceMs: number;
|
|
201
201
|
readonly beforeReceivedAtMs: number;
|
|
202
202
|
}
|
|
203
|
+
/** One bundle filter's stored events in each interval of a time range. */
|
|
204
|
+
interface InsightsCountEventSeriesInput {
|
|
205
|
+
readonly filter: InsightsBundleEventFilter;
|
|
206
|
+
/** Whole UTC hours, at most 90 days, that a whole number of intervals fill. */
|
|
207
|
+
readonly timeRange: InsightsTimeRange;
|
|
208
|
+
/** Whole hours each point spans, from `timeRange.start`. */
|
|
209
|
+
readonly intervalMs: number;
|
|
210
|
+
}
|
|
211
|
+
/** Stored events in [startMs, startMs + intervalMs). */
|
|
212
|
+
interface InsightsEventSeriesPoint {
|
|
213
|
+
readonly startMs: number;
|
|
214
|
+
readonly events: number;
|
|
215
|
+
}
|
|
203
216
|
interface ReleaseReference {
|
|
204
217
|
readonly releaseId: string;
|
|
205
218
|
readonly platform: "ios" | "android";
|
|
@@ -218,44 +231,22 @@ type InsightsCoverage = {
|
|
|
218
231
|
readonly kind: "partial";
|
|
219
232
|
readonly sinceMs: number | null;
|
|
220
233
|
};
|
|
234
|
+
/**
|
|
235
|
+
* A release's counts since its first report, from its lifetime counters,
|
|
236
|
+
* which are kept.
|
|
237
|
+
*/
|
|
221
238
|
interface ReleaseActivityMetrics {
|
|
222
239
|
readonly downloads: number;
|
|
223
240
|
readonly launches: number;
|
|
224
241
|
readonly failedLaunches: number;
|
|
225
|
-
/** Omitted for lifetime-only bundle-row reads. */
|
|
226
|
-
readonly uniqueUsers?: number;
|
|
227
|
-
/**
|
|
228
|
-
* Points of each UTC day, or of each `intervalMs` from the period's start
|
|
229
|
-
* on a release read that asks for one; present only for period reads.
|
|
230
|
-
*/
|
|
231
|
-
readonly series?: readonly {
|
|
232
|
-
readonly startMs: number;
|
|
233
|
-
readonly downloads: number;
|
|
234
|
-
readonly launches: number;
|
|
235
|
-
readonly failedLaunches: number;
|
|
236
|
-
}[];
|
|
237
242
|
}
|
|
238
|
-
|
|
243
|
+
interface InsightsGetReleaseActivityInput {
|
|
244
|
+
/** 1 to 100 releases. */
|
|
239
245
|
readonly releases: readonly ReleaseReference[];
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Whole hours each series point spans, from `timeRange.start`, with
|
|
243
|
-
* every point present; omitted, the series has a point per UTC day
|
|
244
|
-
* with reports. Only with a `timeRange`.
|
|
245
|
-
*/
|
|
246
|
-
readonly intervalMs?: number;
|
|
247
|
-
readonly scope?: never;
|
|
248
|
-
} | {
|
|
249
|
-
readonly scope: InsightsScope;
|
|
250
|
-
readonly timeRange: InsightsTimeRange;
|
|
251
|
-
readonly intervalMs?: never;
|
|
252
|
-
readonly releases?: never;
|
|
253
|
-
};
|
|
246
|
+
}
|
|
254
247
|
interface InsightsGetReleaseActivityResult {
|
|
255
|
-
readonly coverage: InsightsCoverage;
|
|
256
248
|
readonly data: readonly {
|
|
257
|
-
readonly release
|
|
258
|
-
readonly scope?: InsightsScope;
|
|
249
|
+
readonly release: ReleaseReference;
|
|
259
250
|
readonly metrics: ReleaseActivityMetrics;
|
|
260
251
|
}[];
|
|
261
252
|
readonly measuredAtMs: number;
|
|
@@ -291,23 +282,6 @@ interface InsightsGetAppUsageResult {
|
|
|
291
282
|
}[];
|
|
292
283
|
readonly measuredAtMs: number;
|
|
293
284
|
}
|
|
294
|
-
/** Whole UTC days, at most 31, including the current unfinished day. */
|
|
295
|
-
interface InsightsGetDistributionHistoryInput extends InsightsScope {
|
|
296
|
-
readonly timeRange: InsightsTimeRange;
|
|
297
|
-
}
|
|
298
|
-
interface InsightsGetDistributionHistoryResult {
|
|
299
|
-
readonly coverage: InsightsCoverage;
|
|
300
|
-
readonly measuredAtMs: number;
|
|
301
|
-
readonly points: readonly {
|
|
302
|
-
readonly startMs: number;
|
|
303
|
-
readonly bundles: readonly {
|
|
304
|
-
readonly appVersion: string;
|
|
305
|
-
readonly releaseId: string | null;
|
|
306
|
-
readonly bundleKind: "release" | "builtin" | "unknown";
|
|
307
|
-
readonly installations: number;
|
|
308
|
-
}[];
|
|
309
|
-
}[];
|
|
310
|
-
}
|
|
311
285
|
//#endregion
|
|
312
286
|
//#region ../insights/dist/server/schema.d.mts
|
|
313
287
|
//#region src/server/schema.d.ts
|
|
@@ -461,10 +435,6 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
461
435
|
movement_install_id: "string";
|
|
462
436
|
bundle_ref: "string";
|
|
463
437
|
}, {
|
|
464
|
-
readonly recent: {
|
|
465
|
-
readonly eq: readonly ["channel", "platform", "day"];
|
|
466
|
-
readonly sort: readonly ["received_at_ms"];
|
|
467
|
-
};
|
|
468
438
|
readonly movementsByInstall: {
|
|
469
439
|
readonly eq: readonly ["movement_install_id"];
|
|
470
440
|
readonly sort: readonly ["received_at_ms"];
|
|
@@ -564,7 +534,7 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
564
534
|
readonly eq: readonly ["identity"];
|
|
565
535
|
readonly sort: readonly ["bucket_start_ms"];
|
|
566
536
|
};
|
|
567
|
-
}, "
|
|
537
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
568
538
|
readonly insights_overview_daily: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
569
539
|
readonly identity: {
|
|
570
540
|
readonly type: "string";
|
|
@@ -592,7 +562,7 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
592
562
|
readonly eq: readonly ["identity"];
|
|
593
563
|
readonly sort: readonly ["bucket_start_ms"];
|
|
594
564
|
};
|
|
595
|
-
}, "
|
|
565
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
596
566
|
readonly insights_overview_lifetime: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
597
567
|
readonly identity: {
|
|
598
568
|
readonly type: "string";
|
|
@@ -649,68 +619,6 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
649
619
|
readonly sort: readonly ["bucket_start_ms"];
|
|
650
620
|
};
|
|
651
621
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
652
|
-
readonly bundle_daily_heads: import("@hot-updater/plugin-core").TableDefinition<{
|
|
653
|
-
readonly install_id: {
|
|
654
|
-
readonly type: "string";
|
|
655
|
-
readonly maxLength: 255;
|
|
656
|
-
};
|
|
657
|
-
readonly bucket_start_ms: {
|
|
658
|
-
readonly type: "integer";
|
|
659
|
-
};
|
|
660
|
-
readonly id: {
|
|
661
|
-
readonly type: "string";
|
|
662
|
-
readonly maxLength: 36;
|
|
663
|
-
};
|
|
664
|
-
readonly received_at_ms: {
|
|
665
|
-
readonly type: "integer";
|
|
666
|
-
};
|
|
667
|
-
readonly channel: {
|
|
668
|
-
readonly type: "string";
|
|
669
|
-
};
|
|
670
|
-
readonly platform: {
|
|
671
|
-
readonly type: "string";
|
|
672
|
-
readonly maxLength: 16;
|
|
673
|
-
};
|
|
674
|
-
readonly app_version: {
|
|
675
|
-
readonly type: "string";
|
|
676
|
-
};
|
|
677
|
-
readonly release_id: {
|
|
678
|
-
readonly type: "string";
|
|
679
|
-
readonly maxLength: 36;
|
|
680
|
-
};
|
|
681
|
-
readonly bundle_kind: {
|
|
682
|
-
readonly type: "string";
|
|
683
|
-
readonly maxLength: 16;
|
|
684
|
-
};
|
|
685
|
-
}, Readonly<Record<string, import("@hot-updater/plugin-core").FieldType>>, {}, readonly ["install_id", "bucket_start_ms"]>;
|
|
686
|
-
readonly insights_distribution_history: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
687
|
-
readonly channel: {
|
|
688
|
-
readonly type: "string";
|
|
689
|
-
};
|
|
690
|
-
readonly platform: {
|
|
691
|
-
readonly type: "string";
|
|
692
|
-
readonly maxLength: 16;
|
|
693
|
-
};
|
|
694
|
-
readonly app_version: {
|
|
695
|
-
readonly type: "string";
|
|
696
|
-
};
|
|
697
|
-
readonly release_id: {
|
|
698
|
-
readonly type: "string";
|
|
699
|
-
readonly maxLength: 36;
|
|
700
|
-
};
|
|
701
|
-
readonly bundle_kind: {
|
|
702
|
-
readonly type: "string";
|
|
703
|
-
readonly maxLength: 16;
|
|
704
|
-
};
|
|
705
|
-
readonly bucket_start_ms: {
|
|
706
|
-
readonly type: "integer";
|
|
707
|
-
};
|
|
708
|
-
}, "installations", {
|
|
709
|
-
readonly byScope: {
|
|
710
|
-
readonly eq: readonly ["channel", "platform"];
|
|
711
|
-
readonly sort: readonly ["bucket_start_ms"];
|
|
712
|
-
};
|
|
713
|
-
}, never, readonly ["channel", "platform", "app_version", "release_id", "bundle_kind", "bucket_start_ms"]>;
|
|
714
622
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
715
623
|
readonly platform: {
|
|
716
624
|
readonly type: "string";
|
|
@@ -806,8 +714,8 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
806
714
|
findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
|
|
807
715
|
countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
|
|
808
716
|
countEvents: (input: InsightsCountEventsInput) => Promise<number>;
|
|
717
|
+
countEventSeries: (input: InsightsCountEventSeriesInput) => Promise<readonly InsightsEventSeriesPoint[]>;
|
|
809
718
|
getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
|
|
810
|
-
getDistributionHistory: (input: InsightsGetDistributionHistoryInput) => Promise<InsightsGetDistributionHistoryResult>;
|
|
811
719
|
getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
|
|
812
720
|
getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
|
|
813
721
|
};
|
package/dist/index.d.mts
CHANGED
|
@@ -200,6 +200,19 @@ interface InsightsCountEventsInput {
|
|
|
200
200
|
readonly sinceMs: number;
|
|
201
201
|
readonly beforeReceivedAtMs: number;
|
|
202
202
|
}
|
|
203
|
+
/** One bundle filter's stored events in each interval of a time range. */
|
|
204
|
+
interface InsightsCountEventSeriesInput {
|
|
205
|
+
readonly filter: InsightsBundleEventFilter;
|
|
206
|
+
/** Whole UTC hours, at most 90 days, that a whole number of intervals fill. */
|
|
207
|
+
readonly timeRange: InsightsTimeRange;
|
|
208
|
+
/** Whole hours each point spans, from `timeRange.start`. */
|
|
209
|
+
readonly intervalMs: number;
|
|
210
|
+
}
|
|
211
|
+
/** Stored events in [startMs, startMs + intervalMs). */
|
|
212
|
+
interface InsightsEventSeriesPoint {
|
|
213
|
+
readonly startMs: number;
|
|
214
|
+
readonly events: number;
|
|
215
|
+
}
|
|
203
216
|
interface ReleaseReference {
|
|
204
217
|
readonly releaseId: string;
|
|
205
218
|
readonly platform: "ios" | "android";
|
|
@@ -218,44 +231,22 @@ type InsightsCoverage = {
|
|
|
218
231
|
readonly kind: "partial";
|
|
219
232
|
readonly sinceMs: number | null;
|
|
220
233
|
};
|
|
234
|
+
/**
|
|
235
|
+
* A release's counts since its first report, from its lifetime counters,
|
|
236
|
+
* which are kept.
|
|
237
|
+
*/
|
|
221
238
|
interface ReleaseActivityMetrics {
|
|
222
239
|
readonly downloads: number;
|
|
223
240
|
readonly launches: number;
|
|
224
241
|
readonly failedLaunches: number;
|
|
225
|
-
/** Omitted for lifetime-only bundle-row reads. */
|
|
226
|
-
readonly uniqueUsers?: number;
|
|
227
|
-
/**
|
|
228
|
-
* Points of each UTC day, or of each `intervalMs` from the period's start
|
|
229
|
-
* on a release read that asks for one; present only for period reads.
|
|
230
|
-
*/
|
|
231
|
-
readonly series?: readonly {
|
|
232
|
-
readonly startMs: number;
|
|
233
|
-
readonly downloads: number;
|
|
234
|
-
readonly launches: number;
|
|
235
|
-
readonly failedLaunches: number;
|
|
236
|
-
}[];
|
|
237
242
|
}
|
|
238
|
-
|
|
243
|
+
interface InsightsGetReleaseActivityInput {
|
|
244
|
+
/** 1 to 100 releases. */
|
|
239
245
|
readonly releases: readonly ReleaseReference[];
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Whole hours each series point spans, from `timeRange.start`, with
|
|
243
|
-
* every point present; omitted, the series has a point per UTC day
|
|
244
|
-
* with reports. Only with a `timeRange`.
|
|
245
|
-
*/
|
|
246
|
-
readonly intervalMs?: number;
|
|
247
|
-
readonly scope?: never;
|
|
248
|
-
} | {
|
|
249
|
-
readonly scope: InsightsScope;
|
|
250
|
-
readonly timeRange: InsightsTimeRange;
|
|
251
|
-
readonly intervalMs?: never;
|
|
252
|
-
readonly releases?: never;
|
|
253
|
-
};
|
|
246
|
+
}
|
|
254
247
|
interface InsightsGetReleaseActivityResult {
|
|
255
|
-
readonly coverage: InsightsCoverage;
|
|
256
248
|
readonly data: readonly {
|
|
257
|
-
readonly release
|
|
258
|
-
readonly scope?: InsightsScope;
|
|
249
|
+
readonly release: ReleaseReference;
|
|
259
250
|
readonly metrics: ReleaseActivityMetrics;
|
|
260
251
|
}[];
|
|
261
252
|
readonly measuredAtMs: number;
|
|
@@ -291,23 +282,6 @@ interface InsightsGetAppUsageResult {
|
|
|
291
282
|
}[];
|
|
292
283
|
readonly measuredAtMs: number;
|
|
293
284
|
}
|
|
294
|
-
/** Whole UTC days, at most 31, including the current unfinished day. */
|
|
295
|
-
interface InsightsGetDistributionHistoryInput extends InsightsScope {
|
|
296
|
-
readonly timeRange: InsightsTimeRange;
|
|
297
|
-
}
|
|
298
|
-
interface InsightsGetDistributionHistoryResult {
|
|
299
|
-
readonly coverage: InsightsCoverage;
|
|
300
|
-
readonly measuredAtMs: number;
|
|
301
|
-
readonly points: readonly {
|
|
302
|
-
readonly startMs: number;
|
|
303
|
-
readonly bundles: readonly {
|
|
304
|
-
readonly appVersion: string;
|
|
305
|
-
readonly releaseId: string | null;
|
|
306
|
-
readonly bundleKind: "release" | "builtin" | "unknown";
|
|
307
|
-
readonly installations: number;
|
|
308
|
-
}[];
|
|
309
|
-
}[];
|
|
310
|
-
}
|
|
311
285
|
//#endregion
|
|
312
286
|
//#region ../insights/dist/server/schema.d.mts
|
|
313
287
|
//#region src/server/schema.d.ts
|
|
@@ -461,10 +435,6 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
461
435
|
movement_install_id: "string";
|
|
462
436
|
bundle_ref: "string";
|
|
463
437
|
}, {
|
|
464
|
-
readonly recent: {
|
|
465
|
-
readonly eq: readonly ["channel", "platform", "day"];
|
|
466
|
-
readonly sort: readonly ["received_at_ms"];
|
|
467
|
-
};
|
|
468
438
|
readonly movementsByInstall: {
|
|
469
439
|
readonly eq: readonly ["movement_install_id"];
|
|
470
440
|
readonly sort: readonly ["received_at_ms"];
|
|
@@ -564,7 +534,7 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
564
534
|
readonly eq: readonly ["identity"];
|
|
565
535
|
readonly sort: readonly ["bucket_start_ms"];
|
|
566
536
|
};
|
|
567
|
-
}, "
|
|
537
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
568
538
|
readonly insights_overview_daily: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
569
539
|
readonly identity: {
|
|
570
540
|
readonly type: "string";
|
|
@@ -592,7 +562,7 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
592
562
|
readonly eq: readonly ["identity"];
|
|
593
563
|
readonly sort: readonly ["bucket_start_ms"];
|
|
594
564
|
};
|
|
595
|
-
}, "
|
|
565
|
+
}, "activity_users" | "failed_users", readonly ["identity", "bucket_start_ms"]>;
|
|
596
566
|
readonly insights_overview_lifetime: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
597
567
|
readonly identity: {
|
|
598
568
|
readonly type: "string";
|
|
@@ -649,68 +619,6 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
649
619
|
readonly sort: readonly ["bucket_start_ms"];
|
|
650
620
|
};
|
|
651
621
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
652
|
-
readonly bundle_daily_heads: import("@hot-updater/plugin-core").TableDefinition<{
|
|
653
|
-
readonly install_id: {
|
|
654
|
-
readonly type: "string";
|
|
655
|
-
readonly maxLength: 255;
|
|
656
|
-
};
|
|
657
|
-
readonly bucket_start_ms: {
|
|
658
|
-
readonly type: "integer";
|
|
659
|
-
};
|
|
660
|
-
readonly id: {
|
|
661
|
-
readonly type: "string";
|
|
662
|
-
readonly maxLength: 36;
|
|
663
|
-
};
|
|
664
|
-
readonly received_at_ms: {
|
|
665
|
-
readonly type: "integer";
|
|
666
|
-
};
|
|
667
|
-
readonly channel: {
|
|
668
|
-
readonly type: "string";
|
|
669
|
-
};
|
|
670
|
-
readonly platform: {
|
|
671
|
-
readonly type: "string";
|
|
672
|
-
readonly maxLength: 16;
|
|
673
|
-
};
|
|
674
|
-
readonly app_version: {
|
|
675
|
-
readonly type: "string";
|
|
676
|
-
};
|
|
677
|
-
readonly release_id: {
|
|
678
|
-
readonly type: "string";
|
|
679
|
-
readonly maxLength: 36;
|
|
680
|
-
};
|
|
681
|
-
readonly bundle_kind: {
|
|
682
|
-
readonly type: "string";
|
|
683
|
-
readonly maxLength: 16;
|
|
684
|
-
};
|
|
685
|
-
}, Readonly<Record<string, import("@hot-updater/plugin-core").FieldType>>, {}, readonly ["install_id", "bucket_start_ms"]>;
|
|
686
|
-
readonly insights_distribution_history: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
687
|
-
readonly channel: {
|
|
688
|
-
readonly type: "string";
|
|
689
|
-
};
|
|
690
|
-
readonly platform: {
|
|
691
|
-
readonly type: "string";
|
|
692
|
-
readonly maxLength: 16;
|
|
693
|
-
};
|
|
694
|
-
readonly app_version: {
|
|
695
|
-
readonly type: "string";
|
|
696
|
-
};
|
|
697
|
-
readonly release_id: {
|
|
698
|
-
readonly type: "string";
|
|
699
|
-
readonly maxLength: 36;
|
|
700
|
-
};
|
|
701
|
-
readonly bundle_kind: {
|
|
702
|
-
readonly type: "string";
|
|
703
|
-
readonly maxLength: 16;
|
|
704
|
-
};
|
|
705
|
-
readonly bucket_start_ms: {
|
|
706
|
-
readonly type: "integer";
|
|
707
|
-
};
|
|
708
|
-
}, "installations", {
|
|
709
|
-
readonly byScope: {
|
|
710
|
-
readonly eq: readonly ["channel", "platform"];
|
|
711
|
-
readonly sort: readonly ["bucket_start_ms"];
|
|
712
|
-
};
|
|
713
|
-
}, never, readonly ["channel", "platform", "app_version", "release_id", "bundle_kind", "bucket_start_ms"]>;
|
|
714
622
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
715
623
|
readonly platform: {
|
|
716
624
|
readonly type: "string";
|
|
@@ -806,8 +714,8 @@ declare const plugins: readonly [import("@hot-updater/plugin-core").HotUpdaterPl
|
|
|
806
714
|
findLatestEvents: (input: InsightsFindLatestEventsInput) => Promise<readonly BundleEventRow[]>;
|
|
807
715
|
countLatestEvents: (input: InsightsCountLatestEventsInput) => Promise<number>;
|
|
808
716
|
countEvents: (input: InsightsCountEventsInput) => Promise<number>;
|
|
717
|
+
countEventSeries: (input: InsightsCountEventSeriesInput) => Promise<readonly InsightsEventSeriesPoint[]>;
|
|
809
718
|
getReleaseActivity: (input: InsightsGetReleaseActivityInput) => Promise<InsightsGetReleaseActivityResult>;
|
|
810
|
-
getDistributionHistory: (input: InsightsGetDistributionHistoryInput) => Promise<InsightsGetDistributionHistoryResult>;
|
|
811
719
|
getAppUsage: (input: InsightsGetAppUsageInput) => Promise<InsightsGetAppUsageResult>;
|
|
812
720
|
getUpdateFailures: (input: InsightsUpdateFailuresInput) => Promise<InsightsUpdateFailures>;
|
|
813
721
|
};
|
package/dist/lambda/index.cjs
CHANGED
|
@@ -4570,7 +4570,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
|
|
|
4570
4570
|
};
|
|
4571
4571
|
//#endregion
|
|
4572
4572
|
//#region ../../packages/server/dist/version.mjs
|
|
4573
|
-
const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.
|
|
4573
|
+
const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.31";
|
|
4574
4574
|
//#endregion
|
|
4575
4575
|
//#region ../../packages/server/dist/handlerVersionRoutes.mjs
|
|
4576
4576
|
/**
|
|
@@ -9982,42 +9982,23 @@ const createValidatedInsightsModel = (model) => ({
|
|
|
9982
9982
|
]) || !isBundleFilter(input.filter) || !isTimestamp(input.sinceMs) || !isTimestamp(input.beforeReceivedAtMs) || input.sinceMs > input.beforeReceivedAtMs) invalidQuery();
|
|
9983
9983
|
return validateCount(await model.countEvents(input));
|
|
9984
9984
|
},
|
|
9985
|
-
async
|
|
9985
|
+
async countEventSeries(input) {
|
|
9986
9986
|
if (!isRecord$2(input) || !hasOnlyKeys(input, [
|
|
9987
|
-
"
|
|
9988
|
-
"scope",
|
|
9987
|
+
"filter",
|
|
9989
9988
|
"timeRange",
|
|
9990
9989
|
"intervalMs"
|
|
9991
|
-
])) invalidQuery();
|
|
9992
|
-
const
|
|
9993
|
-
const
|
|
9994
|
-
|
|
9995
|
-
const
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
if (!releaseQuery && !scopeQuery) invalidQuery();
|
|
9999
|
-
const result = await model.getReleaseActivity(input);
|
|
10000
|
-
validateAggregateResult(result);
|
|
10001
|
-
if (!Array.isArray(result.data)) invalidResult();
|
|
10002
|
-
return result;
|
|
9990
|
+
]) || !isBundleFilter(input.filter) || !isTimeRange(input.timeRange) || !isTimestamp(input.intervalMs)) invalidQuery();
|
|
9991
|
+
const { start, end } = input.timeRange;
|
|
9992
|
+
const { intervalMs } = input;
|
|
9993
|
+
if (intervalMs === 0 || intervalMs % 36e5 !== 0 || start % 36e5 !== 0 || (end - start) % intervalMs !== 0 || end - start > 7776e6) invalidQuery();
|
|
9994
|
+
const points = await model.countEventSeries(input);
|
|
9995
|
+
if (!Array.isArray(points) || points.length !== (end - start) / intervalMs || points.some((point, index) => !isRecord$2(point) || !hasOnlyKeys(point, ["startMs", "events"]) || point.startMs !== start + index * intervalMs || !isTimestamp(point.events))) invalidResult();
|
|
9996
|
+
return points;
|
|
10003
9997
|
},
|
|
10004
|
-
async
|
|
10005
|
-
if (!isRecord$2(input) || !hasOnlyKeys(input, [
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
"timeRange"
|
|
10009
|
-
]) || !hasScope(input) || !isTimeRange(input.timeRange) || input.timeRange.start % 864e5 !== 0 || input.timeRange.end % 864e5 !== 0 || input.timeRange.end - input.timeRange.start > 26784e5) invalidQuery();
|
|
10010
|
-
const result = await model.getDistributionHistory(input);
|
|
10011
|
-
validateAggregateResult(result);
|
|
10012
|
-
if (!Array.isArray(result.points)) invalidResult();
|
|
10013
|
-
for (const point of result.points) {
|
|
10014
|
-
if (!isTimestamp(point.startMs) || !Array.isArray(point.bundles)) invalidResult();
|
|
10015
|
-
for (const bundle of point.bundles) if (!isText$1(bundle.appVersion) || bundle.releaseId !== null && !isText$1(bundle.releaseId) || ![
|
|
10016
|
-
"release",
|
|
10017
|
-
"builtin",
|
|
10018
|
-
"unknown"
|
|
10019
|
-
].includes(bundle.bundleKind) || !isTimestamp(bundle.installations)) invalidResult();
|
|
10020
|
-
}
|
|
9998
|
+
async getReleaseActivity(input) {
|
|
9999
|
+
if (!isRecord$2(input) || !hasOnlyKeys(input, ["releases"]) || !Array.isArray(input.releases) || input.releases.length < 1 || input.releases.length > 100 || !input.releases.every(isReleaseReference)) invalidQuery();
|
|
10000
|
+
const result = await model.getReleaseActivity(input);
|
|
10001
|
+
if (!isRecord$2(result) || !isTimestamp(result.measuredAtMs) || !Array.isArray(result.data) || result.data.some((item) => !isRecord$2(item) || !isReleaseReference(item.release) || !isRecord$2(item.metrics) || !isTimestamp(item.metrics.downloads) || !isTimestamp(item.metrics.launches) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
|
|
10021
10002
|
return result;
|
|
10022
10003
|
},
|
|
10023
10004
|
async getAppUsage(input) {
|
|
@@ -10050,9 +10031,9 @@ const createInsightsModel = (api) => createValidatedInsightsModel({
|
|
|
10050
10031
|
findLatestEvents: api.findLatestEvents,
|
|
10051
10032
|
countLatestEvents: api.countLatestEvents,
|
|
10052
10033
|
countEvents: api.countEvents,
|
|
10034
|
+
countEventSeries: api.countEventSeries,
|
|
10053
10035
|
getReleaseActivity: api.getReleaseActivity,
|
|
10054
|
-
getAppUsage: api.getAppUsage
|
|
10055
|
-
getDistributionHistory: api.getDistributionHistory
|
|
10036
|
+
getAppUsage: api.getAppUsage
|
|
10056
10037
|
});
|
|
10057
10038
|
//#endregion
|
|
10058
10039
|
//#region ../insights/dist/server/official.mjs
|
|
@@ -10872,14 +10853,6 @@ const bundleEvents = (days) => defineTable({
|
|
|
10872
10853
|
}
|
|
10873
10854
|
},
|
|
10874
10855
|
indexes: {
|
|
10875
|
-
recent: {
|
|
10876
|
-
eq: [
|
|
10877
|
-
"channel",
|
|
10878
|
-
"platform",
|
|
10879
|
-
"day"
|
|
10880
|
-
],
|
|
10881
|
-
sort: ["received_at_ms"]
|
|
10882
|
-
},
|
|
10883
10856
|
movementsByInstall: {
|
|
10884
10857
|
eq: ["movement_install_id"],
|
|
10885
10858
|
sort: ["received_at_ms"]
|
|
@@ -10996,10 +10969,11 @@ const window = {
|
|
|
10996
10969
|
};
|
|
10997
10970
|
/**
|
|
10998
10971
|
* Counters of one period kind: hourly, daily, or lifetime at bucket 0. A
|
|
10999
|
-
* release or channel row counts downloads
|
|
11000
|
-
*
|
|
11001
|
-
*
|
|
11002
|
-
*
|
|
10972
|
+
* release or channel row counts downloads and failed launches, and downloads
|
|
10973
|
+
* a patch delivered and those that fell back from one. Only a release's
|
|
10974
|
+
* lifetime row counts launches, which the bundle list reads and no windowed
|
|
10975
|
+
* read sums. It also counts the release's failed updates (`failed_updates`),
|
|
10976
|
+
* since no breakdown row outlives the raw period; windowed reads sum
|
|
11003
10977
|
* `insights_failures` instead.
|
|
11004
10978
|
*/
|
|
11005
10979
|
const counters = (retention) => defineAggregate(identityFields, {
|
|
@@ -11018,17 +10992,13 @@ const counters = (retention) => defineAggregate(identityFields, {
|
|
|
11018
10992
|
...retention === void 0 ? {} : { retention }
|
|
11019
10993
|
});
|
|
11020
10994
|
/**
|
|
11021
|
-
* Unique-installation sketches of one period kind
|
|
11022
|
-
*
|
|
11023
|
-
*
|
|
10995
|
+
* Unique-installation sketches of one period kind: a usage row's active
|
|
10996
|
+
* installations (`activity_users`), and a `failure` or `check` row's
|
|
10997
|
+
* installations whose update or update check failed (`failed_users`).
|
|
11024
10998
|
*/
|
|
11025
10999
|
const sketches = (retention) => defineAggregate(identityFields, {
|
|
11026
11000
|
key: ["identity", "bucket_start_ms"],
|
|
11027
|
-
distinct: [
|
|
11028
|
-
"launch_users",
|
|
11029
|
-
"activity_users",
|
|
11030
|
-
"failed_users"
|
|
11031
|
-
],
|
|
11001
|
+
distinct: ["activity_users", "failed_users"],
|
|
11032
11002
|
shards: SKETCH_SHARDS,
|
|
11033
11003
|
batched: true,
|
|
11034
11004
|
indexes: { window },
|
|
@@ -11134,71 +11104,6 @@ const insightsDistribution = (retention) => defineAggregate({
|
|
|
11134
11104
|
},
|
|
11135
11105
|
retention
|
|
11136
11106
|
});
|
|
11137
|
-
/** The last running bundle observed per installation and UTC day. */
|
|
11138
|
-
const bundleDailyHeads = (retention) => defineTable({
|
|
11139
|
-
install_id: {
|
|
11140
|
-
type: "string",
|
|
11141
|
-
maxLength: 255
|
|
11142
|
-
},
|
|
11143
|
-
bucket_start_ms: { type: "integer" },
|
|
11144
|
-
id: {
|
|
11145
|
-
type: "string",
|
|
11146
|
-
maxLength: 36
|
|
11147
|
-
},
|
|
11148
|
-
received_at_ms: { type: "integer" },
|
|
11149
|
-
channel: { type: "string" },
|
|
11150
|
-
platform: {
|
|
11151
|
-
type: "string",
|
|
11152
|
-
maxLength: 16
|
|
11153
|
-
},
|
|
11154
|
-
app_version: { type: "string" },
|
|
11155
|
-
release_id: {
|
|
11156
|
-
type: "string",
|
|
11157
|
-
maxLength: 36
|
|
11158
|
-
},
|
|
11159
|
-
bundle_kind: {
|
|
11160
|
-
type: "string",
|
|
11161
|
-
maxLength: 16
|
|
11162
|
-
}
|
|
11163
|
-
}, {
|
|
11164
|
-
key: ["install_id", "bucket_start_ms"],
|
|
11165
|
-
retention
|
|
11166
|
-
});
|
|
11167
|
-
/** Daily observations stay in their day when an installation reports again. */
|
|
11168
|
-
const insightsDistributionHistory = (retention) => defineAggregate({
|
|
11169
|
-
channel: { type: "string" },
|
|
11170
|
-
platform: {
|
|
11171
|
-
type: "string",
|
|
11172
|
-
maxLength: 16
|
|
11173
|
-
},
|
|
11174
|
-
app_version: { type: "string" },
|
|
11175
|
-
release_id: {
|
|
11176
|
-
type: "string",
|
|
11177
|
-
maxLength: 36
|
|
11178
|
-
},
|
|
11179
|
-
bundle_kind: {
|
|
11180
|
-
type: "string",
|
|
11181
|
-
maxLength: 16
|
|
11182
|
-
},
|
|
11183
|
-
bucket_start_ms: { type: "integer" }
|
|
11184
|
-
}, {
|
|
11185
|
-
key: [
|
|
11186
|
-
"channel",
|
|
11187
|
-
"platform",
|
|
11188
|
-
"app_version",
|
|
11189
|
-
"release_id",
|
|
11190
|
-
"bundle_kind",
|
|
11191
|
-
"bucket_start_ms"
|
|
11192
|
-
],
|
|
11193
|
-
gauges: ["installations"],
|
|
11194
|
-
shards: GAUGE_SHARDS,
|
|
11195
|
-
batched: true,
|
|
11196
|
-
indexes: { byScope: {
|
|
11197
|
-
eq: ["channel", "platform"],
|
|
11198
|
-
sort: ["bucket_start_ms"]
|
|
11199
|
-
} },
|
|
11200
|
-
retention
|
|
11201
|
-
});
|
|
11202
11107
|
/** Latest events by the bundle they came from or went to, bucketed like the distribution. */
|
|
11203
11108
|
const insightsLatestByBundle = (retention) => defineAggregate({
|
|
11204
11109
|
platform: {
|
|
@@ -11318,8 +11223,6 @@ const createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTIO
|
|
|
11318
11223
|
insights_overview_lifetime: counters(),
|
|
11319
11224
|
insights_sketches_lifetime: lifetimeSketches(),
|
|
11320
11225
|
insights_distribution: insightsDistribution(daily),
|
|
11321
|
-
bundle_daily_heads: bundleDailyHeads(daily),
|
|
11322
|
-
insights_distribution_history: insightsDistributionHistory(daily),
|
|
11323
11226
|
insights_latest_by_bundle: insightsLatestByBundle(daily),
|
|
11324
11227
|
insights_outcomes: insightsOutcomes(hourly),
|
|
11325
11228
|
insights_failures: insightsFailures(hourly)
|
|
@@ -11362,12 +11265,14 @@ const insightsOverviewDeltas = (event) => {
|
|
|
11362
11265
|
downloads: (previous?.downloads ?? 0) + values.downloads,
|
|
11363
11266
|
launches: (previous?.launches ?? 0) + values.launches,
|
|
11364
11267
|
failedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,
|
|
11365
|
-
launchIdentity: previous?.launchIdentity ?? values.launchIdentity,
|
|
11366
11268
|
activityIdentity: previous?.activityIdentity ?? values.activityIdentity
|
|
11367
11269
|
});
|
|
11368
11270
|
};
|
|
11369
11271
|
const metric = (releaseId, values) => {
|
|
11370
|
-
const
|
|
11272
|
+
const windowed = {
|
|
11273
|
+
...values,
|
|
11274
|
+
launches: 0
|
|
11275
|
+
};
|
|
11371
11276
|
if (releaseId !== null) for (const [periodKind, start] of [["lifetime", 0], ["hour", bucketStartMs]]) append({
|
|
11372
11277
|
scopeKind: "release",
|
|
11373
11278
|
releaseKind: "specific",
|
|
@@ -11378,10 +11283,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
11378
11283
|
appVersion: "",
|
|
11379
11284
|
periodKind,
|
|
11380
11285
|
bucketStartMs: start
|
|
11381
|
-
},
|
|
11382
|
-
...values,
|
|
11383
|
-
...periodKind === "hour" ? { launchIdentity } : {}
|
|
11384
|
-
});
|
|
11286
|
+
}, periodKind === "lifetime" ? values : windowed);
|
|
11385
11287
|
append({
|
|
11386
11288
|
scopeKind: "channel",
|
|
11387
11289
|
releaseKind: "all",
|
|
@@ -11392,10 +11294,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
11392
11294
|
appVersion: "",
|
|
11393
11295
|
periodKind: "hour",
|
|
11394
11296
|
bucketStartMs
|
|
11395
|
-
},
|
|
11396
|
-
...values,
|
|
11397
|
-
launchIdentity
|
|
11398
|
-
});
|
|
11297
|
+
}, windowed);
|
|
11399
11298
|
};
|
|
11400
11299
|
if (event.type === "UPDATE_DOWNLOADED") metric(event.to_release_id, {
|
|
11401
11300
|
downloads: 1,
|
|
@@ -11520,11 +11419,10 @@ const patchCounters = (event) => event.type !== "UPDATE_DOWNLOADED" ? {} : {
|
|
|
11520
11419
|
};
|
|
11521
11420
|
/**
|
|
11522
11421
|
* Counters and sketches for one event: release, channel, and usage rows, with
|
|
11523
|
-
* day rollups for channel and usage.
|
|
11524
|
-
*
|
|
11525
|
-
*
|
|
11526
|
-
*
|
|
11527
|
-
* in the rows that count it.
|
|
11422
|
+
* day rollups for channel and usage. Only usage rows keep a sketch, of active
|
|
11423
|
+
* installations, and only for the event's platform, since a read for every
|
|
11424
|
+
* platform merges the ios and android sketches. A download's patch counters
|
|
11425
|
+
* go in the rows that count it.
|
|
11528
11426
|
*/
|
|
11529
11427
|
const countEvent = (tx, event) => {
|
|
11530
11428
|
const shardBy = event.install_id;
|
|
@@ -11550,11 +11448,7 @@ const countEvent = (tx, event) => {
|
|
|
11550
11448
|
...delta.downloads === 0 ? {} : patchCounters(event)
|
|
11551
11449
|
};
|
|
11552
11450
|
if (Object.keys(counters).length > 0) tx.aggregate(models.counters, key, counters, { shardBy });
|
|
11553
|
-
|
|
11554
|
-
...delta.launchIdentity === void 0 || parts.scopeKind === "channel" ? {} : { launch_users: addDistinct(null, delta.launchIdentity) },
|
|
11555
|
-
...delta.activityIdentity === void 0 ? {} : { activity_users: addDistinct(null, delta.activityIdentity) }
|
|
11556
|
-
};
|
|
11557
|
-
if (models.sketches !== void 0 && Object.keys(sketches).length > 0) tx.aggregate(models.sketches, key, sketches, { shardBy });
|
|
11451
|
+
if (models.sketches !== void 0 && delta.activityIdentity !== void 0) tx.aggregate(models.sketches, key, { activity_users: addDistinct(null, delta.activityIdentity) }, { shardBy });
|
|
11558
11452
|
}
|
|
11559
11453
|
}
|
|
11560
11454
|
};
|
|
@@ -11707,66 +11601,21 @@ const REPEATED_FIELDS = [
|
|
|
11707
11601
|
const repeatsHead = (event, head) => event.type === "UNCHANGED" && head.type !== "UPDATE_DOWNLOADED" && dayOf(event.received_at_ms) === dayOf(head.received_at_ms) && REPEATED_FIELDS.every((field) => event[field] === head[field]);
|
|
11708
11602
|
/**
|
|
11709
11603
|
* Records one event in one transaction: one batch read of the event and its
|
|
11710
|
-
* installation's
|
|
11711
|
-
* changes and one
|
|
11604
|
+
* installation's head, one of the gauge and sketch rows it changes, then one
|
|
11712
11605
|
* write. On a database that batches aggregates (DynamoDB, Firestore), the
|
|
11713
11606
|
* write holds the event's rows and one log row instead, and a compaction
|
|
11714
11607
|
* reads and writes the aggregate rows. A stored event's id changes nothing
|
|
11715
11608
|
* when repeated, whichever installation sends it, and neither does the id
|
|
11716
11609
|
* of the installation's head. An UNCHANGED report that repeats its head on
|
|
11717
|
-
* the same UTC day
|
|
11610
|
+
* the same UTC day writes nothing at all. An older event still counts in its
|
|
11718
11611
|
* own hour but never replaces the head. An update failure is stored and
|
|
11719
11612
|
* counted, but changes what no installation runs, so it moves no head.
|
|
11720
11613
|
*/
|
|
11721
11614
|
const recordEvent = (db, event) => {
|
|
11722
11615
|
assertBundleEventRow(event);
|
|
11723
11616
|
return db.transaction(async (tx) => {
|
|
11724
|
-
const
|
|
11725
|
-
|
|
11726
|
-
bucket_start_ms: dayOf(event.received_at_ms)
|
|
11727
|
-
};
|
|
11728
|
-
const [existing, previous, daily] = await Promise.all([
|
|
11729
|
-
tx.findOne("bundle_events", { id: event.id }),
|
|
11730
|
-
tx.findOne("bundle_event_heads", { install_id: event.install_id }),
|
|
11731
|
-
event.type === "UPDATE_FAILED" ? null : tx.findOne("bundle_daily_heads", dailyKey)
|
|
11732
|
-
]);
|
|
11733
|
-
if (existing !== null || previous?.id === event.id || daily?.id === event.id) return;
|
|
11734
|
-
if (event.type !== "UPDATE_FAILED" && (daily === null || isNewer(event, daily))) {
|
|
11735
|
-
const downloaded = event.type === "UPDATE_DOWNLOADED";
|
|
11736
|
-
const releaseId = downloaded ? event.from_release_id : event.to_release_id;
|
|
11737
|
-
const bundleId = downloaded ? event.from_bundle_id : event.to_bundle_id;
|
|
11738
|
-
const next = {
|
|
11739
|
-
...dailyKey,
|
|
11740
|
-
id: event.id,
|
|
11741
|
-
received_at_ms: event.received_at_ms,
|
|
11742
|
-
channel: event.channel,
|
|
11743
|
-
platform: event.platform,
|
|
11744
|
-
app_version: event.app_version,
|
|
11745
|
-
release_id: releaseId ?? "",
|
|
11746
|
-
bundle_kind: bundleId === "00000000-0000-0000-0000-000000000000" ? "builtin" : releaseId === null ? "unknown" : "release"
|
|
11747
|
-
};
|
|
11748
|
-
const count = (head, delta) => {
|
|
11749
|
-
tx.aggregate("insights_distribution_history", {
|
|
11750
|
-
channel: head.channel,
|
|
11751
|
-
platform: head.platform,
|
|
11752
|
-
app_version: head.app_version,
|
|
11753
|
-
release_id: head.release_id,
|
|
11754
|
-
bundle_kind: head.bundle_kind,
|
|
11755
|
-
bucket_start_ms: head.bucket_start_ms
|
|
11756
|
-
}, { installations: delta }, { shardBy: head.install_id });
|
|
11757
|
-
};
|
|
11758
|
-
if (daily !== null) {
|
|
11759
|
-
if (daily.channel !== next.channel || daily.platform !== next.platform || daily.app_version !== next.app_version || daily.release_id !== next.release_id || daily.bundle_kind !== next.bundle_kind) {
|
|
11760
|
-
count(daily, -1);
|
|
11761
|
-
count(next, 1);
|
|
11762
|
-
}
|
|
11763
|
-
const { install_id: _, bucket_start_ms: __, ...fields } = next;
|
|
11764
|
-
tx.update("bundle_daily_heads", daily, fields);
|
|
11765
|
-
} else {
|
|
11766
|
-
tx.create("bundle_daily_heads", next);
|
|
11767
|
-
count(next, 1);
|
|
11768
|
-
}
|
|
11769
|
-
}
|
|
11617
|
+
const [existing, previous] = await Promise.all([tx.findOne("bundle_events", { id: event.id }), tx.findOne("bundle_event_heads", { install_id: event.install_id })]);
|
|
11618
|
+
if (existing !== null || previous?.id === event.id) return;
|
|
11770
11619
|
if (previous !== null && repeatsHead(event, previous)) return;
|
|
11771
11620
|
if (event.type !== "UNCHANGED") {
|
|
11772
11621
|
tx.create("bundle_events", event);
|
|
@@ -11958,6 +11807,30 @@ const countEvents = async (db, input) => {
|
|
|
11958
11807
|
}));
|
|
11959
11808
|
return await countRaw(db, filter, sinceMs, start) + hours.reduce((sum, row) => sum + row.events, 0) + await countRaw(db, filter, end, beforeReceivedAtMs);
|
|
11960
11809
|
};
|
|
11810
|
+
/**
|
|
11811
|
+
* A bundle filter's stored events in each interval of whole hours: one read
|
|
11812
|
+
* of its hourly counts, every interval present.
|
|
11813
|
+
*/
|
|
11814
|
+
const countEventSeries = async (db, input) => {
|
|
11815
|
+
const { filter, intervalMs } = input;
|
|
11816
|
+
const { start, end } = input.timeRange;
|
|
11817
|
+
const events = Array.from({ length: (end - start) / intervalMs }, () => 0);
|
|
11818
|
+
const hours = await drain((page) => db.findAggregates("insights_outcomes", {
|
|
11819
|
+
index: "byRef",
|
|
11820
|
+
where: scopeOf(filter),
|
|
11821
|
+
range: {
|
|
11822
|
+
gte: start,
|
|
11823
|
+
lt: end
|
|
11824
|
+
},
|
|
11825
|
+
limit: PAGE,
|
|
11826
|
+
...page
|
|
11827
|
+
}));
|
|
11828
|
+
for (const row of hours) events[Math.floor((row.bucket_start_ms - start) / intervalMs)] += row.events;
|
|
11829
|
+
return events.map((count, index) => ({
|
|
11830
|
+
startMs: start + index * intervalMs,
|
|
11831
|
+
events: count
|
|
11832
|
+
}));
|
|
11833
|
+
};
|
|
11961
11834
|
/** A bundle filter's distinct (field, value, type) predicates. */
|
|
11962
11835
|
const latestPredicates = (bundle) => {
|
|
11963
11836
|
if (bundle === void 0) return void 0;
|
|
@@ -12029,7 +11902,7 @@ const retained = (now, { rawDays, dailyDays }) => ({
|
|
|
12029
11902
|
* Whether the rows a window reads still hold all of it; an older start is
|
|
12030
11903
|
* partial from `oldest`, the first bucket its rows keep.
|
|
12031
11904
|
*/
|
|
12032
|
-
const coverageOf = (start, oldest) => start
|
|
11905
|
+
const coverageOf = (start, oldest) => start >= oldest ? {
|
|
12033
11906
|
kind: "complete",
|
|
12034
11907
|
sinceMs: 0
|
|
12035
11908
|
} : {
|
|
@@ -12132,43 +12005,6 @@ const lifetimeMetrics = async (db, release) => {
|
|
|
12132
12005
|
failedLaunches: lifetime?.failed_launches ?? 0
|
|
12133
12006
|
};
|
|
12134
12007
|
};
|
|
12135
|
-
/**
|
|
12136
|
-
* Counters, unique users, and a series over a window: a point per UTC day
|
|
12137
|
-
* with rows, or, with `intervalMs`, every point of that span from the
|
|
12138
|
-
* window's start.
|
|
12139
|
-
*/
|
|
12140
|
-
const rangedMetrics = async (db, parts, users, range, days, hour, intervalMs) => {
|
|
12141
|
-
const [counters, sketches] = await Promise.all([counterRows(db, parts, range, days, hour), sketchRows(db, users.parts, range, days, hour)]);
|
|
12142
|
-
const series = /* @__PURE__ */ new Map();
|
|
12143
|
-
if (intervalMs !== void 0) for (let start = range.start; start < range.end; start += intervalMs) series.set(start, {
|
|
12144
|
-
downloads: 0,
|
|
12145
|
-
launches: 0,
|
|
12146
|
-
failedLaunches: 0
|
|
12147
|
-
});
|
|
12148
|
-
for (const row of counters) {
|
|
12149
|
-
const start = intervalMs === void 0 ? dayFloor(row.bucket_start_ms) : row.bucket_start_ms - (row.bucket_start_ms - range.start) % intervalMs;
|
|
12150
|
-
const point = series.get(start) ?? {
|
|
12151
|
-
downloads: 0,
|
|
12152
|
-
launches: 0,
|
|
12153
|
-
failedLaunches: 0
|
|
12154
|
-
};
|
|
12155
|
-
point.downloads += row.downloads;
|
|
12156
|
-
point.launches += row.launches;
|
|
12157
|
-
point.failedLaunches += row.failed_launches;
|
|
12158
|
-
series.set(start, point);
|
|
12159
|
-
}
|
|
12160
|
-
const total = (field) => counters.reduce((sum, row) => sum + row[field], 0);
|
|
12161
|
-
return {
|
|
12162
|
-
downloads: total("downloads"),
|
|
12163
|
-
launches: total("launches"),
|
|
12164
|
-
failedLaunches: total("failed_launches"),
|
|
12165
|
-
uniqueUsers: countDistinct(mergeDistinct(sketches.map((row) => row[users.field]))),
|
|
12166
|
-
series: [...series].sort(([left], [right]) => left - right).map(([startMs, point]) => ({
|
|
12167
|
-
startMs,
|
|
12168
|
-
...point
|
|
12169
|
-
}))
|
|
12170
|
-
};
|
|
12171
|
-
};
|
|
12172
12008
|
/** A channel and platform's usage rows, of every app version or of one. */
|
|
12173
12009
|
const usageParts = (channel, platform, appVersion) => ({
|
|
12174
12010
|
scopeKind: "usage",
|
|
@@ -12179,35 +12015,15 @@ const usageParts = (channel, platform, appVersion) => ({
|
|
|
12179
12015
|
appVersionKind: appVersion === void 0 ? "all" : "specific",
|
|
12180
12016
|
appVersion: appVersion ?? ""
|
|
12181
12017
|
});
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
const
|
|
12185
|
-
const data = input.scope !== void 0 ? [{
|
|
12186
|
-
scope: input.scope,
|
|
12187
|
-
metrics: await rangedMetrics(db, {
|
|
12188
|
-
scopeKind: "channel",
|
|
12189
|
-
releaseKind: "all",
|
|
12190
|
-
releaseId: "",
|
|
12191
|
-
channel: input.scope.channel,
|
|
12192
|
-
platform: input.scope.platform,
|
|
12193
|
-
appVersionKind: "all",
|
|
12194
|
-
appVersion: ""
|
|
12195
|
-
}, {
|
|
12196
|
-
parts: usageParts(input.scope.channel, input.scope.platform),
|
|
12197
|
-
field: "activity_users"
|
|
12198
|
-
}, input.timeRange, true, kept.hour)
|
|
12199
|
-
}] : await Promise.all(input.releases.map(async (release) => ({
|
|
12200
|
-
release,
|
|
12201
|
-
metrics: input.timeRange === void 0 ? await lifetimeMetrics(db, release) : await rangedMetrics(db, releaseParts(release), {
|
|
12202
|
-
parts: releaseParts(release),
|
|
12203
|
-
field: "launch_users"
|
|
12204
|
-
}, input.timeRange, false, kept.hour, input.intervalMs)
|
|
12205
|
-
})));
|
|
12206
|
-
const oldest = kept[input.scope === void 0 ? "hour" : "day"];
|
|
12018
|
+
/** Each release's lifetime counters, which are kept: one logical row apiece. */
|
|
12019
|
+
const getReleaseActivity = async (db, input, now) => {
|
|
12020
|
+
const measuredAtMs = now();
|
|
12207
12021
|
return {
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12022
|
+
data: await Promise.all(input.releases.map(async (release) => ({
|
|
12023
|
+
release,
|
|
12024
|
+
metrics: await lifetimeMetrics(db, release)
|
|
12025
|
+
}))),
|
|
12026
|
+
measuredAtMs
|
|
12211
12027
|
};
|
|
12212
12028
|
};
|
|
12213
12029
|
/**
|
|
@@ -12467,43 +12283,6 @@ const getUpdateFailures = async (db, input, now, retention) => {
|
|
|
12467
12283
|
}
|
|
12468
12284
|
};
|
|
12469
12285
|
};
|
|
12470
|
-
/** Reads daily gauges, never raw events or mutable latest-state distribution. */
|
|
12471
|
-
const getDistributionHistory = async (db, input, now, retention) => {
|
|
12472
|
-
const at = now();
|
|
12473
|
-
const { start, end } = input.timeRange;
|
|
12474
|
-
const points = /* @__PURE__ */ new Map();
|
|
12475
|
-
for (let day = start; day < end; day += DAY_MS) points.set(day, []);
|
|
12476
|
-
const rows = await drain((page) => db.findAggregates("insights_distribution_history", {
|
|
12477
|
-
index: "byScope",
|
|
12478
|
-
where: {
|
|
12479
|
-
channel: input.channel,
|
|
12480
|
-
platform: input.platform
|
|
12481
|
-
},
|
|
12482
|
-
range: {
|
|
12483
|
-
gte: start,
|
|
12484
|
-
lt: end
|
|
12485
|
-
},
|
|
12486
|
-
limit: PAGE,
|
|
12487
|
-
...page
|
|
12488
|
-
}));
|
|
12489
|
-
for (const row of rows) {
|
|
12490
|
-
if (row.installations <= 0) continue;
|
|
12491
|
-
points.get(row.bucket_start_ms).push({
|
|
12492
|
-
appVersion: row.app_version,
|
|
12493
|
-
releaseId: row.release_id || null,
|
|
12494
|
-
bundleKind: row.bundle_kind,
|
|
12495
|
-
installations: row.installations
|
|
12496
|
-
});
|
|
12497
|
-
}
|
|
12498
|
-
return {
|
|
12499
|
-
coverage: coverageOf(start, retained(at, retention).day),
|
|
12500
|
-
measuredAtMs: at,
|
|
12501
|
-
points: [...points].map(([startMs, bundles]) => ({
|
|
12502
|
-
startMs,
|
|
12503
|
-
bundles
|
|
12504
|
-
}))
|
|
12505
|
-
};
|
|
12506
|
-
};
|
|
12507
12286
|
//#endregion
|
|
12508
12287
|
//#region ../insights/dist/server/queryInput.mjs
|
|
12509
12288
|
const MAX_PAGE_LIMIT = 100;
|
|
@@ -12694,8 +12473,8 @@ const createInsightsApi = (db, now, retention) => ({
|
|
|
12694
12473
|
findLatestEvents: (input) => findLatestEvents(db, input),
|
|
12695
12474
|
countLatestEvents: (input) => countLatestEvents(db, input),
|
|
12696
12475
|
countEvents: (input) => countEvents(db, input),
|
|
12697
|
-
|
|
12698
|
-
|
|
12476
|
+
countEventSeries: (input) => countEventSeries(db, input),
|
|
12477
|
+
getReleaseActivity: (input) => getReleaseActivity(db, input, now),
|
|
12699
12478
|
getAppUsage: (input) => getAppUsage(db, input, now, retention),
|
|
12700
12479
|
/** A release's or a channel's update failures, and their breakdown over a time range. */
|
|
12701
12480
|
getUpdateFailures: (input) => getUpdateFailures(db, input, now, retention)
|
|
@@ -12764,7 +12543,7 @@ const insights = (options = {}) => {
|
|
|
12764
12543
|
const plugin = definePlugin({
|
|
12765
12544
|
id: "insights",
|
|
12766
12545
|
namespace: false,
|
|
12767
|
-
schemaVersion: "1.
|
|
12546
|
+
schemaVersion: "1.2.0",
|
|
12768
12547
|
schema: createInsightsSchema(retention),
|
|
12769
12548
|
init: ({ db, now }) => {
|
|
12770
12549
|
const api = createInsightsApi(db, now, retention);
|
|
@@ -12779,32 +12558,6 @@ const insights = (options = {}) => {
|
|
|
12779
12558
|
handler: (request, params) => routes[handler](params, request)
|
|
12780
12559
|
})),
|
|
12781
12560
|
failuresEndpoint(api),
|
|
12782
|
-
{
|
|
12783
|
-
access: "admin",
|
|
12784
|
-
method: "GET",
|
|
12785
|
-
path: "/distribution-history",
|
|
12786
|
-
handler: async (request) => {
|
|
12787
|
-
const query = new URL(request.url).searchParams;
|
|
12788
|
-
try {
|
|
12789
|
-
const result = await createInsightsModel(api).getDistributionHistory({
|
|
12790
|
-
platform: query.get("platform"),
|
|
12791
|
-
channel: query.get("channel") ?? "",
|
|
12792
|
-
timeRange: {
|
|
12793
|
-
start: Number(query.get("start") ?? NaN),
|
|
12794
|
-
end: Number(query.get("end") ?? NaN)
|
|
12795
|
-
}
|
|
12796
|
-
});
|
|
12797
|
-
return Response.json(result, { headers: { "cache-control": "private, no-store" } });
|
|
12798
|
-
} catch (error) {
|
|
12799
|
-
if (error instanceof DatabaseAdapterInputError) return Response.json({ error: "Choose a platform, channel, and up to 31 whole UTC days." }, { status: 400 });
|
|
12800
|
-
if (!isDatabaseBusyError(error)) throw error;
|
|
12801
|
-
return Response.json({ error: "Service unavailable" }, {
|
|
12802
|
-
status: 503,
|
|
12803
|
-
headers: { "retry-after": "5" }
|
|
12804
|
-
});
|
|
12805
|
-
}
|
|
12806
|
-
}
|
|
12807
|
-
},
|
|
12808
12561
|
{
|
|
12809
12562
|
access: "admin",
|
|
12810
12563
|
method: "GET",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/aws",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.31",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.mjs",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"mime": "^4.0.4",
|
|
48
48
|
"@hot-updater/protocol": "1.0.0-rc.28",
|
|
49
49
|
"@hot-updater/mock": "1.0.0-rc.28",
|
|
50
|
-
"@hot-updater/test-utils": "1.0.0-rc.
|
|
50
|
+
"@hot-updater/test-utils": "1.0.0-rc.30"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@aws-sdk/client-cloudfront": "3.1066.0",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"@aws-sdk/lib-storage": "3.1066.0",
|
|
63
63
|
"@aws-sdk/lib-dynamodb": "3.1066.0",
|
|
64
64
|
"hono": "4.12.34",
|
|
65
|
-
"@hot-updater/cli-tools": "1.0.0-rc.
|
|
65
|
+
"@hot-updater/cli-tools": "1.0.0-rc.31",
|
|
66
66
|
"@hot-updater/plugin-core": "1.0.0-rc.28",
|
|
67
|
-
"@hot-updater/server": "1.0.0-rc.
|
|
67
|
+
"@hot-updater/server": "1.0.0-rc.31"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
70
|
"build": "tsdown",
|