Skip to content

Commit 978c2f4

Browse files
authored
auto prefix non broadcast redux actions
1 parent fe559fe commit 978c2f4

File tree

5 files changed

+115
-15
lines changed

5 files changed

+115
-15
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lastui/rocker",
3-
"version": "0.19.25",
3+
"version": "0.19.26",
44
"license": "Apache-2.0",
55
"author": "[email protected]",
66
"homepage": "https://github.com/lastui/rocker#readme",

platform/src/kernel/reducer/__tests__/modules.test.js

+46-4
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,53 @@ describe("modules reducer", () => {
8181
};
8282

8383
expect(reducer(state, action)).toEqual(expectedState);
84+
8485
expect(reducer(expectedState, action)).toEqual(expectedState);
85-
expect(spyError).toHaveBeenCalledWith(
86-
"module my-feature-broken reducer failed to reduce on action non-handled",
87-
new Error("ouch"),
88-
);
86+
expect(spyError).toHaveBeenCalledWith("module my-feature-broken reducer failed to reduce", new Error("ouch"));
87+
});
88+
89+
it("handles broadcast action", () => {
90+
const action = {
91+
type: "@@FEATURE_BROADCASTING_A_THING",
92+
};
93+
94+
modulesReducers["my-feature-sniff"] = (localState = {}, action) => ({
95+
...localState,
96+
lastAction: action.type,
97+
});
98+
const state = {
99+
...initialState,
100+
};
101+
const expectedState = {
102+
...initialState,
103+
"my-feature-sniff": {
104+
lastAction: "@@FEATURE_BROADCASTING_A_THING",
105+
},
106+
};
107+
108+
expect(reducer(state, action)).toEqual(expectedState);
109+
});
110+
111+
it("handles owned action", () => {
112+
const action = {
113+
type: "$my-feature-sniff$OWNED_ACTION",
114+
};
115+
116+
modulesReducers["my-feature-sniff"] = (localState = {}, action) => ({
117+
...localState,
118+
lastAction: action.type,
119+
});
120+
const state = {
121+
...initialState,
122+
};
123+
const expectedState = {
124+
...initialState,
125+
"my-feature-sniff": {
126+
lastAction: "OWNED_ACTION",
127+
},
128+
};
129+
130+
expect(reducer(state, action)).toEqual(expectedState);
89131
});
90132
});
91133

platform/src/kernel/reducer/modules.js

+25-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import * as constants from "../../constants";
22
import { warning } from "../../utils";
33

4+
const BROADCAST_ACTION_PREFIX = "@@";
5+
6+
const PROBE_ACTION = {
7+
type: undefined,
8+
};
9+
410
const initial = {
511
keys: [],
612
values: [],
@@ -22,7 +28,7 @@ const handler = {
2228
}
2329
const index = target.keys.indexOf(prop);
2430
if (index !== -1) {
25-
return target.values[index][1];
31+
return target.values[index][2];
2632
}
2733
return undefined;
2834
},
@@ -33,9 +39,9 @@ const handler = {
3339
const index = obj.keys.indexOf(prop);
3440
if (index === -1) {
3541
obj.keys.push(prop);
36-
obj.values.push([prop, value]);
42+
obj.values.push([prop, `$${prop}$`, value]);
3743
} else {
38-
obj.values[index] = [prop, value];
44+
obj.values[index] = [prop, `$${prop}$`, value];
3945
}
4046
return true;
4147
},
@@ -96,17 +102,30 @@ function createModulesReducer() {
96102
}
97103
default: {
98104
let nextState = null;
99-
for (const [name, reducer] of modulesReducers) {
105+
for (const [name, prefix, reducer] of modulesReducers) {
106+
let copy = undefined;
107+
108+
if (action.type.startsWith(BROADCAST_ACTION_PREFIX)) {
109+
copy = action;
110+
} else if (action.type.startsWith(prefix)) {
111+
copy = {
112+
...action,
113+
type: action.type.replace(prefix, ""),
114+
};
115+
} else {
116+
copy = PROBE_ACTION;
117+
}
118+
100119
try {
101-
const fragment = reducer(state[name], action);
120+
const fragment = reducer(state[name], copy);
102121
if (state[name] !== fragment) {
103122
if (!nextState) {
104123
nextState = { ...state };
105124
}
106125
nextState[name] = fragment;
107126
}
108127
} catch (error) {
109-
warning(`module ${name} reducer failed to reduce on action ${action.type}`, error);
128+
warning(`module ${name} reducer failed to reduce`, error);
110129
}
111130
}
112131
if (nextState) {

platform/src/kernel/registry/__tests__/store.test.js

+31-3
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ describe("store registry", () => {
217217
const store = getStore().namespace("my-feature");
218218

219219
expect(typeof store.dispatch).toEqual("function");
220-
store.dispatch({ type: "foo" });
221220

222-
expect(storeRef.getActions()).toEqual([{ type: "foo" }]);
221+
store.dispatch({ type: "foo" });
222+
expect(storeRef.getActions()).toEqual([{ type: "$my-feature$foo" }]);
223223
storeRef.clearActions();
224224

225225
store.dispatch({
@@ -228,7 +228,6 @@ describe("store registry", () => {
228228
data: "secret",
229229
},
230230
});
231-
232231
expect(storeRef.getActions()).toEqual([
233232
{
234233
type: SET_SHARED,
@@ -238,6 +237,35 @@ describe("store registry", () => {
238237
},
239238
},
240239
]);
240+
storeRef.clearActions();
241+
242+
store.dispatch({
243+
type: "@@BROADCAST",
244+
payload: {
245+
data: "chatter",
246+
},
247+
});
248+
expect(storeRef.getActions()).toEqual([
249+
{
250+
type: "@@BROADCAST",
251+
payload: {
252+
data: "chatter",
253+
},
254+
},
255+
]);
256+
storeRef.clearActions();
257+
258+
store.dispatch({
259+
type: undefined,
260+
});
261+
expect(storeRef.getActions()).toEqual([]);
262+
storeRef.clearActions();
263+
264+
store.dispatch({
265+
type: "$injection$ACTION",
266+
});
267+
expect(storeRef.getActions()).toEqual([]);
268+
storeRef.clearActions();
241269
});
242270

243271
it(".subscribe", () => {

platform/src/kernel/registry/store.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { SET_SHARED } from "../../constants";
22
import { warning } from "../../utils";
33

4+
const BROADCAST_ACTION_PREFIX = "@@";
5+
46
const nilStore = {
57
dispatch() {
68
warning("Redux store is not provided!");
@@ -28,6 +30,9 @@ const handler = {
2830
let stateProxy = null;
2931
return (name) => ({
3032
dispatch: (action) => {
33+
if (!action.type || action.type[0] === "$") {
34+
return;
35+
}
3136
if (action.type === SET_SHARED) {
3237
return store.dispatch({
3338
type: SET_SHARED,
@@ -37,7 +42,13 @@ const handler = {
3742
},
3843
});
3944
}
40-
return store.dispatch(action);
45+
if (action.type.startsWith(BROADCAST_ACTION_PREFIX)) {
46+
return store.dispatch(action);
47+
}
48+
return store.dispatch({
49+
...action,
50+
type: `$${name}$${action.type}`,
51+
});
4152
},
4253
getState() {
4354
const state = store.getState();

0 commit comments

Comments
 (0)