Better repo architecture.
This commit is contained in:
parent
dd1d16f91c
commit
5ba7493613
65
packages/xo-collection/.editorconfig
Normal file
65
packages/xo-collection/.editorconfig
Normal file
@ -0,0 +1,65 @@
|
||||
# http://EditorConfig.org
|
||||
#
|
||||
# Julien Fontanet's configuration
|
||||
# https://gist.github.com/julien-f/8096213
|
||||
|
||||
# Top-most EditorConfig file.
|
||||
root = true
|
||||
|
||||
# Common config.
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespaces = true
|
||||
|
||||
# CoffeeScript
|
||||
#
|
||||
# https://github.com/polarmobile/coffeescript-style-guide/blob/master/README.md
|
||||
[*.{,lit}coffee]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# Markdown
|
||||
[*.{md,mdwn,mdown,markdown}]
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
|
||||
# Package.json
|
||||
#
|
||||
# This indentation style is the one used by npm.
|
||||
[/package.json]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# Jade
|
||||
[*.jade]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# JavaScript
|
||||
#
|
||||
# Two spaces seems to be the standard most common style, at least in
|
||||
# Node.js (http://nodeguide.com/style.html#tabs-vs-spaces).
|
||||
[*.js]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# Less
|
||||
[*.less]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# Sass
|
||||
#
|
||||
# Style used for http://libsass.com
|
||||
[*.s[ac]ss]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
# YAML
|
||||
#
|
||||
# Only spaces are allowed.
|
||||
[*.yaml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
31
packages/xo-collection/.gitignore
vendored
31
packages/xo-collection/.gitignore
vendored
@ -1,28 +1,7 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
/bower_components/
|
||||
/dist/
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
npm-debug.log
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directory
|
||||
# Commenting this out is preferred by some people, see
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
|
||||
node_modules
|
||||
|
||||
# Users Environment Variables
|
||||
.lock-wscript
|
||||
!node_modules/*
|
||||
node_modules/*/
|
||||
|
2
packages/xo-collection/.npmignore
Normal file
2
packages/xo-collection/.npmignore
Normal file
@ -0,0 +1,2 @@
|
||||
*.spec.js
|
||||
*.spec.js.map
|
5
packages/xo-collection/.travis.yml
Normal file
5
packages/xo-collection/.travis.yml
Normal file
@ -0,0 +1,5 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 'iojs'
|
||||
- '0.12'
|
||||
- '0.10'
|
@ -1,2 +1,182 @@
|
||||
# collection
|
||||
A collection class with a batch feature with commit/rollback/replay
|
||||
# collection [](https://travis-ci.org/marsaud/collection)
|
||||
|
||||
> Generic in-memory collection with events
|
||||
|
||||
## Install
|
||||
|
||||
Installation of the [npm package](https://npmjs.org/package/collection):
|
||||
|
||||
```
|
||||
> npm install --save collection
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var Collection = require('collection')
|
||||
```
|
||||
|
||||
### Creation
|
||||
|
||||
```javascript
|
||||
// Creates a new collection.
|
||||
var col = new Collection()
|
||||
```
|
||||
|
||||
### Manipulation
|
||||
|
||||
**Inserting a new entry**
|
||||
|
||||
```javascript
|
||||
col.add('foo', true)
|
||||
```
|
||||
|
||||
**Updating an existing entry**
|
||||
|
||||
```javascript
|
||||
col.update('foo', false)
|
||||
```
|
||||
|
||||
**Inserting or updating an entry**
|
||||
|
||||
```javascript
|
||||
col.set('bar', true)
|
||||
```
|
||||
|
||||
**Notifying an external update**
|
||||
|
||||
> If an entry is an object, it can be updated directly without using
|
||||
> the `set`/`update` methods.
|
||||
>
|
||||
> To make sure the collection stay in sync and the correct events are
|
||||
> sent, the `touch` method can be used to notify the change.
|
||||
|
||||
```javascript
|
||||
var baz = {}
|
||||
|
||||
col.add('baz', baz)
|
||||
|
||||
baz.prop = true
|
||||
col.touch('baz')
|
||||
```
|
||||
|
||||
> Because this is a much used pattern, `touch` returns the entry to
|
||||
> allow its direct modification.
|
||||
|
||||
```javascript
|
||||
col.touch('baz').prop = false
|
||||
```
|
||||
|
||||
**Removing an existing entry**
|
||||
|
||||
```javascript
|
||||
col.unset('bar')
|
||||
```
|
||||
|
||||
**Removing all entries**
|
||||
|
||||
```javascript
|
||||
col.clear()
|
||||
```
|
||||
|
||||
### Query
|
||||
|
||||
**Checking the existence of an entry**
|
||||
|
||||
```javascript
|
||||
var hasBar = col.has('bar')
|
||||
```
|
||||
|
||||
**Getting an existing entry**
|
||||
|
||||
```javascript
|
||||
var foo = col.get('foo')
|
||||
|
||||
// The second parameter can be used to specify a fallback in case the
|
||||
// entry does not exist.
|
||||
var bar = col.get('bar', 6.28)
|
||||
```
|
||||
|
||||
**Getting the number of entries**
|
||||
|
||||
```javascript
|
||||
var size = col.size
|
||||
```
|
||||
|
||||
### Events
|
||||
|
||||
> The events are emitted asynchronously (at the next turn/tick of the
|
||||
> event loop) and are deduplicated which means, for instance, that an
|
||||
> addition followed by an update will result only in a single
|
||||
> addition.
|
||||
|
||||
**New entries**
|
||||
|
||||
```javascript
|
||||
col.on('add', (added) => {
|
||||
forEach(added, (value, key) => {
|
||||
console.log('+ %s: %j', key, value)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
**Updated entries**
|
||||
|
||||
```javascript
|
||||
col.on('update', (updated) => {
|
||||
forEach(updated, (value, key) => {
|
||||
console.log('- %s: %j', key, value)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
**Removed entries**
|
||||
|
||||
```javascript
|
||||
col.on('remove', (removed) => {
|
||||
// For consistency, `removed` is also a map but contrary to `ædded`
|
||||
// and `updated`, the values associated to the keys are not
|
||||
// significant since the entries have already be removed.
|
||||
|
||||
forEach(removed, (value, key) => {
|
||||
console.log('± %s', key)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Installing dependencies
|
||||
|
||||
```
|
||||
> npm install
|
||||
```
|
||||
|
||||
### Compilation
|
||||
|
||||
The sources files are watched and automatically recompiled on changes.
|
||||
|
||||
```
|
||||
> npm run dev
|
||||
```
|
||||
|
||||
### Tests
|
||||
|
||||
```
|
||||
> npm run test-dev
|
||||
```
|
||||
|
||||
## Contributions
|
||||
|
||||
Contributions are *very* welcomed, either on the documentation or on
|
||||
the code.
|
||||
|
||||
You may:
|
||||
|
||||
- report any [issue](https://github.com/marsaud/collection/issues)
|
||||
you've encountered;
|
||||
- fork and create a pull request.
|
||||
|
||||
## License
|
||||
|
||||
ISC © [Vates SAS](http://vates.fr)
|
||||
|
@ -1,24 +1,50 @@
|
||||
{
|
||||
"name": "xo-collection",
|
||||
"private": true,
|
||||
"name": "collection",
|
||||
"version": "0.0.0",
|
||||
"description": "A generice batch collection attempt",
|
||||
"main": "collection.js",
|
||||
"license": "ISC",
|
||||
"description": "Generic in-memory collection with events",
|
||||
"keywords": [],
|
||||
"homepage": "https://github.com/marsaud/collection",
|
||||
"bugs": "https://github.com/marsaud/collection/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/marsaud/collection.git"
|
||||
},
|
||||
"author": {
|
||||
"name": "Fabrice Marsaud",
|
||||
"email": "fabrice.marsaud@vates.fr"
|
||||
},
|
||||
"preferGlobal": false,
|
||||
"main": "dist/",
|
||||
"files": [
|
||||
"dist/"
|
||||
],
|
||||
"dependencies": {
|
||||
"babel-runtime": "^5",
|
||||
"lodash.foreach": "^3.0.2",
|
||||
"make-error": "^0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel": "^4.7.16",
|
||||
"chai": "^2.2.0",
|
||||
"babel": "^5",
|
||||
"chai": "*",
|
||||
"dirty-chai": "^1.2.0",
|
||||
"event-to-promise": "^0.3.2",
|
||||
"leche": "^2.1.1",
|
||||
"mocha": "^2.2.1",
|
||||
"sinon": "^1.14.1"
|
||||
"mocha": "*",
|
||||
"sinon": "^1.14.1",
|
||||
"standard": "*"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --require babel/register *.spec.js"
|
||||
"build": "mkdir --parents dist && babel --optional=runtime --compact=true --source-maps --out-dir=dist/ src/",
|
||||
"dev": "mkdir --parents dist && babel --watch --optional=runtime --compact=true --source-maps --out-dir=dist/ src/",
|
||||
"prepublish": "npm run build",
|
||||
"test": "standard && npm run build && mocha 'dist/**/*.spec.js'",
|
||||
"test-dev": "standard && mocha --watch --reporter=min 'dist/**/*.spec.js'"
|
||||
},
|
||||
"author": "Fabrice Marsaud <fabrice.marsaud@vates.fr>",
|
||||
"license": "aGPLv3"
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"dist/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import events from 'events'
|
||||
import makeError from 'make-error'
|
||||
|
||||
export const DuplicateEntry = makeError('DuplicateEntry')
|
||||
export const BufferAlreadyFlushed = makeError('BufferAlreadyFlushed')
|
||||
export const DuplicateEntry = makeError('DuplicateEntry')
|
||||
export const IllegalAdd = makeError('IllegalAdd')
|
||||
export const NoSuchEntry = makeError('NoSuchEntry')
|
||||
export const IllegalTouch = makeError('IllegalTouch')
|
||||
export const NoSuchEntry = makeError('NoSuchEntry')
|
||||
|
||||
export default class Collection extends events.EventEmitter {
|
||||
constructor () {
|
@ -1,12 +1,11 @@
|
||||
/* eslint-env mocha */
|
||||
|
||||
import Collection, {DuplicateEntry, NoSuchEntry} from './collection'
|
||||
import Collection, {DuplicateEntry, NoSuchEntry} from './index'
|
||||
|
||||
import eventToPromise from 'event-to-promise'
|
||||
import sinon from 'sinon'
|
||||
|
||||
import chai from 'chai'
|
||||
const expect = chai.expect
|
||||
import chai, {expect} from 'chai'
|
||||
import dirtyChai from 'dirty-chai'
|
||||
chai.use(dirtyChai)
|
||||
|
@ -1,81 +0,0 @@
|
||||
import Collection from './collection';
|
||||
|
||||
let col = new Collection.Collection();
|
||||
|
||||
col.add('foo', 1);
|
||||
|
||||
// An object with id property
|
||||
|
||||
// ====================
|
||||
// Jouer sur le passage par référence, et la convention d'objets avec une prop ID
|
||||
|
||||
let obj = {id: 'bar', content: 2};
|
||||
col.add(obj);
|
||||
console.log(obj.get('bar'));
|
||||
// > {id: 'bar', content: 2}
|
||||
|
||||
col.bufferChanges(true);
|
||||
col.update('bar').content = 4;
|
||||
// update accesses obj at bar key and marks bar as updated. No event emitted.
|
||||
|
||||
col.get('bar').content = 5;
|
||||
obj.content = 6;
|
||||
// bar is already marked as updated, so ...
|
||||
|
||||
col.flush();
|
||||
// ...Emits an update as bar has been "updated to 6"
|
||||
|
||||
col.bufferChanges(true);
|
||||
col.update(obj).content = 7; // Short writing without knowing ID
|
||||
// WARNING, do not change ID after adding ...
|
||||
|
||||
col.bufferChanges(false);
|
||||
col.flush();
|
||||
// No event emitted ... exception thrown ?...
|
||||
col.bufferChanges(true);
|
||||
col.update(obj);
|
||||
col.flush();
|
||||
// Emits an update event as bar has been "updated to 7"
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Special cases :
|
||||
let foo = {id: 'foo'};
|
||||
let bar = {id: 'bar'};
|
||||
col.add(foo);
|
||||
|
||||
try {
|
||||
col.update(foo, bar);
|
||||
} catch(e) {
|
||||
// Throws an instant exception on ID violation
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
try {
|
||||
col.udpate('foo', bar);
|
||||
} catch(e) {
|
||||
// Same
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
try {
|
||||
col.update(foo).id = 'bar';
|
||||
} catch (e) {
|
||||
// Throws an exception at Event emission (key !== content.id)
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
col.bufferChanges(true);
|
||||
col.remove(foo);
|
||||
col.add(foo);
|
||||
col.bufferChanges(false);
|
||||
// Silent...(No events)
|
||||
|
||||
col.bufferChanges(true);
|
||||
col.update(foo).id = 'bar';
|
||||
// Nothing happens
|
||||
try {
|
||||
col.flush();
|
||||
} catch (e) {
|
||||
// Throws
|
||||
console.log(e);
|
||||
}
|
Loading…
Reference in New Issue
Block a user