Skip to content

Comments

Add persist options for temporal store#61

Merged
charkour merged 22 commits intocharkour:rc-2from
SugarF0x:main
Feb 28, 2023
Merged

Add persist options for temporal store#61
charkour merged 22 commits intocharkour:rc-2from
SugarF0x:main

Conversation

@SugarF0x
Copy link
Contributor

@SugarF0x SugarF0x commented Jan 8, 2023

Expose internal temporal store state creator function to allow for middleware injections which include but are not limited to persist

Todo:

  • Cleanup
  • Fix tests

@charkour
Copy link
Owner

Thanks for this! @SugarF0x

I'll help update the tests. Would you like me to make a PR in your fork, is it okay to push to this branch (you might have to click "allow edits from maintainers".

@charkour charkour added the enhancement New feature or request label Jan 10, 2023
@SugarF0x
Copy link
Contributor Author

SugarF0x commented Jan 10, 2023

@charkour Aye, ive checked maintainers' edits so you can push straight to my fork's main branch

@charkour
Copy link
Owner

Sorry, there was a bug due to the lastest version of zustand. Would you be willing to update this PR?

# Conflicts:
#	packages/zundo/__tests__/createVanillaTemporal.test.ts
#	packages/zundo/__tests__/options.test.ts
#	packages/zundo/__tests__/zundo.test.ts
#	packages/zundo/src/index.ts
#	packages/zundo/src/temporal.ts
#	packages/zundo/src/types.ts
#	pnpm-lock.yaml
@SugarF0x
Copy link
Contributor Author

@charkour aye, fixed that up nicely, working just as fine 👌

@SugarF0x
Copy link
Contributor Author

@charkour reconsidered approach, allowed use of practically any kind and any amount of temporal store middlewares while containing the logic within the temporal middleware itself 👌
now just gotta figure out a proper type cast for it 🤔

@charkour
Copy link
Owner

Awesome! I'll take a look at it now. Thanks for the work on it!

@charkour
Copy link
Owner

@SugarF0x, do you like the ability to add different middleware to the temporal store than the main store?

Originally, I thought that we could add the temporal state to the main store. What do you think? Maybe both should be an option.

@SugarF0x
Copy link
Contributor Author

@charkour we could add an option to toggle between the in-store and out-of-store options to base the temporal store at

Initially i also thought about adding temporal to the main store but then decided that this would be a bit of a breaking change

Plus, Im not too convinced that tampering with one's store directly is not too user friendly since that happens implicitly

Imagine adding an undo function to the parent store directly where user has already had an undo function declared effectively overriding it making one question why their function does not what they want it to

Change merge order and now we have a different issue - user declared undo function overrides temporal undo function making it impossible to call temporal undo at all

While that could be pointed out in the README as a caveat or all the temporal functionality could be shoved under a _temporal key at the store root level, but is it really that much better?

I dont think either option is inherently good or bad, Im just trying to play devils advocate here

Both ideas are good and the final choice is on you as the author

In the end, i only ever stuck with the current implementation of having temporal in a dedicated store purely out of the backwards-compatibility consideration

@charkour
Copy link
Owner

I agree with you and your line of thinking. Let's go forward with keeping the temporal state separate from the user state, but I'll also add a separate function that can be used to inject the temporal state into the user state to make middleware simpler.

@charkour
Copy link
Owner

@SugarF0x, would you be willing to update the tests for this PR? I can't seem to be able to edit this branch.

I'm working on the function that allows you to inject directly into the user's state.

@SugarF0x
Copy link
Contributor Author

weird 🤔

image

coming back to the backwards compatibility, no prior tests break 👐

image

@charkour
Copy link
Owner

Tests are looking good!

Thanks for leading this feature development! I think once this is merged, we can release v2 finally!

I'll check this over in a couple hours.

Copy link
Owner

@charkour charkour left a comment

Choose a reason for hiding this comment

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

A couple quick comments

handleSet: StoreApi<TState>['setState'],
) => StoreApi<TState>['setState'];
handleSet?: (handleSet: StoreApi<TState>['setState']) => StoreApi<TState>['setState'];
storeWrap?: (initializer: StateCreator<TemporalStateWithInternals<TState>, [], []>) => StateCreator<TemporalStateWithInternals<TState>, [], []>
Copy link
Owner

Choose a reason for hiding this comment

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

What other names did you think of for storeWrap? I'm wondering if there is a better one we could use.

Perhaps, temporalMiddleware or simply middleware? Maybe storeMiddleware or wrapTemporalStore?

I'm not sure if there are other examples is in the zustand ecosystem that use this pattern we could copy.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

storeWrap was more of a WIP TBD name, either middlewares or middlewareInjection would be much more suitable

alternatively, this could be called storeInitializerInjection since the purpose if it is to add some custom functionality e.g. middlewares to a store initializator which is the zustand name for the function we pass to create method

Copy link
Owner

Choose a reason for hiding this comment

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

Okay, I prefer the name wrapTemporal or wrapTemporalStore.

What do you think?

Once these small comments are addressed, we can merge this in, add docs, and release a new version! Thank you for all the great help.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Happy to be working on this, amazing opportunity to both learn more about middlewares as well as to do some good for the people using this much like i do

wrapTemporalStore sounds good to me

};

export const temporal = zundoImpl as unknown as Zundo;
export { TemporalStateWithInternals };
Copy link
Owner

Choose a reason for hiding this comment

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

Is this export needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ideally we should not be exposing that, its currently sitting here for testing purposes

Copy link
Owner

@charkour charkour left a comment

Choose a reason for hiding this comment

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

This is looking good! Thanks for this.

Once this is no longer a draft, we can merge it in!

@SugarF0x
Copy link
Contributor Author

ye i just gotta figure out how to fix the typing system
its quite complicated with how zustand handles middleware state interface merging
all looks fine on paper but in practice the types go haywire 🤯

@charkour
Copy link
Owner

Sounds good! The types stretch my understanding as well.

I'll look into the type errors as well.

@SugarF0x
Copy link
Contributor Author

@charkour i fixed the typings
does it work? yes
is it pretty? debatable

@SugarF0x
Copy link
Contributor Author

decided to check how other middleware libraries handle middleware injection

image

💀

@charkour
Copy link
Owner

Oh wow. Not much type safety there.

@charkour
Copy link
Owner

Also, the typings are looking good! Thanks again for working on it.

@charkour
Copy link
Owner

Would you like a review on this? Or is it still a draft?

@SugarF0x
Copy link
Contributor Author

@charkour ye i think its review worthy at this point
i wanna give the tests another look this weekend but the implementation itself is pretty much ready i believe

@SugarF0x SugarF0x marked this pull request as ready for review January 19, 2023 13:28
@SugarF0x SugarF0x requested a review from charkour January 19, 2023 13:29
@SugarF0x SugarF0x changed the title [WIP] Add persist options for temporal store Add persist options for temporal store Jan 19, 2023
@charkour charkour self-assigned this Jan 20, 2023
export default defineConfig({
test: {
globals: true, // required
setupFiles: ['vitest-localstorage-mock'],
Copy link
Owner

Choose a reason for hiding this comment

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

This is a nice package. Helpful for testing. Thanks!

# Conflicts:
#	apps/web/package.json
#	packages/zundo/package.json
#	packages/zundo/src/index.ts
#	pnpm-lock.yaml
@charkour
Copy link
Owner

Thanks for the updates to the branch!

@SugarF0x
Copy link
Contributor Author

@charkour aye, my pleasure
is there any eta on this going through?

@charkour
Copy link
Owner

Yeah, sorry this is taking so long. Let's say one week. That way I'll prioritize reviewing this.

Thank you so much for your effort and patience.

@charkour charkour changed the base branch from main to rc-2 February 28, 2023 03:43
@charkour
Copy link
Owner

I'll merge this into the rc-2 branch to prep the Release Candidate for v2

@charkour charkour merged commit 2399917 into charkour:rc-2 Feb 28, 2023
@charkour
Copy link
Owner

Thanks for your patience on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants