feat: database grid infinite scroll, honest row counts, column virtualization (0340) - #534
Merged
crs48 merged 6 commits intoJul 18, 2026
Conversation
useGridDatabase replaces its fixed 500-row page with a growing window (pageSize 500, maxLoaded 2000) and exposes totalRowCount / hasMoreRows / isFetchingMoreRows / fetchMoreRows. count:'exact' folds the true total into the fused row query. Promotes the 0340 scratch verification into useInfiniteQuery.test.tsx — the hook's first committed coverage. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
…tinel (0340) Columns virtualize past 20 fields (horizontal useVirtualizer, overscan 3, spacer cells) so vertical scrolling mounts a bounded cell window instead of every column per overscan row - measured 8.6fps at 128 unvirtualized columns. Footer reads 'N of M rows' from totalRowCount instead of presenting the window size as the total, and onReachEnd fires near the end of loaded rows for infinite scroll. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
…atabase grid (0340) DatabaseView passes totalRowCount/hasMoreRows/fetchMoreRows through to GridSurface, and labels view filter/sort results 'filtered within loaded rows' whenever more rows exist past the window. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
…(0340) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
…0340) Window grows no longer flip the grid's loading state (which unmounted the surface to a skeleton and lost scroll position) - useGridDatabase now reports the masked loading from useInfiniteQuery and surfaces the grow via isFetchingMoreRows. Row models cache per node identity so a grow rebuilds only new rows, and GridRow is memoized so unchanged visible rows skip re-render entirely. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
…ion and infinite scroll Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: xNet Test <test@xnet.dev>
Contributor
🖼️ UI changes in this PRNo visual differences detected in the changed UI. |
Contributor
|
Preview removed for PR #534. |
crs48
deleted the
claude/0340-grid-60fps-frontier-rows-columns-pagination-and
branch
July 18, 2026 02:35
crs48
added a commit
that referenced
this pull request
Jul 18, 2026
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @xnetjs/cli@0.2.0 ### Minor Changes - [#533](#533) [`0a4a1de`](0a4a1de) Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed agent audit trails (exploration 0337). - `@xnetjs/data`: new agent schema pack — `AgentPassport`, `AgentSession`, `AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic id helpers (`agentActionId`, …) and `redactInstruction`. - `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport` (per-agent `did:key` + operator-delegated, attenuation-checked UCAN; wildcards rejected) and `rootIssuers` for delegation-chain root inspection. - `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every tool call lands as an `AgentAction` node and medium+ risk calls park behind a risk-tiered approval ceremony (chat nonce with TTL for medium; xNet-surface only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`, `xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications` outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server; `NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI scopes `agent.approve` and `agent.notifications`. - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports (`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp serve --agent <name> [--db <path>]` serves an agent-scoped session over an agent-signed local store. ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`fa93e2f`](fa93e2f)]: - @xnetjs/data@2.1.0 - @xnetjs/identity@2.1.0 - @xnetjs/plugins@2.1.0 - @xnetjs/runtime@0.5.1 - @xnetjs/sync@2.1.0 - @xnetjs/sqlite@2.1.0 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/data@2.1.0 ### Minor Changes - [#533](#533) [`0a4a1de`](0a4a1de) Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed agent audit trails (exploration 0337). - `@xnetjs/data`: new agent schema pack — `AgentPassport`, `AgentSession`, `AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic id helpers (`agentActionId`, …) and `redactInstruction`. - `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport` (per-agent `did:key` + operator-delegated, attenuation-checked UCAN; wildcards rejected) and `rootIssuers` for delegation-chain root inspection. - `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every tool call lands as an `AgentAction` node and medium+ risk calls park behind a risk-tiered approval ceremony (chat nonce with TTL for medium; xNet-surface only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`, `xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications` outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server; `NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI scopes `agent.approve` and `agent.notifications`. - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports (`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp serve --agent <name> [--db <path>]` serves an agent-scoped session over an agent-signed local store. ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/identity@2.1.0 - @xnetjs/sync@2.1.0 - @xnetjs/storage@2.1.0 - @xnetjs/sqlite@2.1.0 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/identity@2.1.0 ### Minor Changes - [#533](#533) [`0a4a1de`](0a4a1de) Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed agent audit trails (exploration 0337). - `@xnetjs/data`: new agent schema pack — `AgentPassport`, `AgentSession`, `AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic id helpers (`agentActionId`, …) and `redactInstruction`. - `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport` (per-agent `did:key` + operator-delegated, attenuation-checked UCAN; wildcards rejected) and `rootIssuers` for delegation-chain root inspection. - `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every tool call lands as an `AgentAction` node and medium+ risk calls park behind a risk-tiered approval ceremony (chat nonce with TTL for medium; xNet-surface only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`, `xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications` outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server; `NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI scopes `agent.approve` and `agent.notifications`. - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports (`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp serve --agent <name> [--db <path>]` serves an agent-scoped session over an agent-signed local store. ### Patch Changes - Updated dependencies []: - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/plugins@2.1.0 ### Minor Changes - [#533](#533) [`0a4a1de`](0a4a1de) Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed agent audit trails (exploration 0337). - `@xnetjs/data`: new agent schema pack — `AgentPassport`, `AgentSession`, `AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic id helpers (`agentActionId`, …) and `redactInstruction`. - `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport` (per-agent `did:key` + operator-delegated, attenuation-checked UCAN; wildcards rejected) and `rootIssuers` for delegation-chain root inspection. - `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every tool call lands as an `AgentAction` node and medium+ risk calls park behind a risk-tiered approval ceremony (chat nonce with TTL for medium; xNet-surface only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`, `xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications` outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server; `NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI scopes `agent.approve` and `agent.notifications`. - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports (`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp serve --agent <name> [--db <path>]` serves an agent-scoped session over an agent-signed local store. - [#525](#525) [`fa93e2f`](fa93e2f) Thanks [@crs48](https://github.com/crs48)! - Add the workspace-plugin runtime (exploration 0331): author, hot-load, and compose plugins whose source lives in the workspace as a `PluginSource` node. New public surface: `PluginSourceSchema` + `readPluginSourceNode`, an in-browser module builder (`buildPluginModuleGraph`) with a pinned import map, the `SandboxedPluginHost` (`activateWorkspacePlugin`) that loads plugin code only in an opaque-origin iframe and registers data-declared contributions over MessagePort RPC, a gated store RPC (`createPluginStoreRpc`, denylist-wins), a 250ms-debounce hot reloader (`createWorkspacePluginHotReloader`), content-hash pinning + drift diffing (`computePluginSourceHash`, `assessPluginUpdate`), the `plugin_*` agent tools (`createWorkspacePluginAgentTools`) and the `WRITING_XNET_PLUGINS_SKILL_MD` authoring skill, and both publish paths (`requestWorkspacePluginPublish`, `buildCommunityRegistryEntry`). `MCPServerConfig` gains an `extraTools` field to expose the new tools beside the built-ins. ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/abuse@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/react@2.1.0 ### Minor Changes - [#534](#534) [`5473a29`](5473a29) Thanks [@crs48](https://github.com/crs48)! - `useGridDatabase` now pages database rows through a growing window instead of a fixed 500-row page: new `fetchMoreRows()` grows the window by `pageSize` (default 500) up to `maxLoaded` (default 2000, configurable via options), and the result exposes `totalRowCount` (exact matching count), `hasMoreRows`, and `isFetchingMoreRows` so grids can render honest totals and infinite scroll. Existing consumers keep working unchanged — rows still arrive sorted by `sortKey` on the live query path. ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`fa93e2f`](fa93e2f)]: - @xnetjs/data@2.1.0 - @xnetjs/identity@2.1.0 - @xnetjs/plugins@2.1.0 - @xnetjs/data-bridge@2.1.0 - @xnetjs/history@2.1.0 - @xnetjs/runtime@0.5.1 - @xnetjs/sync@2.1.0 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/abuse@2.1.0 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/identity@2.1.0 - @xnetjs/crypto@2.1.0 ## @xnetjs/crypto@2.1.0 ### Patch Changes - Updated dependencies []: - @xnetjs/core@2.1.0 ## @xnetjs/data-bridge@2.1.0 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/sync@2.1.0 - @xnetjs/sqlite@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/history@2.1.0 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/sync@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/runtime@0.5.1 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`fa93e2f`](fa93e2f)]: - @xnetjs/data@2.1.0 - @xnetjs/identity@2.1.0 - @xnetjs/plugins@2.1.0 - @xnetjs/data-bridge@2.1.0 - @xnetjs/history@2.1.0 - @xnetjs/sync@2.1.0 - @xnetjs/storage@2.1.0 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/storage@2.1.0 ### Patch Changes - Updated dependencies []: - @xnetjs/sqlite@2.1.0 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/sync@2.1.0 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/identity@2.1.0 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 ## @xnetjs/core@2.1.0 ## @xnetjs/sqlite@2.1.0 ## xnet-cloud@0.0.19 ### Patch Changes - Updated dependencies []: - @xnetjs/telemetry@0.0.1 - @xnetjs/crypto@2.1.0 - @xnetjs/core@2.1.0 - @xnetjs/cloud@0.0.1 ## xnet-demos@0.1.3 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`5473a29`](5473a29)]: - @xnetjs/data@2.1.0 - @xnetjs/identity@2.1.0 - @xnetjs/react@2.1.0 - @xnetjs/devtools@0.1.0 ## @xnetjs/brain@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/vectors@0.0.1 ## @xnetjs/comms@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/crypto@2.1.0 ## @xnetjs/dashboard@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`5473a29`](5473a29), [`fa93e2f`](fa93e2f)]: - @xnetjs/data@2.1.0 - @xnetjs/plugins@2.1.0 - @xnetjs/react@2.1.0 - @xnetjs/social@0.0.20 ## @xnetjs/labs@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`fa93e2f`](fa93e2f)]: - @xnetjs/data@2.1.0 - @xnetjs/plugins@2.1.0 ## @xnetjs/licenses@0.0.20 ### Patch Changes - Updated dependencies []: - @xnetjs/crypto@2.1.0 ## @xnetjs/maps@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 ## @xnetjs/meetings@0.0.13 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de), [`fa93e2f`](fa93e2f)]: - @xnetjs/data@2.1.0 - @xnetjs/plugins@2.1.0 ## @xnetjs/server@0.0.19 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/identity@2.1.0 - @xnetjs/data-bridge@2.1.0 - @xnetjs/crypto@2.1.0 ## @xnetjs/social@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 - @xnetjs/crypto@2.1.0 ## @xnetjs/unreal@0.0.20 ### Patch Changes - Updated dependencies [[`0a4a1de`](0a4a1de)]: - @xnetjs/data@2.1.0 ## xnet-desktop@2.1.0 Desktop shell release riding the @xnetjs/core 2.1.0 train. Desktop-specific changes are not tracked here; see the core packages' changelogs for what shipped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements exploration 0340 (docs/explorations/0340_[x]GRID_60FPS_FRONTIER…md) — the render-side fixes measured in that doc:
useGridDatabasereplaces its fixed 500-row page with a growing window viauseInfiniteQuery(pageSize 500,maxLoaded2000), andGridSurfacegrows it from a reach-end sentinel. Window grows keep the grid mounted (masked loading), row models cache per node identity, andGridRowis memoized so grows re-render only new rows.count: 'exact'folds the true total into the fused row query; the footer reads "2,000 of 10,000 rows" instead of presenting the window as the total. Client-side filtered/sorted views on capped windows are labeled "filtered within loaded rows".GridSurfacevirtualizes columns (horizontal virtualizer, overscan 3, spacer cells) — vertical scrolling no longer mounts every column per overscan row.useInfiniteQuerygains its first committed test coverage.Validation (live app, Playwright Chromium, same harness as the exploration baseline)
Changeset:
@xnetjs/reactminor. Changelog fragment included.🤖 Generated with Claude Code