@irpclib/irpc 1.0.0-beta.22 → 1.0.0-beta.24
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/dist/call.d.ts +7 -4
- package/dist/call.js +25 -7
- package/dist/context.d.ts +6 -16
- package/dist/context.js +12 -23
- package/dist/credential.d.ts +9 -0
- package/dist/credential.js +16 -0
- package/dist/enum.d.ts +20 -12
- package/dist/enum.js +21 -13
- package/dist/error.d.ts +6 -0
- package/dist/error.js +6 -0
- package/dist/file.d.ts +37 -0
- package/dist/file.js +86 -0
- package/dist/index.d.ts +12 -6
- package/dist/index.js +12 -6
- package/dist/module.d.ts +41 -9
- package/dist/module.js +183 -12
- package/dist/packet.d.ts +32 -0
- package/dist/packet.js +100 -0
- package/dist/reader.d.ts +17 -3
- package/dist/reader.js +23 -4
- package/dist/resolver.d.ts +1 -1
- package/dist/resolver.js +25 -2
- package/dist/router.d.ts +53 -0
- package/dist/router.js +81 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +15 -0
- package/dist/state.d.ts +18 -17
- package/dist/state.js +96 -23
- package/dist/store.d.ts +44 -0
- package/dist/store.js +76 -0
- package/dist/stream.d.ts +13 -2
- package/dist/stream.js +77 -17
- package/dist/transport.d.ts +18 -2
- package/dist/transport.js +46 -5
- package/dist/types.d.ts +103 -17
- package/package.json +9 -7
- package/readme.md +8 -3
- package/dist/uuid.d.ts +0 -21
- package/dist/uuid.js +0 -45
package/dist/stream.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
|
|
2
2
|
import { ERROR_CODE } from "./error.js";
|
|
3
|
+
import { getAbortController, getAbortSignal } from "./context.js";
|
|
3
4
|
import { RemoteState } from "./state.js";
|
|
5
|
+
import { IRPC_STORE } from "./store.js";
|
|
4
6
|
|
|
5
7
|
//#region src/stream.ts
|
|
6
8
|
/**
|
|
@@ -18,34 +20,56 @@ var IRPCStream = class {
|
|
|
18
20
|
value;
|
|
19
21
|
error;
|
|
20
22
|
status = IRPC_STATUS.IDLE;
|
|
23
|
+
closed = false;
|
|
24
|
+
createdAt = Date.now();
|
|
25
|
+
startedAt;
|
|
26
|
+
updatedAt;
|
|
27
|
+
controller;
|
|
21
28
|
/**
|
|
22
29
|
* Initializes a stream wrapping an asynchronous RPC execution.
|
|
23
30
|
*
|
|
24
31
|
* @param id - The unique identifier of the RPC request.
|
|
25
32
|
* @param name - The name of the specification processing the execution.
|
|
26
33
|
* @param initializer - An execution callback that yields an IRPCResponse.
|
|
34
|
+
* @param spec - The specification for the RPC execution.
|
|
35
|
+
* @param router - The router instance managing the stream.
|
|
27
36
|
*/
|
|
28
|
-
constructor(id, name, initializer) {
|
|
37
|
+
constructor(id, name, initializer, spec, router) {
|
|
29
38
|
this.id = id;
|
|
30
39
|
this.name = name;
|
|
31
40
|
this.initializer = initializer;
|
|
41
|
+
this.spec = spec;
|
|
42
|
+
this.router = router;
|
|
43
|
+
IRPC_STORE.queue(this);
|
|
32
44
|
}
|
|
33
45
|
/**
|
|
34
46
|
* Evaluates the underlying initializer and propagates standard transport packets
|
|
35
47
|
* to all bound pipe handlers based on the output lifecycle.
|
|
36
48
|
*/
|
|
37
49
|
async start() {
|
|
38
|
-
if (this.status !== IRPC_STATUS.IDLE) return;
|
|
50
|
+
if (this.status !== IRPC_STATUS.IDLE || this.closed) return;
|
|
51
|
+
this.startedAt = Date.now();
|
|
52
|
+
this.controller = getAbortController();
|
|
53
|
+
const abortSignal = getAbortSignal();
|
|
54
|
+
if (abortSignal?.aborted) {
|
|
55
|
+
this.finish();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
39
58
|
this.status = IRPC_STATUS.PENDING;
|
|
40
59
|
const { id, name } = this;
|
|
41
60
|
try {
|
|
42
|
-
const
|
|
61
|
+
const response = await this.initializer();
|
|
62
|
+
if (abortSignal?.aborted) {
|
|
63
|
+
this.finish();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { result } = response;
|
|
43
67
|
if (result instanceof RemoteState) {
|
|
44
68
|
this.value = result.data;
|
|
45
69
|
if (result.status === IRPC_STATUS.SUCCESS || result.status === IRPC_STATUS.ERROR) {
|
|
46
70
|
if (result.status === IRPC_STATUS.ERROR) {
|
|
47
71
|
this.error = {
|
|
48
|
-
code: ERROR_CODE.
|
|
72
|
+
code: ERROR_CODE.HANDLER_ERROR,
|
|
49
73
|
message: result.error.message
|
|
50
74
|
};
|
|
51
75
|
this.status = IRPC_STATUS.ERROR;
|
|
@@ -60,8 +84,8 @@ var IRPCStream = class {
|
|
|
60
84
|
createdAt: Date.now()
|
|
61
85
|
};
|
|
62
86
|
this.pipeHandlers.forEach((handler) => handler(packet));
|
|
63
|
-
this.errorHandlers.forEach((handler) => handler(this.error));
|
|
64
|
-
this.
|
|
87
|
+
if (this.error) this.errorHandlers.forEach((handler) => handler(this.error));
|
|
88
|
+
this.finish();
|
|
65
89
|
return;
|
|
66
90
|
}
|
|
67
91
|
this.pipeHandlers.forEach((handler) => {
|
|
@@ -81,13 +105,13 @@ var IRPCStream = class {
|
|
|
81
105
|
handler({
|
|
82
106
|
id,
|
|
83
107
|
name,
|
|
84
|
-
type: IRPC_PACKET_TYPE.EVENT,
|
|
85
|
-
status: state.status,
|
|
86
108
|
data: {
|
|
87
109
|
type,
|
|
88
110
|
keys,
|
|
89
111
|
value
|
|
90
112
|
},
|
|
113
|
+
type: IRPC_PACKET_TYPE.EVENT,
|
|
114
|
+
status: state.status,
|
|
91
115
|
createdAt: Date.now()
|
|
92
116
|
});
|
|
93
117
|
});
|
|
@@ -111,27 +135,42 @@ var IRPCStream = class {
|
|
|
111
135
|
createdAt: Date.now()
|
|
112
136
|
});
|
|
113
137
|
});
|
|
114
|
-
|
|
138
|
+
abortSignal?.removeEventListener("abort", abortStream);
|
|
139
|
+
this.finish();
|
|
115
140
|
unsubscribe();
|
|
116
141
|
}
|
|
117
142
|
});
|
|
143
|
+
const abortStream = () => {
|
|
144
|
+
unsubscribe();
|
|
145
|
+
this.finish();
|
|
146
|
+
};
|
|
147
|
+
abortSignal?.addEventListener("abort", abortStream, { once: true });
|
|
118
148
|
} else {
|
|
119
149
|
this.value = result;
|
|
120
|
-
|
|
150
|
+
if (response.error) {
|
|
151
|
+
this.error = response.error;
|
|
152
|
+
this.status = IRPC_STATUS.ERROR;
|
|
153
|
+
this.errorHandlers.forEach((handler) => handler(this.error));
|
|
154
|
+
} else this.status = IRPC_STATUS.SUCCESS;
|
|
121
155
|
const packet = {
|
|
122
156
|
id,
|
|
123
157
|
name,
|
|
124
158
|
type: IRPC_PACKET_TYPE.ANSWER,
|
|
125
|
-
status: IRPC_STATUS.SUCCESS,
|
|
126
159
|
data: this.value,
|
|
160
|
+
error: this.error,
|
|
161
|
+
status: this.status,
|
|
127
162
|
createdAt: Date.now()
|
|
128
163
|
};
|
|
129
164
|
this.pipeHandlers.forEach((handler) => handler(packet));
|
|
130
|
-
this.
|
|
165
|
+
this.finish();
|
|
131
166
|
}
|
|
132
167
|
} catch (error) {
|
|
168
|
+
IRPC_STORE.error(error, [{
|
|
169
|
+
id: this.id,
|
|
170
|
+
name: this.name
|
|
171
|
+
}]);
|
|
133
172
|
this.error = {
|
|
134
|
-
code: ERROR_CODE.
|
|
173
|
+
code: ERROR_CODE.RESOLVE_ERROR,
|
|
135
174
|
message: error.message
|
|
136
175
|
};
|
|
137
176
|
this.status = IRPC_STATUS.ERROR;
|
|
@@ -146,7 +185,7 @@ var IRPCStream = class {
|
|
|
146
185
|
});
|
|
147
186
|
});
|
|
148
187
|
this.errorHandlers.forEach((handler) => handler(this.error));
|
|
149
|
-
this.
|
|
188
|
+
this.finish();
|
|
150
189
|
return;
|
|
151
190
|
}
|
|
152
191
|
}
|
|
@@ -169,8 +208,12 @@ var IRPCStream = class {
|
|
|
169
208
|
});
|
|
170
209
|
return;
|
|
171
210
|
}
|
|
211
|
+
if (this.closed) return;
|
|
172
212
|
this.pipeHandlers.add(handler);
|
|
173
|
-
this.start().catch(() => {
|
|
213
|
+
this.start().catch((err) => IRPC_STORE.error(err, [{
|
|
214
|
+
id: this.id,
|
|
215
|
+
name: this.name
|
|
216
|
+
}]));
|
|
174
217
|
}
|
|
175
218
|
/**
|
|
176
219
|
* Binds a handler to trap any internal runtime failures independently.
|
|
@@ -182,8 +225,12 @@ var IRPCStream = class {
|
|
|
182
225
|
handler(this.error);
|
|
183
226
|
return;
|
|
184
227
|
}
|
|
228
|
+
if (this.closed) return;
|
|
185
229
|
this.errorHandlers.add(handler);
|
|
186
|
-
this.start().catch(() => {
|
|
230
|
+
this.start().catch((err) => IRPC_STORE.error(err, [{
|
|
231
|
+
id: this.id,
|
|
232
|
+
name: this.name
|
|
233
|
+
}]));
|
|
187
234
|
}
|
|
188
235
|
/**
|
|
189
236
|
* Binds a handler triggered upon terminal completion of the stream process (success or error).
|
|
@@ -195,8 +242,21 @@ var IRPCStream = class {
|
|
|
195
242
|
handler();
|
|
196
243
|
return;
|
|
197
244
|
}
|
|
245
|
+
if (this.closed) return;
|
|
198
246
|
this.closeHandlers.add(handler);
|
|
199
|
-
this.start().catch(() => {
|
|
247
|
+
this.start().catch((err) => IRPC_STORE.error(err, [{
|
|
248
|
+
id: this.id,
|
|
249
|
+
name: this.name
|
|
250
|
+
}]));
|
|
251
|
+
}
|
|
252
|
+
finish() {
|
|
253
|
+
this.closed = true;
|
|
254
|
+
this.closeHandlers.forEach((handler) => handler());
|
|
255
|
+
this.pipeHandlers.clear();
|
|
256
|
+
this.errorHandlers.clear();
|
|
257
|
+
this.closeHandlers.clear();
|
|
258
|
+
this.updatedAt = Date.now();
|
|
259
|
+
IRPC_STORE.dequeue(this);
|
|
200
260
|
}
|
|
201
261
|
};
|
|
202
262
|
|
package/dist/transport.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IRPCPackage } from "./module.js";
|
|
2
|
+
import { IRPCCallConfig, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCInputs, IRPCOutput, IRPCSpec, TransportConfig } from "./types.js";
|
|
2
3
|
import { IRPCReader } from "./reader.js";
|
|
3
4
|
import { IRPCCall } from "./call.js";
|
|
4
5
|
|
|
@@ -9,11 +10,14 @@ import { IRPCCall } from "./call.js";
|
|
|
9
10
|
* It handles queuing, debouncing, and timeout management for RPC requests.
|
|
10
11
|
*/
|
|
11
12
|
declare class IRPCTransport {
|
|
13
|
+
#private;
|
|
12
14
|
config?: TransportConfig | undefined;
|
|
15
|
+
modules: Set<IRPCPackage>;
|
|
13
16
|
/**
|
|
14
17
|
* A set of pending RPC calls that are queued for execution.
|
|
15
18
|
*/
|
|
16
19
|
queue: Set<IRPCCall>;
|
|
20
|
+
get credentials(): IRPCCredentials;
|
|
17
21
|
/**
|
|
18
22
|
* Creates a new IRPCTransport instance.
|
|
19
23
|
* @param config - Optional transport configuration including timeout and debounce settings.
|
|
@@ -21,18 +25,30 @@ declare class IRPCTransport {
|
|
|
21
25
|
constructor(config?: TransportConfig | undefined);
|
|
22
26
|
/**
|
|
23
27
|
* Initiates an RPC call with the given specification and arguments.
|
|
28
|
+
* @param reader - The reader instance to attach to the RPC call.
|
|
24
29
|
* @param spec - The RPC specification defining the method to call.
|
|
25
30
|
* @param args - An array of arguments to pass to the RPC method.
|
|
26
31
|
* @param config - Optional call configuration, including timeout, retry settings, and more.
|
|
27
32
|
* @returns A promise that resolves with the RPC response data or rejects with an error.
|
|
28
33
|
*/
|
|
29
|
-
call(spec: IRPCSpec<IRPCInputs, IRPCOutput>, args: IRPCData[], config?: IRPCCallConfig): IRPCReader<IRPCData>;
|
|
34
|
+
call(spec: IRPCSpec<IRPCInputs, IRPCOutput>, args: IRPCData[], config?: IRPCCallConfig, reader?: IRPCReader<IRPCData>): IRPCReader<IRPCData>;
|
|
30
35
|
/**
|
|
31
36
|
* Schedules an RPC call for execution, implementing debouncing logic.
|
|
32
37
|
* Queued calls will be dispatched after the configured debounce delay.
|
|
33
38
|
* @param call - The RPC call to schedule.
|
|
34
39
|
*/
|
|
35
40
|
schedule(call: IRPCCall): void;
|
|
41
|
+
/**
|
|
42
|
+
* Signs an RPC call with credentials.
|
|
43
|
+
* @param cred - The credentials to sign the call with.
|
|
44
|
+
*/
|
|
45
|
+
sign(cred: IRPCCredentialsFactory): void;
|
|
46
|
+
/**
|
|
47
|
+
* Closes an RPC call. This base implementation does nothing.
|
|
48
|
+
* Subclasses should override this method to provide closing logic.
|
|
49
|
+
* @param call - The RPC call to cancel.
|
|
50
|
+
*/
|
|
51
|
+
close(call: IRPCCall): void;
|
|
36
52
|
/**
|
|
37
53
|
* Dispatches a batch of RPC calls. This base implementation rejects all calls
|
|
38
54
|
* with a "not implemented" error. Subclasses should override this method to
|
package/dist/transport.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
|
|
2
2
|
import { ERROR_CODE, ERROR_MESSAGE } from "./error.js";
|
|
3
|
+
import { IRPCReader } from "./reader.js";
|
|
4
|
+
import { IRPC_STORE } from "./store.js";
|
|
3
5
|
import { IRPCCall } from "./call.js";
|
|
6
|
+
import { onCleanup, uuid } from "@anchorlib/core";
|
|
4
7
|
|
|
5
8
|
//#region src/transport.ts
|
|
6
9
|
/**
|
|
@@ -8,10 +11,20 @@ import { IRPCCall } from "./call.js";
|
|
|
8
11
|
* It handles queuing, debouncing, and timeout management for RPC requests.
|
|
9
12
|
*/
|
|
10
13
|
var IRPCTransport = class {
|
|
14
|
+
#credentialFactory;
|
|
15
|
+
modules = /* @__PURE__ */ new Set();
|
|
11
16
|
/**
|
|
12
17
|
* A set of pending RPC calls that are queued for execution.
|
|
13
18
|
*/
|
|
14
19
|
queue = /* @__PURE__ */ new Set();
|
|
20
|
+
get credentials() {
|
|
21
|
+
if (typeof this.#credentialFactory === "function") {
|
|
22
|
+
const cred = this.#credentialFactory();
|
|
23
|
+
if (cred === null || Array.isArray(cred) || typeof cred !== "object") return [];
|
|
24
|
+
return Object.entries(cred);
|
|
25
|
+
}
|
|
26
|
+
return Object.entries(this.#credentialFactory ?? {});
|
|
27
|
+
}
|
|
15
28
|
/**
|
|
16
29
|
* Creates a new IRPCTransport instance.
|
|
17
30
|
* @param config - Optional transport configuration including timeout and debounce settings.
|
|
@@ -21,12 +34,13 @@ var IRPCTransport = class {
|
|
|
21
34
|
}
|
|
22
35
|
/**
|
|
23
36
|
* Initiates an RPC call with the given specification and arguments.
|
|
37
|
+
* @param reader - The reader instance to attach to the RPC call.
|
|
24
38
|
* @param spec - The RPC specification defining the method to call.
|
|
25
39
|
* @param args - An array of arguments to pass to the RPC method.
|
|
26
40
|
* @param config - Optional call configuration, including timeout, retry settings, and more.
|
|
27
41
|
* @returns A promise that resolves with the RPC response data or rejects with an error.
|
|
28
42
|
*/
|
|
29
|
-
call(spec, args, config) {
|
|
43
|
+
call(spec, args, config, reader = new IRPCReader(uuid())) {
|
|
30
44
|
const payload = {
|
|
31
45
|
name: spec.name,
|
|
32
46
|
args
|
|
@@ -40,8 +54,15 @@ var IRPCTransport = class {
|
|
|
40
54
|
maxRetries,
|
|
41
55
|
retryMode,
|
|
42
56
|
retryDelay
|
|
43
|
-
});
|
|
44
|
-
|
|
57
|
+
}, reader);
|
|
58
|
+
if (spec.stream) {
|
|
59
|
+
this.dispatch([call]).finally(() => {}).catch((err) => IRPC_STORE.error(err, [{
|
|
60
|
+
id: call.id,
|
|
61
|
+
name: call.payload.name
|
|
62
|
+
}]));
|
|
63
|
+
return call.reader;
|
|
64
|
+
} else this.schedule(call);
|
|
65
|
+
onCleanup(() => this.close(call));
|
|
45
66
|
return call.reader;
|
|
46
67
|
}
|
|
47
68
|
/**
|
|
@@ -52,12 +73,16 @@ var IRPCTransport = class {
|
|
|
52
73
|
schedule(call) {
|
|
53
74
|
const { debounce } = this.config ?? {};
|
|
54
75
|
if (debounce === false) {
|
|
55
|
-
this.dispatch([call]).finally(() => {}).catch(() => {
|
|
76
|
+
this.dispatch([call]).finally(() => {}).catch((err) => IRPC_STORE.error(err, [{
|
|
77
|
+
id: call.id,
|
|
78
|
+
name: call.payload.name
|
|
79
|
+
}]));
|
|
56
80
|
return;
|
|
57
81
|
}
|
|
58
82
|
const timeout = typeof debounce === "number" && !Number.isNaN(debounce) ? debounce : 0;
|
|
59
83
|
const dispatch = () => {
|
|
60
|
-
|
|
84
|
+
const pending = Array.from(this.queue);
|
|
85
|
+
this.dispatch(pending);
|
|
61
86
|
this.queue.clear();
|
|
62
87
|
};
|
|
63
88
|
if (!this.queue.size) if (timeout === 0) queueMicrotask(dispatch);
|
|
@@ -65,6 +90,22 @@ var IRPCTransport = class {
|
|
|
65
90
|
this.queue.add(call);
|
|
66
91
|
}
|
|
67
92
|
/**
|
|
93
|
+
* Signs an RPC call with credentials.
|
|
94
|
+
* @param cred - The credentials to sign the call with.
|
|
95
|
+
*/
|
|
96
|
+
sign(cred) {
|
|
97
|
+
if (cred === null || Array.isArray(cred) || typeof cred !== "object" && typeof cred !== "function") return;
|
|
98
|
+
this.#credentialFactory = cred;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Closes an RPC call. This base implementation does nothing.
|
|
102
|
+
* Subclasses should override this method to provide closing logic.
|
|
103
|
+
* @param call - The RPC call to cancel.
|
|
104
|
+
*/
|
|
105
|
+
close(call) {
|
|
106
|
+
console.log("[irpc] Closing call", call);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
68
109
|
* Dispatches a batch of RPC calls. This base implementation rejects all calls
|
|
69
110
|
* with a "not implemented" error. Subclasses should override this method to
|
|
70
111
|
* provide actual transport mechanism.
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
|
|
2
2
|
import { ErrorCode } from "./error.js";
|
|
3
|
+
import { IRPCFile } from "./file.js";
|
|
4
|
+
import { IRPCFilePointer } from "./packet.js";
|
|
3
5
|
import { IRPCTransport } from "./transport.js";
|
|
4
6
|
import { RemoteState } from "./state.js";
|
|
5
|
-
import {
|
|
7
|
+
import { IRPCReader } from "./reader.js";
|
|
8
|
+
import { AsyncValue, StateChange } from "@anchorlib/core";
|
|
6
9
|
import { ZodArray, ZodBoolean, ZodNull, ZodNumber, ZodObject, ZodSafeParseResult, ZodString, ZodUndefined } from "zod/v4";
|
|
7
10
|
|
|
8
11
|
//#region src/types.d.ts
|
|
@@ -20,7 +23,7 @@ type IRPCSpecStore = Map<string, IRPCSpec<IRPCInputs, IRPCOutput>>;
|
|
|
20
23
|
type IRPCStatus = (typeof IRPC_STATUS)[keyof typeof IRPC_STATUS];
|
|
21
24
|
type IRPCDataType = (typeof IRPC_DATA_TYPE)[keyof typeof IRPC_DATA_TYPE];
|
|
22
25
|
type IRPCPacketType = (typeof IRPC_PACKET_TYPE)[keyof typeof IRPC_PACKET_TYPE];
|
|
23
|
-
type
|
|
26
|
+
type IRPCBaseContext = (typeof IRPC_BASE_CONTEXT)[keyof typeof IRPC_BASE_CONTEXT];
|
|
24
27
|
type IRPCPacketBase = {
|
|
25
28
|
id: string;
|
|
26
29
|
name: string;
|
|
@@ -29,10 +32,6 @@ type IRPCPacketBase = {
|
|
|
29
32
|
createdAt?: number;
|
|
30
33
|
arrivedAt?: number;
|
|
31
34
|
};
|
|
32
|
-
type IRPCPacketData = {
|
|
33
|
-
type: IRPCDataType;
|
|
34
|
-
value: IRPCData;
|
|
35
|
-
};
|
|
36
35
|
type IRPCPacketCall = IRPCPacketBase & {
|
|
37
36
|
args: IRPCData[];
|
|
38
37
|
};
|
|
@@ -52,6 +51,56 @@ interface IRPCReadable<T> {
|
|
|
52
51
|
error: Error | undefined;
|
|
53
52
|
status: IRPCStatus;
|
|
54
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Represents a client-side stub for a remote function.
|
|
56
|
+
* When called, it returns an IRPCReader to handle the asynchronous result or stream.
|
|
57
|
+
*
|
|
58
|
+
* @template T - The original function type.
|
|
59
|
+
* @template A - The argument types of the function.
|
|
60
|
+
* @template R - The return data type.
|
|
61
|
+
*/
|
|
62
|
+
interface IRPCStub<T, A$1 extends unknown[], R$1 extends IRPCData> {
|
|
63
|
+
(...args: A$1): IRPCReader<R$1>;
|
|
64
|
+
stub: T;
|
|
65
|
+
/**
|
|
66
|
+
* Creates a call that expect to run in browser environment.
|
|
67
|
+
* The function runs immediately on the browser and will not re-run.
|
|
68
|
+
*
|
|
69
|
+
* @param args - A factory function returning the argument array.
|
|
70
|
+
* @returns An IRPCReader instance for handling the asynchronous result or stream.
|
|
71
|
+
*/
|
|
72
|
+
once(...args: A$1): IRPCReader<R$1>;
|
|
73
|
+
/**
|
|
74
|
+
* Creates a reactive call that expect to run in browser environment.
|
|
75
|
+
* The function runs immediately on the browser and will re-run when
|
|
76
|
+
* the reactive dependencies change.
|
|
77
|
+
*
|
|
78
|
+
* @param args - A factory function returning the argument array.
|
|
79
|
+
* @param debounce - The debounce time in milliseconds.
|
|
80
|
+
* @returns An IRPCReader instance for handling the asynchronous result or stream.
|
|
81
|
+
*/
|
|
82
|
+
with(args: () => A$1, debounce?: number): IRPCReader<R$1>;
|
|
83
|
+
/**
|
|
84
|
+
* Creates a reactive call that expect to run in browser environment.
|
|
85
|
+
* The function only runs on the first dependency change and re-run
|
|
86
|
+
* when the reactive dependencies change.
|
|
87
|
+
*
|
|
88
|
+
* @param args - A factory function returning the argument array.
|
|
89
|
+
* @param debounce - The debounce time in milliseconds.
|
|
90
|
+
* @returns An IRPCReader instance for handling the asynchronous result or stream.
|
|
91
|
+
*/
|
|
92
|
+
when(args: () => A$1, debounce?: number): IRPCReader<R$1>;
|
|
93
|
+
later(debounce?: number): IRPCReader<R$1> & {
|
|
94
|
+
dispatch: (...args: A$1) => void;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A utility type that transforms a standard function type into its corresponding IRPCStub.
|
|
99
|
+
* It automatically unwraps RemoteState types to determine the underlying data type.
|
|
100
|
+
*
|
|
101
|
+
* @template T - The function type to be transformed.
|
|
102
|
+
*/
|
|
103
|
+
type IRPCFunction<T> = T extends ((...args: infer A) => infer R) ? R extends RemoteState<infer S> ? S extends IRPCData ? IRPCStub<T, A, S> : IRPCStub<T, A, IRPCData> : R extends Promise<infer O> ? O extends IRPCData ? IRPCStub<T, A, O> : IRPCStub<T, A, IRPCData> : R extends IRPCData ? IRPCStub<T, A, R> : IRPCStub<T, A, IRPCData> : IRPCStub<T, [], IRPCData>;
|
|
55
104
|
/**
|
|
56
105
|
* Represents primitive data types that can be used in IRPC communications.
|
|
57
106
|
* Includes string, number, boolean, null, and undefined.
|
|
@@ -68,7 +117,7 @@ type IRPCObject = {
|
|
|
68
117
|
* Represents all possible data types in IRPC, including primitives, objects, and arrays.
|
|
69
118
|
* This is a recursive type that allows nested structures.
|
|
70
119
|
*/
|
|
71
|
-
type IRPCData = IRPCPrimitive | IRPCObject | IRPCData[];
|
|
120
|
+
type IRPCData = IRPCPrimitive | IRPCObject | IRPCFile | IRPCData[];
|
|
72
121
|
/**
|
|
73
122
|
* Union type of all primitive Zod schema types used for validation.
|
|
74
123
|
*/
|
|
@@ -123,11 +172,11 @@ type IRPCPayload = {
|
|
|
123
172
|
/**
|
|
124
173
|
* Defines the schema for input and output validation of an RPC function.
|
|
125
174
|
*/
|
|
126
|
-
type IRPCSchema<I extends IRPCInputs, O extends IRPCOutput> = {
|
|
175
|
+
type IRPCSchema<I extends IRPCInputs, O$1 extends IRPCOutput> = {
|
|
127
176
|
/** Optional input validation schemas */
|
|
128
177
|
input?: I;
|
|
129
178
|
/** Optional output validation schema */
|
|
130
|
-
output?: O;
|
|
179
|
+
output?: O$1;
|
|
131
180
|
};
|
|
132
181
|
/**
|
|
133
182
|
* Type definition for an RPC handler function.
|
|
@@ -141,13 +190,13 @@ type IRPCHandler = Function;
|
|
|
141
190
|
* @template I - Tuple of input validation schemas
|
|
142
191
|
* @template O - Output validation schema
|
|
143
192
|
*/
|
|
144
|
-
type IRPCInit<I extends IRPCInputs, O extends IRPCOutput> = {
|
|
193
|
+
type IRPCInit<R$1, I extends IRPCInputs, O$1 extends IRPCOutput> = {
|
|
145
194
|
/** The name of the RPC function */
|
|
146
195
|
name: string;
|
|
147
196
|
/** Optional description of the RPC function */
|
|
148
197
|
description?: string;
|
|
149
198
|
/** Optional schema for input/output validation */
|
|
150
|
-
schema?: IRPCSchema<I, O>;
|
|
199
|
+
schema?: IRPCSchema<I, O$1>;
|
|
151
200
|
/** Optional maximum age of a call in milliseconds */
|
|
152
201
|
maxAge?: number;
|
|
153
202
|
/**
|
|
@@ -157,7 +206,20 @@ type IRPCInit<I extends IRPCInputs, O extends IRPCOutput> = {
|
|
|
157
206
|
* This can help reduce the number of actual function executions.
|
|
158
207
|
*/
|
|
159
208
|
coalesce?: boolean;
|
|
209
|
+
/** Optional initialization function to seed the data */
|
|
210
|
+
init?: () => R$1;
|
|
160
211
|
} & IRPCCallConfig;
|
|
212
|
+
/**
|
|
213
|
+
* Configuration options for initializing an RPC stream function.
|
|
214
|
+
* Contains metadata and constraints for the RPC stream function.
|
|
215
|
+
*
|
|
216
|
+
* @template I - Tuple of input validation schemas
|
|
217
|
+
* @template O - Output validation schema
|
|
218
|
+
*/
|
|
219
|
+
type IRPCStreamInit<I extends IRPCInputs, O$1 extends IRPCOutput, R$1> = IRPCInit<R$1, I, O$1> & {
|
|
220
|
+
stream: true;
|
|
221
|
+
ttl?: number;
|
|
222
|
+
};
|
|
161
223
|
/**
|
|
162
224
|
* Type definition for an RPC declaration.
|
|
163
225
|
* Represents an RPC function with its name, description, and configuration.
|
|
@@ -166,9 +228,7 @@ type IRPCInit<I extends IRPCInputs, O extends IRPCOutput> = {
|
|
|
166
228
|
* @template I - Tuple of input validation schemas
|
|
167
229
|
* @template O - Output validation schema
|
|
168
230
|
*/
|
|
169
|
-
type IRPCDeclareInit<F, I extends IRPCInputs, O extends IRPCOutput> = F extends ((...args:
|
|
170
|
-
init: () => R;
|
|
171
|
-
} : IRPCInit<I, O>;
|
|
231
|
+
type IRPCDeclareInit<F, I extends IRPCInputs, O$1 extends IRPCOutput> = F extends ((...args: IRPCData[]) => infer R) ? R extends RemoteState<infer S> ? S extends IRPCData ? IRPCStreamInit<I, O$1, S> : IRPCInit<IRPCData, IRPCInputs, IRPCOutput> : R extends Promise<infer D> ? D extends IRPCData ? IRPCInit<D, I, O$1> : IRPCInit<IRPCData, IRPCInputs, IRPCOutput> : R extends IRPCData ? IRPCInit<R, I, O$1> : IRPCInit<IRPCData, IRPCInputs, IRPCOutput> : IRPCInit<IRPCData, IRPCInputs, IRPCOutput>;
|
|
172
232
|
/**
|
|
173
233
|
* Complete specification for an RPC function including its implementation.
|
|
174
234
|
* Extends IRPCInit with the actual handler function.
|
|
@@ -176,9 +236,14 @@ type IRPCDeclareInit<F, I extends IRPCInputs, O extends IRPCOutput> = F extends
|
|
|
176
236
|
* @template I - Tuple of input validation schemas
|
|
177
237
|
* @template O - Output validation schema
|
|
178
238
|
*/
|
|
179
|
-
type IRPCSpec<I extends IRPCInputs, O extends IRPCOutput> = IRPCInit<I, O> & {
|
|
239
|
+
type IRPCSpec<I extends IRPCInputs, O$1 extends IRPCOutput> = IRPCInit<IRPCData, I, O$1> & {
|
|
240
|
+
/** Optional time-to-live for a call in milliseconds */
|
|
241
|
+
ttl?: number;
|
|
242
|
+
/** Whether to stream the result of the RPC call */
|
|
243
|
+
stream?: boolean;
|
|
180
244
|
/** The actual handler function that implements the RPC */
|
|
181
245
|
handler: IRPCHandler;
|
|
246
|
+
/** Optional initialization function for a stream RPC */
|
|
182
247
|
init?: () => unknown;
|
|
183
248
|
};
|
|
184
249
|
/**
|
|
@@ -191,6 +256,13 @@ type IRPCRequest = {
|
|
|
191
256
|
name: string;
|
|
192
257
|
/** Arguments for the RPC function */
|
|
193
258
|
args: unknown[];
|
|
259
|
+
files?: IRPCFilePointer[];
|
|
260
|
+
};
|
|
261
|
+
type IRPCCredentials = Iterable<[string, AsyncValue]>;
|
|
262
|
+
type IRPCCredentialsFactory = Record<string, AsyncValue> | (() => Record<string, AsyncValue>);
|
|
263
|
+
type IRPCRequests = {
|
|
264
|
+
calls: IRPCRequest[];
|
|
265
|
+
credentials?: IRPCCredentials;
|
|
194
266
|
};
|
|
195
267
|
type IRPCError = {
|
|
196
268
|
code: ErrorCode;
|
|
@@ -238,6 +310,8 @@ type IRPCCallConfig = {
|
|
|
238
310
|
retryMode?: 'linear' | 'exponential';
|
|
239
311
|
/** Base delay between retries in milliseconds */
|
|
240
312
|
retryDelay?: number;
|
|
313
|
+
/** Optional initialization function for a stream RPC */
|
|
314
|
+
init?: () => unknown;
|
|
241
315
|
};
|
|
242
316
|
/**
|
|
243
317
|
* Configuration for transport layer, extending call configuration with debounce settings.
|
|
@@ -246,5 +320,17 @@ type TransportConfig = IRPCCallConfig & {
|
|
|
246
320
|
/** Debounce setting for transport - can be a boolean to enable/disable or a number for specific delay */
|
|
247
321
|
debounce?: number | boolean;
|
|
248
322
|
};
|
|
323
|
+
type StreamCleanup = () => void;
|
|
324
|
+
/**
|
|
325
|
+
* A callback function type used to natively construct and drive a reactive stream.
|
|
326
|
+
* It provides the initial reactive data reference and terminal resolution hooks
|
|
327
|
+
* without forcing strict async/await boundaries, securely yielding stream operations.
|
|
328
|
+
*
|
|
329
|
+
* @template T - The type of data yielded globally by the stream.
|
|
330
|
+
* @param state - The reactive state reference for the stream.
|
|
331
|
+
* @param resolve - Callback to statically mark the stream as successfully completed, optionally with a resolved value.
|
|
332
|
+
* @param reject - Callback to forcefully throw a runtime error into the stream structure.
|
|
333
|
+
*/
|
|
334
|
+
type StreamConstructor<T> = (state: IRPCReadable<T>, resolve: (value?: T) => void, reject: (error: Error) => void) => StreamCleanup | void | Promise<StreamCleanup | void>;
|
|
249
335
|
//#endregion
|
|
250
|
-
export { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCData, IRPCDataSchema, IRPCDataType, IRPCDeclareInit, IRPCError,
|
|
336
|
+
export { IRPCArraySchema, IRPCBaseContext, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCDataSchema, IRPCDataType, IRPCDeclareInit, IRPCError, IRPCFunction, IRPCHandler, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCRequests, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig };
|
package/package.json
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@irpclib/irpc",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.24",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"import": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./server": {
|
|
13
|
+
"types": "./dist/server/index.d.ts",
|
|
14
|
+
"import": "./dist/server/index.js"
|
|
11
15
|
}
|
|
12
16
|
},
|
|
13
|
-
"files": [
|
|
14
|
-
"dist"
|
|
15
|
-
],
|
|
17
|
+
"files": ["dist"],
|
|
16
18
|
"directories": {
|
|
17
19
|
"dist": "./dist"
|
|
18
20
|
},
|
|
@@ -27,7 +29,7 @@
|
|
|
27
29
|
"publint": "0.3.15",
|
|
28
30
|
"rimraf": "6.0.1",
|
|
29
31
|
"tsdown": "0.15.9",
|
|
30
|
-
"vite": "
|
|
32
|
+
"vite": "8.0.10",
|
|
31
33
|
"vitest": "^3.2.4",
|
|
32
34
|
"zod": "^4.1.5"
|
|
33
35
|
},
|
|
@@ -48,6 +50,6 @@
|
|
|
48
50
|
},
|
|
49
51
|
"license": "MIT",
|
|
50
52
|
"dependencies": {
|
|
51
|
-
"@anchorlib/core": "^1.0.0-beta.
|
|
53
|
+
"@anchorlib/core": "^1.0.0-beta.24"
|
|
52
54
|
}
|
|
53
|
-
}
|
|
55
|
+
}
|
package/readme.md
CHANGED
|
@@ -120,7 +120,7 @@ import { loadDashboard } from './index.js';
|
|
|
120
120
|
import { stream } from '@irpclib/irpc';
|
|
121
121
|
|
|
122
122
|
irpc.construct(loadDashboard, (userId) => {
|
|
123
|
-
return stream((data, resolve) => {
|
|
123
|
+
return stream(({ data }, resolve) => {
|
|
124
124
|
const q1 = db.users.get(userId).then(res => data.user = res);
|
|
125
125
|
const q2 = db.sales.aggregate(userId).then(res => data.sales = res);
|
|
126
126
|
|
|
@@ -131,6 +131,8 @@ irpc.construct(loadDashboard, (userId) => {
|
|
|
131
131
|
|
|
132
132
|
### 4. Setup Server
|
|
133
133
|
|
|
134
|
+
The integration point extracts application-level values from transport-specific objects and injects them as standardized context via `initContext`. This keeps middleware and handlers transport-agnostic.
|
|
135
|
+
|
|
134
136
|
```typescript
|
|
135
137
|
// server.ts
|
|
136
138
|
import { setContextProvider } from '@irpclib/irpc';
|
|
@@ -147,7 +149,10 @@ Bun.serve({
|
|
|
147
149
|
port: 3000,
|
|
148
150
|
routes: {
|
|
149
151
|
[transport.endpoint]: {
|
|
150
|
-
POST: (req) => router.resolve(req
|
|
152
|
+
POST: (req) => router.resolve(req, [
|
|
153
|
+
['token', req.headers.get('authorization')],
|
|
154
|
+
['locale', req.headers.get('accept-language')],
|
|
155
|
+
]),
|
|
151
156
|
}
|
|
152
157
|
},
|
|
153
158
|
});
|
|
@@ -256,7 +261,7 @@ export const createUser = irpc.declare({
|
|
|
256
261
|
|
|
257
262
|
## Documentation
|
|
258
263
|
|
|
259
|
-
For detailed documentation, visit [https://
|
|
264
|
+
For detailed documentation, visit [https://airlib.dev/irpc](https://airlib.dev/irpc)
|
|
260
265
|
|
|
261
266
|
## License
|
|
262
267
|
|
package/dist/uuid.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
//#region src/uuid.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* A function that generates a random UUID string.
|
|
4
|
-
*
|
|
5
|
-
* @returns A UUID v4 string in the format xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
6
|
-
*/
|
|
7
|
-
type UUIDProvider = () => string;
|
|
8
|
-
/**
|
|
9
|
-
* Generates a new UUID using the currently configured provider.
|
|
10
|
-
*
|
|
11
|
-
* @returns A UUID string generated by the current provider
|
|
12
|
-
*/
|
|
13
|
-
declare function uuid(): string;
|
|
14
|
-
/**
|
|
15
|
-
* Sets a custom UUID provider function to be used by the uuid() function.
|
|
16
|
-
*
|
|
17
|
-
* @param provider - A function that returns a UUID string when called
|
|
18
|
-
*/
|
|
19
|
-
declare function setUUIDProvider(provider: UUIDProvider): void;
|
|
20
|
-
//#endregion
|
|
21
|
-
export { UUIDProvider, setUUIDProvider, uuid };
|