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