react-elmish 8.0.0-beta.1 → 8.0.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 (43) hide show
  1. package/README.md +132 -57
  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 +40 -5
  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 +7 -5
  23. package/dist/Testing/index.js +21 -1
  24. package/dist/Testing/initAndExecCmd.d.ts +2 -2
  25. package/dist/Testing/initAndExecCmd.js +12 -12
  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 -7
  39. package/dist/index.js +2 -2
  40. package/dist/useElmish.d.ts +6 -6
  41. package/dist/useElmish.js +78 -52
  42. package/package.json +23 -20
  43. package/dist/Testing/fakeOptions.js +0 -31
package/README.md CHANGED
@@ -20,14 +20,16 @@ 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
27
  - [With an update function](#with-an-update-function)
26
- - [Call back parent components](#call-back-parent-components)
27
28
  - [Testing](#testing)
28
29
  - [Testing the init function](#testing-the-init-function)
29
30
  - [Testing the update handler](#testing-the-update-handler)
30
31
  - [Combine update and execCmd](#combine-update-and-execcmd)
32
+ - [Testing subscriptions](#testing-subscriptions)
31
33
  - [UI Tests](#ui-tests)
32
34
  - [Migrations](#migrations)
33
35
  - [From v1.x to v2.x](#from-v1x-to-v2x)
@@ -262,12 +264,6 @@ You can call one of the functions of that object:
262
264
  | `cmd.ofEither` | Calls a function (sync or async) and maps the result into a message. |
263
265
  | `cmd.ofSuccess` | Same as `ofEither` but ignores the error case. |
264
266
  | `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
267
  | `cmd.ofSub` | Use this function to trigger a command in a subscription. |
272
268
 
273
269
  ### Dispatch a message
@@ -568,6 +564,97 @@ class App extends ElmComponent<Shared.Model, Shared.Message, Shared.Props> {
568
564
 
569
565
  In a functional component you can use the **useEffect** hook as normal.
570
566
 
567
+ ## Deferring model updates and messages
568
+
569
+ 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.
570
+
571
+ Without the `defer` function, you would have to return the model and the command in all cases:
572
+
573
+ ```ts
574
+ const update: UpdateMap<Props, Model, Message> = {
575
+ deferSomething (_msg, model) {
576
+ if (model.someCondition) {
577
+ return [{ alwaysUpdate: "someValue", extra: "extra" }, cmd.ofMsg(Msg.alwaysExecute())];
578
+ }
579
+
580
+ return [{ alwaysUpdate: "someValue" }, cmd.ofMsg(Msg.doSomethingElse()), cmd.ofMsg(Msg.alwaysExecute())];
581
+ },
582
+
583
+ ...LoadSettings.update,
584
+ };
585
+ ```
586
+
587
+ Here we always want to update the model with the `alwaysUpdate` property and always dispatch the `alwaysExecute` message.
588
+
589
+ With the `defer` function, you can do this:
590
+
591
+ ```ts
592
+ const update: UpdateMap<Props, Model, Message> = {
593
+ deferSomething (_msg, model, _props, { defer }) {
594
+ defer({ alwaysUpdate: "someValue" }, cmd.ofMsg(Msg.alwaysExecute()));
595
+
596
+ if (model.someCondition) {
597
+ return [{ extra: "extra" }];
598
+ }
599
+
600
+ return [{}, cmd.ofMsg(Msg.doSomethingElse())];
601
+ },
602
+
603
+ ...LoadSettings.update,
604
+ };
605
+ ```
606
+
607
+ 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.
608
+
609
+ ## Call back parent components
610
+
611
+ Since each component has its own model and messages, communication with parent components is done via callback functions.
612
+
613
+ To inform the parent component about some action, let's say to close a dialog form, you do the following:
614
+
615
+ 1. Create a message
616
+
617
+ ```ts Dialog.ts
618
+ export type Message =
619
+ ...
620
+ | { name: "close" }
621
+ ...
622
+
623
+ export const Msg = {
624
+ ...
625
+ close: (): Message => ({ name: "close" }),
626
+ ...
627
+ }
628
+ ```
629
+
630
+ 1. Define a callback function property in the **Props**:
631
+
632
+ ```ts Dialog.ts
633
+ export type Props = {
634
+ onClose: () => void,
635
+ };
636
+ ```
637
+
638
+ 1. Handle the message and call the callback function:
639
+
640
+ ```ts Dialog.ts
641
+ {
642
+ // ...
643
+ close () {
644
+ return [{}, cmd.ofError(props.onClose, Msg.error)];
645
+ }
646
+ // ...
647
+ };
648
+ ```
649
+
650
+ 1. In the **render** method of the parent component pass the callback as prop
651
+
652
+ ```tsx Parent.tsx
653
+ ...
654
+ <Dialog onClose={() => this.dispatch(Msg.closeDialog())}>
655
+ ...
656
+ ```
657
+
571
658
  ## Composition
572
659
 
573
660
  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,6 +757,16 @@ const update: UpdateMap<Props, Model, Message> = {
670
757
  },
671
758
 
672
759
  ...LoadSettings.update,
760
+
761
+ // You can overwrite the LoadSettings messages handlers here
762
+
763
+ settingsLoaded (_msg, _model, _props, { defer, callBase }) {
764
+ // Use defer and callBase to execute the original handler function:
765
+ defer(...callBase(LoadSettings.settingsLoaded));
766
+
767
+ // Do additional stuff
768
+ return [{ /* ... */ }];
769
+ }
673
770
  };
674
771
  ```
675
772
 
@@ -797,55 +894,6 @@ const updateComposition = (model: Model, msg: CompositionMessage): Elm.UpdateRet
797
894
  }
798
895
  ```
799
896
 
800
- ## Call back parent components
801
-
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
807
-
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
- ```
840
-
841
- 1. In the **render** method of the parent component pass the callback as prop
842
-
843
- ```tsx Parent.tsx
844
- ...
845
- <Dialog onClose={() => this.dispatch(Msg.closeDialog())}>
846
- ...
847
- ```
848
-
849
897
  ## Testing
850
898
 
851
899
  To test your **update** handler you can use some helper functions in `react-elmish/dist/Testing`:
@@ -903,7 +951,7 @@ const createUpdateArgs = getCreateUpdateArgs(init, () => ({ /* initial props */
903
951
 
904
952
  it("returns the correct model and cmd", async () => {
905
953
  // arrange
906
- const args = createUpdateArgs(Msg.test(), { /* optionally override model here */ }, { /* optionally override props here */ });
954
+ const args = createUpdateArgs(Msg.test(), { /* optionally override model here */ }, { /* optionally override props here */ }, { /* optionally override options here */ });
907
955
 
908
956
  // act
909
957
  // Call the update handler
@@ -950,6 +998,33 @@ it("returns the correct cmd", async () => {
950
998
  ...
951
999
  ```
952
1000
 
1001
+ ### Testing subscriptions
1002
+
1003
+ 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:
1004
+
1005
+ ```ts
1006
+ import { getCreateModelAndProps, execSubscription } from "react-elmish/dist/Testing";
1007
+ import { init, Msg, subscription } from "./MyComponent";
1008
+
1009
+ const createModelAndProps = getCreateModelAndProps(init, () => ({ /* initial props */ }));
1010
+
1011
+ it("dispatches the eventTriggered message", async () => {
1012
+ // arrange
1013
+ const mockDispatch = jest.fn();
1014
+ const args = createModelAndProps({ /* optionally override model here */ }, { /* optionally override props here */ });
1015
+ const dispose = execSubscription(subscription, mockDispatch, ...args);
1016
+
1017
+ // act
1018
+ // Trigger events
1019
+
1020
+ // assert
1021
+ expect(mockDispatch).toHaveBeenCalledWith(Msg.eventTriggered());
1022
+
1023
+ // Dispose the subscriptions if required
1024
+ dispose();
1025
+ });
1026
+ ```
1027
+
953
1028
  ### UI Tests
954
1029
 
955
1030
  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+IHwgdW5kZWZpbmVkKVtdKTogdm9pZCB7XG5cdGZvciAoY29uc3QgY2FsbCBvZiBjb21tYW5kcy5mbGF0KCkpIHtcblx0XHRpZiAoY2FsbCkge1xuXHRcdFx0Y2FsbChkaXNwYXRjaCk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCB7IGV4ZWNDbWQsIGxvZ01lc3NhZ2UsIG1vZGVsSGFzQ2hhbmdlZCB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBLElBQUFBLEtBQUEsR0FBQUMsT0FBQTtBQUFrQyxTQUFBQywyQkFBQUMsQ0FBQSxFQUFBQyxDQUFBLFFBQUFDLENBQUEseUJBQUFDLE1BQUEsSUFBQUgsQ0FBQSxDQUFBRyxNQUFBLENBQUFDLFFBQUEsS0FBQUosQ0FBQSxxQkFBQUUsQ0FBQSxRQUFBRyxLQUFBLENBQUFDLE9BQUEsQ0FBQU4sQ0FBQSxNQUFBRSxDQUFBLEdBQUFLLDJCQUFBLENBQUFQLENBQUEsTUFBQUMsQ0FBQSxJQUFBRCxDQUFBLHVCQUFBQSxDQUFBLENBQUFRLE1BQUEsSUFBQU4sQ0FBQSxLQUFBRixDQUFBLEdBQUFFLENBQUEsT0FBQU8sRUFBQSxNQUFBQyxDQUFBLFlBQUFBLEVBQUEsZUFBQUMsQ0FBQSxFQUFBRCxDQUFBLEVBQUFFLENBQUEsV0FBQUEsRUFBQSxXQUFBSCxFQUFBLElBQUFULENBQUEsQ0FBQVEsTUFBQSxLQUFBSyxJQUFBLFdBQUFBLElBQUEsTUFBQUMsS0FBQSxFQUFBZCxDQUFBLENBQUFTLEVBQUEsVUFBQVIsQ0FBQSxXQUFBQSxFQUFBRCxDQUFBLFVBQUFBLENBQUEsS0FBQWUsQ0FBQSxFQUFBTCxDQUFBLGdCQUFBTSxTQUFBLGlKQUFBQyxDQUFBLEVBQUFDLENBQUEsT0FBQUMsQ0FBQSxnQkFBQVIsQ0FBQSxXQUFBQSxFQUFBLElBQUFULENBQUEsR0FBQUEsQ0FBQSxDQUFBa0IsSUFBQSxDQUFBcEIsQ0FBQSxNQUFBWSxDQUFBLFdBQUFBLEVBQUEsUUFBQVosQ0FBQSxHQUFBRSxDQUFBLENBQUFtQixJQUFBLFdBQUFILENBQUEsR0FBQWxCLENBQUEsQ0FBQWEsSUFBQSxFQUFBYixDQUFBLEtBQUFDLENBQUEsV0FBQUEsRUFBQUQsQ0FBQSxJQUFBbUIsQ0FBQSxPQUFBRixDQUFBLEdBQUFqQixDQUFBLEtBQUFlLENBQUEsV0FBQUEsRUFBQSxVQUFBRyxDQUFBLFlBQUFoQixDQUFBLGNBQUFBLENBQUEsOEJBQUFpQixDQUFBLFFBQUFGLENBQUE7QUFBQSxTQUFBViw0QkFBQVAsQ0FBQSxFQUFBa0IsQ0FBQSxRQUFBbEIsQ0FBQSwyQkFBQUEsQ0FBQSxTQUFBc0IsaUJBQUEsQ0FBQXRCLENBQUEsRUFBQWtCLENBQUEsT0FBQWhCLENBQUEsTUFBQXFCLFFBQUEsQ0FBQUgsSUFBQSxDQUFBcEIsQ0FBQSxFQUFBd0IsS0FBQSw2QkFBQXRCLENBQUEsSUFBQUYsQ0FBQSxDQUFBeUIsV0FBQSxLQUFBdkIsQ0FBQSxHQUFBRixDQUFBLENBQUF5QixXQUFBLENBQUFDLElBQUEsYUFBQXhCLENBQUEsY0FBQUEsQ0FBQSxHQUFBRyxLQUFBLENBQUFzQixJQUFBLENBQUEzQixDQUFBLG9CQUFBRSxDQUFBLCtDQUFBMEIsSUFBQSxDQUFBMUIsQ0FBQSxJQUFBb0IsaUJBQUEsQ0FBQXRCLENBQUEsRUFBQWtCLENBQUE7QUFBQSxTQUFBSSxrQkFBQXRCLENBQUEsRUFBQWtCLENBQUEsYUFBQUEsQ0FBQSxJQUFBQSxDQUFBLEdBQUFsQixDQUFBLENBQUFRLE1BQUEsTUFBQVUsQ0FBQSxHQUFBbEIsQ0FBQSxDQUFBUSxNQUFBLFlBQUFQLENBQUEsTUFBQVcsQ0FBQSxHQUFBUCxLQUFBLENBQUFhLENBQUEsR0FBQWpCLENBQUEsR0FBQWlCLENBQUEsRUFBQWpCLENBQUEsSUFBQVcsQ0FBQSxDQUFBWCxDQUFBLElBQUFELENBQUEsQ0FBQUMsQ0FBQSxVQUFBVyxDQUFBO0FBR2xDLFNBQVNpQixVQUFVQSxDQUEyQkgsSUFBWSxFQUFFSSxHQUFhLEVBQVE7RUFBQSxJQUFBQyxnQkFBQSxFQUFBQyxpQkFBQSxFQUFBQyxxQkFBQTtFQUNoRixDQUFBRixnQkFBQSxHQUFBRyxjQUFRLENBQUNDLE1BQU0sY0FBQUosZ0JBQUEsZUFBZkEsZ0JBQUEsQ0FBaUJLLElBQUksQ0FBQyxjQUFjLEVBQUVWLElBQUksRUFBRUksR0FBRyxDQUFDSixJQUFJLENBQUM7RUFDckQsQ0FBQU0saUJBQUEsR0FBQUUsY0FBUSxDQUFDQyxNQUFNLGNBQUFILGlCQUFBLGVBQWZBLGlCQUFBLENBQWlCSyxLQUFLLENBQUMsY0FBYyxFQUFFWCxJQUFJLEVBQUVJLEdBQUcsQ0FBQztFQUVqRCxDQUFBRyxxQkFBQSxHQUFBQyxjQUFRLENBQUNJLGtCQUFrQixjQUFBTCxxQkFBQSxlQUEzQkEscUJBQUEsQ0FBQWIsSUFBQSxDQUFBYyxjQUFRLEVBQXNCSixHQUFHLENBQUM7QUFDbkM7QUFFQSxTQUFTUyxlQUFlQSxDQUFTQyxZQUFvQixFQUFFQyxLQUFzQixFQUFXO0VBQ3ZGLE9BQU8sQ0FBQ0MsTUFBTSxDQUFDQyxFQUFFLENBQUNGLEtBQUssRUFBRUQsWUFBWSxDQUFDLElBQUlFLE1BQU0sQ0FBQ0UsbUJBQW1CLENBQUNILEtBQUssQ0FBQyxDQUFDakMsTUFBTSxHQUFHLENBQUM7QUFDdkY7QUFFQSxTQUFTcUMsT0FBT0EsQ0FBV0MsUUFBNEIsRUFBb0Q7RUFBQSxTQUFBQyxJQUFBLEdBQUFDLFNBQUEsQ0FBQXhDLE1BQUEsRUFBL0N5QyxRQUFRLE9BQUE1QyxLQUFBLENBQUEwQyxJQUFBLE9BQUFBLElBQUEsV0FBQUcsSUFBQSxNQUFBQSxJQUFBLEdBQUFILElBQUEsRUFBQUcsSUFBQTtJQUFSRCxRQUFRLENBQUFDLElBQUEsUUFBQUYsU0FBQSxDQUFBRSxJQUFBO0VBQUE7RUFBQSxJQUFBQyxTQUFBLEdBQUFwRCwwQkFBQSxDQUNoRGtELFFBQVEsQ0FBQ0csSUFBSSxDQUFDLENBQUM7SUFBQUMsS0FBQTtFQUFBO0lBQWxDLEtBQUFGLFNBQUEsQ0FBQXhDLENBQUEsTUFBQTBDLEtBQUEsR0FBQUYsU0FBQSxDQUFBdkMsQ0FBQSxJQUFBQyxJQUFBLEdBQW9DO01BQUEsSUFBekJPLElBQUksR0FBQWlDLEtBQUEsQ0FBQXZDLEtBQUE7TUFDZCxJQUFJTSxJQUFJLEVBQUU7UUFDVEEsSUFBSSxDQUFDMEIsUUFBUSxDQUFDO01BQ2Y7SUFDRDtFQUFDLFNBQUFRLEdBQUE7SUFBQUgsU0FBQSxDQUFBbEQsQ0FBQSxDQUFBcUQsR0FBQTtFQUFBO0lBQUFILFNBQUEsQ0FBQXBDLENBQUE7RUFBQTtBQUNGIiwiaWdub3JlTGlzdCI6W119
@@ -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 };