UNPKG

@virtualstate/examples

Version:
118 lines 3.52 kB
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