javascriptregenerated / yieldmachine Goto Github PK
View Code? Open in Web Editor NEWComponents for State Machines, using Generator Functions
Home Page: https://regenerated.dev/yieldmachine
License: MIT License
Components for State Machines, using Generator Functions
Home Page: https://regenerated.dev/yieldmachine
License: MIT License
Any machine can be imported into xstate. Which allows access to their visualisation, React hooks, and other tooling.
Could support by returning an array of sub states rather than the initial state.
Before:
import { start } from "yieldmachine";
function TrafficLights() {
function* Red() {
yield on("timer", Green);
}
function* Green() {
yield on("timer", Yellow);
}
function* Yellow() {
yield on("timer", Red);
}
return Red;
}
const m = start(TrafficLights);
m.current; // { state: "Red", count: 0 }
m.next("timer");
m.current; // { state: "Green", count: 1 }
m.next("timer");
m.current; // { state: "Yellow", count: 2 }
After compiles to:
function* startTrafficLights() {
let count = 0;
let state = "Red";
return {
get current() {
return Object.freeze({ count, state });
}
next(event) {
if (event === "timer") {
count++;
if (state === "Red") {
state = "Green";
} else if (state === "Green") {
state = "Yellow";
} else if (state === "Yellow") {
state = "Red";
}
}
return { value: this.current, done: false };
},
};
}
const m = startTrafficLights();
m.current; // { state: "Red", count: 0 }
m.next("timer");
m.current; // { state: "Green", count: 1 }
m.next("timer");
m.current; // { state: "Yellow", count: 2 }
function reducer(previousState: State, event: React.FormEvent<HTMLFormElement> | React.MouseEvent<HTMLButtonElement>): State {
return previousState.machine.next(event);
}
eventsReducer(machine)
It wouldn’t support side effects and listening/emitting to events (e.g. with listenTo()
).
import { eventsReducer } from 'yieldmachine';
function useMachine(machine) {
const [state, dispatch] = useReducer(eventsReducer(machine));
return [state, dispatch];
}
Declare state machines using components.
YieldMachine is an opinionated library for creating state machines and actors. JavaScript Generator functions allow rich behaviour to be declared and composed together. And its modular design lets plugins add new behaviour.
/viz/1/github/gist/RoyalIcing/e7d97cdf38a2907924ea12e4ebdf3c85
— See a visualizer for this Gist./execute/1/github/gist/RoyalIcing/e7d97cdf38a2907924ea12e4ebdf3c85
— Run the machine in this Gist./execute/1/github/gist/RoyalIcing/e7d97cdf38a2907924ea12e4ebdf3c85?current=loaded
— Run the machine in this Gist from the loaded
state./execute/1/github/gist/RoyalIcing/e7d97cdf38a2907924ea12e4ebdf3c85?current=loaded&events[]=click&events[]=click
— Run the machine in this Gist from the loaded
state and receive two click
events.jsDelivr has a beta service to bundle a ESM JS file from GitHub: jsdelivr/jsdelivr#18263
const machine = start(Machine);
const eventSource = new EventSource();
machine.receiveFrom(eventSource);
const messagesKey = Symbol("messages");
function* Machine() {
yield listenTo(eventSource, "open");
yield on(new Map([["type", "error"], ["readyState", EventSource.CLOSED]]), Closed);
function* Open() {
yield listenTo(eventSource, "message");
yield accumulate("message", messagesKey);
}
function* Closed() {}
return function* Initial() {
yield listenTo(eventSource, "open");
yield on("open", Open);
}
}
Can be plugged into any machine.
Would support an assign
event.
const songID = Symbol();
yield path(['song', songID]);
Add machines that demonstrate common attacks, and what they exploit.
Then show machines that protect against these attacks.
Also provide Playwright scripts that demonstrate the attacks.
https://twitter.com/_jonesian/status/1440101111684165632
my biggest challenge is with data dependencies inside of context. like do i assume the data is there in the initial context or do i have an idle state in each of my machines with an
initialize
method to report the data.
it’s challenging with typescript when everything can possibly be undefined. then using those machines in react becomes challenging because you can’t pass undefined to a hook. so maybe i’m answering my question here haha
See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/formdata_event
const formElem = document.querySelector('form');
// submit handler
formElem.addEventListener('submit', (e) => {
// on form submission, prevent default
e.preventDefault();
console.log(form.querySelector('input[name="field1"]')); // FOO
console.log(form.querySelector('input[name="field2"]')); // BAR
// construct a FormData object, which fires the formdata event
const formData = new FormData(formElem);
// formdata gets modified by the formdata event
console.log(formData.get('field1')); // foo
console.log(formData.get('field2')); // bar
});
// formdata handler to retrieve data
formElem.addEventListener('formdata', (e) => {
console.log('formdata fired');
// modifies the form data
const formData = e.formData;
// formdata gets modified by the formdata event
formData.set('field1', formData.get('field1').toLowerCase());
formData.set('field2', formData.get('field2').toLowerCase());
});
Instead of context we have WebAssembly.Memory
Instead of props we have imports.
Instead of "current state" we have exports.
Perhaps multiple wasm instances (or other state machines) can be synced by replicating input events.
Can derive from one to the other. e.g. Have generator functions internally that become Arrays publicly.
function* loading() {
yield entry(fetchData);
}
Currently:
const machine = …
machine.next("FETCH");
machine.values.then(values => values[0]);
Future:
const machine = …
machine.next("FETCH");
machine.values.then(values => values.fetchData);
Useful for hydration, testing, etc
https://twitter.com/mpocock1/status/1440356513332162575
XState API proposal: 'input'
- Use props and compose other hooks in a totally natural way.
- No more useEffect's - prop changes get flushed to XState via events natively.
https://twitter.com/_jonesian/status/1440366408152481793
This has been my biggest contention with xstate. how to get initialization data into the machine when Im getting it from somewhere else
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.