Skip to content

metapages/metaframe-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Javascript embedded in the URL: run and edit

Run arbitrary user javascript modules embedded in the URL. Designed for metapages so you can connect inputs + outputs to other metaframe URLs.

Javascript high level

  • code is an es6 module
  • top-level await
  • export a function onInputs to listen to inputs
  • send outputs with setOutput/setOutputs (predefined functions available in your module)
  • export a function onResize to listen to window/div resizes
  • use es6 module imports, or add any css / npm modules to the page, they are embedded in the URL

Useful code snippets

Inputs and outputs

Simply export a function (arrow function also good 👍) called onInputs:

// regular js function
export function onInputs(inputs) {
  // do something here
  // inputs is a plain object (key and values)
}
//  OR arrow function
export const onInputs = (inputs) => {
  // do something here
  // inputs is a plain object (key and values)
}

To send outputs, there are two functions in the scope setOutput and setOutputs:

// send a single JSON output
setOutput("outputname", 42);

// send an output object of keys+values
setOutputs({
  outputname:true,
  someOtherOutputName: "bar",
});

Output values can be strings, JSON, objects, arrays, numbers, ArrayBuffers, typed arrays such as Uint8Array;

The root display div element is exposed in the scope

The root display div is exposed in the script scope: the name is root and the id is also root:

console.log(root.id)
// logs "root"
// Add any custom dome elements into "root".

You can also just get it with:

document.getElementById("root")

Window resize

Simply export a function (arrow function also good 👍) called onResize. This will be called when either the window resizes event and/or the local div element resizes:

// regular js function
export function onResize(width, height) {
  // Your own code here, handling the resize of the root div
}
//  OR arrow function
export const onResize = (width, height) => {
  // Your own code here, handling the resize of the root div
}

Unload/cleanup

When iterating with the code editor, the script is re-run. In some cases, this can cause problems as multiple listeners maybe responding to the same event.

This is not an issue when simply running the page once with code, only when develping iteratively.

To have your script cleaned up because of new script (when editing), declare a function cleanup, this will be called prior to the updated script re-running:

// regular js function
export function cleanup() {
	console.log("internal scriptUnload call")
	// do your cleanup here
}
// OR arrow function
export const cleanup = () => {
  // do your cleanup here
}

Wait until page load

You don't need to wait for the load event: your script will not run until load event fires.

Logging to the display (instead of console)

Some globally available functions for logging:

  log("something here");
  logStdout("something here");
  logStderr("an error");

These will be added to the root div (see below) so if your own code manipulates the root div, it could be overwritten. This is mostly useful for headless code.

Misc

  • "use strict" is automatically added to the top of the module code.

Connect upstream/downstream metaframes

Examples

Description

  • user created javascript
  • user defined css modules

Think of this like codepen or others but stripped down focusing on core essentials, performance, and durability.

This website is also a metaframe: connect metaframes together into apps/workflows/dashboards: metapages

Github Repo

Architecture:

  • no state is stored on the server (all embedded in the URL)
    • this imposes some limits but current URL lengths are large or not specifically limited
  • The server simply serves a little index.html
  • The client then runs the embedded javascript (the javascript code is not sent to the server)

The server runs on https://deno.com/deploy which is

  • simple
  • fast
  • very performant
  • deploys immediately with a simply push to the repository
  • 🌟🌟🌟🌟🌟