@hot-updater/plugin-insights 1.0.0-rc.35 → 1.0.0-rc.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.cjs +2 -1
- package/dist/client/index.mjs +2 -1
- package/dist/server/contract.cjs +8 -4
- package/dist/server/contract.mjs +8 -4
- package/dist/server/domain.d.cts +40 -4
- package/dist/server/domain.d.mts +40 -4
- package/dist/server/eventInput.cjs +7 -0
- package/dist/server/eventInput.mjs +7 -0
- package/dist/server/eventRow.cjs +24 -2
- package/dist/server/eventRow.d.cts +35 -1
- package/dist/server/eventRow.d.mts +35 -1
- package/dist/server/eventRow.mjs +24 -3
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +34 -2
- package/dist/server/index.d.mts +34 -2
- package/dist/server/index.mjs +1 -1
- package/dist/server/modelTypes.d.cts +6 -2
- package/dist/server/modelTypes.d.mts +6 -2
- package/dist/server/overview.cjs +7 -5
- package/dist/server/overview.d.cts +3 -3
- package/dist/server/overview.d.mts +3 -3
- package/dist/server/overview.mjs +7 -5
- package/dist/server/provider.cjs +15 -1
- package/dist/server/provider.mjs +15 -1
- package/dist/server/reads.cjs +60 -29
- package/dist/server/reads.mjs +60 -29
- package/dist/server/recordEvent.cjs +156 -22
- package/dist/server/recordEvent.mjs +157 -23
- package/dist/server/schema.cjs +96 -10
- package/dist/server/schema.d.cts +64 -0
- package/dist/server/schema.d.mts +64 -0
- package/dist/server/schema.mjs +93 -11
- package/package.json +5 -5
package/dist/server/schema.d.cts
CHANGED
|
@@ -259,6 +259,38 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
259
259
|
readonly sort: readonly ["bucket_start_ms"];
|
|
260
260
|
};
|
|
261
261
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
262
|
+
readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
263
|
+
readonly channel: {
|
|
264
|
+
readonly type: "string";
|
|
265
|
+
};
|
|
266
|
+
readonly platform: {
|
|
267
|
+
readonly type: "string";
|
|
268
|
+
readonly maxLength: 16;
|
|
269
|
+
};
|
|
270
|
+
readonly app_version: {
|
|
271
|
+
readonly type: "string";
|
|
272
|
+
};
|
|
273
|
+
readonly release_id: {
|
|
274
|
+
readonly type: "string";
|
|
275
|
+
readonly maxLength: 36;
|
|
276
|
+
};
|
|
277
|
+
readonly builtin_bundle_id: {
|
|
278
|
+
readonly type: "string";
|
|
279
|
+
readonly maxLength: 36;
|
|
280
|
+
};
|
|
281
|
+
readonly bucket_start_ms: {
|
|
282
|
+
readonly type: "integer";
|
|
283
|
+
};
|
|
284
|
+
}, "latest_installations", {
|
|
285
|
+
readonly byScope: {
|
|
286
|
+
readonly eq: readonly ["channel", "platform"];
|
|
287
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
288
|
+
};
|
|
289
|
+
readonly byVersion: {
|
|
290
|
+
readonly eq: readonly ["channel", "platform", "app_version"];
|
|
291
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
292
|
+
};
|
|
293
|
+
}, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
|
|
262
294
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
263
295
|
readonly platform: {
|
|
264
296
|
readonly type: "string";
|
|
@@ -594,6 +626,38 @@ declare const insightsSchema: {
|
|
|
594
626
|
readonly sort: readonly ["bucket_start_ms"];
|
|
595
627
|
};
|
|
596
628
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
629
|
+
readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
630
|
+
readonly channel: {
|
|
631
|
+
readonly type: "string";
|
|
632
|
+
};
|
|
633
|
+
readonly platform: {
|
|
634
|
+
readonly type: "string";
|
|
635
|
+
readonly maxLength: 16;
|
|
636
|
+
};
|
|
637
|
+
readonly app_version: {
|
|
638
|
+
readonly type: "string";
|
|
639
|
+
};
|
|
640
|
+
readonly release_id: {
|
|
641
|
+
readonly type: "string";
|
|
642
|
+
readonly maxLength: 36;
|
|
643
|
+
};
|
|
644
|
+
readonly builtin_bundle_id: {
|
|
645
|
+
readonly type: "string";
|
|
646
|
+
readonly maxLength: 36;
|
|
647
|
+
};
|
|
648
|
+
readonly bucket_start_ms: {
|
|
649
|
+
readonly type: "integer";
|
|
650
|
+
};
|
|
651
|
+
}, "latest_installations", {
|
|
652
|
+
readonly byScope: {
|
|
653
|
+
readonly eq: readonly ["channel", "platform"];
|
|
654
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
655
|
+
};
|
|
656
|
+
readonly byVersion: {
|
|
657
|
+
readonly eq: readonly ["channel", "platform", "app_version"];
|
|
658
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
659
|
+
};
|
|
660
|
+
}, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
|
|
597
661
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
598
662
|
readonly platform: {
|
|
599
663
|
readonly type: "string";
|
package/dist/server/schema.d.mts
CHANGED
|
@@ -259,6 +259,38 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
259
259
|
readonly sort: readonly ["bucket_start_ms"];
|
|
260
260
|
};
|
|
261
261
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
262
|
+
readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
263
|
+
readonly channel: {
|
|
264
|
+
readonly type: "string";
|
|
265
|
+
};
|
|
266
|
+
readonly platform: {
|
|
267
|
+
readonly type: "string";
|
|
268
|
+
readonly maxLength: 16;
|
|
269
|
+
};
|
|
270
|
+
readonly app_version: {
|
|
271
|
+
readonly type: "string";
|
|
272
|
+
};
|
|
273
|
+
readonly release_id: {
|
|
274
|
+
readonly type: "string";
|
|
275
|
+
readonly maxLength: 36;
|
|
276
|
+
};
|
|
277
|
+
readonly builtin_bundle_id: {
|
|
278
|
+
readonly type: "string";
|
|
279
|
+
readonly maxLength: 36;
|
|
280
|
+
};
|
|
281
|
+
readonly bucket_start_ms: {
|
|
282
|
+
readonly type: "integer";
|
|
283
|
+
};
|
|
284
|
+
}, "latest_installations", {
|
|
285
|
+
readonly byScope: {
|
|
286
|
+
readonly eq: readonly ["channel", "platform"];
|
|
287
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
288
|
+
};
|
|
289
|
+
readonly byVersion: {
|
|
290
|
+
readonly eq: readonly ["channel", "platform", "app_version"];
|
|
291
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
292
|
+
};
|
|
293
|
+
}, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
|
|
262
294
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
263
295
|
readonly platform: {
|
|
264
296
|
readonly type: "string";
|
|
@@ -594,6 +626,38 @@ declare const insightsSchema: {
|
|
|
594
626
|
readonly sort: readonly ["bucket_start_ms"];
|
|
595
627
|
};
|
|
596
628
|
}, never, readonly ["channel", "platform", "app_version", "release_id", "bucket_start_ms"]>;
|
|
629
|
+
readonly insights_builtin_distribution: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
630
|
+
readonly channel: {
|
|
631
|
+
readonly type: "string";
|
|
632
|
+
};
|
|
633
|
+
readonly platform: {
|
|
634
|
+
readonly type: "string";
|
|
635
|
+
readonly maxLength: 16;
|
|
636
|
+
};
|
|
637
|
+
readonly app_version: {
|
|
638
|
+
readonly type: "string";
|
|
639
|
+
};
|
|
640
|
+
readonly release_id: {
|
|
641
|
+
readonly type: "string";
|
|
642
|
+
readonly maxLength: 36;
|
|
643
|
+
};
|
|
644
|
+
readonly builtin_bundle_id: {
|
|
645
|
+
readonly type: "string";
|
|
646
|
+
readonly maxLength: 36;
|
|
647
|
+
};
|
|
648
|
+
readonly bucket_start_ms: {
|
|
649
|
+
readonly type: "integer";
|
|
650
|
+
};
|
|
651
|
+
}, "latest_installations", {
|
|
652
|
+
readonly byScope: {
|
|
653
|
+
readonly eq: readonly ["channel", "platform"];
|
|
654
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
655
|
+
};
|
|
656
|
+
readonly byVersion: {
|
|
657
|
+
readonly eq: readonly ["channel", "platform", "app_version"];
|
|
658
|
+
readonly sort: readonly ["bucket_start_ms"];
|
|
659
|
+
};
|
|
660
|
+
}, never, readonly ["channel", "platform", "app_version", "release_id", "builtin_bundle_id", "bucket_start_ms"]>;
|
|
597
661
|
readonly insights_latest_by_bundle: import("@hot-updater/plugin-core").AggregateDefinition<{
|
|
598
662
|
readonly platform: {
|
|
599
663
|
readonly type: "string";
|
package/dist/server/schema.mjs
CHANGED
|
@@ -10,18 +10,53 @@ const bucketRetention = (days) => ({
|
|
|
10
10
|
field: "bucket_start_ms",
|
|
11
11
|
days
|
|
12
12
|
});
|
|
13
|
+
/** Every kind of row the table keeps belongs in installation history. */
|
|
13
14
|
const MOVEMENTS = /* @__PURE__ */ new Set([
|
|
14
15
|
"UPDATE_DOWNLOADED",
|
|
15
16
|
"UPDATE_APPLIED",
|
|
16
17
|
"RECOVERED",
|
|
17
|
-
"UPDATE_FAILED"
|
|
18
|
+
"UPDATE_FAILED",
|
|
19
|
+
"UNCHANGED"
|
|
18
20
|
]);
|
|
19
21
|
/** A failed update check: it names no target bundle, so no bundle list shows it. */
|
|
20
22
|
const isFailedCheck = (row) => row.type === "UPDATE_FAILED" && row.metadata?.failure?.stage === "check";
|
|
23
|
+
const metadataOf = (row) => row.metadata ?? {};
|
|
24
|
+
/** A download or apply that arrived after its target ran: it counts nothing. */
|
|
25
|
+
const isLateEvent = (row) => metadataOf(row).late === true;
|
|
21
26
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
27
|
+
* Whether a stored row launched its installation into a bundle release: an
|
|
28
|
+
* apply, or a kept UNCHANGED row that moved the installation to another
|
|
29
|
+
* bundle of a release, as when the apply report never arrived or a rollback
|
|
30
|
+
* to the built-in bundle took it there. A first report, a release change of
|
|
31
|
+
* the bundle already running, and a late row launch nothing.
|
|
32
|
+
*/
|
|
33
|
+
const isLaunch = (row) => {
|
|
34
|
+
if (isLateEvent(row)) return false;
|
|
35
|
+
if (row.type === "UPDATE_APPLIED") return true;
|
|
36
|
+
if (row.type !== "UNCHANGED") return false;
|
|
37
|
+
const kinds = metadataOf(row).change?.kinds ?? [];
|
|
38
|
+
return kinds.includes("bundle") && !kinds.includes("first_seen") && row.to_release_id !== null;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The bundle a stored row's bundle filter matches: `from:<bundle>` for a
|
|
42
|
+
* recovery; `to:<bundle>` for a download, an apply, and an update failure;
|
|
43
|
+
* `on:<bundle>` for an UNCHANGED row that launched a bundle (`isLaunch`), a
|
|
44
|
+
* key no other row uses. None for a failed check, which targets no bundle, a
|
|
45
|
+
* late row, or any other UNCHANGED row.
|
|
46
|
+
*/
|
|
47
|
+
const bundleRefsOf = (row) => {
|
|
48
|
+
if (isFailedCheck(row) || isLateEvent(row)) return [];
|
|
49
|
+
if (row.type === "RECOVERED") return [`from:${row.from_bundle_id}`];
|
|
50
|
+
if (row.type === "UNCHANGED") return isLaunch(row) ? [`on:${row.to_bundle_id}`] : [];
|
|
51
|
+
return [`to:${row.to_bundle_id}`];
|
|
52
|
+
};
|
|
53
|
+
/** The key a bundle filter reads, as `bundleRefsOf` writes it. */
|
|
54
|
+
const bundleRefOfFilter = (filter) => filter.type === "RECOVERED" ? `from:${filter.fromBundleId}` : filter.type === "UNCHANGED" ? `on:${filter.toBundleId}` : `to:${filter.toBundleId}`;
|
|
55
|
+
/**
|
|
56
|
+
* Downloads, applies, recoveries, update failures, and the UNCHANGED
|
|
57
|
+
* reports that changed what their installation runs, whole. An UNCHANGED
|
|
58
|
+
* report that changes nothing counts as a launch and moves its
|
|
59
|
+
* installation's head, but no row keeps it.
|
|
25
60
|
*/
|
|
26
61
|
const bundleEvents = (days) => defineTable({
|
|
27
62
|
id: {
|
|
@@ -76,19 +111,16 @@ const bundleEvents = (days) => defineTable({
|
|
|
76
111
|
type: "integer",
|
|
77
112
|
compute: (row) => row.received_at_ms - row.received_at_ms % DAY_MS
|
|
78
113
|
},
|
|
79
|
-
/**
|
|
114
|
+
/** Every stored event belongs in installation history. */
|
|
80
115
|
movement_install_id: {
|
|
81
116
|
type: "string",
|
|
82
117
|
compute: (row) => MOVEMENTS.has(row.type) ? row.install_id : null
|
|
83
118
|
},
|
|
84
|
-
/**
|
|
85
|
-
* The bundle a bundle filter matches: `from:<bundle>` for RECOVERED,
|
|
86
|
-
* none for a failed check, else `to:<bundle>`.
|
|
87
|
-
*/
|
|
119
|
+
/** The bundle a bundle filter matches (`bundleRefsOf`). */
|
|
88
120
|
bundle_ref: {
|
|
89
121
|
type: "string",
|
|
90
122
|
multi: true,
|
|
91
|
-
compute: (row) =>
|
|
123
|
+
compute: (row) => bundleRefsOf(row)
|
|
92
124
|
}
|
|
93
125
|
},
|
|
94
126
|
indexes: {
|
|
@@ -354,6 +386,55 @@ const insightsDistribution = (retention) => defineAggregate({
|
|
|
354
386
|
},
|
|
355
387
|
retention
|
|
356
388
|
});
|
|
389
|
+
/**
|
|
390
|
+
* The installations of `insights_distribution` that run their native build's
|
|
391
|
+
* built-in bundle, by its ID (`builtin_bundle_id`), within the same rows:
|
|
392
|
+
* reads move them out of the row of their release, or of no release.
|
|
393
|
+
*/
|
|
394
|
+
const insightsBuiltinDistribution = (retention) => defineAggregate({
|
|
395
|
+
channel: { type: "string" },
|
|
396
|
+
platform: {
|
|
397
|
+
type: "string",
|
|
398
|
+
maxLength: 16
|
|
399
|
+
},
|
|
400
|
+
app_version: { type: "string" },
|
|
401
|
+
release_id: {
|
|
402
|
+
type: "string",
|
|
403
|
+
maxLength: 36
|
|
404
|
+
},
|
|
405
|
+
builtin_bundle_id: {
|
|
406
|
+
type: "string",
|
|
407
|
+
maxLength: 36
|
|
408
|
+
},
|
|
409
|
+
bucket_start_ms: { type: "integer" }
|
|
410
|
+
}, {
|
|
411
|
+
key: [
|
|
412
|
+
"channel",
|
|
413
|
+
"platform",
|
|
414
|
+
"app_version",
|
|
415
|
+
"release_id",
|
|
416
|
+
"builtin_bundle_id",
|
|
417
|
+
"bucket_start_ms"
|
|
418
|
+
],
|
|
419
|
+
gauges: ["latest_installations"],
|
|
420
|
+
shards: GAUGE_SHARDS,
|
|
421
|
+
batched: true,
|
|
422
|
+
indexes: {
|
|
423
|
+
byScope: {
|
|
424
|
+
eq: ["channel", "platform"],
|
|
425
|
+
sort: ["bucket_start_ms"]
|
|
426
|
+
},
|
|
427
|
+
byVersion: {
|
|
428
|
+
eq: [
|
|
429
|
+
"channel",
|
|
430
|
+
"platform",
|
|
431
|
+
"app_version"
|
|
432
|
+
],
|
|
433
|
+
sort: ["bucket_start_ms"]
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
retention
|
|
437
|
+
});
|
|
357
438
|
/** Latest events by the bundle they came from or went to, bucketed like the distribution. */
|
|
358
439
|
const insightsLatestByBundle = (retention) => defineAggregate({
|
|
359
440
|
platform: {
|
|
@@ -473,6 +554,7 @@ const createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTIO
|
|
|
473
554
|
insights_overview_lifetime: lifetimeCounters(),
|
|
474
555
|
insights_sketches_lifetime: lifetimeSketches(),
|
|
475
556
|
insights_distribution: insightsDistribution(daily),
|
|
557
|
+
insights_builtin_distribution: insightsBuiltinDistribution(daily),
|
|
476
558
|
insights_latest_by_bundle: insightsLatestByBundle(daily),
|
|
477
559
|
insights_outcomes: insightsOutcomes(hourly),
|
|
478
560
|
insights_failures: insightsFailures(hourly)
|
|
@@ -480,4 +562,4 @@ const createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTIO
|
|
|
480
562
|
};
|
|
481
563
|
const insightsSchema = createInsightsSchema();
|
|
482
564
|
//#endregion
|
|
483
|
-
export { DAILY_EVENTS, DAY_MS, DEFAULT_INSIGHTS_RETENTION, HOUR_MS, createInsightsSchema, insightsSchema, isFailedCheck };
|
|
565
|
+
export { DAILY_EVENTS, DAY_MS, DEFAULT_INSIGHTS_RETENTION, HOUR_MS, bundleRefOfFilter, bundleRefsOf, createInsightsSchema, insightsSchema, isFailedCheck, isLateEvent, isLaunch };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/plugin-insights",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.37",
|
|
5
5
|
"description": "Hot Updater's Insights plugin: launch, download, and update failure events, for the server and the React Native app",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./client": {
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"package.json"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@hot-updater/protocol": "1.0.0-rc.
|
|
36
|
+
"@hot-updater/protocol": "1.0.0-rc.37"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@hot-updater/plugin-core": "^1.0.0-rc.
|
|
39
|
+
"@hot-updater/plugin-core": "^1.0.0-rc.37"
|
|
40
40
|
},
|
|
41
41
|
"peerDependenciesMeta": {
|
|
42
42
|
"@hot-updater/plugin-core": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^20",
|
|
48
48
|
"vitest": "4.1.4",
|
|
49
|
-
"@hot-updater/test-utils": "1.0.0-rc.
|
|
50
|
-
"@hot-updater/plugin-core": "1.0.0-rc.
|
|
49
|
+
"@hot-updater/test-utils": "1.0.0-rc.37",
|
|
50
|
+
"@hot-updater/plugin-core": "1.0.0-rc.37"
|
|
51
51
|
},
|
|
52
52
|
"nx": {
|
|
53
53
|
"implicitDependencies": [
|