Esempio n. 1
0
        public async Task ExampleUsage2()
        {
            var t = Log.MethodEntered("DataStoreExample2.ExampleUsage2");

            // Add a thunk middleware to allow dispatching async actions:
            var thunkMiddleware = Middlewares.NewThunkMiddleware <MyAppState1>();

            // aDD A logging middleware to log all dispatched actions:
            var loggingMiddleware = Middlewares.NewLoggingMiddleware <MyAppState1>();

            // Add a recorder middleware to enable hot reload by replaying previously recorded actions:
            var recorder      = new ReplayRecorder <MyAppState1>();
            var recMiddleware = recorder.CreateMiddleware();

            var undoable = new UndoRedoReducer <MyAppState1>();
            // To allow undo redo on the full store wrap the main reducer with the undo reducer:
            var undoReducer = undoable.Wrap(MyReducers1.ReduceMyAppState1);

            var data  = new MyAppState1(null, null, 0); // the initial immutable state
            var store = new DataStore <MyAppState1>(undoReducer, data, loggingMiddleware, recMiddleware, thunkMiddleware);

            store.storeName = "Store 1";

            TestNormalDispatchOfActions(store);

            TestUndoAndRedo(store);

            await TestAsyncActions(store);

            await TestReplayRecorder(recorder, store);

            TestSkippableUndoActions(store);

            Log.MethodDone(t);
        }
Esempio n. 2
0
        public async Task ExampleUsage1()
        {
            var t = Log.MethodEntered("DataStoreExample3.ExampleUsage1");

            // Add a thunk middleware to allow dispatching async actions:
            var thunkMiddleware = Middlewares.NewThunkMiddleware <MyAppState1>();

            // aDD A logging middleware to log all dispatched actions:
            var loggingMiddleware = Middlewares.NewLoggingMiddleware <MyAppState1>();

            var serverOutboxHandler = new ServerOutboxHandler <MyAppState1>();
            // To allow undo redo on the full store wrap the main reducer with the undo reducer:
            var outboxReducer = serverOutboxHandler.Wrap(MyReducers1.ReduceMyAppState1);
            var initialState  = new MyAppState1(); // the initial immutable state
            var store         = new DataStore <MyAppState1>(outboxReducer, initialState, loggingMiddleware, thunkMiddleware);

            IoC.inject.SetSingleton(store);
            store.storeName = "Store 3";

            { // Do a login which is an async server action that cant be cached optimistically and wont work offline:
                Func <Task> asyncLoginTask = async() => {
                    await TaskV2.Delay(100);

                    store.Dispatch(new ActionUserLoggedIn()
                    {
                        newLoggedInUser = new MyUser1("*****@*****.**")
                    });
                };
                await(store.Dispatch(asyncLoginTask) as Task);
            }
            { // Change the email a first time:
                var a = new ActionOnUser.ChangeEmail()
                {
                    targetEmail = "*****@*****.**", newEmail = "*****@*****.**"
                };
                store.Dispatch(a);
                Assert.Equal(a, store.GetState().serverOutbox.serverActions.First());
                Assert.False(store.GetState().user.emailConfirmed);
            }
            { // Change the email a second time:
                var a = new ActionOnUser.ChangeEmail()
                {
                    targetEmail = "*****@*****.**", newEmail = "*****@*****.**"
                };
                store.Dispatch(a);
                Assert.Equal(a, store.GetState().serverOutbox.serverActions.Last());
            }

            Assert.Equal(2, store.GetState().serverOutbox.serverActions.Count);
            await store.SyncWithServer(store.GetState().serverOutbox.serverActions.First());

            Assert.Single(store.GetState().serverOutbox.serverActions);
            await store.SyncWithServer(store.GetState().serverOutbox.serverActions.First());

            Assert.Empty(store.GetState().serverOutbox.serverActions);
            Assert.True(store.GetState().user.emailConfirmed);

            { // Simulate a server task that has a timeout:
                var a = new ActionOnUser.ChangeEmail()
                {
                    targetEmail = "*****@*****.**", newEmail = "*****@*****.**", simulateOneTimeout = true
                };
                store.Dispatch(a);
                Assert.Single(store.GetState().serverOutbox.serverActions);
                Assert.False(store.GetState().user.emailConfirmed);
                await store.SyncWithServer(a);

                Assert.Empty(store.GetState().serverOutbox.serverActions);
                Assert.Equal(2, a.sentToServerCounter);
                Assert.True(store.GetState().user.emailConfirmed);
            }
            { // Simulate the server rejecting an email change:
                var a = new ActionOnUser.ChangeEmail()
                {
                    targetEmail = "*****@*****.**", newEmail = "*****@*****.**", simulateError = true
                };
                store.Dispatch(a);
                await store.SyncWithServer(a);

                Assert.Empty(store.GetState().serverOutbox.serverActions);
                Assert.Equal("*****@*****.**", store.GetState().user.email);
                Assert.True(store.GetState().user.emailConfirmed);
            }
            { // Test persisting and restoring the full store and continue with the pending server requests:
                store.Dispatch(new ActionOnUser.ChangeEmail()
                {
                    targetEmail = "*****@*****.**", newEmail = "*****@*****.**"
                });
                store.Dispatch(new ActionOnUser.ChangeEmail()
                {
                    targetEmail = "*****@*****.**", newEmail = "*****@*****.**"
                });
                Assert.Equal(2, store.GetState().serverOutbox.serverActions.Count);
                Assert.False(store.GetState().user.emailConfirmed);
                Assert.Equal("*****@*****.**", store.GetState().user.email);

                // Simulate persisiting the store to disk and back into memory:
                string persistedStateJson = TypedJsonHelper.NewTypedJsonWriter().Write(store.GetState());

                store.Destroy(); // Destroy the old store before loading the state again into an new store
                var data2  = TypedJsonHelper.NewTypedJsonReader().Read <MyAppState1>(persistedStateJson);
                var store2 = new DataStore <MyAppState1>(outboxReducer, data2, loggingMiddleware, thunkMiddleware);
                IoC.inject.SetSingleton(store2, overrideExisting: true);
                store2.storeName = "Store 3 (2)";

                Assert.Equal(2, store2.GetState().serverOutbox.serverActions.Count);
                Assert.False(store2.GetState().user.emailConfirmed);
                Assert.Equal("*****@*****.**", store2.GetState().user.email);

                // Sync the pending server tasks one after another:
                foreach (var serverAction in store2.GetState().serverOutbox.serverActions)
                {
                    await store2.SyncWithServer(serverAction);
                }
                Assert.True(store2.GetState().user.emailConfirmed);
                Assert.NotNull(store2.GetState().serverOutbox);
                Assert.Empty(store2.GetState().serverOutbox.serverActions);
            }
        }