Skip to content
Merged
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
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,27 @@ jobs:
python -m pip install build
python -m build

web:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: web/package-lock.json
- run: npm ci
working-directory: web
- run: npm test
working-directory: web
- run: npm run build
working-directory: web
- name: Check static Pages artifact
working-directory: web
run: |
test -s dist/index.html
test "$(find dist -type f | wc -l)" -eq 1

test-embedded:
runs-on: ubuntu-latest
timeout-minutes: 45
Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `miniconf_mqtt` is now async-first on `minimq::Session`. The old `update()` loop was replaced by
`Miniconf::poll().await`, which returns `Changed`, `Connected`, `Reconnected`, or `Other`.
* `miniconf_mqtt` MM2 now publishes retained manifest, paged schema, and authoritative retained
settings. Compatibility with request/response-only settings writes is retained behind the
`compat-settings-ingress` feature.
settings. Compatibility with direct `settings/#` writes is available when applications
explicitly subscribe to and route those publications through `Service`.
* MM2 manifests now publish `epoch` and `schema_rev`. Long-lived Python clients use `schema_rev`
to invalidate cached schema.
* The Python package was restructured from `py/miniconf-mqtt` to `py/` and now targets the MM2
Expand Down
2 changes: 1 addition & 1 deletion miniconf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ boundary needs something more specific:
[`macro@TreeDeserialize`], and [`macro@TreeAny`]. Derive attributes live under
`#[tree(...)]`:

- `rename = "name"` changes a field or variant path segment.
- `rename = ident` changes a field or variant path segment to a Rust identifier.
- `skip` removes a field or variant from the tree.
- `flatten` splices a single unambiguous child tree into its parent.
- `with = module` delegates access to a custom implementation module.
Expand Down
1 change: 1 addition & 0 deletions miniconf_coap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ license.workspace = true
categories.workspace = true
keywords.workspace = true
repository.workspace = true
readme = "README.md"

[lints]
workspace = true
Expand Down
10 changes: 1 addition & 9 deletions miniconf_coap/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
#![no_std]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]

//! Serve selected `miniconf` trees as CoAP resources.
//!
//! The crate is deliberately sessionless. Applications pass caller-owned settings into value
//! routes, and keep ownership of CoAP sockets, message IDs, tokens, routing, retransmission, and
//! unrelated resources.
//!
//! The schema route serves a JSON manifest at `/schema` and compact text schema pages at
//! `/schema/{page}`.

use miniconf::Indices;

/// Maximum Miniconf tree depth supported by `miniconf_coap`.
Expand Down
2 changes: 1 addition & 1 deletion miniconf_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
//!
//! `#[tree(...)]` is accepted on containers, fields, and variants:
//!
//! - `rename = "name"` exposes a different path segment.
//! - `rename = ident` exposes a different Rust identifier as the path segment.
//! - `skip` removes the field or variant from the tree.
//! - `flatten` splices one child tree into the parent when lookup is unambiguous.
//! - `with = module` delegates schema, serialization, deserialization, and `Any`
Expand Down
68 changes: 68 additions & 0 deletions web/src/TreeView.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<svelte:options runes={true} />

<script lang="ts">
import type { TreeActions, TreeNodeView } from "./lib/tree-view";
import type { NavDirection } from "./lib/tree-navigation";
import TreeItem from "./TreeItem.svelte";

type Props = {
root: string;
nodes: Map<string, TreeNodeView>;
selectedPath: string;
expanded: Set<string>;
flashed?: Set<string>;
actions: TreeActions;
};

let {
root,
nodes,
selectedPath,
expanded,
flashed = new Set(),
actions,
}: Props = $props();

let rootNode = $derived(nodes.get(root));
let focusPath = $state<string | undefined>();
let treeActions = $derived({
...actions,
key(node: TreeNodeView, direction: NavDirection, step?: number) {
const next = actions.key(node, direction, step);
focusPath = next;
return next;
},
} satisfies TreeActions);

$effect(() => {
if (focusPath === undefined) {
return;
}
requestAnimationFrame(() => {
document
.querySelector<HTMLElement>(`[data-tree-path="${CSS.escape(focusPath)}"]`)
?.focus();
});
});
</script>

<ul role="tree">
{#if rootNode}
<TreeItem
node={rootNode}
{nodes}
{selectedPath}
{flashed}
{expanded}
actions={treeActions}
/>
{/if}
</ul>

<style>
ul {
margin: 0;
min-width: 0;
padding: 0;
}
</style>
Loading