@irpclib/irpc 1.0.0-beta.20 → 1.0.0-beta.22

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/state.js CHANGED
@@ -2,40 +2,125 @@ import { IRPC_STATUS } from "./enum.js";
2
2
  import { anchor, mutable, subscribe } from "@anchorlib/core";
3
3
 
4
4
  //#region src/state.ts
5
- var RemoteState = class {
6
- #state;
5
+ /**
6
+ * A reactive state wrapper that implements the standard Promise interface.
7
+ *
8
+ * RemoteState acts as a dual-layer abstraction:
9
+ * 1. For asynchronous execution, it operates as a `Promise<T>` that resolves upon completion or rejects upon failure.
10
+ * 2. For reactive environments, it exposes an `.subscribe()` method to react to intermediate data mutations.
11
+ *
12
+ * @template T - The type of data held by the state.
13
+ */
14
+ var RemoteState = class extends Promise {
15
+ state;
16
+ accept;
17
+ reject;
18
+ /**
19
+ * The current data payload of the state.
20
+ */
7
21
  get data() {
8
- return this.#state.data;
22
+ return this.state.data;
9
23
  }
10
24
  set data(data) {
11
- this.#state.data = data;
25
+ this.state.data = data;
12
26
  }
27
+ /**
28
+ * The current error encountered by the state, if any.
29
+ */
13
30
  get error() {
14
- return this.#state.error;
31
+ return this.state.error;
15
32
  }
16
33
  set error(error) {
17
- this.#state.error = error;
34
+ this.state.error = error;
18
35
  }
36
+ /**
37
+ * The execution status of the state (PENDING, SUCCESS, ERROR).
38
+ * Transitioning to a terminal status (SUCCESS or ERROR) will automatically resolve or reject the underlying Promise.
39
+ */
19
40
  get status() {
20
- return this.#state.status;
41
+ return this.state.status;
21
42
  }
22
43
  set status(status) {
23
- this.#state.status = status;
44
+ this.state.status = status;
45
+ if (this.status === IRPC_STATUS.ERROR) {
46
+ this.reject(new Error(this.error.message));
47
+ this.destroy();
48
+ } else if (this.status === IRPC_STATUS.SUCCESS) {
49
+ this.accept(this.data);
50
+ this.destroy();
51
+ }
24
52
  }
53
+ /**
54
+ * Initializes a new RemoteState with an optional initial payload.
55
+ *
56
+ * @param init - An optional starting value for the data payload.
57
+ */
25
58
  constructor(init) {
26
- this.#state = mutable({
27
- data: mutable(init),
59
+ let acceptFn;
60
+ let rejectFn;
61
+ super((resolve, reject) => {
62
+ acceptFn = resolve;
63
+ rejectFn = reject;
64
+ });
65
+ this.accept = acceptFn;
66
+ this.reject = rejectFn;
67
+ this.state = mutable({
68
+ data: init,
28
69
  error: void 0,
29
- status: IRPC_STATUS.IDLE
70
+ status: IRPC_STATUS.PENDING
30
71
  });
31
72
  }
73
+ /**
74
+ * Subscribes to changes emitted by the internal state.
75
+ *
76
+ * @param handler - A callback function invoked whenever the state mutates.
77
+ * @returns An unsubscribe function to terminate the listener.
78
+ */
32
79
  subscribe(handler) {
33
- return subscribe(this.#state, handler);
80
+ return subscribe(this.state, handler);
34
81
  }
82
+ /**
83
+ * Destroys the reactive state bindings.
84
+ */
35
85
  destroy() {
36
- anchor.destroy(this.#state);
86
+ anchor.destroy(this.state);
87
+ }
88
+ /**
89
+ * Ensures that chained Promise operations return standard Promises
90
+ * rather than instantiating new RemoteState subclasses.
91
+ */
92
+ static get [Symbol.species]() {
93
+ return Promise;
37
94
  }
38
95
  };
96
+ /**
97
+ * A utility factory to structurally instantiate an active `RemoteState` pipeline natively
98
+ * decoupled from standard Promise chains. This elegantly captures constructor functions
99
+ * pushing events into the state before terminating mechanically via secure internal hooks.
100
+ *
101
+ * @template T - The type of the streamed payload data.
102
+ * @param construct - The isolated stream constructor callback that natively operates the pipeline.
103
+ * @param init - An optional initial value to prime the state payload inherently.
104
+ * @returns A fully active RemoteState inherently bound to the callbacks executing natively.
105
+ */
106
+ function stream(construct, init) {
107
+ const state = new RemoteState(init);
108
+ const accept = ((...values) => {
109
+ if (values.length > 0) state.data = values[0];
110
+ state.status = IRPC_STATUS.SUCCESS;
111
+ });
112
+ const reject = (error) => {
113
+ state.error = error;
114
+ state.status = IRPC_STATUS.ERROR;
115
+ };
116
+ try {
117
+ const result = construct(state.data, accept, reject);
118
+ if (result instanceof Promise) result.catch(reject);
119
+ } catch (error) {
120
+ reject(error);
121
+ }
122
+ return state;
123
+ }
39
124
 
40
125
  //#endregion
41
- export { RemoteState };
126
+ export { RemoteState, stream };
@@ -0,0 +1,57 @@
1
+ import { IRPCData, IRPCError, IRPCPacketStream, IRPCResponse, IRPCStatus } from "./types.js";
2
+
3
+ //#region src/stream.d.ts
4
+
5
+ /**
6
+ * A server-side producer that normalizes and serializes RPC outputs into standard transport packets.
7
+ *
8
+ * Supports both standard asynchronous responses and reactive streams. When handling a continuous stream,
9
+ * it intercepts state mutations and emits sequential network packets (`ANSWER`, `EVENT`, `CLOSE`).
10
+ *
11
+ * @template T - The type of data yielded by the stream.
12
+ */
13
+ declare class IRPCStream<T extends IRPCData> {
14
+ private id;
15
+ private name;
16
+ private initializer;
17
+ private pipeHandlers;
18
+ private closeHandlers;
19
+ private errorHandlers;
20
+ value?: T;
21
+ error?: IRPCError;
22
+ status: IRPCStatus;
23
+ /**
24
+ * Initializes a stream wrapping an asynchronous RPC execution.
25
+ *
26
+ * @param id - The unique identifier of the RPC request.
27
+ * @param name - The name of the specification processing the execution.
28
+ * @param initializer - An execution callback that yields an IRPCResponse.
29
+ */
30
+ constructor(id: string, name: string, initializer: () => Promise<IRPCResponse>);
31
+ /**
32
+ * Evaluates the underlying initializer and propagates standard transport packets
33
+ * to all bound pipe handlers based on the output lifecycle.
34
+ */
35
+ private start;
36
+ /**
37
+ * Binds a handler to receive the outbound stream packets.
38
+ * If invoked after the stream has fulfilled or rejected natively, it automatically plays back the conclusive packet.
39
+ *
40
+ * @param handler - A callback function to receive packets.
41
+ */
42
+ pipe(handler: (event: IRPCPacketStream<T>) => void): void;
43
+ /**
44
+ * Binds a handler to trap any internal runtime failures independently.
45
+ *
46
+ * @param handler - A callback function to receive stream errors.
47
+ */
48
+ catch(handler: (error: IRPCError) => void): void;
49
+ /**
50
+ * Binds a handler triggered upon terminal completion of the stream process (success or error).
51
+ *
52
+ * @param handler - A callback function invoked at stream completion.
53
+ */
54
+ close(handler: () => void): void;
55
+ }
56
+ //#endregion
57
+ export { IRPCStream };
package/dist/stream.js ADDED
@@ -0,0 +1,204 @@
1
+ import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
+ import { ERROR_CODE } from "./error.js";
3
+ import { RemoteState } from "./state.js";
4
+
5
+ //#region src/stream.ts
6
+ /**
7
+ * A server-side producer that normalizes and serializes RPC outputs into standard transport packets.
8
+ *
9
+ * Supports both standard asynchronous responses and reactive streams. When handling a continuous stream,
10
+ * it intercepts state mutations and emits sequential network packets (`ANSWER`, `EVENT`, `CLOSE`).
11
+ *
12
+ * @template T - The type of data yielded by the stream.
13
+ */
14
+ var IRPCStream = class {
15
+ pipeHandlers = /* @__PURE__ */ new Set();
16
+ closeHandlers = /* @__PURE__ */ new Set();
17
+ errorHandlers = /* @__PURE__ */ new Set();
18
+ value;
19
+ error;
20
+ status = IRPC_STATUS.IDLE;
21
+ /**
22
+ * Initializes a stream wrapping an asynchronous RPC execution.
23
+ *
24
+ * @param id - The unique identifier of the RPC request.
25
+ * @param name - The name of the specification processing the execution.
26
+ * @param initializer - An execution callback that yields an IRPCResponse.
27
+ */
28
+ constructor(id, name, initializer) {
29
+ this.id = id;
30
+ this.name = name;
31
+ this.initializer = initializer;
32
+ }
33
+ /**
34
+ * Evaluates the underlying initializer and propagates standard transport packets
35
+ * to all bound pipe handlers based on the output lifecycle.
36
+ */
37
+ async start() {
38
+ if (this.status !== IRPC_STATUS.IDLE) return;
39
+ this.status = IRPC_STATUS.PENDING;
40
+ const { id, name } = this;
41
+ try {
42
+ const { result } = await this.initializer();
43
+ if (result instanceof RemoteState) {
44
+ this.value = result.data;
45
+ if (result.status === IRPC_STATUS.SUCCESS || result.status === IRPC_STATUS.ERROR) {
46
+ if (result.status === IRPC_STATUS.ERROR) {
47
+ this.error = {
48
+ code: ERROR_CODE.STREAM_ERROR,
49
+ message: result.error.message
50
+ };
51
+ this.status = IRPC_STATUS.ERROR;
52
+ } else this.status = IRPC_STATUS.SUCCESS;
53
+ const packet = {
54
+ id,
55
+ name,
56
+ type: IRPC_PACKET_TYPE.ANSWER,
57
+ data: this.value,
58
+ error: this.error,
59
+ status: this.status,
60
+ createdAt: Date.now()
61
+ };
62
+ this.pipeHandlers.forEach((handler) => handler(packet));
63
+ this.errorHandlers.forEach((handler) => handler(this.error));
64
+ this.closeHandlers.forEach((handler) => handler());
65
+ return;
66
+ }
67
+ this.pipeHandlers.forEach((handler) => {
68
+ handler({
69
+ id,
70
+ name,
71
+ type: IRPC_PACKET_TYPE.ANSWER,
72
+ data: result.data,
73
+ status: result.status,
74
+ createdAt: Date.now()
75
+ });
76
+ });
77
+ const unsubscribe = result.subscribe((state, { type, keys, value }) => {
78
+ if (type === "init") return;
79
+ const [rootKey] = keys;
80
+ if (rootKey === "data") this.pipeHandlers.forEach((handler) => {
81
+ handler({
82
+ id,
83
+ name,
84
+ type: IRPC_PACKET_TYPE.EVENT,
85
+ status: state.status,
86
+ data: {
87
+ type,
88
+ keys,
89
+ value
90
+ },
91
+ createdAt: Date.now()
92
+ });
93
+ });
94
+ else if (rootKey === "status") {
95
+ if (state.status !== IRPC_STATUS.SUCCESS && state.status !== IRPC_STATUS.ERROR) return;
96
+ this.status = state.status;
97
+ if (state.status === IRPC_STATUS.ERROR) {
98
+ this.error = {
99
+ code: ERROR_CODE.STREAM_ERROR,
100
+ message: state.error.message
101
+ };
102
+ this.errorHandlers.forEach((handler) => handler(this.error));
103
+ }
104
+ this.pipeHandlers.forEach((handler) => {
105
+ handler({
106
+ id,
107
+ name,
108
+ type: IRPC_PACKET_TYPE.CLOSE,
109
+ error: this.error,
110
+ status: this.status,
111
+ createdAt: Date.now()
112
+ });
113
+ });
114
+ this.closeHandlers.forEach((handler) => handler());
115
+ unsubscribe();
116
+ }
117
+ });
118
+ } else {
119
+ this.value = result;
120
+ this.status = IRPC_STATUS.SUCCESS;
121
+ const packet = {
122
+ id,
123
+ name,
124
+ type: IRPC_PACKET_TYPE.ANSWER,
125
+ status: IRPC_STATUS.SUCCESS,
126
+ data: this.value,
127
+ createdAt: Date.now()
128
+ };
129
+ this.pipeHandlers.forEach((handler) => handler(packet));
130
+ this.closeHandlers.forEach((handler) => handler());
131
+ }
132
+ } catch (error) {
133
+ this.error = {
134
+ code: ERROR_CODE.STREAM_ERROR,
135
+ message: error.message
136
+ };
137
+ this.status = IRPC_STATUS.ERROR;
138
+ this.pipeHandlers.forEach((handler) => {
139
+ handler({
140
+ id,
141
+ name,
142
+ type: IRPC_PACKET_TYPE.ANSWER,
143
+ status: IRPC_STATUS.ERROR,
144
+ error,
145
+ createdAt: Date.now()
146
+ });
147
+ });
148
+ this.errorHandlers.forEach((handler) => handler(this.error));
149
+ this.closeHandlers.forEach((handler) => handler());
150
+ return;
151
+ }
152
+ }
153
+ /**
154
+ * Binds a handler to receive the outbound stream packets.
155
+ * If invoked after the stream has fulfilled or rejected natively, it automatically plays back the conclusive packet.
156
+ *
157
+ * @param handler - A callback function to receive packets.
158
+ */
159
+ pipe(handler) {
160
+ if (this.status === IRPC_STATUS.SUCCESS || this.status === IRPC_STATUS.ERROR) {
161
+ handler({
162
+ id: this.id,
163
+ name: this.name,
164
+ type: IRPC_PACKET_TYPE.ANSWER,
165
+ data: this.value,
166
+ error: this.error,
167
+ status: this.status,
168
+ createdAt: Date.now()
169
+ });
170
+ return;
171
+ }
172
+ this.pipeHandlers.add(handler);
173
+ this.start().catch(() => {});
174
+ }
175
+ /**
176
+ * Binds a handler to trap any internal runtime failures independently.
177
+ *
178
+ * @param handler - A callback function to receive stream errors.
179
+ */
180
+ catch(handler) {
181
+ if (this.status === IRPC_STATUS.ERROR) {
182
+ handler(this.error);
183
+ return;
184
+ }
185
+ this.errorHandlers.add(handler);
186
+ this.start().catch(() => {});
187
+ }
188
+ /**
189
+ * Binds a handler triggered upon terminal completion of the stream process (success or error).
190
+ *
191
+ * @param handler - A callback function invoked at stream completion.
192
+ */
193
+ close(handler) {
194
+ if (this.status === IRPC_STATUS.SUCCESS || this.status === IRPC_STATUS.ERROR) {
195
+ handler();
196
+ return;
197
+ }
198
+ this.closeHandlers.add(handler);
199
+ this.start().catch(() => {});
200
+ }
201
+ };
202
+
203
+ //#endregion
204
+ export { IRPCStream };
@@ -1,4 +1,5 @@
1
- import { IRPCData, IRPCInputs, IRPCOutput, IRPCSpec, TransportConfig } from "./types.js";
1
+ import { IRPCCallConfig, IRPCData, IRPCInputs, IRPCOutput, IRPCSpec, TransportConfig } from "./types.js";
2
+ import { IRPCReader } from "./reader.js";
2
3
  import { IRPCCall } from "./call.js";
3
4
 
4
5
  //#region src/transport.d.ts
@@ -22,16 +23,16 @@ declare class IRPCTransport {
22
23
  * Initiates an RPC call with the given specification and arguments.
23
24
  * @param spec - The RPC specification defining the method to call.
24
25
  * @param args - An array of arguments to pass to the RPC method.
25
- * @param timeout - Optional timeout value for the RPC call.
26
+ * @param config - Optional call configuration, including timeout, retry settings, and more.
26
27
  * @returns A promise that resolves with the RPC response data or rejects with an error.
27
28
  */
28
- call(spec: IRPCSpec<IRPCInputs, IRPCOutput>, args: IRPCData[], timeout?: number | undefined): Promise<IRPCData>;
29
+ call(spec: IRPCSpec<IRPCInputs, IRPCOutput>, args: IRPCData[], config?: IRPCCallConfig): IRPCReader<IRPCData>;
29
30
  /**
30
31
  * Schedules an RPC call for execution, implementing debouncing logic.
31
32
  * Queued calls will be dispatched after the configured debounce delay.
32
33
  * @param call - The RPC call to schedule.
33
34
  */
34
- protected schedule(call: IRPCCall): void;
35
+ schedule(call: IRPCCall): void;
35
36
  /**
36
37
  * Dispatches a batch of RPC calls. This base implementation rejects all calls
37
38
  * with a "not implemented" error. Subclasses should override this method to
package/dist/transport.js CHANGED
@@ -1,5 +1,6 @@
1
- import { IRPCCall } from "./call.js";
1
+ import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
2
  import { ERROR_CODE, ERROR_MESSAGE } from "./error.js";
3
+ import { IRPCCall } from "./call.js";
3
4
 
4
5
  //#region src/transport.ts
5
6
  /**
@@ -22,27 +23,26 @@ var IRPCTransport = class {
22
23
  * Initiates an RPC call with the given specification and arguments.
23
24
  * @param spec - The RPC specification defining the method to call.
24
25
  * @param args - An array of arguments to pass to the RPC method.
25
- * @param timeout - Optional timeout value for the RPC call.
26
+ * @param config - Optional call configuration, including timeout, retry settings, and more.
26
27
  * @returns A promise that resolves with the RPC response data or rejects with an error.
27
28
  */
28
- call(spec, args, timeout = this.config?.timeout) {
29
+ call(spec, args, config) {
29
30
  const payload = {
30
31
  name: spec.name,
31
32
  args
32
33
  };
33
- return new Promise((resolve, reject) => {
34
- const timer = timeout ? setTimeout(() => {
35
- call.reject(new Error(ERROR_MESSAGE[ERROR_CODE.TIMEOUT]));
36
- }, timeout) : void 0;
37
- const call = new IRPCCall(payload, (value) => {
38
- resolve(value);
39
- clearTimeout(timer);
40
- }, (reason) => {
41
- reject(reason);
42
- clearTimeout(timer);
43
- }, timeout);
44
- this.schedule(call);
34
+ const { timeout, maxRetries, retryMode, retryDelay } = {
35
+ ...this.config,
36
+ ...config
37
+ };
38
+ const call = new IRPCCall(this, payload, {
39
+ timeout,
40
+ maxRetries,
41
+ retryMode,
42
+ retryDelay
45
43
  });
44
+ this.schedule(call);
45
+ return call.reader;
46
46
  }
47
47
  /**
48
48
  * Schedules an RPC call for execution, implementing debouncing logic.
@@ -52,12 +52,12 @@ var IRPCTransport = class {
52
52
  schedule(call) {
53
53
  const { debounce } = this.config ?? {};
54
54
  if (debounce === false) {
55
- this.dispatch([call]).finally(() => {});
55
+ this.dispatch([call]).finally(() => {}).catch(() => {});
56
56
  return;
57
57
  }
58
58
  const timeout = typeof debounce === "number" && !Number.isNaN(debounce) ? debounce : 0;
59
59
  const dispatch = () => {
60
- this.dispatch(Array.from(this.queue)).finally(() => {});
60
+ this.dispatch(Array.from(this.queue)).finally(() => {}).catch(() => {});
61
61
  this.queue.clear();
62
62
  };
63
63
  if (!this.queue.size) if (timeout === 0) queueMicrotask(dispatch);
@@ -73,7 +73,17 @@ var IRPCTransport = class {
73
73
  */
74
74
  async dispatch(calls) {
75
75
  calls.forEach((call) => {
76
- call.reject(new Error(ERROR_MESSAGE[ERROR_CODE.TRANSPORT_NOT_IMPLEMENTED]));
76
+ call.enqueue({
77
+ id: call.id,
78
+ name: call.payload.name,
79
+ type: IRPC_PACKET_TYPE.CLOSE,
80
+ status: IRPC_STATUS.ERROR,
81
+ error: {
82
+ code: ERROR_CODE.TRANSPORT_NOT_IMPLEMENTED,
83
+ message: ERROR_MESSAGE[ERROR_CODE.TRANSPORT_NOT_IMPLEMENTED]
84
+ },
85
+ createdAt: Date.now()
86
+ });
77
87
  });
78
88
  }
79
89
  };
package/dist/types.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { IRPC_DATA_TYPE, IRPC_EVENT_TYPE, IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
2
  import { ErrorCode } from "./error.js";
3
3
  import { IRPCTransport } from "./transport.js";
4
+ import { RemoteState } from "./state.js";
5
+ import { StateChange } from "@anchorlib/core";
4
6
  import { ZodArray, ZodBoolean, ZodNull, ZodNumber, ZodObject, ZodSafeParseResult, ZodString, ZodUndefined } from "zod/v4";
5
7
 
6
8
  //#region src/types.d.ts
@@ -19,28 +21,32 @@ type IRPCStatus = (typeof IRPC_STATUS)[keyof typeof IRPC_STATUS];
19
21
  type IRPCDataType = (typeof IRPC_DATA_TYPE)[keyof typeof IRPC_DATA_TYPE];
20
22
  type IRPCPacketType = (typeof IRPC_PACKET_TYPE)[keyof typeof IRPC_PACKET_TYPE];
21
23
  type IRPCEventType = (typeof IRPC_EVENT_TYPE)[keyof typeof IRPC_EVENT_TYPE];
22
- type IRPCPacket = {
24
+ type IRPCPacketBase = {
23
25
  id: string;
24
26
  name: string;
25
27
  type: IRPCPacketType;
26
- dispatchAt?: number;
27
- receivedAt?: number;
28
+ status: IRPCStatus;
29
+ createdAt?: number;
30
+ arrivedAt?: number;
28
31
  };
29
32
  type IRPCPacketData = {
30
33
  type: IRPCDataType;
31
34
  value: IRPCData;
32
35
  };
33
- type IRPCPacketCall = IRPCPacket & {
36
+ type IRPCPacketCall = IRPCPacketBase & {
34
37
  args: IRPCData[];
35
38
  };
36
- type IRPCPacketAnswer = IRPCPacket & {
37
- data?: IRPCPacketData;
39
+ type IRPCPacketAnswer<T extends IRPCData> = IRPCPacketBase & {
40
+ data?: T;
38
41
  error?: IRPCError;
39
42
  };
40
- type IRPCPacketEvent = IRPCPacket & {
41
- data: IRPCPacketData;
42
- event: IRPCEventType;
43
+ type IRPCPacketEvent = IRPCPacketBase & {
44
+ data: StateChange;
45
+ };
46
+ type IRPCPacketClose = IRPCPacketBase & {
47
+ error?: IRPCError;
43
48
  };
49
+ type IRPCPacketStream<T extends IRPCData> = IRPCPacketAnswer<T> | IRPCPacketEvent | IRPCPacketClose;
44
50
  interface IRPCReadable<T> {
45
51
  data: T;
46
52
  error: Error | undefined;
@@ -102,8 +108,7 @@ type IRPCPackageInfo = {
102
108
  /** Optional description of the namespace */
103
109
  description?: string;
104
110
  };
105
- type IRPCPackageConfig = IRPCPackageInfo & {
106
- timeout?: number;
111
+ type IRPCPackageConfig = IRPCPackageInfo & IRPCCallConfig & {
107
112
  transport?: IRPCTransport;
108
113
  };
109
114
  /**
@@ -145,8 +150,6 @@ type IRPCInit<I extends IRPCInputs, O extends IRPCOutput> = {
145
150
  schema?: IRPCSchema<I, O>;
146
151
  /** Optional maximum age of a call in milliseconds */
147
152
  maxAge?: number;
148
- /** Optional timeout for RPC calls */
149
- timeout?: number;
150
153
  /**
151
154
  * Whether to coalesce multiple calls to the same RPC function within a short time period.
152
155
  * If true, multiple calls with the same parameters will be combined into a single call,
@@ -154,7 +157,18 @@ type IRPCInit<I extends IRPCInputs, O extends IRPCOutput> = {
154
157
  * This can help reduce the number of actual function executions.
155
158
  */
156
159
  coalesce?: boolean;
157
- };
160
+ } & IRPCCallConfig;
161
+ /**
162
+ * Type definition for an RPC declaration.
163
+ * Represents an RPC function with its name, description, and configuration.
164
+ *
165
+ * @template F - The function signature of the RPC
166
+ * @template I - Tuple of input validation schemas
167
+ * @template O - Output validation schema
168
+ */
169
+ type IRPCDeclareInit<F, I extends IRPCInputs, O extends IRPCOutput> = F extends ((...args: any[]) => RemoteState<infer R>) ? IRPCInit<I, IRPCOutput> & {
170
+ init: () => R;
171
+ } : IRPCInit<I, O>;
158
172
  /**
159
173
  * Complete specification for an RPC function including its implementation.
160
174
  * Extends IRPCInit with the actual handler function.
@@ -165,6 +179,7 @@ type IRPCInit<I extends IRPCInputs, O extends IRPCOutput> = {
165
179
  type IRPCSpec<I extends IRPCInputs, O extends IRPCOutput> = IRPCInit<I, O> & {
166
180
  /** The actual handler function that implements the RPC */
167
181
  handler: IRPCHandler;
182
+ init?: () => unknown;
168
183
  };
169
184
  /**
170
185
  * Represents an incoming RPC request.
@@ -194,11 +209,6 @@ type IRPCResponse = {
194
209
  /** Result of the RPC call if successful */
195
210
  result?: unknown;
196
211
  };
197
- type IRPCCache = {
198
- data: IRPCData;
199
- expiresAt: number;
200
- timestamp: number;
201
- };
202
212
  /**
203
213
  * Context storage mechanism for RPC operations.
204
214
  */
@@ -216,9 +226,25 @@ type IRPCContextProvider = {
216
226
  /** Gets the current context store */
217
227
  getStore<K, V>(): IRPCContext<K, V>;
218
228
  };
219
- type TransportConfig = {
229
+ /**
230
+ * Configuration options for an RPC call.
231
+ */
232
+ type IRPCCallConfig = {
233
+ /** Timeout for the RPC call in milliseconds */
220
234
  timeout?: number;
235
+ /** Maximum number of retries for the call */
236
+ maxRetries?: number;
237
+ /** Retry strategy mode - either linear or exponential backoff */
238
+ retryMode?: 'linear' | 'exponential';
239
+ /** Base delay between retries in milliseconds */
240
+ retryDelay?: number;
241
+ };
242
+ /**
243
+ * Configuration for transport layer, extending call configuration with debounce settings.
244
+ */
245
+ type TransportConfig = IRPCCallConfig & {
246
+ /** Debounce setting for transport - can be a boolean to enable/disable or a number for specific delay */
221
247
  debounce?: number | boolean;
222
248
  };
223
249
  //#endregion
224
- export { IRPCArraySchema, IRPCCache, IRPCContext, IRPCContextProvider, IRPCData, IRPCDataSchema, IRPCDataType, IRPCError, IRPCEventType, IRPCHandler, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacket, IRPCPacketAnswer, IRPCPacketCall, IRPCPacketData, IRPCPacketEvent, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStubStore, TransportConfig };
250
+ export { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCData, IRPCDataSchema, IRPCDataType, IRPCDeclareInit, IRPCError, IRPCEventType, IRPCHandler, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketData, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStubStore, TransportConfig };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@irpclib/irpc",
4
- "version": "1.0.0-beta.20",
4
+ "version": "1.0.0-beta.22",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/index.js",
7
7
  "exports": {
@@ -10,7 +10,9 @@
10
10
  "import": "./dist/index.js"
11
11
  }
12
12
  },
13
- "files": ["dist"],
13
+ "files": [
14
+ "dist"
15
+ ],
14
16
  "directories": {
15
17
  "dist": "./dist"
16
18
  },
@@ -46,6 +48,6 @@
46
48
  },
47
49
  "license": "MIT",
48
50
  "dependencies": {
49
- "@anchorlib/core": "1.0.0-beta.19"
51
+ "@anchorlib/core": "^1.0.0-beta.22"
50
52
  }
51
- }
53
+ }