Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions documentation/docs/learn_more/applications.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,19 @@ Your entrypoint will construct an `Application` and then `run` it:
<Tabs groupId="language">
<TabItem value="python" label="Python">
<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../reboot/examples/chat-room/backend/src/main.py&lines=25-33) -->
(CODE:src=../../../reboot/examples/chat-room/backend/src/main.py&lines=26-34) -->
<!-- The below code snippet is automatically added from ../../../reboot/examples/chat-room/backend/src/main.py -->

```py
async def main():
await Application(
servicers=[ChatRoomServicer],
# Message attachments are stored as blobs; `rbt dev run` and
# `rbt serve run` provide a local filesystem data plane (see
# `REBOOT_BLOB_DATA_PLANE_URL` for using a custom one).
libraries=[blobs_library()],
initialize=initialize,
).run()


if __name__ == '__main__':
asyncio.run(main())
```

<!-- MARKDOWN-AUTO-DOCS:END -->
Expand Down Expand Up @@ -59,7 +59,7 @@ instances used by your application are created.
<Tabs groupId="language">
<TabItem value="python" label="Python">
<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../reboot/examples/chat-room/backend/src/main.py&lines=13-20) -->
(CODE:src=../../../reboot/examples/chat-room/backend/src/main.py&lines=14-21) -->
<!-- The below code snippet is automatically added from ../../../reboot/examples/chat-room/backend/src/main.py -->

```py
Expand Down Expand Up @@ -129,7 +129,7 @@ implemented with [Express.js](https://expressjs.com/).

**Limitations of custom HTTP routes**

* Currently only `GET` and `POST` methods are supported.
* Currently only `GET`, `POST`, and `PUT` methods are supported.

* The `/` route is currently used by Reboot itself to
show a helpful page explaining that this is a Reboot
Expand Down
94 changes: 66 additions & 28 deletions documentation/docs/learn_more/call/from_react.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,33 @@ api = API(
</TabItem>
<TabItem value="proto" label="Proto">
<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto&&lines=9-41&syntax=protobuf) -->
(CODE:src=../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto&&lines=9-51&syntax=protobuf) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto -->

```protobuf
// Raised when a requested attachment exceeds the chat room's
// per-attachment size limit.
message AttachmentTooLarge {
// The maximum allowed attachment size, in bytes, so the client can
// show a helpful message.
uint64 max_size_bytes = 1;
}

message Message {
string text = 1;

// Ids of `rbt.std.blobs.v1.Blob`s holding this message's
// attachments. Attachments are visible to all participants from the
// moment the message is sent, while their bytes may still be
// uploading; render their progress reactively via `Blob.Info`.
repeated string attachment_blob_ids = 2;
}

message ChatRoom {
option (rbt.v1alpha1.state) = {
};
repeated string messages = 1;
reserved 1;
repeated Message messages = 2;
}

service ChatRoomMethods {
Expand All @@ -107,24 +126,17 @@ service ChatRoomMethods {
};
}

// Adds a new message to the list of recorded messages.
// Adds a new message to the list of recorded messages, creating a
// `Blob` for each requested attachment. The message is published
// immediately; the caller then uploads the attachment bytes into
// the returned blob ids.
rpc Send(SendRequest) returns (SendResponse) {
option (rbt.v1alpha1.method).writer = {
option (rbt.v1alpha1.method) = {
transaction: {},
errors: [ "AttachmentTooLarge" ],
};
}
}

message MessagesRequest {}

message MessagesResponse {
repeated string messages = 1;
}

message SendRequest {
string message = 1; // E.g. "Hello, World".
}

message SendResponse {}
```

<!-- MARKDOWN-AUTO-DOCS:END -->
Expand Down Expand Up @@ -266,7 +278,7 @@ export const DashboardApp: FC<DashboardConfig> = ({
You can call a `reader` _reactively_ very simply:

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=33-34) -->
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=156-157) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/frontend/web/src/App.tsx -->

```tsx
Expand Down Expand Up @@ -295,7 +307,7 @@ and [`transaction`](/learn_more/define/methods#kinds) methods
are both callable from React.

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=33-33) -->
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=156-156) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/frontend/web/src/App.tsx -->

```tsx
Expand All @@ -312,11 +324,17 @@ This line calls the
in the `.proto` as `Send`, using the lower camel case name `send`:

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=37-37) -->
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=177-183) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/frontend/web/src/App.tsx -->

```tsx
const { aborted } = await send({ message: message });
const { response, aborted } = await send({
message: message,
attachments:
file !== null
? [{ contentType: file.type, sizeBytes: BigInt(file.size) }]
: [],
});
```

<!-- MARKDOWN-AUTO-DOCS:END -->
Expand All @@ -333,12 +351,17 @@ Reboot attaches all in-flight mutations to a `.pending` property of every mutato
facilitate this, for example:

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=81-83) -->
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=302-309) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/frontend/web/src/App.tsx -->

```tsx
{send.pending.map(({ request: { message }, isLoading }) => (
<PendingMessage text={message} isLoading={isLoading} key={message} />
{send.pending.map(({ request, isLoading }, index) => (
<PendingMessage
text={request.message ?? ""}
attachmentCount={request.attachments?.length ?? 0}
isLoading={isLoading}
key={index}
/>
))}
```

Expand All @@ -365,15 +388,30 @@ Every call to a mutator returns both a `response` and an `aborted`; successful c
[Learn more about Reboot errors and error types.](/learn_more/errors)

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=37-41) -->
(CODE:src=../../../../reboot/examples/chat-room/frontend/web/src/App.tsx&&lines=177-196) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/frontend/web/src/App.tsx -->

```tsx
const { aborted } = await send({ message: message });
const { response, aborted } = await send({
message: message,
attachments:
file !== null
? [{ contentType: file.type, sizeBytes: BigInt(file.size) }]
: [],
});
if (aborted !== undefined) {
console.warn(aborted.error.getType());
console.warn(aborted.message);
}
// Surface the failure to the user. The backend's
// `AttachmentTooLarge` error carries the limit, so we can say
// exactly what it is.
if (aborted.error instanceof AttachmentTooLarge) {
const maxMebibytes = Number(aborted.error.maxSizeBytes) / (1024 * 1024);
setError(
`That attachment is too large. The maximum is ${maxMebibytes} MiB.`
);
} else {
setError(`Couldn't send your message: ${aborted.message}`);
}
return;
```

<!-- MARKDOWN-AUTO-DOCS:END -->
Expand Down
13 changes: 7 additions & 6 deletions documentation/docs/learn_more/call/from_within_your_app.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,15 @@ passed as a parameter to your method.
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/backend/src/chat_room_servicer.py -->

```py
self,
context: ReaderContext,
request: MessagesRequest,
) -> MessagesResponse:
return MessagesResponse(messages=self.state.messages)

async def send(
self,
context: WriterContext,
request: SendRequest,
) -> SendResponse:
message = request.message
self.state.messages.extend([message])
return SendResponse()
context: TransactionContext,
```

<!-- MARKDOWN-AUTO-DOCS:END -->
Expand Down
16 changes: 11 additions & 5 deletions documentation/docs/learn_more/define/protobuf.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ To declare a data type called `ChatRoom`, put the following in a `.proto`
file:

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto&lines=9-13&syntax=protobuf) -->
(CODE:src=../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto&lines=27-32&syntax=protobuf) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto -->

```protobuf
message ChatRoom {
option (rbt.v1alpha1.state) = {
};
repeated string messages = 1;
reserved 1;
repeated Message messages = 2;
}
```

Expand All @@ -32,7 +33,7 @@ In addition to defining the data type, you'll also need to define
operations for that type, for example:

<!-- MARKDOWN-AUTO-DOCS:START
(CODE:src=../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto&lines=14-27&syntax=protobuf) -->
(CODE:src=../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto&lines=34-51&syntax=protobuf) -->
<!-- The below code snippet is automatically added from ../../../../reboot/examples/chat-room/api/chat_room/v1/chat_room.proto -->

```protobuf
Expand All @@ -43,9 +44,14 @@ service ChatRoomMethods {
};
}

// Adds a new message to the list of recorded messages.
// Adds a new message to the list of recorded messages, creating a
// `Blob` for each requested attachment. The message is published
// immediately; the caller then uploads the attachment bytes into
// the returned blob ids.
rpc Send(SendRequest) returns (SendResponse) {
option (rbt.v1alpha1.method).writer = {
option (rbt.v1alpha1.method) = {
transaction: {},
errors: [ "AttachmentTooLarge" ],
};
}
}
Expand Down
3 changes: 3 additions & 0 deletions rbt/std/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ ts_project(
},
visibility = ["//visibility:public"],
deps = [
"//rbt/std/blobs/v1:blobs_js_proto",
"//rbt/std/blobs/v1:blobs_js_reboot",
"//rbt/std/blobs/v1:blobs_js_reboot_react",
"//rbt/std/ciphertext/v1:ciphertext_js_proto",
"//rbt/std/ciphertext/v1:ciphertext_js_reboot",
"//rbt/std/collections/ordered_map/v1:ordered_map_js_proto",
Expand Down
92 changes: 92 additions & 0 deletions rbt/std/blobs/v1/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
load(
"@com_github_reboot_dev_reboot//reboot:rules.bzl",
"js_proto_library",
"js_reboot_library",
"js_reboot_react_library",
"py_reboot_library",
)
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")

proto_library(
name = "blobs_proto",
srcs = [
":blobs.proto",
],
visibility = ["//visibility:public"],
deps = [
"@com_github_reboot_dev_reboot//rbt/v1alpha1:options_proto",
"@com_google_protobuf//:descriptor_proto",
],
)

# The blob data-plane interface: a plain gRPC service (no Reboot state
# options). Built with `py_reboot_library` — which, besides the plain
# `_pb2`/`_pb2_grpc` modules the filesystem server uses directly, emits
# the `_rbt` module that lets the Cloud facilitator register it via
# `legacy_grpc_servicers`. Python-only: the JS SDK talks to the `Blob`
# control plane, never the data plane directly.
proto_library(
name = "data_plane_proto",
srcs = [
":data_plane.proto",
],
visibility = ["//visibility:public"],
)

py_reboot_library(
name = "data_plane_py_reboot",
proto = "data_plane.proto",
proto_library = ":data_plane_proto",
visibility = ["//visibility:public"],
)

py_reboot_library(
name = "blobs_py_reboot",
proto = "blobs.proto",
proto_library = ":blobs_proto",
visibility = ["//visibility:public"],
)

js_proto_library(
name = "blobs_js_proto",
package_json = ":package.json",
proto = "blobs.proto",
proto_deps = [
":blobs_proto",
# ISSUE(https://github.com/reboot-dev/mono/issues/3218): Until we can
# use `create_protoc_plugin_rule` we need to repeat the dependencies of
# the `proto_libraries` here.
"@com_github_reboot_dev_reboot//rbt/v1alpha1:options_proto",
"@com_google_protobuf//:descriptor_proto",
],
visibility = ["//visibility:public"],
)

js_reboot_library(
name = "blobs_js_reboot",
srcs = [
":blobs_proto",
],
proto = "blobs.proto",
visibility = ["//visibility:public"],
deps = [
":blobs_js_proto",
],
)

js_reboot_react_library(
name = "blobs_js_reboot_react",
srcs = [
":blobs_js_proto",
],
proto = "blobs.proto",
proto_deps = [
":blobs_proto",
# ISSUE(https://github.com/reboot-dev/mono/issues/3218): Until we can
# use `create_protoc_plugin_rule` we need to repeat the dependencies of
# the `proto_libraries` here.
"@com_github_reboot_dev_reboot//rbt/v1alpha1:options_proto",
"@com_google_protobuf//:descriptor_proto",
],
visibility = ["//visibility:public"],
)
Loading
Loading