🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

@commonmodule/ts

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@commonmodule/ts

A TypeScript utility module that provides various classes and helpers for events, trees, data structures, string manipulation, object comparison, JSON utilities, and communication management through a realtime client.

0.3.6
latest
npm
Version published
Weekly downloads
31
-20.51%
Maintainers
1
Weekly downloads
 
Created
Source

@commonmodule/ts

A TypeScript utility module that provides various classes and helpers for events, trees, data structures, string manipulation, object comparison, JSON utilities, and communication management through a realtime client.

Notice on exports

Most utility classes (e.g. StringUtils, ObjectUtils) are exported as a singleton instance, not the class constructor.

import { StringUtils } from "@commonmodule/ts";
// StringUtils is already an instantiated object – no `new` needed.

When you need the class itself (rare), import from its relative path instead.

Table of Contents

Installation

npm install @commonmodule/ts
# or
yarn add @commonmodule/ts

API Reference

Communication

RealtimeClient

An interface representing a realtime connection or transport layer. Implementations should provide methods for sending and receiving messages.

interface RealtimeClient {
  send(message: string): void;
  onMessage(handler: (message: string) => void): void;
}

Members:

MemberAccessDescription
send(message: string)publicSends a message (serialized string) over the connection.
onMessage(handler: (message: string) => void)publicRegisters a callback that executes whenever a message is received.

MessageChannelManager

A class that manages message channels, actions, and optional request–response flows via a RealtimeClient.

class MessageChannelManager<
  Handlers extends Record<string, (...args: any[]) => any>,
> {
  constructor(client: RealtimeClient) {/* ... */}
  // ...
}

Constructor:

  • client: RealtimeClient – The realtime client instance used for communication.

Members:

MemberAccessDescription
on<Action extends keyof Handlers>(channel: string, action: Action, handler: Handlers[Action])publicSubscribes to a specific channel/action pair.
off<Action extends keyof Handlers>(channel: string, action: Action, handler?: Handlers[Action])publicUnsubscribes from a channel/action. If no handler is specified, removes all handlers for that action.
send(channel: string, action: string, ...args: any[])publicSends a message on the specified channel with the given action and arguments.
request<ResponseType>(channel: string, action: string, ...args: any[]): Promise<ResponseType>publicSends a request message (with a unique requestId) on the specified channel. Returns a Promise that resolves or rejects when the response or error is received.

Event

EventRecord

A simple type alias defining the structure of event-handler objects:

type EventRecord = Record<string, (...args: any[]) => any>;

Each event is identified by a string key, and each key’s value is a function taking arbitrary arguments.

EventContainer

Manages subscriptions and emissions for a set of events described by an EventRecord.

class EventContainer<E extends EventRecord = EventRecord> {
  // ...
}

Members:

MemberAccessDescription
on<K extends keyof E>(eventName: K, eventHandler: E[K])publicRegisters an event handler for the specified event name.
off<K extends keyof E>(eventName: K, eventHandler?: E[K])publicRemoves a handler from an event. If no handler is passed, removes all handlers for that event.
emit<K extends keyof E>(eventName: K, ...args: Parameters<E[K]>): Promise<ReturnType<E[K]>[]>protectedTriggers all handlers associated with an event name (asynchronously). Returns an array of results (including any awaited promises).
hasEvent<K extends keyof E>(eventName: K): booleanprotectedChecks whether this container has any handlers for the given event name.
clearEvents()protectedRemoves all events and handlers from this container (used internally for cleanup).

Note: The emit() method is protected by default in the code above, but you can change it to public if needed in your own implementation.
For asynchronous event results, always await emit() if you need the aggregated return values.

Loaders

ResourceLoader

An abstract class for loading and managing reference-counted resources.

abstract class ResourceLoader<T> {
  // ...
}

Members:

MemberAccessDescription
resources: Map<string, T>protectedStores loaded resources by ID.
pendingLoads: Map<string, Promise<T | undefined>>protectedKeeps track of pending load operations.
load(id: string, ...args: any[]): Promise<T | undefined>publicIncrements the reference count for the resource. If already loaded or loading, returns the existing resource/promise; otherwise, calls loadResource.
isLoaded(id: string): booleanpublicChecks if a resource is currently loaded (i.e., exists in resources map).
release(id: string): voidpublicDecrements the resource’s reference count. If it drops to 0, calls cleanup(resource, id) and removes the resource from resources.
isResourceInUse(id: string): booleanprotectedChecks if a resource is still in use (i.e., reference count > 0).
loadResource(id: string, ...args: any[]): Promise<T | undefined>protected abstractSubclasses must implement the actual resource loading logic.
cleanup(resource: T, id: string): voidprotected abstractSubclasses must define how to clean up the resource (e.g. disposing of memory, closing connections) after the reference count drops to 0.

Tree

TreeNode

An abstract class that represents a tree node structure with a parent-child relationship.

abstract class TreeNode<T extends TreeNode<T>> {
  // ...
}

Key Properties:

  • parent: T | undefined – The parent node.
  • children: T[] – List of child nodes.
  • removed: boolean – If true, the node has been removed from its parent.

Members:

MemberAccessDescription
appendTo(parent: T, index?: number): thispublicAppends the current node to a new parent node. If index is specified, the node is inserted at that position within the parent's children.
clear(...except: (T | undefined)[]): thispublicRemoves all children except for the specified ones.
remove(): voidpublicRemoves the current node from its parent and clears all of its children.

EventTreeNode

Extends TreeNode to add event handling via an internal event container. Particularly useful for hierarchical data structures that emit or listen to events.

abstract class EventTreeNode<
  T extends EventTreeNode<T, E>,
  E extends EventRecord,
> extends TreeNode<T> {
  // ...
}

Key Differences from TreeNode:

  • Has an internal EventContainer to handle its own events.
  • Supports event subscription, emission, and cleanup on removal.

Members:

MemberAccessDescription
on<K extends keyof (E & { remove: () => void })>(eventName: K, handler: (E & { remove: () => void })[K])publicRegisters an event handler for the given event name.
off<K extends keyof (E & { remove: () => void })>(eventName: K, handler?: (E & { remove: () => void })[K])publicUnregisters an event handler for the given event name.
subscribe<E2 extends (EventRecord & { remove: () => void }), K extends keyof E2>(target: EventTreeNode<any, E2>, eventName: K, handler: E2[K])publicSubscribes to events from another EventTreeNode. Automatically unsubscribes if that target node is removed.
remove(): voidpublicRemoves this node, emits a remove event, clears its event handlers, and unsubscribes from any other nodes. Always call super.remove() if you override.

Utils

IntegerUtils

Provides utility methods for integer-related operations (exported as a singleton instance).

Members:

MemberAccessDescription
random(min: number, max: number)publicGenerates a random integer between min and max (inclusive).

StringUtils

Utility class (exported as a singleton instance) for common string manipulations.

Members:

MemberAccessDescription
capitalize(input: string): stringpublicCapitalizes the first letter of each word in a given string, making all other letters lowercase.
isKebabCase(str: string): booleanpublicChecks if a given string is in kebab-case (lowercase words separated by hyphens).
formatNumberWithCommas(value: string, decimals?: number): stringpublicInserts commas as thousands separators in a numeric string. If decimals is provided (and the number is within safe integer range), it formats to that many decimals.

ArrayUtils

Provides utility methods for array manipulation (exported as a singleton instance).

Members:

MemberAccessDescription
pull<T>(array: T[], ...removeList: T[]): voidpublicRemoves the specified elements (removeList) from the given array, if they exist.

ObjectUtils

Utility class (exported as a singleton instance) for object comparisons.

Members:

MemberAccessDescription
isEqual(obj1: any, obj2: any): booleanpublicPerforms a deep comparison to check if two objects are equivalent.

JsonUtils

Utilities for JSON parsing and handling edge cases like nullundefined.

Members:

MemberAccessDescription
parseWithUndefined<T>(data: string): TpublicParses JSON data, converting null values to undefined.

Debouncer

A class to debounce function execution. Useful for events that should only fire after a certain time has elapsed without re-triggering.

class Debouncer {
  constructor(delayMs: number, callback: (...args: any[]) => void) {/* ... */}
  // ...
}

Constructor:

  • delayMs: number – The time in milliseconds to wait before calling the callback. Must be >= 0.
  • callback: (...args: any[]) => void – The function to call after the delay.

Members:

MemberAccessDescription
execute(...args: any[]): voidpublicSchedules the callback to run after the specified delay. If called again before the delay expires, the timer resets.
cancel(): voidpublicCancels any pending debounced callback.
isPending(): booleanpublicReturns true if there is a pending execution that hasn’t yet fired.

Usage Examples

Below are some short usage examples illustrating how to use the provided classes and functions.

StringUtils Example

import { StringUtils } from "@commonmodule/ts";

const text = "hello world from TS";
const capitalized = StringUtils.capitalize(text);
console.log(capitalized);
// Output: "Hello World From Ts"

console.log(StringUtils.isKebabCase("kebab-case-example")); // true

ObjectUtils Example

import { ObjectUtils } from "@commonmodule/ts";

const objA = { name: "Alice", details: { age: 30 } };
const objB = { name: "Alice", details: { age: 30 } };
console.log(ObjectUtils.isEqual(objA, objB)); // true

Debouncer Example

import { Debouncer } from "@commonmodule/ts";

function saveToServer(data: any) {
  console.log("Saving data to server:", data);
}

const debouncedSave = new Debouncer(500, saveToServer);

debouncedSave.execute({ id: 1 });
// If "execute" is called again within 500ms, the old call is canceled
debouncedSave.execute({ id: 2 }); // Only this call will run after 500ms

EventContainer Example

import { EventContainer } from "@commonmodule/ts";

class MyEventContainer extends EventContainer<{
  dataReceived: (data: any) => void;
}> {
  constructor() {
    super();

    this.on("dataReceived", (data) => {
      console.log("Data received:", data);
    });

    // Emit an event
    this.emit("dataReceived", { message: "Hello" });
    // => "Data received: { message: 'Hello' }"
  }
}

MessageChannelManager Example

import { MessageChannelManager, RealtimeClient } from "@commonmodule/ts";

class WebSocketClient implements RealtimeClient {
  private socket: WebSocket;
  private messageHandler?: (message: string) => void;

  constructor(url: string) {
    this.socket = new WebSocket(url);
    this.socket.onmessage = (event) => {
      if (this.messageHandler) {
        this.messageHandler(event.data);
      }
    };
  }

  send(message: string): void {
    this.socket.send(message);
  }

  onMessage(handler: (message: string) => void): void {
    this.messageHandler = handler;
  }
}

const client = new WebSocketClient("ws://example.com");
const manager = new MessageChannelManager<{
  greet: (name: string) => void;
}>(client);

// Listen for 'greet' actions on channel "chat"
manager.on("chat", "greet", (name) => {
  console.log("Hello,", name);
});

// Send a message
manager.send("chat", "greet", "Alice");
// => Console: "Hello, Alice"

// Request/Response pattern
(async () => {
  try {
    const response = await manager.request<string>("chat", "getWelcomeMessage");
    console.log("Received welcome message:", response);
  } catch (error) {
    console.error("Failed to get welcome message:", error);
  }
})();

Contributing

  • Fork the repository.
  • Create a new branch: git checkout -b feature/my-feature.
  • Make your changes and commit: git commit -m 'Add my feature'.
  • Push the changes: git push origin feature/my-feature.
  • Create a pull request.

License

This module is provided under the MIT License. For more details, please see the LICENSE file in the repository.

Author: yj.gaia

FAQs

Package last updated on 10 May 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts