sitepong 0.2.3 → 0.2.5
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/android/build.gradle +39 -0
- package/android/src/main/java/com/sitepong/deviceid/DeviceIdHelper.kt +45 -0
- package/android/src/main/java/com/sitepong/deviceid/DeviceIdModule.kt +45 -0
- package/android/src/main/java/com/sitepong/screenrecorder/ChunkUploader.kt +78 -0
- package/android/src/main/java/com/sitepong/screenrecorder/H264Encoder.kt +163 -0
- package/android/src/main/java/com/sitepong/screenrecorder/ScreenCapture.kt +103 -0
- package/android/src/main/java/com/sitepong/screenrecorder/ScreenRecorderModule.kt +80 -0
- package/android/src/main/java/com/sitepong/screenrecorder/SensitiveViewManager.kt +19 -0
- package/app.plugin.js +426 -0
- package/dist/cdn/sitepong.min.js +5 -5
- package/dist/cdn/sitepong.min.js.map +1 -1
- package/dist/entries/rn.d.ts +188 -16
- package/dist/entries/rn.js +187 -35
- package/dist/entries/rn.js.map +1 -1
- package/dist/entries/web.js +2 -1
- package/dist/entries/web.js.map +1 -1
- package/dist/entries/web.mjs +2 -1
- package/dist/entries/web.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +2 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +2 -1
- package/dist/react/index.mjs.map +1 -1
- package/expo-module.config.json +16 -0
- package/ios/DeviceId/DeviceIdModule.swift +55 -0
- package/ios/DeviceId/KeychainHelper.swift +68 -0
- package/ios/LiveActivity/ConfigStore.swift +43 -0
- package/ios/LiveActivity/DSLNode.swift +188 -0
- package/ios/LiveActivity/SitePongActivityAttributes.swift +112 -0
- package/ios/LiveActivity/SitePongLiveActivityModule.swift +250 -0
- package/ios/LiveActivity/widget/ColorHex.swift +30 -0
- package/ios/LiveActivity/widget/DSLAnimations.swift +128 -0
- package/ios/LiveActivity/widget/DSLRenderer.swift +538 -0
- package/ios/LiveActivity/widget/SitePongLiveActivityWidget.swift +393 -0
- package/ios/LiveActivity/widget/SitePongWidgetBundle.swift +84 -0
- package/ios/ScreenRecorder/ChunkUploader.swift +52 -0
- package/ios/ScreenRecorder/H264Encoder.swift +229 -0
- package/ios/ScreenRecorder/ScreenCapture.swift +149 -0
- package/ios/ScreenRecorder/ScreenRecorderModule.swift +179 -0
- package/ios/ScreenRecorder/SensitiveViewManager.swift +63 -0
- package/ios/Sitepong.podspec +57 -0
- package/ios/WatchtowerCore/Screenshotter.swift +163 -0
- package/ios/WatchtowerCore/SwiftUIModifiers.swift +78 -0
- package/ios/WatchtowerCore/Swizzling.swift +59 -0
- package/ios/WatchtowerCore/TapEvent.swift +61 -0
- package/ios/WatchtowerCore/Transport.swift +136 -0
- package/ios/WatchtowerCore/UIViewExtensions.swift +31 -0
- package/ios/WatchtowerCore/Watchtower.swift +80 -0
- package/ios/WatchtowerCore/WatchtowerEngine.swift +565 -0
- package/ios/WatchtowerCore/WatchtowerHash.swift +120 -0
- package/ios/WatchtowerCore/WatchtowerRegistry.swift +87 -0
- package/package.json +17 -10
package/dist/entries/rn.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { ReactNode, ReactElement } from 'react';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Platform-agnostic storage interface.
|
|
@@ -500,6 +500,7 @@ declare class RNPerformanceManager {
|
|
|
500
500
|
* 2. **Manual**: Call startScreenRecording / stopScreenRecording / flushScreenRecording
|
|
501
501
|
* yourself. Keeps a 60s rolling buffer by default.
|
|
502
502
|
*/
|
|
503
|
+
|
|
503
504
|
interface ScreenRecordingConfig {
|
|
504
505
|
/** Enable screen recording (default: false) */
|
|
505
506
|
enabled?: boolean;
|
|
@@ -541,6 +542,21 @@ declare const flushScreenRecordingOnError: typeof flushScreenRecording;
|
|
|
541
542
|
* Check if screen recording is currently active.
|
|
542
543
|
*/
|
|
543
544
|
declare function isScreenRecording(): boolean;
|
|
545
|
+
/**
|
|
546
|
+
* Register a native view tag as sensitive — it is masked (black rectangle) in
|
|
547
|
+
* recorded frames and Watchtower screenshots. No-ops if native is unavailable.
|
|
548
|
+
*/
|
|
549
|
+
declare function addSensitiveView(viewTag: number): void;
|
|
550
|
+
/** Unregister a previously-registered sensitive view tag. */
|
|
551
|
+
declare function removeSensitiveView(viewTag: number): void;
|
|
552
|
+
/**
|
|
553
|
+
* React component that marks its children as sensitive: content wrapped in
|
|
554
|
+
* <SensitiveView> appears as a black rectangle in recordings and screenshots.
|
|
555
|
+
* Requires `react` and `react-native` at runtime (RN-only).
|
|
556
|
+
*/
|
|
557
|
+
declare function SensitiveView(props: {
|
|
558
|
+
children: ReactNode;
|
|
559
|
+
}): ReactElement;
|
|
544
560
|
|
|
545
561
|
/**
|
|
546
562
|
* SitePong React Native Provider
|
|
@@ -632,9 +648,30 @@ interface RNDeviceInfo {
|
|
|
632
648
|
}
|
|
633
649
|
declare function collectDeviceInfo(): RNDeviceInfo;
|
|
634
650
|
/** @deprecated No-op, returns null. Kept for API compatibility. */
|
|
651
|
+
/**
|
|
652
|
+
* Full native device signals from the bundled `SitePongDeviceId` module —
|
|
653
|
+
* persistent device id (Keychain on iOS / ANDROID_ID on Android), model,
|
|
654
|
+
* OS version, emulator flag, and vendor/android ids. Returns null when the
|
|
655
|
+
* native module is unavailable (web/Node, or a bare app not yet rebuilt).
|
|
656
|
+
*/
|
|
657
|
+
interface NativeDeviceSignals {
|
|
658
|
+
deviceId: string;
|
|
659
|
+
platform: 'ios' | 'android';
|
|
660
|
+
osVersion: string;
|
|
661
|
+
model: string;
|
|
662
|
+
manufacturer: string;
|
|
663
|
+
isEmulator: boolean;
|
|
664
|
+
screenScale: number;
|
|
665
|
+
identifierForVendor?: string;
|
|
666
|
+
androidId?: string;
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Persistent device ID that survives app reinstalls (Keychain on iOS,
|
|
670
|
+
* ANDROID_ID-derived on Android). Returns null when native is unavailable.
|
|
671
|
+
*/
|
|
635
672
|
declare function fetchPersistentDeviceId(): Promise<string | null>;
|
|
636
|
-
/**
|
|
637
|
-
declare function fetchNativeDeviceSignals(): Promise<null>;
|
|
673
|
+
/** Full native device signals for fingerprinting/analytics, or null. */
|
|
674
|
+
declare function fetchNativeDeviceSignals(): Promise<NativeDeviceSignals | null>;
|
|
638
675
|
|
|
639
676
|
/**
|
|
640
677
|
* React Native Error Handler
|
|
@@ -657,9 +694,10 @@ declare function setupRNErrorHandler(options?: RNErrorHandlerOptions): () => voi
|
|
|
657
694
|
*
|
|
658
695
|
* This file is intentionally MINIMAL. The hot path — capturing taps, taking
|
|
659
696
|
* screenshots, perceptual hashing, redaction, and upload — all happens in the
|
|
660
|
-
* shared native engine
|
|
661
|
-
*
|
|
662
|
-
* the RN runtime path; the engine hashes
|
|
697
|
+
* shared native engine (spec §3), which is compiled into THIS package's native
|
|
698
|
+
* module (`SitePongScreenRecorder`) and reached through `./native-modules`.
|
|
699
|
+
* capture-core's JS dHash is NOT on the RN runtime path; the engine hashes
|
|
700
|
+
* natively.
|
|
663
701
|
*
|
|
664
702
|
* JS's only jobs here:
|
|
665
703
|
* (a) start the native engine with apiKey/projectId/endpoint + platform
|
|
@@ -822,13 +860,14 @@ declare function createTrackedDatabase<T extends SQLiteDatabase>(db: T, options?
|
|
|
822
860
|
* Registers Expo push tokens and APNs Live Activity tokens with the
|
|
823
861
|
* SitePong ingest server for remote push notification delivery.
|
|
824
862
|
*
|
|
825
|
-
* For Live Activities, prefer the turnkey
|
|
826
|
-
* package — it ships a built-in
|
|
827
|
-
* custom progress bar with sliding icon,
|
|
828
|
-
* forwards push tokens to the registration
|
|
829
|
-
* automatically. Use the lower-level
|
|
830
|
-
* `registerPushToStartToken` exports below
|
|
831
|
-
* iOS Widget Extension and `ActivityAttributes`
|
|
863
|
+
* For Live Activities, prefer the turnkey API from this same `sitepong`
|
|
864
|
+
* package (`startLiveActivity` in ./live-activity) — it ships a built-in
|
|
865
|
+
* SwiftUI widget template (SF Symbols, custom progress bar with sliding icon,
|
|
866
|
+
* visibility-driven slots) and forwards push tokens to the registration
|
|
867
|
+
* functions in this file automatically. Use the lower-level
|
|
868
|
+
* `registerLiveActivityToken` and `registerPushToStartToken` exports below
|
|
869
|
+
* only if you author your own iOS Widget Extension and `ActivityAttributes`
|
|
870
|
+
* struct in Swift.
|
|
832
871
|
*
|
|
833
872
|
* ## User attribution (two-step)
|
|
834
873
|
*
|
|
@@ -876,10 +915,143 @@ declare function registerLiveActivityToken(activityType: string, activityId: str
|
|
|
876
915
|
* Register a push-to-start token for remotely launching Live Activities (iOS 17.2+).
|
|
877
916
|
*/
|
|
878
917
|
declare function registerPushToStartToken(activityType: string, pushToStartToken: string, options: PushEnvironmentOptions): void;
|
|
918
|
+
|
|
879
919
|
/**
|
|
880
|
-
*
|
|
920
|
+
* iOS Live Activities — drives the SitePong built-in ActivityKit widget template
|
|
921
|
+
* from JavaScript. Ships inside the single `sitepong` package: the native
|
|
922
|
+
* `SitePongLiveActivity` module compiles into the Sitepong pod, and the widget
|
|
923
|
+
* extension is added by app.plugin.js when you opt in with
|
|
924
|
+
* `["sitepong", { "liveActivities": true }]`.
|
|
925
|
+
*
|
|
926
|
+
* Customers never write Swift — call startLiveActivity() with a typed
|
|
927
|
+
* ContentState and the SwiftUI template renders SF Symbols, custom progress
|
|
928
|
+
* bars, and styled text on the lock screen and Dynamic Island. Push tokens for
|
|
929
|
+
* remote updates are forwarded automatically to the SDK's push registration so
|
|
930
|
+
* that backend updates (POST /api/push/live-activity) reach the right device.
|
|
931
|
+
*
|
|
932
|
+
* Requires iOS 16.2+ at runtime. On web/Node or a device without ActivityKit,
|
|
933
|
+
* the native module is unavailable and these calls reject/no-op safely.
|
|
881
934
|
*/
|
|
882
|
-
|
|
935
|
+
type SymbolWeight = 'ultraLight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black';
|
|
936
|
+
type TextWeight = SymbolWeight;
|
|
937
|
+
interface IconSpec {
|
|
938
|
+
symbol: string;
|
|
939
|
+
color?: string;
|
|
940
|
+
weight?: SymbolWeight;
|
|
941
|
+
size?: number;
|
|
942
|
+
}
|
|
943
|
+
interface TextStyle {
|
|
944
|
+
size?: number;
|
|
945
|
+
weight?: TextWeight;
|
|
946
|
+
color?: string;
|
|
947
|
+
italic?: boolean;
|
|
948
|
+
monospacedDigit?: boolean;
|
|
949
|
+
}
|
|
950
|
+
type ProgressSpec = {
|
|
951
|
+
style: 'bar';
|
|
952
|
+
value: number;
|
|
953
|
+
trackColor?: string;
|
|
954
|
+
fillColor?: string;
|
|
955
|
+
label?: string;
|
|
956
|
+
labelStyle?: TextStyle;
|
|
957
|
+
} | {
|
|
958
|
+
style: 'bar-with-icon';
|
|
959
|
+
value: number;
|
|
960
|
+
icon: string;
|
|
961
|
+
iconColor?: string;
|
|
962
|
+
iconWeight?: SymbolWeight;
|
|
963
|
+
trackColor?: string;
|
|
964
|
+
fillColor?: string;
|
|
965
|
+
label?: string;
|
|
966
|
+
labelStyle?: TextStyle;
|
|
967
|
+
} | {
|
|
968
|
+
style: 'circular';
|
|
969
|
+
value: number;
|
|
970
|
+
icon?: string;
|
|
971
|
+
iconColor?: string;
|
|
972
|
+
trackColor?: string;
|
|
973
|
+
fillColor?: string;
|
|
974
|
+
} | {
|
|
975
|
+
style: 'timer';
|
|
976
|
+
endDate?: number;
|
|
977
|
+
startDate?: number;
|
|
978
|
+
trackColor?: string;
|
|
979
|
+
fillColor?: string;
|
|
980
|
+
};
|
|
981
|
+
interface LiveActivityContentState {
|
|
982
|
+
title?: string;
|
|
983
|
+
subtitle?: string;
|
|
984
|
+
titleStyle?: TextStyle;
|
|
985
|
+
subtitleStyle?: TextStyle;
|
|
986
|
+
leadingIcon?: IconSpec;
|
|
987
|
+
trailingIcon?: IconSpec;
|
|
988
|
+
progress?: ProgressSpec;
|
|
989
|
+
backgroundColor?: string;
|
|
990
|
+
dynamicIsland?: {
|
|
991
|
+
compactLeading?: IconSpec | {
|
|
992
|
+
text: string;
|
|
993
|
+
style?: TextStyle;
|
|
994
|
+
};
|
|
995
|
+
compactTrailing?: IconSpec | {
|
|
996
|
+
text: string;
|
|
997
|
+
style?: TextStyle;
|
|
998
|
+
};
|
|
999
|
+
minimal?: IconSpec;
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
interface LiveActivityAttributes {
|
|
1003
|
+
id?: string;
|
|
1004
|
+
metadata?: Record<string, string>;
|
|
1005
|
+
}
|
|
1006
|
+
interface StartLiveActivityOptions {
|
|
1007
|
+
activityType: string;
|
|
1008
|
+
attributes?: LiveActivityAttributes;
|
|
1009
|
+
contentState: LiveActivityContentState;
|
|
1010
|
+
environment?: 'sandbox' | 'production';
|
|
1011
|
+
alert?: {
|
|
1012
|
+
title?: string;
|
|
1013
|
+
body?: string;
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
interface StartedLiveActivity {
|
|
1017
|
+
activityId: string;
|
|
1018
|
+
pushToken: string;
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Start a Live Activity. Returns the ActivityKit id and APNs push token, which
|
|
1022
|
+
* are also registered with the SDK so backend sends reach the right device.
|
|
1023
|
+
*/
|
|
1024
|
+
declare function startLiveActivity(options: StartLiveActivityOptions): Promise<StartedLiveActivity>;
|
|
1025
|
+
/** Update a running Live Activity locally. */
|
|
1026
|
+
declare function updateLiveActivity(activityId: string, contentState: LiveActivityContentState, options?: {
|
|
1027
|
+
alert?: {
|
|
1028
|
+
title?: string;
|
|
1029
|
+
body?: string;
|
|
1030
|
+
};
|
|
1031
|
+
}): Promise<void>;
|
|
1032
|
+
/**
|
|
1033
|
+
* End a running Live Activity and deactivate its push token. Optionally pass a
|
|
1034
|
+
* final content state and a `dismissalDate` (epoch ms) for when the system
|
|
1035
|
+
* removes it from the lock screen.
|
|
1036
|
+
*/
|
|
1037
|
+
declare function endLiveActivity(activityId: string, options?: {
|
|
1038
|
+
finalContentState?: LiveActivityContentState;
|
|
1039
|
+
dismissalDate?: number;
|
|
1040
|
+
}): Promise<void>;
|
|
1041
|
+
/** Are Live Activities supported and enabled by the user on this device? */
|
|
1042
|
+
declare function areLiveActivitiesEnabled(): Promise<boolean>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Subscribe to push-token rotations. `startLiveActivity` already re-registers
|
|
1045
|
+
* tokens automatically; this is exposed for apps that drive ActivityKit
|
|
1046
|
+
* themselves. Returns a subscription with `.remove()`.
|
|
1047
|
+
*/
|
|
1048
|
+
declare function onPushTokenUpdate(listener: (event: {
|
|
1049
|
+
activityId: string;
|
|
1050
|
+
activityType: string;
|
|
1051
|
+
pushToken: string;
|
|
1052
|
+
}) => void): {
|
|
1053
|
+
remove: () => void;
|
|
1054
|
+
};
|
|
883
1055
|
|
|
884
1056
|
interface WidgetSyncOptions {
|
|
885
1057
|
refreshInterval?: number;
|
|
@@ -992,4 +1164,4 @@ declare function reportConversion(props?: Record<string, unknown>): Promise<bool
|
|
|
992
1164
|
*/
|
|
993
1165
|
declare function setRNStorage(storage: StorageAdapter | null): void;
|
|
994
1166
|
|
|
995
|
-
export { type AsyncStorageLike, type DeferredDeepLinkHandler, type ErrorContext, type GroupTraits, type NavigationRef, type NavigationTrackerOptions, type NetworkInterceptionOptions, RNAutocaptureModule, type RNAutocaptureOptions, type RNDeviceInfo, type RNErrorHandlerOptions, RNPerformanceManager, type RemoteConfig, type ScreenRecordingConfig, type SitePongConfig, type SitePongInitConfig, SitePongRNProvider, type SitePongRNProviderProps, type SuperLinkConfig, type SuperLinkDeepLink, type SuperLinkEventType, type SuperLinkFingerprint, type SuperLinkIdentityMetadata, type SuperLinkMatchType, type SuperLinkPlatform, type TrackProperties, type TrackedDatabaseOptions, type UserTraits, type WatchtowerConfig, WatchtowerProvider, type WatchtowerProviderProps, type WidgetSyncOptions, addBreadcrumb, areFlagsReady, captureError, captureMessage, clearAnonymousId, clearUser, collectDeviceInfo, completeFromScan, createAsyncStorageAdapter, createNavigationTracker, createSuperLinkListener, createTrackedDatabase, endLiveActivity, fetchNativeDeviceSignals, fetchPersistentDeviceId, flush, flushScreenRecording, flushScreenRecordingOnError, getAllFlags, getAnonymousId, getFlag, getMatchedDeepLink, getRemoteConfig, getVariant, getVariantPayload, getWatchtowerSessionId, group, handleUniversalLink, identify$1 as identify, initRN, initSuperLinkRN, isInitialized, isRemoteConfigFeatureEnabled, isScreenRecording, markColdStart, onDeferredDeepLink, onRemoteConfigChange, parseUniversalLink, refreshFlags, registerDeviceToken, registerLiveActivityToken, registerPushToStartToken, registerPushToken, reportConversion, resetAnalytics, setAnonymousId, setContext, setCurrentScreen, setRNStorage, setTags, setUser, setWatchtowerUser, setupNetworkInterception, setupRNErrorHandler, startScreenRecording, startWatchtower, stopScreenRecording, stopWatchtower, stopWidgetSync, subscribeNavigationToWatchtower, identify as superlinkIdentify, syncWidgets, track, triggerWidgetRefresh, updateWidgetData, useAppState, useRNPerformance, useRemoteConfig, useScreenTrack, useSitePongRNContext, waitForFlags };
|
|
1167
|
+
export { type AsyncStorageLike, type DeferredDeepLinkHandler, type ErrorContext, type GroupTraits, type IconSpec, type LiveActivityAttributes, type LiveActivityContentState, type NavigationRef, type NavigationTrackerOptions, type NetworkInterceptionOptions, type ProgressSpec, RNAutocaptureModule, type RNAutocaptureOptions, type RNDeviceInfo, type RNErrorHandlerOptions, RNPerformanceManager, type RemoteConfig, type ScreenRecordingConfig, SensitiveView, type SitePongConfig, type SitePongInitConfig, SitePongRNProvider, type SitePongRNProviderProps, type StartLiveActivityOptions, type StartedLiveActivity, type SuperLinkConfig, type SuperLinkDeepLink, type SuperLinkEventType, type SuperLinkFingerprint, type SuperLinkIdentityMetadata, type SuperLinkMatchType, type SuperLinkPlatform, type SymbolWeight, type TextStyle, type TextWeight, type TrackProperties, type TrackedDatabaseOptions, type UserTraits, type WatchtowerConfig, WatchtowerProvider, type WatchtowerProviderProps, type WidgetSyncOptions, addBreadcrumb, addSensitiveView, areFlagsReady, areLiveActivitiesEnabled, captureError, captureMessage, clearAnonymousId, clearUser, collectDeviceInfo, completeFromScan, createAsyncStorageAdapter, createNavigationTracker, createSuperLinkListener, createTrackedDatabase, endLiveActivity, fetchNativeDeviceSignals, fetchPersistentDeviceId, flush, flushScreenRecording, flushScreenRecordingOnError, getAllFlags, getAnonymousId, getFlag, getMatchedDeepLink, getRemoteConfig, getVariant, getVariantPayload, getWatchtowerSessionId, group, handleUniversalLink, identify$1 as identify, initRN, initSuperLinkRN, isInitialized, isRemoteConfigFeatureEnabled, isScreenRecording, markColdStart, onDeferredDeepLink, onPushTokenUpdate, onRemoteConfigChange, parseUniversalLink, refreshFlags, registerDeviceToken, registerLiveActivityToken, registerPushToStartToken, registerPushToken, removeSensitiveView, reportConversion, resetAnalytics, setAnonymousId, setContext, setCurrentScreen, setRNStorage, setTags, setUser, setWatchtowerUser, setupNetworkInterception, setupRNErrorHandler, startLiveActivity, startScreenRecording, startWatchtower, stopScreenRecording, stopWatchtower, stopWidgetSync, subscribeNavigationToWatchtower, identify as superlinkIdentify, syncWidgets, track, triggerWidgetRefresh, updateLiveActivity, updateWidgetData, useAppState, useRNPerformance, useRemoteConfig, useScreenTrack, useSitePongRNContext, waitForFlags };
|
package/dist/entries/rn.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
var React2 = require('react');
|
|
4
4
|
var reactNative = require('react-native');
|
|
5
|
+
var expoModulesCore = require('expo-modules-core');
|
|
5
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
var screenRecorder = require('@sitepong/screen-recorder');
|
|
7
7
|
|
|
8
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
|
|
@@ -1918,7 +1918,8 @@ var RemoteConfigManager = class {
|
|
|
1918
1918
|
if (this.refreshTimer) {
|
|
1919
1919
|
clearTimeout(this.refreshTimer);
|
|
1920
1920
|
}
|
|
1921
|
-
const
|
|
1921
|
+
const ttlSec = typeof this.config.ttl === "number" && this.config.ttl > 0 ? this.config.ttl : 300;
|
|
1922
|
+
const ttlMs = ttlSec * 1e3;
|
|
1922
1923
|
this.refreshTimer = setTimeout(() => {
|
|
1923
1924
|
this.fetchAndApply().catch((err) => {
|
|
1924
1925
|
this.log("Refresh failed:", err);
|
|
@@ -3155,6 +3156,39 @@ function createAsyncStorageAdapter(asyncStorage) {
|
|
|
3155
3156
|
removeItem: (key) => asyncStorage.removeItem(key)
|
|
3156
3157
|
};
|
|
3157
3158
|
}
|
|
3159
|
+
var moduleCache = /* @__PURE__ */ new Map();
|
|
3160
|
+
function getNativeModule(name) {
|
|
3161
|
+
if (moduleCache.has(name)) {
|
|
3162
|
+
return moduleCache.get(name);
|
|
3163
|
+
}
|
|
3164
|
+
let mod = null;
|
|
3165
|
+
try {
|
|
3166
|
+
mod = expoModulesCore.requireNativeModule(name);
|
|
3167
|
+
} catch {
|
|
3168
|
+
mod = null;
|
|
3169
|
+
}
|
|
3170
|
+
moduleCache.set(name, mod);
|
|
3171
|
+
return mod;
|
|
3172
|
+
}
|
|
3173
|
+
function getNativeEventEmitter(nativeModule) {
|
|
3174
|
+
if (!nativeModule) return null;
|
|
3175
|
+
try {
|
|
3176
|
+
return new expoModulesCore.EventEmitter(nativeModule);
|
|
3177
|
+
} catch {
|
|
3178
|
+
return null;
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
function getScreenRecorderModule() {
|
|
3182
|
+
return getNativeModule("SitePongScreenRecorder");
|
|
3183
|
+
}
|
|
3184
|
+
function getDeviceIdModule() {
|
|
3185
|
+
return getNativeModule("SitePongDeviceId");
|
|
3186
|
+
}
|
|
3187
|
+
function getLiveActivityModule() {
|
|
3188
|
+
return getNativeModule("SitePongLiveActivity");
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
// src/react-native/device.ts
|
|
3158
3192
|
function collectDeviceInfo() {
|
|
3159
3193
|
const screen = reactNative.Dimensions.get("screen");
|
|
3160
3194
|
return {
|
|
@@ -3166,23 +3200,25 @@ function collectDeviceInfo() {
|
|
|
3166
3200
|
};
|
|
3167
3201
|
}
|
|
3168
3202
|
async function fetchPersistentDeviceId() {
|
|
3169
|
-
|
|
3203
|
+
const mod = getDeviceIdModule();
|
|
3204
|
+
if (!mod?.getDeviceId) return null;
|
|
3205
|
+
try {
|
|
3206
|
+
return await mod.getDeviceId();
|
|
3207
|
+
} catch {
|
|
3208
|
+
return null;
|
|
3209
|
+
}
|
|
3170
3210
|
}
|
|
3171
3211
|
async function fetchNativeDeviceSignals() {
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
if (!nativeModule) {
|
|
3179
|
-
try {
|
|
3180
|
-
nativeModule = __require("@sitepong/screen-recorder");
|
|
3181
|
-
} catch {
|
|
3182
|
-
nativeModule = null;
|
|
3183
|
-
}
|
|
3212
|
+
const mod = getDeviceIdModule();
|
|
3213
|
+
if (!mod?.getDeviceSignals) return null;
|
|
3214
|
+
try {
|
|
3215
|
+
return await mod.getDeviceSignals();
|
|
3216
|
+
} catch {
|
|
3217
|
+
return null;
|
|
3184
3218
|
}
|
|
3185
|
-
|
|
3219
|
+
}
|
|
3220
|
+
function getNativeModule2() {
|
|
3221
|
+
return getScreenRecorderModule();
|
|
3186
3222
|
}
|
|
3187
3223
|
var ERROR_BUFFER_DURATION = 1e4;
|
|
3188
3224
|
var MANUAL_BUFFER_DURATION = 6e4;
|
|
@@ -3202,7 +3238,7 @@ function startScreenRecording(apiKey, endpoint, sessionId, config = {}) {
|
|
|
3202
3238
|
});
|
|
3203
3239
|
}
|
|
3204
3240
|
function _startRecording(apiKey, endpoint, sessionId, config) {
|
|
3205
|
-
const mod =
|
|
3241
|
+
const mod = getNativeModule2();
|
|
3206
3242
|
if (!mod) return false;
|
|
3207
3243
|
if (!config.enabled) return false;
|
|
3208
3244
|
const sampleRate = config.sampleRate ?? 1;
|
|
@@ -3225,7 +3261,7 @@ function _startRecording(apiKey, endpoint, sessionId, config) {
|
|
|
3225
3261
|
return true;
|
|
3226
3262
|
}
|
|
3227
3263
|
function stopScreenRecording() {
|
|
3228
|
-
const mod =
|
|
3264
|
+
const mod = getNativeModule2();
|
|
3229
3265
|
if (!mod || !recordingActive) return;
|
|
3230
3266
|
if (maxDurationTimer) {
|
|
3231
3267
|
clearTimeout(maxDurationTimer);
|
|
@@ -3236,7 +3272,7 @@ function stopScreenRecording() {
|
|
|
3236
3272
|
recordingActive = false;
|
|
3237
3273
|
}
|
|
3238
3274
|
async function flushScreenRecording() {
|
|
3239
|
-
const mod =
|
|
3275
|
+
const mod = getNativeModule2();
|
|
3240
3276
|
if (!mod || !recordingActive) return;
|
|
3241
3277
|
try {
|
|
3242
3278
|
await mod.flushBuffer();
|
|
@@ -3248,6 +3284,33 @@ var flushScreenRecordingOnError = flushScreenRecording;
|
|
|
3248
3284
|
function isScreenRecording() {
|
|
3249
3285
|
return recordingActive;
|
|
3250
3286
|
}
|
|
3287
|
+
function addSensitiveView(viewTag) {
|
|
3288
|
+
getNativeModule2()?.addSensitiveView(viewTag);
|
|
3289
|
+
}
|
|
3290
|
+
function removeSensitiveView(viewTag) {
|
|
3291
|
+
getNativeModule2()?.removeSensitiveView(viewTag);
|
|
3292
|
+
}
|
|
3293
|
+
function SensitiveView(props) {
|
|
3294
|
+
const tagRef = React2.useRef(null);
|
|
3295
|
+
React2.useEffect(() => {
|
|
3296
|
+
return () => {
|
|
3297
|
+
if (tagRef.current != null) removeSensitiveView(tagRef.current);
|
|
3298
|
+
};
|
|
3299
|
+
}, []);
|
|
3300
|
+
const handleLayout = React2.useCallback((e) => {
|
|
3301
|
+
const nativeTag = e.nativeEvent.target;
|
|
3302
|
+
if (typeof nativeTag === "number" && tagRef.current !== nativeTag) {
|
|
3303
|
+
if (tagRef.current != null) removeSensitiveView(tagRef.current);
|
|
3304
|
+
tagRef.current = nativeTag;
|
|
3305
|
+
addSensitiveView(nativeTag);
|
|
3306
|
+
}
|
|
3307
|
+
}, []);
|
|
3308
|
+
return React2.createElement(
|
|
3309
|
+
reactNative.View,
|
|
3310
|
+
{ collapsable: false, onLayout: handleLayout },
|
|
3311
|
+
props.children
|
|
3312
|
+
);
|
|
3313
|
+
}
|
|
3251
3314
|
|
|
3252
3315
|
// src/react-native/error-handler.ts
|
|
3253
3316
|
function setupRNErrorHandler(options = {}) {
|
|
@@ -3768,10 +3831,24 @@ function useRNPerformance(screenName) {
|
|
|
3768
3831
|
}, [screenName, performanceManager]);
|
|
3769
3832
|
return { duration };
|
|
3770
3833
|
}
|
|
3834
|
+
var warnedMissing = false;
|
|
3835
|
+
function loadBridge() {
|
|
3836
|
+
return getScreenRecorderModule();
|
|
3837
|
+
}
|
|
3771
3838
|
var started = false;
|
|
3772
3839
|
function startWatchtower(config) {
|
|
3773
3840
|
if (started) return;
|
|
3774
|
-
|
|
3841
|
+
const bridge = loadBridge();
|
|
3842
|
+
if (!bridge) {
|
|
3843
|
+
if (!warnedMissing) {
|
|
3844
|
+
warnedMissing = true;
|
|
3845
|
+
console.warn(
|
|
3846
|
+
"[SitePong] Watchtower is enabled but the native module is unavailable. Rebuild the native app (npx expo prebuild && npx expo run:ios) so the bundled SitePong native module is linked."
|
|
3847
|
+
);
|
|
3848
|
+
}
|
|
3849
|
+
return;
|
|
3850
|
+
}
|
|
3851
|
+
bridge.watchtowerStart({
|
|
3775
3852
|
apiKey: config.apiKey,
|
|
3776
3853
|
projectId: config.projectId,
|
|
3777
3854
|
endpoint: config.endpoint,
|
|
@@ -3783,27 +3860,27 @@ function startWatchtower(config) {
|
|
|
3783
3860
|
}
|
|
3784
3861
|
function setWatchtowerUser(distinctId) {
|
|
3785
3862
|
try {
|
|
3786
|
-
|
|
3863
|
+
loadBridge()?.watchtowerSetUser(distinctId);
|
|
3787
3864
|
} catch {
|
|
3788
3865
|
}
|
|
3789
3866
|
}
|
|
3790
3867
|
function getWatchtowerSessionId() {
|
|
3791
3868
|
try {
|
|
3792
|
-
return
|
|
3869
|
+
return loadBridge()?.watchtowerGetSessionId() ?? null;
|
|
3793
3870
|
} catch {
|
|
3794
3871
|
return null;
|
|
3795
3872
|
}
|
|
3796
3873
|
}
|
|
3797
3874
|
function stopWatchtower() {
|
|
3798
3875
|
if (!started) return;
|
|
3799
|
-
|
|
3876
|
+
loadBridge()?.watchtowerStop();
|
|
3800
3877
|
started = false;
|
|
3801
3878
|
}
|
|
3802
3879
|
function subscribeNavigationToWatchtower(navigationRef) {
|
|
3803
3880
|
const unsubscribe = createNavigationTracker(navigationRef, {
|
|
3804
3881
|
screenNameFilter: (name) => {
|
|
3805
3882
|
try {
|
|
3806
|
-
|
|
3883
|
+
loadBridge()?.watchtowerSetScreen(name);
|
|
3807
3884
|
} catch {
|
|
3808
3885
|
}
|
|
3809
3886
|
return name;
|
|
@@ -3811,7 +3888,7 @@ function subscribeNavigationToWatchtower(navigationRef) {
|
|
|
3811
3888
|
});
|
|
3812
3889
|
try {
|
|
3813
3890
|
const route = navigationRef.getCurrentRoute?.();
|
|
3814
|
-
if (route?.name)
|
|
3891
|
+
if (route?.name) loadBridge()?.watchtowerSetScreen(route.name);
|
|
3815
3892
|
} catch {
|
|
3816
3893
|
}
|
|
3817
3894
|
return unsubscribe;
|
|
@@ -3933,16 +4010,84 @@ function createTrackedDatabase(db, options = {}) {
|
|
|
3933
4010
|
});
|
|
3934
4011
|
}
|
|
3935
4012
|
|
|
3936
|
-
// src/react-native/
|
|
3937
|
-
var
|
|
3938
|
-
|
|
3939
|
-
|
|
4013
|
+
// src/react-native/live-activity.ts
|
|
4014
|
+
var activityTypeById = /* @__PURE__ */ new Map();
|
|
4015
|
+
function requireNative() {
|
|
4016
|
+
const mod = getLiveActivityModule();
|
|
4017
|
+
if (!mod) {
|
|
4018
|
+
throw new Error(
|
|
4019
|
+
'[SitePong] Live Activities native module unavailable. Enable the config plugin (["sitepong", { "liveActivities": true }]) and rebuild native (iOS 16.2+).'
|
|
4020
|
+
);
|
|
4021
|
+
}
|
|
4022
|
+
return mod;
|
|
4023
|
+
}
|
|
4024
|
+
async function startLiveActivity(options) {
|
|
4025
|
+
const environment = options.environment ?? "production";
|
|
4026
|
+
const native = requireNative();
|
|
4027
|
+
ensureTokenListener();
|
|
4028
|
+
const result = await native.startActivity({
|
|
4029
|
+
activityType: options.activityType,
|
|
4030
|
+
attributes: options.attributes ?? {},
|
|
4031
|
+
contentState: options.contentState,
|
|
4032
|
+
alert: options.alert
|
|
4033
|
+
});
|
|
4034
|
+
activityTypeById.set(result.activityId, options.activityType);
|
|
4035
|
+
registerLiveActivityToken(options.activityType, result.activityId, result.pushToken, { environment });
|
|
4036
|
+
return result;
|
|
4037
|
+
}
|
|
4038
|
+
async function updateLiveActivity(activityId, contentState, options) {
|
|
4039
|
+
await requireNative().updateActivity({ activityId, contentState, alert: options?.alert });
|
|
4040
|
+
}
|
|
4041
|
+
async function endLiveActivity2(activityId, options) {
|
|
4042
|
+
await requireNative().endActivity({
|
|
4043
|
+
activityId,
|
|
4044
|
+
contentState: options?.finalContentState,
|
|
4045
|
+
dismissalDate: options?.dismissalDate
|
|
4046
|
+
});
|
|
4047
|
+
const activityType = activityTypeById.get(activityId);
|
|
4048
|
+
activityTypeById.delete(activityId);
|
|
4049
|
+
if (activityType) endLiveActivity(activityType, activityId);
|
|
4050
|
+
}
|
|
4051
|
+
async function areLiveActivitiesEnabled() {
|
|
4052
|
+
const mod = getLiveActivityModule();
|
|
4053
|
+
if (!mod?.areActivitiesEnabled) return false;
|
|
3940
4054
|
try {
|
|
3941
|
-
return
|
|
4055
|
+
return await mod.areActivitiesEnabled();
|
|
3942
4056
|
} catch {
|
|
3943
|
-
return
|
|
4057
|
+
return false;
|
|
3944
4058
|
}
|
|
3945
4059
|
}
|
|
4060
|
+
function onPushTokenUpdate(listener) {
|
|
4061
|
+
ensureTokenListener();
|
|
4062
|
+
const emitter = getNativeEventEmitter(getLiveActivityModule());
|
|
4063
|
+
if (!emitter) return { remove: () => {
|
|
4064
|
+
} };
|
|
4065
|
+
const subscription = emitter.addListener("liveActivityPushTokenUpdate", listener);
|
|
4066
|
+
return { remove: () => subscription.remove() };
|
|
4067
|
+
}
|
|
4068
|
+
var tokenListenerInstalled = false;
|
|
4069
|
+
function ensureTokenListener() {
|
|
4070
|
+
if (tokenListenerInstalled) return;
|
|
4071
|
+
const emitter = getNativeEventEmitter(getLiveActivityModule());
|
|
4072
|
+
if (!emitter) return;
|
|
4073
|
+
tokenListenerInstalled = true;
|
|
4074
|
+
emitter.addListener(
|
|
4075
|
+
"liveActivityPushTokenUpdate",
|
|
4076
|
+
(event) => {
|
|
4077
|
+
activityTypeById.set(event.activityId, event.activityType);
|
|
4078
|
+
registerLiveActivityToken(event.activityType, event.activityId, event.pushToken, {
|
|
4079
|
+
environment: "production"
|
|
4080
|
+
});
|
|
4081
|
+
}
|
|
4082
|
+
);
|
|
4083
|
+
}
|
|
4084
|
+
|
|
4085
|
+
// src/react-native/widgets.ts
|
|
4086
|
+
var syncTimer = null;
|
|
4087
|
+
var cachedVersion = 0;
|
|
4088
|
+
function getNativeModule3() {
|
|
4089
|
+
return getLiveActivityModule();
|
|
4090
|
+
}
|
|
3946
4091
|
function getEndpoint2() {
|
|
3947
4092
|
const cfg = sitepong.config;
|
|
3948
4093
|
return cfg?.endpoint || "https://api.sitepong.com";
|
|
@@ -3954,7 +4099,7 @@ function getApiKey2() {
|
|
|
3954
4099
|
async function syncWidgets(options) {
|
|
3955
4100
|
const apiKey = getApiKey2();
|
|
3956
4101
|
if (!apiKey) return;
|
|
3957
|
-
const mod =
|
|
4102
|
+
const mod = getNativeModule3();
|
|
3958
4103
|
if (!mod) return;
|
|
3959
4104
|
try {
|
|
3960
4105
|
const res = await fetch(`${getEndpoint2()}/api/sdk/widgets/config`, {
|
|
@@ -3975,7 +4120,7 @@ async function syncWidgets(options) {
|
|
|
3975
4120
|
syncTimer = setInterval(() => syncWidgets(options), interval);
|
|
3976
4121
|
}
|
|
3977
4122
|
async function updateWidgetData(data) {
|
|
3978
|
-
const mod =
|
|
4123
|
+
const mod = getNativeModule3();
|
|
3979
4124
|
if (!mod) return;
|
|
3980
4125
|
try {
|
|
3981
4126
|
await mod.updateWidgetData(JSON.stringify(data));
|
|
@@ -3984,7 +4129,7 @@ async function updateWidgetData(data) {
|
|
|
3984
4129
|
}
|
|
3985
4130
|
}
|
|
3986
4131
|
function triggerWidgetRefresh() {
|
|
3987
|
-
const mod =
|
|
4132
|
+
const mod = getNativeModule3();
|
|
3988
4133
|
if (!mod) return;
|
|
3989
4134
|
mod.updateWidgetData("{}").catch(() => {
|
|
3990
4135
|
});
|
|
@@ -4179,10 +4324,13 @@ function setRNStorage(storage) {
|
|
|
4179
4324
|
|
|
4180
4325
|
exports.RNAutocaptureModule = RNAutocaptureModule;
|
|
4181
4326
|
exports.RNPerformanceManager = RNPerformanceManager;
|
|
4327
|
+
exports.SensitiveView = SensitiveView;
|
|
4182
4328
|
exports.SitePongRNProvider = SitePongRNProvider;
|
|
4183
4329
|
exports.WatchtowerProvider = WatchtowerProvider;
|
|
4184
4330
|
exports.addBreadcrumb = addBreadcrumb;
|
|
4331
|
+
exports.addSensitiveView = addSensitiveView;
|
|
4185
4332
|
exports.areFlagsReady = areFlagsReady;
|
|
4333
|
+
exports.areLiveActivitiesEnabled = areLiveActivitiesEnabled;
|
|
4186
4334
|
exports.captureError = captureError;
|
|
4187
4335
|
exports.captureMessage = captureMessage;
|
|
4188
4336
|
exports.clearAnonymousId = clearAnonymousId;
|
|
@@ -4193,7 +4341,7 @@ exports.createAsyncStorageAdapter = createAsyncStorageAdapter;
|
|
|
4193
4341
|
exports.createNavigationTracker = createNavigationTracker;
|
|
4194
4342
|
exports.createSuperLinkListener = createSuperLinkListener;
|
|
4195
4343
|
exports.createTrackedDatabase = createTrackedDatabase;
|
|
4196
|
-
exports.endLiveActivity =
|
|
4344
|
+
exports.endLiveActivity = endLiveActivity2;
|
|
4197
4345
|
exports.fetchNativeDeviceSignals = fetchNativeDeviceSignals;
|
|
4198
4346
|
exports.fetchPersistentDeviceId = fetchPersistentDeviceId;
|
|
4199
4347
|
exports.flush = flush;
|
|
@@ -4217,6 +4365,7 @@ exports.isRemoteConfigFeatureEnabled = isRemoteConfigFeatureEnabled;
|
|
|
4217
4365
|
exports.isScreenRecording = isScreenRecording;
|
|
4218
4366
|
exports.markColdStart = markColdStart;
|
|
4219
4367
|
exports.onDeferredDeepLink = onDeferredDeepLink;
|
|
4368
|
+
exports.onPushTokenUpdate = onPushTokenUpdate;
|
|
4220
4369
|
exports.onRemoteConfigChange = onRemoteConfigChange;
|
|
4221
4370
|
exports.parseUniversalLink = parseUniversalLink;
|
|
4222
4371
|
exports.refreshFlags = refreshFlags;
|
|
@@ -4224,6 +4373,7 @@ exports.registerDeviceToken = registerDeviceToken;
|
|
|
4224
4373
|
exports.registerLiveActivityToken = registerLiveActivityToken;
|
|
4225
4374
|
exports.registerPushToStartToken = registerPushToStartToken;
|
|
4226
4375
|
exports.registerPushToken = registerPushToken;
|
|
4376
|
+
exports.removeSensitiveView = removeSensitiveView;
|
|
4227
4377
|
exports.reportConversion = reportConversion;
|
|
4228
4378
|
exports.resetAnalytics = resetAnalytics;
|
|
4229
4379
|
exports.setAnonymousId = setAnonymousId;
|
|
@@ -4235,6 +4385,7 @@ exports.setUser = setUser;
|
|
|
4235
4385
|
exports.setWatchtowerUser = setWatchtowerUser;
|
|
4236
4386
|
exports.setupNetworkInterception = setupNetworkInterception;
|
|
4237
4387
|
exports.setupRNErrorHandler = setupRNErrorHandler;
|
|
4388
|
+
exports.startLiveActivity = startLiveActivity;
|
|
4238
4389
|
exports.startScreenRecording = startScreenRecording;
|
|
4239
4390
|
exports.startWatchtower = startWatchtower;
|
|
4240
4391
|
exports.stopScreenRecording = stopScreenRecording;
|
|
@@ -4245,6 +4396,7 @@ exports.superlinkIdentify = identify3;
|
|
|
4245
4396
|
exports.syncWidgets = syncWidgets;
|
|
4246
4397
|
exports.track = track;
|
|
4247
4398
|
exports.triggerWidgetRefresh = triggerWidgetRefresh;
|
|
4399
|
+
exports.updateLiveActivity = updateLiveActivity;
|
|
4248
4400
|
exports.updateWidgetData = updateWidgetData;
|
|
4249
4401
|
exports.useAppState = useAppState;
|
|
4250
4402
|
exports.useRNPerformance = useRNPerformance;
|