Differences between Total.js v5 and Total.js v4
This blog post describes the main differences between Total.js v4 and Total.js v5. Total.js v5 contains almost new and nicely written code. This blog post will be gradually updated.
Projects
Introduction
What is new in Total.js v5?
Only shorter, cleaner and improved code. Finally, the repository contains much nicer code. It’s fully optimised for Node >18
.
Should I update the Total.js v4 apps?
No. We started testing Total.js v5. You can develop upcoming projects with Total.js v5. For stability reasons, wait before converting older apps to Total.js v5.
Is the Total.js v5 stable?
Almost yes. We use Total.js v5 in several projects, and they work without critical issues. We are working on unit-tests, documentation, etc..
How can I determine Total.js v5 in the code?
console.log(F.is5);
// true or undefined
New start script
We updated the start script for Total.js v5. Don't forget to use it if you want to use Total.js v5.
// Example
require('total5').run({ ... });
Schemas
NEWSCHEMA('Users', function(schema) {
// schema.define() is not supported
schema.action('save', {
name: 'Save ',
params: '*id:String',
input: '*name:String',
action: function($, model) {
// do something
}
});
});
// It's the same like this:
NEWACTION('Users/save', {
name: 'Name of action',
params: '*id:String',
input: '*name:String',
action: function($, model) {
// do something
}
});
// !!! IMPORTANT:
// OLD:
DATA.find('tbl_user').callback($.callback);
// NEW:
DATA.find('tbl_user').callback($);
// OLD:
$.success(true, VALUE);
// NEW:
$.success(VALUE);
Linking schemas:
NEWSCHEMA('@Users', '*name:String,*email:Email');
// NEWSCHEMA('Users', '*name:String,*email:Email'); --> it's the same like above declaration
NEWACTION('Users/create', {
name: 'Create',
input: '@Users',
action: function($, model) {
// Do something
}
});
NEWACTION('Users/update', {
name: 'Update',
input: '@Users',
action: function($, model) {
// Do something
}
});
Partial data:
NEWACTION('Users/save', {
name: 'Name of action',
input: '*name:String,*email:Email',
partial: true, // the same like HTTP PATCH method
action: function($, model) {
// do something
}
});
CALL/EXEC/ACTION:
// OLD:
EXEC('+Users --> save', { name: 'Peter' }, callback);
CALL('-Users --> list').params({}).query({}).user({}).callback(console.log);
// NEW:
ACTION('Users/save', { name: 'Peter' }).params({}).query({}).user({}).callback(console.log);
ACTION('Users/list').params({}).query({}).user({}).callback(console.log);
EXEC() // --> is alias for ACTION()
Routing
Total.js v5 doesn’t use request
and response
instances. It works only with a controller
- alias $
. So every request to an action, file or WebSocket is represented as a controller.
// OLD:
ROUTE('GET /', index);
function index() {
var self = this;
self.view('index');
}
// NEW:
ROUTE('GET /', index);
function index($) {
// $.body {Object}
// $.query {Object}
// $.params {Object}
// $.files {Array Object}
$.view('index');
}
Flags:
// OLD:
ROUTE('POST /something/', action, ['upload', 10000], 1024 * 10);
// NEW:
ROUTE('POST /something/ <10MB <10s @upload', action);
ROUTE('POST /something/ <10s @upload', action, 1024 * 10);
API routing
// OLD:
ROUTE('API /api/ +something *Users --> save');
ROUTE('API /api/ +something *Users --> save email (response)');
ROUTE('POST /form/ *Users --> save email (response)');
// NEW:
ROUTE('API /api/ +something --> Users/save');
ROUTE('API /api/ +something --> Users/save Users/email (response)');
ROUTE('POST /form/ --> Users/save Users/email (response)');
New feature
Routes support the ?
character which is replaced with CONF.$api
value (default: /admin/
).
// NEW:
ROUTE('API ? +something --> Users/save');
ROUTE('API ?/special/ +something --> Users/save Users/email (response)');
// EVALUATED AS:
ROUTE('API /admin/ +something --> Users/save');
ROUTE('API /admin/special/ +something --> Users/save Users/email (response)');
WebSocket routing
// OLD:
ROUTE('SOCKET /endpoint/', socket);
function socket() {
var $ = this;
}
// NEW:
ROUTE('SOCKET /endpoint/', socket);
function socket($) {
}
Localization
// OLD:
TRANSLATOR(language, '@(Something to translate)');
TRANSLATE(language, 'Word');
// NEW:
TRANSLATE(language, '@(Something to translate)');
Determine the language of incoming requests:
// OLD:
LOCALIZE(req => req.user ? req.user.language : req.query.language);
// NEW:
LOCALIZE($ => $.user ? $.user.language : $.query.language);
// $ {Controller}
Common changes
// OLD:
$.success(true, VALUE);
// NEW:
$.success(VALUE);
Configuration
Total.js v5 supports only the one configuration file called /config
. All system keys (90%) were updated to a shorter version:
$customtitles : true
$tms : true
$tmsurl : /$tms/
Keys: https://github.com/totaljs/framework5/blob/main/index.js#L326
Email
// OLD:
Mail.try(smtp, options, callback);
// NEW:
options.server = 'smtp.server.com';
Mail.try(options, callback)
Config:
// OLD:
mail_smtp : smtp.server.com
mail_options : {}
// NEW:
smtp : { "server": "smtp.server.com", "user": "", ... }
// OR
mail : { "server": "smtp.server.com", "user": "", ... }
NoSQL
All NoSQL commands are performed via the Total.js QueryBuilder used in PostgreSQL/MySQL.
NOSQL('products').where('price', '>', 10).callback(console.log);
// OR
DATA.find('nosql/products').where('price', '>', 10).callback(console.log);
PREF
PREF
is removed from Total.js v5. You can use MEMORIZE(name)
method that contains the same functionality.
Internal session mechanism
The SESSION()
method is removed in Total.js v5. The workaround is to use the AUTH()
method with predefined session functionality. More information at the link below: