Skip to content

Commit

Permalink
frontend: expose request prop
Browse files Browse the repository at this point in the history
  • Loading branch information
terrablue committed Oct 22, 2023
1 parent 4fa0eec commit 23ad57c
Show file tree
Hide file tree
Showing 15 changed files with 64 additions and 20 deletions.
4 changes: 2 additions & 2 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
"react-dom": "^18.2.0",
"solid-js": "^1.8.3",
"svelte": "^4.2.2",
"vue": "^3.3.4"
"vue": "^3.3.6"
},
"dependencies": {
"runtime-compat": "^0.32.2"
"runtime-compat": "^0.32.3"
},
"peerDependencies": {
"@babel/core": "7",
Expand Down
14 changes: 12 additions & 2 deletions packages/frontend/src/frontends/common/handler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Response, Status, MediaType } from "runtime-compat/http";
import { map } from "runtime-compat/async";
import { valmap, filter } from "runtime-compat/object";
import register from "./register.js";

export default config => {
Expand All @@ -24,9 +25,17 @@ export default config => {
const data = components.map(component => component.props);
const names = await get_names(components);

const $request = {
request: {
...valmap(filter(request, ([, { get }]) =>
get !== undefined), o => o.get()),
url: request.url,
},
};

if (options.liveview &&
request.headers.get(app.liveview?.header) !== undefined) {
return new Response(JSON.stringify({ names, data }), {
return new Response(JSON.stringify({ names, data, ...$request }), {
status,
headers: { ...await app.headers(),
"Content-Type": MediaType.APPLICATION_JSON },
Expand All @@ -37,9 +46,10 @@ export default config => {
const { body, head } = render(imported, {
components: components.map(({ component }) => component),
data,
...$request,
});

const code = client({ names, data }, options);
const code = client({ names, data, ...$request }, options);
const inlined = await app.inline(code, "module");

const headers = app.headers({ script: inlined.csp });
Expand Down
4 changes: 2 additions & 2 deletions packages/frontend/src/frontends/common/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const ErrorInComponent = (name, path, error) => {
console.log(error);
errors.ErrorInComponent.throw(name, path);
};
const get_error = ({ code, url }, path) =>
in_component(code, new Path(url), new Path(path))
const get_error = (error, path) =>
in_component(error.code, new Path(error.url), new Path(path))
? MissingComponent
: ErrorInComponent;

Expand Down
8 changes: 4 additions & 4 deletions packages/frontend/src/frontends/react/client/create-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ export default length => {
const n = length - 1;
const body = Array.from({ length: n }, (_, i) => i - 1)
.reduceRight((child, _, i) => `components[${i + 1}] !== undefined
? createElement(components[${i}], {...data[${i}]}, ${child})
: createElement(components[${i}], {...data[${i}]})
`, `createElement(components[${n}], {...data[${n}]})`);
? createElement(components[${i}], {request, ...data[${i}]}, ${child})
: createElement(components[${i}], {request, ...data[${i}]})
`, `createElement(components[${n}], {request, ...data[${n}]})`);

return `
import {createElement} from "react";
import {HeadContext, is} from "@primate/frontend/react";
const {Provider} = HeadContext;
export default ({components, data, push_heads: value}) =>
export default ({components, data, request, push_heads: value}) =>
is.client ? ${body} : createElement(Provider, {value}, ${body});
`;
};
6 changes: 5 additions & 1 deletion packages/frontend/src/frontends/react/client/default.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import rootname from "./rootname.js";
import liveview from "./liveview.js";

export default ({ names, data }, options) => `
export default ({ names, data, request }, options) => `
import * as components from "app";
import {hydrateRoot, createElement, ReactHead} from "app";
Expand All @@ -10,6 +10,10 @@ export default ({ names, data }, options) => `
createElement(components.${rootname}, {
components: [${names.map(name => `components.${name}`).join(", ")}],
data: JSON.parse(${JSON.stringify(JSON.stringify(data))}),
request: {
...JSON.parse(${JSON.stringify(JSON.stringify(request))}),
url: new URL(location.href),
},
})
);
${options.liveview ? liveview : ""}`;
4 changes: 4 additions & 0 deletions packages/frontend/src/frontends/react/client/liveview.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ window.addEventListener("DOMContentLoaded", _ => liveview((props, update) => {
createElement(components.${rootname}, {
components: props.names.map(name => components[name]),
data: props.data,
request: {
...props.request,
url: new URL(location.href),
},
})
);
}));`;
9 changes: 5 additions & 4 deletions packages/frontend/src/frontends/solid/client/create-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ export default length => {
const n = length - 1;
const body = Array.from({ length: n }, (_, i) => i - 1)
.reduceRight((child, _, i) => `components[${i + 1}] !== undefined
? createComponent(components[${i}], {...data[${i}], children: ${child}})
: createComponent(components[${i}], {...data[${i}]})
`, `createComponent(components[${n}], {...data[${n}]})`);
? createComponent(components[${i}], {request, ...data[${i}],
children: ${child}})
: createComponent(components[${i}], {request, ...data[${i}]})
`, `createComponent(components[${n}], {request, ...data[${n}]})`);

return `
import {createComponent} from "solid-js/web";
import {HeadContext, is} from "@primate/frontend/solid";
const Provider = HeadContext.Provider;
export default ({components, data, push_heads: value}) =>
export default ({components, data, request, push_heads: value}) =>
is.client ? ${body} : <Provider value={value}>{${body}}</Provider>;
`;
};
6 changes: 5 additions & 1 deletion packages/frontend/src/frontends/solid/client/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import liveview from "./liveview.js";
const { groups: { code: hydration_script } } = generateHydrationScript()
.match(/^<script>(?<code>.*?)<\/script>/u);

export default ({ names, data }, options) => `
export default ({ names, data, request }, options) => `
import * as components from "app";
import {hydrate_solid, render_solid, SolidHead} from "app";
Expand All @@ -17,5 +17,9 @@ export default ({ names, data }, options) => `
let dispose = hydrate_solid(() => components.${rootname}({
components: [${names.map(name => `components.${name}`).join(", ")}],
data: JSON.parse(${JSON.stringify(JSON.stringify(data))}),
request: {
...JSON.parse(${JSON.stringify(JSON.stringify(request))}),
url: new URL(location.href),
},
}), globalThis.window.document.body);
${options.liveview ? liveview : ""}`;
4 changes: 4 additions & 0 deletions packages/frontend/src/frontends/solid/client/liveview.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ window.addEventListener("DOMContentLoaded", _ => liveview((props, update) => {
dispose = render_solid(() => components.${rootname}({
components: props.names.map(name => components[name]),
data: props.data,
request: {
...props.request,
url: new URL(location.href),
},
}), globalThis.window.document.body);
}));`;
8 changes: 5 additions & 3 deletions packages/frontend/src/frontends/svelte/client/create-root.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,21 @@ export default length => {
const body = Array.from({ length: n }, (_, i) => i - 1)
.reduceRight((child, _, i) => `
{#if components[${i + 1}]}
<svelte:component this={components[${i}]} {...data[${i}]}>
<svelte:component this={components[${i}]} {request} {...data[${i}]}>
${child}
</svelte:component>
{:else}
<svelte:component this={components[${i}]} {...data[${i}]} />
<svelte:component this={components[${i}]} {request} {...data[${i}]}/>
{/if}
`, `<svelte:component this={components[${n}]} {...data[${n}]} />`);
`, `<svelte:component this={components[${n}]} {request} {...data[${n}]}/>`);

return `
<script>
import {afterUpdate} from "svelte";
export let components;
export let data;
export let request;
export let update = () => undefined;
afterUpdate(update);
Expand Down
6 changes: 5 additions & 1 deletion packages/frontend/src/frontends/svelte/client/default.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import rootname from "./rootname.js";
import liveview from "./liveview.js";

export default ({ names, data }, options) => `
export default ({ names, data, request }, options) => `
import * as components from "app";
let root = new components.${rootname}({
target: document.body,
hydrate: true,
props: {
components: [${names.map(name => `components.${name}`).join(", ")}],
data: JSON.parse(${JSON.stringify(JSON.stringify(data))}),
request: {
...JSON.parse(${JSON.stringify(JSON.stringify(request))}),
url: new URL(location.href),
},
},
});
${options.liveview ? liveview : ""}`;
1 change: 1 addition & 0 deletions packages/frontend/src/frontends/svelte/client/exports.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { default } from "./default.js";
export { default as expose } from "./expose.js";
export { default as create_root } from "./create-root.js";
export { default as rootname } from "./rootname.js";
3 changes: 3 additions & 0 deletions packages/frontend/src/frontends/svelte/client/expose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default `
export {setContext} from "svelte";
`;
4 changes: 4 additions & 0 deletions packages/frontend/src/frontends/svelte/client/liveview.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ window.addEventListener("DOMContentLoaded", _ => liveview((props, update) => {
props: {
components: props.names.map(name => components[name]),
data: props.data,
request: {
...props.request,
url: new URL(location.href),
},
update,
},
});
Expand Down
3 changes: 3 additions & 0 deletions packages/frontend/src/frontends/svelte/imports.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as compiler from "svelte/compiler";
import { expose } from "./client/exports.js";

export const render = (component, ...args) => {
const { html, head } = component.render(...args);
Expand All @@ -7,6 +8,8 @@ export const render = (component, ...args) => {

export const prepare = async app => {
await app.import("svelte");
// expose code through "app", for bundlers
await app.export({ type: "script", code: expose });
};

export const compile = {
Expand Down

0 comments on commit 23ad57c

Please sign in to comment.