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

Update of typescript definitions #175

Merged
merged 6 commits into from
Jun 5, 2018
Merged

Update of typescript definitions #175

merged 6 commits into from
Jun 5, 2018

Conversation

reuzel
Copy link
Contributor

@reuzel reuzel commented May 11, 2018

Hi,

I took the liberty to update the typescript definitions. They were not working for me, so I corrected them as far as I could.

I tried to use generics on the types, but reverted those changes for now as these become awkward with the field definitions in the types (not sure how to create an array of generic field types, where the generic parameter is not set yet...).

There may be more TODOs but, I think this one is an improvement...

Regards,
Joost

@coveralls
Copy link

coveralls commented May 11, 2018

Coverage Status

Coverage remained the same at 99.976% when pulling ce38a9a on reuzel:master into 8293a6b on mtth:master.

Copy link
Owner

@mtth mtth left a comment

Choose a reason for hiding this comment

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

Thank you for the PR @reuzel! Can you describe the issues you are having with the current typings?

types/index.d.ts Outdated
type Schema = string | object; // TODO object should be further specified
//"virtual" namespace (no JS, just types) for Avro Schema
declare namespace schema
{
Copy link
Owner

Choose a reason for hiding this comment

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

Can you put the opening brace on the same line as the declaration for consistency with the rest of the file? (Throughout too.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ah, styling. Will do.

types/index.d.ts Outdated
fields: {
name: string;
doc?:string;
type: AvroSchema;
Copy link
Owner

Choose a reason for hiding this comment

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

All nested AvroSchemas could be relaxed to Schema (Types are also accepted).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Schema lives in a namespace outside this one (one level up). Would that not violate layering? I thought to make this namespace completely independent on how it is being used. It is just a typescript representation of the Avro spec. Or am I misunderstanding you?

Copy link
Owner

Choose a reason for hiding this comment

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

It's sometimes convenient to nest types inside of a schema declaration (a simpler alternative to passing them through Type.forSchema's registry option). I'm not sure whether the namespacing is worth the extra restriction; it might also break existing code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will change.

types/index.d.ts Outdated
//"virtual" namespace (no JS, just types) for Avro Schema
declare namespace schema
{
export type AvroSchema = DefinedType | DefinedType[];
Copy link
Owner

Choose a reason for hiding this comment

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

Does this allow references? (References can be arbitrary strings, pointing to values in a registry.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ooh, perhaps not. I haven't used references in my project so far. It would be easy to fix, to add a string type to the DefinedType (along with the primitive, complex and logical types). The primitive type than becomes a kind of redundant as they are just a collection of strings, though it still helps in code-completion scenarios.

Copy link
Owner

Choose a reason for hiding this comment

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

Sounds good.

@reuzel
Copy link
Contributor Author

reuzel commented May 14, 2018

The issues I had with the typings where mainly the following:

  • the Blob support was missing
  • As I'm using your library to serialize objects before storing them in a DB, I wanted to use the toBuffer and fromBuffer, but those typings were incorrect.
  • My project streams a large resultset as an Avro encoded and compressed file towards clients. To this end I want to stream the objects to an http result. However, none of the streams in typings inherited from stream.Duplex, making them unusable in most regular streaming scenarios. For example, I couldn't simply pipe to/from them.

Less important:

  • I missed the Avro schema typings (made some mistakes there)
  • All the options were untyped, so I always had to search on the wiki for the exact naming. I was looking for some code-completion there.

@jsphweid
Copy link

Also, should support for .on('finish', () => etc.) be added?

adding support for referenced types,
adding events to BlockDecoder definitions
Update based on pull request mtth/avsc mtth#178
@mtth mtth mentioned this pull request May 20, 2018
Copy link
Owner

@mtth mtth left a comment

Choose a reason for hiding this comment

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

Apologies for the slow review; I was travelling this past week. Mostly just one comment about duplex events.

types/index.d.ts Outdated
//"virtual" namespace (no JS, just types) for Avro Schema
declare namespace schema
{
export type AvroSchema = DefinedType | DefinedType[];
Copy link
Owner

Choose a reason for hiding this comment

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

Sounds good.

types/index.d.ts Outdated
fields: {
name: string;
doc?:string;
type: AvroSchema;
Copy link
Owner

Choose a reason for hiding this comment

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

It's sometimes convenient to nest types inside of a schema declaration (a simpler alternative to passing them through Type.forSchema's registry option). I'm not sure whether the namespacing is worth the extra restriction; it might also break existing code.

types/index.d.ts Outdated
constructor(opts?: Partial<DecoderOptions>);
static defaultCodecs(): CodecOptions;

//adding all listeners, etc. Can't add a single method override for metadata, all base methods need to be repeated :-(
Copy link
Owner

Choose a reason for hiding this comment

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

Are these really required? How come they aren't provided by Duplex?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The implementation of most of these is provided by Duplex. However, in the definition files, Typescipt requires you to specify the overload function (the one with string, (...args:any[]) ). Once you do that, all the events from the base-class (Duplex) are hidden from code completion (at least in vscode). To make them visible again, you have to add them all :-(

I see this as a Typescript or otherwise vscode bug...

Copy link
Owner

Choose a reason for hiding this comment

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

That's a bummer. It might be surprising to add them here but not to the other duplex streams below; I'd prefer staying consistent and not adding them anywhere, at the cost of losing auto-completion (until the issue you mention is fixed) - do you mind you take them out? (Adding them everywhere would be an unreasonable amount of clutter for the benefits.)

types/index.d.ts Outdated
fromString(str: any): any;
createResolver(type: Type): Resolver;
decode(buf: Buffer, pos?: number, resolver?: Resolver): { value: any, offset: number};
encode(val: any, buf: Buffer, pos?: number): void;
Copy link
Owner

Choose a reason for hiding this comment

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

encode returns a number (the new offset in the buffer).

Copy link
Owner

@mtth mtth left a comment

Choose a reason for hiding this comment

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

One last change and I expect this will be ready to merge.

types/index.d.ts Outdated
constructor(opts?: Partial<DecoderOptions>);
static defaultCodecs(): CodecOptions;

//adding all listeners, etc. Can't add a single method override for metadata, all base methods need to be repeated :-(
Copy link
Owner

Choose a reason for hiding this comment

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

That's a bummer. It might be surprising to add them here but not to the other duplex streams below; I'd prefer staying consistent and not adding them anywhere, at the cost of losing auto-completion (until the issue you mention is fixed) - do you mind you take them out? (Adding them everywhere would be an unreasonable amount of clutter for the benefits.)

@alexander-alvarez
Copy link
Contributor

what's the status here? would like to see the types updates wrapped up (or reverted) and released if possible

@reuzel
Copy link
Contributor Author

reuzel commented Jun 1, 2018 via email

@reuzel
Copy link
Contributor Author

reuzel commented Jun 3, 2018

Last question, before making the changes: The BlockDecoder is the only duplex stream where the addition of all the events is necessary, as it is the only one that adds an event. The repetition of events is only necessary when an extension is made. The event override 'hides' the events from the super classes (as far as those exist in JavaScript). As the BlockDecoder is the only one that emits a new type of event, it is the only one for which the repetition is required. Given that, there are thee options:

  1. Remove all the listeners: the metadata event will work type-check wise but is not visible in any code-completion. The Duplex events will be visible.
  2. Add the metadata event, hide all the standard Duplex events.
  3. Add the meta-data event and repeat the definition of all the standard duplex events (as in the current PR).

None of them are as elegant as you would wish, but I leave the choice to you...

Regards,
Joost

@mtth
Copy link
Owner

mtth commented Jun 4, 2018

Thank you for the detailed explanation @reuzel, this makes sense. Can we go with the first option, adding a comment linking to this PR mentioning why the metadata event is not declared? It's unfortunate that code-completion will not display the event, but the benefits outweigh the inconvenience IMHO.

@reuzel
Copy link
Contributor Author

reuzel commented Jun 4, 2018

@mtth The PR should now be in a state that it can be merged.

@alexander-alvarez
Copy link
Contributor

@reuzel worth noting you can do a repository pattern like so https://github.com/Blizzard/node-rdkafka/pull/420/files#diff-b52768974e6bc0faccb7d4b75b162c99R21
so at least the clutter moves somewhere else?

/shrug

@mtth mtth merged commit c4164a7 into mtth:master Jun 5, 2018
@mtth
Copy link
Owner

mtth commented Jun 5, 2018

Merged; thank you @reuzel!

export function createFileDecoder(fileName: string, opts?: Partial<DecoderOptions>): streams.BlockDecoder;
export function createFileEncoder(filePath: string, schema: Schema, opts?: Partial<EncoderOptions>): streams.BlockEncoder;
export function createBlobEncoder(schema: Schema, opts?: Partial<EncoderOptions>): stream.Duplex;
export function createBlobDecoder(blob: Blob, opts?: Partial<DecoderOptions>): streams.BlockDecoder;
Copy link
Contributor

Choose a reason for hiding this comment

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

FWIW I had to add dom as a lib to my tsconfig.json for typescript to compile O.K. after this change.
Not sure if this is something we can work around though in this file. @reuzel

"lib": ["dom"]

Copy link
Contributor

Choose a reason for hiding this comment

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

I think a triple slash directive should make it work, but it's not taking effect on my local
/// <reference types="dom" />

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The triple slash syntax is rather outdated. I never use it anymore. In this case, the lib option seems the right way forward. It is just telling the typescript compiler that the dom objects are assumed to be available. Without, the Blob type would be unknown.

Why do you see this as an issue? As far as I know, the lib option is not transitive, in the sense that clients of your library do not need to add them as long as they do not include the Blob encoders/decoders. As you have nicely splitted that functionality into a browser lib, I don't really see an issue?

By the way, I didn't encounter this issue in my own project. I'm using webpack for the client pieces, and when set in the right mode, WebPack enables the dom objects automatically.

Copy link
Contributor

Choose a reason for hiding this comment

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

I forgot to mention I'm running in node (node doesn't have dom). So it's counter-intuitive from a consumer's standpoint to have to enable the dom types when consuming node.js libraries, when those dom types don't exist.

I think the longer term solution which I might have seen in some comments is to have different declaration files for the different build assets?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants