svelte-spa-history-router 2.2.0-next.2 → 3.0.0-next.1
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/.vscode/extensions.json +3 -0
- package/README.md +86 -28
- package/example/App.svelte +117 -0
- package/{examples/app-svelte5 → example}/index.html +4 -5
- package/example/lib/getArticle.ts +13 -0
- package/example/lib/getArticles.ts +43 -0
- package/example/main.ts +8 -0
- package/{examples/app-svelte5/src → example}/pages/Admin.svelte +1 -0
- package/example/pages/Blog.svelte +19 -0
- package/example/pages/BlogPost.svelte +23 -0
- package/example/pages/IntParam.svelte +14 -0
- package/example/pages/Message.svelte +9 -0
- package/example/pages/Params.svelte +13 -0
- package/{examples/app-svelte4/src → example/pages}/Query.svelte +4 -3
- package/example/pages/Top.svelte +7 -0
- package/example/types.ts +9 -0
- package/package.json +16 -12
- package/playwright-report/index.html +71 -0
- package/src/Router.svelte +104 -75
- package/src/currentURL.ts +9 -0
- package/src/index.ts +7 -0
- package/src/{link.js → link.ts} +4 -7
- package/src/push.ts +18 -0
- package/src/redirect.ts +9 -0
- package/src/spa-context.ts +15 -0
- package/src/spa-event.ts +1 -0
- package/src/types.ts +28 -32
- package/test-results/.last-run.json +4 -0
- package/tests/e2e.spec.ts +133 -0
- package/tsconfig.app.json +27 -0
- package/tsconfig.json +7 -0
- package/tsconfig.node.json +24 -0
- package/{examples/app-svelte5/vite.config.js → vite.config.ts} +3 -2
- package/examples/app-svelte4/dist/Article.js +0 -286
- package/examples/app-svelte4/dist/Article.js.map +0 -1
- package/examples/app-svelte4/dist/Login.js +0 -214
- package/examples/app-svelte4/dist/Login.js.map +0 -1
- package/examples/app-svelte4/dist/Query.js +0 -143
- package/examples/app-svelte4/dist/Query.js.map +0 -1
- package/examples/app-svelte4/dist/index.html +0 -11
- package/examples/app-svelte4/dist/main.js +0 -2
- package/examples/app-svelte4/dist/main.js.map +0 -1
- package/examples/app-svelte4/dist/main2.js +0 -2479
- package/examples/app-svelte4/dist/main2.js.map +0 -1
- package/examples/app-svelte4/package-lock.json +0 -776
- package/examples/app-svelte4/package.json +0 -23
- package/examples/app-svelte4/rollup.config.js +0 -56
- package/examples/app-svelte4/server.js +0 -115
- package/examples/app-svelte4/src/Admin.svelte +0 -3
- package/examples/app-svelte4/src/App.svelte +0 -56
- package/examples/app-svelte4/src/Article.svelte +0 -21
- package/examples/app-svelte4/src/Home.svelte +0 -28
- package/examples/app-svelte4/src/Login.svelte +0 -21
- package/examples/app-svelte4/src/data-source.js +0 -49
- package/examples/app-svelte4/src/main.js +0 -7
- package/examples/app-svelte4/src/store.js +0 -11
- package/examples/app-svelte4/tests/e2e.test.js +0 -129
- package/examples/app-svelte5/dist/assets/Admin-DoyP5Bto.js +0 -1
- package/examples/app-svelte5/dist/assets/Blog-seinfUgf.js +0 -1
- package/examples/app-svelte5/dist/assets/Post-DkdqlSq4.js +0 -1
- package/examples/app-svelte5/dist/assets/index-ADyOUHdb.js +0 -2
- package/examples/app-svelte5/dist/index.html +0 -14
- package/examples/app-svelte5/jsconfig.json +0 -17
- package/examples/app-svelte5/package-lock.json +0 -1183
- package/examples/app-svelte5/package.json +0 -24
- package/examples/app-svelte5/src/App.svelte +0 -65
- package/examples/app-svelte5/src/articles.js +0 -43
- package/examples/app-svelte5/src/main.js +0 -9
- package/examples/app-svelte5/src/pages/Blog.svelte +0 -18
- package/examples/app-svelte5/src/pages/Guide.svelte +0 -21
- package/examples/app-svelte5/src/pages/Home.svelte +0 -6
- package/examples/app-svelte5/src/pages/NotFound.svelte +0 -1
- package/examples/app-svelte5/src/pages/Post.svelte +0 -21
- package/examples/app-svelte5/svelte.config.js +0 -7
- package/examples/app-svelte5/tests/e2e.spec.js +0 -69
- package/jsconfig.json +0 -17
- package/src/index.d.ts +0 -48
- package/src/index.js +0 -19
- package/src/push.js +0 -19
- package/src/stores.js +0 -67
- /package/{examples/app-svelte4/src → example/pages}/NotFound.svelte +0 -0
- /package/{examples/app-svelte5/src → example}/vite-env.d.ts +0 -0
- /package/{examples/app-svelte5/playwright.config.js → playwright.config.js} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# svelte-spa-history-router
|
|
2
2
|
|
|
3
|
-
History base router for Svelte
|
|
3
|
+
History base router for [Svelte](https://svelte.dev/) SPA (Single Page Application).
|
|
4
|
+
|
|
5
|
+
> [!TIP]
|
|
6
|
+
> The offcial routing library of Svelte is [SvelteKit](https://svelte.dev/docs/kit/introduction). This library is intented to be used for small/simple project.
|
|
7
|
+
|
|
4
8
|
|
|
5
9
|
## Features
|
|
6
10
|
|
|
@@ -48,29 +52,30 @@ For example:
|
|
|
48
52
|
```
|
|
49
53
|
|
|
50
54
|
* `Routes` require a `routes` parameter.
|
|
51
|
-
* `routes` is a list of route objects. route object has `path
|
|
55
|
+
* `routes` is a list of route objects. route object has `path` property, and either `component` or `resolver` property.
|
|
52
56
|
|
|
53
57
|
* `path` can be a regular expression. `^` and `$` are automatically added when matching.
|
|
54
|
-
* `component` is a
|
|
55
|
-
* `resolver` is a function to determine component dynamically
|
|
58
|
+
* `component` is a Svelte component. there are no specific requirements for component.
|
|
59
|
+
* `resolver` is a function to determine component dynamically.
|
|
56
60
|
|
|
57
61
|
* Matching is simply performed in the order defined by `routes`.
|
|
58
62
|
|
|
59
|
-
###
|
|
63
|
+
### Path variable
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
Matched paramaters are passed to component as `params` property.
|
|
62
66
|
|
|
63
67
|
For example:
|
|
64
68
|
|
|
65
69
|
```html
|
|
66
70
|
# Article.svelte
|
|
67
71
|
|
|
68
|
-
<script>
|
|
69
|
-
|
|
70
|
-
</script>
|
|
72
|
+
<script lang="ts">
|
|
73
|
+
let { params }: { params: { postId: string } = $props();
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
75
|
+
const postId = $derived(parseInt(params.postId));
|
|
76
|
+
</script>
|
|
77
|
+
<div>
|
|
78
|
+
{ postId }
|
|
74
79
|
</div>
|
|
75
80
|
```
|
|
76
81
|
|
|
@@ -78,7 +83,7 @@ For example:
|
|
|
78
83
|
|
|
79
84
|
To navigate another page, `link` and `push` are available.
|
|
80
85
|
|
|
81
|
-
* `link` used with a `a` tag like below
|
|
86
|
+
* `link` is used with a `a` tag like below
|
|
82
87
|
|
|
83
88
|
```html
|
|
84
89
|
import { link } from 'svelte-spa-history-router';
|
|
@@ -86,12 +91,12 @@ import { link } from 'svelte-spa-history-router';
|
|
|
86
91
|
<a use:link href="/">Home</a>
|
|
87
92
|
```
|
|
88
93
|
|
|
89
|
-
* `push` used to navigate programatically
|
|
94
|
+
* `push` is used to navigate programatically
|
|
90
95
|
|
|
91
96
|
```html
|
|
92
97
|
import { push } from 'svelte-spa-history-router';
|
|
93
98
|
|
|
94
|
-
<button
|
|
99
|
+
<button onclick={ () => push('/') }>Go to Home</button>
|
|
95
100
|
```
|
|
96
101
|
|
|
97
102
|
### resolver
|
|
@@ -105,7 +110,7 @@ Example: code spliting (dynamic import)
|
|
|
105
110
|
import { Router } from 'svelte-spa-history-router';
|
|
106
111
|
|
|
107
112
|
const routes = [
|
|
108
|
-
{ path: '/', resolver:
|
|
113
|
+
{ path: '/', resolver: () => import("Home.svelte") },
|
|
109
114
|
];
|
|
110
115
|
</script>
|
|
111
116
|
<Router {routes}/>
|
|
@@ -114,18 +119,16 @@ Example: code spliting (dynamic import)
|
|
|
114
119
|
Example: dynamic routing and pass value to component props.
|
|
115
120
|
|
|
116
121
|
```html
|
|
117
|
-
<script>
|
|
122
|
+
<script lang="ts">
|
|
118
123
|
import { Router } from 'svelte-spa-history-router';
|
|
119
124
|
|
|
120
125
|
import Article from "./Article.svelte";
|
|
121
126
|
import NotFound from "./NotFound.svelte";
|
|
122
127
|
|
|
123
|
-
async function prefetchArticle(
|
|
124
|
-
const article = await getArticle(
|
|
128
|
+
async function prefetchArticle(params: Record<string, string>) {
|
|
129
|
+
const article = await getArticle(params.postId);
|
|
125
130
|
if (article) {
|
|
126
|
-
|
|
127
|
-
route.props.article = article;
|
|
128
|
-
return Article;
|
|
131
|
+
return { component: Article, props: { article } };
|
|
129
132
|
} else {
|
|
130
133
|
return NotFound;
|
|
131
134
|
}
|
|
@@ -141,13 +144,16 @@ Example: dynamic routing and pass value to component props.
|
|
|
141
144
|
Example: guard
|
|
142
145
|
|
|
143
146
|
```html
|
|
144
|
-
<script>
|
|
147
|
+
<script lang="ts">
|
|
145
148
|
import { Router, redirect } from 'svelte-spa-history-router';
|
|
146
149
|
|
|
147
150
|
import Admin from "./Admin.svelte";
|
|
148
151
|
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
|
|
153
|
+
let user: User = $state()
|
|
154
|
+
|
|
155
|
+
function adminGuard() {
|
|
156
|
+
if (!isAdmin(user)) {
|
|
151
157
|
return redirect("/");
|
|
152
158
|
}
|
|
153
159
|
return Admin;
|
|
@@ -163,20 +169,59 @@ Example: guard
|
|
|
163
169
|
|
|
164
170
|
(Added in v2.0.0)
|
|
165
171
|
|
|
166
|
-
|
|
172
|
+
(Changed resolver interface in v3.0.0-next.0)
|
|
173
|
+
|
|
174
|
+
### currentURL()
|
|
167
175
|
|
|
168
|
-
|
|
176
|
+
state to detect URL changes (including query string or hash)
|
|
169
177
|
|
|
170
178
|
```html
|
|
171
179
|
<script>
|
|
172
180
|
import { currentURL } from "svelte-spa-history-router";
|
|
173
181
|
|
|
174
|
-
|
|
182
|
+
let name = $derived(currentURL().searchParams.get("name") ?? "unknown");
|
|
175
183
|
</script>
|
|
176
184
|
<div>{ name }</div>
|
|
177
185
|
```
|
|
178
186
|
|
|
179
|
-
(Added in
|
|
187
|
+
(Added in v2.1.0)
|
|
188
|
+
|
|
189
|
+
(Replaced to svelte5 `$state()` in v3.0.0-next.0)
|
|
190
|
+
|
|
191
|
+
### Typing
|
|
192
|
+
|
|
193
|
+
svelte-spa-history-router provides `Route` type to check combination of component and props.
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
<script lang="ts">
|
|
197
|
+
import type { Route } from "svelte-spa-history-router"
|
|
198
|
+
|
|
199
|
+
// BlogPost requires article property
|
|
200
|
+
import type BlogPost from "./pages/BlogPost.svelte"
|
|
201
|
+
|
|
202
|
+
import Top from "./pages/Top.svelte"
|
|
203
|
+
|
|
204
|
+
const routes: [
|
|
205
|
+
Route<typeof Top>,
|
|
206
|
+
Route<typeof BlogPost | typeof NotFound>,
|
|
207
|
+
]: [
|
|
208
|
+
{ path: "/", component: Top },
|
|
209
|
+
{
|
|
210
|
+
path: "/blog/posts/(?<slug>.*)",
|
|
211
|
+
resolver: async (params: Record<"slug", string>) => {
|
|
212
|
+
const article = await getArticle(params.slug);
|
|
213
|
+
if (article) {
|
|
214
|
+
const component = (await import("./pages/BlogPost.svelte")).default;
|
|
215
|
+
return { component, props: { article } }
|
|
216
|
+
} else {
|
|
217
|
+
return NotFound;
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
</script>
|
|
223
|
+
|
|
224
|
+
(Added in v3.0.0-next.0)
|
|
180
225
|
|
|
181
226
|
### Full example:
|
|
182
227
|
|
|
@@ -184,6 +229,19 @@ store to detect URL changes (including query string or hash)
|
|
|
184
229
|
|
|
185
230
|
## ChangeLog
|
|
186
231
|
|
|
232
|
+
### 3.0.0-next.0
|
|
233
|
+
|
|
234
|
+
* *[Breaking change]* Drop Svelte4 support
|
|
235
|
+
|
|
236
|
+
* Remove stores of `routeParams` and `currentURL`
|
|
237
|
+
|
|
238
|
+
* *[Breaking change]* Change resolver interface
|
|
239
|
+
* Add `currentURL()` which is rewriten to use `$state()`
|
|
240
|
+
|
|
241
|
+
### 2.2.0
|
|
242
|
+
|
|
243
|
+
* Support Svelte5
|
|
244
|
+
|
|
187
245
|
### 2.2.0-next.1
|
|
188
246
|
|
|
189
247
|
* Fix component type on svelte5 [PR13](https://github.com/ykrods/svelte-spa-history-router/pull/13)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Route } from "svelte-spa-history-router"
|
|
3
|
+
import { Router, link, push, redirect } from "svelte-spa-history-router"
|
|
4
|
+
|
|
5
|
+
import type Admin from "./pages/Admin.svelte"
|
|
6
|
+
import type Blog from "./pages/Blog.svelte"
|
|
7
|
+
import type BlogPost from "./pages/BlogPost.svelte"
|
|
8
|
+
import type Query from "./pages/Query.svelte"
|
|
9
|
+
|
|
10
|
+
import IntParam from "./pages/IntParam.svelte"
|
|
11
|
+
import Message from "./pages/Message.svelte"
|
|
12
|
+
import NotFound from "./pages/NotFound.svelte"
|
|
13
|
+
import Params from "./pages/Params.svelte"
|
|
14
|
+
import Top from "./pages/Top.svelte"
|
|
15
|
+
|
|
16
|
+
import { getArticle } from "./lib/getArticle"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const routes: [
|
|
20
|
+
Route,
|
|
21
|
+
Route<typeof Params>,
|
|
22
|
+
Route<typeof IntParam>,
|
|
23
|
+
Route<typeof IntParam | typeof Message>,
|
|
24
|
+
Route<typeof Blog>,
|
|
25
|
+
Route<typeof BlogPost | typeof NotFound>,
|
|
26
|
+
Route<typeof Admin>,
|
|
27
|
+
Route<typeof Query>,
|
|
28
|
+
Route<typeof NotFound>,
|
|
29
|
+
] = [
|
|
30
|
+
{ path: "/", component: Top },
|
|
31
|
+
// path variable via params
|
|
32
|
+
{ path: "/params/(?<slug>.*)", component: Params },
|
|
33
|
+
// typed props
|
|
34
|
+
{
|
|
35
|
+
path: "/int-param/(?<num>\\d+)",
|
|
36
|
+
resolver: (params: Record<"num", string>) => ({
|
|
37
|
+
component: IntParam,
|
|
38
|
+
props: { num: parseInt(params.num) }
|
|
39
|
+
}),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
path: "/conditional/(?<arg>.+)",
|
|
43
|
+
resolver: (params: Record<"arg", string>) => {
|
|
44
|
+
const arg = parseInt(params.arg)
|
|
45
|
+
if (!Number.isNaN(arg)) {
|
|
46
|
+
return { component: IntParam, props: { num: arg }}
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
component: Message,
|
|
50
|
+
props: { message: `Unexpected param: ${params.arg}` }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
// spliting
|
|
55
|
+
{
|
|
56
|
+
path: "/blog",
|
|
57
|
+
resolver: () => import("./pages/Blog.svelte"),
|
|
58
|
+
},
|
|
59
|
+
// async resolver with props
|
|
60
|
+
// path variable with slash
|
|
61
|
+
// prefetch
|
|
62
|
+
// spliting
|
|
63
|
+
// return component
|
|
64
|
+
{
|
|
65
|
+
path: "/blog/posts/(?<slug>.*)",
|
|
66
|
+
resolver: async (params: Record<"slug", string>) => {
|
|
67
|
+
const article = await getArticle(params.slug);
|
|
68
|
+
if (article) {
|
|
69
|
+
const component = (await import("./pages/BlogPost.svelte")).default;
|
|
70
|
+
return { component, props: { article } }
|
|
71
|
+
} else {
|
|
72
|
+
return NotFound;
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
// guard
|
|
77
|
+
// redirect
|
|
78
|
+
{
|
|
79
|
+
path: "/admin",
|
|
80
|
+
resolver: () => {
|
|
81
|
+
if (user === "admin") {
|
|
82
|
+
return import("./pages/Admin.svelte");
|
|
83
|
+
} else {
|
|
84
|
+
return redirect("/");
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
path: "/query",
|
|
90
|
+
resolver: () => import("./pages/Query.svelte")
|
|
91
|
+
},
|
|
92
|
+
{ path: ".*", component: NotFound },
|
|
93
|
+
]
|
|
94
|
+
|
|
95
|
+
let user = $state("anonymous");
|
|
96
|
+
</script>
|
|
97
|
+
<main>
|
|
98
|
+
<header>
|
|
99
|
+
<nav>
|
|
100
|
+
<a use:link href="/">Top</a> |
|
|
101
|
+
<a use:link href="/params/foo/bar">params</a> |
|
|
102
|
+
<a use:link href="/int-param/3">int param</a> |
|
|
103
|
+
<a use:link href="/conditional/1">conditional (1)</a> |
|
|
104
|
+
<a use:link href="/conditional/a">conditional (a)</a> |
|
|
105
|
+
<a use:link href="/blog">blog</a> |
|
|
106
|
+
<a use:link href="/admin">admin</a> |
|
|
107
|
+
<a use:link href="/query">query</a> |
|
|
108
|
+
|
|
109
|
+
{#if user === "anonymous"}
|
|
110
|
+
<button id="login" onclick={() => { user = "admin" }}>Login</button>
|
|
111
|
+
{:else}
|
|
112
|
+
user: { user } <button onclick={() => { user = "anonymous"; push("/"); }}>Logout</button>
|
|
113
|
+
{/if}
|
|
114
|
+
</nav>
|
|
115
|
+
</header>
|
|
116
|
+
<Router {routes} />
|
|
117
|
+
</main>
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
<!
|
|
1
|
+
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>Vite + Svelte</title>
|
|
8
|
-
<!--app-head-->
|
|
7
|
+
<title>Vite + Svelte + TS</title>
|
|
9
8
|
</head>
|
|
10
9
|
<body>
|
|
11
|
-
<div id="app"
|
|
12
|
-
<script type="module" src="/
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/main.ts"></script>
|
|
13
12
|
</body>
|
|
14
13
|
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Article } from "../types"
|
|
2
|
+
|
|
3
|
+
import { getArticles } from "./getArticles"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export async function getArticle(id: string): Promise<Article | undefined> {
|
|
10
|
+
await sleep(50);
|
|
11
|
+
const articles = await getArticles();
|
|
12
|
+
return articles.find(a => a.id === id);
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Article } from "../types"
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const articles: Article[] = [
|
|
8
|
+
{
|
|
9
|
+
id: '2024/04/01/test-fragment',
|
|
10
|
+
title: 'test fragment',
|
|
11
|
+
date: "2024-04-01",
|
|
12
|
+
html: `<a id="top" href="#bottom">to bottom</a>
|
|
13
|
+
<div style="height:800px">spacer</div>
|
|
14
|
+
<a id="bottom" href="#top">to top</a>`,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: '2024/03/01/baz',
|
|
18
|
+
title: 'baz',
|
|
19
|
+
date: "2024-03-01",
|
|
20
|
+
html: `<p>baz!</p>`,
|
|
21
|
+
prev: '2024/02/01/bar',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: '2024/02/01/bar',
|
|
25
|
+
title: 'bar',
|
|
26
|
+
date: "2024-02-01",
|
|
27
|
+
html: `<p>bar!</p>`,
|
|
28
|
+
next: '2024/03/01/baz',
|
|
29
|
+
prev: '2024/01/01/foo',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: '2024/01/01/foo',
|
|
33
|
+
title: 'foo',
|
|
34
|
+
date: "2024-01-01",
|
|
35
|
+
html: `<p>foo!</p>`,
|
|
36
|
+
next: '2024/02/01/bar',
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export async function getArticles(): Promise<Article[]> {
|
|
41
|
+
await sleep(100);
|
|
42
|
+
return articles;
|
|
43
|
+
}
|
package/example/main.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { link } from "svelte-spa-history-router"
|
|
3
|
+
|
|
4
|
+
import { getArticles } from "../lib/getArticles"
|
|
5
|
+
</script>
|
|
6
|
+
<svelte:head>
|
|
7
|
+
<title>Blog</title>
|
|
8
|
+
</svelte:head>
|
|
9
|
+
<main class="blog">
|
|
10
|
+
{#await getArticles() then articles}
|
|
11
|
+
<h1>Blog</h1>
|
|
12
|
+
<ul>
|
|
13
|
+
{#each articles as article}
|
|
14
|
+
<li>{ article.date } - <a use:link href={`/blog/posts/${article.id}`}>{ article.title }</a></li>
|
|
15
|
+
{/each}
|
|
16
|
+
<li>2024-01-01 - <a use:link href="/blog/posts/2024/01/01/deleted">deleted</a></li>
|
|
17
|
+
</ul>
|
|
18
|
+
{/await}
|
|
19
|
+
</main>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Article } from "../types"
|
|
3
|
+
|
|
4
|
+
import { link } from "svelte-spa-history-router"
|
|
5
|
+
|
|
6
|
+
let { article }: { article: Article } = $props()
|
|
7
|
+
</script>
|
|
8
|
+
<svelte:head>
|
|
9
|
+
<title>{ article.title }</title>
|
|
10
|
+
</svelte:head>
|
|
11
|
+
<main class="post">
|
|
12
|
+
<h1>{ article.title }</h1>
|
|
13
|
+
<div>{ article.date }</div>
|
|
14
|
+
<div>{@html article.html }</div>
|
|
15
|
+
<div>
|
|
16
|
+
{#if article.prev }
|
|
17
|
+
<a use:link href={`/blog/posts/${article.prev}`}>prev</a>
|
|
18
|
+
{/if}
|
|
19
|
+
{#if article.next }
|
|
20
|
+
<a use:link href={`/blog/posts/${article.next}`}>next</a>
|
|
21
|
+
{/if}
|
|
22
|
+
</div>
|
|
23
|
+
</main>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
let {
|
|
3
|
+
num
|
|
4
|
+
}: {
|
|
5
|
+
num: number
|
|
6
|
+
} = $props();
|
|
7
|
+
</script>
|
|
8
|
+
<svelte:head>
|
|
9
|
+
<title>int param</title>
|
|
10
|
+
</svelte:head>
|
|
11
|
+
<main class="int-param">
|
|
12
|
+
<p class="value">value: { num }</p>
|
|
13
|
+
<p class="twice">twice: { num * 2 }</p>
|
|
14
|
+
</main>
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
import { link, currentURL } from "svelte-spa-history-router";
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
let name = $derived(currentURL().searchParams.get("name") ?? 'unknown');
|
|
5
6
|
</script>
|
|
6
7
|
<svelte:head>
|
|
7
8
|
<title>query</title>
|
|
8
9
|
</svelte:head>
|
|
9
|
-
<
|
|
10
|
+
<main class="query">
|
|
10
11
|
<p>name: <span id="name">{ name }</span></p>
|
|
11
12
|
<a use:link href="/query?name=foo">foo</a>
|
|
12
13
|
<a use:link href="/query?name=bar">bar</a>
|
|
13
|
-
</
|
|
14
|
+
</main>
|
package/example/types.ts
ADDED
package/package.json
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-spa-history-router",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-next.1",
|
|
4
4
|
"description": "History base router for Svelte SPA",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "src/index.
|
|
7
|
-
"svelte": "src/index.
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"svelte": "src/index.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"svelte": "./src/index.
|
|
10
|
+
"svelte": "./src/index.ts"
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
|
-
"types": "src/index.d.ts",
|
|
14
13
|
"scripts": {
|
|
15
|
-
"dev": "
|
|
16
|
-
"test": "
|
|
17
|
-
"
|
|
18
|
-
"check": "npx svelte-check"
|
|
14
|
+
"dev": "vite",
|
|
15
|
+
"test": "playwright test",
|
|
16
|
+
"check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
|
|
19
17
|
},
|
|
20
18
|
"peerDependencies": {
|
|
21
|
-
"svelte": "
|
|
19
|
+
"svelte": ">5.0.0"
|
|
22
20
|
},
|
|
23
21
|
"devDependencies": {
|
|
24
|
-
"
|
|
25
|
-
"svelte": "
|
|
22
|
+
"@playwright/test": "1.49.1",
|
|
23
|
+
"@sveltejs/vite-plugin-svelte": "5.0.3",
|
|
24
|
+
"@tsconfig/svelte": "5.0.4",
|
|
25
|
+
"playwright": "1.49.1",
|
|
26
|
+
"svelte": "5.16.0",
|
|
27
|
+
"svelte-check": "4.1.1",
|
|
28
|
+
"typescript": "5.7.2",
|
|
29
|
+
"vite": "6.0.6"
|
|
26
30
|
},
|
|
27
31
|
"author": "ykrods",
|
|
28
32
|
"license": "MIT",
|