@hot-updater/aws 1.0.0-rc.37 → 1.0.0-rc.39

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 CHANGED
@@ -132,9 +132,10 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
132
132
  /** A kept `UNCHANGED` row: what it changed, which the server sets. */
133
133
  readonly change?: BundleEventChange;
134
134
  /**
135
- * A download or apply that arrived after its installation already ran its
136
- * target, as when a reload cut the first runtime's report short: the
137
- * server keeps it in history, but it moves and counts nothing.
135
+ * A download or apply of a target its installation already ran, as when
136
+ * a reload cut the first runtime's report short, or a download that
137
+ * repeats the pending one: the server keeps it in history, but it moves
138
+ * and counts nothing.
138
139
  */
139
140
  readonly late?: true;
140
141
  /**
package/dist/index.d.mts CHANGED
@@ -132,9 +132,10 @@ type DatabaseBundleEventMetadata = DatabaseJsonObject & {
132
132
  /** A kept `UNCHANGED` row: what it changed, which the server sets. */
133
133
  readonly change?: BundleEventChange;
134
134
  /**
135
- * A download or apply that arrived after its installation already ran its
136
- * target, as when a reload cut the first runtime's report short: the
137
- * server keeps it in history, but it moves and counts nothing.
135
+ * A download or apply of a target its installation already ran, as when
136
+ * a reload cut the first runtime's report short, or a download that
137
+ * repeats the pending one: the server keeps it in history, but it moves
138
+ * and counts nothing.
138
139
  */
139
140
  readonly late?: true;
140
141
  /**
@@ -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.37";
4573
+ const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.39";
4574
4574
  //#endregion
4575
4575
  //#region ../../packages/server/dist/handlerVersionRoutes.mjs
4576
4576
  /**
@@ -11577,17 +11577,25 @@ const countEvent = (tx, event) => {
11577
11577
  };
11578
11578
  /**
11579
11579
  * A stored event's outcome rows: its bundle filter's hour, when it has one
11580
- * (`bundleRefsOf`), and every stored event's UTC day.
11580
+ * (`bundleRefsOf`), and every stored event's UTC day. A download that a
11581
+ * launch or crash implied counts in its bundle's download hour too, in the
11582
+ * hour of that launch or crash, so the download series covers what the
11583
+ * release's downloads count; the launch or crash is its row.
11581
11584
  */
11582
11585
  const countOutcome = (tx, event) => {
11583
11586
  const shardBy = event.install_id;
11584
- for (const bundleRef of bundleRefsOf(event)) tx.aggregate("insights_outcomes", {
11587
+ const hour = (type, bundleRef) => tx.aggregate("insights_outcomes", {
11585
11588
  platform: event.platform,
11586
11589
  channel: event.channel,
11587
- type: event.type,
11590
+ type,
11588
11591
  bundle_ref: bundleRef,
11589
11592
  bucket_start_ms: hourOf(event.received_at_ms)
11590
11593
  }, { events: 1 }, { shardBy });
11594
+ for (const bundleRef of bundleRefsOf(event)) hour(event.type, bundleRef);
11595
+ if (event.metadata.implied_download === true) hour("UPDATE_DOWNLOADED", bundleRefOfFilter({
11596
+ type: "UPDATE_DOWNLOADED",
11597
+ toBundleId: event.type === "RECOVERED" ? event.from_bundle_id : event.to_bundle_id
11598
+ }));
11591
11599
  tx.aggregate("insights_outcomes", {
11592
11600
  ...DAILY_EVENTS,
11593
11601
  bucket_start_ms: dayOf(event.received_at_ms)
@@ -11702,19 +11710,25 @@ const minBundleIdOf = (row) => row.metadata?.min_bundle_id;
11702
11710
  /** When the client made a report, from the UUIDv7 it gave it. */
11703
11711
  const madeAt = (id) => isUUIDv7(id) ? extractTimestampFromUUIDv7(id) : null;
11704
11712
  /**
11705
- * A report that arrived after its installation moved past it: a download or
11706
- * an apply of the bundle the head already runs, or an UNCHANGED report of the
11707
- * bundle an apply head left, made before that apply. A reload can cut one
11708
- * runtime's report short and deliver it after the next runtime's. It stays
11709
- * in history but moves and counts nothing.
11713
+ * A report its installation already moved past, which stays in history but
11714
+ * moves and counts nothing:
11715
+ * - a download or an apply of the bundle the head already runs, or a
11716
+ * download that repeats the head's pending one, from the same bundle to
11717
+ * the same bundle: the installation's download or launch already counted;
11718
+ * - an UNCHANGED report made, by its UUIDv7, before the head's report, even
11719
+ * after a later report replaced the apply it preceded: a reload can cut
11720
+ * one runtime's report short and deliver it after the next runtime's.
11721
+ *
11722
+ * Report IDs are made on the device, so a device whose clock jumps back has
11723
+ * its launch reports judged late until its clock passes its latest report.
11710
11724
  */
11711
11725
  const isLate = (event, head) => {
11712
11726
  if (head === null) return false;
11713
- if (event.type === "UPDATE_DOWNLOADED" || event.type === "UPDATE_APPLIED") return event.to_bundle_id === runningOf(head).bundle_id;
11714
- if (event.type === "UNCHANGED" && head.type === "UPDATE_APPLIED" && event.to_bundle_id === head.from_bundle_id) {
11727
+ if (event.type === "UPDATE_DOWNLOADED" || event.type === "UPDATE_APPLIED") return event.to_bundle_id === runningOf(head).bundle_id || event.type === "UPDATE_DOWNLOADED" && head.type === "UPDATE_DOWNLOADED" && event.from_bundle_id === head.from_bundle_id && event.to_bundle_id === head.to_bundle_id;
11728
+ if (event.type === "UNCHANGED") {
11715
11729
  const made = madeAt(event.id);
11716
- const applied = madeAt(head.id);
11717
- return made !== null && applied !== null && made < applied;
11730
+ const latest = madeAt(head.id);
11731
+ return made !== null && latest !== null && made < latest;
11718
11732
  }
11719
11733
  return false;
11720
11734
  };
@@ -12014,7 +12028,11 @@ const countRaw = async (db, filter, from, to) => {
12014
12028
  }
12015
12029
  return total;
12016
12030
  };
12017
- /** Whole hours from outcome counters; the partial hours at either edge from raw events. */
12031
+ /**
12032
+ * Whole hours from outcome counters; the partial hours at either edge from
12033
+ * raw events. A download filter's whole hours count the downloads a launch
12034
+ * or crash implied too, which its raw events do not hold.
12035
+ */
12018
12036
  const countEvents = async (db, input) => {
12019
12037
  const { filter, sinceMs, beforeReceivedAtMs } = input;
12020
12038
  const start = hourCeil(sinceMs);
@@ -12033,8 +12051,9 @@ const countEvents = async (db, input) => {
12033
12051
  return await countRaw(db, filter, sinceMs, start) + hours.reduce((sum, row) => sum + row.events, 0) + await countRaw(db, filter, end, beforeReceivedAtMs);
12034
12052
  };
12035
12053
  /**
12036
- * A bundle filter's stored events in each interval of whole hours: one read
12037
- * of its hourly counts, every interval present.
12054
+ * A bundle filter's stored events in each interval of whole hours, and for a
12055
+ * download filter the downloads a launch or crash implied: one read of its
12056
+ * hourly counts, every interval present.
12038
12057
  */
12039
12058
  const countEventSeries = async (db, input) => {
12040
12059
  const { filter, intervalMs } = input;
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.37",
4
+ "version": "1.0.0-rc.39",
5
5
  "description": "React Native OTA solution for self-hosted",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.mjs",
@@ -45,9 +45,9 @@
45
45
  "es-toolkit": "^1.32.0",
46
46
  "execa": "9.5.2",
47
47
  "mime": "^4.0.4",
48
- "@hot-updater/protocol": "1.0.0-rc.37",
49
- "@hot-updater/mock": "1.0.0-rc.37",
50
- "@hot-updater/test-utils": "1.0.0-rc.37"
48
+ "@hot-updater/protocol": "1.0.0-rc.39",
49
+ "@hot-updater/mock": "1.0.0-rc.39",
50
+ "@hot-updater/test-utils": "1.0.0-rc.39"
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.37",
66
- "@hot-updater/plugin-core": "1.0.0-rc.37",
67
- "@hot-updater/server": "1.0.0-rc.37"
65
+ "@hot-updater/cli-tools": "1.0.0-rc.39",
66
+ "@hot-updater/plugin-core": "1.0.0-rc.39",
67
+ "@hot-updater/server": "1.0.0-rc.39"
68
68
  },
69
69
  "scripts": {
70
70
  "build": "tsdown",