Skip to content

Commit e33d027

Browse files
committed
[inertiajs#1875] Merge pull request #8
Merge punyflash/inertia with some tweaks and fixes
2 parents 61f8e48 + 683e82f commit e33d027

24 files changed

+1306
-409
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88

99
strategy:
1010
matrix:
11-
adapter: ['react', 'vue2', 'vue3']
11+
adapter: ['react', 'vue2', 'vue3', 'svelte']
1212
node-version: [20]
1313

1414
steps:

packages/svelte/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
dist
2+
types
23
node_modules
34
package-lock.json
45
yarn.lock
6+
.svelte-kit

packages/svelte/package.json

+42-7
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@inertiajs/svelte",
33
"version": "1.0.16",
44
"license": "MIT",
5-
"description": "The Svelte adapter for Inertia.js",
5+
"description": "The Svelte 5 adapter for Inertia.js",
66
"contributors": [
77
"Jonathan Reinink <jonathan@reinink.ca>",
88
"Pedro Borges <oi@pedroborg.es>"
@@ -19,17 +19,52 @@
1919
"keywords": [
2020
"svelte"
2121
],
22+
"scripts": {
23+
"build": "npm run package",
24+
"package": "svelte-kit sync && svelte-package && publint",
25+
"prepublishOnly": "npm run package",
26+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
27+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
28+
"test": "vitest"
29+
},
2230
"exports": {
23-
".": "./src/index.js",
24-
"./server": "./src/server.js"
31+
".": {
32+
"types": "./dist/index.d.ts",
33+
"svelte": "./dist/index.js"
34+
},
35+
"./server": {
36+
"types": "./dist/server.d.ts",
37+
"svelte": "./dist/server.js"
38+
}
2539
},
26-
"main": "src/index.js",
40+
"files": [
41+
"dist",
42+
"!dist/**/*.test.*",
43+
"!dist/**/*.spec.*"
44+
],
2745
"peerDependencies": {
28-
"svelte": "^3.20.0 || ^4.0.0 || ^5.0.0 || 5.0.0-next.1"
46+
"svelte": "^5.0.0-next.1"
2947
},
3048
"dependencies": {
3149
"@inertiajs/core": "workspace:*",
3250
"lodash.clonedeep": "^4.5.0",
3351
"lodash.isequal": "^4.5.0"
34-
}
35-
}
52+
},
53+
"devDependencies": {
54+
"axios": "^1.6.8",
55+
"@sveltejs/adapter-auto": "^3.2.0",
56+
"@sveltejs/kit": "^2.5.7",
57+
"@sveltejs/package": "^2.3.1",
58+
"@sveltejs/vite-plugin-svelte": "4.0.0-next.0",
59+
"publint": "^0.1.16",
60+
"svelte": "5.0.0-next.131",
61+
"svelte-check": "^3.7.1",
62+
"tslib": "^2.6.2",
63+
"typescript": "^5.4.5",
64+
"vite": "^5.2.11",
65+
"vitest": "^1.6.0"
66+
},
67+
"svelte": "./dist/index.js",
68+
"types": "./dist/index.d.ts",
69+
"type": "module"
70+
}

packages/svelte/src/Render.svelte

-36
This file was deleted.

packages/svelte/src/createInertiaApp.js

-64
This file was deleted.

packages/svelte/src/App.svelte packages/svelte/src/lib/components/App.svelte

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
<script>
1+
<script lang="ts">
22
import Render, { h } from './Render.svelte'
3-
import store from './store'
3+
import store from '../store'
44
5-
$: child = $store.component && h($store.component.default, $store.page.props)
5+
$: child = $store.component && h($store.component.default, $store.page?.props)
66
$: layout = $store.component && $store.component.layout
77
$: components = layout
88
? Array.isArray(layout)
99
? layout
1010
.concat(child)
1111
.reverse()
12-
.reduce((child, layout) => h(layout, $store.page.props, [child]))
13-
: h(layout, $store.page.props, [child])
12+
.reduce((child, layout) => h(layout, $store.page?.props, [child]))
13+
: h(layout, $store.page?.props, [child])
1414
: child
1515
</script>
1616

packages/svelte/src/Link.svelte packages/svelte/src/lib/components/Link.svelte

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
<script>
1+
<script lang="ts">
2+
import type { Method, PreserveStateOption, RequestPayload } from '@inertiajs/core'
23
import { beforeUpdate } from 'svelte'
3-
import { default as inertia } from './link'
4+
import { inertia } from '../index'
45
5-
export let href
6-
export let as = 'a'
7-
export let data = {}
8-
export let method = 'get'
9-
export let replace = false
10-
export let preserveScroll = false
11-
export let preserveState = null
12-
export let only = []
13-
export let headers = {}
14-
export let queryStringArrayFormat = 'brackets'
6+
export let href: string
7+
export let as: keyof HTMLElementTagNameMap = 'a'
8+
export let data: RequestPayload = {}
9+
export let method: Method = 'get'
10+
export let replace: boolean = false
11+
export let preserveScroll: PreserveStateOption = false
12+
export let preserveState: PreserveStateOption | null = null
13+
export let only: string[] = []
14+
export let headers: Record<string, string> = {}
15+
export let queryStringArrayFormat: 'brackets' | 'indices' = 'brackets'
1516
1617
beforeUpdate(() => {
1718
if (as === 'a' && method.toLowerCase() !== 'get') {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script context="module" lang="ts">
2+
import type { PageProps } from '@inertiajs/core'
3+
import type { InertiaComponentType } from '../types'
4+
5+
type RenderProps = {
6+
component: InertiaComponentType
7+
props?: PageProps
8+
children?: RenderProps[]
9+
} | null
10+
11+
export const h = (component: InertiaComponentType, props?: PageProps, children?: RenderProps[]): RenderProps => {
12+
return {
13+
component,
14+
...(props ? { props } : {}),
15+
...(children ? { children } : {}),
16+
}
17+
}
18+
</script>
19+
20+
<script lang="ts">
21+
import store from '../store'
22+
23+
export let component: InertiaComponentType
24+
export let props: PageProps = {}
25+
export let children: RenderProps[] = []
26+
27+
let prevComponent: InertiaComponentType
28+
let key: number
29+
$: {
30+
if (prevComponent !== component) {
31+
key = Date.now()
32+
prevComponent = component
33+
}
34+
}
35+
</script>
36+
37+
{#if $store.component}
38+
{#key key}
39+
<svelte:component this={component} {...props}>
40+
{#each children as child, index (component && component.length === index ? $store.key : null)}
41+
<svelte:self {...child} />
42+
{/each}
43+
</svelte:component>
44+
{/key}
45+
{/if}

packages/svelte/src/SSR.svelte packages/svelte/src/lib/components/SSR.svelte

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
<script>
1+
<script lang="ts">
2+
import type { Page } from '@inertiajs/core'
23
import App from './App.svelte'
3-
export let id, initialPage
4+
5+
export let id: string
6+
export let initialPage: Page
47
</script>
58

69
<div data-server-rendered="true" {id} data-page={JSON.stringify(initialPage)}>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { VERSION } from 'svelte/compiler';
2+
import { router, setupProgress, type InertiaAppResponse, type Page } from '@inertiajs/core'
3+
import type { ComponentType } from 'svelte'
4+
import App from './components/App.svelte'
5+
import SSR from './components/SSR.svelte'
6+
import store from './store'
7+
import type { ComponentResolver, InertiaComponentType } from './types'
8+
9+
const SVELTE_MAJOR_VERSION = parseInt(VERSION.split('.')[0]);
10+
11+
interface CreateInertiaAppProps {
12+
id?: string
13+
resolve: ComponentResolver
14+
setup: (props: {
15+
el: Element
16+
App: ComponentType<App>
17+
props: {
18+
initialPage: Page
19+
resolveComponent: ComponentResolver
20+
}
21+
}) => void | App
22+
progress?:
23+
| false
24+
| {
25+
delay?: number
26+
color?: string
27+
includeCSS?: boolean
28+
showSpinner?: boolean
29+
}
30+
page?: Page
31+
}
32+
33+
export default async function createInertiaApp({
34+
id = 'app',
35+
resolve,
36+
setup,
37+
progress = {},
38+
page,
39+
}: CreateInertiaAppProps): InertiaAppResponse {
40+
const isServer = typeof window === 'undefined'
41+
const el = isServer ? null : document.getElementById(id)
42+
const initialPage: Page = page || JSON.parse(el?.dataset?.page || '{}')
43+
const resolveComponent = (name: string, page: Page) => Promise.resolve(resolve(name, page))
44+
45+
await resolveComponent(initialPage.component, initialPage).then((initialComponent) => {
46+
store.set({
47+
component: initialComponent as InertiaComponentType,
48+
page: initialPage,
49+
})
50+
})
51+
52+
if (!isServer) {
53+
if (!el) {
54+
throw new Error(`Element with ID "${id}" not found.`)
55+
}
56+
57+
router.init({
58+
initialPage,
59+
resolveComponent,
60+
swapComponent: async ({ component, page, preserveState }) => {
61+
store.update((current) => ({
62+
component: component as InertiaComponentType,
63+
page,
64+
key: preserveState ? current.key : Date.now(),
65+
}))
66+
},
67+
})
68+
69+
if (progress) {
70+
setupProgress(progress)
71+
}
72+
73+
setup({
74+
el,
75+
App,
76+
props: {
77+
initialPage,
78+
resolveComponent,
79+
},
80+
})
81+
}
82+
83+
if (isServer) {
84+
const { html, head } = await (async () => {
85+
if (SVELTE_MAJOR_VERSION < 5) {
86+
return (SSR as any).render({ id, initialPage })
87+
} else {
88+
const { render } = await import('svelte/server')
89+
return render(SSR as any, { props: { id, initialPage } })
90+
}
91+
})()
92+
93+
return {
94+
body: html,
95+
head: [head],
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)