Skip to content

Commit

Permalink
fix: handle the loop guard outside the store value (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
wkillerud authored Oct 7, 2024
1 parent 71bb7c2 commit 2644a7d
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 8 deletions.
16 changes: 10 additions & 6 deletions src/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,18 @@ export function map(channel, topic, initialValue) {
/** @type {MapStore<T & StoreValue>} */
const $store = nsMap(initial);

let source = 'app';
/** @type {import('@podium/browser').MessageHandler<T>} */
const listener = (event) => {
$store.set({ ...event.payload, source: 'bus' });
source = 'bus';
$store.set({ ...event.payload });
};
messageBus.subscribe(channel, topic, listener);

$store.listen(({ source, ...rest }) => {
$store.listen((value) => {
// To avoid an infinite loop we fire this only when the source of the change is the app, not the message bus.
if (source !== 'bus') {
messageBus.publish(channel, topic, { ...rest });
messageBus.publish(channel, topic, value);
}
});

Expand Down Expand Up @@ -167,16 +169,18 @@ export function deepMap(channel, topic, initialValue) {
// @ts-expect-error https://github.com/microsoft/TypeScript/issues/34933
const $store = nsDeepMap(initial);

let source = 'app';
/** @type {import('@podium/browser').MessageHandler<T>} */
const listener = (event) => {
$store.set({ ...event.payload, source: 'bus' });
source = 'bus';
$store.set({ ...event.payload });
};
messageBus.subscribe(channel, topic, listener);

$store.listen(({ source, ...rest }) => {
$store.listen((value) => {
// To avoid an infinite loop we fire this only when the source of the change is the app, not the message bus.
if (source !== 'bus') {
messageBus.publish(channel, topic, { ...rest });
messageBus.publish(channel, topic, value);
}
});

Expand Down
50 changes: 48 additions & 2 deletions tests/store.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ test('map returns a MapStore connected to the Podium MessageBus', () => {
const bus = new MessageBus();
bus.publish('foo', 'bar', { message: 'bar' });

assert.deepStrictEqual($foo.value, { message: 'bar', source: 'bus' });
assert.deepStrictEqual($foo.value, { message: 'bar' });
});

test('deepMap returns a DeepMapStore connected to the Podium MessageBus', () => {
Expand Down Expand Up @@ -74,7 +74,6 @@ test('deepMap returns a DeepMapStore connected to the Podium MessageBus', () =>
},
],
skills: [['Carpentry', 'Sanding'], ['Varnishing']],
source: 'bus',
});
});

Expand All @@ -95,3 +94,50 @@ test('initialValue is ignored if a value exists on the message bus', () => {
});
assert.deepStrictEqual($deepMap.value, { user: { displayName: 'foobar' } });
});

test('does not publish a message on the bus if the bus listener was what wrote to the store', () => {
const bus = new MessageBus();

const $atom = atom('atom', 'test', 'Value');
const $map = map('map', 'test', { title: 'Value' });
const $deepMap = deepMap('deepMap', 'test', {
user: { displayName: 'barfoo' },
});

const atomSub = test.mock.fn();
bus.subscribe('atom', 'test', atomSub);

const mapSub = test.mock.fn();
bus.subscribe('map', 'test', mapSub);

const deepMapSub = test.mock.fn();
bus.subscribe('deepMap', 'test', deepMapSub);

bus.publish('atom', 'test', 'Value');
assert.equal($atom.value, 'Value');
assert.equal(
atomSub.mock.callCount(),
1,
'Expected the atom to not republish the same value to the MessageBus',
);

bus.publish('map', 'test', { title: 'Value' });
assert.deepStrictEqual($map.value, { title: 'Value' });
assert.equal(
mapSub.mock.callCount(),
1,
'Expected the map to not republish the same value to the MessageBus',
);

bus.publish('deepMap', 'test', {
user: { displayName: 'barfoo' },
});
assert.deepStrictEqual($deepMap.value, {
user: { displayName: 'barfoo' },
});
assert.equal(
deepMapSub.mock.callCount(),
1,
'Expected the deepMap to not republish the same value to the MessageBus',
);
});

0 comments on commit 2644a7d

Please sign in to comment.