Create dedicated dates module

This commit is contained in:
Simon Warta 2021-02-11 23:46:33 +01:00
parent c0f30bdfca
commit 85f4bae3c4
9 changed files with 74 additions and 80 deletions

View File

@ -1,7 +1,7 @@
import { fromBase64, fromHex } from "@cosmjs/encoding";
import { ReadonlyDate } from "readonly-date";
import { ReadonlyDateWithNanoseconds } from "../../types";
import { ReadonlyDateWithNanoseconds } from "../../dates";
import { hashBlock, hashTx } from "./hasher";
describe("Hasher", () => {

View File

@ -3,6 +3,7 @@ import { fromBase64, fromHex } from "@cosmjs/encoding";
import { JsonRpcSuccessResponse } from "@cosmjs/json-rpc";
import { assert } from "@cosmjs/utils";
import { DateTime } from "../../dates";
import {
assertArray,
assertBoolean,
@ -11,7 +12,6 @@ import {
assertObject,
assertSet,
assertString,
DateTime,
dictionaryToStringMap,
Integer,
may,

View File

@ -0,0 +1,41 @@
import { ReadonlyDate } from "readonly-date";
import { DateTime } from "./dates";
describe("dates", () => {
describe("DateTime", () => {
it("decodes a string", () => {
expect(DateTime.decode("2020-12-15T10:57:26.778Z").nanoseconds).toEqual(0);
expect(DateTime.decode("2020-12-15T10:57:26.7789Z").nanoseconds).toEqual(900000);
expect(DateTime.decode("2020-12-15T10:57:26.77809Z").nanoseconds).toEqual(90000);
expect(DateTime.decode("2020-12-15T10:57:26.778009Z").nanoseconds).toEqual(9000);
expect(DateTime.decode("2020-12-15T10:57:26.7780009Z").nanoseconds).toEqual(900);
expect(DateTime.decode("2020-12-15T10:57:26.77800009Z").nanoseconds).toEqual(90);
expect(DateTime.decode("2020-12-15T10:57:26.778000009Z").nanoseconds).toEqual(9);
});
it("encodes a string", () => {
const date1 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date1 as any).nanoseconds = 0;
expect(DateTime.encode(date1)).toEqual("2020-12-15T10:57:26.778000000Z");
const date2 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date2 as any).nanoseconds = 900000;
expect(DateTime.encode(date2)).toEqual("2020-12-15T10:57:26.778900000Z");
const date3 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date3 as any).nanoseconds = 90000;
expect(DateTime.encode(date3)).toEqual("2020-12-15T10:57:26.778090000Z");
const date4 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date4 as any).nanoseconds = 9000;
expect(DateTime.encode(date4)).toEqual("2020-12-15T10:57:26.778009000Z");
const date5 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date5 as any).nanoseconds = 900;
expect(DateTime.encode(date5)).toEqual("2020-12-15T10:57:26.778000900Z");
const date6 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date6 as any).nanoseconds = 90;
expect(DateTime.encode(date6)).toEqual("2020-12-15T10:57:26.778000090Z");
const date7 = new ReadonlyDate("2020-12-15T10:57:26.778Z");
(date7 as any).nanoseconds = 9;
expect(DateTime.encode(date7)).toEqual("2020-12-15T10:57:26.778000009Z");
});
});
});

View File

@ -0,0 +1,23 @@
import { fromRfc3339 } from "@cosmjs/encoding";
import { ReadonlyDate } from "readonly-date";
export interface ReadonlyDateWithNanoseconds extends ReadonlyDate {
/* Nanoseconds after the time stored in a vanilla ReadonlyDate (millisecond granularity) */
readonly nanoseconds?: number;
}
export class DateTime {
public static decode(dateTimeString: string): ReadonlyDateWithNanoseconds {
const readonlyDate = fromRfc3339(dateTimeString);
const nanosecondsMatch = dateTimeString.match(/\.(\d+)Z$/);
const nanoseconds = nanosecondsMatch ? nanosecondsMatch[1].slice(3) : "";
(readonlyDate as any).nanoseconds = parseInt(nanoseconds.padEnd(6, "0"), 10);
return readonlyDate as ReadonlyDateWithNanoseconds;
}
public static encode(dateTime: ReadonlyDateWithNanoseconds): string {
const millisecondIso = dateTime.toISOString();
const nanoseconds = dateTime.nanoseconds?.toString() ?? "";
return `${millisecondIso.slice(0, -1)}${nanoseconds.padStart(6, "0")}Z`;
}
}

View File

@ -1,53 +1,8 @@
import { ReadonlyDate } from "readonly-date";
import {
DateTime,
encodeBlockId,
encodeBytes,
encodeInt,
encodeString,
encodeTime,
encodeVersion,
} from "./encodings";
import { ReadonlyDateWithNanoseconds } from "./types";
import { encodeBlockId, encodeBytes, encodeInt, encodeString, encodeTime, encodeVersion } from "./encodings";
describe("encodings", () => {
describe("DateTime", () => {
it("decodes a string", () => {
expect(DateTime.decode("2020-12-15T10:57:26.778Z").nanoseconds).toEqual(0);
expect(DateTime.decode("2020-12-15T10:57:26.7789Z").nanoseconds).toEqual(900000);
expect(DateTime.decode("2020-12-15T10:57:26.77809Z").nanoseconds).toEqual(90000);
expect(DateTime.decode("2020-12-15T10:57:26.778009Z").nanoseconds).toEqual(9000);
expect(DateTime.decode("2020-12-15T10:57:26.7780009Z").nanoseconds).toEqual(900);
expect(DateTime.decode("2020-12-15T10:57:26.77800009Z").nanoseconds).toEqual(90);
expect(DateTime.decode("2020-12-15T10:57:26.778000009Z").nanoseconds).toEqual(9);
});
it("encodes a string", () => {
const date1 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date1 as any).nanoseconds = 0;
expect(DateTime.encode(date1)).toEqual("2020-12-15T10:57:26.778000000Z");
const date2 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date2 as any).nanoseconds = 900000;
expect(DateTime.encode(date2)).toEqual("2020-12-15T10:57:26.778900000Z");
const date3 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date3 as any).nanoseconds = 90000;
expect(DateTime.encode(date3)).toEqual("2020-12-15T10:57:26.778090000Z");
const date4 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date4 as any).nanoseconds = 9000;
expect(DateTime.encode(date4)).toEqual("2020-12-15T10:57:26.778009000Z");
const date5 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date5 as any).nanoseconds = 900;
expect(DateTime.encode(date5)).toEqual("2020-12-15T10:57:26.778000900Z");
const date6 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date6 as any).nanoseconds = 90;
expect(DateTime.encode(date6)).toEqual("2020-12-15T10:57:26.778000090Z");
const date7 = new ReadonlyDate("2020-12-15T10:57:26.778Z") as ReadonlyDateWithNanoseconds;
(date7 as any).nanoseconds = 9;
expect(DateTime.encode(date7)).toEqual("2020-12-15T10:57:26.778000009Z");
});
});
describe("encodeString", () => {
it("works", () => {
expect(encodeString("")).toEqual(Uint8Array.from([0]));

View File

@ -1,8 +1,8 @@
import { fromRfc3339, toUtf8 } from "@cosmjs/encoding";
import { toUtf8 } from "@cosmjs/encoding";
import { Int53 } from "@cosmjs/math";
import { ReadonlyDateWithNanoseconds } from "./dates";
import { BlockId, Version } from "./responses";
import { ReadonlyDateWithNanoseconds } from "./types";
/**
* A runtime checker that ensures a given value is set (i.e. not undefined or null)
@ -156,22 +156,6 @@ export class Integer {
}
}
export class DateTime {
public static decode(dateTimeString: string): ReadonlyDateWithNanoseconds {
const readonlyDate = fromRfc3339(dateTimeString);
const nanosecondsMatch = dateTimeString.match(/\.(\d+)Z$/);
const nanoseconds = nanosecondsMatch ? nanosecondsMatch[1].slice(3) : "";
(readonlyDate as any).nanoseconds = parseInt(nanoseconds.padEnd(6, "0"), 10);
return readonlyDate as ReadonlyDateWithNanoseconds;
}
public static encode(dateTime: ReadonlyDateWithNanoseconds): string {
const millisecondIso = dateTime.toISOString();
const nanoseconds = dateTime.nanoseconds?.toString() ?? "";
return `${millisecondIso.slice(0, -1)}${nanoseconds.padStart(6, "0")}Z`;
}
}
// Encodings needed for hashing block headers
// Several of these functions are inspired by https://github.com/nomic-io/js-tendermint/blob/tendermint-0.30/src/

View File

@ -1,7 +1,7 @@
export { Adaptor } from "./adaptor";
export { adaptor33, adaptor34 } from "./adaptors";
export { Client } from "./client";
export { DateTime } from "./encodings";
export { DateTime, ReadonlyDateWithNanoseconds } from "./dates";
export {
AbciInfoRequest,
AbciQueryParams,
@ -72,10 +72,4 @@ export {
VoteType,
} from "./responses";
export { HttpClient, WebsocketClient } from "./rpcclients"; // TODO: Why do we export those outside of this package?
export {
BlockIdFlag,
CommitSignature,
ReadonlyDateWithNanoseconds,
ValidatorEd25519Pubkey,
ValidatorPubkey,
} from "./types";
export { BlockIdFlag, CommitSignature, ValidatorEd25519Pubkey, ValidatorPubkey } from "./types";

View File

@ -1,6 +1,7 @@
import { ReadonlyDate } from "readonly-date";
import { CommitSignature, ReadonlyDateWithNanoseconds, ValidatorPubkey } from "./types";
import { ReadonlyDateWithNanoseconds } from "./dates";
import { CommitSignature, ValidatorPubkey } from "./types";
export type Response =
| AbciInfoResponse

View File

@ -1,11 +1,7 @@
// Types in this file are exported outside of the @cosmjs/tendermint-rpc package,
// e.g. as part of a request or response
import { ReadonlyDate } from "readonly-date";
export interface ReadonlyDateWithNanoseconds extends ReadonlyDate {
/* Nanoseconds after the time stored in a vanilla ReadonlyDate (millisecond granularity) */
readonly nanoseconds?: number;
}
import { ReadonlyDateWithNanoseconds } from "./dates";
export interface ValidatorEd25519Pubkey {
readonly algorithm: "ed25519";