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