Des routes et des gestionnaires comme Spring Boot, des pages faites de composants comme Vaadin — et tout cela est du .keal. Le C en dessous ouvre des sockets et déplace des octets. Il ne décide rien.
site.livePage("/", { req ->
var count = 0
view({ -> column([
h1("Clicked ${count} times"),
button("Click me", { e -> count = count + 1 })
]) })
}){"p":[["t","0.0.0","Clicked 1 times"]]}Un patch. Le navigateur pose un nœud texte — pas de schéma JSON, pas de point d'entrée, pas d'état client, rien à tenir synchronisé.
| lignes | ce que c'est | |
|---|---|---|
| Keal | 6 604 | tout le cadriciel : HTTP, routage, arbre de composants, rendu, feuilles de style, JSON, tramage WebSocket, gzip, ordonnanceur, sessions, diff, couche SQLite, et le hachage sur lequel repose la sécurité |
| C | 786 | sockets, poll, blobs d'octets, fichiers par morceaux — deux en-têtes, pas de .c |
| JavaScript | 143 | le client du navigateur : ouvrir une socket, signaler un événement, appliquer un patch |
import "kealeb/kealeb.keal"
val site = app("Hello")
site.page("/", { req -> column([
h1("Hello"),
p("from Keal")
])})
site.run(8080)Cinq lignes et un import. C'est une page, mise en forme, en mode sombre si la machine l'est, et elle marche dans tout ce qui sait lire du HTML — il n'y a aucun JavaScript dessus.
Chaque socket est non bloquante, un seul poll mène tout, et un gestionnaire s'exécute sans que rien d'autre ne tourne. L'état de session est un objet Keal ordinaire et une course n'est pas une chose qu'on puisse écrire ici. Le prix est énoncé et non caché : un gestionnaire qui bloque bloque le serveur.
Une page vivante garde son arbre sur le serveur. Un événement exécute un gestionnaire, l'arbre est reconstruit, les deux sont comparés, et ce qui traverse la socket est la liste des changements — sept sortes de patch, chacune un appel dans le navigateur.
Aucune dépendance. SQLite arrive avec un second import et un drapeau ; un programme qui n'ouvre pas de base ne s'y lie jamais. Le hachage, la compression et le tramage WebSocket sont du Keal.
SHA-256, HMAC et PBKDF2 contre les vecteurs publiés par leurs spécifications. La sortie gzip donnée au gzip du système et à Python, les deux devant rendre les octets. Le client du navigateur exécuté contre un vrai serveur à chaque construction.