From 7024b5ec1b135394477aa565bb9b8b8f31860c47 Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Sat, 18 Apr 2015 21:58:17 +0200 Subject: [PATCH] Reorganization of Collection code. --- packages/xo-collection/src/collection.js | 290 ++++++++++++----------- 1 file changed, 156 insertions(+), 134 deletions(-) diff --git a/packages/xo-collection/src/collection.js b/packages/xo-collection/src/collection.js index 19eda32d4..7aff7bbb9 100644 --- a/packages/xo-collection/src/collection.js +++ b/packages/xo-collection/src/collection.js @@ -57,6 +57,121 @@ export default class Collection extends EventEmitter { this._size = 0 } + getId (item) { + return item && item.id + } + + // ----------------------------------------------------------------- + // Properties + // ----------------------------------------------------------------- + + get all () { + return this._items + } + + get size () { + return this._size + } + + // ----------------------------------------------------------------- + // Manipulation + // ----------------------------------------------------------------- + + add (keyOrObjectWithId, valueIfKey = undefined) { + const [key, value] = this._resolveItem(keyOrObjectWithId, valueIfKey) + this._assertHasNot(key) + + this._items[key] = value + this._size++ + this._touch('add', key) + } + + clear () { + forEach(this._items, (_, key) => { + delete this._items[key] + this._size-- + this._touch('remove', key) + }) + } + + remove (keyOrObjectWithId) { + const [key] = this._resolveItem(keyOrObjectWithId) + this._assertHas(key) + + delete this._items[key] + this._size-- + this._touch('remove', key) + } + + set (keyOrObjectWithId, valueIfKey = undefined) { + const [key, value] = this._resolveItem(keyOrObjectWithId, valueIfKey) + + const action = this.has(key) ? 'update' : 'add' + this._items[key] = value + if (action === 'add') { + this._size++ + } + this._touch(action, key) + } + + touch (keyOrObjectWithId) { + const [key] = this._resolveItem(keyOrObjectWithId) + this._assertHas(key) + const value = this.get(key) + if (typeof value !== 'object' || value === null) { + throw new IllegalTouch(value) + } + + this._touch('update', key) + + return this.get(key) + } + + update (keyOrObjectWithId, valueIfKey = undefined) { + const [key, value] = this._resolveItem(keyOrObjectWithId, valueIfKey) + this._assertHas(key) + + this._items[key] = value + this._touch('update', key) + } + + // ----------------------------------------------------------------- + // Query + // ----------------------------------------------------------------- + + get (key, defaultValue) { + if (this.has(key)) { + return this._items[key] + } + + if (arguments.length > 1) { + return defaultValue + } + + // Throws a NoSuchItem. + this._assertHas(key) + } + + has (key) { + return Object.hasOwnProperty.call(this._items, key) + } + + // ----------------------------------------------------------------- + // Iteration + // ----------------------------------------------------------------- + + * [Symbol.iterator] () { + const {_items: items} = this + + for (let key in items) { + yield items[key] + } + } + + // ----------------------------------------------------------------- + // Events buffering + // ----------------------------------------------------------------- + bufferEvents () { ++this._buffering @@ -93,6 +208,47 @@ export default class Collection extends EventEmitter { } } + // ================================================================= + + _assertHas (key) { + if (!this.has(key)) { + throw new NoSuchItem(key) + } + } + + _assertHasNot (key) { + if (this.has(key)) { + throw new DuplicateItem(key) + } + } + + _assertValidKey (key) { + if (!this._isValidKey(key)) { + throw new InvalidKey(key) + } + } + + _isValidKey (key) { + return typeof key === 'number' || typeof key === 'string' + } + + _resolveItem (keyOrObjectWithId, valueIfKey = undefined) { + if (valueIfKey !== undefined) { + this._assertValidKey(keyOrObjectWithId) + + return [keyOrObjectWithId, valueIfKey] + } + + if (this._isValidKey(keyOrObjectWithId)) { + return [keyOrObjectWithId] + } + + const key = this.getId(keyOrObjectWithId) + this._assertValidKey(key) + + return [key, keyOrObjectWithId] + } + _touch (action, key) { if (this._buffering === 0) { const flush = this.bufferEvents() @@ -114,138 +270,4 @@ export default class Collection extends EventEmitter { } } } - - getId (item) { - return item && item.id - } - - has (key) { - return Object.hasOwnProperty.call(this._items, key) - } - - _isValidKey (key) { - return typeof key === 'number' || typeof key === 'string' - } - - _assertValidKey (key) { - if (!this._isValidKey(key)) { - throw new InvalidKey(key) - } - } - - _resolveItem (keyOrObjectWithId, valueIfKey = undefined) { - if (valueIfKey !== undefined) { - this._assertValidKey(keyOrObjectWithId) - - return [keyOrObjectWithId, valueIfKey] - } - - if (this._isValidKey(keyOrObjectWithId)) { - return [keyOrObjectWithId] - } - - const key = this.getId(keyOrObjectWithId) - this._assertValidKey(key) - - return [key, keyOrObjectWithId] - } - - _assertHas (key) { - if (!this.has(key)) { - throw new NoSuchItem(key) - } - } - - _assertHasNot (key) { - if (this.has(key)) { - throw new DuplicateItem(key) - } - } - - add (keyOrObjectWithId, valueIfKey = undefined) { - const [key, value] = this._resolveItem(keyOrObjectWithId, valueIfKey) - this._assertHasNot(key) - - this._items[key] = value - this._size++ - this._touch('add', key) - } - - set (keyOrObjectWithId, valueIfKey = undefined) { - const [key, value] = this._resolveItem(keyOrObjectWithId, valueIfKey) - - const action = this.has(key) ? 'update' : 'add' - this._items[key] = value - if (action === 'add') { - this._size++ - } - this._touch(action, key) - } - - get (key, defaultValue) { - if (this.has(key)) { - return this._items[key] - } - - if (arguments.length > 1) { - return defaultValue - } - - // Throws a NoSuchItem. - this._assertHas(key) - } - - update (keyOrObjectWithId, valueIfKey = undefined) { - const [key, value] = this._resolveItem(keyOrObjectWithId, valueIfKey) - this._assertHas(key) - - this._items[key] = value - this._touch('update', key) - } - - touch (keyOrObjectWithId) { - const [key] = this._resolveItem(keyOrObjectWithId) - this._assertHas(key) - const value = this.get(key) - if (typeof value !== 'object' || value === null) { - throw new IllegalTouch(value) - } - - this._touch('update', key) - - return this.get(key) - } - - remove (keyOrObjectWithId) { - const [key] = this._resolveItem(keyOrObjectWithId) - this._assertHas(key) - - delete this._items[key] - this._size-- - this._touch('remove', key) - } - - clear () { - forEach(this._items, (_, key) => { - delete this._items[key] - this._size-- - this._touch('remove', key) - }) - } - - get size () { - return this._size - } - - get all () { - return this._items - } - - * [Symbol.iterator] () { - const {_items: items} = this - - for (let key in items) { - yield items[key] - } - } }