@hot-updater/plugin-insights 1.0.0-rc.31 → 1.0.0-rc.33
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 +1 -1
- package/dist/server/contract.mjs +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +3 -3
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/server/modelTypes.d.cts +4 -1
- package/dist/server/modelTypes.d.mts +4 -1
- package/dist/server/overview.cjs +14 -16
- package/dist/server/overview.mjs +14 -16
- package/dist/server/reads.cjs +1 -1
- package/dist/server/reads.mjs +1 -1
- package/dist/server/recordEvent.cjs +1 -1
- package/dist/server/recordEvent.mjs +1 -1
- package/dist/server/schema.cjs +29 -16
- package/dist/server/schema.d.cts +6 -6
- package/dist/server/schema.d.mts +6 -6
- package/dist/server/schema.mjs +29 -16
- package/package.json +5 -5
package/dist/server/contract.cjs
CHANGED
|
@@ -166,7 +166,7 @@ const createValidatedInsightsModel = (model) => ({
|
|
|
166
166
|
async getReleaseActivity(input) {
|
|
167
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
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.
|
|
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.applies) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
|
|
170
170
|
return result;
|
|
171
171
|
},
|
|
172
172
|
async getAppUsage(input) {
|
package/dist/server/contract.mjs
CHANGED
|
@@ -166,7 +166,7 @@ const createValidatedInsightsModel = (model) => ({
|
|
|
166
166
|
async getReleaseActivity(input) {
|
|
167
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
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.
|
|
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.applies) || !isTimestamp(item.metrics.failedLaunches))) invalidResult();
|
|
170
170
|
return result;
|
|
171
171
|
},
|
|
172
172
|
async getAppUsage(input) {
|
package/dist/server/index.cjs
CHANGED
|
@@ -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.4.0",
|
|
92
92
|
schema: require_schema.createInsightsSchema(retention),
|
|
93
93
|
init: ({ db, now }) => {
|
|
94
94
|
const api = createInsightsApi(db, now, retention);
|
package/dist/server/index.d.cts
CHANGED
|
@@ -180,7 +180,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
180
180
|
readonly bucket_start_ms: {
|
|
181
181
|
readonly type: "integer";
|
|
182
182
|
};
|
|
183
|
-
}, "downloads" | "
|
|
183
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
184
184
|
readonly window: {
|
|
185
185
|
readonly eq: readonly ["identity"];
|
|
186
186
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -208,7 +208,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
208
208
|
readonly bucket_start_ms: {
|
|
209
209
|
readonly type: "integer";
|
|
210
210
|
};
|
|
211
|
-
}, "downloads" | "
|
|
211
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
212
212
|
readonly window: {
|
|
213
213
|
readonly eq: readonly ["identity"];
|
|
214
214
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -236,7 +236,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
236
236
|
readonly bucket_start_ms: {
|
|
237
237
|
readonly type: "integer";
|
|
238
238
|
};
|
|
239
|
-
}, "downloads" | "
|
|
239
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
|
|
240
240
|
readonly window: {
|
|
241
241
|
readonly eq: readonly ["identity"];
|
|
242
242
|
readonly sort: readonly ["bucket_start_ms"];
|
package/dist/server/index.d.mts
CHANGED
|
@@ -180,7 +180,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
180
180
|
readonly bucket_start_ms: {
|
|
181
181
|
readonly type: "integer";
|
|
182
182
|
};
|
|
183
|
-
}, "downloads" | "
|
|
183
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
184
184
|
readonly window: {
|
|
185
185
|
readonly eq: readonly ["identity"];
|
|
186
186
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -208,7 +208,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
208
208
|
readonly bucket_start_ms: {
|
|
209
209
|
readonly type: "integer";
|
|
210
210
|
};
|
|
211
|
-
}, "downloads" | "
|
|
211
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
212
212
|
readonly window: {
|
|
213
213
|
readonly eq: readonly ["identity"];
|
|
214
214
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -236,7 +236,7 @@ declare const insights: (options?: InsightsOptions) => import("@hot-updater/plug
|
|
|
236
236
|
readonly bucket_start_ms: {
|
|
237
237
|
readonly type: "integer";
|
|
238
238
|
};
|
|
239
|
-
}, "downloads" | "
|
|
239
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
|
|
240
240
|
readonly window: {
|
|
241
241
|
readonly eq: readonly ["identity"];
|
|
242
242
|
readonly sort: readonly ["bucket_start_ms"];
|
package/dist/server/index.mjs
CHANGED
|
@@ -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.4.0",
|
|
91
91
|
schema: createInsightsSchema(retention),
|
|
92
92
|
init: ({ db, now }) => {
|
|
93
93
|
const api = createInsightsApi(db, now, retention);
|
|
@@ -95,8 +95,11 @@ type InsightsCoverage = {
|
|
|
95
95
|
* which are kept.
|
|
96
96
|
*/
|
|
97
97
|
interface ReleaseActivityMetrics {
|
|
98
|
+
/** Download reports of the release. */
|
|
98
99
|
readonly downloads: number;
|
|
99
|
-
|
|
100
|
+
/** Apply reports of the release: installations that started running it. */
|
|
101
|
+
readonly applies: number;
|
|
102
|
+
/** Launches that crashed on the release and recovered to the one before. */
|
|
100
103
|
readonly failedLaunches: number;
|
|
101
104
|
}
|
|
102
105
|
interface InsightsGetReleaseActivityInput {
|
|
@@ -95,8 +95,11 @@ type InsightsCoverage = {
|
|
|
95
95
|
* which are kept.
|
|
96
96
|
*/
|
|
97
97
|
interface ReleaseActivityMetrics {
|
|
98
|
+
/** Download reports of the release. */
|
|
98
99
|
readonly downloads: number;
|
|
99
|
-
|
|
100
|
+
/** Apply reports of the release: installations that started running it. */
|
|
101
|
+
readonly applies: number;
|
|
102
|
+
/** Launches that crashed on the release and recovered to the one before. */
|
|
100
103
|
readonly failedLaunches: number;
|
|
101
104
|
}
|
|
102
105
|
interface InsightsGetReleaseActivityInput {
|
package/dist/server/overview.cjs
CHANGED
|
@@ -31,7 +31,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
31
31
|
counters.set(key, {
|
|
32
32
|
identity,
|
|
33
33
|
downloads: (previous?.downloads ?? 0) + values.downloads,
|
|
34
|
-
|
|
34
|
+
applies: (previous?.applies ?? 0) + values.applies,
|
|
35
35
|
failedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,
|
|
36
36
|
activityIdentity: previous?.activityIdentity ?? values.activityIdentity
|
|
37
37
|
});
|
|
@@ -39,7 +39,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
39
39
|
const metric = (releaseId, values) => {
|
|
40
40
|
const windowed = {
|
|
41
41
|
...values,
|
|
42
|
-
|
|
42
|
+
applies: 0
|
|
43
43
|
};
|
|
44
44
|
if (releaseId !== null) for (const [periodKind, start] of [["lifetime", 0], ["hour", bucketStartMs]]) append({
|
|
45
45
|
scopeKind: "release",
|
|
@@ -66,21 +66,19 @@ const insightsOverviewDeltas = (event) => {
|
|
|
66
66
|
};
|
|
67
67
|
if (event.type === "UPDATE_DOWNLOADED") metric(event.to_release_id, {
|
|
68
68
|
downloads: 1,
|
|
69
|
-
|
|
69
|
+
applies: 0,
|
|
70
70
|
failedLaunches: 0
|
|
71
71
|
});
|
|
72
|
-
else if (event.type
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
}
|
|
72
|
+
else if (event.type === "UPDATE_APPLIED") metric(event.to_release_id, {
|
|
73
|
+
downloads: 0,
|
|
74
|
+
applies: 1,
|
|
75
|
+
failedLaunches: 0
|
|
76
|
+
});
|
|
77
|
+
else if (event.type === "RECOVERED") metric(event.from_release_id, {
|
|
78
|
+
downloads: 0,
|
|
79
|
+
applies: 0,
|
|
80
|
+
failedLaunches: 1
|
|
81
|
+
});
|
|
84
82
|
for (const platform of [event.platform, "all"]) for (const appVersionKind of ["specific", "all"]) append({
|
|
85
83
|
scopeKind: "usage",
|
|
86
84
|
releaseKind: "all",
|
|
@@ -93,7 +91,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
93
91
|
bucketStartMs
|
|
94
92
|
}, {
|
|
95
93
|
downloads: 0,
|
|
96
|
-
|
|
94
|
+
applies: 0,
|
|
97
95
|
failedLaunches: 0,
|
|
98
96
|
activityIdentity: event.install_id
|
|
99
97
|
});
|
package/dist/server/overview.mjs
CHANGED
|
@@ -31,7 +31,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
31
31
|
counters.set(key, {
|
|
32
32
|
identity,
|
|
33
33
|
downloads: (previous?.downloads ?? 0) + values.downloads,
|
|
34
|
-
|
|
34
|
+
applies: (previous?.applies ?? 0) + values.applies,
|
|
35
35
|
failedLaunches: (previous?.failedLaunches ?? 0) + values.failedLaunches,
|
|
36
36
|
activityIdentity: previous?.activityIdentity ?? values.activityIdentity
|
|
37
37
|
});
|
|
@@ -39,7 +39,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
39
39
|
const metric = (releaseId, values) => {
|
|
40
40
|
const windowed = {
|
|
41
41
|
...values,
|
|
42
|
-
|
|
42
|
+
applies: 0
|
|
43
43
|
};
|
|
44
44
|
if (releaseId !== null) for (const [periodKind, start] of [["lifetime", 0], ["hour", bucketStartMs]]) append({
|
|
45
45
|
scopeKind: "release",
|
|
@@ -66,21 +66,19 @@ const insightsOverviewDeltas = (event) => {
|
|
|
66
66
|
};
|
|
67
67
|
if (event.type === "UPDATE_DOWNLOADED") metric(event.to_release_id, {
|
|
68
68
|
downloads: 1,
|
|
69
|
-
|
|
69
|
+
applies: 0,
|
|
70
70
|
failedLaunches: 0
|
|
71
71
|
});
|
|
72
|
-
else if (event.type
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
83
|
-
}
|
|
72
|
+
else if (event.type === "UPDATE_APPLIED") metric(event.to_release_id, {
|
|
73
|
+
downloads: 0,
|
|
74
|
+
applies: 1,
|
|
75
|
+
failedLaunches: 0
|
|
76
|
+
});
|
|
77
|
+
else if (event.type === "RECOVERED") metric(event.from_release_id, {
|
|
78
|
+
downloads: 0,
|
|
79
|
+
applies: 0,
|
|
80
|
+
failedLaunches: 1
|
|
81
|
+
});
|
|
84
82
|
for (const platform of [event.platform, "all"]) for (const appVersionKind of ["specific", "all"]) append({
|
|
85
83
|
scopeKind: "usage",
|
|
86
84
|
releaseKind: "all",
|
|
@@ -93,7 +91,7 @@ const insightsOverviewDeltas = (event) => {
|
|
|
93
91
|
bucketStartMs
|
|
94
92
|
}, {
|
|
95
93
|
downloads: 0,
|
|
96
|
-
|
|
94
|
+
applies: 0,
|
|
97
95
|
failedLaunches: 0,
|
|
98
96
|
activityIdentity: event.install_id
|
|
99
97
|
});
|
package/dist/server/reads.cjs
CHANGED
|
@@ -365,7 +365,7 @@ const lifetimeMetrics = async (db, release) => {
|
|
|
365
365
|
})).rows;
|
|
366
366
|
return {
|
|
367
367
|
downloads: lifetime?.downloads ?? 0,
|
|
368
|
-
|
|
368
|
+
applies: lifetime?.applies ?? 0,
|
|
369
369
|
failedLaunches: lifetime?.failed_launches ?? 0
|
|
370
370
|
};
|
|
371
371
|
};
|
package/dist/server/reads.mjs
CHANGED
|
@@ -365,7 +365,7 @@ const lifetimeMetrics = async (db, release) => {
|
|
|
365
365
|
})).rows;
|
|
366
366
|
return {
|
|
367
367
|
downloads: lifetime?.downloads ?? 0,
|
|
368
|
-
|
|
368
|
+
applies: lifetime?.applies ?? 0,
|
|
369
369
|
failedLaunches: lifetime?.failed_launches ?? 0
|
|
370
370
|
};
|
|
371
371
|
};
|
|
@@ -112,7 +112,7 @@ const countEvent = (tx, event) => {
|
|
|
112
112
|
const counters = {
|
|
113
113
|
...Object.fromEntries([
|
|
114
114
|
["downloads", delta.downloads],
|
|
115
|
-
["
|
|
115
|
+
["applies", delta.applies],
|
|
116
116
|
["failed_launches", delta.failedLaunches]
|
|
117
117
|
].filter(([, value]) => value !== 0)),
|
|
118
118
|
...delta.downloads === 0 ? {} : patchCounters(event)
|
|
@@ -112,7 +112,7 @@ const countEvent = (tx, event) => {
|
|
|
112
112
|
const counters = {
|
|
113
113
|
...Object.fromEntries([
|
|
114
114
|
["downloads", delta.downloads],
|
|
115
|
-
["
|
|
115
|
+
["applies", delta.applies],
|
|
116
116
|
["failed_launches", delta.failedLaunches]
|
|
117
117
|
].filter(([, value]) => value !== 0)),
|
|
118
118
|
...delta.downloads === 0 ? {} : patchCounters(event)
|
package/dist/server/schema.cjs
CHANGED
|
@@ -206,29 +206,42 @@ const window = {
|
|
|
206
206
|
eq: ["identity"],
|
|
207
207
|
sort: ["bucket_start_ms"]
|
|
208
208
|
};
|
|
209
|
+
/** What a release or channel row counts in every period kind. */
|
|
210
|
+
const WINDOW_COUNTERS = [
|
|
211
|
+
"downloads",
|
|
212
|
+
"failed_launches",
|
|
213
|
+
"patch_downloads",
|
|
214
|
+
"patch_fallbacks"
|
|
215
|
+
];
|
|
209
216
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* lifetime row counts launches, which the bundle list reads and no windowed
|
|
214
|
-
* read sums. It also counts the release's failed updates (`failed_updates`),
|
|
215
|
-
* since no breakdown row outlives the raw period; windowed reads sum
|
|
216
|
-
* `insights_failures` instead.
|
|
217
|
+
* Hourly or daily counters: a release or channel row counts downloads,
|
|
218
|
+
* launches that crashed and recovered (`failed_launches`), and downloads a
|
|
219
|
+
* patch delivered and those that fell back from one.
|
|
217
220
|
*/
|
|
218
221
|
const counters = (retention) => (0, _hot_updater_plugin_core.defineAggregate)(identityFields, {
|
|
222
|
+
key: ["identity", "bucket_start_ms"],
|
|
223
|
+
counters: WINDOW_COUNTERS,
|
|
224
|
+
shards: COUNTER_SHARDS,
|
|
225
|
+
batched: true,
|
|
226
|
+
indexes: { window },
|
|
227
|
+
retention
|
|
228
|
+
});
|
|
229
|
+
/**
|
|
230
|
+
* A release's counters since its first report, at bucket 0: the windowed
|
|
231
|
+
* counters, its applies, which the bundle list reads, and its failed updates
|
|
232
|
+
* (`failed_updates`), since no breakdown row outlives the raw period; windowed
|
|
233
|
+
* reads sum `insights_failures` instead.
|
|
234
|
+
*/
|
|
235
|
+
const lifetimeCounters = () => (0, _hot_updater_plugin_core.defineAggregate)(identityFields, {
|
|
219
236
|
key: ["identity", "bucket_start_ms"],
|
|
220
237
|
counters: [
|
|
221
|
-
|
|
222
|
-
"
|
|
223
|
-
"
|
|
224
|
-
"failed_updates",
|
|
225
|
-
"patch_downloads",
|
|
226
|
-
"patch_fallbacks"
|
|
238
|
+
...WINDOW_COUNTERS,
|
|
239
|
+
"applies",
|
|
240
|
+
"failed_updates"
|
|
227
241
|
],
|
|
228
242
|
shards: COUNTER_SHARDS,
|
|
229
243
|
batched: true,
|
|
230
|
-
indexes: { window }
|
|
231
|
-
...retention === void 0 ? {} : { retention }
|
|
244
|
+
indexes: { window }
|
|
232
245
|
});
|
|
233
246
|
/**
|
|
234
247
|
* Unique-installation sketches of one period kind: a usage row's active
|
|
@@ -459,7 +472,7 @@ const createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTIO
|
|
|
459
472
|
insights_overview_daily: counters(daily),
|
|
460
473
|
insights_sketches_daily: sketches(daily),
|
|
461
474
|
/** A release's counters since its first event, and its failed installations: kept. */
|
|
462
|
-
insights_overview_lifetime:
|
|
475
|
+
insights_overview_lifetime: lifetimeCounters(),
|
|
463
476
|
insights_sketches_lifetime: lifetimeSketches(),
|
|
464
477
|
insights_distribution: insightsDistribution(daily),
|
|
465
478
|
insights_latest_by_bundle: insightsLatestByBundle(daily),
|
package/dist/server/schema.d.cts
CHANGED
|
@@ -153,7 +153,7 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
153
153
|
readonly bucket_start_ms: {
|
|
154
154
|
readonly type: "integer";
|
|
155
155
|
};
|
|
156
|
-
}, "downloads" | "
|
|
156
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
157
157
|
readonly window: {
|
|
158
158
|
readonly eq: readonly ["identity"];
|
|
159
159
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -182,7 +182,7 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
182
182
|
readonly bucket_start_ms: {
|
|
183
183
|
readonly type: "integer";
|
|
184
184
|
};
|
|
185
|
-
}, "downloads" | "
|
|
185
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
186
186
|
readonly window: {
|
|
187
187
|
readonly eq: readonly ["identity"];
|
|
188
188
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -211,7 +211,7 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
211
211
|
readonly bucket_start_ms: {
|
|
212
212
|
readonly type: "integer";
|
|
213
213
|
};
|
|
214
|
-
}, "downloads" | "
|
|
214
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
|
|
215
215
|
readonly window: {
|
|
216
216
|
readonly eq: readonly ["identity"];
|
|
217
217
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -488,7 +488,7 @@ declare const insightsSchema: {
|
|
|
488
488
|
readonly bucket_start_ms: {
|
|
489
489
|
readonly type: "integer";
|
|
490
490
|
};
|
|
491
|
-
}, "downloads" | "
|
|
491
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
492
492
|
readonly window: {
|
|
493
493
|
readonly eq: readonly ["identity"];
|
|
494
494
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -517,7 +517,7 @@ declare const insightsSchema: {
|
|
|
517
517
|
readonly bucket_start_ms: {
|
|
518
518
|
readonly type: "integer";
|
|
519
519
|
};
|
|
520
|
-
}, "downloads" | "
|
|
520
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
521
521
|
readonly window: {
|
|
522
522
|
readonly eq: readonly ["identity"];
|
|
523
523
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -546,7 +546,7 @@ declare const insightsSchema: {
|
|
|
546
546
|
readonly bucket_start_ms: {
|
|
547
547
|
readonly type: "integer";
|
|
548
548
|
};
|
|
549
|
-
}, "downloads" | "
|
|
549
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
|
|
550
550
|
readonly window: {
|
|
551
551
|
readonly eq: readonly ["identity"];
|
|
552
552
|
readonly sort: readonly ["bucket_start_ms"];
|
package/dist/server/schema.d.mts
CHANGED
|
@@ -153,7 +153,7 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
153
153
|
readonly bucket_start_ms: {
|
|
154
154
|
readonly type: "integer";
|
|
155
155
|
};
|
|
156
|
-
}, "downloads" | "
|
|
156
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
157
157
|
readonly window: {
|
|
158
158
|
readonly eq: readonly ["identity"];
|
|
159
159
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -182,7 +182,7 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
182
182
|
readonly bucket_start_ms: {
|
|
183
183
|
readonly type: "integer";
|
|
184
184
|
};
|
|
185
|
-
}, "downloads" | "
|
|
185
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
186
186
|
readonly window: {
|
|
187
187
|
readonly eq: readonly ["identity"];
|
|
188
188
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -211,7 +211,7 @@ declare const createInsightsSchema: ({ rawDays, dailyDays }?: InsightsRetention)
|
|
|
211
211
|
readonly bucket_start_ms: {
|
|
212
212
|
readonly type: "integer";
|
|
213
213
|
};
|
|
214
|
-
}, "downloads" | "
|
|
214
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
|
|
215
215
|
readonly window: {
|
|
216
216
|
readonly eq: readonly ["identity"];
|
|
217
217
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -488,7 +488,7 @@ declare const insightsSchema: {
|
|
|
488
488
|
readonly bucket_start_ms: {
|
|
489
489
|
readonly type: "integer";
|
|
490
490
|
};
|
|
491
|
-
}, "downloads" | "
|
|
491
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
492
492
|
readonly window: {
|
|
493
493
|
readonly eq: readonly ["identity"];
|
|
494
494
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -517,7 +517,7 @@ declare const insightsSchema: {
|
|
|
517
517
|
readonly bucket_start_ms: {
|
|
518
518
|
readonly type: "integer";
|
|
519
519
|
};
|
|
520
|
-
}, "downloads" | "
|
|
520
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks", {
|
|
521
521
|
readonly window: {
|
|
522
522
|
readonly eq: readonly ["identity"];
|
|
523
523
|
readonly sort: readonly ["bucket_start_ms"];
|
|
@@ -546,7 +546,7 @@ declare const insightsSchema: {
|
|
|
546
546
|
readonly bucket_start_ms: {
|
|
547
547
|
readonly type: "integer";
|
|
548
548
|
};
|
|
549
|
-
}, "downloads" | "
|
|
549
|
+
}, "downloads" | "failed_launches" | "patch_downloads" | "patch_fallbacks" | "applies" | "failed_updates", {
|
|
550
550
|
readonly window: {
|
|
551
551
|
readonly eq: readonly ["identity"];
|
|
552
552
|
readonly sort: readonly ["bucket_start_ms"];
|
package/dist/server/schema.mjs
CHANGED
|
@@ -206,29 +206,42 @@ const window = {
|
|
|
206
206
|
eq: ["identity"],
|
|
207
207
|
sort: ["bucket_start_ms"]
|
|
208
208
|
};
|
|
209
|
+
/** What a release or channel row counts in every period kind. */
|
|
210
|
+
const WINDOW_COUNTERS = [
|
|
211
|
+
"downloads",
|
|
212
|
+
"failed_launches",
|
|
213
|
+
"patch_downloads",
|
|
214
|
+
"patch_fallbacks"
|
|
215
|
+
];
|
|
209
216
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
* lifetime row counts launches, which the bundle list reads and no windowed
|
|
214
|
-
* read sums. It also counts the release's failed updates (`failed_updates`),
|
|
215
|
-
* since no breakdown row outlives the raw period; windowed reads sum
|
|
216
|
-
* `insights_failures` instead.
|
|
217
|
+
* Hourly or daily counters: a release or channel row counts downloads,
|
|
218
|
+
* launches that crashed and recovered (`failed_launches`), and downloads a
|
|
219
|
+
* patch delivered and those that fell back from one.
|
|
217
220
|
*/
|
|
218
221
|
const counters = (retention) => defineAggregate(identityFields, {
|
|
222
|
+
key: ["identity", "bucket_start_ms"],
|
|
223
|
+
counters: WINDOW_COUNTERS,
|
|
224
|
+
shards: COUNTER_SHARDS,
|
|
225
|
+
batched: true,
|
|
226
|
+
indexes: { window },
|
|
227
|
+
retention
|
|
228
|
+
});
|
|
229
|
+
/**
|
|
230
|
+
* A release's counters since its first report, at bucket 0: the windowed
|
|
231
|
+
* counters, its applies, which the bundle list reads, and its failed updates
|
|
232
|
+
* (`failed_updates`), since no breakdown row outlives the raw period; windowed
|
|
233
|
+
* reads sum `insights_failures` instead.
|
|
234
|
+
*/
|
|
235
|
+
const lifetimeCounters = () => defineAggregate(identityFields, {
|
|
219
236
|
key: ["identity", "bucket_start_ms"],
|
|
220
237
|
counters: [
|
|
221
|
-
|
|
222
|
-
"
|
|
223
|
-
"
|
|
224
|
-
"failed_updates",
|
|
225
|
-
"patch_downloads",
|
|
226
|
-
"patch_fallbacks"
|
|
238
|
+
...WINDOW_COUNTERS,
|
|
239
|
+
"applies",
|
|
240
|
+
"failed_updates"
|
|
227
241
|
],
|
|
228
242
|
shards: COUNTER_SHARDS,
|
|
229
243
|
batched: true,
|
|
230
|
-
indexes: { window }
|
|
231
|
-
...retention === void 0 ? {} : { retention }
|
|
244
|
+
indexes: { window }
|
|
232
245
|
});
|
|
233
246
|
/**
|
|
234
247
|
* Unique-installation sketches of one period kind: a usage row's active
|
|
@@ -459,7 +472,7 @@ const createInsightsSchema = ({ rawDays, dailyDays } = DEFAULT_INSIGHTS_RETENTIO
|
|
|
459
472
|
insights_overview_daily: counters(daily),
|
|
460
473
|
insights_sketches_daily: sketches(daily),
|
|
461
474
|
/** A release's counters since its first event, and its failed installations: kept. */
|
|
462
|
-
insights_overview_lifetime:
|
|
475
|
+
insights_overview_lifetime: lifetimeCounters(),
|
|
463
476
|
insights_sketches_lifetime: lifetimeSketches(),
|
|
464
477
|
insights_distribution: insightsDistribution(daily),
|
|
465
478
|
insights_latest_by_bundle: insightsLatestByBundle(daily),
|
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.33",
|
|
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.29"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@hot-updater/plugin-core": "^1.0.0-rc.
|
|
39
|
+
"@hot-updater/plugin-core": "^1.0.0-rc.29"
|
|
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/plugin-core": "1.0.0-rc.
|
|
50
|
-
"@hot-updater/test-utils": "1.0.0-rc.
|
|
49
|
+
"@hot-updater/plugin-core": "1.0.0-rc.29",
|
|
50
|
+
"@hot-updater/test-utils": "1.0.0-rc.31"
|
|
51
51
|
},
|
|
52
52
|
"nx": {
|
|
53
53
|
"implicitDependencies": [
|