@windrun-huaiin/third-ui 14.0.2 → 14.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clerk/fingerprint/fingerprint-provider.js +150 -26
- package/dist/clerk/fingerprint/fingerprint-provider.mjs +151 -27
- package/dist/clerk/fingerprint/types.d.ts +1 -0
- package/dist/clerk/fingerprint/use-fingerprint.js +20 -1
- package/dist/clerk/fingerprint/use-fingerprint.mjs +21 -2
- package/dist/fuma/mdx/gradient-button.d.ts +2 -1
- package/dist/fuma/mdx/gradient-button.js +2 -2
- package/dist/fuma/mdx/gradient-button.mjs +2 -2
- package/package.json +1 -1
- package/src/clerk/fingerprint/fingerprint-provider.tsx +349 -87
- package/src/clerk/fingerprint/types.ts +2 -1
- package/src/clerk/fingerprint/use-fingerprint.ts +23 -2
- package/src/fuma/mdx/gradient-button.tsx +3 -1
|
@@ -21,6 +21,7 @@ function useFingerprint(config) {
|
|
|
21
21
|
isLoading: false,
|
|
22
22
|
isInitialized: false,
|
|
23
23
|
error: 'Server-side rendering is not supported',
|
|
24
|
+
clearError: () => { },
|
|
24
25
|
initializeAnonymousUser: () => tslib_es6.__awaiter(this, void 0, void 0, function* () { }),
|
|
25
26
|
refreshUserData: () => tslib_es6.__awaiter(this, void 0, void 0, function* () { }),
|
|
26
27
|
};
|
|
@@ -32,6 +33,11 @@ function useFingerprint(config) {
|
|
|
32
33
|
const [isLoading, setIsLoading] = React.useState(true);
|
|
33
34
|
const [isInitialized, setIsInitialized] = React.useState(false);
|
|
34
35
|
const [error, setError] = React.useState(null);
|
|
36
|
+
const isInitializingAnonymousUserRef = React.useRef(false);
|
|
37
|
+
const requestedAnonymousFingerprintRef = React.useRef(null);
|
|
38
|
+
const clearError = React.useCallback(() => {
|
|
39
|
+
setError(null);
|
|
40
|
+
}, []);
|
|
35
41
|
/**
|
|
36
42
|
* 第一阶段:初始化fingerprint ID
|
|
37
43
|
*/
|
|
@@ -60,7 +66,17 @@ function useFingerprint(config) {
|
|
|
60
66
|
setError('Cannot initialize user: Missing fingerprint ID');
|
|
61
67
|
return;
|
|
62
68
|
}
|
|
69
|
+
if (isInitializingAnonymousUserRef.current) {
|
|
70
|
+
console.log('Skipping anonymous user initialization because a request is already in flight:', fingerprintId);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (requestedAnonymousFingerprintRef.current === fingerprintId && isInitialized) {
|
|
74
|
+
console.log('Skipping anonymous user initialization because fingerprint is already initialized:', fingerprintId);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
63
77
|
try {
|
|
78
|
+
isInitializingAnonymousUserRef.current = true;
|
|
79
|
+
requestedAnonymousFingerprintRef.current = fingerprintId;
|
|
64
80
|
setIsLoading(true);
|
|
65
81
|
setError(null);
|
|
66
82
|
console.log('Initializing anonymous user with fingerprintId:', fingerprintId);
|
|
@@ -92,13 +108,15 @@ function useFingerprint(config) {
|
|
|
92
108
|
}
|
|
93
109
|
}
|
|
94
110
|
catch (err) {
|
|
111
|
+
requestedAnonymousFingerprintRef.current = null;
|
|
95
112
|
console.error('Failed to initialize anonymous user:', err);
|
|
96
113
|
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
97
114
|
}
|
|
98
115
|
finally {
|
|
116
|
+
isInitializingAnonymousUserRef.current = false;
|
|
99
117
|
setIsLoading(false);
|
|
100
118
|
}
|
|
101
|
-
}), [fingerprintId, config.apiEndpoint]);
|
|
119
|
+
}), [fingerprintId, config.apiEndpoint, isInitialized]);
|
|
102
120
|
/**
|
|
103
121
|
* 刷新用户数据 - 使用POST请求(后端支持upsert逻辑)
|
|
104
122
|
*/
|
|
@@ -157,6 +175,7 @@ function useFingerprint(config) {
|
|
|
157
175
|
isLoading,
|
|
158
176
|
isInitialized,
|
|
159
177
|
error,
|
|
178
|
+
clearError,
|
|
160
179
|
initializeAnonymousUser,
|
|
161
180
|
refreshUserData,
|
|
162
181
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.mjs';
|
|
3
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
3
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
4
4
|
import { getOrCreateFirstTouchData, getOrGenerateFingerprintId, createFingerprintHeaders } from './fingerprint-client.mjs';
|
|
5
5
|
import { FINGERPRINT_SOURCE_REFER } from './fingerprint-shared.mjs';
|
|
6
6
|
|
|
@@ -19,6 +19,7 @@ function useFingerprint(config) {
|
|
|
19
19
|
isLoading: false,
|
|
20
20
|
isInitialized: false,
|
|
21
21
|
error: 'Server-side rendering is not supported',
|
|
22
|
+
clearError: () => { },
|
|
22
23
|
initializeAnonymousUser: () => __awaiter(this, void 0, void 0, function* () { }),
|
|
23
24
|
refreshUserData: () => __awaiter(this, void 0, void 0, function* () { }),
|
|
24
25
|
};
|
|
@@ -30,6 +31,11 @@ function useFingerprint(config) {
|
|
|
30
31
|
const [isLoading, setIsLoading] = useState(true);
|
|
31
32
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
32
33
|
const [error, setError] = useState(null);
|
|
34
|
+
const isInitializingAnonymousUserRef = useRef(false);
|
|
35
|
+
const requestedAnonymousFingerprintRef = useRef(null);
|
|
36
|
+
const clearError = useCallback(() => {
|
|
37
|
+
setError(null);
|
|
38
|
+
}, []);
|
|
33
39
|
/**
|
|
34
40
|
* 第一阶段:初始化fingerprint ID
|
|
35
41
|
*/
|
|
@@ -58,7 +64,17 @@ function useFingerprint(config) {
|
|
|
58
64
|
setError('Cannot initialize user: Missing fingerprint ID');
|
|
59
65
|
return;
|
|
60
66
|
}
|
|
67
|
+
if (isInitializingAnonymousUserRef.current) {
|
|
68
|
+
console.log('Skipping anonymous user initialization because a request is already in flight:', fingerprintId);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (requestedAnonymousFingerprintRef.current === fingerprintId && isInitialized) {
|
|
72
|
+
console.log('Skipping anonymous user initialization because fingerprint is already initialized:', fingerprintId);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
61
75
|
try {
|
|
76
|
+
isInitializingAnonymousUserRef.current = true;
|
|
77
|
+
requestedAnonymousFingerprintRef.current = fingerprintId;
|
|
62
78
|
setIsLoading(true);
|
|
63
79
|
setError(null);
|
|
64
80
|
console.log('Initializing anonymous user with fingerprintId:', fingerprintId);
|
|
@@ -90,13 +106,15 @@ function useFingerprint(config) {
|
|
|
90
106
|
}
|
|
91
107
|
}
|
|
92
108
|
catch (err) {
|
|
109
|
+
requestedAnonymousFingerprintRef.current = null;
|
|
93
110
|
console.error('Failed to initialize anonymous user:', err);
|
|
94
111
|
setError(err instanceof Error ? err.message : 'Unknown error');
|
|
95
112
|
}
|
|
96
113
|
finally {
|
|
114
|
+
isInitializingAnonymousUserRef.current = false;
|
|
97
115
|
setIsLoading(false);
|
|
98
116
|
}
|
|
99
|
-
}), [fingerprintId, config.apiEndpoint]);
|
|
117
|
+
}), [fingerprintId, config.apiEndpoint, isInitialized]);
|
|
100
118
|
/**
|
|
101
119
|
* 刷新用户数据 - 使用POST请求(后端支持upsert逻辑)
|
|
102
120
|
*/
|
|
@@ -155,6 +173,7 @@ function useFingerprint(config) {
|
|
|
155
173
|
isLoading,
|
|
156
174
|
isInitialized,
|
|
157
175
|
error,
|
|
176
|
+
clearError,
|
|
158
177
|
initializeAnonymousUser,
|
|
159
178
|
refreshUserData,
|
|
160
179
|
};
|
|
@@ -8,8 +8,9 @@ export interface GradientButtonProps {
|
|
|
8
8
|
iconClassName?: string;
|
|
9
9
|
href?: string;
|
|
10
10
|
openInNewTab?: boolean;
|
|
11
|
+
preserveReferrer?: boolean;
|
|
11
12
|
onClick?: () => void | Promise<void>;
|
|
12
13
|
loadingText?: React.ReactNode;
|
|
13
14
|
preventDoubleClick?: boolean;
|
|
14
15
|
}
|
|
15
|
-
export declare function GradientButton({ title, icon, align, disabled, className, href, openInNewTab, onClick, loadingText, preventDoubleClick, iconClassName, }: GradientButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function GradientButton({ title, icon, align, disabled, className, href, openInNewTab, preserveReferrer, onClick, loadingText, preventDoubleClick, iconClassName, }: GradientButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,7 +9,7 @@ var lib = require('@windrun-huaiin/base-ui/lib');
|
|
|
9
9
|
var Link = require('next/link');
|
|
10
10
|
var React = require('react');
|
|
11
11
|
|
|
12
|
-
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, onClick, loadingText, preventDoubleClick = true, iconClassName, }) {
|
|
12
|
+
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, preserveReferrer = false, onClick, loadingText, preventDoubleClick = true, iconClassName, }) {
|
|
13
13
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
14
14
|
const actualLoadingText = loadingText || (title === null || title === void 0 ? void 0 : title.toString().trim()) || 'Loading...';
|
|
15
15
|
const defaultIconClass = "h-4 w-4";
|
|
@@ -84,7 +84,7 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
|
|
|
84
84
|
// for click
|
|
85
85
|
jsxRuntime.jsx("button", { type: "button", className: buttonClassName, onClick: handleClick, disabled: isDisabled, children: buttonContent })) : (
|
|
86
86
|
// for Link
|
|
87
|
-
jsxRuntime.jsx(Link, Object.assign({ href: href || "#", className: utils.cn(buttonClassName, "no-underline hover:no-underline") }, (openInNewTab ? { target: "_blank", rel:
|
|
87
|
+
jsxRuntime.jsx(Link, Object.assign({ href: href || "#", className: utils.cn(buttonClassName, "no-underline hover:no-underline") }, (openInNewTab ? { target: "_blank", rel: preserveReferrer ? 'noopener' : 'noopener noreferrer' } : {}), { onClick: isDisabled ? (e) => e.preventDefault() : undefined, "aria-disabled": isDisabled, children: buttonContent }))) }));
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
exports.GradientButton = GradientButton;
|
|
@@ -7,7 +7,7 @@ import { themeButtonGradientClass, themeButtonGradientHoverClass } from '@windru
|
|
|
7
7
|
import Link from 'next/link';
|
|
8
8
|
import React, { useState } from 'react';
|
|
9
9
|
|
|
10
|
-
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, onClick, loadingText, preventDoubleClick = true, iconClassName, }) {
|
|
10
|
+
function GradientButton({ title, icon, align = 'left', disabled = false, className = "", href, openInNewTab = true, preserveReferrer = false, onClick, loadingText, preventDoubleClick = true, iconClassName, }) {
|
|
11
11
|
const [isLoading, setIsLoading] = useState(false);
|
|
12
12
|
const actualLoadingText = loadingText || (title === null || title === void 0 ? void 0 : title.toString().trim()) || 'Loading...';
|
|
13
13
|
const defaultIconClass = "h-4 w-4";
|
|
@@ -82,7 +82,7 @@ function GradientButton({ title, icon, align = 'left', disabled = false, classNa
|
|
|
82
82
|
// for click
|
|
83
83
|
jsx("button", { type: "button", className: buttonClassName, onClick: handleClick, disabled: isDisabled, children: buttonContent })) : (
|
|
84
84
|
// for Link
|
|
85
|
-
jsx(Link, Object.assign({ href: href || "#", className: cn(buttonClassName, "no-underline hover:no-underline") }, (openInNewTab ? { target: "_blank", rel:
|
|
85
|
+
jsx(Link, Object.assign({ href: href || "#", className: cn(buttonClassName, "no-underline hover:no-underline") }, (openInNewTab ? { target: "_blank", rel: preserveReferrer ? 'noopener' : 'noopener noreferrer' } : {}), { onClick: isDisabled ? (e) => e.preventDefault() : undefined, "aria-disabled": isDisabled, children: buttonContent }))) }));
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
export { GradientButton };
|