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

journeyapps

Package Overview
Dependencies
Maintainers
1
Versions
586
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

journeyapps - npm Package Compare versions

Comparing version 0.3.0 to 0.3.1

db/Batch.js

122

db/database.js

@@ -11,2 +11,3 @@ // # Database

var evaluator = require('./evaluator');
var Batch = require('./Batch');

@@ -70,4 +71,14 @@ require('./primitives');

this._adapter = adapter;
// Extends batch.Batch, passing adapter as an argument to the constructor.
this.Batch = function() {
Batch.call(this, adapter);
};
this.Batch.prototype = Object.create(Batch.prototype);
this.Batch.prototype.constructor = Batch;
}
// ## Collection

@@ -287,4 +298,4 @@ // This is the external interface for an object collection, as in `DB.asset`.

// Wait until this object and its relationships has finished loading, then save it.
// We need to wait for the relationships so that we have their id's.
// Returns a promise that is resolved when this object is saved.

@@ -297,43 +308,67 @@ function _save() {

if(saving) {
// Prevent infinite recursion when saving related objects
return Promise.resolve();
}
saving = true;
try {
var data = objself.toData(false);
var patch = null;
if(persisted) {
patch = objself.toData(true);
// Create a batch with this object.
// Note that other objects may implicitly be added to the batch via
// belongs-to relationships.
var batch = new Batch(adapter);
batch.save(this);
return batch.execute().catch(function(error) {
if(error instanceof Batch.CrudError) {
return Promise.reject(error.firstError());
} else {
return Promise.reject(error);
}
});
}
var promise = adapter.save(data, patch);
/**
* Mark the object as persisted.
*/
function _persisted() {
persisted = true;
// We don't need to wait for the promise to complete - we can immediately reset the state.
persisted = true;
// Clear the "dirty" state
attributesDirty = {};
belongsToDirty = {};
}
/**
* Mark the object as destroyed.
*/
function _destroyed() {
persisted = false;
destroyed = true;
}
// Save related objects
// TODO: we need a way to keep track of the dirty state between this object and related objects,
// so that we don't have to save the entire tree every time.
var promises = [promise];
/**
* Returns an array of this object and any related objects that should be saved.
*
* @param {object[]} [into] - array to populate
*/
function _getDirtyList(into) {
if(into == null) {
into = [];
}
if(destroyed) {
// Don't save a destroyed object
return into;
}
if(saving) {
// Prevent recursion into self
return into;
}
saving = true;
into.push(objself);
try {
Object.keys(belongsToCache).forEach(function(key) {
var related = belongsToCache[key];
// undefined means not dirty, while null means cleared
if(related != null) {
promises.push(related._save());
if(related._adapter === adapter) {
related._getDirtyList(into);
} else {
// Different adapter - can't add to the same batch.
// Don't save the related object in this case.
}
}
});
// Clear the "dirty" state
attributesDirty = {};
belongsToDirty = {};
return Promise.all(promises);
return into;
} finally {

@@ -347,9 +382,9 @@ saving = false;

function _destroy() {
destroyed = true;
if(id != null) {
var promise = adapter.destroy(objself.type.name, objself.id);
persisted = false;
return promise;
return adapter.destroy(objself.type.name, objself.id).then(function() {
_destroyed();
});
} else {
return adapter.deferred();
destroyed = true;
return Promise.resolve();
}

@@ -684,2 +719,5 @@ }

defineHiddenConstant(this, '_display', _display);
defineHiddenConstant(this, '_getDirtyList', _getDirtyList);
defineHiddenConstant(this, '_persisted', _persisted);
defineHiddenConstant(this, '_destroyed', _destroyed);

@@ -962,7 +1000,9 @@ defineHiddenConstant(this, 'toData', toData);

return this._fetch().then(function(objects) {
var promises = [];
var batch = new Batch(adapter);
objects.forEach(function(object) {
promises.push(object._destroy());
batch.destroy(object);
});
return Promise.all(promises);
return batch.execute();
});

@@ -969,0 +1009,0 @@ };

@@ -7,4 +7,4 @@ require('isomorphic-fetch');

var BATCH_LIMIT = 1000;
function apiToInternalFormat(type, apiObj) {

@@ -82,2 +82,3 @@ var dbObj = {

this.name = 'api';
this.batchLimit = BATCH_LIMIT;
var self = this;

@@ -87,2 +88,14 @@

function responseHandler(response) {
if(response.ok) {
return response.json();
} else {
return response.text().then(function(text) {
var error = new Error("HTTP Error " + response.status + ": " + response.statusText + '\n' + text);
error.body = text;
return Promise.reject(error);
});
}
}
function apiGet(url) {

@@ -96,9 +109,3 @@ return fetch(url, Object.assign({},

}, credentials.apiAuthHeaders())
})).then(function(response) {
if(response.ok) {
return response.json();
} else {
return Promise.reject(new Error("HTTP Error " + response.status + ": " + response.statusText));
}
});
})).then(responseHandler);
}

@@ -116,9 +123,3 @@

body: JSON.stringify(data)
})).then(function(response) {
if(response.ok) {
return response.json();
} else {
return Promise.reject(new Error("HTTP Error " + response.status + ": " + response.statusText));
}
});
})).then(responseHandler);
}

@@ -267,2 +268,7 @@

/**
* Post crud actions.
*
* @param {*} actions - array of actions
*/
function postCrud(actions) {

@@ -291,3 +297,8 @@ // TODO: make this work for mobile credentials as well

return postCrud(actions);
return postCrud(actions).then(function(response) {
var error = response.operations[0].error;
if(error) {
throw error;
}
});

@@ -306,4 +317,59 @@ // TODO: trigger attachment upload

});
return postCrud(actions);
return postCrud(actions).then(function(response) {
var error = response.operations[0].error;
// For idempotency, ignore OBJECT_NOT_FOUND
if(error && error.type != 'OBJECT_NOT_FOUND') {
throw error;
}
});
};
this.applyBatch = function(crud) {
var actions = [];
for(var i = 0; i < crud.length; i++) {
var operation = crud[i];
var action = operation.op;
if(action == 'put') {
actions.push({
method: 'put',
object: dbToApiObject(operation.data)
});
} else if(action == 'patch') {
actions.push({
method: 'patch',
object: dbToApiObject(operation.patch)
});
} else if(action == 'delete') {
actions.push({
method: 'delete',
object: {
type: operation.type,
id: operation.id
}
});
} else {
throw new Error("Unknown action: " + action);
}
}
// 4xx / 5xx errors are passed through
return postCrud(actions).then(function(response) {
if(response.operations.length != crud.length) {
throw new Error('Internal error - invalid results received from server. Expected ' + crud.length + ' results, got ' + response.operations.length);
}
var results = [];
for(var j = 0; j < crud.length; j++) {
var error = response.operations[j].error;
if(crud[j].op == 'delete' && error.type == 'OBJECT_NOT_FOUND') {
// For idempotency, we ignore these.
error = null;
}
var result = {
error: error
};
results.push(result);
}
return results;
});
};
}

@@ -310,0 +376,0 @@

@@ -258,3 +258,2 @@ var IndexedAdapter = require('./IndexedAdapter');

return this.promisedTransaction(function(tx) {
// This default implementation does each operation in a separate transaction.
for(var i = 0; i < crud.length; i++) {

@@ -284,2 +283,34 @@ var operation = crud[i];

/**
* Apply a batch of operations in a single transaction.
*
* The entire batch is either successful or not - we don't return errors for
* individual objects.
*/
WebSQLAdapter.prototype.applyBatch = function(crud) {
this.ensureOpen();
var self = this;
var results = [];
return this.promisedTransaction(function(tx) {
for(var i = 0; i < crud.length; i++) {
var operation = crud[i];
var action = operation.op;
if(action == 'put') {
self.transactionSaveData(tx, operation.data, null);
} else if(action == 'patch') {
self.transactionSaveData(tx, operation.data, operation.patch);
} else if(action == 'delete') {
self.transactionDestroy(tx, operation.type, operation.id);
} else {
throw new Error("Unknown action: " + action);
}
results.push({});
}
}).then(function() {
return self.dataChanged();
}).then(function() {
return results;
});
};
// Persist an object and its relationships.

@@ -286,0 +317,0 @@ // The object and it's relationships MUST be loaded before this is called.

{
"name": "journeyapps",
"version": "0.3.0",
"version": "0.3.1",
"description": "Journey JS library",

@@ -41,3 +41,3 @@ "keywords": [

"eslint": "^0.24.1",
"fetch-mock": "^4.1.1",
"fetch-mock": "^5.9.4",
"grunt": "~0.4.1",

@@ -44,0 +44,0 @@ "grunt-cli": "~0.1.9",

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