Modern UI Peer-to-Peer Event (MUPPETs)
This is a React Javascript library for two or more React apps to connect to MUPPET data channels (WebRTC/websockets under the hood), then use simple, React-like interfaces to forward each other serialized UI events from their app (like user clicks, selections, or input) via the MUPPETs protocol.
Login to GitHub's NPM repository on the command line by following this GitHub guide.
If you already have a GitHub Personal Token with registry read access saved somewhere on your local machine (maybe an environment variable), skip straight to the command:
npm login --scope=@noaa-gsl --auth-type=legacy --registry=https://npm.pkg.github.com
entering your GitHub username as the username, and your generated GitHub personal token as the password (should be a 40-character string starting with "ghp_").
This command is pointing NPM to GitHub's Package repository (rather than the default NPM address registry.npmjs.org
) and logging in your CLI session as your GitHub user.
To check that this worked, run this command:
npm whoami --registry=https://npm.pkg.github.com
If it prints your GitHub account name, you're good to go. If it throws a 401
or ENEEDAUTH
, your CLI session is still not logged in GitHub's Package repository.
npm install @noaa-gsl/idsse-muppet
Now you can use the MUPPET library to create new connections to a MUPPET channel and send/receive events over it in your React application.
To use MUPPET channels in your React app, first need to wrap your top-level React component in a MuppetProvider
:
// main.jsx
import ReactDOM from "react-dom/client";
import { MuppetProvider } from "@noaa-gsl/idsse-muppet";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")).render(
<MuppetProvider
clientName="MY_APP"
serverUrl="http://example.com" // URL of WebRTC signaling server
serverPath="/"
channelNames={["my-channel"]}
>
<App>
</MuppetProvider>
);
channelNames
: 1 or more WebRTC rooms on the WebRTC server that you wish to connect to. This will need to line up with the room(s) used by the app with which you want to send/receive messages.clientName
: how your app identifies itself to other apps using MUPPET. This will be prepended to theeventClass
of every event you send. For example, other apps may subscribe to events from you with eventClassMY_APP.SOME_BUTTON_CLICKED
, or if they want to send an RPC type message to your app specifically, they would use this clientName string to address the message.
With that Provider in place, now any components in your React component tree have access to shared, persistent MuppetChannel
instances. You can fetch this channel and use it directly in your React component:
// MyComponent.jsx
import { useState } from 'react';
import { useMuppetChannel, useMuppetCallback } from '@noaa-gsl/idsse-muppet';
function MyComponent() {
// track user's favorite color from other app
const [currentColor, setCurrentColor] = useState('');
const channel = useMuppetChannel('my-channel');
useMuppetCallback(
'my-channel',
(channel, evt) => {
console.log('Received new color selection from OTHER_APP:', evt);
setCurrentColor(event.color);
},
['OTHER_APP.COLOR_SELECTED'],
);
const onButtonClick = () => {
channel?.sendEvent({
eventClass: 'BUTTON_CLICKED',
event: { value: 123 },
});
};
return (
<div>
<button onClick={onButtonClick}>Hello world</button>
<p>Favorite color:</p>
<p>{currentColor}</p>
</div>
);
}
export default MyComponent;
For more details, see the Developer Guide - React.
Although it's not recommended because it can be much harder to manage app state, if you want to use the underlying JS without the niceties of React Context or custom Hooks, see Developer Guide - Vanilla JS
- Ensure you have NPM installed locally
- Clone this repository with
git clone <repo_url>
- Install any 3rd-party JS libraries needed by
cd
ing into your newly-cloned repo and runningnpm install
If you have changes you wish to be incorporated into the main branch, feel free to submit your feature branch for code review! Code should run quickly, quietly (without noisy console messages), and without crashing the page of a project that imports it.
To publish a new version of this package:
- In the package.json file, increase the
version
number (either the patch or minor number are usually fine).- This step is needed so NPM recognizes it as a new version for any repos that install it with
npm install
. If you don't do this, NPM will reject the publish due to a conflict with the last version, and the publish GitHub Action will fail.
- This step is needed so NPM recognizes it as a new version for any repos that install it with
- Go to the Releases page on the GitHub repository and click "Draft a new release"
- Releases should be shown in a sidebar on the right of the
Code
page on GitHub.
- Releases should be shown in a sidebar on the right of the
- Click the "Choose a tag" dropdown, then start typing a new version number in the text box
- This should start with "v", then the same version that you set in the
package.json
file in step 1. - Click "Create new tag"
- Type a bullet point or two about what was changed, or click "Generate release notes" which just links to a diff between this version and the last.
- This should start with "v", then the same version that you set in the
- Make sure "Set as pre-release" is not checked
- This will ensure that projects using this library will download your new version the next time they run
npm install
. - If "pre-release" is checked, it would still publish to NPM but not upgrade by default. Users of the library would have to "opt in" to this latest version by installing it explicitly, e.g.
npm install @noaa-gsl/idsse-muppet@v1.2.3-beta
- This will ensure that projects using this library will download your new version the next time they run
- Click "Publish release"
That's it! A GitHub Action will be kicked off to auto-publish the new version to NPM. You can watch the status on the Actions tab of GitHub.
Once that finishes, projects that use this library can run npm install
, and NPM will upgrade them to the new version of this library in their project (in their package.json, or by running npm ls | grep idsse-muppet
).