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

[Svelte] Improve typescript types + minor fixes #1881 #10

Merged
merged 9 commits into from
Aug 31, 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
83 changes: 47 additions & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 12 additions & 18 deletions packages/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
"description": "The Svelte adapter for Inertia.js",
"contributors": [
"Jonathan Reinink <jonathan@reinink.ca>",
"Pedro Borges <oi@pedroborg.es>",
"Dmytro Morozov <puny.flash@gmail.com>"
"Pedro Borges <oi@pedroborg.es>"
],
"homepage": "https://inertiajs.com/",
"repository": {
Expand Down Expand Up @@ -36,15 +35,17 @@
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.2.0",
"@sveltejs/kit": "^2.5.5",
"@sveltejs/package": "^2.3.0",
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"publint": "^0.2.7",
"svelte": "^4.2.12",
"svelte-check": "^3.6.8",
"@sveltejs/kit": "^2.5.7",
"@sveltejs/package": "^2.3.1",
"@sveltejs/vite-plugin-svelte": "^3.1.0",
"@types/lodash": "^4.17.7",
"axios": "^1.6.8",
"publint": "^0.1.16",
"svelte": "^4.2.16",
"svelte-check": "^3.7.1",
"tslib": "^2.6.2",
"typescript": "^5.4.3",
"vite": "^5.2.7"
"typescript": "^5.4.5",
"vite": "^5.2.11"
},
"exports": {
".": {
Expand All @@ -56,16 +57,9 @@
"svelte": "./dist/server.js"
}
},
"import": "./dist/index.js",
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"typesVersions": {
">4.0": {
".": [
"./dist/index.d.ts"
]
}
},
"dependencies": {
"@inertiajs/core": "1.2.0",
"lodash": "^4.5.0"
Expand Down
6 changes: 2 additions & 4 deletions packages/svelte/src/lib/components/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
import Render, { h } from './Render.svelte'
import store from '../store'

$$props

$: child = $store.component && h($store.component.default, $store.page?.props)
$: child = $store.component?.default && h($store.component.default, $store.page?.props)
$: layout = $store.component && $store.component.layout
$: components = layout
? Array.isArray(layout)
? layout
.concat(child)
.reverse()
.reduce((child, layout) => h(layout, $store.page?.props, [child]))
: h(layout, $store.page?.props, [child])
: h(layout, $store.page?.props, child ? [child] : [])
: child
</script>

Expand Down
23 changes: 9 additions & 14 deletions packages/svelte/src/lib/components/Render.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script context="module" lang="ts">
import type { PageProps } from '@inertiajs/core'
import type { InertiaComponentType } from '../types'
import type { ComponentType } from 'svelte'

type RenderProps = {
component: InertiaComponentType
component: ComponentType
props?: PageProps
children?: RenderProps[]
} | null

export const h = (component: InertiaComponentType, props?: PageProps, children?: RenderProps[]): RenderProps => {
export const h = (component: ComponentType, props?: PageProps, children?: RenderProps[]): RenderProps => {
return {
component,
...(props ? { props } : {}),
Expand All @@ -20,21 +20,16 @@
<script lang="ts">
import store from '../store'

export let component: InertiaComponentType
export let component: ComponentType
export let props: PageProps = {}
export let children: RenderProps[] = []

let prev = component
let key = new Date().getTime()

function updateKey(component: InertiaComponentType) {
if (prev !== component) {
prev = component
key = new Date().getTime()
}
let prevComponent: ComponentType
let key: number
$: if (prevComponent !== component) {
key = Date.now()
prevComponent = component
}

$: updateKey(component)
</script>

{#if $store.component}
Expand Down
12 changes: 9 additions & 3 deletions packages/svelte/src/lib/components/SSR.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
<script lang="ts">
<script context="module" lang="ts">
import type { Page } from '@inertiajs/core'
export type SSRProps = { id: string; initialPage: Page }
</script>

<script lang="ts">
import App from './App.svelte'

export let id: string
export let initialPage: Page
interface $$Props extends SSRProps {}

export let id: $$Props['id']
export let initialPage: $$Props['initialPage']
</script>

<div data-server-rendered="true" {id} data-page={JSON.stringify(initialPage)}>
Expand Down
81 changes: 40 additions & 41 deletions packages/svelte/src/lib/createInertiaApp.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
import { router, setupProgress, type InertiaAppResponse, type Page } from '@inertiajs/core'
import type { ComponentType } from 'svelte'
import SvelteApp from './components/App.svelte'
import SSR from './components/SSR.svelte'
import App from './components/App.svelte'
import SSR, { type SSRProps } from './components/SSR.svelte'
import store from './store'
import type { ComponentResolver, InertiaComponentType } from './types'
import type { ComponentResolver, ResolvedComponent } from './types'

type SvelteRenderResult = { html: string; head: string; css: { code: string } }
type SSRComponent = ComponentType<SSR> & { render: (props: SSRProps) => SvelteRenderResult }

interface CreateInertiaAppProps {
id?: string
resolve: ComponentResolver
setup: (props: {
el: Element
// @ts-ignore
App: ComponentType<SvelteApp>
App: ComponentType<App>
props: {
initialPage: Page
resolveComponent: ComponentResolver
}
}) => void | SvelteApp
}) => void | App
progress?:
| false
| {
Expand All @@ -37,54 +39,51 @@ export default async function createInertiaApp({
}: CreateInertiaAppProps): InertiaAppResponse {
const isServer = typeof window === 'undefined'
const el = isServer ? null : document.getElementById(id)
const initialPage = page || JSON.parse(el?.dataset.page ?? '{}')
const initialPage: Page = page || JSON.parse(el?.dataset?.page || '{}')
const resolveComponent = (name: string) => Promise.resolve(resolve(name))

await resolveComponent(initialPage.component).then((initialComponent) => {
store.set({
component: initialComponent as unknown as InertiaComponentType,
component: initialComponent,
page: initialPage,
})
})

if (!isServer) {
if (!el) {
throw new Error(`Element with ID "${id}" not found.`)
}

router.init({
initialPage,
resolveComponent,
swapComponent: async ({ component, page, preserveState }) => {
store.update((current) => ({
component: component as InertiaComponentType,
page,
key: preserveState ? current.key : Date.now(),
}))
},
})
if (isServer) {
const { html, head, css } = (SSR as SSRComponent).render({ id, initialPage })

if (progress) {
setupProgress(progress)
return {
body: html,
head: [head, `<style data-vite-css>${css.code}</style>`],
}
}

setup({
el,
App: SvelteApp,
props: {
initialPage,
resolveComponent,
},
})

return
if (!el) {
throw new Error(`Element with ID "${id}" not found.`)
}

// Svelte types are written for the DOM API and not the SSR API.
const { html, head, css } = (SSR as any).render({ id, initialPage })
router.init({
initialPage,
resolveComponent,
swapComponent: async ({ component, page, preserveState }) => {
store.update((current) => ({
component: component as ResolvedComponent,
page,
key: preserveState ? current.key : Date.now(),
}))
},
})

return {
body: html,
head: [head, `<style data-vite-css>${css.code}</style>`],
if (progress) {
setupProgress(progress)
}

setup({
el,
App,
props: {
initialPage,
resolveComponent,
},
})
}
2 changes: 1 addition & 1 deletion packages/svelte/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export { default as createInertiaApp } from './createInertiaApp'
export { default as inertia } from './link'
export { default as page } from './page'
export { default as remember } from './remember'
export { default as useForm } from './useForm'
export { default as useForm, type InertiaForm } from './useForm'
Loading
Loading