Skip to content

Commit

Permalink
feat: added + and # wildcard support (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgeOnder authored Apr 20, 2024
1 parent fd24cb1 commit f8bab09
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/poor-plants-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"vue-paho-mqtt": minor
---

feat: added + and # wildcard support
20 changes: 19 additions & 1 deletion src/pahoMqttPlugin/functions/onMessageArrived.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createTopicList } from '~/utils/createTopicList';
import { msgHandlers } from '~/utils/msgHandlers';

export const onMessageArrivedCallback = (message: {
Expand All @@ -6,11 +7,28 @@ export const onMessageArrivedCallback = (message: {
}): void => {
const topic = message.destinationName;
const payload = message.payloadString.replace(/\0.*$/g, '').trim();

const possibleTopics = createTopicList(topic);

if (msgHandlers[topic]) {
msgHandlers[topic].forEach((handler) => {
if (handler) handler(payload);
});
} else {
console.warn('Unhandled topic!', topic, payload);
let found = false;

if (!found)
possibleTopics.forEach((possibleTopic) => {
if (msgHandlers[possibleTopic]) {
msgHandlers[possibleTopic].forEach((handler) => {
if (handler) {
handler(payload);
found = true;
}
});
}
});

if (!found) console.warn('Unhandled topic!', topic, payload);
}
};
4 changes: 2 additions & 2 deletions src/pahoMqttPlugin/utils/__tests__/auth.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {utilClientAuth} from '~/../setupTests';
import { utilClientAuth } from '~/../setupTests';
import { createClient } from '~/config/client';
import { defaultMqttOptions } from '~/config/constants';
import {getMqttOptions, setMqttOptions} from '~/config/options';
import { getMqttOptions, setMqttOptions } from '~/config/options';
import * as UTILS from '~/utils';

describe.runIf(process.env.NODE_ENV === 'broker')('auth utils', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/pahoMqttPlugin/utils/__tests__/secure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { utilClientWss } from '~/../setupTests';
import { createClient } from '~/config/client';
import { defaultMqttOptions } from '~/config/constants';
import * as UTILS from '~/utils';
import {getMqttOptions, setMqttOptions} from "~/config/options";
import { getMqttOptions, setMqttOptions } from '~/config/options';

describe.runIf(process.env.NODE_ENV === 'broker')('auth utils', () => {
test('if status is set right before connection', () => {
Expand Down
21 changes: 19 additions & 2 deletions src/pahoMqttPlugin/utils/__tests__/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { DoneCallback } from 'vitest';
import { utilClient } from '~/../setupTests';
import { createClient } from '~/config/client';
import { MQTT_STATE, defaultMqttOptions } from '~/config/constants';
import {getMqttOptions, setMqttOptions} from '~/config/options';
import { getMqttOptions, setMqttOptions } from '~/config/options';
import { MqttMode } from '~/types/types';
import * as UTILS from '~/utils';

Expand All @@ -11,7 +11,7 @@ describe.runIf(process.env.NODE_ENV === 'broker')('utils', () => {
expect(UTILS.status()).toBe('disconnected');
});
describe('Client', () => {
setMqttOptions(utilClient)
setMqttOptions(utilClient);
createClient(getMqttOptions());
test('if host set correctly', () => {
expect(UTILS.host()).toBe(utilClient.host);
Expand Down Expand Up @@ -117,3 +117,20 @@ describe.runIf(process.env.NODE_ENV === 'broker')('utils', () => {
expect(UTILS.disconnectClient()).resolves.toBe(true);
});
});

describe('createTopicList', () => {
test('if creates a list of topics from a topic string', () => {
expect(UTILS.createTopicList('this/is/a/test/topic')).toEqual([
'+/is/a/test/topic',
'this/+/a/test/topic',
'this/is/+/test/topic',
'this/is/a/+/topic',
'this/is/a/test/+',
'this/#',
'this/is/#',
'this/is/a/#',
'this/is/a/test/#',
'this/is/a/test/topic',
]);
});
});
26 changes: 26 additions & 0 deletions src/pahoMqttPlugin/utils/createTopicList.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Create a list of possible topics from a topic string that may contain wildcards
* @param topic A topic string that may contain wildcards
*/
export function createTopicList(topic: string): string[] {
const parts = topic.split('/');
const result: string[] = [];

for (let i = 0; i < parts.length; i++) {
let generatedTopic =
parts.slice(0, i).join('/') + '/+/' + parts.slice(i + 1).join('/');
if (generatedTopic.startsWith('/'))
generatedTopic = generatedTopic.slice(1);
if (generatedTopic.endsWith('/'))
generatedTopic = generatedTopic.slice(0, -1);
result.push(generatedTopic);
}

for (let i = 0; i < parts.length; i++) {
const generatedTopic =
parts.slice(0, i + 1).join('/') + (i < parts.length - 1 ? '/#' : '');
result.push(generatedTopic);
}

return result;
}
2 changes: 2 additions & 0 deletions src/pahoMqttPlugin/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import { publish } from './publish';
import { subscribe } from './subscribe';
import { unsubscribe } from './unsubscribe';
import { unsubscribeAll } from './unsubscribeAll';
import { createTopicList } from './createTopicList';

export {
connectClient,
createTopicList,
disconnectClient,
publish,
subscribe,
Expand Down

0 comments on commit f8bab09

Please sign in to comment.