@wvdsh/sdk-js 1.3.27 → 1.3.30

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
@@ -84,6 +84,56 @@ var WavedashEvents = {
84
84
  // src/services/audio.ts
85
85
  import { IFRAME_MESSAGE_TYPE } from "@wvdsh/api";
86
86
 
87
+ // src/utils/logger.ts
88
+ var LOG_LEVEL = {
89
+ DEBUG: 0,
90
+ // Most verbose
91
+ INFO: 1,
92
+ WARN: 2,
93
+ ERROR: 3
94
+ };
95
+ var WavedashLogger = class {
96
+ constructor(logLevel = LOG_LEVEL.WARN) {
97
+ this.logLevel = logLevel;
98
+ }
99
+ setLogLevel(level) {
100
+ this.logLevel = level;
101
+ }
102
+ debug(message, ...args) {
103
+ if (this.logLevel <= LOG_LEVEL.DEBUG) {
104
+ console.log(`[WavedashJS] ${message}`, ...args);
105
+ }
106
+ }
107
+ info(message, ...args) {
108
+ if (this.logLevel <= LOG_LEVEL.INFO) {
109
+ console.log(`[WavedashJS] ${message}`, ...args);
110
+ }
111
+ }
112
+ warn(message, ...args) {
113
+ if (this.logLevel <= LOG_LEVEL.WARN) {
114
+ console.warn(`[WavedashJS] ${message}`, ...args);
115
+ }
116
+ }
117
+ error(message, ...args) {
118
+ if (this.logLevel <= LOG_LEVEL.ERROR) {
119
+ console.error(`[WavedashJS] ${message}`, ...args);
120
+ }
121
+ }
122
+ };
123
+ var logger = new WavedashLogger();
124
+
125
+ // src/utils/parentOrigin.ts
126
+ var _parentOrigin = "";
127
+ function setParentOrigin(origin) {
128
+ _parentOrigin = origin;
129
+ }
130
+ function getParentOrigin() {
131
+ return _parentOrigin;
132
+ }
133
+ function hasParentFrame() {
134
+ return _parentOrigin !== "";
135
+ }
136
+
87
137
  // src/services/manager.ts
88
138
  var WavedashManager = class {
89
139
  constructor(sdk) {
@@ -134,6 +184,12 @@ var AudioManager = class extends WavedashManager {
134
184
  * MUTE_CHANGED broadcast, so `isMuted()` updates independently of this result.
135
185
  */
136
186
  async requestMute(muted) {
187
+ if (!hasParentFrame()) {
188
+ logger.debug(
189
+ "requestMute() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"
190
+ );
191
+ return false;
192
+ }
137
193
  const response = await this.sdk.iframeMessenger.requestFromParent(
138
194
  IFRAME_MESSAGE_TYPE.SET_MUTE,
139
195
  { muted }
@@ -146,6 +202,12 @@ var AudioManager = class extends WavedashManager {
146
202
  * host applied the change.
147
203
  */
148
204
  async toggleMute() {
205
+ if (!hasParentFrame()) {
206
+ logger.debug(
207
+ "toggleMute() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"
208
+ );
209
+ return false;
210
+ }
149
211
  const response = await this.sdk.iframeMessenger.requestFromParent(
150
212
  IFRAME_MESSAGE_TYPE.TOGGLE_MUTE
151
213
  );
@@ -241,7 +303,12 @@ var AudioManager = class extends WavedashManager {
241
303
  };
242
304
  var AudioFrameShim = class {
243
305
  constructor(manager, win) {
244
- this.contexts = /* @__PURE__ */ new Map();
306
+ // Weakly tracked so we never outlive the game's own references: pinning a
307
+ // context here would keep its OS audio stream mixing forever, and games that
308
+ // churn contexts would accumulate streams (a crackle source on weaker audio
309
+ // stacks, e.g. Firefox/Windows). The gain lives exactly as long as its context.
310
+ this.contexts = new WeakRefSet();
311
+ this.contextGains = /* @__PURE__ */ new WeakMap();
245
312
  // Tracked media elements + the game's intended muted value (what it last set).
246
313
  this.elements = new WeakRefSet();
247
314
  this.intendedMuted = /* @__PURE__ */ new WeakMap();
@@ -268,11 +335,19 @@ var AudioFrameShim = class {
268
335
  /** Push the current mute state onto everything this frame is tracking. */
269
336
  applyMute(isMuted) {
270
337
  const target = isMuted ? 0 : 1;
271
- this.contexts.forEach((gain, ctx) => {
338
+ this.contexts.forEach((ctx) => {
339
+ const gain = this.contextGains.get(ctx);
340
+ if (!gain) return;
272
341
  const now = ctx.currentTime;
273
- gain.gain.cancelScheduledValues(now);
274
- gain.gain.setValueAtTime(gain.gain.value, now);
275
- gain.gain.linearRampToValueAtTime(target, now + 0.05);
342
+ const param = gain.gain;
343
+ if (typeof param.cancelAndHoldAtTime === "function") {
344
+ param.cancelAndHoldAtTime(now);
345
+ } else {
346
+ const current = param.value;
347
+ param.cancelScheduledValues(now);
348
+ param.setValueAtTime(current, now);
349
+ }
350
+ param.linearRampToValueAtTime(target, now + 0.05);
276
351
  });
277
352
  const setMutedNative = this.originalMutedDescriptor?.set;
278
353
  if (setMutedNative) {
@@ -348,11 +423,13 @@ var AudioFrameShim = class {
348
423
  this.bindChild(node);
349
424
  } else if (node instanceof HTMLElementCtor) {
350
425
  const el = node;
351
- el.querySelectorAll("audio, video").forEach((m2) => {
352
- this.trackElement(m2);
353
- });
354
- el.querySelectorAll("iframe").forEach((f) => {
355
- this.bindChild(f);
426
+ if (!el.firstElementChild) return;
427
+ el.querySelectorAll("audio, video, iframe").forEach((child) => {
428
+ if (child instanceof HTMLIFrameElementCtor) {
429
+ this.bindChild(child);
430
+ } else {
431
+ this.trackElement(child);
432
+ }
356
433
  });
357
434
  }
358
435
  });
@@ -360,7 +437,9 @@ var AudioFrameShim = class {
360
437
  if (node instanceof HTMLIFrameElementCtor) {
361
438
  this.unbindChild(node);
362
439
  } else if (node instanceof HTMLElementCtor) {
363
- node.querySelectorAll("iframe").forEach((f) => {
440
+ const el = node;
441
+ if (!el.firstElementChild) return;
442
+ el.querySelectorAll("iframe").forEach((f) => {
364
443
  this.unbindChild(f);
365
444
  });
366
445
  }
@@ -465,22 +544,46 @@ var AudioFrameShim = class {
465
544
  return /* @__PURE__ */ ((shim) => class extends Original {
466
545
  constructor(opts) {
467
546
  super(opts);
547
+ const realDestination = this.destination;
468
548
  const masterGain = this.createGain();
469
- masterGain.connect(this.destination);
470
- masterGain.gain.setValueAtTime(
471
- shim.manager.isMuted() ? 0 : 1,
472
- this.currentTime
473
- );
549
+ masterGain.connect(realDestination);
550
+ masterGain.gain.value = shim.manager.isMuted() ? 0 : 1;
551
+ Object.defineProperty(masterGain, "maxChannelCount", {
552
+ configurable: true,
553
+ get: () => realDestination.maxChannelCount
554
+ });
555
+ for (const prop of [
556
+ "channelCount",
557
+ "channelCountMode",
558
+ "channelInterpretation"
559
+ ]) {
560
+ const nativeSet = Object.getOwnPropertyDescriptor(
561
+ shim.win.AudioNode.prototype,
562
+ prop
563
+ )?.set;
564
+ Object.defineProperty(masterGain, prop, {
565
+ configurable: true,
566
+ get: () => realDestination[prop],
567
+ set: (value) => {
568
+ realDestination[prop] = value;
569
+ try {
570
+ nativeSet?.call(masterGain, value);
571
+ } catch {
572
+ }
573
+ }
574
+ });
575
+ }
474
576
  Object.defineProperty(this, "destination", {
475
577
  configurable: true,
476
578
  get() {
477
579
  return masterGain;
478
580
  }
479
581
  });
480
- shim.contexts.set(this, masterGain);
582
+ shim.contexts.add(this);
583
+ shim.contextGains.set(this, masterGain);
481
584
  }
482
585
  close() {
483
- shim.contexts.delete(this);
586
+ shim.contextGains.delete(this);
484
587
  return super.close();
485
588
  }
486
589
  })(this);
@@ -548,6 +651,7 @@ var AudioFrameShim = class {
548
651
  }
549
652
  });
550
653
  this.contexts.clear();
654
+ this.contextGains = /* @__PURE__ */ new WeakMap();
551
655
  this.elements.clear();
552
656
  this.intendedMuted = /* @__PURE__ */ new WeakMap();
553
657
  this.intendedUtteranceVolume = /* @__PURE__ */ new WeakMap();
@@ -645,44 +749,6 @@ function toBlobFromIndexedDBValue(value) {
645
749
  throw new Error("Unrecognized value shape from IndexedDB");
646
750
  }
647
751
 
648
- // src/utils/logger.ts
649
- var LOG_LEVEL = {
650
- DEBUG: 0,
651
- // Most verbose
652
- INFO: 1,
653
- WARN: 2,
654
- ERROR: 3
655
- };
656
- var WavedashLogger = class {
657
- constructor(logLevel = LOG_LEVEL.WARN) {
658
- this.logLevel = logLevel;
659
- }
660
- setLogLevel(level) {
661
- this.logLevel = level;
662
- }
663
- debug(message, ...args) {
664
- if (this.logLevel <= LOG_LEVEL.DEBUG) {
665
- console.log(`[WavedashJS] ${message}`, ...args);
666
- }
667
- }
668
- info(message, ...args) {
669
- if (this.logLevel <= LOG_LEVEL.INFO) {
670
- console.log(`[WavedashJS] ${message}`, ...args);
671
- }
672
- }
673
- warn(message, ...args) {
674
- if (this.logLevel <= LOG_LEVEL.WARN) {
675
- console.warn(`[WavedashJS] ${message}`, ...args);
676
- }
677
- }
678
- error(message, ...args) {
679
- if (this.logLevel <= LOG_LEVEL.ERROR) {
680
- console.error(`[WavedashJS] ${message}`, ...args);
681
- }
682
- }
683
- };
684
- var logger = new WavedashLogger();
685
-
686
752
  // src/services/fileSystem.ts
687
753
  import { api } from "@wvdsh/api";
688
754
  var REMOTE_STORAGE_FOLDER = "userfs";
@@ -1129,6 +1195,7 @@ var FullscreenManager = class extends WavedashManager {
1129
1195
  super(sdk);
1130
1196
  this._isFullscreen = false;
1131
1197
  this.listeners = /* @__PURE__ */ new Set();
1198
+ if (!hasParentFrame()) return;
1132
1199
  this.sdk.iframeMessenger.addEventListener(
1133
1200
  IFRAME_MESSAGE_TYPE2.FULLSCREEN_CHANGED,
1134
1201
  (data) => {
@@ -1150,6 +1217,12 @@ var FullscreenManager = class extends WavedashManager {
1150
1217
  * (e.g. browser rejected for lack of user activation).
1151
1218
  */
1152
1219
  async requestFullscreen(fullscreen) {
1220
+ if (!hasParentFrame()) {
1221
+ logger.debug(
1222
+ "requestFullscreen() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"
1223
+ );
1224
+ return false;
1225
+ }
1153
1226
  const response = await this.sdk.iframeMessenger.requestFromParent(
1154
1227
  IFRAME_MESSAGE_TYPE2.SET_FULLSCREEN,
1155
1228
  { fullscreen }
@@ -1157,6 +1230,12 @@ var FullscreenManager = class extends WavedashManager {
1157
1230
  return response.success;
1158
1231
  }
1159
1232
  async toggleFullscreen() {
1233
+ if (!hasParentFrame()) {
1234
+ logger.debug(
1235
+ "toggleFullscreen() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"
1236
+ );
1237
+ return false;
1238
+ }
1160
1239
  const response = await this.sdk.iframeMessenger.requestFromParent(
1161
1240
  IFRAME_MESSAGE_TYPE2.TOGGLE_FULLSCREEN
1162
1241
  );
@@ -1319,7 +1398,7 @@ var HeartbeatManager = class extends WavedashManager {
1319
1398
  this.gamepadPollInterval = setInterval(() => {
1320
1399
  this.pollGamepads();
1321
1400
  }, this.GAMEPAD_POLL_INTERVAL_MS);
1322
- this.deviceFingerprintReady = this.sdk.iframeMessenger.requestFromParent(IFRAME_MESSAGE_TYPE3.GET_DEVICE_FINGERPRINT).then((fingerprint) => {
1401
+ this.deviceFingerprintReady = !hasParentFrame() ? Promise.resolve() : this.sdk.iframeMessenger.requestFromParent(IFRAME_MESSAGE_TYPE3.GET_DEVICE_FINGERPRINT).then((fingerprint) => {
1323
1402
  this.deviceFingerprint = fingerprint;
1324
1403
  }).catch(() => {
1325
1404
  });
@@ -1868,6 +1947,11 @@ var _LobbyManager = class _LobbyManager extends WavedashManager {
1868
1947
  if (!this.lobbyId) {
1869
1948
  throw new Error("User is not in a lobby");
1870
1949
  }
1950
+ if (!hasParentFrame()) {
1951
+ throw new Error(
1952
+ "Lobby invite links are not available outside a Wavedash parent frame (e.g. `wavedash dev`)"
1953
+ );
1954
+ }
1871
1955
  const inviteLink = await this.sdk.iframeMessenger.requestFromParent(
1872
1956
  IFRAME_MESSAGE_TYPE4.GET_LOBBY_INVITE_LINK,
1873
1957
  { lobbyId: this.lobbyId, copyToClipboard }
@@ -2133,6 +2217,7 @@ var OverlayManager = class extends WavedashManager {
2133
2217
  this.toggleOverlay();
2134
2218
  }
2135
2219
  };
2220
+ if (!hasParentFrame()) return;
2136
2221
  this.sdk.iframeMessenger.addEventListener(
2137
2222
  IFRAME_MESSAGE_TYPE5.TAKE_FOCUS,
2138
2223
  takeFocus
@@ -3463,7 +3548,76 @@ _P2PManager.MEMORY_WARNING_THRESHOLD_BYTES = 128 * 1024 * 1024;
3463
3548
  var P2PManager = _P2PManager;
3464
3549
 
3465
3550
  // src/services/paidContent.ts
3466
- import { IFRAME_MESSAGE_TYPE as IFRAME_MESSAGE_TYPE6 } from "@wvdsh/api";
3551
+ import { api as api7, IFRAME_MESSAGE_TYPE as IFRAME_MESSAGE_TYPE6 } from "@wvdsh/api";
3552
+
3553
+ // src/utils/devPaywall.ts
3554
+ var Z_INDEX = 2147483647;
3555
+ function showDevPaywall(contentIdentifier) {
3556
+ if (typeof document === "undefined") return Promise.resolve(false);
3557
+ return new Promise((resolve) => {
3558
+ const overlay = document.createElement("div");
3559
+ overlay.style.cssText = "position:fixed;inset:0;z-index:" + Z_INDEX + ";display:flex;align-items:center;justify-content:center;background:rgba(8,10,18,0.72);font:14px ui-sans-serif,system-ui,sans-serif;color:#e2e8f0";
3560
+ const card = document.createElement("div");
3561
+ card.style.cssText = "max-width:420px;width:calc(100% - 48px);background:#11151f;border:1px solid #2a3344;border-radius:12px;padding:24px;box-shadow:0 20px 60px rgba(0,0,0,0.5);box-sizing:border-box";
3562
+ const badge = document.createElement("p");
3563
+ badge.textContent = "wavedash dev \u2014 simulated purchase";
3564
+ badge.style.cssText = "margin:0 0 12px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:#7c8aa5";
3565
+ const title = document.createElement("p");
3566
+ title.textContent = "Unlock paid content?";
3567
+ title.style.cssText = "margin:0 0 8px;font-size:18px;font-weight:600;color:#f1f5f9";
3568
+ const body = document.createElement("p");
3569
+ body.style.cssText = "margin:0 0 20px;line-height:1.5;color:#cbd5e1";
3570
+ body.append(
3571
+ document.createTextNode("This game is requesting purchase of \u201C")
3572
+ );
3573
+ const id = document.createElement("code");
3574
+ id.textContent = contentIdentifier;
3575
+ id.style.cssText = "background:#1c2433;border-radius:4px;padding:1px 6px;color:#93c5fd";
3576
+ body.append(
3577
+ id,
3578
+ document.createTextNode(
3579
+ "\u201D. No real payment happens in dev \u2014 simulate the outcome to test your flow."
3580
+ )
3581
+ );
3582
+ const buttons = document.createElement("div");
3583
+ buttons.style.cssText = "display:flex;gap:12px;justify-content:flex-end";
3584
+ const baseBtn = "border-radius:8px;padding:9px 18px;font-size:14px;font-weight:600;cursor:pointer;border:1px solid transparent";
3585
+ const cancel = document.createElement("button");
3586
+ cancel.type = "button";
3587
+ cancel.textContent = "Cancel";
3588
+ cancel.style.cssText = baseBtn + ";background:transparent;border-color:#374151;color:#cbd5e1";
3589
+ const buy = document.createElement("button");
3590
+ buy.type = "button";
3591
+ buy.textContent = "Simulate purchase";
3592
+ buy.style.cssText = baseBtn + ";background:#2563eb;color:#fff";
3593
+ buttons.append(cancel, buy);
3594
+ card.append(badge, title, body, buttons);
3595
+ overlay.append(card);
3596
+ let settled = false;
3597
+ const finish = (purchased) => {
3598
+ if (settled) return;
3599
+ settled = true;
3600
+ document.removeEventListener("keydown", onKeyDown, true);
3601
+ overlay.remove();
3602
+ resolve(purchased);
3603
+ };
3604
+ const onKeyDown = (event) => {
3605
+ if (event.key === "Escape") {
3606
+ event.preventDefault();
3607
+ finish(false);
3608
+ }
3609
+ };
3610
+ cancel.addEventListener("click", () => finish(false));
3611
+ buy.addEventListener("click", () => finish(true));
3612
+ overlay.addEventListener("click", (event) => {
3613
+ if (event.target === overlay) finish(false);
3614
+ });
3615
+ document.addEventListener("keydown", onKeyDown, true);
3616
+ document.body.append(overlay);
3617
+ });
3618
+ }
3619
+
3620
+ // src/services/paidContent.ts
3467
3621
  var PAYWALL_TIMEOUT_MS = 10 * 60 * 1e3;
3468
3622
  function decodeJwtPayload(jwt) {
3469
3623
  try {
@@ -3505,6 +3659,22 @@ var PaidContentManager = class extends WavedashManager {
3505
3659
  }
3506
3660
  this.paywallOpen = true;
3507
3661
  this.restorePointerLock = suspendPointerLock();
3662
+ if (!hasParentFrame()) {
3663
+ let purchased;
3664
+ try {
3665
+ purchased = await showDevPaywall(contentIdentifier);
3666
+ } finally {
3667
+ this.restorePointerLock?.();
3668
+ this.restorePointerLock = void 0;
3669
+ this.paywallOpen = false;
3670
+ }
3671
+ if (!purchased) return false;
3672
+ await this.sdk.convexClient.mutation(api7.sdk.paidContent.mockPurchase, {
3673
+ contentIdentifier
3674
+ });
3675
+ await this.sdk.ensureGameplayJwt(true);
3676
+ return true;
3677
+ }
3508
3678
  let response;
3509
3679
  try {
3510
3680
  response = await this.sdk.iframeMessenger.requestFromParent(
@@ -3531,7 +3701,7 @@ var PaidContentManager = class extends WavedashManager {
3531
3701
  };
3532
3702
 
3533
3703
  // src/services/stats.ts
3534
- import { api as api7 } from "@wvdsh/api";
3704
+ import { api as api8 } from "@wvdsh/api";
3535
3705
  import throttle2 from "lodash.throttle";
3536
3706
  var STORE_THROTTLE_MS = 1e3;
3537
3707
  var StatsManager = class extends WavedashManager {
@@ -3589,7 +3759,7 @@ var StatsManager = class extends WavedashManager {
3589
3759
  subscribe() {
3590
3760
  this.subscriptions.push(
3591
3761
  this.sdk.convexClient.onUpdate(
3592
- api7.sdk.gameAchievements.listStatIdentifiers,
3762
+ api8.sdk.gameAchievements.listStatIdentifiers,
3593
3763
  {},
3594
3764
  (ids) => {
3595
3765
  this.knownStatIds = new Set(ids);
@@ -3599,7 +3769,7 @@ var StatsManager = class extends WavedashManager {
3599
3769
  }
3600
3770
  ),
3601
3771
  this.sdk.convexClient.onUpdate(
3602
- api7.sdk.gameAchievements.listAchievementIdentifiers,
3772
+ api8.sdk.gameAchievements.listAchievementIdentifiers,
3603
3773
  {},
3604
3774
  (ids) => {
3605
3775
  this.knownAchievementIds = new Set(ids);
@@ -3609,7 +3779,7 @@ var StatsManager = class extends WavedashManager {
3609
3779
  }
3610
3780
  ),
3611
3781
  this.sdk.convexClient.onUpdate(
3612
- api7.sdk.gameAchievements.getMyAchievementsForGame,
3782
+ api8.sdk.gameAchievements.getMyAchievementsForGame,
3613
3783
  {},
3614
3784
  (achievements) => {
3615
3785
  this.loaded.achievements = true;
@@ -3625,7 +3795,7 @@ var StatsManager = class extends WavedashManager {
3625
3795
  }
3626
3796
  async requestStats() {
3627
3797
  const newStats = await this.sdk.convexClient.query(
3628
- api7.sdk.gameAchievements.getMyStatsForGame,
3798
+ api8.sdk.gameAchievements.getMyStatsForGame,
3629
3799
  {}
3630
3800
  );
3631
3801
  this.loaded.stats = true;
@@ -3656,11 +3826,11 @@ var StatsManager = class extends WavedashManager {
3656
3826
  if (!pending) return;
3657
3827
  this.inFlightPersist = Promise.all([
3658
3828
  pending.stats.length > 0 ? this.sdk.convexClient.mutation(
3659
- api7.sdk.gameAchievements.setUserGameStats,
3829
+ api8.sdk.gameAchievements.setUserGameStats,
3660
3830
  { stats: pending.stats }
3661
3831
  ) : Promise.resolve(),
3662
3832
  pending.achievements.length > 0 ? this.sdk.convexClient.mutation(
3663
- api7.sdk.gameAchievements.setUserGameAchievements,
3833
+ api8.sdk.gameAchievements.setUserGameAchievements,
3664
3834
  { achievements: pending.achievements }
3665
3835
  ) : Promise.resolve()
3666
3836
  ]).then(() => {
@@ -3737,14 +3907,14 @@ var StatsManager = class extends WavedashManager {
3737
3907
  };
3738
3908
 
3739
3909
  // src/services/ugc.ts
3740
- import { api as api8 } from "@wvdsh/api";
3910
+ import { api as api9 } from "@wvdsh/api";
3741
3911
  var UGCManager = class extends WavedashManager {
3742
3912
  constructor(sdk) {
3743
3913
  super(sdk);
3744
3914
  }
3745
3915
  async createUGCItem(ugcType, title, description, visibility, filePath) {
3746
3916
  const { ugcId, uploadUrl } = await this.sdk.convexClient.mutation(
3747
- api8.sdk.userGeneratedContent.createUGCItem,
3917
+ api9.sdk.userGeneratedContent.createUGCItem,
3748
3918
  {
3749
3919
  ugcType,
3750
3920
  title,
@@ -3771,7 +3941,7 @@ var UGCManager = class extends WavedashManager {
3771
3941
  async updateUGCItem(ugcId, updates = {}) {
3772
3942
  const { title, description, visibility, filePath } = updates;
3773
3943
  const { uploadUrl } = await this.sdk.convexClient.mutation(
3774
- api8.sdk.userGeneratedContent.updateUGCItem,
3944
+ api9.sdk.userGeneratedContent.updateUGCItem,
3775
3945
  {
3776
3946
  ugcId,
3777
3947
  title,
@@ -3797,14 +3967,14 @@ var UGCManager = class extends WavedashManager {
3797
3967
  }
3798
3968
  async deleteUGCItem(ugcId) {
3799
3969
  await this.sdk.convexClient.mutation(
3800
- api8.sdk.userGeneratedContent.deleteUGCItem,
3970
+ api9.sdk.userGeneratedContent.deleteUGCItem,
3801
3971
  { ugcId }
3802
3972
  );
3803
3973
  return ugcId;
3804
3974
  }
3805
3975
  async downloadUGCItem(ugcId, filePath) {
3806
3976
  const downloadUrl = await this.sdk.convexClient.query(
3807
- api8.sdk.userGeneratedContent.getUGCItemDownloadUrl,
3977
+ api9.sdk.userGeneratedContent.getUGCItemDownloadUrl,
3808
3978
  { ugcId }
3809
3979
  );
3810
3980
  try {
@@ -3819,7 +3989,7 @@ var UGCManager = class extends WavedashManager {
3819
3989
  const { createdBy, ugcType, titleSearch, numItems, continueCursor } = args;
3820
3990
  const filters = createdBy !== void 0 || ugcType !== void 0 || titleSearch !== void 0 ? { createdBy, ugcType, titleSearch } : void 0;
3821
3991
  return await this.sdk.convexClient.query(
3822
- api8.sdk.userGeneratedContent.listUGCItems,
3992
+ api9.sdk.userGeneratedContent.listUGCItems,
3823
3993
  {
3824
3994
  filters,
3825
3995
  numItems,
@@ -3829,15 +3999,6 @@ var UGCManager = class extends WavedashManager {
3829
3999
  }
3830
4000
  };
3831
4001
 
3832
- // src/utils/parentOrigin.ts
3833
- var _parentOrigin = "";
3834
- function setParentOrigin(origin) {
3835
- _parentOrigin = origin;
3836
- }
3837
- function getParentOrigin() {
3838
- return _parentOrigin;
3839
- }
3840
-
3841
4002
  // src/utils/iframeMessenger.ts
3842
4003
  var RESPONSE_TIMEOUT_MS = 15e3;
3843
4004
  var IFrameMessenger = class {
@@ -5281,6 +5442,7 @@ var WavedashSDK = class extends EventTarget {
5281
5442
  const refreshQuery = new URLSearchParams({
5282
5443
  [UrlParams.Caller]: PlayRouteCaller.Wavedash
5283
5444
  });
5445
+ if (forceRefresh) refreshQuery.set("fresh", "1");
5284
5446
  const refreshPath = `/auth/refresh?${refreshQuery.toString()}`;
5285
5447
  const response = await fetch(refreshPath, {
5286
5448
  method: "POST",