32.0.0 • Published 4 months ago

tachyon-dynamic-settings v32.0.0

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
4 months ago

Dynamic Settings

The dynamic settings package provides Dynamic Settings from Actuator given a appGroup, app, and appEnvironment.

How to Use

Refer to the tachyon-dynamic-settings package example.

Functionality

This package will generate the proper URL for your settings file based on appGroup (e.g. tachyon), app (e.g. tomorrow), and appEnvironment (e.g. production). The terms appGroup and appEnvironment correspond to the Actuator terms platform and environment, respectively. The values themselves correspond directly to the config values defined in Savant/Actuator, with the exception of an appEnvironment of staging being mapped to the environment test for Actuator.

The dynamic settings response will be processed to validate that the spade_url value is a valid URL, and will be returned in the spadeUrl. Invalid URLs will be replaced with the default spade URL https://spade.twitch.tv. The response will also provide fallback values for environment, experiments, and spadeUrl should those keys be missing in the received response to protect against runtime errors. See the next section for using custom dynamic settings.

Runtime Settings Validation and Type Safety

The fetchDynamicSettings function accepts a processor as one of its opts values, and this processor must do runtime validation of any custom dynamic settings added to Savant to protect against Actuator unavailability or settings being deleted or unsafely altered. The fetchDynamicSettings function leverages TypeScript (>= 4.2) to help enforce this policy: all raw dynamic settings keys must be snake-cased, the processor must yield camel-cased versions of raw keys, and all raw dynamic settings values are yielded to the processor as unknown to ensure usage of type-guards. This is mediated by a single RawCustomDynamicSettings generic value passed to fetchDynamicSettings.

Define your custom (raw aka snake-cased) dynamic settings as a type somewhere, and then use that everywhere and this package's types will handle all the camel-case conversion logic under the hood:

type FooDynamicSettings = {
  some_thing: boolean;
};

Pass FooDynamicSettings type to usages of useDynamicSettings to yield the validated and transformed values to components:

const { someThing } = useDynamicSettings<FooDynamicSettings>();

In your processor function, use the type-guards provided by tachyon-utils-ts (ensureBoolean, ensureNumber, ensureString, and other valid Savant types) to test the raw values, yielding either the validated value or an appropriate fallback. Also pass through the non-custom settings like environment, experiments, and spadeUrl.

const fetchFooDynamicSettings = fetchDynamicSettings<FooDynamicSettings>({
  app: 'foo',
  appEnvironment,
  appGroup: 'tachyon',
  processor: ({ some_thing, ...settings }) => {
    const someThing = ensureBoolean(some_thing, true);

    return {
      ...settings,
      someThing,
    };
  },
});

All of this works towards ensuring that there are no errors encountered during runtime from these dynamic settings values that are controlled from outside the application.

Savant Configuration

Savant provides the frontend for managing the dynamic settings values, but those values are provided to applications by the Actuator service