caldera-react

Server-side execution for React ?

Github stars Tracking Chart

?

Caldera is a server-side execution environment for React. Think of it as the Node.js analog to Phoenix LiveView — all of the application logic (including rendering) runs on the server, and DOM updates are sent to the client in real-time.

This allows developers to rapidly build interactive and multiplayer applications without developing boilerplate around RPC layers (REST/GraphQL/gRPC) and messaging primitives (WebSockets/subscriptions/etc).

Because it's built on top of the React reconciler, it's compatible with (currently, a reasonably useful subset of) the existing React API. See what's currently included and what's to come for updates.

Installation

Run npm install caldera to install Caldera.

Examples

A simple example (chat room) to get started:

import React, { useState } from "react";
import { renderCalderaApp, makeSharedResource, useSharedState } from "caldera";
import fs from "fs";

const DATA_PATH = "messages.json";
const messagesResource = makeSharedResource(
  // Load initial messages
  fs.existsSync(DATA_PATH)
    ? JSON.parse(fs.readFileSync(DATA_PATH, "utf-8"))
    : []
);

const usePersistedMessages = () => {
  // Basic shared state, synced with all clients
  const [messages, setMessages] = useSharedState(messagesResource);
  return [
    messages,
    // Persist to disk (in prod, use a database)
    (newMessages) => {
      setMessages(newMessages);
      fs.writeFileSync(DATA_PATH, JSON.stringify(newMessages));
    },
  ];
};

const App = () => {
  const [messages, setMessages] = usePersistedMessages();
  // local state, persisted across client reconnects
  const [draftMsg, setDraftMsg] = useState("");

  return (
    <>
      <h1>Chat Room!</h1>
      {messages.map((message, i) => (
        <div key={i}>{message}</div>
      ))}
      <form
        onSubmit={(e) => {
          e.preventDefault();
          setMessages([...messages, draftMsg]);
          setDraftMsg("");
        }}
      >
        <input
          type="text"
          value={draftMsg}
          onChange={(e) => setDraftMsg(e.target.value)}
        />
        <button type="submit">Submit</button>
      </form>
    </>
  );
};

renderCalderaApp(<App />, { port: 4000 });

Install Babel by running npm install @babel/core @babel/node @babel/preset-react.

Then, run the app using babel-node --presets @babel/preset-react index.jsx. For a runnable version, check the basic-example folder.

A few other examples here demonstrate features like shared state, database usage, and session persistence.

API/Documentation

[Work in progress]

The caldera package provides the following top-level exports:

  • Head: A React component that renders its children into the page's <head />
  • renderCalderaApp: A function that takes in a React element, and runs the Caldera server on port 8080
  • makeSharedResource: Creates a shared resource suitable for use in useSharedState and useSharedReducer
  • useSharedState/useSharedReducer: Shared equivalents to the useState and useReducer hooks that are initialized with the current value of the passed in resource, and trigger rerenders in all other call sites upon updating
  • useHistory/useLocation - hooks that enable routing functionality

What works

  • Basic form inputs (text fields/areas, checkboxes, selects, radio buttons)
  • Basic event listeners (onclick/onchange/onsubmit/onfocus/onblur/keyevents)
  • CSS and other head tags (via <Head />)
  • Basic input reconciliation (currently implemented via debounce)
  • Shared state and reducer hooks
  • State serialization and restore + state "forking" whenever a user opens a new client

What's being worked on

  • More events (ondragstart, intersection observers)
  • <input type="file"> support
  • Better, diff-based input reconciliation

Future plans

  • Proper versioning for state serialization
    • This will allow support for upgrading the server in-place, while retaining certain parts of the client state
  • Support for selectively rendering arbitrary React components on the client

Main metrics

Overview
Name With Ownercalderajs/caldera-react
Primary LanguageTypeScript
Program languageJavaScript (Language Count: 3)
Platform
License:
所有者活动
Created At2020-02-26 04:18:49
Pushed At2023-01-07 16:15:30
Last Commit At2020-08-06 23:58:46
Release Count0
用户参与
Stargazers Count564
Watchers Count10
Fork Count10
Commits Count45
Has Issues Enabled
Issues Count5
Issue Open Count5
Pull Requests Count8
Pull Requests Open Count22
Pull Requests Close Count1
项目设置
Has Wiki Enabled
Is Archived
Is Fork
Is Locked
Is Mirror
Is Private