npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@tsrt/ordering

v0.8.0

Published

Tools for common ordering operations with arrays

Downloads

11

Readme

Typescript Reusable Tools: Ordering

npm version GitHub license Size Downloads

Lib for common ordering operations with arrays.

Important

Until version 1.0.0 Api should be considered as unstable and may be changed.

So prefer using exact version instead of version with ~ or ^.

Usage

import { OrderingService, IOrderingServiceConfig } from '@tsrt/ordering';

interface IOrderedItem { pk: string; order: number };

// Or use default IOrderingItemDefault from package, for example.
// Or redeclare IOrderingItemDefault via Typescipt module augumentation.
// https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation

const config: IOrderingServiceConfig = { ... }
const orderingService = new OrderingService<IOrderedItem>(config);

const initialArray = [{ id: 'A', order: 0 }, { id: 'B', order: 14 }, { id: 'C', order: 22 }];
const orderChanges = [{ id: 'A', order: 15 }, { id: 'C', order: 2 }];

// It will reorder [A, B, C] into [B, A, C] -> [C, B, A], `order` properties will be updated accordingly.
const result = orderingService.reorder(initialArray, orderChanges);

// It will reorder [A, B, C] into [B, C, A], `order` properties will be updated accordingly.
const result = orderingService.reorderByIndex(initialArray, 0, 2);

// Just move item ia array from prevIndex to newIndex. DO NOT updates `order` properties.
const result = orderingService.moveItemInArray(initialArray, 0, 2);

// Here we can check whether it is necessary to perform reordering.
const result = orderingService.hasDuplicateOrEmptyOrders(initialArray);

// Here we can check whether there are any invalid items for reordering inside array.
const result = orderingService.hasInvalidOrderingItems(initialArray);

API reference

OrderingService
export declare class OrderingService<T extends GenericObject = IOrderingItemDefault> {
  /**
   *  Reorders target applying orders from listOfOrdersChanges one by one.
   *
   *  @param target - Original array.
   *  @param listOfOrdersChanges - List of order changes like: [{ `primaryKey`: value, `oderKey`: newOrderValue }]
   *
   *  @returns list, reordered according to provided order changes.
   */
  reorder<I extends T = T>(target: I[], listOfOrdersChanges?: Array<Required<T>>, config?: IOrderingOptions): Array<I & Required<T>>;

  /**
   *  Reorders target, depending on position of reordered item.
   *  Returns new array and does not mutate original array unless `updateTarget` falg is provided.
   *
   *  @param target - Original array.
   *  @param prevIndex - Item to reorder prev (from) index.
   *  @param newIndex - Item to reorder new (to) index.
   *  @param [updateTarget] - Whether to mutate original array.
   */
  reorderByIndex<I extends Required<T> = Required<T>>(target: I[], prevIndex: number, newIndex: number, updateTarget?: boolean): I[];

  /**
   *  Moves item form prevIndex to newIndex inside array.
   *  Returns new array and does not mutate original array unless `updateTarget` falg is provided.
   *
   *  @param target - Original array.
   *  @param prevIndex - Item to move prev (from) index.
   *  @param newIndex - Item to move new (to) index.
   *  @param [updateTarget] - Whether to mutate original array.
   */
  moveItemInArray<I extends T = T>(target: I[], prevIndex: number, newIndex: number, updateTarget?: boolean): I[];

  /**
   *  Checks whether provided array has items without order / empty orders. If has - returns first such item.
   *
   *  @param target - Target array.
   */
  hasDuplicateOrEmptyOrders<I extends T = T>(target: I[]): I;

  /**
   *  Checks whether provided array has invalid items. If has - returns first such item.
   *
   *  Invalid if at least for 1 item inside array one of next conditions is true:
   *  - item is null/undefined/not object;
   *  - item has no `primarKey` property;
   *  - item has no `orderKey` property (only is `strict` mode);
   *  - item `orderKey` property is not null/undefined and not number;
   *  - item `orderKey` property is not null/undefined and less than 0;
   *
   *  @param target - Target array.
   *  @param [strict=false] - Whether to throw an Error if there is no `order` property for at least 1 item.
   */
  hasInvalidOrderingItems<I extends T = T>(target: I[], strict?: boolean): I;
}
Aliases

Is is also possible to import aliases for all OrderingService public methods as functions.

This functions will work with default config:

import { reorder, reorderByIndex, moveItemInArray, hasDuplicateOrEmptyOrders, hasInvalidOrderingItems } from '@tsrt/ordering';

Options

/** Options for OrderingService reorder method. */
export interface IOrderingOptions {
  /** If false, will throw Error if `newOrder` is out of range [min, ..., max] of existing orders. Default: false. */
  allowOrdersOutOfRange?: boolean;

  /** Whether to clamp `newOrder` into range [min, ..., max] of existing orders. Default: false. */
  clampRange?: boolean;

  /**
   *  Whether to insert `empty` or `duplicate` orders only after `max` order of existing orders. Default: false.
   *  If false, will find the minimal unique order inside range [min, ..., max] of existing orders.
   */
  insertAfterOnly?: boolean;

  /** Whether to refresh orders' sequence after reordering (start from zero). Default: false. */
  refreshSequence?: boolean;
}

/** Options for OrderingService constructor. */
export interface IOrderingServiceOptions extends IOrderingOptions {
  /** Primary key to identify entities inside array for reordering. Default: 'id'. */
  primaryKey?: string;

  /** Order key to reorder entities inside array by. Default: 'order'. */
  orderKey?: string;
}

/**
 *  Default ordering item.
 *  Empty interface for TypeScript module augumentation in importing module.
 *
 *  Example: declare module '@tsrt/ordering' { export interface IOrderingItemDefault { pk: number; order?: number } }
 *  @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#module-augmentation.
 */
export interface IOrderingItemDefault { }

Default options:

export const defaultOptions: IOrderingServiceOptions = {
  primaryKey: 'id',
  orderKey: 'order',
  allowOrdersOutOfRange: false,
  clampRange: false,
  insertAfterOnly: false,
  refreshSequence: false,
};

License

This project is licensed under the terms of the MIT license.