@bob-kit/client 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.
@@ -0,0 +1,7 @@
1
+ import type { BobQueryResult, Memory } from "@bob-kit/types";
2
+ export declare class MemoryCache implements Memory {
3
+ cache: Map<any, any>;
4
+ get(id: string): BobQueryResult;
5
+ has(id: string): boolean;
6
+ set(id: string, value: BobQueryResult): Map<any, any>;
7
+ }
package/dist/cache.js ADDED
@@ -0,0 +1,14 @@
1
+ export class MemoryCache {
2
+ constructor() {
3
+ this.cache = new Map();
4
+ }
5
+ get(id) {
6
+ return this.cache.get(id);
7
+ }
8
+ has(id) {
9
+ return this.cache.has(id);
10
+ }
11
+ set(id, value) {
12
+ return this.cache.set(id, value);
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ import type { Motor } from "@bob-kit/types";
2
+ export declare class Daemon {
3
+ private process;
4
+ private buffer;
5
+ private queue;
6
+ constructor(driver: Motor);
7
+ query(message: string): Promise<string>;
8
+ close(): void;
9
+ status(): boolean;
10
+ }
package/dist/daemon.js ADDED
@@ -0,0 +1,47 @@
1
+ import { spawn } from "node:child_process";
2
+ export class Daemon {
3
+ constructor(driver) {
4
+ this.buffer = "";
5
+ this.queue = [];
6
+ const cwd = process.cwd();
7
+ this.process = spawn(`${cwd}/src/bob/motors/bob-windows-amd64.exe`, ["-d", driver, "--json", "--daemon"], {
8
+ stdio: ["pipe", "pipe", "pipe"],
9
+ windowsHide: true,
10
+ });
11
+ this.process.stdout.setEncoding("utf8");
12
+ this.process.stdout.on("data", (data) => {
13
+ this.buffer += data;
14
+ let endIndex;
15
+ while ((endIndex = this.buffer.indexOf("__END__")) !== -1) {
16
+ const response = this.buffer.slice(0, endIndex).trim();
17
+ this.buffer = this.buffer.slice(endIndex + "__END__".length);
18
+ if (this.queue.length) {
19
+ const resolve = this.queue.shift();
20
+ if (resolve)
21
+ resolve(response);
22
+ }
23
+ }
24
+ });
25
+ this.process.on("exit", () => {
26
+ this.buffer = "";
27
+ this.queue = [];
28
+ });
29
+ }
30
+ async query(message) {
31
+ if (!this.process || !this.process.stdin) {
32
+ throw new Error("Daemon process not available.");
33
+ }
34
+ return new Promise((resolve) => {
35
+ this.queue.push(resolve);
36
+ this.process.stdin.write(`${message}\n__END__\n`);
37
+ });
38
+ }
39
+ close() {
40
+ if (this.process && !this.process.killed) {
41
+ this.process.kill();
42
+ }
43
+ }
44
+ status() {
45
+ return !!this.process && !this.process.killed;
46
+ }
47
+ }
@@ -0,0 +1,14 @@
1
+ import type { BobQueryResult, BobResult, Driver } from "@bob-kit/types";
2
+ type BobQueryParams = {
3
+ id?: string;
4
+ driver: Driver;
5
+ input: TemplateStringsArray | string;
6
+ };
7
+ export declare const bobQuery: ({ id, driver: { cache, driver }, input, }: BobQueryParams) => Promise<BobQueryResult>;
8
+ export default function bob(driver: Driver): {
9
+ query: <A, B = any>(input: TemplateStringsArray | string, ...parameters: B[]) => Promise<BobResult<A>>;
10
+ cache: (id: string) => <A, B = any>(input: TemplateStringsArray | string, ...parameters: B[]) => Promise<BobResult<A>>;
11
+ factory: any;
12
+ };
13
+ export { };
14
+
package/dist/index.js ADDED
@@ -0,0 +1,55 @@
1
+ import { Daemon } from "./daemon";
2
+ let daemon;
3
+ export const bobQuery = async ({ id, driver: { cache, driver }, input, }) => {
4
+ daemon = new Daemon(driver);
5
+ const query = typeof input === "string" ? input : input.join("?");
6
+ const cacheKey = id ?? query;
7
+ if (cache) {
8
+ const cached = cache.get(cacheKey);
9
+ if (cached)
10
+ return cache.get(cacheKey);
11
+ }
12
+ const jsonString = await daemon.query(query);
13
+ let json;
14
+ try {
15
+ json = JSON.parse(jsonString);
16
+ }
17
+ catch (err) {
18
+ throw new Error("Invalid JSON returned by daemon '" + err + "'");
19
+ }
20
+ if (cache) {
21
+ cache.set(cacheKey, json);
22
+ }
23
+ return json;
24
+ };
25
+ export default function bob(driver) {
26
+ const execute = async (input, parameters = [], id) => {
27
+ const { error, tables, actions } = await bobQuery({ input, driver, id });
28
+ if (error)
29
+ return { error };
30
+ if (tables) {
31
+ for (const table of tables) {
32
+ await driver.querier(table.trim());
33
+ }
34
+ }
35
+ if (actions) {
36
+ const result = await Promise.all(actions.map((action) => driver.querier(action, ...parameters)));
37
+ if (result.length === 1) {
38
+ return { value: (result[0].length ? result[0] : undefined) };
39
+ }
40
+ return { value: result };
41
+ }
42
+ return { value: undefined };
43
+ };
44
+ return {
45
+ query: (input, ...parameters) => execute(input, parameters),
46
+ cache: (id) => (input, ...parameters) => execute(input, parameters, id),
47
+ factory: new Proxy({}, {
48
+ get(_, id) {
49
+ return (input, ...parameters) => {
50
+ return execute(input, parameters, id);
51
+ };
52
+ },
53
+ }),
54
+ };
55
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { pipeline } from "stream";
4
+ import { promisify } from "util";
5
+ const streamPipeline = promisify(pipeline);
6
+ function detectBobFile() {
7
+ const platform = process.platform; // 'win32', 'darwin', 'linux'
8
+ const arch = process.arch; // 'x64', 'arm64', etc.
9
+ let file = "";
10
+ if (platform === "win32") {
11
+ file = "bob-windows-amd64.exe";
12
+ }
13
+ else if (platform === "darwin") {
14
+ file = arch === "arm64" ? "bob-darwin-arm64" : "bob-darwin-amd64";
15
+ }
16
+ else if (platform === "linux") {
17
+ file = arch === "arm64" ? "bob-linux-arm64" : "bob-linux-amd64";
18
+ }
19
+ else {
20
+ throw new Error(`Unsupported platform: ${platform}`);
21
+ }
22
+ return file;
23
+ }
24
+ async function downloadFile(url, folder, filename) {
25
+ const res = await fetch(url);
26
+ if (!res.ok)
27
+ throw new Error(`Failed to fetch ${url}: ${res.statusText}`);
28
+ fs.mkdirSync(folder, { recursive: true });
29
+ const filePath = path.join(folder, filename);
30
+ const nodeStream = res.body;
31
+ await streamPipeline(nodeStream, fs.createWriteStream(filePath));
32
+ console.log(`Downloaded ${filename} to ${filePath}`);
33
+ }
34
+ (async () => {
35
+ try {
36
+ const version = "v0.0.1"; // or dynamic
37
+ const fileName = detectBobFile();
38
+ const url = `https://github.com/bob-object-builder/bob/releases/download/${version}/${fileName}`;
39
+ const downloadFolder = "src/lib/motors";
40
+ await downloadFile(url, downloadFolder, fileName);
41
+ }
42
+ catch (err) {
43
+ console.error("Error:", err);
44
+ }
45
+ })();
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@bob-kit/client",
3
+ "version": "0.0.1",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "description": "",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ },
16
+ "./cache": {
17
+ "import": "./dist/cache.js",
18
+ "require": "./dist/cache.js",
19
+ "types": "./dist/cache.d.ts"
20
+ },
21
+ "./daemon": {
22
+ "import": "./dist/daemon.js",
23
+ "require": "./dist/daemon.js",
24
+ "types": "./dist/daemon.d.ts"
25
+ },
26
+ "./install": {
27
+ "import": "./dist/install.js",
28
+ "require": "./dist/install.js",
29
+ "types": "./dist/install.d.ts"
30
+ }
31
+ },
32
+ "keywords": [],
33
+ "author": "",
34
+ "license": "ISC",
35
+ "devDependencies": {
36
+ "@types/node": "24.10.1",
37
+ "tsc-alias": "^1.8.16",
38
+ "typescript": "5.9.3"
39
+ },
40
+ "dependencies": {
41
+ "@bob-kit/types": "^0.0.1"
42
+ },
43
+ "scripts": {
44
+ "build": "tsc && tsc-alias",
45
+ "postinstall": "node dist/install.js",
46
+ "test": "echo \"Error: no test specified\" && exit 1"
47
+ }
48
+ }