finished second course
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -300,5 +300,8 @@ TSWLatexianTemp*
|
||||
# Uncomment the next line to have this generated file ignored.
|
||||
#*Notes.bib
|
||||
|
||||
# build
|
||||
build/
|
||||
|
||||
# draw.io
|
||||
*.drawio.bkp
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
% $ 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
|
||||
|
||||
BIN
build/slides.pdf
BIN
build/slides.pdf
Binary file not shown.
BIN
slides.pdf
BIN
slides.pdf
Binary file not shown.
92
slides.tex
92
slides.tex
@@ -329,12 +329,14 @@
|
||||
\item \texttt{number}
|
||||
\item \texttt{string}
|
||||
\item Tableaux (dynamiques) -- exemple : \texttt{string[]} ou \texttt{Array<string>}
|
||||
\item Tuples (taille fixe) -- exemple : \texttt{let x: [string, number]}
|
||||
\item Tuples (taille fixe) -- exemple : \texttt{[string, number]}
|
||||
\item \texttt{enum}
|
||||
\item \texttt{unknown} (type à préciser en le vérifiant à l'exécution)
|
||||
\item \texttt{unknown} (type à préciser)
|
||||
\item \texttt{any} (à éviter : toute valeur autorisée)
|
||||
\item \texttt{void} (absence de valeur)
|
||||
\item \texttt{null} (valeur vide) et \texttt{undefined} (valeur non définie)
|
||||
\item \texttt{undefined} (valeur non définie)
|
||||
\item \texttt{null} (valeur vide)
|
||||
\item \texttt{never} (valeur impossible)
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
@@ -1564,10 +1566,12 @@ export interface APIError {
|
||||
|
||||
\begin{frame}[fragile]{Routage avec Oak : réponse à la requête}
|
||||
\begin{itemize}
|
||||
\item Et finalement, le type de \textbf{toute} réponse de l'API...
|
||||
\item Et finalement, le type de \textbf{toute} réponse de l'API... \emoji{drum}\emoji{drum}\emoji{drum}
|
||||
\end{itemize}
|
||||
|
||||
\vspace{.5cm}
|
||||
\vspace{1.5cm}
|
||||
|
||||
\pause
|
||||
|
||||
\begin{minted}{ts}
|
||||
export type APIResponse<T> = APISuccess<T> | APIFailure;
|
||||
@@ -1587,7 +1591,7 @@ const responseBody: APIResponse<Poll> = {
|
||||
data: poll,
|
||||
};
|
||||
|
||||
// Oak donne passe implicitement le code HTTP OK
|
||||
// Oak passe implicitement le code HTTP OK dans la réponse
|
||||
ctx.response.body = responseBody;
|
||||
\end{minted}
|
||||
\end{frame}
|
||||
@@ -1634,6 +1638,21 @@ ctx.response.body = responseBody;
|
||||
\end{minted}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Routage avec Oak : contexte}
|
||||
Quelques propriétés importantes de l'objet \texttt{ctx: Context}~\footnote{\url{https://jsr.io/@oak/oak/doc/context/~/Context}} :
|
||||
|
||||
\vspace{.5cm}
|
||||
|
||||
\begin{itemize}
|
||||
\item \texttt{request: Request} -- An object which contains information about the current request.
|
||||
\item \texttt{response: Response} -- An object which contains information about the response that will be sent when the middleware finishes processing.
|
||||
\item \texttt{state: S} -- The object to pass state to front-end views. This can be typed by supplying the generic state argument when creating a new app.
|
||||
\begin{itemize}
|
||||
\item \textit{On each request/response cycle, the context's state is cloned from the application state. This means changes to the context's .state will be dropped when the request drops, but "defaults" can be applied to the application's state. Changes to the application's state though won't be reflected until the next request in the context's state.}
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}{Middleware}
|
||||
\begin{itemize}
|
||||
\item Code applicatif qui se positionne \textbf{entre la requête et la réponse}
|
||||
@@ -1689,14 +1708,26 @@ export async function errorMiddleware(ctx: Context, next: Next) { }
|
||||
|
||||
\subsection{Gestion de l'état}
|
||||
|
||||
\begin{frame}{Base de données}
|
||||
\begin{frame}[fragile]{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}
|
||||
\item 2000 : création de SQLite par D. Richard Hipp
|
||||
\item Objectifs initiaux : base de données relationnelle \textbf{légère} et \textbf{sans serveur} pour être \textbf{embarquée} dans les applications
|
||||
\item Caractéristiques :
|
||||
\begin{itemize}
|
||||
\item \textit{In-memory} : les opérations sont réalisées dans la RAM (pas sur le disque)
|
||||
\item \textit{Single-file} : pas de processus serveur, pas de runtime, pas de dépendances, etc.
|
||||
\end{itemize}
|
||||
\item Simple à déployer, simple à maintenir
|
||||
\item Compétitive en matière de fonctionnalités (transactions, concurrence des accès en lecture/écriture, extensible, etc.)
|
||||
\end{itemize}
|
||||
|
||||
\vspace{.5cm}
|
||||
|
||||
\begin{minted}{sh}
|
||||
sqlite3 database.db < schema.sql
|
||||
\end{minted}
|
||||
|
||||
\column{.2\textwidth}
|
||||
\includegraphics[width=\columnwidth]{img/sqlite.png}
|
||||
@@ -1780,19 +1811,29 @@ try {
|
||||
\subsection{Architecture}
|
||||
|
||||
\begin{frame}{Organisation du dépôt}
|
||||
% TODO: pas de paradigme précis, responsabilité côté developpeur
|
||||
|
||||
% TODO: reprendre la terminologie du framework (routes, middleware, etc.)
|
||||
|
||||
\begin{center}
|
||||
\includegraphics[width=.5\textwidth]{img/point.png}
|
||||
\end{center}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Exercice : ...}
|
||||
TODO: proposer une organisation
|
||||
\begin{frame}[fragile]{Exercice 8 : architecture du serveur}
|
||||
\begin{block}{Organisation des fichiers de l'application}
|
||||
Oak ne privilégie pas de paradigme précis, la responsabilité incombe aux développeurs d'organiser le code de leur application. À ce stade, les composants principaux sont :
|
||||
|
||||
TODO: montrer les directives export / import associées
|
||||
\begin{itemize}
|
||||
\item Routes
|
||||
\item Middleware
|
||||
\item Interfaces
|
||||
\item Base de données
|
||||
\end{itemize}
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{Questions}
|
||||
\begin{enumerate}
|
||||
\item Doit-on privilégier une organisation type \texttt{module/module.routes.ts} ? \texttt{routes/module.ts} ? Donner des avantages et des inconvénients.
|
||||
\item Pour les deux cas, montrer les directives \texttt{export} et \texttt{import} associées.
|
||||
\end{enumerate}
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\subsection{Fiabilité et tests}
|
||||
@@ -1817,8 +1858,21 @@ Deno.test({
|
||||
\end{minted}
|
||||
\end{frame}
|
||||
|
||||
\begin{frame}[fragile]{Exercice ...}
|
||||
TODO: écrire des tests pour une ou deux routes
|
||||
\begin{frame}{Exercice 9 : un premier jeu de tests}
|
||||
\begin{block}{Organisation des fichiers de l'application}
|
||||
On souhaite éviter toute \textbf{régression} dans le comportement du serveur. Il faut donc tester \textbf{unitairement} les fonctionnalités de base de l'API.
|
||||
\end{block}
|
||||
|
||||
\begin{alertblock}{Questions}
|
||||
\begin{enumerate}
|
||||
\item Écrire un test pour vérifier le fonctionnement nominal de :
|
||||
\begin{itemize}
|
||||
\item la fonction de vérification de l'interface d'un enregistrement issu de la base de données (\texttt{PollRow}) ;
|
||||
\item la fonction de conversion de cet enregistrement en objet de l'API (\texttt{Poll}) ;
|
||||
\end{itemize}
|
||||
\item Écrire un test pour vérifier le fonctionnement nominal de la route \texttt{/polls}.
|
||||
\end{enumerate}
|
||||
\end{alertblock}
|
||||
\end{frame}
|
||||
|
||||
\section{Client web}
|
||||
|
||||
Reference in New Issue
Block a user