@plushanalytics/react-native-session-replay 1.2.6 → 3.0.2
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 +138 -3
- package/android/src/main/java/com/posthogreactnativesessionreplay/PosthogReactNativeSessionReplayModule.kt +68 -27
- package/ios/PosthogReactNativeSessionReplay.mm +3 -0
- package/ios/PosthogReactNativeSessionReplay.swift +58 -31
- package/lib/commonjs/adapters/mobileReplayAdapter.js +135 -0
- package/lib/commonjs/adapters/mobileReplayAdapter.js.map +1 -0
- package/lib/commonjs/client.js +42 -0
- package/lib/commonjs/client.js.map +1 -0
- package/lib/commonjs/index.js +31 -37
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/nativeBridge.js +50 -0
- package/lib/commonjs/nativeBridge.js.map +1 -0
- package/lib/commonjs/provider.js +45 -0
- package/lib/commonjs/provider.js.map +1 -0
- package/lib/commonjs/types.js +6 -0
- package/lib/commonjs/types.js.map +1 -0
- package/lib/module/adapters/mobileReplayAdapter.js +130 -0
- package/lib/module/adapters/mobileReplayAdapter.js.map +1 -0
- package/lib/module/client.js +33 -0
- package/lib/module/client.js.map +1 -0
- package/lib/module/index.js +3 -33
- package/lib/module/index.js.map +1 -1
- package/lib/module/nativeBridge.js +40 -0
- package/lib/module/nativeBridge.js.map +1 -0
- package/lib/module/provider.js +39 -0
- package/lib/module/provider.js.map +1 -0
- package/lib/module/types.js +4 -0
- package/lib/module/types.js.map +1 -0
- package/lib/typescript/commonjs/src/adapters/mobileReplayAdapter.d.ts +9 -0
- package/lib/typescript/commonjs/src/adapters/mobileReplayAdapter.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/client.d.ts +6 -0
- package/lib/typescript/commonjs/src/client.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +4 -28
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/nativeBridge.d.ts +31 -0
- package/lib/typescript/commonjs/src/nativeBridge.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/provider.d.ts +12 -0
- package/lib/typescript/commonjs/src/provider.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/types.d.ts +32 -0
- package/lib/typescript/commonjs/src/types.d.ts.map +1 -0
- package/lib/typescript/module/src/adapters/mobileReplayAdapter.d.ts +9 -0
- package/lib/typescript/module/src/adapters/mobileReplayAdapter.d.ts.map +1 -0
- package/lib/typescript/module/src/client.d.ts +6 -0
- package/lib/typescript/module/src/client.d.ts.map +1 -0
- package/lib/typescript/module/src/index.d.ts +4 -28
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/nativeBridge.d.ts +31 -0
- package/lib/typescript/module/src/nativeBridge.d.ts.map +1 -0
- package/lib/typescript/module/src/provider.d.ts +12 -0
- package/lib/typescript/module/src/provider.d.ts.map +1 -0
- package/lib/typescript/module/src/types.d.ts +32 -0
- package/lib/typescript/module/src/types.d.ts.map +1 -0
- package/package.json +22 -25
- package/src/adapters/mobileReplayAdapter.ts +206 -0
- package/src/client.ts +43 -0
- package/src/index.tsx +25 -79
- package/src/nativeBridge.ts +86 -0
- package/src/provider.tsx +46 -0
- package/src/types.ts +73 -0
|
@@ -1,29 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}, decideReplayConfig: {
|
|
6
|
-
[key: string]: any;
|
|
7
|
-
}): Promise<void>;
|
|
8
|
-
export declare function startSession(sessionId: string): Promise<void>;
|
|
9
|
-
export declare function endSession(): Promise<void>;
|
|
10
|
-
export declare function isEnabled(): Promise<boolean>;
|
|
11
|
-
export declare function identify(distinctId: string, anonymousId: string): Promise<void>;
|
|
12
|
-
export interface PostHogReactNativeSessionReplayModule {
|
|
13
|
-
start: (sessionId: string, sdkOptions: {
|
|
14
|
-
[key: string]: any;
|
|
15
|
-
}, // options from SDK such as apiKey
|
|
16
|
-
sdkReplayConfig: {
|
|
17
|
-
[key: string]: any;
|
|
18
|
-
}, // config from SDK
|
|
19
|
-
decideReplayConfig: {
|
|
20
|
-
[key: string]: any;
|
|
21
|
-
}) => Promise<void>;
|
|
22
|
-
startSession: (sessionId: string) => Promise<void>;
|
|
23
|
-
endSession: () => Promise<void>;
|
|
24
|
-
isEnabled: () => Promise<boolean>;
|
|
25
|
-
identify: (distinctId: string, anonymousId: string) => Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
declare const PostHogReactNativeSessionReplay: PostHogReactNativeSessionReplayModule;
|
|
28
|
-
export default PostHogReactNativeSessionReplay;
|
|
1
|
+
export { createPlushAnalyticsClient, PlushAnalyticsClient } from "./client";
|
|
2
|
+
export { createMobileReplayRecorderAdapter } from "./adapters/mobileReplayAdapter";
|
|
3
|
+
export { PlushAnalyticsProvider, usePlushAnalytics } from "./provider";
|
|
4
|
+
export type { EventEnvelope, EventType, FlushResult, GroupOptions, IdentifyOptions, JsonValue, MobileReplayConfig, PlushAnalytics, PlushAnalyticsConfig, ReplayChunkEnvelope, ReplayRecordEmission, ReplayRecorderAdapter, RetryOptions, ScreenOptions, SessionRecordingOptions, SessionReplayConfig, SessionReplayMaskingConfig, StorageAdapter, TrackOptions, UnifiedBatchPayload } from "./types";
|
|
29
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACvE,YAAY,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare function start(sessionId: string, sdkOptions: {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
}, sdkReplayConfig: {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}, decideReplayConfig: {
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function startSession(sessionId: string): Promise<void>;
|
|
9
|
+
export declare function endSession(): Promise<void>;
|
|
10
|
+
export declare function flush(): Promise<void>;
|
|
11
|
+
export declare function isEnabled(): Promise<boolean>;
|
|
12
|
+
export declare function identify(distinctId: string, anonymousId: string): Promise<void>;
|
|
13
|
+
export interface PostHogReactNativeSessionReplayModule {
|
|
14
|
+
start: (sessionId: string, sdkOptions: {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
}, // options from SDK such as apiKey
|
|
17
|
+
sdkReplayConfig: {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
}, // config from SDK
|
|
20
|
+
decideReplayConfig: {
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
}) => Promise<void>;
|
|
23
|
+
startSession: (sessionId: string) => Promise<void>;
|
|
24
|
+
endSession: () => Promise<void>;
|
|
25
|
+
flush: () => Promise<void>;
|
|
26
|
+
isEnabled: () => Promise<boolean>;
|
|
27
|
+
identify: (distinctId: string, anonymousId: string) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
declare const PostHogReactNativeSessionReplay: PostHogReactNativeSessionReplayModule;
|
|
30
|
+
export default PostHogReactNativeSessionReplay;
|
|
31
|
+
//# sourceMappingURL=nativeBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeBridge.d.ts","sourceRoot":"","sources":["../../../../src/nativeBridge.ts"],"names":[],"mappings":"AAoBA,wBAAgB,KAAK,CACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAClC,eAAe,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EACvC,kBAAkB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED,wBAAgB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C;AAED,wBAAgB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErC;AAED,wBAAgB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAE5C;AAED,wBAAgB,QAAQ,CACtB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,CACL,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,kCAAkC;IACtE,eAAe,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,kBAAkB;IAC3D,kBAAkB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,KACvC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAED,QAAA,MAAM,+BAA+B,EAAE,qCAOtC,CAAC;AAEF,eAAe,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type PlushAnalyticsClient } from "./client";
|
|
3
|
+
import type { PlushAnalytics, PlushAnalyticsConfig } from "./types";
|
|
4
|
+
type PlushAnalyticsProviderProps = {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
config?: PlushAnalyticsConfig;
|
|
7
|
+
client?: PlushAnalyticsClient;
|
|
8
|
+
};
|
|
9
|
+
export declare function PlushAnalyticsProvider({ children, config, client }: PlushAnalyticsProviderProps): React.ReactElement;
|
|
10
|
+
export declare function usePlushAnalytics(): PlushAnalytics;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAC5E,OAAO,EAA8B,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpE,KAAK,2BAA2B,GAAG;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,CAAC;AAIF,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,MAAM,EACP,EAAE,2BAA2B,GAAG,KAAK,CAAC,YAAY,CAoBlD;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAOlD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EventEnvelope, EventType, FlushResult, GroupOptions, IdentifyOptions, JsonValue, PlushAnalytics as CorePlushAnalytics, PlushAnalyticsConfig as CoreConfig, ReplayChunkEnvelope, ReplayRecordEmission, ReplayRecorderAdapter, RetryOptions, ScreenOptions, SessionRecordingOptions as CoreSessionRecordingOptions, StorageAdapter, TrackOptions, UnifiedBatchPayload } from "@plushanalytics/javascript";
|
|
2
|
+
export type SessionReplayMaskingConfig = {
|
|
3
|
+
textInputs?: boolean;
|
|
4
|
+
images?: boolean;
|
|
5
|
+
sandboxedViews?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type SessionReplayConfig = {
|
|
8
|
+
enabled?: boolean;
|
|
9
|
+
masking?: SessionReplayMaskingConfig;
|
|
10
|
+
captureLog?: boolean;
|
|
11
|
+
captureNetworkTelemetry?: boolean;
|
|
12
|
+
throttleDelayMs?: number;
|
|
13
|
+
};
|
|
14
|
+
export type MobileReplayConfig = SessionReplayConfig & {
|
|
15
|
+
maskAllTextInputs?: boolean;
|
|
16
|
+
maskAllImages?: boolean;
|
|
17
|
+
maskAllSandboxedViews?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type SessionRecordingOptions = CoreSessionRecordingOptions & {
|
|
20
|
+
replayHost?: string;
|
|
21
|
+
replaySnapshotPath?: string;
|
|
22
|
+
replayConfig?: MobileReplayConfig;
|
|
23
|
+
};
|
|
24
|
+
export type PlushAnalyticsConfig = CoreConfig & {
|
|
25
|
+
sessionReplayConfig?: SessionReplayConfig;
|
|
26
|
+
};
|
|
27
|
+
export type { EventEnvelope, EventType, FlushResult, GroupOptions, IdentifyOptions, JsonValue, ReplayChunkEnvelope, ReplayRecordEmission, ReplayRecorderAdapter, RetryOptions, ScreenOptions, StorageAdapter, TrackOptions, UnifiedBatchPayload };
|
|
28
|
+
export type PlushAnalytics = Omit<CorePlushAnalytics, "startSessionRecording" | "startReplay"> & {
|
|
29
|
+
startSessionRecording: (options?: SessionRecordingOptions) => Promise<void>;
|
|
30
|
+
startReplay: (options?: SessionRecordingOptions) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,IAAI,kBAAkB,EACpC,oBAAoB,IAAI,UAAU,EAClC,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,uBAAuB,IAAI,2BAA2B,EACtD,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG;IAErD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,2BAA2B,GAAG;IAElE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C,CAAC;AAEF,YAAY,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,EAAE,uBAAuB,GAAG,aAAa,CAAC,GAAG;IAC/F,qBAAqB,EAAE,CAAC,OAAO,CAAC,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReplayRecorderAdapter, SessionReplayConfig } from "../types";
|
|
2
|
+
type AdapterDefaults = {
|
|
3
|
+
apiKey: string;
|
|
4
|
+
endpoint: string;
|
|
5
|
+
replayConfigDefaults?: SessionReplayConfig;
|
|
6
|
+
};
|
|
7
|
+
export declare function createMobileReplayRecorderAdapter(defaults: AdapterDefaults): ReplayRecorderAdapter;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=mobileReplayAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mobileReplayAdapter.d.ts","sourceRoot":"","sources":["../../../../../src/adapters/mobileReplayAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,qBAAqB,EAErB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB,KAAK,eAAe,GAAG;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,mBAAmB,CAAC;CAC5C,CAAC;AAoJF,wBAAgB,iCAAiC,CAAC,QAAQ,EAAE,eAAe,GAAG,qBAAqB,CA6ClG"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PlushAnalyticsClient } from "@plushanalytics/javascript";
|
|
2
|
+
import type { PlushAnalyticsConfig, SessionRecordingOptions } from "./types";
|
|
3
|
+
export { PlushAnalyticsClient };
|
|
4
|
+
export declare function createPlushAnalyticsClient(config: PlushAnalyticsConfig): PlushAnalyticsClient;
|
|
5
|
+
export type { SessionRecordingOptions };
|
|
6
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAE7E,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAWhC,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAqB7F;AAGD,YAAY,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -1,29 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}, decideReplayConfig: {
|
|
6
|
-
[key: string]: any;
|
|
7
|
-
}): Promise<void>;
|
|
8
|
-
export declare function startSession(sessionId: string): Promise<void>;
|
|
9
|
-
export declare function endSession(): Promise<void>;
|
|
10
|
-
export declare function isEnabled(): Promise<boolean>;
|
|
11
|
-
export declare function identify(distinctId: string, anonymousId: string): Promise<void>;
|
|
12
|
-
export interface PostHogReactNativeSessionReplayModule {
|
|
13
|
-
start: (sessionId: string, sdkOptions: {
|
|
14
|
-
[key: string]: any;
|
|
15
|
-
}, // options from SDK such as apiKey
|
|
16
|
-
sdkReplayConfig: {
|
|
17
|
-
[key: string]: any;
|
|
18
|
-
}, // config from SDK
|
|
19
|
-
decideReplayConfig: {
|
|
20
|
-
[key: string]: any;
|
|
21
|
-
}) => Promise<void>;
|
|
22
|
-
startSession: (sessionId: string) => Promise<void>;
|
|
23
|
-
endSession: () => Promise<void>;
|
|
24
|
-
isEnabled: () => Promise<boolean>;
|
|
25
|
-
identify: (distinctId: string, anonymousId: string) => Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
declare const PostHogReactNativeSessionReplay: PostHogReactNativeSessionReplayModule;
|
|
28
|
-
export default PostHogReactNativeSessionReplay;
|
|
1
|
+
export { createPlushAnalyticsClient, PlushAnalyticsClient } from "./client";
|
|
2
|
+
export { createMobileReplayRecorderAdapter } from "./adapters/mobileReplayAdapter";
|
|
3
|
+
export { PlushAnalyticsProvider, usePlushAnalytics } from "./provider";
|
|
4
|
+
export type { EventEnvelope, EventType, FlushResult, GroupOptions, IdentifyOptions, JsonValue, MobileReplayConfig, PlushAnalytics, PlushAnalyticsConfig, ReplayChunkEnvelope, ReplayRecordEmission, ReplayRecorderAdapter, RetryOptions, ScreenOptions, SessionRecordingOptions, SessionReplayConfig, SessionReplayMaskingConfig, StorageAdapter, TrackOptions, UnifiedBatchPayload } from "./types";
|
|
29
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACvE,YAAY,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,uBAAuB,EACvB,mBAAmB,EACnB,0BAA0B,EAC1B,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare function start(sessionId: string, sdkOptions: {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
}, sdkReplayConfig: {
|
|
4
|
+
[key: string]: any;
|
|
5
|
+
}, decideReplayConfig: {
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
export declare function startSession(sessionId: string): Promise<void>;
|
|
9
|
+
export declare function endSession(): Promise<void>;
|
|
10
|
+
export declare function flush(): Promise<void>;
|
|
11
|
+
export declare function isEnabled(): Promise<boolean>;
|
|
12
|
+
export declare function identify(distinctId: string, anonymousId: string): Promise<void>;
|
|
13
|
+
export interface PostHogReactNativeSessionReplayModule {
|
|
14
|
+
start: (sessionId: string, sdkOptions: {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
}, // options from SDK such as apiKey
|
|
17
|
+
sdkReplayConfig: {
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
}, // config from SDK
|
|
20
|
+
decideReplayConfig: {
|
|
21
|
+
[key: string]: any;
|
|
22
|
+
}) => Promise<void>;
|
|
23
|
+
startSession: (sessionId: string) => Promise<void>;
|
|
24
|
+
endSession: () => Promise<void>;
|
|
25
|
+
flush: () => Promise<void>;
|
|
26
|
+
isEnabled: () => Promise<boolean>;
|
|
27
|
+
identify: (distinctId: string, anonymousId: string) => Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
declare const PostHogReactNativeSessionReplay: PostHogReactNativeSessionReplayModule;
|
|
30
|
+
export default PostHogReactNativeSessionReplay;
|
|
31
|
+
//# sourceMappingURL=nativeBridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeBridge.d.ts","sourceRoot":"","sources":["../../../../src/nativeBridge.ts"],"names":[],"mappings":"AAoBA,wBAAgB,KAAK,CACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAClC,eAAe,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EACvC,kBAAkB,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;AAED,wBAAgB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C;AAED,wBAAgB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErC;AAED,wBAAgB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAE5C;AAED,wBAAgB,QAAQ,CACtB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,MAAM,WAAW,qCAAqC;IACpD,KAAK,EAAE,CACL,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,kCAAkC;IACtE,eAAe,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,EAAE,kBAAkB;IAC3D,kBAAkB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,KACvC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnB,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAElC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAED,QAAA,MAAM,+BAA+B,EAAE,qCAOtC,CAAC;AAEF,eAAe,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type PlushAnalyticsClient } from "./client";
|
|
3
|
+
import type { PlushAnalytics, PlushAnalyticsConfig } from "./types";
|
|
4
|
+
type PlushAnalyticsProviderProps = {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
config?: PlushAnalyticsConfig;
|
|
7
|
+
client?: PlushAnalyticsClient;
|
|
8
|
+
};
|
|
9
|
+
export declare function PlushAnalyticsProvider({ children, config, client }: PlushAnalyticsProviderProps): React.ReactElement;
|
|
10
|
+
export declare function usePlushAnalytics(): PlushAnalytics;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuD,MAAM,OAAO,CAAC;AAC5E,OAAO,EAA8B,KAAK,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpE,KAAK,2BAA2B,GAAG;IACjC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,CAAC;AAIF,wBAAgB,sBAAsB,CAAC,EACrC,QAAQ,EACR,MAAM,EACN,MAAM,EACP,EAAE,2BAA2B,GAAG,KAAK,CAAC,YAAY,CAoBlD;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAOlD"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EventEnvelope, EventType, FlushResult, GroupOptions, IdentifyOptions, JsonValue, PlushAnalytics as CorePlushAnalytics, PlushAnalyticsConfig as CoreConfig, ReplayChunkEnvelope, ReplayRecordEmission, ReplayRecorderAdapter, RetryOptions, ScreenOptions, SessionRecordingOptions as CoreSessionRecordingOptions, StorageAdapter, TrackOptions, UnifiedBatchPayload } from "@plushanalytics/javascript";
|
|
2
|
+
export type SessionReplayMaskingConfig = {
|
|
3
|
+
textInputs?: boolean;
|
|
4
|
+
images?: boolean;
|
|
5
|
+
sandboxedViews?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type SessionReplayConfig = {
|
|
8
|
+
enabled?: boolean;
|
|
9
|
+
masking?: SessionReplayMaskingConfig;
|
|
10
|
+
captureLog?: boolean;
|
|
11
|
+
captureNetworkTelemetry?: boolean;
|
|
12
|
+
throttleDelayMs?: number;
|
|
13
|
+
};
|
|
14
|
+
export type MobileReplayConfig = SessionReplayConfig & {
|
|
15
|
+
maskAllTextInputs?: boolean;
|
|
16
|
+
maskAllImages?: boolean;
|
|
17
|
+
maskAllSandboxedViews?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type SessionRecordingOptions = CoreSessionRecordingOptions & {
|
|
20
|
+
replayHost?: string;
|
|
21
|
+
replaySnapshotPath?: string;
|
|
22
|
+
replayConfig?: MobileReplayConfig;
|
|
23
|
+
};
|
|
24
|
+
export type PlushAnalyticsConfig = CoreConfig & {
|
|
25
|
+
sessionReplayConfig?: SessionReplayConfig;
|
|
26
|
+
};
|
|
27
|
+
export type { EventEnvelope, EventType, FlushResult, GroupOptions, IdentifyOptions, JsonValue, ReplayChunkEnvelope, ReplayRecordEmission, ReplayRecorderAdapter, RetryOptions, ScreenOptions, StorageAdapter, TrackOptions, UnifiedBatchPayload };
|
|
28
|
+
export type PlushAnalytics = Omit<CorePlushAnalytics, "startSessionRecording" | "startReplay"> & {
|
|
29
|
+
startSessionRecording: (options?: SessionRecordingOptions) => Promise<void>;
|
|
30
|
+
startReplay: (options?: SessionRecordingOptions) => Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,IAAI,kBAAkB,EACpC,oBAAoB,IAAI,UAAU,EAClC,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,uBAAuB,IAAI,2BAA2B,EACtD,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG;IAErD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,2BAA2B,GAAG;IAElE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;CAC3C,CAAC;AAEF,YAAY,EACV,aAAa,EACb,SAAS,EACT,WAAW,EACX,YAAY,EACZ,eAAe,EACf,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,EAAE,uBAAuB,GAAG,aAAa,CAAC,GAAG;IAC/F,qBAAqB,EAAE,CAAC,OAAO,CAAC,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plushanalytics/react-native-session-replay",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.0.2",
|
|
4
|
+
"description": "React Native SDK for Plush Analytics events + session replay ingestion.",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
7
7
|
"module": "./lib/module/index.js",
|
|
@@ -36,30 +36,26 @@
|
|
|
36
36
|
"!**/__mocks__",
|
|
37
37
|
"!**/.*"
|
|
38
38
|
],
|
|
39
|
-
"scripts": {
|
|
40
|
-
"example": "pnpm --filter plush-react-native-session-replay-example",
|
|
41
|
-
"test": "jest",
|
|
42
|
-
"typecheck": "tsc",
|
|
43
|
-
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
44
|
-
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
45
|
-
"prepare": "bob build",
|
|
46
|
-
"changeset": "changeset"
|
|
47
|
-
},
|
|
48
39
|
"keywords": [
|
|
49
40
|
"react-native",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
41
|
+
"analytics",
|
|
42
|
+
"session-replay",
|
|
43
|
+
"plushanalytics"
|
|
52
44
|
],
|
|
53
45
|
"repository": {
|
|
54
46
|
"type": "git",
|
|
55
|
-
"url": "
|
|
47
|
+
"url": "https://github.com/plush-analytics/sdks.git",
|
|
48
|
+
"directory": "plush-react-native-session-replay"
|
|
56
49
|
},
|
|
57
50
|
"author": "Plush Analytics",
|
|
58
51
|
"license": "MIT",
|
|
59
52
|
"bugs": {
|
|
60
|
-
"url": "https://github.com/plush-analytics/
|
|
53
|
+
"url": "https://github.com/plush-analytics/sdks/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/plush-analytics/sdks/tree/main/plush-react-native-session-replay",
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@plushanalytics/javascript": "^0.1.6"
|
|
61
58
|
},
|
|
62
|
-
"homepage": "https://github.com/plush-analytics/plush-react-native-session-replay#readme",
|
|
63
59
|
"publishConfig": {
|
|
64
60
|
"registry": "https://registry.npmjs.org/"
|
|
65
61
|
},
|
|
@@ -82,18 +78,10 @@
|
|
|
82
78
|
"turbo": "^2.0.0",
|
|
83
79
|
"typescript": "^5.2.2"
|
|
84
80
|
},
|
|
85
|
-
"pnpm": {
|
|
86
|
-
"overrides": {
|
|
87
|
-
"@types/react": "^18.2.44",
|
|
88
|
-
"node-forge": "1.3.2",
|
|
89
|
-
"fast-xml-parser": "5.3.4"
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
81
|
"peerDependencies": {
|
|
93
82
|
"react": "*",
|
|
94
83
|
"react-native": "*"
|
|
95
84
|
},
|
|
96
|
-
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a",
|
|
97
85
|
"jest": {
|
|
98
86
|
"preset": "react-native",
|
|
99
87
|
"modulePathIgnorePatterns": [
|
|
@@ -161,5 +149,14 @@
|
|
|
161
149
|
"type": "module-legacy",
|
|
162
150
|
"languages": "kotlin-swift",
|
|
163
151
|
"version": "0.41.2"
|
|
152
|
+
},
|
|
153
|
+
"scripts": {
|
|
154
|
+
"example": "pnpm --filter plush-react-native-session-replay-example",
|
|
155
|
+
"build": "bob build",
|
|
156
|
+
"test": "jest",
|
|
157
|
+
"typecheck": "tsc -p tsconfig.build.json --noEmit",
|
|
158
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
159
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
160
|
+
"changeset": "changeset"
|
|
164
161
|
}
|
|
165
|
-
}
|
|
162
|
+
}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
MobileReplayConfig,
|
|
3
|
+
ReplayRecorderAdapter,
|
|
4
|
+
SessionRecordingOptions,
|
|
5
|
+
SessionReplayConfig,
|
|
6
|
+
} from "../types";
|
|
7
|
+
import * as replayModule from "../nativeBridge";
|
|
8
|
+
|
|
9
|
+
type AdapterDefaults = {
|
|
10
|
+
apiKey: string;
|
|
11
|
+
endpoint: string;
|
|
12
|
+
replayConfigDefaults?: SessionReplayConfig;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type StartArgs = {
|
|
16
|
+
onSessionId?: (sessionId: string) => void;
|
|
17
|
+
options?: SessionRecordingOptions;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type NormalizedReplayConfig = {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
maskAllTextInputs: boolean;
|
|
23
|
+
maskAllImages: boolean;
|
|
24
|
+
maskAllSandboxedViews: boolean;
|
|
25
|
+
captureLog: boolean;
|
|
26
|
+
captureNetworkTelemetry: boolean;
|
|
27
|
+
throttleDelayMs: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const DEFAULT_SNAPSHOT_PATH = "/v1/events/batch";
|
|
31
|
+
const DEFAULT_THROTTLE_DELAY_MS = 1000;
|
|
32
|
+
const UUID_PATTERN =
|
|
33
|
+
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
34
|
+
|
|
35
|
+
function assertNonEmpty(value: string, field: string): void {
|
|
36
|
+
if (!value || !value.trim()) {
|
|
37
|
+
throw new Error(`${field} is required.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function normalizeHost(value: string): string {
|
|
42
|
+
return value.replace(/\/+$/, "");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function normalizeSnapshotPath(value: string | undefined): string {
|
|
46
|
+
const trimmed = value?.trim();
|
|
47
|
+
if (!trimmed) return DEFAULT_SNAPSHOT_PATH;
|
|
48
|
+
return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isUuid(value: string): boolean {
|
|
52
|
+
return UUID_PATTERN.test(value);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function generateUuid(): string {
|
|
56
|
+
const cryptoApi = globalThis.crypto as Crypto | undefined;
|
|
57
|
+
if (cryptoApi?.randomUUID) return cryptoApi.randomUUID();
|
|
58
|
+
|
|
59
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (char) => {
|
|
60
|
+
const random = Math.floor(Math.random() * 16);
|
|
61
|
+
const resolved = char === "x" ? random : (random & 0x3) | 0x8;
|
|
62
|
+
return resolved.toString(16);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function resolveSessionId(options?: SessionRecordingOptions): string {
|
|
67
|
+
const requestedSessionId = options?.sessionId?.trim();
|
|
68
|
+
if (requestedSessionId && isUuid(requestedSessionId)) {
|
|
69
|
+
return requestedSessionId;
|
|
70
|
+
}
|
|
71
|
+
return generateUuid();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function assertNoPosthogDotCom(host: string): void {
|
|
75
|
+
const lowered = host.toLowerCase();
|
|
76
|
+
const hostName = (() => {
|
|
77
|
+
try {
|
|
78
|
+
return new URL(host).hostname.toLowerCase();
|
|
79
|
+
} catch {
|
|
80
|
+
return lowered;
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
|
|
84
|
+
if (hostName === "posthog.com" || hostName.endsWith(".posthog.com")) {
|
|
85
|
+
throw new Error("replayHost must not point to posthog.com (or a subdomain).");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function resolveMaskingValue(
|
|
90
|
+
overrideConfig: MobileReplayConfig | undefined,
|
|
91
|
+
defaultConfig: SessionReplayConfig | undefined,
|
|
92
|
+
maskingKey: keyof NonNullable<SessionReplayConfig["masking"]>,
|
|
93
|
+
legacyKey: "maskAllTextInputs" | "maskAllImages" | "maskAllSandboxedViews"
|
|
94
|
+
): boolean {
|
|
95
|
+
const overrideMaskingValue = overrideConfig?.masking?.[maskingKey];
|
|
96
|
+
if (typeof overrideMaskingValue === "boolean") {
|
|
97
|
+
return overrideMaskingValue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const overrideLegacyValue = overrideConfig?.[legacyKey];
|
|
101
|
+
if (typeof overrideLegacyValue === "boolean") {
|
|
102
|
+
return overrideLegacyValue;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const defaultMaskingValue = defaultConfig?.masking?.[maskingKey];
|
|
106
|
+
if (typeof defaultMaskingValue === "boolean") {
|
|
107
|
+
return defaultMaskingValue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function resolveReplayConfig(
|
|
114
|
+
defaultConfig: SessionReplayConfig | undefined,
|
|
115
|
+
overrideConfig: MobileReplayConfig | undefined
|
|
116
|
+
): NormalizedReplayConfig {
|
|
117
|
+
const enabled = overrideConfig?.enabled ?? defaultConfig?.enabled ?? true;
|
|
118
|
+
const captureLog = overrideConfig?.captureLog ?? defaultConfig?.captureLog ?? true;
|
|
119
|
+
const captureNetworkTelemetry =
|
|
120
|
+
overrideConfig?.captureNetworkTelemetry ?? defaultConfig?.captureNetworkTelemetry ?? true;
|
|
121
|
+
|
|
122
|
+
const requestedThrottleDelayMs =
|
|
123
|
+
overrideConfig?.throttleDelayMs ?? defaultConfig?.throttleDelayMs ?? DEFAULT_THROTTLE_DELAY_MS;
|
|
124
|
+
const throttleDelayMs =
|
|
125
|
+
Number.isFinite(requestedThrottleDelayMs) && requestedThrottleDelayMs >= 0
|
|
126
|
+
? requestedThrottleDelayMs
|
|
127
|
+
: DEFAULT_THROTTLE_DELAY_MS;
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
enabled,
|
|
131
|
+
maskAllTextInputs: resolveMaskingValue(
|
|
132
|
+
overrideConfig,
|
|
133
|
+
defaultConfig,
|
|
134
|
+
"textInputs",
|
|
135
|
+
"maskAllTextInputs"
|
|
136
|
+
),
|
|
137
|
+
maskAllImages: resolveMaskingValue(overrideConfig, defaultConfig, "images", "maskAllImages"),
|
|
138
|
+
maskAllSandboxedViews: resolveMaskingValue(
|
|
139
|
+
overrideConfig,
|
|
140
|
+
defaultConfig,
|
|
141
|
+
"sandboxedViews",
|
|
142
|
+
"maskAllSandboxedViews"
|
|
143
|
+
),
|
|
144
|
+
captureLog,
|
|
145
|
+
captureNetworkTelemetry,
|
|
146
|
+
throttleDelayMs,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function toNativeReplayConfig(config: NormalizedReplayConfig): Record<string, unknown> {
|
|
151
|
+
return {
|
|
152
|
+
maskAllTextInputs: config.maskAllTextInputs,
|
|
153
|
+
maskAllImages: config.maskAllImages,
|
|
154
|
+
maskAllSandboxedViews: config.maskAllSandboxedViews,
|
|
155
|
+
captureLog: config.captureLog,
|
|
156
|
+
captureNetworkTelemetry: config.captureNetworkTelemetry,
|
|
157
|
+
throttleDelayMs: config.throttleDelayMs,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function createMobileReplayRecorderAdapter(defaults: AdapterDefaults): ReplayRecorderAdapter {
|
|
162
|
+
assertNonEmpty(defaults.apiKey, "apiKey");
|
|
163
|
+
assertNonEmpty(defaults.endpoint, "endpoint");
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
start: async (args: StartArgs) => {
|
|
167
|
+
const options = args.options;
|
|
168
|
+
const resolvedReplayConfig = resolveReplayConfig(defaults.replayConfigDefaults, options?.replayConfig);
|
|
169
|
+
if (!resolvedReplayConfig.enabled) {
|
|
170
|
+
return () => {};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const host = normalizeHost(options?.replayHost?.trim() || defaults.endpoint);
|
|
174
|
+
assertNoPosthogDotCom(host);
|
|
175
|
+
|
|
176
|
+
const snapshotPath = normalizeSnapshotPath(options?.replaySnapshotPath);
|
|
177
|
+
const activeSessionId = resolveSessionId(options);
|
|
178
|
+
|
|
179
|
+
const sdkOptions = {
|
|
180
|
+
apiKey: defaults.apiKey,
|
|
181
|
+
host,
|
|
182
|
+
debug: false,
|
|
183
|
+
distinctId: options?.userId?.trim() || "",
|
|
184
|
+
anonymousId: "",
|
|
185
|
+
sdkVersion: "plushanalytics-react-native",
|
|
186
|
+
flushAt: 20,
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
await replayModule.start(
|
|
190
|
+
activeSessionId,
|
|
191
|
+
sdkOptions,
|
|
192
|
+
toNativeReplayConfig(resolvedReplayConfig),
|
|
193
|
+
{ endpoint: snapshotPath }
|
|
194
|
+
);
|
|
195
|
+
await replayModule.startSession(activeSessionId);
|
|
196
|
+
args.onSessionId?.(activeSessionId);
|
|
197
|
+
|
|
198
|
+
return () => {
|
|
199
|
+
void replayModule.endSession();
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
flush: async () => {
|
|
203
|
+
await replayModule.flush();
|
|
204
|
+
},
|
|
205
|
+
};
|
|
206
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createPlushAnalyticsClient as createCoreClient,
|
|
3
|
+
PlushAnalyticsClient
|
|
4
|
+
} from "@plushanalytics/javascript";
|
|
5
|
+
import { createMobileReplayRecorderAdapter } from "./adapters/mobileReplayAdapter";
|
|
6
|
+
import type { PlushAnalyticsConfig, SessionRecordingOptions } from "./types";
|
|
7
|
+
|
|
8
|
+
export { PlushAnalyticsClient };
|
|
9
|
+
|
|
10
|
+
const DEFAULT_ENDPOINT = "https://apim-plushanalytics-prod-rwth6ltqgdxg2.azure-api.net/api";
|
|
11
|
+
|
|
12
|
+
function normalizeSource(value: unknown): string | undefined {
|
|
13
|
+
if (typeof value !== "string") return undefined;
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
if (!trimmed) return undefined;
|
|
16
|
+
return trimmed.length > 64 ? trimmed.slice(0, 64) : trimmed;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function createPlushAnalyticsClient(config: PlushAnalyticsConfig): PlushAnalyticsClient {
|
|
20
|
+
const endpoint = config.endpoint ?? DEFAULT_ENDPOINT;
|
|
21
|
+
const source = normalizeSource(config.source) ?? "mobile";
|
|
22
|
+
|
|
23
|
+
const wrapped: PlushAnalyticsConfig = {
|
|
24
|
+
...config,
|
|
25
|
+
endpoint,
|
|
26
|
+
source,
|
|
27
|
+
replay: {
|
|
28
|
+
...(config.replay ?? {}),
|
|
29
|
+
defaultRecorder:
|
|
30
|
+
config.replay?.defaultRecorder ??
|
|
31
|
+
createMobileReplayRecorderAdapter({
|
|
32
|
+
apiKey: config.apiKey,
|
|
33
|
+
endpoint,
|
|
34
|
+
replayConfigDefaults: config.sessionReplayConfig
|
|
35
|
+
})
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return createCoreClient(wrapped);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Re-export the type so consumers can pass platform-specific options while using the core surface.
|
|
43
|
+
export type { SessionRecordingOptions };
|