@sylphx/sdk 0.8.0 → 0.10.0

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.
@@ -606,10 +606,6 @@ var ConsentContext = createContext(null);
606
606
  function useConsentContext() {
607
607
  return useRequiredContext(ConsentContext, "Consent");
608
608
  }
609
- var StorageContext = createContext(null);
610
- function useStorageContext() {
611
- return useRequiredContext(StorageContext, "Storage");
612
- }
613
609
  var NewsletterContext = createContext(null);
614
610
  function useNewsletterContext() {
615
611
  return useRequiredContext(NewsletterContext, "Newsletter");
@@ -11139,78 +11135,13 @@ function useTaskRun(runId, options) {
11139
11135
  };
11140
11136
  }
11141
11137
 
11142
- // src/react/hooks/use-upload.ts
11143
- import { useCallback as useCallback25, useRef as useRef9, useState as useState29 } from "react";
11144
- function useUpload() {
11145
- const ctx = useStorageContext();
11146
- const [progress, setProgress] = useState29(0);
11147
- const [isUploading, setIsUploading] = useState29(false);
11148
- const [error, setError] = useState29(null);
11149
- const abortControllerRef = useRef9(null);
11150
- const reset = useCallback25(() => {
11151
- setProgress(0);
11152
- setIsUploading(false);
11153
- setError(null);
11154
- abortControllerRef.current = null;
11155
- }, []);
11156
- const cancel = useCallback25(() => {
11157
- abortControllerRef.current?.abort();
11158
- abortControllerRef.current = null;
11159
- setIsUploading(false);
11160
- }, []);
11161
- const upload = useCallback25(
11162
- async (file, options) => {
11163
- const controller = new AbortController();
11164
- abortControllerRef.current = controller;
11165
- setIsUploading(true);
11166
- setProgress(0);
11167
- setError(null);
11168
- try {
11169
- const url = await ctx.upload(file, {
11170
- path: options?.path,
11171
- signal: controller.signal,
11172
- onProgress: (event) => {
11173
- const pct = event.progress;
11174
- setProgress(pct);
11175
- options?.onProgress?.(pct);
11176
- }
11177
- });
11178
- setProgress(100);
11179
- const key = options?.path ?? decodeURIComponent(new URL(url).pathname.split("/").pop() ?? file.name);
11180
- return { url, key };
11181
- } catch (err) {
11182
- if (err instanceof DOMException && err.name === "AbortError") {
11183
- throw err;
11184
- }
11185
- const uploadError = err instanceof SylphxError ? err : new SylphxError(err instanceof Error ? err.message : "Upload failed", {
11186
- code: "INTERNAL_SERVER_ERROR"
11187
- });
11188
- setError(uploadError);
11189
- throw uploadError;
11190
- } finally {
11191
- abortControllerRef.current = null;
11192
- setIsUploading(false);
11193
- }
11194
- },
11195
- [ctx]
11196
- );
11197
- return {
11198
- upload,
11199
- progress,
11200
- isUploading,
11201
- error,
11202
- cancel,
11203
- reset
11204
- };
11205
- }
11206
-
11207
11138
  // src/react/monitoring-hooks.ts
11208
- import { useCallback as useCallback26, useEffect as useEffect22, useRef as useRef10 } from "react";
11139
+ import { useCallback as useCallback25, useEffect as useEffect22, useRef as useRef9 } from "react";
11209
11140
  function useErrorTracking() {
11210
11141
  const ctx = useMonitoringContext();
11211
- const breadcrumbsRef = useRef10([]);
11212
- const routeRef = useRef10(null);
11213
- const captureException = useCallback26(
11142
+ const breadcrumbsRef = useRef9([]);
11143
+ const routeRef = useRef9(null);
11144
+ const captureException = useCallback25(
11214
11145
  async (error, options = {}) => {
11215
11146
  try {
11216
11147
  const result = await ctx.captureException(error, {
@@ -11233,7 +11164,7 @@ function useErrorTracking() {
11233
11164
  },
11234
11165
  [ctx]
11235
11166
  );
11236
- const captureMessage = useCallback26(
11167
+ const captureMessage = useCallback25(
11237
11168
  async (message, options = {}) => {
11238
11169
  try {
11239
11170
  const result = await ctx.captureMessage(message, {
@@ -11250,7 +11181,7 @@ function useErrorTracking() {
11250
11181
  },
11251
11182
  [ctx]
11252
11183
  );
11253
- const addBreadcrumb2 = useCallback26((breadcrumb) => {
11184
+ const addBreadcrumb2 = useCallback25((breadcrumb) => {
11254
11185
  breadcrumbsRef.current.push({
11255
11186
  ...breadcrumb,
11256
11187
  timestamp: breadcrumb.timestamp ?? Date.now()
@@ -11259,7 +11190,7 @@ function useErrorTracking() {
11259
11190
  breadcrumbsRef.current = breadcrumbsRef.current.slice(-100);
11260
11191
  }
11261
11192
  }, []);
11262
- const setRoute = useCallback26(
11193
+ const setRoute = useCallback25(
11263
11194
  (route) => {
11264
11195
  routeRef.current = route;
11265
11196
  addBreadcrumb2({
@@ -11279,7 +11210,7 @@ function useErrorTracking() {
11279
11210
  }
11280
11211
  function useErrorBoundary(options = {}) {
11281
11212
  const { captureException } = useErrorTracking();
11282
- const handleError = useCallback26(
11213
+ const handleError = useCallback25(
11283
11214
  async (error, errorInfo) => {
11284
11215
  const eventId = await captureException(error, {
11285
11216
  tags: {
@@ -11339,17 +11270,17 @@ function useGlobalErrorHandler(options = {}) {
11339
11270
  }
11340
11271
 
11341
11272
  // src/react/newsletter-hooks.ts
11342
- import { useCallback as useCallback27, useState as useState30 } from "react";
11273
+ import { useCallback as useCallback26, useState as useState29 } from "react";
11343
11274
  function useNewsletter() {
11344
11275
  const ctx = useNewsletterContext();
11345
- const [isLoading, setIsLoading] = useState30(false);
11346
- const [success, setSuccess] = useState30(false);
11347
- const [error, setError] = useState30(null);
11348
- const reset = useCallback27(() => {
11276
+ const [isLoading, setIsLoading] = useState29(false);
11277
+ const [success, setSuccess] = useState29(false);
11278
+ const [error, setError] = useState29(null);
11279
+ const reset = useCallback26(() => {
11349
11280
  setSuccess(false);
11350
11281
  setError(null);
11351
11282
  }, []);
11352
- const subscribe = useCallback27(
11283
+ const subscribe = useCallback26(
11353
11284
  async (options) => {
11354
11285
  setIsLoading(true);
11355
11286
  setError(null);
@@ -11368,7 +11299,7 @@ function useNewsletter() {
11368
11299
  },
11369
11300
  [ctx]
11370
11301
  );
11371
- const verify = useCallback27(
11302
+ const verify = useCallback26(
11372
11303
  async (token) => {
11373
11304
  setIsLoading(true);
11374
11305
  setError(null);
@@ -11386,7 +11317,7 @@ function useNewsletter() {
11386
11317
  },
11387
11318
  [ctx]
11388
11319
  );
11389
- const unsubscribe = useCallback27(
11320
+ const unsubscribe = useCallback26(
11390
11321
  async (email, token) => {
11391
11322
  setIsLoading(true);
11392
11323
  setError(null);
@@ -11404,7 +11335,7 @@ function useNewsletter() {
11404
11335
  },
11405
11336
  [ctx]
11406
11337
  );
11407
- const resendVerification = useCallback27(
11338
+ const resendVerification = useCallback26(
11408
11339
  async (email) => {
11409
11340
  setIsLoading(true);
11410
11341
  setError(null);
@@ -11422,7 +11353,7 @@ function useNewsletter() {
11422
11353
  },
11423
11354
  [ctx]
11424
11355
  );
11425
- const getUnsubscribeInfo = useCallback27(
11356
+ const getUnsubscribeInfo = useCallback26(
11426
11357
  async (token) => {
11427
11358
  try {
11428
11359
  return await ctx.getUnsubscribeInfo(token);
@@ -11434,7 +11365,7 @@ function useNewsletter() {
11434
11365
  },
11435
11366
  [ctx]
11436
11367
  );
11437
- const updatePreferences = useCallback27(
11368
+ const updatePreferences = useCallback26(
11438
11369
  async (email, preferences) => {
11439
11370
  setIsLoading(true);
11440
11371
  setError(null);
@@ -11452,7 +11383,7 @@ function useNewsletter() {
11452
11383
  },
11453
11384
  [ctx]
11454
11385
  );
11455
- const getPreferences = useCallback27(
11386
+ const getPreferences = useCallback26(
11456
11387
  async (email) => {
11457
11388
  try {
11458
11389
  return await ctx.getPreferences(email);
@@ -11480,20 +11411,20 @@ function useNewsletter() {
11480
11411
  }
11481
11412
  function useSubscriberForm(options = {}) {
11482
11413
  const ctx = useNewsletterContext();
11483
- const [email, setEmail] = useState30("");
11484
- const [preferences, setPreferences] = useState30(options.preferences || {});
11485
- const [isLoading, setIsLoading] = useState30(false);
11486
- const [success, setSuccess] = useState30(false);
11487
- const [requiresVerification, setRequiresVerification] = useState30(false);
11488
- const [alreadySubscribed, setAlreadySubscribed] = useState30(false);
11489
- const [error, setError] = useState30(null);
11490
- const togglePreference = useCallback27((pref) => {
11414
+ const [email, setEmail] = useState29("");
11415
+ const [preferences, setPreferences] = useState29(options.preferences || {});
11416
+ const [isLoading, setIsLoading] = useState29(false);
11417
+ const [success, setSuccess] = useState29(false);
11418
+ const [requiresVerification, setRequiresVerification] = useState29(false);
11419
+ const [alreadySubscribed, setAlreadySubscribed] = useState29(false);
11420
+ const [error, setError] = useState29(null);
11421
+ const togglePreference = useCallback26((pref) => {
11491
11422
  setPreferences((prev) => ({ ...prev, [pref]: !prev[pref] }));
11492
11423
  }, []);
11493
- const setPreference = useCallback27((pref, value) => {
11424
+ const setPreference = useCallback26((pref, value) => {
11494
11425
  setPreferences((prev) => ({ ...prev, [pref]: value }));
11495
11426
  }, []);
11496
- const reset = useCallback27(() => {
11427
+ const reset = useCallback26(() => {
11497
11428
  setEmail("");
11498
11429
  setPreferences(options.preferences || {});
11499
11430
  setSuccess(false);
@@ -11501,7 +11432,7 @@ function useSubscriberForm(options = {}) {
11501
11432
  setAlreadySubscribed(false);
11502
11433
  setError(null);
11503
11434
  }, [options.preferences]);
11504
- const submit = useCallback27(
11435
+ const submit = useCallback26(
11505
11436
  async (e2) => {
11506
11437
  e2?.preventDefault();
11507
11438
  if (!email) {
@@ -11598,7 +11529,7 @@ function AuthLoading({ children, loading = null }) {
11598
11529
 
11599
11530
  // src/react/provider.tsx
11600
11531
  import { QueryClient, QueryClientProvider, useQuery as useQuery5 } from "@tanstack/react-query";
11601
- import { useCallback as useCallback28, useEffect as useEffect23, useMemo as useMemo9, useRef as useRef11, useState as useState31 } from "react";
11532
+ import { useCallback as useCallback27, useEffect as useEffect23, useMemo as useMemo9, useRef as useRef10, useState as useState30 } from "react";
11602
11533
 
11603
11534
  // src/consent.ts
11604
11535
  async function linkAnonymousConsents(config2, input) {
@@ -12319,101 +12250,6 @@ function createNewsletterValue(config2) {
12319
12250
  };
12320
12251
  }
12321
12252
 
12322
- // src/react/context-values/storage.ts
12323
- async function uploadWithPresignedUrl(file, presignedUrl, onProgress) {
12324
- return new Promise((resolve, reject) => {
12325
- const xhr = new XMLHttpRequest();
12326
- if (onProgress) {
12327
- xhr.upload.addEventListener("progress", (e2) => {
12328
- if (e2.lengthComputable) {
12329
- onProgress({
12330
- loaded: e2.loaded,
12331
- total: e2.total,
12332
- progress: Math.round(e2.loaded / e2.total * 100)
12333
- });
12334
- }
12335
- });
12336
- }
12337
- xhr.addEventListener("load", () => {
12338
- if (xhr.status >= 200 && xhr.status < 300) {
12339
- resolve();
12340
- } else {
12341
- reject(new Error(`Upload failed with status ${xhr.status}`));
12342
- }
12343
- });
12344
- xhr.addEventListener("error", () => reject(new Error("Upload network error")));
12345
- xhr.addEventListener("abort", () => reject(new Error("Upload aborted")));
12346
- xhr.open("PUT", presignedUrl);
12347
- xhr.setRequestHeader("Content-Type", file.type || "application/octet-stream");
12348
- xhr.send(file);
12349
- });
12350
- }
12351
- function createStorageValue(config2) {
12352
- const { platformUrl, appId, userId } = config2;
12353
- const handleUpload = async (file, type, options) => {
12354
- const clientPayload = JSON.stringify({
12355
- appId,
12356
- userId,
12357
- type,
12358
- folder: options?.path
12359
- });
12360
- const tokenRes = await fetch(`${platformUrl}/api/v1/storage/upload`, {
12361
- method: "POST",
12362
- headers: { "Content-Type": "application/json" },
12363
- body: JSON.stringify({
12364
- type: "generate-token",
12365
- pathname: file.name,
12366
- clientPayload
12367
- })
12368
- });
12369
- if (!tokenRes.ok) {
12370
- const err = await tokenRes.json().catch(() => ({ error: "Unknown error" }));
12371
- throw new Error(err.error ?? "Failed to get upload token");
12372
- }
12373
- const { presignedUrl, url, storageKey, tokenPayload } = await tokenRes.json();
12374
- await uploadWithPresignedUrl(file, presignedUrl, options?.onProgress);
12375
- const completeRes = await fetch(`${platformUrl}/api/v1/storage/upload`, {
12376
- method: "POST",
12377
- headers: { "Content-Type": "application/json" },
12378
- body: JSON.stringify({
12379
- type: "upload-complete",
12380
- url,
12381
- pathname: storageKey,
12382
- tokenPayload
12383
- })
12384
- });
12385
- if (!completeRes.ok) {
12386
- const err = await completeRes.json().catch(() => ({ error: "Unknown error" }));
12387
- throw new Error(err.error ?? "Failed to complete upload");
12388
- }
12389
- const result = await completeRes.json();
12390
- return result.url;
12391
- };
12392
- return {
12393
- upload: async (file, options) => {
12394
- return handleUpload(file, "file", options);
12395
- },
12396
- uploadAvatar: async (file, options) => {
12397
- if (!userId) {
12398
- throw new Error("Must be logged in to upload avatar");
12399
- }
12400
- return handleUpload(file, "avatar", options);
12401
- },
12402
- deleteFile: async (fileId) => {
12403
- const res = await fetch(`${platformUrl}/api/v1/storage/${fileId}`, {
12404
- method: "DELETE"
12405
- });
12406
- if (!res.ok) throw new Error("Failed to delete file");
12407
- },
12408
- getUrl: async (fileId) => {
12409
- const res = await fetch(`${platformUrl}/api/v1/storage/${fileId}`);
12410
- if (!res.ok) throw new Error("Failed to get file URL");
12411
- const data = await res.json();
12412
- return data.file.url;
12413
- }
12414
- };
12415
- }
12416
-
12417
12253
  // src/react/context-values/webhooks.ts
12418
12254
  function createWebhooksValue(config2) {
12419
12255
  const { api } = config2;
@@ -12603,11 +12439,11 @@ function generateAnonymousId() {
12603
12439
  return v2.toString(16);
12604
12440
  });
12605
12441
  }
12606
- function getOrCreateAnonymousId(storage) {
12607
- let anonymousId = storage.get(STORAGE_KEYS.ANONYMOUS_ID);
12442
+ function getOrCreateAnonymousId(storage2) {
12443
+ let anonymousId = storage2.get(STORAGE_KEYS.ANONYMOUS_ID);
12608
12444
  if (!anonymousId) {
12609
12445
  anonymousId = generateAnonymousId();
12610
- storage.set(STORAGE_KEYS.ANONYMOUS_ID, anonymousId);
12446
+ storage2.set(STORAGE_KEYS.ANONYMOUS_ID, anonymousId);
12611
12447
  }
12612
12448
  return anonymousId;
12613
12449
  }
@@ -12623,29 +12459,29 @@ function captureClickIdsFromUrl() {
12623
12459
  if (ttclid) clickIds.ttclid = ttclid;
12624
12460
  return clickIds;
12625
12461
  }
12626
- function getStoredClickIds(storage) {
12627
- const capturedAtStr = storage.get(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12462
+ function getStoredClickIds(storage2) {
12463
+ const capturedAtStr = storage2.get(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12628
12464
  if (!capturedAtStr) return null;
12629
12465
  const capturedAt = Number.parseInt(capturedAtStr, 10);
12630
12466
  if (Number.isNaN(capturedAt) || Date.now() - capturedAt > CLICK_ID_EXPIRY_MS) {
12631
- storage.remove(STORAGE_KEYS.CLICK_IDS);
12632
- storage.remove(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12467
+ storage2.remove(STORAGE_KEYS.CLICK_IDS);
12468
+ storage2.remove(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12633
12469
  return null;
12634
12470
  }
12635
- return storage.getJSON(STORAGE_KEYS.CLICK_IDS);
12471
+ return storage2.getJSON(STORAGE_KEYS.CLICK_IDS);
12636
12472
  }
12637
- function storeClickIds(storage, clickIds) {
12473
+ function storeClickIds(storage2, clickIds) {
12638
12474
  if (Object.keys(clickIds).length === 0) return;
12639
- const existing = getStoredClickIds(storage) || {};
12475
+ const existing = getStoredClickIds(storage2) || {};
12640
12476
  const merged = { ...existing, ...clickIds };
12641
- storage.setJSON(STORAGE_KEYS.CLICK_IDS, merged);
12642
- storage.set(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT, Date.now().toString());
12477
+ storage2.setJSON(STORAGE_KEYS.CLICK_IDS, merged);
12478
+ storage2.set(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT, Date.now().toString());
12643
12479
  }
12644
- function autoCaptureClickIds(storage) {
12480
+ function autoCaptureClickIds(storage2) {
12645
12481
  const urlClickIds = captureClickIdsFromUrl();
12646
- const storedClickIds = getStoredClickIds(storage) || {};
12482
+ const storedClickIds = getStoredClickIds(storage2) || {};
12647
12483
  if (Object.keys(urlClickIds).length > 0) {
12648
- storeClickIds(storage, urlClickIds);
12484
+ storeClickIds(storage2, urlClickIds);
12649
12485
  return { ...storedClickIds, ...urlClickIds };
12650
12486
  }
12651
12487
  return storedClickIds;
@@ -12828,7 +12664,7 @@ function SylphxProvider({
12828
12664
  config: config2,
12829
12665
  authPrefix = "/auth"
12830
12666
  }) {
12831
- const [queryClient] = useState31(
12667
+ const [queryClient] = useState30(
12832
12668
  () => new QueryClient({
12833
12669
  defaultOptions: {
12834
12670
  queries: {
@@ -12875,20 +12711,20 @@ function SylphxProviderInner({
12875
12711
  return parts.length === 4 && /^[a-z0-9]{12}$/.test(parts[2] ?? "") ? parts[2] : void 0;
12876
12712
  })();
12877
12713
  const platformUrl = resolvedRef ? `https://${resolvedRef}.${DEFAULT_SDK_API_HOST}` : providedPlatformUrl?.trim() || `https://${DEFAULT_SDK_API_HOST}`;
12878
- const storage = useMemo9(() => new SylphxStorage(appId), [appId]);
12879
- const [anonymousId, setAnonymousId] = useState31("");
12714
+ const storage2 = useMemo9(() => new SylphxStorage(appId), [appId]);
12715
+ const [anonymousId, setAnonymousId] = useState30("");
12880
12716
  useEffect23(() => {
12881
- setAnonymousId(getOrCreateAnonymousId(storage));
12882
- }, [storage]);
12883
- const [clickIds, setClickIds] = useState31({});
12884
- const hasInitializedClickIds = useRef11(false);
12717
+ setAnonymousId(getOrCreateAnonymousId(storage2));
12718
+ }, [storage2]);
12719
+ const [clickIds, setClickIds] = useState30({});
12720
+ const hasInitializedClickIds = useRef10(false);
12885
12721
  useEffect23(() => {
12886
12722
  if (hasInitializedClickIds.current) return;
12887
12723
  hasInitializedClickIds.current = true;
12888
- const captured = autoCaptureClickIds(storage);
12724
+ const captured = autoCaptureClickIds(storage2);
12889
12725
  setClickIds(captured);
12890
- }, [storage]);
12891
- const [authState, setAuthState] = useState31({
12726
+ }, [storage2]);
12727
+ const [authState, setAuthState] = useState30({
12892
12728
  isLoaded: false,
12893
12729
  isSignedIn: false,
12894
12730
  user: null,
@@ -12915,7 +12751,7 @@ function SylphxProviderInner({
12915
12751
  setAuthState((prev) => ({ ...prev, isLoaded: true }));
12916
12752
  }
12917
12753
  }, [appId]);
12918
- const authStateRef = useRef11(authState);
12754
+ const authStateRef = useRef10(authState);
12919
12755
  useEffect23(() => {
12920
12756
  authStateRef.current = authState;
12921
12757
  }, [authState]);
@@ -12940,7 +12776,7 @@ function SylphxProviderInner({
12940
12776
  tokenManager.clear();
12941
12777
  }
12942
12778
  }, [authState.isSignedIn, tokenManager]);
12943
- const prevIsSignedIn = useRef11(null);
12779
+ const prevIsSignedIn = useRef10(null);
12944
12780
  useEffect23(() => {
12945
12781
  if (!authState.isLoaded) return;
12946
12782
  if (prevIsSignedIn.current === null) {
@@ -13020,8 +12856,8 @@ function SylphxProviderInner({
13020
12856
  });
13021
12857
  const pushPreferences = pushPreferencesQuery.data ?? null;
13022
12858
  const pushError = pushPreferencesQuery.error;
13023
- const [pushSubscribed, setPushSubscribed] = useState31(false);
13024
- const [analyticsError, setAnalyticsError] = useState31(null);
12859
+ const [pushSubscribed, setPushSubscribed] = useState30(false);
12860
+ const [analyticsError, setAnalyticsError] = useState30(null);
13025
12861
  const mobilePushQuery = useQuery5({
13026
12862
  queryKey: ["sylphx", appId, "mobilePush"],
13027
12863
  queryFn: async () => {
@@ -13059,13 +12895,13 @@ function SylphxProviderInner({
13059
12895
  const inboxPreferences = inboxQuery.data?.preferences ?? null;
13060
12896
  const inboxLoading = inboxQuery.isLoading;
13061
12897
  const inboxError = inboxQuery.error;
13062
- const [pushSupported, setPushSupported] = useState31(false);
12898
+ const [pushSupported, setPushSupported] = useState30(false);
13063
12899
  useEffect23(() => {
13064
12900
  setPushSupported("serviceWorker" in navigator && "PushManager" in window);
13065
12901
  }, []);
13066
- const analyticsQueue = useRef11([]);
13067
- const flushTimeoutRef = useRef11(null);
13068
- const trackedEventIds = useRef11(/* @__PURE__ */ new Set());
12902
+ const analyticsQueue = useRef10([]);
12903
+ const flushTimeoutRef = useRef10(null);
12904
+ const trackedEventIds = useRef10(/* @__PURE__ */ new Set());
13069
12905
  useEffect23(() => {
13070
12906
  if (typeof window === "undefined") return;
13071
12907
  const handleBeforeUnload = () => {
@@ -13130,7 +12966,7 @@ function SylphxProviderInner({
13130
12966
  purchase: autoTracking.purchase ?? true
13131
12967
  };
13132
12968
  }, [autoTracking]);
13133
- const saveTokens = useCallback28(
12969
+ const saveTokens = useCallback27(
13134
12970
  (response) => {
13135
12971
  setAuthState({
13136
12972
  isLoaded: true,
@@ -13158,7 +12994,7 @@ function SylphxProviderInner({
13158
12994
  },
13159
12995
  [appId]
13160
12996
  );
13161
- const clearTokens = useCallback28(
12997
+ const clearTokens = useCallback27(
13162
12998
  (error) => {
13163
12999
  clearUserCookie(appId);
13164
13000
  setAuthState({
@@ -13246,7 +13082,7 @@ function SylphxProviderInner({
13246
13082
  window.history.replaceState({}, "", cleanUrl.toString());
13247
13083
  }
13248
13084
  }, []);
13249
- const resolveRedirectUrl = useCallback28((url) => {
13085
+ const resolveRedirectUrl = useCallback27((url) => {
13250
13086
  if (typeof window === "undefined") return "";
13251
13087
  if (!url) return window.location.href;
13252
13088
  if (url.startsWith("/") && !url.startsWith("//")) {
@@ -13254,7 +13090,7 @@ function SylphxProviderInner({
13254
13090
  }
13255
13091
  return url;
13256
13092
  }, []);
13257
- const signIn = useCallback28(
13093
+ const signIn = useCallback27(
13258
13094
  (options) => {
13259
13095
  const resolvedUrl = resolveRedirectUrl(options?.redirectUrl);
13260
13096
  const redirectUri = isValidRedirectUrl(resolvedUrl, {
@@ -13274,7 +13110,7 @@ function SylphxProviderInner({
13274
13110
  },
13275
13111
  [appId, platformUrl, resolveRedirectUrl]
13276
13112
  );
13277
- const signUp = useCallback28(
13113
+ const signUp = useCallback27(
13278
13114
  (options) => {
13279
13115
  const resolvedUrl = resolveRedirectUrl(options?.redirectUrl);
13280
13116
  const redirectUri = isValidRedirectUrl(resolvedUrl, {
@@ -13295,7 +13131,7 @@ function SylphxProviderInner({
13295
13131
  },
13296
13132
  [appId, platformUrl, resolveRedirectUrl]
13297
13133
  );
13298
- const signOut = useCallback28(
13134
+ const signOut = useCallback27(
13299
13135
  async (options) => {
13300
13136
  try {
13301
13137
  await fetch(`${authPrefix}/signout`, {
@@ -13311,7 +13147,7 @@ function SylphxProviderInner({
13311
13147
  },
13312
13148
  [clearTokens, afterSignOutUrl, authPrefix]
13313
13149
  );
13314
- const getToken = useCallback28(async () => {
13150
+ const getToken = useCallback27(async () => {
13315
13151
  if (!authState.isSignedIn) {
13316
13152
  return null;
13317
13153
  }
@@ -13330,79 +13166,37 @@ function SylphxProviderInner({
13330
13166
  return null;
13331
13167
  }
13332
13168
  }, [authState.isSignedIn, authPrefix]);
13333
- const resetPassword = useCallback28(
13169
+ const resetPassword = useCallback27(
13334
13170
  async (options) => {
13335
- const response = await fetch(`${platformUrl}/v1/auth/reset-password`, {
13336
- method: "POST",
13337
- headers: { "Content-Type": "application/json" },
13338
- body: JSON.stringify({
13339
- token: options.token,
13340
- new_password: options.newPassword,
13341
- client_id: appId || ""
13342
- })
13171
+ await api.post("/auth/reset-password", {
13172
+ token: options.token,
13173
+ newPassword: options.newPassword
13343
13174
  });
13344
- if (!response.ok) {
13345
- const error = await response.json().catch(() => ({ message: "Password reset failed" }));
13346
- throw new Error(error.message || "Password reset failed");
13347
- }
13348
13175
  },
13349
- [appId, platformUrl]
13176
+ [api]
13350
13177
  );
13351
- const verifyEmail = useCallback28(
13178
+ const verifyEmail = useCallback27(
13352
13179
  async (options) => {
13353
- const response = await fetch(`${platformUrl}/v1/auth/verify-email`, {
13354
- method: "POST",
13355
- headers: { "Content-Type": "application/json" },
13356
- body: JSON.stringify({
13357
- token: options.token,
13358
- client_id: appId || ""
13359
- })
13360
- });
13361
- if (!response.ok) {
13362
- const error = await response.json().catch(() => ({ message: "Email verification failed" }));
13363
- throw new Error(error.message || "Email verification failed");
13364
- }
13180
+ await api.post("/auth/verify-email", { token: options.token });
13365
13181
  },
13366
- [appId, platformUrl]
13182
+ [api]
13367
13183
  );
13368
- const resendVerificationEmail = useCallback28(
13184
+ const resendVerificationEmail = useCallback27(
13369
13185
  async (options) => {
13370
- const response = await fetch(`${platformUrl}/v1/auth/resend-verification`, {
13371
- method: "POST",
13372
- headers: { "Content-Type": "application/json" },
13373
- body: JSON.stringify({
13374
- email: options.email,
13375
- client_id: appId || ""
13376
- })
13377
- });
13378
- if (!response.ok) {
13379
- const error = await response.json().catch(() => ({ message: "Failed to resend verification email" }));
13380
- throw new Error(error.message || "Failed to resend verification email");
13381
- }
13186
+ await api.post("/auth/resend-verification", { email: options.email });
13382
13187
  },
13383
- [appId, platformUrl]
13188
+ [api]
13384
13189
  );
13385
- const forgotPassword = useCallback28(
13190
+ const forgotPassword = useCallback27(
13386
13191
  async (options) => {
13387
- const response = await fetch(`${platformUrl}/v1/auth/forgot-password`, {
13388
- method: "POST",
13389
- headers: { "Content-Type": "application/json" },
13390
- body: JSON.stringify({
13391
- email: options.email,
13392
- client_id: appId || ""
13393
- })
13394
- });
13395
- if (!response.ok) {
13396
- const error = await response.json().catch(() => ({ message: "Failed to send password reset email" }));
13397
- throw new Error(error.message || "Failed to send password reset email");
13398
- }
13192
+ await api.post("/auth/forgot-password", { email: options.email });
13399
13193
  },
13400
- [appId, platformUrl]
13194
+ [api]
13401
13195
  );
13402
- const clearOAuthError = useCallback28(() => {
13196
+ const clearOAuthError = useCallback27(() => {
13403
13197
  setAuthState((prev) => ({ ...prev, oauthError: null }));
13404
13198
  }, []);
13405
- const signInWithOAuth = useCallback28(
13199
+ const signInWithOAuth = useCallback27(
13406
13200
  async (options) => {
13407
13201
  const { provider, redirectUrl, scopes } = options;
13408
13202
  const finalDestination = resolveRedirectUrl(redirectUrl);
@@ -13455,31 +13249,31 @@ function SylphxProviderInner({
13455
13249
  },
13456
13250
  [platformUrl, appId, resolveRedirectUrl, authPrefix]
13457
13251
  );
13458
- const signInWithGoogle = useCallback28(
13252
+ const signInWithGoogle = useCallback27(
13459
13253
  (redirectUrl) => signInWithOAuth({ provider: "google", redirectUrl }),
13460
13254
  [signInWithOAuth]
13461
13255
  );
13462
- const signInWithGithub = useCallback28(
13256
+ const signInWithGithub = useCallback27(
13463
13257
  (redirectUrl) => signInWithOAuth({ provider: "github", redirectUrl }),
13464
13258
  [signInWithOAuth]
13465
13259
  );
13466
- const signInWithApple = useCallback28(
13260
+ const signInWithApple = useCallback27(
13467
13261
  (redirectUrl) => signInWithOAuth({ provider: "apple", redirectUrl }),
13468
13262
  [signInWithOAuth]
13469
13263
  );
13470
- const signInWithDiscord = useCallback28(
13264
+ const signInWithDiscord = useCallback27(
13471
13265
  (redirectUrl) => signInWithOAuth({ provider: "discord", redirectUrl }),
13472
13266
  [signInWithOAuth]
13473
13267
  );
13474
- const signInWithTwitter = useCallback28(
13268
+ const signInWithTwitter = useCallback27(
13475
13269
  (redirectUrl) => signInWithOAuth({ provider: "twitter", redirectUrl }),
13476
13270
  [signInWithOAuth]
13477
13271
  );
13478
- const signInWithMicrosoft = useCallback28(
13272
+ const signInWithMicrosoft = useCallback27(
13479
13273
  (redirectUrl) => signInWithOAuth({ provider: "microsoft", redirectUrl }),
13480
13274
  [signInWithOAuth]
13481
13275
  );
13482
- const signInWithMagicLink = useCallback28(
13276
+ const signInWithMagicLink = useCallback27(
13483
13277
  async (options) => {
13484
13278
  const { email, redirectUrl } = options;
13485
13279
  const resolvedRedirect = resolveRedirectUrl(redirectUrl);
@@ -13501,7 +13295,7 @@ function SylphxProviderInner({
13501
13295
  },
13502
13296
  [platformUrl, appId, resolveRedirectUrl]
13503
13297
  );
13504
- const createCheckout = useCallback28(
13298
+ const createCheckout = useCallback27(
13505
13299
  async (planSlug, interval) => {
13506
13300
  if (!authState.user?.id) {
13507
13301
  throw new Error("User must be authenticated to create checkout");
@@ -13517,7 +13311,7 @@ function SylphxProviderInner({
13517
13311
  },
13518
13312
  [api, authState.user?.id]
13519
13313
  );
13520
- const openPortal = useCallback28(async () => {
13314
+ const openPortal = useCallback27(async () => {
13521
13315
  if (!authState.user?.id) {
13522
13316
  throw new Error("User must be signed in to access billing portal");
13523
13317
  }
@@ -13527,12 +13321,12 @@ function SylphxProviderInner({
13527
13321
  });
13528
13322
  window.location.href = data.portalUrl;
13529
13323
  }, [api, authState.user?.id]);
13530
- const refreshSubscription = useCallback28(async () => {
13324
+ const refreshSubscription = useCallback27(async () => {
13531
13325
  await queryClient.invalidateQueries({
13532
13326
  queryKey: ["sylphx", appId, "subscription"]
13533
13327
  });
13534
13328
  }, [queryClient, appId]);
13535
- const [isOnline, setIsOnline] = useState31(true);
13329
+ const [isOnline, setIsOnline] = useState30(true);
13536
13330
  useEffect23(() => {
13537
13331
  setIsOnline(navigator.onLine);
13538
13332
  const handleOnline = () => setIsOnline(true);
@@ -13544,32 +13338,32 @@ function SylphxProviderInner({
13544
13338
  window.removeEventListener("offline", handleOffline);
13545
13339
  };
13546
13340
  }, []);
13547
- const queueToOfflineStorage = useCallback28(
13341
+ const queueToOfflineStorage = useCallback27(
13548
13342
  (events) => {
13549
13343
  try {
13550
- const existingQueue = storage.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13344
+ const existingQueue = storage2.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13551
13345
  const merged = [...existingQueue, ...events];
13552
13346
  const trimmed = merged.length > ANALYTICS_QUEUE_LIMIT ? merged.slice(-ANALYTICS_QUEUE_LIMIT) : merged;
13553
- storage.setJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE, trimmed);
13347
+ storage2.setJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE, trimmed);
13554
13348
  } catch {
13555
13349
  }
13556
13350
  },
13557
- [storage]
13351
+ [storage2]
13558
13352
  );
13559
- const getOfflineQueue = useCallback28(() => {
13353
+ const getOfflineQueue = useCallback27(() => {
13560
13354
  try {
13561
- return storage.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13355
+ return storage2.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13562
13356
  } catch {
13563
13357
  return [];
13564
13358
  }
13565
- }, [storage]);
13566
- const clearOfflineQueue = useCallback28(() => {
13359
+ }, [storage2]);
13360
+ const clearOfflineQueue = useCallback27(() => {
13567
13361
  try {
13568
- storage.remove(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE);
13362
+ storage2.remove(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE);
13569
13363
  } catch {
13570
13364
  }
13571
- }, [storage]);
13572
- const flushAnalytics = useCallback28(async () => {
13365
+ }, [storage2]);
13366
+ const flushAnalytics = useCallback27(async () => {
13573
13367
  const offlineEvents = getOfflineQueue();
13574
13368
  const memoryEvents = analyticsQueue.current;
13575
13369
  const allEvents = [...offlineEvents, ...memoryEvents];
@@ -13612,7 +13406,7 @@ function SylphxProviderInner({
13612
13406
  return () => clearTimeout(timeout);
13613
13407
  }
13614
13408
  }, [isOnline, flushAnalytics]);
13615
- const enqueueAnalytics = useCallback28(
13409
+ const enqueueAnalytics = useCallback27(
13616
13410
  (type, data, eventId) => {
13617
13411
  if (!anonymousId && !authState.user?.id) return;
13618
13412
  const id = eventId || `${type}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
@@ -13648,7 +13442,7 @@ function SylphxProviderInner({
13648
13442
  },
13649
13443
  [authState.user?.id, anonymousId, flushAnalytics]
13650
13444
  );
13651
- const track = useCallback28(
13445
+ const track = useCallback27(
13652
13446
  async (event, properties, options) => {
13653
13447
  const autoEvents = ["$pageview", "$login", "$signup", "$logout", "$purchase"];
13654
13448
  if (autoEvents.includes(event)) {
@@ -13659,7 +13453,7 @@ function SylphxProviderInner({
13659
13453
  }
13660
13454
  let enrichedConversion = options?.conversion;
13661
13455
  if (options?.conversion || options?.destinations) {
13662
- const currentClickIds = getStoredClickIds(storage) || clickIds;
13456
+ const currentClickIds = getStoredClickIds(storage2) || clickIds;
13663
13457
  enrichedConversion = {
13664
13458
  // User-provided conversion data takes precedence
13665
13459
  ...options?.conversion,
@@ -13680,15 +13474,15 @@ function SylphxProviderInner({
13680
13474
  conversion: enrichedConversion
13681
13475
  });
13682
13476
  },
13683
- [enqueueAnalytics, autoTrackConfig, storage, clickIds, authState.user]
13477
+ [enqueueAnalytics, autoTrackConfig, storage2, clickIds, authState.user]
13684
13478
  );
13685
- const page = useCallback28(
13479
+ const page = useCallback27(
13686
13480
  async (name, properties) => {
13687
13481
  enqueueAnalytics("page", { name, properties: properties || {} });
13688
13482
  },
13689
13483
  [enqueueAnalytics]
13690
13484
  );
13691
- const identify = useCallback28(
13485
+ const identify = useCallback27(
13692
13486
  async (traits) => {
13693
13487
  if (!authState.user?.id) return;
13694
13488
  enqueueAnalytics("identify", {
@@ -13698,7 +13492,7 @@ function SylphxProviderInner({
13698
13492
  },
13699
13493
  [authState.user?.id, enqueueAnalytics]
13700
13494
  );
13701
- const queryAnalytics = useCallback28(
13495
+ const queryAnalytics = useCallback27(
13702
13496
  async (analyticsQuery) => {
13703
13497
  try {
13704
13498
  const result = await api.post(
@@ -13717,9 +13511,9 @@ function SylphxProviderInner({
13717
13511
  },
13718
13512
  [api]
13719
13513
  );
13720
- const prevAuthStateRef = useRef11(null);
13721
- const prevSubscriptionRef = useRef11(null);
13722
- const hasTrackedInitialPageview = useRef11(false);
13514
+ const prevAuthStateRef = useRef10(null);
13515
+ const prevSubscriptionRef = useRef10(null);
13516
+ const hasTrackedInitialPageview = useRef10(false);
13723
13517
  useEffect23(() => {
13724
13518
  if (!autoTrackConfig.pageview || hasTrackedInitialPageview.current) return;
13725
13519
  if (!anonymousId && !authState.user?.id) return;
@@ -13767,7 +13561,7 @@ function SylphxProviderInner({
13767
13561
  const userCreatedAt = currentState.user.createdAt ? new Date(currentState.user.createdAt).getTime() : 0;
13768
13562
  const isNewUser = Date.now() - userCreatedAt < NEW_USER_THRESHOLD_MS;
13769
13563
  const eventId = `auth_${currentState.user.id}_${isNewUser ? "signup" : "login"}_${Date.now()}`;
13770
- const currentClickIds = getStoredClickIds(storage) || clickIds;
13564
+ const currentClickIds = getStoredClickIds(storage2) || clickIds;
13771
13565
  if (isNewUser && autoTrackConfig.signup) {
13772
13566
  enqueueAnalytics(
13773
13567
  "track",
@@ -13823,13 +13617,13 @@ function SylphxProviderInner({
13823
13617
  );
13824
13618
  }
13825
13619
  prevAuthStateRef.current = currentState;
13826
- }, [authState, enqueueAnalytics, autoTrackConfig, storage, clickIds]);
13620
+ }, [authState, enqueueAnalytics, autoTrackConfig, storage2, clickIds]);
13827
13621
  useEffect23(() => {
13828
13622
  const prevSub = prevSubscriptionRef.current;
13829
13623
  const currentSub = subscription;
13830
13624
  if (autoTrackConfig.purchase && currentSub && (currentSub.status === "active" || currentSub.status === "trialing") && (!prevSub || prevSub.status !== "active" && prevSub.status !== "trialing")) {
13831
13625
  const eventId = `purchase_${currentSub.id}_${Date.now()}`;
13832
- const currentClickIds = getStoredClickIds(storage) || clickIds;
13626
+ const currentClickIds = getStoredClickIds(storage2) || clickIds;
13833
13627
  enqueueAnalytics(
13834
13628
  "track",
13835
13629
  {
@@ -13855,8 +13649,8 @@ function SylphxProviderInner({
13855
13649
  );
13856
13650
  }
13857
13651
  prevSubscriptionRef.current = currentSub;
13858
- }, [subscription, enqueueAnalytics, autoTrackConfig.purchase, storage, clickIds, authState.user]);
13859
- const subscribePush = useCallback28(async () => {
13652
+ }, [subscription, enqueueAnalytics, autoTrackConfig.purchase, storage2, clickIds, authState.user]);
13653
+ const subscribePush = useCallback27(async () => {
13860
13654
  if (!pushSupported || !vapidPublicKey) return false;
13861
13655
  try {
13862
13656
  const registration = await navigator.serviceWorker.ready;
@@ -13880,7 +13674,7 @@ function SylphxProviderInner({
13880
13674
  return false;
13881
13675
  }
13882
13676
  }, [pushSupported, vapidPublicKey, api]);
13883
- const unsubscribePush = useCallback28(async () => {
13677
+ const unsubscribePush = useCallback27(async () => {
13884
13678
  try {
13885
13679
  const registration = await navigator.serviceWorker.ready;
13886
13680
  const sub = await registration.pushManager.getSubscription();
@@ -13892,7 +13686,7 @@ function SylphxProviderInner({
13892
13686
  } catch {
13893
13687
  }
13894
13688
  }, [api]);
13895
- const updatePushPreferences = useCallback28(
13689
+ const updatePushPreferences = useCallback27(
13896
13690
  async (prefs) => {
13897
13691
  if (prefs.enabled === false) {
13898
13692
  await unsubscribePush();
@@ -13907,7 +13701,7 @@ function SylphxProviderInner({
13907
13701
  [pushPreferences, unsubscribePush, queryClient, appId]
13908
13702
  );
13909
13703
  const mobilePushQueryKey = ["sylphx", appId, "mobilePush"];
13910
- const registerMobileDevice = useCallback28(
13704
+ const registerMobileDevice = useCallback27(
13911
13705
  async (options) => {
13912
13706
  const result = await api.post(
13913
13707
  "/notifications/mobile/register",
@@ -13922,7 +13716,7 @@ function SylphxProviderInner({
13922
13716
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
13923
13717
  [api, queryClient, mobilePushQueryKey]
13924
13718
  );
13925
- const unregisterMobileDevice = useCallback28(
13719
+ const unregisterMobileDevice = useCallback27(
13926
13720
  async (token) => {
13927
13721
  await api.post("/notifications/mobile/unregister", { token });
13928
13722
  void queryClient.invalidateQueries({ queryKey: mobilePushQueryKey });
@@ -13930,7 +13724,7 @@ function SylphxProviderInner({
13930
13724
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
13931
13725
  [api, queryClient, mobilePushQueryKey]
13932
13726
  );
13933
- const getMobilePushPreferences = useCallback28(async () => {
13727
+ const getMobilePushPreferences = useCallback27(async () => {
13934
13728
  await queryClient.invalidateQueries({ queryKey: mobilePushQueryKey });
13935
13729
  const data = queryClient.getQueryData(mobilePushQueryKey);
13936
13730
  if (!data?.preferences) {
@@ -13938,25 +13732,25 @@ function SylphxProviderInner({
13938
13732
  }
13939
13733
  return data.preferences;
13940
13734
  }, [queryClient, mobilePushQueryKey]);
13941
- const copyReferralCode = useCallback28(async () => {
13735
+ const copyReferralCode = useCallback27(async () => {
13942
13736
  if (referralCode) {
13943
13737
  await navigator.clipboard.writeText(referralCode);
13944
13738
  }
13945
13739
  }, [referralCode]);
13946
- const regenerateReferralCode = useCallback28(async () => {
13740
+ const regenerateReferralCode = useCallback27(async () => {
13947
13741
  const data = await api.post("/referrals/code/regenerate");
13948
13742
  void queryClient.invalidateQueries({
13949
13743
  queryKey: ["sylphx", appId, "referrals"]
13950
13744
  });
13951
13745
  return data.code;
13952
13746
  }, [api, queryClient, appId]);
13953
- const redeemReferralCode = useCallback28(
13747
+ const redeemReferralCode = useCallback27(
13954
13748
  async (code, _defaults) => {
13955
13749
  return api.post("/referrals/redeem", { code });
13956
13750
  },
13957
13751
  [api]
13958
13752
  );
13959
- const getReferralLeaderboard = useCallback28(
13753
+ const getReferralLeaderboard = useCallback27(
13960
13754
  async (options) => {
13961
13755
  return api.get("/referrals/leaderboard", {
13962
13756
  limit: options?.limit?.toString(),
@@ -13965,7 +13759,7 @@ function SylphxProviderInner({
13965
13759
  },
13966
13760
  [api]
13967
13761
  );
13968
- const getStreak = useCallback28(
13762
+ const getStreak = useCallback27(
13969
13763
  async (streakId, defaults, userTimezone) => {
13970
13764
  if (!authState.user?.id) {
13971
13765
  throw new Error("User must be authenticated to get streak");
@@ -13978,7 +13772,7 @@ function SylphxProviderInner({
13978
13772
  },
13979
13773
  [api, authState.user?.id]
13980
13774
  );
13981
- const recordStreakActivity = useCallback28(
13775
+ const recordStreakActivity = useCallback27(
13982
13776
  async (streakId, metadata, defaults) => {
13983
13777
  if (!authState.user?.id) {
13984
13778
  throw new Error("User must be authenticated to record activity");
@@ -13991,7 +13785,7 @@ function SylphxProviderInner({
13991
13785
  },
13992
13786
  [api, authState.user?.id]
13993
13787
  );
13994
- const recoverStreak = useCallback28(
13788
+ const recoverStreak = useCallback27(
13995
13789
  async (streakId) => {
13996
13790
  if (!authState.user?.id) {
13997
13791
  throw new Error("User must be authenticated to recover streak");
@@ -14003,7 +13797,7 @@ function SylphxProviderInner({
14003
13797
  },
14004
13798
  [api, authState.user?.id]
14005
13799
  );
14006
- const getEngagementLeaderboard = useCallback28(
13800
+ const getEngagementLeaderboard = useCallback27(
14007
13801
  async (leaderboardId, options) => {
14008
13802
  return api.get(`/engagement/leaderboards/${leaderboardId}`, {
14009
13803
  userId: authState.user?.id ?? void 0,
@@ -14014,7 +13808,7 @@ function SylphxProviderInner({
14014
13808
  },
14015
13809
  [api, authState.user?.id]
14016
13810
  );
14017
- const submitScore = useCallback28(
13811
+ const submitScore = useCallback27(
14018
13812
  async (leaderboardId, value, metadata, defaults) => {
14019
13813
  if (!authState.user?.id) {
14020
13814
  throw new Error("User must be authenticated to submit score");
@@ -14028,7 +13822,7 @@ function SylphxProviderInner({
14028
13822
  },
14029
13823
  [api, authState.user?.id]
14030
13824
  );
14031
- const getAchievements = useCallback28(async () => {
13825
+ const getAchievements = useCallback27(async () => {
14032
13826
  if (!authState.user?.id) {
14033
13827
  throw new Error("User must be authenticated to get achievements");
14034
13828
  }
@@ -14036,7 +13830,7 @@ function SylphxProviderInner({
14036
13830
  userId: authState.user.id
14037
13831
  });
14038
13832
  }, [api, authState.user?.id]);
14039
- const unlockAchievement = useCallback28(
13833
+ const unlockAchievement = useCallback27(
14040
13834
  async (achievementId, defaults) => {
14041
13835
  if (!authState.user?.id) {
14042
13836
  throw new Error("User must be authenticated to unlock achievement");
@@ -14048,7 +13842,7 @@ function SylphxProviderInner({
14048
13842
  },
14049
13843
  [api, authState.user?.id]
14050
13844
  );
14051
- const incrementAchievementProgress = useCallback28(
13845
+ const incrementAchievementProgress = useCallback27(
14052
13846
  async (achievementId, amount, defaults) => {
14053
13847
  if (!authState.user?.id) {
14054
13848
  throw new Error("User must be authenticated to increment progress");
@@ -14062,10 +13856,10 @@ function SylphxProviderInner({
14062
13856
  [api, authState.user?.id]
14063
13857
  );
14064
13858
  const inboxQueryKey = ["sylphx", appId, "inbox"];
14065
- const refreshInbox = useCallback28(async () => {
13859
+ const refreshInbox = useCallback27(async () => {
14066
13860
  await queryClient.invalidateQueries({ queryKey: inboxQueryKey });
14067
13861
  }, [queryClient, inboxQueryKey]);
14068
- const markInboxMessageAsRead = useCallback28(
13862
+ const markInboxMessageAsRead = useCallback27(
14069
13863
  async (messageId) => {
14070
13864
  const previousData = queryClient.getQueryData(inboxQueryKey);
14071
13865
  queryClient.setQueryData(inboxQueryKey, (old) => {
@@ -14088,7 +13882,7 @@ function SylphxProviderInner({
14088
13882
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
14089
13883
  [api, queryClient, inboxQueryKey]
14090
13884
  );
14091
- const markAllInboxMessagesAsRead = useCallback28(async () => {
13885
+ const markAllInboxMessagesAsRead = useCallback27(async () => {
14092
13886
  const previousData = queryClient.getQueryData(inboxQueryKey);
14093
13887
  queryClient.setQueryData(inboxQueryKey, (old) => {
14094
13888
  if (!old) return old;
@@ -14109,7 +13903,7 @@ function SylphxProviderInner({
14109
13903
  throw err;
14110
13904
  }
14111
13905
  }, [api, queryClient, inboxQueryKey]);
14112
- const dismissInboxMessage = useCallback28(
13906
+ const dismissInboxMessage = useCallback27(
14113
13907
  async (messageId) => {
14114
13908
  const previousData = queryClient.getQueryData(inboxQueryKey);
14115
13909
  queryClient.setQueryData(inboxQueryKey, (old) => {
@@ -14129,7 +13923,7 @@ function SylphxProviderInner({
14129
13923
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
14130
13924
  [api, queryClient, inboxQueryKey]
14131
13925
  );
14132
- const recordInboxMessageClick = useCallback28(
13926
+ const recordInboxMessageClick = useCallback27(
14133
13927
  async (messageId, action) => {
14134
13928
  queryClient.setQueryData(inboxQueryKey, (old) => {
14135
13929
  if (!old) return old;
@@ -14151,7 +13945,7 @@ function SylphxProviderInner({
14151
13945
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
14152
13946
  [api, queryClient, inboxQueryKey]
14153
13947
  );
14154
- const updateInboxPreferences = useCallback28(
13948
+ const updateInboxPreferences = useCallback27(
14155
13949
  async (prefs) => {
14156
13950
  const previousData = queryClient.getQueryData(inboxQueryKey);
14157
13951
  queryClient.setQueryData(inboxQueryKey, (old) => {
@@ -14189,15 +13983,6 @@ function SylphxProviderInner({
14189
13983
  }),
14190
13984
  [api, anonymousId, authState.user?.id, config2]
14191
13985
  );
14192
- const storageValue = useMemo9(
14193
- () => createStorageValue({
14194
- api,
14195
- platformUrl,
14196
- appId,
14197
- userId: authState.user?.id ?? null
14198
- }),
14199
- [api, platformUrl, appId, authState.user?.id]
14200
- );
14201
13986
  const newsletterValue = useMemo9(
14202
13987
  () => createNewsletterValue({ api }),
14203
13988
  [api]
@@ -14272,15 +14057,7 @@ function SylphxProviderInner({
14272
14057
  });
14273
14058
  },
14274
14059
  verifyEmail: async (token) => {
14275
- const response = await fetch(`${platformUrl}/v1/auth/verify-email`, {
14276
- method: "POST",
14277
- headers: { "Content-Type": "application/json" },
14278
- body: JSON.stringify({ token, client_id: appId || "" })
14279
- });
14280
- if (!response.ok) {
14281
- const error = await response.json().catch(() => ({ message: "Email verification failed" }));
14282
- throw new Error(error.message || "Email verification failed");
14283
- }
14060
+ await api.post("/auth/verify-email", { token });
14284
14061
  return { success: true };
14285
14062
  },
14286
14063
  logout: async (_refreshToken) => {
@@ -14728,12 +14505,12 @@ function SylphxProviderInner({
14728
14505
  resolvedRef
14729
14506
  ]
14730
14507
  );
14731
- return /* @__PURE__ */ jsx24(AuthContext.Provider, { value: authValue, children: /* @__PURE__ */ jsx24(SdkAuthContext.Provider, { value: sdkAuthValue, children: /* @__PURE__ */ jsx24(UserContext.Provider, { value: userValue, children: /* @__PURE__ */ jsx24(SecurityContext.Provider, { value: securityValue, children: /* @__PURE__ */ jsx24(PlatformContext.Provider, { value: platformValue, children: /* @__PURE__ */ jsx24(StorageContext.Provider, { value: storageValue, children: /* @__PURE__ */ jsx24(AIContext.Provider, { value: aiValue, children: /* @__PURE__ */ jsx24(TasksContext.Provider, { value: tasksValue, children: /* @__PURE__ */ jsx24(MonitoringContext.Provider, { value: monitoringValue, children: /* @__PURE__ */ jsx24(ConsentContext.Provider, { value: consentValue, children: /* @__PURE__ */ jsx24(DatabaseContext.Provider, { value: databaseValue, children: /* @__PURE__ */ jsx24(EmailContext.Provider, { value: emailValue, children: /* @__PURE__ */ jsx24(NewsletterContext.Provider, { value: newsletterValue, children: /* @__PURE__ */ jsx24(WebhooksContext.Provider, { value: webhooksValue, children }) }) }) }) }) }) }) }) }) }) }) }) }) });
14508
+ return /* @__PURE__ */ jsx24(AuthContext.Provider, { value: authValue, children: /* @__PURE__ */ jsx24(SdkAuthContext.Provider, { value: sdkAuthValue, children: /* @__PURE__ */ jsx24(UserContext.Provider, { value: userValue, children: /* @__PURE__ */ jsx24(SecurityContext.Provider, { value: securityValue, children: /* @__PURE__ */ jsx24(PlatformContext.Provider, { value: platformValue, children: /* @__PURE__ */ jsx24(AIContext.Provider, { value: aiValue, children: /* @__PURE__ */ jsx24(TasksContext.Provider, { value: tasksValue, children: /* @__PURE__ */ jsx24(MonitoringContext.Provider, { value: monitoringValue, children: /* @__PURE__ */ jsx24(ConsentContext.Provider, { value: consentValue, children: /* @__PURE__ */ jsx24(DatabaseContext.Provider, { value: databaseValue, children: /* @__PURE__ */ jsx24(EmailContext.Provider, { value: emailValue, children: /* @__PURE__ */ jsx24(NewsletterContext.Provider, { value: newsletterValue, children: /* @__PURE__ */ jsx24(WebhooksContext.Provider, { value: webhooksValue, children }) }) }) }) }) }) }) }) }) }) }) }) });
14732
14509
  }
14733
14510
 
14734
14511
  // src/react/rbac-hooks.ts
14735
14512
  import { useQuery as useQuery6, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
14736
- import { useCallback as useCallback29, useContext as useContext16, useMemo as useMemo10 } from "react";
14513
+ import { useCallback as useCallback28, useContext as useContext16, useMemo as useMemo10 } from "react";
14737
14514
 
14738
14515
  // src/permissions.ts
14739
14516
  async function listPermissions(config2) {
@@ -14795,7 +14572,7 @@ function usePermissions() {
14795
14572
  staleTime: 3e4
14796
14573
  // 30s — permissions change rarely
14797
14574
  });
14798
- const refresh = useCallback29(async () => {
14575
+ const refresh = useCallback28(async () => {
14799
14576
  await queryClient.invalidateQueries({ queryKey: rbacKeys.permissions() });
14800
14577
  }, [queryClient]);
14801
14578
  return {
@@ -14818,7 +14595,7 @@ function useRoles() {
14818
14595
  staleTime: 3e4
14819
14596
  // 30s — roles change rarely
14820
14597
  });
14821
- const refresh = useCallback29(async () => {
14598
+ const refresh = useCallback28(async () => {
14822
14599
  await queryClient.invalidateQueries({ queryKey: rbacKeys.roles() });
14823
14600
  }, [queryClient]);
14824
14601
  return {
@@ -14844,7 +14621,7 @@ function useMemberPermissions(orgIdOrSlug, memberId) {
14844
14621
  staleTime: 15e3
14845
14622
  // 15s — member permissions may change more frequently
14846
14623
  });
14847
- const refresh = useCallback29(async () => {
14624
+ const refresh = useCallback28(async () => {
14848
14625
  if (orgIdOrSlug && memberId) {
14849
14626
  await queryClient.invalidateQueries({
14850
14627
  queryKey: rbacKeys.memberPermissions(orgIdOrSlug, memberId)
@@ -14872,236 +14649,663 @@ function useHasPermission(permissions, required) {
14872
14649
  }
14873
14650
 
14874
14651
  // src/react/storage-hooks.ts
14875
- import { useCallback as useCallback30, useRef as useRef12, useState as useState32 } from "react";
14876
- function useStorage() {
14877
- const ctx = useStorageContext();
14878
- const [isUploading, setIsUploading] = useState32(false);
14879
- const [progress, setProgress] = useState32(0);
14880
- const [bytesUploaded, setBytesUploaded] = useState32(0);
14881
- const [bytesTotal, setBytesTotal] = useState32(0);
14882
- const [uploadError, setUploadError] = useState32(null);
14883
- const [wasCancelled, setWasCancelled] = useState32(false);
14884
- const abortControllerRef = useRef12(null);
14885
- const handleProgress = useCallback30((event) => {
14886
- setProgress(event.progress);
14887
- setBytesUploaded(event.loaded);
14888
- setBytesTotal(event.total);
14889
- }, []);
14890
- const cancel = useCallback30(() => {
14891
- if (abortControllerRef.current) {
14892
- abortControllerRef.current.abort();
14893
- abortControllerRef.current = null;
14894
- setWasCancelled(true);
14895
- setIsUploading(false);
14652
+ import { useMutation as useMutation2, useQuery as useQuery7, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
14653
+ import { useCallback as useCallback29, useContext as useContext17, useMemo as useMemo11, useState as useState31 } from "react";
14654
+
14655
+ // src/lib/retry.ts
14656
+ init_constants();
14657
+ var DEFAULT_RETRY_CONFIG = {
14658
+ maxRetries: 5,
14659
+ baseDelayMs: BASE_RETRY_DELAY_MS,
14660
+ maxDelayMs: MAX_RETRY_DELAY_MS
14661
+ };
14662
+ function calculateBackoffDelay(attempt, config2 = DEFAULT_RETRY_CONFIG) {
14663
+ const exp = config2.baseDelayMs * 2 ** attempt;
14664
+ const capped = Math.min(exp, config2.maxDelayMs);
14665
+ return Math.random() * capped;
14666
+ }
14667
+ function sleep(ms, signal) {
14668
+ return new Promise((resolve, reject) => {
14669
+ if (signal?.aborted) {
14670
+ reject(toAbortError());
14671
+ return;
14896
14672
  }
14897
- }, []);
14898
- const upload = useCallback30(
14899
- async (file, options) => {
14900
- const controller = new AbortController();
14901
- abortControllerRef.current = controller;
14902
- const signal = options?.signal ?? controller.signal;
14903
- setIsUploading(true);
14904
- setProgress(0);
14905
- setBytesUploaded(0);
14906
- setBytesTotal(file.size);
14907
- setUploadError(null);
14908
- setWasCancelled(false);
14673
+ const timer = setTimeout(resolve, ms);
14674
+ signal?.addEventListener(
14675
+ "abort",
14676
+ () => {
14677
+ clearTimeout(timer);
14678
+ reject(toAbortError());
14679
+ },
14680
+ { once: true }
14681
+ );
14682
+ });
14683
+ }
14684
+ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 425, 429]);
14685
+ function isRetryableError(error) {
14686
+ if (isAbortError(error)) return false;
14687
+ if (error instanceof TypeError) return true;
14688
+ if (error instanceof Error && "status" in error) {
14689
+ const status = error.status;
14690
+ return status >= 500 || RETRYABLE_STATUSES.has(status);
14691
+ }
14692
+ return false;
14693
+ }
14694
+ function isAbortError(error) {
14695
+ if (error instanceof DOMException && error.name === "AbortError") return true;
14696
+ if (error instanceof Error && error.name === "AbortError") return true;
14697
+ return false;
14698
+ }
14699
+ function toAbortError(message = "Aborted") {
14700
+ if (typeof DOMException !== "undefined") {
14701
+ return new DOMException(message, "AbortError");
14702
+ }
14703
+ const err = new Error(message);
14704
+ err.name = "AbortError";
14705
+ return err;
14706
+ }
14707
+ async function withRetry(fn, options = {}) {
14708
+ const cfg = {
14709
+ maxRetries: options.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
14710
+ baseDelayMs: options.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
14711
+ maxDelayMs: options.maxDelayMs ?? DEFAULT_RETRY_CONFIG.maxDelayMs
14712
+ };
14713
+ let lastError;
14714
+ for (let attempt = 0; attempt <= cfg.maxRetries; attempt++) {
14715
+ if (options.signal?.aborted) throw toAbortError("Aborted");
14716
+ try {
14717
+ return await fn();
14718
+ } catch (err) {
14719
+ lastError = err;
14720
+ if (isAbortError(err)) throw err;
14721
+ if (attempt === cfg.maxRetries) break;
14722
+ if (!isRetryableError(err)) throw err;
14723
+ const retryAfter = extractRetryAfter(err);
14724
+ const delay2 = retryAfter ?? calculateBackoffDelay(attempt, cfg);
14725
+ options.onRetry?.(attempt, delay2, err);
14726
+ await sleep(delay2, options.signal);
14727
+ }
14728
+ }
14729
+ throw lastError;
14730
+ }
14731
+ function extractRetryAfter(err) {
14732
+ if (err && typeof err === "object" && "retryAfter" in err) {
14733
+ const v2 = err.retryAfter;
14734
+ if (typeof v2 === "number" && v2 > 0) return v2 * 1e3;
14735
+ }
14736
+ return void 0;
14737
+ }
14738
+ function uuidv7() {
14739
+ const ms = BigInt(Date.now());
14740
+ const bytes = randomBytes(16);
14741
+ bytes[0] = Number(ms >> 40n & 0xffn);
14742
+ bytes[1] = Number(ms >> 32n & 0xffn);
14743
+ bytes[2] = Number(ms >> 24n & 0xffn);
14744
+ bytes[3] = Number(ms >> 16n & 0xffn);
14745
+ bytes[4] = Number(ms >> 8n & 0xffn);
14746
+ bytes[5] = Number(ms & 0xffn);
14747
+ bytes[6] = bytes[6] & 15 | 112;
14748
+ bytes[8] = bytes[8] & 63 | 128;
14749
+ const hex = Array.from(bytes, (b2) => b2.toString(16).padStart(2, "0")).join("");
14750
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
14751
+ }
14752
+ function randomBytes(n2) {
14753
+ const out = new Uint8Array(n2);
14754
+ const c2 = globalThis.crypto;
14755
+ if (c2?.getRandomValues) {
14756
+ c2.getRandomValues(out);
14757
+ return out;
14758
+ }
14759
+ for (let i2 = 0; i2 < n2; i2++) out[i2] = Math.floor(Math.random() * 256);
14760
+ return out;
14761
+ }
14762
+
14763
+ // src/storage.ts
14764
+ var PATHS = {
14765
+ uploads: "/storage/uploads",
14766
+ upload: (id) => `/storage/uploads/${encodeURIComponent(String(id))}`,
14767
+ uploadComplete: (id) => `/storage/uploads/${encodeURIComponent(String(id))}:complete`,
14768
+ uploadPart: (id, n2) => `/storage/uploads/${encodeURIComponent(String(id))}/parts/${n2}`,
14769
+ files: "/storage/files",
14770
+ file: (id) => `/storage/files/${encodeURIComponent(String(id))}`,
14771
+ fileRestore: (id) => `/storage/files/${encodeURIComponent(String(id))}:restore`,
14772
+ fileSignedUrl: (id) => `/storage/files/${encodeURIComponent(String(id))}:signedUrl`,
14773
+ fileCopy: (id) => `/storage/files/${encodeURIComponent(String(id))}:copy`,
14774
+ versions: (id) => `/storage/files/${encodeURIComponent(String(id))}/versions`,
14775
+ versionRestore: (id, vid) => `/storage/files/${encodeURIComponent(String(id))}/versions/${encodeURIComponent(String(vid))}:restore`
14776
+ };
14777
+ var isBrowser = () => typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
14778
+ var hasXhr = () => typeof globalThis.XMLHttpRequest !== "undefined";
14779
+ var hasLocalStorage = () => {
14780
+ try {
14781
+ const ls = globalThis.localStorage;
14782
+ return Boolean(ls && typeof ls.getItem === "function");
14783
+ } catch {
14784
+ return false;
14785
+ }
14786
+ };
14787
+ async function computeSha256Hex(blob) {
14788
+ const subtle = globalThis.crypto?.subtle;
14789
+ if (subtle?.digest) {
14790
+ const buf2 = await blob.arrayBuffer();
14791
+ const digest = await subtle.digest("SHA-256", buf2);
14792
+ return bytesToHex(new Uint8Array(digest));
14793
+ }
14794
+ const nodeCrypto = await import("crypto");
14795
+ const hash = nodeCrypto.createHash("sha256");
14796
+ const buf = Buffer.from(await blob.arrayBuffer());
14797
+ hash.update(buf);
14798
+ return hash.digest("hex");
14799
+ }
14800
+ function bytesToHex(b2) {
14801
+ let s2 = "";
14802
+ for (let i2 = 0; i2 < b2.length; i2++) s2 += b2[i2].toString(16).padStart(2, "0");
14803
+ return s2;
14804
+ }
14805
+ var RESUME_KEY_PREFIX = "sylphx_upload_";
14806
+ function resumeKey(uploadId) {
14807
+ return `${RESUME_KEY_PREFIX}${uploadId}`;
14808
+ }
14809
+ function persistResume(rec) {
14810
+ if (hasLocalStorage()) {
14811
+ try {
14812
+ localStorage.setItem(resumeKey(rec.uploadId), JSON.stringify(rec));
14813
+ } catch {
14814
+ }
14815
+ return;
14816
+ }
14817
+ if (!isBrowser()) {
14818
+ void persistResumeNode(rec);
14819
+ }
14820
+ }
14821
+ function clearResume(uploadId) {
14822
+ if (hasLocalStorage()) {
14823
+ try {
14824
+ localStorage.removeItem(resumeKey(uploadId));
14825
+ } catch {
14826
+ }
14827
+ return;
14828
+ }
14829
+ if (!isBrowser()) void clearResumeNode(uploadId);
14830
+ }
14831
+ async function persistResumeNode(rec) {
14832
+ try {
14833
+ const fs = await import("fs/promises");
14834
+ const path = await import("path");
14835
+ const os = await import("os");
14836
+ const dir = path.join(os.homedir(), ".sylphx");
14837
+ await fs.mkdir(dir, { recursive: true });
14838
+ const file = path.join(dir, "uploads.json");
14839
+ let store = {};
14840
+ try {
14841
+ const text = await fs.readFile(file, "utf8");
14842
+ store = JSON.parse(text);
14843
+ } catch {
14844
+ store = {};
14845
+ }
14846
+ store[rec.uploadId] = rec;
14847
+ await fs.writeFile(file, JSON.stringify(store), "utf8");
14848
+ } catch {
14849
+ }
14850
+ }
14851
+ async function clearResumeNode(uploadId) {
14852
+ try {
14853
+ const fs = await import("fs/promises");
14854
+ const path = await import("path");
14855
+ const os = await import("os");
14856
+ const file = path.join(os.homedir(), ".sylphx", "uploads.json");
14857
+ const text = await fs.readFile(file, "utf8");
14858
+ const store = JSON.parse(text);
14859
+ delete store[uploadId];
14860
+ await fs.writeFile(file, JSON.stringify(store), "utf8");
14861
+ } catch {
14862
+ }
14863
+ }
14864
+ function putBlob(url, body, headers, signal, onProgress) {
14865
+ if (hasXhr()) return putBlobXhr(url, body, headers, signal, onProgress);
14866
+ return putBlobFetch(url, body, headers, signal, onProgress);
14867
+ }
14868
+ function putBlobXhr(url, body, headers, signal, onProgress) {
14869
+ return new Promise((resolve, reject) => {
14870
+ const xhr = new XMLHttpRequest();
14871
+ const handleAbort = () => {
14909
14872
  try {
14910
- const url = await ctx.upload(file, {
14911
- ...options,
14912
- signal,
14913
- onProgress: handleProgress
14914
- });
14915
- setProgress(100);
14916
- return url;
14917
- } catch (err) {
14918
- if (err instanceof DOMException && err.name === "AbortError") {
14919
- setWasCancelled(true);
14920
- throw err;
14921
- }
14922
- const error = err instanceof Error ? err : new Error("Upload failed");
14923
- setUploadError(error);
14924
- throw error;
14925
- } finally {
14926
- abortControllerRef.current = null;
14927
- setIsUploading(false);
14873
+ xhr.abort();
14874
+ } catch {
14928
14875
  }
14929
- },
14930
- [ctx, handleProgress]
14931
- );
14932
- const uploadAvatar = useCallback30(
14933
- async (file) => {
14934
- const controller = new AbortController();
14935
- abortControllerRef.current = controller;
14936
- setIsUploading(true);
14937
- setProgress(0);
14938
- setBytesUploaded(0);
14939
- setBytesTotal(file.size);
14940
- setUploadError(null);
14941
- setWasCancelled(false);
14876
+ reject(toAbortError("Upload aborted"));
14877
+ };
14878
+ if (signal?.aborted) {
14879
+ reject(toAbortError("Upload aborted"));
14880
+ return;
14881
+ }
14882
+ signal?.addEventListener("abort", handleAbort, { once: true });
14883
+ if (onProgress) {
14884
+ xhr.upload.addEventListener("progress", (e2) => {
14885
+ if (e2.lengthComputable) onProgress(e2.loaded);
14886
+ });
14887
+ }
14888
+ xhr.addEventListener("load", () => {
14889
+ signal?.removeEventListener("abort", handleAbort);
14890
+ if (xhr.status >= 200 && xhr.status < 300) {
14891
+ const etag = resolveXhrEtag(xhr);
14892
+ resolve({ etag: stripQuotes(etag), status: xhr.status });
14893
+ } else {
14894
+ const err = new Error(`PUT failed with status ${xhr.status}`);
14895
+ err.status = xhr.status;
14896
+ reject(err);
14897
+ }
14898
+ });
14899
+ xhr.addEventListener("error", () => {
14900
+ signal?.removeEventListener("abort", handleAbort);
14901
+ reject(new TypeError("Network error during upload"));
14902
+ });
14903
+ xhr.addEventListener("abort", () => {
14904
+ signal?.removeEventListener("abort", handleAbort);
14905
+ reject(toAbortError("Upload aborted"));
14906
+ });
14907
+ xhr.open("PUT", url);
14908
+ for (const [k2, v2] of Object.entries(headers)) {
14942
14909
  try {
14943
- const url = await ctx.uploadAvatar(file, {
14944
- onProgress: handleProgress
14945
- });
14946
- setProgress(100);
14947
- return url;
14948
- } catch (err) {
14949
- if (err instanceof DOMException && err.name === "AbortError") {
14950
- setWasCancelled(true);
14951
- throw err;
14952
- }
14953
- const error = err instanceof Error ? err : new Error("Avatar upload failed");
14954
- setUploadError(error);
14955
- throw error;
14956
- } finally {
14957
- abortControllerRef.current = null;
14958
- setIsUploading(false);
14910
+ xhr.setRequestHeader(k2, v2);
14911
+ } catch {
14959
14912
  }
14960
- },
14961
- [ctx, handleProgress]
14913
+ }
14914
+ xhr.send(body);
14915
+ });
14916
+ }
14917
+ function resolveXhrEtag(xhr) {
14918
+ const canonical = xhr.getResponseHeader("ETag");
14919
+ if (canonical !== null) return canonical;
14920
+ return xhr.getResponseHeader("etag") ?? "";
14921
+ }
14922
+ async function putBlobFetch(url, body, headers, signal, onProgress) {
14923
+ let stream = body;
14924
+ if (onProgress && typeof TransformStream !== "undefined" && typeof body.stream === "function") {
14925
+ let loaded = 0;
14926
+ const counter = new TransformStream({
14927
+ transform(chunk, controller) {
14928
+ loaded += chunk.byteLength;
14929
+ onProgress(loaded);
14930
+ controller.enqueue(chunk);
14931
+ }
14932
+ });
14933
+ stream = body.stream().pipeThrough(counter);
14934
+ }
14935
+ const res = await fetch(url, {
14936
+ method: "PUT",
14937
+ body: stream,
14938
+ headers,
14939
+ signal,
14940
+ // Required when streaming a request body in Chromium / undici.
14941
+ // Cast: TS lib lacks `duplex`.
14942
+ ...{ duplex: "half" }
14943
+ });
14944
+ if (!res.ok) {
14945
+ const err = new Error(`PUT failed with status ${res.status}`);
14946
+ err.status = res.status;
14947
+ throw err;
14948
+ }
14949
+ const etag = resolveFetchEtag(res.headers);
14950
+ if (onProgress) onProgress(body.size);
14951
+ return { etag: stripQuotes(etag), status: res.status };
14952
+ }
14953
+ function resolveFetchEtag(headers) {
14954
+ const lowerCase = headers.get("etag");
14955
+ if (lowerCase !== null) return lowerCase;
14956
+ return headers.get("ETag") ?? "";
14957
+ }
14958
+ function stripQuotes(s2) {
14959
+ if (s2.length >= 2 && s2.startsWith('"') && s2.endsWith('"')) return s2.slice(1, -1);
14960
+ return s2;
14961
+ }
14962
+ async function putWithRetry(url, body, headers, signal, onProgress) {
14963
+ let lastErr;
14964
+ const maxRetries = 5;
14965
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
14966
+ if (signal?.aborted) throw toAbortError();
14967
+ try {
14968
+ return await putBlob(url, body, headers, signal, onProgress);
14969
+ } catch (err) {
14970
+ if (isAbortError(err)) throw err;
14971
+ lastErr = err;
14972
+ if (attempt === maxRetries || !isRetryableError(err)) throw err;
14973
+ await sleep(calculateBackoffDelay(attempt), signal);
14974
+ }
14975
+ }
14976
+ throw lastErr;
14977
+ }
14978
+ async function uploadsCreate(config2, blob, options) {
14979
+ const signal = options.signal;
14980
+ if (signal?.aborted) throw toAbortError();
14981
+ const filename = options.filename ?? (isFile(blob) ? blob.name : void 0) ?? "upload.bin";
14982
+ const contentType = options.contentType ?? (blob.type && blob.type.length > 0 ? blob.type : "application/octet-stream");
14983
+ const size = blob.size;
14984
+ const checksumSha256 = options.checksumSha256 ?? await computeSha256Hex(blob);
14985
+ const idempotencyKey = options.idempotencyKey ?? uuidv7();
14986
+ const createBody = {
14987
+ filename,
14988
+ contentType,
14989
+ size,
14990
+ folder: options.folder,
14991
+ visibility: options.visibility,
14992
+ metadata: options.metadata,
14993
+ checksumSha256,
14994
+ ifNoneMatch: options.ifNoneMatch
14995
+ };
14996
+ const session = await callApi(config2, PATHS.uploads, {
14997
+ method: "POST",
14998
+ body: createBody,
14999
+ idempotencyKey,
15000
+ signal
15001
+ });
15002
+ const uploadId = session.uploadId;
15003
+ const onAborted = async () => {
15004
+ try {
15005
+ await callApi(config2, PATHS.upload(uploadId), { method: "DELETE" });
15006
+ } catch {
15007
+ }
15008
+ clearResume(String(uploadId));
15009
+ };
15010
+ try {
15011
+ if (session.method === "PUT") {
15012
+ return await runSinglePart(config2, blob, session, options, idempotencyKey);
15013
+ }
15014
+ return await runMultipart(config2, blob, session, options, idempotencyKey);
15015
+ } catch (err) {
15016
+ if (isAbortError(err)) {
15017
+ await onAborted();
15018
+ }
15019
+ throw err;
15020
+ }
15021
+ }
15022
+ function isFile(b2) {
15023
+ return typeof b2.name === "string";
15024
+ }
15025
+ async function runSinglePart(config2, blob, session, options, idempotencyKey) {
15026
+ const { onProgress, signal } = options;
15027
+ const total = blob.size;
15028
+ const trackProgress = onProgress ? (loaded) => {
15029
+ onProgress({ loaded, total, partsCompleted: 0, partsTotal: 1 });
15030
+ } : void 0;
15031
+ const put = await putWithRetry(session.url, blob, session.headers, signal, trackProgress);
15032
+ if (onProgress) onProgress({ loaded: total, total, partsCompleted: 1, partsTotal: 1 });
15033
+ const completion = await callApi(
15034
+ config2,
15035
+ PATHS.uploadComplete(session.uploadId),
15036
+ {
15037
+ method: "POST",
15038
+ body: { parts: [{ partNumber: 1, etag: put.etag }] },
15039
+ idempotencyKey: `${idempotencyKey}:complete`,
15040
+ signal
15041
+ }
15042
+ );
15043
+ clearResume(String(session.uploadId));
15044
+ return await fetchFile(config2, completion.fileId);
15045
+ }
15046
+ async function runMultipart(config2, blob, session, options, idempotencyKey) {
15047
+ const { onProgress, signal } = options;
15048
+ const partSize = session.partSize;
15049
+ const total = blob.size;
15050
+ const partsTotal = session.partCount;
15051
+ const completedParts = [];
15052
+ const partLoaded = /* @__PURE__ */ new Map();
15053
+ const reportProgress = () => {
15054
+ if (!onProgress) return;
15055
+ let loaded = 0;
15056
+ for (const v2 of partLoaded.values()) loaded += v2;
15057
+ onProgress({ loaded, total, partsCompleted: completedParts.length, partsTotal });
15058
+ };
15059
+ for (const part of session.parts) {
15060
+ if (signal?.aborted) throw toAbortError();
15061
+ const offset = (part.partNumber - 1) * partSize;
15062
+ const end = Math.min(offset + partSize, total);
15063
+ const slice = blob.slice(offset, end);
15064
+ const trackProgress = onProgress ? (loaded) => {
15065
+ partLoaded.set(part.partNumber, loaded);
15066
+ reportProgress();
15067
+ } : void 0;
15068
+ const result = await putWithRetry(part.url, slice, {}, signal, trackProgress);
15069
+ completedParts.push({ partNumber: part.partNumber, etag: result.etag });
15070
+ partLoaded.set(part.partNumber, slice.size);
15071
+ reportProgress();
15072
+ persistResume({
15073
+ uploadId: String(session.uploadId),
15074
+ completedParts: [...completedParts],
15075
+ updatedAt: Date.now()
15076
+ });
15077
+ }
15078
+ const completion = await callApi(
15079
+ config2,
15080
+ PATHS.uploadComplete(session.uploadId),
15081
+ {
15082
+ method: "POST",
15083
+ body: { parts: completedParts },
15084
+ idempotencyKey: `${idempotencyKey}:complete`,
15085
+ signal
15086
+ }
14962
15087
  );
14963
- const deleteFile = useCallback30(
14964
- async (fileId) => {
14965
- await ctx.deleteFile(fileId);
15088
+ clearResume(String(session.uploadId));
15089
+ return await fetchFile(config2, completion.fileId);
15090
+ }
15091
+ async function fetchFile(config2, fileId) {
15092
+ return callApi(config2, PATHS.file(fileId), { method: "GET" });
15093
+ }
15094
+ async function uploadsAbort(config2, uploadId) {
15095
+ await withRetry(() => callApi(config2, PATHS.upload(uploadId), { method: "DELETE" }), {
15096
+ maxRetries: 3
15097
+ });
15098
+ clearResume(String(uploadId));
15099
+ }
15100
+ function filesListPage(config2, options, cursor) {
15101
+ const query = {
15102
+ folder: options.folder,
15103
+ cursor: cursor ?? options.cursor,
15104
+ limit: options.limit,
15105
+ includeDeleted: options.includeDeleted
15106
+ };
15107
+ return callApi(config2, PATHS.files, {
15108
+ method: "GET",
15109
+ query: {
15110
+ folder: query.folder,
15111
+ cursor: query.cursor,
15112
+ limit: query.limit,
15113
+ includeDeleted: query.includeDeleted
15114
+ }
15115
+ });
15116
+ }
15117
+ function filesList(config2, options = {}) {
15118
+ const fetchPage = (cursor) => filesListPage(config2, options, cursor);
15119
+ const iter = {
15120
+ [Symbol.asyncIterator]: async function* () {
15121
+ let cursor = options.cursor;
15122
+ do {
15123
+ const page = await fetchPage(cursor ?? void 0);
15124
+ for (const f2 of page.files) yield f2;
15125
+ cursor = page.nextCursor;
15126
+ } while (cursor);
15127
+ }
15128
+ };
15129
+ return Object.assign(iter, { fetchPage });
15130
+ }
15131
+ async function filesGet(config2, fileId) {
15132
+ return callApi(config2, PATHS.file(fileId), { method: "GET" });
15133
+ }
15134
+ async function filesDelete(config2, fileId) {
15135
+ return callApi(config2, PATHS.file(fileId), { method: "DELETE" });
15136
+ }
15137
+ async function filesRestore(config2, fileId) {
15138
+ return callApi(config2, PATHS.fileRestore(fileId), { method: "POST" });
15139
+ }
15140
+ async function filesSignedUrl(config2, fileId, options = {}) {
15141
+ const body = {
15142
+ expiresIn: options.expiresIn,
15143
+ disposition: options.disposition,
15144
+ userId: options.userId
15145
+ };
15146
+ return callApi(config2, PATHS.fileSignedUrl(fileId), {
15147
+ method: "POST",
15148
+ body
15149
+ });
15150
+ }
15151
+ async function filesCopy(config2, fileId, options) {
15152
+ const body = {
15153
+ folder: options.folder,
15154
+ filename: options.filename,
15155
+ visibility: options.visibility,
15156
+ metadata: options.metadata
15157
+ };
15158
+ return callApi(config2, PATHS.fileCopy(fileId), {
15159
+ method: "POST",
15160
+ body
15161
+ });
15162
+ }
15163
+ async function filesVersionsList(config2, fileId) {
15164
+ const data = await callApi(config2, PATHS.versions(fileId), {
15165
+ method: "GET"
15166
+ });
15167
+ return data.versions;
15168
+ }
15169
+ async function filesVersionsRestore(config2, fileId, versionId) {
15170
+ return callApi(config2, PATHS.versionRestore(fileId, versionId), { method: "POST" });
15171
+ }
15172
+ var storage = {
15173
+ uploads: {
15174
+ create: uploadsCreate,
15175
+ abort: uploadsAbort
15176
+ },
15177
+ files: {
15178
+ list: filesList,
15179
+ get: filesGet,
15180
+ delete: filesDelete,
15181
+ restore: filesRestore,
15182
+ signedUrl: filesSignedUrl,
15183
+ copy: filesCopy,
15184
+ versions: {
15185
+ list: filesVersionsList,
15186
+ restore: filesVersionsRestore
15187
+ }
15188
+ }
15189
+ };
15190
+
15191
+ // src/react/storage-hooks.ts
15192
+ function useSdkConfig2() {
15193
+ const platform = useContext17(PlatformContext);
15194
+ const auth = useContext17(AuthContext);
15195
+ return useMemo11(() => {
15196
+ if (!platform?.slug) return null;
15197
+ let cfg = createConfig({
15198
+ secretKey: platform.appId,
15199
+ slug: platform.slug
15200
+ });
15201
+ if (auth?.accessToken) cfg = withToken(cfg, auth.accessToken);
15202
+ return cfg;
15203
+ }, [platform?.slug, platform?.appId, auth?.accessToken]);
15204
+ }
15205
+ var storageKeys = {
15206
+ all: ["storage"],
15207
+ lists: () => [...storageKeys.all, "list"],
15208
+ list: (opts) => [...storageKeys.lists(), opts],
15209
+ files: () => [...storageKeys.all, "file"],
15210
+ file: (id) => [...storageKeys.files(), id]
15211
+ };
15212
+ function useStorage() {
15213
+ const config2 = useSdkConfig2();
15214
+ const queryClient = useQueryClient6();
15215
+ const listQuery = useQuery7({
15216
+ queryKey: storageKeys.list({}),
15217
+ queryFn: async () => {
15218
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15219
+ return storage.files.list(config2).fetchPage();
14966
15220
  },
14967
- [ctx]
14968
- );
14969
- const getUrl = useCallback30(
14970
- async (fileId) => {
14971
- return ctx.getUrl(fileId);
15221
+ enabled: Boolean(config2),
15222
+ staleTime: 6e4
15223
+ });
15224
+ const uploadMutation = useMutation2({
15225
+ mutationFn: async (input) => {
15226
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15227
+ return storage.uploads.create(config2, input.blob, input.options ?? {});
14972
15228
  },
14973
- [ctx]
14974
- );
15229
+ onSuccess: () => {
15230
+ void queryClient.invalidateQueries({ queryKey: storageKeys.lists() });
15231
+ }
15232
+ });
15233
+ const upload = useCallback29(
15234
+ (blob, options) => uploadMutation.mutateAsync({ blob, options }),
15235
+ [uploadMutation]
15236
+ );
15237
+ const refetch = useCallback29(async () => {
15238
+ await listQuery.refetch();
15239
+ }, [listQuery]);
15240
+ const error = uploadMutation.error ?? listQuery.error;
14975
15241
  return {
14976
15242
  upload,
14977
- uploadAvatar,
14978
- deleteFile,
14979
- getUrl,
14980
- cancel,
14981
- isUploading,
14982
- progress,
14983
- bytesUploaded,
14984
- bytesTotal,
14985
- uploadError,
14986
- wasCancelled
14987
- };
14988
- }
14989
- function useFileUpload(options = {}) {
14990
- const ctx = useStorageContext();
14991
- const [isUploading, setIsUploading] = useState32(false);
14992
- const [progress, setProgress] = useState32(0);
14993
- const [bytesUploaded, setBytesUploaded] = useState32(0);
14994
- const [bytesTotal, setBytesTotal] = useState32(0);
14995
- const [error, setError] = useState32(null);
14996
- const [wasCancelled, setWasCancelled] = useState32(false);
14997
- const [url, setUrl] = useState32(null);
14998
- const abortControllerRef = useRef12(null);
14999
- const handleProgress = useCallback30((event) => {
15000
- setProgress(event.progress);
15001
- setBytesUploaded(event.loaded);
15002
- setBytesTotal(event.total);
15003
- }, []);
15004
- const cancel = useCallback30(() => {
15005
- if (abortControllerRef.current) {
15006
- abortControllerRef.current.abort();
15007
- abortControllerRef.current = null;
15008
- setWasCancelled(true);
15009
- setIsUploading(false);
15010
- options.onCancel?.();
15011
- }
15012
- }, [options]);
15013
- const upload = useCallback30(
15014
- async (file) => {
15015
- if (options.accept && options.accept.length > 0) {
15016
- const isAccepted = options.accept.some((type) => {
15017
- if (type.endsWith("/*")) {
15018
- const category = type.slice(0, -2);
15019
- return file.type.startsWith(category);
15020
- }
15021
- return file.type === type;
15022
- });
15023
- if (!isAccepted) {
15024
- const err = new Error(`File type ${file.type} not accepted`);
15025
- setError(err);
15026
- options.onError?.(err);
15027
- throw err;
15028
- }
15029
- }
15030
- if (options.maxSize && file.size > options.maxSize) {
15031
- const maxMB = (options.maxSize / 1024 / 1024).toFixed(1);
15032
- const err = new Error(`File size exceeds ${maxMB}MB limit`);
15033
- setError(err);
15034
- options.onError?.(err);
15035
- throw err;
15036
- }
15037
- const controller = new AbortController();
15038
- abortControllerRef.current = controller;
15039
- setIsUploading(true);
15040
- setProgress(0);
15041
- setBytesUploaded(0);
15042
- setBytesTotal(file.size);
15043
- setError(null);
15044
- setWasCancelled(false);
15045
- setUrl(null);
15046
- try {
15047
- const uploadedUrl = await ctx.upload(file, {
15048
- path: options.path,
15049
- signal: controller.signal,
15050
- onProgress: handleProgress
15051
- });
15052
- setProgress(100);
15053
- setUrl(uploadedUrl);
15054
- options.onSuccess?.(uploadedUrl);
15055
- return uploadedUrl;
15056
- } catch (err) {
15057
- if (err instanceof DOMException && err.name === "AbortError") {
15058
- setWasCancelled(true);
15059
- options.onCancel?.();
15060
- throw err;
15061
- }
15062
- const uploadError = err instanceof Error ? err : new Error("Upload failed");
15063
- setError(uploadError);
15064
- options.onError?.(uploadError);
15065
- throw uploadError;
15066
- } finally {
15067
- abortControllerRef.current = null;
15068
- setIsUploading(false);
15069
- }
15243
+ files: listQuery.data?.files,
15244
+ isUploading: uploadMutation.isPending,
15245
+ isLoadingFiles: listQuery.isLoading,
15246
+ error,
15247
+ refetch
15248
+ };
15249
+ }
15250
+ function useFile(fileId) {
15251
+ const config2 = useSdkConfig2();
15252
+ const query = useQuery7({
15253
+ queryKey: storageKeys.file(String(fileId)),
15254
+ queryFn: async () => {
15255
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15256
+ return storage.files.get(config2, fileId);
15070
15257
  },
15071
- [ctx, options, handleProgress]
15258
+ enabled: Boolean(config2 && fileId),
15259
+ staleTime: 6e4
15260
+ });
15261
+ return {
15262
+ file: query.data,
15263
+ isLoading: query.isLoading,
15264
+ error: query.error
15265
+ };
15266
+ }
15267
+ function useFileList(options = {}) {
15268
+ const config2 = useSdkConfig2();
15269
+ const [pages, setPages] = useState31(
15270
+ null
15072
15271
  );
15073
- const reset = useCallback30(() => {
15074
- setIsUploading(false);
15075
- setProgress(0);
15076
- setBytesUploaded(0);
15077
- setBytesTotal(0);
15078
- setError(null);
15079
- setWasCancelled(false);
15080
- setUrl(null);
15081
- }, []);
15272
+ const query = useQuery7({
15273
+ queryKey: storageKeys.list(options),
15274
+ queryFn: async () => {
15275
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15276
+ const page = await storage.files.list(config2, options).fetchPage(options.cursor);
15277
+ setPages({ files: [...page.files], nextCursor: page.nextCursor });
15278
+ return page;
15279
+ },
15280
+ enabled: Boolean(config2),
15281
+ staleTime: 6e4
15282
+ });
15283
+ const loadMore = useCallback29(async () => {
15284
+ if (!config2) return;
15285
+ const cursor = pages?.nextCursor;
15286
+ if (!cursor) return;
15287
+ const page = await storage.files.list(config2, options).fetchPage(cursor);
15288
+ setPages((prev) => ({
15289
+ files: [...prev?.files ?? [], ...page.files],
15290
+ nextCursor: page.nextCursor
15291
+ }));
15292
+ }, [config2, options, pages?.nextCursor]);
15082
15293
  return {
15083
- upload,
15084
- cancel,
15085
- isUploading,
15086
- progress,
15087
- bytesUploaded,
15088
- bytesTotal,
15089
- error,
15090
- isError: error !== null,
15091
- wasCancelled,
15092
- url,
15093
- reset
15294
+ files: pages?.files ?? query.data?.files ?? [],
15295
+ nextCursor: pages?.nextCursor ?? query.data?.nextCursor ?? null,
15296
+ isLoading: query.isLoading,
15297
+ loadMore
15094
15298
  };
15095
15299
  }
15096
15300
 
15097
15301
  // src/react/task-hooks.ts
15098
- import { useQuery as useQuery7, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
15099
- import { useCallback as useCallback31, useEffect as useEffect24, useRef as useRef13, useState as useState33 } from "react";
15302
+ import { useQuery as useQuery8, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
15303
+ import { useCallback as useCallback30, useEffect as useEffect24, useRef as useRef11, useState as useState32 } from "react";
15100
15304
  function useTasks() {
15101
15305
  const ctx = useTasksContext();
15102
- const [isLoading, setIsLoading] = useState33(false);
15103
- const [error, setError] = useState33(null);
15104
- const isAvailable = useCallback31(async () => {
15306
+ const [isLoading, setIsLoading] = useState32(false);
15307
+ const [error, setError] = useState32(null);
15308
+ const isAvailable = useCallback30(async () => {
15105
15309
  try {
15106
15310
  const status = await ctx.checkStatus();
15107
15311
  return status.available;
@@ -15109,7 +15313,7 @@ function useTasks() {
15109
15313
  return false;
15110
15314
  }
15111
15315
  }, [ctx]);
15112
- const schedule = useCallback31(
15316
+ const schedule = useCallback30(
15113
15317
  async (options) => {
15114
15318
  setIsLoading(true);
15115
15319
  setError(null);
@@ -15125,7 +15329,7 @@ function useTasks() {
15125
15329
  },
15126
15330
  [ctx]
15127
15331
  );
15128
- const createCron = useCallback31(
15332
+ const createCron = useCallback30(
15129
15333
  async (options) => {
15130
15334
  setIsLoading(true);
15131
15335
  setError(null);
@@ -15141,7 +15345,7 @@ function useTasks() {
15141
15345
  },
15142
15346
  [ctx]
15143
15347
  );
15144
- const pauseCron = useCallback31(
15348
+ const pauseCron = useCallback30(
15145
15349
  async (scheduleId) => {
15146
15350
  setIsLoading(true);
15147
15351
  setError(null);
@@ -15157,7 +15361,7 @@ function useTasks() {
15157
15361
  },
15158
15362
  [ctx]
15159
15363
  );
15160
- const resumeCron = useCallback31(
15364
+ const resumeCron = useCallback30(
15161
15365
  async (scheduleId) => {
15162
15366
  setIsLoading(true);
15163
15367
  setError(null);
@@ -15173,7 +15377,7 @@ function useTasks() {
15173
15377
  },
15174
15378
  [ctx]
15175
15379
  );
15176
- const deleteCron = useCallback31(
15380
+ const deleteCron = useCallback30(
15177
15381
  async (scheduleId) => {
15178
15382
  setIsLoading(true);
15179
15383
  setError(null);
@@ -15189,7 +15393,7 @@ function useTasks() {
15189
15393
  },
15190
15394
  [ctx]
15191
15395
  );
15192
- const getJob = useCallback31(
15396
+ const getJob = useCallback30(
15193
15397
  async (jobId) => {
15194
15398
  try {
15195
15399
  return await ctx.getJob(jobId);
@@ -15201,7 +15405,7 @@ function useTasks() {
15201
15405
  },
15202
15406
  [ctx]
15203
15407
  );
15204
- const listJobs = useCallback31(
15408
+ const listJobs = useCallback30(
15205
15409
  async (options = {}) => {
15206
15410
  try {
15207
15411
  const result = await ctx.listJobs(options);
@@ -15214,7 +15418,7 @@ function useTasks() {
15214
15418
  },
15215
15419
  [ctx]
15216
15420
  );
15217
- const cancelJob = useCallback31(
15421
+ const cancelJob = useCallback30(
15218
15422
  async (jobId) => {
15219
15423
  setIsLoading(true);
15220
15424
  setError(null);
@@ -15247,19 +15451,19 @@ function useTasks() {
15247
15451
 
15248
15452
  // src/react/webhooks-hooks.ts
15249
15453
  init_constants();
15250
- import { useInfiniteQuery as useInfiniteQuery2, useQuery as useQuery8, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
15251
- import { useCallback as useCallback32 } from "react";
15454
+ import { useInfiniteQuery as useInfiniteQuery2, useQuery as useQuery9, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
15455
+ import { useCallback as useCallback31 } from "react";
15252
15456
  function useWebhooks() {
15253
15457
  const ctx = useWebhooksContext();
15254
- const queryClient = useQueryClient7();
15255
- const configQuery = useQuery8({
15458
+ const queryClient = useQueryClient8();
15459
+ const configQuery = useQuery9({
15256
15460
  queryKey: ["sylphx", "webhooks", "config"],
15257
15461
  queryFn: () => ctx.getConfig(),
15258
15462
  staleTime: STALE_TIME_STABLE_MS
15259
15463
  // 5 min - config rarely changes
15260
15464
  });
15261
15465
  const config2 = configQuery.data;
15262
- const updateConfig = useCallback32(
15466
+ const updateConfig = useCallback31(
15263
15467
  async (options) => {
15264
15468
  const result = await ctx.updateConfig(options);
15265
15469
  await queryClient.invalidateQueries({
@@ -15269,7 +15473,7 @@ function useWebhooks() {
15269
15473
  },
15270
15474
  [ctx, queryClient]
15271
15475
  );
15272
- const refresh = useCallback32(async () => {
15476
+ const refresh = useCallback31(async () => {
15273
15477
  await queryClient.invalidateQueries({
15274
15478
  queryKey: ["sylphx", "webhooks", "config"]
15275
15479
  });
@@ -15286,7 +15490,7 @@ function useWebhooks() {
15286
15490
  function useWebhookDeliveries(options = {}) {
15287
15491
  const { status, event, limit = 50, skip = false, refetchInterval } = options;
15288
15492
  const ctx = useWebhooksContext();
15289
- const queryClient = useQueryClient7();
15493
+ const queryClient = useQueryClient8();
15290
15494
  const deliveriesQuery = useInfiniteQuery2({
15291
15495
  queryKey: ["sylphx", "webhooks", "deliveries", { status, event, limit }],
15292
15496
  queryFn: async ({ pageParam = 0 }) => {
@@ -15307,7 +15511,7 @@ function useWebhookDeliveries(options = {}) {
15307
15511
  });
15308
15512
  const deliveries = deliveriesQuery.data?.pages.flatMap((page) => page.deliveries) ?? [];
15309
15513
  const total = deliveriesQuery.data?.pages[0]?.total ?? 0;
15310
- const replay = useCallback32(
15514
+ const replay = useCallback31(
15311
15515
  async (deliveryId) => {
15312
15516
  const result = await ctx.replayDelivery(deliveryId);
15313
15517
  await queryClient.invalidateQueries({
@@ -15317,12 +15521,12 @@ function useWebhookDeliveries(options = {}) {
15317
15521
  },
15318
15522
  [ctx, queryClient]
15319
15523
  );
15320
- const refresh = useCallback32(async () => {
15524
+ const refresh = useCallback31(async () => {
15321
15525
  await queryClient.invalidateQueries({
15322
15526
  queryKey: ["sylphx", "webhooks", "deliveries"]
15323
15527
  });
15324
15528
  }, [queryClient]);
15325
- const loadMore = useCallback32(async () => {
15529
+ const loadMore = useCallback31(async () => {
15326
15530
  if (deliveriesQuery.hasNextPage && !deliveriesQuery.isFetchingNextPage) {
15327
15531
  await deliveriesQuery.fetchNextPage();
15328
15532
  }
@@ -15341,14 +15545,14 @@ function useWebhookDeliveries(options = {}) {
15341
15545
  }
15342
15546
  function useWebhookStats(period = "week") {
15343
15547
  const ctx = useWebhooksContext();
15344
- const queryClient = useQueryClient7();
15345
- const statsQuery = useQuery8({
15548
+ const queryClient = useQueryClient8();
15549
+ const statsQuery = useQuery9({
15346
15550
  queryKey: ["sylphx", "webhooks", "stats", period],
15347
15551
  queryFn: () => ctx.getStats(period),
15348
15552
  staleTime: STALE_TIME_MODERATE_MS
15349
15553
  // 2 min - stats aggregate data
15350
15554
  });
15351
- const refresh = useCallback32(async () => {
15555
+ const refresh = useCallback31(async () => {
15352
15556
  await queryClient.invalidateQueries({
15353
15557
  queryKey: ["sylphx", "webhooks", "stats", period]
15354
15558
  });
@@ -15363,7 +15567,7 @@ function useWebhookStats(period = "week") {
15363
15567
 
15364
15568
  // src/react/ui/account-section.tsx
15365
15569
  init_constants();
15366
- import { useCallback as useCallback33, useEffect as useEffect25, useId as useId4, useState as useState34 } from "react";
15570
+ import { useCallback as useCallback32, useEffect as useEffect25, useId as useId4, useState as useState33 } from "react";
15367
15571
  import { Fragment as Fragment18, jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
15368
15572
  function AccountSection(props) {
15369
15573
  return /* @__PURE__ */ jsx25(RequireSdk, { services: ["auth"], componentType: "account", theme: props.theme, children: /* @__PURE__ */ jsx25(AccountSectionInner, { ...props }) });
@@ -15385,22 +15589,22 @@ function AccountSectionInner({
15385
15589
  const styles2 = baseStyles(theme);
15386
15590
  const newEmailId = useId4();
15387
15591
  const emailPasswordId = useId4();
15388
- const [error, setError] = useState34(null);
15389
- const [success, setSuccess] = useState34(null);
15390
- const [showEmailChangeForm, setShowEmailChangeForm] = useState34(false);
15391
- const [newEmail, setNewEmail] = useState34("");
15392
- const [emailPassword, setEmailPassword] = useState34("");
15393
- const [isChangingEmail, setIsChangingEmail] = useState34(false);
15394
- const [isExporting, setIsExporting] = useState34(false);
15395
- const [exportUrl, setExportUrl] = useState34(null);
15396
- const [showDeleteConfirm, setShowDeleteConfirm] = useState34(false);
15397
- const [deleteConfirmText, setDeleteConfirmText] = useState34("");
15398
- const [deletePassword, setDeletePassword] = useState34("");
15399
- const [delete2FACode, setDelete2FACode] = useState34("");
15400
- const [isDeleting, setIsDeleting] = useState34(false);
15401
- const [deleteStep, setDeleteStep] = useState34("confirm");
15402
- const [has2FAEnabled, setHas2FAEnabled] = useState34(false);
15403
- const [isChecking2FA, setIsChecking2FA] = useState34(false);
15592
+ const [error, setError] = useState33(null);
15593
+ const [success, setSuccess] = useState33(null);
15594
+ const [showEmailChangeForm, setShowEmailChangeForm] = useState33(false);
15595
+ const [newEmail, setNewEmail] = useState33("");
15596
+ const [emailPassword, setEmailPassword] = useState33("");
15597
+ const [isChangingEmail, setIsChangingEmail] = useState33(false);
15598
+ const [isExporting, setIsExporting] = useState33(false);
15599
+ const [exportUrl, setExportUrl] = useState33(null);
15600
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState33(false);
15601
+ const [deleteConfirmText, setDeleteConfirmText] = useState33("");
15602
+ const [deletePassword, setDeletePassword] = useState33("");
15603
+ const [delete2FACode, setDelete2FACode] = useState33("");
15604
+ const [isDeleting, setIsDeleting] = useState33(false);
15605
+ const [deleteStep, setDeleteStep] = useState33("confirm");
15606
+ const [has2FAEnabled, setHas2FAEnabled] = useState33(false);
15607
+ const [isChecking2FA, setIsChecking2FA] = useState33(false);
15404
15608
  useEffect25(() => {
15405
15609
  injectGlobalStyles();
15406
15610
  }, []);
@@ -15454,7 +15658,7 @@ function AccountSectionInner({
15454
15658
  setIsExporting(false);
15455
15659
  }
15456
15660
  };
15457
- const checkSecurityStatus = useCallback33(async () => {
15661
+ const checkSecurityStatus = useCallback32(async () => {
15458
15662
  setIsChecking2FA(true);
15459
15663
  try {
15460
15664
  const status = await securityContext.getTwoFactorStatus();
@@ -15990,7 +16194,7 @@ function ShieldIcon({ size = 24, color = "currentColor" }) {
15990
16194
  }
15991
16195
 
15992
16196
  // src/react/ui/analytics-dashboard.tsx
15993
- import { useEffect as useEffect26, useState as useState35 } from "react";
16197
+ import { useEffect as useEffect26, useState as useState34 } from "react";
15994
16198
  import { Fragment as Fragment19, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
15995
16199
  function EventViewer({
15996
16200
  theme = defaultTheme,
@@ -16004,8 +16208,8 @@ function EventViewer({
16004
16208
  emptyMessage = "No events recorded yet",
16005
16209
  title = "Recent Events"
16006
16210
  }) {
16007
- const [search2, setSearch] = useState35("");
16008
- const [expandedId, setExpandedId] = useState35(null);
16211
+ const [search2, setSearch] = useState34("");
16212
+ const [expandedId, setExpandedId] = useState34(null);
16009
16213
  const styles2 = baseStyles(theme);
16010
16214
  useEffect26(() => {
16011
16215
  injectGlobalStyles();
@@ -16643,7 +16847,7 @@ function ChartIcon({ color }) {
16643
16847
 
16644
16848
  // src/react/ui/api-key-manager.tsx
16645
16849
  init_constants();
16646
- import { useEffect as useEffect27, useId as useId5, useState as useState36 } from "react";
16850
+ import { useEffect as useEffect27, useId as useId5, useState as useState35 } from "react";
16647
16851
  import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
16648
16852
  var DEFAULT_SCOPES = [
16649
16853
  "read:users",
@@ -16667,15 +16871,15 @@ function APIKeyManager({
16667
16871
  }) {
16668
16872
  const keyNameId = useId5();
16669
16873
  const expirationId = useId5();
16670
- const [showCreate, setShowCreate] = useState36(false);
16671
- const [name, setName] = useState36("");
16672
- const [selectedScopes, setSelectedScopes] = useState36([]);
16673
- const [expiresIn, setExpiresIn] = useState36(void 0);
16674
- const [isCreating, setIsCreating] = useState36(false);
16675
- const [error, setError] = useState36(null);
16676
- const [newKey, setNewKey] = useState36(null);
16677
- const [revokingId, setRevokingId] = useState36(null);
16678
- const [copied, setCopied] = useState36(false);
16874
+ const [showCreate, setShowCreate] = useState35(false);
16875
+ const [name, setName] = useState35("");
16876
+ const [selectedScopes, setSelectedScopes] = useState35([]);
16877
+ const [expiresIn, setExpiresIn] = useState35(void 0);
16878
+ const [isCreating, setIsCreating] = useState35(false);
16879
+ const [error, setError] = useState35(null);
16880
+ const [newKey, setNewKey] = useState35(null);
16881
+ const [revokingId, setRevokingId] = useState35(null);
16882
+ const [copied, setCopied] = useState35(false);
16679
16883
  const styles2 = baseStyles(theme);
16680
16884
  useEffect27(() => {
16681
16885
  injectGlobalStyles();
@@ -17262,7 +17466,7 @@ function CheckIcon10({ color }) {
17262
17466
  }
17263
17467
 
17264
17468
  // src/react/ui/billing-management.tsx
17265
- import { useEffect as useEffect28, useState as useState37 } from "react";
17469
+ import { useEffect as useEffect28, useState as useState36 } from "react";
17266
17470
  import { Fragment as Fragment20, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
17267
17471
  function InvoiceHistory({
17268
17472
  theme = defaultTheme,
@@ -17274,8 +17478,8 @@ function InvoiceHistory({
17274
17478
  pageSize = 10,
17275
17479
  emptyMessage = "No invoices yet"
17276
17480
  }) {
17277
- const [invoices] = useState37(propInvoices ?? []);
17278
- const [currentPage, setCurrentPage] = useState37(1);
17481
+ const [invoices] = useState36(propInvoices ?? []);
17482
+ const [currentPage, setCurrentPage] = useState36(1);
17279
17483
  const styles2 = baseStyles(theme);
17280
17484
  useEffect28(() => {
17281
17485
  injectGlobalStyles();
@@ -17899,7 +18103,7 @@ function PlusIcon4({ color }) {
17899
18103
 
17900
18104
  // src/react/ui/billing-section.tsx
17901
18105
  init_constants();
17902
- import { useEffect as useEffect29, useState as useState38 } from "react";
18106
+ import { useEffect as useEffect29, useState as useState37 } from "react";
17903
18107
  import { Fragment as Fragment21, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
17904
18108
  function BillingSection(props) {
17905
18109
  return /* @__PURE__ */ jsx29(RequireSdk, { services: ["billing"], componentType: "billing", theme: props.theme, children: /* @__PURE__ */ jsx29(BillingSectionInner, { ...props }) });
@@ -17926,10 +18130,10 @@ function BillingSectionInner({
17926
18130
  refresh: _refresh
17927
18131
  } = useBilling();
17928
18132
  const styles2 = baseStyles(theme);
17929
- const [selectedInterval, setSelectedInterval] = useState38("monthly");
17930
- const [processingPlan, setProcessingPlan] = useState38(null);
17931
- const [error, setError] = useState38(null);
17932
- const [success, setSuccess] = useState38(null);
18133
+ const [selectedInterval, setSelectedInterval] = useState37("monthly");
18134
+ const [processingPlan, setProcessingPlan] = useState37(null);
18135
+ const [error, setError] = useState37(null);
18136
+ const [success, setSuccess] = useState37(null);
17933
18137
  useEffect29(() => {
17934
18138
  injectGlobalStyles();
17935
18139
  }, []);
@@ -18316,8 +18520,8 @@ function CheckIcon11({ color }) {
18316
18520
  // src/react/ui/chat-interface.tsx
18317
18521
  import {
18318
18522
  useEffect as useEffect30,
18319
- useRef as useRef14,
18320
- useState as useState39
18523
+ useRef as useRef12,
18524
+ useState as useState38
18321
18525
  } from "react";
18322
18526
  import { Fragment as Fragment22, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
18323
18527
  function ChatInterface({
@@ -18342,9 +18546,9 @@ function ChatInterface({
18342
18546
  ...chatOptions
18343
18547
  }) {
18344
18548
  const { messages, send, isLoading, error, clear, retry } = useChat(chatOptions);
18345
- const [input, setInput] = useState39("");
18346
- const messagesEndRef = useRef14(null);
18347
- const inputRef = useRef14(null);
18549
+ const [input, setInput] = useState38("");
18550
+ const messagesEndRef = useRef12(null);
18551
+ const inputRef = useRef12(null);
18348
18552
  const styles2 = baseStyles(theme);
18349
18553
  useEffect30(() => {
18350
18554
  injectGlobalStyles();
@@ -18720,8 +18924,8 @@ function ChatInput({
18720
18924
  onSubmit,
18721
18925
  isLoading = false
18722
18926
  }) {
18723
- const [input, setInput] = useState39("");
18724
- const inputRef = useRef14(null);
18927
+ const [input, setInput] = useState38("");
18928
+ const inputRef = useRef12(null);
18725
18929
  const handleSubmit = (e2) => {
18726
18930
  e2?.preventDefault();
18727
18931
  if (!input.trim() || disabled || isLoading) return;
@@ -18823,7 +19027,7 @@ function SendIcon2({ color }) {
18823
19027
 
18824
19028
  // src/react/ui/consent-preferences.tsx
18825
19029
  init_constants();
18826
- import { useEffect as useEffect31, useState as useState40 } from "react";
19030
+ import { useEffect as useEffect31, useState as useState39 } from "react";
18827
19031
  import { Fragment as Fragment23, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
18828
19032
  var CATEGORY_INFO = {
18829
19033
  necessary: {
@@ -18875,8 +19079,8 @@ function ConsentPreferences({
18875
19079
  saveConsents,
18876
19080
  hasConsented
18877
19081
  } = useConsent();
18878
- const [isSaving, setIsSaving] = useState40(false);
18879
- const [saveSuccess, setSaveSuccess] = useState40(false);
19082
+ const [isSaving, setIsSaving] = useState39(false);
19083
+ const [saveSuccess, setSaveSuccess] = useState39(false);
18880
19084
  const styles2 = baseStyles(theme);
18881
19085
  useEffect31(() => {
18882
19086
  injectGlobalStyles();
@@ -19306,7 +19510,7 @@ function CheckIcon12({ color }) {
19306
19510
 
19307
19511
  // src/react/ui/cookie-banner.tsx
19308
19512
  init_constants();
19309
- import { useEffect as useEffect32, useState as useState41 } from "react";
19513
+ import { useEffect as useEffect32, useState as useState40 } from "react";
19310
19514
  import { Fragment as Fragment24, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
19311
19515
  function CookieBanner({
19312
19516
  theme = defaultTheme,
@@ -19333,8 +19537,8 @@ function CookieBanner({
19333
19537
  saveConsents,
19334
19538
  isLoading
19335
19539
  } = useConsent();
19336
- const [showCustomize, setShowCustomize] = useState41(false);
19337
- const [isVisible, setIsVisible] = useState41(false);
19540
+ const [showCustomize, setShowCustomize] = useState40(false);
19541
+ const [isVisible, setIsVisible] = useState40(false);
19338
19542
  const styles2 = baseStyles(theme);
19339
19543
  useEffect32(() => {
19340
19544
  injectGlobalStyles();
@@ -19707,7 +19911,7 @@ init_constants();
19707
19911
  import {
19708
19912
  Component,
19709
19913
  useEffect as useEffect33,
19710
- useState as useState42
19914
+ useState as useState41
19711
19915
  } from "react";
19712
19916
  import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
19713
19917
  var SylphxErrorBoundary = class extends Component {
@@ -19941,12 +20145,12 @@ function FeedbackWidget({
19941
20145
  position = "bottom-right",
19942
20146
  defaultOpen = false
19943
20147
  }) {
19944
- const [isOpen, setIsOpen] = useState42(defaultOpen);
19945
- const [message, setMessage] = useState42("");
19946
- const [email, setEmail] = useState42("");
19947
- const [isSubmitting, setIsSubmitting] = useState42(false);
19948
- const [isSuccess, setIsSuccess] = useState42(false);
19949
- const [error, setError] = useState42(null);
20148
+ const [isOpen, setIsOpen] = useState41(defaultOpen);
20149
+ const [message, setMessage] = useState41("");
20150
+ const [email, setEmail] = useState41("");
20151
+ const [isSubmitting, setIsSubmitting] = useState41(false);
20152
+ const [isSuccess, setIsSuccess] = useState41(false);
20153
+ const [error, setError] = useState41(null);
19950
20154
  const { captureMessage } = useErrorTracking();
19951
20155
  const styles2 = baseStyles(theme);
19952
20156
  useEffect33(() => {
@@ -20186,7 +20390,7 @@ function CheckCircleIcon({ color }) {
20186
20390
 
20187
20391
  // src/react/ui/feature-gate.tsx
20188
20392
  init_constants();
20189
- import { useContext as useContext17, useState as useState43 } from "react";
20393
+ import { useContext as useContext18, useState as useState42 } from "react";
20190
20394
  import { Fragment as Fragment25, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
20191
20395
  function FeatureGate({
20192
20396
  flag,
@@ -20254,8 +20458,8 @@ function FlagDevTools({
20254
20458
  defaultCollapsed = true,
20255
20459
  className
20256
20460
  }) {
20257
- const [isCollapsed, setIsCollapsed] = useState43(defaultCollapsed);
20258
- const context = useContext17(FeatureFlagContext);
20461
+ const [isCollapsed, setIsCollapsed] = useState42(defaultCollapsed);
20462
+ const context = useContext18(FeatureFlagContext);
20259
20463
  const styles2 = baseStyles(theme);
20260
20464
  if (!context) {
20261
20465
  return null;
@@ -20489,8 +20693,54 @@ function CloseIcon4() {
20489
20693
 
20490
20694
  // src/react/ui/file-upload.tsx
20491
20695
  init_constants();
20492
- import { useCallback as useCallback34, useEffect as useEffect34, useRef as useRef15, useState as useState44 } from "react";
20696
+ import { useCallback as useCallback33, useEffect as useEffect34, useRef as useRef13, useState as useState43 } from "react";
20493
20697
  import { Fragment as Fragment26, jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
20698
+ function useUploadAdapter(options = {}) {
20699
+ const { upload: doUpload, isUploading } = useStorage();
20700
+ const [progress, setProgress] = useState43(0);
20701
+ const [error, setError] = useState43(null);
20702
+ const upload = useCallback33(
20703
+ async (file) => {
20704
+ setError(null);
20705
+ setProgress(0);
20706
+ if (options.accept && options.accept.length > 0) {
20707
+ const accepted = options.accept.some(
20708
+ (t2) => t2.endsWith("/*") ? file.type.startsWith(t2.slice(0, -2)) : file.type === t2
20709
+ );
20710
+ if (!accepted) {
20711
+ const e2 = new Error(`File type ${file.type} not accepted`);
20712
+ setError(e2);
20713
+ options.onError?.(e2);
20714
+ throw e2;
20715
+ }
20716
+ }
20717
+ if (options.maxSize && file.size > options.maxSize) {
20718
+ const mb = (options.maxSize / 1024 / 1024).toFixed(1);
20719
+ const e2 = new Error(`File size exceeds ${mb}MB limit`);
20720
+ setError(e2);
20721
+ options.onError?.(e2);
20722
+ throw e2;
20723
+ }
20724
+ try {
20725
+ const result = await doUpload(file, {
20726
+ folder: options.folder,
20727
+ onProgress: (e2) => {
20728
+ setProgress(e2.total > 0 ? Math.round(e2.loaded / e2.total * 100) : 0);
20729
+ }
20730
+ });
20731
+ setProgress(100);
20732
+ return result.url ?? "";
20733
+ } catch (err) {
20734
+ const e2 = err instanceof Error ? err : new Error("Upload failed");
20735
+ setError(e2);
20736
+ options.onError?.(e2);
20737
+ throw e2;
20738
+ }
20739
+ },
20740
+ [doUpload, options.accept, options.maxSize, options.folder, options.onError]
20741
+ );
20742
+ return { upload, isUploading, progress, error };
20743
+ }
20494
20744
  function FileUpload(props) {
20495
20745
  return /* @__PURE__ */ jsx35(RequireSdk, { services: ["storage"], componentType: "storage", theme: props.theme, children: /* @__PURE__ */ jsx35(FileUploadInner, { ...props }) });
20496
20746
  }
@@ -20506,10 +20756,10 @@ function FileUploadInner({
20506
20756
  placeholder = "Drop files here or click to upload",
20507
20757
  showFileList = true
20508
20758
  }) {
20509
- const [isDragging, setIsDragging] = useState44(false);
20510
- const [uploadedFiles, setUploadedFiles] = useState44([]);
20511
- const inputRef = useRef15(null);
20512
- const { upload, isUploading, progress, error } = useFileUpload({
20759
+ const [isDragging, setIsDragging] = useState43(false);
20760
+ const [uploadedFiles, setUploadedFiles] = useState43([]);
20761
+ const inputRef = useRef13(null);
20762
+ const { upload, isUploading, progress, error } = useUploadAdapter({
20513
20763
  accept,
20514
20764
  maxSize,
20515
20765
  onError
@@ -20518,7 +20768,7 @@ function FileUploadInner({
20518
20768
  useEffect34(() => {
20519
20769
  injectGlobalStyles();
20520
20770
  }, []);
20521
- const handleFiles = useCallback34(
20771
+ const handleFiles = useCallback33(
20522
20772
  async (files) => {
20523
20773
  if (!files || files.length === 0) return;
20524
20774
  const fileArray = Array.from(files);
@@ -20537,7 +20787,7 @@ function FileUploadInner({
20537
20787
  },
20538
20788
  [upload, onUpload]
20539
20789
  );
20540
- const handleDrop = useCallback34(
20790
+ const handleDrop = useCallback33(
20541
20791
  (e2) => {
20542
20792
  e2.preventDefault();
20543
20793
  e2.stopPropagation();
@@ -20547,7 +20797,7 @@ function FileUploadInner({
20547
20797
  },
20548
20798
  [handleFiles, disabled]
20549
20799
  );
20550
- const handleDragOver = useCallback34(
20800
+ const handleDragOver = useCallback33(
20551
20801
  (e2) => {
20552
20802
  e2.preventDefault();
20553
20803
  e2.stopPropagation();
@@ -20555,7 +20805,7 @@ function FileUploadInner({
20555
20805
  },
20556
20806
  [disabled]
20557
20807
  );
20558
- const handleDragLeave = useCallback34((e2) => {
20808
+ const handleDragLeave = useCallback33((e2) => {
20559
20809
  e2.preventDefault();
20560
20810
  e2.stopPropagation();
20561
20811
  setIsDragging(false);
@@ -20718,9 +20968,9 @@ function ImageUploaderInner({
20718
20968
  aspectRatio = "1:1",
20719
20969
  placeholder = "Click to upload image"
20720
20970
  }) {
20721
- const [previewUrl, setPreviewUrl] = useState44(value || null);
20722
- const inputRef = useRef15(null);
20723
- const { upload, isUploading, progress, error } = useFileUpload({
20971
+ const [previewUrl, setPreviewUrl] = useState43(value || null);
20972
+ const inputRef = useRef13(null);
20973
+ const { upload, isUploading, progress, error } = useUploadAdapter({
20724
20974
  accept: ["image/*"],
20725
20975
  maxSize,
20726
20976
  onError
@@ -20914,9 +21164,14 @@ function AvatarUploadInner({
20914
21164
  size = 96,
20915
21165
  placeholder = ""
20916
21166
  }) {
20917
- const [previewUrl, setPreviewUrl] = useState44(value || null);
20918
- const inputRef = useRef15(null);
20919
- const { uploadAvatar, isUploading, uploadError } = useStorage();
21167
+ const [previewUrl, setPreviewUrl] = useState43(value || null);
21168
+ const inputRef = useRef13(null);
21169
+ const { upload, isUploading, error } = useUploadAdapter({
21170
+ accept: ["image/*"],
21171
+ maxSize,
21172
+ folder: "avatars",
21173
+ onError
21174
+ });
20920
21175
  const styles2 = baseStyles(theme);
20921
21176
  useEffect34(() => {
20922
21177
  setPreviewUrl(value || null);
@@ -20925,18 +21180,10 @@ function AvatarUploadInner({
20925
21180
  injectGlobalStyles();
20926
21181
  }, []);
20927
21182
  const handleFile = async (file) => {
20928
- if (maxSize && file.size > maxSize) {
20929
- onError?.(new Error(`File size exceeds ${formatFileSize(maxSize)} limit`));
20930
- return;
20931
- }
20932
- if (!file.type.startsWith("image/")) {
20933
- onError?.(new Error("Please upload an image file"));
20934
- return;
20935
- }
20936
21183
  try {
20937
21184
  const localUrl = URL.createObjectURL(file);
20938
21185
  setPreviewUrl(localUrl);
20939
- const url = await uploadAvatar(file);
21186
+ const url = await upload(file);
20940
21187
  setPreviewUrl(url);
20941
21188
  onChange?.(url);
20942
21189
  URL.revokeObjectURL(localUrl);
@@ -21038,14 +21285,14 @@ function AvatarUploadInner({
21038
21285
  ]
21039
21286
  }
21040
21287
  ),
21041
- uploadError && /* @__PURE__ */ jsx35(
21288
+ error && /* @__PURE__ */ jsx35(
21042
21289
  "p",
21043
21290
  {
21044
21291
  style: mergeStyles(styles2.textXs, {
21045
21292
  color: theme.colorDestructive,
21046
21293
  marginTop: "0.5rem"
21047
21294
  }),
21048
- children: uploadError.message
21295
+ children: error.message
21049
21296
  }
21050
21297
  )
21051
21298
  ] });
@@ -21181,17 +21428,17 @@ function CloseIcon5() {
21181
21428
 
21182
21429
  // src/react/ui/job-scheduler.tsx
21183
21430
  init_constants();
21184
- import { useMutation as useMutation2, useQuery as useQuery10, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
21185
- import { useCallback as useCallback36, useEffect as useEffect36, useState as useState46 } from "react";
21431
+ import { useMutation as useMutation3, useQuery as useQuery11, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
21432
+ import { useCallback as useCallback35, useEffect as useEffect36, useState as useState45 } from "react";
21186
21433
 
21187
21434
  // src/react/job-hooks.ts
21188
- import { useQuery as useQuery9, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
21189
- import { useCallback as useCallback35, useEffect as useEffect35, useRef as useRef16, useState as useState45 } from "react";
21435
+ import { useQuery as useQuery10, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
21436
+ import { useCallback as useCallback34, useEffect as useEffect35, useRef as useRef14, useState as useState44 } from "react";
21190
21437
  function useJobs() {
21191
21438
  const ctx = useJobsContext();
21192
- const [isLoading, setIsLoading] = useState45(false);
21193
- const [error, setError] = useState45(null);
21194
- const isAvailable = useCallback35(async () => {
21439
+ const [isLoading, setIsLoading] = useState44(false);
21440
+ const [error, setError] = useState44(null);
21441
+ const isAvailable = useCallback34(async () => {
21195
21442
  try {
21196
21443
  const status = await ctx.checkStatus();
21197
21444
  return status.available;
@@ -21199,7 +21446,7 @@ function useJobs() {
21199
21446
  return false;
21200
21447
  }
21201
21448
  }, [ctx]);
21202
- const schedule = useCallback35(
21449
+ const schedule = useCallback34(
21203
21450
  async (options) => {
21204
21451
  setIsLoading(true);
21205
21452
  setError(null);
@@ -21215,7 +21462,7 @@ function useJobs() {
21215
21462
  },
21216
21463
  [ctx]
21217
21464
  );
21218
- const createCron = useCallback35(
21465
+ const createCron = useCallback34(
21219
21466
  async (options) => {
21220
21467
  setIsLoading(true);
21221
21468
  setError(null);
@@ -21231,7 +21478,7 @@ function useJobs() {
21231
21478
  },
21232
21479
  [ctx]
21233
21480
  );
21234
- const pauseCron = useCallback35(
21481
+ const pauseCron = useCallback34(
21235
21482
  async (scheduleId) => {
21236
21483
  setIsLoading(true);
21237
21484
  setError(null);
@@ -21247,7 +21494,7 @@ function useJobs() {
21247
21494
  },
21248
21495
  [ctx]
21249
21496
  );
21250
- const resumeCron = useCallback35(
21497
+ const resumeCron = useCallback34(
21251
21498
  async (scheduleId) => {
21252
21499
  setIsLoading(true);
21253
21500
  setError(null);
@@ -21263,7 +21510,7 @@ function useJobs() {
21263
21510
  },
21264
21511
  [ctx]
21265
21512
  );
21266
- const deleteCron = useCallback35(
21513
+ const deleteCron = useCallback34(
21267
21514
  async (scheduleId) => {
21268
21515
  setIsLoading(true);
21269
21516
  setError(null);
@@ -21279,7 +21526,7 @@ function useJobs() {
21279
21526
  },
21280
21527
  [ctx]
21281
21528
  );
21282
- const getJob = useCallback35(
21529
+ const getJob = useCallback34(
21283
21530
  async (jobId) => {
21284
21531
  try {
21285
21532
  return await ctx.getJob(jobId);
@@ -21291,7 +21538,7 @@ function useJobs() {
21291
21538
  },
21292
21539
  [ctx]
21293
21540
  );
21294
- const listJobs = useCallback35(
21541
+ const listJobs = useCallback34(
21295
21542
  async (options = {}) => {
21296
21543
  try {
21297
21544
  const result = await ctx.listJobs(options);
@@ -21304,7 +21551,7 @@ function useJobs() {
21304
21551
  },
21305
21552
  [ctx]
21306
21553
  );
21307
- const cancelJob = useCallback35(
21554
+ const cancelJob = useCallback34(
21308
21555
  async (jobId) => {
21309
21556
  setIsLoading(true);
21310
21557
  setError(null);
@@ -21345,14 +21592,14 @@ function JobScheduler({
21345
21592
  showCronTab = true
21346
21593
  }) {
21347
21594
  const { schedule, createCron, isLoading, error } = useJobs();
21348
- const [activeTab, setActiveTab] = useState46("one-time");
21349
- const [name, setName] = useState46("");
21350
- const [callbackUrl, setCallbackUrl] = useState46(defaultCallbackUrl);
21351
- const [payload, setPayload] = useState46("{}");
21352
- const [delay2, setDelay] = useState46(60);
21353
- const [delayUnit, setDelayUnit] = useState46("seconds");
21354
- const [cronExpression, setCronExpression] = useState46("0 9 * * *");
21355
- const [scheduleSuccess, setScheduleSuccess] = useState46(false);
21595
+ const [activeTab, setActiveTab] = useState45("one-time");
21596
+ const [name, setName] = useState45("");
21597
+ const [callbackUrl, setCallbackUrl] = useState45(defaultCallbackUrl);
21598
+ const [payload, setPayload] = useState45("{}");
21599
+ const [delay2, setDelay] = useState45(60);
21600
+ const [delayUnit, setDelayUnit] = useState45("seconds");
21601
+ const [cronExpression, setCronExpression] = useState45("0 9 * * *");
21602
+ const [scheduleSuccess, setScheduleSuccess] = useState45(false);
21356
21603
  const styles2 = baseStyles(theme);
21357
21604
  useEffect36(() => {
21358
21605
  injectGlobalStyles();
@@ -21694,13 +21941,13 @@ function JobList({
21694
21941
  emptyMessage = "No jobs scheduled"
21695
21942
  }) {
21696
21943
  const ctx = useJobsContext();
21697
- const queryClient = useQueryClient9();
21698
- const [filter, setFilter] = useState46("all");
21944
+ const queryClient = useQueryClient10();
21945
+ const [filter, setFilter] = useState45("all");
21699
21946
  const styles2 = baseStyles(theme);
21700
21947
  useEffect36(() => {
21701
21948
  injectGlobalStyles();
21702
21949
  }, []);
21703
- const jobsQuery = useQuery10({
21950
+ const jobsQuery = useQuery11({
21704
21951
  queryKey: ["sylphx", "jobs", "list", filter],
21705
21952
  queryFn: async () => {
21706
21953
  const apiStatus = filter === "all" || filter === "cancelled" ? void 0 : filter;
@@ -21716,13 +21963,13 @@ function JobList({
21716
21963
  const jobs = propJobs ?? jobsQuery.data ?? [];
21717
21964
  const isLoading = !propJobs && jobsQuery.isLoading;
21718
21965
  const filteredJobs = filter === "all" ? jobs : jobs.filter((j) => j.status === filter);
21719
- const cancelMutation = useMutation2({
21966
+ const cancelMutation = useMutation3({
21720
21967
  mutationFn: (jobId) => ctx.cancelJob(jobId),
21721
21968
  onSuccess: () => {
21722
21969
  queryClient.invalidateQueries({ queryKey: ["sylphx", "jobs", "list"] });
21723
21970
  }
21724
21971
  });
21725
- const handleCancel = useCallback36(
21972
+ const handleCancel = useCallback35(
21726
21973
  async (jobId) => {
21727
21974
  if (onCancel) {
21728
21975
  onCancel(jobId);
@@ -21912,9 +22159,9 @@ function CronBuilder({
21912
22159
  onCreate,
21913
22160
  defaultCallbackUrl = ""
21914
22161
  }) {
21915
- const [expression, setExpression] = useState46("0 9 * * *");
21916
- const [callbackUrl, setCallbackUrl] = useState46(defaultCallbackUrl);
21917
- const [name, setName] = useState46("");
22162
+ const [expression, setExpression] = useState45("0 9 * * *");
22163
+ const [callbackUrl, setCallbackUrl] = useState45(defaultCallbackUrl);
22164
+ const [name, setName] = useState45("");
21918
22165
  const styles2 = baseStyles(theme);
21919
22166
  useEffect36(() => {
21920
22167
  injectGlobalStyles();
@@ -22155,7 +22402,7 @@ function JobIcon({ color, size = 24 }) {
22155
22402
  var TaskScheduler = JobScheduler;
22156
22403
 
22157
22404
  // src/react/ui/model-selector.tsx
22158
- import { useEffect as useEffect37, useRef as useRef17, useState as useState47 } from "react";
22405
+ import { useEffect as useEffect37, useRef as useRef15, useState as useState46 } from "react";
22159
22406
  import { Fragment as Fragment27, jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
22160
22407
  function ModelSelector({
22161
22408
  theme = defaultTheme,
@@ -22170,10 +22417,10 @@ function ModelSelector({
22170
22417
  compact = false
22171
22418
  }) {
22172
22419
  const styles2 = baseStyles(theme);
22173
- const [isOpen, setIsOpen] = useState47(false);
22174
- const [searchValue, setSearchValue] = useState47("");
22175
- const containerRef = useRef17(null);
22176
- const inputRef = useRef17(null);
22420
+ const [isOpen, setIsOpen] = useState46(false);
22421
+ const [searchValue, setSearchValue] = useState46("");
22422
+ const containerRef = useRef15(null);
22423
+ const inputRef = useRef15(null);
22177
22424
  const { models, isLoading, error, setSearch, hasMore, loadMore } = useModels({
22178
22425
  capability,
22179
22426
  fetchOnMount: true,
@@ -22702,8 +22949,8 @@ function ModelGrid({
22702
22949
  fetchOnMount: true,
22703
22950
  pageSize: 24
22704
22951
  });
22705
- const [searchValue, setSearchValue] = useState47("");
22706
- const [filterCapability, setFilterCapability] = useState47(capability);
22952
+ const [searchValue, setSearchValue] = useState46("");
22953
+ const [filterCapability, setFilterCapability] = useState46(capability);
22707
22954
  useEffect37(() => {
22708
22955
  injectGlobalStyles();
22709
22956
  }, []);
@@ -22807,7 +23054,7 @@ function ModelGrid({
22807
23054
 
22808
23055
  // src/react/ui/newsletter-form.tsx
22809
23056
  import { EMAIL_REGEX } from "@sylphx/contract";
22810
- import { useEffect as useEffect38, useState as useState48 } from "react";
23057
+ import { useEffect as useEffect38, useState as useState47 } from "react";
22811
23058
  import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
22812
23059
  function NewsletterForm({
22813
23060
  theme = defaultTheme,
@@ -22838,7 +23085,7 @@ function NewsletterForm({
22838
23085
  reset
22839
23086
  } = useSubscriberForm();
22840
23087
  const styles2 = baseStyles(theme);
22841
- const [localError, setLocalError] = useState48(null);
23088
+ const [localError, setLocalError] = useState47(null);
22842
23089
  useEffect38(() => {
22843
23090
  injectGlobalStyles();
22844
23091
  }, []);
@@ -23022,7 +23269,7 @@ function NewsletterForm({
23022
23269
 
23023
23270
  // src/react/ui/notification-settings.tsx
23024
23271
  init_constants();
23025
- import { useEffect as useEffect39, useState as useState49 } from "react";
23272
+ import { useEffect as useEffect39, useState as useState48 } from "react";
23026
23273
  import { jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
23027
23274
  function NotificationSettings({
23028
23275
  theme = defaultTheme,
@@ -23042,10 +23289,10 @@ function NotificationSettings({
23042
23289
  updatePreferences
23043
23290
  } = useNotifications();
23044
23291
  const styles2 = baseStyles(theme);
23045
- const [error, setError] = useState49(null);
23046
- const [success, setSuccess] = useState49(null);
23047
- const [isTogglingPush, setIsTogglingPush] = useState49(false);
23048
- const [localPrefs, setLocalPrefs] = useState49(
23292
+ const [error, setError] = useState48(null);
23293
+ const [success, setSuccess] = useState48(null);
23294
+ const [isTogglingPush, setIsTogglingPush] = useState48(false);
23295
+ const [localPrefs, setLocalPrefs] = useState48(
23049
23296
  () => preferences?.categories ?? {}
23050
23297
  );
23051
23298
  useEffect39(() => {
@@ -23291,7 +23538,7 @@ function BellOffIcon({ size = 24 }) {
23291
23538
 
23292
23539
  // src/react/ui/organization-management.tsx
23293
23540
  init_constants();
23294
- import { useEffect as useEffect40, useId as useId6, useState as useState50 } from "react";
23541
+ import { useEffect as useEffect40, useId as useId6, useState as useState49 } from "react";
23295
23542
  import { Fragment as Fragment28, jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
23296
23543
  function OrganizationProfile(props) {
23297
23544
  return /* @__PURE__ */ jsx40(RequireSdk, { services: ["organization"], componentType: "organization", theme: props.theme, children: /* @__PURE__ */ jsx40(OrganizationProfileInner, { ...props }) });
@@ -23312,12 +23559,12 @@ function OrganizationProfileInner({
23312
23559
  const nameId = useId6();
23313
23560
  const slugId = useId6();
23314
23561
  const deleteConfirmId = useId6();
23315
- const [name, setName] = useState50(org?.name ?? "");
23316
- const [slug, setSlug] = useState50(org?.slug ?? "");
23317
- const [isSaving, setIsSaving] = useState50(false);
23318
- const [isDeleting, setIsDeleting] = useState50(false);
23319
- const [saveSuccess, setSaveSuccess] = useState50(false);
23320
- const [deleteConfirm, setDeleteConfirm] = useState50("");
23562
+ const [name, setName] = useState49(org?.name ?? "");
23563
+ const [slug, setSlug] = useState49(org?.slug ?? "");
23564
+ const [isSaving, setIsSaving] = useState49(false);
23565
+ const [isDeleting, setIsDeleting] = useState49(false);
23566
+ const [saveSuccess, setSaveSuccess] = useState49(false);
23567
+ const [deleteConfirm, setDeleteConfirm] = useState49("");
23321
23568
  const styles2 = baseStyles(theme);
23322
23569
  useEffect40(() => {
23323
23570
  injectGlobalStyles();
@@ -23685,10 +23932,10 @@ function CreateOrganization({
23685
23932
  }) {
23686
23933
  const createNameId = useId6();
23687
23934
  const createSlugId = useId6();
23688
- const [name, setName] = useState50("");
23689
- const [slug, setSlug] = useState50("");
23690
- const [isCreating, setIsCreating] = useState50(false);
23691
- const [error, setError] = useState50(null);
23935
+ const [name, setName] = useState49("");
23936
+ const [slug, setSlug] = useState49("");
23937
+ const [isCreating, setIsCreating] = useState49(false);
23938
+ const [error, setError] = useState49(null);
23692
23939
  const styles2 = baseStyles(theme);
23693
23940
  useEffect40(() => {
23694
23941
  injectGlobalStyles();
@@ -24041,7 +24288,7 @@ function PlusIcon5({ color }) {
24041
24288
 
24042
24289
  // src/react/ui/push-notifications.tsx
24043
24290
  init_constants();
24044
- import { useEffect as useEffect41, useState as useState51 } from "react";
24291
+ import { useEffect as useEffect41, useState as useState50 } from "react";
24045
24292
  import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
24046
24293
  function PushPrompt({
24047
24294
  theme = defaultTheme,
@@ -24057,8 +24304,8 @@ function PushPrompt({
24057
24304
  autoShow = true,
24058
24305
  showDelay = UI_PROMPT_DELAY_MS
24059
24306
  }) {
24060
- const [isVisible, setIsVisible] = useState51(false);
24061
- const [isAnimatingOut, setIsAnimatingOut] = useState51(false);
24307
+ const [isVisible, setIsVisible] = useState50(false);
24308
+ const [isAnimatingOut, setIsAnimatingOut] = useState50(false);
24062
24309
  const { isSupported, isSubscribed, subscribe, error } = useNotifications();
24063
24310
  const styles2 = baseStyles(theme);
24064
24311
  useEffect41(() => {
@@ -24400,7 +24647,7 @@ function NotificationItem({
24400
24647
  onDelete
24401
24648
  }) {
24402
24649
  const styles2 = baseStyles(theme);
24403
- const [showActions, setShowActions] = useState51(false);
24650
+ const [showActions, setShowActions] = useState50(false);
24404
24651
  const itemStyle = {
24405
24652
  position: "relative",
24406
24653
  display: "flex",
@@ -24643,7 +24890,7 @@ function TrashIcon3({ color }) {
24643
24890
 
24644
24891
  // src/react/ui/referral-card.tsx
24645
24892
  init_constants();
24646
- import { useEffect as useEffect42, useId as useId7, useState as useState52 } from "react";
24893
+ import { useEffect as useEffect42, useId as useId7, useState as useState51 } from "react";
24647
24894
  import { Fragment as Fragment29, jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
24648
24895
  function ReferralCard(props) {
24649
24896
  return /* @__PURE__ */ jsx42(RequireSdk, { services: ["analytics"], componentType: "referral", theme: props.theme, children: /* @__PURE__ */ jsx42(ReferralCardInner, { ...props }) });
@@ -24671,9 +24918,9 @@ function ReferralCardInner({
24671
24918
  } = useReferral();
24672
24919
  const styles2 = baseStyles(theme);
24673
24920
  const linkId = useId7();
24674
- const [copied, setCopied] = useState52(null);
24675
- const [isRegenerating, setIsRegenerating] = useState52(false);
24676
- const [error, setError] = useState52(null);
24921
+ const [copied, setCopied] = useState51(null);
24922
+ const [isRegenerating, setIsRegenerating] = useState51(false);
24923
+ const [error, setError] = useState51(null);
24677
24924
  useEffect42(() => {
24678
24925
  injectGlobalStyles();
24679
24926
  }, []);
@@ -25111,8 +25358,8 @@ function EmailIcon({ size = 24 }) {
25111
25358
 
25112
25359
  // src/react/ui/security-settings.tsx
25113
25360
  init_constants();
25114
- import { useMutation as useMutation3, useQuery as useQuery11, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
25115
- import { useCallback as useCallback37, useEffect as useEffect43, useId as useId8, useState as useState53 } from "react";
25361
+ import { useMutation as useMutation4, useQuery as useQuery12, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
25362
+ import { useCallback as useCallback36, useEffect as useEffect43, useId as useId8, useState as useState52 } from "react";
25116
25363
  import { Fragment as Fragment30, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
25117
25364
  function SecuritySettings({
25118
25365
  theme = defaultTheme,
@@ -25126,26 +25373,26 @@ function SecuritySettings({
25126
25373
  }) {
25127
25374
  const userContext = useUserContext();
25128
25375
  const securityContext = useSecurityContext();
25129
- const queryClient = useQueryClient10();
25376
+ const queryClient = useQueryClient11();
25130
25377
  const styles2 = baseStyles(theme);
25131
25378
  const verifyCodeId = useId8();
25132
25379
  const currentPasswordId = useId8();
25133
25380
  const newPasswordId = useId8();
25134
25381
  const confirmPasswordId = useId8();
25135
- const [error, setError] = useState53(null);
25136
- const [success, setSuccess] = useState53(null);
25137
- const [showSetup2FA, setShowSetup2FA] = useState53(false);
25138
- const [totpSecret, setTotpSecret] = useState53(null);
25139
- const [totpQrCode, setTotpQrCode] = useState53(null);
25140
- const [verifyCode, setVerifyCode] = useState53("");
25141
- const [showPasswordChange, setShowPasswordChange] = useState53(false);
25142
- const [currentPassword, setCurrentPassword] = useState53("");
25143
- const [newPassword, setNewPassword] = useState53("");
25144
- const [confirmPassword, setConfirmPassword] = useState53("");
25382
+ const [error, setError] = useState52(null);
25383
+ const [success, setSuccess] = useState52(null);
25384
+ const [showSetup2FA, setShowSetup2FA] = useState52(false);
25385
+ const [totpSecret, setTotpSecret] = useState52(null);
25386
+ const [totpQrCode, setTotpQrCode] = useState52(null);
25387
+ const [verifyCode, setVerifyCode] = useState52("");
25388
+ const [showPasswordChange, setShowPasswordChange] = useState52(false);
25389
+ const [currentPassword, setCurrentPassword] = useState52("");
25390
+ const [newPassword, setNewPassword] = useState52("");
25391
+ const [confirmPassword, setConfirmPassword] = useState52("");
25145
25392
  useEffect43(() => {
25146
25393
  injectGlobalStyles();
25147
25394
  }, []);
25148
- const twoFactorQuery = useQuery11({
25395
+ const twoFactorQuery = useQuery12({
25149
25396
  queryKey: ["sylphx", "security", "2fa-status"],
25150
25397
  queryFn: async () => {
25151
25398
  const data = await securityContext.getTwoFactorStatus();
@@ -25158,7 +25405,7 @@ function SecuritySettings({
25158
25405
  staleTime: STALE_TIME_STABLE_MS
25159
25406
  // 5 min
25160
25407
  });
25161
- const sessionsQuery = useQuery11({
25408
+ const sessionsQuery = useQuery12({
25162
25409
  queryKey: ["sylphx", "security", "sessions"],
25163
25410
  queryFn: async () => {
25164
25411
  const data = await userContext.getSessions();
@@ -25177,7 +25424,7 @@ function SecuritySettings({
25177
25424
  staleTime: STALE_TIME_FREQUENT_MS
25178
25425
  // 1 min - sessions can change
25179
25426
  });
25180
- const loginHistoryQuery = useQuery11({
25427
+ const loginHistoryQuery = useQuery12({
25181
25428
  queryKey: ["sylphx", "security", "login-history"],
25182
25429
  queryFn: async () => {
25183
25430
  const data = await userContext.getLoginHistory({ limit: 10 });
@@ -25216,7 +25463,7 @@ function SecuritySettings({
25216
25463
  return () => clearTimeout(timer);
25217
25464
  }
25218
25465
  }, [success, error]);
25219
- const setup2FAMutation = useMutation3({
25466
+ const setup2FAMutation = useMutation4({
25220
25467
  mutationFn: () => securityContext.twoFactorSetup(),
25221
25468
  onSuccess: (data) => {
25222
25469
  setTotpSecret(data.secret);
@@ -25229,7 +25476,7 @@ function SecuritySettings({
25229
25476
  onError?.(message);
25230
25477
  }
25231
25478
  });
25232
- const enable2FAMutation = useMutation3({
25479
+ const enable2FAMutation = useMutation4({
25233
25480
  mutationFn: (code) => securityContext.twoFactorVerify(code),
25234
25481
  onSuccess: () => {
25235
25482
  queryClient.setQueryData(["sylphx", "security", "2fa-status"], {
@@ -25247,7 +25494,7 @@ function SecuritySettings({
25247
25494
  onError?.(message);
25248
25495
  }
25249
25496
  });
25250
- const disable2FAMutation = useMutation3({
25497
+ const disable2FAMutation = useMutation4({
25251
25498
  mutationFn: (code) => securityContext.twoFactorDisable(code),
25252
25499
  onSuccess: () => {
25253
25500
  queryClient.setQueryData(["sylphx", "security", "2fa-status"], {
@@ -25262,7 +25509,7 @@ function SecuritySettings({
25262
25509
  onError?.(message);
25263
25510
  }
25264
25511
  });
25265
- const changePasswordMutation = useMutation3({
25512
+ const changePasswordMutation = useMutation4({
25266
25513
  mutationFn: ({ current, newPwd }) => userContext.changePassword(current, newPwd),
25267
25514
  onSuccess: () => {
25268
25515
  setShowPasswordChange(false);
@@ -25278,7 +25525,7 @@ function SecuritySettings({
25278
25525
  onError?.(message);
25279
25526
  }
25280
25527
  });
25281
- const revokeSessionMutation = useMutation3({
25528
+ const revokeSessionMutation = useMutation4({
25282
25529
  mutationFn: (sessionId) => userContext.revokeSession(sessionId),
25283
25530
  onSuccess: (_data, sessionId) => {
25284
25531
  queryClient.setQueryData(
@@ -25294,7 +25541,7 @@ function SecuritySettings({
25294
25541
  onError?.(message);
25295
25542
  }
25296
25543
  });
25297
- const revokeAllSessionsMutation = useMutation3({
25544
+ const revokeAllSessionsMutation = useMutation4({
25298
25545
  mutationFn: () => userContext.revokeAllSessions(),
25299
25546
  onSuccess: () => {
25300
25547
  queryClient.setQueryData(
@@ -25310,10 +25557,10 @@ function SecuritySettings({
25310
25557
  onError?.(message);
25311
25558
  }
25312
25559
  });
25313
- const handleStart2FASetup = useCallback37(() => {
25560
+ const handleStart2FASetup = useCallback36(() => {
25314
25561
  setup2FAMutation.mutate();
25315
25562
  }, [setup2FAMutation]);
25316
- const handleEnable2FA = useCallback37(
25563
+ const handleEnable2FA = useCallback36(
25317
25564
  (e2) => {
25318
25565
  e2.preventDefault();
25319
25566
  if (!verifyCode || verifyCode.length !== 6) {
@@ -25324,12 +25571,12 @@ function SecuritySettings({
25324
25571
  },
25325
25572
  [verifyCode, enable2FAMutation]
25326
25573
  );
25327
- const handleDisable2FA = useCallback37(() => {
25574
+ const handleDisable2FA = useCallback36(() => {
25328
25575
  const code = prompt("Enter your 2FA code to disable two-factor authentication:");
25329
25576
  if (!code) return;
25330
25577
  disable2FAMutation.mutate(code);
25331
25578
  }, [disable2FAMutation]);
25332
- const handlePasswordChange = useCallback37(
25579
+ const handlePasswordChange = useCallback36(
25333
25580
  (e2) => {
25334
25581
  e2.preventDefault();
25335
25582
  if (newPassword !== confirmPassword) {
@@ -25347,13 +25594,13 @@ function SecuritySettings({
25347
25594
  },
25348
25595
  [newPassword, confirmPassword, currentPassword, changePasswordMutation]
25349
25596
  );
25350
- const handleRevokeSession = useCallback37(
25597
+ const handleRevokeSession = useCallback36(
25351
25598
  (sessionId) => {
25352
25599
  revokeSessionMutation.mutate(sessionId);
25353
25600
  },
25354
25601
  [revokeSessionMutation]
25355
25602
  );
25356
- const handleRevokeAllSessions = useCallback37(() => {
25603
+ const handleRevokeAllSessions = useCallback36(() => {
25357
25604
  if (!confirm("Are you sure you want to sign out all other devices?")) {
25358
25605
  return;
25359
25606
  }
@@ -25896,8 +26143,8 @@ function DeviceIcon({ device, theme }) {
25896
26143
 
25897
26144
  // src/react/ui/subscriber-preferences.tsx
25898
26145
  init_constants();
25899
- import { useQuery as useQuery12, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
25900
- import { useEffect as useEffect44, useState as useState54 } from "react";
26146
+ import { useQuery as useQuery13, useQueryClient as useQueryClient12 } from "@tanstack/react-query";
26147
+ import { useEffect as useEffect44, useState as useState53 } from "react";
25901
26148
  import { Fragment as Fragment31, jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
25902
26149
  function SubscriberPreferences({
25903
26150
  theme = defaultTheme,
@@ -25914,17 +26161,17 @@ function SubscriberPreferences({
25914
26161
  unsubscribeButtonText = "Unsubscribe from All"
25915
26162
  }) {
25916
26163
  const { getPreferences, updatePreferences } = useNewsletter();
25917
- const queryClient = useQueryClient11();
26164
+ const queryClient = useQueryClient12();
25918
26165
  const styles2 = baseStyles(theme);
25919
- const [selectedPreferences, setSelectedPreferences] = useState54([]);
25920
- const [saving, setSaving] = useState54(false);
25921
- const [unsubscribing, setUnsubscribing] = useState54(false);
25922
- const [error, setError] = useState54(null);
25923
- const [success, setSuccess] = useState54(null);
26166
+ const [selectedPreferences, setSelectedPreferences] = useState53([]);
26167
+ const [saving, setSaving] = useState53(false);
26168
+ const [unsubscribing, setUnsubscribing] = useState53(false);
26169
+ const [error, setError] = useState53(null);
26170
+ const [success, setSuccess] = useState53(null);
25924
26171
  useEffect44(() => {
25925
26172
  injectGlobalStyles();
25926
26173
  }, []);
25927
- const prefsQuery = useQuery12({
26174
+ const prefsQuery = useQuery13({
25928
26175
  queryKey: ["sylphx", "newsletter", "preferences", email],
25929
26176
  queryFn: async () => {
25930
26177
  const prefs = await getPreferences(email);
@@ -26135,7 +26382,7 @@ function SubscriberPreferences({
26135
26382
 
26136
26383
  // src/react/ui/unsubscribe-confirm.tsx
26137
26384
  init_constants();
26138
- import { useEffect as useEffect45, useId as useId9, useState as useState55 } from "react";
26385
+ import { useEffect as useEffect45, useId as useId9, useState as useState54 } from "react";
26139
26386
  import { Fragment as Fragment32, jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
26140
26387
  var DEFAULT_REASONS = [
26141
26388
  { id: "too_many", label: "Too many emails" },
@@ -26162,9 +26409,9 @@ function UnsubscribeConfirm({
26162
26409
  const { unsubscribe, subscribe } = useNewsletter();
26163
26410
  const styles2 = baseStyles(theme);
26164
26411
  const reasonId = useId9();
26165
- const [status, setStatus] = useState55(() => token ? "pending" : "missing_token");
26166
- const [selectedReason, setSelectedReason] = useState55("");
26167
- const [error, setError] = useState55(null);
26412
+ const [status, setStatus] = useState54(() => token ? "pending" : "missing_token");
26413
+ const [selectedReason, setSelectedReason] = useState54("");
26414
+ const [error, setError] = useState54(null);
26168
26415
  useEffect45(() => {
26169
26416
  injectGlobalStyles();
26170
26417
  }, []);
@@ -26524,7 +26771,7 @@ function UnsubscribeConfirm({
26524
26771
 
26525
26772
  // src/react/ui/user-profile.tsx
26526
26773
  init_constants();
26527
- import { useCallback as useCallback38, useEffect as useEffect46, useId as useId10, useRef as useRef18, useState as useState56 } from "react";
26774
+ import { useCallback as useCallback37, useEffect as useEffect46, useId as useId10, useRef as useRef16, useState as useState55 } from "react";
26528
26775
  import { Fragment as Fragment33, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
26529
26776
  function UserProfile(props) {
26530
26777
  return /* @__PURE__ */ jsx46(RequireSdk, { services: ["auth", "storage"], componentType: "user", theme: props.theme, children: /* @__PURE__ */ jsx46(UserProfileInner, { ...props }) });
@@ -26542,16 +26789,16 @@ function UserProfileInner({
26542
26789
  }) {
26543
26790
  const { user, isLoading: isUserLoading, refresh: refreshUser } = useUser();
26544
26791
  const userContext = useUserContext();
26545
- const { uploadAvatar, isUploading: isUploadingAvatar } = useStorage();
26792
+ const { upload: uploadFile, isUploading: isUploadingAvatar } = useStorage();
26546
26793
  const styles2 = baseStyles(theme);
26547
26794
  const nameId = useId10();
26548
26795
  const emailId = useId10();
26549
- const [activeSection, setActiveSection] = useState56(sections[0]);
26550
- const [form, setForm] = useState56({ name: "", image: "" });
26551
- const [error, setError] = useState56(null);
26552
- const [success, setSuccess] = useState56(null);
26553
- const [isLoading, setIsLoading] = useState56(false);
26554
- const fileInputRef = useRef18(null);
26796
+ const [activeSection, setActiveSection] = useState55(sections[0]);
26797
+ const [form, setForm] = useState55({ name: "", image: "" });
26798
+ const [error, setError] = useState55(null);
26799
+ const [success, setSuccess] = useState55(null);
26800
+ const [isLoading, setIsLoading] = useState55(false);
26801
+ const fileInputRef = useRef16(null);
26555
26802
  useEffect46(() => {
26556
26803
  injectGlobalStyles();
26557
26804
  }, []);
@@ -26572,7 +26819,7 @@ function UserProfileInner({
26572
26819
  return () => clearTimeout(timer);
26573
26820
  }
26574
26821
  }, [success, error]);
26575
- const handleProfileUpdate = useCallback38(
26822
+ const handleProfileUpdate = useCallback37(
26576
26823
  async (e2) => {
26577
26824
  e2.preventDefault();
26578
26825
  setIsLoading(true);
@@ -26596,11 +26843,12 @@ function UserProfileInner({
26596
26843
  },
26597
26844
  [form, userContext, refreshUser, onSuccess, onError]
26598
26845
  );
26599
- const handleAvatarUpload = useCallback38(
26846
+ const handleAvatarUpload = useCallback37(
26600
26847
  async (file) => {
26601
26848
  setError(null);
26602
26849
  try {
26603
- const imageUrl = await uploadAvatar(file);
26850
+ const result = await uploadFile(file, { folder: "avatars" });
26851
+ const imageUrl = result.url ?? "";
26604
26852
  setForm((prev) => ({ ...prev, image: imageUrl }));
26605
26853
  setSuccess("Avatar uploaded");
26606
26854
  } catch (err) {
@@ -26609,7 +26857,7 @@ function UserProfileInner({
26609
26857
  onError?.(message);
26610
26858
  }
26611
26859
  },
26612
- [uploadAvatar, onError]
26860
+ [uploadFile, onError]
26613
26861
  );
26614
26862
  const handleFileChange = (e2) => {
26615
26863
  const file = e2.target.files?.[0];
@@ -26899,7 +27147,7 @@ function CloseIcon6({ color }) {
26899
27147
  }
26900
27148
 
26901
27149
  // src/react/ui/webhook-manager.tsx
26902
- import { useEffect as useEffect47, useId as useId11, useState as useState57 } from "react";
27150
+ import { useEffect as useEffect47, useId as useId11, useState as useState56 } from "react";
26903
27151
  import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
26904
27152
  var DEFAULT_EVENTS = [
26905
27153
  "user.created",
@@ -26926,13 +27174,13 @@ function WebhookManager({
26926
27174
  emptyMessage = "No webhooks configured"
26927
27175
  }) {
26928
27176
  const urlId = useId11();
26929
- const [showCreate, setShowCreate] = useState57(false);
26930
- const [url, setUrl] = useState57("");
26931
- const [selectedEvents, setSelectedEvents] = useState57([]);
26932
- const [isCreating, setIsCreating] = useState57(false);
26933
- const [error, setError] = useState57(null);
26934
- const [testingId, setTestingId] = useState57(null);
26935
- const [deletingId, setDeletingId] = useState57(null);
27177
+ const [showCreate, setShowCreate] = useState56(false);
27178
+ const [url, setUrl] = useState56("");
27179
+ const [selectedEvents, setSelectedEvents] = useState56([]);
27180
+ const [isCreating, setIsCreating] = useState56(false);
27181
+ const [error, setError] = useState56(null);
27182
+ const [testingId, setTestingId] = useState56(null);
27183
+ const [deletingId, setDeletingId] = useState56(null);
26936
27184
  const styles2 = baseStyles(theme);
26937
27185
  useEffect47(() => {
26938
27186
  injectGlobalStyles();
@@ -27322,7 +27570,7 @@ function WebhookDeliveryLog({
27322
27570
  emptyMessage = "No deliveries yet",
27323
27571
  maxDeliveries = 50
27324
27572
  }) {
27325
- const [expandedId, setExpandedId] = useState57(null);
27573
+ const [expandedId, setExpandedId] = useState56(null);
27326
27574
  const styles2 = baseStyles(theme);
27327
27575
  useEffect47(() => {
27328
27576
  injectGlobalStyles();
@@ -33219,7 +33467,7 @@ function isWebVitalsInitialized() {
33219
33467
 
33220
33468
  // src/react/hooks/use-session-replay.tsx
33221
33469
  init_constants();
33222
- import { useCallback as useCallback39, useEffect as useEffect48, useRef as useRef19, useState as useState58 } from "react";
33470
+ import { useCallback as useCallback38, useEffect as useEffect48, useRef as useRef17, useState as useState57 } from "react";
33223
33471
  import { jsx as jsx48 } from "react/jsx-runtime";
33224
33472
  function useSessionReplay(options = {}) {
33225
33473
  const {
@@ -33232,14 +33480,14 @@ function useSessionReplay(options = {}) {
33232
33480
  api,
33233
33481
  ...recorderConfig
33234
33482
  } = options;
33235
- const apiRef = useRef19(api);
33483
+ const apiRef = useRef17(api);
33236
33484
  useEffect48(() => {
33237
33485
  apiRef.current = api;
33238
33486
  }, [api]);
33239
- const recorderRef = useRef19(null);
33240
- const currentSessionIdRef = useRef19(null);
33241
- const [sessionId, setSessionId] = useState58(null);
33242
- const [status, setStatus] = useState58({
33487
+ const recorderRef = useRef17(null);
33488
+ const currentSessionIdRef = useRef17(null);
33489
+ const [sessionId, setSessionId] = useState57(null);
33490
+ const [status, setStatus] = useState57({
33243
33491
  state: "idle",
33244
33492
  sessionId: null,
33245
33493
  eventCount: 0,
@@ -33292,7 +33540,7 @@ function useSessionReplay(options = {}) {
33292
33540
  });
33293
33541
  }
33294
33542
  }, [userId]);
33295
- const start = useCallback39(() => {
33543
+ const start = useCallback38(() => {
33296
33544
  if (!recorderRef.current) {
33297
33545
  throw new Error("Recorder not initialized");
33298
33546
  }
@@ -33300,29 +33548,29 @@ function useSessionReplay(options = {}) {
33300
33548
  setSessionId(id);
33301
33549
  return id;
33302
33550
  }, []);
33303
- const pause = useCallback39(() => {
33551
+ const pause = useCallback38(() => {
33304
33552
  recorderRef.current?.pause();
33305
33553
  }, []);
33306
- const resume = useCallback39(() => {
33554
+ const resume = useCallback38(() => {
33307
33555
  recorderRef.current?.resume();
33308
33556
  }, []);
33309
- const stop = useCallback39(async () => {
33557
+ const stop = useCallback38(async () => {
33310
33558
  await recorderRef.current?.stop();
33311
33559
  setSessionId(null);
33312
33560
  }, []);
33313
- const markError = useCallback39(
33561
+ const markError = useCallback38(
33314
33562
  (errorId, error, metadata) => {
33315
33563
  recorderRef.current?.markError(errorId, error, metadata);
33316
33564
  },
33317
33565
  []
33318
33566
  );
33319
- const markNavigation = useCallback39((from, to) => {
33567
+ const markNavigation = useCallback38((from, to) => {
33320
33568
  recorderRef.current?.markNavigation(from, to);
33321
33569
  }, []);
33322
- const markConversion = useCallback39((name, value) => {
33570
+ const markConversion = useCallback38((name, value) => {
33323
33571
  recorderRef.current?.markConversion(name, value);
33324
33572
  }, []);
33325
- const addMarker = useCallback39((type, payload) => {
33573
+ const addMarker = useCallback38((type, payload) => {
33326
33574
  recorderRef.current?.addMarker(type, payload);
33327
33575
  }, []);
33328
33576
  return {
@@ -33371,13 +33619,13 @@ function createDefaultUploadHandler(endpoint) {
33371
33619
  };
33372
33620
  }
33373
33621
  function useSessionReplayErrorMarker() {
33374
- const recorderRef = useRef19(null);
33622
+ const recorderRef = useRef17(null);
33375
33623
  useEffect48(() => {
33376
33624
  if (typeof window !== "undefined" && window.__sylphxRecorder) {
33377
33625
  recorderRef.current = window.__sylphxRecorder;
33378
33626
  }
33379
33627
  }, []);
33380
- const markError = useCallback39((error, errorInfo) => {
33628
+ const markError = useCallback38((error, errorInfo) => {
33381
33629
  const errorId = `err_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
33382
33630
  recorderRef.current?.markError(errorId, error, {
33383
33631
  componentStack: errorInfo?.componentStack?.slice(0, STACK_TRACE_MAX_LENGTH)
@@ -33396,11 +33644,11 @@ function withSessionReplay(Component2, options) {
33396
33644
  }
33397
33645
 
33398
33646
  // src/react/hooks/use-web-vitals.ts
33399
- import { useCallback as useCallback40, useEffect as useEffect49, useRef as useRef20, useState as useState59 } from "react";
33647
+ import { useCallback as useCallback39, useEffect as useEffect49, useRef as useRef18, useState as useState58 } from "react";
33400
33648
  function useWebVitals(options = {}) {
33401
33649
  const { autoInit = true, onReport, ...config2 } = options;
33402
- const [report, setReport] = useState59(null);
33403
- const initRef = useRef20(false);
33650
+ const [report, setReport] = useState58(null);
33651
+ const initRef = useRef18(false);
33404
33652
  useEffect49(() => {
33405
33653
  if (!autoInit || initRef.current) return;
33406
33654
  if (typeof window === "undefined") return;
@@ -33416,10 +33664,10 @@ function useWebVitals(options = {}) {
33416
33664
  return () => {
33417
33665
  };
33418
33666
  }, [autoInit, onReport]);
33419
- const refresh = useCallback40(() => {
33667
+ const refresh = useCallback39(() => {
33420
33668
  setReport(getWebVitalsReport());
33421
33669
  }, []);
33422
- const reset = useCallback40(() => {
33670
+ const reset = useCallback39(() => {
33423
33671
  resetWebVitals();
33424
33672
  setReport(null);
33425
33673
  initRef.current = false;
@@ -33463,7 +33711,7 @@ function useWebVital({ metric }) {
33463
33711
  }
33464
33712
  function useWebVitalsAnalytics(options) {
33465
33713
  const { track, eventPrefix = "web_vital", reportOnHide = true } = options;
33466
- const reportedRef = useRef20(false);
33714
+ const reportedRef = useRef18(false);
33467
33715
  const webVitals = useWebVitals({
33468
33716
  onReport: (metric) => {
33469
33717
  track(`${eventPrefix}_${metric.name.toLowerCase()}`, {
@@ -33506,7 +33754,7 @@ function useWebVitalsAnalytics(options) {
33506
33754
 
33507
33755
  // src/react/hooks/use-error-tracking.ts
33508
33756
  init_constants();
33509
- import { useCallback as useCallback41, useEffect as useEffect50, useRef as useRef21 } from "react";
33757
+ import { useCallback as useCallback40, useEffect as useEffect50, useRef as useRef19 } from "react";
33510
33758
  function useEnhancedErrorTracking(options = {}) {
33511
33759
  const {
33512
33760
  attachReplay = true,
@@ -33516,8 +33764,8 @@ function useEnhancedErrorTracking(options = {}) {
33516
33764
  autoInit = true,
33517
33765
  ...trackerConfig
33518
33766
  } = options;
33519
- const trackerRef = useRef21(null);
33520
- const replaySessionIdRef = useRef21(null);
33767
+ const trackerRef = useRef19(null);
33768
+ const replaySessionIdRef = useRef19(null);
33521
33769
  useEffect50(() => {
33522
33770
  if (typeof window === "undefined") return;
33523
33771
  const tracker = getTracker({
@@ -33561,7 +33809,7 @@ function useEnhancedErrorTracking(options = {}) {
33561
33809
  const interval = setInterval(checkReplaySession, SESSION_REPLAY_STATUS_CHECK_MS);
33562
33810
  return () => clearInterval(interval);
33563
33811
  }, [attachReplay]);
33564
- const captureException = useCallback41(
33812
+ const captureException = useCallback40(
33565
33813
  async (error, opts = {}) => {
33566
33814
  if (!trackerRef.current) {
33567
33815
  return { eventId: "" };
@@ -33589,7 +33837,7 @@ function useEnhancedErrorTracking(options = {}) {
33589
33837
  },
33590
33838
  [attachReplay, onCapture]
33591
33839
  );
33592
- const captureMessage = useCallback41(
33840
+ const captureMessage = useCallback40(
33593
33841
  async (message, opts = {}) => {
33594
33842
  if (!trackerRef.current) {
33595
33843
  return { eventId: "" };
@@ -33600,20 +33848,20 @@ function useEnhancedErrorTracking(options = {}) {
33600
33848
  },
33601
33849
  [onCapture]
33602
33850
  );
33603
- const addBreadcrumb2 = useCallback41((breadcrumb) => {
33851
+ const addBreadcrumb2 = useCallback40((breadcrumb) => {
33604
33852
  trackerRef.current?.addBreadcrumb(breadcrumb);
33605
33853
  }, []);
33606
- const setUser = useCallback41((user) => {
33854
+ const setUser = useCallback40((user) => {
33607
33855
  trackerRef.current?.setUser(user);
33608
33856
  }, []);
33609
- const clearUser = useCallback41(() => {
33857
+ const clearUser = useCallback40(() => {
33610
33858
  trackerRef.current?.clearUser();
33611
33859
  }, []);
33612
- const linkReplaySession = useCallback41((sessionId) => {
33860
+ const linkReplaySession = useCallback40((sessionId) => {
33613
33861
  replaySessionIdRef.current = sessionId;
33614
33862
  trackerRef.current?.setSessionReplayId(sessionId);
33615
33863
  }, []);
33616
- const getReplaySessionId = useCallback41(() => {
33864
+ const getReplaySessionId = useCallback40(() => {
33617
33865
  return replaySessionIdRef.current;
33618
33866
  }, []);
33619
33867
  return {
@@ -34815,10 +35063,10 @@ var DEFAULT_FLAGS_CONFIG = {
34815
35063
  };
34816
35064
 
34817
35065
  // src/react/hooks/use-flag.ts
34818
- import { useCallback as useCallback43, useContext as useContext19, useEffect as useEffect52, useMemo as useMemo12, useRef as useRef23, useState as useState61 } from "react";
35066
+ import { useCallback as useCallback42, useContext as useContext20, useEffect as useEffect52, useMemo as useMemo13, useRef as useRef21, useState as useState60 } from "react";
34819
35067
 
34820
35068
  // src/react/hooks/use-flags.tsx
34821
- import { createContext as createContext7, useCallback as useCallback42, useContext as useContext18, useEffect as useEffect51, useMemo as useMemo11, useRef as useRef22, useState as useState60 } from "react";
35069
+ import { createContext as createContext7, useCallback as useCallback41, useContext as useContext19, useEffect as useEffect51, useMemo as useMemo12, useRef as useRef20, useState as useState59 } from "react";
34822
35070
  import { jsx as jsx49 } from "react/jsx-runtime";
34823
35071
  var FeatureFlagsContext = createContext7(null);
34824
35072
  function FeatureFlagsProvider({
@@ -34830,14 +35078,14 @@ function FeatureFlagsProvider({
34830
35078
  onReady,
34831
35079
  onError
34832
35080
  }) {
34833
- const [isReady, setIsReady] = useState60(!!initialFlags?.length);
34834
- const [isLoading, setIsLoading] = useState60(!initialFlags?.length);
34835
- const [error, setError] = useState60(null);
34836
- const [updateVersion, setUpdateVersion] = useState60(0);
34837
- const evaluatorRef = useRef22(null);
34838
- const streamRef = useRef22(null);
34839
- const experimentsRef = useRef22(null);
34840
- const handleStreamEvent = useCallback42(
35081
+ const [isReady, setIsReady] = useState59(!!initialFlags?.length);
35082
+ const [isLoading, setIsLoading] = useState59(!initialFlags?.length);
35083
+ const [error, setError] = useState59(null);
35084
+ const [updateVersion, setUpdateVersion] = useState59(0);
35085
+ const evaluatorRef = useRef20(null);
35086
+ const streamRef = useRef20(null);
35087
+ const experimentsRef = useRef20(null);
35088
+ const handleStreamEvent = useCallback41(
34841
35089
  (event) => {
34842
35090
  switch (event.type) {
34843
35091
  case "ready":
@@ -34909,7 +35157,7 @@ function FeatureFlagsProvider({
34909
35157
  evaluatorRef.current.setContext(context);
34910
35158
  }
34911
35159
  }, [context]);
34912
- const value = useMemo11(
35160
+ const value = useMemo12(
34913
35161
  () => ({
34914
35162
  evaluator: evaluatorRef.current,
34915
35163
  stream: streamRef.current,
@@ -34928,53 +35176,53 @@ function FeatureFlagsProvider({
34928
35176
  return /* @__PURE__ */ jsx49(FeatureFlagsContext.Provider, { value, children });
34929
35177
  }
34930
35178
  function useFeatureFlags2() {
34931
- const ctx = useContext18(FeatureFlagsContext);
35179
+ const ctx = useContext19(FeatureFlagsContext);
34932
35180
  if (!ctx) {
34933
35181
  throw new Error("useFeatureFlags must be used within a FeatureFlagsProvider");
34934
35182
  }
34935
35183
  const { evaluator, isReady, isLoading, error, flags, updateVersion } = ctx;
34936
- const isEnabled = useCallback42(
35184
+ const isEnabled = useCallback41(
34937
35185
  (flagKey, defaultValue = false) => {
34938
35186
  void updateVersion;
34939
35187
  return evaluator.isEnabled(flagKey, defaultValue);
34940
35188
  },
34941
35189
  [evaluator, updateVersion]
34942
35190
  );
34943
- const getString = useCallback42(
35191
+ const getString = useCallback41(
34944
35192
  (flagKey, defaultValue = "") => {
34945
35193
  void updateVersion;
34946
35194
  return evaluator.getString(flagKey, defaultValue);
34947
35195
  },
34948
35196
  [evaluator, updateVersion]
34949
35197
  );
34950
- const getNumber = useCallback42(
35198
+ const getNumber = useCallback41(
34951
35199
  (flagKey, defaultValue = 0) => {
34952
35200
  void updateVersion;
34953
35201
  return evaluator.getNumber(flagKey, defaultValue);
34954
35202
  },
34955
35203
  [evaluator, updateVersion]
34956
35204
  );
34957
- const getJSON = useCallback42(
35205
+ const getJSON = useCallback41(
34958
35206
  (flagKey, defaultValue) => {
34959
35207
  void updateVersion;
34960
35208
  return evaluator.getJSON(flagKey, defaultValue);
34961
35209
  },
34962
35210
  [evaluator, updateVersion]
34963
35211
  );
34964
- const evaluate = useCallback42(
35212
+ const evaluate = useCallback41(
34965
35213
  (flagKey, defaultValue, contextOverride) => {
34966
35214
  void updateVersion;
34967
35215
  return evaluator.evaluate(flagKey, defaultValue, contextOverride);
34968
35216
  },
34969
35217
  [evaluator, updateVersion]
34970
35218
  );
34971
- const setContext = useCallback42(
35219
+ const setContext = useCallback41(
34972
35220
  (context) => {
34973
35221
  evaluator.setContext(context);
34974
35222
  },
34975
35223
  [evaluator]
34976
35224
  );
34977
- const updateContext = useCallback42(
35225
+ const updateContext = useCallback41(
34978
35226
  (partial) => {
34979
35227
  evaluator.updateContext(partial);
34980
35228
  },
@@ -34996,7 +35244,7 @@ function useFeatureFlags2() {
34996
35244
  }
34997
35245
  function useFlag(flagKey, defaultValue = false) {
34998
35246
  const { isEnabled, updateVersion } = useFeatureFlagsContext();
34999
- return useMemo11(
35247
+ return useMemo12(
35000
35248
  () => isEnabled(flagKey, defaultValue),
35001
35249
  // eslint-disable-next-line react-hooks/exhaustive-deps
35002
35250
  [flagKey, defaultValue, isEnabled]
@@ -35004,7 +35252,7 @@ function useFlag(flagKey, defaultValue = false) {
35004
35252
  }
35005
35253
  function useFlagString(flagKey, defaultValue = "") {
35006
35254
  const { getString, updateVersion } = useFeatureFlagsContext();
35007
- return useMemo11(
35255
+ return useMemo12(
35008
35256
  () => getString(flagKey, defaultValue),
35009
35257
  // eslint-disable-next-line react-hooks/exhaustive-deps
35010
35258
  [flagKey, defaultValue, getString]
@@ -35012,7 +35260,7 @@ function useFlagString(flagKey, defaultValue = "") {
35012
35260
  }
35013
35261
  function useFlagNumber(flagKey, defaultValue = 0) {
35014
35262
  const { getNumber, updateVersion } = useFeatureFlagsContext();
35015
- return useMemo11(
35263
+ return useMemo12(
35016
35264
  () => getNumber(flagKey, defaultValue),
35017
35265
  // eslint-disable-next-line react-hooks/exhaustive-deps
35018
35266
  [flagKey, defaultValue, getNumber]
@@ -35020,7 +35268,7 @@ function useFlagNumber(flagKey, defaultValue = 0) {
35020
35268
  }
35021
35269
  function useFlagJSON(flagKey, defaultValue) {
35022
35270
  const { getJSON, updateVersion } = useFeatureFlagsContext();
35023
- return useMemo11(
35271
+ return useMemo12(
35024
35272
  () => getJSON(flagKey, defaultValue),
35025
35273
  // eslint-disable-next-line react-hooks/exhaustive-deps
35026
35274
  [flagKey, defaultValue, getJSON]
@@ -35028,19 +35276,19 @@ function useFlagJSON(flagKey, defaultValue) {
35028
35276
  }
35029
35277
  function useFlagEvaluation(flagKey, defaultValue, contextOverride) {
35030
35278
  const { evaluate, updateVersion } = useFeatureFlagsContext();
35031
- return useMemo11(
35279
+ return useMemo12(
35032
35280
  () => evaluate(flagKey, defaultValue, contextOverride),
35033
35281
  // eslint-disable-next-line react-hooks/exhaustive-deps
35034
35282
  [flagKey, defaultValue, contextOverride, evaluate]
35035
35283
  );
35036
35284
  }
35037
35285
  function useExperiment(experimentKey) {
35038
- const ctx = useContext18(FeatureFlagsContext);
35286
+ const ctx = useContext19(FeatureFlagsContext);
35039
35287
  if (!ctx) {
35040
35288
  throw new Error("useExperiment must be used within a FeatureFlagsProvider");
35041
35289
  }
35042
35290
  const { experiments, updateVersion } = ctx;
35043
- return useMemo11(() => {
35291
+ return useMemo12(() => {
35044
35292
  const result = experiments.getVariant(experimentKey);
35045
35293
  return {
35046
35294
  variant: result.variant,
@@ -35058,7 +35306,7 @@ function useIsInTreatment(experimentKey) {
35058
35306
  return inExperiment && variant !== "control";
35059
35307
  }
35060
35308
  function useFeatureFlagsContext() {
35061
- const ctx = useContext18(FeatureFlagsContext);
35309
+ const ctx = useContext19(FeatureFlagsContext);
35062
35310
  if (!ctx) {
35063
35311
  throw new Error("Feature flags hooks must be used within a FeatureFlagsProvider");
35064
35312
  }
@@ -35073,7 +35321,7 @@ function useFeatureFlagsContext() {
35073
35321
  };
35074
35322
  }
35075
35323
  function useFlagsReady() {
35076
- const ctx = useContext18(FeatureFlagsContext);
35324
+ const ctx = useContext19(FeatureFlagsContext);
35077
35325
  if (!ctx) {
35078
35326
  return { isReady: false, isLoading: true, error: null };
35079
35327
  }
@@ -35093,22 +35341,22 @@ function useFlagStatus(key, options) {
35093
35341
  pollInterval = DEFAULT_POLL_INTERVAL_MS2,
35094
35342
  context: contextOverride
35095
35343
  } = options ?? {};
35096
- const ctx = useContext19(FeatureFlagsContext);
35097
- const [enabled, setEnabled] = useState61(false);
35098
- const [loading, setLoading] = useState61(!ctx?.isReady);
35099
- const [error, setError] = useState61(null);
35100
- const mountedRef = useRef23(true);
35101
- const evalContext = useMemo12(() => {
35344
+ const ctx = useContext20(FeatureFlagsContext);
35345
+ const [enabled, setEnabled] = useState60(false);
35346
+ const [loading, setLoading] = useState60(!ctx?.isReady);
35347
+ const [error, setError] = useState60(null);
35348
+ const mountedRef = useRef21(true);
35349
+ const evalContext = useMemo13(() => {
35102
35350
  if (contextOverride) return contextOverride;
35103
35351
  if (userId || attributes) return { userId, ...attributes };
35104
35352
  return void 0;
35105
35353
  }, [contextOverride, userId, attributes]);
35106
- const evaluateLocally = useCallback43(() => {
35354
+ const evaluateLocally = useCallback42(() => {
35107
35355
  if (!ctx?.evaluator) return false;
35108
35356
  const result = ctx.evaluator.evaluate(key, false, evalContext);
35109
35357
  return result.value;
35110
35358
  }, [ctx, key, evalContext]);
35111
- const refetch = useCallback43(async () => {
35359
+ const refetch = useCallback42(async () => {
35112
35360
  if (!mountedRef.current) return;
35113
35361
  setError(null);
35114
35362
  try {
@@ -37163,9 +37411,9 @@ var AnalyticsTracker = class {
37163
37411
  }
37164
37412
  }
37165
37413
  getOrCreateAnonymousId() {
37166
- const storage = this.getStorage();
37167
- if (storage) {
37168
- const stored = storage.getItem(this.getStorageKey("anon_id"));
37414
+ const storage2 = this.getStorage();
37415
+ if (storage2) {
37416
+ const stored = storage2.getItem(this.getStorageKey("anon_id"));
37169
37417
  if (stored) return stored;
37170
37418
  }
37171
37419
  const id = this.generateId();
@@ -37173,33 +37421,33 @@ var AnalyticsTracker = class {
37173
37421
  return id;
37174
37422
  }
37175
37423
  persistAnonymousId(id) {
37176
- const storage = this.getStorage();
37177
- if (storage) {
37178
- storage.setItem(this.getStorageKey("anon_id"), id);
37424
+ const storage2 = this.getStorage();
37425
+ if (storage2) {
37426
+ storage2.setItem(this.getStorageKey("anon_id"), id);
37179
37427
  }
37180
37428
  }
37181
37429
  persistDistinctId(id) {
37182
- const storage = this.getStorage();
37183
- if (storage) {
37184
- storage.setItem(this.getStorageKey("distinct_id"), id);
37430
+ const storage2 = this.getStorage();
37431
+ if (storage2) {
37432
+ storage2.setItem(this.getStorageKey("distinct_id"), id);
37185
37433
  }
37186
37434
  }
37187
37435
  clearDistinctId() {
37188
- const storage = this.getStorage();
37189
- if (storage) {
37190
- storage.removeItem(this.getStorageKey("distinct_id"));
37436
+ const storage2 = this.getStorage();
37437
+ if (storage2) {
37438
+ storage2.removeItem(this.getStorageKey("distinct_id"));
37191
37439
  }
37192
37440
  }
37193
37441
  getOrCreateSessionId() {
37194
- const storage = this.getStorage();
37195
- if (storage) {
37196
- const stored = storage.getItem(this.getStorageKey("session_id"));
37197
- const timestamp = storage.getItem(this.getStorageKey("session_ts"));
37442
+ const storage2 = this.getStorage();
37443
+ if (storage2) {
37444
+ const stored = storage2.getItem(this.getStorageKey("session_id"));
37445
+ const timestamp = storage2.getItem(this.getStorageKey("session_ts"));
37198
37446
  if (stored && timestamp) {
37199
37447
  const lastActivity = Number.parseInt(timestamp, 10);
37200
37448
  const timeout = this.config.sessionTimeout ?? ANALYTICS_SESSION_TIMEOUT_MS;
37201
37449
  if (Date.now() - lastActivity < timeout) {
37202
- storage.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37450
+ storage2.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37203
37451
  return stored;
37204
37452
  }
37205
37453
  }
@@ -37209,16 +37457,16 @@ var AnalyticsTracker = class {
37209
37457
  return id;
37210
37458
  }
37211
37459
  persistSessionId(id) {
37212
- const storage = this.getStorage();
37213
- if (storage) {
37214
- storage.setItem(this.getStorageKey("session_id"), id);
37215
- storage.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37460
+ const storage2 = this.getStorage();
37461
+ if (storage2) {
37462
+ storage2.setItem(this.getStorageKey("session_id"), id);
37463
+ storage2.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37216
37464
  }
37217
37465
  }
37218
37466
  loadQueue() {
37219
- const storage = this.getStorage();
37220
- if (storage) {
37221
- const stored = storage.getItem(this.getStorageKey("queue"));
37467
+ const storage2 = this.getStorage();
37468
+ if (storage2) {
37469
+ const stored = storage2.getItem(this.getStorageKey("queue"));
37222
37470
  if (stored) {
37223
37471
  try {
37224
37472
  this.queue = JSON.parse(stored);
@@ -37229,22 +37477,22 @@ var AnalyticsTracker = class {
37229
37477
  }
37230
37478
  }
37231
37479
  persistQueue() {
37232
- const storage = this.getStorage();
37233
- if (storage) {
37234
- storage.setItem(this.getStorageKey("queue"), JSON.stringify(this.queue));
37480
+ const storage2 = this.getStorage();
37481
+ if (storage2) {
37482
+ storage2.setItem(this.getStorageKey("queue"), JSON.stringify(this.queue));
37235
37483
  }
37236
37484
  }
37237
37485
  loadInitialAttribution(key) {
37238
- const storage = this.getStorage();
37239
- if (storage) {
37240
- return storage.getItem(this.getStorageKey(key));
37486
+ const storage2 = this.getStorage();
37487
+ if (storage2) {
37488
+ return storage2.getItem(this.getStorageKey(key));
37241
37489
  }
37242
37490
  return null;
37243
37491
  }
37244
37492
  persistInitialAttribution(key, value) {
37245
- const storage = this.getStorage();
37246
- if (storage) {
37247
- storage.setItem(this.getStorageKey(key), value);
37493
+ const storage2 = this.getStorage();
37494
+ if (storage2) {
37495
+ storage2.setItem(this.getStorageKey(key), value);
37248
37496
  }
37249
37497
  }
37250
37498
  // ==========================================
@@ -37284,7 +37532,7 @@ function resetAnalyticsTracker() {
37284
37532
 
37285
37533
  // src/react/hooks/use-analytics.tsx
37286
37534
  init_constants();
37287
- import React, { createContext as createContext8, useCallback as useCallback44, useContext as useContext20, useEffect as useEffect53, useMemo as useMemo13, useRef as useRef24 } from "react";
37535
+ import React, { createContext as createContext8, useCallback as useCallback43, useContext as useContext21, useEffect as useEffect53, useMemo as useMemo14, useRef as useRef22 } from "react";
37288
37536
  import { Fragment as Fragment34, jsx as jsx50 } from "react/jsx-runtime";
37289
37537
  var AnalyticsContext = createContext8(null);
37290
37538
  function AnalyticsProvider({
@@ -37293,7 +37541,7 @@ function AnalyticsProvider({
37293
37541
  user,
37294
37542
  disabled = false
37295
37543
  }) {
37296
- const trackerRef = useRef24(null);
37544
+ const trackerRef = useRef22(null);
37297
37545
  const [isReady, setIsReady] = React.useState(false);
37298
37546
  useEffect53(() => {
37299
37547
  if (disabled || typeof window === "undefined") return;
@@ -37309,7 +37557,7 @@ function AnalyticsProvider({
37309
37557
  trackerRef.current.identify(user.id, user.properties);
37310
37558
  }
37311
37559
  }, [user]);
37312
- const value = useMemo13(() => {
37560
+ const value = useMemo14(() => {
37313
37561
  if (!trackerRef.current || disabled) return null;
37314
37562
  return {
37315
37563
  tracker: trackerRef.current,
@@ -37322,58 +37570,58 @@ function AnalyticsProvider({
37322
37570
  return /* @__PURE__ */ jsx50(AnalyticsContext.Provider, { value, children });
37323
37571
  }
37324
37572
  function useAnalyticsHook() {
37325
- const ctx = useContext20(AnalyticsContext);
37573
+ const ctx = useContext21(AnalyticsContext);
37326
37574
  const tracker = ctx?.tracker ?? null;
37327
37575
  const isReady = ctx?.isReady ?? false;
37328
- const track = useCallback44(
37576
+ const track = useCallback43(
37329
37577
  (eventName, properties) => {
37330
37578
  tracker?.track(eventName, properties);
37331
37579
  },
37332
37580
  [tracker]
37333
37581
  );
37334
- const identify = useCallback44(
37582
+ const identify = useCallback43(
37335
37583
  (userId, properties) => {
37336
37584
  tracker?.identify(userId, properties);
37337
37585
  },
37338
37586
  [tracker]
37339
37587
  );
37340
- const reset = useCallback44(() => {
37588
+ const reset = useCallback43(() => {
37341
37589
  tracker?.reset();
37342
37590
  }, [tracker]);
37343
- const setUserProperties = useCallback44(
37591
+ const setUserProperties = useCallback43(
37344
37592
  (properties) => {
37345
37593
  tracker?.setUserProperties(properties);
37346
37594
  },
37347
37595
  [tracker]
37348
37596
  );
37349
- const setUserPropertiesOnce = useCallback44(
37597
+ const setUserPropertiesOnce = useCallback43(
37350
37598
  (properties) => {
37351
37599
  tracker?.setUserPropertiesOnce(properties);
37352
37600
  },
37353
37601
  [tracker]
37354
37602
  );
37355
- const incrementUserProperty = useCallback44(
37603
+ const incrementUserProperty = useCallback43(
37356
37604
  (property, value) => {
37357
37605
  tracker?.incrementUserProperty(property, value);
37358
37606
  },
37359
37607
  [tracker]
37360
37608
  );
37361
- const group = useCallback44(
37609
+ const group = useCallback43(
37362
37610
  (groupType, groupKey, properties) => {
37363
37611
  tracker?.group(groupType, groupKey, properties);
37364
37612
  },
37365
37613
  [tracker]
37366
37614
  );
37367
- const register = useCallback44(
37615
+ const register = useCallback43(
37368
37616
  (properties) => {
37369
37617
  tracker?.register(properties);
37370
37618
  },
37371
37619
  [tracker]
37372
37620
  );
37373
- const getDistinctId = useCallback44(() => {
37621
+ const getDistinctId = useCallback43(() => {
37374
37622
  return tracker?.getDistinctId() ?? null;
37375
37623
  }, [tracker]);
37376
- const flush = useCallback44(async () => {
37624
+ const flush = useCallback43(async () => {
37377
37625
  await tracker?.flush();
37378
37626
  }, [tracker]);
37379
37627
  return {
@@ -37392,7 +37640,7 @@ function useAnalyticsHook() {
37392
37640
  }
37393
37641
  function usePageView(pageName, properties) {
37394
37642
  const { track, isReady } = useAnalyticsHook();
37395
- const hasTracked = useRef24(false);
37643
+ const hasTracked = useRef22(false);
37396
37644
  useEffect53(() => {
37397
37645
  if (!isReady || hasTracked.current) return;
37398
37646
  hasTracked.current = true;
@@ -37404,8 +37652,8 @@ function usePageView(pageName, properties) {
37404
37652
  }
37405
37653
  function useComponentTracking(componentName, properties) {
37406
37654
  const { track, isReady } = useAnalyticsHook();
37407
- const mountTime = useRef24(Date.now());
37408
- const hasTracked = useRef24(false);
37655
+ const mountTime = useRef22(Date.now());
37656
+ const hasTracked = useRef22(false);
37409
37657
  useEffect53(() => {
37410
37658
  if (!isReady || hasTracked.current) return;
37411
37659
  hasTracked.current = true;
@@ -37424,7 +37672,7 @@ function useComponentTracking(componentName, properties) {
37424
37672
  }
37425
37673
  function useFeatureTracking(featureName) {
37426
37674
  const { track } = useAnalyticsHook();
37427
- const trackUsed = useCallback44(
37675
+ const trackUsed = useCallback43(
37428
37676
  (properties) => {
37429
37677
  track("feature_used", {
37430
37678
  feature: featureName,
@@ -37433,7 +37681,7 @@ function useFeatureTracking(featureName) {
37433
37681
  },
37434
37682
  [track, featureName]
37435
37683
  );
37436
- const trackError = useCallback44(
37684
+ const trackError = useCallback43(
37437
37685
  (error, properties) => {
37438
37686
  track("feature_error", {
37439
37687
  feature: featureName,
@@ -37448,13 +37696,13 @@ function useFeatureTracking(featureName) {
37448
37696
  }
37449
37697
  function useFormTracking(formName) {
37450
37698
  const { track } = useAnalyticsHook();
37451
- const startTime = useRef24(null);
37452
- const fieldsFilledRef = useRef24(/* @__PURE__ */ new Set());
37453
- const trackStarted = useCallback44(() => {
37699
+ const startTime = useRef22(null);
37700
+ const fieldsFilledRef = useRef22(/* @__PURE__ */ new Set());
37701
+ const trackStarted = useCallback43(() => {
37454
37702
  startTime.current = Date.now();
37455
37703
  track("form_started", { form: formName });
37456
37704
  }, [track, formName]);
37457
- const trackCompleted = useCallback44(
37705
+ const trackCompleted = useCallback43(
37458
37706
  (properties) => {
37459
37707
  const duration = startTime.current ? Date.now() - startTime.current : void 0;
37460
37708
  track("form_completed", {
@@ -37466,7 +37714,7 @@ function useFormTracking(formName) {
37466
37714
  },
37467
37715
  [track, formName]
37468
37716
  );
37469
- const trackAbandoned = useCallback44(() => {
37717
+ const trackAbandoned = useCallback43(() => {
37470
37718
  const duration = startTime.current ? Date.now() - startTime.current : void 0;
37471
37719
  track("form_abandoned", {
37472
37720
  form: formName,
@@ -37474,7 +37722,7 @@ function useFormTracking(formName) {
37474
37722
  fields_filled: fieldsFilledRef.current.size
37475
37723
  });
37476
37724
  }, [track, formName]);
37477
- const trackFieldFilled = useCallback44(
37725
+ const trackFieldFilled = useCallback43(
37478
37726
  (fieldName) => {
37479
37727
  if (!fieldsFilledRef.current.has(fieldName)) {
37480
37728
  fieldsFilledRef.current.add(fieldName);
@@ -37486,7 +37734,7 @@ function useFormTracking(formName) {
37486
37734
  },
37487
37735
  [track, formName]
37488
37736
  );
37489
- const trackError = useCallback44(
37737
+ const trackError = useCallback43(
37490
37738
  (fieldName, error) => {
37491
37739
  track("form_field_error", {
37492
37740
  form: formName,
@@ -37506,12 +37754,12 @@ function useFormTracking(formName) {
37506
37754
  }
37507
37755
  function useTimeTracking(name, options) {
37508
37756
  const { track } = useAnalyticsHook();
37509
- const startTime = useRef24(Date.now());
37510
- const trackedIntervals = useRef24(/* @__PURE__ */ new Set());
37511
- const getTimeSpent = useCallback44(() => {
37757
+ const startTime = useRef22(Date.now());
37758
+ const trackedIntervals = useRef22(/* @__PURE__ */ new Set());
37759
+ const getTimeSpent = useCallback43(() => {
37512
37760
  return Date.now() - startTime.current;
37513
37761
  }, []);
37514
- const trackNow = useCallback44(() => {
37762
+ const trackNow = useCallback43(() => {
37515
37763
  track("time_spent", {
37516
37764
  name,
37517
37765
  duration_ms: getTimeSpent()
@@ -37548,8 +37796,8 @@ function useTimeTracking(name, options) {
37548
37796
  }
37549
37797
 
37550
37798
  // src/react/hooks/use-destination-router.tsx
37551
- import { useCallback as useCallback45, useEffect as useEffect54, useMemo as useMemo14, useRef as useRef25 } from "react";
37552
- import { createContext as createContext9, useContext as useContext21 } from "react";
37799
+ import { useCallback as useCallback44, useEffect as useEffect54, useMemo as useMemo15, useRef as useRef23 } from "react";
37800
+ import { createContext as createContext9, useContext as useContext22 } from "react";
37553
37801
  import { jsx as jsx51 } from "react/jsx-runtime";
37554
37802
  function useDestinationRouter(options) {
37555
37803
  const {
@@ -37559,11 +37807,11 @@ function useDestinationRouter(options) {
37559
37807
  autoInit = true,
37560
37808
  debug = false
37561
37809
  } = options;
37562
- const routerRef = useRef25(null);
37563
- const initializedRef = useRef25(false);
37810
+ const routerRef = useRef23(null);
37811
+ const initializedRef = useRef23(false);
37564
37812
  const { hasConsent: checkConsent } = useConsent();
37565
37813
  const { user } = useUser();
37566
- const router = useMemo14(() => {
37814
+ const router = useMemo15(() => {
37567
37815
  if (!autoInit || typeof window === "undefined") return null;
37568
37816
  const newRouter = createDestinationRouter({
37569
37817
  destinations,
@@ -37588,46 +37836,46 @@ function useDestinationRouter(options) {
37588
37836
  name: user.name
37589
37837
  });
37590
37838
  }, [syncUser, user?.id, user?.email, user?.name]);
37591
- const track = useCallback45(
37839
+ const track = useCallback44(
37592
37840
  (event, properties) => {
37593
37841
  router?.track(event, properties);
37594
37842
  },
37595
37843
  [router]
37596
37844
  );
37597
- const trackTo = useCallback45(
37845
+ const trackTo = useCallback44(
37598
37846
  (destinationType, event, properties) => {
37599
37847
  router?.trackTo(destinationType, event, properties);
37600
37848
  },
37601
37849
  [router]
37602
37850
  );
37603
- const identify = useCallback45(
37851
+ const identify = useCallback44(
37604
37852
  (userId, traits) => {
37605
37853
  router?.identify(userId, traits);
37606
37854
  },
37607
37855
  [router]
37608
37856
  );
37609
- const page = useCallback45(
37857
+ const page = useCallback44(
37610
37858
  (name, properties) => {
37611
37859
  router?.page(name, properties);
37612
37860
  },
37613
37861
  [router]
37614
37862
  );
37615
- const getEnabledDestinations = useCallback45(() => {
37863
+ const getEnabledDestinations = useCallback44(() => {
37616
37864
  return router?.getEnabledDestinations() || [];
37617
37865
  }, [router]);
37618
- const setDestinationEnabled = useCallback45(
37866
+ const setDestinationEnabled = useCallback44(
37619
37867
  (type, enabled) => {
37620
37868
  router?.setDestinationEnabled(type, enabled);
37621
37869
  },
37622
37870
  [router]
37623
37871
  );
37624
- const setConsentChecker = useCallback45(
37872
+ const setConsentChecker = useCallback44(
37625
37873
  (fn) => {
37626
37874
  router?.setConsentChecker(fn);
37627
37875
  },
37628
37876
  [router]
37629
37877
  );
37630
- const setDistinctId = useCallback45(
37878
+ const setDistinctId = useCallback44(
37631
37879
  (id) => {
37632
37880
  router?.setDistinctId(id);
37633
37881
  },
@@ -37655,7 +37903,7 @@ function DestinationRouterProvider({
37655
37903
  return /* @__PURE__ */ jsx51(DestinationRouterContext.Provider, { value: router, children });
37656
37904
  }
37657
37905
  function useRouterContext() {
37658
- return useContext21(DestinationRouterContext);
37906
+ return useContext22(DestinationRouterContext);
37659
37907
  }
37660
37908
 
37661
37909
  // src/lib/tasks/handler.ts
@@ -38392,7 +38640,7 @@ function delay(ms) {
38392
38640
  function sleepUntil(date) {
38393
38641
  return wait(date);
38394
38642
  }
38395
- function withRetry(step, options) {
38643
+ function withRetry2(step, options) {
38396
38644
  return {
38397
38645
  ...step,
38398
38646
  options: {
@@ -38485,7 +38733,7 @@ var job = task;
38485
38733
 
38486
38734
  // src/react/hooks/use-realtime.ts
38487
38735
  init_constants();
38488
- import { useCallback as useCallback46, useContext as useContext22, useEffect as useEffect55, useMemo as useMemo15, useRef as useRef26, useState as useState62 } from "react";
38736
+ import { useCallback as useCallback45, useContext as useContext23, useEffect as useEffect55, useMemo as useMemo16, useRef as useRef24, useState as useState61 } from "react";
38489
38737
  function useRealtime(channel, options = {}) {
38490
38738
  const {
38491
38739
  events,
@@ -38497,17 +38745,17 @@ function useRealtime(channel, options = {}) {
38497
38745
  enabled = true,
38498
38746
  platformUrl: customPlatformUrl
38499
38747
  } = options;
38500
- const [messages, setMessages] = useState62([]);
38501
- const [status, setStatus] = useState62("disconnected");
38502
- const platformContext = useContext22(PlatformContext);
38748
+ const [messages, setMessages] = useState61([]);
38749
+ const [status, setStatus] = useState61("disconnected");
38750
+ const platformContext = useContext23(PlatformContext);
38503
38751
  const appId = platformContext?.appId || "";
38504
- const lastAckRef = useRef26("0");
38505
- const eventSourceRef = useRef26(null);
38506
- const reconnectTimeoutRef = useRef26(null);
38507
- const reconnectAttemptRef = useRef26(0);
38508
- const mountedRef = useRef26(true);
38752
+ const lastAckRef = useRef24("0");
38753
+ const eventSourceRef = useRef24(null);
38754
+ const reconnectTimeoutRef = useRef24(null);
38755
+ const reconnectAttemptRef = useRef24(0);
38756
+ const mountedRef = useRef24(true);
38509
38757
  const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
38510
- const buildUrl = useCallback46(() => {
38758
+ const buildUrl = useCallback45(() => {
38511
38759
  const url = new URL(`${platformUrl}${SDK_API_PATH}/realtime/subscribe`);
38512
38760
  url.searchParams.set("channel", channel);
38513
38761
  if (lastAckRef.current !== "0") {
@@ -38515,7 +38763,7 @@ function useRealtime(channel, options = {}) {
38515
38763
  }
38516
38764
  return url.toString();
38517
38765
  }, [platformUrl, channel]);
38518
- const sdkHeaders = useMemo15(
38766
+ const sdkHeaders = useMemo16(
38519
38767
  () => ({
38520
38768
  "Content-Type": "application/json",
38521
38769
  "x-app-secret": appId,
@@ -38524,7 +38772,7 @@ function useRealtime(channel, options = {}) {
38524
38772
  }),
38525
38773
  [appId]
38526
38774
  );
38527
- const fetchHistory = useCallback46(async () => {
38775
+ const fetchHistory = useCallback45(async () => {
38528
38776
  if (!history2) return;
38529
38777
  const historyLimit = typeof history2 === "number" ? history2 : history2.limit ?? 100;
38530
38778
  const historyStart = typeof history2 === "object" ? history2.start : void 0;
@@ -38548,7 +38796,7 @@ function useRealtime(channel, options = {}) {
38548
38796
  } catch {
38549
38797
  }
38550
38798
  }, [platformUrl, sdkHeaders, channel, history2]);
38551
- const connect = useCallback46(() => {
38799
+ const connect = useCallback45(() => {
38552
38800
  if (!enabled || !appId) return;
38553
38801
  if (eventSourceRef.current) {
38554
38802
  eventSourceRef.current.close();
@@ -38619,7 +38867,7 @@ function useRealtime(channel, options = {}) {
38619
38867
  onReconnect,
38620
38868
  onError
38621
38869
  ]);
38622
- const disconnect = useCallback46(() => {
38870
+ const disconnect = useCallback45(() => {
38623
38871
  if (eventSourceRef.current) {
38624
38872
  eventSourceRef.current.close();
38625
38873
  eventSourceRef.current = null;
@@ -38630,7 +38878,7 @@ function useRealtime(channel, options = {}) {
38630
38878
  }
38631
38879
  setStatus("disconnected");
38632
38880
  }, []);
38633
- const emit = useCallback46(
38881
+ const emit = useCallback45(
38634
38882
  async (event, data) => {
38635
38883
  const response = await fetch(`${platformUrl}${SDK_API_PATH}/realtime/emit`, {
38636
38884
  method: "POST",
@@ -38662,7 +38910,7 @@ function useRealtime(channel, options = {}) {
38662
38910
  },
38663
38911
  [platformUrl, sdkHeaders, channel]
38664
38912
  );
38665
- const clear = useCallback46(() => {
38913
+ const clear = useCallback45(() => {
38666
38914
  setMessages([]);
38667
38915
  lastAckRef.current = "0";
38668
38916
  }, []);
@@ -38695,14 +38943,14 @@ function useRealtimeChannels(channels, options = {}) {
38695
38943
  enabled = true,
38696
38944
  platformUrl: customPlatformUrl
38697
38945
  } = options;
38698
- const [messages, setMessages] = useState62([]);
38699
- const [statuses, setStatuses] = useState62({});
38700
- const platformContext = useContext22(PlatformContext);
38946
+ const [messages, setMessages] = useState61([]);
38947
+ const [statuses, setStatuses] = useState61({});
38948
+ const platformContext = useContext23(PlatformContext);
38701
38949
  const appId = platformContext?.appId || "";
38702
38950
  const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
38703
- const lastAcksRef = useRef26({});
38704
- const eventSourcesRef = useRef26({});
38705
- const mountedRef = useRef26(true);
38951
+ const lastAcksRef = useRef24({});
38952
+ const eventSourcesRef = useRef24({});
38953
+ const mountedRef = useRef24(true);
38706
38954
  const status = (() => {
38707
38955
  const statusValues = Object.values(statuses);
38708
38956
  if (statusValues.length === 0) return "disconnected";
@@ -38711,7 +38959,7 @@ function useRealtimeChannels(channels, options = {}) {
38711
38959
  if (statusValues.every((s2) => s2 === "connected")) return "connected";
38712
38960
  return "disconnected";
38713
38961
  })();
38714
- const connectChannel = useCallback46(
38962
+ const connectChannel = useCallback45(
38715
38963
  (channel) => {
38716
38964
  if (!enabled || !appId) return;
38717
38965
  if (eventSourcesRef.current[channel]) {
@@ -38761,17 +39009,17 @@ function useRealtimeChannels(channels, options = {}) {
38761
39009
  },
38762
39010
  [enabled, appId, platformUrl, events, onConnect, onMessage, onReconnect, onError]
38763
39011
  );
38764
- const connect = useCallback46(() => {
39012
+ const connect = useCallback45(() => {
38765
39013
  channels.forEach(connectChannel);
38766
39014
  }, [channels, connectChannel]);
38767
- const disconnect = useCallback46(() => {
39015
+ const disconnect = useCallback45(() => {
38768
39016
  Object.values(eventSourcesRef.current).forEach((es) => {
38769
39017
  es.close();
38770
39018
  });
38771
39019
  eventSourcesRef.current = {};
38772
39020
  setStatuses({});
38773
39021
  }, []);
38774
- const sdkHeaders = useMemo15(
39022
+ const sdkHeaders = useMemo16(
38775
39023
  () => ({
38776
39024
  "Content-Type": "application/json",
38777
39025
  "x-app-secret": appId,
@@ -38780,7 +39028,7 @@ function useRealtimeChannels(channels, options = {}) {
38780
39028
  }),
38781
39029
  [appId]
38782
39030
  );
38783
- const emit = useCallback46(
39031
+ const emit = useCallback45(
38784
39032
  async (event, data, targetChannel) => {
38785
39033
  const channel = targetChannel || channels[0];
38786
39034
  if (!channel) throw new SylphxError("No channel specified", { code: "BAD_REQUEST" });
@@ -38807,7 +39055,7 @@ function useRealtimeChannels(channels, options = {}) {
38807
39055
  },
38808
39056
  [channels, platformUrl, sdkHeaders]
38809
39057
  );
38810
- const clear = useCallback46(() => {
39058
+ const clear = useCallback45(() => {
38811
39059
  setMessages([]);
38812
39060
  lastAcksRef.current = {};
38813
39061
  }, []);
@@ -38833,13 +39081,13 @@ function useRealtimeChannels(channels, options = {}) {
38833
39081
 
38834
39082
  // src/react/hooks/use-kv.ts
38835
39083
  init_constants();
38836
- import { useCallback as useCallback47, useContext as useContext23, useMemo as useMemo16 } from "react";
39084
+ import { useCallback as useCallback46, useContext as useContext24, useMemo as useMemo17 } from "react";
38837
39085
  function useKv(options = {}) {
38838
39086
  const { platformUrl: customPlatformUrl } = options;
38839
- const platformContext = useContext23(PlatformContext);
39087
+ const platformContext = useContext24(PlatformContext);
38840
39088
  const appId = platformContext?.appId || "";
38841
39089
  const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
38842
- const headers = useMemo16(
39090
+ const headers = useMemo17(
38843
39091
  () => ({
38844
39092
  "Content-Type": "application/json",
38845
39093
  "x-app-secret": appId,
@@ -38848,7 +39096,7 @@ function useKv(options = {}) {
38848
39096
  }),
38849
39097
  [appId]
38850
39098
  );
38851
- const request = useCallback47(
39099
+ const request = useCallback46(
38852
39100
  async (method, path, body) => {
38853
39101
  let lastError;
38854
39102
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
@@ -38904,13 +39152,13 @@ function useKv(options = {}) {
38904
39152
  },
38905
39153
  [platformUrl, headers]
38906
39154
  );
38907
- const get = useCallback47(
39155
+ const get = useCallback46(
38908
39156
  async (key) => {
38909
39157
  return request("GET", `/${encodeURIComponent(key)}`);
38910
39158
  },
38911
39159
  [request]
38912
39160
  );
38913
- const set = useCallback47(
39161
+ const set = useCallback46(
38914
39162
  async (key, value, options2) => {
38915
39163
  const result = await request("POST", "", {
38916
39164
  key,
@@ -38921,28 +39169,28 @@ function useKv(options = {}) {
38921
39169
  },
38922
39170
  [request]
38923
39171
  );
38924
- const del = useCallback47(
39172
+ const del = useCallback46(
38925
39173
  async (key) => {
38926
39174
  const result = await request("DELETE", `/${encodeURIComponent(key)}`);
38927
39175
  return result.deleted;
38928
39176
  },
38929
39177
  [request]
38930
39178
  );
38931
- const exists = useCallback47(
39179
+ const exists = useCallback46(
38932
39180
  async (key) => {
38933
39181
  const result = await request("GET", `/exists/${encodeURIComponent(key)}`);
38934
39182
  return result.exists;
38935
39183
  },
38936
39184
  [request]
38937
39185
  );
38938
- const mget = useCallback47(
39186
+ const mget = useCallback46(
38939
39187
  async (keys) => {
38940
39188
  const result = await request("POST", "/mget", { keys });
38941
39189
  return result.values;
38942
39190
  },
38943
39191
  [request]
38944
39192
  );
38945
- const mset = useCallback47(
39193
+ const mset = useCallback46(
38946
39194
  async (entries, options2) => {
38947
39195
  await request("POST", "/mset", {
38948
39196
  entries,
@@ -38951,7 +39199,7 @@ function useKv(options = {}) {
38951
39199
  },
38952
39200
  [request]
38953
39201
  );
38954
- const incr = useCallback47(
39202
+ const incr = useCallback46(
38955
39203
  async (key, by = 1) => {
38956
39204
  const result = await request("POST", "/incr", {
38957
39205
  key,
@@ -38961,7 +39209,7 @@ function useKv(options = {}) {
38961
39209
  },
38962
39210
  [request]
38963
39211
  );
38964
- const expire = useCallback47(
39212
+ const expire = useCallback46(
38965
39213
  async (key, seconds) => {
38966
39214
  const result = await request("POST", "/expire", {
38967
39215
  key,
@@ -38971,7 +39219,7 @@ function useKv(options = {}) {
38971
39219
  },
38972
39220
  [request]
38973
39221
  );
38974
- const ratelimit = useCallback47(
39222
+ const ratelimit = useCallback46(
38975
39223
  async (key, options2) => {
38976
39224
  return request("POST", "/ratelimit", {
38977
39225
  key,
@@ -38980,7 +39228,7 @@ function useKv(options = {}) {
38980
39228
  },
38981
39229
  [request]
38982
39230
  );
38983
- const hset = useCallback47(
39231
+ const hset = useCallback46(
38984
39232
  async (key, fields) => {
38985
39233
  const result = await request("POST", "/hset", {
38986
39234
  key,
@@ -38990,7 +39238,7 @@ function useKv(options = {}) {
38990
39238
  },
38991
39239
  [request]
38992
39240
  );
38993
- const hget = useCallback47(
39241
+ const hget = useCallback46(
38994
39242
  async (key, field) => {
38995
39243
  const result = await request("POST", "/hget", {
38996
39244
  key,
@@ -39000,7 +39248,7 @@ function useKv(options = {}) {
39000
39248
  },
39001
39249
  [request]
39002
39250
  );
39003
- const hgetall = useCallback47(
39251
+ const hgetall = useCallback46(
39004
39252
  async (key) => {
39005
39253
  const result = await request("POST", "/hgetall", {
39006
39254
  key
@@ -39009,7 +39257,7 @@ function useKv(options = {}) {
39009
39257
  },
39010
39258
  [request]
39011
39259
  );
39012
- const lpush = useCallback47(
39260
+ const lpush = useCallback46(
39013
39261
  async (key, ...values) => {
39014
39262
  const result = await request("POST", "/lpush", {
39015
39263
  key,
@@ -39019,7 +39267,7 @@ function useKv(options = {}) {
39019
39267
  },
39020
39268
  [request]
39021
39269
  );
39022
- const lrange = useCallback47(
39270
+ const lrange = useCallback46(
39023
39271
  async (key, start = 0, stop = -1) => {
39024
39272
  const result = await request("POST", "/lrange", {
39025
39273
  key,
@@ -39030,7 +39278,7 @@ function useKv(options = {}) {
39030
39278
  },
39031
39279
  [request]
39032
39280
  );
39033
- const zadd = useCallback47(
39281
+ const zadd = useCallback46(
39034
39282
  async (key, ...members) => {
39035
39283
  const result = await request("POST", "/zadd", {
39036
39284
  key,
@@ -39040,7 +39288,7 @@ function useKv(options = {}) {
39040
39288
  },
39041
39289
  [request]
39042
39290
  );
39043
- const zrange = useCallback47(
39291
+ const zrange = useCallback46(
39044
39292
  async (key, start = 0, stop = 9, options2) => {
39045
39293
  const result = await request("POST", "/zrange", {
39046
39294
  key,
@@ -39053,7 +39301,7 @@ function useKv(options = {}) {
39053
39301
  },
39054
39302
  [request]
39055
39303
  );
39056
- return useMemo16(
39304
+ return useMemo17(
39057
39305
  () => ({
39058
39306
  get,
39059
39307
  set,
@@ -39094,7 +39342,7 @@ function useKv(options = {}) {
39094
39342
  }
39095
39343
 
39096
39344
  // src/react/hooks/use-search.ts
39097
- import { useCallback as useCallback48, useEffect as useEffect56, useRef as useRef27, useState as useState63 } from "react";
39345
+ import { useCallback as useCallback47, useEffect as useEffect56, useRef as useRef25, useState as useState62 } from "react";
39098
39346
 
39099
39347
  // src/search.ts
39100
39348
  async function search(config2, input) {
@@ -39128,19 +39376,19 @@ function useSearch(config2, options = {}) {
39128
39376
  initialQuery = "",
39129
39377
  ...searchOptions
39130
39378
  } = options;
39131
- const [query, setQueryState] = useState63(initialQuery);
39132
- const [results, setResults] = useState63([]);
39133
- const [total, setTotal] = useState63(0);
39134
- const [loading, setLoading] = useState63(false);
39135
- const [error, setError] = useState63(null);
39136
- const [response, setResponse] = useState63(null);
39137
- const debounceTimer = useRef27(null);
39138
- const abortController = useRef27(null);
39139
- const searchOptionsRef = useRef27(searchOptions);
39379
+ const [query, setQueryState] = useState62(initialQuery);
39380
+ const [results, setResults] = useState62([]);
39381
+ const [total, setTotal] = useState62(0);
39382
+ const [loading, setLoading] = useState62(false);
39383
+ const [error, setError] = useState62(null);
39384
+ const [response, setResponse] = useState62(null);
39385
+ const debounceTimer = useRef25(null);
39386
+ const abortController = useRef25(null);
39387
+ const searchOptionsRef = useRef25(searchOptions);
39140
39388
  useEffect56(() => {
39141
39389
  searchOptionsRef.current = searchOptions;
39142
39390
  });
39143
- const executeSearch = useCallback48(
39391
+ const executeSearch = useCallback47(
39144
39392
  async (q2) => {
39145
39393
  if (!q2 || q2.length < minLength) {
39146
39394
  setResults([]);
@@ -39172,7 +39420,7 @@ function useSearch(config2, options = {}) {
39172
39420
  },
39173
39421
  [config2, minLength]
39174
39422
  );
39175
- const setQuery = useCallback48(
39423
+ const setQuery = useCallback47(
39176
39424
  (q2) => {
39177
39425
  setQueryState(q2);
39178
39426
  if (debounceTimer.current) {
@@ -39192,7 +39440,7 @@ function useSearch(config2, options = {}) {
39192
39440
  },
39193
39441
  [executeSearch, debounceMs, minLength]
39194
39442
  );
39195
- const clear = useCallback48(() => {
39443
+ const clear = useCallback47(() => {
39196
39444
  if (debounceTimer.current) clearTimeout(debounceTimer.current);
39197
39445
  abortController.current?.abort();
39198
39446
  setQueryState("");
@@ -39202,10 +39450,10 @@ function useSearch(config2, options = {}) {
39202
39450
  setLoading(false);
39203
39451
  setError(null);
39204
39452
  }, []);
39205
- const refetch = useCallback48(() => {
39453
+ const refetch = useCallback47(() => {
39206
39454
  executeSearch(query);
39207
39455
  }, [executeSearch, query]);
39208
- const trackResultClick = useCallback48((_documentId, _resultRank) => {
39456
+ const trackResultClick = useCallback47((_documentId, _resultRank) => {
39209
39457
  }, []);
39210
39458
  useEffect56(() => {
39211
39459
  if (initialQuery && initialQuery.length >= minLength) {
@@ -39636,7 +39884,6 @@ export {
39636
39884
  SpeedInsights,
39637
39885
  StatsCard,
39638
39886
  StatsGrid,
39639
- StorageContext,
39640
39887
  SubscriberPreferences,
39641
39888
  SylphxError,
39642
39889
  SylphxErrorBoundary,
@@ -39770,7 +40017,8 @@ export {
39770
40017
  useFeatureFlagDefinitions,
39771
40018
  useFeatureFlags,
39772
40019
  useFeatureTracking,
39773
- useFileUpload,
40020
+ useFile,
40021
+ useFileList,
39774
40022
  useFlag,
39775
40023
  useFlagEvaluation,
39776
40024
  useFlagJSON,
@@ -39830,7 +40078,6 @@ export {
39830
40078
  useSignUpForm,
39831
40079
  useAnalyticsHook as useSmartAnalytics,
39832
40080
  useStorage,
39833
- useStorageContext,
39834
40081
  useStreak,
39835
40082
  useSubscriberForm,
39836
40083
  useSylphx,
@@ -39838,7 +40085,6 @@ export {
39838
40085
  useTasks,
39839
40086
  useTasksContext,
39840
40087
  useTimeTracking,
39841
- useUpload,
39842
40088
  useUser,
39843
40089
  useUserContext,
39844
40090
  useWebAnalytics,
@@ -39857,7 +40103,7 @@ export {
39857
40103
  validateSecretKey,
39858
40104
  validateWorkflow,
39859
40105
  wait,
39860
- withRetry,
40106
+ withRetry2 as withRetry,
39861
40107
  withSessionReplay,
39862
40108
  withTimeout
39863
40109
  };