Skip to content

feat(routing): Add routing infra to contact book manager#99

Merged
mohamedmansour merged 14 commits intomainfrom
mmansour/route-contact-book-example
Mar 13, 2026
Merged

feat(routing): Add routing infra to contact book manager#99
mohamedmansour merged 14 commits intomainfrom
mmansour/route-contact-book-example

Conversation

@mohamedmansour
Copy link
Copy Markdown
Contributor

@mohamedmansour mohamedmansour commented Mar 12, 2026

Description:

Refactors the contact-book-manager example from a single-page monolith into a route-based architecture with lazy-loaded page components and a dedicated Express API server.

Changes

  • Route-based pages — Split the monolithic cb-app into dedicated page components (cb-page-dashboard, cb-page-contacts, cb-page-favorites, cb-page-group) with their own HTML templates and styles
  • Express API server (server/api.ts) — New API backend serving both SSR route state endpoints and REST CRUD endpoints for contacts
  • Client API layer (src/api.ts) — Shared API client and Contact type used across page components
  • Sidebar & header navigation — Updated to use link-based navigation; removed JS-driven nav; fixed link
    text-decoration
  • Contact detail & form — Extracted into standalone components with proper hydration support
  • Data consolidation — Removed duplicate contacts.json; API server now reads from state.json as single source of truth
  • Bump pnpm to 10.31.0

mohamedmansour and others added 6 commits March 12, 2026 13:32
Handler:
- RenderOptions with entry_id and request_path
- Route matcher: iterative path matching (no regex)
- Route handler: component inventory, f-template queries
- Route fragment rendering with specificity-based matching
- Perf: escape_html buffer reuse, route scan guard

Bindings:
- FFI: 6-param webui_handler_render, webui_get_route_templates
- Node: render() with entry + requestPath
- WASM: routing support in render and build_and_render
- CLI serve: JSON partial responses for client navigation

Updated DESIGN.md, integration examples, benchmarks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Navigation API interception for SPA transitions
- Self-registering <webui-route> custom element via connectedCallback
- Iterative path matching with :param, :param?, *splat (no regex)
- Specificity-based route ranking
- Opt-in lazy loading via loaders config with promise dedup
- SSR-safe: preserves server-rendered DOM on initial navigation
- Component inventory bloom filter for template dedup
- webui:route:navigated CustomEvent after each navigation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…xample

- Route definitions in cb-app.html (<route> directive)
- Page components: dashboard, contacts, favorites, group
- Co-located child imports (each component imports its own deps)
- Lazy loading via Router.start({ loaders }) + esbuild --splitting
- Server API for contact CRUD operations
Comment thread examples/app/contact-book-manager/server/api.ts Dismissed
@mohamedmansour mohamedmansour requested a review from a team March 12, 2026 22:30
Copy link
Copy Markdown
Contributor

@akroshg akroshg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

routes made this app so complicated to understand, at least for me.
We should revisit this, once Fast issue gets fixed (specially there are lot of components ts code which I did not bother review it)
Can you also run the performance benchmark before merging code?
cargo bench -p webui --bench contact_book_bench

Comment thread examples/app/contact-book-manager/src/cb-app/cb-app.ts
Comment thread examples/app/contact-book-manager/src/cb-app/cb-app.ts
Comment thread examples/app/contact-book-manager/server/api.ts
Comment thread examples/app/contact-book-manager/server/api.ts
Comment thread examples/app/contact-book-manager/src/api.ts
@mohamedmansour
Copy link
Copy Markdown
Contributor Author

routes made this app so complicated to understand, at least for me. We should revisit this, once Fast issue gets fixed (specially there are lot of components ts code which I did not bother review it) Can you also run the performance benchmark before merging code? cargo bench -p webui --bench contact_book_bench

============================= WebUI Contact Book — Performance Summary =============================
Story                     Iters   Avg(ms)       Min       Max   Dev%       P50       P90       P99       IQR     Bytes
----------------------------------------------------------------------------------------------------
ProtocolParse            147401      0.02      0.01      0.21  10.3%      0.02      0.02      0.02      0.00     29535
Render/10                 21033      0.14      0.12      0.20   5.5%      0.14      0.16      0.17      0.00     41109
Render/100                 3004      1.00      0.90      1.24   3.3%      0.99      1.04      1.12      0.04    149594
Render/1000                 317      9.48      9.11     10.29   2.2%      9.42      9.78     10.16      0.25   1238944
RenderFAST/10             20812      0.14      0.13      0.25   4.3%      0.14      0.15      0.17      0.00     44963
RenderFAST/100             2984      1.01      0.94      1.23   2.9%      1.00      1.04      1.13      0.03    153448
RenderFAST/1000             316      9.50      9.09     10.34   2.6%      9.43      9.85     10.24      0.31   1242798
====================================================================================================

@mohamedmansour mohamedmansour changed the title feat(routing): add routing infra to contact book manager feat(routing): Add routing infra to contact book manager Mar 13, 2026
@mohamedmansour mohamedmansour requested review from a team and akroshg March 13, 2026 04:41
totalContacts: contacts.length,
totalFavorites: favorites.length,
totalGroups: groups.length,
groups,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

groups is not a stat.

if (query) {
const q = query.toLowerCase();
result = result.filter(c =>
c.firstName.toLowerCase().indexOf(q) !== -1 ||
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not saying you have to change it but you have this computeinitials thing as a helper earlier and then you aren't using it here.

Comment thread examples/app/contact-book-manager/README.md
Copy link
Copy Markdown
Contributor Author

@mohamedmansour mohamedmansour left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass

phone: c.getAttribute('phone') || '',
company: c.getAttribute('company') || '',
group: c.getAttribute('group') || '',
favorite: c.getAttribute('favorite') === 'true',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a boolean? I think I would expect c.hasAttribute('favorite')

@mohamedmansour mohamedmansour merged commit c2bf95f into main Mar 13, 2026
15 checks passed
@mohamedmansour mohamedmansour deleted the mmansour/route-contact-book-example branch March 13, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants