Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
•
20d8f83
1
Parent(s):
f9f5b89
upgrade dependencies
Browse files- README.md +14 -1
- package-lock.json +28 -16
- package.json +1 -1
- src/app/layout.tsx +3 -2
- src/app/main.tsx +2 -2
- src/lib/hooks/useDebounce.ts +15 -0
- src/lib/utils/debounceAsync.ts +66 -0
- src/lib/utils/debounceSync.ts +59 -0
README.md
CHANGED
@@ -25,5 +25,18 @@ During development we can use a path like this to quickly test:
|
|
25 |
```
|
26 |
"@aitube/timeline": "file:/Users/jbilcke/Projects/Typescript_Libraries/aitube-timeline",
|
27 |
```
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
|
|
25 |
```
|
26 |
"@aitube/timeline": "file:/Users/jbilcke/Projects/Typescript_Libraries/aitube-timeline",
|
27 |
```
|
28 |
+
|
29 |
+
Your local copy of the aitube-timelien will have to be built using:
|
30 |
+
|
31 |
+
```bash
|
32 |
+
bun run build:dev
|
33 |
+
```
|
34 |
+
|
35 |
+
to build with the jsxDEV enabled.
|
36 |
+
|
37 |
+
If you don't, you will see errors and warnings such as
|
38 |
+
|
39 |
+
```
|
40 |
+
app-index.js:33 Warning: Each child in a list should have a unique "key" prop.
|
41 |
+
```
|
42 |
|
package-lock.json
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
"version": "0.0.0",
|
10 |
"dependencies": {
|
11 |
"@aitube/clap": "0.0.23",
|
12 |
-
"@aitube/timeline": "0.0.
|
13 |
"@huggingface/hub": "^0.15.0",
|
14 |
"@radix-ui/react-accordion": "^1.1.2",
|
15 |
"@radix-ui/react-avatar": "^1.0.4",
|
@@ -84,9 +84,12 @@
|
|
84 |
}
|
85 |
},
|
86 |
"node_modules/@aitube/timeline": {
|
87 |
-
"version": "0.0.
|
88 |
-
"resolved": "https://registry.npmjs.org/@aitube/timeline/-/timeline-0.0.
|
89 |
-
"integrity": "sha512-
|
|
|
|
|
|
|
90 |
"peerDependencies": {
|
91 |
"@aitube/clap": "0.0.23",
|
92 |
"@radix-ui/react-slider": "^1.1.2",
|
@@ -2693,9 +2696,9 @@
|
|
2693 |
}
|
2694 |
},
|
2695 |
"node_modules/@react-three/fiber": {
|
2696 |
-
"version": "8.16.
|
2697 |
-
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.16.
|
2698 |
-
"integrity": "sha512-
|
2699 |
"dependencies": {
|
2700 |
"@babel/runtime": "^7.17.8",
|
2701 |
"@types/react-reconciler": "^0.26.7",
|
@@ -2859,9 +2862,9 @@
|
|
2859 |
"integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ=="
|
2860 |
},
|
2861 |
"node_modules/@types/three": {
|
2862 |
-
"version": "0.
|
2863 |
-
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.
|
2864 |
-
"integrity": "sha512-
|
2865 |
"peer": true,
|
2866 |
"dependencies": {
|
2867 |
"@tweenjs/tween.js": "~23.1.1",
|
@@ -4114,6 +4117,15 @@
|
|
4114 |
"url": "https://github.com/sponsors/ljharb"
|
4115 |
}
|
4116 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4117 |
"node_modules/debounce": {
|
4118 |
"version": "1.2.1",
|
4119 |
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
@@ -4260,9 +4272,9 @@
|
|
4260 |
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
4261 |
},
|
4262 |
"node_modules/electron-to-chromium": {
|
4263 |
-
"version": "1.4.
|
4264 |
-
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.
|
4265 |
-
"integrity": "sha512-
|
4266 |
},
|
4267 |
"node_modules/emoji-regex": {
|
4268 |
"version": "9.2.2",
|
@@ -7768,9 +7780,9 @@
|
|
7768 |
}
|
7769 |
},
|
7770 |
"node_modules/three-stdlib": {
|
7771 |
-
"version": "2.30.
|
7772 |
-
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.30.
|
7773 |
-
"integrity": "sha512-
|
7774 |
"dependencies": {
|
7775 |
"@types/draco3d": "^1.4.0",
|
7776 |
"@types/offscreencanvas": "^2019.6.4",
|
|
|
9 |
"version": "0.0.0",
|
10 |
"dependencies": {
|
11 |
"@aitube/clap": "0.0.23",
|
12 |
+
"@aitube/timeline": "0.0.4",
|
13 |
"@huggingface/hub": "^0.15.0",
|
14 |
"@radix-ui/react-accordion": "^1.1.2",
|
15 |
"@radix-ui/react-avatar": "^1.0.4",
|
|
|
84 |
}
|
85 |
},
|
86 |
"node_modules/@aitube/timeline": {
|
87 |
+
"version": "0.0.4",
|
88 |
+
"resolved": "https://registry.npmjs.org/@aitube/timeline/-/timeline-0.0.4.tgz",
|
89 |
+
"integrity": "sha512-vnwPyt3mFIbXdeK1OTeqXI4WkUkHwgGNI+beBXaLf/neHHVE0vcXx3gQyLaqYIb6oBkaZkFRUcyUNThjAxJWEw==",
|
90 |
+
"dependencies": {
|
91 |
+
"date-fns": "^3.6.0"
|
92 |
+
},
|
93 |
"peerDependencies": {
|
94 |
"@aitube/clap": "0.0.23",
|
95 |
"@radix-ui/react-slider": "^1.1.2",
|
|
|
2696 |
}
|
2697 |
},
|
2698 |
"node_modules/@react-three/fiber": {
|
2699 |
+
"version": "8.16.7",
|
2700 |
+
"resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.16.7.tgz",
|
2701 |
+
"integrity": "sha512-D9z/HmTupS/Z3YqBK+rxPgm3Ou7VvOB8J57+AW7JG2FmhCY4u65Gd6r8i8y61BR/paCk0DCPyyJ5w7FiUEHXgA==",
|
2702 |
"dependencies": {
|
2703 |
"@babel/runtime": "^7.17.8",
|
2704 |
"@types/react-reconciler": "^0.26.7",
|
|
|
2862 |
"integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ=="
|
2863 |
},
|
2864 |
"node_modules/@types/three": {
|
2865 |
+
"version": "0.165.0",
|
2866 |
+
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.165.0.tgz",
|
2867 |
+
"integrity": "sha512-AJK8JZAFNBF0kBXiAIl5pggYlzAGGA8geVYQXAcPCEDRbyA+oEjkpUBcJJrtNz6IiALwzGexFJGZG2yV3WsYBw==",
|
2868 |
"peer": true,
|
2869 |
"dependencies": {
|
2870 |
"@tweenjs/tween.js": "~23.1.1",
|
|
|
4117 |
"url": "https://github.com/sponsors/ljharb"
|
4118 |
}
|
4119 |
},
|
4120 |
+
"node_modules/date-fns": {
|
4121 |
+
"version": "3.6.0",
|
4122 |
+
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
|
4123 |
+
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
|
4124 |
+
"funding": {
|
4125 |
+
"type": "github",
|
4126 |
+
"url": "https://github.com/sponsors/kossnocorp"
|
4127 |
+
}
|
4128 |
+
},
|
4129 |
"node_modules/debounce": {
|
4130 |
"version": "1.2.1",
|
4131 |
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
|
|
|
4272 |
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
4273 |
},
|
4274 |
"node_modules/electron-to-chromium": {
|
4275 |
+
"version": "1.4.788",
|
4276 |
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.788.tgz",
|
4277 |
+
"integrity": "sha512-ubp5+Ev/VV8KuRoWnfP2QF2Bg+O2ZFdb49DiiNbz2VmgkIqrnyYaqIOqj8A6K/3p1xV0QcU5hBQ1+BmB6ot1OA=="
|
4278 |
},
|
4279 |
"node_modules/emoji-regex": {
|
4280 |
"version": "9.2.2",
|
|
|
7780 |
}
|
7781 |
},
|
7782 |
"node_modules/three-stdlib": {
|
7783 |
+
"version": "2.30.3",
|
7784 |
+
"resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.30.3.tgz",
|
7785 |
+
"integrity": "sha512-rYr8PqMljMza+Ct8kQk90Y7y+YcWoPu1thfYv5YGCp0hytNRbxSQWXY4GpdTGymCj3bDggEBpxso53C3pPwhIw==",
|
7786 |
"dependencies": {
|
7787 |
"@types/draco3d": "^1.4.0",
|
7788 |
"@types/offscreencanvas": "^2019.6.4",
|
package.json
CHANGED
@@ -11,7 +11,7 @@
|
|
11 |
},
|
12 |
"dependencies": {
|
13 |
"@aitube/clap": "0.0.23",
|
14 |
-
"@aitube/timeline": "0.0.
|
15 |
"@huggingface/hub": "^0.15.0",
|
16 |
"@radix-ui/react-accordion": "^1.1.2",
|
17 |
"@radix-ui/react-avatar": "^1.0.4",
|
|
|
11 |
},
|
12 |
"dependencies": {
|
13 |
"@aitube/clap": "0.0.23",
|
14 |
+
"@aitube/timeline": "0.0.4",
|
15 |
"@huggingface/hub": "^0.15.0",
|
16 |
"@radix-ui/react-accordion": "^1.1.2",
|
17 |
"@radix-ui/react-avatar": "^1.0.4",
|
src/app/layout.tsx
CHANGED
@@ -14,11 +14,12 @@ export default function RootLayout({
|
|
14 |
children: React.ReactNode
|
15 |
}) {
|
16 |
return (
|
17 |
-
<html lang="en">
|
18 |
<body className={cn(
|
19 |
`h-full w-full overflow-none dark`,
|
20 |
inter.className
|
21 |
-
)}
|
|
|
22 |
{children}
|
23 |
</body>
|
24 |
</html>
|
|
|
14 |
children: React.ReactNode
|
15 |
}) {
|
16 |
return (
|
17 |
+
<html lang="en" style={{ overscrollBehaviorX: "none"}}>
|
18 |
<body className={cn(
|
19 |
`h-full w-full overflow-none dark`,
|
20 |
inter.className
|
21 |
+
)}
|
22 |
+
style={{ overscrollBehaviorX: "none" }}>
|
23 |
{children}
|
24 |
</body>
|
25 |
</html>
|
src/app/main.tsx
CHANGED
@@ -46,13 +46,13 @@ export function Main() {
|
|
46 |
w-screen h-screen
|
47 |
overflow-hidden
|
48 |
items-center justify-center
|
49 |
-
bg-
|
50 |
`
|
51 |
)}
|
52 |
>
|
53 |
{clap
|
54 |
? <ClapTimeline
|
55 |
-
showFPS
|
56 |
className={cn(
|
57 |
|
58 |
)}
|
|
|
46 |
w-screen h-screen
|
47 |
overflow-hidden
|
48 |
items-center justify-center
|
49 |
+
bg-[rgb(58,54,50)]
|
50 |
`
|
51 |
)}
|
52 |
>
|
53 |
{clap
|
54 |
? <ClapTimeline
|
55 |
+
showFPS={false}
|
56 |
className={cn(
|
57 |
|
58 |
)}
|
src/lib/hooks/useDebounce.ts
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { useEffect, useState } from 'react'
|
2 |
+
|
3 |
+
export function useDebounce<T>(value: T, delay?: number): T {
|
4 |
+
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
5 |
+
|
6 |
+
useEffect(() => {
|
7 |
+
const timer = setTimeout(() => setDebouncedValue(value), delay || 500)
|
8 |
+
|
9 |
+
return () => {
|
10 |
+
clearTimeout(timer)
|
11 |
+
}
|
12 |
+
}, [value, delay])
|
13 |
+
|
14 |
+
return debouncedValue
|
15 |
+
}
|
src/lib/utils/debounceAsync.ts
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
|
3 |
+
Here's how you can use the `debounceAsync` function:
|
4 |
+
|
5 |
+
```typescript
|
6 |
+
async function fetchData(query: string): Promise<string> {
|
7 |
+
// Simulating an API call
|
8 |
+
return new Promise((resolve) => {
|
9 |
+
setTimeout(() => {
|
10 |
+
resolve(`Results for ${query}`);
|
11 |
+
}, 500);
|
12 |
+
});
|
13 |
+
}
|
14 |
+
|
15 |
+
const debouncedFetchData = debounceAsync(fetchData, 300);
|
16 |
+
|
17 |
+
(async () => {
|
18 |
+
try {
|
19 |
+
console.log(await debouncedFetchData("query 1")); // This will be ignored
|
20 |
+
console.log(await debouncedFetchData("query 2")); // This will be ignored
|
21 |
+
console.log(await debouncedFetchData("query 3")); // This will return "Results for query 3"
|
22 |
+
} catch (error) {
|
23 |
+
console.error(error);
|
24 |
+
}
|
25 |
+
})();
|
26 |
+
```
|
27 |
+
|
28 |
+
The `debounceAsync` function takes a Promise-based function `func` and a `wait` time as its arguments.
|
29 |
+
It returns a debounced version of the given function that, when called multiple times within the specified wait time, will only execute the last call.
|
30 |
+
*/
|
31 |
+
|
32 |
+
type DebouncedFunction<T extends any[], R> = ((...args: T) => R) & {
|
33 |
+
clear: () => void
|
34 |
+
}
|
35 |
+
|
36 |
+
export function debounceAsync<T extends any[], R>(
|
37 |
+
func: (...args: T) => Promise<R>,
|
38 |
+
wait: number
|
39 |
+
): DebouncedFunction<T, Promise<R | undefined>> {
|
40 |
+
let timeout: NodeJS.Timeout | undefined
|
41 |
+
|
42 |
+
const debounced = (...args: T) => {
|
43 |
+
return new Promise<R | undefined>((resolve, reject) => {
|
44 |
+
if (timeout) {
|
45 |
+
clearTimeout(timeout)
|
46 |
+
}
|
47 |
+
|
48 |
+
timeout = setTimeout(async () => {
|
49 |
+
try {
|
50 |
+
const result = await func(...args)
|
51 |
+
resolve(result)
|
52 |
+
} catch (error) {
|
53 |
+
reject(error)
|
54 |
+
}
|
55 |
+
}, wait)
|
56 |
+
})
|
57 |
+
}
|
58 |
+
|
59 |
+
debounced.clear = () => {
|
60 |
+
if (timeout) {
|
61 |
+
clearTimeout(timeout)
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
return debounced
|
66 |
+
}
|
src/lib/utils/debounceSync.ts
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
type DebouncedFunctionSync<T extends any[], R> = ((...args: T) => R) & {
|
2 |
+
clear: () => void
|
3 |
+
}
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Example usage:
|
7 |
+
* ```typescript
|
8 |
+
* function fetchDataSync(query: string): string {
|
9 |
+
* return `Results for ${query}`;
|
10 |
+
* }
|
11 |
+
*
|
12 |
+
* const debouncedFetchDataSync = debounceSync(fetchDataSync, 300);
|
13 |
+
*
|
14 |
+
* try {
|
15 |
+
* console.log(debouncedFetchDataSync("query 1")); // This will be ignored
|
16 |
+
* console.log(debouncedFetchDataSync("query 2")); // This will be ignored
|
17 |
+
* console.log(debouncedFetchDataSync("query 3")); // This will return "Results for query 3"
|
18 |
+
* } catch (error) {
|
19 |
+
* console.error(error);
|
20 |
+
* }
|
21 |
+
* ```
|
22 |
+
*
|
23 |
+
* Note that the synchronous version of the debounce function will return
|
24 |
+
* the result of the last function call or `undefined` if the function was
|
25 |
+
* not called within the specified wait time. You should also be aware that
|
26 |
+
* this synchronous version may cause blocking if the debounced function
|
27 |
+
* takes a long time to execute.
|
28 |
+
*
|
29 |
+
* @param func
|
30 |
+
* @param wait
|
31 |
+
* @returns
|
32 |
+
*/
|
33 |
+
export function debounceSync<T extends any[], R>(
|
34 |
+
func: (...args: T) => R,
|
35 |
+
wait: number
|
36 |
+
): DebouncedFunctionSync<T, R | undefined> {
|
37 |
+
let timeout: NodeJS.Timeout | undefined
|
38 |
+
|
39 |
+
const debounced = (...args: T): R | undefined => {
|
40 |
+
if (timeout) {
|
41 |
+
clearTimeout(timeout)
|
42 |
+
}
|
43 |
+
|
44 |
+
let result: R | undefined
|
45 |
+
timeout = setTimeout(() => {
|
46 |
+
result = func(...args)
|
47 |
+
}, wait)
|
48 |
+
|
49 |
+
return result
|
50 |
+
}
|
51 |
+
|
52 |
+
debounced.clear = () => {
|
53 |
+
if (timeout) {
|
54 |
+
clearTimeout(timeout)
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
return debounced
|
59 |
+
}
|