@virtualstate/examples
Version:
118 lines • 3.52 kB
JavaScript
import { h, createFragment, createToken } from "@virtualstate/fringe";
import { Collector } from "microtask-collector";
import { Hook } from "@virtualstate/hooks";
const NodeSymbol = Symbol("Node");
function isNetworkVNode(node) {
return node.reference === NodeSymbol;
}
function Node(options, state) {
return {
reference: NodeSymbol,
source: {
options,
state
},
async communicate() {
return undefined;
}
};
}
const PairedMessageSymbol = Symbol("Paired Message");
function PairCommunication(options, state) {
const messages = new Collector();
const node = Node(options, state);
node.communicate = async (source) => {
return new Promise((resolve, reject) => {
messages.add({
reference: PairedMessageSymbol,
source,
resolve,
reject
});
});
};
return [node, messages];
}
function* Sized({ size: targetSize, batch: targetBatch }, state) {
if (!state)
return;
const nodes = [];
let batch = 0;
while (nodes.length !== targetSize) {
nodes.push(state);
if (!targetBatch) {
yield nodes;
}
else {
batch += 1;
if (batch === targetBatch) {
yield nodes;
batch = 0;
}
}
}
if (batch) {
yield h(createFragment, null, nodes);
}
}
const ClosableSymbol = Symbol("Closable");
const Closable = createToken(ClosableSymbol);
const GenerateSymbol = Symbol("Generate");
function Generator(options, state) {
const sources = new Set();
const [node, events] = PairCommunication();
return [
node,
h(InternalGenerator, null),
h(Closable, { close: () => events.close() })
];
async function* InternalGenerator() {
for await (const batch of events) {
for (const {} of batch.filter(event => event.source.reference === GenerateSymbol)) {
sources.add(h(Node, { ...options }, state));
}
yield sources;
}
}
}
async function* Network(options, state) {
const closable = new Collector();
const [root, rootMessages] = PairCommunication();
rootMessages.close();
let messagesSent = 0;
yield (h(createFragment, null,
h(Hook, { hook: (node) => {
if (Closable.is(node)) {
closable.add(node);
return createFragment({});
}
if (!isNetworkVNode(node)) {
return node;
}
if (messagesSent > 100) {
return node;
}
messagesSent += 1;
node.communicate({
reference: GenerateSymbol,
source: root
});
return node;
} }, state),
h(Controller, null)));
async function Controller() {
for await (const batch of closable) {
// Give it x amount of time
await new Promise(resolve => setTimeout(resolve, 500));
for (const fn of batch) {
fn.options.close();
}
}
}
}
export const _N10001_Network = (h(Network, null,
h(Generator, null,
h(Sized, { size: 3 },
h(Node, null)))));
export const _N10001_URL = import.meta.url;
//# sourceMappingURL=network.js.map