Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@nozbe/lokijs

Package Overview
Dependencies
Maintainers
8
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nozbe/lokijs - npm Package Compare versions

Comparing version 1.5.11-wmelon-idb-fix to 1.5.11-wmelon-idb-fix2

2

package.json
{
"name": "@nozbe/lokijs",
"version": "1.5.11-wmelon-idb-fix",
"version": "1.5.11-wmelon-idb-fix2",
"description": "Nozbe's temporary fork of LokiJS - used for WatermelonDB purposes to work around NPM issues",

@@ -5,0 +5,0 @@ "homepage": "https://techfort.github.io/LokiJS/",

@@ -40,2 +40,5 @@ (function(root, factory) {

* Use this as an opportunity to execute code concurrently while IDB does work on a separate thread
* @param {function} options.onDidOverwrite Called when this adapter is forced to overwrite contents
* of IndexedDB. This happens if there's another open tab of the same app that's making changes.
* You might use it as an opportunity to alert user to the potential loss of data
* @param {function} options.serializeChunk Called with a chunk (array of Loki documents) before

@@ -165,65 +168,89 @@ * it's saved to IndexedDB. You can use it to manually compress on-disk representation

var updatePrevVersionIds = function () {
console.error('Unexpected successful tx - cannot update previous version ids');
};
// try..catch is required, e.g.:
// InvalidStateError: Failed to execute 'transaction' on 'IDBDatabase': The database connection is closing.
// (this may happen if another tab has called deleteDatabase)
try {
var updatePrevVersionIds = function () {
console.error('Unexpected successful tx - cannot update previous version ids');
};
var didOverwrite = false;
DEBUG && console.log("save tx: begin");
var tx = this.idb.transaction(['LokiIncrementalData'], "readwrite");
tx.oncomplete = function() {
updatePrevVersionIds();
DEBUG && console.log("save tx: complete");
return finish();
};
var tx = this.idb.transaction(['LokiIncrementalData'], "readwrite");
tx.oncomplete = function() {
updatePrevVersionIds();
finish();
if (didOverwrite && that.options.onDidOverwrite) {
that.options.onDidOverwrite();
}
};
tx.onerror = function(e) {
DEBUG && console.log("save tx: error");
return finish(e);
};
tx.onerror = function(e) {
finish(e);
};
tx.onabort = function(e) {
DEBUG && console.log("save tx: abort");
return finish(e);
};
tx.onabort = function(e) {
finish(e);
};
var store = tx.objectStore('LokiIncrementalData');
var store = tx.objectStore('LokiIncrementalData');
function performSave(maxChunkIds) {
var incremental = !maxChunkIds;
var chunkInfo = that._putInChunks(store, getLokiCopy(), incremental, maxChunkIds);
updatePrevVersionIds = function() {
that._prevLokiVersionId = chunkInfo.lokiVersionId;
chunkInfo.collectionVersionIds.forEach(function (collectionInfo) {
that._prevCollectionVersionIds[collectionInfo.name] = collectionInfo.versionId;
var performSave = function (maxChunkIds) {
try {
var incremental = !maxChunkIds;
var chunkInfo = that._putInChunks(store, getLokiCopy(), incremental, maxChunkIds);
// Update last seen version IDs, but only after the transaction is successful
updatePrevVersionIds = function() {
that._prevLokiVersionId = chunkInfo.lokiVersionId;
chunkInfo.collectionVersionIds.forEach(function (collectionInfo) {
that._prevCollectionVersionIds[collectionInfo.name] = collectionInfo.versionId;
});
};
tx.commit && tx.commit();
} catch (error) {
console.error('idb performSave failed: ', error);
tx.abort();
}
};
// Incrementally saving changed chunks breaks down if there is more than one writer to IDB
// (multiple tabs of the same web app), leading to data corruption. To fix that, we save all
// metadata chunks (loki + collections) with a unique ID on each save and remember it. Before
// the subsequent save, we read loki from IDB to check if its version ID changed. If not, we're
// guaranteed that persisted DB is consistent with our diff. Otherwise, we fall back to the slow
// path and overwrite *all* database chunks with our version. Both reading and writing must
// happen in the same IDB transaction for this to work.
// TODO: We can optimize the slow path by fetching collection metadata chunks and comparing their
// version IDs with those last seen by us. Since any change in collection data requires a metadata
// chunk save, we're guaranteed that if the IDs match, we don't need to overwrite chukns of this collection
var getAllKeysThenSave = function() {
// NOTE: We must fetch all keys to protect against a case where another tab has wrote more
// chunks whan we did -- if so, we must delete them.
idbReq(store.getAllKeys(), function(e) {
var maxChunkIds = getMaxChunkIds(e.target.result);
performSave(maxChunkIds);
}, function(e) {
console.error('Getting all keys failed: ', e);
tx.abort();
});
};
DEBUG && console.log('chunks saved');
tx.commit && tx.commit();
}
function getAllKeysThenSave() {
idbReq(store.getAllKeys(), function(e) {
var maxChunkIds = getMaxChunkIds(e.target.result);
performSave(maxChunkIds);
}, function(e) {
console.error('Getting all keys failed: ', e);
tx.abort();
});
}
var getLokiThenSave = function() {
idbReq(store.get('loki'), function(e) {
if (lokiChunkVersionId(e.target.result) === that._prevLokiVersionId) {
performSave();
} else {
DEBUG && console.warn('Another writer changed Loki IDB, using slow path...');
didOverwrite = true;
getAllKeysThenSave();
}
}, function(e) {
console.error('Getting loki chunk failed: ', e);
tx.abort();
});
};
function getLokiThenSave() {
idbReq(store.get('loki'), function(e) {
if (lokiChunkVersionId(e.target.result) === that._prevLokiVersionId) {
performSave();
} else {
DEBUG && console.warn('--------> LOKI CHANGED!!! [slow path]');
// TODO: Get collection metadata chunks
getAllKeysThenSave();
}
}, function(e) {
console.error('Getting loki chunk failed: ', e);
tx.abort();
});
getLokiThenSave();
} catch (error) {
finish(error);
}
getLokiThenSave();
};

@@ -290,2 +317,3 @@

savedSize += chunkData.length;
DEBUG && incremental && console.log('Saving: ' + collection.name + ".chunk." + chunkId);
idbStore.put({

@@ -325,2 +353,3 @@ key: collection.name + ".chunk." + chunkId,

savedSize += metadataChunk.length;
DEBUG && incremental && console.log('Saving: ' + collection.name + ".metadata");
idbStore.put({

@@ -341,2 +370,3 @@ key: collection.name + ".metadata",

DEBUG && incremental && console.log('Saving: loki');
idbStore.put({ key: "loki", value: serializedMetadata });

@@ -539,2 +569,7 @@

db.onversionchange = function(versionChangeEvent) {
// Ignore if database was deleted and recreated in the meantime
if (that.idb !== db) {
return;
}
DEBUG && console.log('IDB version change', versionChangeEvent);

@@ -547,3 +582,4 @@ // This function will be called if another connection changed DB version

// to force logout
db.close();
that.idb.close();
that.idb = null;
if (that.options.onversionchange) {

@@ -580,11 +616,8 @@ that.options.onversionchange(versionChangeEvent);

var request = tx.objectStore('LokiIncrementalData').getAll();
request.onsuccess = function(e) {
idbReq(tx.objectStore('LokiIncrementalData').getAll(), function(e) {
var chunks = e.target.result;
callback(chunks);
};
request.onerror = function(e) {
}, function(e) {
callback(e);
};
});

@@ -682,3 +715,9 @@ if (this.options.onFetchStart) {

function idbReq(request, onsuccess, onerror) {
request.onsuccess = onsuccess;
request.onsuccess = function (e) {
try {
return onsuccess(e);
} catch (error) {
onerror(error);
}
};
request.onerror = onerror;

@@ -685,0 +724,0 @@ return request;

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc