Skip to content

Commit

Permalink
feat(common): new utils, truncate table ID parts (#1173)
Browse files Browse the repository at this point in the history
Co-authored-by: alvarius <alvarius@lattice.xyz>
  • Loading branch information
holic and alvrs authored Jul 19, 2023
1 parent 5352299 commit 0c4f9fe
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 8 deletions.
13 changes: 13 additions & 0 deletions .changeset/strange-ducks-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@latticexyz/common": minor
---

`TableId.toHex()` now truncates name/namespace to 16 bytes each, to properly fit into a `bytes32` hex string.

Also adds a few utils we'll need in the indexer:

- `bigIntMin` is similar to `Math.min` but for `bigint`s
- `bigIntMax` is similar to `Math.max` but for `bigint`s
- `bigIntSort` for sorting an array of `bigint`s
- `chunk` to split an array into chunks
- `wait` returns a `Promise` that resolves after specified number of milliseconds
14 changes: 10 additions & 4 deletions packages/common/src/TableId.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ describe("TableId", () => {
);
});

it("throws when converting namespaces >16 bytes", () => {
it("truncates namespaces >16 bytes", () => {
const tableId = new TableId("AVeryLongNamespace", "name");
expect(() => tableId.toHex()).toThrow("Size cannot exceed 16 bytes. Given size: 18 bytes.");
expect(tableId.toHex()).toMatchInlineSnapshot(
'"0x41566572794c6f6e674e616d657370616e616d65000000000000000000000000"'
);
expect(TableId.fromHex(tableId.toHex()).namespace).toMatchInlineSnapshot('"AVeryLongNamespa"');
});

it("throws when converting names >16 bytes", () => {
it("truncates names >16 bytes", () => {
const tableId = new TableId("namespace", "AnUnnecessarilyLongName");
expect(() => tableId.toHex()).toThrow("Size cannot exceed 16 bytes. Given size: 23 bytes.");
expect(tableId.toHex()).toMatchInlineSnapshot(
'"0x6e616d65737061636500000000000000416e556e6e65636573736172696c794c"'
);
expect(TableId.fromHex(tableId.toHex()).name).toMatchInlineSnapshot('"AnUnnecessarilyL"');
});

it("can convert from hex string", () => {
Expand Down
8 changes: 4 additions & 4 deletions packages/common/src/TableId.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Hex, stringToHex, hexToString, sliceHex, concatHex } from "viem";

export class TableId {
namespace: string;
name: string;
readonly namespace: string;
readonly name: string;

constructor(namespace: string, name: string) {
this.namespace = namespace;
this.name = name;
this.namespace = namespace.substring(0, 16);
this.name = name.substring(0, 16);
}

toString(): string {
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/utils/bigIntMax.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function bigIntMax(...args: bigint[]): bigint {
return args.reduce((m, e) => (e > m ? e : m));
}
3 changes: 3 additions & 0 deletions packages/common/src/utils/bigIntMin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function bigIntMin(...args: bigint[]): bigint {
return args.reduce((m, e) => (e < m ? e : m));
}
3 changes: 3 additions & 0 deletions packages/common/src/utils/bigIntSort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function bigIntSort(a: bigint, b: bigint): -1 | 0 | 1 {
return a < b ? -1 : a > b ? 1 : 0;
}
94 changes: 94 additions & 0 deletions packages/common/src/utils/chunk.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { describe, it, expect } from "vitest";
import { chunk } from "./chunk";

describe("chunk", () => {
it("splits an array into chunks", () => {
expect(Array.from(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 3))).toMatchInlineSnapshot(`
[
[
1,
2,
3,
],
[
4,
5,
6,
],
[
7,
8,
9,
],
]
`);

expect(Array.from(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 5))).toMatchInlineSnapshot(`
[
[
1,
2,
3,
4,
5,
],
[
6,
7,
8,
9,
],
]
`);

expect(Array.from(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 8))).toMatchInlineSnapshot(`
[
[
1,
2,
3,
4,
5,
6,
7,
8,
],
[
9,
],
]
`);

expect(Array.from(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 9))).toMatchInlineSnapshot(`
[
[
1,
2,
3,
4,
5,
6,
7,
8,
9,
],
]
`);

expect(Array.from(chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 10))).toMatchInlineSnapshot(`
[
[
1,
2,
3,
4,
5,
6,
7,
8,
9,
],
]
`);
});
});
5 changes: 5 additions & 0 deletions packages/common/src/utils/chunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function* chunk<T>(arr: T[], n: number): Generator<T[], void> {
for (let i = 0; i < arr.length; i += n) {
yield arr.slice(i, i + n);
}
}
5 changes: 5 additions & 0 deletions packages/common/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export * from "./assertExhaustive";
export * from "./bigIntMax";
export * from "./bigIntMin";
export * from "./bigIntSort";
export * from "./chunk";
export * from "./curry";
export * from "./isDefined";
export * from "./isNotNull";
export * from "./wait";
3 changes: 3 additions & 0 deletions packages/common/src/utils/wait.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function wait(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}

0 comments on commit 0c4f9fe

Please sign in to comment.