Skip to content

emit: isomorphic ActiveRecord — the use client / use server analog (class-type boundary, profile-selected location) #46

Description

@rubys

Part of #41. Capability C2. Depends on F1 (#38) + K (incl. async-coloring-into-client) + F2. Related: #31, #35, #36.

Goal

Deliver the React Server Components use client / use server benefit — write data logic once, the framework handles where it runs and the wire between — but generalized:

  • the boundary is Ruby class type, not a string directive: ApplicationController = server, Stimulus::Controller / native client = client, ApplicationRecord = isomorphic;
  • the data location (local sqlite-wasm/OPFS / on-device SQLite vs HTTP DB vs /__rpc) is a deploy-profile decision, not authored;
  • reaches client-local (whole backend on-device), which RSC can't.

Existence proof (juntos dictaphone)

The same Clip < ApplicationRecord is used server-side in ClipsController and client-side in a Stimulus controller:

clip = await Clip.create(name:, transcript:, duration:)        # AR in the browser
await clip.audio.attach(@audioBlob, ...)                        # Active Storage, client-side
await clip.broadcast_replace_to("clips")                        # Turbo Stream, from the client

The await is the tell — client AR call sites are async-colored (K §3). roundhouse must make the compiler derive this and emit the model twice (server-language AR + TS/wasm/Kotlin/Swift client AR) from one Ruby source with a matching contract (the F1/#38 polyglot generalization).

Scope

  1. Isomorphic model dual-emit (shared, importable; per-tier).
  2. Transport selection by profile (local DB adapter vs /__rpc).
  3. Carry declarative model metadata across the boundary (validates, has_one_attached, broadcasts_to all run client-side in dictaphone).

THE central decision (folded D — gates this issue)

RPC authorization / exposure boundary: which model operations are client-callable, and how authorized? Client-direct Clip.create bypasses the server's clip_params.permit(...). This is what RSC's 'use server' ceremony exists to guard. Lean server-by-default, client opt-in via a model client / replicated macro.

Open

Local-first sync/conflict when client-local AR later syncs → see #36 (out of v1 scope; name it).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions