@microsoft/live-share-react 2.0.0-internal.5 → 2.0.0-internal.6

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 (380) hide show
  1. package/.nycrc.json +9 -9
  2. package/LICENSE +64 -61
  3. package/README.md +173 -168
  4. package/bin/cjs/index.d.ts +7 -0
  5. package/bin/cjs/index.d.ts.map +1 -0
  6. package/bin/cjs/index.js +23 -0
  7. package/bin/cjs/index.js.map +1 -0
  8. package/bin/cjs/interfaces/LiveInterfaceExtensions.d.ts.map +1 -0
  9. package/bin/cjs/interfaces/LiveInterfaceExtensions.js +7 -0
  10. package/bin/cjs/interfaces/LiveInterfaceExtensions.js.map +1 -0
  11. package/bin/cjs/interfaces/index.d.ts +2 -0
  12. package/bin/cjs/interfaces/index.d.ts.map +1 -0
  13. package/bin/cjs/interfaces/index.js +18 -0
  14. package/bin/cjs/interfaces/index.js.map +1 -0
  15. package/bin/cjs/internal/errors.d.ts.map +1 -0
  16. package/bin/cjs/internal/errors.js +48 -0
  17. package/bin/cjs/internal/errors.js.map +1 -0
  18. package/bin/cjs/internal/index.d.ts +3 -0
  19. package/bin/cjs/internal/index.d.ts.map +1 -0
  20. package/bin/cjs/internal/index.js +19 -0
  21. package/bin/cjs/internal/index.js.map +1 -0
  22. package/bin/{internal → cjs/internal}/type-guards.d.ts +1 -1
  23. package/bin/cjs/internal/type-guards.d.ts.map +1 -0
  24. package/bin/cjs/internal/type-guards.js +24 -0
  25. package/bin/cjs/internal/type-guards.js.map +1 -0
  26. package/bin/cjs/live-hooks/index.d.ts +8 -0
  27. package/bin/cjs/live-hooks/index.d.ts.map +1 -0
  28. package/bin/cjs/live-hooks/index.js +24 -0
  29. package/bin/cjs/live-hooks/index.js.map +1 -0
  30. package/bin/cjs/live-hooks/useLiveCanvas.d.ts +80 -0
  31. package/bin/cjs/live-hooks/useLiveCanvas.d.ts.map +1 -0
  32. package/bin/cjs/live-hooks/useLiveCanvas.js +244 -0
  33. package/bin/cjs/live-hooks/useLiveCanvas.js.map +1 -0
  34. package/bin/{live-hooks → cjs/live-hooks}/useLiveEvent.d.ts +37 -1
  35. package/bin/cjs/live-hooks/useLiveEvent.d.ts.map +1 -0
  36. package/bin/cjs/live-hooks/useLiveEvent.js +150 -0
  37. package/bin/cjs/live-hooks/useLiveEvent.js.map +1 -0
  38. package/bin/cjs/live-hooks/useLiveFollowMode.d.ts +163 -0
  39. package/bin/cjs/live-hooks/useLiveFollowMode.d.ts.map +1 -0
  40. package/bin/cjs/live-hooks/useLiveFollowMode.js +360 -0
  41. package/bin/cjs/live-hooks/useLiveFollowMode.js.map +1 -0
  42. package/bin/cjs/live-hooks/useLivePresence.d.ts +76 -0
  43. package/bin/cjs/live-hooks/useLivePresence.d.ts.map +1 -0
  44. package/bin/cjs/live-hooks/useLivePresence.js +166 -0
  45. package/bin/cjs/live-hooks/useLivePresence.js.map +1 -0
  46. package/bin/{live-hooks → cjs/live-hooks}/useLiveState.d.ts +46 -1
  47. package/bin/cjs/live-hooks/useLiveState.d.ts.map +1 -0
  48. package/bin/cjs/live-hooks/useLiveState.js +130 -0
  49. package/bin/cjs/live-hooks/useLiveState.js.map +1 -0
  50. package/bin/{live-hooks → cjs/live-hooks}/useLiveTimer.d.ts +56 -1
  51. package/bin/cjs/live-hooks/useLiveTimer.d.ts.map +1 -0
  52. package/bin/cjs/live-hooks/useLiveTimer.js +233 -0
  53. package/bin/cjs/live-hooks/useLiveTimer.js.map +1 -0
  54. package/bin/cjs/live-hooks/useMediaSynchronizer.d.ts +86 -0
  55. package/bin/cjs/live-hooks/useMediaSynchronizer.d.ts.map +1 -0
  56. package/bin/cjs/live-hooks/useMediaSynchronizer.js +301 -0
  57. package/bin/cjs/live-hooks/useMediaSynchronizer.js.map +1 -0
  58. package/bin/cjs/package.json +1 -0
  59. package/bin/{providers → cjs/providers}/AzureProvider.d.ts +9 -9
  60. package/bin/cjs/providers/AzureProvider.d.ts.map +1 -0
  61. package/bin/cjs/providers/AzureProvider.js +127 -0
  62. package/bin/cjs/providers/AzureProvider.js.map +1 -0
  63. package/bin/{providers → cjs/providers}/LiveShareProvider.d.ts +106 -4
  64. package/bin/cjs/providers/LiveShareProvider.d.ts.map +1 -0
  65. package/bin/cjs/providers/LiveShareProvider.js +205 -0
  66. package/bin/cjs/providers/LiveShareProvider.js.map +1 -0
  67. package/bin/cjs/providers/index.d.ts +3 -0
  68. package/bin/cjs/providers/index.d.ts.map +1 -0
  69. package/bin/cjs/providers/index.js +19 -0
  70. package/bin/cjs/providers/index.js.map +1 -0
  71. package/bin/cjs/shared-hooks/index.d.ts +7 -0
  72. package/bin/cjs/shared-hooks/index.d.ts.map +1 -0
  73. package/bin/cjs/shared-hooks/index.js +23 -0
  74. package/bin/cjs/shared-hooks/index.js.map +1 -0
  75. package/bin/cjs/shared-hooks/internals/tree-node-constants.d.ts +3 -0
  76. package/bin/cjs/shared-hooks/internals/tree-node-constants.d.ts.map +1 -0
  77. package/bin/cjs/shared-hooks/internals/tree-node-constants.js +6 -0
  78. package/bin/cjs/shared-hooks/internals/tree-node-constants.js.map +1 -0
  79. package/bin/cjs/shared-hooks/internals/tree-node-types.d.ts +10 -0
  80. package/bin/cjs/shared-hooks/internals/tree-node-types.d.ts.map +1 -0
  81. package/bin/cjs/shared-hooks/internals/tree-node-types.js +23 -0
  82. package/bin/cjs/shared-hooks/internals/tree-node-types.js.map +1 -0
  83. package/bin/cjs/shared-hooks/internals/tree-node-utils.d.ts +33 -0
  84. package/bin/cjs/shared-hooks/internals/tree-node-utils.d.ts.map +1 -0
  85. package/bin/cjs/shared-hooks/internals/tree-node-utils.js +193 -0
  86. package/bin/cjs/shared-hooks/internals/tree-node-utils.js.map +1 -0
  87. package/bin/{shared-hooks → cjs/shared-hooks}/useDynamicDDS.d.ts +4 -4
  88. package/bin/cjs/shared-hooks/useDynamicDDS.d.ts.map +1 -0
  89. package/bin/cjs/shared-hooks/useDynamicDDS.js +87 -0
  90. package/bin/cjs/shared-hooks/useDynamicDDS.js.map +1 -0
  91. package/bin/{shared-hooks → cjs/shared-hooks}/useSharedMap.d.ts +4 -2
  92. package/bin/cjs/shared-hooks/useSharedMap.d.ts.map +1 -0
  93. package/bin/cjs/shared-hooks/useSharedMap.js +134 -0
  94. package/bin/cjs/shared-hooks/useSharedMap.js.map +1 -0
  95. package/bin/{shared-hooks → cjs/shared-hooks}/useSharedState.d.ts +1 -1
  96. package/bin/cjs/shared-hooks/useSharedState.d.ts.map +1 -0
  97. package/bin/cjs/shared-hooks/useSharedState.js +80 -0
  98. package/bin/cjs/shared-hooks/useSharedState.js.map +1 -0
  99. package/bin/{shared-hooks → cjs/shared-hooks}/useSharedStateRegistry.d.ts +1 -1
  100. package/bin/cjs/shared-hooks/useSharedStateRegistry.d.ts.map +1 -0
  101. package/bin/cjs/shared-hooks/useSharedStateRegistry.js +120 -0
  102. package/bin/cjs/shared-hooks/useSharedStateRegistry.js.map +1 -0
  103. package/bin/cjs/shared-hooks/useSharedTree.d.ts +57 -0
  104. package/bin/cjs/shared-hooks/useSharedTree.d.ts.map +1 -0
  105. package/bin/cjs/shared-hooks/useSharedTree.js +123 -0
  106. package/bin/cjs/shared-hooks/useSharedTree.js.map +1 -0
  107. package/bin/cjs/shared-hooks/useTreeNode.d.ts +96 -0
  108. package/bin/cjs/shared-hooks/useTreeNode.d.ts.map +1 -0
  109. package/bin/cjs/shared-hooks/useTreeNode.js +135 -0
  110. package/bin/cjs/shared-hooks/useTreeNode.js.map +1 -0
  111. package/bin/{types → cjs/types}/ActionTypes.d.ts +7 -7
  112. package/bin/cjs/types/ActionTypes.d.ts.map +1 -0
  113. package/bin/cjs/types/ActionTypes.js +7 -0
  114. package/bin/cjs/types/ActionTypes.js.map +1 -0
  115. package/bin/cjs/types/PropTypes.d.ts +56 -0
  116. package/bin/cjs/types/PropTypes.d.ts.map +1 -0
  117. package/bin/cjs/types/PropTypes.js +7 -0
  118. package/bin/cjs/types/PropTypes.js.map +1 -0
  119. package/bin/{types → cjs/types}/ResultTypes.d.ts +46 -18
  120. package/bin/cjs/types/ResultTypes.d.ts.map +1 -0
  121. package/bin/cjs/types/ResultTypes.js +7 -0
  122. package/bin/cjs/types/ResultTypes.js.map +1 -0
  123. package/bin/cjs/types/index.d.ts +4 -0
  124. package/bin/cjs/types/index.d.ts.map +1 -0
  125. package/bin/cjs/types/index.js +20 -0
  126. package/bin/cjs/types/index.js.map +1 -0
  127. package/bin/cjs/utils/index.d.ts +2 -0
  128. package/bin/cjs/utils/index.d.ts.map +1 -0
  129. package/bin/cjs/utils/index.js +18 -0
  130. package/bin/cjs/utils/index.js.map +1 -0
  131. package/bin/cjs/utils/type-check.d.ts.map +1 -0
  132. package/bin/cjs/utils/type-check.js +62 -0
  133. package/bin/cjs/utils/type-check.js.map +1 -0
  134. package/bin/esm/index.d.ts +7 -0
  135. package/bin/esm/index.d.ts.map +1 -0
  136. package/bin/esm/index.js +7 -0
  137. package/bin/esm/index.js.map +1 -0
  138. package/bin/esm/interfaces/LiveInterfaceExtensions.d.ts +26 -0
  139. package/bin/esm/interfaces/LiveInterfaceExtensions.d.ts.map +1 -0
  140. package/bin/esm/interfaces/LiveInterfaceExtensions.js.map +1 -0
  141. package/bin/esm/interfaces/index.d.ts +2 -0
  142. package/bin/esm/interfaces/index.d.ts.map +1 -0
  143. package/bin/esm/interfaces/index.js +2 -0
  144. package/bin/esm/interfaces/index.js.map +1 -0
  145. package/bin/esm/internal/errors.d.ts +41 -0
  146. package/bin/esm/internal/errors.d.ts.map +1 -0
  147. package/bin/esm/internal/errors.js.map +1 -0
  148. package/bin/esm/internal/index.d.ts +3 -0
  149. package/bin/esm/internal/index.d.ts.map +1 -0
  150. package/bin/esm/internal/index.js +3 -0
  151. package/bin/esm/internal/index.js.map +1 -0
  152. package/bin/esm/internal/type-guards.d.ts +11 -0
  153. package/bin/esm/internal/type-guards.d.ts.map +1 -0
  154. package/bin/esm/internal/type-guards.js.map +1 -0
  155. package/bin/esm/live-hooks/index.d.ts +8 -0
  156. package/bin/esm/live-hooks/index.d.ts.map +1 -0
  157. package/bin/esm/live-hooks/index.js +8 -0
  158. package/bin/esm/live-hooks/index.js.map +1 -0
  159. package/bin/esm/live-hooks/useLiveCanvas.d.ts +80 -0
  160. package/bin/esm/live-hooks/useLiveCanvas.d.ts.map +1 -0
  161. package/bin/esm/live-hooks/useLiveCanvas.js +238 -0
  162. package/bin/esm/live-hooks/useLiveCanvas.js.map +1 -0
  163. package/bin/esm/live-hooks/useLiveEvent.d.ts +59 -0
  164. package/bin/esm/live-hooks/useLiveEvent.d.ts.map +1 -0
  165. package/bin/{live-hooks → esm/live-hooks}/useLiveEvent.js +41 -5
  166. package/bin/esm/live-hooks/useLiveEvent.js.map +1 -0
  167. package/bin/esm/live-hooks/useLiveFollowMode.d.ts +163 -0
  168. package/bin/esm/live-hooks/useLiveFollowMode.d.ts.map +1 -0
  169. package/bin/{live-hooks → esm/live-hooks}/useLiveFollowMode.js +148 -5
  170. package/bin/esm/live-hooks/useLiveFollowMode.js.map +1 -0
  171. package/bin/esm/live-hooks/useLivePresence.d.ts +76 -0
  172. package/bin/esm/live-hooks/useLivePresence.d.ts.map +1 -0
  173. package/bin/{live-hooks → esm/live-hooks}/useLivePresence.js +67 -13
  174. package/bin/esm/live-hooks/useLivePresence.js.map +1 -0
  175. package/bin/esm/live-hooks/useLiveState.d.ts +66 -0
  176. package/bin/esm/live-hooks/useLiveState.d.ts.map +1 -0
  177. package/bin/{live-hooks → esm/live-hooks}/useLiveState.js +48 -3
  178. package/bin/esm/live-hooks/useLiveState.js.map +1 -0
  179. package/bin/esm/live-hooks/useLiveTimer.d.ts +80 -0
  180. package/bin/esm/live-hooks/useLiveTimer.d.ts.map +1 -0
  181. package/bin/{live-hooks → esm/live-hooks}/useLiveTimer.js +58 -3
  182. package/bin/esm/live-hooks/useLiveTimer.js.map +1 -0
  183. package/bin/esm/live-hooks/useMediaSynchronizer.d.ts +86 -0
  184. package/bin/esm/live-hooks/useMediaSynchronizer.d.ts.map +1 -0
  185. package/bin/{live-hooks → esm/live-hooks}/useMediaSynchronizer.js +65 -4
  186. package/bin/esm/live-hooks/useMediaSynchronizer.js.map +1 -0
  187. package/bin/esm/providers/AzureProvider.d.ts +113 -0
  188. package/bin/esm/providers/AzureProvider.d.ts.map +1 -0
  189. package/bin/{providers → esm/providers}/AzureProvider.js +10 -10
  190. package/bin/esm/providers/AzureProvider.js.map +1 -0
  191. package/bin/esm/providers/LiveShareProvider.d.ts +193 -0
  192. package/bin/esm/providers/LiveShareProvider.d.ts.map +1 -0
  193. package/bin/{providers → esm/providers}/LiveShareProvider.js +111 -9
  194. package/bin/esm/providers/LiveShareProvider.js.map +1 -0
  195. package/bin/esm/providers/index.d.ts +3 -0
  196. package/bin/esm/providers/index.d.ts.map +1 -0
  197. package/bin/esm/providers/index.js +3 -0
  198. package/bin/esm/providers/index.js.map +1 -0
  199. package/bin/esm/shared-hooks/index.d.ts +7 -0
  200. package/bin/esm/shared-hooks/index.d.ts.map +1 -0
  201. package/bin/esm/shared-hooks/index.js +7 -0
  202. package/bin/esm/shared-hooks/index.js.map +1 -0
  203. package/bin/esm/shared-hooks/internals/tree-node-constants.d.ts +3 -0
  204. package/bin/esm/shared-hooks/internals/tree-node-constants.d.ts.map +1 -0
  205. package/bin/esm/shared-hooks/internals/tree-node-constants.js +3 -0
  206. package/bin/esm/shared-hooks/internals/tree-node-constants.js.map +1 -0
  207. package/bin/esm/shared-hooks/internals/tree-node-types.d.ts +10 -0
  208. package/bin/esm/shared-hooks/internals/tree-node-types.d.ts.map +1 -0
  209. package/bin/esm/shared-hooks/internals/tree-node-types.js +18 -0
  210. package/bin/esm/shared-hooks/internals/tree-node-types.js.map +1 -0
  211. package/bin/esm/shared-hooks/internals/tree-node-utils.d.ts +33 -0
  212. package/bin/esm/shared-hooks/internals/tree-node-utils.d.ts.map +1 -0
  213. package/bin/esm/shared-hooks/internals/tree-node-utils.js +188 -0
  214. package/bin/esm/shared-hooks/internals/tree-node-utils.js.map +1 -0
  215. package/bin/esm/shared-hooks/useDynamicDDS.d.ts +23 -0
  216. package/bin/esm/shared-hooks/useDynamicDDS.d.ts.map +1 -0
  217. package/bin/{shared-hooks → esm/shared-hooks}/useDynamicDDS.js +20 -11
  218. package/bin/esm/shared-hooks/useDynamicDDS.js.map +1 -0
  219. package/bin/esm/shared-hooks/useSharedMap.d.ts +25 -0
  220. package/bin/esm/shared-hooks/useSharedMap.d.ts.map +1 -0
  221. package/bin/{shared-hooks → esm/shared-hooks}/useSharedMap.js +27 -13
  222. package/bin/esm/shared-hooks/useSharedMap.js.map +1 -0
  223. package/bin/esm/shared-hooks/useSharedState.d.ts +22 -0
  224. package/bin/esm/shared-hooks/useSharedState.d.ts.map +1 -0
  225. package/bin/{shared-hooks → esm/shared-hooks}/useSharedState.js +2 -2
  226. package/bin/esm/shared-hooks/useSharedState.js.map +1 -0
  227. package/bin/esm/shared-hooks/useSharedStateRegistry.d.ts +37 -0
  228. package/bin/esm/shared-hooks/useSharedStateRegistry.d.ts.map +1 -0
  229. package/bin/{shared-hooks → esm/shared-hooks}/useSharedStateRegistry.js +27 -19
  230. package/bin/esm/shared-hooks/useSharedStateRegistry.js.map +1 -0
  231. package/bin/esm/shared-hooks/useSharedTree.d.ts +57 -0
  232. package/bin/esm/shared-hooks/useSharedTree.d.ts.map +1 -0
  233. package/bin/esm/shared-hooks/useSharedTree.js +117 -0
  234. package/bin/esm/shared-hooks/useSharedTree.js.map +1 -0
  235. package/bin/esm/shared-hooks/useTreeNode.d.ts +96 -0
  236. package/bin/esm/shared-hooks/useTreeNode.d.ts.map +1 -0
  237. package/bin/esm/shared-hooks/useTreeNode.js +132 -0
  238. package/bin/esm/shared-hooks/useTreeNode.js.map +1 -0
  239. package/bin/esm/types/ActionTypes.d.ts +112 -0
  240. package/bin/esm/types/ActionTypes.d.ts.map +1 -0
  241. package/bin/esm/types/ActionTypes.js.map +1 -0
  242. package/bin/esm/types/PropTypes.d.ts +56 -0
  243. package/bin/esm/types/PropTypes.d.ts.map +1 -0
  244. package/bin/esm/types/PropTypes.js.map +1 -0
  245. package/bin/esm/types/ResultTypes.d.ts +330 -0
  246. package/bin/esm/types/ResultTypes.d.ts.map +1 -0
  247. package/bin/esm/types/ResultTypes.js.map +1 -0
  248. package/bin/esm/types/index.d.ts +4 -0
  249. package/bin/esm/types/index.d.ts.map +1 -0
  250. package/bin/esm/types/index.js +4 -0
  251. package/bin/esm/types/index.js.map +1 -0
  252. package/bin/esm/utils/index.d.ts +2 -0
  253. package/bin/esm/utils/index.d.ts.map +1 -0
  254. package/bin/esm/utils/index.js +2 -0
  255. package/bin/esm/utils/index.js.map +1 -0
  256. package/bin/esm/utils/type-check.d.ts +15 -0
  257. package/bin/esm/utils/type-check.d.ts.map +1 -0
  258. package/bin/esm/utils/type-check.js.map +1 -0
  259. package/package.json +61 -47
  260. package/src/index.ts +6 -6
  261. package/src/interfaces/index.ts +1 -1
  262. package/src/internal/index.ts +2 -2
  263. package/src/internal/type-guards.ts +1 -1
  264. package/src/live-hooks/index.ts +7 -7
  265. package/src/live-hooks/useLiveCanvas.ts +154 -82
  266. package/src/live-hooks/useLiveEvent.ts +43 -7
  267. package/src/live-hooks/useLiveFollowMode.ts +149 -6
  268. package/src/live-hooks/useLivePresence.ts +74 -17
  269. package/src/live-hooks/useLiveState.ts +49 -4
  270. package/src/live-hooks/useLiveTimer.ts +59 -4
  271. package/src/live-hooks/useMediaSynchronizer.ts +70 -5
  272. package/src/providers/AzureProvider.tsx +21 -21
  273. package/src/providers/LiveShareProvider.tsx +115 -13
  274. package/src/providers/index.ts +2 -2
  275. package/src/shared-hooks/index.ts +6 -4
  276. package/src/shared-hooks/internals/tree-node-constants.ts +2 -0
  277. package/src/shared-hooks/internals/tree-node-types.ts +26 -0
  278. package/src/shared-hooks/internals/tree-node-utils.ts +269 -0
  279. package/src/shared-hooks/useDynamicDDS.ts +28 -17
  280. package/src/shared-hooks/useSharedMap.ts +42 -17
  281. package/src/shared-hooks/useSharedState.ts +6 -3
  282. package/src/shared-hooks/useSharedStateRegistry.ts +44 -22
  283. package/src/shared-hooks/useSharedTree.ts +144 -0
  284. package/src/shared-hooks/useTreeNode.ts +147 -0
  285. package/src/types/ActionTypes.ts +13 -9
  286. package/src/types/PropTypes.ts +57 -0
  287. package/src/types/ResultTypes.ts +67 -17
  288. package/src/types/index.ts +3 -3
  289. package/src/utils/index.ts +1 -1
  290. package/tsconfig.cjs.json +14 -0
  291. package/tsconfig.json +65 -70
  292. package/bin/index.d.ts +0 -7
  293. package/bin/index.d.ts.map +0 -1
  294. package/bin/index.js +0 -7
  295. package/bin/index.js.map +0 -1
  296. package/bin/interfaces/LiveInterfaceExtensions.d.ts.map +0 -1
  297. package/bin/interfaces/LiveInterfaceExtensions.js.map +0 -1
  298. package/bin/interfaces/index.d.ts +0 -2
  299. package/bin/interfaces/index.d.ts.map +0 -1
  300. package/bin/interfaces/index.js +0 -2
  301. package/bin/interfaces/index.js.map +0 -1
  302. package/bin/internal/errors.d.ts.map +0 -1
  303. package/bin/internal/errors.js.map +0 -1
  304. package/bin/internal/index.d.ts +0 -3
  305. package/bin/internal/index.d.ts.map +0 -1
  306. package/bin/internal/index.js +0 -3
  307. package/bin/internal/index.js.map +0 -1
  308. package/bin/internal/type-guards.d.ts.map +0 -1
  309. package/bin/internal/type-guards.js.map +0 -1
  310. package/bin/live-hooks/index.d.ts +0 -8
  311. package/bin/live-hooks/index.d.ts.map +0 -1
  312. package/bin/live-hooks/index.js +0 -8
  313. package/bin/live-hooks/index.js.map +0 -1
  314. package/bin/live-hooks/useLiveCanvas.d.ts +0 -29
  315. package/bin/live-hooks/useLiveCanvas.d.ts.map +0 -1
  316. package/bin/live-hooks/useLiveCanvas.js +0 -160
  317. package/bin/live-hooks/useLiveCanvas.js.map +0 -1
  318. package/bin/live-hooks/useLiveEvent.d.ts.map +0 -1
  319. package/bin/live-hooks/useLiveEvent.js.map +0 -1
  320. package/bin/live-hooks/useLiveFollowMode.d.ts +0 -24
  321. package/bin/live-hooks/useLiveFollowMode.d.ts.map +0 -1
  322. package/bin/live-hooks/useLiveFollowMode.js.map +0 -1
  323. package/bin/live-hooks/useLivePresence.d.ts +0 -26
  324. package/bin/live-hooks/useLivePresence.d.ts.map +0 -1
  325. package/bin/live-hooks/useLivePresence.js.map +0 -1
  326. package/bin/live-hooks/useLiveState.d.ts.map +0 -1
  327. package/bin/live-hooks/useLiveState.js.map +0 -1
  328. package/bin/live-hooks/useLiveTimer.d.ts.map +0 -1
  329. package/bin/live-hooks/useLiveTimer.js.map +0 -1
  330. package/bin/live-hooks/useMediaSynchronizer.d.ts +0 -25
  331. package/bin/live-hooks/useMediaSynchronizer.d.ts.map +0 -1
  332. package/bin/live-hooks/useMediaSynchronizer.js.map +0 -1
  333. package/bin/providers/AzureProvider.d.ts.map +0 -1
  334. package/bin/providers/AzureProvider.js.map +0 -1
  335. package/bin/providers/LiveShareProvider.d.ts.map +0 -1
  336. package/bin/providers/LiveShareProvider.js.map +0 -1
  337. package/bin/providers/index.d.ts +0 -3
  338. package/bin/providers/index.d.ts.map +0 -1
  339. package/bin/providers/index.js +0 -3
  340. package/bin/providers/index.js.map +0 -1
  341. package/bin/shared-hooks/index.d.ts +0 -5
  342. package/bin/shared-hooks/index.d.ts.map +0 -1
  343. package/bin/shared-hooks/index.js +0 -5
  344. package/bin/shared-hooks/index.js.map +0 -1
  345. package/bin/shared-hooks/useDynamicDDS.d.ts.map +0 -1
  346. package/bin/shared-hooks/useDynamicDDS.js.map +0 -1
  347. package/bin/shared-hooks/useSharedMap.d.ts.map +0 -1
  348. package/bin/shared-hooks/useSharedMap.js.map +0 -1
  349. package/bin/shared-hooks/useSharedState.d.ts.map +0 -1
  350. package/bin/shared-hooks/useSharedState.js.map +0 -1
  351. package/bin/shared-hooks/useSharedStateRegistry.d.ts.map +0 -1
  352. package/bin/shared-hooks/useSharedStateRegistry.js.map +0 -1
  353. package/bin/types/ActionTypes.d.ts.map +0 -1
  354. package/bin/types/ActionTypes.js.map +0 -1
  355. package/bin/types/PropTypes.d.ts +0 -8
  356. package/bin/types/PropTypes.d.ts.map +0 -1
  357. package/bin/types/PropTypes.js.map +0 -1
  358. package/bin/types/ResultTypes.d.ts.map +0 -1
  359. package/bin/types/ResultTypes.js.map +0 -1
  360. package/bin/types/index.d.ts +0 -4
  361. package/bin/types/index.d.ts.map +0 -1
  362. package/bin/types/index.js +0 -4
  363. package/bin/types/index.js.map +0 -1
  364. package/bin/utils/index.d.ts +0 -2
  365. package/bin/utils/index.d.ts.map +0 -1
  366. package/bin/utils/index.js +0 -2
  367. package/bin/utils/index.js.map +0 -1
  368. package/bin/utils/type-check.d.ts.map +0 -1
  369. package/bin/utils/type-check.js.map +0 -1
  370. package/tsconfig.build.json +0 -6
  371. /package/bin/{interfaces → cjs/interfaces}/LiveInterfaceExtensions.d.ts +0 -0
  372. /package/bin/{internal → cjs/internal}/errors.d.ts +0 -0
  373. /package/bin/{utils → cjs/utils}/type-check.d.ts +0 -0
  374. /package/bin/{interfaces → esm/interfaces}/LiveInterfaceExtensions.js +0 -0
  375. /package/bin/{internal → esm/internal}/errors.js +0 -0
  376. /package/bin/{internal → esm/internal}/type-guards.js +0 -0
  377. /package/bin/{types → esm/types}/ActionTypes.js +0 -0
  378. /package/bin/{types → esm/types}/PropTypes.js +0 -0
  379. /package/bin/{types → esm/types}/ResultTypes.js +0 -0
  380. /package/bin/{utils → esm/utils}/type-check.js +0 -0
@@ -5,8 +5,8 @@
5
5
 
6
6
  import React from "react";
7
7
  import { FluidObject, IFluidLoadable } from "@fluidframework/core-interfaces";
8
- import { useFluidObjectsContext } from "../providers";
9
- import { LoadableObjectClass } from "fluid-framework";
8
+ import { useFluidObjectsContext } from "../providers/AzureProvider.js";
9
+ import { SharedObjectKind } from "fluid-framework";
10
10
 
11
11
  /**
12
12
  * Hook to gets or creates a DDS that corresponds to a given uniqueKey string.
@@ -14,17 +14,17 @@ import { LoadableObjectClass } from "fluid-framework";
14
14
  * @remarks
15
15
  * This hook can only be used in a child component of `<LiveShareProvider>` or `<AzureProvider>`.
16
16
  *
17
- * @template T Type of Fluid LoadableObjectClass type to load. Must conform to IFluidLoadable interface.
17
+ * @template T Type of Fluid SharedObjectKind type to load. Must conform to IFluidLoadable interface.
18
18
  * @param uniqueKey uniqueKey value for the data object
19
- * @param loadableObjectClass Fluid LoadableObjectClass<T> to create/load.
19
+ * @param objectKind Fluid SharedObjectKind<T> to create/load.
20
20
  * @param onFirstInitialize Optional. Callback function for when the DDS is first loaded
21
21
  * @returns the DDS object, which is of type T when loaded and undefined while loading
22
22
  */
23
23
  export function useDynamicDDS<
24
- T extends IFluidLoadable = FluidObject<any> & IFluidLoadable
24
+ T extends IFluidLoadable = FluidObject<any> & IFluidLoadable,
25
25
  >(
26
26
  uniqueKey: string,
27
- loadableObjectClass: LoadableObjectClass<T>,
27
+ objectClass: SharedObjectKind<T>,
28
28
  onFirstInitialize?: (dds: T) => void
29
29
  ): {
30
30
  dds: T | undefined;
@@ -37,24 +37,38 @@ export function useDynamicDDS<
37
37
  */
38
38
  const { container, clientRef } = useFluidObjectsContext();
39
39
 
40
+ const mountedRef = React.useRef(false);
41
+ React.useEffect(() => {
42
+ mountedRef.current = true;
43
+ return () => {
44
+ mountedRef.current = false;
45
+ };
46
+ }, []);
47
+
48
+ const getDDSPromisesRef = React.useRef<Map<string, Promise<T>>>(new Map());
49
+
40
50
  /**
41
51
  * Once container is available, this effect will register the setter method so that the DDS loaded
42
52
  * from `dynamicObjects` that matches `uniqueKey` can be passed back to this hook. If one does not yet exist,
43
53
  * a new DDS is automatically created. If multiple users try to create a DDS at the same time when this component first
44
- * mounts, `live-share-turbo` ensures it will ultimately self correct using last-writer wins.
54
+ * mounts, `live-share` ensures it will ultimately self correct using last-writer wins.
45
55
  */
46
56
  React.useEffect(() => {
47
57
  if (container === undefined) return;
48
- let mounted = true;
49
58
  // Callback method to set the `initialData` into the map when the DDS is first created.
50
59
  const onGetDDS = async () => {
51
60
  try {
52
- const dds = await clientRef.current.getDDS<T>(
53
- uniqueKey,
54
- loadableObjectClass,
55
- onFirstInitialize
56
- );
57
- if (mounted) {
61
+ let getPromise = getDDSPromisesRef.current.get(uniqueKey);
62
+ if (!getPromise) {
63
+ getPromise = clientRef.current.getDDS<T>(
64
+ uniqueKey,
65
+ objectClass,
66
+ onFirstInitialize
67
+ );
68
+ getDDSPromisesRef.current.set(uniqueKey, getPromise);
69
+ }
70
+ const dds = await getPromise;
71
+ if (mountedRef.current) {
58
72
  setDDS(dds);
59
73
  }
60
74
  } catch (error: unknown) {
@@ -70,9 +84,6 @@ export function useDynamicDDS<
70
84
  }
71
85
  };
72
86
  onGetDDS();
73
- return () => {
74
- mounted = false;
75
- };
76
87
  }, [container, uniqueKey, onFirstInitialize]);
77
88
 
78
89
  return {
@@ -4,17 +4,20 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { isEntries, isJSON, isMap } from "../utils";
8
- import { IUseSharedMapResults, SharedMapInitialData } from "../types";
9
- import { useDynamicDDS } from "./useDynamicDDS";
10
- import { SharedMap } from "fluid-framework";
11
- import { useFluidObjectsContext } from "../providers";
7
+ import { isEntries, isJSON, isMap } from "../utils/index.js";
8
+ import { IUseSharedMapResults, SharedMapInitialData } from "../types/index.js";
9
+ import { useDynamicDDS } from "./useDynamicDDS.js";
10
+ import { SharedMap } from "fluid-framework/legacy";
12
11
  import {
13
12
  ActionContainerNotJoinedError,
14
13
  ActionLiveDataObjectUndefinedError,
15
- } from "../internal";
14
+ } from "../internal/errors.js";
15
+ import { useFluidObjectsContext } from "../providers/AzureProvider.js";
16
+ import { useSharedTree } from "./useSharedTree.js";
16
17
 
17
18
  /**
19
+ * @deprecated use {@link useSharedTree} instead.
20
+ *
18
21
  * React hook for using a Fluid `SharedMap`.
19
22
  *
20
23
  * @remarks
@@ -28,19 +31,12 @@ import {
28
31
  * will be created, otherwise it will use the existing one.
29
32
  * @param initialData a JS Map, entries array, or JSON object to insert into the `SharedMap` when creating
30
33
  * the DDS for the first time.
31
- * @returns stateful `map` entries, `setEntry` callback, `deleteEntry` callback, and the Fluid `sharedMap`.
34
+ * @returns the Fluid `sharedMap`.
32
35
  */
33
36
  export function useSharedMap<TData = any>(
34
37
  uniqueKey: string,
35
38
  initialData?: SharedMapInitialData<TData>
36
39
  ): IUseSharedMapResults<TData> {
37
- /**
38
- * Stateful readonly map (user facing) with most recent values from `SharedMap` and its setter method.
39
- */
40
- const [map, setMap] = React.useState<ReadonlyMap<string, TData>>(
41
- getInitialData<TData>(initialData)
42
- );
43
-
44
40
  const onFirstInitialize = React.useCallback(
45
41
  (newDDS: SharedMap): void => {
46
42
  /**
@@ -64,6 +60,28 @@ export function useSharedMap<TData = any>(
64
60
 
65
61
  const { container } = useFluidObjectsContext();
66
62
 
63
+ /**
64
+ * User facing: get a value from the Fluid `SharedMap`.
65
+ */
66
+ const getEntry = React.useCallback(
67
+ (key: string) => {
68
+ if (!container) {
69
+ throw new ActionContainerNotJoinedError(
70
+ "sharedMap",
71
+ "getEntry"
72
+ );
73
+ }
74
+ if (sharedMap === undefined) {
75
+ throw new ActionLiveDataObjectUndefinedError(
76
+ "sharedMap",
77
+ "getEntry"
78
+ );
79
+ }
80
+ return sharedMap.get(key);
81
+ },
82
+ [container, sharedMap]
83
+ );
84
+
67
85
  /**
68
86
  * User facing: set a value to the Fluid `SharedMap`.
69
87
  */
@@ -108,13 +126,20 @@ export function useSharedMap<TData = any>(
108
126
  [container, sharedMap]
109
127
  );
110
128
 
129
+ const [sharedMapProxy, setSharedMapProxy] = React.useState<SharedMap>();
130
+
111
131
  // Setup change listeners, initial values, etc.
112
132
  React.useEffect(() => {
113
133
  if (!sharedMap) return;
134
+ setSharedMapProxy(sharedMap);
135
+
136
+ class SharedMapProxyHandler implements ProxyHandler<SharedMap> {}
114
137
 
115
138
  // Register valueChanged listener for `SharedMap`.
116
139
  const onValueChanged = () => {
117
- setMap(new Map<string, TData>(sharedMap.entries()));
140
+ setSharedMapProxy(
141
+ new Proxy(sharedMap, new SharedMapProxyHandler())
142
+ );
118
143
  };
119
144
  sharedMap.on("valueChanged", onValueChanged);
120
145
  // Get initial values from `SharedMap`.
@@ -127,10 +152,10 @@ export function useSharedMap<TData = any>(
127
152
  }, [sharedMap]);
128
153
 
129
154
  return {
130
- map,
155
+ sharedMap: sharedMapProxy,
156
+ getEntry,
131
157
  setEntry,
132
158
  deleteEntry,
133
- sharedMap,
134
159
  };
135
160
  }
136
161
 
@@ -4,10 +4,13 @@
4
4
  */
5
5
 
6
6
  import React from "react";
7
- import { useFluidObjectsContext } from "../providers";
8
- import { DisposeSharedStateAction, SetSharedStateAction } from "../types";
7
+ import { useFluidObjectsContext } from "../providers/index.js";
8
+ import {
9
+ DisposeSharedStateAction,
10
+ SetSharedStateAction,
11
+ } from "../types/index.js";
9
12
  import { v4 as uuid } from "uuid";
10
- import { isPrevStateCallback } from "../internal";
13
+ import { isPrevStateCallback } from "../internal/index.js";
11
14
 
12
15
  /**
13
16
  * Inspired by React's `useState` hook, `useSharedState` makes it easy to synchronize state in your app.
@@ -3,7 +3,11 @@
3
3
  * Licensed under the Microsoft Live Share SDK License.
4
4
  */
5
5
 
6
- import { IValueChanged, SharedMap } from "fluid-framework";
6
+ import {
7
+ IFluidContainer,
8
+ IValueChanged,
9
+ SharedMap,
10
+ } from "fluid-framework/legacy";
7
11
  import React from "react";
8
12
  import {
9
13
  DeleteSharedStateAction,
@@ -12,7 +16,13 @@ import {
12
16
  SetLocalStateAction,
13
17
  UnregisterSharedSetStateAction,
14
18
  UpdateSharedStateAction,
15
- } from "../types";
19
+ } from "../types/index.js";
20
+ import {
21
+ getRootDataObject,
22
+ getRootDirectory,
23
+ TurboDirectory,
24
+ TurboStateMap,
25
+ } from "@microsoft/live-share/internal";
16
26
 
17
27
  /**
18
28
  * Response for the {@link useSharedStateRegistry} hook.
@@ -52,6 +62,8 @@ export const useSharedStateRegistry = (
52
62
  Map<string, Map<string, SetLocalStateAction>>
53
63
  >(new Map());
54
64
 
65
+ const stateMap = useStateMap(results?.container);
66
+
55
67
  /**
56
68
  * @see ISharedStateRegistryResponse.registerSharedSetStateAction
57
69
  */
@@ -76,14 +88,12 @@ export const useSharedStateRegistry = (
76
88
  );
77
89
  }
78
90
  // Set initial values, if known
79
- const stateMap = results?.container.initialObjects
80
- .TURBO_STATE_MAP as SharedMap | undefined;
81
91
  const initialValue = stateMap?.get(uniqueKey);
82
92
  if (initialValue) {
83
93
  setLocalStateAction(initialValue);
84
94
  }
85
95
  },
86
- [results]
96
+ [stateMap]
87
97
  );
88
98
 
89
99
  /**
@@ -105,13 +115,10 @@ export const useSharedStateRegistry = (
105
115
  */
106
116
  const updateSharedState: UpdateSharedStateAction = React.useCallback(
107
117
  (uniqueKey: string, value: any) => {
108
- if (!results) return;
109
- const { container } = results;
110
- const stateMap = container.initialObjects
111
- .TURBO_STATE_MAP as SharedMap;
112
- stateMap.set(uniqueKey, value);
118
+ if (!stateMap) return;
119
+ stateMap?.set(uniqueKey, value);
113
120
  },
114
- [results]
121
+ [stateMap]
115
122
  );
116
123
 
117
124
  /**
@@ -119,25 +126,20 @@ export const useSharedStateRegistry = (
119
126
  */
120
127
  const deleteSharedState: DeleteSharedStateAction = React.useCallback(
121
128
  (uniqueKey: string) => {
122
- if (!results) return;
123
- const { container } = results;
129
+ if (!stateMap) return;
124
130
  let actionsMap =
125
131
  registeredSharedSetStateActionMapRef.current.get(uniqueKey);
126
132
  actionsMap?.clear();
127
- const stateMap = container.initialObjects
128
- .TURBO_STATE_MAP as SharedMap;
129
133
  stateMap.delete(uniqueKey);
130
134
  },
131
- [results]
135
+ [stateMap]
132
136
  );
133
137
 
134
138
  React.useEffect(() => {
135
- if (!results) return;
136
- const { container } = results;
137
- const stateMap = container.initialObjects.TURBO_STATE_MAP as SharedMap;
139
+ if (!stateMap) return;
138
140
  const valueChangedListener = (changed: IValueChanged): void => {
139
141
  if (registeredSharedSetStateActionMapRef.current.has(changed.key)) {
140
- const value = stateMap.get(changed.key);
142
+ const value = stateMap?.get(changed.key);
141
143
  const actionMap =
142
144
  registeredSharedSetStateActionMapRef.current.get(
143
145
  changed.key
@@ -157,9 +159,9 @@ export const useSharedStateRegistry = (
157
159
  });
158
160
  });
159
161
  return () => {
160
- stateMap.off("valueChanged", valueChangedListener);
162
+ stateMap?.off("valueChanged", valueChangedListener);
161
163
  };
162
- }, [results]);
164
+ }, [stateMap]);
163
165
 
164
166
  return {
165
167
  registerSharedSetStateAction,
@@ -168,3 +170,23 @@ export const useSharedStateRegistry = (
168
170
  deleteSharedState,
169
171
  };
170
172
  };
173
+
174
+ const useStateMap = (container: IFluidContainer | undefined) => {
175
+ const [stateMap, setStateMap] = React.useState<SharedMap | undefined>();
176
+ React.useEffect(() => {
177
+ if (!container) {
178
+ return;
179
+ }
180
+ const rootDataObject = getRootDataObject(container);
181
+ const rootDirectory = getRootDirectory(rootDataObject);
182
+ const turboDir = rootDirectory.getSubDirectory(TurboDirectory);
183
+ turboDir
184
+ ?.get(TurboStateMap)
185
+ .get()
186
+ .then((state: SharedMap) => {
187
+ setStateMap(state);
188
+ });
189
+ }, [container]);
190
+
191
+ return stateMap;
192
+ };
@@ -0,0 +1,144 @@
1
+ import {
2
+ ImplicitFieldSchema,
3
+ TreeViewConfiguration,
4
+ SharedTree,
5
+ TreeView,
6
+ ITree,
7
+ InsertableTreeFieldFromImplicitField,
8
+ TreeFieldFromImplicitField,
9
+ } from "fluid-framework";
10
+ import { IUseSharedTreeResults } from "../types/index.js";
11
+ import { useDynamicDDS, useTreeNode } from "../shared-hooks/index.js";
12
+ import React from "react";
13
+
14
+ /**
15
+ * Creates a new Fluid `SharedTree` instance if one doesn't already exist.
16
+ * @remarks
17
+ * Use the `root` variable from the {@link IUseSharedTreeResults} response from this hook with {@link useTreeNode}.
18
+ * This makes `root` stateful with React whenever a leaf of `root` changes.
19
+ *
20
+ * @param uniqueKey the unique key for the `SharedTree`. If one does not yet exist, a new `SharedTree` will be created.
21
+ * Otherwise it will use the existing one.
22
+ * @param treeViewConfiguration the tree view configuration that contains the `SharedTree` field schema.
23
+ * @param initialData the initial data to load into the `SharedTree` when it is first created.
24
+ * @returns the {@link IUseSharedTreeResults} with the `root` node.
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * import { SchemaFactory, TreeViewConfiguration } from "fluid-framework";
29
+ * import { useSharedTree, useTreeNode } from "@microsoft/live-share-react";
30
+ * // Declare a schema factory with your unique uuid
31
+ * const sf = new SchemaFactory("fc1db2e8-0000-11ee-be57-0242ac120002");
32
+ * class YourObject extends sf.object("YourObject", {
33
+ * listChangedCount: sf.number,
34
+ * list: sf.array(sf.string),
35
+ * }) {
36
+ * // You can add your own utility functions
37
+ * insert() {
38
+ * this.list.insertAtEnd("some text");
39
+ * this.listChangedCount += 1;
40
+ * }
41
+ * }
42
+ * const config = new TreeViewConfiguration({ schema: YourObject });
43
+ * const initialData = new YourObject({
44
+ * number: 0,
45
+ * list: [],
46
+ * });
47
+ *
48
+ * // Must be child component of <LiveShareProvider> or <AzureProvider>
49
+ * export const YourComponent = () => {
50
+ * // Get the root node of the `SharedTree` mapped to "some-unique-key"
51
+ * const { root } = useSharedTree("some-unique-key", config, initialData);
52
+ * // Makes root stateful / automatically update when the node changes (e.g., node.count)
53
+ * const { node } = useTreeNode(root);
54
+ * // node.list is its own TreeNode, so we make it stateful as well
55
+ * const { node: list } = useTreeNode(node?.list);
56
+ * if (!node || !list) return (<>"Loading"</>);
57
+ * return (
58
+ * <div>
59
+ * <div>Changed: {node.listChangedCount}</div>
60
+ * <button onClick={() => node.insert()}>Insert</button>
61
+ * { list.map((item) => <div key={item}>{item}</div>) }
62
+ * </div>
63
+ * );
64
+ * }
65
+ * ```
66
+ */
67
+ export function useSharedTree<
68
+ TSchema extends ImplicitFieldSchema = ImplicitFieldSchema,
69
+ >(
70
+ uniqueKey: string,
71
+ treeViewConfiguration: TreeViewConfiguration<TSchema>,
72
+ initialData: InsertableTreeFieldFromImplicitField<TSchema>
73
+ ): IUseSharedTreeResults<TSchema> {
74
+ const [treeView, setTreeView] = React.useState<TreeView<TSchema>>();
75
+ const [root, setRoot] =
76
+ React.useState<TreeFieldFromImplicitField<TSchema>>();
77
+
78
+ const onFirstInitialize = React.useCallback(
79
+ (newDDS: ITree): void => {
80
+ try {
81
+ // Create a `treeView` with the provided `treeViewConfiguration`
82
+ const _treeView = newDDS.viewWith(treeViewConfiguration);
83
+ if (_treeView.compatibility.canInitialize) {
84
+ // Set initial data
85
+ _treeView.initialize(initialData);
86
+ }
87
+ // `onFirstInitialize` is only called for the user that created the tree, but we need this object for all clients.
88
+ // Dispose, since we will call `sharedTree.viewWith` in a `useEffect` down below and set it to state.
89
+ _treeView.dispose();
90
+ } catch (err) {
91
+ console.error(err);
92
+ }
93
+ },
94
+ [treeViewConfiguration, initialData]
95
+ );
96
+ /**
97
+ * User facing: dynamically load the `SharedTree` DDS for the given unique key.
98
+ */
99
+ const { dds: sharedTree } = useDynamicDDS<ITree>(
100
+ uniqueKey,
101
+ SharedTree,
102
+ onFirstInitialize
103
+ );
104
+
105
+ /**
106
+ * Sets the tree view and root view
107
+ */
108
+ React.useEffect(() => {
109
+ if (!sharedTree) return;
110
+ let _treeView: TreeView<TSchema> | undefined = undefined;
111
+ try {
112
+ // Create a `treeView` with the provided `treeViewConfiguration`
113
+ _treeView = sharedTree.viewWith(treeViewConfiguration);
114
+ setTreeView(_treeView);
115
+ } catch (err) {
116
+ console.error(err);
117
+ }
118
+
119
+ // Listen for changes to root view
120
+ const updateRoot = (): void => {
121
+ if (_treeView?.compatibility.canView) {
122
+ setRoot(_treeView.root);
123
+ } else {
124
+ setRoot(undefined);
125
+ }
126
+ };
127
+
128
+ updateRoot();
129
+ const unsubscribeToRoot = _treeView?.events.on(
130
+ "rootChanged",
131
+ updateRoot
132
+ );
133
+ return () => {
134
+ _treeView?.dispose();
135
+ unsubscribeToRoot?.();
136
+ };
137
+ }, [sharedTree, treeViewConfiguration]);
138
+
139
+ return {
140
+ treeView,
141
+ sharedTree,
142
+ root,
143
+ };
144
+ }
@@ -0,0 +1,147 @@
1
+ import { Tree, TreeChangeEvents, TreeNode } from "fluid-framework";
2
+ import { IUseTreeNodeResults } from "../types/index.js";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import {
5
+ getRawNode,
6
+ buildProxy,
7
+ setUpListenersForNodeChildren,
8
+ } from "./internals/tree-node-utils.js";
9
+
10
+ /**
11
+ * Makes a provided Fluid `TreeNode` stateful in React.
12
+ *
13
+ * @param node the Fluid `SharedTree` `TreeNode` instance to make stateful.
14
+ * @param stateChangeType listener type to apply changes for. Default value is "nodeChanged", which has the most optimal performance.
15
+ * Provide "treeChanged" to make all children nodes stateful as well when those child nodes change.
16
+ * When using the default, you must pass all child `TreeNode` values into `useTreeNode` for them to be stateful as well.
17
+ * @returns a stateful version `node`
18
+ *
19
+ * @example
20
+ * Example using default `"nodeChanged"` `stateChangeType`
21
+ * ```tsx
22
+ * import { SchemaFactory, TreeViewConfiguration } from "fluid-framework";
23
+ * import { useSharedTree, useTreeNode } from "@microsoft/live-share-react";
24
+ * // Declare a schema factory with your unique uuid
25
+ * const sf = new SchemaFactory("fc1db2e8-0000-11ee-be57-0242ac120002");
26
+ * class YourObject extends sf.object("YourObject", {
27
+ * listChangedCount: sf.number,
28
+ * list: sf.array(sf.string),
29
+ * }) {
30
+ * // You can add your own utility functions
31
+ * insert() {
32
+ * this.list.insertAtEnd("some text");
33
+ * this.listChangedCount += 1;
34
+ * }
35
+ * }
36
+ * const config = new TreeViewConfiguration({ schema: YourObject });
37
+ * const initialData = new YourObject({
38
+ * number: 0,
39
+ * list: [],
40
+ * });
41
+ *
42
+ * // Must be child component of <LiveShareProvider> or <AzureProvider>
43
+ * export const YourComponent = () => {
44
+ * // Get the root node of the `SharedTree` mapped to "some-unique-key"
45
+ * const { root } = useSharedTree("some-unique-key", config, initialData);
46
+ * // Makes root stateful / automatically update when the node changes (e.g., node.count)
47
+ * const { node } = useTreeNode(root);
48
+ * // node.list is its own TreeNode, so we make it stateful as well
49
+ * const { node: list } = useTreeNode(node?.list);
50
+ * if (!node || !list) return (<>"Loading"</>);
51
+ * return (
52
+ * <div>
53
+ * <div>Changed: {node.listChangedCount}</div>
54
+ * <button onClick={() => node.insert()}>Insert</button>
55
+ * { list.map((item) => <div key={item}>{item}</div>) }
56
+ * </div>
57
+ * );
58
+ * }
59
+ * ```
60
+ *
61
+ * @example
62
+ * Example using `"treeChanged"` `stateChangeType`
63
+ * ```tsx
64
+ * import { SchemaFactory, TreeViewConfiguration } from "fluid-framework";
65
+ * import { useSharedTree, useTreeNode } from "@microsoft/live-share-react";
66
+ * // Declare a schema factory with your unique uuid
67
+ * const sf = new SchemaFactory("fc1db2e8-0000-11ee-be57-0242ac120002");
68
+ *
69
+ * class ChildObject extends sf.object("ChildObject", {
70
+ * count: sf.number,
71
+ * }) {
72
+ * increment() {
73
+ * this.count += 1;
74
+ * }
75
+ * }
76
+ *
77
+ * class YourObject extends sf.object("YourObject", {
78
+ * child: ChildObject,
79
+ * }) {}
80
+ * const config = new TreeViewConfiguration({ schema: YourObject });
81
+ * const initialData = new YourObject({
82
+ * child: new ChildObject({ count: 0 }),
83
+ * });
84
+ *
85
+ * // Must be child component of <LiveShareProvider> or <AzureProvider>
86
+ * export const YourComponent = () => {
87
+ * // Get the root node of the `SharedTree` mapped to "some-unique-key"
88
+ * const { root } = useSharedTree("some-unique-key", config, initialData);
89
+ * // Using "treeChanged" prop makes all children nodes stateful as well.
90
+ * // Use with caution / measure render performance with React dev tools.
91
+ * const { node } = useTreeNode(root, "treeChanged");
92
+ * if (!node) return (<>"Loading"</>);
93
+ * return (
94
+ * <div>
95
+ * <div>Changed: {node.child.count}</div>
96
+ * <button onClick={() => node.increment()}>Insert</button>
97
+ * </div>
98
+ * );
99
+ * }
100
+ * ```
101
+ */
102
+ export function useTreeNode<TNode extends TreeNode | undefined = TreeNode>(
103
+ node: TNode,
104
+ stateChangeType: keyof TreeChangeEvents = "nodeChanged"
105
+ ): IUseTreeNodeResults<TNode> {
106
+ // When we return a proxied node to a developer, it's possible they will pass it back to us in this hook.
107
+ // We can't listen using Tree.on using a proxy node though...
108
+ // Thus, if we are already listening to a node from another instance of this hook, we look for the unproxied node.
109
+ const rawNode = getRawNode(node);
110
+ const [proxyNode, setProxyNode] = useState<TNode>(rawNode);
111
+ const treeProxyMapRef = useRef<WeakMap<TreeNode, TreeNode>>(new WeakMap());
112
+
113
+ useEffect(() => {
114
+ if (!rawNode) return;
115
+
116
+ // Set default value
117
+ setProxyNode(rawNode);
118
+ function onNodeChanged() {
119
+ if (!rawNode) return;
120
+
121
+ const proxyNode = buildProxy(rawNode, treeProxyMapRef.current);
122
+ setProxyNode(proxyNode);
123
+ }
124
+ // Listen to Fluid's base node from their TreeView so Fluid flex nodes continue to work
125
+ const unsubscribeListeners: (() => void)[] = [
126
+ Tree.on(rawNode, "nodeChanged", onNodeChanged),
127
+ ];
128
+ if (stateChangeType === "treeChanged") {
129
+ // Recursively for all child nodes of this node in the tree
130
+ setUpListenersForNodeChildren(
131
+ rawNode,
132
+ rawNode,
133
+ treeProxyMapRef.current,
134
+ unsubscribeListeners,
135
+ // TODO: fix typing so casting isn't necessary
136
+ setProxyNode as any
137
+ );
138
+ }
139
+ return () => {
140
+ unsubscribeListeners.forEach((unsubscribe) => unsubscribe());
141
+ };
142
+ }, [rawNode, stateChangeType]);
143
+
144
+ return {
145
+ node: proxyNode,
146
+ };
147
+ }