@sparkstone/id-order-spacing v1.1.1
id-order-spacing
A lightweight utility library for updating the ordering of items when they are moved within an array. This package calculates new order values and applies minimal spacing adjustments to ensure consistency and avoid collisions.
What's New
- Bugfixes and stability improvements.
step
andminimumStep
are now exposed for customization.- Improved
batchIterator
example. - Simplified insert-at-end pattern using
calculateInsert(items, newItem)
.
Overview
This library offers two main functions for managing item order within an array: calculateInsert
and calculateUpdateFromMove
.
- calculateInsert is used to insert an item into an array at a specific index (or at the end if no index is provided), calculating a new order value and adjusting spacing if needed.
- calculateUpdateFromMove moves an item from one index to another within an existing array, ensuring minimal disruption to the overall order while avoiding collisions.
This is particularly useful when storing sorted arrays in a database where frequent insertions and moves occur. The library minimizes database writes by only updating order values that require adjustment.
Installation
pnpm install @sparkstone/id-order-spacing
# or
npm install @sparkstone/id-order-spacing
Usage
Simple Insert (including append)
import { calculateInsert } from "@sparkstone/id-order-spacing";
interface Item {
id: string;
order: number;
}
const items: Item[] = [
{ id: "a", order: 100 },
{ id: "b", order: 200 },
{ id: "c", order: 300 },
];
const newItem: Item = { id: "d", order: 0 }; // order will be calculated
// Insert at index 1
const result1 = calculateInsert(items, newItem, 1);
// Or insert at the end
const result2 = calculateInsert(items, newItem);
console.log(result2.items); // d gets placed after c
// After insertion:
// 1. Insert result2.item into the database (order already assigned)
await db.create(result2.item);
// 2. Iterate over `result2.changes` and update affected items in the database.
for (const [id, order] of result2.changes.entries()) {
await db.update(id, { order });
}
Moving Items
import {
calculateUpdateFromMove,
batchIterator,
} from "@sparkstone/id-order-spacing";
const result = calculateUpdateFromMove(unwrap(executors()), fromIndex, toIndex);
for (const subset of batchIterator(result.changes.entries(), 10)) {
const batch = db.createBatch();
for (const [id, order] of subset) {
batch.update(id, { order });
}
await batch.send();
}
API
calculateInsert<T>(items: T[], item: T, index?: number, opts?: { step?: number, minimumStep?: number })
items
: sorted array of items with{ id: string; order: number }
item
: the item to insert (itsorder
will be assigned)index
: optional index; if omitted, inserts at the endopts
: optional object to override defaultstep
andminimumStep
- Returns:
{ changes, items, item }
calculateUpdateFromMove<T>(items: T[], fromIndex: number, toIndex: number, opts?: { step?: number, minimumStep?: number })
- Moves an item and returns
{ changes, items }
- If
fromIndex === toIndex
, returns empty changes. opts
: optional object to override defaultstep
andminimumStep
step
and minimumStep
These constants are exposed for advanced use:
import { step, minimumStep } from "@sparkstone/id-order-spacing";
console.log(step); // Default spacing step size (e.g. 100)
console.log(minimumStep); // Minimum gap before rebalance triggers (e.g. 5)
Updated Batch Iterator Example
import {
calculateUpdateFromMove,
batchIterator,
} from "@sparkstone/id-order-spacing";
const result = calculateUpdateFromMove(unwrap(executors()), fromIndex, toIndex);
for (const subset of batchIterator(result.changes.entries(), 10)) {
const batch = db.createBatch();
for (const [id, order] of subset) {
batch.update(id, { order });
}
await batch.send();
}
Database Use Case
By assigning order
values and using these functions, you minimize write operations when inserting or moving items in database-backed lists. After each operation:
- Insert the new item with its assigned
order
(returned asresult.item
). - Apply any changes listed in the
changes
map by updating affected records. - Use
batchIterator
to efficiently batch updates if your database supports batch writes.
This minimizes the number of writes required to keep your ordering stable and avoids unnecessary updates.
Build
pnpm run build
Repository
- GitHub: https://github.com/odama626/id-order-spacing
- Issues: https://github.com/odama626/id-order-spacing/issues
License
MIT