Skip to content

Commit 95cb640

Browse files
committed
Integrate a TypeScript client
1 parent 4bdb2c8 commit 95cb640

29 files changed

+1722
-97
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_executable(
2+
005-echo-server
3+
main.cc
4+
)
5+
6+
target_link_libraries(
7+
005-echo-server PRIVATE
8+
eglt::actions
9+
eglt::data
10+
eglt::nodes
11+
eglt::service
12+
eglt::sdk::serving::websockets
13+
)

examples/005-echo-server/main.cc

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include <cstdint>
2+
#include <iostream>
3+
#include <memory>
4+
#include <optional>
5+
#include <ostream>
6+
#include <sstream>
7+
#include <string>
8+
#include <string_view>
9+
10+
#include <eglt/absl_headers.h>
11+
#include <eglt/actions/action.h>
12+
#include <eglt/data/eg_structs.h>
13+
#include <eglt/nodes/async_node.h>
14+
#include <eglt/sdk/serving/websockets.h>
15+
#include <eglt/service/service.h>
16+
17+
ABSL_FLAG(uint16_t, port, 20000, "Port to bind to.");
18+
19+
// Simply some type aliases to make the code more readable.
20+
using Action = eglt::Action;
21+
using ActionRegistry = eglt::ActionRegistry;
22+
using Chunk = eglt::Chunk;
23+
using Service = eglt::Service;
24+
25+
absl::Status RunEcho(const std::shared_ptr<Action>& action) {
26+
auto input_text = action->GetNode("text");
27+
input_text->SetReaderOptions(/*ordered=*/true,
28+
/*remove_chunks=*/true);
29+
std::optional<Chunk> chunk;
30+
while (true) {
31+
*input_text >> chunk;
32+
33+
if (!chunk.has_value()) {
34+
break;
35+
}
36+
37+
if (auto status = input_text->GetReaderStatus(); !status.ok()) {
38+
LOG(ERROR) << "Failed to read input: " << status;
39+
return status;
40+
}
41+
42+
action->GetNode("response") << *chunk;
43+
}
44+
45+
// This is necessary and indicates the end of stream.
46+
action->GetNode("response") << eglt::EndOfStream();
47+
48+
return absl::OkStatus();
49+
}
50+
51+
ActionRegistry MakeActionRegistry() {
52+
ActionRegistry registry;
53+
54+
registry.Register(/*name=*/"echo",
55+
/*schema=*/
56+
{
57+
.name = "echo",
58+
.inputs = {{"text", "text/plain"}},
59+
.outputs = {{"response", "text/plain"}},
60+
},
61+
/*handler=*/RunEcho);
62+
return registry;
63+
}
64+
65+
int main(int argc, char** argv) {
66+
absl::InstallFailureSignalHandler({});
67+
absl::ParseCommandLine(argc, argv);
68+
69+
eglt::SessionMessage message{
70+
.node_fragments = {eglt::NodeFragment{.id = "test",
71+
.chunk = eglt::EndOfStream()}},
72+
};
73+
for (const auto bytes = cppack::Pack(message); const auto& byte : bytes) {
74+
std::cout << std::hex << static_cast<int>(byte) << " ";
75+
}
76+
std::cout << std::endl;
77+
78+
const uint16_t port = absl::GetFlag(FLAGS_port);
79+
ActionRegistry action_registry = MakeActionRegistry();
80+
eglt::Service service(&action_registry);
81+
eglt::sdk::WebsocketEvergreenServer server(&service, "0.0.0.0", port);
82+
server.Run();
83+
server.Join().IgnoreError();
84+
85+
return 0;
86+
}

examples/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_subdirectory(000-actions)
22
add_subdirectory(001-bidi-actions)
33
add_subdirectory(002-chunks-from-custom-types)
4-
add_subdirectory(004-connections-through-nodes)
4+
add_subdirectory(004-connections-through-nodes)
5+
add_subdirectory(005-echo-server)

js/.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ charset = utf-8
55
end_of_line = lf
66
trim_trailing_whitespace = true
77
insert_final_newline = true
8+
max_line_length = 80
89

910
[*.md]
1011
insert_final_newline = false

js/.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"parser": "typescript",
33
"semi": true,
44
"singleQuote": true,
5-
"trailingComma": "all"
5+
"trailingComma": "all",
6+
"maxLineLength": 80
67
}

js/__tests__/unit/main.test.ts

Lines changed: 0 additions & 40 deletions
This file was deleted.

js/eslint.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export default tseslint.config(
2323
},
2424

2525
rules: {
26-
'@typescript-eslint/explicit-function-return-type': 'warn',
26+
'@typescript-eslint/explicit-function-return-type': 'off',
2727
},
2828

2929
languageOptions: {

js/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export { Action, ActionRegistry } from './src/action.js';
2+
export { AsyncNode, NodeMap } from './src/asyncNode.js';
3+
export { ChunkStore, LocalChunkStore } from './src/chunkStore.js';
4+
export { ChunkStoreReader } from './src/chunkStoreReader.js';
5+
export { ChunkStoreWriter } from './src/chunkStoreWriter.js';
6+
export { endOfStream, isEndOfStream, isNullChunk } from './src/data.js';
7+
export { Session } from './src/session.js';
8+
export * from './src/msgpack.js';
9+
export { EvergreenStream } from './src/stream.js';
10+
export { Lock, Event, Channel, Deque } from './src/utils.js';

js/package-lock.json

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/package.json

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
{
2-
"name": "actionengine-ts",
2+
"name": "actionengine",
33
"version": "0.1.0",
4+
"author": "Google DeepMind <[email protected]>",
5+
"license": "Apache-2.0",
46
"description": "A TypeScript client library for Action Engine.",
57
"type": "module",
8+
"exports": {
9+
".": "./build/actionengine.js"
10+
},
11+
"types": "index.ts",
612
"engines": {
713
"node": ">= 23.0 < 24"
814
},
@@ -13,34 +19,35 @@
1319
"@typescript-eslint/parser": "~8.19",
1420
"@vitest/coverage-v8": "~2.1",
1521
"@vitest/eslint-plugin": "~1.1",
16-
"eslint-config-prettier": "~9.1",
1722
"eslint": "~9.17",
23+
"eslint-config-prettier": "~9.1",
1824
"globals": "~15.14",
1925
"prettier": "~3.4",
2026
"rimraf": "~6.0",
2127
"ts-api-utils": "~2.0",
22-
"typescript-eslint": "~8.19",
2328
"typescript": "~5.7",
29+
"typescript-eslint": "~8.19",
2430
"vitest": "~2.1"
2531
},
2632
"scripts": {
27-
"start": "node build/src/main.js",
2833
"clean": "rimraf coverage build tmp",
2934
"prebuild": "npm run lint",
3035
"build": "tsc -p tsconfig.json",
36+
"build:bundle": "esbuild --bundle index.ts --format=esm --outfile=build/actionengine.js",
3137
"build:watch": "tsc -w -p tsconfig.json",
3238
"build:release": "npm run clean && tsc -p tsconfig.release.json",
39+
"build:typings": "tsc --declaration --emitDeclarationOnly --outDir build",
3340
"lint": "eslint .",
3441
"test": "vitest run unit --config __tests__/vitest.config.ts",
3542
"test:coverage": "vitest run unit --config __tests__/vitest.config.ts --coverage.enabled --coverage.all",
3643
"prettier": "prettier \"{src,__{tests}__}/**/*.{ts,mts}\" --config .prettierrc --write",
3744
"prettier:check": "prettier \"{src,__{tests}__}/**/*.{ts,mts}\" --config .prettierrc --check",
3845
"test:watch": "vitest unit"
3946
},
40-
"author": "Jakub Synowiec <[email protected]>",
41-
"license": "Apache-2.0",
4247
"dependencies": {
43-
"tslib": "~2.8"
48+
"@msgpack/msgpack": "^3.1.1",
49+
"tslib": "~2.8",
50+
"uuid": "^11.1.0"
4451
},
4552
"volta": {
4653
"node": "22.12.0"

0 commit comments

Comments
 (0)