total5 0.0.16-1 → 0.0.16-11
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/aimodel.js +143 -0
- package/api.js +58 -28
- package/builders.js +43 -11
- package/changelog.txt +30 -0
- package/cms.js +22 -5
- package/controller.js +2 -2
- package/debug.js +0 -1
- package/edit.js +84 -45
- package/flow-flowstream.js +52 -15
- package/flow.js +1 -1
- package/global.js +23 -9
- package/index.js +33 -14
- package/jsonschema.js +1 -1
- package/package.json +1 -1
- package/routing.js +7 -7
- package/utils.js +202 -49
- package/websocket.js +28 -9
- package/workers.js +14 -14
package/aimodel.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
// AI
|
|
2
|
+
// The MIT License
|
|
3
|
+
// Copyright 2026 (c) Peter Širka <petersirka@gmail.com>
|
|
4
|
+
|
|
5
|
+
function AI(model) {
|
|
6
|
+
const t = this;
|
|
7
|
+
|
|
8
|
+
t.options = {};
|
|
9
|
+
t.options.callback = NOOP;
|
|
10
|
+
t.config = {};
|
|
11
|
+
|
|
12
|
+
t.payload = {};
|
|
13
|
+
t.payload.model = model;
|
|
14
|
+
t.payload.messages = [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Enables think mode
|
|
18
|
+
AI.prototype.think = function () {
|
|
19
|
+
const t = this;
|
|
20
|
+
t.payload.think = true;
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// Internal function
|
|
25
|
+
// Appends content message
|
|
26
|
+
AI.prototype.message = function(role, content, merge) {
|
|
27
|
+
|
|
28
|
+
const t = this;
|
|
29
|
+
|
|
30
|
+
if (merge) {
|
|
31
|
+
for (let m of t.payload.messages) {
|
|
32
|
+
if (m.role === role) {
|
|
33
|
+
|
|
34
|
+
if (typeof(content) === 'object') {
|
|
35
|
+
for (let key in content)
|
|
36
|
+
m[key] = content[key];
|
|
37
|
+
} else
|
|
38
|
+
m.content += merge + content;
|
|
39
|
+
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const msg = { role: role };
|
|
46
|
+
|
|
47
|
+
if (typeof(content) === 'object') {
|
|
48
|
+
for (let key in content)
|
|
49
|
+
msg[key] = content[key];
|
|
50
|
+
} else
|
|
51
|
+
msg.content = content;
|
|
52
|
+
|
|
53
|
+
t.payload.messages.push(msg);
|
|
54
|
+
return t;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
AI.prototype.configure = function(opt) {
|
|
58
|
+
const t = this;
|
|
59
|
+
for (let key in opt)
|
|
60
|
+
t.config[key] = opt[key];
|
|
61
|
+
return t;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
AI.prototype.system = function(content, merge) {
|
|
65
|
+
return this.message('system', content, merge);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
AI.prototype.user = function(content, merge) {
|
|
69
|
+
return this.message('user', content, merge);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
AI.prototype.prompt = function(content) {
|
|
73
|
+
this.payload.prompt = content;
|
|
74
|
+
return this;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
AI.prototype.assistant = function(content, merge) {
|
|
78
|
+
return this.message('assistant', content, merge);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
AI.prototype.promise = function($) {
|
|
82
|
+
const t = this;
|
|
83
|
+
return new Promise(function(resolve, reject) {
|
|
84
|
+
t.callback(function(err, response) {
|
|
85
|
+
if (err) {
|
|
86
|
+
if ($ && $.invalid)
|
|
87
|
+
$.invalid(err);
|
|
88
|
+
else
|
|
89
|
+
reject(F.TUtils.toError(err));
|
|
90
|
+
} else
|
|
91
|
+
resolve(response);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
AI.prototype.stream = function(fn) {
|
|
97
|
+
const t = this;
|
|
98
|
+
t.options.stream = fn;
|
|
99
|
+
t.options.$running && clearImmediate(t.options.$running);
|
|
100
|
+
t.options.$running = setImmediate(() => t.run());
|
|
101
|
+
return t;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
AI.prototype.callback = function(fn) {
|
|
105
|
+
const t = this;
|
|
106
|
+
t.options.callback = fn;
|
|
107
|
+
t.options.$running && clearImmediate(t.options.$running);
|
|
108
|
+
t.options.$running = setImmediate(() => t.run());
|
|
109
|
+
return t;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// Internal function
|
|
113
|
+
AI.prototype.run = function() {
|
|
114
|
+
const t = this;
|
|
115
|
+
let ai = F.aimodels[t.payload.model];
|
|
116
|
+
if (ai) {
|
|
117
|
+
if (ai.config) {
|
|
118
|
+
for (let key in ai.config) {
|
|
119
|
+
if (t.config[key] === undefined)
|
|
120
|
+
t.config[key] = ai.config[key];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
ai.callback(t, t.options.callback);
|
|
124
|
+
} else
|
|
125
|
+
t.options.callback('AI model not found.');
|
|
126
|
+
return t;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
exports.exec = function(model) {
|
|
130
|
+
return new AI(model);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
exports.newai = function(model, config, callback) {
|
|
134
|
+
|
|
135
|
+
if (typeof(config) === 'function') {
|
|
136
|
+
callback = config;
|
|
137
|
+
config = null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const models = model.split(/,/).trim();
|
|
141
|
+
for (const m of models)
|
|
142
|
+
F.aimodels[m] = { config, callback };
|
|
143
|
+
};
|
package/api.js
CHANGED
|
@@ -10,17 +10,29 @@ const REG_TEXT = /^text\/(html|plain|xml)/;
|
|
|
10
10
|
var cache = {};
|
|
11
11
|
|
|
12
12
|
// Registers a new API type
|
|
13
|
-
exports.newapi = function(type, callback) {
|
|
13
|
+
exports.newapi = function(type, config, callback) {
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
let t = typeof(type);
|
|
16
|
+
|
|
17
|
+
if (t === 'function') {
|
|
16
18
|
callback = type;
|
|
17
19
|
type = 'default';
|
|
20
|
+
config = null;
|
|
21
|
+
} else if (t === 'object') {
|
|
22
|
+
callback = config;
|
|
23
|
+
config = type;
|
|
24
|
+
type = 'default';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (typeof(config) === 'function') {
|
|
28
|
+
callback = config;
|
|
29
|
+
config = null;
|
|
18
30
|
}
|
|
19
31
|
|
|
20
32
|
if (type.indexOf(',') !== -1) {
|
|
21
33
|
var arr = type.split(',').trim();
|
|
22
34
|
for (var m of arr)
|
|
23
|
-
exports.newapi(m, callback);
|
|
35
|
+
exports.newapi(m, config, callback);
|
|
24
36
|
return;
|
|
25
37
|
}
|
|
26
38
|
|
|
@@ -30,15 +42,17 @@ exports.newapi = function(type, callback) {
|
|
|
30
42
|
cache[lower] = lower;
|
|
31
43
|
|
|
32
44
|
if (callback)
|
|
33
|
-
F.apiservices[lower] = callback;
|
|
45
|
+
F.apiservices[lower] = { config, callback };
|
|
34
46
|
else
|
|
35
47
|
delete F.apiservices[lower];
|
|
36
48
|
|
|
37
49
|
};
|
|
38
50
|
|
|
39
51
|
function APIOptions(api) {
|
|
40
|
-
|
|
41
|
-
|
|
52
|
+
const t = this;
|
|
53
|
+
t.api = api;
|
|
54
|
+
t.retries = 0;
|
|
55
|
+
t.config = {};
|
|
42
56
|
}
|
|
43
57
|
|
|
44
58
|
APIOptions.prototype.retry = function() {
|
|
@@ -58,8 +72,8 @@ APICallProto.output = function(type) {
|
|
|
58
72
|
};
|
|
59
73
|
|
|
60
74
|
APICallProto.promise = function($) {
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
const t = this;
|
|
76
|
+
const promise = new Promise(function(resolve, reject) {
|
|
63
77
|
t.$callback = function(err, response) {
|
|
64
78
|
if (err) {
|
|
65
79
|
if ($ && $.invalid) {
|
|
@@ -75,7 +89,7 @@ APICallProto.promise = function($) {
|
|
|
75
89
|
};
|
|
76
90
|
|
|
77
91
|
APICallProto.audit = function($, message, type) {
|
|
78
|
-
|
|
92
|
+
const t = this;
|
|
79
93
|
t.$audit = function() {
|
|
80
94
|
// Dynamic arguments
|
|
81
95
|
if (message)
|
|
@@ -85,8 +99,15 @@ APICallProto.audit = function($, message, type) {
|
|
|
85
99
|
return t;
|
|
86
100
|
};
|
|
87
101
|
|
|
102
|
+
APICallProto.configure = function(opt) {
|
|
103
|
+
const t = this;
|
|
104
|
+
for (let key in opt)
|
|
105
|
+
t.options.config[key] = opt[key];
|
|
106
|
+
return t;
|
|
107
|
+
};
|
|
108
|
+
|
|
88
109
|
APICallProto.done = function($, callback) {
|
|
89
|
-
|
|
110
|
+
const t = this;
|
|
90
111
|
t.$callback = function(err, response) {
|
|
91
112
|
if (err)
|
|
92
113
|
$.invalid(err);
|
|
@@ -119,12 +140,12 @@ APICallProto.controller = function($) {
|
|
|
119
140
|
|
|
120
141
|
APICallProto.file = function(filename, path, name) {
|
|
121
142
|
|
|
122
|
-
|
|
143
|
+
const t = this;
|
|
123
144
|
|
|
124
145
|
if (!t.options.files)
|
|
125
146
|
t.options.files = [];
|
|
126
147
|
|
|
127
|
-
|
|
148
|
+
const obj = { name: name || ('file' + t.options.files.length), filename: filename, path: path };
|
|
128
149
|
|
|
129
150
|
if (t.options.files)
|
|
130
151
|
t.options.files.push(obj);
|
|
@@ -146,14 +167,14 @@ APICallProto.logerror = function() {
|
|
|
146
167
|
};
|
|
147
168
|
|
|
148
169
|
APICallProto.callback = APICallProto.pipe = function($) {
|
|
149
|
-
|
|
170
|
+
const t = this;
|
|
150
171
|
t.$callback = typeof($) === 'function' ? $ : $.callback();
|
|
151
172
|
return t;
|
|
152
173
|
};
|
|
153
174
|
|
|
154
175
|
APICallProto.evaluate = function(err, response) {
|
|
155
176
|
|
|
156
|
-
|
|
177
|
+
const t = this;
|
|
157
178
|
if (!err && t.$error) {
|
|
158
179
|
if (t.$error_reverse) {
|
|
159
180
|
if (response)
|
|
@@ -184,16 +205,24 @@ APICallProto.evaluate = function(err, response) {
|
|
|
184
205
|
};
|
|
185
206
|
|
|
186
207
|
function execapi(api) {
|
|
187
|
-
|
|
188
|
-
if (conn)
|
|
189
|
-
|
|
190
|
-
|
|
208
|
+
const conn = F.apiservices[cache[api.options.name]] || F.apiservices['*'];
|
|
209
|
+
if (conn) {
|
|
210
|
+
|
|
211
|
+
if (conn.config) {
|
|
212
|
+
for (let key in conn.config) {
|
|
213
|
+
if (api.options.config[key] === undefined)
|
|
214
|
+
api.options.config[key] = conn.config[key];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
conn.callback.call(api, api.options, (err, response) => api.evaluate(err, response));
|
|
219
|
+
} else
|
|
191
220
|
api.evaluate('API is not initialized');
|
|
192
221
|
}
|
|
193
222
|
|
|
194
223
|
// Executes API
|
|
195
224
|
exports.exec = function(name, schema, data, $) {
|
|
196
|
-
|
|
225
|
+
const api = new APICall();
|
|
197
226
|
api.options.name = cache[name] || name;
|
|
198
227
|
api.options.schema = schema;
|
|
199
228
|
api.options.data = data;
|
|
@@ -212,7 +241,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
212
241
|
if (opt.data && typeof(opt.data) !== 'object')
|
|
213
242
|
opt.data = { value: opt.data };
|
|
214
243
|
|
|
215
|
-
|
|
244
|
+
const req = {};
|
|
216
245
|
|
|
217
246
|
req.method = 'POST';
|
|
218
247
|
req.url = 'https://' + F.config.$tapiurl + '.api.totaljs.com/' + opt.schema + '/';
|
|
@@ -226,7 +255,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
226
255
|
req.type = 'json';
|
|
227
256
|
req.timeout = 60000;
|
|
228
257
|
req.keepalive = true;
|
|
229
|
-
req.headers = { 'x-token': opt.token || F.config.totalapi || F.config.secret_totalapi || F.config.$tapisecret || '-', 'x-app': encodeURIComponent(F.config.name) };
|
|
258
|
+
req.headers = { 'x-token': opt.token || opt.config.token || F.config.totalapi || F.config.secret_totalapi || F.config.$tapisecret || '-', 'x-app': encodeURIComponent(F.config.name) };
|
|
230
259
|
req.custom = true;
|
|
231
260
|
|
|
232
261
|
req.callback = function(err, response) {
|
|
@@ -236,7 +265,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
236
265
|
return;
|
|
237
266
|
}
|
|
238
267
|
|
|
239
|
-
|
|
268
|
+
const buffer = [];
|
|
240
269
|
|
|
241
270
|
// Error
|
|
242
271
|
if (response.status > 200) {
|
|
@@ -256,7 +285,8 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
256
285
|
if (opt.output === 'base64') {
|
|
257
286
|
output = output.toString('base64');
|
|
258
287
|
} else if (opt.output !== 'binary' && opt.output !== 'buffer') {
|
|
259
|
-
|
|
288
|
+
|
|
289
|
+
const type = response.headers['content-type'];
|
|
260
290
|
|
|
261
291
|
if (REG_BINARY.test(type)) {
|
|
262
292
|
next(null, output);
|
|
@@ -292,20 +322,20 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
292
322
|
}
|
|
293
323
|
|
|
294
324
|
var type = (response.headers['content-type'] || '').toLowerCase();
|
|
295
|
-
|
|
325
|
+
const index = type.lastIndexOf(';');
|
|
296
326
|
if (index !== -1)
|
|
297
327
|
type = type.substring(0, index);
|
|
298
328
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
329
|
+
const ext = type ? F.TUtils.getExtensionFromContentType(type) : 'bin';
|
|
330
|
+
const id = fsdata[1] || UID();
|
|
331
|
+
const filename = fsdata[2] || id + '.' + ext;
|
|
302
332
|
|
|
303
333
|
response.stream.pause();
|
|
304
334
|
fs.save(id, filename, response.stream, next);
|
|
305
335
|
return;
|
|
306
336
|
}
|
|
307
337
|
|
|
308
|
-
|
|
338
|
+
const writer = F.Fs.createWriteStream(opt.output);
|
|
309
339
|
response.stream.pipe(writer);
|
|
310
340
|
F.cleanup(writer, () => opt.next(null, opt.output));
|
|
311
341
|
};
|
package/builders.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Total.js Builders
|
|
2
2
|
// The MIT License
|
|
3
|
-
// Copyright 2023 (c) Peter Širka <petersirka@gmail.com>
|
|
3
|
+
// Copyright 2023-2026 (c) Peter Širka <petersirka@gmail.com>
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
@@ -153,7 +153,13 @@ Options.prototype.promisify = function(fn, a, b, c) {
|
|
|
153
153
|
});
|
|
154
154
|
};
|
|
155
155
|
|
|
156
|
-
Options.prototype.status = function() {
|
|
156
|
+
Options.prototype.status = function(a, b, c, d) {
|
|
157
|
+
this.status2?.call(this, a, b, c, d);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
Options.prototype.progress = function(a, b, c, d) {
|
|
161
|
+
this.progress2?.call(this, a, b, c, d);
|
|
162
|
+
};
|
|
157
163
|
|
|
158
164
|
Options.prototype.publish = function(value) {
|
|
159
165
|
var self = this;
|
|
@@ -241,7 +247,7 @@ Options.prototype.successful = function(callback) {
|
|
|
241
247
|
};
|
|
242
248
|
};
|
|
243
249
|
|
|
244
|
-
Options.prototype.callback = Options.prototype.pipe = function(value) {
|
|
250
|
+
Options.prototype.callback = Options.prototype.output = Options.prototype.pipe = function(value) {
|
|
245
251
|
|
|
246
252
|
var self = this;
|
|
247
253
|
|
|
@@ -252,7 +258,7 @@ Options.prototype.callback = Options.prototype.pipe = function(value) {
|
|
|
252
258
|
};
|
|
253
259
|
}
|
|
254
260
|
|
|
255
|
-
self.$callback(self.error.items.length ? self.error : null, value);
|
|
261
|
+
self.$callback.call(self, self.error.items.length ? self.error : null, value);
|
|
256
262
|
};
|
|
257
263
|
|
|
258
264
|
Options.prototype.done = function(arg) {
|
|
@@ -1348,6 +1354,11 @@ ActionCaller.prototype.status = function(fn) {
|
|
|
1348
1354
|
return this;
|
|
1349
1355
|
};
|
|
1350
1356
|
|
|
1357
|
+
ActionCaller.prototype.progress = function(fn) {
|
|
1358
|
+
this.options.progress = fn;
|
|
1359
|
+
return this;
|
|
1360
|
+
};
|
|
1361
|
+
|
|
1351
1362
|
ActionCaller.prototype.exec = function() {
|
|
1352
1363
|
|
|
1353
1364
|
let self = this;
|
|
@@ -1394,6 +1405,8 @@ ActionCaller.prototype.exec = function() {
|
|
|
1394
1405
|
let type = meta.payload || (action.input ? '+' : '-');
|
|
1395
1406
|
let $ = self.$;
|
|
1396
1407
|
|
|
1408
|
+
$.$end = false;
|
|
1409
|
+
$.name = action.name;
|
|
1397
1410
|
$.id = action.id;
|
|
1398
1411
|
$.error = self.error;
|
|
1399
1412
|
$.controller = self.controller;
|
|
@@ -1404,9 +1417,19 @@ ActionCaller.prototype.exec = function() {
|
|
|
1404
1417
|
|
|
1405
1418
|
$.$callback = function(err, response) {
|
|
1406
1419
|
|
|
1420
|
+
if ($.$end)
|
|
1421
|
+
return;
|
|
1422
|
+
|
|
1423
|
+
$.$end = true;
|
|
1424
|
+
|
|
1425
|
+
if ($.$timeout) {
|
|
1426
|
+
clearTimeout($.$timeout);
|
|
1427
|
+
$.$timeout = null;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1407
1430
|
if (!err) {
|
|
1408
1431
|
if (action.jsoutput)
|
|
1409
|
-
response = action.jsoutput.transform(response).response;
|
|
1432
|
+
response = action.jsoutput.transform(response).response || {};
|
|
1410
1433
|
|
|
1411
1434
|
if (action.extend) {
|
|
1412
1435
|
if (action.extend.includes('.'))
|
|
@@ -1470,7 +1493,7 @@ ActionCaller.prototype.exec = function() {
|
|
|
1470
1493
|
self.cancel();
|
|
1471
1494
|
return;
|
|
1472
1495
|
}
|
|
1473
|
-
$.query = response.response;
|
|
1496
|
+
$.query = response.response || {};
|
|
1474
1497
|
} else
|
|
1475
1498
|
$.query = query;
|
|
1476
1499
|
|
|
@@ -1482,7 +1505,7 @@ ActionCaller.prototype.exec = function() {
|
|
|
1482
1505
|
self.cancel();
|
|
1483
1506
|
return;
|
|
1484
1507
|
}
|
|
1485
|
-
$.params = response.response;
|
|
1508
|
+
$.params = response.response || {};
|
|
1486
1509
|
} else
|
|
1487
1510
|
$.params = params;
|
|
1488
1511
|
|
|
@@ -1492,12 +1515,21 @@ ActionCaller.prototype.exec = function() {
|
|
|
1492
1515
|
self.cancel();
|
|
1493
1516
|
return;
|
|
1494
1517
|
}
|
|
1495
|
-
$.payload = response.response;
|
|
1518
|
+
$.payload = response.response || {};
|
|
1496
1519
|
} else
|
|
1497
1520
|
$.payload = payload;
|
|
1498
1521
|
|
|
1499
1522
|
if (self.options.status)
|
|
1500
|
-
$.
|
|
1523
|
+
$.status2 = self.options.status;
|
|
1524
|
+
|
|
1525
|
+
if (self.options.progress)
|
|
1526
|
+
$.progress2 = self.options.progress;
|
|
1527
|
+
|
|
1528
|
+
if (action.timeout) {
|
|
1529
|
+
$.$timeout = setTimeout(function() {
|
|
1530
|
+
$.invalid('Timeout.');
|
|
1531
|
+
}, action.timeout);
|
|
1532
|
+
}
|
|
1501
1533
|
|
|
1502
1534
|
if (action.middleware) {
|
|
1503
1535
|
action.middleware.wait(function(name, next) {
|
|
@@ -1523,9 +1555,9 @@ ActionCaller.prototype.finish = function(value) {
|
|
|
1523
1555
|
if (self.error.length)
|
|
1524
1556
|
$.invalid(self.error);
|
|
1525
1557
|
else
|
|
1526
|
-
$.callback(value === undefined ? self.$.response : value);
|
|
1558
|
+
$.callback.call($, value === undefined ? self.$.response : value);
|
|
1527
1559
|
} else
|
|
1528
|
-
self.options.callback(self.error.length ? self.error : null, value === undefined ? self.$.response : value);
|
|
1560
|
+
self.options.callback.call(self.$, self.error.length ? self.error : null, value === undefined ? self.$.response : value);
|
|
1529
1561
|
|
|
1530
1562
|
self.options.callback = null;
|
|
1531
1563
|
}
|
package/changelog.txt
CHANGED
|
@@ -6,6 +6,36 @@
|
|
|
6
6
|
- framework reads a `/config` file in `plugins`
|
|
7
7
|
- added `RESTBuilder.?.logerror()` method for printing errors into the console
|
|
8
8
|
- added `API.?.logerror()` method for printing errors into the console
|
|
9
|
+
- fixed handling of unexpected problems in the Flow with the main process becoming disconnected
|
|
10
|
+
- fixed `uptime` value in the framework stats
|
|
11
|
+
- improved auditlogs by adding `files`
|
|
12
|
+
- fixed unexpected errors when compressing/decompressing data via WebSocket
|
|
13
|
+
- fixed processing TMS data in the FlowStream
|
|
14
|
+
- added a new config key `CONF.$httpcacheoffset` for extending `last-modified` header
|
|
15
|
+
- exended `Total.download()` by adding `size {Number}` property to the response
|
|
16
|
+
- extended FlowStream by adding the ability to execute Total.js actions
|
|
17
|
+
- added a new global event `ON('flowstream', function(instance) {`
|
|
18
|
+
- added new action methods `$.progress(percentage)` and `ACTION().progress(console.log)` to measure percentage
|
|
19
|
+
- fixed Total error handling
|
|
20
|
+
- improved compiling navigation in the CMS compiler
|
|
21
|
+
- fixed filling of the `template` property in the CMS compiler
|
|
22
|
+
- added a new method `U.aistreamer(on_line, on_message)`
|
|
23
|
+
- added `Flow.edit(proxy_socket_url)` method for the remote editing of the FlowStream
|
|
24
|
+
- added a new global methods `AIMODEL()` and `NEWAIMODEL()`
|
|
25
|
+
- added `exec` command to the remote editing functionality
|
|
26
|
+
- always set `cwd` directory for the current executed script
|
|
27
|
+
- added `timeout {Number}` property into the `NEWACTION` method
|
|
28
|
+
- extended `NEWAPI(type, [config], config)` by adding the `config` argument
|
|
29
|
+
- replaced `Url.parse()` with `new URL()`
|
|
30
|
+
- fixed `NEWFORK()` method
|
|
31
|
+
- fixed callback with `$` in the `ACTION().callback($)`
|
|
32
|
+
- fixed returing a default JSON schema object in actions
|
|
33
|
+
- added support for nested inline action schemas in action schemas
|
|
34
|
+
- fixed loading of `totalapi` key via `LOADCONFIG()`
|
|
35
|
+
- changed `SIGTERM` for `SIGKILL` in the `NEWFORK()` method
|
|
36
|
+
- extended `data` object in the `DEF.onAudit` delegate by adding `sessionid {String}` property
|
|
37
|
+
- fixed promise in the `AJAX()` method
|
|
38
|
+
- added `options.timeout {Number}` to the `WebSocketClient`
|
|
9
39
|
|
|
10
40
|
========================
|
|
11
41
|
0.0.15
|
package/cms.js
CHANGED
|
@@ -548,6 +548,7 @@ exports.compile = function(html, widgets, used) {
|
|
|
548
548
|
opt.html = body.substring(body.lastIndexOf('~BEG~') + 5, body.lastIndexOf('~END~'));
|
|
549
549
|
opt.config = config || EMPTYOBJECT;
|
|
550
550
|
opt.render = widget.render;
|
|
551
|
+
opt.template = widget.ui ? widget.ui.template : '';
|
|
551
552
|
opt.beg = opt.body.substring(0, opt.body.indexOf('>') + 1);
|
|
552
553
|
opt.end = opt.body.substring(opt.body.lastIndexOf('<'));
|
|
553
554
|
|
|
@@ -575,14 +576,30 @@ exports.compile = function(html, widgets, used) {
|
|
|
575
576
|
let endindex = html.indexOf('</script>', index);
|
|
576
577
|
let endhead = html.indexOf('>', index);
|
|
577
578
|
let head = html.substring(begindex, endhead);
|
|
578
|
-
let
|
|
579
|
+
let uid = head.match(/id=".*?"/i);
|
|
579
580
|
let template = html.substring(html.indexOf('>', endhead) + 1, endindex);
|
|
581
|
+
let name = '';
|
|
580
582
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
583
|
+
if (uid && uid[0]) {
|
|
584
|
+
uid = uid[0];
|
|
585
|
+
uid = uid.substring(4, uid.length - 1);
|
|
586
|
+
name = uid.capitalize();
|
|
587
|
+
} else {
|
|
588
|
+
uid = head.match(/name=".*?"/i);
|
|
589
|
+
if (uid && uid[0]) {
|
|
590
|
+
uid = uid[0];
|
|
591
|
+
uid = uid.substring(6, uid.length - 1);
|
|
592
|
+
name = uid.capitalize();
|
|
593
|
+
uid = HASH(uid).toString(36); // Backward compatibility with old CMS
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (name) {
|
|
598
|
+
html = html.replace(html.substring(begindex, endindex + 9), '~WIDGET#' + response.tangular.length + '~');
|
|
599
|
+
response.tangular.push({ id: uid, name: name, type: 'nav', template: Tangular.compile(template) });
|
|
600
|
+
}
|
|
585
601
|
|
|
602
|
+
index = begindex;
|
|
586
603
|
}
|
|
587
604
|
|
|
588
605
|
index = 0;
|
package/controller.js
CHANGED
|
@@ -115,7 +115,7 @@ function Controller(req, res) {
|
|
|
115
115
|
Controller.prototype = {
|
|
116
116
|
|
|
117
117
|
get query() {
|
|
118
|
-
return this.$query || (this.$query =
|
|
118
|
+
return this.$query || (this.$query = this.uri.search.parseEncoded());
|
|
119
119
|
},
|
|
120
120
|
|
|
121
121
|
set query(val) {
|
|
@@ -1617,7 +1617,7 @@ function send_file(ctrl, path, ext) {
|
|
|
1617
1617
|
ctrl.response.headers['cache-control'] = NOCACHE;
|
|
1618
1618
|
|
|
1619
1619
|
if (!cache)
|
|
1620
|
-
cache = { date: stats.mtime.toUTCString(), size: stats.size };
|
|
1620
|
+
cache = { date: (CONF.$httpcacheoffset ? stats.mtime.add(CONF.$httpcacheoffset) : stats.mtime).toUTCString(), size: stats.size };
|
|
1621
1621
|
|
|
1622
1622
|
ctrl.response.headers['last-modified'] = cache.date;
|
|
1623
1623
|
ctrl.response.headers.etag = '858' + F.config.$httpetag;
|