@powerhousedao/academy 0.1.0-dev.0
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.
- package/.vscode/settings.json +3 -0
- package/CHANGELOG.md +9 -0
- package/Dockerfile +31 -0
- package/ProcFile +1 -0
- package/README.md +43 -0
- package/babel.config.js +3 -0
- package/blog/BeyondCommunication-ABlueprintForDevelopment.md +88 -0
- package/blog/TheChallengeOfChange.md +86 -0
- package/blog/images/Iteration.png +0 -0
- package/blog/images/RAD.png +0 -0
- package/docs/academy/01-GetStarted/00-GetStarted.mdx +181 -0
- package/docs/academy/01-GetStarted/01_InstallDemoPackage.md +38 -0
- package/docs/academy/01-GetStarted/02-ToDoList/01-CreateNewPowerhouseProject.md +97 -0
- package/docs/academy/01-GetStarted/02-ToDoList/02-DefineToDoListDocumentModel.md +86 -0
- package/docs/academy/01-GetStarted/02-ToDoList/03-ImplementOperationReducers.md +201 -0
- package/docs/academy/01-GetStarted/02-ToDoList/04-BuildToDoListEditor.md +494 -0
- package/docs/academy/01-GetStarted/02-ToDoList/_category_.json +8 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/DocumentModelHeader.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/DocumentModelOperations.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/OpenDocumentModelEditor.gif +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/completeEditor.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/connectApp.gif +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/form.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/mytodolist.gif +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/reducers.png +0 -0
- package/docs/academy/01-GetStarted/02-ToDoList/images/vscode.png +0 -0
- package/docs/academy/01-GetStarted/styles.module.css +99 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/00-BuilderTools.md +234 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/01-SetupBuilderEnvironment.md +247 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/04-UtilitiesAndTips.md +79 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/01-SetupBuilderEnvironment.md +216 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/02-CreateNewPowerhouseProject.md +78 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/03-DefineChatroomDocumentModel.md +139 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/04-ImplementOperationReducers.md +364 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/05-ImplementChatroomEditor.md +194 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/06-LaunchALocalReactor.md +15 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-1.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-2.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-3.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-4.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image-5.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/image.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/ChatRoomConnectApp.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/ChatRoomTest.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/completeEditor.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/form.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/reducers.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/Chatroom/images/vscode.png +0 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-MoreTutorials/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/01-Create/02-StandardDocumentModelWorkflow.md +229 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/01-BuildingBeautifulDocumentEditors.md +109 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/02-ConfiguringDrives.md +51 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/03-BuildingADriveExplorer.md +174 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/01-OperationHistory.md +67 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/02-RevisionHistoryTimeline.md +132 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/_category_.json +7 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/committer-address-popup.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/revision-hash-popup.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/revision-history-list.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/07-DocumentTools/images/signature-details-popup.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/images/CreateDrive.png +0 -0
- package/docs/academy/02-AdvancedTutorial/03-BuildingUserExperiences/images/mytodolist.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/01-ReadingAndWritingThroughTheAPI.mdx +121 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/02-GraphQLAtPowerhouse.md +156 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/03-WorkingWithSubgraphs/02-GraphQLAndSubgraphs.mdx +119 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/03-WorkingWithSubgraphs/03-WorkingWithSubgraphs.md +312 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/03-WorkingWithSubgraphs/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/04-analytics-processor.md +342 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/01-SetupBuilderEnvironment.md +215 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/02-CreateNewPowerhouseProject.md +55 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/03-GenerateAnAnalyticsProcessor.md +173 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/04-UpdateAnalyticsProcessor.md +223 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-SPV.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-a-new-asset.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Create-a-transaction.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/Transaction-table.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/create-a-new-RWA-document.gif +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/05-AnalyticsProcessorTutorial/images/granularity.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/QueryingADocumentWithGraphQL.md +244 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/listener-raw.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/raw-reports1.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/raw-reports2.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/GraphQL References/rwa-reports/rwaRegister.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/apse.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/best-practices.md +60 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/filter.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/filteroptions.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/graphql/index.md +166 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/graphql/integration.md +75 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/dbs.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/high-level.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/indexeddb.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/libs-core.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/libs.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/lod.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/logo.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/navbar.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-1.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-2.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-3.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-4.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-5.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/overview-6.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/paths-1.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/images/paths-2.jpg +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/intro.md +149 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/benchmarks.md +27 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/browser.md +77 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/compatibility.md +14 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/index.md +230 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/memory.md +72 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/pg.md +63 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/schema.md +14 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/typescript/utilities.md +102 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/use-cases/index.md +7 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/use-cases/maker.md +652 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/06-Analytics Engine/use-cases/processors.md +3 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/OperationHistory.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/OperationsQuery.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/QueryDocumentID.png +0 -0
- package/docs/academy/02-AdvancedTutorial/04-WorkWithData/images/SwitchboardButton.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/00-IntegrateInAFront-End +3 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/01-IntroducingFusion +18 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/02-IntroductionToPackages.md +79 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/02-PublishYourProject.md +230 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/03-RunOnACloudServer.md +279 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/03-SetupEnvironment.md +436 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/04-GraphQLNamespacing +44 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/05-LaunchYourBackend.md +3 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/06-LaunchYourFrontend.md +3 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/_category_.json +8 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/SSHConnection.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/homedesign.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/keyconcepts.png +0 -0
- package/docs/academy/02-AdvancedTutorial/05-Launch/images/tutorialschema.png +0 -0
- package/docs/academy/02-AdvancedTutorial/06-Authorization/Authorization.md +100 -0
- package/docs/academy/02-AdvancedTutorial/_category_.json +7 -0
- package/docs/academy/03-APIReferences/00-PowerhouseCLI.md +1 -0
- package/docs/academy/03-APIReferences/_category_.json +7 -0
- package/docs/academy/04-ComponentLibrary/01-PowerhouseDesignSystem.md +94 -0
- package/docs/academy/04-ComponentLibrary/02-BuildingWithScalars.md +54 -0
- package/docs/academy/04-ComponentLibrary/03-Scalar-Components/01-phid-field.mdx +72 -0
- package/docs/academy/04-ComponentLibrary/03-Scalar-Components/02-input-field.mdx +0 -0
- package/docs/academy/04-ComponentLibrary/04-Complex-Components/01-sidebar.mdx +36 -0
- package/docs/academy/04-ComponentLibrary/05-Layout-Components/01-test-toupdate.mdx +61 -0
- package/docs/academy/04-ComponentLibrary/06-Fragments/01-test-toupdate.mdx +61 -0
- package/docs/academy/04-ComponentLibrary/_category_.json +8 -0
- package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +50 -0
- package/docs/academy/05-Architecture/01-WorkingWithTheReactor.md +48 -0
- package/docs/academy/05-Architecture/02-ReferencingMonorepoPackages +65 -0
- package/docs/academy/05-Architecture/04-MovingBeyondCRUD +61 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/01-WhatIsADocumentModel.md +188 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/02-DAOandDocumentsModelsQ+A.md +177 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/02-domain-modeling.md +103 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/03-BenefitsOfDocumentModels.md +95 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/05-best-practices.md +257 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/_category_.json +8 -0
- package/docs/academy/05-Architecture/05-DocumentModelTheory/three-data-layers.png +0 -0
- package/docs/academy/05-Architecture/_category_.json +7 -0
- package/docs/academy/05-Architecture/images/image.png +0 -0
- package/docs/academy/06-Cookbook.md +905 -0
- package/docs/academy/07-Glossary.md +50 -0
- package/docs/bookofpowerhouse/01-Overview.md +29 -0
- package/docs/bookofpowerhouse/02-GeneralFrameworkAndPhilosophy.md +15 -0
- package/docs/bookofpowerhouse/03-PowerhouseSoftwareArchitecture.md +33 -0
- package/docs/bookofpowerhouse/04-DevelopmentApproaches.md +36 -0
- package/docs/bookofpowerhouse/05-SNOsandANewModelForOSSandPublicGoods.md +73 -0
- package/docs/bookofpowerhouse/06-SNOsInActionAndPlatformEconomies.md +17 -0
- package/docs/renown/01-intro.md +18 -0
- package/docs/renown/02-renown-login-flow.md +60 -0
- package/docusaurus +0 -0
- package/docusaurus.config.ts +170 -0
- package/package.json +50 -0
- package/powerhouse-docs@0.0.0 +0 -0
- package/sidebars.ts +33 -0
- package/src/components/HomepageFeatures/index.tsx +250 -0
- package/src/components/HomepageFeatures/styles.module.css +267 -0
- package/src/css/custom.css +450 -0
- package/src/pages/index.module.css +37 -0
- package/src/pages/index.tsx +42 -0
- package/src/pages/markdown-page.md +7 -0
- package/static/.nojekyll +0 -0
- package/static/fonts/FranieBold.otf +0 -0
- package/static/fonts/FranieRegular.otf +0 -0
- package/static/img/Powerhouse Website Drive.png +0 -0
- package/static/img/Powerhouse Website Storage Layer (1).png +0 -0
- package/static/img/Powerhouse Website Storage Layer.png +0 -0
- package/static/img/Powerhouse-main-light.svg +13 -0
- package/static/img/Powerhouse-main.svg +13 -0
- package/static/img/Renown Intro Diagram.png +0 -0
- package/static/img/Union.svg +3 -0
- package/static/img/academy/icons/Advanced.svg +4 -0
- package/static/img/academy/icons/Book.svg +5 -0
- package/static/img/academy/icons/Cookbook.svg +3 -0
- package/static/img/academy/icons/Create.svg +3 -0
- package/static/img/academy/icons/Data.svg +3 -0
- package/static/img/academy/icons/Editor.svg +3 -0
- package/static/img/academy/icons/Flash.svg +3 -0
- package/static/img/academy/icons/Launch.svg +3 -0
- package/static/img/academy-icon.png +0 -0
- package/static/img/connect-icon.png +0 -0
- package/static/img/connect.png +0 -0
- package/static/img/docusaurus-social-card.jpg +0 -0
- package/static/img/docusaurus.png +0 -0
- package/static/img/empty-background.png +0 -0
- package/static/img/favicon.ico +0 -0
- package/static/img/fusion-icon.png +0 -0
- package/static/img/fusion.png +0 -0
- package/static/img/ph-icon-light.svg +3 -0
- package/static/img/powerhouse-layer.png +0 -0
- package/static/img/powerhouse-storage-layer.png +0 -0
- package/static/img/reactor.png +0 -0
- package/static/img/renown-icon.png +0 -0
- package/static/img/renown.png +0 -0
- package/static/img/switchboard-icon.png +0 -0
- package/static/img/switchboard.png +0 -0
- package/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/static/img/undraw_docusaurus_react.svg +170 -0
- package/static/img/undraw_docusaurus_tree.svg +40 -0
- package/static/img/video-placeholder.svg +16 -0
- package/static.json +7 -0
- package/tsconfig.json +7 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# The ToDoList Data Model
|
|
2
|
+
|
|
3
|
+
In this tutorial, you will learn how to design your document model and export it to be later used in your Powerhouse project.
|
|
4
|
+
If you don't have a document model created yet, have a look at the previous step of this tutorial to create a new document model.
|
|
5
|
+
|
|
6
|
+
Before you start, make sure you have the Connect application running with the command `ph connect`
|
|
7
|
+
|
|
8
|
+
## ToDoList Document Model Schema
|
|
9
|
+
|
|
10
|
+
Likely you have called your project 'ToDoList'. If not, please make a new document and pay attention to the capitalization as it influences our code. We'll continue with this project to teach you how to create a document model and later an editor for your model. We use the GraphQL Schema Definition Language (SDL) to define the document model schema. Below, you can see the SDL for the `ToDoList` document model.
|
|
11
|
+
|
|
12
|
+
:::info
|
|
13
|
+
This schema contains the **data structure** of the document model and the basic operations that can be performed on the document model.
|
|
14
|
+
Document models in Powerhouse leverage **event sourcing principles**, where every state transition is represented by an operation. GraphQL input types describe operations, ensuring that user intents are captured effectively. These operations detail the parameters needed for state transitions. The use of GraphQL aligns these transitions with explicit, validated, and reproducible commands, supporting **CQRS** (Command Query Responsibility Segregation) patterns.
|
|
15
|
+
:::
|
|
16
|
+
|
|
17
|
+
## State Schema
|
|
18
|
+
|
|
19
|
+
```graphql
|
|
20
|
+
# The state of our todolist
|
|
21
|
+
type ToDoListState {
|
|
22
|
+
items: [ToDoItem!]!
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
# A single to-do item
|
|
26
|
+
type ToDoItem {
|
|
27
|
+
id: ID!
|
|
28
|
+
text: String!
|
|
29
|
+
checked: Boolean!
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Operations Schema
|
|
34
|
+
|
|
35
|
+
```graphql
|
|
36
|
+
# Defines a GraphQL input type for adding a new to-do item
|
|
37
|
+
input AddTodoItemInput {
|
|
38
|
+
id: ID!
|
|
39
|
+
text: String!
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# Defines a GraphQL input type for updating a to-do item
|
|
43
|
+
input UpdateTodoItemInput {
|
|
44
|
+
id: ID!
|
|
45
|
+
text: String
|
|
46
|
+
checked: Boolean
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Defines a GraphQL input type for deleting a to-do item
|
|
50
|
+
input DeleteTodoItemInput {
|
|
51
|
+
id: ID!
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Define the Document Model
|
|
56
|
+
|
|
57
|
+
To be able to define the document model, you need to open the document model editor in Connect.
|
|
58
|
+
|
|
59
|
+
The steps below show you how to do this:
|
|
60
|
+
|
|
61
|
+
1. In the Connect application, click on the **'document model'** editor to open the document model editor.
|
|
62
|
+
2. Call your document model 'ToDoList' and pay attention to capitalization.
|
|
63
|
+
3. You'll be presented with a form to fill in metadata about the document model. Fill in the details in the respective fields.
|
|
64
|
+
|
|
65
|
+
In the `Document Type` field, type `powerhouse/todolist`. This defines the new type of document that will be created with this document model.
|
|
66
|
+
|
|
67
|
+

|
|
68
|
+
|
|
69
|
+
4. In the code editor, you can see the SDL for the document model. Replace the existing SDL with the SDL defined in the [State Schema](#state-schema) section. Only copy and paste the types, leaving the inputs for the next step. You can, however, already press the 'Sync with schema' button to set the initial state of your document model based on your Schema Definition Language.
|
|
70
|
+
5. Below the editor, there is an input field `Add module`. You need to create and name a module that the input operations will be added to. In this case, we will name the module `to_do_list`. Press enter.
|
|
71
|
+
6. Now there is a new field, called `Add operation`. Here you will have to add each input operation to the module, one by one.
|
|
72
|
+
7. Inside the `Add operation` field, type `ADD_TODO_ITEM` and press enter. A small editor will appear underneath it, with an empty input type that you have to fill. Copy the first input type from the [Operations Schema](#operations-schema) section and paste it in the editor. The editor should look like this:
|
|
73
|
+
|
|
74
|
+
```graphql
|
|
75
|
+
input AddTodoItemInput {
|
|
76
|
+
id: ID!
|
|
77
|
+
text: String!
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
7. Repeat step 6 for the other input operations. You may have noticed that you only need to add the name of the operation (e.g., `UPDATE_TODO_ITEM`, `DELETE_TODO_ITEM`) without the `Input` suffix. It will then be generated once you press enter.
|
|
82
|
+
8. Once you have added all the input operations, click on the `Export` button, at the top right of the editor, to save the document model on your local machine. Ideally, you should save your file in the root of your Powerhouse project on your machine.
|
|
83
|
+
|
|
84
|
+
Check below screenshot for the complete implementation:
|
|
85
|
+
|
|
86
|
+

|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Implement Operation Reducers
|
|
2
|
+
|
|
3
|
+
In this section, we will implement and test the operation reducers for the **ToDoList** document model. In order to do this, you have to export the document model from the Connect application and import it into your powerhouse project directory.
|
|
4
|
+
|
|
5
|
+
To export the document model, follow the steps in the [Define ToDoList Document Model](/docs/academy/GetStarted/ToDoList/DefineToDoListDocumentModel) section.
|
|
6
|
+
|
|
7
|
+
## Understanding Reducers in Document Models
|
|
8
|
+
|
|
9
|
+
Reducers are a core concept in Powerhouse document models. They implement the state transition logic for each operation defined in your schema:
|
|
10
|
+
|
|
11
|
+
1. **Connection to Schema Definition Language (SDL)**: The reducers directly implement the operations you defined in your SDL. Remember how we defined `AddTodoItemInput`, `UpdateTodoItemInput`, and `DeleteTodoItemInput` in our schema? The reducers provide the actual implementation of what happens when those operations are performed.
|
|
12
|
+
|
|
13
|
+
2. **Event Sourcing Pattern**: Document models in Powerhouse follow event sourcing principles, where each operation is recorded in the document's history. The current state of the document is derived by applying all operations in sequence.
|
|
14
|
+
|
|
15
|
+
3. **Immutable Updates**: While the reducer code appears to modify the state directly, Powerhouse handles immutability behind the scenes. Each operation produces a new document state without modifying the previous one.
|
|
16
|
+
|
|
17
|
+
4. **Type Safety**: Powerhouse generates TypeScript types from your SDL, ensuring that your reducers and operations are type-safe.
|
|
18
|
+
|
|
19
|
+
5. **Pure Functions**: Reducers should be pure functions that only depend on the current state and the operation input, making them predictable and testable.
|
|
20
|
+
|
|
21
|
+
Let's see how these concepts are implemented in our **ToDoList** document model.
|
|
22
|
+
|
|
23
|
+
## Import Document Model and Generate Code
|
|
24
|
+
|
|
25
|
+
To import the document model into your powerhouse project, you can either:
|
|
26
|
+
|
|
27
|
+
- Copy and paste the file directly into the root of your powerhouse project.
|
|
28
|
+
- Or drag and drop the file into the powerhouse project directory in the VSCode editor as seen in the image below:
|
|
29
|
+
|
|
30
|
+
Either step will import the document model into your powerhouse project.
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
The next steps will take place in the VSCode editor. Make sure to have it open and the terminal window inside VSCode open as well.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
To write the operation reducers of the **ToDoList** document model, you need to generate the document model code from the document model file you have exported into the powerhouse project directory.
|
|
38
|
+
|
|
39
|
+
To do this, run the following command in the terminal:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
ph generate ToDoList.phdm.zip
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Now you can navigate to `/document-models/to-do-list/src/reducers/to-do-list.ts` and start writing the operation reducers.
|
|
46
|
+
|
|
47
|
+
Open the `to-do-list.ts` file and you should see the code that needs to be filled for the three operations you have defined earlier. Image below shows the code that needs to be filled:
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
## Write the Operation Reducers
|
|
52
|
+
|
|
53
|
+
1. Copy and paste the code below into the `to-do-list.ts` file in the `reducers` folder.
|
|
54
|
+
2. Save the file.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { ToDoListToDoListOperations } from '../../gen/to-do-list/operations.js';
|
|
59
|
+
|
|
60
|
+
// REMARKS: This is our main reducer object that implements all operations defined in the schema.
|
|
61
|
+
// The ToDoListToDoListOperations type is auto-generated from our SDL and ensures type safety.
|
|
62
|
+
export const reducer: ToDoListToDoListOperations = {
|
|
63
|
+
// REMARKS: The addTodoItemOperation adds a new item to our todolist.
|
|
64
|
+
// - state: The current document state that we can modify
|
|
65
|
+
// - action: Contains the operation type and input data from the client
|
|
66
|
+
// - dispatch: Function to trigger additional operations (not used here)
|
|
67
|
+
addTodoItemOperation(state, action, dispatch) {
|
|
68
|
+
// REMARKS: While this looks like we're directly mutating state, Powerhouse
|
|
69
|
+
// handles immutability behind the scenes, creating a new state object.
|
|
70
|
+
state.items.push({
|
|
71
|
+
id: action.input.id, // Using the client-provided ID
|
|
72
|
+
text: action.input.text, // Setting the todo text from input
|
|
73
|
+
checked: false, // New items always start unchecked
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// REMARKS: The updateTodoItemOperation modifies an existing todo item.
|
|
78
|
+
// It handles partial updates, allowing only specific fields to be updated.
|
|
79
|
+
updateTodoItemOperation(state, action, dispatch) {
|
|
80
|
+
// REMARKS: First find the item we want to update by its ID
|
|
81
|
+
const item = state.items.find(item => item.id === action.input.id);
|
|
82
|
+
|
|
83
|
+
// REMARKS: Proper error handling if item doesn't exist
|
|
84
|
+
if (!item) {
|
|
85
|
+
throw new Error(`Item with id ${action.input.id} not found`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// REMARKS: We only update fields that were included in the input
|
|
89
|
+
// This allows for partial updates (only update what was provided)
|
|
90
|
+
if (action.input.text) {
|
|
91
|
+
item.text = action.input.text;
|
|
92
|
+
}
|
|
93
|
+
if (typeof action.input.checked === 'boolean') {
|
|
94
|
+
item.checked = action.input.checked;
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// REMARKS: The deleteTodoItemOperation removes an item from the list.
|
|
99
|
+
// This showcases functional programming with array filters for immutable updates.
|
|
100
|
+
deleteTodoItemOperation(state, action, dispatch) {
|
|
101
|
+
// REMARKS: Create a new array containing only items that don't match the ID
|
|
102
|
+
// This is a common pattern for immutable array updates in JavaScript
|
|
103
|
+
state.items = state.items.filter(item => item.id !== action.input.id);
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Write the Operation Reducers Tests
|
|
109
|
+
|
|
110
|
+
In order to make sure the operation reducers are working as expected, you need to write tests for them.
|
|
111
|
+
|
|
112
|
+
Navigate to `/document-models/to-do-list/src/reducers/tests/to-do-list.test.ts` and copy and paste the code below into the file. Save the file.
|
|
113
|
+
|
|
114
|
+
Here are the tests for the three operations written in the reducers file. This test file creates an empty ToDoList document model, then adds a todo item, updates it and deletes it.
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
import utils from '../../gen/utils';
|
|
118
|
+
import { reducer } from '../../gen/reducer';
|
|
119
|
+
import * as creators from '../../gen/creators';
|
|
120
|
+
import { ToDoListDocument } from '../../gen/types';
|
|
121
|
+
|
|
122
|
+
// REMARKS:
|
|
123
|
+
// These tests demonstrate the event sourcing principles of our document model.
|
|
124
|
+
// Each operation is recorded in the document's operations list and affects the state.
|
|
125
|
+
|
|
126
|
+
describe('Todolist Operations', () => {
|
|
127
|
+
let document: ToDoListDocument;
|
|
128
|
+
|
|
129
|
+
beforeEach(() => {
|
|
130
|
+
// REMARKS: We start with a fresh, empty document for each test
|
|
131
|
+
document = utils.createDocument();
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('should handle addTodoItem operation', () => {
|
|
135
|
+
// REMARKS: We create an input object matching our AddTodoItemInput schema
|
|
136
|
+
const input = { id: '1', text: 'Buy milk' };
|
|
137
|
+
|
|
138
|
+
// REMARKS: We apply the operation to get a new document state
|
|
139
|
+
// Note how we use the creators to generate the operation action
|
|
140
|
+
const updatedDocument = reducer(document, creators.addTodoItem(input));
|
|
141
|
+
|
|
142
|
+
// REMARKS: We verify that:
|
|
143
|
+
// 1. The operation was recorded in the document's operation history
|
|
144
|
+
// 2. The state was updated according to our reducer implementation
|
|
145
|
+
expect(updatedDocument.operations.global).toHaveLength(1);
|
|
146
|
+
expect(updatedDocument.operations.global[0].type).toBe('ADD_TODO_ITEM');
|
|
147
|
+
expect(updatedDocument.state.global.items).toHaveLength(1);
|
|
148
|
+
expect(updatedDocument.state.global.items[0].text).toBe('Buy milk');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should handle updateTodoItem operation', () => {
|
|
152
|
+
// REMARKS: For update, we first need to add an item, then update it
|
|
153
|
+
// This demonstrates the sequential application of operations
|
|
154
|
+
const addInput = { id: '1', text: 'Buy milk' };
|
|
155
|
+
const updateInput = { id: '1', text: 'Buy bread' };
|
|
156
|
+
|
|
157
|
+
// REMARKS: Operations are applied in sequence, building up document state
|
|
158
|
+
const createdDocument = reducer(document, creators.addTodoItem(addInput));
|
|
159
|
+
const updatedDocument = reducer(createdDocument, creators.updateTodoItem(updateInput));
|
|
160
|
+
|
|
161
|
+
// REMARKS: Now we have 2 operations in history, and the state reflects both
|
|
162
|
+
expect(updatedDocument.operations.global).toHaveLength(2);
|
|
163
|
+
expect(updatedDocument.state.global.items[0].text).toBe('Buy bread');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should handle deleteTodoItem operation', () => {
|
|
167
|
+
// REMARKS: Similar pattern - add an item, then delete it
|
|
168
|
+
const addInput = { id: '1', text: 'Buy milk' };
|
|
169
|
+
const deleteInput = { id: '1' };
|
|
170
|
+
|
|
171
|
+
const createdDocument = reducer(document, creators.addTodoItem(addInput));
|
|
172
|
+
const updatedDocument = reducer(createdDocument, creators.deleteTodoItem(deleteInput));
|
|
173
|
+
|
|
174
|
+
// REMARKS: After deletion, we still have 2 operations in history,
|
|
175
|
+
// but the items array is now empty again in the final state
|
|
176
|
+
expect(updatedDocument.operations.global).toHaveLength(2);
|
|
177
|
+
expect(updatedDocument.state.global.items).toHaveLength(0);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Now you can run the tests to make sure the operation reducers are working as expected.
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pnpm run test
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Output should be as follows:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
Test Files 2 passed (2)
|
|
192
|
+
Tests 5 passed (5)
|
|
193
|
+
Start at 12:04:57
|
|
194
|
+
Duration 417ms (transform 79ms, setup 0ms, collect 174ms, tests 12ms, environment 0ms, prepare 158ms)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
If you got the same output, you have successfully implemented the operation reducers and tests for the **ToDoList** document model. Congratulations, you've successfully setup the backbone for a simple **ToDoList** document model.
|
|
198
|
+
|
|
199
|
+
:::tip
|
|
200
|
+
Continue to the next chapter on your builder track to learn how to implement the document model editor so you can see a simple user interface for the **ToDoList** document model in action. Click here for the [ToDoList Editor](/docs/academy/GetStarted/ToDoList/BuildToDoListEditor)
|
|
201
|
+
:::
|