sse-hooks 1.3.0 → 2.0.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/cli.mjs +373 -0
- package/package.json +17 -34
- package/README.md +0 -171
- package/dist/index.cjs +0 -3108
- package/dist/index.d.cts +0 -2429
- package/dist/index.d.mts +0 -2429
- package/dist/index.d.ts +0 -2429
- package/dist/index.mjs +0 -3009
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
|
|
6
|
+
// src/cli/commands/add.ts
|
|
7
|
+
import inquirer from "inquirer";
|
|
8
|
+
|
|
9
|
+
// src/cli/utils/config.ts
|
|
10
|
+
import fs from "fs-extra";
|
|
11
|
+
import path from "path";
|
|
12
|
+
|
|
13
|
+
// src/cli/utils/logger.ts
|
|
14
|
+
import chalk from "chalk";
|
|
15
|
+
var error = (message) => {
|
|
16
|
+
console.error(chalk.red(`\u274C ${message}`));
|
|
17
|
+
};
|
|
18
|
+
var success = (message) => {
|
|
19
|
+
console.log(chalk.green(`\u2705 ${message}`));
|
|
20
|
+
};
|
|
21
|
+
var info = (message) => {
|
|
22
|
+
console.log(chalk.blue(`\u2139 ${message}`));
|
|
23
|
+
};
|
|
24
|
+
var warn = (message) => {
|
|
25
|
+
console.warn(chalk.yellow(`\u26A0 ${message}`));
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// src/cli/utils/constants.ts
|
|
29
|
+
var ORIGIN = "https://sse-hooks.vercel.app";
|
|
30
|
+
var REGISTRY_CONFIG = {
|
|
31
|
+
ORIGIN,
|
|
32
|
+
BASE_URL: `${ORIGIN}/api/registry/hook`,
|
|
33
|
+
MANIFEST_ENDPOINT: "manifest.json",
|
|
34
|
+
HOOK_ENDPOINT: (name) => `${name}/meta.json`,
|
|
35
|
+
ERRORS: {
|
|
36
|
+
FETCH_FAILED: "Failed to fetch from registry",
|
|
37
|
+
MANIFEST_NOT_FOUND: "Registry manifest not found",
|
|
38
|
+
HOOK_NOT_FOUND: "Hook not found in registry"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
var DEFAULT_CONFIG_VALUES = {
|
|
42
|
+
HOOKS_DIR: "src/hooks",
|
|
43
|
+
REPO_URL: REGISTRY_CONFIG.BASE_URL
|
|
44
|
+
};
|
|
45
|
+
var CLI = {
|
|
46
|
+
COMMAND_NAME: "sse-tools",
|
|
47
|
+
CONFIG_FILE: "sse.config.json",
|
|
48
|
+
COMMANDS: {
|
|
49
|
+
INIT: "init",
|
|
50
|
+
ADD: "add",
|
|
51
|
+
LIST: "list"
|
|
52
|
+
},
|
|
53
|
+
PROMPTS: {
|
|
54
|
+
HOOKS_DIR: "Where should hooks be stored?",
|
|
55
|
+
DEFAULT_LANG: "Default hook language?",
|
|
56
|
+
REPO_URL: "Registry API URL?"
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/cli/utils/config.ts
|
|
61
|
+
async function getConfig() {
|
|
62
|
+
try {
|
|
63
|
+
const configPath = path.resolve(CLI.CONFIG_FILE);
|
|
64
|
+
if (!await fs.pathExists(configPath)) {
|
|
65
|
+
warn(
|
|
66
|
+
`Configuration not found. Run "${CLI.COMMAND_NAME} ${CLI.COMMANDS.INIT}" first.`
|
|
67
|
+
);
|
|
68
|
+
throw new Error("Configuration missing");
|
|
69
|
+
}
|
|
70
|
+
return await fs.readJson(configPath);
|
|
71
|
+
} catch (err) {
|
|
72
|
+
error("Failed to read configuration");
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async function saveConfig(config) {
|
|
77
|
+
try {
|
|
78
|
+
await fs.writeJson(CLI.CONFIG_FILE, config, { spaces: 2 });
|
|
79
|
+
} catch (err) {
|
|
80
|
+
error("Failed to save configuration");
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/cli/utils/registry.ts
|
|
86
|
+
import axios from "axios";
|
|
87
|
+
import fs2 from "fs-extra";
|
|
88
|
+
import path2 from "path";
|
|
89
|
+
async function fetchHookList(registryUrl) {
|
|
90
|
+
try {
|
|
91
|
+
const baseUrl = registryUrl.replace(/\/$/, "");
|
|
92
|
+
const manifestUrl = `${baseUrl}/${REGISTRY_CONFIG.MANIFEST_ENDPOINT}`;
|
|
93
|
+
info(`Fetching hook list...`);
|
|
94
|
+
const response = await axios.get(manifestUrl);
|
|
95
|
+
if (response.data?.hooks && Array.isArray(response.data.hooks)) {
|
|
96
|
+
return response.data.hooks;
|
|
97
|
+
}
|
|
98
|
+
throw new Error(REGISTRY_CONFIG.ERRORS.MANIFEST_NOT_FOUND);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
101
|
+
error("Failed to fetch hook list: " + message);
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function downloadHook(registryUrl, hookNameOrUrl, language, filePath, metaOnly = false) {
|
|
106
|
+
try {
|
|
107
|
+
let hookUrl;
|
|
108
|
+
if (hookNameOrUrl.startsWith("http://") || hookNameOrUrl.startsWith("https://")) {
|
|
109
|
+
hookUrl = hookNameOrUrl;
|
|
110
|
+
} else {
|
|
111
|
+
const baseUrl = registryUrl.replace(/\/$/, "");
|
|
112
|
+
hookUrl = `${baseUrl}/${REGISTRY_CONFIG.HOOK_ENDPOINT(hookNameOrUrl)}`;
|
|
113
|
+
}
|
|
114
|
+
const response = await axios.get(hookUrl);
|
|
115
|
+
const metaData = response.data;
|
|
116
|
+
if (metaOnly) {
|
|
117
|
+
return metaData;
|
|
118
|
+
}
|
|
119
|
+
const code = language === "js" ? metaData.file.js : metaData.file.content;
|
|
120
|
+
if (!code) {
|
|
121
|
+
throw new Error(`Code for ${language.toUpperCase()} not found.`);
|
|
122
|
+
}
|
|
123
|
+
if (filePath) {
|
|
124
|
+
await fs2.ensureDir(path2.dirname(filePath));
|
|
125
|
+
await fs2.writeFile(filePath, code);
|
|
126
|
+
}
|
|
127
|
+
return metaData;
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (axios.isAxiosError(err) && err.response?.status === 404) {
|
|
130
|
+
error(`Hook "${hookNameOrUrl}" not found in registry.`);
|
|
131
|
+
throw new Error(REGISTRY_CONFIG.ERRORS.HOOK_NOT_FOUND);
|
|
132
|
+
}
|
|
133
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
134
|
+
error(`Failed to process hook: ${hookNameOrUrl} - ${message}`);
|
|
135
|
+
throw err;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/cli/commands/add.ts
|
|
140
|
+
import path4 from "path";
|
|
141
|
+
import fs4 from "fs-extra";
|
|
142
|
+
import chalk3 from "chalk";
|
|
143
|
+
import ora2 from "ora";
|
|
144
|
+
|
|
145
|
+
// src/cli/utils/npm.ts
|
|
146
|
+
import path3 from "path";
|
|
147
|
+
import fs3 from "fs/promises";
|
|
148
|
+
import { execSync } from "child_process";
|
|
149
|
+
import { error as error2 } from "console";
|
|
150
|
+
import chalk2 from "chalk";
|
|
151
|
+
import ora from "ora";
|
|
152
|
+
async function installNpmDependencies(dependencies = []) {
|
|
153
|
+
if (!dependencies.length) return;
|
|
154
|
+
const pkgPath = path3.join(process.cwd(), "package.json");
|
|
155
|
+
let pkg2;
|
|
156
|
+
try {
|
|
157
|
+
pkg2 = JSON.parse(await fs3.readFile(pkgPath, "utf-8"));
|
|
158
|
+
} catch {
|
|
159
|
+
error2("package.json not found. Skipping dependency installation.");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
163
|
+
const missingDeps = dependencies.filter((dep) => !allDeps[dep]);
|
|
164
|
+
if (missingDeps.length > 0) {
|
|
165
|
+
const spinner = ora(
|
|
166
|
+
`Installing dependencies: ${chalk2.cyan(missingDeps.join(", "))}...`
|
|
167
|
+
).start();
|
|
168
|
+
try {
|
|
169
|
+
const agent = process.env.npm_config_user_agent || "";
|
|
170
|
+
const command = agent.includes("pnpm") ? "pnpm add" : agent.includes("yarn") ? "yarn add" : "npm install";
|
|
171
|
+
execSync(`${command} ${missingDeps.join(" ")}`, { stdio: "ignore" });
|
|
172
|
+
spinner.succeed(chalk2.green("Dependencies installed successfully."));
|
|
173
|
+
} catch (err) {
|
|
174
|
+
spinner.fail(chalk2.red("Failed to install dependencies."));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/cli/commands/add.ts
|
|
180
|
+
async function addCommand(hookNames = [], options = {}) {
|
|
181
|
+
try {
|
|
182
|
+
const config = await getConfig();
|
|
183
|
+
const installDir = config.hooks.hooksDir;
|
|
184
|
+
const language = options?.language || config?.hooks.defaultLanguage;
|
|
185
|
+
let initialQueue = [...hookNames];
|
|
186
|
+
if (initialQueue.length === 0) {
|
|
187
|
+
const availableHooks = await fetchHookList(config.hooks.registryUrl);
|
|
188
|
+
const { selectedHooks } = await inquirer.prompt([
|
|
189
|
+
{
|
|
190
|
+
type: "checkbox",
|
|
191
|
+
name: "selectedHooks",
|
|
192
|
+
message: "Select hooks to install:",
|
|
193
|
+
pageSize: 10,
|
|
194
|
+
choices: availableHooks.map((hook) => ({
|
|
195
|
+
name: `${hook.name} - ${hook.description}`,
|
|
196
|
+
value: hook.name
|
|
197
|
+
})),
|
|
198
|
+
validate: (input) => input.length > 0 || "You must choose at least one hook"
|
|
199
|
+
}
|
|
200
|
+
]);
|
|
201
|
+
initialQueue = selectedHooks;
|
|
202
|
+
}
|
|
203
|
+
const hooksToInstall = /* @__PURE__ */ new Set();
|
|
204
|
+
const dependenciesToInstall = /* @__PURE__ */ new Set();
|
|
205
|
+
const payloadMap = /* @__PURE__ */ new Map();
|
|
206
|
+
const resolveSpinner = ora2("Resolving hooks...").start();
|
|
207
|
+
try {
|
|
208
|
+
const queue = [...initialQueue];
|
|
209
|
+
while (queue.length > 0) {
|
|
210
|
+
const currentInput = queue.shift();
|
|
211
|
+
if (!currentInput.startsWith("http") && hooksToInstall.has(currentInput)) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const meta = await downloadHook(
|
|
215
|
+
config.hooks.registryUrl,
|
|
216
|
+
currentInput,
|
|
217
|
+
language,
|
|
218
|
+
"",
|
|
219
|
+
true
|
|
220
|
+
);
|
|
221
|
+
const realName = meta.name;
|
|
222
|
+
if (hooksToInstall.has(realName)) continue;
|
|
223
|
+
hooksToInstall.add(realName);
|
|
224
|
+
payloadMap.set(realName, meta);
|
|
225
|
+
if (meta.registryDependencies) {
|
|
226
|
+
queue.push(...meta.registryDependencies);
|
|
227
|
+
}
|
|
228
|
+
if (meta.dependencies) {
|
|
229
|
+
meta.dependencies.forEach((dep) => dependenciesToInstall.add(dep));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
resolveSpinner.stop();
|
|
233
|
+
} catch (err) {
|
|
234
|
+
resolveSpinner.fail("Failed to resolve hooks.");
|
|
235
|
+
error(err instanceof Error ? err.message : "Unknown error");
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const sortedHooks = Array.from(hooksToInstall).sort();
|
|
239
|
+
const sortedDeps = Array.from(dependenciesToInstall).sort();
|
|
240
|
+
if (sortedHooks.length) {
|
|
241
|
+
console.log(chalk3.bold.cyan(`
|
|
242
|
+
Hooks:`));
|
|
243
|
+
sortedHooks.forEach((h) => console.log(`- ${h}`));
|
|
244
|
+
}
|
|
245
|
+
if (sortedDeps.length) {
|
|
246
|
+
console.log(chalk3.bold.cyan(`
|
|
247
|
+
Dependencies:`));
|
|
248
|
+
sortedDeps.forEach((d) => console.log(`- ${d}`));
|
|
249
|
+
}
|
|
250
|
+
console.log("");
|
|
251
|
+
const { proceed } = await inquirer.prompt([
|
|
252
|
+
{
|
|
253
|
+
type: "confirm",
|
|
254
|
+
name: "proceed",
|
|
255
|
+
message: "Ready to install. Proceed?",
|
|
256
|
+
default: true
|
|
257
|
+
}
|
|
258
|
+
]);
|
|
259
|
+
if (!proceed) {
|
|
260
|
+
info("Operation cancelled.");
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
if (sortedDeps.length) {
|
|
264
|
+
await installNpmDependencies(sortedDeps);
|
|
265
|
+
}
|
|
266
|
+
const writeSpinner = ora2("Writing components...").start();
|
|
267
|
+
for (const name of sortedHooks) {
|
|
268
|
+
const meta = payloadMap.get(name);
|
|
269
|
+
const code = language === "js" ? meta.file.js : meta.file.content;
|
|
270
|
+
const fileName = `${meta.name}.${language}`;
|
|
271
|
+
const filePath = path4.join(installDir, fileName);
|
|
272
|
+
try {
|
|
273
|
+
await fs4.access(filePath);
|
|
274
|
+
} catch {
|
|
275
|
+
}
|
|
276
|
+
await fs4.ensureDir(path4.dirname(filePath));
|
|
277
|
+
await fs4.writeFile(filePath, code);
|
|
278
|
+
}
|
|
279
|
+
writeSpinner.succeed(chalk3.green("Done."));
|
|
280
|
+
if (hooksToInstall.size > 0) {
|
|
281
|
+
success(
|
|
282
|
+
`Installed ${hooksToInstall.size} component(s) to ${chalk3.cyan(
|
|
283
|
+
installDir
|
|
284
|
+
)}`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
} catch (err) {
|
|
288
|
+
if (err.message === "Configuration missing") {
|
|
289
|
+
error('No configuration found. Please run "sse-tool init" first.');
|
|
290
|
+
} else {
|
|
291
|
+
error(err instanceof Error ? err.message : "An unknown error occurred");
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/cli/commands/list.ts
|
|
297
|
+
import Table from "cli-table3";
|
|
298
|
+
async function listCommand() {
|
|
299
|
+
try {
|
|
300
|
+
const config = await getConfig();
|
|
301
|
+
const hooks = await fetchHookList(config.hooks.registryUrl);
|
|
302
|
+
const table = new Table({
|
|
303
|
+
head: ["Hook Name", "Description"],
|
|
304
|
+
colWidths: [25, 60]
|
|
305
|
+
});
|
|
306
|
+
hooks.forEach((hook) => {
|
|
307
|
+
table.push([hook.name, hook.description || "-"]);
|
|
308
|
+
});
|
|
309
|
+
console.log(table.toString());
|
|
310
|
+
info(`Total hooks: ${hooks.length}`);
|
|
311
|
+
} catch (err) {
|
|
312
|
+
error(
|
|
313
|
+
"Failed to list hooks: " + (err instanceof Error ? err.message : "Unknown error")
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/cli/commands/init.ts
|
|
319
|
+
import inquirer2 from "inquirer";
|
|
320
|
+
import fs5 from "fs-extra";
|
|
321
|
+
import path5 from "path";
|
|
322
|
+
async function initCommand() {
|
|
323
|
+
let isTypeScriptProject = false;
|
|
324
|
+
try {
|
|
325
|
+
const pkgPath = path5.resolve("package.json");
|
|
326
|
+
if (await fs5.pathExists(pkgPath)) {
|
|
327
|
+
const pkg2 = await fs5.readJson(pkgPath);
|
|
328
|
+
const allDeps = { ...pkg2.dependencies, ...pkg2.devDependencies };
|
|
329
|
+
if (allDeps.typescript) {
|
|
330
|
+
isTypeScriptProject = true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
} catch (err) {
|
|
334
|
+
}
|
|
335
|
+
const answers = await inquirer2.prompt([
|
|
336
|
+
{
|
|
337
|
+
type: "input",
|
|
338
|
+
name: "hooksDir",
|
|
339
|
+
message: CLI.PROMPTS.HOOKS_DIR,
|
|
340
|
+
default: DEFAULT_CONFIG_VALUES.HOOKS_DIR
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
type: "list",
|
|
344
|
+
name: "defaultLanguage",
|
|
345
|
+
message: CLI.PROMPTS.DEFAULT_LANG,
|
|
346
|
+
choices: ["ts", "js"],
|
|
347
|
+
default: isTypeScriptProject ? "ts" : "js"
|
|
348
|
+
}
|
|
349
|
+
]);
|
|
350
|
+
await saveConfig({
|
|
351
|
+
hooks: {
|
|
352
|
+
hooksDir: answers.hooksDir,
|
|
353
|
+
defaultLanguage: answers.defaultLanguage,
|
|
354
|
+
registryUrl: DEFAULT_CONFIG_VALUES.REPO_URL
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
success("Configuration saved!");
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// src/cli.ts
|
|
361
|
+
import { readFileSync } from "fs";
|
|
362
|
+
var program = new Command();
|
|
363
|
+
var pkg = JSON.parse(
|
|
364
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf-8")
|
|
365
|
+
);
|
|
366
|
+
program.name(pkg?.name || "sse-tool").description("CLI for managing custom React hooks").version(`${pkg?.version}`, "-v, --version", "Output the current version");
|
|
367
|
+
program.command("init").description("Initialize hooks configuration").action(initCommand);
|
|
368
|
+
program.command("add [hooks...]").description("Add one or more custom hooks").option("-l, --language <language>", "Specify hook language (js|ts)").option("-d, --dir <directory>", "Specify installation directory").action((hooks, options) => {
|
|
369
|
+
const hookNames = Array.isArray(hooks) ? hooks : hooks ? [hooks] : [];
|
|
370
|
+
addCommand(hookNames, options);
|
|
371
|
+
});
|
|
372
|
+
program.command("list").description("List available hooks").action(listCommand);
|
|
373
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,46 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sse-hooks",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Tools for SSE Hooks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SSE World",
|
|
7
|
-
"
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsup"
|
|
9
|
+
},
|
|
8
10
|
"files": [
|
|
9
|
-
"dist"
|
|
11
|
+
"dist/**/*"
|
|
10
12
|
],
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
"exports": {
|
|
14
|
-
"./package.json": "./package.json",
|
|
15
|
-
".": {
|
|
16
|
-
"import": {
|
|
17
|
-
"types": "./dist/index.d.mts",
|
|
18
|
-
"default": "./dist/index.mjs"
|
|
19
|
-
},
|
|
20
|
-
"require": {
|
|
21
|
-
"types": "./dist/index.d.cts",
|
|
22
|
-
"default": "./dist/index.cjs"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"scripts": {
|
|
27
|
-
"build": "unbuild",
|
|
28
|
-
"build:index": "node ./scripts/generate-index.js",
|
|
29
|
-
"meta:gen": "node scripts/generate-meta.js --create",
|
|
30
|
-
"meta:rm": "node scripts/generate-meta.js --rm"
|
|
13
|
+
"bin": {
|
|
14
|
+
"sse-hooks": "dist/cli.mjs"
|
|
31
15
|
},
|
|
32
16
|
"devDependencies": {
|
|
33
|
-
"@types/
|
|
34
|
-
"
|
|
35
|
-
"@types/react": "^19.2.2",
|
|
36
|
-
"@types/react-dom": "^19.2.2",
|
|
37
|
-
"prettier": "^3.8.1",
|
|
38
|
-
"typescript": "^5.9.2"
|
|
17
|
+
"@types/fs-extra": "^11.0.4",
|
|
18
|
+
"tsup": "^8.5.1"
|
|
39
19
|
},
|
|
40
20
|
"dependencies": {
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
21
|
+
"axios": "^1.13.4",
|
|
22
|
+
"chalk": "^4.1.2",
|
|
23
|
+
"cli-table3": "^0.6.5",
|
|
24
|
+
"commander": "^14.0.3",
|
|
25
|
+
"fs-extra": "^11.3.3",
|
|
26
|
+
"inquirer": "^13.2.2",
|
|
27
|
+
"ora": "^9.1.0"
|
|
45
28
|
}
|
|
46
29
|
}
|
package/README.md
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
### 📡 Sensors
|
|
4
|
-
- [`useAudioRecorder`](https://sse-hooks.vercel.app/docs/hooks/use-audio-recorder) — A comprehensive hook for audio recording with real-time analysis using getUserMedia, MediaRecorder, and Web Audio APIs.
|
|
5
|
-
- [`useHover`](https://sse-hooks.vercel.app/docs/hooks/use-hover) — Custom hook that tracks whether a DOM element is being hovered over.
|
|
6
|
-
- [`useMediaQuery`](https://sse-hooks.vercel.app/docs/hooks/use-media-query) — Custom hook that tracks the state of a media query using the [`Match Media API`](https://developer.
|
|
7
|
-
- [`useMediaSession`](https://sse-hooks.vercel.app/docs/hooks/use-media-session) — Custom hook that interacts with the [Media Session API](https://developer.
|
|
8
|
-
- [`useResizeObserver`](https://sse-hooks.vercel.app/docs/hooks/use-resize-observer) — Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.
|
|
9
|
-
- [`useScreenShare`](https://sse-hooks.vercel.app/docs/hooks/use-screen-share) — Custom hook that captures the user's screen or specific application window.
|
|
10
|
-
- [`useUserMedia`](https://sse-hooks.vercel.app/docs/hooks/use-user-media) — Custom hook that captures audio and video from the user's device.
|
|
11
|
-
|
|
12
|
-
### 💾 State
|
|
13
|
-
- [`useBoolean`](https://sse-hooks.vercel.app/docs/hooks/use-boolean) — Custom hook that handles boolean state with useful utility functions.
|
|
14
|
-
- [`useCounter`](https://sse-hooks.vercel.app/docs/hooks/use-counter) — Custom hook that manages a counter with increment, decrement, reset, and setCount functionalities.
|
|
15
|
-
- [`useMap`](https://sse-hooks.vercel.app/docs/hooks/use-map) — Custom hook that manages a key-value [`Map`](https://developer.
|
|
16
|
-
- [`useStep`](https://sse-hooks.vercel.app/docs/hooks/use-step) — Custom hook that manages and navigates between steps in a multi-step process.
|
|
17
|
-
- [`useToggle`](https://sse-hooks.vercel.app/docs/hooks/use-toggle) — Custom hook that manages a boolean toggle state in React components.
|
|
18
|
-
|
|
19
|
-
### ⚡ Side Effects
|
|
20
|
-
- [`useCountdown`](https://sse-hooks.vercel.app/docs/hooks/use-countdown) — Custom hook that manages countdown.
|
|
21
|
-
- [`useDebounceCallback`](https://sse-hooks.vercel.app/docs/hooks/use-debounce-callback) — Custom hook that creates a debounced version of a callback function.
|
|
22
|
-
- [`useDebounceValue`](https://sse-hooks.vercel.app/docs/hooks/use-debounce-value) — Custom hook that returns a debounced version of the provided value, along with a function to update it.
|
|
23
|
-
- [`useInterval`](https://sse-hooks.vercel.app/docs/hooks/use-interval) — Custom hook that creates an interval that invokes a callback function at a specified delay using the [`setInterval API`](https://developer.
|
|
24
|
-
- [`useTimeout`](https://sse-hooks.vercel.app/docs/hooks/use-timeout) — Custom hook that handles timeouts in React components using the [`setTimeout API`](https://developer.
|
|
25
|
-
|
|
26
|
-
### 🔄 LifeCycle
|
|
27
|
-
- [`useIsClient`](https://sse-hooks.vercel.app/docs/hooks/use-is-client) — Custom hook that determines if the code is running on the client side (in the browser).
|
|
28
|
-
- [`useIsMounted`](https://sse-hooks.vercel.app/docs/hooks/use-is-mounted) — Custom hook that determines if the component is currently mounted.
|
|
29
|
-
- [`useUnmount`](https://sse-hooks.vercel.app/docs/hooks/use-unmount) — Custom hook that runs a cleanup function when the component is unmounted.
|
|
30
|
-
|
|
31
|
-
### 🎨 DOM & UI
|
|
32
|
-
- [`useClickAnyWhere`](https://sse-hooks.vercel.app/docs/hooks/use-click-any-where) — Custom hook that handles click events anywhere on the document.
|
|
33
|
-
- [`useClickAway`](https://sse-hooks.vercel.app/docs/hooks/use-click-away) — Custom hook that triggers a callback when a user clicks outside the referenced element.
|
|
34
|
-
- [`useDarkMode`](https://sse-hooks.vercel.app/docs/hooks/use-dark-mode) — Custom hook that returns the current state of the dark mode.
|
|
35
|
-
- [`useDocumentTitle`](https://sse-hooks.vercel.app/docs/hooks/use-document-title) — Custom hook that sets the document title.
|
|
36
|
-
- [`useScript`](https://sse-hooks.vercel.app/docs/hooks/use-script) — Custom hook that dynamically loads scripts and tracking their loading status.
|
|
37
|
-
- [`useScrollLock`](https://sse-hooks.vercel.app/docs/hooks/use-scroll-lock) — A custom hook that locks and unlocks scroll.
|
|
38
|
-
- [`useTernaryDarkMode`](https://sse-hooks.vercel.app/docs/hooks/use-ternary-dark-mode) — Custom hook that manages ternary (system, dark, light) dark mode with local storage support.
|
|
39
|
-
|
|
40
|
-
### 📦 Storage
|
|
41
|
-
- [`useIndexedDB`](https://sse-hooks.vercel.app/docs/hooks/use-indexed-db) — Custom hook that provides an interface to the [`IndexedDB API`](https://developer.
|
|
42
|
-
- [`useLocalStorage`](https://sse-hooks.vercel.app/docs/hooks/use-local-storage) — Custom hook that uses the [`localStorage API`](https://developer.
|
|
43
|
-
- [`useSessionStorage`](https://sse-hooks.vercel.app/docs/hooks/use-session-storage) — Custom hook that uses the [`sessionStorage API`](https://developer.
|
|
44
|
-
|
|
45
|
-
### 🌐 Network
|
|
46
|
-
- [`useFetch`](https://sse-hooks.vercel.app/docs/hooks/use-fetch) — Custom hook that provides a wrapper around the native [`fetch API`](https://developer.
|
|
47
|
-
|
|
48
|
-
### 📦 Uncategorized
|
|
49
|
-
- [`useCookie`](https://sse-hooks.vercel.app/docs/hooks/use-cookie) — Custom hook that manages state synchronized with a browser [`cookie`](https://developer.
|
|
50
|
-
- [`useCopyToClipboard`](https://sse-hooks.vercel.app/docs/hooks/use-copy-to-clipboard) — Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.
|
|
51
|
-
- [`useEventCallback`](https://sse-hooks.vercel.app/docs/hooks/use-event-callback) — Custom hook that creates a memoized event callback.
|
|
52
|
-
- [`useEventListener`](https://sse-hooks.vercel.app/docs/hooks/use-event-listener) — .
|
|
53
|
-
- [`useForkRef`](https://sse-hooks.vercel.app/docs/hooks/use-fork-ref) — Merges refs into a single memoized callback ref or `null`.
|
|
54
|
-
- [`useIntersectionObserver`](https://sse-hooks.vercel.app/docs/hooks/use-intersection-observer) — Custom hook that tracks the intersection of a DOM element with its containing element or the viewport using the [`Intersection Observer API`](https://developer.
|
|
55
|
-
- [`useReadLocalStorage`](https://sse-hooks.vercel.app/docs/hooks/use-read-local-storage) — .
|
|
56
|
-
- [`useScreen`](https://sse-hooks.vercel.app/docs/hooks/use-screen) — .
|
|
57
|
-
- [`useWindowSize`](https://sse-hooks.vercel.app/docs/hooks/use-window-size) — .
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
- [`useAudioRecorder`](/react-hook/use-audio-recorder) — A comprehensive hook for audio recording with real-time analysis using getUserMedia, MediaRecorder, and Web Audio APIs.
|
|
61
|
-
- [`useBoolean`](/react-hook/use-boolean) — Custom hook that handles boolean state with useful utility functions.
|
|
62
|
-
- [`useClickAnyWhere`](/react-hook/use-click-any-where) — Custom hook that handles click events anywhere on the document.
|
|
63
|
-
- [`useClickAway`](/react-hook/use-click-away) — Custom hook that triggers a callback when a user clicks outside the referenced element.
|
|
64
|
-
- [`useCookie`](/react-hook/use-cookie) — Custom hook that manages state synchronized with a browser [`cookie`](https://developer.
|
|
65
|
-
- [`useCopyToClipboard`](/react-hook/use-copy-to-clipboard) — Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.
|
|
66
|
-
- [`useCountdown`](/react-hook/use-countdown) — Custom hook that manages countdown.
|
|
67
|
-
- [`useCounter`](/react-hook/use-counter) — Custom hook that manages a counter with increment, decrement, reset, and setCount functionalities.
|
|
68
|
-
- [`useDarkMode`](/react-hook/use-dark-mode) — Custom hook that returns the current state of the dark mode.
|
|
69
|
-
- [`useDebounceCallback`](/react-hook/use-debounce-callback) — Custom hook that creates a debounced version of a callback function.
|
|
70
|
-
- [`useDebounceValue`](/react-hook/use-debounce-value) — Custom hook that returns a debounced version of the provided value, along with a function to update it.
|
|
71
|
-
- [`useDocumentTitle`](/react-hook/use-document-title) — Custom hook that sets the document title.
|
|
72
|
-
- [`useEventCallback`](/react-hook/use-event-callback) — Custom hook that creates a memoized event callback.
|
|
73
|
-
- [`useEventListener`](/react-hook/use-event-listener) — .
|
|
74
|
-
- [`useFetch`](/react-hook/use-fetch) — Custom hook that provides a wrapper around the native [`fetch API`](https://developer.
|
|
75
|
-
- [`useForkRef`](/react-hook/use-fork-ref) — Merges refs into a single memoized callback ref or `null`.
|
|
76
|
-
- [`useHover`](/react-hook/use-hover) — Custom hook that tracks whether a DOM element is being hovered over.
|
|
77
|
-
- [`useIndexedDB`](/react-hook/use-indexed-db) — Custom hook that provides an interface to the [`IndexedDB API`](https://developer.
|
|
78
|
-
- [`useIntersectionObserver`](/react-hook/use-intersection-observer) — Custom hook that tracks the intersection of a DOM element with its containing element or the viewport using the [`Intersection Observer API`](https://developer.
|
|
79
|
-
- [`useInterval`](/react-hook/use-interval) — Custom hook that creates an interval that invokes a callback function at a specified delay using the [`setInterval API`](https://developer.
|
|
80
|
-
- [`useIsClient`](/react-hook/use-is-client) — Custom hook that determines if the code is running on the client side (in the browser).
|
|
81
|
-
- [`useIsMounted`](/react-hook/use-is-mounted) — Custom hook that determines if the component is currently mounted.
|
|
82
|
-
- [`useLocalStorage`](/react-hook/use-local-storage) — Custom hook that uses the [`localStorage API`](https://developer.
|
|
83
|
-
- [`useMap`](/react-hook/use-map) — Custom hook that manages a key-value [`Map`](https://developer.
|
|
84
|
-
- [`useMediaQuery`](/react-hook/use-media-query) — Custom hook that tracks the state of a media query using the [`Match Media API`](https://developer.
|
|
85
|
-
- [`useMediaSession`](/react-hook/use-media-session) — Custom hook that interacts with the [Media Session API](https://developer.
|
|
86
|
-
- [`useReadLocalStorage`](/react-hook/use-read-local-storage) — .
|
|
87
|
-
- [`useResizeObserver`](/react-hook/use-resize-observer) — Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.
|
|
88
|
-
- [`useScreen`](/react-hook/use-screen) — .
|
|
89
|
-
- [`useScreenShare`](/react-hook/use-screen-share) — Custom hook that captures the user's screen or specific application window.
|
|
90
|
-
- [`useScript`](/react-hook/use-script) — Custom hook that dynamically loads scripts and tracking their loading status.
|
|
91
|
-
- [`useScrollLock`](/react-hook/use-scroll-lock) — A custom hook that locks and unlocks scroll.
|
|
92
|
-
- [`useSessionStorage`](/react-hook/use-session-storage) — Custom hook that uses the [`sessionStorage API`](https://developer.
|
|
93
|
-
- [`useStep`](/react-hook/use-step) — Custom hook that manages and navigates between steps in a multi-step process.
|
|
94
|
-
- [`useTernaryDarkMode`](/react-hook/use-ternary-dark-mode) — Custom hook that manages ternary (system, dark, light) dark mode with local storage support.
|
|
95
|
-
- [`useTimeout`](/react-hook/use-timeout) — Custom hook that handles timeouts in React components using the [`setTimeout API`](https://developer.
|
|
96
|
-
- [`useToggle`](/react-hook/use-toggle) — Custom hook that manages a boolean toggle state in React components.
|
|
97
|
-
- [`useUnmount`](/react-hook/use-unmount) — Custom hook that runs a cleanup function when the component is unmounted.
|
|
98
|
-
- [`useUserMedia`](/react-hook/use-user-media) — Custom hook that captures audio and video from the user's device.
|
|
99
|
-
- [`useWindowSize`](/react-hook/use-window-size) — .
|
|
100
|
-
## 🪝 Available Hooks
|
|
101
|
-
|
|
102
|
-
<!-- HOOKS:START -->
|
|
103
|
-
|
|
104
|
-
### 📡 Sensors
|
|
105
|
-
- [`useAudioRecorder`](https://sse-hooks.vercel.app/docs/hooks/use-audio-recorder) — A comprehensive hook for audio recording with real-time analysis using getUserMedia, MediaRecorder, and Web Audio APIs.
|
|
106
|
-
- [`useConferenceSystem`](https://sse-hooks.vercel.app/docs/hooks/use-conference-system) — A comprehensive hook for managing video conferencing state, including camera access, screen sharing, network monitoring, and automatic media quality adjustment.
|
|
107
|
-
- [`useHover`](https://sse-hooks.vercel.app/docs/hooks/use-hover) — Custom hook that tracks whether a DOM element is being hovered over.
|
|
108
|
-
- [`useMediaQuery`](https://sse-hooks.vercel.app/docs/hooks/use-media-query) — Custom hook that tracks the state of a media query using the [`Match Media API`](https://developer.
|
|
109
|
-
- [`useMediaSession`](https://sse-hooks.vercel.app/docs/hooks/use-media-session) — Custom hook that interacts with the [Media Session API](https://developer.
|
|
110
|
-
- [`useResizeObserver`](https://sse-hooks.vercel.app/docs/hooks/use-resize-observer) — Custom hook that observes the size of an element using the [`ResizeObserver API`](https://developer.
|
|
111
|
-
- [`useScreenShare`](https://sse-hooks.vercel.app/docs/hooks/use-screen-share) — Custom hook that captures the user's screen or specific application window.
|
|
112
|
-
- [`useUserMedia`](https://sse-hooks.vercel.app/docs/hooks/use-user-media) — Custom hook that captures audio and video from the user's device.
|
|
113
|
-
|
|
114
|
-
### 💾 State
|
|
115
|
-
- [`useBoolean`](https://sse-hooks.vercel.app/docs/hooks/use-boolean) — Custom hook that handles boolean state with useful utility functions.
|
|
116
|
-
- [`useCounter`](https://sse-hooks.vercel.app/docs/hooks/use-counter) — Custom hook that manages a counter with increment, decrement, reset, and setCount functionalities.
|
|
117
|
-
- [`useMap`](https://sse-hooks.vercel.app/docs/hooks/use-map) — Custom hook that manages a key-value [`Map`](https://developer.
|
|
118
|
-
- [`useRoleGuard`](https://sse-hooks.vercel.app/docs/hooks/use-role-guard) — Custom hook for Role-Based Access Control (RBAC).
|
|
119
|
-
- [`useStep`](https://sse-hooks.vercel.app/docs/hooks/use-step) — Custom hook that manages and navigates between steps in a multi-step process.
|
|
120
|
-
- [`useToggle`](https://sse-hooks.vercel.app/docs/hooks/use-toggle) — Custom hook that manages a boolean toggle state in React components.
|
|
121
|
-
|
|
122
|
-
### ⚡ Side Effects
|
|
123
|
-
- [`useCountdown`](https://sse-hooks.vercel.app/docs/hooks/use-countdown) — Custom hook that manages countdown.
|
|
124
|
-
- [`useDebounceCallback`](https://sse-hooks.vercel.app/docs/hooks/use-debounce-callback) — Custom hook that creates a debounced version of a callback function.
|
|
125
|
-
- [`useDebounceValue`](https://sse-hooks.vercel.app/docs/hooks/use-debounce-value) — Custom hook that returns a debounced version of the provided value, along with a function to update it.
|
|
126
|
-
- [`useInterval`](https://sse-hooks.vercel.app/docs/hooks/use-interval) — Custom hook that creates an interval that invokes a callback function at a specified delay using the [`setInterval API`](https://developer.
|
|
127
|
-
- [`useTimeout`](https://sse-hooks.vercel.app/docs/hooks/use-timeout) — Custom hook that handles timeouts in React components using the [`setTimeout API`](https://developer.
|
|
128
|
-
|
|
129
|
-
### 🔄 LifeCycle
|
|
130
|
-
- [`useIsClient`](https://sse-hooks.vercel.app/docs/hooks/use-is-client) — Custom hook that determines if the code is running on the client side (in the browser).
|
|
131
|
-
- [`useIsMounted`](https://sse-hooks.vercel.app/docs/hooks/use-is-mounted) — Custom hook that determines if the component is currently mounted.
|
|
132
|
-
- [`useUnmount`](https://sse-hooks.vercel.app/docs/hooks/use-unmount) — Custom hook that runs a cleanup function when the component is unmounted.
|
|
133
|
-
|
|
134
|
-
### 🎨 DOM & UI
|
|
135
|
-
- [`useClickAnyWhere`](https://sse-hooks.vercel.app/docs/hooks/use-click-any-where) — Custom hook that handles click events anywhere on the document.
|
|
136
|
-
- [`useClickAway`](https://sse-hooks.vercel.app/docs/hooks/use-click-away) — Custom hook that triggers a callback when a user clicks outside the referenced element.
|
|
137
|
-
- [`useDarkMode`](https://sse-hooks.vercel.app/docs/hooks/use-dark-mode) — Custom hook that returns the current state of the dark mode.
|
|
138
|
-
- [`useDocumentTitle`](https://sse-hooks.vercel.app/docs/hooks/use-document-title) — Custom hook that sets the document title.
|
|
139
|
-
- [`useForkRef`](https://sse-hooks.vercel.app/docs/hooks/use-fork-ref) — Merges refs into a single memoized callback ref or `null`.
|
|
140
|
-
- [`useScript`](https://sse-hooks.vercel.app/docs/hooks/use-script) — Custom hook that dynamically loads scripts and tracking their loading status.
|
|
141
|
-
- [`useScrollLock`](https://sse-hooks.vercel.app/docs/hooks/use-scroll-lock) — A custom hook that locks and unlocks scroll.
|
|
142
|
-
- [`useTernaryDarkMode`](https://sse-hooks.vercel.app/docs/hooks/use-ternary-dark-mode) — Custom hook that manages ternary (system, dark, light) dark mode with local storage support.
|
|
143
|
-
|
|
144
|
-
### 📦 Storage
|
|
145
|
-
- [`useCookie`](https://sse-hooks.vercel.app/docs/hooks/use-cookie) — Custom hook that manages state synchronized with a browser [`cookie`](https://developer.
|
|
146
|
-
- [`useIndexedDB`](https://sse-hooks.vercel.app/docs/hooks/use-indexed-db) — Custom hook that provides an interface to the [`IndexedDB API`](https://developer.
|
|
147
|
-
- [`useLocalStorage`](https://sse-hooks.vercel.app/docs/hooks/use-local-storage) — Custom hook that uses the [`localStorage API`](https://developer.
|
|
148
|
-
- [`useSessionStorage`](https://sse-hooks.vercel.app/docs/hooks/use-session-storage) — Custom hook that uses the [`sessionStorage API`](https://developer.
|
|
149
|
-
|
|
150
|
-
### 🌐 Network
|
|
151
|
-
- [`useFetch`](https://sse-hooks.vercel.app/docs/hooks/use-fetch) — Custom hook that provides a wrapper around the native [`fetch API`](https://developer.
|
|
152
|
-
- [`useNetworkInformation`](https://sse-hooks.vercel.app/docs/hooks/use-network-information) — Custom hook that tracks the device's network connection status and details (speed, type)
|
|
153
|
-
using the Network Information API.
|
|
154
|
-
|
|
155
|
-
### 🛠️ Utilities
|
|
156
|
-
- [`useCopyToClipboard`](https://sse-hooks.vercel.app/docs/hooks/use-copy-to-clipboard) — Custom hook that copies text to the clipboard using the [`Clipboard API`](https://developer.
|
|
157
|
-
- [`useEventCallback`](https://sse-hooks.vercel.app/docs/hooks/use-event-callback) — Custom hook that creates a memoized event callback.
|
|
158
|
-
- [`useKbd`](https://sse-hooks.vercel.app/docs/hooks/use-kbd) — Custom hook that detects the operating system (Mac vs.
|
|
159
|
-
- [`useMediaQuality`](https://sse-hooks.vercel.app/docs/hooks/use-media-quality) — Custom hook to manage video stream quality by applying constraints (resolution and frame rate)
|
|
160
|
-
to a MediaStream track.
|
|
161
|
-
- [`useSSR`](https://sse-hooks.vercel.app/docs/hooks/use-ssr) — Custom hook that detects the current environment (Browser, Server, or Native)
|
|
162
|
-
and capability support (Workers, EventListeners).
|
|
163
|
-
- [`useSymbol`](https://sse-hooks.vercel.app/docs/hooks/use-symbol) — Custom hook for managing ES6 Symbols.
|
|
164
|
-
|
|
165
|
-
### 📦 Uncategorized
|
|
166
|
-
- [`useEventListener`](https://sse-hooks.vercel.app/docs/hooks/use-event-listener) — .
|
|
167
|
-
- [`useIntersectionObserver`](https://sse-hooks.vercel.app/docs/hooks/use-intersection-observer) — Custom hook that tracks the intersection of a DOM element with its containing element or the viewport using the [`Intersection Observer API`](https://developer.
|
|
168
|
-
- [`useReadLocalStorage`](https://sse-hooks.vercel.app/docs/hooks/use-read-local-storage) — .
|
|
169
|
-
- [`useScreen`](https://sse-hooks.vercel.app/docs/hooks/use-screen) — .
|
|
170
|
-
- [`useWindowSize`](https://sse-hooks.vercel.app/docs/hooks/use-window-size) — .
|
|
171
|
-
<!-- HOOKS:END -->
|