# Petite veille tech


## Vision

Application de messagerie et réseau social **absolument décentralisé**. Aucun serveur central, aucun point de contrôle unique. L'application utilise **tous les moyens à sa disposition** pour faire parvenir un message d'un point A à un point B, en privilégiant toujours la méthode la plus efficace disponible à un instant donné.

Le réseau doit pouvoir fonctionner **avec ou sans Internet**. L'application est autosuffisante : elle peut former son propre réseau de proche en proche sans dépendre d'aucune infrastructure extérieure (antennes, routeurs, box).

## Stack technique

| Couche       | Technologie                                  | Rôle                                                  |
| ------------ | -------------------------------------------- | ----------------------------------------------------- |
| UI / Logique | **Leptos** (Rust → WASM)                     | Framework frontend, rendu client-side uniquement      |
| Concurrency  | WebAssembly (SharedArrayBuffer, Web Workers) | Multiprocessing, channels Rust, gestion du protocole  |
| Natif        | **Tauri Mobile**                             | Wrapper natif iOS/Android autour de la webview Leptos |
| Build PWA    | **Trunk**                                    | Compilation WASM → fichiers statiques                 |
| Build natif  | **Tauri CLI** + Xcode / Android Studio       | Plugins natifs Swift (iOS) + Kotlin (Android)         |

**Partage de code** : ~98% de la codebase est commune entre la PWA et les versions natives. Les plugins natifs (BLE, MultipeerConnectivity, etc.) sont des **capabilities optionnelles** activées quand disponibles.


## Distribution

L'application se décline en **trois modes de diffusion** pour minimiser la dépendance aux stores et garantir l'accès en toutes circonstances.

```mermaid
graph TD
    APP[Application Leptos / WASM]
    APP -->|PWA| PWA[URL]
    APP -->|Tauri Android| AND[.apk / .aab]
    APP -->|Tauri iOS| IOS[.ipa]


    AND --> FDROID[F-Droid]
    AND --> APK[APK direct]
    IOS --> ALTSTORE_PAL[AltStore PAL — UE/Japon/Brésil]
    IOS --> ALTSTORE[AltStore — monde entier]

    style PWA fill:#4caf50,color:#fff
    style FDROID fill:#4caf50,color:#fff
    style APK fill:#4caf50,color:#fff
    style ALTSTORE fill:#ff9800,color:#fff
    style ALTSTORE_PAL fill:#ff9800,color:#fff
```

| Mode             | Plateforme                 | Friction                     | Résistance à la censure        |
| ---------------- | -------------------------- | ---------------------------- | ------------------------------ |
| **PWA**          | iOS + Android (navigateur) | Nulle (une URL)              | Maximale tant que l'URL existe |
| **F-Droid**      | Android                    | Faible                       | Maximale aucune review         |
| **APK direct**   | Android                    | Faible                       | Maximale                       |
| **AltStore PAL** | iOS (UE/Japan/Brésil)      | Modérée (notarization Apple) | Apple peut révoquer            |
| **Altstore**     | iOS (mondial)              | Modérée (notarization Apple) | Apple peut révoquer            |

**Principe** : la PWA garantit que l'application reste accessible quel que soit le contexte. Les versions natives sur stores alternatifs sont un **bonus** qui débloque des capabilities matérielles supplémentaires.
## Capacités par plateforme

### Stockage

|                        | PWA                                                   | Natif iOS              | Natif Android          |
| ---------------------- | ----------------------------------------------------- | ---------------------- | ---------------------- |
| **IndexedDB**          | Données structurées, messages, queue                  | ok                     | ok                     |
| **OPFS**               | Fichiers binaires, médias (accès synchrone en Worker) | ok                     | ok                     |
| **Storage persistant** | `navigator.storage.persist()`(pas dispo sur iOS)      | File system natif      | File system natif      |
| **Quota**              | iOS ~1 GB (variable) · Chrome 60% disque              | Illimité (sandbox app) | Illimité (sandbox app) |
| **Éviction**           | iOS : 7 jours sans usage → cache effacé               | Pas d'éviction         | Pas d'éviction         |

### 4.2 Accès matériel et réseau

| Capability                | PWA iOS                        | PWA Android                    | Natif iOS       | Natif Android |
| ------------------------- | ------------------------------ | ------------------------------ | --------------- | ------------- |
| **WebSocket**             | foreground                     | foreground                     | background      | background    |
| **WebRTC (LAN)**          | après pairing                  | après pairing                  | après pairing   | après pairing |
| **WebRTC (Internet)**     | via STUN                       | via STUN                       | via STUN        | via STUN      |
| **BLE advertise**         | x                              | x                              | background      | background    |
| **BLE scan**              | x                              | foreground (scan uniquement)   | background      | background    |
| **MultipeerConnectivity** | x                              | x                              | (BLE+WiFi+AWDL) | x             |
| **WiFi Direct**           | x                              | x                              | x               | ok            |
| **Nearby Connections**    | x                              | x                              | x               | ok (BLE+WiFi) |
| **Ultrasonore**           | background (hack MediaSession) | background (hack MediaSession) | background      | background    |
| **Micro**                 | foreground                     | foreground                     | background      | background    |

##  Modes de communication

Le protocole sélectionne **dynamiquement** le meilleur transport disponible, par ordre de priorité décroissante :

1. Internet (WebSocket / WebRTC via STUN)
2. Réseau local (WebRTC host candidates sur LAN partagé)
3. Ondes radio (BLE, MultipeerConnectivity, WiFi Direct)
4. Ultrasons (fallback universel)

### Internet — WebSocket / WebRTC via STUN

|                            | Valeur                                                                                                                       |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Portée**                 | Illimitée (mondiale)                                                                                                         |
| **Débit**                  | WebSocket : illimité · WebRTC Data Channel : illimité                                                                        |
| **Mode**                   | Full-duplex                                                                                                                  |
| **Latence**                | ~50-200 ms                                                                                                                   |
| **Background**             | Natif : ok / PWA : nope)                                                                                                     |
| **Disponible**             | Toutes versions (quand Internet est accessible)                                                                              |
| **Infrastructure requise** | Serveurs : STUN (lightweight) + éventuellement TURN pour NAT difficiles. Bootstrap server optionnel pour discovery initiale. |


### Réseau local (LAN) — WebRTC host candidates

|                            | Valeur                                                    |
| -------------------------- | --------------------------------------------------------- |
| **Portée**                 | Portée du WiFi local (~30-50m)                            |
| **Débit**                  | Illimité (WiFi)                                           |
| **Mode**                   | Full-duplex                                               |
| **Latence**                | ~1-5 ms                                                   |
| **Background**             | Natif : ok · PWA : nope                                   |
| **Disponible**             | Toutes versions (quand 2+ pairs sur le même WiFi)         |
| **Infrastructure requise** | nécessite un WiFi partagé (box, hotspot)                  |
| **Pairing**                | Nécessite signaling initial (QR, ultrasons, ou bootstrap) |


### Ondes radio — BLE (iOS ↔ Android)

|                            | Valeur                                                                                         |
| -------------------------- | ---------------------------------------------------------------------------------------------- |
| **Portée**                 | ~10 m                                                                                          |
| **Débit utile**            | ~100-500 kbit/s (GATT) · ~1-2 Mbit/s théorique                                                 |
| **Mode**                   | Full-duplex (connexion GATT établie)                                                           |
| **Latence**                | ~10-50 ms                                                                                      |
| **Background**             |  Natif iOS (`bluetooth-central` + `bluetooth-peripheral`) · Natif Android (foreground service) |
| **Disponible**             | Natif iOS + Natif Android uniquement                                                           |
| **Discovery**              | Automatique (advertise + scan) — pas de pairing manuel                                         |
| **Infrastructure requise** | Aucune                                                                                         |


### Ondes radio — MultipeerConnectivity (iOS ↔ iOS)

|                            | Valeur                                |
| -------------------------- | ------------------------------------- |
| **Portée**                 | ~10-30 m (BLE + WiFi + AWDL combinés) |
| **Débit**                  | WiFi : plusieurs Mbit/s               |
| **Mode**                   | Full-duplex                           |
| **Latence**                | ~5-20 ms                              |
| **Background**             | (session persistante)                 |
| **Disponible**             | Natif iOS uniquement                  |
| **Discovery**              | Automatique                           |
| **Infrastructure requise** | Aucune                                |

### Ondes radio — WiFi Direct / Nearby Connections (Android ↔ Android)

|                            | Valeur                                              |
| -------------------------- | --------------------------------------------------- |
| **Portée**                 | ~50-100 m (WiFi Direct)                             |
| **Débit**                  | WiFi : plusieurs Mbit/s                             |
| **Mode**                   | Full-duplex                                         |
| **Latence**                | ~5-20 ms                                            |
| **Background**             | (foreground uniquement)                             |
| **Disponible**             | Natif Android uniquement                            |
| **Discovery**              | Automatique (Nearby Connections combine BLE + WiFi) |
| **Infrastructure requise** | Aucune                                              |

### Ultrasons — fallback universel

|                            | Valeur                                                |
| -------------------------- | ----------------------------------------------------- |
| **Portée**                 | ~2 m (volume max, 18-19 kHz)                          |
| **Débit**                  | ~300 bits/s (FSK à 19 kHz)                            |
| **Mode**                   | **Half-duplex** (mono — voir ci-dessous)              |
| **Latence**                | ~1-2 s par transmission                               |
| **Background**             | PWA : nope (micro tué) · Natif : ok                   |
| **Disponible**             | Toutes versions (PWA + natif iOS + natif Android)     |
| **Discovery**              | Broadcast chirp périodique                            |
| **Infrastructure requise** | Aucune                                                |
| **Discrétion**             | Inaudible (18-19 kHz, au-dessus de l'audition adulte) |


### Qui peut parler à qui, et comment

| Source → Destination                     | Meilleur transport       | Fallback                        |
| ---------------------------------------- | ------------------------ | ------------------------------- |
| PWA → PWA                                | Ultrasons (seule option) | QR code manuel (et encore mdrr) |
| PWA → Natif iOS                          | Ultrasons                | —                               |
| PWA → Natif Android                      | Ultrasons                | —                               |
| Natif iOS → Natif iOS                    | MultipeerConnectivity    | BLE → Ultrasons                 |
| Natif Android → Natif Android            | WiFi Direct / Nearby     | BLE → Ultrasons                 |
| Natif iOS → Natif Android                | BLE                      | Ultrasons                       |
| N'importe qui → N'importe qui (Internet) | WebSocket / WebRTC       | Tout le reste                   |
| N'importe qui → N'importe qui (LAN)      | WebRTC host candidates   | BLE → Ultrasons                 |

##  Formation du mesh autonome

### Principe du store-and-forward

Chaque pair stocke les messages en local (IndexedDB / storage natif) et les re-broadcast dès qu'un voisin entre à portée. Les messages voyagent hop par hop, potentiellement avec délai.

```mermaid
sequenceDiagram
    participant A as Alice
    participant B as Bob
    participant C as Charlie
    participant D as Dave

    A->>A: Écrit message pour Dave<br/>Stocké en IndexedDB
    Note over A: Aucun pair à portée<br/>Message en attente

    A->>B: Pair entre à portée (BLE ~10m)<br/>Transfert du message
    B->>B: Stocke en local
    B->>C: Relay vers Charlie (BLE ~10m)
    C->>C: Stocke en local
    C->>D: Relay vers Dave (BLE ~10m)
    D->>D: Message reçu ! ACK généré
    D->>C: ACK remonte (BLE)
    C->>B: ACK relay
    B->>A: ACK relay → message purgé de la queue
```

### Mesh avec transports hétérogènes

Dans la vraie vie, le mesh mêle téléphones PWA et natifs, avec des transports différents à chaque hop.

```mermaid
graph TD
    subgraph "5 tel, pas d'Internet"
        A["PWA Alice"]
        B["Natif iOS Bob"]
        C["Natif Android Charlie"]
        D["Natif iOS Dave"]
        E["PWA Eve"]

        A -->|"Ultrasons ~2m ~300b/s"| B
        B -->|"BLE ~10m ~500kb/s"| C
        C -->|"BLE ~10m ~500kb/s"| D
        B -->|"MultipeerConnectivity ~30m Mbit/s"| D
        A -->|"Ultrasons ~2m"| E
    end

    style A fill:#4caf50,color:#fff
    style E fill:#4caf50,color:#fff
    style B fill:#2196f3,color:#fff
    style D fill:#2196f3,color:#fff
    style C fill:#ff9800,color:#fff
```

**Exemple de routage** : Alice (PWA) veut envoyer un message à Dave (natif iOS) :
1. Alice émet en ultrasons vers Bob (~2m, half-duplex, ~5s)
2. Bob (natif iOS) relaye à Dave via MultipeerConnectivity (~30m, full-duplex, instantané)
3. Dave accuse réception → ACK remonte par le même chemin

### Mode half-duplex ultrasonore — séquence temporelle

L'ultrasonore étant half-duplex, chaque pair alterne entre émission et écoute selon un cycle :

```mermaid
sequenceDiagram
    participant A as Phone A (émetteur)
    participant B as Phone B (récepteur)

    Note over A,B: Phase 1 — A émet, B écoute
    A->>B: Chirp discovery (~0.5s)<br/>"Je suis PeerId X"
    B->>B: Décodage + stockage

    Note over A,B: Phase 2 — B répond, A écoute
    B->>A: Réponse (~2s)<br/>PeerId Y + ICE candidates
    A->>A: Décodage + stockage

    Note over A,B: Phase 3 — A confirme, B écoute
    A->>B: ACK (~0.3s)<br/>Confirmation réception

    Note over A,B: Phase 4 — Silencieux, switch transport
    Note over A,B: Si BLE/Multipeer disponible → upgrade
    Note over A,B: Sinon → continue en ultrasons
```

Récapitulatif des transports

| Transport                 | Portée | Débit          | Mode            | Background          | iOS | Android | PWA |
| ------------------------- | ------ | -------------- | --------------- | ------------------- | --- | ------- | --- |
| **WebSocket**             | ∞      | Illimité       | Full-duplex     | Natif ok / PWA nope | ok  | ok      | ok  |
| **WebRTC (Internet)**     | ∞      | Illimité       | Full-duplex     | Natif ok/ PWA nope  | ok  | ok      | ok  |
| **WebRTC (LAN)**          | ~50m   | Illimité       | Full-duplex     | Natif ok / PWA nope | ok  | ok      | ok  |
| **BLE**                   | ~10m   | ~500 kbit/s    | Full-duplex     | ok natif            | ok  | ok      | x   |
| **MultipeerConnectivity** | ~30m   | Mbit/s         | Full-duplex     | ok ios              | ok  | x       | x   |
| **WiFi Direct**           | ~100m  | Mbit/s         | Full-duplex     | ok android          | x   | ok      |     |
| **Ultrasons**             | ~2m    | ~300 bits/s    | **Half-duplex** | Natif ok / PWA nope | ok  | ok      | x   |
| **QR code**               | Visuel | ~60 bytes/scan | One-shot        | N/A                 | ok  | ok      | ok  |
