spierala / mini-rx-store Goto Github PK
View Code? Open in Web Editor NEWMiniRx - The reactive state management platform
Home Page: https://mini-rx.io
License: Other
MiniRx - The reactive state management platform
Home Page: https://mini-rx.io
License: Other
as you can see I create a Class and use library:
import {
configureStore,
Store as MiniStore,
ReduxDevtoolsExtension,
ImmutableStateExtension,
UndoExtension,
LoggerExtension,
} from "mini-rx-store";
import { take } from "rxjs";
import { STATES_INFO } from "./states-info";
import { SsrService } from "@/app/shared/services/ssr/ssr.service";
import COUNTER_EFFECTS from "./counter/counter.effect";
import { counterReducer } from "./counter/counter.reducer";
import { initialCounterState } from "./counter/initial-counter.state";
import superjson from 'superjson';
import * as devalue from 'devalue';
interface StoreOptions {
reducers: any;
initialState: any;
}
export class StateManager {
private ssrService = SsrService.instance();
private miniState: MiniStore = null!;
private static mirror: StateManager;
private static storeOptions: StoreOptions = {
reducers: {
counter: counterReducer,
},
initialState: {
counter: initialCounterState,
},
}
private constructor() {}
static instance(): StateManager {
if (!StateManager.mirror) {
StateManager.mirror = new StateManager();
StateManager.mirror.init(this.storeOptions);
}
return StateManager.mirror;
}
private init(options: StoreOptions) {
let extensions: any[] = [
new ImmutableStateExtension(),
new UndoExtension({ bufferSize: 100 }),
// new LoggerExtension(),
];
if (this.ssrService.isPlatformBrowser()) {
extensions.push(
new ReduxDevtoolsExtension({
name: "BAMAN SHOWCASE",
maxAge: 100,
latency: 0,
}),
)
}
const opt = {
...options,
extensions,
};
this.miniState = configureStore(opt);
COUNTER_EFFECTS.forEach((effect: any) => this.miniState.effect(effect));
}
get store(): MiniStore {
return this.miniState;
}
exportStates(): Promise<string> {
return new Promise((resolve, reject) => {
this.miniState
.select((states: any) => states)
.pipe(take(1))
.subscribe({
next: (obj) => {
// let sJson = superjson.stringify(obj);
let sJson = devalue.stringify(obj);
resolve(sJson);
},
error: (error) => {
reject(error);
},
});
});
}
resetStore() {
STATES_INFO.forEach((state: any) =>
this.miniState.dispatch(state.actions.reset())
);
}
replaceStore(sJson: string) {
let store = this.miniState;
// let obj = superjson.parse<any>(sJson);
let obj = devalue.parse(sJson);
Object.keys(obj).forEach(function (key, index) {
const state = STATES_INFO.find((s) => s.name === key);
if (state) {
store.dispatch(state.actions.replace(obj[key]));
}
});
}
}
but sometimes, when I refresh prject, it says: @mini-rx: configureStore
was called multiple times.
I expect each time class created, get single instance of store.
how can I solve it?
It would be cool to make the management of entity data (collections of data: e.g. Products, Todos) more straight forward in MiniRx.
Currently the immutable updates of entities require quite some boilerplate code.
MiniRx has two APIs to manage state... both need to be able to manage entities and if possible many entities in one feature state.
Redux
API: NgRx entitiy adapter could be a good fit in generalFeatureStore
, ComponentStore
API: the entity adapter could be used there as wellRegarding the naming of functions which update entity state: Most probably we should use similar/identical names like NgRx entityAdapter, Akita EntityStore or Elf. These names are known by developers.
Should "MiniRx Entity" be part of the mini-rx-store lib or should it be a dedicated lib? Or is maybe a second entry point in mini-rx-store good enough (for tree-shaking)?
When using some class store's functions (class implement FeatureStore), i need to get the RAW state from the signal FeatureStore. My implemented FeatureStore is injected in Angular constructor.
I tried to used the state() (this.store.state().XYZ) but the function is deprecated and still not replaced
Using this.store.select() return a signal. To get the RAW state i need to write this.store.select()() and it's very ugly.
What is the best practice to obtain the raw state from the store presently ?
I'd like to have a possibility to edit an item before it gets passed into the
.select(state=> state.data['myItemId']).subscribe(myItem => {})
callback function after I selected it from the store. Is there a way to see what items are currently subscribed too? Or is there a way hook into 'subscribe' to edit 'myItem' I subscribed to before it get's passed into my subscribe callback?
I am using this package in a node environment (I need state management and I am using rxjs extensively so this project works quite neatly) and I am seeing window is not defined errors when running my application. I understand that you want to provide redux devtools compatibility which requires setting properties on the window. Could you perhaps check the presence of the window
global variable and perform the redux devtools setup logic only if it is defined? If you are open to a pull request let me know.
Currently MiniRx uses an Angular workspace (Angular 9) to manage the two libraries (mini-rx-store and mini-rx-store-ng) and the two demo apps.
Using a Nx workspace is the more modern approach and it includes many of the community best practices (Jest, EsLint, Cypress). Read more here: https://nx.dev/
With Nx we can create real TypeScript libraries: https://www.youtube.com/watch?v=-OmQ-PaSY5M&t=4s
That is exactly what we need for the mini-rx-store library.
Overview of what we need:
Libs:
mini-rx-store: typescript library (publishable), migrate Jest tests
mini-rx-store-ng: angular library (publishable), migrate Jest tests
Apps:
mini-rx-store-showcase (angular app)
mini-rx-store-showcase-redux (angular app)
or:
replace the two apps with this angular app: https://github.com/spierala/mini-rx-angular-demo
Read more about publishable libraries in Nx: https://nx.dev/l/r/structure/buildable-and-publishable-libraries#publishable-libraries
Migration:
I experimented with migrating existing Angular workspaces to Nx and the experience was not so great. IMO it is better to create an empty Nx workspace and create the libs and apps and then copy&paste the src code from the old Angular workspace.
I discovered this really nice looking project and am thinking about switching to it for my state-management.
However, the documentation does not use Redux Toolkit
, but simple Redux
.
Is this library compatible with Redux Toolkit
or will I have to write more boilerplate for simple Redux
?
I have to start several new projects... Can I use Mini-RX-store in production and be sure to make the right choice?. Development seems to have been interrupted for a few months. Thanks in advance...
Originally posted in the NgRx repo, but the same issue exists in MiniRx Store.
hi,
currently the trace tab displays the message: "To enable tracing action calls, you should set trace option to true for Redux DevTools enhancer. Refer to this page for more details"i could not find any option like trace: boolean in the docs or typescript file. is there an option for tracing? if not will there be one in the future? im using angular v13.
thank you
See original issue in NgRx: ngrx/platform#3517
A Component Store could be beneficial to manage state at a local (component) level.
But let's see what we have already in MiniRx...
MiniRx Store and Feature Store manage state at a global level:
MiniRx Store
Read more in the MiniRx Store docs here: https://mini-rx.io/docs/redux
MiniRx Feature Stores
Read more in the MiniRx Feature Store docs here: https://mini-rx.io/docs/fs-quick-start
MiniRx Feature Stores come close to a Component Store since they are destroyable.
See an example in the Angular Demo here: https://angular-demo.mini-rx.io/#/counter
The "counter" Feature Store looks like this:
https://github.com/spierala/mini-rx-angular-demo/blob/main/src/app/modules/counter/state/counter-state.service.ts
Note that it has to provide a unique feature key:
constructor() {
super('counter-' + id++, initialState);
}
The feature key is used to register the counter states into the global state object:
The counter component provides its own instance of the counter-state.service. See here:
https://github.com/spierala/mini-rx-angular-demo/blob/main/src/app/modules/counter/counter/counter.component.ts#L9
When the counter components are destroyed then the corresponding feature states are removed from the global state object.
PROs
CONs
What could it look like?
Mini Redux?
PROs
CONs
Internal unique id creation?
We could try to make the registration of multiple Feature Stores more straightforward, especially the unique id thing, which could be handled internally
Detached Mode?
Prevent Feature Store from the registration on the global Redux store. Instead the Feature Store could fall back to a local Redux.
Again we need Redux mostly to keep the undo functionality (using the UndoExtension).
Angular 17.3
TS 5.4.5
The same issue appears in NgRx/Effects: ngrx/platform#4275
createEffect in MiniRx is heavily inspired by NgRx...
We can apply the same fix as the NgRx team.
In the meanwhile it is possible to downgrade to TS 5.3.3 and the issue is gone.
This libs have to be fixed:
There is a refactor of mini-rx-store ongoing (#209) to use also @mini-rx/common. The refactor of mini-rx-store will be released as a new major version (v6). I suggest to release the TypeScript fix also as part of v6. In that case the fix has to be applied only in @mini-rx/common.
Is there any way to access the root state in a reducer? This would be to read data, not to manipulate the state beyond the reducer's scope.
In our use case, we need to look up values in a map, stored in a different branch of the root-state.
The MiniRx Signal Store uses the same concept as the original RxJS-based MiniRx Store. As a result there is a lot of code which can be shared between the two store solutions. For that reason the @mini-rx/common lib was created. @mini-rx/common is already used by the Signal Store.
See here the full public API of @mini-rx/common: https://github.com/spierala/mini-rx-store/blob/master/libs/common/src/index.ts
This is a quite large task. But is is definitely possible to create smaller sub-tasks:
mini-rx-signal store is covered by a lot of unit tests.
The tests will make the refactor relatively safe.
Indeed some tests can also be removed if mini-rx-store code is replaced with @mini-rx/common code.
When using effect that don't require an argument ( like loadTodos() is your documentation). Typescript complain about missing argument (observableOrValue: unknown) => void
feature-store.d.ts in line 15 =====> (observableOrValue: ObservableType | Observable) => void> the argument is not optional
Angular 15
"mini-rx-store": "^4.1.0",
"mini-rx-store-ng": "^3.0.0",
"typescript": "4.8.4",
We are trying to use the store within a shared worker in such a setup there is no "window" object, like it is used in some places:
it would be great to have a parameter to use self
in such places or get any other hints on how to implement such a plan
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.