Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support svelte 5 #55

Merged
merged 6 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions assets/app/stack/svelte/5/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),

kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
strict: false
})
}
};

export default config;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import type { ClassicScheme } from "rete-svelte-plugin";
import type { ClassicScheme } from "rete-svelte-plugin/* [svelte5] /5 [/svelte5] */";
type Position = { x: number; y: number };

// svelte-ignore unused-export-let
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import type { ClassicScheme, SvelteArea2D } from "rete-svelte-plugin";
import { Ref } from "rete-svelte-plugin";
import type { ClassicScheme, SvelteArea2D } from "rete-svelte-plugin/* [svelte5] /5 [/svelte5] */";
import { Ref } from "rete-svelte-plugin/* [svelte5] /5 [/svelte5] */";
type NodeExtraData = { width?: number; height?: number };

function sortByIndex<K, I extends undefined | { index?: number }>(
Expand Down
3 changes: 2 additions & 1 deletion assets/app/stack/svelte/modules/routes/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script>
import Header from "./Header.svelte";
import "./styles.css";
/* [!svelte5] import "./styles.css"; [/!svelte5] */
/* [svelte5] import "../app.css"; [/svelte5] */
</script>

<div class="app">
Expand Down
6 changes: 2 additions & 4 deletions assets/app/stack/svelte/modules/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import welcome from "$lib/images/svelte-welcome.webp";
import welcome_fallback from "$lib/images/svelte-welcome.png";

import "./styles.css";
import "../common.css";
import "../customization/background.css";
import { onMount } from "svelte";
let el: HTMLElement;

Expand Down Expand Up @@ -33,9 +34,6 @@
</section>

<style>
@import '../common.css';
@import '../customization/background.css';

section {
display: flex;
flex-direction: column;
Expand Down
8 changes: 8 additions & 0 deletions assets/app/stack/svelte/modules/shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
declare module '*.svelte' {
import type { Component } from 'svelte'

// eslint-disable-next-line init-declarations
const component: Component

export default component
}
2 changes: 1 addition & 1 deletion assets/app/templates/3d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ConnectionPlugin, Presets as ConnectionPresets } from 'rete-connection-
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [vue-render] import { VuePlugin, VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/vue-render] */
/* [angular-render] import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/* [angular12] /12 [/angular12] *//* [angular13] /13 [/angular13] *//* [angular14] /14 [/angular14] *//* [angular15] /15 [/angular15] *//* [angular16] /16 [/angular16] *//* [angular17] /17 [/angular17] *//* [angular18] /18 [/angular18] */' [/angular-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin' [/svelte-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/svelte-render] */
/* [lit-render] import { LitPlugin, LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/lit-render] */
/* [dataflow] import { DataflowEngine, DataflowNode } from 'rete-engine' [/dataflow] */
/* [arrange] import { AutoArrangePlugin, Presets as ArrangePresets } from 'rete-auto-arrange-plugin' [/arrange] */
Expand Down
8 changes: 4 additions & 4 deletions assets/app/templates/customization
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [stack-vue] import { VuePlugin, VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/stack-vue] */
/* [stack-angular] import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/* [angular12] /12 [/angular12] *//* [angular13] /13 [/angular13] *//* [angular14] /14 [/angular14] *//* [angular15] /15 [/angular15] *//* [angular16] /16 [/angular16] *//* [angular17] /17 [/angular17] *//* [angular18] /18 [/angular18] */' [/stack-angular] */
/* [stack-svelte] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin' [/stack-svelte] */
/* [stack-svelte] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/stack-svelte] */
/* [stack-lit] import { LitPlugin, LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/stack-lit] */
/* [stack-react] import { CustomNode } from "../customization/CustomNode";
import { StyledNode } from "../customization/StyledNode";
Expand Down Expand Up @@ -127,13 +127,13 @@ export async function createEditor(container: HTMLElement/* [stack-angular] , in
SveltePresets.classic.setup({
customize: {
node() {
return CustomNodeComponent as any;
return CustomNodeComponent;
},
connection() {
return CustomConnectionComponent as any;
return CustomConnectionComponent;
},
socket() {
return CustomSocketComponent as any;
return CustomSocketComponent;
}
},
})
Expand Down
2 changes: 1 addition & 1 deletion assets/app/templates/default
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Area2D, /* [import-area-extensions] AreaExtensions, [/import-area-exten
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [vue-render] import { VuePlugin, VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/vue-render] */
/* [angular-render] import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/* [angular12] /12 [/angular12] *//* [angular13] /13 [/angular13] *//* [angular14] /14 [/angular14] *//* [angular15] /15 [/angular15] *//* [angular16] /16 [/angular16] *//* [angular17] /17 [/angular17] *//* [angular18] /18 [/angular18] */' [/angular-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin' [/svelte-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/svelte-render] */
/* [lit-render] import { LitPlugin, LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/lit-render] */
/* [dataflow] import { DataflowEngine, DataflowNode } from 'rete-engine' [/dataflow] */
/* [arrange] import { AutoArrangePlugin, Presets as ArrangePresets } from 'rete-auto-arrange-plugin' [/arrange] */
Expand Down
2 changes: 1 addition & 1 deletion assets/app/templates/perf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { /* [import-area-extensions] AreaExtensions, [/import-area-extensions] *
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [vue-render] import { VuePlugin, VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/vue-render] */
/* [angular-render] import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/* [angular12] /12 [/angular12] *//* [angular13] /13 [/angular13] *//* [angular14] /14 [/angular14] *//* [angular15] /15 [/angular15] *//* [angular16] /16 [/angular16] *//* [angular17] /17 [/angular17] *//* [angular18] /18 [/angular18] */' [/angular-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin' [/svelte-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/svelte-render] */
/* [lit-render] import { LitPlugin, LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/lit-render] */


Expand Down
2 changes: 1 addition & 1 deletion assets/app/templates/scopes
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Area2D, /* [import-area-extensions] AreaExtensions, [/import-area-exten
/* [react18] import { createRoot } from 'react-dom/client' [/react18] */
/* [vue-render] import { VuePlugin, VueArea2D, Presets as VuePresets } from 'rete-vue-plugin/* [vue2] /vue2 [/vue2] */' [/vue-render] */
/* [angular-render] import { AngularPlugin, AngularArea2D, Presets as AngularPresets } from 'rete-angular-plugin/* [angular12] /12 [/angular12] *//* [angular13] /13 [/angular13] *//* [angular14] /14 [/angular14] *//* [angular15] /15 [/angular15] *//* [angular16] /16 [/angular16] *//* [angular17] /17 [/angular17] *//* [angular18] /18 [/angular18] */' [/angular-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin' [/svelte-render] */
/* [svelte-render] import { SveltePlugin, SvelteArea2D, Presets as SveltePresets } from 'rete-svelte-plugin/* [svelte5] /5 [/svelte5] */' [/svelte-render] */
/* [lit-render] import { LitPlugin, LitArea2D, Presets as LitPresets } from '@retejs/lit-plugin' [/lit-render] */
import { ScopesPlugin, Presets as ScopesPresets } from "rete-scopes-plugin";
/* [context-menu] import { ContextMenuPlugin, ContextMenuExtra, Presets as ContextMenuPresets } from 'rete-context-menu-plugin' [/context-menu] */
Expand Down
3 changes: 2 additions & 1 deletion src/app/features.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AppStack } from '.'
import { AngularVersion } from './stack/angular'
import { SvelteVersion } from './stack/svelte'
import { DefaultTemplateKey } from './template-builder'

function ver(name: string, next: boolean) {
Expand Down Expand Up @@ -92,7 +93,7 @@
templateKeys: DefaultTemplateKey[] = ['svelte-render']
requiredDependencies: string[] = ['sass']

constructor(version: 3 | 4, next: boolean) {
constructor(version: SvelteVersion, next: boolean) {
this.templateKeys.push(`svelte${version}`)
this.requiredDependencies.push(
ver('rete-render-utils', next),
Expand Down Expand Up @@ -245,5 +246,5 @@
}

export function getDependencies(features: Feature[]) {
return features.map(feature => feature.requiredDependencies || []).flat()

Check warning on line 249 in src/app/features.ts

View workflow job for this annotation

GitHub Actions / ci / ci

Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator
}
10 changes: 7 additions & 3 deletions src/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
ViteBuilder, VueBuilder, VueViteBuilder
} from './stack'
import { AngularVersion } from './stack/angular'
import { SvelteVersion } from './stack/svelte'
import { DefaultTemplateKey, TemplateBuilder } from './template-builder'

export const builders = {
Expand All @@ -26,7 +27,7 @@
}

export type AppStack = keyof typeof builders
export const appStacks = Object.keys(builders) as AppStack[]

Check warning on line 30 in src/app/index.ts

View workflow job for this annotation

GitHub Actions / ci / ci

The 'Object.keys(builders) as AppStack[]' has unsafe 'as' type assertion
export { Features }

type Options = {
Expand All @@ -41,9 +42,9 @@
}

// eslint-disable-next-line max-statements, complexity
export async function createApp({ name, stack, version, features, depsAlias, forceInstall = false, next = false }: Options) {

Check warning on line 45 in src/app/index.ts

View workflow job for this annotation

GitHub Actions / ci / ci

This line has a length of 125. Maximum allowed is 120
const appName = name || await input('Name')

Check warning on line 46 in src/app/index.ts

View workflow job for this annotation

GitHub Actions / ci / ci

Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator
const selectedStack = stack || await select('Stack (framework)', appStacks.map(key => ({

Check warning on line 47 in src/app/index.ts

View workflow job for this annotation

GitHub Actions / ci / ci

Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator
name: builders[key].name,
value: key
})))
Expand All @@ -51,12 +52,15 @@
if (!appStacks.includes(selectedStack)) throwError('unknown stack')

const builder = builders[selectedStack]
const selectedVersion = version || await select('Version', builder.versions.map(value => ({
const builderVersions = builder.versions as number[]
const selectedVersion = version || await select<number>('Version', builderVersions.map(value => ({

Check warning on line 56 in src/app/index.ts

View workflow job for this annotation

GitHub Actions / ci / ci

Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator
name: String(value),
value: value
})))

if (!builder.versions.includes(selectedVersion)) throwError('specified version is not available for selected stack')
if (!builderVersions.includes(selectedVersion)) {
throwError('specified version is not available for selected stack')
}

const featuresList: Features.Feature[] = [
new Features.Default(builder.foundation, next),
Expand All @@ -71,7 +75,7 @@
? selectedVersion as 2
: 3, next),
new Features.Svelte(builder.foundation === 'svelte'
? selectedVersion as 4
? selectedVersion as SvelteVersion
: 4, next),
new Features.Lit(builder.foundation === 'lit'
? selectedVersion as 3
Expand Down
8 changes: 5 additions & 3 deletions src/app/stack/angular/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { basename, dirname, join } from 'path'
import { AppBuilder } from '../../app-builder'
import { assetsCommon, assetsStack } from '../../consts'
import { TemplateBuilder } from '../../template-builder'
import { FileTemplate } from '../../template-builder-helpers'
import { removeBudgets } from './budgets'
import { installCompatibleTS } from './compatibility'

Expand Down Expand Up @@ -56,10 +57,11 @@ export class AngularBuilder implements AppBuilder {
}
})

const appModulePath = join(src, 'app', 'app.module.ts')
const appFile = await fs.promises.readFile(appModulePath, { encoding: 'utf-8' })
const fileTemplate = new FileTemplate(template)

await fs.promises.writeFile(appModulePath, await template.build(appFile))
await fileTemplate.apply([
join(src, 'app', 'app.module.ts')
])
}

async putScript(name: string, path: string, code: string): Promise<void> {
Expand Down
65 changes: 65 additions & 0 deletions src/app/stack/svelte/compatibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { join } from 'path'

interface ToolsSet {
create: {
version: string
flags?: string[]
}
kit: {
version: string
}
config?: {
path?: string
}
adapter: {
version: string
}
}

const legacy: ToolsSet = {
create: {
version: '4'
},
kit: {
version: '1'
},
adapter: {
version: '2'
}
}

const tools: Record<`v${number}`, ToolsSet> = {
v5: {
create: {
version: '6',
flags: ['--svelte5']
},
kit: {
version: '2'
},
config: {
path: '5'
},
adapter: {
version: '3'
}
},
v4: legacy,
v3: legacy
}

export function getToolsFor(version: number) {
return tools[`v${version}`]
}

export function getConfigFor(version: number) {
const name = 'svelte.config.js'
const path = version === 5
? '5'
: '.'

return {
source: join(path, name),
name
}
}
44 changes: 31 additions & 13 deletions src/app/stack/svelte/index.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,57 @@
import execa from 'execa'
import fs from 'fs'
import fse from 'fs-extra'
import { dirname, join } from 'path'

import { exec } from '../../../shared/exec'
import { getTSConfig, setTSConfig } from '../../../shared/ts-config'
import { AppBuilder } from '../../app-builder'
import { assetsCommon, assetsStack } from '../../consts'
import { TemplateBuilder } from '../../template-builder'
import { FileTemplate } from '../../template-builder-helpers'
import { getConfigFor, getToolsFor } from './compatibility'

export type SvelteVersion = 3 | 4 | 5

export class SvelteBuilder implements AppBuilder {
public name = 'Svelte'
public versions = [3, 4]
public versions: SvelteVersion[] = [3, 4, 5]
public foundation = 'svelte' as const

public async create(name: string, version: number) {
await execa('npm', [
'create', `svelte-with-args@4`, '-y',
'--',
const tools = getToolsFor(version)

await exec('npx', [
`create-svelte-with-args@${tools.create.version}`,
'--name', name,
'--template', 'default',
'--types', 'typescript',
'--no-prettier', '--no-eslint', '--no-playwright', '--no-vitest'
'--no-prettier', '--no-eslint', '--no-playwright', '--no-vitest',
...tools.create.flags ?? []
], { stdio: 'inherit' })
await execa('npm', ['i'], { cwd: join(process.cwd(), name), stdio: 'inherit' })
await exec('npm', ['i'], { cwd: join(process.cwd(), name), stdio: 'inherit' })

const tsConfig = await getTSConfig(name)

tsConfig.compilerOptions.preserveValueImports = false
tsConfig.compilerOptions.importsNotUsedAsValues = 'preserve'
tsConfig.compilerOptions.verbatimModuleSyntax = false

await setTSConfig(name, tsConfig)

await execa('npm', [
await exec('npm', [
'i',
`svelte@${version}`,
`@sveltejs/kit@1`
`@sveltejs/kit@${tools.kit.version}`
], { stdio: 'inherit', cwd: name })

const configName = 'svelte.config.js'
const { name: configName, source } = getConfigFor(version)

await fse.copy(join(assetsStack, 'svelte', configName), join(name, configName), { overwrite: true })
await execa('npm', ['i', `@sveltejs/adapter-static@2`], { stdio: 'inherit', cwd: name })
await fse.copy(join(assetsStack, 'svelte', source), join(name, configName), { overwrite: true })
await exec('npm', ['i', `@sveltejs/adapter-static@${tools.adapter.version}`], { stdio: 'inherit', cwd: name })
}

async putAssets(name: string) {
// eslint-disable-next-line @typescript-eslint/naming-convention
async putAssets<K extends string>(name: string, _version: number, template: TemplateBuilder<K>) {
const modules = join(assetsStack, 'svelte', 'modules')
const src = join(name, 'src')

Expand All @@ -54,6 +63,15 @@ export class SvelteBuilder implements AppBuilder {
recursive: true,
overwrite: true
})

const fileTemplate = new FileTemplate(template)

await fileTemplate.apply([
join(src, 'customization', 'CustomConnection.svelte'),
join(src, 'customization', 'CustomNode.svelte'),
join(src, 'routes', '+layout.svelte'),
join(src, 'routes', '+page.svelte')
], false)
}

async putScript(name: string, path: string, code: string) {
Expand Down
15 changes: 15 additions & 0 deletions src/app/template-builder-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import fs from 'fs'

import { TemplateBuilder } from './template-builder'

export class FileTemplate<K extends string> {
constructor(private readonly template: TemplateBuilder<K>) {}

async apply(modules: string[], format = true) {
for (const module of modules) {
const file = await fs.promises.readFile(module, { encoding: 'utf-8' })

await fs.promises.writeFile(module, await this.template.build(file, format))
}
}
}
3 changes: 2 additions & 1 deletion src/app/template-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import prettier from 'prettier'

import { assets as assetsRoot } from '../consts'
import { AngularVersion } from './stack/angular'
import { SvelteVersion } from './stack/svelte'

export const templatesPath = join(assetsRoot, 'app', 'templates')
export const entryScriptPath = join(assetsRoot, 'app', 'entry_ts')
export type DefaultTemplateKey = 'zoom-at' | 'react-render' | 'react18' | 'vue-render'
| `vue${2 | 3}` | 'angular-render' | `angular${AngularVersion}`
| 'svelte-render' | `svelte${3 | 4}` | 'lit-render' | `lit${3}`
| 'svelte-render' | `svelte${SvelteVersion}` | 'lit-render' | `lit${3}`
| 'dataflow' | 'arrange' | 'sizes' | 'readonly' | 'order-nodes' | 'selectable'
| 'context-menu' | 'import-area-extensions' | 'minimap' | 'reroute' | `stack-${string}`

Expand Down
Loading
Loading