initial commit

This commit is contained in:
Julien Oculi 2024-01-23 14:13:26 +01:00
commit a0862ad35d
9 changed files with 846 additions and 0 deletions

16
client/app.tsx Normal file
View file

@ -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 (
<main>
<h2>Live example</h2>
<DbGraph db={siteDb} />
</main>
)
}

34
client/db_graph.tsx Normal file
View file

@ -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<HTMLDivElement>(null)
useEffect(() => {
drawDb({ db, graph })
}, [])
return <div class='graph' ref={graph}></div>
}
function drawDb({ db, graph }: { db: DbEntry[]; graph: Ref<HTMLDivElement> }) {
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',
},
})
}

View file

@ -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<HTMLAnchorElement>('#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<HTMLAnchorElement>('.cell-p>a')).map(
getNodeId,
)
}

530
client/site_db_manual.ts Normal file
View file

@ -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,
],
},
]

40
datas.ts Normal file
View file

@ -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] },
]

21
deno.json Normal file
View file

@ -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"
}
}

116
deno.lock Normal file
View file

@ -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"
}
}

12
script.tsx Normal file
View file

@ -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(<App />, document.body)

35
server.tsx Normal file
View file

@ -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 (
<html lang='fr'>
<head>
<title>Démo</title>
</head>
<body>
</body>
<script type='module' dangerouslySetInnerHTML={{ __html: script.code }}>
</script>
</html>
)
}
Deno.serve(() =>
new Response(ssr(<Template />), {
headers: {
'Content-Type': 'text/html; charset=utf-8',
},
})
)