@workos-inc/widgets 1.20.2-next.1792700156145 → 1.20.2

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 (202) hide show
  1. package/CHANGELOG.md +4 -10
  2. package/dist/cjs/admin-portal-audit-log-streaming.client.cjs +2 -1
  3. package/dist/cjs/admin-portal-audit-log-streaming.client.cjs.map +1 -1
  4. package/dist/cjs/admin-portal-domain-verification.client.cjs +3 -2
  5. package/dist/cjs/admin-portal-domain-verification.client.cjs.map +1 -1
  6. package/dist/cjs/admin-portal-sso-connection.client.cjs +2 -1
  7. package/dist/cjs/admin-portal-sso-connection.client.cjs.map +1 -1
  8. package/dist/cjs/api/api-provider.cjs +23 -1
  9. package/dist/cjs/api/api-provider.cjs.map +1 -1
  10. package/dist/cjs/api/api-provider.d.cts.map +1 -1
  11. package/dist/cjs/api/claims.cjs.map +1 -1
  12. package/dist/cjs/api/claims.d.cts +2 -1
  13. package/dist/cjs/api/claims.d.cts.map +1 -1
  14. package/dist/cjs/api/client-graphql/client.cjs +3 -2
  15. package/dist/cjs/api/client-graphql/client.cjs.map +1 -1
  16. package/dist/cjs/api/client-graphql/hooks.cjs +3 -20
  17. package/dist/cjs/api/client-graphql/hooks.cjs.map +1 -1
  18. package/dist/cjs/api/client-graphql/hooks.d.cts +3 -12
  19. package/dist/cjs/api/client-graphql/hooks.d.cts.map +1 -1
  20. package/dist/cjs/api/client-graphql/query-keys.cjs +25 -0
  21. package/dist/cjs/api/client-graphql/query-keys.cjs.map +1 -0
  22. package/dist/cjs/api/client-graphql/query-keys.d.cts +16 -0
  23. package/dist/cjs/api/client-graphql/query-keys.d.cts.map +1 -0
  24. package/dist/cjs/components/copy-text.cjs +1 -1
  25. package/dist/cjs/components/copy-text.cjs.map +1 -1
  26. package/dist/cjs/components/form.cjs +9 -13
  27. package/dist/cjs/components/form.cjs.map +1 -1
  28. package/dist/cjs/components/form.d.cts.map +1 -1
  29. package/dist/cjs/components/otp-input.cjs +1 -0
  30. package/dist/cjs/components/otp-input.cjs.map +1 -1
  31. package/dist/cjs/directory-sync.client.cjs +2 -1
  32. package/dist/cjs/directory-sync.client.cjs.map +1 -1
  33. package/dist/cjs/lib/api/api-key.cjs +4 -3
  34. package/dist/cjs/lib/api/api-key.cjs.map +1 -1
  35. package/dist/cjs/lib/api/me.cjs +2 -1
  36. package/dist/cjs/lib/api/me.cjs.map +1 -1
  37. package/dist/cjs/lib/api/pipes.cjs +7 -6
  38. package/dist/cjs/lib/api/pipes.cjs.map +1 -1
  39. package/dist/cjs/lib/api/user-api-key.cjs +3 -2
  40. package/dist/cjs/lib/api/user-api-key.cjs.map +1 -1
  41. package/dist/cjs/lib/i18n/intl-context.cjs.map +1 -1
  42. package/dist/cjs/lib/i18n/intl-context.d.cts +1 -0
  43. package/dist/cjs/lib/i18n/intl-context.d.cts.map +1 -1
  44. package/dist/cjs/lib/i18n/use-translation.cjs +2 -2
  45. package/dist/cjs/lib/i18n/use-translation.cjs.map +1 -1
  46. package/dist/cjs/lib/use-composed-event-handlers.cjs +15 -0
  47. package/dist/cjs/lib/use-composed-event-handlers.cjs.map +1 -0
  48. package/dist/cjs/lib/use-composed-event-handlers.d.cts +6 -0
  49. package/dist/cjs/lib/use-composed-event-handlers.d.cts.map +1 -0
  50. package/dist/cjs/lib/use-debounce.cjs +124 -116
  51. package/dist/cjs/lib/use-debounce.cjs.map +1 -1
  52. package/dist/cjs/lib/use-debounce.d.cts +53 -48
  53. package/dist/cjs/lib/use-debounce.d.cts.map +1 -1
  54. package/dist/cjs/lib/use-widgets-invalidator.cjs +3 -3
  55. package/dist/cjs/lib/use-widgets-invalidator.cjs.map +1 -1
  56. package/dist/cjs/lib/use-widgets-invalidator.d.cts.map +1 -1
  57. package/dist/cjs/lib/utils.cjs +0 -7
  58. package/dist/cjs/lib/utils.cjs.map +1 -1
  59. package/dist/cjs/lib/utils.d.cts +0 -3
  60. package/dist/cjs/lib/utils.d.cts.map +1 -1
  61. package/dist/cjs/organization-switcher.client.cjs +2 -1
  62. package/dist/cjs/organization-switcher.client.cjs.map +1 -1
  63. package/dist/cjs/pipes-admin.client.cjs +2 -1
  64. package/dist/cjs/pipes-admin.client.cjs.map +1 -1
  65. package/dist/cjs/pipes.client.cjs +2 -1
  66. package/dist/cjs/pipes.client.cjs.map +1 -1
  67. package/dist/cjs/user-security.client.cjs +2 -1
  68. package/dist/cjs/user-security.client.cjs.map +1 -1
  69. package/dist/cjs/user-sessions.client.cjs +2 -1
  70. package/dist/cjs/user-sessions.client.cjs.map +1 -1
  71. package/dist/cjs/widgets/api-keys/api-keys-search.cjs +1 -1
  72. package/dist/cjs/widgets/api-keys/api-keys-search.cjs.map +1 -1
  73. package/dist/cjs/widgets/api-keys/user-api-keys-search.cjs +1 -1
  74. package/dist/cjs/widgets/api-keys/user-api-keys-search.cjs.map +1 -1
  75. package/dist/cjs/widgets/organization-switcher/organization-switcher.cjs +19 -5
  76. package/dist/cjs/widgets/organization-switcher/organization-switcher.cjs.map +1 -1
  77. package/dist/cjs/widgets/organization-switcher/organization-switcher.d.cts +2 -1
  78. package/dist/cjs/widgets/organization-switcher/organization-switcher.d.cts.map +1 -1
  79. package/dist/cjs/widgets/pipes/pipes.cjs +3 -2
  80. package/dist/cjs/widgets/pipes/pipes.cjs.map +1 -1
  81. package/dist/cjs/widgets/user-sessions/logout-all-sessions-dialog.cjs +2 -1
  82. package/dist/cjs/widgets/user-sessions/logout-all-sessions-dialog.cjs.map +1 -1
  83. package/dist/cjs/widgets/user-sessions/logout-dialog.cjs +2 -1
  84. package/dist/cjs/widgets/user-sessions/logout-dialog.cjs.map +1 -1
  85. package/dist/cjs/widgets/users-management/invite-user-dialog.cjs +5 -6
  86. package/dist/cjs/widgets/users-management/invite-user-dialog.cjs.map +1 -1
  87. package/dist/cjs/widgets/users-management/users-management-utils.cjs +4 -3
  88. package/dist/cjs/widgets/users-management/users-management-utils.cjs.map +1 -1
  89. package/dist/cjs/widgets/users-management/users-management.cjs.map +1 -1
  90. package/dist/cjs/widgets/users-management/users-search.cjs +1 -1
  91. package/dist/cjs/widgets/users-management/users-search.cjs.map +1 -1
  92. package/dist/esm/admin-portal-audit-log-streaming.client.js +2 -1
  93. package/dist/esm/admin-portal-audit-log-streaming.client.js.map +1 -1
  94. package/dist/esm/admin-portal-domain-verification.client.js +2 -1
  95. package/dist/esm/admin-portal-domain-verification.client.js.map +1 -1
  96. package/dist/esm/admin-portal-sso-connection.client.js +2 -1
  97. package/dist/esm/admin-portal-sso-connection.client.js.map +1 -1
  98. package/dist/esm/api/api-provider.d.ts.map +1 -1
  99. package/dist/esm/api/api-provider.js +23 -1
  100. package/dist/esm/api/api-provider.js.map +1 -1
  101. package/dist/esm/api/claims.d.ts +2 -1
  102. package/dist/esm/api/claims.d.ts.map +1 -1
  103. package/dist/esm/api/claims.js.map +1 -1
  104. package/dist/esm/api/client-graphql/client.js +3 -2
  105. package/dist/esm/api/client-graphql/client.js.map +1 -1
  106. package/dist/esm/api/client-graphql/hooks.d.ts +3 -12
  107. package/dist/esm/api/client-graphql/hooks.d.ts.map +1 -1
  108. package/dist/esm/api/client-graphql/hooks.js +1 -18
  109. package/dist/esm/api/client-graphql/hooks.js.map +1 -1
  110. package/dist/esm/api/client-graphql/query-keys.d.ts +16 -0
  111. package/dist/esm/api/client-graphql/query-keys.d.ts.map +1 -0
  112. package/dist/esm/api/client-graphql/query-keys.js +23 -0
  113. package/dist/esm/api/client-graphql/query-keys.js.map +1 -0
  114. package/dist/esm/components/copy-text.js +1 -1
  115. package/dist/esm/components/copy-text.js.map +1 -1
  116. package/dist/esm/components/form.d.ts.map +1 -1
  117. package/dist/esm/components/form.js +9 -13
  118. package/dist/esm/components/form.js.map +1 -1
  119. package/dist/esm/components/otp-input.js +1 -0
  120. package/dist/esm/components/otp-input.js.map +1 -1
  121. package/dist/esm/directory-sync.client.js +2 -1
  122. package/dist/esm/directory-sync.client.js.map +1 -1
  123. package/dist/esm/lib/api/api-key.js +2 -1
  124. package/dist/esm/lib/api/api-key.js.map +1 -1
  125. package/dist/esm/lib/api/me.js +2 -1
  126. package/dist/esm/lib/api/me.js.map +1 -1
  127. package/dist/esm/lib/api/pipes.js +2 -1
  128. package/dist/esm/lib/api/pipes.js.map +1 -1
  129. package/dist/esm/lib/api/user-api-key.js +2 -1
  130. package/dist/esm/lib/api/user-api-key.js.map +1 -1
  131. package/dist/esm/lib/i18n/intl-context.d.ts +1 -0
  132. package/dist/esm/lib/i18n/intl-context.d.ts.map +1 -1
  133. package/dist/esm/lib/i18n/intl-context.js.map +1 -1
  134. package/dist/esm/lib/i18n/use-translation.js +2 -2
  135. package/dist/esm/lib/i18n/use-translation.js.map +1 -1
  136. package/dist/esm/lib/use-composed-event-handlers.d.ts +6 -0
  137. package/dist/esm/lib/use-composed-event-handlers.d.ts.map +1 -0
  138. package/dist/esm/lib/use-composed-event-handlers.js +12 -0
  139. package/dist/esm/lib/use-composed-event-handlers.js.map +1 -0
  140. package/dist/esm/lib/use-debounce.d.ts +53 -48
  141. package/dist/esm/lib/use-debounce.d.ts.map +1 -1
  142. package/dist/esm/lib/use-debounce.js +124 -116
  143. package/dist/esm/lib/use-debounce.js.map +1 -1
  144. package/dist/esm/lib/use-widgets-invalidator.d.ts.map +1 -1
  145. package/dist/esm/lib/use-widgets-invalidator.js +2 -2
  146. package/dist/esm/lib/use-widgets-invalidator.js.map +1 -1
  147. package/dist/esm/lib/utils.d.ts +0 -3
  148. package/dist/esm/lib/utils.d.ts.map +1 -1
  149. package/dist/esm/lib/utils.js +1 -7
  150. package/dist/esm/lib/utils.js.map +1 -1
  151. package/dist/esm/organization-switcher.client.js +2 -1
  152. package/dist/esm/organization-switcher.client.js.map +1 -1
  153. package/dist/esm/pipes-admin.client.js +2 -1
  154. package/dist/esm/pipes-admin.client.js.map +1 -1
  155. package/dist/esm/pipes.client.js +2 -1
  156. package/dist/esm/pipes.client.js.map +1 -1
  157. package/dist/esm/user-security.client.js +2 -1
  158. package/dist/esm/user-security.client.js.map +1 -1
  159. package/dist/esm/user-sessions.client.js +2 -1
  160. package/dist/esm/user-sessions.client.js.map +1 -1
  161. package/dist/esm/widgets/api-keys/api-keys-search.js +1 -1
  162. package/dist/esm/widgets/api-keys/api-keys-search.js.map +1 -1
  163. package/dist/esm/widgets/api-keys/user-api-keys-search.js +1 -1
  164. package/dist/esm/widgets/api-keys/user-api-keys-search.js.map +1 -1
  165. package/dist/esm/widgets/organization-switcher/organization-switcher.d.ts +2 -1
  166. package/dist/esm/widgets/organization-switcher/organization-switcher.d.ts.map +1 -1
  167. package/dist/esm/widgets/organization-switcher/organization-switcher.js +19 -5
  168. package/dist/esm/widgets/organization-switcher/organization-switcher.js.map +1 -1
  169. package/dist/esm/widgets/pipes/pipes.js +2 -1
  170. package/dist/esm/widgets/pipes/pipes.js.map +1 -1
  171. package/dist/esm/widgets/user-sessions/logout-all-sessions-dialog.js +2 -1
  172. package/dist/esm/widgets/user-sessions/logout-all-sessions-dialog.js.map +1 -1
  173. package/dist/esm/widgets/user-sessions/logout-dialog.js +2 -1
  174. package/dist/esm/widgets/user-sessions/logout-dialog.js.map +1 -1
  175. package/dist/esm/widgets/users-management/invite-user-dialog.js +5 -6
  176. package/dist/esm/widgets/users-management/invite-user-dialog.js.map +1 -1
  177. package/dist/esm/widgets/users-management/users-management-utils.js +2 -1
  178. package/dist/esm/widgets/users-management/users-management-utils.js.map +1 -1
  179. package/dist/esm/widgets/users-management/users-management.js.map +1 -1
  180. package/dist/esm/widgets/users-management/users-search.js +1 -1
  181. package/dist/esm/widgets/users-management/users-search.js.map +1 -1
  182. package/package.json +1 -1
  183. package/src/api/api-provider.tsx +39 -1
  184. package/src/api/claims.ts +2 -1
  185. package/src/api/client-graphql/client.ts +8 -2
  186. package/src/api/client-graphql/hooks.ts +8 -27
  187. package/src/api/client-graphql/query-keys.ts +29 -0
  188. package/src/components/copy-text.tsx +1 -1
  189. package/src/components/form.tsx +33 -29
  190. package/src/components/otp-input.tsx +2 -0
  191. package/src/lib/i18n/intl-context.tsx +4 -0
  192. package/src/lib/i18n/use-translation.ts +1 -4
  193. package/src/lib/use-composed-event-handlers.ts +25 -0
  194. package/src/lib/use-debounce.ts +289 -237
  195. package/src/lib/use-widgets-invalidator.ts +0 -4
  196. package/src/lib/utils.ts +0 -12
  197. package/src/widgets/api-keys/api-keys-search.tsx +6 -3
  198. package/src/widgets/api-keys/user-api-keys-search.tsx +6 -3
  199. package/src/widgets/organization-switcher/organization-switcher.tsx +32 -8
  200. package/src/widgets/users-management/invite-user-dialog.tsx +9 -11
  201. package/src/widgets/users-management/users-management.tsx +1 -1
  202. package/src/widgets/users-management/users-search.tsx +6 -3
@@ -1,3 +1,4 @@
1
+ import { useLayoutEffect } from "./use-layout-effect.js";
1
2
  import { canUseDOM } from "./utils.js";
2
3
  import * as React from "react";
3
4
  //#region src/lib/use-debounce.ts
@@ -31,34 +32,25 @@ import * as React from "react";
31
32
  * article](https://css-tricks.com/debouncing-throttling-explained-examples/)
32
33
  * for details over the differences between `debounce` and `throttle`.
33
34
  *
34
- * @category Function
35
- * @param {Function} func The function to debounce.
36
- * @param {number} [wait=0] The number of milliseconds to delay; if omitted,
37
- * `requestAnimationFrame` is used (if available, otherwise it will be
38
- * setTimeout(...,0)).
39
- * @param {Object} [options={}] The options object. Controls if `func` should be
40
- * invoked on the leading edge of the timeout.
41
- * @param {boolean} [options.leading=false] The maximum time `func` is allowed
42
- * to be delayed before it's invoked.
43
- * @param {number} [options.maxWait] Controls if `func` should be invoked the
44
- * trailing edge of the timeout.
45
- * @param {boolean} [options.trailing=true]
46
- * @returns {Function} Returns the new debounced function.
35
+ * @param func The function to debounce
36
+ * @param options The options object
37
+ * @returns Returns the new debounced function.
47
38
  * @example
48
39
  * ```tsx
49
40
  * // Avoid costly calculations while the window size is in flux.
50
- * const resizeHandler = useDebouncedCallback(calculateLayout, 150);
41
+ * const resizeHandler = useDebouncedCallback(calculateLayout, { wait: 150 });
51
42
  * window.addEventListener('resize', resizeHandler)
52
43
  *
53
44
  * // Invoke `sendMail` when clicked, debouncing subsequent calls.
54
- * const clickHandler = useDebouncedCallback(sendMail, 300, {
45
+ * const clickHandler = useDebouncedCallback(sendMail, {
46
+ * wait: 300,
55
47
  * leading: true,
56
48
  * trailing: false,
57
49
  * })
58
50
  * <button onClick={clickHandler}>click me</button>
59
51
  *
60
52
  * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
61
- * const debounced = useDebouncedCallback(batchLog, 250, { 'maxWait': 1000 })
53
+ * const debounced = useDebouncedCallback(batchLog, { wait: 250, maxWait: 1000 })
62
54
  * const source = new EventSource('/stream')
63
55
  * source.addEventListener('message', debounced)
64
56
  *
@@ -69,125 +61,141 @@ import * as React from "react";
69
61
  * const status = debounced.isPending() ? "Pending..." : "Ready"
70
62
  * ```
71
63
  */
72
- function useDebouncedCallback(func, wait, options) {
73
- const lastCallTime = React.useRef(null);
74
- const lastInvokeTime = React.useRef(0);
75
- const timerId = React.useRef(null);
76
- const lastArgs = React.useRef(null);
77
- const lastThis = React.useRef(void 0);
78
- const result = React.useRef(void 0);
79
- const funcRef = React.useRef(func);
80
- const mounted = React.useRef(true);
81
- const visibilityListener = React.useRef(null);
82
- const debouncedRef = React.useRef(void 0);
83
- funcRef.current = func;
84
- const useRAF = !wait && wait !== 0 && canUseDOM;
85
- if (typeof func !== "function") throw new TypeError("Expected a function");
86
- wait = +(wait || 0);
87
- options = options || {};
88
- const leading = !!options.leading;
89
- const trailing = "trailing" in options ? !!options.trailing : true;
64
+ function useDebouncedCallback(func, options = {}) {
65
+ const { wait = 0, leading = false, trailing = true, maxWait: maxWaitOption, debounceOnServer = false } = options;
66
+ const useRAF = options.wait === void 0 && canUseDOM;
90
67
  const flushOnExit = !!options.flushOnExit && trailing;
91
- const maxing = "maxWait" in options;
92
- const debounceOnServer = "debounceOnServer" in options ? !!options.debounceOnServer : false;
93
- const maxWait = maxing ? Math.max(+(options.maxWait || 0), wait) : null;
68
+ const maxWait = maxWaitOption === void 0 ? null : Math.max(maxWaitOption ?? 0, wait);
69
+ const stateRef = React.useRef({
70
+ func,
71
+ lastCallTime: null,
72
+ lastInvokeTime: 0,
73
+ timerId: null,
74
+ lastArgs: null,
75
+ lastThis: void 0,
76
+ result: void 0,
77
+ mounted: true,
78
+ visibilityListener: null,
79
+ debounced: void 0
80
+ });
94
81
  const debounced = React.useMemo(() => {
95
- const invokeFunc = (time) => {
96
- const args = lastArgs.current;
97
- const thisArg = lastThis.current;
98
- lastArgs.current = lastThis.current = null;
99
- lastInvokeTime.current = time;
100
- return result.current = funcRef.current.apply(thisArg, args || []);
82
+ const config = {
83
+ wait,
84
+ maxWait,
85
+ leading,
86
+ trailing,
87
+ flushOnExit,
88
+ useRAF,
89
+ debounceOnServer
101
90
  };
102
- const startTimer = (pendingFunc, wait) => {
103
- if (useRAF) cancelAnimationFrame(timerId.current);
104
- timerId.current = useRAF ? requestAnimationFrame(pendingFunc) : setTimeout(pendingFunc, wait);
91
+ const debounced = function(...args) {
92
+ return debounce(stateRef.current, config, this, args);
105
93
  };
106
- const shouldInvoke = (time) => {
107
- if (!mounted.current) return false;
108
- const timeSinceLastCall = time - (lastCallTime.current || 0);
109
- const timeSinceLastInvoke = time - lastInvokeTime.current;
110
- return !lastCallTime.current || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= (maxWait || 0);
111
- };
112
- const trailingEdge = (time) => {
113
- timerId.current = null;
114
- if (trailing && lastArgs.current) return invokeFunc(time);
115
- lastArgs.current = lastThis.current = null;
116
- return result.current;
117
- };
118
- const timerExpired = () => {
119
- const time = Date.now();
120
- if (shouldInvoke(time)) return trailingEdge(time);
121
- if (!mounted.current) return;
122
- const timeSinceLastCall = time - (lastCallTime.current || 0);
123
- const timeSinceLastInvoke = time - lastInvokeTime.current;
124
- const timeWaiting = wait - timeSinceLastCall;
125
- const remainingWait = maxing ? Math.min(timeWaiting, (maxWait || 0) - timeSinceLastInvoke) : timeWaiting;
126
- startTimer(timerExpired, remainingWait);
127
- };
128
- const func = (...args) => {
129
- if (!canUseDOM && !debounceOnServer) return;
130
- const time = Date.now();
131
- const isInvoking = shouldInvoke(time);
132
- lastArgs.current = args;
133
- lastThis.current = this;
134
- lastCallTime.current = time;
135
- if (flushOnExit && !visibilityListener.current) {
136
- visibilityListener.current = () => {
137
- if (globalThis.document?.visibilityState === "hidden") debouncedRef.current?.flush();
138
- };
139
- globalThis.document?.addEventListener?.("visibilitychange", visibilityListener.current);
140
- }
141
- if (isInvoking) {
142
- if (!timerId.current && mounted.current) {
143
- lastInvokeTime.current = lastCallTime.current;
144
- startTimer(timerExpired, wait);
145
- return leading ? invokeFunc(lastCallTime.current) : result.current;
146
- }
147
- if (maxing) {
148
- startTimer(timerExpired, wait);
149
- return invokeFunc(lastCallTime.current);
150
- }
151
- }
152
- if (!timerId.current) startTimer(timerExpired, wait);
153
- return result.current;
154
- };
155
- func.cancel = () => {
156
- if (timerId.current) useRAF ? cancelAnimationFrame(timerId.current) : clearTimeout(timerId.current);
157
- lastInvokeTime.current = 0;
158
- lastArgs.current = lastCallTime.current = lastThis.current = timerId.current = null;
159
- };
160
- func.isPending = () => {
161
- return !!timerId.current;
162
- };
163
- func.flush = () => {
164
- return !timerId.current ? result.current : trailingEdge(Date.now());
165
- };
166
- return func;
94
+ debounced.cancel = () => cancel(stateRef.current, config);
95
+ debounced.isPending = () => !!stateRef.current.timerId;
96
+ debounced.flush = () => flush(stateRef.current, config);
97
+ return debounced;
167
98
  }, [
168
- leading,
169
- maxing,
170
99
  wait,
171
100
  maxWait,
101
+ leading,
172
102
  trailing,
173
103
  flushOnExit,
174
104
  useRAF,
175
105
  debounceOnServer
176
106
  ]);
177
- debouncedRef.current = debounced;
107
+ useLayoutEffect(() => {
108
+ stateRef.current.func = func;
109
+ stateRef.current.debounced = debounced;
110
+ });
178
111
  React.useEffect(() => {
179
- mounted.current = true;
112
+ const state = stateRef.current;
113
+ state.mounted = true;
180
114
  return () => {
181
- if (flushOnExit) debouncedRef.current?.flush();
182
- if (visibilityListener.current) {
183
- globalThis.document?.removeEventListener?.("visibilitychange", visibilityListener.current);
184
- visibilityListener.current = null;
115
+ if (flushOnExit) state.debounced?.flush();
116
+ if (state.visibilityListener) {
117
+ globalThis.document?.removeEventListener?.("visibilitychange", state.visibilityListener);
118
+ state.visibilityListener = null;
185
119
  }
186
- mounted.current = false;
120
+ state.mounted = false;
187
121
  };
188
122
  }, [flushOnExit]);
189
123
  return debounced;
190
124
  }
125
+ function invokeFunc(state, time) {
126
+ const args = state.lastArgs;
127
+ const thisArg = state.lastThis;
128
+ state.lastArgs = state.lastThis = null;
129
+ state.lastInvokeTime = time;
130
+ return state.result = state.func.apply(thisArg, args || []);
131
+ }
132
+ function startTimer(state, config, wait) {
133
+ const onTimer = () => timerExpired(state, config);
134
+ if (config.useRAF) cancelAnimationFrame(state.timerId);
135
+ state.timerId = config.useRAF ? requestAnimationFrame(onTimer) : setTimeout(onTimer, wait);
136
+ }
137
+ function shouldInvoke(state, { wait, maxWait }, time) {
138
+ if (!state.mounted) return false;
139
+ const timeSinceLastCall = time - (state.lastCallTime || 0);
140
+ const timeSinceLastInvoke = time - state.lastInvokeTime;
141
+ return !state.lastCallTime || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxWait !== null && timeSinceLastInvoke >= maxWait;
142
+ }
143
+ function trailingEdge(state, config, time) {
144
+ state.timerId = null;
145
+ if (config.trailing && state.lastArgs) return invokeFunc(state, time);
146
+ state.lastArgs = state.lastThis = null;
147
+ return state.result;
148
+ }
149
+ function timerExpired(state, config) {
150
+ const time = Date.now();
151
+ if (shouldInvoke(state, config, time)) {
152
+ trailingEdge(state, config, time);
153
+ return;
154
+ }
155
+ if (!state.mounted) return;
156
+ const timeSinceLastCall = time - (state.lastCallTime || 0);
157
+ const timeSinceLastInvoke = time - state.lastInvokeTime;
158
+ const timeWaiting = config.wait - timeSinceLastCall;
159
+ startTimer(state, config, config.maxWait !== null ? Math.min(timeWaiting, config.maxWait - timeSinceLastInvoke) : timeWaiting);
160
+ }
161
+ function debounce(state, config, thisArg, args) {
162
+ if (!canUseDOM && !config.debounceOnServer) return;
163
+ const time = Date.now();
164
+ const isInvoking = shouldInvoke(state, config, time);
165
+ state.lastArgs = args;
166
+ state.lastThis = thisArg;
167
+ state.lastCallTime = time;
168
+ if (config.flushOnExit && !state.visibilityListener) {
169
+ state.visibilityListener = () => {
170
+ if (globalThis.document?.visibilityState === "hidden") state.debounced?.flush();
171
+ };
172
+ globalThis.document?.addEventListener?.("visibilitychange", state.visibilityListener);
173
+ }
174
+ if (isInvoking) {
175
+ if (!state.timerId && state.mounted) {
176
+ state.lastInvokeTime = time;
177
+ startTimer(state, config, config.wait);
178
+ return config.leading ? invokeFunc(state, time) : state.result;
179
+ }
180
+ if (config.maxWait !== null) {
181
+ startTimer(state, config, config.wait);
182
+ return invokeFunc(state, time);
183
+ }
184
+ }
185
+ if (!state.timerId) startTimer(state, config, config.wait);
186
+ return state.result;
187
+ }
188
+ function cancel(state, config) {
189
+ if (state.timerId) {
190
+ if (config.useRAF) cancelAnimationFrame(state.timerId);
191
+ else clearTimeout(state.timerId);
192
+ }
193
+ state.lastInvokeTime = 0;
194
+ state.lastArgs = state.lastCallTime = state.lastThis = state.timerId = null;
195
+ }
196
+ function flush(state, config) {
197
+ return !state.timerId ? state.result : trailingEdge(state, config, Date.now());
198
+ }
191
199
  //#endregion
192
200
  export { useDebouncedCallback };
193
201
 
@@ -1 +1 @@
1
- {"version":3,"file":"use-debounce.js","names":[],"sources":["../../../src/lib/use-debounce.ts"],"sourcesContent":["// Fork of https://github.com/xnimorz/use-debounce\n// MIT License, Copyright (c) 2018 Nikita Mostovoy\nimport * as React from \"react\";\nimport { canUseDOM } from \"./utils.js\";\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked, or until the next browser frame is drawn.\n *\n * The debounced function comes with a `cancel` method to cancel delayed `func`\n * invocations and a `flush` method to immediately invoke them.\n *\n * Provide `options` to indicate whether `func` should be invoked on the leading\n * and/or trailing edge of the `wait` timeout. The `func` is invoked with the\n * last arguments provided to the debounced function.\n *\n * Subsequent calls to the debounced function return the result of the last\n * `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is invoked\n * more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * See [David Corbacho's\n * article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `debounce` and `throttle`.\n *\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay; if omitted,\n * `requestAnimationFrame` is used (if available, otherwise it will be\n * setTimeout(...,0)).\n * @param {Object} [options={}] The options object. Controls if `func` should be\n * invoked on the leading edge of the timeout.\n * @param {boolean} [options.leading=false] The maximum time `func` is allowed\n * to be delayed before it's invoked.\n * @param {number} [options.maxWait] Controls if `func` should be invoked the\n * trailing edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * @returns {Function} Returns the new debounced function.\n * @example\n * ```tsx\n * // Avoid costly calculations while the window size is in flux.\n * const resizeHandler = useDebouncedCallback(calculateLayout, 150);\n * window.addEventListener('resize', resizeHandler)\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * const clickHandler = useDebouncedCallback(sendMail, 300, {\n * leading: true,\n * trailing: false,\n * })\n * <button onClick={clickHandler}>click me</button>\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * const debounced = useDebouncedCallback(batchLog, 250, { 'maxWait': 1000 })\n * const source = new EventSource('/stream')\n * source.addEventListener('message', debounced)\n *\n * // Cancel the trailing debounced invocation.\n * window.addEventListener('popstate', debounced.cancel)\n *\n * // Check for pending invocations.\n * const status = debounced.isPending() ? \"Pending...\" : \"Ready\"\n * ```\n */\nfunction useDebouncedCallback<T extends (...args: any) => ReturnType<T>>(\n this: unknown,\n func: T,\n wait?: number,\n options?: Options,\n): DebouncedState<T> {\n const lastCallTime = React.useRef<number>(null);\n const lastInvokeTime = React.useRef(0);\n const timerId = React.useRef<number>(null);\n const lastArgs = React.useRef<unknown[]>(null);\n const lastThis = React.useRef<unknown>(undefined);\n const result = React.useRef<ReturnType<T>>(undefined);\n const funcRef = React.useRef(func);\n const mounted = React.useRef(true);\n const visibilityListener = React.useRef<VoidFunction>(null);\n const debouncedRef = React.useRef<DebouncedState<T>>(undefined);\n // Always keep the latest version of debounce callback, with no wait time.\n // TODO: Fix this!\n // eslint-disable-next-line react-hooks/exhaustive-deps\n funcRef.current = func;\n\n // Bypass `requestAnimationFrame` by explicitly setting `wait=0`.\n const useRAF = !wait && wait !== 0 && canUseDOM;\n\n if (typeof func !== \"function\") {\n throw new TypeError(\"Expected a function\");\n }\n\n wait = +(wait || 0);\n options = options || {};\n\n const leading = !!options.leading;\n const trailing = \"trailing\" in options ? !!options.trailing : true; // `true` by default\n const flushOnExit = !!options.flushOnExit && trailing;\n const maxing = \"maxWait\" in options;\n const debounceOnServer =\n \"debounceOnServer\" in options ? !!options.debounceOnServer : false; // `false` by default\n const maxWait = maxing ? Math.max(+(options.maxWait || 0), wait) : null;\n\n // You may have a question, why we have so many code under the useMemo definition.\n //\n // This was made as we want to escape from useCallback hell and\n // not to initialize a number of functions each time useDebouncedCallback is called.\n //\n // It means that we have less garbage for our GC calls which improves performance.\n // Also, it makes this library smaller.\n //\n // And the last reason, that the code without lots of useCallback with deps is easier to read.\n // You have only one place for that.\n const debounced = React.useMemo(() => {\n const invokeFunc = (time: number) => {\n const args = lastArgs.current;\n const thisArg = lastThis.current;\n lastArgs.current = lastThis.current = null;\n lastInvokeTime.current = time;\n\n return (result.current = funcRef.current.apply(thisArg, args || []));\n };\n\n const startTimer = (pendingFunc: () => void, wait: number) => {\n if (useRAF) {\n cancelAnimationFrame(timerId.current!);\n }\n timerId.current = useRAF\n ? requestAnimationFrame(pendingFunc)\n : (setTimeout(pendingFunc, wait) as unknown as number);\n };\n\n const shouldInvoke = (time: number) => {\n if (!mounted.current) return false;\n\n const timeSinceLastCall = time - (lastCallTime.current || 0);\n const timeSinceLastInvoke = time - lastInvokeTime.current;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (\n !lastCallTime.current ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxing && timeSinceLastInvoke >= (maxWait || 0))\n );\n };\n\n const trailingEdge = (time: number) => {\n timerId.current = null;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs.current) {\n return invokeFunc(time);\n }\n\n lastArgs.current = lastThis.current = null;\n return result.current;\n };\n\n const timerExpired = () => {\n const time = Date.now();\n\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // https://github.com/xnimorz/use-debounce/issues/97\n if (!mounted.current) {\n return;\n }\n // Remaining wait calculation\n const timeSinceLastCall = time - (lastCallTime.current || 0);\n const timeSinceLastInvoke = time - lastInvokeTime.current;\n const timeWaiting = wait - timeSinceLastCall;\n const remainingWait = maxing\n ? Math.min(timeWaiting, (maxWait || 0) - timeSinceLastInvoke)\n : timeWaiting;\n\n // Restart the timer\n startTimer(timerExpired, remainingWait);\n };\n\n const func: DebouncedState<T> = (...args: Parameters<T>): ReturnType<T> => {\n if (!canUseDOM && !debounceOnServer) {\n // TODO: Fixme\n return undefined!;\n }\n\n const time = Date.now();\n const isInvoking = shouldInvoke(time);\n\n lastArgs.current = args;\n lastThis.current = this;\n lastCallTime.current = time;\n\n if (flushOnExit && !visibilityListener.current) {\n visibilityListener.current = () => {\n if (globalThis.document?.visibilityState === \"hidden\") {\n debouncedRef.current?.flush();\n }\n };\n globalThis.document?.addEventListener?.(\n \"visibilitychange\",\n visibilityListener.current,\n );\n }\n if (isInvoking) {\n if (!timerId.current && mounted.current) {\n // Reset any `maxWait` timer.\n lastInvokeTime.current = lastCallTime.current;\n // Start the timer for the trailing edge.\n startTimer(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(lastCallTime.current) : result.current!;\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n startTimer(timerExpired, wait);\n return invokeFunc(lastCallTime.current);\n }\n }\n if (!timerId.current) {\n startTimer(timerExpired, wait);\n }\n return result.current!;\n };\n\n func.cancel = () => {\n if (timerId.current) {\n useRAF\n ? cancelAnimationFrame(timerId.current!)\n : clearTimeout(timerId.current!);\n }\n lastInvokeTime.current = 0;\n lastArgs.current =\n lastCallTime.current =\n lastThis.current =\n timerId.current =\n null;\n };\n\n func.isPending = () => {\n return !!timerId.current;\n };\n\n func.flush = () => {\n return !timerId.current ? result.current : trailingEdge(Date.now());\n };\n\n return func;\n }, [\n leading,\n maxing,\n wait,\n maxWait,\n trailing,\n flushOnExit,\n useRAF,\n debounceOnServer,\n ]);\n\n // Store reference to debounced function for cleanup\n debouncedRef.current = debounced;\n\n React.useEffect(() => {\n mounted.current = true;\n return () => {\n if (flushOnExit) {\n debouncedRef.current?.flush();\n }\n if (visibilityListener.current) {\n globalThis.document?.removeEventListener?.(\n \"visibilitychange\",\n visibilityListener.current,\n );\n visibilityListener.current = null;\n }\n mounted.current = false;\n };\n }, [flushOnExit]);\n\n return debounced;\n}\n\ninterface CallOptions {\n /**\n * Controls if the function should be invoked on the leading edge of the timeout.\n */\n leading?: boolean;\n /**\n * Controls if the function should be invoked on the trailing edge of the timeout.\n */\n trailing?: boolean;\n /**\n * Controls if the function should be invoked when the React component unmounts or\n * the page is closed. This is usually desirable whenever `func` has persistent side-effects\n * such as persists data.\n *\n * NOTE: If the callback calls `fetch()`, you usually also want to specify the `keepalive=true`\n * option for `fetch()` so it can finish in the background after the page is closed.\n *\n * This option has no effect if `trailing == false`.\n */\n flushOnExit?: boolean;\n}\n\ninterface Options extends CallOptions {\n /**\n * The maximum time the given function is allowed to be delayed before it's invoked.\n */\n maxWait?: number;\n /**\n * If the setting is set to true, all debouncing and timers will happen on the server side as well\n */\n debounceOnServer?: boolean;\n}\n\ninterface ControlFunctions<ReturnT> {\n /**\n * Cancel pending function invocations\n */\n cancel: () => void;\n /**\n * Immediately invoke pending function invocations\n */\n flush: () => ReturnT | undefined;\n /**\n * Returns `true` if there are any pending function invocations\n */\n isPending: () => boolean;\n}\n\n/**\n * Subsequent calls to the debounced function return the result of the last func invocation.\n * Note, that if there are no previous invocations you will get undefined. You should check it in your code properly.\n */\ninterface DebouncedState<\n T extends (...args: any) => ReturnType<T>,\n> extends ControlFunctions<ReturnType<T>> {\n (...args: Parameters<T>): ReturnType<T> | undefined;\n}\n\nexport { useDebouncedCallback };\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-debounce.js","names":[],"sources":["../../../src/lib/use-debounce.ts"],"sourcesContent":["// Fork of https://github.com/xnimorz/use-debounce\n// MIT License, Copyright (c) 2018 Nikita Mostovoy\nimport * as React from \"react\";\nimport { useLayoutEffect } from \"./use-layout-effect.js\";\nimport { canUseDOM } from \"./utils.js\";\n\ninterface Options {\n /**\n * The number of milliseconds to delay. if omitted, invocation is deferred to\n * the next animation frame (or the next tick where that's unavailable).\n */\n wait?: number;\n /**\n * Controls if the function should be invoked on the leading edge of the\n * timeout.\n * @default false\n */\n leading?: boolean;\n /**\n * Controls if the function should be invoked on the trailing edge of the\n * timeout.\n * @default true\n */\n trailing?: boolean;\n /**\n * Controls if the function should be invoked when the React component\n * unmounts or the page is closed. This is usually desirable whenever `func`\n * has persistent side-effects such as persists data.\n *\n * NOTE: If the callback calls `fetch()`, you usually also want to specify the\n * `keepalive=true` option for `fetch()` so it can finish in the background\n * after the page is closed.\n *\n * This option has no effect if `trailing == false`.\n *\n * @default false\n */\n flushOnExit?: boolean;\n /**\n * The maximum time the given function is allowed to be delayed before it's\n * invoked. Pass `null` and the maximum wait time is equal to the `wait` time.\n */\n maxWait?: number | null;\n /**\n * If the setting is set to true, all debouncing and timers will happen on the\n * server side as well.\n *\n * @default false\n */\n debounceOnServer?: boolean;\n}\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked, or until the next browser frame is drawn.\n *\n * The debounced function comes with a `cancel` method to cancel delayed `func`\n * invocations and a `flush` method to immediately invoke them.\n *\n * Provide `options` to indicate whether `func` should be invoked on the leading\n * and/or trailing edge of the `wait` timeout. The `func` is invoked with the\n * last arguments provided to the debounced function.\n *\n * Subsequent calls to the debounced function return the result of the last\n * `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is invoked\n * more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * See [David Corbacho's\n * article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `debounce` and `throttle`.\n *\n * @param func The function to debounce\n * @param options The options object\n * @returns Returns the new debounced function.\n * @example\n * ```tsx\n * // Avoid costly calculations while the window size is in flux.\n * const resizeHandler = useDebouncedCallback(calculateLayout, { wait: 150 });\n * window.addEventListener('resize', resizeHandler)\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * const clickHandler = useDebouncedCallback(sendMail, {\n * wait: 300,\n * leading: true,\n * trailing: false,\n * })\n * <button onClick={clickHandler}>click me</button>\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * const debounced = useDebouncedCallback(batchLog, { wait: 250, maxWait: 1000 })\n * const source = new EventSource('/stream')\n * source.addEventListener('message', debounced)\n *\n * // Cancel the trailing debounced invocation.\n * window.addEventListener('popstate', debounced.cancel)\n *\n * // Check for pending invocations.\n * const status = debounced.isPending() ? \"Pending...\" : \"Ready\"\n * ```\n */\nfunction useDebouncedCallback<T extends (...args: any) => ReturnType<T>>(\n func: T,\n options: Options = {},\n): DebouncedState<T> {\n const {\n wait = 0,\n leading = false,\n trailing = true,\n maxWait: maxWaitOption,\n debounceOnServer = false,\n } = options;\n // Bypass `requestAnimationFrame` by explicitly setting `wait: 0`.\n const useRAF = options.wait === undefined && canUseDOM;\n const flushOnExit = !!options.flushOnExit && trailing;\n const maxWait =\n maxWaitOption === undefined ? null : Math.max(maxWaitOption ?? 0, wait);\n\n const stateRef = React.useRef<DebounceState<T>>({\n func,\n lastCallTime: null,\n lastInvokeTime: 0,\n timerId: null,\n lastArgs: null,\n lastThis: undefined,\n result: undefined,\n mounted: true,\n visibilityListener: null,\n debounced: undefined,\n });\n\n const debounced = React.useMemo(() => {\n const config: DebounceConfig = {\n wait,\n maxWait,\n leading,\n trailing,\n flushOnExit,\n useRAF,\n debounceOnServer,\n };\n const debounced: DebouncedState<T> = function (\n this: unknown,\n ...args: Parameters<T>\n ) {\n return debounce(stateRef.current, config, this, args);\n };\n debounced.cancel = () => cancel(stateRef.current, config);\n debounced.isPending = () => !!stateRef.current.timerId;\n debounced.flush = () => flush(stateRef.current, config);\n return debounced;\n }, [wait, maxWait, leading, trailing, flushOnExit, useRAF, debounceOnServer]);\n\n useLayoutEffect(() => {\n stateRef.current.func = func;\n stateRef.current.debounced = debounced;\n });\n\n React.useEffect(() => {\n const state = stateRef.current;\n state.mounted = true;\n return () => {\n if (flushOnExit) {\n state.debounced?.flush();\n }\n if (state.visibilityListener) {\n globalThis.document?.removeEventListener?.(\n \"visibilitychange\",\n state.visibilityListener,\n );\n state.visibilityListener = null;\n }\n state.mounted = false;\n };\n }, [flushOnExit]);\n\n return debounced;\n}\n\n/**\n * Mutable timer state for a hook instance. It outlives any single debounced\n * function, so changing options doesn't drop pending invocations.\n */\ninterface DebounceState<T extends (...args: any) => ReturnType<T>> {\n func: T;\n lastCallTime: number | null;\n lastInvokeTime: number;\n timerId: number | null;\n lastArgs: Parameters<T> | null;\n lastThis: unknown;\n result: ReturnType<T> | undefined;\n mounted: boolean;\n visibilityListener: VoidFunction | null;\n debounced: DebouncedState<T> | undefined;\n}\n\ninterface DebounceConfig {\n wait: number;\n maxWait: number | null;\n leading: boolean;\n trailing: boolean;\n flushOnExit: boolean;\n useRAF: boolean;\n debounceOnServer: boolean;\n}\n\nfunction invokeFunc<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n time: number,\n) {\n const args = state.lastArgs;\n const thisArg = state.lastThis;\n state.lastArgs = state.lastThis = null;\n state.lastInvokeTime = time;\n\n return (state.result = state.func.apply(thisArg, args || []));\n}\n\nfunction startTimer<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n config: DebounceConfig,\n wait: number,\n) {\n const onTimer = () => timerExpired(state, config);\n if (config.useRAF) {\n cancelAnimationFrame(state.timerId!);\n }\n state.timerId = config.useRAF\n ? requestAnimationFrame(onTimer)\n : (setTimeout(onTimer, wait) as unknown as number);\n}\n\nfunction shouldInvoke<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n { wait, maxWait }: DebounceConfig,\n time: number,\n) {\n if (!state.mounted) return false;\n\n const timeSinceLastCall = time - (state.lastCallTime || 0);\n const timeSinceLastInvoke = time - state.lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (\n !state.lastCallTime ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxWait !== null && timeSinceLastInvoke >= maxWait)\n );\n}\n\nfunction trailingEdge<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n config: DebounceConfig,\n time: number,\n) {\n state.timerId = null;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (config.trailing && state.lastArgs) {\n return invokeFunc(state, time);\n }\n\n state.lastArgs = state.lastThis = null;\n return state.result;\n}\n\nfunction timerExpired<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n config: DebounceConfig,\n) {\n const time = Date.now();\n\n if (shouldInvoke(state, config, time)) {\n trailingEdge(state, config, time);\n return;\n }\n // https://github.com/xnimorz/use-debounce/issues/97\n if (!state.mounted) {\n return;\n }\n // Remaining wait calculation\n const timeSinceLastCall = time - (state.lastCallTime || 0);\n const timeSinceLastInvoke = time - state.lastInvokeTime;\n const timeWaiting = config.wait - timeSinceLastCall;\n const remainingWait =\n config.maxWait !== null\n ? Math.min(timeWaiting, config.maxWait - timeSinceLastInvoke)\n : timeWaiting;\n\n // Restart the timer\n startTimer(state, config, remainingWait);\n}\n\nfunction debounce<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n config: DebounceConfig,\n thisArg: unknown,\n args: Parameters<T>,\n): ReturnType<T> | undefined {\n if (!canUseDOM && !config.debounceOnServer) {\n return undefined;\n }\n\n const time = Date.now();\n const isInvoking = shouldInvoke(state, config, time);\n\n state.lastArgs = args;\n state.lastThis = thisArg;\n state.lastCallTime = time;\n\n if (config.flushOnExit && !state.visibilityListener) {\n state.visibilityListener = () => {\n if (globalThis.document?.visibilityState === \"hidden\") {\n state.debounced?.flush();\n }\n };\n globalThis.document?.addEventListener?.(\n \"visibilitychange\",\n state.visibilityListener,\n );\n }\n if (isInvoking) {\n if (!state.timerId && state.mounted) {\n // Reset any `maxWait` timer.\n state.lastInvokeTime = time;\n // Start the timer for the trailing edge.\n startTimer(state, config, config.wait);\n // Invoke the leading edge.\n return config.leading ? invokeFunc(state, time) : state.result;\n }\n if (config.maxWait !== null) {\n // Handle invocations in a tight loop.\n startTimer(state, config, config.wait);\n return invokeFunc(state, time);\n }\n }\n if (!state.timerId) {\n startTimer(state, config, config.wait);\n }\n return state.result;\n}\n\nfunction cancel<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n config: DebounceConfig,\n) {\n if (state.timerId) {\n if (config.useRAF) {\n cancelAnimationFrame(state.timerId);\n } else {\n clearTimeout(state.timerId);\n }\n }\n state.lastInvokeTime = 0;\n state.lastArgs = state.lastCallTime = state.lastThis = state.timerId = null;\n}\n\nfunction flush<T extends (...args: any) => ReturnType<T>>(\n state: DebounceState<T>,\n config: DebounceConfig,\n) {\n return !state.timerId\n ? state.result\n : trailingEdge(state, config, Date.now());\n}\n\ninterface ControlFunctions<ReturnT> {\n /**\n * Cancel pending function invocations\n */\n cancel: () => void;\n /**\n * Immediately invoke pending function invocations\n */\n flush: () => ReturnT | undefined;\n /**\n * Returns `true` if there are any pending function invocations\n */\n isPending: () => boolean;\n}\n\n/**\n * Subsequent calls to the debounced function return the result of the last func invocation.\n * Note, that if there are no previous invocations you will get undefined. You should check it in your code properly.\n */\ninterface DebouncedState<\n T extends (...args: any) => ReturnType<T>,\n> extends ControlFunctions<ReturnType<T>> {\n (...args: Parameters<T>): ReturnType<T> | undefined;\n}\n\nexport { useDebouncedCallback };\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-widgets-invalidator.d.ts","names":[],"sources":["../../../src/lib/use-widgets-invalidator.ts"],"mappings":";iBAmBS,+BAAqB"}
1
+ {"version":3,"file":"use-widgets-invalidator.d.ts","names":[],"sources":["../../../src/lib/use-widgets-invalidator.ts"],"mappings":";iBAeS,+BAAqB"}
@@ -1,4 +1,5 @@
1
- import { isClientGraphqlQueryKey } from "../api/client-graphql/hooks.js";
1
+ import { isClientGraphqlQueryKey } from "../api/client-graphql/query-keys.js";
2
+ import "../api/client-graphql/hooks.js";
2
3
  import { useQueryClient } from "@tanstack/react-query";
3
4
  import * as React from "react";
4
5
  //#region src/lib/use-widgets-invalidator.ts
@@ -6,7 +7,6 @@ function useWidgetsInvalidatorImpl() {
6
7
  const queryClient = useQueryClient();
7
8
  return React.useCallback(async () => {
8
9
  await queryClient.invalidateQueries({ queryKey: ["authToken"] });
9
- await new Promise((resolve) => setTimeout(resolve, 1));
10
10
  return queryClient.invalidateQueries({ predicate: (query) => isClientGraphqlQueryKey(query.queryKey) });
11
11
  }, [queryClient]);
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-widgets-invalidator.js","names":[],"sources":["../../../src/lib/use-widgets-invalidator.ts"],"sourcesContent":["import { useQueryClient } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport { isClientGraphqlQueryKey } from \"../api/client-graphql/hooks.js\";\n\nfunction useWidgetsInvalidatorImpl() {\n const queryClient = useQueryClient();\n\n return React.useCallback(async () => {\n await queryClient.invalidateQueries({ queryKey: [\"authToken\"] });\n // TODO: Unclear why, but invalidating other widgets' queries immediately\n // after the authToken invalidation (even though it's async?) doesn't work,\n // and We end up with stale data. Waiting for the next tick fixes this.\n await new Promise((resolve) => setTimeout(resolve, 1));\n return queryClient.invalidateQueries({\n predicate: (query) => isClientGraphqlQueryKey(query.queryKey),\n });\n }, [queryClient]);\n}\n\nfunction useWidgetsInvalidator() {\n try {\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n return useWidgetsInvalidatorImpl();\n } catch {\n throw Error(\n \"useWidgetsInvalidation must be used within the `WorkOsWidgets` provider component\",\n );\n }\n}\n\nexport { useWidgetsInvalidator };\n"],"mappings":";;;;AAIA,SAAS,4BAA4B;CACnC,MAAM,cAAc,eAAe;CAEnC,OAAO,MAAM,YAAY,YAAY;EACnC,MAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC;EAI/D,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,CAAC,CAAC;EACrD,OAAO,YAAY,kBAAkB,EACnC,YAAY,UAAU,wBAAwB,MAAM,QAAQ,EAC9D,CAAC;CACH,GAAG,CAAC,WAAW,CAAC;AAClB;AAEA,SAAS,wBAAwB;CAC/B,IAAI;EAEF,OAAO,0BAA0B;CACnC,QAAQ;EACN,MAAM,MACJ,mFACF;CACF;AACF"}
1
+ {"version":3,"file":"use-widgets-invalidator.js","names":[],"sources":["../../../src/lib/use-widgets-invalidator.ts"],"sourcesContent":["import { useQueryClient } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport { isClientGraphqlQueryKey } from \"../api/client-graphql/hooks.js\";\n\nfunction useWidgetsInvalidatorImpl() {\n const queryClient = useQueryClient();\n\n return React.useCallback(async () => {\n await queryClient.invalidateQueries({ queryKey: [\"authToken\"] });\n return queryClient.invalidateQueries({\n predicate: (query) => isClientGraphqlQueryKey(query.queryKey),\n });\n }, [queryClient]);\n}\n\nfunction useWidgetsInvalidator() {\n try {\n // oxlint-disable-next-line react-hooks/rules-of-hooks\n return useWidgetsInvalidatorImpl();\n } catch {\n throw Error(\n \"useWidgetsInvalidation must be used within the `WorkOsWidgets` provider component\",\n );\n }\n}\n\nexport { useWidgetsInvalidator };\n"],"mappings":";;;;;AAIA,SAAS,4BAA4B;CACnC,MAAM,cAAc,eAAe;CAEnC,OAAO,MAAM,YAAY,YAAY;EACnC,MAAM,YAAY,kBAAkB,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC;EAC/D,OAAO,YAAY,kBAAkB,EACnC,YAAY,UAAU,wBAAwB,MAAM,QAAQ,EAC9D,CAAC;CACH,GAAG,CAAC,WAAW,CAAC;AAClB;AAEA,SAAS,wBAAwB;CAC/B,IAAI;EAEF,OAAO,0BAA0B;CACnC,QAAQ;EACN,MAAM,MACJ,mFACF;CACF;AACF"}
@@ -1,8 +1,5 @@
1
1
  //#region src/lib/utils.d.ts
2
2
  export declare const canUseDOM: boolean;
3
- export declare function composeEventHandlers<E extends {
4
- defaultPrevented: boolean;
5
- }>(originalEventHandler?: (event: E) => void, ourEventHandler?: (event: E) => void): (event: E) => void;
6
3
  export declare function getBestName({ firstName, lastName }: {
7
4
  firstName?: string | null | undefined;
8
5
  lastName?: string | null | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/lib/utils.ts"],"mappings":";qBAAa;wBAMG,qBAAqB;EAAY;GAC/C,wBAAwB,OAAO,YAC/B,mBAAmB,OAAO,cAAU,OAED;wBAQrB,cACd,WACA;EAEA;EACA;;wBAKc,aAAa,iBAAiB;wBAI9B,YAAY,iBAAiB,SAAS;wBAWtC,cAAc,iBAAiB,SAAS;;;;;;wBAWxC,eACd,cACA;EAAW;EAA4B;EAAiB"}
1
+ {"version":3,"file":"utils.d.ts","names":[],"sources":["../../../src/lib/utils.ts"],"mappings":";qBAAa;wBAMG,cACd,WACA;EAEA;EACA;;wBAKc,aAAa,iBAAiB;wBAI9B,YAAY,iBAAiB,SAAS;wBAWtC,cAAc,iBAAiB,SAAS;;;;;;wBAWxC,eACd,cACA;EAAW;EAA4B;EAAiB"}
@@ -1,11 +1,5 @@
1
1
  //#region src/lib/utils.ts
2
2
  const canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement);
3
- function composeEventHandlers(originalEventHandler, ourEventHandler) {
4
- return function handleEvent(event) {
5
- originalEventHandler?.(event);
6
- if (!event || !event.defaultPrevented) return ourEventHandler?.(event);
7
- };
8
- }
9
3
  function getBestName({ firstName, lastName }) {
10
4
  return [firstName, lastName].filter(Boolean).join(" ") || null;
11
5
  }
@@ -53,6 +47,6 @@ function openUrlViaForm(href, options) {
53
47
  document.body.removeChild(form);
54
48
  }
55
49
  //#endregion
56
- export { canUseDOM, composeEventHandlers, getBestName, isErrorLike, isObjectLike, isPromiseLike, openUrlViaForm };
50
+ export { canUseDOM, getBestName, isErrorLike, isObjectLike, isPromiseLike, openUrlViaForm };
57
51
 
58
52
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":[],"sources":["../../../src/lib/utils.ts"],"sourcesContent":["export const canUseDOM = !!(\n typeof window !== \"undefined\" &&\n window.document &&\n window.document.createElement\n);\n\nexport function composeEventHandlers<E extends { defaultPrevented: boolean }>(\n originalEventHandler?: (event: E) => void,\n ourEventHandler?: (event: E) => void,\n) {\n return function handleEvent(event: E) {\n originalEventHandler?.(event);\n if (!event || !event.defaultPrevented) {\n return ourEventHandler?.(event);\n }\n };\n}\n\nexport function getBestName({\n firstName,\n lastName,\n}: {\n firstName?: string | null | undefined;\n lastName?: string | null | undefined;\n}) {\n return [firstName, lastName].filter(Boolean).join(\" \") || null;\n}\n\nexport function isObjectLike(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isErrorLike(value: unknown): value is Error {\n return (\n isObjectLike(value) &&\n \"message\" in value &&\n typeof value.message === \"string\" &&\n \"name\" in value &&\n typeof value.name === \"string\" &&\n (!(\"stack\" in value && value.stack) || typeof value.stack === \"string\")\n );\n}\n\nexport function isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n isObjectLike(value) && \"then\" in value && typeof value.then === \"function\"\n );\n}\n\n/**\n * Opens links via form submission instead of URL query parameters. This keeps\n * sensitive parameters in the request body rather than the URL, reducing\n * exposure in server logs, browser history, and referrer headers.\n */\nexport function openUrlViaForm(\n href: string,\n options: { sensitiveParams?: string[]; target?: string; rel?: string },\n): void {\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n throw new TypeError(\"Invalid URL\");\n }\n\n let { target, rel, sensitiveParams = [] } = options;\n\n // API tokens are always treated as sensitive parameters\n sensitiveParams = [...sensitiveParams, \"apiToken\"];\n\n const form = document.createElement(\"form\");\n form.method = \"POST\";\n if (target) {\n form.target = target;\n }\n\n if (!rel && target === \"_blank\") {\n rel = \"noopener noreferrer\";\n }\n\n if (rel) {\n form.rel = rel;\n }\n\n for (const paramName of sensitiveParams) {\n const paramValue = url.searchParams.get(paramName);\n if (paramValue === null) {\n continue;\n }\n\n url.searchParams.delete(paramName);\n const fieldInput = document.createElement(\"input\");\n fieldInput.type = \"hidden\";\n fieldInput.name = paramName;\n fieldInput.value = paramValue;\n form.appendChild(fieldInput);\n }\n\n const formAction = url.toString();\n form.action = formAction;\n document.body.appendChild(form);\n form.submit();\n document.body.removeChild(form);\n}\n"],"mappings":";AAAA,MAAa,YAAY,CAAC,EACxB,OAAO,WAAW,eAClB,OAAO,YACP,OAAO,SAAS;AAGlB,SAAgB,qBACd,sBACA,iBACA;CACA,OAAO,SAAS,YAAY,OAAU;EACpC,uBAAuB,KAAK;EAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,kBACnB,OAAO,kBAAkB,KAAK;CAElC;AACF;AAEA,SAAgB,YAAY,EAC1B,WACA,YAIC;CACD,OAAO,CAAC,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK;AAC5D;AAEA,SAAgB,aAAa,OAAiC;CAC5D,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAgB,YAAY,OAAgC;CAC1D,OACE,aAAa,KAAK,KAClB,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,UAAU,SACV,OAAO,MAAM,SAAS,aACrB,EAAE,WAAW,SAAS,MAAM,UAAU,OAAO,MAAM,UAAU;AAElE;AAEA,SAAgB,cAAc,OAA+C;CAC3E,OACE,aAAa,KAAK,KAAK,UAAU,SAAS,OAAO,MAAM,SAAS;AAEpE;;;;;;AAOA,SAAgB,eACd,MACA,SACM;CACN,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,IAAI;CACpB,QAAQ;EACN,MAAM,IAAI,UAAU,aAAa;CACnC;CAEA,IAAI,EAAE,QAAQ,KAAK,kBAAkB,CAAC,MAAM;CAG5C,kBAAkB,CAAC,GAAG,iBAAiB,UAAU;CAEjD,MAAM,OAAO,SAAS,cAAc,MAAM;CAC1C,KAAK,SAAS;CACd,IAAI,QACF,KAAK,SAAS;CAGhB,IAAI,CAAC,OAAO,WAAW,UACrB,MAAM;CAGR,IAAI,KACF,KAAK,MAAM;CAGb,KAAK,MAAM,aAAa,iBAAiB;EACvC,MAAM,aAAa,IAAI,aAAa,IAAI,SAAS;EACjD,IAAI,eAAe,MACjB;EAGF,IAAI,aAAa,OAAO,SAAS;EACjC,MAAM,aAAa,SAAS,cAAc,OAAO;EACjD,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,WAAW,QAAQ;EACnB,KAAK,YAAY,UAAU;CAC7B;CAGA,KAAK,SADc,IAAI,SACT;CACd,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,OAAO;CACZ,SAAS,KAAK,YAAY,IAAI;AAChC"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/lib/utils.ts"],"sourcesContent":["export const canUseDOM = !!(\n typeof window !== \"undefined\" &&\n window.document &&\n window.document.createElement\n);\n\nexport function getBestName({\n firstName,\n lastName,\n}: {\n firstName?: string | null | undefined;\n lastName?: string | null | undefined;\n}) {\n return [firstName, lastName].filter(Boolean).join(\" \") || null;\n}\n\nexport function isObjectLike(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\nexport function isErrorLike(value: unknown): value is Error {\n return (\n isObjectLike(value) &&\n \"message\" in value &&\n typeof value.message === \"string\" &&\n \"name\" in value &&\n typeof value.name === \"string\" &&\n (!(\"stack\" in value && value.stack) || typeof value.stack === \"string\")\n );\n}\n\nexport function isPromiseLike(value: unknown): value is PromiseLike<unknown> {\n return (\n isObjectLike(value) && \"then\" in value && typeof value.then === \"function\"\n );\n}\n\n/**\n * Opens links via form submission instead of URL query parameters. This keeps\n * sensitive parameters in the request body rather than the URL, reducing\n * exposure in server logs, browser history, and referrer headers.\n */\nexport function openUrlViaForm(\n href: string,\n options: { sensitiveParams?: string[]; target?: string; rel?: string },\n): void {\n let url: URL;\n try {\n url = new URL(href);\n } catch {\n throw new TypeError(\"Invalid URL\");\n }\n\n let { target, rel, sensitiveParams = [] } = options;\n\n // API tokens are always treated as sensitive parameters\n sensitiveParams = [...sensitiveParams, \"apiToken\"];\n\n const form = document.createElement(\"form\");\n form.method = \"POST\";\n if (target) {\n form.target = target;\n }\n\n if (!rel && target === \"_blank\") {\n rel = \"noopener noreferrer\";\n }\n\n if (rel) {\n form.rel = rel;\n }\n\n for (const paramName of sensitiveParams) {\n const paramValue = url.searchParams.get(paramName);\n if (paramValue === null) {\n continue;\n }\n\n url.searchParams.delete(paramName);\n const fieldInput = document.createElement(\"input\");\n fieldInput.type = \"hidden\";\n fieldInput.name = paramName;\n fieldInput.value = paramValue;\n form.appendChild(fieldInput);\n }\n\n const formAction = url.toString();\n form.action = formAction;\n document.body.appendChild(form);\n form.submit();\n document.body.removeChild(form);\n}\n"],"mappings":";AAAA,MAAa,YAAY,CAAC,EACxB,OAAO,WAAW,eAClB,OAAO,YACP,OAAO,SAAS;AAGlB,SAAgB,YAAY,EAC1B,WACA,YAIC;CACD,OAAO,CAAC,WAAW,QAAQ,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK;AAC5D;AAEA,SAAgB,aAAa,OAAiC;CAC5D,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAgB,YAAY,OAAgC;CAC1D,OACE,aAAa,KAAK,KAClB,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,UAAU,SACV,OAAO,MAAM,SAAS,aACrB,EAAE,WAAW,SAAS,MAAM,UAAU,OAAO,MAAM,UAAU;AAElE;AAEA,SAAgB,cAAc,OAA+C;CAC3E,OACE,aAAa,KAAK,KAAK,UAAU,SAAS,OAAO,MAAM,SAAS;AAEpE;;;;;;AAOA,SAAgB,eACd,MACA,SACM;CACN,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,IAAI;CACpB,QAAQ;EACN,MAAM,IAAI,UAAU,aAAa;CACnC;CAEA,IAAI,EAAE,QAAQ,KAAK,kBAAkB,CAAC,MAAM;CAG5C,kBAAkB,CAAC,GAAG,iBAAiB,UAAU;CAEjD,MAAM,OAAO,SAAS,cAAc,MAAM;CAC1C,KAAK,SAAS;CACd,IAAI,QACF,KAAK,SAAS;CAGhB,IAAI,CAAC,OAAO,WAAW,UACrB,MAAM;CAGR,IAAI,KACF,KAAK,MAAM;CAGb,KAAK,MAAM,aAAa,iBAAiB;EACvC,MAAM,aAAa,IAAI,aAAa,IAAI,SAAS;EACjD,IAAI,eAAe,MACjB;EAGF,IAAI,aAAa,OAAO,SAAS;EACjC,MAAM,aAAa,SAAS,cAAc,OAAO;EACjD,WAAW,OAAO;EAClB,WAAW,OAAO;EAClB,WAAW,QAAQ;EACnB,KAAK,YAAY,UAAU;CAC7B;CAGA,KAAK,SADc,IAAI,SACT;CACd,SAAS,KAAK,YAAY,IAAI;CAC9B,KAAK,OAAO;CACZ,SAAS,KAAK,YAAY,IAAI;AAChC"}
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
  import { useWorkOsApiUrl } from "./lib/widgets-context.js";
3
+ import { clientGraphqlQueryKey } from "./api/client-graphql/query-keys.js";
3
4
  import { ApiProvider, useApiReady } from "./api/api-provider.js";
4
- import { clientGraphqlQueryKey, useClientGraphqlQuery } from "./api/client-graphql/hooks.js";
5
+ import { useClientGraphqlQuery } from "./api/client-graphql/hooks.js";
5
6
  import { ErrorBoundary } from "./components/error-boundary.js";
6
7
  import { OrganizationSwitcher as OrganizationSwitcher$1, OrganizationSwitcherError, OrganizationSwitcherLoading } from "./widgets/organization-switcher/organization-switcher.js";
7
8
  import { keepPreviousData } from "@tanstack/react-query";
@@ -1 +1 @@
1
- {"version":3,"file":"organization-switcher.client.js","names":["OrganizationSwitcherPresentational"],"sources":["../../src/organization-switcher.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { keepPreviousData } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport type { AuthToken } from \"./api/api-provider.js\";\nimport { ApiProvider, useApiReady } from \"./api/api-provider.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlQuery,\n} from \"./api/client-graphql/hooks.js\";\nimport { ErrorBoundary } from \"./components/error-boundary.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport type {\n OrganizationSwitcherErrorProps,\n OrganizationSwitcherLoadingProps,\n OrganizationSwitcherPassthroughProps,\n UserOrganization,\n} from \"./widgets/organization-switcher/organization-switcher.js\";\nimport {\n OrganizationSwitcherError,\n OrganizationSwitcherLoading,\n OrganizationSwitcher as OrganizationSwitcherPresentational,\n} from \"./widgets/organization-switcher/organization-switcher.js\";\n\ninterface OrganizationSwitcherProps extends OrganizationSwitcherPassthroughProps {\n authToken: AuthToken;\n}\n\nconst OrganizationSwitcher: React.FC<OrganizationSwitcherProps> = ({\n authToken,\n organizationLabel,\n switchToOrganization,\n truncateBehavior,\n variant,\n ...domProps\n}) => {\n const baseUrl = useWorkOsApiUrl();\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <OrganizationSwitcherError\n error={error}\n variant={variant}\n {...domProps}\n />\n )}\n >\n <ApiProvider\n widgetType=\"organization-switcher\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <OrganizationSwitcherImpl\n switchToOrganization={switchToOrganization}\n organizationLabel={organizationLabel}\n truncateBehavior={truncateBehavior}\n variant={variant}\n {...domProps}\n />\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\n// Constant reference to avoid unnecessary prop changes\nconst emptyOrganizations: UserOrganization[] = [];\n\ninterface OrganizationSwitcherImplProps extends OrganizationSwitcherPassthroughProps {}\n\nconst OrganizationSwitcherImpl: React.FC<OrganizationSwitcherImplProps> = ({\n variant,\n switchToOrganization,\n organizationLabel,\n truncateBehavior,\n children,\n ...domProps\n}) => {\n const isApiReady = useApiReady();\n const organizationsQuery = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListUserOrganizations\"),\n queryFn: (sdk) => sdk.ListUserOrganizations(),\n select: (data) => data.organizations,\n placeholderData: keepPreviousData,\n });\n\n const organizations = organizationsQuery.data ?? emptyOrganizations;\n\n if (organizationsQuery.isLoading || !isApiReady) {\n return <OrganizationSwitcherLoading variant={variant} {...domProps} />;\n }\n\n if (organizationsQuery.isError) {\n return (\n <OrganizationSwitcherError\n error={organizationsQuery.error}\n variant={variant}\n {...domProps}\n />\n );\n }\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <OrganizationSwitcherError\n error={error}\n variant={variant}\n {...domProps}\n />\n )}\n >\n <OrganizationSwitcherPresentational\n organizations={organizations}\n switchToOrganization={switchToOrganization}\n variant={variant}\n organizationLabel={organizationLabel}\n truncateBehavior={truncateBehavior}\n {...domProps}\n >\n {children}\n </OrganizationSwitcherPresentational>\n </ErrorBoundary>\n );\n};\n\nexport type {\n OrganizationSwitcherProps,\n OrganizationSwitcherLoadingProps,\n OrganizationSwitcherErrorProps,\n};\nexport {\n OrganizationSwitcher,\n OrganizationSwitcherLoading,\n OrganizationSwitcherError,\n};\n"],"mappings":";;;;;;;;;;AA4BA,MAAM,wBAA6D,EACjE,WACA,mBACA,sBACA,kBACA,SACA,GAAG,eACC;CACJ,MAAM,UAAU,gBAAgB;CAEhC,OACE,oBAAC,eAAD;EACE,iBAAiB,EAAE,YACjB,oBAAC,2BAAD;GACS;GACE;GACT,GAAI;EACL,CAAA;EAGH,UAAA,oBAAC,aAAD;GACE,YAAW;GACA;GACF;GAET,UAAA,oBAAC,0BAAD;IACwB;IACH;IACD;IACT;IACT,GAAI;GACL,CAAA;EACU,CAAA;CACA,CAAA;AAEnB;AAGA,MAAM,qBAAyC,CAAC;AAIhD,MAAM,4BAAqE,EACzE,SACA,sBACA,mBACA,kBACA,UACA,GAAG,eACC;CACJ,MAAM,aAAa,YAAY;CAC/B,MAAM,qBAAqB,sBAAsB;EAC/C,UAAU,sBAAsB,uBAAuB;EACvD,UAAU,QAAQ,IAAI,sBAAsB;EAC5C,SAAS,SAAS,KAAK;EACvB,iBAAiB;CACnB,CAAC;CAED,MAAM,gBAAgB,mBAAmB,QAAQ;CAEjD,IAAI,mBAAmB,aAAa,CAAC,YACnC,OAAO,oBAAC,6BAAD;EAAsC;EAAS,GAAI;CAAW,CAAA;CAGvE,IAAI,mBAAmB,SACrB,OACE,oBAAC,2BAAD;EACE,OAAO,mBAAmB;EACjB;EACT,GAAI;CACL,CAAA;CAIL,OACE,oBAAC,eAAD;EACE,iBAAiB,EAAE,YACjB,oBAAC,2BAAD;GACS;GACE;GACT,GAAI;EACL,CAAA;EAGH,UAAA,oBAACA,wBAAD;GACiB;GACO;GACb;GACU;GACD;GAClB,GAAI;GAEH;EACiC,CAAA;CACvB,CAAA;AAEnB"}
1
+ {"version":3,"file":"organization-switcher.client.js","names":["OrganizationSwitcherPresentational"],"sources":["../../src/organization-switcher.client.tsx"],"sourcesContent":["\"use client\";\n\nimport { keepPreviousData } from \"@tanstack/react-query\";\nimport * as React from \"react\";\nimport type { AuthToken } from \"./api/api-provider.js\";\nimport { ApiProvider, useApiReady } from \"./api/api-provider.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlQuery,\n} from \"./api/client-graphql/hooks.js\";\nimport { ErrorBoundary } from \"./components/error-boundary.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport type {\n OrganizationSwitcherErrorProps,\n OrganizationSwitcherLoadingProps,\n OrganizationSwitcherPassthroughProps,\n UserOrganization,\n} from \"./widgets/organization-switcher/organization-switcher.js\";\nimport {\n OrganizationSwitcherError,\n OrganizationSwitcherLoading,\n OrganizationSwitcher as OrganizationSwitcherPresentational,\n} from \"./widgets/organization-switcher/organization-switcher.js\";\n\ninterface OrganizationSwitcherProps extends OrganizationSwitcherPassthroughProps {\n authToken: AuthToken;\n}\n\nconst OrganizationSwitcher: React.FC<OrganizationSwitcherProps> = ({\n authToken,\n organizationLabel,\n switchToOrganization,\n truncateBehavior,\n variant,\n ...domProps\n}) => {\n const baseUrl = useWorkOsApiUrl();\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <OrganizationSwitcherError\n error={error}\n variant={variant}\n {...domProps}\n />\n )}\n >\n <ApiProvider\n widgetType=\"organization-switcher\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <OrganizationSwitcherImpl\n switchToOrganization={switchToOrganization}\n organizationLabel={organizationLabel}\n truncateBehavior={truncateBehavior}\n variant={variant}\n {...domProps}\n />\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\n// Constant reference to avoid unnecessary prop changes\nconst emptyOrganizations: UserOrganization[] = [];\n\ninterface OrganizationSwitcherImplProps extends OrganizationSwitcherPassthroughProps {}\n\nconst OrganizationSwitcherImpl: React.FC<OrganizationSwitcherImplProps> = ({\n variant,\n switchToOrganization,\n organizationLabel,\n truncateBehavior,\n children,\n ...domProps\n}) => {\n const isApiReady = useApiReady();\n const organizationsQuery = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListUserOrganizations\"),\n queryFn: (sdk) => sdk.ListUserOrganizations(),\n select: (data) => data.organizations,\n placeholderData: keepPreviousData,\n });\n\n const organizations = organizationsQuery.data ?? emptyOrganizations;\n\n if (organizationsQuery.isLoading || !isApiReady) {\n return <OrganizationSwitcherLoading variant={variant} {...domProps} />;\n }\n\n if (organizationsQuery.isError) {\n return (\n <OrganizationSwitcherError\n error={organizationsQuery.error}\n variant={variant}\n {...domProps}\n />\n );\n }\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <OrganizationSwitcherError\n error={error}\n variant={variant}\n {...domProps}\n />\n )}\n >\n <OrganizationSwitcherPresentational\n organizations={organizations}\n switchToOrganization={switchToOrganization}\n variant={variant}\n organizationLabel={organizationLabel}\n truncateBehavior={truncateBehavior}\n {...domProps}\n >\n {children}\n </OrganizationSwitcherPresentational>\n </ErrorBoundary>\n );\n};\n\nexport type {\n OrganizationSwitcherProps,\n OrganizationSwitcherLoadingProps,\n OrganizationSwitcherErrorProps,\n};\nexport {\n OrganizationSwitcher,\n OrganizationSwitcherLoading,\n OrganizationSwitcherError,\n};\n"],"mappings":";;;;;;;;;;;AA4BA,MAAM,wBAA6D,EACjE,WACA,mBACA,sBACA,kBACA,SACA,GAAG,eACC;CACJ,MAAM,UAAU,gBAAgB;CAEhC,OACE,oBAAC,eAAD;EACE,iBAAiB,EAAE,YACjB,oBAAC,2BAAD;GACS;GACE;GACT,GAAI;EACL,CAAA;EAGH,UAAA,oBAAC,aAAD;GACE,YAAW;GACA;GACF;GAET,UAAA,oBAAC,0BAAD;IACwB;IACH;IACD;IACT;IACT,GAAI;GACL,CAAA;EACU,CAAA;CACA,CAAA;AAEnB;AAGA,MAAM,qBAAyC,CAAC;AAIhD,MAAM,4BAAqE,EACzE,SACA,sBACA,mBACA,kBACA,UACA,GAAG,eACC;CACJ,MAAM,aAAa,YAAY;CAC/B,MAAM,qBAAqB,sBAAsB;EAC/C,UAAU,sBAAsB,uBAAuB;EACvD,UAAU,QAAQ,IAAI,sBAAsB;EAC5C,SAAS,SAAS,KAAK;EACvB,iBAAiB;CACnB,CAAC;CAED,MAAM,gBAAgB,mBAAmB,QAAQ;CAEjD,IAAI,mBAAmB,aAAa,CAAC,YACnC,OAAO,oBAAC,6BAAD;EAAsC;EAAS,GAAI;CAAW,CAAA;CAGvE,IAAI,mBAAmB,SACrB,OACE,oBAAC,2BAAD;EACE,OAAO,mBAAmB;EACjB;EACT,GAAI;CACL,CAAA;CAIL,OACE,oBAAC,eAAD;EACE,iBAAiB,EAAE,YACjB,oBAAC,2BAAD;GACS;GACE;GACT,GAAI;EACL,CAAA;EAGH,UAAA,oBAACA,wBAAD;GACiB;GACO;GACb;GACU;GACD;GAClB,GAAI;GAEH;EACiC,CAAA;CACvB,CAAA;AAEnB"}
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
  import { useWorkOsApiUrl } from "./lib/widgets-context.js";
3
3
  import { useIsHydrated } from "./lib/use-is-hydrated.js";
4
+ import { clientGraphqlQueryKey } from "./api/client-graphql/query-keys.js";
4
5
  import { ApiProvider } from "./api/api-provider.js";
5
- import { clientGraphqlQueryKey, useClientGraphqlQuery } from "./api/client-graphql/hooks.js";
6
+ import { useClientGraphqlQuery } from "./api/client-graphql/hooks.js";
6
7
  import { ErrorBoundary } from "./components/error-boundary.js";
7
8
  import { PipesCredentialUserIdContext } from "./widgets/pipes/pipes-credential-attribution.js";
8
9
  import { PipesAdmin as PipesAdmin$1, PipesAdminError, PipesAdminLoading, PipesAdminSections, useManageableIntegrations, useOrganizationOwnedIntegrations } from "./widgets/pipes-admin/pipes-admin.js";
@@ -1 +1 @@
1
- {"version":3,"file":"pipes-admin.client.js","names":["PipesAdminPresentational","PipesAdminSectionsPresentational"],"sources":["../../src/pipes-admin.client.tsx"],"sourcesContent":["\"use client\";\nimport type { AuthToken } from \"./api/api-provider.js\";\nimport { ApiProvider } from \"./api/api-provider.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlQuery,\n} from \"./api/client-graphql/hooks.js\";\nimport { ErrorBoundary } from \"./components/error-boundary.js\";\nimport { useIsHydrated } from \"./lib/use-is-hydrated.js\";\nimport type { WidgetRootDomProps } from \"./lib/widget-types.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport {\n PipesAdminError,\n PipesAdminLoading,\n PipesAdmin as PipesAdminPresentational,\n PipesAdminSections as PipesAdminSectionsPresentational,\n useManageableIntegrations,\n useOrganizationOwnedIntegrations,\n} from \"./widgets/pipes-admin/pipes-admin.js\";\nimport type {\n PipesAdminErrorProps,\n PipesAdminLoadingProps,\n} from \"./widgets/pipes-admin/pipes-admin.js\";\nimport { PipesCredentialUserIdContext } from \"./widgets/pipes/pipes-credential-attribution.js\";\n\ninterface PipesAdminProps extends WidgetRootDomProps {\n authToken: AuthToken;\n /**\n * The acting person's WorkOS user ID for shared API-key and client-credentials\n * writes with an application credential token. Required for those writes only.\n * User-backed sessions use the authenticated user; a different ID is rejected.\n * This prop is not rendered and does not grant authorization. The API validates\n * identity and organization membership.\n */\n userId?: string;\n /**\n * Opt in to the sectioned administrator experience: the connections the\n * organization owns and shares with everyone (which the administrator can\n * configure, connect, reauthorize and disconnect), followed by the provider\n * settings that govern what members may connect to on their own.\n *\n * The two sections are fetched separately, so provider settings render as\n * soon as they resolve regardless of the shared section.\n *\n * Defaults to `false`, which renders the single unsectioned provider\n * settings list and never requests organization-owned connections.\n */\n enableSharedConnections?: boolean;\n}\n\nconst PipesAdmin: React.FC<PipesAdminProps> = ({\n authToken,\n userId,\n enableSharedConnections,\n ...domProps\n}) => {\n const baseUrl = useWorkOsApiUrl();\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <PipesAdminError {...domProps} error={error} />\n )}\n >\n <ApiProvider\n widgetType=\"pipes-admin\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <PipesCredentialUserIdContext.Provider value={userId}>\n <PipesAdminImpl\n enableSharedConnections={enableSharedConnections}\n {...domProps}\n />\n </PipesCredentialUserIdContext.Provider>\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\ninterface PipesAdminImplProps extends Omit<\n PipesAdminProps,\n \"authToken\" | \"userId\"\n> {}\n\n// The two experiences are separate components so the opt-out path mounts no\n// organization-owned hook at all, and therefore issues exactly the requests it\n// always has.\nconst PipesAdminImpl: React.FC<PipesAdminImplProps> = ({\n enableSharedConnections,\n ...props\n}) => {\n return enableSharedConnections ? (\n <PipesAdminSectionsImpl {...props} />\n ) : (\n <PipesAdminProviderSettingsImpl {...props} />\n );\n};\n\ninterface PipesAdminProviderSettingsImplProps extends Omit<\n PipesAdminImplProps,\n \"enableSharedConnections\"\n> {}\n\nconst PipesAdminProviderSettingsImpl: React.FC<\n PipesAdminProviderSettingsImplProps\n> = (props) => {\n const isHydrated = useIsHydrated();\n const integrations = useManageableIntegrations();\n\n if (!isHydrated || integrations.isLoading) {\n return <PipesAdminLoading count={6} {...props} />;\n }\n\n if (integrations.isError) {\n return <PipesAdminError error={integrations.error} {...props} />;\n }\n\n return (\n <PipesAdminPresentational integrations={integrations.data} {...props} />\n );\n};\n\ninterface PipesAdminSectionsImplProps extends Omit<\n PipesAdminImplProps,\n \"enableSharedConnections\"\n> {}\n\nconst PipesAdminSectionsImpl: React.FC<PipesAdminSectionsImplProps> = (\n props,\n) => {\n const isHydrated = useIsHydrated();\n const integrations = useManageableIntegrations();\n // Both sections have their own cache entry and resolve independently:\n // provider settings render as soon as they arrive, and a slow or failing\n // organization request only affects the shared section.\n const shared = useOrganizationOwnedIntegrations();\n const organizations = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListUserOrganizations\"),\n queryFn: (sdk) => sdk.ListUserOrganizations(),\n });\n const organizationName = organizations.data?.organizations.find(\n (organization) => organization.isCurrent,\n )?.name;\n\n if (!isHydrated || integrations.isLoading) {\n return <PipesAdminLoading count={6} {...props} />;\n }\n\n if (integrations.isError) {\n return <PipesAdminError error={integrations.error} {...props} />;\n }\n\n return (\n <PipesAdminSectionsPresentational\n integrations={integrations.data}\n sharedIntegrations={shared.data}\n isSharedLoading={shared.isLoading}\n organizationName={organizationName}\n {...props}\n />\n );\n};\n\nexport type { PipesAdminProps, PipesAdminLoadingProps, PipesAdminErrorProps };\nexport { PipesAdmin, PipesAdminLoading, PipesAdminError };\n"],"mappings":";;;;;;;;;;AAkDA,MAAM,cAAyC,EAC7C,WACA,QACA,yBACA,GAAG,eACC;CACJ,MAAM,UAAU,gBAAgB;CAEhC,OACE,oBAAC,eAAD;EACE,iBAAiB,EAAE,YACjB,oBAAC,iBAAD;GAAiB,GAAI;GAAiB;EAAQ,CAAA;EAGhD,UAAA,oBAAC,aAAD;GACE,YAAW;GACA;GACF;GAET,UAAA,oBAAC,6BAA6B,UAA9B;IAAuC,OAAO;IAC5C,UAAA,oBAAC,gBAAD;KAC2B;KACzB,GAAI;IACL,CAAA;GACoC,CAAA;EAC5B,CAAA;CACA,CAAA;AAEnB;AAUA,MAAM,kBAAiD,EACrD,yBACA,GAAG,YACC;CACJ,OAAO,0BACL,oBAAC,wBAAD,EAAwB,GAAI,MAAQ,CAAA,IAEpC,oBAAC,gCAAD,EAAgC,GAAI,MAAQ,CAAA;AAEhD;AAOA,MAAM,kCAED,UAAU;CACb,MAAM,aAAa,cAAc;CACjC,MAAM,eAAe,0BAA0B;CAE/C,IAAI,CAAC,cAAc,aAAa,WAC9B,OAAO,oBAAC,mBAAD;EAAmB,OAAO;EAAG,GAAI;CAAQ,CAAA;CAGlD,IAAI,aAAa,SACf,OAAO,oBAAC,iBAAD;EAAiB,OAAO,aAAa;EAAO,GAAI;CAAQ,CAAA;CAGjE,OACE,oBAACA,cAAD;EAA0B,cAAc,aAAa;EAAM,GAAI;CAAQ,CAAA;AAE3E;AAOA,MAAM,0BACJ,UACG;CACH,MAAM,aAAa,cAAc;CACjC,MAAM,eAAe,0BAA0B;CAI/C,MAAM,SAAS,iCAAiC;CAKhD,MAAM,mBAJgB,sBAAsB;EAC1C,UAAU,sBAAsB,uBAAuB;EACvD,UAAU,QAAQ,IAAI,sBAAsB;CAC9C,CACyB,CAAA,CAAc,MAAM,cAAc,MACxD,iBAAiB,aAAa,SACjC,CAAC,EAAE;CAEH,IAAI,CAAC,cAAc,aAAa,WAC9B,OAAO,oBAAC,mBAAD;EAAmB,OAAO;EAAG,GAAI;CAAQ,CAAA;CAGlD,IAAI,aAAa,SACf,OAAO,oBAAC,iBAAD;EAAiB,OAAO,aAAa;EAAO,GAAI;CAAQ,CAAA;CAGjE,OACE,oBAACC,oBAAD;EACE,cAAc,aAAa;EAC3B,oBAAoB,OAAO;EAC3B,iBAAiB,OAAO;EACN;EAClB,GAAI;CACL,CAAA;AAEL"}
1
+ {"version":3,"file":"pipes-admin.client.js","names":["PipesAdminPresentational","PipesAdminSectionsPresentational"],"sources":["../../src/pipes-admin.client.tsx"],"sourcesContent":["\"use client\";\nimport type { AuthToken } from \"./api/api-provider.js\";\nimport { ApiProvider } from \"./api/api-provider.js\";\nimport {\n clientGraphqlQueryKey,\n useClientGraphqlQuery,\n} from \"./api/client-graphql/hooks.js\";\nimport { ErrorBoundary } from \"./components/error-boundary.js\";\nimport { useIsHydrated } from \"./lib/use-is-hydrated.js\";\nimport type { WidgetRootDomProps } from \"./lib/widget-types.js\";\nimport { useWorkOsApiUrl } from \"./lib/widgets-context.js\";\nimport {\n PipesAdminError,\n PipesAdminLoading,\n PipesAdmin as PipesAdminPresentational,\n PipesAdminSections as PipesAdminSectionsPresentational,\n useManageableIntegrations,\n useOrganizationOwnedIntegrations,\n} from \"./widgets/pipes-admin/pipes-admin.js\";\nimport type {\n PipesAdminErrorProps,\n PipesAdminLoadingProps,\n} from \"./widgets/pipes-admin/pipes-admin.js\";\nimport { PipesCredentialUserIdContext } from \"./widgets/pipes/pipes-credential-attribution.js\";\n\ninterface PipesAdminProps extends WidgetRootDomProps {\n authToken: AuthToken;\n /**\n * The acting person's WorkOS user ID for shared API-key and client-credentials\n * writes with an application credential token. Required for those writes only.\n * User-backed sessions use the authenticated user; a different ID is rejected.\n * This prop is not rendered and does not grant authorization. The API validates\n * identity and organization membership.\n */\n userId?: string;\n /**\n * Opt in to the sectioned administrator experience: the connections the\n * organization owns and shares with everyone (which the administrator can\n * configure, connect, reauthorize and disconnect), followed by the provider\n * settings that govern what members may connect to on their own.\n *\n * The two sections are fetched separately, so provider settings render as\n * soon as they resolve regardless of the shared section.\n *\n * Defaults to `false`, which renders the single unsectioned provider\n * settings list and never requests organization-owned connections.\n */\n enableSharedConnections?: boolean;\n}\n\nconst PipesAdmin: React.FC<PipesAdminProps> = ({\n authToken,\n userId,\n enableSharedConnections,\n ...domProps\n}) => {\n const baseUrl = useWorkOsApiUrl();\n\n return (\n <ErrorBoundary\n fallbackRender={({ error }) => (\n <PipesAdminError {...domProps} error={error} />\n )}\n >\n <ApiProvider\n widgetType=\"pipes-admin\"\n authToken={authToken}\n baseUrl={baseUrl}\n >\n <PipesCredentialUserIdContext.Provider value={userId}>\n <PipesAdminImpl\n enableSharedConnections={enableSharedConnections}\n {...domProps}\n />\n </PipesCredentialUserIdContext.Provider>\n </ApiProvider>\n </ErrorBoundary>\n );\n};\n\ninterface PipesAdminImplProps extends Omit<\n PipesAdminProps,\n \"authToken\" | \"userId\"\n> {}\n\n// The two experiences are separate components so the opt-out path mounts no\n// organization-owned hook at all, and therefore issues exactly the requests it\n// always has.\nconst PipesAdminImpl: React.FC<PipesAdminImplProps> = ({\n enableSharedConnections,\n ...props\n}) => {\n return enableSharedConnections ? (\n <PipesAdminSectionsImpl {...props} />\n ) : (\n <PipesAdminProviderSettingsImpl {...props} />\n );\n};\n\ninterface PipesAdminProviderSettingsImplProps extends Omit<\n PipesAdminImplProps,\n \"enableSharedConnections\"\n> {}\n\nconst PipesAdminProviderSettingsImpl: React.FC<\n PipesAdminProviderSettingsImplProps\n> = (props) => {\n const isHydrated = useIsHydrated();\n const integrations = useManageableIntegrations();\n\n if (!isHydrated || integrations.isLoading) {\n return <PipesAdminLoading count={6} {...props} />;\n }\n\n if (integrations.isError) {\n return <PipesAdminError error={integrations.error} {...props} />;\n }\n\n return (\n <PipesAdminPresentational integrations={integrations.data} {...props} />\n );\n};\n\ninterface PipesAdminSectionsImplProps extends Omit<\n PipesAdminImplProps,\n \"enableSharedConnections\"\n> {}\n\nconst PipesAdminSectionsImpl: React.FC<PipesAdminSectionsImplProps> = (\n props,\n) => {\n const isHydrated = useIsHydrated();\n const integrations = useManageableIntegrations();\n // Both sections have their own cache entry and resolve independently:\n // provider settings render as soon as they arrive, and a slow or failing\n // organization request only affects the shared section.\n const shared = useOrganizationOwnedIntegrations();\n const organizations = useClientGraphqlQuery({\n queryKey: clientGraphqlQueryKey(\"ListUserOrganizations\"),\n queryFn: (sdk) => sdk.ListUserOrganizations(),\n });\n const organizationName = organizations.data?.organizations.find(\n (organization) => organization.isCurrent,\n )?.name;\n\n if (!isHydrated || integrations.isLoading) {\n return <PipesAdminLoading count={6} {...props} />;\n }\n\n if (integrations.isError) {\n return <PipesAdminError error={integrations.error} {...props} />;\n }\n\n return (\n <PipesAdminSectionsPresentational\n integrations={integrations.data}\n sharedIntegrations={shared.data}\n isSharedLoading={shared.isLoading}\n organizationName={organizationName}\n {...props}\n />\n );\n};\n\nexport type { PipesAdminProps, PipesAdminLoadingProps, PipesAdminErrorProps };\nexport { PipesAdmin, PipesAdminLoading, PipesAdminError };\n"],"mappings":";;;;;;;;;;;AAkDA,MAAM,cAAyC,EAC7C,WACA,QACA,yBACA,GAAG,eACC;CACJ,MAAM,UAAU,gBAAgB;CAEhC,OACE,oBAAC,eAAD;EACE,iBAAiB,EAAE,YACjB,oBAAC,iBAAD;GAAiB,GAAI;GAAiB;EAAQ,CAAA;EAGhD,UAAA,oBAAC,aAAD;GACE,YAAW;GACA;GACF;GAET,UAAA,oBAAC,6BAA6B,UAA9B;IAAuC,OAAO;IAC5C,UAAA,oBAAC,gBAAD;KAC2B;KACzB,GAAI;IACL,CAAA;GACoC,CAAA;EAC5B,CAAA;CACA,CAAA;AAEnB;AAUA,MAAM,kBAAiD,EACrD,yBACA,GAAG,YACC;CACJ,OAAO,0BACL,oBAAC,wBAAD,EAAwB,GAAI,MAAQ,CAAA,IAEpC,oBAAC,gCAAD,EAAgC,GAAI,MAAQ,CAAA;AAEhD;AAOA,MAAM,kCAED,UAAU;CACb,MAAM,aAAa,cAAc;CACjC,MAAM,eAAe,0BAA0B;CAE/C,IAAI,CAAC,cAAc,aAAa,WAC9B,OAAO,oBAAC,mBAAD;EAAmB,OAAO;EAAG,GAAI;CAAQ,CAAA;CAGlD,IAAI,aAAa,SACf,OAAO,oBAAC,iBAAD;EAAiB,OAAO,aAAa;EAAO,GAAI;CAAQ,CAAA;CAGjE,OACE,oBAACA,cAAD;EAA0B,cAAc,aAAa;EAAM,GAAI;CAAQ,CAAA;AAE3E;AAOA,MAAM,0BACJ,UACG;CACH,MAAM,aAAa,cAAc;CACjC,MAAM,eAAe,0BAA0B;CAI/C,MAAM,SAAS,iCAAiC;CAKhD,MAAM,mBAJgB,sBAAsB;EAC1C,UAAU,sBAAsB,uBAAuB;EACvD,UAAU,QAAQ,IAAI,sBAAsB;CAC9C,CACyB,CAAA,CAAc,MAAM,cAAc,MACxD,iBAAiB,aAAa,SACjC,CAAC,EAAE;CAEH,IAAI,CAAC,cAAc,aAAa,WAC9B,OAAO,oBAAC,mBAAD;EAAmB,OAAO;EAAG,GAAI;CAAQ,CAAA;CAGlD,IAAI,aAAa,SACf,OAAO,oBAAC,iBAAD;EAAiB,OAAO,aAAa;EAAO,GAAI;CAAQ,CAAA;CAGjE,OACE,oBAACC,oBAAD;EACE,cAAc,aAAa;EAC3B,oBAAoB,OAAO;EAC3B,iBAAiB,OAAO;EACN;EAClB,GAAI;CACL,CAAA;AAEL"}
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
  import { useWorkOsApiUrl } from "./lib/widgets-context.js";
3
3
  import { useIsHydrated } from "./lib/use-is-hydrated.js";
4
+ import { clientGraphqlQueryKey } from "./api/client-graphql/query-keys.js";
4
5
  import { ApiProvider } from "./api/api-provider.js";
5
- import { clientGraphqlQueryKey, useClientGraphqlQuery } from "./api/client-graphql/hooks.js";
6
+ import { useClientGraphqlQuery } from "./api/client-graphql/hooks.js";
6
7
  import { ErrorBoundary } from "./components/error-boundary.js";
7
8
  import { useMyDataIntegrations, useSharedDataConnections } from "./lib/api/pipes.js";
8
9
  import { Pipes as Pipes$1, PipesError, PipesLoading, PipesSections } from "./widgets/pipes/pipes.js";