Skip to content

Commit 93fe6a2

Browse files
author
Tor Hovland
committed
Supporting START, IMPORT_STATE and RESET from Redux DevTools.
1 parent 206aa72 commit 93fe6a2

File tree

3 files changed

+59
-7
lines changed

3 files changed

+59
-7
lines changed

src/BlazorRedux/DevToolsInterop.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ public static class DevToolsInterop
1111
private static bool _isReady;
1212
private static readonly Queue<Tuple<string, string>> Q = new Queue<Tuple<string, string>>();
1313

14+
public static event EventHandler Reset;
1415
public static event StringEventHandler TimeTravel;
1516

17+
private static void OnReset(EventArgs e)
18+
{
19+
var handler = Reset;
20+
handler?.Invoke(null, e);
21+
}
22+
1623
private static void OnTimeTravel(StringEventArgs e)
1724
{
1825
var handler = TimeTravel;
@@ -33,6 +40,11 @@ public static void DevToolsReady()
3340
_isReady = true;
3441
}
3542

43+
public static void DevToolsReset()
44+
{
45+
OnReset(new EventArgs());
46+
}
47+
3648
public static void TimeTravelFromJs(string state)
3749
{
3850
OnTimeTravel(new StringEventArgs(state));

src/BlazorRedux/ReduxDevTools.cs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
1313
builder.OpenElement(seq++, "script");
1414
builder.AddContent(seq++,
1515
@"(function () {
16+
function timeTravel(state) {
17+
const timeTravel = Blazor.platform.findMethod('BlazorRedux', 'BlazorRedux', 'DevToolsInterop', 'TimeTravelFromJs');
18+
Blazor.platform.callMethod(timeTravel, null, [ Blazor.platform.toDotNetString(JSON.stringify(state)) ]);
19+
}
20+
1621
Blazor.registerFunction('log', (action, state) => {
1722
var json = JSON.parse(state);
1823
@@ -40,17 +45,42 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
4045
}
4146
4247
devTools.subscribe((message) => {
43-
if (message.type === 'DISPATCH' && message.state) {
44-
const timeTravel = Blazor.platform.findMethod('BlazorRedux', 'BlazorRedux', 'DevToolsInterop', 'TimeTravelFromJs');
45-
Blazor.platform.callMethod(timeTravel, null, [ Blazor.platform.toDotNetString(message.state) ]);
48+
if (message.type === 'START') {
49+
console.log('Connected with Redux DevTools.');
50+
const devToolsReady = Blazor.platform.findMethod('BlazorRedux', 'BlazorRedux', 'DevToolsInterop', 'DevToolsReady');
51+
Blazor.platform.callMethod(devToolsReady, null, []);
52+
}
53+
else if (message.type === 'DISPATCH' && message.payload) {
54+
var payload = message.payload;
55+
56+
if (payload.type === 'IMPORT_STATE') {
57+
// Hydration of state from a previous session
58+
var states = payload.nextLiftedState.computedStates;
59+
var index = payload.nextLiftedState.currentStateIndex;
60+
var state = states[index].state;
61+
timeTravel(state);
62+
}
63+
else if (payload.type === 'RESET') {
64+
// Reset state
65+
const devToolsReset = Blazor.platform.findMethod('BlazorRedux', 'BlazorRedux', 'DevToolsInterop', 'DevToolsReset');
66+
Blazor.platform.callMethod(devToolsReset, null, []);
67+
}
68+
else {
69+
console.log('Unhandled payload from Redux DevTools:');
70+
console.log(payload);
71+
}
72+
}
73+
else if (message.type === 'DISPATCH' && message.state) {
74+
// Time-traveling
75+
timeTravel(message.state);
76+
}
77+
else {
78+
console.log('Unhandled message from Redux DevTools:');
79+
console.log(message);
4680
}
4781
});
4882
4983
window.devTools = devTools;
50-
console.log('Connected with Redux DevTools.');
51-
52-
const devToolsReady = Blazor.platform.findMethod('BlazorRedux', 'BlazorRedux', 'DevToolsInterop', 'DevToolsReady');
53-
Blazor.platform.callMethod(devToolsReady, null, []);
5484
}());");
5585

5686
builder.CloseElement();

src/BlazorRedux/Store.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,16 @@ namespace BlazorRedux
77
public class Store<TState, TAction> : IDisposable
88
{
99
private readonly Reducer<TState, TAction> _reducer;
10+
private readonly TState _initialState;
1011
private readonly object _syncRoot = new object();
1112

1213
public Store(Reducer<TState, TAction> reducer, TState initialState = default(TState))
1314
{
1415
_reducer = reducer;
16+
_initialState = initialState;
1517
State = initialState;
1618

19+
DevToolsInterop.Reset += OnDevToolsReset;
1720
DevToolsInterop.TimeTravel += OnDevToolsTimeTravel;
1821

1922
DevToolsInterop.Log("initial", JsonUtil.Serialize(State));
@@ -26,9 +29,16 @@ public class Store<TState, TAction> : IDisposable
2629

2730
public void Dispose()
2831
{
32+
DevToolsInterop.Reset -= OnDevToolsReset;
2933
DevToolsInterop.TimeTravel -= OnDevToolsTimeTravel;
3034
}
3135

36+
private void OnDevToolsReset(object sender, EventArgs e)
37+
{
38+
var state = _initialState;
39+
TimeTravel(state);
40+
}
41+
3242
private void OnDevToolsTimeTravel(object sender, StringEventArgs e)
3343
{
3444
var state = JsonUtil.Deserialize<TState>(e.String);

0 commit comments

Comments
 (0)