@meta2d/core 1.0.71 → 1.0.73
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/package.json +3 -2
- package/src/canvas/canvas.js +6 -5
- package/src/canvas/canvas.js.map +1 -1
- package/src/core.d.ts +12 -3
- package/src/core.js +200 -52
- package/src/core.js.map +1 -1
- package/src/diagrams/rectangle.js +29 -0
- package/src/diagrams/rectangle.js.map +1 -1
- package/src/dialog/dialog.js +9 -1
- package/src/dialog/dialog.js.map +1 -1
- package/src/event/event.d.ts +2 -0
- package/src/message/message.d.ts +2 -0
- package/src/message/message.js +6 -4
- package/src/message/message.js.map +1 -1
- package/src/pen/model.d.ts +5 -0
- package/src/pen/model.js.map +1 -1
- package/src/pen/render.js +18 -1
- package/src/pen/render.js.map +1 -1
- package/src/store/store.d.ts +33 -2
- package/src/store/store.js.map +1 -1
- package/src/theme.d.ts +9 -0
- package/src/theme.js +116 -28
- package/src/theme.js.map +1 -1
- package/src/utils/jetLinks.d.ts +1 -0
- package/src/utils/jetLinks.js +88 -4
- package/src/utils/jetLinks.js.map +1 -1
- package/src/utils/url.js +4 -1
- package/src/utils/url.js.map +1 -1
package/src/core.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Canvas } from './canvas';
|
|
|
3
3
|
import { Options, PenPlugin, PluginOptions } from './options';
|
|
4
4
|
import { calcTextDrawRect, calcTextLines, calcTextRect, facePen, getWords, LockState, Pen, renderPenRaw, IValue, setElemPosition } from './pen';
|
|
5
5
|
import { Point } from './point';
|
|
6
|
-
import { EditAction, register, registerAnchors, registerCanvasDraw, Meta2dData, Meta2dStore, Network, HttpOptions } from './store';
|
|
6
|
+
import { EditAction, register, registerAnchors, registerCanvasDraw, Meta2dData, Meta2dStore, Network, HttpOptions, Sql } from './store';
|
|
7
7
|
import { Padding } from './utils';
|
|
8
8
|
import { Rect } from './rect';
|
|
9
9
|
import { Event, TriggerCondition } from './event';
|
|
@@ -17,6 +17,7 @@ export declare class Meta2d {
|
|
|
17
17
|
mqttClient: MqttClient;
|
|
18
18
|
websockets: WebSocket[];
|
|
19
19
|
mqttClients: MqttClient[];
|
|
20
|
+
eventSources: EventSource[];
|
|
20
21
|
penPluginMap: Map<PenPlugin, {
|
|
21
22
|
tag?: string;
|
|
22
23
|
name?: string;
|
|
@@ -235,9 +236,17 @@ export declare class Meta2d {
|
|
|
235
236
|
updateTimerList: any[];
|
|
236
237
|
sqlTimerList: any[];
|
|
237
238
|
connectNetwork(): void;
|
|
239
|
+
iotMqttClient: MqttClient;
|
|
240
|
+
iotTimer: any;
|
|
241
|
+
iotWebsocketClient: WebSocket;
|
|
242
|
+
connectIot(): Promise<void>;
|
|
243
|
+
connectSqls(): void;
|
|
244
|
+
connectSSE(net: Network): void;
|
|
245
|
+
closeSSE(): void;
|
|
238
246
|
connectNetWebSocket(net: Network): void;
|
|
239
|
-
|
|
240
|
-
|
|
247
|
+
getMqttUrl(): Promise<string>;
|
|
248
|
+
getIotToken(devices: any, type: number): Promise<any>;
|
|
249
|
+
doSqlCode(sql: Sql): Promise<void>;
|
|
241
250
|
randomString(e: number): string;
|
|
242
251
|
mockValue(data: any): any;
|
|
243
252
|
dataMock(): void;
|
package/src/core.js
CHANGED
|
@@ -13,7 +13,7 @@ import pkg from '../package.json';
|
|
|
13
13
|
import { lockedError } from './utils/error';
|
|
14
14
|
import { Scroll } from './scroll';
|
|
15
15
|
import { getter } from './utils/object';
|
|
16
|
-
import { getCookie, getMeta2dData, queryURLParams } from './utils/url';
|
|
16
|
+
import { getCookie, getMeta2dData, getToken, queryURLParams } from './utils/url';
|
|
17
17
|
import { HotkeyType } from './data';
|
|
18
18
|
import { Message, messageList } from './message';
|
|
19
19
|
import { closeJetLinks, connectJetLinks, getSendData, sendJetLinksData } from './utils/jetLinks';
|
|
@@ -25,6 +25,7 @@ export class Meta2d {
|
|
|
25
25
|
mqttClient;
|
|
26
26
|
websockets;
|
|
27
27
|
mqttClients;
|
|
28
|
+
eventSources;
|
|
28
29
|
penPluginMap = new Map();
|
|
29
30
|
socketFn;
|
|
30
31
|
events = {};
|
|
@@ -134,6 +135,7 @@ export class Meta2d {
|
|
|
134
135
|
this.canvas.scroll && this.canvas.scroll.hide();
|
|
135
136
|
}
|
|
136
137
|
}
|
|
138
|
+
this.canvas?.initGlobalStyle();
|
|
137
139
|
}
|
|
138
140
|
getOptions() {
|
|
139
141
|
return this.store.options;
|
|
@@ -151,6 +153,11 @@ export class Meta2d {
|
|
|
151
153
|
// 更新全局的主题css变量
|
|
152
154
|
le5leTheme.updateCssRule(this.store.id, theme);
|
|
153
155
|
this.canvas.initGlobalStyle();
|
|
156
|
+
for (let i = 0; i < this.store.data.pens.length; i++) {
|
|
157
|
+
const pen = this.store.data.pens[i];
|
|
158
|
+
// 调用pen的主题设置函数,如果单个pen有主题的自定义设置的话
|
|
159
|
+
pen.setTheme && pen.setTheme(pen, this.store.styles);
|
|
160
|
+
}
|
|
154
161
|
this.render();
|
|
155
162
|
}
|
|
156
163
|
setDatabyOptions(options = {}) {
|
|
@@ -528,6 +535,7 @@ export class Meta2d {
|
|
|
528
535
|
const data = await getMeta2dData(this.store, id);
|
|
529
536
|
if (data) {
|
|
530
537
|
this.open(data);
|
|
538
|
+
this.fitView(true, 10);
|
|
531
539
|
}
|
|
532
540
|
}
|
|
533
541
|
doSendDataEvent(value, topics) {
|
|
@@ -919,6 +927,8 @@ export class Meta2d {
|
|
|
919
927
|
initBinds() {
|
|
920
928
|
this.jetLinksList = [];
|
|
921
929
|
this.store.bind = {};
|
|
930
|
+
const devices = [];
|
|
931
|
+
const properties = [];
|
|
922
932
|
this.store.data.pens.forEach((pen) => {
|
|
923
933
|
pen.realTimes?.forEach((realTime) => {
|
|
924
934
|
if (realTime.bind && realTime.bind.id) {
|
|
@@ -981,9 +991,55 @@ export class Meta2d {
|
|
|
981
991
|
});
|
|
982
992
|
}
|
|
983
993
|
}
|
|
994
|
+
if (realTime.bind.class === 'iot') {
|
|
995
|
+
let bind = realTime.bind.id.split('#');
|
|
996
|
+
let idx = devices.findIndex((item) => item.deviceId === bind[0]);
|
|
997
|
+
if (idx > -1) {
|
|
998
|
+
if (!devices[idx].properties.includes(bind[1])) {
|
|
999
|
+
devices[idx].properties.push(bind[1]);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
else {
|
|
1003
|
+
devices.push({
|
|
1004
|
+
deviceId: bind[0],
|
|
1005
|
+
properties: [bind[1]],
|
|
1006
|
+
token: realTime.bind.token
|
|
1007
|
+
});
|
|
1008
|
+
}
|
|
1009
|
+
let index = properties.findIndex((item) => item.key === realTime.bind.id);
|
|
1010
|
+
if (index === -1) {
|
|
1011
|
+
properties.push({
|
|
1012
|
+
key: realTime.bind.id,
|
|
1013
|
+
label: realTime.bind.label,
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
else if (realTime.bind.class === 'sql') {
|
|
1018
|
+
let bind = realTime.bind.id.split('#');
|
|
1019
|
+
const sql = this.store.data.sqls.find((item) => item.bindId === bind[0]);
|
|
1020
|
+
if (sql) {
|
|
1021
|
+
if (!sql.keys) {
|
|
1022
|
+
sql.keys = [];
|
|
1023
|
+
}
|
|
1024
|
+
bind.shift();
|
|
1025
|
+
const key = bind.join('#');
|
|
1026
|
+
if (!sql.keys.includes(key)) {
|
|
1027
|
+
sql.keys.push(key);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
984
1031
|
}
|
|
985
1032
|
});
|
|
986
1033
|
});
|
|
1034
|
+
if (devices.length) {
|
|
1035
|
+
if (!this.store.data.iot) {
|
|
1036
|
+
this.store.data.iot = {};
|
|
1037
|
+
}
|
|
1038
|
+
this.store.data.iot.devices = devices;
|
|
1039
|
+
}
|
|
1040
|
+
if (properties.length) {
|
|
1041
|
+
this.store.data.iot.list = properties;
|
|
1042
|
+
}
|
|
987
1043
|
}
|
|
988
1044
|
connectSocket() {
|
|
989
1045
|
this.connectWebsocket();
|
|
@@ -1931,8 +1987,10 @@ export class Meta2d {
|
|
|
1931
1987
|
let mqttIndex = 0;
|
|
1932
1988
|
this.mqttClients = [];
|
|
1933
1989
|
let websocketIndex = 0;
|
|
1990
|
+
let sseIndex = 0;
|
|
1934
1991
|
let sqlIndex = 0;
|
|
1935
1992
|
this.websockets = [];
|
|
1993
|
+
this.eventSources = [];
|
|
1936
1994
|
networks.forEach(async (net) => {
|
|
1937
1995
|
// if (net.type === 'subscribe') {
|
|
1938
1996
|
if (net.protocol === 'mqtt') {
|
|
@@ -2001,54 +2059,101 @@ export class Meta2d {
|
|
|
2001
2059
|
body: net.body,
|
|
2002
2060
|
});
|
|
2003
2061
|
}
|
|
2004
|
-
else if (net.protocol === 'iot') {
|
|
2005
|
-
const token = await this.getIotToken(net.devices);
|
|
2006
|
-
//物联网设备
|
|
2007
|
-
if (net.method === 'mqtt') {
|
|
2008
|
-
net.index = mqttIndex;
|
|
2009
|
-
this.mqttClients[mqttIndex] = mqtt.connect(net.url);
|
|
2010
|
-
this.mqttClients[mqttIndex].on('message', (topic, message) => {
|
|
2011
|
-
this.socketCallback(message.toString(), {
|
|
2012
|
-
topic: `le5le-iot/properties/${token}`,
|
|
2013
|
-
type: 'iot',
|
|
2014
|
-
url: net.url,
|
|
2015
|
-
method: 'mqtt',
|
|
2016
|
-
});
|
|
2017
|
-
});
|
|
2018
|
-
this.mqttClients[mqttIndex].on('error', (error) => {
|
|
2019
|
-
this.store.emitter.emit('error', { type: 'mqtt', error });
|
|
2020
|
-
});
|
|
2021
|
-
this.mqttClients[mqttIndex].subscribe(`le5le-iot/properties/${token}`);
|
|
2022
|
-
mqttIndex += 1;
|
|
2023
|
-
}
|
|
2024
|
-
else if (net.method === 'websocket') {
|
|
2025
|
-
net.index = websocketIndex;
|
|
2026
|
-
this.websockets[websocketIndex] = new WebSocket(`${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/api/ws/iot/properties`, token);
|
|
2027
|
-
this.websockets[websocketIndex].onmessage = (e) => {
|
|
2028
|
-
this.socketCallback(e.data, { type: 'iot', method: 'websocket' });
|
|
2029
|
-
};
|
|
2030
|
-
this.websockets[websocketIndex].onerror = (error) => {
|
|
2031
|
-
this.store.emitter.emit('error', { type: 'websocket', error });
|
|
2032
|
-
};
|
|
2033
|
-
websocketIndex += 1;
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
else if (net.protocol === 'sql') {
|
|
2037
|
-
await this.doSqlCode('list', net.dbId, net.sql);
|
|
2038
|
-
if (net.interval) {
|
|
2039
|
-
net.index = sqlIndex;
|
|
2040
|
-
this.sqlTimerList[sqlIndex] = setInterval(async () => {
|
|
2041
|
-
await this.doSqlCode('list', net.dbId, net.sql);
|
|
2042
|
-
}, net.interval);
|
|
2043
|
-
sqlIndex += 1;
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
2062
|
else if (net.protocol === 'ADIIOT') {
|
|
2047
2063
|
connectJetLinks(this, net);
|
|
2048
2064
|
}
|
|
2065
|
+
else if (net.protocol === 'SSE') {
|
|
2066
|
+
net.index = sseIndex;
|
|
2067
|
+
this.connectSSE(net);
|
|
2068
|
+
sseIndex += 1;
|
|
2069
|
+
}
|
|
2049
2070
|
});
|
|
2050
2071
|
}
|
|
2051
2072
|
this.onNetworkConnect(https);
|
|
2073
|
+
this.connectIot();
|
|
2074
|
+
this.connectSqls();
|
|
2075
|
+
}
|
|
2076
|
+
iotMqttClient;
|
|
2077
|
+
iotTimer;
|
|
2078
|
+
iotWebsocketClient;
|
|
2079
|
+
async connectIot() {
|
|
2080
|
+
const { iot } = this.store.data;
|
|
2081
|
+
if (!(iot && iot?.devices?.length)) {
|
|
2082
|
+
return;
|
|
2083
|
+
}
|
|
2084
|
+
const url = globalThis.iotUrl || await this.getMqttUrl();
|
|
2085
|
+
if (!url) {
|
|
2086
|
+
console.warn('iot Request address error');
|
|
2087
|
+
return;
|
|
2088
|
+
}
|
|
2089
|
+
const token = await this.getIotToken(iot.devices, iot.protocol === 'websocket' ? 1 : undefined);
|
|
2090
|
+
//物联网设备
|
|
2091
|
+
// if(iot.protocol === 'mqtt'){
|
|
2092
|
+
// const url ='ws://192.168.110.148:8083/mqtt'; //`${location.protocol === 'https:'?'wss':'ws'}://${iot.host}:${location.protocol === 'https:'?'8084':'8083'}/mqtt`
|
|
2093
|
+
this.iotMqttClient = mqtt.connect(url);
|
|
2094
|
+
this.iotMqttClient.on('message', (topic, message) => {
|
|
2095
|
+
this.socketCallback(message.toString(), {
|
|
2096
|
+
topic: `le5le-iot/properties/${token}`,
|
|
2097
|
+
type: 'iot',
|
|
2098
|
+
url,
|
|
2099
|
+
method: 'mqtt'
|
|
2100
|
+
});
|
|
2101
|
+
});
|
|
2102
|
+
this.iotMqttClient.on('error', (error) => {
|
|
2103
|
+
this.store.emitter.emit('error', { type: 'mqtt', error });
|
|
2104
|
+
});
|
|
2105
|
+
this.iotMqttClient.subscribe(`le5le-iot/properties/${token}`);
|
|
2106
|
+
this.iotTimer = setInterval(() => {
|
|
2107
|
+
this.iotMqttClient && this.iotMqttClient.publish(`le5le-iot/subscribe/ping`, token);
|
|
2108
|
+
}, 300000);
|
|
2109
|
+
// }else if(iot.protocol === 'websocket'){
|
|
2110
|
+
// const url = 'ws://192.168.110.6/api/ws/iot/properties'// `${location.protocol === 'https:'?'wss':'ws'}://${location.host}/api/ws/iot/properties`
|
|
2111
|
+
// this.iotWebsocketClient = new WebSocket(
|
|
2112
|
+
// url,
|
|
2113
|
+
// token
|
|
2114
|
+
// );
|
|
2115
|
+
// this.iotWebsocketClient.onmessage = (e) => {
|
|
2116
|
+
// this.socketCallback(e.data, { type: 'iot', method: 'websocket' });
|
|
2117
|
+
// };
|
|
2118
|
+
// this.iotWebsocketClient.onerror = (error) => {
|
|
2119
|
+
// this.store.emitter.emit('error', { type: 'websocket', error });
|
|
2120
|
+
// };
|
|
2121
|
+
// }
|
|
2122
|
+
}
|
|
2123
|
+
// type SqlType = 'list' | 'get' | 'exec' | 'add' | 'update' | 'delete';
|
|
2124
|
+
connectSqls() {
|
|
2125
|
+
const { sqls } = this.store.data;
|
|
2126
|
+
if (sqls && sqls.length) {
|
|
2127
|
+
let sqlIndex = 0;
|
|
2128
|
+
sqls.forEach(async (sql) => {
|
|
2129
|
+
await this.doSqlCode(sql);
|
|
2130
|
+
if (sql.interval) {
|
|
2131
|
+
sql.index = sqlIndex;
|
|
2132
|
+
this.sqlTimerList[sqlIndex] = setInterval(async () => {
|
|
2133
|
+
await this.doSqlCode(sql);
|
|
2134
|
+
}, sql.interval);
|
|
2135
|
+
sqlIndex += 1;
|
|
2136
|
+
}
|
|
2137
|
+
});
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
connectSSE(net) {
|
|
2141
|
+
this.eventSources[net.index] = new EventSource(net.url, { withCredentials: net.withCredentials });
|
|
2142
|
+
this.eventSources[net.index].onmessage = (e) => {
|
|
2143
|
+
this.socketCallback(e.data, { type: 'SSE', url: net.url });
|
|
2144
|
+
};
|
|
2145
|
+
this.eventSources[net.index].onerror = (error) => {
|
|
2146
|
+
this.store.emitter.emit('error', { type: 'SSE', error });
|
|
2147
|
+
};
|
|
2148
|
+
}
|
|
2149
|
+
closeSSE() {
|
|
2150
|
+
this.eventSources &&
|
|
2151
|
+
this.eventSources.forEach((es) => {
|
|
2152
|
+
if (es) {
|
|
2153
|
+
es.close();
|
|
2154
|
+
es = undefined;
|
|
2155
|
+
}
|
|
2156
|
+
});
|
|
2052
2157
|
}
|
|
2053
2158
|
connectNetWebSocket(net) {
|
|
2054
2159
|
if (this.websockets[net.index]) {
|
|
@@ -2080,28 +2185,59 @@ export class Meta2d {
|
|
|
2080
2185
|
}, 2000);
|
|
2081
2186
|
};
|
|
2082
2187
|
}
|
|
2083
|
-
async
|
|
2188
|
+
async getMqttUrl() {
|
|
2189
|
+
const res = await fetch('/api/iot/app/mqtt', {
|
|
2190
|
+
method: 'GET',
|
|
2191
|
+
headers: {
|
|
2192
|
+
Authorization: `Bearer ${getToken()}`,
|
|
2193
|
+
},
|
|
2194
|
+
});
|
|
2195
|
+
if (res.ok) {
|
|
2196
|
+
const data = await res.text();
|
|
2197
|
+
let results = JSON.parse(data);
|
|
2198
|
+
let port = results.wssPort || results.wsPort;
|
|
2199
|
+
if (!port) {
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
return `${location.protocol === 'https:' ? 'wss' : 'ws'}://${results.host}:${location.protocol === 'https:' ? results.wssPort : results.wsPort}${results.path}`;
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
async getIotToken(devices, type) {
|
|
2084
2206
|
const res = await fetch('/api/iot/subscribe/properties', {
|
|
2085
2207
|
method: 'POST',
|
|
2086
|
-
|
|
2208
|
+
headers: {
|
|
2209
|
+
Authorization: `Bearer ${getToken()}`,
|
|
2210
|
+
},
|
|
2211
|
+
body: JSON.stringify({ devices: devices, type }),
|
|
2087
2212
|
});
|
|
2088
2213
|
if (res.ok) {
|
|
2089
2214
|
const data = await res.text();
|
|
2090
2215
|
return JSON.parse(data).token;
|
|
2091
2216
|
}
|
|
2092
2217
|
}
|
|
2093
|
-
async doSqlCode(
|
|
2094
|
-
const
|
|
2218
|
+
async doSqlCode(sql) {
|
|
2219
|
+
const method = sql.method || 'get';
|
|
2220
|
+
let _sql = sql.sql;
|
|
2221
|
+
if (method === 'list') {
|
|
2222
|
+
_sql += ` LIMIT ${sql.pageSize || 20}` + (sql.current > 1 ? (' OFFSET ' + (sql.current - 1) * sql.pageSize) : '');
|
|
2223
|
+
}
|
|
2224
|
+
const res = await fetch(`/api/iot/data/sql/${method}`, {
|
|
2095
2225
|
method: 'POST',
|
|
2096
|
-
|
|
2226
|
+
headers: {
|
|
2227
|
+
Authorization: `Bearer ${getCookie('token') || localStorage.getItem('token') || new URLSearchParams(location.search).get('token') || ''}`,
|
|
2228
|
+
},
|
|
2229
|
+
body: JSON.stringify({ dbid: sql.dbid, sql: _sql, }),
|
|
2097
2230
|
});
|
|
2098
2231
|
if (res.ok) {
|
|
2099
|
-
|
|
2232
|
+
let data = await res.text();
|
|
2100
2233
|
if (data) {
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2234
|
+
const arr = [];
|
|
2235
|
+
data = JSON.parse(data);
|
|
2236
|
+
sql.keys?.forEach((key) => {
|
|
2237
|
+
arr.push({ id: sql.bindId + '#' + key, value: getter(data, key.split('#').join('.')) });
|
|
2104
2238
|
});
|
|
2239
|
+
arr.push({ id: sql.bindId, value: data });
|
|
2240
|
+
this.socketCallback(JSON.stringify(arr), { type: 'sql', url: `/api/iot/data/sql/${method}`, method });
|
|
2105
2241
|
}
|
|
2106
2242
|
}
|
|
2107
2243
|
}
|
|
@@ -2436,7 +2572,19 @@ export class Meta2d {
|
|
|
2436
2572
|
clearInterval(_sqlTimer);
|
|
2437
2573
|
_sqlTimer = undefined;
|
|
2438
2574
|
});
|
|
2575
|
+
if (this.iotMqttClient) {
|
|
2576
|
+
this.iotMqttClient.end();
|
|
2577
|
+
this.iotMqttClient = undefined;
|
|
2578
|
+
}
|
|
2579
|
+
clearInterval(this.iotTimer);
|
|
2580
|
+
this.iotTimer = undefined;
|
|
2581
|
+
// if(this.iotWebsocketClient){
|
|
2582
|
+
// this.iotWebsocketClient.onclose = undefined;
|
|
2583
|
+
// this.iotWebsocketClient.close();
|
|
2584
|
+
// this.iotWebsocketClient = undefined;
|
|
2585
|
+
// }
|
|
2439
2586
|
closeJetLinks(this);
|
|
2587
|
+
this.closeSSE();
|
|
2440
2588
|
}
|
|
2441
2589
|
socketCallback(message, context) {
|
|
2442
2590
|
this.store.emitter.emit('socket', { message, context });
|