A human-friendly standard for Flux action objects with utility functions for validation and error handling
npx @tessl/cli install tessl/npm-flux-standard-action@2.1.0Flux Standard Action provides a standardized format for Flux action objects in JavaScript applications, particularly Redux-based systems. It defines a human-friendly specification that requires actions to be plain objects with a 'type' property, and optionally 'payload', 'error', and 'meta' properties.
npm install flux-standard-actionimport { isFSA, isError, FluxStandardAction, FSA } from "flux-standard-action";For CommonJS:
const { isFSA, isError } = require("flux-standard-action");import { isFSA, isError, FluxStandardAction } from "flux-standard-action";
// Example FSA-compliant action
const action: FluxStandardAction = {
type: 'ADD_TODO',
payload: {
text: 'Do something.'
}
};
// Validate FSA compliance
if (isFSA(action)) {
console.log('Action is FSA compliant');
}
// Example error action
const errorAction: FluxStandardAction = {
type: 'LOAD_USER_FAILURE',
payload: new Error('Network error'),
error: true
};
// Check if action represents an error
if (isError(errorAction)) {
console.log('Action represents an error');
}Flux Standard Action is built around two key concepts:
error flagFunctions to validate whether actions conform to the FSA specification.
/**
* Returns true if action is FSA compliant
* @param action - The action object to validate
* @returns Type guard indicating FSA compliance
*/
function isFSA<Type extends string = string, Payload = undefined, Meta = undefined>(
action: any
): action is FluxStandardAction<Type, Payload, Meta>;
/**
* Returns true if action is FSA compliant error (action.error must be strictly true)
* @param action - The action object to check
* @returns Type guard indicating error FSA
*/
function isError<Type extends string = string, CustomError extends Error = Error, Meta = undefined>(
action: any
): action is ErrorFluxStandardAction<Type, CustomError, Meta>;Standard interfaces for defining FSA-compliant actions.
/**
* A Flux Standard action with optional payload and metadata properties
*/
interface FluxStandardAction<
Type extends string = string,
Payload = undefined,
Meta = undefined
> {
/** The type of an action identifies to the consumer the nature of the action that has occurred */
type: Type;
/** The optional payload property MAY be any type of value */
payload?: Payload;
/** The optional error property MAY be set to true if the action represents an error. If error has any other value besides true, including undefined, the action MUST NOT be interpreted as an error */
error?: boolean;
/** The optional meta property MAY be any type of value for extra information */
meta?: Meta;
}
/**
* An extension of the Flux Standard action that represents an action containing an error as its payload
*/
interface ErrorFluxStandardAction<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> extends FluxStandardAction<Type, CustomError, Meta> {
/** The required error property MUST be set to true if the action represents an error */
error: true;
}Specialized action types for when payload or metadata are required.
/**
* A Flux Standard action with a required payload property
*/
interface FluxStandardActionWithPayload<
Type extends string = string,
Payload = undefined,
Meta = undefined
> extends FluxStandardAction<Type, Payload, Meta> {
/** The required payload property MAY be any type of value */
payload: Payload;
}
/**
* A Flux Standard action with a required metadata property
*/
interface FluxStandardActionWithMeta<
Type extends string = string,
Payload = undefined,
Meta = undefined
> extends FluxStandardAction<Type, Payload, Meta> {
/** The required meta property MAY be any type of value */
meta: Meta;
}
/**
* A Flux Standard action with required payload and metadata properties
*/
type FluxStandardActionWithPayloadAndMeta<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = FluxStandardActionWithPayload<Type, Payload, Meta> &
FluxStandardActionWithMeta<Type, Payload, Meta>;Smart action types that automatically infer required properties based on generic parameters.
/**
* A Flux Standard action with inferred requirements for the payload and metadata properties.
* The payload and meta properties will be required if the corresponding type argument is not undefined
*/
type FluxStandardActionAuto<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = Payload extends undefined
? (Meta extends undefined
? FluxStandardAction<Type, Payload, Meta>
: FluxStandardActionWithMeta<Type, Payload, Meta>)
: (Meta extends undefined
? FluxStandardActionWithPayload<Type, Payload, Meta>
: FluxStandardActionWithPayloadAndMeta<Type, Payload, Meta>);Specialized error action types with required properties.
/**
* A Flux Standard Error Action with a required payload property
*/
type ErrorFluxStandardActionWithPayload<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardAction<Type, CustomError, Meta> &
FluxStandardActionWithPayload<Type, CustomError, Meta>;
/**
* A Flux Standard Error Action with a required metadata property
*/
type ErrorFluxStandardActionWithMeta<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardAction<Type, CustomError, Meta> &
FluxStandardActionWithMeta<Type, CustomError, Meta>;
/**
* A Flux Standard Error Action with required payload and metadata properties
*/
type ErrorFluxStandardActionWithPayloadAndMeta<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardActionWithPayload<Type, CustomError, Meta> &
ErrorFluxStandardActionWithMeta<Type, CustomError, Meta>;
/**
* A Flux Standard Error action with inferred requirements for the payload and metadata properties.
* The payload property will always be required, since the CustomError type argument does not allow for specification of the undefined type
*/
type ErrorFluxStandardActionAuto<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = Meta extends undefined
? ErrorFluxStandardActionWithPayload<Type, CustomError, Meta>
: ErrorFluxStandardActionWithPayloadAndMeta<Type, CustomError, Meta>;Convenient short aliases for common action types.
/** Alias for FluxStandardAction */
type FSA<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = FluxStandardAction<Type, Payload, Meta>;
/** Alias for ErrorFluxStandardAction */
type ErrorFSA<
CustomError extends Error = Error,
Meta = undefined,
Type extends string = string
> = ErrorFluxStandardAction<Type, CustomError, Meta>;
/** Alias for FluxStandardActionWithPayload */
type FSAWithPayload<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = FluxStandardActionWithPayload<Type, Payload, Meta>;
/** Alias for FluxStandardActionWithMeta */
type FSAWithMeta<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = FluxStandardActionWithMeta<Type, Payload, Meta>;
/** Alias for FluxStandardActionWithPayloadAndMeta */
type FSAWithPayloadAndMeta<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = FluxStandardActionWithPayloadAndMeta<Type, Payload, Meta>;
/** Alias for FluxStandardActionAuto */
type FSAAuto<
Type extends string = string,
Payload = undefined,
Meta = undefined
> = FluxStandardActionAuto<Type, Payload, Meta>;
/** Alias for ErrorFluxStandardActionWithPayload */
type ErrorFSAWithPayload<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardActionWithPayload<Type, CustomError, Meta>;
/** Alias for ErrorFluxStandardActionWithMeta */
type ErrorFSAWithMeta<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardActionWithMeta<Type, CustomError, Meta>;
/** Alias for ErrorFluxStandardActionWithPayloadAndMeta */
type ErrorFSAWithPayloadAndMeta<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardActionWithPayloadAndMeta<Type, CustomError, Meta>;
/** Alias for ErrorFluxStandardActionAuto */
type ErrorFSAAuto<
Type extends string = string,
CustomError extends Error = Error,
Meta = undefined
> = ErrorFluxStandardActionAuto<Type, CustomError, Meta>;import { FluxStandardAction, FSA } from "flux-standard-action";
// Basic action
const addTodo: FSA<'ADD_TODO', { text: string }> = {
type: 'ADD_TODO',
payload: { text: 'Learn TypeScript' }
};
// Action with metadata
const loadUser: FSA<'LOAD_USER', { id: number }, { timestamp: number }> = {
type: 'LOAD_USER',
payload: { id: 123 },
meta: { timestamp: Date.now() }
};
// Error action
const loadUserError: ErrorFSA<Error, { retry: boolean }> = {
type: 'LOAD_USER_FAILURE',
payload: new Error('Network timeout'),
error: true,
meta: { retry: true }
};import { isFSA, isError } from "flux-standard-action";
function handleAction(action: any) {
// Validate FSA compliance
if (!isFSA(action)) {
console.warn('Action is not FSA compliant:', action);
return;
}
// Check if it's an error action (error must be strictly true)
if (isError(action)) {
console.error('Action error:', action.payload);
return;
}
// Process normal action
console.log('Processing action:', action.type);
}
// Note: isError only returns true for action.error === true
const notAnError = { type: 'TEST', error: 'true' }; // String 'true' is not an error
const isAnError = { type: 'TEST', error: true }; // Boolean true is an error
console.log(isError(notAnError)); // false
console.log(isError(isAnError)); // trueimport { FSAAuto } from "flux-standard-action";
// Payload automatically required when type is not undefined
const actionWithPayload: FSAAuto<'SET_USER', { name: string }> = {
type: 'SET_USER',
payload: { name: 'Alice' } // Required because Payload is not undefined
};
// Both payload and meta automatically required
const actionWithBoth: FSAAuto<'UPDATE_USER', { name: string }, { source: string }> = {
type: 'UPDATE_USER',
payload: { name: 'Bob' }, // Required
meta: { source: 'api' } // Required
};