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

Convert to typescript #9

Merged
merged 130 commits into from
Apr 11, 2021
Merged

Convert to typescript #9

merged 130 commits into from
Apr 11, 2021

Conversation

usu
Copy link
Member

@usu usu commented Nov 27, 2020

I've started to dive into Typescript. Looks promising to me so far.

@carlobeltrame Can you have a look at it if you feel this goes into the right direction? If so, I'd continue piece-by-piece with the rest of the code.

@carlobeltrame
Copy link
Member

Ah wow, nice, thanks! Maybe have a look at https://github.com/ecamp/hal-json-vuex/tree/refactor-to-classes where I started to refactor the storeValueProxy file into classes. I think that should be completed before moving to Typescript, what do you think?

@usu
Copy link
Member Author

usu commented Nov 29, 2020

I think that should be completed before moving to Typescript, what do you think?

Ah nice, didn't see that branch before. Yes, makes sense to complete & merge that one before. Otherwise we'll have tons of conflicts.

@usu usu marked this pull request as draft December 1, 2020 20:53
Copy link
Member

@carlobeltrame carlobeltrame left a comment

Choose a reason for hiding this comment

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

Looking good :) a few comments from my side for now. Let me know if you want me to continue this.

src/StoreValue.ts Outdated Show resolved Hide resolved
src/QueryablePromise.ts Outdated Show resolved Hide resolved
src/QueryablePromise.ts Outdated Show resolved Hide resolved
src/interfaces/ApiActions.ts Outdated Show resolved Hide resolved
src/interfaces/Config.ts Show resolved Hide resolved
webpack.config.js Show resolved Hide resolved
src/interfaces/StoreData.ts Outdated Show resolved Hide resolved
@usu
Copy link
Member Author

usu commented Dec 6, 2020

@carlobeltrame I believe this is in a state where you could have another look at it. Would say 95% complete as a first shot. Appreciate a careful review.

Some open actions (potentially as separate issues, to be discussed):

  • Discuss and resolve the various inline comments marked as "TODO"
  • Avoid usage of "any" and inline rule exclusions
  • Real world test in ecamp3 (only tested independetly so far)
  • Consider splitting up index (Install/Export, API actions, helper functions)
  • Consider implementation of CanHaveItems as mixin/composable instead of as a base class
  • Naming and file organization: Names of classes/interfaces/etc. have now grown historically. I think it makes sense to take a step back and review what the best and most consistent naming would be.
  • LoadingStoreCollection is a class with a static function only which is a Javascript antipattern. Consider implementing as simple function or integrate back to LoadingStoreValue.
  • Unit tests for separate components?

@usu usu marked this pull request as ready for review December 6, 2020 11:54
Copy link
Member

@carlobeltrame carlobeltrame left a comment

Choose a reason for hiding this comment

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

Nice work, thank you! I have tried to answer all your todos. There is still some work to do before we can merge this I think, but if you feel that some things should be done in later iterations let me know.

src/CanHaveItems.ts Outdated Show resolved Hide resolved
src/LoadingStoreValue.ts Show resolved Hide resolved
src/CanHaveItems.ts Outdated Show resolved Hide resolved
src/CanHaveItems.ts Outdated Show resolved Hide resolved
* @param arrayLoaded Promise that resolves once the array has finished loading
* @param existingContent optionally set the elements that are already known, for random access
*/
static create (loadArray: Promise<Array<Resource> | undefined>, existingContent: Array<Resource> = []): Array<Resource> {
Copy link
Member

Choose a reason for hiding this comment

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

LoadingStoreCollection is a class with a static function only which is a Javascript antipattern. Consider implementing as simple function or integrate back to LoadingStoreValue.

The create method should probably be replaced with a constructor, right? If that's not possible in TypeScript, we could just store the existingContent on the LoadingStoreCollection instance and wrap it that way.

Copy link
Member Author

Choose a reason for hiding this comment

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

In this case, we either need to wrap it. Or extend the Array class. I tried latter, and somehow failed. Let my try former 😵

Copy link
Member

@carlobeltrame carlobeltrame Mar 23, 2021

Choose a reason for hiding this comment

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

One conclusion from my experiments: Extending the Array class is not possible, because the LoadingStoreCollection has different type signatures for either find or map:

  • If LoadingStoreCollection inherits from Array<Resource> or some other Array<Something>, or we make a generic LoadingStoreCollection<T>, the find method can no longer return a LoadingStoreValue, but must return Resource or Something or T.
  • If LoadingStoreCollection inherits from Array<LoadingStoreValue>, the map method cannot be made to work the way we want, because it has to potentially transform the LoadingStoreValues into objects of other classes, depending on the callback passed to map (the callback might map every entry to an integer, for example).

So a wrapper that implements Resource or better Collection is the only option I see to avoid the static create method.

Copy link
Member

Choose a reason for hiding this comment

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

TODO: Try something like LoadingStoreValue<T> extends T, this way the Array contract could maybe hold

src/LoadingStoreValue.ts Outdated Show resolved Hide resolved
src/LoadingStoreValue.ts Show resolved Hide resolved
src/QueryablePromise.ts Outdated Show resolved Hide resolved
src/QueryablePromise.ts Outdated Show resolved Hide resolved
src/StoreValue.ts Outdated Show resolved Hide resolved
@usu
Copy link
Member Author

usu commented Dec 6, 2020

There is still some work to do before we can merge this I think, but if you feel that some things should be done in later iterations let me know.

Yes agree. Let me see how far I get with the open points. Some of the questions I raised in the earlier comment might be too big to also squeeze into this pull request.

By the way: I also just uploaded a rebased version of the code status as of today (separating renaming of files and actual code change). Might be a bit easier to verify the code changes by looking at the last commit only:
usu@17d57ff

src/HasItems.ts Outdated Show resolved Hide resolved
@carlobeltrame
Copy link
Member

I have also continued this a little, and I have come to the conclusion that for HasItems, normal inheritance should be enough, we don't need the more generic variant of mixins you described (a mixin is valuable if you want to apply it to multiple different base classes, but we only ever apply it to StoreValue).
But I am not quite finished with resolving all type-related refactorings I was doing. Maybe we can have a look at it some time.

@carlobeltrame
Copy link
Member

carlobeltrame commented Mar 23, 2021

Mein aktuellster Stand ist jetzt auf diesem Branch, damit wir uns nicht mehr über-pushen: https://github.com/ecamp/hal-json-vuex/tree/feature/typescript

src/HasItems.ts Outdated Show resolved Hide resolved
src/index.ts Outdated Show resolved Hide resolved
src/index.ts Outdated Show resolved Hide resolved
@usu usu requested a review from carlobeltrame April 5, 2021 11:42
@usu
Copy link
Member Author

usu commented Apr 5, 2021

@carlobeltrame
The 2 open points discussed last week are now implemented

  • $loadItems resolves to the collection object instead of the array of items
  • get cannot be used anymore with embedded collections (limited to reloading)

We'll probably still see more changes on the embedded collections. I don't think it's coded super cleanly.

But would appreciate if we can merge the current status and then divide future work into smaller chunks.

Alternatively, we could also open a v2-alpha branch (+v2 alpha releases) and start PR/merging into the alpha branch until we feel the interface is robust and stable enough.

Copy link
Member

@carlobeltrame carlobeltrame left a comment

Choose a reason for hiding this comment

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

LGTM, thanks a lot!

The alpha strategy sounds good. In case we ever decide to backport anything to an old major version, I'd rather have a sound pre-typescript version than an early typescript version which may contain flaws that we do not know as of now.

@@ -0,0 +1,48 @@
// import LoadingStoreCollection from './LoadingStoreCollection'
Copy link
Member

Choose a reason for hiding this comment

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

Remove?

* @param reloadProperty property in the containing entity under which the embedded collection is saved
* @param apiActions dependency injection of API actions
* @param config dependency injection of config object
* @param loadParent a promise that will resolve when the parent entity has finished (re-)loading
Copy link
Member

Choose a reason for hiding this comment

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

Outdated jsDoc comment

src/HasItems.ts Outdated
Comment on lines 39 to 40
* Returns true if any of the items within 'array' is not yet known to the API (meaning it has never been loaded)
*/
Copy link
Member

Choose a reason for hiding this comment

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

Indentation

src/HasItems.ts Outdated

// eager loading of 'fetchAllUri' (e.g. parent for embedded collections)
if (config.avoidNPlusOneRequests && reloadUri) {
return apiActions.reload({ _meta: { reload: { uri: reloadUri || '', property: reloadProperty || '' } } }) as Promise<Collection>
Copy link
Member

Choose a reason for hiding this comment

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

This as is here to convince TypeScript that the server has previously sent a collection, so it will send a collection again, right? Consider adding a comment that explains this

@usu usu changed the base branch from master to next April 9, 2021 16:44
@usu
Copy link
Member Author

usu commented Apr 9, 2021

@carlobeltrame I've changed the target branch to next instead of master. So we merge and then tag/publish as 2.0.0-alpha.0? Or 1.3.0-alpha.0?

@carlobeltrame
Copy link
Member

Yes, +1 for 2.0.0-alpha.0, since technically we already made some small breaking changes (to undocumented features), and this allows us to clean up some more if we deem it necessary.

@carlobeltrame carlobeltrame merged commit 406bdc1 into ecamp:next Apr 11, 2021
@carlobeltrame
Copy link
Member

v2.0.0-alpha.0 is published: https://www.npmjs.com/package/hal-json-vuex?activeTab=versions

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

3 participants