Skip to content

Instantly share code, notes, and snippets.

@FND
Last active May 21, 2023 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FND/34f76fa4cd8b70dc257dc693ae2119eb to your computer and use it in GitHub Desktop.
Save FND/34f76fa4cd8b70dc257dc693ae2119eb to your computer and use it in GitHub Desktop.
Preact Signals
# http://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 80
indent_style = tab
indent_size = 4
[*.md]
indent_style = space
[COMMIT_EDITMSG]
trim_trailing_whitespace = false
max_line_length = 72
indent_style = space
/node_modules
/dist

Getting Started

  • ensure Deno is installed

  • deno task check checks code for stylistic consistency

    deno fmt can be used to automatically format code

  • deno task build performs a one-time compilation

    deno task dev automatically recompiles while monitoring code changes

    deno task prod activates minification

{
"tasks": {
"check": "deno lint && deno fmt --check",
"prod": "deno task build --minify",
"dev": "deno task build --watch=forever"
},
"fmt": {
"files": {
"include": ["./"]
},
"options": {
"lineWidth": 90,
"useTabs": true,
"indentWidth": 4
}
},
"lint": {
"files": {
"include": ["./"]
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Preact Signals</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
*,
*::before,
*::after {
box-sizing: border-box;
}
:root {
--h-size: 60ch;
--spacing: 0.5rem;
}
body {
max-width: calc(var(--h-size) + 2 * var(--spacing));
margin: 1rem auto;
padding-left: var(--spacing);
padding-right: var(--spacing);
font-family: system-ui, sans-serif;
line-height: 1.5;
}
output {
font-family: monospace;
}
output:last-of-type > :last-child::before { /* XXX: hacky */
content: "🧮 ";
visibility: hidden;
}
</style>
</head>
<body>
<h1>Preact Signals</h1>
<script src="./dist/bundle.js"></script>
</body>
</html>
import { batch, computed, effect, signal } from "@preact/signals-core";
const LOWBABILITY = 0.3;
const FREQUENCY = 1000;
const counter = signal(5);
const trend = signal(null);
const summary = computed(() => {
const ts = new Date().toISOString().substring(11, 19);
return `${trend.value?.symbol || ""} [${ts}] counter at ${counter.value}`.trim();
});
setInterval(() => {
const i = counter.value;
const [count, symbol] = Math.random() > LOWBABILITY ? [i + 1, "📈"] : [i - 1, "📉"];
batch(() => {
counter.value = count;
// NB: just using a string would suppress updates for recurring values
trend.value = { symbol };
});
}, FREQUENCY);
// UI
const chart = spawn("output");
const log = spawn("output");
effect(() => {
const { value } = trend;
if (value) {
chart.textContent += value.symbol;
}
});
effect(() => {
const el = document.createElement("div");
el.textContent = summary.value;
log.prepend(el);
});
function spawn(tag) {
const el = document.createElement(tag);
document.body.appendChild(el);
return el;
}
{
"scripts": {
"build": "esbuild ./index.js --bundle --format=esm --outfile=dist/bundle.js"
},
"dependencies": {
"@preact/signals-core": "1.3.0"
},
"devDependencies": {
"esbuild": "^0.17.18"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment