@irpclib/irpc 1.0.0-beta.24 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ import { IRPCCrudMeta, IRPCData, IRPCDriver, IRPCStub } from "./types.js";
2
+ import { IRPCPackage } from "./module.js";
3
+
4
+ //#region src/adapter.d.ts
5
+ declare class NextDriver extends Error {
6
+ constructor();
7
+ }
8
+ /** Extracts operational method names from an adapter, excluding its own API. */
9
+ type AttachableMethod<T> = string & keyof Omit<T, 'attach' | 'use' | 'dispatch'>;
10
+ type AnyStub = IRPCStub<any, any[], any>;
11
+ /**
12
+ * Attaches handlers to IRPC stubs and bridges them to drivers.
13
+ * Dispatches calls through the registered driver chain.
14
+ */
15
+ declare class IRPCAdapter {
16
+ private module;
17
+ private drivers;
18
+ constructor(module: IRPCPackage);
19
+ /**
20
+ * Runs a get operation through the driver chain
21
+ * @param meta - Resolved entity metadata
22
+ * @param id - The entity identifier
23
+ */
24
+ get(meta: IRPCCrudMeta, id: IRPCData): Promise<IRPCData> | IRPCData;
25
+ /**
26
+ * Runs a create operation through the driver chain
27
+ * @param meta - Resolved entity metadata
28
+ * @param data - The entity data to create
29
+ */
30
+ create(meta: IRPCCrudMeta, data: IRPCData): Promise<IRPCData> | IRPCData;
31
+ /**
32
+ * Runs an update operation through the driver chain
33
+ * @param meta - Resolved entity metadata
34
+ * @param id - The entity identifier
35
+ * @param data - The entity data to update
36
+ */
37
+ update(meta: IRPCCrudMeta, id: IRPCData, data: IRPCData): Promise<IRPCData> | IRPCData;
38
+ /**
39
+ * Runs a delete operation through the driver chain
40
+ * @param meta - Resolved entity metadata
41
+ * @param id - The entity identifier
42
+ */
43
+ delete(meta: IRPCCrudMeta, id: IRPCData): Promise<IRPCData> | IRPCData;
44
+ /**
45
+ * Dispatches a method call through each registered driver in order
46
+ * @param method - The method name to dispatch
47
+ * @param meta - Resolved entity metadata
48
+ * @param args - Arguments forwarded to the driver method
49
+ * @throws CrudError.notImplemented if no driver handles the method
50
+ */
51
+ protected dispatch(method: string, meta: IRPCCrudMeta, ...args: IRPCData[]): Promise<IRPCData> | IRPCData;
52
+ /**
53
+ * Attaches a single stub to a specific method on this adapter
54
+ * @param stub - The stub function to attach
55
+ * @param method - The method name matching an adapter operation
56
+ * @throws CrudError.notFound if the stub is not registered in the package
57
+ */
58
+ attach(stub: AnyStub, method: AttachableMethod<this>): this;
59
+ /**
60
+ * Attaches stubs to this adapter by matching object keys to adapter methods
61
+ * @param stubs - Object mapping method names to stub functions
62
+ * @throws CrudError.notFound if a stub is not registered in the package
63
+ */
64
+ attach(stubs: Partial<Record<AttachableMethod<this>, AnyStub>>): this;
65
+ /**
66
+ * Registers a driver to handle dispatched operations
67
+ * @param driver - The driver implementation
68
+ */
69
+ use(driver: IRPCDriver): this;
70
+ /**
71
+ * Signals the current driver to pass execution to the next driver in the chain
72
+ */
73
+ static next(): NextDriver;
74
+ }
75
+ //#endregion
76
+ export { IRPCAdapter };
@@ -0,0 +1,109 @@
1
+ import { CrudError } from "./error.js";
2
+
3
+ //#region src/adapter.ts
4
+ var NextDriver = class extends Error {
5
+ constructor() {
6
+ super("Next driver");
7
+ }
8
+ };
9
+ /**
10
+ * Attaches handlers to IRPC stubs and bridges them to drivers.
11
+ * Dispatches calls through the registered driver chain.
12
+ */
13
+ var IRPCAdapter = class {
14
+ drivers = /* @__PURE__ */ new Set();
15
+ constructor(module) {
16
+ this.module = module;
17
+ }
18
+ /**
19
+ * Runs a get operation through the driver chain
20
+ * @param meta - Resolved entity metadata
21
+ * @param id - The entity identifier
22
+ */
23
+ get(meta, id) {
24
+ return this.dispatch("get", meta, id);
25
+ }
26
+ /**
27
+ * Runs a create operation through the driver chain
28
+ * @param meta - Resolved entity metadata
29
+ * @param data - The entity data to create
30
+ */
31
+ create(meta, data) {
32
+ return this.dispatch("create", meta, data);
33
+ }
34
+ /**
35
+ * Runs an update operation through the driver chain
36
+ * @param meta - Resolved entity metadata
37
+ * @param id - The entity identifier
38
+ * @param data - The entity data to update
39
+ */
40
+ update(meta, id, data) {
41
+ return this.dispatch("update", meta, id, data);
42
+ }
43
+ /**
44
+ * Runs a delete operation through the driver chain
45
+ * @param meta - Resolved entity metadata
46
+ * @param id - The entity identifier
47
+ */
48
+ delete(meta, id) {
49
+ return this.dispatch("delete", meta, id);
50
+ }
51
+ /**
52
+ * Dispatches a method call through each registered driver in order
53
+ * @param method - The method name to dispatch
54
+ * @param meta - Resolved entity metadata
55
+ * @param args - Arguments forwarded to the driver method
56
+ * @throws CrudError.notImplemented if no driver handles the method
57
+ */
58
+ dispatch(method, meta, ...args) {
59
+ for (const driver of this.drivers) {
60
+ const fn = driver[method];
61
+ if (!fn) continue;
62
+ try {
63
+ return fn(meta, ...args);
64
+ } catch (err) {
65
+ if (err instanceof NextDriver) continue;
66
+ throw err;
67
+ }
68
+ }
69
+ throw CrudError.notImplemented(method);
70
+ }
71
+ attach(stubOrStubs, m) {
72
+ const stubs = m ? { [m]: stubOrStubs } : stubOrStubs;
73
+ const key = this.module.config.key ?? "id";
74
+ for (const [method, stub] of Object.entries(stubs)) {
75
+ if (!stub) continue;
76
+ const spec = this.module["stubs"].get(stub);
77
+ if (!spec) throw CrudError.notFound();
78
+ const meta = {
79
+ name: spec.name.replace(`.${method}`, ""),
80
+ key,
81
+ description: spec.description,
82
+ schema: spec.schema,
83
+ maxAge: spec.maxAge,
84
+ coalesce: spec.coalesce
85
+ };
86
+ this.module.construct(stub, ((...args) => {
87
+ return this[method](meta, ...args);
88
+ }));
89
+ }
90
+ return this;
91
+ }
92
+ /**
93
+ * Registers a driver to handle dispatched operations
94
+ * @param driver - The driver implementation
95
+ */
96
+ use(driver) {
97
+ this.drivers.add(driver);
98
+ return this;
99
+ }
100
+ /**
101
+ * Signals the current driver to pass execution to the next driver in the chain
102
+ */
103
+ static next() {
104
+ return new NextDriver();
105
+ }
106
+ };
107
+
108
+ //#endregion
109
+ export { IRPCAdapter };
package/dist/call.d.ts CHANGED
@@ -12,7 +12,9 @@ declare const DEFAULT_RETRY_DELAY = 1000;
12
12
  declare class IRPCCall {
13
13
  transport: IRPCTransport;
14
14
  payload: IRPCPayload;
15
- options: IRPCCallConfig;
15
+ options: IRPCCallConfig & {
16
+ seed?: () => IRPCData;
17
+ };
16
18
  /**
17
19
  * Unique identifier for this RPC call, generated using shortId().
18
20
  */
@@ -51,7 +53,9 @@ declare class IRPCCall {
51
53
  * @param payload - The RPC payload containing method and parameters
52
54
  * @param options - Options for the call, such as timeout, maxRetries, etc.
53
55
  */
54
- constructor(transport: IRPCTransport, payload: IRPCPayload, options: IRPCCallConfig, reader?: IRPCReader<IRPCData>);
56
+ constructor(transport: IRPCTransport, payload: IRPCPayload, options: IRPCCallConfig & {
57
+ seed?: () => IRPCData;
58
+ }, reader?: IRPCReader<IRPCData>);
55
59
  enqueue(packet: IRPCPacketStream<IRPCData>): void;
56
60
  /**
57
61
  * Resolves the RPC call with the provided value.
package/dist/call.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { CallError } from "./error.js";
1
2
  import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
- import { ERROR_CODE, ERROR_MESSAGE } from "./error.js";
3
3
  import { IRPCReader } from "./reader.js";
4
4
  import { IRPC_STORE } from "./store.js";
5
5
  import { uuid } from "@anchorlib/core";
@@ -60,16 +60,13 @@ var IRPCCall = class {
60
60
  name: this.payload.name,
61
61
  type: IRPC_PACKET_TYPE.CLOSE,
62
62
  status: IRPC_STATUS.ERROR,
63
- error: {
64
- code: ERROR_CODE.TIMEOUT,
65
- message: ERROR_MESSAGE[ERROR_CODE.TIMEOUT]
66
- },
63
+ error: CallError.timeout().json(),
67
64
  createdAt: Date.now()
68
65
  });
69
66
  clearTimeout(this.retryId);
70
- this.reject(new Error(ERROR_MESSAGE[ERROR_CODE.TIMEOUT]), false);
67
+ this.reject(CallError.timeout(), false);
71
68
  }, options.timeout);
72
- this.reader = reader ?? new IRPCReader(uuid(), options?.init?.());
69
+ this.reader = reader ?? new IRPCReader(uuid(), options?.seed?.());
73
70
  this.reader.onClose = () => this.close();
74
71
  this.id = this.reader.id;
75
72
  }
@@ -105,7 +102,7 @@ var IRPCCall = class {
105
102
  if (maxRetries && retriable) {
106
103
  if (reason) this.retryReasons.add(reason);
107
104
  if (this.retries >= maxRetries) {
108
- IRPC_STORE.error(/* @__PURE__ */ new Error(`${ERROR_MESSAGE[ERROR_CODE.CALL_MAX_RETRIES_REACHED]}: ${Array.from(this.retryReasons).map((r) => r.message).join(", ")}`), [{
105
+ IRPC_STORE.error(CallError.maxRetries(this.retryReasons), [{
109
106
  id: this.id,
110
107
  name: this.payload.name
111
108
  }]);
package/dist/enum.d.ts CHANGED
@@ -4,15 +4,6 @@ declare const IRPC_PACKET_TYPE: {
4
4
  readonly EVENT: "event";
5
5
  readonly CLOSE: "close";
6
6
  readonly ANSWER: "answer";
7
- readonly REQUEST: "request";
8
- readonly RESPONSE: "response";
9
- };
10
- declare const IRPC_DATA_TYPE: {
11
- readonly ARRAY: "array";
12
- readonly OBJECT: "object";
13
- readonly READABLE: "readable";
14
- readonly WRITABLE: "writable";
15
- readonly PRIMITIVE: "primitive";
16
7
  };
17
8
  declare const IRPC_STATUS: {
18
9
  readonly IDLE: "idle";
@@ -40,4 +31,4 @@ declare const IRPC_FILE_STATUS: {
40
31
  readonly ERROR: "error";
41
32
  };
42
33
  //#endregion
43
- export { IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT };
34
+ export { IRPC_BASE_CONTEXT, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT };
package/dist/enum.js CHANGED
@@ -3,16 +3,7 @@ const IRPC_PACKET_TYPE = {
3
3
  CALL: "call",
4
4
  EVENT: "event",
5
5
  CLOSE: "close",
6
- ANSWER: "answer",
7
- REQUEST: "request",
8
- RESPONSE: "response"
9
- };
10
- const IRPC_DATA_TYPE = {
11
- ARRAY: "array",
12
- OBJECT: "object",
13
- READABLE: "readable",
14
- WRITABLE: "writable",
15
- PRIMITIVE: "primitive"
6
+ ANSWER: "answer"
16
7
  };
17
8
  const IRPC_STATUS = {
18
9
  IDLE: "idle",
@@ -41,4 +32,4 @@ const IRPC_FILE_STATUS = {
41
32
  };
42
33
 
43
34
  //#endregion
44
- export { IRPC_BASE_CONTEXT, IRPC_DATA_TYPE, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT };
35
+ export { IRPC_BASE_CONTEXT, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT };
package/dist/error.d.ts CHANGED
@@ -1,61 +1,127 @@
1
+ import { IRPCPacketError } from "./types.js";
2
+
1
3
  //#region src/error.d.ts
2
- declare const ERROR_CODE: {
3
- UNKNOWN: string;
4
- TIMEOUT: string;
5
- NOT_FOUND: string;
6
- NOT_SUPPORTED: string;
7
- INVALID_TYPE: string;
8
- INVALID_STATE: string;
9
- INVALID_VALUE: string;
10
- INVALID_INPUT: string;
11
- INVALID_OUTPUT: string;
12
- NOT_IMPLEMENTED: string;
13
- INVALID_HANDLER: string;
14
- INVALID_OPERATION: string;
15
- INVALID_HOOK: string;
16
- TRANSPORT_MISSING: string;
17
- TRANSPORT_INVALID: string;
18
- TRANSPORT_NOT_IMPLEMENTED: string;
19
- STUB_MISSING: string;
20
- STUB_INVALID: string;
21
- STUB_NOT_IMPLEMENTED: string;
22
- RESOLVER_MISSING: string;
23
- RESOLVER_NOT_IMPLEMENTED: string;
24
- RESOLVER_NOT_FOUND: string;
25
- RESOLVER_NOT_SUPPORTED: string;
26
- STREAM_ERROR: string;
27
- HANDLER_ERROR: string;
28
- RESOLVE_ERROR: string;
29
- CALL_MAX_RETRIES_REACHED: string;
30
- };
31
- type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];
32
- declare const ERROR_MESSAGE: {
33
- [ERROR_CODE.UNKNOWN]: string;
34
- [ERROR_CODE.TIMEOUT]: string;
35
- [ERROR_CODE.NOT_FOUND]: string;
36
- [ERROR_CODE.NOT_SUPPORTED]: string;
37
- [ERROR_CODE.INVALID_TYPE]: string;
38
- [ERROR_CODE.INVALID_STATE]: string;
39
- [ERROR_CODE.INVALID_VALUE]: string;
40
- [ERROR_CODE.INVALID_INPUT]: string;
41
- [ERROR_CODE.INVALID_OUTPUT]: string;
42
- [ERROR_CODE.NOT_IMPLEMENTED]: string;
43
- [ERROR_CODE.INVALID_HANDLER]: string;
44
- [ERROR_CODE.INVALID_OPERATION]: string;
45
- [ERROR_CODE.INVALID_HOOK]: string;
46
- [ERROR_CODE.TRANSPORT_MISSING]: string;
47
- [ERROR_CODE.TRANSPORT_INVALID]: string;
48
- [ERROR_CODE.TRANSPORT_NOT_IMPLEMENTED]: string;
49
- [ERROR_CODE.STUB_INVALID]: string;
50
- [ERROR_CODE.STREAM_ERROR]: string;
51
- [ERROR_CODE.HANDLER_ERROR]: string;
52
- [ERROR_CODE.RESOLVE_ERROR]: string;
53
- [ERROR_CODE.STUB_NOT_IMPLEMENTED]: string;
54
- [ERROR_CODE.RESOLVER_MISSING]: string;
55
- [ERROR_CODE.RESOLVER_NOT_IMPLEMENTED]: string;
56
- [ERROR_CODE.RESOLVER_NOT_FOUND]: string;
57
- [ERROR_CODE.RESOLVER_NOT_SUPPORTED]: string;
58
- [ERROR_CODE.CALL_MAX_RETRIES_REACHED]: string;
4
+ declare const IRPC_ERROR_TYPE: {
5
+ readonly STUB: "stub";
6
+ readonly HOOK: "hook";
7
+ readonly CALL: "call";
8
+ readonly CRUD: "crud";
9
+ readonly HANDLER: "handler";
10
+ readonly RESOLVE: "resolve";
11
+ readonly TRANSPORT: "transport";
59
12
  };
13
+ type IRPCErrorType = (typeof IRPC_ERROR_TYPE)[keyof typeof IRPC_ERROR_TYPE];
14
+ declare const STUB_ERROR: {
15
+ readonly DUPLICATE: "duplicate";
16
+ readonly INVALID: "invalid";
17
+ readonly NOT_FOUND: "not_found";
18
+ readonly INVALID_NAME: "invalid_name";
19
+ readonly INVALID_VERSION: "invalid_version";
20
+ };
21
+ declare const HANDLER_ERROR: {
22
+ readonly INVALID: "invalid";
23
+ readonly MISSING: "missing";
24
+ readonly ERROR: "error";
25
+ };
26
+ declare const TRANSPORT_ERROR: {
27
+ readonly INVALID: "invalid";
28
+ readonly MISSING: "missing";
29
+ readonly NOT_IMPLEMENTED: "not_implemented";
30
+ readonly NOT_CONNECTED: "not_connected";
31
+ readonly CLOSED: "closed";
32
+ readonly INVALID_BODY: "invalid_body";
33
+ readonly STREAM_TERMINATED: "stream_terminated";
34
+ readonly ERROR: "error";
35
+ };
36
+ declare const RESOLVE_ERROR: {
37
+ readonly NOT_FOUND: "not_found";
38
+ readonly INVALID_INPUT: "invalid_input";
39
+ readonly INVALID_OUTPUT: "invalid_output";
40
+ readonly ERROR: "error";
41
+ };
42
+ declare const HOOK_ERROR: {
43
+ readonly INVALID: "invalid";
44
+ readonly ERROR: "error";
45
+ };
46
+ declare const CALL_ERROR: {
47
+ readonly TIMEOUT: "timeout";
48
+ readonly MAX_RETRIES: "max_retries";
49
+ readonly STREAM_ERROR: "stream_error";
50
+ };
51
+ declare const CRUD_ERROR: {
52
+ readonly NOT_FOUND: "not_found";
53
+ readonly NOT_IMPLEMENTED: "not_implemented";
54
+ };
55
+ /**
56
+ * Base error class for all IRPC errors.
57
+ *
58
+ * @property type - The domain category of the error (stub, handler, transport, etc.)
59
+ * @property code - A stable, machine-readable code for translation or programmatic matching.
60
+ */
61
+ declare class IRPCError extends Error {
62
+ type: IRPCErrorType;
63
+ code: string;
64
+ cause?: Error | undefined;
65
+ constructor(type: IRPCErrorType, code: string, message: string, cause?: Error | undefined);
66
+ /** Serialize to the wire format used in IRPC packets. */
67
+ json(): IRPCPacketError;
68
+ /** Reconstruct an IRPCError from a wire packet error. */
69
+ static from(obj: IRPCPacketError): IRPCError;
70
+ }
71
+ /** Errors related to stub declaration, registration, and lookup. */
72
+ declare class StubError extends IRPCError {
73
+ constructor(code: string, message: string, cause?: Error);
74
+ static duplicate(name: string): StubError;
75
+ static invalid(): StubError;
76
+ static notFound(): StubError;
77
+ static invalidName(name: string): StubError;
78
+ static invalidVersion(version: string): StubError;
79
+ }
80
+ /** Errors related to handler registration and execution. */
81
+ declare class HandlerError extends IRPCError {
82
+ constructor(code: string, message: string, cause?: Error);
83
+ static invalid(): HandlerError;
84
+ static missing(name: string): HandlerError;
85
+ static failed(input: Error | string): HandlerError;
86
+ }
87
+ /** Errors related to the transport layer. */
88
+ declare class TransportError extends IRPCError {
89
+ constructor(code: string, message: string, cause?: Error);
90
+ static missing(): TransportError;
91
+ static invalid(): TransportError;
92
+ static notImplemented(): TransportError;
93
+ static notConnected(name: string): TransportError;
94
+ static closed(name: string): TransportError;
95
+ static invalidBody(): TransportError;
96
+ static streamTerminated(): TransportError;
97
+ static failed(input: Error | string): TransportError;
98
+ }
99
+ /** Errors related to server-side request resolution. */
100
+ declare class ResolveError extends IRPCError {
101
+ constructor(code: string, message: string, cause?: Error);
102
+ static notFound(name: string): ResolveError;
103
+ static invalidInput(input: Error | string): ResolveError;
104
+ static invalidOutput(input?: Error | string): ResolveError;
105
+ static failed(input: Error | string): ResolveError;
106
+ }
107
+ /** Errors related to hook registration and execution. */
108
+ declare class HookError extends IRPCError {
109
+ constructor(code: string, message: string, cause?: Error);
110
+ static invalid(): HookError;
111
+ static failed(input: Error | string): HookError;
112
+ }
113
+ /** Errors related to call execution lifecycle. */
114
+ declare class CallError extends IRPCError {
115
+ constructor(code: string, message: string, cause?: Error);
116
+ static timeout(): CallError;
117
+ static maxRetries(reasons: Set<Error>): CallError;
118
+ static streamError(input: Error | string): CallError;
119
+ }
120
+ /** Errors related to CRUD adapter operations. */
121
+ declare class CrudError extends IRPCError {
122
+ constructor(code: string, message: string, cause?: Error);
123
+ static notFound(): CrudError;
124
+ static notImplemented(method: string): CrudError;
125
+ }
60
126
  //#endregion
61
- export { ERROR_CODE, ERROR_MESSAGE, ErrorCode };
127
+ export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPCErrorType, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError };