JSPM

@avstantso/core

1.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 1070
  • Score
    100M100P100Q81814F
  • License MIT

Core global AVStantso singleton

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@avstantso/core) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    @avstantso/core

    npm version License: MIT

    Core foundation package providing the global AVStantso singleton namespace and avstantso runtime object. This package serves as the base for the entire AVStantso ecosystem, offering TypeScript utilities, error handling, atomic object registry, and function utilities.

    Features

    • Global singleton pattern for shared utilities across packages
    • Comprehensive TypeScript type helpers
    • Centralized error handling system
    • Atomic objects registry for custom serialization
    • Function utilities for advanced patterns
    • Generic type validators and casters
    • Zero additional dependencies (uses @avstantso/std-ext)

    Installation

    npm install @avstantso/core

    or

    yarn add @avstantso/core

    Usage

    Global Singleton Access

    Import the package once in your application entry point to enable the global singleton:

    import '@avstantso/core';
    
    // The AVStantso singleton is now available globally
    avstantso.Catch(error); // Handle errors using centralized error handling

    Direct Member Imports

    You can also import specific members directly without relying on the global singleton:

    import { Func, Generic, X } from '@avstantso/core';
    
    // Use imported members directly
    const isExtended = Func.isExt(myFunction);
    const casted = Generic.Cast<MyType>(value);
    
    // X is a no-op function useful for Promise chains
    promise.then(X).catch(X); // Ignore both success and error

    Exported Members:

    • Func - Function utilities (same as avstantso.Func)
    • Generic - Generic type utilities (same as avstantso.Generic)
    • X - No-op function for ignoring Promise results

    API Reference

    AVStantso.TS - TypeScript Type Helpers

    Essential TypeScript utility types for building robust type-safe applications.
    These are foundational types that @avstantso/ts extends with additional utilities.

    AVStantso.TS.Key

    Union of all valid object key types supported by TypeScript.

    Type: string | number | symbol

    Example:

    function getProperty<T, K extends AVStantso.TS.Key>(obj: T, key: K) {
      return obj[key];
    }

    AVStantso.TS.Key2Key<K>

    Creates a record mapping each key to itself.

    Type Parameters:

    • K extends Key - Union of keys to map

    Example:

    type Letters = AVStantso.TS.Key2Key<'a' | 'b' | 'c'>;
    // Result: { a: 'a', b: 'b', c: 'c' }

    AVStantso.TS.Arr

    Type representing any array, useful for type guards and constraints.

    Warning: Use only for checks or constraints, not for definitions.

    Example:

    type IsStruct<T extends object> = T extends AVStantso.TS.Arr ? false : true;

    AVStantso.TS.ArrR

    Type representing any readonly array.

    Example:

    function processArray<T extends AVStantso.TS.ArrR>(arr: T) {
      // Handle readonly arrays
    }

    AVStantso.TS.OL<T>

    One or List - accepts either a single value of type T or a readonly array of T.

    Type Parameters:

    • T - Value or item type

    Example:

    function normalize<T>(input: AVStantso.TS.OL<T>): T[] {
      return Array.isArray(input) ? [...input] : [input];
    }
    
    normalize(5);           // [5]
    normalize([1, 2, 3]);   // [1, 2, 3]

    AVStantso.TS.Func<R, P>

    Generic function type with optional result and parameter types.

    Type Parameters:

    • R - Return type (default: unknown)
    • P extends Arr - Parameters array type (default: any[])

    Example:

    type StringValidator = AVStantso.TS.Func<boolean, [string]>;
    const isEmail: StringValidator = (str) => /\S+@\S+\.\S+/.test(str);
    AVStantso.TS.Func.Is<T, IfTrue, IfFalse>

    Type-level function check that returns different types based on whether T is a function.

    Type Parameters:

    • T - Type to check
    • IfTrue - Result if T is a function (default: true)
    • IfFalse - Result if T is not a function (default: false)

    Example:

    type Check1 = AVStantso.TS.Func.Is<() => void>;        // true
    type Check2 = AVStantso.TS.Func.Is<{ name: string }>;  // false
    type Check3 = AVStantso.TS.Func.Is<undefined>;         // false
    AVStantso.TS.Func.Promise<R, P>

    Function type that returns a Promise.

    Type Parameters:

    • R - Promise result type (default: unknown)
    • P extends Arr - Parameters array type (default: any[])

    Example:

    type AsyncFetcher = AVStantso.TS.Func.Promise<string, [string]>;
    const fetchData: AsyncFetcher = async (url) => {
      const response = await fetch(url);
      return response.text();
    };

    AVStantso.TS.Proc<P>

    Procedure type - a function that returns void.

    Type Parameters:

    • P extends Arr - Parameters array type (default: any[])

    Example:

    type Logger = AVStantso.TS.Proc<[string, ...any[]]>;
    const log: Logger = (message, ...args) => {
      console.log(message, ...args);
    };
    AVStantso.TS.Proc.Promise<P>

    Procedure type that returns Promise<void>.

    Example:

    type AsyncAction = AVStantso.TS.Proc.Promise<[number]>;
    const saveData: AsyncAction = async (id) => {
      await fetch(`/api/save/${id}`, { method: 'POST' });
    };

    AVStantso.TS.Class<I, P>

    Generic class constructor type.

    Type Parameters:

    • I - Instance type (default: unknown)
    • P extends Arr - Constructor parameters (default: any[])

    Example:

    type UserClass = AVStantso.TS.Class<User, [string, number]>;
    
    function createInstance<T>(ctor: AVStantso.TS.Class<T>, ...args: any[]): T {
      return new ctor(...args);
    }

    AVStantso.TS.HasString<U, IfTrue, IfFalse>

    Checks if a union type includes the string type (not just string literals).

    Type Parameters:

    • U - Union type to check
    • IfTrue - Result if union includes string (default: true)
    • IfFalse - Result if union doesn't include string (default: false)

    Example:

    type Check1 = AVStantso.TS.HasString<string>;              // true
    type Check2 = AVStantso.TS.HasString<'A' | 'B' | 'C'>;     // false
    type Check3 = AVStantso.TS.HasString<'A' | 'B' | string>;  // true
    type Check4 = AVStantso.TS.HasString<number>;              // false

    AVStantso.CheckType<TActual, TExpected>

    Type-level assertion that ensures TActual extends TExpected. Used for type validation in examples and tests.

    Type Parameters:

    • TActual - The actual calculated type
    • TExpected - The expected type constraint

    Example:

    type User = { id: string; version: number };
    
    // This compiles - User extends Pick<User, 'id'>
    type Valid = AVStantso.CheckType<User, Pick<User, 'id'>>;
    
    // This fails - User doesn't extend { name: string }
    // type Invalid = AVStantso.CheckType<User, { name: string }>;
    //                ❌ Type 'User' does not satisfy the constraint '{ name: string }'

    AVStantso.Catch - Error Handling System

    Centralized error handling with filtering capabilities.

    Setup:

    import axios from 'axios';
    import toast from 'any-toaster-library';
    
    // Filter out cancelled requests
    avstantso.Catch._addFilter(axios.isCancel);
    
    // Set default error handler
    avstantso.Catch._default = (error) => {
      toast.error(`Error: ${error.message}`);
    };
    
    // Export for use in app
    export const E: AVStantso.Catch = avstantso.Catch;

    Usage:

    import { E } from './error-handler';
    
    // In React component
    useEffect(() => {
      axiosInstance.get('/api/users')
        .then(setUsers, E);  // E handles any errors
    }, []);
    
    // In async functions
    async function loadData() {
      try {
        const data = await fetchData();
        processData(data);
      } catch (error) {
        E(error);  // Centralized error handling
      }
    }

    Methods:

    • avstantso.Catch._addFilter(predicate) - Add error filter to ignore specific errors
    • avstantso.Catch._default - Set default error handler function
    • avstantso.Catch(error) - Handle an error using registered handlers

    AVStantso.AtomicObjects - Custom Object Registry

    Registry system for objects requiring special serialization or visualization logic.

    Members:

    • avstantso.AtomicObjects.classes - Readonly map of registered atomic object classes
    • avstantso.AtomicObjects.register(class, options) - Register a class as atomic
    • avstantso.AtomicObjects.is(obj) - Check if object is atomic
    • avstantso.AtomicObjects.descriptor(obj) - Get atomic object descriptor

    Example - Deep Clone with Atomic Objects:

    import { Date } from 'some-custom-date-library';
    
    // Register custom Date class
    avstantso.AtomicObjects.register(Date, {
      clone: (date) => new Date(date.getTime()),
      serialize: (date) => date.toISOString(),
    });
    
    function deepClone(obj: unknown): unknown {
      // Handle primitives
      if (typeof obj !== 'object' || obj === null) return obj;
    
      // Handle atomic objects (Date, RegExp, custom classes, etc.)
      const descriptor = avstantso.AtomicObjects.descriptor(obj);
      if (descriptor) return descriptor.clone(obj);
    
      // Handle arrays
      if (Array.isArray(obj)) return obj.map(deepClone);
    
      // Handle plain objects
      return Object.fromEntries(
        Object.entries(obj).map(([key, value]) => [key, deepClone(value)])
      );
    }
    
    const original = {
      name: 'John',
      birthDate: new Date('1990-01-01'),
      tags: ['developer', 'typescript']
    };
    
    const cloned = deepClone(original);
    // Custom Date instance is properly cloned using registered clone method

    AVStantso.Generic - Generic Type Utilities

    Utilities for working with generic types.

    Members:

    • AVStantso.Generic.Validator - Type validator for generics
    • AVStantso.Generic.Cast - Type casting utility to resolve generic issues

    Example:

    function process<T>(value: T) {
      // Use Generic.Cast to resolve complex generic scenarios
      const casted = AVStantso.Generic.Cast<SomeComplexType>(value);
      return casted;
    }

    AVStantso.Func - Function Utilities

    Runtime utilities for working with functions.

    Members:

    • avstantso.Func.OwnPropertyDescriptors - Property descriptors of the base Function prototype
    • avstantso.Func.isPropAllowed(key) - Check if a property name can be used for function extension
    • avstantso.Func.isPropAllowed.Not(key) - Check if property name is reserved
    • avstantso.Func.isExt(func) - Check if function has extended properties
    • avstantso.Func.Dynamic<N, F>(name, func) - Creates a named function wrapper for better debugging in development environments

    Example - Type Guard Function Factory:

    const Types = ['insert', 'update', 'delete'] as const;
    type ActionType = typeof Types[number];
    
    type Action<T extends ActionType> =
      | (T extends 'insert' ? { type: 'insert'; value: string } : never)
      | (T extends 'update' ? { type: 'update'; id: number; value: string } : never)
      | (T extends 'delete' ? { type: 'delete'; id: number } : never);
    
    // Base type guard function
    function _isActionType<T extends ActionType>(
      type: T,
      action: Action<ActionType>
    ): action is Action<T> {
      return action.type === type;
    }
    
    console.log(avstantso.Func.isExt(_isActionType)); // false
    
    // Extend function with type-specific methods
    const isActionType = Object.assign(
      _isActionType,
      Object.fromEntries(
        Types
          .filter(avstantso.Func.isPropAllowed)  // Filter valid property names
          .map((type) => [
            type,
            _isActionType.bind(null, type)
          ])
      )
    ) as typeof _isActionType & Record<ActionType, (action: Action<ActionType>) => boolean>;
    
    console.log(avstantso.Func.isExt(isActionType));  // true
    
    // Usage
    const action: Action<ActionType> = { type: 'insert', value: 'test' };
    
    if (isActionType.insert(action)) {
      console.log(action.value);  // TypeScript knows this is insert action
    }
    avstantso.Func.Dynamic<N, F>(name, func)

    Creates a named function wrapper for better debugging in development environments. In production, returns the original function unchanged.

    Type Parameters:

    • N extends string - Function name for debugging
    • F extends Function - Function to wrap

    Parameters:

    • name - The name to give the function (visible in stack traces and debuggers)
    • func - The function implementation

    Returns: In development mode, returns a named wrapper function; in production, returns func unchanged

    Use Cases:

    • Better stack traces in development
    • Improved debugging experience
    • Named anonymous functions without performance cost in production

    Example:

    // Without Dynamic - anonymous function in stack traces
    const handler1 = (event: Event) => {
      console.log(event);
    };
    
    // With Dynamic - named function in development, original in production
    const handler2 = avstantso.Func.Dynamic('handleClick', (event: Event) => {
      console.log(event);
    });
    
    // Development: Stack trace shows "handleClick"
    // Production: No performance overhead, uses original function
    
    // Useful for dynamically created functions
    function createValidator(fieldName: string) {
      return avstantso.Func.Dynamic(
        `validate${fieldName}`,
        (value: unknown) => {
          // validation logic
          return typeof value === 'string';
        }
      );
    }
    
    const validateUsername = createValidator('Username');
    // In dev tools: function name shows as "validateUsername"

    AVStantso.X - No-op Utility

    A no-op (no operation) function that returns undefined. Useful for ignoring Promise results in .then() and .catch() chains.

    Signature: X<T = any>(): T

    Returns: undefined

    Use Cases:

    • Ignore Promise success or error results
    • Cleaner alternative to empty arrow functions
    • Make intent explicit in Promise chains

    Example:

    import { X } from '@avstantso/core';
    // or use: avstantso.X
    
    // Instead of this:
    promise.then(() => {}).catch(() => {});
    
    // Use X for cleaner code:
    promise.then(X).catch(X);
    
    // Practical example - fire and forget
    async function savePreferences(prefs: UserPrefs) {
      // Save to server but don't wait or handle errors
      saveToServer(prefs).then(X).catch(X);
    
      // Continue with other work
      updateLocalCache(prefs);
    }
    
    // Another example - optional logging
    const logError = process.env.DEBUG ? console.error : X;
    promise.catch(logError); // Only logs in DEBUG mode

    Global Runtime Object

    The avstantso global object provides runtime access to all features.

    Properties:

    • avstantso.freeze() - Recursively freeze all internals (call after setup)
    • avstantso.symbolFreeze - Symbol for custom freeze behavior
    • avstantso.debugState - External state for debugging (available until freeze)
    • avstantso.RegisterGlobalNamespace(name, statics?) - Factory for creating custom global namespaces

    avstantso.RegisterGlobalNamespace<TCode>(name, statics?)

    Registers a global namespace and singleton, similar to how AVStantso/avstantso itself is created. Creates two global references:

    • globalThis.Name (capitalized) - the namespace for TypeScript type declarations
    • globalThis.name (lowercase) - the singleton for runtime code access

    The lowercase singleton avoids reference errors in Jest and other test environments where global namespace access may be restricted.

    Type Parameters:

    • TCode - Interface describing the runtime structure of the singleton (e.g., MyApp.Code)

    Parameters:

    • name: string - The global name to register (e.g., 'MyApp' creates MyApp and myapp)
    • statics?: object - Optional initial static properties to include in the singleton

    Returns: The created singleton object with registration utilities (_reg, freeze(), symbolFreeze)

    Features:

    • Creates a freezable singleton accessible globally by both capitalized and lowercase names
    • Provides _reg proxy for registering new fields with lazy initialization
    • Supports freeze() method to recursively freeze all internals
    • Includes symbolFreeze for custom freeze behavior on specific objects

    Important: All exported namespace constants and functions (UPPERCASE) must be expressed through the lowercase singleton global variable. This ensures consistent runtime behavior across different environments.

    Important: In TypeScript namespace (e.g. MyApp) runtime features must be only in the root namespace (not in nested namespaces). If you use complex structure and nesting:

    • define internal-used runtimes only in the root namespace
    • define export consts from _reg only in the root namespace
    • for nested features use _reg without saving the result
    • see my source code as a reference to avoid hard-to-catch errors in different environments

    Example:

    // Create a custom namespace for your application
    const myApp = avstantso.RegisterGlobalNamespace<MyApp.Code>('MyApp', {
      version: '1.0.0'
    });
    
    // TypeScript namespace declarations use uppercase
    declare namespace MyApp {
      export interface Config { debug: boolean, apiUrl: string };
      export interface Utils {
        format(value: string): string;
      };
    
      // Runtime interface of myApp
      export interface Code {
        Config: Config;
        Utils: Utils;
      }
    
      // Register new fields using the _reg proxy
      export const Config = myApp._reg.Config({ debug: true, apiUrl: '/api' });
      export const Utils = myApp._reg.Utils.format((singleton) => {
        // Lazy initialization with access to partial singleton
        return (value: string) => value.trim().toLowerCase();
      });
    }
    
    // Access globally via lowercase singleton (recommended)
    console.log(myapp.version);       // '1.0.0'
    console.log(myapp.Config.debug);  // true
    
    // In file my-app.export.ts
    import version = MyApp.version;
    import Config = MyApp.Config;
    import Utils = MyApp.Utils;
    
    export { version, Config, Utils };
    
    // In any file of your app:
    import { version, Config } from './my-app.export';
    
    console.log(version);       // '1.0.0'
    console.log(Config.debug);  // true
    
    // In index file
    // Freeze when setup is complete
    myapp.freeze();

    Requirements

    • Node.js 12.0 or higher
    • TypeScript 4.0 or higher (for TypeScript projects)

    Dependencies

    • @avstantso/std-ext - Standard library extensions

    License

    MIT - See LICENSE file for details

    Repository

    GitLab - avstantso-js/cross-platform-utils

    Contributing

    Contributions are welcome! Please feel free to submit issues or pull requests to the repository.