Why does LokiSFSAdapter work on Linux, but not on Windows?

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?

+5
source share

Source: https://habr.com/ru/post/1274848/


All Articles