commit d4b7a1ba998c6da1234b1e5e28a5a00eb46e0da7 Author: khannurien Date: Sat Jan 17 08:39:11 2026 +0100 initial commit diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..f9b1d30 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,54 @@ +FROM mcr.microsoft.com/devcontainers/base:ubuntu + +# Install dependencies for TeX Live installation and usage +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \ + perl \ + biber \ + wget \ + fontconfig \ + make \ + git \ + curl \ + python3 \ + python3-pygments \ + && rm -rf /var/lib/apt/lists/* + +# Set non-root user provided by Microsoft base image +ARG USERNAME=vscode + +# Switch to user home directory +USER $USERNAME +WORKDIR /home/$USERNAME + +# Set TeX Live paths and update environment +ENV TEXLIVE_INSTALL_PREFIX="/usr/local/texlive" +ENV TEXLIVE_INSTALL_TEXDIR="${TEXLIVE_INSTALL_PREFIX}/2025" +ENV PATH="${TEXLIVE_INSTALL_TEXDIR}/bin/x86_64-linux:${PATH}" + +# Download and install TeX Live 2025 as root +RUN wget -q https://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz && \ + tar -xzf install-tl-unx.tar.gz && \ + rm install-tl-unx.tar.gz && \ + cd install-tl-* && \ + echo "selected_scheme scheme-full" > texlive.profile && \ + echo "TEXDIR ${TEXLIVE_INSTALL_TEXDIR}" >> texlive.profile && \ + echo "TEXMFCONFIG /home/vscode/.texlive2025/texmf-config" >> texlive.profile && \ + echo "TEXMFVAR /home/vscode/.texlive2025/texmf-var" >> texlive.profile && \ + echo "instopt_adjustpath 1" >> texlive.profile && \ + echo "tlpdbopt_autobackup 0" >> texlive.profile && \ + sudo perl ./install-tl --profile=texlive.profile --no-interaction && \ + cd .. && rm -rf install-tl-* + +# User-writeable directories for TeX Live and LuaLaTeX +ENV TEXMFCONFIG="/home/vscode/.texlive2025/texmf-config" +ENV TEXMFVAR="/home/vscode/.texlive2025/texmf-var" +ENV LUAOTFLOAD_HOME="/home/vscode/.texlive2025/texmf-var/luatex-cache" +ENV LUAOTFLOAD_DB="/home/vscode/.texlive2025/texmf-var/luatex-cache/database.sqlite" + +# Install latexmk +RUN sudo tlmgr option autobackup 0 && \ + sudo tlmgr install latexmk && \ + sudo tlmgr path add + +# Set the working directory back to a neutral location +WORKDIR /workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..28d9e73 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,118 @@ +{ + "name": "LaTeX Dev Container", + "image": "ghcr.io/khannurien/latex-devcontainer:2025.12", + "customizations": { + "vscode": { + "settings": { + // VSCode text editor settings + "editor.fontSize": 16, + "editor.tabSize": 2, + "editor.lineHeight": 1.8, + "editor.cursorBlinking": "phase", + "editor.unicodeHighlight.nonBasicASCII": false, + "editor.wordWrap": "on", + "editor.wrappingStrategy": "advanced", + "editor.wordBasedSuggestions": "off", + // "editor.quickSuggestions": { + // "other": "on", + // "comments": "off", + // "strings": "off" + // }, + // "editor.acceptSuggestionOnEnter": "off", + // LaTeX Workshop settings + "latex-workshop.intellisense.package.enabled": true, + "latex-workshop.intellisense.unimathsymbols.enabled": true, + "latex-workshop.intellisense.citation.backend": "biblatex", + "latex-workshop.latex.outDir": "build", + "latex-workshop.latex.autoBuild.run": "onFileChange", + "latex-workshop.latex.autoBuild.interval": 3000, + "latex-workshop.synctex.afterBuild.enabled": true, + "latex-workshop.view.autoFocus.enabled": false, + "latex-workshop.view.pdf.reload.transition": "fade", + "latex-workshop.view.pdf.viewer": "tab", + "latex-workshop.view.pdf.zoom": "auto", + "latex-workshop.latex.tools": [ + { + "args": [ + "-shell-escape", + "-synctex=1", + "-interaction=nonstopmode", + "-file-line-error", + "-pdf", + "-outdir=%OUTDIR%", + "-out2dir=.", + "-pdflatex", + "-e", + "$bibtex='biber %O %S';", + "%DOC%" + ], + "command": "latexmk", + "name": "latexmk + pdflatex + biber" + }, + { + "args": [ + "-shell-escape", + "-synctex=1", + "-interaction=nonstopmode", + "-file-line-error", + "-pdf", + "-outdir=%OUTDIR%", + "-out2dir=.", + "-xelatex", + "-e", + "$bibtex='biber %O %S';", + "%DOC%" + ], + "command": "latexmk", + "name": "latexmk + xelatex + biber" + }, + { + "args": [ + "-shell-escape", + "-synctex=1", + "-interaction=nonstopmode", + "-file-line-error", + "-pdf", + "-outdir=%OUTDIR%", + "-out2dir=.", + "-lualatex", + "-e", + "$bibtex='biber %O %S';", + "%DOC%" + ], + "command": "latexmk", + "name": "latexmk + lualatex + biber" + } + ], + "latex-workshop.latex.recipes": [ + { + "name": "latexmk + lualatex + biber", + "tools": [ + "latexmk + lualatex + biber" + ] + }, + { + "name": "latexmk + xelatex + biber", + "tools": [ + "latexmk + xelatex + biber" + ] + }, + { + "name": "latexmk + pdflatex + biber", + "tools": [ + "latexmk + pdflatex + biber" + ] + } + ], + "latex-workshop.latex.recipe.default": "lastUsed" + }, + "extensions": [ + "james-yu.latex-workshop", + "wayou.vscode-todo-highlight" + ] + } + }, + "remoteUser": "vscode", + "updateRemoteUserUID": true, + "features": {} +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e964244 --- /dev/null +++ b/.gitignore @@ -0,0 +1,301 @@ +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.log +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 +.*.lb + +## Intermediate documents: +*.dvi +*.xdv +*-converted-to.* +# these rules might exclude image files for figures etc. +# *.ps +# *.eps +# *.pdf + +## Generated if empty string is given at "Please type another file name for output:" +.pdf + +## Bibliography auxiliary files (bibtex/biblatex/biber): +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.run.xml + +## Build tool auxiliary files: +*.fdb_latexmk +*.synctex +*.synctex(busy) +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync + +## Build tool directories for auxiliary files +# latexrun +latex.out/ + +## Auxiliary and intermediate files from other packages: +# algorithms +*.alg +*.loa + +# achemso +acs-*.bib + +# amsthm +*.thm + +# beamer +*.nav +*.pre +*.snm +*.vrb + +# changes +*.soc + +# comment +*.cut + +# cprotect +*.cpt + +# elsarticle (documentclass of Elsevier journals) +*.spl + +# endnotes +*.ent + +# fixme +*.lox + +# feynmf/feynmp +*.mf +*.mp +*.t[1-9] +*.t[1-9][0-9] +*.tfm + +#(r)(e)ledmac/(r)(e)ledpar +*.end +*.?end +*.[1-9] +*.[1-9][0-9] +*.[1-9][0-9][0-9] +*.[1-9]R +*.[1-9][0-9]R +*.[1-9][0-9][0-9]R +*.eledsec[1-9] +*.eledsec[1-9]R +*.eledsec[1-9][0-9] +*.eledsec[1-9][0-9]R +*.eledsec[1-9][0-9][0-9] +*.eledsec[1-9][0-9][0-9]R + +# glossaries +*.acn +*.acr +*.glg +*.glo +*.gls +*.glsdefs +*.lzo +*.lzs +*.slg +*.slo +*.sls + +# uncomment this for glossaries-extra (will ignore makeindex's style files!) +# *.ist + +# gnuplot +*.gnuplot +*.table + +# gnuplottex +*-gnuplottex-* + +# gregoriotex +*.gaux +*.glog +*.gtex + +# htlatex +*.4ct +*.4tc +*.idv +*.lg +*.trc +*.xref + +# hyperref +*.brf + +# knitr +*-concordance.tex +# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files +# *.tikz +*-tikzDictionary + +# listings +*.lol + +# luatexja-ruby +*.ltjruby + +# makeidx +*.idx +*.ilg +*.ind + +# minitoc +*.maf +*.mlf +*.mlt +*.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* + +# minted +_minted* +*.pyg + +# morewrites +*.mw + +# newpax +*.newpax + +# nomencl +*.nlg +*.nlo +*.nls + +# pax +*.pax + +# pdfpcnotes +*.pdfpc + +# sagetex +*.sagetex.sage +*.sagetex.py +*.sagetex.scmd + +# scrwfile +*.wrt + +# svg +svg-inkscape/ + +# sympy +*.sout +*.sympy +sympy-plots-for-*.tex/ + +# pdfcomment +*.upa +*.upb + +# pythontex +*.pytxcode +pythontex-files-*/ + +# tcolorbox +*.listing + +# thmtools +*.loe + +# TikZ & PGF +*.dpth +*.md5 +*.auxlock + +# titletoc +*.ptc + +# todonotes +*.tdo + +# vhistory +*.hst +*.ver + +# easy-todo +*.lod + +# xcolor +*.xcp + +# xmpincl +*.xmpi + +# xindy +*.xdy + +# xypic precompiled matrices and outlines +*.xyc +*.xyd + +# endfloat +*.ttt +*.fff + +# Latexian +TSWLatexianTemp* + +## Editors: +# WinEdt +*.bak +*.sav + +# Texpad +.texpadtmp + +# LyX +*.lyx~ + +# Kile +*.backup + +# gummi +.*.swp + +# KBibTeX +*~[0-9]* + +# TeXnicCenter +*.tps + +# auto folder when using emacs and auctex +./auto/* +*.el + +# expex forward references with \gathertags +*-tags.tex + +# standalone packages +*.sta + +# Makeindex log files +*.lpz + +# xwatermark package +*.xwm + +# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib +# option is specified. Footnotes are the stored in a file with suffix Notes.bib. +# Uncomment the next line to have this generated file ignored. +#*Notes.bib diff --git a/.vscode/ltex.dictionary.fr.txt b/.vscode/ltex.dictionary.fr.txt new file mode 100644 index 0000000..50f23dd --- /dev/null +++ b/.vscode/ltex.dictionary.fr.txt @@ -0,0 +1,3 @@ +UMR +STICC +POJO diff --git a/.vscode/ltex.hiddenFalsePositives.fr.txt b/.vscode/ltex.hiddenFalsePositives.fr.txt new file mode 100644 index 0000000..140586b --- /dev/null +++ b/.vscode/ltex.hiddenFalsePositives.fr.txt @@ -0,0 +1 @@ +{"rule":"FR_SPELLING_RULE","sentence":"^\\QVincent Lannurien 1 \\E(?:Dummy|Ina|Jimmy-|Dummy-|Maniquí-|Maniquíes-|Dummy\\+|Dummy's\\+)[0-9]+\\Q Vincent Lannurien\\E$"} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b51a8d7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,103 @@ +{ + // VSCode text editor settings + "editor.fontSize": 16, + "editor.tabSize": 2, + "editor.lineHeight": 1.8, + "editor.cursorBlinking": "phase", + "editor.unicodeHighlight.nonBasicASCII": false, + "editor.wordWrap": "on", + "editor.wrappingStrategy": "advanced", + "editor.wordBasedSuggestions": "off", + // "editor.quickSuggestions": { + // "other": "on", + // "comments": "off", + // "strings": "off" + // }, + // "editor.acceptSuggestionOnEnter": "off", + // LaTeX Workshop settings + "latex-workshop.intellisense.package.enabled": true, + "latex-workshop.intellisense.unimathsymbols.enabled": true, + "latex-workshop.intellisense.citation.backend": "biblatex", + "latex-workshop.latex.outDir": "build", + "latex-workshop.latex.autoBuild.run": "onFileChange", + "latex-workshop.latex.autoBuild.interval": 3000, + "latex-workshop.synctex.afterBuild.enabled": true, + "latex-workshop.view.autoFocus.enabled": false, + "latex-workshop.view.pdf.reload.transition": "fade", + "latex-workshop.view.pdf.viewer": "tab", + "latex-workshop.view.pdf.zoom": "auto", + "latex-workshop.latex.tools": [ + { + "args": [ + "-shell-escape", + "-synctex=1", + "-interaction=nonstopmode", + "-file-line-error", + "-pdf", + "-outdir=%OUTDIR%", + "-out2dir=.", + "-pdflatex", + "-e", + "$bibtex='biber %O %S';", + "%DOC%" + ], + "command": "latexmk", + "name": "latexmk + pdflatex + biber" + }, + { + "args": [ + "-shell-escape", + "-synctex=1", + "-interaction=nonstopmode", + "-file-line-error", + "-pdf", + "-outdir=%OUTDIR%", + "-out2dir=.", + "-xelatex", + "-e", + "$bibtex='biber %O %S';", + "%DOC%" + ], + "command": "latexmk", + "name": "latexmk + xelatex + biber" + }, + { + "args": [ + "-shell-escape", + "-synctex=1", + "-interaction=nonstopmode", + "-file-line-error", + "-pdf", + "-outdir=%OUTDIR%", + "-out2dir=.", + "-lualatex", + "-e", + "$bibtex='biber %O %S';", + "%DOC%" + ], + "command": "latexmk", + "name": "latexmk + lualatex + biber" + } + ], + "latex-workshop.latex.recipes": [ + { + "name": "latexmk + lualatex + biber", + "tools": [ + "latexmk + lualatex + biber" + ] + }, + { + "name": "latexmk + xelatex + biber", + "tools": [ + "latexmk + xelatex + biber" + ] + }, + { + "name": "latexmk + pdflatex + biber", + "tools": [ + "latexmk + pdflatex + biber" + ] + } + ], + "latex-workshop.latex.recipe.default": "lastUsed" +} \ No newline at end of file diff --git a/build/slides.bbl-SAVE-ERROR b/build/slides.bbl-SAVE-ERROR new file mode 100644 index 0000000..44fd23b --- /dev/null +++ b/build/slides.bbl-SAVE-ERROR @@ -0,0 +1,110 @@ +% $ biblatex auxiliary file $ +% $ biblatex bbl format version 3.3 $ +% Do not modify the above lines! +% +% This is an auxiliary file used by the 'biblatex' package. +% This file may safely be deleted. It will be recreated by +% biber as required. +% +\begingroup +\makeatletter +\@ifundefined{ver@biblatex.sty} + {\@latex@error + {Missing 'biblatex' package} + {The bibliography requires the 'biblatex' package.} + \aftergroup\endinput} + {} +\endgroup + + +\refsection{0} + \datalist[entry]{nty/global//global/global/global} + \entry{greggFlameGraph2016}{article}{}{} + \name{author}{1}{}{% + {{hash=b45aef384111d7e9dd71b74ba427b5f1}{% + family={Gregg}, + familyi={G\bibinitperiod}, + given={Brendan}, + giveni={B\bibinitperiod}}}% + } + \strng{namehash}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{fullhash}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{fullhashraw}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{bibnamehash}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{authorbibnamehash}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{authornamehash}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{authorfullhash}{b45aef384111d7e9dd71b74ba427b5f1} + \strng{authorfullhashraw}{b45aef384111d7e9dd71b74ba427b5f1} + \field{sortinit}{G} + \field{sortinithash}{32d67eca0634bf53703493fb1090a2e8} + \field{labelnamesource}{author} + \field{labeltitlesource}{title} + \field{abstract}{This visualization of software execution is a new necessity for performance profiling and debugging.} + \field{issn}{0001-0782, 1557-7317} + \field{journaltitle}{Communications of the ACM} + \field{langid}{english} + \field{month}{5} + \field{number}{6} + \field{title}{The Flame Graph} + \field{urlday}{16} + \field{urlmonth}{1} + \field{urlyear}{2026} + \field{volume}{59} + \field{year}{2016} + \field{urldateera}{ce} + \field{pages}{48\bibrangedash 57} + \range{pages}{10} + \verb{doi} + \verb 10.1145/2909476 + \endverb + \endentry + \entry{HandbookTypeScriptHandbook}{book}{}{} + \name{author}{1}{}{% + {{hash=140864078aeca1c7c35b4beb33c53c34}{% + family={Microsoft}, + familyi={M\bibinitperiod}}}% + } + \strng{namehash}{140864078aeca1c7c35b4beb33c53c34} + \strng{fullhash}{140864078aeca1c7c35b4beb33c53c34} + \strng{fullhashraw}{140864078aeca1c7c35b4beb33c53c34} + \strng{bibnamehash}{140864078aeca1c7c35b4beb33c53c34} + \strng{authorbibnamehash}{140864078aeca1c7c35b4beb33c53c34} + \strng{authornamehash}{140864078aeca1c7c35b4beb33c53c34} + \strng{authorfullhash}{140864078aeca1c7c35b4beb33c53c34} + \strng{authorfullhashraw}{140864078aeca1c7c35b4beb33c53c34} + \field{sortinit}{M} + \field{sortinithash}{4625c616857f13d17ce56f7d4f97d451} + \field{labelnamesource}{author} + \field{labeltitlesource}{title} + \field{howpublished}{https://www.typescriptlang.org/docs/handbook/intro.html} + \field{title}{The {{TypeScript Handbook}}} + \field{year}{2026} + \endentry + \entry{poggialiConciseTypeScriptBook2026}{book}{}{} + \name{author}{1}{}{% + {{hash=6455011b3c9d32fd16da63c7b54ef9e8}{% + family={Poggiali}, + familyi={P\bibinitperiod}, + given={Simone}, + giveni={S\bibinitperiod}}}% + } + \strng{namehash}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{fullhash}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{fullhashraw}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{bibnamehash}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{authorbibnamehash}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{authornamehash}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{authorfullhash}{6455011b3c9d32fd16da63c7b54ef9e8} + \strng{authorfullhashraw}{6455011b3c9d32fd16da63c7b54ef9e8} + \field{sortinit}{P} + \field{sortinithash}{ff3bcf24f47321b42cb156c2cc8a8422} + \field{labelnamesource}{author} + \field{labeltitlesource}{title} + \field{howpublished}{https://gibbok.github.io/typescript-book/book/the-concise-typescript-book/} + \field{title}{The {{Concise TypeScript Book}}} + \field{year}{2026} + \endentry + \enddatalist +\endrefsection +\endinput + diff --git a/build/slides.bcf-SAVE-ERROR b/build/slides.bcf-SAVE-ERROR new file mode 100644 index 0000000..820c979 --- /dev/null +++ b/build/slides.bcf-SAVE-ERROR @@ -0,0 +1,2377 @@ + + + + + + output_encoding + utf8 + + + input_encoding + utf8 + + + debug + 0 + + + mincrossrefs + 2 + + + minxrefs + 2 + + + sortcase + 1 + + + sortupper + 1 + + + + + + + alphaothers + + + + + extradatecontext + labelname + labeltitle + + + labelalpha + 0 + + + labelnamespec + shortauthor + author + shorteditor + editor + translator + + + labeltitle + 0 + + + labeltitlespec + shorttitle + title + maintitle + + + labeltitleyear + 0 + + + labeldateparts + 0 + + + labeldatespec + date + year + eventdate + origdate + urldate + nodate + + + julian + 0 + + + gregorianstart + 1582-10-15 + + + maxalphanames + 3 + + + maxbibnames + 3 + + + maxcitenames + 3 + + + maxsortnames + 3 + + + maxitems + 3 + + + minalphanames + 1 + + + minbibnames + 1 + + + mincitenames + 1 + + + minsortnames + 1 + + + minitems + 1 + + + nohashothers + 0 + + + noroman + 0 + + + nosortothers + 0 + + + pluralothers + 0 + + + singletitle + 0 + + + skipbib + 0 + + + skipbiblist + 0 + + + skiplab + 0 + + + sortalphaothers + + + + + sortlocale + french + + + sortingtemplatename + nty + + + sortsets + 0 + + + uniquelist + false + + + uniquename + false + + + uniqueprimaryauthor + 0 + + + uniquetitle + 0 + + + uniquebaretitle + 0 + + + uniquework + 0 + + + useprefix + 0 + + + useafterword + 1 + + + useannotator + 1 + + + useauthor + 1 + + + usebookauthor + 1 + + + usecommentator + 1 + + + useeditor + 1 + + + useeditora + 1 + + + useeditorb + 1 + + + useeditorc + 1 + + + useforeword + 1 + + + useholder + 1 + + + useintroduction + 1 + + + usenamea + 1 + + + usenameb + 1 + + + usenamec + 1 + + + usetranslator + 0 + + + useshortauthor + 1 + + + useshorteditor + 1 + + + + + + extradatecontext + labelname + labeltitle + + + labelalpha + 0 + + + labelnamespec + shortauthor + author + shorteditor + editor + translator + + + labeltitle + 0 + + + labeltitlespec + shorttitle + title + maintitle + + + labeltitleyear + 0 + + + labeldateparts + 0 + + + labeldatespec + date + year + eventdate + origdate + urldate + nodate + + + maxalphanames + 3 + + + maxbibnames + 3 + + + maxcitenames + 3 + + + maxsortnames + 3 + + + maxitems + 3 + + + minalphanames + 1 + + + minbibnames + 1 + + + mincitenames + 1 + + + minsortnames + 1 + + + minitems + 1 + + + nohashothers + 0 + + + noroman + 0 + + + nosortothers + 0 + + + singletitle + 0 + + + skipbib + 0 + + + skipbiblist + 0 + + + skiplab + 0 + + + uniquelist + false + + + uniquename + false + + + uniqueprimaryauthor + 0 + + + uniquetitle + 0 + + + uniquebaretitle + 0 + + + uniquework + 0 + + + useprefix + 0 + + + useafterword + 1 + + + useannotator + 1 + + + useauthor + 1 + + + usebookauthor + 1 + + + usecommentator + 1 + + + useeditor + 1 + + + useeditora + 1 + + + useeditorb + 1 + + + useeditorc + 1 + + + useforeword + 1 + + + useholder + 1 + + + useintroduction + 1 + + + usenamea + 1 + + + usenameb + 1 + + + usenamec + 1 + + + usetranslator + 0 + + + useshortauthor + 1 + + + useshorteditor + 1 + + + + + datamodel + labelalphanametemplate + labelalphatemplate + inheritance + translit + uniquenametemplate + namehashtemplate + sortingnamekeytemplate + sortingtemplate + extradatespec + extradatecontext + labelnamespec + labeltitlespec + labeldatespec + controlversion + alphaothers + sortalphaothers + presort + citepagerange + texencoding + bibencoding + sortingtemplatename + sortlocale + language + autolang + langhook + indexing + hyperref + backrefsetstyle + block + pagetracker + citecounter + citetracker + ibidtracker + idemtracker + opcittracker + loccittracker + labeldate + labeltime + dateera + date + time + eventdate + eventtime + origdate + origtime + urldate + urltime + alldatesusetime + alldates + alltimes + gregorianstart + autocite + notetype + uniquelist + uniquename + refsection + refsegment + citereset + sortlos + babel + datelabel + backrefstyle + arxiv + familyinits + giveninits + prefixinits + suffixinits + useafterword + useannotator + useauthor + usebookauthor + usecommentator + useeditor + useeditora + useeditorb + useeditorc + useforeword + useholder + useintroduction + usenamea + usenameb + usenamec + usetranslator + useshortauthor + useshorteditor + debug + loadfiles + safeinputenc + sortcase + sortupper + terseinits + abbreviate + dateabbrev + clearlang + sortcites + sortsets + backref + backreffloats + trackfloats + parentracker + labeldateusetime + datecirca + dateuncertain + dateusetime + eventdateusetime + origdateusetime + urldateusetime + julian + datezeros + timezeros + timezones + seconds + autopunct + punctfont + labelnumber + labelalpha + labeltitle + labeltitleyear + labeldateparts + pluralothers + nohashothers + nosortothers + noroman + singletitle + uniquetitle + uniquebaretitle + uniquework + uniqueprimaryauthor + defernumbers + locallabelwidth + bibwarn + useprefix + skipbib + skipbiblist + skiplab + dataonly + defernums + firstinits + sortfirstinits + sortgiveninits + labelyear + isbn + url + doi + eprint + related + subentry + bibtexcaseprotection + mincrossrefs + minxrefs + maxnames + minnames + maxbibnames + minbibnames + maxcitenames + mincitenames + maxsortnames + minsortnames + maxitems + minitems + maxalphanames + minalphanames + maxparens + dateeraauto + + + alphaothers + sortalphaothers + presort + indexing + citetracker + ibidtracker + idemtracker + opcittracker + loccittracker + uniquelist + uniquename + familyinits + giveninits + prefixinits + suffixinits + useafterword + useannotator + useauthor + usebookauthor + usecommentator + useeditor + useeditora + useeditorb + useeditorc + useforeword + useholder + useintroduction + usenamea + usenameb + usenamec + usetranslator + useshortauthor + useshorteditor + terseinits + abbreviate + dateabbrev + clearlang + labelnumber + labelalpha + labeltitle + labeltitleyear + labeldateparts + nohashothers + nosortothers + noroman + singletitle + uniquetitle + uniquebaretitle + uniquework + uniqueprimaryauthor + useprefix + skipbib + skipbiblist + skiplab + dataonly + skiplos + labelyear + isbn + url + doi + eprint + related + subentry + bibtexcaseprotection + labelalphatemplate + translit + sortexclusion + sortinclusion + extradatecontext + labelnamespec + labeltitlespec + labeldatespec + maxnames + minnames + maxbibnames + minbibnames + maxcitenames + mincitenames + maxsortnames + minsortnames + maxitems + minitems + maxalphanames + minalphanames + + + noinherit + nametemplates + labelalphanametemplatename + uniquenametemplatename + namehashtemplatename + sortingnamekeytemplatename + presort + indexing + citetracker + ibidtracker + idemtracker + opcittracker + loccittracker + uniquelist + uniquename + familyinits + giveninits + prefixinits + suffixinits + useafterword + useannotator + useauthor + usebookauthor + usecommentator + useeditor + useeditora + useeditorb + useeditorc + useforeword + useholder + useintroduction + usenamea + usenameb + usenamec + usetranslator + useshortauthor + useshorteditor + terseinits + abbreviate + dateabbrev + clearlang + labelnumber + labelalpha + labeltitle + labeltitleyear + labeldateparts + nohashothers + nosortothers + noroman + singletitle + uniquetitle + uniquebaretitle + uniquework + uniqueprimaryauthor + useprefix + skipbib + skipbiblist + skiplab + dataonly + skiplos + isbn + url + doi + eprint + related + subentry + bibtexcaseprotection + maxnames + minnames + maxbibnames + minbibnames + maxcitenames + mincitenames + maxsortnames + minsortnames + maxitems + minitems + maxalphanames + minalphanames + + + nametemplates + labelalphanametemplatename + uniquenametemplatename + namehashtemplatename + sortingnamekeytemplatename + uniquelist + uniquename + familyinits + giveninits + prefixinits + suffixinits + terseinits + nohashothers + nosortothers + useprefix + + + nametemplates + labelalphanametemplatename + uniquenametemplatename + namehashtemplatename + sortingnamekeytemplatename + uniquename + familyinits + giveninits + prefixinits + suffixinits + terseinits + useprefix + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + prefix + family + + + + + shorthand + label + labelname + labelname + + + year + + + + + + labelyear + year + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + prefix + family + given + + + + family + given + prefix + suffix + + + + + prefix + family + + + given + + + suffix + + + prefix + + + mm + + + + sf,sm,sn,pf,pm,pn,pp + family,given,prefix,suffix + boolean,integer,string,xml + default,transliteration,transcription,translation + + + article + artwork + audio + bibnote + book + bookinbook + booklet + collection + commentary + customa + customb + customc + customd + custome + customf + dataset + inbook + incollection + inproceedings + inreference + image + jurisdiction + legal + legislation + letter + manual + misc + movie + music + mvcollection + mvreference + mvproceedings + mvbook + online + patent + performance + periodical + proceedings + reference + report + review + set + software + standard + suppbook + suppcollection + suppperiodical + thesis + unpublished + video + xdata + + + sortyear + volume + volumes + abstract + addendum + annotation + booksubtitle + booktitle + booktitleaddon + chapter + edition + eid + entrysubtype + eprintclass + eprinttype + eventtitle + eventtitleaddon + gender + howpublished + indexsorttitle + indextitle + isan + isbn + ismn + isrn + issn + issue + issuesubtitle + issuetitle + issuetitleaddon + iswc + journalsubtitle + journaltitle + journaltitleaddon + label + langid + langidopts + library + mainsubtitle + maintitle + maintitleaddon + nameaddon + note + number + origtitle + pagetotal + part + relatedstring + relatedtype + reprinttitle + series + shorthandintro + subtitle + title + titleaddon + usera + userb + userc + userd + usere + userf + venue + version + shorthand + shortjournal + shortseries + shorttitle + sorttitle + sortshorthand + sortkey + presort + institution + lista + listb + listc + listd + liste + listf + location + organization + origlocation + origpublisher + publisher + afterword + annotator + author + bookauthor + commentator + editor + editora + editorb + editorc + foreword + holder + introduction + namea + nameb + namec + translator + shortauthor + shorteditor + sortname + authortype + editoratype + editorbtype + editorctype + editortype + bookpagination + nameatype + namebtype + namectype + pagination + pubstate + type + language + origlanguage + crossref + xref + date + endyear + year + month + day + hour + minute + second + timezone + yeardivision + endmonth + endday + endhour + endminute + endsecond + endtimezone + endyeardivision + eventdate + eventendyear + eventyear + eventmonth + eventday + eventhour + eventminute + eventsecond + eventtimezone + eventyeardivision + eventendmonth + eventendday + eventendhour + eventendminute + eventendsecond + eventendtimezone + eventendyeardivision + origdate + origendyear + origyear + origmonth + origday + orighour + origminute + origsecond + origtimezone + origyeardivision + origendmonth + origendday + origendhour + origendminute + origendsecond + origendtimezone + origendyeardivision + urldate + urlendyear + urlyear + urlmonth + urlday + urlhour + urlminute + urlsecond + urltimezone + urlyeardivision + urlendmonth + urlendday + urlendhour + urlendminute + urlendsecond + urlendtimezone + urlendyeardivision + doi + eprint + file + verba + verbb + verbc + url + xdata + ids + entryset + related + keywords + options + relatedoptions + pages + execute + + + abstract + annotation + authortype + bookpagination + crossref + day + doi + eprint + eprintclass + eprinttype + endday + endhour + endminute + endmonth + endsecond + endtimezone + endyear + endyeardivision + entryset + entrysubtype + execute + file + gender + hour + ids + indextitle + indexsorttitle + isan + ismn + iswc + keywords + label + langid + langidopts + library + lista + listb + listc + listd + liste + listf + minute + month + namea + nameb + namec + nameatype + namebtype + namectype + nameaddon + options + origday + origendday + origendhour + origendminute + origendmonth + origendsecond + origendtimezone + origendyear + origendyeardivision + orighour + origminute + origmonth + origsecond + origtimezone + origyear + origyeardivision + origlocation + origpublisher + origtitle + pagination + presort + related + relatedoptions + relatedstring + relatedtype + second + shortauthor + shorteditor + shorthand + shorthandintro + shortjournal + shortseries + shorttitle + sortkey + sortname + sortshorthand + sorttitle + sortyear + timezone + url + urlday + urlendday + urlendhour + urlendminute + urlendmonth + urlendsecond + urlendtimezone + urlendyear + urlhour + urlminute + urlmonth + urlsecond + urltimezone + urlyear + usera + userb + userc + userd + usere + userf + verba + verbb + verbc + xdata + xref + year + yeardivision + + + set + entryset + + + article + addendum + annotator + author + commentator + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + eid + issn + issue + issuetitle + issuesubtitle + issuetitleaddon + journalsubtitle + journaltitle + journaltitleaddon + language + note + number + origlanguage + pages + pubstate + series + subtitle + title + titleaddon + translator + version + volume + + + bibnote + note + + + book + author + addendum + afterword + annotator + chapter + commentator + edition + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + eid + foreword + introduction + isbn + language + location + maintitle + maintitleaddon + mainsubtitle + note + number + origlanguage + pages + pagetotal + part + publisher + pubstate + series + subtitle + title + titleaddon + translator + volume + volumes + + + mvbook + addendum + afterword + annotator + author + commentator + edition + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + foreword + introduction + isbn + language + location + note + number + origlanguage + pagetotal + publisher + pubstate + series + subtitle + title + titleaddon + translator + volume + volumes + + + inbook + bookinbook + suppbook + addendum + afterword + annotator + author + booktitle + bookauthor + booksubtitle + booktitleaddon + chapter + commentator + edition + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + eid + foreword + introduction + isbn + language + location + mainsubtitle + maintitle + maintitleaddon + note + number + origlanguage + part + publisher + pages + pubstate + series + subtitle + title + titleaddon + translator + volume + volumes + + + booklet + addendum + author + chapter + editor + editortype + eid + howpublished + language + location + note + pages + pagetotal + pubstate + subtitle + title + titleaddon + type + + + collection + reference + addendum + afterword + annotator + chapter + commentator + edition + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + eid + foreword + introduction + isbn + language + location + mainsubtitle + maintitle + maintitleaddon + note + number + origlanguage + pages + pagetotal + part + publisher + pubstate + series + subtitle + title + titleaddon + translator + volume + volumes + + + mvcollection + mvreference + addendum + afterword + annotator + author + commentator + edition + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + foreword + introduction + isbn + language + location + note + number + origlanguage + publisher + pubstate + subtitle + title + titleaddon + translator + volume + volumes + + + incollection + suppcollection + inreference + addendum + afterword + annotator + author + booksubtitle + booktitle + booktitleaddon + chapter + commentator + edition + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + eid + foreword + introduction + isbn + language + location + mainsubtitle + maintitle + maintitleaddon + note + number + origlanguage + pages + part + publisher + pubstate + series + subtitle + title + titleaddon + translator + volume + volumes + + + dataset + addendum + author + edition + editor + editortype + language + location + note + number + organization + publisher + pubstate + series + subtitle + title + titleaddon + type + version + + + manual + addendum + author + chapter + edition + editor + editortype + eid + isbn + language + location + note + number + organization + pages + pagetotal + publisher + pubstate + series + subtitle + title + titleaddon + type + version + + + misc + software + addendum + author + editor + editortype + howpublished + language + location + note + organization + pubstate + subtitle + title + titleaddon + type + version + + + online + addendum + author + editor + editortype + language + note + organization + pubstate + subtitle + title + titleaddon + version + + + patent + addendum + author + holder + location + note + number + pubstate + subtitle + title + titleaddon + type + version + + + periodical + addendum + editor + editora + editorb + editorc + editortype + editoratype + editorbtype + editorctype + issn + issue + issuesubtitle + issuetitle + issuetitleaddon + language + note + number + pubstate + series + subtitle + title + titleaddon + volume + yeardivision + + + mvproceedings + addendum + editor + editortype + eventday + eventendday + eventendhour + eventendminute + eventendmonth + eventendsecond + eventendtimezone + eventendyear + eventendyeardivision + eventhour + eventminute + eventmonth + eventsecond + eventtimezone + eventyear + eventyeardivision + eventtitle + eventtitleaddon + isbn + language + location + note + number + organization + pagetotal + publisher + pubstate + series + subtitle + title + titleaddon + venue + volumes + + + proceedings + addendum + chapter + editor + editortype + eid + eventday + eventendday + eventendhour + eventendminute + eventendmonth + eventendsecond + eventendtimezone + eventendyear + eventendyeardivision + eventhour + eventminute + eventmonth + eventsecond + eventtimezone + eventyear + eventyeardivision + eventtitle + eventtitleaddon + isbn + language + location + mainsubtitle + maintitle + maintitleaddon + note + number + organization + pages + pagetotal + part + publisher + pubstate + series + subtitle + title + titleaddon + venue + volume + volumes + + + inproceedings + addendum + author + booksubtitle + booktitle + booktitleaddon + chapter + editor + editortype + eid + eventday + eventendday + eventendhour + eventendminute + eventendmonth + eventendsecond + eventendtimezone + eventendyear + eventendyeardivision + eventhour + eventminute + eventmonth + eventsecond + eventtimezone + eventyear + eventyeardivision + eventtitle + eventtitleaddon + isbn + language + location + mainsubtitle + maintitle + maintitleaddon + note + number + organization + pages + part + publisher + pubstate + series + subtitle + title + titleaddon + venue + volume + volumes + + + report + addendum + author + chapter + eid + institution + isrn + language + location + note + number + pages + pagetotal + pubstate + subtitle + title + titleaddon + type + version + + + thesis + addendum + author + chapter + eid + institution + language + location + note + pages + pagetotal + pubstate + subtitle + title + titleaddon + type + + + unpublished + addendum + author + eventday + eventendday + eventendhour + eventendminute + eventendmonth + eventendsecond + eventendtimezone + eventendyear + eventendyeardivision + eventhour + eventminute + eventmonth + eventsecond + eventtimezone + eventyear + eventyeardivision + eventtitle + eventtitleaddon + howpublished + language + location + note + pubstate + subtitle + title + titleaddon + type + venue + + + abstract + addendum + afterword + annotator + author + bookauthor + booksubtitle + booktitle + booktitleaddon + chapter + commentator + editor + editora + editorb + editorc + foreword + holder + institution + introduction + issuesubtitle + issuetitle + issuetitleaddon + journalsubtitle + journaltitle + journaltitleaddon + location + mainsubtitle + maintitle + maintitleaddon + nameaddon + note + organization + origlanguage + origlocation + origpublisher + origtitle + part + publisher + relatedstring + series + shortauthor + shorteditor + shorthand + shortjournal + shortseries + shorttitle + sortname + sortshorthand + sorttitle + subtitle + title + titleaddon + translator + venue + + + article + book + inbook + bookinbook + suppbook + booklet + collection + incollection + suppcollection + manual + misc + mvbook + mvcollection + online + patent + periodical + suppperiodical + proceedings + inproceedings + reference + inreference + report + set + thesis + unpublished + + + date + year + + + + + set + + entryset + + + + article + + author + journaltitle + title + + + + book + mvbook + + author + title + + + + inbook + bookinbook + suppbook + + author + title + booktitle + + + + booklet + + + author + editor + + title + + + + collection + reference + mvcollection + mvreference + + editor + title + + + + incollection + suppcollection + inreference + + author + editor + title + booktitle + + + + dataset + + title + + + + manual + + title + + + + misc + software + + title + + + + online + + title + + url + doi + eprint + + + + + patent + + author + title + number + + + + periodical + + editor + title + + + + proceedings + mvproceedings + + title + + + + inproceedings + + author + title + booktitle + + + + report + + author + title + type + institution + + + + thesis + + author + title + type + institution + + + + unpublished + + author + title + + + + + isbn + + + issn + + + ismn + + + gender + + + + + + + slides.bib + + + HandbookTypeScriptHandbook + poggialiConciseTypeScriptBook2026 diff --git a/build/slides.pdf b/build/slides.pdf new file mode 100644 index 0000000..09be62e Binary files /dev/null and b/build/slides.pdf differ diff --git a/img/async-joke.jpg b/img/async-joke.jpg new file mode 100644 index 0000000..93151cc Binary files /dev/null and b/img/async-joke.jpg differ diff --git a/img/brace.png b/img/brace.png new file mode 100644 index 0000000..8309d30 Binary files /dev/null and b/img/brace.png differ diff --git a/img/deno.png b/img/deno.png new file mode 100644 index 0000000..2556453 Binary files /dev/null and b/img/deno.png differ diff --git a/img/flamegraph.png b/img/flamegraph.png new file mode 100644 index 0000000..59b3343 Binary files /dev/null and b/img/flamegraph.png differ diff --git a/img/http-message.png b/img/http-message.png new file mode 100644 index 0000000..a2a903e Binary files /dev/null and b/img/http-message.png differ diff --git a/img/javascript-alert.png b/img/javascript-alert.png new file mode 100644 index 0000000..4b4fbc5 Binary files /dev/null and b/img/javascript-alert.png differ diff --git a/img/jetbrains-ecosystem-2025-evolution.png b/img/jetbrains-ecosystem-2025-evolution.png new file mode 100644 index 0000000..ab53156 Binary files /dev/null and b/img/jetbrains-ecosystem-2025-evolution.png differ diff --git a/img/jetbrains-ecosystem-2025-platforms.png b/img/jetbrains-ecosystem-2025-platforms.png new file mode 100644 index 0000000..f5341b1 Binary files /dev/null and b/img/jetbrains-ecosystem-2025-platforms.png differ diff --git a/img/js-event-loop.png b/img/js-event-loop.png new file mode 100644 index 0000000..01ca26e Binary files /dev/null and b/img/js-event-loop.png differ diff --git a/img/js.png b/img/js.png new file mode 100644 index 0000000..7e798a2 Binary files /dev/null and b/img/js.png differ diff --git a/img/jsr.png b/img/jsr.png new file mode 100644 index 0000000..e252ae7 Binary files /dev/null and b/img/jsr.png differ diff --git a/img/logos.png b/img/logos.png new file mode 100644 index 0000000..f9f03cf Binary files /dev/null and b/img/logos.png differ diff --git a/img/netscape.png b/img/netscape.png new file mode 100644 index 0000000..accf054 Binary files /dev/null and b/img/netscape.png differ diff --git a/img/nodejs.png b/img/nodejs.png new file mode 100644 index 0000000..a789ce1 Binary files /dev/null and b/img/nodejs.png differ diff --git a/img/npm.png b/img/npm.png new file mode 100644 index 0000000..ad3ad03 Binary files /dev/null and b/img/npm.png differ diff --git a/img/oak.png b/img/oak.png new file mode 100644 index 0000000..4e85ae4 Binary files /dev/null and b/img/oak.png differ diff --git a/img/osi-model.png b/img/osi-model.png new file mode 100644 index 0000000..3dc3fe9 Binary files /dev/null and b/img/osi-model.png differ diff --git a/img/point.png b/img/point.png new file mode 100644 index 0000000..f4086bd Binary files /dev/null and b/img/point.png differ diff --git a/img/promises.png b/img/promises.png new file mode 100644 index 0000000..7e0439b Binary files /dev/null and b/img/promises.png differ diff --git a/img/scaling-monolith.png b/img/scaling-monolith.png new file mode 100644 index 0000000..0d8f37a Binary files /dev/null and b/img/scaling-monolith.png differ diff --git a/img/scaling-uservices.png b/img/scaling-uservices.png new file mode 100644 index 0000000..96f0d13 Binary files /dev/null and b/img/scaling-uservices.png differ diff --git a/img/series-of-tubes.png b/img/series-of-tubes.png new file mode 100644 index 0000000..236f0ab Binary files /dev/null and b/img/series-of-tubes.png differ diff --git a/img/sqlite.png b/img/sqlite.png new file mode 100644 index 0000000..1b3bb5f Binary files /dev/null and b/img/sqlite.png differ diff --git a/img/tbl.jpg b/img/tbl.jpg new file mode 100644 index 0000000..262ce99 Binary files /dev/null and b/img/tbl.jpg differ diff --git a/img/ts.png b/img/ts.png new file mode 100644 index 0000000..ed68967 Binary files /dev/null and b/img/ts.png differ diff --git a/res/.$architecture.drawio.bkp b/res/.$architecture.drawio.bkp new file mode 100644 index 0000000..898ec35 --- /dev/null +++ b/res/.$architecture.drawio.bkp @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/.$js-event-loop.drawio.bkp b/res/.$js-event-loop.drawio.bkp new file mode 100644 index 0000000..877e3c2 --- /dev/null +++ b/res/.$js-event-loop.drawio.bkp @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/architecture.drawio b/res/architecture.drawio new file mode 100644 index 0000000..5cdcdf3 --- /dev/null +++ b/res/architecture.drawio @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/js-event-loop.drawio b/res/js-event-loop.drawio new file mode 100644 index 0000000..877e3c2 --- /dev/null +++ b/res/js-event-loop.drawio @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/scaling.drawio b/res/scaling.drawio new file mode 100644 index 0000000..d8b05c7 --- /dev/null +++ b/res/scaling.drawio @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/slides.bib b/slides.bib new file mode 100644 index 0000000..7711c61 --- /dev/null +++ b/slides.bib @@ -0,0 +1,29 @@ +@book{poggialiConciseTypeScriptBook2026, + title = {The {{Concise TypeScript Book}}}, + author = {Poggiali, Simone}, + year = 2026, + howpublished = {https://gibbok.github.io/typescript-book/book/the-concise-typescript-book/}, +} + +@book{HandbookTypeScriptHandbook, + title = {The {{TypeScript Handbook}}}, + author = {Microsoft}, + year = 2026, + howpublished = {https://www.typescriptlang.org/docs/handbook/intro.html}, +} + +@article{greggFlameGraph2016, + title = {The Flame Graph}, + author = {Gregg, Brendan}, + year = 2016, + month = may, + journal = {Communications of the ACM}, + volume = {59}, + number = {6}, + pages = {48--57}, + issn = {0001-0782, 1557-7317}, + doi = {10.1145/2909476}, + urldate = {2026-01-16}, + abstract = {This visualization of software execution is a new necessity for performance profiling and debugging.}, + langid = {english}, +} diff --git a/slides.cls b/slides.cls new file mode 100644 index 0000000..ddd17f6 --- /dev/null +++ b/slides.cls @@ -0,0 +1,215 @@ +\ProvidesClass{slides}[27/01/2025 v1] + +\PassOptionsToPackage{dvipsnames}{xcolor} +\PassOptionsToPackage{unicode}{hyperref} +\PassOptionsToPackage{naturalnames}{hyperref} +\LoadClass[aspectratio=169,10pt]{beamer} + +% speaker notes +% open pdf in dual screen using pympress (https://github.com/Cimbali/pympress) +% \setbeameroption{show notes on second screen=right} + +% listings (should be loaded before csquotes) +\RequirePackage{minted} + +% language and encoding +\RequirePackage[french]{babel} +\RequirePackage[T1]{fontenc} +\RequirePackage{csquotes} + +% biblatex for references on slides +\RequirePackage[backend=biber]{biblatex} +% clean, short citations in footnotes (cf. https://tex.stackexchange.com/a/587604) +\renewbibmacro{in:}{} +% \AtEveryCitekey{\clearfield{journaltitle}} +\AtEveryCitekey{\clearfield{volume}} +\AtEveryCitekey{\clearfield{number}} +% \AtEveryCitekey{\clearfield{booktitle}} +% \AtEveryCitekey{\clearfield{series}} +\AtEveryCitekey{\clearfield{pages}} +\AtEveryCitekey{\clearfield{month}} +\AtEveryCitekey{\clearlist{publisher}} +\AtEveryCitekey{\clearname{editor}} +\AtEveryCitekey{\clearlist{location}} +\AtEveryCitekey{\clearfield{doi}} +\AtEveryCitekey{\clearfield{isbn}} +\AtEveryCitekey{\clearfield{issn}} +\AtEveryCitekey{\clearfield{eprint}} +\AtEveryCitekey{\clearfield{url}} +\AtEveryCitekey{\clearfield{urlyear}} +\AtEveryCitekey{\clearfield{urlmonth}} +\AtEveryCitekey{\clearfield{urlday}} +% include reference number in citations (cf. https://tex.stackexchange.com/a/176295) +\DeclareCiteCommand{\fullcite} + {\usebibmacro{prenote}} + {{\printtext[labelnumberwidth]{% + \printfield{prefixnumber}% + \printfield{labelnumber}}} % + \usedriver + {\DeclareNameAlias{sortname}{default}} + {\thefield{entrytype}}} + {\multicitedelim} + {\usebibmacro{postnote}} +% blank footnotes using \footnote[]{} +\let\svthefootnote\thefootnote +\textheight 1in +\newcommand\blankfootnote[1]{% + \let\thefootnote\relax\footnotetext{#1}% + \let\thefootnote\svthefootnote% +} +\let\svfootnote\footnote +\renewcommand\footnote[2][?]{% + \if\relax#1\relax% + \blankfootnote{#2}% + \else% + \if?#1\svfootnote{#2}\else\svfootnote[#1]{#2}\fi% + \fi +} + +% captions +\RequirePackage{caption} +\captionsetup{font=scriptsize,labelfont=scriptsize} + +% beamer theme +\usetheme{moloch} +\RequirePackage{appendixnumberbeamer} +\RequirePackage{fontspec} +\setsansfont[ + ItalicFont={Fira Sans Light Italic}, + BoldFont={Fira Sans}, + BoldItalicFont={Fira Sans Italic} +]{Fira Sans Light} +\setmonofont[BoldFont={Fira Mono Medium}]{Fira Mono} +% \setmonofont{Fantasque Sans Mono} +\AtBeginEnvironment{tabular}{% + \addfontfeature{Numbers={Monospaced}} +} +% https://steeven9.github.io/USI-LaTeX/html/packages_hyperref_babel_xcolor3.html +% Section 3.2 of: +% https://mirror.ibcp.fr/pub/CTAN/macros/latex/contrib/beamer-contrib/themes/moloch/moloch.pdf +\definecolor{ubo}{HTML}{8c3759} +\setbeamercolor{progress bar}{fg=ubo} +\setbeamercolor{title separator}{fg=ubo} +\setbeamercolor{frametitle}{bg=ubo} +% \setbeamercolor{progress bar}{fg=BrickRed} +% \setbeamercolor{title separator}{fg=BrickRed} +% footnote font size +\setbeamerfont{footnote}{size=\tiny} +% frame numbering font size +\setbeamerfont{footline}{size=\footnotesize} +% solid background for blocks +\molochset{block=fill} +% remove section frames +% \molochset{sectionpage=none} +% enable subsection frames +\molochset{subsectionpage=progressbar} +% table of contents +\setbeamertemplate{section in toc}[sections numbered] +% smaller first-level bullet points +\setbeamertemplate{itemize item}{\textbullet} +% smaller bibliography entries +\renewcommand*{\bibfont}{\scriptsize} + +% figures uncover animation (cf. https://tex.stackexchange.com/a/354033/95423) +\setbeamercovered{transparent} +\newcommand<>{\uncovergraphics}[2][{}]{ + \begin{tikzpicture} + \node[anchor=south west,inner sep=0] (B) at (4,0) + {\includegraphics[#1]{#2}}; + \alt#3{}{% + \fill [draw=none, fill=palette primary.fg, fill opacity=0.9] (B.north west) -- (B.north east) -- (B.south east) -- (B.south west) -- (B.north west) -- cycle; + } + \end{tikzpicture} +} + +% fonts and symbols +\RequirePackage{pifont} +\newcommand{\cmark}{\color{YellowGreen}\ding{51}} +\newcommand{\xmark}{\color{BrickRed}\ding{55}} +\RequirePackage{textcomp} +\RequirePackage{emoji} +% markers +\RequirePackage{circledsteps} +\pgfkeys{/csteps/inner color=white} +\pgfkeys{/csteps/fill color=black} +\newcommand{\DONE}{% + \CircledParamOpts{inner color=black, outer color=LimeGreen, fill color=LimeGreen}{1}{\textbf{DONE}} % +} +\newcommand{\TODO}{% + \CircledParamOpts{inner color=black, outer color=Goldenrod, fill color=Goldenrod}{1}{\textbf{TODO}} % +} +\newcommand{\FIXME}{% + \CircledParamOpts{inner color=white, outer color=Red, fill color=Red}{1}{\textbf{FIXME}} % +} +% custom font size for a slide (cf. https://tex.stackexchange.com/a/401409) +\RequirePackage{environ} +\newcommand{\customframefont}[1]{ + \setbeamertemplate{itemize/enumerate body begin}{#1} + \setbeamertemplate{itemize/enumerate subbody begin}{#1} +} +\NewEnviron{framefont}[1]{ + \customframefont{#1} % for itemize/enumerate + {#1 % For the text outside itemize/enumerate + \BODY + } + \customframefont{\normalsize} +} +% math +\RequirePackage{amsmath,amssymb,amsfonts} +% resizebox +\RequirePackage{graphicx} +\RequirePackage{subcaption} +% tables +\RequirePackage{tabularx} +\RequirePackage{booktabs} +% various tabular columns with text wrapping +\newcolumntype{L}{>{\arraybackslash}m{\linewidth}} +\newcolumntype{M}{>{\centering\arraybackslash}m{0.33\linewidth}} +\newcolumntype{Y}{>{\centering\arraybackslash}m{0.15\linewidth}} +\newcolumntype{y}{>{\arraybackslash}m{0.15\linewidth}} +% generic horizontally centered column with line breaks +\newcolumntype{Z}{>{\centering\arraybackslash}X} +% vertical centering of text in all tabularx columns +\renewcommand\tabularxcolumn[1]{m{#1}} +% links +\RequirePackage{hyperref} + +% redefine title page +% https://tex.stackexchange.com/a/396409 +% Section 6.2.3 of: +% https://ctan.math.illinois.edu/macros/latex/contrib/beamer-contrib/themes/moloch/moloch.pdf +\makeatletter +\setbeamertemplate{title page}{ + \begin{minipage}[b][\paperheight]{\textwidth} + % \vfill% + \ifx\inserttitle\@empty\else\usebeamertemplate*{title}\fi + \ifx\insertsubtitle\@empty\else\usebeamertemplate*{subtitle}\fi + \vspace{.2cm} + \ifx\insertdate\@empty\else\usebeamertemplate*{date}\fi + \usebeamertemplate*{title separator} + \vspace{-.2cm} + \begin{columns}[] + \column{0.4\linewidth} + \ifx\beamer@shortauthor\@empty\else\usebeamertemplate*{author}\fi + \column{0.4\linewidth} + % \begin{table}[] + % \begin{flushleft} + % \small + % \begin{tabular}{ll} + % Rapporteur & Blabla \\ + % Rapporteur & Blabla + % \end{tabular} + % \end{flushleft} + % \end{table} + \end{columns} + \begin{columns}[b] + \column{0.4\linewidth} + \ifx\insertinstitute\@empty\else\usebeamertemplate*{institute}\fi + \column{0.5\linewidth} + \vspace{-2cm} + \ifx\inserttitlegraphic\@empty\else\inserttitlegraphic\fi + \end{columns} + \vspace*{.2cm} + \end{minipage} +} +\makeatother diff --git a/slides.pdf b/slides.pdf new file mode 100644 index 0000000..09be62e Binary files /dev/null and b/slides.pdf differ diff --git a/slides.tex b/slides.tex new file mode 100644 index 0000000..4cce5b2 --- /dev/null +++ b/slides.tex @@ -0,0 +1,1306 @@ +\documentclass{slides} +\addbibresource{slides.bib} + +\title{Systèmes à objets répartis} +\subtitle{M1 Informatique, S8} +\date{Janvier 2026} +\titlegraphic{\flushright\includegraphics[height=1.3cm]{img/logos.png}\vspace{.5cm}} + +\author{ + \texorpdfstring{ + \begin{table}[] + \begin{flushleft} + \begin{tabular}{ll} + & Vincent Lannurien~\inst{1} \\ + & \url{vincent.lannurien@univ-brest.fr} \\ + \end{tabular} + \end{flushleft} + \end{table} + } + { + Vincent Lannurien + } +} + +\institute{ + \texorpdfstring{ + \begin{table}[] + \centering + \begin{flushleft} + \begin{tabular}{L} + \inst{1}~Lab-STICC, CNRS UMR 6285, Université de Bretagne Occidentale, Brest + \end{tabular} + \end{flushleft} + \end{table} + } + { + Lab-STICC, CNRS UMR 6285, Université de Bretagne Occidentale, Brest + } +} + +\begin{document} + +\maketitle + +\begin{frame}{Introduction} + ... +\end{frame} + +\begin{framefont}{\small} +\begin{frame}[t]{Plan du cours} + \begin{columns} + \column{0.5\textwidth} + \tableofcontents%[hideallsubsections] + + \column{0.5\textwidth} + \begin{center} + \includegraphics[width=0.9\columnwidth]{img/logos.png} + \end{center} + \end{columns} +\end{frame} +\end{framefont} + +\section{Organisation de l'UE} + +\begin{frame}{Organisation de l'UE -- Contenu} + \begin{itemize} + \item Objectifs : + \begin{itemize} + \item Développer une application suivant l'\textbf{architecture trois tiers}, s'appuyant sur des communications via \textbf{HTTP} et \textbf{WebSockets} ; + \item Comprendre les mécanismes de l'\textbf{authentification} (avec ou sans état) d'un client auprès d'un serveur ; + \item S'initier au \textbf{déploiement} d'une application répartie à l'aide d'un \textit{reverse proxy}. + \end{itemize} + \item Prérequis : + \begin{itemize} + \item Côté client : HTML/CSS + \end{itemize} + \item Méthode : + \begin{itemize} + \item Un peu de cours... + \item Beaucoup de pratique ! + \end{itemize} + \end{itemize} +\end{frame} + +\begin{frame}{Organisation de l'UE -- Logistique} + \begin{itemize} + \item Volume horaire : + \begin{itemize} + \item CM : 3 séances de 2h (total : 6h) + \item TP : 8 séances de 2h (total : 16h) + \end{itemize} + \item Contrôle des connaissances : + \begin{itemize} + \item TP noté (2h sur cette partie du cours) + \item Examen final (2h en tout) + \end{itemize} + \end{itemize} +\end{frame} + +\section{Introduction} + +\begin{frame}{Contenu du cours} + \begin{itemize} + \item État et gestion de l'état + \begin{itemize} + \item Contrats + \begin{itemize} + \item Interfaces + \item \textit{Data Transfer Objects} + \end{itemize} + \item Persistance + \begin{itemize} + \item Base de données + \item Cache + \end{itemize} + \end{itemize} + \item Protocoles + \begin{itemize} + \item HTTP + \begin{itemize} + \item \textit{Status codes} + \item \textit{CORS} (\textit{Cross-Origin Resource Sharing}) + \end{itemize} + \item Authentification + \begin{itemize} + \item \textit{Tokens} + \end{itemize} + \end{itemize} + \item Performances et profilage + \begin{itemize} + \item Instrumentation (serveur) + \item Inspecteur (client) + \item Injection de trafic + \end{itemize} + \item Déploiement + \begin{itemize} + \item SSL, certificats + \item \textit{Reverse proxy} + \end{itemize} + \end{itemize} +\end{frame} + +\begin{frame}{Technologies utilisées} + \begin{itemize} + \item Côté serveur : + \begin{itemize} + \item Runtime (Deno) + \item Langage (TypeScript) + \item Framework (Oak) + \item Base de données (SQLite) + \item Cache (Redis) + \end{itemize} + \item Côté client : + \begin{itemize} + \item Bundler (Vite) + \item Langage (TypeScript) + \item Framework (React) + \end{itemize} + \item Communications : + \begin{itemize} + \item Requêtes HTTP + \item WebSockets + \end{itemize} + \end{itemize} +\end{frame} + +\section{Cas d'usage} + +\begin{frame}{Présentation de l'application} + \begin{block}{Description} + L'application est une \textbf{plateforme de sondages en ligne}. + + Elle permet à des utilisateurs de \textbf{créer des sondages} et d'ajouter des \textbf{options de réponse}. + + Les participants peuvent \textbf{voter} pour une ou plusieurs options selon des règles définies par le créateur du sondage. + + L'application gère également l'\textbf{authentification} des utilisateurs et assure la \textbf{persistance} des données. + \end{block} +\end{frame} + +\begin{frame}{Présentation de l'application} + \begin{alertblock}{Acteurs} + Les acteurs de l'application sont les suivants : + + \begin{itemize} + \item Utilisateur authentifié : peut créer des sondages, voter, et consulter les résultats ; + \item Utilisateur invité : peut voter (si autorisé) et consulter les résultats (si autorisé) ; + \item Administrateur : peut gérer les sondages et les utilisateurs. + \end{itemize} + \end{alertblock} +\end{frame} + +\begin{frame}{Présentation de l'application} + \begin{alertblock}{Fonctionnalités} + Les principales fonctionnalités de l'application peuvent être résumées ainsi : + + \begin{itemize} + \item Création de sondages avec : titre, description, date de création, date d'expiration, statut (actif/inactif) ; + \item Ajout d'options à un sondage : texte descriptif ; + \item Vote pour une option de sondage ; + \item Consultation des résultats (nombre de votes par option) ; + \item Gestion des utilisateurs (inscription, authentification). + \end{itemize} + \end{alertblock} +\end{frame} + +\section{Architecture : modèle client/serveur} + +\begin{frame}{Vue d'ensemble} + +\end{frame} + +\begin{frame}{Monolithes ou microservices} + \centering + \includegraphics[width=.8\textwidth]{img/scaling-monolith.png} +\end{frame} + +\begin{frame}{Monolithes ou microservices} + \centering + \includegraphics[width=.8\textwidth]{img/scaling-uservices.png} +\end{frame} + +\section{JavaScript, TypeScript et runtime} + +\begin{frame}{JavaScript} + \centering + \includegraphics[width=.5\textwidth]{img/javascript-alert.png} +\end{frame} + +\begin{frame}{JavaScript} + \begin{columns} + \column{.8\textwidth} + \begin{itemize} + \item 1995 : Brendan Eich développe en 10 jours un langage simple, interprété par le navigateur, pour dynamiser les pages web + \item 1997 : première standardisation par ECMA (\textit{European Computer Manufacturers Association}) sous le nom ECMAScript + \item 2005 : AJAX popularise les applications web dynamiques + \item 2008 : Google publie la machine virtuelle V8 pour l'exécution du code JavaScript dans Chrome + \item 2009 : Node.js étend l'utilisation de JavaScript au côté serveur + \item 2010 -- 2014 : émergence des frameworks et d'un outillage moderne pour JavaScript (jQuery, AngularJS, etc.) + \item 2015 : ECMAScript Edition 6 (ES6/ES2015) transforme le langage (modules, classes, \textit{arrow functions}, \textit{Promises}) + \end{itemize} + + \column{.2\textwidth} + \includegraphics[width=\columnwidth]{img/js.png} + \includegraphics[width=\columnwidth]{img/netscape.png} + \includegraphics[width=\columnwidth]{img/nodejs.png} + \end{columns} +\end{frame} + +\begin{frame} + \begin{columns} + \column{.6\textwidth} + \centering + \includegraphics[width=.9\columnwidth]{img/jetbrains-ecosystem-2025-evolution.png} + + \column{.4\textwidth} + \begin{itemize} + \item \textit{"Among the most dramatic rises in real-world usage over the last five years is TypeScript."} + \end{itemize} + \end{columns} +\end{frame} + +\begin{frame} + \centering + \includegraphics[width=.7\columnwidth]{img/jetbrains-ecosystem-2025-platforms.png} + + \footnote[]{\url{https://devecosystem-2025.jetbrains.com/tools-and-trends}} +\end{frame} + +\begin{frame}{TypeScript} + \begin{itemize} + \item Conçu en 2012 par Anders Hejlsberg + \item Open source, maintenu par Microsoft + \item Ni interprété, ni compilé : langage \textbf{transpilé} vers JavaScript, \textit{superset} de JS + \item Exécutable dans n'importe quel \textit{runtime} JS (navigateur, Node.js, etc.) + \item Multi-paradigme : \textbf{fonctionnel}, générique, impératif, orienté objet + \end{itemize} +\end{frame} + +\begin{frame}{TypeScript} + \begin{columns} + \column{.8\textwidth} + \begin{itemize} + \item \textbf{Typage statique} : détecter les erreurs et incohérences à la compilation (donc avant l'exécution) + \item \textbf{Interopérabilité} : typage \textit{progressif} (tout fichier JavaScript valide est un fichier TypeScript valide) + \end{itemize} + + \column{.2\textwidth} + \includegraphics[width=\columnwidth]{img/ts.png} + \end{columns} + + Adoption par l'industrie : + \begin{itemize} + \item Slack~\footnote[frame]{\url{https://slack.engineering/typescript-at-slack/}} : migration du frontend React vers TS pour sécuriser les appels d'API et réduire les erreurs au runtime + \item Airbnb~\footnote[frame]{\url{https://www.youtube.com/watch?v=P-J9Eg7hJwE}} : typage progressif du code JS pour réduire les coûts de maintenance + \item Microsoft~\footnote[frame]{\url{https://www.git-tower.com/blog/developing-for-the-desktop-vscode}} : migration vers TS pour faciliter l'évolution de VS Code ($>$ 1M SLoC) + \item Shopify~\footnote[frame]{\url{https://shopify.engineering/migrating-large-typescript-codebases-project-references}} : migration frontend et backend pour fiabiliser les fonctions critiques + \end{itemize} +\end{frame} + +\begin{frame}{TypeScript} + \begin{itemize} + \item Ressources : + \begin{itemize} + \item \textit{The TypeScript Handbook}~\footnote{\fullcite{HandbookTypeScriptHandbook}} + \item \textit{The Concise TypeScript Book}~\footnote{\fullcite{poggialiConciseTypeScriptBook2026}} + \end{itemize} + \end{itemize} +\end{frame} + +\begin{frame}{TypeScript : typage du code JavaScript} + Types de base disponibles dans TypeScript~\footnote{\url{https://www.typescriptlang.org/docs/handbook/2/everyday-types.html}} : + \begin{itemize} + \item \texttt{boolean} + \item \texttt{number} + \item \texttt{string} + \item Tableaux (dynamiques) : \texttt{type[]} ou \texttt{Array} + \item Tuples (taille fixe) : \texttt{let x: [string, number]} + \item \texttt{enum} + \item \texttt{unknown} + \item \texttt{any} + \item \texttt{void} + \item \texttt{null} et \texttt{undefined} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Exercice 1 : les pièges du typage dynamique} + \begin{block}{Fonctions et paramètres} + \begin{itemize} + \item Écrire une fonction \texttt{addition(a, b)} qui additionne deux nombres. + \item Tester la fonction avec les entrées suivantes : + \end{itemize} + \end{block} + + \begin{minted}{js} +addition(2, 3); // attendu : 5 +addition("2", 3); // attendu : ? +addition(true, 3); // attendu : ? + \end{minted} + + \begin{alertblock}{Questions} + \begin{enumerate} + \item Que se passe-t-il pour les deux derniers cas ? + \item Quels problèmes cela pose-t-il poser dans une application réelle ? + \item Proposer une version TypeScript pour éviter ces erreurs \textit{à la compilation}. + \end{enumerate} + \end{alertblock} +\end{frame} + +\begin{frame}[fragile]{Exercice 1 : les pièges du typage dynamique} + \begin{minted}{ts} +function addition2(a: number, b: number): number { + return a + b; +} + +console.log(addition2(2, 3)); +// L'argument de type 'string' n'est pas attribuable au paramètre +// de type 'number'.ts(2345) +console.log(addition2("2", 3)); +// L'argument de type 'boolean' n'est pas attribuable au paramètre +// de type 'number'.ts(2345) +console.log(addition2(true, 3)); + \end{minted} +\end{frame} + +\begin{frame}[fragile]{JavaScript : POJO (\textit{Plain Old Java Object})} + \begin{minted}{js} +const o = { + "foo": "bar", + "value": 42, + other: true, +} + +console.log(o.foo); +console.log(o["value"]); +console.log(o.other); + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Typage, interfaces et classes} + \begin{columns} + \column{.5\textwidth} + \begin{minted}{ts} +// Définition +interface Bidule { + truc: string; + machin: number; + toto?: boolean; +} + +// Instanciation +const b: Bidule = { + truc: "bidule", + machin: 42, +}; + \end{minted} + + \column{.5\textwidth} + \begin{minted}{ts} +// Définition +class Bidule { + constructor( + public truc: string, + public machin: number, + public toto?: boolean, + ) {} +} + +// Instanciation +const b: Bidule = new Bidule( + "bidule", 42 +); + \end{minted} + \end{columns} +\end{frame} + +\begin{frame}[fragile]{Exercice 2 : interfaces et contrats} + \begin{block}{Typage des objets} + \begin{itemize} + \item Écrire une fonction \texttt{afficherUtilisateur(u)} qui prend un objet représentant un utilisateur et affiche son nom et son âge. + \item Tester la fonction avec les entrées suivantes : + \end{itemize} + \end{block} + + \begin{minted}{js} +afficherUtilisateur({ nom: "Alice", age: 25 }); +afficherUtilisateur({ nom: "Bob" }); + \end{minted} + + \begin{alertblock}{Questions} + \begin{enumerate} + \item Que se passe-t-il pour le second cas ? + \item Comment TypeScript peut-il garantir la présence des propriétés attendues ? + \item Proposer une solution avec TypeScript. + \end{enumerate} + \end{alertblock} +\end{frame} + +\begin{frame}[fragile]{Exercice 2 : interfaces et contrats} + \begin{minted}{ts} +interface Utilisateur { + nom: string; + age: number; +} + +function afficherUtilisateur(u: Utilisateur): void { + console.log(`${u.nom} a ${u.age} ans`); +} + +afficherUtilisateur({ nom: "Alice", age: 25 }); +// L'argument de type '{ nom: string; }' n'est pas attribuable +// au paramètre de type 'Utilisateur'. +// La propriété 'age' est absente du type '{ nom: string; }' +// mais obligatoire dans le type 'Utilisateur'.ts(2345) +afficherUtilisateur({ nom: "Bob" }); + \end{minted} +\end{frame} + +\begin{frame}{Typage, interfaces et classes} + \begin{itemize} + \item Types \textbf{effacés} à la compilation + \begin{itemize} + \item Pas d'impact sur les performances (compromis : temps de compilation vs temps d'exécution) + \item Une erreur de typage n'empêche pas la compilation vers JavaScript + \end{itemize} + \item Corollaire : il n'est pas possible de vérifier les types TypeScript \textbf{lors de l'exécution} du programme... + \item ... sauf pour les types primitifs de JavaScript ! + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Typage, interfaces et classes} + \begin{minted}{ts} +// type union : soit number, soit string +const fn = (x: number | string) => { + // typeof type guard + if (typeof x === 'number') { + return x + 1; + } + + return -1; +}; + \end{minted} + + \begin{minted}{ts} +// type union : soit string, soit null +const toUpperCase = (name: string | null) => { + // truthiness narrowing + if (name) { + return name.toUpperCase(); + } else { + return null; + } +}; + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Exercice 3 : types au \textit{runtime}} + \begin{minted}[fontsize=\footnotesize]{ts} +interface Animal { + name: string; +} +interface Dog extends Animal { + bark: () => void; +} +interface Cat extends Animal { + meow: () => void; +} +const makeNoise = (animal: Animal) => { + if (animal instanceof Dog) { + // 'Dog' fait référence à un type mais s'utilise en tant que valeur ici.ts(2693) + animal.bark(); + } else { + animal.meow(); + } +}; + \end{minted} + + \begin{alertblock}{Questions} + \begin{enumerate} + \item Que signifie l'erreur levée par le compilateur ? + \item Comment peut-on vérifier la nature de l'objet \texttt{animal} au \textit{runtime} ? + \end{enumerate} + \end{alertblock} +\end{frame} + +\begin{frame}[fragile]{Exercice 3 : types au \textit{runtime}} + \begin{minted}{ts} +interface Dog { + kind: "dog"; // Tagged union + bark: () => void; +} + +interface Cat { + kind: "cat"; // Tagged union + meow: () => void; +} + +type Animal = Dog | Cat; // Union type + +const makeNoise = (animal: Animal) => { + if (animal.kind === "dog") animal.bark(); + else animal.meow(); +}; + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Exercice 3 : types au \textit{runtime}} + \begin{minted}{ts} +class Dog { + constructor(public name: string, public bark: () => void) {} +} + +class Cat { + constructor(public name: string, public meow: () => void) {} +} + +type Animal = Dog | Cat; // Union type + +const makeNoise = (animal: Animal) => { + if (animal instanceof Dog) animal.bark(); + else animal.meow(); +}; + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Généricité} + \begin{itemize} + \item \texttt{SomeContainer} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Exercice 3 : types au \textit{runtime}} + \begin{minted}[fontsize=\footnotesize]{ts} +interface Dog { + kind: "dog"; // Tagged union + bark: () => void; +} +interface Cat { + kind: "cat"; // Tagged union + meow: () => void; +} +type Animal = Dog | Cat; +const makeNoise = (animal: Animal) => { + if (animal.kind === "dog") animal.bark(); + else animal.meow(); +}; +const dog: Dog = { + kind: "dog", + bark: () => console.log("bark") +}; +makeNoise(dog); + \end{minted} +\end{frame} + +\begin{frame}{Gestion des erreurs : exceptions} + \begin{itemize} + \item Exceptions + \item \texttt{try}/\texttt{catch} + \end{itemize} +\end{frame} + +\begin{frame}{Programmation asynchrone} + TODO: Exemple (requête API) avec figure + + Comment manipuler des données... + \begin{itemize} + \item que l'on n'a pas encore ? + \item que l'on n'aura peut-être jamais ? + \item qui l'on obtient dans un temps variable ? + \end{itemize} +\end{frame} + +\begin{frame}{Programmation asynchrone} + \begin{itemize} + \item API : \textbf{Promises} + \begin{itemize} + \item Traiter des opérations \textbf{asynchrones} + \item Une Promise \textit{encapsule un résultat futur} + \item Elle est associée à des \textit{callbacks} qui seront exécutés à l'obtention de ce résultat + \item Elle peut être \textit{résolue} (réussite) ou \textit{rejetée} (échec) + \end{itemize} + \end{itemize} + + \centering + \includegraphics[width=.8\textwidth]{img/promises.png} + + \footnote[]{\url{https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise}} +\end{frame} + +\begin{frame}[fragile]{Programmation asynchrone} + \begin{minted}[fontsize=\footnotesize]{ts} +function repeatMaybe(repeat: string): Promise { + return new Promise((resolve, reject) => { + const maybe: number = randomIntegerBetween(0, 1); + + if (!maybe) { + reject("Nope"); + return; + } + + setTimeout(() => { + resolve(repeat); + }, 1000); + }); +} + +const blabla = repeatMaybe("bla").then((result: string) => { + console.log(result); +}).catch((error: string) => { + console.log(error) +}); + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Programmation asynchrone} + \begin{columns} + \column{.5\textwidth} + \begin{itemize} + \item API : \texttt{async}/\texttt{await} + \begin{itemize} + \item Sucre syntaxique pour "aplatir" du code asynchrone + \item \texttt{async} définit une fonction asynchrone + \item \texttt{await} met l'exécution du programme en pause dans l'attente d'un résultat + \end{itemize} + \end{itemize} + + \column{.5\textwidth} + \centering + \includegraphics[width=.7\columnwidth]{img/async-joke.jpg} + \end{columns} + + \vspace{1cm} + + \begin{columns} + \column{.5\textwidth} + \begin{minted}[fontsize=\footnotesize]{ts} +asyncFunction().then((res) => { + console.log(res); +}).catch((err) => { + console.log(err); +}); + \end{minted} + + \column{.5\textwidth} + \begin{minted}[fontsize=\footnotesize]{ts} +try { + const res = await asyncFunction(); + console.log(res); // "bla" +} catch (err) { + console.log(err); // "Nope" +} + \end{minted} + \end{columns} +\end{frame} + +\begin{frame}[fragile]{Programmation asynchrone} + \begin{minted}[fontsize=\footnotesize]{ts} +function repeatMaybe(repeat: string): Promise { + return new Promise((resolve, reject) => { + const maybe: number = randomIntegerBetween(0, 1); + + if (!maybe) { + reject("Nope"); + return; + } + + setTimeout(() => { + resolve(repeat); + }, 1000); + }); +} + +try { + const blabla = await repeatMaybe("bla"); + console.log(blabla); // "bla" +} catch (error) { + console.log(error); // "Nope" +} + \end{minted} +\end{frame} + +\begin{frame}{Programmation parallèle} + \begin{itemize} + \item \texttt{Promise.all} + \item \texttt{Promise.allSettled} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Exercice 4 : programmation asynchrone} + \begin{block}{Manipuler l'API Promise} + \begin{itemize} + \item Écrire une fonction \texttt{readTextFileIfExists(path)} qui lit un fichier s'il existe et retourne son contenu si le fichier n'est pas vide : + \end{itemize} + \end{block} + + \begin{minted}{js} +readTextFileIfExists("data.txt") + .then(text => console.log("File contents:", text)) + .catch(err => console.error("I/O error:", err.message)); + \end{minted} + + \begin{alertblock}{Questions} + \begin{enumerate} + \item Quelle est la signature de cette fonction en TypeScript ? + \item Comment utiliser cette fonction avec \texttt{await} ? + \item Comment utiliser cette fonction sur une liste de fichiers ? + \item Comment paralléliser la lecture des fichiers de la liste ? + \end{enumerate} + \end{alertblock} +\end{frame} + +\begin{frame}[fragile]{Exercice 4 : programmation asynchrone} + \begin{minted}[fontsize=\footnotesize]{js} +function readTextFileIfExists(path) { + return new Promise((resolve, reject) => { + if (!path) { + reject(new Error("No file path provided")); + return; + } + + readFile(path, "utf8") + .then(data => { + if (data.length === 0) { + reject(new Error("File is empty")); // explicit failure + } else { + resolve(data); // successful read + } + }) + .catch(err => reject(err)); // I/O error + }); +} + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Exercice 4 : programmation asynchrone} + \begin{minted}{js} +try { + const text = await readTextFileIfExists("data.txt"); + console.log("File contents:", text); +} catch (err) { + console.error("I/O error:", err.message); +} + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Exercice 4 : programmation asynchrone} + \begin{minted}{js} +const files = ["file1.txt", "file2.txt", "file3.txt"]; + +for (const file of files) { + try { + const text = await readTextFileIfExists(file); + console.log("File contents:", text); + } catch (err) { + console.error("I/O error:", err.message); + continue; + } +} + \end{minted} + + \vspace{.5cm} + + \begin{block}{\emoji{thinking}} + Temps d'exécution total = ? + \end{block} +\end{frame} + +\begin{frame}[fragile]{Exercice 4 : programmation asynchrone} + \begin{minted}{js} +const files = ["does_not_exist.txt", "file2.txt", "file3.txt"]; + +const contents = await Promise.all( + files.map(readTextFileIfExists) +); +try { + contents.forEach((text, i) => { + console.log("File contents:", text); + }); +} catch (err) { + console.error("I/O error:", err.message); +} + \end{minted} + + \vspace{.5cm} + + \begin{block}{\emoji{thinking}} + Temps d'exécution total = ? + \end{block} +\end{frame} + +\begin{frame}[fragile]{Exercice 4 : programmation asynchrone} + \begin{minted}{js} +const files = ["does_not_exist.txt", "file2.txt", "file3.txt"]; + +const contents = await Promise.allSettled( + files.map(readTextFileIfExists) +); +contents.forEach((result, i) => { + if (result.status === "fulfilled") { + console.log("File contents:", result.value); + } else if (result.status === "rejected") { + console.error("I/O error:", result.reason); + } +}); + \end{minted} + + \vspace{.5cm} + + \begin{block}{\emoji{thinking}} + Temps d'exécution total = ? + \end{block} +\end{frame} + +\begin{frame}{Exécution : machine virtuelle} + \begin{itemize} + \item JavaScript : langage interprété dans une VM + \item Langage permet d'exprimer des instructions \textbf{asynchrones} + \item Runtime \textbf{synchrone} : boucle d'événements (pas de coroutines, pas de threads~\footnote{Sauf \textit{workers}, voir~\url{https://developer.mozilla.org/en-US/docs/Glossary/Thread}}) + \end{itemize} + + \centering + \includegraphics[width=\textwidth]{img/js-event-loop.png} +\end{frame} + +\begin{frame}{Runtime : Deno} + \begin{columns} + \column{.8\textwidth} + \begin{itemize} + \item Runtime pour exécuter du code JavaScript en-dehors du navigateur + \item Basé sur le moteur V8 (comme Node.js) + \item Créé en 2018 par Ryan Dahl, développeur de Node.js~\footnote[frame]{\url{https://www.youtube.com/watch?v=M3BM9TB-8yA}} + \item Points forts : + \begin{itemize} + \item \textit{Sandbox} : permissions explicites (lecture/écriture, accès au réseau, etc.) + \item Exécute du code TypeScript sans outillage supplémentaire + \item Inclut un formateur, un \textit{linter}, une plateforme de test, un profileur + \end{itemize} + \end{itemize} + + \column{.2\textwidth} + \includegraphics[width=\columnwidth]{img/deno.png} + \end{columns} +\end{frame} + +\begin{frame}{Sécurité, permissions} + \begin{itemize} + \item \textit{Supply-chain attack} : introduction de vulnérabilités dans un logiciel \textit{via} compromission d'une ou plusieurs de ses dépendances + \item Exemple : \textit{Shai Hulud}, novembre 2025~\footnote[frame]{\url{https://www.cert.ssi.gouv.fr/actualite/CERTFR-2025-ACT-051/}}, 700 paquets compromis sur NPM + \begin{itemize} + \item récupération de différents secrets présents sur la machine compromise [...] ; + \item exfiltration des secrets ; + \item réplication par l'infection de paquets NPM ; + \item suppression de données utilisateurs ; + \item mise en place de persistance. + \end{itemize} + \end{itemize} +\end{frame} + +\begin{frame}{Gestion des dépendances} + \begin{columns} + \column{.8\textwidth} + Outils (npm, etc.) + + Modules (ESM vs CommonJS) et imports + + \column{.2\textwidth} + \includegraphics[width=\columnwidth]{img/npm.png} + \includegraphics[width=\columnwidth]{img/jsr.png} + \end{columns} +\end{frame} + +\section{Serveur web} + +\begin{frame}{HTTP} + \centering + \includegraphics[width=.6\textwidth]{img/series-of-tubes.png} +\end{frame} + +\begin{frame}{HTTP} + \begin{columns} + \column{.6\textwidth} + \begin{itemize} + \item \textit{Hypertext Transfer Protocol} : à l'origine, sert à partager des pages web reliées entre elles par des liens + \item Inventé au CERN~\footnote[frame]{Initialement \textit{Conseil européen pour la recherche nucléaire}, plus grand centre de recherche au monde en physique des particules} par un chercheur britannique, Tim Berners-Lee, entre 1989 et 1991 + \item 1997 : standardisation de HTTP/1.1 : + \begin{itemize} + \item Apparition de l'en-tête \texttt{Host}, permettant d'héberger plusieurs domaines sur la même adresse IP, donc la colocation de serveurs web + \end{itemize} + \end{itemize} + + \begin{center} + \includegraphics[width=.4\columnwidth]{img/tbl.jpg} + \end{center} + + \column{.4\textwidth} + \includegraphics[width=\columnwidth]{img/osi-model.png} + \end{columns} +\end{frame} + +\begin{frame}{HTTP : requêtes et réponses} + \centering + \includegraphics[width=\textwidth]{img/http-message.png} +\end{frame} + +\begin{frame}{HTTP : méthodes} + Méthodes principales pour les requêtes HTTP~\footnote[frame]{\url{https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods}}, aussi appelées \textit{verbes} : + + \begin{itemize} + \item \texttt{GET} : demande d'une ressource + \item \texttt{POST} : envoi de données du \textit{corps} de la requête vers une ressource + \item \texttt{PUT} : remplacement d'une ressource par le \textit{corps} de la requête + \item \texttt{DELETE} : suppression d'une ressource + \end{itemize} +\end{frame} + +\begin{frame}{HTTP : codes de réponse} + \begin{itemize} + \item \texttt{100} à \texttt{199} : réponses informatives + \begin{itemize} + \item \texttt{101 Switching Protocols} + \end{itemize} + \item \texttt{200} à \texttt{299} : réponses de succès + \begin{itemize} + \item \texttt{200 OK} + \end{itemize} + \item \texttt{300} à \texttt{399} : réponses de redirection + \begin{itemize} + \item \texttt{301 Moved Permanently} + \end{itemize} + \item \texttt{400} à \texttt{499} : erreurs du client + \begin{itemize} + \item \texttt{401 Unauthorized} + \end{itemize} + \item \texttt{500} à \texttt{599} : erreurs du serveur + \begin{itemize} + \item \texttt{500 Internal Server Error} + \end{itemize} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Exercice 5 : un serveur HTTP minimal avec TypeScript} + \begin{block}{Lire et écrire sur un socket TCP} + Ci-dessous, la boucle principale pour ouvrir et écouter sur un socket TCP avec Deno. Dès la connexion d'un \textbf{client}, on passe le socket à la fonction \texttt{handleConn}. + \end{block} + + \begin{minted}{ts} +// TCP socket +const listener = Deno.listen({ port: 8080 }); +// Strings <-> Bytes +const decoder = new TextDecoder(); +const encoder = new TextEncoder(); +// Listen loop +for await (const conn of listener) { + handleConn(conn); +} + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Exercice 5 : un serveur HTTP minimal avec TypeScript} + \begin{block}{Lire et écrire sur un socket TCP} + Ci-dessous, la fonction \texttt{handleConn} par laquelle chaque \textbf{requête} en provenance d'un \textbf{client} est traitée. Le serveur reçoit un \textbf{tableau d'octets} ; on le convertit en une chaîne de caractères dans \texttt{rawRequest}. + \end{block} + + \begin{minted}{ts} +async function handleConn(conn: Deno.Conn) { + const buf = new Uint8Array(1024); + const bytes = await conn.read(buf); + if (bytes === null) { + conn.close(); + return; + } + + const rawRequest = decoder.decode(buf.subarray(0, bytes)); +} + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Exercice 5 : un serveur HTTP minimal avec TypeScript} + \begin{minted}{sh} +curl -X POST http://localhost:8080 \ + -H "Content-Type: text/plain" \ + --data "hello world" + \end{minted} + + \vspace{1cm} + + \begin{columns} + \column{.5\textwidth} + \begin{minted}{text} +POST / HTTP/1.1 +Host: localhost:8080 +User-Agent: curl/8.14.1 +Accept: */* +Content-Type: text/plain +Content-Length: 11 + +hello world + \end{minted} + + \column{.5\textwidth} + \begin{alertblock}{Questions} + \begin{enumerate} + \item Quels sont les champs à inclure dans la réponse que l'on va retourner au client ? + \item Compléter la fonction \texttt{handleConn} pour signifier une réponse OK comportant du texte au format JSON. + \item TODO: new Date().toUTCString(); + \end{enumerate} + \end{alertblock} + \end{columns} +\end{frame} + +\begin{frame}{Framework pour serveur HTTP : Oak} + \begin{columns} + \column{.8\textwidth} + \begin{itemize} + \item Inspiré par Express.js, initialement développé pour Deno + \item Framework \textit{middleware} : un logiciel qui s'intercale entre la requête d'un client et la réponse d'un serveur + \item \textbf{Contexte} $=$ \textbf{Requête} $+$ \textbf{Réponse} + \item Mécanisme principal : le \textbf{routage} + \begin{itemize} + \item Pour un point d'entrée donné, appliquer telle fonction, retourner telle valeur + \item Requête : \texttt{GET http://blabla.com/item/123} + \item Route : \texttt{/item/:itemId} + \item Fonction : \texttt{getItem(id)} + \item Réponse : \texttt{\{ id: 123, value: "..." \}} + \end{itemize} + \end{itemize} + + \column{.2\textwidth} + \includegraphics[width=\columnwidth]{img/oak.png} + \end{columns} +\end{frame} + +\begin{frame}{JSON} + +\end{frame} + +\begin{frame}{Middleware} + +\end{frame} + +\begin{frame}{Middleware : CORS} + TODO: à mettre côté client ? +\end{frame} + +\begin{frame}{Middleware : Gestion des erreurs} + +\end{frame} + +\begin{frame}{Base de données} + \begin{columns} + \column{.8\textwidth} + \begin{itemize} + \item SQLite + \item Interactions avec SQLite : bibliothèque + \item Conversion des \textbf{enregistrements} vers des \textbf{objets} + \end{itemize} + + \column{.2\textwidth} + \includegraphics[width=\columnwidth]{img/sqlite.png} + \end{columns} +\end{frame} + +\begin{frame}[fragile]{Base de données : rappels sur SQL} + \begin{minted}{sql} +CREATE TABLE things ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + maybe TEXT, + active INTEGER NOT NULL +); + +CREATE TABLE thing_options ( + id TEXT PRIMARY KEY, + thing_id TEXT NOT NULL, + value TEXT NOT NULL, + FOREIGN KEY (thing_id) REFERENCES things(id) ON DELETE CASCADE +); + \end{minted} +\end{frame} + +\begin{frame}[fragile]{Tests} + \begin{minted}{ts} +import { assertEquals, assert } from "@std/assert"; + +const BASE_URL = `http://localhost:8000`; + +Deno.test({ + name: "polls management API", + async fn() { + const listRes = await fetch(`${BASE_URL}/polls`); + assertEquals(listRes.status, 200); + + const listBody = await listRes.json(); + assert(listBody.success); + assert(listBody.data.length >= 1); + }, +}); + \end{minted} +\end{frame} + +\section{Client web} + +\begin{frame}{HTTP, encore} + \begin{itemize} + \item API \texttt{fetch} + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Un client web minimal avec TypeScript} + \begin{minted}{js} + const foo = "bar"; + \end{minted} +\end{frame} + +\begin{frame}{Framework : React} + \begin{itemize} + \item Hooks + \begin{itemize} + \item \texttt{useParams} + \item \texttt{useState} + \item \texttt{useRef} + \end{itemize} + \item Functional Components + \item React Router + \end{itemize} +\end{frame} + +\begin{frame}{Bundling} + \begin{itemize} + \item Bundler + \item Vite + \end{itemize} +\end{frame} + +\begin{frame}{React : architecture} + \begin{itemize} + \item Service Layer Pattern + \end{itemize} +\end{frame} + +\begin{frame}{Bundler} + +\end{frame} + +\section{Authentification} + +\begin{frame}{Concepts généraux} + +\end{frame} + +\begin{frame}{\textit{Stateful} : Sessions} + +\end{frame} + +\begin{frame}{\textit{Stateless} : JWT} + +\end{frame} + +\section{Interactions} + +\begin{frame}{REST} + +\end{frame} + +\begin{frame}{Data Transfer Objects} + +\end{frame} + +\begin{frame}{WebSockets} + +\end{frame} + +\section{Déploiement de l'application} + +\begin{frame}{Nom d'hôte, port, adresse} + \begin{center} + \texttt{% + {\color{BrickRed}https}://% + {\color{MidnightBlue}foo.bar}.% + {\color{Orchid}com}% + [:{\color{LimeGreen}443}]/% + {\color{YellowOrange}baz.html}% + } + \end{center} + + \begin{center} + \includegraphics[width=.5\textwidth]{img/brace.png} + \end{center} + + \begin{itemize} + \item \texttt{{\color{BrickRed}https}} : protocole + \item \texttt{{\color{MidnightBlue}foo.bar}} : nom d'hôte (\textit{hostname}) + \item \texttt{{\color{Orchid}com}} : \textit{TLD} (\textit{Top-Level Domain}) + \item \texttt{{\color{LimeGreen}443}} : port (HTTP : 80, HTTPS : 443) + \item \texttt{{\color{YellowOrange}baz.html}} : nom de fichier + \end{itemize} +\end{frame} + +\begin{frame}[fragile]{Reverse proxy} + \begin{minted}[fontsize=\footnotesize]{text} +http { + server { + listen 80; + server_name coucou.localhost; + + location / { + proxy_pass http://127.0.0.1:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } +} + \end{minted} +\end{frame} + +\begin{frame}{Certificats SSL} + \begin{itemize} + \item Protocole (TLSv1.2, TLSv1.3) + \item Algorithme de chiffrement : AES 128/256, etc. + \end{itemize} +\end{frame} + +\section{Débuggage et profilage} + +\begin{frame}{Côté serveur} + \begin{columns} + \column{.5\textwidth} + \begin{itemize} + \item \texttt{deno run --v8-flags="--prof" main.ts} + \begin{itemize} + \item Crée un fichier .log dans le répertoire courant + \item \textit{"V8 has built-in sample-based profiling. Profiling is turned off by default, but can be enabled via the \texttt{--prof} command-line option. The sampler records stacks of both JavaScript and C/C++ code."} + \end{itemize} + \item Lecture du fichier avec cpupro~\footnote[frame]{\url{https://discoveryjs.github.io/cpupro/}} + \begin{itemize} + \item Visualisation : \textit{flame graph}~\footnote[frame]{\fullcite{greggFlameGraph2016}} + \end{itemize} + \end{itemize} + + \column{.5\textwidth} + \includegraphics[width=\columnwidth]{img/flamegraph.png} + \end{columns} +\end{frame} + +\begin{frame}{Côté client} + +\end{frame} + +\appendix + +\section{Bibliographie} + +\begin{frame}[allowframebreaks]{Références} + \printbibliography[heading=none] +\end{frame} + +% \appendix + +% \section{Annexes} + +% \begin{frame}{Annexe 1 -- ...} +% \end{frame} + +\end{document}