ForgeTotal.js 5
en

Total.js 5

Compile and run a native server component

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

NEWCOMPONENT(html, [callback]) compiles a server component, distinct from a browser jComponent. It accepts source text containing script total or script node; without a callback it returns a promise. A name loads components/name.html; a URL downloads source. This recipe uses inline trusted code only, without remote source or npm declarations.

The exported component supplies metadata, config defaults and make(instance,config). component.create(overrides) creates an instance with cloned defaults. Declare inputs:[{id,schema}] for input transformation. instance.input(inputId,data,callback) delivers a message whose .data and .error reflect schema validation. The handler still runs on invalid input, so check message.error before processing. message.send(outputId,data) emits an output; message.destroy() ends it.

instance.reconfigure(values) updates its configuration and calls its configure/save hooks. instance.remove() calls lifecycle hooks and removes the instance; component.remove() removes all instances and invokes uninstall. Components execute with the application's privileges and are not a sandbox.

controllers/components.js
exports.install = function() {
	ROUTE('GET /native-component/', exercise);
};
async function exercise($) {
	try {
		var source = '<script total>exports.id="native-echo";exports.name="Native echo";exports.config={prefix:"one:"};exports.inputs=[{id:"input",schema:"*name:String"}];exports.make=function(instance,config){instance.message=function($){if($.error){$.send("invalid",{invalid:true});$.destroy();return;}$.send("output",{text:config.prefix+$.data.name});$.destroy();};instance.destroy=function(){MAIN.componentClosed=true;};};</script>';
		var component = await NEWCOMPONENT(source);
		component.debugger = false;
		var instance = component.create();
		var first = await new Promise(resolve => instance.input('input',{name:'Ann'},message => resolve(message.data)));
		var invalid = await new Promise(resolve => instance.input('input',{},message => resolve(message.data)));
		instance.reconfigure({prefix:'two:'});
		var second = await new Promise(resolve => instance.input('input',{name:'Bob'},message => resolve(message.data)));
		instance.remove();
		var rejected = false;
		try { await NEWCOMPONENT('<body>no backend script</body>'); } catch (e) { rejected = true; }
		$.json({first:first,invalid:invalid,second:second,remaining:component.instances.length,closed:MAIN.componentClosed,rejected:rejected});
	} catch (e) { $.invalid(e); }
}