Files
festipod/.project/knowledge/nextgraph-integration-model.md
T
Sylvain Duchesne 445a448031 docs: NextGraph multi-user data model — stores, auth matrix, inbox fork plan
Capture the multi-user design exploration as project knowledge + briefs:
- knowledge: NextGraph store types/permissions (+ inbox at protocol, SDK
  exposure, local repo path); integration model (iframe, where the verifier
  runs, generic JS plumbing, ngd stateful, build-time broker target)
- briefs: multi-store refactor; authorization matrix + query inventory +
  derived store partitions; temporary fork to expose the inbox (3 layers:
  SDK fork, Coolify self-hosting, Festipod integration; libs via build:ng)
- fix stale @ng-org versions (alpha.11 -> alpha.13) and a broken
  decision-record link in data-layer.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 17:38:51 +02:00

6.4 KiB
Raw Blame History

Modèle d'intégration et de déploiement NextGraph

Comment une app web tierce s'intègre à NextGraph, et où tourne le moteur (verifier).

Overview

NextGraph s'utilise depuis une app web via un proxy iframe (@ng-org/web) : l'app tierce ne contient pas le moteur, elle délègue à un ng-app hébergé (par défaut nextgraph.net) qui exécute le moteur dans une iframe. Comprendre ce découpage est nécessaire pour savoir ce qu'on peut modifier sans auto-héberger. Vérifié dans nextgraph-rs le 2026-05-21 (voir chemin du repo local).

Les paquets JS

  • @ng-org/web — paquet publié. Proxy postMessage léger (aucun wasm embarqué). C'est le chemin d'intégration d'une app web tierce. @ng-org/orm et tous les exemples officiels (expense-tracker…) en dépendent. Festipod l'utilise.
  • @ng-org/api-web — paquet privé ("private": true, non publié). Moteur navigateur complet : charge @ng-org/lib-wasm dans un Web Worker (?worker&inline), utilise sessionStorage/Worker. Consommé uniquement par app/nextgraph (le frontend ng-app) et engine/broker/auth. C'est le moteur interne de l'app NextGraph, pas une cible d'intégration tierce.
  • @ng-org/lib-wasm — le moteur compilé en wasm (contient le verifier via la dépendance nextgraph / local_broker). Source : sdk/js/lib-wasm/.
  • nextgraph (npm) — l'API NodeJS (build pkg-node de lib-wasm).
  • @ng-org/orm — l'ORM réactif (useShape…), bâti sur @ng-org/web.

Où tourne le verifier

Dans le modèle web standard (iframe), le verifier tourne dans l'iframe : app/nextgraph charge api-weblib-wasm dans un Web Worker, côté navigateur. Le broker (ngd) ne fait que le transport et le stockage.

Conséquence : modifier la logique du verifier (ex. request_processor, inbox_processor) = reconstruire le ng-app, pas le broker.

Le modèle iframe (intégration tierce)

  • @ng-org/web redirige vers le ng-app hébergé, qui recharge l'app tierce dans une iframe après authentification, puis relaie les appels par postMessage.
  • Reciblable au build via variables d'env (fichier sdk/js/web/src/index.ts) :
Variable Cible
NG_REDIR_SERVER défaut nextgraph.net
NG_DEV3 127.0.0.1:3033
NG_DEV localhost:14402 (redir) / 14404 (origin)
NG_DEV_LOCAL_BROKER localhost:1421

Une app tierce peut donc pointer @ng-org/web vers un ng-app auto-hébergé sans changer son code, juste en rebuildant avec ces variables.

Build pipeline lib-wasm

Scripts cargo dans sdk/js/lib-wasm/Cargo.toml ([package.metadata.scripts]) :

  • web / webdevwasm-pack build --target web
  • node / nodedevwasm-pack build -t nodejs
  • app / appdevwasm-pack build --target bundler

Post-traités par prepare-web.js / prepare-node.js.

Plomberie proxy ↔ iframe ↔ worker (générique)

Le chemin d'appel d'une méthode du moteur est entièrement générique — aucune allowlist :

  • @ng-org/web (proxy) : un Proxy JS qui relaie n'importe quel nom de méthode à l'iframe par postMessage (applypostMessage({method, args})). Seules les méthodes streamées ont une entrée dans une table interne (positions d'arguments) ; les autres passent en simple requête/réponse.
  • app/nextgraphapi-web/wasm-worker.js : dispatch générique Reflect.apply(ng[method], null, args) (la table mapping est commentée/inutilisée).

Conséquence : une nouvelle fonction wasm en requête/réponse simple est atteignable de bout en bout via ce forwarding générique sans modifier le JS. Mais c'est un mécanisme de relais, pas un substitut à une API typée : l'appeler ainsi est un appel string non typé/non documenté (hack de test). Pour une intégration propre, on ajoute la méthode à la surface d'API du paquet (@ng-org/web) et à ses .d.ts, et éventuellement à @ng-org/orm (qui, lui, n'est pas un forwarder générique).

Cas streamé : une méthode en flux exige une entrée dans la table de streaming des deux côtésE dans @ng-org/web (ngweb.js) et streamed_api dans api-web/main.ts. (Méthodes streamées actuelles : doc_subscribe, orm_start_graph, orm_start_discrete, file_get, app_request_stream.)

Ciblage du broker : build-time uniquement

La cible (broker/ng-app) est figée au build de @ng-org/web via import.meta.env (sdk/js/web/src/index.ts) — pas d'override runtime, et init() ne prend pas d'URL de broker. Pour pointer une app vers un ng-app auto-hébergé, il faut donc rebuilder @ng-org/web avec NG_REDIR_SERVER/NG_DEV* (paquet en TypeScript pur, sans wasm → build trivial).

Le broker (ngd)

  • Supporte déjà nativement l'inbox (inbox_post, inbox_register, inbox_pop_for_user dans engine/net/src/server_broker.rs). Un ngd standard router­ait l'inbox — aucun patch broker nécessaire.
  • C'est un démon WebSocket (async-tungstenite), stateful : stockage RocksDB sous --base-path, identité de pair (PeerId) persistée. Le volume est critique (clés + données chiffrées des users).
  • CLI (bin/ngd/src/cli.rs) : --local PORT, et surtout --domain DOMAIN:PORT,LOCAL_PORT = mode « derrière reverse-proxy TLS-terminé qui envoie X-Forwarded-For » (adapté à Traefik/Coolify).
  • Ne sert pas de fichiers statiques : pas de ServeDir/HTTP statique dans le crate. Le ng-app frontend est un déploiement statique séparé (pnpm webfilebuild). En prod, un reverse-proxy sert le statique du ng-app et proxy le WebSocket vers ngd sur un même domaine.
  • Premier démarrage interactif : ngd émet un lien d'invitation pour créer le wallet admin (cf. DEV.md « first run »). Wrinkle pour un déploiement conteneurisé headless.
  • Les Dockerfiles officiels (bin/ngd/docker/Dockerfile.{alpine,fedora,ubuntu}) sont incomplets/cassés (chemins obsolètes, échec de link llvm/clang documenté en commentaire) — pas de build conteneur turnkey.

See Also