keycloakify 10.0.0-rc.22 → 10.0.0-rc.24

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 (236) hide show
  1. package/PUBLIC_URL.d.ts +1 -1
  2. package/PUBLIC_URL.js +1 -1
  3. package/PUBLIC_URL.js.map +1 -1
  4. package/account/Fallback.js.map +1 -1
  5. package/account/Template.js +3 -3
  6. package/account/Template.js.map +1 -1
  7. package/account/i18n/baseMessages/index.js.map +1 -1
  8. package/account/i18n/i18n.js.map +1 -1
  9. package/account/index.d.ts +2 -2
  10. package/account/index.js +1 -2
  11. package/account/index.js.map +1 -1
  12. package/account/kcContext/KcContext.d.ts +12 -0
  13. package/account/kcContext/KcContext.js.map +1 -1
  14. package/account/kcContext/getKcContextMock.d.ts +24 -0
  15. package/account/kcContext/getKcContextMock.js +28 -0
  16. package/account/kcContext/getKcContextMock.js.map +1 -0
  17. package/account/kcContext/index.d.ts +2 -1
  18. package/account/kcContext/index.js +1 -1
  19. package/account/kcContext/index.js.map +1 -1
  20. package/account/kcContext/kcContextMocks.js +23 -91
  21. package/account/kcContext/kcContextMocks.js.map +1 -1
  22. package/account/pages/Account.js +1 -1
  23. package/account/pages/Account.js.map +1 -1
  24. package/account/pages/Applications.js +2 -2
  25. package/account/pages/Applications.js.map +1 -1
  26. package/account/pages/FederatedIdentity.js +1 -1
  27. package/account/pages/FederatedIdentity.js.map +1 -1
  28. package/account/pages/Log.js +1 -1
  29. package/account/pages/Log.js.map +1 -1
  30. package/account/pages/Password.js +6 -4
  31. package/account/pages/Password.js.map +1 -1
  32. package/account/pages/Sessions.js +1 -1
  33. package/account/pages/Sessions.js.map +1 -1
  34. package/account/pages/Totp.js +1 -1
  35. package/account/pages/Totp.js.map +1 -1
  36. package/bin/main.js +174 -162
  37. package/lib/BASE_URL.js.map +1 -1
  38. package/login/Fallback.js.map +1 -1
  39. package/login/Template.js +7 -7
  40. package/login/Template.js.map +1 -1
  41. package/login/UserProfileFormFields.js +24 -68
  42. package/login/UserProfileFormFields.js.map +1 -1
  43. package/login/i18n/baseMessages/index.js.map +1 -1
  44. package/login/i18n/i18n.d.ts +1 -1
  45. package/login/i18n/i18n.js +1 -1
  46. package/login/i18n/i18n.js.map +1 -1
  47. package/login/index.d.ts +2 -3
  48. package/login/index.js +1 -2
  49. package/login/index.js.map +1 -1
  50. package/login/kcContext/KcContext.d.ts +23 -13
  51. package/login/kcContext/KcContext.js.map +1 -1
  52. package/login/kcContext/getKcContextMock.d.ts +24 -0
  53. package/login/kcContext/getKcContextMock.js +28 -0
  54. package/login/kcContext/getKcContextMock.js.map +1 -0
  55. package/login/kcContext/index.d.ts +2 -1
  56. package/login/kcContext/index.js +1 -1
  57. package/login/kcContext/index.js.map +1 -1
  58. package/login/kcContext/kcContextMocks.js +29 -103
  59. package/login/kcContext/kcContextMocks.js.map +1 -1
  60. package/login/lib/useDownloadTerms.js +8 -14
  61. package/login/lib/useDownloadTerms.js.map +1 -1
  62. package/login/lib/useGetClassName.js +1 -1
  63. package/login/lib/useGetClassName.js.map +1 -1
  64. package/login/lib/useUserProfileForm.d.ts +9 -1
  65. package/login/lib/useUserProfileForm.js +94 -15
  66. package/login/lib/useUserProfileForm.js.map +1 -1
  67. package/login/pages/Code.js +1 -1
  68. package/login/pages/Code.js.map +1 -1
  69. package/login/pages/DeleteAccountConfirm.js +2 -2
  70. package/login/pages/DeleteAccountConfirm.js.map +1 -1
  71. package/login/pages/DeleteCredential.js +1 -1
  72. package/login/pages/DeleteCredential.js.map +1 -1
  73. package/login/pages/Error.js +1 -1
  74. package/login/pages/Error.js.map +1 -1
  75. package/login/pages/FrontchannelLogout.js +1 -1
  76. package/login/pages/FrontchannelLogout.js.map +1 -1
  77. package/login/pages/IdpReviewUserProfile.js +1 -1
  78. package/login/pages/IdpReviewUserProfile.js.map +1 -1
  79. package/login/pages/Info.js +5 -5
  80. package/login/pages/Info.js.map +1 -1
  81. package/login/pages/Login.js +4 -4
  82. package/login/pages/Login.js.map +1 -1
  83. package/login/pages/LoginConfigTotp.js +2 -2
  84. package/login/pages/LoginConfigTotp.js.map +1 -1
  85. package/login/pages/LoginIdpLinkConfirm.js +1 -1
  86. package/login/pages/LoginIdpLinkConfirm.js.map +1 -1
  87. package/login/pages/LoginIdpLinkEmail.js +1 -1
  88. package/login/pages/LoginIdpLinkEmail.js.map +1 -1
  89. package/login/pages/LoginOauth2DeviceVerifyUserCode.js +1 -1
  90. package/login/pages/LoginOauth2DeviceVerifyUserCode.js.map +1 -1
  91. package/login/pages/LoginOauthGrant.js +2 -2
  92. package/login/pages/LoginOauthGrant.js.map +1 -1
  93. package/login/pages/LoginOtp.js +1 -1
  94. package/login/pages/LoginOtp.js.map +1 -1
  95. package/login/pages/LoginPageExpired.js +1 -1
  96. package/login/pages/LoginPageExpired.js.map +1 -1
  97. package/login/pages/LoginPassword.js +3 -3
  98. package/login/pages/LoginPassword.js.map +1 -1
  99. package/login/pages/LoginRecoveryAuthnCodeConfig.js +10 -10
  100. package/login/pages/LoginRecoveryAuthnCodeConfig.js.map +1 -1
  101. package/login/pages/LoginRecoveryAuthnCodeInput.js +1 -1
  102. package/login/pages/LoginRecoveryAuthnCodeInput.js.map +1 -1
  103. package/login/pages/LoginResetOtp.js +1 -1
  104. package/login/pages/LoginResetOtp.js.map +1 -1
  105. package/login/pages/LoginResetPassword.js +2 -2
  106. package/login/pages/LoginResetPassword.js.map +1 -1
  107. package/login/pages/LoginUpdatePassword.js +3 -3
  108. package/login/pages/LoginUpdatePassword.js.map +1 -1
  109. package/login/pages/LoginUpdateProfile.js +4 -2
  110. package/login/pages/LoginUpdateProfile.js.map +1 -1
  111. package/login/pages/LoginUsername.js +3 -3
  112. package/login/pages/LoginUsername.js.map +1 -1
  113. package/login/pages/LoginVerifyEmail.js +1 -1
  114. package/login/pages/LoginVerifyEmail.js.map +1 -1
  115. package/login/pages/LoginX509Info.js +1 -1
  116. package/login/pages/LoginX509Info.js.map +1 -1
  117. package/login/pages/LogoutConfirm.js +1 -1
  118. package/login/pages/LogoutConfirm.js.map +1 -1
  119. package/login/pages/Register.js +8 -4
  120. package/login/pages/Register.js.map +1 -1
  121. package/login/pages/SamlPostForm.js +1 -1
  122. package/login/pages/SamlPostForm.js.map +1 -1
  123. package/login/pages/SelectAuthenticator.js +2 -2
  124. package/login/pages/SelectAuthenticator.js.map +1 -1
  125. package/login/pages/Terms.js +1 -1
  126. package/login/pages/Terms.js.map +1 -1
  127. package/login/pages/UpdateEmail.js +5 -3
  128. package/login/pages/UpdateEmail.js.map +1 -1
  129. package/login/pages/WebauthnAuthenticate.js +8 -8
  130. package/login/pages/WebauthnAuthenticate.js.map +1 -1
  131. package/login/pages/WebauthnError.js +2 -2
  132. package/login/pages/WebauthnError.js.map +1 -1
  133. package/login/pages/WebauthnRegister.js +5 -5
  134. package/login/pages/WebauthnRegister.js.map +1 -1
  135. package/package.json +26 -38
  136. package/src/PUBLIC_URL.ts +1 -1
  137. package/src/account/Template.tsx +2 -3
  138. package/src/account/index.ts +2 -2
  139. package/src/account/kcContext/KcContext.ts +19 -1
  140. package/src/account/kcContext/getKcContextMock.ts +80 -0
  141. package/src/account/kcContext/index.ts +2 -1
  142. package/src/account/kcContext/kcContextMocks.ts +26 -91
  143. package/src/bin/copy-keycloak-resources-to-public.ts +1 -4
  144. package/src/bin/keycloakify/generateFtl/ftl_object_to_js_code_declaring_an_object.ftl +19 -11
  145. package/src/bin/start-keycloak/start-keycloak.ts +18 -5
  146. package/src/bin/tools/getNpmWorkspaceRootDirPath.ts +25 -25
  147. package/src/login/Template.tsx +4 -5
  148. package/src/login/UserProfileFormFields.tsx +28 -80
  149. package/src/login/i18n/i18n.tsx +3 -3
  150. package/src/login/index.ts +6 -3
  151. package/src/login/kcContext/KcContext.ts +43 -31
  152. package/src/login/kcContext/getKcContextMock.ts +80 -0
  153. package/src/login/kcContext/index.ts +7 -1
  154. package/src/login/kcContext/kcContextMocks.ts +92 -165
  155. package/src/login/lib/useDownloadTerms.ts +10 -24
  156. package/src/login/lib/useGetClassName.ts +1 -1
  157. package/src/login/lib/useUserProfileForm.tsx +117 -13
  158. package/src/login/pages/LoginConfigTotp.tsx +1 -1
  159. package/src/login/pages/LoginRecoveryAuthnCodeConfig.tsx +7 -8
  160. package/src/login/pages/WebauthnAuthenticate.tsx +2 -3
  161. package/src/login/pages/WebauthnRegister.tsx +2 -3
  162. package/src/tools/ExtractAfterStartingWith.ts +4 -0
  163. package/src/tools/StatefulObservable/hooks/useRerenderOnChange.ts +4 -4
  164. package/src/tools/ValueOf.ts +2 -0
  165. package/src/tools/deepAssign.ts +51 -20
  166. package/src/tools/structuredCloneButFunctions.ts +24 -0
  167. package/src/tools/useInsertLinkTags.ts +78 -87
  168. package/src/tools/useInsertScriptTags.ts +69 -78
  169. package/src/tools/useOnFirstMount.ts +18 -0
  170. package/tools/Array.prototype.every.js.map +1 -1
  171. package/tools/ExtractAfterStartingWith.d.ts +1 -0
  172. package/tools/ExtractAfterStartingWith.js +2 -0
  173. package/tools/ExtractAfterStartingWith.js.map +1 -0
  174. package/tools/HTMLElement.prototype.prepend.js.map +1 -1
  175. package/tools/StatefulObservable/StatefulObservable.js.map +1 -1
  176. package/tools/StatefulObservable/hooks/useRerenderOnChange.d.ts +1 -1
  177. package/tools/StatefulObservable/hooks/useRerenderOnChange.js +4 -4
  178. package/tools/StatefulObservable/hooks/useRerenderOnChange.js.map +1 -1
  179. package/tools/ValueOf.d.ts +2 -0
  180. package/tools/ValueOf.js +2 -0
  181. package/tools/ValueOf.js.map +1 -0
  182. package/tools/clsx.js.map +1 -1
  183. package/tools/deepAssign.d.ts +1 -0
  184. package/tools/deepAssign.js +39 -16
  185. package/tools/deepAssign.js.map +1 -1
  186. package/tools/formatNumber.js.map +1 -1
  187. package/tools/structuredCloneButFunctions.d.ts +7 -0
  188. package/tools/structuredCloneButFunctions.js +19 -0
  189. package/tools/structuredCloneButFunctions.js.map +1 -0
  190. package/tools/useInsertLinkTags.d.ts +11 -6
  191. package/tools/useInsertLinkTags.js +53 -53
  192. package/tools/useInsertLinkTags.js.map +1 -1
  193. package/tools/useInsertScriptTags.d.ts +15 -6
  194. package/tools/useInsertScriptTags.js +56 -64
  195. package/tools/useInsertScriptTags.js.map +1 -1
  196. package/tools/useOnFirstMount.d.ts +2 -0
  197. package/tools/useOnFirstMount.js +15 -0
  198. package/tools/useOnFirstMount.js.map +1 -0
  199. package/tools/useSetClassName.js.map +1 -1
  200. package/vite-plugin/index.js +66 -64
  201. package/account/kcContext/createGetKcContext.d.ts +0 -19
  202. package/account/kcContext/createGetKcContext.js +0 -78
  203. package/account/kcContext/createGetKcContext.js.map +0 -1
  204. package/account/kcContext/getKcContext.d.ts +0 -13
  205. package/account/kcContext/getKcContext.js +0 -13
  206. package/account/kcContext/getKcContext.js.map +0 -1
  207. package/account/kcContext/getKcContextFromWindow.d.ts +0 -10
  208. package/account/kcContext/getKcContextFromWindow.js +0 -5
  209. package/account/kcContext/getKcContextFromWindow.js.map +0 -1
  210. package/login/kcContext/createGetKcContext.d.ts +0 -19
  211. package/login/kcContext/createGetKcContext.js +0 -117
  212. package/login/kcContext/createGetKcContext.js.map +0 -1
  213. package/login/kcContext/getKcContext.d.ts +0 -13
  214. package/login/kcContext/getKcContext.js +0 -13
  215. package/login/kcContext/getKcContext.js.map +0 -1
  216. package/login/kcContext/getKcContextFromWindow.d.ts +0 -10
  217. package/login/kcContext/getKcContextFromWindow.js +0 -5
  218. package/login/kcContext/getKcContextFromWindow.js.map +0 -1
  219. package/src/account/kcContext/createGetKcContext.ts +0 -134
  220. package/src/account/kcContext/getKcContext.ts +0 -23
  221. package/src/account/kcContext/getKcContextFromWindow.ts +0 -15
  222. package/src/login/kcContext/createGetKcContext.ts +0 -206
  223. package/src/login/kcContext/getKcContext.ts +0 -23
  224. package/src/login/kcContext/getKcContextFromWindow.ts +0 -15
  225. package/src/tools/AndByDiscriminatingKey.ts +0 -31
  226. package/src/tools/deepClone.ts +0 -19
  227. package/src/tools/memoize.ts +0 -55
  228. package/tools/AndByDiscriminatingKey.d.ts +0 -5
  229. package/tools/AndByDiscriminatingKey.js +0 -2
  230. package/tools/AndByDiscriminatingKey.js.map +0 -1
  231. package/tools/deepClone.d.ts +0 -2
  232. package/tools/deepClone.js +0 -14
  233. package/tools/deepClone.js.map +0 -1
  234. package/tools/memoize.d.ts +0 -7
  235. package/tools/memoize.js +0 -38
  236. package/tools/memoize.js.map +0 -1
@@ -3,12 +3,10 @@ import { clsx } from "keycloakify/tools/clsx";
3
3
  import type { PageProps } from "keycloakify/login/pages/PageProps";
4
4
  import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
5
5
  import { assert } from "tsafe/assert";
6
- import { createUseInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
6
+ import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
7
7
  import type { KcContext } from "../kcContext";
8
8
  import type { I18n } from "../i18n";
9
9
 
10
- const { useInsertScriptTags } = createUseInsertScriptTags();
11
-
12
10
  export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext, { pageId: "webauthn-authenticate.ftl" }>, I18n>) {
13
11
  const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
14
12
 
@@ -31,6 +29,7 @@ export default function WebauthnAuthenticate(props: PageProps<Extract<KcContext,
31
29
  const { msg, msgStr, advancedMsg } = i18n;
32
30
 
33
31
  const { insertScriptTags } = useInsertScriptTags({
32
+ componentOrHookName: "WebauthnAuthenticate",
34
33
  scriptTags: [
35
34
  {
36
35
  type: "text/javascript",
@@ -3,12 +3,10 @@ import { clsx } from "keycloakify/tools/clsx";
3
3
  import type { PageProps } from "keycloakify/login/pages/PageProps";
4
4
  import { useGetClassName } from "keycloakify/login/lib/useGetClassName";
5
5
  import { assert } from "tsafe/assert";
6
- import { createUseInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
6
+ import { useInsertScriptTags } from "keycloakify/tools/useInsertScriptTags";
7
7
  import type { KcContext } from "../kcContext";
8
8
  import type { I18n } from "../i18n";
9
9
 
10
- const { useInsertScriptTags } = createUseInsertScriptTags();
11
-
12
10
  export default function WebauthnRegister(props: PageProps<Extract<KcContext, { pageId: "webauthn-register.ftl" }>, I18n>) {
13
11
  const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
14
12
 
@@ -35,6 +33,7 @@ export default function WebauthnRegister(props: PageProps<Extract<KcContext, { p
35
33
  const { msg, msgStr } = i18n;
36
34
 
37
35
  const { insertScriptTags } = useInsertScriptTags({
36
+ componentOrHookName: "WebauthnRegister",
38
37
  scriptTags: [
39
38
  {
40
39
  type: "text/javascript",
@@ -0,0 +1,4 @@
1
+ export type ExtractAfterStartingWith<
2
+ Prefix extends string,
3
+ StrEnum
4
+ > = StrEnum extends `${Prefix}${infer U}` ? U : never;
@@ -5,15 +5,15 @@ import type { StatefulObservable } from "../StatefulObservable";
5
5
  /**
6
6
  * Equivalent of https://docs.evt.land/api/react-hooks
7
7
  * */
8
- export function useRerenderOnChange($: StatefulObservable<unknown>): void {
8
+ export function useRerenderOnChange(obs: StatefulObservable<unknown>): void {
9
9
  //NOTE: We use function in case the state is a function
10
- const [, setCurrent] = useState(() => $.current);
10
+ const [, setCurrent] = useState(() => obs.current);
11
11
 
12
12
  useObservable(
13
13
  ({ registerSubscription }) => {
14
- const subscription = $.subscribe(current => setCurrent(() => current));
14
+ const subscription = obs.subscribe(current => setCurrent(() => current));
15
15
  registerSubscription(subscription);
16
16
  },
17
- [$]
17
+ [obs]
18
18
  );
19
19
  }
@@ -0,0 +1,2 @@
1
+ /** Pendant of `keyof T` */
2
+ export type ValueOf<T> = T[keyof T];
@@ -1,45 +1,61 @@
1
1
  import { assert } from "tsafe/assert";
2
2
  import { is } from "tsafe/is";
3
- import { deepClone } from "./deepClone";
3
+ import { structuredCloneButFunctions } from "./structuredCloneButFunctions";
4
4
 
5
- //Warning: Be mindful that because of array this is not idempotent.
5
+ /** NOTE: Array a copied over, not merged. */
6
6
  export function deepAssign(params: {
7
7
  target: Record<string, unknown>;
8
8
  source: Record<string, unknown>;
9
- }) {
10
- const { target } = params;
11
-
12
- const source = deepClone(params.source);
9
+ }): void {
10
+ const { target, source } = params;
13
11
 
14
12
  Object.keys(source).forEach(key => {
15
13
  var dereferencedSource = source[key];
16
14
 
15
+ if (dereferencedSource === undefined) {
16
+ delete target[key];
17
+ return;
18
+ }
19
+
20
+ if (dereferencedSource instanceof Date) {
21
+ assign({
22
+ target,
23
+ key,
24
+ value: new Date(dereferencedSource.getTime())
25
+ });
26
+
27
+ return;
28
+ }
29
+
30
+ if (dereferencedSource instanceof Array) {
31
+ assign({
32
+ target,
33
+ key,
34
+ value: structuredCloneButFunctions(dereferencedSource)
35
+ });
36
+
37
+ return;
38
+ }
39
+
17
40
  if (
18
- target[key] === undefined ||
19
41
  dereferencedSource instanceof Function ||
20
42
  !(dereferencedSource instanceof Object)
21
43
  ) {
22
- Object.defineProperty(target, key, {
23
- enumerable: true,
24
- writable: true,
25
- configurable: true,
44
+ assign({
45
+ target,
46
+ key,
26
47
  value: dereferencedSource
27
48
  });
28
49
 
29
50
  return;
30
51
  }
31
52
 
32
- const dereferencedTarget = target[key];
33
-
34
- if (dereferencedSource instanceof Array) {
35
- assert(is<unknown[]>(dereferencedTarget));
36
- assert(is<unknown[]>(dereferencedSource));
37
-
38
- dereferencedSource.forEach(entry => dereferencedTarget.push(entry));
39
-
40
- return;
53
+ if (!(target[key] instanceof Object)) {
54
+ target[key] = {};
41
55
  }
42
56
 
57
+ const dereferencedTarget = target[key];
58
+
43
59
  assert(is<Record<string, unknown>>(dereferencedTarget));
44
60
  assert(is<Record<string, unknown>>(dereferencedSource));
45
61
 
@@ -49,3 +65,18 @@ export function deepAssign(params: {
49
65
  });
50
66
  });
51
67
  }
68
+
69
+ function assign(params: {
70
+ target: Record<string, unknown>;
71
+ key: string;
72
+ value: unknown;
73
+ }): void {
74
+ const { target, key, value } = params;
75
+
76
+ Object.defineProperty(target, key, {
77
+ enumerable: true,
78
+ writable: true,
79
+ configurable: true,
80
+ value
81
+ });
82
+ }
@@ -0,0 +1,24 @@
1
+ import "minimal-polyfills/Object.fromEntries";
2
+
3
+ /**
4
+ * Functionally equivalent to structuredClone but
5
+ * functions are not cloned but kept as is.
6
+ * (as opposed to structuredClone that chokes if it encounters a function)
7
+ */
8
+ export function structuredCloneButFunctions<T>(o: T): T {
9
+ if (!(o instanceof Object)) {
10
+ return o;
11
+ }
12
+
13
+ if (typeof o === "function") {
14
+ return o;
15
+ }
16
+
17
+ if (o instanceof Array) {
18
+ return o.map(structuredCloneButFunctions) as any;
19
+ }
20
+
21
+ return Object.fromEntries(
22
+ Object.entries(o).map(([key, value]) => [key, structuredCloneButFunctions(value)])
23
+ ) as any;
24
+ }
@@ -1,95 +1,86 @@
1
- import { useReducer, useEffect } from "react";
2
-
3
- export function createUseInsertLinkTags() {
4
- let linkTagsContext:
5
- | {
6
- styleSheetHrefs: string[];
7
- prAreAllStyleSheetsLoaded: Promise<void>;
8
- remove: () => void;
9
- }
10
- | undefined = undefined;
11
-
12
- /** NOTE: The hrefs can't changes. There should be only one one call on this. */
13
- function useInsertLinkTags(params: { hrefs: string[] }) {
14
- const { hrefs } = params;
15
-
16
- const [areAllStyleSheetsLoaded, setAllStyleSheetLoaded] = useReducer(
17
- () => true,
18
- hrefs.length === 0
19
- );
20
-
21
- useEffect(() => {
22
- let isActive = true;
23
-
24
- mount_link_tags: {
25
- if (linkTagsContext !== undefined) {
26
- if (
27
- JSON.stringify(linkTagsContext.styleSheetHrefs) ===
28
- JSON.stringify(hrefs)
29
- ) {
30
- break mount_link_tags;
31
- }
32
-
33
- linkTagsContext.remove();
34
-
35
- linkTagsContext = undefined;
1
+ import { useEffect, useReducer } from "react";
2
+ import { useConst } from "keycloakify/tools/useConst";
3
+ import { id } from "tsafe/id";
4
+ import { useOnFistMount } from "keycloakify/tools/useOnFirstMount";
5
+
6
+ const alreadyMountedComponentOrHookNames = new Set<string>();
7
+
8
+ /**
9
+ * NOTE: The component that use this hook can only be mounded once!
10
+ * And can't rerender with different hrefs.
11
+ * If it's mounted again the page will be reloaded.
12
+ * This simulates the behavior of a server rendered page that imports css stylesheet in the head.
13
+ */
14
+ export function useInsertLinkTags(params: {
15
+ componentOrHookName: string;
16
+ hrefs: string[];
17
+ }) {
18
+ const { hrefs, componentOrHookName } = params;
19
+
20
+ useOnFistMount(() => {
21
+ const isAlreadyMounted =
22
+ alreadyMountedComponentOrHookNames.has(componentOrHookName);
23
+
24
+ if (isAlreadyMounted) {
25
+ window.location.reload();
26
+ return;
27
+ }
28
+
29
+ alreadyMountedComponentOrHookNames.add(componentOrHookName);
30
+ });
31
+
32
+ const [areAllStyleSheetsLoaded, setAllStyleSheetsLoaded] = useReducer(
33
+ () => true,
34
+ false
35
+ );
36
+
37
+ const refPrAllStyleSheetLoaded = useConst(() => ({
38
+ current: id<Promise<void> | undefined>(undefined)
39
+ }));
40
+
41
+ useEffect(() => {
42
+ let isActive = true;
43
+
44
+ (refPrAllStyleSheetLoaded.current ??= (async () => {
45
+ let lastMountedHtmlElement: HTMLLinkElement | undefined = undefined;
46
+
47
+ const prs: Promise<void>[] = [];
48
+
49
+ for (const href of hrefs) {
50
+ const htmlElement = document.createElement("link");
51
+
52
+ prs.push(
53
+ new Promise<void>(resolve =>
54
+ htmlElement.addEventListener("load", () => resolve())
55
+ )
56
+ );
57
+
58
+ htmlElement.rel = "stylesheet";
59
+
60
+ htmlElement.href = href;
61
+
62
+ if (lastMountedHtmlElement !== undefined) {
63
+ lastMountedHtmlElement.insertAdjacentElement("afterend", htmlElement);
64
+ } else {
65
+ document.head.prepend(htmlElement);
36
66
  }
37
67
 
38
- let lastMountedHtmlElement: HTMLLinkElement | undefined = undefined;
39
-
40
- const prs: Promise<void>[] = [];
41
- const removeFns: (() => void)[] = [];
42
-
43
- for (const href of hrefs) {
44
- const htmlElement = document.createElement("link");
45
-
46
- prs.push(
47
- new Promise<void>(resolve =>
48
- htmlElement.addEventListener("load", () => resolve())
49
- )
50
- );
51
-
52
- htmlElement.rel = "stylesheet";
53
-
54
- htmlElement.href = href;
55
-
56
- if (lastMountedHtmlElement !== undefined) {
57
- lastMountedHtmlElement.insertAdjacentElement(
58
- "afterend",
59
- htmlElement
60
- );
61
- } else {
62
- document.head.prepend(htmlElement);
63
- }
64
-
65
- removeFns.push(() => {
66
- htmlElement.remove();
67
- });
68
-
69
- lastMountedHtmlElement = htmlElement;
70
- }
71
-
72
- linkTagsContext = {
73
- styleSheetHrefs: hrefs,
74
- prAreAllStyleSheetsLoaded: Promise.all(prs).then(() => undefined),
75
- remove: () => removeFns.forEach(fn => fn())
76
- };
68
+ lastMountedHtmlElement = htmlElement;
77
69
  }
78
70
 
79
- linkTagsContext.prAreAllStyleSheetsLoaded.then(() => {
80
- if (!isActive) {
81
- return;
82
- }
83
- setAllStyleSheetLoaded();
84
- });
71
+ await Promise.all(prs);
72
+ })()).then(() => {
73
+ if (!isActive) {
74
+ return;
75
+ }
85
76
 
86
- return () => {
87
- isActive = false;
88
- };
89
- }, []);
77
+ setAllStyleSheetsLoaded();
78
+ });
90
79
 
91
- return { areAllStyleSheetsLoaded };
92
- }
80
+ return () => {
81
+ isActive = false;
82
+ };
83
+ }, []);
93
84
 
94
- return { useInsertLinkTags };
85
+ return { areAllStyleSheetsLoaded };
95
86
  }
@@ -1,6 +1,6 @@
1
1
  import { useCallback } from "react";
2
- import { useConst } from "keycloakify/tools/useConst";
3
2
  import { assert } from "tsafe/assert";
3
+ import { useOnFistMount } from "keycloakify/tools/useOnFirstMount";
4
4
 
5
5
  export type ScriptTag = ScriptTag.TextContent | ScriptTag.Src;
6
6
 
@@ -17,95 +17,86 @@ export namespace ScriptTag {
17
17
  };
18
18
  }
19
19
 
20
- export function createUseInsertScriptTags() {
21
- let areScriptsInserted = false;
22
-
23
- function useInsertScriptTags(params: { scriptTags: ScriptTag[] }) {
24
- const { scriptTags } = params;
20
+ const alreadyMountedComponentOrHookNames = new Set<string>();
21
+
22
+ /**
23
+ * NOTE: The component that use this hook can only be mounded once!
24
+ * And can't rerender with different scriptTags.
25
+ * If it's mounted again the page will be reloaded.
26
+ * This simulates the behavior of a server rendered page that imports javascript in the head.
27
+ *
28
+ * The returned function is supposed to be called in a useEffect and
29
+ * will not download the scripts multiple times event if called more than once (react strict mode).
30
+ *
31
+ */
32
+ export function useInsertScriptTags(params: {
33
+ componentOrHookName: string;
34
+ scriptTags: ScriptTag[];
35
+ }) {
36
+ const { scriptTags, componentOrHookName } = params;
37
+
38
+ useOnFistMount(() => {
39
+ const isAlreadyMounted =
40
+ alreadyMountedComponentOrHookNames.has(componentOrHookName);
41
+
42
+ if (isAlreadyMounted) {
43
+ window.location.reload();
44
+ return;
45
+ }
46
+
47
+ alreadyMountedComponentOrHookNames.add(componentOrHookName);
48
+ });
25
49
 
26
- const currentScriptTagsRef = useConst(() => ({
27
- current: scriptTags
28
- }));
50
+ let areScriptsInserted = false;
29
51
 
30
- currentScriptTagsRef.current = scriptTags;
52
+ const insertScriptTags = useCallback(() => {
53
+ if (areScriptsInserted) {
54
+ return;
55
+ }
31
56
 
32
- const insertScriptTags = useCallback(() => {
57
+ scriptTags.forEach(scriptTag => {
58
+ // NOTE: Avoid loading same script twice. (Like jQuery for example)
33
59
  {
34
- const getFingerprint = (scriptTags: ScriptTag[]) =>
35
- scriptTags
36
- .map((scriptTag): string => {
37
- if ("textContent" in scriptTag) {
38
- return scriptTag.textContent;
39
- }
40
- if ("src" in scriptTag) {
41
- return scriptTag.src;
42
- }
43
- assert(false);
44
- })
45
- .join("---");
46
-
47
- if (
48
- getFingerprint(scriptTags) !==
49
- getFingerprint(currentScriptTagsRef.current)
50
- ) {
51
- // NOTE: This is for when the scripts imported in the Template have changed switching
52
- // from one page to another in storybook.
53
- window.location.reload();
54
-
55
- return;
56
- }
57
- }
58
-
59
- if (areScriptsInserted) {
60
- return;
61
- }
62
-
63
- scriptTags.forEach(scriptTag => {
64
- // NOTE: Avoid loading same script twice. (Like jQuery for example)
65
- {
66
- const scripts = document.getElementsByTagName("script");
67
- for (let i = 0; i < scripts.length; i++) {
68
- const script = scripts[i];
69
- if ("textContent" in scriptTag) {
70
- if (script.textContent === scriptTag.textContent) {
71
- return;
72
- }
73
- continue;
60
+ const scripts = document.getElementsByTagName("script");
61
+ for (let i = 0; i < scripts.length; i++) {
62
+ const script = scripts[i];
63
+ if ("textContent" in scriptTag) {
64
+ if (script.textContent === scriptTag.textContent) {
65
+ return;
74
66
  }
75
- if ("src" in scriptTag) {
76
- if (script.getAttribute("src") === scriptTag.src) {
77
- return;
78
- }
79
- continue;
67
+ continue;
68
+ }
69
+ if ("src" in scriptTag) {
70
+ if (script.getAttribute("src") === scriptTag.src) {
71
+ return;
80
72
  }
81
- assert(false);
73
+ continue;
82
74
  }
75
+ assert(false);
83
76
  }
77
+ }
84
78
 
85
- const htmlElement = document.createElement("script");
86
-
87
- htmlElement.type = scriptTag.type;
79
+ const htmlElement = document.createElement("script");
88
80
 
89
- (() => {
90
- if ("textContent" in scriptTag) {
91
- htmlElement.textContent = scriptTag.textContent;
92
- return;
93
- }
94
- if ("src" in scriptTag) {
95
- htmlElement.src = scriptTag.src;
96
- return;
97
- }
98
- assert(false);
99
- })();
81
+ htmlElement.type = scriptTag.type;
100
82
 
101
- document.head.appendChild(htmlElement);
102
- });
83
+ (() => {
84
+ if ("textContent" in scriptTag) {
85
+ htmlElement.textContent = scriptTag.textContent;
86
+ return;
87
+ }
88
+ if ("src" in scriptTag) {
89
+ htmlElement.src = scriptTag.src;
90
+ return;
91
+ }
92
+ assert(false);
93
+ })();
103
94
 
104
- areScriptsInserted = true;
105
- }, []);
95
+ document.head.appendChild(htmlElement);
96
+ });
106
97
 
107
- return { insertScriptTags };
108
- }
98
+ areScriptsInserted = true;
99
+ }, []);
109
100
 
110
- return { useInsertScriptTags };
101
+ return { insertScriptTags };
111
102
  }
@@ -0,0 +1,18 @@
1
+ import { useEffect } from "react";
2
+ import { useConst } from "powerhooks/useConst";
3
+ import { id } from "tsafe/id";
4
+
5
+ /** Callback is guaranteed to be call only once per component mount event in strict mode */
6
+ export function useOnFistMount(callback: () => void) {
7
+ const refHasCallbackBeenCalled = useConst(() => ({ current: id<boolean>(false) }));
8
+
9
+ useEffect(() => {
10
+ if (refHasCallbackBeenCalled.current) {
11
+ return;
12
+ }
13
+
14
+ callback();
15
+
16
+ refHasCallbackBeenCalled.current = true;
17
+ }, []);
18
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"Array.prototype.every.js","sourceRoot":"","sources":["../src/tools/Array.prototype.every.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,UAAU,UAAe,EAAE,OAAY;QAC3D,YAAY,CAAC;QACb,IAAI,CAAC,EAAE,CAAC,CAAC;QAET,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACf,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACvD,CAAC;QAED,8DAA8D;QAC9D,4BAA4B;QAC5B,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAErB,mEAAmE;QACnE,sCAAsC;QACtC,oCAAoC;QACpC,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAEzB,sEAAsE;QACtE,IACI,OAAO,UAAU,KAAK,UAAU;YAChC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,mBAAmB,EACpE,CAAC;YACC,MAAM,IAAI,SAAS,EAAE,CAAC;QAC1B,CAAC;QAED,yEAAyE;QACzE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,CAAC,GAAG,OAAO,CAAC;QAChB,CAAC;QAED,iBAAiB;QACjB,CAAC,GAAG,CAAC,CAAC;QAEN,2BAA2B;QAC3B,OAAO,CAAC,GAAG,GAAG,EAAE,CAAC;YACb,IAAI,MAAM,CAAC;YAEX,4BAA4B;YAC5B,yDAAyD;YACzD,oEAAoE;YACpE,mCAAmC;YACnC,qCAAqC;YACrC,+BAA+B;YAC/B,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACT,IAAI,UAAU,CAAC;gBACf,iEAAiE;gBACjE,4BAA4B;gBAC5B,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAEd,uEAAuE;gBACvE,+DAA+D;gBAC/D,2CAA2C;gBAC3C,iDAAiD;gBACjD,IAAI,CAAC;oBAAE,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;;oBAChD,UAAU,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAE3C,wDAAwD;gBACxD,IAAI,CAAC,UAAU,EAAE,CAAC;oBACd,OAAO,KAAK,CAAC;gBACjB,CAAC;YACL,CAAC;YACD,CAAC,EAAE,CAAC;QACR,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"Array.prototype.every.js","sourceRoot":"","sources":["../src/tools/Array.prototype.every.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE;IACxB,KAAK,CAAC,SAAS,CAAC,KAAK,GAAG,UAAU,UAAe,EAAE,OAAY;QAC3D,YAAY,CAAC;QACb,IAAI,CAAC,EAAE,CAAC,CAAC;QAET,IAAI,IAAI,IAAI,IAAI,EAAE;YACd,MAAM,IAAI,SAAS,CAAC,6BAA6B,CAAC,CAAC;SACtD;QAED,8DAA8D;QAC9D,4BAA4B;QAC5B,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAErB,mEAAmE;QACnE,sCAAsC;QACtC,oCAAoC;QACpC,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;QAEzB,sEAAsE;QACtE,IACI,OAAO,UAAU,KAAK,UAAU;YAChC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,mBAAmB,EACpE;YACE,MAAM,IAAI,SAAS,EAAE,CAAC;SACzB;QAED,yEAAyE;QACzE,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;YACtB,CAAC,GAAG,OAAO,CAAC;SACf;QAED,iBAAiB;QACjB,CAAC,GAAG,CAAC,CAAC;QAEN,2BAA2B;QAC3B,OAAO,CAAC,GAAG,GAAG,EAAE;YACZ,IAAI,MAAM,CAAC;YAEX,4BAA4B;YAC5B,yDAAyD;YACzD,oEAAoE;YACpE,mCAAmC;YACnC,qCAAqC;YACrC,+BAA+B;YAC/B,IAAI,CAAC,IAAI,CAAC,EAAE;gBACR,IAAI,UAAU,CAAC;gBACf,iEAAiE;gBACjE,4BAA4B;gBAC5B,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAEd,uEAAuE;gBACvE,+DAA+D;gBAC/D,2CAA2C;gBAC3C,iDAAiD;gBACjD,IAAI,CAAC;oBAAE,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;;oBAChD,UAAU,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAE3C,wDAAwD;gBACxD,IAAI,CAAC,UAAU,EAAE;oBACb,OAAO,KAAK,CAAC;iBAChB;aACJ;YACD,CAAC,EAAE,CAAC;SACP;QACD,OAAO,IAAI,CAAC;IAChB,CAAC,CAAC;CACL"}
@@ -0,0 +1 @@
1
+ export type ExtractAfterStartingWith<Prefix extends string, StrEnum> = StrEnum extends `${Prefix}${infer U}` ? U : never;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ExtractAfterStartingWith.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExtractAfterStartingWith.js","sourceRoot":"","sources":["../src/tools/ExtractAfterStartingWith.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"HTMLElement.prototype.prepend.js","sourceRoot":"","sources":["../src/tools/HTMLElement.prototype.prepend.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;IACjC,WAAW,CAAC,SAAS,CAAC,OAAO,GAAG,UAAU,SAAS;QAC/C,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"HTMLElement.prototype.prepend.js","sourceRoot":"","sources":["../src/tools/HTMLElement.prototype.prepend.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE;IAChC,WAAW,CAAC,SAAS,CAAC,OAAO,GAAG,UAAU,SAAS;QAC/C,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;YAC/B,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;SAC5E;QAED,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC,CAAC;CACL"}
@@ -1 +1 @@
1
- {"version":3,"file":"StatefulObservable.js","sourceRoot":"","sources":["../../src/tools/StatefulObservable/StatefulObservable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAW9B,MAAM,UAAU,wBAAwB,CACpC,eAAwB;IAExB,MAAM,aAAa,GAA0B,EAAE,CAAC;IAEhD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;QACvB,IAAI,YAAY,GAAoB,SAAS,CAAC;QAE9C,SAAS,GAAG,CAAC,IAAO;YAChB,YAAY,GAAG,CAAC,IAAI,CAAC,CAAC;YAEtB,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO;YACH,GAAG,EAAE,GAAG,EAAE;gBACN,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;oBAC7B,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;oBACvB,MAAM,CAAC,CAAC,EAAE,CAAY,YAAY,CAAC,CAAC,CAAC;gBACzC,CAAC;gBACD,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;YACD,GAAG;SACN,CAAC;IACN,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,MAAM,CAAC,cAAc,CACxB;QACI,OAAO,EAAE,IAAgB;QACzB,SAAS,EAAE,CAAC,IAAuB,EAAE,EAAE;YACnC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEzB,OAAO;gBACH,WAAW,EAAE,GAAG,EAAE,CACd,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aAC3D,CAAC;QACN,CAAC;KACJ,EACD,SAAS,EACT;QACI,UAAU,EAAE,IAAI;QAChB,GAAG;QACH,GAAG;KACN,CACJ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"StatefulObservable.js","sourceRoot":"","sources":["../../src/tools/StatefulObservable/StatefulObservable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAW9B,MAAM,UAAU,wBAAwB,CACpC,eAAwB;IAExB,MAAM,aAAa,GAA0B,EAAE,CAAC;IAEhD,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;QACvB,IAAI,YAAY,GAAoB,SAAS,CAAC;QAE9C,SAAS,GAAG,CAAC,IAAO;YAChB,YAAY,GAAG,CAAC,IAAI,CAAC,CAAC;YAEtB,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO;YACH,GAAG,EAAE,GAAG,EAAE;gBACN,IAAI,YAAY,KAAK,SAAS,EAAE;oBAC5B,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;oBACvB,MAAM,CAAC,CAAC,EAAE,CAAY,YAAY,CAAC,CAAC,CAAC;iBACxC;gBACD,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;YACD,GAAG;SACN,CAAC;IACN,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,MAAM,CAAC,cAAc,CACxB;QACI,OAAO,EAAE,IAAgB;QACzB,SAAS,EAAE,CAAC,IAAuB,EAAE,EAAE;YACnC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEzB,OAAO;gBACH,WAAW,EAAE,GAAG,EAAE,CACd,aAAa,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;aAC3D,CAAC;QACN,CAAC;KACJ,EACD,SAAS,EACT;QACI,UAAU,EAAE,IAAI;QAChB,GAAG;QACH,GAAG;KACN,CACJ,CAAC;AACN,CAAC"}
@@ -2,4 +2,4 @@ import type { StatefulObservable } from "../StatefulObservable";
2
2
  /**
3
3
  * Equivalent of https://docs.evt.land/api/react-hooks
4
4
  * */
5
- export declare function useRerenderOnChange($: StatefulObservable<unknown>): void;
5
+ export declare function useRerenderOnChange(obs: StatefulObservable<unknown>): void;
@@ -3,12 +3,12 @@ import { useState } from "react";
3
3
  /**
4
4
  * Equivalent of https://docs.evt.land/api/react-hooks
5
5
  * */
6
- export function useRerenderOnChange($) {
6
+ export function useRerenderOnChange(obs) {
7
7
  //NOTE: We use function in case the state is a function
8
- const [, setCurrent] = useState(() => $.current);
8
+ const [, setCurrent] = useState(() => obs.current);
9
9
  useObservable(({ registerSubscription }) => {
10
- const subscription = $.subscribe(current => setCurrent(() => current));
10
+ const subscription = obs.subscribe(current => setCurrent(() => current));
11
11
  registerSubscription(subscription);
12
- }, [$]);
12
+ }, [obs]);
13
13
  }
14
14
  //# sourceMappingURL=useRerenderOnChange.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useRerenderOnChange.js","sourceRoot":"","sources":["../../../src/tools/StatefulObservable/hooks/useRerenderOnChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC;;KAEK;AACL,MAAM,UAAU,mBAAmB,CAAC,CAA8B;IAC9D,uDAAuD;IACvD,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEjD,aAAa,CACT,CAAC,EAAE,oBAAoB,EAAE,EAAE,EAAE;QACzB,MAAM,YAAY,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACvE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC,EACD,CAAC,CAAC,CAAC,CACN,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"useRerenderOnChange.js","sourceRoot":"","sources":["../../../src/tools/StatefulObservable/hooks/useRerenderOnChange.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC;;KAEK;AACL,MAAM,UAAU,mBAAmB,CAAC,GAAgC;IAChE,uDAAuD;IACvD,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAEnD,aAAa,CACT,CAAC,EAAE,oBAAoB,EAAE,EAAE,EAAE;QACzB,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACzE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACvC,CAAC,EACD,CAAC,GAAG,CAAC,CACR,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Pendant of `keyof T` */
2
+ export type ValueOf<T> = T[keyof T];
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ValueOf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValueOf.js","sourceRoot":"","sources":["../src/tools/ValueOf.ts"],"names":[],"mappings":""}