Offline runnable Thesaurus Training Web App – JavaScript in Action

Since Web SQL is deprecated I use IndexedDB as client storage to get the offline part of my offline runnable thesaurus training web app done. I did not get memory limits yet on any browser. Just on desktop safari it takes eternity to import the data into IndexedDB. On mobile Safari it will probably take 10 times eternity. So, safari users can forget the offline part und must go the online route. Or install Chrome or Firefox. But, hey, thanks to progressive enhancement, the app will not break for you und you can still use the app with all features online. I do not suspend Safari users from thesaurus training! The CSV files which I converted the wordnet DB by a small Java program from an SQLite DB into are 16.7 MB big. The CSV files are stored as ZIP files on the server. They are downloaded and decompressed by using the JavaScript library zip.js. According to the author the library uses many interesting APIs of which Typed array (originated in WebGL) is mandatory and Web workers, File, File Writer and File Directories and System can be treated as optional. I use the whole package for now and will do the fine tuning, which means integrating older browsers, later. Only for production I had to change the code to have the file sizes of the zipped CSV files as static arguments available, since the Ajax requests for getting the Content-Length from response headers for that files failed. Since it’s static data, I have no problem doing this and I do not have to puzzle on the strange problem.
As I had read Christian Heilmanns book alone, the only thing to structure my code was the JavaScript object notation. But I found it too bad, that each and every variable and function was public. That’s not a nice interface for the small library I had written to download and uncompress the data and store it into IndexedDB and to access the data. This is not how software development works. I want to be able to read the code several years later und a clear public interface helps enormously. Here is an example model for how I am structuring my database code now:

var KasparDavid = (function () {
 // Instance stores a reference to the Singleton
 var instance;
 function init() {
   // Singleton
   // Private methods and variables
   function getName(){
       return privateNameFirst + " " + privateNameLast;
   }
   var privateNameFirst = "Kaspar";
   var privateNameLast = "David";
   return {
     // Public methods and variables
     introduceYourselfTo: function (name) {
       console.log( "Hello " + name + ", I'm " + getName());
     },
     publicFunction: "intoduceYourselfTo"
   };
 };
 return {
   // Get the Singleton instance if one exists
   // or create one if it doesn't
   getInstance: function () {
     if ( !instance ) {
       instance = init();
     }
     return instance;
   }
 };
})();
// Usage:
var singleA = KasparDavid.getInstance();
var singleB = KasparDavid.getInstance();
console.log( singleA === singleB ); // true
singleA.introduceYourselfTo("Sandra");

Like the example class KasparDavid I have a Singleton data access class which has only one instance because I do not want to have some functionality executed multiple times simultaneously. The data access class has a public interface and hides all the complex things, that have to be done to import the data and show the import state and to make complex queries that return a model for rendering.
The database script is unobtrusive since the app does not depend on the offline feature. If no JavaScript is available loading the data works with good old reloading the page. If the import is running the data requested by the user is loaded via Ajax. I like JavaScript here very much. The Ajax request fetches some JSON wich can be directly converted into a complex JavaScript object.