@restatedev/restate-sdk 1.1.0 → 1.1.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/dist/cjs/src/generated/version.d.ts +1 -1
- package/dist/cjs/src/generated/version.js +1 -1
- package/dist/cjs/src/types/rpc.js +3 -3
- package/dist/cjs/src/types/rpc.js.map +1 -1
- package/dist/cjs/src/user_agent.d.ts +1 -1
- package/dist/cjs/test/service_bind.test.js +48 -0
- package/dist/cjs/test/service_bind.test.js.map +1 -1
- package/dist/cjs/test/testdriver.d.ts +18 -12
- package/dist/cjs/test/testdriver.d.ts.map +1 -1
- package/dist/cjs/test/testdriver.js +96 -57
- package/dist/cjs/test/testdriver.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/src/generated/version.d.ts +1 -1
- package/dist/esm/src/generated/version.js +1 -1
- package/dist/esm/src/types/rpc.js +3 -3
- package/dist/esm/src/types/rpc.js.map +1 -1
- package/dist/esm/src/user_agent.d.ts +1 -1
- package/dist/esm/test/service_bind.test.js +28 -3
- package/dist/esm/test/service_bind.test.js.map +1 -1
- package/dist/esm/test/testdriver.d.ts +18 -12
- package/dist/esm/test/testdriver.d.ts.map +1 -1
- package/dist/esm/test/testdriver.js +92 -55
- package/dist/esm/test/testdriver.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { Connection } from "../src/connection/connection.js";
|
|
2
1
|
import { Message } from "../src/types/types.js";
|
|
3
2
|
import type { ObjectContext } from "../src/context.js";
|
|
4
|
-
import type { VirtualObjectDefinition } from "../src/public_api.js";
|
|
3
|
+
import type { ServiceDefinition, VirtualObjectDefinition, WorkflowDefinition } from "../src/public_api.js";
|
|
5
4
|
export type TestRequest = {
|
|
6
5
|
name: string;
|
|
7
6
|
};
|
|
@@ -15,17 +14,24 @@ export declare const GreeterApi: VirtualObjectDefinition<"greeter", TestGreeter>
|
|
|
15
14
|
export interface TestGreeter {
|
|
16
15
|
greet(ctx: ObjectContext, message: TestRequest): Promise<TestResponse>;
|
|
17
16
|
}
|
|
18
|
-
export declare class TestDriver
|
|
19
|
-
private readonly
|
|
20
|
-
private
|
|
21
|
-
private stateMachine;
|
|
22
|
-
private completionMessages;
|
|
17
|
+
export declare class TestDriver {
|
|
18
|
+
private readonly uut;
|
|
19
|
+
private readonly input;
|
|
23
20
|
constructor(instance: TestGreeter, entries: Message[]);
|
|
24
|
-
headers(): ReadonlyMap<string, string | string[] | undefined>;
|
|
25
21
|
run(): Promise<Message[]>;
|
|
26
|
-
send(msg: Message): Promise<void>;
|
|
27
|
-
onClose(): void;
|
|
28
|
-
end(): Promise<void>;
|
|
29
|
-
onError(): void;
|
|
30
22
|
}
|
|
23
|
+
interface RunOptions {
|
|
24
|
+
service?: string;
|
|
25
|
+
handler?: string;
|
|
26
|
+
input: Message[];
|
|
27
|
+
}
|
|
28
|
+
export declare class UUT<N extends string, T> {
|
|
29
|
+
private readonly definition;
|
|
30
|
+
private readonly defaultService;
|
|
31
|
+
private readonly defaultHandler;
|
|
32
|
+
constructor(definition: ServiceDefinition<N, T> | VirtualObjectDefinition<N, T> | WorkflowDefinition<N, T>);
|
|
33
|
+
run(options: RunOptions): Promise<Message[]>;
|
|
34
|
+
}
|
|
35
|
+
export declare function testService<N extends string, T>(definition: ServiceDefinition<N, T> | VirtualObjectDefinition<N, T> | WorkflowDefinition<N, T>): UUT<N, T>;
|
|
36
|
+
export {};
|
|
31
37
|
//# sourceMappingURL=testdriver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testdriver.d.ts","sourceRoot":"","sources":["../../../test/testdriver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testdriver.d.ts","sourceRoot":"","sources":["../../../test/testdriver.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGhD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAK9B,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,YAAY;mBACR,YAAY,KAAG,YAAY;CAC3C,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,uBAAuB,CAAC,SAAS,EAAE,WAAW,CAEtE,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACxE;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;gBAGtB,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE;IAc/C,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;CAKhC;AAUD,UAAU,UAAU;IAElB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;CAClB;AAED,qBAAa,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC;IAMhC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAL7B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAIrB,UAAU,EACvB,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC;IA4BjB,GAAG,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAiH1D;AAGD,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAC7C,UAAU,EACN,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,GACvB,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC7B,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,GAC3B,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAEX"}
|
|
@@ -9,12 +9,10 @@
|
|
|
9
9
|
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
|
|
10
10
|
*/
|
|
11
11
|
import { COMPLETION_MESSAGE_TYPE, ENTRY_ACK_MESSAGE_TYPE, START_MESSAGE_TYPE, StartMessage, } from "../src/types/protocol.js";
|
|
12
|
-
import { formatMessageAsJson } from "../src/utils/utils.js";
|
|
13
12
|
import { Message } from "../src/types/types.js";
|
|
14
13
|
import { StateMachine } from "../src/state_machine.js";
|
|
15
14
|
import { InvocationBuilder } from "../src/invocation.js";
|
|
16
15
|
import { object } from "../src/public_api.js";
|
|
17
|
-
import { HandlerKind } from "../src/types/rpc.js";
|
|
18
16
|
import { NodeEndpoint } from "../src/endpoint/node_endpoint.js";
|
|
19
17
|
export const TestResponse = {
|
|
20
18
|
create: (test) => test,
|
|
@@ -23,111 +21,150 @@ export const GreeterApi = {
|
|
|
23
21
|
name: "greeter",
|
|
24
22
|
};
|
|
25
23
|
export class TestDriver {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
completionMessages;
|
|
24
|
+
uut;
|
|
25
|
+
input;
|
|
26
|
+
// Deprecated, please use testService below
|
|
30
27
|
constructor(instance, entries) {
|
|
31
|
-
this.
|
|
32
|
-
const svc = object({
|
|
28
|
+
this.uut = testService(object({
|
|
33
29
|
name: "greeter",
|
|
34
30
|
handlers: {
|
|
35
31
|
greet: async (ctx, arg) => {
|
|
36
32
|
return instance.greet(ctx, arg);
|
|
37
33
|
},
|
|
38
34
|
},
|
|
35
|
+
}));
|
|
36
|
+
this.input = entries;
|
|
37
|
+
}
|
|
38
|
+
async run() {
|
|
39
|
+
return await this.uut.run({
|
|
40
|
+
input: this.input,
|
|
39
41
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* This class' only purpose is to make certain methods accessible in tests.
|
|
46
|
+
* Those methods are otherwise protected, to reduce the public interface and
|
|
47
|
+
* make it simpler for users to understand what methods are relevant for them,
|
|
48
|
+
* and which ones are not.
|
|
49
|
+
*/
|
|
50
|
+
class TestRestateServer extends NodeEndpoint {
|
|
51
|
+
}
|
|
52
|
+
export class UUT {
|
|
53
|
+
definition;
|
|
54
|
+
defaultService;
|
|
55
|
+
defaultHandler;
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
57
|
+
constructor(definition) {
|
|
58
|
+
this.definition = definition;
|
|
59
|
+
// Infer service name and handler
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
|
|
61
|
+
this.defaultService = definition.name;
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
63
|
+
const definitionRecord = definition;
|
|
64
|
+
if (definitionRecord && definitionRecord.service != undefined) {
|
|
65
|
+
this.defaultHandler = Object.keys(definitionRecord.service)[0];
|
|
66
|
+
}
|
|
67
|
+
else if (definitionRecord && definitionRecord.object != undefined) {
|
|
68
|
+
this.defaultHandler = Object.keys(definitionRecord.object)[0];
|
|
69
|
+
}
|
|
70
|
+
else if (definitionRecord && definitionRecord.workflow != undefined) {
|
|
71
|
+
this.defaultHandler = Object.keys(definitionRecord.workflow)[0];
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
throw new TypeError("supports only a service or a virtual object or a workflow definition");
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async run(options) {
|
|
78
|
+
const restateServer = new TestRestateServer();
|
|
79
|
+
restateServer.bind(this.definition);
|
|
80
|
+
// Sanity check on input messages
|
|
81
|
+
if (options.input.length < 2) {
|
|
42
82
|
throw new Error("Less than two runtime messages supplied for test. Need to have at least start message and input message.");
|
|
43
83
|
}
|
|
44
|
-
if (
|
|
84
|
+
if (options.input[0].messageType !== START_MESSAGE_TYPE) {
|
|
45
85
|
throw new Error("First message has to be start message.");
|
|
46
86
|
}
|
|
47
87
|
// Get the index of where the completion messages start in the entries list
|
|
48
|
-
const firstCompletionIndex =
|
|
88
|
+
const firstCompletionIndex = options.input.findIndex((value) => value.messageType === COMPLETION_MESSAGE_TYPE ||
|
|
49
89
|
value.messageType === ENTRY_ACK_MESSAGE_TYPE);
|
|
50
90
|
// The last message of the replay is the one right before the first completion
|
|
51
|
-
const endOfReplay = firstCompletionIndex !== -1 ? firstCompletionIndex :
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const startEntry =
|
|
55
|
-
|
|
91
|
+
const endOfReplay = firstCompletionIndex !== -1 ? firstCompletionIndex : options.input.length;
|
|
92
|
+
// --- Patch StartMessage with the right number of entries
|
|
93
|
+
const startMsg = options.input[0];
|
|
94
|
+
const startEntry = startMsg.message;
|
|
95
|
+
options.input[0] = new Message(startMsg.messageType, new StartMessage({
|
|
56
96
|
id: startEntry.id,
|
|
57
97
|
debugId: startEntry.debugId,
|
|
58
98
|
knownEntries: endOfReplay - 1,
|
|
59
99
|
stateMap: startEntry.stateMap,
|
|
60
100
|
partialState: startEntry.partialState,
|
|
61
101
|
key: startEntry.key,
|
|
62
|
-
}),
|
|
63
|
-
|
|
64
|
-
|
|
102
|
+
}), startMsg.completed, startMsg.requiresAck);
|
|
103
|
+
// TODO the production code here is doing some bad assumption,
|
|
104
|
+
// by assuming that during the initial replay phase no CompletionMessages are sent.
|
|
105
|
+
// Although this is currently correct, it is correct only due to how the runtime is implemented,
|
|
106
|
+
// and might not be generally true if we change the runtime.
|
|
107
|
+
// This should probably be fixed in the production code, and subsequently the test should
|
|
108
|
+
// stop splitting the input messages here.
|
|
109
|
+
const replayMessages = options.input.slice(0, endOfReplay);
|
|
110
|
+
const completionMessages = options.input.slice(endOfReplay);
|
|
65
111
|
if (replayMessages.filter((value) => value.messageType === COMPLETION_MESSAGE_TYPE ||
|
|
66
112
|
value.messageType === ENTRY_ACK_MESSAGE_TYPE).length > 0) {
|
|
67
113
|
throw new Error("You cannot interleave replay messages with completion or ack messages. First define the replay messages, then the completion messages.");
|
|
68
114
|
}
|
|
69
|
-
if (
|
|
115
|
+
if (completionMessages.filter((value) => value.messageType !== COMPLETION_MESSAGE_TYPE &&
|
|
70
116
|
value.messageType !== ENTRY_ACK_MESSAGE_TYPE).length > 0) {
|
|
71
117
|
throw new Error("You cannot interleave replay messages with completion or ack messages. First define the replay messages, then the completion messages.");
|
|
72
118
|
}
|
|
73
|
-
const method =
|
|
74
|
-
.componentByName(
|
|
119
|
+
const method = restateServer
|
|
120
|
+
.componentByName(options.service ? options.service : this.defaultService)
|
|
75
121
|
?.handlerMatching({
|
|
76
|
-
componentName:
|
|
77
|
-
handlerName:
|
|
122
|
+
componentName: options.service ? options.service : this.defaultService,
|
|
123
|
+
handlerName: options.handler ? options.handler : this.defaultHandler,
|
|
78
124
|
});
|
|
79
125
|
if (!method) {
|
|
80
|
-
throw new Error("
|
|
126
|
+
throw new Error("Can't find the handler to execute");
|
|
81
127
|
}
|
|
82
128
|
const invocationBuilder = new InvocationBuilder(method);
|
|
83
129
|
replayMessages.forEach((el) => invocationBuilder.handleMessage(el));
|
|
84
130
|
const invocation = invocationBuilder.build();
|
|
85
|
-
|
|
131
|
+
const testConnection = new TestConnection();
|
|
132
|
+
const stateMachine = new StateMachine(testConnection, invocation, method.kind(),
|
|
86
133
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
headers() {
|
|
90
|
-
return new Map();
|
|
91
|
-
}
|
|
92
|
-
async run() {
|
|
93
|
-
const completed = this.stateMachine.invoke();
|
|
134
|
+
restateServer.builder.logger, invocation.inferLoggerContext());
|
|
135
|
+
const completed = stateMachine.invoke();
|
|
94
136
|
// we send the completions here. Because we don't await the messages that we send the completions for,
|
|
95
137
|
// we enqueue those completions in the event loop, so they get processed when everything else is done.
|
|
96
138
|
// This is highly fragile!!!
|
|
97
|
-
|
|
98
|
-
setTimeout(() =>
|
|
139
|
+
completionMessages.forEach((el) => {
|
|
140
|
+
setTimeout(() => stateMachine.handleMessage(el));
|
|
99
141
|
});
|
|
100
142
|
// Set the input channel to closed a bit after sending the messages
|
|
101
143
|
// to make the service finish up the work it can do and suspend or send back a response.
|
|
102
|
-
setTimeout(() =>
|
|
144
|
+
setTimeout(() => stateMachine.handleInputClosed());
|
|
103
145
|
await completed;
|
|
104
|
-
return Promise.resolve(
|
|
146
|
+
return Promise.resolve(testConnection.sentMessages());
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
150
|
+
export function testService(definition) {
|
|
151
|
+
return new UUT(definition);
|
|
152
|
+
}
|
|
153
|
+
class TestConnection {
|
|
154
|
+
result = [];
|
|
155
|
+
headers() {
|
|
156
|
+
return new Map();
|
|
105
157
|
}
|
|
106
158
|
send(msg) {
|
|
107
159
|
this.result.push(msg);
|
|
108
|
-
this.restateServer.builder.rlog.debug(`Adding result to the result array. Message type: ${msg.messageType}, message:
|
|
109
|
-
${msg.message instanceof Uint8Array
|
|
110
|
-
? msg.message.toString()
|
|
111
|
-
: formatMessageAsJson(msg.message)}`);
|
|
112
160
|
return Promise.resolve();
|
|
113
161
|
}
|
|
114
|
-
onClose() {
|
|
115
|
-
// nothing to do
|
|
116
|
-
}
|
|
117
162
|
async end() {
|
|
118
163
|
// nothing to do
|
|
119
164
|
return Promise.resolve();
|
|
120
165
|
}
|
|
121
|
-
|
|
122
|
-
|
|
166
|
+
sentMessages() {
|
|
167
|
+
return this.result;
|
|
123
168
|
}
|
|
124
169
|
}
|
|
125
|
-
/**
|
|
126
|
-
* This class' only purpose is to make certain methods accessible in tests.
|
|
127
|
-
* Those methods are otherwise protected, to reduce the public interface and
|
|
128
|
-
* make it simpler for users to understand what methods are relevant for them,
|
|
129
|
-
* and which ones are not.
|
|
130
|
-
*/
|
|
131
|
-
class TestRestateServer extends NodeEndpoint {
|
|
132
|
-
}
|
|
133
170
|
//# sourceMappingURL=testdriver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testdriver.js","sourceRoot":"","sources":["../../../test/testdriver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,YAAY,GACb,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"testdriver.js","sourceRoot":"","sources":["../../../test/testdriver.ts"],"names":[],"mappings":"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"}
|