@supernova-studio/client 1.96.6 → 1.96.7

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 (349) hide show
  1. package/dist/index.d.mts +101177 -143251
  2. package/dist/index.d.ts +101177 -143251
  3. package/dist/index.js +408 -105
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +5542 -5239
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +20 -9
  8. package/src/api/client.ts +62 -0
  9. package/src/api/conversion/analytics/index.ts +3 -0
  10. package/src/api/conversion/analytics/page-visits-to-comparison-dto.ts +65 -0
  11. package/src/api/conversion/analytics/page-visits-to-dto.ts +68 -0
  12. package/src/api/conversion/analytics/page-visits-to-heatmap-dto.ts +49 -0
  13. package/src/api/conversion/documentation/documentation-group-v1-to-dto.ts +114 -0
  14. package/src/api/conversion/documentation/documentation-group-v2-to-dto.ts +91 -0
  15. package/src/api/conversion/documentation/documentation-item-configuration-v1-to-dto.ts +52 -0
  16. package/src/api/conversion/documentation/documentation-item-configuration-v2-to-dto.ts +34 -0
  17. package/src/api/conversion/documentation/documentation-page-to-dto-utils.ts +134 -0
  18. package/src/api/conversion/documentation/documentation-page-v1-to-dto.ts +69 -0
  19. package/src/api/conversion/documentation/documentation-page-v2-to-dto.ts +84 -0
  20. package/src/api/conversion/documentation/documentation-settings-to-dto.ts +14 -0
  21. package/src/api/conversion/documentation/index.ts +8 -0
  22. package/src/api/conversion/export/index.ts +1 -0
  23. package/src/api/conversion/export/pipeline.ts +27 -0
  24. package/src/api/conversion/index.ts +4 -0
  25. package/src/api/conversion/integrations/git.ts +37 -0
  26. package/src/api/conversion/integrations/index.ts +2 -0
  27. package/src/api/conversion/integrations/integration.ts +37 -0
  28. package/src/api/dto/access-tokens/access-token.ts +45 -0
  29. package/src/api/dto/access-tokens/index.ts +1 -0
  30. package/src/api/dto/aux/color.ts +7 -0
  31. package/src/api/dto/aux/index.ts +4 -0
  32. package/src/api/dto/aux/meta.ts +8 -0
  33. package/src/api/dto/aux/object-metadata.ts +29 -0
  34. package/src/api/dto/aux/pagination.ts +8 -0
  35. package/src/api/dto/bff/app-bootstrap-data.ts +20 -0
  36. package/src/api/dto/bff/index.ts +1 -0
  37. package/src/api/dto/collections/index.ts +1 -0
  38. package/src/api/dto/collections/token-collection.ts +32 -0
  39. package/src/api/dto/design-systems/brand.ts +44 -0
  40. package/src/api/dto/design-systems/code-component-usage.ts +52 -0
  41. package/src/api/dto/design-systems/code-component.ts +101 -0
  42. package/src/api/dto/design-systems/code-history.ts +43 -0
  43. package/src/api/dto/design-systems/code-scan.ts +29 -0
  44. package/src/api/dto/design-systems/code-snapshots.ts +46 -0
  45. package/src/api/dto/design-systems/component.ts +40 -0
  46. package/src/api/dto/design-systems/contact.ts +11 -0
  47. package/src/api/dto/design-systems/data-source.ts +216 -0
  48. package/src/api/dto/design-systems/design-system.ts +75 -0
  49. package/src/api/dto/design-systems/documentation-search.ts +31 -0
  50. package/src/api/dto/design-systems/elements-diff.ts +14 -0
  51. package/src/api/dto/design-systems/figma-variables.ts +122 -0
  52. package/src/api/dto/design-systems/file.ts +71 -0
  53. package/src/api/dto/design-systems/import-job.ts +62 -0
  54. package/src/api/dto/design-systems/index.ts +24 -0
  55. package/src/api/dto/design-systems/members.ts +52 -0
  56. package/src/api/dto/design-systems/redirects.ts +33 -0
  57. package/src/api/dto/design-systems/role.ts +11 -0
  58. package/src/api/dto/design-systems/stats.ts +20 -0
  59. package/src/api/dto/design-systems/storybook.ts +45 -0
  60. package/src/api/dto/design-systems/user-design-systems.ts +10 -0
  61. package/src/api/dto/design-systems/version-room.ts +12 -0
  62. package/src/api/dto/design-systems/version.ts +56 -0
  63. package/src/api/dto/design-systems/view.ts +45 -0
  64. package/src/api/dto/design-tokens/design-token.ts +78 -0
  65. package/src/api/dto/design-tokens/index.ts +1 -0
  66. package/src/api/dto/documentation/analytics-v2.ts +80 -0
  67. package/src/api/dto/documentation/analytics.ts +32 -0
  68. package/src/api/dto/documentation/anchor.ts +15 -0
  69. package/src/api/dto/documentation/approvals.ts +21 -0
  70. package/src/api/dto/documentation/block-definition.ts +28 -0
  71. package/src/api/dto/documentation/block.ts +6 -0
  72. package/src/api/dto/documentation/documentation-page-snapshot.ts +18 -0
  73. package/src/api/dto/documentation/documentation.ts +34 -0
  74. package/src/api/dto/documentation/index.ts +11 -0
  75. package/src/api/dto/documentation/link-preview.ts +23 -0
  76. package/src/api/dto/documentation/publish.ts +23 -0
  77. package/src/api/dto/documentation/room.ts +12 -0
  78. package/src/api/dto/elements/components/figma-component-group.ts +19 -0
  79. package/src/api/dto/elements/components/figma-component.ts +56 -0
  80. package/src/api/dto/elements/components/index.ts +2 -0
  81. package/src/api/dto/elements/documentation/configuration.ts +20 -0
  82. package/src/api/dto/elements/documentation/draft-state.ts +37 -0
  83. package/src/api/dto/elements/documentation/group-action.ts +108 -0
  84. package/src/api/dto/elements/documentation/group-v1.ts +35 -0
  85. package/src/api/dto/elements/documentation/group-v2.ts +117 -0
  86. package/src/api/dto/elements/documentation/hierarchy.ts +25 -0
  87. package/src/api/dto/elements/documentation/index.ts +16 -0
  88. package/src/api/dto/elements/documentation/item-configuration-v1.ts +24 -0
  89. package/src/api/dto/elements/documentation/item-configuration-v2.ts +14 -0
  90. package/src/api/dto/elements/documentation/metadata.ts +8 -0
  91. package/src/api/dto/elements/documentation/page-actions-v2.ts +138 -0
  92. package/src/api/dto/elements/documentation/page-content.ts +15 -0
  93. package/src/api/dto/elements/documentation/page-dependencies.ts +30 -0
  94. package/src/api/dto/elements/documentation/page-v1.ts +21 -0
  95. package/src/api/dto/elements/documentation/page-v2.ts +132 -0
  96. package/src/api/dto/elements/documentation/settings.ts +9 -0
  97. package/src/api/dto/elements/documentation/structure.ts +37 -0
  98. package/src/api/dto/elements/elements-action-v2.ts +125 -0
  99. package/src/api/dto/elements/figma-nodes/figma-node-structure.ts +27 -0
  100. package/src/api/dto/elements/figma-nodes/figma-node-v1.ts +32 -0
  101. package/src/api/dto/elements/figma-nodes/figma-node-v2.ts +32 -0
  102. package/src/api/dto/elements/figma-nodes/figma-node.ts +103 -0
  103. package/src/api/dto/elements/figma-nodes/index.ts +5 -0
  104. package/src/api/dto/elements/figma-nodes/node-actions-v2.ts +25 -0
  105. package/src/api/dto/elements/frame-node-structures/frame-node-structure.ts +17 -0
  106. package/src/api/dto/elements/frame-node-structures/index.ts +1 -0
  107. package/src/api/dto/elements/get-elements-v2.ts +27 -0
  108. package/src/api/dto/elements/index.ts +7 -0
  109. package/src/api/dto/elements/properties/index.ts +2 -0
  110. package/src/api/dto/elements/properties/property-definitions.ts +75 -0
  111. package/src/api/dto/elements/properties/property-values.ts +50 -0
  112. package/src/api/dto/events/forge-project.ts +51 -0
  113. package/src/api/dto/events/index.ts +2 -0
  114. package/src/api/dto/events/workspace.ts +81 -0
  115. package/src/api/dto/export/exporter-property.ts +114 -0
  116. package/src/api/dto/export/exporter.ts +115 -0
  117. package/src/api/dto/export/filter.ts +20 -0
  118. package/src/api/dto/export/index.ts +5 -0
  119. package/src/api/dto/export/job.ts +114 -0
  120. package/src/api/dto/export/pipeline.ts +60 -0
  121. package/src/api/dto/figma-components/assets/download.ts +30 -0
  122. package/src/api/dto/figma-components/assets/index.ts +1 -0
  123. package/src/api/dto/figma-components/index.ts +1 -0
  124. package/src/api/dto/figma-exporter/figma-node.ts +11 -0
  125. package/src/api/dto/figma-exporter/index.ts +1 -0
  126. package/src/api/dto/files/files.ts +94 -0
  127. package/src/api/dto/files/index.ts +1 -0
  128. package/src/api/dto/forge/agent.ts +38 -0
  129. package/src/api/dto/forge/artifact.ts +94 -0
  130. package/src/api/dto/forge/feature-messages.ts +551 -0
  131. package/src/api/dto/forge/feature-room.ts +12 -0
  132. package/src/api/dto/forge/figma-node.ts +117 -0
  133. package/src/api/dto/forge/index.ts +28 -0
  134. package/src/api/dto/forge/iteration-message-old.ts +43 -0
  135. package/src/api/dto/forge/knowledge-item.ts +67 -0
  136. package/src/api/dto/forge/memory.ts +67 -0
  137. package/src/api/dto/forge/participant.ts +44 -0
  138. package/src/api/dto/forge/project-action.ts +123 -0
  139. package/src/api/dto/forge/project-artifact-room.ts +12 -0
  140. package/src/api/dto/forge/project-artifact.ts +85 -0
  141. package/src/api/dto/forge/project-context-feedback.ts +141 -0
  142. package/src/api/dto/forge/project-context-override.ts +41 -0
  143. package/src/api/dto/forge/project-context-scope.ts +23 -0
  144. package/src/api/dto/forge/project-context-v2.ts +228 -0
  145. package/src/api/dto/forge/project-context.ts +72 -0
  146. package/src/api/dto/forge/project-feature.ts +86 -0
  147. package/src/api/dto/forge/project-figma-node.ts +9 -0
  148. package/src/api/dto/forge/project-file.ts +48 -0
  149. package/src/api/dto/forge/project-invitation.ts +46 -0
  150. package/src/api/dto/forge/project-iteration-old.ts +54 -0
  151. package/src/api/dto/forge/project-member.ts +67 -0
  152. package/src/api/dto/forge/project-room.ts +12 -0
  153. package/src/api/dto/forge/project-section.ts +37 -0
  154. package/src/api/dto/forge/project.ts +105 -0
  155. package/src/api/dto/forge/relation.ts +34 -0
  156. package/src/api/dto/forge/threads.ts +153 -0
  157. package/src/api/dto/index.ts +25 -0
  158. package/src/api/dto/liveblocks/auth-response.ts +7 -0
  159. package/src/api/dto/liveblocks/index.ts +1 -0
  160. package/src/api/dto/mcp/index.ts +1 -0
  161. package/src/api/dto/mcp/stream.ts +17 -0
  162. package/src/api/dto/notifications/index.ts +2 -0
  163. package/src/api/dto/notifications/notifications.ts +65 -0
  164. package/src/api/dto/notifications/settings.ts +10 -0
  165. package/src/api/dto/portal/index.ts +1 -0
  166. package/src/api/dto/portal/portal-settings.ts +45 -0
  167. package/src/api/dto/sandboxes/index.ts +1 -0
  168. package/src/api/dto/sandboxes/template.ts +143 -0
  169. package/src/api/dto/storybook-sites/index.ts +1 -0
  170. package/src/api/dto/storybook-sites/storybook-sites.ts +60 -0
  171. package/src/api/dto/themes/index.ts +2 -0
  172. package/src/api/dto/themes/override.ts +27 -0
  173. package/src/api/dto/themes/theme.ts +53 -0
  174. package/src/api/dto/threads/index.ts +1 -0
  175. package/src/api/dto/threads/threads.ts +280 -0
  176. package/src/api/dto/trail-events/index.ts +1 -0
  177. package/src/api/dto/trail-events/trail-events.ts +172 -0
  178. package/src/api/dto/users/authenticated-user.ts +92 -0
  179. package/src/api/dto/users/index.ts +2 -0
  180. package/src/api/dto/users/user.ts +27 -0
  181. package/src/api/dto/workspaces/billing.ts +156 -0
  182. package/src/api/dto/workspaces/enums.ts +13 -0
  183. package/src/api/dto/workspaces/git.ts +32 -0
  184. package/src/api/dto/workspaces/index.ts +15 -0
  185. package/src/api/dto/workspaces/integrations.ts +34 -0
  186. package/src/api/dto/workspaces/invitations.ts +47 -0
  187. package/src/api/dto/workspaces/ip-whitelist.ts +33 -0
  188. package/src/api/dto/workspaces/knowledge-items-search.ts +37 -0
  189. package/src/api/dto/workspaces/login-screen.ts +42 -0
  190. package/src/api/dto/workspaces/membership.ts +55 -0
  191. package/src/api/dto/workspaces/npm-registry.ts +62 -0
  192. package/src/api/dto/workspaces/products.ts +45 -0
  193. package/src/api/dto/workspaces/subscription.ts +170 -0
  194. package/src/api/dto/workspaces/transfer-ownership.ts +7 -0
  195. package/src/api/dto/workspaces/untyped-data.ts +35 -0
  196. package/src/api/dto/workspaces/workspace.ts +49 -0
  197. package/src/api/endpoints/auth-tokens.ts +28 -0
  198. package/src/api/endpoints/codegen/codegen.ts +16 -0
  199. package/src/api/endpoints/codegen/ds-pipelines.ts +37 -0
  200. package/src/api/endpoints/codegen/exporters.ts +54 -0
  201. package/src/api/endpoints/codegen/index.ts +5 -0
  202. package/src/api/endpoints/codegen/jobs.ts +15 -0
  203. package/src/api/endpoints/codegen/pipelines.ts +55 -0
  204. package/src/api/endpoints/design-system/analytics.ts +14 -0
  205. package/src/api/endpoints/design-system/bff.ts +13 -0
  206. package/src/api/endpoints/design-system/code-snapshots.ts +47 -0
  207. package/src/api/endpoints/design-system/contact.ts +12 -0
  208. package/src/api/endpoints/design-system/design-systems.ts +90 -0
  209. package/src/api/endpoints/design-system/figma-node-structures.ts +20 -0
  210. package/src/api/endpoints/design-system/index.ts +11 -0
  211. package/src/api/endpoints/design-system/members.ts +24 -0
  212. package/src/api/endpoints/design-system/redirects.ts +46 -0
  213. package/src/api/endpoints/design-system/sources.ts +80 -0
  214. package/src/api/endpoints/design-system/storybook.ts +28 -0
  215. package/src/api/endpoints/design-system/versions/brands.ts +45 -0
  216. package/src/api/endpoints/design-system/versions/documentation.ts +107 -0
  217. package/src/api/endpoints/design-system/versions/ds-components.ts +30 -0
  218. package/src/api/endpoints/design-system/versions/elements-action.ts +65 -0
  219. package/src/api/endpoints/design-system/versions/elements.ts +27 -0
  220. package/src/api/endpoints/design-system/versions/figma-component-groups.ts +13 -0
  221. package/src/api/endpoints/design-system/versions/figma-components.ts +15 -0
  222. package/src/api/endpoints/design-system/versions/figma-frame-structures.ts +13 -0
  223. package/src/api/endpoints/design-system/versions/files.ts +43 -0
  224. package/src/api/endpoints/design-system/versions/import-jobs.ts +13 -0
  225. package/src/api/endpoints/design-system/versions/index.ts +19 -0
  226. package/src/api/endpoints/design-system/versions/overrides.ts +17 -0
  227. package/src/api/endpoints/design-system/versions/property-definitions.ts +43 -0
  228. package/src/api/endpoints/design-system/versions/property-values.ts +25 -0
  229. package/src/api/endpoints/design-system/versions/stats.ts +12 -0
  230. package/src/api/endpoints/design-system/versions/themes.ts +35 -0
  231. package/src/api/endpoints/design-system/versions/token-collections.ts +13 -0
  232. package/src/api/endpoints/design-system/versions/token-groups.ts +30 -0
  233. package/src/api/endpoints/design-system/versions/tokens.ts +29 -0
  234. package/src/api/endpoints/design-system/versions/versions.ts +90 -0
  235. package/src/api/endpoints/feedback.ts +60 -0
  236. package/src/api/endpoints/files.ts +25 -0
  237. package/src/api/endpoints/forge/agents.ts +54 -0
  238. package/src/api/endpoints/forge/artifacts.ts +54 -0
  239. package/src/api/endpoints/forge/documents.ts +18 -0
  240. package/src/api/endpoints/forge/feature-artifacts.ts +39 -0
  241. package/src/api/endpoints/forge/feature-iterations.ts +49 -0
  242. package/src/api/endpoints/forge/feature-messages.ts +68 -0
  243. package/src/api/endpoints/forge/features.ts +63 -0
  244. package/src/api/endpoints/forge/forge.ts +38 -0
  245. package/src/api/endpoints/forge/index.ts +16 -0
  246. package/src/api/endpoints/forge/iteration-tags.ts +13 -0
  247. package/src/api/endpoints/forge/memory.ts +41 -0
  248. package/src/api/endpoints/forge/project-contexts.ts +49 -0
  249. package/src/api/endpoints/forge/project-files.ts +41 -0
  250. package/src/api/endpoints/forge/project-invitations.ts +39 -0
  251. package/src/api/endpoints/forge/project-iterations.ts +65 -0
  252. package/src/api/endpoints/forge/project-members.ts +55 -0
  253. package/src/api/endpoints/forge/projects.ts +56 -0
  254. package/src/api/endpoints/index.ts +13 -0
  255. package/src/api/endpoints/liveblocks.ts +14 -0
  256. package/src/api/endpoints/mcp/index.ts +1 -0
  257. package/src/api/endpoints/mcp/streams.ts +21 -0
  258. package/src/api/endpoints/sandboxes/builds.ts +30 -0
  259. package/src/api/endpoints/sandboxes/index.ts +3 -0
  260. package/src/api/endpoints/sandboxes/sandboxes.ts +13 -0
  261. package/src/api/endpoints/sandboxes/templates.ts +16 -0
  262. package/src/api/endpoints/storybook-sites.ts +42 -0
  263. package/src/api/endpoints/threads.ts +38 -0
  264. package/src/api/endpoints/users.ts +26 -0
  265. package/src/api/endpoints/workspaces/billing.ts +24 -0
  266. package/src/api/endpoints/workspaces/chat-threads.ts +95 -0
  267. package/src/api/endpoints/workspaces/index.ts +9 -0
  268. package/src/api/endpoints/workspaces/integrations.ts +15 -0
  269. package/src/api/endpoints/workspaces/invites.ts +34 -0
  270. package/src/api/endpoints/workspaces/knowledge-items.ts +59 -0
  271. package/src/api/endpoints/workspaces/members.ts +31 -0
  272. package/src/api/endpoints/workspaces/npm-register.ts +20 -0
  273. package/src/api/endpoints/workspaces/subscription.ts +31 -0
  274. package/src/api/endpoints/workspaces/workspaces.ts +84 -0
  275. package/src/api/index.ts +6 -0
  276. package/src/api/payloads/design-systems/code-snapshots.ts +27 -0
  277. package/src/api/payloads/design-systems/index.ts +3 -0
  278. package/src/api/payloads/design-systems/update-design-system.ts +42 -0
  279. package/src/api/payloads/design-systems/version.ts +29 -0
  280. package/src/api/payloads/documentation/analytics.ts +36 -0
  281. package/src/api/payloads/documentation/block-definitions.ts +18 -0
  282. package/src/api/payloads/documentation/design-data-doc-diff.ts +7 -0
  283. package/src/api/payloads/documentation/index.ts +3 -0
  284. package/src/api/payloads/export/index.ts +1 -0
  285. package/src/api/payloads/export/pipeline.ts +111 -0
  286. package/src/api/payloads/index.ts +6 -0
  287. package/src/api/payloads/liveblocks/auth.ts +7 -0
  288. package/src/api/payloads/liveblocks/index.ts +1 -0
  289. package/src/api/payloads/users/index.ts +1 -0
  290. package/src/api/payloads/users/notifications/index.ts +1 -0
  291. package/src/api/payloads/users/notifications/notification-settings.ts +17 -0
  292. package/src/api/payloads/workspaces/index.ts +2 -0
  293. package/src/api/payloads/workspaces/workspace-configuration.ts +62 -0
  294. package/src/api/payloads/workspaces/workspace-integrations.ts +35 -0
  295. package/src/api/transport/index.ts +2 -0
  296. package/src/api/transport/request-executor-error.ts +60 -0
  297. package/src/api/transport/request-executor.ts +94 -0
  298. package/src/events/design-system.ts +21 -0
  299. package/src/events/event.ts +6 -0
  300. package/src/events/index.ts +2 -0
  301. package/src/index.ts +5 -0
  302. package/src/sync/docs-local-action-executor.ts +412 -0
  303. package/src/sync/docs-structure-repo.ts +283 -0
  304. package/src/sync/index.ts +5 -0
  305. package/src/sync/project-content-repo.ts +215 -0
  306. package/src/sync/project-local-action-executor.ts +415 -0
  307. package/src/sync/types.ts +37 -0
  308. package/src/utils/figma.ts +72 -0
  309. package/src/utils/hash.ts +62 -0
  310. package/src/utils/index.ts +4 -0
  311. package/src/utils/query.ts +41 -0
  312. package/src/utils/redirect-validation.ts +76 -0
  313. package/src/yjs/design-system-content/documentation-hierarchy.ts +35 -0
  314. package/src/yjs/design-system-content/index.ts +2 -0
  315. package/src/yjs/design-system-content/item-configuration.ts +62 -0
  316. package/src/yjs/docs-editor/blocks-to-prosemirror.ts +764 -0
  317. package/src/yjs/docs-editor/index.ts +7 -0
  318. package/src/yjs/docs-editor/list-tree-builder.ts +127 -0
  319. package/src/yjs/docs-editor/mock.ts +2271 -0
  320. package/src/yjs/docs-editor/model/block.ts +8 -0
  321. package/src/yjs/docs-editor/model/index.ts +2 -0
  322. package/src/yjs/docs-editor/model/page.ts +8 -0
  323. package/src/yjs/docs-editor/prosemirror/index.ts +3 -0
  324. package/src/yjs/docs-editor/prosemirror/inner-editor-schema.ts +145 -0
  325. package/src/yjs/docs-editor/prosemirror/main-editor-schema.ts +577 -0
  326. package/src/yjs/docs-editor/prosemirror/types.ts +19 -0
  327. package/src/yjs/docs-editor/prosemirror-to-blocks.ts +986 -0
  328. package/src/yjs/docs-editor/utils.ts +115 -0
  329. package/src/yjs/feature-room/backend.ts +36 -0
  330. package/src/yjs/feature-room/base.ts +109 -0
  331. package/src/yjs/feature-room/frontend.ts +53 -0
  332. package/src/yjs/feature-room/index.ts +3 -0
  333. package/src/yjs/forge-project-room/backend.ts +59 -0
  334. package/src/yjs/forge-project-room/base.ts +190 -0
  335. package/src/yjs/forge-project-room/index.ts +2 -0
  336. package/src/yjs/index.ts +7 -0
  337. package/src/yjs/thread-room/backend.ts +32 -0
  338. package/src/yjs/thread-room/base.ts +71 -0
  339. package/src/yjs/thread-room/frontend.ts +39 -0
  340. package/src/yjs/thread-room/index.ts +3 -0
  341. package/src/yjs/utils/index.ts +1 -0
  342. package/src/yjs/utils/key-value-storage.ts +57 -0
  343. package/src/yjs/version-room/backend.ts +101 -0
  344. package/src/yjs/version-room/base.ts +323 -0
  345. package/src/yjs/version-room/compute-dto.ts +387 -0
  346. package/src/yjs/version-room/frontend.ts +76 -0
  347. package/src/yjs/version-room/index.ts +6 -0
  348. package/src/yjs/version-room/types.ts +31 -0
  349. package/src/yjs/version-room/utils.ts +109 -0
@@ -0,0 +1,412 @@
1
+ import {
2
+ defaultDocumentationItemConfigurationV2,
3
+ generateShortPersistentId,
4
+ mapByUnique,
5
+ RoomType,
6
+ slugify,
7
+ } from "@supernova-studio/model";
8
+ import { DTOElementActionInput, DTOElementActionInputOfType } from "../api";
9
+ import { VersionRoomApproval, VersionRoomBaseYDocState, VersionRoomDocsPage, VersionRoomDocsPageGroup } from "../yjs";
10
+ import { LocalApproval, LocalDocsPage, LocalDocsPageGroup } from "./types";
11
+
12
+ //
13
+ // Types
14
+ //
15
+
16
+ type Page = LocalDocsPage | VersionRoomDocsPage;
17
+ type Group = LocalDocsPageGroup | VersionRoomDocsPageGroup;
18
+ type ApprovalState = LocalApproval | VersionRoomApproval;
19
+
20
+ //
21
+ // Interface
22
+ //
23
+
24
+ type Input = LocalExecutorConfig & {
25
+ actions: DTOElementActionInput[];
26
+ };
27
+
28
+ export function applyActionsLocally(input: Input) {
29
+ const actionExecutor = new LocalDocsElementActionExecutor(input);
30
+ actionExecutor.applyActions(input.actions);
31
+ return actionExecutor.localState;
32
+ }
33
+
34
+ //
35
+ // Executor
36
+ //
37
+
38
+ type LocalExecutorConfig = {
39
+ userId: string;
40
+ designSystemVersionId: string;
41
+ remoteState: VersionRoomBaseYDocState;
42
+ };
43
+
44
+ export class LocalDocsElementActionExecutor {
45
+ private readonly userId: string;
46
+ private readonly designSystemVersionId: string;
47
+
48
+ private readonly pages: Map<string, Page>;
49
+ private readonly groups: Map<string, Group>;
50
+ private readonly approvalStates: Map<string, ApprovalState>;
51
+ private readonly pageLiveblockRoomIds: Record<string, string>;
52
+
53
+ constructor(config: LocalExecutorConfig) {
54
+ const { designSystemVersionId, remoteState, userId } = config;
55
+
56
+ this.userId = userId;
57
+ this.designSystemVersionId = designSystemVersionId;
58
+
59
+ // Seed the state with remote state
60
+ this.pages = mapByUnique(remoteState.pages, p => p.persistentId);
61
+ this.groups = mapByUnique(remoteState.groups, p => p.persistentId);
62
+ this.approvalStates = mapByUnique(remoteState.approvals, a => a.pagePersistentId);
63
+ this.pageLiveblockRoomIds = { ...remoteState.pageLiveblockRoomIds };
64
+ }
65
+
66
+ get localState() {
67
+ return {
68
+ pages: Array.from(this.pages.values()),
69
+ groups: Array.from(this.groups.values()),
70
+ approvals: Array.from(this.approvalStates.values()),
71
+ pageLiveblockRoomIds: this.pageLiveblockRoomIds,
72
+ };
73
+ }
74
+
75
+ applyActions(trx: DTOElementActionInput[]) {
76
+ trx.forEach(trx => this.applyTransaction(trx));
77
+ }
78
+
79
+ applyTransaction(trx: DTOElementActionInput) {
80
+ switch (trx.type) {
81
+ // Groups
82
+ case "DocumentationGroupCreate":
83
+ return this.documentationGroupCreate(trx);
84
+ case "DocumentationGroupUpdate":
85
+ return this.documentationGroupUpdate(trx);
86
+ case "DocumentationGroupMove":
87
+ return this.documentationGroupMove(trx);
88
+
89
+ // Groups - unsupported
90
+ case "DocumentationGroupDelete":
91
+ case "DocumentationGroupDuplicate":
92
+ case "DocumentationGroupRestore":
93
+ throw new Error(`Transaction type ${trx.type} is not yet implemented`);
94
+
95
+ // Pages
96
+ case "DocumentationPageCreate":
97
+ return this.documentationPageCreate(trx);
98
+ case "DocumentationPageUpdate":
99
+ return this.documentationPageUpdate(trx);
100
+ case "DocumentationPageMove":
101
+ return this.documentationPageMove(trx);
102
+ case "DocumentationPageDelete":
103
+ return this.documentationPageDelete(trx);
104
+
105
+ // Pages - unsupported
106
+ case "DocumentationPageApprovalStateChange":
107
+ return this.documentationApprovalStateUpdate(trx);
108
+
109
+ case "DocumentationPageDuplicate":
110
+ case "DocumentationPageRestore":
111
+ throw new Error(`Transaction type ${trx.type} is not yet implemented`);
112
+
113
+ // Tabs
114
+ case "DocumentationTabCreate":
115
+ return this.documentationTabCreate(trx);
116
+
117
+ case "DocumentationTabGroupDelete":
118
+ throw new Error(`Transaction type ${trx.type} is not yet implemented`);
119
+
120
+ // Won't ever be supported
121
+ case "FigmaNodeRenderAsync":
122
+ throw new Error(`Transaction type ${trx.type} is not a documentation element action`);
123
+ }
124
+ }
125
+
126
+ //
127
+ // Pages
128
+ //
129
+
130
+ private documentationPageCreate(trx: DTOElementActionInputOfType<"DocumentationPageCreate">) {
131
+ const { input } = trx;
132
+ const { persistentId } = input;
133
+
134
+ if (this.pages.has(input.persistentId)) {
135
+ // TODO Artem: uncomment when this is synced with remote state
136
+ // throw new Error(`Cannot create page: persistent id ${input.persistentId} already exists`);
137
+ return;
138
+ }
139
+
140
+ if (!this.groups.has(input.parentPersistentId)) {
141
+ throw new Error(`Cannot create page: parent persistent id ${input.parentPersistentId} was not found`);
142
+ }
143
+
144
+ const localPage: LocalDocsPage = {
145
+ persistentId,
146
+ createdAt: new Date(),
147
+ parentPersistentId: input.parentPersistentId,
148
+ shortPersistentId: generateShortPersistentId(),
149
+ slug: slugify(input.title),
150
+ meta: { name: input.title },
151
+ updatedAt: new Date(),
152
+ data: {
153
+ // TODO Artem: move somewhere reusable
154
+ configuration: input.configuration
155
+ ? { ...defaultDocumentationItemConfigurationV2, ...input.configuration }
156
+ : input.configuration,
157
+ },
158
+ sortOrder: this.calculateSortOrder(input.parentPersistentId, input.afterPersistentId),
159
+ designSystemVersionId: this.designSystemVersionId,
160
+ };
161
+
162
+ this.pages.set(persistentId, localPage);
163
+
164
+ const roomId = `${RoomType.DocumentationPage}:${this.designSystemVersionId}:${persistentId}`;
165
+ this.pageLiveblockRoomIds[persistentId] = roomId;
166
+ }
167
+
168
+ private documentationPageUpdate(trx: DTOElementActionInputOfType<"DocumentationPageUpdate">) {
169
+ const { input } = trx;
170
+
171
+ const existingPage = this.pages.get(input.id);
172
+ if (!existingPage) {
173
+ throw new Error(`Cannot update page: page id ${input.id} was not found`);
174
+ }
175
+
176
+ const localPage: LocalDocsPage = {
177
+ ...existingPage,
178
+ userSlug: undefined,
179
+ meta: {
180
+ ...existingPage.meta,
181
+ name: input.title ?? existingPage.meta.name,
182
+ },
183
+ data: {
184
+ // TODO Artem: move somewhere reusable
185
+ configuration: input.configuration
186
+ ? { ...(existingPage.data.configuration ?? defaultDocumentationItemConfigurationV2), ...input.configuration }
187
+ : existingPage.data.configuration,
188
+ },
189
+ };
190
+
191
+ this.pages.set(localPage.persistentId, localPage);
192
+ }
193
+
194
+ private documentationPageMove(trx: DTOElementActionInputOfType<"DocumentationPageMove">) {
195
+ const { input } = trx;
196
+
197
+ if (!this.groups.has(input.parentPersistentId)) {
198
+ throw new Error(`Cannot move page: page parent id ${input.parentPersistentId} was not found`);
199
+ }
200
+
201
+ const existingPage = this.pages.get(input.id);
202
+ if (!existingPage) {
203
+ throw new Error(`Cannot update page: page id ${input.id} was not found`);
204
+ }
205
+
206
+ const localPage: LocalDocsPage = {
207
+ ...existingPage,
208
+ userSlug: undefined,
209
+ sortOrder: this.calculateSortOrder(input.parentPersistentId, input.afterPersistentId),
210
+ parentPersistentId: input.parentPersistentId,
211
+ };
212
+
213
+ this.pages.set(localPage.persistentId, localPage);
214
+ }
215
+
216
+ private documentationPageDelete(trx: DTOElementActionInputOfType<"DocumentationPageDelete">) {
217
+ const { input } = trx;
218
+
219
+ if (!this.pages.delete(trx.input.id)) {
220
+ throw new Error(`Cannot delete page: page id ${input.id} was not found`);
221
+ }
222
+
223
+ delete this.pageLiveblockRoomIds[trx.input.id];
224
+ }
225
+
226
+ //
227
+ // Group
228
+ //
229
+
230
+ private documentationGroupCreate(trx: DTOElementActionInputOfType<"DocumentationGroupCreate">) {
231
+ const { input } = trx;
232
+
233
+ if (this.groups.has(input.persistentId)) {
234
+ // TODO Artem: uncomment when this is synced with remote state
235
+ // throw new Error(`Cannot create page: persistent id ${input.persistentId} already exists`);
236
+ return;
237
+ }
238
+
239
+ const localGroup: LocalDocsPageGroup = {
240
+ parentPersistentId: input.parentPersistentId,
241
+ persistentId: input.persistentId,
242
+ shortPersistentId: generateShortPersistentId(),
243
+ slug: slugify(input.title),
244
+ meta: { name: input.title },
245
+ createdAt: new Date(),
246
+ updatedAt: new Date(),
247
+ data: {
248
+ // TODO Artem: move somewhere reusable
249
+ configuration: input.configuration
250
+ ? { ...defaultDocumentationItemConfigurationV2, ...input.configuration }
251
+ : input.configuration,
252
+ },
253
+ sortOrder: this.calculateSortOrder(input.parentPersistentId, input.afterPersistentId),
254
+ designSystemVersionId: this.designSystemVersionId,
255
+ };
256
+
257
+ this.groups.set(localGroup.persistentId, localGroup);
258
+ }
259
+
260
+ private documentationGroupUpdate(trx: DTOElementActionInputOfType<"DocumentationGroupUpdate">) {
261
+ const { input } = trx;
262
+
263
+ const existingGroup = this.groups.get(input.id);
264
+ if (!existingGroup) {
265
+ throw new Error(`Cannot update group: group id ${input.id} was not found`);
266
+ }
267
+
268
+ const localGroup: LocalDocsPageGroup = {
269
+ ...existingGroup,
270
+ userSlug: undefined,
271
+ meta: {
272
+ ...existingGroup.meta,
273
+ name: input.title ?? existingGroup.meta.name,
274
+ },
275
+ data: {
276
+ ...existingGroup.data,
277
+
278
+ // TODO Artem: move somewhere reusable
279
+ configuration: input.configuration
280
+ ? {
281
+ ...(existingGroup.data?.configuration ?? defaultDocumentationItemConfigurationV2),
282
+ ...input.configuration,
283
+ }
284
+ : existingGroup.data?.configuration,
285
+ },
286
+ };
287
+
288
+ this.groups.set(localGroup.persistentId, localGroup);
289
+ }
290
+
291
+ private documentationGroupMove(trx: DTOElementActionInputOfType<"DocumentationGroupMove">) {
292
+ const { input } = trx;
293
+
294
+ if (!this.groups.has(input.parentPersistentId)) {
295
+ throw new Error(`Cannot move group: group parent id ${input.parentPersistentId} was not found`);
296
+ }
297
+
298
+ const existingGroup = this.groups.get(input.id);
299
+ if (!existingGroup) {
300
+ throw new Error(`Cannot update group: group id ${input.id} was not found`);
301
+ }
302
+
303
+ const localGroup: LocalDocsPageGroup = {
304
+ ...existingGroup,
305
+ userSlug: undefined,
306
+ sortOrder: this.calculateSortOrder(input.parentPersistentId, input.afterPersistentId),
307
+ parentPersistentId: input.parentPersistentId,
308
+ };
309
+
310
+ this.groups.set(localGroup.persistentId, localGroup);
311
+ }
312
+
313
+ //
314
+ // Tabs
315
+ //
316
+
317
+ private documentationTabCreate(trx: DTOElementActionInputOfType<"DocumentationTabCreate">) {
318
+ const { input } = trx;
319
+
320
+ const page = this.pages.get(input.fromItemPersistentId);
321
+ if (!page) {
322
+ throw new Error(`Cannot create tab: page id ${input.fromItemPersistentId} was not found`);
323
+ }
324
+
325
+ // Create tab group in place of the page
326
+ const tabGroup: LocalDocsPageGroup = {
327
+ parentPersistentId: page.parentPersistentId,
328
+ persistentId: input.persistentId,
329
+ shortPersistentId: generateShortPersistentId(),
330
+ slug: page.slug,
331
+ meta: page.meta,
332
+ createdAt: new Date(),
333
+ updatedAt: new Date(),
334
+ data: {
335
+ behavior: "Tabs",
336
+ configuration: page?.data.configuration,
337
+ },
338
+ sortOrder: page.sortOrder,
339
+ designSystemVersionId: this.designSystemVersionId,
340
+ };
341
+ this.groups.set(input.persistentId, tabGroup);
342
+
343
+ const newLocalPage: LocalDocsPage = {
344
+ ...page,
345
+ userSlug: undefined,
346
+ sortOrder: 0,
347
+ parentPersistentId: input.persistentId,
348
+ meta: { name: input.tabName },
349
+ };
350
+ this.pages.set(newLocalPage.persistentId, newLocalPage);
351
+ }
352
+
353
+ //
354
+ // Approval states
355
+ //
356
+
357
+ private documentationApprovalStateUpdate(trx: DTOElementActionInputOfType<"DocumentationPageApprovalStateChange">) {
358
+ const { input } = trx;
359
+
360
+ const existingApproval = this.approvalStates.get(input.persistentId);
361
+
362
+ if (input.approvalState) {
363
+ this.approvalStates.set(input.persistentId, {
364
+ approvalState: input.approvalState,
365
+ createdAt: existingApproval?.createdAt ?? new Date(),
366
+ designSystemVersionId: this.designSystemVersionId,
367
+ pagePersistentId: input.persistentId,
368
+ updatedAt: new Date(),
369
+ updatedByUserId: this.userId,
370
+ } satisfies LocalApproval);
371
+ } else {
372
+ this.approvalStates.delete(input.persistentId);
373
+ }
374
+ }
375
+
376
+ //
377
+ // Utils
378
+ //
379
+
380
+ private calculateSortOrder(parentPersistentId: string, afterPersistentId?: string | null): number {
381
+ const sortOrderStep = Math.pow(2, 16);
382
+
383
+ const neighbours = [
384
+ ...Array.from(this.pages.values()).filter(p => p.parentPersistentId === parentPersistentId),
385
+ ...Array.from(this.groups.values()).filter(g => g.parentPersistentId === parentPersistentId),
386
+ ];
387
+
388
+ // If no neighbors, just assign 0
389
+ if (!neighbours.length) return 0;
390
+
391
+ neighbours.sort((lhs, rhs) => lhs.sortOrder - rhs.sortOrder);
392
+
393
+ // Null afterPersistentId means beginning
394
+ if (afterPersistentId === null) return neighbours[0].sortOrder - sortOrderStep;
395
+
396
+ // Undefined afterPersistentId means default behavior (end of the list)
397
+ if (!afterPersistentId) return neighbours[neighbours.length - 1].sortOrder + sortOrderStep;
398
+
399
+ const index = neighbours.findIndex(e => e.persistentId === afterPersistentId);
400
+
401
+ // If page is not found or adding after the last item is requested, assign last position
402
+ if (index < 0 || index === neighbours.length - 1) {
403
+ return neighbours[neighbours.length - 1].sortOrder + sortOrderStep;
404
+ }
405
+
406
+ // Insert in between items
407
+ const left = neighbours[index].sortOrder;
408
+ const right = neighbours[index + 1]?.sortOrder ?? left + sortOrderStep * 2;
409
+
410
+ return (right + left) / 2;
411
+ }
412
+ }
@@ -0,0 +1,283 @@
1
+ import { OmitStrict } from "@supernova-studio/model";
2
+ import PQueue from "p-queue";
3
+ import * as Y from "yjs";
4
+ import {
5
+ DTODocumentationHierarchyV2,
6
+ DTODocumentationSettings,
7
+ DTOElementActionInput,
8
+ DTOElementActionInputOfType,
9
+ DTOPageBlockDefinition,
10
+ } from "../api";
11
+ import { DocumentationPageEditorModel, generatePageContentHash, VersionRoomBaseYDoc } from "../yjs";
12
+ import { computeDocsHierarchy } from "../yjs/version-room/compute-dto";
13
+ import { VersionRoomBaseYDocState } from "../yjs/version-room/types";
14
+ import { applyActionsLocally } from "./docs-local-action-executor";
15
+ import { SupportedElementActionType } from "./types";
16
+
17
+ type YObserver = () => void;
18
+ type HierarchyObserver = (hierarchy: DTODocumentationHierarchyV2) => void;
19
+ type SettingsObserver = (settings: DTODocumentationSettings) => void;
20
+ type ErrorObserver<T> = (error: unknown, actionMetadata: T | undefined) => void;
21
+
22
+ type TransactionExecutor = (trx: DTOElementActionInput) => Promise<void>;
23
+ type InternalTransactionExecutor<T> = (trx: InternalAction<T>) => Promise<void>;
24
+ type TransactionIdGenerator = () => string;
25
+
26
+ type Action = DTOElementActionInputOfType<SupportedElementActionType>;
27
+ type InputAction<T> = OmitStrict<Action, "tId">;
28
+ type InternalAction<T> = { action: Action; metadata?: T };
29
+
30
+ export class DocsStructureRepository<T> {
31
+ private userId: string;
32
+ private designSystemVersionId: string;
33
+
34
+ private readonly yDoc: Y.Doc;
35
+ private readonly yObserver: YObserver;
36
+ private _yState: VersionRoomBaseYDocState | undefined;
37
+
38
+ private _currentHierarchy: DTODocumentationHierarchyV2 | undefined;
39
+ private _currentSettings: DTODocumentationSettings | undefined;
40
+
41
+ private localActions: DTOElementActionInput[] = [];
42
+ private readonly actionQueue: TransactionQueue<T>;
43
+ private readonly hierarchyObservers = new Set<HierarchyObserver>();
44
+ private readonly settingsObservers = new Set<SettingsObserver>();
45
+ private readonly errorObservers = new Set<ErrorObserver<T>>();
46
+ private readonly initCallbacks = new Set<() => void>();
47
+
48
+ private readonly transactionIdGenerator: TransactionIdGenerator;
49
+ private readonly transactionExecutor: TransactionExecutor;
50
+
51
+ constructor(config: {
52
+ userId: string;
53
+ designSystemVersionId: string;
54
+ yDoc: Y.Doc;
55
+ transactionExecutor: TransactionExecutor;
56
+ transactionIdGenerator: TransactionIdGenerator;
57
+ }) {
58
+ this.userId = config.userId;
59
+ this.designSystemVersionId = config.designSystemVersionId;
60
+ this.yDoc = config.yDoc;
61
+
62
+ this.yObserver = this.yDoc.on("update", () => this.onYUpdate()) as YObserver;
63
+ this.onYUpdate();
64
+
65
+ this.transactionExecutor = config.transactionExecutor;
66
+ this.transactionIdGenerator = config.transactionIdGenerator;
67
+
68
+ this.actionQueue = new TransactionQueue(action => this.executeInternalAction(action));
69
+ }
70
+
71
+ //
72
+ // Lifecycle
73
+ //
74
+
75
+ get isInitialized(): boolean {
76
+ return !!this._currentHierarchy;
77
+ }
78
+
79
+ onInitialized(): Promise<void> {
80
+ if (this.isInitialized) return Promise.resolve();
81
+ return new Promise(resolve => {
82
+ this.initCallbacks.add(resolve);
83
+ });
84
+ }
85
+
86
+ addHierarchyObserver(observer: HierarchyObserver) {
87
+ this.hierarchyObservers.add(observer);
88
+ if (this._currentHierarchy) observer(this._currentHierarchy);
89
+ }
90
+
91
+ removeHierarchyObserver(observer: HierarchyObserver) {
92
+ this.hierarchyObservers.delete(observer);
93
+ }
94
+
95
+ addSettingsObserver(observer: SettingsObserver) {
96
+ this.settingsObservers.add(observer);
97
+ if (this._currentSettings) observer(this._currentSettings);
98
+ }
99
+
100
+ removeSettingsObserver(observer: SettingsObserver) {
101
+ this.settingsObservers.delete(observer);
102
+ }
103
+
104
+ addErrorObserver(observer: ErrorObserver<T>) {
105
+ this.errorObservers.add(observer);
106
+ }
107
+
108
+ removeErrorObserver(observer: ErrorObserver<T>) {
109
+ this.errorObservers.delete(observer);
110
+ }
111
+
112
+ dispose() {
113
+ this.yDoc.off("update", this.yObserver);
114
+ this.hierarchyObservers.clear();
115
+ this.settingsObservers.clear();
116
+ this.errorObservers.clear();
117
+ this.actionQueue.clear();
118
+ }
119
+
120
+ //
121
+ // Accessors
122
+ //
123
+
124
+ get currentHierarchy(): DTODocumentationHierarchyV2 {
125
+ const hierarchy = this._currentHierarchy;
126
+ if (!hierarchy) throw new Error(`Hierarchy cannot be accessed while it's still loading`);
127
+ return hierarchy;
128
+ }
129
+
130
+ //
131
+ // Actions
132
+ //
133
+
134
+ executeAction(action: InputAction<T>, metadata?: T) {
135
+ void this.executeActionPromise(action, metadata);
136
+ }
137
+
138
+ executeActionPromise(action: InputAction<T>, metadata?: T) {
139
+ const fullAction: DTOElementActionInput = { ...action, tId: this.transactionIdGenerator() };
140
+ this.localActions.push(fullAction);
141
+ this.refreshHierarchy();
142
+ return this.actionQueue.enqueue({ action: fullAction, metadata });
143
+ }
144
+
145
+ notifyPageContentUpdated(
146
+ pagePersistentId: string,
147
+ content: DocumentationPageEditorModel,
148
+ definitions: DTOPageBlockDefinition[]
149
+ ) {
150
+ const pageContentHash = generatePageContentHash(content, definitions);
151
+ new VersionRoomBaseYDoc(this.yDoc).updateDocumentationPageContentHashes({
152
+ [pagePersistentId]: pageContentHash,
153
+ });
154
+ }
155
+
156
+ private async executeInternalAction(action: InternalAction<T>) {
157
+ try {
158
+ return await this.transactionExecutor(action.action);
159
+ } catch (e: unknown) {
160
+ // Remove this action from local actions and reload hierarchy
161
+ this.localActions = this.localActions.filter(a => a.tId !== action.action.tId);
162
+ this.refreshHierarchy();
163
+
164
+ this.errorObservers.forEach(o => o(e, action.metadata));
165
+ }
166
+ }
167
+
168
+ //
169
+ // Reactions
170
+ //
171
+
172
+ private refreshState() {
173
+ this.refreshHierarchy();
174
+ this.refreshSettings();
175
+ }
176
+
177
+ private refreshSettings() {
178
+ const yState = this._yState;
179
+ if (!yState) return;
180
+
181
+ // Calculate new settings
182
+ const newSettings: DTODocumentationSettings = {
183
+ isApprovalRequiredForPublishing: yState.settings.approvalRequiredForPublishing,
184
+ isApprovalsFeatureEnabled: yState.settings.isApprovalFeatureEnabled,
185
+ isDraftFeatureAdopted: yState.settings.isDraftFeatureAdopted,
186
+ };
187
+
188
+ // Only invoke when changed
189
+ if (
190
+ !this._currentSettings ||
191
+ newSettings.isApprovalRequiredForPublishing !== this._currentSettings.isApprovalRequiredForPublishing ||
192
+ newSettings.isApprovalsFeatureEnabled !== this._currentSettings.isApprovalsFeatureEnabled ||
193
+ newSettings.isDraftFeatureAdopted !== this._currentSettings.isDraftFeatureAdopted
194
+ ) {
195
+ this._currentSettings = newSettings;
196
+
197
+ // Invoke observers
198
+ this.settingsObservers.forEach(o => o(newSettings));
199
+ }
200
+ }
201
+
202
+ private refreshHierarchy() {
203
+ const yState = this._yState;
204
+ if (!yState) return;
205
+
206
+ // Calculate new hierarchy
207
+ const hierarchy = this.calculateHierarchy(yState);
208
+ if (!hierarchy) return;
209
+ this._currentHierarchy = hierarchy;
210
+
211
+ // Invoke observers
212
+ this.hierarchyObservers.forEach(o => o(hierarchy));
213
+ }
214
+
215
+ private calculateHierarchy(yState: VersionRoomBaseYDocState) {
216
+ // Remove local actions that have been applied remotely
217
+ const executedTransactionIds = new Set(yState.executedTransactionIds);
218
+ const localActions = this.localActions.filter(a => a.tId && !executedTransactionIds.has(a.tId));
219
+ this.localActions = localActions;
220
+
221
+ // Apply local actions onto the Yjs state
222
+ const { pages, groups, approvals, pageLiveblockRoomIds } = applyActionsLocally({
223
+ userId: this.userId,
224
+ designSystemVersionId: this.designSystemVersionId,
225
+ remoteState: yState,
226
+ actions: localActions,
227
+ });
228
+
229
+ const hierarchy = computeDocsHierarchy(
230
+ {
231
+ // Merged remote + local
232
+ pages,
233
+ groups,
234
+ approvals,
235
+ pageLiveblockRoomIds,
236
+
237
+ // Remote only
238
+ groupSnapshots: yState.groupSnapshots,
239
+ pageContentHashes: yState.pageContentHashes,
240
+ pageSnapshots: yState.pageSnapshots,
241
+ settings: yState.settings,
242
+ },
243
+ { includeDeletedContent: true }
244
+ );
245
+
246
+ return hierarchy;
247
+ }
248
+
249
+ private onYUpdate() {
250
+ const newState = new VersionRoomBaseYDoc(this.yDoc).getState();
251
+ if (newState.groups.length) {
252
+ this._yState = newState;
253
+ this.refreshState();
254
+
255
+ // Flush init callbacks
256
+ this.initCallbacks.forEach(f => f());
257
+ this.initCallbacks.clear();
258
+ }
259
+ }
260
+ }
261
+
262
+ class TransactionQueue<T> {
263
+ private readonly executor: InternalTransactionExecutor<T>;
264
+ private readonly queue = new PQueue({
265
+ concurrency: 1,
266
+ });
267
+
268
+ constructor(executor: InternalTransactionExecutor<T>) {
269
+ this.executor = executor;
270
+ }
271
+
272
+ enqueue(trx: InternalAction<T>) {
273
+ return this.queue.add(() => this.executor(trx));
274
+ }
275
+
276
+ onEmpty() {
277
+ return this.queue.onEmpty();
278
+ }
279
+
280
+ clear() {
281
+ this.queue.clear();
282
+ }
283
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./docs-local-action-executor";
2
+ export * from "./docs-structure-repo";
3
+ export * from "./project-content-repo";
4
+ export * from "./project-local-action-executor";
5
+ export * from "./types";