@poveste/plugin-svelte 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.node.ts DELETED
@@ -1,101 +0,0 @@
1
- import type { Plugin } from 'poveste'
2
- import { existsSync } from 'node:fs'
3
- import { createRequire } from 'node:module'
4
- import { dirname, join } from 'pathe'
5
- import { defaultColors } from 'poveste'
6
- import generateStoryCommand from './commands/generate-story.server.js'
7
- import { listComponentFiles } from './util/list-components.js'
8
- import { disableStoryComponentHmr } from './util/story-hmr.js'
9
-
10
- export function HstSvelte(): Plugin {
11
- return {
12
- name: '@poveste/plugin-svelte',
13
-
14
- defaultConfig() {
15
- const svelteClientAliases = getSvelteClientAliases()
16
-
17
- return {
18
- supportMatch: [
19
- {
20
- id: 'svelte',
21
- patterns: ['**/*.svelte'],
22
- pluginIds: ['svelte4'],
23
- },
24
- ],
25
- theme: {
26
- colors: {
27
- primary: defaultColors.orange,
28
- },
29
- logo: {
30
- square: '@poveste/plugin-svelte/assets/poveste-svelte.svg',
31
- light: '@poveste/plugin-svelte/assets/poveste-svelte-text.svg',
32
- dark: '@poveste/plugin-svelte/assets/poveste-svelte-text.svg',
33
- },
34
- },
35
- viteIgnorePlugins: [
36
- 'vite-plugin-sveltekit-compile',
37
- ],
38
- vite: svelteClientAliases.length
39
- ? {
40
- plugins: [
41
- disableStoryComponentHmr(),
42
- ],
43
- resolve: {
44
- alias: svelteClientAliases,
45
- },
46
- }
47
- : {
48
- plugins: [
49
- disableStoryComponentHmr(),
50
- ],
51
- },
52
- }
53
- },
54
-
55
- supportPlugin: {
56
- id: 'svelte4',
57
- moduleName: '@poveste/plugin-svelte',
58
- setupFn: ['setupSvelte3', 'setupSvelte4', 'setupSvelte5'],
59
- importStoryComponent: (file, index) => `import Comp${index} from ${JSON.stringify(file.moduleId)}`,
60
- },
61
-
62
- commands: [
63
- generateStoryCommand,
64
- ],
65
-
66
- async onDevEvent(api) {
67
- switch (api.event) {
68
- case 'listSvelteComponents': {
69
- return listComponentFiles(api.payload.search, api.getConfig().storyMatch)
70
- }
71
- }
72
- },
73
- }
74
- }
75
-
76
- export * from './helpers.js'
77
-
78
- function getSvelteClientAliases() {
79
- try {
80
- const require = createRequire(join(process.cwd(), 'package.json'))
81
- const sveltePackagePath = require.resolve('svelte/package.json')
82
- const svelteDir = dirname(sveltePackagePath)
83
-
84
- const aliasEntries = [
85
- [/^svelte$/, join(svelteDir, 'src/index-client.js')],
86
- [/^svelte\/legacy$/, join(svelteDir, 'src/legacy/legacy-client.js')],
87
- [/^svelte\/store$/, join(svelteDir, 'src/store/index-client.js')],
88
- [/^svelte\/reactivity$/, join(svelteDir, 'src/reactivity/index-client.js')],
89
- ] as const
90
-
91
- return aliasEntries
92
- .filter(([, replacement]) => existsSync(replacement))
93
- .map(([find, replacement]) => ({
94
- find,
95
- replacement,
96
- }))
97
- }
98
- catch {
99
- return []
100
- }
101
- }
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './helpers.js'
@@ -1,16 +0,0 @@
1
- import { globby } from 'globby'
2
-
3
- export async function listComponentFiles(search = '', ignore: string[] = [], limit = 10) {
4
- let files = await globby('**/*.svelte', {
5
- gitignore: true,
6
- ignore: [
7
- 'node_modules',
8
- ...ignore,
9
- ],
10
- })
11
- if (search) {
12
- const searchText = search.toLowerCase()
13
- files = files.filter(file => file.toLowerCase().includes(searchText))
14
- }
15
- return files.slice(0, limit)
16
- }
@@ -1,52 +0,0 @@
1
- const storyFileRE = /\.story\.svelte$/
2
-
3
- type DynamicCompileOptions = NonNullable<SveltePluginApi['options']>['dynamicCompileOptions']
4
-
5
- interface SveltePluginApi {
6
- options?: {
7
- dynamicCompileOptions?: (data: {
8
- filename: string
9
- code: string
10
- compileOptions: Record<string, any>
11
- }) => Partial<Record<string, any>> | void | Promise<Partial<Record<string, any>> | void>
12
- }
13
- }
14
-
15
- interface SvelteConfigPlugin {
16
- name: string
17
- api?: SveltePluginApi
18
- __povesteStoryHmrPatched?: boolean
19
- }
20
-
21
- export function disableStoryComponentHmr() {
22
- return {
23
- name: 'poveste:svelte-story-hmr',
24
- apply: 'serve' as const,
25
- configResolved(config: { readonly plugins: readonly unknown[] }) {
26
- for (const plugin of config.plugins as SvelteConfigPlugin[]) {
27
- if (plugin.name !== 'vite-plugin-svelte:config' || plugin.__povesteStoryHmrPatched) {
28
- continue
29
- }
30
-
31
- const options = plugin.api?.options
32
- if (!options) {
33
- continue
34
- }
35
-
36
- const originalDynamicCompileOptions = options.dynamicCompileOptions as DynamicCompileOptions
37
- options.dynamicCompileOptions = async (data) => {
38
- const result = await originalDynamicCompileOptions?.(data)
39
- if (!storyFileRE.test(data.filename)) {
40
- return result
41
- }
42
-
43
- return {
44
- ...result,
45
- hmr: false,
46
- }
47
- }
48
- plugin.__povesteStoryHmrPatched = true
49
- }
50
- },
51
- }
52
- }
@@ -1,153 +0,0 @@
1
- import type { SvelteStorySetupApi, SvelteStorySetupHandler } from '../helpers.js'
2
- import * as svelte from 'svelte'
3
-
4
- type SetupModule = Record<string, unknown>
5
-
6
- const setupHookNames = [
7
- 'setupSvelte3',
8
- 'setupSvelte4',
9
- 'setupSvelte5',
10
- ] as const
11
-
12
- export interface MountedSvelteComponent {
13
- app: any
14
- destroy: () => void
15
- }
16
-
17
- export interface LegacyStateApi {
18
- captureState: () => Record<string, any> | null
19
- injectState: (state: Record<string, any>) => void
20
- }
21
-
22
- function loadSvelteModule(moduleId: string) {
23
- return import(/* @vite-ignore */ moduleId)
24
- }
25
-
26
- export async function mountSvelteComponent(
27
- component: any,
28
- options: Record<string, any>,
29
- mode: 'auto' | 'client' | 'server-compat' = 'auto',
30
- ): Promise<MountedSvelteComponent> {
31
- if (mode !== 'server-compat') {
32
- if (typeof (svelte as any)?.mount === 'function') {
33
- const app = (svelte as any).mount(component, options)
34
- return {
35
- app,
36
- destroy: () => {
37
- if (typeof (svelte as any).unmount === 'function') {
38
- ;(svelte as any).unmount(app)
39
- }
40
- else {
41
- app?.$destroy?.()
42
- }
43
- },
44
- }
45
- }
46
- }
47
-
48
- try {
49
- // eslint-disable-next-line new-cap
50
- const app = new component(options)
51
- return {
52
- app,
53
- destroy: () => {
54
- app?.$destroy?.()
55
- },
56
- }
57
- }
58
- catch (error) {
59
- const legacyModuleId = ['svelte', 'legacy'].join('/')
60
- const legacy = await loadSvelteModule(legacyModuleId).catch(() => null)
61
- if (typeof legacy?.createClassComponent === 'function') {
62
- const app = legacy.createClassComponent({
63
- component,
64
- ...options,
65
- })
66
- return {
67
- app,
68
- destroy: () => {
69
- app?.$destroy?.()
70
- },
71
- }
72
- }
73
-
74
- throw error
75
- }
76
- }
77
-
78
- export function getLegacyStateApi(app: any): LegacyStateApi | null {
79
- if (typeof app?.$capture_state !== 'function' || typeof app?.$inject_state !== 'function') {
80
- return null
81
- }
82
-
83
- return {
84
- captureState: () => app.$capture_state(),
85
- injectState: (state) => {
86
- app.$inject_state(state)
87
- },
88
- }
89
- }
90
-
91
- export async function callSetupFunctions(
92
- generatedSetup: SetupModule,
93
- setup: SetupModule,
94
- setupApi: SvelteStorySetupApi,
95
- variantSetupApp?: SvelteStorySetupHandler | null,
96
- ) {
97
- for (const hookName of setupHookNames) {
98
- const generatedHook = generatedSetup[hookName] as SvelteStorySetupHandler | undefined
99
- if (typeof generatedHook === 'function') {
100
- await generatedHook(setupApi)
101
- }
102
-
103
- const setupHook = setup[hookName] as SvelteStorySetupHandler | undefined
104
- if (typeof setupHook === 'function') {
105
- await setupHook(setupApi)
106
- }
107
- }
108
-
109
- if (typeof variantSetupApp === 'function') {
110
- await variantSetupApp(setupApi)
111
- }
112
- }
113
-
114
- /**
115
- * Adds `controlComponent` to a props object **without** spreading it.
116
- *
117
- * Svelte 5 passes a bound prop as an accessor pair — `bind:value` becomes a
118
- * `get value()` / `set value(v)` on the props object. Spreading invokes the
119
- * getter and writes a plain data property, so the setter is dropped and the
120
- * child's write-back silently goes nowhere: reads keep working, writes stop.
121
- * That was the whole of #81.
122
- *
123
- * Copying the descriptors keeps the setter intact.
124
- */
125
- function withControlComponent(props: any, controlComponent: any) {
126
- const merged = Object.defineProperties({}, Object.getOwnPropertyDescriptors(props ?? {}))
127
- Object.defineProperty(merged, 'controlComponent', {
128
- value: controlComponent,
129
- enumerable: true,
130
- writable: true,
131
- configurable: true,
132
- })
133
- return merged
134
- }
135
-
136
- export function createWrappedComponent(Wrap: any, controlComponent: any) {
137
- function ProxyWrap(anchorOrOptions: any, props?: any) {
138
- if (new.target) {
139
- return new Wrap({
140
- ...anchorOrOptions,
141
- props: withControlComponent(anchorOrOptions?.props, controlComponent),
142
- })
143
- }
144
-
145
- return Wrap(anchorOrOptions, withControlComponent(props, controlComponent))
146
- }
147
-
148
- if (Wrap?.element) {
149
- ProxyWrap.element = Wrap.element
150
- }
151
-
152
- return ProxyWrap
153
- }
package/svelte.config.js DELETED
@@ -1,5 +0,0 @@
1
- import sveltePreprocess from 'svelte-preprocess'
2
-
3
- export default {
4
- preprocess: sveltePreprocess(),
5
- }
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "exclude": [
4
- "src/client",
5
- "src/collect"
6
- ]
7
- }
package/tsconfig.json DELETED
@@ -1,41 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- // Volar
5
- "jsx": "preserve",
6
- "lib": [
7
- "ESNext",
8
- "DOM"
9
- ],
10
- "rootDir": "src",
11
- "module": "ESNext",
12
- "moduleResolution": "bundler",
13
- "resolveJsonModule": true,
14
- "types": [
15
- "node"
16
- ],
17
- "strictBindCallApply": true,
18
- "strictFunctionTypes": true,
19
- "alwaysStrict": true,
20
- // Strict
21
- "noImplicitAny": false,
22
- "noImplicitThis": true,
23
- "outDir": "dist",
24
- "removeComments": false,
25
- "sourceMap": false,
26
- "allowSyntheticDefaultImports": true,
27
- "esModuleInterop": true,
28
- "verbatimModuleSyntax": true,
29
- "skipLibCheck": true,
30
- "preserveWatchOutput": true
31
- },
32
- "include": [
33
- "src"
34
- ],
35
- "exclude": [
36
- "node_modules",
37
- "generated/**/*",
38
- "dist/**/*",
39
- "src/**/*.spec.ts"
40
- ]
41
- }
package/vite.config.ts DELETED
@@ -1,103 +0,0 @@
1
- import { svelte } from '@sveltejs/vite-plugin-svelte'
2
- import fs from 'fs-extra'
3
- import { globbySync } from 'globby'
4
- import { defineConfig } from 'vite'
5
- import pkg from './package.json'
6
-
7
- export default defineConfig({
8
- plugins: [
9
- svelte(),
10
- {
11
- name: 'poveste:preserve:import.dynamic',
12
- enforce: 'pre',
13
- transform(code) {
14
- if (code.includes('import(')) {
15
- return {
16
- code: code.replace(/import\(/g, 'import__dyn('),
17
- }
18
- }
19
- },
20
- closeBundle() {
21
- try {
22
- const rawSvelteFiles = globbySync([
23
- 'src/client/**/*.svelte',
24
- 'src/collect/**/*.svelte',
25
- ])
26
- const rawSvelteBasenames = rawSvelteFiles.map(file => file.split('/').pop()?.replace(/\.svelte$/, '')).filter(Boolean)
27
-
28
- for (const file of rawSvelteFiles) {
29
- const target = file.replace(/^src\//, 'dist/')
30
- fs.ensureDirSync(target.replace(/\/[^/]+$/, ''))
31
- fs.copyFileSync(file, target)
32
- }
33
-
34
- const files = globbySync('./dist/**/*.js')
35
- for (const file of files) {
36
- let content = fs.readFileSync(file, 'utf-8')
37
- let updated = false
38
-
39
- if (content.includes('import__dyn')) {
40
- content = content.replace(/import__dyn\(/g, 'import(/* @vite-ignore */')
41
- updated = true
42
- }
43
-
44
- if (content.includes('.svelte.js')) {
45
- content = content.replace(/\.svelte\.js(["'])/g, '.svelte$1')
46
- updated = true
47
- }
48
-
49
- for (const basename of rawSvelteBasenames) {
50
- const compiledImport = `./${basename}.js`
51
- if (content.includes(compiledImport)) {
52
- content = content.replaceAll(compiledImport, `./${basename}.svelte`)
53
- updated = true
54
- }
55
- }
56
-
57
- if (updated) {
58
- fs.writeFileSync(file, content, 'utf-8')
59
- }
60
- }
61
- }
62
- catch (e) {
63
- console.error(e)
64
- }
65
- },
66
- },
67
- ],
68
- build: {
69
- emptyOutDir: false,
70
- outDir: 'dist',
71
- cssCodeSplit: false,
72
- rollupOptions: {
73
- external: [
74
- ...Object.keys(pkg.dependencies).map(dep => new RegExp(`^${dep}(\\/?)`)),
75
- ...Object.keys(pkg.peerDependencies).map(dep => new RegExp(`^${dep}(\\/?)`)),
76
- /^node:/,
77
- /^virtual:/,
78
- /^\$/, // Virtual modules
79
- ],
80
-
81
- input: [
82
- 'src/client/index.ts',
83
- 'src/collect/index.ts',
84
- ],
85
-
86
- output: {
87
- // manualChunks (id) {
88
- // if (id.includes('node_modules')) {
89
- // return 'vendor'
90
- // }
91
- // },
92
- entryFileNames: '[name].js',
93
- chunkFileNames: '[name].js',
94
- assetFileNames: '[name][extname]',
95
- // hoistTransitiveImports: false,
96
- preserveModules: true,
97
- preserveModulesRoot: 'src',
98
- },
99
- treeshake: false,
100
- preserveEntrySignatures: 'strict',
101
- },
102
- },
103
- })