Skip to content

Add inspector SQLite shell and property bindings#4410

Open
NathanFlurry wants to merge 7 commits intomainfrom
inspector-sqlite-shell
Open

Add inspector SQLite shell and property bindings#4410
NathanFlurry wants to merge 7 commits intomainfrom
inspector-sqlite-shell

Conversation

@NathanFlurry
Copy link
Member

Description

This adds a manual SQLite shell to the actor Inspector UI, including query execution, result rendering, and editable named-property inputs that re-run the preview. It also adds POST /inspector/database/execute support for both positional args and named properties, updates the raw SQLite binding helpers, and documents the new flow.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

Ran pnpm exec vitest run tests/driver-memory.test.ts -t "POST /inspector/database/execute|GET /inspector/state returns actor state" in rivetkit-typescript/packages/rivetkit.

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@railway-app
Copy link

railway-app bot commented Mar 12, 2026

🚅 Deployed to the rivet-pr-4410 environment in rivet-frontend

Service Status Web Updated (UTC)
frontend-cloud 😴 Sleeping (View Logs) Web Mar 13, 2026 at 5:44 pm
frontend-inspector 😴 Sleeping (View Logs) Web Mar 13, 2026 at 4:05 pm
ladle ❌ Build Failed (View Logs) Web Mar 13, 2026 at 3:41 am
mcp-hub ✅ Success (View Logs) Web Mar 12, 2026 at 8:06 pm
website ❌ Build Failed (View Logs) Web Mar 12, 2026 at 8:05 pm

@NathanFlurry NathanFlurry requested a review from jog1t March 12, 2026 20:01
@railway-app railway-app bot temporarily deployed to rivet-frontend / rivet-pr-4410 March 13, 2026 02:51 Destroyed
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 13, 2026

More templates

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@4410

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@4410

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@4410

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@4410

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@4410

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@4410

@rivetkit/sqlite-vfs

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@4410

@rivetkit/traces

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@4410

@rivetkit/workflow-engine

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@4410

@rivetkit/virtual-websocket

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@4410

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@4410

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@4410

commit: 7dd1550

@claude
Copy link

claude bot commented Mar 13, 2026

PR Review: Add inspector SQLite shell and property bindings

This is a solid feature addition. The backend refactoring (PRAGMA-based schema introspection, named bindings, withDatabase lock helper) is a genuine improvement over the previous approach.

BUGS

parseEditedCellValue regex truncates type names (actor-database.tsx): The regex /\b(int|real|floa|doub|dec|num|bool)\b/ uses truncated fragments 'floa' and 'doub' with word boundaries that prevent matching the actual SQLite type names FLOAT or DOUBLE. Values in those columns will not be coerced to numbers. Fix: use full names 'float' and 'double'.

DEFAULT_SQL hardcodes test_data (actor-database.tsx): Leftover development artifact. Any actor without a test_data table will see an error when opening the SQL shell. Better default: SELECT name FROM sqlite_master WHERE type = 'table'.

CORRECTNESS

applyEdits is not transactional (actor-database.tsx): Staged cell edits are applied as individual sequential UPDATE statements. If one fails midway, earlier updates are already committed and the UI shows the batch as still pending. Wrapping the batch in BEGIN/COMMIT/ROLLBACK would make multi-cell edits atomic.

Null round-trip is broken (actor-database.tsx): formatCellDraft returns an empty string for null. When saved, parseEditedCellValue returns empty string not null. A NULL cell cannot be edited back to NULL unless the user types the word null. Consider using 'NULL' as the initial draft value for null cells to match expected parsing behavior.

MINOR

normalizeSqlitePropertyBindings triple-keys every property (actor-inspector.ts): Each unadorned key is expanded to three entries (colon, at-sign, dollar). Only one is ever used by SQLite. A brief comment explaining the intent would help future readers.

withDatabase relies on result as T cast (actor-inspector.ts): The let result pattern works today but is fragile. Returning directly from the lock callback would be more explicit.

jsonSafe silently truncates bigints (actor-inspector.ts): BigInts beyond MAX_SAFE_INTEGER lose precision. Acceptable for a debugging tool but worth a comment.

Named binding extraction does not skip string literals (actor-database.tsx): extractNamedBindings matches raw SQL, so bindings inside quoted strings generate spurious UI fields. Minor UX issue, not a security concern.

TEST COVERAGE: Happy-path tests are good. Suggested additions: empty sql, both args and properties supplied simultaneously, invalid binding type, malformed SQL.

DOCUMENTATION: Additions in debugging.mdx, sqlite.mdx, and skill-base-rivetkit.md are clear and accurate.

SUMMARY: The two bugs (regex truncation and DEFAULT_SQL) and the null round-trip should be fixed before merge. Non-transactional edit batching is a correctness concern worth addressing. Everything else is minor polish.

Copy link
Contributor

@jog1t jog1t left a comment

Choose a reason for hiding this comment

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

some stuff related to the react code, which llm did you use? i think we need to install react skills in the repo for better results.

}, [stagedEdits]);
const stagedEditCount = stagedEditList.length;

useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

this should happen on callback, no need for useEffect here, common llm mistake

just call those cleanup functions when the setTable i called, in transition for batched update.

setTableEditError(null);
}, []);

const applyEdits = useCallback(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

i wonder if this could be moved to the mutation, instead of doing everything here

const hasNextPage = page < totalPages - 1;
const hasPrevPage = page > 0;

const beginCellEdit = useCallback(
Copy link
Contributor

Choose a reason for hiding this comment

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

there's a lot of logic that can be encapsulated in the separate hook so the row editing is a separate hook.

Record<string, string>
>({});
const [bindingChangeToken, setBindingChangeToken] = useState(0);
const [result, setResult] = useState<DatabaseExecuteResult | null>(null);
Copy link
Contributor

Choose a reason for hiding this comment

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

there's no need to have this here, you can use the mutation state for that.

const hasMixedBindings = hasNamedBindings && hasPositionalBindings;

useEffect(() => {
setPropertyDrafts((current) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

thats create a race condition that can overwrite user interaction (seen below), this can be derived on a first render.

};
}, [namedBindings, propertyDrafts]);

const resultColumns = useMemo(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

no need for useMemos, they obstruct the code and are added by the react compiler

bindingError === null &&
propertiesError === null;

useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

what this do?

Comment on lines +761 to +781
<ScrollArea className="h-full w-full">
{result === null ? null : result.rows.length === 0 ? (
<div className="px-3 py-4 text-sm text-muted-foreground">
Statement executed successfully. No rows were
returned.
</div>
) : resultRowsAreTable && resultColumns.length > 0 ? (
<DatabaseTable
className="overflow-hidden"
columns={resultColumns}
enableColumnResizing={false}
enableRowSelection={false}
enableSorting={false}
data={result.rows}
/>
) : (
<pre className="overflow-auto px-3 py-4 text-xs">
{JSON.stringify(result.rows, null, 2)}
</pre>
)}
</ScrollArea>
Copy link
Contributor

Choose a reason for hiding this comment

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

i think this view should be rethinked -> inline editing is not possible when using db shell, is that correct?

}

const response = await fetch(
`${computeActorUrl({ ...credentials, actorId })}/inspector/database/execute`,
Copy link
Contributor

Choose a reason for hiding this comment

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

why does this not follow the BARE protocol?

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