@zudojs/rpc 1.4.2 → 1.5.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.
- package/README.md +22 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/rpc/client/index.d.ts +0 -1
- package/dist/rpc/client/index.js +0 -1
- package/dist/rpc/client/rpcClient.core.d.ts +0 -1
- package/dist/rpc/client/rpcClient.core.js +0 -1
- package/dist/rpc/client/rpcWireError.helper.d.ts +0 -1
- package/dist/rpc/client/rpcWireError.helper.js +0 -1
- package/dist/rpc/constants/index.d.ts +1 -2
- package/dist/rpc/constants/index.js +1 -2
- package/dist/rpc/constants/rpcConstants.core.d.ts +7 -1
- package/dist/rpc/constants/rpcConstants.core.js +7 -1
- package/dist/rpc/context/index.d.ts +0 -1
- package/dist/rpc/context/index.js +0 -1
- package/dist/rpc/context/rpcContext.type.d.ts +0 -1
- package/dist/rpc/context/rpcContext.type.js +0 -1
- package/dist/rpc/dispatcher/index.d.ts +0 -1
- package/dist/rpc/dispatcher/index.js +0 -1
- package/dist/rpc/dispatcher/rpcDispatcher.core.d.ts +0 -1
- package/dist/rpc/dispatcher/rpcDispatcher.core.js +10 -4
- package/dist/rpc/dispatcher/rpcDispatcher.downstream.d.ts +26 -0
- package/dist/rpc/dispatcher/rpcDispatcher.downstream.js +41 -0
- package/dist/rpc/errors/index.d.ts +0 -1
- package/dist/rpc/errors/index.js +0 -1
- package/dist/rpc/errors/rpc.errors.d.ts +0 -1
- package/dist/rpc/errors/rpc.errors.js +0 -1
- package/dist/rpc/errors/rpcErrorCause.helper.d.ts +10 -0
- package/dist/rpc/errors/rpcErrorCause.helper.js +18 -0
- package/dist/rpc/interceptor/index.d.ts +0 -1
- package/dist/rpc/interceptor/index.js +0 -1
- package/dist/rpc/interceptor/rpcInterceptor.type.d.ts +0 -1
- package/dist/rpc/interceptor/rpcInterceptor.type.js +0 -1
- package/dist/rpc/middleware/index.d.ts +0 -1
- package/dist/rpc/middleware/index.js +0 -1
- package/dist/rpc/middleware/rpcMiddleware.core.d.ts +0 -1
- package/dist/rpc/middleware/rpcMiddleware.core.js +0 -1
- package/dist/rpc/procedure/index.d.ts +0 -1
- package/dist/rpc/procedure/index.js +0 -1
- package/dist/rpc/procedure/rpcProcedure.type.d.ts +0 -1
- package/dist/rpc/procedure/rpcProcedure.type.js +0 -1
- package/dist/rpc/procedure/rpcProcedureRegistry.core.d.ts +0 -1
- package/dist/rpc/procedure/rpcProcedureRegistry.core.js +0 -1
- package/dist/rpc/procedure/rpcProcedureRouter.core.d.ts +0 -1
- package/dist/rpc/procedure/rpcProcedureRouter.core.js +0 -1
- package/dist/rpc/reliability/cancellation/rpcAbort.helper.d.ts +0 -1
- package/dist/rpc/reliability/cancellation/rpcAbort.helper.js +0 -1
- package/dist/rpc/reliability/cancellation/rpcCancellation.helper.d.ts +0 -1
- package/dist/rpc/reliability/cancellation/rpcCancellation.helper.js +0 -1
- package/dist/rpc/reliability/deadline/rpcDeadline.helper.d.ts +0 -1
- package/dist/rpc/reliability/deadline/rpcDeadline.helper.js +0 -1
- package/dist/rpc/reliability/index.d.ts +0 -1
- package/dist/rpc/reliability/index.js +0 -1
- package/dist/rpc/reliability/retry/rpcRetry.helper.d.ts +9 -1
- package/dist/rpc/reliability/retry/rpcRetry.helper.js +0 -1
- package/dist/rpc/reliability/timeout/rpcTimeout.helper.d.ts +0 -1
- package/dist/rpc/reliability/timeout/rpcTimeout.helper.js +0 -1
- package/dist/rpc/server/index.d.ts +0 -1
- package/dist/rpc/server/index.js +0 -1
- package/dist/rpc/server/rpcBaseErrorMapping.helper.d.ts +0 -1
- package/dist/rpc/server/rpcBaseErrorMapping.helper.js +0 -1
- package/dist/rpc/server/rpcDownstreamMapping.helper.d.ts +15 -0
- package/dist/rpc/server/rpcDownstreamMapping.helper.js +27 -0
- package/dist/rpc/server/rpcErrorMapping.helper.d.ts +2 -4
- package/dist/rpc/server/rpcErrorMapping.helper.js +6 -4
- package/dist/rpc/server/rpcServer.core.d.ts +0 -1
- package/dist/rpc/server/rpcServer.core.js +0 -1
- package/dist/rpc/streaming/index.d.ts +0 -1
- package/dist/rpc/streaming/index.js +0 -1
- package/dist/rpc/streaming/rpcStreaming.type.d.ts +0 -1
- package/dist/rpc/streaming/rpcStreaming.type.js +0 -1
- package/dist/rpc/transport/codec/index.d.ts +0 -1
- package/dist/rpc/transport/codec/index.js +0 -1
- package/dist/rpc/transport/codec/rpcBody.helper.d.ts +0 -1
- package/dist/rpc/transport/codec/rpcBody.helper.js +0 -1
- package/dist/rpc/transport/codec/rpcCodec.helper.d.ts +0 -1
- package/dist/rpc/transport/codec/rpcCodec.helper.js +0 -1
- package/dist/rpc/transport/http/index.d.ts +0 -1
- package/dist/rpc/transport/http/index.js +0 -1
- package/dist/rpc/transport/http/rpcFetchHandler.core.d.ts +0 -1
- package/dist/rpc/transport/http/rpcFetchHandler.core.js +0 -1
- package/dist/rpc/transport/http/rpcHttpExchange.helper.d.ts +0 -1
- package/dist/rpc/transport/http/rpcHttpExchange.helper.js +1 -10
- package/dist/rpc/transport/http/rpcHttpStatus.helper.d.ts +0 -1
- package/dist/rpc/transport/http/rpcHttpStatus.helper.js +0 -1
- package/dist/rpc/transport/http/rpcHttpTransport.core.d.ts +0 -1
- package/dist/rpc/transport/http/rpcHttpTransport.core.js +0 -1
- package/dist/rpc/transport/index.d.ts +0 -1
- package/dist/rpc/transport/index.js +0 -1
- package/dist/rpc/transport/memory/index.d.ts +0 -1
- package/dist/rpc/transport/memory/index.js +0 -1
- package/dist/rpc/transport/memory/rpcMemoryTransport.core.d.ts +0 -1
- package/dist/rpc/transport/memory/rpcMemoryTransport.core.js +0 -1
- package/dist/rpc/transport/rpcTransport.type.d.ts +0 -1
- package/dist/rpc/transport/rpcTransport.type.js +0 -1
- package/dist/rpc/types/index.d.ts +0 -1
- package/dist/rpc/types/index.js +0 -1
- package/dist/rpc/types/rpcMetadata.type.d.ts +0 -1
- package/dist/rpc/types/rpcMetadata.type.js +0 -1
- package/dist/rpc/types/rpcProcedureName.type.d.ts +0 -1
- package/dist/rpc/types/rpcProcedureName.type.js +0 -1
- package/dist/rpc/types/rpcRequest.type.d.ts +0 -1
- package/dist/rpc/types/rpcRequest.type.js +0 -1
- package/dist/rpc/types/rpcResponse.type.d.ts +0 -1
- package/dist/rpc/types/rpcResponse.type.js +0 -1
- package/dist/rpc/validation/index.d.ts +0 -1
- package/dist/rpc/validation/index.js +0 -1
- package/dist/rpc/validation/rpcValidation.core.d.ts +0 -1
- package/dist/rpc/validation/rpcValidation.core.js +0 -1
- package/dist/testing/index.d.ts +0 -1
- package/dist/testing/index.js +0 -1
- package/package.json +7 -7
- package/dist/rpc/validation/rpcUnsafeKey.helper.d.ts +0 -18
- package/dist/rpc/validation/rpcUnsafeKey.helper.js +0 -60
package/README.md
CHANGED
|
@@ -206,6 +206,14 @@ A pending call's deadline and a `retry()` backoff hold a normal (ref'd)
|
|
|
206
206
|
timer, cleared as soon as the call settles, so a plain script awaiting a call
|
|
207
207
|
stays alive until it resolves or times out.
|
|
208
208
|
|
|
209
|
+
`retry(operation, { attempts, delay, backoff, jitter, retryIf, signal })`
|
|
210
|
+
counts **calls**, not retries: `attempts: 3` runs the operation up to three
|
|
211
|
+
times (one call plus two retries) and `attempts: 1` never retries. This is
|
|
212
|
+
the opposite of `@zudojs/lifecycle`, whose `attempts` counts the retries after
|
|
213
|
+
the first call. `delay` is the base backoff in milliseconds (`"fixed"` by
|
|
214
|
+
default; `"linear"` and `"exponential"` scale it per attempt, capped by
|
|
215
|
+
`maxDelay`), and `jitter` defaults to `"full"`.
|
|
216
|
+
|
|
209
217
|
### Middleware and trusted identity
|
|
210
218
|
|
|
211
219
|
Everything in a frame, `metadata` included, is written by the caller: any
|
|
@@ -274,6 +282,20 @@ generic message. To send a custom code, build the error with `expose: true`. A h
|
|
|
274
282
|
`output` schema is treated the same way: it is the server's fault, not the
|
|
275
283
|
caller's.
|
|
276
284
|
|
|
285
|
+
A failure of something the handler *called* is reported as
|
|
286
|
+
`RPC_UNAVAILABLE`, not as an internal error and not as this procedure's own
|
|
287
|
+
timeout: an `RPCTransportError`, or an `RPCTimeoutError` naming another
|
|
288
|
+
procedure, thrown inside a handler or middleware — what an `RPCClient`
|
|
289
|
+
raises when a downstream service cannot be reached or does not answer — is
|
|
290
|
+
wrapped in an `RPCUnavailableError` (the original as `cause`) and answered
|
|
291
|
+
with `{ code: "RPC_UNAVAILABLE", message: UNAVAILABLE_ERROR_MESSAGE }`, so
|
|
292
|
+
the caller can retry while the downstream error's own text stays out of the
|
|
293
|
+
response; the wrapped error is handed to `onInternalError` for logging. A
|
|
294
|
+
timeout about the procedure itself still goes out as `RPC_TIMEOUT`: the
|
|
295
|
+
dispatcher's own (including when a cooperative handler rethrows
|
|
296
|
+
`context.signal.reason`) and one a handler throws under its own procedure
|
|
297
|
+
name.
|
|
298
|
+
|
|
277
299
|
```typescript
|
|
278
300
|
const server = new RPCServer(undefined, undefined, {
|
|
279
301
|
limits: { maxPayloadBytes: 256 * 1024, maxRequestIdLength: 128 },
|
package/dist/index.d.ts
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
export type { RPCProcedureName, RPCMetadata, RPCMetadataOptions, RPCRequest, RPCRequestOptions, RPCErrorPayload, RPCResponse, } from "./rpc/types/index.js";
|
|
29
29
|
export { createRPCMetadata, createRPCRequest, createRPCResponse, createRPCErrorResponse, } from "./rpc/types/index.js";
|
|
30
|
-
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpc/constants/index.js";
|
|
30
|
+
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, UNAVAILABLE_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpc/constants/index.js";
|
|
31
31
|
export type { RPCRequestLimits, RPCSchema } from "./rpc/validation/index.js";
|
|
32
32
|
export { assertValidProcedureName, assertValidRequest, measurePayloadBytes, toValidationIssues, parseInput, parseOutput, } from "./rpc/validation/index.js";
|
|
33
33
|
export type { RPCErrorOptions } from "./rpc/errors/index.js";
|
|
@@ -50,4 +50,3 @@ export type { RPCInterceptor } from "./rpc/interceptor/index.js";
|
|
|
50
50
|
export { createNoopRPCInterceptor } from "./rpc/interceptor/index.js";
|
|
51
51
|
export type { RPCStreamingHandler, RPCStreamingProcedure, } from "./rpc/streaming/index.js";
|
|
52
52
|
export { createRPCStreamingProcedure } from "./rpc/streaming/index.js";
|
|
53
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*/
|
|
28
28
|
export { createRPCMetadata, createRPCRequest, createRPCResponse, createRPCErrorResponse, } from "./rpc/types/index.js";
|
|
29
29
|
// Constants
|
|
30
|
-
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpc/constants/index.js";
|
|
30
|
+
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, UNAVAILABLE_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpc/constants/index.js";
|
|
31
31
|
export { assertValidProcedureName, assertValidRequest, measurePayloadBytes, toValidationIssues, parseInput, parseOutput, } from "./rpc/validation/index.js";
|
|
32
32
|
export { RPCError, RPCProcedureNotFoundError, RPCInvalidRequestError, RPCValidationError, RPCAuthenticationError, RPCForbiddenError, RPCTimeoutError, RPCCancelledError, RPCInternalError, RPCTransportError, RPCSerializationError, RPCDeserializationError, RPCUnavailableError, RPCRateLimitedError, RPCDeadlineExceededError, RPCDuplicateProcedureError, createRPCError, isRPCError, } from "./rpc/errors/index.js";
|
|
33
33
|
export { createRPCProcedure } from "./rpc/procedure/index.js";
|
|
@@ -44,4 +44,3 @@ export * from "./rpc/client/index.js";
|
|
|
44
44
|
export { createTimeout, withTimeout, runWithTimeout, getRemainingTime, isDeadlineExceeded, throwIfDeadlineExceeded, readDeadline, createCancellableSignal, cancelSignal, throwIfCancelled, combineSignals, DEFAULT_RETRY_OPTIONS, calculateRetryDelay, retry, } from "./rpc/reliability/index.js";
|
|
45
45
|
export { createNoopRPCInterceptor } from "./rpc/interceptor/index.js";
|
|
46
46
|
export { createRPCStreamingProcedure } from "./rpc/streaming/index.js";
|
|
47
|
-
//# sourceMappingURL=index.js.map
|
package/dist/rpc/client/index.js
CHANGED
|
@@ -3,5 +3,4 @@
|
|
|
3
3
|
* and frame sizes, procedure-name rules, and the fixed internal-error
|
|
4
4
|
* message returned to remote callers.
|
|
5
5
|
*/
|
|
6
|
-
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpcConstants.core.js";
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
|
6
|
+
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, UNAVAILABLE_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpcConstants.core.js";
|
|
@@ -3,5 +3,4 @@
|
|
|
3
3
|
* and frame sizes, procedure-name rules, and the fixed internal-error
|
|
4
4
|
* message returned to remote callers.
|
|
5
5
|
*/
|
|
6
|
-
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpcConstants.core.js";
|
|
7
|
-
//# sourceMappingURL=index.js.map
|
|
6
|
+
export { DEFAULT_RPC_TIMEOUT, MAX_RPC_PAYLOAD_SIZE, MAX_RPC_REQUEST_ID_LENGTH, MAX_PENDING_REQUESTS, MAX_MIDDLEWARE, MAX_PROCEDURES, MAX_PROCEDURE_NAME_LENGTH, MAX_TIMER_DELAY, PROCEDURE_NAME_PATTERN, INTERNAL_ERROR_MESSAGE, UNAVAILABLE_ERROR_MESSAGE, DEFAULT_RPC_HTTP_MAX_BODY_BYTES, MAX_RPC_FRAME_DEPTH, } from "./rpcConstants.core.js";
|
|
@@ -54,6 +54,13 @@ export declare const MAX_TIMER_DELAY = 2147483647;
|
|
|
54
54
|
* request id instead.
|
|
55
55
|
*/
|
|
56
56
|
export declare const INTERNAL_ERROR_MESSAGE = "The server encountered an internal error while handling this request.";
|
|
57
|
+
/**
|
|
58
|
+
* Message sent with `RPC_UNAVAILABLE` when a handler failed because a
|
|
59
|
+
* service it called — over RPC or otherwise — could not be reached or
|
|
60
|
+
* timed out. The downstream error's own text (hosts, paths, timeouts) is
|
|
61
|
+
* server detail and goes to `onInternalError` instead.
|
|
62
|
+
*/
|
|
63
|
+
export declare const UNAVAILABLE_ERROR_MESSAGE = "A service this request depends on is temporarily unavailable.";
|
|
57
64
|
/**
|
|
58
65
|
* Default limit, in bytes, on an HTTP request or response body carrying
|
|
59
66
|
* one RPC frame: the payload limit plus headroom for the frame envelope
|
|
@@ -65,4 +72,3 @@ export declare const DEFAULT_RPC_HTTP_MAX_BODY_BYTES: number;
|
|
|
65
72
|
* Bounds the work a hostile peer can force with deeply nested JSON.
|
|
66
73
|
*/
|
|
67
74
|
export declare const MAX_RPC_FRAME_DEPTH = 128;
|
|
68
|
-
//# sourceMappingURL=rpcConstants.core.d.ts.map
|
|
@@ -54,6 +54,13 @@ export const MAX_TIMER_DELAY = 2_147_483_647;
|
|
|
54
54
|
* request id instead.
|
|
55
55
|
*/
|
|
56
56
|
export const INTERNAL_ERROR_MESSAGE = "The server encountered an internal error while handling this request.";
|
|
57
|
+
/**
|
|
58
|
+
* Message sent with `RPC_UNAVAILABLE` when a handler failed because a
|
|
59
|
+
* service it called — over RPC or otherwise — could not be reached or
|
|
60
|
+
* timed out. The downstream error's own text (hosts, paths, timeouts) is
|
|
61
|
+
* server detail and goes to `onInternalError` instead.
|
|
62
|
+
*/
|
|
63
|
+
export const UNAVAILABLE_ERROR_MESSAGE = "A service this request depends on is temporarily unavailable.";
|
|
57
64
|
/**
|
|
58
65
|
* Default limit, in bytes, on an HTTP request or response body carrying
|
|
59
66
|
* one RPC frame: the payload limit plus headroom for the frame envelope
|
|
@@ -65,4 +72,3 @@ export const DEFAULT_RPC_HTTP_MAX_BODY_BYTES = MAX_RPC_PAYLOAD_SIZE + 64 * 1024;
|
|
|
65
72
|
* Bounds the work a hostile peer can force with deeply nested JSON.
|
|
66
73
|
*/
|
|
67
74
|
export const MAX_RPC_FRAME_DEPTH = 128;
|
|
68
|
-
//# sourceMappingURL=rpcConstants.core.js.map
|
|
@@ -61,4 +61,3 @@ export declare function bindRPCContextInput(context: RPCContext, input: unknown)
|
|
|
61
61
|
* Creates a new RPC context.
|
|
62
62
|
*/
|
|
63
63
|
export declare function createRPCContext(request: RPCRequest, signal: AbortSignal, options?: RPCContextOptions): RPCContext;
|
|
64
|
-
//# sourceMappingURL=rpcContext.type.d.ts.map
|
|
@@ -5,6 +5,7 @@ import { DEFAULT_RPC_TIMEOUT } from "../constants/rpcConstants.core.js";
|
|
|
5
5
|
import { parseInput, parseOutput } from "../validation/rpcValidation.core.js";
|
|
6
6
|
import { readDeadline, throwIfDeadlineExceeded, } from "../reliability/deadline/rpcDeadline.helper.js";
|
|
7
7
|
import { createTimeout } from "../reliability/timeout/rpcTimeout.helper.js";
|
|
8
|
+
import { toUpstreamError } from "./rpcDispatcher.downstream.js";
|
|
8
9
|
import { abortReasonToRPCError, raceAbort, } from "../reliability/cancellation/rpcAbort.helper.js";
|
|
9
10
|
/**
|
|
10
11
|
* Dispatches RPC requests to registered procedures.
|
|
@@ -66,9 +67,15 @@ export class RPCDispatcher {
|
|
|
66
67
|
? parseInput(procedure.options.input, request.payload, request.procedure)
|
|
67
68
|
: request.payload;
|
|
68
69
|
bindRPCContextInput(context, input);
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
let result;
|
|
71
|
+
try {
|
|
72
|
+
result = await this.middleware.execute(context, async () => {
|
|
73
|
+
return procedure.handler(input, context);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
throw toUpstreamError(error, request.procedure, controller.signal);
|
|
78
|
+
}
|
|
72
79
|
return procedure.options?.output
|
|
73
80
|
? parseOutput(procedure.options.output, result, request.procedure)
|
|
74
81
|
: result;
|
|
@@ -148,4 +155,3 @@ export class RPCDispatcher {
|
|
|
148
155
|
return configured;
|
|
149
156
|
}
|
|
150
157
|
}
|
|
151
|
-
//# sourceMappingURL=rpcDispatcher.core.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation of downstream failures raised inside a handler.
|
|
3
|
+
*
|
|
4
|
+
* A handler that calls another service over RPC gets that client's errors:
|
|
5
|
+
* an `RPCTransportError` when the peer could not be reached, an
|
|
6
|
+
* `RPCTimeoutError` when it did not answer in time. Rethrown as they are,
|
|
7
|
+
* the transport error went out as `RPC_INTERNAL_ERROR` (its code is not
|
|
8
|
+
* public vocabulary) and the timeout as `RPC_TIMEOUT` — which told the
|
|
9
|
+
* caller *this* procedure had timed out, when it was a dependency that had.
|
|
10
|
+
* Both are one condition from the caller's point of view: the service is
|
|
11
|
+
* unavailable right now, and the call may be retried.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Returns the error a handler's failure should propagate as.
|
|
15
|
+
*
|
|
16
|
+
* A downstream failure becomes an `RPCUnavailableError` with the original
|
|
17
|
+
* as `cause`; the server maps it to `RPC_UNAVAILABLE` and hands the cause
|
|
18
|
+
* to `onInternalError`. Downstream means an `RPCTransportError` (only a
|
|
19
|
+
* transport raises one) or an `RPCTimeoutError` that names a procedure
|
|
20
|
+
* other than this one — an `RPCClient` stamps the procedure it was calling
|
|
21
|
+
* on every timeout it raises. A timeout about this procedure — the
|
|
22
|
+
* dispatcher's own, which a cooperative handler rethrows from
|
|
23
|
+
* `context.signal.reason`, or one a handler throws under its own name —
|
|
24
|
+
* stays `RPC_TIMEOUT`, as does everything else.
|
|
25
|
+
*/
|
|
26
|
+
export declare function toUpstreamError(error: unknown, procedureName: string, signal: AbortSignal): unknown;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation of downstream failures raised inside a handler.
|
|
3
|
+
*
|
|
4
|
+
* A handler that calls another service over RPC gets that client's errors:
|
|
5
|
+
* an `RPCTransportError` when the peer could not be reached, an
|
|
6
|
+
* `RPCTimeoutError` when it did not answer in time. Rethrown as they are,
|
|
7
|
+
* the transport error went out as `RPC_INTERNAL_ERROR` (its code is not
|
|
8
|
+
* public vocabulary) and the timeout as `RPC_TIMEOUT` — which told the
|
|
9
|
+
* caller *this* procedure had timed out, when it was a dependency that had.
|
|
10
|
+
* Both are one condition from the caller's point of view: the service is
|
|
11
|
+
* unavailable right now, and the call may be retried.
|
|
12
|
+
*/
|
|
13
|
+
import { RPCTimeoutError, RPCTransportError, RPCUnavailableError, } from "../errors/rpc.errors.js";
|
|
14
|
+
import { withCause } from "../errors/rpcErrorCause.helper.js";
|
|
15
|
+
import { UNAVAILABLE_ERROR_MESSAGE } from "../constants/rpcConstants.core.js";
|
|
16
|
+
/**
|
|
17
|
+
* Returns the error a handler's failure should propagate as.
|
|
18
|
+
*
|
|
19
|
+
* A downstream failure becomes an `RPCUnavailableError` with the original
|
|
20
|
+
* as `cause`; the server maps it to `RPC_UNAVAILABLE` and hands the cause
|
|
21
|
+
* to `onInternalError`. Downstream means an `RPCTransportError` (only a
|
|
22
|
+
* transport raises one) or an `RPCTimeoutError` that names a procedure
|
|
23
|
+
* other than this one — an `RPCClient` stamps the procedure it was calling
|
|
24
|
+
* on every timeout it raises. A timeout about this procedure — the
|
|
25
|
+
* dispatcher's own, which a cooperative handler rethrows from
|
|
26
|
+
* `context.signal.reason`, or one a handler throws under its own name —
|
|
27
|
+
* stays `RPC_TIMEOUT`, as does everything else.
|
|
28
|
+
*/
|
|
29
|
+
export function toUpstreamError(error, procedureName, signal) {
|
|
30
|
+
if (signal.aborted && error === signal.reason) {
|
|
31
|
+
return error;
|
|
32
|
+
}
|
|
33
|
+
const downstream = error instanceof RPCTransportError ||
|
|
34
|
+
(error instanceof RPCTimeoutError &&
|
|
35
|
+
error.procedureName !== undefined &&
|
|
36
|
+
error.procedureName !== procedureName);
|
|
37
|
+
if (downstream) {
|
|
38
|
+
return withCause(new RPCUnavailableError(UNAVAILABLE_ERROR_MESSAGE, procedureName), error);
|
|
39
|
+
}
|
|
40
|
+
return error;
|
|
41
|
+
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export { RPCError, RPCProcedureNotFoundError, RPCInvalidRequestError, RPCValidationError, RPCAuthenticationError, RPCForbiddenError, RPCTimeoutError, RPCCancelledError, RPCInternalError, RPCTransportError, RPCSerializationError, RPCDeserializationError, RPCUnavailableError, RPCRateLimitedError, RPCDeadlineExceededError, RPCDuplicateProcedureError, createRPCError, isRPCError, } from "./rpc.errors.js";
|
|
2
2
|
export type { RPCErrorOptions } from "./rpc.errors.js";
|
|
3
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/rpc/errors/index.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
1
|
export { RPCError, RPCProcedureNotFoundError, RPCInvalidRequestError, RPCValidationError, RPCAuthenticationError, RPCForbiddenError, RPCTimeoutError, RPCCancelledError, RPCInternalError, RPCTransportError, RPCSerializationError, RPCDeserializationError, RPCUnavailableError, RPCRateLimitedError, RPCDeadlineExceededError, RPCDuplicateProcedureError, createRPCError, isRPCError, } from "./rpc.errors.js";
|
|
2
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export { RPCError, RPCProcedureNotFoundError, RPCInvalidRequestError, RPCValidationError, RPCAuthenticationError, RPCForbiddenError, RPCTimeoutError, RPCCancelledError, RPCInternalError, RPCTransportError, RPCSerializationError, RPCDeserializationError, RPCUnavailableError, RPCRateLimitedError, RPCDeadlineExceededError, RPCDuplicateProcedureError, createRPCError, isRPCError, } from "@zudojs/errors";
|
|
2
2
|
export type { RPCErrorOptions } from "@zudojs/errors";
|
|
3
|
-
//# sourceMappingURL=rpc.errors.d.ts.map
|
|
@@ -1,2 +1 @@
|
|
|
1
1
|
export { RPCError, RPCProcedureNotFoundError, RPCInvalidRequestError, RPCValidationError, RPCAuthenticationError, RPCForbiddenError, RPCTimeoutError, RPCCancelledError, RPCInternalError, RPCTransportError, RPCSerializationError, RPCDeserializationError, RPCUnavailableError, RPCRateLimitedError, RPCDeadlineExceededError, RPCDuplicateProcedureError, createRPCError, isRPCError, } from "@zudojs/errors";
|
|
2
|
-
//# sourceMappingURL=rpc.errors.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attaches a cause to an error whose constructor takes none.
|
|
3
|
+
*
|
|
4
|
+
* The `@zudojs/errors` RPC classes fix their options in the constructor, so
|
|
5
|
+
* an error that wraps another (a transport failure wrapping a fetch error,
|
|
6
|
+
* an unavailable error wrapping a downstream timeout) gets its `cause` set
|
|
7
|
+
* afterwards. Non-enumerable, like the platform's own `Error.cause`, so it
|
|
8
|
+
* is not serialized by accident.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withCause<T extends Error>(error: T, cause: unknown): T;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attaches a cause to an error whose constructor takes none.
|
|
3
|
+
*
|
|
4
|
+
* The `@zudojs/errors` RPC classes fix their options in the constructor, so
|
|
5
|
+
* an error that wraps another (a transport failure wrapping a fetch error,
|
|
6
|
+
* an unavailable error wrapping a downstream timeout) gets its `cause` set
|
|
7
|
+
* afterwards. Non-enumerable, like the platform's own `Error.cause`, so it
|
|
8
|
+
* is not serialized by accident.
|
|
9
|
+
*/
|
|
10
|
+
export function withCause(error, cause) {
|
|
11
|
+
Object.defineProperty(error, "cause", {
|
|
12
|
+
value: cause,
|
|
13
|
+
enumerable: false,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
});
|
|
17
|
+
return error;
|
|
18
|
+
}
|
|
@@ -2,4 +2,3 @@ export type { RPCHandler, RPCProcedure, RPCProcedureOptions, } from "./rpcProced
|
|
|
2
2
|
export { createRPCProcedure } from "./rpcProcedure.type.js";
|
|
3
3
|
export { RPCProcedureRegistry } from "./rpcProcedureRegistry.core.js";
|
|
4
4
|
export { RPCProcedureRouter } from "./rpcProcedureRouter.core.js";
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -46,4 +46,3 @@ export interface RPCProcedure<TInput = unknown, TOutput = unknown> {
|
|
|
46
46
|
* Creates a new RPC procedure.
|
|
47
47
|
*/
|
|
48
48
|
export declare function createRPCProcedure<TInput = unknown, TOutput = unknown>(name: RPCProcedureName, handler: RPCHandler<TInput, TOutput>, options?: RPCProcedureOptions<TInput, TOutput>): RPCProcedure<TInput, TOutput>;
|
|
49
|
-
//# sourceMappingURL=rpcProcedure.type.d.ts.map
|
|
@@ -14,4 +14,3 @@ export declare function abortReasonToRPCError(signal: AbortSignal, procedureName
|
|
|
14
14
|
* Settles with `promise`, or rejects as soon as `signal` aborts.
|
|
15
15
|
*/
|
|
16
16
|
export declare function raceAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined, procedureName?: string): Promise<T>;
|
|
17
|
-
//# sourceMappingURL=rpcAbort.helper.d.ts.map
|
|
@@ -4,4 +4,3 @@ export type { CancellableSignal } from "./cancellation/rpcCancellation.helper.js
|
|
|
4
4
|
export { createCancellableSignal, cancelSignal, throwIfCancelled, combineSignals, } from "./cancellation/rpcCancellation.helper.js";
|
|
5
5
|
export type { RPCBackoff, RPCJitter, RPCRetryOptions, } from "./retry/rpcRetry.helper.js";
|
|
6
6
|
export { DEFAULT_RETRY_OPTIONS, calculateRetryDelay, retry, } from "./retry/rpcRetry.helper.js";
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -2,4 +2,3 @@ export { createTimeout, withTimeout, runWithTimeout, } from "./timeout/rpcTimeou
|
|
|
2
2
|
export { getRemainingTime, isDeadlineExceeded, throwIfDeadlineExceeded, readDeadline, } from "./deadline/rpcDeadline.helper.js";
|
|
3
3
|
export { createCancellableSignal, cancelSignal, throwIfCancelled, combineSignals, } from "./cancellation/rpcCancellation.helper.js";
|
|
4
4
|
export { DEFAULT_RETRY_OPTIONS, calculateRetryDelay, retry, } from "./retry/rpcRetry.helper.js";
|
|
5
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -15,7 +15,16 @@ export type RPCJitter = "none" | "full" | "equal";
|
|
|
15
15
|
* Retry options.
|
|
16
16
|
*/
|
|
17
17
|
export interface RPCRetryOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Total number of calls, not the number of retries: `attempts: 3` calls
|
|
20
|
+
* the operation up to three times (one call plus two retries), and
|
|
21
|
+
* `attempts: 1` never retries. Values below 1 are treated as 1.
|
|
22
|
+
*
|
|
23
|
+
* Note that `@zudojs/lifecycle` counts the other way — its `attempts`
|
|
24
|
+
* is the number of retries after the first call.
|
|
25
|
+
*/
|
|
18
26
|
readonly attempts: number;
|
|
27
|
+
/** Base delay before a retry, in milliseconds; see `backoff`. */
|
|
19
28
|
readonly delay: number;
|
|
20
29
|
readonly maxDelay?: number;
|
|
21
30
|
readonly backoff?: RPCBackoff;
|
|
@@ -51,4 +60,3 @@ export declare function calculateRetryDelay(attempt: number, options: RPCRetryOp
|
|
|
51
60
|
* failing dependency do not synchronise into a retry wave.
|
|
52
61
|
*/
|
|
53
62
|
export declare function retry<T>(operation: () => Promise<T>, options: RPCRetryOptions): Promise<T>;
|
|
54
|
-
//# sourceMappingURL=rpcRetry.helper.d.ts.map
|
|
@@ -29,4 +29,3 @@ export declare function withTimeout<T>(promise: Promise<T>, duration: number, pr
|
|
|
29
29
|
* stop its own work rather than continuing unobserved.
|
|
30
30
|
*/
|
|
31
31
|
export declare function runWithTimeout<T>(operation: (signal: AbortSignal) => Promise<T>, duration: number, procedureName?: string, parentSignal?: AbortSignal): Promise<T>;
|
|
32
|
-
//# sourceMappingURL=rpcTimeout.helper.d.ts.map
|
|
@@ -6,4 +6,3 @@ export type { RPCServerOptions } from "./rpcServer.core.js";
|
|
|
6
6
|
export { RPCServer } from "./rpcServer.core.js";
|
|
7
7
|
export type { RPCMappedError } from "./rpcErrorMapping.helper.js";
|
|
8
8
|
export { mapRPCError } from "./rpcErrorMapping.helper.js";
|
|
9
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/rpc/server/index.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire mapping for failures of something the server itself called.
|
|
3
|
+
*
|
|
4
|
+
* A transport failure inside a handler is a dependency the server could not
|
|
5
|
+
* reach, not a fault of the request: `RPC_UNAVAILABLE`, so the caller may
|
|
6
|
+
* retry, with the transport's own text (hosts, paths) withheld. An
|
|
7
|
+
* `RPCUnavailableError` carrying a `cause` is the dispatcher's wrap of such
|
|
8
|
+
* a failure; its cause is worth logging, so it is reported as internal too.
|
|
9
|
+
*/
|
|
10
|
+
import type { RPCMappedError } from "./rpcErrorMapping.helper.js";
|
|
11
|
+
/**
|
|
12
|
+
* Maps a downstream failure onto `RPC_UNAVAILABLE`, marked internal so the
|
|
13
|
+
* original reaches `onInternalError`; `undefined` for anything else.
|
|
14
|
+
*/
|
|
15
|
+
export declare function mapDownstreamError(error: Error): RPCMappedError | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire mapping for failures of something the server itself called.
|
|
3
|
+
*
|
|
4
|
+
* A transport failure inside a handler is a dependency the server could not
|
|
5
|
+
* reach, not a fault of the request: `RPC_UNAVAILABLE`, so the caller may
|
|
6
|
+
* retry, with the transport's own text (hosts, paths) withheld. An
|
|
7
|
+
* `RPCUnavailableError` carrying a `cause` is the dispatcher's wrap of such
|
|
8
|
+
* a failure; its cause is worth logging, so it is reported as internal too.
|
|
9
|
+
*/
|
|
10
|
+
import { RPCTransportError, RPCUnavailableError, } from "../errors/rpc.errors.js";
|
|
11
|
+
import { UNAVAILABLE_ERROR_MESSAGE } from "../constants/rpcConstants.core.js";
|
|
12
|
+
/**
|
|
13
|
+
* Maps a downstream failure onto `RPC_UNAVAILABLE`, marked internal so the
|
|
14
|
+
* original reaches `onInternalError`; `undefined` for anything else.
|
|
15
|
+
*/
|
|
16
|
+
export function mapDownstreamError(error) {
|
|
17
|
+
if (error instanceof RPCTransportError) {
|
|
18
|
+
return unavailable(UNAVAILABLE_ERROR_MESSAGE);
|
|
19
|
+
}
|
|
20
|
+
if (error instanceof RPCUnavailableError && error.cause !== undefined) {
|
|
21
|
+
return unavailable(error.message);
|
|
22
|
+
}
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
function unavailable(message) {
|
|
26
|
+
return { payload: { code: "RPC_UNAVAILABLE", message }, internal: true };
|
|
27
|
+
}
|