Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions example/streaming/podlets/content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Podlet from '@podium/podlet';
import express from 'express';

const podlet = new Podlet({
name: 'content',
version: Date.now().toString(),
pathname: '/',
});

podlet.css({ value: 'http://localhost:6103/css' });

const app = express();

app.use(podlet.middleware());

app.get('/manifest.json', (req, res) => {
res.send(podlet);
});

app.get('/css', (req, res) => {
res.set('Content-Type', 'text/css');
res.send(`
.content {
border: 1px solid black;
border-radius: 5px;
width: 100%;
padding: 20px;
margin: 0;
margin-bottom: 20px;
box-sizing: border-box;
}
`);
});

app.get('/', (req, res) => {
res.send(`
<section class="content">
main content goes here
</section>
`);
Comment on lines +45 to +56
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The layout examples have some inline documentation explaining the different parts. It would be nice to have something similar for at least one of the podlets, or in a separate README.

If it's covered in the podlet-repo, perhaps link to docs there?

});

app.listen(6103, () => {
console.log(`content podlet server running at http://localhost:6103`);
});
45 changes: 45 additions & 0 deletions example/streaming/podlets/footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import Podlet from '@podium/podlet';
import express from 'express';

const podlet = new Podlet({
name: 'footer',
version: Date.now().toString(),
pathname: '/',
});

podlet.css({ value: 'http://localhost:6104/css' });

const app = express();

app.use(podlet.middleware());

app.get('/manifest.json', (req, res) => {
res.send(podlet);
});

app.get('/css', (req, res) => {
res.set('Content-Type', 'text/css');
res.send(`
footer {
border: 1px solid black;
border-radius: 5px;
width: 100%;
padding: 20px;
margin: 0;
margin-bottom: 20px;
box-sizing: border-box;
}
`);
});

app.get('/', (req, res) => {
res.send(`
<footer>
footer content
</footer>
`);
});

app.listen(6104, () => {
console.log(`footer podlet server running at http://localhost:6104`);
});
50 changes: 50 additions & 0 deletions example/streaming/podlets/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Podlet from '@podium/podlet';
import express from 'express';

const podlet = new Podlet({
name: 'header',
version: Date.now().toString(),
pathname: '/',
});

podlet.css({ value: 'http://localhost:6101/css' });

const app = express();

app.use(podlet.middleware());

app.get('/manifest.json', (req, res) => {
res.send(podlet);
});

app.get('/css', (req, res) => {
res.set('Content-Type', 'text/css');
res.send(`
header {
border: 1px solid black;
border-radius: 5px;
width: 100%;
padding: 20px;
margin: 0;
margin-bottom: 20px;
box-sizing: border-box;
}
header h1 {
text-align: center;
margin: 0;
padding: 0;
}
`);
});

app.get('/', (req, res) => {
res.send(`
<header>
<h1>Header</h1>
</header>
`);
});

app.listen(6101, () => {
console.log(`header podlet server running at http://localhost:6101`);
});
62 changes: 62 additions & 0 deletions example/streaming/podlets/menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import Podlet from '@podium/podlet';
import express from 'express';

const podlet = new Podlet({
name: 'menu',
version: Date.now().toString(),
pathname: '/',
});

podlet.css({ value: 'http://localhost:6102/css' });

const app = express();

app.use(podlet.middleware());

app.get('/manifest.json', (req, res) => {
res.send(podlet);
});

app.get('/css', (req, res) => {
res.set('Content-Type', 'text/css');
res.send(`
menu {
border: 1px solid black;
border-radius: 5px;
width: 100%;
padding: 10px;
margin: 0;
margin-bottom: 20px;
box-sizing: border-box;
}
menu ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
justify-content: space-evenly;
align-items: center;
}
menu ul li {
margin: 0;
padding: 0;
}
`);
});

app.get('/', (req, res) => {
res.send(`
<menu>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/things">Things</a></li>
<li><a href="/stuff">Stuff</a></li>
</ul>
</menu>
`);
});

app.listen(6102, () => {
console.log(`menu podlet server running at http://localhost:6102`);
});
165 changes: 165 additions & 0 deletions example/streaming/server-advanced.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import express from 'express';
import Layout from '../../lib/layout.js';

const layout = new Layout({
pathname: '/foo',
logger: console,
name: 'demo',
});

const content = layout.client.register({
name: 'content',
uri: 'http://localhost:6103/manifest.json',
});

const header = layout.client.register({
name: 'header',
uri: 'http://localhost:6101/manifest.json',
});

const menu = layout.client.register({
name: 'menu',
uri: 'http://localhost:6102/manifest.json',
});

const footer = layout.client.register({
name: 'footer',
uri: 'http://localhost:6104/manifest.json',
});

layout.css({ value: '/css' });

const app = express();

app.use(layout.pathname(), layout.middleware());

app.get('/foo/css', (req, res) => {
res.set('Content-Type', 'text/css');
res.send(`
@keyframes pulse {
0% {
background-color: #e0e0e0;
}
50% {
background-color: #f0f0f0;
}
100% {
background-color: #e0e0e0;
}
}
.skeleton {
width: 100%;
background-color: #e0e0e0;
border-radius: 5px;
animation: pulse 1.5s infinite ease-in-out;
margin: 0;
margin-bottom: 20px;
box-sizing: border-box;
}
.skeleton.header {
height:79px;
}
.skeleton.menu {
height:40px;
}
.skeleton.content {
height:60px;
}
.skeleton.footer {
height:60px;
}
`);
});

app.get(layout.pathname(), async (req, res) => {
const incoming = res.locals.podium;

incoming.view = {
title: 'Example streaming application',
};

const headerFetch = header.fetch(incoming);
const menuFetch = menu.fetch(incoming);
const contentFetch = content.fetch(incoming);
const footerFetch = footer.fetch(incoming);

incoming.hints.on('complete', async ({ js, css }) => {
// set the assets on httpincoming so that they are available in the document template
incoming.js = [...incoming.js, ...js];
incoming.css = [...incoming.css, ...css];

// set up the stream which will send the document template head
const stream = res.podiumStream();

// stream in the document body with slot placeholders for podlets
stream.send(`
<template shadowrootmode="open">
<link href="/foo/css" type="text/css" rel="stylesheet">
<div class="container">
<div>
<div>
<slot name="header"><div class="skeleton header"></div></slot>
</div>
</div>
<div>
<div>
<slot name="menu"><div class="skeleton menu"></div></slot>
</div>
<div>
<slot name="content"><div class="skeleton content"></div></slot>
</div>
</div>
<div>
<div>
<slot name="footer"><div class="skeleton footer"></div></slot>
</div>
</div>
</div>
</template>
`);

// fake 1 second delay
await new Promise((res) => setTimeout(res, 1000));

// stream in podlet content when available...
headerFetch.then((content) => {
stream.send(`<div slot="header">${content}</div>`);
});

await new Promise((res) => setTimeout(res, 1000));

menuFetch.then((content) => {
stream.send(`<div slot="menu">${content}</div>`);
});

await new Promise((res) => setTimeout(res, 1000));

contentFetch.then((content) => {
stream.send(`<div slot="content">${content}</div>`);
});

await new Promise((res) => setTimeout(res, 1000));

footerFetch.then((content) => {
stream.send(`<div slot="footer">${content}</div>`);
});

// close out the dom and the stream
await Promise.all([headerFetch, menuFetch, contentFetch, footerFetch]);
stream.done();
});
});

app.use(`${layout.pathname()}/assets`, express.static('assets'));

// eslint-disable-next-line no-unused-vars
app.use((error, req, res, next) => {
console.error(error);
res.status(500).send(
'<html><body><h1>Internal server error</h1></body></html>',
);
});

app.listen(6123, () => {
console.log(`layout server running at http://localhost:6123`);
});
Loading