From a77230a4bfa23071f239d4e49f71517705773f71 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:53:24 -0500 Subject: [PATCH 01/15] Update CONTRIBUTING.md --- CONTRIBUTING.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f7454d..6478458 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,7 +37,8 @@ It has `yarn storybook` for testing Storybook and `yarn dev` for testing the app For testing with external projects that use Yarn, the framework and renderer can be linked locally. **Note:** The default Yarn Plug n' Play installs WILL NOT work when testing. -This is because Yarn PnP will use virtual paths for dependencies of linked dependencies. The framework does not resolve these virtual paths, so your test app will break. +This is because Yarn PnP will use virtual paths for dependencies of linked dependencies. +The framework does not resolve these virtual paths, so your test app will break. This can be fixed by specifying the node linker to be "node-modules". ### Example External Testing App From 776f06f17d3127d83e7a417b45bb6d936adc2579 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:42:40 -0500 Subject: [PATCH 02/15] Added source decorator --- .gitignore | 3 + example/package.json | 2 +- package.json | 2 + packages/frameworks/solid-vite/package.json | 2 +- packages/renderers/solid/package.json | 8 +- .../renderers/solid/src/docs/jsxDecorator.tsx | 14 -- .../solid/src/docs/sourceDecorator.tsx | 215 ++++++++++++++++++ .../solid/src/entry-preview-docs.tsx | 4 +- yarn.lock | 33 ++- 9 files changed, 253 insertions(+), 30 deletions(-) delete mode 100644 packages/renderers/solid/src/docs/jsxDecorator.tsx create mode 100644 packages/renderers/solid/src/docs/sourceDecorator.tsx diff --git a/.gitignore b/.gitignore index daeaba4..7c88b43 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ node_modules # build dist bench + +# vite +vite.config.ts.timestamp-* diff --git a/example/package.json b/example/package.json index b5f2412..4bd20ed 100644 --- a/example/package.json +++ b/example/package.json @@ -31,6 +31,6 @@ "vite-plugin-solid": "^2.8.2" }, "dependencies": { - "solid-js": "^1.9.2" + "solid-js": "^1.9.3" } } diff --git a/package.json b/package.json index ae6f02c..e6ca177 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "@fal-works/esbuild-plugin-global-externals": "^2.1.2", "@types/fs-extra": "^11.0.4", "@types/node": "^18.0.0", + "esbuild": "^0.24.0", "esbuild-plugin-alias": "^0.2.1", "esbuild-plugin-solid": "^0.6.0", "eslint": "^9.13.0", @@ -29,6 +30,7 @@ "rollup": "^4.24.0", "rollup-plugin-dts": "^6.1.1", "slash": "^5.1.0", + "solid-js": "^1.9.3", "sort-package-json": "^2.10.1", "ts-node": "^10.9.2", "tsup": "^8.3.0", diff --git a/packages/frameworks/solid-vite/package.json b/packages/frameworks/solid-vite/package.json index 5b3ca57..4804c09 100644 --- a/packages/frameworks/solid-vite/package.json +++ b/packages/frameworks/solid-vite/package.json @@ -56,7 +56,7 @@ }, "devDependencies": { "@storybook/types": "next", - "solid-js": "^1.9.2", + "solid-js": "^1.9.3", "storybook": "next", "storybook-solidjs": "workspace:*", "vite": "^5.4.8" diff --git a/packages/renderers/solid/package.json b/packages/renderers/solid/package.json index e35ad09..853edc1 100644 --- a/packages/renderers/solid/package.json +++ b/packages/renderers/solid/package.json @@ -52,13 +52,12 @@ "@storybook/preview-api": "next", "@storybook/test": "next", "@storybook/types": "next", + "@types/babel__standalone": "link:.yarn/cache/null", "async-mutex": "^0.5.0", - "esbuild": "^0.24.0", - "esbuild-plugin-solid": "^0.6.0", "storybook": "next" }, "peerDependencies": { - "solid-js": "^1.9.2" + "solid-js": "^1.9.3" }, "engines": { "node": ">=18.0.0" @@ -74,5 +73,8 @@ "./src/entry-preview-docs.tsx" ], "platform": "browser" + }, + "dependencies": { + "@babel/standalone": "^7.26.2" } } diff --git a/packages/renderers/solid/src/docs/jsxDecorator.tsx b/packages/renderers/solid/src/docs/jsxDecorator.tsx deleted file mode 100644 index 46ba551..0000000 --- a/packages/renderers/solid/src/docs/jsxDecorator.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import type { StoryContext, PartialStoryFn } from '@storybook/types'; -import { SolidRenderer } from '../types'; - -export const jsxDecorator = ( - storyFn: PartialStoryFn, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - _: StoryContext, -) => { - //TODO: needs research about how to generate raw JSX from a solid component - //due to it lacks of a vdom. - const story = storyFn(); - - return story; -}; diff --git a/packages/renderers/solid/src/docs/sourceDecorator.tsx b/packages/renderers/solid/src/docs/sourceDecorator.tsx new file mode 100644 index 0000000..5db56bb --- /dev/null +++ b/packages/renderers/solid/src/docs/sourceDecorator.tsx @@ -0,0 +1,215 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +// @babel/standalone does not export types, +// so this file is a mess of anys. + +import type { StoryContext, PartialStoryFn } from '@storybook/types'; +import { SolidRenderer } from '../types'; + +import { SNIPPET_RENDERED, SourceType } from '@storybook/docs-tools'; +import { addons, useEffect } from '@storybook/preview-api'; + +// @ts-expect-error Types are not up to date +import * as Babel from '@babel/standalone'; +const parser = Babel.packages.parser; +const generate = Babel.packages.generator.default; +const t = Babel.packages.types; + +function skipSourceRender(context: StoryContext): boolean { + const sourceParams = context?.parameters.docs?.source; + const isArgsStory = context?.parameters.__isArgsStory; + + // always render if the user forces it + if (sourceParams?.type === SourceType.DYNAMIC) { + return false; + } + + // never render if the user is forcing the block to render code, or + // if the user provides code, or if it's not an args story. + return ( + !isArgsStory || sourceParams?.code || sourceParams?.type === SourceType.CODE + ); +} + +/** + * Generate JSX source code from stories. + */ +export const sourceDecorator = ( + storyFn: PartialStoryFn, + ctx: StoryContext, +) => { + // Strategy: Since SolidJS doesn't have a VDOM, + // it isn't possible to get information directly about inner components. + // Instead, there needs to be an altered render function + // that records information about component properties, + // or source code extraction from files. + // This decorator uses the latter technique. + // By using the source code string generated by CSF-tools, + // we can then parse the properties of the `args` object, + // and return the source slices. + + // Note: this also means we are limited in how we can + // get the component name. + // Since Storybook doesn't do source code extraction for + // story metas (yet), we can use the title for now. + const channel = addons.getChannel(); + const story = storyFn(); + const skip = skipSourceRender(ctx); + + // eslint-disable-next-line prefer-const + let source: string | null; + + useEffect(() => { + if (!skip && source) { + const { id, unmappedArgs } = ctx; + channel.emit(SNIPPET_RENDERED, { id, args: unmappedArgs, source }); + } + }); + + if (skip) return story; + + const docs = ctx?.parameters?.docs; + const src = docs?.source?.originalSource; + const name = ctx.title.split('/').at(-1)!; + + source = generateSolidSource(name, src); + console.log(source); + + return story; +}; + +/** + * Generate Solid JSX from story source. + */ +function generateSolidSource(name: string, src: string): string | null { + try { + const { attributes, children } = parseProps(src); + + const selfClosing = children == null || children.length == 0; + + const component = { + type: 'JSXElement', + openingElement: { + type: 'JSXOpeningElement', + name: { + type: 'JSXIdentifier', + name, + }, + attributes: attributes, + selfClosing, + }, + children: children ?? [], + closingElement: selfClosing + ? undefined + : { + type: 'JSXClosingElement', + name: { + type: 'JSXIdentifier', + name, + }, + }, + }; + + console.log(component); + + return generate(component, { compact: false }).code; + } catch (e) { + console.error(e); + return null; + } +} + +function toJSXChild(node: any): object { + if ( + t.isJSXElement(node) || + t.isJSXText(node) || + t.isJSXExpressionContainer(node) || + t.isJSXSpreadChild(node) || + t.isJSXFragment(node) + ) { + return node; + } + + if (t.isStringLiteral(node)) { + return { + type: 'JSXText', + value: node.value, + }; + } + + if (t.isExpression(node)) { + return { + type: 'JSXExpressionContainer', + value: node, + }; + } + + return { + type: 'JSXExpressionContainer', + value: t.jsxEmptyExpression(), + }; +} + +interface SolidProps { + attributes: object[]; + children: object[] | null; +} + +/** + * Parses component properties from source expression. + * + * The source code will be in the form of a `Story` object. + */ +function parseProps(src: string): SolidProps { + const ast = parser.parseExpression(src, { plugins: ['jsx'] }); + console.log(ast); + if (ast.type != 'ObjectExpression') throw 'Expected `ObjectExpression` type'; + // Find args property. + const args_prop = ast.properties.find((v: any) => { + if (v.type != 'ObjectProperty') return false; + if (v.key.type != 'Identifier') return false; + return v.key.name == 'args'; + }) as any | undefined; + // No args just there aren't any properties or children. + if (!args_prop) + return { + attributes: [], + children: null, + }; + // Get arguments. + const args = args_prop.value; + if (args.type != 'ObjectExpression') throw 'Expected `ObjectExpression` type'; + + // Construct props object, where values are source code slices. + const attributes: object[] = []; + let children: object[] | null = null; + for (const el of args.properties) { + if (el.type != 'ObjectProperty') continue; + if (el.key.type != 'Identifier') continue; + + if (el.key.name == 'children') { + children = [toJSXChild(el.value)]; + continue; + } + + let value: any = { + type: 'JSXExpressionContainer', + expression: el.value, + }; + + if (el.value.type == 'BooleanLiteral' && el.value.value == true) { + value = undefined; + } + + attributes.push({ + type: 'JSXAttribute', + name: { + type: 'JSXIdentifier', + name: el.key.name, + }, + value, + }); + } + + return { attributes, children }; +} diff --git a/packages/renderers/solid/src/entry-preview-docs.tsx b/packages/renderers/solid/src/entry-preview-docs.tsx index d734120..132fef2 100644 --- a/packages/renderers/solid/src/entry-preview-docs.tsx +++ b/packages/renderers/solid/src/entry-preview-docs.tsx @@ -4,7 +4,7 @@ import { enhanceArgTypes, extractComponentDescription, } from '@storybook/docs-tools'; -import { jsxDecorator } from './docs/jsxDecorator'; +import { sourceDecorator } from './docs/sourceDecorator'; import type { Decorator, SolidRenderer } from './public-types'; import { ArgTypesEnhancer } from '@storybook/types'; @@ -15,7 +15,7 @@ export const parameters = { }, }; -export const decorators: Decorator[] = [jsxDecorator]; +export const decorators: Decorator[] = [sourceDecorator]; export const argTypesEnhancers: ArgTypesEnhancer[] = [ enhanceArgTypes, diff --git a/yarn.lock b/yarn.lock index 4dc8281..9e118a9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -340,6 +340,13 @@ __metadata: languageName: node linkType: hard +"@babel/standalone@npm:^7.26.2": + version: 7.26.2 + resolution: "@babel/standalone@npm:7.26.2" + checksum: 10/c2ab46394145734d27359d78a8e0486daea8242f9346309bad45656b4b12e4e472e5e12bb9d2ab153f065c2b4b30adf8ff66f00a43c198a47148c8f5eaaa0f5e + languageName: node + linkType: hard + "@babel/template@npm:^7.25.7": version: 7.25.7 resolution: "@babel/template@npm:7.25.7" @@ -1512,6 +1519,7 @@ __metadata: "@fal-works/esbuild-plugin-global-externals": "npm:^2.1.2" "@types/fs-extra": "npm:^11.0.4" "@types/node": "npm:^18.0.0" + esbuild: "npm:^0.24.0" esbuild-plugin-alias: "npm:^0.2.1" esbuild-plugin-solid: "npm:^0.6.0" eslint: "npm:^9.13.0" @@ -1527,6 +1535,7 @@ __metadata: rollup: "npm:^4.24.0" rollup-plugin-dts: "npm:^6.1.1" slash: "npm:^5.1.0" + solid-js: "npm:^1.9.3" sort-package-json: "npm:^2.10.1" ts-node: "npm:^10.9.2" tsup: "npm:^8.3.0" @@ -1960,6 +1969,12 @@ __metadata: languageName: node linkType: hard +"@types/babel__standalone@link:.yarn/cache/null::locator=storybook-solidjs%40workspace%3Apackages%2Frenderers%2Fsolid": + version: 0.0.0-use.local + resolution: "@types/babel__standalone@link:.yarn/cache/null::locator=storybook-solidjs%40workspace%3Apackages%2Frenderers%2Fsolid" + languageName: node + linkType: soft + "@types/babel__template@npm:*": version: 7.4.4 resolution: "@types/babel__template@npm:7.4.4" @@ -5550,14 +5565,14 @@ __metadata: languageName: node linkType: hard -"solid-js@npm:^1.9.2": - version: 1.9.2 - resolution: "solid-js@npm:1.9.2" +"solid-js@npm:^1.9.3": + version: 1.9.3 + resolution: "solid-js@npm:1.9.3" dependencies: csstype: "npm:^3.1.0" seroval: "npm:^1.1.0" seroval-plugins: "npm:^1.1.0" - checksum: 10/d2ffa823eefc77b08c5944fba44548feb4bf174e0a1a10d5b6e6ce0b9235bbb4ca0cd2079d2cb226f5a0dff307ae9582e20163c28c223da903ab8aa8328ed19e + checksum: 10/01c932a700f1eaef8280a2ae90f991179f0ad391e0e465cc07f0802b34dca7751878d33bb1d65fcd76c6209b24bd08aef016eaf5e1f77734051a5f849bef0d84 languageName: node linkType: hard @@ -5650,7 +5665,7 @@ __metadata: autoprefixer: "npm:^10.4.20" postcss: "npm:^8.4.47" solid-devtools: "npm:^0.29.2" - solid-js: "npm:^1.9.2" + solid-js: "npm:^1.9.3" storybook: "npm:next" storybook-solidjs: "workspace:*" storybook-solidjs-vite: "workspace:*" @@ -5668,7 +5683,7 @@ __metadata: "@storybook/builder-vite": "npm:next" "@storybook/types": "npm:next" magic-string: "npm:^0.30.11" - solid-js: "npm:^1.9.2" + solid-js: "npm:^1.9.3" storybook: "npm:next" storybook-solidjs: "workspace:*" vite: "npm:^5.4.8" @@ -5680,17 +5695,17 @@ __metadata: version: 0.0.0-use.local resolution: "storybook-solidjs@workspace:packages/renderers/solid" dependencies: + "@babel/standalone": "npm:^7.26.2" "@storybook/docs-tools": "npm:next" "@storybook/global": "npm:^5.0.0" "@storybook/preview-api": "npm:next" "@storybook/test": "npm:next" "@storybook/types": "npm:next" + "@types/babel__standalone": "link:.yarn/cache/null" async-mutex: "npm:^0.5.0" - esbuild: "npm:^0.24.0" - esbuild-plugin-solid: "npm:^0.6.0" storybook: "npm:next" peerDependencies: - solid-js: ^1.9.2 + solid-js: ^1.9.3 languageName: unknown linkType: soft From 526cb22c976cbbd7cee8e3ecf18885ec74fa4804 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Tue, 5 Nov 2024 18:43:27 -0500 Subject: [PATCH 03/15] Fix missing type info in releases --- packages/frameworks/solid-vite/package.json | 2 +- packages/renderers/solid/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frameworks/solid-vite/package.json b/packages/frameworks/solid-vite/package.json index 4804c09..74522e5 100644 --- a/packages/frameworks/solid-vite/package.json +++ b/packages/frameworks/solid-vite/package.json @@ -45,7 +45,7 @@ "*.d.ts" ], "scripts": { - "prepack": "yarn build", + "prepack": "yarn build --optimized --reset", "build": "npx jiti ../../../scripts/prepare/build.ts", "check": "npx jiti ../../../scripts/prepare/check.ts" }, diff --git a/packages/renderers/solid/package.json b/packages/renderers/solid/package.json index 853edc1..c33f8c4 100644 --- a/packages/renderers/solid/package.json +++ b/packages/renderers/solid/package.json @@ -42,7 +42,7 @@ "*.d.ts" ], "scripts": { - "prepack": "yarn build", + "prepack": "yarn build --optimized --reset", "build": "npx jiti ../../../scripts/prepare/build.ts", "check": "npx jiti ../../../scripts/prepare/check.ts" }, From d224bd34c6253e95bf4d92a05f99d2cd4fcda3c8 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Wed, 6 Nov 2024 15:42:11 -0500 Subject: [PATCH 04/15] Change versions --- packages/frameworks/solid-vite/package.json | 2 +- packages/renderers/solid/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/frameworks/solid-vite/package.json b/packages/frameworks/solid-vite/package.json index 74522e5..f87e656 100644 --- a/packages/frameworks/solid-vite/package.json +++ b/packages/frameworks/solid-vite/package.json @@ -1,7 +1,7 @@ { "name": "storybook-solidjs-vite", "type": "module", - "version": "1.0.0-beta.3", + "version": "1.0.0-beta.4", "description": "Storybook for SolidJS and Vite: Develop SolidJS in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/packages/renderers/solid/package.json b/packages/renderers/solid/package.json index c33f8c4..eb2720a 100644 --- a/packages/renderers/solid/package.json +++ b/packages/renderers/solid/package.json @@ -1,7 +1,7 @@ { "name": "storybook-solidjs", "type": "module", - "version": "1.0.0-beta.3", + "version": "1.0.0-beta.4", "description": "Storybook SolidJS renderer", "keywords": [ "storybook" From e3336bf8982bc8ad71f2d81a077b42ee8136ce5b Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Wed, 6 Nov 2024 19:34:21 -0500 Subject: [PATCH 05/15] Add authentication to publishing --- .github/workflows/solid-vite.yml | 2 +- .github/workflows/solid.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/solid-vite.yml b/.github/workflows/solid-vite.yml index 4ca66ec..063b097 100644 --- a/.github/workflows/solid-vite.yml +++ b/.github/workflows/solid-vite.yml @@ -42,4 +42,4 @@ jobs: run: yarn npm publish working-directory: packages/frameworks/solid-vite env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/solid.yml b/.github/workflows/solid.yml index 3238247..5d56683 100644 --- a/.github/workflows/solid.yml +++ b/.github/workflows/solid.yml @@ -50,4 +50,4 @@ jobs: run: yarn npm publish working-directory: packages/renderers/solid env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + YARN_NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From 0b88efb77722053e592eadb78a467a3cee148e3e Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:08:09 -0500 Subject: [PATCH 06/15] Update README.md --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 07816b7..6bdb4da 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,15 @@ This is a framework to allow using [Storybook](https://storybook.js.org/) with [SolidJS](https://www.solidjs.com/). -| Feature | State | -| --------------------------------------------------- | :---: | -| `JS` and `TS` integration with Storybook cli | ✅ | -| Fine grained updates in storybook controls | ✅ | -| Compatible with `@storybook/addon-interactions` | ✅ | -| Compatible with `@storybook/test` | ✅ | -| Automatic story actions | ⏳ | -| Full props table with description in docs view mode | ⏳ | -| Code snippets generation in docs view mode | ⏳ | -| `SolidJS` docs in the official Storybook website | ⏳ | +## Features +- [ ] `JS` and `TS` integration with Storybook CLI +- [x] Fine grained updates in storybook controls +- [x] Compatible with `@storybook/addon-interactions` +- [x] Compatible with `@storybook/test` +- [ ] Automatic story actions +- [ ] Full props table with description in docs view mode +- [ ] Code snippets generation in docs view mode +- [ ] `SolidJS` docs in the official Storybook website ## Notes about pending features ⏳ From 58ec297504755beb1f4acb0e208dee893896f366 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:09:08 -0500 Subject: [PATCH 07/15] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6bdb4da..2a8a1bb 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ This is a framework to allow using [Storybook](https://storybook.js.org/) with [SolidJS](https://www.solidjs.com/). ## Features -- [ ] `JS` and `TS` integration with Storybook CLI +- [x] `JS` and `TS` integration with Storybook CLI - [x] Fine grained updates in storybook controls - [x] Compatible with `@storybook/addon-interactions` - [x] Compatible with `@storybook/test` +- [x] Code snippets generation in docs view mode - [ ] Automatic story actions - [ ] Full props table with description in docs view mode -- [ ] Code snippets generation in docs view mode - [ ] `SolidJS` docs in the official Storybook website ## Notes about pending features ⏳ From cd8bde3e4e382e21acb858819555e40016da70b9 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Wed, 6 Nov 2024 20:10:47 -0500 Subject: [PATCH 08/15] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2a8a1bb..94f4e54 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ This is a framework to allow using [Storybook](https://storybook.js.org/) with [SolidJS](https://www.solidjs.com/). ## Features + - [x] `JS` and `TS` integration with Storybook CLI - [x] Fine grained updates in storybook controls - [x] Compatible with `@storybook/addon-interactions` @@ -18,13 +19,11 @@ This is a framework to allow using [Storybook](https://storybook.js.org/) with [ - **Full props table with description in docs view mode**: Feature under research. For now, props are rendered partially in the docs view table with a blank description. -- **Code snippets generation in docs view mode**: Feature under research. Because `solid` components lack a virtual dom, a common `jsx-parser` doesn't work for generating a code snippet from the rendered story. For now, it outputs the original story source code. To output a more complex code implementation, you can use the `render` key inside a `csf` story definition. - - **`SolidJS` docs in the official Storybook website**: It's still pending to add documentation about Storybook stories definitions using SolidJS. ## Setup -In an existing Solid project, run `npx storybook@next init` (Storybook 8+ is required) +In an existing Solid project, run `npx storybook@latest init` (Storybook 8+ is required) See the [Storybook Docs](https://storybook.js.org/docs?renderer=solid) for the best documentation on getting started with Storybook. From 7811473666f75af1031cf18431d1637d85b89bd7 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 14:26:52 -0500 Subject: [PATCH 09/15] Remove logs and cover object methods --- .../solid/src/docs/sourceDecorator.tsx | 116 ++++++++++++++---- 1 file changed, 91 insertions(+), 25 deletions(-) diff --git a/packages/renderers/solid/src/docs/sourceDecorator.tsx b/packages/renderers/solid/src/docs/sourceDecorator.tsx index 5db56bb..543f9f0 100644 --- a/packages/renderers/solid/src/docs/sourceDecorator.tsx +++ b/packages/renderers/solid/src/docs/sourceDecorator.tsx @@ -73,7 +73,6 @@ export const sourceDecorator = ( const name = ctx.title.split('/').at(-1)!; source = generateSolidSource(name, src); - console.log(source); return story; }; @@ -110,8 +109,6 @@ function generateSolidSource(name: string, src: string): string | null { }, }; - console.log(component); - return generate(component, { compact: false }).code; } catch (e) { console.error(e); @@ -119,6 +116,9 @@ function generateSolidSource(name: string, src: string): string | null { } } +/** + * Convert any AST node to a JSX child node. + */ function toJSXChild(node: any): object { if ( t.isJSXElement(node) || @@ -162,7 +162,6 @@ interface SolidProps { */ function parseProps(src: string): SolidProps { const ast = parser.parseExpression(src, { plugins: ['jsx'] }); - console.log(ast); if (ast.type != 'ObjectExpression') throw 'Expected `ObjectExpression` type'; // Find args property. const args_prop = ast.properties.find((v: any) => { @@ -184,32 +183,99 @@ function parseProps(src: string): SolidProps { const attributes: object[] = []; let children: object[] | null = null; for (const el of args.properties) { - if (el.type != 'ObjectProperty') continue; - if (el.key.type != 'Identifier') continue; + let attr: object | null = null; + + switch (el.type) { + case 'ObjectProperty': + if (el.key.type != 'Identifier') { + console.warn('Encountered computed key, skipping...'); + continue; + } + if (el.key.name == 'children') { + children = [toJSXChild(el.value)]; + continue; + } + + attr = parseProperty(el); + break; + case 'ObjectMethod': + attr = parseMethod(el); + break; + case 'SpreadElement': + // Spread elements use external values, should not be used. + console.warn('Encountered spread element, skipping....'); + continue; + } - if (el.key.name == 'children') { - children = [toJSXChild(el.value)]; - continue; + if (attr) { + attributes.push(attr); } + } - let value: any = { - type: 'JSXExpressionContainer', - expression: el.value, - }; + return { attributes, children }; +} - if (el.value.type == 'BooleanLiteral' && el.value.value == true) { - value = undefined; - } +/** + * Parse an object property. + * + * JSX flag attributes are mapped from boolean literals. + */ +function parseProperty(el: any): object | null { + let value: any = { + type: 'JSXExpressionContainer', + expression: el.value, + }; - attributes.push({ - type: 'JSXAttribute', - name: { - type: 'JSXIdentifier', - name: el.key.name, - }, - value, - }); + if (el.value.type == 'BooleanLiteral' && el.value.value == true) { + value = undefined; } - return { attributes, children }; + return { + type: 'JSXAttribute', + name: { + type: 'JSXIdentifier', + name: el.key.name, + }, + value, + }; +} + +/** + * Parse an object method. + * + * Note that object methods cannot be generators. + * This means that methods can be mapped straight to arrow functions. + */ +function parseMethod(el: any): object | null { + if (el.kind != 'method') { + console.warn('Encountered getter or setter, skipping...'); + return null; + } + + if (el.key.type != 'Identifier') { + console.warn('Encountered computed key, skipping...'); + return null; + } + + const { params, body, async, returnType, typeParameters } = el; + + return { + type: 'JSXAttribute', + name: { + type: 'JSXIdentifier', + name: el.key.name, + }, + value: { + type: 'JSXExpressionContainer', + expression: { + type: 'ArrowFunctionExpression', + params, + body, + async, + expression: false, + returnType, + typeParameters, + }, + }, + }; } From e493f5591237f2af3e23157c07294a0f5304d635 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 15:58:55 -0500 Subject: [PATCH 10/15] Move try catch up --- .../solid/src/docs/sourceDecorator.tsx | 68 +++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/packages/renderers/solid/src/docs/sourceDecorator.tsx b/packages/renderers/solid/src/docs/sourceDecorator.tsx index 543f9f0..768cf27 100644 --- a/packages/renderers/solid/src/docs/sourceDecorator.tsx +++ b/packages/renderers/solid/src/docs/sourceDecorator.tsx @@ -56,8 +56,7 @@ export const sourceDecorator = ( const story = storyFn(); const skip = skipSourceRender(ctx); - // eslint-disable-next-line prefer-const - let source: string | null; + let source: string | null = null; useEffect(() => { if (!skip && source) { @@ -72,7 +71,11 @@ export const sourceDecorator = ( const src = docs?.source?.originalSource; const name = ctx.title.split('/').at(-1)!; - source = generateSolidSource(name, src); + try { + source = generateSolidSource(name, src); + } catch (e) { + console.error(e); + } return story; }; @@ -80,40 +83,35 @@ export const sourceDecorator = ( /** * Generate Solid JSX from story source. */ -function generateSolidSource(name: string, src: string): string | null { - try { - const { attributes, children } = parseProps(src); - - const selfClosing = children == null || children.length == 0; - - const component = { - type: 'JSXElement', - openingElement: { - type: 'JSXOpeningElement', - name: { - type: 'JSXIdentifier', - name, - }, - attributes: attributes, - selfClosing, +export function generateSolidSource(name: string, src: string): string { + const { attributes, children } = parseProps(src); + + const selfClosing = children == null || children.length == 0; + + const component = { + type: 'JSXElement', + openingElement: { + type: 'JSXOpeningElement', + name: { + type: 'JSXIdentifier', + name, }, - children: children ?? [], - closingElement: selfClosing - ? undefined - : { - type: 'JSXClosingElement', - name: { - type: 'JSXIdentifier', - name, - }, + attributes: attributes, + selfClosing, + }, + children: children ?? [], + closingElement: selfClosing + ? undefined + : { + type: 'JSXClosingElement', + name: { + type: 'JSXIdentifier', + name, }, - }; + }, + }; - return generate(component, { compact: false }).code; - } catch (e) { - console.error(e); - return null; - } + return generate(component, { compact: false }).code; } /** @@ -169,7 +167,7 @@ function parseProps(src: string): SolidProps { if (v.key.type != 'Identifier') return false; return v.key.name == 'args'; }) as any | undefined; - // No args just there aren't any properties or children. + // No args, so there aren't any properties or children. if (!args_prop) return { attributes: [], From 5558ae526aa6a8996a349d9076841fec88e784b2 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:31:04 -0500 Subject: [PATCH 11/15] Add testing for source transformer --- package.json | 9 +- .../solid/src/docs/sourceDecorator.test.tsx | 127 ++++++++ .../solid/src/docs/sourceDecorator.tsx | 2 +- yarn.lock | 278 +++++++++++++++++- 4 files changed, 408 insertions(+), 8 deletions(-) create mode 100644 packages/renderers/solid/src/docs/sourceDecorator.test.tsx diff --git a/package.json b/package.json index e6ca177..c7213af 100644 --- a/package.json +++ b/package.json @@ -35,16 +35,19 @@ "ts-node": "^10.9.2", "tsup": "^8.3.0", "typescript": "^5.6.3", - "typescript-eslint": "^8.10.0" + "typescript-eslint": "^8.10.0", + "vitest": "^2.1.4" }, "scripts": { "build": "yarn workspaces foreach --all -pt run build", - "check:all": "yarn run check:lint && yarn run check:format", + "check:all": "yarn run check:lint && yarn run check:test && yarn run check:format", "check:format": "prettier --check .", "check:lint": "eslint .", + "check:test": "vitest run --no-isolate", "fix:all": "yarn run fix:lint && yarn run fix:format", "fix:format": "prettier --write .", - "fix:lint": "eslint . --fix" + "fix:lint": "eslint . --fix", + "test": "vitest" }, "packageManager": "yarn@4.5.1" } diff --git a/packages/renderers/solid/src/docs/sourceDecorator.test.tsx b/packages/renderers/solid/src/docs/sourceDecorator.test.tsx new file mode 100644 index 0000000..07b8361 --- /dev/null +++ b/packages/renderers/solid/src/docs/sourceDecorator.test.tsx @@ -0,0 +1,127 @@ +import { afterAll, describe, expect, test, vi } from 'vitest'; +import { generateSolidSource } from './sourceDecorator'; + +test('plain component', () => { + const newSrc1 = generateSolidSource('Component', '{ }'); + + expect(newSrc1).toMatchInlineSnapshot(`""`); + + const newSrc2 = generateSolidSource('Component', '{ args: { } }'); + + expect(newSrc2).toMatchInlineSnapshot(`""`); +}); + +test('component with props', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { foo: 32, bar: "Hello" } }', + ); + + expect(newSrc).toMatchInlineSnapshot( + `""`, + ); +}); + +test('component with children', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { children: "Hello" } }', + ); + + expect(newSrc).toMatchInlineSnapshot(`"Hello"`); +}); + +test('component with true prop', () => { + const newSrc = generateSolidSource('Component', '{ args: { foo: true } }'); + + expect(newSrc).toMatchInlineSnapshot(`""`); +}); + +test('component with props and children', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { foo: 32, children: "Hello" } }', + ); + + expect(newSrc).toMatchInlineSnapshot( + `"Hello"`, + ); +}); + +test('component with method prop', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { search() { return 32; } } }', + ); + + expect(newSrc).toMatchInlineSnapshot(` + " { + return 32; + }} />" + `); +}); + +test('component missing story config', () => { + const newSrc = () => generateSolidSource('Component', '5 + 4'); + + expect(newSrc).toThrow('Expected `ObjectExpression` type'); +}); + +test('component has invalid args', () => { + const newSrc = () => generateSolidSource('Component', '{ args: 5 }'); + + expect(newSrc).toThrow('Expected `ObjectExpression` type'); +}); + +describe('catch warnings for skipped props', () => { + const consoleMock = vi.spyOn(console, 'warn').mockImplementation(() => {}); + + afterAll(() => { + consoleMock.mockReset(); + }); + + test('component prop has computed name', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { ["foo"]: 32 } }', + ); + + expect(newSrc).toMatchInlineSnapshot(`""`); + expect(consoleMock).toHaveBeenCalledWith( + 'Encountered computed key, skipping...', + ); + }); + + test('component method has computed name', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { ["foo"]() { return 32; } } }', + ); + + expect(newSrc).toMatchInlineSnapshot(`""`); + expect(consoleMock).toHaveBeenCalledWith( + 'Encountered computed key, skipping...', + ); + }); + + test('component method is a getter or setter', () => { + const newSrc = generateSolidSource( + 'Component', + '{ args: { get foo() { return 32; } } }', + ); + + expect(newSrc).toMatchInlineSnapshot(`""`); + expect(consoleMock).toHaveBeenCalledWith( + 'Encountered getter or setter, skipping...', + ); + }); + + test('component prop is a spread element', () => { + const newSrc = generateSolidSource('Component', '{ args: { ...foo } }'); + + expect(newSrc).toMatchInlineSnapshot(`""`); + expect(consoleMock).toHaveBeenCalledWith( + 'Encountered spread element, skipping...', + ); + }); +}); diff --git a/packages/renderers/solid/src/docs/sourceDecorator.tsx b/packages/renderers/solid/src/docs/sourceDecorator.tsx index 768cf27..5bc035d 100644 --- a/packages/renderers/solid/src/docs/sourceDecorator.tsx +++ b/packages/renderers/solid/src/docs/sourceDecorator.tsx @@ -201,7 +201,7 @@ function parseProps(src: string): SolidProps { break; case 'SpreadElement': // Spread elements use external values, should not be used. - console.warn('Encountered spread element, skipping....'); + console.warn('Encountered spread element, skipping...'); continue; } diff --git a/yarn.lock b/yarn.lock index 9e118a9..6b80ffc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1541,6 +1541,7 @@ __metadata: tsup: "npm:^8.3.0" typescript: "npm:^5.6.3" typescript-eslint: "npm:^8.10.0" + vitest: "npm:^2.1.4" languageName: unknown linkType: soft @@ -2187,6 +2188,37 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/expect@npm:2.1.4" + dependencies: + "@vitest/spy": "npm:2.1.4" + "@vitest/utils": "npm:2.1.4" + chai: "npm:^5.1.2" + tinyrainbow: "npm:^1.2.0" + checksum: 10/0b3806d39233843a9661f6d5ccde489c9b6d278426f889198a862d601dcc186f107398487374195eb0dae90c9f69628f3f216200d644f817fa25d64ae1bc537e + languageName: node + linkType: hard + +"@vitest/mocker@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/mocker@npm:2.1.4" + dependencies: + "@vitest/spy": "npm:2.1.4" + estree-walker: "npm:^3.0.3" + magic-string: "npm:^0.30.12" + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + checksum: 10/00f323cc184977b247a1f0b9c51fdcceb97377031d728c69ef0bd14ebf0256742a94c68c6caa90eb073ed3de4277febd7d54715508bff05bb2fb7767ce11afbe + languageName: node + linkType: hard + "@vitest/pretty-format@npm:2.0.5": version: 2.0.5 resolution: "@vitest/pretty-format@npm:2.0.5" @@ -2205,6 +2237,36 @@ __metadata: languageName: node linkType: hard +"@vitest/pretty-format@npm:2.1.4, @vitest/pretty-format@npm:^2.1.4": + version: 2.1.4 + resolution: "@vitest/pretty-format@npm:2.1.4" + dependencies: + tinyrainbow: "npm:^1.2.0" + checksum: 10/434e6a7903f72a3796f26516ad728aca92724909e18fd3f2cd4b9b8b0ae2cc7b4cd86e92ab9f2ac7bc005c7a7ef0bcb9d768c0264b4b0625f1f0748cc615f1f6 + languageName: node + linkType: hard + +"@vitest/runner@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/runner@npm:2.1.4" + dependencies: + "@vitest/utils": "npm:2.1.4" + pathe: "npm:^1.1.2" + checksum: 10/51dbea968ace6edefb058d88c9736fa524a64f4dc750ec163b43f5015a31b31f2d80a7b20de4c2a819fbfb172162ad4d0f8428c78fa7ca832c1a1b135161ac4b + languageName: node + linkType: hard + +"@vitest/snapshot@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/snapshot@npm:2.1.4" + dependencies: + "@vitest/pretty-format": "npm:2.1.4" + magic-string: "npm:^0.30.12" + pathe: "npm:^1.1.2" + checksum: 10/785f74cf5f7745eb0dcb73fe3c628bc1f687c6341e8ba63d722fa83609d21465302ebd208405b9f91ce87fb36720a0f361c949983d5caccbcb8ec2119f995483 + languageName: node + linkType: hard + "@vitest/spy@npm:2.0.5": version: 2.0.5 resolution: "@vitest/spy@npm:2.0.5" @@ -2214,6 +2276,15 @@ __metadata: languageName: node linkType: hard +"@vitest/spy@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/spy@npm:2.1.4" + dependencies: + tinyspy: "npm:^3.0.2" + checksum: 10/4dd3e7c28928abb047c567b3711d1cbccd59aaae294c57efaab83cdd723b568882de5376fc086c919a4cb6d1df5e6cc0502b3171cce06dfce87863c731fd5d36 + languageName: node + linkType: hard + "@vitest/utils@npm:2.0.5": version: 2.0.5 resolution: "@vitest/utils@npm:2.0.5" @@ -2226,6 +2297,17 @@ __metadata: languageName: node linkType: hard +"@vitest/utils@npm:2.1.4": + version: 2.1.4 + resolution: "@vitest/utils@npm:2.1.4" + dependencies: + "@vitest/pretty-format": "npm:2.1.4" + loupe: "npm:^3.1.2" + tinyrainbow: "npm:^1.2.0" + checksum: 10/aaaf5310943abca0f0080d9638e67838f7e519d5670ec32e61184915efdfa5ec61d9b495cad6cb7dc492e8caeed14593e78dda77c8ea59c1671a231661f57142 + languageName: node + linkType: hard + "@vitest/utils@npm:^2.1.1": version: 2.1.3 resolution: "@vitest/utils@npm:2.1.3" @@ -2639,6 +2721,19 @@ __metadata: languageName: node linkType: hard +"chai@npm:^5.1.2": + version: 5.1.2 + resolution: "chai@npm:5.1.2" + dependencies: + assertion-error: "npm:^2.0.1" + check-error: "npm:^2.1.1" + deep-eql: "npm:^5.0.1" + loupe: "npm:^3.1.0" + pathval: "npm:^2.0.0" + checksum: 10/e8c2bbc83cb5a2f87130d93056d4cfbbe04106e12aa798b504816dbe3fa538a9f68541b472e56cbf0f54558b501d7e31867d74b8218abcd5a8cc8ba536fba46c + languageName: node + linkType: hard + "chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -2830,7 +2925,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5": +"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.3.5, debug@npm:^4.3.7": version: 4.3.7 resolution: "debug@npm:4.3.7" dependencies: @@ -3503,6 +3598,13 @@ __metadata: languageName: node linkType: hard +"expect-type@npm:^1.1.0": + version: 1.1.0 + resolution: "expect-type@npm:1.1.0" + checksum: 10/05fca80ddc7d493a89361f783c6b000750fa04a8226bc24701f3b90adb0efc2fb467f2a0baaed4015a02d8b9034ef5bb87521df9dba980f50b1105bd596ef833 + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" @@ -4404,7 +4506,7 @@ __metadata: languageName: node linkType: hard -"loupe@npm:^3.1.0, loupe@npm:^3.1.1": +"loupe@npm:^3.1.0, loupe@npm:^3.1.1, loupe@npm:^3.1.2": version: 3.1.2 resolution: "loupe@npm:3.1.2" checksum: 10/8f5734e53fb64cd914aa7d986e01b6d4c2e3c6c56dcbd5428d71c2703f0ab46b5ab9f9eeaaf2b485e8a1c43f865bdd16ec08ae1a661c8f55acdbd9f4d59c607a @@ -4436,7 +4538,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.10, magic-string@npm:^0.30.11": +"magic-string@npm:^0.30.10, magic-string@npm:^0.30.11, magic-string@npm:^0.30.12": version: 0.30.12 resolution: "magic-string@npm:0.30.12" dependencies: @@ -4917,6 +5019,13 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.1.2": + version: 1.1.2 + resolution: "pathe@npm:1.1.2" + checksum: 10/f201d796351bf7433d147b92c20eb154a4e0ea83512017bf4ec4e492a5d6e738fb45798be4259a61aa81270179fce11026f6ff0d3fa04173041de044defe9d80 + languageName: node + linkType: hard + "pathval@npm:^2.0.0": version: 2.0.0 resolution: "pathval@npm:2.0.0" @@ -5487,6 +5596,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 10/e93ff66c6531a079af8fb217240df01f980155b5dc408d2d7bebc398dd284e383eb318153bf8acd4db3c4fe799aa5b9a641e38b0ba3b1975700b1c89547ea4e7 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.3": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -5653,6 +5769,20 @@ __metadata: languageName: node linkType: hard +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 10/2d4dc4e64e2db796de4a3c856d5943daccdfa3dd092e452a1ce059c81e9a9c29e0b9badba91b43ef0d5ff5c04ee62feb3bcc559a804e16faf447bac2d883aa99 + languageName: node + linkType: hard + +"std-env@npm:^3.7.0": + version: 3.8.0 + resolution: "std-env@npm:3.8.0" + checksum: 10/034176196cfcaaab16dbdd96fc9e925a9544799fb6dc5a3e36fe43270f3a287c7f779d785b89edaf22cef2b5f1dcada2aae67430b8602e785ee74bdb3f671768 + languageName: node + linkType: hard + "storybook-solid-example@workspace:example": version: 0.0.0-use.local resolution: "storybook-solid-example@workspace:example" @@ -5919,6 +6049,20 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.9.0": + version: 2.9.0 + resolution: "tinybench@npm:2.9.0" + checksum: 10/cfa1e1418e91289219501703c4693c70708c91ffb7f040fd318d24aef419fb5a43e0c0160df9471499191968b2451d8da7f8087b08c3133c251c40d24aced06c + languageName: node + linkType: hard + +"tinyexec@npm:^0.3.1": + version: 0.3.1 + resolution: "tinyexec@npm:0.3.1" + checksum: 10/0537c70590d52d354f40c0255ff0f654a3d18ddb3812b440ddf9d436edf516c8057838ad5a38744c0c59670ec03e3cf23fbe04ae3d49f031d948274e99002569 + languageName: node + linkType: hard + "tinyglobby@npm:^0.2.1": version: 0.2.9 resolution: "tinyglobby@npm:0.2.9" @@ -5929,6 +6073,13 @@ __metadata: languageName: node linkType: hard +"tinypool@npm:^1.0.1": + version: 1.0.1 + resolution: "tinypool@npm:1.0.1" + checksum: 10/eaceb93784b8e27e60c0e3e2c7d11c29e1e79b2a025b2c232215db73b90fe22bd4753ad53fc8e801c2b5a63b94a823af549555d8361272bc98271de7dd4a9925 + languageName: node + linkType: hard + "tinyrainbow@npm:^1.2.0": version: 1.2.0 resolution: "tinyrainbow@npm:1.2.0" @@ -5936,7 +6087,7 @@ __metadata: languageName: node linkType: hard -"tinyspy@npm:^3.0.0": +"tinyspy@npm:^3.0.0, tinyspy@npm:^3.0.2": version: 3.0.2 resolution: "tinyspy@npm:3.0.2" checksum: 10/5db671b2ff5cd309de650c8c4761ca945459d7204afb1776db9a04fb4efa28a75f08517a8620c01ee32a577748802231ad92f7d5b194dc003ee7f987a2a06337 @@ -6263,6 +6414,20 @@ __metadata: languageName: node linkType: hard +"vite-node@npm:2.1.4": + version: 2.1.4 + resolution: "vite-node@npm:2.1.4" + dependencies: + cac: "npm:^6.7.14" + debug: "npm:^4.3.7" + pathe: "npm:^1.1.2" + vite: "npm:^5.0.0" + bin: + vite-node: vite-node.mjs + checksum: 10/3c3fbe6e41ab1716f4e6e0b52dcb80e027cb481df03e31d9bb5d16bb0ffabc5c884cca705ef8a5dea60f787e5eb78a428977d0d40e61e1f331bfb8c3d486d3e2 + languageName: node + linkType: hard + "vite-plugin-solid@npm:^2.10.2, vite-plugin-solid@npm:^2.8.2": version: 2.10.2 resolution: "vite-plugin-solid@npm:2.10.2" @@ -6284,6 +6449,49 @@ __metadata: languageName: node linkType: hard +"vite@npm:^5.0.0": + version: 5.4.10 + resolution: "vite@npm:5.4.10" + dependencies: + esbuild: "npm:^0.21.3" + fsevents: "npm:~2.3.3" + postcss: "npm:^8.4.43" + rollup: "npm:^4.20.0" + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + sass-embedded: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 10/5d4a427d585d6f9114fc383114f707dca46408f54b221709e5eb6b0c16e0b4dec4baf908a7db9a8f1e5b16e64b655900ac14629abe61c698cbe296115c65ed8a + languageName: node + linkType: hard + "vite@npm:^5.4.8": version: 5.4.8 resolution: "vite@npm:5.4.8" @@ -6339,6 +6547,56 @@ __metadata: languageName: node linkType: hard +"vitest@npm:^2.1.4": + version: 2.1.4 + resolution: "vitest@npm:2.1.4" + dependencies: + "@vitest/expect": "npm:2.1.4" + "@vitest/mocker": "npm:2.1.4" + "@vitest/pretty-format": "npm:^2.1.4" + "@vitest/runner": "npm:2.1.4" + "@vitest/snapshot": "npm:2.1.4" + "@vitest/spy": "npm:2.1.4" + "@vitest/utils": "npm:2.1.4" + chai: "npm:^5.1.2" + debug: "npm:^4.3.7" + expect-type: "npm:^1.1.0" + magic-string: "npm:^0.30.12" + pathe: "npm:^1.1.2" + std-env: "npm:^3.7.0" + tinybench: "npm:^2.9.0" + tinyexec: "npm:^0.3.1" + tinypool: "npm:^1.0.1" + tinyrainbow: "npm:^1.2.0" + vite: "npm:^5.0.0" + vite-node: "npm:2.1.4" + why-is-node-running: "npm:^2.3.0" + peerDependencies: + "@edge-runtime/vm": "*" + "@types/node": ^18.0.0 || >=20.0.0 + "@vitest/browser": 2.1.4 + "@vitest/ui": 2.1.4 + happy-dom: "*" + jsdom: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@types/node": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + bin: + vitest: vitest.mjs + checksum: 10/bf0bb39e6148678ccc0d856a6a08e99458e80266558f97757bd20980812cd439f51599bcb64c807805594bf6fdb2111fdca688bc8884524819cc4a84a4598109 + languageName: node + linkType: hard + "walk-up-path@npm:^3.0.1": version: 3.0.1 resolution: "walk-up-path@npm:3.0.1" @@ -6406,6 +6664,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.3.0": + version: 2.3.0 + resolution: "why-is-node-running@npm:2.3.0" + dependencies: + siginfo: "npm:^2.0.0" + stackback: "npm:0.0.2" + bin: + why-is-node-running: cli.js + checksum: 10/0de6e6cd8f2f94a8b5ca44e84cf1751eadcac3ebedcdc6e5fbbe6c8011904afcbc1a2777c53496ec02ced7b81f2e7eda61e76bf8262a8bc3ceaa1f6040508051 + languageName: node + linkType: hard + "word-wrap@npm:^1.2.5": version: 1.2.5 resolution: "word-wrap@npm:1.2.5" From 2b42819a2d5f4f6632cfa21b09feed2dccdea279 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:52:27 -0500 Subject: [PATCH 12/15] Optimize workflows and add testing to CI --- .github/actions/setup/action.yml | 24 ++++++++++++++++ .github/workflows/ci.yml | 48 ++++++-------------------------- .github/workflows/solid-vite.yml | 21 +------------- .github/workflows/solid.yml | 21 +------------- 4 files changed, 34 insertions(+), 80 deletions(-) create mode 100644 .github/actions/setup/action.yml diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..b7cb7fa --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,24 @@ +name: Setup Standard Workflow +runs: + using: composite + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + - name: Enable Corepack + run: corepack enable && corepack install + - name: Print versions + run: node --version && yarn --version + - name: Get yarn cache directory path + id: yarn-cache-dir-path + run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT + - uses: actions/cache@v4 + id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + - name: Install project dependencies + run: yarn install diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3eace3f..9f810c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,50 +9,18 @@ jobs: format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '20' - - name: Enable Corepack - run: corepack enable && corepack install - - name: Print versions - run: node --version && yarn --version - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - uses: actions/cache@v4 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Install project dependencies - run: yarn install + - uses: ./.github/actions/setup - name: Run formatter run: yarn check:format lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '20' - - name: Enable Corepack - run: corepack enable && corepack install - - name: Print versions - run: node --version && yarn --version - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - uses: actions/cache@v4 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Install project dependencies - run: yarn install + - uses: ./.github/actions/setup - name: Run linter run: yarn check:lint + test: + runs-on: ubuntu-latest + steps: + - uses: ./.github/actions/setup + - name: Run tests + run: yarn check:test diff --git a/.github/workflows/solid-vite.yml b/.github/workflows/solid-vite.yml index 063b097..f98dcd5 100644 --- a/.github/workflows/solid-vite.yml +++ b/.github/workflows/solid-vite.yml @@ -14,26 +14,7 @@ jobs: runs-on: ubuntu-latest name: Lib workflow steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '20' - - name: Enable Corepack - run: corepack enable && corepack install - - name: Print versions - run: node --version && yarn --version - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - uses: actions/cache@v4 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Install project dependencies - run: yarn install + - uses: ./.github/actions/setup - name: Check bundling run: yarn check working-directory: packages/frameworks/solid-vite diff --git a/.github/workflows/solid.yml b/.github/workflows/solid.yml index 5d56683..ee83105 100644 --- a/.github/workflows/solid.yml +++ b/.github/workflows/solid.yml @@ -22,26 +22,7 @@ jobs: runs-on: ubuntu-latest name: Lib workflow steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: '20' - - name: Enable Corepack - run: corepack enable && corepack install - - name: Print versions - run: node --version && yarn --version - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - - uses: actions/cache@v4 - id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Install project dependencies - run: yarn install + - uses: ./.github/actions/setup - name: Check bundling run: yarn check working-directory: packages/renderers/solid From 358bbfdddca6f841cc73e90b8155f578f0153fdb Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:54:51 -0500 Subject: [PATCH 13/15] Move checkout to parents --- .github/actions/setup/action.yml | 1 - .github/workflows/ci.yml | 3 +++ .github/workflows/solid-vite.yml | 1 + .github/workflows/solid.yml | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index b7cb7fa..3b35c72 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -2,7 +2,6 @@ name: Setup Standard Workflow runs: using: composite steps: - - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '20' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9f810c6..0e4b1dc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,18 +9,21 @@ jobs: format: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Run formatter run: yarn check:format lint: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Run linter run: yarn check:lint test: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Run tests run: yarn check:test diff --git a/.github/workflows/solid-vite.yml b/.github/workflows/solid-vite.yml index f98dcd5..51ef761 100644 --- a/.github/workflows/solid-vite.yml +++ b/.github/workflows/solid-vite.yml @@ -14,6 +14,7 @@ jobs: runs-on: ubuntu-latest name: Lib workflow steps: + - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Check bundling run: yarn check diff --git a/.github/workflows/solid.yml b/.github/workflows/solid.yml index ee83105..4778ef4 100644 --- a/.github/workflows/solid.yml +++ b/.github/workflows/solid.yml @@ -22,6 +22,7 @@ jobs: runs-on: ubuntu-latest name: Lib workflow steps: + - uses: actions/checkout@v4 - uses: ./.github/actions/setup - name: Check bundling run: yarn check From 1b330ee7cf639222f9767d88c37586b077d92917 Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:58:03 -0500 Subject: [PATCH 14/15] Added shell property --- .github/actions/setup/action.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 3b35c72..75287f8 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -6,11 +6,14 @@ runs: with: node-version: '20' - name: Enable Corepack + shell: bash run: corepack enable && corepack install - name: Print versions + shell: bash run: node --version && yarn --version - name: Get yarn cache directory path id: yarn-cache-dir-path + shell: bash run: echo "dir=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT - uses: actions/cache@v4 id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) @@ -20,4 +23,5 @@ runs: restore-keys: | ${{ runner.os }}-yarn- - name: Install project dependencies + shell: bash run: yarn install From 2e216fa06e12af393e145f2acac3496f3dd02bee Mon Sep 17 00:00:00 2001 From: Jonah Henriksson <33059163+JonahPlusPlus@users.noreply.github.com> Date: Sun, 10 Nov 2024 18:04:39 -0500 Subject: [PATCH 15/15] Update CONTRIBUTING.md --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6478458..f6fc1d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,8 +18,9 @@ Install dependencies with `yarn`. To build packages, run `yarn build`, either in the top-level for all or inside a specific package for one. -For formatting and linting, run `yarn check:all` to run checks and `yarn fix:all` to apply fixes where possible. -There is also `*:format` and `*:lint` variants for running them separately (e.g. `yarn check:format` to check formatting). +For formatting, linting, and testing, run `yarn check:all` to run checks and `yarn fix:all` to apply fixes where possible. +There is also `*:format`, `*:lint`, and `*:test` variants for running them separately (e.g. `yarn check:format` to check formatting). +(There is no `fix:test` variant) These checks run during CI, so remember to run `yarn fix:all` before pushing (or create a githook to do it automatically).