Skip to content

Commit

Permalink
test a monorepo setup
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Feb 18, 2021
1 parent 0581a4a commit e8b5880
Show file tree
Hide file tree
Showing 210 changed files with 38,428 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/wmr/demo/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FOO="bar"
OVERRIDE=1
EMPTY=
1 change: 1 addition & 0 deletions packages/wmr/demo/.env.development
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FOO_DEV="bar"
1 change: 1 addition & 0 deletions packages/wmr/demo/.env.development.local
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FOO_DEV_LOCAL="bar"
2 changes: 2 additions & 0 deletions packages/wmr/demo/.env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FOO_LOCAL="bar"
OVERRIDE=11
5 changes: 5 additions & 0 deletions packages/wmr/demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"alias": {
"react": "preact/compat"
}
}
22 changes: 22 additions & 0 deletions packages/wmr/demo/public/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useLoc } from './lib/loc.js';

export default function Header() {
const { url }: { url: string } = useLoc();
return (
<header>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/compat">Compat</a>
<a href="/class-fields">Class-Fields</a>
<a href="/files">Files</a>
<a href="/env">Env</a>
<a href="/error">Error</a>
</nav>
<label>
URL:
<input readonly value={url} ref={c => c && (c.size = c.value.length)} />
</label>
</header>
);
}
24 changes: 24 additions & 0 deletions packages/wmr/demo/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8">
<title>WMR Demo</title>
<meta name="description" content="WMR Demo">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="data:">
<link rel="preload" as="script" href="/index.tsx" crossorigin>
<link rel="stylesheet" href="/style.css">
</head>

<body>
<script type="module" src="/index.tsx"></script>

<!-- a little in-page console -->
<!-- <script type="module" src="https://not-rawgit.glitch.me/gist/developit/60b810cbcb55e1da198a634218adcc90/raw/tiny-console.js"></script> -->

<!-- test: external stylesheets don't break style HMR -->
<!-- <link rel="stylesheet" href="https://unpkg.com/spectre.css/dist/spectre.min.css"> -->
</body>

</html>
47 changes: 47 additions & 0 deletions packages/wmr/demo/public/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { h, render } from 'preact';
import { Loc, Router } from './lib/loc.js';
import lazy, { ErrorBoundary } from './lib/lazy.js';
import Home from './pages/home.js';
// import About from './pages/about/index.js';
import NotFound from './pages/_404.js';
import Header from './header.tsx';
// import './style.css';

const About = lazy(() => import('./pages/about/index.js'));
const CompatPage = lazy(() => import('./pages/compat.js'));
const ClassFields = lazy(() => import('./pages/class-fields.js'));
const Files = lazy(() => import('./pages/files/index.js'));
const Environment = lazy(async () => (await import('./pages/environment/index.js')).Environment);

export function App() {
return (
<Loc>
<div class="app">
<Header />
<ErrorBoundary>
<Router>
<Home path="/" />
<About path="/about" />
<CompatPage path="/compat" />
<ClassFields path="/class-fields" />
<Files path="/files" />
<Environment path="/env" />
<NotFound default />
</Router>
</ErrorBoundary>
</div>
</Loc>
);
}

if (typeof window !== 'undefined') {
render(<App />, document.body);
}

export async function prerender(data) {
const { prerender } = await import('./lib/prerender.js');
return await prerender(<App {...data} />);
}

// @ts-ignore
if (module.hot) module.hot.accept(u => render(<u.module.App />, document.body));
23 changes: 23 additions & 0 deletions packages/wmr/demo/public/lib/lazy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { h } from 'preact';
import { useState, useRef } from 'preact/hooks';

export default function lazy(load) {
let p, c;
return props => {
if (!p) p = load().then(m => ((c = (m && m.default) || m), 1));
const [, update] = useState(0);
const r = useRef(c);
if (!r.current) r.current = p.then(update);
if (c === undefined) throw p;
return h(c, props);
};
}

export function ErrorBoundary(props) {
this.componentDidCatch = absorb;
return props.children;
}
function absorb(err) {
if (err && err.then) this.__d = true;
else if (this.props.onError) this.props.onError(err);
}
77 changes: 77 additions & 0 deletions packages/wmr/demo/public/lib/loc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { h, createContext, cloneElement } from 'preact';
import { useContext, useMemo, useReducer, useEffect, useRef } from 'preact/hooks';

const UPDATE = (state, url, push) => {
if (url && url.type === 'click') {
const link = url.target.closest('a[href]');
if (!link || link.origin != location.origin) return state;
url.preventDefault();
push = true;
url = link.href.replace(location.origin, '');
} else if (typeof url !== 'string') url = location.pathname + location.search;
if (push === true) history.pushState(null, '', url);
else if (push === false) history.replaceState(null, '', url);
return url;
};

export function Loc(props) {
const [url, route] = useReducer(UPDATE, location.pathname + location.search);
const value = useMemo(() => {
const u = new URL(url, location.origin);
const path = u.pathname.replace(/(.)\/$/g, '$1');
return { url, path, query: Object.fromEntries(u.searchParams), route };
}, [url]);
useEffect(() => {
addEventListener('click', route);
addEventListener('popstate', route);
return () => {
removeEventListener('click', route);
removeEventListener('popstate', route);
};
});
return h(Loc.ctx.Provider, { value }, props.children);
}

export function Router(props) {
const [, update] = useReducer(c => c + 1, 0);
const loc = useLoc();
const { url, path, query } = loc;
const cur = useRef(loc);
const prev = useRef();
const curChildren = useRef();
const prevChildren = useRef();
const pending = useRef();
if (url !== cur.current.url) {
pending.current = null;
prev.current = cur.current;
prevChildren.current = curChildren.current;
cur.current = loc;
}
this.componentDidCatch = err => {
if (err && err.then) pending.current = err;
};
useEffect(() => {
let p = pending.current;
const commit = () => {
if (cur.current.url !== url || pending.current !== p) return;
if (props.onLoadEnd) props.onLoadEnd(url);
prev.current = prevChildren.current = null;
update(0);
};
if (p) {
if (props.onLoadStart) props.onLoadStart(url);
p.then(commit);
} else commit();
}, [url]);
const children = [].concat(...props.children);
let a = children.filter(c => c.props.path === path);
if (a.length == 0) a = children.filter(c => c.props.default);
curChildren.current = a.map((p, i) => cloneElement(p, { path, query }));
return curChildren.current.concat(prevChildren.current || []);
}

Loc.Router = Router;

Loc.ctx = createContext(/** @type {{ url: string, path: string, query: object, route }} */ ({}));

export const useLoc = () => useContext(Loc.ctx);
42 changes: 42 additions & 0 deletions packages/wmr/demo/public/lib/prerender.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// this should be provided by WMR or an npm module.

import { h, options, cloneElement } from 'preact';
import renderToString from 'preact-render-to-string';

let vnodeHook;

const old = options.vnode;
options.vnode = vnode => {
if (old) old(vnode);
if (vnodeHook) vnodeHook(vnode);
};

export async function prerender(vnode, data) {
let tries = 0;
if (typeof vnode === 'function') {
vnode = h(vnode, data);
} else if (data) {
vnode = cloneElement(vnode, data);
}
const render = () => {
if (++tries > 10) return;
try {
return renderToString(vnode);
} catch (e) {
if (e && e.then) return e.then(render);
throw e;
}
};
let links = new Set();
vnodeHook = ({ type, props }) => {
if (type === 'a' && props && props.href && (!props.target || props.target === '_self')) {
links.add(props.href);
}
};
try {
const html = await render();
return { html, links };
} finally {
vnodeHook = null;
}
}
8 changes: 8 additions & 0 deletions packages/wmr/demo/public/pages/_404.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const NotFound = () => (
<section>
<h1>404: Not Found</h1>
<p>It's gone :(</p>
</section>
);

export default NotFound;
11 changes: 11 additions & 0 deletions packages/wmr/demo/public/pages/about/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styles from './style.module.css';

const About = ({ query }) => (
<section class={styles.about}>
<h1>About</h1>
<p>My name is Jason.</p>
<pre>{JSON.stringify(query)}</pre>
</section>
);

export default About;
3 changes: 3 additions & 0 deletions packages/wmr/demo/public/pages/about/style.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.about {
background: #dbcfe7;
}
20 changes: 20 additions & 0 deletions packages/wmr/demo/public/pages/class-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Component } from 'preact';

export default class ClassFields extends Component {
state = {
value: 1
};

onClick = () => {
this.setState(prev => ({ value: prev.value + 1 }));
};

render() {
return (
<div>
<p>State: {this.state.value}</p>
<button onClick={this.onClick}>click me</button>
</div>
);
}
}
8 changes: 8 additions & 0 deletions packages/wmr/demo/public/pages/compat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { useState } from 'preact/hooks';
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';

export default function CompatDemo() {
const [value, onChange] = useState(new Date());
return <Calendar onChange={onChange} showWeekNumbers value={value} />;
}
1 change: 1 addition & 0 deletions packages/wmr/demo/public/pages/environment/foo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const foo = 42;
27 changes: 27 additions & 0 deletions packages/wmr/demo/public/pages/environment/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import './style.css';
import { foo } from './foo.js';

export function Environment() {
return (
<table>
<thead>
<tr>
<th>Name {foo}</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{Object.keys(process.env)
.sort()
.map(key => {
return (
<tr key={key}>
<td>{key}</td>
<td>{String(process.env[key])}</td>
</tr>
);
})}
</tbody>
</table>
);
}
16 changes: 16 additions & 0 deletions packages/wmr/demo/public/pages/environment/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
table {
margin: 4rem;
border-collapse: collapse;
border-spacing: 0;
}

td,
th {
padding: 0.5rem 0.75rem;
border: 0.0625rem solid #d0d0d0;
text-align: left;
}

tbody tr:nth-child(even) {
background: #eee;
}
Binary file added packages/wmr/demo/public/pages/files/img.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions packages/wmr/demo/public/pages/files/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import jpg from './img.jpg';

export default function Files() {
return (
<div style="padding: 2rem;">
<h1>Files</h1>
<p>
jpg: {jpg}
<br />
<img src={jpg} alt="" height="320" />
</p>
</div>
);
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit e8b5880

Please sign in to comment.