npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

backpage

v0.0.2-8

Published

Naive static HTML streaming based on React for Node.js CLI applications.

Downloads

41

Readme

NPM version Repository package.json version MIT License Discord

BackPage

Naive static HTML streaming based on React for Node.js CLI applications.

How does it work?

BackPage renders your React application to HTML and streams updates (static HTML snapshots) to your browser.

It is designed for really simple GUI as a complementary to text logs, so advanced user interaction is neither supported nor its goal.

Features

  • Stream static HTML from React rendering.
  • Send notification to browser.
  • Simple user interaction with HTML form.
  • Simple webhook usages with /action/[action-name] and /notify endpoints.
  • Public URL via backpage.cloud.

Table of Contents

Installation

npm install react backpage

Basic Usage

main.tsx

import {BackPage} from 'backpage';
import React from 'react';

import {App} from './app.js';

const page = new BackPage();

page.render(<App />);

// Print page information including URL.
page.guide();

app.tsx

import React, {useState, useEffect} from 'react';

export const App = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const timer = setInterval(
      setCount(count => count + 1),
      1000,
    );

    return () => clearInterval(timer);
  }, []);

  return <div>Count: {count}</div>;
};

Form-based Interaction

See Form and ActionButton for simple usage.

Events

BackPage can proxy explicitly specified events that bubble to document from the browser to your Node.js React application.

const page = new BackPage({
  events: ['click'],
});

page.render(
  <div
    onClick={() => {
      console.info('This will work.');
    }}
  >
    Click me!
  </div>,
);

Events are proxied asynchronously, and just for the purpose of triggering actions in your Node.js application.

Not all events bubble, please checkout relevant documents for more information.

click

Properties:

  • altKey
  • ctrlKey
  • metaKey
  • shiftKey

input

Effects:

  • Sets event.target.value to the value of the input element.

Browser Notification

A notification can be sent to the browser using either page.notify() or /notify endpoint.

To send notification to the browser using page.notify():

page.notify('Hello BackPage!');

page.notify({
  title: 'Hello BackPage!',
  body: 'This is a notification from BackPage.',
});

You can also setup a fallback for notifications not getting clicked within the timeout:

const page = new BackPage({
  notify: {
    // timeout: 30_000,
    fallback: notification => {
      // Handle the notification manually.

      // Optionally return a webhook URL or request options to initiate an HTTP
      // request.
      return 'https://some.webhook/';
    },
  },
});

page.notify({
  title: 'Hello BackPage!',
  body: 'Click me or your webhook will get fired!',
});

To send notification to the browser using /notify endpoint:

await fetch('http://localhost:12368/notify', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    title: 'Hello BackPage!',
    body: 'This is a notification from BackPage.',
  }),
});

A timeout field can also be specified (a number or false) to override the default value.

Action

A simple webhook can be setup with /action/[action-name] endpoint.

page.registerAction('hello', data => {
  console.info('Hello', data);
});

To trigger this action:

await fetch('http://localhost:12368/action/hello', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'BackPage',
  }),
});

This uses the same mechanism as the Form action, so you may want to avoid using the same action name (if you explicitly specify one for Form).

BackPage Cloud

By specifying a UUID as token, you can get a public URL from backpage.cloud:

import {BackPage, getPersistentToken} from 'backpage';

const page = new BackPage({
  // You can also use any random UUID for temporary page.
  token: getPersistentToken(),
  // Different pages can be setup using the same token with different names.
  // name: 'project-name',
});

page.guide();

You can also create a temporary front only page for web notifications using https://backpage.cloud/new.

Note: backpage.cloud may introduce value-added services for significant network traffic to cover the expense in the future.

Examples

Check out src/examples.

Built-in Components

Form

A Form is based on HTML form element and has similar usage, except that action is proxied backed by POST requests and accepts callback with the form data object as its parameter.

const action = data => console.info(data);

page.render(
  <Form action={action}>
    <input name="name" />
    <button type="submit">Submit</button>
  </Form>,
);

ActionButton

In many cases, only the button is relevant for an action. ActionButton wraps a button within a Form for those cases:

const action = () => console.info('Launch!');

page.render(<ActionButton action={action}>Launch</ActionButton>);

You can also put multiple ActionButtons in an explicit Form to share the form inputs:

const actionA = data => console.info('action-a', data);
const actionB = data => console.info('action-b', data);

page.render(
  <Form>
    <input name="name" />
    <ActionButton action={actionA}>Action A</ActionButton>
    <ActionButton action={actionB}>Action B</ActionButton>
  </Form>,
);

Title

Sets document.title of the page.

page.render(
  <>
    <Title>Awesome Page</Title>
    <div>Hello BackPage!</div>
  </>,
);

You can also specify title in BackPage options if it not dynamic.

Style

Adds a style element to the page with content loaded from src (local path).

const App = () => (
  <>
    <Style src={STYLE_PATH} />
    <div>Hello BackPage!</div>
  </>
);

You can directly use <link rel="stylesheet" href="..." /> for CSS links.

Console

Intercepts console outputs using patch-console.

const App = () => (
  <>
    <h2>Logs</h2>
    <Console />
  </>
);

License

MIT License.