svelte-spa-history-router 2.2.0 → 3.0.0-next.2
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 +72 -36
- 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 -845
- 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/jsconfig.json +0 -17
- package/examples/app-svelte5/package-lock.json +0 -1258
- package/examples/app-svelte5/package.json +0 -23
- 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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
History base router for [Svelte](https://svelte.dev/) SPA (Single Page Application).
|
|
4
4
|
|
|
5
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 project.
|
|
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
7
|
|
|
8
8
|
|
|
9
9
|
## Features
|
|
@@ -52,17 +52,17 @@ For example:
|
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
* `Routes` require a `routes` parameter.
|
|
55
|
-
* `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.
|
|
56
56
|
|
|
57
57
|
* `path` can be a regular expression. `^` and `$` are automatically added when matching.
|
|
58
|
-
* `component` is a
|
|
59
|
-
* `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.
|
|
60
60
|
|
|
61
61
|
* Matching is simply performed in the order defined by `routes`.
|
|
62
62
|
|
|
63
|
-
###
|
|
63
|
+
### Path variable
|
|
64
64
|
|
|
65
|
-
Matched paramaters
|
|
65
|
+
Matched paramaters are passed to component as `params` property.
|
|
66
66
|
|
|
67
67
|
For example:
|
|
68
68
|
|
|
@@ -70,7 +70,7 @@ For example:
|
|
|
70
70
|
# Article.svelte
|
|
71
71
|
|
|
72
72
|
<script lang="ts">
|
|
73
|
-
let { params } = $props();
|
|
73
|
+
let { params }: { params: { postId: string } = $props();
|
|
74
74
|
|
|
75
75
|
const postId = $derived(parseInt(params.postId));
|
|
76
76
|
</script>
|
|
@@ -79,25 +79,11 @@ For example:
|
|
|
79
79
|
</div>
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
[Additional] For svelte4, `routeParams` is a store to contain matched value to current route.
|
|
83
|
-
|
|
84
|
-
```html
|
|
85
|
-
# Article.svelte
|
|
86
|
-
|
|
87
|
-
<script>
|
|
88
|
-
import { routeParams } from 'svelte-spa-history-router';
|
|
89
|
-
</script>
|
|
90
|
-
|
|
91
|
-
<div class="article">
|
|
92
|
-
postId: {$routeParams.postId}
|
|
93
|
-
</div>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
82
|
### Navigation methods
|
|
97
83
|
|
|
98
84
|
To navigate another page, `link` and `push` are available.
|
|
99
85
|
|
|
100
|
-
* `link` used with a `a` tag like below
|
|
86
|
+
* `link` is used with a `a` tag like below
|
|
101
87
|
|
|
102
88
|
```html
|
|
103
89
|
import { link } from 'svelte-spa-history-router';
|
|
@@ -105,12 +91,12 @@ import { link } from 'svelte-spa-history-router';
|
|
|
105
91
|
<a use:link href="/">Home</a>
|
|
106
92
|
```
|
|
107
93
|
|
|
108
|
-
* `push` used to navigate programatically
|
|
94
|
+
* `push` is used to navigate programatically
|
|
109
95
|
|
|
110
96
|
```html
|
|
111
97
|
import { push } from 'svelte-spa-history-router';
|
|
112
98
|
|
|
113
|
-
<button
|
|
99
|
+
<button onclick={ () => push('/') }>Go to Home</button>
|
|
114
100
|
```
|
|
115
101
|
|
|
116
102
|
### resolver
|
|
@@ -133,18 +119,16 @@ Example: code spliting (dynamic import)
|
|
|
133
119
|
Example: dynamic routing and pass value to component props.
|
|
134
120
|
|
|
135
121
|
```html
|
|
136
|
-
<script>
|
|
122
|
+
<script lang="ts">
|
|
137
123
|
import { Router } from 'svelte-spa-history-router';
|
|
138
124
|
|
|
139
125
|
import Article from "./Article.svelte";
|
|
140
126
|
import NotFound from "./NotFound.svelte";
|
|
141
127
|
|
|
142
|
-
async function prefetchArticle(
|
|
128
|
+
async function prefetchArticle(params: Record<string, string>) {
|
|
143
129
|
const article = await getArticle(params.postId);
|
|
144
130
|
if (article) {
|
|
145
|
-
|
|
146
|
-
props.article = article;
|
|
147
|
-
return Article;
|
|
131
|
+
return { component: Article, props: { article } };
|
|
148
132
|
} else {
|
|
149
133
|
return NotFound;
|
|
150
134
|
}
|
|
@@ -160,13 +144,16 @@ Example: dynamic routing and pass value to component props.
|
|
|
160
144
|
Example: guard
|
|
161
145
|
|
|
162
146
|
```html
|
|
163
|
-
<script>
|
|
147
|
+
<script lang="ts">
|
|
164
148
|
import { Router, redirect } from 'svelte-spa-history-router';
|
|
165
149
|
|
|
166
150
|
import Admin from "./Admin.svelte";
|
|
167
151
|
|
|
168
|
-
|
|
169
|
-
|
|
152
|
+
|
|
153
|
+
let user: User = $state()
|
|
154
|
+
|
|
155
|
+
function adminGuard() {
|
|
156
|
+
if (!isAdmin(user)) {
|
|
170
157
|
return redirect("/");
|
|
171
158
|
}
|
|
172
159
|
return Admin;
|
|
@@ -182,20 +169,60 @@ Example: guard
|
|
|
182
169
|
|
|
183
170
|
(Added in v2.0.0)
|
|
184
171
|
|
|
185
|
-
|
|
172
|
+
(Changed resolver interface in v3.0.0-next.1)
|
|
173
|
+
|
|
174
|
+
### currentURL()
|
|
186
175
|
|
|
187
|
-
|
|
176
|
+
state to detect URL changes (including query string or hash)
|
|
188
177
|
|
|
189
178
|
```html
|
|
190
179
|
<script>
|
|
191
180
|
import { currentURL } from "svelte-spa-history-router";
|
|
192
181
|
|
|
193
|
-
|
|
182
|
+
let name = $derived(currentURL().searchParams.get("name") ?? "unknown");
|
|
194
183
|
</script>
|
|
195
184
|
<div>{ name }</div>
|
|
196
185
|
```
|
|
197
186
|
|
|
198
|
-
(Added in
|
|
187
|
+
(Added in v2.1.0)
|
|
188
|
+
|
|
189
|
+
(Replaced to svelte5 `$state()` in v3.0.0-next.1)
|
|
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
|
+
|
|
225
|
+
(Added in v3.0.0-next.1)
|
|
199
226
|
|
|
200
227
|
### Full example:
|
|
201
228
|
|
|
@@ -203,6 +230,15 @@ store to detect URL changes (including query string or hash)
|
|
|
203
230
|
|
|
204
231
|
## ChangeLog
|
|
205
232
|
|
|
233
|
+
### 3.0.0-next.1
|
|
234
|
+
|
|
235
|
+
* *[Breaking change]* Drop Svelte4 support
|
|
236
|
+
|
|
237
|
+
* Remove stores of `routeParams` and `currentURL`
|
|
238
|
+
|
|
239
|
+
* *[Breaking change]* Change resolver interface
|
|
240
|
+
* Add `currentURL()` which is rewriten to use `$state()`
|
|
241
|
+
|
|
206
242
|
### 2.2.0
|
|
207
243
|
|
|
208
244
|
* Support Svelte5
|
|
@@ -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.2",
|
|
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",
|