+ ${name} +
+
+ ${description}
+
+ GitHub
+
+
${topics.map((txt) => html`${txt}`)}
+diff --git a/.eslintrc.json b/.eslintrc.json
index 3cc4182..4a7f0c4 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -28,7 +28,7 @@
}
},
{
- "files": ["src/**/*.js"],
+ "files": ["src/**/*.mjs"],
"env": {
"browser": true,
"es6": true
diff --git a/src/js/main.mjs b/src/js/main.mjs
index 134a980..e5a5ab2 100644
--- a/src/js/main.mjs
+++ b/src/js/main.mjs
@@ -1,66 +1,83 @@
-import { app, h, text } from 'https://cdn.skypack.dev/hyperapp@2';
+//@ts-check
+import { reactive, html } from 'https://esm.sh/@arrow-js/core';
-const initialState = {
- status: 'idle',
- repos: [],
-};
+/**
+ * @typedef {Object} Repository
+ * @property {string} name
+ * @property {string} topics
+ * @property {string} homepageUrl
+ * @property {string} description
+ * @property {string} url
+ */
-const SetStatus = (state, status) => ({ ...state, status });
+/**
+ * @typedef {Object} Data
+ * @property {'idle' | 'loading' | 'loaded' | 'error'} status
+ * @property {Repository[]} repos
+ */
-const GotProjects = (state, repos = []) => ({
- ...SetStatus(state, 'loaded'),
- repos,
+/**
+ * @type {Data}
+ */
+const data = reactive({
+ status: 'idle',
+ repos: [],
});
-function branch(prop, branches) {
- return branches[prop] || branches.default;
+function branch(branches) {
+ return branches[data.status] || branches.default;
}
-async function FetchProjects(dispatch) {
- dispatch(SetStatus, 'loading');
+async function fetchProjects() {
+ data.status = 'loading';
try {
const response = await fetch('/.netlify/functions/fetch-projects');
if (!response.ok) {
throw response;
}
- dispatch(GotProjects, await response.json());
+ Object.assign(data, {
+ status: 'loaded',
+ repos: await response.json(),
+ });
} catch (error) {
console.error(error);
- dispatch(SetStatus, 'error');
+ Object.assign(data, {
+ status: 'error',
+ repos: [],
+ });
}
}
-function Link(href, txt) {
- return h('a', { target: '_blank', href }, text(txt));
+/**
+ *
+ * @param {Repository} repository
+ * @returns
+ */
+function RepoItem({ name, topics, homepageUrl, description, url }) {
+ return html`
+ ${description} ${topics.map((txt) => html`${txt}`)}
+ ${name}
+
+
+
+ GitHub
+
+
Loading...
`, + loaded: data.repos.map(RepoItem), + error: html`Error!
`, + })}`; -function RepoItem({ name, topics, homepageUrl, description, url }) { - return h('article', { class: 'card' }, [ - h('header', {}, h('h2', {}, Link(homepageUrl, name))), - h('p', {}, [ - h('div', {}, text(description)), - h('small', {}, Link(url, 'GitHub')), - ]), - h('p', { class: 'cluster' }, topics.map(Label)), - ]); -} +template(document.getElementById('main')); -app({ - init: [initialState, [FetchProjects]], - node: document.getElementById('main'), - view: ({ repos, status }) => - h( - 'main', - {}, - branch(status, { - loading: h('p', {}, text('Loading...')), - loaded: h('div', {}, repos.map(RepoItem)), - error: h('p', {}, text('Error')), - }), - ), -}); +fetchProjects();