-
-
Notifications
You must be signed in to change notification settings - Fork 236
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
feat(Parser): just-in-time YTNode generation #310
Conversation
Add support for inferring primatives types
Correct types and linting for generated typescript class
Awesome work. I've submitted a review. Thanks! |
The test cases for music is failing because 'MusicCardShelf' is not found. Don't think I should fix it here since it is out of the scope of this PR. However, you can see how the new generator tried to figure out this node 😆 MusicCardShelf not found!
This is a bug, want to help us fix it? Follow the instructions at https://github.com/LuanRT/YouTube.js/blob/main/docs/updating-the-parser.md or report it at https://github.com/LuanRT/YouTube.js/issues!
Introspected and JIT generated this class in the meantime:
class MusicCardShelf extends YTNode {
static type = 'MusicCardShelf';
thumbnail: YTNodes.MusicThumbnail | null;
title: Text;
subtitle: Text;
contents: ObservedArray<YTNodes.Message | YTNodes.MusicResponsiveListItem> | null;
buttons: ObservedArray<YTNodes.Button> | null;
menu: YTNodes.Menu | null;
on_tap: {
click_tracking_params: string,
watch_endpoint: NavigationEndpoint
};
header: YTNodes.MusicCardShelfHeaderBasic | null;
thumbnail_overlay: YTNodes.MusicItemThumbnailOverlay | null;
constructor(data: RawNode) {
super();
this.thumbnail = Parser.parseItem(data.thumbnail, [ YTNodes.MusicThumbnail ]);
this.title = new Text(data.title);
this.subtitle = new Text(data.subtitle);
this.contents = Parser.parse(data.contents, true, [ YTNodes.Message, YTNodes.MusicResponsiveListItem ]);
this.buttons = Parser.parse(data.buttons, true, [ YTNodes.Button ]);
this.menu = Parser.parseItem(data.menu, [ YTNodes.Menu ]);
this.on_tap = {
click_tracking_params: data.onTap.clickTrackingParams,
watch_endpoint: new NavigationEndpoint(data.onTap.watchEndpoint)
};
this.header = Parser.parseItem(data.header, [ YTNodes.MusicCardShelfHeaderBasic ]);
this.thumbnail_overlay = Parser.parseItem(data.thumbnailOverlay, [ YTNodes.MusicItemThumbnailOverlay ]);
}
} |
The wording of this message sounds a bit weird Possible alternatives: Also is there a reason you went with Other than that it's quite impressive |
Also might have missed it in the docs in this pull request, but you seem to have only documented how to manually generate and use nodes but now how the auto-generated ones can be used or accessed. |
Parse will return null if no data is passed in while parseArray will return an empty array if there's no data. Not sure which if preferred in this case. |
Looks good. I'll probably add the new YouTube Music node in the main branch today so this doesn't error out upon merging. |
Sometimes YouTube adds new renderers to their responses. Our current approach requires new nodes to be added to the codebase before users can interact with these new nodes. This is a problem because it requires a new release of the library to be published before users can interact with these new nodes. This PR adds a new feature to the library that allows users to interact with these new nodes without requiring a new release of the library. This is done by generating the missing nodes on-demand at runtime.
Using our existing
YTNode
class, users can interact with these new nodes in a type-safe way, however will not be able to cast them to the node's specific type, as this requires the node to be defined in the codebase.This new implementation outputs the generated nodes as TypeScript classes to the console, so that we may implement new nodes easier.
The current implementation recognises the following values:
This may be expanded in the future.
At runtime, these JIT generated nodes will revalidate themselves when constructed, so that when the types changes, the node will be re-generated.
Basic Example
Given an unknown node's classdata (in this case SearchSubMenu), we can generate a new node class on-demand:
Generates the following TypeScript code and outputs it as warnings to the console:
Revalidation Example
Sometimes keys are optional, we cannot determine this given only one example, so we need to figure this out as new examples of the node is encountered. This example showcases how this works.
This will output the following warnings to the console:
Type of change
Please delete options that are not relevant.
Checklist: