@primate/svelte 0.15.0 → 0.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primate/svelte",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "description": "Primate Svelte module",
5
5
  "homepage": "https://primatejs.com/modules/svelte",
6
6
  "bugs": "https://github.com/primatejs/primate/issues",
@@ -0,0 +1,14 @@
1
+ import rootname from "./rootname.js";
2
+ import liveview from "./liveview.js";
3
+
4
+ export default ({names, data}, options) => `
5
+ import * as components from "app";
6
+ let root = new components.${rootname}({
7
+ target: document.body,
8
+ hydrate: true,
9
+ props: {
10
+ components: [${names.map(name => `components.${name}`).join(", ")}],
11
+ data: JSON.parse(${JSON.stringify(JSON.stringify(data))}),
12
+ },
13
+ });
14
+ ${options.liveview ? liveview : ""}`;
@@ -0,0 +1,25 @@
1
+ export default (length, data) => {
2
+ const n = length - 1;
3
+ const body = Array.from({length: n}, (_, i) => i - 1)
4
+ .reduceRight((child, _, i) => `
5
+ {#if components[${i + 1}]}
6
+ <svelte:component this={components[${i}]} ${data}={data[${i}]}>
7
+ ${child}
8
+ </svelte:component>
9
+ {:else}
10
+ <svelte:component this={components[${i}]} ${data}={data[${i}]} />
11
+ {/if}
12
+ `, `<svelte:component this={components[${n}]} ${data}={data[${n}]} />`);
13
+
14
+ return `
15
+ <script>
16
+ import {afterUpdate} from "svelte";
17
+ export let components;
18
+ export let data;
19
+ export let update = () => undefined;
20
+
21
+ afterUpdate(update);
22
+ </script>
23
+ ${body}
24
+ `;
25
+ };
@@ -0,0 +1,3 @@
1
+ export {default as client} from "./client.js";
2
+ export {default as create_root} from "./create-root.js";
3
+ export {default as rootname} from "./rootname.js";
@@ -0,0 +1,16 @@
1
+ import rootname from "./rootname.js";
2
+
3
+ export default `
4
+ const {liveview} = components;
5
+ window.addEventListener("DOMContentLoaded", _ => liveview((props, update) => {
6
+ root.$destroy();
7
+ root = new components.${rootname}({
8
+ target: document.body,
9
+ hydrate: true,
10
+ props: {
11
+ components: props.names.map(name => components[name]),
12
+ data: props.data,
13
+ update,
14
+ },
15
+ });
16
+ }));`;
@@ -0,0 +1 @@
1
+ export default "root";
package/src/module.js CHANGED
@@ -4,13 +4,14 @@ import {Response, Status, MediaType} from "runtime-compat/http";
4
4
  import * as compiler from "svelte/compiler";
5
5
  import {tryreturn} from "runtime-compat/async";
6
6
  import errors from "./errors.js";
7
+ import {client, create_root, rootname} from "./client/exports.js";
7
8
 
8
9
  const endings = {
9
10
  svelte: ".svelte",
10
11
  js: ".svelte.js",
11
12
  };
12
- const rootname = "root";
13
13
 
14
+ const encoder = new TextEncoder();
14
15
  const hash = async (string, algorithm = "sha-256") => {
15
16
  const base = 16;
16
17
  const target_pad_length = 2;
@@ -25,11 +26,6 @@ const normalize = async path => `_${await hash(path)}`;
25
26
 
26
27
  const filename = `${rootname}.js`;
27
28
 
28
- const options = {
29
- server: {generate: "ssr", hydratable: true},
30
- client: {generate: "dom", hydratable: true},
31
- };
32
-
33
29
  const type = "module";
34
30
 
35
31
  const load = async path =>
@@ -39,10 +35,12 @@ const load = async path =>
39
35
  const make_component = base => async (name, props) =>
40
36
  ({name, component: await load(base.join(name)), props});
41
37
 
42
- const encoder = new TextEncoder();
43
-
44
38
  const handler = (name, props = {}, {status = Status.OK, page} = {}) =>
45
39
  async (app, {layouts = [], as_layout} = {}, request) => {
40
+ const options = {
41
+ liveview: app.liveview !== undefined,
42
+ };
43
+ const {headers} = request;
46
44
  const {paths} = app.build;
47
45
  const make = make_component(paths.server.join(app.config.build.app));
48
46
  if (as_layout) {
@@ -57,15 +55,14 @@ const handler = (name, props = {}, {status = Status.OK, page} = {}) =>
57
55
  const data = components.map(component => component.props);
58
56
  const names = await Promise.all(components.map(component =>
59
57
  normalize(component.name)));
60
-
61
- const liveview = app.liveview !== undefined;
62
- if (liveview && request.headers.get(app.liveview.header) !== undefined) {
58
+ if (options.liveview && headers.get(app.liveview.header) !== undefined) {
63
59
  return new Response(JSON.stringify({names, data}), {
64
60
  status,
65
61
  headers: {...await app.headers(),
66
62
  "Content-Type": MediaType.APPLICATION_JSON},
67
63
  });
68
64
  }
65
+
69
66
  const root = paths.server.join(filename);
70
67
  const imported = (await import(root)).default;
71
68
  const {html} = imported.render({
@@ -73,67 +70,21 @@ const handler = (name, props = {}, {status = Status.OK, page} = {}) =>
73
70
  data,
74
71
  });
75
72
 
76
- const code = `
77
- import * as components from "app";
78
- const getComponents = names =>
79
- Object.entries(components).filter(([name, component]) =>
80
- names.includes(name))
81
- .map(([, component]) => component);
82
- let root = new components.${rootname}({
83
- target: document.body,
84
- hydrate: true,
85
- props: {
86
- components: getComponents([${names.map(name => `"${name}"`)}]),
87
- data: JSON.parse(${JSON.stringify(JSON.stringify(data))}),
88
- },
89
- });
90
-
91
- ${liveview ? `
92
- const {liveview} = components;
93
- window.addEventListener("DOMContentLoaded", _ => liveview(props => {
94
- root.$destroy();
95
- root = new components.${rootname}({
96
- target: document.body,
97
- hydrate: true,
98
- props: {
99
- components: getComponents(props.names),
100
- data: props.data,
101
- },
102
- });
103
- }));
104
- ` : ""}
105
- `;
73
+ const code = client({names, data}, options);
106
74
 
107
75
  await app.publish({code, type, inline: true});
108
-
109
- const headers = await app.headers();
76
+ // needs to be called before app.render
77
+ const headers$ = await app.headers();
110
78
 
111
79
  return new Response(await app.render({body: html, page}), {
112
80
  status,
113
- headers: {...headers, "Content-Type": MediaType.TEXT_HTML},
81
+ headers: {...headers$, "Content-Type": MediaType.TEXT_HTML},
114
82
  });
115
83
  };
116
84
 
117
- const create_root = (length, data) => {
118
- const n = length - 1;
119
- const body = Array.from({length: n}, (_, i) => i - 1)
120
- .reduceRight((child, _, i) => `
121
- {#if components[${i + 1}]}
122
- <svelte:component this={components[${i}]} ${data}={data[${i}]}>
123
- ${child}
124
- </svelte:component>
125
- {:else}
126
- <svelte:component this={components[${i}]} ${data}={data[${i}]} />
127
- {/if}
128
- `, `<svelte:component this={components[${n}]} ${data}={data[${n}]} />`);
129
-
130
- return `
131
- <script>
132
- export let components;
133
- export let data;
134
- </script>
135
- ${body}
136
- `;
85
+ const options = {
86
+ server: {generate: "ssr", hydratable: true},
87
+ client: {generate: "dom", hydratable: true},
137
88
  };
138
89
 
139
90
  const {svelte, js} = endings;