├── README.md ├── public ├── robots.txt ├── style │ ├── global.css │ └── home.css ├── assets │ ├── logo.svg │ └── logo-x-static.svg └── favicon.svg ├── .npmrc ├── src ├── components │ ├── Example.tsx │ ├── h.ts │ └── Tour.astro └── pages │ └── index.astro ├── .gitignore ├── Dockerfile ├── package.json ├── snowpack.config.js ├── astro.config.mjs ├── CODE-OF-CONDUCT.md └── LICENCE /README.md: -------------------------------------------------------------------------------- 1 | # Virtual State & Astro Example 2 | 3 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | ## force pnpm to hoist 2 | shamefully-hoist = true -------------------------------------------------------------------------------- /src/components/Example.tsx: -------------------------------------------------------------------------------- 1 | import { h } from "./h"; 2 | 3 | export async function *Example() { 4 | 5 | const result = await new Promise(resolve => setTimeout(resolve, 10, "🐸")); 6 | 7 | yield `${result} ${result}`; 8 | 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist 3 | 4 | # dependencies 5 | node_modules/ 6 | .snowpack/ 7 | 8 | # logs 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | 13 | # environment variables 14 | .env 15 | .env.production 16 | 17 | # macOS-specific files 18 | .DS_Store 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:15 2 | 3 | WORKDIR /usr/src 4 | 5 | RUN npm install --global http-server 6 | 7 | COPY ./package.json ./ 8 | COPY ./*lock* ./ 9 | 10 | RUN yarn 11 | 12 | COPY snowpack.config.js . 13 | COPY tsconfig.json . 14 | COPY .prettierrc . 15 | COPY src src 16 | COPY scripts scripts 17 | COPY public public 18 | 19 | RUN yarn build 20 | 21 | EXPOSE 8080 22 | 23 | CMD ["http-server", "./build", "-p", "8080", "--cors", "--proxy", "http://localhost:8080?"] 24 | -------------------------------------------------------------------------------- /public/style/global.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | } 5 | 6 | :root { 7 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; 8 | font-size: 1rem; 9 | --user-font-scale: 1rem - 16px; 10 | font-size: clamp(0.875rem, 0.4626rem + 1.0309vw + var(--user-font-scale), 1.125rem); 11 | } 12 | 13 | body { 14 | padding: 4rem 2rem; 15 | width: 100%; 16 | min-height: 100vh; 17 | display: grid; 18 | justify-content: center; 19 | background: #f9fafb; 20 | color: #111827; 21 | } 22 | 23 | @media (prefers-color-scheme: dark) { 24 | body { 25 | background: #111827; 26 | color: #fff; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@astrojs/starter-kit", 3 | "private": true, 4 | "type": "module", 5 | "license": "CC-0", 6 | "scripts": { 7 | "start": "astro dev", 8 | "build": "astro build" 9 | }, 10 | "devDependencies": { 11 | "astro": "^0.14.0" 12 | }, 13 | "dependencies": { 14 | "@virtualstate/astro-renderer": "^2.20.6", 15 | "@virtualstate/dom": "^2.20.6", 16 | "@virtualstate/examples": "^2.20.6", 17 | "@virtualstate/fringe": "^2.20.6", 18 | "@virtualstate/hooks": "^2.20.6", 19 | "@virtualstate/hooks-extended": "^2.20.6", 20 | "@virtualstate/union": "^2.20.6", 21 | "@virtualstate/x": "^2.20.6", 22 | "canvas": "^2.8.0", 23 | "dom-lite": "^20.2.0", 24 | "iterable": "^5.7.0", 25 | "jsdom": "^16.6.0", 26 | "microtask-collector": "^3.1.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /snowpack.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import("snowpack").SnowpackUserConfig } */ 2 | export default { 3 | mount: { 4 | /* ... */ 5 | "src": "/", 6 | "public": "/" 7 | }, 8 | exclude: [ 9 | "**/node_modules/**/*", 10 | ], 11 | plugins: [ 12 | /* ... */ 13 | ], 14 | routes: [ 15 | /* Enable an SPA Fallback in development: */ 16 | // {"match": "routes", "src": ".*", "dest": "/index.html"}, 17 | ], 18 | optimize: { 19 | /* Example: Bundle your final build: */ 20 | bundle: false, 21 | minify: false, 22 | target: "esnext" 23 | }, 24 | packageOptions: { 25 | /* ... */ 26 | }, 27 | devOptions: { 28 | /* ... */ 29 | }, 30 | buildOptions: { 31 | /* ... */ 32 | jsxFactory: "h", 33 | jsxFragment: "createFragment" 34 | }, 35 | env: { 36 | 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /public/style/home.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --font-mono: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Liberation Mono", "Nimbus Mono L", Monaco, "Courier New", Courier, monospace; 3 | --color-light: #F3F4F6; 4 | } 5 | 6 | @media (prefers-color-scheme: dark) { 7 | :root { 8 | --color-light: #1F2937; 9 | } 10 | } 11 | 12 | a { 13 | color: inherit; 14 | } 15 | 16 | header > div { 17 | font-size: clamp(2rem, -0.4742rem + 6.1856vw, 2.75rem); 18 | } 19 | 20 | header > div { 21 | display: flex; 22 | flex-direction: column; 23 | align-items: center; 24 | } 25 | 26 | header h1 { 27 | font-size: 1em; 28 | font-weight: 500; 29 | } 30 | header img { 31 | width: 2em; 32 | height: 2.667em; 33 | } 34 | 35 | h2 { 36 | font-weight: 500; 37 | font-size: clamp(1.5rem, 1rem + 1.25vw, 2rem); 38 | } 39 | -------------------------------------------------------------------------------- /astro.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | // projectRoot: '.', // Where to resolve all URLs relative to. Useful if you have a monorepo project. 3 | // pages: './src/pages', // Path to Astro components, pages, and data 4 | // dist: './dist', // When running `astro build`, path to final static output 5 | // public: './public', // A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that don’t need processing. 6 | buildOptions: { 7 | // site: 'http://example.com', // Your public domain, e.g.: https://my-site.dev/. Used to generate sitemaps and canonical URLs. 8 | // sitemap: true, // Generate sitemap (set to "false" to disable) 9 | }, 10 | devOptions: { 11 | // port: 3000, // The port to run the dev server on. 12 | // tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js' 13 | }, 14 | renderers: [ 15 | "@virtualstate/astro-renderer" 16 | ] 17 | }; 18 | -------------------------------------------------------------------------------- /public/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Tour from '../components/Tour.astro'; 3 | --- 4 | 5 | 6 | 7 | 8 | 9 | 10 | VSX & Astro 11 | 12 | 13 | 14 | 15 | 16 | 17 | 33 | 34 | 35 |
36 |
37 |
38 |
39 | Astro logo 40 | Virtual State logo 41 |
42 |

Welcome to Astro & Virtual State

43 |
44 |
45 | 46 | 47 |
48 | 49 | 50 | -------------------------------------------------------------------------------- /src/components/h.ts: -------------------------------------------------------------------------------- 1 | import { createNode, Source, VNode, VNodeRepresentationSource, Fragment } from "@virtualstate/x"; 2 | import { 3 | isGetDocumentNodeOptions, 4 | isNativeOptions, 5 | NativeOptions, 6 | isOnBeforeRenderOptions, 7 | isAttributesOptions 8 | } from "@virtualstate/dom"; 9 | 10 | export function h(source?: unknown, options?: object, ...children: VNodeRepresentationSource[]): VNode { 11 | if (source === "fragment") { 12 | return h(Fragment, options, ...children); 13 | } 14 | 15 | if (typeof source === "string" && options && !isNativeOptions(options)) { 16 | // Please if you have a solution to do this without any, please let me know 17 | const resultingOptions: Partial = { 18 | type: "Element", 19 | attributes: {}, 20 | }; 21 | 22 | const toJSON = () => ({ 23 | attributes: resultingOptions.attributes 24 | }); 25 | 26 | Object.defineProperty(resultingOptions, "toJSON", { 27 | value: toJSON, 28 | enumerable: false 29 | }); 30 | 31 | let remainingOptions: object = options; 32 | 33 | if (isGetDocumentNodeOptions(remainingOptions)) { 34 | const { getDocumentNode, ...nextRemainingOptions } = remainingOptions; 35 | remainingOptions = nextRemainingOptions; 36 | resultingOptions.getDocumentNode = getDocumentNode; 37 | } 38 | 39 | if (isOnBeforeRenderOptions(remainingOptions)) { 40 | const { onBeforeRender, ...nextRemainingOptions } = remainingOptions; 41 | remainingOptions = nextRemainingOptions; 42 | resultingOptions.onBeforeRender = onBeforeRender; 43 | } 44 | 45 | const finalOptions = { 46 | attributes: remainingOptions 47 | }; 48 | 49 | if (isAttributesOptions(finalOptions)) { 50 | resultingOptions.attributes = finalOptions.attributes; 51 | } 52 | 53 | return h(source, resultingOptions, ...children); 54 | } 55 | 56 | return createNode(source, options || {}, ...children); 57 | } 58 | -------------------------------------------------------------------------------- /src/components/Tour.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import { Markdown } from 'astro/components'; 3 | import { Example } from './Example'; 4 | import { h } from "./h"; 5 | 6 | --- 7 |
8 | 11 | 12 |
13 | 14 | 15 | ## 🚀 Project Structure 16 | 17 | Inside of your Astro project, you'll see the following folders and files: 18 | 19 | ``` 20 | / 21 | ├── public/ 22 | │ ├── robots.txt 23 | │ └── favicon.ico 24 | ├── src/ 25 | │ ├── components/ 26 | │ │ ├── Example.tsx 27 | │ │ └── Tour.astro 28 | │ └── pages/ 29 | │ └── index.astro 30 | └── package.json 31 | ``` 32 | 33 | Astro looks for `.astro` or `.md` files in the `src/pages/` directory. 34 | Each page is exposed as a route based on its file name. 35 | 36 | Virtual State supports importing `.tsx` or `.jsx` files in the `src/components/` directory.\ 37 | Each component can be its own export in a module (`.tsx`/`.jsx`) file. 38 | 39 | Any static assets, like images, can be placed in the `public/` directory. 40 | 41 | 42 |
43 | 44 |
45 | 46 |
47 | 48 |
49 |

👀 Want to learn more?

50 |

Feel free to check our documentation or jump into our Discord server.

51 |
52 | 53 |
54 | 55 | 97 | -------------------------------------------------------------------------------- /CODE-OF-CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [conduct@fabiancook.dev](mailto:conduct@fabiancook.dev). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 146 | 147 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /public/assets/logo-x-static.svg: -------------------------------------------------------------------------------- 1 | 2 | 146 | 147 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | --------------------------------------------------------------------------------