RFC - Standalone API #1978
-
A few ideas are being bounced around on what this could look like. Please ensure that it clearly states the following aspects of your proposal:
Please also take the time to look at other proposals and engage in respectful discussion. |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 4 replies
-
I suggest using the same methods in other 3rd party libraries (such as NgRx). Our users can register states via bootstrapApplication(AppComponent, {
providers: [
// might be named whatever we want
provideNgxs(states)
]
}) I haven't thought about the function names; let's assume that they can be called anything for the time being. The same with feature states: const routes = [
{
path: 'blog',
loadComponent: () => import('....'),
providers: [
// might be named whatever we want
provideNgxsFeatureStates([BlogState]),
],
},
]; Our users are able to provide configuration through bootstrapApplication(AppComponent, {
providers: [
provideNgxs(
states,
withNgxsConfig({
developmentMode: !environment.product,
})
),
],
}); What about import { withNgxsLoggerPlugin } from '@ngxs/logger-plugin';
import { provideNgxs, withNgxsConfig, withNgxsPlugin } from '@ngxs/store';
bootstrapApplication(AppComponent, {
providers: [
provideNgxs(
states,
withNgxsConfig({
developmentMode: !environment.product,
}),
withNgxsLoggerPlugin(),
withNgxsPlugin(MyCustomPlugin)
),
],
}); Feature plugins (doesn't exist yet, under consideration): import { provideNgxsStorageFeatureStates } from '@ngxs/storage-plugin';
import { provideNgxsFeatureStates } from '@ngxs/store';
const routes = [
{
path: 'blog',
loadComponent: () => import('....'),
providers: [
// might be named whatever we want
provideNgxsFeatureStates([BlogState, My_Other_Feature_State]),
provideNgxsStorageFeatureStates([BlogState]),
],
},
]; The new implementation is backwards compatible with the previous one. TODO: this post may be updated later, I just drafted my thought aloud real quick... |
Beta Was this translation helpful? Give feedback.
-
Related PR: #1999 |
Beta Was this translation helpful? Give feedback.
-
Following on from @arturovt's recommendations above, this is the API that I think makes sense:
Plugins could be left to define their own pattern for standalone API, but the following pattern could be recommended:
Bringing this all together, it would appear in code as follows: import { provideNgxsLoggerPlugin } from '@ngxs/logger-plugin';
import { provideNgxs } from '@ngxs/store';
bootstrapApplication(AppComponent, {
providers: [
provideNgxs( states, { developmentMode: !environment.production } ),
provideNgxsLoggerPlugin(),
],
}); "Feature" states: import { provideNgxsStates } from '@ngxs/store';
const routes = [
{
path: 'blog',
loadComponent: () => import('....'),
providers: [
provideNgxsStates([BlogState, My_Other_Feature_State]),
],
},
]; Just for testing out the APIs of other proposals I would also like to mention a potential local component state provider API (see RFC #1979 ):
|
Beta Was this translation helpful? Give feedback.
-
i think im leaning towards the following naming:
I will say tho, that i also like for local-component states, what about:
my thinking is that the word Local/Component would indicate that the state will only live will the component is alive |
Beta Was this translation helpful? Give feedback.
-
We had a discussion with Mark regarding signatures of these APIs: provideNgxs(states: StateClass[] = [], config?: NgxsConfig);
provideNgxsStates(states: StateClass[]);
provideNgxsPlugin(plugin: NgxsPlugin); We had a thought that NGXS has internal actions These technical constraints require keeping backward compatible signatures of the standalone API. So Those APIs will never be provided on the component level, which is guaranteed by types being returned by those APIs ( Our plugins will expose functions because plugins rely on user provided configurations. That's why the signature of core NGXS plugins will be: export function provideNgxsLoggerPlugin(config) {
return makeEnvironmentProviders([
{ provide: NGXS_LOGGER_PLUGIN_OPTIONS, ....},
provideNgxsPlugin(NgxsLoggerPlugin)
]);
} Note: the bootstrapApplication(..., {
providers: [
{
provide: NGXS_PLUGINS,
useClass: PLUGIN,
multi: true
},
{
provide: NGXS_PLUGINS,
useClass: PLUGIN,
multi: true
},
{
provide: NGXS_PLUGINS,
useClass: PLUGIN,
multi: true
},
{
provide: NGXS_PLUGINS,
useClass: PLUGIN,
multi: true
}
]
}); I think we should have a minimal handshake agreed on namings (even tho namings are hard). Note: please let's NOT discuss the component state in this discussion because I'm worried about the cognitive overload 😄 UPD (July 26)We have agreed to use the following namings and signatures: function provideStore(
states?: StateClass[],
...features: EnvironmentProviders[]
): EnvironmentProviders;
function provideStore(
states?: StateClass[],
options?: NgxsModuleOptions,
...features: EnvironmentProviders[]
): EnvironmentProviders;
function provideStates(
states: StateClass[],
...features: EnvironmentProviders[]
): EnvironmentProviders; Example: provideStore(
[TodosState],
{ developmentMode: !environment.production, selectorOptions: {} },
withNgxsFormPlugin(),
withNgxsLoggerPlugin({ logger: console, collapsed: false, disabled: true }),
withNgxsReduxDevtoolsPlugin({ disabled: environment.production }),
withNgxsRouterPlugin(),
withNgxsStoragePlugin({ key: [TODOS_STORAGE_KEY] })
) |
Beta Was this translation helpful? Give feedback.
We had a discussion with Mark regarding signatures of these APIs:
We had a thought that
provideNgxs
may only be called with the config, and all of the states are registered usingprovideNgxsStates
. Thus,provideNgxs
is only responsible for setting the Store up. But this is not backward compatible with the current implementation because it breaks the order of the executed code.NGXS has internal actions
InitState
andUpdateState
.InitState
is always dispatched once when theNgxsModule.forRoot
registers root states provided inforRoot
.UpdateState
is d…