Skip to content

Revamp site & playground; new RPC + live + scope features (#74)#74

Merged
ryanrasti merged 1 commit into
mainfrom
ryan_ops_demo
May 7, 2026
Merged

Revamp site & playground; new RPC + live + scope features (#74)#74
ryanrasti merged 1 commit into
mainfrom
ryan_ops_demo

Conversation

@ryanrasti
Copy link
Copy Markdown
Owner

@ryanrasti ryanrasti commented May 5, 2026

  1. RPC: exoeval safely interprets restricted JS against @tool-marked
    methods; streaming via AsyncIterable.
  2. Live queries: qb.live(db) re-yields rows when committed mutations
    would change the result.
  3. Principals: .scope(ctx) / .contextOf(row) thread a principal
    object through the query graph (codegen flows it n joins deep).
  4. Site: Next → Astro.
  5. Playground: WMS-themed demo exercising RPC + live + scoped reads.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR modernizes the Typegres demo/playground and extends core library capabilities to support (1) capability-rooted RPC over exoeval with streaming results, and (2) scoped queries that carry a per-request “principal/context” tag through relation traversal and hydration.

Changes:

  • Add scoped query context propagation (Table.scope(ctx) + Table.contextOf(row)) and update codegen to preserve scope through relation methods.
  • Improve type/runtime ergonomics for expressions and rows (e.g., TsTypeOf non-Anynever, SetRow accepts expressions; add Any.in(...); harden Any.from(...) against accidental class-instance params).
  • Replace the site’s Next-based demo with an Astro-based static site + new in-browser playground, including live queries and RPC streaming.

Reviewed changes

Copilot reviewed 73 out of 77 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
tsdown.config.ts Adds exoeval entry point to the build outputs.
src/types/runtime.ts Refines TsTypeOf, SetRow, and runtime guards for update expressions.
src/types/overrides/any.ts Adds Any.in(...) and tightens Any.from(...) runtime validation.
src/types/index.test.ts Adds/updates type & runtime tests for TsTypeOf, Any.in, and Any.from.
src/tables/generate.ts Adds @tool() decoration defaults + scope propagation in generated relations; introduces block-update mode.
src/tables/generate.test.ts Tests for new table generation/update behavior and decorator preservation.
src/table.ts Introduces scoped query tagging API (scope, context, contextOf) and context typing.
src/scope.test.ts End-to-end tests for scope propagation across hydration and relation hops.
src/rpc.test.ts Updates RPC usage to pass captures via second argument.
src/live/ISSUES.md Documents a new live-update ambiguity issue and suggested fixes.
src/live/extractor.ts Adjusts runLiveIteration DB typing to Database<any>.
src/live/events.ts Moves events-table DDL out to a standalone module; re-exports for compatibility.
src/live/events-ddl.ts New standalone module exporting events table name + DDL statements.
src/live/bus.ts Adds subscription cancellation to unblock parked consumers on stop/shutdown.
src/index.ts Re-exports RPC/tooling and live-events entry points; makes typegres generic over context type.
src/exoeval/rpc.ts Changes RawChannel to streaming, adds hybrid run() return (thenable + async iterable), improves safeStringify.
src/exoeval/rpc.test.ts Adds tests for captures-as-arg, streaming behavior, and array non-streaming semantics.
src/exoeval/index.ts Re-exports tool and RPC utilities from exoeval package entry.
src/database.ts Makes Database generic over context; forwards context into db.Table; ensures live events DDL exists on startLive; abort-aware live iteration.
src/builder/update.ts Allows SET values to be typed expressions (Any) without re-wrapping.
src/builder/update.test.ts Adds coverage for .set() with expressions and returning projections.
src/builder/query.ts Documents/locks RowTypeToTsType behavior; adds .live(db) terminator; broadens db arg types.
src/builder/query.test.ts Pins nested scalar typing + verifies row method keys become never.
src/builder/insert.ts Broadens db arg typing to Database<any>.
src/builder/delete.ts Broadens db arg typing to Database<any>.
site/vitest.config.ts Adds SWC decorators support for vitest and widens deps handling for file:.. typegres.
site/tsconfig.json Switches to Astro strict tsconfig base and updates includes/excludes.
site/tailwind.config.js Adds table flash animations for the playground output UI.
site/src/styles/globals.css New consolidated global styles for Astro site.
site/src/pages/play.astro Adds /play route for the new playground.
site/src/pages/index.astro Adds Astro home route wrapper around the React home page component.
site/src/pages/docs.astro Static redirect page for typedoc output under /api/.
site/src/pages/_PlayWidgets.tsx Widget UI + code stamping for the playground; uses Any.in and live/execute terminators.
site/src/pages/_PlayPaths.ts Centralizes widget file path constants.
site/src/pages/_PlayPageInner.tsx Eager Monaco/editor shell with lazy-loaded active output area.
site/src/pages/_PlayPage.tsx Client-only React entry for Astro with error boundary wrapper.
site/src/pages/_PlayActiveArea.tsx Lazy-loaded runtime area: runs/stops RPC streams, renders table/SQL, captures .debug() output.
site/src/pages/_HomePage.tsx Updates home content and removes Next-specific UI artifacts.
site/src/layouts/BaseLayout.astro New Astro base layout w/ meta tags and plausible analytics.
site/src/demo/widgets/orders.ts Demo widget script for orders (live query).
site/src/demo/widgets/inventory.ts Demo widget script for inventory (live query + debug).
site/src/demo/server/api.ts New capability-rooted API and in-memory RPC client wiring for the demo.
site/src/demo/seed.ts New demo DDL + seed data for PGlite runtime.
site/src/demo/schema/users.ts Demo schema class for users with @tool() fields/relations + live transformer.
site/src/demo/schema/shipments.ts Demo schema class for shipments + relations + live transformer.
site/src/demo/schema/organizations.ts Demo schema class for organizations + relations + live transformer.
site/src/demo/schema/orders.ts Demo schema class for orders + row action method demonstrating SQL CASE update.
site/src/demo/schema/order_lines.ts Demo schema class for order_lines + relations + live transformer.
site/src/demo/schema/locations.ts Demo schema class for locations + relations + live transformer.
site/src/demo/schema/inventory_positions.ts Demo schema class for inventory_positions + row action method for adjustments.
site/src/demo/schema/customers.ts Demo schema class for customers + relations + live transformer.
site/src/demo/runtime.ts Boots PGlite + runs migrations/seed + starts live bus for the playground.
site/src/demo/demo.test.ts E2E tests covering scoped reads, Any.in, relation traversal scope, live streaming, stop semantics, and debug logging.
site/src/components/SyntaxHighlight.tsx Removes Next "use client" directive (Astro/React islands).
site/src/components/CodeEditor.tsx Replaces Next dynamic import with React.lazy for Monaco editor integration.
site/package.json Switches site from Next to Astro; updates deps/scripts; uses typegres: file:...
site/next.config.js Removes Next configuration (deleted).
site/next-env.d.ts Removes Next TypeScript env file (deleted).
site/index.html Removes prior static entrypoint (deleted).
site/globals.css Removes prior global styles file (deleted).
site/astro.config.mjs Adds Astro config with SWC decorators, PGlite asset handling, and dev fs widening.
site/app/play/page.tsx Removes Next App Router playground page (deleted).
site/app/layout.tsx Removes Next root layout (deleted).
site/app/icon.svg Removes Next icon asset (deleted).
site/app/docs/route.ts Removes Next redirect route (deleted).
site/.gitignore Adds Astro build artifacts and generated/public outputs to ignores.
site/.eslintrc.json Removes Next ESLint config (deleted).
README.md Updates examples, status section, and adds link to /play demo.
package.json Adds ./exoeval export path for consumers.
ISSUES.md Marks several “critical” issues as fixed and updates roadmap items.
examples/basic/typegres.config.ts Updates config import path to typegres root export.
examples/basic/src/tables/toys.ts Updates imports to typegres root export.
examples/basic/src/tables/teams.ts Updates imports to typegres root export.
examples/basic/src/tables/microchips.ts Updates imports to typegres root export.
examples/basic/src/tables/dogs.ts Updates imports to typegres root export and consolidates sql import.
examples/basic/src/tables/collars.ts Updates imports to typegres root export.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread site/src/demo/runtime.ts Outdated
Comment on lines +7 to +9
import type { OperatorRoot } from "./server/api";

export const db = await typegres<OperatorRoot>({ type: "pglite" });
Comment thread site/src/demo/schema/orders.ts Outdated
Comment on lines +1 to +4
import { Int8, Text, Timestamptz, TypegresLiveEvents, sql, tool, type Database } from "typegres";
import { db } from "../runtime";
import type { OperatorRoot } from "../server/api";
import { Customers } from "./customers";
Comment on lines +1 to +4
import { Int8, Text, TypegresLiveEvents, sql, tool, type Database } from "typegres";
import { db } from "../runtime";
import type { OperatorRoot } from "../server/api";
import { Locations } from "./locations";
Comment thread site/src/demo/schema/organizations.ts
Comment thread site/src/demo/schema/locations.ts Outdated
@tool() organization_id = (Int8<1>).column({ nonNull: true });
// relations
@tool() organization() { return Organizations.scope(Locations.contextOf(this)).where(({ organizations }) => organizations.id["="](this.organization_id)).cardinality("one"); }
@tool() inventory_positions() { return InventoryPositions.scope(Locations.contextOf(this)).where(({ inventory_positions }) => inventory_positions.location_id["="](this.id)).cardinality("one"); }
Comment thread site/src/components/CodeEditor.tsx Outdated
Comment on lines 18 to 22
}

const MonacoEditor = dynamic(() => import("@monaco-editor/react"), {
ssr: false,
});
const MonacoEditor = lazy(() => import("@monaco-editor/react"));

export interface CodeEditorProps {
Comment thread src/table.ts
Comment thread src/table.ts
Comment thread site/src/demo/seed.ts
Comment on lines +11 to +23
sql`CREATE TABLE organizations (
id int8 GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name text NOT NULL,
slug text NOT NULL UNIQUE
)`,
sql`CREATE TABLE users (
id int8 GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
organization_id int8 NOT NULL REFERENCES organizations(id),
name text NOT NULL,
email text NOT NULL UNIQUE,
role text NOT NULL,
token text NOT NULL UNIQUE
)`,
  1. RPC: exoeval safely interprets restricted JS against `@tool`-marked
     methods; streaming via AsyncIterable.
  2. Live queries: `qb.live(db)` re-yields rows when committed mutations
     would change the result.
  3. Principals: `.scope(ctx)` / `.contextOf(row)` thread a principal
     object through the query graph (codegen flows it n joins deep).
  4. Site: Next → Astro.
  5. Playground: WMS-themed demo exercising RPC + live + scoped reads.
@ryanrasti ryanrasti changed the title Re-vamp demo & some fixes along the way Revamp site & playground; new RPC + live + scope features (#74) May 7, 2026
@ryanrasti ryanrasti merged commit a0129a0 into main May 7, 2026
3 checks passed
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