@restatedev/restate-sdk 0.7.3-worker → 0.8.1
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/LICENSE +1 -1
- package/README.md +29 -51
- package/dist/clients/workflow_client.d.ts +77 -0
- package/dist/clients/workflow_client.d.ts.map +1 -0
- package/dist/clients/workflow_client.js +172 -0
- package/dist/clients/workflow_client.js.map +1 -0
- package/dist/connection/buffered_connection.js +44 -0
- package/dist/connection/buffered_connection.js.map +1 -0
- package/dist/connection/connection.js +13 -0
- package/dist/connection/connection.js.map +1 -0
- package/dist/connection/embedded_connection.js +59 -0
- package/dist/connection/embedded_connection.js.map +1 -0
- package/dist/connection/http_connection.js +203 -0
- package/dist/connection/http_connection.js.map +1 -0
- package/dist/connection/lambda_connection.js +58 -0
- package/dist/connection/lambda_connection.js.map +1 -0
- package/dist/{restate_context.d.ts → context.d.ts} +239 -170
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +113 -0
- package/dist/context.js.map +1 -0
- package/dist/{restate_context_impl.d.ts → context_impl.d.ts} +26 -30
- package/dist/context_impl.d.ts.map +1 -0
- package/dist/context_impl.js +439 -0
- package/dist/context_impl.js.map +1 -0
- package/dist/embedded/api.d.ts +2 -2
- package/dist/embedded/api.d.ts.map +1 -1
- package/dist/embedded/api.js +35 -0
- package/dist/embedded/api.js.map +1 -0
- package/dist/embedded/handler.d.ts +2 -2
- package/dist/embedded/handler.d.ts.map +1 -1
- package/dist/embedded/handler.js +26 -0
- package/dist/embedded/handler.js.map +1 -0
- package/dist/embedded/http2_remote.js +91 -0
- package/dist/embedded/http2_remote.js.map +1 -0
- package/dist/embedded/invocation.d.ts.map +1 -1
- package/dist/embedded/invocation.js +94 -0
- package/dist/embedded/invocation.js.map +1 -0
- package/dist/endpoint/endpoint_impl.d.ts +35 -0
- package/dist/endpoint/endpoint_impl.d.ts.map +1 -0
- package/dist/endpoint/endpoint_impl.js +405 -0
- package/dist/endpoint/endpoint_impl.js.map +1 -0
- package/dist/endpoint/http2_handler.d.ts +11 -0
- package/dist/endpoint/http2_handler.d.ts.map +1 -0
- package/dist/endpoint/http2_handler.js +119 -0
- package/dist/endpoint/http2_handler.js.map +1 -0
- package/dist/endpoint/lambda_handler.d.ts +15 -0
- package/dist/endpoint/lambda_handler.d.ts.map +1 -0
- package/dist/endpoint/lambda_handler.js +144 -0
- package/dist/endpoint/lambda_handler.js.map +1 -0
- package/dist/endpoint.d.ts +161 -0
- package/dist/endpoint.d.ts.map +1 -0
- package/dist/endpoint.js +22 -0
- package/dist/endpoint.js.map +1 -0
- package/dist/generated/dev/restate/events.js +371 -0
- package/dist/generated/dev/restate/events.js.map +1 -0
- package/dist/generated/dev/restate/ext.js +215 -0
- package/dist/generated/dev/restate/ext.js.map +1 -0
- package/dist/generated/google/protobuf/descriptor.js +6676 -0
- package/dist/generated/google/protobuf/descriptor.js.map +1 -0
- package/dist/generated/google/protobuf/empty.js +107 -0
- package/dist/generated/google/protobuf/empty.js.map +1 -0
- package/dist/generated/google/protobuf/struct.js +754 -0
- package/dist/generated/google/protobuf/struct.js.map +1 -0
- package/dist/generated/proto/discovery.js +364 -0
- package/dist/generated/proto/discovery.js.map +1 -0
- package/dist/generated/proto/dynrpc.js +668 -0
- package/dist/generated/proto/dynrpc.js.map +1 -0
- package/dist/generated/proto/javascript.d.ts +13 -0
- package/dist/generated/proto/javascript.d.ts.map +1 -1
- package/dist/generated/proto/javascript.js +416 -0
- package/dist/generated/proto/javascript.js.map +1 -0
- package/dist/generated/proto/protocol.d.ts +43 -0
- package/dist/generated/proto/protocol.d.ts.map +1 -1
- package/dist/generated/proto/protocol.js +2641 -0
- package/dist/generated/proto/protocol.js.map +1 -0
- package/dist/generated/proto/services.js +1535 -0
- package/dist/generated/proto/services.js.map +1 -0
- package/dist/generated/proto/test.js +321 -0
- package/dist/generated/proto/test.js.map +1 -0
- package/dist/invocation.d.ts +4 -1
- package/dist/invocation.d.ts.map +1 -1
- package/dist/invocation.js +157 -0
- package/dist/invocation.js.map +1 -0
- package/dist/io/decoder.d.ts +1 -0
- package/dist/io/decoder.d.ts.map +1 -1
- package/dist/io/decoder.js +140 -0
- package/dist/io/decoder.js.map +1 -0
- package/dist/io/encoder.d.ts +1 -2
- package/dist/io/encoder.d.ts.map +1 -1
- package/dist/io/encoder.js +68 -0
- package/dist/io/encoder.js.map +1 -0
- package/dist/journal.d.ts +13 -4
- package/dist/journal.d.ts.map +1 -1
- package/dist/journal.js +405 -0
- package/dist/journal.js.map +1 -0
- package/dist/local_state_store.d.ts +5 -3
- package/dist/local_state_store.d.ts.map +1 -1
- package/dist/local_state_store.js +82 -0
- package/dist/local_state_store.js.map +1 -0
- package/dist/logger.d.ts +19 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +90 -0
- package/dist/logger.js.map +1 -0
- package/dist/promise_combinator_tracker.d.ts +29 -0
- package/dist/promise_combinator_tracker.d.ts.map +1 -0
- package/dist/promise_combinator_tracker.js +128 -0
- package/dist/promise_combinator_tracker.js.map +1 -0
- package/dist/public_api.d.ts +5 -5
- package/dist/public_api.d.ts.map +1 -1
- package/dist/public_api.js +60 -0
- package/dist/public_api.js.map +1 -0
- package/dist/state_machine.d.ts +19 -12
- package/dist/state_machine.d.ts.map +1 -1
- package/dist/state_machine.js +437 -0
- package/dist/state_machine.js.map +1 -0
- package/dist/types/errors.d.ts +12 -3
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +273 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/grpc.d.ts +6 -4
- package/dist/types/grpc.d.ts.map +1 -1
- package/dist/types/grpc.js +81 -0
- package/dist/types/grpc.js.map +1 -0
- package/dist/types/protocol.d.ts +9 -5
- package/dist/types/protocol.d.ts.map +1 -1
- package/dist/types/protocol.js +147 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/router.d.ts +8 -8
- package/dist/types/router.d.ts.map +1 -1
- package/dist/types/router.js +36 -0
- package/dist/types/router.js.map +1 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +138 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/{assumpsions.d.ts → assumptions.d.ts} +1 -1
- package/dist/utils/{assumpsions.d.ts.map → assumptions.d.ts.map} +1 -1
- package/dist/utils/assumptions.js +101 -0
- package/dist/utils/assumptions.js.map +1 -0
- package/dist/utils/message_logger.d.ts +28 -0
- package/dist/utils/message_logger.d.ts.map +1 -0
- package/dist/utils/message_logger.js +88 -0
- package/dist/utils/message_logger.js.map +1 -0
- package/dist/utils/promises.d.ts +15 -0
- package/dist/utils/promises.d.ts.map +1 -0
- package/dist/utils/promises.js +67 -0
- package/dist/utils/promises.js.map +1 -0
- package/dist/utils/public_utils.js +49 -0
- package/dist/utils/public_utils.js.map +1 -0
- package/dist/utils/rand.d.ts +1 -1
- package/dist/utils/rand.d.ts.map +1 -1
- package/dist/utils/rand.js +114 -0
- package/dist/utils/rand.js.map +1 -0
- package/dist/utils/utils.d.ts +1 -10
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +122 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/workflows/workflow.d.ts +101 -0
- package/dist/workflows/workflow.d.ts.map +1 -0
- package/dist/workflows/workflow.js +80 -0
- package/dist/workflows/workflow.js.map +1 -0
- package/dist/workflows/workflow_state_service.d.ts +35 -0
- package/dist/workflows/workflow_state_service.d.ts.map +1 -0
- package/dist/workflows/workflow_state_service.js +201 -0
- package/dist/workflows/workflow_state_service.js.map +1 -0
- package/dist/workflows/workflow_wrapper_service.d.ts +10 -0
- package/dist/workflows/workflow_wrapper_service.d.ts.map +1 -0
- package/dist/workflows/workflow_wrapper_service.js +264 -0
- package/dist/workflows/workflow_wrapper_service.js.map +1 -0
- package/package.json +38 -39
- package/src/clients/workflow_client.ts +290 -0
- package/src/connection/buffered_connection.ts +47 -0
- package/src/connection/connection.ts +34 -0
- package/src/connection/embedded_connection.ts +62 -0
- package/src/connection/http_connection.ts +228 -0
- package/src/connection/lambda_connection.ts +69 -0
- package/src/context.ts +633 -0
- package/src/context_impl.ts +721 -0
- package/src/embedded/api.ts +57 -0
- package/src/embedded/handler.ts +36 -0
- package/src/embedded/http2_remote.ts +103 -0
- package/src/embedded/invocation.ts +126 -0
- package/src/endpoint/endpoint_impl.ts +623 -0
- package/src/endpoint/http2_handler.ts +151 -0
- package/src/endpoint/lambda_handler.ts +181 -0
- package/src/endpoint.ts +187 -0
- package/src/generated/dev/restate/events.ts +430 -0
- package/src/generated/dev/restate/ext.ts +238 -0
- package/src/generated/google/protobuf/descriptor.ts +7889 -0
- package/src/generated/google/protobuf/empty.ts +150 -0
- package/src/generated/google/protobuf/struct.ts +878 -0
- package/src/generated/proto/discovery.ts +423 -0
- package/src/generated/proto/dynrpc.ts +768 -0
- package/src/generated/proto/javascript.ts +488 -0
- package/src/generated/proto/protocol.ts +3091 -0
- package/src/generated/proto/services.ts +1834 -0
- package/src/generated/proto/test.ts +387 -0
- package/src/invocation.ts +212 -0
- package/src/io/decoder.ts +171 -0
- package/src/io/encoder.ts +72 -0
- package/src/journal.ts +537 -0
- package/src/local_state_store.ts +94 -0
- package/src/logger.ts +121 -0
- package/src/promise_combinator_tracker.ts +191 -0
- package/src/public_api.ts +53 -0
- package/src/state_machine.ts +635 -0
- package/src/types/errors.ts +297 -0
- package/src/types/grpc.ts +97 -0
- package/src/types/protocol.ts +201 -0
- package/src/types/router.ts +118 -0
- package/src/types/types.ts +160 -0
- package/src/utils/assumptions.ts +131 -0
- package/src/utils/message_logger.ts +112 -0
- package/src/utils/promises.ts +118 -0
- package/src/utils/public_utils.ts +91 -0
- package/src/utils/rand.ts +142 -0
- package/src/utils/utils.ts +178 -0
- package/src/workflows/workflow.ts +178 -0
- package/src/workflows/workflow_state_service.ts +299 -0
- package/src/workflows/workflow_wrapper_service.ts +314 -0
- package/dist/cloudflare_bundle.js +0 -27387
- package/dist/restate_context.d.ts.map +0 -1
- package/dist/restate_context_impl.d.ts.map +0 -1
- package/dist/server/base_restate_server.d.ts +0 -32
- package/dist/server/base_restate_server.d.ts.map +0 -1
- package/dist/server/restate_lambda_handler.d.ts +0 -104
- package/dist/server/restate_lambda_handler.d.ts.map +0 -1
- package/dist/server/restate_server.d.ts +0 -97
- package/dist/server/restate_server.d.ts.map +0 -1
- package/dist/utils/logger.d.ts +0 -60
- package/dist/utils/logger.d.ts.map +0 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
|
|
3
|
+
*
|
|
4
|
+
* This file is part of the Restate SDK for Node.js/TypeScript,
|
|
5
|
+
* which is released under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* You can find a copy of the license in file LICENSE in the root
|
|
8
|
+
* directory of this repository or package, or at
|
|
9
|
+
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { Connection } from "./connection";
|
|
13
|
+
import { encodeMessage } from "../io/encoder";
|
|
14
|
+
import {
|
|
15
|
+
ERROR_MESSAGE_TYPE,
|
|
16
|
+
OUTPUT_STREAM_ENTRY_MESSAGE_TYPE,
|
|
17
|
+
SUSPENSION_MESSAGE_TYPE,
|
|
18
|
+
} from "../types/protocol";
|
|
19
|
+
import { Message } from "../types/types";
|
|
20
|
+
import { rlog } from "../logger";
|
|
21
|
+
|
|
22
|
+
const RESOLVED: Promise<void> = Promise.resolve();
|
|
23
|
+
|
|
24
|
+
export class LambdaConnection implements Connection {
|
|
25
|
+
// Empty buffer to store journal output messages
|
|
26
|
+
private outputBuffer: Buffer = Buffer.alloc(0);
|
|
27
|
+
|
|
28
|
+
// Callback to resolve the invocation promise of the Lambda handler when the response is ready
|
|
29
|
+
private readonly completionPromise: Promise<Buffer>;
|
|
30
|
+
private resolveOnCompleted!: (value: Buffer | PromiseLike<Buffer>) => void;
|
|
31
|
+
|
|
32
|
+
constructor(private suspendedOrCompleted = false) {
|
|
33
|
+
// Promise that signals when the invocation is over, to then flush the messages
|
|
34
|
+
this.completionPromise = new Promise<Buffer>((resolve) => {
|
|
35
|
+
this.resolveOnCompleted = resolve;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Send a message back to the runtime
|
|
40
|
+
send(msg: Message): Promise<void> {
|
|
41
|
+
// Add the header and the body to buffer and add to the output buffer
|
|
42
|
+
const msgBuffer = encodeMessage(msg);
|
|
43
|
+
this.outputBuffer = Buffer.concat([this.outputBuffer, msgBuffer]);
|
|
44
|
+
|
|
45
|
+
// An output message, suspension message or error message is the end of a Lambda invocation
|
|
46
|
+
if (
|
|
47
|
+
msg.messageType === OUTPUT_STREAM_ENTRY_MESSAGE_TYPE ||
|
|
48
|
+
msg.messageType === SUSPENSION_MESSAGE_TYPE ||
|
|
49
|
+
msg.messageType === ERROR_MESSAGE_TYPE
|
|
50
|
+
) {
|
|
51
|
+
this.suspendedOrCompleted = true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return RESOLVED;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getResult(): Promise<Buffer> {
|
|
58
|
+
return this.completionPromise;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
end(): Promise<void> {
|
|
62
|
+
if (this.suspendedOrCompleted) {
|
|
63
|
+
rlog.debug("Flushing output buffer...");
|
|
64
|
+
this.resolveOnCompleted(this.outputBuffer);
|
|
65
|
+
}
|
|
66
|
+
this.outputBuffer = Buffer.alloc(0);
|
|
67
|
+
return RESOLVED;
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/context.ts
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2024 - Restate Software, Inc., Restate GmbH
|
|
3
|
+
*
|
|
4
|
+
* This file is part of the Restate SDK for Node.js/TypeScript,
|
|
5
|
+
* which is released under the MIT license.
|
|
6
|
+
*
|
|
7
|
+
* You can find a copy of the license in file LICENSE in the root
|
|
8
|
+
* directory of this repository or package, or at
|
|
9
|
+
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { RetrySettings } from "./utils/public_utils";
|
|
13
|
+
import { Client, SendClient } from "./types/router";
|
|
14
|
+
import { ContextImpl } from "./context_impl";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Key value store operations. Only keyed services have an attached key-value store.
|
|
18
|
+
*/
|
|
19
|
+
export interface KeyValueStore {
|
|
20
|
+
/**
|
|
21
|
+
* Get/retrieve state from the Restate runtime.
|
|
22
|
+
* Note that state objects are serialized with `Buffer.from(JSON.stringify(theObject))`
|
|
23
|
+
* and deserialized with `JSON.parse(value.toString()) as T`.
|
|
24
|
+
*
|
|
25
|
+
* @param name key of the state to retrieve
|
|
26
|
+
* @returns a Promise that is resolved with the value of the state key
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* const ctx = restate.useContext(this);
|
|
30
|
+
* const state = await ctx.get<string>("STATE");
|
|
31
|
+
*/
|
|
32
|
+
get<T>(name: string): Promise<T | null>;
|
|
33
|
+
|
|
34
|
+
stateKeys(): Promise<Array<string>>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Set/store state in the Restate runtime.
|
|
38
|
+
* Note that state objects are serialized with `Buffer.from(JSON.stringify(theObject))`
|
|
39
|
+
* and deserialized with `JSON.parse(value.toString()) as T`.
|
|
40
|
+
*
|
|
41
|
+
* @param name key of the state to set
|
|
42
|
+
* @param value value to set
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const ctx = restate.useContext(this);
|
|
46
|
+
* ctx.set("STATE", "Hello");
|
|
47
|
+
*/
|
|
48
|
+
set<T>(name: string, value: T): void;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Clear/delete state in the Restate runtime.
|
|
52
|
+
* @param name key of the state to delete
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* const ctx = restate.useContext(this);
|
|
56
|
+
* ctx.clear("STATE");
|
|
57
|
+
*/
|
|
58
|
+
clear(name: string): void;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Clear/delete all the state entries in the Restate runtime.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const ctx = restate.useContext(this);
|
|
65
|
+
* ctx.clearAll();
|
|
66
|
+
*/
|
|
67
|
+
clearAll(): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The context that gives access to all Restate-backed operations, for example
|
|
72
|
+
* - sending reliable messages / RPC through Restate
|
|
73
|
+
* - side effects
|
|
74
|
+
* - sleeps and delayed calls
|
|
75
|
+
* - awakeables
|
|
76
|
+
* - ...
|
|
77
|
+
*
|
|
78
|
+
* Keyed services can also access their key-value store using the {@link KeyedContext}.
|
|
79
|
+
*
|
|
80
|
+
* In gRPC-based API, to access this context, use {@link useContext}.
|
|
81
|
+
*/
|
|
82
|
+
export interface Context {
|
|
83
|
+
/**
|
|
84
|
+
* The unique id that identifies the current function invocation. This id is guaranteed to be
|
|
85
|
+
* unique across invocations, but constant across reties and suspensions.
|
|
86
|
+
*/
|
|
87
|
+
id: Buffer;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Name of the service.
|
|
91
|
+
*/
|
|
92
|
+
serviceName: string;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Deterministic random methods; these are inherently predictable (seeded on the invocation ID, which is not secret)
|
|
96
|
+
* and so should not be used for any cryptographic purposes. They are useful for identifiers, idempotency keys,
|
|
97
|
+
* and for uniform sampling from a set of options. If a cryptographically secure value is needed, please generate that
|
|
98
|
+
* externally and capture the result with a side effect.
|
|
99
|
+
*
|
|
100
|
+
* Calls to these methods from inside side effects are disallowed and will fail - side effects must be idempotent, and
|
|
101
|
+
* these calls are not.
|
|
102
|
+
*/
|
|
103
|
+
rand: Rand;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Console to use for logging. It attaches to each log message some contextual information,
|
|
107
|
+
* such as invoked service method and invocation id, and automatically excludes logs during replay.
|
|
108
|
+
*/
|
|
109
|
+
console: Console;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Execute a side effect and store the result in Restate. The side effect will thus not
|
|
113
|
+
* be re-executed during a later replay, but take the durable result from Restate.
|
|
114
|
+
*
|
|
115
|
+
* Side effects let you capture potentially non-deterministic computation and interaction
|
|
116
|
+
* with external systems in a safe way.
|
|
117
|
+
*
|
|
118
|
+
* Failure semantics of side effects are:
|
|
119
|
+
* - If a side effect executed and persisted before, the result (value or Error) will be
|
|
120
|
+
* taken from the Restate journal.
|
|
121
|
+
* - There is a small window where a side effect may be re-executed twice, if a failure
|
|
122
|
+
* occurred between execution and persisting the result.
|
|
123
|
+
* - No second side effect will be executed while a previous side effect's result is not
|
|
124
|
+
* yet durable. That way, side effects that build on top of each other can assume
|
|
125
|
+
* deterministic results from previous effects, and at most one side effect will be
|
|
126
|
+
* re-executed on replay (the latest, if the failure happened in the small windows
|
|
127
|
+
* described above).
|
|
128
|
+
*
|
|
129
|
+
* This function takes an optional retry policy, that determines what happens if the
|
|
130
|
+
* side effect throws an error. The default retry policy retries infinitely, with exponential
|
|
131
|
+
* backoff and uses suspending sleep for the wait times between retries.
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* const ctx = restate.useContext(this);
|
|
135
|
+
* const result = await ctx.sideEffect(async () => someExternalAction() )
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* const paymentAction = async () => {
|
|
139
|
+
* const result = await paymentClient.call(txId, methodIdentifier, amount);
|
|
140
|
+
* if (result.error) {
|
|
141
|
+
* throw result.error;
|
|
142
|
+
* } else {
|
|
143
|
+
* return result.payment_accepted;
|
|
144
|
+
* }
|
|
145
|
+
* }
|
|
146
|
+
* const paymentAccepted: boolean =
|
|
147
|
+
* await ctx.sideEffect(paymentAction, { maxRetries: 10});
|
|
148
|
+
*
|
|
149
|
+
* @param fn The function to run as a side effect.
|
|
150
|
+
* @param retryPolicy The optional policy describing how retries happen.
|
|
151
|
+
*/
|
|
152
|
+
sideEffect<T>(fn: () => Promise<T>, retryPolicy?: RetrySettings): Promise<T>;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Register an awakeable and pause the processing until the awakeable ID (and optional payload) have been returned to the service
|
|
156
|
+
* (via ctx.completeAwakeable(...)). The SDK deserializes the payload with `JSON.parse(result.toString()) as T`.
|
|
157
|
+
* @returns
|
|
158
|
+
* - id: the string ID that has to be used to complete the awakaeble by some external service
|
|
159
|
+
* - promise: the Promise that needs to be awaited and that is resolved with the payload that was supplied by the service which completed the awakeable
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* const ctx = restate.useContext(this);
|
|
163
|
+
* const awakeable = ctx.awakeable<string>();
|
|
164
|
+
*
|
|
165
|
+
* // send the awakeable ID to some external service that will wake this one back up
|
|
166
|
+
* // The ID can be retrieved by:
|
|
167
|
+
* const id = awakeable.id;
|
|
168
|
+
*
|
|
169
|
+
* // ... send to external service ...
|
|
170
|
+
*
|
|
171
|
+
* // Wait for the external service to wake this service back up
|
|
172
|
+
* const result = await awakeable.promise;
|
|
173
|
+
*/
|
|
174
|
+
awakeable<T>(): { id: string; promise: CombineablePromise<T> };
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Resolve an awakeable of another service.
|
|
178
|
+
* @param id the string ID of the awakeable.
|
|
179
|
+
* This is supplied by the service that needs to be woken up.
|
|
180
|
+
* @param payload the payload to pass to the service that is woken up.
|
|
181
|
+
* The SDK serializes the payload with `Buffer.from(JSON.stringify(payload))`
|
|
182
|
+
* and deserializes it in the receiving service with `JSON.parse(result.toString()) as T`.
|
|
183
|
+
*
|
|
184
|
+
* @example
|
|
185
|
+
* const ctx = restate.useContext(this);
|
|
186
|
+
* // The sleeping service should have sent the awakeableIdentifier string to this service.
|
|
187
|
+
* ctx.resolveAwakeable(awakeableIdentifier, "hello");
|
|
188
|
+
*/
|
|
189
|
+
resolveAwakeable<T>(id: string, payload?: T): void;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Reject an awakeable of another service. When rejecting, the service waiting on this awakeable will be woken up with a terminal error with the provided reason.
|
|
193
|
+
* @param id the string ID of the awakeable.
|
|
194
|
+
* This is supplied by the service that needs to be woken up.
|
|
195
|
+
* @param reason the reason of the rejection.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* const ctx = restate.useContext(this);
|
|
199
|
+
* // The sleeping service should have sent the awakeableIdentifier string to this service.
|
|
200
|
+
* ctx.rejectAwakeable(awakeableIdentifier, "super bad error");
|
|
201
|
+
*/
|
|
202
|
+
rejectAwakeable(id: string, reason: string): void;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Sleep until a timeout has passed.
|
|
206
|
+
* @param millis duration of the sleep in millis.
|
|
207
|
+
* This is a lower-bound.
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* const ctx = restate.useContext(this);
|
|
211
|
+
* await ctx.sleep(1000);
|
|
212
|
+
*/
|
|
213
|
+
sleep(millis: number): CombineablePromise<void>;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Makes a type-safe request/response RPC to the specified target service.
|
|
217
|
+
*
|
|
218
|
+
* The RPC goes through Restate and is guaranteed to be reliably delivered. The RPC is also
|
|
219
|
+
* journaled for durable execution and will thus not be duplicated when the handler is re-invoked
|
|
220
|
+
* for retries or after suspending.
|
|
221
|
+
*
|
|
222
|
+
* This call will return the result produced by the target handler, or the Error, if the target
|
|
223
|
+
* handler finishes with a Terminal Error.
|
|
224
|
+
*
|
|
225
|
+
* This call is a suspension point: The handler might suspend while awaiting the response and
|
|
226
|
+
* resume once the response is available.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* *Service Side:*
|
|
230
|
+
* ```ts
|
|
231
|
+
* const router = restate.router({
|
|
232
|
+
* someAction: async(ctx: restate.RpcContext, req: string) => { ... },
|
|
233
|
+
* anotherAction: async(ctx: restate.RpcContext, count: number) => { ... }
|
|
234
|
+
* });
|
|
235
|
+
*
|
|
236
|
+
* // option 1: export only the type signature of the router
|
|
237
|
+
* export type myApiType = typeof router;
|
|
238
|
+
*
|
|
239
|
+
* // option 2: export the API definition with type and name (path)
|
|
240
|
+
* export const myApi: restate.ServiceApi<typeof router> = { path : "myservice" };
|
|
241
|
+
*
|
|
242
|
+
* restate.createServer().bindRouter("myservice", router).listen(9080);
|
|
243
|
+
* ```
|
|
244
|
+
* **Client side:**
|
|
245
|
+
* ```ts
|
|
246
|
+
* // option 1: use only types and supply service name separately
|
|
247
|
+
* const result1 = await ctx.rpc<myApiType>({path: "myservice"}).someAction("hello!");
|
|
248
|
+
*
|
|
249
|
+
* // option 2: use full API spec
|
|
250
|
+
* const result2 = await ctx.rpc(myApi).anotherAction(1337);
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
rpc<M>(opts: ServiceApi<M>): Client<M>;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Makes a type-safe one-way RPC to the specified target service. This method effectively behaves
|
|
257
|
+
* like enqueuing the message in a message queue.
|
|
258
|
+
*
|
|
259
|
+
* The message goes through Restate and is guaranteed to be reliably delivered. The RPC is also
|
|
260
|
+
* journaled for durable execution and will thus not be duplicated when the handler is re-invoked
|
|
261
|
+
* for retries or after suspending.
|
|
262
|
+
*
|
|
263
|
+
* This call will return immediately; the message sending happens asynchronously in the background.
|
|
264
|
+
* Despite that, the message is guaranteed to be sent, because the completion of the invocation that
|
|
265
|
+
* triggers the send (calls this function) happens logically after the sending. That means that any
|
|
266
|
+
* failure where the message does not reach Restate also cannot complete this invocation, and will
|
|
267
|
+
* hence recover this handler and (through the durable execution) recover the message to be sent.
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* *Service Side:*
|
|
271
|
+
* ```ts
|
|
272
|
+
* const router = restate.router({
|
|
273
|
+
* someAction: async(ctx: restate.RpcContext, req: string) => { ... },
|
|
274
|
+
* anotherAction: async(ctx: restate.RpcContext, count: number) => { ... }
|
|
275
|
+
* });
|
|
276
|
+
*
|
|
277
|
+
* // option 1: export only the type signature of the router
|
|
278
|
+
* export type myApiType = typeof router;
|
|
279
|
+
*
|
|
280
|
+
* // option 2: export the API definition with type and name (path)
|
|
281
|
+
* export const myApi: restate.ServiceApi<typeof router> = { path : "myservice" };
|
|
282
|
+
*
|
|
283
|
+
* restate.createServer().bindRouter("myservice", router).listen(9080);
|
|
284
|
+
* ```
|
|
285
|
+
* **Client side:**
|
|
286
|
+
* ```ts
|
|
287
|
+
* // option 1: use only types and supply service name separately
|
|
288
|
+
* ctx.send<myApiType>({path: "myservice"}).someAction("hello!");
|
|
289
|
+
*
|
|
290
|
+
* // option 2: use full API spec
|
|
291
|
+
* ctx.send(myApi).anotherAction(1337);
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
send<M>(opts: ServiceApi<M>): SendClient<M>;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Makes a type-safe one-way RPC to the specified target service, after a delay specified by the
|
|
298
|
+
* milliseconds' argument.
|
|
299
|
+
* This method is like stetting up a fault-tolerant cron job that enqueues the message in a
|
|
300
|
+
* message queue.
|
|
301
|
+
* The handler calling this function does not have to stay active for the delay time.
|
|
302
|
+
*
|
|
303
|
+
* Both the delay timer and the message are durably stored in Restate and guaranteed to be reliably
|
|
304
|
+
* delivered. The delivery happens no earlier than specified through the delay, but may happen
|
|
305
|
+
* later, if the target service is down, or backpressuring the system.
|
|
306
|
+
*
|
|
307
|
+
* The delay message is journaled for durable execution and will thus not be duplicated when the
|
|
308
|
+
* handler is re-invoked for retries or after suspending.
|
|
309
|
+
*
|
|
310
|
+
* This call will return immediately; the message sending happens asynchronously in the background.
|
|
311
|
+
* Despite that, the message is guaranteed to be sent, because the completion of the invocation that
|
|
312
|
+
* triggers the send (calls this function) happens logically after the sending. That means that any
|
|
313
|
+
* failure where the message does not reach Restate also cannot complete this invocation, and will
|
|
314
|
+
* hence recover this handler and (through the durable execution) recover the message to be sent.
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* *Service Side:*
|
|
318
|
+
* ```ts
|
|
319
|
+
* const router = restate.router({
|
|
320
|
+
* someAction: async(ctx: restate.RpcContext, req: string) => { ... },
|
|
321
|
+
* anotherAction: async(ctx: restate.RpcContext, count: number) => { ... }
|
|
322
|
+
* });
|
|
323
|
+
*
|
|
324
|
+
* // option 1: export only the type signature of the router
|
|
325
|
+
* export type myApiType = typeof router;
|
|
326
|
+
*
|
|
327
|
+
* // option 2: export the API definition with type and name (path)
|
|
328
|
+
* export const myApi: restate.ServiceApi<typeof router> = { path : "myservice" };
|
|
329
|
+
*
|
|
330
|
+
* restate.createServer().bindRouter("myservice", router).listen(9080);
|
|
331
|
+
* ```
|
|
332
|
+
* **Client side:**
|
|
333
|
+
* ```ts
|
|
334
|
+
* // option 1: use only types and supply service name separately
|
|
335
|
+
* ctx.sendDelayed<myApiType>({path: "myservice"}, 60_000).someAction("hello!");
|
|
336
|
+
*
|
|
337
|
+
* // option 2: use full API spec
|
|
338
|
+
* ctx.sendDelayed(myApi, 60_000).anotherAction(1337);
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
sendDelayed<M>(opts: ServiceApi<M>, delay: number): SendClient<M>;
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Get the {@link RestateGrpcChannel} to invoke gRPC based services.
|
|
345
|
+
*/
|
|
346
|
+
grpcChannel(): RestateGrpcChannel;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* The context that gives access to all Restate-backed operations, for example
|
|
351
|
+
* - sending reliable messages / RPC through Restate
|
|
352
|
+
* - access/update state
|
|
353
|
+
* - side effects
|
|
354
|
+
* - sleeps and delayed calls
|
|
355
|
+
* - awakeables
|
|
356
|
+
* - ...
|
|
357
|
+
*
|
|
358
|
+
* This context can be used only within keyed services/routers.
|
|
359
|
+
*
|
|
360
|
+
* In gRPC-based API, to access this context, use {@link useKeyedContext}.
|
|
361
|
+
*/
|
|
362
|
+
export interface KeyedContext extends Context, KeyValueStore {}
|
|
363
|
+
|
|
364
|
+
export interface Rand {
|
|
365
|
+
/**
|
|
366
|
+
* Equivalent of JS `Math.random()` but deterministic; seeded by the invocation ID of the current invocation,
|
|
367
|
+
* each call will return a new pseudorandom float within the range [0,1)
|
|
368
|
+
*/
|
|
369
|
+
random(): number;
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Using the same random source and seed as random(), produce a UUID version 4 string. This is inherently predictable
|
|
373
|
+
* based on the invocation ID and should not be used in cryptographic contexts
|
|
374
|
+
*/
|
|
375
|
+
uuidv4(): string;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* A promise that can be combined using Promise combinators in RestateContext.
|
|
380
|
+
*/
|
|
381
|
+
export type CombineablePromise<T> = Promise<T> & {
|
|
382
|
+
__restate_context: Context;
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Creates a promise that awaits for the current promise up to the specified timeout duration.
|
|
386
|
+
* If the timeout is fired, this Promise will be rejected with a {@link TimeoutError}.
|
|
387
|
+
*
|
|
388
|
+
* @param millis duration of the sleep in millis.
|
|
389
|
+
* This is a lower-bound.
|
|
390
|
+
*/
|
|
391
|
+
orTimeout(millis: number): Promise<T>;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
export const CombineablePromise = {
|
|
395
|
+
/**
|
|
396
|
+
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
|
397
|
+
* resolve, or rejected when any Promise is rejected.
|
|
398
|
+
*
|
|
399
|
+
* See {@link Promise.all} for more details.
|
|
400
|
+
*
|
|
401
|
+
* @param values An iterable of Promises.
|
|
402
|
+
* @returns A new Promise.
|
|
403
|
+
*/
|
|
404
|
+
all<T extends readonly CombineablePromise<unknown>[] | []>(
|
|
405
|
+
values: T
|
|
406
|
+
): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }> {
|
|
407
|
+
if (values.length == 0) {
|
|
408
|
+
return Promise.all(values);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return (values[0].__restate_context as ContextImpl).createCombinator(
|
|
412
|
+
Promise.all.bind(Promise),
|
|
413
|
+
values
|
|
414
|
+
) as Promise<{
|
|
415
|
+
-readonly [P in keyof T]: Awaited<T[P]>;
|
|
416
|
+
}>;
|
|
417
|
+
},
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
|
421
|
+
* or rejected.
|
|
422
|
+
*
|
|
423
|
+
* See {@link Promise.race} for more details.
|
|
424
|
+
*
|
|
425
|
+
* @param values An iterable of Promises.
|
|
426
|
+
* @returns A new Promise.
|
|
427
|
+
*/
|
|
428
|
+
race<T extends readonly CombineablePromise<unknown>[] | []>(
|
|
429
|
+
values: T
|
|
430
|
+
): Promise<Awaited<T[number]>> {
|
|
431
|
+
if (values.length == 0) {
|
|
432
|
+
return Promise.race(values);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return (values[0].__restate_context as ContextImpl).createCombinator(
|
|
436
|
+
Promise.race.bind(Promise),
|
|
437
|
+
values
|
|
438
|
+
) as Promise<Awaited<T[number]>>;
|
|
439
|
+
},
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Creates a promise that fulfills when any of the input's promises fulfills, with this first fulfillment value.
|
|
443
|
+
* It rejects when all the input's promises reject (including when an empty iterable is passed),
|
|
444
|
+
* with an AggregateError containing an array of rejection reasons.
|
|
445
|
+
*
|
|
446
|
+
* See {@link Promise.any} for more details.
|
|
447
|
+
*
|
|
448
|
+
* @param values An iterable of Promises.
|
|
449
|
+
* @returns A new Promise.
|
|
450
|
+
*/
|
|
451
|
+
any<T extends readonly CombineablePromise<unknown>[] | []>(
|
|
452
|
+
values: T
|
|
453
|
+
): Promise<Awaited<T[number]>> {
|
|
454
|
+
if (values.length == 0) {
|
|
455
|
+
return Promise.any(values);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return (values[0].__restate_context as ContextImpl).createCombinator(
|
|
459
|
+
Promise.any.bind(Promise),
|
|
460
|
+
values
|
|
461
|
+
) as Promise<Awaited<T[number]>>;
|
|
462
|
+
},
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Creates a promise that fulfills when all the input's promises settle (including when an empty iterable is passed),
|
|
466
|
+
* with an array of objects that describe the outcome of each promise.
|
|
467
|
+
*
|
|
468
|
+
* See {@link Promise.allSettled} for more details.
|
|
469
|
+
*
|
|
470
|
+
* @param values An iterable of Promises.
|
|
471
|
+
* @returns A new Promise.
|
|
472
|
+
*/
|
|
473
|
+
allSettled<T extends readonly CombineablePromise<unknown>[] | []>(
|
|
474
|
+
values: T
|
|
475
|
+
): Promise<{
|
|
476
|
+
-readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>;
|
|
477
|
+
}> {
|
|
478
|
+
if (values.length == 0) {
|
|
479
|
+
return Promise.allSettled(values);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return (values[0].__restate_context as ContextImpl).createCombinator(
|
|
483
|
+
Promise.allSettled.bind(Promise),
|
|
484
|
+
values
|
|
485
|
+
) as Promise<{
|
|
486
|
+
-readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>;
|
|
487
|
+
}>;
|
|
488
|
+
},
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// ----------------------------------------------------------------------------
|
|
492
|
+
// types and functions for the gRPC-based API
|
|
493
|
+
// ----------------------------------------------------------------------------
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* Interface to interact with **gRPC** based services. You can use this interface to instantiate a gRPC generated client.
|
|
497
|
+
*/
|
|
498
|
+
export interface RestateGrpcChannel {
|
|
499
|
+
/**
|
|
500
|
+
* Unidirectional call to other Restate services ( = in background / async / not waiting on response).
|
|
501
|
+
* To do this, wrap the call via the proto-ts client with oneWayCall, as shown in the example.
|
|
502
|
+
*
|
|
503
|
+
* NOTE: this returns a Promise because we override the gRPC clients provided by proto-ts.
|
|
504
|
+
* So we are required to return a Promise.
|
|
505
|
+
*
|
|
506
|
+
* @param call Invoke another service by using the generated proto-ts client.
|
|
507
|
+
* @example
|
|
508
|
+
* const ctx = restate.useContext(this);
|
|
509
|
+
* const client = new GreeterClientImpl(ctx);
|
|
510
|
+
* await ctx.oneWayCall(() =>
|
|
511
|
+
* client.greet(Request.create({ name: "Peter" }))
|
|
512
|
+
* )
|
|
513
|
+
*/
|
|
514
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
515
|
+
oneWayCall(call: () => Promise<any>): Promise<void>;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Delayed unidirectional call to other Restate services ( = in background / async / not waiting on response).
|
|
519
|
+
* To do this, wrap the call via the proto-ts client with delayedCall, as shown in the example.
|
|
520
|
+
* Add the delay in millis as the second parameter.
|
|
521
|
+
*
|
|
522
|
+
* NOTE: this returns a Promise because we override the gRPC clients provided by proto-ts.
|
|
523
|
+
* So we are required to return a Promise.
|
|
524
|
+
*
|
|
525
|
+
* @param call Invoke another service by using the generated proto-ts client.
|
|
526
|
+
* @param delayMillis millisecond delay duration to delay the execution of the call
|
|
527
|
+
* @example
|
|
528
|
+
* const ctx = restate.useContext(this);
|
|
529
|
+
* const client = new GreeterClientImpl(ctx);
|
|
530
|
+
* await ctx.delayedCall(() =>
|
|
531
|
+
* client.greet(Request.create({ name: "Peter" })),
|
|
532
|
+
* 5000
|
|
533
|
+
* )
|
|
534
|
+
*/
|
|
535
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
536
|
+
delayedCall(call: () => Promise<any>, delayMillis?: number): Promise<void>;
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Call another Restate service and await the response.
|
|
540
|
+
*
|
|
541
|
+
* This function is not recommended to be called directly. Instead, use the generated gRPC client
|
|
542
|
+
* that was generated based on the Protobuf service definitions (which internally use this method):
|
|
543
|
+
*
|
|
544
|
+
* @example
|
|
545
|
+
* ```
|
|
546
|
+
* const ctx = restate.useContext(this);
|
|
547
|
+
* const client = new GreeterClientImpl(ctx);
|
|
548
|
+
* client.greet(Request.create({ name: "Peter" }))
|
|
549
|
+
* ```
|
|
550
|
+
*
|
|
551
|
+
* @param service name of the service to call
|
|
552
|
+
* @param method name of the method to call
|
|
553
|
+
* @param data payload as Uint8Array
|
|
554
|
+
* @returns a Promise that is resolved with the response of the called service
|
|
555
|
+
*/
|
|
556
|
+
request(
|
|
557
|
+
service: string,
|
|
558
|
+
method: string,
|
|
559
|
+
data: Uint8Array
|
|
560
|
+
): Promise<Uint8Array>;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* @deprecated use {@link KeyedContext}.
|
|
565
|
+
*/
|
|
566
|
+
export type RestateContext = KeyedContext;
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Returns the {@link Context} which is the entrypoint for all interaction with Restate.
|
|
570
|
+
* Use this from within a method to retrieve the {@link Context}.
|
|
571
|
+
* The context is bounded to a single invocation.
|
|
572
|
+
*
|
|
573
|
+
* @example
|
|
574
|
+
* const ctx = restate.useContext(this);
|
|
575
|
+
*
|
|
576
|
+
*/
|
|
577
|
+
export function useContext<T>(instance: T): Context {
|
|
578
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
579
|
+
const wrapper = instance as any;
|
|
580
|
+
if (wrapper.$$restate === undefined || wrapper.$$restate === null) {
|
|
581
|
+
throw new Error(`not running within a Restate call.`);
|
|
582
|
+
}
|
|
583
|
+
return wrapper.$$restate;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Returns the {@link KeyedContext} which is the entrypoint for all interaction with Restate.
|
|
588
|
+
* Use this from within a method of a keyed service to retrieve the {@link KeyedContext}.
|
|
589
|
+
* The context is bounded to a single invocation.
|
|
590
|
+
*
|
|
591
|
+
* @example
|
|
592
|
+
* const ctx = restate.useKeyedContext(this);
|
|
593
|
+
*
|
|
594
|
+
*/
|
|
595
|
+
export function useKeyedContext<T>(instance: T): KeyedContext {
|
|
596
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
597
|
+
const wrapper = instance as any;
|
|
598
|
+
if (wrapper.$$restate === undefined || wrapper.$$restate === null) {
|
|
599
|
+
throw new Error(`not running within a Restate call.`);
|
|
600
|
+
}
|
|
601
|
+
return wrapper.$$restate;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// ----------------------------------------------------------------------------
|
|
605
|
+
// types for the rpc-handler-based API
|
|
606
|
+
// ----------------------------------------------------------------------------
|
|
607
|
+
|
|
608
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* ServiceApi captures the type and parameters to make RPC calls and send messages to
|
|
612
|
+
* a set of RPC handlers in a router.
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* **Service Side:**
|
|
616
|
+
* ```ts
|
|
617
|
+
* const router = restate.router({
|
|
618
|
+
* someAction: async(ctx: restate.RpcContext, req: string) => { ... },
|
|
619
|
+
* anotherAction: async(ctx: restate.RpcContext, count: number) => { ... }
|
|
620
|
+
* });
|
|
621
|
+
*
|
|
622
|
+
* export const myApi: restate.ServiceApi<typeof router> = { path : "myservice" };
|
|
623
|
+
*
|
|
624
|
+
* restate.createServer().bindRouter("myservice", router).listen(9080);
|
|
625
|
+
* ```
|
|
626
|
+
* **Client side:**
|
|
627
|
+
* ```ts
|
|
628
|
+
* ctx.rpc(myApi).someAction("hello!");
|
|
629
|
+
* ```
|
|
630
|
+
*/
|
|
631
|
+
export type ServiceApi<_M = unknown> = {
|
|
632
|
+
path: string;
|
|
633
|
+
};
|