feat(example): une app d'exemple, écrite comme un consommateur
Le harnais e2e parlait à un sac de méthodes posé sur `window.__sdk`. Il prouvait que les fonctions s'exécutaient, jamais qu'on pouvait écrire une application avec — et cet écart a livré un vrai défaut : l'inbox d'un document était verte en test et inutilisable en vrai, parce que le harnais faisait traverser une adresse d'une identité à l'autre par une variable, ce qu'aucune application ne peut faire. `examples/notebook` est une application minimale en DOM natif, qui résout `@ng-eventually/client` comme un consommateur externe (workspace, dépendance déclarée, aucun import privilégié). Elle ne peut faire que ce qu'une application peut faire. Elle s'est déjà payée deux fois pendant son écriture : - `UnionSubject.subject` et `.graph` étaient typés `string` alors que ce sont toujours des références de document. Un consommateur devait donc caster ce qu'il venait de lire avant de le repasser — un cast à cet endroit précis rouvre la confusion que les types template literal existent pour fermer. - l'écran d'accès normalisait ce que l'utilisateur SAISIT mais pas ce que l'URL porte, si bien qu'un lien `?ng-id=@Erin` ouvrait un espace différent de celui de la même personne tapant `erin`. Une seule normalisation désormais, celle du registre. Le domaine est volontairement mince — des notes — mais suffit à exercer le placement par scope, la possession de caps, le partage dirigé, les inbox par document et la lecture réactive. 170 tests unitaires, typecheck vert sur la lib, l'exemple et le harnais.
This commit is contained in:
@@ -57,10 +57,19 @@ void sparqlUpdate;
|
||||
|
||||
/** One subject read from a doc, with its properties (predicate → values). */
|
||||
export interface UnionSubject {
|
||||
/** The subject IRI (`?s`) — in the polyfill, the doc's own NURI. */
|
||||
subject: string;
|
||||
/**
|
||||
* The subject IRI (`?s`) — in the polyfill, the doc's own NURI.
|
||||
*
|
||||
* Typed `Nuri`, not `string`: both fields are always document references here (the
|
||||
* read is anchored per document and the subject is pinned to the anchor), and typing
|
||||
* them loosely forced a consumer to cast whatever it had just read before it could
|
||||
* pass it back — `shareNote(note.doc)`, `leaveMessage(note.doc)`. A cast at that
|
||||
* boundary re-opens exactly the confusion the template literal types exist to close.
|
||||
* Found by writing the example application (`examples/notebook`).
|
||||
*/
|
||||
subject: Nuri;
|
||||
/** The graph (doc NURI) the subject was read from. */
|
||||
graph: string;
|
||||
graph: Nuri;
|
||||
/** predicate IRI → the list of object values (literals or IRIs) for it. */
|
||||
props: Record<string, string[]>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user