Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base as an interface instead of a class #172

Closed
wants to merge 13 commits into from
Closed

Conversation

amaury1093
Copy link
Contributor

@amaury1093 amaury1093 commented Sep 27, 2018

Proposal: remove the Base class, use an interface Codec<T> instead, that all api-codec types needs to implement (+/- similar to a rust trait).

In particular, use as much as possible existing JavaScript classes (Array, Map, ...) and create child classes that implement Codec<T>.

Types:

  • Vector extends Array
  • Struct extends Map
  • UInt extends BN
  • Text extends String
  • Bool extends Boolean
  • Moment extends Date
  • U8a extends Uint8Array
  • maybe others

Note: Tests don't change at all, cf *.spec.js, only syntax simplifications.

@jacogr If this is something that's interesting, I'll have a look more into it tomorrow.

@amaury1093 amaury1093 added the WIP Work in Progress label Sep 27, 2018
@jacogr
Copy link
Member

jacogr commented Sep 28, 2018

Related #161

@jacogr
Copy link
Member

jacogr commented Sep 30, 2018

One additional thing, for UInt, probably want to extends BN (When going for BigInt, probably need to extends that). I'm currently doing a lot of stuff such as -

          new BlockNumber(
            sessionCurrentIndex.toBn()
              .sub(eraLastLengthChange.toBn())
              .mod(sessionsPerEra.toBn())
              .mul(sessionLength.toBn())
              .add(sessionBlockProgress.toBn())
          )

(in the observable API - they are all BlockNumber, but have a conversion for each and then a final wrap)

For the time-being, will probably just fake add/sub/mul (a couple of them), that way when we extend properly, there is no change, just thing being more effective)

@amaury1093
Copy link
Contributor Author

amaury1093 commented Oct 5, 2018

Things I'm not 100% satisfied:

  1. fromJSON and fromU8a: most of the JS types (like BN, Uint8Array...) don't allow you to replace the value as is, so where before we had this.raw = ..., now I cannot say this = .... We really need to remove fromJSON and fromU8a for cleanliness, this PR is blocked by Intelligent constructor #217.
  2. a.byteLength vs a.byteLength(): BN has byteLength() method, and Uint8Array has byteLength property. If we remove BN, we could go with get byteLength() {...} everywhere, for consistency.
  3. Tuple should extend Vector instead of Struct.
  4. Enum.spec.ts is the only .ts test file, because I need it to test TS enums.

Still TODO:

  • Option
  • EnumType
  • Address (extends AccountId | AccountIndex)

this.raw = Moment.decode(input);

return this;
// FIXME this returns a new Object unfortunately, can't "replace" current value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove from, as per your other PR.


const BITLENGTH = 64;

// A wrapper around seconds/timestamps. Internally the representation only has
// second precicion (aligning with Rust), so any numbers passed an/out are always
// per-second. For any encoding/decoding the 1000 multiplier would be applied to
// get it in line with JavaScript formats
export default class Moment extends Base<Date> {
export default class Moment extends Date implements Codec<Moment> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct, i.e. Codec<Moment> (e.g. Bool above extends built-in JS Boolean class, one of the 2 is wrong)

// Two solutions:
// - either use static
// - or completely remove from*, and force to use constructor
return new Text(u8aToUtf8(input.subarray(offset, offset + length.toNumber())));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, the other PR needs to go first. (This will just create too much messy-ness)

@@ -4,6 +4,11 @@

import Enum from './Enum';

enum TestEnum {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could actually go full-hog ts specs now. (Previously it was problematic since I fed it garbage data - either way, not needed right now)

super(
value instanceof U8aFixed
? value
: U8aFixed.trimLength(toU8a(value), bitLength / 8)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just check current master as well, I had some hoops to jump through - well, if not corrects, tests do catch this one.

private _bitLength: BitLength;
private _isHexJson: boolean;

constructor (value: AnyNumber = 0, bitLength: BitLength = 64, isHexJson: boolean = true) {
super(
UInt.decode(value)
UInt.decode(value).toNumber()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cannot use toNumber here - JS numbers are limited to 53 bits (on uints) - rather toString() it into a decimal representation.

@@ -11,4 +11,16 @@ export type AnyNumber = UInt | BN | Uint8Array | number | string;

export type AnyU8a = U8a | Uint8Array | Array<number> | string;

export interface Codec<T> {
byteLength(): number;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, to get past the BN vs Array issue, call this encodedLength, which is actually exactly what it is. (As a property/getter)

@amaury1093
Copy link
Contributor Author

This is a clusterfuck of merge conflicts. Will open a new one once everything else is ready.

@amaury1093 amaury1093 closed this Oct 15, 2018
@jacogr jacogr deleted the am-new-types branch October 16, 2018 10:59
@polkadot-js-bot
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@polkadot-js polkadot-js locked as resolved and limited conversation to collaborators Jun 9, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
WIP Work in Progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants