Skip to content

Commit

Permalink
chore: Ban TS types throughout (#3518)
Browse files Browse the repository at this point in the history
This was previously only done for replicache.

The motivation is to be able to run ts directly using node at some
point. This is a step in that direction.

The way to transition old TS enums to non TS enums is to do:

```ts
const enum E = {
  A = 1,
  B = 2,
  D = 4,
}
```

```ts
// e-enum.ts
export const A = 1;
export const B = 2;
export const D = 4;
export type A = typeof A;
export type B = typeof B;
export type D = typeof D;
```

Then in the importer do:

```ts
import * as E from './e-enum.ts';
import type {Enum} from 'shared/enum.ts';
type E = Enum<typeof E>;
```

Then you can use E and E.A as both a type and a value.

https://esbuild.github.io/try/#YgAwLjI0LjIALS1taW5pZnkgLS1idW5kbGUgLS1mb3JtYXQ9ZXNtAGUAZW50cnkuanMAaW1wb3J0ICogYXMgRSBmcm9tICcuL2UtZW51bS50cyc7CgppZiAoRS5BID09PSAxKSB7CiAgY29uc29sZS5sb2coRS5CKTsKfSBlbHNlIHsKICBjb25zb2xlLmxvZygndW5yZWFjaGFibGUnKTsKfQAAZS1lbnVtLnRzAGV4cG9ydCBjb25zdCBBID0gMTsKZXhwb3J0IGNvbnN0IEIgPSAyOwpleHBvcnQgY29uc3QgRCA9IDQ7CiAKZXhwb3J0IHR5cGUgQSA9IHR5cGVvZiBBOwpleHBvcnQgdHlwZSBCID0gdHlwZW9mIEI7CmV4cG9ydCB0eXBlIEQgPSB0eXBlb2YgRDs
  • Loading branch information
arv authored Jan 13, 2025
1 parent 9f3a68b commit fe4e0b1
Show file tree
Hide file tree
Showing 84 changed files with 425 additions and 233 deletions.
7 changes: 7 additions & 0 deletions eslint-config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
{
"extends": ["@rocicorp/eslint-config"],
"rules": {
"no-restricted-syntax": [
"error",
{
"selector": "TSEnumDeclaration",
"message": "Enums are not allowed. See shared/enum.ts"
}
],
"no-restricted-imports": [
"error",
{
Expand Down
11 changes: 1 addition & 10 deletions packages/replicache/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,7 @@
"!*.tsbuildinfo"
],
"eslintConfig": {
"extends": "../../eslint-config.json",
"rules": {
"no-restricted-syntax": [
"error",
{
"selector": "TSEnumDeclaration",
"message": "Enums are not allowed"
}
]
}
"extends": "../../eslint-config.json"
},
"prettier": "@rocicorp/prettier-config"
}
15 changes: 9 additions & 6 deletions packages/replicache/src/btree/node.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {beforeEach, describe, expect, test} from 'vitest';
import {assert} from '../../../shared/src/asserts.js';
import type {Enum} from '../../../shared/src/enum.js';
import type {ReadonlyJSONValue} from '../../../shared/src/json.js';
import {toRefs} from '../dag/chunk.js';
import type {Read, Store, Write} from '../dag/store.js';
Expand Down Expand Up @@ -31,6 +32,8 @@ import {
import {BTreeRead, NODE_HEADER_SIZE} from './read.js';
import {BTreeWrite} from './write.js';

type FormatVersion = Enum<typeof FormatVersion>;

describe('btree node', () => {
function createSizedEntry<K, V>(
key: K,
Expand All @@ -47,7 +50,7 @@ describe('btree node', () => {
function makeTree(
node: TreeData,
dagStore: Store,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
): Promise<Hash> {
return withWrite(dagStore, async dagWrite => {
const [h] = await makeTreeInner(node, dagWrite);
Expand Down Expand Up @@ -96,7 +99,7 @@ describe('btree node', () => {
async function readTreeData(
rootHash: Hash,
dagRead: Read,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
): Promise<Record<string, unknown>> {
const chunk = await dagRead.getChunk(rootHash);
const node = parseBTreeNode(chunk?.data, formatVersion, getEntrySize);
Expand Down Expand Up @@ -129,7 +132,7 @@ describe('btree node', () => {
async function expectTree(
rootHash: Hash,
dagStore: Store,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
expected: TreeData,
) {
await withRead(dagStore, async dagRead => {
Expand All @@ -154,7 +157,7 @@ describe('btree node', () => {
function doRead<R>(
rootHash: Hash,
dagStore: Store,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
fn: (r: BTreeRead) => R | Promise<R>,
): Promise<R> {
return withRead(dagStore, dagWrite => {
Expand All @@ -172,7 +175,7 @@ describe('btree node', () => {
function doWrite(
rootHash: Hash,
dagStore: Store,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
fn: (w: BTreeWrite) => void | Promise<void>,
): Promise<Hash> {
return withWrite(dagStore, async dagWrite => {
Expand Down Expand Up @@ -1656,7 +1659,7 @@ describe('Write nodes using ChainBuilder', () => {
);
}

const getBTreeNodes = async (formatVersion: FormatVersion.Type) => {
const getBTreeNodes = async (formatVersion: FormatVersion) => {
const dagStore = new TestStore();
const clientID = 'client1';
const b = new ChainBuilder(dagStore, undefined, formatVersion);
Expand Down
9 changes: 6 additions & 3 deletions packages/replicache/src/btree/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
assertNumber,
assertString,
} from '../../../shared/src/asserts.js';
import type {Enum} from '../../../shared/src/enum.js';
import {joinIterables} from '../../../shared/src/iterables.js';
import {
type JSONValue,
Expand All @@ -25,6 +26,8 @@ import {type Hash, emptyHash, newRandomHash} from '../hash.js';
import type {BTreeRead} from './read.js';
import type {BTreeWrite} from './write.js';

type FormatVersion = Enum<typeof FormatVersion>;

export type Entry<V> = readonly [key: string, value: V, sizeOfEntry: number];

export const NODE_LEVEL = 0;
Expand All @@ -43,7 +46,7 @@ export type DataNode = BaseNode<FrozenJSONValue>;
export function makeNodeChunkData<V>(
level: number,
entries: ReadonlyArray<Entry<V>>,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
): BaseNode<V> {
return deepFreeze([
level,
Expand Down Expand Up @@ -173,7 +176,7 @@ export function binarySearchFound(

export function parseBTreeNode(
v: unknown,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
getSizeOfEntry: <K, V>(key: K, value: V) => number,
): InternalNode | DataNode {
if (skipBTreeNodeAsserts && formatVersion >= FormatVersion.V7) {
Expand Down Expand Up @@ -291,7 +294,7 @@ abstract class NodeImpl<Value> {

export function toChunkData<V>(
node: NodeImpl<V>,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
): BaseNode<V> {
return makeNodeChunkData(node.level, node.entries, formatVersion);
}
Expand Down
5 changes: 4 additions & 1 deletion packages/replicache/src/btree/read.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {Enum} from '../../../shared/src/enum.js';
import {deepEqual} from '../../../shared/src/json.js';
import type {Read} from '../dag/store.js';
import type {FormatVersion} from '../format-version-enum.js';
import * as FormatVersion from '../format-version-enum.js';
import type {FrozenJSONValue} from '../frozen-json.js';
import {type Hash, emptyHash} from '../hash.js';
import {getSizeOfEntry} from '../size-of-value.js';
Expand Down Expand Up @@ -28,6 +29,8 @@ import {
computeSplices,
} from './splice.js';

type FormatVersion = Enum<typeof FormatVersion>;

/**
* The size of the header of a node. (If we had compile time
* constants we would have used that).
Expand Down
5 changes: 4 additions & 1 deletion packages/replicache/src/btree/write.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import {Lock} from '@rocicorp/lock';
import {assert} from '../../../shared/src/asserts.js';
import type {Enum} from '../../../shared/src/enum.js';
import type {ReadonlyJSONValue} from '../../../shared/src/json.js';
import {type Chunk, type CreateChunk, toRefs} from '../dag/chunk.js';
import type {Write} from '../dag/store.js';
import type {FormatVersion} from '../format-version-enum.js';
import * as FormatVersion from '../format-version-enum.js';
import type {FrozenJSONValue} from '../frozen-json.js';
import {type Hash, emptyHash, newRandomHash} from '../hash.js';
import {getSizeOfEntry} from '../size-of-value.js';
Expand All @@ -20,6 +21,8 @@ import {
} from './node.js';
import {BTreeRead} from './read.js';

type FormatVersion = Enum<typeof FormatVersion>;

export class BTreeWrite extends BTreeRead {
/**
* This rw lock is used to ensure we do not mutate the btree in parallel. It
Expand Down
2 changes: 0 additions & 2 deletions packages/replicache/src/dag/key-type-enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ export type ChunkData = typeof ChunkData;
export type ChunkMeta = typeof ChunkMeta;
export type ChunkRefCount = typeof ChunkRefCount;
export type Head = typeof Head;

export type Type = ChunkData | ChunkMeta | ChunkRefCount | Head;
9 changes: 6 additions & 3 deletions packages/replicache/src/db/commit.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {describe, expect, test} from 'vitest';
import {assert} from '../../../shared/src/asserts.js';
import type {Enum} from '../../../shared/src/enum.js';
import {Chunk, type Refs, toRefs} from '../dag/chunk.js';
import {TestStore} from '../dag/test-store.js';
import * as FormatVersion from '../format-version-enum.js';
Expand All @@ -25,8 +26,10 @@ import {
import * as MetaType from './meta-type-enum.js';
import {ChainBuilder} from './test-helpers.js';

type FormatVersion = Enum<typeof FormatVersion>;

describe('base snapshot', () => {
const t = async (formatVersion: FormatVersion.Type) => {
const t = async (formatVersion: FormatVersion) => {
const clientID = 'client-id';
const store = new TestStore();
const b = new ChainBuilder(store, undefined, formatVersion);
Expand Down Expand Up @@ -85,7 +88,7 @@ describe('base snapshot', () => {
});

describe('local mutations', () => {
const t = async (formatVersion: FormatVersion.Type) => {
const t = async (formatVersion: FormatVersion) => {
const clientID = 'client-id';
const store = new TestStore();
const b = new ChainBuilder(store, undefined, formatVersion);
Expand Down Expand Up @@ -189,7 +192,7 @@ test('local mutations greater than', async () => {
});

describe('chain', () => {
const t = async (formatVersion: FormatVersion.Type) => {
const t = async (formatVersion: FormatVersion) => {
const clientID = 'client-id';
const store = new TestStore();
const b = new ChainBuilder(store, undefined, formatVersion);
Expand Down
2 changes: 0 additions & 2 deletions packages/replicache/src/db/index-operation-enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@ export const Remove = 1;

export type Add = typeof Add;
export type Remove = typeof Remove;

export type Type = Add | Remove;
5 changes: 4 additions & 1 deletion packages/replicache/src/db/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {LogContext} from '@rocicorp/logger';
import {expect, test} from 'vitest';
import type {Enum} from '../../../shared/src/enum.js';
import type {JSONValue} from '../../../shared/src/json.js';
import {stringCompare} from '../../../shared/src/string-compare.js';
import {asyncIterableToArray} from '../async-iterable-to-array.js';
Expand All @@ -21,6 +22,8 @@ import {
indexValue,
} from './index.js';

type IndexOperation = Enum<typeof IndexOperation>;

test('test index key', () => {
const testValid = (secondary: string, primary: string) => {
// Ensure the encoded value is what we expect.
Expand Down Expand Up @@ -198,7 +201,7 @@ test('index value', async () => {
key: string,
value: JSONValue,
jsonPointer: string,
op: IndexOperation.Type,
op: IndexOperation,
expected: number[] | string,
) => {
const dagStore = new TestStore();
Expand Down
5 changes: 4 additions & 1 deletion packages/replicache/src/db/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type {LogContext} from '@rocicorp/logger';
import type {Enum} from '../../../shared/src/enum.js';
import type {BTreeRead} from '../btree/read.js';
import type {BTreeWrite} from '../btree/write.js';
import type {FrozenJSONObject, FrozenJSONValue} from '../frozen-json.js';
import type {Hash} from '../hash.js';
import type {IndexRecord} from './commit.js';
import * as IndexOperation from './index-operation-enum.js';

type IndexOperation = Enum<typeof IndexOperation>;

export class IndexRead<BTree = BTreeRead> {
readonly meta: IndexRecord;
readonly map: BTree;
Expand All @@ -32,7 +35,7 @@ export class IndexWrite extends IndexRead<BTreeWrite> {
export async function indexValue(
lc: LogContext,
index: BTreeWrite,
op: IndexOperation.Type,
op: IndexOperation,
key: string,
val: FrozenJSONValue,
jsonPointer: string,
Expand Down
2 changes: 0 additions & 2 deletions packages/replicache/src/db/meta-type-enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ export const SnapshotDD31 = 5;

export type LocalDD31 = typeof LocalDD31;
export type SnapshotDD31 = typeof SnapshotDD31;

export type Type = LocalDD31 | SnapshotDD31;
5 changes: 4 additions & 1 deletion packages/replicache/src/db/read.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {LogContext} from '@rocicorp/logger';
import {describe, expect, test} from 'vitest';
import type {Enum} from '../../../shared/src/enum.js';
import {mustGetHeadHash} from '../dag/store.js';
import {TestStore} from '../dag/test-store.js';
import * as FormatVersion from '../format-version-enum.js';
Expand All @@ -8,8 +9,10 @@ import {readFromDefaultHead} from './read.js';
import {initDB} from './test-helpers.js';
import {newWriteLocal} from './write.js';

type FormatVersion = Enum<typeof FormatVersion>;

describe('basics', () => {
const t = async (replicacheFormatVersion: FormatVersion.Type) => {
const t = async (replicacheFormatVersion: FormatVersion) => {
const clientID = 'client-id';
const dagStore = new TestStore();
const lc = new LogContext();
Expand Down
5 changes: 4 additions & 1 deletion packages/replicache/src/db/read.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {Enum} from '../../../shared/src/enum.js';
import {BTreeRead} from '../btree/read.js';
import type {Read as DagRead} from '../dag/store.js';
import type {FormatVersion} from '../format-version-enum.js';
import * as FormatVersion from '../format-version-enum.js';
import type {FrozenJSONValue} from '../frozen-json.js';
import type {Hash} from '../hash.js';
import {
Expand All @@ -12,6 +13,8 @@ import {
} from './commit.js';
import {IndexRead} from './index.js';

type FormatVersion = Enum<typeof FormatVersion>;

export class Read {
readonly #dagRead: DagRead;
map: BTreeRead;
Expand Down
15 changes: 9 additions & 6 deletions packages/replicache/src/db/rebase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {LogContext} from '@rocicorp/logger';
import sinon from 'sinon';
import {afterEach, describe, expect, test} from 'vitest';
import {assert} from '../../../shared/src/asserts.js';
import type {Enum} from '../../../shared/src/enum.js';
import {BTreeRead} from '../btree/read.js';
import type {Read} from '../dag/store.js';
import {TestStore} from '../dag/test-store.js';
Expand All @@ -24,12 +25,14 @@ import {
import {rebaseMutationAndCommit, rebaseMutationAndPutCommit} from './rebase.js';
import {ChainBuilder} from './test-helpers.js';

type FormatVersion = Enum<typeof FormatVersion>;

afterEach(() => {
sinon.restore();
});

async function createMutationSequenceFixture() {
const formatVersion: FormatVersion.Type = FormatVersion.Latest;
const formatVersion = FormatVersion.Latest;
const clientID = 'test_client_id';
const store = new TestStore();
const b = new ChainBuilder(store, undefined, formatVersion);
Expand All @@ -54,7 +57,7 @@ async function createMutationSequenceFixture() {
};

const fixture = {
formatVersion,
formatVersion: formatVersion as FormatVersion,
clientID,
store,
localCommit1,
Expand Down Expand Up @@ -139,7 +142,7 @@ async function createMutationSequenceFixture() {
}

async function createMissingMutatorFixture() {
const formatVersion: FormatVersion.Type = FormatVersion.Latest;
const formatVersion = FormatVersion.Latest;
const consoleErrorStub = sinon.stub(console, 'error');
const clientID = 'test_client_id';
const store = new TestStore();
Expand All @@ -152,7 +155,7 @@ async function createMissingMutatorFixture() {
const syncSnapshotCommit = syncChain[0] as Commit<SnapshotMetaDD31>;

const fixture = {
formatVersion,
formatVersion: formatVersion as FormatVersion,
clientID,
store,
localCommit,
Expand Down Expand Up @@ -204,7 +207,7 @@ async function createMissingMutatorFixture() {
async function commitAndBTree(
name = SYNC_HEAD_NAME,
read: Read,
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
): Promise<[Commit<Meta>, BTreeRead]> {
const commit = await commitFromHead(name, read);
const btreeRead = new BTreeRead(read, formatVersion, commit.valueHash);
Expand Down Expand Up @@ -437,7 +440,7 @@ describe('rebaseMutationAndPutCommit', () => {

async function testThrowsErrorOnClientIDMismatch(
variant: 'commit' | 'putCommit',
formatVersion: FormatVersion.Type,
formatVersion: FormatVersion,
) {
assert(formatVersion >= FormatVersion.DD31);
const clientID = 'test_client_id';
Expand Down
Loading

0 comments on commit fe4e0b1

Please sign in to comment.