@sylphx/sdk 0.9.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 +104 -291
- package/dist/index.mjs +461 -194
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.ts +91 -310
- package/dist/react/index.mjs +1273 -977
- 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,7 +13166,7 @@ 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
13171
|
await api.post("/auth/reset-password", {
|
|
13336
13172
|
token: options.token,
|
|
@@ -13339,28 +13175,28 @@ function SylphxProviderInner({
|
|
|
13339
13175
|
},
|
|
13340
13176
|
[api]
|
|
13341
13177
|
);
|
|
13342
|
-
const verifyEmail =
|
|
13178
|
+
const verifyEmail = useCallback27(
|
|
13343
13179
|
async (options) => {
|
|
13344
13180
|
await api.post("/auth/verify-email", { token: options.token });
|
|
13345
13181
|
},
|
|
13346
13182
|
[api]
|
|
13347
13183
|
);
|
|
13348
|
-
const resendVerificationEmail =
|
|
13184
|
+
const resendVerificationEmail = useCallback27(
|
|
13349
13185
|
async (options) => {
|
|
13350
13186
|
await api.post("/auth/resend-verification", { email: options.email });
|
|
13351
13187
|
},
|
|
13352
13188
|
[api]
|
|
13353
13189
|
);
|
|
13354
|
-
const forgotPassword =
|
|
13190
|
+
const forgotPassword = useCallback27(
|
|
13355
13191
|
async (options) => {
|
|
13356
13192
|
await api.post("/auth/forgot-password", { email: options.email });
|
|
13357
13193
|
},
|
|
13358
13194
|
[api]
|
|
13359
13195
|
);
|
|
13360
|
-
const clearOAuthError =
|
|
13196
|
+
const clearOAuthError = useCallback27(() => {
|
|
13361
13197
|
setAuthState((prev) => ({ ...prev, oauthError: null }));
|
|
13362
13198
|
}, []);
|
|
13363
|
-
const signInWithOAuth =
|
|
13199
|
+
const signInWithOAuth = useCallback27(
|
|
13364
13200
|
async (options) => {
|
|
13365
13201
|
const { provider, redirectUrl, scopes } = options;
|
|
13366
13202
|
const finalDestination = resolveRedirectUrl(redirectUrl);
|
|
@@ -13413,31 +13249,31 @@ function SylphxProviderInner({
|
|
|
13413
13249
|
},
|
|
13414
13250
|
[platformUrl, appId, resolveRedirectUrl, authPrefix]
|
|
13415
13251
|
);
|
|
13416
|
-
const signInWithGoogle =
|
|
13252
|
+
const signInWithGoogle = useCallback27(
|
|
13417
13253
|
(redirectUrl) => signInWithOAuth({ provider: "google", redirectUrl }),
|
|
13418
13254
|
[signInWithOAuth]
|
|
13419
13255
|
);
|
|
13420
|
-
const signInWithGithub =
|
|
13256
|
+
const signInWithGithub = useCallback27(
|
|
13421
13257
|
(redirectUrl) => signInWithOAuth({ provider: "github", redirectUrl }),
|
|
13422
13258
|
[signInWithOAuth]
|
|
13423
13259
|
);
|
|
13424
|
-
const signInWithApple =
|
|
13260
|
+
const signInWithApple = useCallback27(
|
|
13425
13261
|
(redirectUrl) => signInWithOAuth({ provider: "apple", redirectUrl }),
|
|
13426
13262
|
[signInWithOAuth]
|
|
13427
13263
|
);
|
|
13428
|
-
const signInWithDiscord =
|
|
13264
|
+
const signInWithDiscord = useCallback27(
|
|
13429
13265
|
(redirectUrl) => signInWithOAuth({ provider: "discord", redirectUrl }),
|
|
13430
13266
|
[signInWithOAuth]
|
|
13431
13267
|
);
|
|
13432
|
-
const signInWithTwitter =
|
|
13268
|
+
const signInWithTwitter = useCallback27(
|
|
13433
13269
|
(redirectUrl) => signInWithOAuth({ provider: "twitter", redirectUrl }),
|
|
13434
13270
|
[signInWithOAuth]
|
|
13435
13271
|
);
|
|
13436
|
-
const signInWithMicrosoft =
|
|
13272
|
+
const signInWithMicrosoft = useCallback27(
|
|
13437
13273
|
(redirectUrl) => signInWithOAuth({ provider: "microsoft", redirectUrl }),
|
|
13438
13274
|
[signInWithOAuth]
|
|
13439
13275
|
);
|
|
13440
|
-
const signInWithMagicLink =
|
|
13276
|
+
const signInWithMagicLink = useCallback27(
|
|
13441
13277
|
async (options) => {
|
|
13442
13278
|
const { email, redirectUrl } = options;
|
|
13443
13279
|
const resolvedRedirect = resolveRedirectUrl(redirectUrl);
|
|
@@ -13459,7 +13295,7 @@ function SylphxProviderInner({
|
|
|
13459
13295
|
},
|
|
13460
13296
|
[platformUrl, appId, resolveRedirectUrl]
|
|
13461
13297
|
);
|
|
13462
|
-
const createCheckout =
|
|
13298
|
+
const createCheckout = useCallback27(
|
|
13463
13299
|
async (planSlug, interval) => {
|
|
13464
13300
|
if (!authState.user?.id) {
|
|
13465
13301
|
throw new Error("User must be authenticated to create checkout");
|
|
@@ -13475,7 +13311,7 @@ function SylphxProviderInner({
|
|
|
13475
13311
|
},
|
|
13476
13312
|
[api, authState.user?.id]
|
|
13477
13313
|
);
|
|
13478
|
-
const openPortal =
|
|
13314
|
+
const openPortal = useCallback27(async () => {
|
|
13479
13315
|
if (!authState.user?.id) {
|
|
13480
13316
|
throw new Error("User must be signed in to access billing portal");
|
|
13481
13317
|
}
|
|
@@ -13485,12 +13321,12 @@ function SylphxProviderInner({
|
|
|
13485
13321
|
});
|
|
13486
13322
|
window.location.href = data.portalUrl;
|
|
13487
13323
|
}, [api, authState.user?.id]);
|
|
13488
|
-
const refreshSubscription =
|
|
13324
|
+
const refreshSubscription = useCallback27(async () => {
|
|
13489
13325
|
await queryClient.invalidateQueries({
|
|
13490
13326
|
queryKey: ["sylphx", appId, "subscription"]
|
|
13491
13327
|
});
|
|
13492
13328
|
}, [queryClient, appId]);
|
|
13493
|
-
const [isOnline, setIsOnline] =
|
|
13329
|
+
const [isOnline, setIsOnline] = useState30(true);
|
|
13494
13330
|
useEffect23(() => {
|
|
13495
13331
|
setIsOnline(navigator.onLine);
|
|
13496
13332
|
const handleOnline = () => setIsOnline(true);
|
|
@@ -13502,32 +13338,32 @@ function SylphxProviderInner({
|
|
|
13502
13338
|
window.removeEventListener("offline", handleOffline);
|
|
13503
13339
|
};
|
|
13504
13340
|
}, []);
|
|
13505
|
-
const queueToOfflineStorage =
|
|
13341
|
+
const queueToOfflineStorage = useCallback27(
|
|
13506
13342
|
(events) => {
|
|
13507
13343
|
try {
|
|
13508
|
-
const existingQueue =
|
|
13344
|
+
const existingQueue = storage2.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
|
|
13509
13345
|
const merged = [...existingQueue, ...events];
|
|
13510
13346
|
const trimmed = merged.length > ANALYTICS_QUEUE_LIMIT ? merged.slice(-ANALYTICS_QUEUE_LIMIT) : merged;
|
|
13511
|
-
|
|
13347
|
+
storage2.setJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE, trimmed);
|
|
13512
13348
|
} catch {
|
|
13513
13349
|
}
|
|
13514
13350
|
},
|
|
13515
|
-
[
|
|
13351
|
+
[storage2]
|
|
13516
13352
|
);
|
|
13517
|
-
const getOfflineQueue =
|
|
13353
|
+
const getOfflineQueue = useCallback27(() => {
|
|
13518
13354
|
try {
|
|
13519
|
-
return
|
|
13355
|
+
return storage2.getJSON(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE) || [];
|
|
13520
13356
|
} catch {
|
|
13521
13357
|
return [];
|
|
13522
13358
|
}
|
|
13523
|
-
}, [
|
|
13524
|
-
const clearOfflineQueue =
|
|
13359
|
+
}, [storage2]);
|
|
13360
|
+
const clearOfflineQueue = useCallback27(() => {
|
|
13525
13361
|
try {
|
|
13526
|
-
|
|
13362
|
+
storage2.remove(STORAGE_KEYS.OFFLINE_ANALYTICS_QUEUE);
|
|
13527
13363
|
} catch {
|
|
13528
13364
|
}
|
|
13529
|
-
}, [
|
|
13530
|
-
const flushAnalytics =
|
|
13365
|
+
}, [storage2]);
|
|
13366
|
+
const flushAnalytics = useCallback27(async () => {
|
|
13531
13367
|
const offlineEvents = getOfflineQueue();
|
|
13532
13368
|
const memoryEvents = analyticsQueue.current;
|
|
13533
13369
|
const allEvents = [...offlineEvents, ...memoryEvents];
|
|
@@ -13570,7 +13406,7 @@ function SylphxProviderInner({
|
|
|
13570
13406
|
return () => clearTimeout(timeout);
|
|
13571
13407
|
}
|
|
13572
13408
|
}, [isOnline, flushAnalytics]);
|
|
13573
|
-
const enqueueAnalytics =
|
|
13409
|
+
const enqueueAnalytics = useCallback27(
|
|
13574
13410
|
(type, data, eventId) => {
|
|
13575
13411
|
if (!anonymousId && !authState.user?.id) return;
|
|
13576
13412
|
const id = eventId || `${type}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
@@ -13606,7 +13442,7 @@ function SylphxProviderInner({
|
|
|
13606
13442
|
},
|
|
13607
13443
|
[authState.user?.id, anonymousId, flushAnalytics]
|
|
13608
13444
|
);
|
|
13609
|
-
const track =
|
|
13445
|
+
const track = useCallback27(
|
|
13610
13446
|
async (event, properties, options) => {
|
|
13611
13447
|
const autoEvents = ["$pageview", "$login", "$signup", "$logout", "$purchase"];
|
|
13612
13448
|
if (autoEvents.includes(event)) {
|
|
@@ -13617,7 +13453,7 @@ function SylphxProviderInner({
|
|
|
13617
13453
|
}
|
|
13618
13454
|
let enrichedConversion = options?.conversion;
|
|
13619
13455
|
if (options?.conversion || options?.destinations) {
|
|
13620
|
-
const currentClickIds = getStoredClickIds(
|
|
13456
|
+
const currentClickIds = getStoredClickIds(storage2) || clickIds;
|
|
13621
13457
|
enrichedConversion = {
|
|
13622
13458
|
// User-provided conversion data takes precedence
|
|
13623
13459
|
...options?.conversion,
|
|
@@ -13638,15 +13474,15 @@ function SylphxProviderInner({
|
|
|
13638
13474
|
conversion: enrichedConversion
|
|
13639
13475
|
});
|
|
13640
13476
|
},
|
|
13641
|
-
[enqueueAnalytics, autoTrackConfig,
|
|
13477
|
+
[enqueueAnalytics, autoTrackConfig, storage2, clickIds, authState.user]
|
|
13642
13478
|
);
|
|
13643
|
-
const page =
|
|
13479
|
+
const page = useCallback27(
|
|
13644
13480
|
async (name, properties) => {
|
|
13645
13481
|
enqueueAnalytics("page", { name, properties: properties || {} });
|
|
13646
13482
|
},
|
|
13647
13483
|
[enqueueAnalytics]
|
|
13648
13484
|
);
|
|
13649
|
-
const identify =
|
|
13485
|
+
const identify = useCallback27(
|
|
13650
13486
|
async (traits) => {
|
|
13651
13487
|
if (!authState.user?.id) return;
|
|
13652
13488
|
enqueueAnalytics("identify", {
|
|
@@ -13656,7 +13492,7 @@ function SylphxProviderInner({
|
|
|
13656
13492
|
},
|
|
13657
13493
|
[authState.user?.id, enqueueAnalytics]
|
|
13658
13494
|
);
|
|
13659
|
-
const queryAnalytics =
|
|
13495
|
+
const queryAnalytics = useCallback27(
|
|
13660
13496
|
async (analyticsQuery) => {
|
|
13661
13497
|
try {
|
|
13662
13498
|
const result = await api.post(
|
|
@@ -13675,9 +13511,9 @@ function SylphxProviderInner({
|
|
|
13675
13511
|
},
|
|
13676
13512
|
[api]
|
|
13677
13513
|
);
|
|
13678
|
-
const prevAuthStateRef =
|
|
13679
|
-
const prevSubscriptionRef =
|
|
13680
|
-
const hasTrackedInitialPageview =
|
|
13514
|
+
const prevAuthStateRef = useRef10(null);
|
|
13515
|
+
const prevSubscriptionRef = useRef10(null);
|
|
13516
|
+
const hasTrackedInitialPageview = useRef10(false);
|
|
13681
13517
|
useEffect23(() => {
|
|
13682
13518
|
if (!autoTrackConfig.pageview || hasTrackedInitialPageview.current) return;
|
|
13683
13519
|
if (!anonymousId && !authState.user?.id) return;
|
|
@@ -13725,7 +13561,7 @@ function SylphxProviderInner({
|
|
|
13725
13561
|
const userCreatedAt = currentState.user.createdAt ? new Date(currentState.user.createdAt).getTime() : 0;
|
|
13726
13562
|
const isNewUser = Date.now() - userCreatedAt < NEW_USER_THRESHOLD_MS;
|
|
13727
13563
|
const eventId = `auth_${currentState.user.id}_${isNewUser ? "signup" : "login"}_${Date.now()}`;
|
|
13728
|
-
const currentClickIds = getStoredClickIds(
|
|
13564
|
+
const currentClickIds = getStoredClickIds(storage2) || clickIds;
|
|
13729
13565
|
if (isNewUser && autoTrackConfig.signup) {
|
|
13730
13566
|
enqueueAnalytics(
|
|
13731
13567
|
"track",
|
|
@@ -13781,13 +13617,13 @@ function SylphxProviderInner({
|
|
|
13781
13617
|
);
|
|
13782
13618
|
}
|
|
13783
13619
|
prevAuthStateRef.current = currentState;
|
|
13784
|
-
}, [authState, enqueueAnalytics, autoTrackConfig,
|
|
13620
|
+
}, [authState, enqueueAnalytics, autoTrackConfig, storage2, clickIds]);
|
|
13785
13621
|
useEffect23(() => {
|
|
13786
13622
|
const prevSub = prevSubscriptionRef.current;
|
|
13787
13623
|
const currentSub = subscription;
|
|
13788
13624
|
if (autoTrackConfig.purchase && currentSub && (currentSub.status === "active" || currentSub.status === "trialing") && (!prevSub || prevSub.status !== "active" && prevSub.status !== "trialing")) {
|
|
13789
13625
|
const eventId = `purchase_${currentSub.id}_${Date.now()}`;
|
|
13790
|
-
const currentClickIds = getStoredClickIds(
|
|
13626
|
+
const currentClickIds = getStoredClickIds(storage2) || clickIds;
|
|
13791
13627
|
enqueueAnalytics(
|
|
13792
13628
|
"track",
|
|
13793
13629
|
{
|
|
@@ -13813,8 +13649,8 @@ function SylphxProviderInner({
|
|
|
13813
13649
|
);
|
|
13814
13650
|
}
|
|
13815
13651
|
prevSubscriptionRef.current = currentSub;
|
|
13816
|
-
}, [subscription, enqueueAnalytics, autoTrackConfig.purchase,
|
|
13817
|
-
const subscribePush =
|
|
13652
|
+
}, [subscription, enqueueAnalytics, autoTrackConfig.purchase, storage2, clickIds, authState.user]);
|
|
13653
|
+
const subscribePush = useCallback27(async () => {
|
|
13818
13654
|
if (!pushSupported || !vapidPublicKey) return false;
|
|
13819
13655
|
try {
|
|
13820
13656
|
const registration = await navigator.serviceWorker.ready;
|
|
@@ -13838,7 +13674,7 @@ function SylphxProviderInner({
|
|
|
13838
13674
|
return false;
|
|
13839
13675
|
}
|
|
13840
13676
|
}, [pushSupported, vapidPublicKey, api]);
|
|
13841
|
-
const unsubscribePush =
|
|
13677
|
+
const unsubscribePush = useCallback27(async () => {
|
|
13842
13678
|
try {
|
|
13843
13679
|
const registration = await navigator.serviceWorker.ready;
|
|
13844
13680
|
const sub = await registration.pushManager.getSubscription();
|
|
@@ -13850,7 +13686,7 @@ function SylphxProviderInner({
|
|
|
13850
13686
|
} catch {
|
|
13851
13687
|
}
|
|
13852
13688
|
}, [api]);
|
|
13853
|
-
const updatePushPreferences =
|
|
13689
|
+
const updatePushPreferences = useCallback27(
|
|
13854
13690
|
async (prefs) => {
|
|
13855
13691
|
if (prefs.enabled === false) {
|
|
13856
13692
|
await unsubscribePush();
|
|
@@ -13865,7 +13701,7 @@ function SylphxProviderInner({
|
|
|
13865
13701
|
[pushPreferences, unsubscribePush, queryClient, appId]
|
|
13866
13702
|
);
|
|
13867
13703
|
const mobilePushQueryKey = ["sylphx", appId, "mobilePush"];
|
|
13868
|
-
const registerMobileDevice =
|
|
13704
|
+
const registerMobileDevice = useCallback27(
|
|
13869
13705
|
async (options) => {
|
|
13870
13706
|
const result = await api.post(
|
|
13871
13707
|
"/notifications/mobile/register",
|
|
@@ -13880,7 +13716,7 @@ function SylphxProviderInner({
|
|
|
13880
13716
|
// biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
|
|
13881
13717
|
[api, queryClient, mobilePushQueryKey]
|
|
13882
13718
|
);
|
|
13883
|
-
const unregisterMobileDevice =
|
|
13719
|
+
const unregisterMobileDevice = useCallback27(
|
|
13884
13720
|
async (token) => {
|
|
13885
13721
|
await api.post("/notifications/mobile/unregister", { token });
|
|
13886
13722
|
void queryClient.invalidateQueries({ queryKey: mobilePushQueryKey });
|
|
@@ -13888,7 +13724,7 @@ function SylphxProviderInner({
|
|
|
13888
13724
|
// biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
|
|
13889
13725
|
[api, queryClient, mobilePushQueryKey]
|
|
13890
13726
|
);
|
|
13891
|
-
const getMobilePushPreferences =
|
|
13727
|
+
const getMobilePushPreferences = useCallback27(async () => {
|
|
13892
13728
|
await queryClient.invalidateQueries({ queryKey: mobilePushQueryKey });
|
|
13893
13729
|
const data = queryClient.getQueryData(mobilePushQueryKey);
|
|
13894
13730
|
if (!data?.preferences) {
|
|
@@ -13896,25 +13732,25 @@ function SylphxProviderInner({
|
|
|
13896
13732
|
}
|
|
13897
13733
|
return data.preferences;
|
|
13898
13734
|
}, [queryClient, mobilePushQueryKey]);
|
|
13899
|
-
const copyReferralCode =
|
|
13735
|
+
const copyReferralCode = useCallback27(async () => {
|
|
13900
13736
|
if (referralCode) {
|
|
13901
13737
|
await navigator.clipboard.writeText(referralCode);
|
|
13902
13738
|
}
|
|
13903
13739
|
}, [referralCode]);
|
|
13904
|
-
const regenerateReferralCode =
|
|
13740
|
+
const regenerateReferralCode = useCallback27(async () => {
|
|
13905
13741
|
const data = await api.post("/referrals/code/regenerate");
|
|
13906
13742
|
void queryClient.invalidateQueries({
|
|
13907
13743
|
queryKey: ["sylphx", appId, "referrals"]
|
|
13908
13744
|
});
|
|
13909
13745
|
return data.code;
|
|
13910
13746
|
}, [api, queryClient, appId]);
|
|
13911
|
-
const redeemReferralCode =
|
|
13747
|
+
const redeemReferralCode = useCallback27(
|
|
13912
13748
|
async (code, _defaults) => {
|
|
13913
13749
|
return api.post("/referrals/redeem", { code });
|
|
13914
13750
|
},
|
|
13915
13751
|
[api]
|
|
13916
13752
|
);
|
|
13917
|
-
const getReferralLeaderboard =
|
|
13753
|
+
const getReferralLeaderboard = useCallback27(
|
|
13918
13754
|
async (options) => {
|
|
13919
13755
|
return api.get("/referrals/leaderboard", {
|
|
13920
13756
|
limit: options?.limit?.toString(),
|
|
@@ -13923,7 +13759,7 @@ function SylphxProviderInner({
|
|
|
13923
13759
|
},
|
|
13924
13760
|
[api]
|
|
13925
13761
|
);
|
|
13926
|
-
const getStreak =
|
|
13762
|
+
const getStreak = useCallback27(
|
|
13927
13763
|
async (streakId, defaults, userTimezone) => {
|
|
13928
13764
|
if (!authState.user?.id) {
|
|
13929
13765
|
throw new Error("User must be authenticated to get streak");
|
|
@@ -13936,7 +13772,7 @@ function SylphxProviderInner({
|
|
|
13936
13772
|
},
|
|
13937
13773
|
[api, authState.user?.id]
|
|
13938
13774
|
);
|
|
13939
|
-
const recordStreakActivity =
|
|
13775
|
+
const recordStreakActivity = useCallback27(
|
|
13940
13776
|
async (streakId, metadata, defaults) => {
|
|
13941
13777
|
if (!authState.user?.id) {
|
|
13942
13778
|
throw new Error("User must be authenticated to record activity");
|
|
@@ -13949,7 +13785,7 @@ function SylphxProviderInner({
|
|
|
13949
13785
|
},
|
|
13950
13786
|
[api, authState.user?.id]
|
|
13951
13787
|
);
|
|
13952
|
-
const recoverStreak =
|
|
13788
|
+
const recoverStreak = useCallback27(
|
|
13953
13789
|
async (streakId) => {
|
|
13954
13790
|
if (!authState.user?.id) {
|
|
13955
13791
|
throw new Error("User must be authenticated to recover streak");
|
|
@@ -13961,7 +13797,7 @@ function SylphxProviderInner({
|
|
|
13961
13797
|
},
|
|
13962
13798
|
[api, authState.user?.id]
|
|
13963
13799
|
);
|
|
13964
|
-
const getEngagementLeaderboard =
|
|
13800
|
+
const getEngagementLeaderboard = useCallback27(
|
|
13965
13801
|
async (leaderboardId, options) => {
|
|
13966
13802
|
return api.get(`/engagement/leaderboards/${leaderboardId}`, {
|
|
13967
13803
|
userId: authState.user?.id ?? void 0,
|
|
@@ -13972,7 +13808,7 @@ function SylphxProviderInner({
|
|
|
13972
13808
|
},
|
|
13973
13809
|
[api, authState.user?.id]
|
|
13974
13810
|
);
|
|
13975
|
-
const submitScore =
|
|
13811
|
+
const submitScore = useCallback27(
|
|
13976
13812
|
async (leaderboardId, value, metadata, defaults) => {
|
|
13977
13813
|
if (!authState.user?.id) {
|
|
13978
13814
|
throw new Error("User must be authenticated to submit score");
|
|
@@ -13986,7 +13822,7 @@ function SylphxProviderInner({
|
|
|
13986
13822
|
},
|
|
13987
13823
|
[api, authState.user?.id]
|
|
13988
13824
|
);
|
|
13989
|
-
const getAchievements =
|
|
13825
|
+
const getAchievements = useCallback27(async () => {
|
|
13990
13826
|
if (!authState.user?.id) {
|
|
13991
13827
|
throw new Error("User must be authenticated to get achievements");
|
|
13992
13828
|
}
|
|
@@ -13994,7 +13830,7 @@ function SylphxProviderInner({
|
|
|
13994
13830
|
userId: authState.user.id
|
|
13995
13831
|
});
|
|
13996
13832
|
}, [api, authState.user?.id]);
|
|
13997
|
-
const unlockAchievement =
|
|
13833
|
+
const unlockAchievement = useCallback27(
|
|
13998
13834
|
async (achievementId, defaults) => {
|
|
13999
13835
|
if (!authState.user?.id) {
|
|
14000
13836
|
throw new Error("User must be authenticated to unlock achievement");
|
|
@@ -14006,7 +13842,7 @@ function SylphxProviderInner({
|
|
|
14006
13842
|
},
|
|
14007
13843
|
[api, authState.user?.id]
|
|
14008
13844
|
);
|
|
14009
|
-
const incrementAchievementProgress =
|
|
13845
|
+
const incrementAchievementProgress = useCallback27(
|
|
14010
13846
|
async (achievementId, amount, defaults) => {
|
|
14011
13847
|
if (!authState.user?.id) {
|
|
14012
13848
|
throw new Error("User must be authenticated to increment progress");
|
|
@@ -14020,10 +13856,10 @@ function SylphxProviderInner({
|
|
|
14020
13856
|
[api, authState.user?.id]
|
|
14021
13857
|
);
|
|
14022
13858
|
const inboxQueryKey = ["sylphx", appId, "inbox"];
|
|
14023
|
-
const refreshInbox =
|
|
13859
|
+
const refreshInbox = useCallback27(async () => {
|
|
14024
13860
|
await queryClient.invalidateQueries({ queryKey: inboxQueryKey });
|
|
14025
13861
|
}, [queryClient, inboxQueryKey]);
|
|
14026
|
-
const markInboxMessageAsRead =
|
|
13862
|
+
const markInboxMessageAsRead = useCallback27(
|
|
14027
13863
|
async (messageId) => {
|
|
14028
13864
|
const previousData = queryClient.getQueryData(inboxQueryKey);
|
|
14029
13865
|
queryClient.setQueryData(inboxQueryKey, (old) => {
|
|
@@ -14046,7 +13882,7 @@ function SylphxProviderInner({
|
|
|
14046
13882
|
// biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
|
|
14047
13883
|
[api, queryClient, inboxQueryKey]
|
|
14048
13884
|
);
|
|
14049
|
-
const markAllInboxMessagesAsRead =
|
|
13885
|
+
const markAllInboxMessagesAsRead = useCallback27(async () => {
|
|
14050
13886
|
const previousData = queryClient.getQueryData(inboxQueryKey);
|
|
14051
13887
|
queryClient.setQueryData(inboxQueryKey, (old) => {
|
|
14052
13888
|
if (!old) return old;
|
|
@@ -14067,7 +13903,7 @@ function SylphxProviderInner({
|
|
|
14067
13903
|
throw err;
|
|
14068
13904
|
}
|
|
14069
13905
|
}, [api, queryClient, inboxQueryKey]);
|
|
14070
|
-
const dismissInboxMessage =
|
|
13906
|
+
const dismissInboxMessage = useCallback27(
|
|
14071
13907
|
async (messageId) => {
|
|
14072
13908
|
const previousData = queryClient.getQueryData(inboxQueryKey);
|
|
14073
13909
|
queryClient.setQueryData(inboxQueryKey, (old) => {
|
|
@@ -14087,7 +13923,7 @@ function SylphxProviderInner({
|
|
|
14087
13923
|
// biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
|
|
14088
13924
|
[api, queryClient, inboxQueryKey]
|
|
14089
13925
|
);
|
|
14090
|
-
const recordInboxMessageClick =
|
|
13926
|
+
const recordInboxMessageClick = useCallback27(
|
|
14091
13927
|
async (messageId, action) => {
|
|
14092
13928
|
queryClient.setQueryData(inboxQueryKey, (old) => {
|
|
14093
13929
|
if (!old) return old;
|
|
@@ -14109,7 +13945,7 @@ function SylphxProviderInner({
|
|
|
14109
13945
|
// biome-ignore lint/correctness/useExhaustiveDependencies: query key is stable
|
|
14110
13946
|
[api, queryClient, inboxQueryKey]
|
|
14111
13947
|
);
|
|
14112
|
-
const updateInboxPreferences =
|
|
13948
|
+
const updateInboxPreferences = useCallback27(
|
|
14113
13949
|
async (prefs) => {
|
|
14114
13950
|
const previousData = queryClient.getQueryData(inboxQueryKey);
|
|
14115
13951
|
queryClient.setQueryData(inboxQueryKey, (old) => {
|
|
@@ -14147,15 +13983,6 @@ function SylphxProviderInner({
|
|
|
14147
13983
|
}),
|
|
14148
13984
|
[api, anonymousId, authState.user?.id, config2]
|
|
14149
13985
|
);
|
|
14150
|
-
const storageValue = useMemo9(
|
|
14151
|
-
() => createStorageValue({
|
|
14152
|
-
api,
|
|
14153
|
-
platformUrl,
|
|
14154
|
-
appId,
|
|
14155
|
-
userId: authState.user?.id ?? null
|
|
14156
|
-
}),
|
|
14157
|
-
[api, platformUrl, appId, authState.user?.id]
|
|
14158
|
-
);
|
|
14159
13986
|
const newsletterValue = useMemo9(
|
|
14160
13987
|
() => createNewsletterValue({ api }),
|
|
14161
13988
|
[api]
|
|
@@ -14678,12 +14505,12 @@ function SylphxProviderInner({
|
|
|
14678
14505
|
resolvedRef
|
|
14679
14506
|
]
|
|
14680
14507
|
);
|
|
14681
|
-
return /* @__PURE__ */ jsx24(AuthContext.Provider, { value: authValue, children: /* @__PURE__ */ jsx24(SdkAuthContext.Provider, { value: sdkAuthValue, children: /* @__PURE__ */ jsx24(UserContext.Provider, { value: userValue, children: /* @__PURE__ */ jsx24(SecurityContext.Provider, { value: securityValue, children: /* @__PURE__ */ jsx24(PlatformContext.Provider, { value: platformValue, children: /* @__PURE__ */ jsx24(
|
|
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 }) }) }) }) }) }) }) }) }) }) }) }) });
|
|
14682
14509
|
}
|
|
14683
14510
|
|
|
14684
14511
|
// src/react/rbac-hooks.ts
|
|
14685
14512
|
import { useQuery as useQuery6, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
|
|
14686
|
-
import { useCallback as
|
|
14513
|
+
import { useCallback as useCallback28, useContext as useContext16, useMemo as useMemo10 } from "react";
|
|
14687
14514
|
|
|
14688
14515
|
// src/permissions.ts
|
|
14689
14516
|
async function listPermissions(config2) {
|
|
@@ -14745,7 +14572,7 @@ function usePermissions() {
|
|
|
14745
14572
|
staleTime: 3e4
|
|
14746
14573
|
// 30s — permissions change rarely
|
|
14747
14574
|
});
|
|
14748
|
-
const refresh =
|
|
14575
|
+
const refresh = useCallback28(async () => {
|
|
14749
14576
|
await queryClient.invalidateQueries({ queryKey: rbacKeys.permissions() });
|
|
14750
14577
|
}, [queryClient]);
|
|
14751
14578
|
return {
|
|
@@ -14768,7 +14595,7 @@ function useRoles() {
|
|
|
14768
14595
|
staleTime: 3e4
|
|
14769
14596
|
// 30s — roles change rarely
|
|
14770
14597
|
});
|
|
14771
|
-
const refresh =
|
|
14598
|
+
const refresh = useCallback28(async () => {
|
|
14772
14599
|
await queryClient.invalidateQueries({ queryKey: rbacKeys.roles() });
|
|
14773
14600
|
}, [queryClient]);
|
|
14774
14601
|
return {
|
|
@@ -14794,7 +14621,7 @@ function useMemberPermissions(orgIdOrSlug, memberId) {
|
|
|
14794
14621
|
staleTime: 15e3
|
|
14795
14622
|
// 15s — member permissions may change more frequently
|
|
14796
14623
|
});
|
|
14797
|
-
const refresh =
|
|
14624
|
+
const refresh = useCallback28(async () => {
|
|
14798
14625
|
if (orgIdOrSlug && memberId) {
|
|
14799
14626
|
await queryClient.invalidateQueries({
|
|
14800
14627
|
queryKey: rbacKeys.memberPermissions(orgIdOrSlug, memberId)
|
|
@@ -14822,236 +14649,663 @@ function useHasPermission(permissions, required) {
|
|
|
14822
14649
|
}
|
|
14823
14650
|
|
|
14824
14651
|
// src/react/storage-hooks.ts
|
|
14825
|
-
import {
|
|
14826
|
-
|
|
14827
|
-
|
|
14828
|
-
|
|
14829
|
-
|
|
14830
|
-
|
|
14831
|
-
|
|
14832
|
-
|
|
14833
|
-
|
|
14834
|
-
|
|
14835
|
-
|
|
14836
|
-
|
|
14837
|
-
|
|
14838
|
-
|
|
14839
|
-
|
|
14840
|
-
|
|
14841
|
-
|
|
14842
|
-
|
|
14843
|
-
|
|
14844
|
-
|
|
14845
|
-
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;
|
|
14846
14672
|
}
|
|
14847
|
-
|
|
14848
|
-
|
|
14849
|
-
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
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 = () => {
|
|
14859
14872
|
try {
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
signal,
|
|
14863
|
-
onProgress: handleProgress
|
|
14864
|
-
});
|
|
14865
|
-
setProgress(100);
|
|
14866
|
-
return url;
|
|
14867
|
-
} catch (err) {
|
|
14868
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
14869
|
-
setWasCancelled(true);
|
|
14870
|
-
throw err;
|
|
14871
|
-
}
|
|
14872
|
-
const error = err instanceof Error ? err : new Error("Upload failed");
|
|
14873
|
-
setUploadError(error);
|
|
14874
|
-
throw error;
|
|
14875
|
-
} finally {
|
|
14876
|
-
abortControllerRef.current = null;
|
|
14877
|
-
setIsUploading(false);
|
|
14873
|
+
xhr.abort();
|
|
14874
|
+
} catch {
|
|
14878
14875
|
}
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
|
|
14882
|
-
|
|
14883
|
-
|
|
14884
|
-
|
|
14885
|
-
|
|
14886
|
-
|
|
14887
|
-
|
|
14888
|
-
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
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)) {
|
|
14892
14909
|
try {
|
|
14893
|
-
|
|
14894
|
-
|
|
14895
|
-
});
|
|
14896
|
-
setProgress(100);
|
|
14897
|
-
return url;
|
|
14898
|
-
} catch (err) {
|
|
14899
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
14900
|
-
setWasCancelled(true);
|
|
14901
|
-
throw err;
|
|
14902
|
-
}
|
|
14903
|
-
const error = err instanceof Error ? err : new Error("Avatar upload failed");
|
|
14904
|
-
setUploadError(error);
|
|
14905
|
-
throw error;
|
|
14906
|
-
} finally {
|
|
14907
|
-
abortControllerRef.current = null;
|
|
14908
|
-
setIsUploading(false);
|
|
14910
|
+
xhr.setRequestHeader(k2, v2);
|
|
14911
|
+
} catch {
|
|
14909
14912
|
}
|
|
14910
|
-
}
|
|
14911
|
-
|
|
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
|
+
}
|
|
14912
15087
|
);
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
|
|
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();
|
|
14916
15220
|
},
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
|
|
14921
|
-
|
|
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 ?? {});
|
|
14922
15228
|
},
|
|
14923
|
-
|
|
14924
|
-
|
|
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;
|
|
14925
15241
|
return {
|
|
14926
15242
|
upload,
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
14938
|
-
|
|
14939
|
-
|
|
14940
|
-
|
|
14941
|
-
const [isUploading, setIsUploading] = useState32(false);
|
|
14942
|
-
const [progress, setProgress] = useState32(0);
|
|
14943
|
-
const [bytesUploaded, setBytesUploaded] = useState32(0);
|
|
14944
|
-
const [bytesTotal, setBytesTotal] = useState32(0);
|
|
14945
|
-
const [error, setError] = useState32(null);
|
|
14946
|
-
const [wasCancelled, setWasCancelled] = useState32(false);
|
|
14947
|
-
const [url, setUrl] = useState32(null);
|
|
14948
|
-
const abortControllerRef = useRef12(null);
|
|
14949
|
-
const handleProgress = useCallback30((event) => {
|
|
14950
|
-
setProgress(event.progress);
|
|
14951
|
-
setBytesUploaded(event.loaded);
|
|
14952
|
-
setBytesTotal(event.total);
|
|
14953
|
-
}, []);
|
|
14954
|
-
const cancel = useCallback30(() => {
|
|
14955
|
-
if (abortControllerRef.current) {
|
|
14956
|
-
abortControllerRef.current.abort();
|
|
14957
|
-
abortControllerRef.current = null;
|
|
14958
|
-
setWasCancelled(true);
|
|
14959
|
-
setIsUploading(false);
|
|
14960
|
-
options.onCancel?.();
|
|
14961
|
-
}
|
|
14962
|
-
}, [options]);
|
|
14963
|
-
const upload = useCallback30(
|
|
14964
|
-
async (file) => {
|
|
14965
|
-
if (options.accept && options.accept.length > 0) {
|
|
14966
|
-
const isAccepted = options.accept.some((type) => {
|
|
14967
|
-
if (type.endsWith("/*")) {
|
|
14968
|
-
const category = type.slice(0, -2);
|
|
14969
|
-
return file.type.startsWith(category);
|
|
14970
|
-
}
|
|
14971
|
-
return file.type === type;
|
|
14972
|
-
});
|
|
14973
|
-
if (!isAccepted) {
|
|
14974
|
-
const err = new Error(`File type ${file.type} not accepted`);
|
|
14975
|
-
setError(err);
|
|
14976
|
-
options.onError?.(err);
|
|
14977
|
-
throw err;
|
|
14978
|
-
}
|
|
14979
|
-
}
|
|
14980
|
-
if (options.maxSize && file.size > options.maxSize) {
|
|
14981
|
-
const maxMB = (options.maxSize / 1024 / 1024).toFixed(1);
|
|
14982
|
-
const err = new Error(`File size exceeds ${maxMB}MB limit`);
|
|
14983
|
-
setError(err);
|
|
14984
|
-
options.onError?.(err);
|
|
14985
|
-
throw err;
|
|
14986
|
-
}
|
|
14987
|
-
const controller = new AbortController();
|
|
14988
|
-
abortControllerRef.current = controller;
|
|
14989
|
-
setIsUploading(true);
|
|
14990
|
-
setProgress(0);
|
|
14991
|
-
setBytesUploaded(0);
|
|
14992
|
-
setBytesTotal(file.size);
|
|
14993
|
-
setError(null);
|
|
14994
|
-
setWasCancelled(false);
|
|
14995
|
-
setUrl(null);
|
|
14996
|
-
try {
|
|
14997
|
-
const uploadedUrl = await ctx.upload(file, {
|
|
14998
|
-
path: options.path,
|
|
14999
|
-
signal: controller.signal,
|
|
15000
|
-
onProgress: handleProgress
|
|
15001
|
-
});
|
|
15002
|
-
setProgress(100);
|
|
15003
|
-
setUrl(uploadedUrl);
|
|
15004
|
-
options.onSuccess?.(uploadedUrl);
|
|
15005
|
-
return uploadedUrl;
|
|
15006
|
-
} catch (err) {
|
|
15007
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
15008
|
-
setWasCancelled(true);
|
|
15009
|
-
options.onCancel?.();
|
|
15010
|
-
throw err;
|
|
15011
|
-
}
|
|
15012
|
-
const uploadError = err instanceof Error ? err : new Error("Upload failed");
|
|
15013
|
-
setError(uploadError);
|
|
15014
|
-
options.onError?.(uploadError);
|
|
15015
|
-
throw uploadError;
|
|
15016
|
-
} finally {
|
|
15017
|
-
abortControllerRef.current = null;
|
|
15018
|
-
setIsUploading(false);
|
|
15019
|
-
}
|
|
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);
|
|
15020
15257
|
},
|
|
15021
|
-
|
|
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
|
|
15022
15271
|
);
|
|
15023
|
-
const
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
|
|
15031
|
-
|
|
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]);
|
|
15032
15293
|
return {
|
|
15033
|
-
|
|
15034
|
-
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
bytesUploaded,
|
|
15038
|
-
bytesTotal,
|
|
15039
|
-
error,
|
|
15040
|
-
isError: error !== null,
|
|
15041
|
-
wasCancelled,
|
|
15042
|
-
url,
|
|
15043
|
-
reset
|
|
15294
|
+
files: pages?.files ?? query.data?.files ?? [],
|
|
15295
|
+
nextCursor: pages?.nextCursor ?? query.data?.nextCursor ?? null,
|
|
15296
|
+
isLoading: query.isLoading,
|
|
15297
|
+
loadMore
|
|
15044
15298
|
};
|
|
15045
15299
|
}
|
|
15046
15300
|
|
|
15047
15301
|
// src/react/task-hooks.ts
|
|
15048
|
-
import { useQuery as
|
|
15049
|
-
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";
|
|
15050
15304
|
function useTasks() {
|
|
15051
15305
|
const ctx = useTasksContext();
|
|
15052
|
-
const [isLoading, setIsLoading] =
|
|
15053
|
-
const [error, setError] =
|
|
15054
|
-
const isAvailable =
|
|
15306
|
+
const [isLoading, setIsLoading] = useState32(false);
|
|
15307
|
+
const [error, setError] = useState32(null);
|
|
15308
|
+
const isAvailable = useCallback30(async () => {
|
|
15055
15309
|
try {
|
|
15056
15310
|
const status = await ctx.checkStatus();
|
|
15057
15311
|
return status.available;
|
|
@@ -15059,7 +15313,7 @@ function useTasks() {
|
|
|
15059
15313
|
return false;
|
|
15060
15314
|
}
|
|
15061
15315
|
}, [ctx]);
|
|
15062
|
-
const schedule =
|
|
15316
|
+
const schedule = useCallback30(
|
|
15063
15317
|
async (options) => {
|
|
15064
15318
|
setIsLoading(true);
|
|
15065
15319
|
setError(null);
|
|
@@ -15075,7 +15329,7 @@ function useTasks() {
|
|
|
15075
15329
|
},
|
|
15076
15330
|
[ctx]
|
|
15077
15331
|
);
|
|
15078
|
-
const createCron =
|
|
15332
|
+
const createCron = useCallback30(
|
|
15079
15333
|
async (options) => {
|
|
15080
15334
|
setIsLoading(true);
|
|
15081
15335
|
setError(null);
|
|
@@ -15091,7 +15345,7 @@ function useTasks() {
|
|
|
15091
15345
|
},
|
|
15092
15346
|
[ctx]
|
|
15093
15347
|
);
|
|
15094
|
-
const pauseCron =
|
|
15348
|
+
const pauseCron = useCallback30(
|
|
15095
15349
|
async (scheduleId) => {
|
|
15096
15350
|
setIsLoading(true);
|
|
15097
15351
|
setError(null);
|
|
@@ -15107,7 +15361,7 @@ function useTasks() {
|
|
|
15107
15361
|
},
|
|
15108
15362
|
[ctx]
|
|
15109
15363
|
);
|
|
15110
|
-
const resumeCron =
|
|
15364
|
+
const resumeCron = useCallback30(
|
|
15111
15365
|
async (scheduleId) => {
|
|
15112
15366
|
setIsLoading(true);
|
|
15113
15367
|
setError(null);
|
|
@@ -15123,7 +15377,7 @@ function useTasks() {
|
|
|
15123
15377
|
},
|
|
15124
15378
|
[ctx]
|
|
15125
15379
|
);
|
|
15126
|
-
const deleteCron =
|
|
15380
|
+
const deleteCron = useCallback30(
|
|
15127
15381
|
async (scheduleId) => {
|
|
15128
15382
|
setIsLoading(true);
|
|
15129
15383
|
setError(null);
|
|
@@ -15139,7 +15393,7 @@ function useTasks() {
|
|
|
15139
15393
|
},
|
|
15140
15394
|
[ctx]
|
|
15141
15395
|
);
|
|
15142
|
-
const getJob =
|
|
15396
|
+
const getJob = useCallback30(
|
|
15143
15397
|
async (jobId) => {
|
|
15144
15398
|
try {
|
|
15145
15399
|
return await ctx.getJob(jobId);
|
|
@@ -15151,7 +15405,7 @@ function useTasks() {
|
|
|
15151
15405
|
},
|
|
15152
15406
|
[ctx]
|
|
15153
15407
|
);
|
|
15154
|
-
const listJobs =
|
|
15408
|
+
const listJobs = useCallback30(
|
|
15155
15409
|
async (options = {}) => {
|
|
15156
15410
|
try {
|
|
15157
15411
|
const result = await ctx.listJobs(options);
|
|
@@ -15164,7 +15418,7 @@ function useTasks() {
|
|
|
15164
15418
|
},
|
|
15165
15419
|
[ctx]
|
|
15166
15420
|
);
|
|
15167
|
-
const cancelJob =
|
|
15421
|
+
const cancelJob = useCallback30(
|
|
15168
15422
|
async (jobId) => {
|
|
15169
15423
|
setIsLoading(true);
|
|
15170
15424
|
setError(null);
|
|
@@ -15197,19 +15451,19 @@ function useTasks() {
|
|
|
15197
15451
|
|
|
15198
15452
|
// src/react/webhooks-hooks.ts
|
|
15199
15453
|
init_constants();
|
|
15200
|
-
import { useInfiniteQuery as useInfiniteQuery2, useQuery as
|
|
15201
|
-
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";
|
|
15202
15456
|
function useWebhooks() {
|
|
15203
15457
|
const ctx = useWebhooksContext();
|
|
15204
|
-
const queryClient =
|
|
15205
|
-
const configQuery =
|
|
15458
|
+
const queryClient = useQueryClient8();
|
|
15459
|
+
const configQuery = useQuery9({
|
|
15206
15460
|
queryKey: ["sylphx", "webhooks", "config"],
|
|
15207
15461
|
queryFn: () => ctx.getConfig(),
|
|
15208
15462
|
staleTime: STALE_TIME_STABLE_MS
|
|
15209
15463
|
// 5 min - config rarely changes
|
|
15210
15464
|
});
|
|
15211
15465
|
const config2 = configQuery.data;
|
|
15212
|
-
const updateConfig =
|
|
15466
|
+
const updateConfig = useCallback31(
|
|
15213
15467
|
async (options) => {
|
|
15214
15468
|
const result = await ctx.updateConfig(options);
|
|
15215
15469
|
await queryClient.invalidateQueries({
|
|
@@ -15219,7 +15473,7 @@ function useWebhooks() {
|
|
|
15219
15473
|
},
|
|
15220
15474
|
[ctx, queryClient]
|
|
15221
15475
|
);
|
|
15222
|
-
const refresh =
|
|
15476
|
+
const refresh = useCallback31(async () => {
|
|
15223
15477
|
await queryClient.invalidateQueries({
|
|
15224
15478
|
queryKey: ["sylphx", "webhooks", "config"]
|
|
15225
15479
|
});
|
|
@@ -15236,7 +15490,7 @@ function useWebhooks() {
|
|
|
15236
15490
|
function useWebhookDeliveries(options = {}) {
|
|
15237
15491
|
const { status, event, limit = 50, skip = false, refetchInterval } = options;
|
|
15238
15492
|
const ctx = useWebhooksContext();
|
|
15239
|
-
const queryClient =
|
|
15493
|
+
const queryClient = useQueryClient8();
|
|
15240
15494
|
const deliveriesQuery = useInfiniteQuery2({
|
|
15241
15495
|
queryKey: ["sylphx", "webhooks", "deliveries", { status, event, limit }],
|
|
15242
15496
|
queryFn: async ({ pageParam = 0 }) => {
|
|
@@ -15257,7 +15511,7 @@ function useWebhookDeliveries(options = {}) {
|
|
|
15257
15511
|
});
|
|
15258
15512
|
const deliveries = deliveriesQuery.data?.pages.flatMap((page) => page.deliveries) ?? [];
|
|
15259
15513
|
const total = deliveriesQuery.data?.pages[0]?.total ?? 0;
|
|
15260
|
-
const replay =
|
|
15514
|
+
const replay = useCallback31(
|
|
15261
15515
|
async (deliveryId) => {
|
|
15262
15516
|
const result = await ctx.replayDelivery(deliveryId);
|
|
15263
15517
|
await queryClient.invalidateQueries({
|
|
@@ -15267,12 +15521,12 @@ function useWebhookDeliveries(options = {}) {
|
|
|
15267
15521
|
},
|
|
15268
15522
|
[ctx, queryClient]
|
|
15269
15523
|
);
|
|
15270
|
-
const refresh =
|
|
15524
|
+
const refresh = useCallback31(async () => {
|
|
15271
15525
|
await queryClient.invalidateQueries({
|
|
15272
15526
|
queryKey: ["sylphx", "webhooks", "deliveries"]
|
|
15273
15527
|
});
|
|
15274
15528
|
}, [queryClient]);
|
|
15275
|
-
const loadMore =
|
|
15529
|
+
const loadMore = useCallback31(async () => {
|
|
15276
15530
|
if (deliveriesQuery.hasNextPage && !deliveriesQuery.isFetchingNextPage) {
|
|
15277
15531
|
await deliveriesQuery.fetchNextPage();
|
|
15278
15532
|
}
|
|
@@ -15291,14 +15545,14 @@ function useWebhookDeliveries(options = {}) {
|
|
|
15291
15545
|
}
|
|
15292
15546
|
function useWebhookStats(period = "week") {
|
|
15293
15547
|
const ctx = useWebhooksContext();
|
|
15294
|
-
const queryClient =
|
|
15295
|
-
const statsQuery =
|
|
15548
|
+
const queryClient = useQueryClient8();
|
|
15549
|
+
const statsQuery = useQuery9({
|
|
15296
15550
|
queryKey: ["sylphx", "webhooks", "stats", period],
|
|
15297
15551
|
queryFn: () => ctx.getStats(period),
|
|
15298
15552
|
staleTime: STALE_TIME_MODERATE_MS
|
|
15299
15553
|
// 2 min - stats aggregate data
|
|
15300
15554
|
});
|
|
15301
|
-
const refresh =
|
|
15555
|
+
const refresh = useCallback31(async () => {
|
|
15302
15556
|
await queryClient.invalidateQueries({
|
|
15303
15557
|
queryKey: ["sylphx", "webhooks", "stats", period]
|
|
15304
15558
|
});
|
|
@@ -15313,7 +15567,7 @@ function useWebhookStats(period = "week") {
|
|
|
15313
15567
|
|
|
15314
15568
|
// src/react/ui/account-section.tsx
|
|
15315
15569
|
init_constants();
|
|
15316
|
-
import { useCallback as
|
|
15570
|
+
import { useCallback as useCallback32, useEffect as useEffect25, useId as useId4, useState as useState33 } from "react";
|
|
15317
15571
|
import { Fragment as Fragment18, jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
15318
15572
|
function AccountSection(props) {
|
|
15319
15573
|
return /* @__PURE__ */ jsx25(RequireSdk, { services: ["auth"], componentType: "account", theme: props.theme, children: /* @__PURE__ */ jsx25(AccountSectionInner, { ...props }) });
|
|
@@ -15335,22 +15589,22 @@ function AccountSectionInner({
|
|
|
15335
15589
|
const styles2 = baseStyles(theme);
|
|
15336
15590
|
const newEmailId = useId4();
|
|
15337
15591
|
const emailPasswordId = useId4();
|
|
15338
|
-
const [error, setError] =
|
|
15339
|
-
const [success, setSuccess] =
|
|
15340
|
-
const [showEmailChangeForm, setShowEmailChangeForm] =
|
|
15341
|
-
const [newEmail, setNewEmail] =
|
|
15342
|
-
const [emailPassword, setEmailPassword] =
|
|
15343
|
-
const [isChangingEmail, setIsChangingEmail] =
|
|
15344
|
-
const [isExporting, setIsExporting] =
|
|
15345
|
-
const [exportUrl, setExportUrl] =
|
|
15346
|
-
const [showDeleteConfirm, setShowDeleteConfirm] =
|
|
15347
|
-
const [deleteConfirmText, setDeleteConfirmText] =
|
|
15348
|
-
const [deletePassword, setDeletePassword] =
|
|
15349
|
-
const [delete2FACode, setDelete2FACode] =
|
|
15350
|
-
const [isDeleting, setIsDeleting] =
|
|
15351
|
-
const [deleteStep, setDeleteStep] =
|
|
15352
|
-
const [has2FAEnabled, setHas2FAEnabled] =
|
|
15353
|
-
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);
|
|
15354
15608
|
useEffect25(() => {
|
|
15355
15609
|
injectGlobalStyles();
|
|
15356
15610
|
}, []);
|
|
@@ -15404,7 +15658,7 @@ function AccountSectionInner({
|
|
|
15404
15658
|
setIsExporting(false);
|
|
15405
15659
|
}
|
|
15406
15660
|
};
|
|
15407
|
-
const checkSecurityStatus =
|
|
15661
|
+
const checkSecurityStatus = useCallback32(async () => {
|
|
15408
15662
|
setIsChecking2FA(true);
|
|
15409
15663
|
try {
|
|
15410
15664
|
const status = await securityContext.getTwoFactorStatus();
|
|
@@ -15940,7 +16194,7 @@ function ShieldIcon({ size = 24, color = "currentColor" }) {
|
|
|
15940
16194
|
}
|
|
15941
16195
|
|
|
15942
16196
|
// src/react/ui/analytics-dashboard.tsx
|
|
15943
|
-
import { useEffect as useEffect26, useState as
|
|
16197
|
+
import { useEffect as useEffect26, useState as useState34 } from "react";
|
|
15944
16198
|
import { Fragment as Fragment19, jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
15945
16199
|
function EventViewer({
|
|
15946
16200
|
theme = defaultTheme,
|
|
@@ -15954,8 +16208,8 @@ function EventViewer({
|
|
|
15954
16208
|
emptyMessage = "No events recorded yet",
|
|
15955
16209
|
title = "Recent Events"
|
|
15956
16210
|
}) {
|
|
15957
|
-
const [search2, setSearch] =
|
|
15958
|
-
const [expandedId, setExpandedId] =
|
|
16211
|
+
const [search2, setSearch] = useState34("");
|
|
16212
|
+
const [expandedId, setExpandedId] = useState34(null);
|
|
15959
16213
|
const styles2 = baseStyles(theme);
|
|
15960
16214
|
useEffect26(() => {
|
|
15961
16215
|
injectGlobalStyles();
|
|
@@ -16593,7 +16847,7 @@ function ChartIcon({ color }) {
|
|
|
16593
16847
|
|
|
16594
16848
|
// src/react/ui/api-key-manager.tsx
|
|
16595
16849
|
init_constants();
|
|
16596
|
-
import { useEffect as useEffect27, useId as useId5, useState as
|
|
16850
|
+
import { useEffect as useEffect27, useId as useId5, useState as useState35 } from "react";
|
|
16597
16851
|
import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
16598
16852
|
var DEFAULT_SCOPES = [
|
|
16599
16853
|
"read:users",
|
|
@@ -16617,15 +16871,15 @@ function APIKeyManager({
|
|
|
16617
16871
|
}) {
|
|
16618
16872
|
const keyNameId = useId5();
|
|
16619
16873
|
const expirationId = useId5();
|
|
16620
|
-
const [showCreate, setShowCreate] =
|
|
16621
|
-
const [name, setName] =
|
|
16622
|
-
const [selectedScopes, setSelectedScopes] =
|
|
16623
|
-
const [expiresIn, setExpiresIn] =
|
|
16624
|
-
const [isCreating, setIsCreating] =
|
|
16625
|
-
const [error, setError] =
|
|
16626
|
-
const [newKey, setNewKey] =
|
|
16627
|
-
const [revokingId, setRevokingId] =
|
|
16628
|
-
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);
|
|
16629
16883
|
const styles2 = baseStyles(theme);
|
|
16630
16884
|
useEffect27(() => {
|
|
16631
16885
|
injectGlobalStyles();
|
|
@@ -17212,7 +17466,7 @@ function CheckIcon10({ color }) {
|
|
|
17212
17466
|
}
|
|
17213
17467
|
|
|
17214
17468
|
// src/react/ui/billing-management.tsx
|
|
17215
|
-
import { useEffect as useEffect28, useState as
|
|
17469
|
+
import { useEffect as useEffect28, useState as useState36 } from "react";
|
|
17216
17470
|
import { Fragment as Fragment20, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
17217
17471
|
function InvoiceHistory({
|
|
17218
17472
|
theme = defaultTheme,
|
|
@@ -17224,8 +17478,8 @@ function InvoiceHistory({
|
|
|
17224
17478
|
pageSize = 10,
|
|
17225
17479
|
emptyMessage = "No invoices yet"
|
|
17226
17480
|
}) {
|
|
17227
|
-
const [invoices] =
|
|
17228
|
-
const [currentPage, setCurrentPage] =
|
|
17481
|
+
const [invoices] = useState36(propInvoices ?? []);
|
|
17482
|
+
const [currentPage, setCurrentPage] = useState36(1);
|
|
17229
17483
|
const styles2 = baseStyles(theme);
|
|
17230
17484
|
useEffect28(() => {
|
|
17231
17485
|
injectGlobalStyles();
|
|
@@ -17849,7 +18103,7 @@ function PlusIcon4({ color }) {
|
|
|
17849
18103
|
|
|
17850
18104
|
// src/react/ui/billing-section.tsx
|
|
17851
18105
|
init_constants();
|
|
17852
|
-
import { useEffect as useEffect29, useState as
|
|
18106
|
+
import { useEffect as useEffect29, useState as useState37 } from "react";
|
|
17853
18107
|
import { Fragment as Fragment21, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
17854
18108
|
function BillingSection(props) {
|
|
17855
18109
|
return /* @__PURE__ */ jsx29(RequireSdk, { services: ["billing"], componentType: "billing", theme: props.theme, children: /* @__PURE__ */ jsx29(BillingSectionInner, { ...props }) });
|
|
@@ -17876,10 +18130,10 @@ function BillingSectionInner({
|
|
|
17876
18130
|
refresh: _refresh
|
|
17877
18131
|
} = useBilling();
|
|
17878
18132
|
const styles2 = baseStyles(theme);
|
|
17879
|
-
const [selectedInterval, setSelectedInterval] =
|
|
17880
|
-
const [processingPlan, setProcessingPlan] =
|
|
17881
|
-
const [error, setError] =
|
|
17882
|
-
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);
|
|
17883
18137
|
useEffect29(() => {
|
|
17884
18138
|
injectGlobalStyles();
|
|
17885
18139
|
}, []);
|
|
@@ -18266,8 +18520,8 @@ function CheckIcon11({ color }) {
|
|
|
18266
18520
|
// src/react/ui/chat-interface.tsx
|
|
18267
18521
|
import {
|
|
18268
18522
|
useEffect as useEffect30,
|
|
18269
|
-
useRef as
|
|
18270
|
-
useState as
|
|
18523
|
+
useRef as useRef12,
|
|
18524
|
+
useState as useState38
|
|
18271
18525
|
} from "react";
|
|
18272
18526
|
import { Fragment as Fragment22, jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
18273
18527
|
function ChatInterface({
|
|
@@ -18292,9 +18546,9 @@ function ChatInterface({
|
|
|
18292
18546
|
...chatOptions
|
|
18293
18547
|
}) {
|
|
18294
18548
|
const { messages, send, isLoading, error, clear, retry } = useChat(chatOptions);
|
|
18295
|
-
const [input, setInput] =
|
|
18296
|
-
const messagesEndRef =
|
|
18297
|
-
const inputRef =
|
|
18549
|
+
const [input, setInput] = useState38("");
|
|
18550
|
+
const messagesEndRef = useRef12(null);
|
|
18551
|
+
const inputRef = useRef12(null);
|
|
18298
18552
|
const styles2 = baseStyles(theme);
|
|
18299
18553
|
useEffect30(() => {
|
|
18300
18554
|
injectGlobalStyles();
|
|
@@ -18670,8 +18924,8 @@ function ChatInput({
|
|
|
18670
18924
|
onSubmit,
|
|
18671
18925
|
isLoading = false
|
|
18672
18926
|
}) {
|
|
18673
|
-
const [input, setInput] =
|
|
18674
|
-
const inputRef =
|
|
18927
|
+
const [input, setInput] = useState38("");
|
|
18928
|
+
const inputRef = useRef12(null);
|
|
18675
18929
|
const handleSubmit = (e2) => {
|
|
18676
18930
|
e2?.preventDefault();
|
|
18677
18931
|
if (!input.trim() || disabled || isLoading) return;
|
|
@@ -18773,7 +19027,7 @@ function SendIcon2({ color }) {
|
|
|
18773
19027
|
|
|
18774
19028
|
// src/react/ui/consent-preferences.tsx
|
|
18775
19029
|
init_constants();
|
|
18776
|
-
import { useEffect as useEffect31, useState as
|
|
19030
|
+
import { useEffect as useEffect31, useState as useState39 } from "react";
|
|
18777
19031
|
import { Fragment as Fragment23, jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
18778
19032
|
var CATEGORY_INFO = {
|
|
18779
19033
|
necessary: {
|
|
@@ -18825,8 +19079,8 @@ function ConsentPreferences({
|
|
|
18825
19079
|
saveConsents,
|
|
18826
19080
|
hasConsented
|
|
18827
19081
|
} = useConsent();
|
|
18828
|
-
const [isSaving, setIsSaving] =
|
|
18829
|
-
const [saveSuccess, setSaveSuccess] =
|
|
19082
|
+
const [isSaving, setIsSaving] = useState39(false);
|
|
19083
|
+
const [saveSuccess, setSaveSuccess] = useState39(false);
|
|
18830
19084
|
const styles2 = baseStyles(theme);
|
|
18831
19085
|
useEffect31(() => {
|
|
18832
19086
|
injectGlobalStyles();
|
|
@@ -19256,7 +19510,7 @@ function CheckIcon12({ color }) {
|
|
|
19256
19510
|
|
|
19257
19511
|
// src/react/ui/cookie-banner.tsx
|
|
19258
19512
|
init_constants();
|
|
19259
|
-
import { useEffect as useEffect32, useState as
|
|
19513
|
+
import { useEffect as useEffect32, useState as useState40 } from "react";
|
|
19260
19514
|
import { Fragment as Fragment24, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
19261
19515
|
function CookieBanner({
|
|
19262
19516
|
theme = defaultTheme,
|
|
@@ -19283,8 +19537,8 @@ function CookieBanner({
|
|
|
19283
19537
|
saveConsents,
|
|
19284
19538
|
isLoading
|
|
19285
19539
|
} = useConsent();
|
|
19286
|
-
const [showCustomize, setShowCustomize] =
|
|
19287
|
-
const [isVisible, setIsVisible] =
|
|
19540
|
+
const [showCustomize, setShowCustomize] = useState40(false);
|
|
19541
|
+
const [isVisible, setIsVisible] = useState40(false);
|
|
19288
19542
|
const styles2 = baseStyles(theme);
|
|
19289
19543
|
useEffect32(() => {
|
|
19290
19544
|
injectGlobalStyles();
|
|
@@ -19657,7 +19911,7 @@ init_constants();
|
|
|
19657
19911
|
import {
|
|
19658
19912
|
Component,
|
|
19659
19913
|
useEffect as useEffect33,
|
|
19660
|
-
useState as
|
|
19914
|
+
useState as useState41
|
|
19661
19915
|
} from "react";
|
|
19662
19916
|
import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
19663
19917
|
var SylphxErrorBoundary = class extends Component {
|
|
@@ -19891,12 +20145,12 @@ function FeedbackWidget({
|
|
|
19891
20145
|
position = "bottom-right",
|
|
19892
20146
|
defaultOpen = false
|
|
19893
20147
|
}) {
|
|
19894
|
-
const [isOpen, setIsOpen] =
|
|
19895
|
-
const [message, setMessage] =
|
|
19896
|
-
const [email, setEmail] =
|
|
19897
|
-
const [isSubmitting, setIsSubmitting] =
|
|
19898
|
-
const [isSuccess, setIsSuccess] =
|
|
19899
|
-
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);
|
|
19900
20154
|
const { captureMessage } = useErrorTracking();
|
|
19901
20155
|
const styles2 = baseStyles(theme);
|
|
19902
20156
|
useEffect33(() => {
|
|
@@ -20136,7 +20390,7 @@ function CheckCircleIcon({ color }) {
|
|
|
20136
20390
|
|
|
20137
20391
|
// src/react/ui/feature-gate.tsx
|
|
20138
20392
|
init_constants();
|
|
20139
|
-
import { useContext as
|
|
20393
|
+
import { useContext as useContext18, useState as useState42 } from "react";
|
|
20140
20394
|
import { Fragment as Fragment25, jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
20141
20395
|
function FeatureGate({
|
|
20142
20396
|
flag,
|
|
@@ -20204,8 +20458,8 @@ function FlagDevTools({
|
|
|
20204
20458
|
defaultCollapsed = true,
|
|
20205
20459
|
className
|
|
20206
20460
|
}) {
|
|
20207
|
-
const [isCollapsed, setIsCollapsed] =
|
|
20208
|
-
const context =
|
|
20461
|
+
const [isCollapsed, setIsCollapsed] = useState42(defaultCollapsed);
|
|
20462
|
+
const context = useContext18(FeatureFlagContext);
|
|
20209
20463
|
const styles2 = baseStyles(theme);
|
|
20210
20464
|
if (!context) {
|
|
20211
20465
|
return null;
|
|
@@ -20439,8 +20693,54 @@ function CloseIcon4() {
|
|
|
20439
20693
|
|
|
20440
20694
|
// src/react/ui/file-upload.tsx
|
|
20441
20695
|
init_constants();
|
|
20442
|
-
import { useCallback as
|
|
20696
|
+
import { useCallback as useCallback33, useEffect as useEffect34, useRef as useRef13, useState as useState43 } from "react";
|
|
20443
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
|
+
}
|
|
20444
20744
|
function FileUpload(props) {
|
|
20445
20745
|
return /* @__PURE__ */ jsx35(RequireSdk, { services: ["storage"], componentType: "storage", theme: props.theme, children: /* @__PURE__ */ jsx35(FileUploadInner, { ...props }) });
|
|
20446
20746
|
}
|
|
@@ -20456,10 +20756,10 @@ function FileUploadInner({
|
|
|
20456
20756
|
placeholder = "Drop files here or click to upload",
|
|
20457
20757
|
showFileList = true
|
|
20458
20758
|
}) {
|
|
20459
|
-
const [isDragging, setIsDragging] =
|
|
20460
|
-
const [uploadedFiles, setUploadedFiles] =
|
|
20461
|
-
const inputRef =
|
|
20462
|
-
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({
|
|
20463
20763
|
accept,
|
|
20464
20764
|
maxSize,
|
|
20465
20765
|
onError
|
|
@@ -20468,7 +20768,7 @@ function FileUploadInner({
|
|
|
20468
20768
|
useEffect34(() => {
|
|
20469
20769
|
injectGlobalStyles();
|
|
20470
20770
|
}, []);
|
|
20471
|
-
const handleFiles =
|
|
20771
|
+
const handleFiles = useCallback33(
|
|
20472
20772
|
async (files) => {
|
|
20473
20773
|
if (!files || files.length === 0) return;
|
|
20474
20774
|
const fileArray = Array.from(files);
|
|
@@ -20487,7 +20787,7 @@ function FileUploadInner({
|
|
|
20487
20787
|
},
|
|
20488
20788
|
[upload, onUpload]
|
|
20489
20789
|
);
|
|
20490
|
-
const handleDrop =
|
|
20790
|
+
const handleDrop = useCallback33(
|
|
20491
20791
|
(e2) => {
|
|
20492
20792
|
e2.preventDefault();
|
|
20493
20793
|
e2.stopPropagation();
|
|
@@ -20497,7 +20797,7 @@ function FileUploadInner({
|
|
|
20497
20797
|
},
|
|
20498
20798
|
[handleFiles, disabled]
|
|
20499
20799
|
);
|
|
20500
|
-
const handleDragOver =
|
|
20800
|
+
const handleDragOver = useCallback33(
|
|
20501
20801
|
(e2) => {
|
|
20502
20802
|
e2.preventDefault();
|
|
20503
20803
|
e2.stopPropagation();
|
|
@@ -20505,7 +20805,7 @@ function FileUploadInner({
|
|
|
20505
20805
|
},
|
|
20506
20806
|
[disabled]
|
|
20507
20807
|
);
|
|
20508
|
-
const handleDragLeave =
|
|
20808
|
+
const handleDragLeave = useCallback33((e2) => {
|
|
20509
20809
|
e2.preventDefault();
|
|
20510
20810
|
e2.stopPropagation();
|
|
20511
20811
|
setIsDragging(false);
|
|
@@ -20668,9 +20968,9 @@ function ImageUploaderInner({
|
|
|
20668
20968
|
aspectRatio = "1:1",
|
|
20669
20969
|
placeholder = "Click to upload image"
|
|
20670
20970
|
}) {
|
|
20671
|
-
const [previewUrl, setPreviewUrl] =
|
|
20672
|
-
const inputRef =
|
|
20673
|
-
const { upload, isUploading, progress, error } =
|
|
20971
|
+
const [previewUrl, setPreviewUrl] = useState43(value || null);
|
|
20972
|
+
const inputRef = useRef13(null);
|
|
20973
|
+
const { upload, isUploading, progress, error } = useUploadAdapter({
|
|
20674
20974
|
accept: ["image/*"],
|
|
20675
20975
|
maxSize,
|
|
20676
20976
|
onError
|
|
@@ -20864,9 +21164,14 @@ function AvatarUploadInner({
|
|
|
20864
21164
|
size = 96,
|
|
20865
21165
|
placeholder = ""
|
|
20866
21166
|
}) {
|
|
20867
|
-
const [previewUrl, setPreviewUrl] =
|
|
20868
|
-
const inputRef =
|
|
20869
|
-
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
|
+
});
|
|
20870
21175
|
const styles2 = baseStyles(theme);
|
|
20871
21176
|
useEffect34(() => {
|
|
20872
21177
|
setPreviewUrl(value || null);
|
|
@@ -20875,18 +21180,10 @@ function AvatarUploadInner({
|
|
|
20875
21180
|
injectGlobalStyles();
|
|
20876
21181
|
}, []);
|
|
20877
21182
|
const handleFile = async (file) => {
|
|
20878
|
-
if (maxSize && file.size > maxSize) {
|
|
20879
|
-
onError?.(new Error(`File size exceeds ${formatFileSize(maxSize)} limit`));
|
|
20880
|
-
return;
|
|
20881
|
-
}
|
|
20882
|
-
if (!file.type.startsWith("image/")) {
|
|
20883
|
-
onError?.(new Error("Please upload an image file"));
|
|
20884
|
-
return;
|
|
20885
|
-
}
|
|
20886
21183
|
try {
|
|
20887
21184
|
const localUrl = URL.createObjectURL(file);
|
|
20888
21185
|
setPreviewUrl(localUrl);
|
|
20889
|
-
const url = await
|
|
21186
|
+
const url = await upload(file);
|
|
20890
21187
|
setPreviewUrl(url);
|
|
20891
21188
|
onChange?.(url);
|
|
20892
21189
|
URL.revokeObjectURL(localUrl);
|
|
@@ -20988,14 +21285,14 @@ function AvatarUploadInner({
|
|
|
20988
21285
|
]
|
|
20989
21286
|
}
|
|
20990
21287
|
),
|
|
20991
|
-
|
|
21288
|
+
error && /* @__PURE__ */ jsx35(
|
|
20992
21289
|
"p",
|
|
20993
21290
|
{
|
|
20994
21291
|
style: mergeStyles(styles2.textXs, {
|
|
20995
21292
|
color: theme.colorDestructive,
|
|
20996
21293
|
marginTop: "0.5rem"
|
|
20997
21294
|
}),
|
|
20998
|
-
children:
|
|
21295
|
+
children: error.message
|
|
20999
21296
|
}
|
|
21000
21297
|
)
|
|
21001
21298
|
] });
|
|
@@ -21131,17 +21428,17 @@ function CloseIcon5() {
|
|
|
21131
21428
|
|
|
21132
21429
|
// src/react/ui/job-scheduler.tsx
|
|
21133
21430
|
init_constants();
|
|
21134
|
-
import { useMutation as
|
|
21135
|
-
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";
|
|
21136
21433
|
|
|
21137
21434
|
// src/react/job-hooks.ts
|
|
21138
|
-
import { useQuery as
|
|
21139
|
-
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";
|
|
21140
21437
|
function useJobs() {
|
|
21141
21438
|
const ctx = useJobsContext();
|
|
21142
|
-
const [isLoading, setIsLoading] =
|
|
21143
|
-
const [error, setError] =
|
|
21144
|
-
const isAvailable =
|
|
21439
|
+
const [isLoading, setIsLoading] = useState44(false);
|
|
21440
|
+
const [error, setError] = useState44(null);
|
|
21441
|
+
const isAvailable = useCallback34(async () => {
|
|
21145
21442
|
try {
|
|
21146
21443
|
const status = await ctx.checkStatus();
|
|
21147
21444
|
return status.available;
|
|
@@ -21149,7 +21446,7 @@ function useJobs() {
|
|
|
21149
21446
|
return false;
|
|
21150
21447
|
}
|
|
21151
21448
|
}, [ctx]);
|
|
21152
|
-
const schedule =
|
|
21449
|
+
const schedule = useCallback34(
|
|
21153
21450
|
async (options) => {
|
|
21154
21451
|
setIsLoading(true);
|
|
21155
21452
|
setError(null);
|
|
@@ -21165,7 +21462,7 @@ function useJobs() {
|
|
|
21165
21462
|
},
|
|
21166
21463
|
[ctx]
|
|
21167
21464
|
);
|
|
21168
|
-
const createCron =
|
|
21465
|
+
const createCron = useCallback34(
|
|
21169
21466
|
async (options) => {
|
|
21170
21467
|
setIsLoading(true);
|
|
21171
21468
|
setError(null);
|
|
@@ -21181,7 +21478,7 @@ function useJobs() {
|
|
|
21181
21478
|
},
|
|
21182
21479
|
[ctx]
|
|
21183
21480
|
);
|
|
21184
|
-
const pauseCron =
|
|
21481
|
+
const pauseCron = useCallback34(
|
|
21185
21482
|
async (scheduleId) => {
|
|
21186
21483
|
setIsLoading(true);
|
|
21187
21484
|
setError(null);
|
|
@@ -21197,7 +21494,7 @@ function useJobs() {
|
|
|
21197
21494
|
},
|
|
21198
21495
|
[ctx]
|
|
21199
21496
|
);
|
|
21200
|
-
const resumeCron =
|
|
21497
|
+
const resumeCron = useCallback34(
|
|
21201
21498
|
async (scheduleId) => {
|
|
21202
21499
|
setIsLoading(true);
|
|
21203
21500
|
setError(null);
|
|
@@ -21213,7 +21510,7 @@ function useJobs() {
|
|
|
21213
21510
|
},
|
|
21214
21511
|
[ctx]
|
|
21215
21512
|
);
|
|
21216
|
-
const deleteCron =
|
|
21513
|
+
const deleteCron = useCallback34(
|
|
21217
21514
|
async (scheduleId) => {
|
|
21218
21515
|
setIsLoading(true);
|
|
21219
21516
|
setError(null);
|
|
@@ -21229,7 +21526,7 @@ function useJobs() {
|
|
|
21229
21526
|
},
|
|
21230
21527
|
[ctx]
|
|
21231
21528
|
);
|
|
21232
|
-
const getJob =
|
|
21529
|
+
const getJob = useCallback34(
|
|
21233
21530
|
async (jobId) => {
|
|
21234
21531
|
try {
|
|
21235
21532
|
return await ctx.getJob(jobId);
|
|
@@ -21241,7 +21538,7 @@ function useJobs() {
|
|
|
21241
21538
|
},
|
|
21242
21539
|
[ctx]
|
|
21243
21540
|
);
|
|
21244
|
-
const listJobs =
|
|
21541
|
+
const listJobs = useCallback34(
|
|
21245
21542
|
async (options = {}) => {
|
|
21246
21543
|
try {
|
|
21247
21544
|
const result = await ctx.listJobs(options);
|
|
@@ -21254,7 +21551,7 @@ function useJobs() {
|
|
|
21254
21551
|
},
|
|
21255
21552
|
[ctx]
|
|
21256
21553
|
);
|
|
21257
|
-
const cancelJob =
|
|
21554
|
+
const cancelJob = useCallback34(
|
|
21258
21555
|
async (jobId) => {
|
|
21259
21556
|
setIsLoading(true);
|
|
21260
21557
|
setError(null);
|
|
@@ -21295,14 +21592,14 @@ function JobScheduler({
|
|
|
21295
21592
|
showCronTab = true
|
|
21296
21593
|
}) {
|
|
21297
21594
|
const { schedule, createCron, isLoading, error } = useJobs();
|
|
21298
|
-
const [activeTab, setActiveTab] =
|
|
21299
|
-
const [name, setName] =
|
|
21300
|
-
const [callbackUrl, setCallbackUrl] =
|
|
21301
|
-
const [payload, setPayload] =
|
|
21302
|
-
const [delay2, setDelay] =
|
|
21303
|
-
const [delayUnit, setDelayUnit] =
|
|
21304
|
-
const [cronExpression, setCronExpression] =
|
|
21305
|
-
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);
|
|
21306
21603
|
const styles2 = baseStyles(theme);
|
|
21307
21604
|
useEffect36(() => {
|
|
21308
21605
|
injectGlobalStyles();
|
|
@@ -21644,13 +21941,13 @@ function JobList({
|
|
|
21644
21941
|
emptyMessage = "No jobs scheduled"
|
|
21645
21942
|
}) {
|
|
21646
21943
|
const ctx = useJobsContext();
|
|
21647
|
-
const queryClient =
|
|
21648
|
-
const [filter, setFilter] =
|
|
21944
|
+
const queryClient = useQueryClient10();
|
|
21945
|
+
const [filter, setFilter] = useState45("all");
|
|
21649
21946
|
const styles2 = baseStyles(theme);
|
|
21650
21947
|
useEffect36(() => {
|
|
21651
21948
|
injectGlobalStyles();
|
|
21652
21949
|
}, []);
|
|
21653
|
-
const jobsQuery =
|
|
21950
|
+
const jobsQuery = useQuery11({
|
|
21654
21951
|
queryKey: ["sylphx", "jobs", "list", filter],
|
|
21655
21952
|
queryFn: async () => {
|
|
21656
21953
|
const apiStatus = filter === "all" || filter === "cancelled" ? void 0 : filter;
|
|
@@ -21666,13 +21963,13 @@ function JobList({
|
|
|
21666
21963
|
const jobs = propJobs ?? jobsQuery.data ?? [];
|
|
21667
21964
|
const isLoading = !propJobs && jobsQuery.isLoading;
|
|
21668
21965
|
const filteredJobs = filter === "all" ? jobs : jobs.filter((j) => j.status === filter);
|
|
21669
|
-
const cancelMutation =
|
|
21966
|
+
const cancelMutation = useMutation3({
|
|
21670
21967
|
mutationFn: (jobId) => ctx.cancelJob(jobId),
|
|
21671
21968
|
onSuccess: () => {
|
|
21672
21969
|
queryClient.invalidateQueries({ queryKey: ["sylphx", "jobs", "list"] });
|
|
21673
21970
|
}
|
|
21674
21971
|
});
|
|
21675
|
-
const handleCancel =
|
|
21972
|
+
const handleCancel = useCallback35(
|
|
21676
21973
|
async (jobId) => {
|
|
21677
21974
|
if (onCancel) {
|
|
21678
21975
|
onCancel(jobId);
|
|
@@ -21862,9 +22159,9 @@ function CronBuilder({
|
|
|
21862
22159
|
onCreate,
|
|
21863
22160
|
defaultCallbackUrl = ""
|
|
21864
22161
|
}) {
|
|
21865
|
-
const [expression, setExpression] =
|
|
21866
|
-
const [callbackUrl, setCallbackUrl] =
|
|
21867
|
-
const [name, setName] =
|
|
22162
|
+
const [expression, setExpression] = useState45("0 9 * * *");
|
|
22163
|
+
const [callbackUrl, setCallbackUrl] = useState45(defaultCallbackUrl);
|
|
22164
|
+
const [name, setName] = useState45("");
|
|
21868
22165
|
const styles2 = baseStyles(theme);
|
|
21869
22166
|
useEffect36(() => {
|
|
21870
22167
|
injectGlobalStyles();
|
|
@@ -22105,7 +22402,7 @@ function JobIcon({ color, size = 24 }) {
|
|
|
22105
22402
|
var TaskScheduler = JobScheduler;
|
|
22106
22403
|
|
|
22107
22404
|
// src/react/ui/model-selector.tsx
|
|
22108
|
-
import { useEffect as useEffect37, useRef as
|
|
22405
|
+
import { useEffect as useEffect37, useRef as useRef15, useState as useState46 } from "react";
|
|
22109
22406
|
import { Fragment as Fragment27, jsx as jsx37, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
22110
22407
|
function ModelSelector({
|
|
22111
22408
|
theme = defaultTheme,
|
|
@@ -22120,10 +22417,10 @@ function ModelSelector({
|
|
|
22120
22417
|
compact = false
|
|
22121
22418
|
}) {
|
|
22122
22419
|
const styles2 = baseStyles(theme);
|
|
22123
|
-
const [isOpen, setIsOpen] =
|
|
22124
|
-
const [searchValue, setSearchValue] =
|
|
22125
|
-
const containerRef =
|
|
22126
|
-
const inputRef =
|
|
22420
|
+
const [isOpen, setIsOpen] = useState46(false);
|
|
22421
|
+
const [searchValue, setSearchValue] = useState46("");
|
|
22422
|
+
const containerRef = useRef15(null);
|
|
22423
|
+
const inputRef = useRef15(null);
|
|
22127
22424
|
const { models, isLoading, error, setSearch, hasMore, loadMore } = useModels({
|
|
22128
22425
|
capability,
|
|
22129
22426
|
fetchOnMount: true,
|
|
@@ -22652,8 +22949,8 @@ function ModelGrid({
|
|
|
22652
22949
|
fetchOnMount: true,
|
|
22653
22950
|
pageSize: 24
|
|
22654
22951
|
});
|
|
22655
|
-
const [searchValue, setSearchValue] =
|
|
22656
|
-
const [filterCapability, setFilterCapability] =
|
|
22952
|
+
const [searchValue, setSearchValue] = useState46("");
|
|
22953
|
+
const [filterCapability, setFilterCapability] = useState46(capability);
|
|
22657
22954
|
useEffect37(() => {
|
|
22658
22955
|
injectGlobalStyles();
|
|
22659
22956
|
}, []);
|
|
@@ -22757,7 +23054,7 @@ function ModelGrid({
|
|
|
22757
23054
|
|
|
22758
23055
|
// src/react/ui/newsletter-form.tsx
|
|
22759
23056
|
import { EMAIL_REGEX } from "@sylphx/contract";
|
|
22760
|
-
import { useEffect as useEffect38, useState as
|
|
23057
|
+
import { useEffect as useEffect38, useState as useState47 } from "react";
|
|
22761
23058
|
import { jsx as jsx38, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
22762
23059
|
function NewsletterForm({
|
|
22763
23060
|
theme = defaultTheme,
|
|
@@ -22788,7 +23085,7 @@ function NewsletterForm({
|
|
|
22788
23085
|
reset
|
|
22789
23086
|
} = useSubscriberForm();
|
|
22790
23087
|
const styles2 = baseStyles(theme);
|
|
22791
|
-
const [localError, setLocalError] =
|
|
23088
|
+
const [localError, setLocalError] = useState47(null);
|
|
22792
23089
|
useEffect38(() => {
|
|
22793
23090
|
injectGlobalStyles();
|
|
22794
23091
|
}, []);
|
|
@@ -22972,7 +23269,7 @@ function NewsletterForm({
|
|
|
22972
23269
|
|
|
22973
23270
|
// src/react/ui/notification-settings.tsx
|
|
22974
23271
|
init_constants();
|
|
22975
|
-
import { useEffect as useEffect39, useState as
|
|
23272
|
+
import { useEffect as useEffect39, useState as useState48 } from "react";
|
|
22976
23273
|
import { jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
22977
23274
|
function NotificationSettings({
|
|
22978
23275
|
theme = defaultTheme,
|
|
@@ -22992,10 +23289,10 @@ function NotificationSettings({
|
|
|
22992
23289
|
updatePreferences
|
|
22993
23290
|
} = useNotifications();
|
|
22994
23291
|
const styles2 = baseStyles(theme);
|
|
22995
|
-
const [error, setError] =
|
|
22996
|
-
const [success, setSuccess] =
|
|
22997
|
-
const [isTogglingPush, setIsTogglingPush] =
|
|
22998
|
-
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(
|
|
22999
23296
|
() => preferences?.categories ?? {}
|
|
23000
23297
|
);
|
|
23001
23298
|
useEffect39(() => {
|
|
@@ -23241,7 +23538,7 @@ function BellOffIcon({ size = 24 }) {
|
|
|
23241
23538
|
|
|
23242
23539
|
// src/react/ui/organization-management.tsx
|
|
23243
23540
|
init_constants();
|
|
23244
|
-
import { useEffect as useEffect40, useId as useId6, useState as
|
|
23541
|
+
import { useEffect as useEffect40, useId as useId6, useState as useState49 } from "react";
|
|
23245
23542
|
import { Fragment as Fragment28, jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
23246
23543
|
function OrganizationProfile(props) {
|
|
23247
23544
|
return /* @__PURE__ */ jsx40(RequireSdk, { services: ["organization"], componentType: "organization", theme: props.theme, children: /* @__PURE__ */ jsx40(OrganizationProfileInner, { ...props }) });
|
|
@@ -23262,12 +23559,12 @@ function OrganizationProfileInner({
|
|
|
23262
23559
|
const nameId = useId6();
|
|
23263
23560
|
const slugId = useId6();
|
|
23264
23561
|
const deleteConfirmId = useId6();
|
|
23265
|
-
const [name, setName] =
|
|
23266
|
-
const [slug, setSlug] =
|
|
23267
|
-
const [isSaving, setIsSaving] =
|
|
23268
|
-
const [isDeleting, setIsDeleting] =
|
|
23269
|
-
const [saveSuccess, setSaveSuccess] =
|
|
23270
|
-
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("");
|
|
23271
23568
|
const styles2 = baseStyles(theme);
|
|
23272
23569
|
useEffect40(() => {
|
|
23273
23570
|
injectGlobalStyles();
|
|
@@ -23635,10 +23932,10 @@ function CreateOrganization({
|
|
|
23635
23932
|
}) {
|
|
23636
23933
|
const createNameId = useId6();
|
|
23637
23934
|
const createSlugId = useId6();
|
|
23638
|
-
const [name, setName] =
|
|
23639
|
-
const [slug, setSlug] =
|
|
23640
|
-
const [isCreating, setIsCreating] =
|
|
23641
|
-
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);
|
|
23642
23939
|
const styles2 = baseStyles(theme);
|
|
23643
23940
|
useEffect40(() => {
|
|
23644
23941
|
injectGlobalStyles();
|
|
@@ -23991,7 +24288,7 @@ function PlusIcon5({ color }) {
|
|
|
23991
24288
|
|
|
23992
24289
|
// src/react/ui/push-notifications.tsx
|
|
23993
24290
|
init_constants();
|
|
23994
|
-
import { useEffect as useEffect41, useState as
|
|
24291
|
+
import { useEffect as useEffect41, useState as useState50 } from "react";
|
|
23995
24292
|
import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
23996
24293
|
function PushPrompt({
|
|
23997
24294
|
theme = defaultTheme,
|
|
@@ -24007,8 +24304,8 @@ function PushPrompt({
|
|
|
24007
24304
|
autoShow = true,
|
|
24008
24305
|
showDelay = UI_PROMPT_DELAY_MS
|
|
24009
24306
|
}) {
|
|
24010
|
-
const [isVisible, setIsVisible] =
|
|
24011
|
-
const [isAnimatingOut, setIsAnimatingOut] =
|
|
24307
|
+
const [isVisible, setIsVisible] = useState50(false);
|
|
24308
|
+
const [isAnimatingOut, setIsAnimatingOut] = useState50(false);
|
|
24012
24309
|
const { isSupported, isSubscribed, subscribe, error } = useNotifications();
|
|
24013
24310
|
const styles2 = baseStyles(theme);
|
|
24014
24311
|
useEffect41(() => {
|
|
@@ -24350,7 +24647,7 @@ function NotificationItem({
|
|
|
24350
24647
|
onDelete
|
|
24351
24648
|
}) {
|
|
24352
24649
|
const styles2 = baseStyles(theme);
|
|
24353
|
-
const [showActions, setShowActions] =
|
|
24650
|
+
const [showActions, setShowActions] = useState50(false);
|
|
24354
24651
|
const itemStyle = {
|
|
24355
24652
|
position: "relative",
|
|
24356
24653
|
display: "flex",
|
|
@@ -24593,7 +24890,7 @@ function TrashIcon3({ color }) {
|
|
|
24593
24890
|
|
|
24594
24891
|
// src/react/ui/referral-card.tsx
|
|
24595
24892
|
init_constants();
|
|
24596
|
-
import { useEffect as useEffect42, useId as useId7, useState as
|
|
24893
|
+
import { useEffect as useEffect42, useId as useId7, useState as useState51 } from "react";
|
|
24597
24894
|
import { Fragment as Fragment29, jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
24598
24895
|
function ReferralCard(props) {
|
|
24599
24896
|
return /* @__PURE__ */ jsx42(RequireSdk, { services: ["analytics"], componentType: "referral", theme: props.theme, children: /* @__PURE__ */ jsx42(ReferralCardInner, { ...props }) });
|
|
@@ -24621,9 +24918,9 @@ function ReferralCardInner({
|
|
|
24621
24918
|
} = useReferral();
|
|
24622
24919
|
const styles2 = baseStyles(theme);
|
|
24623
24920
|
const linkId = useId7();
|
|
24624
|
-
const [copied, setCopied] =
|
|
24625
|
-
const [isRegenerating, setIsRegenerating] =
|
|
24626
|
-
const [error, setError] =
|
|
24921
|
+
const [copied, setCopied] = useState51(null);
|
|
24922
|
+
const [isRegenerating, setIsRegenerating] = useState51(false);
|
|
24923
|
+
const [error, setError] = useState51(null);
|
|
24627
24924
|
useEffect42(() => {
|
|
24628
24925
|
injectGlobalStyles();
|
|
24629
24926
|
}, []);
|
|
@@ -25061,8 +25358,8 @@ function EmailIcon({ size = 24 }) {
|
|
|
25061
25358
|
|
|
25062
25359
|
// src/react/ui/security-settings.tsx
|
|
25063
25360
|
init_constants();
|
|
25064
|
-
import { useMutation as
|
|
25065
|
-
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";
|
|
25066
25363
|
import { Fragment as Fragment30, jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
25067
25364
|
function SecuritySettings({
|
|
25068
25365
|
theme = defaultTheme,
|
|
@@ -25076,26 +25373,26 @@ function SecuritySettings({
|
|
|
25076
25373
|
}) {
|
|
25077
25374
|
const userContext = useUserContext();
|
|
25078
25375
|
const securityContext = useSecurityContext();
|
|
25079
|
-
const queryClient =
|
|
25376
|
+
const queryClient = useQueryClient11();
|
|
25080
25377
|
const styles2 = baseStyles(theme);
|
|
25081
25378
|
const verifyCodeId = useId8();
|
|
25082
25379
|
const currentPasswordId = useId8();
|
|
25083
25380
|
const newPasswordId = useId8();
|
|
25084
25381
|
const confirmPasswordId = useId8();
|
|
25085
|
-
const [error, setError] =
|
|
25086
|
-
const [success, setSuccess] =
|
|
25087
|
-
const [showSetup2FA, setShowSetup2FA] =
|
|
25088
|
-
const [totpSecret, setTotpSecret] =
|
|
25089
|
-
const [totpQrCode, setTotpQrCode] =
|
|
25090
|
-
const [verifyCode, setVerifyCode] =
|
|
25091
|
-
const [showPasswordChange, setShowPasswordChange] =
|
|
25092
|
-
const [currentPassword, setCurrentPassword] =
|
|
25093
|
-
const [newPassword, setNewPassword] =
|
|
25094
|
-
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("");
|
|
25095
25392
|
useEffect43(() => {
|
|
25096
25393
|
injectGlobalStyles();
|
|
25097
25394
|
}, []);
|
|
25098
|
-
const twoFactorQuery =
|
|
25395
|
+
const twoFactorQuery = useQuery12({
|
|
25099
25396
|
queryKey: ["sylphx", "security", "2fa-status"],
|
|
25100
25397
|
queryFn: async () => {
|
|
25101
25398
|
const data = await securityContext.getTwoFactorStatus();
|
|
@@ -25108,7 +25405,7 @@ function SecuritySettings({
|
|
|
25108
25405
|
staleTime: STALE_TIME_STABLE_MS
|
|
25109
25406
|
// 5 min
|
|
25110
25407
|
});
|
|
25111
|
-
const sessionsQuery =
|
|
25408
|
+
const sessionsQuery = useQuery12({
|
|
25112
25409
|
queryKey: ["sylphx", "security", "sessions"],
|
|
25113
25410
|
queryFn: async () => {
|
|
25114
25411
|
const data = await userContext.getSessions();
|
|
@@ -25127,7 +25424,7 @@ function SecuritySettings({
|
|
|
25127
25424
|
staleTime: STALE_TIME_FREQUENT_MS
|
|
25128
25425
|
// 1 min - sessions can change
|
|
25129
25426
|
});
|
|
25130
|
-
const loginHistoryQuery =
|
|
25427
|
+
const loginHistoryQuery = useQuery12({
|
|
25131
25428
|
queryKey: ["sylphx", "security", "login-history"],
|
|
25132
25429
|
queryFn: async () => {
|
|
25133
25430
|
const data = await userContext.getLoginHistory({ limit: 10 });
|
|
@@ -25166,7 +25463,7 @@ function SecuritySettings({
|
|
|
25166
25463
|
return () => clearTimeout(timer);
|
|
25167
25464
|
}
|
|
25168
25465
|
}, [success, error]);
|
|
25169
|
-
const setup2FAMutation =
|
|
25466
|
+
const setup2FAMutation = useMutation4({
|
|
25170
25467
|
mutationFn: () => securityContext.twoFactorSetup(),
|
|
25171
25468
|
onSuccess: (data) => {
|
|
25172
25469
|
setTotpSecret(data.secret);
|
|
@@ -25179,7 +25476,7 @@ function SecuritySettings({
|
|
|
25179
25476
|
onError?.(message);
|
|
25180
25477
|
}
|
|
25181
25478
|
});
|
|
25182
|
-
const enable2FAMutation =
|
|
25479
|
+
const enable2FAMutation = useMutation4({
|
|
25183
25480
|
mutationFn: (code) => securityContext.twoFactorVerify(code),
|
|
25184
25481
|
onSuccess: () => {
|
|
25185
25482
|
queryClient.setQueryData(["sylphx", "security", "2fa-status"], {
|
|
@@ -25197,7 +25494,7 @@ function SecuritySettings({
|
|
|
25197
25494
|
onError?.(message);
|
|
25198
25495
|
}
|
|
25199
25496
|
});
|
|
25200
|
-
const disable2FAMutation =
|
|
25497
|
+
const disable2FAMutation = useMutation4({
|
|
25201
25498
|
mutationFn: (code) => securityContext.twoFactorDisable(code),
|
|
25202
25499
|
onSuccess: () => {
|
|
25203
25500
|
queryClient.setQueryData(["sylphx", "security", "2fa-status"], {
|
|
@@ -25212,7 +25509,7 @@ function SecuritySettings({
|
|
|
25212
25509
|
onError?.(message);
|
|
25213
25510
|
}
|
|
25214
25511
|
});
|
|
25215
|
-
const changePasswordMutation =
|
|
25512
|
+
const changePasswordMutation = useMutation4({
|
|
25216
25513
|
mutationFn: ({ current, newPwd }) => userContext.changePassword(current, newPwd),
|
|
25217
25514
|
onSuccess: () => {
|
|
25218
25515
|
setShowPasswordChange(false);
|
|
@@ -25228,7 +25525,7 @@ function SecuritySettings({
|
|
|
25228
25525
|
onError?.(message);
|
|
25229
25526
|
}
|
|
25230
25527
|
});
|
|
25231
|
-
const revokeSessionMutation =
|
|
25528
|
+
const revokeSessionMutation = useMutation4({
|
|
25232
25529
|
mutationFn: (sessionId) => userContext.revokeSession(sessionId),
|
|
25233
25530
|
onSuccess: (_data, sessionId) => {
|
|
25234
25531
|
queryClient.setQueryData(
|
|
@@ -25244,7 +25541,7 @@ function SecuritySettings({
|
|
|
25244
25541
|
onError?.(message);
|
|
25245
25542
|
}
|
|
25246
25543
|
});
|
|
25247
|
-
const revokeAllSessionsMutation =
|
|
25544
|
+
const revokeAllSessionsMutation = useMutation4({
|
|
25248
25545
|
mutationFn: () => userContext.revokeAllSessions(),
|
|
25249
25546
|
onSuccess: () => {
|
|
25250
25547
|
queryClient.setQueryData(
|
|
@@ -25260,10 +25557,10 @@ function SecuritySettings({
|
|
|
25260
25557
|
onError?.(message);
|
|
25261
25558
|
}
|
|
25262
25559
|
});
|
|
25263
|
-
const handleStart2FASetup =
|
|
25560
|
+
const handleStart2FASetup = useCallback36(() => {
|
|
25264
25561
|
setup2FAMutation.mutate();
|
|
25265
25562
|
}, [setup2FAMutation]);
|
|
25266
|
-
const handleEnable2FA =
|
|
25563
|
+
const handleEnable2FA = useCallback36(
|
|
25267
25564
|
(e2) => {
|
|
25268
25565
|
e2.preventDefault();
|
|
25269
25566
|
if (!verifyCode || verifyCode.length !== 6) {
|
|
@@ -25274,12 +25571,12 @@ function SecuritySettings({
|
|
|
25274
25571
|
},
|
|
25275
25572
|
[verifyCode, enable2FAMutation]
|
|
25276
25573
|
);
|
|
25277
|
-
const handleDisable2FA =
|
|
25574
|
+
const handleDisable2FA = useCallback36(() => {
|
|
25278
25575
|
const code = prompt("Enter your 2FA code to disable two-factor authentication:");
|
|
25279
25576
|
if (!code) return;
|
|
25280
25577
|
disable2FAMutation.mutate(code);
|
|
25281
25578
|
}, [disable2FAMutation]);
|
|
25282
|
-
const handlePasswordChange =
|
|
25579
|
+
const handlePasswordChange = useCallback36(
|
|
25283
25580
|
(e2) => {
|
|
25284
25581
|
e2.preventDefault();
|
|
25285
25582
|
if (newPassword !== confirmPassword) {
|
|
@@ -25297,13 +25594,13 @@ function SecuritySettings({
|
|
|
25297
25594
|
},
|
|
25298
25595
|
[newPassword, confirmPassword, currentPassword, changePasswordMutation]
|
|
25299
25596
|
);
|
|
25300
|
-
const handleRevokeSession =
|
|
25597
|
+
const handleRevokeSession = useCallback36(
|
|
25301
25598
|
(sessionId) => {
|
|
25302
25599
|
revokeSessionMutation.mutate(sessionId);
|
|
25303
25600
|
},
|
|
25304
25601
|
[revokeSessionMutation]
|
|
25305
25602
|
);
|
|
25306
|
-
const handleRevokeAllSessions =
|
|
25603
|
+
const handleRevokeAllSessions = useCallback36(() => {
|
|
25307
25604
|
if (!confirm("Are you sure you want to sign out all other devices?")) {
|
|
25308
25605
|
return;
|
|
25309
25606
|
}
|
|
@@ -25846,8 +26143,8 @@ function DeviceIcon({ device, theme }) {
|
|
|
25846
26143
|
|
|
25847
26144
|
// src/react/ui/subscriber-preferences.tsx
|
|
25848
26145
|
init_constants();
|
|
25849
|
-
import { useQuery as
|
|
25850
|
-
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";
|
|
25851
26148
|
import { Fragment as Fragment31, jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
25852
26149
|
function SubscriberPreferences({
|
|
25853
26150
|
theme = defaultTheme,
|
|
@@ -25864,17 +26161,17 @@ function SubscriberPreferences({
|
|
|
25864
26161
|
unsubscribeButtonText = "Unsubscribe from All"
|
|
25865
26162
|
}) {
|
|
25866
26163
|
const { getPreferences, updatePreferences } = useNewsletter();
|
|
25867
|
-
const queryClient =
|
|
26164
|
+
const queryClient = useQueryClient12();
|
|
25868
26165
|
const styles2 = baseStyles(theme);
|
|
25869
|
-
const [selectedPreferences, setSelectedPreferences] =
|
|
25870
|
-
const [saving, setSaving] =
|
|
25871
|
-
const [unsubscribing, setUnsubscribing] =
|
|
25872
|
-
const [error, setError] =
|
|
25873
|
-
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);
|
|
25874
26171
|
useEffect44(() => {
|
|
25875
26172
|
injectGlobalStyles();
|
|
25876
26173
|
}, []);
|
|
25877
|
-
const prefsQuery =
|
|
26174
|
+
const prefsQuery = useQuery13({
|
|
25878
26175
|
queryKey: ["sylphx", "newsletter", "preferences", email],
|
|
25879
26176
|
queryFn: async () => {
|
|
25880
26177
|
const prefs = await getPreferences(email);
|
|
@@ -26085,7 +26382,7 @@ function SubscriberPreferences({
|
|
|
26085
26382
|
|
|
26086
26383
|
// src/react/ui/unsubscribe-confirm.tsx
|
|
26087
26384
|
init_constants();
|
|
26088
|
-
import { useEffect as useEffect45, useId as useId9, useState as
|
|
26385
|
+
import { useEffect as useEffect45, useId as useId9, useState as useState54 } from "react";
|
|
26089
26386
|
import { Fragment as Fragment32, jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
26090
26387
|
var DEFAULT_REASONS = [
|
|
26091
26388
|
{ id: "too_many", label: "Too many emails" },
|
|
@@ -26112,9 +26409,9 @@ function UnsubscribeConfirm({
|
|
|
26112
26409
|
const { unsubscribe, subscribe } = useNewsletter();
|
|
26113
26410
|
const styles2 = baseStyles(theme);
|
|
26114
26411
|
const reasonId = useId9();
|
|
26115
|
-
const [status, setStatus] =
|
|
26116
|
-
const [selectedReason, setSelectedReason] =
|
|
26117
|
-
const [error, setError] =
|
|
26412
|
+
const [status, setStatus] = useState54(() => token ? "pending" : "missing_token");
|
|
26413
|
+
const [selectedReason, setSelectedReason] = useState54("");
|
|
26414
|
+
const [error, setError] = useState54(null);
|
|
26118
26415
|
useEffect45(() => {
|
|
26119
26416
|
injectGlobalStyles();
|
|
26120
26417
|
}, []);
|
|
@@ -26474,7 +26771,7 @@ function UnsubscribeConfirm({
|
|
|
26474
26771
|
|
|
26475
26772
|
// src/react/ui/user-profile.tsx
|
|
26476
26773
|
init_constants();
|
|
26477
|
-
import { useCallback as
|
|
26774
|
+
import { useCallback as useCallback37, useEffect as useEffect46, useId as useId10, useRef as useRef16, useState as useState55 } from "react";
|
|
26478
26775
|
import { Fragment as Fragment33, jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
26479
26776
|
function UserProfile(props) {
|
|
26480
26777
|
return /* @__PURE__ */ jsx46(RequireSdk, { services: ["auth", "storage"], componentType: "user", theme: props.theme, children: /* @__PURE__ */ jsx46(UserProfileInner, { ...props }) });
|
|
@@ -26492,16 +26789,16 @@ function UserProfileInner({
|
|
|
26492
26789
|
}) {
|
|
26493
26790
|
const { user, isLoading: isUserLoading, refresh: refreshUser } = useUser();
|
|
26494
26791
|
const userContext = useUserContext();
|
|
26495
|
-
const {
|
|
26792
|
+
const { upload: uploadFile, isUploading: isUploadingAvatar } = useStorage();
|
|
26496
26793
|
const styles2 = baseStyles(theme);
|
|
26497
26794
|
const nameId = useId10();
|
|
26498
26795
|
const emailId = useId10();
|
|
26499
|
-
const [activeSection, setActiveSection] =
|
|
26500
|
-
const [form, setForm] =
|
|
26501
|
-
const [error, setError] =
|
|
26502
|
-
const [success, setSuccess] =
|
|
26503
|
-
const [isLoading, setIsLoading] =
|
|
26504
|
-
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);
|
|
26505
26802
|
useEffect46(() => {
|
|
26506
26803
|
injectGlobalStyles();
|
|
26507
26804
|
}, []);
|
|
@@ -26522,7 +26819,7 @@ function UserProfileInner({
|
|
|
26522
26819
|
return () => clearTimeout(timer);
|
|
26523
26820
|
}
|
|
26524
26821
|
}, [success, error]);
|
|
26525
|
-
const handleProfileUpdate =
|
|
26822
|
+
const handleProfileUpdate = useCallback37(
|
|
26526
26823
|
async (e2) => {
|
|
26527
26824
|
e2.preventDefault();
|
|
26528
26825
|
setIsLoading(true);
|
|
@@ -26546,11 +26843,12 @@ function UserProfileInner({
|
|
|
26546
26843
|
},
|
|
26547
26844
|
[form, userContext, refreshUser, onSuccess, onError]
|
|
26548
26845
|
);
|
|
26549
|
-
const handleAvatarUpload =
|
|
26846
|
+
const handleAvatarUpload = useCallback37(
|
|
26550
26847
|
async (file) => {
|
|
26551
26848
|
setError(null);
|
|
26552
26849
|
try {
|
|
26553
|
-
const
|
|
26850
|
+
const result = await uploadFile(file, { folder: "avatars" });
|
|
26851
|
+
const imageUrl = result.url ?? "";
|
|
26554
26852
|
setForm((prev) => ({ ...prev, image: imageUrl }));
|
|
26555
26853
|
setSuccess("Avatar uploaded");
|
|
26556
26854
|
} catch (err) {
|
|
@@ -26559,7 +26857,7 @@ function UserProfileInner({
|
|
|
26559
26857
|
onError?.(message);
|
|
26560
26858
|
}
|
|
26561
26859
|
},
|
|
26562
|
-
[
|
|
26860
|
+
[uploadFile, onError]
|
|
26563
26861
|
);
|
|
26564
26862
|
const handleFileChange = (e2) => {
|
|
26565
26863
|
const file = e2.target.files?.[0];
|
|
@@ -26849,7 +27147,7 @@ function CloseIcon6({ color }) {
|
|
|
26849
27147
|
}
|
|
26850
27148
|
|
|
26851
27149
|
// src/react/ui/webhook-manager.tsx
|
|
26852
|
-
import { useEffect as useEffect47, useId as useId11, useState as
|
|
27150
|
+
import { useEffect as useEffect47, useId as useId11, useState as useState56 } from "react";
|
|
26853
27151
|
import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
26854
27152
|
var DEFAULT_EVENTS = [
|
|
26855
27153
|
"user.created",
|
|
@@ -26876,13 +27174,13 @@ function WebhookManager({
|
|
|
26876
27174
|
emptyMessage = "No webhooks configured"
|
|
26877
27175
|
}) {
|
|
26878
27176
|
const urlId = useId11();
|
|
26879
|
-
const [showCreate, setShowCreate] =
|
|
26880
|
-
const [url, setUrl] =
|
|
26881
|
-
const [selectedEvents, setSelectedEvents] =
|
|
26882
|
-
const [isCreating, setIsCreating] =
|
|
26883
|
-
const [error, setError] =
|
|
26884
|
-
const [testingId, setTestingId] =
|
|
26885
|
-
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);
|
|
26886
27184
|
const styles2 = baseStyles(theme);
|
|
26887
27185
|
useEffect47(() => {
|
|
26888
27186
|
injectGlobalStyles();
|
|
@@ -27272,7 +27570,7 @@ function WebhookDeliveryLog({
|
|
|
27272
27570
|
emptyMessage = "No deliveries yet",
|
|
27273
27571
|
maxDeliveries = 50
|
|
27274
27572
|
}) {
|
|
27275
|
-
const [expandedId, setExpandedId] =
|
|
27573
|
+
const [expandedId, setExpandedId] = useState56(null);
|
|
27276
27574
|
const styles2 = baseStyles(theme);
|
|
27277
27575
|
useEffect47(() => {
|
|
27278
27576
|
injectGlobalStyles();
|
|
@@ -33169,7 +33467,7 @@ function isWebVitalsInitialized() {
|
|
|
33169
33467
|
|
|
33170
33468
|
// src/react/hooks/use-session-replay.tsx
|
|
33171
33469
|
init_constants();
|
|
33172
|
-
import { useCallback as
|
|
33470
|
+
import { useCallback as useCallback38, useEffect as useEffect48, useRef as useRef17, useState as useState57 } from "react";
|
|
33173
33471
|
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
33174
33472
|
function useSessionReplay(options = {}) {
|
|
33175
33473
|
const {
|
|
@@ -33182,14 +33480,14 @@ function useSessionReplay(options = {}) {
|
|
|
33182
33480
|
api,
|
|
33183
33481
|
...recorderConfig
|
|
33184
33482
|
} = options;
|
|
33185
|
-
const apiRef =
|
|
33483
|
+
const apiRef = useRef17(api);
|
|
33186
33484
|
useEffect48(() => {
|
|
33187
33485
|
apiRef.current = api;
|
|
33188
33486
|
}, [api]);
|
|
33189
|
-
const recorderRef =
|
|
33190
|
-
const currentSessionIdRef =
|
|
33191
|
-
const [sessionId, setSessionId] =
|
|
33192
|
-
const [status, setStatus] =
|
|
33487
|
+
const recorderRef = useRef17(null);
|
|
33488
|
+
const currentSessionIdRef = useRef17(null);
|
|
33489
|
+
const [sessionId, setSessionId] = useState57(null);
|
|
33490
|
+
const [status, setStatus] = useState57({
|
|
33193
33491
|
state: "idle",
|
|
33194
33492
|
sessionId: null,
|
|
33195
33493
|
eventCount: 0,
|
|
@@ -33242,7 +33540,7 @@ function useSessionReplay(options = {}) {
|
|
|
33242
33540
|
});
|
|
33243
33541
|
}
|
|
33244
33542
|
}, [userId]);
|
|
33245
|
-
const start =
|
|
33543
|
+
const start = useCallback38(() => {
|
|
33246
33544
|
if (!recorderRef.current) {
|
|
33247
33545
|
throw new Error("Recorder not initialized");
|
|
33248
33546
|
}
|
|
@@ -33250,29 +33548,29 @@ function useSessionReplay(options = {}) {
|
|
|
33250
33548
|
setSessionId(id);
|
|
33251
33549
|
return id;
|
|
33252
33550
|
}, []);
|
|
33253
|
-
const pause =
|
|
33551
|
+
const pause = useCallback38(() => {
|
|
33254
33552
|
recorderRef.current?.pause();
|
|
33255
33553
|
}, []);
|
|
33256
|
-
const resume =
|
|
33554
|
+
const resume = useCallback38(() => {
|
|
33257
33555
|
recorderRef.current?.resume();
|
|
33258
33556
|
}, []);
|
|
33259
|
-
const stop =
|
|
33557
|
+
const stop = useCallback38(async () => {
|
|
33260
33558
|
await recorderRef.current?.stop();
|
|
33261
33559
|
setSessionId(null);
|
|
33262
33560
|
}, []);
|
|
33263
|
-
const markError =
|
|
33561
|
+
const markError = useCallback38(
|
|
33264
33562
|
(errorId, error, metadata) => {
|
|
33265
33563
|
recorderRef.current?.markError(errorId, error, metadata);
|
|
33266
33564
|
},
|
|
33267
33565
|
[]
|
|
33268
33566
|
);
|
|
33269
|
-
const markNavigation =
|
|
33567
|
+
const markNavigation = useCallback38((from, to) => {
|
|
33270
33568
|
recorderRef.current?.markNavigation(from, to);
|
|
33271
33569
|
}, []);
|
|
33272
|
-
const markConversion =
|
|
33570
|
+
const markConversion = useCallback38((name, value) => {
|
|
33273
33571
|
recorderRef.current?.markConversion(name, value);
|
|
33274
33572
|
}, []);
|
|
33275
|
-
const addMarker =
|
|
33573
|
+
const addMarker = useCallback38((type, payload) => {
|
|
33276
33574
|
recorderRef.current?.addMarker(type, payload);
|
|
33277
33575
|
}, []);
|
|
33278
33576
|
return {
|
|
@@ -33321,13 +33619,13 @@ function createDefaultUploadHandler(endpoint) {
|
|
|
33321
33619
|
};
|
|
33322
33620
|
}
|
|
33323
33621
|
function useSessionReplayErrorMarker() {
|
|
33324
|
-
const recorderRef =
|
|
33622
|
+
const recorderRef = useRef17(null);
|
|
33325
33623
|
useEffect48(() => {
|
|
33326
33624
|
if (typeof window !== "undefined" && window.__sylphxRecorder) {
|
|
33327
33625
|
recorderRef.current = window.__sylphxRecorder;
|
|
33328
33626
|
}
|
|
33329
33627
|
}, []);
|
|
33330
|
-
const markError =
|
|
33628
|
+
const markError = useCallback38((error, errorInfo) => {
|
|
33331
33629
|
const errorId = `err_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
33332
33630
|
recorderRef.current?.markError(errorId, error, {
|
|
33333
33631
|
componentStack: errorInfo?.componentStack?.slice(0, STACK_TRACE_MAX_LENGTH)
|
|
@@ -33346,11 +33644,11 @@ function withSessionReplay(Component2, options) {
|
|
|
33346
33644
|
}
|
|
33347
33645
|
|
|
33348
33646
|
// src/react/hooks/use-web-vitals.ts
|
|
33349
|
-
import { useCallback as
|
|
33647
|
+
import { useCallback as useCallback39, useEffect as useEffect49, useRef as useRef18, useState as useState58 } from "react";
|
|
33350
33648
|
function useWebVitals(options = {}) {
|
|
33351
33649
|
const { autoInit = true, onReport, ...config2 } = options;
|
|
33352
|
-
const [report, setReport] =
|
|
33353
|
-
const initRef =
|
|
33650
|
+
const [report, setReport] = useState58(null);
|
|
33651
|
+
const initRef = useRef18(false);
|
|
33354
33652
|
useEffect49(() => {
|
|
33355
33653
|
if (!autoInit || initRef.current) return;
|
|
33356
33654
|
if (typeof window === "undefined") return;
|
|
@@ -33366,10 +33664,10 @@ function useWebVitals(options = {}) {
|
|
|
33366
33664
|
return () => {
|
|
33367
33665
|
};
|
|
33368
33666
|
}, [autoInit, onReport]);
|
|
33369
|
-
const refresh =
|
|
33667
|
+
const refresh = useCallback39(() => {
|
|
33370
33668
|
setReport(getWebVitalsReport());
|
|
33371
33669
|
}, []);
|
|
33372
|
-
const reset =
|
|
33670
|
+
const reset = useCallback39(() => {
|
|
33373
33671
|
resetWebVitals();
|
|
33374
33672
|
setReport(null);
|
|
33375
33673
|
initRef.current = false;
|
|
@@ -33413,7 +33711,7 @@ function useWebVital({ metric }) {
|
|
|
33413
33711
|
}
|
|
33414
33712
|
function useWebVitalsAnalytics(options) {
|
|
33415
33713
|
const { track, eventPrefix = "web_vital", reportOnHide = true } = options;
|
|
33416
|
-
const reportedRef =
|
|
33714
|
+
const reportedRef = useRef18(false);
|
|
33417
33715
|
const webVitals = useWebVitals({
|
|
33418
33716
|
onReport: (metric) => {
|
|
33419
33717
|
track(`${eventPrefix}_${metric.name.toLowerCase()}`, {
|
|
@@ -33456,7 +33754,7 @@ function useWebVitalsAnalytics(options) {
|
|
|
33456
33754
|
|
|
33457
33755
|
// src/react/hooks/use-error-tracking.ts
|
|
33458
33756
|
init_constants();
|
|
33459
|
-
import { useCallback as
|
|
33757
|
+
import { useCallback as useCallback40, useEffect as useEffect50, useRef as useRef19 } from "react";
|
|
33460
33758
|
function useEnhancedErrorTracking(options = {}) {
|
|
33461
33759
|
const {
|
|
33462
33760
|
attachReplay = true,
|
|
@@ -33466,8 +33764,8 @@ function useEnhancedErrorTracking(options = {}) {
|
|
|
33466
33764
|
autoInit = true,
|
|
33467
33765
|
...trackerConfig
|
|
33468
33766
|
} = options;
|
|
33469
|
-
const trackerRef =
|
|
33470
|
-
const replaySessionIdRef =
|
|
33767
|
+
const trackerRef = useRef19(null);
|
|
33768
|
+
const replaySessionIdRef = useRef19(null);
|
|
33471
33769
|
useEffect50(() => {
|
|
33472
33770
|
if (typeof window === "undefined") return;
|
|
33473
33771
|
const tracker = getTracker({
|
|
@@ -33511,7 +33809,7 @@ function useEnhancedErrorTracking(options = {}) {
|
|
|
33511
33809
|
const interval = setInterval(checkReplaySession, SESSION_REPLAY_STATUS_CHECK_MS);
|
|
33512
33810
|
return () => clearInterval(interval);
|
|
33513
33811
|
}, [attachReplay]);
|
|
33514
|
-
const captureException =
|
|
33812
|
+
const captureException = useCallback40(
|
|
33515
33813
|
async (error, opts = {}) => {
|
|
33516
33814
|
if (!trackerRef.current) {
|
|
33517
33815
|
return { eventId: "" };
|
|
@@ -33539,7 +33837,7 @@ function useEnhancedErrorTracking(options = {}) {
|
|
|
33539
33837
|
},
|
|
33540
33838
|
[attachReplay, onCapture]
|
|
33541
33839
|
);
|
|
33542
|
-
const captureMessage =
|
|
33840
|
+
const captureMessage = useCallback40(
|
|
33543
33841
|
async (message, opts = {}) => {
|
|
33544
33842
|
if (!trackerRef.current) {
|
|
33545
33843
|
return { eventId: "" };
|
|
@@ -33550,20 +33848,20 @@ function useEnhancedErrorTracking(options = {}) {
|
|
|
33550
33848
|
},
|
|
33551
33849
|
[onCapture]
|
|
33552
33850
|
);
|
|
33553
|
-
const addBreadcrumb2 =
|
|
33851
|
+
const addBreadcrumb2 = useCallback40((breadcrumb) => {
|
|
33554
33852
|
trackerRef.current?.addBreadcrumb(breadcrumb);
|
|
33555
33853
|
}, []);
|
|
33556
|
-
const setUser =
|
|
33854
|
+
const setUser = useCallback40((user) => {
|
|
33557
33855
|
trackerRef.current?.setUser(user);
|
|
33558
33856
|
}, []);
|
|
33559
|
-
const clearUser =
|
|
33857
|
+
const clearUser = useCallback40(() => {
|
|
33560
33858
|
trackerRef.current?.clearUser();
|
|
33561
33859
|
}, []);
|
|
33562
|
-
const linkReplaySession =
|
|
33860
|
+
const linkReplaySession = useCallback40((sessionId) => {
|
|
33563
33861
|
replaySessionIdRef.current = sessionId;
|
|
33564
33862
|
trackerRef.current?.setSessionReplayId(sessionId);
|
|
33565
33863
|
}, []);
|
|
33566
|
-
const getReplaySessionId =
|
|
33864
|
+
const getReplaySessionId = useCallback40(() => {
|
|
33567
33865
|
return replaySessionIdRef.current;
|
|
33568
33866
|
}, []);
|
|
33569
33867
|
return {
|
|
@@ -34765,10 +35063,10 @@ var DEFAULT_FLAGS_CONFIG = {
|
|
|
34765
35063
|
};
|
|
34766
35064
|
|
|
34767
35065
|
// src/react/hooks/use-flag.ts
|
|
34768
|
-
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";
|
|
34769
35067
|
|
|
34770
35068
|
// src/react/hooks/use-flags.tsx
|
|
34771
|
-
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";
|
|
34772
35070
|
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
34773
35071
|
var FeatureFlagsContext = createContext7(null);
|
|
34774
35072
|
function FeatureFlagsProvider({
|
|
@@ -34780,14 +35078,14 @@ function FeatureFlagsProvider({
|
|
|
34780
35078
|
onReady,
|
|
34781
35079
|
onError
|
|
34782
35080
|
}) {
|
|
34783
|
-
const [isReady, setIsReady] =
|
|
34784
|
-
const [isLoading, setIsLoading] =
|
|
34785
|
-
const [error, setError] =
|
|
34786
|
-
const [updateVersion, setUpdateVersion] =
|
|
34787
|
-
const evaluatorRef =
|
|
34788
|
-
const streamRef =
|
|
34789
|
-
const experimentsRef =
|
|
34790
|
-
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(
|
|
34791
35089
|
(event) => {
|
|
34792
35090
|
switch (event.type) {
|
|
34793
35091
|
case "ready":
|
|
@@ -34859,7 +35157,7 @@ function FeatureFlagsProvider({
|
|
|
34859
35157
|
evaluatorRef.current.setContext(context);
|
|
34860
35158
|
}
|
|
34861
35159
|
}, [context]);
|
|
34862
|
-
const value =
|
|
35160
|
+
const value = useMemo12(
|
|
34863
35161
|
() => ({
|
|
34864
35162
|
evaluator: evaluatorRef.current,
|
|
34865
35163
|
stream: streamRef.current,
|
|
@@ -34878,53 +35176,53 @@ function FeatureFlagsProvider({
|
|
|
34878
35176
|
return /* @__PURE__ */ jsx49(FeatureFlagsContext.Provider, { value, children });
|
|
34879
35177
|
}
|
|
34880
35178
|
function useFeatureFlags2() {
|
|
34881
|
-
const ctx =
|
|
35179
|
+
const ctx = useContext19(FeatureFlagsContext);
|
|
34882
35180
|
if (!ctx) {
|
|
34883
35181
|
throw new Error("useFeatureFlags must be used within a FeatureFlagsProvider");
|
|
34884
35182
|
}
|
|
34885
35183
|
const { evaluator, isReady, isLoading, error, flags, updateVersion } = ctx;
|
|
34886
|
-
const isEnabled =
|
|
35184
|
+
const isEnabled = useCallback41(
|
|
34887
35185
|
(flagKey, defaultValue = false) => {
|
|
34888
35186
|
void updateVersion;
|
|
34889
35187
|
return evaluator.isEnabled(flagKey, defaultValue);
|
|
34890
35188
|
},
|
|
34891
35189
|
[evaluator, updateVersion]
|
|
34892
35190
|
);
|
|
34893
|
-
const getString =
|
|
35191
|
+
const getString = useCallback41(
|
|
34894
35192
|
(flagKey, defaultValue = "") => {
|
|
34895
35193
|
void updateVersion;
|
|
34896
35194
|
return evaluator.getString(flagKey, defaultValue);
|
|
34897
35195
|
},
|
|
34898
35196
|
[evaluator, updateVersion]
|
|
34899
35197
|
);
|
|
34900
|
-
const getNumber =
|
|
35198
|
+
const getNumber = useCallback41(
|
|
34901
35199
|
(flagKey, defaultValue = 0) => {
|
|
34902
35200
|
void updateVersion;
|
|
34903
35201
|
return evaluator.getNumber(flagKey, defaultValue);
|
|
34904
35202
|
},
|
|
34905
35203
|
[evaluator, updateVersion]
|
|
34906
35204
|
);
|
|
34907
|
-
const getJSON =
|
|
35205
|
+
const getJSON = useCallback41(
|
|
34908
35206
|
(flagKey, defaultValue) => {
|
|
34909
35207
|
void updateVersion;
|
|
34910
35208
|
return evaluator.getJSON(flagKey, defaultValue);
|
|
34911
35209
|
},
|
|
34912
35210
|
[evaluator, updateVersion]
|
|
34913
35211
|
);
|
|
34914
|
-
const evaluate =
|
|
35212
|
+
const evaluate = useCallback41(
|
|
34915
35213
|
(flagKey, defaultValue, contextOverride) => {
|
|
34916
35214
|
void updateVersion;
|
|
34917
35215
|
return evaluator.evaluate(flagKey, defaultValue, contextOverride);
|
|
34918
35216
|
},
|
|
34919
35217
|
[evaluator, updateVersion]
|
|
34920
35218
|
);
|
|
34921
|
-
const setContext =
|
|
35219
|
+
const setContext = useCallback41(
|
|
34922
35220
|
(context) => {
|
|
34923
35221
|
evaluator.setContext(context);
|
|
34924
35222
|
},
|
|
34925
35223
|
[evaluator]
|
|
34926
35224
|
);
|
|
34927
|
-
const updateContext =
|
|
35225
|
+
const updateContext = useCallback41(
|
|
34928
35226
|
(partial) => {
|
|
34929
35227
|
evaluator.updateContext(partial);
|
|
34930
35228
|
},
|
|
@@ -34946,7 +35244,7 @@ function useFeatureFlags2() {
|
|
|
34946
35244
|
}
|
|
34947
35245
|
function useFlag(flagKey, defaultValue = false) {
|
|
34948
35246
|
const { isEnabled, updateVersion } = useFeatureFlagsContext();
|
|
34949
|
-
return
|
|
35247
|
+
return useMemo12(
|
|
34950
35248
|
() => isEnabled(flagKey, defaultValue),
|
|
34951
35249
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34952
35250
|
[flagKey, defaultValue, isEnabled]
|
|
@@ -34954,7 +35252,7 @@ function useFlag(flagKey, defaultValue = false) {
|
|
|
34954
35252
|
}
|
|
34955
35253
|
function useFlagString(flagKey, defaultValue = "") {
|
|
34956
35254
|
const { getString, updateVersion } = useFeatureFlagsContext();
|
|
34957
|
-
return
|
|
35255
|
+
return useMemo12(
|
|
34958
35256
|
() => getString(flagKey, defaultValue),
|
|
34959
35257
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34960
35258
|
[flagKey, defaultValue, getString]
|
|
@@ -34962,7 +35260,7 @@ function useFlagString(flagKey, defaultValue = "") {
|
|
|
34962
35260
|
}
|
|
34963
35261
|
function useFlagNumber(flagKey, defaultValue = 0) {
|
|
34964
35262
|
const { getNumber, updateVersion } = useFeatureFlagsContext();
|
|
34965
|
-
return
|
|
35263
|
+
return useMemo12(
|
|
34966
35264
|
() => getNumber(flagKey, defaultValue),
|
|
34967
35265
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34968
35266
|
[flagKey, defaultValue, getNumber]
|
|
@@ -34970,7 +35268,7 @@ function useFlagNumber(flagKey, defaultValue = 0) {
|
|
|
34970
35268
|
}
|
|
34971
35269
|
function useFlagJSON(flagKey, defaultValue) {
|
|
34972
35270
|
const { getJSON, updateVersion } = useFeatureFlagsContext();
|
|
34973
|
-
return
|
|
35271
|
+
return useMemo12(
|
|
34974
35272
|
() => getJSON(flagKey, defaultValue),
|
|
34975
35273
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34976
35274
|
[flagKey, defaultValue, getJSON]
|
|
@@ -34978,19 +35276,19 @@ function useFlagJSON(flagKey, defaultValue) {
|
|
|
34978
35276
|
}
|
|
34979
35277
|
function useFlagEvaluation(flagKey, defaultValue, contextOverride) {
|
|
34980
35278
|
const { evaluate, updateVersion } = useFeatureFlagsContext();
|
|
34981
|
-
return
|
|
35279
|
+
return useMemo12(
|
|
34982
35280
|
() => evaluate(flagKey, defaultValue, contextOverride),
|
|
34983
35281
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34984
35282
|
[flagKey, defaultValue, contextOverride, evaluate]
|
|
34985
35283
|
);
|
|
34986
35284
|
}
|
|
34987
35285
|
function useExperiment(experimentKey) {
|
|
34988
|
-
const ctx =
|
|
35286
|
+
const ctx = useContext19(FeatureFlagsContext);
|
|
34989
35287
|
if (!ctx) {
|
|
34990
35288
|
throw new Error("useExperiment must be used within a FeatureFlagsProvider");
|
|
34991
35289
|
}
|
|
34992
35290
|
const { experiments, updateVersion } = ctx;
|
|
34993
|
-
return
|
|
35291
|
+
return useMemo12(() => {
|
|
34994
35292
|
const result = experiments.getVariant(experimentKey);
|
|
34995
35293
|
return {
|
|
34996
35294
|
variant: result.variant,
|
|
@@ -35008,7 +35306,7 @@ function useIsInTreatment(experimentKey) {
|
|
|
35008
35306
|
return inExperiment && variant !== "control";
|
|
35009
35307
|
}
|
|
35010
35308
|
function useFeatureFlagsContext() {
|
|
35011
|
-
const ctx =
|
|
35309
|
+
const ctx = useContext19(FeatureFlagsContext);
|
|
35012
35310
|
if (!ctx) {
|
|
35013
35311
|
throw new Error("Feature flags hooks must be used within a FeatureFlagsProvider");
|
|
35014
35312
|
}
|
|
@@ -35023,7 +35321,7 @@ function useFeatureFlagsContext() {
|
|
|
35023
35321
|
};
|
|
35024
35322
|
}
|
|
35025
35323
|
function useFlagsReady() {
|
|
35026
|
-
const ctx =
|
|
35324
|
+
const ctx = useContext19(FeatureFlagsContext);
|
|
35027
35325
|
if (!ctx) {
|
|
35028
35326
|
return { isReady: false, isLoading: true, error: null };
|
|
35029
35327
|
}
|
|
@@ -35043,22 +35341,22 @@ function useFlagStatus(key, options) {
|
|
|
35043
35341
|
pollInterval = DEFAULT_POLL_INTERVAL_MS2,
|
|
35044
35342
|
context: contextOverride
|
|
35045
35343
|
} = options ?? {};
|
|
35046
|
-
const ctx =
|
|
35047
|
-
const [enabled, setEnabled] =
|
|
35048
|
-
const [loading, setLoading] =
|
|
35049
|
-
const [error, setError] =
|
|
35050
|
-
const mountedRef =
|
|
35051
|
-
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(() => {
|
|
35052
35350
|
if (contextOverride) return contextOverride;
|
|
35053
35351
|
if (userId || attributes) return { userId, ...attributes };
|
|
35054
35352
|
return void 0;
|
|
35055
35353
|
}, [contextOverride, userId, attributes]);
|
|
35056
|
-
const evaluateLocally =
|
|
35354
|
+
const evaluateLocally = useCallback42(() => {
|
|
35057
35355
|
if (!ctx?.evaluator) return false;
|
|
35058
35356
|
const result = ctx.evaluator.evaluate(key, false, evalContext);
|
|
35059
35357
|
return result.value;
|
|
35060
35358
|
}, [ctx, key, evalContext]);
|
|
35061
|
-
const refetch =
|
|
35359
|
+
const refetch = useCallback42(async () => {
|
|
35062
35360
|
if (!mountedRef.current) return;
|
|
35063
35361
|
setError(null);
|
|
35064
35362
|
try {
|
|
@@ -37113,9 +37411,9 @@ var AnalyticsTracker = class {
|
|
|
37113
37411
|
}
|
|
37114
37412
|
}
|
|
37115
37413
|
getOrCreateAnonymousId() {
|
|
37116
|
-
const
|
|
37117
|
-
if (
|
|
37118
|
-
const stored =
|
|
37414
|
+
const storage2 = this.getStorage();
|
|
37415
|
+
if (storage2) {
|
|
37416
|
+
const stored = storage2.getItem(this.getStorageKey("anon_id"));
|
|
37119
37417
|
if (stored) return stored;
|
|
37120
37418
|
}
|
|
37121
37419
|
const id = this.generateId();
|
|
@@ -37123,33 +37421,33 @@ var AnalyticsTracker = class {
|
|
|
37123
37421
|
return id;
|
|
37124
37422
|
}
|
|
37125
37423
|
persistAnonymousId(id) {
|
|
37126
|
-
const
|
|
37127
|
-
if (
|
|
37128
|
-
|
|
37424
|
+
const storage2 = this.getStorage();
|
|
37425
|
+
if (storage2) {
|
|
37426
|
+
storage2.setItem(this.getStorageKey("anon_id"), id);
|
|
37129
37427
|
}
|
|
37130
37428
|
}
|
|
37131
37429
|
persistDistinctId(id) {
|
|
37132
|
-
const
|
|
37133
|
-
if (
|
|
37134
|
-
|
|
37430
|
+
const storage2 = this.getStorage();
|
|
37431
|
+
if (storage2) {
|
|
37432
|
+
storage2.setItem(this.getStorageKey("distinct_id"), id);
|
|
37135
37433
|
}
|
|
37136
37434
|
}
|
|
37137
37435
|
clearDistinctId() {
|
|
37138
|
-
const
|
|
37139
|
-
if (
|
|
37140
|
-
|
|
37436
|
+
const storage2 = this.getStorage();
|
|
37437
|
+
if (storage2) {
|
|
37438
|
+
storage2.removeItem(this.getStorageKey("distinct_id"));
|
|
37141
37439
|
}
|
|
37142
37440
|
}
|
|
37143
37441
|
getOrCreateSessionId() {
|
|
37144
|
-
const
|
|
37145
|
-
if (
|
|
37146
|
-
const stored =
|
|
37147
|
-
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"));
|
|
37148
37446
|
if (stored && timestamp) {
|
|
37149
37447
|
const lastActivity = Number.parseInt(timestamp, 10);
|
|
37150
37448
|
const timeout = this.config.sessionTimeout ?? ANALYTICS_SESSION_TIMEOUT_MS;
|
|
37151
37449
|
if (Date.now() - lastActivity < timeout) {
|
|
37152
|
-
|
|
37450
|
+
storage2.setItem(this.getStorageKey("session_ts"), Date.now().toString());
|
|
37153
37451
|
return stored;
|
|
37154
37452
|
}
|
|
37155
37453
|
}
|
|
@@ -37159,16 +37457,16 @@ var AnalyticsTracker = class {
|
|
|
37159
37457
|
return id;
|
|
37160
37458
|
}
|
|
37161
37459
|
persistSessionId(id) {
|
|
37162
|
-
const
|
|
37163
|
-
if (
|
|
37164
|
-
|
|
37165
|
-
|
|
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());
|
|
37166
37464
|
}
|
|
37167
37465
|
}
|
|
37168
37466
|
loadQueue() {
|
|
37169
|
-
const
|
|
37170
|
-
if (
|
|
37171
|
-
const stored =
|
|
37467
|
+
const storage2 = this.getStorage();
|
|
37468
|
+
if (storage2) {
|
|
37469
|
+
const stored = storage2.getItem(this.getStorageKey("queue"));
|
|
37172
37470
|
if (stored) {
|
|
37173
37471
|
try {
|
|
37174
37472
|
this.queue = JSON.parse(stored);
|
|
@@ -37179,22 +37477,22 @@ var AnalyticsTracker = class {
|
|
|
37179
37477
|
}
|
|
37180
37478
|
}
|
|
37181
37479
|
persistQueue() {
|
|
37182
|
-
const
|
|
37183
|
-
if (
|
|
37184
|
-
|
|
37480
|
+
const storage2 = this.getStorage();
|
|
37481
|
+
if (storage2) {
|
|
37482
|
+
storage2.setItem(this.getStorageKey("queue"), JSON.stringify(this.queue));
|
|
37185
37483
|
}
|
|
37186
37484
|
}
|
|
37187
37485
|
loadInitialAttribution(key) {
|
|
37188
|
-
const
|
|
37189
|
-
if (
|
|
37190
|
-
return
|
|
37486
|
+
const storage2 = this.getStorage();
|
|
37487
|
+
if (storage2) {
|
|
37488
|
+
return storage2.getItem(this.getStorageKey(key));
|
|
37191
37489
|
}
|
|
37192
37490
|
return null;
|
|
37193
37491
|
}
|
|
37194
37492
|
persistInitialAttribution(key, value) {
|
|
37195
|
-
const
|
|
37196
|
-
if (
|
|
37197
|
-
|
|
37493
|
+
const storage2 = this.getStorage();
|
|
37494
|
+
if (storage2) {
|
|
37495
|
+
storage2.setItem(this.getStorageKey(key), value);
|
|
37198
37496
|
}
|
|
37199
37497
|
}
|
|
37200
37498
|
// ==========================================
|
|
@@ -37234,7 +37532,7 @@ function resetAnalyticsTracker() {
|
|
|
37234
37532
|
|
|
37235
37533
|
// src/react/hooks/use-analytics.tsx
|
|
37236
37534
|
init_constants();
|
|
37237
|
-
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";
|
|
37238
37536
|
import { Fragment as Fragment34, jsx as jsx50 } from "react/jsx-runtime";
|
|
37239
37537
|
var AnalyticsContext = createContext8(null);
|
|
37240
37538
|
function AnalyticsProvider({
|
|
@@ -37243,7 +37541,7 @@ function AnalyticsProvider({
|
|
|
37243
37541
|
user,
|
|
37244
37542
|
disabled = false
|
|
37245
37543
|
}) {
|
|
37246
|
-
const trackerRef =
|
|
37544
|
+
const trackerRef = useRef22(null);
|
|
37247
37545
|
const [isReady, setIsReady] = React.useState(false);
|
|
37248
37546
|
useEffect53(() => {
|
|
37249
37547
|
if (disabled || typeof window === "undefined") return;
|
|
@@ -37259,7 +37557,7 @@ function AnalyticsProvider({
|
|
|
37259
37557
|
trackerRef.current.identify(user.id, user.properties);
|
|
37260
37558
|
}
|
|
37261
37559
|
}, [user]);
|
|
37262
|
-
const value =
|
|
37560
|
+
const value = useMemo14(() => {
|
|
37263
37561
|
if (!trackerRef.current || disabled) return null;
|
|
37264
37562
|
return {
|
|
37265
37563
|
tracker: trackerRef.current,
|
|
@@ -37272,58 +37570,58 @@ function AnalyticsProvider({
|
|
|
37272
37570
|
return /* @__PURE__ */ jsx50(AnalyticsContext.Provider, { value, children });
|
|
37273
37571
|
}
|
|
37274
37572
|
function useAnalyticsHook() {
|
|
37275
|
-
const ctx =
|
|
37573
|
+
const ctx = useContext21(AnalyticsContext);
|
|
37276
37574
|
const tracker = ctx?.tracker ?? null;
|
|
37277
37575
|
const isReady = ctx?.isReady ?? false;
|
|
37278
|
-
const track =
|
|
37576
|
+
const track = useCallback43(
|
|
37279
37577
|
(eventName, properties) => {
|
|
37280
37578
|
tracker?.track(eventName, properties);
|
|
37281
37579
|
},
|
|
37282
37580
|
[tracker]
|
|
37283
37581
|
);
|
|
37284
|
-
const identify =
|
|
37582
|
+
const identify = useCallback43(
|
|
37285
37583
|
(userId, properties) => {
|
|
37286
37584
|
tracker?.identify(userId, properties);
|
|
37287
37585
|
},
|
|
37288
37586
|
[tracker]
|
|
37289
37587
|
);
|
|
37290
|
-
const reset =
|
|
37588
|
+
const reset = useCallback43(() => {
|
|
37291
37589
|
tracker?.reset();
|
|
37292
37590
|
}, [tracker]);
|
|
37293
|
-
const setUserProperties =
|
|
37591
|
+
const setUserProperties = useCallback43(
|
|
37294
37592
|
(properties) => {
|
|
37295
37593
|
tracker?.setUserProperties(properties);
|
|
37296
37594
|
},
|
|
37297
37595
|
[tracker]
|
|
37298
37596
|
);
|
|
37299
|
-
const setUserPropertiesOnce =
|
|
37597
|
+
const setUserPropertiesOnce = useCallback43(
|
|
37300
37598
|
(properties) => {
|
|
37301
37599
|
tracker?.setUserPropertiesOnce(properties);
|
|
37302
37600
|
},
|
|
37303
37601
|
[tracker]
|
|
37304
37602
|
);
|
|
37305
|
-
const incrementUserProperty =
|
|
37603
|
+
const incrementUserProperty = useCallback43(
|
|
37306
37604
|
(property, value) => {
|
|
37307
37605
|
tracker?.incrementUserProperty(property, value);
|
|
37308
37606
|
},
|
|
37309
37607
|
[tracker]
|
|
37310
37608
|
);
|
|
37311
|
-
const group =
|
|
37609
|
+
const group = useCallback43(
|
|
37312
37610
|
(groupType, groupKey, properties) => {
|
|
37313
37611
|
tracker?.group(groupType, groupKey, properties);
|
|
37314
37612
|
},
|
|
37315
37613
|
[tracker]
|
|
37316
37614
|
);
|
|
37317
|
-
const register =
|
|
37615
|
+
const register = useCallback43(
|
|
37318
37616
|
(properties) => {
|
|
37319
37617
|
tracker?.register(properties);
|
|
37320
37618
|
},
|
|
37321
37619
|
[tracker]
|
|
37322
37620
|
);
|
|
37323
|
-
const getDistinctId =
|
|
37621
|
+
const getDistinctId = useCallback43(() => {
|
|
37324
37622
|
return tracker?.getDistinctId() ?? null;
|
|
37325
37623
|
}, [tracker]);
|
|
37326
|
-
const flush =
|
|
37624
|
+
const flush = useCallback43(async () => {
|
|
37327
37625
|
await tracker?.flush();
|
|
37328
37626
|
}, [tracker]);
|
|
37329
37627
|
return {
|
|
@@ -37342,7 +37640,7 @@ function useAnalyticsHook() {
|
|
|
37342
37640
|
}
|
|
37343
37641
|
function usePageView(pageName, properties) {
|
|
37344
37642
|
const { track, isReady } = useAnalyticsHook();
|
|
37345
|
-
const hasTracked =
|
|
37643
|
+
const hasTracked = useRef22(false);
|
|
37346
37644
|
useEffect53(() => {
|
|
37347
37645
|
if (!isReady || hasTracked.current) return;
|
|
37348
37646
|
hasTracked.current = true;
|
|
@@ -37354,8 +37652,8 @@ function usePageView(pageName, properties) {
|
|
|
37354
37652
|
}
|
|
37355
37653
|
function useComponentTracking(componentName, properties) {
|
|
37356
37654
|
const { track, isReady } = useAnalyticsHook();
|
|
37357
|
-
const mountTime =
|
|
37358
|
-
const hasTracked =
|
|
37655
|
+
const mountTime = useRef22(Date.now());
|
|
37656
|
+
const hasTracked = useRef22(false);
|
|
37359
37657
|
useEffect53(() => {
|
|
37360
37658
|
if (!isReady || hasTracked.current) return;
|
|
37361
37659
|
hasTracked.current = true;
|
|
@@ -37374,7 +37672,7 @@ function useComponentTracking(componentName, properties) {
|
|
|
37374
37672
|
}
|
|
37375
37673
|
function useFeatureTracking(featureName) {
|
|
37376
37674
|
const { track } = useAnalyticsHook();
|
|
37377
|
-
const trackUsed =
|
|
37675
|
+
const trackUsed = useCallback43(
|
|
37378
37676
|
(properties) => {
|
|
37379
37677
|
track("feature_used", {
|
|
37380
37678
|
feature: featureName,
|
|
@@ -37383,7 +37681,7 @@ function useFeatureTracking(featureName) {
|
|
|
37383
37681
|
},
|
|
37384
37682
|
[track, featureName]
|
|
37385
37683
|
);
|
|
37386
|
-
const trackError =
|
|
37684
|
+
const trackError = useCallback43(
|
|
37387
37685
|
(error, properties) => {
|
|
37388
37686
|
track("feature_error", {
|
|
37389
37687
|
feature: featureName,
|
|
@@ -37398,13 +37696,13 @@ function useFeatureTracking(featureName) {
|
|
|
37398
37696
|
}
|
|
37399
37697
|
function useFormTracking(formName) {
|
|
37400
37698
|
const { track } = useAnalyticsHook();
|
|
37401
|
-
const startTime =
|
|
37402
|
-
const fieldsFilledRef =
|
|
37403
|
-
const trackStarted =
|
|
37699
|
+
const startTime = useRef22(null);
|
|
37700
|
+
const fieldsFilledRef = useRef22(/* @__PURE__ */ new Set());
|
|
37701
|
+
const trackStarted = useCallback43(() => {
|
|
37404
37702
|
startTime.current = Date.now();
|
|
37405
37703
|
track("form_started", { form: formName });
|
|
37406
37704
|
}, [track, formName]);
|
|
37407
|
-
const trackCompleted =
|
|
37705
|
+
const trackCompleted = useCallback43(
|
|
37408
37706
|
(properties) => {
|
|
37409
37707
|
const duration = startTime.current ? Date.now() - startTime.current : void 0;
|
|
37410
37708
|
track("form_completed", {
|
|
@@ -37416,7 +37714,7 @@ function useFormTracking(formName) {
|
|
|
37416
37714
|
},
|
|
37417
37715
|
[track, formName]
|
|
37418
37716
|
);
|
|
37419
|
-
const trackAbandoned =
|
|
37717
|
+
const trackAbandoned = useCallback43(() => {
|
|
37420
37718
|
const duration = startTime.current ? Date.now() - startTime.current : void 0;
|
|
37421
37719
|
track("form_abandoned", {
|
|
37422
37720
|
form: formName,
|
|
@@ -37424,7 +37722,7 @@ function useFormTracking(formName) {
|
|
|
37424
37722
|
fields_filled: fieldsFilledRef.current.size
|
|
37425
37723
|
});
|
|
37426
37724
|
}, [track, formName]);
|
|
37427
|
-
const trackFieldFilled =
|
|
37725
|
+
const trackFieldFilled = useCallback43(
|
|
37428
37726
|
(fieldName) => {
|
|
37429
37727
|
if (!fieldsFilledRef.current.has(fieldName)) {
|
|
37430
37728
|
fieldsFilledRef.current.add(fieldName);
|
|
@@ -37436,7 +37734,7 @@ function useFormTracking(formName) {
|
|
|
37436
37734
|
},
|
|
37437
37735
|
[track, formName]
|
|
37438
37736
|
);
|
|
37439
|
-
const trackError =
|
|
37737
|
+
const trackError = useCallback43(
|
|
37440
37738
|
(fieldName, error) => {
|
|
37441
37739
|
track("form_field_error", {
|
|
37442
37740
|
form: formName,
|
|
@@ -37456,12 +37754,12 @@ function useFormTracking(formName) {
|
|
|
37456
37754
|
}
|
|
37457
37755
|
function useTimeTracking(name, options) {
|
|
37458
37756
|
const { track } = useAnalyticsHook();
|
|
37459
|
-
const startTime =
|
|
37460
|
-
const trackedIntervals =
|
|
37461
|
-
const getTimeSpent =
|
|
37757
|
+
const startTime = useRef22(Date.now());
|
|
37758
|
+
const trackedIntervals = useRef22(/* @__PURE__ */ new Set());
|
|
37759
|
+
const getTimeSpent = useCallback43(() => {
|
|
37462
37760
|
return Date.now() - startTime.current;
|
|
37463
37761
|
}, []);
|
|
37464
|
-
const trackNow =
|
|
37762
|
+
const trackNow = useCallback43(() => {
|
|
37465
37763
|
track("time_spent", {
|
|
37466
37764
|
name,
|
|
37467
37765
|
duration_ms: getTimeSpent()
|
|
@@ -37498,8 +37796,8 @@ function useTimeTracking(name, options) {
|
|
|
37498
37796
|
}
|
|
37499
37797
|
|
|
37500
37798
|
// src/react/hooks/use-destination-router.tsx
|
|
37501
|
-
import { useCallback as
|
|
37502
|
-
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";
|
|
37503
37801
|
import { jsx as jsx51 } from "react/jsx-runtime";
|
|
37504
37802
|
function useDestinationRouter(options) {
|
|
37505
37803
|
const {
|
|
@@ -37509,11 +37807,11 @@ function useDestinationRouter(options) {
|
|
|
37509
37807
|
autoInit = true,
|
|
37510
37808
|
debug = false
|
|
37511
37809
|
} = options;
|
|
37512
|
-
const routerRef =
|
|
37513
|
-
const initializedRef =
|
|
37810
|
+
const routerRef = useRef23(null);
|
|
37811
|
+
const initializedRef = useRef23(false);
|
|
37514
37812
|
const { hasConsent: checkConsent } = useConsent();
|
|
37515
37813
|
const { user } = useUser();
|
|
37516
|
-
const router =
|
|
37814
|
+
const router = useMemo15(() => {
|
|
37517
37815
|
if (!autoInit || typeof window === "undefined") return null;
|
|
37518
37816
|
const newRouter = createDestinationRouter({
|
|
37519
37817
|
destinations,
|
|
@@ -37538,46 +37836,46 @@ function useDestinationRouter(options) {
|
|
|
37538
37836
|
name: user.name
|
|
37539
37837
|
});
|
|
37540
37838
|
}, [syncUser, user?.id, user?.email, user?.name]);
|
|
37541
|
-
const track =
|
|
37839
|
+
const track = useCallback44(
|
|
37542
37840
|
(event, properties) => {
|
|
37543
37841
|
router?.track(event, properties);
|
|
37544
37842
|
},
|
|
37545
37843
|
[router]
|
|
37546
37844
|
);
|
|
37547
|
-
const trackTo =
|
|
37845
|
+
const trackTo = useCallback44(
|
|
37548
37846
|
(destinationType, event, properties) => {
|
|
37549
37847
|
router?.trackTo(destinationType, event, properties);
|
|
37550
37848
|
},
|
|
37551
37849
|
[router]
|
|
37552
37850
|
);
|
|
37553
|
-
const identify =
|
|
37851
|
+
const identify = useCallback44(
|
|
37554
37852
|
(userId, traits) => {
|
|
37555
37853
|
router?.identify(userId, traits);
|
|
37556
37854
|
},
|
|
37557
37855
|
[router]
|
|
37558
37856
|
);
|
|
37559
|
-
const page =
|
|
37857
|
+
const page = useCallback44(
|
|
37560
37858
|
(name, properties) => {
|
|
37561
37859
|
router?.page(name, properties);
|
|
37562
37860
|
},
|
|
37563
37861
|
[router]
|
|
37564
37862
|
);
|
|
37565
|
-
const getEnabledDestinations =
|
|
37863
|
+
const getEnabledDestinations = useCallback44(() => {
|
|
37566
37864
|
return router?.getEnabledDestinations() || [];
|
|
37567
37865
|
}, [router]);
|
|
37568
|
-
const setDestinationEnabled =
|
|
37866
|
+
const setDestinationEnabled = useCallback44(
|
|
37569
37867
|
(type, enabled) => {
|
|
37570
37868
|
router?.setDestinationEnabled(type, enabled);
|
|
37571
37869
|
},
|
|
37572
37870
|
[router]
|
|
37573
37871
|
);
|
|
37574
|
-
const setConsentChecker =
|
|
37872
|
+
const setConsentChecker = useCallback44(
|
|
37575
37873
|
(fn) => {
|
|
37576
37874
|
router?.setConsentChecker(fn);
|
|
37577
37875
|
},
|
|
37578
37876
|
[router]
|
|
37579
37877
|
);
|
|
37580
|
-
const setDistinctId =
|
|
37878
|
+
const setDistinctId = useCallback44(
|
|
37581
37879
|
(id) => {
|
|
37582
37880
|
router?.setDistinctId(id);
|
|
37583
37881
|
},
|
|
@@ -37605,7 +37903,7 @@ function DestinationRouterProvider({
|
|
|
37605
37903
|
return /* @__PURE__ */ jsx51(DestinationRouterContext.Provider, { value: router, children });
|
|
37606
37904
|
}
|
|
37607
37905
|
function useRouterContext() {
|
|
37608
|
-
return
|
|
37906
|
+
return useContext22(DestinationRouterContext);
|
|
37609
37907
|
}
|
|
37610
37908
|
|
|
37611
37909
|
// src/lib/tasks/handler.ts
|
|
@@ -38342,7 +38640,7 @@ function delay(ms) {
|
|
|
38342
38640
|
function sleepUntil(date) {
|
|
38343
38641
|
return wait(date);
|
|
38344
38642
|
}
|
|
38345
|
-
function
|
|
38643
|
+
function withRetry2(step, options) {
|
|
38346
38644
|
return {
|
|
38347
38645
|
...step,
|
|
38348
38646
|
options: {
|
|
@@ -38435,7 +38733,7 @@ var job = task;
|
|
|
38435
38733
|
|
|
38436
38734
|
// src/react/hooks/use-realtime.ts
|
|
38437
38735
|
init_constants();
|
|
38438
|
-
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";
|
|
38439
38737
|
function useRealtime(channel, options = {}) {
|
|
38440
38738
|
const {
|
|
38441
38739
|
events,
|
|
@@ -38447,17 +38745,17 @@ function useRealtime(channel, options = {}) {
|
|
|
38447
38745
|
enabled = true,
|
|
38448
38746
|
platformUrl: customPlatformUrl
|
|
38449
38747
|
} = options;
|
|
38450
|
-
const [messages, setMessages] =
|
|
38451
|
-
const [status, setStatus] =
|
|
38452
|
-
const platformContext =
|
|
38748
|
+
const [messages, setMessages] = useState61([]);
|
|
38749
|
+
const [status, setStatus] = useState61("disconnected");
|
|
38750
|
+
const platformContext = useContext23(PlatformContext);
|
|
38453
38751
|
const appId = platformContext?.appId || "";
|
|
38454
|
-
const lastAckRef =
|
|
38455
|
-
const eventSourceRef =
|
|
38456
|
-
const reconnectTimeoutRef =
|
|
38457
|
-
const reconnectAttemptRef =
|
|
38458
|
-
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);
|
|
38459
38757
|
const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
|
|
38460
|
-
const buildUrl =
|
|
38758
|
+
const buildUrl = useCallback45(() => {
|
|
38461
38759
|
const url = new URL(`${platformUrl}${SDK_API_PATH}/realtime/subscribe`);
|
|
38462
38760
|
url.searchParams.set("channel", channel);
|
|
38463
38761
|
if (lastAckRef.current !== "0") {
|
|
@@ -38465,7 +38763,7 @@ function useRealtime(channel, options = {}) {
|
|
|
38465
38763
|
}
|
|
38466
38764
|
return url.toString();
|
|
38467
38765
|
}, [platformUrl, channel]);
|
|
38468
|
-
const sdkHeaders =
|
|
38766
|
+
const sdkHeaders = useMemo16(
|
|
38469
38767
|
() => ({
|
|
38470
38768
|
"Content-Type": "application/json",
|
|
38471
38769
|
"x-app-secret": appId,
|
|
@@ -38474,7 +38772,7 @@ function useRealtime(channel, options = {}) {
|
|
|
38474
38772
|
}),
|
|
38475
38773
|
[appId]
|
|
38476
38774
|
);
|
|
38477
|
-
const fetchHistory =
|
|
38775
|
+
const fetchHistory = useCallback45(async () => {
|
|
38478
38776
|
if (!history2) return;
|
|
38479
38777
|
const historyLimit = typeof history2 === "number" ? history2 : history2.limit ?? 100;
|
|
38480
38778
|
const historyStart = typeof history2 === "object" ? history2.start : void 0;
|
|
@@ -38498,7 +38796,7 @@ function useRealtime(channel, options = {}) {
|
|
|
38498
38796
|
} catch {
|
|
38499
38797
|
}
|
|
38500
38798
|
}, [platformUrl, sdkHeaders, channel, history2]);
|
|
38501
|
-
const connect =
|
|
38799
|
+
const connect = useCallback45(() => {
|
|
38502
38800
|
if (!enabled || !appId) return;
|
|
38503
38801
|
if (eventSourceRef.current) {
|
|
38504
38802
|
eventSourceRef.current.close();
|
|
@@ -38569,7 +38867,7 @@ function useRealtime(channel, options = {}) {
|
|
|
38569
38867
|
onReconnect,
|
|
38570
38868
|
onError
|
|
38571
38869
|
]);
|
|
38572
|
-
const disconnect =
|
|
38870
|
+
const disconnect = useCallback45(() => {
|
|
38573
38871
|
if (eventSourceRef.current) {
|
|
38574
38872
|
eventSourceRef.current.close();
|
|
38575
38873
|
eventSourceRef.current = null;
|
|
@@ -38580,7 +38878,7 @@ function useRealtime(channel, options = {}) {
|
|
|
38580
38878
|
}
|
|
38581
38879
|
setStatus("disconnected");
|
|
38582
38880
|
}, []);
|
|
38583
|
-
const emit =
|
|
38881
|
+
const emit = useCallback45(
|
|
38584
38882
|
async (event, data) => {
|
|
38585
38883
|
const response = await fetch(`${platformUrl}${SDK_API_PATH}/realtime/emit`, {
|
|
38586
38884
|
method: "POST",
|
|
@@ -38612,7 +38910,7 @@ function useRealtime(channel, options = {}) {
|
|
|
38612
38910
|
},
|
|
38613
38911
|
[platformUrl, sdkHeaders, channel]
|
|
38614
38912
|
);
|
|
38615
|
-
const clear =
|
|
38913
|
+
const clear = useCallback45(() => {
|
|
38616
38914
|
setMessages([]);
|
|
38617
38915
|
lastAckRef.current = "0";
|
|
38618
38916
|
}, []);
|
|
@@ -38645,14 +38943,14 @@ function useRealtimeChannels(channels, options = {}) {
|
|
|
38645
38943
|
enabled = true,
|
|
38646
38944
|
platformUrl: customPlatformUrl
|
|
38647
38945
|
} = options;
|
|
38648
|
-
const [messages, setMessages] =
|
|
38649
|
-
const [statuses, setStatuses] =
|
|
38650
|
-
const platformContext =
|
|
38946
|
+
const [messages, setMessages] = useState61([]);
|
|
38947
|
+
const [statuses, setStatuses] = useState61({});
|
|
38948
|
+
const platformContext = useContext23(PlatformContext);
|
|
38651
38949
|
const appId = platformContext?.appId || "";
|
|
38652
38950
|
const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
|
|
38653
|
-
const lastAcksRef =
|
|
38654
|
-
const eventSourcesRef =
|
|
38655
|
-
const mountedRef =
|
|
38951
|
+
const lastAcksRef = useRef24({});
|
|
38952
|
+
const eventSourcesRef = useRef24({});
|
|
38953
|
+
const mountedRef = useRef24(true);
|
|
38656
38954
|
const status = (() => {
|
|
38657
38955
|
const statusValues = Object.values(statuses);
|
|
38658
38956
|
if (statusValues.length === 0) return "disconnected";
|
|
@@ -38661,7 +38959,7 @@ function useRealtimeChannels(channels, options = {}) {
|
|
|
38661
38959
|
if (statusValues.every((s2) => s2 === "connected")) return "connected";
|
|
38662
38960
|
return "disconnected";
|
|
38663
38961
|
})();
|
|
38664
|
-
const connectChannel =
|
|
38962
|
+
const connectChannel = useCallback45(
|
|
38665
38963
|
(channel) => {
|
|
38666
38964
|
if (!enabled || !appId) return;
|
|
38667
38965
|
if (eventSourcesRef.current[channel]) {
|
|
@@ -38711,17 +39009,17 @@ function useRealtimeChannels(channels, options = {}) {
|
|
|
38711
39009
|
},
|
|
38712
39010
|
[enabled, appId, platformUrl, events, onConnect, onMessage, onReconnect, onError]
|
|
38713
39011
|
);
|
|
38714
|
-
const connect =
|
|
39012
|
+
const connect = useCallback45(() => {
|
|
38715
39013
|
channels.forEach(connectChannel);
|
|
38716
39014
|
}, [channels, connectChannel]);
|
|
38717
|
-
const disconnect =
|
|
39015
|
+
const disconnect = useCallback45(() => {
|
|
38718
39016
|
Object.values(eventSourcesRef.current).forEach((es) => {
|
|
38719
39017
|
es.close();
|
|
38720
39018
|
});
|
|
38721
39019
|
eventSourcesRef.current = {};
|
|
38722
39020
|
setStatuses({});
|
|
38723
39021
|
}, []);
|
|
38724
|
-
const sdkHeaders =
|
|
39022
|
+
const sdkHeaders = useMemo16(
|
|
38725
39023
|
() => ({
|
|
38726
39024
|
"Content-Type": "application/json",
|
|
38727
39025
|
"x-app-secret": appId,
|
|
@@ -38730,7 +39028,7 @@ function useRealtimeChannels(channels, options = {}) {
|
|
|
38730
39028
|
}),
|
|
38731
39029
|
[appId]
|
|
38732
39030
|
);
|
|
38733
|
-
const emit =
|
|
39031
|
+
const emit = useCallback45(
|
|
38734
39032
|
async (event, data, targetChannel) => {
|
|
38735
39033
|
const channel = targetChannel || channels[0];
|
|
38736
39034
|
if (!channel) throw new SylphxError("No channel specified", { code: "BAD_REQUEST" });
|
|
@@ -38757,7 +39055,7 @@ function useRealtimeChannels(channels, options = {}) {
|
|
|
38757
39055
|
},
|
|
38758
39056
|
[channels, platformUrl, sdkHeaders]
|
|
38759
39057
|
);
|
|
38760
|
-
const clear =
|
|
39058
|
+
const clear = useCallback45(() => {
|
|
38761
39059
|
setMessages([]);
|
|
38762
39060
|
lastAcksRef.current = {};
|
|
38763
39061
|
}, []);
|
|
@@ -38783,13 +39081,13 @@ function useRealtimeChannels(channels, options = {}) {
|
|
|
38783
39081
|
|
|
38784
39082
|
// src/react/hooks/use-kv.ts
|
|
38785
39083
|
init_constants();
|
|
38786
|
-
import { useCallback as
|
|
39084
|
+
import { useCallback as useCallback46, useContext as useContext24, useMemo as useMemo17 } from "react";
|
|
38787
39085
|
function useKv(options = {}) {
|
|
38788
39086
|
const { platformUrl: customPlatformUrl } = options;
|
|
38789
|
-
const platformContext =
|
|
39087
|
+
const platformContext = useContext24(PlatformContext);
|
|
38790
39088
|
const appId = platformContext?.appId || "";
|
|
38791
39089
|
const platformUrl = customPlatformUrl || platformContext?.platformUrl || `https://${DEFAULT_SDK_API_HOST}`;
|
|
38792
|
-
const headers =
|
|
39090
|
+
const headers = useMemo17(
|
|
38793
39091
|
() => ({
|
|
38794
39092
|
"Content-Type": "application/json",
|
|
38795
39093
|
"x-app-secret": appId,
|
|
@@ -38798,7 +39096,7 @@ function useKv(options = {}) {
|
|
|
38798
39096
|
}),
|
|
38799
39097
|
[appId]
|
|
38800
39098
|
);
|
|
38801
|
-
const request =
|
|
39099
|
+
const request = useCallback46(
|
|
38802
39100
|
async (method, path, body) => {
|
|
38803
39101
|
let lastError;
|
|
38804
39102
|
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
@@ -38854,13 +39152,13 @@ function useKv(options = {}) {
|
|
|
38854
39152
|
},
|
|
38855
39153
|
[platformUrl, headers]
|
|
38856
39154
|
);
|
|
38857
|
-
const get =
|
|
39155
|
+
const get = useCallback46(
|
|
38858
39156
|
async (key) => {
|
|
38859
39157
|
return request("GET", `/${encodeURIComponent(key)}`);
|
|
38860
39158
|
},
|
|
38861
39159
|
[request]
|
|
38862
39160
|
);
|
|
38863
|
-
const set =
|
|
39161
|
+
const set = useCallback46(
|
|
38864
39162
|
async (key, value, options2) => {
|
|
38865
39163
|
const result = await request("POST", "", {
|
|
38866
39164
|
key,
|
|
@@ -38871,28 +39169,28 @@ function useKv(options = {}) {
|
|
|
38871
39169
|
},
|
|
38872
39170
|
[request]
|
|
38873
39171
|
);
|
|
38874
|
-
const del =
|
|
39172
|
+
const del = useCallback46(
|
|
38875
39173
|
async (key) => {
|
|
38876
39174
|
const result = await request("DELETE", `/${encodeURIComponent(key)}`);
|
|
38877
39175
|
return result.deleted;
|
|
38878
39176
|
},
|
|
38879
39177
|
[request]
|
|
38880
39178
|
);
|
|
38881
|
-
const exists =
|
|
39179
|
+
const exists = useCallback46(
|
|
38882
39180
|
async (key) => {
|
|
38883
39181
|
const result = await request("GET", `/exists/${encodeURIComponent(key)}`);
|
|
38884
39182
|
return result.exists;
|
|
38885
39183
|
},
|
|
38886
39184
|
[request]
|
|
38887
39185
|
);
|
|
38888
|
-
const mget =
|
|
39186
|
+
const mget = useCallback46(
|
|
38889
39187
|
async (keys) => {
|
|
38890
39188
|
const result = await request("POST", "/mget", { keys });
|
|
38891
39189
|
return result.values;
|
|
38892
39190
|
},
|
|
38893
39191
|
[request]
|
|
38894
39192
|
);
|
|
38895
|
-
const mset =
|
|
39193
|
+
const mset = useCallback46(
|
|
38896
39194
|
async (entries, options2) => {
|
|
38897
39195
|
await request("POST", "/mset", {
|
|
38898
39196
|
entries,
|
|
@@ -38901,7 +39199,7 @@ function useKv(options = {}) {
|
|
|
38901
39199
|
},
|
|
38902
39200
|
[request]
|
|
38903
39201
|
);
|
|
38904
|
-
const incr =
|
|
39202
|
+
const incr = useCallback46(
|
|
38905
39203
|
async (key, by = 1) => {
|
|
38906
39204
|
const result = await request("POST", "/incr", {
|
|
38907
39205
|
key,
|
|
@@ -38911,7 +39209,7 @@ function useKv(options = {}) {
|
|
|
38911
39209
|
},
|
|
38912
39210
|
[request]
|
|
38913
39211
|
);
|
|
38914
|
-
const expire =
|
|
39212
|
+
const expire = useCallback46(
|
|
38915
39213
|
async (key, seconds) => {
|
|
38916
39214
|
const result = await request("POST", "/expire", {
|
|
38917
39215
|
key,
|
|
@@ -38921,7 +39219,7 @@ function useKv(options = {}) {
|
|
|
38921
39219
|
},
|
|
38922
39220
|
[request]
|
|
38923
39221
|
);
|
|
38924
|
-
const ratelimit =
|
|
39222
|
+
const ratelimit = useCallback46(
|
|
38925
39223
|
async (key, options2) => {
|
|
38926
39224
|
return request("POST", "/ratelimit", {
|
|
38927
39225
|
key,
|
|
@@ -38930,7 +39228,7 @@ function useKv(options = {}) {
|
|
|
38930
39228
|
},
|
|
38931
39229
|
[request]
|
|
38932
39230
|
);
|
|
38933
|
-
const hset =
|
|
39231
|
+
const hset = useCallback46(
|
|
38934
39232
|
async (key, fields) => {
|
|
38935
39233
|
const result = await request("POST", "/hset", {
|
|
38936
39234
|
key,
|
|
@@ -38940,7 +39238,7 @@ function useKv(options = {}) {
|
|
|
38940
39238
|
},
|
|
38941
39239
|
[request]
|
|
38942
39240
|
);
|
|
38943
|
-
const hget =
|
|
39241
|
+
const hget = useCallback46(
|
|
38944
39242
|
async (key, field) => {
|
|
38945
39243
|
const result = await request("POST", "/hget", {
|
|
38946
39244
|
key,
|
|
@@ -38950,7 +39248,7 @@ function useKv(options = {}) {
|
|
|
38950
39248
|
},
|
|
38951
39249
|
[request]
|
|
38952
39250
|
);
|
|
38953
|
-
const hgetall =
|
|
39251
|
+
const hgetall = useCallback46(
|
|
38954
39252
|
async (key) => {
|
|
38955
39253
|
const result = await request("POST", "/hgetall", {
|
|
38956
39254
|
key
|
|
@@ -38959,7 +39257,7 @@ function useKv(options = {}) {
|
|
|
38959
39257
|
},
|
|
38960
39258
|
[request]
|
|
38961
39259
|
);
|
|
38962
|
-
const lpush =
|
|
39260
|
+
const lpush = useCallback46(
|
|
38963
39261
|
async (key, ...values) => {
|
|
38964
39262
|
const result = await request("POST", "/lpush", {
|
|
38965
39263
|
key,
|
|
@@ -38969,7 +39267,7 @@ function useKv(options = {}) {
|
|
|
38969
39267
|
},
|
|
38970
39268
|
[request]
|
|
38971
39269
|
);
|
|
38972
|
-
const lrange =
|
|
39270
|
+
const lrange = useCallback46(
|
|
38973
39271
|
async (key, start = 0, stop = -1) => {
|
|
38974
39272
|
const result = await request("POST", "/lrange", {
|
|
38975
39273
|
key,
|
|
@@ -38980,7 +39278,7 @@ function useKv(options = {}) {
|
|
|
38980
39278
|
},
|
|
38981
39279
|
[request]
|
|
38982
39280
|
);
|
|
38983
|
-
const zadd =
|
|
39281
|
+
const zadd = useCallback46(
|
|
38984
39282
|
async (key, ...members) => {
|
|
38985
39283
|
const result = await request("POST", "/zadd", {
|
|
38986
39284
|
key,
|
|
@@ -38990,7 +39288,7 @@ function useKv(options = {}) {
|
|
|
38990
39288
|
},
|
|
38991
39289
|
[request]
|
|
38992
39290
|
);
|
|
38993
|
-
const zrange =
|
|
39291
|
+
const zrange = useCallback46(
|
|
38994
39292
|
async (key, start = 0, stop = 9, options2) => {
|
|
38995
39293
|
const result = await request("POST", "/zrange", {
|
|
38996
39294
|
key,
|
|
@@ -39003,7 +39301,7 @@ function useKv(options = {}) {
|
|
|
39003
39301
|
},
|
|
39004
39302
|
[request]
|
|
39005
39303
|
);
|
|
39006
|
-
return
|
|
39304
|
+
return useMemo17(
|
|
39007
39305
|
() => ({
|
|
39008
39306
|
get,
|
|
39009
39307
|
set,
|
|
@@ -39044,7 +39342,7 @@ function useKv(options = {}) {
|
|
|
39044
39342
|
}
|
|
39045
39343
|
|
|
39046
39344
|
// src/react/hooks/use-search.ts
|
|
39047
|
-
import { useCallback as
|
|
39345
|
+
import { useCallback as useCallback47, useEffect as useEffect56, useRef as useRef25, useState as useState62 } from "react";
|
|
39048
39346
|
|
|
39049
39347
|
// src/search.ts
|
|
39050
39348
|
async function search(config2, input) {
|
|
@@ -39078,19 +39376,19 @@ function useSearch(config2, options = {}) {
|
|
|
39078
39376
|
initialQuery = "",
|
|
39079
39377
|
...searchOptions
|
|
39080
39378
|
} = options;
|
|
39081
|
-
const [query, setQueryState] =
|
|
39082
|
-
const [results, setResults] =
|
|
39083
|
-
const [total, setTotal] =
|
|
39084
|
-
const [loading, setLoading] =
|
|
39085
|
-
const [error, setError] =
|
|
39086
|
-
const [response, setResponse] =
|
|
39087
|
-
const debounceTimer =
|
|
39088
|
-
const abortController =
|
|
39089
|
-
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);
|
|
39090
39388
|
useEffect56(() => {
|
|
39091
39389
|
searchOptionsRef.current = searchOptions;
|
|
39092
39390
|
});
|
|
39093
|
-
const executeSearch =
|
|
39391
|
+
const executeSearch = useCallback47(
|
|
39094
39392
|
async (q2) => {
|
|
39095
39393
|
if (!q2 || q2.length < minLength) {
|
|
39096
39394
|
setResults([]);
|
|
@@ -39122,7 +39420,7 @@ function useSearch(config2, options = {}) {
|
|
|
39122
39420
|
},
|
|
39123
39421
|
[config2, minLength]
|
|
39124
39422
|
);
|
|
39125
|
-
const setQuery =
|
|
39423
|
+
const setQuery = useCallback47(
|
|
39126
39424
|
(q2) => {
|
|
39127
39425
|
setQueryState(q2);
|
|
39128
39426
|
if (debounceTimer.current) {
|
|
@@ -39142,7 +39440,7 @@ function useSearch(config2, options = {}) {
|
|
|
39142
39440
|
},
|
|
39143
39441
|
[executeSearch, debounceMs, minLength]
|
|
39144
39442
|
);
|
|
39145
|
-
const clear =
|
|
39443
|
+
const clear = useCallback47(() => {
|
|
39146
39444
|
if (debounceTimer.current) clearTimeout(debounceTimer.current);
|
|
39147
39445
|
abortController.current?.abort();
|
|
39148
39446
|
setQueryState("");
|
|
@@ -39152,10 +39450,10 @@ function useSearch(config2, options = {}) {
|
|
|
39152
39450
|
setLoading(false);
|
|
39153
39451
|
setError(null);
|
|
39154
39452
|
}, []);
|
|
39155
|
-
const refetch =
|
|
39453
|
+
const refetch = useCallback47(() => {
|
|
39156
39454
|
executeSearch(query);
|
|
39157
39455
|
}, [executeSearch, query]);
|
|
39158
|
-
const trackResultClick =
|
|
39456
|
+
const trackResultClick = useCallback47((_documentId, _resultRank) => {
|
|
39159
39457
|
}, []);
|
|
39160
39458
|
useEffect56(() => {
|
|
39161
39459
|
if (initialQuery && initialQuery.length >= minLength) {
|
|
@@ -39586,7 +39884,6 @@ export {
|
|
|
39586
39884
|
SpeedInsights,
|
|
39587
39885
|
StatsCard,
|
|
39588
39886
|
StatsGrid,
|
|
39589
|
-
StorageContext,
|
|
39590
39887
|
SubscriberPreferences,
|
|
39591
39888
|
SylphxError,
|
|
39592
39889
|
SylphxErrorBoundary,
|
|
@@ -39720,7 +40017,8 @@ export {
|
|
|
39720
40017
|
useFeatureFlagDefinitions,
|
|
39721
40018
|
useFeatureFlags,
|
|
39722
40019
|
useFeatureTracking,
|
|
39723
|
-
|
|
40020
|
+
useFile,
|
|
40021
|
+
useFileList,
|
|
39724
40022
|
useFlag,
|
|
39725
40023
|
useFlagEvaluation,
|
|
39726
40024
|
useFlagJSON,
|
|
@@ -39780,7 +40078,6 @@ export {
|
|
|
39780
40078
|
useSignUpForm,
|
|
39781
40079
|
useAnalyticsHook as useSmartAnalytics,
|
|
39782
40080
|
useStorage,
|
|
39783
|
-
useStorageContext,
|
|
39784
40081
|
useStreak,
|
|
39785
40082
|
useSubscriberForm,
|
|
39786
40083
|
useSylphx,
|
|
@@ -39788,7 +40085,6 @@ export {
|
|
|
39788
40085
|
useTasks,
|
|
39789
40086
|
useTasksContext,
|
|
39790
40087
|
useTimeTracking,
|
|
39791
|
-
useUpload,
|
|
39792
40088
|
useUser,
|
|
39793
40089
|
useUserContext,
|
|
39794
40090
|
useWebAnalytics,
|
|
@@ -39807,7 +40103,7 @@ export {
|
|
|
39807
40103
|
validateSecretKey,
|
|
39808
40104
|
validateWorkflow,
|
|
39809
40105
|
wait,
|
|
39810
|
-
withRetry,
|
|
40106
|
+
withRetry2 as withRetry,
|
|
39811
40107
|
withSessionReplay,
|
|
39812
40108
|
withTimeout
|
|
39813
40109
|
};
|