elm-pages 3.0.0-beta.5 → 3.0.0-beta.7
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/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/src/build.js +22 -29
- package/generator/src/config.js +39 -0
- package/generator/src/dev-server.js +21 -50
- package/generator/src/pre-render-html.js +34 -18
- package/generator/src/vite-utils.js +78 -0
- package/package.json +2 -2
- package/src/DataSource.elm +28 -28
- package/src/Pages/Generate.elm +445 -94
- package/src/Pages/Internal/Platform.elm +31 -24
|
Binary file
|
|
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
|
|
|
75
75
|
const { Elm } = require("./Runner.elm.js");
|
|
76
76
|
|
|
77
77
|
// Start the Elm app
|
|
78
|
-
const flags = { initialSeed:
|
|
78
|
+
const flags = { initialSeed: 2254786925, fuzzRuns: 100, filter: null };
|
|
79
79
|
const app = Elm.Runner.init({ flags: flags });
|
|
80
80
|
|
|
81
81
|
// Record the timing at which we received the last "runTest" message
|
|
Binary file
|
|
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
|
|
|
75
75
|
const { Elm } = require("./Runner.elm.js");
|
|
76
76
|
|
|
77
77
|
// Start the Elm app
|
|
78
|
-
const flags = { initialSeed:
|
|
78
|
+
const flags = { initialSeed: 3791732356, fuzzRuns: 100, filter: null };
|
|
79
79
|
const app = Elm.Runner.init({ flags: flags });
|
|
80
80
|
|
|
81
81
|
// Record the timing at which we received the last "runTest" message
|
package/generator/src/build.js
CHANGED
|
@@ -16,6 +16,8 @@ const { build } = require("vite");
|
|
|
16
16
|
const preRenderHtml = require("./pre-render-html.js");
|
|
17
17
|
const esbuild = require("esbuild");
|
|
18
18
|
const { createHash } = require("crypto");
|
|
19
|
+
const { merge_vite_configs } = require("./vite-utils.js");
|
|
20
|
+
const { resolveConfig } = require("./config.js");
|
|
19
21
|
|
|
20
22
|
let pool = [];
|
|
21
23
|
let pagesReady;
|
|
@@ -75,40 +77,31 @@ async function run(options) {
|
|
|
75
77
|
const generateCode = codegen.generate(options.base);
|
|
76
78
|
|
|
77
79
|
await generateCode;
|
|
80
|
+
|
|
81
|
+
const config = await resolveConfig();
|
|
78
82
|
await fsPromises.writeFile(
|
|
79
83
|
"elm-stuff/elm-pages/index.html",
|
|
80
|
-
preRenderHtml.templateHtml()
|
|
84
|
+
preRenderHtml.templateHtml(false, config.headTagsTemplate)
|
|
81
85
|
);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const viteConfig = config.vite || {};
|
|
96
|
-
|
|
97
|
-
const buildComplete = build({
|
|
98
|
-
configFile: false,
|
|
99
|
-
root: process.cwd(),
|
|
100
|
-
base: options.base,
|
|
101
|
-
ssr: false,
|
|
102
|
-
|
|
103
|
-
build: {
|
|
104
|
-
manifest: true,
|
|
105
|
-
outDir: "dist",
|
|
106
|
-
rollupOptions: {
|
|
107
|
-
input: "elm-stuff/elm-pages/index.html",
|
|
86
|
+
const viteConfig = merge_vite_configs(
|
|
87
|
+
{
|
|
88
|
+
configFile: false,
|
|
89
|
+
root: process.cwd(),
|
|
90
|
+
base: options.base,
|
|
91
|
+
ssr: false,
|
|
92
|
+
|
|
93
|
+
build: {
|
|
94
|
+
manifest: true,
|
|
95
|
+
outDir: "dist",
|
|
96
|
+
rollupOptions: {
|
|
97
|
+
input: "elm-stuff/elm-pages/index.html",
|
|
98
|
+
},
|
|
108
99
|
},
|
|
109
100
|
},
|
|
110
|
-
|
|
111
|
-
|
|
101
|
+
config.vite || {}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const buildComplete = build(viteConfig);
|
|
112
105
|
const compileClientDone = compileElm(options);
|
|
113
106
|
await buildComplete;
|
|
114
107
|
await compileClientDone;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
|
|
3
|
+
async function resolveConfig() {
|
|
4
|
+
return await import(path.join(process.cwd(), "elm-pages.config.mjs"))
|
|
5
|
+
.then(async (elmPagesConfig) => {
|
|
6
|
+
return (
|
|
7
|
+
elmPagesConfig.default || {
|
|
8
|
+
headTagsTemplate: defaultHeadTagsTemplate,
|
|
9
|
+
}
|
|
10
|
+
);
|
|
11
|
+
})
|
|
12
|
+
.catch((error) => {
|
|
13
|
+
console.warn(
|
|
14
|
+
"No `elm-pages.config.mjs` file found. Using default config."
|
|
15
|
+
);
|
|
16
|
+
return {
|
|
17
|
+
headTagsTemplate: defaultHeadTagsTemplate,
|
|
18
|
+
vite: {},
|
|
19
|
+
};
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function defaultHeadTagsTemplate(context) {
|
|
24
|
+
return `
|
|
25
|
+
<link rel="stylesheet" href="/style.css" />
|
|
26
|
+
<meta charset="UTF-8" />
|
|
27
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
28
|
+
<meta name="generator" content="elm-pages v${context.cliVersion}" />
|
|
29
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
30
|
+
<meta name="theme-color" content="#ffffff" />
|
|
31
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
32
|
+
<meta
|
|
33
|
+
name="apple-mobile-web-app-status-bar-style"
|
|
34
|
+
content="black-translucent"
|
|
35
|
+
/>
|
|
36
|
+
`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = { resolveConfig };
|
|
@@ -24,6 +24,9 @@ const busboy = require("busboy");
|
|
|
24
24
|
const { createServer: createViteServer } = require("vite");
|
|
25
25
|
const cliVersion = require("../../package.json").version;
|
|
26
26
|
const esbuild = require("esbuild");
|
|
27
|
+
const { merge_vite_configs } = require("./vite-utils.js");
|
|
28
|
+
const { templateHtml } = require("./pre-render-html.js");
|
|
29
|
+
const { resolveConfig } = require("./config.js");
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
32
|
* @param {{ port: string; base: string; https: boolean; debug: boolean; }} options
|
|
@@ -117,27 +120,23 @@ async function start(options) {
|
|
|
117
120
|
watcher.add(sourceDirs);
|
|
118
121
|
}
|
|
119
122
|
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
root: process.cwd(),
|
|
138
|
-
base: options.base,
|
|
139
|
-
...viteConfig,
|
|
140
|
-
});
|
|
123
|
+
const config = await resolveConfig();
|
|
124
|
+
const vite = await createViteServer(
|
|
125
|
+
merge_vite_configs(
|
|
126
|
+
{
|
|
127
|
+
server: {
|
|
128
|
+
middlewareMode: "ssr",
|
|
129
|
+
base: options.base,
|
|
130
|
+
port: options.port,
|
|
131
|
+
},
|
|
132
|
+
configFile: false,
|
|
133
|
+
root: process.cwd(),
|
|
134
|
+
base: options.base,
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
config.vite
|
|
138
|
+
)
|
|
139
|
+
);
|
|
141
140
|
esbuild
|
|
142
141
|
.build({
|
|
143
142
|
entryPoints: ["./port-data-source"],
|
|
@@ -459,35 +458,7 @@ async function start(options) {
|
|
|
459
458
|
}
|
|
460
459
|
case "html": {
|
|
461
460
|
try {
|
|
462
|
-
const template =
|
|
463
|
-
/*html*/
|
|
464
|
-
`<!DOCTYPE html>
|
|
465
|
-
<!-- ROOT --><html lang="en">
|
|
466
|
-
<head>
|
|
467
|
-
<script src="/hmr.js" type="text/javascript"></script>
|
|
468
|
-
<script src="/elm.js" type="text/javascript"></script>
|
|
469
|
-
<link rel="stylesheet" href="/style.css">
|
|
470
|
-
<link rel="stylesheet" href="/dev-style.css">
|
|
471
|
-
<script src="/elm-pages.js" type="module"></script>
|
|
472
|
-
<meta charset="UTF-8" />
|
|
473
|
-
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
474
|
-
<title><!-- PLACEHOLDER_TITLE --></title>
|
|
475
|
-
<meta name="generator" content="elm-pages v${cliVersion}" />
|
|
476
|
-
<meta name="mobile-web-app-capable" content="yes" />
|
|
477
|
-
<meta name="theme-color" content="#ffffff" />
|
|
478
|
-
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
479
|
-
<meta
|
|
480
|
-
name="apple-mobile-web-app-status-bar-style"
|
|
481
|
-
content="black-translucent"
|
|
482
|
-
/>
|
|
483
|
-
<!-- PLACEHOLDER_HEAD_AND_DATA -->
|
|
484
|
-
</head>
|
|
485
|
-
<body>
|
|
486
|
-
<div data-url="" display="none"></div>
|
|
487
|
-
<!-- PLACEHOLDER_HTML -->
|
|
488
|
-
</body>
|
|
489
|
-
</html>
|
|
490
|
-
`;
|
|
461
|
+
const template = templateHtml(true, config.headTagsTemplate);
|
|
491
462
|
const processedTemplate = await vite.transformIndexHtml(
|
|
492
463
|
req.originalUrl,
|
|
493
464
|
template
|
|
@@ -17,28 +17,34 @@ function wrapHtml(basePath, fromElm, contentDatPayload) {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* @param {boolean} devMode
|
|
22
|
+
* @param {(context: {cliVersion: string;}) => string} userHeadTagsTemplate
|
|
23
|
+
*/
|
|
24
|
+
function templateHtml(devMode, userHeadTagsTemplate) {
|
|
21
25
|
return /* html */ `<!DOCTYPE html>
|
|
22
26
|
<!-- ROOT --><html lang="en">
|
|
23
27
|
<head>
|
|
24
|
-
<!-- PLACEHOLDER_PRELOADS -->
|
|
25
|
-
<script defer src="/elm.js" type="text/javascript"></script>
|
|
26
|
-
<script defer src="${path.join(
|
|
27
|
-
__dirname,
|
|
28
|
-
"../static-code/elm-pages.js"
|
|
29
|
-
)}" type="module"></script>
|
|
30
|
-
<link rel="stylesheet" href="/style.css" />
|
|
31
|
-
<meta charset="UTF-8" />
|
|
32
|
-
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
33
28
|
<title><!-- PLACEHOLDER_TITLE --></title>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
${
|
|
30
|
+
devMode
|
|
31
|
+
? `
|
|
32
|
+
<script src="/hmr.js" type="text/javascript"></script>
|
|
33
|
+
<link rel="stylesheet" href="/dev-style.css">`
|
|
34
|
+
: `
|
|
35
|
+
<!-- PLACEHOLDER_PRELOADS -->`
|
|
36
|
+
}
|
|
37
|
+
<script defer src="/elm.js" type="text/javascript"></script>
|
|
38
|
+
${
|
|
39
|
+
devMode
|
|
40
|
+
? `<script src="/elm-pages.js" type="module"></script>
|
|
41
|
+
`
|
|
42
|
+
: `<script defer src="${path.join(
|
|
43
|
+
__dirname,
|
|
44
|
+
"../static-code/elm-pages.js"
|
|
45
|
+
)}" type="module"></script>`
|
|
46
|
+
}
|
|
47
|
+
${indent(userHeadTagsTemplate({ cliVersion }))}
|
|
42
48
|
<!-- PLACEHOLDER_HEAD_AND_DATA -->
|
|
43
49
|
</head>
|
|
44
50
|
<body>
|
|
@@ -48,6 +54,16 @@ function templateHtml() {
|
|
|
48
54
|
</html>`;
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
/**
|
|
58
|
+
* @param {string} snippet
|
|
59
|
+
*/
|
|
60
|
+
function indent(snippet) {
|
|
61
|
+
return snippet
|
|
62
|
+
.split("\n")
|
|
63
|
+
.map((line) => ` ${line}`)
|
|
64
|
+
.join("\n");
|
|
65
|
+
}
|
|
66
|
+
|
|
51
67
|
/**
|
|
52
68
|
* @param {string} processedTemplate
|
|
53
69
|
*/
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/** This code is from https://github.com/sveltejs/kit/blob/3b457f67d4d7c59fc63bb3f600a490e4dacc2e62/packages/kit/src/exports/vite/utils.js */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {...import('vite').UserConfig} configs
|
|
5
|
+
* @returns {import('vite').UserConfig}
|
|
6
|
+
*/
|
|
7
|
+
function merge_vite_configs(...configs) {
|
|
8
|
+
return deep_merge(
|
|
9
|
+
...configs.map((config) => ({
|
|
10
|
+
...config,
|
|
11
|
+
resolve: {
|
|
12
|
+
...config.resolve,
|
|
13
|
+
alias: normalize_alias(config.resolve?.alias || {}),
|
|
14
|
+
},
|
|
15
|
+
}))
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Takes zero or more objects and returns a new object that has all the values
|
|
21
|
+
* deeply merged together. None of the original objects will be mutated at any
|
|
22
|
+
* level, and the returned object will have no references to the original
|
|
23
|
+
* objects at any depth. If there's a conflict the last one wins, except for
|
|
24
|
+
* arrays which will be combined.
|
|
25
|
+
* @param {...Object} objects
|
|
26
|
+
* @returns {Record<string, any>} the merged object
|
|
27
|
+
*/
|
|
28
|
+
function deep_merge(...objects) {
|
|
29
|
+
const result = {};
|
|
30
|
+
/** @type {string[]} */
|
|
31
|
+
objects.forEach((o) => merge_into(result, o));
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* normalize kit.vite.resolve.alias as an array
|
|
37
|
+
* @param {import('vite').AliasOptions} o
|
|
38
|
+
* @returns {import('vite').Alias[]}
|
|
39
|
+
*/
|
|
40
|
+
function normalize_alias(o) {
|
|
41
|
+
if (Array.isArray(o)) return o;
|
|
42
|
+
return Object.entries(o).map(([find, replacement]) => ({
|
|
43
|
+
find,
|
|
44
|
+
replacement,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Merges b into a, recursively, mutating a.
|
|
50
|
+
* @param {Record<string, any>} a
|
|
51
|
+
* @param {Record<string, any>} b
|
|
52
|
+
*/
|
|
53
|
+
function merge_into(a, b) {
|
|
54
|
+
/**
|
|
55
|
+
* Checks for "plain old Javascript object", typically made as an object
|
|
56
|
+
* literal. Excludes Arrays and built-in types like Buffer.
|
|
57
|
+
* @param {any} x
|
|
58
|
+
*/
|
|
59
|
+
const is_plain_object = (x) =>
|
|
60
|
+
typeof x === "object" && x.constructor === Object;
|
|
61
|
+
|
|
62
|
+
for (const prop in b) {
|
|
63
|
+
if (is_plain_object(b[prop])) {
|
|
64
|
+
if (!is_plain_object(a[prop])) {
|
|
65
|
+
a[prop] = {};
|
|
66
|
+
}
|
|
67
|
+
merge_into(a[prop], b[prop]);
|
|
68
|
+
} else if (Array.isArray(b[prop])) {
|
|
69
|
+
if (!Array.isArray(a[prop])) {
|
|
70
|
+
a[prop] = [];
|
|
71
|
+
}
|
|
72
|
+
a[prop].push(...b[prop]);
|
|
73
|
+
} else {
|
|
74
|
+
a[prop] = b[prop];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
module.exports = { merge_vite_configs };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elm-pages",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.7",
|
|
4
4
|
"homepage": "https://elm-pages.com",
|
|
5
5
|
"moduleResolution": "node",
|
|
6
6
|
"description": "Type-safe static sites, written in pure elm with your own custom elm-markup syntax.",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"object-hash": "^2.2.0",
|
|
46
46
|
"serve-static": "^1.15.0",
|
|
47
47
|
"terser": "^5.14.2",
|
|
48
|
-
"vite": "^3.
|
|
48
|
+
"vite": "^3.1.8",
|
|
49
49
|
"which": "^2.0.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
package/src/DataSource.elm
CHANGED
|
@@ -123,16 +123,16 @@ A common use for this is to map your data into your elm-pages view:
|
|
|
123
123
|
map : (a -> b) -> DataSource a -> DataSource b
|
|
124
124
|
map fn requestInfo =
|
|
125
125
|
case requestInfo of
|
|
126
|
-
|
|
127
|
-
|
|
126
|
+
ApiRoute value ->
|
|
127
|
+
ApiRoute (fn value)
|
|
128
128
|
|
|
129
129
|
Request urls lookupFn ->
|
|
130
130
|
Request
|
|
131
131
|
urls
|
|
132
132
|
(mapLookupFn fn lookupFn)
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
RequestError error ->
|
|
135
|
+
RequestError error
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
mapLookupFn : (a -> b) -> (d -> c -> DataSource a) -> d -> c -> DataSource b
|
|
@@ -182,8 +182,8 @@ resolve =
|
|
|
182
182
|
|
|
183
183
|
-}
|
|
184
184
|
combine : List (DataSource value) -> DataSource (List value)
|
|
185
|
-
combine =
|
|
186
|
-
List.
|
|
185
|
+
combine items =
|
|
186
|
+
List.foldl (map2 (::)) (succeed []) items |> map List.reverse
|
|
187
187
|
|
|
188
188
|
|
|
189
189
|
{-| Like map, but it takes in two `Request`s.
|
|
@@ -212,11 +212,8 @@ combine =
|
|
|
212
212
|
map2 : (a -> b -> c) -> DataSource a -> DataSource b -> DataSource c
|
|
213
213
|
map2 fn request1 request2 =
|
|
214
214
|
case ( request1, request2 ) of
|
|
215
|
-
(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
( _, RequestError error ) ->
|
|
219
|
-
RequestError error
|
|
215
|
+
( ApiRoute value1, ApiRoute value2 ) ->
|
|
216
|
+
ApiRoute (fn value1 value2)
|
|
220
217
|
|
|
221
218
|
( Request urls1 lookupFn1, Request urls2 lookupFn2 ) ->
|
|
222
219
|
Request
|
|
@@ -233,8 +230,11 @@ map2 fn request1 request2 =
|
|
|
233
230
|
urls1
|
|
234
231
|
(mapReq fn (\_ _ -> ApiRoute value2) lookupFn1)
|
|
235
232
|
|
|
236
|
-
(
|
|
237
|
-
|
|
233
|
+
( RequestError error, _ ) ->
|
|
234
|
+
RequestError error
|
|
235
|
+
|
|
236
|
+
( _, RequestError error ) ->
|
|
237
|
+
RequestError error
|
|
238
238
|
|
|
239
239
|
|
|
240
240
|
mapReq : (a -> b -> c) -> (e -> d -> DataSource a) -> (e -> d -> DataSource b) -> e -> d -> DataSource c
|
|
@@ -247,9 +247,6 @@ mapReq fn lookupFn1 lookupFn2 maybeMock rawResponses =
|
|
|
247
247
|
lookup : Maybe Pages.StaticHttpRequest.MockResolver -> DataSource value -> RequestsAndPending -> Result Pages.StaticHttpRequest.Error value
|
|
248
248
|
lookup maybeMockResolver requestInfo rawResponses =
|
|
249
249
|
case requestInfo of
|
|
250
|
-
RequestError error ->
|
|
251
|
-
Err error
|
|
252
|
-
|
|
253
250
|
Request urls lookupFn ->
|
|
254
251
|
lookup maybeMockResolver
|
|
255
252
|
(addUrls urls (lookupFn maybeMockResolver rawResponses))
|
|
@@ -258,18 +255,21 @@ lookup maybeMockResolver requestInfo rawResponses =
|
|
|
258
255
|
ApiRoute value ->
|
|
259
256
|
Ok value
|
|
260
257
|
|
|
258
|
+
RequestError error ->
|
|
259
|
+
Err error
|
|
260
|
+
|
|
261
261
|
|
|
262
262
|
addUrls : List HashRequest.Request -> DataSource value -> DataSource value
|
|
263
263
|
addUrls urlsToAdd requestInfo =
|
|
264
264
|
case requestInfo of
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
ApiRoute value ->
|
|
266
|
+
ApiRoute value
|
|
267
267
|
|
|
268
268
|
Request initialUrls function ->
|
|
269
269
|
Request (initialUrls ++ urlsToAdd) function
|
|
270
270
|
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
RequestError error ->
|
|
272
|
+
RequestError error
|
|
273
273
|
|
|
274
274
|
|
|
275
275
|
{-| The full details to perform a StaticHttp request.
|
|
@@ -286,14 +286,14 @@ type alias RequestDetails =
|
|
|
286
286
|
lookupUrls : DataSource value -> List RequestDetails
|
|
287
287
|
lookupUrls requestInfo =
|
|
288
288
|
case requestInfo of
|
|
289
|
-
|
|
290
|
-
-- TODO should this have URLs passed through?
|
|
289
|
+
ApiRoute _ ->
|
|
291
290
|
[]
|
|
292
291
|
|
|
293
292
|
Request urls _ ->
|
|
294
293
|
urls
|
|
295
294
|
|
|
296
|
-
|
|
295
|
+
RequestError _ ->
|
|
296
|
+
-- TODO should this have URLs passed through?
|
|
297
297
|
[]
|
|
298
298
|
|
|
299
299
|
|
|
@@ -324,19 +324,19 @@ andThen fn requestInfo =
|
|
|
324
324
|
rawResponses
|
|
325
325
|
|> (\result ->
|
|
326
326
|
case result of
|
|
327
|
-
Err error ->
|
|
328
|
-
RequestError error
|
|
329
|
-
|
|
330
327
|
Ok value ->
|
|
331
328
|
case fn value of
|
|
329
|
+
ApiRoute finalValue ->
|
|
330
|
+
ApiRoute finalValue
|
|
331
|
+
|
|
332
332
|
Request values function ->
|
|
333
333
|
Request values function
|
|
334
334
|
|
|
335
335
|
RequestError error ->
|
|
336
336
|
RequestError error
|
|
337
337
|
|
|
338
|
-
|
|
339
|
-
|
|
338
|
+
Err error ->
|
|
339
|
+
RequestError error
|
|
340
340
|
)
|
|
341
341
|
)
|
|
342
342
|
|
package/src/Pages/Generate.elm
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
-
module Pages.Generate exposing
|
|
1
|
+
module Pages.Generate exposing
|
|
2
|
+
( buildWithLocalState, buildNoState, Builder
|
|
3
|
+
, Type(..)
|
|
4
|
+
, serverRender
|
|
5
|
+
, preRender, single
|
|
6
|
+
)
|
|
2
7
|
|
|
3
8
|
{-|
|
|
4
9
|
|
|
5
|
-
|
|
10
|
+
|
|
11
|
+
## Initializing the Generator Builder
|
|
12
|
+
|
|
13
|
+
@docs buildWithLocalState, buildNoState, Builder
|
|
14
|
+
|
|
15
|
+
@docs Type
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## Generating Server-Rendered Pages
|
|
19
|
+
|
|
20
|
+
@docs serverRender
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## Generating pre-rendered pages
|
|
24
|
+
|
|
25
|
+
@docs preRender, single
|
|
6
26
|
|
|
7
27
|
-}
|
|
8
28
|
|
|
@@ -30,12 +50,18 @@ typeToDeclaration name type_ =
|
|
|
30
50
|
|
|
31
51
|
{-| -}
|
|
32
52
|
type Builder
|
|
33
|
-
=
|
|
53
|
+
= ServerRender
|
|
34
54
|
{ data : ( Type, Elm.Expression -> Elm.Expression )
|
|
35
55
|
, action : ( Type, Elm.Expression -> Elm.Expression )
|
|
36
56
|
, head : Elm.Expression -> Elm.Expression
|
|
37
57
|
, moduleName : List String
|
|
38
58
|
}
|
|
59
|
+
| PreRender
|
|
60
|
+
{ data : ( Type, Elm.Expression -> Elm.Expression )
|
|
61
|
+
, pages : Maybe Elm.Expression
|
|
62
|
+
, head : Elm.Expression -> Elm.Expression
|
|
63
|
+
, moduleName : List String
|
|
64
|
+
}
|
|
39
65
|
|
|
40
66
|
|
|
41
67
|
{-| -}
|
|
@@ -47,7 +73,56 @@ serverRender :
|
|
|
47
73
|
}
|
|
48
74
|
-> Builder
|
|
49
75
|
serverRender =
|
|
50
|
-
|
|
76
|
+
ServerRender
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
{-| -}
|
|
80
|
+
preRender :
|
|
81
|
+
{ data : ( Type, Elm.Expression -> Elm.Expression )
|
|
82
|
+
, pages : Elm.Expression
|
|
83
|
+
, head : Elm.Expression -> Elm.Expression
|
|
84
|
+
, moduleName : List String
|
|
85
|
+
}
|
|
86
|
+
-> Builder
|
|
87
|
+
preRender input =
|
|
88
|
+
--let
|
|
89
|
+
-- hasDynamicRouteSegments : Bool
|
|
90
|
+
-- hasDynamicRouteSegments =
|
|
91
|
+
-- RoutePattern.fromModuleName input.moduleName
|
|
92
|
+
-- -- TODO give error if not parseable here
|
|
93
|
+
-- |> Maybe.map RoutePattern.hasRouteParams
|
|
94
|
+
-- |> Maybe.withDefault False
|
|
95
|
+
--in
|
|
96
|
+
PreRender
|
|
97
|
+
{ data = input.data
|
|
98
|
+
, pages =
|
|
99
|
+
input.pages
|
|
100
|
+
|> Elm.withType
|
|
101
|
+
(Elm.Annotation.namedWith [ "DataSource" ]
|
|
102
|
+
"DataSource"
|
|
103
|
+
[ Elm.Annotation.list <| Elm.Annotation.named [] "RouteParams"
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
|> Just
|
|
107
|
+
, head = input.head
|
|
108
|
+
, moduleName = input.moduleName
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
{-| -}
|
|
113
|
+
single :
|
|
114
|
+
{ data : ( Type, Elm.Expression )
|
|
115
|
+
, head : Elm.Expression -> Elm.Expression
|
|
116
|
+
, moduleName : List String
|
|
117
|
+
}
|
|
118
|
+
-> Builder
|
|
119
|
+
single input =
|
|
120
|
+
PreRender
|
|
121
|
+
{ data = ( Tuple.first input.data, \_ -> Tuple.second input.data )
|
|
122
|
+
, pages = Nothing
|
|
123
|
+
, head = input.head
|
|
124
|
+
, moduleName = input.moduleName
|
|
125
|
+
}
|
|
51
126
|
|
|
52
127
|
|
|
53
128
|
{-| -}
|
|
@@ -56,20 +131,42 @@ buildNoState :
|
|
|
56
131
|
}
|
|
57
132
|
-> Builder
|
|
58
133
|
-> Elm.File
|
|
59
|
-
buildNoState definitions
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
134
|
+
buildNoState definitions builder_ =
|
|
135
|
+
case builder_ of
|
|
136
|
+
ServerRender builder ->
|
|
137
|
+
userFunction builder.moduleName
|
|
138
|
+
{ view = \_ -> definitions.view
|
|
139
|
+
, localState = Nothing
|
|
140
|
+
, data = builder.data |> Tuple.second
|
|
141
|
+
, action = builder.action |> Tuple.second |> Action
|
|
142
|
+
, head = builder.head
|
|
143
|
+
, types =
|
|
144
|
+
{ model = Alias (Elm.Annotation.record [])
|
|
145
|
+
, msg = Alias Elm.Annotation.unit
|
|
146
|
+
, data = builder.data |> Tuple.first
|
|
147
|
+
, actionData = builder.action |> Tuple.first
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
PreRender builder ->
|
|
152
|
+
userFunction builder.moduleName
|
|
153
|
+
{ view = \_ -> definitions.view
|
|
154
|
+
, localState = Nothing
|
|
155
|
+
, data = builder.data |> Tuple.second
|
|
156
|
+
, action = builder.pages |> Pages
|
|
157
|
+
, head = builder.head
|
|
158
|
+
, types =
|
|
159
|
+
{ model = Alias (Elm.Annotation.record [])
|
|
160
|
+
, msg = Alias Elm.Annotation.unit
|
|
161
|
+
, data = builder.data |> Tuple.first
|
|
162
|
+
, actionData =
|
|
163
|
+
Elm.Annotation.namedWith [ "DataSource" ]
|
|
164
|
+
"DataSource"
|
|
165
|
+
[ Elm.Annotation.list (Elm.Annotation.named [] "RouteParams")
|
|
166
|
+
]
|
|
167
|
+
|> Alias
|
|
168
|
+
}
|
|
169
|
+
}
|
|
73
170
|
|
|
74
171
|
|
|
75
172
|
{-| -}
|
|
@@ -83,25 +180,57 @@ buildWithLocalState :
|
|
|
83
180
|
}
|
|
84
181
|
-> Builder
|
|
85
182
|
-> Elm.File
|
|
86
|
-
buildWithLocalState definitions
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
183
|
+
buildWithLocalState definitions builder_ =
|
|
184
|
+
case builder_ of
|
|
185
|
+
ServerRender builder ->
|
|
186
|
+
userFunction builder.moduleName
|
|
187
|
+
{ view = definitions.view
|
|
188
|
+
, localState =
|
|
189
|
+
Just
|
|
190
|
+
{ update = definitions.update
|
|
191
|
+
, init = definitions.init
|
|
192
|
+
, subscriptions = definitions.subscriptions
|
|
193
|
+
}
|
|
194
|
+
, data = builder.data |> Tuple.second
|
|
195
|
+
, action = builder.action |> Tuple.second |> Action
|
|
196
|
+
, head = builder.head
|
|
197
|
+
, types =
|
|
198
|
+
{ model = definitions.model
|
|
199
|
+
, msg = definitions.msg
|
|
200
|
+
, data = builder.data |> Tuple.first
|
|
201
|
+
, actionData = builder.action |> Tuple.first
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
PreRender builder ->
|
|
206
|
+
userFunction builder.moduleName
|
|
207
|
+
{ view = definitions.view
|
|
208
|
+
, localState =
|
|
209
|
+
Just
|
|
210
|
+
{ update = definitions.update
|
|
211
|
+
, init = definitions.init
|
|
212
|
+
, subscriptions = definitions.subscriptions
|
|
213
|
+
}
|
|
214
|
+
, data = builder.data |> Tuple.second
|
|
215
|
+
, action = builder.pages |> Pages
|
|
216
|
+
, head = builder.head
|
|
217
|
+
, types =
|
|
218
|
+
{ model = definitions.model
|
|
219
|
+
, msg = definitions.msg
|
|
220
|
+
, data = builder.data |> Tuple.first
|
|
221
|
+
, actionData =
|
|
222
|
+
Elm.Annotation.namedWith [ "DataSource" ]
|
|
223
|
+
"DataSource"
|
|
224
|
+
[ Elm.Annotation.list (Elm.Annotation.named [] "RouteParams")
|
|
225
|
+
]
|
|
226
|
+
|> Alias
|
|
227
|
+
}
|
|
94
228
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
, msg = definitions.msg
|
|
101
|
-
, data = builder.data |> Tuple.first
|
|
102
|
-
, actionData = builder.action |> Tuple.first
|
|
103
|
-
}
|
|
104
|
-
}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
type ActionOrPages
|
|
232
|
+
= Action (Elm.Expression -> Elm.Expression)
|
|
233
|
+
| Pages (Maybe Elm.Expression)
|
|
105
234
|
|
|
106
235
|
|
|
107
236
|
{-| -}
|
|
@@ -116,7 +245,7 @@ userFunction :
|
|
|
116
245
|
, subscriptions : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
|
|
117
246
|
}
|
|
118
247
|
, data : Elm.Expression -> Elm.Expression
|
|
119
|
-
, action :
|
|
248
|
+
, action : ActionOrPages
|
|
120
249
|
, head : Elm.Expression -> Elm.Expression
|
|
121
250
|
, types : { model : Type, msg : Type, data : Type, actionData : Type }
|
|
122
251
|
}
|
|
@@ -225,25 +354,84 @@ userFunction moduleName definitions =
|
|
|
225
354
|
}
|
|
226
355
|
)
|
|
227
356
|
|
|
228
|
-
dataFn : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
|
|
357
|
+
dataFn : { declaration : Elm.Declaration, call : List Elm.Expression -> Elm.Expression, callFrom : List String -> List Elm.Expression -> Elm.Expression }
|
|
229
358
|
dataFn =
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
359
|
+
case definitions.action of
|
|
360
|
+
Pages Nothing ->
|
|
361
|
+
Elm.Declare.function "data"
|
|
362
|
+
[]
|
|
363
|
+
(\_ ->
|
|
364
|
+
definitions.data Elm.unit
|
|
365
|
+
|> Elm.withType
|
|
366
|
+
(case definitions.action of
|
|
367
|
+
Pages _ ->
|
|
368
|
+
Elm.Annotation.namedWith [ "DataSource" ]
|
|
369
|
+
"DataSource"
|
|
370
|
+
[ Elm.Annotation.named [] "Data"
|
|
371
|
+
]
|
|
372
|
+
|
|
373
|
+
Action _ ->
|
|
374
|
+
myType "Data"
|
|
375
|
+
)
|
|
376
|
+
)
|
|
237
377
|
|
|
238
|
-
|
|
378
|
+
_ ->
|
|
379
|
+
Elm.Declare.function "data"
|
|
380
|
+
[ ( "routeParams"
|
|
381
|
+
, "RouteParams"
|
|
382
|
+
|> Elm.Annotation.named []
|
|
383
|
+
|> Just
|
|
384
|
+
)
|
|
385
|
+
]
|
|
386
|
+
(\args ->
|
|
387
|
+
case args of
|
|
388
|
+
[ arg ] ->
|
|
389
|
+
definitions.data arg
|
|
390
|
+
|> Elm.withType
|
|
391
|
+
(case definitions.action of
|
|
392
|
+
Pages _ ->
|
|
393
|
+
Elm.Annotation.namedWith [ "DataSource" ]
|
|
394
|
+
"DataSource"
|
|
395
|
+
[ Elm.Annotation.named [] "Data"
|
|
396
|
+
]
|
|
397
|
+
|
|
398
|
+
Action _ ->
|
|
399
|
+
myType "Data"
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
_ ->
|
|
403
|
+
Elm.unit
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
actionFn : Maybe { declaration : Elm.Declaration, call : List Elm.Expression -> Elm.Expression, callFrom : List String -> List Elm.Expression -> Elm.Expression }
|
|
239
407
|
actionFn =
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
408
|
+
case definitions.action of
|
|
409
|
+
Action action_ ->
|
|
410
|
+
Elm.Declare.function "action"
|
|
411
|
+
[ ( "routeParams"
|
|
412
|
+
, "RouteParams"
|
|
413
|
+
|> Elm.Annotation.named []
|
|
414
|
+
|> Just
|
|
415
|
+
)
|
|
416
|
+
]
|
|
417
|
+
(\args ->
|
|
418
|
+
case args of
|
|
419
|
+
[ arg ] ->
|
|
420
|
+
action_ arg |> Elm.withType (myType "ActionData")
|
|
421
|
+
|
|
422
|
+
_ ->
|
|
423
|
+
Elm.unit
|
|
424
|
+
)
|
|
425
|
+
|> Just
|
|
426
|
+
|
|
427
|
+
Pages pages_ ->
|
|
428
|
+
pages_
|
|
429
|
+
|> Maybe.map
|
|
430
|
+
(\justPagesExpression ->
|
|
431
|
+
Elm.Declare.function "pages"
|
|
432
|
+
[]
|
|
433
|
+
(\_ -> justPagesExpression)
|
|
434
|
+
)
|
|
247
435
|
|
|
248
436
|
headFn : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
|
|
249
437
|
headFn =
|
|
@@ -268,49 +456,87 @@ userFunction moduleName definitions =
|
|
|
268
456
|
)
|
|
269
457
|
)
|
|
270
458
|
, Elm.declaration "route"
|
|
271
|
-
(
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
>> Elm.withType
|
|
291
|
-
(Elm.Annotation.namedWith [ "RouteBuilder" ]
|
|
292
|
-
"StatefulRoute"
|
|
293
|
-
[ localType "RouteParams"
|
|
294
|
-
, localType "Data"
|
|
295
|
-
, localType "ActionData"
|
|
296
|
-
, localType "Model"
|
|
297
|
-
, localType "Msg"
|
|
298
|
-
]
|
|
299
|
-
)
|
|
459
|
+
(case definitions.action of
|
|
460
|
+
Action _ ->
|
|
461
|
+
serverRender_
|
|
462
|
+
{ action =
|
|
463
|
+
\routeParams ->
|
|
464
|
+
actionFn
|
|
465
|
+
|> Maybe.map
|
|
466
|
+
(\justActionFn ->
|
|
467
|
+
justActionFn.call [ routeParams ]
|
|
468
|
+
|> Elm.withType (myType "ActionData")
|
|
469
|
+
)
|
|
470
|
+
|> Maybe.withDefault Elm.unit
|
|
471
|
+
, data =
|
|
472
|
+
\routeParams ->
|
|
473
|
+
dataFn.call [ routeParams ]
|
|
474
|
+
|> Elm.withType (myType "Data")
|
|
475
|
+
, head = headFn.call
|
|
476
|
+
}
|
|
300
477
|
|
|
478
|
+
Pages _ ->
|
|
479
|
+
(case actionFn of
|
|
301
480
|
Nothing ->
|
|
302
|
-
|
|
303
|
-
{
|
|
481
|
+
single_
|
|
482
|
+
{ data =
|
|
483
|
+
dataFn.call []
|
|
484
|
+
|> Elm.withType
|
|
485
|
+
(Elm.Annotation.namedWith [ "DataSource" ]
|
|
486
|
+
"DataSource"
|
|
487
|
+
[ Elm.Annotation.named [] "Data"
|
|
488
|
+
]
|
|
489
|
+
)
|
|
490
|
+
, head = headFn.call
|
|
304
491
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
]
|
|
312
|
-
|
|
313
|
-
|
|
492
|
+
|
|
493
|
+
Just justActionFn ->
|
|
494
|
+
preRender_
|
|
495
|
+
{ pages = justActionFn.call []
|
|
496
|
+
, data =
|
|
497
|
+
\routeParams ->
|
|
498
|
+
dataFn.call [ routeParams ]
|
|
499
|
+
|> Elm.withType
|
|
500
|
+
(Elm.Annotation.namedWith [ "DataSource" ]
|
|
501
|
+
"DataSource"
|
|
502
|
+
[ Elm.Annotation.named [] "Data"
|
|
503
|
+
]
|
|
504
|
+
)
|
|
505
|
+
, head = headFn.call
|
|
506
|
+
}
|
|
507
|
+
)
|
|
508
|
+
|> (case localDefinitions of
|
|
509
|
+
Just local ->
|
|
510
|
+
buildWithLocalState_
|
|
511
|
+
{ view = viewFn.call
|
|
512
|
+
, update = local.updateFn.call
|
|
513
|
+
, init = local.initFn.call
|
|
514
|
+
, subscriptions = local.subscriptionsFn.call
|
|
515
|
+
}
|
|
516
|
+
>> Elm.withType
|
|
517
|
+
(Elm.Annotation.namedWith [ "RouteBuilder" ]
|
|
518
|
+
"StatefulRoute"
|
|
519
|
+
[ localType "RouteParams"
|
|
520
|
+
, localType "Data"
|
|
521
|
+
, localType "ActionData"
|
|
522
|
+
, localType "Model"
|
|
523
|
+
, localType "Msg"
|
|
524
|
+
]
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
Nothing ->
|
|
528
|
+
buildNoState_
|
|
529
|
+
{ view = viewFn.call Elm.unit
|
|
530
|
+
}
|
|
531
|
+
>> Elm.withType
|
|
532
|
+
(Elm.Annotation.namedWith [ "RouteBuilder" ]
|
|
533
|
+
"StatelessRoute"
|
|
534
|
+
[ localType "RouteParams"
|
|
535
|
+
, localType "Data"
|
|
536
|
+
, localType "ActionData"
|
|
537
|
+
]
|
|
538
|
+
)
|
|
539
|
+
)
|
|
314
540
|
)
|
|
315
541
|
]
|
|
316
542
|
++ (case localDefinitions of
|
|
@@ -326,10 +552,13 @@ userFunction moduleName definitions =
|
|
|
326
552
|
++ [ definitions.types.data |> typeToDeclaration "Data"
|
|
327
553
|
, definitions.types.actionData |> typeToDeclaration "ActionData"
|
|
328
554
|
, dataFn.declaration
|
|
329
|
-
, actionFn.declaration
|
|
330
555
|
, headFn.declaration
|
|
331
556
|
, viewFn.declaration
|
|
332
557
|
]
|
|
558
|
+
++ ([ actionFn |> Maybe.map .declaration
|
|
559
|
+
]
|
|
560
|
+
|> List.filterMap identity
|
|
561
|
+
)
|
|
333
562
|
)
|
|
334
563
|
|
|
335
564
|
|
|
@@ -463,6 +692,128 @@ serverRender_ serverRenderArg =
|
|
|
463
692
|
]
|
|
464
693
|
|
|
465
694
|
|
|
695
|
+
preRender_ :
|
|
696
|
+
{ data : Elm.Expression -> Elm.Expression
|
|
697
|
+
, pages : Elm.Expression
|
|
698
|
+
, head : Elm.Expression -> Elm.Expression
|
|
699
|
+
}
|
|
700
|
+
-> Elm.Expression
|
|
701
|
+
preRender_ serverRenderArg =
|
|
702
|
+
Elm.apply
|
|
703
|
+
(Elm.value
|
|
704
|
+
{ importFrom = [ "RouteBuilder" ]
|
|
705
|
+
, name = "preRender"
|
|
706
|
+
, annotation =
|
|
707
|
+
Just
|
|
708
|
+
(Elm.Annotation.function
|
|
709
|
+
[ Elm.Annotation.record
|
|
710
|
+
[ ( "data"
|
|
711
|
+
, Elm.Annotation.function
|
|
712
|
+
[ Elm.Annotation.var "routeParams" ]
|
|
713
|
+
(Elm.Annotation.namedWith
|
|
714
|
+
[ "DataSource" ]
|
|
715
|
+
"DataSource"
|
|
716
|
+
[ Elm.Annotation.var "data"
|
|
717
|
+
]
|
|
718
|
+
)
|
|
719
|
+
)
|
|
720
|
+
, ( "pages"
|
|
721
|
+
, Elm.Annotation.namedWith
|
|
722
|
+
[ "DataSource" ]
|
|
723
|
+
"DataSource"
|
|
724
|
+
[ Elm.Annotation.list (Elm.Annotation.named [] "RouteParams")
|
|
725
|
+
]
|
|
726
|
+
)
|
|
727
|
+
, ( "head"
|
|
728
|
+
, Elm.Annotation.function
|
|
729
|
+
[ Elm.Annotation.namedWith
|
|
730
|
+
[ "RouteBuilder" ]
|
|
731
|
+
"StaticPayload"
|
|
732
|
+
[ Elm.Annotation.var "data"
|
|
733
|
+
, Elm.Annotation.var "action"
|
|
734
|
+
, Elm.Annotation.var "routeParams"
|
|
735
|
+
]
|
|
736
|
+
]
|
|
737
|
+
(Elm.Annotation.list
|
|
738
|
+
(Elm.Annotation.namedWith [ "Head" ] "Tag" [])
|
|
739
|
+
)
|
|
740
|
+
)
|
|
741
|
+
]
|
|
742
|
+
]
|
|
743
|
+
(Elm.Annotation.namedWith
|
|
744
|
+
[ "RouteBuilder" ]
|
|
745
|
+
"Builder"
|
|
746
|
+
[ Elm.Annotation.named [] "RouteParams"
|
|
747
|
+
, Elm.Annotation.named [] "Data"
|
|
748
|
+
, Elm.Annotation.named [] "Action"
|
|
749
|
+
]
|
|
750
|
+
)
|
|
751
|
+
)
|
|
752
|
+
}
|
|
753
|
+
)
|
|
754
|
+
[ Elm.record
|
|
755
|
+
[ Tuple.pair "data" (Elm.functionReduced "serverRenderUnpack" serverRenderArg.data)
|
|
756
|
+
, Tuple.pair "pages" serverRenderArg.pages
|
|
757
|
+
, Tuple.pair "head" (Elm.functionReduced "serverRenderUnpack" serverRenderArg.head)
|
|
758
|
+
]
|
|
759
|
+
]
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
single_ :
|
|
763
|
+
{ data : Elm.Expression
|
|
764
|
+
, head : Elm.Expression -> Elm.Expression
|
|
765
|
+
}
|
|
766
|
+
-> Elm.Expression
|
|
767
|
+
single_ serverRenderArg =
|
|
768
|
+
Elm.apply
|
|
769
|
+
(Elm.value
|
|
770
|
+
{ importFrom = [ "RouteBuilder" ]
|
|
771
|
+
, name = "single"
|
|
772
|
+
, annotation =
|
|
773
|
+
Just
|
|
774
|
+
(Elm.Annotation.function
|
|
775
|
+
[ Elm.Annotation.record
|
|
776
|
+
[ ( "data"
|
|
777
|
+
, Elm.Annotation.namedWith
|
|
778
|
+
[ "DataSource" ]
|
|
779
|
+
"DataSource"
|
|
780
|
+
[ Elm.Annotation.var "data"
|
|
781
|
+
]
|
|
782
|
+
)
|
|
783
|
+
, ( "head"
|
|
784
|
+
, Elm.Annotation.function
|
|
785
|
+
[ Elm.Annotation.namedWith
|
|
786
|
+
[ "RouteBuilder" ]
|
|
787
|
+
"StaticPayload"
|
|
788
|
+
[ Elm.Annotation.var "data"
|
|
789
|
+
, Elm.Annotation.var "action"
|
|
790
|
+
, Elm.Annotation.var "routeParams"
|
|
791
|
+
]
|
|
792
|
+
]
|
|
793
|
+
(Elm.Annotation.list
|
|
794
|
+
(Elm.Annotation.namedWith [ "Head" ] "Tag" [])
|
|
795
|
+
)
|
|
796
|
+
)
|
|
797
|
+
]
|
|
798
|
+
]
|
|
799
|
+
(Elm.Annotation.namedWith
|
|
800
|
+
[ "RouteBuilder" ]
|
|
801
|
+
"Builder"
|
|
802
|
+
[ Elm.Annotation.named [] "RouteParams"
|
|
803
|
+
, Elm.Annotation.named [] "Data"
|
|
804
|
+
, Elm.Annotation.named [] "Action"
|
|
805
|
+
]
|
|
806
|
+
)
|
|
807
|
+
)
|
|
808
|
+
}
|
|
809
|
+
)
|
|
810
|
+
[ Elm.record
|
|
811
|
+
[ Tuple.pair "data" serverRenderArg.data
|
|
812
|
+
, Tuple.pair "head" (Elm.functionReduced "serverRenderUnpack" serverRenderArg.head)
|
|
813
|
+
]
|
|
814
|
+
]
|
|
815
|
+
|
|
816
|
+
|
|
466
817
|
buildWithLocalState_ :
|
|
467
818
|
{ view :
|
|
468
819
|
Elm.Expression
|
|
@@ -423,9 +423,7 @@ update config appMsg model =
|
|
|
423
423
|
)
|
|
424
424
|
|
|
425
425
|
else
|
|
426
|
-
(
|
|
427
|
-
| url = url
|
|
428
|
-
}
|
|
426
|
+
( model
|
|
429
427
|
, NoEffect
|
|
430
428
|
)
|
|
431
429
|
-- TODO is it reasonable to always re-fetch route data if you re-navigate to the current route? Might be a good
|
|
@@ -605,27 +603,32 @@ update config appMsg model =
|
|
|
605
603
|
, actionData = newActionData
|
|
606
604
|
}
|
|
607
605
|
|
|
608
|
-
( userModel,
|
|
606
|
+
( userModel, userEffect ) =
|
|
609
607
|
-- TODO if urlWithoutRedirectResolution is different from the url with redirect resolution, then
|
|
610
608
|
-- instead of calling update, call pushUrl (I think?)
|
|
611
609
|
-- TODO include user Cmd
|
|
612
|
-
|
|
613
|
-
(
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
610
|
+
if stayingOnSamePath then
|
|
611
|
+
( previousPageData.userModel, NoEffect )
|
|
612
|
+
|
|
613
|
+
else
|
|
614
|
+
config.update model.pageFormState
|
|
615
|
+
(model.inFlightFetchers |> toFetcherState)
|
|
616
|
+
(model.transition |> Maybe.map Tuple.second)
|
|
617
|
+
newSharedData
|
|
618
|
+
newPageData
|
|
619
|
+
model.key
|
|
620
|
+
(config.onPageChange
|
|
621
|
+
{ protocol = model.url.protocol
|
|
622
|
+
, host = model.url.host
|
|
623
|
+
, port_ = model.url.port_
|
|
624
|
+
, path = urlPathToPath urlWithoutRedirectResolution
|
|
625
|
+
, query = urlWithoutRedirectResolution.query
|
|
626
|
+
, fragment = urlWithoutRedirectResolution.fragment
|
|
627
|
+
, metadata = config.urlToRoute urlWithoutRedirectResolution
|
|
628
|
+
}
|
|
629
|
+
)
|
|
630
|
+
previousPageData.userModel
|
|
631
|
+
|> Tuple.mapSecond UserCmd
|
|
629
632
|
|
|
630
633
|
updatedModel : Model userModel pageData actionData sharedData
|
|
631
634
|
updatedModel =
|
|
@@ -656,10 +659,13 @@ update config appMsg model =
|
|
|
656
659
|
, currentPath = newUrl.path
|
|
657
660
|
}
|
|
658
661
|
, if not stayingOnSamePath && scrollToTopWhenDone then
|
|
659
|
-
|
|
662
|
+
Batch
|
|
663
|
+
[ ScrollToTop
|
|
664
|
+
, userEffect
|
|
665
|
+
]
|
|
660
666
|
|
|
661
667
|
else
|
|
662
|
-
|
|
668
|
+
userEffect
|
|
663
669
|
)
|
|
664
670
|
|> (case maybeUserMsg of
|
|
665
671
|
Just userMsg ->
|
|
@@ -1392,7 +1398,8 @@ loadDataAndUpdateUrl ( newPageData, newSharedData, newActionData ) maybeUserMsg
|
|
|
1392
1398
|
, actionData = newActionData
|
|
1393
1399
|
}
|
|
1394
1400
|
|
|
1395
|
-
|
|
1401
|
+
-- TODO use userEffect here?
|
|
1402
|
+
( userModel, userEffect ) =
|
|
1396
1403
|
-- TODO if urlWithoutRedirectResolution is different from the url with redirect resolution, then
|
|
1397
1404
|
-- instead of calling update, call pushUrl (I think?)
|
|
1398
1405
|
-- TODO include user Cmd
|