This commit is contained in:
maciejhirsz
2018-06-27 15:56:32 +02:00
parent 0580e25380
commit 4812a5ddce
53 changed files with 152 additions and 1002 deletions
+22
View File
@@ -0,0 +1,22 @@
/**
* PhantomData akin to Rust, because sometimes you need to be smarter than
* the compiler.
*/
export class PhantomData<P> { private __PHANTOM__: P }
/**
* Opaque type, similar to `opaque type` in Flow, or new types in Rust/C.
* These should be produced only by manually casting `t as Opaque<T, P>`.
*
* `P` can be anything as it's never actually used. Using strings is okay:
*
* ```
* type MyType = Opaque<number, 'MyType'>;
* ```
*/
export type Opaque<T, P> = T & PhantomData<P>;
/**
* Just a readable shorthand for null-ish-able types, akin to `T?` in Flow.
*/
export type Maybe<T> = T | null | undefined;
+14 -10
View File
@@ -1,4 +1,4 @@
import { Opaque } from './types';
import { Opaque } from './helpers';
/**
* Unique type-constrained Id number.
@@ -8,28 +8,32 @@ export type Id<T> = Opaque<number, T>;
/**
* Higher order function producing new auto-incremented `Id`s.
*/
export function idGenerator<T>(): () => Id<T> {
export function idGenerator<I extends Id<any>>(): () => I {
let current = 0;
return () => current++ as Id<T>;
return () => current++ as I;
}
interface HasId<T> {
id: Id<T>;
interface HasId<I> {
id: I;
}
export class IdSet<T> {
private map: Map<Id<T>, T> = new Map();
export class IdSet<I extends Id<any>, T> {
private map: Map<I, T> = new Map();
public add(item: T & HasId<T>) {
public add(item: T & HasId<I>) {
this.map.set(item.id, item);
}
public remove(item: T & HasId<T>) {
public remove(item: T & HasId<I>) {
this.map.delete(item.id);
}
public get entries(): IterableIterator<T> {
public entries(): IterableIterator<[I, T]> {
return this.map.entries();
}
public values(): IterableIterator<T> {
return this.map.values();
}
}
+6 -2
View File
@@ -1,3 +1,7 @@
export * from './id';
export * from './iterators';
export * from './types';
export * from './helpers';
export * from './id';
import * as Types from './types';
export { Types };
+37 -20
View File
@@ -1,22 +1,39 @@
/**
* PhantomData akin to Rust, because sometimes you need to be smarter than
* the compiler.
*/
export class PhantomData<P> { private __PHANTOM__: P }
import { Opaque } from './helpers';
import { Id } from './id';
/**
* Opaque type, similar to `opaque type` in Flow, or new types in Rust/C.
* These should be produced only by manually casting `t as Opaque<T, P>`.
*
* `P` can be anything as it's never actually used. Using strings is okay:
*
* ```
* type MyType = Opaque<number, 'MyType'>;
* ```
*/
export type Opaque<T, P> = T & PhantomData<P>;
export type FeedId = Id<'Feed'>;
export type NodeId = Id<'Node'>;
export type NodeName = Opaque<string, 'NodeName'>;
export type BlockNumber = Opaque<number, 'BlockNumber'>;
export type Milliseconds = Opaque<number, 'Milliseconds'>;
/**
* Just a readable shorthand for null-ish-able types, akin to `T?` in Flow.
*/
export type Maybe<T> = T | null | undefined;
export interface BlockDetails {
height: BlockNumber;
blockTime: Milliseconds;
}
export interface NodeDetails {
name: NodeName;
}
interface BestBlock {
action: 'best';
payload: BlockNumber;
}
interface AddedNode {
action: 'added';
payload: [NodeId, NodeDetails, BlockDetails];
}
interface RemovedNode {
action: 'removed';
payload: NodeId;
}
interface Imported {
action: 'imported';
payload: [NodeId, BlockDetails];
}
export type FeedMessage = BestBlock | AddedNode | RemovedNode | Imported;