ai-functions 0.4.0 → 2.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +9 -0
- package/dist/rpc/auth.d.ts +69 -0
- package/dist/rpc/auth.d.ts.map +1 -0
- package/dist/rpc/auth.js +136 -0
- package/dist/rpc/auth.js.map +1 -0
- package/dist/rpc/client.d.ts +62 -0
- package/dist/rpc/client.d.ts.map +1 -0
- package/dist/rpc/client.js +103 -0
- package/dist/rpc/client.js.map +1 -0
- package/dist/rpc/deferred.d.ts +60 -0
- package/dist/rpc/deferred.d.ts.map +1 -0
- package/dist/rpc/deferred.js +96 -0
- package/dist/rpc/deferred.js.map +1 -0
- package/dist/rpc/index.d.ts +22 -0
- package/dist/rpc/index.d.ts.map +1 -0
- package/dist/rpc/index.js +38 -0
- package/dist/rpc/index.js.map +1 -0
- package/dist/rpc/local.d.ts +42 -0
- package/dist/rpc/local.d.ts.map +1 -0
- package/dist/rpc/local.js +50 -0
- package/dist/rpc/local.js.map +1 -0
- package/dist/rpc/server.d.ts +165 -0
- package/dist/rpc/server.d.ts.map +1 -0
- package/dist/rpc/server.js +405 -0
- package/dist/rpc/server.js.map +1 -0
- package/dist/rpc/session.d.ts +32 -0
- package/dist/rpc/session.d.ts.map +1 -0
- package/dist/rpc/session.js +43 -0
- package/dist/rpc/session.js.map +1 -0
- package/dist/rpc/transport.d.ts +306 -0
- package/dist/rpc/transport.d.ts.map +1 -0
- package/dist/rpc/transport.js +731 -0
- package/dist/rpc/transport.js.map +1 -0
- package/package.json +1 -1
- package/.turbo/turbo-test.log +0 -105
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authenticated RPC client with oauth.do integration
|
|
3
|
+
*
|
|
4
|
+
* Provides unified auth for all primitives:
|
|
5
|
+
* - Default target: apis.do/rpc
|
|
6
|
+
* - Token from DO_TOKEN env or oauth.do CLI flow
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Default RPC endpoints
|
|
10
|
+
*/
|
|
11
|
+
export declare const DEFAULT_WS_URL = "wss://apis.do/rpc";
|
|
12
|
+
export declare const DEFAULT_HTTP_URL = "https://apis.do/rpc";
|
|
13
|
+
/**
|
|
14
|
+
* Options for creating an authenticated client
|
|
15
|
+
*/
|
|
16
|
+
export interface AuthenticatedClientOptions {
|
|
17
|
+
/** WebSocket URL (default: wss://apis.do/rpc) */
|
|
18
|
+
wsUrl?: string;
|
|
19
|
+
/** HTTP URL (default: https://apis.do/rpc) */
|
|
20
|
+
httpUrl?: string;
|
|
21
|
+
/** Bearer token (default: from DO_TOKEN env or oauth.do) */
|
|
22
|
+
token?: string;
|
|
23
|
+
/** Prefer WebSocket over HTTP */
|
|
24
|
+
preferWebSocket?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Global RPC configuration
|
|
28
|
+
*/
|
|
29
|
+
export interface RPCConfig {
|
|
30
|
+
/** Default WebSocket URL */
|
|
31
|
+
wsUrl?: string;
|
|
32
|
+
/** Default HTTP URL */
|
|
33
|
+
httpUrl?: string;
|
|
34
|
+
/** Bearer token */
|
|
35
|
+
token?: string;
|
|
36
|
+
/** Prefer WebSocket */
|
|
37
|
+
preferWebSocket?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Configure global RPC settings
|
|
41
|
+
*/
|
|
42
|
+
export declare function configureRPC(config: RPCConfig): void;
|
|
43
|
+
/**
|
|
44
|
+
* Create an authenticated RPC session
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* // Uses default apis.do/rpc with DO_TOKEN
|
|
49
|
+
* const api = await createAuthenticatedClient<MyAPI>()
|
|
50
|
+
*
|
|
51
|
+
* // Custom endpoint
|
|
52
|
+
* const api = await createAuthenticatedClient<MyAPI>({
|
|
53
|
+
* wsUrl: 'wss://custom.example.com/rpc',
|
|
54
|
+
* token: 'my-token'
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare function createAuthenticatedClient<T>(options?: AuthenticatedClientOptions): Promise<T>;
|
|
59
|
+
/**
|
|
60
|
+
* Get or create the default RPC client
|
|
61
|
+
*
|
|
62
|
+
* Uses apis.do/rpc with auth from DO_TOKEN or oauth.do
|
|
63
|
+
*/
|
|
64
|
+
export declare function getDefaultRPCClient<T>(): Promise<T>;
|
|
65
|
+
/**
|
|
66
|
+
* Clear the cached token and client (useful for logout)
|
|
67
|
+
*/
|
|
68
|
+
export declare function clearRPCAuth(): void;
|
|
69
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/rpc/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH;;GAEG;AACH,eAAO,MAAM,cAAc,sBAAsB,CAAA;AACjD,eAAO,MAAM,gBAAgB,wBAAwB,CAAA;AAErD;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uBAAuB;IACvB,eAAe,CAAC,EAAE,OAAO,CAAA;CAC1B;AAKD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAKpD;AA4DD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAcD;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAKzD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,IAAI,CAGnC"}
|
package/dist/rpc/auth.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authenticated RPC client with oauth.do integration
|
|
3
|
+
*
|
|
4
|
+
* Provides unified auth for all primitives:
|
|
5
|
+
* - Default target: apis.do/rpc
|
|
6
|
+
* - Token from DO_TOKEN env or oauth.do CLI flow
|
|
7
|
+
*/
|
|
8
|
+
// Use require-style imports to avoid TypeScript's deep type instantiation
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
10
|
+
const capnweb = require('capnweb');
|
|
11
|
+
/**
|
|
12
|
+
* Default RPC endpoints
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_WS_URL = 'wss://apis.do/rpc';
|
|
15
|
+
export const DEFAULT_HTTP_URL = 'https://apis.do/rpc';
|
|
16
|
+
let globalConfig = {};
|
|
17
|
+
let cachedToken = null;
|
|
18
|
+
/**
|
|
19
|
+
* Configure global RPC settings
|
|
20
|
+
*/
|
|
21
|
+
export function configureRPC(config) {
|
|
22
|
+
globalConfig = { ...globalConfig, ...config };
|
|
23
|
+
if (config.token) {
|
|
24
|
+
cachedToken = config.token;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get the auth token from various sources
|
|
29
|
+
*
|
|
30
|
+
* Priority:
|
|
31
|
+
* 1. Explicitly provided token
|
|
32
|
+
* 2. Cached token from previous auth
|
|
33
|
+
* 3. DO_TOKEN environment variable
|
|
34
|
+
* 4. oauth.do CLI flow (if available)
|
|
35
|
+
*/
|
|
36
|
+
async function getToken(explicitToken) {
|
|
37
|
+
// 1. Explicit token
|
|
38
|
+
if (explicitToken) {
|
|
39
|
+
return explicitToken;
|
|
40
|
+
}
|
|
41
|
+
// 2. Cached token
|
|
42
|
+
if (cachedToken) {
|
|
43
|
+
return cachedToken;
|
|
44
|
+
}
|
|
45
|
+
// 3. Environment variable
|
|
46
|
+
const envToken = typeof process !== 'undefined' ? process.env?.DO_TOKEN : undefined;
|
|
47
|
+
if (envToken) {
|
|
48
|
+
cachedToken = envToken;
|
|
49
|
+
return envToken;
|
|
50
|
+
}
|
|
51
|
+
// 4. Try oauth.do CLI flow
|
|
52
|
+
try {
|
|
53
|
+
const token = await getTokenFromOAuth();
|
|
54
|
+
if (token) {
|
|
55
|
+
cachedToken = token;
|
|
56
|
+
return token;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// oauth.do not available, continue without auth
|
|
61
|
+
}
|
|
62
|
+
throw new Error('No auth token available. Set DO_TOKEN environment variable or run `npx oauth.do login`');
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get token from oauth.do CLI secrets
|
|
66
|
+
*/
|
|
67
|
+
async function getTokenFromOAuth() {
|
|
68
|
+
// Dynamic import to avoid bundling oauth.do if not needed
|
|
69
|
+
try {
|
|
70
|
+
// @ts-expect-error oauth.do is an optional dependency
|
|
71
|
+
const oauth = await import('oauth.do');
|
|
72
|
+
const token = await oauth.getToken?.();
|
|
73
|
+
return token || null;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Create an authenticated RPC session
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* // Uses default apis.do/rpc with DO_TOKEN
|
|
85
|
+
* const api = await createAuthenticatedClient<MyAPI>()
|
|
86
|
+
*
|
|
87
|
+
* // Custom endpoint
|
|
88
|
+
* const api = await createAuthenticatedClient<MyAPI>({
|
|
89
|
+
* wsUrl: 'wss://custom.example.com/rpc',
|
|
90
|
+
* token: 'my-token'
|
|
91
|
+
* })
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export async function createAuthenticatedClient(options = {}) {
|
|
95
|
+
const { wsUrl = globalConfig.wsUrl || DEFAULT_WS_URL, httpUrl = globalConfig.httpUrl || DEFAULT_HTTP_URL, token, preferWebSocket = globalConfig.preferWebSocket ?? true } = options;
|
|
96
|
+
const authToken = await getToken(token || globalConfig.token);
|
|
97
|
+
// Create session with auth header
|
|
98
|
+
// Note: capnweb handles auth via the URL or we need to extend it
|
|
99
|
+
const authWsUrl = addAuthToUrl(wsUrl, authToken);
|
|
100
|
+
const authHttpUrl = addAuthToUrl(httpUrl, authToken);
|
|
101
|
+
if (preferWebSocket) {
|
|
102
|
+
// RpcStub<T> proxies all methods of T, so cast is safe at runtime
|
|
103
|
+
return capnweb.newWebSocketRpcSession(authWsUrl);
|
|
104
|
+
}
|
|
105
|
+
// RpcStub<T> proxies all methods of T, so cast is safe at runtime
|
|
106
|
+
return capnweb.newHttpBatchRpcSession(authHttpUrl);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Add auth token to URL (as query param for WebSocket, header handled separately for HTTP)
|
|
110
|
+
*/
|
|
111
|
+
function addAuthToUrl(url, token) {
|
|
112
|
+
const parsed = new URL(url);
|
|
113
|
+
parsed.searchParams.set('token', token);
|
|
114
|
+
return parsed.toString();
|
|
115
|
+
}
|
|
116
|
+
// Default client singleton
|
|
117
|
+
let defaultClient = null;
|
|
118
|
+
/**
|
|
119
|
+
* Get or create the default RPC client
|
|
120
|
+
*
|
|
121
|
+
* Uses apis.do/rpc with auth from DO_TOKEN or oauth.do
|
|
122
|
+
*/
|
|
123
|
+
export async function getDefaultRPCClient() {
|
|
124
|
+
if (!defaultClient) {
|
|
125
|
+
defaultClient = await createAuthenticatedClient();
|
|
126
|
+
}
|
|
127
|
+
return defaultClient;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Clear the cached token and client (useful for logout)
|
|
131
|
+
*/
|
|
132
|
+
export function clearRPCAuth() {
|
|
133
|
+
cachedToken = null;
|
|
134
|
+
defaultClient = null;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/rpc/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Client with promise pipelining support
|
|
3
|
+
*
|
|
4
|
+
* Batches multiple deferred operations into single round trips.
|
|
5
|
+
*/
|
|
6
|
+
import { type Deferred, type Operation, type DeferredContext } from './deferred.js';
|
|
7
|
+
/**
|
|
8
|
+
* RPC transport interface - implement this for different protocols
|
|
9
|
+
*/
|
|
10
|
+
export interface RPCTransport {
|
|
11
|
+
/**
|
|
12
|
+
* Execute a batch of calls and return results
|
|
13
|
+
*/
|
|
14
|
+
batch(calls: RPCCall[]): Promise<RPCResult[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Optional: execute a single call (defaults to batch of 1)
|
|
17
|
+
*/
|
|
18
|
+
call?(call: RPCCall): Promise<RPCResult>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A single RPC call
|
|
22
|
+
*/
|
|
23
|
+
export interface RPCCall {
|
|
24
|
+
id: string;
|
|
25
|
+
method: string;
|
|
26
|
+
params: unknown[];
|
|
27
|
+
chain?: Operation[];
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Result of an RPC call
|
|
31
|
+
*/
|
|
32
|
+
export interface RPCResult {
|
|
33
|
+
id: string;
|
|
34
|
+
result?: unknown;
|
|
35
|
+
error?: {
|
|
36
|
+
message: string;
|
|
37
|
+
code?: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Options for creating an RPC client
|
|
42
|
+
*/
|
|
43
|
+
export interface RPCClientOptions {
|
|
44
|
+
/** The transport to use for RPC calls */
|
|
45
|
+
transport: RPCTransport;
|
|
46
|
+
/** How long to wait before flushing pending calls (default: 0 - microtask) */
|
|
47
|
+
batchDelayMs?: number;
|
|
48
|
+
/** Maximum calls per batch (default: 100) */
|
|
49
|
+
maxBatchSize?: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Create an RPC client with automatic batching
|
|
53
|
+
*/
|
|
54
|
+
export declare function createRPCClient(options: RPCClientOptions): {
|
|
55
|
+
call: <T>(method: string, ...params: unknown[]) => Deferred<T>;
|
|
56
|
+
forceFlush: () => Promise<void>;
|
|
57
|
+
createContext: (method: string, params: unknown[]) => DeferredContext;
|
|
58
|
+
/** Number of pending calls */
|
|
59
|
+
readonly pendingCount: number;
|
|
60
|
+
};
|
|
61
|
+
export type RPCClient = ReturnType<typeof createRPCClient>;
|
|
62
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/rpc/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAA8B,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAE/G;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IAE7C;;OAEG;IACH,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,SAAS,EAAE,YAAY,CAAA;IACvB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAWD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB;WAiFzC,CAAC,UAAU,MAAM,aAAa,OAAO,EAAE,KAAG,QAAQ,CAAC,CAAC,CAAC;;4BARpC,MAAM,UAAU,OAAO,EAAE,KAAG,eAAe;IAsBxE,8BAA8B;;EAKjC;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAA"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC Client with promise pipelining support
|
|
3
|
+
*
|
|
4
|
+
* Batches multiple deferred operations into single round trips.
|
|
5
|
+
*/
|
|
6
|
+
import { createDeferred, applyChain } from './deferred.js';
|
|
7
|
+
/**
|
|
8
|
+
* Create an RPC client with automatic batching
|
|
9
|
+
*/
|
|
10
|
+
export function createRPCClient(options) {
|
|
11
|
+
const { transport, batchDelayMs = 0, maxBatchSize = 100 } = options;
|
|
12
|
+
let pendingCalls = [];
|
|
13
|
+
let flushScheduled = false;
|
|
14
|
+
let callId = 0;
|
|
15
|
+
const flush = async () => {
|
|
16
|
+
if (pendingCalls.length === 0)
|
|
17
|
+
return;
|
|
18
|
+
const batch = pendingCalls.splice(0, maxBatchSize);
|
|
19
|
+
flushScheduled = pendingCalls.length > 0;
|
|
20
|
+
if (flushScheduled) {
|
|
21
|
+
scheduleFlush();
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const results = await transport.batch(batch.map(p => p.call));
|
|
25
|
+
const resultMap = new Map(results.map(r => [r.id, r]));
|
|
26
|
+
for (const pending of batch) {
|
|
27
|
+
const result = resultMap.get(pending.call.id);
|
|
28
|
+
if (!result) {
|
|
29
|
+
pending.reject(new Error(`No result for call ${pending.call.id}`));
|
|
30
|
+
}
|
|
31
|
+
else if (result.error) {
|
|
32
|
+
pending.reject(new Error(result.error.message));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
pending.resolve(result.result);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
for (const pending of batch) {
|
|
41
|
+
pending.reject(error instanceof Error ? error : new Error(String(error)));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const scheduleFlush = () => {
|
|
46
|
+
if (flushScheduled)
|
|
47
|
+
return;
|
|
48
|
+
flushScheduled = true;
|
|
49
|
+
if (batchDelayMs === 0) {
|
|
50
|
+
queueMicrotask(() => {
|
|
51
|
+
flushScheduled = false;
|
|
52
|
+
flush();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
flushScheduled = false;
|
|
58
|
+
flush();
|
|
59
|
+
}, batchDelayMs);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Queue an RPC call and return a promise for the result
|
|
64
|
+
*/
|
|
65
|
+
const queueCall = (method, params, chain = []) => {
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
const id = `${++callId}`;
|
|
68
|
+
pendingCalls.push({
|
|
69
|
+
call: { id, method, params, chain },
|
|
70
|
+
resolve,
|
|
71
|
+
reject
|
|
72
|
+
});
|
|
73
|
+
scheduleFlush();
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Create a DeferredContext that uses this client
|
|
78
|
+
*/
|
|
79
|
+
const createContext = (method, params) => ({
|
|
80
|
+
resolve: (operations) => queueCall(method, params, operations)
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* Call a method and get a Deferred result
|
|
84
|
+
*/
|
|
85
|
+
const call = (method, ...params) => {
|
|
86
|
+
const context = createContext(method, params);
|
|
87
|
+
return createDeferred(context);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Force flush any pending calls
|
|
91
|
+
*/
|
|
92
|
+
const forceFlush = () => flush();
|
|
93
|
+
return {
|
|
94
|
+
call,
|
|
95
|
+
forceFlush,
|
|
96
|
+
createContext,
|
|
97
|
+
/** Number of pending calls */
|
|
98
|
+
get pendingCount() {
|
|
99
|
+
return pendingCalls.length;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/rpc/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deferred<T> - Cap'n Proto style promise pipelining for TypeScript
|
|
3
|
+
*
|
|
4
|
+
* Allows calling methods and accessing properties on promises before they resolve.
|
|
5
|
+
* All operations are batched and sent in a single round trip when awaited.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFERRED: unique symbol;
|
|
8
|
+
export declare const DEFERRED_CHAIN: unique symbol;
|
|
9
|
+
/**
|
|
10
|
+
* A chain of operations to apply to a value
|
|
11
|
+
*/
|
|
12
|
+
export type Operation = {
|
|
13
|
+
type: 'property';
|
|
14
|
+
key: string | symbol;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'call';
|
|
17
|
+
args: unknown[];
|
|
18
|
+
} | {
|
|
19
|
+
type: 'map';
|
|
20
|
+
fn: (value: unknown) => unknown;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Deferred<T> wraps a future value T, allowing property access and method calls
|
|
24
|
+
* to be pipelined before the value resolves.
|
|
25
|
+
*/
|
|
26
|
+
export type Deferred<T> = {
|
|
27
|
+
readonly [DEFERRED]: true;
|
|
28
|
+
readonly [DEFERRED_CHAIN]: Operation[];
|
|
29
|
+
} & {
|
|
30
|
+
[K in keyof T]: T[K] extends (...args: infer A) => infer R ? (...args: A) => Deferred<Awaited<R>> : Deferred<T[K]>;
|
|
31
|
+
} & {
|
|
32
|
+
map<U>(fn: (value: T) => U): Deferred<U>;
|
|
33
|
+
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
34
|
+
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<T | TResult>;
|
|
35
|
+
finally(onfinally?: (() => void) | null): Promise<T>;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Context for resolving deferred values
|
|
39
|
+
*/
|
|
40
|
+
export interface DeferredContext {
|
|
41
|
+
resolve<T>(operations: Operation[]): Promise<T>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a Deferred value that will be resolved by the given context
|
|
45
|
+
*/
|
|
46
|
+
export declare function createDeferred<T>(context: DeferredContext, chain?: Operation[]): Deferred<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Check if a value is a Deferred
|
|
49
|
+
*/
|
|
50
|
+
export declare function isDeferred<T>(value: unknown): value is Deferred<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Apply a chain of operations to a value
|
|
53
|
+
*/
|
|
54
|
+
export declare function applyChain(value: unknown, operations: Operation[]): unknown;
|
|
55
|
+
/**
|
|
56
|
+
* Create a simple local context that resolves immediately
|
|
57
|
+
* (useful for testing or in-memory implementations)
|
|
58
|
+
*/
|
|
59
|
+
export declare function createLocalContext<T>(getValue: () => T | Promise<T>): DeferredContext;
|
|
60
|
+
//# sourceMappingURL=deferred.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred.d.ts","sourceRoot":"","sources":["../../src/rpc/deferred.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,eAAO,MAAM,QAAQ,eAAqB,CAAA;AAC1C,eAAO,MAAM,cAAc,eAA0B,CAAA;AAErD;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,EAAE,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CAAE,CAAA;AAEpD;;;GAGG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;IACxB,QAAQ,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;IACzB,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,CAAA;CACvC,GAAG;KAED,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,GACtD,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GACpC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACnB,GAAG;IAEF,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAExC,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EACjC,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,EACrE,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAC1E,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,CAAA;IAC/B,KAAK,CAAC,OAAO,GAAG,KAAK,EACnB,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,GACxE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,CAAA;IACvB,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACrD,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAChD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,eAAe,EACxB,KAAK,GAAE,SAAS,EAAO,GACtB,QAAQ,CAAC,CAAC,CAAC,CA+Cb;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,CAElE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAyB3E;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,eAAe,CAOrF"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deferred<T> - Cap'n Proto style promise pipelining for TypeScript
|
|
3
|
+
*
|
|
4
|
+
* Allows calling methods and accessing properties on promises before they resolve.
|
|
5
|
+
* All operations are batched and sent in a single round trip when awaited.
|
|
6
|
+
*/
|
|
7
|
+
// Symbol to identify Deferred objects
|
|
8
|
+
export const DEFERRED = Symbol('Deferred');
|
|
9
|
+
export const DEFERRED_CHAIN = Symbol('DeferredChain');
|
|
10
|
+
/**
|
|
11
|
+
* Create a Deferred value that will be resolved by the given context
|
|
12
|
+
*/
|
|
13
|
+
export function createDeferred(context, chain = []) {
|
|
14
|
+
const resolve = () => context.resolve(chain);
|
|
15
|
+
const handler = {
|
|
16
|
+
get(_, prop) {
|
|
17
|
+
// Handle special symbols
|
|
18
|
+
if (prop === DEFERRED)
|
|
19
|
+
return true;
|
|
20
|
+
if (prop === DEFERRED_CHAIN)
|
|
21
|
+
return chain;
|
|
22
|
+
// Handle Promise interface
|
|
23
|
+
if (prop === 'then') {
|
|
24
|
+
return (onfulfilled, onrejected) => resolve().then(onfulfilled, onrejected);
|
|
25
|
+
}
|
|
26
|
+
if (prop === 'catch') {
|
|
27
|
+
return (onrejected) => resolve().catch(onrejected);
|
|
28
|
+
}
|
|
29
|
+
if (prop === 'finally') {
|
|
30
|
+
return (onfinally) => resolve().finally(onfinally);
|
|
31
|
+
}
|
|
32
|
+
// Handle map
|
|
33
|
+
if (prop === 'map') {
|
|
34
|
+
return (fn) => createDeferred(context, [...chain, { type: 'map', fn }]);
|
|
35
|
+
}
|
|
36
|
+
// Property access - add to chain
|
|
37
|
+
return createDeferred(context, [...chain, { type: 'property', key: prop }]);
|
|
38
|
+
},
|
|
39
|
+
apply(_, __, args) {
|
|
40
|
+
// Function call - add to chain
|
|
41
|
+
return createDeferred(context, [...chain, { type: 'call', args }]);
|
|
42
|
+
},
|
|
43
|
+
// Make it callable
|
|
44
|
+
has(_, prop) {
|
|
45
|
+
return prop === DEFERRED || prop === DEFERRED_CHAIN || prop === 'then' || prop === 'catch' || prop === 'finally' || prop === 'map';
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
// Create a function so it can be called
|
|
49
|
+
const target = function () { };
|
|
50
|
+
return new Proxy(target, handler);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if a value is a Deferred
|
|
54
|
+
*/
|
|
55
|
+
export function isDeferred(value) {
|
|
56
|
+
return typeof value === 'object' && value !== null && DEFERRED in value;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Apply a chain of operations to a value
|
|
60
|
+
*/
|
|
61
|
+
export function applyChain(value, operations) {
|
|
62
|
+
let result = value;
|
|
63
|
+
for (const op of operations) {
|
|
64
|
+
if (result === null || result === undefined) {
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
switch (op.type) {
|
|
68
|
+
case 'property':
|
|
69
|
+
result = result[op.key];
|
|
70
|
+
break;
|
|
71
|
+
case 'call':
|
|
72
|
+
if (typeof result !== 'function') {
|
|
73
|
+
throw new Error(`Cannot call non-function`);
|
|
74
|
+
}
|
|
75
|
+
result = result(...op.args);
|
|
76
|
+
break;
|
|
77
|
+
case 'map':
|
|
78
|
+
result = op.fn(result);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Create a simple local context that resolves immediately
|
|
86
|
+
* (useful for testing or in-memory implementations)
|
|
87
|
+
*/
|
|
88
|
+
export function createLocalContext(getValue) {
|
|
89
|
+
return {
|
|
90
|
+
async resolve(operations) {
|
|
91
|
+
const value = await getValue();
|
|
92
|
+
return applyChain(value, operations);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=deferred.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred.js","sourceRoot":"","sources":["../../src/rpc/deferred.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sCAAsC;AACtC,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;AAC1C,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,eAAe,CAAC,CAAA;AA2CrD;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAwB,EACxB,QAAqB,EAAE;IAEvB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAI,KAAK,CAAC,CAAA;IAE/C,MAAM,OAAO,GAAyB;QACpC,GAAG,CAAC,CAAC,EAAE,IAAI;YACT,yBAAyB;YACzB,IAAI,IAAI,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAClC,IAAI,IAAI,KAAK,cAAc;gBAAE,OAAO,KAAK,CAAA;YAEzC,2BAA2B;YAC3B,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO,CAAC,WAAmC,EAAE,UAAyC,EAAE,EAAE,CACxF,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAA;YAC3C,CAAC;YACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBACrB,OAAO,CAAC,UAAyC,EAAE,EAAE,CACnD,OAAO,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;YAC/B,CAAC;YACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,OAAO,CAAC,SAAsB,EAAE,EAAE,CAChC,OAAO,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAChC,CAAC;YAED,aAAa;YACb,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;gBACnB,OAAO,CAAC,EAA+B,EAAE,EAAE,CACzC,cAAc,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;YAC5D,CAAC;YAED,iCAAiC;YACjC,OAAO,cAAc,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QAC7E,CAAC;QAED,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI;YACf,+BAA+B;YAC/B,OAAO,cAAc,CAAC,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QACpE,CAAC;QAED,mBAAmB;QACnB,GAAG,CAAC,CAAC,EAAE,IAAI;YACT,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,cAAc,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,CAAA;QACpI,CAAC;KACF,CAAA;IAED,wCAAwC;IACxC,MAAM,MAAM,GAAG,cAAY,CAAsB,CAAA;IACjD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,CAAgB,CAAA;AAClD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAI,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,CAAA;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc,EAAE,UAAuB;IAChE,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC5C,OAAO,MAAM,CAAA;QACf,CAAC;QAED,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YAChB,KAAK,UAAU;gBACb,MAAM,GAAI,MAA2C,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;gBAC7D,MAAK;YACP,KAAK,MAAM;gBACT,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;oBACjC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;gBAC7C,CAAC;gBACD,MAAM,GAAI,MAA0C,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;gBAChE,MAAK;YACP,KAAK,KAAK;gBACR,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;gBACtB,MAAK;QACT,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAI,QAA8B;IAClE,OAAO;QACL,KAAK,CAAC,OAAO,CAAI,UAAuB;YACtC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAA;YAC9B,OAAO,UAAU,CAAC,KAAK,EAAE,UAAU,CAAM,CAAA;QAC3C,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC primitives with unified auth
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Promise pipelining (Cap'n Proto style)
|
|
6
|
+
* - Multiple transports: HTTP, WebSocket, postMessage
|
|
7
|
+
* - Bidirectional RPC callbacks
|
|
8
|
+
* - Async iterators for streaming
|
|
9
|
+
* - Unified authentication via oauth.do
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
export { newWebSocketRpcSession, newHttpBatchRpcSession, RpcTarget, type RpcStub, type RpcPromise } from 'capnweb';
|
|
14
|
+
export { newWorkersRpcResponse } from 'capnweb';
|
|
15
|
+
export { createDeferred, isDeferred, applyChain, createLocalContext, DEFERRED, DEFERRED_CHAIN, type Deferred, type Operation, type DeferredContext, } from './deferred.js';
|
|
16
|
+
export { createRPCClient, type RPCClient, type RPCTransport, type RPCCall, type RPCResult, type RPCClientOptions, } from './client.js';
|
|
17
|
+
export { type Transport, type StreamingTransport, type RPCMessage, type OperationDescriptor, type ConnectionState, type TransportEvents, HTTPTransport, createHTTPTransport, type HTTPTransportOptions, WebSocketTransport, createWebSocketTransport, type WebSocketTransportOptions, PostMessageTransport, createPostMessageTransport, type PostMessageTransportOptions, CallbackRegistry, generateMessageId, } from './transport.js';
|
|
18
|
+
export { createRPCSession, type RPCSessionOptions } from './session.js';
|
|
19
|
+
export { createLocalTarget, LocalTarget } from './local.js';
|
|
20
|
+
export { createAuthenticatedClient, getDefaultRPCClient, configureRPC, type AuthenticatedClientOptions, type RPCConfig } from './auth.js';
|
|
21
|
+
export { createHTTPHandler, createWSHandler, createBridgeHandler, createRPCMiddleware, mountRPC, type RPCMethod, type RPCMethods, type RPCHandlerOptions, } from './server.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,SAAS,EACT,KAAK,OAAO,EACZ,KAAK,UAAU,EAChB,MAAM,SAAS,CAAA;AAGhB,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAG/C,OAAO,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,cAAc,EACd,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,eAAe,EAEpB,aAAa,EACb,mBAAmB,EACnB,KAAK,oBAAoB,EAEzB,kBAAkB,EAClB,wBAAwB,EACxB,KAAK,yBAAyB,EAE9B,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,2BAA2B,EAEhC,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG3D,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,YAAY,EACZ,KAAK,0BAA0B,EAC/B,KAAK,SAAS,EACf,MAAM,WAAW,CAAA;AAGlB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,EACR,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,iBAAiB,GACvB,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RPC primitives with unified auth
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Promise pipelining (Cap'n Proto style)
|
|
6
|
+
* - Multiple transports: HTTP, WebSocket, postMessage
|
|
7
|
+
* - Bidirectional RPC callbacks
|
|
8
|
+
* - Async iterators for streaming
|
|
9
|
+
* - Unified authentication via oauth.do
|
|
10
|
+
*
|
|
11
|
+
* @packageDocumentation
|
|
12
|
+
*/
|
|
13
|
+
// Re-export core capnweb types - consumers import from here, not capnweb directly
|
|
14
|
+
export { newWebSocketRpcSession, newHttpBatchRpcSession, RpcTarget } from 'capnweb';
|
|
15
|
+
// For Cloudflare Workers server-side
|
|
16
|
+
export { newWorkersRpcResponse } from 'capnweb';
|
|
17
|
+
// Export deferred/promise pipelining
|
|
18
|
+
export { createDeferred, isDeferred, applyChain, createLocalContext, DEFERRED, DEFERRED_CHAIN, } from './deferred.js';
|
|
19
|
+
// Export RPC client
|
|
20
|
+
export { createRPCClient, } from './client.js';
|
|
21
|
+
// Export transports
|
|
22
|
+
export {
|
|
23
|
+
// HTTP
|
|
24
|
+
HTTPTransport, createHTTPTransport,
|
|
25
|
+
// WebSocket
|
|
26
|
+
WebSocketTransport, createWebSocketTransport,
|
|
27
|
+
// postMessage
|
|
28
|
+
PostMessageTransport, createPostMessageTransport,
|
|
29
|
+
// Utilities
|
|
30
|
+
CallbackRegistry, generateMessageId, } from './transport.js';
|
|
31
|
+
// Export our session utilities
|
|
32
|
+
export { createRPCSession } from './session.js';
|
|
33
|
+
export { createLocalTarget, LocalTarget } from './local.js';
|
|
34
|
+
// Export authenticated client
|
|
35
|
+
export { createAuthenticatedClient, getDefaultRPCClient, configureRPC } from './auth.js';
|
|
36
|
+
// Export server handlers (Hono)
|
|
37
|
+
export { createHTTPHandler, createWSHandler, createBridgeHandler, createRPCMiddleware, mountRPC, } from './server.js';
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpc/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,kFAAkF;AAClF,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,SAAS,EAGV,MAAM,SAAS,CAAA;AAEhB,qCAAqC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAE/C,qCAAqC;AACrC,OAAO,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,cAAc,GAIf,MAAM,eAAe,CAAA;AAEtB,oBAAoB;AACpB,OAAO,EACL,eAAe,GAMhB,MAAM,aAAa,CAAA;AAEpB,oBAAoB;AACpB,OAAO;AAQL,OAAO;AACP,aAAa,EACb,mBAAmB;AAEnB,YAAY;AACZ,kBAAkB,EAClB,wBAAwB;AAExB,cAAc;AACd,oBAAoB,EACpB,0BAA0B;AAE1B,YAAY;AACZ,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AAEvB,+BAA+B;AAC/B,OAAO,EAAE,gBAAgB,EAA0B,MAAM,cAAc,CAAA;AACvE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE3D,8BAA8B;AAC9B,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,YAAY,EAGb,MAAM,WAAW,CAAA;AAElB,gCAAgC;AAChC,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,QAAQ,GAIT,MAAM,aAAa,CAAA"}
|