total5 0.0.15 → 0.0.16-10
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 +66 -28
- package/builders.js +63 -19
- package/changelog.txt +33 -0
- package/cms.js +22 -5
- package/controller.js +2 -2
- package/debug.js +2 -2
- package/edit.js +84 -45
- package/flow-flowstream.js +52 -15
- package/flow.js +1 -1
- package/global.js +6 -2
- package/index.js +55 -19
- package/jsonschema.js +1 -1
- package/package.json +1 -1
- package/routing.js +7 -7
- package/utils.js +114 -35
- package/websocket.js +22 -6
- package/workers.js +13 -13
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);
|
|
@@ -140,15 +161,20 @@ APICallProto.error = APICallProto.err = function(err, reverse) {
|
|
|
140
161
|
return this;
|
|
141
162
|
};
|
|
142
163
|
|
|
164
|
+
APICallProto.logerror = function() {
|
|
165
|
+
this.$loggerror = true;
|
|
166
|
+
return this;
|
|
167
|
+
};
|
|
168
|
+
|
|
143
169
|
APICallProto.callback = APICallProto.pipe = function($) {
|
|
144
|
-
|
|
170
|
+
const t = this;
|
|
145
171
|
t.$callback = typeof($) === 'function' ? $ : $.callback();
|
|
146
172
|
return t;
|
|
147
173
|
};
|
|
148
174
|
|
|
149
175
|
APICallProto.evaluate = function(err, response) {
|
|
150
176
|
|
|
151
|
-
|
|
177
|
+
const t = this;
|
|
152
178
|
if (!err && t.$error) {
|
|
153
179
|
if (t.$error_reverse) {
|
|
154
180
|
if (response)
|
|
@@ -161,6 +187,9 @@ APICallProto.evaluate = function(err, response) {
|
|
|
161
187
|
err = t.$error;
|
|
162
188
|
}
|
|
163
189
|
|
|
190
|
+
if (t.$logerror)
|
|
191
|
+
F.error(err, 'API: ' + t.options.name + ' --> ' + t.options.schema);
|
|
192
|
+
|
|
164
193
|
if (err) {
|
|
165
194
|
t.$callback_fail && t.$callback_fail(err);
|
|
166
195
|
} else {
|
|
@@ -176,16 +205,24 @@ APICallProto.evaluate = function(err, response) {
|
|
|
176
205
|
};
|
|
177
206
|
|
|
178
207
|
function execapi(api) {
|
|
179
|
-
|
|
180
|
-
if (conn)
|
|
181
|
-
|
|
182
|
-
|
|
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
|
|
183
220
|
api.evaluate('API is not initialized');
|
|
184
221
|
}
|
|
185
222
|
|
|
186
223
|
// Executes API
|
|
187
224
|
exports.exec = function(name, schema, data, $) {
|
|
188
|
-
|
|
225
|
+
const api = new APICall();
|
|
189
226
|
api.options.name = cache[name] || name;
|
|
190
227
|
api.options.schema = schema;
|
|
191
228
|
api.options.data = data;
|
|
@@ -204,7 +241,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
204
241
|
if (opt.data && typeof(opt.data) !== 'object')
|
|
205
242
|
opt.data = { value: opt.data };
|
|
206
243
|
|
|
207
|
-
|
|
244
|
+
const req = {};
|
|
208
245
|
|
|
209
246
|
req.method = 'POST';
|
|
210
247
|
req.url = 'https://' + F.config.$tapiurl + '.api.totaljs.com/' + opt.schema + '/';
|
|
@@ -218,7 +255,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
218
255
|
req.type = 'json';
|
|
219
256
|
req.timeout = 60000;
|
|
220
257
|
req.keepalive = true;
|
|
221
|
-
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) };
|
|
222
259
|
req.custom = true;
|
|
223
260
|
|
|
224
261
|
req.callback = function(err, response) {
|
|
@@ -228,7 +265,7 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
228
265
|
return;
|
|
229
266
|
}
|
|
230
267
|
|
|
231
|
-
|
|
268
|
+
const buffer = [];
|
|
232
269
|
|
|
233
270
|
// Error
|
|
234
271
|
if (response.status > 200) {
|
|
@@ -248,7 +285,8 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
248
285
|
if (opt.output === 'base64') {
|
|
249
286
|
output = output.toString('base64');
|
|
250
287
|
} else if (opt.output !== 'binary' && opt.output !== 'buffer') {
|
|
251
|
-
|
|
288
|
+
|
|
289
|
+
const type = response.headers['content-type'];
|
|
252
290
|
|
|
253
291
|
if (REG_BINARY.test(type)) {
|
|
254
292
|
next(null, output);
|
|
@@ -284,20 +322,20 @@ exports.newapi('TotalAPI,TAPI', function(opt, next) {
|
|
|
284
322
|
}
|
|
285
323
|
|
|
286
324
|
var type = (response.headers['content-type'] || '').toLowerCase();
|
|
287
|
-
|
|
325
|
+
const index = type.lastIndexOf(';');
|
|
288
326
|
if (index !== -1)
|
|
289
327
|
type = type.substring(0, index);
|
|
290
328
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
329
|
+
const ext = type ? F.TUtils.getExtensionFromContentType(type) : 'bin';
|
|
330
|
+
const id = fsdata[1] || UID();
|
|
331
|
+
const filename = fsdata[2] || id + '.' + ext;
|
|
294
332
|
|
|
295
333
|
response.stream.pause();
|
|
296
334
|
fs.save(id, filename, response.stream, next);
|
|
297
335
|
return;
|
|
298
336
|
}
|
|
299
337
|
|
|
300
|
-
|
|
338
|
+
const writer = F.Fs.createWriteStream(opt.output);
|
|
301
339
|
response.stream.pipe(writer);
|
|
302
340
|
F.cleanup(writer, () => opt.next(null, opt.output));
|
|
303
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) {
|
|
@@ -382,9 +388,10 @@ ErrorBuilder.prototype.push = function(err, path, index) {
|
|
|
382
388
|
return self;
|
|
383
389
|
};
|
|
384
390
|
|
|
385
|
-
ErrorBuilder.prototype.push2 = function(name, path, index) {
|
|
391
|
+
ErrorBuilder.prototype.push2 = function(name, path, index, error) {
|
|
386
392
|
let self = this;
|
|
387
|
-
|
|
393
|
+
|
|
394
|
+
self.items.push({ name: self.prefix + name, error: error || '@', path: path, index: index });
|
|
388
395
|
|
|
389
396
|
if (self.$throw) {
|
|
390
397
|
let errors = self.output();
|
|
@@ -563,7 +570,12 @@ RESTP.insecure = function() {
|
|
|
563
570
|
};
|
|
564
571
|
|
|
565
572
|
RESTP.error = function(err) {
|
|
566
|
-
this.$
|
|
573
|
+
this.$errormessage = err;
|
|
574
|
+
return this;
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
RESTP.logerror = function() {
|
|
578
|
+
this.$loggerror = true;
|
|
567
579
|
return this;
|
|
568
580
|
};
|
|
569
581
|
|
|
@@ -904,7 +916,7 @@ RESTP.exec = function(callback) {
|
|
|
904
916
|
if (!callback)
|
|
905
917
|
callback = NOOP;
|
|
906
918
|
|
|
907
|
-
|
|
919
|
+
let self = this;
|
|
908
920
|
|
|
909
921
|
if (self.operation) {
|
|
910
922
|
|
|
@@ -939,15 +951,15 @@ RESTP.exec = function(callback) {
|
|
|
939
951
|
self.$callback = callback;
|
|
940
952
|
|
|
941
953
|
if (restbuilderupgrades.length) {
|
|
942
|
-
for (
|
|
954
|
+
for (let i = 0; i < restbuilderupgrades.length; i++)
|
|
943
955
|
restbuilderupgrades[i](self);
|
|
944
956
|
}
|
|
945
957
|
|
|
946
|
-
|
|
958
|
+
let key;
|
|
947
959
|
|
|
948
960
|
if (self.$expire && !self.$nocache) {
|
|
949
961
|
key = 'restbuilder' + ((self.options.url || '') + (self.options.socketpath || '') + (self.options.path || '') + (self.options.body || '')).hash(true);
|
|
950
|
-
|
|
962
|
+
let data = F.cache.read(key);
|
|
951
963
|
if (data) {
|
|
952
964
|
data = data.value;
|
|
953
965
|
if (self.$resolve) {
|
|
@@ -1053,7 +1065,7 @@ function restbuilder_callback(err, response) {
|
|
|
1053
1065
|
if (val instanceof Array && val.length && val[0] && val[0].error)
|
|
1054
1066
|
err = ErrorBuilder.assign(val);
|
|
1055
1067
|
else
|
|
1056
|
-
err =
|
|
1068
|
+
err = (new ErrorBuilder()).push2(output.status, undefined, undefined, response.body);
|
|
1057
1069
|
}
|
|
1058
1070
|
|
|
1059
1071
|
if (!err && key)
|
|
@@ -1079,6 +1091,12 @@ function restbuilder_callback(err, response) {
|
|
|
1079
1091
|
val = jsresponse.response;
|
|
1080
1092
|
}
|
|
1081
1093
|
|
|
1094
|
+
if (err && self.$loggerror)
|
|
1095
|
+
F.error(new Error(response.body || err.toString()), 'RESTBuilder', self.options.method + ' ' + (self.options.url || self.options.path));
|
|
1096
|
+
|
|
1097
|
+
if (self.$errormessage && err)
|
|
1098
|
+
err = self.$errormessage;
|
|
1099
|
+
|
|
1082
1100
|
if (self.$resolve) {
|
|
1083
1101
|
|
|
1084
1102
|
if (err) {
|
|
@@ -1336,6 +1354,11 @@ ActionCaller.prototype.status = function(fn) {
|
|
|
1336
1354
|
return this;
|
|
1337
1355
|
};
|
|
1338
1356
|
|
|
1357
|
+
ActionCaller.prototype.progress = function(fn) {
|
|
1358
|
+
this.options.progress = fn;
|
|
1359
|
+
return this;
|
|
1360
|
+
};
|
|
1361
|
+
|
|
1339
1362
|
ActionCaller.prototype.exec = function() {
|
|
1340
1363
|
|
|
1341
1364
|
let self = this;
|
|
@@ -1382,6 +1405,8 @@ ActionCaller.prototype.exec = function() {
|
|
|
1382
1405
|
let type = meta.payload || (action.input ? '+' : '-');
|
|
1383
1406
|
let $ = self.$;
|
|
1384
1407
|
|
|
1408
|
+
$.$end = false;
|
|
1409
|
+
$.name = action.name;
|
|
1385
1410
|
$.id = action.id;
|
|
1386
1411
|
$.error = self.error;
|
|
1387
1412
|
$.controller = self.controller;
|
|
@@ -1392,9 +1417,19 @@ ActionCaller.prototype.exec = function() {
|
|
|
1392
1417
|
|
|
1393
1418
|
$.$callback = function(err, response) {
|
|
1394
1419
|
|
|
1420
|
+
if ($.$end)
|
|
1421
|
+
return;
|
|
1422
|
+
|
|
1423
|
+
$.$end = true;
|
|
1424
|
+
|
|
1425
|
+
if ($.$timeout) {
|
|
1426
|
+
clearTimeout($.$timeout);
|
|
1427
|
+
$.$timeout = null;
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1395
1430
|
if (!err) {
|
|
1396
1431
|
if (action.jsoutput)
|
|
1397
|
-
response = action.jsoutput.transform(response).response;
|
|
1432
|
+
response = action.jsoutput.transform(response).response || {};
|
|
1398
1433
|
|
|
1399
1434
|
if (action.extend) {
|
|
1400
1435
|
if (action.extend.includes('.'))
|
|
@@ -1458,7 +1493,7 @@ ActionCaller.prototype.exec = function() {
|
|
|
1458
1493
|
self.cancel();
|
|
1459
1494
|
return;
|
|
1460
1495
|
}
|
|
1461
|
-
$.query = response.response;
|
|
1496
|
+
$.query = response.response || {};
|
|
1462
1497
|
} else
|
|
1463
1498
|
$.query = query;
|
|
1464
1499
|
|
|
@@ -1470,7 +1505,7 @@ ActionCaller.prototype.exec = function() {
|
|
|
1470
1505
|
self.cancel();
|
|
1471
1506
|
return;
|
|
1472
1507
|
}
|
|
1473
|
-
$.params = response.response;
|
|
1508
|
+
$.params = response.response || {};
|
|
1474
1509
|
} else
|
|
1475
1510
|
$.params = params;
|
|
1476
1511
|
|
|
@@ -1480,12 +1515,21 @@ ActionCaller.prototype.exec = function() {
|
|
|
1480
1515
|
self.cancel();
|
|
1481
1516
|
return;
|
|
1482
1517
|
}
|
|
1483
|
-
$.payload = response.response;
|
|
1518
|
+
$.payload = response.response || {};
|
|
1484
1519
|
} else
|
|
1485
1520
|
$.payload = payload;
|
|
1486
1521
|
|
|
1487
1522
|
if (self.options.status)
|
|
1488
|
-
$.
|
|
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
|
+
}
|
|
1489
1533
|
|
|
1490
1534
|
if (action.middleware) {
|
|
1491
1535
|
action.middleware.wait(function(name, next) {
|
|
@@ -1511,9 +1555,9 @@ ActionCaller.prototype.finish = function(value) {
|
|
|
1511
1555
|
if (self.error.length)
|
|
1512
1556
|
$.invalid(self.error);
|
|
1513
1557
|
else
|
|
1514
|
-
$.callback(value === undefined ? self.$.response : value);
|
|
1558
|
+
$.callback.call($, value === undefined ? self.$.response : value);
|
|
1515
1559
|
} else
|
|
1516
|
-
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);
|
|
1517
1561
|
|
|
1518
1562
|
self.options.callback = null;
|
|
1519
1563
|
}
|
package/changelog.txt
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
|
+
========================
|
|
2
|
+
0.0.16
|
|
3
|
+
========================
|
|
4
|
+
|
|
5
|
+
- improved loading plugins
|
|
6
|
+
- framework reads a `/config` file in `plugins`
|
|
7
|
+
- added `RESTBuilder.?.logerror()` method for printing errors into the console
|
|
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
|
+
|
|
1
34
|
========================
|
|
2
35
|
0.0.15
|
|
3
36
|
========================
|
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;
|
package/debug.js
CHANGED
|
@@ -75,6 +75,7 @@ function runwatching() {
|
|
|
75
75
|
const REG_PUBLIC = /\/public\//i;
|
|
76
76
|
const REG_INDEX = new RegExp(FILENAME.replace(/\.js$/, '') + '_.*?\\.js$');
|
|
77
77
|
const REG_EXTENSION = /\.(js|ts|py|resource|package|bundle|build|flow|url|html)$/i;
|
|
78
|
+
const REG_CONFIG = /\/config$/
|
|
78
79
|
const REG_RELOAD = /\.(js|ts|py|css|html|htm|jpg|png|gif|ico|svg|webp|resource)$/i;
|
|
79
80
|
const isRELOAD = !!options.livereload;
|
|
80
81
|
const SPEED = isRELOAD ? 1000 : 1500;
|
|
@@ -105,7 +106,6 @@ function runwatching() {
|
|
|
105
106
|
skipbundle = true;
|
|
106
107
|
F.directory = directory = F.path.join(directory, '.src');
|
|
107
108
|
}
|
|
108
|
-
|
|
109
109
|
} catch(e) {}
|
|
110
110
|
|
|
111
111
|
const fork = F.Child.fork;
|
|
@@ -210,7 +210,7 @@ function runwatching() {
|
|
|
210
210
|
if (isdir)
|
|
211
211
|
return true;
|
|
212
212
|
|
|
213
|
-
if (!REG_PUBLIC.test(path) && REG_EXTENSION.test(path))
|
|
213
|
+
if (!REG_PUBLIC.test(path) && (REG_CONFIG.test(path) || REG_EXTENSION.test(path)))
|
|
214
214
|
return true;
|
|
215
215
|
|
|
216
216
|
return false;
|