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

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 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
57 changes: 29 additions & 28 deletions package-lock.json

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

29 changes: 11 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 <[email protected]>",
"Pedro Borges <[email protected]>",
"Dmytro Morozov <[email protected]>"
"Pedro Borges <[email protected]>"
],
"homepage": "https://inertiajs.com/",
"repository": {
Expand Down Expand Up @@ -35,16 +34,17 @@
"svelte": "^3.20.0 || ^4.0.0"
},
"devDependencies": {
"axios": "^1.6.8",
"@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",
"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 +56,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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does nothing


$: 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: 10 additions & 13 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,18 @@
<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
$: {
jamesst20 marked this conversation as resolved.
Show resolved Hide resolved
if (prevComponent !== component) {
key = Date.now()
prevComponent = component
}
}
Copy link
Contributor Author

@jamesst20 jamesst20 May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prior to the typescript merge we had

$: {
  if (prevComponent !== component) {
    key = Date.now()
    prevComponent = component
  }
}

and with the typescript merge we are now having

function updateKey(component: InertiaComponentType) {
  if (prev !== component) {
    prev = component
    key = new Date().getTime()
  }
}


$: updateKey(component)

While it looks like to be the same, it ain't. Everything between ${...} is reactive and is able to trigger state update unlike when it's wrapped into a method. Maybe it doesn't matter, however I don't see any justification for that change


$: 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>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No changes here. Exporting the types to use in createInertiaApp for the SSR instead of casting to any for better typing.


<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) {
jamesst20 marked this conversation as resolved.
Show resolved Hide resolved
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'
4 changes: 2 additions & 2 deletions packages/svelte/src/lib/store.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Page } from '@inertiajs/core'
import { writable } from 'svelte/store'
import type { InertiaComponentType } from './types'
import type { ResolvedComponent } from './types'

interface Store {
component: InertiaComponentType | null
component: ResolvedComponent | null
page: Page | null
key?: number | null
}
Expand Down
10 changes: 4 additions & 6 deletions packages/svelte/src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import type { PageProps } from '@inertiajs/core'
import type { ComponentType } from 'svelte'

export type ComponentResolver = (name: string) => ComponentType | Promise<ComponentType>
export type ComponentResolver = (name: string) => ResolvedComponent | Promise<ResolvedComponent>

export interface InertiaComponentType extends ComponentType {
default: InertiaComponentType
layout: InertiaComponentType
props: PageProps
export type ResolvedComponent = {
default?: ComponentType
layout?: ComponentType
}
Loading
Loading