diff --git a/index.js b/index.js index 07cef7e..a6ef607 100644 --- a/index.js +++ b/index.js @@ -50,7 +50,8 @@ function Store (dbName, options) { var storeApi = db.hoodieApi({emitter: emitter}) var state = { - objectTypeById: {} + objectTypeById: {}, + scopedApis: {} } // possible race condition... diff --git a/lib/scoped/index.js b/lib/scoped/index.js index 36d8449..3cc8595 100644 --- a/lib/scoped/index.js +++ b/lib/scoped/index.js @@ -7,6 +7,10 @@ function scoped (state, api, type) { throw new TypeError('type must be set for scoped stores') } + if (state.scopedApis[type]) { + return state.scopedApis[type] + } + var emitter = new EventEmitter() var scopedApi = { @@ -37,6 +41,7 @@ function scoped (state, api, type) { } api.on('change', require('../utils/handle-type-change').bind(null, state, emitter, type)) + state.scopedApis[type] = scopedApi return scopedApi } diff --git a/lib/utils/handle-type-change.js b/lib/utils/handle-type-change.js index 8ddd3ba..a2719d1 100644 --- a/lib/utils/handle-type-change.js +++ b/lib/utils/handle-type-change.js @@ -11,10 +11,16 @@ function handleTypeChange (state, emitter, type, eventName, object) { return } - if (wasScopeType && !isScopeType) { + if (objectWasDeleted(object) || objectMovedScope(wasScopeType, isScopeType)) { object = clone(object) object.type = type scopedEventName = 'remove' + + if (objectWasDeleted(object)) { + delete state.objectTypeById[object.id] + } else { + state.objectTypeById[object.id] = type + } } else if (!wasScopeType && isScopeType) { state.objectTypeById[object.id] = type scopedEventName = 'add' @@ -25,3 +31,11 @@ function handleTypeChange (state, emitter, type, eventName, object) { emitter.emit(type + ':' + scopedEventName, object) emitter.emit(type + ':change', scopedEventName, object) } + +function objectWasDeleted (object) { + return object._deleted +} + +function objectMovedScope (wasScopeType, isScopeType) { + return wasScopeType && !isScopeType +} diff --git a/tests/specs/scoped.js b/tests/specs/scoped.js index 92d7775..46b46f5 100644 --- a/tests/specs/scoped.js +++ b/tests/specs/scoped.js @@ -910,8 +910,7 @@ test('scoped store methods with type conflict', function (t) { .catch(verifyError.bind(null, 'remove')) }) -// prepared for https://github.com/hoodiehq/camp/issues/30 -test.skip('scoped store.add should invoke store.on("add") and store.on("change") with event "add"', function (t) { +test('scoped store.add should invoke store.on("add") and store.on("change") with event "add"', function (t) { t.plan(3) var store = new Store('test-db-scoped-on', merge({remote: 'test-db-scoped-on'}, options)) var onEvents = [] @@ -937,11 +936,15 @@ test.skip('scoped store.add should invoke store.on("add") and store.on("change") t.is(onEvents[0], 'add', '"add" should trigger') t.is(onEvents[1], 'change add', '"change add" should trigger') }) + + .then(function () { + store.reset() + }) + .catch(t.fail) }) -// prepared for https://github.com/hoodiehq/camp/issues/30 -test.skip('scoped store.removeAll should invoke store.on("remove")', function (t) { +test('scoped store.removeAll should invoke store.on("remove")', function (t) { t.plan(2) var store = new Store('test-db-scoped-on', merge({remote: 'test-db-scoped-on'}, options)) var onEvents = [] @@ -966,11 +969,15 @@ test.skip('scoped store.removeAll should invoke store.on("remove")', function (t .then(function () { return store('test').removeAll() + + .then(function () { + t.is(onEvents.length, 4, 'There should be four Elements in the onEvents array') + t.is(onEvents[2], 'remove', '"remove" should trigger') + }) }) .then(function () { - t.is(onEvents.length, 4, 'There should be two Elements in the onEvents array') - t.is(onEvents[3], 'remove', '"remove" should trigger') + store.reset() }) .catch(t.fail)