initial commit
This commit is contained in:
commit
a0862ad35d
16
client/app.tsx
Normal file
16
client/app.tsx
Normal 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
34
client/db_graph.tsx
Normal 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',
|
||||
},
|
||||
})
|
||||
}
|
42
client/fetch_db_from_site.ts
Normal file
42
client/fetch_db_from_site.ts
Normal 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
530
client/site_db_manual.ts
Normal 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
40
datas.ts
Normal 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
21
deno.json
Normal 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
116
deno.lock
Normal 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
12
script.tsx
Normal 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
35
server.tsx
Normal 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',
|
||||
},
|
||||
})
|
||||
)
|
Loading…
Reference in a new issue