total5 0.0.7-2 → 0.0.7

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/changelog.txt CHANGED
@@ -9,6 +9,16 @@
9
9
  - added `$.ctrl(ctrl_instance)` method
10
10
  - extended `Mail.from(email, [name])` method by adding `name` argument by [Marek Mráz](https://github.com/Mrazbb)
11
11
  - added `CONF.mail_from_name {String}` option
12
+ - improved `$.query` parser
13
+ - improved `Total.run()` method
14
+ - added a new method `NEWCOMPONENT(html_or_URL_or_name, [callback])`
15
+ - it compiles a FlowStream component to a method
16
+ - extended FlowStream by adding support for `input` and `output` Total.js inline schemas
17
+ - fixed memory usage in the Flow in non-worker mode
18
+ - improved Flow error handling
19
+ - improved HTML parser
20
+ - improved `controller.view()` supports calling without arguments
21
+ - extended ViewEngine by adding `view.renderlayout(name, content)` method
12
22
 
13
23
  ========================
14
24
  0.0.6
package/components.js ADDED
@@ -0,0 +1,381 @@
1
+ 'use strict';
2
+
3
+ const REG_ARGS = /\{{1,2}[a-z0-9_.-\s]+\}{1,2}/gi;
4
+
5
+ function variables(str, data, encoding) {
6
+
7
+ if (typeof(str) === 'object') {
8
+ var obj = {};
9
+ for (var key in str) {
10
+ var val = str[key];
11
+ if (typeof(val) === 'string')
12
+ obj[key] = variables.call(this, val, data, encoding);
13
+ else
14
+ obj[key] = val;
15
+ }
16
+ return obj;
17
+ }
18
+
19
+ if (typeof(str) !== 'string' || str.indexOf('{') === -1)
20
+ return str;
21
+
22
+ var main = this.instance ? this.instance.module : (this.module || this);
23
+
24
+ if (data == null || data == true)
25
+ data = this;
26
+
27
+ return str.replace(REG_ARGS, function(text) {
28
+
29
+ var l = text[1] === '{' ? 2 : 1;
30
+ var key = text.substring(l, text.length - l).trim();
31
+ var val = null;
32
+
33
+ if (main.variables)
34
+ val = main.variables[key];
35
+
36
+ if (!val && main.variables2)
37
+ val = main.variables2[key];
38
+
39
+ if (!val && main.secrets)
40
+ val = main.secrets[key];
41
+
42
+ /*
43
+ if (!val && key === 'hostname') {
44
+ val = '';
45
+ if (val[val.length - 1] === '/')
46
+ val = val.substring(0, val.length - 1);
47
+ }*/
48
+
49
+ var customencoding = typeof(encoding) === 'function';
50
+
51
+ if (!val && data != null && typeof(data) === 'object') {
52
+ var nested = key.indexOf('.') !== -1;
53
+ val = nested ? F.TUtils.get(data, key) : data[key];
54
+ }
55
+
56
+ if (customencoding) {
57
+
58
+ val = encoding(val, key);
59
+
60
+ } else {
61
+
62
+ if (encoding !== 'json') {
63
+ if (val instanceof Date)
64
+ val = val.format();
65
+ }
66
+
67
+ switch (encoding) {
68
+ case 'urlencoded':
69
+ case 'url':
70
+ val = encodeURIComponent(val);
71
+ break;
72
+ case 'json':
73
+ val = JSON.stringify(val);
74
+ break;
75
+ case 'querify':
76
+ val = F.TUtils.querify(val).substring(1);
77
+ break;
78
+ }
79
+ }
80
+
81
+ return val == null ? text : val;
82
+
83
+ });
84
+ }
85
+
86
+ function Component() {
87
+ let t = this;
88
+ t.variables = t.variables2 = {};
89
+ t.secrets = {};
90
+ t.instances = [];
91
+ t.debugger = true;
92
+ }
93
+
94
+ Component.prototype.service = function(counter) {
95
+ for (let m of this.instances)
96
+ m.service && m.service(counter);
97
+ };
98
+
99
+ Component.prototype.status = function(instance, msg) {
100
+ if (t.debugger)
101
+ console.log('STATUS', this.name, msg);
102
+ };
103
+
104
+ Component.prototype.debug = function(instance, msg) {
105
+ if (t.debugger)
106
+ console.log('DEBUG', this.name + ':', msg);
107
+ };
108
+
109
+ Component.prototype.dashboard = function(instance, msg) {
110
+ if (t.debugger)
111
+ console.log('DASHBOARD', this.name + ':', msg);
112
+ };
113
+
114
+ Component.prototype.throw = function(instance, err) {
115
+ if (t.debugger)
116
+ console.log('ERROR', this.name + ':', err);
117
+ };
118
+
119
+ Component.prototype.output = function(instance, response) {
120
+ if (t.debugger)
121
+ console.log('OUTPUT', this.name + ' | ' + response.output + ':', response.data);
122
+ };
123
+
124
+ Component.prototype.create = function(opt, status) {
125
+
126
+ let t = this;
127
+ let instance = new Instance();
128
+ instance.id = U.random_text(8);
129
+ instance.config = t.config ? F.TUtils.clone(t.config) : {};
130
+ instance.module = t;
131
+
132
+ if (opt) {
133
+ for (let key in opt)
134
+ instance.config[key] = opt[key];
135
+ }
136
+
137
+ t.instances.push(instance);
138
+ t.onextend && t.onextend(instance);
139
+ t.make.call(instance, instance, instance.config, status);
140
+ t.oncreate && setImmediate(() => t.oncreate(instance));
141
+ return instance;
142
+ };
143
+
144
+ Component.prototype.remove = function() {
145
+ let t = this;
146
+ t.instances.wait(function(instance, next) {
147
+ instance.remove();
148
+ setImmediate(next);
149
+ }, function() {
150
+ t.uninstall && t.uninstall.call(t, t);
151
+ });
152
+ };
153
+
154
+ Component.prototype.save = function(instance) {
155
+ // save state
156
+ };
157
+
158
+ function Message() {
159
+ let t = this;
160
+ t.repo = {};
161
+ t.vars = {};
162
+ t.used = 1;
163
+ t.main = null;
164
+ t.processed = 0;
165
+ }
166
+
167
+ Message.prototype.replace = variables;
168
+
169
+ Message.prototype.send = function(output, data) {
170
+ let t = this;
171
+ if (!t.instance)
172
+ return;
173
+ if (data != null)
174
+ t.data = data;
175
+ t.output = output;
176
+ t.callback && t.callback(t);
177
+ t.instance.output && t.instance.output(t);
178
+ };
179
+
180
+ Message.prototype.end = Message.prototype.destroy = function() {
181
+ let t = this;
182
+ t.data = null;
183
+ t.fromcomponent = null;
184
+ t.instance = null;
185
+ t.vars = null;
186
+ t.repo = null;
187
+ t.refs = null;
188
+ }
189
+
190
+ function Instance() {
191
+ let t = this;
192
+ t.id = U.random_text(8);
193
+ t.cache = {};
194
+ t.middleware = NOOP;
195
+ t.transform = NOOP;
196
+ t.replace = variables;
197
+ t.instances = EMPTYOBJECT;
198
+ t.components = EMPTYOBJECT;
199
+ }
200
+
201
+ Instance.prototype.replace = variables;
202
+
203
+ Instance.prototype.remove = function() {
204
+ let t = this;
205
+ t.close && t.close.call(t, true);
206
+ t.destroy && t.destroy.call(t);
207
+ t.module.onremove && t.module.onremove(t);
208
+ let index = t.module.instances.indexOf(t);
209
+ t.module.instances.splice(index, 1);
210
+ };
211
+
212
+ Instance.prototype.input = function(input, data, callback) {
213
+ let t = this;
214
+ if (t.message) {
215
+
216
+ let msg = t.newmessage(data);
217
+ msg.input = input;
218
+ msg.callback = callback;
219
+
220
+ var schema = t.module.inputschemas[input];
221
+ if (schema) {
222
+ let tmp = schema.transform(msg.data);
223
+ msg.data = tmp.response;
224
+ msg.error = tmp.error;
225
+ }
226
+
227
+ t.message(msg);
228
+ let fn = t['message_' + input];
229
+ fn && fn(msg);
230
+ }
231
+ };
232
+
233
+ Instance.prototype.send = function(output, data) {
234
+ let msg = data instanceof Message ? data : this.newmessage();
235
+ msg.output = output;
236
+ msg.data = data;x
237
+ msg.send(output);
238
+ };
239
+
240
+ Instance.prototype.newmessage = function(data) {
241
+ var t = this;
242
+ var msg = new Message();
243
+ msg.from = msg.instance = t;
244
+ msg.fromid = msg.id;
245
+ msg.fromcomponent = msg.component;
246
+ msg.data = data instanceof Message ? data.data : data;
247
+ return msg;
248
+ };
249
+
250
+ Instance.prototype.save = function() {
251
+ this.module.save(this);
252
+ };
253
+
254
+ Instance.prototype.output = function(response) {
255
+ this.module.output(this, response);
256
+ };
257
+
258
+ Instance.prototype.debug = function(msg) {
259
+ this.module.debug(this, msg);
260
+ };
261
+
262
+ Instance.prototype.throw = function(err) {
263
+ this.module.throw(this, error);
264
+ };
265
+
266
+ Instance.prototype.dashboard = function(msg) {
267
+ this.module.dashboard(this, msg);
268
+ };
269
+
270
+ Instance.prototype.reconfigure = function(opt) {
271
+ let t = this;
272
+ for (let key in opt)
273
+ t.config[key] = opt[key];
274
+ t.configure && t.configure(t.config);
275
+ t.save();
276
+ };
277
+
278
+ Instance.prototype.status = function(msg) {
279
+ this.module.status(this, msg);
280
+ };
281
+
282
+ Instance.prototype.logger = NOOP;
283
+ Instance.prototype.transform = NOOP;
284
+ Instance.prototype.middleware = NOOP;
285
+
286
+ exports.compile = function(html, callback) {
287
+
288
+ if (callback == null) {
289
+ return new Promise(function(resolve, reject) {
290
+ exports.compile(html, function(err, com) {
291
+ if (err)
292
+ reject(err);
293
+ else
294
+ resolve(com);
295
+ });
296
+ })
297
+ }
298
+
299
+ if ((/^http(s)\:\/\//i).test(html)) {
300
+ let opt = {};
301
+ opt.url = html;
302
+ opt.callback = function(err, response) {
303
+ console.log(err, response);
304
+ if (err)
305
+ callback(err);
306
+ else
307
+ exports.compile(response.body, callback);
308
+ };
309
+ REQUEST(opt);
310
+ return;
311
+ }
312
+
313
+ if (!html.includes('<')) {
314
+ F.Fs.readFile(PATH.root('components/' + html + '.html'), 'utf8', function(err, response) {
315
+ if (err)
316
+ callback(err);
317
+ else
318
+ exports.compile(response, callback);
319
+ });
320
+ return;
321
+ }
322
+
323
+ var meta = html.parseComponent({ readme: '<readme>', settings: '<settings>', css: '<style>', be: '<script total>', be2: '<script node>', js: '<script>', html: '<body>', schema: '<schema>', template: '<template>' });
324
+ var node = (meta.be || meta.be2 || '').trim().replace(/\n\t/g, '\n');
325
+
326
+ if (!meta.be && !meta.be2) {
327
+ var e = new Error('Invalid component content');
328
+ callback(e);
329
+ return;
330
+ }
331
+
332
+ var fn = null;
333
+ var com = new Component();
334
+
335
+ delete meta.be;
336
+ delete meta.be2;
337
+ com.ui = meta;
338
+
339
+ try {
340
+ fn = new Function('exports', 'require', node);
341
+ fn(com, F.require);
342
+ } catch (e) {
343
+ callback(e);
344
+ return;
345
+ }
346
+
347
+ var errors = [];
348
+
349
+ (com.npm || EMPTYARRAY).wait(function(name, next) {
350
+ NPMINSTALL(name, function(err) {
351
+ if (err) {
352
+ callback(err);
353
+ next = null;
354
+ } else
355
+ next();
356
+ });
357
+ }, function() {
358
+
359
+ com.inputschemas = {};
360
+ com.outputschemas = {};
361
+
362
+ if (com.inputs) {
363
+ for (let m of com.inputs) {
364
+ if (m.schema)
365
+ com.inputschemas[m.id] = m.schema.toJSONSchema();
366
+ }
367
+ }
368
+
369
+ if (com.outputs) {
370
+ for (let m of com.outputs) {
371
+ if (m.schema)
372
+ com.outputschemas[m.id] = m.schema.toJSONSchema();
373
+ }
374
+ }
375
+
376
+ com.install && com.install.call(com, com);
377
+
378
+ callback(null, com);
379
+ });
380
+
381
+ };
package/controller.js CHANGED
@@ -113,6 +113,14 @@ function Controller(req, res) {
113
113
 
114
114
  Controller.prototype = {
115
115
 
116
+ get query() {
117
+ return this.$query || (this.$query = ctrl.uri.search.parseEncoded());
118
+ },
119
+
120
+ set query(val) {
121
+ this.$query = val;
122
+ },
123
+
116
124
  get mobile() {
117
125
  let ua = this.headers['user-agent'];
118
126
  return ua ? REG_MOBILE.test(ua) : false;
@@ -458,13 +466,17 @@ Controller.prototype.layout = function(name) {
458
466
  Controller.prototype.view = function(name, model) {
459
467
 
460
468
  var ctrl = this;
469
+ var view = new F.TViewEngine.View(ctrl);
470
+
471
+ if (!name)
472
+ return view;
461
473
 
462
474
  if (ctrl.destroyed)
463
475
  return;
464
476
 
465
- var view = new F.TViewEngine.View(ctrl);
466
477
  ctrl.response.layout && view.layout(ctrl.response.layout);
467
478
  setImmediate(renderview, view, name, model);
479
+
468
480
  return view;
469
481
  };
470
482
 
@@ -1017,12 +1029,16 @@ Controller.prototype.$route = function() {
1017
1029
 
1018
1030
  ctrl.payload = Buffer.concat(ctrl.payload);
1019
1031
  F.stats.performance.download += ctrl.payload.length / 1024 / 1024;
1032
+ let val;
1033
+
1020
1034
  switch (ctrl.datatype) {
1021
1035
  case 'json':
1022
- ctrl.body = F.def.parsers.json(ctrl.payload.toString('utf8'));
1036
+ val = ctrl.payload.toString('utf8');
1037
+ ctrl.body = val ? F.def.parsers.json(val) : null;
1023
1038
  break;
1024
1039
  case 'urlencoded':
1025
- ctrl.body = F.def.parsers.urlencoded(ctrl.payload.toString('utf8'));
1040
+ val = ctrl.payload.toString('utf8');
1041
+ ctrl.body = val ? F.def.parsers.urlencoded(val) : {};
1026
1042
  break;
1027
1043
  }
1028
1044
 
@@ -1320,7 +1320,7 @@ function init_current(meta, callback, nested) {
1320
1320
 
1321
1321
  if (instance) {
1322
1322
  if (typeof(instance) === 'string') {
1323
- if (source === 'add') {
1323
+ if (source === 'add' || source === 'register') {
1324
1324
  componentid = instance;
1325
1325
  F.error(err, 'FlowStream | register component | ' + instance);
1326
1326
  } else if (meta.design[instance]) {
@@ -1339,9 +1339,6 @@ function init_current(meta, callback, nested) {
1339
1339
  } else if (source === 'instance_make') {
1340
1340
  instanceid = instance.id;
1341
1341
  componentid = instance.component;
1342
- } else if (source === 'register') {
1343
- instanceid = '';
1344
- componentid = instance;
1345
1342
  } else {
1346
1343
  instanceid = instance.id;
1347
1344
  componentid = instance.module.id;
@@ -1449,9 +1446,11 @@ function init_current(meta, callback, nested) {
1449
1446
  } else if (source === 'register') {
1450
1447
  instanceid = '';
1451
1448
  componentid = instance;
1449
+ } else if (source === 'add') {
1450
+ componentid = instance;
1452
1451
  } else {
1453
1452
  instanceid = instance.id;
1454
- componentid = instance.module.id;
1453
+ componentid = instance.module ? instance.module.id : null;
1455
1454
  }
1456
1455
  }
1457
1456
 
@@ -2461,6 +2460,8 @@ function MAKEFLOWSTREAM(meta) {
2461
2460
  minutes = stats.minutes;
2462
2461
  if (isFLOWSTREAMWORKER)
2463
2462
  memory = process.memoryUsage().heapUsed;
2463
+ else if (F.consumption.memory)
2464
+ memory = F.consumption.memory * 1024 * 1024;
2464
2465
  }
2465
2466
 
2466
2467
  flow.stats.memory = memory;
package/flow.js CHANGED
@@ -16,7 +16,6 @@ FS.worker = false;
16
16
  FS.instances = {};
17
17
  FS.onerror = function(err, source, id, componentid, stack) {
18
18
 
19
- throw new Error('FET');
20
19
  var flow = FS.db[this.id];
21
20
  var empty = '---';
22
21
  var output = '';
package/flowstream.js CHANGED
@@ -305,10 +305,8 @@ function variables(str, data, encoding) {
305
305
 
306
306
  var customencoding = typeof(encoding) === 'function';
307
307
 
308
- if (!val && data != null && typeof(data) === 'object') {
309
- var nested = key.indexOf('.') !== -1;
310
- val = nested ? F.TUtils.get(data, key) : data[key];
311
- }
308
+ if (!val && data != null && typeof(data) === 'object')
309
+ val = key.includes('.') ? F.TUtils.get(data, key) : data[key];
312
310
 
313
311
  if (customencoding) {
314
312
 
@@ -353,7 +351,7 @@ function timeouthandler(msg) {
353
351
 
354
352
  MP.send = function(outputindex, data, clonedata) {
355
353
 
356
- var self = this;
354
+ let self = this;
357
355
 
358
356
  if (clonedata == null)
359
357
  clonedata = self.main.cloning;
@@ -364,13 +362,13 @@ MP.send = function(outputindex, data, clonedata) {
364
362
  return 0;
365
363
  }
366
364
 
367
- var outputs;
368
- var count = 0;
365
+ let outputs;
366
+ let count = 0;
369
367
 
370
368
  if (outputindex == null) {
371
369
 
372
370
  if (self.instance.connections) {
373
- for (var key in self.instance.connections)
371
+ for (let key in self.instance.connections)
374
372
  count += self.send(key);
375
373
  }
376
374
 
@@ -381,8 +379,8 @@ MP.send = function(outputindex, data, clonedata) {
381
379
  }
382
380
 
383
381
 
384
- var meta = self.main.meta;
385
- var now = Date.now();
382
+ let meta = self.main.meta;
383
+ let now = Date.now();
386
384
 
387
385
  outputs = self.instance.connections ? (self.instance.connections[outputindex] || F.EMPTYARRAY) : F.EMPTYARRAY;
388
386
 
@@ -407,7 +405,7 @@ MP.send = function(outputindex, data, clonedata) {
407
405
  return count;
408
406
  }
409
407
 
410
- var tid = self.toid + D + outputindex + (self.color || '');
408
+ let tid = self.toid + D + outputindex + (self.color || '');
411
409
 
412
410
  if (self.main.stats.traffic[tid]) {
413
411
  self.main.stats.traffic[tid]++;
@@ -419,29 +417,30 @@ MP.send = function(outputindex, data, clonedata) {
419
417
  if (self.transformation === '1')
420
418
  self.transformation = '_' + tid;
421
419
 
422
- for (var i = 0; i < outputs.length; i++) {
423
- var output = outputs[i];
420
+ for (let i = 0; i < outputs.length; i++) {
421
+
422
+ let output = outputs[i];
424
423
 
425
424
  if (output.disabled || output.paused)
426
425
  continue;
427
426
 
428
- var schema = meta.flow[output.id];
427
+ let schema = meta.flow[output.id];
429
428
  if (schema && (schema.message || schema['message_' + output.index]) && schema.component && schema.ready && self.main.$can(true, output.id, output.index)) {
430
- var next = meta.components[schema.component];
429
+ let next = meta.components[schema.component];
431
430
  if (next && next.connected && !next.isdestroyed && !next.disabled) {
432
431
 
433
432
  if (output.color && self.color && self.color !== output.color)
434
433
  continue;
435
434
 
436
- var inputindex = output.index;
437
- var message = self.clone();
435
+ let inputindex = output.index;
436
+ let message = self.clone();
438
437
 
439
438
  if (data != undefined)
440
439
  message.data = data;
441
440
 
442
441
  if (clonedata && message.data && typeof(message.data) === 'object') {
443
442
  if (message.data instanceof Buffer) {
444
- var buf = Buffer.alloc(message.data.length);
443
+ let buf = Buffer.alloc(message.data.length);
445
444
  buf.copy(message.data);
446
445
  message.data = buf;
447
446
  } else
@@ -462,6 +461,13 @@ MP.send = function(outputindex, data, clonedata) {
462
461
  message.ts = now;
463
462
  message.color = output.color;
464
463
 
464
+ let ti = schema.inputschemas[message.input];
465
+ if (ti && ti.schema) {
466
+ let tmp = ti.schema.transform(typeof(message.data) === 'object' ? message.data : {});
467
+ message.data = tmp.response;
468
+ message.error = tmp.error;
469
+ }
470
+
465
471
  if (self.$timeout)
466
472
  message.$timeoutid = setTimeout(timeouthandler, self.$timeout, message);
467
473
 
@@ -999,7 +1005,6 @@ function newmessage(data) {
999
1005
  msg.data = data instanceof Message ? data.data : data;
1000
1006
  msg.cloned = 0;
1001
1007
  msg.count = 0;
1002
- msg.instance = self;
1003
1008
  msg.duration = msg.ts = Date.now();
1004
1009
  msg.used = 1;
1005
1010
  msg.main = self instanceof FlowStream ? self : self.main;
@@ -1141,6 +1146,13 @@ FP.ontrigger = function(outputindex, data, controller, events) {
1141
1146
  message.cache = target.cache;
1142
1147
  message.processed = 0;
1143
1148
 
1149
+ let ti = target.inputschemas[message.input];
1150
+ if (ti && ti.schema) {
1151
+ let tmp = ti.schema.transform(message.data);
1152
+ message.data = tmp.response;
1153
+ message.error = tmp.error;
1154
+ }
1155
+
1144
1156
  target.stats.pending++;
1145
1157
  target.stats.input++;
1146
1158
  schema.stats.output++;
@@ -1194,6 +1206,7 @@ FP.reconfigure = function(id, config, rewrite) {
1194
1206
  self.onreconfigure && self.onreconfigure(instance);
1195
1207
  self.$events.configure && self.emit('configure', instance);
1196
1208
  }
1209
+
1197
1210
  return !!instance;
1198
1211
  };
1199
1212
 
@@ -1606,6 +1619,28 @@ FP.initcomponent = function(key, component) {
1606
1619
  instance.replace = variables;
1607
1620
  instance.instances = self.meta.flow;
1608
1621
  instance.components = self.meta.components;
1622
+ instance.inputschemas = {};
1623
+ instance.outputschemas = {};
1624
+
1625
+ // Due to inline data schemas
1626
+ if (component.inputs) {
1627
+ for (let m of component.inputs) {
1628
+ let tmp = CLONE(m);
1629
+ instance.inputschemas[m.id] = tmp;
1630
+ if (tmp.schema)
1631
+ tmp.schema = tmp.schema.toJSONSchema();
1632
+ }
1633
+ }
1634
+
1635
+ // Due to inline data schemas
1636
+ if (component.outputs) {
1637
+ for (let m in component.outputs) {
1638
+ let tmp = CLONE(m);
1639
+ instance.outputschemas[m.id] = tmp;
1640
+ if (tmp.schema)
1641
+ tmp.schema = tmp.schema.toJSONSchema();
1642
+ }
1643
+ }
1609
1644
 
1610
1645
  self.onconnect && self.onconnect(instance);
1611
1646
  self.$events.connect && self.emit('connect', instance);
package/global.js CHANGED
@@ -40,6 +40,7 @@ global.DATA = new F.TQueryBuilder.Controller(true);
40
40
  global.DB = () => new F.TQueryBuilder.Controller();
41
41
  global.CACHE = F.cache;
42
42
  global.NEWACTION = F.TBuilders.newaction;
43
+ global.NEWCOMPONENT = F.newcomponent;
43
44
  global.NEWSCHEMA = F.TBuilders.newschema;
44
45
  global.ACTION = global.EXEC = F.TBuilders.action;
45
46
  global.TEMPLATE = F.template;
package/htmlparser.js CHANGED
@@ -561,7 +561,15 @@ function parseHTML(html, trim, onerror, isxml) {
561
561
  }
562
562
 
563
563
  var tag = node;
564
- var index = tag.indexOf(' ');
564
+ var index = -1;
565
+
566
+ for (let i = 0; i < tag.length; i++) {
567
+ let c = tag[i];
568
+ if (c === '\n' || c === ' ' || c === '/' || c === '>') {
569
+ index = i;
570
+ break;
571
+ }
572
+ }
565
573
 
566
574
  if (index > 0) {
567
575
  tag = tag.substring(0, index);
@@ -597,9 +605,14 @@ function parseHTML(html, trim, onerror, isxml) {
597
605
  case 'BR':
598
606
  case 'HR':
599
607
  case 'IMG':
608
+ case 'INPUT':
600
609
  case 'META':
601
610
  case 'LINK':
602
- case 'INPUT':
611
+ case 'SOURCE':
612
+ case 'AREA':
613
+ case 'COL':
614
+ case 'EMBED':
615
+ case 'TRACK':
603
616
  dom.unpair = true;
604
617
  return str;
605
618
  }
package/index.js CHANGED
@@ -1243,6 +1243,11 @@ F.httpload = function(opt) {
1243
1243
  F.server = F.Http.createServer(F.THttp.listen);
1244
1244
  F.server.on('upgrade', F.TWebSocket.listen);
1245
1245
 
1246
+ CONF.$performance && F.server.on('connection', function(socket) {
1247
+ socket.setNoDelay(true);
1248
+ socket.setKeepAlive(true, 10);
1249
+ });
1250
+
1246
1251
  var unixsocket = opt.unixsocket || F.config.$unixsocket;
1247
1252
  if (unixsocket) {
1248
1253
 
@@ -2499,7 +2504,7 @@ F.filestorage = function(name) {
2499
2504
 
2500
2505
  F.encryptreq = function(ctrl, val, key, strict) {
2501
2506
  var obj = {};
2502
- obj.ua = ctrl.ua;
2507
+ obj.ua = HASH(ctrl.headers['user-agent'] || '').toString(36);
2503
2508
  if (strict)
2504
2509
  obj.ip = ctrl.ip;
2505
2510
  obj.data = val;
@@ -2510,7 +2515,7 @@ F.decryptreq = function(ctrl, val, key) {
2510
2515
  if (!val)
2511
2516
  return;
2512
2517
  var obj = F.decrypt(val, key || '', true);
2513
- if (!obj || (obj.ip && obj.ip !== ctrl.ip) || (obj.ua !== ctrl.ua))
2518
+ if (!obj || (obj.ip && obj.ip !== ctrl.ip) || (obj.ua !== HASH(ctrl.headers['user-agent'] || '').toString(36)))
2514
2519
  return;
2515
2520
  return obj.data;
2516
2521
  };
@@ -2572,6 +2577,8 @@ F.dir = function(val) {
2572
2577
  };
2573
2578
 
2574
2579
  F.run = function(opt) {
2580
+ if (!opt)
2581
+ opt = {};
2575
2582
  var type = opt.watcher === false ? 'release' : 'debug';
2576
2583
  opt.watcher = false;
2577
2584
  require('./' + type)(opt);
@@ -2648,6 +2655,10 @@ F.datauri = function(path) {
2648
2655
  }));
2649
2656
  };
2650
2657
 
2658
+ F.newcomponent = function(html, callback) {
2659
+ return require('./components').compile(html, callback);
2660
+ };
2661
+
2651
2662
  F.loadstats = function() {
2652
2663
 
2653
2664
  var main = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "total5",
3
- "version": "0.0.7-2",
3
+ "version": "0.0.7",
4
4
  "description": "Total.js framework v5",
5
5
  "main": "index.js",
6
6
  "directories": {
package/viewengine.js CHANGED
@@ -873,12 +873,21 @@ View.prototype.set = function() {
873
873
  return '';
874
874
  };
875
875
 
876
+ View.prototype.renderlayout = function(name, content) {
877
+ let self = this;
878
+ self.output = content;
879
+ self.islayout = true;
880
+ content = self.render(self.repository.layout);
881
+ self.islayout = false;
882
+ return content;
883
+ };
884
+
876
885
  View.prototype.render = function(name, model, ispartial = false) {
877
886
 
878
- var self = this;
879
- var key = name + '_' + self.language;
880
- var fn = F.temporary.views[key];
881
- var content;
887
+ let self = this;
888
+ let key = name + '_' + self.language;
889
+ let fn = F.temporary.views[key];
890
+ let content;
882
891
 
883
892
  self.model = model;
884
893
 
@@ -897,6 +906,7 @@ View.prototype.render = function(name, model, ispartial = false) {
897
906
  self.output = content;
898
907
  self.islayout = true;
899
908
  content = self.render(self.repository.layout);
909
+ self.islayout = false;
900
910
  }
901
911
 
902
912
  return content;