toiljs 0.0.12 → 0.0.15
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/README.md +1 -1
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/index.js +2926 -191
- package/build/client/.tsbuildinfo +1 -1
- package/build/client/head/metadata.d.ts +3 -1
- package/build/client/head/metadata.js +8 -0
- package/build/client/index.d.ts +4 -4
- package/build/client/index.js +2 -2
- package/build/client/navigation/navigation.d.ts +2 -0
- package/build/client/navigation/navigation.js +9 -1
- package/build/client/routing/loader.d.ts +2 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/config.d.ts +2 -0
- package/build/compiler/config.js +1 -0
- package/build/compiler/generate.js +10 -1
- package/build/compiler/index.js +2 -0
- package/build/compiler/prerender.js +1 -0
- package/build/compiler/seo.d.ts +1 -1
- package/build/compiler/seo.js +3 -2
- package/build/compiler/ssg.d.ts +5 -0
- package/build/compiler/ssg.js +90 -0
- package/examples/basic/client/routes/search.tsx +61 -61
- package/package.json +4 -3
- package/src/client/head/metadata.ts +112 -94
- package/src/client/index.ts +89 -79
- package/src/client/navigation/navigation.ts +235 -215
- package/src/client/routing/loader.ts +10 -0
- package/src/client/search/search.ts +189 -189
- package/src/client/search/use-page-search.ts +73 -73
- package/src/compiler/config.ts +182 -173
- package/src/compiler/generate.ts +394 -378
- package/src/compiler/index.ts +3 -0
- package/src/compiler/pages.ts +2 -2
- package/src/compiler/prerender.ts +156 -152
- package/src/compiler/seo.ts +390 -381
- package/src/compiler/ssg.ts +126 -0
- package/test/dom/error-overlay.test.tsx +44 -44
- package/test/dom/router-loading.test.tsx +1 -1
- package/test/dom/use-metadata.test.tsx +58 -0
- package/test/seo.test.ts +164 -164
- package/test/ssg.test.ts +36 -0
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
|
|
3
|
-
export const metadata: Toil.Metadata = {
|
|
4
|
-
title: 'Search',
|
|
5
|
-
description: 'Search every page by its metadata and jump straight to it.',
|
|
6
|
-
keywords: ['search', 'find', 'pages', 'metadata']
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
// A tiny site-wide search box. `usePageSearch` queries the compiler-built index of every page's
|
|
10
|
-
// metadata (title/description/keywords/OpenGraph + static `searchHints` on dynamic routes), returns
|
|
11
|
-
// ranked matches with their route `path`, and `goTo` navigates to whichever one you pick.
|
|
12
|
-
export default function Search() {
|
|
13
|
-
const [query, setQuery] = useState('');
|
|
14
|
-
const { results, pages, goTo } = Toil.usePageSearch(query, { includeDynamic: true });
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<main>
|
|
18
|
-
<h1>Search</h1>
|
|
19
|
-
<p>
|
|
20
|
-
Type to search across the metadata of all {pages.length} pages
|
|
21
|
-
OpenGraph. Indexed at build by <code>client/routes/*</code>.
|
|
22
|
-
</p>
|
|
23
|
-
|
|
24
|
-
<input
|
|
25
|
-
type="search"
|
|
26
|
-
value={query}
|
|
27
|
-
onChange={(e) => {
|
|
28
|
-
setQuery(e.target.value);
|
|
29
|
-
}}
|
|
30
|
-
placeholder="Search pages… (try “blog”, “features”, “started”)"
|
|
31
|
-
aria-label="Search pages"
|
|
32
|
-
autoFocus
|
|
33
|
-
style={{ width: '100%', padding: '0.6rem 0.8rem', fontSize: '1rem' }}
|
|
34
|
-
/>
|
|
35
|
-
|
|
36
|
-
{query.trim() !== '' && (
|
|
37
|
-
<ul style={{ listStyle: 'none', padding: 0, marginTop: '1rem' }}>
|
|
38
|
-
{results.length === 0 && <li>No pages match “{query}”.</li>}
|
|
39
|
-
{results.map((r) => (
|
|
40
|
-
<li key={r.page.path} style={{ marginBottom: '0.75rem' }}>
|
|
41
|
-
<button
|
|
42
|
-
type="button"
|
|
43
|
-
onClick={() => {
|
|
44
|
-
goTo(r);
|
|
45
|
-
}}
|
|
46
|
-
disabled={r.page.dynamic}
|
|
47
|
-
title={r.page.dynamic ? 'Dynamic route
|
|
48
|
-
style={{ textAlign: 'left', cursor: r.page.dynamic ? 'default' : 'pointer' }}>
|
|
49
|
-
<strong>{r.page.metadata.title ?? r.page.path}</strong> <code>{r.page.path}</code>
|
|
50
|
-
{r.page.metadata.description !== undefined && <div>{r.page.metadata.description}</div>}
|
|
51
|
-
<small>
|
|
52
|
-
score {r.score.toFixed(1)} · matched {r.matches.join(', ')}
|
|
53
|
-
</small>
|
|
54
|
-
</button>
|
|
55
|
-
</li>
|
|
56
|
-
))}
|
|
57
|
-
</ul>
|
|
58
|
-
)}
|
|
59
|
-
</main>
|
|
60
|
-
);
|
|
61
|
-
}
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export const metadata: Toil.Metadata = {
|
|
4
|
+
title: 'Search',
|
|
5
|
+
description: 'Search every page by its metadata and jump straight to it.',
|
|
6
|
+
keywords: ['search', 'find', 'pages', 'metadata']
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// A tiny site-wide search box. `usePageSearch` queries the compiler-built index of every page's
|
|
10
|
+
// metadata (title/description/keywords/OpenGraph + static `searchHints` on dynamic routes), returns
|
|
11
|
+
// ranked matches with their route `path`, and `goTo` navigates to whichever one you pick.
|
|
12
|
+
export default function Search() {
|
|
13
|
+
const [query, setQuery] = useState('');
|
|
14
|
+
const { results, pages, goTo } = Toil.usePageSearch(query, { includeDynamic: true });
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<main>
|
|
18
|
+
<h1>Search</h1>
|
|
19
|
+
<p>
|
|
20
|
+
Type to search across the metadata of all {pages.length} pages, title, description, keywords, and
|
|
21
|
+
OpenGraph. Indexed at build by <code>client/routes/*</code>.
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<input
|
|
25
|
+
type="search"
|
|
26
|
+
value={query}
|
|
27
|
+
onChange={(e) => {
|
|
28
|
+
setQuery(e.target.value);
|
|
29
|
+
}}
|
|
30
|
+
placeholder="Search pages… (try “blog”, “features”, “started”)"
|
|
31
|
+
aria-label="Search pages"
|
|
32
|
+
autoFocus
|
|
33
|
+
style={{ width: '100%', padding: '0.6rem 0.8rem', fontSize: '1rem' }}
|
|
34
|
+
/>
|
|
35
|
+
|
|
36
|
+
{query.trim() !== '' && (
|
|
37
|
+
<ul style={{ listStyle: 'none', padding: 0, marginTop: '1rem' }}>
|
|
38
|
+
{results.length === 0 && <li>No pages match “{query}”.</li>}
|
|
39
|
+
{results.map((r) => (
|
|
40
|
+
<li key={r.page.path} style={{ marginBottom: '0.75rem' }}>
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
onClick={() => {
|
|
44
|
+
goTo(r);
|
|
45
|
+
}}
|
|
46
|
+
disabled={r.page.dynamic}
|
|
47
|
+
title={r.page.dynamic ? 'Dynamic route, needs params to open' : undefined}
|
|
48
|
+
style={{ textAlign: 'left', cursor: r.page.dynamic ? 'default' : 'pointer' }}>
|
|
49
|
+
<strong>{r.page.metadata.title ?? r.page.path}</strong> <code>{r.page.path}</code>
|
|
50
|
+
{r.page.metadata.description !== undefined && <div>{r.page.metadata.description}</div>}
|
|
51
|
+
<small>
|
|
52
|
+
score {r.score.toFixed(1)} · matched {r.matches.join(', ')}
|
|
53
|
+
</small>
|
|
54
|
+
</button>
|
|
55
|
+
</li>
|
|
56
|
+
))}
|
|
57
|
+
</ul>
|
|
58
|
+
)}
|
|
59
|
+
</main>
|
|
60
|
+
);
|
|
61
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toiljs",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.15",
|
|
5
5
|
"author": "Dacely",
|
|
6
6
|
"description": "The modern React framework: a file-based React frontend and a ToilScript-compiled WebAssembly backend.",
|
|
7
7
|
"engines": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"build:io": "tsc -p tsconfig.io.json",
|
|
78
78
|
"build:backend": "tsc -p tsconfig.backend.json",
|
|
79
79
|
"build:compiler": "tsc -p tsconfig.compiler.json",
|
|
80
|
-
"build:cli": "tsc -p tsconfig.cli.json",
|
|
80
|
+
"build:cli": "tsc -p tsconfig.cli.json --noEmit && esbuild src/cli/index.ts --bundle --platform=node --format=esm --outfile=build/cli/index.js --external:toiljs/*",
|
|
81
81
|
"build:server": "toilscript --target release",
|
|
82
82
|
"test": "vitest run --coverage",
|
|
83
83
|
"test:watch": "vitest",
|
|
@@ -94,7 +94,6 @@
|
|
|
94
94
|
"@btc-vision/as-bignum": "^1.0.0",
|
|
95
95
|
"@btc-vision/as-loader": "^0.0.0",
|
|
96
96
|
"@btc-vision/hyper-express": "^6.17.4",
|
|
97
|
-
"@clack/prompts": "^1.5.0",
|
|
98
97
|
"@eslint-react/eslint-plugin": "^5.8.8",
|
|
99
98
|
"@eslint/js": "^10.0.1",
|
|
100
99
|
"@typescript-eslint/utils": "^8.60.0",
|
|
@@ -118,6 +117,7 @@
|
|
|
118
117
|
},
|
|
119
118
|
"devDependencies": {
|
|
120
119
|
"@babel/core": "^7.29.7",
|
|
120
|
+
"@clack/prompts": "^1.5.0",
|
|
121
121
|
"@babel/preset-env": "^7.29.7",
|
|
122
122
|
"@babel/preset-typescript": "^7.29.7",
|
|
123
123
|
"@btc-vision/as-covers-assembly": "^0.4.5",
|
|
@@ -133,6 +133,7 @@
|
|
|
133
133
|
"@types/react-dom": "^19.2.3",
|
|
134
134
|
"@vitest/coverage-v8": "^4.1.7",
|
|
135
135
|
"@vitest/ui": "^4.1.7",
|
|
136
|
+
"esbuild": "^0.28.0",
|
|
136
137
|
"eslint": "^10.4.1",
|
|
137
138
|
"jsdom": "^29.1.1",
|
|
138
139
|
"micromatch": "^4.0.8",
|
|
@@ -1,94 +1,112 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Route metadata, the declarative SEO counterpart to `useHead`/`<Head>`. A route file may
|
|
3
|
-
* `export const metadata` (static) or `export const generateMetadata` (dynamic, using its loader
|
|
4
|
-
* data); the compiler-driven loader resolves it to a {@link HeadSpec} that the router applies as the
|
|
5
|
-
* route's baseline head (component-level `useHead`/`<Head>` still compose on top and can override).
|
|
6
|
-
*/
|
|
7
|
-
import type
|
|
8
|
-
import type { RouteParams } from '../routing/match.js';
|
|
9
|
-
|
|
10
|
-
/** OpenGraph fields, expanded to `og:*` meta tags. */
|
|
11
|
-
export interface OpenGraph {
|
|
12
|
-
readonly title?: string;
|
|
13
|
-
readonly description?: string;
|
|
14
|
-
readonly type?: string;
|
|
15
|
-
readonly url?: string;
|
|
16
|
-
readonly image?: string;
|
|
17
|
-
readonly siteName?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/** A route's metadata. Convenience fields expand to the right `<meta>`/`<link>` tags. */
|
|
21
|
-
export interface Metadata {
|
|
22
|
-
/** Document title. */
|
|
23
|
-
readonly title?: string;
|
|
24
|
-
/** Template applied to the title (`%s` = the title), e.g. `'%s · toiljs'`. */
|
|
25
|
-
readonly titleTemplate?: string;
|
|
26
|
-
/** `<meta name="description">`. */
|
|
27
|
-
readonly description?: string;
|
|
28
|
-
/** `<meta name="keywords">`, joined with `, ` if an array. */
|
|
29
|
-
readonly keywords?: string | readonly string[];
|
|
30
|
-
/** `<link rel="canonical">`. */
|
|
31
|
-
readonly canonical?: string;
|
|
32
|
-
/** `<meta name="robots">`, e.g. `'noindex, nofollow'`. */
|
|
33
|
-
readonly robots?: string;
|
|
34
|
-
/** `<meta name="theme-color">`. */
|
|
35
|
-
readonly themeColor?: string;
|
|
36
|
-
/** OpenGraph (`og:*`) tags. */
|
|
37
|
-
readonly openGraph?: OpenGraph;
|
|
38
|
-
/** Escape hatch: extra raw `<meta>` tags. */
|
|
39
|
-
readonly meta?: readonly MetaTag[];
|
|
40
|
-
/** Escape hatch: extra raw `<link>` tags. */
|
|
41
|
-
readonly link?: readonly LinkTag[];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Arguments passed to {@link GenerateMetadata}: route params, query, and the loader's data. */
|
|
45
|
-
export interface GenerateMetadataArgs<T = unknown> {
|
|
46
|
-
readonly params: RouteParams;
|
|
47
|
-
readonly searchParams: URLSearchParams;
|
|
48
|
-
readonly data: T;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** A route's `export const generateMetadata`, dynamic metadata derived from params/query/loader data. */
|
|
52
|
-
export type GenerateMetadata<T = unknown> = (
|
|
53
|
-
args: GenerateMetadataArgs<T>,
|
|
54
|
-
) => Metadata | Promise<Metadata>;
|
|
55
|
-
|
|
56
|
-
/** Expands a {@link Metadata} into a {@link HeadSpec} (title + concrete meta/link tags). */
|
|
57
|
-
export function resolveMetadata(metadata: Metadata): HeadSpec {
|
|
58
|
-
const meta: MetaTag[] = [];
|
|
59
|
-
if (metadata.description !== undefined) {
|
|
60
|
-
meta.push({ name: 'description', content: metadata.description });
|
|
61
|
-
}
|
|
62
|
-
if (metadata.keywords !== undefined) {
|
|
63
|
-
const content =
|
|
64
|
-
typeof metadata.keywords === 'string'
|
|
65
|
-
? metadata.keywords
|
|
66
|
-
: metadata.keywords.join(', ');
|
|
67
|
-
meta.push({ name: 'keywords', content });
|
|
68
|
-
}
|
|
69
|
-
if (metadata.robots !== undefined) meta.push({ name: 'robots', content: metadata.robots });
|
|
70
|
-
if (metadata.themeColor !== undefined) {
|
|
71
|
-
meta.push({ name: 'theme-color', content: metadata.themeColor });
|
|
72
|
-
}
|
|
73
|
-
const og = metadata.openGraph;
|
|
74
|
-
if (og) {
|
|
75
|
-
const pairs: readonly [string, string | undefined][] = [
|
|
76
|
-
['og:title', og.title],
|
|
77
|
-
['og:description', og.description],
|
|
78
|
-
['og:type', og.type],
|
|
79
|
-
['og:url', og.url],
|
|
80
|
-
['og:image', og.image],
|
|
81
|
-
['og:site_name', og.siteName],
|
|
82
|
-
];
|
|
83
|
-
for (const [property, content] of pairs) {
|
|
84
|
-
if (content !== undefined) meta.push({ property, content });
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (metadata.meta) meta.push(...metadata.meta);
|
|
88
|
-
|
|
89
|
-
const link: LinkTag[] = [];
|
|
90
|
-
if (metadata.canonical !== undefined) link.push({ rel: 'canonical', href: metadata.canonical });
|
|
91
|
-
if (metadata.link) link.push(...metadata.link);
|
|
92
|
-
|
|
93
|
-
return { title: metadata.title, titleTemplate: metadata.titleTemplate, meta, link };
|
|
94
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Route metadata, the declarative SEO counterpart to `useHead`/`<Head>`. A route file may
|
|
3
|
+
* `export const metadata` (static) or `export const generateMetadata` (dynamic, using its loader
|
|
4
|
+
* data); the compiler-driven loader resolves it to a {@link HeadSpec} that the router applies as the
|
|
5
|
+
* route's baseline head (component-level `useHead`/`<Head>` still compose on top and can override).
|
|
6
|
+
*/
|
|
7
|
+
import { useHead, type HeadSpec, type LinkTag, type MetaTag } from './head.js';
|
|
8
|
+
import type { RouteParams } from '../routing/match.js';
|
|
9
|
+
|
|
10
|
+
/** OpenGraph fields, expanded to `og:*` meta tags. */
|
|
11
|
+
export interface OpenGraph {
|
|
12
|
+
readonly title?: string;
|
|
13
|
+
readonly description?: string;
|
|
14
|
+
readonly type?: string;
|
|
15
|
+
readonly url?: string;
|
|
16
|
+
readonly image?: string;
|
|
17
|
+
readonly siteName?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** A route's metadata. Convenience fields expand to the right `<meta>`/`<link>` tags. */
|
|
21
|
+
export interface Metadata {
|
|
22
|
+
/** Document title. */
|
|
23
|
+
readonly title?: string;
|
|
24
|
+
/** Template applied to the title (`%s` = the title), e.g. `'%s · toiljs'`. */
|
|
25
|
+
readonly titleTemplate?: string;
|
|
26
|
+
/** `<meta name="description">`. */
|
|
27
|
+
readonly description?: string;
|
|
28
|
+
/** `<meta name="keywords">`, joined with `, ` if an array. */
|
|
29
|
+
readonly keywords?: string | readonly string[];
|
|
30
|
+
/** `<link rel="canonical">`. */
|
|
31
|
+
readonly canonical?: string;
|
|
32
|
+
/** `<meta name="robots">`, e.g. `'noindex, nofollow'`. */
|
|
33
|
+
readonly robots?: string;
|
|
34
|
+
/** `<meta name="theme-color">`. */
|
|
35
|
+
readonly themeColor?: string;
|
|
36
|
+
/** OpenGraph (`og:*`) tags. */
|
|
37
|
+
readonly openGraph?: OpenGraph;
|
|
38
|
+
/** Escape hatch: extra raw `<meta>` tags. */
|
|
39
|
+
readonly meta?: readonly MetaTag[];
|
|
40
|
+
/** Escape hatch: extra raw `<link>` tags. */
|
|
41
|
+
readonly link?: readonly LinkTag[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Arguments passed to {@link GenerateMetadata}: route params, query, and the loader's data. */
|
|
45
|
+
export interface GenerateMetadataArgs<T = unknown> {
|
|
46
|
+
readonly params: RouteParams;
|
|
47
|
+
readonly searchParams: URLSearchParams;
|
|
48
|
+
readonly data: T;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** A route's `export const generateMetadata`, dynamic metadata derived from params/query/loader data. */
|
|
52
|
+
export type GenerateMetadata<T = unknown> = (
|
|
53
|
+
args: GenerateMetadataArgs<T>,
|
|
54
|
+
) => Metadata | Promise<Metadata>;
|
|
55
|
+
|
|
56
|
+
/** Expands a {@link Metadata} into a {@link HeadSpec} (title + concrete meta/link tags). */
|
|
57
|
+
export function resolveMetadata(metadata: Metadata): HeadSpec {
|
|
58
|
+
const meta: MetaTag[] = [];
|
|
59
|
+
if (metadata.description !== undefined) {
|
|
60
|
+
meta.push({ name: 'description', content: metadata.description });
|
|
61
|
+
}
|
|
62
|
+
if (metadata.keywords !== undefined) {
|
|
63
|
+
const content =
|
|
64
|
+
typeof metadata.keywords === 'string'
|
|
65
|
+
? metadata.keywords
|
|
66
|
+
: metadata.keywords.join(', ');
|
|
67
|
+
meta.push({ name: 'keywords', content });
|
|
68
|
+
}
|
|
69
|
+
if (metadata.robots !== undefined) meta.push({ name: 'robots', content: metadata.robots });
|
|
70
|
+
if (metadata.themeColor !== undefined) {
|
|
71
|
+
meta.push({ name: 'theme-color', content: metadata.themeColor });
|
|
72
|
+
}
|
|
73
|
+
const og = metadata.openGraph;
|
|
74
|
+
if (og) {
|
|
75
|
+
const pairs: readonly [string, string | undefined][] = [
|
|
76
|
+
['og:title', og.title],
|
|
77
|
+
['og:description', og.description],
|
|
78
|
+
['og:type', og.type],
|
|
79
|
+
['og:url', og.url],
|
|
80
|
+
['og:image', og.image],
|
|
81
|
+
['og:site_name', og.siteName],
|
|
82
|
+
];
|
|
83
|
+
for (const [property, content] of pairs) {
|
|
84
|
+
if (content !== undefined) meta.push({ property, content });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (metadata.meta) meta.push(...metadata.meta);
|
|
88
|
+
|
|
89
|
+
const link: LinkTag[] = [];
|
|
90
|
+
if (metadata.canonical !== undefined) link.push({ rel: 'canonical', href: metadata.canonical });
|
|
91
|
+
if (metadata.link) link.push(...metadata.link);
|
|
92
|
+
|
|
93
|
+
return { title: metadata.title, titleTemplate: metadata.titleTemplate, meta, link };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Applies a route-style {@link Metadata} object from inside any component for that component's
|
|
98
|
+
* lifetime, reverting on unmount. The runtime counterpart of a route's `metadata` export, for
|
|
99
|
+
* content that isn't itself a route file (a rendered article, a widget, ...). Composes through the
|
|
100
|
+
* head manager like {@link useHead}; a route's own `metadata` (applied last) still wins for keys it
|
|
101
|
+
* sets, so this fills in for routes that declare none. Resolved fresh each render, the head manager
|
|
102
|
+
* dedupes by value, so passing a computed object is fine.
|
|
103
|
+
*/
|
|
104
|
+
export function useMetadata(metadata: Metadata): void {
|
|
105
|
+
useHead(resolveMetadata(metadata));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Declarative form of {@link useMetadata}: `<Metadata title="…" openGraph={…} />`. Renders nothing. */
|
|
109
|
+
export function Metadata(props: Metadata): null {
|
|
110
|
+
useMetadata(props);
|
|
111
|
+
return null;
|
|
112
|
+
}
|
package/src/client/index.ts
CHANGED
|
@@ -1,79 +1,89 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* toiljs client runtime, published as `toiljs/client`. Re-exports the router (mount/Router/Link),
|
|
3
|
-
* navigation hooks, prefetching, and the route types consumed by the compiler-generated entry.
|
|
4
|
-
* Zero imports needed in user route files beyond this package.
|
|
5
|
-
*
|
|
6
|
-
* Internals are split by concern: route `types`, history-based `navigation`, the params
|
|
7
|
-
* `params-context` + `hooks`, `lazy` component resolution, the `Link`/`Router` components,
|
|
8
|
-
* `mount`, `match` (pure matcher), `prefetch` (link prefetcher), and `channel` (WebSocket helper).
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export { mount } from './routing/mount.js';
|
|
12
|
-
export { Router } from './routing/Router.js';
|
|
13
|
-
export { Link } from './navigation/Link.js';
|
|
14
|
-
export type { LinkProps } from './navigation/Link.js';
|
|
15
|
-
export { NavLink, matchActive } from './navigation/NavLink.js';
|
|
16
|
-
export type { NavLinkProps, NavLinkState } from './navigation/NavLink.js';
|
|
17
|
-
export {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
} from './routing/
|
|
38
|
-
export {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export {
|
|
54
|
-
export type {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
} from './
|
|
70
|
-
export {
|
|
71
|
-
export type {
|
|
72
|
-
export {
|
|
73
|
-
export type {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
/**
|
|
2
|
+
* toiljs client runtime, published as `toiljs/client`. Re-exports the router (mount/Router/Link),
|
|
3
|
+
* navigation hooks, prefetching, and the route types consumed by the compiler-generated entry.
|
|
4
|
+
* Zero imports needed in user route files beyond this package.
|
|
5
|
+
*
|
|
6
|
+
* Internals are split by concern: route `types`, history-based `navigation`, the params
|
|
7
|
+
* `params-context` + `hooks`, `lazy` component resolution, the `Link`/`Router` components,
|
|
8
|
+
* `mount`, `match` (pure matcher), `prefetch` (link prefetcher), and `channel` (WebSocket helper).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export { mount } from './routing/mount.js';
|
|
12
|
+
export { Router } from './routing/Router.js';
|
|
13
|
+
export { Link } from './navigation/Link.js';
|
|
14
|
+
export type { LinkProps } from './navigation/Link.js';
|
|
15
|
+
export { NavLink, matchActive } from './navigation/NavLink.js';
|
|
16
|
+
export type { NavLinkProps, NavLinkState } from './navigation/NavLink.js';
|
|
17
|
+
export {
|
|
18
|
+
navigate,
|
|
19
|
+
back,
|
|
20
|
+
forward,
|
|
21
|
+
refresh,
|
|
22
|
+
setViewTransitions,
|
|
23
|
+
setTransitions,
|
|
24
|
+
href,
|
|
25
|
+
} from './navigation/navigation.js';
|
|
26
|
+
export type { NavigateOptions } from './navigation/navigation.js';
|
|
27
|
+
export {
|
|
28
|
+
useParams,
|
|
29
|
+
useNavigate,
|
|
30
|
+
useLocation,
|
|
31
|
+
usePathname,
|
|
32
|
+
useSearchParams,
|
|
33
|
+
useRouter,
|
|
34
|
+
useNavigationPending,
|
|
35
|
+
} from './routing/hooks.js';
|
|
36
|
+
export type { RouterInstance } from './routing/hooks.js';
|
|
37
|
+
export { useLoaderData, revalidate, invalidateLoaderData } from './routing/loader.js';
|
|
38
|
+
export type {
|
|
39
|
+
LoaderArgs,
|
|
40
|
+
LoaderFunction,
|
|
41
|
+
LoaderData,
|
|
42
|
+
Revalidate,
|
|
43
|
+
StaticParams,
|
|
44
|
+
GenerateStaticParams,
|
|
45
|
+
} from './routing/loader.js';
|
|
46
|
+
export { useAction } from './routing/action.js';
|
|
47
|
+
export type {
|
|
48
|
+
UseActionOptions,
|
|
49
|
+
ActionState,
|
|
50
|
+
ActionHandle,
|
|
51
|
+
RevalidateTarget,
|
|
52
|
+
} from './routing/action.js';
|
|
53
|
+
export { prefetch } from './navigation/prefetch.js';
|
|
54
|
+
export type {
|
|
55
|
+
RouteDef,
|
|
56
|
+
LayoutLoader,
|
|
57
|
+
LayoutComponentLoader,
|
|
58
|
+
NotFoundLoader,
|
|
59
|
+
RouteErrorProps,
|
|
60
|
+
Register,
|
|
61
|
+
RoutePath,
|
|
62
|
+
Href,
|
|
63
|
+
} from './types.js';
|
|
64
|
+
export { matchRoute } from './routing/match.js';
|
|
65
|
+
export type { RouteParams } from './routing/match.js';
|
|
66
|
+
export { connectChannel, useChannel, resolveChannelUrl } from './channel/channel.js';
|
|
67
|
+
export type { Channel, ChannelOptions, ChannelHook, ChannelData } from './channel/channel.js';
|
|
68
|
+
export { useHead, useTitle, Head, mergeHead } from './head/head.js';
|
|
69
|
+
export type { HeadSpec, MetaTag, LinkTag, ResolvedHead } from './head/head.js';
|
|
70
|
+
export { resolveMetadata, useMetadata, Metadata } from './head/metadata.js';
|
|
71
|
+
export type { GenerateMetadata, GenerateMetadataArgs, OpenGraph } from './head/metadata.js';
|
|
72
|
+
export { searchPages, registerPages, getPages, pagePath } from './search/search.js';
|
|
73
|
+
export type {
|
|
74
|
+
PageMeta,
|
|
75
|
+
PageSearchResult,
|
|
76
|
+
PageSearchOptions,
|
|
77
|
+
SearchField,
|
|
78
|
+
SearchHints,
|
|
79
|
+
} from './search/search.js';
|
|
80
|
+
export { usePageSearch } from './search/use-page-search.js';
|
|
81
|
+
export type { PageSearch } from './search/use-page-search.js';
|
|
82
|
+
export { Image } from './components/Image.js';
|
|
83
|
+
export type { ImageProps } from './components/Image.js';
|
|
84
|
+
export { Script } from './components/Script.js';
|
|
85
|
+
export type { ScriptProps, ScriptStrategy } from './components/Script.js';
|
|
86
|
+
export { Form } from './components/Form.js';
|
|
87
|
+
export type { FormProps } from './components/Form.js';
|
|
88
|
+
export { Slot } from './components/Slot.js';
|
|
89
|
+
export type { SlotProps } from './components/Slot.js';
|