Skip to content

Commit 097cd89

Browse files
committed
add reload on import failure if desired
1 parent 177658b commit 097cd89

File tree

5 files changed

+70
-22
lines changed

5 files changed

+70
-22
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@idrinth/react-file-based-routes",
3-
"version": "1.0.2",
3+
"version": "1.1.0",
44
"repository": "https://github.com/idrinth/react-file-based-routes",
55
"description": "A simple file based routing library, that does not force itself on you.",
66
"license": "MIT",

src/configuration.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ interface FileFinder {
3131
pagesRoot: string,
3232
distJSRoot: string,
3333
}
34+
interface Runtime {
35+
reloadWaitMs: number,
36+
}
3437
export interface Configuration {
38+
runtime: Runtime,
3539
sitemap: Sitemap,
3640
routes: Routes,
3741
htmlMinify: HTMLMinify,
@@ -45,6 +49,9 @@ export default (cwd: string, cliArguments: string[]): Configuration => {
4549
build: true,
4650
domain: '',
4751
},
52+
runtime: {
53+
reloadWaitMs: 0,
54+
},
4855
routes: {
4956
build: true,
5057
type: 'tsx',
@@ -89,7 +96,7 @@ export default (cwd: string, cliArguments: string[]): Configuration => {
8996
for (const param of cliArguments) {
9097
if (param.startsWith('--')) {
9198
const [setting, value,] = param.substring(2).split('=') as [string, undefined|string];
92-
const [group, detail,] = setting.split('.') as [keyof Configuration, keyof Sitemap|keyof Routes|keyof FileFinder|keyof FileBuilder|keyof HTMLMinify];
99+
const [group, detail,] = setting.split('.') as [keyof Configuration, keyof Runtime|keyof Sitemap|keyof Routes|keyof FileFinder|keyof FileBuilder|keyof HTMLMinify];
93100
if (group && typeof config[group] === 'object' && detail) {
94101
// @ts-ignore TS7053
95102
if (typeof config[group][detail] === 'boolean') {
@@ -117,5 +124,8 @@ export default (cwd: string, cliArguments: string[]): Configuration => {
117124
if (config.routes.type !== 'tsx' && config.routes.type !== 'jsx') {
118125
throw new Error('config.routes.type must be set to either tsx or jsx.');
119126
}
127+
if (config.runtime.reloadWaitMs < 0) {
128+
throw new Error('config.runtime.reloadWaitMs must be set to at least 0.');
129+
}
120130
return config;
121131
}

src/generate-routes.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import Writer from './writer.js';
99
export default (cwd: string, configuration: Configuration) => {
1010
const writers: Writer[] = [];
1111
if (configuration.routes.build && configuration.routes.type === 'tsx') {
12-
writers.push(new TsxWriter())
12+
writers.push(new TsxWriter(configuration.runtime.reloadWaitMs,))
1313
}
1414
if (configuration.routes.build && configuration.routes.type === 'jsx') {
15-
writers.push(new JsxWriter())
15+
writers.push(new JsxWriter(configuration.runtime.reloadWaitMs,))
1616
}
1717
if (configuration.sitemap.build) {
1818
writers.push(new SitemapWriter(configuration.sitemap.domain));

src/jsx-writer.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,31 @@ export default class JsxWriter implements Writer {
44
fileName(): string {
55
return 'src/routes.jsx';
66
}
7-
private items: string[] = [];
7+
protected items: string[] = [];
8+
constructor(private readonly waitReloadMS: number) {
9+
}
810
// @ts-ignore TS6133
911
add(path: string, url: string, changed: string): void
1012
{
1113
this.items.push(` (() => {
12-
const LazyElement = lazy(() => import(
13-
\'./pages/${path}/index.tsx\',
14-
),);
14+
const LazyElement = lazy(async() => {
15+
try {
16+
return await import(
17+
'./pages/${path}/index.tsx',
18+
);
19+
} catch (e) {
20+
if (OfflineLoader && ! window.navigator.onLine) {
21+
return {default: OfflineLoader};
22+
}
23+
if (RefreshLoader) {
24+
window.setTimeout(() => window.location.reload(), ${this.waitReloadMS},);
25+
return {default: RefreshLoader};
26+
}
27+
throw e;
28+
}
29+
},);
1530
return {
16-
path: \'${url}\',
31+
path: '${url}',
1732
exact: true,
1833
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
1934
};
@@ -24,9 +39,13 @@ export default class JsxWriter implements Writer {
2439
return 'import React, {\n' +
2540
' lazy,\n' +
2641
' Suspense,\n' +
27-
'} from \'react\';\n' +
28-
'export default (Loader) => [\n '
42+
'} from \'react\';\n\n' +
43+
'export default (' +
44+
' Loader,' +
45+
' RefreshLoader = undefined,' +
46+
' OfflineLoader = undefined,' +
47+
') => [\n '
2948
+ this.items.join('\n ')
30-
+ '\n];'
49+
+ '\n];\n'
3150
}
3251
}

src/tsx-writer.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,50 @@ export default class TsxWriter implements Writer {
44
fileName(): string {
55
return 'src/routes.tsx';
66
}
7-
private items: string[] = [];
7+
protected items: string[] = [];
8+
constructor(private readonly waitReloadMS: number) {
9+
}
810
// @ts-ignore TS6133
911
add(path: string, url: string, changed: string): void
1012
{
1113
this.items.push(` (() => {
12-
const LazyElement = lazy(() => import(
13-
\'./pages/${path}/index.tsx\',
14-
),);
14+
const LazyElement = lazy(async(): Promise\<{default: ComponentType<any>;}\> => {
15+
try {
16+
return await import(
17+
'./pages/${path}/index.tsx',
18+
);
19+
} catch (e) {
20+
if (OfflineLoader && ! window.navigator.onLine) {
21+
return {default: OfflineLoader};
22+
}
23+
if (RefreshLoader) {
24+
window.setTimeout(() => window.location.reload(), ${this.waitReloadMS},);
25+
return {default: RefreshLoader};
26+
}
27+
throw e;
28+
}
29+
},);
1530
return {
16-
path: \'${url}\',
31+
path: '${url}',
1732
exact: true,
1833
element: <Suspense fallback={<Loader/>}><LazyElement/></Suspense>,
1934
};
20-
})(),`,
35+
})(),`
2136
);
2237
}
2338
toString(): string {
2439
return 'import React, {\n' +
2540
' lazy,\n' +
2641
' Suspense,\n' +
2742
' ElementType,\n' +
28-
'} from \'react\';\n' +
29-
'export default (Loader: ElementType) => [\n '
43+
' ComponentType,\n' +
44+
'} from \'react\';\n\n' +
45+
'export default (\n' +
46+
' Loader: ElementType,\n' +
47+
' RefreshLoader: ComponentType|undefined = undefined,\n' +
48+
' OfflineLoader: ComponentType|undefined = undefined,\n' +
49+
') => [\n '
3050
+ this.items.join('\n ')
31-
+ '\n];'
32-
51+
+ '\n];\n'
3352
}
3453
}

0 commit comments

Comments
 (0)