@pyrpc/client 0.1.0-alpha.3 → 0.3.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/README.md CHANGED
@@ -1,68 +1,68 @@
1
- # @pyrpc/client
2
-
3
- Universal TypeScript client for [pyRPC](https://pyrpc.dev). Type-safe RPC calls to your Python backend — install, import, call.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @pyrpc/client
9
- # or
10
- pnpm add @pyrpc/client
11
- # or
12
- bun add @pyrpc/client
13
- ```
14
-
15
- The postinstall script in `@pyrpc/types` will prompt for your server URL and generate typed contracts automatically.
16
-
17
- For CI, set the `PYRPC_URL` environment variable:
18
-
19
- ```bash
20
- PYRPC_URL=https://api.example.com npm install @pyrpc/client
21
- ```
22
-
23
- ## Usage
24
-
25
- ```typescript
26
- import { createClient } from "@pyrpc/client";
27
- import type { Types } from "@pyrpc/types";
28
-
29
- const client = createClient<Types>({
30
- baseUrl: "https://api.example.com",
31
- });
32
-
33
- const user = await client.get_user(1);
34
- console.log(user.name);
35
- ```
36
-
37
- The proxy-based API lets you call any remote procedure as a local method. Parameters are passed positionally or as a single object for named arguments.
38
-
39
- ### Error handling
40
-
41
- ```typescript
42
- import { createClient, PyRPCError } from "@pyrpc/client";
43
-
44
- try {
45
- await client.delete_user(1);
46
- } catch (error) {
47
- if (error instanceof PyRPCError) {
48
- console.error(error.code, error.message);
49
- }
50
- }
51
- ```
52
-
53
- ## API
54
-
55
- ### `createClient<TTypes>(options?)`
56
-
57
- Creates a proxy client that forwards method calls to the server.
58
-
59
- - `baseUrl` — Server root URL (defaults to `window.location.origin` in browsers)
60
- - `headers` — Static or async `HeadersInit`
61
-
62
- ## Keywords
63
-
64
- rpc, pyrpc, typescript, client, type-safe, api, remote-procedure-call
65
-
66
- ## License
67
-
68
- MIT
1
+ # @pyrpc/client
2
+
3
+ Universal TypeScript client for [pyRPC](https://pyrpc.dev). Type-safe RPC calls to your Python backend — install, import, call.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @pyrpc/client
9
+ # or
10
+ pnpm add @pyrpc/client
11
+ # or
12
+ bun add @pyrpc/client
13
+ ```
14
+
15
+ The postinstall script in `@pyrpc/types` will prompt for your server URL and generate typed contracts automatically.
16
+
17
+ For CI, set the `PYRPC_URL` environment variable:
18
+
19
+ ```bash
20
+ PYRPC_URL=https://api.example.com npm install @pyrpc/client
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```typescript
26
+ import { createClient } from "@pyrpc/client";
27
+ import type { Types } from "@pyrpc/types";
28
+
29
+ const client = createClient<Types>({
30
+ baseUrl: "https://api.example.com",
31
+ });
32
+
33
+ const user = await client.get_user(1);
34
+ console.log(user.name);
35
+ ```
36
+
37
+ The proxy-based API lets you call any remote procedure as a local method. Parameters are passed positionally or as a single object for named arguments.
38
+
39
+ ### Error handling
40
+
41
+ ```typescript
42
+ import { createClient, PyRPCError } from "@pyrpc/client";
43
+
44
+ try {
45
+ await client.delete_user(1);
46
+ } catch (error) {
47
+ if (error instanceof PyRPCError) {
48
+ console.error(error.code, error.message);
49
+ }
50
+ }
51
+ ```
52
+
53
+ ## API
54
+
55
+ ### `createClient<TTypes>(options?)`
56
+
57
+ Creates a proxy client that forwards method calls to the server.
58
+
59
+ - `baseUrl` — Server root URL (defaults to `window.location.origin` in browsers)
60
+ - `headers` — Static or async `HeadersInit`
61
+
62
+ ## Keywords
63
+
64
+ rpc, pyrpc, typescript, client, type-safe, api, remote-procedure-call
65
+
66
+ ## License
67
+
68
+ MIT
package/package.json CHANGED
@@ -1,35 +1,35 @@
1
- {
2
- "name": "@pyrpc/client",
3
- "version": "0.1.0-alpha.3",
4
- "description": "Universal TypeScript client for pyRPC",
5
- "main": "./dist/index.js",
6
- "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "files": [
9
- "dist"
10
- ],
11
- "scripts": {
12
- "build": "tsup src/index.ts --format cjs,esm --dts",
13
- "dev": "tsup src/index.ts --format cjs,esm --watch --dts",
14
- "lint": "eslint src/**/*.ts",
15
- "test": "vitest run"
16
- },
17
- "keywords": [
18
- "rpc",
19
- "pyrpc",
20
- "typescript",
21
- "client",
22
- "api"
23
- ],
24
- "author": "",
25
- "license": "MIT",
26
- "dependencies": {
27
- "@pyrpc/types": "^0.1.0-alpha.1"
28
- },
29
- "devDependencies": {
30
- "@types/node": "^20.19.39",
31
- "tsup": "^8.5.1",
32
- "typescript": "^5.9.3",
33
- "vitest": "^3.0.0"
34
- }
35
- }
1
+ {
2
+ "name": "@pyrpc/client",
3
+ "version": "0.3.0",
4
+ "description": "Universal TypeScript client for pyRPC",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsup src/index.ts --format cjs,esm --dts",
13
+ "dev": "tsup src/index.ts --format cjs,esm --watch --dts",
14
+ "lint": "eslint src/**/*.ts",
15
+ "test": "vitest run"
16
+ },
17
+ "keywords": [
18
+ "rpc",
19
+ "pyrpc",
20
+ "typescript",
21
+ "client",
22
+ "api"
23
+ ],
24
+ "author": "",
25
+ "license": "MIT",
26
+ "dependencies": {
27
+ "@pyrpc/types": "^0.1.0-alpha.1"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.19.39",
31
+ "tsup": "^8.5.1",
32
+ "typescript": "^5.9.3",
33
+ "vitest": "^3.0.0"
34
+ }
35
+ }
package/dist/index.d.mts DELETED
@@ -1,51 +0,0 @@
1
- interface RpcRequest {
2
- id: string;
3
- method: string;
4
- params: any[] | Record<string, any>;
5
- }
6
- interface RpcResponse<T = any> {
7
- id: string;
8
- result: T | null;
9
- error: {
10
- code: number;
11
- message: string;
12
- data?: any;
13
- } | null;
14
- }
15
- interface ClientOptions {
16
- /**
17
- * The base URL of the pyRPC server.
18
- * If omitted in a browser environment, it defaults to the current origin + '/rpc'.
19
- */
20
- baseUrl?: string;
21
- /**
22
- * Optional custom headers to send with each request.
23
- */
24
- headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
25
- }
26
-
27
- declare class PyRPCClient {
28
- private baseUrl;
29
- private options;
30
- constructor(options?: ClientOptions);
31
- /**
32
- * Internal method to perform the fetch request.
33
- */
34
- private request;
35
- /**
36
- * Creates a proxy that allows calling remote procedures as if they were local methods.
37
- */
38
- get rpc(): any;
39
- }
40
- /**
41
- * Modern factory API for pyRPC.
42
- */
43
- declare function createClient<TTypes = any>(options?: ClientOptions): PyRPCClient & TTypes;
44
-
45
- declare class PyRPCError extends Error {
46
- readonly code: number;
47
- readonly data?: any;
48
- constructor(code: number, message: string, data?: any);
49
- }
50
-
51
- export { type ClientOptions, PyRPCClient, PyRPCError, type RpcRequest, type RpcResponse, createClient };
package/dist/index.d.ts DELETED
@@ -1,51 +0,0 @@
1
- interface RpcRequest {
2
- id: string;
3
- method: string;
4
- params: any[] | Record<string, any>;
5
- }
6
- interface RpcResponse<T = any> {
7
- id: string;
8
- result: T | null;
9
- error: {
10
- code: number;
11
- message: string;
12
- data?: any;
13
- } | null;
14
- }
15
- interface ClientOptions {
16
- /**
17
- * The base URL of the pyRPC server.
18
- * If omitted in a browser environment, it defaults to the current origin + '/rpc'.
19
- */
20
- baseUrl?: string;
21
- /**
22
- * Optional custom headers to send with each request.
23
- */
24
- headers?: HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
25
- }
26
-
27
- declare class PyRPCClient {
28
- private baseUrl;
29
- private options;
30
- constructor(options?: ClientOptions);
31
- /**
32
- * Internal method to perform the fetch request.
33
- */
34
- private request;
35
- /**
36
- * Creates a proxy that allows calling remote procedures as if they were local methods.
37
- */
38
- get rpc(): any;
39
- }
40
- /**
41
- * Modern factory API for pyRPC.
42
- */
43
- declare function createClient<TTypes = any>(options?: ClientOptions): PyRPCClient & TTypes;
44
-
45
- declare class PyRPCError extends Error {
46
- readonly code: number;
47
- readonly data?: any;
48
- constructor(code: number, message: string, data?: any);
49
- }
50
-
51
- export { type ClientOptions, PyRPCClient, PyRPCError, type RpcRequest, type RpcResponse, createClient };
package/dist/index.js DELETED
@@ -1,127 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- PyRPCClient: () => PyRPCClient,
24
- PyRPCError: () => PyRPCError,
25
- createClient: () => createClient
26
- });
27
- module.exports = __toCommonJS(index_exports);
28
-
29
- // src/error.ts
30
- var PyRPCError = class _PyRPCError extends Error {
31
- code;
32
- data;
33
- constructor(code, message, data) {
34
- super(message);
35
- this.name = "PyRPCError";
36
- this.code = code;
37
- this.data = data;
38
- Object.setPrototypeOf(this, _PyRPCError.prototype);
39
- }
40
- };
41
-
42
- // src/client.ts
43
- var NO_BASE_URL_ERROR = `
44
- No baseUrl detected.
45
-
46
- pyRPC could not automatically determine your server location.
47
-
48
- If your frontend and backend are deployed separately, provide:
49
-
50
- createClient({
51
- baseUrl: "https://api.example.com"
52
- })
53
- `;
54
- var PyRPCClient = class {
55
- baseUrl;
56
- options;
57
- constructor(options = {}) {
58
- let baseUrl = options.baseUrl;
59
- if (!baseUrl) {
60
- if (typeof window !== "undefined" && window.location) {
61
- baseUrl = window.location.origin;
62
- } else {
63
- throw new Error(NO_BASE_URL_ERROR);
64
- }
65
- }
66
- this.baseUrl = baseUrl.replace(/\/$/, "");
67
- this.options = options;
68
- }
69
- /**
70
- * Internal method to perform the fetch request.
71
- */
72
- async request(method, params) {
73
- const id = Math.random().toString(36).substring(7);
74
- const body = { id, method, params };
75
- const baseHeaders = {
76
- "Content-Type": "application/json"
77
- };
78
- let userHeaders = {};
79
- if (this.options.headers) {
80
- userHeaders = typeof this.options.headers === "function" ? await this.options.headers() : this.options.headers;
81
- }
82
- const headers = { ...baseHeaders, ...Object.fromEntries(new Headers(userHeaders).entries()) };
83
- const response = await fetch(`${this.baseUrl}/rpc`, {
84
- method: "POST",
85
- headers,
86
- body: JSON.stringify(body)
87
- });
88
- if (!response.ok) {
89
- throw new Error(`HTTP error! status: ${response.status}`);
90
- }
91
- const data = await response.json();
92
- if (data.error) {
93
- throw new PyRPCError(data.error.code, data.error.message, data.error.data);
94
- }
95
- return data.result;
96
- }
97
- /**
98
- * Creates a proxy that allows calling remote procedures as if they were local methods.
99
- */
100
- get rpc() {
101
- return new Proxy({}, {
102
- get: (_, method) => {
103
- return (...args) => {
104
- const params = args.length === 1 && typeof args[0] === "object" && !Array.isArray(args[0]) ? args[0] : args;
105
- return this.request(method, params);
106
- };
107
- }
108
- });
109
- }
110
- };
111
- function createClient(options = {}) {
112
- const client = new PyRPCClient(options);
113
- return new Proxy(client, {
114
- get(target, prop, receiver) {
115
- if (prop in target) {
116
- return Reflect.get(target, prop, receiver);
117
- }
118
- return target.rpc[prop];
119
- }
120
- });
121
- }
122
- // Annotate the CommonJS export names for ESM import in node:
123
- 0 && (module.exports = {
124
- PyRPCClient,
125
- PyRPCError,
126
- createClient
127
- });
package/dist/index.mjs DELETED
@@ -1,98 +0,0 @@
1
- // src/error.ts
2
- var PyRPCError = class _PyRPCError extends Error {
3
- code;
4
- data;
5
- constructor(code, message, data) {
6
- super(message);
7
- this.name = "PyRPCError";
8
- this.code = code;
9
- this.data = data;
10
- Object.setPrototypeOf(this, _PyRPCError.prototype);
11
- }
12
- };
13
-
14
- // src/client.ts
15
- var NO_BASE_URL_ERROR = `
16
- No baseUrl detected.
17
-
18
- pyRPC could not automatically determine your server location.
19
-
20
- If your frontend and backend are deployed separately, provide:
21
-
22
- createClient({
23
- baseUrl: "https://api.example.com"
24
- })
25
- `;
26
- var PyRPCClient = class {
27
- baseUrl;
28
- options;
29
- constructor(options = {}) {
30
- let baseUrl = options.baseUrl;
31
- if (!baseUrl) {
32
- if (typeof window !== "undefined" && window.location) {
33
- baseUrl = window.location.origin;
34
- } else {
35
- throw new Error(NO_BASE_URL_ERROR);
36
- }
37
- }
38
- this.baseUrl = baseUrl.replace(/\/$/, "");
39
- this.options = options;
40
- }
41
- /**
42
- * Internal method to perform the fetch request.
43
- */
44
- async request(method, params) {
45
- const id = Math.random().toString(36).substring(7);
46
- const body = { id, method, params };
47
- const baseHeaders = {
48
- "Content-Type": "application/json"
49
- };
50
- let userHeaders = {};
51
- if (this.options.headers) {
52
- userHeaders = typeof this.options.headers === "function" ? await this.options.headers() : this.options.headers;
53
- }
54
- const headers = { ...baseHeaders, ...Object.fromEntries(new Headers(userHeaders).entries()) };
55
- const response = await fetch(`${this.baseUrl}/rpc`, {
56
- method: "POST",
57
- headers,
58
- body: JSON.stringify(body)
59
- });
60
- if (!response.ok) {
61
- throw new Error(`HTTP error! status: ${response.status}`);
62
- }
63
- const data = await response.json();
64
- if (data.error) {
65
- throw new PyRPCError(data.error.code, data.error.message, data.error.data);
66
- }
67
- return data.result;
68
- }
69
- /**
70
- * Creates a proxy that allows calling remote procedures as if they were local methods.
71
- */
72
- get rpc() {
73
- return new Proxy({}, {
74
- get: (_, method) => {
75
- return (...args) => {
76
- const params = args.length === 1 && typeof args[0] === "object" && !Array.isArray(args[0]) ? args[0] : args;
77
- return this.request(method, params);
78
- };
79
- }
80
- });
81
- }
82
- };
83
- function createClient(options = {}) {
84
- const client = new PyRPCClient(options);
85
- return new Proxy(client, {
86
- get(target, prop, receiver) {
87
- if (prop in target) {
88
- return Reflect.get(target, prop, receiver);
89
- }
90
- return target.rpc[prop];
91
- }
92
- });
93
- }
94
- export {
95
- PyRPCClient,
96
- PyRPCError,
97
- createClient
98
- };