From a0862ad35d1bc38ad04ef19d4b77803ce600d515 Mon Sep 17 00:00:00 2001 From: Julien Oculi Date: Tue, 23 Jan 2024 14:13:26 +0100 Subject: [PATCH] initial commit --- client/app.tsx | 16 ++ client/db_graph.tsx | 34 +++ client/fetch_db_from_site.ts | 42 +++ client/site_db_manual.ts | 530 +++++++++++++++++++++++++++++++++++ datas.ts | 40 +++ deno.json | 21 ++ deno.lock | 116 ++++++++ script.tsx | 12 + server.tsx | 35 +++ 9 files changed, 846 insertions(+) create mode 100644 client/app.tsx create mode 100644 client/db_graph.tsx create mode 100644 client/fetch_db_from_site.ts create mode 100644 client/site_db_manual.ts create mode 100644 datas.ts create mode 100644 deno.json create mode 100644 deno.lock create mode 100644 script.tsx create mode 100644 server.tsx diff --git a/client/app.tsx b/client/app.tsx new file mode 100644 index 0000000..61b5a12 --- /dev/null +++ b/client/app.tsx @@ -0,0 +1,16 @@ +import { DbGraph } from './db_graph.tsx' +import { siteDb } from './site_db_manual.ts' +// import { fetchDbFromSite } from './fetch_db_from_site.ts' + +//! Blocked by server config, return empty content +//! Get datas manually (site_db_manual.ts) +// const siteDb = await fetchDbFromSite('https://www.pierregrangepraderas.net/') + +export function App() { + return ( +
+

Live example

+ +
+ ) +} diff --git a/client/db_graph.tsx b/client/db_graph.tsx new file mode 100644 index 0000000..c270886 --- /dev/null +++ b/client/db_graph.tsx @@ -0,0 +1,34 @@ +import { Ref, useEffect, useRef } from 'preact/hooks' +import * as vis from 'vis-network' +import { DbEntry } from '../datas.ts' + +export function DbGraph({ db }: { db: DbEntry[] }) { + const graph = useRef(null) + + useEffect(() => { + drawDb({ db, graph }) + }, []) + + return
+} + +function drawDb({ db, graph }: { db: DbEntry[]; graph: Ref }) { + const nodes = db.map(({ id, title, links }) => ({ + id, + label: title, + value: links.length, + })) + + const edges = db.map(({ id, links }) => + links.map((link) => ({ from: id, to: link, value: id + link })) + ).flat() + + return new vis.Network(graph.current!, { + nodes, + edges, + }, { + nodes: { + shape: 'dot', + }, + }) +} diff --git a/client/fetch_db_from_site.ts b/client/fetch_db_from_site.ts new file mode 100644 index 0000000..4804b17 --- /dev/null +++ b/client/fetch_db_from_site.ts @@ -0,0 +1,42 @@ +import { DbEntry } from '../datas.ts' + +const domParser = new DOMParser() + +export async function fetchDbFromSite(siteUrl: string) { + const index = await fetch(siteUrl, { mode: 'no-cors' }) + .then((response) => response.text()) + .then((raw) => domParser.parseFromString(raw, 'text/html')) + + const nodes = Array.from( + index.querySelectorAll('#episodes>a'), + ) + .map((a) => ({ href: a.href, title: a.innerText })) + + const db: DbEntry[] = [] + + for (const node of nodes) { + const id = getNodeId(node) + const title = node.title + const content = node.href + const links = await getNodeLinks(node) + + db.push({ id, title, content, links }) + } + + return db +} + +function getNodeId({ href }: { href: string }) { + const { pathname } = new URL(href) + return Number.parseInt(pathname.slice(1, -5)) +} + +async function getNodeLinks({ href }: { href: string }) { + const page = await fetch(href, { mode: 'no-cors' }) + .then((response) => response.text()) + .then((raw) => domParser.parseFromString(raw, 'text/html')) + + return Array.from(page.querySelectorAll('.cell-p>a')).map( + getNodeId, + ) +} diff --git a/client/site_db_manual.ts b/client/site_db_manual.ts new file mode 100644 index 0000000..bb567d3 --- /dev/null +++ b/client/site_db_manual.ts @@ -0,0 +1,530 @@ +import { DbEntry } from '../datas.ts' + +export const siteDb: DbEntry[] = [ + { + 'id': 2, + 'title': '# 2 : Don-t-trust-the-curator', + 'content': 'https://www.pierregrangepraderas.net/2.html', + 'links': [], + }, + { + 'id': 14, + 'title': '# 14 : Empiric State Building I', + 'content': 'https://www.pierregrangepraderas.net/14.html', + 'links': [ + 1112, + 574, + ], + }, + { + 'id': 21, + 'title': '# 21 : Ne pensez pas...', + 'content': 'https://www.pierregrangepraderas.net/21.html', + 'links': [], + }, + { + 'id': 34, + 'title': '# 34 : la guerre des Clowns', + 'content': 'https://www.pierregrangepraderas.net/34.html', + 'links': [], + }, + { + 'id': 51, + 'title': '# 51 : Carte de la Ruche', + 'content': 'https://www.pierregrangepraderas.net/51.html', + 'links': [], + }, + { + 'id': 53, + 'title': '# 53 : Échec', + 'content': 'https://www.pierregrangepraderas.net/53.html', + 'links': [], + }, + { + 'id': 89, + 'title': '# 89 : Il faut, Il faut, HILFE!', + 'content': 'https://www.pierregrangepraderas.net/89.html', + 'links': [], + }, + { + 'id': 112, + 'title': '# 112 : Aiolos, Dieu des ventilateurs', + 'content': 'https://www.pierregrangepraderas.net/112.html', + 'links': [ + 1120, + 493, + 1041, + 372, + ], + }, + { + 'id': 121, + 'title': '# 121 : Language is a bitch', + 'content': 'https://www.pierregrangepraderas.net/121.html', + 'links': [], + }, + { + 'id': 125, + 'title': '# 125 : Déchariter', + 'content': 'https://www.pierregrangepraderas.net/125.html', + 'links': [], + }, + { + 'id': 131, + 'title': '# 131 : À voir temps marché', + 'content': 'https://www.pierregrangepraderas.net/131.html', + 'links': [], + }, + { + 'id': 142, + 'title': '# 142 : Fabuleux', + 'content': 'https://www.pierregrangepraderas.net/142.html', + 'links': [], + }, + { + 'id': 165, + 'title': '# 165 : Pelota Roja', + 'content': 'https://www.pierregrangepraderas.net/165.html', + 'links': [], + }, + { + 'id': 168, + 'title': '# 168 : Comme un monde', + 'content': 'https://www.pierregrangepraderas.net/168.html', + 'links': [], + }, + { + 'id': 179, + 'title': '# 179 : Black Heart For No expansion', + 'content': 'https://www.pierregrangepraderas.net/179.html', + 'links': [], + }, + { + 'id': 182, + 'title': '# 182 : Culture de la statistique', + 'content': 'https://www.pierregrangepraderas.net/182.html', + 'links': [], + }, + { + 'id': 185, + 'title': '# 185 : Le Réel', + 'content': 'https://www.pierregrangepraderas.net/185.html', + 'links': [], + }, + { + 'id': 191, + 'title': '# 191 : Standard Soul', + 'content': 'https://www.pierregrangepraderas.net/191.html', + 'links': [], + }, + { + 'id': 193, + 'title': '# 193 : Prisma de Sephoris', + 'content': 'https://www.pierregrangepraderas.net/193.html', + 'links': [], + }, + { + 'id': 205, + 'title': '# 205 : Le Festif', + 'content': 'https://www.pierregrangepraderas.net/205.html', + 'links': [], + }, + { + 'id': 216, + 'title': '# 216 : Ἐν ἀρχῇ UFO Λόγος', + 'content': 'https://www.pierregrangepraderas.net/216.html', + 'links': [], + }, + { + 'id': 226, + 'title': '# 226 : Victor et Fortuna', + 'content': 'https://www.pierregrangepraderas.net/226.html', + 'links': [], + }, + { + 'id': 229, + 'title': '# 229 : Victor', + 'content': 'https://www.pierregrangepraderas.net/229.html', + 'links': [ + 748, + ], + }, + { + 'id': 279, + 'title': '# 279 : Résister', + 'content': 'https://www.pierregrangepraderas.net/279.html', + 'links': [], + }, + { + 'id': 312, + 'title': '# 312 : CrePon et La lavande', + 'content': 'https://www.pierregrangepraderas.net/312.html', + 'links': [], + }, + { + 'id': 372, + 'title': "# 372 : Le voyage d'IB-DA dans le nord", + 'content': 'https://www.pierregrangepraderas.net/372.html', + 'links': [ + 493, + ], + }, + { + 'id': 386, + 'title': '# 386 : le hacking comme est-éthique', + 'content': 'https://www.pierregrangepraderas.net/386.html', + 'links': [], + }, + { + 'id': 387, + 'title': '# 387 : Conte-férence 11-02-15confMaisonEcoconfMaisonEco', + 'content': 'https://www.pierregrangepraderas.net/387.html', + 'links': [], + }, + { + 'id': 440, + 'title': '# 440 : les Inquiétrides', + 'content': 'https://www.pierregrangepraderas.net/440.html', + 'links': [], + }, + { + 'id': 493, + 'title': '# 493 : IB-DA', + 'content': 'https://www.pierregrangepraderas.net/493.html', + 'links': [ + 191, + 718, + 615, + 609, + 165, + ], + }, + { + 'id': 498, + 'title': '# 498 : We Make Resistance', + 'content': 'https://www.pierregrangepraderas.net/498.html', + 'links': [], + }, + { + 'id': 513, + 'title': '# 513 : Echelle de Môbius aka Le fantôme-ÂM', + 'content': 'https://www.pierregrangepraderas.net/513.html', + 'links': [], + }, + { + 'id': 559, + 'title': '# 559 : Le rucher du CAPC', + 'content': 'https://www.pierregrangepraderas.net/559.html', + 'links': [ + 636, + ], + }, + { + 'id': 584, + 'title': '# 584 : We Make Paperclips', + 'content': 'https://www.pierregrangepraderas.net/584.html', + 'links': [2014], + }, + { + 'id': 604, + 'title': "# 604 : Bureau d'essai", + 'content': 'https://www.pierregrangepraderas.net/604.html', + 'links': [], + }, + { + 'id': 609, + 'title': '# 609 : La montée des petits âmes', + 'content': 'https://www.pierregrangepraderas.net/609.html', + 'links': [], + }, + { + 'id': 615, + 'title': '# 615 : Fort-Daeffort-da', + 'content': 'https://www.pierregrangepraderas.net/615.html', + 'links': [ + 372, + 1041, + ], + }, + { + 'id': 636, + 'title': '# 636 : Punk BEEs not DeAd', + 'content': 'https://www.pierregrangepraderas.net/636.html', + 'links': [ + 559, + ], + }, + { + 'id': 641, + 'title': '# 641 : Ismes aux doigts levés', + 'content': 'https://www.pierregrangepraderas.net/641.html', + 'links': [], + }, + { + 'id': 646, + 'title': '# 646 : The sausages in the Darkness - opus 1', + 'content': 'https://www.pierregrangepraderas.net/646.html', + 'links': [], + }, + { + 'id': 708, + 'title': "# 708 : Ça n'est pas la carte...", + 'content': 'https://www.pierregrangepraderas.net/708.html', + 'links': [], + }, + { + 'id': 712, + 'title': '# 712 : Disruptive Bullshit', + 'content': 'https://www.pierregrangepraderas.net/712.html', + 'links': [], + }, + { + 'id': 718, + 'title': '# 718 : "S"', + 'content': 'https://www.pierregrangepraderas.net/718.html', + 'links': [ + 493, + ], + }, + { + 'id': 724, + 'title': '# 724 : Re-la_guerre', + 'content': 'https://www.pierregrangepraderas.net/724.html', + 'links': [], + }, + { + 'id': 748, + 'title': '# 748 : Le banquet des Plus', + 'content': 'https://www.pierregrangepraderas.net/748.html', + 'links': [], + }, + { + 'id': 768, + 'title': '# 768 : Apiers', + 'content': 'https://www.pierregrangepraderas.net/768.html', + 'links': [], + }, + { + 'id': 813, + 'title': "# 813 : His Master's Voices", + 'content': 'https://www.pierregrangepraderas.net/813.html', + 'links': [], + }, + { + 'id': 828, + 'title': '# 828 : PH-AM-Apparition', + 'content': 'https://www.pierregrangepraderas.net/828.html', + 'links': [], + }, + { + 'id': 912, + 'title': '# 912 : Un Golem !', + 'content': 'https://www.pierregrangepraderas.net/912.html', + 'links': [ + 4334, + ], + }, + { + 'id': 935, + 'title': "# 935 : Maux d'ordre", + 'content': 'https://www.pierregrangepraderas.net/935.html', + 'links': [], + }, + { + 'id': 946, + 'title': '# 946 : Please Interpret!', + 'content': 'https://www.pierregrangepraderas.net/946.html', + 'links': [], + }, + { + 'id': 950, + 'title': "# 950 : L'origine du codeorigine-du-codeorigine-du-code", + 'content': 'https://www.pierregrangepraderas.net/950.html', + 'links': [], + }, + { + 'id': 955, + 'title': '# 955 : Armira', + 'content': 'https://www.pierregrangepraderas.net/955.html', + 'links': [ + 2807, + ], + }, + { + 'id': 987, + 'title': '# 987 : Bénévole International en Entreprise', + 'content': 'https://www.pierregrangepraderas.net/987.html', + 'links': [], + }, + { + 'id': 992, + 'title': '# 992 : Death Athraction', + 'content': 'https://www.pierregrangepraderas.net/992.html', + 'links': [], + }, + { + 'id': 1024, + 'title': '# 1024 : Armoiries', + 'content': 'https://www.pierregrangepraderas.net/1024.html', + 'links': [], + }, + { + 'id': 1041, + 'title': '# 1041 : Linguic Pics Passage', + 'content': 'https://www.pierregrangepraderas.net/1041.html', + 'links': [ + 493, + ], + }, + { + 'id': 1112, + 'title': '# 1112 : Empiric State Building II', + 'content': 'https://www.pierregrangepraderas.net/1112.html', + 'links': [ + 205, + 14, + 574, + ], + }, + { + 'id': 1120, + 'title': '# 1120 : Les Katastropheins', + 'content': 'https://www.pierregrangepraderas.net/1120.html', + 'links': [ + 112, + 185, + ], + }, + { + 'id': 1122, + 'title': '# 1122 : NFT', + 'content': 'https://www.pierregrangepraderas.net/1122.html', + 'links': [ + 1885, + ], + }, + { + 'id': 1420, + 'title': '# 1420 : Le Graphostrophe', + 'content': 'https://www.pierregrangepraderas.net/1420.html', + 'links': [], + }, + { + 'id': 1692, + 'title': '# 1692 : Planète', + 'content': 'https://www.pierregrangepraderas.net/1692.html', + 'links': [], + }, + { + 'id': 1716, + 'title': '# 1716 : Espaces', + 'content': 'https://www.pierregrangepraderas.net/1716.html', + 'links': [], + }, + { + 'id': 1789, + 'title': '# 1789 : 1% Guillotine bot', + 'content': 'https://www.pierregrangepraderas.net/1789.html', + 'links': [], + }, + { + 'id': 1822, + 'title': '# 1822 : Ruche Valise', + 'content': 'https://www.pierregrangepraderas.net/1822.html', + 'links': [ + 768, + ], + }, + { + 'id': 1831, + 'title': "# 1831 : L'artiste, le libriste et le Hacker...", + 'content': 'https://www.pierregrangepraderas.net/1831.html', + 'links': [], + }, + { + 'id': 1885, + 'title': '# 1885 : Digitale_CaverneDigitale_CaverneDigitale_Caverne', + 'content': 'https://www.pierregrangepraderas.net/1885.html', + 'links': [ + 1122, + ], + }, + { + 'id': 1961, + 'title': '# 1961 : triptique-Nico', + 'content': 'https://www.pierregrangepraderas.net/1961.html', + 'links': [], + }, + { + 'id': 2018, + 'title': '# 2018 : Trouver Saussure', + 'content': 'https://www.pierregrangepraderas.net/2018.html', + 'links': [], + }, + { + 'id': 2145, + 'title': '# 2145 : Esbattre Solstice', + 'content': 'https://www.pierregrangepraderas.net/2145.html', + 'links': [], + }, + { + 'id': 2327, + 'title': '# 2327 : Messe Transhumaniste', + 'content': 'https://www.pierregrangepraderas.net/2327.html', + 'links': [], + }, + { + 'id': 2541, + 'title': '# 2541 : Make Install Politiks', + 'content': 'https://www.pierregrangepraderas.net/2541.html', + 'links': [], + }, + { + 'id': 2706, + 'title': '# 2706 : les Rotabators', + 'content': 'https://www.pierregrangepraderas.net/2706.html', + 'links': [ + 112, + ], + }, + { + 'id': 2807, + 'title': '# 2807 : Nekato La petite Sorcière', + 'content': 'https://www.pierregrangepraderas.net/2807.html', + 'links': [], + }, + { + 'id': 3023, + 'title': '# 3023 : Listen to me Major Walsh', + 'content': 'https://www.pierregrangepraderas.net/3023.html', + 'links': [], + }, + { + 'id': 3042, + 'title': '# 3042 : Œdipe learning', + 'content': 'https://www.pierregrangepraderas.net/3042.html', + 'links': [], + }, + { + 'id': 4183, + 'title': '# 4183 : if and only if-Nazrati', + 'content': 'https://www.pierregrangepraderas.net/4183.html', + 'links': [], + }, + { + 'id': 4334, + 'title': '# 4334d14 : Résidence à Nekatoenea', + 'content': 'https://www.pierregrangepraderas.net/4334d14.html', + 'links': [ + 279, + 912, + 955, + 3248, + 3042, + 168, + 2147, + 2807, + 279, + ], + }, +] diff --git a/datas.ts b/datas.ts new file mode 100644 index 0000000..dfd45bc --- /dev/null +++ b/datas.ts @@ -0,0 +1,40 @@ +export type DbEntry = { + id: number + title: string + content: string + links: number[] +} + +// Db example +export const db: DbEntry[] = [ + { id: 1, title: 'node1', content: 'Node 1 content', links: [3, 4] }, + { id: 2, title: 'node2', content: 'Node 2 content', links: [1, 11, 8] }, + { id: 3, title: 'node3', content: 'Node 3 content', links: [4, 2] }, + { id: 4, title: 'node4', content: 'Node 4 content', links: [10] }, + { id: 5, title: 'node5', content: 'Node 5 content', links: [] }, + { + id: 6, + title: 'node6', + content: 'Node 6 content', + links: [1, 7, 12, 15, 16], + }, + { id: 7, title: 'node7', content: 'Node 7 content', links: [3, 4] }, + { id: 8, title: 'node8', content: 'Node 8 content', links: [2, 3, 7] }, + { id: 9, title: 'node9', content: 'Node 9 content', links: [13, 14] }, + { id: 10, title: 'node10', content: 'Node 10 content', links: [4] }, + { id: 11, title: 'node11', content: 'Node 11 content', links: [7] }, + { id: 12, title: 'node12', content: 'Node 12 content', links: [20, 19, 18] }, + { + id: 13, + title: 'node13', + content: 'Node 13 content', + links: [17, 15, 13, 11, 10, 9], + }, + { id: 14, title: 'node14', content: 'Node 14 content', links: [8, 7, 6] }, + { id: 15, title: 'node15', content: 'Node 15 content', links: [] }, + { id: 16, title: 'node16', content: 'Node 16 content', links: [1, 2] }, + { id: 17, title: 'node17', content: 'Node 17 content', links: [9, 11] }, + { id: 18, title: 'node18', content: 'Node 18 content', links: [4, 6, 8] }, + { id: 19, title: 'node19', content: 'Node 19 content', links: [1, 3, 5] }, + { id: 20, title: 'node20', content: 'Node 20 content', links: [17] }, +] diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..70fc625 --- /dev/null +++ b/deno.json @@ -0,0 +1,21 @@ +{ + "tasks": { + "serve": "deno run --allow-env --allow-read --allow-write --allow-net --watch=./client,./script.tsx ./server.tsx" + }, + "fmt": { + "singleQuote": true, + "semiColons": false, + "useTabs": true + }, + "compilerOptions": { + "jsx": "react-jsx", + "jsxImportSource": "preact" + }, + "imports": { + "preact": "https://esm.sh/preact@10.19.3", + "preact/": "https://esm.sh/preact@10.19.3/", + "preact-render-to-string": "https://esm.sh/preact-render-to-string@6.3.1", + "vis-network": "https://esm.sh/vis-network@9.1.9", + "emit": "https://deno.land/x/emit@0.34.0/mod.ts" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..441bfda --- /dev/null +++ b/deno.lock @@ -0,0 +1,116 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "npm:vis-network@9.1.9": "npm:vis-network@9.1.9_@egjs+hammerjs@2.0.17_component-emitter@1.3.0_keycharm@0.4.0_uuid@9.0.0_vis-data@7.1.9__uuid@9.0.0__vis-util@5.0.7___@egjs+hammerjs@2.0.17___component-emitter@1.3.0__@egjs+hammerjs@2.0.17__component-emitter@1.3.0_vis-util@5.0.7__@egjs+hammerjs@2.0.17__component-emitter@1.3.0" + }, + "npm": { + "@egjs/hammerjs@2.0.17": { + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "dependencies": { + "@types/hammerjs": "@types/hammerjs@2.0.45" + } + }, + "@types/hammerjs@2.0.45": { + "integrity": "sha512-qkcUlZmX6c4J8q45taBKTL3p+LbITgyx7qhlPYOdOHZB7B31K0mXbP5YA7i7SgDeEGuI9MnumiKPEMrxg8j3KQ==", + "dependencies": {} + }, + "component-emitter@1.3.0": { + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dependencies": {} + }, + "keycharm@0.4.0": { + "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", + "dependencies": {} + }, + "uuid@9.0.0": { + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "dependencies": {} + }, + "vis-data@7.1.9_uuid@9.0.0_vis-util@5.0.7__@egjs+hammerjs@2.0.17__component-emitter@1.3.0_@egjs+hammerjs@2.0.17_component-emitter@1.3.0": { + "integrity": "sha512-COQsxlVrmcRIbZMMTYwD+C2bxYCFDNQ2EHESklPiInbD/Pk3JZ6qNL84Bp9wWjYjAzXfSlsNaFtRk+hO9yBPWA==", + "dependencies": { + "uuid": "uuid@9.0.0", + "vis-util": "vis-util@5.0.7_@egjs+hammerjs@2.0.17_component-emitter@1.3.0" + } + }, + "vis-network@9.1.9_@egjs+hammerjs@2.0.17_component-emitter@1.3.0_keycharm@0.4.0_uuid@9.0.0_vis-data@7.1.9__uuid@9.0.0__vis-util@5.0.7___@egjs+hammerjs@2.0.17___component-emitter@1.3.0__@egjs+hammerjs@2.0.17__component-emitter@1.3.0_vis-util@5.0.7__@egjs+hammerjs@2.0.17__component-emitter@1.3.0": { + "integrity": "sha512-Ft+hLBVyiLstVYSb69Q1OIQeh3FeUxHJn0WdFcq+BFPqs+Vq1ibMi2sb//cxgq1CP7PH4yOXnHxEH/B2VzpZYA==", + "dependencies": { + "@egjs/hammerjs": "@egjs/hammerjs@2.0.17", + "component-emitter": "component-emitter@1.3.0", + "keycharm": "keycharm@0.4.0", + "uuid": "uuid@9.0.0", + "vis-data": "vis-data@7.1.9_uuid@9.0.0_vis-util@5.0.7__@egjs+hammerjs@2.0.17__component-emitter@1.3.0_@egjs+hammerjs@2.0.17_component-emitter@1.3.0", + "vis-util": "vis-util@5.0.7_@egjs+hammerjs@2.0.17_component-emitter@1.3.0" + } + }, + "vis-util@5.0.7_@egjs+hammerjs@2.0.17_component-emitter@1.3.0": { + "integrity": "sha512-E3L03G3+trvc/X4LXvBfih3YIHcKS2WrP0XTdZefr6W6Qi/2nNCqZfe4JFfJU6DcQLm6Gxqj2Pfl+02859oL5A==", + "dependencies": { + "@egjs/hammerjs": "@egjs/hammerjs@2.0.17", + "component-emitter": "component-emitter@1.3.0" + } + } + } + }, + "redirects": { + "https://esm.sh/preact/jsx-runtime": "https://esm.sh/preact@10.15.1/jsx-runtime" + }, + "remote": { + "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", + "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d", + "https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9", + "https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf", + "https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37", + "https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f", + "https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d", + "https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b", + "https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", + "https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", + "https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d", + "https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44", + "https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757", + "https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21", + "https://deno.land/std@0.186.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.186.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.186.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.186.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.186.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", + "https://deno.land/std@0.186.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.186.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", + "https://deno.land/std@0.186.0/path/mod.ts": "ee161baec5ded6510ee1d1fb6a75a0f5e4b41f3f3301c92c716ecbdf7dae910d", + "https://deno.land/std@0.186.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", + "https://deno.land/std@0.186.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", + "https://deno.land/std@0.186.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/x/deno_cache@0.5.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e", + "https://deno.land/x/deno_cache@0.5.2/cache.ts": "92ce8511e1e5c00fdf53a41619aa77d632ea8e0fc711324322e4d5ebf8133911", + "https://deno.land/x/deno_cache@0.5.2/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0", + "https://deno.land/x/deno_cache@0.5.2/deps.ts": "26a75905652510b76e54b6d5ef3cf824d1062031e00782efcd768978419224e7", + "https://deno.land/x/deno_cache@0.5.2/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069", + "https://deno.land/x/deno_cache@0.5.2/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa", + "https://deno.land/x/deno_cache@0.5.2/file_fetcher.ts": "89616c50b6df73fb04e73d0b7cd99e5f2ed7967386913d65b9e8baa4238501f7", + "https://deno.land/x/deno_cache@0.5.2/http_cache.ts": "407135eaf2802809ed373c230d57da7ef8dff923c4abf205410b9b99886491fd", + "https://deno.land/x/deno_cache@0.5.2/lib/deno_cache_dir.generated.js": "18b6526d0c50791a73dd0eb894e99de1ac05ee79dcbd53298ff5b5b6b0757fe6", + "https://deno.land/x/deno_cache@0.5.2/lib/snippets/deno_cache_dir-77bed54ace8005e0/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6", + "https://deno.land/x/deno_cache@0.5.2/mod.ts": "0b4d071ad095128bdc2b1bc6e5d2095222dcbae08287261690ee9757e6300db6", + "https://deno.land/x/deno_cache@0.5.2/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2", + "https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66", + "https://deno.land/x/emit@0.34.0/_utils.ts": "98412edc7aa29e77d592b54fbad00bdec1b05d0c25eb772a5f8edc9813e08d88", + "https://deno.land/x/emit@0.34.0/emit.generated.js": "0586871a05d1602a105e184e29d9141c9856e3c93f4391533c0a107155216a3b", + "https://deno.land/x/emit@0.34.0/mod.ts": "b3d26b75a059ab4098ee191562bf21e634c5abf936b06d0c8d656a4e08f1e291", + "https://deno.land/x/wasmbuild@0.15.1/cache.ts": "9d01b5cb24e7f2a942bbd8d14b093751fa690a6cde8e21709ddc97667e6669ed", + "https://deno.land/x/wasmbuild@0.15.1/loader.ts": "8c2fc10e21678e42f84c5135d8ab6ab7dc92424c3f05d2354896a29ccfd02a63", + "https://esm.sh/preact-render-to-string@6.3.1": "0271e7b46cc287b7402e0ff3f6cb7acc2d705c88507c40ebb6492b4b6994a7eb", + "https://esm.sh/preact@10.19.3/jsx-runtime": "fbb7b13320ceb568f0c0cf81a83b56620e4d6d38ed0a05463080f8423ac72a57", + "https://esm.sh/stable/preact@10.19.2/denonext/preact.mjs": "dc999b6432dc04d74ad7b692a8801f346294d815266dff915d0f222c120fd0b0", + "https://esm.sh/stable/preact@10.19.3/denonext/jsx-runtime.js": "5e053858ef4f26caaf5e8a0032cb8658328cc1fde74727485eea09af2f10027c", + "https://esm.sh/stable/preact@10.19.3/denonext/preact.mjs": "56bdea10da1452aff749df2c9371c1368a90449cc53c522fa2e332327b33a860", + "https://esm.sh/v135/preact-render-to-string@6.3.1/denonext/preact-render-to-string.mjs": "4a20c2006328c1bf41ea0320558e0ed0a9f7835e83eabd33844c86ad1fc726dc" + } +} diff --git a/script.tsx b/script.tsx new file mode 100644 index 0000000..a0357bc --- /dev/null +++ b/script.tsx @@ -0,0 +1,12 @@ +import { h, render } from 'preact' +import { App } from './client/app.tsx' + +window['h'] = h + +declare global { + interface Window { + h: typeof h + } +} + +render(, document.body) diff --git a/server.tsx b/server.tsx new file mode 100644 index 0000000..d46dcd2 --- /dev/null +++ b/server.tsx @@ -0,0 +1,35 @@ +import { bundle } from 'emit' +import ssr from 'preact-render-to-string' +import denoConfig from './deno.json' with { type: 'json' } + +const script = await bundle('./script.tsx', { + minify: true, + type: 'module', + compilerOptions: { + inlineSourceMap: true, + jsxFactory: 'h', + }, + 'importMap': { imports: denoConfig.imports }, +}) + +function Template() { + return ( + + + Démo + + + + + + ) +} + +Deno.serve(() => + new Response(ssr(