sitepong 0.2.13 → 0.2.15
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/dist/cdn/sitepong.min.js +5 -5
- package/dist/cdn/sitepong.min.js.map +1 -1
- package/dist/entries/rn.d.ts +28 -1
- package/dist/entries/rn.js +44 -5
- package/dist/entries/rn.js.map +1 -1
- package/dist/entries/web.js +30 -2
- package/dist/entries/web.js.map +1 -1
- package/dist/entries/web.mjs +30 -2
- package/dist/entries/web.mjs.map +1 -1
- package/dist/index.d.mts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +5 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +5 -1
- package/dist/react/index.mjs.map +1 -1
- package/ios/ScreenRecorder/ScreenRecorderModule.swift +9 -3
- package/ios/WatchtowerCore/StructuralRecorder.swift +163 -19
- package/ios/WatchtowerCore/TapEvent.swift +5 -0
- package/ios/WatchtowerCore/Watchtower.swift +48 -3
- package/ios/WatchtowerCore/WatchtowerEngine.swift +26 -1
- package/package.json +1 -1
package/dist/entries/rn.d.ts
CHANGED
|
@@ -360,6 +360,14 @@ interface SitePongInitConfig extends SitePongConfig {
|
|
|
360
360
|
blockSelector?: string;
|
|
361
361
|
/** CSS selector whose text is masked in the screen template */
|
|
362
362
|
maskSelector?: string;
|
|
363
|
+
/**
|
|
364
|
+
* Release channel / environment tagged on events (development | preview |
|
|
365
|
+
* production | …). Defaults to the SDK `environment` (usually 'production').
|
|
366
|
+
* A channel in `ignoreChannels` suppresses capture entirely.
|
|
367
|
+
*/
|
|
368
|
+
channel?: string;
|
|
369
|
+
/** Channels for which capture is a no-op (default ['development']). */
|
|
370
|
+
ignoreChannels?: string[];
|
|
363
371
|
};
|
|
364
372
|
/** Cron monitoring configuration */
|
|
365
373
|
crons?: {
|
|
@@ -738,6 +746,17 @@ interface WatchtowerConfig {
|
|
|
738
746
|
* Default 30_000 (30s). Lower it in tests to exercise session rolling.
|
|
739
747
|
*/
|
|
740
748
|
sessionGraceMs?: number;
|
|
749
|
+
/**
|
|
750
|
+
* Release channel / environment tagged on every event (development | preview
|
|
751
|
+
* | production | …). When omitted, the native engine auto-resolves it:
|
|
752
|
+
* debug builds → "development", release builds → "production".
|
|
753
|
+
*/
|
|
754
|
+
channel?: string;
|
|
755
|
+
/**
|
|
756
|
+
* Channels for which capture is a complete no-op (default ["development"]).
|
|
757
|
+
* Debug builds thus self-suppress; pass [] to capture dev on demand.
|
|
758
|
+
*/
|
|
759
|
+
ignoreChannels?: string[];
|
|
741
760
|
}
|
|
742
761
|
/**
|
|
743
762
|
* Start the shared native capture engine for React Native. Idempotent.
|
|
@@ -749,7 +768,7 @@ declare function startWatchtower(config: WatchtowerConfig): void;
|
|
|
749
768
|
* Set user identity — stamped as distinct_id on every subsequent event. Call
|
|
750
769
|
* this wherever you call the SDK's identify(), with the same id.
|
|
751
770
|
*/
|
|
752
|
-
declare function setWatchtowerUser(distinctId: string | null): void;
|
|
771
|
+
declare function setWatchtowerUser(distinctId: string | null, email?: string | null, name?: string | null): void;
|
|
753
772
|
/**
|
|
754
773
|
* The engine's current capture session id (null when not running). Attach it
|
|
755
774
|
* to error reports/analytics — it is the key that joins an error to its
|
|
@@ -792,6 +811,14 @@ interface StructuralCaptureConfig {
|
|
|
792
811
|
sampleIntervalMs?: number;
|
|
793
812
|
flushIntervalMs?: number;
|
|
794
813
|
debug?: boolean;
|
|
814
|
+
/**
|
|
815
|
+
* Release channel / environment (development | preview | production | …).
|
|
816
|
+
* Defaults to 'development' under __DEV__, else 'production'. A channel in
|
|
817
|
+
* `ignoreChannels` makes start() a no-op so dev replays are never sent.
|
|
818
|
+
*/
|
|
819
|
+
channel?: string;
|
|
820
|
+
/** Channels for which capture is a no-op (default ['development']). */
|
|
821
|
+
ignoreChannels?: string[];
|
|
795
822
|
}
|
|
796
823
|
declare class StructuralCapture {
|
|
797
824
|
private readonly recorder;
|
package/dist/entries/rn.js
CHANGED
|
@@ -2625,7 +2625,7 @@ var SitePongClient = class {
|
|
|
2625
2625
|
}
|
|
2626
2626
|
for (const hook of this.identifyHooks) {
|
|
2627
2627
|
try {
|
|
2628
|
-
hook(userId);
|
|
2628
|
+
hook(userId, traits);
|
|
2629
2629
|
} catch (err) {
|
|
2630
2630
|
this.log("identify hook failed:", err);
|
|
2631
2631
|
}
|
|
@@ -2731,6 +2731,10 @@ var SitePongClient = class {
|
|
|
2731
2731
|
flushInterval: opts.flushInterval,
|
|
2732
2732
|
blockSelector: opts.blockSelector,
|
|
2733
2733
|
maskSelector: opts.maskSelector,
|
|
2734
|
+
// Channel defaults to the SDK environment; ignoreChannels defaults to
|
|
2735
|
+
// ['development'] inside the capture when omitted.
|
|
2736
|
+
channel: opts.channel ?? this.config.environment,
|
|
2737
|
+
ignoreChannels: opts.ignoreChannels,
|
|
2734
2738
|
debug: this.config.debug
|
|
2735
2739
|
});
|
|
2736
2740
|
this.watchtowerCapture.start(this.analyticsManager?.getAutocaptureModule() ?? null);
|
|
@@ -3149,7 +3153,7 @@ sitepong.flushProfiles.bind(sitepong);
|
|
|
3149
3153
|
var getRemoteConfig = sitepong.getRemoteConfig.bind(sitepong);
|
|
3150
3154
|
var isRemoteConfigFeatureEnabled = sitepong.isRemoteConfigFeatureEnabled.bind(sitepong);
|
|
3151
3155
|
var onRemoteConfigChange = sitepong.onRemoteConfigChange.bind(sitepong);
|
|
3152
|
-
sitepong.registerIdentifyHook.bind(sitepong);
|
|
3156
|
+
var registerIdentifyHook = sitepong.registerIdentifyHook.bind(sitepong);
|
|
3153
3157
|
|
|
3154
3158
|
// src/react-native/storage.ts
|
|
3155
3159
|
function createAsyncStorageAdapter(asyncStorage) {
|
|
@@ -3954,9 +3958,26 @@ function fiberRootFromInstance(instance) {
|
|
|
3954
3958
|
return fiberRoot && typeof fiberRoot === "object" && fiberRoot.current ? fiberRoot : null;
|
|
3955
3959
|
}
|
|
3956
3960
|
|
|
3961
|
+
// src/analytics/channel.ts
|
|
3962
|
+
function normalize(v) {
|
|
3963
|
+
const c = v?.trim().toLowerCase();
|
|
3964
|
+
return c && c.length > 0 ? c : void 0;
|
|
3965
|
+
}
|
|
3966
|
+
function resolveChannel(explicit, buildDefault) {
|
|
3967
|
+
return normalize(explicit) ?? buildDefault;
|
|
3968
|
+
}
|
|
3969
|
+
function isChannelSuppressed(channel, ignoreChannels) {
|
|
3970
|
+
const ignore = (ignoreChannels ?? ["development"]).map((c) => normalize(c)).filter((c) => c !== void 0);
|
|
3971
|
+
return ignore.includes(channel);
|
|
3972
|
+
}
|
|
3973
|
+
|
|
3957
3974
|
// src/react-native/structural/capture.ts
|
|
3958
3975
|
var WALK_BUDGET_MS = 24;
|
|
3959
3976
|
var MAX_OVERLOAD_SKIP = 8;
|
|
3977
|
+
function rnDefaultChannel() {
|
|
3978
|
+
const dev = globalThis.__DEV__;
|
|
3979
|
+
return dev ? "development" : "production";
|
|
3980
|
+
}
|
|
3960
3981
|
function genSessionId() {
|
|
3961
3982
|
const rand = Math.floor(Math.random() * 16777215).toString(36);
|
|
3962
3983
|
return `wt-${Date.now().toString(36)}-${rand}`;
|
|
@@ -4005,6 +4026,11 @@ var StructuralCapture = class {
|
|
|
4005
4026
|
}
|
|
4006
4027
|
start(cfg) {
|
|
4007
4028
|
if (this.running) return;
|
|
4029
|
+
const channel = resolveChannel(cfg.channel, rnDefaultChannel());
|
|
4030
|
+
if (isChannelSuppressed(channel, cfg.ignoreChannels)) {
|
|
4031
|
+
if (cfg.debug) console.log("[structural] suppressed channel", channel, "\u2014 not capturing");
|
|
4032
|
+
return;
|
|
4033
|
+
}
|
|
4008
4034
|
installStructuralHook();
|
|
4009
4035
|
this.cfg = cfg;
|
|
4010
4036
|
this.sessionId = cfg.sessionId || genSessionId();
|
|
@@ -4725,6 +4751,7 @@ function loadBridge() {
|
|
|
4725
4751
|
return getScreenRecorderModule();
|
|
4726
4752
|
}
|
|
4727
4753
|
var started = false;
|
|
4754
|
+
var identifyHookUnsub = null;
|
|
4728
4755
|
function startWatchtower(config) {
|
|
4729
4756
|
if (started) return;
|
|
4730
4757
|
const bridge = loadBridge();
|
|
@@ -4743,14 +4770,24 @@ function startWatchtower(config) {
|
|
|
4743
4770
|
endpoint: config.endpoint,
|
|
4744
4771
|
sampleRate: config.sampleRate ?? 0.1,
|
|
4745
4772
|
platform: config.platform ?? "react-native-ios",
|
|
4746
|
-
sessionGraceMs: config.sessionGraceMs ?? 3e4
|
|
4773
|
+
sessionGraceMs: config.sessionGraceMs ?? 3e4,
|
|
4774
|
+
// Forwarded to WatchtowerCore; undefined channel → native auto-resolves
|
|
4775
|
+
// (debug→development, release→production). ignoreChannels defaults to
|
|
4776
|
+
// ["development"] natively when omitted.
|
|
4777
|
+
channel: config.channel,
|
|
4778
|
+
ignoreChannels: config.ignoreChannels
|
|
4747
4779
|
});
|
|
4748
4780
|
started = true;
|
|
4749
4781
|
if (config.distinctId) setWatchtowerUser(config.distinctId);
|
|
4782
|
+
if (!identifyHookUnsub) {
|
|
4783
|
+
identifyHookUnsub = registerIdentifyHook(
|
|
4784
|
+
(userId, traits) => setWatchtowerUser(userId, traits?.email ?? null, traits?.name ?? null)
|
|
4785
|
+
);
|
|
4786
|
+
}
|
|
4750
4787
|
}
|
|
4751
|
-
function setWatchtowerUser(distinctId) {
|
|
4788
|
+
function setWatchtowerUser(distinctId, email = null, name = null) {
|
|
4752
4789
|
try {
|
|
4753
|
-
loadBridge()?.watchtowerSetUser(distinctId);
|
|
4790
|
+
loadBridge()?.watchtowerSetUser(distinctId, email, name);
|
|
4754
4791
|
} catch {
|
|
4755
4792
|
}
|
|
4756
4793
|
}
|
|
@@ -4765,6 +4802,8 @@ function stopWatchtower() {
|
|
|
4765
4802
|
if (!started) return;
|
|
4766
4803
|
loadBridge()?.watchtowerStop();
|
|
4767
4804
|
started = false;
|
|
4805
|
+
identifyHookUnsub?.();
|
|
4806
|
+
identifyHookUnsub = null;
|
|
4768
4807
|
}
|
|
4769
4808
|
function subscribeNavigationToWatchtower(navigationRef) {
|
|
4770
4809
|
const unsubscribe = createNavigationTracker(navigationRef, {
|