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

Extract helpers.ts #764

Merged
merged 8 commits into from
Oct 27, 2023
Merged

Extract helpers.ts #764

merged 8 commits into from
Oct 27, 2023

Conversation

MinhxNguyen7
Copy link
Member

Summary

Extract all course/WebSOC-related functionality to the WebSOC class in $lib/websoc.ts. There should be no change in behavior

I do not sleep with OOP, but my God is this better than the garbage can that was the old helpers.ts.

Test Plan

Check that everything works. I can't get too much more specific than that.

This PR mostly touches on WebSOC data request, caching, and manipulation functionality, so checking if things load properly is the priority.

Issues

Closes #760

@MinhxNguyen7 MinhxNguyen7 added the codefix Refactoring or improving the codebase label Oct 27, 2023
@MinhxNguyen7 MinhxNguyen7 self-assigned this Oct 27, 2023
@MinhxNguyen7 MinhxNguyen7 marked this pull request as ready for review October 27, 2023 04:13
@github-actions github-actions bot requested a review from EricPedley October 27, 2023 04:13
Copy link
Member

@EricPedley EricPedley left a comment

Choose a reason for hiding this comment

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

Yeah OOP kinda is the exact right tool for encapsulating the websoc query functions with the cache. Now we know for sure the private functions are only used within that class. LGTM! 🚀

bonus points for negative diff
image

@EricPedley EricPedley merged commit 98b511a into main Oct 27, 2023
7 checks passed
@EricPedley EricPedley deleted the refactor-helpers branch October 27, 2023 04:58
@ap0nia
Copy link
Collaborator

ap0nia commented Oct 27, 2023

I don't think it makes any sense to make one class to encapsulate private functions. You could accomplish the exact same thing by not exporting the private functions from the module. There's no benefit to OOP because instances of the websoc query class don't inherently manage any individual data, this is a perfect scenario to apply procedural programming because all you're doing is processing data in -> data out with not many side effects. (There aren't even multiple instances, it's just one).

Am I missing something?

@EricPedley
Copy link
Member

The websoc class also has its cache, which makes sense as a private field and changes as a side effect when the public methods are called. I don't really see the downside of this approach vs a module with functions we don't export

@ap0nia
Copy link
Collaborator

ap0nia commented Oct 27, 2023

If that's the only benefit of having this class, then I think it would be clearer if everything was static. For example:

export class Websoc {
  private static cache = {}

  public static async query() {
    // ...
  }
}

// Usage:

Websoc.query(...)

In my opinion, I just dislike this illusion of encapsulation. The constructor doesn't actually do anything unique per instantiation, and the class itself isn't used in a way that actually takes advantage of OOP; it's literally just a couple of methods that are invoked like regular functions, but now you need to say websoc.query(...) instead of queryWebsoc(...), which seems like you should be aware of the extra class logic in class Websoc (which, counterintuitively, there isn't any --aside from the cache).

I think static would be a valid compromise because it's "closer" to the level of module instantiation in that it doesn't readily support unique behavior per instance, and can exist just to encapsulate variables and mutate them freely (since imports/exports are immutable by the ES6 standard).

Also, we should migrate to Tanstack query eventually ™️, which handles rendering and caching. So the most ideal scenario in the future is that these are just procedural functions that fetch data for the library's hooks, and the library handles caching, mutations, and other server-side state altogether. (i.e. the endgoal is to not have a class).

@MinhxNguyen7
Copy link
Member Author

This is equivalent to using a static class. The interface would be the same. Again, I'm not married to OOP; there's no reason a singleton is better than static here.

It should be a class because it has state and side effects. Every function accesses it. It's not really a valid point to say, "well it doesn't have that much state", because having state just sitting around in the module is unclear in the opposite direction. It's not just data in -> data out, so that shouldn't be indicated.

Also, I strongly prefer websoc.query() because of the namespace. It's much quicker to read. It makes it clear that all interfacing with WebSOC is done here and nothing else.

This is not about encapsulation or safety in some way. It's cleaner and clearer.

I'm not familiar with Tanstack. What's the advantage there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codefix Refactoring or improving the codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Duplicate code in helpers.ts and course-helpers.ts
3 participants