@primate/solid 0.1.0 → 0.2.0
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 -2
- package/package.json +4 -3
- package/src/module.js +46 -132
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primate/solid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Primate Solid module",
|
|
5
5
|
"homepage": "https://primatejs.com/modules/solid",
|
|
6
6
|
"bugs": "https://github.com/primatejs/primate/issues",
|
|
@@ -16,12 +16,13 @@
|
|
|
16
16
|
"directory": "packages/solid"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"@primate/frontend": "^0.2.0",
|
|
19
20
|
"babel-preset-solid": "^1.7.7",
|
|
20
|
-
"runtime-compat": "^0.25.
|
|
21
|
+
"runtime-compat": "^0.25.7",
|
|
21
22
|
"solid-js": "^1.7.11"
|
|
22
23
|
},
|
|
23
24
|
"peerDependencies": {
|
|
24
|
-
"primate": "0.
|
|
25
|
+
"primate": "0.22"
|
|
25
26
|
},
|
|
26
27
|
"type": "module",
|
|
27
28
|
"exports": "./src/exports.js"
|
package/src/module.js
CHANGED
|
@@ -1,63 +1,38 @@
|
|
|
1
|
-
import crypto from "runtime-compat/crypto";
|
|
2
1
|
import {Path} from "runtime-compat/fs";
|
|
3
2
|
import {Response, Status, MediaType} from "runtime-compat/http";
|
|
3
|
+
import * as base from "@primate/frontend";
|
|
4
|
+
import {renderToString as render} from "solid-js/web";
|
|
4
5
|
import {transformAsync} from "@babel/core";
|
|
5
6
|
import solid from "babel-preset-solid";
|
|
6
|
-
import {renderToString} from "solid-js/web";
|
|
7
|
-
import {tryreturn} from "runtime-compat/async";
|
|
8
|
-
import errors from "./errors.js";
|
|
9
7
|
import {client, create_root, rootname, hydrate} from "./client/exports.js";
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
const packager = import.meta.runtime?.packager ?? "package.json";
|
|
13
|
-
const library = import.meta.runtime?.library ?? "node_modules";
|
|
14
|
-
|
|
15
|
-
const encoder = new TextEncoder();
|
|
16
|
-
const hash = async (string, algorithm = "sha-256") => {
|
|
17
|
-
const base = 16;
|
|
18
|
-
const target_pad_length = 2;
|
|
19
|
-
const target_slice = 12;
|
|
20
|
-
const bytes = await crypto.subtle.digest(algorithm, encoder.encode(string));
|
|
21
|
-
return Array.from(new Uint8Array(bytes))
|
|
22
|
-
.map(byte => byte.toString(base).padStart(target_pad_length, "0"))
|
|
23
|
-
.join("")
|
|
24
|
-
.slice(0, target_slice);
|
|
25
|
-
};
|
|
26
|
-
const normalize = async path => `solid_${await hash(path)}`;
|
|
9
|
+
const normalize = base.normalize("solid");
|
|
27
10
|
|
|
28
11
|
const import$ = async (module, app, copy_dependency) => {
|
|
29
|
-
const {
|
|
12
|
+
const {library, packager} = app;
|
|
13
|
+
const {http: {static: {root}}} = app.config;
|
|
30
14
|
const parts = module.split("/");
|
|
31
15
|
const path = [library, ...parts];
|
|
32
16
|
const pkg = await Path.resolve().join(...path, packager).json();
|
|
33
17
|
if (copy_dependency) {
|
|
34
18
|
const dependency = Path.resolve().join(...path);
|
|
35
|
-
const to = app.
|
|
19
|
+
const to = app.runpath(app.config.location.client, library, ...parts);
|
|
36
20
|
await dependency.file.copy(`${to}`);
|
|
37
21
|
}
|
|
38
22
|
|
|
39
23
|
const entry = pkg.exports["."].browser.import;
|
|
40
|
-
app.importmaps[module] = new Path(root,
|
|
24
|
+
app.importmaps[module] = new Path(root, library, module, entry).path;
|
|
41
25
|
};
|
|
42
26
|
|
|
43
|
-
const filename = `${rootname}.js`;
|
|
44
27
|
const type = "module";
|
|
45
28
|
|
|
46
|
-
const
|
|
47
|
-
tryreturn(async () => (await import(`${path}.js`)).default)
|
|
48
|
-
.orelse(error => {console.log(error);return errors.MissingComponent.throw(path.name, path)});
|
|
49
|
-
|
|
50
|
-
const make_component = base => async (name, props) =>
|
|
51
|
-
({name, component: await load(base.join(name)), props});
|
|
52
|
-
|
|
53
|
-
const handler = (name, props = {}, {status = Status.OK} = {}) =>
|
|
29
|
+
const handler = config => (name, props = {}, {status = Status.OK, page} = {}) =>
|
|
54
30
|
async (app, {layouts = [], as_layout} = {}, request) => {
|
|
31
|
+
const {make, root} = config;
|
|
32
|
+
const {headers} = request;
|
|
55
33
|
const options = {
|
|
56
34
|
liveview: app.liveview !== undefined,
|
|
57
35
|
};
|
|
58
|
-
const {headers} = request;
|
|
59
|
-
const {paths} = app.build;
|
|
60
|
-
const make = make_component(paths.server.join(app.config.build.app));
|
|
61
36
|
if (as_layout) {
|
|
62
37
|
return make(name, props);
|
|
63
38
|
}
|
|
@@ -78,9 +53,8 @@ const handler = (name, props = {}, {status = Status.OK} = {}) =>
|
|
|
78
53
|
});
|
|
79
54
|
}
|
|
80
55
|
|
|
81
|
-
const root = paths.server.join(filename);
|
|
82
56
|
const imported = (await import(root)).default;
|
|
83
|
-
const body =
|
|
57
|
+
const body = render(() => imported({
|
|
84
58
|
components: components.map(({component}) => component),
|
|
85
59
|
data,
|
|
86
60
|
}));
|
|
@@ -91,120 +65,60 @@ const handler = (name, props = {}, {status = Status.OK} = {}) =>
|
|
|
91
65
|
// needs to be called before app.render
|
|
92
66
|
const headers$ = await app.headers();
|
|
93
67
|
|
|
94
|
-
return new Response(await app.render({body}), {
|
|
68
|
+
return new Response(await app.render({body, page}), {
|
|
95
69
|
status,
|
|
96
70
|
headers: {...headers$, "Content-Type": MediaType.TEXT_HTML},
|
|
97
71
|
});
|
|
98
72
|
};
|
|
99
73
|
|
|
100
|
-
const options = {
|
|
101
|
-
server: [solid, {
|
|
102
|
-
generate: "ssr",
|
|
103
|
-
hydratable: true,
|
|
104
|
-
}],
|
|
105
|
-
client: [solid, {
|
|
106
|
-
generate: "dom",
|
|
107
|
-
hydratable: true,
|
|
108
|
-
}],
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
const transform = {
|
|
112
|
-
async server(file) {
|
|
113
|
-
return (await transformAsync(file, {presets: [options.server]})).code;
|
|
114
|
-
},
|
|
115
|
-
async client(file) {
|
|
116
|
-
return (await transformAsync(file, {presets: [options.client]})).code;
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
|
|
120
74
|
export default ({
|
|
121
|
-
|
|
75
|
+
directory,
|
|
76
|
+
dynamicProps,
|
|
122
77
|
extension = "jsx",
|
|
123
78
|
} = {}) => {
|
|
124
|
-
const env = {};
|
|
125
|
-
const copy_re = new RegExp(`^.*.(?:${extension})$`, "u");
|
|
126
|
-
const collect_re = new RegExp(`^.*.${extension}$`, "u");
|
|
127
|
-
const extensions = {
|
|
128
|
-
from: `.${extension}`,
|
|
129
|
-
to: `.${extension}.js`,
|
|
130
|
-
};
|
|
131
|
-
|
|
132
79
|
return {
|
|
133
|
-
name: "
|
|
134
|
-
init(app, next/*0.21 compat, remove >0.21*/ = () => null) {
|
|
135
|
-
env.source = app.build.paths.components;
|
|
136
|
-
|
|
137
|
-
return next(app);
|
|
138
|
-
},
|
|
80
|
+
name: "primate:solid",
|
|
139
81
|
register(app, next) {
|
|
140
|
-
app.register(extension, handler);
|
|
82
|
+
app.register(extension, handler(base.register({app, rootname})));
|
|
83
|
+
|
|
141
84
|
return next(app);
|
|
142
85
|
},
|
|
143
86
|
async compile(app, next) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}));
|
|
157
|
-
|
|
158
|
-
const root = await transform.server(create_root(app.layoutDepth,
|
|
159
|
-
dynamicProps));
|
|
160
|
-
const to = app.build.paths.server.join(filename);
|
|
161
|
-
await to.file.write(root);
|
|
87
|
+
await base.compile({
|
|
88
|
+
app,
|
|
89
|
+
directory: directory ?? app.config.location.components,
|
|
90
|
+
extension,
|
|
91
|
+
rootname,
|
|
92
|
+
create_root,
|
|
93
|
+
dynamicProps,
|
|
94
|
+
async compile(file) {
|
|
95
|
+
const presets = [[solid, {generate: "ssr", hydratable: true}]];
|
|
96
|
+
return (await transformAsync(file, {presets})).code;
|
|
97
|
+
},
|
|
98
|
+
});
|
|
162
99
|
|
|
163
100
|
return next(app);
|
|
164
101
|
},
|
|
165
102
|
async publish(app, next) {
|
|
166
|
-
|
|
167
|
-
await target.file.create();
|
|
168
|
-
|
|
169
|
-
// create client components
|
|
170
|
-
const components = await env.source.collect(collect_re);
|
|
171
|
-
await Promise.all(components.map(async component => {
|
|
172
|
-
const name = component.path.replace(`${env.source}/`, "");
|
|
173
|
-
const file = await component.file.read();
|
|
174
|
-
const code = await transform.client(file);
|
|
175
|
-
const build = app.config.build.app;
|
|
176
|
-
const {path} = component;
|
|
177
|
-
|
|
178
|
-
{
|
|
179
|
-
{
|
|
180
|
-
const src = `${path}.js`.replace(`${env.source}`, _ => build);
|
|
181
|
-
await app.publish({src,
|
|
182
|
-
code: code.replaceAll(extensions.from, extensions.to),
|
|
183
|
-
type});
|
|
184
|
-
}
|
|
185
|
-
const imported = await normalize(name);
|
|
186
|
-
app.bootstrap({
|
|
187
|
-
type: "script",
|
|
188
|
-
code: `export {default as ${imported}} from "./${name}.js";\n`,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
}));
|
|
192
|
-
|
|
103
|
+
// import libs
|
|
193
104
|
await import$("solid-js", app, true);
|
|
194
105
|
await import$("solid-js/web", app);
|
|
195
|
-
|
|
196
|
-
app.
|
|
197
|
-
|
|
198
|
-
{
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
106
|
+
// export hydration code
|
|
107
|
+
app.export({type: "script", code: hydrate});
|
|
108
|
+
|
|
109
|
+
await base.publish({
|
|
110
|
+
app,
|
|
111
|
+
directory: directory ?? app.config.location.components,
|
|
112
|
+
extension,
|
|
113
|
+
rootname,
|
|
114
|
+
create_root,
|
|
115
|
+
dynamicProps,
|
|
116
|
+
normalize,
|
|
117
|
+
async compile(file) {
|
|
118
|
+
const presets = [[solid, {generate: "dom", hydratable: true}]];
|
|
119
|
+
return {js: (await transformAsync(file, {presets})).code};
|
|
120
|
+
},
|
|
121
|
+
});
|
|
208
122
|
|
|
209
123
|
return next(app);
|
|
210
124
|
},
|