{"id":15044807,"url":"https://github.com/virtualstate/x","last_synced_at":"2025-10-24T14:30:36.209Z","repository":{"id":49167582,"uuid":"365539598","full_name":"virtualstate/x","owner":"virtualstate","description":"Bring your own JavaScript tooling.","archived":false,"fork":false,"pushed_at":"2022-04-05T12:09:35.000Z","size":3665,"stargazers_count":23,"open_issues_count":8,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-17T20:28:59.549Z","etag":null,"topics":["backend","bring-your-own","deno","frontend","javascript","jsx","nodejs","promise","typescript","vsx","web"],"latest_commit_sha":null,"homepage":"https://virtualstate.dev","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/virtualstate.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-05-08T14:48:46.000Z","updated_at":"2023-03-28T08:10:48.000Z","dependencies_parsed_at":"2022-09-05T16:50:25.363Z","dependency_job_id":null,"html_url":"https://github.com/virtualstate/x","commit_stats":null,"previous_names":[],"tags_count":187,"template":false,"template_full_name":null,"purl":"pkg:github/virtualstate/x","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualstate%2Fx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualstate%2Fx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualstate%2Fx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualstate%2Fx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/virtualstate","download_url":"https://codeload.github.com/virtualstate/x/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/virtualstate%2Fx/sbom","scorecard":{"id":923317,"data":{"date":"2025-08-11","repo":{"name":"github.com/virtualstate/x","commit":"7532c261c8cca3123259480fab16693d1b760fb0"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/codeql-analysis.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-actions.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/release-actions.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-actions.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/release-actions.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-actions.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/virtualstate/x/release-actions.yml/main?enable=pin","Warn: containerImage not pinned by hash: .devcontainer/Dockerfile:5","Info:   0 out of   7 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/release-actions.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"SAST","score":10,"reason":"SAST tool detected: CodeQL","details":["Info: SAST configuration detected: CodeQL","Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: github.com/virtualstate/.github/SECURITY.md:1","Info: Found linked content: github.com/virtualstate/.github/SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: github.com/virtualstate/.github/SECURITY.md:1","Info: Found text in security policy: github.com/virtualstate/.github/SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":0,"reason":"41 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-8hfj-j24r-96c4","Warn: Project is vulnerable to: GHSA-wc69-rhjr-hc9g","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-xvf7-4v9q-58w6","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-3j8f-xvm3-ffx4","Warn: Project is vulnerable to: GHSA-4p35-cfcx-8653","Warn: Project is vulnerable to: GHSA-7f3x-x4pr-wqhj","Warn: Project is vulnerable to: GHSA-jpp7-7chh-cf67","Warn: Project is vulnerable to: GHSA-q6wq-5p59-983w","Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2","Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-25T06:53:53.175Z","repository_id":49167582,"created_at":"2025-08-25T06:53:53.175Z","updated_at":"2025-08-25T06:53:53.175Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280225805,"owners_count":26293888,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","bring-your-own","deno","frontend","javascript","jsx","nodejs","promise","typescript","vsx","web"],"created_at":"2024-09-24T20:51:04.280Z","updated_at":"2025-10-24T14:30:34.366Z","avatar_url":"https://github.com/virtualstate.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [@virtualstate/x](http://npmjs.com/package/@virtualstate/x) \n\n\u003e _Bring your own_ JavaScript tooling\n\n### Test Coverage\n\n[//]: # (badges)\n\n![nycrc config on GitHub](https://img.shields.io/nycrc/virtualstate/x) ![87.85%25 lines covered](https://img.shields.io/badge/lines-87.85%25-brightgreen) ![87.85%25 statements covered](https://img.shields.io/badge/statements-87.85%25-brightgreen) ![67.51%25 functions covered](https://img.shields.io/badge/functions-67.51%25-yellow) ![83.11%25 branches covered](https://img.shields.io/badge/branches-83.11%25-brightgreen) ![100%25 branchesTrue covered](https://img.shields.io/badge/branchesTrue-100%25-brightgreen)\n\n[//]: # (badges)\n\n## About\n\n`@virtualstate/x` (or vsx) provides baseline functionality to enable a wide range of \nsolutions for JavaScript based services, user interfaces, or scripts. \n\nThe core module [`@virtualstate/fringe`](https://github.com/virtualstate/x/tree/main/packages/fringe) provides a `jsx` interface to enable developer\ndriven definitions, workflows, transitions, and logic, while providing consistent\na inline async resolution interface. \n\nBy default, all JavaScript patterns can be utilised within the base tooling, and \nit is up to individual implementations to decide on finer details, for example \nif your project needs copy node trees into a [web page's DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model)\nor if your individual component (or entire site?) could be rendered as a static string, \nthese code paths will need to be decided on, as there is no one size fits all.\n\n\u003e If you want to get started, fork or clone the \n\u003e [virtualstate.dev](https://github.com/virtualstate/virtualstate.dev)\n\u003e repository for an already set up project. \n\u003e \n\u003e It utilises [@virtualstate/dom's render function](https://github.com/virtualstate/virtualstate.dev/blob/main/src/index.tsx#L22) to \n\u003e render a tree into the documents body in page, while also [doing the same in a prerender step](https://github.com/virtualstate/virtualstate.dev/blob/38bde3c370ebaf72b1a5ed1548f0f3a58ceb26c2/scripts/prerender.js#L47) to\n\u003e allow for static loading of pages where JavaScript is not available.\n\n## Running Examples\n\nThere is a bunch of different examples available in [packages/examples](https://github.com/virtualstate/x/tree/main/packages/examples) see:\n\n\u003e If you have a code example you would like to share and it utilises one of the packages provided by this repository, you're very welcome to [fork this repo](https://docs.github.com/en/get-started/quickstart/fork-a-repo) and raise a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) with your example!\n\n- [Deno](#running-examples-with-deno)\n- [Node](#running-examples-with-node)\n- [npx](#running-examples-with-npx)\n\n### Running examples with Deno \n\n```bash \ndeno run \\                                                                                                                                                                                             *[main] \n  --import-map=https://cdn.skypack.dev/@virtualstate/deno/import-map.json \\\n  --allow-net \\\n  https://cdn.skypack.dev/@virtualstate/examples/lib/log.js\n```\n\n### Running examples with Node\n\n```bash \ngit clone https://github.com/virtualstate/x.git \ncd x \nyarn\nyarn build\nyarn examples:log\n```\n\n### Running examples with npx\n\n```bash\nnpx @virtualstate/examples@^2.14.10 \n```\n\n## [`h`](http://npmjs.com/package/@virtualstate/fringe)\n\nThe `h` function provides [JSX](https://www.typescriptlang.org/docs/handbook/jsx.html) functionality to your code. \n\nIf you are utilising TypeScript, in your `tsconfig.config.json` you will need to add to `compilerOptions` the\nkeys `jsx`, `jsxFactory`, and `jsxFragmentFactory`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"jsx\": \"react\",\n    \"jsxFactory\": \"h\",\n    \"jsxFragmentFactory\": \"createFragment\"\n  }\n}\n```\n\nIf you are using a JavaScript build tool like [Snowpack](https://www.snowpack.dev/)\nyou may also need to add JSX related configuration, e.g. [`\"jsxFactory\": \"h\"`](https://www.snowpack.dev/reference/configuration#buildoptionsjsxfactory) and\n[`\"jsxFactory\": \"createFragment\"`](https://www.snowpack.dev/reference/configuration#buildoptionsjsxfragment)\n\n[Demo Usage](https://github.com/fabiancook/fabiancook.dev)\n\n```typescript\nimport { h, createFragment } from \"@virtualstate/x\";\n\nasync function AsyncExample() {\n  return await new Promise(\n    resolve =\u003e setTimeout(resolve, 1500, `Async result: ${Math.random()}`)\n  );\n}\n\nasync function *Loading(options: unknown, child: VNode) {\n  yield \u003c\u003eLoading!\u003c/\u003e;\n  yield child;\n}\n\nexport async function InitialExample() {\n  return (\n    \u003cdiv class=\"output\"\u003e\n      \u003ch3\u003e\n        This is an example of various\n        capabilities of this pattern\n      \u003c/h3\u003e\n      \u003cpre\u003e\n        \u003cLoading\u003e\n          \u003cAsyncExample /\u003e\n        \u003c/Loading\u003e\n      \u003c/pre\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n### Working with a virtual node\n\n[Related Blog Post](https://fabiancook.dev/2021/05/23/rendering)\n\n\u003e Psst, the VNode type can be found at [packages/frings/src/vnode.ts](https://github.com/virtualstate/x/blob/main/packages/fringe/src/vnode.ts)\n\nThe returned of `h` is a `VNode`:\n\n```typescript\nexport interface VNode {\n  source: unknown;\n  options?: object;\n  children?: AsyncIterable\u003cVNode[]\u003e;\n}\n```\n\nScalar nodes created with `h` will be returned directly\n\n```typescript\nimport { h } from \"@virtualstate/x\";\n\nconst node = h(1);\nconst { source: one } = node;\nconsole.log({ one }); // Logs { one: 1 }\n```\n\nAny scalar nodes with `h` that have children can be read using `for await`\n\n\u003e Psst, new documentation is expected here [completely static nodes can be read in a completely static way]()\n\u003e however this is a bit more specific to use\n\u003e \n\u003e An example of this can be found at [packages/examples/static](https://github.com/virtualstate/x/blob/a450413207532f8202279bd6a032a2a89df68940/packages/examples/src/examples/static/static.tsx#L16)\n\u003e where `children` is accessed like `const [thread, spikeyCactus, cactus, scroll] = node.children;` \n\n```typescript\n\nconst first = h(\"first\");\nconst second = h(\"second\");\nconst third = h(\"third\");\nconst node = h(\"result\", {}, first, second, third);\n\nconst { source: result, children } = node;\nconsole.log({ result }); // Logs { result: \"result\" }\n\nif (!children) throw new Error(\"Expected children\");\n\nfor await (const results of children) {\n  // Eventually Logs { results: [\"first\", \"second\", \"third\" ] }\n  console.log({ results: results.map(node =\u003e node.source) });\n}\n```\n\nAny function type can be used as a virtual node\n\n```typescript\nimport { h } from \"@virtualstate/x\";\n\nfunction Fn() {\n  return \"Function ✨\";\n}\nasync function AsyncFn() {\n  await new Promise\u003cvoid\u003e(queueMicrotask);\n  return \"Async Function 💡\";\n}\nfunction *GeneratorFn() {\n  yield \"GeneratorFn Loading\";\n  yield \"GeneratorFn 💥\";\n}\nasync function *AsyncGeneratorFn() {\n  yield \"AsyncGeneratorFn Loading\";\n  yield \"AsyncGeneratorFn 🔥\";\n}\nfunction Fns() {\n  return [\n    h(Fn),\n    h(AsyncFn),\n    h(GeneratorFn),\n    h(AsyncGeneratorFn)\n  ]\n    .map(node =\u003e f(\"fn\", { name: node.source.name }, node.source.name, node));\n}\n\nconst { children } = f(Fns);\n\nif (!children) throw new Error(\"Expected children\");\n\nfor await (const results of children) {\n  // Eventually Logs { results: [\"Fn\", \"AsyncFn\", \"GeneratorFn\", \"AsyncGeneratorFn\" ] }\n  console.log({ results: results.map(node =\u003e node.options.name) });\n}\n\n```\n\n## [`union`](http://npmjs.com/package/@virtualstate/union)\n\nUnion provides direct async resolution of multiple async iterators, for example\nthe returned type of `h(...).children` has an async iterator that produces\nvalues that represents groups of output state, these groups need to be chopped up\ninto workable sync units. \n\n`union` does this by resolving in the best case all known iterators in under a single microtask,\nor at the works case, at least one iterator resolution, after the microtask cut off point. \n\nUsing `union` a developer can treat a group of values with async iterators\nas single unit with all async resolution abstracted away to within.\n\nBelow are some demos/examples that display patterns accessible through `union`.\nFeel free to add your own!\n\n- [CodeSandbox Demo 1](https://codesandbox.io/s/interesting-yalow-hh5ow?file=/src/index.ts:809-880)\n- [CodeSandbox Demo 2](https://codesandbox.io/s/cool-snow-z6ese?file=/src/index.ts)\n\n```typescript\nimport { union } from \"@virtualstate/x\";\n\nasync function wait(ms = 10) {\n  await new Promise((resolve) =\u003e setTimeout(resolve, ms));\n}\n\nasync function* left() {\n  yield \"Left 1\";\n  await wait(19);\n  yield \"Left 2\";\n  await wait(401);\n  yield \"Left 3\";\n}\n\nfunction* middle() {\n  yield \"Middle 1\";\n  yield \"Middle 2\";\n  yield \"Middle 3\";\n}\n\nasync function* right() {\n  yield \"Right 1\";\n  await wait(401);\n  yield \"Right 2\";\n  yield \"Right 3\";\n  await wait(19);\n  yield \"Right 4\";\n}\n\nfor await (const [leftResult, middleResult, rightResult] of union([\n  left(),\n  middle(),\n  right()\n])) {\n  const result = { leftResult, middleResult, rightResult };\n  console.log(result);\n  document.body.innerHTML = JSON.stringify(result, undefined, \"  \");\n}\n```\n\n## Discord\n\nInterested in talking more about the project? Find us on [Discord](https://discord.gg/E2K6Q9QH6A)\n\n## Contributing\n\nPlease see [Contributing](./CONTRIBUTING.md)\n\n## Code of Conduct \n\nThis project and everyone participating in it is governed by the [Code of Conduct listed here](./CODE-OF-CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [conduct@fabiancook.dev](mailto:conduct@fabiancook.dev).\n\n## Licence\n\nThis repository is licensed under the [MIT](https://choosealicense.com/licenses/mit/) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirtualstate%2Fx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvirtualstate%2Fx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirtualstate%2Fx/lists"}