Skip to content

fix(router): replace bloom filter inventory with index-based bitfield#220

Merged
mohamedmansour merged 1 commit intomainfrom
fix/inventory-index-bitfield
Apr 11, 2026
Merged

fix(router): replace bloom filter inventory with index-based bitfield#220
mohamedmansour merged 1 commit intomainfrom
fix/inventory-index-bitfield

Conversation

@mohamedmansour
Copy link
Copy Markdown
Contributor

The FNV-1a bloom filter (256-bit, hash mod 256) caused false-positive collisions when many components mapped to the same bit position. This broke client-side navigation in apps with 30+ components -- the server would skip sending templates it thought the client already had.

Replace with sequential index-based bitfield:

  • Server assigns each custom element a sequential index (0, 1, 2...) based on alphabetically sorted component names from both protocol.fragments and protocol.components
  • Inventory is a hex-encoded bitfield where bit N = component N loaded
  • Zero hash collisions guaranteed
  • Bitfield size = ceil(N/8) bytes (e.g. 3 bytes for 19 components vs 32 bytes for the old bloom filter)

Client changes:

  • Inventory is now an opaque hex string -- client stores it from SSR meta tag, sends it back via X-WebUI-Inventory, receives updated hex from partial responses
  • Renamed releaseTemplates() to gc() -- clears all cached templates and resets inventory to empty
  • Removed all client-side hash functions and bit manipulation
  • inventory.ts simplified to just a module doc comment

Server changes (route_handler.rs):

  • build_component_index() assigns sequential indices from the union of protocol.fragments and protocol.components (hyphenated names only)
  • filter_needed_components() uses bitwise has_component/set_component with the index map instead of FNV-1a hash
  • SSR emits compact inventory meta tag

@mohamedmansour mohamedmansour requested review from a team and mcritzjam April 11, 2026 07:41
The FNV-1a bloom filter (256-bit, hash mod 256) caused false-positive
collisions when many components mapped to the same bit position. This
broke client-side navigation in apps with 20+ components -- the server
would skip sending templates it thought the client already had.

Replace with sequential index-based bitfield:
- Server assigns each custom element a sequential index (0, 1, 2...)
  based on alphabetically sorted component names from both
  protocol.fragments and protocol.components
- Inventory is a hex-encoded bitfield where bit N = component N loaded
- Zero hash collisions guaranteed
- Bitfield size = ceil(N/8) bytes (e.g. 3 bytes for 19 components
  vs 32 bytes for the old bloom filter)

Client changes:
- Inventory is now an opaque hex string -- client stores it from SSR
  meta tag, sends it back via X-WebUI-Inventory, receives updated hex
  from partial responses
- Renamed releaseTemplates() to gc() -- clears all cached templates
  and resets inventory to empty
- Removed all client-side hash functions and bit manipulation
- inventory.ts simplified to just a module doc comment

Server changes (route_handler.rs):
- build_component_index() assigns sequential indices from the union of
  protocol.fragments and protocol.components (hyphenated names only)
- filter_needed_components() uses bitwise has_component/set_component
  with the index map instead of FNV-1a hash
- SSR emits compact inventory meta tag

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohamedmansour mohamedmansour force-pushed the fix/inventory-index-bitfield branch from 6f971fb to 45ae03f Compare April 11, 2026 08:08
@mohamedmansour mohamedmansour merged commit bf5e264 into main Apr 11, 2026
21 checks passed
@mohamedmansour mohamedmansour deleted the fix/inventory-index-bitfield branch April 11, 2026 17:19
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.

2 participants