@sylphx/silk-vite-plugin 1.0.0 → 1.1.0

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.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # @sylphx/silk-vite-plugin
2
+
3
+ Vite plugin for Silk - enables build-time CSS extraction and optimization.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @sylphx/silk @sylphx/silk-vite-plugin
9
+ # or
10
+ bun add @sylphx/silk @sylphx/silk-vite-plugin
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ **vite.config.ts:**
16
+
17
+ ```typescript
18
+ import { defineConfig } from 'vite'
19
+ import { silk } from '@sylphx/silk-vite-plugin'
20
+
21
+ export default defineConfig({
22
+ plugins: [
23
+ silk({
24
+ outputFile: 'silk.css', // Output CSS file
25
+ inject: true, // Auto-inject CSS
26
+ minify: true, // Minify CSS in production
27
+ watch: true // Watch for changes
28
+ })
29
+ ]
30
+ })
31
+ ```
32
+
33
+ **Import CSS in your app:**
34
+
35
+ ```typescript
36
+ import './silk.css'
37
+ ```
38
+
39
+ ## Features
40
+
41
+ - ✅ **Build-time Extraction** - Zero runtime CSS-in-JS overhead
42
+ - ✅ **Auto Injection** - Automatically inject CSS into HTML
43
+ - ✅ **Production Optimization** - Minification and deduplication
44
+ - ✅ **Hot Module Replacement** - Watch mode for development
45
+ - ✅ **TypeScript Support** - Full type safety
46
+
47
+ ## Options
48
+
49
+ ```typescript
50
+ interface SilkPluginOptions {
51
+ outputFile?: string // Output CSS file (default: 'silk.css')
52
+ inject?: boolean // Auto-inject CSS (default: true)
53
+ minify?: boolean // Minify CSS (default: based on mode)
54
+ watch?: boolean // Watch for changes (default: true)
55
+ }
56
+ ```
57
+
58
+ ## Ecosystem
59
+
60
+ ### Core
61
+ - **[@sylphx/silk](https://www.npmjs.com/package/@sylphx/silk)** - Core styling system
62
+
63
+ ### Framework Integrations
64
+ - **[@sylphx/silk-react](https://www.npmjs.com/package/@sylphx/silk-react)** - React bindings
65
+ - **[@sylphx/silk-vue](https://www.npmjs.com/package/@sylphx/silk-vue)** - Vue 3 Composition API
66
+ - **[@sylphx/silk-svelte](https://www.npmjs.com/package/@sylphx/silk-svelte)** - Svelte reactive stores
67
+ - **[@sylphx/silk-solid](https://www.npmjs.com/package/@sylphx/silk-solid)** - Solid.js fine-grained reactivity
68
+
69
+ ### Meta-Framework Plugins
70
+ - **[@sylphx/silk-nextjs](https://www.npmjs.com/package/@sylphx/silk-nextjs)** - Next.js App Router & RSC
71
+ - **[@sylphx/silk-remix](https://www.npmjs.com/package/@sylphx/silk-remix)** - Remix streaming SSR
72
+ - **[@sylphx/silk-astro](https://www.npmjs.com/package/@sylphx/silk-astro)** - Astro islands architecture
73
+
74
+ ## Documentation
75
+
76
+ Full documentation: [GitHub Repository](https://github.com/sylphxltd/silk)
77
+
78
+ ## License
79
+
80
+ MIT © [SylphX Ltd](https://sylphx.com)
package/dist/index.d.ts CHANGED
@@ -1,8 +1,33 @@
1
1
  /**
2
2
  * @sylphx/silk-vite-plugin
3
- * Build-time CSS extraction for zero runtime overhead
3
+ * Build-time CSS extraction with pre-compression (15-25% smaller)
4
4
  */
5
5
  import type { Plugin } from 'vite';
6
+ export interface CompressionOptions {
7
+ /**
8
+ * Enable Brotli compression (.css.br)
9
+ * 15-25% smaller than gzip, 70% compression for CSS
10
+ * @default true
11
+ */
12
+ brotli?: boolean;
13
+ /**
14
+ * Brotli quality (0-11, higher = better compression but slower)
15
+ * Use 11 for production (static compression, no runtime cost)
16
+ * @default 11
17
+ */
18
+ brotliQuality?: number;
19
+ /**
20
+ * Enable gzip compression (.css.gz)
21
+ * Fallback for older servers
22
+ * @default true
23
+ */
24
+ gzip?: boolean;
25
+ /**
26
+ * Gzip level (0-9)
27
+ * @default 9
28
+ */
29
+ gzipLevel?: number;
30
+ }
6
31
  export interface SilkPluginOptions {
7
32
  /**
8
33
  * Output CSS file path (relative to outDir)
@@ -24,6 +49,12 @@ export interface SilkPluginOptions {
24
49
  * @default true
25
50
  */
26
51
  watch?: boolean;
52
+ /**
53
+ * Pre-compression options (Brotli + gzip)
54
+ * Generates .br and .gz files for web servers
55
+ * @default { brotli: true, gzip: true }
56
+ */
57
+ compression?: CompressionOptions;
27
58
  }
28
59
  export declare function silk(options?: SilkPluginOptions): Plugin;
29
60
  export default silk;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAKjD,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,IAAI,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAyI5D;AAED,eAAe,IAAI,CAAA;AAEnB;;;GAGG;AACH,eAAO,MAAM,UAAU,iVAYtB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAOjD,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAEhB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf;;;;OAIG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAA;CACjC;AAED,wBAAgB,IAAI,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAoN5D;AAED,eAAe,IAAI,CAAA;AAEnB;;;GAGG;AACH,eAAO,MAAM,UAAU,iVAYtB,CAAA"}
package/dist/index.js CHANGED
@@ -1,13 +1,56 @@
1
1
  /**
2
2
  * @sylphx/silk-vite-plugin
3
- * Build-time CSS extraction for zero runtime overhead
3
+ * Build-time CSS extraction with pre-compression (15-25% smaller)
4
4
  */
5
5
  import { cssRules } from '@sylphx/silk';
6
+ import { compress } from 'brotli-wasm';
7
+ import { gzipSync } from 'node:zlib';
6
8
  export function silk(options = {}) {
7
- const { outputFile = 'silk.css', inject = true, minify, watch = true } = options;
9
+ const { outputFile = 'silk.css', inject = true, minify, watch = true, compression = {} } = options;
10
+ const compressionConfig = {
11
+ brotli: compression.brotli ?? true,
12
+ brotliQuality: compression.brotliQuality ?? 11,
13
+ gzip: compression.gzip ?? true,
14
+ gzipLevel: compression.gzipLevel ?? 9,
15
+ };
8
16
  let server;
9
17
  let isBuild = false;
10
18
  const cssCache = new Set();
19
+ /**
20
+ * Generate compressed versions of CSS
21
+ */
22
+ async function generateCompressedAssets(css, fileName) {
23
+ const outputs = [];
24
+ // Generate Brotli (.br)
25
+ if (compressionConfig.brotli) {
26
+ try {
27
+ const compressed = await compress(Buffer.from(css, 'utf-8'), {
28
+ quality: compressionConfig.brotliQuality,
29
+ });
30
+ outputs.push({
31
+ fileName: `${fileName}.br`,
32
+ source: Buffer.from(compressed),
33
+ });
34
+ }
35
+ catch (error) {
36
+ console.warn('Brotli compression failed:', error);
37
+ }
38
+ }
39
+ // Generate gzip (.gz)
40
+ if (compressionConfig.gzip) {
41
+ try {
42
+ const compressed = gzipSync(css, { level: compressionConfig.gzipLevel });
43
+ outputs.push({
44
+ fileName: `${fileName}.gz`,
45
+ source: compressed,
46
+ });
47
+ }
48
+ catch (error) {
49
+ console.warn('Gzip compression failed:', error);
50
+ }
51
+ }
52
+ return outputs;
53
+ }
11
54
  /**
12
55
  * Collect CSS rules from runtime
13
56
  */
@@ -81,18 +124,40 @@ export function silk(options = {}) {
81
124
  return `${styleTag}\n${html}`;
82
125
  },
83
126
  },
84
- generateBundle(_, bundle) {
127
+ async generateBundle(_, bundle) {
85
128
  if (!isBuild)
86
129
  return;
87
130
  const css = generateCSS();
88
131
  if (!css)
89
132
  return;
90
- // Emit CSS file
133
+ // Emit main CSS file
91
134
  this.emitFile({
92
135
  type: 'asset',
93
136
  fileName: outputFile,
94
137
  source: css,
95
138
  });
139
+ // Generate and emit compressed versions
140
+ const compressedAssets = await generateCompressedAssets(css, outputFile);
141
+ for (const asset of compressedAssets) {
142
+ this.emitFile({
143
+ type: 'asset',
144
+ fileName: asset.fileName,
145
+ source: asset.source,
146
+ });
147
+ }
148
+ // Log compression results
149
+ if (compressedAssets.length > 0) {
150
+ const originalSize = Buffer.byteLength(css, 'utf-8');
151
+ console.log('\n📦 Silk CSS Bundle:');
152
+ console.log(` Original: ${formatBytes(originalSize)} (${outputFile})`);
153
+ for (const asset of compressedAssets) {
154
+ const compressedSize = asset.source.length;
155
+ const savings = ((1 - compressedSize / originalSize) * 100).toFixed(1);
156
+ const ext = asset.fileName.split('.').pop();
157
+ console.log(` ${ext?.toUpperCase()}: ${formatBytes(compressedSize)} (-${savings}%)`);
158
+ }
159
+ console.log('');
160
+ }
96
161
  // Update HTML to reference external CSS file
97
162
  for (const fileName in bundle) {
98
163
  const chunk = bundle[fileName];
@@ -139,3 +204,13 @@ if (import.meta.hot) {
139
204
  })
140
205
  }
141
206
  `;
207
+ /**
208
+ * Format bytes to human-readable format
209
+ */
210
+ function formatBytes(bytes) {
211
+ if (bytes < 1024)
212
+ return `${bytes}B`;
213
+ if (bytes < 1024 * 1024)
214
+ return `${(bytes / 1024).toFixed(1)}KB`;
215
+ return `${(bytes / 1024 / 1024).toFixed(1)}MB`;
216
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sylphx/silk-vite-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Vite plugin for Silk - Build-time CSS extraction with production optimizations",
5
5
  "keywords": [
6
6
  "silk",
@@ -43,6 +43,7 @@
43
43
  "@sylphx/silk": "workspace:*"
44
44
  },
45
45
  "devDependencies": {
46
+ "brotli-wasm": "^3.0.1",
46
47
  "typescript": "^5.3.0",
47
48
  "vite": "^5.0.0"
48
49
  },