@zuplo/cli 7.7.8 → 7.7.9
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/node_modules/@posthog/core/dist/error-tracking/parsers/base.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/error-tracking/parsers/base.js +19 -2
- package/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs +19 -2
- package/node_modules/@posthog/core/dist/index.d.ts +7 -0
- package/node_modules/@posthog/core/dist/index.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/index.js +82 -21
- package/node_modules/@posthog/core/dist/index.mjs +4 -0
- package/node_modules/@posthog/core/dist/logs/index.d.ts +3 -2
- package/node_modules/@posthog/core/dist/logs/index.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/logs/index.js +28 -22
- package/node_modules/@posthog/core/dist/logs/index.mjs +29 -23
- package/node_modules/@posthog/core/dist/logs/logs-utils.js +1 -1
- package/node_modules/@posthog/core/dist/logs/logs-utils.mjs +2 -2
- package/node_modules/@posthog/core/dist/logs/types.d.ts +2 -2
- package/node_modules/@posthog/core/dist/metrics/index.d.ts +5 -2
- package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/metrics/index.js +28 -14
- package/node_modules/@posthog/core/dist/metrics/index.mjs +29 -15
- package/node_modules/@posthog/core/dist/metrics/metrics-utils.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/metrics/metrics-utils.js +1 -2
- package/node_modules/@posthog/core/dist/metrics/metrics-utils.mjs +2 -3
- package/node_modules/@posthog/core/dist/metrics/types.d.ts +7 -0
- package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts +32 -4
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.js +68 -20
- package/node_modules/@posthog/core/dist/posthog-core-stateless.mjs +68 -20
- package/node_modules/@posthog/core/dist/traces/config.d.ts +13 -0
- package/node_modules/@posthog/core/dist/traces/config.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/config.js +101 -0
- package/node_modules/@posthog/core/dist/traces/config.mjs +63 -0
- package/node_modules/@posthog/core/dist/traces/context.d.ts +18 -0
- package/node_modules/@posthog/core/dist/traces/context.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/context.js +53 -0
- package/node_modules/@posthog/core/dist/traces/context.mjs +15 -0
- package/node_modules/@posthog/core/dist/traces/ids.d.ts +12 -0
- package/node_modules/@posthog/core/dist/traces/ids.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/ids.js +92 -0
- package/node_modules/@posthog/core/dist/traces/ids.mjs +42 -0
- package/node_modules/@posthog/core/dist/traces/index.d.ts +150 -0
- package/node_modules/@posthog/core/dist/traces/index.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/index.js +551 -0
- package/node_modules/@posthog/core/dist/traces/index.mjs +513 -0
- package/node_modules/@posthog/core/dist/traces/otlp.d.ts +24 -0
- package/node_modules/@posthog/core/dist/traces/otlp.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/otlp.js +158 -0
- package/node_modules/@posthog/core/dist/traces/otlp.mjs +108 -0
- package/node_modules/@posthog/core/dist/traces/sanitize.d.ts +32 -0
- package/node_modules/@posthog/core/dist/traces/sanitize.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/sanitize.js +93 -0
- package/node_modules/@posthog/core/dist/traces/sanitize.mjs +43 -0
- package/node_modules/@posthog/core/dist/traces/span.d.ts +189 -0
- package/node_modules/@posthog/core/dist/traces/span.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/span.js +533 -0
- package/node_modules/@posthog/core/dist/traces/span.mjs +462 -0
- package/node_modules/@posthog/core/dist/traces/traceparent.d.ts +51 -0
- package/node_modules/@posthog/core/dist/traces/traceparent.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/traceparent.js +116 -0
- package/node_modules/@posthog/core/dist/traces/traceparent.mjs +63 -0
- package/node_modules/@posthog/core/dist/traces/types.d.ts +114 -0
- package/node_modules/@posthog/core/dist/traces/types.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/traces/types.js +18 -0
- package/node_modules/@posthog/core/dist/traces/types.mjs +1 -0
- package/node_modules/@posthog/core/dist/utils/backoff.d.ts +23 -0
- package/node_modules/@posthog/core/dist/utils/backoff.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/utils/backoff.js +65 -0
- package/node_modules/@posthog/core/dist/utils/backoff.mjs +14 -0
- package/node_modules/@posthog/core/dist/utils/flush-timer.d.ts +26 -0
- package/node_modules/@posthog/core/dist/utils/flush-timer.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/utils/flush-timer.js +67 -0
- package/node_modules/@posthog/core/dist/utils/flush-timer.mjs +29 -0
- package/node_modules/@posthog/core/dist/utils/json-utils.d.ts +7 -0
- package/node_modules/@posthog/core/dist/utils/json-utils.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/utils/json-utils.js +27 -0
- package/node_modules/@posthog/core/dist/utils/json-utils.mjs +25 -1
- package/node_modules/@posthog/core/dist/utils/otlp-resource.d.ts +13 -2
- package/node_modules/@posthog/core/dist/utils/otlp-resource.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/utils/otlp-resource.js +34 -7
- package/node_modules/@posthog/core/dist/utils/otlp-resource.mjs +26 -2
- package/node_modules/@posthog/core/dist/utils/retry-after.d.ts +55 -0
- package/node_modules/@posthog/core/dist/utils/retry-after.d.ts.map +1 -0
- package/node_modules/@posthog/core/dist/utils/retry-after.js +95 -0
- package/node_modules/@posthog/core/dist/utils/retry-after.mjs +50 -0
- package/node_modules/@posthog/core/package.json +3 -3
- package/node_modules/@posthog/core/src/error-tracking/parsers/base.spec.ts +77 -7
- package/node_modules/@posthog/core/src/error-tracking/parsers/base.ts +42 -19
- package/node_modules/@posthog/core/src/index.ts +18 -0
- package/node_modules/@posthog/core/src/logs/index.spec.ts +490 -2
- package/node_modules/@posthog/core/src/logs/index.ts +63 -31
- package/node_modules/@posthog/core/src/logs/logs-utils.ts +2 -2
- package/node_modules/@posthog/core/src/logs/types.ts +2 -2
- package/node_modules/@posthog/core/src/metrics/index.spec.ts +304 -0
- package/node_modules/@posthog/core/src/metrics/index.ts +53 -16
- package/node_modules/@posthog/core/src/metrics/metrics-utils.ts +2 -3
- package/node_modules/@posthog/core/src/metrics/types.ts +10 -2
- package/node_modules/@posthog/core/src/posthog-core-stateless.ts +157 -38
- package/node_modules/@posthog/core/src/traces/config.spec.ts +271 -0
- package/node_modules/@posthog/core/src/traces/config.ts +142 -0
- package/node_modules/@posthog/core/src/traces/context.ts +30 -0
- package/node_modules/@posthog/core/src/traces/ids.spec.ts +115 -0
- package/node_modules/@posthog/core/src/traces/ids.ts +75 -0
- package/node_modules/@posthog/core/src/traces/index.spec.ts +3187 -0
- package/node_modules/@posthog/core/src/traces/index.ts +1060 -0
- package/node_modules/@posthog/core/src/traces/live-spans.spec.ts +69 -0
- package/node_modules/@posthog/core/src/traces/otlp.spec.ts +368 -0
- package/node_modules/@posthog/core/src/traces/otlp.ts +191 -0
- package/node_modules/@posthog/core/src/traces/sanitize.ts +116 -0
- package/node_modules/@posthog/core/src/traces/span.spec.ts +1122 -0
- package/node_modules/@posthog/core/src/traces/span.ts +822 -0
- package/node_modules/@posthog/core/src/traces/traceparent.spec.ts +184 -0
- package/node_modules/@posthog/core/src/traces/traceparent.ts +172 -0
- package/node_modules/@posthog/core/src/traces/types.ts +140 -0
- package/node_modules/@posthog/core/src/utils/backoff.ts +44 -0
- package/node_modules/@posthog/core/src/utils/flush-timer.ts +50 -0
- package/node_modules/@posthog/core/src/utils/json-utils.ts +33 -0
- package/node_modules/@posthog/core/src/utils/otlp-resource.spec.ts +55 -9
- package/node_modules/@posthog/core/src/utils/otlp-resource.ts +45 -4
- package/node_modules/@posthog/core/src/utils/retry-after.ts +135 -0
- package/node_modules/@posthog/types/dist/index.d.ts +1 -0
- package/node_modules/@posthog/types/dist/index.d.ts.map +1 -1
- package/node_modules/@posthog/types/dist/posthog-config.d.ts +10 -5
- package/node_modules/@posthog/types/dist/posthog-config.d.ts.map +1 -1
- package/node_modules/@posthog/types/dist/traces.d.ts +387 -0
- package/node_modules/@posthog/types/dist/traces.d.ts.map +1 -0
- package/node_modules/@posthog/types/dist/traces.js +18 -0
- package/node_modules/@posthog/types/dist/traces.mjs +1 -0
- package/node_modules/@posthog/types/package.json +1 -1
- package/node_modules/@posthog/types/src/index.ts +19 -0
- package/node_modules/@posthog/types/src/posthog-config.ts +10 -5
- package/node_modules/@posthog/types/src/traces.ts +429 -0
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/package.json +1 -1
- package/node_modules/@zuplo/openapi-tools/package.json +1 -1
- package/node_modules/@zuplo/otel/package.json +1 -1
- package/node_modules/@zuplo/runtime/out/esm/{chunk-DRQ5CMVC.js → chunk-KNAYKBEE.js} +80 -80
- package/node_modules/@zuplo/runtime/out/esm/chunk-KNAYKBEE.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/package.json +11 -11
- package/node_modules/@zuplo/runtime/out/esm/chunk-DRQ5CMVC.js.map +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-DRQ5CMVC.js.LEGAL.txt → chunk-KNAYKBEE.js.LEGAL.txt} +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Longest `Retry-After` the SDK will wait. A rate-limit window can legitimately
|
|
3
|
+
* be long, but nothing upstream of the SDK bounds this header — it is as likely
|
|
4
|
+
* to come from a proxy or CDN as from PostHog — and an unbounded value would
|
|
5
|
+
* strand a queue for hours, so the wait is capped and the retry happens early.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MAX_RETRY_AFTER_MS: number;
|
|
8
|
+
/**
|
|
9
|
+
* `Retry-After` as milliseconds from now. The header is either delta-seconds or
|
|
10
|
+
* an HTTP-date; anything else, a date already in the past, or a non-positive
|
|
11
|
+
* delta yields `undefined` so the caller keeps its own backoff. The result is
|
|
12
|
+
* capped at `MAX_RETRY_AFTER_MS`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseRetryAfterMs(value: unknown, now?: number): number | undefined;
|
|
15
|
+
/** The part of an export outcome the window reads. */
|
|
16
|
+
export type RetryAfterOutcome = {
|
|
17
|
+
kind: 'ok' | 'retry-later' | 'too-large' | 'fatal';
|
|
18
|
+
retryAfterMs?: number;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* The wait an ingestion endpoint asked for, shared by the logs, metrics and
|
|
22
|
+
* traces export queues.
|
|
23
|
+
*
|
|
24
|
+
* Held as an absolute deadline rather than a duration, so a timer armed while
|
|
25
|
+
* the wait is already part-served counts down the remainder instead of
|
|
26
|
+
* restarting it.
|
|
27
|
+
*/
|
|
28
|
+
export declare class RetryAfterWindow {
|
|
29
|
+
private _until;
|
|
30
|
+
private _installedAt;
|
|
31
|
+
/**
|
|
32
|
+
* Folds one export outcome into the window.
|
|
33
|
+
*
|
|
34
|
+
* A refusal naming a longer wait than the one being served pushes the
|
|
35
|
+
* deadline out, but never past `MAX_RETRY_AFTER_MS` from where the window was
|
|
36
|
+
* first installed. That ceiling is the SDK's own policy rather than OTLP's,
|
|
37
|
+
* which asks for the header to be honoured and names no cap: a host flushing
|
|
38
|
+
* faster than the window is long would otherwise refresh the deadline forever
|
|
39
|
+
* and never recover, since logs gates its size trigger and `onReconnect` on
|
|
40
|
+
* the window and metrics re-arms its timer from it. The cost is that a wait
|
|
41
|
+
* longer than the ceiling is served short.
|
|
42
|
+
*
|
|
43
|
+
* The deadline is never pulled in, so a shorter header cannot cut a wait the
|
|
44
|
+
* endpoint already asked for.
|
|
45
|
+
*/
|
|
46
|
+
record(outcome: RetryAfterOutcome): void;
|
|
47
|
+
/**
|
|
48
|
+
* Milliseconds left of the wait, `0` when none is open. Closes a window it
|
|
49
|
+
* finds spent, so a later backward clock step cannot bring it back.
|
|
50
|
+
*/
|
|
51
|
+
remainingMs(): number;
|
|
52
|
+
isOpen(): boolean;
|
|
53
|
+
reset(): void;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=retry-after.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-after.d.ts","sourceRoot":"","sources":["../../src/utils/retry-after.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,QAAa,CAAA;AAS5C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,SAAS,CAuB9F;AAED,sDAAsD;AACtD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,IAAI,GAAG,aAAa,GAAG,WAAW,GAAG,OAAO,CAAA;IAClD,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAI;IAClB,OAAO,CAAC,YAAY,CAAI;IAExB;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IA8BxC;;;OAGG;IACH,WAAW,IAAI,MAAM;IAarB,MAAM,IAAI,OAAO;IAIjB,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
const MAX_RETRY_AFTER_MS = 300000;
|
|
31
|
+
const CLOCK_STEP_TOLERANCE_MS = 5000;
|
|
32
|
+
function parseRetryAfterMs(value, now = Date.now()) {
|
|
33
|
+
if ('string' != typeof value || !value) return;
|
|
34
|
+
const raw = value.trim();
|
|
35
|
+
const trimmed = /^\d+\s*,/.test(raw) ? raw.slice(0, raw.indexOf(',')).trim() : raw;
|
|
36
|
+
const seconds = /^\d+$/.test(trimmed) ? Number(trimmed) : 0 / 0;
|
|
37
|
+
if (!Number.isFinite(seconds) && /^[+-]?[\d.]+$/.test(trimmed)) return;
|
|
38
|
+
const ms = Number.isFinite(seconds) ? 1000 * seconds : Date.parse(trimmed) - now;
|
|
39
|
+
if (!Number.isFinite(ms) || ms <= 0) return;
|
|
40
|
+
return Math.min(ms, MAX_RETRY_AFTER_MS);
|
|
41
|
+
}
|
|
42
|
+
class RetryAfterWindow {
|
|
43
|
+
record(outcome) {
|
|
44
|
+
if ('too-large' === outcome.kind) return;
|
|
45
|
+
if ('retry-later' !== outcome.kind) return void this.reset();
|
|
46
|
+
if (!outcome.retryAfterMs) return;
|
|
47
|
+
const open = this.isOpen();
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
const asked = Math.min(outcome.retryAfterMs, MAX_RETRY_AFTER_MS);
|
|
50
|
+
if (!open) {
|
|
51
|
+
this._installedAt = now;
|
|
52
|
+
this._until = now + asked;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this._until = Math.max(this._until, Math.min(now + asked, this._installedAt + MAX_RETRY_AFTER_MS));
|
|
56
|
+
}
|
|
57
|
+
remainingMs() {
|
|
58
|
+
const now = Date.now();
|
|
59
|
+
if (now < this._installedAt - CLOCK_STEP_TOLERANCE_MS) {
|
|
60
|
+
this.reset();
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
const remaining = Math.min(MAX_RETRY_AFTER_MS, Math.max(0, this._until - now));
|
|
64
|
+
if (0 === remaining) this.reset();
|
|
65
|
+
return remaining;
|
|
66
|
+
}
|
|
67
|
+
isOpen() {
|
|
68
|
+
return this.remainingMs() > 0;
|
|
69
|
+
}
|
|
70
|
+
reset() {
|
|
71
|
+
this._until = 0;
|
|
72
|
+
this._installedAt = 0;
|
|
73
|
+
}
|
|
74
|
+
constructor(){
|
|
75
|
+
this._until = 0;
|
|
76
|
+
this._installedAt = 0;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
80
|
+
RetryAfterWindow: ()=>RetryAfterWindow,
|
|
81
|
+
parseRetryAfterMs: ()=>parseRetryAfterMs
|
|
82
|
+
}, {
|
|
83
|
+
MAX_RETRY_AFTER_MS: MAX_RETRY_AFTER_MS
|
|
84
|
+
});
|
|
85
|
+
exports.MAX_RETRY_AFTER_MS = __webpack_exports__.MAX_RETRY_AFTER_MS;
|
|
86
|
+
exports.RetryAfterWindow = __webpack_exports__.RetryAfterWindow;
|
|
87
|
+
exports.parseRetryAfterMs = __webpack_exports__.parseRetryAfterMs;
|
|
88
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
89
|
+
"MAX_RETRY_AFTER_MS",
|
|
90
|
+
"RetryAfterWindow",
|
|
91
|
+
"parseRetryAfterMs"
|
|
92
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
93
|
+
Object.defineProperty(exports, '__esModule', {
|
|
94
|
+
value: true
|
|
95
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const MAX_RETRY_AFTER_MS = 300000;
|
|
2
|
+
const CLOCK_STEP_TOLERANCE_MS = 5000;
|
|
3
|
+
function parseRetryAfterMs(value, now = Date.now()) {
|
|
4
|
+
if ('string' != typeof value || !value) return;
|
|
5
|
+
const raw = value.trim();
|
|
6
|
+
const trimmed = /^\d+\s*,/.test(raw) ? raw.slice(0, raw.indexOf(',')).trim() : raw;
|
|
7
|
+
const seconds = /^\d+$/.test(trimmed) ? Number(trimmed) : 0 / 0;
|
|
8
|
+
if (!Number.isFinite(seconds) && /^[+-]?[\d.]+$/.test(trimmed)) return;
|
|
9
|
+
const ms = Number.isFinite(seconds) ? 1000 * seconds : Date.parse(trimmed) - now;
|
|
10
|
+
if (!Number.isFinite(ms) || ms <= 0) return;
|
|
11
|
+
return Math.min(ms, MAX_RETRY_AFTER_MS);
|
|
12
|
+
}
|
|
13
|
+
class RetryAfterWindow {
|
|
14
|
+
record(outcome) {
|
|
15
|
+
if ('too-large' === outcome.kind) return;
|
|
16
|
+
if ('retry-later' !== outcome.kind) return void this.reset();
|
|
17
|
+
if (!outcome.retryAfterMs) return;
|
|
18
|
+
const open = this.isOpen();
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
const asked = Math.min(outcome.retryAfterMs, MAX_RETRY_AFTER_MS);
|
|
21
|
+
if (!open) {
|
|
22
|
+
this._installedAt = now;
|
|
23
|
+
this._until = now + asked;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this._until = Math.max(this._until, Math.min(now + asked, this._installedAt + MAX_RETRY_AFTER_MS));
|
|
27
|
+
}
|
|
28
|
+
remainingMs() {
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
if (now < this._installedAt - CLOCK_STEP_TOLERANCE_MS) {
|
|
31
|
+
this.reset();
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
const remaining = Math.min(MAX_RETRY_AFTER_MS, Math.max(0, this._until - now));
|
|
35
|
+
if (0 === remaining) this.reset();
|
|
36
|
+
return remaining;
|
|
37
|
+
}
|
|
38
|
+
isOpen() {
|
|
39
|
+
return this.remainingMs() > 0;
|
|
40
|
+
}
|
|
41
|
+
reset() {
|
|
42
|
+
this._until = 0;
|
|
43
|
+
this._installedAt = 0;
|
|
44
|
+
}
|
|
45
|
+
constructor(){
|
|
46
|
+
this._until = 0;
|
|
47
|
+
this._installedAt = 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export { MAX_RETRY_AFTER_MS, RetryAfterWindow, parseRetryAfterMs };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@posthog/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.53.0",
|
|
4
4
|
"bugs": {
|
|
5
5
|
"url": "https://github.com/PostHog/posthog-js/issues"
|
|
6
6
|
},
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
}
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@posthog/types": "^1.
|
|
73
|
+
"@posthog/types": "^1.411.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@rslib/core": "0.23.2",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"lint:fix": "oxlint --report-unused-disable-directives-severity error src --fix",
|
|
85
85
|
"build": "rslib build",
|
|
86
86
|
"dev": "rslib build -w",
|
|
87
|
-
"test:unit": "vitest run",
|
|
87
|
+
"test:unit": "NODE_OPTIONS=--expose-gc vitest run",
|
|
88
88
|
"package": "pnpm pack --out $PACKAGE_DEST/%s.tgz"
|
|
89
89
|
}
|
|
90
90
|
}
|
|
@@ -1,21 +1,47 @@
|
|
|
1
1
|
import { createFrame } from './base'
|
|
2
2
|
import { createDefaultStackParser } from './index'
|
|
3
3
|
|
|
4
|
-
describe('createFrame', () => {
|
|
5
|
-
const platform = 'web:javascript'
|
|
6
|
-
|
|
4
|
+
describe.each(['web:javascript', 'hermes'] as const)('createFrame (%s)', (platform) => {
|
|
7
5
|
it('marks ordinary browser frames as in_app', () => {
|
|
8
6
|
const frame = createFrame(platform, 'https://example.com/app.js', 'doThing', 1, 2)
|
|
9
7
|
expect(frame.in_app).toBe(true)
|
|
10
8
|
})
|
|
11
9
|
|
|
12
|
-
it(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
it.each([
|
|
11
|
+
['Safari masking an extension content script', 'webkit-masked-url://hidden/'],
|
|
12
|
+
['an Android in-app browser bridge', 'iabjs://navigation_performance_logger_android'],
|
|
13
|
+
['a Chromium extension content script', 'chrome-extension://abcdef/content.js'],
|
|
14
|
+
['a Firefox extension content script', 'moz-extension://abcdef/content.js'],
|
|
15
|
+
['a Safari extension, which the parser prefixes with a bare scheme', 'safari-extension:abcdef/content.js'],
|
|
16
|
+
['a Safari web extension', 'safari-web-extension:abcdef/content.js'],
|
|
17
|
+
['an extension with a mixed-case scheme', 'CHROME-Extension://abcdef/content.js'],
|
|
18
|
+
['an unknown container scheme', 'other-bridge://injected.js'],
|
|
19
|
+
['an inline data URL', 'data:text/javascript,void 0'],
|
|
20
|
+
])('does not mark a frame the container injected as in_app: %s', (_name, filename) => {
|
|
21
|
+
const frame = createFrame(platform, filename, 'doThing', 1, 2)
|
|
16
22
|
expect(frame.in_app).toBe(false)
|
|
17
23
|
})
|
|
18
24
|
|
|
25
|
+
it.each([
|
|
26
|
+
['a script served over http', 'http://localhost:8000/app.js'],
|
|
27
|
+
['a Cordova or Electron app served from disk', 'file:///android_asset/www/app.js'],
|
|
28
|
+
['a worker the page created from a blob', 'blob:https://example.com/6b0b0e6a'],
|
|
29
|
+
['a Capacitor webview', 'capacitor://localhost/app.js'],
|
|
30
|
+
['an Ionic webview', 'ionic://localhost/app.js'],
|
|
31
|
+
['a script with a mixed-case scheme', 'HTTPS://example.com/app.js'],
|
|
32
|
+
['a webpack source frame', 'webpack:///./src/App.js'],
|
|
33
|
+
['an Angular JIT component', 'ng:///CheckoutComponent.js'],
|
|
34
|
+
['a custom app scheme, as an Electron or React Native shell serves', 'app://checkout.js'],
|
|
35
|
+
['a bundler-rewritten dev frame', 'webpack-internal:///./src/App.js'],
|
|
36
|
+
['a React Native release bundle, which has no scheme', 'index.android.bundle'],
|
|
37
|
+
['an absolute path with no scheme', '/data/user/0/com.example/files/index.bundle'],
|
|
38
|
+
['a Windows path with backslashes', 'C:\\app\\index.bundle'],
|
|
39
|
+
['a Windows path with forward slashes', 'C:/app/index.bundle'],
|
|
40
|
+
])("still marks the app's own code as in_app: %s", (_name, filename) => {
|
|
41
|
+
const frame = createFrame(platform, filename, 'doThing', 1, 2)
|
|
42
|
+
expect(frame.in_app).toBe(true)
|
|
43
|
+
})
|
|
44
|
+
|
|
19
45
|
it('keeps the masked frame rather than discarding it', () => {
|
|
20
46
|
const frame = createFrame(platform, 'webkit-masked-url://hidden/', 'someFn', 3, 4)
|
|
21
47
|
expect(frame).toMatchObject({
|
|
@@ -70,6 +96,50 @@ describe('createDefaultStackParser in_app classification', () => {
|
|
|
70
96
|
])
|
|
71
97
|
})
|
|
72
98
|
|
|
99
|
+
it('demotes the bridge frames an Android in-app browser serves from its own scheme', () => {
|
|
100
|
+
const frames = parse(
|
|
101
|
+
'Error: Error invoking postMessage: Java object is gone\n' +
|
|
102
|
+
' at sendDataToNative (iabjs://navigation_performance_logger_android:1:10198)\n' +
|
|
103
|
+
' at sendJsBlockingTimeMessage (iabjs://navigation_performance_logger_android:1:14668)'
|
|
104
|
+
)
|
|
105
|
+
expect(frames.map((f) => [f.function, f.in_app])).toEqual([
|
|
106
|
+
['sendJsBlockingTimeMessage', false],
|
|
107
|
+
['sendDataToNative', false],
|
|
108
|
+
])
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it.each([
|
|
112
|
+
' at CheckoutComponent_Template (ng:///CheckoutComponent.js:10:5)',
|
|
113
|
+
'CheckoutComponent_Template@ng:///CheckoutComponent.js:10:5',
|
|
114
|
+
])('keeps Angular JIT application frames as in_app: %s', (stackLine) => {
|
|
115
|
+
const frames = parse(`Error: template failed\n${stackLine}`)
|
|
116
|
+
expect(frames).toEqual([
|
|
117
|
+
expect.objectContaining({
|
|
118
|
+
filename: 'ng:///CheckoutComponent.js',
|
|
119
|
+
function: 'CheckoutComponent_Template',
|
|
120
|
+
lineno: 10,
|
|
121
|
+
colno: 5,
|
|
122
|
+
in_app: true,
|
|
123
|
+
}),
|
|
124
|
+
])
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it.each([
|
|
128
|
+
'webkit-masked-url://hidden/',
|
|
129
|
+
'<anonymous>',
|
|
130
|
+
'iabjs://navigation_performance_logger_android',
|
|
131
|
+
'chrome-extension://abcdef/content.js',
|
|
132
|
+
'moz-extension://abcdef/content.js',
|
|
133
|
+
])('retains injected frames without demoting the calling app frame: %s', (filename) => {
|
|
134
|
+
const frames = parse(
|
|
135
|
+
`Error: boom\n at injected (${filename}:1:2)\n at checkout (https://example.com/app.js:10:5)`
|
|
136
|
+
)
|
|
137
|
+
expect(frames.map((frame) => [frame.filename, frame.in_app])).toEqual([
|
|
138
|
+
['https://example.com/app.js', true],
|
|
139
|
+
[filename, false],
|
|
140
|
+
])
|
|
141
|
+
})
|
|
142
|
+
|
|
73
143
|
it("keeps the page's own eval'd code as in_app", () => {
|
|
74
144
|
// V8 attributes eval'd code to the script that called eval; the chrome parser already
|
|
75
145
|
// rewrites these frames to that URL, so they must not be caught by the <anonymous> rule.
|
|
@@ -7,21 +7,47 @@ import { StackFrame } from '../types'
|
|
|
7
7
|
|
|
8
8
|
export const UNKNOWN_FUNCTION = '?'
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
const MASKED_URL_PREFIX = 'webkit-masked-url://'
|
|
16
|
-
|
|
17
|
-
// Chromium's counterpart: a script with no URL at all -- code injected by an extension
|
|
18
|
-
// (`chrome.scripting.executeScript`), pasted into devtools, or evaluated from a string -- shows
|
|
19
|
-
// up as a bare `<anonymous>:line:col` frame. The page's own eval'd code is *not* affected: V8
|
|
20
|
-
// reports it as `eval at <anonymous> (https://site/app.js:1:2)` and the chrome parser already
|
|
21
|
-
// rewrites that to the site URL. A bare `<anonymous>` can never be symbolicated, so treating it
|
|
22
|
-
// as in_app only ever pulled an unresolvable frame into the site's own stack.
|
|
10
|
+
// Chromium reports a script with no URL at all -- code injected by an extension
|
|
11
|
+
// (`chrome.scripting.executeScript`), pasted into devtools, or evaluated from a string -- as a bare
|
|
12
|
+
// `<anonymous>:line:col` frame. The page's own eval'd code is *not* affected: V8 reports it as
|
|
13
|
+
// `eval at <anonymous> (https://site/app.js:1:2)` and the chrome parser already rewrites that to
|
|
14
|
+
// the site URL. A bare `<anonymous>` can never be symbolicated.
|
|
23
15
|
const ANONYMOUS_FILENAME = '<anonymous>'
|
|
24
16
|
|
|
17
|
+
// A leading `scheme:` in a filename, needing two characters or more so that a Windows drive letter
|
|
18
|
+
// such as `C:` does not read as one.
|
|
19
|
+
const URL_SCHEME = /^([a-z][a-z0-9.+-]+):/i
|
|
20
|
+
|
|
21
|
+
// The schemes an app is served over. Everything else names code the container put into the page
|
|
22
|
+
// rather than code the app loaded: Safari masks extension content scripts as `webkit-masked-url://`,
|
|
23
|
+
// Chromium serves them from `chrome-extension://`, and Android in-app browsers serve their native
|
|
24
|
+
// bridge from schemes such as `iabjs://`. Listing every injector's scheme never keeps up with the
|
|
25
|
+
// next one, so accept the schemes an app is served over and reject the rest.
|
|
26
|
+
const APP_URL_SCHEMES = [
|
|
27
|
+
'http',
|
|
28
|
+
'https',
|
|
29
|
+
'file',
|
|
30
|
+
'blob',
|
|
31
|
+
'app',
|
|
32
|
+
'capacitor',
|
|
33
|
+
'ionic',
|
|
34
|
+
'webpack',
|
|
35
|
+
'webpack-internal',
|
|
36
|
+
'ng',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
// Is this filename a script the app itself loaded? A filename with no scheme is one: React Native
|
|
40
|
+
// names its own bundle `index.android.bundle`, and a bundler can report a bare path.
|
|
41
|
+
function isAppFilename(filename: string): boolean {
|
|
42
|
+
if (!filename || filename === ANONYMOUS_FILENAME) {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const scheme = URL_SCHEME.exec(filename)
|
|
47
|
+
|
|
48
|
+
return !scheme || APP_URL_SCHEMES.includes((scheme[1] as string).toLowerCase())
|
|
49
|
+
}
|
|
50
|
+
|
|
25
51
|
export function createFrame(
|
|
26
52
|
platform: StackFrame['platform'],
|
|
27
53
|
filename: string,
|
|
@@ -34,12 +60,9 @@ export function createFrame(
|
|
|
34
60
|
platform,
|
|
35
61
|
filename,
|
|
36
62
|
function: func === '<anonymous>' ? UNKNOWN_FUNCTION : func,
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
// bridge scripts this way. Such a frame can never be symbolicated either, so it must not
|
|
41
|
-
// count as the page's own code.
|
|
42
|
-
in_app: !!filename && !filename.startsWith(MASKED_URL_PREFIX) && filename !== ANONYMOUS_FILENAME,
|
|
63
|
+
// Keep a frame the app did not load -- it is still useful context -- but do not let it count as
|
|
64
|
+
// in_app and pull the issue into the app's own stack.
|
|
65
|
+
in_app: isAppFilename(filename),
|
|
43
66
|
}
|
|
44
67
|
|
|
45
68
|
if (!isUndefined(lineno)) {
|
|
@@ -87,6 +87,24 @@ export type {
|
|
|
87
87
|
Metrics,
|
|
88
88
|
MetricsConfig,
|
|
89
89
|
} from './metrics/types'
|
|
90
|
+
export { PostHogTraces } from './traces'
|
|
91
|
+
export { SyncSpanContextManager } from './traces/context'
|
|
92
|
+
export { inertSpan, runWithActiveSpan } from './traces/span'
|
|
93
|
+
export { resolveTracesConfig } from './traces/config'
|
|
94
|
+
export type { ResolvedTracesConfig, SpanContextManager, TraceSdkContext } from './traces/types'
|
|
95
|
+
// The `beforeSpanSend` shapes come straight from @posthog/types: hooks see the
|
|
96
|
+
// public record, not core's internal one, which also carries `traceState`.
|
|
97
|
+
export type { SpanRecord, BeforeSpanSendFn } from '@posthog/types'
|
|
98
|
+
export type {
|
|
99
|
+
Span,
|
|
100
|
+
SpanAttributes,
|
|
101
|
+
SpanAttributeValue,
|
|
102
|
+
SpanKind,
|
|
103
|
+
SpanStatusCode,
|
|
104
|
+
SpanTimeInput,
|
|
105
|
+
StartSpanOptions,
|
|
106
|
+
TracesConfig,
|
|
107
|
+
} from './traces/types'
|
|
90
108
|
export { uuidv7 } from './vendor/uuidv7'
|
|
91
109
|
export * from './cookie'
|
|
92
110
|
export * from './posthog-core'
|