@modelnex/sdk 0.5.49 → 0.5.51

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 CHANGED
@@ -3881,16 +3881,17 @@ function compactTourForTransport(tour) {
3881
3881
 
3882
3882
  // src/utils/tourSessionPersistence.ts
3883
3883
  var ACTIVE_TOUR_SESSION_STORAGE_KEY = "modelnex-active-tour-session";
3884
- var ACTIVE_TOUR_SESSION_VERSION = 1;
3884
+ var ACTIVE_TOUR_SESSION_VERSION = 2;
3885
3885
  var ACTIVE_TOUR_SESSION_MAX_AGE_MS = 10 * 60 * 1e3;
3886
3886
  function canUseSessionStorage2() {
3887
3887
  return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
3888
3888
  }
3889
- function persistActiveTourSession(runId) {
3889
+ function persistActiveTourSession(runId, experienceType) {
3890
3890
  if (!canUseSessionStorage2() || !Number.isFinite(runId)) return;
3891
3891
  const session = {
3892
3892
  version: ACTIVE_TOUR_SESSION_VERSION,
3893
3893
  runId,
3894
+ experienceType,
3894
3895
  savedAt: Date.now()
3895
3896
  };
3896
3897
  try {
@@ -3911,7 +3912,7 @@ function readPersistedActiveTourSession() {
3911
3912
  const raw = window.sessionStorage.getItem(ACTIVE_TOUR_SESSION_STORAGE_KEY);
3912
3913
  if (!raw) return null;
3913
3914
  const parsed = JSON.parse(raw);
3914
- const isValid = parsed && parsed.version === ACTIVE_TOUR_SESSION_VERSION && typeof parsed.runId === "number" && Number.isFinite(parsed.runId) && typeof parsed.savedAt === "number" && Number.isFinite(parsed.savedAt);
3915
+ const isValid = parsed && parsed.version === ACTIVE_TOUR_SESSION_VERSION && typeof parsed.runId === "number" && Number.isFinite(parsed.runId) && typeof parsed.experienceType === "string" && typeof parsed.savedAt === "number" && Number.isFinite(parsed.savedAt);
3915
3916
  if (!isValid) {
3916
3917
  clearPersistedActiveTourSession();
3917
3918
  return null;
@@ -4543,9 +4544,12 @@ function useTourPlayback({
4543
4544
  const pendingTourOptionsRef = (0, import_react12.useRef)(null);
4544
4545
  const showCaptionsRef = (0, import_react12.useRef)(showCaptions);
4545
4546
  const initialPersistedTourSessionRef = (0, import_react12.useRef)(readPersistedActiveTourSession());
4546
- const runIdRef = (0, import_react12.useRef)(initialPersistedTourSessionRef.current?.runId ?? null);
4547
+ const runIdRef = (0, import_react12.useRef)(
4548
+ initialPersistedTourSessionRef.current?.experienceType === experienceType ? initialPersistedTourSessionRef.current.runId : null
4549
+ );
4547
4550
  const turnIdRef = (0, import_react12.useRef)(null);
4548
4551
  const startRequestedRef = (0, import_react12.useRef)(false);
4552
+ const serverStateRef = (0, import_react12.useRef)(null);
4549
4553
  const playbackOwnerIdRef = (0, import_react12.useRef)(`playback-owner-${Math.random().toString(36).slice(2, 10)}`);
4550
4554
  const claimedPlaybackOwnerKeyRef = (0, import_react12.useRef)(null);
4551
4555
  const socketRef = (0, import_react12.useRef)(null);
@@ -4565,6 +4569,7 @@ function useTourPlayback({
4565
4569
  toursApiBaseRef.current = toursApiBase;
4566
4570
  pendingTourRef.current = pendingTour;
4567
4571
  showCaptionsRef.current = showCaptions;
4572
+ serverStateRef.current = serverState;
4568
4573
  const releasePlaybackOwnership = (0, import_react12.useCallback)(() => {
4569
4574
  const claimedKey = claimedPlaybackOwnerKeyRef.current;
4570
4575
  if (!claimedKey) return;
@@ -4572,7 +4577,8 @@ function useTourPlayback({
4572
4577
  claimedPlaybackOwnerKeyRef.current = null;
4573
4578
  }, []);
4574
4579
  const emitTourInit = (0, import_react12.useCallback)((socket, currentWebsiteId, profile) => {
4575
- const persistedRunId = runIdRef.current ?? readPersistedActiveTourSession()?.runId ?? null;
4580
+ const persistedSession = readPersistedActiveTourSession();
4581
+ const persistedRunId = runIdRef.current ?? (persistedSession?.experienceType === experienceTypeRef.current ? persistedSession.runId : null);
4576
4582
  const payload = {};
4577
4583
  if (currentWebsiteId) {
4578
4584
  payload.websiteId = currentWebsiteId;
@@ -4605,6 +4611,7 @@ function useTourPlayback({
4605
4611
  emitTourInit(socket, currentWebsiteId, profile);
4606
4612
  };
4607
4613
  const handleServerState = (payload) => {
4614
+ serverStateRef.current = payload;
4608
4615
  if (typeof payload?.runId === "number") {
4609
4616
  runIdRef.current = payload.runId;
4610
4617
  }
@@ -4612,7 +4619,7 @@ function useTourPlayback({
4612
4619
  turnIdRef.current = payload.turnId ?? null;
4613
4620
  }
4614
4621
  if (payload?.isActive && typeof payload?.runId === "number") {
4615
- persistActiveTourSession(payload.runId);
4622
+ persistActiveTourSession(payload.runId, experienceTypeRef.current);
4616
4623
  } else if (payload?.isActive === false) {
4617
4624
  clearPersistedActiveTourSession();
4618
4625
  }
@@ -5247,7 +5254,7 @@ function useTourPlayback({
5247
5254
  if (isActiveRef.current) return;
5248
5255
  runIdRef.current = typeof tourData.runId === "number" ? tourData.runId : runIdRef.current;
5249
5256
  if (typeof runIdRef.current === "number") {
5250
- persistActiveTourSession(runIdRef.current);
5257
+ persistActiveTourSession(runIdRef.current, experienceTypeRef.current);
5251
5258
  }
5252
5259
  const tour = tourData.tourContext ?? tourRef.current;
5253
5260
  const expType = experienceTypeRef.current;
@@ -5268,6 +5275,9 @@ function useTourPlayback({
5268
5275
  claimedPlaybackOwnerKeyRef.current = ownerKey;
5269
5276
  skipRequestedRef.current = false;
5270
5277
  startRequestedRef.current = false;
5278
+ setPendingTour(null);
5279
+ pendingTourRef.current = null;
5280
+ pendingTourOptionsRef.current = null;
5271
5281
  const total = tourData.totalSteps ?? tour?.steps?.length ?? 0;
5272
5282
  const requestedStepIndex = typeof tourData.currentStepIndex === "number" ? tourData.currentStepIndex : 0;
5273
5283
  const clampedStepIndex = Math.max(0, Math.min(requestedStepIndex, Math.max(0, total - 1)));
@@ -5574,6 +5584,14 @@ function useTourPlayback({
5574
5584
  }, { devMode: devModeRef.current });
5575
5585
  return;
5576
5586
  }
5587
+ if (serverStateRef.current?.isActive && typeof serverStateRef.current?.runId === "number") {
5588
+ emitSdkDebugLog("[TourClient] Ignoring start request because the server already has an active run", {
5589
+ tourId: tour.id,
5590
+ activeRunId: serverStateRef.current.runId,
5591
+ activeStepIndex: serverStateRef.current.stepIndex
5592
+ }, { devMode: devModeRef.current });
5593
+ return;
5594
+ }
5577
5595
  setPendingTour(null);
5578
5596
  pendingTourRef.current = null;
5579
5597
  let retries = 0;
package/dist/index.mjs CHANGED
@@ -3056,16 +3056,17 @@ function compactTourForTransport(tour) {
3056
3056
 
3057
3057
  // src/utils/tourSessionPersistence.ts
3058
3058
  var ACTIVE_TOUR_SESSION_STORAGE_KEY = "modelnex-active-tour-session";
3059
- var ACTIVE_TOUR_SESSION_VERSION = 1;
3059
+ var ACTIVE_TOUR_SESSION_VERSION = 2;
3060
3060
  var ACTIVE_TOUR_SESSION_MAX_AGE_MS = 10 * 60 * 1e3;
3061
3061
  function canUseSessionStorage2() {
3062
3062
  return typeof window !== "undefined" && typeof window.sessionStorage !== "undefined";
3063
3063
  }
3064
- function persistActiveTourSession(runId) {
3064
+ function persistActiveTourSession(runId, experienceType) {
3065
3065
  if (!canUseSessionStorage2() || !Number.isFinite(runId)) return;
3066
3066
  const session = {
3067
3067
  version: ACTIVE_TOUR_SESSION_VERSION,
3068
3068
  runId,
3069
+ experienceType,
3069
3070
  savedAt: Date.now()
3070
3071
  };
3071
3072
  try {
@@ -3086,7 +3087,7 @@ function readPersistedActiveTourSession() {
3086
3087
  const raw = window.sessionStorage.getItem(ACTIVE_TOUR_SESSION_STORAGE_KEY);
3087
3088
  if (!raw) return null;
3088
3089
  const parsed = JSON.parse(raw);
3089
- const isValid = parsed && parsed.version === ACTIVE_TOUR_SESSION_VERSION && typeof parsed.runId === "number" && Number.isFinite(parsed.runId) && typeof parsed.savedAt === "number" && Number.isFinite(parsed.savedAt);
3090
+ const isValid = parsed && parsed.version === ACTIVE_TOUR_SESSION_VERSION && typeof parsed.runId === "number" && Number.isFinite(parsed.runId) && typeof parsed.experienceType === "string" && typeof parsed.savedAt === "number" && Number.isFinite(parsed.savedAt);
3090
3091
  if (!isValid) {
3091
3092
  clearPersistedActiveTourSession();
3092
3093
  return null;
@@ -3714,9 +3715,12 @@ function useTourPlayback({
3714
3715
  const pendingTourOptionsRef = useRef7(null);
3715
3716
  const showCaptionsRef = useRef7(showCaptions);
3716
3717
  const initialPersistedTourSessionRef = useRef7(readPersistedActiveTourSession());
3717
- const runIdRef = useRef7(initialPersistedTourSessionRef.current?.runId ?? null);
3718
+ const runIdRef = useRef7(
3719
+ initialPersistedTourSessionRef.current?.experienceType === experienceType ? initialPersistedTourSessionRef.current.runId : null
3720
+ );
3718
3721
  const turnIdRef = useRef7(null);
3719
3722
  const startRequestedRef = useRef7(false);
3723
+ const serverStateRef = useRef7(null);
3720
3724
  const playbackOwnerIdRef = useRef7(`playback-owner-${Math.random().toString(36).slice(2, 10)}`);
3721
3725
  const claimedPlaybackOwnerKeyRef = useRef7(null);
3722
3726
  const socketRef = useRef7(null);
@@ -3736,6 +3740,7 @@ function useTourPlayback({
3736
3740
  toursApiBaseRef.current = toursApiBase;
3737
3741
  pendingTourRef.current = pendingTour;
3738
3742
  showCaptionsRef.current = showCaptions;
3743
+ serverStateRef.current = serverState;
3739
3744
  const releasePlaybackOwnership = useCallback6(() => {
3740
3745
  const claimedKey = claimedPlaybackOwnerKeyRef.current;
3741
3746
  if (!claimedKey) return;
@@ -3743,7 +3748,8 @@ function useTourPlayback({
3743
3748
  claimedPlaybackOwnerKeyRef.current = null;
3744
3749
  }, []);
3745
3750
  const emitTourInit = useCallback6((socket, currentWebsiteId, profile) => {
3746
- const persistedRunId = runIdRef.current ?? readPersistedActiveTourSession()?.runId ?? null;
3751
+ const persistedSession = readPersistedActiveTourSession();
3752
+ const persistedRunId = runIdRef.current ?? (persistedSession?.experienceType === experienceTypeRef.current ? persistedSession.runId : null);
3747
3753
  const payload = {};
3748
3754
  if (currentWebsiteId) {
3749
3755
  payload.websiteId = currentWebsiteId;
@@ -3776,6 +3782,7 @@ function useTourPlayback({
3776
3782
  emitTourInit(socket, currentWebsiteId, profile);
3777
3783
  };
3778
3784
  const handleServerState = (payload) => {
3785
+ serverStateRef.current = payload;
3779
3786
  if (typeof payload?.runId === "number") {
3780
3787
  runIdRef.current = payload.runId;
3781
3788
  }
@@ -3783,7 +3790,7 @@ function useTourPlayback({
3783
3790
  turnIdRef.current = payload.turnId ?? null;
3784
3791
  }
3785
3792
  if (payload?.isActive && typeof payload?.runId === "number") {
3786
- persistActiveTourSession(payload.runId);
3793
+ persistActiveTourSession(payload.runId, experienceTypeRef.current);
3787
3794
  } else if (payload?.isActive === false) {
3788
3795
  clearPersistedActiveTourSession();
3789
3796
  }
@@ -4418,7 +4425,7 @@ function useTourPlayback({
4418
4425
  if (isActiveRef.current) return;
4419
4426
  runIdRef.current = typeof tourData.runId === "number" ? tourData.runId : runIdRef.current;
4420
4427
  if (typeof runIdRef.current === "number") {
4421
- persistActiveTourSession(runIdRef.current);
4428
+ persistActiveTourSession(runIdRef.current, experienceTypeRef.current);
4422
4429
  }
4423
4430
  const tour = tourData.tourContext ?? tourRef.current;
4424
4431
  const expType = experienceTypeRef.current;
@@ -4439,6 +4446,9 @@ function useTourPlayback({
4439
4446
  claimedPlaybackOwnerKeyRef.current = ownerKey;
4440
4447
  skipRequestedRef.current = false;
4441
4448
  startRequestedRef.current = false;
4449
+ setPendingTour(null);
4450
+ pendingTourRef.current = null;
4451
+ pendingTourOptionsRef.current = null;
4442
4452
  const total = tourData.totalSteps ?? tour?.steps?.length ?? 0;
4443
4453
  const requestedStepIndex = typeof tourData.currentStepIndex === "number" ? tourData.currentStepIndex : 0;
4444
4454
  const clampedStepIndex = Math.max(0, Math.min(requestedStepIndex, Math.max(0, total - 1)));
@@ -4745,6 +4755,14 @@ function useTourPlayback({
4745
4755
  }, { devMode: devModeRef.current });
4746
4756
  return;
4747
4757
  }
4758
+ if (serverStateRef.current?.isActive && typeof serverStateRef.current?.runId === "number") {
4759
+ emitSdkDebugLog("[TourClient] Ignoring start request because the server already has an active run", {
4760
+ tourId: tour.id,
4761
+ activeRunId: serverStateRef.current.runId,
4762
+ activeStepIndex: serverStateRef.current.stepIndex
4763
+ }, { devMode: devModeRef.current });
4764
+ return;
4765
+ }
4748
4766
  setPendingTour(null);
4749
4767
  pendingTourRef.current = null;
4750
4768
  let retries = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelnex/sdk",
3
- "version": "0.5.49",
3
+ "version": "0.5.51",
4
4
  "description": "React SDK for natural language control of web apps via AI agents",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",