Skip to content

Design Settings Manager

Flynn Duniho edited this page May 30, 2024 · 1 revision

UR-CENTRAL manages common settings across all modules, their derived data, changes to network data, in one place.

Design Goals

  • settings can be organized by system name or module or concept on-the-fly
  • module names are definable
  • to be importable by all modules, no shared dependencies
  • short syntax so encouraged to use it
  • syntax evokes important programming and system concepts
  • easy to find occurences using search
  • can be used to manage several types of state and control data
  • easy to inspect data from console or read/write from database

Kind Of Values Represented

  • STATIC VALUES defined on startup, not changing or mutable
  • DEFAULT VALUES that can be overridden
  • DERIVED VALUES that are computed as a result of a change in another value
  • STATE VALUES that can be inspected to see if it's changed since last check
  • VALUE EVENTS that fire an event to subscribers
  • SETTABLE VALUES that update on a queue using a timer interval
  • NETWORK VALUES that are shared across the entire network
  • SERVER VALUES that are accessible and source from server

Flow

constant            default -> user read
[module] setting    default -> module init -> user read
[session] setting   default -> session init -> user read
[session] setting   default -> session update -> [change event] -> user read
[network] setting   default -> network update -> [change event] -> user read
[user] setting      novalue -> user write -> user read

Namespaces

  • namespaces must be created by a single module that 'owns' it
  • reserved namespaces exist and can not be defined
  • namespaces use object dot notation
  • reserved namespaces defined on server for use by clients
  • client namespaces and keys are always lowercase (enforced by UR)
  • reserved namespaces use PascalCase always
  • Server - values stored on the server, read-only
  • Network - values

Methods

// reading norm settings
const setting = CENTRAL.GetVal( 'key' ); // return the setting value
const setting = CENTRAL.GetVal( 'namespace.key' ); // return the named setting for namespace
// creating dynamic settings / state
CENTRAL.CreateBinding( 'key', { options } ); // define setting object
const bref = CENTRAL.GetBinding( 'key' ); // return named setting object for module
CENTRAL.CreateBinding( 'namespace.key', { options } ); // define named setting value
const bref = CENTRAL.GetBinding( 'namespace.key' ); // return the named setting object for module
// subscribing to setting / state changes
bref.OnValueUpdated(func); // subscribe to changes
// reading bound values
bref.Value(); // returns the value
// setting bound values, which must match shape of original
// the bref object itself could be used
bref.SetValue(value); // sets the value if it's not a bound value
// annotating setting objects with other data
// note: this might be a DANGEROUS feature to provide
// note: it depends whether the returned Binding objects are a single object or an instance
bref.Meta(); // returns meta object for use of note taking not on the value, but the ref itself so it's shared by everyone who requests this binding.
bref.SetMeta(); // updates the meta object (similar to React component setState()
bref.OnMetaUpdated(funct); subscribe to Meta changes

Example

// owner of the value defines it. multiple defs will throw an error
const titleList = CENTRAL.CreateBinding('mycontrol.titlelist'); // all lowercase

// users of the value retrieve the object
const boundList = CENTRAL.GetBinding( 'mycontrol.titlelist' );

// subscribe to changes
boundList.OnValueUpdated((arr)=>{
  console.log(`${boundList.name} updated array boundList`,arr);
  this.setState({ list: arr });  // also update React local stuff
});

// manipulate and update the value
let arr = boundList.Get();
arr.sort();
arr.push('another element');
boundList.Value(arr); // update the values, which will trigger subscribers