diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..a85fe12 --- /dev/null +++ b/USAGE.md @@ -0,0 +1,353 @@ +# Svelte Dynamic Component Engine - Usage Guide + +## Overview + +The Svelte Dynamic Component Engine now supports both file-based and string-based compilation of Svelte components. This allows you to compile Svelte components directly from source code strings without requiring physical files on the filesystem. + +## Installation + +```bash +npm install @mateothegreat/dynamic-component-engine +``` + +## API Reference + +### Types + +```typescript +interface ComponentSource { + name: string; // Component name + source: string; // Component source code + filename?: string; // Optional custom filename + type?: 'svelte' | 'ts' | 'js'; // Component type (auto-detected if not specified) +} + +interface CompilerOptions { + output: string; // Output directory + target: string; // Build target (default: 'esnext') + format: string; // Output format (default: 'esm') + debug: boolean; // Enable debug logging + banner: string; // Banner text for compiled files +} +``` + +## String-Based Compilation + +### Single Component + +```typescript +import { compileComponentFromSource } from '@mateothegreat/dynamic-component-engine/compiler'; + +const svelteSource = ` + + +

Hello {name}!

+

Count: {count}

+ + + +`; + +const result = await compileComponentFromSource( + 'HelloComponent', + svelteSource, + { + output: './dist', + target: 'esnext', + format: 'esm', + debug: true, + banner: '// Compiled with Svelte Dynamic Component Engine' + }, + 'svelte' // Component type (optional, auto-detected) +); + +console.log('Compiled files:', result?.length); +``` + +### Multiple Components + +```typescript +import { compileComponentsFromSource } from '@mateothegreat/dynamic-component-engine/compiler'; + +const components = [ + { + name: 'Button', + source: ` + + + + + + `, + type: 'svelte' + }, + { + name: 'Card', + source: ` + + +
+

{title}

+
+ +
+
+ + + `, + type: 'svelte' + } +]; + +const results = await compileComponentsFromSource(components, { + output: './dist/components', + target: 'esnext', + format: 'esm', + debug: false, + banner: '' +}); + +console.log(`Compiled ${results?.length} component files`); +``` + +## File-Based Compilation (Backward Compatible) + +### CLI Usage + +```bash +# Compile components from files +node src/compiler.ts --input="src/components/**/*.svelte" --output="./dist" --debug + +# With custom options +node src/compiler.ts \ + --input="src/components/**/*.svelte" \ + --output="./public/components" \ + --target="es2020" \ + --format="esm" \ + --banner="// My Custom Banner" \ + --debug +``` + +### Programmatic Usage + +```typescript +import { bundleSvelteFromFiles } from '@mateothegreat/dynamic-component-engine/compiler'; + +// Single file +const result = await bundleSvelteFromFiles( + 'src/components/MyComponent.svelte', + { + input: '', // Not used for file-based compilation + output: './dist', + target: 'esnext', + format: 'esm', + debug: true, + banner: '// Compiled component' + } +); + +// Multiple files +const results = await bundleSvelteFromFiles( + ['src/components/Button.svelte', 'src/components/Card.svelte'], + options +); +``` + +## Advanced Usage + +### Dynamic Component Loading + +After compilation, you can dynamically load and use your components: + +```typescript +// Assuming you've compiled a component and it's available +const componentModule = await import('./dist/HelloComponent.js'); +const componentFactory = componentModule.default; + +// Mount the component +const rendered = componentFactory( + document.getElementById('app'), // target element + { name: 'Svelte', count: 5 } // props +); + +// Later, destroy the component +rendered.destroy(); +``` + +### Runtime Component Generation + +```typescript +// Generate component source dynamically +function generateComponentSource(componentName: string, props: string[]): string { + const propsDeclaration = props.map(prop => `export let ${prop};`).join('\n '); + const propsDisplay = props.map(prop => `

{${prop}}

`).join('\n '); + + return ` + + +
+

${componentName}

+ ${propsDisplay} +
+ + + `; +} + +// Compile the dynamically generated component +const dynamicSource = generateComponentSource('UserCard', ['name', 'email', 'role']); +const result = await compileComponentFromSource('UserCard', dynamicSource, options); +``` + +### Error Handling + +```typescript +try { + const result = await compileComponentFromSource('MyComponent', source, options); + + if (!result || result.length === 0) { + console.error('Compilation failed: No output files generated'); + return; + } + + console.log('Compilation successful:', result.map(f => f.path)); +} catch (error) { + console.error('Compilation error:', error.message); + + if (error.errors) { + error.errors.forEach(err => { + console.error(` ${err.location?.file}:${err.location?.line} - ${err.text}`); + }); + } +} +``` + +## Configuration Options + +### Build Targets + +- `'es5'` - ES5 compatible output +- `'es2015'` - ES2015/ES6 compatible output +- `'es2017'` - ES2017 compatible output (default for most use cases) +- `'es2020'` - ES2020 compatible output +- `'esnext'` - Latest ECMAScript features (default) + +### Output Formats + +- `'esm'` - ES modules (default, recommended) +- `'cjs'` - CommonJS modules + +### Debug Mode + +When `debug: true` is enabled: +- Detailed build logs are shown +- Compilation timing information +- Plugin processing details +- Source map generation (if supported) + +## Best Practices + +1. **Component Naming**: Use PascalCase for component names (`MyComponent`, not `myComponent`) + +2. **Type Safety**: Explicitly specify component type when known: + ```typescript + const component = { name: 'Button', source: '...', type: 'svelte' as const }; + ``` + +3. **Error Boundaries**: Always wrap compilation in try-catch blocks + +4. **Performance**: For batch compilation, use `compileComponentsFromSource` instead of multiple `compileComponentFromSource` calls + +5. **Memory Management**: Remember to call `destroy()` on rendered components to prevent memory leaks + +## Troubleshooting + +### Common Issues + +**Issue**: `Expected ">" but found "lang"` +**Solution**: Ensure component type is set to `'svelte'` or let auto-detection work by including Svelte syntax in the source. + +**Issue**: `Virtual file not found` +**Solution**: This usually indicates a problem with the virtual file system. Use the new string-based compilation which uses `stdin` instead. + +**Issue**: CSS not being injected +**Solution**: Ensure `css: "injected"` is set in the Svelte compiler options (this is the default in the new version). + +### Debug Information + +Enable debug mode to get detailed information about the compilation process: + +```typescript +const result = await compileComponentFromSource(name, source, { + ...options, + debug: true +}); +``` + +This will show: +- Component detection results +- Build configuration +- Plugin execution order +- Compilation timing +- Output file details \ No newline at end of file diff --git a/build.js b/build.ts similarity index 100% rename from build.js rename to build.ts diff --git a/demo/build.js b/demo/build.js deleted file mode 100644 index 8c7f99d..0000000 --- a/demo/build.js +++ /dev/null @@ -1,34 +0,0 @@ -import esbuild from "esbuild"; -import esbuildSvelte from "esbuild-svelte"; -import { sveltePreprocess } from "svelte-preprocess"; - -async function bundleSvelte(entry) { - const build = await esbuild.build({ - logLevel: "debug", - entryPoints: Array.isArray(entry) ? entry : [entry], - target: "esnext", - format: "esm", - splitting: false, - packages: "external", - banner: { - js: "// I'm compiled from entry.ts which imports simple.svelte using esbuild-svelte." - }, - bundle: true, - outdir: "./public", - plugins: [ - esbuildSvelte({ - preprocess: sveltePreprocess(), - css: true, - compilerOptions: { - css: "injected", - preserveComments: true, - preserveWhitespace: true - } - }) - ] - }); - - return build.outputFiles; -} - -bundleSvelte(["./src/components/entry.ts"]); diff --git a/demo/index.html b/demo/index.html index 6893ea7..7329a60 100644 --- a/demo/index.html +++ b/demo/index.html @@ -7,9 +7,10 @@ diff --git a/demo/package-lock.json b/demo/package-lock.json index 1d7dba2..592ff4f 100644 --- a/demo/package-lock.json +++ b/demo/package-lock.json @@ -1,27 +1,31 @@ { "name": "demo", - "version": "0.0.1", + "version": "0.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "demo", - "version": "0.0.1", + "version": "0.0.0", "dependencies": { - "tailwindcss": "^4.1.11" + "yargs": "^18.0.0" + }, + "bin": { + "compile-components": "bin/compile-components" }, "devDependencies": { - "@lucide/svelte": "^0.525.0", - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", - "@tailwindcss/vite": "^4.1.11", - "@testing-library/jest-dom": "^6.6.3", + "@lucide/svelte": "^0.539.0", + "@sveltejs/vite-plugin-svelte": "^6.1.2", + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", + "@tailwindcss/vite": "^4.1.12", + "@testing-library/jest-dom": "^6.7.0", "@testing-library/svelte": "^5.2.8", "@tsconfig/svelte": "^5.0.4", - "@types/node": "^24.0.10", + "@types/node": "^24.3.0", + "@types/yargs": "^17.0.33", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", - "bits-ui": "^2.8.10", + "bits-ui": "^2.9.3", "clsx": "^2.1.1", "esbuild-plugin-cache": "^0.2.10", "esbuild-svelte": "^0.9.3", @@ -29,17 +33,18 @@ "mode-watcher": "^1.1.0", "prettier": "^3.6.2", "prettier-plugin-svelte": "^3.4.0", - "prettier-plugin-tailwindcss": "^0.6.13", - "svelte": "^5.35.1", - "svelte-check": "^4.2.2", + "prettier-plugin-tailwindcss": "^0.6.14", + "svelte": "^5.38.1", + "svelte-check": "^4.3.1", "svelte-preprocess": "^6.0.3", "svelte-sonner": "^1.0.5", "tailwind-merge": "^3.3.1", - "tailwind-variants": "^1.0.0", - "tw-animate-css": "^1.3.4", - "typescript": "~5.8.3", - "vite": "^6.3.5", - "vite-plugin-version-mark": "^0.1.4", + "tailwind-variants": "^2.1.0", + "tailwindcss": "^4.1.12", + "tw-animate-css": "^1.3.6", + "typescript": "~5.9.2", + "vite": "^7.1.5", + "vite-plugin-version-mark": "^0.2.2", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4" } @@ -795,6 +800,17 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -824,15 +840,68 @@ } }, "node_modules/@lucide/svelte": { - "version": "0.525.0", - "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.525.0.tgz", - "integrity": "sha512-dyUxkXzepagLUzL8jHQNdeH286nC66ClLACsg+Neu/bjkRJWPWMzkT+H0DKlE70QdkicGCfs1ZGmXCc351hmZA==", + "version": "0.539.0", + "resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.539.0.tgz", + "integrity": "sha512-OWhw4BhHO+owmOE/ijSNLnw/flbW2/DsLzMHAeM8oEjLsO0xE6glX0ADCDwxKItTs5ZJYssfyGNXxMXrea173w==", "dev": true, "license": "ISC", "peerDependencies": { "svelte": "^5" } }, + "node_modules/@nuxt/kit": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.0.3.tgz", + "integrity": "sha512-9+lwvP4n8KhO91azoebO0o39smESGzEV4HU6nef9HIFyt04YwlVMY37Pk63GgZn0WhWVjyPWcQWs0rUdZUYcPw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "c12": "^3.2.0", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.7", + "ignore": "^7.0.5", + "jiti": "^2.5.1", + "klona": "^2.0.6", + "mlly": "^1.7.4", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "semver": "^7.7.2", + "std-env": "^3.9.0", + "tinyglobby": "^0.2.14", + "ufo": "^1.6.1", + "unctx": "^2.4.1", + "unimport": "^5.2.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/schema": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@nuxt/schema/-/schema-4.0.3.tgz", + "integrity": "sha512-acDigyy8tF8xDCMFee00mt5u2kE5Qx5Y34ButBlibLzhguQjc+6f6FpMGdieN07oahjpegWIQG66yQywjw+sKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@vue/shared": "^3.5.18", + "consola": "^3.4.2", + "defu": "^6.1.4", + "pathe": "^2.0.3", + "std-env": "^3.9.0", + "ufo": "1.6.1" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1142,43 +1211,43 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.1.0.tgz", - "integrity": "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.1.2.tgz", + "integrity": "sha512-7v+7OkUYelC2dhhYDAgX1qO2LcGscZ18Hi5kKzJQq7tQeXpH215dd0+J/HnX2zM5B3QKcIrTVqCGkZXAy5awYw==", "dev": true, "license": "MIT", "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", - "vitefu": "^1.0.6" + "vitefu": "^1.1.1" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { "svelte": "^5.0.0", - "vite": "^6.0.0" + "vite": "^6.3.0 || ^7.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz", - "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.0.tgz", + "integrity": "sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ==", "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.3.7" + "debug": "^4.4.1" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", - "vite": "^6.0.0" + "vite": "^6.3.0 || ^7.0.0" } }, "node_modules/@swc/helpers": { @@ -1193,25 +1262,25 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.12.tgz", + "integrity": "sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.5.1", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" + "tailwindcss": "4.1.12" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.12.tgz", + "integrity": "sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -1223,24 +1292,24 @@ "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" + "@tailwindcss/oxide-android-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-arm64": "4.1.12", + "@tailwindcss/oxide-darwin-x64": "4.1.12", + "@tailwindcss/oxide-freebsd-x64": "4.1.12", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.12", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.12", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.12", + "@tailwindcss/oxide-linux-x64-musl": "4.1.12", + "@tailwindcss/oxide-wasm32-wasi": "4.1.12", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.12", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.12" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.12.tgz", + "integrity": "sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==", "cpu": [ "arm64" ], @@ -1255,9 +1324,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.12.tgz", + "integrity": "sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==", "cpu": [ "arm64" ], @@ -1272,9 +1341,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.12.tgz", + "integrity": "sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==", "cpu": [ "x64" ], @@ -1289,9 +1358,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.12.tgz", + "integrity": "sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==", "cpu": [ "x64" ], @@ -1306,9 +1375,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.12.tgz", + "integrity": "sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==", "cpu": [ "arm" ], @@ -1323,9 +1392,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.12.tgz", + "integrity": "sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==", "cpu": [ "arm64" ], @@ -1340,9 +1409,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.12.tgz", + "integrity": "sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==", "cpu": [ "arm64" ], @@ -1357,9 +1426,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.12.tgz", + "integrity": "sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==", "cpu": [ "x64" ], @@ -1374,9 +1443,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.12.tgz", + "integrity": "sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==", "cpu": [ "x64" ], @@ -1391,9 +1460,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.12.tgz", + "integrity": "sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -1409,21 +1478,81 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", + "@emnapi/core": "^1.4.5", + "@emnapi/runtime": "^1.4.5", + "@emnapi/wasi-threads": "^1.0.4", + "@napi-rs/wasm-runtime": "^0.2.12", + "@tybys/wasm-util": "^0.10.0", "tslib": "^2.8.0" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.4.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.4", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.4.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.0", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.12.tgz", + "integrity": "sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==", "cpu": [ "arm64" ], @@ -1438,9 +1567,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.12.tgz", + "integrity": "sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==", "cpu": [ "x64" ], @@ -1455,15 +1584,15 @@ } }, "node_modules/@tailwindcss/vite": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz", - "integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.12.tgz", + "integrity": "sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==", "dev": true, "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "tailwindcss": "4.1.11" + "@tailwindcss/node": "4.1.12", + "@tailwindcss/oxide": "4.1.12", + "tailwindcss": "4.1.12" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" @@ -1524,18 +1653,17 @@ "license": "MIT" }, "node_modules/@testing-library/jest-dom": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", - "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.7.0.tgz", + "integrity": "sha512-RI2e97YZ7MRa+vxP4UUnMuMFL2buSsf0ollxUbTgrbPLKhMn8KVTx7raS6DYjC7v1NDVrioOvaShxsguLNISCA==", "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", - "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.21", + "picocolors": "^1.1.1", "redent": "^3.0.0" }, "engines": { @@ -1609,13 +1737,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz", - "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.8.0" + "undici-types": "~7.10.0" } }, "node_modules/@types/node-fetch": { @@ -1629,6 +1757,23 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@vitest/coverage-v8": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", @@ -1800,6 +1945,14 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/@vue/shared": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz", + "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -1913,9 +2066,9 @@ "license": "MIT" }, "node_modules/bits-ui": { - "version": "2.8.10", - "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.8.10.tgz", - "integrity": "sha512-MOobkqapDZNrpcNmeL2g664xFmH4tZBOKBTxFmsQYMZQuybSZHQnPXy+AjM5XZEXRmCFx5+XRmo6+fC3vHh1hQ==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.9.3.tgz", + "integrity": "sha512-jSoi3U1pfhLQVKZ3j+1GbeuvT1w6cMbnrVWhObVE+DRuV+zcpKeUnd6zpz7NYF47HsSXVNjI1rJdZH+A5sNsOQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1985,6 +2138,36 @@ "balanced-match": "^1.0.0" } }, + "node_modules/c12": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/c12/-/c12-3.2.0.tgz", + "integrity": "sha512-ixkEtbYafL56E6HiFuonMm1ZjoKtIo7TH68/uiEq4DAwv9NcUX2nJ95F8TrbMeNjqIkZpruo3ojXQJ+MGG5gcQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "chokidar": "^4.0.3", + "confbox": "^0.2.2", + "defu": "^6.1.4", + "dotenv": "^17.2.1", + "exsolve": "^1.0.7", + "giget": "^2.0.0", + "jiti": "^2.5.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "perfect-debounce": "^1.0.0", + "pkg-types": "^2.2.0", + "rc9": "^2.1.2" + }, + "peerDependencies": { + "magicast": "^0.3.5" + }, + "peerDependenciesMeta": { + "magicast": { + "optional": true + } + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -2026,20 +2209,6 @@ "node": ">=12" } }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -2076,6 +2245,83 @@ "node": ">=18" } }, + "node_modules/citty": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", + "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "consola": "^3.2.3" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -2119,6 +2365,25 @@ "node": ">= 0.8" } }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2214,6 +2479,14 @@ "node": ">=0.10.0" } }, + "node_modules/defu": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2270,6 +2543,14 @@ "node": ">=6" } }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -2287,6 +2568,20 @@ "dev": true, "license": "MIT" }, + "node_modules/dotenv": { + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.1.tgz", + "integrity": "sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2317,9 +2612,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "dev": true, "license": "MIT", "dependencies": { @@ -2343,6 +2638,14 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/errx": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/errx/-/errx-0.1.0.tgz", + "integrity": "sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -2468,6 +2771,29 @@ "svelte": ">=4.2.1 <6" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/esm-env": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", @@ -2476,9 +2802,9 @@ "license": "MIT" }, "node_modules/esrap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.0.1.tgz", - "integrity": "sha512-6n1JodkxeMvyTDCog7J//t8Yti//fGicZgtFLko6h/aEpc54BK9O8k9cZgC2J8+2Dh1U5uYIxuJWSsylybvFBA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", + "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", "dev": true, "license": "MIT", "dependencies": { @@ -2505,12 +2831,23 @@ "node": ">=12.0.0" } }, + "node_modules/exsolve": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", + "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "picomatch": "^3 || ^4" }, @@ -2552,9 +2889,9 @@ } }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "license": "MIT", "dependencies": { @@ -2593,6 +2930,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -2632,6 +2990,25 @@ "node": ">= 0.4" } }, + "node_modules/giget": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", + "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.0", + "defu": "^6.1.4", + "node-fetch-native": "^1.6.6", + "nypm": "^0.6.0", + "pathe": "^2.0.3" + }, + "bin": { + "giget": "dist/cli.mjs" + } + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -2793,6 +3170,17 @@ "node": ">=0.10.0" } }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", @@ -2915,9 +3303,9 @@ } }, "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", + "integrity": "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==", "dev": true, "license": "MIT", "bin": { @@ -2981,6 +3369,25 @@ "node": ">=6" } }, + "node_modules/klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/knitwork": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/knitwork/-/knitwork-1.2.0.tgz", + "integrity": "sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/lightningcss": { "version": "1.30.1", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", @@ -3220,6 +3627,25 @@ "url": "https://opencollective.com/parcel" } }, + "node_modules/local-pkg": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", + "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mlly": "^1.7.4", + "pkg-types": "^2.0.1", + "quansync": "^0.2.8" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", @@ -3227,13 +3653,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, "node_modules/loupe": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", @@ -3394,6 +3813,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/mlly": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", + "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.14.0", + "pathe": "^2.0.1", + "pkg-types": "^1.3.0", + "ufo": "^1.5.4" + } + }, + "node_modules/mlly/node_modules/confbox": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/mlly/node_modules/pkg-types": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", + "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, "node_modules/mode-watcher": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-1.1.0.tgz", @@ -3475,6 +3929,14 @@ } } }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/node-fetch/node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -3507,6 +3969,43 @@ "dev": true, "license": "MIT" }, + "node_modules/nypm": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.1.tgz", + "integrity": "sha512-hlacBiRiv1k9hZFiphPUkfSQ/ZfQzZDzC+8z0wL3lvDAOUu/2NnChkKuMoMjNur/9OpKuz2QsIeiPVN0xM5Q0w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "citty": "^0.1.6", + "consola": "^3.4.2", + "pathe": "^2.0.3", + "pkg-types": "^2.2.0", + "tinyexec": "^1.0.1" + }, + "bin": { + "nypm": "dist/cli.mjs" + }, + "engines": { + "node": "^14.16.0 || >=16.10.0" + } + }, + "node_modules/nypm/node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ohash": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", + "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -3571,6 +4070,14 @@ "node": ">= 14.16" } }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -3579,9 +4086,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -3591,6 +4098,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/pkg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", + "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -3648,9 +4168,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.13.tgz", - "integrity": "sha512-uQ0asli1+ic8xrrSmIOaElDu0FacR4x69GynTh2oZjFY10JUt6EEumTQl5tB4fMeD6I1naKd+4rXQQ7esT2i1g==", + "version": "0.6.14", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.14.tgz", + "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", "dev": true, "license": "MIT", "engines": { @@ -3658,6 +4178,8 @@ }, "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-hermes": "*", + "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", @@ -3679,6 +4201,12 @@ "@ianvs/prettier-plugin-sort-imports": { "optional": true }, + "@prettier/plugin-hermes": { + "optional": true + }, + "@prettier/plugin-oxc": { + "optional": true + }, "@prettier/plugin-pug": { "optional": true }, @@ -3764,6 +4292,36 @@ "node": ">=6" } }, + "node_modules/quansync": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz", + "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/rc9": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", + "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "defu": "^6.1.4", + "destr": "^2.0.3" + } + }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -3895,6 +4453,14 @@ "node": ">=v12.22.7" } }, + "node_modules/scule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz", + "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/semver": { "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", @@ -4048,7 +4614,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -4078,7 +4643,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4144,13 +4708,13 @@ } }, "node_modules/svelte": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.35.1.tgz", - "integrity": "sha512-3kNMwstMB2VUBod63H6BQPzBr7NiPRR9qFVzrWqW/nU4ulqqAYZsJ6E7m8LYFoRzuW6yylx+uzdgKVhFKZVf4Q==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.38.1.tgz", + "integrity": "sha512-fO6CLDfJYWHgfo6lQwkQU2vhCiHc2MBl6s3vEhK+sSZru17YL4R5s1v14ndRpqKAIkq8nCz6MTk1yZbESZWeyQ==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", + "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", @@ -4159,7 +4723,7 @@ "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", - "esrap": "^2.0.0", + "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -4170,9 +4734,9 @@ } }, "node_modules/svelte-check": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.2.2.tgz", - "integrity": "sha512-1+31EOYZ7NKN0YDMKusav2hhEoA51GD9Ws6o//0SphMT0ve9mBTsTUEX7OmDMadUP3KjNHsSKtJrqdSaD8CrGQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.1.tgz", + "integrity": "sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg==", "dev": true, "license": "MIT", "dependencies": { @@ -4342,37 +4906,30 @@ } }, "node_modules/tailwind-variants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-1.0.0.tgz", - "integrity": "sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-2.1.0.tgz", + "integrity": "sha512-82m0eRex0z6A3GpvfoTCpHr+wWJmbecfVZfP3mqLoDxeya5tN4mYJQZwa5Aw1hRZTedwpu1D2JizYenoEdyD8w==", "dev": true, "license": "MIT", - "dependencies": { - "tailwind-merge": "3.0.2" - }, "engines": { "node": ">=16.x", "pnpm": ">=7.x" }, "peerDependencies": { + "tailwind-merge": ">=3.0.0", "tailwindcss": "*" - } - }, - "node_modules/tailwind-variants/node_modules/tailwind-merge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.0.2.tgz", - "integrity": "sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" + }, + "peerDependenciesMeta": { + "tailwind-merge": { + "optional": true + } } }, "node_modules/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.12.tgz", + "integrity": "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==", + "dev": true, "license": "MIT" }, "node_modules/tapable": { @@ -4433,14 +4990,14 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -4561,12 +5118,13 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/tw-animate-css": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.4.tgz", - "integrity": "sha512-dd1Ht6/YQHcNbq0znIT6dG8uhO7Ce+VIIhZUhjsryXsMPJQz3bZg7Q2eNzLwipb25bRZslGb2myio5mScd1TFg==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.3.6.tgz", + "integrity": "sha512-9dy0R9UsYEGmgf26L8UcHiLmSFTHa9+D7+dAt/G/sF5dCnPePZbfgDYinc7/UzAM7g/baVrmS6m9yEpU46d+LA==", "dev": true, "license": "MIT", "funding": { @@ -4574,9 +5132,9 @@ } }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4587,32 +5145,133 @@ "node": ">=14.17" } }, + "node_modules/ufo": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", + "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/unctx": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/unctx/-/unctx-2.4.1.tgz", + "integrity": "sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.14.0", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17", + "unplugin": "^2.1.0" + } + }, "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", "dev": true, "license": "MIT" }, + "node_modules/unimport": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/unimport/-/unimport-5.2.0.tgz", + "integrity": "sha512-bTuAMMOOqIAyjV4i4UH7P07pO+EsVxmhOzQ2YJ290J6mkLUdozNhb5I/YoOEheeNADC03ent3Qj07X0fWfUpmw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.15.0", + "escape-string-regexp": "^5.0.0", + "estree-walker": "^3.0.3", + "local-pkg": "^1.1.1", + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "pkg-types": "^2.2.0", + "scule": "^1.3.0", + "strip-literal": "^3.0.0", + "tinyglobby": "^0.2.14", + "unplugin": "^2.3.5", + "unplugin-utils": "^0.2.4" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.5.tgz", + "integrity": "sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.14.1", + "picomatch": "^4.0.2", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin-utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/unplugin-utils/-/unplugin-utils-0.2.5.tgz", + "integrity": "sha512-gwXJnPRewT4rT7sBi/IvxKTjsms7jX7QIDLOClApuZwR49SXbrB1z2NLUZ+vDHyqCj/n58OzRRqaW+B8OZi8vg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "pathe": "^2.0.3", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/sxzz" + } + }, + "node_modules/untyped": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/untyped/-/untyped-2.0.0.tgz", + "integrity": "sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "citty": "^0.1.6", + "defu": "^6.1.4", + "jiti": "^2.4.2", + "knitwork": "^1.2.0", + "scule": "^1.3.0" + }, + "bin": { + "untyped": "dist/cli.mjs" + } + }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", + "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -4621,14 +5280,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -4693,12 +5352,14 @@ } }, "node_modules/vite-plugin-version-mark": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/vite-plugin-version-mark/-/vite-plugin-version-mark-0.1.4.tgz", - "integrity": "sha512-0uoEWDnrH9ho4IwTzyFKosA+XnOWK7uT8WwCskPb2DVeFrCSn4sfPG7b+8l9EFWHgCx0n52iqwQEbs3w5FFzpw==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/vite-plugin-version-mark/-/vite-plugin-version-mark-0.2.2.tgz", + "integrity": "sha512-qFxfnlpK++zBX7sWdOOmRFE+Yd7G/6vZ7mJFvlEhp/vLtqMU9cN0LWX+VcfVXubnyiGTpSzt/fzoejHRyTrbIQ==", "dev": true, "license": "MIT", "peerDependencies": { + "@nuxt/kit": ">3.3.0", + "@nuxt/schema": ">3.3.0", "vite": "*" } }, @@ -4723,9 +5384,9 @@ } }, "node_modules/vitefu": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.0.tgz", - "integrity": "sha512-AiG/L9DVsEYHWQ9jAEnke0nKiASlPw+JYwDl6Z4l6a6/IqT1tKseEl6R5+rVnKJt/K3jCTWiQvgoIh5MuqBJJQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "dev": true, "license": "MIT", "workspaces": [ @@ -4838,6 +5499,14 @@ "node": ">=12" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", @@ -5032,6 +5701,15 @@ "dev": true, "license": "MIT" }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", @@ -5042,6 +5720,55 @@ "node": ">=18" } }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zimmerframe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", diff --git a/demo/package.json b/demo/package.json index 3d0cb84..37c4840 100644 --- a/demo/package.json +++ b/demo/package.json @@ -1,24 +1,29 @@ { "name": "demo", - "version": "0.0.1", + "version": "0.0.0", + "bin": { + "compile-components": "./bin/compile-components" + }, "type": "module", "scripts": { "dev": "vite", "build": "vite build", - "check": "svelte-check && tsc" + "check": "svelte-check && tsc", + "compile": "node bin/compile-components" }, "devDependencies": { - "@lucide/svelte": "^0.525.0", - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", - "@tailwindcss/vite": "^4.1.11", - "@testing-library/jest-dom": "^6.6.3", + "@lucide/svelte": "^0.539.0", + "@sveltejs/vite-plugin-svelte": "^6.1.2", + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", + "@tailwindcss/vite": "^4.1.12", + "@testing-library/jest-dom": "^6.7.0", "@testing-library/svelte": "^5.2.8", "@tsconfig/svelte": "^5.0.4", - "@types/node": "^24.0.10", + "@types/node": "^24.3.0", + "@types/yargs": "^17.0.33", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", - "bits-ui": "^2.8.10", + "bits-ui": "^2.9.3", "clsx": "^2.1.1", "esbuild-plugin-cache": "^0.2.10", "esbuild-svelte": "^0.9.3", @@ -26,21 +31,22 @@ "mode-watcher": "^1.1.0", "prettier": "^3.6.2", "prettier-plugin-svelte": "^3.4.0", - "prettier-plugin-tailwindcss": "^0.6.13", - "svelte": "^5.35.1", - "svelte-check": "^4.2.2", + "prettier-plugin-tailwindcss": "^0.6.14", + "svelte": "^5.38.1", + "svelte-check": "^4.3.1", "svelte-preprocess": "^6.0.3", "svelte-sonner": "^1.0.5", "tailwind-merge": "^3.3.1", - "tailwind-variants": "^1.0.0", - "tw-animate-css": "^1.3.4", - "typescript": "~5.8.3", - "vite": "^6.3.5", - "vite-plugin-version-mark": "^0.1.4", + "tailwind-variants": "^2.1.0", + "tailwindcss": "^4.1.12", + "tw-animate-css": "^1.3.6", + "typescript": "~5.9.2", + "vite": "^7.1.5", + "vite-plugin-version-mark": "^0.2.2", "vite-tsconfig-paths": "^5.1.4", "vitest": "^3.2.4" }, "dependencies": { - "tailwindcss": "^4.1.11" + "yargs": "^18.0.0" } } diff --git a/demo/public/entry.js b/demo/public/entry.js deleted file mode 100644 index 3ca08dd..0000000 --- a/demo/public/entry.js +++ /dev/null @@ -1,80 +0,0 @@ -// I'm compiled from entry.ts which imports simple.svelte using esbuild-svelte. - -// src/components/entry.ts -import { mount, unmount } from "svelte"; - -// src/components/simple.svelte -import "svelte/internal/disclose-version"; -import * as $ from "svelte/internal/client"; -var on_click = (_, testState) => $.update(testState); -var root = $.from_html( - ` - -
-
-

Simple Component

-

This is a simple component that is rendered on the receiving side.
See the source code for more details.

-
-
- \`name\` from $props(): - -
-
- testState: - -
- -
`, - 1 -); -function Simple($$anchor, $$props) { - "use strict"; - let testState = $.state(1); - $.next(); - var fragment = root(); - var div = $.sibling($.first_child(fragment)); - var div_1 = $.sibling($.child(div), 3); - var span = $.sibling($.child(div_1), 3); - var text = $.child(span); - $.reset(span); - $.next(); - $.reset(div_1); - var div_2 = $.sibling(div_1, 2); - var span_1 = $.sibling($.child(div_2), 3); - var text_1 = $.child(span_1, true); - $.reset(span_1); - $.next(); - $.reset(div_2); - var button = $.sibling(div_2, 2); - button.__click = [on_click, testState]; - $.next(); - $.reset(div); - $.template_effect(() => { - $.set_text(text, `"${$$props.name ?? ""}"`); - $.set_text(text_1, $.get(testState)); - }); - $.append($$anchor, fragment); -} -$.delegate(["click"]); - -// src/components/entry.ts -var factory = (target, props) => { - const component = mount(Simple, { - target, - props - }); - return { - component, - name: "Simple", - props, - destroy: () => { - console.log("entry.ts -> simple.svelte", "destroying component", component); - unmount(component); - } - }; -}; -export { - factory as default -}; diff --git a/demo/src/components/entry.ts b/demo/shared-components/simple/entry.ts similarity index 100% rename from demo/src/components/entry.ts rename to demo/shared-components/simple/entry.ts diff --git a/demo/shared-components/simple/simple.js b/demo/shared-components/simple/simple.js new file mode 100644 index 0000000..90d35c9 --- /dev/null +++ b/demo/shared-components/simple/simple.js @@ -0,0 +1,87 @@ +"use strict"; +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] + }) : x)(function(x) { + if (typeof require !== "undefined") return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); + }); + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + + // demo/shared-components/simple/simple.svelte + var import_disclose_version = __require("svelte/internal/disclose-version"); + var $ = __toESM(__require("svelte/internal/client")); + var on_click = (_, testState) => $.update(testState); + var root = $.from_html( + ` + +
+
+

Simple.svelte

+

This is a simple component that is rendered on the receiving side.
See the source code for more details.

+
+
+ \`name\` from $props(): + +
+
+ testState: + +
+ +
`, + 1 + ); + function Simple($$anchor, $$props) { + "use strict"; + let testState = $.state(1); + $.next(); + var fragment = root(); + var div = $.sibling($.first_child(fragment)); + var div_1 = $.sibling($.child(div), 3); + var span = $.sibling($.child(div_1), 3); + var text = $.child(span); + $.reset(span); + $.next(); + $.reset(div_1); + var div_2 = $.sibling(div_1, 2); + var span_1 = $.sibling($.child(div_2), 3); + var text_1 = $.child(span_1, true); + $.reset(span_1); + $.next(); + $.reset(div_2); + var button = $.sibling(div_2, 2); + button.__click = [on_click, testState]; + $.next(); + $.reset(div); + $.template_effect(() => { + $.set_text(text, `"${$$props.name ?? ""}"`); + $.set_text(text_1, $.get(testState)); + }); + $.append($$anchor, fragment); + } + $.delegate(["click"]); +})(); diff --git a/demo/shared-components/simple/simple.svelte b/demo/shared-components/simple/simple.svelte new file mode 100644 index 0000000..84f640a --- /dev/null +++ b/demo/shared-components/simple/simple.svelte @@ -0,0 +1,22 @@ + + +
+
+

Simple.svelte

+

This is a simple component that is rendered on the receiving side.
See the source code for more details.

+
+
+ `name` from $props(): + "{name}" +
+
+ testState: + {testState} +
+ +
diff --git a/demo/src/app.svelte b/demo/src/app.svelte index 6ddf03e..aa731d6 100644 --- a/demo/src/app.svelte +++ b/demo/src/app.svelte @@ -1,186 +1,100 @@ -{#snippet loading()} -
-
-
Compiling component...
+
+
+ +
-{/snippet} - -{#snippet pkg()} - {@const version = getVersion()} - - -{/snippet} - -
-
-
-
Svelte Dynamic Component Engine
- - - Live Demo - -
-

This demo shows how to use the Svelte Dynamic Component Engine to render a component at runtime in the browser using Svelte 5.

-
- - - - - - - {@render pkg()} -
-
-
-
-
-
- - Rendered Component -
- -
-
- -
- {#if isLoading} - {@render loading()} - {/if} -
-
-
-
-

🚀 Load + Render:

-

{loadTime.toFixed(2)}ms

+
+
-
-
- - Source Code -
-
- {#if isLoading} - {@render loading()} - {:else} -
{sourceText}
- {/if} -
-
-
- - +
diff --git a/demo/src/components/entry.js b/demo/src/components/entry.js deleted file mode 100644 index 1d4518c..0000000 --- a/demo/src/components/entry.js +++ /dev/null @@ -1,35 +0,0 @@ -import { mount, unmount } from "svelte"; -import Simple from "./simple.svelte"; -/** - * The factory function is used to create a new instance of the component - * when being rendered on the receiving side. - * - * This is important because it allows us to have granular control over the component - * lifecycle and not require the receiving side to bear that burden. - * - * @param {HTMLElement} target The target element to mount the component on. - * @param {SimpleProps} props The props to pass to the component. - * - * @returns {Rendered} A Rendered object that contains the component, name, props, and destroy function. - */ -const factory = (target, props) => { - const component = mount(Simple, { - target, - props: props - }); - return { - component, - name: "Simple", - props: props, - destroy: () => { - console.log("entry.ts -> simple.svelte", "destroying component", component); - unmount(component); - } - }; -}; -/** - * Export the factory function as the default export to make it easier - * on the receiving side performing the dynamic import. - */ -export { factory as default }; -//# sourceMappingURL=entry.js.map \ No newline at end of file diff --git a/demo/src/components/entry.js.map b/demo/src/components/entry.js.map deleted file mode 100644 index 2909901..0000000 --- a/demo/src/components/entry.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"entry.js","sourceRoot":"","sources":["entry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAuB,MAAM,QAAQ,CAAC;AAC7D,OAAO,MAAM,MAAM,iBAAiB,CAAC;AAQrC;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,GAAG,CAAC,MAAmB,EAAE,KAAmB,EAAyB,EAAE;IAClF,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE;QAC9B,MAAM;QACN,KAAK,EAAE,KAAoB;KAC5B,CAAC,CAAC;IAEH,OAAO;QACL,SAAS;QACT,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,KAAoB;QAC3B,OAAO,EAAE,GAAG,EAAE;YACZ,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAC;YAC5E,OAAO,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,CAAC"} \ No newline at end of file diff --git a/demo/src/components/index.js b/demo/src/components/index.js deleted file mode 100644 index 5035086..0000000 --- a/demo/src/components/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./entry"; -export { default as Simple } from "./simple.svelte"; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/demo/src/components/index.js.map b/demo/src/components/index.js.map deleted file mode 100644 index 1e91985..0000000 --- a/demo/src/components/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC"} \ No newline at end of file diff --git a/demo/src/components/index.ts b/demo/src/components/index.ts deleted file mode 100644 index d7f5885..0000000 --- a/demo/src/components/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./entry"; -export { default as Simple } from "./simple.svelte"; diff --git a/demo/src/components/simple.svelte b/demo/src/components/simple.svelte deleted file mode 100644 index a572aa2..0000000 --- a/demo/src/components/simple.svelte +++ /dev/null @@ -1,22 +0,0 @@ - - -
-
-

Simple Component

-

This is a simple component that is rendered on the receiving side.
See the source code for more details.

-
-
- `name` from $props(): - "{name}" -
-
- testState: - {testState} -
- -
diff --git a/demo/src/extras/hooks/use-clipboard.svelte.ts b/demo/src/extras/hooks/use-clipboard.svelte.ts deleted file mode 100644 index 3bcad7c..0000000 --- a/demo/src/extras/hooks/use-clipboard.svelte.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* - Installed from @ieedan/shadcn-svelte-extras -*/ - -type Options = { - /** The time before the copied status is reset. */ - delay: number; -}; - -/** Use this hook to copy text to the clipboard and show a copied state. - * - * ## Usage - * ```svelte - * - * - * - * ``` - * - */ -export class UseClipboard { - #copiedStatus = $state<"success" | "failure">(); - private delay: number; - private timeout: ReturnType | undefined = undefined; - - constructor({ delay = 500 }: Partial = {}) { - this.delay = delay; - } - - /** Copies the given text to the users clipboard. - * - * ## Usage - * ```ts - * clipboard.copy('Hello, World!'); - * ``` - * - * @param text - * @returns - */ - async copy(text: string) { - if (this.timeout) { - this.#copiedStatus = undefined; - clearTimeout(this.timeout); - } - - try { - await navigator.clipboard.writeText(text); - - this.#copiedStatus = "success"; - - this.timeout = setTimeout(() => { - this.#copiedStatus = undefined; - }, this.delay); - } catch { - // an error can occur when not in the browser or if the user hasn't given clipboard access - this.#copiedStatus = "failure"; - - this.timeout = setTimeout(() => { - this.#copiedStatus = undefined; - }, this.delay); - } - - return this.#copiedStatus; - } - - /** true when the user has just copied to the clipboard. */ - get copied() { - return this.#copiedStatus === "success"; - } - - /** Indicates whether a copy has occurred - * and gives a status of either `success` or `failure`. */ - get status() { - return this.#copiedStatus; - } -} diff --git a/demo/src/extras/ui/button/button.svelte b/demo/src/extras/ui/button/button.svelte deleted file mode 100644 index b78cc58..0000000 --- a/demo/src/extras/ui/button/button.svelte +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - { - onclick?.(e); - - if (type === undefined) return; - - if (onClickPromise) { - loading = true; - - await onClickPromise(e); - - loading = false; - } - }}> - {#if type !== undefined && loading} -
-
- -
-
- Loading - {/if} - {@render children?.()} -
diff --git a/demo/src/extras/ui/button/index.ts b/demo/src/extras/ui/button/index.ts deleted file mode 100644 index bd53eb3..0000000 --- a/demo/src/extras/ui/button/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - Installed from @ieedan/shadcn-svelte-extras -*/ - -import Root, { type ButtonProps, type ButtonSize, type ButtonVariant, type AnchorElementProps, type ButtonElementProps, type ButtonPropsWithoutHTML, buttonVariants } from "./button.svelte"; - -export { - Root, - type ButtonProps as Props, - // - Root as Button, - buttonVariants, - type ButtonProps, - type ButtonSize, - type ButtonVariant, - type AnchorElementProps, - type ButtonElementProps, - type ButtonPropsWithoutHTML -}; diff --git a/demo/src/extras/ui/copy-button/copy-button.svelte b/demo/src/extras/ui/copy-button/copy-button.svelte deleted file mode 100644 index 7ca761e..0000000 --- a/demo/src/extras/ui/copy-button/copy-button.svelte +++ /dev/null @@ -1,58 +0,0 @@ - - - - - diff --git a/demo/src/extras/ui/copy-button/index.ts b/demo/src/extras/ui/copy-button/index.ts deleted file mode 100644 index 20047fa..0000000 --- a/demo/src/extras/ui/copy-button/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* - Installed from @ieedan/shadcn-svelte-extras -*/ - -import CopyButton from "./copy-button.svelte"; - -export { CopyButton }; diff --git a/demo/src/extras/ui/copy-button/types.ts b/demo/src/extras/ui/copy-button/types.ts deleted file mode 100644 index 7683a1d..0000000 --- a/demo/src/extras/ui/copy-button/types.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - Installed from @ieedan/shadcn-svelte-extras -*/ - -import type { Snippet } from "svelte"; -import type { ButtonPropsWithoutHTML } from "../button"; -import type { UseClipboard } from "../../hooks/use-clipboard.svelte"; -import type { HTMLAttributes } from "svelte/elements"; -import type { WithChildren, WithoutChildren } from "bits-ui"; - -export type CopyButtonPropsWithoutHTML = WithChildren< - Pick & { - ref?: HTMLButtonElement | null; - text: string; - icon?: Snippet<[]>; - animationDuration?: number; - onCopy?: (status: UseClipboard["status"]) => void; - } ->; - -export type CopyButtonProps = CopyButtonPropsWithoutHTML & WithoutChildren>; diff --git a/demo/src/extras/utils/utils.ts b/demo/src/extras/utils/utils.ts deleted file mode 100644 index 1ff3140..0000000 --- a/demo/src/extras/utils/utils.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - Installed from @ieedan/shadcn-svelte-extras -*/ - -import { type ClassValue, clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type WithoutChild = T extends { child?: any } ? Omit : T; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export type WithoutChildren = T extends { children?: any } ? Omit : T; -export type WithoutChildrenOrChild = WithoutChildren>; -export type WithElementRef = T & { ref?: U | null }; diff --git a/demo/src/global.d.ts b/demo/src/global.d.ts new file mode 100644 index 0000000..766ac9d --- /dev/null +++ b/demo/src/global.d.ts @@ -0,0 +1,7 @@ +import type { Version } from "./lib/version/types"; + +declare global { + const __VERSION__: Version | undefined; +} + +export {}; diff --git a/demo/src/lib/clipboard.ts b/demo/src/lib/clipboard.ts new file mode 100644 index 0000000..c3d2a07 --- /dev/null +++ b/demo/src/lib/clipboard.ts @@ -0,0 +1,115 @@ +// src/lib/actions/clipboard.ts + +import type { Attachment } from "svelte/attachments"; + +export type ClipboardStatus = "idle" | "success" | "failure"; + +export interface ClipboardOptions { + /** The time in milliseconds before the status resets to idle (default: 2000) */ + delay?: number; + /** Callback when copy succeeds */ + onSuccess?: (text: string) => void; + /** Callback when copy fails */ + onFailure?: (error: Error) => void; + /** Callback when status changes */ + onStatusChange?: (status: ClipboardStatus) => void; +} + +interface ClipboardState { + status: ClipboardStatus; + timeout?: ReturnType; +} + +/** + * Svelte 5 attachment action for copying text to clipboard + * + * @example + * ```svelte + * + * + * + * ``` + */ +export const clipboard = (value: any, options: ClipboardOptions): Attachment => { + return (node: HTMLElement) => { + const state: ClipboardState = { + status: "idle", + timeout: undefined + }; + + const updateStatus = (newStatus: ClipboardStatus) => { + state.status = newStatus; + options.onStatusChange?.(newStatus); + }; + + const resetStatus = () => { + if (state.timeout) { + clearTimeout(state.timeout); + state.timeout = undefined; + } + + const delay = options.delay ?? 2000; + + state.timeout = setTimeout(() => { + updateStatus("idle"); + state.timeout = undefined; + }, delay); + }; + + const handleClick = async (event: MouseEvent) => { + // Prevent default if it's a button inside a form + if (node.tagName === "BUTTON" && node.closest("form")) { + event.preventDefault(); + } + + // Clear any existing timeout + if (state.timeout) { + clearTimeout(state.timeout); + state.timeout = undefined; + } + + try { + await navigator.clipboard.writeText(value); + updateStatus("success"); + options.onSuccess?.(value); + resetStatus(); + } catch (error) { + const err = error instanceof Error ? error : new Error("Failed to copy to clipboard"); + updateStatus("failure"); + options.onFailure?.(err); + resetStatus(); + } + }; + + // Add click listener + node.addEventListener("click", handleClick); + + // Add appropriate ARIA attributes + node.setAttribute("role", "button"); + node.setAttribute("aria-label", "Copy to clipboard"); + + // Add cursor style if not already set + if (!node.style.cursor) { + node.style.cursor = "pointer"; + } + + return () => { + if (state.timeout) { + clearTimeout(state.timeout); + } + node.removeEventListener("click", handleClick); + node.removeAttribute("role"); + node.removeAttribute("aria-label"); + }; + }; +}; diff --git a/demo/src/lib/components/ui/button/index.js b/demo/src/lib/components/ui/button/index.js deleted file mode 100644 index e727484..0000000 --- a/demo/src/lib/components/ui/button/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import Root, { buttonVariants, } from "./button.svelte"; -export { Root, -// -Root as Button, buttonVariants, }; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/demo/src/lib/components/ui/button/index.js.map b/demo/src/lib/components/ui/button/index.js.map deleted file mode 100644 index 9d6e764..0000000 --- a/demo/src/lib/components/ui/button/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAIZ,cAAc,GACd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,IAAI;AAEJ,EAAE;AACF,IAAI,IAAI,MAAM,EACd,cAAc,GAId,CAAC"} \ No newline at end of file diff --git a/demo/src/lib/components/ui/sonner/index.js b/demo/src/lib/components/ui/sonner/index.js deleted file mode 100644 index 55afb49..0000000 --- a/demo/src/lib/components/ui/sonner/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Toaster } from "./sonner.svelte"; -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/demo/src/lib/components/ui/sonner/index.js.map b/demo/src/lib/components/ui/sonner/index.js.map deleted file mode 100644 index 2a11a9e..0000000 --- a/demo/src/lib/components/ui/sonner/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAC"} \ No newline at end of file diff --git a/src/lib/logger.ts b/demo/src/lib/logger.ts similarity index 100% rename from src/lib/logger.ts rename to demo/src/lib/logger.ts diff --git a/demo/src/lib/utils.js b/demo/src/lib/utils.js deleted file mode 100644 index ad49281..0000000 --- a/demo/src/lib/utils.js +++ /dev/null @@ -1,6 +0,0 @@ -import { clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; -export function cn(...inputs) { - return twMerge(clsx(inputs)); -} -//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/demo/src/lib/utils.js.map b/demo/src/lib/utils.js.map deleted file mode 100644 index 84cf4e1..0000000 --- a/demo/src/lib/utils.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACzC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC9B,CAAC"} \ No newline at end of file diff --git a/demo/src/lib/version/browser.ts b/demo/src/lib/version/browser.ts new file mode 100644 index 0000000..a56e3d8 --- /dev/null +++ b/demo/src/lib/version/browser.ts @@ -0,0 +1,48 @@ +import type { Version } from "./types"; +import type { VersionConfig } from "./vite-plugin-version"; + +declare const __VERSION__: Version | undefined; + +export const getVersion = (config?: VersionConfig): Version => { + if (config?.debug) { + console.log("getVersion()", "checking available version sources"); + } + + if (typeof __VERSION__ !== "undefined") { + if (config?.debug) { + console.log("getVersion()", "Found __VERSION__ from build-time replacement:", __VERSION__); + } + return __VERSION__; + } + + if (import.meta.env.VITE_VERSION) { + try { + const parsed = JSON.parse(import.meta.env.VITE_VERSION as string); + if (config?.debug) { + console.log("getVersion()", "Found VITE_VERSION from import.meta.env:", parsed); + } + return parsed; + } catch (e) { + console.error("getVersion()", "Failed to parse VITE_VERSION:", e); + } + } + + // Fallback + if (config?.debug) { + console.error("getVersion()", "no version information available"); + } + return { + location: null, + tag: "unknown", + commit: { + long: "unknown", + short: "unknown" + }, + dirty: true, + branch: "unknown", + date: { + actual: new Date(1970, 1, 1), + human: "unknown" + } + }; +}; diff --git a/demo/src/lib/version/exec.ts b/demo/src/lib/version/exec.ts new file mode 100644 index 0000000..65ac7c9 --- /dev/null +++ b/demo/src/lib/version/exec.ts @@ -0,0 +1,23 @@ +import { spawnSync } from "node:child_process"; + +export const exec = ( + command: string +): { + output: string; + status: number | null; +} => { + const result = spawnSync(command, { + cwd: process.cwd(), + shell: true + }); + if (result.status !== 0) { + return { + output: result.stderr.toString().trim(), + status: result.status + }; + } + return { + output: result.stdout.toString().trim(), + status: result.status + }; +}; diff --git a/demo/src/lib/version/git.ts b/demo/src/lib/version/git.ts new file mode 100644 index 0000000..24b5515 --- /dev/null +++ b/demo/src/lib/version/git.ts @@ -0,0 +1,58 @@ +import { exec } from "./exec"; +import type { Version } from "./types"; + +export type GitLookup = "tag" | "commit" | "branch" | "dirty" | "date"; + +export const git = { + status: () => exec("git status")?.output, + tag: () => exec("git describe --tags --abbrev=0")?.output, + fetch: () => exec("git fetch --all -v ")?.output, + log: () => exec("git log --graph -10 --branches --remotes --tags --format=format:'%Cgreen%h %Creset• %s (%cN, %cr) %Cred%d' --date-order")?.output, + date: () => exec("git log -1 --format=%cd")?.output, + commit: { + long: () => exec("git rev-parse HEAD")?.output, + short: () => exec("git rev-parse --short HEAD")?.output + }, + branch: () => exec("git rev-parse --abbrev-ref HEAD")?.output, + dirty: () => exec("git diff --quiet")?.status !== 0, + lookup: (lookups: GitLookup[]): Version => { + for (const lookup of lookups) { + switch (lookup) { + case "tag": + return { + location: "git-tag", + tag: git.tag() + }; + case "commit": + return { + location: "git-commit", + commit: { + long: git.commit.long() ?? "unknown", + short: git.commit.short() ?? "unknown" + } + }; + case "branch": + return { + location: "git-branch", + branch: git.branch() ?? "unknown" + }; + case "dirty": + return { + location: "git-dirty", + dirty: git.dirty() + }; + case "date": + return { + location: "git-date", + date: { + actual: new Date(git.date() ?? "unknown"), + human: git.date() ?? "unknown" + } + }; + + default: + throw new Error(`Unknown git lookup: ${lookup}`); + } + } + } +}; diff --git a/demo/src/lib/version/index.ts b/demo/src/lib/version/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/demo/src/lib/version/types.ts b/demo/src/lib/version/types.ts new file mode 100644 index 0000000..1b88519 --- /dev/null +++ b/demo/src/lib/version/types.ts @@ -0,0 +1,16 @@ +import type { VersionLocation } from "./vite-plugin-version"; + +export type Version = { + location: VersionLocation; + tag?: string; + commit?: { + long: string; + short: string; + }; + dirty?: boolean; + branch?: string; + date?: { + actual: Date; + human: string; + }; +}; diff --git a/demo/src/lib/version/version.ts b/demo/src/lib/version/version.ts new file mode 100644 index 0000000..6baa9a0 --- /dev/null +++ b/demo/src/lib/version/version.ts @@ -0,0 +1,47 @@ +import fs from "node:fs"; +import { git } from "./git"; +import type { Version } from "./types"; +import type { VersionConfig } from "./vite-plugin-version"; + +export const ago = (date: Date, locale = "en"): string => { + const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" }); + + const now = new Date(); + const diff = (date.getTime() - now.getTime()) / 1000; + + const units: [Intl.RelativeTimeFormatUnit, number][] = [ + ["year", diff / (60 * 60 * 24 * 365)], + ["month", diff / (60 * 60 * 24 * 30)], + ["week", diff / (60 * 60 * 24 * 7)], + ["day", diff / (60 * 60 * 24)], + ["hour", diff / (60 * 60)], + ["minute", diff / 60], + ["second", diff] + ]; + + for (const [unit, value] of units) { + const rounded = Math.round(value); + if (Math.abs(rounded) >= 1) { + return rtf.format(rounded, unit); + } + } + + return rtf.format(0, "second"); +}; + +export const setVersion = (config?: VersionConfig): Version => { + for (const location of config?.locations ?? ["git-tag", "package.json"]) { + if (location === "git-tag") { + return { + location: "git-tag", + tag: git.tag() + }; + } else if (location === "package.json") { + const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); + return { + location: "package.json", + tag: pkg.version + }; + } + } +}; diff --git a/demo/src/lib/version/vite-plugin-version.ts b/demo/src/lib/version/vite-plugin-version.ts new file mode 100644 index 0000000..1b3677c --- /dev/null +++ b/demo/src/lib/version/vite-plugin-version.ts @@ -0,0 +1,62 @@ +import { setVersion } from "./version"; + +export type VersionLocation = "git-tag" | "git-commit" | "git-branch" | "git-dirty" | "git-date" | "package.json"; + +export interface VersionConfig { + debug?: boolean; + /** + * The locations to check for version information. + * + * The order is important, the first location that is found will be used + * otherwise the next (fallback) location will be used. + * + * @default ["git-tag", "package.json"] + */ + locations?: VersionLocation[]; +} + +/** + * This plugin is used to set the version of the application. + * + * @param {VersionConfig} pluginConfig The plugin configuration. + * + * @returns {any} The plugin option. + * + * @example + * ```ts + * import { versionPlugin } from "vite-plugin-version"; + * + * export default defineConfig({ + * plugins: [versionPlugin()] + * }); + * ``` + */ +export const versionPlugin = (pluginConfig?: VersionConfig): any => { + const versionData = setVersion(pluginConfig); + const versionString = JSON.stringify(versionData); + + return { + name: "version-plugin", + config(config: any) { + if (pluginConfig?.debug) { + console.log("versionPlugin.config() versionData:", versionData); + } + + // Merge with existing define config: + config.define = { + ...config.define, + // This will replace __VERSION__ in the code at build time: + __VERSION__: versionString + }; + + // For import.meta.env.VITE_VERSION access: + process.env.VITE_VERSION = versionString; + + if (pluginConfig?.debug) { + console.log("versionPlugin.config() config.define:", config.define); + } + + return config; + } + }; +}; diff --git a/demo/src/main.js b/demo/src/main.js deleted file mode 100644 index ba7e77c..0000000 --- a/demo/src/main.js +++ /dev/null @@ -1,8 +0,0 @@ -import { mount } from "svelte"; -import "./app.css"; -import App from "./app.svelte"; -const app = mount(App, { - target: document.getElementById("app") -}); -export default app; -//# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/demo/src/main.js.map b/demo/src/main.js.map deleted file mode 100644 index 7fa5f21..0000000 --- a/demo/src/main.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,WAAW,CAAC;AACnB,OAAO,GAAG,MAAM,cAAc,CAAC;AAE/B,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE;IACrB,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAE;CACxC,CAAC,CAAC;AAEH,eAAe,GAAG,CAAC"} \ No newline at end of file diff --git a/demo/src/test-setup.js b/demo/src/test-setup.js deleted file mode 100644 index e7e0b07..0000000 --- a/demo/src/test-setup.js +++ /dev/null @@ -1,33 +0,0 @@ -import "@testing-library/jest-dom"; -import { vi } from "vitest"; -// Mock URL.createObjectURL and URL.revokeObjectURL for tests -globalThis.URL.createObjectURL = vi.fn(() => "blob:test-url"); -globalThis.URL.revokeObjectURL = vi.fn(); -// Mock console methods to reduce test noise -globalThis.console = Object.assign(Object.assign({}, console), { warn: vi.fn(), error: vi.fn() }); -// Setup DOM environment -Object.defineProperty(window, "location", { - value: { - href: "http://localhost:3000" - }, - writable: true -}); -// Create a mock component class for testing -export class MockSvelteComponent { - constructor({ target, props }) { - this.target = target; - this.props = props; - this.render(); - } - render() { - if (this.target) { - this.target.innerHTML = "
Mock Dynamic Component
"; - } - } - $destroy() { - if (this.target) { - this.target.innerHTML = ""; - } - } -} -//# sourceMappingURL=test-setup.js.map \ No newline at end of file diff --git a/demo/src/test-setup.js.map b/demo/src/test-setup.js.map deleted file mode 100644 index 039759f..0000000 --- a/demo/src/test-setup.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"test-setup.js","sourceRoot":"","sources":["test-setup.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC;AACnC,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE5B,6DAA6D;AAC7D,UAAU,CAAC,GAAG,CAAC,eAAe,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;AAC9D,UAAU,CAAC,GAAG,CAAC,eAAe,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAEzC,4CAA4C;AAC5C,UAAU,CAAC,OAAO,mCACb,OAAO,KACV,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,GACf,CAAC;AAEF,wBAAwB;AACxB,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE;IACxC,KAAK,EAAE;QACL,IAAI,EAAE,uBAAuB;KAC9B;IACD,QAAQ,EAAE,IAAI;CACf,CAAC,CAAC;AAEH,4CAA4C;AAC5C,MAAM,OAAO,mBAAmB;IAI9B,YAAY,EAAE,MAAM,EAAE,KAAK,EAAwC;QACjE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;IAED,MAAM;QACJ,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,mCAAmC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,QAAQ;QACN,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;QAC7B,CAAC;IACH,CAAC;CACF"} \ No newline at end of file diff --git a/demo/src/test-setup.ts b/demo/src/test-setup.ts index fabd443..6710c5b 100644 --- a/demo/src/test-setup.ts +++ b/demo/src/test-setup.ts @@ -1,18 +1,24 @@ import "@testing-library/jest-dom"; import { vi } from "vitest"; -// Mock URL.createObjectURL and URL.revokeObjectURL for tests +/** + * Mock URL.createObjectURL and URL.revokeObjectURL for tests. + */ globalThis.URL.createObjectURL = vi.fn(() => "blob:test-url"); globalThis.URL.revokeObjectURL = vi.fn(); -// Mock console methods to reduce test noise +/** + * Mock console methods to reduce test noise. + */ globalThis.console = { ...console, warn: vi.fn(), error: vi.fn() }; -// Setup DOM environment +/** + * Setup DOM environment. + */ Object.defineProperty(window, "location", { value: { href: "http://localhost:3000" @@ -20,7 +26,9 @@ Object.defineProperty(window, "location", { writable: true }); -// Create a mock component class for testing +/** + * Create a mock component class for testing. + */ export class MockSvelteComponent { public target: HTMLElement; public props: any; diff --git a/demo/src/vite-env.d.ts b/demo/src/vite-env.d.ts index e69c825..ddd6bdf 100644 --- a/demo/src/vite-env.d.ts +++ b/demo/src/vite-env.d.ts @@ -1,11 +1,5 @@ -/// /// -interface ViteTypeOptions { - // By adding this line, you can make the type of ImportMetaEnv strict - // to disallow unknown keys. - // strictImportMetaEnv: unknown -} interface ImportMetaEnv { - readonly CURRENT_VERSION: Version; + readonly VITE_VERSION: string; // JSON stringified Version object from my plugin. } diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 2652022..0c91dd4 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -2,16 +2,8 @@ "compilerOptions": { "module": "esnext", "moduleResolution": "bundler", - "target": "es2023", - /** - Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript - to enforce using `import type` instead of `import` for Types. - */ + "target": "es2022", "verbatimModuleSyntax": true, - /** - To have warnings/errors of the Svelte compiler at the correct position, - enable source maps by default. - */ "sourceMap": true, "strict": true, "strictNullChecks": false, @@ -19,11 +11,11 @@ "skipLibCheck": true, "paths": { "@mateothegreat/dynamic-component-engine": ["../src/index.ts"], + "@mateothegreat/dynamic-component-engine/compiler": ["../src/compiler/index.ts"], "$lib": ["./src/lib"], "$lib/*": ["./src/lib/*"], "$components/*": ["./src/lib/components/ui/*"] } }, - "include": ["./src/**/*.ts", "./src/**/*.js", "./src/**/*.svelte"], - "exclude": ["src/lib/components/ui"] + "include": ["./src/**/*.ts", "./src/**/*.svelte", "./src/**/*.svelte.ts"] } diff --git a/demo/vercel.json b/demo/vercel.json new file mode 100644 index 0000000..066f3ec --- /dev/null +++ b/demo/vercel.json @@ -0,0 +1,6 @@ +{ + "routes": [{ "src": "/[^.]+", "dest": "/", "status": 200 }], + "github": { + "enabled": true + } +} diff --git a/demo/vite.config.ts b/demo/vite.config.ts index 9db975d..c2067cd 100644 --- a/demo/vite.config.ts +++ b/demo/vite.config.ts @@ -4,10 +4,14 @@ import tailwindcss from "@tailwindcss/vite"; import path from "path"; import { defineConfig } from "vite"; import tsconfigPaths from "vite-tsconfig-paths"; -import versionPlugin from "../vite-plugin-version"; +import { versionPlugin } from "./src/lib/version/vite-plugin-version"; export default defineConfig({ + logLevel: "info", plugins: [ + versionPlugin({ + locations: ["package.json"] + }), tsconfigPaths(), svelte(), svelteInspector({ @@ -15,20 +19,11 @@ export default defineConfig({ showToggleButton: "always", toggleButtonPos: "bottom-left" }), - versionPlugin(), - /** - * This sets it so that when you change a file, the whole page will reload - * rather than hmr only reloading the changes. - */ - // { - // name: "full-reload", - // handleHotUpdate({ server }) { - // server.ws.send({ type: "full-reload" }); - // return []; - // } - // }, tailwindcss() ], + build: { + reportCompressedSize: true + }, resolve: { alias: { "@mateothegreat/dynamic-component-engine": path.resolve(__dirname, "../src/index.ts"), diff --git a/docs/reactivity.md b/docs/reactivity.md new file mode 100644 index 0000000..6681535 --- /dev/null +++ b/docs/reactivity.md @@ -0,0 +1,134 @@ +# Rune-Based Reactive State Sharing Problem Statement + +The problem arises when Svelte 5 runes create reactive references that lose their reactivity when serialized across compilation boundaries. + +## The Core Issue + +When we have `let count = $state(123)` in our parent component, we're creating a reactive reference. + +However, when we try to pass this to a dynamically compiled component, several things break the reactivity chain: + +### 1. **Value** vs **Reference** Passing + +Parent component: + +```ts +let count = $state(123); +``` + +What you're actually passing to the dynamic component: + +```ts +const props = { count }; // This passes the VALUE (123), not the reactive reference +``` + +The `$state(123)` creates a reactive proxy/reference, but when you put count in the props object, you're passing the current value (`123`), not the reactive reference itself. + +### 2. Compilation Boundary Isolation + +Parent component (compiled at build time): + +```ts +let count = $state(123); +``` + +Dynamic component (compiled at runtime): + +```ts +let { count } = $props(); // This creates a NEW local variable, disconnected from parent +``` + +Each Svelte compilation creates its own reactive scope. The dynamically compiled component has no knowledge of the parent's reactive system - **it's essentially a _separate_ "universe" of reactivity**. + +### 3. Svelte's Internal Reactivity System + +Svelte 5 runes work through: + ++ Reactive proxies that track dependencies. ++ Effect scheduling that runs when dependencies change. ++ Component boundaries that isolate reactive scopes + +When you pass count as a prop, the dynamic component receives a **snapshot** _value_, **not** a reactive subscription. + +### 4. The Mount/Unmount API Limitation + +```ts +const component = mount(DynamicComponent, { target, props: { count: 123 } }); +``` + +Svelte's `mount()` API expects static props at mount time. It doesn't have a built-in mechanism to pass ongoing reactive references that update the component after mounting. + +### Why The Original Approach Didn't Work + +Parent component: + +```ts +let count = $state(123); +``` + +Dynamic component template: + +```ts +let { count = $bindable(0) } = $props(); +``` + +This creates two separate reactive variables with the same name but no connection between them. + +The `$bindable()` in the dynamic component creates its own reactive reference, completely isolated from the parent's `$state()`. + +### The Real Solution Would Require + +1) Passing reactive references (not values) across compilation boundaries. +2) Shared reactive context that both components can access. +3) Live prop updates after component mounting. +4) Cross-compilation reactive dependency tracking. + +This is why the `SharedRuneStore` solution works (see [/src/shared-rune-store.ts](../src/shared-rune-store.ts)) - it creates a shared reactive context that both the parent and dynamic components can subscribe to, bypassing the compilation boundary limitations. + +## Potential Solutions + +### Solution 1: Reactive Context Injection + +Modify the factory function to accept reactive context objects that get injected into the component's compilation scope. + +Instead of passing static values, pass rune references directly through the compilation process. + +**Approach**: + ++ Extend `ComponentCompiler.render()` to accept a reactiveContext parameter containing rune objects. ++ Modify transformCompiledCode() to inject these runes as imports/globals in the compiled component. ++ The dynamic component accesses parent runes directly via injected context. + +### Solution 2: Rune Reference Passing + +Create a mechanism to pass actual rune references (not their values) through the mount system by + +serializing rune getters/setters and reconstructing them in the dynamic component. + +**Approach**: + ++ Extend the factory function to accept rune descriptors `({ get: () => value, set: (v) => {...} })`. ++ Transform the compiled code to wire these descriptors to local rune state. ++ Dynamic components get direct access to parent runes through the descriptor interface. + +### Solution 3: Shared Rune Store + +Implement a global rune store that both parent and dynamic components can subscribe to, using Svelte 5's $state() with a singleton pattern. + +**Approach**: + ++ Create a `SharedRuneStore` class with `$state()` values. ++ Parent components register their runes in the store. ++ Dynamic components access the same rune references from the store. ++ No wrapper/proxy - direct rune access through shared state container. + +### Solution 4: Compilation-Time Rune Binding + +Modify the source transformation to replace rune references in the dynamic component with bindings to externally provided rune objects. + +**Approach**: + ++ Parse the dynamic component source for rune usage patterns. ++ Replace `let { count = $bindable(0) } = $props()` with direct external rune bindings. ++ Inject the actual parent runes as module-level imports during compilation. ++ Component uses parent runes as if they were its own. \ No newline at end of file diff --git a/docs/readme.md b/docs/readme.md index afe6044..b030f6b 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -2,6 +2,9 @@ A powerful, secure, and flexible runtime component compiler for Svelte 5+ applications. +> [!NOTE] +> Live demo is available at [https://dynamic-component-engine.matthewdavis.io](https://dynamic-component-engine.matthewdavis.io)! + ## ✨ Features - **Runtime Component Compilation**: Transform Svelte component strings into fully functional components on the fly. @@ -86,7 +89,30 @@ Here's an example of how to use the dynamic component engine to render a compone You must first compile your Svelte component(s) down to a string and serve it to the client (http endpoint, websockets, etc.) then you can use the `load` and `render` functions to dynamically render the component(s) in the browser. -### `esbuild-svelte` +### Using the [`compile-components`](../demo/bin/compile-components) script + +I've provided an easy button to compile your components down to a single file that can be served to the client. + +Simply run `npm run compile` and it will compile all the components in the `shared-components` directory down to a single files that can be served to the client. +Your output will look like this: + +```sh +➜ npm run compile + +> demo@0.0.1 compile +> node bin/compile-components + +Discovering components via ./shared-components/**/entry.ts ++ Discovered component entrypoint: shared-components/simple/entry.ts + +Compiling (1) component... + + public/entry.js 2.7kb + +⚡ Done in 191ms +``` + +### Manually using `esbuild-svelte` ```typescript import esbuild from "esbuild"; @@ -116,28 +142,12 @@ async function bundleSvelte(entry) { return build.outputFiles; } -bundleSvelte(["./src/components/entry.ts"]); -``` - -Now you're ready to compile your svelte component(s) down to an esm module: - -```bash -node build.js -``` - -Should show something like this in your terminal: - -```shell -$ node build.js - - public/entry.js 1.2kb - -⚡ Done in 156ms +bundleSvelte(["./shared-components/simple/entry.ts"]); ``` ### Output -After running `node build.js` the output will be a single file in the `public` directory and will look like this: +After running `npm run compile` the output will be a single file in the `public` directory and will look like this: ```js const compiledComponentSource = ` diff --git a/out/entry.js b/out/entry.js new file mode 100644 index 0000000..0c0345c --- /dev/null +++ b/out/entry.js @@ -0,0 +1,107 @@ +"use strict"; +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { + get: (a, b) => (typeof require !== "undefined" ? require : a)[b] + }) : x)(function(x) { + if (typeof require !== "undefined") return require.apply(this, arguments); + throw Error('Dynamic require of "' + x + '" is not supported'); + }); + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + + // demo/shared-components/simple/entry.ts + var import_svelte = __require("svelte"); + + // demo/shared-components/simple/simple.svelte + var import_disclose_version = __require("svelte/internal/disclose-version"); + var $ = __toESM(__require("svelte/internal/client")); + var on_click = (_, testState) => $.update(testState); + var root = $.from_html( + ` + +
+
+

Simple.svelte

+

This is a simple component that is rendered on the receiving side.
See the source code for more details.

+
+
+ \`name\` from $props(): + +
+
+ testState: + +
+ +
`, + 1 + ); + function Simple($$anchor, $$props) { + "use strict"; + let testState = $.state(1); + $.next(); + var fragment = root(); + var div = $.sibling($.first_child(fragment)); + var div_1 = $.sibling($.child(div), 3); + var span = $.sibling($.child(div_1), 3); + var text = $.child(span); + $.reset(span); + $.next(); + $.reset(div_1); + var div_2 = $.sibling(div_1, 2); + var span_1 = $.sibling($.child(div_2), 3); + var text_1 = $.child(span_1, true); + $.reset(span_1); + $.next(); + $.reset(div_2); + var button = $.sibling(div_2, 2); + button.__click = [on_click, testState]; + $.next(); + $.reset(div); + $.template_effect(() => { + $.set_text(text, `"${$$props.name ?? ""}"`); + $.set_text(text_1, $.get(testState)); + }); + $.append($$anchor, fragment); + } + $.delegate(["click"]); + + // demo/shared-components/simple/entry.ts + var factory = (target, props) => { + const component = (0, import_svelte.mount)(Simple, { + target, + props + }); + return { + component, + name: "Simple", + props, + destroy: () => { + console.log("entry.ts -> simple.svelte", "destroying component", component); + (0, import_svelte.unmount)(component); + } + }; + }; +})(); diff --git a/package-lock.json b/package-lock.json index 5cdee2b..c67ce6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,27 +9,29 @@ "version": "0.0.1", "license": "MIT", "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "@testing-library/jest-dom": "^6.6.3", + "@sveltejs/vite-plugin-svelte": "^6.1.2", + "@testing-library/jest-dom": "^6.7.0", "@testing-library/svelte": "^5.2.8", "@tsconfig/svelte": "^5.0.4", - "@types/node": "^24.0.10", + "@types/node": "^24.3.0", + "@types/yargs": "^17.0.33", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", "esbuild-plugin-cache": "^0.2.10", "esbuild-svelte": "^0.9.3", + "esbuild-wasm": "^0.25.9", "jsdom": "^26.1.0", "prettier": "^3.6.2", "prettier-plugin-svelte": "^3.4.0", - "prettier-plugin-tailwindcss": "^0.6.13", - "svelte": "^5.35.1", - "svelte-check": "^4.2.2", + "prettier-plugin-tailwindcss": "^0.6.14", + "svelte": "^5.38.1", + "svelte-check": "^4.3.1", "svelte-preprocess": "^6.0.3", - "tsup": "^8.5.0", - "typescript": "~5.8.3", - "vite": "^6.3.5", + "typescript": "~5.9.2", + "vite": "^7.1.5", "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.2.4" + "vitest": "^3.2.4", + "yargs": "^18.0.0" }, "peerDependencies": { "svelte": "^5.0.0" @@ -734,6 +736,17 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -1071,43 +1084,43 @@ } }, "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.1.0.tgz", - "integrity": "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-6.1.2.tgz", + "integrity": "sha512-7v+7OkUYelC2dhhYDAgX1qO2LcGscZ18Hi5kKzJQq7tQeXpH215dd0+J/HnX2zM5B3QKcIrTVqCGkZXAy5awYw==", "dev": true, "license": "MIT", "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", + "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", - "vitefu": "^1.0.6" + "vitefu": "^1.1.1" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { "svelte": "^5.0.0", - "vite": "^6.0.0" + "vite": "^6.3.0 || ^7.0.0" } }, - "node_modules/@sveltejs/vite-plugin-svelte/node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz", - "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==", + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-5.0.0.tgz", + "integrity": "sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ==", "dev": true, "license": "MIT", "dependencies": { - "debug": "^4.3.7" + "debug": "^4.4.1" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22" + "node": "^20.19 || ^22.12 || >=24" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", - "vite": "^6.0.0" + "vite": "^6.3.0 || ^7.0.0" } }, "node_modules/@testing-library/dom": { @@ -1165,18 +1178,17 @@ "license": "MIT" }, "node_modules/@testing-library/jest-dom": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.6.3.tgz", - "integrity": "sha512-IteBhl4XqYNkM54f4ejhLRJiZNqcSCoXUOG2CPK7qbD322KjQozM4kHQOfkG2oln9b9HTYqs+Sae8vBATubxxA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.7.0.tgz", + "integrity": "sha512-RI2e97YZ7MRa+vxP4UUnMuMFL2buSsf0ollxUbTgrbPLKhMn8KVTx7raS6DYjC7v1NDVrioOvaShxsguLNISCA==", "dev": true, "license": "MIT", "dependencies": { "@adobe/css-tools": "^4.4.0", "aria-query": "^5.0.0", - "chalk": "^3.0.0", "css.escape": "^1.5.1", "dom-accessibility-api": "^0.6.3", - "lodash": "^4.17.21", + "picocolors": "^1.1.1", "redent": "^3.0.0" }, "engines": { @@ -1250,13 +1262,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.10.tgz", - "integrity": "sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==", + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", + "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~7.8.0" + "undici-types": "~7.10.0" } }, "node_modules/@types/node-fetch": { @@ -1270,6 +1282,23 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@vitest/coverage-v8": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz", @@ -1490,13 +1519,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, "node_modules/aria-query": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", @@ -1570,22 +1592,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/bundle-require": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bundle-require/-/bundle-require-5.1.0.tgz", - "integrity": "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-tsconfig": "^0.2.3" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "esbuild": ">=0.18" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -1627,20 +1633,6 @@ "node": ">=12" } }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -1667,6 +1659,77 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -1710,33 +1773,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/confbox": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/consola": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.18.0 || >=16.10.0" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2062,6 +2098,29 @@ "svelte": ">=4.2.1 <6" } }, + "node_modules/esbuild-wasm": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.9.tgz", + "integrity": "sha512-Jpv5tCSwQg18aCqCRD3oHIX/prBhXMDapIoG//A+6+dV0e7KQMGFg85ihJ5T1EeMjbZjON3TqFy0VrGAnIHLDA==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/esm-env": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", @@ -2070,9 +2129,9 @@ "license": "MIT" }, "node_modules/esrap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.0.1.tgz", - "integrity": "sha512-6n1JodkxeMvyTDCog7J//t8Yti//fGicZgtFLko6h/aEpc54BK9O8k9cZgC2J8+2Dh1U5uYIxuJWSsylybvFBA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", + "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", "dev": true, "license": "MIT", "dependencies": { @@ -2100,11 +2159,14 @@ } }, "node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "picomatch": "^3 || ^4" }, @@ -2121,18 +2183,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fix-dts-default-cjs-exports": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fix-dts-default-cjs-exports/-/fix-dts-default-cjs-exports-1.0.1.tgz", - "integrity": "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "magic-string": "^0.30.17", - "mlly": "^1.7.4", - "rollup": "^4.34.8" - } - }, "node_modules/flatted": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", @@ -2158,9 +2208,9 @@ } }, "node_modules/form-data": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", - "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", "dev": true, "license": "MIT", "dependencies": { @@ -2199,6 +2249,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -2506,16 +2579,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/joycon": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -2579,6 +2642,8 @@ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14" }, @@ -2586,23 +2651,6 @@ "url": "https://github.com/sponsors/antonk52" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/load-tsconfig": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", - "integrity": "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", @@ -2610,20 +2658,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==", - "dev": true, - "license": "MIT" - }, "node_modules/loupe": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.4.tgz", @@ -2755,19 +2789,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mlly": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", - "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.14.0", - "pathe": "^2.0.1", - "pkg-types": "^1.3.0", - "ufo": "^1.5.4" - } - }, "node_modules/mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", @@ -2795,18 +2816,6 @@ "dev": true, "license": "MIT" }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -2879,16 +2888,6 @@ "dev": true, "license": "MIT" }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -2961,9 +2960,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -2973,28 +2972,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-types": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "confbox": "^0.1.8", - "mlly": "^1.7.4", - "pathe": "^2.0.1" - } - }, "node_modules/postcss": { "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", @@ -3040,6 +3017,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "lilconfig": "^3.1.1" }, @@ -3095,9 +3074,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.13.tgz", - "integrity": "sha512-uQ0asli1+ic8xrrSmIOaElDu0FacR4x69GynTh2oZjFY10JUt6EEumTQl5tB4fMeD6I1naKd+4rXQQ7esT2i1g==", + "version": "0.6.14", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.14.tgz", + "integrity": "sha512-pi2e/+ZygeIqntN+vC573BcW5Cve8zUB0SSAGxqpB4f96boZF4M3phPVoOFCeypwkpRYdi7+jQ5YJJUwrkGUAg==", "dev": true, "license": "MIT", "engines": { @@ -3105,6 +3084,8 @@ }, "peerDependencies": { "@ianvs/prettier-plugin-sort-imports": "*", + "@prettier/plugin-hermes": "*", + "@prettier/plugin-oxc": "*", "@prettier/plugin-pug": "*", "@shopify/prettier-plugin-liquid": "*", "@trivago/prettier-plugin-sort-imports": "*", @@ -3126,6 +3107,12 @@ "@ianvs/prettier-plugin-sort-imports": { "optional": true }, + "@prettier/plugin-hermes": { + "optional": true + }, + "@prettier/plugin-oxc": { + "optional": true + }, "@prettier/plugin-pug": { "optional": true }, @@ -3246,16 +3233,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/rollup": { "version": "4.44.1", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.1.tgz", @@ -3407,19 +3384,6 @@ "node": ">=18" } }, - "node_modules/source-map": { - "version": "0.8.0-beta.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", - "integrity": "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -3430,35 +3394,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/source-map/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/source-map/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -3603,29 +3538,6 @@ "dev": true, "license": "MIT" }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3640,13 +3552,13 @@ } }, "node_modules/svelte": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.35.1.tgz", - "integrity": "sha512-3kNMwstMB2VUBod63H6BQPzBr7NiPRR9qFVzrWqW/nU4ulqqAYZsJ6E7m8LYFoRzuW6yylx+uzdgKVhFKZVf4Q==", + "version": "5.38.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.38.1.tgz", + "integrity": "sha512-fO6CLDfJYWHgfo6lQwkQU2vhCiHc2MBl6s3vEhK+sSZru17YL4R5s1v14ndRpqKAIkq8nCz6MTk1yZbESZWeyQ==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", + "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", @@ -3655,7 +3567,7 @@ "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", - "esrap": "^2.0.0", + "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -3666,9 +3578,9 @@ } }, "node_modules/svelte-check": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.2.2.tgz", - "integrity": "sha512-1+31EOYZ7NKN0YDMKusav2hhEoA51GD9Ws6o//0SphMT0ve9mBTsTUEX7OmDMadUP3KjNHsSKtJrqdSaD8CrGQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.1.tgz", + "integrity": "sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg==", "dev": true, "license": "MIT", "dependencies": { @@ -3767,29 +3679,6 @@ "node": ">=18" } }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -3805,14 +3694,14 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.3" }, "engines": { "node": ">=12.0.0" @@ -3907,23 +3796,6 @@ "node": ">=18" } }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/tsconfck": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", @@ -3945,63 +3817,10 @@ } } }, - "node_modules/tsup": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/tsup/-/tsup-8.5.0.tgz", - "integrity": "sha512-VmBp77lWNQq6PfuMqCHD3xWl22vEoWsKajkF8t+yMBawlUS8JzEI+vOVMeuNZIuMML8qXRizFKi9oD5glKQVcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-require": "^5.1.0", - "cac": "^6.7.14", - "chokidar": "^4.0.3", - "consola": "^3.4.0", - "debug": "^4.4.0", - "esbuild": "^0.25.0", - "fix-dts-default-cjs-exports": "^1.0.0", - "joycon": "^3.1.1", - "picocolors": "^1.1.1", - "postcss-load-config": "^6.0.1", - "resolve-from": "^5.0.0", - "rollup": "^4.34.8", - "source-map": "0.8.0-beta.0", - "sucrase": "^3.35.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.11", - "tree-kill": "^1.2.2" - }, - "bin": { - "tsup": "dist/cli-default.js", - "tsup-node": "dist/cli-node.js" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@microsoft/api-extractor": "^7.36.0", - "@swc/core": "^1", - "postcss": "^8.4.12", - "typescript": ">=4.5.0" - }, - "peerDependenciesMeta": { - "@microsoft/api-extractor": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "postcss": { - "optional": true - }, - "typescript": { - "optional": true - } - } - }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4012,39 +3831,32 @@ "node": ">=14.17" } }, - "node_modules/ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", - "dev": true, - "license": "MIT" - }, "node_modules/undici-types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", - "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", + "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", "dev": true, "license": "MIT" }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz", + "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -4053,14 +3865,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -4145,9 +3957,9 @@ } }, "node_modules/vitefu": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.0.tgz", - "integrity": "sha512-AiG/L9DVsEYHWQ9jAEnke0nKiASlPw+JYwDl6Z4l6a6/IqT1tKseEl6R5+rVnKJt/K3jCTWiQvgoIh5MuqBJJQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", "dev": true, "license": "MIT", "workspaces": [ @@ -4454,6 +4266,69 @@ "dev": true, "license": "MIT" }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zimmerframe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", diff --git a/package.json b/package.json index 72e0912..992bd41 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,21 @@ { "name": "@mateothegreat/dynamic-component-engine", "version": "0.0.1", - "type": "module", - "moduleResolution": "bundler", "description": "A powerful, secure, and flexible runtime component compiler for Svelte 5+ applications.", "author": "Matthew Davis ", "license": "MIT", + "type": "module", + "moduleResolution": "bundler", + "types": "./index.d.ts", "exports": { ".": { - "import": "./src/index.ts", - "types": "./src/index.ts" + "types": "./index.d.ts", + "import": "./index.js" } }, + "files": [ + "./**/*" + ], "scripts": { "dev": "vite", "build": "vite build", @@ -22,26 +26,29 @@ "test:coverage": "vitest --coverage" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^5.1.0", - "@testing-library/jest-dom": "^6.6.3", + "@sveltejs/vite-plugin-svelte": "^6.1.2", + "@testing-library/jest-dom": "^6.7.0", "@testing-library/svelte": "^5.2.8", "@tsconfig/svelte": "^5.0.4", - "@types/node": "^24.0.10", + "@types/node": "^24.3.0", + "@types/yargs": "^17.0.33", "@vitest/coverage-v8": "^3.2.4", "@vitest/ui": "^3.2.4", "esbuild-plugin-cache": "^0.2.10", "esbuild-svelte": "^0.9.3", + "esbuild-wasm": "^0.25.9", "jsdom": "^26.1.0", "prettier": "^3.6.2", "prettier-plugin-svelte": "^3.4.0", - "prettier-plugin-tailwindcss": "^0.6.13", - "svelte": "^5.35.1", - "svelte-check": "^4.2.2", + "prettier-plugin-tailwindcss": "^0.6.14", + "svelte": "^5.38.1", + "svelte-check": "^4.3.1", "svelte-preprocess": "^6.0.3", - "typescript": "~5.8.3", - "vite": "^6.3.5", + "typescript": "~5.9.2", + "vite": "^7.1.5", "vite-tsconfig-paths": "^5.1.4", - "vitest": "^3.2.4" + "vitest": "^3.2.4", + "yargs": "^18.0.0" }, "peerDependencies": { "svelte": "^5.0.0" diff --git a/src/compiler/index.ts b/src/compiler/index.ts new file mode 100644 index 0000000..e3ce6fd --- /dev/null +++ b/src/compiler/index.ts @@ -0,0 +1 @@ +export * from "./runtime"; diff --git a/src/compiler/runtime.test.ts b/src/compiler/runtime.test.ts new file mode 100644 index 0000000..6edeea6 --- /dev/null +++ b/src/compiler/runtime.test.ts @@ -0,0 +1,240 @@ +// import { JSDOM } from "jsdom"; +// import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +// import { SvelteRuntimeCompiler } from "./runtime-orig"; + +// describe("SvelteRuntimeCompiler", () => { +// let dom: JSDOM; +// let container: HTMLElement; + +// beforeEach(() => { +// // Setup DOM environment +// dom = new JSDOM(""); +// global.document = dom.window.document as any; +// global.window = dom.window as any; +// global.HTMLElement = dom.window.HTMLElement; +// global.URL = dom.window.URL; +// global.Blob = dom.window.Blob; + +// // Create container for component mounting +// container = document.createElement("div"); +// container.id = "test-container"; +// document.body.appendChild(container); +// }); + +// afterEach(() => { +// // Cleanup +// if (container && container.parentNode) { +// container.parentNode.removeChild(container); +// } +// SvelteRuntimeCompiler.clearCache(); +// }); + +// describe("render", () => { +// it("should compile and render a simple component", async () => { +// const source = ` +// +//

Hello {name}!

+// `; + +// const component = await SvelteRuntimeCompiler.render(source, container, { name: "Test" }); + +// expect(component).toBeDefined(); +// expect(component.component).toBeDefined(); +// expect(component.destroy).toBeInstanceOf(Function); +// expect(component.update).toBeInstanceOf(Function); +// }); + +// it("should compile component with state and reactivity", async () => { +// const source = ` +// +//
+//

Count: {count}

+// +//
+// `; + +// const component = await SvelteRuntimeCompiler.render(source, container, { initialValue: 5 }); + +// expect(component).toBeDefined(); +// expect(component.component).toBeDefined(); +// }); + +// it("should handle CSS injection when enabled", async () => { +// const source = ` +// + +//
Hello!
+ +// +// `; + +// const component = await SvelteRuntimeCompiler.render( +// source, +// container, +// { color: "red" }, +// { injectCss: true } +// ); + +// expect(component).toBeDefined(); +// }); + +// it("should handle component destruction", async () => { +// const source = ` +// +//

{text}

+// `; + +// const component = await SvelteRuntimeCompiler.render(source, container, { text: "Test" }); + +// expect(container.innerHTML).not.toBe(""); + +// component.destroy(); + +// expect(container.innerHTML).toBe(""); +// }); + +// it("should cache compiled components", async () => { +// const source = ` +// +// {value} +// `; + +// // First render +// const component1 = await SvelteRuntimeCompiler.render(source, container, { value: 1 }); + +// // Destroy first component +// component1.destroy(); + +// // Create new container +// const container2 = document.createElement("div"); +// document.body.appendChild(container2); + +// // Second render (should use cache) +// const component2 = await SvelteRuntimeCompiler.render(source, container2, { value: 2 }); + +// expect(component2).toBeDefined(); + +// // Cleanup +// component2.destroy(); +// container2.parentNode?.removeChild(container2); +// }); + +// it("should handle compilation errors gracefully", async () => { +// const invalidSource = ` +// +//

Test

+// `; + +// await expect(SvelteRuntimeCompiler.render(invalidSource, container)).rejects.toThrow( +// "Component compilation failed" +// ); +// }); + +// it("should use custom component name when provided", async () => { +// const source = ` +// +//

{greeting}

+// `; + +// const component = await SvelteRuntimeCompiler.render( +// source, +// container, +// { greeting: "Hello" }, +// { name: "CustomGreeting" } +// ); + +// expect(component).toBeDefined(); +// // The component name is used internally in the factory +// }); + +// it("should handle components with effects", async () => { +// const source = ` +// +//
+//

Count: {count}

+//

Doubled: {doubled}

+//
+// `; + +// const component = await SvelteRuntimeCompiler.render(source, container); + +// expect(component).toBeDefined(); +// }); + +// it("should log warning when update is called", async () => { +// const consoleSpy = vi.spyOn(console, "warn"); + +// const source = ` +// +//

{text}

+// `; + +// const component = await SvelteRuntimeCompiler.render(source, container, { text: "Test" }); + +// component.update?.({ text: "Updated" }); + +// expect(consoleSpy).toHaveBeenCalledWith( +// "Direct prop updates not supported in runtime compilation. Recreate component instead." +// ); + +// consoleSpy.mockRestore(); +// }); +// }); + +// describe("clearCache", () => { +// it("should clear the component cache", async () => { +// const consoleSpy = vi.spyOn(console, "log"); + +// const source = ` +// +// {value} +// `; + +// // Compile once to populate cache +// const component = await SvelteRuntimeCompiler.render(source, container, { value: 1 }); +// component.destroy(); + +// // Clear cache +// SvelteRuntimeCompiler.clearCache(); + +// expect(consoleSpy).toHaveBeenCalledWith("Component cache cleared"); + +// consoleSpy.mockRestore(); +// }); +// }); +// }); diff --git a/src/compiler/runtime.ts b/src/compiler/runtime.ts new file mode 100644 index 0000000..6abd03e --- /dev/null +++ b/src/compiler/runtime.ts @@ -0,0 +1,237 @@ +import { compile, type CompileOptions, type CompileResult } from "svelte/compiler"; +import { SharedRuneStore } from "../shared-rune-store.js"; + +// Re-export for convenience +export { SharedRuneStore, sharedStore } from "../shared-rune-store.js"; + +export interface CompiledComponent { + component: any; + destroy: () => void; + update: (props: Record) => void; + result?: { + name?: string; + filename?: string; + hasCSS?: boolean; + length: number; + }; +} + +export interface CompilerOptions { + css?: boolean; + sourcemap?: boolean; + name?: string; + cache?: boolean; + onMount?: (component: any) => void; + onDestroy?: () => void; + onError?: (error: Error) => void; + useSandbox?: boolean; // Optional: render inside iframe for isolation + sharedStore?: SharedRuneStore; // Optional: shared rune store for reactive state +} + +/** + * Runtime compiler for Svelte 5 components with reactive props and optional sandboxing. + * Compiles Svelte source strings into live components using mount/unmount APIs. + */ +export class ComponentCompiler { + private static componentCache = new Map(); + + /** + * Dynamically load compiled JavaScript as an ES module. + * Uses Blob URLs to simulate module imports at runtime. + * + * @param source - Transformed JavaScript code. + * + * @returns The component factory function. + */ + private static async loadModule(source: string): Promise { + const blob = new Blob([source], { type: "application/javascript" }); + const url = URL.createObjectURL(blob); + try { + const module = await import(/* @vite-ignore */ url); + URL.revokeObjectURL(url); + return module.default; + } finally { + URL.revokeObjectURL(url); + } + } + + /** + * Compile Svelte source code into JavaScript using Svelte 5 compiler. + * + * @param source - Svelte component source. + * @param options - Compiler options. + * + * @returns CompileResult containing JS and CSS. + */ + private static compileSource(source: string, options: CompilerOptions = {}): CompileResult { + const compileOptions: CompileOptions = { + generate: "client", + css: options.css ? "injected" : "external", + // If true, returns the modern version of the AST. Will become true by default in Svelte 6, + // and the option will be removed in Svelte 7. + modernAst: true, + // Set to true to force the compiler into runes mode, even if there are no indications of runes usage. + // Set to false to force the compiler into ignoring runes, even if there are indications of runes usage. + // Set to undefined (the default) to infer runes mode from the component code. + // Is always true for JS/TS modules compiled with Svelte. Will be true by default in Svelte 6. + // Note that setting this to true in your svelte.config.js will force runes mode for your entire project, + // including components in node_modules, which is likely not what you want. If you're using Vite, consider + // using dynamicCompileOptions instead. + runes: true, + filename: options.name || "DynamicComponent.svelte" + }; + + return compile(source, compileOptions); + } + + /** + * Transforms compiled JS to wrap the component in a factory using mount/unmount to + * enable lifecycle control and prop injection. + * + * @param code - Compiled JS code. + * @param componentName - Name of the component. + * @param sharedStore - Optional shared rune store for reactive state. + * + * @returns Transformed JS code as string. + */ + private static transformCompiledCode(code: string, componentName: string, sharedStore?: SharedRuneStore): string { + const lines = code.split("\n"); + + /** + * Inject mount and unmount imports so that the wrapper can do it's job. + */ + lines.unshift(`import { mount, unmount } from "svelte";`); + + /** + * If a shared store is provided, inject it as a parameter in the factory function. + */ + + /** + * Replace default export with named component so that when the component is rendered, + * the component is not exported as default but as a named component. + */ + const exportDefault = lines.findIndex((line) => line.startsWith("export default")); + if (exportDefault !== -1) { + const line = lines[exportDefault]; + if (line) { + lines[exportDefault] = line.replace(/export default\s+/, `const ${componentName} = `); + } + } + + /** + * This is to wrap the component in a factory function so that we can: + * 1. Create a new instance of the component. + * 2. Mount the component into the target element. + * 3. Return the component and the destroy function. + */ + const factoryCode = sharedStore + ? ` + const factory = (target, props, sharedStore) => { + // Make sharedStore globally available within this module + globalThis.sharedStore = sharedStore; + const component = mount(${componentName}, { target, props }); + return { + component, + destroy: () => unmount(component) + }; + }; + export { factory as default }; + ` + : ` + const factory = (target, props) => { + const component = mount(${componentName}, { target, props }); + return { + component, + destroy: () => unmount(component) + }; + }; + export { factory as default }; + `; + + lines.push(factoryCode); + + return lines.join("\n"); + } + + /** + * Renders a compiled component into a target DOM element. + * + * @param source - Svelte source code. + * @param target - DOM element to mount into. + * @param props - Initial props. + * @param options - Compiler and lifecycle options. + * + * @returns A compiled component instance. + */ + static async render( + source: string, + target: HTMLElement, + props: Record = {}, + options: CompilerOptions = {} + ): Promise { + try { + const cacheKey = source + JSON.stringify(options); + let fn: Function | undefined; + + if (options.cache) { + fn = this.componentCache.get(cacheKey); + } + + const compiled = this.compileSource(source, options); + /** + * Strip the file extension from the name. + * + * This is to prevent the following error (the name of function is not valid because of the dot): + * ```ts + * const DynamicComponent.svelte = function DynamicComponent($$anchor, $$props) { + * SyntaxError: Missing initializer in const declaration (at 21242b81-0fce-4eb9-8a92-d21cf4e83631:11:7) + * ``` + */ + const componentName = options.name?.replace(/\.(svelte|js)$/, "") || "DynamicComponent"; + const transformedCode = this.transformCompiledCode(compiled.js.code, componentName, options.sharedStore); + + fn = await this.loadModule(transformedCode); + this.componentCache.set(cacheKey, fn); + + const instance = options.sharedStore ? fn(target, props, options.sharedStore) : fn(target, props); + + const component = { + component: instance.component, + destroy: () => { + instance.destroy(); + target.innerHTML = ""; + options.onDestroy?.(); + }, + update: (props: Record) => { + console.log("needs to propagate the update to the component", props); + // instance.update(props); + }, + result: { + name: componentName, + filename: options.name, + hasCSS: !!compiled.css, + length: compiled.js.code.length + } + }; + + /** + * If the caller provides an onMount callback, call it with the component instance + * so that the caller can do something with the newcomponent instance. + */ + options.onMount?.(instance.component); + + return component; + } catch (error) { + const err = error instanceof Error ? error : new Error(String(error)); + options.onError?.(err); + throw err; + } + } + + /** + * Clears the internal component cache. + */ + static clearCache(): void { + this.componentCache.clear(); + } +} diff --git a/src/lib/dynamic-components.ts b/src/dynamic-components.ts similarity index 91% rename from src/lib/dynamic-components.ts rename to src/dynamic-components.ts index f59c6c0..940f2fb 100644 --- a/src/lib/dynamic-components.ts +++ b/src/dynamic-components.ts @@ -1,10 +1,4 @@ import type { mount } from "svelte"; -import { Logger, LogLevel } from "./logger"; - -/** - * The logger for the dynamic-components module. - */ -const logger = new Logger("dynamic-components.ts", { level: LogLevel.DEBUG }); /** * The type of the component instance returned by the `mount` function. @@ -53,6 +47,7 @@ export interface RenderOptions { export const load = async (source: string): Promise => { const url = URL.createObjectURL(new Blob([source], { type: "application/javascript" })); const module = await import(/* @vite-ignore */ url); + URL.revokeObjectURL(url); return module.default; }; diff --git a/src/index.ts b/src/index.ts index 05752ce..7fa67fc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,5 @@ -export * from "./lib/dynamic-components"; -export * from "./lib/logger"; -export * from "./version"; +// Make it easier to import when through package.json (cjs and esm are the usual suspects 🤸‍♀️ ofc). +export * from "./compiler"; +export * from "./dynamic-components"; +export * from "./loader"; +export * from "./shared-rune-store"; diff --git a/src/loader.ts b/src/loader.ts new file mode 100644 index 0000000..513f194 --- /dev/null +++ b/src/loader.ts @@ -0,0 +1,19 @@ +import { load, render, type Rendered } from "./dynamic-components"; + +export const loadComponent = async (renderRef: HTMLElement, props: T): Promise> => { + const source = await fetch("/entry.js").then((res) => res.text()); + const fn = await load(source); + + /** + * We pass type type to the render function to infer the type of the props for the + * component. This is useful because we can then use the props type for accessing the + * props of the renderedcomponent. + */ + const component = await render(fn, { + source: source, + target: renderRef!, + props: props + }); + + return component; +}; diff --git a/src/shared-rune-store.ts b/src/shared-rune-store.ts new file mode 100644 index 0000000..d281e31 --- /dev/null +++ b/src/shared-rune-store.ts @@ -0,0 +1,142 @@ +/** + * Shared Rune Store for reactive state sharing between parent and dynamically compiled components. + * Creates a bridge for passing reactive state between components without using runes directly in TS. + */ + +type StateValue = { + value: T; + subscribers: Set<() => void>; +}; + +export class SharedRuneStore { + private static instance: SharedRuneStore | null = null; + private store = new Map(); + + private constructor() {} + + static getInstance(): SharedRuneStore { + if (!SharedRuneStore.instance) { + SharedRuneStore.instance = new SharedRuneStore(); + } + return SharedRuneStore.instance; + } + + /** + * Set a reactive value in the store + */ + set(key: string, value: T): void { + if (!this.store.has(key)) { + this.store.set(key, { value, subscribers: new Set() }); + } else { + const state = this.store.get(key)!; + state.value = value; + // Notify all subscribers + state.subscribers.forEach(callback => callback()); + } + } + + /** + * Get a reactive value from the store + */ + get(key: string): T { + const state = this.store.get(key); + return state ? state.value : undefined; + } + + /** + * Subscribe to changes on a key + */ + subscribe(key: string, callback: (value: T) => void): () => void { + if (!this.store.has(key)) { + this.store.set(key, { value: undefined, subscribers: new Set() }); + } + + const state = this.store.get(key)!; + const wrappedCallback = () => callback(state.value); + state.subscribers.add(wrappedCallback); + + // Return unsubscribe function + return () => { + state.subscribers.delete(wrappedCallback); + }; + } + + /** + * Get a reactive getter function for a store value + */ + getter(key: string): () => T { + return () => this.get(key); + } + + /** + * Get a reactive setter function for a store value + */ + setter(key: string): (value: T) => void { + return (value: T) => { + this.set(key, value); + }; + } + + /** + * Get both getter and setter for a store value + */ + accessor(key: string): { get: () => T; set: (value: T) => void } { + return { + get: this.getter(key), + set: this.setter(key) + }; + } + + /** + * Check if a key exists in the store + */ + has(key: string): boolean { + return this.store.has(key); + } + + /** + * Remove a value from the store + */ + delete(key: string): void { + this.store.delete(key); + } + + /** + * Clear all values from the store + */ + clear(): void { + this.store.clear(); + } + + /** + * Get all keys in the store + */ + keys(): string[] { + return Array.from(this.store.keys()); + } + + /** + * Create a reactive reference for use in Svelte components + */ + createReactiveRef(key: string, initialValue?: T): { + get value(): T; + set value(newValue: T); + } { + // Initialize with the provided initial value if key doesn't exist + if (!this.has(key) && initialValue !== undefined) { + this.set(key, initialValue); + } + + return { + get value(): T { + return this.get(key); + }, + set value(newValue: T) { + this.set(key, newValue); + } + }; + } +} + +// Export singleton instance for convenience +export const sharedStore = SharedRuneStore.getInstance(); \ No newline at end of file diff --git a/src/test-setup.ts b/src/test-setup.ts deleted file mode 100644 index fabd443..0000000 --- a/src/test-setup.ts +++ /dev/null @@ -1,45 +0,0 @@ -import "@testing-library/jest-dom"; -import { vi } from "vitest"; - -// Mock URL.createObjectURL and URL.revokeObjectURL for tests -globalThis.URL.createObjectURL = vi.fn(() => "blob:test-url"); -globalThis.URL.revokeObjectURL = vi.fn(); - -// Mock console methods to reduce test noise -globalThis.console = { - ...console, - warn: vi.fn(), - error: vi.fn() -}; - -// Setup DOM environment -Object.defineProperty(window, "location", { - value: { - href: "http://localhost:3000" - }, - writable: true -}); - -// Create a mock component class for testing -export class MockSvelteComponent { - public target: HTMLElement; - public props: any; - - constructor({ target, props }: { target: HTMLElement; props?: any }) { - this.target = target; - this.props = props; - this.render(); - } - - render() { - if (this.target) { - this.target.innerHTML = "
Mock Dynamic Component
"; - } - } - - $destroy() { - if (this.target) { - this.target.innerHTML = ""; - } - } -} diff --git a/src/version.ts b/src/version.ts deleted file mode 100644 index c61cf16..0000000 --- a/src/version.ts +++ /dev/null @@ -1,18 +0,0 @@ -export type Version = { - tag: string; - commit: { - long: string; - short: string; - }; - dirty: boolean; - branch: string; - date: { - actual: Date; - human: string; - }; -}; - -export const getVersion = (): Version => { - const version = JSON.parse(import.meta.env.VERSION); - return version; -}; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts deleted file mode 100644 index 4078e74..0000000 --- a/src/vite-env.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -/// -/// diff --git a/svelte.config.js b/svelte.config.js deleted file mode 100644 index 447c400..0000000 --- a/svelte.config.js +++ /dev/null @@ -1,5 +0,0 @@ -import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; - -export default { - preprocess: [vitePreprocess({})] -}; diff --git a/tsconfig.json b/tsconfig.json index 3204699..59b107e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,23 +1,20 @@ { + "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { - "module": "esnext", + "rootDir": "./src", + "outDir": "./dist", + "module": "es2022", "moduleResolution": "bundler", - "target": "es2023", - /** - Svelte Preprocess cannot figure out whether you have a value or a type, so tell TypeScript - to enforce using `import type` instead of `import` for Types. - */ + "target": "es2022", "verbatimModuleSyntax": true, - /** - To have warnings/errors of the Svelte compiler at the correct position, - enable source maps by default. - */ - "noEmit": true, "sourceMap": true, "strict": true, - "strictNullChecks": false, - "esModuleInterop": true, + "isolatedModules": true, + "noImplicitAny": true, + "noUncheckedIndexedAccess": true, + "noImplicitReturns": true, + "noImplicitThis": true, "skipLibCheck": true }, - "include": ["./src/**/*"] + "include": ["./src/**/*.ts", "runtime-orig.ts"] } diff --git a/vite-plugin-version.ts b/vite-plugin-version.ts deleted file mode 100644 index 2a9a724..0000000 --- a/vite-plugin-version.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { execSync, spawnSync } from "child_process"; -import type { Plugin } from "vite"; - -export const ago = (date: Date, locale = "en"): string => { - const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" }); - - const now = new Date(); - const diff = (date.getTime() - now.getTime()) / 1000; - - const units: [Intl.RelativeTimeFormatUnit, number][] = [ - ["year", diff / (60 * 60 * 24 * 365)], - ["month", diff / (60 * 60 * 24 * 30)], - ["week", diff / (60 * 60 * 24 * 7)], - ["day", diff / (60 * 60 * 24)], - ["hour", diff / (60 * 60)], - ["minute", diff / 60], - ["second", diff] - ]; - - for (const [unit, value] of units) { - const rounded = Math.round(value); - if (Math.abs(rounded) >= 1) { - return rtf.format(rounded, unit); - } - } - - return rtf.format(0, "second"); -}; - -export default function versionPlugin(): Plugin { - return { - name: "version-plugin", - applyToEnvironment(env) { - env.config.env.VERSION = JSON.stringify({ - date: { - actual: new Date(execSync("git log -1 --format=%cd").toString()), - human: ago(new Date(execSync("git log -1 --format=%cd").toString())) - }, - tag: execSync("git describe --tags --abbrev=0").toString().trim(), - commit: { - long: execSync("git rev-parse HEAD").toString().trim(), - short: execSync("git rev-parse --short HEAD").toString().trim() - }, - dirty: spawnSync("git diff --quiet").status !== 0, - branch: execSync("git rev-parse --abbrev-ref HEAD").toString().trim() - }); - return true; - } - }; -} diff --git a/vite.config.ts b/vite.config.ts index 11f61c5..03f6f1f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,16 +1,6 @@ -import { svelte } from "@sveltejs/vite-plugin-svelte"; - import { defineConfig } from "vite"; - import tsconfigPaths from "vite-tsconfig-paths"; -import { sveltePreprocess } from "svelte-preprocess"; - export default defineConfig({ - plugins: [ - tsconfigPaths(), - svelte({ - preprocess: [sveltePreprocess({ typescript: true })] - }) - ] + plugins: [tsconfigPaths()] });