some cleanup
This commit is contained in:
@@ -28,9 +28,8 @@ Map-shaped `DTree` values can also represent list-like data when their keys are
|
||||
|
||||
You will encounter `DTree` throughout the runtime, especially in:
|
||||
|
||||
- `context.var`
|
||||
- `context.cfg`
|
||||
- `context.call`
|
||||
- `context.props`
|
||||
- `context.connection`
|
||||
- `json_decode()` results
|
||||
- `unit_call()` return values
|
||||
@@ -107,7 +106,7 @@ For non-map values, `each()` still invokes the callback once:
|
||||
- `key` is an empty string
|
||||
|
||||
```cpp
|
||||
context.var["items"].each([&](DTree item, String key) {
|
||||
context.connection["items"].each([&](DTree item, String key) {
|
||||
print(key, ": ", item.to_string(), "\n");
|
||||
});
|
||||
```
|
||||
@@ -119,7 +118,7 @@ String theme = context.cfg.get_by_path("theme/key").to_string();
|
||||
|
||||
u64 compiled_mtime = unit_info("test/hello.uce")["compiled_mtime"].to_u64();
|
||||
|
||||
bool dark_mode = context.call["dark_mode"].to_bool();
|
||||
bool dark_mode = context.props["dark_mode"].to_bool();
|
||||
|
||||
if(DTree* user = payload.key("user")) {
|
||||
print(user->to_json());
|
||||
|
||||
@@ -8,7 +8,7 @@ Request& context;
|
||||
>types
|
||||
|
||||
:content
|
||||
`Request& context` is the request-local state object passed into UCE handlers. It carries incoming request data, response state, runtime metadata, and helper trees such as `context.cfg`, `context.var`, and `context.call`.
|
||||
`Request& context` is the request-local state object passed into UCE handlers. It carries incoming request data, response state, runtime metadata, and helper trees such as `context.cfg`, `context.props`, and `context.connection`.
|
||||
|
||||
## Core Fields
|
||||
|
||||
@@ -20,9 +20,8 @@ Request& context;
|
||||
- `StringMap session`: current session data
|
||||
- `String session_id`: session cookie ID
|
||||
- `String session_name`: session cookie name
|
||||
- `DTree var`: user-defined request-local data
|
||||
- `DTree cfg`: request-local configuration tree
|
||||
- `DTree call`: invocation or message-local structured data
|
||||
- `DTree call`: invocation-local structured data for helpers such as component and unit calls
|
||||
- `DTree connection`: broker-owned WebSocket connection state that persists across `WS(Request& context)` calls for the same socket
|
||||
- `std::vector<UploadedFile> uploaded_files`: files uploaded in the current request
|
||||
- `StringMap header`: headers to send back to the browser
|
||||
@@ -45,7 +44,9 @@ Request& context;
|
||||
## Common Usage Notes
|
||||
|
||||
- `context.cfg` is the usual place for structured configuration. Use `context.cfg.get_by_path("path/to/value")` for deep reads.
|
||||
- `context.call` carries invocation data for component calls, unit calls, and WebSocket messages.
|
||||
- `context.props` carries invocation data for component calls and unit calls.
|
||||
- `context.in` carries the current request body, and for `WS(Request& context)` it is the current WebSocket message payload.
|
||||
- `context.params["WS_..."]` exposes the current WebSocket message metadata directly on the request parameter map.
|
||||
- `context.connection` is only meaningful for WebSocket traffic and persists for the lifetime of the connection.
|
||||
|
||||
`unit_render(String file_name, [Request& context])` invokes another UCE file using the current or supplied request context.
|
||||
|
||||
@@ -25,7 +25,7 @@ This keeps page rendering and component rendering separate:
|
||||
|
||||
A file intended only for component reuse can define `COMPONENT()` without defining `RENDER()`.
|
||||
|
||||
Inside component handlers, props arrive through `context.call`.
|
||||
Inside component handlers, props arrive through `context.props`.
|
||||
|
||||
When you call `component(":NAME", props, context)` or `component_render(":NAME", props, context)`, the runtime resolves `:NAME` against the current `.uce` file instead of requiring the file name again.
|
||||
|
||||
@@ -34,12 +34,12 @@ When you call `component(":NAME", props, context)` or `component_render(":NAME",
|
||||
```cpp
|
||||
COMPONENT(Request& context)
|
||||
{
|
||||
<><section><?: component(":BODY", context.call, context) ?></section></>
|
||||
<><section><?: component(":BODY", context.props, context) ?></section></>
|
||||
}
|
||||
|
||||
COMPONENT:BODY(Request& context)
|
||||
{
|
||||
<><p><?= context.call["body"] ?></p></>
|
||||
<><p><?= context.props["body"] ?></p></>
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ The default page entrypoint is always the plain `RENDER(Request& context)` handl
|
||||
|
||||
Reusable component handlers now live on `COMPONENT(Request& context)` and `COMPONENT:NAME(Request& context)`. The component helpers call those handlers, not `RENDER()`.
|
||||
|
||||
The request environment is passed explicitly through `context`, including params, cookies, post data, session state, headers, uploaded files, and the current `context.call` tree.
|
||||
The request environment is passed explicitly through `context`, including params, cookies, post data, session state, headers, uploaded files, and the current `context.props` tree.
|
||||
|
||||
For a normal direct page request, `context.call` starts empty.
|
||||
For a normal direct page request, `context.props` starts empty.
|
||||
|
||||
If the page is invoked from another UCE file via `unit_render(file_name, context)`, the callee receives that same `context`.
|
||||
|
||||
|
||||
+15
-7
@@ -12,7 +12,7 @@ Defines the WebSocket message handler for the current `.ws.uce` page.
|
||||
|
||||
The same page may expose both `RENDER(Request& context)` and `WS(Request& context)`. `RENDER(Request& context)` serves the initial HTTP response, while `WS(Request& context)` is called whenever a complete WebSocket message arrives for that page.
|
||||
|
||||
UCE reassembles fragmented messages before calling `WS(Request& context)`. Text and binary frames are both delivered. Use `context.call`, `context.connection`, `ws_opcode()`, and `ws_is_binary()` to inspect the current message.
|
||||
UCE reassembles fragmented messages before calling `WS(Request& context)`. Text and binary frames are both delivered. The current payload is available directly on `context.in`, message metadata is mirrored into `context.params["WS_..."]`, and connection-local state lives on `context.connection`.
|
||||
|
||||
## Connection State
|
||||
|
||||
@@ -20,13 +20,21 @@ UCE reassembles fragmented messages before calling `WS(Request& context)`. Text
|
||||
|
||||
## Message Data
|
||||
|
||||
The current message data is available in `context.call`:
|
||||
The current message payload is available as:
|
||||
|
||||
- `context.call["message"]`: current message payload
|
||||
- `context.call["connection_id"]`: sender connection ID
|
||||
- `context.call["scope"]`: current endpoint scope
|
||||
- `context.call["opcode"]`: WebSocket opcode of the current message
|
||||
- `context.call["document_uri"]`: request URI of the current endpoint
|
||||
- `context.in`: current WebSocket payload
|
||||
- `context.params["WS_MESSAGE"]`: same payload mirrored into the parameter map
|
||||
|
||||
The current message metadata is available as:
|
||||
|
||||
- `context.params["WS_CONNECTION_ID"]`: sender connection ID
|
||||
- `context.params["WS_SCOPE"]`: current endpoint scope
|
||||
- `context.params["WS_CONNECTION_COUNT"]`: number of currently connected clients in that scope
|
||||
- `context.params["WS_OPCODE"]`: WebSocket opcode of the current message
|
||||
- `context.params["WS_MESSAGE_TYPE"]`: `TEXT` or `BINARY`
|
||||
- `context.params["WS_DOCUMENT_URI"]`: request URI of the current endpoint
|
||||
|
||||
Helper wrappers such as `ws_message()`, `ws_connection_id()`, `ws_scope()`, `ws_connection_count()`, `ws_opcode()`, and `ws_is_binary()` are still available when that reads better for the handler.
|
||||
|
||||
## Related Concepts
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ Literal output with trusted unescaped markup:
|
||||
```cpp
|
||||
RENDER(Request& context)
|
||||
{
|
||||
<><div class="panel"><?: component("components/card", context.call, context) ?></div></>
|
||||
<><div class="panel"><?: component("components/card", context.props, context) ?></div></>
|
||||
}
|
||||
```
|
||||
|
||||
@@ -96,7 +96,7 @@ Roughly becomes:
|
||||
|
||||
```cpp
|
||||
print(R"(<div class="panel">)");
|
||||
print(component("components/card", context.call, context));
|
||||
print(component("components/card", context.props, context));
|
||||
print(R"(</div>)");
|
||||
```
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Renders another `.uce` file as a component and returns the captured output as a
|
||||
|
||||
`component()` resolves the target file relative to the current page and also tries the `components/` prefix automatically, mirroring the shorthand used by the starter example project.
|
||||
|
||||
Component props are passed in `context.call`.
|
||||
Component props are passed in `context.props`.
|
||||
|
||||
Because `<?= ... ?>` HTML-escapes its value, embed component markup with `<?: component(...) ?>`, `print(component(...))`, or use `component_render(...)` for direct output.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ Renders another `.uce` file as a component and writes the result directly to the
|
||||
|
||||
This is the direct-output counterpart to `component()`.
|
||||
|
||||
Component props are passed through `context.call`, and `name:COMPONENTFUNC` may be used to select a named handler exported by `COMPONENT:COMPONENTFUNC(Request& context)`.
|
||||
Component props are passed through `context.props`, and `name:COMPONENTFUNC` may be used to select a named handler exported by `COMPONENT:COMPONENTFUNC(Request& context)`.
|
||||
|
||||
When `name` starts with `:`, the runtime resolves that named handler against the current `.uce` file.
|
||||
|
||||
|
||||
@@ -70,22 +70,22 @@ options["components"]["node.directive"] = "components/markdown/directive";
|
||||
|
||||
If both an exact directive hook and a generic `node.directive` hook exist, the exact directive hook wins.
|
||||
|
||||
When a markdown hook component is called, its props arrive in `context.call`.
|
||||
When a markdown hook component is called, its props arrive in `context.props`.
|
||||
|
||||
Useful fields include:
|
||||
|
||||
- `context.call["hook"]` for the matched hook key such as `:::warning` or `node.code_block`
|
||||
- `context.call["target"]` for the resolved component target name
|
||||
- `context.call["default_html"]` for the renderer output without the hook
|
||||
- `context.call["children_html"]` for already-rendered child HTML
|
||||
- `context.call["node"]` for the full AST node
|
||||
- `context.call["type"]` for the node type
|
||||
- `context.call["name"]` for the directive name when applicable
|
||||
- `context.call["argument"]` for directive remainder after the name
|
||||
- `context.call["text"]` for source text used by nodes such as `code_block`
|
||||
- `context.call["lang"]` for fenced code language
|
||||
- `context.call["href"]`, `context.call["src"]`, and `context.call["title"]`
|
||||
- `context.call["options"]` for the full markdown options tree
|
||||
- `context.props["hook"]` for the matched hook key such as `:::warning` or `node.code_block`
|
||||
- `context.props["target"]` for the resolved component target name
|
||||
- `context.props["default_html"]` for the renderer output without the hook
|
||||
- `context.props["children_html"]` for already-rendered child HTML
|
||||
- `context.props["node"]` for the full AST node
|
||||
- `context.props["type"]` for the node type
|
||||
- `context.props["name"]` for the directive name when applicable
|
||||
- `context.props["argument"]` for directive remainder after the name
|
||||
- `context.props["text"]` for source text used by nodes such as `code_block`
|
||||
- `context.props["lang"]` for fenced code language
|
||||
- `context.props["href"]`, `context.props["src"]`, and `context.props["title"]`
|
||||
- `context.props["options"]` for the full markdown options tree
|
||||
|
||||
Directive blocks use this form:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user