feat: experiment with different implementations of LSEQ
This commit is contained in:
commit
1e45ef9314
23 changed files with 3578 additions and 0 deletions
61
typescript/README.md
Normal file
61
typescript/README.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# @peoplesgrocers/lseq
|
||||
|
||||
TypeScript implementation of the L-SEQ algorithm for fractional indexing and list CRDTs.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install @peoplesgrocers/lseq
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import { LSEQ, compareLSEQ } from '@peoplesgrocers/lseq';
|
||||
|
||||
// Create a new L-SEQ instance
|
||||
const lseq = new LSEQ();
|
||||
|
||||
// Allocate identifiers
|
||||
const id1 = lseq.alloc(null, null); // First identifier
|
||||
const id2 = lseq.alloc(id1, null); // After id1
|
||||
const id3 = lseq.alloc(id1, id2); // Between id1 and id2
|
||||
|
||||
// Sort identifiers
|
||||
const ids = [id3, id1, id2];
|
||||
ids.sort(compareLSEQ);
|
||||
console.log(ids); // [id1, id3, id2] - properly ordered
|
||||
|
||||
// Custom random function (useful for deterministic testing)
|
||||
const deterministicLSEQ = new LSEQ(() => 0.5);
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### `LSEQ`
|
||||
|
||||
#### `constructor(random?: () => number)`
|
||||
|
||||
Creates a new L-SEQ instance.
|
||||
|
||||
- `random`: Optional custom random function (defaults to `Math.random`)
|
||||
|
||||
#### `alloc(before: string | null, after: string | null): string`
|
||||
|
||||
Allocates a new identifier between two existing identifiers.
|
||||
|
||||
- `before`: The identifier that should come before the new one (or `null` for beginning)
|
||||
- `after`: The identifier that should come after the new one (or `null` for end)
|
||||
- Returns: A new identifier that sorts between `before` and `after`
|
||||
|
||||
### `compareLSEQ(a: string, b: string): number`
|
||||
|
||||
Compares two L-SEQ identifiers for sorting.
|
||||
|
||||
- Returns: `-1` if `a < b`, `1` if `a > b`, `0` if `a === b`
|
||||
|
||||
## How it works
|
||||
|
||||
L-SEQ generates identifiers using a base-64 alphabet that maintains lexicographic ordering. Each identifier is a sequence of characters from this alphabet, and new identifiers are generated by finding space between existing ones at different depths.
|
||||
|
||||
The algorithm uses alternating allocation strategies (bias toward min or max) at different depths to avoid degenerative cases and maintain good performance characteristics.
|
||||
Loading…
Add table
Add a link
Reference in a new issue