Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,19 @@ ArduinoIoTCloud.connect(options)
.catch(error => console.error(error));
```

## Override MQTT Library

If for any reason (e.g., a `React Native` project) the standard [mqtt library](https://github.com/mqttjs/MQTT.js) causes issues, it's possible to override it using `ArduinoIoTCloudFactory`.

```ts
import { ArduinoIoTCloudFactory, MqttConnect, ConnectionOptions } from 'arduino-iot-js';

const connect = (url: string, options: ConnectionOptions) => // Put your library here (es. new Paho.MQTT.Client(options.host, Number(options.port)); )

const ArduinoIoTCloud = ArduinoIoTCloudFactory(connect);

```

## Development

### Testing
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "arduino-iot-js",
"version": "0.9.5",
"version": "0.9.7",
"license": "GPLv3",
"description": "JS module providing Arduino Create IoT Cloud Connection",
"main": "./lib/index.js",
Expand Down
4 changes: 2 additions & 2 deletions src/builder/APIConnectionBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MqttClient } from 'mqtt';
import { MqttConnect } from '../mqtt/IMqttClient';
import { IHttpClient } from '../http/IHttpClient';
import { Connection } from '../connection/Connection';
import { IConnection } from '../connection/IConnection';
Expand All @@ -16,7 +16,7 @@ function isApiOptions(options: CloudOptions): options is APIOptions {
}

export class APIConnectionBuilder implements IConnectionBuilder {
constructor(private client: IHttpClient, private mqttConnect: (string, IClientOptions) => MqttClient) {}
constructor(private client: IHttpClient, private mqttConnect: MqttConnect) {}

public canBuild(options: CloudOptions): boolean {
return isApiOptions(options);
Expand Down
4 changes: 2 additions & 2 deletions src/builder/TokenConnectionBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { MqttClient } from 'mqtt';
import { MqttConnect } from '../mqtt/IMqttClient';
import { Connection } from '../connection/Connection';
import { IConnection } from '../connection/IConnection';
import { IConnectionBuilder } from './IConnectionBuilder';
import { BrowserOptions, CloudOptions, BaseCloudOptions } from '../client/ICloudClient';

export class TokenConnectionBuilder implements IConnectionBuilder {
constructor(private mqttConnect: (string, IClientOptions) => MqttClient) {}
constructor(private mqttConnect: MqttConnect) {}

canBuild(options: CloudOptions): boolean {
return !!(options as BrowserOptions).token;
Expand Down
14 changes: 7 additions & 7 deletions src/connection/Connection.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import mqtt from 'mqtt';
import { Observable, Subject } from 'rxjs';

import SenML from '../senML';
import Utils from '../utils';
import { IMqttClient, MqttConnect } from '../mqtt/IMqttClient';
import { CloudMessageValue } from '../client/ICloudClient';
import { IConnection, CloudMessage, ConnectionOptions } from './IConnection';

Expand All @@ -18,12 +18,12 @@
public token: string;
public messages: Observable<CloudMessage>;

private _client: mqtt.MqttClient;
private get client(): mqtt.MqttClient {
private _client: IMqttClient;
private get client(): IMqttClient {
return this._client;
}

private set client(client: mqtt.MqttClient) {
private set client(client: IMqttClient) {
this._client = client;
const messages = (this.messages = new Subject<CloudMessage>());

Expand All @@ -37,7 +37,7 @@
host: string,
port: string | number,
token: string,
mqttConnect: (string, IClientOptions) => mqtt.MqttClient
mqttConnect: MqttConnect
): Promise<IConnection> {
if (!token) throw new Error('connection failed: you need to provide a valid token');
if (!host) throw new Error('connection failed: you need to provide a valid host (broker)');
Expand All @@ -58,25 +58,25 @@
return connection;
}

public on(event: any, cb: any): IConnection {

Check warning on line 61 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 61 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 61 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 61 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
this.client.on(event, cb);
return this;
}
public end(force?: boolean, opts?: Record<string, any>, cb?: mqtt.CloseCallback): IConnection {
public end(force?: boolean, opts?: Record<string, any>, cb?: Function): IConnection {

Check warning on line 65 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 65 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
this.client.end(force, opts, cb);
return this;
}
public reconnect(opts?: mqtt.IClientReconnectOptions): IConnection {
public reconnect(opts?: object): IConnection {
this.client.reconnect(opts);
return this;
}

public unsubscribe(topic: string | string[], opts?: any, callback?: any): IConnection {

Check warning on line 74 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 74 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 74 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 74 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
this.client.subscribe(topic, opts, callback);
return this;
}

public publish(topic: any, message: any, opts?: any, callback?: any): IConnection {

Check warning on line 79 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type

Check warning on line 79 in src/connection/Connection.ts

View workflow job for this annotation

GitHub Actions / test

Unexpected any. Specify a different type
this.client.publish(topic, message, opts, callback);
return this;
}
Expand Down
52 changes: 30 additions & 22 deletions src/connection/IConnection.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
import { Observable } from 'rxjs';
import {
IClientOptions,
OnConnectCallback,
OnMessageCallback,
OnPacketCallback,
OnErrorCallback,
CloseCallback,
IClientReconnectOptions,
PacketCallback,
IClientPublishOptions,
} from 'mqtt';

import { CloudMessageValue } from '../client/ICloudClient';

export type ConnectionOptions = IClientOptions;
export type ConnectionOptions = {
port?: number;
host?: string;
hostname?: string;
path?: string;
protocol?: 'wss' | 'ws' | 'mqtt' | 'mqtts' | 'tcp' | 'ssl' | 'wx' | 'wxs';
wsOptions?: object;
keepalive?: number;
clientId?: string;
protocolId?: string;
protocolVersion?: number;
clean?: boolean;
reconnectPeriod?: number;
connectTimeout?: number;
username?: string;
password?: string;
queueQoSZero?: boolean;
reschedulePings?: boolean;
resubscribe?: boolean;
properties?: object;
servers?: object;
will?: object;
};

export type CloudMessage = {
topic: string;
propertyName?: string;
Expand All @@ -24,21 +36,17 @@ export interface IConnection {
token?: string;
messages?: Observable<CloudMessage>;

on(event: 'connect', cb: OnConnectCallback): IConnection;
on(event: 'message', cb: OnMessageCallback): IConnection;
on(event: 'packetsend' | 'packetreceive', cb: OnPacketCallback): IConnection;
on(event: 'error', cb: OnErrorCallback): IConnection;
on(event: 'error', cb: (error: Error) => void): IConnection;
on(event: string, cb: Function): IConnection;
on(event: any, cb: any): IConnection;

end(force?: boolean, opts?: Record<string, any>, cb?: CloseCallback): IConnection;
end(force?: boolean, opts?: Record<string, any>, cb?: Function): IConnection;

reconnect(opts?: IClientReconnectOptions): IConnection;
reconnect(opts?: object): IConnection;

unsubscribe(topic: string | string[], opts?: Record<string, any>, callback?: PacketCallback): IConnection;
unsubscribe(topic: string | string[], opts?: Record<string, any>, callback?: Function): IConnection;

publish(topic: string, message: string | Buffer, opts: IClientPublishOptions, callback?: PacketCallback): IConnection;
publish(topic: string, message: string | Buffer, callback?: PacketCallback): IConnection;
publish(topic: string, message: string | Buffer, opts: object, callback?: Function): IConnection;
publish(topic: string, message: string | Buffer, callback?: Function): IConnection;
publish(topic: any, message: any, opts?: any, callback?: any): IConnection;

subscribe(topic: any, callback?: any): IConnection;
Expand Down
24 changes: 14 additions & 10 deletions src/index.lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,25 @@
*
*/

import SenML from './senML';
import fetch from 'node-fetch';
import mqtt from 'mqtt';
import fetch from 'node-fetch';

import { HttpClientFactory } from './http/HttpClientFactory';
import SenML from './senML';
import { CloudClient } from './client/CloudClient';
import { ConnectionOptions } from './connection/IConnection';
import { HttpClientFactory } from './http/HttpClientFactory';
import { IMqttClient, MqttConnect } from './mqtt/IMqttClient';
import { APIConnectionBuilder } from './builder/APIConnectionBuilder';
import { TokenConnectionBuilder } from './builder/TokenConnectionBuilder';

const builders = [
new TokenConnectionBuilder(mqtt.connect),
new APIConnectionBuilder(HttpClientFactory.Create(fetch), mqtt.connect),
];
const ArduinoIoTCloud = new CloudClient(builders);
const ArduinoIoTCloudFactory = (mqttConnect: MqttConnect) =>
new CloudClient([
new TokenConnectionBuilder(mqttConnect),
new APIConnectionBuilder(HttpClientFactory.Create(fetch), mqttConnect),
]);

const ArduinoIoTCloud = ArduinoIoTCloudFactory(mqtt.connect);

export { SenML };
export { ArduinoIoTCloud };
export { ArduinoIoTCloudFactory, ArduinoIoTCloud };
export { SenML, IMqttClient, MqttConnect, ConnectionOptions };
export { CloudOptions, CloudMessageValue } from './client/ICloudClient';
21 changes: 13 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,23 @@

import 'whatwg-fetch';
import mqtt from 'mqtt/dist/mqtt';

import SenML from './senML';
import { HttpClientFactory } from './http/HttpClientFactory';
import { CloudClient } from './client/CloudClient';
import { ConnectionOptions } from './connection/IConnection';
import { HttpClientFactory } from './http/HttpClientFactory';
import { IMqttClient, MqttConnect } from './mqtt/IMqttClient';
import { APIConnectionBuilder } from './builder/APIConnectionBuilder';
import { TokenConnectionBuilder } from './builder/TokenConnectionBuilder';

const builders = [
new TokenConnectionBuilder(mqtt.connect),
new APIConnectionBuilder(HttpClientFactory.Create(fetch), mqtt.connect),
];
const ArduinoIoTCloud = new CloudClient(builders);
const ArduinoIoTCloudFactory = (mqttConnect: MqttConnect) =>
new CloudClient([
new TokenConnectionBuilder(mqttConnect),
new APIConnectionBuilder(HttpClientFactory.Create(fetch), mqttConnect),
]);

const ArduinoIoTCloud = ArduinoIoTCloudFactory(mqtt.connect);

export { SenML };
export { ArduinoIoTCloud };
export { ArduinoIoTCloudFactory, ArduinoIoTCloud };
export { SenML, IMqttClient, MqttConnect, ConnectionOptions };
export { CloudOptions, CloudMessageValue } from './client/ICloudClient';
17 changes: 17 additions & 0 deletions src/mqtt/IMqttClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ConnectionOptions } from '../connection/IConnection';

export interface IMqttClient {
on(event: 'error', cb: (error: Error) => void): IMqttClient;
on(event: string, cb: Function): IMqttClient;

publish(topic: string, message: string | Buffer, opts: object, callback?: Function): IMqttClient;
publish(topic: string, message: string | Buffer, callback?: Function): IMqttClient;

end(force?: boolean, opts?: object, cb?: Function): IMqttClient;

subscribe(topic: string | string[], opts?: object, callback?: Function): IMqttClient;

reconnect(opts?: object): IMqttClient;
}

export type MqttConnect = (url: string, options: ConnectionOptions) => IMqttClient;
Loading