Charger des scripts dans IndexedDB

Comment faire de IndexedDB une bibliothèque de fonctions pour une application Web ou Electron.

Nous voulons stocker le script suivant dans la base de données:

// Classical Fibonacci algorithm

var fibmax=16
var z=0

function fib(n) {
   if(n<=1) {
      z=n
   }   
   else {
      z=0+fib(n-1)+fib(n-2)
   }
   return z
}

alert("Script available")

Le message d'alerte n'est là que pour la démonstration.

Le script a un titre, "Fibo" qui sert de clé d'indexation.

1) Ajouter le script à la base

function addScript(dname, sname, scriptTitle, code) {
  return new Promise(function(resolve) {
    var r = window.indexedDB.open(dname)
      r.onupgradeneeded = function() {
        var idb = r.result
        var store = idb.createObjectStore(sname)
     }
     r.onsuccess = function() {
        var idb = r.result
        let tactn = idb.transaction(sname, "readwrite")
        var store = tactn.objectStore(sname)
        store.put(code, scriptTitle)
        resolve(idb)
     }
     r.onerror = function (e) {
       alert("Enable to access IndexedDB, " + e.target.errorCode)
     }    
  })
}

La base n'utilise pas de schéma comme c'est le cas pour l'importation d'objets JavaScript, aussi la commande put à pour paramètres le code de la fonction et le titre qui sert de clé d'indexation.

Le code du script est téléchargé à partir d'un fichier source avec la commande fetch.

async function loadFile(fname, title) {
  var response = await fetch(fname)
  var code = await response.text()
  var idb = await addScript("Library", "LibStore", title, code)
  return idb
}

La base de donnée dans l'exemple est nommée "Library" et la table de stockage "LibStore".

2) Afficher le contenu de la base

Le script est retrouvé dans la base à partir de son titre et le code obtenu par la méthode get de IndexedDB.

function getCode(dname, sname, scriptTitle) {
  return new Promise(function(resolve) {
    var r = indexedDB.open(dname)
    r.onsuccess = function(e) {
      var idb = r.result
      let tactn = idb.transaction(sname, "readonly")
      let store = tactn.objectStore(sname)
      let code = store.get(scriptTitle)
      code.onsuccess = function() {
        resolve(code.result)
      }
      tactn.oncomplete = function() {
        idb.close()
      }
    }
  })
}

La fonction suivante affiche le titre et le code dans la page HTML.

async function show() {
  var title = "Fibo"
  var code = await getCode("Library", "LibStore", title)
  document.getElementById("title").innerHTML = title
  document.getElementById("code").innerHTML = code
}

Pour les présenter, on place le titre dans une balise <div> et le code dans une balise <pre>

Le code est ainsi juste affiché. Si on veut le rendre actif, on le placera plutôt dans une balise <script>.

3) Lancer le script

Il est placé dans cette balise:

<script id="script"></script>

Le script est rendu actif et exécuté:

async function runScript() {
  var title = "Fibo"
  var code = await getCode("Library", "LibStore", title)
  document.getElementById("script").innerHTML = code

  var result = document.getElementById("result")
  for(let i=2; i< 15; i++) {
     result.innerHTML += fib(i) + "</br>"
  }    
}

Dès que le code est inséré dans la balise <script>, il devient actif et la commande alert affiche le message "Script disponible". La fonction fib elle attend d'être appelée, ce que fait la boucle ci-dessus, le résulat de l'appel étant affiché dans une nouvelle balise.

Le code source complet est dans disponible dans une archive à télécharger.

Vous pouvez tester la démo localement avec Firefox ou en ligne avec tout navigateur:

Voir aussi: