@cratis/arc.react.mvvm 18.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 (238) hide show
  1. package/Bindings.ts +18 -0
  2. package/IHandleParams.ts +14 -0
  3. package/IHandleProps.ts +14 -0
  4. package/IHandleQueryParams.ts +14 -0
  5. package/IViewModelDetached.ts +12 -0
  6. package/MVVMContext.tsx +27 -0
  7. package/MobxOptions.ts +20 -0
  8. package/README.md +65 -0
  9. package/WellKnownBindings.ts +11 -0
  10. package/browser/ILocalStorage.ts +11 -0
  11. package/browser/INavigation.ts +9 -0
  12. package/browser/Navigation.ts +29 -0
  13. package/browser/index.ts +6 -0
  14. package/dialogs/BusyIndicator.ts +24 -0
  15. package/dialogs/DialogMediator.tsx +51 -0
  16. package/dialogs/DialogMediatorHandler.ts +67 -0
  17. package/dialogs/DialogRegistration.ts +25 -0
  18. package/dialogs/Dialogs.ts +58 -0
  19. package/dialogs/IDialogMediatorHandler.ts +40 -0
  20. package/dialogs/IDialogs.ts +37 -0
  21. package/dialogs/index.ts +12 -0
  22. package/dialogs/useDialog.tsx +34 -0
  23. package/dist/cjs/Bindings.d.ts +4 -0
  24. package/dist/cjs/Bindings.d.ts.map +1 -0
  25. package/dist/cjs/Bindings.js +21 -0
  26. package/dist/cjs/Bindings.js.map +1 -0
  27. package/dist/cjs/IHandleParams.d.ts +4 -0
  28. package/dist/cjs/IHandleParams.d.ts.map +1 -0
  29. package/dist/cjs/IHandleProps.d.ts +4 -0
  30. package/dist/cjs/IHandleProps.d.ts.map +1 -0
  31. package/dist/cjs/IHandleQueryParams.d.ts +4 -0
  32. package/dist/cjs/IHandleQueryParams.d.ts.map +1 -0
  33. package/dist/cjs/IViewModelDetached.d.ts +4 -0
  34. package/dist/cjs/IViewModelDetached.d.ts.map +1 -0
  35. package/dist/cjs/MVVMContext.d.ts +9 -0
  36. package/dist/cjs/MVVMContext.d.ts.map +1 -0
  37. package/dist/cjs/MVVMContext.js +21 -0
  38. package/dist/cjs/MVVMContext.js.map +1 -0
  39. package/dist/cjs/MobxOptions.d.ts +12 -0
  40. package/dist/cjs/MobxOptions.d.ts.map +1 -0
  41. package/dist/cjs/WellKnownBindings.d.ts +6 -0
  42. package/dist/cjs/WellKnownBindings.d.ts.map +1 -0
  43. package/dist/cjs/WellKnownBindings.js +10 -0
  44. package/dist/cjs/WellKnownBindings.js.map +1 -0
  45. package/dist/cjs/browser/ILocalStorage.d.ts +9 -0
  46. package/dist/cjs/browser/ILocalStorage.d.ts.map +1 -0
  47. package/dist/cjs/browser/ILocalStorage.js +7 -0
  48. package/dist/cjs/browser/ILocalStorage.js.map +1 -0
  49. package/dist/cjs/browser/INavigation.d.ts +5 -0
  50. package/dist/cjs/browser/INavigation.d.ts.map +1 -0
  51. package/dist/cjs/browser/INavigation.js +7 -0
  52. package/dist/cjs/browser/INavigation.js.map +1 -0
  53. package/dist/cjs/browser/Navigation.d.ts +7 -0
  54. package/dist/cjs/browser/Navigation.d.ts.map +1 -0
  55. package/dist/cjs/browser/Navigation.js +25 -0
  56. package/dist/cjs/browser/Navigation.js.map +1 -0
  57. package/dist/cjs/browser/index.d.ts +4 -0
  58. package/dist/cjs/browser/index.d.ts.map +1 -0
  59. package/dist/cjs/browser/index.js +12 -0
  60. package/dist/cjs/browser/index.js.map +1 -0
  61. package/dist/cjs/dialogs/BusyIndicator.d.ts +7 -0
  62. package/dist/cjs/dialogs/BusyIndicator.d.ts.map +1 -0
  63. package/dist/cjs/dialogs/BusyIndicator.js +16 -0
  64. package/dist/cjs/dialogs/BusyIndicator.js.map +1 -0
  65. package/dist/cjs/dialogs/DialogMediator.d.ts +11 -0
  66. package/dist/cjs/dialogs/DialogMediator.d.ts.map +1 -0
  67. package/dist/cjs/dialogs/DialogMediator.js +17 -0
  68. package/dist/cjs/dialogs/DialogMediator.js.map +1 -0
  69. package/dist/cjs/dialogs/DialogMediatorHandler.d.ts +14 -0
  70. package/dist/cjs/dialogs/DialogMediatorHandler.d.ts.map +1 -0
  71. package/dist/cjs/dialogs/DialogMediatorHandler.js +46 -0
  72. package/dist/cjs/dialogs/DialogMediatorHandler.js.map +1 -0
  73. package/dist/cjs/dialogs/DialogRegistration.d.ts +8 -0
  74. package/dist/cjs/dialogs/DialogRegistration.d.ts.map +1 -0
  75. package/dist/cjs/dialogs/DialogRegistration.js +13 -0
  76. package/dist/cjs/dialogs/DialogRegistration.js.map +1 -0
  77. package/dist/cjs/dialogs/Dialogs.d.ts +13 -0
  78. package/dist/cjs/dialogs/Dialogs.d.ts.map +1 -0
  79. package/dist/cjs/dialogs/Dialogs.js +40 -0
  80. package/dist/cjs/dialogs/Dialogs.js.map +1 -0
  81. package/dist/cjs/dialogs/IDialogMediatorHandler.d.ts +10 -0
  82. package/dist/cjs/dialogs/IDialogMediatorHandler.d.ts.map +1 -0
  83. package/dist/cjs/dialogs/IDialogMediatorHandler.js +7 -0
  84. package/dist/cjs/dialogs/IDialogMediatorHandler.js.map +1 -0
  85. package/dist/cjs/dialogs/IDialogs.d.ts +9 -0
  86. package/dist/cjs/dialogs/IDialogs.d.ts.map +1 -0
  87. package/dist/cjs/dialogs/IDialogs.js +7 -0
  88. package/dist/cjs/dialogs/IDialogs.js.map +1 -0
  89. package/dist/cjs/dialogs/index.d.ts +10 -0
  90. package/dist/cjs/dialogs/index.d.ts.map +1 -0
  91. package/dist/cjs/dialogs/index.js +24 -0
  92. package/dist/cjs/dialogs/index.js.map +1 -0
  93. package/dist/cjs/dialogs/useDialog.d.ts +5 -0
  94. package/dist/cjs/dialogs/useDialog.d.ts.map +1 -0
  95. package/dist/cjs/dialogs/useDialog.js +23 -0
  96. package/dist/cjs/dialogs/useDialog.js.map +1 -0
  97. package/dist/cjs/index.d.ts +14 -0
  98. package/dist/cjs/index.d.ts.map +1 -0
  99. package/dist/cjs/index.js +22 -0
  100. package/dist/cjs/index.js.map +1 -0
  101. package/dist/cjs/messaging/IMessenger.d.ts +8 -0
  102. package/dist/cjs/messaging/IMessenger.d.ts.map +1 -0
  103. package/dist/cjs/messaging/IMessenger.js +7 -0
  104. package/dist/cjs/messaging/IMessenger.js.map +1 -0
  105. package/dist/cjs/messaging/Message.d.ts +7 -0
  106. package/dist/cjs/messaging/Message.d.ts.map +1 -0
  107. package/dist/cjs/messaging/Message.js +13 -0
  108. package/dist/cjs/messaging/Message.js.map +1 -0
  109. package/dist/cjs/messaging/Messenger.d.ts +9 -0
  110. package/dist/cjs/messaging/Messenger.d.ts.map +1 -0
  111. package/dist/cjs/messaging/Messenger.js +20 -0
  112. package/dist/cjs/messaging/Messenger.js.map +1 -0
  113. package/dist/cjs/messaging/index.d.ts +4 -0
  114. package/dist/cjs/messaging/index.d.ts.map +1 -0
  115. package/dist/cjs/messaging/index.js +12 -0
  116. package/dist/cjs/messaging/index.js.map +1 -0
  117. package/dist/cjs/withViewModel.d.ts +8 -0
  118. package/dist/cjs/withViewModel.d.ts.map +1 -0
  119. package/dist/cjs/withViewModel.js +125 -0
  120. package/dist/cjs/withViewModel.js.map +1 -0
  121. package/dist/esm/Bindings.d.ts +4 -0
  122. package/dist/esm/Bindings.d.ts.map +1 -0
  123. package/dist/esm/Bindings.js +19 -0
  124. package/dist/esm/Bindings.js.map +1 -0
  125. package/dist/esm/IHandleParams.d.ts +4 -0
  126. package/dist/esm/IHandleParams.d.ts.map +1 -0
  127. package/dist/esm/IHandleParams.js +2 -0
  128. package/dist/esm/IHandleParams.js.map +1 -0
  129. package/dist/esm/IHandleProps.d.ts +4 -0
  130. package/dist/esm/IHandleProps.d.ts.map +1 -0
  131. package/dist/esm/IHandleProps.js +2 -0
  132. package/dist/esm/IHandleProps.js.map +1 -0
  133. package/dist/esm/IHandleQueryParams.d.ts +4 -0
  134. package/dist/esm/IHandleQueryParams.d.ts.map +1 -0
  135. package/dist/esm/IHandleQueryParams.js +2 -0
  136. package/dist/esm/IHandleQueryParams.js.map +1 -0
  137. package/dist/esm/IViewModelDetached.d.ts +4 -0
  138. package/dist/esm/IViewModelDetached.d.ts.map +1 -0
  139. package/dist/esm/IViewModelDetached.js +2 -0
  140. package/dist/esm/IViewModelDetached.js.map +1 -0
  141. package/dist/esm/MVVMContext.d.ts +9 -0
  142. package/dist/esm/MVVMContext.d.ts.map +1 -0
  143. package/dist/esm/MVVMContext.js +18 -0
  144. package/dist/esm/MVVMContext.js.map +1 -0
  145. package/dist/esm/MobxOptions.d.ts +12 -0
  146. package/dist/esm/MobxOptions.d.ts.map +1 -0
  147. package/dist/esm/MobxOptions.js +2 -0
  148. package/dist/esm/MobxOptions.js.map +1 -0
  149. package/dist/esm/WellKnownBindings.d.ts +6 -0
  150. package/dist/esm/WellKnownBindings.d.ts.map +1 -0
  151. package/dist/esm/WellKnownBindings.js +8 -0
  152. package/dist/esm/WellKnownBindings.js.map +1 -0
  153. package/dist/esm/browser/ILocalStorage.d.ts +9 -0
  154. package/dist/esm/browser/ILocalStorage.d.ts.map +1 -0
  155. package/dist/esm/browser/ILocalStorage.js +5 -0
  156. package/dist/esm/browser/ILocalStorage.js.map +1 -0
  157. package/dist/esm/browser/INavigation.d.ts +5 -0
  158. package/dist/esm/browser/INavigation.d.ts.map +1 -0
  159. package/dist/esm/browser/INavigation.js +5 -0
  160. package/dist/esm/browser/INavigation.js.map +1 -0
  161. package/dist/esm/browser/Navigation.d.ts +7 -0
  162. package/dist/esm/browser/Navigation.d.ts.map +1 -0
  163. package/dist/esm/browser/Navigation.js +23 -0
  164. package/dist/esm/browser/Navigation.js.map +1 -0
  165. package/dist/esm/browser/index.d.ts +4 -0
  166. package/dist/esm/browser/index.d.ts.map +1 -0
  167. package/dist/esm/browser/index.js +4 -0
  168. package/dist/esm/browser/index.js.map +1 -0
  169. package/dist/esm/dialogs/BusyIndicator.d.ts +7 -0
  170. package/dist/esm/dialogs/BusyIndicator.d.ts.map +1 -0
  171. package/dist/esm/dialogs/BusyIndicator.js +14 -0
  172. package/dist/esm/dialogs/BusyIndicator.js.map +1 -0
  173. package/dist/esm/dialogs/DialogMediator.d.ts +11 -0
  174. package/dist/esm/dialogs/DialogMediator.d.ts.map +1 -0
  175. package/dist/esm/dialogs/DialogMediator.js +13 -0
  176. package/dist/esm/dialogs/DialogMediator.js.map +1 -0
  177. package/dist/esm/dialogs/DialogMediatorHandler.d.ts +14 -0
  178. package/dist/esm/dialogs/DialogMediatorHandler.d.ts.map +1 -0
  179. package/dist/esm/dialogs/DialogMediatorHandler.js +44 -0
  180. package/dist/esm/dialogs/DialogMediatorHandler.js.map +1 -0
  181. package/dist/esm/dialogs/DialogRegistration.d.ts +8 -0
  182. package/dist/esm/dialogs/DialogRegistration.d.ts.map +1 -0
  183. package/dist/esm/dialogs/DialogRegistration.js +11 -0
  184. package/dist/esm/dialogs/DialogRegistration.js.map +1 -0
  185. package/dist/esm/dialogs/Dialogs.d.ts +13 -0
  186. package/dist/esm/dialogs/Dialogs.d.ts.map +1 -0
  187. package/dist/esm/dialogs/Dialogs.js +38 -0
  188. package/dist/esm/dialogs/Dialogs.js.map +1 -0
  189. package/dist/esm/dialogs/IDialogMediatorHandler.d.ts +10 -0
  190. package/dist/esm/dialogs/IDialogMediatorHandler.d.ts.map +1 -0
  191. package/dist/esm/dialogs/IDialogMediatorHandler.js +5 -0
  192. package/dist/esm/dialogs/IDialogMediatorHandler.js.map +1 -0
  193. package/dist/esm/dialogs/IDialogs.d.ts +9 -0
  194. package/dist/esm/dialogs/IDialogs.d.ts.map +1 -0
  195. package/dist/esm/dialogs/IDialogs.js +5 -0
  196. package/dist/esm/dialogs/IDialogs.js.map +1 -0
  197. package/dist/esm/dialogs/index.d.ts +10 -0
  198. package/dist/esm/dialogs/index.d.ts.map +1 -0
  199. package/dist/esm/dialogs/index.js +9 -0
  200. package/dist/esm/dialogs/index.js.map +1 -0
  201. package/dist/esm/dialogs/useDialog.d.ts +5 -0
  202. package/dist/esm/dialogs/useDialog.d.ts.map +1 -0
  203. package/dist/esm/dialogs/useDialog.js +21 -0
  204. package/dist/esm/dialogs/useDialog.js.map +1 -0
  205. package/dist/esm/index.d.ts +14 -0
  206. package/dist/esm/index.d.ts.map +1 -0
  207. package/dist/esm/index.js +12 -0
  208. package/dist/esm/index.js.map +1 -0
  209. package/dist/esm/messaging/IMessenger.d.ts +8 -0
  210. package/dist/esm/messaging/IMessenger.d.ts.map +1 -0
  211. package/dist/esm/messaging/IMessenger.js +5 -0
  212. package/dist/esm/messaging/IMessenger.js.map +1 -0
  213. package/dist/esm/messaging/Message.d.ts +7 -0
  214. package/dist/esm/messaging/Message.d.ts.map +1 -0
  215. package/dist/esm/messaging/Message.js +11 -0
  216. package/dist/esm/messaging/Message.js.map +1 -0
  217. package/dist/esm/messaging/Messenger.d.ts +9 -0
  218. package/dist/esm/messaging/Messenger.d.ts.map +1 -0
  219. package/dist/esm/messaging/Messenger.js +18 -0
  220. package/dist/esm/messaging/Messenger.js.map +1 -0
  221. package/dist/esm/messaging/index.d.ts +4 -0
  222. package/dist/esm/messaging/index.d.ts.map +1 -0
  223. package/dist/esm/messaging/index.js +4 -0
  224. package/dist/esm/messaging/index.js.map +1 -0
  225. package/dist/esm/tsconfig.tsbuildinfo +1 -0
  226. package/dist/esm/withViewModel.d.ts +8 -0
  227. package/dist/esm/withViewModel.d.ts.map +1 -0
  228. package/dist/esm/withViewModel.js +123 -0
  229. package/dist/esm/withViewModel.js.map +1 -0
  230. package/global.d.ts +11 -0
  231. package/index.ts +21 -0
  232. package/messaging/IMessenger.ts +28 -0
  233. package/messaging/Message.ts +18 -0
  234. package/messaging/Messenger.ts +26 -0
  235. package/messaging/for_Messenger/when_publishing_message_with_subscriber.ts +27 -0
  236. package/messaging/index.ts +6 -0
  237. package/package.json +71 -0
  238. package/withViewModel.tsx +181 -0
package/Bindings.ts ADDED
@@ -0,0 +1,18 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { container } from 'tsyringe';
5
+ import { IMessenger, Messenger } from './messaging';
6
+ import { Constructor } from '@cratis/fundamentals';
7
+ import { ILocalStorage, INavigation, Navigation } from './browser';
8
+ import { IdentityProvider, IIdentityProvider } from '@cratis/arc/identity';
9
+
10
+ export class Bindings {
11
+ static initialize() {
12
+ container.registerSingleton(IMessenger as Constructor<IMessenger>, Messenger);
13
+ container.registerSingleton(INavigation as Constructor<INavigation>, Navigation);
14
+ container.registerSingleton(IIdentityProvider as Constructor<IIdentityProvider>, IdentityProvider);
15
+ container.registerInstance(ILocalStorage as Constructor<ILocalStorage>, localStorage);
16
+ }
17
+ }
18
+
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Represents a component that can handle parameters, typically a viewModel.
6
+ */
7
+ export interface IHandleParams<T = object> {
8
+
9
+ /**
10
+ * Handle params.
11
+ * @param params Params to handle.
12
+ */
13
+ handleParams(params: T): void;
14
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Represents a component that can handle props, typically a viewModel.
6
+ */
7
+ export interface IHandleProps<T = object> {
8
+
9
+ /**
10
+ * Handle props.
11
+ * @param props Props to handle.
12
+ */
13
+ handleProps(props: T): void;
14
+ }
@@ -0,0 +1,14 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Represents a component that can handle query parameters, typically a viewModel.
6
+ */
7
+ export interface IHandleQueryParams<T = object> {
8
+
9
+ /**
10
+ * Handle query params.
11
+ * @param queryParams Query Params to handle.
12
+ */
13
+ handleQueryParams(queryParams: T): void;
14
+ }
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Represents the view model that is detached from the view. Use this to get the signature of the method that gets called when the view model is detached from the view.
6
+ */
7
+ export interface IViewModelDetached {
8
+ /**
9
+ * Method that gets called when the view model is detached from the view.
10
+ */
11
+ detached(): void;
12
+ }
@@ -0,0 +1,27 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import React from 'react';
5
+ import { Bindings } from './Bindings';
6
+ import { configure as configureMobx } from 'mobx';
7
+ import { MobxOptions } from './MobxOptions';
8
+
9
+ export interface MVVMProps {
10
+ children?: JSX.Element | JSX.Element[];
11
+ mobx?: MobxOptions;
12
+ }
13
+
14
+ export const MVVMContext = React.createContext({});
15
+
16
+ export const MVVM = (props: MVVMProps) => {
17
+ const options: MobxOptions = {
18
+ ...{ enforceActions: 'never' },
19
+ ...(props.mobx || {}),
20
+ };
21
+
22
+ configureMobx(options);
23
+
24
+ Bindings.initialize();
25
+
26
+ return <MVVMContext.Provider value={{}}>{props.children}</MVVMContext.Provider>;
27
+ };
package/MobxOptions.ts ADDED
@@ -0,0 +1,20 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export interface MobxOptions {
5
+ enforceActions?: "never" | "always" | "observed";
6
+ computedRequiresReaction?: boolean;
7
+ /**
8
+ * Warn if you try to create to derivation / reactive context without accessing any observable.
9
+ */
10
+ reactionRequiresObservable?: boolean;
11
+ /**
12
+ * Warn if observables are accessed outside a reactive context
13
+ */
14
+ observableRequiresReaction?: boolean;
15
+ isolateGlobalState?: boolean;
16
+ disableErrorBoundaries?: boolean;
17
+ safeDescriptors?: boolean;
18
+ reactionScheduler?: (f: () => void) => void;
19
+ useProxies?: "always" | "never" | "ifavailable";
20
+ }
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # Cratis Application Model
2
+
3
+ ## Packages / Deployables
4
+
5
+ [![Nuget](https://img.shields.io/nuget/v/Cratis.Arc?logo=nuget)](http://nuget.org/packages/Cratis.Arc)
6
+ [![NPM](https://img.shields.io/npm/v/@cratis/arc?label=@cratis/arc&logo=npm)](https://www.npmjs.com/package/@cratis/arc)
7
+
8
+ ## Builds
9
+
10
+ [![.NET Build](https://github.com/cratis/arc/actions/workflows/dotnet-build.yml/badge.svg)](https://github.com/cratis/arc/actions/workflows/dotnet-build.yml)
11
+ [![JavaScript Build](https://github.com/cratis/arc/actions/workflows/javascript-build.yml/badge.svg)](https://github.com/cratis/arc/actions/workflows/javascript-build.yml)
12
+ [![Documentation site](https://github.com/Cratis/Documentation/actions/workflows/pages.yml/badge.svg)](https://github.com/Cratis/Documentation/actions/workflows/pages.yml)
13
+
14
+ ## Description
15
+
16
+ The Cratis Application model represents an opinionated approach to building consistent applications based on the concepts behind CQRS.
17
+ It offers extensions for different frameworks and is built on top of ASP.NET Core. One of the traits of Arc has is the
18
+ bridging between the backend and the frontend. Arc provides a tool, called **ProxyGenerator** that generates TypeScript
19
+ code for recognized artifacts matching the criteria of what is considered a **commmand** or a **query**.
20
+
21
+ ## Contributing
22
+
23
+ If you want to jump into building this repository and possibly contributing, please refer to [contributing](./Documentation/contributing/index.md).
24
+
25
+ ### Prerequisites
26
+
27
+ The following are prerequisites to work with this repository.
28
+
29
+ * [.NET 8+](https://dotnet.microsoft.com/en-us/).
30
+ * [Node 16+](https://nodejs.org/en)
31
+ * [Yarn](https://yarnpkg.com)
32
+
33
+ ### Central Package Management
34
+
35
+ This repository leverages [Central Package Management](https://learn.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management), which
36
+ means that all package versions are managed from a file at the root level called [Directory.Packages.props](./Directory.Packages.props).
37
+
38
+ In addition there are also [Directory.Build.props](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory?view=vs-2022#directorybuildprops-and-directorybuildtargets) files for
39
+ setting up common settings that are applied cross cuttingly.
40
+
41
+ ### Root package.json
42
+
43
+ The `package.json` found at the root level defines all the workspaces. It is assumed
44
+
45
+ All developer dependencies are defined in the top level `package.json`. The reason for this is to be able to provide global scripts
46
+ for every package to use for easier maintenance.
47
+
48
+ The `package.json` found at the top level contains scripts that can then be used in a child project for this to work properly.
49
+
50
+ In a package, all you need to do is to define the scripts to use the global scripts in the `package.json´ of that project:
51
+
52
+ ```json
53
+ {
54
+ "scripts": {
55
+ "prepublish": "yarn g:build",
56
+ "clean": "yarn g:clean",
57
+ "build": "yarn g:build",
58
+ "lint": "yarn g:lint",
59
+ "lint:ci": "yarn g:lint:ci",
60
+ "test": "yarn g:test",
61
+ "ci": "yarn g:ci",
62
+ "up": "yarn g:up"
63
+ }
64
+ }
65
+ ```
@@ -0,0 +1,11 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Well-known IoC binding constants.
6
+ */
7
+ export const WellKnownBindings = {
8
+ queryParams: 'queryParams',
9
+ params: 'params',
10
+ props: 'props'
11
+ };
@@ -0,0 +1,11 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export abstract class ILocalStorage implements Storage {
5
+ abstract length: number;
6
+ abstract clear(): void;
7
+ abstract getItem(key: string): string | null;
8
+ abstract key(index: number): string | null;
9
+ abstract removeItem(key: string): void;
10
+ abstract setItem(key: string, value: string): void;
11
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export type UrlChangedCallback = (url: string, previousUrl: string) => void;
5
+
6
+ export abstract class INavigation {
7
+ abstract onUrlChanged(callback: UrlChangedCallback): void;
8
+ }
9
+
@@ -0,0 +1,29 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { INavigation, UrlChangedCallback } from './INavigation';
5
+
6
+ export class Navigation implements INavigation {
7
+ private readonly _callbacks: UrlChangedCallback[] = [];
8
+
9
+ constructor() {
10
+ const previousUrl = location.href;
11
+ const observer = new MutationObserver(() => {
12
+ if (location.href !== previousUrl) {
13
+ for( const callback of this._callbacks ) {
14
+ callback(location.href, previousUrl);
15
+ }
16
+ }
17
+ });
18
+ observer.observe(document.body,
19
+ {
20
+ childList: true,
21
+ subtree: true
22
+ }
23
+ );
24
+ }
25
+
26
+ onUrlChanged(callback: UrlChangedCallback): void {
27
+ this._callbacks.push(callback);
28
+ }
29
+ }
@@ -0,0 +1,6 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export * from './INavigation';
5
+ export * from './Navigation';
6
+ export * from './ILocalStorage';
@@ -0,0 +1,24 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { CloseDialog, DialogResult } from '@cratis/arc.react/dialogs';
5
+
6
+ /**
7
+ * Represents a busy indicator dialog.
8
+ */
9
+ export class BusyIndicator {
10
+
11
+ /**
12
+ * Initializes a new instance of {@link BusyIndicator}.
13
+ * @param {CloseDialog<void>} _closeDialog The dialog resolver to use for closing the dialog.
14
+ */
15
+ constructor(private readonly _closeDialog: CloseDialog<void>) {
16
+ }
17
+
18
+ /**
19
+ * Close the busy indicator dialog.
20
+ */
21
+ close() {
22
+ this._closeDialog(DialogResult.None);
23
+ }
24
+ }
@@ -0,0 +1,51 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import React from 'react';
5
+ import { IDialogMediatorHandler } from './IDialogMediatorHandler';
6
+
7
+ /**
8
+ * Context for the dialog mediator.
9
+ */
10
+ export const DialogMediatorContext = React.createContext<IDialogMediatorHandler>(undefined!);
11
+
12
+ /**
13
+ * Props for the dialog mediator.
14
+ */
15
+ export interface DialogMediatorProps {
16
+ /**
17
+ * Children to provide the dialog mediator to.
18
+ */
19
+ children?: JSX.Element | JSX.Element[];
20
+
21
+ /**
22
+ * The dialog mediator context.
23
+ */
24
+ handler: IDialogMediatorHandler;
25
+
26
+ /**
27
+ * Parent handler, if any.
28
+ */
29
+ parentHandler?: IDialogMediatorHandler;
30
+ }
31
+
32
+ /**
33
+ * Use the dialog mediator.
34
+ * @returns The dialog mediator.
35
+ */
36
+ export const useDialogMediator = () => {
37
+ return React.useContext(DialogMediatorContext);
38
+ };
39
+
40
+ /**
41
+ * Provide the dialog mediator to the children.
42
+ * @param {DialogMediatorProps} props Props for the dialog mediator.
43
+ * @returns Provider for the dialog mediator.
44
+ */
45
+ export const DialogMediator = (props: DialogMediatorProps) => {
46
+ return (
47
+ <DialogMediatorContext.Provider value={props.handler}>
48
+ {props.children}
49
+ </DialogMediatorContext.Provider>
50
+ );
51
+ };
@@ -0,0 +1,67 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { Constructor } from '@cratis/fundamentals';
5
+ import { CloseDialog, DialogResponse } from '@cratis/arc.react/dialogs';
6
+ import { IDialogMediatorHandler } from './IDialogMediatorHandler';
7
+ import { DialogRegistration, DialogRequest } from './DialogRegistration';
8
+
9
+ /**
10
+ * Represents an implementation of {@link IDialogMediatorHandler}
11
+ */
12
+ export class DialogMediatorHandler extends IDialogMediatorHandler {
13
+ private _registrations: WeakMap<Constructor, DialogRegistration<object, object>> = new WeakMap();
14
+
15
+ /**
16
+ * Initializes a new instance of {@link DialogMediatorHandler}
17
+ * @param {IDialogMediatorHandler} _parent Optional parent handler.
18
+ */
19
+ constructor(readonly _parent: IDialogMediatorHandler | null = null) {
20
+ super();
21
+ }
22
+
23
+ /** @inheritdoc */
24
+ subscribe<TRequest extends object, TResponse>(requestType: Constructor<TRequest>, requester: DialogRequest<TRequest, TResponse>, closeDialog: CloseDialog<TResponse>): void {
25
+ this._registrations.set(
26
+ requestType,
27
+ new DialogRegistration<TRequest, TResponse>(requester, closeDialog) as unknown as DialogRegistration<object, object>);
28
+ }
29
+
30
+ /** @inheritdoc */
31
+ hasSubscriber<TRequest extends object>(requestType: Constructor<TRequest>): boolean {
32
+ return this._registrations.has(requestType);
33
+ }
34
+
35
+ /** @inheritdoc */
36
+ show<TRequest extends object, TResponse>(request: TRequest): Promise<DialogResponse<TResponse>> {
37
+ if (!this.hasSubscriber(request.constructor as Constructor)) {
38
+ if (this._parent) {
39
+ return this._parent.show(request);
40
+ }
41
+
42
+ return Promise.reject('No registration found for request');
43
+ }
44
+
45
+ const promise = new Promise<DialogResponse<TResponse>>((resolve) => {
46
+ const registration = this._registrations.get(request.constructor as Constructor)!;
47
+ registration.requester(request, (result, response) => {
48
+ resolve([result, response as TResponse]);
49
+ });
50
+ });
51
+
52
+ return promise;
53
+ }
54
+
55
+ /** @inheritdoc */
56
+ getRegistration<TRequest extends object, TResponse>(requestType: Constructor<TRequest>): DialogRegistration<TRequest, TResponse> {
57
+ if (!this.hasSubscriber(requestType)) {
58
+ if (this._parent) {
59
+ return this._parent.getRegistration(requestType);
60
+ }
61
+
62
+ throw new Error('No registration found for request');
63
+ }
64
+
65
+ return this._registrations.get(requestType)! as unknown as DialogRegistration<TRequest, TResponse>;
66
+ }
67
+ }
@@ -0,0 +1,25 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { CloseDialog } from '@cratis/arc.react/dialogs';
5
+
6
+ /**
7
+ * Represents the delegate for a dialog request.
8
+ */
9
+ export type DialogRequest<TRequest extends object, TResponse> = (request: TRequest, closeDialog: CloseDialog<TResponse>) => void;
10
+
11
+ /**
12
+ * Represents the registration of a dialog.
13
+ */
14
+ export class DialogRegistration<TRequest extends object, TResponse> {
15
+
16
+ /**
17
+ * Initializes a new instance of {@link DialogRegistration}.
18
+ * @param requester The requester for the dialog.
19
+ * @param resolver The resolver for the dialog.
20
+ */
21
+ constructor(
22
+ readonly requester: DialogRequest<TRequest, TResponse>,
23
+ readonly resolver: CloseDialog<TResponse>) {
24
+ }
25
+ }
@@ -0,0 +1,58 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { DialogResponse, DialogResult, IDialogComponents, ConfirmationDialogRequest, BusyIndicatorDialogRequest, CloseDialog } from '@cratis/arc.react/dialogs';
5
+ import { DialogButtons } from '@cratis/arc.react/dialogs/DialogButtons';
6
+ import { IDialogs } from './IDialogs';
7
+ import { BusyIndicator } from './BusyIndicator';
8
+ import { IDialogMediatorHandler } from './IDialogMediatorHandler';
9
+
10
+ /**
11
+ * Represents an implementation of {@link IDialogs}.
12
+ */
13
+ export class Dialogs extends IDialogs {
14
+
15
+ /**
16
+ * Initializes a new instance of the {@link Dialogs} class.
17
+ */
18
+ constructor(
19
+ private readonly _dialogMediatorHandler: IDialogMediatorHandler,
20
+ dialogComponents: IDialogComponents) {
21
+ super();
22
+
23
+ /* eslint-disable @typescript-eslint/no-empty-function */
24
+ _dialogMediatorHandler.subscribe(ConfirmationDialogRequest, async (request, resolver) => {
25
+ const [result] = await dialogComponents.showConfirmation(request as ConfirmationDialogRequest);
26
+ resolver(result);
27
+ }, () => { });
28
+ /* eslint-enable @typescript-eslint/no-empty-function */
29
+
30
+ let busyIndicatorResolver: CloseDialog<void> | undefined = undefined;
31
+
32
+ _dialogMediatorHandler.subscribe(BusyIndicatorDialogRequest, (request, resolver) => {
33
+ busyIndicatorResolver = resolver;
34
+ return dialogComponents.showBusyIndicator(request as BusyIndicatorDialogRequest);
35
+ }, () => {
36
+ busyIndicatorResolver?.(DialogResult.Cancelled, undefined);
37
+ });
38
+ }
39
+
40
+ /** @inheritdoc */
41
+ show<TRequest extends object, TResponse = object>(request: TRequest): Promise<DialogResponse<TResponse>> {
42
+ return this._dialogMediatorHandler.show<TRequest, TResponse>(request);
43
+ }
44
+
45
+ /** @inheritdoc */
46
+ async showConfirmation(title: string, message: string, buttons: DialogButtons): Promise<DialogResult> {
47
+ const [result] = await this.show<ConfirmationDialogRequest>(new ConfirmationDialogRequest(title, message, buttons));
48
+ return result;
49
+ }
50
+
51
+ /** @inheritdoc */
52
+ showBusyIndicator(title: string, message: string): BusyIndicator {
53
+ this.show<BusyIndicatorDialogRequest, void>(new BusyIndicatorDialogRequest(title, message));
54
+ const registration = this._dialogMediatorHandler.getRegistration<BusyIndicatorDialogRequest, void>(BusyIndicatorDialogRequest);
55
+ const busyIndicator = new BusyIndicator(registration.resolver);
56
+ return busyIndicator;
57
+ }
58
+ }
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { Constructor } from '@cratis/fundamentals';
5
+ import { CloseDialog, DialogResponse } from '@cratis/arc.react/dialogs';
6
+ import { DialogRegistration, DialogRequest } from './DialogRegistration';
7
+
8
+ /**
9
+ * Defines a system that can handle dialog requests and responses.
10
+ */
11
+ export abstract class IDialogMediatorHandler {
12
+
13
+ /**
14
+ * Subscribes to a request type.
15
+ * @param {Constructor} requestType Type of request.
16
+ * @param {DialogRequest} requester The delegate that will be called when a request is made.
17
+ * @param {CloseDialog} closeDialog The delegate that will be called when dialog is typically closed and response is resolved.
18
+ */
19
+ abstract subscribe<TRequest extends object, TResponse>(requestType: Constructor<TRequest>, requester: DialogRequest<TRequest, TResponse>, closeDialog: CloseDialog<TResponse>): void;
20
+
21
+ /**
22
+ * Check if there is a subscriber for a given request type.
23
+ * @param {Constructor} requestType Type of request.
24
+ * @returns {boolean} True if there is a subscriber, false otherwise.
25
+ */
26
+ abstract hasSubscriber<TRequest extends object>(requestType: Constructor<TRequest>): boolean;
27
+
28
+ /**
29
+ * Show a dialog based on a request.
30
+ * @param {*} request An instance of the dialog request.
31
+ */
32
+ abstract show<TRequest extends object, TResponse>(request: TRequest): Promise<DialogResponse<TResponse>>;
33
+
34
+ /**
35
+ * Get the registration for a given request type.
36
+ * @param {Constructor} requestType Type of request.
37
+ * @returns {DialogRegistration} The registration for the request type.
38
+ */
39
+ abstract getRegistration<TRequest extends object, TResponse>(requestType: Constructor<TRequest>): DialogRegistration<TRequest, TResponse>;
40
+ }
@@ -0,0 +1,37 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { DialogResponse, DialogResult } from '@cratis/arc.react/dialogs';
5
+ import { DialogButtons } from '@cratis/arc.react/dialogs/DialogButtons';
6
+ import { BusyIndicator } from './BusyIndicator';
7
+
8
+ /**
9
+ * Defines a service for working with dialogs from a view model.
10
+ */
11
+ export abstract class IDialogs {
12
+ /**
13
+ * Show a dialog in the context of the current view and view model. This requires the view to host the dialog.
14
+ * @param {*} input The input to pass to the dialog.
15
+ * @returns {Promise<*>} The output from the dialog.
16
+ */
17
+ abstract show<TRequest extends object, TResponse = object>(input: TRequest): Promise<DialogResponse<TResponse>>;
18
+
19
+ /**
20
+ * Show a standard confirmation dialog.
21
+ * @param {String} title Title of the dialog.
22
+ * @param {String} message Message to show inside the dialog.
23
+ * @param {DialogButtons} buttons Buttons to have on the dialog
24
+ * @returns {Promise<DialogResult>} The result of the dialog.
25
+ */
26
+ abstract showConfirmation(title: string, message: string, buttons: DialogButtons): Promise<DialogResult>;
27
+
28
+ /**
29
+ * Show a standard busy indicator dialog.
30
+ * @param {String} title Title of the dialog.
31
+ * @param {String} message Message to show inside the dialog.
32
+ * @returns {BusyIndicator} The busy indicator instance.
33
+ */
34
+ abstract showBusyIndicator(title: string, message: string): BusyIndicator;
35
+ }
36
+
37
+
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ export * from './BusyIndicator';
5
+ export * from './DialogMediator';
6
+ export * from './DialogMediatorHandler';
7
+ export * from './DialogRegistration';
8
+ export * from './Dialogs';
9
+ export * from './IDialogMediatorHandler';
10
+ export * from './IDialogs';
11
+ export * from './Dialogs';
12
+ export * from './useDialog';
@@ -0,0 +1,34 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { useEffect, ComponentType, FC, useCallback } from 'react';
5
+ import { Constructor } from '@cratis/fundamentals';
6
+ import { DialogResult, ShowDialog, useDialog as useDialogBase } from '@cratis/arc.react/dialogs';
7
+ import { useDialogMediator } from './DialogMediator';
8
+
9
+ /**
10
+ * Use a dialog request for showing a dialog, similar to useDialog.
11
+ * @param requestType Type of request to use that represents a request that will be made by your view model.
12
+ * @param DialogComponent The dialog component to render.
13
+ * @returns A tuple with a component to use for rendering the dialog.
14
+ */
15
+ export function useDialog<TProps extends object = object, TResponse = object>(
16
+ requestType: Constructor<TProps>,
17
+ DialogComponent: ComponentType<TProps>
18
+ ): [FC<TProps>, ShowDialog<TProps, TResponse>] {
19
+ const mediator = useDialogMediator();
20
+ const [DialogWrapper, showDialog, actualDialogContext] = useDialogBase<TResponse, TProps>(DialogComponent);
21
+
22
+ const closeDialog = useCallback((result: DialogResult, value?: TResponse) => {
23
+ actualDialogContext.closeDialog(result, value as TResponse);
24
+ }, []);
25
+
26
+ useEffect(() => {
27
+ mediator.subscribe(requestType, async (request, resolver) => {
28
+ const [result, response] = await showDialog(request as unknown as TProps);
29
+ resolver(result, response);
30
+ }, closeDialog);
31
+ }, []);
32
+
33
+ return [DialogWrapper, showDialog];
34
+ }
@@ -0,0 +1,4 @@
1
+ export declare class Bindings {
2
+ static initialize(): void;
3
+ }
4
+ //# sourceMappingURL=Bindings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bindings.d.ts","sourceRoot":"","sources":["../../Bindings.ts"],"names":[],"mappings":"AASA,qBAAa,QAAQ;IACjB,MAAM,CAAC,UAAU;CAMpB"}
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ var tsyringe = require('tsyringe');
4
+ var IMessenger = require('./messaging/IMessenger.js');
5
+ var Messenger = require('./messaging/Messenger.js');
6
+ var INavigation = require('./browser/INavigation.js');
7
+ var Navigation = require('./browser/Navigation.js');
8
+ var ILocalStorage = require('./browser/ILocalStorage.js');
9
+ var identity = require('@cratis/arc/identity');
10
+
11
+ class Bindings {
12
+ static initialize() {
13
+ tsyringe.container.registerSingleton(IMessenger.IMessenger, Messenger.Messenger);
14
+ tsyringe.container.registerSingleton(INavigation.INavigation, Navigation.Navigation);
15
+ tsyringe.container.registerSingleton(identity.IIdentityProvider, identity.IdentityProvider);
16
+ tsyringe.container.registerInstance(ILocalStorage.ILocalStorage, localStorage);
17
+ }
18
+ }
19
+
20
+ exports.Bindings = Bindings;
21
+ //# sourceMappingURL=Bindings.js.map