ForgeTotal.js 5
en

Total.js 5

The small global helpers: MAIN, REPO, FUNC, NOW, CLONE, COPY, QUERIFY and PROMISIFY

Total.js 5 · total5@0.0.19 globalsutilitieshelpers Executed against Total.js 5

total5 creates a few global objects for your own use and a few helpers that save a line of code. Nothing here needs setup.

  • MAIN, REPO and FUNC are empty objects that the framework creates once: keep application data in MAIN, other data in REPO and your own functions in FUNC. TEMP is an object for temporary data that the framework replaces from time to time, so do not keep anything in it that you need later.
  • NOW is the current date as a Date. It is refreshed about once a minute (and by some calls), so use new Date() when you need the exact time.
  • EMPTYARRAY and EMPTYOBJECT are frozen empty values to return instead of creating new ones: they cannot be changed.
  • MODS and PLUGINS are objects with the loaded modules and plugins by id. F and Total are the same object, the framework, and print is console.log. NOOP is a function that does nothing.
  • REQUIRE(name) is require that also resolves packages from the node_modules of the application and accepts names such as node:path.
  • CLONE(value) makes a deep copy: nested objects, arrays and dates are copied. COPY(from, to) copies the properties of the first object into the second and returns the second.
  • QUERIFY([url], object) builds a query string from an object: empty values and null are skipped and an array becomes a comma separated value. With an url it returns url?..., without one it returns ?....
  • PROMISIFY(fn, a, b, c) calls fn(a, b, c, callback) and returns a promise that resolves with the response of the callback or rejects with its error.
controllers/helpers.js
MAIN.started = 'yes';
REPO.counter = 1;
FUNC.double = n => n * 2;

exports.install = function() {
	ROUTE('GET /helpers/', helpers);
	ROUTE('GET /promisify/', promisify);
};

function helpers($) {

	const source = { a: 1, nested: { b: [1, 2] }, date: new Date(2026, 0, 5) };
	const cloned = CLONE(source);
	const target = { x: 1 };
	const returned = COPY({ y: 2 }, target);

	$.json({
		shared: [MAIN.started, REPO.counter, FUNC.double(4), typeof TEMP],
		now: [NOW instanceof Date, Math.abs(Date.now() - NOW.getTime()) < 120000],
		emptyarray: [EMPTYARRAY.length, Object.isFrozen(EMPTYARRAY)],
		emptyobject: [Object.keys(EMPTYOBJECT).length, Object.isFrozen(EMPTYOBJECT)],
		registries: [typeof MODS, typeof PLUGINS],
		same: [F === Total, typeof print, NOOP() === undefined],
		require: typeof REQUIRE('node:path').join,
		clone: [cloned !== source, cloned.nested !== source.nested, cloned.nested.b !== source.nested.b, cloned.date instanceof Date, cloned.nested.b.join()],
		copy: [returned === target, target.x, target.y],
		querify: QUERIFY('/search/', { q: 'a b', page: 2, empty: '', nothing: null, list: [1, 2] }),
		querify2: QUERIFY({ q: 'x' })
	});
}

async function promisify($) {

	const add = (a, b, callback) => setImmediate(callback, null, a + b);
	const fail = (callback) => setImmediate(callback, 'It failed');

	const sum = await PROMISIFY(add, 2, 3);
	let error = null;

	try {
		await PROMISIFY(fail);
	} catch (e) {
		error = e.message || String(e);
	}

	$.json({ sum: sum, error: error });
}