@machhub-dev/sdk-ts 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/classes/collection.d.ts +3 -1
- package/dist/cjs/classes/collection.js +4 -1
- package/dist/cjs/classes/tag.d.ts +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/services/mqtt.service.d.ts +2 -1
- package/dist/cjs/services/mqtt.service.js +36 -2
- package/dist/cjs/types/operator.models.d.ts +28 -0
- package/dist/cjs/types/operator.models.js +6 -0
- package/dist/classes/collection.d.ts +3 -1
- package/dist/classes/collection.js +4 -1
- package/dist/classes/tag.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/services/mqtt.service.d.ts +2 -1
- package/dist/services/mqtt.service.js +36 -2
- package/dist/types/operator.models.d.ts +28 -0
- package/dist/types/operator.models.js +5 -0
- package/package.json +1 -1
- package/src/classes/tag.ts +1 -1
- package/src/services/mqtt.service.ts +41 -4
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { HTTPService } from "../services/http.service.js";
|
|
2
2
|
import { MQTTService } from "../services/mqtt.service.js";
|
|
3
|
+
import { Operator } from "../types/operator.models.js";
|
|
3
4
|
export declare class CollectionError extends Error {
|
|
4
5
|
operation: string;
|
|
5
6
|
collectionName: string;
|
|
@@ -12,7 +13,7 @@ export declare class Collection {
|
|
|
12
13
|
protected collectionName: string;
|
|
13
14
|
protected queryParams: Record<string, any>;
|
|
14
15
|
constructor(httpService: HTTPService, mqttService: MQTTService | null, collectionName: string);
|
|
15
|
-
filter(fieldName: string, operator:
|
|
16
|
+
filter(fieldName: string, operator: Operator, value: any): Collection;
|
|
16
17
|
sort(field: string, direction?: "asc" | "desc"): Collection;
|
|
17
18
|
limit(limit: number): Collection;
|
|
18
19
|
offset(offset: number): Collection;
|
|
@@ -21,6 +22,7 @@ export declare class Collection {
|
|
|
21
22
|
first(): Promise<any>;
|
|
22
23
|
getAll(options?: {
|
|
23
24
|
expand?: string | string[];
|
|
25
|
+
fields?: string | string[];
|
|
24
26
|
}): Promise<any[]>;
|
|
25
27
|
count(options?: {
|
|
26
28
|
filter?: any;
|
|
@@ -55,7 +55,10 @@ class Collection {
|
|
|
55
55
|
try {
|
|
56
56
|
this.applyOptions(options);
|
|
57
57
|
if (options?.expand) {
|
|
58
|
-
this.queryParams.expand = Array.isArray(options.expand) ? options.expand.join() : options.expand;
|
|
58
|
+
this.queryParams.expand = Array.isArray(options.expand) ? options.expand.join(",") : options.expand;
|
|
59
|
+
}
|
|
60
|
+
if (options?.fields) {
|
|
61
|
+
this.queryParams.fields = Array.isArray(options.fields) ? options.fields.join(",") : options.fields;
|
|
59
62
|
}
|
|
60
63
|
return await this.httpService.request.get(this.collectionName + "/all", this.queryParams);
|
|
61
64
|
}
|
|
@@ -6,5 +6,5 @@ export declare class Tag {
|
|
|
6
6
|
constructor(httpService: HTTPService, mqttService: MQTTService | null);
|
|
7
7
|
getAllTags(): Promise<string[]>;
|
|
8
8
|
publish(topic: string, data: any): Promise<void>;
|
|
9
|
-
subscribe(topic: string, callback: (data: any) => void): Promise<void>;
|
|
9
|
+
subscribe(topic: string, callback: (data: any, topic?: string) => void): Promise<void>;
|
|
10
10
|
}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { SDK, type SDKConfig } from './sdk-ts.js';
|
|
2
2
|
export type { LoginResponse, PermissionResponse, User, Group, Feature, Permission, ActionResponse, Action, Scope } from './types/auth.models.js';
|
|
3
|
+
export type { Operator } from './types/operator.models.js';
|
|
3
4
|
export type { BaseResponse } from './types/response.models.js';
|
|
4
5
|
export type { RecordID } from './types/recordID.models.js';
|
|
5
6
|
export type { HistorizedData } from './types/tag.models.js';
|
|
@@ -7,9 +7,10 @@ export declare class MQTTService {
|
|
|
7
7
|
constructor(url: string);
|
|
8
8
|
static getInstance(url?: string, developerKey?: string): Promise<MQTTService>;
|
|
9
9
|
static resetInstance(): void;
|
|
10
|
-
addTopicHandler(topic: string, handler: (message: unknown) => void): void;
|
|
10
|
+
addTopicHandler(topic: string, handler: (message: unknown, topic?: string) => void): void;
|
|
11
11
|
clearTopics(): void;
|
|
12
12
|
publish(topic: string, message: unknown): boolean;
|
|
13
13
|
private attachMessageListener;
|
|
14
|
+
private matchesTopic;
|
|
14
15
|
private parseMessage;
|
|
15
16
|
}
|
|
@@ -89,14 +89,48 @@ class MQTTService {
|
|
|
89
89
|
});
|
|
90
90
|
this.client.on('message', (topic, message) => {
|
|
91
91
|
for (const subscribedTopic of this.subscribedTopics) {
|
|
92
|
-
if (
|
|
92
|
+
if (this.matchesTopic(subscribedTopic.topic, topic)) {
|
|
93
93
|
const parsedMessage = this.parseMessage(message, topic);
|
|
94
|
-
subscribedTopic.handler(parsedMessage);
|
|
94
|
+
subscribedTopic.handler(parsedMessage, topic);
|
|
95
95
|
break;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
});
|
|
99
99
|
}
|
|
100
|
+
// Matches MQTT topic patterns with wildcards (+ for single level, # for multi-level)
|
|
101
|
+
matchesTopic(pattern, topic) {
|
|
102
|
+
// Handle exact match first for performance
|
|
103
|
+
if (pattern === topic) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
const patternParts = pattern.split('/');
|
|
107
|
+
const topicParts = topic.split('/');
|
|
108
|
+
let i = 0;
|
|
109
|
+
let j = 0;
|
|
110
|
+
while (i < patternParts.length && j < topicParts.length) {
|
|
111
|
+
const patternPart = patternParts[i];
|
|
112
|
+
if (patternPart === '#') {
|
|
113
|
+
// Multi-level wildcard matches everything from this point
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
else if (patternPart === '+') {
|
|
117
|
+
// Single-level wildcard matches any single level
|
|
118
|
+
i++;
|
|
119
|
+
j++;
|
|
120
|
+
}
|
|
121
|
+
else if (patternPart === topicParts[j]) {
|
|
122
|
+
// Exact match
|
|
123
|
+
i++;
|
|
124
|
+
j++;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
// No match
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Check if we've consumed both pattern and topic completely
|
|
132
|
+
return i === patternParts.length && j === topicParts.length;
|
|
133
|
+
}
|
|
100
134
|
parseMessage(message, topic) {
|
|
101
135
|
try {
|
|
102
136
|
return JSON.parse(message.toString());
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SurrealDB Operators
|
|
3
|
+
* Reference: https://surrealdb.com/docs/surrealql/operators
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Comparison operators
|
|
7
|
+
*/
|
|
8
|
+
export type ComparisonOperator = "=" | "!=" | "==" | "?=" | "*=" | "~" | "!~" | "?~" | "*~" | "<" | "<=" | ">" | ">=";
|
|
9
|
+
/**
|
|
10
|
+
* Containment operators
|
|
11
|
+
*/
|
|
12
|
+
export type ContainmentOperator = "CONTAINS" | "CONTAINSNOT" | "CONTAINSALL" | "CONTAINSANY" | "CONTAINSNONE" | "INSIDE" | "NOTINSIDE" | "ALLINSIDE" | "ANYINSIDE" | "NONEINSIDE";
|
|
13
|
+
/**
|
|
14
|
+
* String operators
|
|
15
|
+
*/
|
|
16
|
+
export type StringOperator = "@@" | "@0@" | "@1@" | "@2@" | "@3@";
|
|
17
|
+
/**
|
|
18
|
+
* Array operators
|
|
19
|
+
*/
|
|
20
|
+
export type ArrayOperator = "IN" | "NOT IN";
|
|
21
|
+
/**
|
|
22
|
+
* All available operators in SurrealDB
|
|
23
|
+
*/
|
|
24
|
+
export type Operator = ComparisonOperator | ContainmentOperator | StringOperator | ArrayOperator;
|
|
25
|
+
/**
|
|
26
|
+
* Common operators for basic queries
|
|
27
|
+
*/
|
|
28
|
+
export type BasicOperator = "=" | "!=" | "<" | "<=" | ">" | ">=" | "CONTAINS" | "IN";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { HTTPService } from "../services/http.service.js";
|
|
2
2
|
import { MQTTService } from "../services/mqtt.service.js";
|
|
3
|
+
import { Operator } from "../types/operator.models.js";
|
|
3
4
|
export declare class CollectionError extends Error {
|
|
4
5
|
operation: string;
|
|
5
6
|
collectionName: string;
|
|
@@ -12,7 +13,7 @@ export declare class Collection {
|
|
|
12
13
|
protected collectionName: string;
|
|
13
14
|
protected queryParams: Record<string, any>;
|
|
14
15
|
constructor(httpService: HTTPService, mqttService: MQTTService | null, collectionName: string);
|
|
15
|
-
filter(fieldName: string, operator:
|
|
16
|
+
filter(fieldName: string, operator: Operator, value: any): Collection;
|
|
16
17
|
sort(field: string, direction?: "asc" | "desc"): Collection;
|
|
17
18
|
limit(limit: number): Collection;
|
|
18
19
|
offset(offset: number): Collection;
|
|
@@ -21,6 +22,7 @@ export declare class Collection {
|
|
|
21
22
|
first(): Promise<any>;
|
|
22
23
|
getAll(options?: {
|
|
23
24
|
expand?: string | string[];
|
|
25
|
+
fields?: string | string[];
|
|
24
26
|
}): Promise<any[]>;
|
|
25
27
|
count(options?: {
|
|
26
28
|
filter?: any;
|
|
@@ -51,7 +51,10 @@ export class Collection {
|
|
|
51
51
|
try {
|
|
52
52
|
this.applyOptions(options);
|
|
53
53
|
if (options?.expand) {
|
|
54
|
-
this.queryParams.expand = Array.isArray(options.expand) ? options.expand.join() : options.expand;
|
|
54
|
+
this.queryParams.expand = Array.isArray(options.expand) ? options.expand.join(",") : options.expand;
|
|
55
|
+
}
|
|
56
|
+
if (options?.fields) {
|
|
57
|
+
this.queryParams.fields = Array.isArray(options.fields) ? options.fields.join(",") : options.fields;
|
|
55
58
|
}
|
|
56
59
|
return await this.httpService.request.get(this.collectionName + "/all", this.queryParams);
|
|
57
60
|
}
|
package/dist/classes/tag.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export declare class Tag {
|
|
|
6
6
|
constructor(httpService: HTTPService, mqttService: MQTTService | null);
|
|
7
7
|
getAllTags(): Promise<string[]>;
|
|
8
8
|
publish(topic: string, data: any): Promise<void>;
|
|
9
|
-
subscribe(topic: string, callback: (data: any) => void): Promise<void>;
|
|
9
|
+
subscribe(topic: string, callback: (data: any, topic?: string) => void): Promise<void>;
|
|
10
10
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { SDK, type SDKConfig } from './sdk-ts.js';
|
|
2
2
|
export type { LoginResponse, PermissionResponse, User, Group, Feature, Permission, ActionResponse, Action, Scope } from './types/auth.models.js';
|
|
3
|
+
export type { Operator } from './types/operator.models.js';
|
|
3
4
|
export type { BaseResponse } from './types/response.models.js';
|
|
4
5
|
export type { RecordID } from './types/recordID.models.js';
|
|
5
6
|
export type { HistorizedData } from './types/tag.models.js';
|
|
@@ -7,9 +7,10 @@ export declare class MQTTService {
|
|
|
7
7
|
constructor(url: string);
|
|
8
8
|
static getInstance(url?: string, developerKey?: string): Promise<MQTTService>;
|
|
9
9
|
static resetInstance(): void;
|
|
10
|
-
addTopicHandler(topic: string, handler: (message: unknown) => void): void;
|
|
10
|
+
addTopicHandler(topic: string, handler: (message: unknown, topic?: string) => void): void;
|
|
11
11
|
clearTopics(): void;
|
|
12
12
|
publish(topic: string, message: unknown): boolean;
|
|
13
13
|
private attachMessageListener;
|
|
14
|
+
private matchesTopic;
|
|
14
15
|
private parseMessage;
|
|
15
16
|
}
|
|
@@ -83,14 +83,48 @@ export class MQTTService {
|
|
|
83
83
|
});
|
|
84
84
|
this.client.on('message', (topic, message) => {
|
|
85
85
|
for (const subscribedTopic of this.subscribedTopics) {
|
|
86
|
-
if (
|
|
86
|
+
if (this.matchesTopic(subscribedTopic.topic, topic)) {
|
|
87
87
|
const parsedMessage = this.parseMessage(message, topic);
|
|
88
|
-
subscribedTopic.handler(parsedMessage);
|
|
88
|
+
subscribedTopic.handler(parsedMessage, topic);
|
|
89
89
|
break;
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
93
|
}
|
|
94
|
+
// Matches MQTT topic patterns with wildcards (+ for single level, # for multi-level)
|
|
95
|
+
matchesTopic(pattern, topic) {
|
|
96
|
+
// Handle exact match first for performance
|
|
97
|
+
if (pattern === topic) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
const patternParts = pattern.split('/');
|
|
101
|
+
const topicParts = topic.split('/');
|
|
102
|
+
let i = 0;
|
|
103
|
+
let j = 0;
|
|
104
|
+
while (i < patternParts.length && j < topicParts.length) {
|
|
105
|
+
const patternPart = patternParts[i];
|
|
106
|
+
if (patternPart === '#') {
|
|
107
|
+
// Multi-level wildcard matches everything from this point
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
else if (patternPart === '+') {
|
|
111
|
+
// Single-level wildcard matches any single level
|
|
112
|
+
i++;
|
|
113
|
+
j++;
|
|
114
|
+
}
|
|
115
|
+
else if (patternPart === topicParts[j]) {
|
|
116
|
+
// Exact match
|
|
117
|
+
i++;
|
|
118
|
+
j++;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
// No match
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Check if we've consumed both pattern and topic completely
|
|
126
|
+
return i === patternParts.length && j === topicParts.length;
|
|
127
|
+
}
|
|
94
128
|
parseMessage(message, topic) {
|
|
95
129
|
try {
|
|
96
130
|
return JSON.parse(message.toString());
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SurrealDB Operators
|
|
3
|
+
* Reference: https://surrealdb.com/docs/surrealql/operators
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Comparison operators
|
|
7
|
+
*/
|
|
8
|
+
export type ComparisonOperator = "=" | "!=" | "==" | "?=" | "*=" | "~" | "!~" | "?~" | "*~" | "<" | "<=" | ">" | ">=";
|
|
9
|
+
/**
|
|
10
|
+
* Containment operators
|
|
11
|
+
*/
|
|
12
|
+
export type ContainmentOperator = "CONTAINS" | "CONTAINSNOT" | "CONTAINSALL" | "CONTAINSANY" | "CONTAINSNONE" | "INSIDE" | "NOTINSIDE" | "ALLINSIDE" | "ANYINSIDE" | "NONEINSIDE";
|
|
13
|
+
/**
|
|
14
|
+
* String operators
|
|
15
|
+
*/
|
|
16
|
+
export type StringOperator = "@@" | "@0@" | "@1@" | "@2@" | "@3@";
|
|
17
|
+
/**
|
|
18
|
+
* Array operators
|
|
19
|
+
*/
|
|
20
|
+
export type ArrayOperator = "IN" | "NOT IN";
|
|
21
|
+
/**
|
|
22
|
+
* All available operators in SurrealDB
|
|
23
|
+
*/
|
|
24
|
+
export type Operator = ComparisonOperator | ContainmentOperator | StringOperator | ArrayOperator;
|
|
25
|
+
/**
|
|
26
|
+
* Common operators for basic queries
|
|
27
|
+
*/
|
|
28
|
+
export type BasicOperator = "=" | "!=" | "<" | "<=" | ">" | ">=" | "CONTAINS" | "IN";
|
package/package.json
CHANGED
package/src/classes/tag.ts
CHANGED
|
@@ -21,7 +21,7 @@ export class Tag {
|
|
|
21
21
|
this.mqttService.publish(topic, data);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
async subscribe(topic: string, callback: (data: any) => void): Promise<void> {
|
|
24
|
+
async subscribe(topic: string, callback: (data: any, topic?: string) => void): Promise<void> {
|
|
25
25
|
if (!this.mqttService) {
|
|
26
26
|
throw new Error("MQTT service not connected");
|
|
27
27
|
}
|
|
@@ -2,7 +2,7 @@ import mqtt from 'mqtt';
|
|
|
2
2
|
|
|
3
3
|
interface SubscribedTopic {
|
|
4
4
|
topic: string;
|
|
5
|
-
handler: (message: unknown) => void;
|
|
5
|
+
handler: (message: unknown, topic?: string) => void;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export class MQTTService {
|
|
@@ -46,7 +46,7 @@ export class MQTTService {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// addTopicHandler Adds a topic and handler to the subscribed list
|
|
49
|
-
public addTopicHandler(topic: string, handler: (message: unknown) => void): void {
|
|
49
|
+
public addTopicHandler(topic: string, handler: (message: unknown, topic?: string) => void): void {
|
|
50
50
|
try {
|
|
51
51
|
this.subscribedTopics.push({ topic, handler });
|
|
52
52
|
if (topic == "") return;
|
|
@@ -101,15 +101,52 @@ export class MQTTService {
|
|
|
101
101
|
|
|
102
102
|
this.client.on('message', (topic: string, message: Buffer) => {
|
|
103
103
|
for (const subscribedTopic of this.subscribedTopics) {
|
|
104
|
-
if (
|
|
104
|
+
if (this.matchesTopic(subscribedTopic.topic, topic)) {
|
|
105
105
|
const parsedMessage = this.parseMessage(message, topic);
|
|
106
|
-
subscribedTopic.handler(parsedMessage);
|
|
106
|
+
subscribedTopic.handler(parsedMessage, topic);
|
|
107
107
|
break;
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// Matches MQTT topic patterns with wildcards (+ for single level, # for multi-level)
|
|
114
|
+
private matchesTopic(pattern: string, topic: string): boolean {
|
|
115
|
+
// Handle exact match first for performance
|
|
116
|
+
if (pattern === topic) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const patternParts = pattern.split('/');
|
|
121
|
+
const topicParts = topic.split('/');
|
|
122
|
+
|
|
123
|
+
let i = 0;
|
|
124
|
+
let j = 0;
|
|
125
|
+
|
|
126
|
+
while (i < patternParts.length && j < topicParts.length) {
|
|
127
|
+
const patternPart = patternParts[i];
|
|
128
|
+
|
|
129
|
+
if (patternPart === '#') {
|
|
130
|
+
// Multi-level wildcard matches everything from this point
|
|
131
|
+
return true;
|
|
132
|
+
} else if (patternPart === '+') {
|
|
133
|
+
// Single-level wildcard matches any single level
|
|
134
|
+
i++;
|
|
135
|
+
j++;
|
|
136
|
+
} else if (patternPart === topicParts[j]) {
|
|
137
|
+
// Exact match
|
|
138
|
+
i++;
|
|
139
|
+
j++;
|
|
140
|
+
} else {
|
|
141
|
+
// No match
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Check if we've consumed both pattern and topic completely
|
|
147
|
+
return i === patternParts.length && j === topicParts.length;
|
|
148
|
+
}
|
|
149
|
+
|
|
113
150
|
private parseMessage(message: Buffer, topic: string): unknown {
|
|
114
151
|
try {
|
|
115
152
|
return JSON.parse(message.toString());
|