@microsoft/live-share-react 2.0.0-internal.2 → 2.0.0-internal.20

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 (252) hide show
  1. package/LICENSE +64 -61
  2. package/README.md +175 -164
  3. package/bin/esm/index.d.ts +7 -0
  4. package/bin/esm/index.d.ts.map +1 -0
  5. package/bin/esm/index.js +7 -0
  6. package/bin/esm/index.js.map +1 -0
  7. package/bin/esm/interfaces/LiveInterfaceExtensions.d.ts.map +1 -0
  8. package/bin/esm/interfaces/LiveInterfaceExtensions.js.map +1 -0
  9. package/bin/esm/interfaces/index.d.ts +2 -0
  10. package/bin/esm/interfaces/index.d.ts.map +1 -0
  11. package/bin/esm/interfaces/index.js +2 -0
  12. package/bin/esm/interfaces/index.js.map +1 -0
  13. package/bin/esm/internal/errors.d.ts.map +1 -0
  14. package/bin/esm/internal/errors.js.map +1 -0
  15. package/bin/esm/internal/index.d.ts +3 -0
  16. package/bin/esm/internal/index.d.ts.map +1 -0
  17. package/bin/esm/internal/index.js +3 -0
  18. package/bin/esm/internal/index.js.map +1 -0
  19. package/bin/{internal → esm/internal}/type-guards.d.ts +1 -1
  20. package/bin/esm/internal/type-guards.d.ts.map +1 -0
  21. package/bin/esm/internal/type-guards.js.map +1 -0
  22. package/bin/esm/live-hooks/index.d.ts +8 -0
  23. package/bin/esm/live-hooks/index.d.ts.map +1 -0
  24. package/bin/esm/live-hooks/index.js +8 -0
  25. package/bin/esm/live-hooks/index.js.map +1 -0
  26. package/bin/esm/live-hooks/useLiveCanvas.d.ts +80 -0
  27. package/bin/esm/live-hooks/useLiveCanvas.d.ts.map +1 -0
  28. package/bin/esm/live-hooks/useLiveCanvas.js +237 -0
  29. package/bin/esm/live-hooks/useLiveCanvas.js.map +1 -0
  30. package/bin/{live-hooks → esm/live-hooks}/useLiveEvent.d.ts +37 -1
  31. package/bin/esm/live-hooks/useLiveEvent.d.ts.map +1 -0
  32. package/bin/{live-hooks → esm/live-hooks}/useLiveEvent.js +45 -18
  33. package/bin/esm/live-hooks/useLiveEvent.js.map +1 -0
  34. package/bin/esm/live-hooks/useLiveFollowMode.d.ts +163 -0
  35. package/bin/esm/live-hooks/useLiveFollowMode.d.ts.map +1 -0
  36. package/bin/{live-hooks → esm/live-hooks}/useLiveFollowMode.js +173 -39
  37. package/bin/esm/live-hooks/useLiveFollowMode.js.map +1 -0
  38. package/bin/esm/live-hooks/useLivePresence.d.ts +76 -0
  39. package/bin/esm/live-hooks/useLivePresence.d.ts.map +1 -0
  40. package/bin/{live-hooks → esm/live-hooks}/useLivePresence.js +74 -25
  41. package/bin/esm/live-hooks/useLivePresence.js.map +1 -0
  42. package/bin/{live-hooks → esm/live-hooks}/useLiveState.d.ts +46 -1
  43. package/bin/esm/live-hooks/useLiveState.d.ts.map +1 -0
  44. package/bin/{live-hooks → esm/live-hooks}/useLiveState.js +58 -18
  45. package/bin/esm/live-hooks/useLiveState.js.map +1 -0
  46. package/bin/{live-hooks → esm/live-hooks}/useLiveTimer.d.ts +56 -1
  47. package/bin/esm/live-hooks/useLiveTimer.d.ts.map +1 -0
  48. package/bin/{live-hooks → esm/live-hooks}/useLiveTimer.js +80 -34
  49. package/bin/esm/live-hooks/useLiveTimer.js.map +1 -0
  50. package/bin/esm/live-hooks/useMediaSynchronizer.d.ts +86 -0
  51. package/bin/esm/live-hooks/useMediaSynchronizer.d.ts.map +1 -0
  52. package/bin/{live-hooks → esm/live-hooks}/useMediaSynchronizer.js +89 -37
  53. package/bin/esm/live-hooks/useMediaSynchronizer.js.map +1 -0
  54. package/bin/{providers → esm/providers}/AzureProvider.d.ts +9 -9
  55. package/bin/esm/providers/AzureProvider.d.ts.map +1 -0
  56. package/bin/{providers → esm/providers}/AzureProvider.js +28 -33
  57. package/bin/esm/providers/AzureProvider.js.map +1 -0
  58. package/bin/{providers → esm/providers}/LiveShareProvider.d.ts +106 -4
  59. package/bin/esm/providers/LiveShareProvider.d.ts.map +1 -0
  60. package/bin/esm/providers/LiveShareProvider.js +196 -0
  61. package/bin/esm/providers/LiveShareProvider.js.map +1 -0
  62. package/bin/esm/providers/index.d.ts +3 -0
  63. package/bin/esm/providers/index.d.ts.map +1 -0
  64. package/bin/esm/providers/index.js +3 -0
  65. package/bin/esm/providers/index.js.map +1 -0
  66. package/bin/esm/shared-hooks/index.d.ts +7 -0
  67. package/bin/esm/shared-hooks/index.d.ts.map +1 -0
  68. package/bin/esm/shared-hooks/index.js +7 -0
  69. package/bin/esm/shared-hooks/index.js.map +1 -0
  70. package/bin/esm/shared-hooks/internals/tree-node-constants.d.ts +3 -0
  71. package/bin/esm/shared-hooks/internals/tree-node-constants.d.ts.map +1 -0
  72. package/bin/esm/shared-hooks/internals/tree-node-constants.js +3 -0
  73. package/bin/esm/shared-hooks/internals/tree-node-constants.js.map +1 -0
  74. package/bin/esm/shared-hooks/internals/tree-node-types.d.ts +10 -0
  75. package/bin/esm/shared-hooks/internals/tree-node-types.d.ts.map +1 -0
  76. package/bin/esm/shared-hooks/internals/tree-node-types.js +18 -0
  77. package/bin/esm/shared-hooks/internals/tree-node-types.js.map +1 -0
  78. package/bin/esm/shared-hooks/internals/tree-node-utils.d.ts +33 -0
  79. package/bin/esm/shared-hooks/internals/tree-node-utils.d.ts.map +1 -0
  80. package/bin/esm/shared-hooks/internals/tree-node-utils.js +186 -0
  81. package/bin/esm/shared-hooks/internals/tree-node-utils.js.map +1 -0
  82. package/bin/{shared-hooks → esm/shared-hooks}/useDynamicDDS.d.ts +4 -4
  83. package/bin/esm/shared-hooks/useDynamicDDS.d.ts.map +1 -0
  84. package/bin/{shared-hooks → esm/shared-hooks}/useDynamicDDS.js +22 -22
  85. package/bin/esm/shared-hooks/useDynamicDDS.js.map +1 -0
  86. package/bin/{shared-hooks → esm/shared-hooks}/useSharedMap.d.ts +4 -2
  87. package/bin/esm/shared-hooks/useSharedMap.d.ts.map +1 -0
  88. package/bin/{shared-hooks → esm/shared-hooks}/useSharedMap.js +28 -14
  89. package/bin/esm/shared-hooks/useSharedMap.js.map +1 -0
  90. package/bin/{shared-hooks → esm/shared-hooks}/useSharedState.d.ts +1 -1
  91. package/bin/esm/shared-hooks/useSharedState.d.ts.map +1 -0
  92. package/bin/{shared-hooks → esm/shared-hooks}/useSharedState.js +2 -2
  93. package/bin/esm/shared-hooks/useSharedState.js.map +1 -0
  94. package/bin/{shared-hooks → esm/shared-hooks}/useSharedStateRegistry.d.ts +1 -1
  95. package/bin/esm/shared-hooks/useSharedStateRegistry.d.ts.map +1 -0
  96. package/bin/{shared-hooks → esm/shared-hooks}/useSharedStateRegistry.js +35 -24
  97. package/bin/esm/shared-hooks/useSharedStateRegistry.js.map +1 -0
  98. package/bin/esm/shared-hooks/useSharedTree.d.ts +57 -0
  99. package/bin/esm/shared-hooks/useSharedTree.d.ts.map +1 -0
  100. package/bin/esm/shared-hooks/useSharedTree.js +117 -0
  101. package/bin/esm/shared-hooks/useSharedTree.js.map +1 -0
  102. package/bin/esm/shared-hooks/useTreeNode.d.ts +96 -0
  103. package/bin/esm/shared-hooks/useTreeNode.d.ts.map +1 -0
  104. package/bin/esm/shared-hooks/useTreeNode.js +132 -0
  105. package/bin/esm/shared-hooks/useTreeNode.js.map +1 -0
  106. package/bin/{types → esm/types}/ActionTypes.d.ts +7 -7
  107. package/bin/esm/types/ActionTypes.d.ts.map +1 -0
  108. package/bin/esm/types/ActionTypes.js.map +1 -0
  109. package/bin/esm/types/FluidMap.d.ts +151 -0
  110. package/bin/esm/types/FluidMap.d.ts.map +1 -0
  111. package/bin/esm/types/FluidMap.js +24 -0
  112. package/bin/esm/types/FluidMap.js.map +1 -0
  113. package/bin/esm/types/PropTypes.d.ts +56 -0
  114. package/bin/esm/types/PropTypes.d.ts.map +1 -0
  115. package/bin/esm/types/PropTypes.js.map +1 -0
  116. package/bin/{types → esm/types}/ResultTypes.d.ts +62 -18
  117. package/bin/esm/types/ResultTypes.d.ts.map +1 -0
  118. package/bin/esm/types/ResultTypes.js.map +1 -0
  119. package/bin/esm/types/index.d.ts +4 -0
  120. package/bin/esm/types/index.d.ts.map +1 -0
  121. package/bin/esm/types/index.js +4 -0
  122. package/bin/esm/types/index.js.map +1 -0
  123. package/bin/esm/utils/index.d.ts +2 -0
  124. package/bin/esm/utils/index.d.ts.map +1 -0
  125. package/bin/esm/utils/index.js +2 -0
  126. package/bin/esm/utils/index.js.map +1 -0
  127. package/bin/esm/utils/type-check.d.ts.map +1 -0
  128. package/bin/{utils → esm/utils}/type-check.js +1 -1
  129. package/bin/esm/utils/type-check.js.map +1 -0
  130. package/package.json +51 -47
  131. package/src/index.ts +6 -6
  132. package/src/interfaces/index.ts +1 -1
  133. package/src/internal/index.ts +2 -2
  134. package/src/internal/type-guards.ts +1 -1
  135. package/src/live-hooks/index.ts +7 -7
  136. package/src/live-hooks/useLiveCanvas.ts +154 -82
  137. package/src/live-hooks/useLiveEvent.ts +43 -7
  138. package/src/live-hooks/useLiveFollowMode.ts +149 -6
  139. package/src/live-hooks/useLivePresence.ts +80 -17
  140. package/src/live-hooks/useLiveState.ts +54 -6
  141. package/src/live-hooks/useLiveTimer.ts +59 -4
  142. package/src/live-hooks/useMediaSynchronizer.ts +71 -6
  143. package/src/providers/AzureProvider.tsx +21 -21
  144. package/src/providers/LiveShareProvider.tsx +115 -13
  145. package/src/providers/index.ts +2 -2
  146. package/src/shared-hooks/index.ts +6 -4
  147. package/src/shared-hooks/internals/tree-node-constants.ts +2 -0
  148. package/src/shared-hooks/internals/tree-node-types.ts +26 -0
  149. package/src/shared-hooks/internals/tree-node-utils.ts +269 -0
  150. package/src/shared-hooks/useDynamicDDS.ts +28 -17
  151. package/src/shared-hooks/useSharedMap.ts +42 -17
  152. package/src/shared-hooks/useSharedState.ts +6 -3
  153. package/src/shared-hooks/useSharedStateRegistry.ts +44 -22
  154. package/src/shared-hooks/useSharedTree.ts +144 -0
  155. package/src/shared-hooks/useTreeNode.ts +147 -0
  156. package/src/types/ActionTypes.ts +13 -9
  157. package/src/types/FluidMap.ts +169 -0
  158. package/src/types/PropTypes.ts +57 -0
  159. package/src/types/ResultTypes.ts +88 -17
  160. package/src/types/index.ts +3 -3
  161. package/src/utils/index.ts +1 -1
  162. package/tsconfig.json +64 -70
  163. package/.nycrc.json +0 -10
  164. package/bin/index.d.ts +0 -7
  165. package/bin/index.d.ts.map +0 -1
  166. package/bin/index.js +0 -7
  167. package/bin/index.js.map +0 -1
  168. package/bin/interfaces/LiveInterfaceExtensions.d.ts.map +0 -1
  169. package/bin/interfaces/LiveInterfaceExtensions.js.map +0 -1
  170. package/bin/interfaces/index.d.ts +0 -2
  171. package/bin/interfaces/index.d.ts.map +0 -1
  172. package/bin/interfaces/index.js +0 -2
  173. package/bin/interfaces/index.js.map +0 -1
  174. package/bin/internal/errors.d.ts.map +0 -1
  175. package/bin/internal/errors.js.map +0 -1
  176. package/bin/internal/index.d.ts +0 -3
  177. package/bin/internal/index.d.ts.map +0 -1
  178. package/bin/internal/index.js +0 -3
  179. package/bin/internal/index.js.map +0 -1
  180. package/bin/internal/type-guards.d.ts.map +0 -1
  181. package/bin/internal/type-guards.js.map +0 -1
  182. package/bin/live-hooks/index.d.ts +0 -8
  183. package/bin/live-hooks/index.d.ts.map +0 -1
  184. package/bin/live-hooks/index.js +0 -8
  185. package/bin/live-hooks/index.js.map +0 -1
  186. package/bin/live-hooks/useLiveCanvas.d.ts +0 -29
  187. package/bin/live-hooks/useLiveCanvas.d.ts.map +0 -1
  188. package/bin/live-hooks/useLiveCanvas.js +0 -160
  189. package/bin/live-hooks/useLiveCanvas.js.map +0 -1
  190. package/bin/live-hooks/useLiveEvent.d.ts.map +0 -1
  191. package/bin/live-hooks/useLiveEvent.js.map +0 -1
  192. package/bin/live-hooks/useLiveFollowMode.d.ts +0 -24
  193. package/bin/live-hooks/useLiveFollowMode.d.ts.map +0 -1
  194. package/bin/live-hooks/useLiveFollowMode.js.map +0 -1
  195. package/bin/live-hooks/useLivePresence.d.ts +0 -26
  196. package/bin/live-hooks/useLivePresence.d.ts.map +0 -1
  197. package/bin/live-hooks/useLivePresence.js.map +0 -1
  198. package/bin/live-hooks/useLiveState.d.ts.map +0 -1
  199. package/bin/live-hooks/useLiveState.js.map +0 -1
  200. package/bin/live-hooks/useLiveTimer.d.ts.map +0 -1
  201. package/bin/live-hooks/useLiveTimer.js.map +0 -1
  202. package/bin/live-hooks/useMediaSynchronizer.d.ts +0 -25
  203. package/bin/live-hooks/useMediaSynchronizer.d.ts.map +0 -1
  204. package/bin/live-hooks/useMediaSynchronizer.js.map +0 -1
  205. package/bin/providers/AzureProvider.d.ts.map +0 -1
  206. package/bin/providers/AzureProvider.js.map +0 -1
  207. package/bin/providers/LiveShareProvider.d.ts.map +0 -1
  208. package/bin/providers/LiveShareProvider.js +0 -95
  209. package/bin/providers/LiveShareProvider.js.map +0 -1
  210. package/bin/providers/index.d.ts +0 -3
  211. package/bin/providers/index.d.ts.map +0 -1
  212. package/bin/providers/index.js +0 -3
  213. package/bin/providers/index.js.map +0 -1
  214. package/bin/shared-hooks/index.d.ts +0 -5
  215. package/bin/shared-hooks/index.d.ts.map +0 -1
  216. package/bin/shared-hooks/index.js +0 -5
  217. package/bin/shared-hooks/index.js.map +0 -1
  218. package/bin/shared-hooks/useDynamicDDS.d.ts.map +0 -1
  219. package/bin/shared-hooks/useDynamicDDS.js.map +0 -1
  220. package/bin/shared-hooks/useSharedMap.d.ts.map +0 -1
  221. package/bin/shared-hooks/useSharedMap.js.map +0 -1
  222. package/bin/shared-hooks/useSharedState.d.ts.map +0 -1
  223. package/bin/shared-hooks/useSharedState.js.map +0 -1
  224. package/bin/shared-hooks/useSharedStateRegistry.d.ts.map +0 -1
  225. package/bin/shared-hooks/useSharedStateRegistry.js.map +0 -1
  226. package/bin/types/ActionTypes.d.ts.map +0 -1
  227. package/bin/types/ActionTypes.js.map +0 -1
  228. package/bin/types/PropTypes.d.ts +0 -8
  229. package/bin/types/PropTypes.d.ts.map +0 -1
  230. package/bin/types/PropTypes.js.map +0 -1
  231. package/bin/types/ResultTypes.d.ts.map +0 -1
  232. package/bin/types/ResultTypes.js.map +0 -1
  233. package/bin/types/index.d.ts +0 -4
  234. package/bin/types/index.d.ts.map +0 -1
  235. package/bin/types/index.js +0 -4
  236. package/bin/types/index.js.map +0 -1
  237. package/bin/utils/index.d.ts +0 -2
  238. package/bin/utils/index.d.ts.map +0 -1
  239. package/bin/utils/index.js +0 -2
  240. package/bin/utils/index.js.map +0 -1
  241. package/bin/utils/type-check.d.ts.map +0 -1
  242. package/bin/utils/type-check.js.map +0 -1
  243. package/tsconfig.build.json +0 -6
  244. /package/bin/{interfaces → esm/interfaces}/LiveInterfaceExtensions.d.ts +0 -0
  245. /package/bin/{interfaces → esm/interfaces}/LiveInterfaceExtensions.js +0 -0
  246. /package/bin/{internal → esm/internal}/errors.d.ts +0 -0
  247. /package/bin/{internal → esm/internal}/errors.js +0 -0
  248. /package/bin/{internal → esm/internal}/type-guards.js +0 -0
  249. /package/bin/{types → esm/types}/ActionTypes.js +0 -0
  250. /package/bin/{types → esm/types}/PropTypes.js +0 -0
  251. /package/bin/{types → esm/types}/ResultTypes.js +0 -0
  252. /package/bin/{utils → esm/utils}/type-check.d.ts +0 -0
@@ -2,20 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
5
  import { LiveDataObjectInitializeState, LiveFollowMode, } from "@microsoft/live-share";
15
6
  import React from "react";
16
- import { useDynamicDDS } from "../shared-hooks";
17
- import { useFluidObjectsContext } from "../providers";
18
- import { ActionContainerNotJoinedError, ActionLiveDataObjectInitializedError, ActionLiveDataObjectUndefinedError, } from "../internal";
7
+ import { useDynamicDDS } from "../shared-hooks/index.js";
8
+ import { useFluidObjectsContext } from "../providers/index.js";
9
+ import { ActionContainerNotJoinedError, ActionLiveDataObjectInitializedError, ActionLiveDataObjectUndefinedError, } from "../internal/index.js";
19
10
  /**
20
11
  * React hook for using a Live Share `LiveFollowMode`.
21
12
  *
@@ -31,6 +22,145 @@ import { ActionContainerNotJoinedError, ActionLiveDataObjectInitializedError, Ac
31
22
  * @param initialData The initial value for the local user's `stateValue`.
32
23
  * @param allowedRoles Optional. The user roles that are allowed to present to use `startPresenting()` or `stopPresenting()`.
33
24
  * @returns `IUseLiveFollowModeResults` results, which contains React stateful objects and callbacks.
25
+ *
26
+ * @example
27
+ ```jsx
28
+ import { FollowModeType } from "@microsoft/live-share";
29
+ import { useLiveFollowMode } from "@microsoft/live-share-react";
30
+ // As an example, we will use a fake component to denote what a 3D viewer might look like in an app
31
+ import { Example3DModelViewer } from "./components";
32
+
33
+ // Define a unique key that differentiates this usage of `useLiveFollowMode` from others in your app
34
+ const MY_UNIQUE_KEY = "follow-mode-key";
35
+
36
+ // Define the initial stateValue for the local user (optional).
37
+ const startingCameraPosition = {
38
+ x: 0,
39
+ y: 0,
40
+ z: 0,
41
+ };
42
+
43
+ // Example component for using useLiveFollowMode
44
+ export function MyLiveFollowMode() {
45
+ const {
46
+ state,
47
+ localUser,
48
+ otherUsers,
49
+ allUsers,
50
+ liveFollowMode,
51
+ update,
52
+ startPresenting,
53
+ stopPresenting,
54
+ beginSuspension,
55
+ endSuspension,
56
+ followUser,
57
+ stopFollowing,
58
+ } = useLiveFollowMode(MY_UNIQUE_KEY, startingCameraPosition);
59
+
60
+ // Example of an event listener for a camera position changed event.
61
+ // For something like a camera change event, you should use a debounce function.
62
+ function onCameraPositionChanged(position, isUserAction) {
63
+ // Broadcast change to other users so that they have their latest camera position
64
+ update(position);
65
+ // If the local user changed the position while following another user, we want to suspend.
66
+ // Note: helps to distinguish changes initiated by the local user (e.g., drag mouse) separately from other change events.
67
+ if (!isUserAction) return;
68
+ switch (state.type) {
69
+ case FollowModeType.followPresenter:
70
+ case FollowModeType.followUser: {
71
+ // This will trigger a "stateChanged" event update for the local user only.
72
+ followMode.beginSuspension();
73
+ break;
74
+ }
75
+ default: {
76
+ // No need to suspend for other types
77
+ break;
78
+ }
79
+ }
80
+ }
81
+
82
+ // Can optionally get the relevant user's presence object
83
+ const followingUser = liveFollowMode?.getUser(state.followingUserId);
84
+
85
+ // Render loading UI when creating LiveFollowMode instance for first time
86
+ if (!liveFollowMode) return <>Loading...</>;
87
+
88
+ // Render UI
89
+ return (
90
+ <div>
91
+ {state.type === FollowModeType.local && (
92
+ <div>
93
+ <p>{""}</p>
94
+ <button onClick={startPresenting}>
95
+ {"Start presenting"}
96
+ </button>
97
+ </div>
98
+ )}
99
+ {state.type === FollowModeType.activeFollowers && (
100
+ <div>
101
+ <p>{`${state.otherUsersCount} users are following you`}</p>
102
+ <button onClick={startPresenting}>
103
+ {"Present to all"}
104
+ </button>
105
+ </div>
106
+ )}
107
+ {state.type === FollowModeType.activePresenter && (
108
+ <div>
109
+ <p>{`You are actively presenting to everyone`}</p>
110
+ <button onClick={stopPresenting}>
111
+ {"Stop presenting"}
112
+ </button>
113
+ </div>
114
+ )}
115
+ {state.type === FollowModeType.followPresenter && (
116
+ <div>
117
+ <p>{`${followingUser?.displayName} is presenting to everyone`}</p>
118
+ <button onClick={startPresenting}>{"Take control"}</button>
119
+ </div>
120
+ )}
121
+ {state.type === FollowModeType.suspendFollowPresenter && (
122
+ <div>
123
+ <p>{`${followingUser?.displayName} is presenting to everyone`}</p>
124
+ <button onClick={endSuspension}>
125
+ {"Sync to presenter"}
126
+ </button>
127
+ </div>
128
+ )}
129
+ {state.type === FollowModeType.followUser && (
130
+ <div>
131
+ <p>{`You are following ${followingUser?.displayName}`}</p>
132
+ <button onClick={stopFollowing}>{"Stop following"}</button>
133
+ </div>
134
+ )}
135
+ {state.type === FollowModeType.suspendFollowUser && (
136
+ <div>
137
+ <p>{`You were following ${followingUser?.displayName}`}</p>
138
+ <button onClick={stopFollowing}>
139
+ {"Resume following"}
140
+ </button>
141
+ </div>
142
+ )}
143
+ <div>
144
+ <p>{"Follow a specific user:"}</p>
145
+ {otherUsers.map((user) => (
146
+ <button
147
+ onClick={() => {
148
+ followUser(user.userId);
149
+ }}
150
+ key={user.userId}
151
+ >
152
+ {user.displayName}
153
+ </button>
154
+ ))}
155
+ </div>
156
+ <Example3DModelViewer
157
+ cameraPosition={state.value}
158
+ onCameraPositionChanged={onCameraPositionChanged}
159
+ />
160
+ </div>
161
+ );
162
+ };
163
+ ```
34
164
  */
35
165
  export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
36
166
  /**
@@ -48,16 +178,20 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
48
178
  /**
49
179
  * User facing: list of non-local user's presence objects.
50
180
  */
51
- const otherUsers = allUsers.filter((user) => !user.isLocalUser);
181
+ const otherUsers = React.useMemo(() => {
182
+ return allUsers.filter((user) => !user.isLocalUser);
183
+ }, [allUsers]);
52
184
  /**
53
185
  * User facing: local user's presence object.
54
186
  */
55
- const localUser = allUsers.find((user) => user.isLocalUser);
187
+ const localUser = React.useMemo(() => {
188
+ return allUsers.find((user) => user.isLocalUser);
189
+ }, [allUsers]);
56
190
  const { container } = useFluidObjectsContext();
57
191
  /**
58
192
  * User facing: callback to update the local user's custom data for their follow state.
59
193
  */
60
- const update = React.useCallback((stateValue) => __awaiter(this, void 0, void 0, function* () {
194
+ const update = React.useCallback(async (stateValue) => {
61
195
  if (!container) {
62
196
  throw new ActionContainerNotJoinedError("liveFollowMode", "update");
63
197
  }
@@ -67,12 +201,12 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
67
201
  if (!liveFollowMode.isInitialized) {
68
202
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "update");
69
203
  }
70
- return yield liveFollowMode.update(stateValue);
71
- }), [container, liveFollowMode]);
204
+ return await liveFollowMode.update(stateValue);
205
+ }, [container, liveFollowMode]);
72
206
  /**
73
207
  * User facing: callback to start presenting.
74
208
  */
75
- const startPresenting = React.useCallback(() => __awaiter(this, void 0, void 0, function* () {
209
+ const startPresenting = React.useCallback(async () => {
76
210
  if (!container) {
77
211
  throw new ActionContainerNotJoinedError("liveFollowMode", "startPresenting");
78
212
  }
@@ -82,12 +216,12 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
82
216
  if (!liveFollowMode.isInitialized) {
83
217
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "startPresenting");
84
218
  }
85
- return yield liveFollowMode.startPresenting();
86
- }), [container, liveFollowMode]);
219
+ return await liveFollowMode.startPresenting();
220
+ }, [container, liveFollowMode]);
87
221
  /**
88
222
  * User facing: callback to stop presenting.
89
223
  */
90
- const stopPresenting = React.useCallback(() => __awaiter(this, void 0, void 0, function* () {
224
+ const stopPresenting = React.useCallback(async () => {
91
225
  if (!container) {
92
226
  throw new ActionContainerNotJoinedError("liveFollowMode", "stopPresenting");
93
227
  }
@@ -97,12 +231,12 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
97
231
  if (!liveFollowMode.isInitialized) {
98
232
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "stopPresenting");
99
233
  }
100
- return yield liveFollowMode.stopPresenting();
101
- }), [container, liveFollowMode]);
234
+ return await liveFollowMode.stopPresenting();
235
+ }, [container, liveFollowMode]);
102
236
  /**
103
237
  * User facing: callback to suspend sync.
104
238
  */
105
- const beginSuspension = React.useCallback(() => __awaiter(this, void 0, void 0, function* () {
239
+ const beginSuspension = React.useCallback(async () => {
106
240
  if (!container) {
107
241
  throw new ActionContainerNotJoinedError("liveFollowMode", "syncToPresenter");
108
242
  }
@@ -112,12 +246,12 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
112
246
  if (!liveFollowMode.isInitialized) {
113
247
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "syncToPresenter");
114
248
  }
115
- return yield liveFollowMode.beginSuspension();
116
- }), [container, liveFollowMode]);
249
+ return await liveFollowMode.beginSuspension();
250
+ }, [container, liveFollowMode]);
117
251
  /**
118
252
  * User facing: callback to end current suspension.
119
253
  */
120
- const endSuspension = React.useCallback(() => __awaiter(this, void 0, void 0, function* () {
254
+ const endSuspension = React.useCallback(async () => {
121
255
  if (!container) {
122
256
  throw new ActionContainerNotJoinedError("liveFollowMode", "syncToPresenter");
123
257
  }
@@ -127,12 +261,12 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
127
261
  if (!liveFollowMode.isInitialized) {
128
262
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "syncToPresenter");
129
263
  }
130
- return yield liveFollowMode.endSuspension();
131
- }), [container, liveFollowMode]);
264
+ return await liveFollowMode.endSuspension();
265
+ }, [container, liveFollowMode]);
132
266
  /**
133
267
  * User facing: callback to follow a specific user.
134
268
  */
135
- const followUser = React.useCallback((userId) => __awaiter(this, void 0, void 0, function* () {
269
+ const followUser = React.useCallback(async (userId) => {
136
270
  if (!container) {
137
271
  throw new ActionContainerNotJoinedError("liveFollowMode", "followUser");
138
272
  }
@@ -142,12 +276,12 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
142
276
  if (!liveFollowMode.isInitialized) {
143
277
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "followUser");
144
278
  }
145
- return yield liveFollowMode.followUser(userId);
146
- }), [container, liveFollowMode]);
279
+ return await liveFollowMode.followUser(userId);
280
+ }, [container, liveFollowMode]);
147
281
  /**
148
282
  * User facing: callback to stop following a user.
149
283
  */
150
- const stopFollowing = React.useCallback(() => __awaiter(this, void 0, void 0, function* () {
284
+ const stopFollowing = React.useCallback(async () => {
151
285
  if (!container) {
152
286
  throw new ActionContainerNotJoinedError("liveFollowMode", "stopFollowing");
153
287
  }
@@ -157,8 +291,8 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
157
291
  if (!liveFollowMode.isInitialized) {
158
292
  throw new ActionLiveDataObjectInitializedError("liveFollowMode", "stopFollowing");
159
293
  }
160
- return yield liveFollowMode.stopFollowing();
161
- }), [container, liveFollowMode]);
294
+ return await liveFollowMode.stopFollowing();
295
+ }, [container, liveFollowMode]);
162
296
  /**
163
297
  * Setup change listeners and start `LiveFollowMode` if needed
164
298
  */
@@ -167,14 +301,14 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
167
301
  return;
168
302
  const onPresenceChanged = () => {
169
303
  const updatedLocalUsers = [];
170
- liveFollowMode === null || liveFollowMode === void 0 ? void 0 : liveFollowMode.getUsers().forEach((user) => {
304
+ liveFollowMode?.getUsers().forEach((user) => {
171
305
  updatedLocalUsers.push(user);
172
306
  });
173
307
  setAllUsers(updatedLocalUsers);
174
308
  };
175
309
  liveFollowMode.on("presenceChanged", onPresenceChanged);
176
310
  const onStateChanged = () => {
177
- setState(liveFollowMode === null || liveFollowMode === void 0 ? void 0 : liveFollowMode.state);
311
+ setState(liveFollowMode?.state);
178
312
  };
179
313
  liveFollowMode.on("stateChanged", onStateChanged);
180
314
  if (liveFollowMode.initializeState ===
@@ -186,8 +320,8 @@ export function useLiveFollowMode(uniqueKey, initialData, allowedRoles) {
186
320
  onPresenceChanged();
187
321
  onStateChanged();
188
322
  return () => {
189
- liveFollowMode === null || liveFollowMode === void 0 ? void 0 : liveFollowMode.off("presenceChanged", onPresenceChanged);
190
- liveFollowMode === null || liveFollowMode === void 0 ? void 0 : liveFollowMode.off("stateChanged", onStateChanged);
323
+ liveFollowMode?.off("presenceChanged", onPresenceChanged);
324
+ liveFollowMode?.off("stateChanged", onStateChanged);
191
325
  };
192
326
  }, [liveFollowMode]);
193
327
  return {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveFollowMode.js","sourceRoot":"","sources":["../../../src/live-hooks/useLiveFollowMode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the Microsoft Live Share SDK License.
4
+ */
5
+ import { UserMeetingRole, LivePresenceData } from "@microsoft/live-share";
6
+ import { IUseLivePresenceResults } from "../types/index.js";
7
+ /**
8
+ * React hook for using a Live Share `LivePresence`.
9
+ *
10
+ * @remarks
11
+ * Use this hook if you want to track presence for who is currently using this component, such as
12
+ * who is online or who is viewing a specific document. With presence, you can sent along any custom
13
+ * user data. This is useful for rendering a list of users, profile pictures, cursor positions, and more.
14
+ * This hook can only be used in a child component of `<LiveShareProvider>` or `<AzureProvider>`.
15
+ *
16
+ * @template TData Optional typing for the custom user presence data object. Default is `object` type.
17
+ * @param uniqueKey The unique key for `LivePresence`. If one does not yet exist, a new one will be created.
18
+ * @param initialData Initial presence data object for the user. Can be value or a function to get the value.
19
+ * @param allowedRoles Optional. the user roles that are allowed to mutate the synchronized state
20
+ * will be created, otherwise it will use the existing one. Default value is ":<dds-default>"
21
+ * @returns stateful `localUser`, `otherUsers` list, and `allUsers` list. Also returns a callback method
22
+ * to update the local user's presence and the `LivePresence` Fluid object.
23
+ *
24
+ * @example
25
+ ```jsx
26
+ import { useLivePresence } from "@microsoft/live-share-react";
27
+
28
+ // Define a unique key that differentiates this usage of `useLivePresence` from others in your app
29
+ const MY_UNIQUE_KEY = "presence-key";
30
+
31
+ // Example component for using useLivePresence
32
+ export const MyCustomPresence = () => {
33
+ const {
34
+ allUsers,
35
+ localUser,
36
+ livePresence,
37
+ updatePresence,
38
+ } = useLivePresence(MY_UNIQUE_KEY, {
39
+ picture: "DEFAULT_PROFILE_PICTURE_URL",
40
+ readyToStart: false,
41
+ });
42
+
43
+ // Callback to update the user's presence
44
+ const onToggleReady = () => {
45
+ updatePresence({
46
+ ...localUser.data,
47
+ readyToStart: !localUser.data.readyToStart,
48
+ });
49
+ }
50
+
51
+ // Render loading UI while loading LivePresence for first time
52
+ if (!livePresence) return <>Loading...</>;
53
+
54
+ // Render presence UI
55
+ return (
56
+ {allUsers.map((user) => (
57
+ <div key={user.userId}>
58
+ <div>
59
+ {user.displayName}
60
+ </div>
61
+ <div>
62
+ {`Ready: ${user.data.readyToStart}`}
63
+ </div>
64
+ {user.isLocalUser && (
65
+ <button onClick={onToggleReady}>
66
+ {"Toggle ready"}
67
+ </button>
68
+ )}
69
+ </div>
70
+ ))}
71
+ );
72
+ }
73
+ ```
74
+ */
75
+ export declare function useLivePresence<TData extends LivePresenceData = any>(uniqueKey: string, initialData: TData | (() => TData), allowedRoles?: UserMeetingRole[]): IUseLivePresenceResults<TData>;
76
+ //# sourceMappingURL=useLivePresence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLivePresence.d.ts","sourceRoot":"","sources":["../../../src/live-hooks/useLivePresence.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGH,eAAe,EAEf,gBAAgB,EAEnB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACH,uBAAuB,EAE1B,MAAM,mBAAmB,CAAC;AAS3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,wBAAgB,eAAe,CAAC,KAAK,SAAS,gBAAgB,GAAG,GAAG,EAChE,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,KAAK,GAAG,CAAC,MAAM,KAAK,CAAC,EAClC,YAAY,CAAC,EAAE,eAAe,EAAE,GACjC,uBAAuB,CAAC,KAAK,CAAC,CAwGhC"}
@@ -2,20 +2,11 @@
2
2
  * Copyright (c) Microsoft Corporation. All rights reserved.
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
- return new (P || (P = Promise))(function (resolve, reject) {
8
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
- step((generator = generator.apply(thisArg, _arguments || [])).next());
12
- });
13
- };
14
- import { PresenceState, LivePresence, LiveDataObjectInitializeState, } from "@microsoft/live-share";
5
+ import { LivePresence, LiveDataObjectInitializeState, PresenceStatus, } from "@microsoft/live-share";
15
6
  import React from "react";
16
- import { useDynamicDDS } from "../shared-hooks";
17
- import { useFluidObjectsContext } from "../providers";
18
- import { ActionContainerNotJoinedError, ActionLiveDataObjectInitializedError, ActionLiveDataObjectUndefinedError, } from "../internal";
7
+ import { useDynamicDDS } from "../shared-hooks/index.js";
8
+ import { useFluidObjectsContext } from "../providers/index.js";
9
+ import { ActionContainerNotJoinedError, ActionLiveDataObjectInitializedError, ActionLiveDataObjectUndefinedError, } from "../internal/index.js";
19
10
  /**
20
11
  * React hook for using a Live Share `LivePresence`.
21
12
  *
@@ -27,14 +18,64 @@ import { ActionContainerNotJoinedError, ActionLiveDataObjectInitializedError, Ac
27
18
  *
28
19
  * @template TData Optional typing for the custom user presence data object. Default is `object` type.
29
20
  * @param uniqueKey The unique key for `LivePresence`. If one does not yet exist, a new one will be created.
30
- * @param initialData Optional. Initial presence data object for the user. Can be value or a function to get the value.
31
- * @param initialPresenceState Optional. Initial status of the user's presence. Default is online.
21
+ * @param initialData Initial presence data object for the user. Can be value or a function to get the value.
32
22
  * @param allowedRoles Optional. the user roles that are allowed to mutate the synchronized state
33
23
  * will be created, otherwise it will use the existing one. Default value is ":<dds-default>"
34
24
  * @returns stateful `localUser`, `otherUsers` list, and `allUsers` list. Also returns a callback method
35
25
  * to update the local user's presence and the `LivePresence` Fluid object.
26
+ *
27
+ * @example
28
+ ```jsx
29
+ import { useLivePresence } from "@microsoft/live-share-react";
30
+
31
+ // Define a unique key that differentiates this usage of `useLivePresence` from others in your app
32
+ const MY_UNIQUE_KEY = "presence-key";
33
+
34
+ // Example component for using useLivePresence
35
+ export const MyCustomPresence = () => {
36
+ const {
37
+ allUsers,
38
+ localUser,
39
+ livePresence,
40
+ updatePresence,
41
+ } = useLivePresence(MY_UNIQUE_KEY, {
42
+ picture: "DEFAULT_PROFILE_PICTURE_URL",
43
+ readyToStart: false,
44
+ });
45
+
46
+ // Callback to update the user's presence
47
+ const onToggleReady = () => {
48
+ updatePresence({
49
+ ...localUser.data,
50
+ readyToStart: !localUser.data.readyToStart,
51
+ });
52
+ }
53
+
54
+ // Render loading UI while loading LivePresence for first time
55
+ if (!livePresence) return <>Loading...</>;
56
+
57
+ // Render presence UI
58
+ return (
59
+ {allUsers.map((user) => (
60
+ <div key={user.userId}>
61
+ <div>
62
+ {user.displayName}
63
+ </div>
64
+ <div>
65
+ {`Ready: ${user.data.readyToStart}`}
66
+ </div>
67
+ {user.isLocalUser && (
68
+ <button onClick={onToggleReady}>
69
+ {"Toggle ready"}
70
+ </button>
71
+ )}
72
+ </div>
73
+ ))}
74
+ );
75
+ }
76
+ ```
36
77
  */
37
- export function useLivePresence(uniqueKey, initialData, initialPresenceState = PresenceState.online, allowedRoles) {
78
+ export function useLivePresence(uniqueKey, initialData, allowedRoles) {
38
79
  /**
39
80
  * Stateful all user presence list and its non-user-facing setter method.
40
81
  */
@@ -42,20 +83,27 @@ export function useLivePresence(uniqueKey, initialData, initialPresenceState = P
42
83
  /**
43
84
  * User facing: dynamically load the DDS for the given unique key.
44
85
  */
45
- const { dds: livePresence } = useDynamicDDS(uniqueKey, (LivePresence));
86
+ const { dds: livePresence } = useDynamicDDS(uniqueKey, LivePresence);
46
87
  /**
47
88
  * User facing: list of non-local user's presence objects.
48
89
  */
49
- const otherUsers = allUsers.filter((user) => !user.isLocalUser);
90
+ const otherUsers = React.useMemo(() => {
91
+ return allUsers.filter((user) => !user.isLocalUser);
92
+ }, [allUsers]);
50
93
  /**
51
94
  * User facing: local user's presence object.
52
95
  */
53
- const localUser = allUsers.find((user) => user.isLocalUser);
96
+ const localUser = React.useMemo(() => {
97
+ return allUsers.find((user) => user.isLocalUser);
98
+ }, [allUsers]);
99
+ const onlineUsers = React.useMemo(() => {
100
+ return allUsers.filter((user) => user.status === PresenceStatus.online);
101
+ }, [allUsers]);
54
102
  const { container } = useFluidObjectsContext();
55
103
  /**
56
104
  * User facing: callback to update the local user's presence.
57
105
  */
58
- const updatePresence = React.useCallback((data, state) => __awaiter(this, void 0, void 0, function* () {
106
+ const updatePresence = React.useCallback(async (data) => {
59
107
  if (!container) {
60
108
  throw new ActionContainerNotJoinedError("livePresence", "updatePresence");
61
109
  }
@@ -65,8 +113,8 @@ export function useLivePresence(uniqueKey, initialData, initialPresenceState = P
65
113
  if (!livePresence.isInitialized) {
66
114
  throw new ActionLiveDataObjectInitializedError("livePresence", "updatePresence");
67
115
  }
68
- return yield livePresence.update(data, state);
69
- }), [container, livePresence]);
116
+ return await livePresence.update(data);
117
+ }, [container, livePresence]);
70
118
  /**
71
119
  * Setup change listeners and start `LivePresence` if needed
72
120
  */
@@ -75,7 +123,7 @@ export function useLivePresence(uniqueKey, initialData, initialPresenceState = P
75
123
  return;
76
124
  const onPresenceChanged = () => {
77
125
  const updatedLocalUsers = [];
78
- livePresence === null || livePresence === void 0 ? void 0 : livePresence.getUsers().forEach((user) => {
126
+ livePresence?.getUsers().forEach((user) => {
79
127
  updatedLocalUsers.push(user);
80
128
  });
81
129
  setAllUsers(updatedLocalUsers);
@@ -85,17 +133,18 @@ export function useLivePresence(uniqueKey, initialData, initialPresenceState = P
85
133
  LiveDataObjectInitializeState.needed) {
86
134
  livePresence.initialize(isInitialDataCallback(initialData)
87
135
  ? initialData()
88
- : initialData, initialPresenceState, allowedRoles);
136
+ : initialData, allowedRoles);
89
137
  }
90
138
  onPresenceChanged();
91
139
  return () => {
92
- livePresence === null || livePresence === void 0 ? void 0 : livePresence.off("presenceChanged", onPresenceChanged);
140
+ livePresence?.off("presenceChanged", onPresenceChanged);
93
141
  };
94
142
  }, [livePresence]);
95
143
  return {
96
144
  localUser,
97
145
  otherUsers,
98
146
  allUsers,
147
+ onlineUsers,
99
148
  livePresence,
100
149
  updatePresence,
101
150
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLivePresence.js","sourceRoot":"","sources":["../../../src/live-hooks/useLivePresence.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
  import { LiveState, UserMeetingRole } from "@microsoft/live-share";
6
- import { SetLiveStateAction } from "../types";
6
+ import { SetLiveStateAction } from "../types/index.js";
7
7
  /**
8
8
  * React hook for using a Live Share `LiveState`.
9
9
  *
@@ -16,6 +16,51 @@ import { SetLiveStateAction } from "../types";
16
16
  * @param allowedRoles Optional. the user roles that are allowed to mutate the synchronized state
17
17
  * @returns ordered values: first value is the synchronized state value and the second is a setter to change the state value.
18
18
  * The setter returns a void promise, which will throw if the user does not have the required roles to set.
19
+ *
20
+ * @example
21
+ ```jsx
22
+ import { useLiveState } from "@microsoft/live-share-react";
23
+
24
+ const planets = [
25
+ "Mercury",
26
+ "Venus",
27
+ "Earth",
28
+ "Mars",
29
+ "Jupiter",
30
+ "Saturn",
31
+ "Uranus",
32
+ "Neptune",
33
+ ];
34
+
35
+ // Define a unique key that differentiates this usage of `useLiveState` from others in your app
36
+ const MY_UNIQUE_KEY = "selected-planet-key";
37
+
38
+ // Example component for using useLiveState
39
+ export const MyCustomState = () => {
40
+ const [planet, setPlanet, liveState] = useLiveState(MY_UNIQUE_KEY, planets[0]);
41
+
42
+ // Render loading UI when creating LiveState instance for first time
43
+ if (!liveState) return <>Loading...</>;
44
+
45
+ // Render UI
46
+ return (
47
+ <div>
48
+ {`Current planet: ${planet}`}
49
+ {"Select a planet below:"}
50
+ {planets.map((planet) => (
51
+ <button
52
+ key={planet}
53
+ onClick={() => {
54
+ setPlanet(planet);
55
+ }}
56
+ >
57
+ {planet}
58
+ </button>
59
+ ))}
60
+ </div>
61
+ );
62
+ };
63
+ ```
19
64
  */
20
65
  export declare function useLiveState<TState = any>(uniqueKey: string, initialState: TState, allowedRoles?: UserMeetingRole[]): [TState, SetLiveStateAction<TState>, LiveState<TState> | undefined];
21
66
  //# sourceMappingURL=useLiveState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveState.d.ts","sourceRoot":"","sources":["../../../src/live-hooks/useLiveState.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEH,SAAS,EACT,eAAe,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAUvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAG,GAAG,EACrC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,eAAe,EAAE,GACjC,CAAC,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,CAwErE"}