iobroker.prosoft_flow 0.1.0
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/README.md +79 -0
- package/admin/jsonConfig.json +778 -0
- package/admin/prosoft_flow.png +0 -0
- package/io-package.json +3272 -0
- package/lib/engineBridge.js +178 -0
- package/main.js +832 -0
- package/package.json +42 -0
- package/prebuilds/linux-arm64/prosoft_flow_engine.node.gz +0 -0
- package/prebuilds/linux-x64/prosoft_flow_engine.node.gz +0 -0
- package/prebuilds/osx-arm64/prosoft_flow_engine.node.gz +0 -0
- package/prebuilds/osx-x64/prosoft_flow_engine.node.gz +0 -0
- package/prebuilds/win-x64/prosoft_flow_engine.node.gz +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const path = require('node:path');
|
|
3
|
+
const fs = require('node:fs');
|
|
4
|
+
const zlib = require('node:zlib');
|
|
5
|
+
const os = require('node:os');
|
|
6
|
+
const crypto = require('node:crypto');
|
|
7
|
+
|
|
8
|
+
const PACKAGE_PREFIX = 'iobroker.prosoft_flow';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* node `process.platform`-`process.arch` -> the .NET RID that names prebuilds/<rid>/.
|
|
12
|
+
*/
|
|
13
|
+
function ridFor(platform, arch) {
|
|
14
|
+
return (
|
|
15
|
+
{
|
|
16
|
+
'win32-x64': 'win-x64',
|
|
17
|
+
'linux-x64': 'linux-x64',
|
|
18
|
+
'linux-arm64': 'linux-arm64',
|
|
19
|
+
'darwin-arm64': 'osx-arm64',
|
|
20
|
+
'darwin-x64': 'osx-x64',
|
|
21
|
+
}[`${platform}-${arch}`] || `${platform}-${arch}`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Artifact name inside publish directory.
|
|
27
|
+
*/
|
|
28
|
+
function devPublishName(platform) {
|
|
29
|
+
if (platform === 'win32') {
|
|
30
|
+
return 'prosoft_flow_engine.dll';
|
|
31
|
+
}
|
|
32
|
+
return platform === 'darwin' ? 'prosoft_flow_engine.dylib' : 'prosoft_flow_engine.so';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Decompresses <file>.gz if present.
|
|
37
|
+
*/
|
|
38
|
+
function decompress(gzPath, log) {
|
|
39
|
+
try {
|
|
40
|
+
const target = gzPath.slice(0, -3); // strip ".gz"
|
|
41
|
+
if (fs.existsSync(target) && fs.statSync(target).mtimeMs >= fs.statSync(gzPath).mtimeMs) {
|
|
42
|
+
return target;
|
|
43
|
+
}
|
|
44
|
+
const buf = zlib.gunzipSync(fs.readFileSync(gzPath));
|
|
45
|
+
try {
|
|
46
|
+
fs.writeFileSync(target, buf);
|
|
47
|
+
return target;
|
|
48
|
+
} catch {
|
|
49
|
+
const dir = path.join(os.tmpdir(), 'iobroker.prosoft_flow-engine');
|
|
50
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
51
|
+
const hash = crypto.createHash('sha256').update(buf).digest('hex').slice(0, 16);
|
|
52
|
+
const cached = path.join(dir, `prosoft_flow_engine-${hash}.node`);
|
|
53
|
+
if (!fs.existsSync(cached)) {
|
|
54
|
+
fs.writeFileSync(cached, buf);
|
|
55
|
+
}
|
|
56
|
+
return cached;
|
|
57
|
+
}
|
|
58
|
+
} catch (e) {
|
|
59
|
+
if (log && log.debug) {
|
|
60
|
+
log.debug(`engineBridge: could not decompress ${gzPath}: ${e.message}`);
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Loads the platform-specific AOT engine addon and returns its Engine surface.
|
|
68
|
+
*/
|
|
69
|
+
function load(log) {
|
|
70
|
+
const rid = ridFor(process.platform, process.arch);
|
|
71
|
+
const tried = [];
|
|
72
|
+
|
|
73
|
+
const prebuild = path.join(__dirname, '..', 'prebuilds', rid, 'prosoft_flow_engine.node');
|
|
74
|
+
const bundledGz = `${prebuild}.gz`;
|
|
75
|
+
const devPublish = path.join(
|
|
76
|
+
__dirname,
|
|
77
|
+
'..',
|
|
78
|
+
'native',
|
|
79
|
+
'ProsoftEngine.Node',
|
|
80
|
+
'bin',
|
|
81
|
+
'Release',
|
|
82
|
+
'net10.0',
|
|
83
|
+
rid,
|
|
84
|
+
'publish',
|
|
85
|
+
devPublishName(process.platform),
|
|
86
|
+
);
|
|
87
|
+
const devDebug = path.join(
|
|
88
|
+
__dirname,
|
|
89
|
+
'..',
|
|
90
|
+
'native',
|
|
91
|
+
'ProsoftEngine.Node',
|
|
92
|
+
'bin',
|
|
93
|
+
'Debug',
|
|
94
|
+
'net10.0',
|
|
95
|
+
devPublishName(process.platform),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// 1. Prebuild expanded binary
|
|
99
|
+
if (fs.existsSync(prebuild)) {
|
|
100
|
+
return unwrap(prebuild, log);
|
|
101
|
+
}
|
|
102
|
+
tried.push(prebuild);
|
|
103
|
+
|
|
104
|
+
// 2. Bundled compressed binary (.node.gz)
|
|
105
|
+
if (fs.existsSync(bundledGz)) {
|
|
106
|
+
const expanded = decompress(bundledGz, log);
|
|
107
|
+
if (expanded) {
|
|
108
|
+
return unwrap(expanded, log);
|
|
109
|
+
}
|
|
110
|
+
tried.push(`${bundledGz} (decompress failed)`);
|
|
111
|
+
} else {
|
|
112
|
+
tried.push(bundledGz);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// 3. Dev publish output (Release Native AOT)
|
|
116
|
+
if (fs.existsSync(devPublish)) {
|
|
117
|
+
return unwrap(devPublish, log);
|
|
118
|
+
}
|
|
119
|
+
tried.push(devPublish);
|
|
120
|
+
|
|
121
|
+
// 4. Dev debug output
|
|
122
|
+
if (fs.existsSync(devDebug)) {
|
|
123
|
+
return unwrap(devDebug, log);
|
|
124
|
+
}
|
|
125
|
+
tried.push(devDebug);
|
|
126
|
+
|
|
127
|
+
throw new Error(`Prosoft Flow Engine native addon not found for ${rid}; tried:\n${tried.join('\n')}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function unwrap(modulePath, log) {
|
|
131
|
+
if (log && log.debug) {
|
|
132
|
+
log.debug(`engineBridge: loading native module from ${modulePath}`);
|
|
133
|
+
}
|
|
134
|
+
const mod = require(modulePath);
|
|
135
|
+
if (!mod.Engine) {
|
|
136
|
+
throw new Error(`engineBridge: ${modulePath} has no Engine export`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const raw = mod.Engine;
|
|
140
|
+
return {
|
|
141
|
+
ping: () => (raw.ping ? raw.ping() : raw.Ping()),
|
|
142
|
+
version: () => (raw.version ? raw.version() : raw.Version()),
|
|
143
|
+
onEvent: (cb) => (raw.onEvent ? raw.onEvent(cb) : raw.OnEvent(cb)),
|
|
144
|
+
init: (cfg) => (raw.init ? raw.init(cfg) : raw.Init(cfg)),
|
|
145
|
+
start: () => (raw.start ? raw.start() : raw.Start()),
|
|
146
|
+
stop: () => (raw.stop ? raw.stop() : raw.Stop()),
|
|
147
|
+
write: (t, v) => (raw.write ? raw.write(t, v) : raw.Write(t, v)),
|
|
148
|
+
read: (t) => (raw.read ? raw.read(t) : raw.Read(t)),
|
|
149
|
+
getStats: () => (raw.getStats ? raw.getStats() : raw.GetStats()),
|
|
150
|
+
getReport: (r) => (raw.getReport ? raw.getReport(r) : raw.GetReport(r)),
|
|
151
|
+
readReportWithAge: (grp, age) => (raw.readReportWithAge ? raw.readReportWithAge(grp, age) : raw.ReadReportWithAge(grp, age)),
|
|
152
|
+
getLicenseInfo: (k) => (raw.getLicenseInfo ? raw.getLicenseInfo(k) : raw.GetLicenseInfo(k)),
|
|
153
|
+
setLicenseKey: (k) => (raw.setLicenseKey ? raw.setLicenseKey(k) : raw.SetLicenseKey(k)),
|
|
154
|
+
getLicenseState: () => (raw.getLicenseState ? raw.getLicenseState() : raw.GetLicenseState()),
|
|
155
|
+
getHardwareId: () => (raw.getHardwareId ? raw.getHardwareId() : raw.GetHardwareId()),
|
|
156
|
+
getEnvironmentType: () => (raw.getEnvironmentType ? raw.getEnvironmentType() : raw.GetEnvironmentType()),
|
|
157
|
+
|
|
158
|
+
// PascalCase aliases
|
|
159
|
+
Ping: () => (raw.ping ? raw.ping() : raw.Ping()),
|
|
160
|
+
Version: () => (raw.version ? raw.version() : raw.Version()),
|
|
161
|
+
OnEvent: (cb) => (raw.onEvent ? raw.onEvent(cb) : raw.OnEvent(cb)),
|
|
162
|
+
Init: (cfg) => (raw.init ? raw.init(cfg) : raw.Init(cfg)),
|
|
163
|
+
Start: () => (raw.start ? raw.start() : raw.Start()),
|
|
164
|
+
Stop: () => (raw.stop ? raw.stop() : raw.Stop()),
|
|
165
|
+
Write: (t, v) => (raw.write ? raw.write(t, v) : raw.Write(t, v)),
|
|
166
|
+
Read: (t) => (raw.read ? raw.read(t) : raw.Read(t)),
|
|
167
|
+
GetStats: () => (raw.getStats ? raw.getStats() : raw.GetStats()),
|
|
168
|
+
GetReport: (r) => (raw.getReport ? raw.getReport(r) : raw.GetReport(r)),
|
|
169
|
+
ReadReportWithAge: (grp, age) => (raw.readReportWithAge ? raw.readReportWithAge(grp, age) : raw.ReadReportWithAge(grp, age)),
|
|
170
|
+
GetLicenseInfo: (k) => (raw.getLicenseInfo ? raw.getLicenseInfo(k) : raw.GetLicenseInfo(k)),
|
|
171
|
+
SetLicenseKey: (k) => (raw.setLicenseKey ? raw.setLicenseKey(k) : raw.SetLicenseKey(k)),
|
|
172
|
+
GetLicenseState: () => (raw.getLicenseState ? raw.getLicenseState() : raw.GetLicenseState()),
|
|
173
|
+
GetHardwareId: () => (raw.getHardwareId ? raw.getHardwareId() : raw.GetHardwareId()),
|
|
174
|
+
GetEnvironmentType: () => (raw.getEnvironmentType ? raw.getEnvironmentType() : raw.GetEnvironmentType()),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
module.exports = { load, ridFor, devPublishName };
|