@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,215 @@
1
+ import { OmitStrict } from "@supernova-studio/model";
2
+ import PQueue from "p-queue";
3
+ import * as Y from "yjs";
4
+ import { DTOForgeProjectAction, DTOForgeProjectActionOfType } from "../api";
5
+ import { ForgeProjectRoomBaseYDoc, ForgeProjectRoomBaseYDocState } from "../yjs";
6
+ import { applyProjectActionsLocally } from "./project-local-action-executor";
7
+ import { ProjectContentState } from "./types";
8
+
9
+ type YObserver = () => void;
10
+ type ProjectContentObserver = (projectContent: ProjectContentState) => void;
11
+ type ErrorObserver<T> = (error: unknown, actionMetadata: T | undefined) => void;
12
+
13
+ type TransactionExecutor = (trx: DTOForgeProjectAction) => Promise<void>;
14
+ type InternalTransactionExecutor<T> = (trx: InternalAction<T>) => Promise<void>;
15
+ type TransactionIdGenerator = () => string;
16
+
17
+ type Action = DTOForgeProjectActionOfType<DTOForgeProjectAction["type"]>;
18
+ type InputAction<T> = OmitStrict<Action, "tId">;
19
+ type InternalAction<T> = { action: Action; metadata?: T };
20
+
21
+ export class ForgeProjectContentRepository<T> {
22
+ private userId: string;
23
+ private projectId: string;
24
+
25
+ private readonly yDoc: Y.Doc;
26
+ private readonly yObserver: YObserver;
27
+ private _yState: ForgeProjectRoomBaseYDocState | undefined;
28
+
29
+ private _currentProjectContent: ProjectContentState | undefined;
30
+
31
+ private localActions: DTOForgeProjectAction[] = [];
32
+ private readonly actionQueue: TransactionQueue<T>;
33
+ private readonly projectContentObservers = new Set<ProjectContentObserver>();
34
+ private readonly errorObservers = new Set<ErrorObserver<T>>();
35
+ private readonly initCallbacks = new Set<() => void>();
36
+
37
+ private readonly transactionIdGenerator: TransactionIdGenerator;
38
+ private readonly transactionExecutor: TransactionExecutor;
39
+
40
+ constructor(config: {
41
+ userId: string;
42
+ projectId: string;
43
+ yDoc: Y.Doc;
44
+ transactionExecutor: TransactionExecutor;
45
+ transactionIdGenerator: TransactionIdGenerator;
46
+ }) {
47
+ this.userId = config.userId;
48
+ this.projectId = config.projectId;
49
+ this.yDoc = config.yDoc;
50
+
51
+ this.yObserver = this.yDoc.on("update", () => this.onYUpdate()) as YObserver;
52
+ this.onYUpdate();
53
+
54
+ this.transactionExecutor = config.transactionExecutor;
55
+ this.transactionIdGenerator = config.transactionIdGenerator;
56
+
57
+ this.actionQueue = new TransactionQueue(action => this.executeInternalAction(action));
58
+ }
59
+
60
+ //
61
+ // Lifecycle
62
+ //
63
+
64
+ get isInitialized(): boolean {
65
+ return !!this._currentProjectContent;
66
+ }
67
+
68
+ onInitialized(): Promise<void> {
69
+ if (this.isInitialized) return Promise.resolve();
70
+ return new Promise(resolve => {
71
+ this.initCallbacks.add(resolve);
72
+ });
73
+ }
74
+
75
+ addProjectContentObserver(observer: ProjectContentObserver) {
76
+ this.projectContentObservers.add(observer);
77
+ if (this._currentProjectContent) observer(this._currentProjectContent);
78
+ }
79
+
80
+ removeProjectContentObserver(observer: ProjectContentObserver) {
81
+ this.projectContentObservers.delete(observer);
82
+ }
83
+
84
+ addErrorObserver(observer: ErrorObserver<T>) {
85
+ this.errorObservers.add(observer);
86
+ }
87
+
88
+ removeErrorObserver(observer: ErrorObserver<T>) {
89
+ this.errorObservers.delete(observer);
90
+ }
91
+
92
+ dispose() {
93
+ this.yDoc.off("update", this.yObserver);
94
+ this.projectContentObservers.clear();
95
+ this.errorObservers.clear();
96
+ this.actionQueue.clear();
97
+ }
98
+
99
+ //
100
+ // Accessors
101
+ //
102
+
103
+ get currentProjectContent(): ProjectContentState {
104
+ const projectContent = this._currentProjectContent;
105
+ if (!projectContent) throw new Error(`Project content cannot be accessed while it's still loading`);
106
+ return projectContent;
107
+ }
108
+
109
+ //
110
+ // Actions
111
+ //
112
+
113
+ executeAction(action: InputAction<T>, metadata?: T) {
114
+ void this.executeActionPromise(action, metadata);
115
+ }
116
+
117
+ executeActionPromise(action: InputAction<T>, metadata?: T) {
118
+ const fullAction: DTOForgeProjectAction = { ...action, tId: this.transactionIdGenerator() };
119
+ this.localActions.push(fullAction);
120
+ this.refreshProjectContent();
121
+ return this.actionQueue.enqueue({ action: fullAction, metadata });
122
+ }
123
+
124
+ private async executeInternalAction(action: InternalAction<T>) {
125
+ try {
126
+ return await this.transactionExecutor(action.action);
127
+ } catch (e: unknown) {
128
+ // Remove this action from local actions and reload projectContent
129
+ this.localActions = this.localActions.filter(a => a.tId !== action.action.tId);
130
+ this.refreshProjectContent();
131
+
132
+ this.errorObservers.forEach(o => o(e, action.metadata));
133
+ }
134
+ }
135
+
136
+ //
137
+ // Reactions
138
+ //
139
+
140
+ private refreshState() {
141
+ this.refreshProjectContent();
142
+ }
143
+
144
+ private refreshProjectContent() {
145
+ const yState = this._yState;
146
+ if (!yState) return;
147
+
148
+ // Calculate new project content
149
+ const projectContent = this.calculateProjectState(yState);
150
+ if (!projectContent) return;
151
+ this._currentProjectContent = projectContent;
152
+
153
+ // Invoke observers
154
+ this.projectContentObservers.forEach(o => o(projectContent));
155
+ }
156
+
157
+ private calculateProjectState(yState: ForgeProjectRoomBaseYDocState): ProjectContentState {
158
+ // Remove local actions that have been applied remotely
159
+ const executedTransactionIds = new Set(yState.executedTransactionIds);
160
+ const localActions = this.localActions.filter(a => a.tId && !executedTransactionIds.has(a.tId));
161
+ this.localActions = localActions;
162
+
163
+ // Apply local actions onto the Yjs state
164
+ const state = applyProjectActionsLocally({
165
+ userId: this.userId,
166
+ projectId: this.projectId,
167
+ remoteState: yState,
168
+ actions: localActions,
169
+ });
170
+
171
+ return {
172
+ artifacts: state.artifacts,
173
+ features: state.features,
174
+ artifactSections: state.artifactSections,
175
+ featureSections: state.featureSections,
176
+ // we don't apply local actions to relations, so we can just use the Yjs state
177
+ relations: yState.relations,
178
+ };
179
+ }
180
+
181
+ private onYUpdate() {
182
+ const newState = new ForgeProjectRoomBaseYDoc(this.yDoc).getState();
183
+ if (newState.isLoaded) {
184
+ this._yState = newState;
185
+ this.refreshState();
186
+
187
+ // Flush init callbacks
188
+ this.initCallbacks.forEach(f => f());
189
+ this.initCallbacks.clear();
190
+ }
191
+ }
192
+ }
193
+
194
+ class TransactionQueue<T> {
195
+ private readonly executor: InternalTransactionExecutor<T>;
196
+ private readonly queue = new PQueue({
197
+ concurrency: 1,
198
+ });
199
+
200
+ constructor(executor: InternalTransactionExecutor<T>) {
201
+ this.executor = executor;
202
+ }
203
+
204
+ enqueue(trx: InternalAction<T>) {
205
+ return this.queue.add(() => this.executor(trx));
206
+ }
207
+
208
+ onEmpty() {
209
+ return this.queue.onEmpty();
210
+ }
211
+
212
+ clear() {
213
+ this.queue.clear();
214
+ }
215
+ }
@@ -0,0 +1,415 @@
1
+ import { mapByUnique } from "@supernova-studio/model";
2
+ import {
3
+ DTOForgeProjectAction,
4
+ DTOForgeProjectActionOfType,
5
+ DTOForgeProjectArtifact,
6
+ DTOForgeProjectFeature,
7
+ DTOForgeSection,
8
+ } from "../api";
9
+
10
+ //
11
+ // Interface
12
+ //
13
+
14
+ type Input = LocalExecutorConfig & {
15
+ actions: DTOForgeProjectAction[];
16
+ };
17
+
18
+ export function applyProjectActionsLocally(input: Input) {
19
+ const actionExecutor = new LocalProjectActionExecutor(input);
20
+ actionExecutor.applyActions(input.actions);
21
+ return actionExecutor.localState;
22
+ }
23
+
24
+ //
25
+ // Executor
26
+ //
27
+
28
+ type LocalExecutorConfig = {
29
+ userId: string;
30
+ projectId: string;
31
+ remoteState: ForgeProjectYDocState;
32
+ };
33
+
34
+ type ForgeProjectYDocState = {
35
+ artifacts: DTOForgeProjectArtifact[];
36
+ features: DTOForgeProjectFeature[];
37
+ artifactSections: DTOForgeSection[];
38
+ featureSections: DTOForgeSection[];
39
+ };
40
+
41
+ export class LocalProjectActionExecutor {
42
+ private readonly userId: string;
43
+ private readonly projectId: string;
44
+
45
+ private readonly artifacts: Map<string, DTOForgeProjectArtifact>;
46
+ private readonly features: Map<string, DTOForgeProjectFeature>;
47
+ private readonly artifactSections: Map<string, DTOForgeSection>;
48
+ private readonly featureSections: Map<string, DTOForgeSection>;
49
+
50
+ constructor(config: LocalExecutorConfig) {
51
+ const { projectId, remoteState, userId } = config;
52
+
53
+ this.userId = userId;
54
+ this.projectId = projectId;
55
+
56
+ // Seed the state with remote state
57
+ this.artifacts = mapByUnique(remoteState.artifacts, p => p.id);
58
+ this.features = mapByUnique(remoteState.features, p => p.id);
59
+ this.artifactSections = mapByUnique(remoteState.artifactSections, p => p.id);
60
+ this.featureSections = mapByUnique(remoteState.featureSections, p => p.id);
61
+ }
62
+
63
+ get localState() {
64
+ return {
65
+ artifacts: Array.from(this.artifacts.values()),
66
+ features: Array.from(this.features.values()),
67
+ artifactSections: Array.from(this.artifactSections.values()),
68
+ featureSections: Array.from(this.featureSections.values()),
69
+ };
70
+ }
71
+
72
+ applyActions(trx: DTOForgeProjectAction[]) {
73
+ trx.forEach(trx => this.applyTransaction(trx));
74
+ }
75
+
76
+ applyTransaction(trx: DTOForgeProjectAction) {
77
+ switch (trx.type) {
78
+ case "ArtifactCreate":
79
+ return this.artifactCreate(trx);
80
+ case "ArtifactUpdate":
81
+ return this.artifactUpdate(trx);
82
+ case "ArtifactDelete":
83
+ return this.artifactDelete(trx);
84
+ case "ArtifactMove":
85
+ return this.artifactMove(trx);
86
+ case "FeatureCreate":
87
+ return this.featureCreate(trx);
88
+ case "FeatureDelete":
89
+ return this.featureDelete(trx);
90
+ case "FeatureUpdate":
91
+ return this.featureUpdate(trx);
92
+ case "FeatureMove":
93
+ return this.featureMove(trx);
94
+ case "SectionCreate":
95
+ return this.sectionCreate(trx);
96
+ case "SectionUpdate":
97
+ return this.sectionUpdate(trx);
98
+ case "SectionDelete":
99
+ return this.sectionDelete(trx);
100
+ case "SectionMove":
101
+ return this.sectionMove(trx);
102
+ }
103
+ }
104
+
105
+ //
106
+ // Artifacts
107
+ //
108
+
109
+ public calculateSectionSortOrder(items: Map<string, DTOForgeSection>, afterItemId?: string | null) {
110
+ const sortedItems = Array.from(items.values()).sort((a, b) => a.sortOrder - b.sortOrder);
111
+ const sortOrder = this.calculateSortOrderNoDb(
112
+ pId => sortedItems.find(s => s.projectId === pId),
113
+ pId => sortedItems.findLast(s => s.projectId === pId),
114
+ (pId, id) => sortedItems.find(s => s.projectId === pId && s.id === id),
115
+ (pId, sortOrder) => sortedItems.find(s => s.projectId === pId && s.sortOrder > sortOrder),
116
+ (pId, sortOrder, step) =>
117
+ items.forEach(s => (s.sortOrder > sortOrder && s.projectId === pId ? (s.sortOrder += step) : {})),
118
+ this.projectId,
119
+ afterItemId
120
+ );
121
+ return sortOrder ?? 0;
122
+ }
123
+
124
+ public calculateItemSortOrder<T extends DTOForgeProjectArtifact | DTOForgeProjectFeature>(
125
+ items: Map<string, T>,
126
+ afterItemId?: string | null,
127
+ sectionId?: string | null
128
+ ) {
129
+ const sortedItems = Array.from(items.values()).sort((a, b) => a.sortOrder - b.sortOrder);
130
+ const matchIds = (i: T, pId: string, sId?: string) => i.sectionId === sId && i.projectId === pId;
131
+ const sortOrder = this.calculateSortOrderNoDb(
132
+ (pId, sId) => sortedItems.find(i => matchIds(i, pId, sId)),
133
+ (pId, sId) => sortedItems.findLast(i => matchIds(i, pId, sId)),
134
+ (pId, id, sId) => sortedItems.find(i => i.id === id && matchIds(i, pId, sId)),
135
+ (pId, sortOrder, sId) => sortedItems.find(i => i.sortOrder > sortOrder && matchIds(i, pId, sId)),
136
+ (pId, sortOrder, step, sId) =>
137
+ items.forEach(i => (i.sortOrder > sortOrder && matchIds(i, pId, sId) ? (i.sortOrder += step) : {})),
138
+ this.projectId,
139
+ afterItemId,
140
+ sectionId ?? undefined
141
+ );
142
+ return sortOrder ?? 0;
143
+ }
144
+
145
+ // See also calculateSectionSortOrder and calculateSectionedItemSortOrder
146
+ public calculateSortOrderNoDb(
147
+ findFirst: (projectId: string, sectionId?: string) => { sortOrder: number } | null | undefined,
148
+ findLast: (projectId: string, sectionId?: string) => { sortOrder: number } | null | undefined,
149
+ findUnique: (projectId: string, id: string, sectionId?: string) => { sortOrder: number } | null | undefined,
150
+ findNext: (projectId: string, sortOrder: number, sectionId?: string) => { sortOrder: number } | null | undefined,
151
+ shiftAfter: (projectId: string, sortOrder: number, step: number, sectionId?: string) => void,
152
+ projectId: string,
153
+ afterItemId?: string | null,
154
+ sectionId?: string
155
+ ): number | null {
156
+ const SORT_ORDER_STEP = 1000;
157
+ if (afterItemId === undefined) {
158
+ // Move to END: last.sortOrder + step
159
+ const lastSection = findLast(projectId, sectionId);
160
+ return (lastSection?.sortOrder ?? 0) + SORT_ORDER_STEP;
161
+ } else if (afterItemId === null) {
162
+ // Move to BEGINNING: first.sortOrder - step
163
+ const firstSection = findFirst(projectId, sectionId);
164
+ return (firstSection?.sortOrder ?? SORT_ORDER_STEP) - SORT_ORDER_STEP;
165
+ } else {
166
+ // Move AFTER target section: average of neighbors
167
+ const targetSection = findUnique(projectId, afterItemId, sectionId);
168
+ if (!targetSection) return null;
169
+
170
+ // Find the next section after target (if any)
171
+ const nextSection = findNext(projectId, targetSection.sortOrder, sectionId);
172
+ if (nextSection) {
173
+ // Position between target and next: average of neighbors
174
+ let newSortOrder = Math.floor((targetSection.sortOrder + nextSection.sortOrder) / 2);
175
+
176
+ // If average would be same as target (too close), use target + step
177
+ if (newSortOrder <= targetSection.sortOrder) {
178
+ newSortOrder = targetSection.sortOrder + SORT_ORDER_STEP / 2;
179
+ shiftAfter(projectId, targetSection.sortOrder, SORT_ORDER_STEP, sectionId);
180
+ }
181
+ return newSortOrder;
182
+ } else {
183
+ // No next section: position at end (target + step)
184
+ return targetSection.sortOrder + SORT_ORDER_STEP;
185
+ }
186
+ }
187
+ }
188
+
189
+ private artifactCreate(trx: DTOForgeProjectActionOfType<"ArtifactCreate">) {
190
+ const { input } = trx;
191
+ const { id, afterArtifactId, sectionId } = input;
192
+ const sortOrder = this.calculateItemSortOrder(this.artifacts, afterArtifactId, sectionId);
193
+
194
+ this.artifacts.set(id, {
195
+ id,
196
+ projectId: this.projectId,
197
+ sectionId: sectionId,
198
+ sortOrder: sortOrder,
199
+ title: input.title,
200
+ updatedAt: new Date(),
201
+ createdAt: new Date(),
202
+ createdByUserId: this.userId,
203
+ isArchived: false,
204
+ });
205
+ }
206
+
207
+ //
208
+ // Feature
209
+ //
210
+
211
+ private artifactUpdate(trx: DTOForgeProjectActionOfType<"ArtifactUpdate">) {
212
+ const { input } = trx;
213
+ const { id } = input;
214
+
215
+ const existingArtifact = this.artifacts.get(id);
216
+ if (!existingArtifact) {
217
+ throw new Error(`Cannot update artifact: artifact ${id} was not found in local storage`);
218
+ }
219
+
220
+ const mergedArtifact: DTOForgeProjectArtifact = {
221
+ ...existingArtifact,
222
+ title: input.title ?? existingArtifact.title,
223
+ isArchived: input.isArchived ?? existingArtifact.isArchived,
224
+ updatedAt: new Date(),
225
+ };
226
+
227
+ this.artifacts.set(id, mergedArtifact);
228
+ }
229
+
230
+ private artifactMove(trx: DTOForgeProjectActionOfType<"ArtifactMove">) {
231
+ const { input } = trx;
232
+ const { id, afterId, sectionId } = input;
233
+
234
+ const existingArtifact = this.artifacts.get(id);
235
+ if (!existingArtifact) {
236
+ throw new Error(`Cannot move artifact: artifact ${id} was not found in local storage`);
237
+ }
238
+
239
+ const sortOrder = this.calculateItemSortOrder(this.artifacts, afterId, sectionId);
240
+
241
+ const mergedArtifact: DTOForgeProjectArtifact = {
242
+ ...existingArtifact,
243
+ sortOrder,
244
+ updatedAt: new Date(),
245
+ };
246
+
247
+ this.artifacts.set(id, mergedArtifact);
248
+ }
249
+
250
+ private artifactDelete(trx: DTOForgeProjectActionOfType<"ArtifactDelete">) {
251
+ const { input } = trx;
252
+ const { id } = input;
253
+
254
+ if (!this.artifacts.delete(id)) {
255
+ throw new Error(`Cannot delete artifact: artifact ${id} was not found in local storage`);
256
+ }
257
+ }
258
+
259
+ private featureCreate(trx: DTOForgeProjectActionOfType<"FeatureCreate">) {
260
+ const { input } = trx;
261
+ const { id, afterFeatureId, sectionId } = input;
262
+ const sortOrder = this.calculateItemSortOrder(this.features, afterFeatureId, sectionId);
263
+
264
+ this.features.set(id, {
265
+ id,
266
+ projectId: this.projectId,
267
+ description: input.description,
268
+ isArchived: false,
269
+ sectionId: input.sectionId,
270
+ sortOrder: sortOrder,
271
+ name: input.name ?? "New Feature",
272
+ status: "Draft",
273
+ updatedAt: new Date(),
274
+ createdAt: new Date(),
275
+ createdByUserId: this.userId,
276
+ lastReplyTimestamp: undefined,
277
+ numberOfIterations: 0,
278
+ numberOfBookmarkedIterations: 0,
279
+ });
280
+ }
281
+
282
+ //
283
+ // Sections
284
+ //
285
+
286
+ private featureUpdate(trx: DTOForgeProjectActionOfType<"FeatureUpdate">) {
287
+ const { input } = trx;
288
+ const { id } = input;
289
+
290
+ const existingFeature = this.features.get(id);
291
+ if (!existingFeature) {
292
+ throw new Error(`Cannot update feature: feature ${id} was not found in local storage`);
293
+ }
294
+
295
+ let publishedState = existingFeature.publishedState;
296
+
297
+ if (input.publishedState === null) {
298
+ publishedState = undefined;
299
+ } else if (input.publishedState) {
300
+ publishedState = {
301
+ ...input.publishedState,
302
+ lastPublishedAt: new Date(),
303
+ };
304
+ }
305
+
306
+ const mergedFeature: DTOForgeProjectFeature = {
307
+ ...existingFeature,
308
+ name: input.name ?? existingFeature.name,
309
+ description: input.description ?? existingFeature.description,
310
+ isArchived: input.isArchived ?? existingFeature.isArchived,
311
+ status: input.status ?? existingFeature.status,
312
+ updatedAt: new Date(),
313
+ publishedState,
314
+ };
315
+
316
+ this.features.set(id, mergedFeature);
317
+ }
318
+
319
+ private featureMove(trx: DTOForgeProjectActionOfType<"FeatureMove">) {
320
+ const { input } = trx;
321
+ const { id, afterId, sectionId } = input;
322
+
323
+ const existingFeature = this.features.get(id);
324
+ if (!existingFeature) {
325
+ throw new Error(`Cannot move feature: feature ${id} was not found in local storage`);
326
+ }
327
+
328
+ const sortOrder = this.calculateItemSortOrder(this.features, afterId, sectionId);
329
+
330
+ const mergedFeature: DTOForgeProjectFeature = {
331
+ ...existingFeature,
332
+ sortOrder,
333
+ updatedAt: new Date(),
334
+ };
335
+
336
+ this.features.set(id, mergedFeature);
337
+ }
338
+
339
+ private featureDelete(trx: DTOForgeProjectActionOfType<"FeatureDelete">) {
340
+ const { input } = trx;
341
+ const { id } = input;
342
+
343
+ if (!this.features.delete(id)) {
344
+ throw new Error(`Cannot delete feature: feature ${id} was not found in local storage`);
345
+ }
346
+ }
347
+
348
+ private sectionCreate(trx: DTOForgeProjectActionOfType<"SectionCreate">) {
349
+ const { input } = trx;
350
+ const { id, afterSectionId } = input;
351
+ const sections = input.childType === "Artifact" ? this.artifactSections : this.featureSections;
352
+ const sortOrder = this.calculateSectionSortOrder(sections, afterSectionId);
353
+
354
+ sections.set(id, {
355
+ id,
356
+ projectId: this.projectId,
357
+ name: input.name,
358
+ childType: input.childType,
359
+ sortOrder: sortOrder,
360
+ updatedAt: new Date(),
361
+ createdAt: new Date(),
362
+ });
363
+ }
364
+
365
+ private sectionUpdate(trx: DTOForgeProjectActionOfType<"SectionUpdate">) {
366
+ const { input } = trx;
367
+ const { id } = input;
368
+
369
+ const existingSection = this.artifactSections.get(id) ?? this.featureSections.get(id);
370
+ if (!existingSection) {
371
+ throw new Error(`Cannot update section: section ${id} was not found in local storage`);
372
+ }
373
+
374
+ const mergedSection: DTOForgeSection = {
375
+ ...existingSection,
376
+ name: input.name ?? existingSection.name,
377
+ updatedAt: new Date(),
378
+ };
379
+
380
+ const sections = existingSection.childType === "Artifact" ? this.artifactSections : this.featureSections;
381
+ sections.set(id, mergedSection);
382
+ }
383
+
384
+ private sectionMove(trx: DTOForgeProjectActionOfType<"SectionMove">) {
385
+ const { input } = trx;
386
+ const { id, afterSectionId } = input;
387
+
388
+ const existingSection = this.artifactSections.get(id) ?? this.featureSections.get(id);
389
+ if (!existingSection) {
390
+ throw new Error(`Cannot move section: section ${id} was not found in local storage`);
391
+ }
392
+
393
+ const sections = existingSection.childType === "Artifact" ? this.artifactSections : this.featureSections;
394
+ const sortOrder = this.calculateSectionSortOrder(sections, afterSectionId);
395
+
396
+ const mergedSection: DTOForgeSection = {
397
+ ...existingSection,
398
+ sortOrder,
399
+ updatedAt: new Date(),
400
+ };
401
+
402
+ sections.set(id, mergedSection);
403
+ }
404
+
405
+ private sectionDelete(trx: DTOForgeProjectActionOfType<"SectionDelete">) {
406
+ const { input } = trx;
407
+ const { id } = input;
408
+
409
+ const isArtifactSection = this.artifactSections.delete(id);
410
+ const isFeatureSection = this.featureSections.delete(id);
411
+ if (!isArtifactSection && !isFeatureSection) {
412
+ throw new Error(`Cannot delete section: section ${id} was not found in local storage`);
413
+ }
414
+ }
415
+ }
@@ -0,0 +1,37 @@
1
+ import { DocumentationPageApproval, DocumentationPageV2, ElementGroup, OmitStrict } from "@supernova-studio/model";
2
+ import {
3
+ DTOElementActionInput,
4
+ DTOForgeProjectArtifact,
5
+ DTOForgeProjectFeature,
6
+ DTOForgeRelation,
7
+ DTOForgeSection,
8
+ } from "../api";
9
+
10
+ export type LocalDocsPage = OmitStrict<DocumentationPageV2, "id" | "userSlug"> & { userSlug?: undefined };
11
+ export type LocalDocsPageGroup = OmitStrict<ElementGroup, "id" | "brandPersistentId" | "childType" | "userSlug"> & {
12
+ userSlug?: undefined;
13
+ };
14
+
15
+ export type LocalApproval = OmitStrict<DocumentationPageApproval, "id" | "pageId" | "persistentId">;
16
+
17
+ type NarrowedUnion<T, U extends T> = U;
18
+ export type SupportedElementActionType = NarrowedUnion<
19
+ DTOElementActionInput["type"],
20
+ | "DocumentationPageCreate"
21
+ | "DocumentationPageUpdate"
22
+ | "DocumentationPageDelete"
23
+ | "DocumentationPageMove"
24
+ | "DocumentationGroupCreate"
25
+ | "DocumentationGroupUpdate"
26
+ | "DocumentationGroupMove"
27
+ | "DocumentationPageApprovalStateChange"
28
+ | "DocumentationTabCreate"
29
+ >;
30
+
31
+ export type ProjectContentState = {
32
+ artifacts: DTOForgeProjectArtifact[];
33
+ features: DTOForgeProjectFeature[];
34
+ artifactSections: DTOForgeSection[];
35
+ featureSections: DTOForgeSection[];
36
+ relations: DTOForgeRelation[];
37
+ };