Run arbitrary user javascript modules embedded in the URL. Designed for metapages so you can connect inputs + outputs to other metaframe URLs.
- 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
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 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")
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
}
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
}
You don't need to wait for the load
event: your script will not run until load
event fires.
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.
"use strict"
is automatically added to the top of the module code.
- 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
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
- 🌟🌟🌟🌟🌟