diff --git a/src/common/SharedStateCollection.js b/src/common/SharedStateCollection.js index 2240f0cb..e55c647a 100644 --- a/src/common/SharedStateCollection.js +++ b/src/common/SharedStateCollection.js @@ -222,8 +222,19 @@ class SharedStateCollection { this.#onUpdateCallbacks.add(callback); if (executeListener === true) { + // filter `event: true` parameters from currentValues, this is missleading + // as we are in the context of a callback, not from an active read + const schema = this.getSchema(); + this.#states.forEach(state => { const currentValues = state.getValues(); + + for (let name in schema) { + if (schema[name].event === true) { + delete currentValues[name]; + } + } + const oldValues = {}; const context = null; diff --git a/tests/states/StateCollection.spec.js b/tests/states/StateCollection.spec.js index f596cf1a..63719d35 100644 --- a/tests/states/StateCollection.spec.js +++ b/tests/states/StateCollection.spec.js @@ -346,6 +346,29 @@ describe(`# SharedStateCollection`, () => { await state.delete(); await delay(50); }); + + it('should not propagate event parameters on first call if `executeListener=true`', async () => { + server.stateManager.registerSchema('with-event', { + bool: { type: 'boolean', event: true, }, + int: { type: 'integer', default: 20, }, + }); + const state = await server.stateManager.create('with-event'); + const collection = await server.stateManager.getCollection('with-event'); + + let onUpdateCalled = false; + collection.onUpdate((state, newValues, oldValues, context) => { + onUpdateCalled = true; + assert.deepEqual(newValues, { int: 20 }); + assert.deepEqual(oldValues, {}); + assert.deepEqual(context, null); + }, true); + + await delay(10); + + assert.equal(onUpdateCalled, true); + server.stateManager.deleteSchema('with-event'); + }); + }); describe(`## onAttach(callback)`, () => {