@keyframerdev/vitals 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -53,13 +53,14 @@ Before your store release, declare it in the stores' privacy forms (App Store: D
53
53
  | `appVersion` | required | The version people see (`2.4.1`) |
54
54
  | `build` | none | The build number (`812`) |
55
55
  | `environment` | `'development'` when `__DEV__`, else `'production'` | Development reports are kept only when the project accepts development builds |
56
- | `sampleRate` | `0.1` | The share of sessions that report, until the project's settings say otherwise |
56
+ | `sampleRate` | `0.1` | The share of sessions that report. Release builds use it until the project's settings arrive, then the project's rate. Development builds always use it, and report every session when you leave it out (no daily cap either: someone is testing) |
57
57
  | `navigationRef` | none | Screens are named from its routes |
58
58
  | `screenName` | the route's name | `(route) => string`, to name routes yourself (still masked) |
59
59
  | `storage` | none | Anything with `getItem`, `setItem` and `removeItem` (AsyncStorage, an MMKV wrapper) |
60
60
  | `device` | none | `{ model, memoryBytes, memoryGb, tier, displayHz }`, read by the app (for example from `expo-device`) |
61
61
  | `appId` | none | The bundle id or package name |
62
62
  | `endpoint` | `https://vitals.keyframer.dev` | The ingest server |
63
+ | `debug` | `false` | Logs what the SDK decides, measures and sends: the session and its sampling, frames a second per thread, each report against the server's limits. Lines are tagged `[Keyframer.dev]` and go through `console.debug`, so Metro shows them as `DEBUG` (a note for you, such as development builds being off, is `INFO`; a refused report is `WARN`). For development builds |
63
64
 
64
65
  ## Call sites with file and line
65
66
 
package/dist/index.js CHANGED
@@ -624,7 +624,7 @@ var MAX_FRAME_MS = 10 * 60 * 1000;
624
624
 
625
625
  // src/version.ts
626
626
  var SDK_NAME = "@keyframerdev/vitals";
627
- var SDK_VERSION = "0.1.4";
627
+ var SDK_VERSION = "0.1.6";
628
628
 
629
629
  // src/controller.ts
630
630
  var STORAGE_KEYS = {
@@ -684,6 +684,7 @@ async function write(storage, key, value) {
684
684
  await storage.setItem(key, JSON.stringify(value));
685
685
  } catch {}
686
686
  }
687
+ var TAG = "[Keyframer.dev]";
687
688
 
688
689
  class VitalsController {
689
690
  env;
@@ -793,9 +794,12 @@ class VitalsController {
793
794
  this.seq = 0;
794
795
  this.sampleRate = this.rate();
795
796
  const env = this.opts.environment ?? "production";
796
- const devOk = env === "production" || !this.config || this.config.collect.development;
797
- let sampled = devOk && this.sampleRate > 0 && this.env.random() < this.sampleRate;
798
- if (sampled) {
797
+ const dev = env === "development";
798
+ const devOk = !dev || !this.config || this.config.collect.development;
799
+ const draw = this.env.random();
800
+ let sampled = devOk && this.sampleRate > 0 && draw < this.sampleRate;
801
+ let capped = false;
802
+ if (sampled && !dev) {
799
803
  const day = (this.env.day ?? localDay)(this.env.wall());
800
804
  if (!this.dayCount || this.dayCount.day !== day) {
801
805
  const saved = await read(this.opts.storage, STORAGE_KEYS.day);
@@ -803,9 +807,10 @@ class VitalsController {
803
807
  return;
804
808
  this.dayCount = saved && saved.day === day ? saved : { day, n: 0 };
805
809
  }
806
- if (this.dayCount.n >= VITALS_MAX_SESSIONS_PER_DAY)
810
+ if (this.dayCount.n >= VITALS_MAX_SESSIONS_PER_DAY) {
807
811
  sampled = false;
808
- else {
812
+ capped = true;
813
+ } else {
809
814
  this.dayCount.n++;
810
815
  await write(this.opts.storage, STORAGE_KEYS.day, this.dayCount);
811
816
  if (run !== this.run)
@@ -813,7 +818,8 @@ class VitalsController {
813
818
  }
814
819
  }
815
820
  this.sampled = sampled;
816
- this.debug(`session ${this.nonce.slice(0, 6)}: ${sampled ? "sampled" : "not sampled"} (rate ${this.sampleRate}, environment ${env}` + `${devOk ? "" : ", the project does not collect development builds"})`);
821
+ const why = sampled ? "" : !devOk ? ": the project does not keep development builds" : capped ? `: ${VITALS_MAX_SESSIONS_PER_DAY} sessions already reported today on this device (the daily cap)` : `: drew ${draw.toFixed(2)} against the rate`;
822
+ this.debug(`Motion Vitals ${SDK_VERSION}, session ${this.nonce.slice(0, 6)}: ${sampled ? "sampled" : "not sampled"} (rate ${this.sampleRate}, environment ${env})${why}`);
817
823
  if (!sampled)
818
824
  return;
819
825
  this.collector.clear();
@@ -1258,7 +1264,7 @@ class VitalsController {
1258
1264
  if (kept)
1259
1265
  this.debug("this project keeps development builds: this build's reports show in the dashboard's Development view");
1260
1266
  else
1261
- this.env.log?.("[keyframer vitals] This project does not keep reports from development builds, so this build sends nothing. " + `To test here, turn on "Development builds" in the project's setup on keyframer.dev, then reload. Release builds are not affected.`, "info");
1267
+ this.env.log?.(`${TAG} This project does not keep reports from development builds, so this build sends nothing. ` + `To test here, turn on "Development builds" in the project's setup on keyframer.dev, then reload. Release builds are not affected.`, "info");
1262
1268
  }
1263
1269
  if (!kept && this.sampled)
1264
1270
  this.endSampling();
@@ -1283,7 +1289,7 @@ class VitalsController {
1283
1289
  return true;
1284
1290
  }
1285
1291
  rate() {
1286
- const r = this.config ? this.config.sampleRate : this.opts?.sampleRate ?? VITALS_DEFAULT_SAMPLE_RATE;
1292
+ const r = this.opts?.environment === "development" ? this.opts.sampleRate ?? 1 : this.config ? this.config.sampleRate : this.opts?.sampleRate ?? VITALS_DEFAULT_SAMPLE_RATE;
1287
1293
  return Number.isFinite(r) ? Math.max(0, Math.min(1, r)) : VITALS_DEFAULT_SAMPLE_RATE;
1288
1294
  }
1289
1295
  clearTimers() {
@@ -1295,11 +1301,11 @@ class VitalsController {
1295
1301
  }
1296
1302
  }
1297
1303
  log(message) {
1298
- this.env.log?.(`[keyframer vitals] ${message}`);
1304
+ this.env.log?.(`${TAG} ${message}`, "warn");
1299
1305
  }
1300
1306
  debug(message) {
1301
1307
  if (this.opts?.debug)
1302
- this.env.log?.(`[keyframer vitals] ${message}`, "debug");
1308
+ this.env.log?.(`${TAG} ${message}`, "debug");
1303
1309
  }
1304
1310
  }
1305
1311
 
@@ -1450,7 +1456,7 @@ var env = {
1450
1456
  setTimeout: (fn, ms) => setTimeout(fn, ms),
1451
1457
  clearTimeout: (h) => clearTimeout(h),
1452
1458
  platform: { os: Platform.OS === "ios" ? "ios" : "android", osMajor: osMajor() },
1453
- log: (m, level) => level === "debug" || level === "info" ? console.log(m) : console.warn(m)
1459
+ log: (m, level) => level === "debug" ? console.debug(m) : level === "info" ? console.info(m) : console.warn(m)
1454
1460
  };
1455
1461
  var controller = new VitalsController(env);
1456
1462
  var jsHook = createJsHook(controller, () => checkScreen());
@@ -236,6 +236,11 @@ export declare class VitalsController {
236
236
  private developmentConfig;
237
237
  private killSwitch;
238
238
  private allowed;
239
+ /**
240
+ * Release builds: the project's rate once its config is known, the app's until then. Development builds:
241
+ * the app's own rate, else every session. Someone is testing, and the project's 10% left nine runs in
242
+ * ten silent after the first session.
243
+ */
239
244
  private rate;
240
245
  private clearTimers;
241
246
  private log;
@@ -1,3 +1,3 @@
1
1
  /** This package's version: sent in every report's `sdk`, and compared with the config's `minSdk`. Keep it in step with package.json. */
2
2
  export declare const SDK_NAME = "@keyframerdev/vitals";
3
- export declare const SDK_VERSION = "0.1.4";
3
+ export declare const SDK_VERSION = "0.1.6";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keyframerdev/vitals",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Motion Vitals for React Native: slow frames and janky animations from production, by screen and call site",
5
5
  "keywords": [
6
6
  "react-native",