boosten-runtime 0.1.0-alpha.1 → 0.2.1
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/chunk-VFNN22DR.js +3 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -1
- package/dist/telemetry.d.ts +46 -0
- package/dist/telemetry.js +98 -0
- package/package.json +5 -1
package/dist/chunk-VFNN22DR.js
CHANGED
|
@@ -130,8 +130,8 @@ var PIIDetectedError = class extends Error {
|
|
|
130
130
|
var _EMAIL_RE = /[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/;
|
|
131
131
|
var _IPV4_RE = /\b(?:\d{1,3}\.){3}\d{1,3}\b/;
|
|
132
132
|
var _IPV6_RE = /(?:[0-9a-f]{1,4}:){2,7}[0-9a-f]{0,4}|(?:[0-9a-f]{1,4}:)*:[0-9a-f]{1,4}/i;
|
|
133
|
-
var _JWT_RE =
|
|
134
|
-
var _BEARER_RE =
|
|
133
|
+
var _JWT_RE = /eyJ[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+\.[A-Za-z0-9_\-]+/;
|
|
134
|
+
var _BEARER_RE = /bearer\s+\S{8,}/i;
|
|
135
135
|
var _PHONE_RE = /(?:\+\d{1,3}[\s\-.]?)?\(?\d{3}\)?[\s\-.]?\d{3}[\s\-.]?\d{4}/;
|
|
136
136
|
function findDeniedValueFragment(val) {
|
|
137
137
|
if (typeof val !== "string" || val.length < 5) return null;
|
|
@@ -165,6 +165,7 @@ function findDeniedFragment(name) {
|
|
|
165
165
|
for (const t of tokens) {
|
|
166
166
|
if (t === d) return denied;
|
|
167
167
|
}
|
|
168
|
+
if (d.length >= 5 && normalized.includes(d)) return denied;
|
|
168
169
|
}
|
|
169
170
|
return null;
|
|
170
171
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export { BoostenPhase, BootKind, PerfEvent, PerfSample, ScreenScoreBreakdown } f
|
|
|
2
2
|
export { PIIDetectedError, PII_DENYLIST, assertNoPII, checkNoPII } from './no-pii.js';
|
|
3
3
|
export { SafeTransmitOptions, safeTransmit } from './transmit.js';
|
|
4
4
|
export { BOOSTEN_CHECKLIST, BoostenChecklistEntry, CHECKLIST_COUNT, CHECKLIST_VERSION, getChecklistEntry, listChecklistIds } from 'boosten-checklist';
|
|
5
|
+
export { DEFAULT_TELEMETRY_ENDPOINT, type TelemetryClient, type TelemetryOptions, type TelemetrySample, enableTelemetry } from './telemetry.js';
|
|
5
6
|
|
|
6
7
|
/** Indeed-derived mobile thresholds. ~6× stricter than Core Web Vitals. */
|
|
7
8
|
declare const SCORE_THRESHOLDS: {
|
|
@@ -29,6 +30,6 @@ declare const RATING_CUTOFFS: {
|
|
|
29
30
|
readonly good: 85;
|
|
30
31
|
readonly needsWork: 60;
|
|
31
32
|
};
|
|
32
|
-
declare const RUNTIME_VERSION = "0.
|
|
33
|
+
declare const RUNTIME_VERSION = "0.2.0";
|
|
33
34
|
|
|
34
35
|
export { RATING_CUTOFFS, RUNTIME_VERSION, SCORE_THRESHOLDS, SCORE_WEIGHTS };
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,10 @@ import {
|
|
|
8
8
|
checkNoPII
|
|
9
9
|
} from "./chunk-VFNN22DR.js";
|
|
10
10
|
import "./chunk-6F4PWJZI.js";
|
|
11
|
+
import {
|
|
12
|
+
DEFAULT_TELEMETRY_ENDPOINT,
|
|
13
|
+
enableTelemetry
|
|
14
|
+
} from "./telemetry.js";
|
|
11
15
|
|
|
12
16
|
// src/index.ts
|
|
13
17
|
import {
|
|
@@ -31,9 +35,10 @@ var RATING_CUTOFFS = {
|
|
|
31
35
|
good: 85,
|
|
32
36
|
needsWork: 60
|
|
33
37
|
};
|
|
34
|
-
var RUNTIME_VERSION = "0.
|
|
38
|
+
var RUNTIME_VERSION = "0.2.0";
|
|
35
39
|
export {
|
|
36
40
|
BOOSTEN_CHECKLIST,
|
|
41
|
+
DEFAULT_TELEMETRY_ENDPOINT,
|
|
37
42
|
CHECKLIST_COUNT,
|
|
38
43
|
CHECKLIST_VERSION,
|
|
39
44
|
PIIDetectedError,
|
|
@@ -44,6 +49,7 @@ export {
|
|
|
44
49
|
SCORE_WEIGHTS,
|
|
45
50
|
assertNoPII,
|
|
46
51
|
checkNoPII,
|
|
52
|
+
enableTelemetry,
|
|
47
53
|
getChecklistEntry,
|
|
48
54
|
listChecklistIds,
|
|
49
55
|
safeTransmit
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type SafeTransmitOptions } from "./transmit.js";
|
|
2
|
+
|
|
3
|
+
export interface TelemetryOptions {
|
|
4
|
+
installId: string;
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
packageVersion?: string;
|
|
7
|
+
fetchOptions?: SafeTransmitOptions;
|
|
8
|
+
/** Previously-issued bearer token (e.g. restored from AsyncStorage on app
|
|
9
|
+
* launch). When absent the client will call /installs/consent to get one. */
|
|
10
|
+
deleteToken?: string;
|
|
11
|
+
/** Callback fired the first time the server issues a delete token, so the
|
|
12
|
+
* host app can persist it for the next launch. */
|
|
13
|
+
onTokenIssued?: (token: string) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface TelemetrySample {
|
|
17
|
+
routeLabel: string;
|
|
18
|
+
durationMs: number;
|
|
19
|
+
rating: "good" | "needs-work" | "poor";
|
|
20
|
+
ruleId?: string;
|
|
21
|
+
metadata?: Record<string, unknown> | null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface TelemetryClient {
|
|
25
|
+
readonly installId: string;
|
|
26
|
+
readonly endpoint: string;
|
|
27
|
+
readonly enabled: boolean;
|
|
28
|
+
/** Bearer token issued by the server on first successful consent. Null
|
|
29
|
+
* until /installs/consent succeeds. Persist this for the next launch
|
|
30
|
+
* and pass it back via opts.deleteToken. */
|
|
31
|
+
readonly deleteToken: string | null;
|
|
32
|
+
consent(): Promise<number>;
|
|
33
|
+
/** Send a batch of samples. Will lazily call /installs/consent if no
|
|
34
|
+
* delete token has been issued yet. Returns the number of samples the
|
|
35
|
+
* server accepted, or 0 on auth/network failure or if disabled. */
|
|
36
|
+
transmit(samples: readonly TelemetrySample[]): Promise<number>;
|
|
37
|
+
disable(): void;
|
|
38
|
+
enable(): void;
|
|
39
|
+
/** Calls /installs/forget with the stored delete token. Returns the HTTP
|
|
40
|
+
* status, or 0 if no token was ever issued (nothing to forget remotely). */
|
|
41
|
+
forget(): Promise<number>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare const DEFAULT_TELEMETRY_ENDPOINT: string;
|
|
45
|
+
|
|
46
|
+
export declare function enableTelemetry(opts: TelemetryOptions): TelemetryClient;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { safeTransmit } from "./transmit.js";
|
|
2
|
+
import { assertNoPII } from "./no-pii.js";
|
|
3
|
+
|
|
4
|
+
var DEFAULT_TELEMETRY_ENDPOINT = "https://boosten.replit.app/api";
|
|
5
|
+
var RUNTIME_VERSION = "0.2.1";
|
|
6
|
+
|
|
7
|
+
function enableTelemetry(opts) {
|
|
8
|
+
if (!opts || typeof opts.installId !== "string" || opts.installId.length < 8) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
"enableTelemetry: opts.installId is required and must be at least 8 chars (use a UUIDv4)"
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
var installId = opts.installId;
|
|
14
|
+
var endpoint = (opts.endpoint || DEFAULT_TELEMETRY_ENDPOINT).replace(/\/+$/, "");
|
|
15
|
+
var packageVersion = opts.packageVersion || RUNTIME_VERSION;
|
|
16
|
+
var fetchOptions = opts.fetchOptions || {};
|
|
17
|
+
var enabled = true;
|
|
18
|
+
// Bearer token returned by the server on first successful consent.
|
|
19
|
+
// Required as Authorization on /samples and as deleteToken on /forget.
|
|
20
|
+
var deleteToken = (opts.deleteToken && typeof opts.deleteToken === "string") ? opts.deleteToken : null;
|
|
21
|
+
var onTokenIssued = (typeof opts.onTokenIssued === "function") ? opts.onTokenIssued : null;
|
|
22
|
+
|
|
23
|
+
async function tryRegisterConsent() {
|
|
24
|
+
try {
|
|
25
|
+
var res = await safeTransmit(
|
|
26
|
+
endpoint + "/installs/consent",
|
|
27
|
+
{ installId: installId, runtime: "js", packageVersion: packageVersion },
|
|
28
|
+
fetchOptions
|
|
29
|
+
);
|
|
30
|
+
if (res && res.ok) {
|
|
31
|
+
var body = null;
|
|
32
|
+
try { body = await res.json(); } catch (_e) { body = null; }
|
|
33
|
+
if (body && typeof body.deleteToken === "string" && body.deleteToken.length > 0) {
|
|
34
|
+
deleteToken = body.deleteToken;
|
|
35
|
+
if (onTokenIssued) {
|
|
36
|
+
try { onTokenIssued(deleteToken); } catch (_e) {}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return res ? res.status : 0;
|
|
41
|
+
} catch (_e) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
get installId() { return installId; },
|
|
48
|
+
get endpoint() { return endpoint; },
|
|
49
|
+
get enabled() { return enabled; },
|
|
50
|
+
get deleteToken() { return deleteToken; },
|
|
51
|
+
enable: function () { enabled = true; },
|
|
52
|
+
disable: function () { enabled = false; },
|
|
53
|
+
consent: async function () {
|
|
54
|
+
if (!enabled) return 0;
|
|
55
|
+
return await tryRegisterConsent();
|
|
56
|
+
},
|
|
57
|
+
transmit: async function (samples) {
|
|
58
|
+
if (!enabled || !samples || samples.length === 0) return 0;
|
|
59
|
+
if (!deleteToken) {
|
|
60
|
+
await tryRegisterConsent();
|
|
61
|
+
}
|
|
62
|
+
if (!deleteToken) return 0;
|
|
63
|
+
var batch = samples.slice(0, 100);
|
|
64
|
+
var payload = { installId: installId, packageVersion: packageVersion, samples: batch };
|
|
65
|
+
assertNoPII(payload);
|
|
66
|
+
try {
|
|
67
|
+
var authOpts = Object.assign({}, fetchOptions, {
|
|
68
|
+
headers: Object.assign(
|
|
69
|
+
{},
|
|
70
|
+
(fetchOptions && fetchOptions.headers) || {},
|
|
71
|
+
{ "Authorization": "Bearer " + deleteToken }
|
|
72
|
+
),
|
|
73
|
+
});
|
|
74
|
+
var res = await safeTransmit(endpoint + "/samples", payload, authOpts);
|
|
75
|
+
if (res.ok) return batch.length;
|
|
76
|
+
return 0;
|
|
77
|
+
} catch (_e) {
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
forget: async function () {
|
|
82
|
+
enabled = false;
|
|
83
|
+
if (!deleteToken) return 0;
|
|
84
|
+
try {
|
|
85
|
+
var res = await safeTransmit(
|
|
86
|
+
endpoint + "/installs/forget",
|
|
87
|
+
{ installId: installId, deleteToken: deleteToken },
|
|
88
|
+
fetchOptions
|
|
89
|
+
);
|
|
90
|
+
return res.status;
|
|
91
|
+
} catch (_e) {
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { DEFAULT_TELEMETRY_ENDPOINT, enableTelemetry };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "boosten-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "React Native performance runtime: tracker hook, frame sampler, boot ladder, novel detectors, score formula. Zero-config, in-memory by default.",
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"./types": {
|
|
13
13
|
"types": "./dist/types.d.ts",
|
|
14
14
|
"default": "./dist/types.js"
|
|
15
|
+
},
|
|
16
|
+
"./telemetry": {
|
|
17
|
+
"types": "./dist/telemetry.d.ts",
|
|
18
|
+
"default": "./dist/telemetry.js"
|
|
15
19
|
}
|
|
16
20
|
},
|
|
17
21
|
"files": [
|