@sylphx/sdk 0.9.0 → 0.10.1

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");
@@ -1045,7 +1041,7 @@ var PlatformContext = createContext3(null);
1045
1041
  // src/connection-url.ts
1046
1042
  var SYLPHX_PROTOCOL = "sylphx:";
1047
1043
  var DEFAULT_VERSION = "v1";
1048
- var CREDENTIAL_REGEX = /^(pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}$/;
1044
+ var CREDENTIAL_REGEX = /^(pk|sk)_(dev|stg|prod|prev)(?:_[a-z0-9]{12})?_[a-f0-9]{32,64}$/;
1049
1045
  var VERSION_REGEX = /^v[0-9]+$/;
1050
1046
  var SLUG_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
1051
1047
  var InvalidConnectionUrlError = class _InvalidConnectionUrlError extends Error {
@@ -1062,7 +1058,7 @@ function fail(reason) {
1062
1058
  function parseCredential(raw) {
1063
1059
  const match = CREDENTIAL_REGEX.exec(raw);
1064
1060
  if (!match) {
1065
- fail(`credential must match (pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}, got "${raw}"`);
1061
+ fail(`credential must match (pk|sk)_(dev|stg|prod|prev)(_{ref})?_{hex}, got "${raw}"`);
1066
1062
  }
1067
1063
  return {
1068
1064
  credentialType: match[1],
@@ -1140,7 +1136,7 @@ function parseConnectionUrl(url) {
1140
1136
  init_constants();
1141
1137
  var LEGACY_EMBEDDED_REF_PATTERN = /^(pk|sk)_(dev|stg|prod|prev)_[a-z0-9]{12}_[a-f0-9]+$/;
1142
1138
  var LEGACY_APP_KEY_PATTERN = /^app_(dev|stg|prod|prev)_/;
1143
- var MIGRATION_MESSAGE = "API key format has changed. Use a sylphx:// connection URL instead.\n\nNew format: sylphx://pk_prod_{hex}@your-slug.api.sylphx.com\n\nGenerate new credentials from the Sylphx Console \u2192 Your App \u2192 Environments.\nSee https://docs.sylphx.com/migration for details.";
1139
+ var MIGRATION_MESSAGE = "API key format has changed. Use a sylphx:// connection URL instead.\n\nNew format: sylphx://pk_prod_{ref?}_{hex}@your-slug.api.sylphx.com\n\nGenerate new credentials from the Sylphx Console \u2192 Your App \u2192 Environments.\nSee https://docs.sylphx.com/migration for details.";
1144
1140
  function rejectLegacyKeyFormat(input) {
1145
1141
  const trimmed = input.trim().toLowerCase();
1146
1142
  if (LEGACY_APP_KEY_PATTERN.test(trimmed)) {
@@ -1263,7 +1259,7 @@ function createConfigFromComponents(input) {
1263
1259
  });
1264
1260
  }
1265
1261
  throw new SylphxError(
1266
- `[Sylphx] Invalid credential format. Expected (pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}. Got: "${trimmedCred.slice(0, 30)}..."`,
1262
+ `[Sylphx] Invalid credential format. Expected (pk|sk)_(dev|stg|prod|prev)(_{ref})?_{hex}. Got: "${trimmedCred.slice(0, 30)}..."`,
1267
1263
  { code: "BAD_REQUEST" }
1268
1264
  );
1269
1265
  }
@@ -2752,6 +2748,7 @@ var ORG_STORAGE_KEY = "sylphx_active_org";
2752
2748
  var ORG_BROADCAST_CHANNEL = "sylphx_org_sync";
2753
2749
  function useOrganization() {
2754
2750
  const platform = useContext4(PlatformContext);
2751
+ const auth = useAuthContextSafe();
2755
2752
  const [organizations, setOrganizations] = useState4([]);
2756
2753
  const [organization, setOrganization] = useState4(null);
2757
2754
  const [members, setMembers] = useState4([]);
@@ -2828,6 +2825,9 @@ function useOrganization() {
2828
2825
  }
2829
2826
  try {
2830
2827
  const result = await getOrganization(config2, orgIdOrSlug);
2828
+ if (auth?.isSignedIn) {
2829
+ await auth.switchOrganizationToken(result.organization.id);
2830
+ }
2831
2831
  setOrganization(result.organization);
2832
2832
  setRole(result.membership?.role ?? null);
2833
2833
  storeOrgSlug(result.organization.slug);
@@ -2848,7 +2848,7 @@ function useOrganization() {
2848
2848
  setError(err instanceof Error ? err : new Error("Failed to load organization"));
2849
2849
  }
2850
2850
  },
2851
- [config2, storeOrgSlug, broadcastOrgChange]
2851
+ [auth, config2, storeOrgSlug, broadcastOrgChange]
2852
2852
  );
2853
2853
  useEffect3(() => {
2854
2854
  if (!config2) {
@@ -3010,6 +3010,7 @@ function useOrganization() {
3010
3010
  role,
3011
3011
  hasPermission: hasPermission2,
3012
3012
  setOrganization: selectOrganization,
3013
+ switchOrg: selectOrganization,
3013
3014
  createOrganization: createOrg,
3014
3015
  updateOrganization: updateOrg,
3015
3016
  deleteOrganization: deleteOrg,
@@ -11139,78 +11140,13 @@ function useTaskRun(runId, options) {
11139
11140
  };
11140
11141
  }
11141
11142
 
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
11143
  // src/react/monitoring-hooks.ts
11208
- import { useCallback as useCallback26, useEffect as useEffect22, useRef as useRef10 } from "react";
11144
+ import { useCallback as useCallback25, useEffect as useEffect22, useRef as useRef9 } from "react";
11209
11145
  function useErrorTracking() {
11210
11146
  const ctx = useMonitoringContext();
11211
- const breadcrumbsRef = useRef10([]);
11212
- const routeRef = useRef10(null);
11213
- const captureException = useCallback26(
11147
+ const breadcrumbsRef = useRef9([]);
11148
+ const routeRef = useRef9(null);
11149
+ const captureException = useCallback25(
11214
11150
  async (error, options = {}) => {
11215
11151
  try {
11216
11152
  const result = await ctx.captureException(error, {
@@ -11233,7 +11169,7 @@ function useErrorTracking() {
11233
11169
  },
11234
11170
  [ctx]
11235
11171
  );
11236
- const captureMessage = useCallback26(
11172
+ const captureMessage = useCallback25(
11237
11173
  async (message, options = {}) => {
11238
11174
  try {
11239
11175
  const result = await ctx.captureMessage(message, {
@@ -11250,7 +11186,7 @@ function useErrorTracking() {
11250
11186
  },
11251
11187
  [ctx]
11252
11188
  );
11253
- const addBreadcrumb2 = useCallback26((breadcrumb) => {
11189
+ const addBreadcrumb2 = useCallback25((breadcrumb) => {
11254
11190
  breadcrumbsRef.current.push({
11255
11191
  ...breadcrumb,
11256
11192
  timestamp: breadcrumb.timestamp ?? Date.now()
@@ -11259,7 +11195,7 @@ function useErrorTracking() {
11259
11195
  breadcrumbsRef.current = breadcrumbsRef.current.slice(-100);
11260
11196
  }
11261
11197
  }, []);
11262
- const setRoute = useCallback26(
11198
+ const setRoute = useCallback25(
11263
11199
  (route) => {
11264
11200
  routeRef.current = route;
11265
11201
  addBreadcrumb2({
@@ -11279,7 +11215,7 @@ function useErrorTracking() {
11279
11215
  }
11280
11216
  function useErrorBoundary(options = {}) {
11281
11217
  const { captureException } = useErrorTracking();
11282
- const handleError = useCallback26(
11218
+ const handleError = useCallback25(
11283
11219
  async (error, errorInfo) => {
11284
11220
  const eventId = await captureException(error, {
11285
11221
  tags: {
@@ -11339,17 +11275,17 @@ function useGlobalErrorHandler(options = {}) {
11339
11275
  }
11340
11276
 
11341
11277
  // src/react/newsletter-hooks.ts
11342
- import { useCallback as useCallback27, useState as useState30 } from "react";
11278
+ import { useCallback as useCallback26, useState as useState29 } from "react";
11343
11279
  function useNewsletter() {
11344
11280
  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(() => {
11281
+ const [isLoading, setIsLoading] = useState29(false);
11282
+ const [success, setSuccess] = useState29(false);
11283
+ const [error, setError] = useState29(null);
11284
+ const reset = useCallback26(() => {
11349
11285
  setSuccess(false);
11350
11286
  setError(null);
11351
11287
  }, []);
11352
- const subscribe = useCallback27(
11288
+ const subscribe = useCallback26(
11353
11289
  async (options) => {
11354
11290
  setIsLoading(true);
11355
11291
  setError(null);
@@ -11368,7 +11304,7 @@ function useNewsletter() {
11368
11304
  },
11369
11305
  [ctx]
11370
11306
  );
11371
- const verify = useCallback27(
11307
+ const verify = useCallback26(
11372
11308
  async (token) => {
11373
11309
  setIsLoading(true);
11374
11310
  setError(null);
@@ -11386,7 +11322,7 @@ function useNewsletter() {
11386
11322
  },
11387
11323
  [ctx]
11388
11324
  );
11389
- const unsubscribe = useCallback27(
11325
+ const unsubscribe = useCallback26(
11390
11326
  async (email, token) => {
11391
11327
  setIsLoading(true);
11392
11328
  setError(null);
@@ -11404,7 +11340,7 @@ function useNewsletter() {
11404
11340
  },
11405
11341
  [ctx]
11406
11342
  );
11407
- const resendVerification = useCallback27(
11343
+ const resendVerification = useCallback26(
11408
11344
  async (email) => {
11409
11345
  setIsLoading(true);
11410
11346
  setError(null);
@@ -11422,7 +11358,7 @@ function useNewsletter() {
11422
11358
  },
11423
11359
  [ctx]
11424
11360
  );
11425
- const getUnsubscribeInfo = useCallback27(
11361
+ const getUnsubscribeInfo = useCallback26(
11426
11362
  async (token) => {
11427
11363
  try {
11428
11364
  return await ctx.getUnsubscribeInfo(token);
@@ -11434,7 +11370,7 @@ function useNewsletter() {
11434
11370
  },
11435
11371
  [ctx]
11436
11372
  );
11437
- const updatePreferences = useCallback27(
11373
+ const updatePreferences = useCallback26(
11438
11374
  async (email, preferences) => {
11439
11375
  setIsLoading(true);
11440
11376
  setError(null);
@@ -11452,7 +11388,7 @@ function useNewsletter() {
11452
11388
  },
11453
11389
  [ctx]
11454
11390
  );
11455
- const getPreferences = useCallback27(
11391
+ const getPreferences = useCallback26(
11456
11392
  async (email) => {
11457
11393
  try {
11458
11394
  return await ctx.getPreferences(email);
@@ -11480,20 +11416,20 @@ function useNewsletter() {
11480
11416
  }
11481
11417
  function useSubscriberForm(options = {}) {
11482
11418
  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) => {
11419
+ const [email, setEmail] = useState29("");
11420
+ const [preferences, setPreferences] = useState29(options.preferences || {});
11421
+ const [isLoading, setIsLoading] = useState29(false);
11422
+ const [success, setSuccess] = useState29(false);
11423
+ const [requiresVerification, setRequiresVerification] = useState29(false);
11424
+ const [alreadySubscribed, setAlreadySubscribed] = useState29(false);
11425
+ const [error, setError] = useState29(null);
11426
+ const togglePreference = useCallback26((pref) => {
11491
11427
  setPreferences((prev) => ({ ...prev, [pref]: !prev[pref] }));
11492
11428
  }, []);
11493
- const setPreference = useCallback27((pref, value) => {
11429
+ const setPreference = useCallback26((pref, value) => {
11494
11430
  setPreferences((prev) => ({ ...prev, [pref]: value }));
11495
11431
  }, []);
11496
- const reset = useCallback27(() => {
11432
+ const reset = useCallback26(() => {
11497
11433
  setEmail("");
11498
11434
  setPreferences(options.preferences || {});
11499
11435
  setSuccess(false);
@@ -11501,7 +11437,7 @@ function useSubscriberForm(options = {}) {
11501
11437
  setAlreadySubscribed(false);
11502
11438
  setError(null);
11503
11439
  }, [options.preferences]);
11504
- const submit = useCallback27(
11440
+ const submit = useCallback26(
11505
11441
  async (e2) => {
11506
11442
  e2?.preventDefault();
11507
11443
  if (!email) {
@@ -11598,7 +11534,7 @@ function AuthLoading({ children, loading = null }) {
11598
11534
 
11599
11535
  // src/react/provider.tsx
11600
11536
  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";
11537
+ import { useCallback as useCallback27, useEffect as useEffect23, useMemo as useMemo9, useRef as useRef10, useState as useState30 } from "react";
11602
11538
 
11603
11539
  // src/consent.ts
11604
11540
  async function linkAnonymousConsents(config2, input) {
@@ -11612,13 +11548,14 @@ async function linkAnonymousConsents(config2, input) {
11612
11548
  init_constants();
11613
11549
 
11614
11550
  // src/key-validation.ts
11615
- var PUBLIC_KEY_PATTERN = /^pk_(dev|stg|prod)_[a-z0-9]{12}_[a-f0-9]{32}$/;
11551
+ var PUBLIC_KEY_PATTERN = /^pk_(dev|stg|prod|prev)(?:_[a-z0-9]{12})?_[a-f0-9]{32}$/;
11616
11552
  var APP_ID_PATTERN = /^(app|pk)_(dev|stg|prod|prev)_[a-z0-9_-]+$/;
11617
- var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod)_[a-z0-9_-]+$/;
11553
+ var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod|prev)_[a-z0-9_-]+$/;
11618
11554
  var ENV_PREFIX_MAP = {
11619
11555
  dev: "development",
11620
11556
  stg: "staging",
11621
- prod: "production"
11557
+ prod: "production",
11558
+ prev: "preview"
11622
11559
  };
11623
11560
  function detectKeyIssues(key) {
11624
11561
  const issues = [];
@@ -11643,7 +11580,7 @@ The SDK will automatically sanitize the key, but fixing the source is recommende
11643
11580
  }
11644
11581
  function createInvalidKeyError(keyType, key, envVarName) {
11645
11582
  const maskedKey = key.length > 20 ? `${key.slice(0, 20)}...` : key;
11646
- const formatHint = keyType === "appId" ? "pk_(dev|stg|prod)_{ref}_{hex} or app_(dev|stg|prod)_[id]" : "sk_(dev|stg|prod)_{ref}_{hex}";
11583
+ const formatHint = keyType === "appId" ? "pk_(dev|stg|prod|prev)_{ref}_{hex} or app_(dev|stg|prod|prev)_[id]" : "sk_(dev|stg|prod|prev)_{ref}_{hex}";
11647
11584
  const keyTypeName = keyType === "appId" ? "App ID" : "Secret Key";
11648
11585
  return `[Sylphx] Invalid ${keyTypeName} format.
11649
11586
 
@@ -11656,7 +11593,7 @@ You can find your keys in the Sylphx Console \u2192 API Keys.
11656
11593
  Common issues:
11657
11594
  \u2022 Key has uppercase characters (must be lowercase)
11658
11595
  \u2022 Key has wrong prefix (App ID: pk_ or app_, Secret Key: sk_)
11659
- \u2022 Key has invalid environment (must be dev, stg, or prod)
11596
+ \u2022 Key has invalid environment (must be dev, stg, prod, or prev)
11660
11597
  \u2022 Key was copied with extra whitespace`;
11661
11598
  }
11662
11599
  function extractEnvironment(key) {
@@ -11703,7 +11640,7 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
11703
11640
  };
11704
11641
  }
11705
11642
  function validatePublicKey(key) {
11706
- return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "NEXT_PUBLIC_SYLPHX_KEY");
11643
+ return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "publishable credential");
11707
11644
  }
11708
11645
  function validateAppId(key) {
11709
11646
  return validateKeyForType(key, "appId", APP_ID_PATTERN, "NEXT_PUBLIC_SYLPHX_APP_ID");
@@ -11719,7 +11656,7 @@ function validateAndSanitizeAppId(key) {
11719
11656
  return result.sanitizedKey;
11720
11657
  }
11721
11658
  function validateSecretKey(key) {
11722
- return validateKeyForType(key, "secret", SECRET_KEY_PATTERN, "SYLPHX_SECRET_KEY");
11659
+ return validateKeyForType(key, "secret", SECRET_KEY_PATTERN, "secret credential");
11723
11660
  }
11724
11661
  function validateAndSanitizeSecretKey(key) {
11725
11662
  const result = validateSecretKey(key);
@@ -11760,7 +11697,7 @@ function isProductionKey(key) {
11760
11697
  }
11761
11698
  function getCookieNamespace(secretKey) {
11762
11699
  const env = detectEnvironment(secretKey);
11763
- const shortEnv = env === "development" ? "dev" : env === "staging" ? "stg" : "prod";
11700
+ const shortEnv = env === "development" ? "dev" : env === "staging" ? "stg" : env === "preview" ? "prev" : "prod";
11764
11701
  return `sylphx_${shortEnv}`;
11765
11702
  }
11766
11703
  function detectKeyType(key) {
@@ -11790,7 +11727,7 @@ function validateKey(key) {
11790
11727
  return {
11791
11728
  valid: false,
11792
11729
  sanitizedKey: "",
11793
- error: key ? `Invalid key format. Keys must start with 'pk_' (publishable), 'app_' (legacy), or 'sk_' (secret), followed by environment (dev/stg/prod). Got: ${key.slice(0, 20)}...` : "API key is required but was not provided.",
11730
+ error: key ? `Invalid key format. Keys must start with 'pk_' (publishable), 'app_' (legacy), or 'sk_' (secret), followed by environment (dev/stg/prod/prev). Got: ${key.slice(0, 20)}...` : "API key is required but was not provided.",
11794
11731
  issues: key ? ["invalid_format"] : ["missing"]
11795
11732
  };
11796
11733
  }
@@ -12319,101 +12256,6 @@ function createNewsletterValue(config2) {
12319
12256
  };
12320
12257
  }
12321
12258
 
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
12259
  // src/react/context-values/webhooks.ts
12418
12260
  function createWebhooksValue(config2) {
12419
12261
  const { api } = config2;
@@ -12603,11 +12445,11 @@ function generateAnonymousId() {
12603
12445
  return v2.toString(16);
12604
12446
  });
12605
12447
  }
12606
- function getOrCreateAnonymousId(storage) {
12607
- let anonymousId = storage.get(STORAGE_KEYS.ANONYMOUS_ID);
12448
+ function getOrCreateAnonymousId(storage2) {
12449
+ let anonymousId = storage2.get(STORAGE_KEYS.ANONYMOUS_ID);
12608
12450
  if (!anonymousId) {
12609
12451
  anonymousId = generateAnonymousId();
12610
- storage.set(STORAGE_KEYS.ANONYMOUS_ID, anonymousId);
12452
+ storage2.set(STORAGE_KEYS.ANONYMOUS_ID, anonymousId);
12611
12453
  }
12612
12454
  return anonymousId;
12613
12455
  }
@@ -12623,29 +12465,29 @@ function captureClickIdsFromUrl() {
12623
12465
  if (ttclid) clickIds.ttclid = ttclid;
12624
12466
  return clickIds;
12625
12467
  }
12626
- function getStoredClickIds(storage) {
12627
- const capturedAtStr = storage.get(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12468
+ function getStoredClickIds(storage2) {
12469
+ const capturedAtStr = storage2.get(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12628
12470
  if (!capturedAtStr) return null;
12629
12471
  const capturedAt = Number.parseInt(capturedAtStr, 10);
12630
12472
  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);
12473
+ storage2.remove(STORAGE_KEYS.CLICK_IDS);
12474
+ storage2.remove(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT);
12633
12475
  return null;
12634
12476
  }
12635
- return storage.getJSON(STORAGE_KEYS.CLICK_IDS);
12477
+ return storage2.getJSON(STORAGE_KEYS.CLICK_IDS);
12636
12478
  }
12637
- function storeClickIds(storage, clickIds) {
12479
+ function storeClickIds(storage2, clickIds) {
12638
12480
  if (Object.keys(clickIds).length === 0) return;
12639
- const existing = getStoredClickIds(storage) || {};
12481
+ const existing = getStoredClickIds(storage2) || {};
12640
12482
  const merged = { ...existing, ...clickIds };
12641
- storage.setJSON(STORAGE_KEYS.CLICK_IDS, merged);
12642
- storage.set(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT, Date.now().toString());
12483
+ storage2.setJSON(STORAGE_KEYS.CLICK_IDS, merged);
12484
+ storage2.set(STORAGE_KEYS.CLICK_IDS_CAPTURED_AT, Date.now().toString());
12643
12485
  }
12644
- function autoCaptureClickIds(storage) {
12486
+ function autoCaptureClickIds(storage2) {
12645
12487
  const urlClickIds = captureClickIdsFromUrl();
12646
- const storedClickIds = getStoredClickIds(storage) || {};
12488
+ const storedClickIds = getStoredClickIds(storage2) || {};
12647
12489
  if (Object.keys(urlClickIds).length > 0) {
12648
- storeClickIds(storage, urlClickIds);
12490
+ storeClickIds(storage2, urlClickIds);
12649
12491
  return { ...storedClickIds, ...urlClickIds };
12650
12492
  }
12651
12493
  return storedClickIds;
@@ -12828,7 +12670,7 @@ function SylphxProvider({
12828
12670
  config: config2,
12829
12671
  authPrefix = "/auth"
12830
12672
  }) {
12831
- const [queryClient] = useState31(
12673
+ const [queryClient] = useState30(
12832
12674
  () => new QueryClient({
12833
12675
  defaultOptions: {
12834
12676
  queries: {
@@ -12875,20 +12717,20 @@ function SylphxProviderInner({
12875
12717
  return parts.length === 4 && /^[a-z0-9]{12}$/.test(parts[2] ?? "") ? parts[2] : void 0;
12876
12718
  })();
12877
12719
  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("");
12720
+ const storage2 = useMemo9(() => new SylphxStorage(appId), [appId]);
12721
+ const [anonymousId, setAnonymousId] = useState30("");
12880
12722
  useEffect23(() => {
12881
- setAnonymousId(getOrCreateAnonymousId(storage));
12882
- }, [storage]);
12883
- const [clickIds, setClickIds] = useState31({});
12884
- const hasInitializedClickIds = useRef11(false);
12723
+ setAnonymousId(getOrCreateAnonymousId(storage2));
12724
+ }, [storage2]);
12725
+ const [clickIds, setClickIds] = useState30({});
12726
+ const hasInitializedClickIds = useRef10(false);
12885
12727
  useEffect23(() => {
12886
12728
  if (hasInitializedClickIds.current) return;
12887
12729
  hasInitializedClickIds.current = true;
12888
- const captured = autoCaptureClickIds(storage);
12730
+ const captured = autoCaptureClickIds(storage2);
12889
12731
  setClickIds(captured);
12890
- }, [storage]);
12891
- const [authState, setAuthState] = useState31({
12732
+ }, [storage2]);
12733
+ const [authState, setAuthState] = useState30({
12892
12734
  isLoaded: false,
12893
12735
  isSignedIn: false,
12894
12736
  user: null,
@@ -12915,7 +12757,7 @@ function SylphxProviderInner({
12915
12757
  setAuthState((prev) => ({ ...prev, isLoaded: true }));
12916
12758
  }
12917
12759
  }, [appId]);
12918
- const authStateRef = useRef11(authState);
12760
+ const authStateRef = useRef10(authState);
12919
12761
  useEffect23(() => {
12920
12762
  authStateRef.current = authState;
12921
12763
  }, [authState]);
@@ -12940,7 +12782,7 @@ function SylphxProviderInner({
12940
12782
  tokenManager.clear();
12941
12783
  }
12942
12784
  }, [authState.isSignedIn, tokenManager]);
12943
- const prevIsSignedIn = useRef11(null);
12785
+ const prevIsSignedIn = useRef10(null);
12944
12786
  useEffect23(() => {
12945
12787
  if (!authState.isLoaded) return;
12946
12788
  if (prevIsSignedIn.current === null) {
@@ -13020,8 +12862,8 @@ function SylphxProviderInner({
13020
12862
  });
13021
12863
  const pushPreferences = pushPreferencesQuery.data ?? null;
13022
12864
  const pushError = pushPreferencesQuery.error;
13023
- const [pushSubscribed, setPushSubscribed] = useState31(false);
13024
- const [analyticsError, setAnalyticsError] = useState31(null);
12865
+ const [pushSubscribed, setPushSubscribed] = useState30(false);
12866
+ const [analyticsError, setAnalyticsError] = useState30(null);
13025
12867
  const mobilePushQuery = useQuery5({
13026
12868
  queryKey: ["sylphx", appId, "mobilePush"],
13027
12869
  queryFn: async () => {
@@ -13059,13 +12901,13 @@ function SylphxProviderInner({
13059
12901
  const inboxPreferences = inboxQuery.data?.preferences ?? null;
13060
12902
  const inboxLoading = inboxQuery.isLoading;
13061
12903
  const inboxError = inboxQuery.error;
13062
- const [pushSupported, setPushSupported] = useState31(false);
12904
+ const [pushSupported, setPushSupported] = useState30(false);
13063
12905
  useEffect23(() => {
13064
12906
  setPushSupported("serviceWorker" in navigator && "PushManager" in window);
13065
12907
  }, []);
13066
- const analyticsQueue = useRef11([]);
13067
- const flushTimeoutRef = useRef11(null);
13068
- const trackedEventIds = useRef11(/* @__PURE__ */ new Set());
12908
+ const analyticsQueue = useRef10([]);
12909
+ const flushTimeoutRef = useRef10(null);
12910
+ const trackedEventIds = useRef10(/* @__PURE__ */ new Set());
13069
12911
  useEffect23(() => {
13070
12912
  if (typeof window === "undefined") return;
13071
12913
  const handleBeforeUnload = () => {
@@ -13130,7 +12972,7 @@ function SylphxProviderInner({
13130
12972
  purchase: autoTracking.purchase ?? true
13131
12973
  };
13132
12974
  }, [autoTracking]);
13133
- const saveTokens = useCallback28(
12975
+ const saveTokens = useCallback27(
13134
12976
  (response) => {
13135
12977
  setAuthState({
13136
12978
  isLoaded: true,
@@ -13158,7 +13000,7 @@ function SylphxProviderInner({
13158
13000
  },
13159
13001
  [appId]
13160
13002
  );
13161
- const clearTokens = useCallback28(
13003
+ const clearTokens = useCallback27(
13162
13004
  (error) => {
13163
13005
  clearUserCookie(appId);
13164
13006
  setAuthState({
@@ -13198,6 +13040,8 @@ function SylphxProviderInner({
13198
13040
  user: event.data.user,
13199
13041
  error: null
13200
13042
  }));
13043
+ } else if (event.data?.type === "org-token-change") {
13044
+ tokenManager.invalidate();
13201
13045
  }
13202
13046
  };
13203
13047
  channel.addEventListener("message", handleMessage);
@@ -13205,7 +13049,7 @@ function SylphxProviderInner({
13205
13049
  channel.removeEventListener("message", handleMessage);
13206
13050
  channel.close();
13207
13051
  };
13208
- }, [appId]);
13052
+ }, [appId, tokenManager]);
13209
13053
  useEffect23(() => {
13210
13054
  const handleVisibilityChange = () => {
13211
13055
  if (document.visibilityState === "visible") {
@@ -13246,7 +13090,7 @@ function SylphxProviderInner({
13246
13090
  window.history.replaceState({}, "", cleanUrl.toString());
13247
13091
  }
13248
13092
  }, []);
13249
- const resolveRedirectUrl = useCallback28((url) => {
13093
+ const resolveRedirectUrl = useCallback27((url) => {
13250
13094
  if (typeof window === "undefined") return "";
13251
13095
  if (!url) return window.location.href;
13252
13096
  if (url.startsWith("/") && !url.startsWith("//")) {
@@ -13254,7 +13098,7 @@ function SylphxProviderInner({
13254
13098
  }
13255
13099
  return url;
13256
13100
  }, []);
13257
- const signIn = useCallback28(
13101
+ const signIn = useCallback27(
13258
13102
  (options) => {
13259
13103
  const resolvedUrl = resolveRedirectUrl(options?.redirectUrl);
13260
13104
  const redirectUri = isValidRedirectUrl(resolvedUrl, {
@@ -13274,7 +13118,7 @@ function SylphxProviderInner({
13274
13118
  },
13275
13119
  [appId, platformUrl, resolveRedirectUrl]
13276
13120
  );
13277
- const signUp = useCallback28(
13121
+ const signUp = useCallback27(
13278
13122
  (options) => {
13279
13123
  const resolvedUrl = resolveRedirectUrl(options?.redirectUrl);
13280
13124
  const redirectUri = isValidRedirectUrl(resolvedUrl, {
@@ -13295,7 +13139,7 @@ function SylphxProviderInner({
13295
13139
  },
13296
13140
  [appId, platformUrl, resolveRedirectUrl]
13297
13141
  );
13298
- const signOut = useCallback28(
13142
+ const signOut = useCallback27(
13299
13143
  async (options) => {
13300
13144
  try {
13301
13145
  await fetch(`${authPrefix}/signout`, {
@@ -13311,7 +13155,7 @@ function SylphxProviderInner({
13311
13155
  },
13312
13156
  [clearTokens, afterSignOutUrl, authPrefix]
13313
13157
  );
13314
- const getToken = useCallback28(async () => {
13158
+ const getToken = useCallback27(async () => {
13315
13159
  if (!authState.isSignedIn) {
13316
13160
  return null;
13317
13161
  }
@@ -13330,7 +13174,40 @@ function SylphxProviderInner({
13330
13174
  return null;
13331
13175
  }
13332
13176
  }, [authState.isSignedIn, authPrefix]);
13333
- const resetPassword = useCallback28(
13177
+ const switchOrganizationToken = useCallback27(
13178
+ async (orgId) => {
13179
+ if (!authState.isSignedIn) {
13180
+ throw new Error("Not authenticated");
13181
+ }
13182
+ const response = await fetch(`${authPrefix}/switch-org`, {
13183
+ method: "POST",
13184
+ headers: { "Content-Type": "application/json" },
13185
+ credentials: "include",
13186
+ body: JSON.stringify({ orgId })
13187
+ });
13188
+ if (!response.ok) {
13189
+ const data = await response.json().catch(() => ({}));
13190
+ throw new Error(data.error || data.message || "Failed to switch organization");
13191
+ }
13192
+ tokenManager.invalidate();
13193
+ setAuthState((prev) => ({
13194
+ ...prev,
13195
+ isLoaded: true,
13196
+ isSignedIn: true,
13197
+ error: null
13198
+ }));
13199
+ if (typeof window !== "undefined" && typeof BroadcastChannel !== "undefined") {
13200
+ try {
13201
+ const channel = new BroadcastChannel(`sylphx-auth-${appId}`);
13202
+ channel.postMessage({ type: "org-token-change" });
13203
+ channel.close();
13204
+ } catch {
13205
+ }
13206
+ }
13207
+ },
13208
+ [appId, authPrefix, authState.isSignedIn, tokenManager]
13209
+ );
13210
+ const resetPassword = useCallback27(
13334
13211
  async (options) => {
13335
13212
  await api.post("/auth/reset-password", {
13336
13213
  token: options.token,
@@ -13339,28 +13216,28 @@ function SylphxProviderInner({
13339
13216
  },
13340
13217
  [api]
13341
13218
  );
13342
- const verifyEmail = useCallback28(
13219
+ const verifyEmail = useCallback27(
13343
13220
  async (options) => {
13344
13221
  await api.post("/auth/verify-email", { token: options.token });
13345
13222
  },
13346
13223
  [api]
13347
13224
  );
13348
- const resendVerificationEmail = useCallback28(
13225
+ const resendVerificationEmail = useCallback27(
13349
13226
  async (options) => {
13350
13227
  await api.post("/auth/resend-verification", { email: options.email });
13351
13228
  },
13352
13229
  [api]
13353
13230
  );
13354
- const forgotPassword = useCallback28(
13231
+ const forgotPassword = useCallback27(
13355
13232
  async (options) => {
13356
13233
  await api.post("/auth/forgot-password", { email: options.email });
13357
13234
  },
13358
13235
  [api]
13359
13236
  );
13360
- const clearOAuthError = useCallback28(() => {
13237
+ const clearOAuthError = useCallback27(() => {
13361
13238
  setAuthState((prev) => ({ ...prev, oauthError: null }));
13362
13239
  }, []);
13363
- const signInWithOAuth = useCallback28(
13240
+ const signInWithOAuth = useCallback27(
13364
13241
  async (options) => {
13365
13242
  const { provider, redirectUrl, scopes } = options;
13366
13243
  const finalDestination = resolveRedirectUrl(redirectUrl);
@@ -13413,31 +13290,31 @@ function SylphxProviderInner({
13413
13290
  },
13414
13291
  [platformUrl, appId, resolveRedirectUrl, authPrefix]
13415
13292
  );
13416
- const signInWithGoogle = useCallback28(
13293
+ const signInWithGoogle = useCallback27(
13417
13294
  (redirectUrl) => signInWithOAuth({ provider: "google", redirectUrl }),
13418
13295
  [signInWithOAuth]
13419
13296
  );
13420
- const signInWithGithub = useCallback28(
13297
+ const signInWithGithub = useCallback27(
13421
13298
  (redirectUrl) => signInWithOAuth({ provider: "github", redirectUrl }),
13422
13299
  [signInWithOAuth]
13423
13300
  );
13424
- const signInWithApple = useCallback28(
13301
+ const signInWithApple = useCallback27(
13425
13302
  (redirectUrl) => signInWithOAuth({ provider: "apple", redirectUrl }),
13426
13303
  [signInWithOAuth]
13427
13304
  );
13428
- const signInWithDiscord = useCallback28(
13305
+ const signInWithDiscord = useCallback27(
13429
13306
  (redirectUrl) => signInWithOAuth({ provider: "discord", redirectUrl }),
13430
13307
  [signInWithOAuth]
13431
13308
  );
13432
- const signInWithTwitter = useCallback28(
13309
+ const signInWithTwitter = useCallback27(
13433
13310
  (redirectUrl) => signInWithOAuth({ provider: "twitter", redirectUrl }),
13434
13311
  [signInWithOAuth]
13435
13312
  );
13436
- const signInWithMicrosoft = useCallback28(
13313
+ const signInWithMicrosoft = useCallback27(
13437
13314
  (redirectUrl) => signInWithOAuth({ provider: "microsoft", redirectUrl }),
13438
13315
  [signInWithOAuth]
13439
13316
  );
13440
- const signInWithMagicLink = useCallback28(
13317
+ const signInWithMagicLink = useCallback27(
13441
13318
  async (options) => {
13442
13319
  const { email, redirectUrl } = options;
13443
13320
  const resolvedRedirect = resolveRedirectUrl(redirectUrl);
@@ -13459,7 +13336,7 @@ function SylphxProviderInner({
13459
13336
  },
13460
13337
  [platformUrl, appId, resolveRedirectUrl]
13461
13338
  );
13462
- const createCheckout = useCallback28(
13339
+ const createCheckout = useCallback27(
13463
13340
  async (planSlug, interval) => {
13464
13341
  if (!authState.user?.id) {
13465
13342
  throw new Error("User must be authenticated to create checkout");
@@ -13475,7 +13352,7 @@ function SylphxProviderInner({
13475
13352
  },
13476
13353
  [api, authState.user?.id]
13477
13354
  );
13478
- const openPortal = useCallback28(async () => {
13355
+ const openPortal = useCallback27(async () => {
13479
13356
  if (!authState.user?.id) {
13480
13357
  throw new Error("User must be signed in to access billing portal");
13481
13358
  }
@@ -13485,12 +13362,12 @@ function SylphxProviderInner({
13485
13362
  });
13486
13363
  window.location.href = data.portalUrl;
13487
13364
  }, [api, authState.user?.id]);
13488
- const refreshSubscription = useCallback28(async () => {
13365
+ const refreshSubscription = useCallback27(async () => {
13489
13366
  await queryClient.invalidateQueries({
13490
13367
  queryKey: ["sylphx", appId, "subscription"]
13491
13368
  });
13492
13369
  }, [queryClient, appId]);
13493
- const [isOnline, setIsOnline] = useState31(true);
13370
+ const [isOnline, setIsOnline] = useState30(true);
13494
13371
  useEffect23(() => {
13495
13372
  setIsOnline(navigator.onLine);
13496
13373
  const handleOnline = () => setIsOnline(true);
@@ -13502,32 +13379,32 @@ function SylphxProviderInner({
13502
13379
  window.removeEventListener("offline", handleOffline);
13503
13380
  };
13504
13381
  }, []);
13505
- const queueToOfflineStorage = useCallback28(
13382
+ const queueToOfflineStorage = useCallback27(
13506
13383
  (events) => {
13507
13384
  try {
13508
- const existingQueue = storage.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13385
+ const existingQueue = storage2.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13509
13386
  const merged = [...existingQueue, ...events];
13510
13387
  const trimmed = merged.length > ANALYTICS_QUEUE_LIMIT ? merged.slice(-ANALYTICS_QUEUE_LIMIT) : merged;
13511
- storage.setJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE, trimmed);
13388
+ storage2.setJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE, trimmed);
13512
13389
  } catch {
13513
13390
  }
13514
13391
  },
13515
- [storage]
13392
+ [storage2]
13516
13393
  );
13517
- const getOfflineQueue = useCallback28(() => {
13394
+ const getOfflineQueue = useCallback27(() => {
13518
13395
  try {
13519
- return storage.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13396
+ return storage2.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
13520
13397
  } catch {
13521
13398
  return [];
13522
13399
  }
13523
- }, [storage]);
13524
- const clearOfflineQueue = useCallback28(() => {
13400
+ }, [storage2]);
13401
+ const clearOfflineQueue = useCallback27(() => {
13525
13402
  try {
13526
- storage.remove(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE);
13403
+ storage2.remove(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE);
13527
13404
  } catch {
13528
13405
  }
13529
- }, [storage]);
13530
- const flushAnalytics = useCallback28(async () => {
13406
+ }, [storage2]);
13407
+ const flushAnalytics = useCallback27(async () => {
13531
13408
  const offlineEvents = getOfflineQueue();
13532
13409
  const memoryEvents = analyticsQueue.current;
13533
13410
  const allEvents = [...offlineEvents, ...memoryEvents];
@@ -13570,7 +13447,7 @@ function SylphxProviderInner({
13570
13447
  return () => clearTimeout(timeout);
13571
13448
  }
13572
13449
  }, [isOnline, flushAnalytics]);
13573
- const enqueueAnalytics = useCallback28(
13450
+ const enqueueAnalytics = useCallback27(
13574
13451
  (type, data, eventId) => {
13575
13452
  if (!anonymousId && !authState.user?.id) return;
13576
13453
  const id = eventId || `${type}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
@@ -13606,7 +13483,7 @@ function SylphxProviderInner({
13606
13483
  },
13607
13484
  [authState.user?.id, anonymousId, flushAnalytics]
13608
13485
  );
13609
- const track = useCallback28(
13486
+ const track = useCallback27(
13610
13487
  async (event, properties, options) => {
13611
13488
  const autoEvents = ["$pageview", "$login", "$signup", "$logout", "$purchase"];
13612
13489
  if (autoEvents.includes(event)) {
@@ -13617,7 +13494,7 @@ function SylphxProviderInner({
13617
13494
  }
13618
13495
  let enrichedConversion = options?.conversion;
13619
13496
  if (options?.conversion || options?.destinations) {
13620
- const currentClickIds = getStoredClickIds(storage) || clickIds;
13497
+ const currentClickIds = getStoredClickIds(storage2) || clickIds;
13621
13498
  enrichedConversion = {
13622
13499
  // User-provided conversion data takes precedence
13623
13500
  ...options?.conversion,
@@ -13638,15 +13515,15 @@ function SylphxProviderInner({
13638
13515
  conversion: enrichedConversion
13639
13516
  });
13640
13517
  },
13641
- [enqueueAnalytics, autoTrackConfig, storage, clickIds, authState.user]
13518
+ [enqueueAnalytics, autoTrackConfig, storage2, clickIds, authState.user]
13642
13519
  );
13643
- const page = useCallback28(
13520
+ const page = useCallback27(
13644
13521
  async (name, properties) => {
13645
13522
  enqueueAnalytics("page", { name, properties: properties || {} });
13646
13523
  },
13647
13524
  [enqueueAnalytics]
13648
13525
  );
13649
- const identify = useCallback28(
13526
+ const identify = useCallback27(
13650
13527
  async (traits) => {
13651
13528
  if (!authState.user?.id) return;
13652
13529
  enqueueAnalytics("identify", {
@@ -13656,7 +13533,7 @@ function SylphxProviderInner({
13656
13533
  },
13657
13534
  [authState.user?.id, enqueueAnalytics]
13658
13535
  );
13659
- const queryAnalytics = useCallback28(
13536
+ const queryAnalytics = useCallback27(
13660
13537
  async (analyticsQuery) => {
13661
13538
  try {
13662
13539
  const result = await api.post(
@@ -13675,9 +13552,9 @@ function SylphxProviderInner({
13675
13552
  },
13676
13553
  [api]
13677
13554
  );
13678
- const prevAuthStateRef = useRef11(null);
13679
- const prevSubscriptionRef = useRef11(null);
13680
- const hasTrackedInitialPageview = useRef11(false);
13555
+ const prevAuthStateRef = useRef10(null);
13556
+ const prevSubscriptionRef = useRef10(null);
13557
+ const hasTrackedInitialPageview = useRef10(false);
13681
13558
  useEffect23(() => {
13682
13559
  if (!autoTrackConfig.pageview || hasTrackedInitialPageview.current) return;
13683
13560
  if (!anonymousId && !authState.user?.id) return;
@@ -13725,7 +13602,7 @@ function SylphxProviderInner({
13725
13602
  const userCreatedAt = currentState.user.createdAt ? new Date(currentState.user.createdAt).getTime() : 0;
13726
13603
  const isNewUser = Date.now() - userCreatedAt < NEW_USER_THRESHOLD_MS;
13727
13604
  const eventId = `auth_${currentState.user.id}_${isNewUser ? "signup" : "login"}_${Date.now()}`;
13728
- const currentClickIds = getStoredClickIds(storage) || clickIds;
13605
+ const currentClickIds = getStoredClickIds(storage2) || clickIds;
13729
13606
  if (isNewUser && autoTrackConfig.signup) {
13730
13607
  enqueueAnalytics(
13731
13608
  "track",
@@ -13781,13 +13658,13 @@ function SylphxProviderInner({
13781
13658
  );
13782
13659
  }
13783
13660
  prevAuthStateRef.current = currentState;
13784
- }, [authState, enqueueAnalytics, autoTrackConfig, storage, clickIds]);
13661
+ }, [authState, enqueueAnalytics, autoTrackConfig, storage2, clickIds]);
13785
13662
  useEffect23(() => {
13786
13663
  const prevSub = prevSubscriptionRef.current;
13787
13664
  const currentSub = subscription;
13788
13665
  if (autoTrackConfig.purchase && currentSub && (currentSub.status === "active" || currentSub.status === "trialing") && (!prevSub || prevSub.status !== "active" && prevSub.status !== "trialing")) {
13789
13666
  const eventId = `purchase_${currentSub.id}_${Date.now()}`;
13790
- const currentClickIds = getStoredClickIds(storage) || clickIds;
13667
+ const currentClickIds = getStoredClickIds(storage2) || clickIds;
13791
13668
  enqueueAnalytics(
13792
13669
  "track",
13793
13670
  {
@@ -13813,8 +13690,8 @@ function SylphxProviderInner({
13813
13690
  );
13814
13691
  }
13815
13692
  prevSubscriptionRef.current = currentSub;
13816
- }, [subscription, enqueueAnalytics, autoTrackConfig.purchase, storage, clickIds, authState.user]);
13817
- const subscribePush = useCallback28(async () => {
13693
+ }, [subscription, enqueueAnalytics, autoTrackConfig.purchase, storage2, clickIds, authState.user]);
13694
+ const subscribePush = useCallback27(async () => {
13818
13695
  if (!pushSupported || !vapidPublicKey) return false;
13819
13696
  try {
13820
13697
  const registration = await navigator.serviceWorker.ready;
@@ -13838,7 +13715,7 @@ function SylphxProviderInner({
13838
13715
  return false;
13839
13716
  }
13840
13717
  }, [pushSupported, vapidPublicKey, api]);
13841
- const unsubscribePush = useCallback28(async () => {
13718
+ const unsubscribePush = useCallback27(async () => {
13842
13719
  try {
13843
13720
  const registration = await navigator.serviceWorker.ready;
13844
13721
  const sub = await registration.pushManager.getSubscription();
@@ -13850,7 +13727,7 @@ function SylphxProviderInner({
13850
13727
  } catch {
13851
13728
  }
13852
13729
  }, [api]);
13853
- const updatePushPreferences = useCallback28(
13730
+ const updatePushPreferences = useCallback27(
13854
13731
  async (prefs) => {
13855
13732
  if (prefs.enabled === false) {
13856
13733
  await unsubscribePush();
@@ -13865,7 +13742,7 @@ function SylphxProviderInner({
13865
13742
  [pushPreferences, unsubscribePush, queryClient, appId]
13866
13743
  );
13867
13744
  const mobilePushQueryKey = ["sylphx", appId, "mobilePush"];
13868
- const registerMobileDevice = useCallback28(
13745
+ const registerMobileDevice = useCallback27(
13869
13746
  async (options) => {
13870
13747
  const result = await api.post(
13871
13748
  "/notifications/mobile/register",
@@ -13880,7 +13757,7 @@ function SylphxProviderInner({
13880
13757
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
13881
13758
  [api, queryClient, mobilePushQueryKey]
13882
13759
  );
13883
- const unregisterMobileDevice = useCallback28(
13760
+ const unregisterMobileDevice = useCallback27(
13884
13761
  async (token) => {
13885
13762
  await api.post("/notifications/mobile/unregister", { token });
13886
13763
  void queryClient.invalidateQueries({ queryKey: mobilePushQueryKey });
@@ -13888,7 +13765,7 @@ function SylphxProviderInner({
13888
13765
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
13889
13766
  [api, queryClient, mobilePushQueryKey]
13890
13767
  );
13891
- const getMobilePushPreferences = useCallback28(async () => {
13768
+ const getMobilePushPreferences = useCallback27(async () => {
13892
13769
  await queryClient.invalidateQueries({ queryKey: mobilePushQueryKey });
13893
13770
  const data = queryClient.getQueryData(mobilePushQueryKey);
13894
13771
  if (!data?.preferences) {
@@ -13896,25 +13773,25 @@ function SylphxProviderInner({
13896
13773
  }
13897
13774
  return data.preferences;
13898
13775
  }, [queryClient, mobilePushQueryKey]);
13899
- const copyReferralCode = useCallback28(async () => {
13776
+ const copyReferralCode = useCallback27(async () => {
13900
13777
  if (referralCode) {
13901
13778
  await navigator.clipboard.writeText(referralCode);
13902
13779
  }
13903
13780
  }, [referralCode]);
13904
- const regenerateReferralCode = useCallback28(async () => {
13781
+ const regenerateReferralCode = useCallback27(async () => {
13905
13782
  const data = await api.post("/referrals/code/regenerate");
13906
13783
  void queryClient.invalidateQueries({
13907
13784
  queryKey: ["sylphx", appId, "referrals"]
13908
13785
  });
13909
13786
  return data.code;
13910
13787
  }, [api, queryClient, appId]);
13911
- const redeemReferralCode = useCallback28(
13788
+ const redeemReferralCode = useCallback27(
13912
13789
  async (code, _defaults) => {
13913
13790
  return api.post("/referrals/redeem", { code });
13914
13791
  },
13915
13792
  [api]
13916
13793
  );
13917
- const getReferralLeaderboard = useCallback28(
13794
+ const getReferralLeaderboard = useCallback27(
13918
13795
  async (options) => {
13919
13796
  return api.get("/referrals/leaderboard", {
13920
13797
  limit: options?.limit?.toString(),
@@ -13923,7 +13800,7 @@ function SylphxProviderInner({
13923
13800
  },
13924
13801
  [api]
13925
13802
  );
13926
- const getStreak = useCallback28(
13803
+ const getStreak = useCallback27(
13927
13804
  async (streakId, defaults, userTimezone) => {
13928
13805
  if (!authState.user?.id) {
13929
13806
  throw new Error("User must be authenticated to get streak");
@@ -13936,7 +13813,7 @@ function SylphxProviderInner({
13936
13813
  },
13937
13814
  [api, authState.user?.id]
13938
13815
  );
13939
- const recordStreakActivity = useCallback28(
13816
+ const recordStreakActivity = useCallback27(
13940
13817
  async (streakId, metadata, defaults) => {
13941
13818
  if (!authState.user?.id) {
13942
13819
  throw new Error("User must be authenticated to record activity");
@@ -13949,7 +13826,7 @@ function SylphxProviderInner({
13949
13826
  },
13950
13827
  [api, authState.user?.id]
13951
13828
  );
13952
- const recoverStreak = useCallback28(
13829
+ const recoverStreak = useCallback27(
13953
13830
  async (streakId) => {
13954
13831
  if (!authState.user?.id) {
13955
13832
  throw new Error("User must be authenticated to recover streak");
@@ -13961,7 +13838,7 @@ function SylphxProviderInner({
13961
13838
  },
13962
13839
  [api, authState.user?.id]
13963
13840
  );
13964
- const getEngagementLeaderboard = useCallback28(
13841
+ const getEngagementLeaderboard = useCallback27(
13965
13842
  async (leaderboardId, options) => {
13966
13843
  return api.get(`/engagement/leaderboards/${leaderboardId}`, {
13967
13844
  userId: authState.user?.id ?? void 0,
@@ -13972,7 +13849,7 @@ function SylphxProviderInner({
13972
13849
  },
13973
13850
  [api, authState.user?.id]
13974
13851
  );
13975
- const submitScore = useCallback28(
13852
+ const submitScore = useCallback27(
13976
13853
  async (leaderboardId, value, metadata, defaults) => {
13977
13854
  if (!authState.user?.id) {
13978
13855
  throw new Error("User must be authenticated to submit score");
@@ -13986,7 +13863,7 @@ function SylphxProviderInner({
13986
13863
  },
13987
13864
  [api, authState.user?.id]
13988
13865
  );
13989
- const getAchievements = useCallback28(async () => {
13866
+ const getAchievements = useCallback27(async () => {
13990
13867
  if (!authState.user?.id) {
13991
13868
  throw new Error("User must be authenticated to get achievements");
13992
13869
  }
@@ -13994,7 +13871,7 @@ function SylphxProviderInner({
13994
13871
  userId: authState.user.id
13995
13872
  });
13996
13873
  }, [api, authState.user?.id]);
13997
- const unlockAchievement = useCallback28(
13874
+ const unlockAchievement = useCallback27(
13998
13875
  async (achievementId, defaults) => {
13999
13876
  if (!authState.user?.id) {
14000
13877
  throw new Error("User must be authenticated to unlock achievement");
@@ -14006,7 +13883,7 @@ function SylphxProviderInner({
14006
13883
  },
14007
13884
  [api, authState.user?.id]
14008
13885
  );
14009
- const incrementAchievementProgress = useCallback28(
13886
+ const incrementAchievementProgress = useCallback27(
14010
13887
  async (achievementId, amount, defaults) => {
14011
13888
  if (!authState.user?.id) {
14012
13889
  throw new Error("User must be authenticated to increment progress");
@@ -14020,10 +13897,10 @@ function SylphxProviderInner({
14020
13897
  [api, authState.user?.id]
14021
13898
  );
14022
13899
  const inboxQueryKey = ["sylphx", appId, "inbox"];
14023
- const refreshInbox = useCallback28(async () => {
13900
+ const refreshInbox = useCallback27(async () => {
14024
13901
  await queryClient.invalidateQueries({ queryKey: inboxQueryKey });
14025
13902
  }, [queryClient, inboxQueryKey]);
14026
- const markInboxMessageAsRead = useCallback28(
13903
+ const markInboxMessageAsRead = useCallback27(
14027
13904
  async (messageId) => {
14028
13905
  const previousData = queryClient.getQueryData(inboxQueryKey);
14029
13906
  queryClient.setQueryData(inboxQueryKey, (old) => {
@@ -14046,7 +13923,7 @@ function SylphxProviderInner({
14046
13923
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
14047
13924
  [api, queryClient, inboxQueryKey]
14048
13925
  );
14049
- const markAllInboxMessagesAsRead = useCallback28(async () => {
13926
+ const markAllInboxMessagesAsRead = useCallback27(async () => {
14050
13927
  const previousData = queryClient.getQueryData(inboxQueryKey);
14051
13928
  queryClient.setQueryData(inboxQueryKey, (old) => {
14052
13929
  if (!old) return old;
@@ -14067,7 +13944,7 @@ function SylphxProviderInner({
14067
13944
  throw err;
14068
13945
  }
14069
13946
  }, [api, queryClient, inboxQueryKey]);
14070
- const dismissInboxMessage = useCallback28(
13947
+ const dismissInboxMessage = useCallback27(
14071
13948
  async (messageId) => {
14072
13949
  const previousData = queryClient.getQueryData(inboxQueryKey);
14073
13950
  queryClient.setQueryData(inboxQueryKey, (old) => {
@@ -14087,7 +13964,7 @@ function SylphxProviderInner({
14087
13964
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
14088
13965
  [api, queryClient, inboxQueryKey]
14089
13966
  );
14090
- const recordInboxMessageClick = useCallback28(
13967
+ const recordInboxMessageClick = useCallback27(
14091
13968
  async (messageId, action) => {
14092
13969
  queryClient.setQueryData(inboxQueryKey, (old) => {
14093
13970
  if (!old) return old;
@@ -14109,7 +13986,7 @@ function SylphxProviderInner({
14109
13986
  // biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
14110
13987
  [api, queryClient, inboxQueryKey]
14111
13988
  );
14112
- const updateInboxPreferences = useCallback28(
13989
+ const updateInboxPreferences = useCallback27(
14113
13990
  async (prefs) => {
14114
13991
  const previousData = queryClient.getQueryData(inboxQueryKey);
14115
13992
  queryClient.setQueryData(inboxQueryKey, (old) => {
@@ -14147,15 +14024,6 @@ function SylphxProviderInner({
14147
14024
  }),
14148
14025
  [api, anonymousId, authState.user?.id, config2]
14149
14026
  );
14150
- const storageValue = useMemo9(
14151
- () => createStorageValue({
14152
- api,
14153
- platformUrl,
14154
- appId,
14155
- userId: authState.user?.id ?? null
14156
- }),
14157
- [api, platformUrl, appId, authState.user?.id]
14158
- );
14159
14027
  const newsletterValue = useMemo9(
14160
14028
  () => createNewsletterValue({ api }),
14161
14029
  [api]
@@ -14499,6 +14367,7 @@ function SylphxProviderInner({
14499
14367
  signUp,
14500
14368
  signOut,
14501
14369
  getToken,
14370
+ switchOrganizationToken,
14502
14371
  resetPassword,
14503
14372
  verifyEmail,
14504
14373
  resendVerificationEmail,
@@ -14522,6 +14391,7 @@ function SylphxProviderInner({
14522
14391
  signUp,
14523
14392
  signOut,
14524
14393
  getToken,
14394
+ switchOrganizationToken,
14525
14395
  resetPassword,
14526
14396
  verifyEmail,
14527
14397
  resendVerificationEmail,
@@ -14541,6 +14411,7 @@ function SylphxProviderInner({
14541
14411
  () => ({
14542
14412
  appId,
14543
14413
  platformUrl,
14414
+ authPrefix,
14544
14415
  slug: resolvedRef,
14545
14416
  ref: resolvedRef,
14546
14417
  anonymousId,
@@ -14616,6 +14487,7 @@ function SylphxProviderInner({
14616
14487
  api,
14617
14488
  appId,
14618
14489
  platformUrl,
14490
+ authPrefix,
14619
14491
  anonymousId,
14620
14492
  queryClient,
14621
14493
  clickIds,
@@ -14678,12 +14550,12 @@ function SylphxProviderInner({
14678
14550
  resolvedRef
14679
14551
  ]
14680
14552
  );
14681
- 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 }) }) }) }) }) }) }) }) }) }) }) }) }) });
14553
+ 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 }) }) }) }) }) }) }) }) }) }) }) }) });
14682
14554
  }
14683
14555
 
14684
14556
  // src/react/rbac-hooks.ts
14685
14557
  import { useQuery as useQuery6, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
14686
- import { useCallback as useCallback29, useContext as useContext16, useMemo as useMemo10 } from "react";
14558
+ import { useCallback as useCallback28, useContext as useContext16, useMemo as useMemo10 } from "react";
14687
14559
 
14688
14560
  // src/permissions.ts
14689
14561
  async function listPermissions(config2) {
@@ -14745,7 +14617,7 @@ function usePermissions() {
14745
14617
  staleTime: 3e4
14746
14618
  // 30s — permissions change rarely
14747
14619
  });
14748
- const refresh = useCallback29(async () => {
14620
+ const refresh = useCallback28(async () => {
14749
14621
  await queryClient.invalidateQueries({ queryKey: rbacKeys.permissions() });
14750
14622
  }, [queryClient]);
14751
14623
  return {
@@ -14768,7 +14640,7 @@ function useRoles() {
14768
14640
  staleTime: 3e4
14769
14641
  // 30s — roles change rarely
14770
14642
  });
14771
- const refresh = useCallback29(async () => {
14643
+ const refresh = useCallback28(async () => {
14772
14644
  await queryClient.invalidateQueries({ queryKey: rbacKeys.roles() });
14773
14645
  }, [queryClient]);
14774
14646
  return {
@@ -14794,7 +14666,7 @@ function useMemberPermissions(orgIdOrSlug, memberId) {
14794
14666
  staleTime: 15e3
14795
14667
  // 15s — member permissions may change more frequently
14796
14668
  });
14797
- const refresh = useCallback29(async () => {
14669
+ const refresh = useCallback28(async () => {
14798
14670
  if (orgIdOrSlug && memberId) {
14799
14671
  await queryClient.invalidateQueries({
14800
14672
  queryKey: rbacKeys.memberPermissions(orgIdOrSlug, memberId)
@@ -14822,236 +14694,642 @@ function useHasPermission(permissions, required) {
14822
14694
  }
14823
14695
 
14824
14696
  // src/react/storage-hooks.ts
14825
- import { useCallback as useCallback30, useRef as useRef12, useState as useState32 } from "react";
14826
- function useStorage() {
14827
- const ctx = useStorageContext();
14828
- const [isUploading, setIsUploading] = useState32(false);
14829
- const [progress, setProgress] = useState32(0);
14830
- const [bytesUploaded, setBytesUploaded] = useState32(0);
14831
- const [bytesTotal, setBytesTotal] = useState32(0);
14832
- const [uploadError, setUploadError] = useState32(null);
14833
- const [wasCancelled, setWasCancelled] = useState32(false);
14834
- const abortControllerRef = useRef12(null);
14835
- const handleProgress = useCallback30((event) => {
14836
- setProgress(event.progress);
14837
- setBytesUploaded(event.loaded);
14838
- setBytesTotal(event.total);
14839
- }, []);
14840
- const cancel = useCallback30(() => {
14841
- if (abortControllerRef.current) {
14842
- abortControllerRef.current.abort();
14843
- abortControllerRef.current = null;
14844
- setWasCancelled(true);
14845
- setIsUploading(false);
14697
+ import { useMutation as useMutation2, useQuery as useQuery7, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
14698
+ import { useCallback as useCallback29, useContext as useContext17, useMemo as useMemo11, useState as useState31 } from "react";
14699
+
14700
+ // src/lib/retry.ts
14701
+ init_constants();
14702
+ var DEFAULT_RETRY_CONFIG = {
14703
+ maxRetries: 5,
14704
+ baseDelayMs: BASE_RETRY_DELAY_MS,
14705
+ maxDelayMs: MAX_RETRY_DELAY_MS
14706
+ };
14707
+ function calculateBackoffDelay(attempt, config2 = DEFAULT_RETRY_CONFIG) {
14708
+ const exp = config2.baseDelayMs * 2 ** attempt;
14709
+ const capped = Math.min(exp, config2.maxDelayMs);
14710
+ return Math.random() * capped;
14711
+ }
14712
+ function sleep(ms, signal) {
14713
+ return new Promise((resolve, reject) => {
14714
+ if (signal?.aborted) {
14715
+ reject(toAbortError());
14716
+ return;
14846
14717
  }
14847
- }, []);
14848
- const upload = useCallback30(
14849
- async (file, options) => {
14850
- const controller = new AbortController();
14851
- abortControllerRef.current = controller;
14852
- const signal = options?.signal ?? controller.signal;
14853
- setIsUploading(true);
14854
- setProgress(0);
14855
- setBytesUploaded(0);
14856
- setBytesTotal(file.size);
14857
- setUploadError(null);
14858
- setWasCancelled(false);
14718
+ const timer = setTimeout(resolve, ms);
14719
+ signal?.addEventListener(
14720
+ "abort",
14721
+ () => {
14722
+ clearTimeout(timer);
14723
+ reject(toAbortError());
14724
+ },
14725
+ { once: true }
14726
+ );
14727
+ });
14728
+ }
14729
+ var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 425, 429]);
14730
+ function isRetryableError(error) {
14731
+ if (isAbortError(error)) return false;
14732
+ if (error instanceof TypeError) return true;
14733
+ if (error instanceof Error && "status" in error) {
14734
+ const status = error.status;
14735
+ return status >= 500 || RETRYABLE_STATUSES.has(status);
14736
+ }
14737
+ return false;
14738
+ }
14739
+ function isAbortError(error) {
14740
+ if (error instanceof DOMException && error.name === "AbortError") return true;
14741
+ if (error instanceof Error && error.name === "AbortError") return true;
14742
+ return false;
14743
+ }
14744
+ function toAbortError(message = "Aborted") {
14745
+ if (typeof DOMException !== "undefined") {
14746
+ return new DOMException(message, "AbortError");
14747
+ }
14748
+ const err = new Error(message);
14749
+ err.name = "AbortError";
14750
+ return err;
14751
+ }
14752
+ async function withRetry(fn, options = {}) {
14753
+ const cfg = {
14754
+ maxRetries: options.maxRetries ?? DEFAULT_RETRY_CONFIG.maxRetries,
14755
+ baseDelayMs: options.baseDelayMs ?? DEFAULT_RETRY_CONFIG.baseDelayMs,
14756
+ maxDelayMs: options.maxDelayMs ?? DEFAULT_RETRY_CONFIG.maxDelayMs
14757
+ };
14758
+ let lastError;
14759
+ for (let attempt = 0; attempt <= cfg.maxRetries; attempt++) {
14760
+ if (options.signal?.aborted) throw toAbortError("Aborted");
14761
+ try {
14762
+ return await fn();
14763
+ } catch (err) {
14764
+ lastError = err;
14765
+ if (isAbortError(err)) throw err;
14766
+ if (attempt === cfg.maxRetries) break;
14767
+ if (!isRetryableError(err)) throw err;
14768
+ const retryAfter = extractRetryAfter(err);
14769
+ const delay2 = retryAfter ?? calculateBackoffDelay(attempt, cfg);
14770
+ options.onRetry?.(attempt, delay2, err);
14771
+ await sleep(delay2, options.signal);
14772
+ }
14773
+ }
14774
+ throw lastError;
14775
+ }
14776
+ function extractRetryAfter(err) {
14777
+ if (err && typeof err === "object" && "retryAfter" in err) {
14778
+ const v2 = err.retryAfter;
14779
+ if (typeof v2 === "number" && v2 > 0) return v2 * 1e3;
14780
+ }
14781
+ return void 0;
14782
+ }
14783
+ function uuidv7() {
14784
+ const ms = BigInt(Date.now());
14785
+ const bytes = randomBytes(16);
14786
+ bytes[0] = Number(ms >> 40n & 0xffn);
14787
+ bytes[1] = Number(ms >> 32n & 0xffn);
14788
+ bytes[2] = Number(ms >> 24n & 0xffn);
14789
+ bytes[3] = Number(ms >> 16n & 0xffn);
14790
+ bytes[4] = Number(ms >> 8n & 0xffn);
14791
+ bytes[5] = Number(ms & 0xffn);
14792
+ bytes[6] = bytes[6] & 15 | 112;
14793
+ bytes[8] = bytes[8] & 63 | 128;
14794
+ const hex = Array.from(bytes, (b2) => b2.toString(16).padStart(2, "0")).join("");
14795
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
14796
+ }
14797
+ function randomBytes(n2) {
14798
+ const out = new Uint8Array(n2);
14799
+ const c2 = globalThis.crypto;
14800
+ if (c2?.getRandomValues) {
14801
+ c2.getRandomValues(out);
14802
+ return out;
14803
+ }
14804
+ for (let i2 = 0; i2 < n2; i2++) out[i2] = Math.floor(Math.random() * 256);
14805
+ return out;
14806
+ }
14807
+
14808
+ // src/storage.ts
14809
+ var PATHS = {
14810
+ uploads: "/storage/uploads",
14811
+ upload: (id) => `/storage/uploads/${encodeURIComponent(String(id))}`,
14812
+ uploadComplete: (id) => `/storage/uploads/${encodeURIComponent(String(id))}:complete`,
14813
+ uploadPart: (id, n2) => `/storage/uploads/${encodeURIComponent(String(id))}/parts/${n2}`,
14814
+ files: "/storage/files",
14815
+ file: (id) => `/storage/files/${encodeURIComponent(String(id))}`,
14816
+ fileRestore: (id) => `/storage/files/${encodeURIComponent(String(id))}:restore`,
14817
+ fileSignedUrl: (id) => `/storage/files/${encodeURIComponent(String(id))}:signedUrl`,
14818
+ fileCopy: (id) => `/storage/files/${encodeURIComponent(String(id))}:copy`,
14819
+ versions: (id) => `/storage/files/${encodeURIComponent(String(id))}/versions`,
14820
+ versionRestore: (id, vid) => `/storage/files/${encodeURIComponent(String(id))}/versions/${encodeURIComponent(String(vid))}:restore`
14821
+ };
14822
+ var hasXhr = () => typeof globalThis.XMLHttpRequest !== "undefined";
14823
+ var hasLocalStorage = () => {
14824
+ try {
14825
+ const ls = globalThis.localStorage;
14826
+ return Boolean(ls && typeof ls.getItem === "function");
14827
+ } catch {
14828
+ return false;
14829
+ }
14830
+ };
14831
+ async function computeSha256Hex(blob) {
14832
+ const subtle = globalThis.crypto?.subtle;
14833
+ if (!subtle?.digest) {
14834
+ throw new SylphxError("Web Crypto SHA-256 support is required for storage uploads", {
14835
+ code: "NOT_IMPLEMENTED"
14836
+ });
14837
+ }
14838
+ const buf = await blob.arrayBuffer();
14839
+ const digest = await subtle.digest("SHA-256", buf);
14840
+ return bytesToHex(new Uint8Array(digest));
14841
+ }
14842
+ function bytesToHex(b2) {
14843
+ let s2 = "";
14844
+ for (let i2 = 0; i2 < b2.length; i2++) s2 += b2[i2].toString(16).padStart(2, "0");
14845
+ return s2;
14846
+ }
14847
+ var RESUME_KEY_PREFIX = "sylphx_upload_";
14848
+ function resumeKey(uploadId) {
14849
+ return `${RESUME_KEY_PREFIX}${uploadId}`;
14850
+ }
14851
+ function persistResume(rec) {
14852
+ if (hasLocalStorage()) {
14853
+ try {
14854
+ localStorage.setItem(resumeKey(rec.uploadId), JSON.stringify(rec));
14855
+ } catch {
14856
+ }
14857
+ }
14858
+ }
14859
+ function clearResume(uploadId) {
14860
+ if (hasLocalStorage()) {
14861
+ try {
14862
+ localStorage.removeItem(resumeKey(uploadId));
14863
+ } catch {
14864
+ }
14865
+ }
14866
+ }
14867
+ function putBlob(url, body, headers, signal, onProgress) {
14868
+ if (hasXhr()) return putBlobXhr(url, body, headers, signal, onProgress);
14869
+ return putBlobFetch(url, body, headers, signal, onProgress);
14870
+ }
14871
+ function putBlobXhr(url, body, headers, signal, onProgress) {
14872
+ return new Promise((resolve, reject) => {
14873
+ const xhr = new XMLHttpRequest();
14874
+ const handleAbort = () => {
14859
14875
  try {
14860
- const url = await ctx.upload(file, {
14861
- ...options,
14862
- signal,
14863
- onProgress: handleProgress
14864
- });
14865
- setProgress(100);
14866
- return url;
14867
- } catch (err) {
14868
- if (err instanceof DOMException && err.name === "AbortError") {
14869
- setWasCancelled(true);
14870
- throw err;
14871
- }
14872
- const error = err instanceof Error ? err : new Error("Upload failed");
14873
- setUploadError(error);
14874
- throw error;
14875
- } finally {
14876
- abortControllerRef.current = null;
14877
- setIsUploading(false);
14876
+ xhr.abort();
14877
+ } catch {
14878
14878
  }
14879
- },
14880
- [ctx, handleProgress]
14881
- );
14882
- const uploadAvatar = useCallback30(
14883
- async (file) => {
14884
- const controller = new AbortController();
14885
- abortControllerRef.current = controller;
14886
- setIsUploading(true);
14887
- setProgress(0);
14888
- setBytesUploaded(0);
14889
- setBytesTotal(file.size);
14890
- setUploadError(null);
14891
- setWasCancelled(false);
14879
+ reject(toAbortError("Upload aborted"));
14880
+ };
14881
+ if (signal?.aborted) {
14882
+ reject(toAbortError("Upload aborted"));
14883
+ return;
14884
+ }
14885
+ signal?.addEventListener("abort", handleAbort, { once: true });
14886
+ if (onProgress) {
14887
+ xhr.upload.addEventListener("progress", (e2) => {
14888
+ if (e2.lengthComputable) onProgress(e2.loaded);
14889
+ });
14890
+ }
14891
+ xhr.addEventListener("load", () => {
14892
+ signal?.removeEventListener("abort", handleAbort);
14893
+ if (xhr.status >= 200 && xhr.status < 300) {
14894
+ const etag = resolveXhrEtag(xhr);
14895
+ resolve({ etag: stripQuotes(etag), status: xhr.status });
14896
+ } else {
14897
+ const err = new Error(`PUT failed with status ${xhr.status}`);
14898
+ err.status = xhr.status;
14899
+ reject(err);
14900
+ }
14901
+ });
14902
+ xhr.addEventListener("error", () => {
14903
+ signal?.removeEventListener("abort", handleAbort);
14904
+ reject(new TypeError("Network error during upload"));
14905
+ });
14906
+ xhr.addEventListener("abort", () => {
14907
+ signal?.removeEventListener("abort", handleAbort);
14908
+ reject(toAbortError("Upload aborted"));
14909
+ });
14910
+ xhr.open("PUT", url);
14911
+ for (const [k2, v2] of Object.entries(headers)) {
14892
14912
  try {
14893
- const url = await ctx.uploadAvatar(file, {
14894
- onProgress: handleProgress
14895
- });
14896
- setProgress(100);
14897
- return url;
14898
- } catch (err) {
14899
- if (err instanceof DOMException && err.name === "AbortError") {
14900
- setWasCancelled(true);
14901
- throw err;
14902
- }
14903
- const error = err instanceof Error ? err : new Error("Avatar upload failed");
14904
- setUploadError(error);
14905
- throw error;
14906
- } finally {
14907
- abortControllerRef.current = null;
14908
- setIsUploading(false);
14913
+ xhr.setRequestHeader(k2, v2);
14914
+ } catch {
14909
14915
  }
14910
- },
14911
- [ctx, handleProgress]
14916
+ }
14917
+ xhr.send(body);
14918
+ });
14919
+ }
14920
+ function resolveXhrEtag(xhr) {
14921
+ const canonical = xhr.getResponseHeader("ETag");
14922
+ if (canonical !== null) return canonical;
14923
+ return xhr.getResponseHeader("etag") ?? "";
14924
+ }
14925
+ async function putBlobFetch(url, body, headers, signal, onProgress) {
14926
+ let stream = body;
14927
+ if (onProgress && typeof TransformStream !== "undefined" && typeof body.stream === "function") {
14928
+ let loaded = 0;
14929
+ const counter = new TransformStream({
14930
+ transform(chunk, controller) {
14931
+ loaded += chunk.byteLength;
14932
+ onProgress(loaded);
14933
+ controller.enqueue(chunk);
14934
+ }
14935
+ });
14936
+ stream = body.stream().pipeThrough(counter);
14937
+ }
14938
+ const res = await fetch(url, {
14939
+ method: "PUT",
14940
+ body: stream,
14941
+ headers,
14942
+ signal,
14943
+ // Required when streaming a request body in Chromium / undici.
14944
+ // Cast: TS lib lacks `duplex`.
14945
+ ...{ duplex: "half" }
14946
+ });
14947
+ if (!res.ok) {
14948
+ const err = new Error(`PUT failed with status ${res.status}`);
14949
+ err.status = res.status;
14950
+ throw err;
14951
+ }
14952
+ const etag = resolveFetchEtag(res.headers);
14953
+ if (onProgress) onProgress(body.size);
14954
+ return { etag: stripQuotes(etag), status: res.status };
14955
+ }
14956
+ function resolveFetchEtag(headers) {
14957
+ const lowerCase = headers.get("etag");
14958
+ if (lowerCase !== null) return lowerCase;
14959
+ return headers.get("ETag") ?? "";
14960
+ }
14961
+ function stripQuotes(s2) {
14962
+ if (s2.length >= 2 && s2.startsWith('"') && s2.endsWith('"')) return s2.slice(1, -1);
14963
+ return s2;
14964
+ }
14965
+ async function putWithRetry(url, body, headers, signal, onProgress) {
14966
+ let lastErr;
14967
+ const maxRetries = 5;
14968
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
14969
+ if (signal?.aborted) throw toAbortError();
14970
+ try {
14971
+ return await putBlob(url, body, headers, signal, onProgress);
14972
+ } catch (err) {
14973
+ if (isAbortError(err)) throw err;
14974
+ lastErr = err;
14975
+ if (attempt === maxRetries || !isRetryableError(err)) throw err;
14976
+ await sleep(calculateBackoffDelay(attempt), signal);
14977
+ }
14978
+ }
14979
+ throw lastErr;
14980
+ }
14981
+ async function uploadsCreate(config2, blob, options) {
14982
+ const signal = options.signal;
14983
+ if (signal?.aborted) throw toAbortError();
14984
+ const filename = options.filename ?? (isFile(blob) ? blob.name : void 0) ?? "upload.bin";
14985
+ const contentType = options.contentType ?? (blob.type && blob.type.length > 0 ? blob.type : "application/octet-stream");
14986
+ const size = blob.size;
14987
+ const checksumSha256 = options.checksumSha256 ?? await computeSha256Hex(blob);
14988
+ const idempotencyKey = options.idempotencyKey ?? uuidv7();
14989
+ const createBody = {
14990
+ filename,
14991
+ contentType,
14992
+ size,
14993
+ folder: options.folder,
14994
+ visibility: options.visibility,
14995
+ metadata: options.metadata,
14996
+ checksumSha256,
14997
+ ifNoneMatch: options.ifNoneMatch
14998
+ };
14999
+ const session = await callApi(config2, PATHS.uploads, {
15000
+ method: "POST",
15001
+ body: createBody,
15002
+ idempotencyKey,
15003
+ signal
15004
+ });
15005
+ const uploadId = session.uploadId;
15006
+ const onAborted = async () => {
15007
+ try {
15008
+ await callApi(config2, PATHS.upload(uploadId), { method: "DELETE" });
15009
+ } catch {
15010
+ }
15011
+ clearResume(String(uploadId));
15012
+ };
15013
+ try {
15014
+ if (session.method === "PUT") {
15015
+ return await runSinglePart(config2, blob, session, options, idempotencyKey);
15016
+ }
15017
+ return await runMultipart(config2, blob, session, options, idempotencyKey);
15018
+ } catch (err) {
15019
+ if (isAbortError(err)) {
15020
+ await onAborted();
15021
+ }
15022
+ throw err;
15023
+ }
15024
+ }
15025
+ function isFile(b2) {
15026
+ return typeof b2.name === "string";
15027
+ }
15028
+ async function runSinglePart(config2, blob, session, options, idempotencyKey) {
15029
+ const { onProgress, signal } = options;
15030
+ const total = blob.size;
15031
+ const trackProgress = onProgress ? (loaded) => {
15032
+ onProgress({ loaded, total, partsCompleted: 0, partsTotal: 1 });
15033
+ } : void 0;
15034
+ const put = await putWithRetry(session.url, blob, session.headers, signal, trackProgress);
15035
+ if (onProgress) onProgress({ loaded: total, total, partsCompleted: 1, partsTotal: 1 });
15036
+ const completion = await callApi(
15037
+ config2,
15038
+ PATHS.uploadComplete(session.uploadId),
15039
+ {
15040
+ method: "POST",
15041
+ body: { parts: [{ partNumber: 1, etag: put.etag }] },
15042
+ idempotencyKey: `${idempotencyKey}:complete`,
15043
+ signal
15044
+ }
15045
+ );
15046
+ clearResume(String(session.uploadId));
15047
+ return await fetchFile(config2, completion.fileId);
15048
+ }
15049
+ async function runMultipart(config2, blob, session, options, idempotencyKey) {
15050
+ const { onProgress, signal } = options;
15051
+ const partSize = session.partSize;
15052
+ const total = blob.size;
15053
+ const partsTotal = session.partCount;
15054
+ const completedParts = [];
15055
+ const partLoaded = /* @__PURE__ */ new Map();
15056
+ const reportProgress = () => {
15057
+ if (!onProgress) return;
15058
+ let loaded = 0;
15059
+ for (const v2 of partLoaded.values()) loaded += v2;
15060
+ onProgress({ loaded, total, partsCompleted: completedParts.length, partsTotal });
15061
+ };
15062
+ for (const part of session.parts) {
15063
+ if (signal?.aborted) throw toAbortError();
15064
+ const offset = (part.partNumber - 1) * partSize;
15065
+ const end = Math.min(offset + partSize, total);
15066
+ const slice = blob.slice(offset, end);
15067
+ const trackProgress = onProgress ? (loaded) => {
15068
+ partLoaded.set(part.partNumber, loaded);
15069
+ reportProgress();
15070
+ } : void 0;
15071
+ const result = await putWithRetry(part.url, slice, {}, signal, trackProgress);
15072
+ completedParts.push({ partNumber: part.partNumber, etag: result.etag });
15073
+ partLoaded.set(part.partNumber, slice.size);
15074
+ reportProgress();
15075
+ persistResume({
15076
+ uploadId: String(session.uploadId),
15077
+ completedParts: [...completedParts],
15078
+ updatedAt: Date.now()
15079
+ });
15080
+ }
15081
+ const completion = await callApi(
15082
+ config2,
15083
+ PATHS.uploadComplete(session.uploadId),
15084
+ {
15085
+ method: "POST",
15086
+ body: { parts: completedParts },
15087
+ idempotencyKey: `${idempotencyKey}:complete`,
15088
+ signal
15089
+ }
14912
15090
  );
14913
- const deleteFile = useCallback30(
14914
- async (fileId) => {
14915
- await ctx.deleteFile(fileId);
15091
+ clearResume(String(session.uploadId));
15092
+ return await fetchFile(config2, completion.fileId);
15093
+ }
15094
+ async function fetchFile(config2, fileId) {
15095
+ return callApi(config2, PATHS.file(fileId), { method: "GET" });
15096
+ }
15097
+ async function uploadsAbort(config2, uploadId) {
15098
+ await withRetry(() => callApi(config2, PATHS.upload(uploadId), { method: "DELETE" }), {
15099
+ maxRetries: 3
15100
+ });
15101
+ clearResume(String(uploadId));
15102
+ }
15103
+ function filesListPage(config2, options, cursor) {
15104
+ const query = {
15105
+ folder: options.folder,
15106
+ cursor: cursor ?? options.cursor,
15107
+ limit: options.limit,
15108
+ includeDeleted: options.includeDeleted
15109
+ };
15110
+ return callApi(config2, PATHS.files, {
15111
+ method: "GET",
15112
+ query: {
15113
+ folder: query.folder,
15114
+ cursor: query.cursor,
15115
+ limit: query.limit,
15116
+ includeDeleted: query.includeDeleted
15117
+ }
15118
+ });
15119
+ }
15120
+ function filesList(config2, options = {}) {
15121
+ const fetchPage = (cursor) => filesListPage(config2, options, cursor);
15122
+ const iter = {
15123
+ [Symbol.asyncIterator]: async function* () {
15124
+ let cursor = options.cursor;
15125
+ do {
15126
+ const page = await fetchPage(cursor ?? void 0);
15127
+ for (const f2 of page.files) yield f2;
15128
+ cursor = page.nextCursor;
15129
+ } while (cursor);
15130
+ }
15131
+ };
15132
+ return Object.assign(iter, { fetchPage });
15133
+ }
15134
+ async function filesGet(config2, fileId) {
15135
+ return callApi(config2, PATHS.file(fileId), { method: "GET" });
15136
+ }
15137
+ async function filesDelete(config2, fileId) {
15138
+ return callApi(config2, PATHS.file(fileId), { method: "DELETE" });
15139
+ }
15140
+ async function filesRestore(config2, fileId) {
15141
+ return callApi(config2, PATHS.fileRestore(fileId), { method: "POST" });
15142
+ }
15143
+ async function filesSignedUrl(config2, fileId, options = {}) {
15144
+ const body = {
15145
+ expiresIn: options.expiresIn,
15146
+ disposition: options.disposition,
15147
+ userId: options.userId
15148
+ };
15149
+ return callApi(config2, PATHS.fileSignedUrl(fileId), {
15150
+ method: "POST",
15151
+ body
15152
+ });
15153
+ }
15154
+ async function filesCopy(config2, fileId, options) {
15155
+ const body = {
15156
+ folder: options.folder,
15157
+ filename: options.filename,
15158
+ visibility: options.visibility,
15159
+ metadata: options.metadata
15160
+ };
15161
+ return callApi(config2, PATHS.fileCopy(fileId), {
15162
+ method: "POST",
15163
+ body
15164
+ });
15165
+ }
15166
+ async function filesVersionsList(config2, fileId) {
15167
+ const data = await callApi(config2, PATHS.versions(fileId), {
15168
+ method: "GET"
15169
+ });
15170
+ return data.versions;
15171
+ }
15172
+ async function filesVersionsRestore(config2, fileId, versionId) {
15173
+ return callApi(config2, PATHS.versionRestore(fileId, versionId), { method: "POST" });
15174
+ }
15175
+ var storage = {
15176
+ uploads: {
15177
+ create: uploadsCreate,
15178
+ abort: uploadsAbort
15179
+ },
15180
+ files: {
15181
+ list: filesList,
15182
+ get: filesGet,
15183
+ delete: filesDelete,
15184
+ restore: filesRestore,
15185
+ signedUrl: filesSignedUrl,
15186
+ copy: filesCopy,
15187
+ versions: {
15188
+ list: filesVersionsList,
15189
+ restore: filesVersionsRestore
15190
+ }
15191
+ }
15192
+ };
15193
+
15194
+ // src/react/storage-hooks.ts
15195
+ function useSdkConfig2() {
15196
+ const platform = useContext17(PlatformContext);
15197
+ const auth = useContext17(AuthContext);
15198
+ return useMemo11(() => {
15199
+ if (!platform?.slug) return null;
15200
+ let cfg = createConfig({
15201
+ secretKey: platform.appId,
15202
+ slug: platform.slug
15203
+ });
15204
+ if (auth?.accessToken) cfg = withToken(cfg, auth.accessToken);
15205
+ return cfg;
15206
+ }, [platform?.slug, platform?.appId, auth?.accessToken]);
15207
+ }
15208
+ var storageKeys = {
15209
+ all: ["storage"],
15210
+ lists: () => [...storageKeys.all, "list"],
15211
+ list: (opts) => [...storageKeys.lists(), opts],
15212
+ files: () => [...storageKeys.all, "file"],
15213
+ file: (id) => [...storageKeys.files(), id]
15214
+ };
15215
+ function useStorage() {
15216
+ const config2 = useSdkConfig2();
15217
+ const queryClient = useQueryClient6();
15218
+ const [progress, setProgress] = useState31(0);
15219
+ const listQuery = useQuery7({
15220
+ queryKey: storageKeys.list({}),
15221
+ queryFn: async () => {
15222
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15223
+ return storage.files.list(config2).fetchPage();
14916
15224
  },
14917
- [ctx]
14918
- );
14919
- const getUrl = useCallback30(
14920
- async (fileId) => {
14921
- return ctx.getUrl(fileId);
15225
+ enabled: Boolean(config2),
15226
+ staleTime: 6e4
15227
+ });
15228
+ const uploadMutation = useMutation2({
15229
+ mutationFn: async (input) => {
15230
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15231
+ setProgress(0);
15232
+ return storage.uploads.create(config2, input.blob, {
15233
+ ...input.options ?? {},
15234
+ onProgress: (event) => {
15235
+ const nextProgress = event.total > 0 ? Math.min(100, Math.round(event.loaded / event.total * 100)) : 0;
15236
+ setProgress(nextProgress);
15237
+ input.options?.onProgress?.(event);
15238
+ }
15239
+ });
14922
15240
  },
14923
- [ctx]
14924
- );
15241
+ onSuccess: () => {
15242
+ setProgress(100);
15243
+ void queryClient.invalidateQueries({ queryKey: storageKeys.lists() });
15244
+ },
15245
+ onError: () => {
15246
+ setProgress(0);
15247
+ }
15248
+ });
15249
+ const upload = useCallback29(
15250
+ (blob, options) => uploadMutation.mutateAsync({ blob, options }),
15251
+ [uploadMutation]
15252
+ );
15253
+ const uploadAvatar = useCallback29(
15254
+ (blob, options) => upload(blob, { visibility: "public", folder: "avatars", ...options }),
15255
+ [upload]
15256
+ );
15257
+ const refetch = useCallback29(async () => {
15258
+ await listQuery.refetch();
15259
+ }, [listQuery]);
15260
+ const error = uploadMutation.error ?? listQuery.error;
15261
+ const uploadError = uploadMutation.error;
14925
15262
  return {
14926
15263
  upload,
14927
15264
  uploadAvatar,
14928
- deleteFile,
14929
- getUrl,
14930
- cancel,
14931
- isUploading,
15265
+ files: listQuery.data?.files,
15266
+ isUploading: uploadMutation.isPending,
15267
+ isLoadingFiles: listQuery.isLoading,
14932
15268
  progress,
14933
- bytesUploaded,
14934
- bytesTotal,
15269
+ error,
14935
15270
  uploadError,
14936
- wasCancelled
15271
+ refetch
14937
15272
  };
14938
15273
  }
14939
- function useFileUpload(options = {}) {
14940
- const ctx = useStorageContext();
14941
- const [isUploading, setIsUploading] = useState32(false);
14942
- const [progress, setProgress] = useState32(0);
14943
- const [bytesUploaded, setBytesUploaded] = useState32(0);
14944
- const [bytesTotal, setBytesTotal] = useState32(0);
14945
- const [error, setError] = useState32(null);
14946
- const [wasCancelled, setWasCancelled] = useState32(false);
14947
- const [url, setUrl] = useState32(null);
14948
- const abortControllerRef = useRef12(null);
14949
- const handleProgress = useCallback30((event) => {
14950
- setProgress(event.progress);
14951
- setBytesUploaded(event.loaded);
14952
- setBytesTotal(event.total);
14953
- }, []);
14954
- const cancel = useCallback30(() => {
14955
- if (abortControllerRef.current) {
14956
- abortControllerRef.current.abort();
14957
- abortControllerRef.current = null;
14958
- setWasCancelled(true);
14959
- setIsUploading(false);
14960
- options.onCancel?.();
14961
- }
14962
- }, [options]);
14963
- const upload = useCallback30(
14964
- async (file) => {
14965
- if (options.accept && options.accept.length > 0) {
14966
- const isAccepted = options.accept.some((type) => {
14967
- if (type.endsWith("/*")) {
14968
- const category = type.slice(0, -2);
14969
- return file.type.startsWith(category);
14970
- }
14971
- return file.type === type;
14972
- });
14973
- if (!isAccepted) {
14974
- const err = new Error(`File type ${file.type} not accepted`);
14975
- setError(err);
14976
- options.onError?.(err);
14977
- throw err;
14978
- }
14979
- }
14980
- if (options.maxSize && file.size > options.maxSize) {
14981
- const maxMB = (options.maxSize / 1024 / 1024).toFixed(1);
14982
- const err = new Error(`File size exceeds ${maxMB}MB limit`);
14983
- setError(err);
14984
- options.onError?.(err);
14985
- throw err;
14986
- }
14987
- const controller = new AbortController();
14988
- abortControllerRef.current = controller;
14989
- setIsUploading(true);
14990
- setProgress(0);
14991
- setBytesUploaded(0);
14992
- setBytesTotal(file.size);
14993
- setError(null);
14994
- setWasCancelled(false);
14995
- setUrl(null);
14996
- try {
14997
- const uploadedUrl = await ctx.upload(file, {
14998
- path: options.path,
14999
- signal: controller.signal,
15000
- onProgress: handleProgress
15001
- });
15002
- setProgress(100);
15003
- setUrl(uploadedUrl);
15004
- options.onSuccess?.(uploadedUrl);
15005
- return uploadedUrl;
15006
- } catch (err) {
15007
- if (err instanceof DOMException && err.name === "AbortError") {
15008
- setWasCancelled(true);
15009
- options.onCancel?.();
15010
- throw err;
15011
- }
15012
- const uploadError = err instanceof Error ? err : new Error("Upload failed");
15013
- setError(uploadError);
15014
- options.onError?.(uploadError);
15015
- throw uploadError;
15016
- } finally {
15017
- abortControllerRef.current = null;
15018
- setIsUploading(false);
15019
- }
15274
+ function useFile(fileId) {
15275
+ const config2 = useSdkConfig2();
15276
+ const query = useQuery7({
15277
+ queryKey: storageKeys.file(String(fileId)),
15278
+ queryFn: async () => {
15279
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15280
+ return storage.files.get(config2, fileId);
15020
15281
  },
15021
- [ctx, options, handleProgress]
15282
+ enabled: Boolean(config2 && fileId),
15283
+ staleTime: 6e4
15284
+ });
15285
+ return {
15286
+ file: query.data,
15287
+ isLoading: query.isLoading,
15288
+ error: query.error
15289
+ };
15290
+ }
15291
+ function useFileList(options = {}) {
15292
+ const config2 = useSdkConfig2();
15293
+ const [pages, setPages] = useState31(
15294
+ null
15022
15295
  );
15023
- const reset = useCallback30(() => {
15024
- setIsUploading(false);
15025
- setProgress(0);
15026
- setBytesUploaded(0);
15027
- setBytesTotal(0);
15028
- setError(null);
15029
- setWasCancelled(false);
15030
- setUrl(null);
15031
- }, []);
15296
+ const query = useQuery7({
15297
+ queryKey: storageKeys.list(options),
15298
+ queryFn: async () => {
15299
+ if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15300
+ const page = await storage.files.list(config2, options).fetchPage(options.cursor);
15301
+ setPages({ files: [...page.files], nextCursor: page.nextCursor });
15302
+ return page;
15303
+ },
15304
+ enabled: Boolean(config2),
15305
+ staleTime: 6e4
15306
+ });
15307
+ const loadMore = useCallback29(async () => {
15308
+ if (!config2) return;
15309
+ const cursor = pages?.nextCursor;
15310
+ if (!cursor) return;
15311
+ const page = await storage.files.list(config2, options).fetchPage(cursor);
15312
+ setPages((prev) => ({
15313
+ files: [...prev?.files ?? [], ...page.files],
15314
+ nextCursor: page.nextCursor
15315
+ }));
15316
+ }, [config2, options, pages?.nextCursor]);
15032
15317
  return {
15033
- upload,
15034
- cancel,
15035
- isUploading,
15036
- progress,
15037
- bytesUploaded,
15038
- bytesTotal,
15039
- error,
15040
- isError: error !== null,
15041
- wasCancelled,
15042
- url,
15043
- reset
15318
+ files: pages?.files ?? query.data?.files ?? [],
15319
+ nextCursor: pages?.nextCursor ?? query.data?.nextCursor ?? null,
15320
+ isLoading: query.isLoading,
15321
+ loadMore
15044
15322
  };
15045
15323
  }
15046
15324
 
15047
15325
  // src/react/task-hooks.ts
15048
- import { useQuery as useQuery7, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
15049
- import { useCallback as useCallback31, useEffect as useEffect24, useRef as useRef13, useState as useState33 } from "react";
15326
+ import { useQuery as useQuery8, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
15327
+ import { useCallback as useCallback30, useEffect as useEffect24, useRef as useRef11, useState as useState32 } from "react";
15050
15328
  function useTasks() {
15051
15329
  const ctx = useTasksContext();
15052
- const [isLoading, setIsLoading] = useState33(false);
15053
- const [error, setError] = useState33(null);
15054
- const isAvailable = useCallback31(async () => {
15330
+ const [isLoading, setIsLoading] = useState32(false);
15331
+ const [error, setError] = useState32(null);
15332
+ const isAvailable = useCallback30(async () => {
15055
15333
  try {
15056
15334
  const status = await ctx.checkStatus();
15057
15335
  return status.available;
@@ -15059,7 +15337,7 @@ function useTasks() {
15059
15337
  return false;
15060
15338
  }
15061
15339
  }, [ctx]);
15062
- const schedule = useCallback31(
15340
+ const schedule = useCallback30(
15063
15341
  async (options) => {
15064
15342
  setIsLoading(true);
15065
15343
  setError(null);
@@ -15075,7 +15353,7 @@ function useTasks() {
15075
15353
  },
15076
15354
  [ctx]
15077
15355
  );
15078
- const createCron = useCallback31(
15356
+ const createCron = useCallback30(
15079
15357
  async (options) => {
15080
15358
  setIsLoading(true);
15081
15359
  setError(null);
@@ -15091,7 +15369,7 @@ function useTasks() {
15091
15369
  },
15092
15370
  [ctx]
15093
15371
  );
15094
- const pauseCron = useCallback31(
15372
+ const pauseCron = useCallback30(
15095
15373
  async (scheduleId) => {
15096
15374
  setIsLoading(true);
15097
15375
  setError(null);
@@ -15107,7 +15385,7 @@ function useTasks() {
15107
15385
  },
15108
15386
  [ctx]
15109
15387
  );
15110
- const resumeCron = useCallback31(
15388
+ const resumeCron = useCallback30(
15111
15389
  async (scheduleId) => {
15112
15390
  setIsLoading(true);
15113
15391
  setError(null);
@@ -15123,7 +15401,7 @@ function useTasks() {
15123
15401
  },
15124
15402
  [ctx]
15125
15403
  );
15126
- const deleteCron = useCallback31(
15404
+ const deleteCron = useCallback30(
15127
15405
  async (scheduleId) => {
15128
15406
  setIsLoading(true);
15129
15407
  setError(null);
@@ -15139,7 +15417,7 @@ function useTasks() {
15139
15417
  },
15140
15418
  [ctx]
15141
15419
  );
15142
- const getJob = useCallback31(
15420
+ const getJob = useCallback30(
15143
15421
  async (jobId) => {
15144
15422
  try {
15145
15423
  return await ctx.getJob(jobId);
@@ -15151,7 +15429,7 @@ function useTasks() {
15151
15429
  },
15152
15430
  [ctx]
15153
15431
  );
15154
- const listJobs = useCallback31(
15432
+ const listJobs = useCallback30(
15155
15433
  async (options = {}) => {
15156
15434
  try {
15157
15435
  const result = await ctx.listJobs(options);
@@ -15164,7 +15442,7 @@ function useTasks() {
15164
15442
  },
15165
15443
  [ctx]
15166
15444
  );
15167
- const cancelJob = useCallback31(
15445
+ const cancelJob = useCallback30(
15168
15446
  async (jobId) => {
15169
15447
  setIsLoading(true);
15170
15448
  setError(null);
@@ -15197,19 +15475,19 @@ function useTasks() {
15197
15475
 
15198
15476
  // src/react/webhooks-hooks.ts
15199
15477
  init_constants();
15200
- import { useInfiniteQuery as useInfiniteQuery2, useQuery as useQuery8, useQueryClient as useQueryClient7 } from "@tanstack/react-query";
15201
- import { useCallback as useCallback32 } from "react";
15478
+ import { useInfiniteQuery as useInfiniteQuery2, useQuery as useQuery9, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
15479
+ import { useCallback as useCallback31 } from "react";
15202
15480
  function useWebhooks() {
15203
15481
  const ctx = useWebhooksContext();
15204
- const queryClient = useQueryClient7();
15205
- const configQuery = useQuery8({
15482
+ const queryClient = useQueryClient8();
15483
+ const configQuery = useQuery9({
15206
15484
  queryKey: ["sylphx", "webhooks", "config"],
15207
15485
  queryFn: () => ctx.getConfig(),
15208
15486
  staleTime: STALE_TIME_STABLE_MS
15209
15487
  // 5 min - config rarely changes
15210
15488
  });
15211
15489
  const config2 = configQuery.data;
15212
- const updateConfig = useCallback32(
15490
+ const updateConfig = useCallback31(
15213
15491
  async (options) => {
15214
15492
  const result = await ctx.updateConfig(options);
15215
15493
  await queryClient.invalidateQueries({
@@ -15219,7 +15497,7 @@ function useWebhooks() {
15219
15497
  },
15220
15498
  [ctx, queryClient]
15221
15499
  );
15222
- const refresh = useCallback32(async () => {
15500
+ const refresh = useCallback31(async () => {
15223
15501
  await queryClient.invalidateQueries({
15224
15502
  queryKey: ["sylphx", "webhooks", "config"]
15225
15503
  });
@@ -15236,7 +15514,7 @@ function useWebhooks() {
15236
15514
  function useWebhookDeliveries(options = {}) {
15237
15515
  const { status, event, limit = 50, skip = false, refetchInterval } = options;
15238
15516
  const ctx = useWebhooksContext();
15239
- const queryClient = useQueryClient7();
15517
+ const queryClient = useQueryClient8();
15240
15518
  const deliveriesQuery = useInfiniteQuery2({
15241
15519
  queryKey: ["sylphx", "webhooks", "deliveries", { status, event, limit }],
15242
15520
  queryFn: async ({ pageParam = 0 }) => {
@@ -15257,7 +15535,7 @@ function useWebhookDeliveries(options = {}) {
15257
15535
  });
15258
15536
  const deliveries = deliveriesQuery.data?.pages.flatMap((page) => page.deliveries) ?? [];
15259
15537
  const total = deliveriesQuery.data?.pages[0]?.total ?? 0;
15260
- const replay = useCallback32(
15538
+ const replay = useCallback31(
15261
15539
  async (deliveryId) => {
15262
15540
  const result = await ctx.replayDelivery(deliveryId);
15263
15541
  await queryClient.invalidateQueries({
@@ -15267,12 +15545,12 @@ function useWebhookDeliveries(options = {}) {
15267
15545
  },
15268
15546
  [ctx, queryClient]
15269
15547
  );
15270
- const refresh = useCallback32(async () => {
15548
+ const refresh = useCallback31(async () => {
15271
15549
  await queryClient.invalidateQueries({
15272
15550
  queryKey: ["sylphx", "webhooks", "deliveries"]
15273
15551
  });
15274
15552
  }, [queryClient]);
15275
- const loadMore = useCallback32(async () => {
15553
+ const loadMore = useCallback31(async () => {
15276
15554
  if (deliveriesQuery.hasNextPage && !deliveriesQuery.isFetchingNextPage) {
15277
15555
  await deliveriesQuery.fetchNextPage();
15278
15556
  }
@@ -15291,14 +15569,14 @@ function useWebhookDeliveries(options = {}) {
15291
15569
  }
15292
15570
  function useWebhookStats(period = "week") {
15293
15571
  const ctx = useWebhooksContext();
15294
- const queryClient = useQueryClient7();
15295
- const statsQuery = useQuery8({
15572
+ const queryClient = useQueryClient8();
15573
+ const statsQuery = useQuery9({
15296
15574
  queryKey: ["sylphx", "webhooks", "stats", period],
15297
15575
  queryFn: () => ctx.getStats(period),
15298
15576
  staleTime: STALE_TIME_MODERATE_MS
15299
15577
  // 2 min - stats aggregate data
15300
15578
  });
15301
- const refresh = useCallback32(async () => {
15579
+ const refresh = useCallback31(async () => {
15302
15580
  await queryClient.invalidateQueries({
15303
15581
  queryKey: ["sylphx", "webhooks", "stats", period]
15304
15582
  });
@@ -15313,7 +15591,7 @@ function useWebhookStats(period = "week") {
15313
15591
 
15314
15592
  // src/react/ui/account-section.tsx
15315
15593
  init_constants();
15316
- import { useCallback as useCallback33, useEffect as useEffect25, useId as useId4, useState as useState34 } from "react";
15594
+ import { useCallback as useCallback32, useEffect as useEffect25, useId as useId4, useState as useState33 } from "react";
15317
15595
  import { Fragment as Fragment18, jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
15318
15596
  function AccountSection(props) {
15319
15597
  return /* @__PURE__ */ jsx25(RequireSdk, { services: ["auth"], componentType: "account", theme: props.theme, children: /* @__PURE__ */ jsx25(AccountSectionInner, { ...props }) });
@@ -15335,22 +15613,22 @@ function AccountSectionInner({
15335
15613
  const styles2 = baseStyles(theme);
15336
15614
  const newEmailId = useId4();
15337
15615
  const emailPasswordId = useId4();
15338
- const [error, setError] = useState34(null);
15339
- const [success, setSuccess] = useState34(null);
15340
- const [showEmailChangeForm, setShowEmailChangeForm] = useState34(false);
15341
- const [newEmail, setNewEmail] = useState34("");
15342
- const [emailPassword, setEmailPassword] = useState34("");
15343
- const [isChangingEmail, setIsChangingEmail] = useState34(false);
15344
- const [isExporting, setIsExporting] = useState34(false);
15345
- const [exportUrl, setExportUrl] = useState34(null);
15346
- const [showDeleteConfirm, setShowDeleteConfirm] = useState34(false);
15347
- const [deleteConfirmText, setDeleteConfirmText] = useState34("");
15348
- const [deletePassword, setDeletePassword] = useState34("");
15349
- const [delete2FACode, setDelete2FACode] = useState34("");
15350
- const [isDeleting, setIsDeleting] = useState34(false);
15351
- const [deleteStep, setDeleteStep] = useState34("confirm");
15352
- const [has2FAEnabled, setHas2FAEnabled] = useState34(false);
15353
- const [isChecking2FA, setIsChecking2FA] = useState34(false);
15616
+ const [error, setError] = useState33(null);
15617
+ const [success, setSuccess] = useState33(null);
15618
+ const [showEmailChangeForm, setShowEmailChangeForm] = useState33(false);
15619
+ const [newEmail, setNewEmail] = useState33("");
15620
+ const [emailPassword, setEmailPassword] = useState33("");
15621
+ const [isChangingEmail, setIsChangingEmail] = useState33(false);
15622
+ const [isExporting, setIsExporting] = useState33(false);
15623
+ const [exportUrl, setExportUrl] = useState33(null);
15624
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState33(false);
15625
+ const [deleteConfirmText, setDeleteConfirmText] = useState33("");
15626
+ const [deletePassword, setDeletePassword] = useState33("");
15627
+ const [delete2FACode, setDelete2FACode] = useState33("");
15628
+ const [isDeleting, setIsDeleting] = useState33(false);
15629
+ const [deleteStep, setDeleteStep] = useState33("confirm");
15630
+ const [has2FAEnabled, setHas2FAEnabled] = useState33(false);
15631
+ const [isChecking2FA, setIsChecking2FA] = useState33(false);
15354
15632
  useEffect25(() => {
15355
15633
  injectGlobalStyles();
15356
15634
  }, []);
@@ -15404,7 +15682,7 @@ function AccountSectionInner({
15404
15682
  setIsExporting(false);
15405
15683
  }
15406
15684
  };
15407
- const checkSecurityStatus = useCallback33(async () => {
15685
+ const checkSecurityStatus = useCallback32(async () => {
15408
15686
  setIsChecking2FA(true);
15409
15687
  try {
15410
15688
  const status = await securityContext.getTwoFactorStatus();
@@ -15940,7 +16218,7 @@ function ShieldIcon({ size = 24, color = "currentColor" }) {
15940
16218
  }
15941
16219
 
15942
16220
  // src/react/ui/analytics-dashboard.tsx
15943
- import { useEffect as useEffect26, useState as useState35 } from "react";
16221
+ import { useEffect as useEffect26, useState as useState34 } from "react";
15944
16222
  import { Fragment as Fragment19, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
15945
16223
  function EventViewer({
15946
16224
  theme = defaultTheme,
@@ -15954,8 +16232,8 @@ function EventViewer({
15954
16232
  emptyMessage = "No events recorded yet",
15955
16233
  title = "Recent Events"
15956
16234
  }) {
15957
- const [search2, setSearch] = useState35("");
15958
- const [expandedId, setExpandedId] = useState35(null);
16235
+ const [search2, setSearch] = useState34("");
16236
+ const [expandedId, setExpandedId] = useState34(null);
15959
16237
  const styles2 = baseStyles(theme);
15960
16238
  useEffect26(() => {
15961
16239
  injectGlobalStyles();
@@ -16593,7 +16871,7 @@ function ChartIcon({ color }) {
16593
16871
 
16594
16872
  // src/react/ui/api-key-manager.tsx
16595
16873
  init_constants();
16596
- import { useEffect as useEffect27, useId as useId5, useState as useState36 } from "react";
16874
+ import { useEffect as useEffect27, useId as useId5, useState as useState35 } from "react";
16597
16875
  import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
16598
16876
  var DEFAULT_SCOPES = [
16599
16877
  "read:users",
@@ -16617,15 +16895,15 @@ function APIKeyManager({
16617
16895
  }) {
16618
16896
  const keyNameId = useId5();
16619
16897
  const expirationId = useId5();
16620
- const [showCreate, setShowCreate] = useState36(false);
16621
- const [name, setName] = useState36("");
16622
- const [selectedScopes, setSelectedScopes] = useState36([]);
16623
- const [expiresIn, setExpiresIn] = useState36(void 0);
16624
- const [isCreating, setIsCreating] = useState36(false);
16625
- const [error, setError] = useState36(null);
16626
- const [newKey, setNewKey] = useState36(null);
16627
- const [revokingId, setRevokingId] = useState36(null);
16628
- const [copied, setCopied] = useState36(false);
16898
+ const [showCreate, setShowCreate] = useState35(false);
16899
+ const [name, setName] = useState35("");
16900
+ const [selectedScopes, setSelectedScopes] = useState35([]);
16901
+ const [expiresIn, setExpiresIn] = useState35(void 0);
16902
+ const [isCreating, setIsCreating] = useState35(false);
16903
+ const [error, setError] = useState35(null);
16904
+ const [newKey, setNewKey] = useState35(null);
16905
+ const [revokingId, setRevokingId] = useState35(null);
16906
+ const [copied, setCopied] = useState35(false);
16629
16907
  const styles2 = baseStyles(theme);
16630
16908
  useEffect27(() => {
16631
16909
  injectGlobalStyles();
@@ -17212,7 +17490,7 @@ function CheckIcon10({ color }) {
17212
17490
  }
17213
17491
 
17214
17492
  // src/react/ui/billing-management.tsx
17215
- import { useEffect as useEffect28, useState as useState37 } from "react";
17493
+ import { useEffect as useEffect28, useState as useState36 } from "react";
17216
17494
  import { Fragment as Fragment20, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
17217
17495
  function InvoiceHistory({
17218
17496
  theme = defaultTheme,
@@ -17224,8 +17502,8 @@ function InvoiceHistory({
17224
17502
  pageSize = 10,
17225
17503
  emptyMessage = "No invoices yet"
17226
17504
  }) {
17227
- const [invoices] = useState37(propInvoices ?? []);
17228
- const [currentPage, setCurrentPage] = useState37(1);
17505
+ const [invoices] = useState36(propInvoices ?? []);
17506
+ const [currentPage, setCurrentPage] = useState36(1);
17229
17507
  const styles2 = baseStyles(theme);
17230
17508
  useEffect28(() => {
17231
17509
  injectGlobalStyles();
@@ -17849,7 +18127,7 @@ function PlusIcon4({ color }) {
17849
18127
 
17850
18128
  // src/react/ui/billing-section.tsx
17851
18129
  init_constants();
17852
- import { useEffect as useEffect29, useState as useState38 } from "react";
18130
+ import { useEffect as useEffect29, useState as useState37 } from "react";
17853
18131
  import { Fragment as Fragment21, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
17854
18132
  function BillingSection(props) {
17855
18133
  return /* @__PURE__ */ jsx29(RequireSdk, { services: ["billing"], componentType: "billing", theme: props.theme, children: /* @__PURE__ */ jsx29(BillingSectionInner, { ...props }) });
@@ -17876,10 +18154,10 @@ function BillingSectionInner({
17876
18154
  refresh: _refresh
17877
18155
  } = useBilling();
17878
18156
  const styles2 = baseStyles(theme);
17879
- const [selectedInterval, setSelectedInterval] = useState38("monthly");
17880
- const [processingPlan, setProcessingPlan] = useState38(null);
17881
- const [error, setError] = useState38(null);
17882
- const [success, setSuccess] = useState38(null);
18157
+ const [selectedInterval, setSelectedInterval] = useState37("monthly");
18158
+ const [processingPlan, setProcessingPlan] = useState37(null);
18159
+ const [error, setError] = useState37(null);
18160
+ const [success, setSuccess] = useState37(null);
17883
18161
  useEffect29(() => {
17884
18162
  injectGlobalStyles();
17885
18163
  }, []);
@@ -18266,8 +18544,8 @@ function CheckIcon11({ color }) {
18266
18544
  // src/react/ui/chat-interface.tsx
18267
18545
  import {
18268
18546
  useEffect as useEffect30,
18269
- useRef as useRef14,
18270
- useState as useState39
18547
+ useRef as useRef12,
18548
+ useState as useState38
18271
18549
  } from "react";
18272
18550
  import { Fragment as Fragment22, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
18273
18551
  function ChatInterface({
@@ -18292,9 +18570,9 @@ function ChatInterface({
18292
18570
  ...chatOptions
18293
18571
  }) {
18294
18572
  const { messages, send, isLoading, error, clear, retry } = useChat(chatOptions);
18295
- const [input, setInput] = useState39("");
18296
- const messagesEndRef = useRef14(null);
18297
- const inputRef = useRef14(null);
18573
+ const [input, setInput] = useState38("");
18574
+ const messagesEndRef = useRef12(null);
18575
+ const inputRef = useRef12(null);
18298
18576
  const styles2 = baseStyles(theme);
18299
18577
  useEffect30(() => {
18300
18578
  injectGlobalStyles();
@@ -18670,8 +18948,8 @@ function ChatInput({
18670
18948
  onSubmit,
18671
18949
  isLoading = false
18672
18950
  }) {
18673
- const [input, setInput] = useState39("");
18674
- const inputRef = useRef14(null);
18951
+ const [input, setInput] = useState38("");
18952
+ const inputRef = useRef12(null);
18675
18953
  const handleSubmit = (e2) => {
18676
18954
  e2?.preventDefault();
18677
18955
  if (!input.trim() || disabled || isLoading) return;
@@ -18773,7 +19051,7 @@ function SendIcon2({ color }) {
18773
19051
 
18774
19052
  // src/react/ui/consent-preferences.tsx
18775
19053
  init_constants();
18776
- import { useEffect as useEffect31, useState as useState40 } from "react";
19054
+ import { useEffect as useEffect31, useState as useState39 } from "react";
18777
19055
  import { Fragment as Fragment23, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
18778
19056
  var CATEGORY_INFO = {
18779
19057
  necessary: {
@@ -18825,8 +19103,8 @@ function ConsentPreferences({
18825
19103
  saveConsents,
18826
19104
  hasConsented
18827
19105
  } = useConsent();
18828
- const [isSaving, setIsSaving] = useState40(false);
18829
- const [saveSuccess, setSaveSuccess] = useState40(false);
19106
+ const [isSaving, setIsSaving] = useState39(false);
19107
+ const [saveSuccess, setSaveSuccess] = useState39(false);
18830
19108
  const styles2 = baseStyles(theme);
18831
19109
  useEffect31(() => {
18832
19110
  injectGlobalStyles();
@@ -19256,7 +19534,7 @@ function CheckIcon12({ color }) {
19256
19534
 
19257
19535
  // src/react/ui/cookie-banner.tsx
19258
19536
  init_constants();
19259
- import { useEffect as useEffect32, useState as useState41 } from "react";
19537
+ import { useEffect as useEffect32, useState as useState40 } from "react";
19260
19538
  import { Fragment as Fragment24, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
19261
19539
  function CookieBanner({
19262
19540
  theme = defaultTheme,
@@ -19283,8 +19561,8 @@ function CookieBanner({
19283
19561
  saveConsents,
19284
19562
  isLoading
19285
19563
  } = useConsent();
19286
- const [showCustomize, setShowCustomize] = useState41(false);
19287
- const [isVisible, setIsVisible] = useState41(false);
19564
+ const [showCustomize, setShowCustomize] = useState40(false);
19565
+ const [isVisible, setIsVisible] = useState40(false);
19288
19566
  const styles2 = baseStyles(theme);
19289
19567
  useEffect32(() => {
19290
19568
  injectGlobalStyles();
@@ -19657,7 +19935,7 @@ init_constants();
19657
19935
  import {
19658
19936
  Component,
19659
19937
  useEffect as useEffect33,
19660
- useState as useState42
19938
+ useState as useState41
19661
19939
  } from "react";
19662
19940
  import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
19663
19941
  var SylphxErrorBoundary = class extends Component {
@@ -19891,12 +20169,12 @@ function FeedbackWidget({
19891
20169
  position = "bottom-right",
19892
20170
  defaultOpen = false
19893
20171
  }) {
19894
- const [isOpen, setIsOpen] = useState42(defaultOpen);
19895
- const [message, setMessage] = useState42("");
19896
- const [email, setEmail] = useState42("");
19897
- const [isSubmitting, setIsSubmitting] = useState42(false);
19898
- const [isSuccess, setIsSuccess] = useState42(false);
19899
- const [error, setError] = useState42(null);
20172
+ const [isOpen, setIsOpen] = useState41(defaultOpen);
20173
+ const [message, setMessage] = useState41("");
20174
+ const [email, setEmail] = useState41("");
20175
+ const [isSubmitting, setIsSubmitting] = useState41(false);
20176
+ const [isSuccess, setIsSuccess] = useState41(false);
20177
+ const [error, setError] = useState41(null);
19900
20178
  const { captureMessage } = useErrorTracking();
19901
20179
  const styles2 = baseStyles(theme);
19902
20180
  useEffect33(() => {
@@ -20136,7 +20414,7 @@ function CheckCircleIcon({ color }) {
20136
20414
 
20137
20415
  // src/react/ui/feature-gate.tsx
20138
20416
  init_constants();
20139
- import { useContext as useContext17, useState as useState43 } from "react";
20417
+ import { useContext as useContext18, useState as useState42 } from "react";
20140
20418
  import { Fragment as Fragment25, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
20141
20419
  function FeatureGate({
20142
20420
  flag,
@@ -20204,8 +20482,8 @@ function FlagDevTools({
20204
20482
  defaultCollapsed = true,
20205
20483
  className
20206
20484
  }) {
20207
- const [isCollapsed, setIsCollapsed] = useState43(defaultCollapsed);
20208
- const context = useContext17(FeatureFlagContext);
20485
+ const [isCollapsed, setIsCollapsed] = useState42(defaultCollapsed);
20486
+ const context = useContext18(FeatureFlagContext);
20209
20487
  const styles2 = baseStyles(theme);
20210
20488
  if (!context) {
20211
20489
  return null;
@@ -20439,8 +20717,54 @@ function CloseIcon4() {
20439
20717
 
20440
20718
  // src/react/ui/file-upload.tsx
20441
20719
  init_constants();
20442
- import { useCallback as useCallback34, useEffect as useEffect34, useRef as useRef15, useState as useState44 } from "react";
20720
+ import { useCallback as useCallback33, useEffect as useEffect34, useRef as useRef13, useState as useState43 } from "react";
20443
20721
  import { Fragment as Fragment26, jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
20722
+ function useUploadAdapter(options = {}) {
20723
+ const { upload: doUpload, isUploading } = useStorage();
20724
+ const [progress, setProgress] = useState43(0);
20725
+ const [error, setError] = useState43(null);
20726
+ const upload = useCallback33(
20727
+ async (file) => {
20728
+ setError(null);
20729
+ setProgress(0);
20730
+ if (options.accept && options.accept.length > 0) {
20731
+ const accepted = options.accept.some(
20732
+ (t2) => t2.endsWith("/*") ? file.type.startsWith(t2.slice(0, -2)) : file.type === t2
20733
+ );
20734
+ if (!accepted) {
20735
+ const e2 = new Error(`File type ${file.type} not accepted`);
20736
+ setError(e2);
20737
+ options.onError?.(e2);
20738
+ throw e2;
20739
+ }
20740
+ }
20741
+ if (options.maxSize && file.size > options.maxSize) {
20742
+ const mb = (options.maxSize / 1024 / 1024).toFixed(1);
20743
+ const e2 = new Error(`File size exceeds ${mb}MB limit`);
20744
+ setError(e2);
20745
+ options.onError?.(e2);
20746
+ throw e2;
20747
+ }
20748
+ try {
20749
+ const result = await doUpload(file, {
20750
+ folder: options.folder,
20751
+ onProgress: (e2) => {
20752
+ setProgress(e2.total > 0 ? Math.round(e2.loaded / e2.total * 100) : 0);
20753
+ }
20754
+ });
20755
+ setProgress(100);
20756
+ return result.url ?? "";
20757
+ } catch (err) {
20758
+ const e2 = err instanceof Error ? err : new Error("Upload failed");
20759
+ setError(e2);
20760
+ options.onError?.(e2);
20761
+ throw e2;
20762
+ }
20763
+ },
20764
+ [doUpload, options.accept, options.maxSize, options.folder, options.onError]
20765
+ );
20766
+ return { upload, isUploading, progress, error };
20767
+ }
20444
20768
  function FileUpload(props) {
20445
20769
  return /* @__PURE__ */ jsx35(RequireSdk, { services: ["storage"], componentType: "storage", theme: props.theme, children: /* @__PURE__ */ jsx35(FileUploadInner, { ...props }) });
20446
20770
  }
@@ -20456,10 +20780,10 @@ function FileUploadInner({
20456
20780
  placeholder = "Drop files here or click to upload",
20457
20781
  showFileList = true
20458
20782
  }) {
20459
- const [isDragging, setIsDragging] = useState44(false);
20460
- const [uploadedFiles, setUploadedFiles] = useState44([]);
20461
- const inputRef = useRef15(null);
20462
- const { upload, isUploading, progress, error } = useFileUpload({
20783
+ const [isDragging, setIsDragging] = useState43(false);
20784
+ const [uploadedFiles, setUploadedFiles] = useState43([]);
20785
+ const inputRef = useRef13(null);
20786
+ const { upload, isUploading, progress, error } = useUploadAdapter({
20463
20787
  accept,
20464
20788
  maxSize,
20465
20789
  onError
@@ -20468,7 +20792,7 @@ function FileUploadInner({
20468
20792
  useEffect34(() => {
20469
20793
  injectGlobalStyles();
20470
20794
  }, []);
20471
- const handleFiles = useCallback34(
20795
+ const handleFiles = useCallback33(
20472
20796
  async (files) => {
20473
20797
  if (!files || files.length === 0) return;
20474
20798
  const fileArray = Array.from(files);
@@ -20487,7 +20811,7 @@ function FileUploadInner({
20487
20811
  },
20488
20812
  [upload, onUpload]
20489
20813
  );
20490
- const handleDrop = useCallback34(
20814
+ const handleDrop = useCallback33(
20491
20815
  (e2) => {
20492
20816
  e2.preventDefault();
20493
20817
  e2.stopPropagation();
@@ -20497,7 +20821,7 @@ function FileUploadInner({
20497
20821
  },
20498
20822
  [handleFiles, disabled]
20499
20823
  );
20500
- const handleDragOver = useCallback34(
20824
+ const handleDragOver = useCallback33(
20501
20825
  (e2) => {
20502
20826
  e2.preventDefault();
20503
20827
  e2.stopPropagation();
@@ -20505,7 +20829,7 @@ function FileUploadInner({
20505
20829
  },
20506
20830
  [disabled]
20507
20831
  );
20508
- const handleDragLeave = useCallback34((e2) => {
20832
+ const handleDragLeave = useCallback33((e2) => {
20509
20833
  e2.preventDefault();
20510
20834
  e2.stopPropagation();
20511
20835
  setIsDragging(false);
@@ -20668,9 +20992,9 @@ function ImageUploaderInner({
20668
20992
  aspectRatio = "1:1",
20669
20993
  placeholder = "Click to upload image"
20670
20994
  }) {
20671
- const [previewUrl, setPreviewUrl] = useState44(value || null);
20672
- const inputRef = useRef15(null);
20673
- const { upload, isUploading, progress, error } = useFileUpload({
20995
+ const [previewUrl, setPreviewUrl] = useState43(value || null);
20996
+ const inputRef = useRef13(null);
20997
+ const { upload, isUploading, progress, error } = useUploadAdapter({
20674
20998
  accept: ["image/*"],
20675
20999
  maxSize,
20676
21000
  onError
@@ -20864,9 +21188,14 @@ function AvatarUploadInner({
20864
21188
  size = 96,
20865
21189
  placeholder = ""
20866
21190
  }) {
20867
- const [previewUrl, setPreviewUrl] = useState44(value || null);
20868
- const inputRef = useRef15(null);
20869
- const { uploadAvatar, isUploading, uploadError } = useStorage();
21191
+ const [previewUrl, setPreviewUrl] = useState43(value || null);
21192
+ const inputRef = useRef13(null);
21193
+ const { upload, isUploading, error } = useUploadAdapter({
21194
+ accept: ["image/*"],
21195
+ maxSize,
21196
+ folder: "avatars",
21197
+ onError
21198
+ });
20870
21199
  const styles2 = baseStyles(theme);
20871
21200
  useEffect34(() => {
20872
21201
  setPreviewUrl(value || null);
@@ -20875,18 +21204,10 @@ function AvatarUploadInner({
20875
21204
  injectGlobalStyles();
20876
21205
  }, []);
20877
21206
  const handleFile = async (file) => {
20878
- if (maxSize && file.size > maxSize) {
20879
- onError?.(new Error(`File size exceeds ${formatFileSize(maxSize)} limit`));
20880
- return;
20881
- }
20882
- if (!file.type.startsWith("image/")) {
20883
- onError?.(new Error("Please upload an image file"));
20884
- return;
20885
- }
20886
21207
  try {
20887
21208
  const localUrl = URL.createObjectURL(file);
20888
21209
  setPreviewUrl(localUrl);
20889
- const url = await uploadAvatar(file);
21210
+ const url = await upload(file);
20890
21211
  setPreviewUrl(url);
20891
21212
  onChange?.(url);
20892
21213
  URL.revokeObjectURL(localUrl);
@@ -20988,14 +21309,14 @@ function AvatarUploadInner({
20988
21309
  ]
20989
21310
  }
20990
21311
  ),
20991
- uploadError && /* @__PURE__ */ jsx35(
21312
+ error && /* @__PURE__ */ jsx35(
20992
21313
  "p",
20993
21314
  {
20994
21315
  style: mergeStyles(styles2.textXs, {
20995
21316
  color: theme.colorDestructive,
20996
21317
  marginTop: "0.5rem"
20997
21318
  }),
20998
- children: uploadError.message
21319
+ children: error.message
20999
21320
  }
21000
21321
  )
21001
21322
  ] });
@@ -21131,17 +21452,17 @@ function CloseIcon5() {
21131
21452
 
21132
21453
  // src/react/ui/job-scheduler.tsx
21133
21454
  init_constants();
21134
- import { useMutation as useMutation2, useQuery as useQuery10, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
21135
- import { useCallback as useCallback36, useEffect as useEffect36, useState as useState46 } from "react";
21455
+ import { useMutation as useMutation3, useQuery as useQuery11, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
21456
+ import { useCallback as useCallback35, useEffect as useEffect36, useState as useState45 } from "react";
21136
21457
 
21137
21458
  // src/react/job-hooks.ts
21138
- import { useQuery as useQuery9, useQueryClient as useQueryClient8 } from "@tanstack/react-query";
21139
- import { useCallback as useCallback35, useEffect as useEffect35, useRef as useRef16, useState as useState45 } from "react";
21459
+ import { useQuery as useQuery10, useQueryClient as useQueryClient9 } from "@tanstack/react-query";
21460
+ import { useCallback as useCallback34, useEffect as useEffect35, useRef as useRef14, useState as useState44 } from "react";
21140
21461
  function useJobs() {
21141
21462
  const ctx = useJobsContext();
21142
- const [isLoading, setIsLoading] = useState45(false);
21143
- const [error, setError] = useState45(null);
21144
- const isAvailable = useCallback35(async () => {
21463
+ const [isLoading, setIsLoading] = useState44(false);
21464
+ const [error, setError] = useState44(null);
21465
+ const isAvailable = useCallback34(async () => {
21145
21466
  try {
21146
21467
  const status = await ctx.checkStatus();
21147
21468
  return status.available;
@@ -21149,7 +21470,7 @@ function useJobs() {
21149
21470
  return false;
21150
21471
  }
21151
21472
  }, [ctx]);
21152
- const schedule = useCallback35(
21473
+ const schedule = useCallback34(
21153
21474
  async (options) => {
21154
21475
  setIsLoading(true);
21155
21476
  setError(null);
@@ -21165,7 +21486,7 @@ function useJobs() {
21165
21486
  },
21166
21487
  [ctx]
21167
21488
  );
21168
- const createCron = useCallback35(
21489
+ const createCron = useCallback34(
21169
21490
  async (options) => {
21170
21491
  setIsLoading(true);
21171
21492
  setError(null);
@@ -21181,7 +21502,7 @@ function useJobs() {
21181
21502
  },
21182
21503
  [ctx]
21183
21504
  );
21184
- const pauseCron = useCallback35(
21505
+ const pauseCron = useCallback34(
21185
21506
  async (scheduleId) => {
21186
21507
  setIsLoading(true);
21187
21508
  setError(null);
@@ -21197,7 +21518,7 @@ function useJobs() {
21197
21518
  },
21198
21519
  [ctx]
21199
21520
  );
21200
- const resumeCron = useCallback35(
21521
+ const resumeCron = useCallback34(
21201
21522
  async (scheduleId) => {
21202
21523
  setIsLoading(true);
21203
21524
  setError(null);
@@ -21213,7 +21534,7 @@ function useJobs() {
21213
21534
  },
21214
21535
  [ctx]
21215
21536
  );
21216
- const deleteCron = useCallback35(
21537
+ const deleteCron = useCallback34(
21217
21538
  async (scheduleId) => {
21218
21539
  setIsLoading(true);
21219
21540
  setError(null);
@@ -21229,7 +21550,7 @@ function useJobs() {
21229
21550
  },
21230
21551
  [ctx]
21231
21552
  );
21232
- const getJob = useCallback35(
21553
+ const getJob = useCallback34(
21233
21554
  async (jobId) => {
21234
21555
  try {
21235
21556
  return await ctx.getJob(jobId);
@@ -21241,7 +21562,7 @@ function useJobs() {
21241
21562
  },
21242
21563
  [ctx]
21243
21564
  );
21244
- const listJobs = useCallback35(
21565
+ const listJobs = useCallback34(
21245
21566
  async (options = {}) => {
21246
21567
  try {
21247
21568
  const result = await ctx.listJobs(options);
@@ -21254,7 +21575,7 @@ function useJobs() {
21254
21575
  },
21255
21576
  [ctx]
21256
21577
  );
21257
- const cancelJob = useCallback35(
21578
+ const cancelJob = useCallback34(
21258
21579
  async (jobId) => {
21259
21580
  setIsLoading(true);
21260
21581
  setError(null);
@@ -21295,14 +21616,14 @@ function JobScheduler({
21295
21616
  showCronTab = true
21296
21617
  }) {
21297
21618
  const { schedule, createCron, isLoading, error } = useJobs();
21298
- const [activeTab, setActiveTab] = useState46("one-time");
21299
- const [name, setName] = useState46("");
21300
- const [callbackUrl, setCallbackUrl] = useState46(defaultCallbackUrl);
21301
- const [payload, setPayload] = useState46("{}");
21302
- const [delay2, setDelay] = useState46(60);
21303
- const [delayUnit, setDelayUnit] = useState46("seconds");
21304
- const [cronExpression, setCronExpression] = useState46("0 9 * * *");
21305
- const [scheduleSuccess, setScheduleSuccess] = useState46(false);
21619
+ const [activeTab, setActiveTab] = useState45("one-time");
21620
+ const [name, setName] = useState45("");
21621
+ const [callbackUrl, setCallbackUrl] = useState45(defaultCallbackUrl);
21622
+ const [payload, setPayload] = useState45("{}");
21623
+ const [delay2, setDelay] = useState45(60);
21624
+ const [delayUnit, setDelayUnit] = useState45("seconds");
21625
+ const [cronExpression, setCronExpression] = useState45("0 9 * * *");
21626
+ const [scheduleSuccess, setScheduleSuccess] = useState45(false);
21306
21627
  const styles2 = baseStyles(theme);
21307
21628
  useEffect36(() => {
21308
21629
  injectGlobalStyles();
@@ -21644,13 +21965,13 @@ function JobList({
21644
21965
  emptyMessage = "No jobs scheduled"
21645
21966
  }) {
21646
21967
  const ctx = useJobsContext();
21647
- const queryClient = useQueryClient9();
21648
- const [filter, setFilter] = useState46("all");
21968
+ const queryClient = useQueryClient10();
21969
+ const [filter, setFilter] = useState45("all");
21649
21970
  const styles2 = baseStyles(theme);
21650
21971
  useEffect36(() => {
21651
21972
  injectGlobalStyles();
21652
21973
  }, []);
21653
- const jobsQuery = useQuery10({
21974
+ const jobsQuery = useQuery11({
21654
21975
  queryKey: ["sylphx", "jobs", "list", filter],
21655
21976
  queryFn: async () => {
21656
21977
  const apiStatus = filter === "all" || filter === "cancelled" ? void 0 : filter;
@@ -21666,13 +21987,13 @@ function JobList({
21666
21987
  const jobs = propJobs ?? jobsQuery.data ?? [];
21667
21988
  const isLoading = !propJobs && jobsQuery.isLoading;
21668
21989
  const filteredJobs = filter === "all" ? jobs : jobs.filter((j) => j.status === filter);
21669
- const cancelMutation = useMutation2({
21990
+ const cancelMutation = useMutation3({
21670
21991
  mutationFn: (jobId) => ctx.cancelJob(jobId),
21671
21992
  onSuccess: () => {
21672
21993
  queryClient.invalidateQueries({ queryKey: ["sylphx", "jobs", "list"] });
21673
21994
  }
21674
21995
  });
21675
- const handleCancel = useCallback36(
21996
+ const handleCancel = useCallback35(
21676
21997
  async (jobId) => {
21677
21998
  if (onCancel) {
21678
21999
  onCancel(jobId);
@@ -21862,9 +22183,9 @@ function CronBuilder({
21862
22183
  onCreate,
21863
22184
  defaultCallbackUrl = ""
21864
22185
  }) {
21865
- const [expression, setExpression] = useState46("0 9 * * *");
21866
- const [callbackUrl, setCallbackUrl] = useState46(defaultCallbackUrl);
21867
- const [name, setName] = useState46("");
22186
+ const [expression, setExpression] = useState45("0 9 * * *");
22187
+ const [callbackUrl, setCallbackUrl] = useState45(defaultCallbackUrl);
22188
+ const [name, setName] = useState45("");
21868
22189
  const styles2 = baseStyles(theme);
21869
22190
  useEffect36(() => {
21870
22191
  injectGlobalStyles();
@@ -22105,7 +22426,7 @@ function JobIcon({ color, size = 24 }) {
22105
22426
  var TaskScheduler = JobScheduler;
22106
22427
 
22107
22428
  // src/react/ui/model-selector.tsx
22108
- import { useEffect as useEffect37, useRef as useRef17, useState as useState47 } from "react";
22429
+ import { useEffect as useEffect37, useRef as useRef15, useState as useState46 } from "react";
22109
22430
  import { Fragment as Fragment27, jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
22110
22431
  function ModelSelector({
22111
22432
  theme = defaultTheme,
@@ -22120,10 +22441,10 @@ function ModelSelector({
22120
22441
  compact = false
22121
22442
  }) {
22122
22443
  const styles2 = baseStyles(theme);
22123
- const [isOpen, setIsOpen] = useState47(false);
22124
- const [searchValue, setSearchValue] = useState47("");
22125
- const containerRef = useRef17(null);
22126
- const inputRef = useRef17(null);
22444
+ const [isOpen, setIsOpen] = useState46(false);
22445
+ const [searchValue, setSearchValue] = useState46("");
22446
+ const containerRef = useRef15(null);
22447
+ const inputRef = useRef15(null);
22127
22448
  const { models, isLoading, error, setSearch, hasMore, loadMore } = useModels({
22128
22449
  capability,
22129
22450
  fetchOnMount: true,
@@ -22652,8 +22973,8 @@ function ModelGrid({
22652
22973
  fetchOnMount: true,
22653
22974
  pageSize: 24
22654
22975
  });
22655
- const [searchValue, setSearchValue] = useState47("");
22656
- const [filterCapability, setFilterCapability] = useState47(capability);
22976
+ const [searchValue, setSearchValue] = useState46("");
22977
+ const [filterCapability, setFilterCapability] = useState46(capability);
22657
22978
  useEffect37(() => {
22658
22979
  injectGlobalStyles();
22659
22980
  }, []);
@@ -22757,7 +23078,7 @@ function ModelGrid({
22757
23078
 
22758
23079
  // src/react/ui/newsletter-form.tsx
22759
23080
  import { EMAIL_REGEX } from "@sylphx/contract";
22760
- import { useEffect as useEffect38, useState as useState48 } from "react";
23081
+ import { useEffect as useEffect38, useState as useState47 } from "react";
22761
23082
  import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
22762
23083
  function NewsletterForm({
22763
23084
  theme = defaultTheme,
@@ -22788,7 +23109,7 @@ function NewsletterForm({
22788
23109
  reset
22789
23110
  } = useSubscriberForm();
22790
23111
  const styles2 = baseStyles(theme);
22791
- const [localError, setLocalError] = useState48(null);
23112
+ const [localError, setLocalError] = useState47(null);
22792
23113
  useEffect38(() => {
22793
23114
  injectGlobalStyles();
22794
23115
  }, []);
@@ -22972,7 +23293,7 @@ function NewsletterForm({
22972
23293
 
22973
23294
  // src/react/ui/notification-settings.tsx
22974
23295
  init_constants();
22975
- import { useEffect as useEffect39, useState as useState49 } from "react";
23296
+ import { useEffect as useEffect39, useState as useState48 } from "react";
22976
23297
  import { jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
22977
23298
  function NotificationSettings({
22978
23299
  theme = defaultTheme,
@@ -22992,10 +23313,10 @@ function NotificationSettings({
22992
23313
  updatePreferences
22993
23314
  } = useNotifications();
22994
23315
  const styles2 = baseStyles(theme);
22995
- const [error, setError] = useState49(null);
22996
- const [success, setSuccess] = useState49(null);
22997
- const [isTogglingPush, setIsTogglingPush] = useState49(false);
22998
- const [localPrefs, setLocalPrefs] = useState49(
23316
+ const [error, setError] = useState48(null);
23317
+ const [success, setSuccess] = useState48(null);
23318
+ const [isTogglingPush, setIsTogglingPush] = useState48(false);
23319
+ const [localPrefs, setLocalPrefs] = useState48(
22999
23320
  () => preferences?.categories ?? {}
23000
23321
  );
23001
23322
  useEffect39(() => {
@@ -23241,7 +23562,7 @@ function BellOffIcon({ size = 24 }) {
23241
23562
 
23242
23563
  // src/react/ui/organization-management.tsx
23243
23564
  init_constants();
23244
- import { useEffect as useEffect40, useId as useId6, useState as useState50 } from "react";
23565
+ import { useEffect as useEffect40, useId as useId6, useState as useState49 } from "react";
23245
23566
  import { Fragment as Fragment28, jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
23246
23567
  function OrganizationProfile(props) {
23247
23568
  return /* @__PURE__ */ jsx40(RequireSdk, { services: ["organization"], componentType: "organization", theme: props.theme, children: /* @__PURE__ */ jsx40(OrganizationProfileInner, { ...props }) });
@@ -23262,12 +23583,12 @@ function OrganizationProfileInner({
23262
23583
  const nameId = useId6();
23263
23584
  const slugId = useId6();
23264
23585
  const deleteConfirmId = useId6();
23265
- const [name, setName] = useState50(org?.name ?? "");
23266
- const [slug, setSlug] = useState50(org?.slug ?? "");
23267
- const [isSaving, setIsSaving] = useState50(false);
23268
- const [isDeleting, setIsDeleting] = useState50(false);
23269
- const [saveSuccess, setSaveSuccess] = useState50(false);
23270
- const [deleteConfirm, setDeleteConfirm] = useState50("");
23586
+ const [name, setName] = useState49(org?.name ?? "");
23587
+ const [slug, setSlug] = useState49(org?.slug ?? "");
23588
+ const [isSaving, setIsSaving] = useState49(false);
23589
+ const [isDeleting, setIsDeleting] = useState49(false);
23590
+ const [saveSuccess, setSaveSuccess] = useState49(false);
23591
+ const [deleteConfirm, setDeleteConfirm] = useState49("");
23271
23592
  const styles2 = baseStyles(theme);
23272
23593
  useEffect40(() => {
23273
23594
  injectGlobalStyles();
@@ -23635,10 +23956,10 @@ function CreateOrganization({
23635
23956
  }) {
23636
23957
  const createNameId = useId6();
23637
23958
  const createSlugId = useId6();
23638
- const [name, setName] = useState50("");
23639
- const [slug, setSlug] = useState50("");
23640
- const [isCreating, setIsCreating] = useState50(false);
23641
- const [error, setError] = useState50(null);
23959
+ const [name, setName] = useState49("");
23960
+ const [slug, setSlug] = useState49("");
23961
+ const [isCreating, setIsCreating] = useState49(false);
23962
+ const [error, setError] = useState49(null);
23642
23963
  const styles2 = baseStyles(theme);
23643
23964
  useEffect40(() => {
23644
23965
  injectGlobalStyles();
@@ -23991,7 +24312,7 @@ function PlusIcon5({ color }) {
23991
24312
 
23992
24313
  // src/react/ui/push-notifications.tsx
23993
24314
  init_constants();
23994
- import { useEffect as useEffect41, useState as useState51 } from "react";
24315
+ import { useEffect as useEffect41, useState as useState50 } from "react";
23995
24316
  import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
23996
24317
  function PushPrompt({
23997
24318
  theme = defaultTheme,
@@ -24007,8 +24328,8 @@ function PushPrompt({
24007
24328
  autoShow = true,
24008
24329
  showDelay = UI_PROMPT_DELAY_MS
24009
24330
  }) {
24010
- const [isVisible, setIsVisible] = useState51(false);
24011
- const [isAnimatingOut, setIsAnimatingOut] = useState51(false);
24331
+ const [isVisible, setIsVisible] = useState50(false);
24332
+ const [isAnimatingOut, setIsAnimatingOut] = useState50(false);
24012
24333
  const { isSupported, isSubscribed, subscribe, error } = useNotifications();
24013
24334
  const styles2 = baseStyles(theme);
24014
24335
  useEffect41(() => {
@@ -24350,7 +24671,7 @@ function NotificationItem({
24350
24671
  onDelete
24351
24672
  }) {
24352
24673
  const styles2 = baseStyles(theme);
24353
- const [showActions, setShowActions] = useState51(false);
24674
+ const [showActions, setShowActions] = useState50(false);
24354
24675
  const itemStyle = {
24355
24676
  position: "relative",
24356
24677
  display: "flex",
@@ -24593,7 +24914,7 @@ function TrashIcon3({ color }) {
24593
24914
 
24594
24915
  // src/react/ui/referral-card.tsx
24595
24916
  init_constants();
24596
- import { useEffect as useEffect42, useId as useId7, useState as useState52 } from "react";
24917
+ import { useEffect as useEffect42, useId as useId7, useState as useState51 } from "react";
24597
24918
  import { Fragment as Fragment29, jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
24598
24919
  function ReferralCard(props) {
24599
24920
  return /* @__PURE__ */ jsx42(RequireSdk, { services: ["analytics"], componentType: "referral", theme: props.theme, children: /* @__PURE__ */ jsx42(ReferralCardInner, { ...props }) });
@@ -24621,9 +24942,9 @@ function ReferralCardInner({
24621
24942
  } = useReferral();
24622
24943
  const styles2 = baseStyles(theme);
24623
24944
  const linkId = useId7();
24624
- const [copied, setCopied] = useState52(null);
24625
- const [isRegenerating, setIsRegenerating] = useState52(false);
24626
- const [error, setError] = useState52(null);
24945
+ const [copied, setCopied] = useState51(null);
24946
+ const [isRegenerating, setIsRegenerating] = useState51(false);
24947
+ const [error, setError] = useState51(null);
24627
24948
  useEffect42(() => {
24628
24949
  injectGlobalStyles();
24629
24950
  }, []);
@@ -25061,8 +25382,8 @@ function EmailIcon({ size = 24 }) {
25061
25382
 
25062
25383
  // src/react/ui/security-settings.tsx
25063
25384
  init_constants();
25064
- import { useMutation as useMutation3, useQuery as useQuery11, useQueryClient as useQueryClient10 } from "@tanstack/react-query";
25065
- import { useCallback as useCallback37, useEffect as useEffect43, useId as useId8, useState as useState53 } from "react";
25385
+ import { useMutation as useMutation4, useQuery as useQuery12, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
25386
+ import { useCallback as useCallback36, useEffect as useEffect43, useId as useId8, useState as useState52 } from "react";
25066
25387
  import { Fragment as Fragment30, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
25067
25388
  function SecuritySettings({
25068
25389
  theme = defaultTheme,
@@ -25076,26 +25397,26 @@ function SecuritySettings({
25076
25397
  }) {
25077
25398
  const userContext = useUserContext();
25078
25399
  const securityContext = useSecurityContext();
25079
- const queryClient = useQueryClient10();
25400
+ const queryClient = useQueryClient11();
25080
25401
  const styles2 = baseStyles(theme);
25081
25402
  const verifyCodeId = useId8();
25082
25403
  const currentPasswordId = useId8();
25083
25404
  const newPasswordId = useId8();
25084
25405
  const confirmPasswordId = useId8();
25085
- const [error, setError] = useState53(null);
25086
- const [success, setSuccess] = useState53(null);
25087
- const [showSetup2FA, setShowSetup2FA] = useState53(false);
25088
- const [totpSecret, setTotpSecret] = useState53(null);
25089
- const [totpQrCode, setTotpQrCode] = useState53(null);
25090
- const [verifyCode, setVerifyCode] = useState53("");
25091
- const [showPasswordChange, setShowPasswordChange] = useState53(false);
25092
- const [currentPassword, setCurrentPassword] = useState53("");
25093
- const [newPassword, setNewPassword] = useState53("");
25094
- const [confirmPassword, setConfirmPassword] = useState53("");
25406
+ const [error, setError] = useState52(null);
25407
+ const [success, setSuccess] = useState52(null);
25408
+ const [showSetup2FA, setShowSetup2FA] = useState52(false);
25409
+ const [totpSecret, setTotpSecret] = useState52(null);
25410
+ const [totpQrCode, setTotpQrCode] = useState52(null);
25411
+ const [verifyCode, setVerifyCode] = useState52("");
25412
+ const [showPasswordChange, setShowPasswordChange] = useState52(false);
25413
+ const [currentPassword, setCurrentPassword] = useState52("");
25414
+ const [newPassword, setNewPassword] = useState52("");
25415
+ const [confirmPassword, setConfirmPassword] = useState52("");
25095
25416
  useEffect43(() => {
25096
25417
  injectGlobalStyles();
25097
25418
  }, []);
25098
- const twoFactorQuery = useQuery11({
25419
+ const twoFactorQuery = useQuery12({
25099
25420
  queryKey: ["sylphx", "security", "2fa-status"],
25100
25421
  queryFn: async () => {
25101
25422
  const data = await securityContext.getTwoFactorStatus();
@@ -25108,7 +25429,7 @@ function SecuritySettings({
25108
25429
  staleTime: STALE_TIME_STABLE_MS
25109
25430
  // 5 min
25110
25431
  });
25111
- const sessionsQuery = useQuery11({
25432
+ const sessionsQuery = useQuery12({
25112
25433
  queryKey: ["sylphx", "security", "sessions"],
25113
25434
  queryFn: async () => {
25114
25435
  const data = await userContext.getSessions();
@@ -25127,7 +25448,7 @@ function SecuritySettings({
25127
25448
  staleTime: STALE_TIME_FREQUENT_MS
25128
25449
  // 1 min - sessions can change
25129
25450
  });
25130
- const loginHistoryQuery = useQuery11({
25451
+ const loginHistoryQuery = useQuery12({
25131
25452
  queryKey: ["sylphx", "security", "login-history"],
25132
25453
  queryFn: async () => {
25133
25454
  const data = await userContext.getLoginHistory({ limit: 10 });
@@ -25166,7 +25487,7 @@ function SecuritySettings({
25166
25487
  return () => clearTimeout(timer);
25167
25488
  }
25168
25489
  }, [success, error]);
25169
- const setup2FAMutation = useMutation3({
25490
+ const setup2FAMutation = useMutation4({
25170
25491
  mutationFn: () => securityContext.twoFactorSetup(),
25171
25492
  onSuccess: (data) => {
25172
25493
  setTotpSecret(data.secret);
@@ -25179,7 +25500,7 @@ function SecuritySettings({
25179
25500
  onError?.(message);
25180
25501
  }
25181
25502
  });
25182
- const enable2FAMutation = useMutation3({
25503
+ const enable2FAMutation = useMutation4({
25183
25504
  mutationFn: (code) => securityContext.twoFactorVerify(code),
25184
25505
  onSuccess: () => {
25185
25506
  queryClient.setQueryData(["sylphx", "security", "2fa-status"], {
@@ -25197,7 +25518,7 @@ function SecuritySettings({
25197
25518
  onError?.(message);
25198
25519
  }
25199
25520
  });
25200
- const disable2FAMutation = useMutation3({
25521
+ const disable2FAMutation = useMutation4({
25201
25522
  mutationFn: (code) => securityContext.twoFactorDisable(code),
25202
25523
  onSuccess: () => {
25203
25524
  queryClient.setQueryData(["sylphx", "security", "2fa-status"], {
@@ -25212,7 +25533,7 @@ function SecuritySettings({
25212
25533
  onError?.(message);
25213
25534
  }
25214
25535
  });
25215
- const changePasswordMutation = useMutation3({
25536
+ const changePasswordMutation = useMutation4({
25216
25537
  mutationFn: ({ current, newPwd }) => userContext.changePassword(current, newPwd),
25217
25538
  onSuccess: () => {
25218
25539
  setShowPasswordChange(false);
@@ -25228,7 +25549,7 @@ function SecuritySettings({
25228
25549
  onError?.(message);
25229
25550
  }
25230
25551
  });
25231
- const revokeSessionMutation = useMutation3({
25552
+ const revokeSessionMutation = useMutation4({
25232
25553
  mutationFn: (sessionId) => userContext.revokeSession(sessionId),
25233
25554
  onSuccess: (_data, sessionId) => {
25234
25555
  queryClient.setQueryData(
@@ -25244,7 +25565,7 @@ function SecuritySettings({
25244
25565
  onError?.(message);
25245
25566
  }
25246
25567
  });
25247
- const revokeAllSessionsMutation = useMutation3({
25568
+ const revokeAllSessionsMutation = useMutation4({
25248
25569
  mutationFn: () => userContext.revokeAllSessions(),
25249
25570
  onSuccess: () => {
25250
25571
  queryClient.setQueryData(
@@ -25260,10 +25581,10 @@ function SecuritySettings({
25260
25581
  onError?.(message);
25261
25582
  }
25262
25583
  });
25263
- const handleStart2FASetup = useCallback37(() => {
25584
+ const handleStart2FASetup = useCallback36(() => {
25264
25585
  setup2FAMutation.mutate();
25265
25586
  }, [setup2FAMutation]);
25266
- const handleEnable2FA = useCallback37(
25587
+ const handleEnable2FA = useCallback36(
25267
25588
  (e2) => {
25268
25589
  e2.preventDefault();
25269
25590
  if (!verifyCode || verifyCode.length !== 6) {
@@ -25274,12 +25595,12 @@ function SecuritySettings({
25274
25595
  },
25275
25596
  [verifyCode, enable2FAMutation]
25276
25597
  );
25277
- const handleDisable2FA = useCallback37(() => {
25598
+ const handleDisable2FA = useCallback36(() => {
25278
25599
  const code = prompt("Enter your 2FA code to disable two-factor authentication:");
25279
25600
  if (!code) return;
25280
25601
  disable2FAMutation.mutate(code);
25281
25602
  }, [disable2FAMutation]);
25282
- const handlePasswordChange = useCallback37(
25603
+ const handlePasswordChange = useCallback36(
25283
25604
  (e2) => {
25284
25605
  e2.preventDefault();
25285
25606
  if (newPassword !== confirmPassword) {
@@ -25297,13 +25618,13 @@ function SecuritySettings({
25297
25618
  },
25298
25619
  [newPassword, confirmPassword, currentPassword, changePasswordMutation]
25299
25620
  );
25300
- const handleRevokeSession = useCallback37(
25621
+ const handleRevokeSession = useCallback36(
25301
25622
  (sessionId) => {
25302
25623
  revokeSessionMutation.mutate(sessionId);
25303
25624
  },
25304
25625
  [revokeSessionMutation]
25305
25626
  );
25306
- const handleRevokeAllSessions = useCallback37(() => {
25627
+ const handleRevokeAllSessions = useCallback36(() => {
25307
25628
  if (!confirm("Are you sure you want to sign out all other devices?")) {
25308
25629
  return;
25309
25630
  }
@@ -25846,8 +26167,8 @@ function DeviceIcon({ device, theme }) {
25846
26167
 
25847
26168
  // src/react/ui/subscriber-preferences.tsx
25848
26169
  init_constants();
25849
- import { useQuery as useQuery12, useQueryClient as useQueryClient11 } from "@tanstack/react-query";
25850
- import { useEffect as useEffect44, useState as useState54 } from "react";
26170
+ import { useQuery as useQuery13, useQueryClient as useQueryClient12 } from "@tanstack/react-query";
26171
+ import { useEffect as useEffect44, useState as useState53 } from "react";
25851
26172
  import { Fragment as Fragment31, jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
25852
26173
  function SubscriberPreferences({
25853
26174
  theme = defaultTheme,
@@ -25864,17 +26185,17 @@ function SubscriberPreferences({
25864
26185
  unsubscribeButtonText = "Unsubscribe from All"
25865
26186
  }) {
25866
26187
  const { getPreferences, updatePreferences } = useNewsletter();
25867
- const queryClient = useQueryClient11();
26188
+ const queryClient = useQueryClient12();
25868
26189
  const styles2 = baseStyles(theme);
25869
- const [selectedPreferences, setSelectedPreferences] = useState54([]);
25870
- const [saving, setSaving] = useState54(false);
25871
- const [unsubscribing, setUnsubscribing] = useState54(false);
25872
- const [error, setError] = useState54(null);
25873
- const [success, setSuccess] = useState54(null);
26190
+ const [selectedPreferences, setSelectedPreferences] = useState53([]);
26191
+ const [saving, setSaving] = useState53(false);
26192
+ const [unsubscribing, setUnsubscribing] = useState53(false);
26193
+ const [error, setError] = useState53(null);
26194
+ const [success, setSuccess] = useState53(null);
25874
26195
  useEffect44(() => {
25875
26196
  injectGlobalStyles();
25876
26197
  }, []);
25877
- const prefsQuery = useQuery12({
26198
+ const prefsQuery = useQuery13({
25878
26199
  queryKey: ["sylphx", "newsletter", "preferences", email],
25879
26200
  queryFn: async () => {
25880
26201
  const prefs = await getPreferences(email);
@@ -26085,7 +26406,7 @@ function SubscriberPreferences({
26085
26406
 
26086
26407
  // src/react/ui/unsubscribe-confirm.tsx
26087
26408
  init_constants();
26088
- import { useEffect as useEffect45, useId as useId9, useState as useState55 } from "react";
26409
+ import { useEffect as useEffect45, useId as useId9, useState as useState54 } from "react";
26089
26410
  import { Fragment as Fragment32, jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
26090
26411
  var DEFAULT_REASONS = [
26091
26412
  { id: "too_many", label: "Too many emails" },
@@ -26112,9 +26433,9 @@ function UnsubscribeConfirm({
26112
26433
  const { unsubscribe, subscribe } = useNewsletter();
26113
26434
  const styles2 = baseStyles(theme);
26114
26435
  const reasonId = useId9();
26115
- const [status, setStatus] = useState55(() => token ? "pending" : "missing_token");
26116
- const [selectedReason, setSelectedReason] = useState55("");
26117
- const [error, setError] = useState55(null);
26436
+ const [status, setStatus] = useState54(() => token ? "pending" : "missing_token");
26437
+ const [selectedReason, setSelectedReason] = useState54("");
26438
+ const [error, setError] = useState54(null);
26118
26439
  useEffect45(() => {
26119
26440
  injectGlobalStyles();
26120
26441
  }, []);
@@ -26474,7 +26795,7 @@ function UnsubscribeConfirm({
26474
26795
 
26475
26796
  // src/react/ui/user-profile.tsx
26476
26797
  init_constants();
26477
- import { useCallback as useCallback38, useEffect as useEffect46, useId as useId10, useRef as useRef18, useState as useState56 } from "react";
26798
+ import { useCallback as useCallback37, useEffect as useEffect46, useId as useId10, useRef as useRef16, useState as useState55 } from "react";
26478
26799
  import { Fragment as Fragment33, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
26479
26800
  function UserProfile(props) {
26480
26801
  return /* @__PURE__ */ jsx46(RequireSdk, { services: ["auth", "storage"], componentType: "user", theme: props.theme, children: /* @__PURE__ */ jsx46(UserProfileInner, { ...props }) });
@@ -26492,16 +26813,16 @@ function UserProfileInner({
26492
26813
  }) {
26493
26814
  const { user, isLoading: isUserLoading, refresh: refreshUser } = useUser();
26494
26815
  const userContext = useUserContext();
26495
- const { uploadAvatar, isUploading: isUploadingAvatar } = useStorage();
26816
+ const { upload: uploadFile, isUploading: isUploadingAvatar } = useStorage();
26496
26817
  const styles2 = baseStyles(theme);
26497
26818
  const nameId = useId10();
26498
26819
  const emailId = useId10();
26499
- const [activeSection, setActiveSection] = useState56(sections[0]);
26500
- const [form, setForm] = useState56({ name: "", image: "" });
26501
- const [error, setError] = useState56(null);
26502
- const [success, setSuccess] = useState56(null);
26503
- const [isLoading, setIsLoading] = useState56(false);
26504
- const fileInputRef = useRef18(null);
26820
+ const [activeSection, setActiveSection] = useState55(sections[0]);
26821
+ const [form, setForm] = useState55({ name: "", image: "" });
26822
+ const [error, setError] = useState55(null);
26823
+ const [success, setSuccess] = useState55(null);
26824
+ const [isLoading, setIsLoading] = useState55(false);
26825
+ const fileInputRef = useRef16(null);
26505
26826
  useEffect46(() => {
26506
26827
  injectGlobalStyles();
26507
26828
  }, []);
@@ -26522,7 +26843,7 @@ function UserProfileInner({
26522
26843
  return () => clearTimeout(timer);
26523
26844
  }
26524
26845
  }, [success, error]);
26525
- const handleProfileUpdate = useCallback38(
26846
+ const handleProfileUpdate = useCallback37(
26526
26847
  async (e2) => {
26527
26848
  e2.preventDefault();
26528
26849
  setIsLoading(true);
@@ -26546,11 +26867,12 @@ function UserProfileInner({
26546
26867
  },
26547
26868
  [form, userContext, refreshUser, onSuccess, onError]
26548
26869
  );
26549
- const handleAvatarUpload = useCallback38(
26870
+ const handleAvatarUpload = useCallback37(
26550
26871
  async (file) => {
26551
26872
  setError(null);
26552
26873
  try {
26553
- const imageUrl = await uploadAvatar(file);
26874
+ const result = await uploadFile(file, { folder: "avatars" });
26875
+ const imageUrl = result.url ?? "";
26554
26876
  setForm((prev) => ({ ...prev, image: imageUrl }));
26555
26877
  setSuccess("Avatar uploaded");
26556
26878
  } catch (err) {
@@ -26559,7 +26881,7 @@ function UserProfileInner({
26559
26881
  onError?.(message);
26560
26882
  }
26561
26883
  },
26562
- [uploadAvatar, onError]
26884
+ [uploadFile, onError]
26563
26885
  );
26564
26886
  const handleFileChange = (e2) => {
26565
26887
  const file = e2.target.files?.[0];
@@ -26849,7 +27171,7 @@ function CloseIcon6({ color }) {
26849
27171
  }
26850
27172
 
26851
27173
  // src/react/ui/webhook-manager.tsx
26852
- import { useEffect as useEffect47, useId as useId11, useState as useState57 } from "react";
27174
+ import { useEffect as useEffect47, useId as useId11, useState as useState56 } from "react";
26853
27175
  import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
26854
27176
  var DEFAULT_EVENTS = [
26855
27177
  "user.created",
@@ -26876,13 +27198,13 @@ function WebhookManager({
26876
27198
  emptyMessage = "No webhooks configured"
26877
27199
  }) {
26878
27200
  const urlId = useId11();
26879
- const [showCreate, setShowCreate] = useState57(false);
26880
- const [url, setUrl] = useState57("");
26881
- const [selectedEvents, setSelectedEvents] = useState57([]);
26882
- const [isCreating, setIsCreating] = useState57(false);
26883
- const [error, setError] = useState57(null);
26884
- const [testingId, setTestingId] = useState57(null);
26885
- const [deletingId, setDeletingId] = useState57(null);
27201
+ const [showCreate, setShowCreate] = useState56(false);
27202
+ const [url, setUrl] = useState56("");
27203
+ const [selectedEvents, setSelectedEvents] = useState56([]);
27204
+ const [isCreating, setIsCreating] = useState56(false);
27205
+ const [error, setError] = useState56(null);
27206
+ const [testingId, setTestingId] = useState56(null);
27207
+ const [deletingId, setDeletingId] = useState56(null);
26886
27208
  const styles2 = baseStyles(theme);
26887
27209
  useEffect47(() => {
26888
27210
  injectGlobalStyles();
@@ -27272,7 +27594,7 @@ function WebhookDeliveryLog({
27272
27594
  emptyMessage = "No deliveries yet",
27273
27595
  maxDeliveries = 50
27274
27596
  }) {
27275
- const [expandedId, setExpandedId] = useState57(null);
27597
+ const [expandedId, setExpandedId] = useState56(null);
27276
27598
  const styles2 = baseStyles(theme);
27277
27599
  useEffect47(() => {
27278
27600
  injectGlobalStyles();
@@ -33169,7 +33491,7 @@ function isWebVitalsInitialized() {
33169
33491
 
33170
33492
  // src/react/hooks/use-session-replay.tsx
33171
33493
  init_constants();
33172
- import { useCallback as useCallback39, useEffect as useEffect48, useRef as useRef19, useState as useState58 } from "react";
33494
+ import { useCallback as useCallback38, useEffect as useEffect48, useRef as useRef17, useState as useState57 } from "react";
33173
33495
  import { jsx as jsx48 } from "react/jsx-runtime";
33174
33496
  function useSessionReplay(options = {}) {
33175
33497
  const {
@@ -33182,14 +33504,14 @@ function useSessionReplay(options = {}) {
33182
33504
  api,
33183
33505
  ...recorderConfig
33184
33506
  } = options;
33185
- const apiRef = useRef19(api);
33507
+ const apiRef = useRef17(api);
33186
33508
  useEffect48(() => {
33187
33509
  apiRef.current = api;
33188
33510
  }, [api]);
33189
- const recorderRef = useRef19(null);
33190
- const currentSessionIdRef = useRef19(null);
33191
- const [sessionId, setSessionId] = useState58(null);
33192
- const [status, setStatus] = useState58({
33511
+ const recorderRef = useRef17(null);
33512
+ const currentSessionIdRef = useRef17(null);
33513
+ const [sessionId, setSessionId] = useState57(null);
33514
+ const [status, setStatus] = useState57({
33193
33515
  state: "idle",
33194
33516
  sessionId: null,
33195
33517
  eventCount: 0,
@@ -33242,7 +33564,7 @@ function useSessionReplay(options = {}) {
33242
33564
  });
33243
33565
  }
33244
33566
  }, [userId]);
33245
- const start = useCallback39(() => {
33567
+ const start = useCallback38(() => {
33246
33568
  if (!recorderRef.current) {
33247
33569
  throw new Error("Recorder not initialized");
33248
33570
  }
@@ -33250,29 +33572,29 @@ function useSessionReplay(options = {}) {
33250
33572
  setSessionId(id);
33251
33573
  return id;
33252
33574
  }, []);
33253
- const pause = useCallback39(() => {
33575
+ const pause = useCallback38(() => {
33254
33576
  recorderRef.current?.pause();
33255
33577
  }, []);
33256
- const resume = useCallback39(() => {
33578
+ const resume = useCallback38(() => {
33257
33579
  recorderRef.current?.resume();
33258
33580
  }, []);
33259
- const stop = useCallback39(async () => {
33581
+ const stop = useCallback38(async () => {
33260
33582
  await recorderRef.current?.stop();
33261
33583
  setSessionId(null);
33262
33584
  }, []);
33263
- const markError = useCallback39(
33585
+ const markError = useCallback38(
33264
33586
  (errorId, error, metadata) => {
33265
33587
  recorderRef.current?.markError(errorId, error, metadata);
33266
33588
  },
33267
33589
  []
33268
33590
  );
33269
- const markNavigation = useCallback39((from, to) => {
33591
+ const markNavigation = useCallback38((from, to) => {
33270
33592
  recorderRef.current?.markNavigation(from, to);
33271
33593
  }, []);
33272
- const markConversion = useCallback39((name, value) => {
33594
+ const markConversion = useCallback38((name, value) => {
33273
33595
  recorderRef.current?.markConversion(name, value);
33274
33596
  }, []);
33275
- const addMarker = useCallback39((type, payload) => {
33597
+ const addMarker = useCallback38((type, payload) => {
33276
33598
  recorderRef.current?.addMarker(type, payload);
33277
33599
  }, []);
33278
33600
  return {
@@ -33321,13 +33643,13 @@ function createDefaultUploadHandler(endpoint) {
33321
33643
  };
33322
33644
  }
33323
33645
  function useSessionReplayErrorMarker() {
33324
- const recorderRef = useRef19(null);
33646
+ const recorderRef = useRef17(null);
33325
33647
  useEffect48(() => {
33326
33648
  if (typeof window !== "undefined" && window.__sylphxRecorder) {
33327
33649
  recorderRef.current = window.__sylphxRecorder;
33328
33650
  }
33329
33651
  }, []);
33330
- const markError = useCallback39((error, errorInfo) => {
33652
+ const markError = useCallback38((error, errorInfo) => {
33331
33653
  const errorId = `err_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
33332
33654
  recorderRef.current?.markError(errorId, error, {
33333
33655
  componentStack: errorInfo?.componentStack?.slice(0, STACK_TRACE_MAX_LENGTH)
@@ -33346,11 +33668,11 @@ function withSessionReplay(Component2, options) {
33346
33668
  }
33347
33669
 
33348
33670
  // src/react/hooks/use-web-vitals.ts
33349
- import { useCallback as useCallback40, useEffect as useEffect49, useRef as useRef20, useState as useState59 } from "react";
33671
+ import { useCallback as useCallback39, useEffect as useEffect49, useRef as useRef18, useState as useState58 } from "react";
33350
33672
  function useWebVitals(options = {}) {
33351
33673
  const { autoInit = true, onReport, ...config2 } = options;
33352
- const [report, setReport] = useState59(null);
33353
- const initRef = useRef20(false);
33674
+ const [report, setReport] = useState58(null);
33675
+ const initRef = useRef18(false);
33354
33676
  useEffect49(() => {
33355
33677
  if (!autoInit || initRef.current) return;
33356
33678
  if (typeof window === "undefined") return;
@@ -33366,10 +33688,10 @@ function useWebVitals(options = {}) {
33366
33688
  return () => {
33367
33689
  };
33368
33690
  }, [autoInit, onReport]);
33369
- const refresh = useCallback40(() => {
33691
+ const refresh = useCallback39(() => {
33370
33692
  setReport(getWebVitalsReport());
33371
33693
  }, []);
33372
- const reset = useCallback40(() => {
33694
+ const reset = useCallback39(() => {
33373
33695
  resetWebVitals();
33374
33696
  setReport(null);
33375
33697
  initRef.current = false;
@@ -33413,7 +33735,7 @@ function useWebVital({ metric }) {
33413
33735
  }
33414
33736
  function useWebVitalsAnalytics(options) {
33415
33737
  const { track, eventPrefix = "web_vital", reportOnHide = true } = options;
33416
- const reportedRef = useRef20(false);
33738
+ const reportedRef = useRef18(false);
33417
33739
  const webVitals = useWebVitals({
33418
33740
  onReport: (metric) => {
33419
33741
  track(`${eventPrefix}_${metric.name.toLowerCase()}`, {
@@ -33456,7 +33778,7 @@ function useWebVitalsAnalytics(options) {
33456
33778
 
33457
33779
  // src/react/hooks/use-error-tracking.ts
33458
33780
  init_constants();
33459
- import { useCallback as useCallback41, useEffect as useEffect50, useRef as useRef21 } from "react";
33781
+ import { useCallback as useCallback40, useEffect as useEffect50, useRef as useRef19 } from "react";
33460
33782
  function useEnhancedErrorTracking(options = {}) {
33461
33783
  const {
33462
33784
  attachReplay = true,
@@ -33466,8 +33788,8 @@ function useEnhancedErrorTracking(options = {}) {
33466
33788
  autoInit = true,
33467
33789
  ...trackerConfig
33468
33790
  } = options;
33469
- const trackerRef = useRef21(null);
33470
- const replaySessionIdRef = useRef21(null);
33791
+ const trackerRef = useRef19(null);
33792
+ const replaySessionIdRef = useRef19(null);
33471
33793
  useEffect50(() => {
33472
33794
  if (typeof window === "undefined") return;
33473
33795
  const tracker = getTracker({
@@ -33511,7 +33833,7 @@ function useEnhancedErrorTracking(options = {}) {
33511
33833
  const interval = setInterval(checkReplaySession, SESSION_REPLAY_STATUS_CHECK_MS);
33512
33834
  return () => clearInterval(interval);
33513
33835
  }, [attachReplay]);
33514
- const captureException = useCallback41(
33836
+ const captureException = useCallback40(
33515
33837
  async (error, opts = {}) => {
33516
33838
  if (!trackerRef.current) {
33517
33839
  return { eventId: "" };
@@ -33539,7 +33861,7 @@ function useEnhancedErrorTracking(options = {}) {
33539
33861
  },
33540
33862
  [attachReplay, onCapture]
33541
33863
  );
33542
- const captureMessage = useCallback41(
33864
+ const captureMessage = useCallback40(
33543
33865
  async (message, opts = {}) => {
33544
33866
  if (!trackerRef.current) {
33545
33867
  return { eventId: "" };
@@ -33550,20 +33872,20 @@ function useEnhancedErrorTracking(options = {}) {
33550
33872
  },
33551
33873
  [onCapture]
33552
33874
  );
33553
- const addBreadcrumb2 = useCallback41((breadcrumb) => {
33875
+ const addBreadcrumb2 = useCallback40((breadcrumb) => {
33554
33876
  trackerRef.current?.addBreadcrumb(breadcrumb);
33555
33877
  }, []);
33556
- const setUser = useCallback41((user) => {
33878
+ const setUser = useCallback40((user) => {
33557
33879
  trackerRef.current?.setUser(user);
33558
33880
  }, []);
33559
- const clearUser = useCallback41(() => {
33881
+ const clearUser = useCallback40(() => {
33560
33882
  trackerRef.current?.clearUser();
33561
33883
  }, []);
33562
- const linkReplaySession = useCallback41((sessionId) => {
33884
+ const linkReplaySession = useCallback40((sessionId) => {
33563
33885
  replaySessionIdRef.current = sessionId;
33564
33886
  trackerRef.current?.setSessionReplayId(sessionId);
33565
33887
  }, []);
33566
- const getReplaySessionId = useCallback41(() => {
33888
+ const getReplaySessionId = useCallback40(() => {
33567
33889
  return replaySessionIdRef.current;
33568
33890
  }, []);
33569
33891
  return {
@@ -34765,10 +35087,10 @@ var DEFAULT_FLAGS_CONFIG = {
34765
35087
  };
34766
35088
 
34767
35089
  // src/react/hooks/use-flag.ts
34768
- import { useCallback as useCallback43, useContext as useContext19, useEffect as useEffect52, useMemo as useMemo12, useRef as useRef23, useState as useState61 } from "react";
35090
+ import { useCallback as useCallback42, useContext as useContext20, useEffect as useEffect52, useMemo as useMemo13, useRef as useRef21, useState as useState60 } from "react";
34769
35091
 
34770
35092
  // src/react/hooks/use-flags.tsx
34771
- import { createContext as createContext7, useCallback as useCallback42, useContext as useContext18, useEffect as useEffect51, useMemo as useMemo11, useRef as useRef22, useState as useState60 } from "react";
35093
+ import { createContext as createContext7, useCallback as useCallback41, useContext as useContext19, useEffect as useEffect51, useMemo as useMemo12, useRef as useRef20, useState as useState59 } from "react";
34772
35094
  import { jsx as jsx49 } from "react/jsx-runtime";
34773
35095
  var FeatureFlagsContext = createContext7(null);
34774
35096
  function FeatureFlagsProvider({
@@ -34780,14 +35102,14 @@ function FeatureFlagsProvider({
34780
35102
  onReady,
34781
35103
  onError
34782
35104
  }) {
34783
- const [isReady, setIsReady] = useState60(!!initialFlags?.length);
34784
- const [isLoading, setIsLoading] = useState60(!initialFlags?.length);
34785
- const [error, setError] = useState60(null);
34786
- const [updateVersion, setUpdateVersion] = useState60(0);
34787
- const evaluatorRef = useRef22(null);
34788
- const streamRef = useRef22(null);
34789
- const experimentsRef = useRef22(null);
34790
- const handleStreamEvent = useCallback42(
35105
+ const [isReady, setIsReady] = useState59(!!initialFlags?.length);
35106
+ const [isLoading, setIsLoading] = useState59(!initialFlags?.length);
35107
+ const [error, setError] = useState59(null);
35108
+ const [updateVersion, setUpdateVersion] = useState59(0);
35109
+ const evaluatorRef = useRef20(null);
35110
+ const streamRef = useRef20(null);
35111
+ const experimentsRef = useRef20(null);
35112
+ const handleStreamEvent = useCallback41(
34791
35113
  (event) => {
34792
35114
  switch (event.type) {
34793
35115
  case "ready":
@@ -34859,7 +35181,7 @@ function FeatureFlagsProvider({
34859
35181
  evaluatorRef.current.setContext(context);
34860
35182
  }
34861
35183
  }, [context]);
34862
- const value = useMemo11(
35184
+ const value = useMemo12(
34863
35185
  () => ({
34864
35186
  evaluator: evaluatorRef.current,
34865
35187
  stream: streamRef.current,
@@ -34878,53 +35200,53 @@ function FeatureFlagsProvider({
34878
35200
  return /* @__PURE__ */ jsx49(FeatureFlagsContext.Provider, { value, children });
34879
35201
  }
34880
35202
  function useFeatureFlags2() {
34881
- const ctx = useContext18(FeatureFlagsContext);
35203
+ const ctx = useContext19(FeatureFlagsContext);
34882
35204
  if (!ctx) {
34883
35205
  throw new Error("useFeatureFlags must be used within a FeatureFlagsProvider");
34884
35206
  }
34885
35207
  const { evaluator, isReady, isLoading, error, flags, updateVersion } = ctx;
34886
- const isEnabled = useCallback42(
35208
+ const isEnabled = useCallback41(
34887
35209
  (flagKey, defaultValue = false) => {
34888
35210
  void updateVersion;
34889
35211
  return evaluator.isEnabled(flagKey, defaultValue);
34890
35212
  },
34891
35213
  [evaluator, updateVersion]
34892
35214
  );
34893
- const getString = useCallback42(
35215
+ const getString = useCallback41(
34894
35216
  (flagKey, defaultValue = "") => {
34895
35217
  void updateVersion;
34896
35218
  return evaluator.getString(flagKey, defaultValue);
34897
35219
  },
34898
35220
  [evaluator, updateVersion]
34899
35221
  );
34900
- const getNumber = useCallback42(
35222
+ const getNumber = useCallback41(
34901
35223
  (flagKey, defaultValue = 0) => {
34902
35224
  void updateVersion;
34903
35225
  return evaluator.getNumber(flagKey, defaultValue);
34904
35226
  },
34905
35227
  [evaluator, updateVersion]
34906
35228
  );
34907
- const getJSON = useCallback42(
35229
+ const getJSON = useCallback41(
34908
35230
  (flagKey, defaultValue) => {
34909
35231
  void updateVersion;
34910
35232
  return evaluator.getJSON(flagKey, defaultValue);
34911
35233
  },
34912
35234
  [evaluator, updateVersion]
34913
35235
  );
34914
- const evaluate = useCallback42(
35236
+ const evaluate = useCallback41(
34915
35237
  (flagKey, defaultValue, contextOverride) => {
34916
35238
  void updateVersion;
34917
35239
  return evaluator.evaluate(flagKey, defaultValue, contextOverride);
34918
35240
  },
34919
35241
  [evaluator, updateVersion]
34920
35242
  );
34921
- const setContext = useCallback42(
35243
+ const setContext = useCallback41(
34922
35244
  (context) => {
34923
35245
  evaluator.setContext(context);
34924
35246
  },
34925
35247
  [evaluator]
34926
35248
  );
34927
- const updateContext = useCallback42(
35249
+ const updateContext = useCallback41(
34928
35250
  (partial) => {
34929
35251
  evaluator.updateContext(partial);
34930
35252
  },
@@ -34946,7 +35268,7 @@ function useFeatureFlags2() {
34946
35268
  }
34947
35269
  function useFlag(flagKey, defaultValue = false) {
34948
35270
  const { isEnabled, updateVersion } = useFeatureFlagsContext();
34949
- return useMemo11(
35271
+ return useMemo12(
34950
35272
  () => isEnabled(flagKey, defaultValue),
34951
35273
  // eslint-disable-next-line react-hooks/exhaustive-deps
34952
35274
  [flagKey, defaultValue, isEnabled]
@@ -34954,7 +35276,7 @@ function useFlag(flagKey, defaultValue = false) {
34954
35276
  }
34955
35277
  function useFlagString(flagKey, defaultValue = "") {
34956
35278
  const { getString, updateVersion } = useFeatureFlagsContext();
34957
- return useMemo11(
35279
+ return useMemo12(
34958
35280
  () => getString(flagKey, defaultValue),
34959
35281
  // eslint-disable-next-line react-hooks/exhaustive-deps
34960
35282
  [flagKey, defaultValue, getString]
@@ -34962,7 +35284,7 @@ function useFlagString(flagKey, defaultValue = "") {
34962
35284
  }
34963
35285
  function useFlagNumber(flagKey, defaultValue = 0) {
34964
35286
  const { getNumber, updateVersion } = useFeatureFlagsContext();
34965
- return useMemo11(
35287
+ return useMemo12(
34966
35288
  () => getNumber(flagKey, defaultValue),
34967
35289
  // eslint-disable-next-line react-hooks/exhaustive-deps
34968
35290
  [flagKey, defaultValue, getNumber]
@@ -34970,7 +35292,7 @@ function useFlagNumber(flagKey, defaultValue = 0) {
34970
35292
  }
34971
35293
  function useFlagJSON(flagKey, defaultValue) {
34972
35294
  const { getJSON, updateVersion } = useFeatureFlagsContext();
34973
- return useMemo11(
35295
+ return useMemo12(
34974
35296
  () => getJSON(flagKey, defaultValue),
34975
35297
  // eslint-disable-next-line react-hooks/exhaustive-deps
34976
35298
  [flagKey, defaultValue, getJSON]
@@ -34978,19 +35300,19 @@ function useFlagJSON(flagKey, defaultValue) {
34978
35300
  }
34979
35301
  function useFlagEvaluation(flagKey, defaultValue, contextOverride) {
34980
35302
  const { evaluate, updateVersion } = useFeatureFlagsContext();
34981
- return useMemo11(
35303
+ return useMemo12(
34982
35304
  () => evaluate(flagKey, defaultValue, contextOverride),
34983
35305
  // eslint-disable-next-line react-hooks/exhaustive-deps
34984
35306
  [flagKey, defaultValue, contextOverride, evaluate]
34985
35307
  );
34986
35308
  }
34987
35309
  function useExperiment(experimentKey) {
34988
- const ctx = useContext18(FeatureFlagsContext);
35310
+ const ctx = useContext19(FeatureFlagsContext);
34989
35311
  if (!ctx) {
34990
35312
  throw new Error("useExperiment must be used within a FeatureFlagsProvider");
34991
35313
  }
34992
35314
  const { experiments, updateVersion } = ctx;
34993
- return useMemo11(() => {
35315
+ return useMemo12(() => {
34994
35316
  const result = experiments.getVariant(experimentKey);
34995
35317
  return {
34996
35318
  variant: result.variant,
@@ -35008,7 +35330,7 @@ function useIsInTreatment(experimentKey) {
35008
35330
  return inExperiment && variant !== "control";
35009
35331
  }
35010
35332
  function useFeatureFlagsContext() {
35011
- const ctx = useContext18(FeatureFlagsContext);
35333
+ const ctx = useContext19(FeatureFlagsContext);
35012
35334
  if (!ctx) {
35013
35335
  throw new Error("Feature flags hooks must be used within a FeatureFlagsProvider");
35014
35336
  }
@@ -35023,7 +35345,7 @@ function useFeatureFlagsContext() {
35023
35345
  };
35024
35346
  }
35025
35347
  function useFlagsReady() {
35026
- const ctx = useContext18(FeatureFlagsContext);
35348
+ const ctx = useContext19(FeatureFlagsContext);
35027
35349
  if (!ctx) {
35028
35350
  return { isReady: false, isLoading: true, error: null };
35029
35351
  }
@@ -35043,22 +35365,22 @@ function useFlagStatus(key, options) {
35043
35365
  pollInterval = DEFAULT_POLL_INTERVAL_MS2,
35044
35366
  context: contextOverride
35045
35367
  } = options ?? {};
35046
- const ctx = useContext19(FeatureFlagsContext);
35047
- const [enabled, setEnabled] = useState61(false);
35048
- const [loading, setLoading] = useState61(!ctx?.isReady);
35049
- const [error, setError] = useState61(null);
35050
- const mountedRef = useRef23(true);
35051
- const evalContext = useMemo12(() => {
35368
+ const ctx = useContext20(FeatureFlagsContext);
35369
+ const [enabled, setEnabled] = useState60(false);
35370
+ const [loading, setLoading] = useState60(!ctx?.isReady);
35371
+ const [error, setError] = useState60(null);
35372
+ const mountedRef = useRef21(true);
35373
+ const evalContext = useMemo13(() => {
35052
35374
  if (contextOverride) return contextOverride;
35053
35375
  if (userId || attributes) return { userId, ...attributes };
35054
35376
  return void 0;
35055
35377
  }, [contextOverride, userId, attributes]);
35056
- const evaluateLocally = useCallback43(() => {
35378
+ const evaluateLocally = useCallback42(() => {
35057
35379
  if (!ctx?.evaluator) return false;
35058
35380
  const result = ctx.evaluator.evaluate(key, false, evalContext);
35059
35381
  return result.value;
35060
35382
  }, [ctx, key, evalContext]);
35061
- const refetch = useCallback43(async () => {
35383
+ const refetch = useCallback42(async () => {
35062
35384
  if (!mountedRef.current) return;
35063
35385
  setError(null);
35064
35386
  try {
@@ -35857,23 +36179,24 @@ var mixpanelHandler = {
35857
36179
  const { token, debug } = config2;
35858
36180
  ((f2, b2) => {
35859
36181
  if (!b2) return;
35860
- const c2 = {};
35861
- c2._i = [];
35862
- c2.init = (e2, f3) => {
35863
- c2._i.push([e2, f3]);
35864
- };
35865
- c2.track = (...args) => {
35866
- c2._i[0]?.[2]?.track?.(...args);
35867
- };
35868
- c2.identify = (...args) => {
35869
- c2._i[0]?.[2]?.identify?.(...args);
35870
- };
35871
- c2.people = {
35872
- // biome-ignore lint/suspicious/noExplicitAny: Mixpanel SDK vendor snippet — matches Mixpanel's own typings
35873
- set: (...args) => {
35874
- c2._i[0]?.[2]?.people?.set?.(...args);
36182
+ const c2 = {
36183
+ _i: [],
36184
+ init: (token2, options = {}) => {
36185
+ c2._i.push([token2, options]);
36186
+ },
36187
+ track: (...args) => {
36188
+ c2._i[0]?.[2]?.track?.(String(args[0] ?? ""), args[1]);
36189
+ },
36190
+ identify: (...args) => {
36191
+ c2._i[0]?.[2]?.identify?.(String(args[0] ?? ""));
36192
+ },
36193
+ people: {
36194
+ set: (...args) => {
36195
+ c2._i[0]?.[2]?.people?.set?.(args[0]);
36196
+ }
35875
36197
  }
35876
36198
  };
36199
+ c2._i = [];
35877
36200
  const a2 = b2.createElement("script");
35878
36201
  a2.type = "text/javascript";
35879
36202
  a2.async = true;
@@ -35933,14 +36256,16 @@ var segmentHandler = {
35933
36256
  "setAnonymousId",
35934
36257
  "addDestinationMiddleware"
35935
36258
  ];
35936
- analytics.factory = // biome-ignore lint/suspicious/noExplicitAny: Segment SDK vendor snippet — returns a stub function that matches any Segment analytics method signature
35937
- (e2) => (...args) => {
35938
- args.unshift(e2);
35939
- analytics.push(args);
35940
- return analytics;
36259
+ analytics.factory = (method) => {
36260
+ return (...args) => {
36261
+ args.unshift(method);
36262
+ analytics.push(args);
36263
+ return analytics;
36264
+ };
35941
36265
  };
35942
36266
  for (let e2 = 0; e2 < analytics.methods.length; e2++) {
35943
36267
  const key = analytics.methods[e2];
36268
+ if (!key) continue;
35944
36269
  analytics[key] = analytics.factory(key);
35945
36270
  }
35946
36271
  analytics.load = (key, e2) => {
@@ -35972,7 +36297,24 @@ var posthogHandler = {
35972
36297
  const { apiKey, apiHost = "https://us.i.posthog.com" } = config2;
35973
36298
  ((t2, e2) => {
35974
36299
  if (!e2) return;
35975
- const o2 = {};
36300
+ const o2 = {
36301
+ __load_queue: [],
36302
+ _i: [],
36303
+ people: {
36304
+ set: (...args) => {
36305
+ o2.__load_queue.push(["people.set", args]);
36306
+ }
36307
+ },
36308
+ init: (apiKey2, config3) => {
36309
+ o2._i.push([apiKey2, config3]);
36310
+ const r2 = e2.createElement("script");
36311
+ r2.type = "text/javascript";
36312
+ r2.async = true;
36313
+ r2.src = "https://us-assets.i.posthog.com/static/array.js";
36314
+ const s2 = e2.getElementsByTagName("script")[0];
36315
+ s2.parentNode?.insertBefore(r2, s2);
36316
+ }
36317
+ };
35976
36318
  let n2;
35977
36319
  const p2 = [
35978
36320
  "snapshot",
@@ -35998,27 +36340,10 @@ var posthogHandler = {
35998
36340
  for (n2 of p2) {
35999
36341
  o2[n2] = /* @__PURE__ */ ((n3) => (...args) => {
36000
36342
  if (!o2.__loaded) {
36001
- o2.__load_queue = o2.__load_queue || [];
36002
36343
  o2.__load_queue.push([n3, args]);
36003
36344
  }
36004
36345
  })(n2);
36005
36346
  }
36006
- o2.people = {
36007
- // biome-ignore lint/suspicious/noExplicitAny: PostHog SDK vendor snippet — matches PostHog's own typings
36008
- set: (...args) => {
36009
- o2.__load_queue.push(["people.set", args]);
36010
- }
36011
- };
36012
- o2._i = [];
36013
- o2.init = (apiKey2, config3) => {
36014
- o2._i.push([apiKey2, config3]);
36015
- const r2 = e2.createElement("script");
36016
- r2.type = "text/javascript";
36017
- r2.async = true;
36018
- r2.src = "https://us-assets.i.posthog.com/static/array.js";
36019
- const s2 = e2.getElementsByTagName("script")[0];
36020
- s2.parentNode?.insertBefore(r2, s2);
36021
- };
36022
36347
  t2.posthog = o2;
36023
36348
  })(window, document);
36024
36349
  window.posthog?.init(apiKey, { api_host: apiHost });
@@ -36038,25 +36363,26 @@ var amplitudeHandler = {
36038
36363
  const { apiKey, serverUrl } = config2;
36039
36364
  ((e2, t2) => {
36040
36365
  if (!t2) return;
36041
- const r2 = {};
36042
- r2._q = [];
36043
- r2.track = (...args) => {
36044
- r2._q.push(["track", args]);
36045
- };
36046
- r2.identify = (...args) => {
36047
- r2._q.push(["identify", args]);
36048
- };
36049
- r2.setUserId = (...args) => {
36050
- r2._q.push(["setUserId", args]);
36051
- };
36052
- r2.init = (apiKey2, options) => {
36053
- r2._q.push(["init", [apiKey2, options]]);
36054
- const n2 = t2.createElement("script");
36055
- n2.type = "text/javascript";
36056
- n2.async = true;
36057
- n2.src = "https://cdn.amplitude.com/libs/analytics-browser-2.0.0-min.js.gz";
36058
- const o2 = t2.getElementsByTagName("script")[0];
36059
- o2.parentNode?.insertBefore(n2, o2);
36366
+ const r2 = {
36367
+ _q: [],
36368
+ track: (...args) => {
36369
+ r2._q.push(["track", [...args]]);
36370
+ },
36371
+ identify: (...args) => {
36372
+ r2._q.push(["identify", [...args]]);
36373
+ },
36374
+ setUserId: (...args) => {
36375
+ r2._q.push(["setUserId", [...args]]);
36376
+ },
36377
+ init: (apiKey2, options) => {
36378
+ r2._q.push(["init", [apiKey2, options]]);
36379
+ const n2 = t2.createElement("script");
36380
+ n2.type = "text/javascript";
36381
+ n2.async = true;
36382
+ n2.src = "https://cdn.amplitude.com/libs/analytics-browser-2.0.0-min.js.gz";
36383
+ const o2 = t2.getElementsByTagName("script")[0];
36384
+ o2.parentNode?.insertBefore(n2, o2);
36385
+ }
36060
36386
  };
36061
36387
  e2.amplitude = r2;
36062
36388
  })(window, document);
@@ -37113,9 +37439,9 @@ var AnalyticsTracker = class {
37113
37439
  }
37114
37440
  }
37115
37441
  getOrCreateAnonymousId() {
37116
- const storage = this.getStorage();
37117
- if (storage) {
37118
- const stored = storage.getItem(this.getStorageKey("anon_id"));
37442
+ const storage2 = this.getStorage();
37443
+ if (storage2) {
37444
+ const stored = storage2.getItem(this.getStorageKey("anon_id"));
37119
37445
  if (stored) return stored;
37120
37446
  }
37121
37447
  const id = this.generateId();
@@ -37123,33 +37449,33 @@ var AnalyticsTracker = class {
37123
37449
  return id;
37124
37450
  }
37125
37451
  persistAnonymousId(id) {
37126
- const storage = this.getStorage();
37127
- if (storage) {
37128
- storage.setItem(this.getStorageKey("anon_id"), id);
37452
+ const storage2 = this.getStorage();
37453
+ if (storage2) {
37454
+ storage2.setItem(this.getStorageKey("anon_id"), id);
37129
37455
  }
37130
37456
  }
37131
37457
  persistDistinctId(id) {
37132
- const storage = this.getStorage();
37133
- if (storage) {
37134
- storage.setItem(this.getStorageKey("distinct_id"), id);
37458
+ const storage2 = this.getStorage();
37459
+ if (storage2) {
37460
+ storage2.setItem(this.getStorageKey("distinct_id"), id);
37135
37461
  }
37136
37462
  }
37137
37463
  clearDistinctId() {
37138
- const storage = this.getStorage();
37139
- if (storage) {
37140
- storage.removeItem(this.getStorageKey("distinct_id"));
37464
+ const storage2 = this.getStorage();
37465
+ if (storage2) {
37466
+ storage2.removeItem(this.getStorageKey("distinct_id"));
37141
37467
  }
37142
37468
  }
37143
37469
  getOrCreateSessionId() {
37144
- const storage = this.getStorage();
37145
- if (storage) {
37146
- const stored = storage.getItem(this.getStorageKey("session_id"));
37147
- const timestamp = storage.getItem(this.getStorageKey("session_ts"));
37470
+ const storage2 = this.getStorage();
37471
+ if (storage2) {
37472
+ const stored = storage2.getItem(this.getStorageKey("session_id"));
37473
+ const timestamp = storage2.getItem(this.getStorageKey("session_ts"));
37148
37474
  if (stored && timestamp) {
37149
37475
  const lastActivity = Number.parseInt(timestamp, 10);
37150
37476
  const timeout = this.config.sessionTimeout ?? ANALYTICS_SESSION_TIMEOUT_MS;
37151
37477
  if (Date.now() - lastActivity < timeout) {
37152
- storage.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37478
+ storage2.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37153
37479
  return stored;
37154
37480
  }
37155
37481
  }
@@ -37159,16 +37485,16 @@ var AnalyticsTracker = class {
37159
37485
  return id;
37160
37486
  }
37161
37487
  persistSessionId(id) {
37162
- const storage = this.getStorage();
37163
- if (storage) {
37164
- storage.setItem(this.getStorageKey("session_id"), id);
37165
- storage.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37488
+ const storage2 = this.getStorage();
37489
+ if (storage2) {
37490
+ storage2.setItem(this.getStorageKey("session_id"), id);
37491
+ storage2.setItem(this.getStorageKey("session_ts"), Date.now().toString());
37166
37492
  }
37167
37493
  }
37168
37494
  loadQueue() {
37169
- const storage = this.getStorage();
37170
- if (storage) {
37171
- const stored = storage.getItem(this.getStorageKey("queue"));
37495
+ const storage2 = this.getStorage();
37496
+ if (storage2) {
37497
+ const stored = storage2.getItem(this.getStorageKey("queue"));
37172
37498
  if (stored) {
37173
37499
  try {
37174
37500
  this.queue = JSON.parse(stored);
@@ -37179,22 +37505,22 @@ var AnalyticsTracker = class {
37179
37505
  }
37180
37506
  }
37181
37507
  persistQueue() {
37182
- const storage = this.getStorage();
37183
- if (storage) {
37184
- storage.setItem(this.getStorageKey("queue"), JSON.stringify(this.queue));
37508
+ const storage2 = this.getStorage();
37509
+ if (storage2) {
37510
+ storage2.setItem(this.getStorageKey("queue"), JSON.stringify(this.queue));
37185
37511
  }
37186
37512
  }
37187
37513
  loadInitialAttribution(key) {
37188
- const storage = this.getStorage();
37189
- if (storage) {
37190
- return storage.getItem(this.getStorageKey(key));
37514
+ const storage2 = this.getStorage();
37515
+ if (storage2) {
37516
+ return storage2.getItem(this.getStorageKey(key));
37191
37517
  }
37192
37518
  return null;
37193
37519
  }
37194
37520
  persistInitialAttribution(key, value) {
37195
- const storage = this.getStorage();
37196
- if (storage) {
37197
- storage.setItem(this.getStorageKey(key), value);
37521
+ const storage2 = this.getStorage();
37522
+ if (storage2) {
37523
+ storage2.setItem(this.getStorageKey(key), value);
37198
37524
  }
37199
37525
  }
37200
37526
  // ==========================================
@@ -37234,7 +37560,7 @@ function resetAnalyticsTracker() {
37234
37560
 
37235
37561
  // src/react/hooks/use-analytics.tsx
37236
37562
  init_constants();
37237
- import React, { createContext as createContext8, useCallback as useCallback44, useContext as useContext20, useEffect as useEffect53, useMemo as useMemo13, useRef as useRef24 } from "react";
37563
+ import React, { createContext as createContext8, useCallback as useCallback43, useContext as useContext21, useEffect as useEffect53, useMemo as useMemo14, useRef as useRef22 } from "react";
37238
37564
  import { Fragment as Fragment34, jsx as jsx50 } from "react/jsx-runtime";
37239
37565
  var AnalyticsContext = createContext8(null);
37240
37566
  function AnalyticsProvider({
@@ -37243,7 +37569,7 @@ function AnalyticsProvider({
37243
37569
  user,
37244
37570
  disabled = false
37245
37571
  }) {
37246
- const trackerRef = useRef24(null);
37572
+ const trackerRef = useRef22(null);
37247
37573
  const [isReady, setIsReady] = React.useState(false);
37248
37574
  useEffect53(() => {
37249
37575
  if (disabled || typeof window === "undefined") return;
@@ -37259,7 +37585,7 @@ function AnalyticsProvider({
37259
37585
  trackerRef.current.identify(user.id, user.properties);
37260
37586
  }
37261
37587
  }, [user]);
37262
- const value = useMemo13(() => {
37588
+ const value = useMemo14(() => {
37263
37589
  if (!trackerRef.current || disabled) return null;
37264
37590
  return {
37265
37591
  tracker: trackerRef.current,
@@ -37272,58 +37598,58 @@ function AnalyticsProvider({
37272
37598
  return /* @__PURE__ */ jsx50(AnalyticsContext.Provider, { value, children });
37273
37599
  }
37274
37600
  function useAnalyticsHook() {
37275
- const ctx = useContext20(AnalyticsContext);
37601
+ const ctx = useContext21(AnalyticsContext);
37276
37602
  const tracker = ctx?.tracker ?? null;
37277
37603
  const isReady = ctx?.isReady ?? false;
37278
- const track = useCallback44(
37604
+ const track = useCallback43(
37279
37605
  (eventName, properties) => {
37280
37606
  tracker?.track(eventName, properties);
37281
37607
  },
37282
37608
  [tracker]
37283
37609
  );
37284
- const identify = useCallback44(
37610
+ const identify = useCallback43(
37285
37611
  (userId, properties) => {
37286
37612
  tracker?.identify(userId, properties);
37287
37613
  },
37288
37614
  [tracker]
37289
37615
  );
37290
- const reset = useCallback44(() => {
37616
+ const reset = useCallback43(() => {
37291
37617
  tracker?.reset();
37292
37618
  }, [tracker]);
37293
- const setUserProperties = useCallback44(
37619
+ const setUserProperties = useCallback43(
37294
37620
  (properties) => {
37295
37621
  tracker?.setUserProperties(properties);
37296
37622
  },
37297
37623
  [tracker]
37298
37624
  );
37299
- const setUserPropertiesOnce = useCallback44(
37625
+ const setUserPropertiesOnce = useCallback43(
37300
37626
  (properties) => {
37301
37627
  tracker?.setUserPropertiesOnce(properties);
37302
37628
  },
37303
37629
  [tracker]
37304
37630
  );
37305
- const incrementUserProperty = useCallback44(
37631
+ const incrementUserProperty = useCallback43(
37306
37632
  (property, value) => {
37307
37633
  tracker?.incrementUserProperty(property, value);
37308
37634
  },
37309
37635
  [tracker]
37310
37636
  );
37311
- const group = useCallback44(
37637
+ const group = useCallback43(
37312
37638
  (groupType, groupKey, properties) => {
37313
37639
  tracker?.group(groupType, groupKey, properties);
37314
37640
  },
37315
37641
  [tracker]
37316
37642
  );
37317
- const register = useCallback44(
37643
+ const register = useCallback43(
37318
37644
  (properties) => {
37319
37645
  tracker?.register(properties);
37320
37646
  },
37321
37647
  [tracker]
37322
37648
  );
37323
- const getDistinctId = useCallback44(() => {
37649
+ const getDistinctId = useCallback43(() => {
37324
37650
  return tracker?.getDistinctId() ?? null;
37325
37651
  }, [tracker]);
37326
- const flush = useCallback44(async () => {
37652
+ const flush = useCallback43(async () => {
37327
37653
  await tracker?.flush();
37328
37654
  }, [tracker]);
37329
37655
  return {
@@ -37342,7 +37668,7 @@ function useAnalyticsHook() {
37342
37668
  }
37343
37669
  function usePageView(pageName, properties) {
37344
37670
  const { track, isReady } = useAnalyticsHook();
37345
- const hasTracked = useRef24(false);
37671
+ const hasTracked = useRef22(false);
37346
37672
  useEffect53(() => {
37347
37673
  if (!isReady || hasTracked.current) return;
37348
37674
  hasTracked.current = true;
@@ -37354,8 +37680,8 @@ function usePageView(pageName, properties) {
37354
37680
  }
37355
37681
  function useComponentTracking(componentName, properties) {
37356
37682
  const { track, isReady } = useAnalyticsHook();
37357
- const mountTime = useRef24(Date.now());
37358
- const hasTracked = useRef24(false);
37683
+ const mountTime = useRef22(Date.now());
37684
+ const hasTracked = useRef22(false);
37359
37685
  useEffect53(() => {
37360
37686
  if (!isReady || hasTracked.current) return;
37361
37687
  hasTracked.current = true;
@@ -37374,7 +37700,7 @@ function useComponentTracking(componentName, properties) {
37374
37700
  }
37375
37701
  function useFeatureTracking(featureName) {
37376
37702
  const { track } = useAnalyticsHook();
37377
- const trackUsed = useCallback44(
37703
+ const trackUsed = useCallback43(
37378
37704
  (properties) => {
37379
37705
  track("feature_used", {
37380
37706
  feature: featureName,
@@ -37383,7 +37709,7 @@ function useFeatureTracking(featureName) {
37383
37709
  },
37384
37710
  [track, featureName]
37385
37711
  );
37386
- const trackError = useCallback44(
37712
+ const trackError = useCallback43(
37387
37713
  (error, properties) => {
37388
37714
  track("feature_error", {
37389
37715
  feature: featureName,
@@ -37398,13 +37724,13 @@ function useFeatureTracking(featureName) {
37398
37724
  }
37399
37725
  function useFormTracking(formName) {
37400
37726
  const { track } = useAnalyticsHook();
37401
- const startTime = useRef24(null);
37402
- const fieldsFilledRef = useRef24(/* @__PURE__ */ new Set());
37403
- const trackStarted = useCallback44(() => {
37727
+ const startTime = useRef22(null);
37728
+ const fieldsFilledRef = useRef22(/* @__PURE__ */ new Set());
37729
+ const trackStarted = useCallback43(() => {
37404
37730
  startTime.current = Date.now();
37405
37731
  track("form_started", { form: formName });
37406
37732
  }, [track, formName]);
37407
- const trackCompleted = useCallback44(
37733
+ const trackCompleted = useCallback43(
37408
37734
  (properties) => {
37409
37735
  const duration = startTime.current ? Date.now() - startTime.current : void 0;
37410
37736
  track("form_completed", {
@@ -37416,7 +37742,7 @@ function useFormTracking(formName) {
37416
37742
  },
37417
37743
  [track, formName]
37418
37744
  );
37419
- const trackAbandoned = useCallback44(() => {
37745
+ const trackAbandoned = useCallback43(() => {
37420
37746
  const duration = startTime.current ? Date.now() - startTime.current : void 0;
37421
37747
  track("form_abandoned", {
37422
37748
  form: formName,
@@ -37424,7 +37750,7 @@ function useFormTracking(formName) {
37424
37750
  fields_filled: fieldsFilledRef.current.size
37425
37751
  });
37426
37752
  }, [track, formName]);
37427
- const trackFieldFilled = useCallback44(
37753
+ const trackFieldFilled = useCallback43(
37428
37754
  (fieldName) => {
37429
37755
  if (!fieldsFilledRef.current.has(fieldName)) {
37430
37756
  fieldsFilledRef.current.add(fieldName);
@@ -37436,7 +37762,7 @@ function useFormTracking(formName) {
37436
37762
  },
37437
37763
  [track, formName]
37438
37764
  );
37439
- const trackError = useCallback44(
37765
+ const trackError = useCallback43(
37440
37766
  (fieldName, error) => {
37441
37767
  track("form_field_error", {
37442
37768
  form: formName,
@@ -37456,12 +37782,12 @@ function useFormTracking(formName) {
37456
37782
  }
37457
37783
  function useTimeTracking(name, options) {
37458
37784
  const { track } = useAnalyticsHook();
37459
- const startTime = useRef24(Date.now());
37460
- const trackedIntervals = useRef24(/* @__PURE__ */ new Set());
37461
- const getTimeSpent = useCallback44(() => {
37785
+ const startTime = useRef22(Date.now());
37786
+ const trackedIntervals = useRef22(/* @__PURE__ */ new Set());
37787
+ const getTimeSpent = useCallback43(() => {
37462
37788
  return Date.now() - startTime.current;
37463
37789
  }, []);
37464
- const trackNow = useCallback44(() => {
37790
+ const trackNow = useCallback43(() => {
37465
37791
  track("time_spent", {
37466
37792
  name,
37467
37793
  duration_ms: getTimeSpent()
@@ -37498,8 +37824,8 @@ function useTimeTracking(name, options) {
37498
37824
  }
37499
37825
 
37500
37826
  // src/react/hooks/use-destination-router.tsx
37501
- import { useCallback as useCallback45, useEffect as useEffect54, useMemo as useMemo14, useRef as useRef25 } from "react";
37502
- import { createContext as createContext9, useContext as useContext21 } from "react";
37827
+ import { useCallback as useCallback44, useEffect as useEffect54, useMemo as useMemo15, useRef as useRef23 } from "react";
37828
+ import { createContext as createContext9, useContext as useContext22 } from "react";
37503
37829
  import { jsx as jsx51 } from "react/jsx-runtime";
37504
37830
  function useDestinationRouter(options) {
37505
37831
  const {
@@ -37509,11 +37835,11 @@ function useDestinationRouter(options) {
37509
37835
  autoInit = true,
37510
37836
  debug = false
37511
37837
  } = options;
37512
- const routerRef = useRef25(null);
37513
- const initializedRef = useRef25(false);
37838
+ const routerRef = useRef23(null);
37839
+ const initializedRef = useRef23(false);
37514
37840
  const { hasConsent: checkConsent } = useConsent();
37515
37841
  const { user } = useUser();
37516
- const router = useMemo14(() => {
37842
+ const router = useMemo15(() => {
37517
37843
  if (!autoInit || typeof window === "undefined") return null;
37518
37844
  const newRouter = createDestinationRouter({
37519
37845
  destinations,
@@ -37538,46 +37864,46 @@ function useDestinationRouter(options) {
37538
37864
  name: user.name
37539
37865
  });
37540
37866
  }, [syncUser, user?.id, user?.email, user?.name]);
37541
- const track = useCallback45(
37867
+ const track = useCallback44(
37542
37868
  (event, properties) => {
37543
37869
  router?.track(event, properties);
37544
37870
  },
37545
37871
  [router]
37546
37872
  );
37547
- const trackTo = useCallback45(
37873
+ const trackTo = useCallback44(
37548
37874
  (destinationType, event, properties) => {
37549
37875
  router?.trackTo(destinationType, event, properties);
37550
37876
  },
37551
37877
  [router]
37552
37878
  );
37553
- const identify = useCallback45(
37879
+ const identify = useCallback44(
37554
37880
  (userId, traits) => {
37555
37881
  router?.identify(userId, traits);
37556
37882
  },
37557
37883
  [router]
37558
37884
  );
37559
- const page = useCallback45(
37885
+ const page = useCallback44(
37560
37886
  (name, properties) => {
37561
37887
  router?.page(name, properties);
37562
37888
  },
37563
37889
  [router]
37564
37890
  );
37565
- const getEnabledDestinations = useCallback45(() => {
37891
+ const getEnabledDestinations = useCallback44(() => {
37566
37892
  return router?.getEnabledDestinations() || [];
37567
37893
  }, [router]);
37568
- const setDestinationEnabled = useCallback45(
37894
+ const setDestinationEnabled = useCallback44(
37569
37895
  (type, enabled) => {
37570
37896
  router?.setDestinationEnabled(type, enabled);
37571
37897
  },
37572
37898
  [router]
37573
37899
  );
37574
- const setConsentChecker = useCallback45(
37900
+ const setConsentChecker = useCallback44(
37575
37901
  (fn) => {
37576
37902
  router?.setConsentChecker(fn);
37577
37903
  },
37578
37904
  [router]
37579
37905
  );
37580
- const setDistinctId = useCallback45(
37906
+ const setDistinctId = useCallback44(
37581
37907
  (id) => {
37582
37908
  router?.setDistinctId(id);
37583
37909
  },
@@ -37605,7 +37931,7 @@ function DestinationRouterProvider({
37605
37931
  return /* @__PURE__ */ jsx51(DestinationRouterContext.Provider, { value: router, children });
37606
37932
  }
37607
37933
  function useRouterContext() {
37608
- return useContext21(DestinationRouterContext);
37934
+ return useContext22(DestinationRouterContext);
37609
37935
  }
37610
37936
 
37611
37937
  // src/lib/tasks/handler.ts
@@ -37720,7 +38046,7 @@ function createTasksHandler(taskDefs, options = {}) {
37720
38046
  { status: 400 }
37721
38047
  );
37722
38048
  }
37723
- const signingSecret = options.signingSecret ?? process.env.SYLPHX_SIGNING_SECRET ?? process.env.SYLPHX_SECRET_KEY ?? "";
38049
+ const signingSecret = options.signingSecret ?? process.env.SYLPHX_SIGNING_SECRET ?? "";
37724
38050
  if (signingSecret) {
37725
38051
  const signature = req.headers.get("x-sylphx-signature") ?? "";
37726
38052
  if (!signature) {
@@ -37951,7 +38277,9 @@ var TasksClient = class {
37951
38277
  const params = new URLSearchParams();
37952
38278
  if (options?.limit) params.set("limit", String(options.limit));
37953
38279
  if (options?.offset) params.set("offset", String(options.offset));
37954
- const response = await this.fetch(`/jobs/dlq?${params.toString()}`);
38280
+ const response = await this.fetch(
38281
+ `/jobs/dlq?${params.toString()}`
38282
+ );
37955
38283
  return { entries: response.entries, total: response.total };
37956
38284
  }
37957
38285
  /**
@@ -37996,7 +38324,9 @@ var TasksClient = class {
37996
38324
  * Get a workflow by ID
37997
38325
  */
37998
38326
  async getWorkflow(workflowId) {
37999
- const response = await this.fetch(`/workflows/${workflowId}`);
38327
+ const response = await this.fetch(
38328
+ `/workflows/${workflowId}`
38329
+ );
38000
38330
  return response.workflow;
38001
38331
  }
38002
38332
  /**
@@ -38017,7 +38347,9 @@ var TasksClient = class {
38017
38347
  if (options?.status) params.set("status", options.status);
38018
38348
  if (options?.limit) params.set("limit", String(options.limit));
38019
38349
  if (options?.offset) params.set("offset", String(options.offset));
38020
- const response = await this.fetch(`/workflows?${params.toString()}`);
38350
+ const response = await this.fetch(
38351
+ `/workflows?${params.toString()}`
38352
+ );
38021
38353
  return { workflows: response.workflows, total: response.total };
38022
38354
  }
38023
38355
  // =========================================================================
@@ -38031,25 +38363,33 @@ var TasksClient = class {
38031
38363
  if (options?.status) params.set("status", options.status);
38032
38364
  if (options?.limit) params.set("limit", String(options.limit));
38033
38365
  if (options?.offset) params.set("offset", String(options.offset));
38034
- const response = await this.fetch(`/jobs/scheduled?${params.toString()}`);
38366
+ const response = await this.fetch(
38367
+ `/jobs/scheduled?${params.toString()}`
38368
+ );
38035
38369
  return { scheduled: response.scheduled, total: response.total };
38036
38370
  }
38037
38371
  /**
38038
38372
  * Pause a scheduled job
38039
38373
  */
38040
38374
  async pauseScheduledJob(scheduleId) {
38041
- const response = await this.fetch(`/jobs/scheduled/${scheduleId}/pause`, {
38042
- method: "POST"
38043
- });
38375
+ const response = await this.fetch(
38376
+ `/jobs/scheduled/${scheduleId}/pause`,
38377
+ {
38378
+ method: "POST"
38379
+ }
38380
+ );
38044
38381
  return response.scheduled;
38045
38382
  }
38046
38383
  /**
38047
38384
  * Resume a scheduled job
38048
38385
  */
38049
38386
  async resumeScheduledJob(scheduleId) {
38050
- const response = await this.fetch(`/jobs/scheduled/${scheduleId}/resume`, {
38051
- method: "POST"
38052
- });
38387
+ const response = await this.fetch(
38388
+ `/jobs/scheduled/${scheduleId}/resume`,
38389
+ {
38390
+ method: "POST"
38391
+ }
38392
+ );
38053
38393
  return response.scheduled;
38054
38394
  }
38055
38395
  /**
@@ -38091,7 +38431,6 @@ var TasksClient = class {
38091
38431
  // =========================================================================
38092
38432
  // Internal
38093
38433
  // =========================================================================
38094
- // biome-ignore lint/suspicious/noExplicitAny: Internal method, type safety enforced at public API level -- Internal method, type safety enforced at public API level
38095
38434
  async fetch(path, options) {
38096
38435
  const url = `${this.config.apiEndpoint}${path}`;
38097
38436
  const response = await fetch(url, {
@@ -38105,10 +38444,12 @@ var TasksClient = class {
38105
38444
  }
38106
38445
  });
38107
38446
  if (!response.ok) {
38108
- const error = await response.json().catch(() => ({ message: response.statusText }));
38109
- throw new Error(error.message || `HTTP ${response.status}`);
38447
+ const errorPayload = await response.json().catch(() => ({ message: response.statusText }));
38448
+ const message = typeof errorPayload === "object" && errorPayload !== null && "message" in errorPayload && typeof errorPayload.message === "string" ? errorPayload.message : response.statusText;
38449
+ throw new Error(message || `HTTP ${response.status}`);
38110
38450
  }
38111
- return response.json();
38451
+ const payload = await response.json();
38452
+ return payload;
38112
38453
  }
38113
38454
  // =========================================================================
38114
38455
  // Native Task Engine — Handler API
@@ -38151,31 +38492,35 @@ var TasksClient = class {
38151
38492
  * Returns the taskRunId which can be used to poll status.
38152
38493
  */
38153
38494
  async trigger(taskName, payload, options) {
38154
- const response = await this.fetch("/tasks/trigger", {
38155
- method: "POST",
38156
- body: JSON.stringify({
38157
- taskName,
38158
- payload,
38159
- delay: options?.delay,
38160
- scheduledFor: options?.scheduledFor?.toISOString(),
38161
- idempotencyKey: options?.idempotencyKey,
38162
- maxAttempts: options?.maxAttempts
38163
- })
38164
- });
38495
+ const response = await this.fetch(
38496
+ "/tasks/trigger",
38497
+ {
38498
+ method: "POST",
38499
+ body: JSON.stringify({
38500
+ taskName,
38501
+ payload,
38502
+ delay: options?.delay,
38503
+ scheduledFor: options?.scheduledFor?.toISOString(),
38504
+ idempotencyKey: options?.idempotencyKey,
38505
+ maxAttempts: options?.maxAttempts
38506
+ })
38507
+ }
38508
+ );
38165
38509
  return response;
38166
38510
  }
38167
38511
  /**
38168
38512
  * Fetch the current status of a task run.
38169
38513
  */
38170
38514
  async getTaskRun(taskRunId) {
38171
- const response = await this.fetch(`/tasks/${taskRunId}`);
38172
- return response;
38515
+ return this.fetch(`/tasks/${taskRunId}`);
38173
38516
  }
38174
38517
  /**
38175
38518
  * Cancel a pending or waiting task run.
38176
38519
  */
38177
38520
  async cancelTaskRun(taskRunId) {
38178
- const response = await this.fetch(`/tasks/${taskRunId}/cancel`, { method: "POST" });
38521
+ const response = await this.fetch(`/tasks/${taskRunId}/cancel`, {
38522
+ method: "POST"
38523
+ });
38179
38524
  return response.success;
38180
38525
  }
38181
38526
  /**
@@ -38187,8 +38532,7 @@ var TasksClient = class {
38187
38532
  if (options?.status) params.set("status", options.status);
38188
38533
  if (options?.limit) params.set("limit", String(options.limit));
38189
38534
  if (options?.offset) params.set("offset", String(options.offset));
38190
- const response = await this.fetch(`/tasks?${params.toString()}`);
38191
- return response;
38535
+ return this.fetch(`/tasks?${params.toString()}`);
38192
38536
  }
38193
38537
  };
38194
38538
  function createTasksClient(config2) {
@@ -38342,7 +38686,7 @@ function delay(ms) {
38342
38686
  function sleepUntil(date) {
38343
38687
  return wait(date);
38344
38688
  }
38345
- function withRetry(step, options) {
38689
+ function withRetry2(step, options) {
38346
38690
  return {
38347
38691
  ...step,
38348
38692
  options: {
@@ -38435,7 +38779,7 @@ var job = task;
38435
38779
 
38436
38780
  // src/react/hooks/use-realtime.ts
38437
38781
  init_constants();
38438
- import { useCallback as useCallback46, useContext as useContext22, useEffect as useEffect55, useMemo as useMemo15, useRef as useRef26, useState as useState62 } from "react";
38782
+ import { useCallback as useCallback45, useContext as useContext23, useEffect as useEffect55, useMemo as useMemo16, useRef as useRef24, useState as useState61 } from "react";
38439
38783
  function useRealtime(channel, options = {}) {
38440
38784
  const {
38441
38785
  events,
@@ -38447,17 +38791,17 @@ function useRealtime(channel, options = {}) {
38447
38791
  enabled = true,
38448
38792
  platformUrl: customPlatformUrl
38449
38793
  } = options;
38450
- const [messages, setMessages] = useState62([]);
38451
- const [status, setStatus] = useState62("disconnected");
38452
- const platformContext = useContext22(PlatformContext);
38794
+ const [messages, setMessages] = useState61([]);
38795
+ const [status, setStatus] = useState61("disconnected");
38796
+ const platformContext = useContext23(PlatformContext);
38453
38797
  const appId = platformContext?.appId || "";
38454
- const lastAckRef = useRef26("0");
38455
- const eventSourceRef = useRef26(null);
38456
- const reconnectTimeoutRef = useRef26(null);
38457
- const reconnectAttemptRef = useRef26(0);
38458
- const mountedRef = useRef26(true);
38798
+ const lastAckRef = useRef24("0");
38799
+ const eventSourceRef = useRef24(null);
38800
+ const reconnectTimeoutRef = useRef24(null);
38801
+ const reconnectAttemptRef = useRef24(0);
38802
+ const mountedRef = useRef24(true);
38459
38803
  const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
38460
- const buildUrl = useCallback46(() => {
38804
+ const buildUrl = useCallback45(() => {
38461
38805
  const url = new URL(`${platformUrl}${SDK_API_PATH}/realtime/subscribe`);
38462
38806
  url.searchParams.set("channel", channel);
38463
38807
  if (lastAckRef.current !== "0") {
@@ -38465,7 +38809,7 @@ function useRealtime(channel, options = {}) {
38465
38809
  }
38466
38810
  return url.toString();
38467
38811
  }, [platformUrl, channel]);
38468
- const sdkHeaders = useMemo15(
38812
+ const sdkHeaders = useMemo16(
38469
38813
  () => ({
38470
38814
  "Content-Type": "application/json",
38471
38815
  "x-app-secret": appId,
@@ -38474,7 +38818,7 @@ function useRealtime(channel, options = {}) {
38474
38818
  }),
38475
38819
  [appId]
38476
38820
  );
38477
- const fetchHistory = useCallback46(async () => {
38821
+ const fetchHistory = useCallback45(async () => {
38478
38822
  if (!history2) return;
38479
38823
  const historyLimit = typeof history2 === "number" ? history2 : history2.limit ?? 100;
38480
38824
  const historyStart = typeof history2 === "object" ? history2.start : void 0;
@@ -38498,7 +38842,7 @@ function useRealtime(channel, options = {}) {
38498
38842
  } catch {
38499
38843
  }
38500
38844
  }, [platformUrl, sdkHeaders, channel, history2]);
38501
- const connect = useCallback46(() => {
38845
+ const connect = useCallback45(() => {
38502
38846
  if (!enabled || !appId) return;
38503
38847
  if (eventSourceRef.current) {
38504
38848
  eventSourceRef.current.close();
@@ -38569,7 +38913,7 @@ function useRealtime(channel, options = {}) {
38569
38913
  onReconnect,
38570
38914
  onError
38571
38915
  ]);
38572
- const disconnect = useCallback46(() => {
38916
+ const disconnect = useCallback45(() => {
38573
38917
  if (eventSourceRef.current) {
38574
38918
  eventSourceRef.current.close();
38575
38919
  eventSourceRef.current = null;
@@ -38580,7 +38924,7 @@ function useRealtime(channel, options = {}) {
38580
38924
  }
38581
38925
  setStatus("disconnected");
38582
38926
  }, []);
38583
- const emit = useCallback46(
38927
+ const emit = useCallback45(
38584
38928
  async (event, data) => {
38585
38929
  const response = await fetch(`${platformUrl}${SDK_API_PATH}/realtime/emit`, {
38586
38930
  method: "POST",
@@ -38612,7 +38956,7 @@ function useRealtime(channel, options = {}) {
38612
38956
  },
38613
38957
  [platformUrl, sdkHeaders, channel]
38614
38958
  );
38615
- const clear = useCallback46(() => {
38959
+ const clear = useCallback45(() => {
38616
38960
  setMessages([]);
38617
38961
  lastAckRef.current = "0";
38618
38962
  }, []);
@@ -38645,14 +38989,14 @@ function useRealtimeChannels(channels, options = {}) {
38645
38989
  enabled = true,
38646
38990
  platformUrl: customPlatformUrl
38647
38991
  } = options;
38648
- const [messages, setMessages] = useState62([]);
38649
- const [statuses, setStatuses] = useState62({});
38650
- const platformContext = useContext22(PlatformContext);
38992
+ const [messages, setMessages] = useState61([]);
38993
+ const [statuses, setStatuses] = useState61({});
38994
+ const platformContext = useContext23(PlatformContext);
38651
38995
  const appId = platformContext?.appId || "";
38652
38996
  const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
38653
- const lastAcksRef = useRef26({});
38654
- const eventSourcesRef = useRef26({});
38655
- const mountedRef = useRef26(true);
38997
+ const lastAcksRef = useRef24({});
38998
+ const eventSourcesRef = useRef24({});
38999
+ const mountedRef = useRef24(true);
38656
39000
  const status = (() => {
38657
39001
  const statusValues = Object.values(statuses);
38658
39002
  if (statusValues.length === 0) return "disconnected";
@@ -38661,7 +39005,7 @@ function useRealtimeChannels(channels, options = {}) {
38661
39005
  if (statusValues.every((s2) => s2 === "connected")) return "connected";
38662
39006
  return "disconnected";
38663
39007
  })();
38664
- const connectChannel = useCallback46(
39008
+ const connectChannel = useCallback45(
38665
39009
  (channel) => {
38666
39010
  if (!enabled || !appId) return;
38667
39011
  if (eventSourcesRef.current[channel]) {
@@ -38711,17 +39055,17 @@ function useRealtimeChannels(channels, options = {}) {
38711
39055
  },
38712
39056
  [enabled, appId, platformUrl, events, onConnect, onMessage, onReconnect, onError]
38713
39057
  );
38714
- const connect = useCallback46(() => {
39058
+ const connect = useCallback45(() => {
38715
39059
  channels.forEach(connectChannel);
38716
39060
  }, [channels, connectChannel]);
38717
- const disconnect = useCallback46(() => {
39061
+ const disconnect = useCallback45(() => {
38718
39062
  Object.values(eventSourcesRef.current).forEach((es) => {
38719
39063
  es.close();
38720
39064
  });
38721
39065
  eventSourcesRef.current = {};
38722
39066
  setStatuses({});
38723
39067
  }, []);
38724
- const sdkHeaders = useMemo15(
39068
+ const sdkHeaders = useMemo16(
38725
39069
  () => ({
38726
39070
  "Content-Type": "application/json",
38727
39071
  "x-app-secret": appId,
@@ -38730,7 +39074,7 @@ function useRealtimeChannels(channels, options = {}) {
38730
39074
  }),
38731
39075
  [appId]
38732
39076
  );
38733
- const emit = useCallback46(
39077
+ const emit = useCallback45(
38734
39078
  async (event, data, targetChannel) => {
38735
39079
  const channel = targetChannel || channels[0];
38736
39080
  if (!channel) throw new SylphxError("No channel specified", { code: "BAD_REQUEST" });
@@ -38757,7 +39101,7 @@ function useRealtimeChannels(channels, options = {}) {
38757
39101
  },
38758
39102
  [channels, platformUrl, sdkHeaders]
38759
39103
  );
38760
- const clear = useCallback46(() => {
39104
+ const clear = useCallback45(() => {
38761
39105
  setMessages([]);
38762
39106
  lastAcksRef.current = {};
38763
39107
  }, []);
@@ -38783,13 +39127,13 @@ function useRealtimeChannels(channels, options = {}) {
38783
39127
 
38784
39128
  // src/react/hooks/use-kv.ts
38785
39129
  init_constants();
38786
- import { useCallback as useCallback47, useContext as useContext23, useMemo as useMemo16 } from "react";
39130
+ import { useCallback as useCallback46, useContext as useContext24, useMemo as useMemo17 } from "react";
38787
39131
  function useKv(options = {}) {
38788
39132
  const { platformUrl: customPlatformUrl } = options;
38789
- const platformContext = useContext23(PlatformContext);
39133
+ const platformContext = useContext24(PlatformContext);
38790
39134
  const appId = platformContext?.appId || "";
38791
39135
  const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
38792
- const headers = useMemo16(
39136
+ const headers = useMemo17(
38793
39137
  () => ({
38794
39138
  "Content-Type": "application/json",
38795
39139
  "x-app-secret": appId,
@@ -38798,7 +39142,7 @@ function useKv(options = {}) {
38798
39142
  }),
38799
39143
  [appId]
38800
39144
  );
38801
- const request = useCallback47(
39145
+ const request = useCallback46(
38802
39146
  async (method, path, body) => {
38803
39147
  let lastError;
38804
39148
  for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
@@ -38854,13 +39198,13 @@ function useKv(options = {}) {
38854
39198
  },
38855
39199
  [platformUrl, headers]
38856
39200
  );
38857
- const get = useCallback47(
39201
+ const get = useCallback46(
38858
39202
  async (key) => {
38859
39203
  return request("GET", `/${encodeURIComponent(key)}`);
38860
39204
  },
38861
39205
  [request]
38862
39206
  );
38863
- const set = useCallback47(
39207
+ const set = useCallback46(
38864
39208
  async (key, value, options2) => {
38865
39209
  const result = await request("POST", "", {
38866
39210
  key,
@@ -38871,28 +39215,28 @@ function useKv(options = {}) {
38871
39215
  },
38872
39216
  [request]
38873
39217
  );
38874
- const del = useCallback47(
39218
+ const del = useCallback46(
38875
39219
  async (key) => {
38876
39220
  const result = await request("DELETE", `/${encodeURIComponent(key)}`);
38877
39221
  return result.deleted;
38878
39222
  },
38879
39223
  [request]
38880
39224
  );
38881
- const exists = useCallback47(
39225
+ const exists = useCallback46(
38882
39226
  async (key) => {
38883
39227
  const result = await request("GET", `/exists/${encodeURIComponent(key)}`);
38884
39228
  return result.exists;
38885
39229
  },
38886
39230
  [request]
38887
39231
  );
38888
- const mget = useCallback47(
39232
+ const mget = useCallback46(
38889
39233
  async (keys) => {
38890
39234
  const result = await request("POST", "/mget", { keys });
38891
39235
  return result.values;
38892
39236
  },
38893
39237
  [request]
38894
39238
  );
38895
- const mset = useCallback47(
39239
+ const mset = useCallback46(
38896
39240
  async (entries, options2) => {
38897
39241
  await request("POST", "/mset", {
38898
39242
  entries,
@@ -38901,7 +39245,7 @@ function useKv(options = {}) {
38901
39245
  },
38902
39246
  [request]
38903
39247
  );
38904
- const incr = useCallback47(
39248
+ const incr = useCallback46(
38905
39249
  async (key, by = 1) => {
38906
39250
  const result = await request("POST", "/incr", {
38907
39251
  key,
@@ -38911,7 +39255,7 @@ function useKv(options = {}) {
38911
39255
  },
38912
39256
  [request]
38913
39257
  );
38914
- const expire = useCallback47(
39258
+ const expire = useCallback46(
38915
39259
  async (key, seconds) => {
38916
39260
  const result = await request("POST", "/expire", {
38917
39261
  key,
@@ -38921,7 +39265,7 @@ function useKv(options = {}) {
38921
39265
  },
38922
39266
  [request]
38923
39267
  );
38924
- const ratelimit = useCallback47(
39268
+ const ratelimit = useCallback46(
38925
39269
  async (key, options2) => {
38926
39270
  return request("POST", "/ratelimit", {
38927
39271
  key,
@@ -38930,7 +39274,7 @@ function useKv(options = {}) {
38930
39274
  },
38931
39275
  [request]
38932
39276
  );
38933
- const hset = useCallback47(
39277
+ const hset = useCallback46(
38934
39278
  async (key, fields) => {
38935
39279
  const result = await request("POST", "/hset", {
38936
39280
  key,
@@ -38940,7 +39284,7 @@ function useKv(options = {}) {
38940
39284
  },
38941
39285
  [request]
38942
39286
  );
38943
- const hget = useCallback47(
39287
+ const hget = useCallback46(
38944
39288
  async (key, field) => {
38945
39289
  const result = await request("POST", "/hget", {
38946
39290
  key,
@@ -38950,7 +39294,7 @@ function useKv(options = {}) {
38950
39294
  },
38951
39295
  [request]
38952
39296
  );
38953
- const hgetall = useCallback47(
39297
+ const hgetall = useCallback46(
38954
39298
  async (key) => {
38955
39299
  const result = await request("POST", "/hgetall", {
38956
39300
  key
@@ -38959,7 +39303,7 @@ function useKv(options = {}) {
38959
39303
  },
38960
39304
  [request]
38961
39305
  );
38962
- const lpush = useCallback47(
39306
+ const lpush = useCallback46(
38963
39307
  async (key, ...values) => {
38964
39308
  const result = await request("POST", "/lpush", {
38965
39309
  key,
@@ -38969,7 +39313,7 @@ function useKv(options = {}) {
38969
39313
  },
38970
39314
  [request]
38971
39315
  );
38972
- const lrange = useCallback47(
39316
+ const lrange = useCallback46(
38973
39317
  async (key, start = 0, stop = -1) => {
38974
39318
  const result = await request("POST", "/lrange", {
38975
39319
  key,
@@ -38980,7 +39324,7 @@ function useKv(options = {}) {
38980
39324
  },
38981
39325
  [request]
38982
39326
  );
38983
- const zadd = useCallback47(
39327
+ const zadd = useCallback46(
38984
39328
  async (key, ...members) => {
38985
39329
  const result = await request("POST", "/zadd", {
38986
39330
  key,
@@ -38990,7 +39334,7 @@ function useKv(options = {}) {
38990
39334
  },
38991
39335
  [request]
38992
39336
  );
38993
- const zrange = useCallback47(
39337
+ const zrange = useCallback46(
38994
39338
  async (key, start = 0, stop = 9, options2) => {
38995
39339
  const result = await request("POST", "/zrange", {
38996
39340
  key,
@@ -39003,7 +39347,7 @@ function useKv(options = {}) {
39003
39347
  },
39004
39348
  [request]
39005
39349
  );
39006
- return useMemo16(
39350
+ return useMemo17(
39007
39351
  () => ({
39008
39352
  get,
39009
39353
  set,
@@ -39044,7 +39388,7 @@ function useKv(options = {}) {
39044
39388
  }
39045
39389
 
39046
39390
  // src/react/hooks/use-search.ts
39047
- import { useCallback as useCallback48, useEffect as useEffect56, useRef as useRef27, useState as useState63 } from "react";
39391
+ import { useCallback as useCallback47, useEffect as useEffect56, useRef as useRef25, useState as useState62 } from "react";
39048
39392
 
39049
39393
  // src/search.ts
39050
39394
  async function search(config2, input) {
@@ -39078,19 +39422,19 @@ function useSearch(config2, options = {}) {
39078
39422
  initialQuery = "",
39079
39423
  ...searchOptions
39080
39424
  } = options;
39081
- const [query, setQueryState] = useState63(initialQuery);
39082
- const [results, setResults] = useState63([]);
39083
- const [total, setTotal] = useState63(0);
39084
- const [loading, setLoading] = useState63(false);
39085
- const [error, setError] = useState63(null);
39086
- const [response, setResponse] = useState63(null);
39087
- const debounceTimer = useRef27(null);
39088
- const abortController = useRef27(null);
39089
- const searchOptionsRef = useRef27(searchOptions);
39425
+ const [query, setQueryState] = useState62(initialQuery);
39426
+ const [results, setResults] = useState62([]);
39427
+ const [total, setTotal] = useState62(0);
39428
+ const [loading, setLoading] = useState62(false);
39429
+ const [error, setError] = useState62(null);
39430
+ const [response, setResponse] = useState62(null);
39431
+ const debounceTimer = useRef25(null);
39432
+ const abortController = useRef25(null);
39433
+ const searchOptionsRef = useRef25(searchOptions);
39090
39434
  useEffect56(() => {
39091
39435
  searchOptionsRef.current = searchOptions;
39092
39436
  });
39093
- const executeSearch = useCallback48(
39437
+ const executeSearch = useCallback47(
39094
39438
  async (q2) => {
39095
39439
  if (!q2 || q2.length < minLength) {
39096
39440
  setResults([]);
@@ -39122,7 +39466,7 @@ function useSearch(config2, options = {}) {
39122
39466
  },
39123
39467
  [config2, minLength]
39124
39468
  );
39125
- const setQuery = useCallback48(
39469
+ const setQuery = useCallback47(
39126
39470
  (q2) => {
39127
39471
  setQueryState(q2);
39128
39472
  if (debounceTimer.current) {
@@ -39142,7 +39486,7 @@ function useSearch(config2, options = {}) {
39142
39486
  },
39143
39487
  [executeSearch, debounceMs, minLength]
39144
39488
  );
39145
- const clear = useCallback48(() => {
39489
+ const clear = useCallback47(() => {
39146
39490
  if (debounceTimer.current) clearTimeout(debounceTimer.current);
39147
39491
  abortController.current?.abort();
39148
39492
  setQueryState("");
@@ -39152,10 +39496,10 @@ function useSearch(config2, options = {}) {
39152
39496
  setLoading(false);
39153
39497
  setError(null);
39154
39498
  }, []);
39155
- const refetch = useCallback48(() => {
39499
+ const refetch = useCallback47(() => {
39156
39500
  executeSearch(query);
39157
39501
  }, [executeSearch, query]);
39158
- const trackResultClick = useCallback48((_documentId, _resultRank) => {
39502
+ const trackResultClick = useCallback47((_documentId, _resultRank) => {
39159
39503
  }, []);
39160
39504
  useEffect56(() => {
39161
39505
  if (initialQuery && initialQuery.length >= minLength) {
@@ -39586,7 +39930,6 @@ export {
39586
39930
  SpeedInsights,
39587
39931
  StatsCard,
39588
39932
  StatsGrid,
39589
- StorageContext,
39590
39933
  SubscriberPreferences,
39591
39934
  SylphxError,
39592
39935
  SylphxErrorBoundary,
@@ -39720,7 +40063,8 @@ export {
39720
40063
  useFeatureFlagDefinitions,
39721
40064
  useFeatureFlags,
39722
40065
  useFeatureTracking,
39723
- useFileUpload,
40066
+ useFile,
40067
+ useFileList,
39724
40068
  useFlag,
39725
40069
  useFlagEvaluation,
39726
40070
  useFlagJSON,
@@ -39780,7 +40124,6 @@ export {
39780
40124
  useSignUpForm,
39781
40125
  useAnalyticsHook as useSmartAnalytics,
39782
40126
  useStorage,
39783
- useStorageContext,
39784
40127
  useStreak,
39785
40128
  useSubscriberForm,
39786
40129
  useSylphx,
@@ -39788,7 +40131,6 @@ export {
39788
40131
  useTasks,
39789
40132
  useTasksContext,
39790
40133
  useTimeTracking,
39791
- useUpload,
39792
40134
  useUser,
39793
40135
  useUserContext,
39794
40136
  useWebAnalytics,
@@ -39807,7 +40149,7 @@ export {
39807
40149
  validateSecretKey,
39808
40150
  validateWorkflow,
39809
40151
  wait,
39810
- withRetry,
40152
+ withRetry2 as withRetry,
39811
40153
  withSessionReplay,
39812
40154
  withTimeout
39813
40155
  };