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.
Files changed (45) hide show
  1. package/README.md +145 -54
  2. package/dist/Common.d.ts +2 -2
  3. package/dist/Common.js +21 -9
  4. package/dist/ElmComponent.d.ts +4 -3
  5. package/dist/ElmComponent.js +82 -65
  6. package/dist/ErrorHandling.d.ts +2 -2
  7. package/dist/ErrorHandling.js +3 -4
  8. package/dist/Init.d.ts +3 -3
  9. package/dist/Init.js +2 -3
  10. package/dist/Testing/createModelAndProps.d.ts +3 -0
  11. package/dist/Testing/createModelAndProps.js +26 -0
  12. package/dist/Testing/createUpdateArgsFactory.d.ts +6 -5
  13. package/dist/Testing/createUpdateArgsFactory.js +12 -10
  14. package/dist/Testing/execCmd.d.ts +4 -2
  15. package/dist/Testing/execCmd.js +43 -8
  16. package/dist/Testing/execSubscription.d.ts +5 -0
  17. package/dist/Testing/execSubscription.js +28 -0
  18. package/dist/Testing/getCreateUpdateArgs.d.ts +16 -4
  19. package/dist/Testing/getCreateUpdateArgs.js +30 -20
  20. package/dist/Testing/getUpdateFn.d.ts +9 -9
  21. package/dist/Testing/getUpdateFn.js +68 -30
  22. package/dist/Testing/index.d.ts +9 -9
  23. package/dist/Testing/index.js +21 -1
  24. package/dist/Testing/initAndExecCmd.d.ts +2 -2
  25. package/dist/Testing/initAndExecCmd.js +13 -13
  26. package/dist/Testing/renderWithModel.d.ts +3 -3
  27. package/dist/Testing/renderWithModel.js +8 -8
  28. package/dist/Types.d.ts +16 -10
  29. package/dist/Types.js +1 -1
  30. package/dist/cmd.d.ts +62 -60
  31. package/dist/cmd.js +67 -66
  32. package/dist/createCallBase.d.ts +3 -0
  33. package/dist/createCallBase.js +21 -0
  34. package/dist/createDefer.d.ts +6 -0
  35. package/dist/createDefer.js +27 -0
  36. package/dist/{Testing/fakeOptions.d.ts → fakeOptions.d.ts} +3 -3
  37. package/dist/fakeOptions.js +31 -0
  38. package/dist/index.d.ts +7 -8
  39. package/dist/index.js +8 -1
  40. package/dist/mergeSubscriptions.d.ts +4 -0
  41. package/dist/mergeSubscriptions.js +45 -0
  42. package/dist/useElmish.d.ts +6 -6
  43. package/dist/useElmish.js +78 -52
  44. package/package.json +23 -20
  45. 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
- - [Call back parent components](#call-back-parent-components)
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
- ## With an update function
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
- ## Call back parent components
898
+ ### Merge multiple subscriptions
801
899
 
802
- Since each component has its own model and messages, communication with parent components is done via callback functions.
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
- ```ts Dialog.ts
809
- export type Message =
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
- 1. In the **render** method of the parent component pass the callback as prop
906
+ function localSubscription (model: Model): SubscriptionResult<Message> {
907
+ // ...
908
+ }
842
909
 
843
- ```tsx Parent.tsx
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, execCmd, };
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 ? void 0 : _Services$logger.info("Message from", name, msg.name);
13
- (_Services$logger2 = _Init.Services.logger) === null || _Services$logger2 === void 0 ? void 0 : _Services$logger2.debug("Message from", name, msg);
14
- (_Services$dispatchMid = _Init.Services.dispatchMiddleware) === null || _Services$dispatchMid === void 0 ? void 0 : _Services$dispatchMid.call(_Init.Services, msg);
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.forEach(function (cmd) {
24
- return cmd === null || cmd === void 0 ? void 0 : cmd.forEach(function (call) {
25
- return call(dispatch);
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,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfSW5pdCIsInJlcXVpcmUiLCJsb2dNZXNzYWdlIiwibmFtZSIsIm1zZyIsIl9TZXJ2aWNlcyRsb2dnZXIiLCJfU2VydmljZXMkbG9nZ2VyMiIsIl9TZXJ2aWNlcyRkaXNwYXRjaE1pZCIsIlNlcnZpY2VzIiwibG9nZ2VyIiwiaW5mbyIsImRlYnVnIiwiZGlzcGF0Y2hNaWRkbGV3YXJlIiwiY2FsbCIsIm1vZGVsSGFzQ2hhbmdlZCIsImN1cnJlbnRNb2RlbCIsIm1vZGVsIiwiT2JqZWN0IiwiaXMiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwibGVuZ3RoIiwiZXhlY0NtZCIsImRpc3BhdGNoIiwiX2xlbiIsImFyZ3VtZW50cyIsImNvbW1hbmRzIiwiQXJyYXkiLCJfa2V5IiwiZm9yRWFjaCIsImNtZCJdLCJzb3VyY2VzIjpbIi4uL3NyYy9Db21tb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2VydmljZXMgfSBmcm9tIFwiLi9Jbml0XCI7XG5pbXBvcnQgeyBDbWQsIERpc3BhdGNoLCBNZXNzYWdlIH0gZnJvbSBcIi4vVHlwZXNcIjtcblxuZnVuY3Rpb24gbG9nTWVzc2FnZTxUTWVzc2FnZSBleHRlbmRzIE1lc3NhZ2U+IChuYW1lOiBzdHJpbmcsIG1zZzogVE1lc3NhZ2UpOiB2b2lkIHtcbiAgICBTZXJ2aWNlcy5sb2dnZXI/LmluZm8oXCJNZXNzYWdlIGZyb21cIiwgbmFtZSwgbXNnLm5hbWUpO1xuICAgIFNlcnZpY2VzLmxvZ2dlcj8uZGVidWcoXCJNZXNzYWdlIGZyb21cIiwgbmFtZSwgbXNnKTtcblxuICAgIFNlcnZpY2VzLmRpc3BhdGNoTWlkZGxld2FyZT8uKG1zZyk7XG59XG5cbmZ1bmN0aW9uIG1vZGVsSGFzQ2hhbmdlZDxUTW9kZWw+IChjdXJyZW50TW9kZWw6IFRNb2RlbCwgbW9kZWw6IFBhcnRpYWw8VE1vZGVsPik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhT2JqZWN0LmlzKG1vZGVsLCBjdXJyZW50TW9kZWwpICYmIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG1vZGVsKS5sZW5ndGggPiAwO1xufVxuXG5mdW5jdGlvbiBleGVjQ21kPFRNZXNzYWdlPiAoZGlzcGF0Y2g6IERpc3BhdGNoPFRNZXNzYWdlPiwgLi4uY29tbWFuZHM6IChDbWQ8VE1lc3NhZ2U+IHwgdW5kZWZpbmVkKSBbXSk6IHZvaWQge1xuICAgIGNvbW1hbmRzLmZvckVhY2goY21kID0+IGNtZD8uZm9yRWFjaChjYWxsID0+IGNhbGwoZGlzcGF0Y2gpKSk7XG59XG5cbmV4cG9ydCB7XG4gICAgbG9nTWVzc2FnZSxcbiAgICBtb2RlbEhhc0NoYW5nZWQsXG4gICAgZXhlY0NtZCxcbn07Il0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLEtBQUEsR0FBQUMsT0FBQTtBQUdBLFNBQVNDLFVBQVVBLENBQTRCQyxJQUFZLEVBQUVDLEdBQWEsRUFBUTtFQUFBLElBQUFDLGdCQUFBLEVBQUFDLGlCQUFBLEVBQUFDLHFCQUFBO0VBQzlFLENBQUFGLGdCQUFBLEdBQUFHLGNBQVEsQ0FBQ0MsTUFBTSxjQUFBSixnQkFBQSx1QkFBZkEsZ0JBQUEsQ0FBaUJLLElBQUksQ0FBQyxjQUFjLEVBQUVQLElBQUksRUFBRUMsR0FBRyxDQUFDRCxJQUFJLENBQUM7RUFDckQsQ0FBQUcsaUJBQUEsR0FBQUUsY0FBUSxDQUFDQyxNQUFNLGNBQUFILGlCQUFBLHVCQUFmQSxpQkFBQSxDQUFpQkssS0FBSyxDQUFDLGNBQWMsRUFBRVIsSUFBSSxFQUFFQyxHQUFHLENBQUM7RUFFakQsQ0FBQUcscUJBQUEsR0FBQUMsY0FBUSxDQUFDSSxrQkFBa0IsY0FBQUwscUJBQUEsdUJBQTNCQSxxQkFBQSxDQUFBTSxJQUFBLENBQUFMLGNBQVEsRUFBc0JKLEdBQUcsQ0FBQztBQUN0QztBQUVBLFNBQVNVLGVBQWVBLENBQVVDLFlBQW9CLEVBQUVDLEtBQXNCLEVBQVc7RUFDckYsT0FBTyxDQUFDQyxNQUFNLENBQUNDLEVBQUUsQ0FBQ0YsS0FBSyxFQUFFRCxZQUFZLENBQUMsSUFBSUUsTUFBTSxDQUFDRSxtQkFBbUIsQ0FBQ0gsS0FBSyxDQUFDLENBQUNJLE1BQU0sR0FBRyxDQUFDO0FBQzFGO0FBRUEsU0FBU0MsT0FBT0EsQ0FBWUMsUUFBNEIsRUFBcUQ7RUFBQSxTQUFBQyxJQUFBLEdBQUFDLFNBQUEsQ0FBQUosTUFBQSxFQUFoREssUUFBUSxPQUFBQyxLQUFBLENBQUFILElBQUEsT0FBQUEsSUFBQSxXQUFBSSxJQUFBLE1BQUFBLElBQUEsR0FBQUosSUFBQSxFQUFBSSxJQUFBO0lBQVJGLFFBQVEsQ0FBQUUsSUFBQSxRQUFBSCxTQUFBLENBQUFHLElBQUE7RUFBQTtFQUNqRUYsUUFBUSxDQUFDRyxPQUFPLENBQUMsVUFBQUMsR0FBRztJQUFBLE9BQUlBLEdBQUcsYUFBSEEsR0FBRyx1QkFBSEEsR0FBRyxDQUFFRCxPQUFPLENBQUMsVUFBQWYsSUFBSTtNQUFBLE9BQUlBLElBQUksQ0FBQ1MsUUFBUSxDQUFDO0lBQUEsRUFBQztFQUFBLEVBQUM7QUFDakUifQ==
41
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfSW5pdCIsInJlcXVpcmUiLCJfY3JlYXRlRm9yT2ZJdGVyYXRvckhlbHBlciIsInIiLCJlIiwidCIsIlN5bWJvbCIsIml0ZXJhdG9yIiwiQXJyYXkiLCJpc0FycmF5IiwiX3Vuc3VwcG9ydGVkSXRlcmFibGVUb0FycmF5IiwibGVuZ3RoIiwiX24iLCJGIiwicyIsIm4iLCJkb25lIiwidmFsdWUiLCJmIiwiVHlwZUVycm9yIiwibyIsImEiLCJ1IiwiY2FsbCIsIm5leHQiLCJfYXJyYXlMaWtlVG9BcnJheSIsInRvU3RyaW5nIiwic2xpY2UiLCJjb25zdHJ1Y3RvciIsIm5hbWUiLCJmcm9tIiwidGVzdCIsImxvZ01lc3NhZ2UiLCJtc2ciLCJfU2VydmljZXMkbG9nZ2VyIiwiX1NlcnZpY2VzJGxvZ2dlcjIiLCJfU2VydmljZXMkZGlzcGF0Y2hNaWQiLCJTZXJ2aWNlcyIsImxvZ2dlciIsImluZm8iLCJkZWJ1ZyIsImRpc3BhdGNoTWlkZGxld2FyZSIsIm1vZGVsSGFzQ2hhbmdlZCIsImN1cnJlbnRNb2RlbCIsIm1vZGVsIiwiT2JqZWN0IiwiaXMiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiZXhlY0NtZCIsImRpc3BhdGNoIiwiX2xlbiIsImFyZ3VtZW50cyIsImNvbW1hbmRzIiwiX2tleSIsIl9pdGVyYXRvciIsImZsYXQiLCJfc3RlcCIsImVyciJdLCJzb3VyY2VzIjpbIi4uL3NyYy9Db21tb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU2VydmljZXMgfSBmcm9tIFwiLi9Jbml0XCI7XG5pbXBvcnQgdHlwZSB7IENtZCwgRGlzcGF0Y2gsIE1lc3NhZ2UgfSBmcm9tIFwiLi9UeXBlc1wiO1xuXG5mdW5jdGlvbiBsb2dNZXNzYWdlPFRNZXNzYWdlIGV4dGVuZHMgTWVzc2FnZT4obmFtZTogc3RyaW5nLCBtc2c6IFRNZXNzYWdlKTogdm9pZCB7XG5cdFNlcnZpY2VzLmxvZ2dlcj8uaW5mbyhcIk1lc3NhZ2UgZnJvbVwiLCBuYW1lLCBtc2cubmFtZSk7XG5cdFNlcnZpY2VzLmxvZ2dlcj8uZGVidWcoXCJNZXNzYWdlIGZyb21cIiwgbmFtZSwgbXNnKTtcblxuXHRTZXJ2aWNlcy5kaXNwYXRjaE1pZGRsZXdhcmU/Lihtc2cpO1xufVxuXG5mdW5jdGlvbiBtb2RlbEhhc0NoYW5nZWQ8VE1vZGVsPihjdXJyZW50TW9kZWw6IFRNb2RlbCwgbW9kZWw6IFBhcnRpYWw8VE1vZGVsPik6IGJvb2xlYW4ge1xuXHRyZXR1cm4gIU9iamVjdC5pcyhtb2RlbCwgY3VycmVudE1vZGVsKSAmJiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhtb2RlbCkubGVuZ3RoID4gMDtcbn1cblxuZnVuY3Rpb24gZXhlY0NtZDxUTWVzc2FnZT4oZGlzcGF0Y2g6IERpc3BhdGNoPFRNZXNzYWdlPiwgLi4uY29tbWFuZHM6IChDbWQ8VE1lc3NhZ2U+IHwgdW5kZWZpbmVkKVtdKTogdm9pZCB7XG5cdGZvciAoY29uc3QgY2FsbCBvZiBjb21tYW5kcy5mbGF0KCkpIHtcblx0XHRpZiAoY2FsbCkge1xuXHRcdFx0Y2FsbChkaXNwYXRjaCk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCB7IGV4ZWNDbWQsIGxvZ01lc3NhZ2UsIG1vZGVsSGFzQ2hhbmdlZCB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLEtBQUEsR0FBQUMsT0FBQTtBQUFrQyxTQUFBQywyQkFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEseUJBQUFDLE1BQUEsSUFBQUgsQ0FBQSxDQUFBRyxNQUFBLENBQUFDLFFBQUEsS0FBQUosQ0FBQSxxQkFBQUUsQ0FBQSxRQUFBRyxLQUFBLENBQUFDLE9BQUEsQ0FBQU4sQ0FBQSxNQUFBRSxDQUFBLEdBQUFLLDJCQUFBLENBQUFQLENBQUEsTUFBQUMsQ0FBQSxJQUFBRCxDQUFBLHVCQUFBQSxDQUFBLENBQUFRLE1BQUEsSUFBQU4sQ0FBQSxLQUFBRixDQUFBLEdBQUFFLENBQUEsT0FBQU8sRUFBQSxNQUFBQyxDQUFBLFlBQUFBLEVBQUEsZUFBQUMs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
@@ -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 reentered;
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 };