TL DR Part of the Javascript code runs flawlessly on Linux but behaves inconsistently on Windows.
I am coding an Electron application using Vue.js for frontend, Vuex for data management, and LokiJS for persistence (with its file system adapter in the background). I develop this application on Linux, but from time to time I have to switch to Windows to create a Windows build for the client. Linux compilation always works flawlessly, and Windows doesnβt work properly. I assumed that this is a LokiJS problem, however, when isolating LokiJS-specific code, it worked fine even on Windows.
Here is a simplified store.js file containing all the relevant Vuex and LokiJS codes in my application.
import loki from 'lokijs' import LokiSFSAdapter from 'lokijs/src/loki-fs-structured-adapter' import MainState from '../index' // a Vuex.Store object const state = { ads: [], profiles: [] } var sfsAdapter = new LokiSFSAdapter('loki') var db = new loki('database.json', { autoupdate: true, autoload: true, autoloadCallback: setupHandler, adapter: sfsAdapter }) function setupCollection (collectionName) { var collection = db.getCollection(collectionName) if (collection === null) { collection = db.addCollection(collectionName) } } function setupHandler () { setupCollection('ads') setupCollection('profiles') MainState.commit('updateAds') MainState.commit('updateProfiles') } window.onbeforeunload = function () { db.saveDatabase() db.close() } const mutations = { updateAds (state) { state.ads = db.getCollection('ads').data.slice() }, updateProfiles (state) { state.profiles = db.getCollection('profiles').data.slice() } } const actions = { async addProfile (context) { db.getCollection('profiles').insert({ /* default data */ }) db.saveDatabase() context.commit('updateProfiles') }, async updateProfile (context, obj) { db.getCollection('profiles').update(obj) db.saveDatabase() context.commit('updateProfiles') }, async deleteProfile (context, id) { db.getCollection('profiles').removeWhere({'$loki': {'$eq': id}}) db.saveDatabase() context.commit('updateProfiles') }, async addAd (context) { db.getCollection('ads').insert({ /* default data */ }) db.saveDatabase() context.commit('updateAds') }, async deleteAd (context, id) { db.getCollection('ads').removeWhere({'$loki': {'$eq': id}}) db.saveDatabase() context.commit('updateAds') } }
Linux behavior
- it calls
setupHandler every time the application starts, - it correctly saves the data in
database.json and the corresponding collections in database.json.0 and database.json.1 for ads and profiles - when
addAd() is called, it can access all the data correctly by calling db.getCollection('ads') and then insert() on it.
Windows Behavior
- only calls
setupHandler if database.json does not exist. It creates database.json correctly if it does not exist. - creates only one file -
database.json.0 , but does not save any data, it is just an empty file. It does not even create database.json.1 for the second collection. - obviously, since the data is not actually saved,
db.getCollection('ads') returns null , which leads to TypeError: Cannot read property 'insert' of null when addAd() called when the application is launched sequentially. - If this launch of
database.json was created, the application behaves normally, insert() seems to work, but the data is not saved when exiting, and successive runs result in behavior at the point indicated above.
Question
Is this a bug somewhere deep in LokiJS / Vuex, or is it just that I am abusing their API?
source share