@react-grab/cursor 0.0.59 → 0.0.61

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/README.md CHANGED
@@ -18,46 +18,61 @@ yarn add @react-grab/cursor
18
18
 
19
19
  The server runs on port `5567` by default.
20
20
 
21
+ ### Quick Start (CLI)
22
+
23
+ Start the server in the background before running your dev server:
24
+
25
+ ```bash
26
+ npx @react-grab/cursor && pnpm run dev
27
+ ```
28
+
29
+ The server will run as a detached background process. **Note:** Stopping your dev server (Ctrl+C) won't stop the React Grab server. To stop it:
30
+
31
+ ```bash
32
+ pkill -f "react-grab.*server"
33
+ ```
34
+
35
+ ### Recommended: Config File (Automatic Lifecycle)
36
+
37
+ For better lifecycle management, start the server from your config file. This ensures the server stops when your dev server stops:
38
+
21
39
  ### Vite
22
40
 
23
41
  ```ts
24
42
  // vite.config.ts
25
- import "@react-grab/cursor/server";
43
+ import { startServer } from "@react-grab/cursor/server";
44
+
45
+ if (process.env.NODE_ENV === "development") {
46
+ startServer();
47
+ }
26
48
  ```
27
49
 
28
50
  ### Next.js
29
51
 
30
52
  ```ts
31
53
  // next.config.ts
32
- import "@react-grab/cursor/server";
54
+ import { startServer } from "@react-grab/cursor/server";
55
+
56
+ if (process.env.NODE_ENV === "development") {
57
+ startServer();
58
+ }
33
59
  ```
34
60
 
35
61
  ## Client Usage
36
62
 
37
- ```tsx
38
- import { init } from "react-grab/core";
39
- import { createCursorAgentProvider } from "@react-grab/cursor/client";
40
-
41
- const agentProvider = createCursorAgentProvider();
63
+ ### Script Tag
42
64
 
43
- init({
44
- agent: {
45
- provider: agentProvider,
46
- },
47
- });
65
+ ```html
66
+ <script src="//unpkg.com/react-grab/dist/index.global.js"></script>
67
+ <script src="//unpkg.com/@react-grab/cursor/dist/client.global.js"></script>
48
68
  ```
49
69
 
50
- ## Configuration
51
-
52
- You can customize the server URL and default options:
70
+ ### ES Module
53
71
 
54
72
  ```tsx
55
- const agentProvider = createCursorAgentProvider({
56
- getOptions: () => ({
57
- model: "composer-1",
58
- workspace: "/path/to/workspace",
59
- }),
60
- });
73
+ import { attachAgent } from "@react-grab/cursor/client";
74
+
75
+ attachAgent();
61
76
  ```
62
77
 
63
78
  ## How It Works
package/dist/cli.cjs ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ var child_process = require('child_process');
5
+ var url = require('url');
6
+ var path = require('path');
7
+
8
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
+ var __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)));
10
+ var __dirname$1 = path.dirname(__filename$1);
11
+ var serverPath = path.join(__dirname$1, "server.js");
12
+ child_process.spawn(process.execPath, [serverPath], {
13
+ detached: true,
14
+ stdio: "ignore"
15
+ }).unref();
16
+ console.log("[React Grab] Server starting on port 5567...");
package/dist/cli.d.cts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'child_process';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname, join } from 'path';
5
+
6
+ var __filename = fileURLToPath(import.meta.url);
7
+ var __dirname = dirname(__filename);
8
+ var serverPath = join(__dirname, "server.js");
9
+ spawn(process.execPath, [serverPath], {
10
+ detached: true,
11
+ stdio: "ignore"
12
+ }).unref();
13
+ console.log("[React Grab] Server starting on port 5567...");
package/dist/client.cjs CHANGED
@@ -104,6 +104,7 @@ var attachAgent = async () => {
104
104
  { once: true }
105
105
  );
106
106
  };
107
+ attachAgent();
107
108
 
108
109
  exports.attachAgent = attachAgent;
109
110
  exports.createCursorAgentProvider = createCursorAgentProvider;
@@ -0,0 +1,4 @@
1
+ var ReactGrabCursor=(function(exports){'use strict';var l=`http://localhost:${5567}`,A="react-grab:agent-sessions",f=n=>{let t="",r="";for(let e of n.split(`
2
+ `))e.startsWith("event:")?t=e.slice(6).trim():e.startsWith("data:")&&(r=e.slice(5).trim());return {eventType:t,data:r}};async function*y(n){let t=n.getReader(),r=new TextDecoder,e="";try{for(;;){let{done:o,value:i}=await t.read();i&&(e+=r.decode(i,{stream:!0}));let s;for(;(s=e.indexOf(`
3
+
4
+ `))!==-1;){let{eventType:c,data:a}=f(e.slice(0,s));if(e=e.slice(s+2),c==="done")return;if(c==="error")throw new Error(a||"Agent error");a&&(yield a);}if(o)break}}finally{t.releaseLock();}}async function*d(n,t,r){let e=await fetch(`${n}/agent`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:r});if(!e.ok)throw new Error(`Server error: ${e.status}`);if(!e.body)throw new Error("No response body");yield*y(e.body);}var E=(n={})=>{let{serverUrl:t=l,getOptions:r}=n,e=o=>({...r?.()??{},...o??{}});return {send:async function*(o,i){let s={...o,options:e(o.options)};yield*d(t,s,i);},resume:async function*(o,i){let s=sessionStorage.getItem(A);if(!s)throw new Error("No sessions to resume");let a=JSON.parse(s)[o];if(!a)throw new Error(`Session ${o} not found`);let g=a.context,p={...g,options:e(g.options)};yield "Resuming...",yield*d(t,p,i);},supportsResume:true}},C=async()=>{if(typeof window>"u")return;let n=E(),t=window.__REACT_GRAB__;if(t){t.setAgent({provider:n});return}window.addEventListener("react-grab:init",r=>{r.detail.setAgent({provider:n});},{once:true});};C();exports.attachAgent=C;exports.createCursorAgentProvider=E;return exports;})({});
package/dist/client.js CHANGED
@@ -102,5 +102,6 @@ var attachAgent = async () => {
102
102
  { once: true }
103
103
  );
104
104
  };
105
+ attachAgent();
105
106
 
106
107
  export { attachAgent, createCursorAgentProvider };
package/dist/server.cjs CHANGED
@@ -1,13 +1,16 @@
1
1
  'use strict';
2
2
 
3
3
  var child_process = require('child_process');
4
+ var net = require('net');
4
5
  var http = require('http');
5
6
  var http2 = require('http2');
6
7
  var stream = require('stream');
7
8
  var crypto = require('crypto');
8
9
 
10
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
9
11
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
12
 
13
+ var net__default = /*#__PURE__*/_interopDefault(net);
11
14
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
12
15
 
13
16
  // src/server.ts
@@ -2399,28 +2402,26 @@ ${content}`;
2399
2402
  });
2400
2403
  return app;
2401
2404
  };
2402
- var killProcessOnPort = (port) => {
2403
- try {
2404
- if (process.platform === "win32") {
2405
- child_process.execSync(
2406
- `for /f "tokens=5" %a in ('netstat -aon ^| findstr :${port} ^| findstr LISTENING') do taskkill /F /PID %a`,
2407
- { stdio: "ignore", timeout: 1e3, shell: "cmd.exe" }
2408
- );
2409
- } else {
2410
- child_process.execSync(`lsof -ti:${port} | xargs kill -9 2>/dev/null`, {
2411
- stdio: "ignore",
2412
- timeout: 1e3
2413
- });
2414
- }
2415
- } catch {
2405
+ var isPortInUse = (port) => new Promise((resolve) => {
2406
+ const server = net__default.default.createServer();
2407
+ server.once("error", () => resolve(true));
2408
+ server.once("listening", () => {
2409
+ server.close();
2410
+ resolve(false);
2411
+ });
2412
+ server.listen(port);
2413
+ });
2414
+ var startServer = async (port = DEFAULT_PORT) => {
2415
+ if (await isPortInUse(port)) {
2416
+ return;
2416
2417
  }
2417
- };
2418
- var startServer = (port = DEFAULT_PORT) => {
2419
- killProcessOnPort(port);
2420
2418
  const app = createServer();
2421
2419
  serve({ fetch: app.fetch, port });
2422
- console.log("React Grab Cursor server running on port", port);
2420
+ console.log(`[React Grab] Server started on port ${port}`);
2423
2421
  };
2422
+ if ((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('server.cjs', document.baseURI).href)) === `file://${process.argv[1]}`) {
2423
+ startServer(DEFAULT_PORT).catch(console.error);
2424
+ }
2424
2425
 
2425
2426
  exports.createServer = createServer;
2426
2427
  exports.startServer = startServer;
package/dist/server.d.cts CHANGED
@@ -2,6 +2,6 @@ import * as hono_types from 'hono/types';
2
2
  import { Hono } from 'hono';
3
3
 
4
4
  declare const createServer: () => Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
5
- declare const startServer: (port?: number) => void;
5
+ declare const startServer: (port?: number) => Promise<void>;
6
6
 
7
7
  export { createServer, startServer };
package/dist/server.d.ts CHANGED
@@ -2,6 +2,6 @@ import * as hono_types from 'hono/types';
2
2
  import { Hono } from 'hono';
3
3
 
4
4
  declare const createServer: () => Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
5
- declare const startServer: (port?: number) => void;
5
+ declare const startServer: (port?: number) => Promise<void>;
6
6
 
7
7
  export { createServer, startServer };
package/dist/server.js CHANGED
@@ -1,4 +1,5 @@
1
- import { execSync, spawn } from 'child_process';
1
+ import { spawn } from 'child_process';
2
+ import net from 'net';
2
3
  import { createServer as createServer$1 } from 'http';
3
4
  import { Http2ServerRequest } from 'http2';
4
5
  import { Readable } from 'stream';
@@ -2393,27 +2394,25 @@ ${content}`;
2393
2394
  });
2394
2395
  return app;
2395
2396
  };
2396
- var killProcessOnPort = (port) => {
2397
- try {
2398
- if (process.platform === "win32") {
2399
- execSync(
2400
- `for /f "tokens=5" %a in ('netstat -aon ^| findstr :${port} ^| findstr LISTENING') do taskkill /F /PID %a`,
2401
- { stdio: "ignore", timeout: 1e3, shell: "cmd.exe" }
2402
- );
2403
- } else {
2404
- execSync(`lsof -ti:${port} | xargs kill -9 2>/dev/null`, {
2405
- stdio: "ignore",
2406
- timeout: 1e3
2407
- });
2408
- }
2409
- } catch {
2397
+ var isPortInUse = (port) => new Promise((resolve) => {
2398
+ const server = net.createServer();
2399
+ server.once("error", () => resolve(true));
2400
+ server.once("listening", () => {
2401
+ server.close();
2402
+ resolve(false);
2403
+ });
2404
+ server.listen(port);
2405
+ });
2406
+ var startServer = async (port = DEFAULT_PORT) => {
2407
+ if (await isPortInUse(port)) {
2408
+ return;
2410
2409
  }
2411
- };
2412
- var startServer = (port = DEFAULT_PORT) => {
2413
- killProcessOnPort(port);
2414
2410
  const app = createServer();
2415
2411
  serve({ fetch: app.fetch, port });
2416
- console.log("React Grab Cursor server running on port", port);
2412
+ console.log(`[React Grab] Server started on port ${port}`);
2417
2413
  };
2414
+ if (import.meta.url === `file://${process.argv[1]}`) {
2415
+ startServer(DEFAULT_PORT).catch(console.error);
2416
+ }
2418
2417
 
2419
2418
  export { createServer, startServer };
package/package.json CHANGED
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "name": "@react-grab/cursor",
3
- "version": "0.0.59",
3
+ "version": "0.0.61",
4
4
  "type": "module",
5
+ "bin": {
6
+ "react-grab-cursor": "./dist/cli.js"
7
+ },
5
8
  "exports": {
6
9
  "./client": {
7
10
  "types": "./dist/client.d.ts",
@@ -12,8 +15,11 @@
12
15
  "types": "./dist/server.d.ts",
13
16
  "import": "./dist/server.js",
14
17
  "require": "./dist/server.cjs"
15
- }
18
+ },
19
+ "./dist/*": "./dist/*.js",
20
+ "./dist/*.js": "./dist/*.js"
16
21
  },
22
+ "browser": "dist/client.global.js",
17
23
  "files": [
18
24
  "dist"
19
25
  ],
@@ -23,10 +29,10 @@
23
29
  "dependencies": {
24
30
  "@hono/node-server": "^1.19.6",
25
31
  "hono": "^4.0.0",
26
- "react-grab": "0.0.59"
32
+ "react-grab": "0.0.61"
27
33
  },
28
34
  "scripts": {
29
35
  "dev": "tsup --watch",
30
- "build": "NODE_ENV=production tsup"
36
+ "build": "rm -rf dist && NODE_ENV=production tsup"
31
37
  }
32
38
  }