@irpclib/irpc 1.0.0-beta.25 → 1.1.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.js CHANGED
@@ -1,5 +1,5 @@
1
- import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
1
  import { CallError } from "./error.js";
2
+ import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
3
3
  import { IRPCReader } from "./reader.js";
4
4
  import { IRPC_STORE } from "./store.js";
5
5
  import { uuid } from "@anchorlib/core";
package/dist/error.d.ts CHANGED
@@ -5,6 +5,7 @@ declare const IRPC_ERROR_TYPE: {
5
5
  readonly STUB: "stub";
6
6
  readonly HOOK: "hook";
7
7
  readonly CALL: "call";
8
+ readonly CRUD: "crud";
8
9
  readonly HANDLER: "handler";
9
10
  readonly RESOLVE: "resolve";
10
11
  readonly TRANSPORT: "transport";
@@ -47,6 +48,10 @@ declare const CALL_ERROR: {
47
48
  readonly MAX_RETRIES: "max_retries";
48
49
  readonly STREAM_ERROR: "stream_error";
49
50
  };
51
+ declare const CRUD_ERROR: {
52
+ readonly NOT_FOUND: "not_found";
53
+ readonly NOT_IMPLEMENTED: "not_implemented";
54
+ };
50
55
  /**
51
56
  * Base error class for all IRPC errors.
52
57
  *
@@ -112,5 +117,11 @@ declare class CallError extends IRPCError {
112
117
  static maxRetries(reasons: Set<Error>): CallError;
113
118
  static streamError(input: Error | string): CallError;
114
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
+ }
115
126
  //#endregion
116
- export { CALL_ERROR, CallError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPCErrorType, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError };
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 };
package/dist/error.js CHANGED
@@ -3,6 +3,7 @@ const IRPC_ERROR_TYPE = {
3
3
  STUB: "stub",
4
4
  HOOK: "hook",
5
5
  CALL: "call",
6
+ CRUD: "crud",
6
7
  HANDLER: "handler",
7
8
  RESOLVE: "resolve",
8
9
  TRANSPORT: "transport"
@@ -44,6 +45,10 @@ const CALL_ERROR = {
44
45
  MAX_RETRIES: "max_retries",
45
46
  STREAM_ERROR: "stream_error"
46
47
  };
48
+ const CRUD_ERROR = {
49
+ NOT_FOUND: "not_found",
50
+ NOT_IMPLEMENTED: "not_implemented"
51
+ };
47
52
  function unwrap(input) {
48
53
  if (input instanceof Error) return {
49
54
  message: input.message,
@@ -199,14 +204,27 @@ var CallError = class CallError extends IRPCError {
199
204
  return new CallError(CALL_ERROR.STREAM_ERROR, message, cause);
200
205
  }
201
206
  };
207
+ /** Errors related to CRUD adapter operations. */
208
+ var CrudError = class CrudError extends IRPCError {
209
+ constructor(code, message, cause) {
210
+ super(IRPC_ERROR_TYPE.CRUD, code, message, cause);
211
+ }
212
+ static notFound() {
213
+ return new CrudError(CRUD_ERROR.NOT_FOUND, "Unknown CRUD instance — was it created with pkg.crud()?");
214
+ }
215
+ static notImplemented(method) {
216
+ return new CrudError(CRUD_ERROR.NOT_IMPLEMENTED, `CRUD method "${method}" not implemented.`);
217
+ }
218
+ };
202
219
  const IRPC_ERROR_CLASS = {
203
220
  [IRPC_ERROR_TYPE.STUB]: StubError,
204
221
  [IRPC_ERROR_TYPE.HANDLER]: HandlerError,
205
222
  [IRPC_ERROR_TYPE.TRANSPORT]: TransportError,
206
223
  [IRPC_ERROR_TYPE.RESOLVE]: ResolveError,
207
224
  [IRPC_ERROR_TYPE.HOOK]: HookError,
208
- [IRPC_ERROR_TYPE.CALL]: CallError
225
+ [IRPC_ERROR_TYPE.CALL]: CallError,
226
+ [IRPC_ERROR_TYPE.CRUD]: CrudError
209
227
  };
210
228
 
211
229
  //#endregion
212
- export { CALL_ERROR, CallError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError };
230
+ export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError };
package/dist/index.d.ts CHANGED
@@ -1,19 +1,20 @@
1
- import { IRPCCacheEntry, IRPCCacher } from "./cache.js";
2
1
  import { IRPC_BASE_CONTEXT, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT } from "./enum.js";
3
2
  import { IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe } from "./file.js";
4
3
  import { IRPCFilePointer, IRPCFileQueue, IRPCPacketJson, IRPCPacketQueues, IRPC_FILE_IDENTIFIER, PacketStream, decode, encode, isFilePointer } from "./packet.js";
5
- import { IRPCHookArgs, IRPCPackage, IRPCSpecHook, createPackage, intercept } from "./module.js";
4
+ import { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, IRPCCall } from "./call.js";
6
5
  import { IRPCTransport } from "./transport.js";
7
- import { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCDataSchema, IRPCDeclareInit, IRPCDefined, IRPCFunction, IRPCHandler, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCRequests, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig } from "./types.js";
6
+ import { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCCrudField, IRPCCrudMeta, IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDataSchema, IRPCDeclareConfig, IRPCDeclareInit, IRPCDefined, IRPCDriver, IRPCEntityId, IRPCFunction, IRPCHandler, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCRequests, IRPCResponse, IRPCReturnOf, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig } from "./types.js";
8
7
  import { RemoteState, stream } from "./state.js";
9
8
  import { IRPCReader } from "./reader.js";
10
- import { DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, IRPCCall } from "./call.js";
9
+ import { IRPCHookArgs, IRPCPackage, IRPCSpecHook, createPackage, intercept } from "./module.js";
10
+ import { IRPCAdapter } from "./adapter.js";
11
+ import { IRPCCacheEntry, IRPCCacher } from "./cache.js";
11
12
  import { createContext, createContextStore, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext } from "./context.js";
12
13
  import { createCredentials, credential, getCredentials } from "./credential.js";
13
- import { CALL_ERROR, CallError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPCErrorType, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError } from "./error.js";
14
+ import { 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 } from "./error.js";
14
15
  import { IRPCResolver } from "./resolver.js";
15
16
  import { IRPCHook, IRPCRouter } from "./router.js";
16
17
  import { IRPCStream } from "./stream.js";
17
18
  import { IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPC_STORE } from "./store.js";
18
19
  import { plan } from "@anchorlib/core";
19
- export { CALL_ERROR, CallError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCArraySchema, IRPCCacheEntry, IRPCCacher, IRPCCall, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCDataSchema, IRPCDeclareInit, IRPCDefined, IRPCError, IRPCErrorType, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFilePointer, IRPCFileQueue, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe, IRPCFunction, IRPCHandler, IRPCHook, IRPCHookArgs, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackage, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, 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_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, PacketStream, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StreamCleanup, StreamConstructor, StubError, TRANSPORT_ERROR, TransportConfig, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
20
+ export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCAdapter, IRPCArraySchema, IRPCCacheEntry, IRPCCacher, IRPCCall, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCCrudField, IRPCCrudMeta, IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDataSchema, IRPCDeclareConfig, IRPCDeclareInit, IRPCDefined, IRPCDriver, IRPCEntityId, IRPCError, IRPCErrorType, IRPCFile, IRPCFileMeta, IRPCFilePipe, IRPCFilePointer, IRPCFileQueue, IRPCFileState, IRPCFileStatus, IRPCFileStream, IRPCFileUnpipe, IRPCFunction, IRPCHandler, IRPCHook, IRPCHookArgs, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackage, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketJson, IRPCPacketQueues, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCReader, IRPCRequest, IRPCRequests, IRPCResolver, IRPCResponse, IRPCReturnOf, IRPCRouter, IRPCSchema, IRPCSpec, IRPCSpecHook, IRPCSpecStore, IRPCStatus, IRPCStore, IRPCStoreEvent, IRPCStoreSubscriber, IRPCStream, IRPCStreamInit, IRPCStub, IRPCStubStore, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, PacketStream, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StreamCleanup, StreamConstructor, StubError, TRANSPORT_ERROR, TransportConfig, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
+ import { CALL_ERROR, CRUD_ERROR, CallError, CrudError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError } from "./error.js";
2
+ import { IRPCAdapter } from "./adapter.js";
1
3
  import { IRPCCacher } from "./cache.js";
2
4
  import { IRPC_BASE_CONTEXT, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE_EVENT } from "./enum.js";
3
- import { CALL_ERROR, CallError, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCError, IRPC_ERROR_TYPE, RESOLVE_ERROR, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError } from "./error.js";
4
5
  import { createContext, createContextStore, getAbortController, getAbortSignal, getContext, setContext, setContextProvider, withContext } from "./context.js";
5
6
  import { RemoteState, stream } from "./state.js";
6
7
  import { IRPCReader } from "./reader.js";
@@ -14,6 +15,7 @@ import { createCredentials, credential, getCredentials } from "./credential.js";
14
15
  import { IRPCFile, IRPCFileStream } from "./file.js";
15
16
  import { IRPC_FILE_IDENTIFIER, decode, encode, isFilePointer } from "./packet.js";
16
17
  import { IRPCResolver } from "./resolver.js";
18
+ import { IRPCDriver } from "./types.js";
17
19
  import { plan } from "@anchorlib/core";
18
20
 
19
- export { CALL_ERROR, CallError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCCacher, IRPCCall, IRPCError, IRPCFile, IRPCFileStream, IRPCPackage, IRPCReader, IRPCResolver, IRPCRouter, IRPCStore, IRPCStream, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
21
+ export { CALL_ERROR, CRUD_ERROR, CallError, CrudError, DEFAULT_RETRY_DELAY, DEFAULT_RETRY_MODE, HANDLER_ERROR, HOOK_ERROR, HandlerError, HookError, IRPCAdapter, IRPCCacher, IRPCCall, IRPCDriver, IRPCError, IRPCFile, IRPCFileStream, IRPCPackage, IRPCReader, IRPCResolver, IRPCRouter, IRPCStore, IRPCStream, IRPCTransport, IRPC_BASE_CONTEXT, IRPC_ERROR_TYPE, IRPC_FILE_IDENTIFIER, IRPC_FILE_STATUS, IRPC_PACKET_TYPE, IRPC_STATUS, IRPC_STORE, IRPC_STORE_EVENT, RESOLVE_ERROR, RemoteState, ResolveError, STUB_ERROR, StubError, TRANSPORT_ERROR, TransportError, createContext, createContextStore, createCredentials, createPackage, credential, decode, encode, getAbortController, getAbortSignal, getContext, getCredentials, intercept, isFilePointer, plan, setContext, setContextProvider, stream, withContext };
package/dist/module.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IRPCTransport } from "./transport.js";
2
- import { IRPCData, IRPCDeclareInit, IRPCFunction, IRPCHandler, IRPCInputs, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCRequest, IRPCSpec, IRPCStub } from "./types.js";
2
+ import { IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDeclareConfig, IRPCDeclareInit, IRPCFunction, IRPCHandler, IRPCInferInit, IRPCInputs, IRPCObject, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCRequest, IRPCReturnOf, IRPCSpec, IRPCStub } from "./types.js";
3
3
  import { RemoteState } from "./state.js";
4
4
  import { IRPCReader } from "./reader.js";
5
5
 
@@ -17,7 +17,7 @@ type IRPCSpecHook<F$1> = (req: IRPCHookArgs<F$1>) => void | Promise<void>;
17
17
  * and their corresponding stubs. It manages the configuration, transport, and execution
18
18
  * of remote procedure calls.
19
19
  */
20
- declare class IRPCPackage {
20
+ declare class IRPCPackage<K extends string = 'id'> {
21
21
  /**
22
22
  * A map storing all IRPC specifications by their names
23
23
  */
@@ -54,12 +54,38 @@ declare class IRPCPackage {
54
54
  */
55
55
  constructor(config?: Partial<IRPCPackageConfig>);
56
56
  /**
57
- * Declares a new IRPC specification and creates a corresponding stub function
58
- * @param options - The initialization object containing the IRPC specification
59
- * @returns A stub function that can be used to call the IRPC
60
- * @throws Error if an IRPC with the same name already exists
57
+ * Declares a new IRPC specification and returns a callable stub.
58
+ *
59
+ * @param name - The unique name for the IRPC specification.
60
+ * @param seedOrConfig - The initial data seed function, or configuration object.
61
+ * @param config - Optional configuration (if seed was provided).
62
+ * @returns A stub function that can be used to call the IRPC.
63
+ * @throws Error if an IRPC with the same name already exists.
64
+ */
65
+ declare<F, I extends IRPCInputs = IRPCInputs, O extends IRPCOutput = IRPCOutput>(name: string, seedOrConfig: (() => IRPCReturnOf<F>) | (IRPCDeclareConfig<I, O> & IRPCInferInit<IRPCReturnOf<F>>), config?: IRPCDeclareConfig<I, O>): IRPCFunction<F>;
66
+ /**
67
+ * Declares a new IRPC specification and returns a callable stub.
68
+ *
69
+ * @param options - The initialization object containing name, seed, and configuration.
70
+ * @returns A stub function that can be used to call the IRPC.
71
+ * @throws Error if an IRPC with the same name already exists.
61
72
  */
62
73
  declare<F, I extends IRPCInputs = IRPCInputs, O extends IRPCOutput = IRPCOutput>(options: IRPCDeclareInit<F, I, O>): IRPCFunction<F>;
74
+ /**
75
+ * Declares CRUD stubs (get, create, update, delete) for an entity
76
+ * @param name - The entity name used as prefix for stub names
77
+ * @param seed - Factory function returning a default entity instance
78
+ * @param options - Optional configuration for caching, schemas, and call behavior
79
+ * @returns An object containing the four CRUD stub functions
80
+ */
81
+ crud<T extends IRPCObject, I extends IRPCObject = T, U extends IRPCObject = T, CK extends string = K>(name: string, seed: () => T, options?: IRPCCrudOptions): IRPCCrudStubs<T, CK, I, U>;
82
+ /**
83
+ * Removes CRUD methods from a stubs object and unregisters their specs
84
+ * @param stubs - The CRUD stubs object to modify
85
+ * @param keys - The method names to remove
86
+ * @returns The stubs object without the excluded methods
87
+ */
88
+ exclude<S extends object, E extends IRPCCrudMethod>(stubs: S, keys: E[]): Omit<S, E>;
63
89
  /**
64
90
  * Resolves and executes an IRPC call based on a request object
65
91
  * @param req - The request containing the IRPC name and arguments
@@ -76,13 +102,17 @@ declare class IRPCPackage {
76
102
  */
77
103
  construct<F, A extends unknown[], R extends IRPCData>(stub: IRPCStub<F, A, R>, handler: F): this;
78
104
  /**
79
- * Registers a hook function for a specific stub function
80
- * @param stub - The stub function created by declare()
81
- * @param handler - The hook function to register
82
- * @returns This IRPCPackage instance for chaining
83
- * @throws Error if the stub is invalid or if no IRPC exists for the stub
105
+ * Registers a hook for a specific stub.
106
+ * @param stub - The stub function created by declare().
107
+ * @param handler - The hook function to register.
84
108
  */
85
109
  hook<F extends IRPCHandler>(stub: F, handler: IRPCSpecHook<F>): this;
110
+ /**
111
+ * Registers a hook for all stubs in a group (e.g., CRUD).
112
+ * @param stubs - An object whose values are stub functions.
113
+ * @param handler - The hook function to register.
114
+ */
115
+ hook(stubs: Record<string, IRPCHandler>, handler: IRPCSpecHook<IRPCHandler>): this;
86
116
  /**
87
117
  * Resolves and executes all registered hooks for a given request
88
118
  * @param req - The request containing the IRPC name and arguments
@@ -122,7 +152,9 @@ declare class IRPCPackage {
122
152
  * @param config - Optional partial configuration for the package
123
153
  * @returns A new IRPCPackage instance
124
154
  */
125
- declare function createPackage(config?: Partial<IRPCPackageConfig>): IRPCPackage;
155
+ declare function createPackage<K extends string = 'id'>(config?: Partial<IRPCPackageConfig> & {
156
+ key?: K;
157
+ }): IRPCPackage<K>;
126
158
  /**
127
159
  * Intercepts local function call to get an instant response without remote execution.
128
160
  *
package/dist/module.js CHANGED
@@ -1,6 +1,6 @@
1
+ import { HandlerError, ResolveError, StubError, TransportError } from "./error.js";
1
2
  import { IRPCCacher } from "./cache.js";
2
3
  import { IRPC_STATUS } from "./enum.js";
3
- import { HandlerError, ResolveError, StubError, TransportError } from "./error.js";
4
4
  import { getAbortSignal } from "./context.js";
5
5
  import { RemoteState } from "./state.js";
6
6
  import { IRPCReader } from "./reader.js";
@@ -37,6 +37,7 @@ var IRPCPackage = class {
37
37
  config = {
38
38
  name: "global",
39
39
  version: "1.0.0",
40
+ key: "id",
40
41
  timeout: DEFAULT_TIMEOUT
41
42
  };
42
43
  /**
@@ -71,13 +72,18 @@ var IRPCPackage = class {
71
72
  this.configure(config ?? {});
72
73
  IRPC_STORE.register(this);
73
74
  }
74
- /**
75
- * Declares a new IRPC specification and creates a corresponding stub function
76
- * @param options - The initialization object containing the IRPC specification
77
- * @returns A stub function that can be used to call the IRPC
78
- * @throws Error if an IRPC with the same name already exists
79
- */
80
- declare(options) {
75
+ declare(nameOrOptions, seedOrConfig, config) {
76
+ let options;
77
+ if (typeof nameOrOptions === "string") if (typeof seedOrConfig === "function") options = {
78
+ name: nameOrOptions,
79
+ seed: seedOrConfig,
80
+ ...config
81
+ };
82
+ else options = {
83
+ name: nameOrOptions,
84
+ ...seedOrConfig
85
+ };
86
+ else options = nameOrOptions;
81
87
  const $options = options;
82
88
  if (this.specs.has($options.name)) throw StubError.duplicate($options.name);
83
89
  if ($options.init && !$options.seed) $options.seed = $options.init;
@@ -156,22 +162,23 @@ var IRPCPackage = class {
156
162
  const cached = caches.get(callKey);
157
163
  if (cached) return cached.value;
158
164
  if (spec.coalesce !== false && calls.has(callKey)) return calls.get(callKey);
159
- const { timeout, maxRetries, retryDelay, retryMode } = {
165
+ const { timeout, maxRetries, retryDelay, retryMode, standalone } = {
160
166
  ...this.config,
161
167
  ...spec
162
168
  };
163
- const config = {
169
+ const config$1 = {
164
170
  timeout,
165
171
  maxRetries,
166
172
  retryDelay,
167
- retryMode
173
+ retryMode,
174
+ standalone
168
175
  };
169
176
  const hooks = this.hooks.get(spec);
170
177
  if (hooks) hooks.forEach((hook) => hook({
171
178
  name: spec.name,
172
179
  args
173
180
  }));
174
- const call = typeof spec.handler === "function" ? intercept(spec, args, reader) : this.transport.call(spec, args, config, reader);
181
+ const call = typeof spec.handler === "function" ? intercept(spec, args, reader) : this.transport.call(spec, args, config$1, reader);
175
182
  calls.set(callKey, call);
176
183
  if (spec.maxAge) caches.set(callKey, call, spec.maxAge);
177
184
  onCleanup(() => call.close());
@@ -185,6 +192,50 @@ var IRPCPackage = class {
185
192
  return stub;
186
193
  }
187
194
  /**
195
+ * Declares CRUD stubs (get, create, update, delete) for an entity
196
+ * @param name - The entity name used as prefix for stub names
197
+ * @param seed - Factory function returning a default entity instance
198
+ * @param options - Optional configuration for caching, schemas, and call behavior
199
+ * @returns An object containing the four CRUD stub functions
200
+ */
201
+ crud(name, seed, options) {
202
+ const { description, schema, maxAge, coalesce,...callConfig } = options ?? {};
203
+ const desc = (method) => typeof description === "string" ? description : description?.[method];
204
+ const init = (method) => ({
205
+ ...callConfig,
206
+ name: `${name}.${method}`,
207
+ seed,
208
+ description: desc(method),
209
+ schema: schema?.[method],
210
+ ...method === "get" ? { maxAge } : {},
211
+ coalesce
212
+ });
213
+ return {
214
+ get: this.declare(init("get")),
215
+ create: this.declare(init("create")),
216
+ update: this.declare(init("update")),
217
+ delete: this.declare(init("delete"))
218
+ };
219
+ }
220
+ /**
221
+ * Removes CRUD methods from a stubs object and unregisters their specs
222
+ * @param stubs - The CRUD stubs object to modify
223
+ * @param keys - The method names to remove
224
+ * @returns The stubs object without the excluded methods
225
+ */
226
+ exclude(stubs, keys) {
227
+ for (const key of keys) {
228
+ const stub = stubs[key];
229
+ if (stub) {
230
+ const spec = this.stubs.get(stub);
231
+ if (spec) this.specs.delete(spec.name);
232
+ this.stubs.delete(stub);
233
+ }
234
+ delete stubs[key];
235
+ }
236
+ return stubs;
237
+ }
238
+ /**
188
239
  * Resolves and executes an IRPC call based on a request object
189
240
  * @param req - The request containing the IRPC name and arguments
190
241
  * @returns The result of the IRPC execution
@@ -211,21 +262,21 @@ var IRPCPackage = class {
211
262
  spec.handler = handler;
212
263
  return this;
213
264
  }
214
- /**
215
- * Registers a hook function for a specific stub function
216
- * @param stub - The stub function created by declare()
217
- * @param handler - The hook function to register
218
- * @returns This IRPCPackage instance for chaining
219
- * @throws Error if the stub is invalid or if no IRPC exists for the stub
220
- */
221
- hook(stub, handler) {
222
- if (!this.stubs.has(stub)) {
223
- const error = StubError.notFound();
224
- IRPC_STORE.error(error);
265
+ hook(stubOrGroup, handler) {
266
+ if (typeof stubOrGroup === "function") {
267
+ if (!this.stubs.has(stubOrGroup)) {
268
+ const error = StubError.notFound();
269
+ IRPC_STORE.error(error);
270
+ return this;
271
+ }
272
+ const spec = this.stubs.get(stubOrGroup);
273
+ this.hooks.get(spec).add(handler);
225
274
  return this;
226
275
  }
227
- const spec = this.stubs.get(stub);
228
- this.hooks.get(spec).add(handler);
276
+ for (const stub of Object.values(stubOrGroup)) if (typeof stub === "function" && this.stubs.has(stub)) {
277
+ const spec = this.stubs.get(stub);
278
+ this.hooks.get(spec).add(handler);
279
+ }
229
280
  return this;
230
281
  }
231
282
  /**
package/dist/reader.js CHANGED
@@ -1,5 +1,5 @@
1
- import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
1
  import { IRPCError } from "./error.js";
2
+ import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
3
3
  import { RemoteState } from "./state.js";
4
4
  import { replay } from "@anchorlib/core";
5
5
 
@@ -1,5 +1,5 @@
1
- import { IRPCPackage } from "./module.js";
2
1
  import { IRPCDataSchema, IRPCInputs, IRPCOutput, IRPCRequest, IRPCResponse, IRPCSpec } from "./types.js";
2
+ import { IRPCPackage } from "./module.js";
3
3
 
4
4
  //#region src/resolver.d.ts
5
5
 
package/dist/router.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { IRPCPackage } from "./module.js";
2
1
  import { IRPCTransport } from "./transport.js";
3
2
  import { IRPCPacketError, 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>;
package/dist/router.js CHANGED
@@ -1,5 +1,5 @@
1
- import { IRPC_BASE_CONTEXT, IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
1
  import { HookError } from "./error.js";
2
+ import { IRPC_BASE_CONTEXT, IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
3
3
  import { createContextStore, withContext } from "./context.js";
4
4
  import { IRPC_STORE } from "./store.js";
5
5
 
package/dist/state.js CHANGED
@@ -1,5 +1,5 @@
1
- import { IRPC_STATUS } from "./enum.js";
2
1
  import { IRPCError, IRPC_ERROR_TYPE } from "./error.js";
2
+ import { IRPC_STATUS } from "./enum.js";
3
3
  import { getAbortSignal } from "./context.js";
4
4
  import { $do, anchor, mutable, onCleanup, replay, subscribe } from "@anchorlib/core";
5
5
 
package/dist/store.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IRPC_STORE_EVENT } from "./enum.js";
2
- import { IRPCPackage } from "./module.js";
3
2
  import { IRPCData } from "./types.js";
3
+ import { IRPCPackage } from "./module.js";
4
4
  import { IRPCRouter } from "./router.js";
5
5
  import { IRPCStream } from "./stream.js";
6
6
 
@@ -27,7 +27,7 @@ declare class IRPCStore {
27
27
  #private;
28
28
  calls: Set<IRPCStream<IRPCData>>;
29
29
  routers: Set<IRPCRouter>;
30
- packages: Set<IRPCPackage>;
30
+ packages: Set<IRPCPackage<"id">>;
31
31
  callCount: number;
32
32
  errorCount: number;
33
33
  register(pkg: IRPCPackage): void;
package/dist/stream.js CHANGED
@@ -1,5 +1,5 @@
1
- import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
1
  import { CallError, HandlerError, ResolveError } from "./error.js";
2
+ import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
3
3
  import { getAbortController, getAbortSignal } from "./context.js";
4
4
  import { RemoteState } from "./state.js";
5
5
  import { IRPC_STORE } from "./store.js";
@@ -1,7 +1,7 @@
1
- import { IRPCPackage } from "./module.js";
1
+ import { IRPCCall } from "./call.js";
2
2
  import { IRPCCallConfig, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCInputs, IRPCOutput, IRPCSpec, TransportConfig } from "./types.js";
3
3
  import { IRPCReader } from "./reader.js";
4
- import { IRPCCall } from "./call.js";
4
+ import { IRPCPackage } from "./module.js";
5
5
 
6
6
  //#region src/transport.d.ts
7
7
 
@@ -12,7 +12,7 @@ import { IRPCCall } from "./call.js";
12
12
  declare class IRPCTransport {
13
13
  #private;
14
14
  config?: TransportConfig | undefined;
15
- modules: Set<IRPCPackage>;
15
+ modules: Set<IRPCPackage<"id">>;
16
16
  /**
17
17
  * A set of pending RPC calls that are queued for execution.
18
18
  */
@@ -50,13 +50,23 @@ declare class IRPCTransport {
50
50
  */
51
51
  close(call: IRPCCall): void;
52
52
  /**
53
- * Dispatches a batch of RPC calls. This base implementation rejects all calls
54
- * with a "not implemented" error. Subclasses should override this method to
55
- * provide actual transport mechanism.
53
+ * Dispatches RPC calls over the transport. Subclasses must override this
54
+ * to provide the actual transport mechanism (HTTP, WebSocket, etc.).
55
+ *
56
+ * When `standalone` is true, the call requires its own dedicated HTTP
57
+ * round-trip with full response lifecycle (cookies, headers). This is
58
+ * used for operations like authentication where `Set-Cookie` headers
59
+ * must flow back to the client. Only one call is dispatched at a time
60
+ * in standalone mode.
61
+ *
62
+ * When `standalone` is false or undefined, calls may be batched and
63
+ * streamed together in a single request.
64
+ *
56
65
  * @param calls - An array of RPC calls to dispatch.
66
+ * @param standalone - When true, dispatch as a dedicated request with full HTTP lifecycle.
57
67
  * @returns A promise that resolves when all calls have been processed.
58
68
  */
59
- protected dispatch(calls: IRPCCall[]): Promise<void>;
69
+ protected dispatch(calls: IRPCCall[], standalone?: boolean): Promise<void>;
60
70
  }
61
71
  //#endregion
62
72
  export { IRPCTransport };
package/dist/transport.js CHANGED
@@ -1,5 +1,5 @@
1
- import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
2
1
  import { TransportError } from "./error.js";
2
+ import { IRPC_PACKET_TYPE, IRPC_STATUS } from "./enum.js";
3
3
  import { IRPCReader } from "./reader.js";
4
4
  import { IRPC_STORE } from "./store.js";
5
5
  import { IRPCCall } from "./call.js";
@@ -55,8 +55,8 @@ var IRPCTransport = class {
55
55
  retryMode,
56
56
  retryDelay
57
57
  }, reader);
58
- if (spec.stream) {
59
- this.dispatch([call]).finally(() => {}).catch((err) => IRPC_STORE.error(err, [{
58
+ if (spec.stream || config?.standalone) {
59
+ this.dispatch([call], config?.standalone).finally(() => {}).catch((err) => IRPC_STORE.error(err, [{
60
60
  id: call.id,
61
61
  name: call.payload.name
62
62
  }]));
@@ -106,13 +106,23 @@ var IRPCTransport = class {
106
106
  console.log("[irpc] Closing call", call);
107
107
  }
108
108
  /**
109
- * Dispatches a batch of RPC calls. This base implementation rejects all calls
110
- * with a "not implemented" error. Subclasses should override this method to
111
- * provide actual transport mechanism.
109
+ * Dispatches RPC calls over the transport. Subclasses must override this
110
+ * to provide the actual transport mechanism (HTTP, WebSocket, etc.).
111
+ *
112
+ * When `standalone` is true, the call requires its own dedicated HTTP
113
+ * round-trip with full response lifecycle (cookies, headers). This is
114
+ * used for operations like authentication where `Set-Cookie` headers
115
+ * must flow back to the client. Only one call is dispatched at a time
116
+ * in standalone mode.
117
+ *
118
+ * When `standalone` is false or undefined, calls may be batched and
119
+ * streamed together in a single request.
120
+ *
112
121
  * @param calls - An array of RPC calls to dispatch.
122
+ * @param standalone - When true, dispatch as a dedicated request with full HTTP lifecycle.
113
123
  * @returns A promise that resolves when all calls have been processed.
114
124
  */
115
- async dispatch(calls) {
125
+ async dispatch(calls, standalone) {
116
126
  calls.forEach((call) => {
117
127
  call.enqueue({
118
128
  id: call.id,
package/dist/types.d.ts CHANGED
@@ -160,6 +160,8 @@ type IRPCPackageInfo = {
160
160
  description?: string;
161
161
  };
162
162
  type IRPCPackageConfig = IRPCPackageInfo & IRPCCallConfig & {
163
+ /** Primary key field name for CRUD operations. Defaults to 'id'. */
164
+ key?: string;
163
165
  transport?: IRPCTransport;
164
166
  };
165
167
  /**
@@ -214,6 +216,28 @@ type IRPCInferInit<R$1> = R$1 extends IRPCDefined ? {
214
216
  } : {
215
217
  seed?: () => R$1;
216
218
  };
219
+ /**
220
+ * Extracts the data type from a function's return type by unwrapping
221
+ * RemoteState and Promise wrappers.
222
+ *
223
+ * @template F - The function type to extract from.
224
+ */
225
+ type IRPCReturnOf<F> = F extends ((...args: infer _A) => infer R) ? R extends RemoteState<infer S> ? S : R extends Promise<infer D> ? D : R : IRPCData;
226
+ /**
227
+ * Configuration options for the shorthand `declare(name, seed, config?)` overload.
228
+ * Contains all IRPCInit fields except `name` and `seed`.
229
+ *
230
+ * @template I - Tuple of input validation schemas
231
+ * @template O - Output validation schema
232
+ */
233
+ type IRPCDeclareConfig<I extends IRPCInputs = IRPCInputs, O$1 extends IRPCOutput = IRPCOutput> = {
234
+ description?: string;
235
+ schema?: IRPCSchema<I, O$1>;
236
+ maxAge?: number;
237
+ coalesce?: boolean;
238
+ stream?: true;
239
+ ttl?: number;
240
+ } & IRPCCallConfig;
217
241
  /**
218
242
  * Configuration options for initializing an RPC stream function.
219
243
  * Contains metadata and constraints for the RPC stream function.
@@ -234,6 +258,64 @@ type IRPCStreamInit<I extends IRPCInputs, O$1 extends IRPCOutput, R$1> = IRPCIni
234
258
  * @template O - Output validation schema
235
259
  */
236
260
  type IRPCDeclareInit<F, I extends IRPCInputs, O$1 extends IRPCOutput> = F extends ((...args: infer _A) => infer R) ? R extends RemoteState<infer S> ? S extends IRPCData ? IRPCStreamInit<I, O$1, S> : IRPCInit<S, IRPCInputs, IRPCOutput> : R extends Promise<infer D> ? D extends IRPCData ? IRPCInit<D, I, O$1> : IRPCInit<D, IRPCInputs, IRPCOutput> : R extends IRPCData ? IRPCInit<R, I, O$1> : IRPCInit<R, IRPCInputs, IRPCOutput> : IRPCInit<IRPCData, IRPCInputs, IRPCOutput>;
261
+ type IRPCCrudMethod = 'get' | 'create' | 'update' | 'delete';
262
+ /**
263
+ * Discriminated field — shared value or per-operation values.
264
+ */
265
+ type IRPCCrudField<T> = T | {
266
+ get?: T;
267
+ create?: T;
268
+ update?: T;
269
+ delete?: T;
270
+ };
271
+ type IRPCCrudOptions = {
272
+ description?: IRPCCrudField<string>;
273
+ schema?: {
274
+ get?: IRPCSchema<IRPCInputs, IRPCOutput>;
275
+ create?: IRPCSchema<IRPCInputs, IRPCOutput>;
276
+ update?: IRPCSchema<IRPCInputs, IRPCOutput>;
277
+ delete?: IRPCSchema<IRPCInputs, IRPCOutput>;
278
+ };
279
+ /** Cache max age — only applied to get. */
280
+ maxAge?: number;
281
+ coalesce?: boolean;
282
+ } & IRPCCallConfig;
283
+ /**
284
+ * ID type extracted from entity using the key field.
285
+ * Falls back to string if the key doesn't exist on the entity.
286
+ */
287
+ type IRPCEntityId<T, K$1 extends string> = K$1 extends keyof T ? T[K$1] : string;
288
+ type IRPCCrudStubs<T extends IRPCObject, K$1 extends string, I extends IRPCObject = T, U extends IRPCObject = T> = {
289
+ get: IRPCFunction<(id: IRPCEntityId<T, K$1>) => Promise<T> | RemoteState<T>>;
290
+ create: IRPCFunction<(data: I) => Promise<T> | RemoteState<T>>;
291
+ update: IRPCFunction<(id: IRPCEntityId<T, K$1>, data: U) => Promise<T> | RemoteState<T>>;
292
+ delete: IRPCFunction<(id: IRPCEntityId<T, K$1>) => Promise<T> | RemoteState<T>>;
293
+ };
294
+ /**
295
+ * Per-method resolved metadata — discriminated fields flattened,
296
+ * method-specific options applied. Passed to driver on every call.
297
+ */
298
+ type IRPCCrudMeta = {
299
+ /** Entity/table name. */
300
+ name: string;
301
+ /** Primary key field name. */
302
+ key: string;
303
+ /** Resolved description for this method. */
304
+ description?: string;
305
+ /** Resolved schema for this method. */
306
+ schema?: IRPCSchema<IRPCInputs, IRPCOutput>;
307
+ maxAge?: number;
308
+ coalesce?: boolean;
309
+ } & IRPCCallConfig;
310
+ /**
311
+ * Base class for CRUD drivers that receive per-method resolved metadata on every call
312
+ */
313
+ declare abstract class IRPCDriver {
314
+ get?(meta: IRPCCrudMeta, id: IRPCData): Promise<IRPCData> | IRPCData;
315
+ create?(meta: IRPCCrudMeta, data: IRPCData): Promise<IRPCData> | IRPCData;
316
+ update?(meta: IRPCCrudMeta, id: IRPCData, data: IRPCData): Promise<IRPCData> | IRPCData;
317
+ delete?(meta: IRPCCrudMeta, id: IRPCData): Promise<IRPCData> | IRPCData;
318
+ }
237
319
  /**
238
320
  * Complete specification for an RPC function including its implementation.
239
321
  * Extends IRPCInit with the actual handler function.
@@ -314,6 +396,8 @@ type IRPCCallConfig = {
314
396
  retryMode?: 'linear' | 'exponential';
315
397
  /** Base delay between retries in milliseconds */
316
398
  retryDelay?: number;
399
+ /** Optional flag to dispatch the call as a standalone HTTP request with full cookie/header lifecycle */
400
+ standalone?: boolean;
317
401
  };
318
402
  /**
319
403
  * Configuration for transport layer, extending call configuration with debounce settings.
@@ -335,4 +419,4 @@ type StreamCleanup = () => void;
335
419
  */
336
420
  type StreamConstructor<T> = (state: IRPCReadable<T>, resolve: (value?: T) => void, reject: (error: Error) => void) => StreamCleanup | void | Promise<StreamCleanup | void>;
337
421
  //#endregion
338
- export { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCData, IRPCDataSchema, IRPCDeclareInit, IRPCDefined, IRPCFunction, IRPCHandler, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCRequests, IRPCResponse, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig };
422
+ export { IRPCArraySchema, IRPCCallConfig, IRPCContext, IRPCContextProvider, IRPCCredentials, IRPCCredentialsFactory, IRPCCrudField, IRPCCrudMeta, IRPCCrudMethod, IRPCCrudOptions, IRPCCrudStubs, IRPCData, IRPCDataSchema, IRPCDeclareConfig, IRPCDeclareInit, IRPCDefined, IRPCDriver, IRPCEntityId, IRPCFunction, IRPCHandler, IRPCInferInit, IRPCInit, IRPCInputs, IRPCObject, IRPCObjectSchema, IRPCOutput, IRPCPackageConfig, IRPCPackageInfo, IRPCPacketAnswer, IRPCPacketBase, IRPCPacketCall, IRPCPacketClose, IRPCPacketError, IRPCPacketEvent, IRPCPacketStream, IRPCPacketType, IRPCParseResult, IRPCPayload, IRPCPrimitive, IRPCPrimitiveSchema, IRPCReadable, IRPCRequest, IRPCRequests, IRPCResponse, IRPCReturnOf, IRPCSchema, IRPCSpec, IRPCSpecStore, IRPCStatus, IRPCStreamInit, IRPCStub, IRPCStubStore, StreamCleanup, StreamConstructor, TransportConfig };
package/dist/types.js CHANGED
@@ -1 +1,8 @@
1
- export { };
1
+ //#region src/types.ts
2
+ /**
3
+ * Base class for CRUD drivers that receive per-method resolved metadata on every call
4
+ */
5
+ var IRPCDriver = class {};
6
+
7
+ //#endregion
8
+ export { IRPCDriver };
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.25",
4
+ "version": "1.1.0",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/index.js",
7
7
  "exports": {
@@ -36,6 +36,7 @@
36
36
  "zod": "^4.1.5"
37
37
  },
38
38
  "peerDependencies": {
39
+ "@anchorlib/core": "^1.1.0",
39
40
  "typescript": "^5.9.3"
40
41
  },
41
42
  "optionalDependencies": {
@@ -44,14 +45,11 @@
44
45
  "scripts": {
45
46
  "dev": "rimraf dist && tsdown --watch ./src",
46
47
  "clean": "rimraf dist",
47
- "build": "rimraf dist && tsdown && publint",
48
+ "build": "bun run clean && tsdown && publint",
48
49
  "format": "biome format --write",
49
50
  "test": "rimraf coverage && vitest --run",
50
51
  "test:preview": "rimraf coverage && vitest --run && vite preview --outDir coverage",
51
- "prepublish": "bun run format && bun run clean && tsdown && publint"
52
+ "prepublish": "bun run format && bun run build"
52
53
  },
53
- "license": "MIT",
54
- "dependencies": {
55
- "@anchorlib/core": "^1.0.0-beta.25"
56
- }
54
+ "license": "MIT"
57
55
  }