Skip to content

SNA Component Concepts

DSri Seah edited this page Dec 3, 2024 · 3 revisions

SNA_Component is a helper class that allows a code module to participate in the SNA Lifecycle. It implements the SNA_ComponentProps interface.

SNA_ComponentProps Interface

/// SNA COMPONENT DEFAULT EXPORT /////////////////////////////////////////////////
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// a SNA component uses the sna-hooks, sna-urnet, and sna-monitor modules to
/// add itself to the overall SNA lifecycle.
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
export type MOD_PreConfig = (DataObj) => void; // called before lifecycle
export type MOD_PreHook = () => void; // called before lifecycle
export type MOD_AddComponent = ({ f_AddComponent: Function }) => void; // called during reg
export type MOD_EventRegister = (evt: string, notifyCB: Function) => void;
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// for code modules, exporting default SNA with SNA_Component is a suggested
/// practice
export interface SNA_ComponentProps {
  _name?: string;
  AddComponent?: MOD_AddComponent;
  PreConfig?: MOD_PreConfig;
  PreHook?: MOD_PreHook;
  Subscribe?: MOD_EventRegister;
  Unsubscribe?: MOD_EventRegister;
}

Syntax for Declaring an SNA Component

To use this class in an app built on-top of the URSYS core library, import the SNA module and export SNA_DeclareModule()

import { SNA } from '@ursys/core'; 

export default SNA.DeclareComponent('ComponentName', {
    AddComponent: f_AddComponent => {},
    PreConfig: config => {},
    PreHook: () => {},
    Subscribe: (evt, callback) => {},
    Unsubscribe: (evt, callback) => {}
});

Tip

An SNA Component always exports the module interface as default; you can export the API of the module itself using a regular export statement as follows:

// SNA module default export
export default SNA.DeclareComponent('ComponentName', {
    AddComponent: f_AddComponent => {},
    PreConfig: config => {},
    PreHook: () => {},
    Subscribe: (evt, callback) => {},
    Unsubscribe: (evt, callback) => {}
});
// your API exports
export {
    MethodA,
    MethodB
}

Connecting an SNA Component to a SNA App's Lifecycle

Once a module is declared as an SNA_Component using the above syntax, your bootstrap code looks like this:

// webapp version
import { SNA } from '@ursys/core'; 
import MySNAComponent from './library/mod-sna-component.ts';

SNA.GlobalConfig({ foo: 'bar' });
SNA.RegisterComponent(MySNAComponent);
await SNA.Start();

It's very similar on the server side too when bootstrapping the build-and-serve appserver process:

// appserver version (nodejs)
import * as PATH from 'node:path';
import { SNA } from '@ursys/core'; 
import MySNAComponent from './library/mod-sna-component.ts';
const sna_project_dir = PATH.dirname(process.argv[1]);
const runtime_dir = PATH.join(sna_project_dir,'_runtime');
SNA.GlobalConfig({ sna_project_dir, runtime_dir });
SNA.RegisterComponent(MySNAComponent);
await SNA.Build(sna_project_dir);

The above examples use SNA.RegisterComponent() to add your SNA module to the startup chain by providing hook functions. These are all optional.

Briefly, here is what the hook functions do:

  • AddComponent( f_AddComponent ) - Called by SNA to allow an SNA Component to register additional components. The function f_AddComponent is provided as a replacement for SNA.RegisterComponent, which may not be callable from within a dependent module. This allows for chained dependencies for your SNA components.
  • PreConfig( config ) - Called by SNA for any module that wants to add properties to the global configuration object, which can then be provided to each SNA Component when the lifecycle starts up.
  • PreHook() - Called by SNA after PreConfig to call add itself to a lifecycle phase by name. This allows an SNA Component to inject itself into any lifecycle point before startup.

Additionally:

  • Subscribe(evt, callback) - Declared by components that are subscribable using the EventMachine interface.
  • Unsubscribe(evet, callback) - The mirror function for Subscribe().