sitepong 0.2.3 → 0.2.4
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 +188 -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,34 @@ 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
|
+
const { View } = __require("react-native");
|
|
3309
|
+
return React2.createElement(
|
|
3310
|
+
View,
|
|
3311
|
+
{ collapsable: false, onLayout: handleLayout },
|
|
3312
|
+
props.children
|
|
3313
|
+
);
|
|
3314
|
+
}
|
|
3251
3315
|
|
|
3252
3316
|
// src/react-native/error-handler.ts
|
|
3253
3317
|
function setupRNErrorHandler(options = {}) {
|
|
@@ -3768,10 +3832,24 @@ function useRNPerformance(screenName) {
|
|
|
3768
3832
|
}, [screenName, performanceManager]);
|
|
3769
3833
|
return { duration };
|
|
3770
3834
|
}
|
|
3835
|
+
var warnedMissing = false;
|
|
3836
|
+
function loadBridge() {
|
|
3837
|
+
return getScreenRecorderModule();
|
|
3838
|
+
}
|
|
3771
3839
|
var started = false;
|
|
3772
3840
|
function startWatchtower(config) {
|
|
3773
3841
|
if (started) return;
|
|
3774
|
-
|
|
3842
|
+
const bridge = loadBridge();
|
|
3843
|
+
if (!bridge) {
|
|
3844
|
+
if (!warnedMissing) {
|
|
3845
|
+
warnedMissing = true;
|
|
3846
|
+
console.warn(
|
|
3847
|
+
"[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."
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3850
|
+
return;
|
|
3851
|
+
}
|
|
3852
|
+
bridge.watchtowerStart({
|
|
3775
3853
|
apiKey: config.apiKey,
|
|
3776
3854
|
projectId: config.projectId,
|
|
3777
3855
|
endpoint: config.endpoint,
|
|
@@ -3783,27 +3861,27 @@ function startWatchtower(config) {
|
|
|
3783
3861
|
}
|
|
3784
3862
|
function setWatchtowerUser(distinctId) {
|
|
3785
3863
|
try {
|
|
3786
|
-
|
|
3864
|
+
loadBridge()?.watchtowerSetUser(distinctId);
|
|
3787
3865
|
} catch {
|
|
3788
3866
|
}
|
|
3789
3867
|
}
|
|
3790
3868
|
function getWatchtowerSessionId() {
|
|
3791
3869
|
try {
|
|
3792
|
-
return
|
|
3870
|
+
return loadBridge()?.watchtowerGetSessionId() ?? null;
|
|
3793
3871
|
} catch {
|
|
3794
3872
|
return null;
|
|
3795
3873
|
}
|
|
3796
3874
|
}
|
|
3797
3875
|
function stopWatchtower() {
|
|
3798
3876
|
if (!started) return;
|
|
3799
|
-
|
|
3877
|
+
loadBridge()?.watchtowerStop();
|
|
3800
3878
|
started = false;
|
|
3801
3879
|
}
|
|
3802
3880
|
function subscribeNavigationToWatchtower(navigationRef) {
|
|
3803
3881
|
const unsubscribe = createNavigationTracker(navigationRef, {
|
|
3804
3882
|
screenNameFilter: (name) => {
|
|
3805
3883
|
try {
|
|
3806
|
-
|
|
3884
|
+
loadBridge()?.watchtowerSetScreen(name);
|
|
3807
3885
|
} catch {
|
|
3808
3886
|
}
|
|
3809
3887
|
return name;
|
|
@@ -3811,7 +3889,7 @@ function subscribeNavigationToWatchtower(navigationRef) {
|
|
|
3811
3889
|
});
|
|
3812
3890
|
try {
|
|
3813
3891
|
const route = navigationRef.getCurrentRoute?.();
|
|
3814
|
-
if (route?.name)
|
|
3892
|
+
if (route?.name) loadBridge()?.watchtowerSetScreen(route.name);
|
|
3815
3893
|
} catch {
|
|
3816
3894
|
}
|
|
3817
3895
|
return unsubscribe;
|
|
@@ -3933,16 +4011,84 @@ function createTrackedDatabase(db, options = {}) {
|
|
|
3933
4011
|
});
|
|
3934
4012
|
}
|
|
3935
4013
|
|
|
3936
|
-
// src/react-native/
|
|
3937
|
-
var
|
|
3938
|
-
|
|
3939
|
-
|
|
4014
|
+
// src/react-native/live-activity.ts
|
|
4015
|
+
var activityTypeById = /* @__PURE__ */ new Map();
|
|
4016
|
+
function requireNative() {
|
|
4017
|
+
const mod = getLiveActivityModule();
|
|
4018
|
+
if (!mod) {
|
|
4019
|
+
throw new Error(
|
|
4020
|
+
'[SitePong] Live Activities native module unavailable. Enable the config plugin (["sitepong", { "liveActivities": true }]) and rebuild native (iOS 16.2+).'
|
|
4021
|
+
);
|
|
4022
|
+
}
|
|
4023
|
+
return mod;
|
|
4024
|
+
}
|
|
4025
|
+
async function startLiveActivity(options) {
|
|
4026
|
+
const environment = options.environment ?? "production";
|
|
4027
|
+
const native = requireNative();
|
|
4028
|
+
ensureTokenListener();
|
|
4029
|
+
const result = await native.startActivity({
|
|
4030
|
+
activityType: options.activityType,
|
|
4031
|
+
attributes: options.attributes ?? {},
|
|
4032
|
+
contentState: options.contentState,
|
|
4033
|
+
alert: options.alert
|
|
4034
|
+
});
|
|
4035
|
+
activityTypeById.set(result.activityId, options.activityType);
|
|
4036
|
+
registerLiveActivityToken(options.activityType, result.activityId, result.pushToken, { environment });
|
|
4037
|
+
return result;
|
|
4038
|
+
}
|
|
4039
|
+
async function updateLiveActivity(activityId, contentState, options) {
|
|
4040
|
+
await requireNative().updateActivity({ activityId, contentState, alert: options?.alert });
|
|
4041
|
+
}
|
|
4042
|
+
async function endLiveActivity2(activityId, options) {
|
|
4043
|
+
await requireNative().endActivity({
|
|
4044
|
+
activityId,
|
|
4045
|
+
contentState: options?.finalContentState,
|
|
4046
|
+
dismissalDate: options?.dismissalDate
|
|
4047
|
+
});
|
|
4048
|
+
const activityType = activityTypeById.get(activityId);
|
|
4049
|
+
activityTypeById.delete(activityId);
|
|
4050
|
+
if (activityType) endLiveActivity(activityType, activityId);
|
|
4051
|
+
}
|
|
4052
|
+
async function areLiveActivitiesEnabled() {
|
|
4053
|
+
const mod = getLiveActivityModule();
|
|
4054
|
+
if (!mod?.areActivitiesEnabled) return false;
|
|
3940
4055
|
try {
|
|
3941
|
-
return
|
|
4056
|
+
return await mod.areActivitiesEnabled();
|
|
3942
4057
|
} catch {
|
|
3943
|
-
return
|
|
4058
|
+
return false;
|
|
3944
4059
|
}
|
|
3945
4060
|
}
|
|
4061
|
+
function onPushTokenUpdate(listener) {
|
|
4062
|
+
ensureTokenListener();
|
|
4063
|
+
const emitter = getNativeEventEmitter(getLiveActivityModule());
|
|
4064
|
+
if (!emitter) return { remove: () => {
|
|
4065
|
+
} };
|
|
4066
|
+
const subscription = emitter.addListener("liveActivityPushTokenUpdate", listener);
|
|
4067
|
+
return { remove: () => subscription.remove() };
|
|
4068
|
+
}
|
|
4069
|
+
var tokenListenerInstalled = false;
|
|
4070
|
+
function ensureTokenListener() {
|
|
4071
|
+
if (tokenListenerInstalled) return;
|
|
4072
|
+
const emitter = getNativeEventEmitter(getLiveActivityModule());
|
|
4073
|
+
if (!emitter) return;
|
|
4074
|
+
tokenListenerInstalled = true;
|
|
4075
|
+
emitter.addListener(
|
|
4076
|
+
"liveActivityPushTokenUpdate",
|
|
4077
|
+
(event) => {
|
|
4078
|
+
activityTypeById.set(event.activityId, event.activityType);
|
|
4079
|
+
registerLiveActivityToken(event.activityType, event.activityId, event.pushToken, {
|
|
4080
|
+
environment: "production"
|
|
4081
|
+
});
|
|
4082
|
+
}
|
|
4083
|
+
);
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
// src/react-native/widgets.ts
|
|
4087
|
+
var syncTimer = null;
|
|
4088
|
+
var cachedVersion = 0;
|
|
4089
|
+
function getNativeModule3() {
|
|
4090
|
+
return getLiveActivityModule();
|
|
4091
|
+
}
|
|
3946
4092
|
function getEndpoint2() {
|
|
3947
4093
|
const cfg = sitepong.config;
|
|
3948
4094
|
return cfg?.endpoint || "https://api.sitepong.com";
|
|
@@ -3954,7 +4100,7 @@ function getApiKey2() {
|
|
|
3954
4100
|
async function syncWidgets(options) {
|
|
3955
4101
|
const apiKey = getApiKey2();
|
|
3956
4102
|
if (!apiKey) return;
|
|
3957
|
-
const mod =
|
|
4103
|
+
const mod = getNativeModule3();
|
|
3958
4104
|
if (!mod) return;
|
|
3959
4105
|
try {
|
|
3960
4106
|
const res = await fetch(`${getEndpoint2()}/api/sdk/widgets/config`, {
|
|
@@ -3975,7 +4121,7 @@ async function syncWidgets(options) {
|
|
|
3975
4121
|
syncTimer = setInterval(() => syncWidgets(options), interval);
|
|
3976
4122
|
}
|
|
3977
4123
|
async function updateWidgetData(data) {
|
|
3978
|
-
const mod =
|
|
4124
|
+
const mod = getNativeModule3();
|
|
3979
4125
|
if (!mod) return;
|
|
3980
4126
|
try {
|
|
3981
4127
|
await mod.updateWidgetData(JSON.stringify(data));
|
|
@@ -3984,7 +4130,7 @@ async function updateWidgetData(data) {
|
|
|
3984
4130
|
}
|
|
3985
4131
|
}
|
|
3986
4132
|
function triggerWidgetRefresh() {
|
|
3987
|
-
const mod =
|
|
4133
|
+
const mod = getNativeModule3();
|
|
3988
4134
|
if (!mod) return;
|
|
3989
4135
|
mod.updateWidgetData("{}").catch(() => {
|
|
3990
4136
|
});
|
|
@@ -4179,10 +4325,13 @@ function setRNStorage(storage) {
|
|
|
4179
4325
|
|
|
4180
4326
|
exports.RNAutocaptureModule = RNAutocaptureModule;
|
|
4181
4327
|
exports.RNPerformanceManager = RNPerformanceManager;
|
|
4328
|
+
exports.SensitiveView = SensitiveView;
|
|
4182
4329
|
exports.SitePongRNProvider = SitePongRNProvider;
|
|
4183
4330
|
exports.WatchtowerProvider = WatchtowerProvider;
|
|
4184
4331
|
exports.addBreadcrumb = addBreadcrumb;
|
|
4332
|
+
exports.addSensitiveView = addSensitiveView;
|
|
4185
4333
|
exports.areFlagsReady = areFlagsReady;
|
|
4334
|
+
exports.areLiveActivitiesEnabled = areLiveActivitiesEnabled;
|
|
4186
4335
|
exports.captureError = captureError;
|
|
4187
4336
|
exports.captureMessage = captureMessage;
|
|
4188
4337
|
exports.clearAnonymousId = clearAnonymousId;
|
|
@@ -4193,7 +4342,7 @@ exports.createAsyncStorageAdapter = createAsyncStorageAdapter;
|
|
|
4193
4342
|
exports.createNavigationTracker = createNavigationTracker;
|
|
4194
4343
|
exports.createSuperLinkListener = createSuperLinkListener;
|
|
4195
4344
|
exports.createTrackedDatabase = createTrackedDatabase;
|
|
4196
|
-
exports.endLiveActivity =
|
|
4345
|
+
exports.endLiveActivity = endLiveActivity2;
|
|
4197
4346
|
exports.fetchNativeDeviceSignals = fetchNativeDeviceSignals;
|
|
4198
4347
|
exports.fetchPersistentDeviceId = fetchPersistentDeviceId;
|
|
4199
4348
|
exports.flush = flush;
|
|
@@ -4217,6 +4366,7 @@ exports.isRemoteConfigFeatureEnabled = isRemoteConfigFeatureEnabled;
|
|
|
4217
4366
|
exports.isScreenRecording = isScreenRecording;
|
|
4218
4367
|
exports.markColdStart = markColdStart;
|
|
4219
4368
|
exports.onDeferredDeepLink = onDeferredDeepLink;
|
|
4369
|
+
exports.onPushTokenUpdate = onPushTokenUpdate;
|
|
4220
4370
|
exports.onRemoteConfigChange = onRemoteConfigChange;
|
|
4221
4371
|
exports.parseUniversalLink = parseUniversalLink;
|
|
4222
4372
|
exports.refreshFlags = refreshFlags;
|
|
@@ -4224,6 +4374,7 @@ exports.registerDeviceToken = registerDeviceToken;
|
|
|
4224
4374
|
exports.registerLiveActivityToken = registerLiveActivityToken;
|
|
4225
4375
|
exports.registerPushToStartToken = registerPushToStartToken;
|
|
4226
4376
|
exports.registerPushToken = registerPushToken;
|
|
4377
|
+
exports.removeSensitiveView = removeSensitiveView;
|
|
4227
4378
|
exports.reportConversion = reportConversion;
|
|
4228
4379
|
exports.resetAnalytics = resetAnalytics;
|
|
4229
4380
|
exports.setAnonymousId = setAnonymousId;
|
|
@@ -4235,6 +4386,7 @@ exports.setUser = setUser;
|
|
|
4235
4386
|
exports.setWatchtowerUser = setWatchtowerUser;
|
|
4236
4387
|
exports.setupNetworkInterception = setupNetworkInterception;
|
|
4237
4388
|
exports.setupRNErrorHandler = setupRNErrorHandler;
|
|
4389
|
+
exports.startLiveActivity = startLiveActivity;
|
|
4238
4390
|
exports.startScreenRecording = startScreenRecording;
|
|
4239
4391
|
exports.startWatchtower = startWatchtower;
|
|
4240
4392
|
exports.stopScreenRecording = stopScreenRecording;
|
|
@@ -4245,6 +4397,7 @@ exports.superlinkIdentify = identify3;
|
|
|
4245
4397
|
exports.syncWidgets = syncWidgets;
|
|
4246
4398
|
exports.track = track;
|
|
4247
4399
|
exports.triggerWidgetRefresh = triggerWidgetRefresh;
|
|
4400
|
+
exports.updateLiveActivity = updateLiveActivity;
|
|
4248
4401
|
exports.updateWidgetData = updateWidgetData;
|
|
4249
4402
|
exports.useAppState = useAppState;
|
|
4250
4403
|
exports.useRNPerformance = useRNPerformance;
|