Skip to content

Commit 92cdcf9

Browse files
committed
feat(almin): Make dispatcher optional
1 parent 990aca0 commit 92cdcf9

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

packages/almin/src/Context.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@ See https://github.com/almin/almin/releases/tag/almin%400.13.10 for more details
5151
*/
5252
export interface ContextArgs<T> {
5353
/**
54-
* Pass Dispatcher instance
54+
* Dispatcher instance.
55+
*
56+
* Notes: Almin 0.16+
57+
*
58+
* It it optional parameter.
5559
*/
56-
dispatcher: Dispatcher;
60+
dispatcher?: Dispatcher;
5761
/**
58-
* Pass StoreGroup instance
62+
* StoreGroup instance
5963
*/
6064
store: StoreLike<T>;
6165
/**
@@ -100,16 +104,14 @@ export class Context<T> {
100104
private config: ContextConfig;
101105

102106
/**
103-
* `dispatcher` is an instance of `Dispatcher`.
104-
* `store` is an instance of StoreLike implementation
107+
* Context should be initialized with `store` that is an instance of StoreLike implementation
105108
*
106109
* ### Example
107110
*
108111
* It is minimal initialization.
109112
*
110113
* ```js
111114
* const context = new Context({
112-
* dispatcher: new Dispatcher(),
113115
* store: new MyStore()
114116
* });
115117
* ```
@@ -121,16 +123,17 @@ export class Context<T> {
121123
* new AStore(), new BStore(), new CStore()
122124
* ]);
123125
* const context = new Context({
124-
* dispatcher: new Dispatcher(),
125126
* store: storeGroup
126127
* });
127128
* ```
128129
*/
129130
constructor(args: ContextArgs<T>) {
130131
const store = args.store;
131132
StoreGroupValidator.validateInstance(store);
132-
// central dispatcher
133-
this.dispatcher = args.dispatcher;
133+
// Central dispatcher
134+
// Almin 0.16+: dispatcher is optional.
135+
// https://github.com/almin/almin/issues/185
136+
this.dispatcher = args.dispatcher || new Dispatcher();
134137
// Implementation Note:
135138
// Delegate dispatch event to Store|StoreGroup from Dispatcher
136139
// StoreGroup call each Store#receivePayload, but pass directly Store is not.

packages/almin/test/Context-test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ParentUseCase } from "./use-case/NestingUseCase";
2121
import { NotExecuteUseCase } from "./use-case/NotExecuteUseCase";
2222
import { SinonStub } from "sinon";
2323
import { UseCaseFunction } from "../src/FunctionalUseCaseContext";
24+
import { createUpdatableStoreWithUseCase } from "./helper/create-update-store-usecase";
2425

2526
const sinon = require("sinon");
2627

@@ -545,6 +546,40 @@ describe("Context", function() {
545546
});
546547
});
547548

549+
describe("Dispatcher", () => {
550+
it("`dispatcher` is optional", () => {
551+
const { MockStore, MockUseCase } = createUpdatableStoreWithUseCase("test");
552+
553+
class UpdateUseCase extends MockUseCase {
554+
execute() {
555+
this.dispatchUpdateState({
556+
value: "update"
557+
});
558+
}
559+
}
560+
561+
// Context class provide observing and communicating with **Store** and **UseCase**
562+
const store = new MockStore();
563+
const storeGroup = new StoreGroup({
564+
test: store
565+
});
566+
const context = new Context({
567+
dispatcher: new Dispatcher(),
568+
store: storeGroup
569+
});
570+
return context
571+
.useCase(new UpdateUseCase())
572+
.execute()
573+
.then(() => {
574+
assert.deepEqual(storeGroup.getState(), {
575+
test: {
576+
value: "update"
577+
}
578+
});
579+
});
580+
});
581+
});
582+
548583
describe("Constructor with Store instance", () => {
549584
it("should Context delegate payload to Store#receivePayload", () => {
550585
class CounterStore extends Store {

packages/almin/test/helper/create-update-store-usecase.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Payload, Store, UseCase } from "../../src";
44
import { shallowEqual } from "shallow-equal-object";
55

66
export function createUpdatableStoreWithUseCase(name: string) {
7+
let isSharedStateChanged = false;
78
let sharedState = {};
89

910
/**
@@ -13,6 +14,7 @@ export function createUpdatableStoreWithUseCase(name: string) {
1314
*/
1415
const requestUpdateState = (newState: any) => {
1516
sharedState = newState;
17+
isSharedStateChanged = true;
1618
};
1719

1820
class StoreUpdatePayload implements Payload {
@@ -53,8 +55,9 @@ export function createUpdatableStoreWithUseCase(name: string) {
5355
receivePayload(payload: Payload) {
5456
if (payload instanceof StoreUpdatePayload) {
5557
this.setState(payload.state);
56-
} else if (!shallowEqual(this.state, sharedState)) {
58+
} else if (isSharedStateChanged && !shallowEqual(this.state, sharedState)) {
5759
this.setState(sharedState);
60+
isSharedStateChanged = false;
5861
}
5962
}
6063

0 commit comments

Comments
 (0)