Skip to content

Instantly share code, notes, and snippets.

@lakefox
Created June 28, 2023 16:50
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 lakefox/a94be6d342f4a836301d7b172756aa7c to your computer and use it in GitHub Desktop.
Save lakefox/a94be6d342f4a836301d7b172756aa7c to your computer and use it in GitHub Desktop.
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="./js/state.js"></script>
</head>
<body>
<main>
<h1>To-Do</h1>
<ul id="todo"></ul>
<input type="text" id="text" />
<button id="submit">Enter</button>
</main>
<script src="./js/script.js"></script>
</body>
</html>
let { define, listen, f } = new State();
define("list", document.querySelector("#todo"));
define("text", document.querySelector("#text"));
define("submit", document.querySelector("#submit"));
define("todos", []);
f(({ list, text, todos }) => {
list.innerHTML = "";
for (let i = 0; i < todos.length; i++) {
let li = document.createElement("li");
li.innerHTML = todos[i];
list.appendChild(li);
}
text.value = "";
});
listen("submit", "click", ({ text, todos }) => {
todos.push(text.value);
return { todos };
});
function State(v) {
let context = {};
let dependencies = {};
let renders = {};
this.f = async (render = () => {}) => {
let name = `f${Object.keys(renders).length}`;
renders[name] = render;
try {
await run(render, name, context);
} catch (error) {
// this doesn't need to do anything
}
};
this.define = (name, element) => {
context[name] = element;
};
this.listen = (name, event, handler) => {
context[name].addEventListener(event, async () => {
let ctx = context;
ctx.parent = context[name];
await run(handler, name, ctx, dependencies);
});
};
async function run(func, name, context) {
let require = {};
for (const key in context) {
if (Object.hasOwnProperty.call(context, key)) {
Object.defineProperty(require, key, {
get() {
if (dependencies[key] == undefined) {
dependencies[key] = [];
}
if (dependencies[key].indexOf(name) == -1) {
dependencies[key].push(name);
}
return context[key];
},
});
}
}
let data = func(require);
if (typeof data?.then === "function") {
data = await data;
}
Object.assign(context, data);
for (const key in dependencies) {
if (Object.hasOwnProperty.call(dependencies, key)) {
for (let i = 0; i < dependencies[key].length; i++) {
if (
renders[dependencies[key][i]] &&
dependencies[key][i] != name
) {
console.log(name, key, dependencies[key][i]);
renders[dependencies[key][i]](context);
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment