@weaverclub/render 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/entrypoint +0 -0
  2. package/package.json +6 -2
  3. package/.github/workflows/publish.yml +0 -44
  4. package/biome.json +0 -42
  5. package/build.ts +0 -62
  6. package/bun.lock +0 -733
  7. package/bunfig.toml +0 -3
  8. package/ideas.md +0 -11
  9. package/publish.ts +0 -62
  10. package/src/cli/command/renderCommand.ts +0 -112
  11. package/src/cli/entrypoint.ts +0 -25
  12. package/src/core/bundler.ts +0 -180
  13. package/src/core/control/arrayControl.ts +0 -15
  14. package/src/core/control/booleanControl.ts +0 -15
  15. package/src/core/control/control.ts +0 -7
  16. package/src/core/control/controlBuilder.ts +0 -87
  17. package/src/core/control/numberControl.ts +0 -15
  18. package/src/core/control/stringControl.ts +0 -15
  19. package/src/core/control/variantControl.ts +0 -18
  20. package/src/core/css/css.ts +0 -50
  21. package/src/core/css/tailwind.ts +0 -172
  22. package/src/core/html.ts +0 -63
  23. package/src/core/pkg.ts +0 -92
  24. package/src/core/story.ts +0 -52
  25. package/src/core/tsconfig.ts +0 -46
  26. package/src/react/react.ts +0 -2
  27. package/src/react/reactControlBuilder.ts +0 -130
  28. package/src/react/reactStory.ts +0 -36
  29. package/src/server/api/getStories.ts +0 -44
  30. package/src/server/api/renderIframe.ts +0 -66
  31. package/src/server/backend.ts +0 -104
  32. package/src/server/streaming.ts +0 -16
  33. package/src/ui/api.ts +0 -16
  34. package/src/ui/app.tsx +0 -23
  35. package/src/ui/cn.ts +0 -6
  36. package/src/ui/components/appSidebar.tsx +0 -76
  37. package/src/ui/components/button.stories.tsx +0 -32
  38. package/src/ui/components/button.tsx +0 -55
  39. package/src/ui/components/command.tsx +0 -187
  40. package/src/ui/components/contextMenu.tsx +0 -261
  41. package/src/ui/components/dialog.tsx +0 -153
  42. package/src/ui/components/input.tsx +0 -23
  43. package/src/ui/components/inputGroup.tsx +0 -157
  44. package/src/ui/components/kdb.tsx +0 -26
  45. package/src/ui/components/searchCommand.tsx +0 -5
  46. package/src/ui/components/separator.tsx +0 -22
  47. package/src/ui/components/sheet.tsx +0 -131
  48. package/src/ui/components/sidebar.tsx +0 -725
  49. package/src/ui/components/skeleton.tsx +0 -13
  50. package/src/ui/components/spinner.tsx +0 -15
  51. package/src/ui/components/tabButton.tsx +0 -80
  52. package/src/ui/components/tabContent.tsx +0 -20
  53. package/src/ui/components/tabList.tsx +0 -53
  54. package/src/ui/components/textarea.tsx +0 -17
  55. package/src/ui/components/tooltip.tsx +0 -67
  56. package/src/ui/frontend.tsx +0 -68
  57. package/src/ui/hooks/useMobile.ts +0 -23
  58. package/src/ui/index.html +0 -12
  59. package/src/ui/routeTree.gen.ts +0 -35
  60. package/src/ui/routes/__root.tsx +0 -9
  61. package/src/ui/styles.css +0 -123
  62. package/src/ui/tabs.tsx +0 -89
  63. package/tsconfig.json +0 -25
  64. package/tsr.config.json +0 -6
package/bunfig.toml DELETED
@@ -1,3 +0,0 @@
1
- [serve.static]
2
- plugins = ["bun-plugin-tailwind"]
3
- env = "BUN_PUBLIC_*"
package/ideas.md DELETED
@@ -1,11 +0,0 @@
1
- - [ ] Implement dark mode
2
- - [ ] Multi theme support
3
- - [ ] Global Component integration (example: change button variant in Header)
4
- - [ ] Undo/Apply changes
5
- - [ ] Multi tab support
6
- - [ ] Icon swapper integration (Lucide/HugeIcons etc)
7
- - [ ] ACP integration
8
-
9
- # v1.0 features
10
- - [ ] Multi lang/lib/framework support (React, Vue, Svelte, Solid, Angular etc)
11
- - [ ] Static build
package/publish.ts DELETED
@@ -1,62 +0,0 @@
1
- import { $ } from 'bun'
2
- import pkg from './package.json'
3
-
4
- const args = Bun.argv.slice(2)
5
- const versionArg = args[0]
6
-
7
- if (!versionArg) {
8
- console.error('❌ Usage: bun run publish <version>')
9
- console.error(' Example: bun run publish 1.0.2')
10
- console.error(' Example: bun run publish patch')
11
- console.error(' Example: bun run publish minor')
12
- console.error(' Example: bun run publish major')
13
- process.exit(1)
14
- }
15
-
16
- const currentVersion = pkg.version
17
- let newVersion: string
18
-
19
- if (['patch', 'minor', 'major'].includes(versionArg)) {
20
- const [major, minor, patch] = currentVersion.split('.').map(Number)
21
- switch (versionArg) {
22
- case 'patch':
23
- newVersion = `${major}.${minor}.${(patch ?? 0) + 1}`
24
- break
25
- case 'minor':
26
- newVersion = `${major}.${(minor ?? 0) + 1}.0`
27
- break
28
- case 'major':
29
- newVersion = `${(major ?? 0) + 1}.0.0`
30
- break
31
- default:
32
- newVersion = currentVersion
33
- }
34
- } else {
35
- newVersion = versionArg
36
- }
37
-
38
- console.log(`📦 Publishing render v${newVersion}`)
39
- console.log(` Current version: ${currentVersion}`)
40
- console.log('')
41
-
42
- // Run tests first
43
- // console.log('🧪 Running tests...')
44
- // await $`bun run test run`
45
-
46
- // Bump version
47
- console.log(`\n📝 Bumping version to ${newVersion}...`)
48
- await $`npm version ${newVersion} --no-git-tag-version`
49
-
50
- // Build
51
- console.log('\n🔨 Building...')
52
- await $`bun run build`
53
-
54
- // Git commit, tag, and push
55
- console.log('\n📤 Committing and pushing...')
56
- await $`git add package.json`
57
- await $`git commit -m "v${newVersion}"`
58
- await $`git tag v${newVersion}`
59
- await $`git push origin main --tags`
60
-
61
- console.log(`\n✅ Done! v${newVersion} is being published via GitHub Actions.`)
62
- console.log(` Check: https://github.com/weaverclub/render/actions`)
@@ -1,112 +0,0 @@
1
- import { watch } from 'node:fs'
2
- import { Path } from '@effect/platform'
3
- import { BunContext } from '@effect/platform-bun'
4
- import { Console, Effect } from 'effect'
5
- import { loadCSS } from '#core/css/css'
6
- import { compileTailwindCss } from '#core/css/tailwind'
7
- import { loadStories } from '#core/story'
8
- import {
9
- notifyHmrClients,
10
- startBackend,
11
- updateBackendState
12
- } from '#server/backend'
13
-
14
- export const renderCommand = Effect.fn(function* ({ path }: RenderCommandArgs) {
15
- const { resolve } = yield* Path.Path
16
-
17
- const absolutePath = resolve(path)
18
-
19
- let stories = yield* loadStories(absolutePath)
20
- let css = yield* loadCSS(absolutePath)
21
-
22
- yield* Console.log(`Found ${stories.length} stories`)
23
-
24
- const backend = yield* startBackend({
25
- stories,
26
- css,
27
- projectRoot: absolutePath
28
- })
29
-
30
- yield* Console.log('👀 Watching for file changes...')
31
-
32
- // Set up file watcher for HMR
33
- let debounceTimer: ReturnType<typeof setTimeout> | null = null
34
- const watcher = watch(
35
- absolutePath,
36
- { recursive: true },
37
- (_event, filename) => {
38
- // Only react to relevant file changes
39
- if (!filename) return
40
-
41
- // Ignore node_modules entirely
42
- if (filename.includes('node_modules')) return
43
-
44
- const isRelevant =
45
- filename.endsWith('.tsx') ||
46
- filename.endsWith('.ts') ||
47
- filename.endsWith('.jsx') ||
48
- filename.endsWith('.js') ||
49
- filename.endsWith('.css')
50
-
51
- if (!isRelevant) return
52
-
53
- // Debounce rapid changes
54
- if (debounceTimer) clearTimeout(debounceTimer)
55
- debounceTimer = setTimeout(async () => {
56
- console.log(`\n🔄 File changed: ${filename}`)
57
- console.time(' ⏱️ Total HMR')
58
-
59
- try {
60
- // Run story loading and CSS compilation in parallel
61
- // Total time = max(stories, css) instead of sum
62
- const [newStories, newCss] = await Promise.all([
63
- Effect.runPromise(
64
- loadStories(absolutePath).pipe(Effect.provide(BunContext.layer))
65
- ),
66
- Effect.runPromise(
67
- compileTailwindCss(absolutePath).pipe(
68
- Effect.provide(BunContext.layer)
69
- )
70
- )
71
- ])
72
-
73
- stories = newStories
74
- css = [newCss]
75
- console.log(
76
- ` Reloaded ${stories.length} stories, CSS: ${newCss.compiledOutput.length} bytes`
77
- )
78
-
79
- // Update backend state for new requests
80
- updateBackendState({
81
- stories,
82
- css,
83
- projectRoot: absolutePath
84
- })
85
-
86
- // Notify connected clients
87
- notifyHmrClients()
88
- console.timeEnd(' ⏱️ Total HMR')
89
- console.log(` ✅ HMR complete`)
90
- } catch (error) {
91
- console.timeEnd(' ⏱️ Total HMR')
92
- console.error(' Error during reload:', error)
93
- }
94
- }, 100)
95
- }
96
- )
97
-
98
- // Handle cleanup on exit
99
- process.on('SIGINT', () => {
100
- console.log('\n\n👋 Shutting down...')
101
- watcher.close()
102
- backend.stop()
103
- process.exit(0)
104
- })
105
-
106
- // Keep the server running
107
- yield* Effect.never
108
- })
109
-
110
- type RenderCommandArgs = {
111
- path: string
112
- }
@@ -1,25 +0,0 @@
1
- #! /usr/bin/env bun
2
-
3
- import { Args, Command } from '@effect/cli'
4
- import { BunContext, BunRuntime } from '@effect/platform-bun'
5
- import { Effect } from 'effect'
6
- import pkg from '../../package.json' with { type: 'json' }
7
- import { renderCommand } from './command/renderCommand'
8
-
9
- const path = Args.path()
10
-
11
- const command = Command.make('render', { path }).pipe(
12
- Command.withDescription('The simplest way to preview React components'),
13
- Command.withHandler(renderCommand)
14
- )
15
-
16
- const cli = Command.run(command, {
17
- name: 'Render',
18
- version: pkg.version
19
- })
20
-
21
- Effect.suspend(() => cli(process.argv)).pipe(
22
- Effect.provide(BunContext.layer),
23
- Effect.tapErrorCause(Effect.logError),
24
- BunRuntime.runMain
25
- )
@@ -1,180 +0,0 @@
1
- import { FileSystem } from '@effect/platform'
2
- import { Effect, Option, Schema } from 'effect'
3
- import { findNearestNodeModules, getProjectDependencies } from './pkg'
4
- import { findNearestTsconfig } from './tsconfig'
5
-
6
- // Common React-related packages that might not be direct dependencies
7
- const commonExternals = [
8
- 'react',
9
- 'react-dom',
10
- 'react/jsx-runtime',
11
- 'react/jsx-dev-runtime',
12
- '@weaverclub/render'
13
- ]
14
-
15
- const moduleSchema = Schema.Record({
16
- key: Schema.String,
17
- value: Schema.Any
18
- })
19
-
20
- export const bundleStoryFile = Effect.fn(function* ({
21
- storyPath,
22
- projectRoot
23
- }: BundleStoryFileArgs) {
24
- const tsconfigPath = yield* findNearestTsconfig(projectRoot)
25
- const deps = yield* getProjectDependencies(projectRoot)
26
- const args = ['build', storyPath, '--target', 'bun', '--format', 'esm']
27
-
28
- for (const dep of deps) args.push('--external', dep)
29
- for (const ext of commonExternals)
30
- if (!deps.includes(ext)) args.push('--external', ext)
31
- if (Option.isSome(tsconfigPath))
32
- args.push('--tsconfig-override', tsconfigPath.value)
33
-
34
- const proc = Bun.spawn(['bun', ...args], {
35
- cwd: projectRoot,
36
- stdout: 'pipe',
37
- stderr: 'pipe'
38
- })
39
-
40
- const [stdout, stderr] = yield* Effect.all(
41
- [
42
- Effect.tryPromise(() => new Response(proc.stdout).text()),
43
- Effect.tryPromise(() => new Response(proc.stderr).text())
44
- ],
45
- {
46
- concurrency: 'unbounded'
47
- }
48
- )
49
-
50
- const exitCode = yield* Effect.tryPromise(() => proc.exited)
51
-
52
- if (exitCode !== 0)
53
- return yield* Effect.fail(`Bundle failed:\n${stderr || stdout}`)
54
-
55
- return stdout
56
- })
57
-
58
- /**
59
- * Bundle a story file for the browser with React hydration support.
60
- * This creates a self-contained bundle that can run in the browser.
61
- */
62
- export const bundleStoryForBrowser = Effect.fn(function* ({
63
- storyPath,
64
- projectRoot,
65
- storyId
66
- }: BundleStoryForBrowserArgs) {
67
- const tsconfigPath = yield* findNearestTsconfig(projectRoot)
68
-
69
- // Create a temporary entry file that imports the story and hydrates it
70
- const fs = yield* FileSystem.FileSystem
71
- const nodeModules = yield* findNearestNodeModules(projectRoot)
72
-
73
- const tempDir = Option.isSome(nodeModules)
74
- ? `${nodeModules.value}/.cache/render`
75
- : `${projectRoot}/.render-cache`
76
-
77
- yield* fs.makeDirectory(tempDir, { recursive: true })
78
-
79
- const entryFile = `${tempDir}/hydrate-${storyId.replace(/[^a-z0-9]/gi, '_')}.tsx`
80
-
81
- // Write the hydration entry file - using explicit React import for JSX
82
- const entryCode = `
83
- import * as React from 'react';
84
- import * as ReactDOMClient from 'react-dom/client';
85
- import * as StoryModule from '${storyPath}';
86
-
87
- const rootElement = document.getElementById('root');
88
-
89
- // Find the story export
90
- let StoryExport;
91
- for (const [key, exported] of Object.entries(StoryModule)) {
92
- if (exported && typeof exported === 'object' && '~type' in exported && exported['~type'] === 'ReactStory') {
93
- StoryExport = exported;
94
- break;
95
- }
96
- }
97
-
98
- if (StoryExport && rootElement) {
99
- // Get default props (empty for now, will be enhanced later)
100
- const defaultProps = {};
101
- const element = StoryExport.render(defaultProps);
102
- ReactDOMClient.hydrateRoot(rootElement, element);
103
- }
104
- `
105
-
106
- yield* fs.writeFileString(entryFile, entryCode)
107
-
108
- // Build for browser
109
- const args = ['build', entryFile, '--target', 'browser', '--format', 'esm']
110
-
111
- // Don't mark anything as external for browser bundle - we need everything inlined
112
- if (Option.isSome(tsconfigPath))
113
- args.push('--tsconfig-override', tsconfigPath.value)
114
-
115
- const proc = Bun.spawn(['bun', ...args], {
116
- cwd: projectRoot,
117
- stdout: 'pipe',
118
- stderr: 'pipe'
119
- })
120
-
121
- const [stdout, stderr] = yield* Effect.all(
122
- [
123
- Effect.tryPromise(() => new Response(proc.stdout).text()),
124
- Effect.tryPromise(() => new Response(proc.stderr).text())
125
- ],
126
- {
127
- concurrency: 'unbounded'
128
- }
129
- )
130
-
131
- const exitCode = yield* Effect.tryPromise(() => proc.exited)
132
-
133
- // Clean up temp file
134
- yield* fs.remove(entryFile).pipe(Effect.ignore)
135
-
136
- if (exitCode !== 0)
137
- return yield* Effect.fail(`Browser bundle failed:\n${stderr || stdout}`)
138
-
139
- return stdout
140
- })
141
-
142
- export const importStoryWithBundler = Effect.fn(function* ({
143
- storyPath,
144
- projectRoot
145
- }: ImportStoryWithBundlerArgs) {
146
- const fs = yield* FileSystem.FileSystem
147
-
148
- const nodeModules = yield* findNearestNodeModules(projectRoot)
149
- const bundledCode = yield* bundleStoryFile({
150
- storyPath,
151
- projectRoot
152
- })
153
-
154
- const tempFile = yield* fs.makeTempFileScoped({
155
- directory: Option.isSome(nodeModules) ? nodeModules.value : undefined,
156
- suffix: '.mjs'
157
- })
158
-
159
- yield* fs.writeFileString(tempFile, bundledCode)
160
-
161
- const module = yield* Effect.tryPromise(() => import(tempFile))
162
-
163
- return yield* Schema.decodeUnknown(moduleSchema)(module)
164
- })
165
-
166
- type BundleStoryFileArgs = {
167
- storyPath: string
168
- projectRoot: string
169
- }
170
-
171
- type BundleStoryForBrowserArgs = {
172
- storyPath: string
173
- projectRoot: string
174
- storyId: string
175
- }
176
-
177
- type ImportStoryWithBundlerArgs = {
178
- storyPath: string
179
- projectRoot: string
180
- }
@@ -1,15 +0,0 @@
1
- import { Control } from './control'
2
-
3
- export class ArrayControl<T> extends Control {
4
- public defaultValue: Array<T>
5
-
6
- public constructor(args: ArrayControlArgs<T>) {
7
- super(args.name)
8
- this.defaultValue = args.defaultValue
9
- }
10
- }
11
-
12
- type ArrayControlArgs<T> = {
13
- name: string
14
- defaultValue: Array<T>
15
- }
@@ -1,15 +0,0 @@
1
- import { Control } from './control'
2
-
3
- export class BooleanControl extends Control {
4
- public defaultValue: boolean
5
-
6
- public constructor(args: BooleanControlArgs) {
7
- super(args.name)
8
- this.defaultValue = args.defaultValue
9
- }
10
- }
11
-
12
- type BooleanControlArgs = {
13
- name: string
14
- defaultValue: boolean
15
- }
@@ -1,7 +0,0 @@
1
- export class Control {
2
- public name: string
3
-
4
- public constructor(name: string) {
5
- this.name = name
6
- }
7
- }
@@ -1,87 +0,0 @@
1
- import type { Control } from './control'
2
-
3
- export interface ControlBuilder<Props, Used extends keyof Props> {
4
- array<Name extends Exclude<ArrayPropNames<Props>, Used> & string>(
5
- name: Name,
6
- options: {
7
- defaultValue: Props[Name]
8
- }
9
- ): ControlBuilder<Props, Used | Name>
10
-
11
- bool<Name extends Exclude<BooleanPropNames<Props>, Used> & string>(
12
- name: Name,
13
- options: {
14
- defaultValue: boolean
15
- }
16
- ): ControlBuilder<Props, Used | Name>
17
-
18
- number<Name extends Exclude<NumberPropNames<Props>, Used> & string>(
19
- name: Name,
20
- options: {
21
- defaultValue: number
22
- }
23
- ): ControlBuilder<Props, Used | Name>
24
-
25
- string<Name extends Exclude<StringPropNames<Props>, Used> & string>(
26
- name: Name,
27
- options: {
28
- defaultValue: string
29
- }
30
- ): ControlBuilder<Props, Used | Name>
31
-
32
- variant<Name extends Exclude<VariantPropNames<Props>, Used> & string>(
33
- name: Name,
34
- options: {
35
- defaultValue: ExtractStringLiteralUnion<Props[Name]>
36
- options: ExtractStringLiteralUnion<Props[Name]>[]
37
- }
38
- ): ControlBuilder<Props, Used | Name>
39
- }
40
-
41
- type NonNullableValue<T> = T extends null | undefined ? never : T
42
-
43
- export type ExtractStringLiteralUnion<T> =
44
- NonNullableValue<T> extends string
45
- ? string extends NonNullableValue<T>
46
- ? never
47
- : NonNullableValue<T>
48
- : never
49
-
50
- export type ArrayPropNames<Props> = {
51
- [K in keyof Props]: NonNullableValue<Props[K]> extends readonly unknown[]
52
- ? K
53
- : never
54
- }[keyof Props]
55
-
56
- export type BooleanPropNames<Props> = {
57
- [K in keyof Props]: NonNullableValue<Props[K]> extends boolean
58
- ? boolean extends NonNullableValue<Props[K]>
59
- ? K
60
- : never
61
- : never
62
- }[keyof Props]
63
-
64
- export type NumberPropNames<Props> = {
65
- [K in keyof Props]: NonNullableValue<Props[K]> extends number
66
- ? number extends NonNullableValue<Props[K]>
67
- ? K
68
- : never
69
- : never
70
- }[keyof Props]
71
-
72
- export type StringPropNames<Props> = {
73
- [K in keyof Props]: NonNullableValue<Props[K]> extends string
74
- ? string extends NonNullableValue<Props[K]>
75
- ? K
76
- : never
77
- : never
78
- }[keyof Props]
79
-
80
- export type VariantPropNames<Props> = {
81
- [K in keyof Props]: ExtractStringLiteralUnion<Props[K]> extends never
82
- ? never
83
- : K
84
- }[keyof Props]
85
-
86
- // biome-ignore lint/suspicious/noExplicitAny: Required for flexible builder type
87
- export type UnfinishedControls = ControlBuilder<any, any> | Control[]
@@ -1,15 +0,0 @@
1
- import { Control } from './control'
2
-
3
- export class NumberControl extends Control {
4
- public defaultValue: number
5
-
6
- public constructor(args: NumberControlArgs) {
7
- super(args.name)
8
- this.defaultValue = args.defaultValue
9
- }
10
- }
11
-
12
- type NumberControlArgs = {
13
- name: string
14
- defaultValue: number
15
- }
@@ -1,15 +0,0 @@
1
- import { Control } from './control'
2
-
3
- export class StringControl extends Control {
4
- public defaultValue: string
5
-
6
- public constructor(args: StringControlArgs) {
7
- super(args.name)
8
- this.defaultValue = args.defaultValue
9
- }
10
- }
11
-
12
- type StringControlArgs = {
13
- name: string
14
- defaultValue: string
15
- }
@@ -1,18 +0,0 @@
1
- import { Control } from './control'
2
-
3
- export class VariantControl<T> extends Control {
4
- public defaultValue: T
5
- public options: Array<T>
6
-
7
- public constructor(args: VariantControlArgs<T>) {
8
- super(args.name)
9
- this.defaultValue = args.defaultValue
10
- this.options = args.options
11
- }
12
- }
13
-
14
- type VariantControlArgs<T> = {
15
- name: string
16
- options: Array<T>
17
- defaultValue: T
18
- }
@@ -1,50 +0,0 @@
1
- import { Array as Arr, Effect } from 'effect'
2
- import { getProjectDependencies } from '../pkg'
3
- import { compileTailwindCss } from './tailwind'
4
-
5
- const tailwindDependencyNames = [
6
- 'tailwindcss',
7
- '@tailwindcss/vite',
8
- '@tailwindcss/cli'
9
- ]
10
-
11
- const cssStategyMap: Record<
12
- CSSStrategy,
13
- (projectRoot: string) => Effect.Effect<CSS, Error>
14
- > = {
15
- tailwind: compileTailwindCss
16
- }
17
-
18
- export const loadCSS = Effect.fn(function* (projectRoot: string) {
19
- const strategies = yield* detectCSSStrategies(projectRoot)
20
-
21
- const tasks = Arr.map(Array.from(strategies), (strategy) => {
22
- const loadFn = cssStategyMap[strategy]
23
- return loadFn(projectRoot)
24
- })
25
-
26
- const results = yield* Effect.all(tasks, {
27
- concurrency: 'unbounded'
28
- })
29
-
30
- return results
31
- })
32
-
33
- export const detectCSSStrategies = Effect.fn(function* (projectRoot: string) {
34
- const deps = yield* getProjectDependencies(projectRoot)
35
-
36
- const strategies = new Set<CSSStrategy>()
37
-
38
- for (const depName of tailwindDependencyNames) {
39
- if (deps.includes(depName)) strategies.add('tailwind')
40
- }
41
-
42
- return strategies
43
- })
44
-
45
- type CSSStrategy = 'tailwind'
46
-
47
- export type CSS = {
48
- paths: string[]
49
- compiledOutput: string
50
- }