New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

dojo-dstore

Package Overview
Dependencies
Maintainers
3
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dojo-dstore - npm Package Compare versions

Comparing version 1.2.0 to 1.2.1

136

docs/Collection.md

@@ -9,5 +9,7 @@ # Collection

store.filter({priority: 'high'}).sort('dueDate').forEach(function (object) {
// called for each item in the final result set
});
```javascript
store.filter({priority: 'high'}).sort('dueDate').forEach(function (object) {
// called for each item in the final result set
});
```

@@ -20,11 +22,17 @@ In addition, the `track()` method may be used to track store changes, ensuring notifications include index information about object changes, and keeping result sets up-to-date after a query. The `fetch()` method is an alternate way to retrieve results, providing a promise to an array for accessing query results. The sections below describes each of these methods and how to use them.

var filter = new store.Filter();
```javascript
var filter = new store.Filter();
```
We now have a `filter` object, that represents a filter, without any operators applied yet. We can create new filter objects by calling the operator methods on the filter object. The operator methods will return new filter objects that hold the operator condition. For example, to specify that we want to retrieve objects with a `priority` property with a value of `"high"`, and `stars` property with a value greater than `5`, we could write:
var highPriorityFiveStarFilter = filter.eq('priority', 'high').gt('stars', 5);
```javascript
var highPriorityFiveStarFilter = filter.eq('priority', 'high').gt('stars', 5);
```
This filter object can then be passed as the argument to the `filter()` method on a collection/store:
var highPriorityFiveStarCollection = store.filter(highPriorityFiveStarFilter);
```javascript
var highPriorityFiveStarCollection = store.filter(highPriorityFiveStarFilter);
```

@@ -50,5 +58,9 @@ The following methods are available on the filter objects. First are the property filtering methods, which each take a property name as the first argument, and a property value to compare for the second argument:

var tasksOfHighPriorityProjects = taskStore.filter(
new Filter().in('projectId',
projectStore.filter({priority: 'high'}).select('id')));
```javascript
var tasksOfHighPriorityProjects = taskStore.filter(
new Filter().in('projectId',
projectStore.filter({ priority: 'high' }).select('id')
)
);
```

@@ -61,2 +73,18 @@ ### Implementations

`dstore/SimpleQuery` provides a simple shorthand for nested property queries - a side-effect of this is that property names that contain the period character are not supported. Example nested property query:
```javascript
store.filter({ 'name.last': 'Smith' })
```
This would match the object:
```javascript
{
name: {
first: 'John',
last: 'Smith'
}
}
```
For the `dstore/Request`/`dstore/Rest` stores, you can define alternate serializations of filters to URL queries for existing or new methods by overriding the `_renderFilterParams`. This method is called with a filter object (and by default is recursively called by combinatorial operators), and should return a string serialization of the filter, that will be inserted into the query string of the URL sent to the server.

@@ -92,13 +120,22 @@

This also sorts the collection, but can be called to define multiple sort orders by priority. Each argument is an object with a `property` property and an optional `descending` property (defaults to ascending, if not set), to define the order. For example: `collection.sort([{property:'lastName'}, {property: 'firstName'}])` would result in a new collection sorted by lastName, with firstName used to sort identical lastName values.
This also sorts the collection, but can be called to define multiple sort orders by priority. Each argument is an object with a `property` property and an optional `descending` property (defaults to ascending, if not set), to define the order. For example:
```javascript
collection.sort([
{ property: 'lastName' },
{ property: 'firstName' }
])
```
would result in a new collection sorted by `lastName`, with `firstName` used to sort identical `lastName` values.
#### select([property, ...])
#### `select([property, ...])`
This selects specific properties that should be included in the returned objects.
#### select(property)
#### `select(property)`
This will indicate that the return results will consist of the values of the given property of the queried objects. For example, this would return a collection of name values, pulled from the original collection of objects:
collection.select('name');
```javascript
collection.select('name');
```

@@ -130,3 +167,3 @@ #### `forEach(callback, thisObject)`

If detecting when an item is removed from a collection due to an update is desired, set `filterEvents` to `false` and use the `matchesFilter(item)` method to test if each item updated is currently in the collection.
If detecting when an item is removed from a collection due to an update is desired, set `filterEvents` to `false` and use the `matchesFilter(item)` method to test if each item updated is currently in the collection.

@@ -139,29 +176,41 @@ There is also a corresponding `emit(type, event)` method (from the [Store interface](Store.md#method-summary)) that can be used to emit events when objects have changed.

var TrackableMemory = declare([Memory, Trackable]);
```javascript
var TrackableMemory = declare([Memory, Trackable]);
```
Trackable requires client side querying functionality. Client side querying functionality is available in `dstore/SimpleQuery` (and inherited by `dstore/Memory`). If you are using a `Request`, `Rest`, or other server side store, you will need to implement client-side query functionality (by implemented querier methods), or mixin `SimpleQuery`:
Trackable requires client side querying functionality. Client side querying functionality is available in `dstore/SimpleQuery` (and inherited by `dstore/Memory`). If you are using a `Request`, `Rest`, or other server side store, you will need to implement client-side query functionality (by implementing querier methods), or mixin `SimpleQuery`:
var TrackableRest = declare([Rest, SimpleQuery, Trackable]);
```javascript
var TrackableRest = declare([Rest, SimpleQuery, Trackable]);
```
Once we have created a new instance from this store, we can track a collection, which could be the top level store itself, or a downstream filtered or sorted collection:
var store = new TrackableMemory({data: ...});
var filteredSorted = store.filter({inStock: true}).sort('price');
var tracked = filteredSorted.track();
```javascript
var store = new TrackableMemory({ data: [...] });
var filteredSorted = store.filter({ inStock: true }).sort('price');
var tracked = filteredSorted.track();
```
Once we have a tracked collection, we can listen for notifications:
tracked.on('add, update, delete', function(event){
var newIndex = event.index;
var oldIndex = event.previousIndex;
var object = event.target;
});
```javascript
tracked.on('add, update, delete', function (event) {
var newIndex = event.index;
var oldIndex = event.previousIndex;
var object = event.target;
});
```
Trackable requires fetched data to determine the position of modified objects and can work with either full or partial data. We can do a `fetch()` or `forEach()` to access all the items in the filtered collection:
tracked.fetch();
```javascript
tracked.fetch();
```
Or we can do a `fetchRange()` to make individual range requests for items in the collection:
tracked.fetchRange(0, 10);
```javascript
tracked.fetchRange(0, 10);
```

@@ -182,18 +231,21 @@ Trackable will keep track of each page of data, and send out notifications based on the data it has available, along with index information, indicating the new and old position of the object that was modified. Regardless of whether full or partial data is fetched, tracked events and the indices they report are relative to the entire collection, not relative to individual fetched ranges. Tracked events also include a `totalLength` property indicating the total length of the collection.

declare([Memory], {
getChildren: new QueryMethod({
type: 'children',
querierFactory: function (parent) {
var parentId = this.getIdentity(parent);
```javascript
declare([Memory], {
getChildren: new QueryMethod({
type: 'children',
querierFactory: function (parent) {
var parentId = this.getIdentity(parent);
return function (data) {
// note: in this case, the input data is ignored as this querier
// returns an object's array of children instead
return function (data) {
// note: in this case, the input data is ignored as this querier
// returns an object's array of children instead
// return the children of the parent
// or an empty array if the parent no longer exists
var parent = this.getSync(parentId);
return parent ? parent.children : [];
};
}
})
// return the children of the parent
// or an empty array if the parent no longer exists
var parent = this.getSync(parentId);
return parent ? parent.children : [];
};
}
})
});
```

@@ -22,16 +22,22 @@ # Included Stores

// create the class based on the Memory store with added functionality
var TrackedTreeMemoryStore = declare([Memory, Trackable, Tree]);
// now create an instance
var myStore = new TrackedTreeMemoryStore({data: [...]});
```javascript
// create the class based on the Memory store with added functionality
var TrackedTreeMemoryStore = declare([Memory, Trackable, Tree]);
// now create an instance
var myStore = new TrackedTreeMemoryStore({ data: [...] });
```
The store mixins can only be used as mixins, but stores can be combined with other stores as well. For example, if we wanted to add the Rest functionality to the RequestMemory store (so the entire store data was retrieved from the server on construction, but data changes are sent to the server), we could write:
var RestMemoryStore = declare([Rest, RequestMemory]);
// now create an instance
var myStore = new RestMemoryStore({target: '/data-source/'});
```javascript
var RestMemoryStore = declare([Rest, RequestMemory]);
// now create an instance
var myStore = new RestMemoryStore({ target: '/data-source/' });
```
Another common case is needing to add tracking to the `dstore/Rest` store, which requires client side querying, which be provided by `dstore/SimpleQuery`:
Another common case is needing to add tracking to the `dstore/Rest` store, which requires client side querying, which can be provided by `dstore/SimpleQuery`:
```javascript
var TrackedRestStore = declare([Rest, SimpleQuery, Trackable]);
```

@@ -44,9 +50,11 @@ ## Memory

myStore = new Memory({
data: [{
id: 1,
aProperty: ...,
...
}]
});
```javascript
myStore = new Memory({
data: [{
id: 1,
aProperty: ...,
...
}]
});
```

@@ -76,2 +84,18 @@ The array supplied as the `data` property will not be copied, it will be used as-is as the store's data. It can be changed at run-time with the `setData` method.

### Server considerations for a `Request/Rest` store
The response should be in JSON format. It should include the data and a number indicating the total number of items:
* **data**: the response can either be a JSON array containing the items or a JSON object with an `items` property that is an array containing the items
* **total**: if the response is an array then the total should be specified in the `Content-Range` header, e.g.:
* `Content-Range: items 0-24/500`
* If the response is an object then the total should be specified on the `total` property of the object, e.g.:
```
{
"total": 500,
"items": [ /* ...items */ ]
}
```
## Rest

@@ -83,8 +107,12 @@

myStore = new Rest({
target: '/PathToData/'
});
```javascript
myStore = new Rest({
target: '/PathToData/'
});
```
All modification or retrieval methods (except `getIdentity()`) on `Request` and `Rest` execute asynchronously, returning a promise.
The server must respond to GET requests for an item by ID with an object representing the item (not an array).
## Store

@@ -120,32 +148,36 @@

var dbConfig = {
version: 5,
stores: {
posts: {
name: 10,
id: {
autoIncrement: true,
preference: 100
},
tags: {
multiEntry: true,
preference: 5
},
content: {
indexed: false
}
```javascript
var dbConfig = {
version: 5,
stores: {
posts: {
name: 10,
id: {
autoIncrement: true,
preference: 100
},
commments: {
author: {},
content: {
indexed: false
}
tags: {
multiEntry: true,
preference: 5
},
content: {
indexed: false
}
},
commments: {
author: {},
content: {
indexed: false
}
}
};
}
};
```
In addition, each store should define a `storeName` property to identify which database store corresponds to the store instance. For example:
var postsStore = new LocalDB({dbConfig: dbConfig, storeName: 'posts'});
var commentsStore = new LocalDB({dbConfig: dbConfig, storeName: 'comments'});
```javascript
var postsStore = new LocalDB({ dbConfig: dbConfig, storeName: 'posts' });
var commentsStore = new LocalDB({ dbConfig: dbConfig, storeName: 'comments' });
```

@@ -158,5 +190,7 @@ Once created, these stores can be used like any other store.

var cachedStore = Cache.create(existingStore, {
cachingStore: new Memory()
});
```javascript
var cachedStore = Cache.create(existingStore, {
cachingStore: new Memory()
});
```

@@ -170,3 +204,3 @@ This store has the following properties and methods:

`allLoaded` | This is a flag indicating that the given collection/store has its data loaded. This can be useful if you want to provide a caching store prepopulated with data for a given collection. If you are setting this to true, make sure you set `isValidFetchCache` to true as well to indicate that the data is available for fetching.
`canCacheQuery(method, args)' | This can be a boolean or a method that will indicate if a collection can be cached (if it should have `isValidFetchCache` set to true), based on the query method and arguments used to derive the collection.
`canCacheQuery(method, args)` | This can be a boolean or a method that will indicate if a collection can be cached (if it should have `isValidFetchCache` set to true), based on the query method and arguments used to derive the collection.
`isLoaded(object)` | This can be defined to indicate if a given object in a query can be cached (by default, objects are cached).

@@ -194,19 +228,21 @@

dstore also includes support for using RQL as the query language for filtering. This can be enabled by mixin `dstore/extensions/RqlQuery` into your collection type:
dstore also includes support for using RQL as the query language for filtering. This can be enabled by mixing `dstore/extensions/RqlQuery` into your collection type:
require([
'dojo/_base/declare',
'dstore/Memory',
'dstore/extensions/RqlQuery'
], function (declare, Memory, RqlQuery) {
var RqlStore = declare([ Memory, RqlQuery ]);
var rqlStore = new RqlStore({
...
});
```javascript
require([
'dojo/_base/declare',
'dstore/Memory',
'dstore/extensions/RqlQuery'
], function (declare, Memory, RqlQuery) {
var RqlStore = declare([ Memory, RqlQuery ]);
var rqlStore = new RqlStore({
...
});
rqlStore.filter('price<10|rating>3').forEach(function (product) {
// return each product that has a price less than 10 or a rating greater than 3
});
}};
rqlStore.filter('price<10|rating>3').forEach(function (product) {
// return each product that has a price less than 10 or a rating greater than 3
});
}};
```
Make sure you have installed/included the [rql](https://github.com/persvr/rql) package if you are using the RQL query engine.

@@ -41,4 +41,6 @@ define(['dojo/_base/declare'], function (declare) {

// returned filter is the same as the single argument
filter.type = argsArray[0].type;
filter.args = argsArray[0].args.slice();
if (argsArray[0].type) {
filter.type = argsArray[0].type;
filter.args = argsArray[0].args.slice();
}
}

@@ -92,2 +94,2 @@ return filter;

return Filter;
});
});

@@ -99,2 +99,3 @@ define([

var total;
var sortOptionIndex;

@@ -106,3 +107,4 @@ // Apply sorting

var sortOptions;
while ((sortOptions = sort.pop())) {
for (sortOptionIndex = sort.length - 1; sortOptionIndex >= 0; sortOptionIndex--) {
sortOptions = sort[sortOptionIndex];
results = results.sort(sortOptions.attribute, sortOptions.descending);

@@ -109,0 +111,0 @@ }

@@ -1,35 +0,47 @@

var miniExcludes = {
// jshint unused: false
var profile = (function () {
var miniExcludes = {
'dstore/README.md': 1,
'dstore/package': 1
},
isTestRe = /\/test\//;
};
var amdRegex = /\.js$/;
var isRqlRegex = /RqlQuery\.js/;
var isTestRegex = /\/tests\//;
var miniExcludeRegex = /\/(?:tests|demos|docs)\//;
var packages = {};
var packages = {};
try {
// retrieve the set of packages for determining which modules to include
require(['util/build/buildControl'], function (buildControl) {
packages = buildControl.packages;
});
} catch (error) {
console.error('Unable to retrieve packages for determining optional package support in dstore');
}
var profile = {
resourceTags: {
test: function (filename, mid) {
return isTestRe.test(filename);
},
try {
// retrieve the set of packages for determining which modules to include
require([ 'util/build/buildControl' ], function (buildControl) {
packages = buildControl.packages;
});
}
catch (error) {
console.error('Unable to retrieve packages for determining optional package support in dstore');
}
miniExclude: function (filename, mid) {
return /\/(?:tests|demos|docs)\//.test(filename) || mid in miniExcludes;
},
return {
resourceTags: {
test: function (filename) {
return isTestRegex.test(filename);
},
amd: function (filename, mid) {
return /\.js$/.test(filename);
miniExclude: function (filename, mid) {
return miniExcludeRegex.test(filename) || mid in miniExcludes;
},
amd: function (filename) {
return amdRegex.test(filename);
},
copyOnly: function (filename) {
// conditionally omit modules dependent on rql packages
return isTestRegex.test(filename) || (!packages.rql && isRqlRegex.test(filename));
}
},
copyOnly: function (filename, mid) {
// conditionally omit modules dependent on rql packages
return (!packages['rql'] && /RqlQuery\.js/.test(filename));
}
}
};
trees: [
[ '.', '.', /(?:\/\.)|(?:~$)|(?:(?:html-report|node_modules)\/)/ ]
]
};
})();
{
"name": "dojo-dstore",
"author": "Kris Zyp",
"version": "1.2.0",
"version": "1.2.1",
"description": "A data collection infrastructure",

@@ -12,2 +12,3 @@ "license": "BSD-3-Clause",

"dependencies": {
"@types/dojo": "^1.9.0",
"dojo": "^1.9.0"

@@ -23,3 +24,4 @@ },

"main": "./Store",
"types": "./typings/dstore.d.ts",
"dojoBuild": "package.js"
}

@@ -184,38 +184,47 @@ define([

_createSortQuerier: function (sorted) {
_createSortQuerier: function (sortOptions) {
var queryAccessors = this.queryAccessors;
return function (data) {
data = data.slice();
data.sort(typeof sorted == 'function' ? sorted : function (a, b) {
for (var i = 0; i < sorted.length; i++) {
var comparison;
var sorter = sorted[i];
if (typeof sorter == 'function') {
comparison = sorter(a, b);
} else {
var getProperty = sorter.get || (sorter.get = makeGetter(sorter.property, queryAccessors));
var descending = sorter.descending;
var aValue = getProperty(a);
var bValue = getProperty(b);
aValue != null && (aValue = aValue.valueOf());
bValue != null && (bValue = bValue.valueOf());
if (aValue === bValue) {
comparison = 0;
if (typeof sortOptions === 'function') {
data.sort(sortOptions);
}
else if (sortOptions && sortOptions.length) {
data.sort(function (a, b) {
for (var i = 0; i < sortOptions.length; i++) {
var comparison;
var sorter = sortOptions[i];
if (typeof sorter == 'function') {
comparison = sorter(a, b);
} else {
var getProperty = sorter.get || (sorter.get = makeGetter(sorter.property, queryAccessors));
var descending = sorter.descending;
var aValue = getProperty(a);
var bValue = getProperty(b);
aValue != null && (aValue = aValue.valueOf());
bValue != null && (bValue = bValue.valueOf());
if (aValue === bValue) {
comparison = 0;
}
else {
// Prioritize undefined > null > defined
var isALessThanB = typeof bValue === 'undefined' ||
bValue === null && typeof aValue !== 'undefined' ||
aValue != null && aValue < bValue;
comparison = Boolean(descending) === isALessThanB ? 1 : -1;
}
}
else {
// Prioritize undefined > null > defined
var isALessThanB = typeof bValue === 'undefined' ||
bValue === null && typeof aValue !== 'undefined' ||
aValue != null && aValue < bValue;
comparison = Boolean(descending) === isALessThanB ? 1 : -1;
if (comparison !== 0) {
return comparison;
}
}
if (comparison !== 0) {
return comparison;
}
}
return 0;
});
return 0;
});
}
return data;

@@ -222,0 +231,0 @@ };

@@ -161,3 +161,7 @@ define([

return this.storage.emit(type, event);
} finally {
}
catch (error) {
console.error(error);
}
finally {
// Return the initial value of event.cancelable because a listener error makes it impossible

@@ -164,0 +168,0 @@ // to know whether the event was actually canceled

@@ -1,2 +0,2 @@

/// <reference path="../dojo/dojo.d.ts" />
/// <reference types="dojo" />

@@ -301,2 +301,3 @@ declare module dstore {

isAvailableInCache(): void;
refresh(target?: string): dstore.FetchPromise<T>;
sort(property: string | { (a: T, b: T): number; }, descending?: boolean): RequestMemory<T>;

@@ -303,0 +304,0 @@ track(): RequestMemory<T>;

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