W7 done done

This commit is contained in:
root
2026-06-15 11:04:16 +00:00
parent 04745f39a8
commit 1743c51e46
33 changed files with 110 additions and 547 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ 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`.
Pages intended to serve WebSocket traffic may expose both `RENDER(Request& context)` and `WS(Request& context)`. Files may also define `COMPONENT()` handlers when they intentionally need both page and component behavior in one unit.
Pages that serve WebSocket traffic may expose both `RENDER(Request& context)` and `WS(Request& context)`. Files may also define `COMPONENT()` handlers when one unit needs both page and component behavior.
In that case:
+30
View File
@@ -0,0 +1,30 @@
:sig
String base64_decode(String raw, bool& ok)
:params
raw : Base64 encoded string
ok : set to `true` when decoding succeeds; set to `false` for invalid input
return value : decoded binary-safe string, or an empty string when decoding fails
:see
>string
base64_encode
:content
Decodes a Base64 string.
Pass a `bool` variable for `ok` so callers can distinguish invalid input from a valid empty decoded value.
Example:
```uce
bool ok = false;
String decoded = base64_decode("aGVsbG8=", ok);
// ok == true
// decoded == "hello"
```
Related:
- PHP: `base64_decode($value, true)`
- JavaScript / Node.js: `Buffer.from(value, "base64")`
+27
View File
@@ -0,0 +1,27 @@
:sig
String base64_encode(String raw)
:params
raw : binary-safe source string
return value : Base64 encoded string
:see
>string
base64_decode
:content
Encodes a string with Base64.
UCE strings can contain binary data, so `raw` may include NUL bytes and non-text bytes.
Example:
```uce
String encoded = base64_encode("hello");
// encoded == "aGVsbG8="
```
Related:
- PHP: `base64_encode()`
- JavaScript / Node.js: `Buffer.from(value).toString("base64")`
+4 -4
View File
@@ -27,7 +27,7 @@ UCE is server-first C++ with a small template preprocessor. It does not try to b
- `ONCE(Request& context)` is per-request setup for a unit before its first render/component entry.
- `INIT(Request& context)` is worker-local setup when a unit is loaded.
- `<?= expression ?>` is escaped interpolation; prefer it for user-visible text.
- `<?: expression ?>` is trusted raw markup output, closer to a deliberate `dangerouslySetInnerHTML` decision.
- `<?: expression ?>` writes trusted raw markup, similar to `dangerouslySetInnerHTML` in React.
- `unit_render()` renders another page unit; `component()` returns component HTML as a string.
## Routes and Layouts
@@ -51,11 +51,11 @@ DValue app_items = dv_filter(menu, [](DValue item, String key) { return(item["se
DValue by_section = dv_group_by(menu, [](DValue item, String key) { return(item["section"].to_string()); });
```
Use these when the transformation communicates intent. Prefer explicit loops when side effects or multi-step validation are the main concern.
Use these when a short transformation is clearer than a loop. Prefer explicit loops for side effects or multi-step validation.
## Assets and Islands
Global runtime APIs for assets and islands are intentionally not part of UCE core. The starter emits CSS and JavaScript from the owning unit's `ONCE(Request& context)` hook, with a few shared sibling asset components when multiple components need the same files. The only starter web-affordance helper left is `COMPONENT:island` in `components/theme/web_affordances.uce` for small progressive-enhancement modules. This keeps app policy in the app without an asset registry layer.
UCE core does not provide a global asset or island registry. The starter emits CSS and JavaScript from the owning unit's `ONCE(Request& context)` hook, with a few shared sibling asset components when multiple components need the same files. The starter's `COMPONENT:island` helper in `components/theme/web_affordances.uce` covers small progressive-enhancement modules while keeping app policy in the app.
## Debugging
@@ -66,4 +66,4 @@ When a unit fails to compile, UCE reports the source path, generated C++ path, c
- No client-side virtual DOM is built into UCE.
- No global file-router is imposed by the runtime.
- No JSX-like component tags are required for this workflow.
- Component children/slot syntax is intentionally deferred; use explicit props and component calls for now.
- Component children/slot syntax is not part of UCE yet; use explicit props and component calls for now.
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Keeps children for which f returns true. List-like input stays list-like.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
DValue visible = dv_filter(items, [](DValue item, String key) { return(item["hidden"].to_bool() == false); });
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Groups children into list-like buckets by the string returned from f.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
DValue by_section = dv_group_by(menu, [](DValue item, String key) { return(item["section"].to_string()); });
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns map keys from a DValue. Scalar values produce an empty list.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
StringList keys = dv_keys(context.cfg["menu"]);
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Transforms each child. List-like input stays list-like; map input keeps keys.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
DValue titles = dv_map(items, [](DValue item, String key) { DValue out; out = item["title"].to_string(); return(out); });
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Copies a DValue map except for selected keys.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
DValue safe_user = dv_omit(user, {"password_hash"});
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Copies only selected keys from a DValue map.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
DValue public_user = dv_pick(user, {"name", "avatar"});
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns child values as a list-like DValue.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
DValue menu_items = dv_values(context.cfg["menu"]);
+1 -1
View File
@@ -4,7 +4,7 @@ vector<T> filter(vector<T> items, function<bool (T)> f)
:params
items : list of items to be filtered
f : a function that decides which items should be in the new list
f : predicate function; items are kept when this returns `true`
return value : a new list
:see
+1 -1
View File
@@ -27,7 +27,7 @@ items["custom"] = "x";
// items.is_list() == false, items.is_array() == true
```
`dv_map()` and `dv_filter()` use this distinction to decide whether results re-index from zero or keep their original keys.
`dv_map()` and `dv_filter()` use this distinction: list inputs re-index from zero, while map inputs keep their original keys.
## Related Concepts
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns true when every item matches.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
bool all_named = list_every(routes, [](String s) { return(s != ""); });
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns the first matching item or fallback.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
String route = list_find(routes, [](String s) { return(str_starts_with(s, "dashboard")); }, "index");
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns true when any item matches.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
bool has_dashboard = list_some(routes, [](String s) { return(s == "dashboard"); });
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns a sorted copy of the list.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
auto sorted = list_sort(tags);
+1 -1
View File
@@ -12,7 +12,7 @@ filter
:content
Returns the first occurrence of each string, preserving input order.
These helpers are intentionally small data-shaping conveniences for render code, routers, and configuration trees. They are useful when porting habits from React/Next/Remix code where lists of routes, navigation items, cards, or records are transformed close to the rendering boundary.
These helpers keep common data-shaping code close to render code, routers, and configuration trees. They are useful for route lists, navigation items, cards, and records that need simple transformations before rendering.
```cpp
auto tags = list_unique({"uce", "docs", "uce"});
+29
View File
@@ -0,0 +1,29 @@
:sig
StringMap split_kv(String s, char separator = '=', bool trim_whitespace = true, bool uppercase_keys = false)
:params
s : input containing one key/value pair per line
separator : character separating each key from its value
trim_whitespace : trim keys and values when true
uppercase_keys : uppercase keys when true
return value : map of parsed keys and values
:see
>string
split
split_http_headers
:content
Parses simple line-based key/value text into a `StringMap`.
Each non-empty line is split on the first `separator`. Lines without the separator are kept with an empty value.
Example:
```uce
StringMap cfg = split_kv("host = localhost\nport = 8080");
// cfg["host"] == "localhost"
// cfg["port"] == "8080"
```
This is useful for small config files, metadata blocks, and tests that need predictable key/value parsing.
+1 -1
View File
@@ -20,7 +20,7 @@ If a process with the same `key` is already running anywhere in the runtime inst
Task keys may contain ordinary user-facing text. UCE hashes the key before using it as an internal lock/status filename so slashes and other path-like characters cannot escape the task state directory.
`timeout` is enforced in the child process with an alarm. The default is ten minutes. Pass `0` only for tasks that are intentionally unbounded and have their own shutdown path.
`timeout` is enforced in the child process with an alarm. The default is ten minutes. Pass `0` only for tasks that have their own shutdown path.
Related:
+1 -1
View File
@@ -21,7 +21,7 @@ Starts a repeating background worker process.
If a process with the same `key` is already running anywhere in the runtime instance, `task_repeat()` does not start a second worker and instead returns the PID of the existing one. Coordination is through the same shared task state used by `task()`.
`timeout` bounds the lifetime of the repeating worker. The default is ten minutes. Pass `0` only for intentionally unbounded workers with another shutdown path.
`timeout` bounds the lifetime of the repeating worker. The default is ten minutes. Pass `0` only for workers that have another shutdown path.
Related:
+1 -1
View File
@@ -12,7 +12,7 @@ Returns the payload of the current WebSocket message being handled by `WS(Reques
For text frames this is the decoded text payload. For binary frames this `String` contains the raw message bytes.
Use `ws_is_binary()` or `ws_opcode()` to decide how the payload should be interpreted.
Use `ws_is_binary()` or `ws_opcode()` to choose how to parse the payload.
Related:
+1 -1
View File
@@ -15,7 +15,7 @@ String
:content
Parses a simple XML document into a structured `DValue`.
`xml_decode()` is intentionally small. It does not validate schemas, DTDs, namespaces, or document types. It parses the first root element and returns the same structural element shape accepted by `xml_encode()`.
`xml_decode()` parses a compact XML subset. It does not validate schemas, DTDs, namespaces, or document types. It parses the first root element and returns the same structural element shape accepted by `xml_encode()`.
Try the live example in the [XML demo](../demo/xml.uce).
+1 -1
View File
@@ -15,7 +15,7 @@ xml_decode
:content
Parses a practical YAML subset into a `DValue`.
`yaml_decode()` is designed for concise UCE config files. It intentionally avoids full YAML schema behavior and does not support anchors, aliases, tags, directives, or complex inline collection syntax.
`yaml_decode()` is designed for concise UCE config files. It supports a practical YAML subset and does not implement anchors, aliases, tags, directives, or complex inline collection syntax.
Try the live example in the [YAML demo](../demo/yaml.uce).