@powerhousedao/academy 0.1.0-dev.3 → 0.1.0-dev.5

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 (189) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +1 -1
  3. package/docs/academy/01-GetStarted/00-ExploreDemoPackage.md +78 -0
  4. package/docs/academy/01-GetStarted/{03-ToDoList/01-CreateNewPowerhouseProject.md → 01-CreateNewPowerhouseProject.md} +10 -8
  5. package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +97 -0
  6. package/docs/academy/01-GetStarted/{03-ToDoList/03-ImplementOperationReducers.md → 03-ImplementOperationReducers.md} +20 -16
  7. package/docs/academy/01-GetStarted/{03-ToDoList/04-BuildToDoListEditor.md → 04-BuildToDoListEditor.md} +15 -15
  8. package/docs/academy/01-GetStarted/{00-GetStarted.mdx → home.mdx} +41 -52
  9. package/docs/academy/{02-AdvancedTutorial/01-Create/01-SetupBuilderEnvironment.md → 02-MasteryTrack/01-BuilderEnvironment/01-Prerequisites.md} +78 -43
  10. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/02-StandardDocumentModelWorkflow.md +253 -0
  11. package/docs/academy/{02-AdvancedTutorial/01-Create/00-BuilderTools.md → 02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md} +1 -1
  12. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/_category_.json +7 -0
  13. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/01-WhatIsADocumentModel.md +188 -0
  14. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +72 -0
  15. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +119 -0
  16. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +116 -0
  17. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +282 -0
  18. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +277 -0
  19. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +1 -0
  20. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/_category_.json +7 -0
  21. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/02-ConfiguringDrives.md +2 -2
  22. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/03-BuildingADriveExplorer.md +1 -1
  23. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-DocumentTools/00-DocumentToolbar.md +20 -0
  24. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/01-OperationHistory.md +1 -1
  25. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/01-ReadingAndWritingThroughTheAPI.mdx +2 -2
  26. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/02-GraphQLAtPowerhouse.md +1 -1
  27. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/graphql/index.md +1 -1
  28. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/02-IntroductionToPackages.md +2 -2
  29. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/03-RunOnACloudServer.md +3 -3
  30. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/03-SetupEnvironment.md +1 -1
  31. package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/_category_.json +1 -1
  32. package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +740 -0
  33. package/docs/academy/04-APIReferences/01-ReactHooks.md +16 -0
  34. package/docs/academy/04-APIReferences/02-ReactorAPI.md +1 -0
  35. package/docs/academy/04-APIReferences/03-Configuration.md +64 -0
  36. package/docs/academy/{04-ComponentLibrary/01-PowerhouseDesignSystem.md → 06-ComponentLibrary/00-DocumentEngineering.md} +8 -8
  37. package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/02-BuildingWithScalars.md +2 -2
  38. package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/03-Scalar-Components/01-phid-field.mdx +1 -1
  39. package/docs/academy/{06-Cookbook.md → 07-Cookbook.md} +24 -18
  40. package/docs/academy/08-Glossary.md +82 -0
  41. package/docusaurus.config.ts +7 -14
  42. package/package.json +11 -8
  43. package/scripts/generate-combined-cli-docs.ts +80 -0
  44. package/sidebars.ts +100 -14
  45. package/src/components/HomepageFeatures/index.tsx +10 -10
  46. package/src/css/custom.css +11 -0
  47. package/src/pages/{index.tsx → _archive-homepage.tsx} +1 -1
  48. package/src/theme/DocCardList/index.tsx +30 -0
  49. package/static/img/storybook-icon.svg +18 -0
  50. package/docs/academy/01-GetStarted/01-InstallDemoPackage.md +0 -38
  51. package/docs/academy/01-GetStarted/02-LoginWithRenown.md +0 -32
  52. package/docs/academy/01-GetStarted/03-ToDoList/02-DefineToDoListDocumentModel.md +0 -86
  53. package/docs/academy/01-GetStarted/03-ToDoList/_category_.json +0 -8
  54. package/docs/academy/01-GetStarted/_category_.json +0 -3
  55. package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/_category_.json +0 -8
  56. package/docs/academy/02-AdvancedTutorial/01-Create/02-StandardDocumentModelWorkflow.md +0 -229
  57. package/docs/academy/03-APIReferences/00-PowerhouseCLI.md +0 -40
  58. package/docs/academy/03-APIReferences/01-ReactHooks.md +0 -3
  59. package/docs/academy/03-APIReferences/02-ReactorUsage.md +0 -1
  60. package/docs/academy/07-Glossary.md +0 -53
  61. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/DocumentModelHeader.png +0 -0
  62. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/DocumentModelOperations.png +0 -0
  63. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/OpenDocumentModelEditor.gif +0 -0
  64. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/completeEditor.png +0 -0
  65. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/connectApp.gif +0 -0
  66. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/form.png +0 -0
  67. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/mytodolist.gif +0 -0
  68. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/reducers.png +0 -0
  69. /package/docs/academy/01-GetStarted/{03-ToDoList/images → images}/vscode.png +0 -0
  70. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/01-BuildingBeautifulDocumentEditors.md +0 -0
  71. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/02-RevisionHistoryTimeline.md +0 -0
  72. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/_category_.json +0 -0
  73. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/images/committer-address-popup.png +0 -0
  74. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/images/revision-hash-popup.png +0 -0
  75. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/images/revision-history-list.png +0 -0
  76. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/07-DocumentTools/images/signature-details-popup.png +0 -0
  77. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/01-RenownAuthenticationFlow.md +0 -0
  78. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/02-Authorization.md +0 -0
  79. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/_category_.json +0 -0
  80. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/images/ConnectAddress.png +0 -0
  81. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/images/LoginComplete.png +0 -0
  82. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/images/OperationsHistory.png +0 -0
  83. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/images/RenownLogin.png +0 -0
  84. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/08-Authorization/images/ReturnToConnect.png +0 -0
  85. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/_category_.json +0 -0
  86. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/images/CreateDrive.png +0 -0
  87. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/images/CreateNewDrive.png +0 -0
  88. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/03-BuildingUserExperiences/images/mytodolist.gif +0 -0
  89. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/03-WorkingWithSubgraphs/02-GraphQLAndSubgraphs.mdx +0 -0
  90. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/03-WorkingWithSubgraphs/03-WorkingWithSubgraphs.md +0 -0
  91. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/03-WorkingWithSubgraphs/_category_.json +0 -0
  92. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/04-analytics-processor.md +0 -0
  93. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/01-SetupBuilderEnvironment.md +0 -0
  94. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/02-CreateNewPowerhouseProject.md +0 -0
  95. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/03-GenerateAnAnalyticsProcessor.md +0 -0
  96. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/04-UpdateAnalyticsProcessor.md +0 -0
  97. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/_category_.json +0 -0
  98. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-SPV.gif +0 -0
  99. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-a-new-asset.png +0 -0
  100. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-a-transaction.gif +0 -0
  101. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Transaction-table.png +0 -0
  102. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/images/create-a-new-RWA-document.gif +0 -0
  103. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/05-AnalyticsProcessorTutorial/images/granularity.png +0 -0
  104. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/GraphQL References/QueryingADocumentWithGraphQL.md +0 -0
  105. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/listener-raw.png +0 -0
  106. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/raw-reports1.png +0 -0
  107. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/raw-reports2.png +0 -0
  108. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/rwaRegister.png +0 -0
  109. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/apse.png +0 -0
  110. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/best-practices.md +0 -0
  111. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/filter.png +0 -0
  112. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/filteroptions.png +0 -0
  113. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/graphql/integration.md +0 -0
  114. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/dbs.png +0 -0
  115. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/high-level.jpg +0 -0
  116. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/indexeddb.png +0 -0
  117. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/libs-core.jpg +0 -0
  118. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/libs.jpg +0 -0
  119. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/lod.jpg +0 -0
  120. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/logo.png +0 -0
  121. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/navbar.png +0 -0
  122. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/overview-1.jpg +0 -0
  123. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/overview-2.jpg +0 -0
  124. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/overview-3.jpg +0 -0
  125. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/overview-4.jpg +0 -0
  126. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/overview-5.jpg +0 -0
  127. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/overview-6.jpg +0 -0
  128. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/paths-1.jpg +0 -0
  129. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/images/paths-2.jpg +0 -0
  130. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/intro.md +0 -0
  131. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/benchmarks.md +0 -0
  132. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/browser.md +0 -0
  133. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/compatibility.md +0 -0
  134. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/index.md +0 -0
  135. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/memory.md +0 -0
  136. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/pg.md +0 -0
  137. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/schema.md +0 -0
  138. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/typescript/utilities.md +0 -0
  139. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/use-cases/index.md +0 -0
  140. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/use-cases/maker.md +0 -0
  141. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/06-Analytics Engine/use-cases/processors.md +0 -0
  142. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/_category_.json +0 -0
  143. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/images/OperationHistory.png +0 -0
  144. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/images/OperationsQuery.png +0 -0
  145. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/images/QueryDocumentID.png +0 -0
  146. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/04-WorkWithData/images/SwitchboardButton.png +0 -0
  147. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/00-IntegrateInAFront-End +0 -0
  148. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/01-IntroducingFusion +0 -0
  149. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/02-PublishYourProject.md +0 -0
  150. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/04-GraphQLNamespacing +0 -0
  151. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/05-LaunchYourBackend.md +0 -0
  152. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/06-LaunchYourFrontend.md +0 -0
  153. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/_category_.json +0 -0
  154. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/images/SSHConnection.png +0 -0
  155. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/images/homedesign.png +0 -0
  156. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/images/keyconcepts.png +0 -0
  157. /package/docs/academy/{02-AdvancedTutorial → 02-MasteryTrack}/05-Launch/images/tutorialschema.png +0 -0
  158. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/01-SetupBuilderEnvironment.md +0 -0
  159. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/02-CreateNewPowerhouseProject.md +0 -0
  160. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/03-DefineChatroomDocumentModel.md +0 -0
  161. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/04-ImplementOperationReducers.md +0 -0
  162. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/05-ImplementChatroomEditor.md +0 -0
  163. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/06-LaunchALocalReactor.md +0 -0
  164. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/_category_.json +0 -0
  165. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/image-1.png +0 -0
  166. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/image-2.png +0 -0
  167. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/image-3.png +0 -0
  168. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/image-4.png +0 -0
  169. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/image-5.png +0 -0
  170. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/image.png +0 -0
  171. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/images/ChatRoomConnectApp.gif +0 -0
  172. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/images/ChatRoomTest.gif +0 -0
  173. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/images/completeEditor.png +0 -0
  174. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/images/form.png +0 -0
  175. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/images/reducers.png +0 -0
  176. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials → 03-ExampleUsecases}/Chatroom/images/vscode.png +0 -0
  177. /package/docs/academy/{03-APIReferences → 04-APIReferences}/_category_.json +0 -0
  178. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{01-WhatIsADocumentModel.md → 01-WhatIsADocumentModel} +0 -0
  179. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{02-DAOandDocumentsModelsQ+A.md → 02-DAOandDocumentsModelsQ+A} +0 -0
  180. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{02-domain-modeling.md → 02-domain-modeling} +0 -0
  181. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{03-BenefitsOfDocumentModels.md → 03-BenefitsOfDocumentModels} +0 -0
  182. /package/docs/academy/{02-AdvancedTutorial/01-Create/02-MoreTutorials/04-UtilitiesAndTips.md → 05-Architecture/05-DocumentModelTheory/04-UtilitiesAndTips} +0 -0
  183. /package/docs/academy/05-Architecture/05-DocumentModelTheory/{05-best-practices.md → 05-best-practices} +0 -0
  184. /package/docs/academy/{04-ComponentLibrary/00-StorybookLink → 06-ComponentLibrary/01-StorybookLink} +0 -0
  185. /package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/03-Scalar-Components/02-input-field.mdx +0 -0
  186. /package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/04-Complex-Components/01-sidebar.mdx +0 -0
  187. /package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/05-Layout-Components/01-test-toupdate.mdx +0 -0
  188. /package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/06-Fragments/01-test-toupdate.mdx +0 -0
  189. /package/docs/academy/{04-ComponentLibrary → 06-ComponentLibrary}/_category_.json +0 -0
@@ -0,0 +1,72 @@
1
+ # Specify the State Schema
2
+
3
+ The state schema is the backbone of your document model. It defines the structure, data types, and relationships of the information your document will hold. In Powerhouse, we use the GraphQL Schema Definition Language (SDL) to define this schema. A well-defined state schema is crucial for ensuring data integrity, consistency, and for enabling powerful querying and manipulation capabilities.
4
+
5
+ ## Core Concepts
6
+
7
+ ### Types
8
+ At the heart of GraphQL SDL are **types**. Types define the shape of your data. You can define custom object types that represent the entities in your document. For example, in a `ToDoList` document, you might have a `ToDoListState` type and a `ToDoItem` type.
9
+
10
+ * **`ToDoListState`**: This could be the root type representing the overall state of the to-do list. It might contain a list of `ToDoItem` objects.
11
+ * **`ToDoItem`**: This type would represent an individual to-do item, with properties like an `id`, `text` (the task description), and `checked` (a boolean indicating if the task is completed).
12
+
13
+ ### Fields
14
+ Each type has **fields**, which represent the properties of that type. Each field has a name and a type. For instance, the `ToDoItem` type would have an `id` field of type `ID!`, a `text` field of type `String!`, and a `checked` field of type `Boolean!`.
15
+
16
+ ### Scalars
17
+ GraphQL has a set of built-in **scalar types**:
18
+ * `String`: A UTF‐8 character sequence.
19
+ * `Int`: A signed 32‐bit integer.
20
+ * `Float`: A signed double-precision floating-point value.
21
+ * `Boolean`: `true` or `false`.
22
+ * `ID`: A unique identifier, often used as a key for a field. It is serialized in the same way as a String; however, it is not intended to be human-readable.
23
+
24
+ ### Lists and Non-Null
25
+ You can modify types using lists and non-null indicators:
26
+ * **Lists**: To indicate that a field will return a list of a certain type, you wrap the type in square brackets, e.g., `[ToDoItem!]!`. This means the field `items` in `ToDoListState` will be a list of `ToDoItem` objects.
27
+ * **Non-Null**: To indicate that a field cannot be null, you add an exclamation mark `!` after the type name, e.g., `String!`. This means that the `text` field of a `ToDoItem` must always have a value. The outer `!` in `[ToDoItem!]!` means the list itself cannot be null (it must be at least an empty list), and the inner `!` on `ToDoItem!` means that every item within that list must also be non-null.
28
+
29
+ ## Example: ToDoList State Schema
30
+
31
+ Let's revisit the `ToDoList` example from the "Define the ToDoList document specification" tutorial.
32
+
33
+ ```graphql
34
+ # The state of our ToDoList
35
+ type ToDoListState {
36
+ items: [ToDoItem!]!
37
+ }
38
+
39
+ # A single to-do item
40
+ type ToDoItem {
41
+ id: ID!
42
+ text: String!
43
+ checked: Boolean!
44
+ }
45
+ ```
46
+
47
+ ### Breakdown:
48
+
49
+ * **`ToDoListState` type**:
50
+ * `items: [ToDoItem!]!`: This field defines that our `ToDoListState` contains a list called `items`.
51
+ * `[ToDoItem!]`: This signifies that `items` is a list of `ToDoItem` objects.
52
+ * `ToDoItem!`: The `!` after `ToDoItem` means that no item in the list can be null. Each entry must be a valid `ToDoItem`.
53
+ * The final `!` after `[ToDoItem!]` means that the `items` list itself cannot be null. It can be an empty list `[]`, but it cannot be absent.
54
+
55
+ * **`ToDoItem` type**:
56
+ * `id: ID!`: Each `ToDoItem` has a unique identifier that cannot be null. This is crucial for referencing specific items, for example, when updating or deleting them.
57
+ * `text: String!`: The textual description of the to-do item. It cannot be null, ensuring every to-do has a description.
58
+ * `checked: Boolean!`: Indicates whether the to-do item is completed. It defaults to a boolean value (true or false) and cannot be null.
59
+
60
+ ## Best Practices for Designing Your State Schema
61
+
62
+ 1. **Start Simple, Iterate**: Begin with the core entities and properties. You can always expand and refine your schema as your understanding of the document's requirements grows.
63
+ 2. **Clarity and Explicitness**: Name your types and fields clearly and descriptively. This makes the schema easier to understand and maintain.
64
+ 3. **Use Non-Null Wisely**: Enforce data integrity by using non-null (`!`) for fields that must always have a value. However, be mindful not to over-constrain if a field can genuinely be optional.
65
+ 4. **Normalize vs. Denormalize**:
66
+ * **Normalization**: Similar to relational databases, you can normalize your data by having distinct types and linking them via IDs. This can reduce data redundancy. For example, if you had `User` and `ToDoItem` and wanted to assign tasks, you might have an `assigneeId` field in `ToDoItem` that links to a `User`'s `id`.
67
+ * **Denormalization**: Sometimes, for performance or simplicity, you might embed data directly. For instance, if user information associated with a to-do item was very simple and only used in that context, you might embed user fields directly in `ToDoItem`.
68
+ * The choice depends on your specific use case, query patterns, and how data is updated.
69
+ 5. **Consider Future Needs**: While you shouldn't over-engineer, think a little about potential future enhancements. For example, adding a `createdAt: String` or `dueDate: String` field to `ToDoItem` might be useful later.
70
+ 6. **Root State Type**: It's a common pattern to have a single root type for your document state (e.g., `ToDoListState`). This provides a clear entry point for accessing all document data.
71
+
72
+ By carefully defining your state schema, you lay a solid foundation for your Powerhouse document model, making it robust, maintainable, and easy to work with. The schema dictates not only how data is stored but also how it can be queried and mutated through operations, which will be covered in the next section.
@@ -0,0 +1,119 @@
1
+ # Specify Document Operations
2
+
3
+ In the previous section, we defined the state schema for our document model. Now, we turn our attention to a critical aspect of document model creation: **specifying document operations**. These operations are the heart of your document's behavior, dictating how its state can be modified.
4
+
5
+ ## What are Document Operations?
6
+
7
+ In Powerhouse, document models adhere to event sourcing principles. This means that every change to a document's state is the result of a sequence of operations (or events). Instead of directly mutating the state, you define specific, named operations that describe the intended change.
8
+
9
+ For example, in our `ToDoList` document model, operations might include:
10
+
11
+ * `ADD_TODO_ITEM`: To add a new task.
12
+ * `UPDATE_TODO_ITEM`: To modify an existing task (e.g., change its text or mark it as completed).
13
+ * `DELETE_TODO_ITEM`: To remove a task.
14
+
15
+ Each operation acts as a command that, when applied, transitions the document from one state to the next. The complete history of these operations defines the document's journey to its current state.
16
+
17
+ ## Connecting Operations to the Schema
18
+
19
+ In the "Define ToDoList Document Model" guide, we used GraphQL `input` types to define the structure of the data required for each operation. Let's revisit that:
20
+
21
+ ```graphql
22
+ # From 02-DefineToDoListDocumentModel.md
23
+ # Defines a GraphQL input type for adding a new to-do item
24
+ input AddTodoItemInput {
25
+ id: ID!
26
+ text: String!
27
+ }
28
+
29
+ # Defines a GraphQL input type for updating a to-do item
30
+ input UpdateTodoItemInput {
31
+ id: ID!
32
+ text: String
33
+ checked: Boolean
34
+ }
35
+
36
+ # Defines a GraphQL input type for deleting a to-do item
37
+ input DeleteTodoItemInput {
38
+ id: ID!
39
+ }
40
+ ```
41
+
42
+ These `input` types are not just abstract definitions; they are the **specifications for our document operations**.
43
+
44
+ * **`AddTodoItemInput`** specifies that to execute an `ADD_TODO_ITEM` operation, we need an `id` and `text` for the new item.
45
+ * **`UpdateTodoItemInput`** specifies that for an `UPDATE_TODO_ITEM` operation, we need the `id` of the item to update, and optionally new `text` or a `checked` status.
46
+ * **`DeleteTodoItemInput`** specifies that a `DELETE_TODO_ITEM` operation requires the `id` of the item to be removed.
47
+
48
+ The Powerhouse Connect application uses these GraphQL input types when you define operations within a module (e.g., the `to_do_list` module with operations `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, `DELETE_TODO_ITEM`).
49
+
50
+ ## Designing Effective Document Operations
51
+
52
+ Careful design of your document operations is crucial for a robust and maintainable document model. Here are some key considerations:
53
+
54
+ ### 1. Granularity
55
+ Operations should be granular enough to represent distinct user intentions or logical changes.
56
+
57
+ * **Too coarse:** An operation like `MODIFY_TODOLIST` that takes a whole new list of items would be too broad. It would be hard to track specific changes and could lead to complex reducer logic.
58
+ * **Too fine:** While possible, having separate operations like `SET_TODO_ITEM_TEXT` and `SET_TODO_ITEM_CHECKED_STATUS` might be overly verbose if these are often updated together. `UPDATE_TODO_ITEM` with optional fields offers a good balance.
59
+ * **Just right:** The `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, and `DELETE_TODO_ITEM` operations for our `ToDoList` are good examples. They represent clear, atomic changes.
60
+
61
+ ### 2. Naming Conventions
62
+ Clear and consistent naming makes your operations understandable. A common convention is `VERB_NOUN` or `VERB_NOUN_SUBJECT`.
63
+
64
+ * Examples: `ADD_ITEM`, `UPDATE_USER_PROFILE`, `ASSIGN_TASK_TO_USER`.
65
+ * In our case: `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, `DELETE_TODO_ITEM`.
66
+
67
+ The name you provide in the Connect UI (e.g., `ADD_TODO_ITEM`) directly corresponds to the operation type that will be recorded and that your reducers will handle.
68
+
69
+ ### 3. Input Types (Payloads)
70
+ The input type for an operation (its payload) should contain all the necessary information to perform that operation, and nothing more.
71
+
72
+ * **Completeness:** If an operation needs a user ID to authorize a change, include it in the input.
73
+ * **Conciseness:** Avoid including data that isn't directly used by the operation.
74
+ * **Clarity:** Use descriptive field names within your input types. `action.input.text` is clearer than `action.input.t`.
75
+
76
+ The GraphQL `input` types we defined earlier (`AddTodoItemInput`, `UpdateTodoItemInput`, `DeleteTodoItemInput`) serve precisely this purpose. They ensure that whoever triggers an operation provides the correct data in the correct format.
77
+
78
+ ### 4. Immutability and Pure Functions
79
+ While not specified in the operation definition itself, remember that the *implementation* of these operations (the reducers) should treat state as immutable and behave as pure functions. The operation specification (input type) provides the data for these pure functions.
80
+
81
+ ## Role in Event Sourcing and CQRS
82
+
83
+ * **Events:** Each successfully executed operation is recorded as an event in the document's history. This history provides an audit trail and allows for replaying events to reconstruct state, which is invaluable for debugging and understanding how a document evolved.
84
+ * **Commands:** Document operations are essentially "commands" in a Command Query Responsibility Segregation (CQRS) pattern. They represent an intent to change the state. The processing of this command (by the reducer) leads to one or more events being stored and the state being updated.
85
+
86
+ ## From Specification to Implementation
87
+
88
+ Specifying your document operations is the bridge between defining your data structure (the state schema) and implementing the logic that changes that data (the reducers).
89
+
90
+ 1. **You define the state schema** (e.g., `ToDoListState`, `ToDoItem`).
91
+ 2. **You specify the operations** that can alter this state, along with their required input data (e.g., `ADD_TODO_ITEM` with `AddTodoItemInput`).
92
+ 3. **Next, you will implement reducers** for each specified operation. Each reducer will take the current state and an operation's input, and produce a new state.
93
+
94
+ The generated code from `ph generate` (as seen in `03-ImplementOperationReducers.md`) will create a structure for your reducers based on the operations you specified in the Connect application (which, in turn, were based on your GraphQL input types).
95
+
96
+ For example, the `ToDoListToDoListOperations` type generated by Powerhouse will expect methods corresponding to `addTodoItemOperation`, `updateTodoItemOperation`, and `deleteTodoItemOperation`.
97
+
98
+ ```typescript
99
+ // From 03-ImplementOperationReducers.md
100
+ import { ToDoListToDoListOperations } from '../../gen/to-do-list/operations.js';
101
+
102
+ export const reducer: ToDoListToDoListOperations = {
103
+ addTodoItemOperation(state, action, dispatch) {
104
+ // Implementation uses action.input which matches AddTodoItemInput
105
+ },
106
+ updateTodoItemOperation(state, action, dispatch) {
107
+ // Implementation uses action.input which matches UpdateTodoItemInput
108
+ },
109
+ deleteTodoItemOperation(state, action, dispatch) {
110
+ // Implementation uses action.input which matches DeleteTodoItemInput
111
+ },
112
+ };
113
+ ```
114
+
115
+ ## Conclusion
116
+
117
+ Specifying document operations is a foundational step in building robust and predictable document models in Powerhouse. By clearly defining the "what" (the operation and its input) before implementing the "how" (the reducer logic), you create a clear contract for state transitions. This approach enhances type safety, testability, and the overall maintainability of your document model.
118
+
119
+ In the next section, we will dive deeper into the implementation of the reducer functions for these specified operations.
@@ -0,0 +1,116 @@
1
+ # Use the Document Model Generator
2
+
3
+ In the Powerhouse Document Model development workflow, after specifying your document model's state schema and operations within the Connect application and exporting it as a `.phdm.zip` file, the next crucial step is to translate this specification into a tangible codebase. This is where the Powerhouse Document Model Generator comes into play.
4
+
5
+ The Document Model Generator is a powerful command-line tool (`ph generate`) that processes your exported `.phdm.zip` file and scaffolds the necessary directory structure and foundational code for your document model. It automates the creation of boilerplate code, ensuring consistency, type safety, and adherence to Powerhouse conventions, thereby significantly accelerating the development process.
6
+
7
+ This document provides a deep dive into using the Document Model Generator, understanding its output, and appreciating its role in the broader context of document model creation.
8
+
9
+ ## Prerequisites
10
+
11
+ Before you can use the Document Model Generator, ensure you have the following:
12
+
13
+ 1. **Powerhouse CLI (`ph-cmd`) Installed:** The generator is part of the Powerhouse CLI. If you haven't installed it, refer to the [Builder Tools documentation](/academy/MasteryTrack/BuilderEnvironment/BuilderTools#installing-the-powerhouse-cli).
14
+ 2. **Document Model Specification File (`.phdm.zip`):** You must have already defined your document model in Connect and exported it. This file (e.g., `YourModelName.phdm.zip`) contains the GraphQL schema for your document's state and operations. This process is typically covered in a preceding step, such as "Define [YourModelName] Document Model."
15
+
16
+ ## The Command
17
+
18
+ The core command to invoke the Document Model Generator is:
19
+
20
+ ```bash
21
+ ph generate <YourModelName.phdm.zip>
22
+ ```
23
+
24
+ Replace `<YourModelName.phdm.zip>` with the actual filename of your exported document model specification. For instance, if your exported file is named `Invoice.phdm.zip`, the command would be:
25
+
26
+ ```bash
27
+ ph generate Invoice.phdm.zip
28
+ ```
29
+
30
+ When executed, this command reads and parses the specification file and generates a set of files and directories within your Powerhouse project.
31
+
32
+ ## What Happens Under the Hood? A Deep Dive into the Generated Artifacts
33
+
34
+ Running `ph generate` triggers a series of actions that lay the groundwork for your document model's implementation. Let's explore the typical output structure and the significance of each generated component.
35
+
36
+ The generator creates a new directory specific to your document model, usually located at:
37
+ `document-models/<YourModelName>/`
38
+
39
+ For example, using `Invoice.phdm.zip` would result in a directory structure under `document-models/invoice/`. Inside this directory, you will find:
40
+
41
+ 1. **`spec.json` (or similar JSON representation):**
42
+ * **Purpose:** This file is a JSON representation of your document model specification, derived directly from the `.phdm.zip` file. It contains the parsed schema, operation definitions, document type, and other metadata.
43
+ * **Significance:** It serves as the canonical, machine-readable definition of your model within the project, which other tools or processes might reference.
44
+
45
+ 2. **`schema.graphql`:**
46
+ * **Purpose:** This file contains the raw GraphQL Schema Definition Language (SDL) for both the state and operations of your document model, exactly as you defined it in Connect.
47
+ * **Significance:** Provides a human-readable reference of the schema and can be useful for quick checks or for tools that might directly consume GraphQL SDL.
48
+
49
+ 3. **The `gen/` Directory (Generated Code):**
50
+ This directory is pivotal as it houses all the code automatically generated by the tool. **You should generally avoid manually editing files within the `gen/` directory**, as they will be overwritten if you regenerate the model.
51
+ Key files within `gen/` include:
52
+
53
+ * **`types.ts`:**
54
+ * **Purpose:** Contains TypeScript interfaces and type definitions derived from your GraphQL schema. This includes types for your document's state (e.g., `InvoiceState`), any complex types used within the state (e.g., `LineItem`), and types for the inputs of each defined operation (e.g., `AddLineItemInput`).
55
+ * **Significance:** This is the cornerstone of type safety in your document model implementation. By using these generated types, you ensure that your reducer logic and any client-side interactions adhere to the defined data structures, catching errors at compile-time rather than runtime.
56
+
57
+ * **`operations.ts` (or `creators.ts`, `actions.ts`):**
58
+ * **Purpose:** This file exports "action creator" functions for each operation defined in your schema. These functions take the input parameters for an operation and return a correctly structured action object that can be processed by the reducer system.
59
+ * **Significance:** Action creators simplify the process of creating and dispatching operations, reduce the likelihood of errors in action formatting, and improve code readability. For example, instead of manually constructing an action object like `{ type: "ADD_LINE_ITEM", input: { ... } }`, you'd use a function like `creators.addLineItem({ ... })`.
60
+
61
+ * **`utils.ts`:**
62
+ * **Purpose:** Often includes utility functions related to your document model. A common utility is a function to create an empty or initial instance of your document (e.g., `utils.createDocument()`). This is based on the default values and structure defined in your state schema.
63
+ * **Significance:** Provides convenient helpers for common tasks, particularly for initializing new documents in tests or application code.
64
+
65
+ * **`reducer.ts` (or similar, defining the reducer interface/skeleton):**
66
+ * **Purpose:** This file might contain a TypeScript interface or a skeleton object that your actual reducer implementation (in the `src/` directory) will need to conform to. It outlines the expected shape of the reducer map, ensuring that you provide an implementation for every defined operation.
67
+ * **Significance:** Guides the implementation of your reducers and helps maintain consistency, ensuring that all defined operations are accounted for.
68
+
69
+ 4. **The `src/` Directory (Source Code for Your Implementation):**
70
+ This directory is where you, the developer, will write the custom logic for your document model. Unlike the `gen/` directory, files here are meant to be manually edited.
71
+
72
+ * **`reducers/`:**
73
+ * **`your-model-name.ts` (e.g., `invoice.ts`):** This is the most important file you'll work with after generation. It's where you implement the **reducer functions** for each operation. The generator usually creates a skeleton file with function stubs for each operation, which you then fill in with the actual state transition logic.
74
+ * **Significance:** This is the heart of your document model's behavior, defining how the state changes in response to each operation. The next step in the Mastery Track will typically focus on implementing these reducers.
75
+ * **`reducers/tests/`:**
76
+ * **`your-model-name.test.ts` (e.g., `invoice.test.ts`):** A placeholder or basic test file is often generated here, encouraging you to write unit tests for your reducer logic.
77
+ * **Significance:** Emphasizes the importance of testing your document model's core logic to ensure correctness and reliability.
78
+ * **`utils/` (optional):**
79
+ * **Purpose:** You can create this directory for any custom utility functions specific to your document model's implementation that don't fit directly into the reducers.
80
+ * **Significance:** Helps in organizing shared logic or complex computations that might be used across multiple reducers or other parts of your model's ecosystem.
81
+
82
+ ## Benefits of Using the Document Model Generator
83
+
84
+ Leveraging the `ph generate` command offers numerous advantages:
85
+
86
+ 1. **Reduced Boilerplate:** Automates the creation of repetitive code (type definitions, action creators), saving significant development time and effort.
87
+ 2. **Consistency:** Enforces a standardized project structure and coding patterns across different document models, making projects easier to understand and maintain.
88
+ 3. **Type Safety:** The generation of TypeScript types from your GraphQL schema is a massive boon for catching errors early in the development cycle and improving code quality.
89
+ 4. **Accelerated Development:** By providing a ready-to-use scaffold, developers can immediately focus on implementing the core business logic in the reducers, rather than setting up the foundational plumbing.
90
+ 5. **Alignment with Powerhouse Ecosystem:** The generated code is designed to integrate seamlessly with other parts of the Powerhouse ecosystem, such as the reducer execution engine and UI components.
91
+ 6. **Single Source of Truth:** Ensures that your codebase (especially types and action creators) stays synchronized with the document model specification defined in Connect. If the specification changes, regenerating the model will update these components accordingly.
92
+
93
+ ## Example Workflow Snippet
94
+
95
+ Let's assume you have defined a `ProjectTask` document model and exported `ProjectTask.phdm.zip`.
96
+
97
+ 1. **Navigate to your Powerhouse project root in the terminal.**
98
+ 2. **Run the generator:**
99
+ ```bash
100
+ ph generate ProjectTask.phdm.zip
101
+ ```
102
+ 3. **Explore the generated files:**
103
+ You would now find a new directory `document-models/project-task/` containing:
104
+ * `project-task/spec.json`
105
+ * `project-task/schema.graphql`
106
+ * `project-task/gen/types.ts` (with `ProjectTaskState`, `AssignUserInput`, etc.)
107
+ * `project-task/gen/operations.ts` (with `creators.assignUser(...)`, `creators.completeTask(...)`, etc.)
108
+ * `project-task/src/reducers/project-task.ts` (with empty functions like `assignUserOperation`, `completeTaskOperation` awaiting your implementation).
109
+
110
+ ## Next Steps
111
+
112
+ Once the Document Model Generator has successfully scaffolded your project, the immediate next step is to implement the logic for each operation within the generated reducer files (e.g., `document-models/YourModelName/src/reducers/your-model-name.ts`). This involves taking the current state and the action input, and returning the new state of the document.
113
+
114
+ Subsequently, you will write unit tests for these reducers to ensure they behave as expected under various conditions. This iterative process of defining, generating, implementing, and testing forms the core loop of document model development in Powerhouse.
115
+
116
+ By understanding the role and output of the Document Model Generator, you are well-equipped to efficiently build robust and maintainable document models within the Powerhouse framework.
@@ -0,0 +1,282 @@
1
+ # Implement Document Reducers
2
+
3
+ ## The Heart of Document Logic
4
+
5
+ In our journey through Powerhouse Document Model creation, we've defined the "what" – the structure of our data ([State Schema](02-SpecifyTheStateSchema.md)) and the ways it can be changed ([Document Operations](03-SpecifyDocumentOperations.md)). We've also seen how the [Document Model Generator](04-UseTheDocumentModelGenerator.md) translates these specifications into a coded scaffold. Now, we arrive at the "how": implementing **Document Reducers**.
6
+
7
+ Reducers are the core logic units of your document model. They are the functions that take the current state of your document and an operation (an "action"), and then determine the *new* state of the document. They are the embodiment of your business rules and the engine that drives state transitions in a predictable, auditable, and immutable way.
8
+
9
+ ## Recap: The Journey to Reducer Implementation
10
+
11
+ Before diving into the specifics of writing reducers, let's recall the preceding steps:
12
+
13
+ 1. **State Schema Definition**: You designed the GraphQL `type` definitions for your document's data structure (e.g., `ToDoListState`, `ToDoItem`).
14
+ 2. **Document Operation Specification**: You defined the GraphQL `input` types that specify the parameters for each allowed modification to your document (e.g., `AddTodoItemInput`, `UpdateTodoItemInput`). These were then associated with named operations (e.g., `ADD_TODO_ITEM`) in the Connect application.
15
+ 3. **Code Generation**: You used `ph generate <YourModelName.phdm.zip>` to create the necessary TypeScript types, action creators, and, crucially, the skeleton file for your reducers (typically `document-models/<YourModelName>/src/reducers/<your-model-name>.ts`).
16
+
17
+ This generated reducer file is our starting point. It will contain function stubs or an object structure expecting your reducer implementations, all typed according to your schema.
18
+
19
+ ## What is a Reducer? The Core Principles
20
+
21
+ In the context of Powerhouse and inspired by patterns like Redux, a reducer is a **pure function** with the following signature (conceptually):
22
+
23
+ `(currentState, action) => newState`
24
+
25
+ Let's break down its components and principles:
26
+
27
+ * **`currentState`**: This is the complete, current state of your document model instance before the operation is applied. It's crucial to treat this as **immutable**.
28
+ * **`action`**: This is an object describing the operation to be performed. It typically has:
29
+ * A `type` property: A string identifying the operation (e.g., `'ADD_TODO_ITEM'`).
30
+ * An `input` property (or similar, like `payload`): An object containing the data necessary for the operation, matching the GraphQL `input` type you defined (e.g., `{ id: '1', text: 'Buy groceries' }` for `AddTodoItemInput`).
31
+ * **`newState`**: The reducer must return a *new* state object representing the state after the operation has been applied. If the operation does not result in a state change, the reducer should return the `currentState` object itself.
32
+
33
+ ### Key Principles Guiding Reducer Implementation:
34
+
35
+ 1. **Purity**:
36
+ * **Deterministic**: Given the same `currentState` and `action`, a reducer must *always* produce the same `newState`.
37
+ * **No Side Effects**: Reducers must not perform any side effects. This means no API calls, no direct DOM manipulation, no `Math.random()` (unless seeded deterministically for specific testing scenarios), and no modification of variables outside their own scope. Their sole job is to compute the next state.
38
+
39
+ 2. **Immutability**:
40
+ * **Never Mutate `currentState`**: You must never directly modify the `currentState` object or any of its nested properties.
41
+ * **Always Return a New Object for Changes**: If the state changes, you must create and return a brand new object. If the state does not change, you return the original `currentState` object.
42
+ * This is fundamental to Powerhouse's event sourcing architecture, enabling time travel, efficient change detection, and a clear audit trail. We'll explore techniques for immutability shortly.
43
+
44
+ 3. **Single Source of Truth**: The document state managed by reducers is the single source of truth for that document instance. All UI rendering and data queries are derived from this state.
45
+
46
+ 4. **Delegation to Specific Operation Handlers**:
47
+ While you can write one large reducer that uses a `switch` statement or `if/else if` blocks based on `action.type`, Powerhouse's generated code typically encourages a more modular approach. You'll often implement a separate function for each operation, which are then combined into a main reducer object or map. The `ph generate` command usually sets up this structure for you. For example, in your `document-models/to-do-list/src/reducers/to-do-list.ts`, you'll find an object structure like this:
48
+
49
+ ```typescript
50
+ // Example structure from 01-GetStarted/03-ImplementOperationReducers.md
51
+ import { ToDoListToDoListOperations } from '../../gen/to-do-list/operations.js'; // Generated type for operations
52
+ import { ToDoListState } from '../../gen/types.js'; // Generated type for state
53
+
54
+ export const reducer: ToDoListToDoListOperations = {
55
+ addTodoItemOperation(state: ToDoListState, action, dispatch) {
56
+ // Your logic for ADD_TODO_ITEM
57
+ // ...
58
+ return newState;
59
+ },
60
+ updateTodoItemOperation(state: ToDoListState, action, dispatch) {
61
+ // Your logic for UPDATE_TODO_ITEM
62
+ // ...
63
+ return newState;
64
+ },
65
+ deleteTodoItemOperation(state: ToDoListState, action, dispatch) {
66
+ // Your logic for DELETE_TODO_ITEM
67
+ // ...
68
+ return newState;
69
+ },
70
+ // ... other operations
71
+ };
72
+ ```
73
+ The `ToDoListToDoListOperations` type (or similar, depending on your model name) is generated by Powerhouse and ensures your reducer object correctly implements all defined operations. The `state` and `action` parameters within these methods will also be strongly typed based on your schema.
74
+
75
+ The `dispatch` parameter is an advanced feature allowing a reducer to trigger subsequent operations. While powerful for complex workflows, it's often not needed for basic operations and can be ignored if unused.
76
+
77
+ ## Implementing Reducer Logic: A Practical Guide
78
+
79
+ Let's use our familiar `ToDoList` example (as detailed in `01-GetStarted/03-ImplementOperationReducers.md`) to illustrate common patterns.
80
+
81
+ Assume our `ToDoListState` is:
82
+ ```typescript
83
+ interface ToDoItem {
84
+ id: string;
85
+ text: string;
86
+ checked: boolean;
87
+ }
88
+
89
+ interface ToDoListState {
90
+ items: ToDoItem[];
91
+ }
92
+ ```
93
+
94
+ And our action creators (from `../../gen/creators` or `../../gen/operations.js`) provide actions like:
95
+ * `actions.addTodoItem({ id: 'some-id', text: 'New Task' })`
96
+ * `actions.updateTodoItem({ id: 'item-id', text: 'Updated Task Text', checked: true })`
97
+ * `actions.deleteTodoItem({ id: 'item-id' })`
98
+
99
+ ### 1. Adding an Item (e.g., `addTodoItemOperation`)
100
+
101
+ To add a new item to the `items` array immutably:
102
+
103
+ ```typescript
104
+ addTodoItemOperation(state: ToDoListState, action: /* AddTodoItemActionType */ any, dispatch) {
105
+ const newItem: ToDoItem = {
106
+ id: action.input.id,
107
+ text: action.input.text,
108
+ checked: false, // New items default to unchecked
109
+ };
110
+
111
+ // Return a new state object
112
+ return {
113
+ ...state, // Copy all existing properties from the current state
114
+ items: [...state.items, newItem], // Create a new items array: spread existing items, add the new one
115
+ };
116
+ }
117
+ ```
118
+ **Explanation**:
119
+ * We use the spread operator (`...state`) to copy top-level properties from the old state into the new state object.
120
+ * For the `items` array, we create a *new* array by spreading the existing `state.items` and then appending the `newItem`.
121
+
122
+ ### 2. Updating an Item (e.g., `updateTodoItemOperation`)
123
+
124
+ To update an existing item in the `items` array immutably:
125
+
126
+ ```typescript
127
+ updateTodoItemOperation(state: ToDoListState, action: /* UpdateTodoItemActionType */ any, dispatch) {
128
+ const { id, text, checked } = action.input;
129
+
130
+ // Return a new state object
131
+ return {
132
+ ...state,
133
+ items: state.items.map(item => {
134
+ if (item.id === id) {
135
+ // This is the item to update. Return a *new* item object.
136
+ return {
137
+ ...item, // Copy existing properties of the item
138
+ // Update only fields that are provided in the action input
139
+ ...(text !== undefined && { text: text }),
140
+ ...(checked !== undefined && { checked: checked }),
141
+ };
142
+ }
143
+ // This is not the item we're looking for, return it unchanged.
144
+ return item;
145
+ }),
146
+ };
147
+ }
148
+ ```
149
+ **Explanation**:
150
+ * We use the `map` array method, which always returns a *new* array.
151
+ * For the item that matches `action.input.id`, we create a new item object using the spread operator (`...item`) and then overwrite the properties (`text`, `checked`) that are present in `action.input`.
152
+ * The conditional spread (`...(condition && { property: value })`) is a concise way to only include a property in the new object if its corresponding input value is provided. This elegantly handles partial updates.
153
+ * If an item doesn't match the ID, it's returned as is.
154
+
155
+ **Error Handling Note**: In a real application, you might want to add a check to see if an item with `action.input.id` actually exists. If not, you could throw an error or handle it according to your application's requirements:
156
+ ```typescript
157
+ // Inside updateTodoItemOperation, before returning:
158
+ const itemToUpdate = state.items.find(item => item.id === action.input.id);
159
+ if (!itemToUpdate) {
160
+ // Option 1: Throw an error (Powerhouse runtime might catch this)
161
+ throw new Error(`Item with id ${action.input.id} not found.`);
162
+ // Option 2: Return current state (no change)
163
+ // return state;
164
+ }
165
+ // ... proceed with map
166
+ ```
167
+
168
+ ### 3. Deleting an Item (e.g., `deleteTodoItemOperation`)
169
+
170
+ To remove an item from the `items` array immutably:
171
+
172
+ ```typescript
173
+ deleteTodoItemOperation(state: ToDoListState, action: /* DeleteTodoItemActionType */ any, dispatch) {
174
+ const { id } = action.input;
175
+
176
+ // Return a new state object
177
+ return {
178
+ ...state,
179
+ items: state.items.filter(item => item.id !== id), // Create a new array excluding the item to delete
180
+ };
181
+ }
182
+ ```
183
+ **Explanation**:
184
+ * We use the `filter` array method, which returns a *new* array containing only the elements for which the callback function returns `true`.
185
+
186
+ ## Leveraging Generated Types
187
+
188
+ As highlighted in [Using the Document Model Generator](04-UseTheDocumentModelGenerator.md), `ph generate` produces TypeScript types for your state (e.g., `ToDoListState`, `ToDoItem`) and the inputs for your operations (e.g., `AddTodoItemInput`, `UpdateTodoItemInput`).
189
+
190
+ **Always use these generated types in your reducer implementations!**
191
+
192
+ ```typescript
193
+ import {
194
+ ToDoListState,
195
+ AddTodoItemInput, // Generated input type
196
+ // ... other types
197
+ } from '../../gen/types.js';
198
+ import { ToDoListToDoListOperations } from '../../gen/to-do-list/operations.js'; // Generated operations type
199
+
200
+ // Define the type for the action more explicitly if needed, or rely on inferred types
201
+ // from ToDoListToDoListOperations. For complex actions, defining specific action types can be beneficial.
202
+ // For example:
203
+ // interface AddTodoItemAction {
204
+ // type: 'ADD_TODO_ITEM'; // Or the specific string constant used by the action creator
205
+ // input: AddTodoItemInput;
206
+ // }
207
+
208
+ export const reducer: ToDoListToDoListOperations = {
209
+ addTodoItemOperation(state: ToDoListState, action: { input: AddTodoItemInput /* plus type property */ }, dispatch) {
210
+ // Now 'action.input.text' and 'action.input.id' are type-checked
211
+ const newItem = {
212
+ id: action.input.id,
213
+ text: action.input.text,
214
+ checked: false,
215
+ };
216
+ return {
217
+ ...state,
218
+ items: [...state.items, newItem],
219
+ };
220
+ },
221
+ // ... other reducers
222
+ };
223
+ ```
224
+ Using these types provides:
225
+ * **Compile-time safety**: Catch errors related to incorrect property names or data types before runtime.
226
+ * **Autocompletion and IntelliSense**: Improved developer experience in your IDE.
227
+ * **Clearer code**: Types serve as documentation for the expected data structures.
228
+
229
+ ## Testing Your Reducers
230
+
231
+ Reducers, being pure functions, are inherently easy to test. For each reducer:
232
+ 1. Set up an initial state.
233
+ 2. Create an action object (ideally using the generated action creators from `../../gen/creators.js` or `../../gen/operations.js`).
234
+ 3. Call the reducer function with the initial state and the action.
235
+ 4. Assert that the returned new state is what you expect it to be.
236
+ 5. Crucially, also assert that the *original* state object was not modified.
237
+
238
+ The `01-GetStarted/03-ImplementOperationReducers.md` document provides excellent examples of reducer tests:
239
+
240
+ ```typescript
241
+ // Example from 01-GetStarted/03-ImplementOperationReducers.md (simplified)
242
+ import utils from '../../gen/utils'; // For createDocument
243
+ import { reducer } from '../../gen/reducer'; // The combined reducer
244
+ import * as creators from '../../gen/creators'; // Action creators
245
+ import { ToDoListDocument, ToDoListState } from '../../gen/types';
246
+
247
+ describe('Todolist Operations', () => {
248
+ let document: ToDoListDocument; // Assuming ToDoListDocument wraps ToDoListState
249
+
250
+ beforeEach(() => {
251
+ document = utils.createDocument(); // Gets initial state
252
+ });
253
+
254
+ it('should handle addTodoItem operation', () => {
255
+ const input = { id: '1', text: 'Buy milk' };
256
+ const action = creators.addTodoItem(input); // Use action creator
257
+
258
+ // Assuming your main reducer takes the whole document and action
259
+ const updatedDocument = reducer(document, action);
260
+
261
+ expect(updatedDocument.state.global.items).toHaveLength(1);
262
+ expect(updatedDocument.state.global.items[0].text).toBe('Buy milk');
263
+ // Also check that document.state.global.items is different from updatedDocument.state.global.items (immutability)
264
+ });
265
+ });
266
+ ```
267
+
268
+ The generator typically creates a test file skeleton (e.g., `document-models/<YourModelName>/src/reducers/tests/<your-model-name>.test.ts`) to get you started. **Thoroughly testing your reducers is paramount for a robust document model.**
269
+
270
+ ## Reducers and the Event Sourcing Model
271
+
272
+ Every time a reducer processes an operation and returns a new state, Powerhouse records the original operation (the "event") in an append-only log associated with the document instance. The current state of the document is effectively a "fold" or "reduction" of all past events, applied sequentially by the reducers.
273
+
274
+ This is why purity and immutability are so critical:
275
+ * **Purity** ensures that replaying the same sequence of events will always yield the exact same final state.
276
+ * **Immutability** ensures that each event clearly defines a discrete state transition, making it easy to audit changes and understand the document's history.
277
+
278
+ ## Conclusion
279
+
280
+ Implementing document reducers is where you breathe life into your document model's specification. By adhering to the principles of purity and immutability, and by leveraging the type safety provided by Powerhouse's code generation, you can build predictable, testable, and maintainable business logic. These reducers form the immutable backbone of your document's state management, perfectly aligning with the event sourcing architecture that underpins Powerhouse.
281
+
282
+ With your reducers implemented and tested, your document model is now functionally complete from a data manipulation perspective. The next stages often involve building user interfaces or integrations that interact with this model by dispatching the operations you've now so carefully implemented.