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 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
- if (typeof(type) === 'function') {
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
- this.api = api;
41
- this.retries = 0;
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
- var t = this;
62
- var promise = new Promise(function(resolve, reject) {
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
- var t = this;
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
- var t = this;
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
- var t = this;
143
+ const t = this;
123
144
 
124
145
  if (!t.options.files)
125
146
  t.options.files = [];
126
147
 
127
- var obj = { name: name || ('file' + t.options.files.length), filename: filename, path: path };
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
- var t = this;
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
- var t = this;
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
- var conn = F.apiservices[cache[api.options.name]] || F.apiservices['*'];
188
- if (conn)
189
- conn.call(api, api.options, (err, response) => api.evaluate(err, response));
190
- else
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
- var api = new APICall();
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
- var req = {};
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
- var buffer = [];
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
- var type = response.headers['content-type'];
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
- var index = type.lastIndexOf(';');
325
+ const index = type.lastIndexOf(';');
296
326
  if (index !== -1)
297
327
  type = type.substring(0, index);
298
328
 
299
- var ext = type ? F.TUtils.getExtensionFromContentType(type) : 'bin';
300
- var id = fsdata[1] || UID();
301
- var filename = fsdata[2] || id + '.' + ext;
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
- var writer = F.Fs.createWriteStream(opt.output);
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
- $.status = self.options.status;
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 name = head.match(/name=".*?"/i)[0];
579
+ let uid = head.match(/id=".*?"/i);
579
580
  let template = html.substring(html.indexOf('>', endhead) + 1, endindex);
581
+ let name = '';
580
582
 
581
- name = name.substring(6, name.length - 1);
582
- html = html.replace(html.substring(begindex, endindex + 9), '~WIDGET#' + response.tangular.length + '~');
583
- response.tangular.push({ id: HASH(name).toString(36), name: name, type: 'nav', template: Tangular.compile(template) });
584
- index = begindex;
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 = ctrl.uri.search.parseEncoded());
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;
package/debug.js CHANGED
@@ -106,7 +106,6 @@ function runwatching() {
106
106
  skipbundle = true;
107
107
  F.directory = directory = F.path.join(directory, '.src');
108
108
  }
109
-
110
109
  } catch(e) {}
111
110
 
112
111
  const fork = F.Child.fork;