@modelnex/sdk 0.5.17 → 0.5.18
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/index.js +66 -5
- package/dist/index.mjs +66 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2718,6 +2718,31 @@ function createTourSocketPool({
|
|
|
2718
2718
|
}
|
|
2719
2719
|
var tourSocketPool = createTourSocketPool();
|
|
2720
2720
|
|
|
2721
|
+
// src/utils/tour-playback-guards.ts
|
|
2722
|
+
function shouldExecuteTourCommandBatch(isPlaybackActive) {
|
|
2723
|
+
return isPlaybackActive;
|
|
2724
|
+
}
|
|
2725
|
+
function shouldAcceptTourStart(state) {
|
|
2726
|
+
return !state.isPlaybackActive && !state.startRequested;
|
|
2727
|
+
}
|
|
2728
|
+
function shouldRunTourAutoDiscovery(state) {
|
|
2729
|
+
return state.enableAutoDiscovery && !state.disabled && !state.isPlaybackActive && !state.startRequested && !state.hasPendingTour;
|
|
2730
|
+
}
|
|
2731
|
+
function shouldLogTourDebugEntry(state) {
|
|
2732
|
+
if (!state.isPlaybackActive) {
|
|
2733
|
+
if (state.entryType !== "tour_start") {
|
|
2734
|
+
return false;
|
|
2735
|
+
}
|
|
2736
|
+
if (state.entryTourType && state.entryTourType !== state.experienceType) {
|
|
2737
|
+
return false;
|
|
2738
|
+
}
|
|
2739
|
+
}
|
|
2740
|
+
if (state.entryTourType && state.entryTourType !== state.experienceType) {
|
|
2741
|
+
return false;
|
|
2742
|
+
}
|
|
2743
|
+
return true;
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2721
2746
|
// src/hooks/useTourPlayback.ts
|
|
2722
2747
|
function resolveElement(step) {
|
|
2723
2748
|
const el = step.element;
|
|
@@ -3251,6 +3276,7 @@ function useTourPlayback({
|
|
|
3251
3276
|
const showCaptionsRef = (0, import_react12.useRef)(showCaptions);
|
|
3252
3277
|
const runIdRef = (0, import_react12.useRef)(null);
|
|
3253
3278
|
const turnIdRef = (0, import_react12.useRef)(null);
|
|
3279
|
+
const startRequestedRef = (0, import_react12.useRef)(false);
|
|
3254
3280
|
const socketRef = (0, import_react12.useRef)(null);
|
|
3255
3281
|
const socketIdRef = (0, import_react12.useRef)(socketId);
|
|
3256
3282
|
const commandUrlRef = (0, import_react12.useRef)(commandUrl);
|
|
@@ -3303,6 +3329,11 @@ function useTourPlayback({
|
|
|
3303
3329
|
}
|
|
3304
3330
|
};
|
|
3305
3331
|
const handleCommand = async (payload) => {
|
|
3332
|
+
if (!shouldExecuteTourCommandBatch(isActiveRef.current)) {
|
|
3333
|
+
const activeType = experienceTypeRef.current;
|
|
3334
|
+
console.log("[TourClient] Ignoring command batch for inactive playback hook:", activeType, payload.stepIndex);
|
|
3335
|
+
return;
|
|
3336
|
+
}
|
|
3306
3337
|
const emitIfOpen = (ev, data) => {
|
|
3307
3338
|
if (socketRef.current !== socket) return;
|
|
3308
3339
|
emitSocketEvent(socket, ev, data);
|
|
@@ -3809,6 +3840,7 @@ function useTourPlayback({
|
|
|
3809
3840
|
return;
|
|
3810
3841
|
}
|
|
3811
3842
|
skipRequestedRef.current = false;
|
|
3843
|
+
startRequestedRef.current = false;
|
|
3812
3844
|
const total = tourData.totalSteps ?? tour?.steps?.length ?? 0;
|
|
3813
3845
|
isActiveRef.current = true;
|
|
3814
3846
|
setIsActive(true);
|
|
@@ -3867,6 +3899,15 @@ function useTourPlayback({
|
|
|
3867
3899
|
};
|
|
3868
3900
|
const handleDebugLog = (entry) => {
|
|
3869
3901
|
const isDev = devModeRef.current || process.env.NODE_ENV === "development" || typeof window !== "undefined" && window.MODELNEX_DEBUG;
|
|
3902
|
+
const entryTourType = entry?.data?.tourContext?.type ?? tourRef.current?.type ?? null;
|
|
3903
|
+
if (!shouldLogTourDebugEntry({
|
|
3904
|
+
isPlaybackActive: isActiveRef.current,
|
|
3905
|
+
entryType: entry?.type,
|
|
3906
|
+
entryTourType,
|
|
3907
|
+
experienceType: experienceTypeRef.current
|
|
3908
|
+
})) {
|
|
3909
|
+
return;
|
|
3910
|
+
}
|
|
3870
3911
|
if (isDev) {
|
|
3871
3912
|
console.log(`%c[ModelNex Tour] ${entry.type}`, "color: #3b82f6; font-weight: bold", entry);
|
|
3872
3913
|
if (typeof window !== "undefined") {
|
|
@@ -3972,6 +4013,7 @@ function useTourPlayback({
|
|
|
3972
4013
|
const stopTour = (0, import_react12.useCallback)(() => {
|
|
3973
4014
|
skipRequestedRef.current = true;
|
|
3974
4015
|
isActiveRef.current = false;
|
|
4016
|
+
startRequestedRef.current = false;
|
|
3975
4017
|
activeExecutionTokenRef.current += 1;
|
|
3976
4018
|
commandInFlightRef.current = false;
|
|
3977
4019
|
activeCommandBatchIdRef.current = null;
|
|
@@ -4013,6 +4055,7 @@ function useTourPlayback({
|
|
|
4013
4055
|
const endingPreviewRunId = previewRunIdRef.current;
|
|
4014
4056
|
const endingStepOrder = stepIndexRef.current;
|
|
4015
4057
|
isActiveRef.current = false;
|
|
4058
|
+
startRequestedRef.current = false;
|
|
4016
4059
|
setPlaybackState("complete");
|
|
4017
4060
|
removeHighlight();
|
|
4018
4061
|
removeCaption();
|
|
@@ -4046,6 +4089,13 @@ function useTourPlayback({
|
|
|
4046
4089
|
onTourEnd?.();
|
|
4047
4090
|
}, [experienceType, userProfile, serverUrl, voice, onTourEnd, websiteId]);
|
|
4048
4091
|
const runTour = (0, import_react12.useCallback)(async (tour, options) => {
|
|
4092
|
+
if (!shouldAcceptTourStart({
|
|
4093
|
+
isPlaybackActive: isActiveRef.current,
|
|
4094
|
+
startRequested: startRequestedRef.current
|
|
4095
|
+
})) {
|
|
4096
|
+
console.log("[TourClient] Ignoring duplicate start request while playback is already active or starting:", tour.id);
|
|
4097
|
+
return;
|
|
4098
|
+
}
|
|
4049
4099
|
setPendingTour(null);
|
|
4050
4100
|
pendingTourRef.current = null;
|
|
4051
4101
|
let retries = 0;
|
|
@@ -4057,6 +4107,7 @@ function useTourPlayback({
|
|
|
4057
4107
|
console.warn("[TourClient] Cannot run tour, socket not connected.");
|
|
4058
4108
|
return;
|
|
4059
4109
|
}
|
|
4110
|
+
startRequestedRef.current = true;
|
|
4060
4111
|
const shouldReview = Boolean(options?.reviewMode);
|
|
4061
4112
|
resetCaptionSuppression();
|
|
4062
4113
|
setReviewStatusMessage(null);
|
|
@@ -4088,8 +4139,13 @@ function useTourPlayback({
|
|
|
4088
4139
|
});
|
|
4089
4140
|
}, [serverUrl, websiteId]);
|
|
4090
4141
|
(0, import_react12.useEffect)(() => {
|
|
4091
|
-
if (!
|
|
4092
|
-
|
|
4142
|
+
if (!shouldRunTourAutoDiscovery({
|
|
4143
|
+
enableAutoDiscovery,
|
|
4144
|
+
disabled,
|
|
4145
|
+
isPlaybackActive: isActiveRef.current,
|
|
4146
|
+
startRequested: startRequestedRef.current,
|
|
4147
|
+
hasPendingTour: Boolean(pendingTourRef.current)
|
|
4148
|
+
})) return;
|
|
4093
4149
|
if (typeof window === "undefined") return;
|
|
4094
4150
|
const params = new URLSearchParams(window.location.search);
|
|
4095
4151
|
const queryParam = experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
|
|
@@ -4137,8 +4193,13 @@ function useTourPlayback({
|
|
|
4137
4193
|
};
|
|
4138
4194
|
}, [serverUrl, toursApiBase, disabled, websiteId, experienceType, enableAutoDiscovery]);
|
|
4139
4195
|
(0, import_react12.useEffect)(() => {
|
|
4140
|
-
if (!
|
|
4141
|
-
|
|
4196
|
+
if (!shouldRunTourAutoDiscovery({
|
|
4197
|
+
enableAutoDiscovery,
|
|
4198
|
+
disabled,
|
|
4199
|
+
isPlaybackActive: isActiveRef.current,
|
|
4200
|
+
startRequested: startRequestedRef.current,
|
|
4201
|
+
hasPendingTour: Boolean(pendingTourRef.current)
|
|
4202
|
+
})) return;
|
|
4142
4203
|
if (!websiteId || !userProfile) return;
|
|
4143
4204
|
if (typeof window !== "undefined") {
|
|
4144
4205
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -4177,7 +4238,7 @@ function useTourPlayback({
|
|
|
4177
4238
|
cancelled = true;
|
|
4178
4239
|
clearTimeout(timer);
|
|
4179
4240
|
};
|
|
4180
|
-
}, [websiteId, serverUrl, toursApiBase, disabled, experienceType, userProfile, enableAutoDiscovery]);
|
|
4241
|
+
}, [websiteId, serverUrl, toursApiBase, disabled, experienceType, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, enableAutoDiscovery]);
|
|
4181
4242
|
(0, import_react12.useEffect)(() => {
|
|
4182
4243
|
if (!disabled || !isActiveRef.current) return;
|
|
4183
4244
|
stopTour();
|
package/dist/index.mjs
CHANGED
|
@@ -2508,6 +2508,31 @@ function createTourSocketPool({
|
|
|
2508
2508
|
}
|
|
2509
2509
|
var tourSocketPool = createTourSocketPool();
|
|
2510
2510
|
|
|
2511
|
+
// src/utils/tour-playback-guards.ts
|
|
2512
|
+
function shouldExecuteTourCommandBatch(isPlaybackActive) {
|
|
2513
|
+
return isPlaybackActive;
|
|
2514
|
+
}
|
|
2515
|
+
function shouldAcceptTourStart(state) {
|
|
2516
|
+
return !state.isPlaybackActive && !state.startRequested;
|
|
2517
|
+
}
|
|
2518
|
+
function shouldRunTourAutoDiscovery(state) {
|
|
2519
|
+
return state.enableAutoDiscovery && !state.disabled && !state.isPlaybackActive && !state.startRequested && !state.hasPendingTour;
|
|
2520
|
+
}
|
|
2521
|
+
function shouldLogTourDebugEntry(state) {
|
|
2522
|
+
if (!state.isPlaybackActive) {
|
|
2523
|
+
if (state.entryType !== "tour_start") {
|
|
2524
|
+
return false;
|
|
2525
|
+
}
|
|
2526
|
+
if (state.entryTourType && state.entryTourType !== state.experienceType) {
|
|
2527
|
+
return false;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
if (state.entryTourType && state.entryTourType !== state.experienceType) {
|
|
2531
|
+
return false;
|
|
2532
|
+
}
|
|
2533
|
+
return true;
|
|
2534
|
+
}
|
|
2535
|
+
|
|
2511
2536
|
// src/hooks/useTourPlayback.ts
|
|
2512
2537
|
function resolveElement(step) {
|
|
2513
2538
|
const el = step.element;
|
|
@@ -3041,6 +3066,7 @@ function useTourPlayback({
|
|
|
3041
3066
|
const showCaptionsRef = useRef8(showCaptions);
|
|
3042
3067
|
const runIdRef = useRef8(null);
|
|
3043
3068
|
const turnIdRef = useRef8(null);
|
|
3069
|
+
const startRequestedRef = useRef8(false);
|
|
3044
3070
|
const socketRef = useRef8(null);
|
|
3045
3071
|
const socketIdRef = useRef8(socketId);
|
|
3046
3072
|
const commandUrlRef = useRef8(commandUrl);
|
|
@@ -3093,6 +3119,11 @@ function useTourPlayback({
|
|
|
3093
3119
|
}
|
|
3094
3120
|
};
|
|
3095
3121
|
const handleCommand = async (payload) => {
|
|
3122
|
+
if (!shouldExecuteTourCommandBatch(isActiveRef.current)) {
|
|
3123
|
+
const activeType = experienceTypeRef.current;
|
|
3124
|
+
console.log("[TourClient] Ignoring command batch for inactive playback hook:", activeType, payload.stepIndex);
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3096
3127
|
const emitIfOpen = (ev, data) => {
|
|
3097
3128
|
if (socketRef.current !== socket) return;
|
|
3098
3129
|
emitSocketEvent(socket, ev, data);
|
|
@@ -3599,6 +3630,7 @@ function useTourPlayback({
|
|
|
3599
3630
|
return;
|
|
3600
3631
|
}
|
|
3601
3632
|
skipRequestedRef.current = false;
|
|
3633
|
+
startRequestedRef.current = false;
|
|
3602
3634
|
const total = tourData.totalSteps ?? tour?.steps?.length ?? 0;
|
|
3603
3635
|
isActiveRef.current = true;
|
|
3604
3636
|
setIsActive(true);
|
|
@@ -3657,6 +3689,15 @@ function useTourPlayback({
|
|
|
3657
3689
|
};
|
|
3658
3690
|
const handleDebugLog = (entry) => {
|
|
3659
3691
|
const isDev = devModeRef.current || process.env.NODE_ENV === "development" || typeof window !== "undefined" && window.MODELNEX_DEBUG;
|
|
3692
|
+
const entryTourType = entry?.data?.tourContext?.type ?? tourRef.current?.type ?? null;
|
|
3693
|
+
if (!shouldLogTourDebugEntry({
|
|
3694
|
+
isPlaybackActive: isActiveRef.current,
|
|
3695
|
+
entryType: entry?.type,
|
|
3696
|
+
entryTourType,
|
|
3697
|
+
experienceType: experienceTypeRef.current
|
|
3698
|
+
})) {
|
|
3699
|
+
return;
|
|
3700
|
+
}
|
|
3660
3701
|
if (isDev) {
|
|
3661
3702
|
console.log(`%c[ModelNex Tour] ${entry.type}`, "color: #3b82f6; font-weight: bold", entry);
|
|
3662
3703
|
if (typeof window !== "undefined") {
|
|
@@ -3762,6 +3803,7 @@ function useTourPlayback({
|
|
|
3762
3803
|
const stopTour = useCallback7(() => {
|
|
3763
3804
|
skipRequestedRef.current = true;
|
|
3764
3805
|
isActiveRef.current = false;
|
|
3806
|
+
startRequestedRef.current = false;
|
|
3765
3807
|
activeExecutionTokenRef.current += 1;
|
|
3766
3808
|
commandInFlightRef.current = false;
|
|
3767
3809
|
activeCommandBatchIdRef.current = null;
|
|
@@ -3803,6 +3845,7 @@ function useTourPlayback({
|
|
|
3803
3845
|
const endingPreviewRunId = previewRunIdRef.current;
|
|
3804
3846
|
const endingStepOrder = stepIndexRef.current;
|
|
3805
3847
|
isActiveRef.current = false;
|
|
3848
|
+
startRequestedRef.current = false;
|
|
3806
3849
|
setPlaybackState("complete");
|
|
3807
3850
|
removeHighlight();
|
|
3808
3851
|
removeCaption();
|
|
@@ -3836,6 +3879,13 @@ function useTourPlayback({
|
|
|
3836
3879
|
onTourEnd?.();
|
|
3837
3880
|
}, [experienceType, userProfile, serverUrl, voice, onTourEnd, websiteId]);
|
|
3838
3881
|
const runTour = useCallback7(async (tour, options) => {
|
|
3882
|
+
if (!shouldAcceptTourStart({
|
|
3883
|
+
isPlaybackActive: isActiveRef.current,
|
|
3884
|
+
startRequested: startRequestedRef.current
|
|
3885
|
+
})) {
|
|
3886
|
+
console.log("[TourClient] Ignoring duplicate start request while playback is already active or starting:", tour.id);
|
|
3887
|
+
return;
|
|
3888
|
+
}
|
|
3839
3889
|
setPendingTour(null);
|
|
3840
3890
|
pendingTourRef.current = null;
|
|
3841
3891
|
let retries = 0;
|
|
@@ -3847,6 +3897,7 @@ function useTourPlayback({
|
|
|
3847
3897
|
console.warn("[TourClient] Cannot run tour, socket not connected.");
|
|
3848
3898
|
return;
|
|
3849
3899
|
}
|
|
3900
|
+
startRequestedRef.current = true;
|
|
3850
3901
|
const shouldReview = Boolean(options?.reviewMode);
|
|
3851
3902
|
resetCaptionSuppression();
|
|
3852
3903
|
setReviewStatusMessage(null);
|
|
@@ -3878,8 +3929,13 @@ function useTourPlayback({
|
|
|
3878
3929
|
});
|
|
3879
3930
|
}, [serverUrl, websiteId]);
|
|
3880
3931
|
useEffect11(() => {
|
|
3881
|
-
if (!
|
|
3882
|
-
|
|
3932
|
+
if (!shouldRunTourAutoDiscovery({
|
|
3933
|
+
enableAutoDiscovery,
|
|
3934
|
+
disabled,
|
|
3935
|
+
isPlaybackActive: isActiveRef.current,
|
|
3936
|
+
startRequested: startRequestedRef.current,
|
|
3937
|
+
hasPendingTour: Boolean(pendingTourRef.current)
|
|
3938
|
+
})) return;
|
|
3883
3939
|
if (typeof window === "undefined") return;
|
|
3884
3940
|
const params = new URLSearchParams(window.location.search);
|
|
3885
3941
|
const queryParam = experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
|
|
@@ -3927,8 +3983,13 @@ function useTourPlayback({
|
|
|
3927
3983
|
};
|
|
3928
3984
|
}, [serverUrl, toursApiBase, disabled, websiteId, experienceType, enableAutoDiscovery]);
|
|
3929
3985
|
useEffect11(() => {
|
|
3930
|
-
if (!
|
|
3931
|
-
|
|
3986
|
+
if (!shouldRunTourAutoDiscovery({
|
|
3987
|
+
enableAutoDiscovery,
|
|
3988
|
+
disabled,
|
|
3989
|
+
isPlaybackActive: isActiveRef.current,
|
|
3990
|
+
startRequested: startRequestedRef.current,
|
|
3991
|
+
hasPendingTour: Boolean(pendingTourRef.current)
|
|
3992
|
+
})) return;
|
|
3932
3993
|
if (!websiteId || !userProfile) return;
|
|
3933
3994
|
if (typeof window !== "undefined") {
|
|
3934
3995
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -3967,7 +4028,7 @@ function useTourPlayback({
|
|
|
3967
4028
|
cancelled = true;
|
|
3968
4029
|
clearTimeout(timer);
|
|
3969
4030
|
};
|
|
3970
|
-
}, [websiteId, serverUrl, toursApiBase, disabled, experienceType, userProfile, enableAutoDiscovery]);
|
|
4031
|
+
}, [websiteId, serverUrl, toursApiBase, disabled, experienceType, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, enableAutoDiscovery]);
|
|
3971
4032
|
useEffect11(() => {
|
|
3972
4033
|
if (!disabled || !isActiveRef.current) return;
|
|
3973
4034
|
stopTour();
|