JSPM

  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q75458F
  • License MIT

LiveViewJS brings the power of LiveView to Typescript and Javascript developers and applications.

Package Exports

  • liveviewjs
  • liveviewjs/dist/server/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (liveviewjs) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

LiveViewJS

Front-end framework for back-end developers

Credit πŸ™Œ

This is a backend implementation of Phoenix LiveView in Typescript. What the Phoenix folks have built is phenominal and I wanted to use that paradigm in Typescript and make it available to others.

Quick Overview of LiveView Approach

How Phoenix desribes LiveView:

LiveView is an exciting new library which enables rich, real-time user experiences with server-rendered HTML. LiveView powered applications are stateful on the server with bidrectional communication via WebSockets, offering a vastly simplified programming model compared to JavaScript alternatives.

In other words, LiveView takes a very different approach than the popular SPA frameworks like React, Vuejs, and Svelt to building rich, highly interactive web applications. Instead of sending down a bundle of javascript, LiveView apps render an HTML page on the first request and then connect via a persistent socket over which client events are sent and updated received. These events may trigger a state update on the server and a re-calculation of what the page should look like. Instead of reloading the page, the client receives a "diff" of the page via the socket and the page's DOM is updated. See a detailed sequence diagram of the client/server lifecycle.

The programming paradigm is extremely powerful and productive!

Feedback is a 🎁

Please feel free to open an issue with questions, bugs, etc.

Status - Ξ²

LiveViewJS is in Ξ²eta. The project is still young but the code is stable, tested, and well-documented.

Implemented Phoenix Bindings

The bindings below marked with βœ… are working and tested and most of them have example usage in the examples codebase. Those with ?, I have not gotten around to testing so not sure if they work. Those marked with ❌ are not yet implemented and known not to work.

(See Phoenix Bindings Docs for more details)

Binding Attribute Supported
Params phx-value-* βœ…
Click Events phx-click βœ…
Click Events phx-click-away βœ…
Form Events phx-change βœ…
Form Events phx-submit βœ…
Form Events phx-feedback-for βœ…
Form Events phx-disable-with βœ…
Form Events phx-trigger-action οΉ–
Form Events phx-auto-recover οΉ–
Focus Events phx-blur βœ…
Focus Events phx-focus βœ…
Focus Events phx-window-blur βœ…
Focus Events phx-window-focus βœ…
Key Events phx-keydown βœ…
Key Events phx-keyup βœ…
Key Events phx-window-keydown βœ…
Key Events phx-window-keyup βœ…
Key Events phx-key βœ…
DOM Patching phx-update βœ…
DOM Patching phx-remove οΉ–
JS Interop phx-hook βœ…
Rate Limiting phx-debounce βœ…
Rate Limiting phx-throttle βœ…
Static Tracking phx-track-static ❌

LiveViewJS Changesets

Phoenix's Ecto ORM library and Phoenix LiveView rely on Ecto Changesets to allow filtering, validation, and other logic to be applied to the data. Changesets are a powerful way to apply logic to data and are used in Phoenix's ORM and LiveView. LiveViewJS uses Changesets to provide a similar API to Phoenix's though it is NOT a full-blown ORM.

Detailed documentation on LiveViewJS Changesets.

Usage - Show me some code! ⌨️

Step 0 Install LiveViewJS npm i liveviewjs

Step 1 Implement a LiveViewComponent

import { SessionData } from "express-session";
import { BaseLiveView, html, LiveViewContext, LiveViewExternalEventListener, LiveViewMeta, LiveViewMountParams, LiveViewSocket, LiveViewTemplate } from "liveviewjs";

// describe the context (i.e. state of the view)
interface ClickDemoContext extends LiveViewContext{
  count: number;
}
type MyEvent = "user-clicked";
// implement the LiveView
export class ClickDemo extends BaseLiveView<ClickDemoContext, never> implements
// add listener for external events
LiveViewExternalEventListener<ClickDemoContext, MyEvent, never>{

  // mount only called once per http request and per socket connection
  mount(params: LiveViewMountParams, session: Partial<SessionData>, socket: LiveViewSocket<ClickDemoContext>){
    socket.assign({count: 0}); // set initial count to 0
  }

  // render the LiveView content (called each time an event is received)
  render(context: ClickDemoContext, meta: LiveViewMeta): LiveViewTemplate | Promise<LiveViewTemplate> {
    const { count } = context;
    return html`
      <h2>Click Demo</h2>
      <button phx-click="${MyEvent}" type="button">Click to Increment</button>
      <p><strong>Count:</strong>${count}</p>
    `
  }

  // handle user interactions from client
  handleEvent(event: MyEvent, params: never, socket: LiveViewSocket<ClickDemoContext>): void | Promise<void> {
    socket.assign({count: socket.context.count + 1}); // increment count
  }

}

Step 2 - Register your LiveViewComponents and start the server with LiveViewServer

// import package
import {LiveViewServer} from "liveviewjs";

// create new LiveViewServer
const server = new LiveViewServer();

// define your routes by mapping paths to LiveViewComponents
const router: LiveViewRouter = {
  "/clickdemo": new ClickDemo();
}
// AND then passing the router to the server
server.registerLiveViewRoutes(router);

// OR register your route with the server directly
// server.registerLiveViewRoute("/clickdemo", new ClickDemo());

// then start the server
server.start();

Additional Feature Documentation

Other features to be implemented:

NPM Commands

npm i - install the deps

npm run build - builds the framework, client, and examples (server)

npm run watch - continually rebuilds the codebase when files are updated

npm run examples - runs the examples [See src/examples]

npm run test - runs the (few) tests

Run and Browse Examples

Credit: These examples are adapted from an amazing Phoenix Video / Code Course authored by the folks at Pragmatic Studio.

Navigate to src/examples to see the example code.

Run npm run examples then point your browser to:

  • http://localhost:4444/ - Shows the index of all the examples

There is also a standalone TodoMVC example application written in LiveViewJS.

More Details on the Approach to Building LiveViewJS πŸ“

  • Reuse Phoenix Client Libraries and app.js code - The Phoenix team has done a ton of heavy lifting on the client that we can just use. We also benefit from fixes and improvements in the future. [See src/client/liveview.ts for client code.]

  • Reuse Phoenix socket message protocol - The Phoenix team already figured out a great protocol to send events to/from the server. We just implemented a different backend.

  • Follow component API design (i.e. mount, render etc), reimplemented with Typescript (so even more type-safe) - Components in LiveViewJS follow the mount, render, handleEvent, and handleInfo API defined in Phoenix. Again, no need to invent a new API.

Gratitude πŸ™

Thanks to @ogrodnek for the early support, feedback, and the idea to reuse the Phoenix client code instead of reinventing!

Thanks to @blimmer for the awesome feedback, documentation suggests, and support!