Skip to content

Client/server Data Strategy #38

Description

@bart-krakowski

Parent

#25

What to build

Add a pluggable `strategy` option to the kernel (inspired by AG Grid's row model). In `'client'` mode all pipeline stages run in-process. In `'server'` mode the delegatable stages — recurrence-expand, conflict-detect, slot-generation — run server-side via the same isomorphic Validation Core; the client receives materialized results and only runs clip-to-viewport and layout.

The consumer's calendar API is identical in both modes. The observable output (`Day[]`, event layout, conflict arrays) must match regardless of which strategy is active.

This is computation push-down, not just data-sourcing. The boundary is serializable for free because ADR-0002 restricts all public types to native `Date`, `YYYY-MM-DD` strings, and plain objects — no Temporal instances, no class instances.

The kernel emits a serializable operation request per delegatable stage (e.g. `{ op: 'expandRange', range, events, config }`). This request is also the TanStack Query key, so caching and invalidation require no extra plumbing. The consumer provides a `transport` function that forwards the request to their endpoint, which calls the matching server-side handler from `@tanstack/time-server`.

In `'client'` mode advisory and authoritative validation collapse — the client is the only validator. In `'server'` mode the client runs advisory checks; the server is authoritative.

Acceptance criteria

  • `createCalendar({ strategy: 'client' })` behaves identically to the current in-process behaviour
  • `createCalendar({ strategy: 'server', transport })` forwards delegatable stages to the consumer's `transport` function
  • `transport` receives a serializable operation request and returns a plain-object result; it owns the fetch/RPC/auth
  • The operation request object is stable and suitable as a TanStack Query `queryKey`
  • `@tanstack/time-server` exports a handler per delegatable operation that the consumer's endpoint calls
  • Given the same event data, `strategy: 'client'` and `strategy: 'server'` (with a mock transport) produce identical `Day[]` output
  • Clip-to-viewport and layout always run client-side regardless of strategy

Blocked by

#28
#37

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions