-
Notifications
You must be signed in to change notification settings - Fork 36
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
[BB pr#39] KIT-40 [Demo/POC] How to extend the Engine #39
Comments
Typescript autocomplete catFacts correctly here. We don’t need to specify a “state type” anywhere. |
This piece of code |
Maybe we shouldn’t export the Engine type but only the ReduxEngine? (here renamed to |
This is how we get the complete extended state. By adding the 2 types. |
I think #2 would be the correct way to go about it, otherwise the release process might get “crowded”, it will be harder to release some integration individually. Now, if we take what you have here a step even further:
Then we’d have a Then we’d have a Now, let’s say salesforce/service now team need to create something for case deflection, which would hypothetically need to call the “customer service API” to power the main feature of the package, and also the search-api because they need a query suggestions feature that is not exposed through the customer service API . They would first create a Then they would create a Repeat for commerce, We could even try to think how this could be used to create a Now would that architecture makes sense, or would it be complicating things “needlessly” ? Just typing it out made me doubt that this might be over engineered. Would we be jumping all across the places in different packages to be able to do our day to day job ? Is that inventing a problem that does not even exist yet ? What you have right now also seems pretty powerful. And I’m going to approve for this reason. But something to discuss… |
|
Reading it I feel this way too, maybe it’s a bit too much over-engineering for now. We only have to define what is “Core”, meaning what features (slices) and what component would all engines in all Coveo teams need. That core would stay in the current headless package. Let’s call it Then we could have an Engine with all the stuff for a search page (what headless is now currently). Let’s call it Then for all product types (commerce, salesforce, service, etc.) they could have their own package too, they could import what they need from I think we should keep it 1 package = 1 product or tool (like bueno). That would prevent jumping around for most of the time. I think that this could all be possible with what we have in this PR (using addons) we would have to set up a test-package to have a better idea. |
I think it’s nice for developers to have access to the type if they want to create their own engine implementations. I also think HeadlessEngine is good name for the default/native engine, especially if we one day export other kinds of engines from this package or others. |
Why does the engine need to be publicly exposed? |
Seems to me that this function should accept a generic type, since it is no longer returning a HeadlessState when the additionalReducers argument is passed. |
Could the cast be removed if we allowed passing a generic to the configureStore function instead? |
Hmm, personally I have the opposite view. I don’t like the idea of developers/users needing to install multiple packages to use different apis. What features belong together is blurry and I don’t see why we should decide this for our users. Then there is the aspect of wiring packages. Not so difficult for one type as shown in this PR, but once you have 3 or 4 different Engine state types, along with the required reducers (not necessarily easy to figure out), then I can see it becoming challenge. I think Olivier your comment here
comes from good intentions, trying to hide the wiring. However, it does not scale, as the permutations will grow very quickly. I think all functionality that we code should exist in the headless package. Using a plugin model one could pick-and-choose when configuring the reducer. As a helper, we can expose a function that returns all reducers.
If someone wants to optimize for bundle size, they can build their own reducers object. We can also expose other helpers that return combinations of reducers based on the apis “commerceReducers”, “caseDeflectionReducers“ etc. that can be composed as desired.
For the typescript, it would be cool if the developer did not have to pass anything in and the |
My main concern with this is the release process might become pretty complicated, and a lot of “hey guys when is the release for headless, I have this super important client/feature that is waiting on it”. But heh, if it comes to that then I guess we have a “nice problem on our hand” :slight_smile: Because it means many teams are using the project 😉 And this can be mitigated by having proper validation tool/automated test, making the release process very quick. So my proposition was in the hope of trying to scale the humans, not the code 😃 Which I think is just as hard, if not more… |
Ok, I see. We could mitigate such risks in different ways. Automated tests would be great. If unavailable, we can also publish an alpha package on every merge commit, or every night, for people who need changes in a short window. |
Following on the above comment, I think it’s better if the Engine interface accepts the “full state” as a generic, rather than the additional state. This does not force a developer to use the full HeadlessState if they do not want to. It also simplifies repeating the |
Okay, so code every features & component inside headless, expose everything, even the reducers? Then the issue comes to: the customer has to know what Component deals with what reducers, actions etc. I can see complexity here…. What we could do is have one BIG core package that has everything & expose everything. But either have wrapper packages that make it more elegant or find another clever way to organize export. The hardest thing is to get the typescript definitions to follow. |
Thanks for the feedback guys! So now, following this, I infer the state from the reducers that are passed to the engine. I export the current reducers as “core reducers” and use those as default. So a user is now able to pick & chose the reducers he requires. One limitation I see is that we use the HeadlessState interface throughout the code and export it. This causes the following issues:
Also, of course creating an engine with no “core-reducers” will break the API for example. Maybe we should have both “core-reducers”, that are obligatory, and “search-reducers” that are for the search. Components should also specify what reducers are required to be included in the engine. Anyways, still lots of questions 🤔 🤔 🤔 |
Is this cast still needed? If so, is there something we could do with |
Nice, did not know that RTK exported these types. |
On the question of core vs search reducers, I think these helpers would be useful to expose one day, but I do not think it’s important at this stage. I think what is currently called For the default value of the For #2 on the reference documentation, I believe we can still get jsDoc if one adds it above the property in the object. Would something like this work? e.g.
For #1, I see … interesting problem. It makes sense too in that a class usually only needs a slice of state, not the whole thing. Stricter typing would also guide a dev as to what reducers they need to configure for the headless class to work correctly. If we had types for each of the reducers, I think we could solve this problem. Could something along these lines work?
Overall, this PR is looking good. Nice investigations 💯 |
|
Yes, it returns an ugly |
Thanks! For #1, yes we’ll have to divide the reducer maps and specify them in each components, not necessary for now, but once we extract the core yes. For #2 I found the way to do it, it won’t be an issue for now (assigning |
Bundle Size Report
|
I was thinking some more end of day yesterday … “searchReducers” is probably better than “allReducers” for now. In the longer term, this will avoid bloating early headless users, while keeping the naming representative. |
I’d want to rename that search reducer/slice then 😉 |
Everything under the /addon-example folder is not intended to be merged (or maybe it should be? as a code example, with more documentation).
I modified a few thing about the Engine’s type to make it possible to extend it without too much hassle. Basically, when you pass some custom made reducers to the
addons
option, it will “magically” add a piece of state!I made it possible to extend the Component type too with an extended Engine.
This example would work well for customers and other teams at the company. A question right now is where we would put the code? I see 2 ways:
FEEDBACK!! 🙏 🙏 🙏
https://coveord.atlassian.net/browse/KIT-40 & https://coveord.atlassian.net/browse/KIT-28
The text was updated successfully, but these errors were encountered: