v0.1.0-pre.057
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: KHADHROONY_BOT3_MIGRATION_CLOSURE_TODO.md -->
|
<!-- file: KHADHROONY_BOT3_MIGRATION_CLOSURE_TODO.md -->
|
||||||
<!-- version: 3 -->
|
<!-- version: 4 -->
|
||||||
|
|
||||||
# Checklist détaillée de clôture de la migration `khadhroony-bot3`
|
# Checklist détaillée de clôture de la migration `khadhroony-bot3`
|
||||||
|
|
||||||
@@ -24,12 +24,12 @@
|
|||||||
- [x] Transformer `RULES.md` en index normatif.
|
- [x] Transformer `RULES.md` en index normatif.
|
||||||
- [x] Corriger `docs/DELTA_WORKFLOW.md` pour Bot3, `-delta`, `delta-fix-XXX`, exclusion de `Cargo.lock` et absence de SHA256.
|
- [x] Corriger `docs/DELTA_WORKFLOW.md` pour Bot3, `-delta`, `delta-fix-XXX`, exclusion de `Cargo.lock` et absence de SHA256.
|
||||||
- [x] Adapter le script d’audit aux nouveaux fichiers de règles.
|
- [x] Adapter le script d’audit aux nouveaux fichiers de règles.
|
||||||
- [ ] Relire intégralement les quatre fichiers de règles après application du delta.
|
- [x] Relire intégralement les quatre fichiers de règles après application du delta.
|
||||||
- [ ] Comparer ligne par ligne les règles Bot2 encore applicables avec les règles Bot3.
|
- [ ] Comparer ligne par ligne les règles Bot2 encore applicables avec les règles Bot3.
|
||||||
- [ ] Documenter chaque règle Bot2 écartée et sa justification.
|
- [ ] Documenter chaque règle Bot2 écartée et sa justification.
|
||||||
- [ ] Vérifier l’absence de contradiction sur les imports, réexports, façades, Tauri, TS-RS, logging, versionnement et archives.
|
- [ ] Vérifier l’absence de contradiction sur les imports, réexports, façades, Tauri, TS-RS, logging, versionnement et archives.
|
||||||
- [ ] Exécuter `cargo fmt --all`.
|
- [x] Exécuter `cargo fmt --all`.
|
||||||
- [ ] Exécuter `python3 scripts/audit_rust_workspace_rules.py`.
|
- [x] Exécuter `python3 scripts/audit_rust_workspace_rules.py`.
|
||||||
|
|
||||||
## 0.1 Classification des matrices de contrat
|
## 0.1 Classification des matrices de contrat
|
||||||
|
|
||||||
@@ -39,24 +39,24 @@
|
|||||||
- [x] Mettre à jour les dix-sept fichiers Rust contenant les `include_str!` concernés.
|
- [x] Mettre à jour les dix-sept fichiers Rust contenant les `include_str!` concernés.
|
||||||
- [x] Conserver le déplacement et les mises à jour de chemins dans une même livraison atomique.
|
- [x] Conserver le déplacement et les mises à jour de chemins dans une même livraison atomique.
|
||||||
- [x] Lister chaque ancien fichier avec une commande `rm --` dans `delta.md`.
|
- [x] Lister chaque ancien fichier avec une commande `rm --` dans `delta.md`.
|
||||||
- [ ] Exécuter les tests des crates consommatrices dans le workspace réel.
|
- [x] Exécuter les tests des crates consommatrices dans le workspace réel (`kb-lib`, `kb-onchain-transport`, `kb-pipeline-demo-scenarios`).
|
||||||
- [ ] Vérifier qu’aucune référence résiduelle ne pointe vers les anciens chemins `docs/*.json`.
|
- [x] Vérifier qu’aucune référence résiduelle ne pointe vers les anciens chemins `docs/*.json`.
|
||||||
|
|
||||||
## 1. Contrôles rapides avant code fonctionnel
|
## 1. Contrôles rapides avant code fonctionnel
|
||||||
|
|
||||||
### 1.1 TS-RS
|
### 1.1 TS-RS
|
||||||
|
|
||||||
- [ ] Rechercher `export_to` uniquement dans les fichiers `.rs` de `kb-config`, `kb-lib` et `kb-app-demo-desktop`.
|
- [x] Rechercher `export_to` uniquement dans les fichiers `.rs` de `kb-config`, `kb-lib` et `kb-app-demo-desktop`.
|
||||||
- [ ] Vérifier les sorties `kb_config`.
|
- [x] Vérifier les sorties `kb_config`.
|
||||||
- [ ] Vérifier les sorties `kb_lib`.
|
- [x] Vérifier les sorties `kb_lib` dans `kb-lib/frontend/ts/bindings/kb_lib`.
|
||||||
- [ ] Vérifier les sorties `kb_app_demo_desktop`.
|
- [x] Vérifier les sorties `kb_app_demo_desktop`.
|
||||||
- [ ] Supprimer les chemins historiques `kb_executor_*`.
|
- [ ] Supprimer les chemins historiques `kb_executor_*`.
|
||||||
- [ ] Supprimer les chemins historiques `kb_decoder_*`.
|
- [ ] Supprimer les chemins historiques `kb_decoder_*`.
|
||||||
- [ ] Supprimer les chemins historiques `kb_materializer_*`.
|
- [ ] Supprimer les chemins historiques `kb_materializer_*`.
|
||||||
- [ ] Supprimer les chemins historiques `kb_model`.
|
- [ ] Supprimer les chemins historiques `kb_model`.
|
||||||
- [ ] Supprimer les chemins historiques `kb_store_pg` et `kb_store_core`.
|
- [ ] Supprimer les chemins historiques `kb_store_pg` et `kb_store_core`.
|
||||||
- [ ] Régénérer les bindings via les tests TS-RS.
|
- [x] Régénérer les bindings via les tests TS-RS exécutés pendant les tests complets des crates.
|
||||||
- [ ] Vérifier que les fichiers générés correspondent exactement aux chemins déclarés.
|
- [x] Vérifier que les fichiers générés correspondent aux chemins déclarés pour `kb_config`, `kb_lib` et `kb_app_demo_desktop`.
|
||||||
|
|
||||||
### 1.2 Anciens chemins et nomenclature
|
### 1.2 Anciens chemins et nomenclature
|
||||||
|
|
||||||
@@ -68,30 +68,30 @@
|
|||||||
|
|
||||||
### 1.3 Frontend et menu
|
### 1.3 Frontend et menu
|
||||||
|
|
||||||
- [ ] Auditer les occurrences `Copier` et `Effacer` dans tous les HTML et TypeScript.
|
- [x] Auditer les occurrences `Copier` et `Effacer` dans tous les HTML et TypeScript.
|
||||||
- [ ] Garantir une seule paire de contrôles par sortie.
|
- [ ] Garantir une seule paire de contrôles par sortie.
|
||||||
- [ ] Vérifier l’ordre du menu : Configuration, Transport et collecte, Pipeline, SQL, Exécution.
|
- [x] Vérifier et corriger l’ordre du menu : Configuration, Transport et collecte, Pipeline, SQL, Exécution.
|
||||||
- [ ] Vérifier les séparateurs.
|
- [ ] Vérifier les séparateurs.
|
||||||
- [ ] Supprimer les entrées mortes.
|
- [ ] Supprimer les entrées mortes.
|
||||||
- [ ] Identifier les fenêtres migrées mais non reliées.
|
- [x] Identifier les modules SPL backend comme composants de la fenêtre consolidée `demo_execution_spl`, et non comme fenêtres autonomes oubliées.
|
||||||
|
|
||||||
## 2. Corrections UI rapides
|
## 2. Corrections UI rapides
|
||||||
|
|
||||||
### 2.1 HTTP JSON-RPC
|
### 2.1 HTTP JSON-RPC
|
||||||
|
|
||||||
- [ ] Remplacer le viewer JSON du résultat par un `textarea readonly`.
|
- [x] Remplacer le viewer JSON du résultat par un `textarea readonly`.
|
||||||
- [ ] Fixer la hauteur.
|
- [x] Fixer la hauteur.
|
||||||
- [ ] Activer le scroll interne.
|
- [x] Activer le scroll interne.
|
||||||
- [ ] Garantir exactement un bouton Copier.
|
- [x] Garantir exactement un bouton Copier pour la sortie principale.
|
||||||
- [ ] Garantir exactement un bouton Effacer.
|
- [x] Garantir exactement un bouton Effacer pour la sortie principale.
|
||||||
- [ ] Vider le buffer TypeScript lors de l’effacement.
|
- [x] Vider le buffer TypeScript lors de l’effacement.
|
||||||
- [ ] Tester JSON, scalaire, texte, erreur et résultat vide.
|
- [ ] Tester JSON, scalaire, texte, erreur et résultat vide.
|
||||||
|
|
||||||
### 2.2 WebSocket
|
### 2.2 WebSocket
|
||||||
|
|
||||||
- [ ] Afficher les messages dans un composant texte/log.
|
- [x] Afficher les messages dans un composant texte/log.
|
||||||
- [ ] Fixer la hauteur et le scroll interne.
|
- [x] Fixer la hauteur et le scroll interne.
|
||||||
- [ ] Garantir une seule paire Copier/Effacer.
|
- [x] Garantir une seule paire Copier/Effacer pour la sortie Messages.
|
||||||
- [ ] Conserver les messages pendant la session active.
|
- [ ] Conserver les messages pendant la session active.
|
||||||
- [ ] Restaurer l’affichage après fermeture/réouverture de la fenêtre.
|
- [ ] Restaurer l’affichage après fermeture/réouverture de la fenêtre.
|
||||||
|
|
||||||
@@ -302,9 +302,9 @@
|
|||||||
- [ ] `cargo test -p kb-store`.
|
- [ ] `cargo test -p kb-store`.
|
||||||
- [ ] `cargo check -p kb-lib`.
|
- [ ] `cargo check -p kb-lib`.
|
||||||
- [ ] `cargo test -p kb-lib`.
|
- [ ] `cargo test -p kb-lib`.
|
||||||
- [ ] `cargo check -p kb-app-demo-desktop`.
|
- [x] `cargo check -p kb-app-demo-desktop`.
|
||||||
- [ ] `cargo test -p kb-app-demo-desktop`.
|
- [ ] `cargo test -p kb-app-demo-desktop` (112 tests passaient, 1 contrat d’ordre de décodeurs corrigé dans `pre.057`; relance requise).
|
||||||
- [ ] `cargo check --workspace`.
|
- [x] `cargo check --workspace`.
|
||||||
- [ ] `cargo test --workspace`.
|
- [ ] `cargo test --workspace`.
|
||||||
- [ ] `python3 scripts/audit_rust_workspace_rules.py`.
|
- [ ] `python3 scripts/audit_rust_workspace_rules.py`.
|
||||||
- [ ] `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`.
|
- [ ] `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: RULES_SPECIFIC_KHADHROONY.md -->
|
<!-- file: RULES_SPECIFIC_KHADHROONY.md -->
|
||||||
<!-- version: 3 -->
|
<!-- version: 4 -->
|
||||||
|
|
||||||
# Règles spécifiques à `khadhroony-bot3`
|
# Règles spécifiques à `khadhroony-bot3`
|
||||||
|
|
||||||
@@ -216,7 +216,9 @@ Les `program_id` connus doivent être définis une seule fois dans `kb-program-i
|
|||||||
|
|
||||||
## Validation frontend Tauri
|
## Validation frontend Tauri
|
||||||
|
|
||||||
- Pour `kb-app-demo-desktop`, ne pas lancer `npm --prefix kb-app-demo run build` séparément : la validation frontend de développement est réalisée par `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`, qui démarre et pilote le serveur Vite.
|
- Pour `kb-app-demo-desktop`, ne jamais exécuter `npm run build`, `npm --prefix kb-app-demo-desktop run build` ni une commande équivalente de build frontend autonome.
|
||||||
|
- L’installation manuelle d’une dépendance frontend est limitée aux commandes npm d’ajout nécessaires, notamment `npm i -D <package>` pour une dépendance de développement ; `node_modules/` et `package-lock.json` restent locaux, générés et non livrables.
|
||||||
|
- La validation frontend de développement est réalisée uniquement par `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`, qui démarre et pilote Vite selon la configuration Tauri.
|
||||||
|
|
||||||
## Architecture `khadhroony-bot3`
|
## Architecture `khadhroony-bot3`
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: kb-app-demo-desktop/frontend/demo_http.html -->
|
<!-- file: kb-app-demo-desktop/frontend/demo_http.html -->
|
||||||
<!-- version: 4 -->
|
<!-- version: 5 -->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
|
|
||||||
@@ -72,9 +72,12 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
<h2 class="h5 card-title mb-0">Résultat</h2>
|
<h2 class="h5 card-title mb-0">Résultat</h2>
|
||||||
<button id="copyHttpResultButton" class="btn btn-sm btn-outline-secondary">Copier</button>
|
<div class="d-flex gap-2">
|
||||||
|
<button id="copyHttpResultButton" class="btn btn-sm btn-outline-secondary" type="button">Copier</button>
|
||||||
|
<button id="clearHttpResultButton" class="btn btn-sm btn-outline-secondary" type="button">Effacer</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea id="httpResultOutput" class="form-control font-monospace" rows="18" readonly data-json-viewer="true">Aucune requête exécutée.</textarea>
|
<textarea id="httpResultOutput" class="form-control font-monospace" style="height: 24rem; overflow-y: auto;" readonly>Aucune requête exécutée.</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -89,9 +89,12 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||||
<h2 class="h5 card-title mb-0">Messages</h2>
|
<h2 class="h5 card-title mb-0">Messages</h2>
|
||||||
<button id="copyWsResultButton" class="btn btn-sm btn-outline-secondary">Copier</button>
|
<div class="d-flex gap-2">
|
||||||
|
<button id="copyWsResultButton" class="btn btn-sm btn-outline-secondary" type="button">Copier</button>
|
||||||
|
<button id="clearWsResultButton" class="btn btn-sm btn-outline-secondary" type="button">Effacer</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea id="wsResultOutput" class="form-control font-monospace" rows="16" readonly data-json-viewer="true">Aucune connexion active.</textarea>
|
<textarea id="wsResultOutput" class="form-control font-monospace" style="height: 24rem; overflow-y: auto;" readonly>Aucune connexion active.</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
<hr class="dropdown-divider">
|
<hr class="dropdown-divider">
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h6 class="dropdown-header">Stockage</h6>
|
<h6 class="dropdown-header">SQL</h6>
|
||||||
</li>
|
</li>
|
||||||
<li><a id="openDemoSqlDiagLink" class="dropdown-item" href="#">SQL diagnostics</a></li>
|
<li><a id="openDemoSqlDiagLink" class="dropdown-item" href="#">SQL diagnostics</a></li>
|
||||||
<li><a id="openDemoSqlPgRawLink" class="dropdown-item" href="#">SQL PostgreSQL raw</a></li>
|
<li><a id="openDemoSqlPgRawLink" class="dropdown-item" href="#">SQL PostgreSQL raw</a></li>
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
<hr class="dropdown-divider">
|
<hr class="dropdown-divider">
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<h6 class="dropdown-header">Exécution Devnet</h6>
|
<h6 class="dropdown-header">Exécution</h6>
|
||||||
</li>
|
</li>
|
||||||
<li><a id="openDemoExecutionSolanaCoreLink" class="dropdown-item" href="#">Solana Core</a></li>
|
<li><a id="openDemoExecutionSolanaCoreLink" class="dropdown-item" href="#">Solana Core</a></li>
|
||||||
<li><a id="openDemoExecutionSplLink" class="dropdown-item" href="#">SPL</a></li>
|
<li><a id="openDemoExecutionSplLink" class="dropdown-item" href="#">SPL</a></li>
|
||||||
@@ -98,4 +98,4 @@
|
|||||||
<script type="module" src="ts/main.ts" defer></script>
|
<script type="module" src="ts/main.ts" defer></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: kb-app-demo-desktop/frontend/ts/demo_http.ts
|
// file: kb-app-demo-desktop/frontend/ts/demo_http.ts
|
||||||
// version: 4
|
// version: 5
|
||||||
|
|
||||||
import * as bootstrap from "bootstrap";
|
import * as bootstrap from "bootstrap";
|
||||||
import "simplebar";
|
import "simplebar";
|
||||||
@@ -17,6 +17,7 @@ import type { DemoHttpRoleOption } from "./bindings/kb_app_demo_desktop/demo_htt
|
|||||||
|
|
||||||
let roleOptions: DemoHttpRoleOption[] = [];
|
let roleOptions: DemoHttpRoleOption[] = [];
|
||||||
let methodOptions: DemoHttpMethodOption[] = [];
|
let methodOptions: DemoHttpMethodOption[] = [];
|
||||||
|
let httpResultBuffer = "Aucune requête exécutée.";
|
||||||
|
|
||||||
function textInputValue(selector: string): string {
|
function textInputValue(selector: string): string {
|
||||||
const element = document.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(selector);
|
const element = document.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(selector);
|
||||||
@@ -30,6 +31,16 @@ function writeTextarea(selector: string, value: string): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function writeHttpResult(value: string): void {
|
||||||
|
httpResultBuffer = value;
|
||||||
|
writeTextarea("#httpResultOutput", httpResultBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearHttpResult(): void {
|
||||||
|
httpResultBuffer = "";
|
||||||
|
writeTextarea("#httpResultOutput", httpResultBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
function jsonText(value: unknown): string {
|
function jsonText(value: unknown): string {
|
||||||
if (typeof value === "string") {
|
if (typeof value === "string") {
|
||||||
return value;
|
return value;
|
||||||
@@ -121,7 +132,7 @@ async function refreshHttpOptions(): Promise<void> {
|
|||||||
refreshMethodList();
|
refreshMethodList();
|
||||||
} catch (caughtError) {
|
} catch (caughtError) {
|
||||||
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
||||||
writeTextarea("#httpResultOutput", `Erreur options HTTP : ${message}`);
|
writeHttpResult(`Erreur options HTTP : ${message}`);
|
||||||
frontendError("kb-app-demo-desktop.frontend.demo_http", `HTTP options loading failed: ${message}`);
|
frontendError("kb-app-demo-desktop.frontend.demo_http", `HTTP options loading failed: ${message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,14 +156,14 @@ async function executeHttpRequest(): Promise<void> {
|
|||||||
configJson: textInputValue("#httpConfigInput") || null,
|
configJson: textInputValue("#httpConfigInput") || null,
|
||||||
paramsJson: textInputValue("#httpParamsInput") || null,
|
paramsJson: textInputValue("#httpParamsInput") || null,
|
||||||
};
|
};
|
||||||
writeTextarea("#httpResultOutput", "Exécution en cours...");
|
writeHttpResult("Exécution en cours...");
|
||||||
try {
|
try {
|
||||||
const response = await invoke<DemoHttpExecutionPayload>("demo_http_execute_request", { request });
|
const response = await invoke<DemoHttpExecutionPayload>("demo_http_execute_request", { request });
|
||||||
writeTextarea("#httpResultOutput", formatHttpExecutionPayload(response));
|
writeHttpResult(formatHttpExecutionPayload(response));
|
||||||
frontendDebug("kb-app-demo-desktop.frontend.demo_http", `HTTP request completed: ${response.method}`);
|
frontendDebug("kb-app-demo-desktop.frontend.demo_http", `HTTP request completed: ${response.method}`);
|
||||||
} catch (caughtError) {
|
} catch (caughtError) {
|
||||||
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
||||||
writeTextarea("#httpResultOutput", `Erreur : ${message}`);
|
writeHttpResult(`Erreur : ${message}`);
|
||||||
frontendError("kb-app-demo-desktop.frontend.demo_http", `HTTP request failed: ${message}`);
|
frontendError("kb-app-demo-desktop.frontend.demo_http", `HTTP request failed: ${message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,6 +187,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
document.querySelector<HTMLButtonElement>("#copyHttpResultButton")?.addEventListener("click", () => {
|
document.querySelector<HTMLButtonElement>("#copyHttpResultButton")?.addEventListener("click", () => {
|
||||||
void copyTextarea("#httpResultOutput");
|
void copyTextarea("#httpResultOutput");
|
||||||
});
|
});
|
||||||
|
document.querySelector<HTMLButtonElement>("#clearHttpResultButton")?.addEventListener("click", clearHttpResult);
|
||||||
void refreshHttpOptions();
|
void refreshHttpOptions();
|
||||||
void refreshHttpPool();
|
void refreshHttpPool();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import type {DemoWsUnsubscribeRequest} from "./bindings/kb_app_demo_desktop/demo
|
|||||||
|
|
||||||
let roleOptions: DemoWsRoleOption[] = [];
|
let roleOptions: DemoWsRoleOption[] = [];
|
||||||
let methodOptions: DemoWsMethodOption[] = [];
|
let methodOptions: DemoWsMethodOption[] = [];
|
||||||
|
let wsMessageBuffer = "Aucune connexion active.";
|
||||||
|
|
||||||
const maxResultOutputCharacters = 200_000;
|
const maxResultOutputCharacters = 200_000;
|
||||||
const maxIncomingMessageCharacters = 25_000;
|
const maxIncomingMessageCharacters = 25_000;
|
||||||
@@ -51,16 +52,33 @@ function capTextareaValue(value: string): string {
|
|||||||
return `... historique tronqué côté UI ...\n${value.slice(value.length - maxResultOutputCharacters)}`;
|
return `... historique tronqué côté UI ...\n${value.slice(value.length - maxResultOutputCharacters)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function writeWsMessages(value: string): void {
|
||||||
|
wsMessageBuffer = capTextareaValue(value);
|
||||||
|
writeTextarea("#wsResultOutput", wsMessageBuffer);
|
||||||
|
const element = document.querySelector<HTMLTextAreaElement>("#wsResultOutput");
|
||||||
|
if (element) {
|
||||||
|
element.scrollTop = element.scrollHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function appendTextarea(selector: string, value: string): void {
|
function appendTextarea(selector: string, value: string): void {
|
||||||
const element = document.querySelector<HTMLTextAreaElement>(selector);
|
if (selector !== "#wsResultOutput") {
|
||||||
if (!element) {
|
const element = document.querySelector<HTMLTextAreaElement>(selector);
|
||||||
|
if (element) {
|
||||||
|
const previous = element.value.trim();
|
||||||
|
const safeValue = truncateIncomingMessage(value);
|
||||||
|
element.value = capTextareaValue(previous.length > 0 ? `${previous}\n\n${safeValue}` : safeValue);
|
||||||
|
element.scrollTop = element.scrollHeight;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const previous = element.value.trim();
|
const previous = wsMessageBuffer.trim();
|
||||||
const safeValue = truncateIncomingMessage(value);
|
const safeValue = truncateIncomingMessage(value);
|
||||||
const nextValue = previous.length > 0 ? `${previous}\n\n${safeValue}` : safeValue;
|
writeWsMessages(previous.length > 0 ? `${previous}\n\n${safeValue}` : safeValue);
|
||||||
element.value = capTextareaValue(nextValue);
|
}
|
||||||
element.scrollTop = element.scrollHeight;
|
|
||||||
|
function clearWsMessages(): void {
|
||||||
|
writeWsMessages("");
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsonText(value: unknown): string {
|
function jsonText(value: unknown): string {
|
||||||
@@ -195,7 +213,7 @@ async function refreshWsOptions(): Promise<void> {
|
|||||||
refreshMethodList();
|
refreshMethodList();
|
||||||
} catch (caughtError) {
|
} catch (caughtError) {
|
||||||
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
||||||
writeTextarea("#wsResultOutput", `Erreur options WebSocket : ${message}`);
|
writeWsMessages(`Erreur options WebSocket : ${message}`);
|
||||||
frontendError("kb-app-demo-desktop.frontend.demo_ws", `WebSocket options loading failed: ${message}`);
|
frontendError("kb-app-demo-desktop.frontend.demo_ws", `WebSocket options loading failed: ${message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,15 +248,15 @@ async function connectWsRequest(): Promise<void> {
|
|||||||
filterJson: textInputValue("#wsFilterInput") || null,
|
filterJson: textInputValue("#wsFilterInput") || null,
|
||||||
configJson: textInputValue("#wsConfigInput") || null,
|
configJson: textInputValue("#wsConfigInput") || null,
|
||||||
};
|
};
|
||||||
writeTextarea("#wsResultOutput", "Souscription en cours sur la connexion WebSocket...");
|
writeWsMessages("Souscription en cours sur la connexion WebSocket...");
|
||||||
try {
|
try {
|
||||||
const response = await invoke<DemoWsExecutionPayload>("demo_ws_connect", { request });
|
const response = await invoke<DemoWsExecutionPayload>("demo_ws_connect", { request });
|
||||||
writeTextarea("#wsResultOutput", formatWsExecutionPayload(response));
|
writeWsMessages(formatWsExecutionPayload(response));
|
||||||
frontendDebug("kb-app-demo-desktop.frontend.demo_ws", `WebSocket subscribed: ${response.method}`);
|
frontendDebug("kb-app-demo-desktop.frontend.demo_ws", `WebSocket subscribed: ${response.method}`);
|
||||||
await refreshWsStatus();
|
await refreshWsStatus();
|
||||||
} catch (caughtError) {
|
} catch (caughtError) {
|
||||||
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
const message = caughtError instanceof Error ? caughtError.message : String(caughtError);
|
||||||
writeTextarea("#wsResultOutput", `Erreur : ${message}`);
|
writeWsMessages(`Erreur : ${message}`);
|
||||||
frontendError("kb-app-demo-desktop.frontend.demo_ws", `WebSocket subscription failed: ${message}`);
|
frontendError("kb-app-demo-desktop.frontend.demo_ws", `WebSocket subscription failed: ${message}`);
|
||||||
await refreshWsStatus();
|
await refreshWsStatus();
|
||||||
}
|
}
|
||||||
@@ -318,6 +336,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
document.querySelector<HTMLButtonElement>("#copyWsResultButton")?.addEventListener("click", () => {
|
document.querySelector<HTMLButtonElement>("#copyWsResultButton")?.addEventListener("click", () => {
|
||||||
void copyTextarea("#wsResultOutput");
|
void copyTextarea("#wsResultOutput");
|
||||||
});
|
});
|
||||||
|
document.querySelector<HTMLButtonElement>("#clearWsResultButton")?.addEventListener("click", clearWsMessages);
|
||||||
void installWsEventListeners();
|
void installWsEventListeners();
|
||||||
void refreshWsOptions();
|
void refreshWsOptions();
|
||||||
void refreshWsPool();
|
void refreshWsPool();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: kb-app-demo-desktop/src/demo_decode_replay.rs
|
// file: kb-app-demo-desktop/src/demo_decode_replay.rs
|
||||||
// version: 27
|
// version: 28
|
||||||
|
|
||||||
//! Tauri commands and UI payloads for contextual instruction decode replay.
|
//! Tauri commands and UI payloads for contextual instruction decode replay.
|
||||||
|
|
||||||
@@ -727,13 +727,13 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
names,
|
names,
|
||||||
std::vec![
|
std::vec![
|
||||||
"metadata_metaplex_token_metadata".to_string(),
|
|
||||||
"solana_native_classifier".to_string(),
|
"solana_native_classifier".to_string(),
|
||||||
"spl_associated_token_account".to_string(),
|
"spl_associated_token_account".to_string(),
|
||||||
"spl_elgamal_registry".to_string(),
|
"spl_elgamal_registry".to_string(),
|
||||||
"spl_memo".to_string(),
|
"spl_memo".to_string(),
|
||||||
"spl_token".to_string(),
|
"spl_token".to_string(),
|
||||||
"spl_token2022".to_string(),
|
"spl_token2022".to_string(),
|
||||||
|
"metadata_metaplex_token_metadata".to_string(),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: kb-config/src/environment.rs
|
// file: kb-config/src/environment.rs
|
||||||
// version: 1
|
// version: 2
|
||||||
|
|
||||||
//! Environment-file loading and configuration placeholder resolution.
|
//! Environment-file loading and configuration placeholder resolution.
|
||||||
|
|
||||||
@@ -64,8 +64,9 @@ pub fn resolve_environment_placeholders(raw: &str) -> std::string::String {
|
|||||||
},
|
},
|
||||||
std::option::Option::None => (expression, std::option::Option::None),
|
std::option::Option::None => (expression, std::option::Option::None),
|
||||||
};
|
};
|
||||||
let resolved =
|
let resolved = std::env::var(name)
|
||||||
std::env::var(name).ok().or_else(|| fallback.map(|value| value.to_string()));
|
.ok()
|
||||||
|
.or_else(|| return fallback.map(|value| return value.to_string()));
|
||||||
match resolved {
|
match resolved {
|
||||||
std::option::Option::Some(value) => output.push_str(&value),
|
std::option::Option::Some(value) => output.push_str(&value),
|
||||||
std::option::Option::None => output.push_str(&raw[start..=end]),
|
std::option::Option::None => output.push_str(&raw[start..=end]),
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user