react-elmish 8.0.0-beta.1 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -54
- package/dist/Common.d.ts +2 -2
- package/dist/Common.js +21 -9
- package/dist/ElmComponent.d.ts +4 -3
- package/dist/ElmComponent.js +82 -65
- package/dist/ErrorHandling.d.ts +2 -2
- package/dist/ErrorHandling.js +3 -4
- package/dist/Init.d.ts +3 -3
- package/dist/Init.js +2 -3
- package/dist/Testing/createModelAndProps.d.ts +3 -0
- package/dist/Testing/createModelAndProps.js +26 -0
- package/dist/Testing/createUpdateArgsFactory.d.ts +6 -5
- package/dist/Testing/createUpdateArgsFactory.js +12 -10
- package/dist/Testing/execCmd.d.ts +4 -2
- package/dist/Testing/execCmd.js +43 -8
- package/dist/Testing/execSubscription.d.ts +5 -0
- package/dist/Testing/execSubscription.js +28 -0
- package/dist/Testing/getCreateUpdateArgs.d.ts +16 -4
- package/dist/Testing/getCreateUpdateArgs.js +30 -20
- package/dist/Testing/getUpdateFn.d.ts +9 -9
- package/dist/Testing/getUpdateFn.js +68 -30
- package/dist/Testing/index.d.ts +9 -9
- package/dist/Testing/index.js +21 -1
- package/dist/Testing/initAndExecCmd.d.ts +2 -2
- package/dist/Testing/initAndExecCmd.js +13 -13
- package/dist/Testing/renderWithModel.d.ts +3 -3
- package/dist/Testing/renderWithModel.js +8 -8
- package/dist/Types.d.ts +16 -10
- package/dist/Types.js +1 -1
- package/dist/cmd.d.ts +62 -60
- package/dist/cmd.js +67 -66
- package/dist/createCallBase.d.ts +3 -0
- package/dist/createCallBase.js +21 -0
- package/dist/createDefer.d.ts +6 -0
- package/dist/createDefer.js +27 -0
- package/dist/{Testing/fakeOptions.d.ts → fakeOptions.d.ts} +3 -3
- package/dist/fakeOptions.js +31 -0
- package/dist/index.d.ts +7 -8
- package/dist/index.js +8 -1
- package/dist/mergeSubscriptions.d.ts +4 -0
- package/dist/mergeSubscriptions.js +45 -0
- package/dist/useElmish.d.ts +6 -6
- package/dist/useElmish.js +78 -52
- package/package.json +23 -20
- package/dist/Testing/fakeOptions.js +0 -31
package/README.md
CHANGED
|
@@ -20,14 +20,17 @@ This library brings the elmish pattern to react.
|
|
|
20
20
|
- [Setup](#setup)
|
|
21
21
|
- [Error handling](#error-handling)
|
|
22
22
|
- [React life cycle management](#react-life-cycle-management)
|
|
23
|
+
- [Deferring model updates and messages](#deferring-model-updates-and-messages)
|
|
24
|
+
- [Call back parent components](#call-back-parent-components)
|
|
23
25
|
- [Composition](#composition)
|
|
24
26
|
- [With an `UpdateMap`](#with-an-updatemap)
|
|
25
|
-
- [With an update function](#with-an-update-function)
|
|
26
|
-
- [
|
|
27
|
+
- [With an update function](#with-an-update-function)
|
|
28
|
+
- [Merge multiple subscriptions](#merge-multiple-subscriptions)
|
|
27
29
|
- [Testing](#testing)
|
|
28
30
|
- [Testing the init function](#testing-the-init-function)
|
|
29
31
|
- [Testing the update handler](#testing-the-update-handler)
|
|
30
32
|
- [Combine update and execCmd](#combine-update-and-execcmd)
|
|
33
|
+
- [Testing subscriptions](#testing-subscriptions)
|
|
31
34
|
- [UI Tests](#ui-tests)
|
|
32
35
|
- [Migrations](#migrations)
|
|
33
36
|
- [From v1.x to v2.x](#from-v1x-to-v2x)
|
|
@@ -262,12 +265,6 @@ You can call one of the functions of that object:
|
|
|
262
265
|
| `cmd.ofEither` | Calls a function (sync or async) and maps the result into a message. |
|
|
263
266
|
| `cmd.ofSuccess` | Same as `ofEither` but ignores the error case. |
|
|
264
267
|
| `cmd.ofError` | Same as `ofEither` but ignores the success case. |
|
|
265
|
-
| `cmd.ofFunc.either` | Calls a synchronous function and maps the result into a message. |
|
|
266
|
-
| `cmd.ofFunc.perform` | Same as `either` but ignores the error case. |
|
|
267
|
-
| `cmd.ofFunc.attempt` | Same as `either` but ignores the success case. |
|
|
268
|
-
| `cmd.ofPromise.either` | Calls an async function and maps the result into a message. |
|
|
269
|
-
| `cmd.ofPromise.perform` | Same as `either` but ignores the error case. |
|
|
270
|
-
| `cmd.ofPromise.attempt` | Same as `either` but ignores the success case. |
|
|
271
268
|
| `cmd.ofSub` | Use this function to trigger a command in a subscription. |
|
|
272
269
|
|
|
273
270
|
### Dispatch a message
|
|
@@ -568,6 +565,97 @@ class App extends ElmComponent<Shared.Model, Shared.Message, Shared.Props> {
|
|
|
568
565
|
|
|
569
566
|
In a functional component you can use the **useEffect** hook as normal.
|
|
570
567
|
|
|
568
|
+
## Deferring model updates and messages
|
|
569
|
+
|
|
570
|
+
Sometimes you want to always dispatch a message or update the model in all cases. You can use the `defer` function from the `options` parameter to do this. The `options` parameter is the fourth parameter of the `update` function.
|
|
571
|
+
|
|
572
|
+
Without the `defer` function, you would have to return the model and the command in all cases:
|
|
573
|
+
|
|
574
|
+
```ts
|
|
575
|
+
const update: UpdateMap<Props, Model, Message> = {
|
|
576
|
+
deferSomething (_msg, model) {
|
|
577
|
+
if (model.someCondition) {
|
|
578
|
+
return [{ alwaysUpdate: "someValue", extra: "extra" }, cmd.ofMsg(Msg.alwaysExecute())];
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
return [{ alwaysUpdate: "someValue" }, cmd.ofMsg(Msg.doSomethingElse()), cmd.ofMsg(Msg.alwaysExecute())];
|
|
582
|
+
},
|
|
583
|
+
|
|
584
|
+
...LoadSettings.update,
|
|
585
|
+
};
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Here we always want to update the model with the `alwaysUpdate` property and always dispatch the `alwaysExecute` message.
|
|
589
|
+
|
|
590
|
+
With the `defer` function, you can do this:
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
const update: UpdateMap<Props, Model, Message> = {
|
|
594
|
+
deferSomething (_msg, model, _props, { defer }) {
|
|
595
|
+
defer({ alwaysUpdate: "someValue" }, cmd.ofMsg(Msg.alwaysExecute()));
|
|
596
|
+
|
|
597
|
+
if (model.someCondition) {
|
|
598
|
+
return [{ extra: "extra" }];
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
return [{}, cmd.ofMsg(Msg.doSomethingElse())];
|
|
602
|
+
},
|
|
603
|
+
|
|
604
|
+
...LoadSettings.update,
|
|
605
|
+
};
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
The `defer` function can be called multiple times. Model updates and commands are then aggregated. Model updates by the return value overwrite the deferred model updates, while deferred messages are dispatched after the returned messages.
|
|
609
|
+
|
|
610
|
+
## Call back parent components
|
|
611
|
+
|
|
612
|
+
Since each component has its own model and messages, communication with parent components is done via callback functions.
|
|
613
|
+
|
|
614
|
+
To inform the parent component about some action, let's say to close a dialog form, you do the following:
|
|
615
|
+
|
|
616
|
+
1. Create a message
|
|
617
|
+
|
|
618
|
+
```ts Dialog.ts
|
|
619
|
+
export type Message =
|
|
620
|
+
...
|
|
621
|
+
| { name: "close" }
|
|
622
|
+
...
|
|
623
|
+
|
|
624
|
+
export const Msg = {
|
|
625
|
+
...
|
|
626
|
+
close: (): Message => ({ name: "close" }),
|
|
627
|
+
...
|
|
628
|
+
}
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
1. Define a callback function property in the **Props**:
|
|
632
|
+
|
|
633
|
+
```ts Dialog.ts
|
|
634
|
+
export type Props = {
|
|
635
|
+
onClose: () => void,
|
|
636
|
+
};
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
1. Handle the message and call the callback function:
|
|
640
|
+
|
|
641
|
+
```ts Dialog.ts
|
|
642
|
+
{
|
|
643
|
+
// ...
|
|
644
|
+
close () {
|
|
645
|
+
return [{}, cmd.ofError(props.onClose, Msg.error)];
|
|
646
|
+
}
|
|
647
|
+
// ...
|
|
648
|
+
};
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
1. In the **render** method of the parent component pass the callback as prop
|
|
652
|
+
|
|
653
|
+
```tsx Parent.tsx
|
|
654
|
+
...
|
|
655
|
+
<Dialog onClose={() => this.dispatch(Msg.closeDialog())}>
|
|
656
|
+
...
|
|
657
|
+
```
|
|
658
|
+
|
|
571
659
|
## Composition
|
|
572
660
|
|
|
573
661
|
If you have some business logic that you want to reuse in other components, you can do this by using different sources for messages.
|
|
@@ -670,10 +758,20 @@ const update: UpdateMap<Props, Model, Message> = {
|
|
|
670
758
|
},
|
|
671
759
|
|
|
672
760
|
...LoadSettings.update,
|
|
761
|
+
|
|
762
|
+
// You can overwrite the LoadSettings messages handlers here
|
|
763
|
+
|
|
764
|
+
settingsLoaded (_msg, _model, _props, { defer, callBase }) {
|
|
765
|
+
// Use defer and callBase to execute the original handler function:
|
|
766
|
+
defer(...callBase(LoadSettings.settingsLoaded));
|
|
767
|
+
|
|
768
|
+
// Do additional stuff
|
|
769
|
+
return [{ /* ... */ }];
|
|
770
|
+
}
|
|
673
771
|
};
|
|
674
772
|
```
|
|
675
773
|
|
|
676
|
-
|
|
774
|
+
### With an update function
|
|
677
775
|
|
|
678
776
|
Let's say you want to load some settings, you can write a module like this:
|
|
679
777
|
|
|
@@ -797,54 +895,20 @@ const updateComposition = (model: Model, msg: CompositionMessage): Elm.UpdateRet
|
|
|
797
895
|
}
|
|
798
896
|
```
|
|
799
897
|
|
|
800
|
-
|
|
898
|
+
### Merge multiple subscriptions
|
|
801
899
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
To inform the parent component about some action, let's say to close a dialog form, you do the following:
|
|
805
|
-
|
|
806
|
-
1. Create a message
|
|
900
|
+
If you use composition and thus have multiple subscriptions, you can merge them with the `mergeSubscriptions` function:
|
|
807
901
|
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
| { name: "close" }
|
|
812
|
-
...
|
|
813
|
-
|
|
814
|
-
export const Msg = {
|
|
815
|
-
...
|
|
816
|
-
close: (): Message => ({ name: "close" }),
|
|
817
|
-
...
|
|
818
|
-
}
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
1. Define a callback function property in the **Props**:
|
|
822
|
-
|
|
823
|
-
```ts Dialog.ts
|
|
824
|
-
export type Props = {
|
|
825
|
-
onClose: () => void,
|
|
826
|
-
};
|
|
827
|
-
```
|
|
828
|
-
|
|
829
|
-
1. Handle the message and call the callback function:
|
|
830
|
-
|
|
831
|
-
```ts Dialog.ts
|
|
832
|
-
{
|
|
833
|
-
// ...
|
|
834
|
-
close () {
|
|
835
|
-
return [{}, cmd.ofError(props.onClose, Msg.error)];
|
|
836
|
-
}
|
|
837
|
-
// ...
|
|
838
|
-
};
|
|
839
|
-
```
|
|
902
|
+
```ts
|
|
903
|
+
import { mergeSubscriptions } from "react-elmish";
|
|
904
|
+
import * as LoadSettings from "./LoadSettings";
|
|
840
905
|
|
|
841
|
-
|
|
906
|
+
function localSubscription (model: Model): SubscriptionResult<Message> {
|
|
907
|
+
// ...
|
|
908
|
+
}
|
|
842
909
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
<Dialog onClose={() => this.dispatch(Msg.closeDialog())}>
|
|
846
|
-
...
|
|
847
|
-
```
|
|
910
|
+
const subscription = mergeSubscriptions(LoadSettings.subscription, localSubscription);
|
|
911
|
+
```
|
|
848
912
|
|
|
849
913
|
## Testing
|
|
850
914
|
|
|
@@ -903,7 +967,7 @@ const createUpdateArgs = getCreateUpdateArgs(init, () => ({ /* initial props */
|
|
|
903
967
|
|
|
904
968
|
it("returns the correct model and cmd", async () => {
|
|
905
969
|
// arrange
|
|
906
|
-
const args = createUpdateArgs(Msg.test(), { /* optionally override model here */ }, { /* optionally override props here */ });
|
|
970
|
+
const args = createUpdateArgs(Msg.test(), { /* optionally override model here */ }, { /* optionally override props here */ }, { /* optionally override options here */ });
|
|
907
971
|
|
|
908
972
|
// act
|
|
909
973
|
// Call the update handler
|
|
@@ -950,6 +1014,33 @@ it("returns the correct cmd", async () => {
|
|
|
950
1014
|
...
|
|
951
1015
|
```
|
|
952
1016
|
|
|
1017
|
+
### Testing subscriptions
|
|
1018
|
+
|
|
1019
|
+
It is almost the same as testing the `update` function. You can use the `getCreateModelAndProps` function to create a factory for the model and the props. Then use `execSubscription` to execute the subscriptions:
|
|
1020
|
+
|
|
1021
|
+
```ts
|
|
1022
|
+
import { getCreateModelAndProps, execSubscription } from "react-elmish/dist/Testing";
|
|
1023
|
+
import { init, Msg, subscription } from "./MyComponent";
|
|
1024
|
+
|
|
1025
|
+
const createModelAndProps = getCreateModelAndProps(init, () => ({ /* initial props */ }));
|
|
1026
|
+
|
|
1027
|
+
it("dispatches the eventTriggered message", async () => {
|
|
1028
|
+
// arrange
|
|
1029
|
+
const mockDispatch = jest.fn();
|
|
1030
|
+
const args = createModelAndProps({ /* optionally override model here */ }, { /* optionally override props here */ });
|
|
1031
|
+
const dispose = execSubscription(subscription, mockDispatch, ...args);
|
|
1032
|
+
|
|
1033
|
+
// act
|
|
1034
|
+
// Trigger events
|
|
1035
|
+
|
|
1036
|
+
// assert
|
|
1037
|
+
expect(mockDispatch).toHaveBeenCalledWith(Msg.eventTriggered());
|
|
1038
|
+
|
|
1039
|
+
// Dispose the subscriptions if required
|
|
1040
|
+
dispose();
|
|
1041
|
+
});
|
|
1042
|
+
```
|
|
1043
|
+
|
|
953
1044
|
### UI Tests
|
|
954
1045
|
|
|
955
1046
|
To test UI components with a fake model you can use `renderWithModel` from the Testing namespace. The first parameter is a function to render your component (e.g. with **@testing-library/react**). The second parameter is the fake model. The third parameter is an optional options object, where you can also pass a fake `dispatch` function.
|
package/dist/Common.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Cmd, Dispatch, Message } from "./Types";
|
|
1
|
+
import type { Cmd, Dispatch, Message } from "./Types";
|
|
2
2
|
declare function logMessage<TMessage extends Message>(name: string, msg: TMessage): void;
|
|
3
3
|
declare function modelHasChanged<TModel>(currentModel: TModel, model: Partial<TModel>): boolean;
|
|
4
4
|
declare function execCmd<TMessage>(dispatch: Dispatch<TMessage>, ...commands: (Cmd<TMessage> | undefined)[]): void;
|
|
5
|
-
export { logMessage, modelHasChanged
|
|
5
|
+
export { execCmd, logMessage, modelHasChanged };
|
package/dist/Common.js
CHANGED
|
@@ -7,11 +7,14 @@ exports.execCmd = execCmd;
|
|
|
7
7
|
exports.logMessage = logMessage;
|
|
8
8
|
exports.modelHasChanged = modelHasChanged;
|
|
9
9
|
var _Init = require("./Init");
|
|
10
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
11
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
12
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
10
13
|
function logMessage(name, msg) {
|
|
11
14
|
var _Services$logger, _Services$logger2, _Services$dispatchMid;
|
|
12
|
-
(_Services$logger = _Init.Services.logger) === null || _Services$logger === void 0
|
|
13
|
-
(_Services$logger2 = _Init.Services.logger) === null || _Services$logger2 === void 0
|
|
14
|
-
(_Services$dispatchMid = _Init.Services.dispatchMiddleware) === null || _Services$dispatchMid === void 0
|
|
15
|
+
(_Services$logger = _Init.Services.logger) === null || _Services$logger === void 0 || _Services$logger.info("Message from", name, msg.name);
|
|
16
|
+
(_Services$logger2 = _Init.Services.logger) === null || _Services$logger2 === void 0 || _Services$logger2.debug("Message from", name, msg);
|
|
17
|
+
(_Services$dispatchMid = _Init.Services.dispatchMiddleware) === null || _Services$dispatchMid === void 0 || _Services$dispatchMid.call(_Init.Services, msg);
|
|
15
18
|
}
|
|
16
19
|
function modelHasChanged(currentModel, model) {
|
|
17
20
|
return !Object.is(model, currentModel) && Object.getOwnPropertyNames(model).length > 0;
|
|
@@ -20,10 +23,19 @@ function execCmd(dispatch) {
|
|
|
20
23
|
for (var _len = arguments.length, commands = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
21
24
|
commands[_key - 1] = arguments[_key];
|
|
22
25
|
}
|
|
23
|
-
commands.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
var _iterator = _createForOfIteratorHelper(commands.flat()),
|
|
27
|
+
_step;
|
|
28
|
+
try {
|
|
29
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
30
|
+
var call = _step.value;
|
|
31
|
+
if (call) {
|
|
32
|
+
call(dispatch);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
} catch (err) {
|
|
36
|
+
_iterator.e(err);
|
|
37
|
+
} finally {
|
|
38
|
+
_iterator.f();
|
|
39
|
+
}
|
|
28
40
|
}
|
|
29
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,
|
|
41
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfSW5pdCIsInJlcXVpcmUiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsInIiLCJlIiwidCIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiQXJyYXkiLCJpc0FycmF5IiwiX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IiwibGVuZ3RoIiwiX24iLCJGIiwicyIsIm4iLCJkb25lIiwidmFsdWUiLCJmIiwiVHlwZUVycm9yIiwibyIsImEiLCJ1IiwiY2FsbCIsIm5leHQiLCJfYXJyYXlMaWtlVG9BcnJheSIsInRvU3RyaW5nIiwic2xpY2UiLCJjb25zdHJ1Y3RvciIsIm5hbWUiLCJmcm9tIiwidGVzdCIsImxvZ01lc3NhZ2UiLCJtc2ciLCJfU2VydmljZXMkbG9nZ2VyIiwiX1NlcnZpY2VzJGxvZ2dlcjIiLCJfU2VydmljZXMkZGlzcGF0Y2hNaWQiLCJTZXJ2aWNlcyIsImxvZ2dlciIsImluZm8iLCJkZWJ1ZyIsImRpc3BhdGNoTWlkZGxld2FyZSIsIm1vZGVsSGFzQ2hhbmdlZCIsImN1cnJlbnRNb2RlbCIsIm1vZGVsIiwiT2JqZWN0IiwiaXMiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiZXhlY0NtZCIsImRpc3BhdGNoIiwiX2xlbiIsImFyZ3VtZW50cyIsImNvbW1hbmRzIiwiX2tleSIsIl9pdGVyYXRvciIsImZsYXQiLCJfc3RlcCIsImVyciJdLCJzb3VyY2VzIjpbIi4uL3NyYy9Db21tb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2VydmljZXMgfSBmcm9tIFwiLi9Jbml0XCI7XG5pbXBvcnQgdHlwZSB7IENtZCwgRGlzcGF0Y2gsIE1lc3NhZ2UgfSBmcm9tIFwiLi9UeXBlc1wiO1xuXG5mdW5jdGlvbiBsb2dNZXNzYWdlPFRNZXNzYWdlIGV4dGVuZHMgTWVzc2FnZT4obmFtZTogc3RyaW5nLCBtc2c6IFRNZXNzYWdlKTogdm9pZCB7XG5cdFNlcnZpY2VzLmxvZ2dlcj8uaW5mbyhcIk1lc3NhZ2UgZnJvbVwiLCBuYW1lLCBtc2cubmFtZSk7XG5cdFNlcnZpY2VzLmxvZ2dlcj8uZGVidWcoXCJNZXNzYWdlIGZyb21cIiwgbmFtZSwgbXNnKTtcblxuXHRTZXJ2aWNlcy5kaXNwYXRjaE1pZGRsZXdhcmU/Lihtc2cpO1xufVxuXG5mdW5jdGlvbiBtb2RlbEhhc0NoYW5nZWQ8VE1vZGVsPihjdXJyZW50TW9kZWw6IFRNb2RlbCwgbW9kZWw6IFBhcnRpYWw8VE1vZGVsPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gIU9iamVjdC5pcyhtb2RlbCwgY3VycmVudE1vZGVsKSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhtb2RlbCkubGVuZ3RoID4gMDtcbn1cblxuZnVuY3Rpb24gZXhlY0NtZDxUTWVzc2FnZT4oZGlzcGF0Y2g6IERpc3BhdGNoPFRNZXNzYWdlPiwgLi4uY29tbWFuZHM6IChDbWQ8VE1lc3NhZ2U+IHwgdW5kZWZpbmVkKVtdKTogdm9pZCB7XG5cdGZvciAoY29uc3QgY2FsbCBvZiBjb21tYW5kcy5mbGF0KCkpIHtcblx0XHRpZiAoY2FsbCkge1xuXHRcdFx0Y2FsbChkaXNwYXRjaCk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCB7IGV4ZWNDbWQsIGxvZ01lc3NhZ2UsIG1vZGVsSGFzQ2hhbmdlZCB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLEtBQUEsR0FBQUMsT0FBQTtBQUFrQyxTQUFBQywyQkFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEseUJBQUFDLE1BQUEsSUFBQUgsQ0FBQSxDQUFBRyxNQUFBLENBQUFDLFFBQUEsS0FBQUosQ0FBQSxxQkFBQUUsQ0FBQSxRQUFBRyxLQUFBLENBQUFDLE9BQUEsQ0FBQU4sQ0FBQSxNQUFBRSxDQUFBLEdBQUFLLDJCQUFBLENBQUFQLENBQUEsTUFBQUMsQ0FBQSxJQUFBRCxDQUFBLHVCQUFBQSxDQUFBLENBQUFRLE1BQUEsSUFBQU4sQ0FBQSxLQUFBRixDQUFBLEdBQUFFLENBQUEsT0FBQU8sRUFBQSxNQUFBQyxDQUFBLFlBQUFBLEVBQUEsZUFBQUMs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
|
package/dist/ElmComponent.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { InitFunction, Message, UpdateFunction } from "./Types";
|
|
2
|
+
import type { InitFunction, Message, UpdateFunction } from "./Types";
|
|
3
3
|
/**
|
|
4
4
|
* Abstract class for a react class component using the Elmish pattern.
|
|
5
5
|
* @export
|
|
@@ -14,7 +14,7 @@ declare abstract class ElmComponent<TModel, TMessage extends Message, TProps> ex
|
|
|
14
14
|
private initCommands;
|
|
15
15
|
private readonly componentName;
|
|
16
16
|
private readonly buffer;
|
|
17
|
-
private
|
|
17
|
+
private running;
|
|
18
18
|
private mounted;
|
|
19
19
|
private currentModel;
|
|
20
20
|
/**
|
|
@@ -55,10 +55,11 @@ declare abstract class ElmComponent<TModel, TMessage extends Message, TProps> ex
|
|
|
55
55
|
* @param {TModel} model The current model.
|
|
56
56
|
* @param {TMessage} msg The message to process.
|
|
57
57
|
* @param {TProps} props The props of the component.
|
|
58
|
+
* @param options The options for the update function.
|
|
58
59
|
* @returns The new model (can also be an empty object {}) and an optional new message to dispatch.
|
|
59
60
|
* @abstract
|
|
60
61
|
* @memberof ElmComponent
|
|
61
62
|
*/
|
|
62
63
|
abstract update: UpdateFunction<TProps, TModel, TMessage>;
|
|
63
64
|
}
|
|
64
|
-
export { ElmComponent
|
|
65
|
+
export { ElmComponent };
|