@irpclib/irpc 1.0.0-beta.23 → 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/context.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IRPCContext, IRPCContextProvider } from "./types.js";
2
- import { AsyncStore, getContext, setContext } from "@anchorlib/core";
2
+ import { AsyncStore, createContext, getContext, setContext } from "@anchorlib/core";
3
3
 
4
4
  //#region src/context.d.ts
5
5
 
@@ -23,8 +23,8 @@ declare function withContext<R>(ctx: IRPCContext<string | symbol, unknown>, fn:
23
23
  * @param init - Optional initial key-value pairs for the context
24
24
  * @returns A new Map instance representing the context
25
25
  */
26
- declare function createContext<K extends string | symbol, V>(init?: [K, V][]): AsyncStore;
26
+ declare function createContextStore<K extends string | symbol, V>(init?: [K, V][]): AsyncStore;
27
27
  declare function getAbortSignal(): AbortSignal | undefined;
28
28
  declare function getAbortController(): AbortController | undefined;
29
29
  //#endregion
30
- export { createContext, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext };
30
+ export { createContext, createContextStore, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext };
package/dist/context.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IRPC_BASE_CONTEXT } from "./enum.js";
2
- import { AsyncStore, getContext, setAsyncScope, setContext, withIsolation } from "@anchorlib/core";
2
+ import { AsyncStore, createContext, getContext, setAsyncScope, setContext, withIsolation } from "@anchorlib/core";
3
3
 
4
4
  //#region src/context.ts
5
5
  /**
@@ -26,7 +26,7 @@ function withContext(ctx, fn) {
26
26
  * @param init - Optional initial key-value pairs for the context
27
27
  * @returns A new Map instance representing the context
28
28
  */
29
- function createContext(init) {
29
+ function createContextStore(init) {
30
30
  return new AsyncStore(init);
31
31
  }
32
32
  function getAbortSignal() {
@@ -37,4 +37,4 @@ function getAbortController() {
37
37
  }
38
38
 
39
39
  //#endregion
40
- export { createContext, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext };
40
+ export { createContext, createContextStore, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext };
@@ -0,0 +1,9 @@
1
+ import { IRPCCredentials } from "./types.js";
2
+ import { AsyncStore } from "@anchorlib/core";
3
+
4
+ //#region src/credential.d.ts
5
+ declare function createCredentials(seeds: IRPCCredentials): AsyncStore;
6
+ declare function getCredentials(): AsyncStore;
7
+ declare function credential<V>(key: string): V | undefined;
8
+ //#endregion
9
+ export { createCredentials, credential, getCredentials };
@@ -0,0 +1,16 @@
1
+ import { IRPC_BASE_CONTEXT } from "./enum.js";
2
+ import { AsyncStore, getContext } from "@anchorlib/core";
3
+
4
+ //#region src/credential.ts
5
+ function createCredentials(seeds) {
6
+ return new AsyncStore(seeds);
7
+ }
8
+ function getCredentials() {
9
+ return getContext(IRPC_BASE_CONTEXT.CREDENTIALS);
10
+ }
11
+ function credential(key) {
12
+ return getCredentials()?.get(key);
13
+ }
14
+
15
+ //#endregion
16
+ export { createCredentials, credential, getCredentials };
package/dist/enum.d.ts CHANGED
@@ -31,6 +31,7 @@ declare const IRPC_STORE_EVENT: {
31
31
  declare const IRPC_BASE_CONTEXT: {
32
32
  readonly ABORT_SIGNAL: symbol;
33
33
  readonly ABORT_CONTROLLER: symbol;
34
+ readonly CREDENTIALS: symbol;
34
35
  };
35
36
  declare const IRPC_FILE_STATUS: {
36
37
  readonly IDLE: "idle";
package/dist/enum.js CHANGED
@@ -30,7 +30,8 @@ const IRPC_STORE_EVENT = {
30
30
  };
31
31
  const IRPC_BASE_CONTEXT = {
32
32
  ABORT_SIGNAL: Symbol("abort-signal"),
33
- ABORT_CONTROLLER: Symbol("abort-controller")
33
+ ABORT_CONTROLLER: Symbol("abort-controller"),
34
+ CREDENTIALS: Symbol("credentials")
34
35
  };
35
36
  const IRPC_FILE_STATUS = {
36
37
  IDLE: "idle",
package/dist/error.d.ts CHANGED
@@ -24,6 +24,8 @@ declare const ERROR_CODE: {
24
24
  RESOLVER_NOT_FOUND: string;
25
25
  RESOLVER_NOT_SUPPORTED: string;
26
26
  STREAM_ERROR: string;
27
+ HANDLER_ERROR: string;
28
+ RESOLVE_ERROR: string;
27
29
  CALL_MAX_RETRIES_REACHED: string;
28
30
  };
29
31
  type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];
@@ -46,6 +48,8 @@ declare const ERROR_MESSAGE: {
46
48
  [ERROR_CODE.TRANSPORT_NOT_IMPLEMENTED]: string;
47
49
  [ERROR_CODE.STUB_INVALID]: string;
48
50
  [ERROR_CODE.STREAM_ERROR]: string;
51
+ [ERROR_CODE.HANDLER_ERROR]: string;
52
+ [ERROR_CODE.RESOLVE_ERROR]: string;
49
53
  [ERROR_CODE.STUB_NOT_IMPLEMENTED]: string;
50
54
  [ERROR_CODE.RESOLVER_MISSING]: string;
51
55
  [ERROR_CODE.RESOLVER_NOT_IMPLEMENTED]: string;
package/dist/error.js CHANGED
@@ -24,6 +24,8 @@ const ERROR_CODE = {
24
24
  RESOLVER_NOT_FOUND: "resolver_not_found",
25
25
  RESOLVER_NOT_SUPPORTED: "resolver_not_supported",
26
26
  STREAM_ERROR: "stream_error",
27
+ HANDLER_ERROR: "handler_error",
28
+ RESOLVE_ERROR: "resolve_error",
27
29
  CALL_MAX_RETRIES_REACHED: "call_max_retries_reached"
28
30
  };
29
31
  const ERROR_MESSAGE = {
@@ -45,6 +47,8 @@ const ERROR_MESSAGE = {
45
47
  [ERROR_CODE.TRANSPORT_NOT_IMPLEMENTED]: "IRPC: Transport not implemented error",
46
48
  [ERROR_CODE.STUB_INVALID]: "IRPC: Stub invalid error",
47
49
  [ERROR_CODE.STREAM_ERROR]: "IRPC: Stream error",
50
+ [ERROR_CODE.HANDLER_ERROR]: "IRPC: Handler error",
51
+ [ERROR_CODE.RESOLVE_ERROR]: "IRPC: Resolve error",
48
52
  [ERROR_CODE.STUB_NOT_IMPLEMENTED]: "IRPC: Stub not implemented error",
49
53
  [ERROR_CODE.RESOLVER_MISSING]: "IRPC: Resolver missing error",
50
54
  [ERROR_CODE.RESOLVER_NOT_IMPLEMENTED]: "IRPC: Resolver not implemented error",
package/dist/index.d.ts CHANGED
@@ -2,17 +2,18 @@ import { IRPCCacheEntry, IRPCCacher } from "./cache.js";
2
2
  import { IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT } from "./enum.js";
3
3
  import { ERROR_CODE, ERROR_MESSAGE, ErrorCode } from "./error.js";
4
4
  import { IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe } from "./file.js";
5
+ import { IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_FILE_IDENTIFIER, PacketStream, decode, encode, isFilePointer } from "./packet.js";
6
+ import { IRPCHookArgs, IRPCPackage, IRPCSpecHook, createPackage, intercept } from "./module.js";
5
7
  import { IRPCTransport } from "./transport.js";
6
- import { IRPCArraySchema, IRPCBaseContext, IRPCCallConfig, IRPCContext, IRPCContextProvider, 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, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig } from "./types.js";
8
+ import { 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 } from "./types.js";
7
9
  import { RemoteState, stream } from "./state.js";
8
10
  import { IRPCReader } from "./reader.js";
9
11
  import { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, IRPCCall } from "./call.js";
10
- import { createContext, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext } from "./context.js";
11
- import { IRPCHookArgs, IRPCPackage, IRPCSpecHook, createPackage, intercept } from "./module.js";
12
- import { IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_FILE_IDENTIFIER, PacketStream, decode, encode, isFilePointer } from "./packet.js";
12
+ import { createContext, createContextStore, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext } from "./context.js";
13
+ import { createCredentials, credential, getCredentials } from "./credential.js";
13
14
  import { IRPCResolver } from "./resolver.js";
14
15
  import { IRPCHook, IRPCRouter } from "./router.js";
15
16
  import { IRPCStream } from "./stream.js";
16
17
  import { IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPC_STORE } from "./store.js";
17
18
  import { plan } from "@anchorlib/core";
18
- export { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, ERROR_CODE, ERROR_MESSAGE, ErrorCode, IRPCArraySchema, IRPCBaseContext, IRPCCacheEntry, IRPCCacher, IRPCCall, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCData, IRPCDataSchema, IRPCDataType, IRPCDeclareInit, IRPCError, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFilePointer, IRPCFileQueue, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe, IRPCFunction, IRPCHandler, IRPCHook, IRPCHookArgs, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackage, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketEvent, IRPCPacketJson, IRPCPacketQueues, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCReader, IRPCRequest, IRPCResolver, IRPCResponse, IRPCRouter, IRPCSchema, IRPCSpec, IRPCSpecHook, IRPCSpecStore, IRPCStatus, IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPCStream, IRPCStreamInit, IRPCStub, IRPCStubStore, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, PacketStream, RemoteState, StreamCleanup, StreamConstructor, TransportConfig, createContext, createPackage, decode, encode, getAbortController, getAbortSignal, getContext, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
19
+ export { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, ERROR_CODE, ERROR_MESSAGE, ErrorCode, IRPCArraySchema, IRPCBaseContext, IRPCCacheEntry, IRPCCacher, IRPCCall, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCDataSchema, IRPCDataType, IRPCDeclareInit, IRPCError, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFilePointer, IRPCFileQueue, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe, IRPCFunction, IRPCHandler, IRPCHook, IRPCHookArgs, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackage, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketEvent, IRPCPacketJson, IRPCPacketQueues, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCReader, IRPCRequest, IRPCRequests, IRPCResolver, IRPCResponse, IRPCRouter, IRPCSchema, IRPCSpec, IRPCSpecHook, IRPCSpecStore, IRPCStatus, IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPCStream, IRPCStreamInit, IRPCStub, IRPCStubStore, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, PacketStream, RemoteState, StreamCleanup, StreamConstructor, TransportConfig, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { IRPCCacher } from "./cache.js";
2
2
  import { IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT } from "./enum.js";
3
3
  import { ERROR_CODE, ERROR_MESSAGE } from "./error.js";
4
- import { createContext, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext } from "./context.js";
4
+ import { createContext, createContextStore, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext } from "./context.js";
5
5
  import { RemoteState, stream } from "./state.js";
6
6
  import { IRPCReader } from "./reader.js";
7
7
  import { IRPCTransport } from "./transport.js";
@@ -10,9 +10,10 @@ import { IRPCRouter } from "./router.js";
10
10
  import { IRPCStream } from "./stream.js";
11
11
  import { IRPCStore, IRPC_STORE } from "./store.js";
12
12
  import { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, IRPCCall } from "./call.js";
13
+ import { createCredentials, credential, getCredentials } from "./credential.js";
13
14
  import { IRPCFile, IRPCFileStream } from "./file.js";
14
15
  import { IRPC_FILE_IDENTIFIER, decode, encode, isFilePointer } from "./packet.js";
15
16
  import { IRPCResolver } from "./resolver.js";
16
17
  import { plan } from "@anchorlib/core";
17
18
 
18
- export { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, ERROR_CODE, ERROR_MESSAGE, IRPCCacher, IRPCCall, IRPCFile, IRPCFileStream, IRPCPackage, IRPCReader, IRPCResolver, IRPCRouter, IRPCStore, IRPCStream, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, RemoteState, createContext, createPackage, decode, encode, getAbortController, getAbortSignal, getContext, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
19
+ export { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, ERROR_CODE, ERROR_MESSAGE, IRPCCacher, IRPCCall, IRPCFile, IRPCFileStream, IRPCPackage, IRPCReader, IRPCResolver, IRPCRouter, IRPCStore, IRPCStream, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, RemoteState, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
package/dist/module.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { IRPCCacher } from "./cache.js";
2
2
  import { IRPC_STATUS } from "./enum.js";
3
3
  import { ERROR_CODE, ERROR_MESSAGE } from "./error.js";
4
+ import { getAbortSignal } from "./context.js";
4
5
  import { RemoteState } from "./state.js";
5
6
  import { IRPCReader } from "./reader.js";
6
7
  import { IRPCTransport } from "./transport.js";
@@ -98,6 +99,23 @@ var IRPCPackage = class {
98
99
  stub.when = (getArgs, debounce) => {
99
100
  return prepare(typeof getArgs === "function" ? getArgs : () => getArgs, true, debounce);
100
101
  };
102
+ stub.later = (debounce) => {
103
+ const reader = new IRPCReader(uuid(), spec.init(), IRPC_STATUS.IDLE, true);
104
+ if (debounce) {
105
+ const [schedule, cancel] = microtask(debounce);
106
+ reader.dispatch = (...args) => schedule(() => {
107
+ reader.resume();
108
+ execute(args, reader);
109
+ });
110
+ onCleanup(cancel);
111
+ return reader;
112
+ }
113
+ reader.dispatch = (...args) => {
114
+ reader.resume();
115
+ execute(args, reader);
116
+ };
117
+ return reader;
118
+ };
101
119
  /**
102
120
  * A preparation utility to generate and schedule call on the browser environment.
103
121
  *
@@ -230,6 +248,8 @@ var IRPCPackage = class {
230
248
  */
231
249
  use(transport) {
232
250
  if (!(transport instanceof IRPCTransport)) throw new Error(ERROR_MESSAGE[ERROR_CODE.TRANSPORT_INVALID]);
251
+ if (this.transport) this.transport.modules.delete(this);
252
+ transport.modules.add(this);
233
253
  this.config.transport = transport;
234
254
  return this;
235
255
  }
@@ -283,10 +303,18 @@ function createPackage(config) {
283
303
  * @returns {IRPCReader<IRPCData>} - The IRPCReader object for consumer.
284
304
  */
285
305
  function intercept(spec, args, reader) {
306
+ const signal = getAbortSignal();
307
+ if (signal?.aborted) {
308
+ reader.abort();
309
+ return reader;
310
+ }
311
+ const abort = () => reader.abort();
312
+ signal?.addEventListener("abort", abort, { once: true });
286
313
  try {
287
314
  const result = spec.handler(...args);
288
315
  if (!(result instanceof Promise)) {
289
316
  reader.accept(result);
317
+ signal?.removeEventListener("abort", abort);
290
318
  return reader;
291
319
  }
292
320
  if (!(result instanceof RemoteState)) {
@@ -294,6 +322,8 @@ function intercept(spec, args, reader) {
294
322
  reader.accept(value);
295
323
  }).catch((err) => {
296
324
  reader.reject(err);
325
+ }).finally(() => {
326
+ signal?.removeEventListener("abort", abort);
297
327
  });
298
328
  return reader;
299
329
  }
@@ -303,13 +333,24 @@ function intercept(spec, args, reader) {
303
333
  const [rootKey] = event.keys;
304
334
  if (rootKey === "status") {
305
335
  reader.status = event.value;
306
- if (reader.status === IRPC_STATUS.SUCCESS) unsubscribe();
336
+ if (reader.status === IRPC_STATUS.SUCCESS || reader.status === IRPC_STATUS.ERROR) {
337
+ signal?.removeEventListener("abort", subAbort);
338
+ unsubscribe();
339
+ }
307
340
  return;
308
341
  }
309
342
  replay(reader.state, event);
310
343
  });
344
+ const subAbort = () => {
345
+ unsubscribe();
346
+ reader.abort();
347
+ result.abort();
348
+ };
349
+ signal?.addEventListener("abort", subAbort, { once: true });
350
+ signal?.removeEventListener("abort", abort);
311
351
  } catch (error) {
312
352
  reader.reject(error);
353
+ signal?.removeEventListener("abort", abort);
313
354
  }
314
355
  return reader;
315
356
  }
package/dist/reader.d.ts CHANGED
@@ -17,8 +17,9 @@ declare class IRPCReader<T extends IRPCData> extends RemoteState<T> {
17
17
  * @param id - The unique identifier for this state instance.
18
18
  * @param init - An optional starting value for the data payload.
19
19
  * @param status - The initial status of the state (PENDING, SUCCESS, ERROR).
20
+ * @param resumable - Whether the state should be resumable after being closed.
20
21
  */
21
- constructor(id: string, init?: T, status?: IRPCStatus);
22
+ constructor(id: string, init?: T, status?: IRPCStatus, resumable?: boolean);
22
23
  /**
23
24
  * Pushes incoming network packets into this reader, evaluating payload data
24
25
  * and subsequently updating the core state values locally.
package/dist/reader.js CHANGED
@@ -16,9 +16,10 @@ var IRPCReader = class extends RemoteState {
16
16
  * @param id - The unique identifier for this state instance.
17
17
  * @param init - An optional starting value for the data payload.
18
18
  * @param status - The initial status of the state (PENDING, SUCCESS, ERROR).
19
+ * @param resumable - Whether the state should be resumable after being closed.
19
20
  */
20
- constructor(id, init, status = IRPC_STATUS.PENDING) {
21
- super(init, status);
21
+ constructor(id, init, status = IRPC_STATUS.PENDING, resumable) {
22
+ super(init, status, resumable);
22
23
  this.id = id;
23
24
  }
24
25
  /**
@@ -1,5 +1,5 @@
1
- import { IRPCDataSchema, IRPCInputs, IRPCOutput, IRPCRequest, IRPCResponse, IRPCSpec } from "./types.js";
2
1
  import { IRPCPackage } from "./module.js";
2
+ import { IRPCDataSchema, IRPCInputs, IRPCOutput, IRPCRequest, IRPCResponse, IRPCSpec } from "./types.js";
3
3
 
4
4
  //#region src/resolver.d.ts
5
5
 
package/dist/resolver.js CHANGED
@@ -96,7 +96,25 @@ var IRPCResolver = class {
96
96
  result
97
97
  };
98
98
  }
99
- const output = parseOutput(await result, schema);
99
+ const data = await result;
100
+ if (data instanceof RemoteState) {
101
+ data.unpipe();
102
+ const output$1 = parseOutput(data.data, schema);
103
+ if (!output$1.success) return {
104
+ id,
105
+ name,
106
+ error: {
107
+ code: ERROR_CODE.INVALID_OUTPUT,
108
+ message: output$1.error?.message
109
+ }
110
+ };
111
+ return {
112
+ id,
113
+ name,
114
+ result: data
115
+ };
116
+ }
117
+ const output = parseOutput(data, schema);
100
118
  if (output.success) return {
101
119
  id,
102
120
  name,
@@ -115,7 +133,7 @@ var IRPCResolver = class {
115
133
  id,
116
134
  name,
117
135
  error: {
118
- code: ERROR_CODE.UNKNOWN,
136
+ code: ERROR_CODE.HANDLER_ERROR,
119
137
  message: error.message
120
138
  }
121
139
  };
package/dist/router.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { IRPCPackage } from "./module.js";
1
2
  import { IRPCTransport } from "./transport.js";
2
3
  import { IRPCRequest } from "./types.js";
3
- import { IRPCPackage } from "./module.js";
4
4
 
5
5
  //#region src/router.d.ts
6
6
  type IRPCHook = () => void | Promise<void>;
@@ -21,6 +21,17 @@ declare class IRPCRouter {
21
21
  * @returns The current Router instance for chaining
22
22
  */
23
23
  use(hook: IRPCHook): this;
24
+ /**
25
+ * Run a function within an isolated IRPC Router context.
26
+ * This make sure any subsequent RPC calls will be seeded with the hooks added to the router.
27
+ *
28
+ * @param handler - The handler function to isolate
29
+ * @param controller - The AbortController to use for cancellation
30
+ * @param context - Additional context to pass to the handler
31
+ * @param preHook - A hook function to run before the router hooks
32
+ * @returns The result of the isolated handler function
33
+ */
34
+ isolate<T>(handler: () => T | Promise<T>, controller: AbortController, context?: Array<[string | symbol, unknown]>, preHook?: IRPCHook): Promise<Promise<T>>;
24
35
  /**
25
36
  * Resolves hook functions for a given request
26
37
  * @param req - The IRPC request to process hook for
package/dist/router.js CHANGED
@@ -1,5 +1,6 @@
1
- import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
1
+ import { IRPC_BASE_CONTEXT, IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
2
  import { ERROR_CODE, ERROR_MESSAGE } from "./error.js";
3
+ import { createContextStore, withContext } from "./context.js";
3
4
  import { IRPC_STORE } from "./store.js";
4
5
 
5
6
  //#region src/router.ts
@@ -31,6 +32,27 @@ var IRPCRouter = class {
31
32
  return this;
32
33
  }
33
34
  /**
35
+ * Run a function within an isolated IRPC Router context.
36
+ * This make sure any subsequent RPC calls will be seeded with the hooks added to the router.
37
+ *
38
+ * @param handler - The handler function to isolate
39
+ * @param controller - The AbortController to use for cancellation
40
+ * @param context - Additional context to pass to the handler
41
+ * @param preHook - A hook function to run before the router hooks
42
+ * @returns The result of the isolated handler function
43
+ */
44
+ isolate(handler, controller, context = [], preHook) {
45
+ return withContext(createContextStore([
46
+ [IRPC_BASE_CONTEXT.ABORT_SIGNAL, controller.signal],
47
+ [IRPC_BASE_CONTEXT.ABORT_CONTROLLER, controller],
48
+ ...context
49
+ ]), async () => {
50
+ await preHook?.();
51
+ for (const hook of this.hooks) await hook();
52
+ return handler();
53
+ });
54
+ }
55
+ /**
34
56
  * Resolves hook functions for a given request
35
57
  * @param req - The IRPC request to process hook for
36
58
  * @returns An error response if hook fails, undefined otherwise
package/dist/state.d.ts CHANGED
@@ -15,6 +15,7 @@ import { StateSubscriber } from "@anchorlib/core";
15
15
  */
16
16
  declare class RemoteState<T> extends Promise<T> {
17
17
  #private;
18
+ private resumable?;
18
19
  get state(): IRPCReadable<T>;
19
20
  /**
20
21
  * The current data payload of the state.
@@ -37,8 +38,9 @@ declare class RemoteState<T> extends Promise<T> {
37
38
  *
38
39
  * @param init - An optional starting value for the data payload.
39
40
  * @param status - The initial status of the state (PENDING, SUCCESS, ERROR).
41
+ * @param resumable - Whether the state should be resumable after being closed.
40
42
  */
41
- constructor(init?: T, status?: IRPCStatus);
43
+ constructor(init?: T, status?: IRPCStatus, resumable?: boolean | undefined);
42
44
  accept(value?: T): void;
43
45
  reject(error?: Error): void;
44
46
  abort(): void;
@@ -53,6 +55,9 @@ declare class RemoteState<T> extends Promise<T> {
53
55
  * Closes the reactive state and terminates the underlying Promise.
54
56
  */
55
57
  close(): void;
58
+ protected resume(): void;
59
+ pipe(): this;
60
+ unpipe(): this;
56
61
  /**
57
62
  * Destroys the reactive state bindings.
58
63
  */
package/dist/state.js CHANGED
@@ -18,6 +18,7 @@ var RemoteState = class extends Promise {
18
18
  #accept;
19
19
  #reject;
20
20
  #closed = false;
21
+ #locked;
21
22
  get state() {
22
23
  return this.#state;
23
24
  }
@@ -59,14 +60,17 @@ var RemoteState = class extends Promise {
59
60
  *
60
61
  * @param init - An optional starting value for the data payload.
61
62
  * @param status - The initial status of the state (PENDING, SUCCESS, ERROR).
63
+ * @param resumable - Whether the state should be resumable after being closed.
62
64
  */
63
- constructor(init, status = IRPC_STATUS.PENDING) {
65
+ constructor(init, status = IRPC_STATUS.PENDING, resumable) {
64
66
  let acceptFn;
65
67
  let rejectFn;
66
68
  super((resolve, reject) => {
69
+ if (resumable) resolve(init);
67
70
  acceptFn = resolve;
68
71
  rejectFn = reject;
69
72
  });
73
+ this.resumable = resumable;
70
74
  this.#accept = acceptFn;
71
75
  this.#reject = rejectFn;
72
76
  this.#state = mutable({
@@ -123,10 +127,25 @@ var RemoteState = class extends Promise {
123
127
  this.#accept(this.data);
124
128
  this.destroy();
125
129
  }
130
+ resume() {
131
+ this.#closed = false;
132
+ }
133
+ pipe() {
134
+ this.#locked = this.then;
135
+ this.then = void 0;
136
+ return this;
137
+ }
138
+ unpipe() {
139
+ if (!this.#locked) return this;
140
+ this.then = this.#locked;
141
+ this.#locked = void 0;
142
+ return this;
143
+ }
126
144
  /**
127
145
  * Destroys the reactive state bindings.
128
146
  */
129
147
  destroy() {
148
+ if (this.resumable) return;
130
149
  anchor.destroy(this.state);
131
150
  }
132
151
  /**
package/dist/store.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IRPC_STORE_EVENT } from "./enum.js";
2
- import { IRPCData } from "./types.js";
3
2
  import { IRPCPackage } from "./module.js";
3
+ import { IRPCData } from "./types.js";
4
4
  import { IRPCRouter } from "./router.js";
5
5
  import { IRPCStream } from "./stream.js";
6
6
 
package/dist/stream.js CHANGED
@@ -69,7 +69,7 @@ var IRPCStream = class {
69
69
  if (result.status === IRPC_STATUS.SUCCESS || result.status === IRPC_STATUS.ERROR) {
70
70
  if (result.status === IRPC_STATUS.ERROR) {
71
71
  this.error = {
72
- code: ERROR_CODE.STREAM_ERROR,
72
+ code: ERROR_CODE.HANDLER_ERROR,
73
73
  message: result.error.message
74
74
  };
75
75
  this.status = IRPC_STATUS.ERROR;
@@ -148,10 +148,7 @@ var IRPCStream = class {
148
148
  } else {
149
149
  this.value = result;
150
150
  if (response.error) {
151
- this.error = {
152
- code: ERROR_CODE.STREAM_ERROR,
153
- message: response.error.message
154
- };
151
+ this.error = response.error;
155
152
  this.status = IRPC_STATUS.ERROR;
156
153
  this.errorHandlers.forEach((handler) => handler(this.error));
157
154
  } else this.status = IRPC_STATUS.SUCCESS;
@@ -173,7 +170,7 @@ var IRPCStream = class {
173
170
  name: this.name
174
171
  }]);
175
172
  this.error = {
176
- code: ERROR_CODE.STREAM_ERROR,
173
+ code: ERROR_CODE.RESOLVE_ERROR,
177
174
  message: error.message
178
175
  };
179
176
  this.status = IRPC_STATUS.ERROR;
@@ -1,4 +1,5 @@
1
- import { IRPCCallConfig, IRPCData, IRPCInputs, IRPCOutput, IRPCSpec, TransportConfig } from "./types.js";
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.
@@ -34,6 +38,11 @@ declare class IRPCTransport {
34
38
  * @param call - The RPC call to schedule.
35
39
  */
36
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;
37
46
  /**
38
47
  * Closes an RPC call. This base implementation does nothing.
39
48
  * Subclasses should override this method to provide closing logic.
package/dist/transport.js CHANGED
@@ -11,10 +11,20 @@ import { onCleanup, uuid } from "@anchorlib/core";
11
11
  * It handles queuing, debouncing, and timeout management for RPC requests.
12
12
  */
13
13
  var IRPCTransport = class {
14
+ #credentialFactory;
15
+ modules = /* @__PURE__ */ new Set();
14
16
  /**
15
17
  * A set of pending RPC calls that are queued for execution.
16
18
  */
17
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
+ }
18
28
  /**
19
29
  * Creates a new IRPCTransport instance.
20
30
  * @param config - Optional transport configuration including timeout and debounce settings.
@@ -80,6 +90,14 @@ var IRPCTransport = class {
80
90
  this.queue.add(call);
81
91
  }
82
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
+ /**
83
101
  * Closes an RPC call. This base implementation does nothing.
84
102
  * Subclasses should override this method to provide closing logic.
85
103
  * @param call - The RPC call to cancel.
package/dist/types.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
2
  import { ErrorCode } from "./error.js";
3
3
  import { IRPCFile } from "./file.js";
4
+ import { IRPCFilePointer } from "./packet.js";
4
5
  import { IRPCTransport } from "./transport.js";
5
6
  import { RemoteState } from "./state.js";
6
7
  import { IRPCReader } from "./reader.js";
7
- import { StateChange } from "@anchorlib/core";
8
+ import { AsyncValue, StateChange } from "@anchorlib/core";
8
9
  import { ZodArray, ZodBoolean, ZodNull, ZodNumber, ZodObject, ZodSafeParseResult, ZodString, ZodUndefined } from "zod/v4";
9
10
 
10
11
  //#region src/types.d.ts
@@ -89,6 +90,9 @@ interface IRPCStub<T, A$1 extends unknown[], R$1 extends IRPCData> {
89
90
  * @returns An IRPCReader instance for handling the asynchronous result or stream.
90
91
  */
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
+ };
92
96
  }
93
97
  /**
94
98
  * A utility type that transforms a standard function type into its corresponding IRPCStub.
@@ -252,6 +256,13 @@ type IRPCRequest = {
252
256
  name: string;
253
257
  /** Arguments for the RPC function */
254
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;
255
266
  };
256
267
  type IRPCError = {
257
268
  code: ErrorCode;
@@ -322,4 +333,4 @@ type StreamCleanup = () => void;
322
333
  */
323
334
  type StreamConstructor<T> = (state: IRPCReadable<T>, resolve: (value?: T) => void, reject: (error: Error) => void) => StreamCleanup | void | Promise<StreamCleanup | void>;
324
335
  //#endregion
325
- export { IRPCArraySchema, IRPCBaseContext, IRPCCallConfig, IRPCContext, IRPCContextProvider, 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, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig };
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,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@irpclib/irpc",
4
- "version": "1.0.0-beta.23",
4
+ "version": "1.0.0-beta.24",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/index.js",
7
7
  "exports": {
@@ -50,6 +50,6 @@
50
50
  },
51
51
  "license": "MIT",
52
52
  "dependencies": {
53
- "@anchorlib/core": "^1.0.0-beta.23"
53
+ "@anchorlib/core": "^1.0.0-beta.24"
54
54
  }
55
55
  }