quack-search 0.0.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/bin/quack-darwin-arm64 +0 -0
- package/bin/quack-darwin-x64 +0 -0
- package/bin/quack-linux-x64 +0 -0
- package/bin/quack-windows-x64.exe +0 -0
- package/dist/index.js +110 -0
- package/package.json +21 -0
- package/scripts/postinstall.js +25 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/core/runner.ts
|
|
3
|
+
import { spawn } from "child_process";
|
|
4
|
+
|
|
5
|
+
// src/core/binary.ts
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
|
|
8
|
+
// src/util/path.ts
|
|
9
|
+
import { dirname } from "path";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
function resolveDirname(metaUrl) {
|
|
12
|
+
return typeof import.meta.dir === "string" ? import.meta.dir : dirname(fileURLToPath(metaUrl));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/core/binary.ts
|
|
16
|
+
function resolveBinaryPath(metaUrl) {
|
|
17
|
+
const platform = process.platform;
|
|
18
|
+
const arch = process.arch;
|
|
19
|
+
let suffix;
|
|
20
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
21
|
+
suffix = "darwin-arm64";
|
|
22
|
+
} else if (platform === "darwin" && arch === "x64") {
|
|
23
|
+
suffix = "darwin-x64";
|
|
24
|
+
} else if (platform === "linux" && arch === "x64") {
|
|
25
|
+
suffix = "linux-x64";
|
|
26
|
+
} else if (platform === "win32" && arch === "x64") {
|
|
27
|
+
suffix = "windows-x64.exe";
|
|
28
|
+
} else {
|
|
29
|
+
throw new Error(`unsupported platform: ${platform} ${arch}`);
|
|
30
|
+
}
|
|
31
|
+
const dir = resolveDirname(metaUrl);
|
|
32
|
+
return join(dir, "..", "bin", `quack-${suffix}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// src/core/runner.ts
|
|
36
|
+
function runCore(payload, timeoutMs = 30000, metaUrl = import.meta.url) {
|
|
37
|
+
return new Promise((resolve, reject) => {
|
|
38
|
+
const binaryPath = resolveBinaryPath(metaUrl);
|
|
39
|
+
const proc = spawn(binaryPath, {
|
|
40
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
41
|
+
});
|
|
42
|
+
let stdout = "";
|
|
43
|
+
let stderr = "";
|
|
44
|
+
const timeout = setTimeout(() => {
|
|
45
|
+
proc.kill();
|
|
46
|
+
reject(new Error("core process timed out"));
|
|
47
|
+
}, timeoutMs);
|
|
48
|
+
proc.stdout.on("data", (d) => {
|
|
49
|
+
stdout += d.toString();
|
|
50
|
+
});
|
|
51
|
+
proc.stderr.on("data", (d) => {
|
|
52
|
+
stderr += d.toString();
|
|
53
|
+
});
|
|
54
|
+
proc.on("error", (err) => {
|
|
55
|
+
clearTimeout(timeout);
|
|
56
|
+
reject(err);
|
|
57
|
+
});
|
|
58
|
+
proc.on("close", (code) => {
|
|
59
|
+
clearTimeout(timeout);
|
|
60
|
+
if (code !== 0) {
|
|
61
|
+
reject(new Error(stderr || "core process failed"));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
let parsed;
|
|
65
|
+
try {
|
|
66
|
+
parsed = JSON.parse(stdout);
|
|
67
|
+
} catch {
|
|
68
|
+
reject(new Error("invalid JSON returned from core"));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (parsed.error) {
|
|
72
|
+
reject(new Error(parsed.error));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!parsed.text) {
|
|
76
|
+
reject(new Error("empty response from core"));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
resolve(parsed.text);
|
|
80
|
+
});
|
|
81
|
+
proc.stdin.write(JSON.stringify(payload));
|
|
82
|
+
proc.stdin.end();
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/api/search.ts
|
|
87
|
+
async function search(query, options = {}) {
|
|
88
|
+
if (!query) {
|
|
89
|
+
throw new Error("query is required");
|
|
90
|
+
}
|
|
91
|
+
return runCore({
|
|
92
|
+
action: "search",
|
|
93
|
+
query,
|
|
94
|
+
maxResults: options.maxResults ?? 10
|
|
95
|
+
}, options.timeoutMs);
|
|
96
|
+
}
|
|
97
|
+
// src/api/fetch.ts
|
|
98
|
+
async function fetchContent(url, timeoutMs) {
|
|
99
|
+
if (!url) {
|
|
100
|
+
throw new Error("url is required");
|
|
101
|
+
}
|
|
102
|
+
return runCore({
|
|
103
|
+
action: "fetch",
|
|
104
|
+
url
|
|
105
|
+
}, timeoutMs);
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
search,
|
|
109
|
+
fetchContent
|
|
110
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "quack-search",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"bin",
|
|
9
|
+
"scripts"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "bun build src/index.ts --outdir dist --target bun",
|
|
13
|
+
"postinstall": "node scripts/postinstall.js"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/bun": "latest"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": "^5"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { platform, arch } from "node:process";
|
|
2
|
+
import { chmodSync, existsSync } from "node:fs";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const BIN_DIR = join(__dirname, "..", "bin");
|
|
8
|
+
|
|
9
|
+
function suffix() {
|
|
10
|
+
if (platform === "darwin" && arch === "arm64") return "darwin-arm64";
|
|
11
|
+
if (platform === "darwin" && arch === "x64") return "darwin-x64";
|
|
12
|
+
if (platform === "linux" && arch === "x64") return "linux-x64";
|
|
13
|
+
if (platform === "win32" && arch === "x64") return "windows-x64.exe";
|
|
14
|
+
throw new Error(`Unsupported platform: ${platform} ${arch}`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const binPath = join(BIN_DIR, `quack-${suffix()}`);
|
|
18
|
+
|
|
19
|
+
if (!existsSync(binPath)) {
|
|
20
|
+
console.error(`Missing binary: ${binPath}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
chmodSync(binPath, 0o755);
|
|
25
|
+
console.log(`quack binary ready: ${binPath}`);
|