@zuplo/cli 6.71.21 → 6.71.23
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/exception-steps.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/error-tracking/exception-steps.js +6 -24
- package/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs +7 -25
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts +6 -0
- package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core-stateless.js +75 -17
- package/node_modules/@posthog/core/dist/posthog-core-stateless.mjs +73 -18
- package/node_modules/@posthog/core/dist/posthog-core.d.ts +2 -2
- package/node_modules/@posthog/core/dist/posthog-core.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/posthog-core.js +10 -6
- package/node_modules/@posthog/core/dist/posthog-core.mjs +11 -7
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.d.ts +1 -0
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.js +3 -0
- package/node_modules/@posthog/core/dist/testing/PostHogCoreTestClient.mjs +3 -0
- package/node_modules/@posthog/core/dist/utils/promise-queue.d.ts +3 -0
- package/node_modules/@posthog/core/dist/utils/promise-queue.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/utils/promise-queue.js +15 -3
- package/node_modules/@posthog/core/dist/utils/promise-queue.mjs +15 -3
- package/node_modules/@posthog/core/dist/utils/string-utils.d.ts +1 -0
- package/node_modules/@posthog/core/dist/utils/string-utils.d.ts.map +1 -1
- package/node_modules/@posthog/core/dist/utils/string-utils.js +21 -0
- package/node_modules/@posthog/core/dist/utils/string-utils.mjs +19 -1
- package/node_modules/@posthog/core/package.json +1 -1
- package/node_modules/@posthog/core/src/error-tracking/exception-steps.ts +5 -42
- package/node_modules/@posthog/core/src/posthog-core-stateless.ts +118 -23
- package/node_modules/@posthog/core/src/posthog-core.ts +18 -7
- package/node_modules/@posthog/core/src/testing/PostHogCoreTestClient.ts +4 -0
- package/node_modules/@posthog/core/src/utils/promise-queue.ts +17 -4
- package/node_modules/@posthog/core/src/utils/string-utils.spec.ts +38 -1
- package/node_modules/@posthog/core/src/utils/string-utils.ts +42 -0
- package/node_modules/@posthog/types/dist/posthog.d.ts +12 -0
- package/node_modules/@posthog/types/dist/posthog.d.ts.map +1 -1
- package/node_modules/@posthog/types/package.json +1 -1
- package/node_modules/@posthog/types/src/posthog.ts +13 -0
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/buffer.d.ts +64 -25
- package/node_modules/@types/node/crypto.d.ts +18 -5
- package/node_modules/@types/node/diagnostics_channel.d.ts +237 -3
- package/node_modules/@types/node/dns.d.ts +1 -1
- package/node_modules/@types/node/ffi.d.ts +486 -0
- package/node_modules/@types/node/fs/promises.d.ts +3 -0
- package/node_modules/@types/node/fs.d.ts +21 -6
- package/node_modules/@types/node/http.d.ts +25 -0
- package/node_modules/@types/node/index.d.ts +1 -0
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/process.d.ts +14 -1
- package/node_modules/@types/node/quic.d.ts +92 -11
- package/node_modules/@types/node/sqlite.d.ts +55 -0
- package/node_modules/@types/node/stream/iter.d.ts +150 -0
- package/node_modules/@types/node/stream.d.ts +32 -0
- package/node_modules/@types/node/test.d.ts +112 -2
- package/node_modules/@types/node/ts5.6/index.d.ts +1 -0
- package/node_modules/@types/node/ts5.7/index.d.ts +1 -0
- package/node_modules/@types/node/util.d.ts +19 -2
- package/node_modules/@types/node/v8.d.ts +84 -2
- package/node_modules/@types/node/worker_threads.d.ts +8 -7
- package/node_modules/@zuplo/core/customer.cli.minified.js +2 -2
- package/node_modules/@zuplo/core/index.minified.js +2 -2
- package/node_modules/@zuplo/core/package.json +1 -1
- package/node_modules/@zuplo/graphql/out/esm/index.js +11 -11
- package/node_modules/@zuplo/graphql/out/esm/index.js.map +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-DQ4ANJLR.js → chunk-4MNJC7E2.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/chunk-4MNJC7E2.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-2Y72LML3.js → chunk-4QJJMELB.js} +2 -2
- package/node_modules/@zuplo/runtime/out/esm/{chunk-2Y72LML3.js.map → chunk-4QJJMELB.js.map} +1 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-5CYWMN74.js +402 -0
- package/node_modules/@zuplo/runtime/out/esm/chunk-5CYWMN74.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/{chunk-L3MZGNQA.js → chunk-DSZS6PZJ.js} +10 -10
- package/node_modules/@zuplo/runtime/out/esm/chunk-DSZS6PZJ.js.map +1 -0
- package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/internal/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +7 -7
- package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js.map +1 -1
- package/node_modules/@zuplo/runtime/out/esm/mocks/index.js +1 -1
- package/node_modules/@zuplo/runtime/out/types/index.d.ts +1050 -18
- package/node_modules/@zuplo/runtime/out/types/mcp-gateway/index.d.ts +33 -7
- package/node_modules/@zuplo/runtime/package.json +1 -1
- package/node_modules/iconv-lite/encodings/sbcs-data.js +2 -0
- package/node_modules/iconv-lite/encodings/utf32.js +10 -3
- package/node_modules/iconv-lite/package.json +2 -2
- package/node_modules/iconv-lite/types/encodings.d.ts +2 -0
- package/node_modules/protobufjs/dist/light/protobuf.js +2 -2
- package/node_modules/protobufjs/dist/light/protobuf.min.js +2 -2
- package/node_modules/protobufjs/dist/minimal/protobuf.js +2 -2
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +2 -2
- package/node_modules/protobufjs/dist/protobuf.js +5 -2
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/package.json +1 -1
- package/node_modules/protobufjs/src/parse.js +3 -0
- package/node_modules/toad-cache/README.md +10 -9
- package/node_modules/toad-cache/dist/toad-cache.cjs +139 -139
- package/node_modules/toad-cache/dist/toad-cache.mjs +136 -140
- package/node_modules/toad-cache/package.json +8 -8
- package/node_modules/toad-cache/toad-cache.d.cts +20 -14
- package/node_modules/toad-cache/toad-cache.d.ts +18 -14
- package/package.json +6 -6
- package/node_modules/@zuplo/runtime/out/esm/chunk-DQ4ANJLR.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-I5HLAHUY.js +0 -357
- package/node_modules/@zuplo/runtime/out/esm/chunk-I5HLAHUY.js.map +0 -1
- package/node_modules/@zuplo/runtime/out/esm/chunk-L3MZGNQA.js.map +0 -1
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-I5HLAHUY.js.LEGAL.txt → chunk-5CYWMN74.js.LEGAL.txt} +0 -0
- /package/node_modules/@zuplo/runtime/out/esm/{chunk-L3MZGNQA.js.LEGAL.txt → chunk-DSZS6PZJ.js.LEGAL.txt} +0 -0
|
@@ -123,13 +123,16 @@ class PostHogCore extends external_posthog_core_stateless_js_namespaceObject.Pos
|
|
|
123
123
|
};
|
|
124
124
|
}
|
|
125
125
|
enrichProperties(properties) {
|
|
126
|
-
|
|
126
|
+
const userProperties = properties || {};
|
|
127
|
+
const enriched = {
|
|
127
128
|
...this.props,
|
|
128
129
|
...this.sessionProps,
|
|
129
|
-
...
|
|
130
|
+
...userProperties,
|
|
130
131
|
...this.getCommonEventProperties(),
|
|
131
132
|
$session_id: this.getSessionId()
|
|
132
133
|
};
|
|
134
|
+
(0, external_posthog_core_stateless_js_namespaceObject.applyCallerFeatureFlagOverrides)(enriched, userProperties);
|
|
135
|
+
return enriched;
|
|
133
136
|
}
|
|
134
137
|
getSessionId() {
|
|
135
138
|
if (!this._isInitialized) return '';
|
|
@@ -606,9 +609,10 @@ class PostHogCore extends external_posthog_core_stateless_js_namespaceObject.Pos
|
|
|
606
609
|
payload
|
|
607
610
|
};
|
|
608
611
|
}
|
|
609
|
-
getFeatureFlag(key) {
|
|
612
|
+
getFeatureFlag(key, options) {
|
|
610
613
|
const result = this._getFeatureFlagResult(key, {
|
|
611
|
-
missingFlagBehavior: 'getFeatureFlag'
|
|
614
|
+
missingFlagBehavior: 'getFeatureFlag',
|
|
615
|
+
sendEvent: options?.sendEvent
|
|
612
616
|
});
|
|
613
617
|
return result?.variant ?? result?.enabled;
|
|
614
618
|
}
|
|
@@ -653,8 +657,8 @@ class PostHogCore extends external_posthog_core_stateless_js_namespaceObject.Pos
|
|
|
653
657
|
payloads
|
|
654
658
|
};
|
|
655
659
|
}
|
|
656
|
-
isFeatureEnabled(key) {
|
|
657
|
-
const response = this.getFeatureFlag(key);
|
|
660
|
+
isFeatureEnabled(key, options) {
|
|
661
|
+
const response = this.getFeatureFlag(key, options);
|
|
658
662
|
if (void 0 === response) return;
|
|
659
663
|
return !!response;
|
|
660
664
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createFlagsResponseFromFlagsAndPayloads, flagDetailsToResults, getEnabledFromValue, getFeatureFlagValue, getFlagValuesFromFlags, getPayloadsFromFlags, getVariantFromValue, normalizeFlagsResponse, parsePayload, updateFlagValue } from "./featureFlagUtils.mjs";
|
|
2
2
|
import { Compression, FeatureFlagError, PostHogPersistedProperty } from "./types.mjs";
|
|
3
|
-
import { PostHogCoreStateless, QuotaLimitedFeature, maybeAdd } from "./posthog-core-stateless.mjs";
|
|
3
|
+
import { PostHogCoreStateless, QuotaLimitedFeature, applyCallerFeatureFlagOverrides, maybeAdd } from "./posthog-core-stateless.mjs";
|
|
4
4
|
import { uuidv7 } from "./vendor/uuidv7.mjs";
|
|
5
5
|
import { getEventUuid, getPersonPropertiesHash, isArray, isEmptyObject, isNullish, isObject, isString } from "./utils/index.mjs";
|
|
6
6
|
class PostHogCore extends PostHogCoreStateless {
|
|
@@ -95,13 +95,16 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
enrichProperties(properties) {
|
|
98
|
-
|
|
98
|
+
const userProperties = properties || {};
|
|
99
|
+
const enriched = {
|
|
99
100
|
...this.props,
|
|
100
101
|
...this.sessionProps,
|
|
101
|
-
...
|
|
102
|
+
...userProperties,
|
|
102
103
|
...this.getCommonEventProperties(),
|
|
103
104
|
$session_id: this.getSessionId()
|
|
104
105
|
};
|
|
106
|
+
applyCallerFeatureFlagOverrides(enriched, userProperties);
|
|
107
|
+
return enriched;
|
|
105
108
|
}
|
|
106
109
|
getSessionId() {
|
|
107
110
|
if (!this._isInitialized) return '';
|
|
@@ -578,9 +581,10 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
578
581
|
payload
|
|
579
582
|
};
|
|
580
583
|
}
|
|
581
|
-
getFeatureFlag(key) {
|
|
584
|
+
getFeatureFlag(key, options) {
|
|
582
585
|
const result = this._getFeatureFlagResult(key, {
|
|
583
|
-
missingFlagBehavior: 'getFeatureFlag'
|
|
586
|
+
missingFlagBehavior: 'getFeatureFlag',
|
|
587
|
+
sendEvent: options?.sendEvent
|
|
584
588
|
});
|
|
585
589
|
return result?.variant ?? result?.enabled;
|
|
586
590
|
}
|
|
@@ -625,8 +629,8 @@ class PostHogCore extends PostHogCoreStateless {
|
|
|
625
629
|
payloads
|
|
626
630
|
};
|
|
627
631
|
}
|
|
628
|
-
isFeatureEnabled(key) {
|
|
629
|
-
const response = this.getFeatureFlag(key);
|
|
632
|
+
isFeatureEnabled(key, options) {
|
|
633
|
+
const response = this.getFeatureFlag(key, options);
|
|
630
634
|
if (void 0 === response) return;
|
|
631
635
|
return !!response;
|
|
632
636
|
}
|
|
@@ -12,6 +12,7 @@ export declare class PostHogCoreTestClient extends PostHogCore {
|
|
|
12
12
|
_cachedDistinctId?: string;
|
|
13
13
|
constructor(mocks: PostHogCoreTestClientMocks, apiKey: string, options?: PostHogCoreOptions);
|
|
14
14
|
getFlags(distinctId: string, groups?: Record<string, string | number>, personProperties?: Record<string, string>, groupProperties?: Record<string, Record<string, string>>, extraPayload?: Record<string, any>): Promise<GetFlagsResult>;
|
|
15
|
+
flushWithPendingPromises(): Promise<void>;
|
|
15
16
|
getPersistedProperty<T>(key: string): T;
|
|
16
17
|
setPersistedProperty<T>(key: string, value: T | null): void;
|
|
17
18
|
fetch(url: string, options: PostHogFetchOptions): Promise<PostHogFetchResponse>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostHogCoreTestClient.d.ts","sourceRoot":"","sources":["../../src/testing/PostHogCoreTestClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAItH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAA;IAC9E,OAAO,EAAE;QACP,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7C,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,CAAA;KAC/C,CAAA;CACF;AAED,qBAAa,qBAAsB,SAAQ,WAAW;IAIlD,OAAO,CAAC,KAAK;IAHR,iBAAiB,CAAC,EAAE,MAAM,CAAA;gBAGvB,KAAK,EAAE,0BAA0B,EACzC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB;IAQvB,QAAQ,CACb,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM,EAC5C,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAC7C,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAC5D,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACrC,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"PostHogCoreTestClient.d.ts","sourceRoot":"","sources":["../../src/testing/PostHogCoreTestClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAItH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAA;IAC9E,OAAO,EAAE;QACP,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;QAC7C,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,CAAA;KAC/C,CAAA;CACF;AAED,qBAAa,qBAAsB,SAAQ,WAAW;IAIlD,OAAO,CAAC,KAAK;IAHR,iBAAiB,CAAC,EAAE,MAAM,CAAA;gBAGvB,KAAK,EAAE,0BAA0B,EACzC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB;IAQvB,QAAQ,CACb,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAM,EAC5C,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAC7C,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAC5D,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GACrC,OAAO,CAAC,cAAc,CAAC;IAInB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhD,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC;IAGvC,oBAAoB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;IAG3D,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAG/E,YAAY,IAAI,MAAM;IAGtB,iBAAiB,IAAI,MAAM;IAG3B,kBAAkB,IAAI,MAAM;CAG7B;AAED,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,EACd,UAAU,kBAAkB,EAC5B,aAAa,CAAC,KAAK,EAAE,0BAA0B,KAAK,IAAI,EACxD,eAAc;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;CAAO,KACtD,CAAC,qBAAqB,EAAE,0BAA0B,CAsBpD,CAAA"}
|
|
@@ -37,6 +37,9 @@ class PostHogCoreTestClient extends external_posthog_core_js_namespaceObject.Pos
|
|
|
37
37
|
getFlags(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}) {
|
|
38
38
|
return super.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
39
39
|
}
|
|
40
|
+
flushWithPendingPromises() {
|
|
41
|
+
return super.flushWithPendingPromises();
|
|
42
|
+
}
|
|
40
43
|
getPersistedProperty(key) {
|
|
41
44
|
return this.mocks.storage.getItem(key);
|
|
42
45
|
}
|
|
@@ -8,6 +8,9 @@ class PostHogCoreTestClient extends PostHogCore {
|
|
|
8
8
|
getFlags(distinctId, groups = {}, personProperties = {}, groupProperties = {}, extraPayload = {}) {
|
|
9
9
|
return super.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
|
|
10
10
|
}
|
|
11
|
+
flushWithPendingPromises() {
|
|
12
|
+
return super.flushWithPendingPromises();
|
|
13
|
+
}
|
|
11
14
|
getPersistedProperty(key) {
|
|
12
15
|
return this.mocks.storage.getItem(key);
|
|
13
16
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export declare class PromiseQueue {
|
|
2
2
|
private promiseByIds;
|
|
3
|
+
private nextId;
|
|
3
4
|
add(promise: Promise<any>): Promise<any>;
|
|
4
5
|
join(): Promise<void>;
|
|
6
|
+
getPromises(ignoredPromises?: Promise<any>[], maxId?: number): Promise<any>[];
|
|
7
|
+
get maxId(): number;
|
|
5
8
|
get length(): number;
|
|
6
9
|
}
|
|
7
10
|
//# sourceMappingURL=promise-queue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promise-queue.d.ts","sourceRoot":"","sources":["../../src/utils/promise-queue.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"promise-queue.d.ts","sourceRoot":"","sources":["../../src/utils/promise-queue.ts"],"names":[],"mappings":"AAEA,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAA4D;IAChF,OAAO,CAAC,MAAM,CAAY;IAEnB,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAYlC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,WAAW,CAAC,eAAe,GAAE,OAAO,CAAC,GAAG,CAAC,EAAO,EAAE,KAAK,GAAE,MAAoB,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE;IAOrG,IAAW,KAAK,IAAI,MAAM,CAEzB;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;CACF"}
|
|
@@ -30,26 +30,38 @@ const uuidv7_js_namespaceObject = require("../vendor/uuidv7.js");
|
|
|
30
30
|
class PromiseQueue {
|
|
31
31
|
add(promise) {
|
|
32
32
|
const promiseUUID = (0, uuidv7_js_namespaceObject.uuidv7)();
|
|
33
|
-
|
|
33
|
+
const id = ++this.nextId;
|
|
34
|
+
this.promiseByIds[promiseUUID] = {
|
|
35
|
+
id,
|
|
36
|
+
promise
|
|
37
|
+
};
|
|
34
38
|
promise.catch(()=>{}).finally(()=>{
|
|
35
39
|
delete this.promiseByIds[promiseUUID];
|
|
36
40
|
});
|
|
37
41
|
return promise;
|
|
38
42
|
}
|
|
39
43
|
async join() {
|
|
40
|
-
let promises = Object.values(this.promiseByIds);
|
|
44
|
+
let promises = Object.values(this.promiseByIds).map((item)=>item.promise);
|
|
41
45
|
let length = promises.length;
|
|
42
46
|
while(length > 0){
|
|
43
47
|
await Promise.all(promises);
|
|
44
|
-
promises = Object.values(this.promiseByIds);
|
|
48
|
+
promises = Object.values(this.promiseByIds).map((item)=>item.promise);
|
|
45
49
|
length = promises.length;
|
|
46
50
|
}
|
|
47
51
|
}
|
|
52
|
+
getPromises(ignoredPromises = [], maxId = this.nextId) {
|
|
53
|
+
const ignoredPromiseSet = new Set(ignoredPromises);
|
|
54
|
+
return Object.values(this.promiseByIds).filter((item)=>item.id <= maxId && !ignoredPromiseSet.has(item.promise)).map((item)=>item.promise);
|
|
55
|
+
}
|
|
56
|
+
get maxId() {
|
|
57
|
+
return this.nextId;
|
|
58
|
+
}
|
|
48
59
|
get length() {
|
|
49
60
|
return Object.keys(this.promiseByIds).length;
|
|
50
61
|
}
|
|
51
62
|
constructor(){
|
|
52
63
|
this.promiseByIds = {};
|
|
64
|
+
this.nextId = 0;
|
|
53
65
|
}
|
|
54
66
|
}
|
|
55
67
|
exports.PromiseQueue = __webpack_exports__.PromiseQueue;
|
|
@@ -2,26 +2,38 @@ import { uuidv7 } from "../vendor/uuidv7.mjs";
|
|
|
2
2
|
class PromiseQueue {
|
|
3
3
|
add(promise) {
|
|
4
4
|
const promiseUUID = uuidv7();
|
|
5
|
-
|
|
5
|
+
const id = ++this.nextId;
|
|
6
|
+
this.promiseByIds[promiseUUID] = {
|
|
7
|
+
id,
|
|
8
|
+
promise
|
|
9
|
+
};
|
|
6
10
|
promise.catch(()=>{}).finally(()=>{
|
|
7
11
|
delete this.promiseByIds[promiseUUID];
|
|
8
12
|
});
|
|
9
13
|
return promise;
|
|
10
14
|
}
|
|
11
15
|
async join() {
|
|
12
|
-
let promises = Object.values(this.promiseByIds);
|
|
16
|
+
let promises = Object.values(this.promiseByIds).map((item)=>item.promise);
|
|
13
17
|
let length = promises.length;
|
|
14
18
|
while(length > 0){
|
|
15
19
|
await Promise.all(promises);
|
|
16
|
-
promises = Object.values(this.promiseByIds);
|
|
20
|
+
promises = Object.values(this.promiseByIds).map((item)=>item.promise);
|
|
17
21
|
length = promises.length;
|
|
18
22
|
}
|
|
19
23
|
}
|
|
24
|
+
getPromises(ignoredPromises = [], maxId = this.nextId) {
|
|
25
|
+
const ignoredPromiseSet = new Set(ignoredPromises);
|
|
26
|
+
return Object.values(this.promiseByIds).filter((item)=>item.id <= maxId && !ignoredPromiseSet.has(item.promise)).map((item)=>item.promise);
|
|
27
|
+
}
|
|
28
|
+
get maxId() {
|
|
29
|
+
return this.nextId;
|
|
30
|
+
}
|
|
20
31
|
get length() {
|
|
21
32
|
return Object.keys(this.promiseByIds).length;
|
|
22
33
|
}
|
|
23
34
|
constructor(){
|
|
24
35
|
this.promiseByIds = {};
|
|
36
|
+
this.nextId = 0;
|
|
25
37
|
}
|
|
26
38
|
}
|
|
27
39
|
export { PromiseQueue };
|
|
@@ -4,6 +4,7 @@ export declare function includes<T>(arr: T[], needle: T): boolean;
|
|
|
4
4
|
export declare const trim: (str: string) => string;
|
|
5
5
|
export declare const stripLeadingDollar: (s: string) => string;
|
|
6
6
|
export declare function isDistinctIdStringLike(value: string): boolean;
|
|
7
|
+
export declare function safeJsonStringify(value: unknown): string;
|
|
7
8
|
/**
|
|
8
9
|
* Creates a hash string from distinct_id and person properties.
|
|
9
10
|
* Used to detect if person properties have changed to avoid duplicate $set events.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string-utils.d.ts","sourceRoot":"","sources":["../../src/utils/string-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;AAC9D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAA;AAKzD,eAAO,MAAM,IAAI,GAAa,KAAK,MAAM,KAAG,MAM3C,CAAA;AAID,eAAO,MAAM,kBAAkB,GAAa,GAAG,MAAM,KAAG,MAEvD,CAAA;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7D;AAuBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,EACjD,uBAAuB,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,GACpD,MAAM,CAMR"}
|
|
1
|
+
{"version":3,"file":"string-utils.d.ts","sourceRoot":"","sources":["../../src/utils/string-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAExC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;AAC9D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAA;AAKzD,eAAO,MAAM,IAAI,GAAa,KAAK,MAAM,KAAG,MAM3C,CAAA;AAID,eAAO,MAAM,kBAAkB,GAAa,GAAG,MAAM,KAAG,MAEvD,CAAA;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAwCxD;AAuBD;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,EACjD,uBAAuB,CAAC,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAA;CAAE,GACpD,MAAM,CAMR"}
|
|
@@ -27,6 +27,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
27
27
|
getPersonPropertiesHash: ()=>getPersonPropertiesHash,
|
|
28
28
|
includes: ()=>includes,
|
|
29
29
|
isDistinctIdStringLike: ()=>isDistinctIdStringLike,
|
|
30
|
+
safeJsonStringify: ()=>safeJsonStringify,
|
|
30
31
|
stripLeadingDollar: ()=>stripLeadingDollar,
|
|
31
32
|
trim: ()=>trim
|
|
32
33
|
});
|
|
@@ -45,6 +46,24 @@ function isDistinctIdStringLike(value) {
|
|
|
45
46
|
'distinctid'
|
|
46
47
|
].includes(value.toLowerCase());
|
|
47
48
|
}
|
|
49
|
+
function safeJsonStringify(value) {
|
|
50
|
+
const ancestors = [];
|
|
51
|
+
return JSON.stringify(value, function(_key, replacementValue) {
|
|
52
|
+
if ('bigint' == typeof replacementValue) return replacementValue.toString();
|
|
53
|
+
if ('function' == typeof replacementValue || 'symbol' == typeof replacementValue) return;
|
|
54
|
+
if (replacementValue instanceof Error) return {
|
|
55
|
+
name: replacementValue.name,
|
|
56
|
+
message: replacementValue.message,
|
|
57
|
+
stack: replacementValue.stack
|
|
58
|
+
};
|
|
59
|
+
if (replacementValue && 'object' == typeof replacementValue) {
|
|
60
|
+
while(ancestors.length > 0 && ancestors[ancestors.length - 1] !== this)ancestors.pop();
|
|
61
|
+
if (ancestors.includes(replacementValue)) return '[Circular]';
|
|
62
|
+
ancestors.push(replacementValue);
|
|
63
|
+
}
|
|
64
|
+
return replacementValue;
|
|
65
|
+
}) ?? 'null';
|
|
66
|
+
}
|
|
48
67
|
function deepSortKeys(value) {
|
|
49
68
|
if (null === value || 'object' != typeof value) return value;
|
|
50
69
|
if (Array.isArray(value)) return value.map(deepSortKeys);
|
|
@@ -63,12 +82,14 @@ function getPersonPropertiesHash(distinct_id, userPropertiesToSet, userPropertie
|
|
|
63
82
|
exports.getPersonPropertiesHash = __webpack_exports__.getPersonPropertiesHash;
|
|
64
83
|
exports.includes = __webpack_exports__.includes;
|
|
65
84
|
exports.isDistinctIdStringLike = __webpack_exports__.isDistinctIdStringLike;
|
|
85
|
+
exports.safeJsonStringify = __webpack_exports__.safeJsonStringify;
|
|
66
86
|
exports.stripLeadingDollar = __webpack_exports__.stripLeadingDollar;
|
|
67
87
|
exports.trim = __webpack_exports__.trim;
|
|
68
88
|
for(var __webpack_i__ in __webpack_exports__)if (-1 === [
|
|
69
89
|
"getPersonPropertiesHash",
|
|
70
90
|
"includes",
|
|
71
91
|
"isDistinctIdStringLike",
|
|
92
|
+
"safeJsonStringify",
|
|
72
93
|
"stripLeadingDollar",
|
|
73
94
|
"trim"
|
|
74
95
|
].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
|
|
@@ -13,6 +13,24 @@ function isDistinctIdStringLike(value) {
|
|
|
13
13
|
'distinctid'
|
|
14
14
|
].includes(value.toLowerCase());
|
|
15
15
|
}
|
|
16
|
+
function safeJsonStringify(value) {
|
|
17
|
+
const ancestors = [];
|
|
18
|
+
return JSON.stringify(value, function(_key, replacementValue) {
|
|
19
|
+
if ('bigint' == typeof replacementValue) return replacementValue.toString();
|
|
20
|
+
if ('function' == typeof replacementValue || 'symbol' == typeof replacementValue) return;
|
|
21
|
+
if (replacementValue instanceof Error) return {
|
|
22
|
+
name: replacementValue.name,
|
|
23
|
+
message: replacementValue.message,
|
|
24
|
+
stack: replacementValue.stack
|
|
25
|
+
};
|
|
26
|
+
if (replacementValue && 'object' == typeof replacementValue) {
|
|
27
|
+
while(ancestors.length > 0 && ancestors[ancestors.length - 1] !== this)ancestors.pop();
|
|
28
|
+
if (ancestors.includes(replacementValue)) return '[Circular]';
|
|
29
|
+
ancestors.push(replacementValue);
|
|
30
|
+
}
|
|
31
|
+
return replacementValue;
|
|
32
|
+
}) ?? 'null';
|
|
33
|
+
}
|
|
16
34
|
function deepSortKeys(value) {
|
|
17
35
|
if (null === value || 'object' != typeof value) return value;
|
|
18
36
|
if (Array.isArray(value)) return value.map(deepSortKeys);
|
|
@@ -28,4 +46,4 @@ function getPersonPropertiesHash(distinct_id, userPropertiesToSet, userPropertie
|
|
|
28
46
|
userPropertiesToSetOnce: userPropertiesToSetOnce ? deepSortKeys(userPropertiesToSetOnce) : void 0
|
|
29
47
|
});
|
|
30
48
|
}
|
|
31
|
-
export { getPersonPropertiesHash, includes, isDistinctIdStringLike, stripLeadingDollar, trim };
|
|
49
|
+
export { getPersonPropertiesHash, includes, isDistinctIdStringLike, safeJsonStringify, stripLeadingDollar, trim };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isArray, isNumber, isObject, isString } from '@/utils'
|
|
1
|
+
import { isArray, isNumber, isObject, isString, safeJsonStringify } from '@/utils'
|
|
2
2
|
|
|
3
3
|
export const EXCEPTION_STEP_INTERNAL_FIELDS = {
|
|
4
4
|
MESSAGE: '$message',
|
|
@@ -134,8 +134,10 @@ function normalizePositiveInteger(input: number | undefined, fallback: number):
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
function normalizeAndSerializeStep(step: ExceptionStep): { step: ExceptionStep; json: string } | undefined {
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
let json: string
|
|
138
|
+
try {
|
|
139
|
+
json = safeJsonStringify(step)
|
|
140
|
+
} catch {
|
|
139
141
|
return undefined
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -166,45 +168,6 @@ function normalizeAndSerializeStep(step: ExceptionStep): { step: ExceptionStep;
|
|
|
166
168
|
}
|
|
167
169
|
}
|
|
168
170
|
|
|
169
|
-
function safeStringify(value: unknown): string | undefined {
|
|
170
|
-
const seen = new WeakSet<object>()
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
return JSON.stringify(value, (_key, replacementValue: unknown) => {
|
|
174
|
-
if (typeof replacementValue === 'bigint') {
|
|
175
|
-
return replacementValue.toString()
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (typeof replacementValue === 'function' || typeof replacementValue === 'symbol') {
|
|
179
|
-
return undefined
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (replacementValue instanceof Date) {
|
|
183
|
-
return replacementValue.toISOString()
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (replacementValue instanceof Error) {
|
|
187
|
-
return {
|
|
188
|
-
name: replacementValue.name,
|
|
189
|
-
message: replacementValue.message,
|
|
190
|
-
stack: replacementValue.stack,
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (replacementValue && typeof replacementValue === 'object') {
|
|
195
|
-
if (seen.has(replacementValue)) {
|
|
196
|
-
return '[Circular]'
|
|
197
|
-
}
|
|
198
|
-
seen.add(replacementValue)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
return replacementValue
|
|
202
|
-
})
|
|
203
|
-
} catch {
|
|
204
|
-
return undefined
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
171
|
export function getUtf8ByteLength(value: string): number {
|
|
209
172
|
if (typeof TextEncoder !== 'undefined') {
|
|
210
173
|
return new TextEncoder().encode(value).length
|
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
STRING_FORMAT,
|
|
35
35
|
createLogger,
|
|
36
36
|
getEventUuid,
|
|
37
|
+
safeJsonStringify,
|
|
37
38
|
} from './utils'
|
|
38
39
|
import { uuidv7 } from './vendor/uuidv7'
|
|
39
40
|
import {
|
|
@@ -82,6 +83,18 @@ class PostHogFetchNetworkError extends Error {
|
|
|
82
83
|
export const maybeAdd = (key: string, value: JsonType | undefined): Record<string, JsonType> =>
|
|
83
84
|
value !== undefined ? { [key]: value } : {}
|
|
84
85
|
|
|
86
|
+
// Caller-supplied `$feature/*` and `$active_feature_flags` win over the SDK's cached flag values.
|
|
87
|
+
export const applyCallerFeatureFlagOverrides = (
|
|
88
|
+
target: PostHogEventProperties,
|
|
89
|
+
callerProperties: PostHogEventProperties
|
|
90
|
+
): void => {
|
|
91
|
+
for (const key of Object.keys(callerProperties)) {
|
|
92
|
+
if (key.startsWith('$feature/') || key === '$active_feature_flags') {
|
|
93
|
+
target[key] = callerProperties[key]
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
export async function logFlushError(err: any): Promise<void> {
|
|
86
99
|
if (err instanceof PostHogFetchHttpError) {
|
|
87
100
|
let text = ''
|
|
@@ -112,7 +125,13 @@ export function isPostHogFetchNetworkError(err: unknown): err is PostHogFetchNet
|
|
|
112
125
|
return err instanceof PostHogFetchNetworkError
|
|
113
126
|
}
|
|
114
127
|
|
|
115
|
-
function isRetryableFlagsFetchError(
|
|
128
|
+
function isRetryableFlagsFetchError(
|
|
129
|
+
err: unknown
|
|
130
|
+
): err is PostHogFetchNetworkError | (PostHogFetchHttpError & { status: 502 | 504 }) {
|
|
131
|
+
if (err instanceof PostHogFetchHttpError) {
|
|
132
|
+
return err.status === 502 || err.status === 504
|
|
133
|
+
}
|
|
134
|
+
|
|
116
135
|
if (!(err instanceof PostHogFetchNetworkError)) {
|
|
117
136
|
return false
|
|
118
137
|
}
|
|
@@ -126,6 +145,13 @@ function isPostHogFetchContentTooLargeError(err: unknown): err is PostHogFetchHt
|
|
|
126
145
|
return typeof err === 'object' && err instanceof PostHogFetchHttpError && err.status === 413
|
|
127
146
|
}
|
|
128
147
|
|
|
148
|
+
function isPostHogFetchRetryableError(err: unknown): err is PostHogFetchHttpError | PostHogFetchNetworkError {
|
|
149
|
+
if (err instanceof PostHogFetchHttpError) {
|
|
150
|
+
return err.status === 408 || err.status === 429 || err.status >= 500
|
|
151
|
+
}
|
|
152
|
+
return isPostHogFetchNetworkError(err)
|
|
153
|
+
}
|
|
154
|
+
|
|
129
155
|
function isPostHogEventProperties(value: JsonType | undefined): value is PostHogEventProperties {
|
|
130
156
|
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
131
157
|
}
|
|
@@ -163,6 +189,7 @@ export abstract class PostHogCoreStateless {
|
|
|
163
189
|
private maxQueueSize: number
|
|
164
190
|
private flushInterval: number
|
|
165
191
|
private flushPromise: Promise<any> | null = null
|
|
192
|
+
private flushPromises: Set<Promise<any>> = new Set()
|
|
166
193
|
private shutdownPromise: Promise<void> | null = null
|
|
167
194
|
private requestTimeout: number
|
|
168
195
|
private featureFlagsRequestTimeoutMs: number
|
|
@@ -250,7 +277,7 @@ export abstract class PostHogCoreStateless {
|
|
|
250
277
|
this._retryOptions = {
|
|
251
278
|
retryCount: options.fetchRetryCount ?? 3,
|
|
252
279
|
retryDelay: options.fetchRetryDelay ?? 3000, // 3 seconds
|
|
253
|
-
retryCheck:
|
|
280
|
+
retryCheck: isPostHogFetchRetryableError,
|
|
254
281
|
}
|
|
255
282
|
this.requestTimeout = options.requestTimeout ?? 10000 // 10 seconds
|
|
256
283
|
this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3000 // 3 seconds
|
|
@@ -369,13 +396,16 @@ export abstract class PostHogCoreStateless {
|
|
|
369
396
|
event: string
|
|
370
397
|
properties?: PostHogEventProperties
|
|
371
398
|
}): PostHogEventProperties {
|
|
399
|
+
const userProperties = payload.properties || {}
|
|
400
|
+
const properties: PostHogEventProperties = {
|
|
401
|
+
...userProperties,
|
|
402
|
+
...this.getCommonEventProperties(), // Common PH props
|
|
403
|
+
}
|
|
404
|
+
applyCallerFeatureFlagOverrides(properties, userProperties)
|
|
372
405
|
return {
|
|
373
406
|
distinct_id: payload.distinct_id,
|
|
374
407
|
event: payload.event,
|
|
375
|
-
properties
|
|
376
|
-
...(payload.properties || {}),
|
|
377
|
-
...this.getCommonEventProperties(), // Common PH props
|
|
378
|
-
},
|
|
408
|
+
properties,
|
|
379
409
|
}
|
|
380
410
|
}
|
|
381
411
|
|
|
@@ -515,6 +545,28 @@ export abstract class PostHogCoreStateless {
|
|
|
515
545
|
})
|
|
516
546
|
}
|
|
517
547
|
|
|
548
|
+
protected async groupIdentifyStatelessImmediate(
|
|
549
|
+
groupType: string,
|
|
550
|
+
groupKey: string | number,
|
|
551
|
+
groupProperties?: PostHogEventProperties,
|
|
552
|
+
options?: PostHogCaptureOptions,
|
|
553
|
+
distinctId?: string,
|
|
554
|
+
eventProperties?: PostHogEventProperties
|
|
555
|
+
): Promise<void> {
|
|
556
|
+
const payload = this.buildPayload({
|
|
557
|
+
distinct_id: distinctId || `$${groupType}_${groupKey}`,
|
|
558
|
+
event: '$groupidentify',
|
|
559
|
+
properties: {
|
|
560
|
+
$group_type: groupType,
|
|
561
|
+
$group_key: groupKey,
|
|
562
|
+
$group_set: groupProperties || {},
|
|
563
|
+
...(eventProperties || {}),
|
|
564
|
+
},
|
|
565
|
+
})
|
|
566
|
+
|
|
567
|
+
await this.sendImmediate('capture', payload, options)
|
|
568
|
+
}
|
|
569
|
+
|
|
518
570
|
protected async getRemoteConfig(): Promise<PostHogRemoteConfig | undefined> {
|
|
519
571
|
await this._initPromise
|
|
520
572
|
|
|
@@ -585,7 +637,7 @@ export abstract class PostHogCoreStateless {
|
|
|
585
637
|
|
|
586
638
|
this._logger.info('Flags URL', url)
|
|
587
639
|
|
|
588
|
-
// Retry only network/transport/timeout failures
|
|
640
|
+
// Retry only network/transport/timeout failures and selected gateway HTTP errors for /flags.
|
|
589
641
|
return this.fetchWithRetry(
|
|
590
642
|
url,
|
|
591
643
|
fetchOptions,
|
|
@@ -831,9 +883,8 @@ export abstract class PostHogCoreStateless {
|
|
|
831
883
|
): Promise<PostHogFeatureFlagDetails | undefined> {
|
|
832
884
|
await this._initPromise
|
|
833
885
|
|
|
834
|
-
const extraPayload: Record<string, any> = {
|
|
835
|
-
|
|
836
|
-
extraPayload['geoip_disable'] = true
|
|
886
|
+
const extraPayload: Record<string, any> = {
|
|
887
|
+
geoip_disable: disableGeoip ?? this.disableGeoip,
|
|
837
888
|
}
|
|
838
889
|
if (flagKeysToEvaluate) {
|
|
839
890
|
extraPayload['flag_keys_to_evaluate'] = flagKeysToEvaluate
|
|
@@ -1054,7 +1105,7 @@ export abstract class PostHogCoreStateless {
|
|
|
1054
1105
|
data.historical_migration = true
|
|
1055
1106
|
}
|
|
1056
1107
|
|
|
1057
|
-
const payload =
|
|
1108
|
+
const payload = safeJsonStringify(data)
|
|
1058
1109
|
|
|
1059
1110
|
const url = `${this.host}/batch/`
|
|
1060
1111
|
|
|
@@ -1145,6 +1196,28 @@ export abstract class PostHogCoreStateless {
|
|
|
1145
1196
|
})
|
|
1146
1197
|
}
|
|
1147
1198
|
|
|
1199
|
+
private async waitForPendingPromises(
|
|
1200
|
+
maxPromiseId: number,
|
|
1201
|
+
ignoredPromises: (Promise<any> | null | undefined)[] = []
|
|
1202
|
+
): Promise<void> {
|
|
1203
|
+
const ignoredPendingPromises = ignoredPromises.filter((promise): promise is Promise<any> => !!promise)
|
|
1204
|
+
let iteration = 0
|
|
1205
|
+
|
|
1206
|
+
while (true) {
|
|
1207
|
+
const promises = this.promiseQueue.getPromises([...ignoredPendingPromises, ...this.flushPromises], maxPromiseId)
|
|
1208
|
+
if (promises.length === 0) {
|
|
1209
|
+
return
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
if (iteration > 0) {
|
|
1213
|
+
this._logger.debug(`flush() re-checking ${promises.length} pending promise(s) before flushing`)
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
await Promise.all(promises.map((promise) => promise.catch(() => {})))
|
|
1217
|
+
iteration++
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1148
1221
|
/**
|
|
1149
1222
|
* Flushes the queue of pending events.
|
|
1150
1223
|
*
|
|
@@ -1173,22 +1246,44 @@ export abstract class PostHogCoreStateless {
|
|
|
1173
1246
|
* @throws PostHogFetchNetworkError
|
|
1174
1247
|
* @throws Error
|
|
1175
1248
|
*/
|
|
1176
|
-
|
|
1249
|
+
protected flushWithPendingPromises(): Promise<void> {
|
|
1250
|
+
return this.flushInternal(true)
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
flush(): Promise<void> {
|
|
1254
|
+
return this.flushInternal(false)
|
|
1255
|
+
}
|
|
1256
|
+
|
|
1257
|
+
private flushInternal(waitForPendingPromises: boolean): Promise<void> {
|
|
1177
1258
|
if (this.disabled) {
|
|
1178
|
-
return
|
|
1259
|
+
return Promise.resolve()
|
|
1179
1260
|
}
|
|
1180
1261
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1262
|
+
const previousFlushPromise = this.flushPromise
|
|
1263
|
+
const maxPromiseId = this.promiseQueue.maxId
|
|
1264
|
+
|
|
1265
|
+
// Register this flush in the promise queue synchronously so shutdown() can't miss it,
|
|
1266
|
+
// but exclude it from the pending-work wait to avoid self-waiting.
|
|
1267
|
+
const nextFlushPromise: Promise<void> = Promise.resolve()
|
|
1268
|
+
.then(() => {
|
|
1269
|
+
if (waitForPendingPromises) {
|
|
1270
|
+
return this.waitForPendingPromises(maxPromiseId, [previousFlushPromise, nextFlushPromise])
|
|
1271
|
+
}
|
|
1272
|
+
})
|
|
1273
|
+
// Wait for the current flush operation to finish (regardless of success or failure), then try to flush again.
|
|
1274
|
+
// Use allSettled instead of finally to be defensive around flush throwing errors immediately rather than rejecting.
|
|
1275
|
+
// Use a custom allSettled implementation to avoid issues with patching Promise on RN
|
|
1276
|
+
.then(() => allSettled([previousFlushPromise]))
|
|
1277
|
+
.then(() => {
|
|
1278
|
+
return this._flush()
|
|
1279
|
+
})
|
|
1187
1280
|
|
|
1188
1281
|
this.flushPromise = nextFlushPromise
|
|
1282
|
+
this.flushPromises.add(nextFlushPromise)
|
|
1189
1283
|
void this.addPendingPromise(nextFlushPromise)
|
|
1190
1284
|
|
|
1191
1285
|
allSettled([nextFlushPromise]).then(() => {
|
|
1286
|
+
this.flushPromises.delete(nextFlushPromise)
|
|
1192
1287
|
// If there are no others waiting to flush, clear the promise.
|
|
1193
1288
|
// We don't strictly need to do this, but it could make debugging easier
|
|
1194
1289
|
if (this.flushPromise === nextFlushPromise) {
|
|
@@ -1250,7 +1345,7 @@ export abstract class PostHogCoreStateless {
|
|
|
1250
1345
|
data.historical_migration = true
|
|
1251
1346
|
}
|
|
1252
1347
|
|
|
1253
|
-
const payload =
|
|
1348
|
+
const payload = safeJsonStringify(data)
|
|
1254
1349
|
|
|
1255
1350
|
const url = `${this.host}/batch/`
|
|
1256
1351
|
|
|
@@ -1271,8 +1366,8 @@ export abstract class PostHogCoreStateless {
|
|
|
1271
1366
|
if (isPostHogFetchContentTooLargeError(err)) {
|
|
1272
1367
|
return false
|
|
1273
1368
|
}
|
|
1274
|
-
// otherwise, retry on network errors
|
|
1275
|
-
return
|
|
1369
|
+
// otherwise, retry on transient HTTP and network errors
|
|
1370
|
+
return isPostHogFetchRetryableError(err)
|
|
1276
1371
|
},
|
|
1277
1372
|
}
|
|
1278
1373
|
|
|
@@ -1345,7 +1440,7 @@ export abstract class PostHogCoreStateless {
|
|
|
1345
1440
|
if (isPostHogFetchContentTooLargeError(err)) {
|
|
1346
1441
|
return false
|
|
1347
1442
|
}
|
|
1348
|
-
return
|
|
1443
|
+
return isPostHogFetchRetryableError(err)
|
|
1349
1444
|
},
|
|
1350
1445
|
})
|
|
1351
1446
|
return { kind: 'ok' }
|