Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export async function run(main) {
R.regOpaqueObject(main);
try {
const producer = createProducer();
for await (const i of main(producer, producer.dispatch)) {
}
} catch (e) {
console.error(e);
}
}
function _signal(dispatch, type, value) {
return dispatch({ type, ...value });
}
R.regOpaqueObject(_signal);
/**
* Helper function for binding message dispatching into components event handlers
*
* @param {Dispatch} dispatch
* @param {string} type
* @param {any} value
*/
export function signal(dispatch, type, value) {
return R.bind(_signal, null, dispatch, type, value);
}
/**
* Sends `{type:"FLUSH"}` message in the beginning and after each new input message
*
* @type {Transducer}
/** adds Increment Async button */
export async function* incrementAsync(input, dispatch) {
yield {
type: "MENU_ITEM",
index: 300,
value: (
<button>
Increment Async
</button>
)
};
yield* input;
}
function nop() {}
R.regOpaqueObject(nop);
export async function* incrementIfOdd(input, dispatch) {
for await (const i of input) {
if (i.type === "VALUE")
yield {
type: "MENU_ITEM",
index: 400,
value: (
<button>
Increment if odd
</button>
)
async function* render(input) {
R.regOpaqueObject(el);
let control;
for await (const i of input) {
if (i.type === "CONTROL") control = i.value;
else if (i.type === "FLUSH" && control) {
ReactDOM.render(control, el);
control = null;
}
yield i;
}
};
*
* @param {...Transducer} args
* @returns {Transducer}
*/
export function pipe(...args) {
return function(input, dispatch) {
for (const f of args) input = f(input, dispatch);
return input;
};
}
function resend(action) {
return this.send(action);
}
R.regOpaqueObject(resend);
/**
* Creates a producer, an `AsyncIterable` with `dispatch` field to send messages
*
* @returns {Producer}
*/
export function createProducer() {
const producer = R.producer();
producer.dispatch = R.bind(resend, producer);
return producer;
}
/**
* The main loop for the transducers passed as input.
* It just reads all values from `main` output until it's done
*
/** @file increment async and incremet if odd */
import * as R from "@effectful/es-persist-serialization";
import * as Kit from "./kit";
import React from "react";
function runIncrementAsync(dispatch) {
setTimeout(() => dispatch({ type: "INCREMENT" }), 1000);
}
R.regOpaqueObject(runIncrementAsync);
/** adds Increment Async button */
export async function* incrementAsync(input, dispatch) {
yield {
type: "MENU_ITEM",
index: 300,
value: (
<button>
Increment Async
</button>
)
};
yield* input;
}
function nop() {}
yield { type: "FLUSH" };
} else yield { type: "ITEM", value: i.value, key: i.key };
}
}
} finally {
for (const i of threads.values()) i.source.stop();
await R.all([...threads.values()].map(i => i.iter.return()));
}
};
}
function forkDispatch(dispatch, key, value) {
return dispatch({ type: "ITEM", key, value });
}
R.regOpaqueObject(forkDispatch);
async function* forkMain(input, dispatch, threads, transducer) {
let cur = 0;
for await (const i of input) {
if (i.type === "ITEM") {
const thread = threads.get(i.key);
thread.source.dispatch(i.value);
} else if (i.type === "NEW") {
const source = createProducer();
const key = i.key || ++cur;
const iter = transducer(
source,
R.bind(forkDispatch, null, dispatch, key)
)[Symbol.asyncIterator]();
const thread = { iter, key, task: iter.next(), source };
threads.set(key, thread);
export default function fork(transducer) {
transducer = pipe(
transducer,
handleDelete
);
R.regOpaqueObject(transducer);
return async function* fork(input, dispatch) {
let cur = 0;
const threads = new Map();
const iter = forkMain(input, dispatch, threads, transducer);
const main = { iter, task: iter.next() };
const suspended = [];
try {
for (;;) {
const i = await R.any([main, ...threads.values()].map(forkCont));
if (i.done) {
if (i === main) return i.value;
threads.delete(i.key);
i.source.stop();
await i.iter.return();
continue;
}
/**
* combining all the steps, more a kind of a configuration file
*/
import * as D from "./draw";
import * as S from "./state";
import { run, render } from "./kit";
import * as R from "@effectful/es-persist-serialization";
const root = document.getElementById("root");
R.regOpaqueObject(root, "root");
run(
D.rootContainer,
D.animateDelete({}),
D.insertBox,
D.collectBoxes,
S.saveLocal,
render(root)
);
export function run(...args) {
const { producer, event } = createProducer();
const main = pipe(...args);
R.regOpaqueObject(main);
return main(producer, event);
}
}
export const pipe = (...args) => (input, dispatch) =>
args.reduce((interm, step) => step(share(interm), dispatch), input);
export function run(...args) {
const { producer, event } = createProducer();
const main = pipe(...args);
R.regOpaqueObject(main);
return main(producer, event);
}
function id(v) {
return v;
}
R.regOpaqueObject(id);
export async function* anim({ delay = 400, easing = id }) {
const start = performance.now();
const stop = start + delay;
const step = 1 / delay;
yield easing(0);
for (let cur; (cur = await new Promise(requestAnimationFrame)) < stop; )
yield easing(step * (cur - start));
yield easing(1);
}
export const render = el =>
async function render(input) {
for await (const i of input) {
if (i.type === "ROOT") ReactDOM.render(i.value, el);
}