@powerhousedao/academy 4.1.0-dev.8 → 4.1.0-dev.80

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 (108) hide show
  1. package/.vscode/settings.json +1 -1
  2. package/CHANGELOG.md +605 -0
  3. package/README.md +3 -3
  4. package/babel.config.js +1 -1
  5. package/blog/BeyondCommunication-ABlueprintForDevelopment.md +25 -24
  6. package/blog/TheChallengeOfChange.md +21 -21
  7. package/docs/academy/01-GetStarted/00-ExploreDemoPackage.mdx +67 -30
  8. package/docs/academy/01-GetStarted/01-CreateNewPowerhouseProject.md +38 -21
  9. package/docs/academy/01-GetStarted/02-DefineToDoListDocumentModel.md +24 -19
  10. package/docs/academy/01-GetStarted/03-ImplementOperationReducers.md +44 -41
  11. package/docs/academy/01-GetStarted/04-BuildToDoListEditor.md +10 -10
  12. package/docs/academy/01-GetStarted/05-VetraStudio.md +164 -0
  13. package/docs/academy/01-GetStarted/06-ReactorMCP.md +58 -0
  14. package/docs/academy/01-GetStarted/home.mdx +185 -90
  15. package/docs/academy/01-GetStarted/images/Modules.png +0 -0
  16. package/docs/academy/01-GetStarted/images/VetraStudioDrive.png +0 -0
  17. package/docs/academy/01-GetStarted/styles.module.css +5 -5
  18. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/01-Prerequisites.md +46 -18
  19. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/02-StandardDocumentModelWorkflow.md +118 -68
  20. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/03-BuilderTools.md +75 -33
  21. package/docs/academy/02-MasteryTrack/01-BuilderEnvironment/_category_.json +6 -6
  22. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/01-WhatIsADocumentModel.md +30 -21
  23. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/02-SpecifyTheStateSchema.md +41 -37
  24. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/03-SpecifyDocumentOperations.md +29 -25
  25. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/04-UseTheDocumentModelGenerator.md +36 -37
  26. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/05-ImplementDocumentReducers.md +128 -109
  27. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/06-ImplementDocumentModelTests.md +95 -86
  28. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/07-ExampleToDoListRepository.md +7 -9
  29. package/docs/academy/02-MasteryTrack/02-DocumentModelCreation/_category_.json +6 -6
  30. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/01-BuildingDocumentEditors.md +65 -47
  31. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/02-ConfiguringDrives.md +77 -62
  32. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/03-BuildingADriveExplorer.md +360 -349
  33. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/00-DocumentToolbar.mdx +16 -10
  34. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/01-OperationHistory.md +10 -7
  35. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/02-RevisionHistoryTimeline.md +26 -11
  36. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/06-DocumentTools/_category_.json +6 -6
  37. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-Authorization/01-RenownAuthenticationFlow.md +14 -7
  38. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-Authorization/02-Authorization.md +0 -1
  39. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/07-Authorization/_category_.json +5 -5
  40. package/docs/academy/02-MasteryTrack/03-BuildingUserExperiences/_category_.json +1 -1
  41. package/docs/academy/02-MasteryTrack/04-WorkWithData/01-GraphQLAtPowerhouse.md +45 -33
  42. package/docs/academy/02-MasteryTrack/04-WorkWithData/02-UsingTheAPI.mdx +61 -18
  43. package/docs/academy/02-MasteryTrack/04-WorkWithData/03-UsingSubgraphs.md +105 -456
  44. package/docs/academy/02-MasteryTrack/04-WorkWithData/04-analytics-processor.md +126 -110
  45. package/docs/academy/02-MasteryTrack/04-WorkWithData/05-RelationalDbProcessor.md +98 -65
  46. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/GraphQL References/QueryingADocumentWithGraphQL.md +23 -21
  47. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/best-practices.md +9 -9
  48. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/graphql/index.md +11 -23
  49. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/graphql/integration.md +25 -9
  50. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/intro.md +10 -10
  51. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/benchmarks.md +1 -1
  52. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/index.md +16 -11
  53. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/memory.md +6 -5
  54. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/schema.md +2 -2
  55. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/typescript/utilities.md +7 -5
  56. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/use-cases/maker.md +32 -58
  57. package/docs/academy/02-MasteryTrack/04-WorkWithData/06-Analytics Engine/use-cases/processors.md +1 -1
  58. package/docs/academy/02-MasteryTrack/04-WorkWithData/07-drive-analytics.md +105 -71
  59. package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_01-SetupBuilderEnvironment.md +22 -0
  60. package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_02-CreateNewPowerhouseProject.md +9 -8
  61. package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_03-GenerateAnAnalyticsProcessor.md +28 -32
  62. package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_04-UpdateAnalyticsProcessor.md +25 -26
  63. package/docs/academy/02-MasteryTrack/04-WorkWithData/_ARCHIVE-AnalyticsProcessorTutorial/_category_.json +1 -1
  64. package/docs/academy/02-MasteryTrack/04-WorkWithData/_category_.json +7 -7
  65. package/docs/academy/02-MasteryTrack/05-Launch/01-IntroductionToPackages.md +3 -4
  66. package/docs/academy/02-MasteryTrack/05-Launch/02-PublishYourProject.md +69 -45
  67. package/docs/academy/02-MasteryTrack/05-Launch/03-SetupEnvironment.md +70 -40
  68. package/docs/academy/02-MasteryTrack/05-Launch/04-ConfigureEnvironment.md +1 -0
  69. package/docs/academy/02-MasteryTrack/05-Launch/_category_.json +7 -7
  70. package/docs/academy/02-MasteryTrack/_category_.json +6 -6
  71. package/docs/academy/03-ExampleUsecases/Chatroom/02-CreateNewPowerhouseProject.md +5 -3
  72. package/docs/academy/03-ExampleUsecases/Chatroom/03-DefineChatroomDocumentModel.md +38 -37
  73. package/docs/academy/03-ExampleUsecases/Chatroom/04-ImplementOperationReducers.md +45 -41
  74. package/docs/academy/03-ExampleUsecases/Chatroom/05-ImplementChatroomEditor.md +14 -14
  75. package/docs/academy/03-ExampleUsecases/Chatroom/06-LaunchALocalReactor.md +6 -6
  76. package/docs/academy/03-ExampleUsecases/Chatroom/_category_.json +1 -1
  77. package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +140 -61
  78. package/docs/academy/04-APIReferences/01-ReactHooks.md +649 -141
  79. package/docs/academy/04-APIReferences/04-RelationalDatabase.md +121 -113
  80. package/docs/academy/04-APIReferences/05-PHDocumentMigrationGuide.md +48 -41
  81. package/docs/academy/04-APIReferences/_category_.json +6 -6
  82. package/docs/academy/05-Architecture/00-PowerhouseArchitecture.md +1 -2
  83. package/docs/academy/05-Architecture/01-WorkingWithTheReactor.md +11 -8
  84. package/docs/academy/05-Architecture/05-DocumentModelTheory/_category_.json +1 -1
  85. package/docs/academy/05-Architecture/_category_.json +6 -6
  86. package/docs/academy/06-ComponentLibrary/00-DocumentEngineering.md +25 -23
  87. package/docs/academy/06-ComponentLibrary/02-CreateCustomScalars.md +105 -93
  88. package/docs/academy/06-ComponentLibrary/03-IntegrateIntoAReactComponent.md +1 -0
  89. package/docs/academy/06-ComponentLibrary/_category_.json +7 -7
  90. package/docs/academy/07-Cookbook.md +268 -35
  91. package/docs/academy/08-Glossary.md +7 -1
  92. package/docs/bookofpowerhouse/01-Overview.md +2 -2
  93. package/docs/bookofpowerhouse/02-GeneralFrameworkAndPhilosophy.md +1 -7
  94. package/docs/bookofpowerhouse/03-PowerhouseSoftwareArchitecture.md +10 -7
  95. package/docs/bookofpowerhouse/04-DevelopmentApproaches.md +10 -4
  96. package/docs/bookofpowerhouse/05-SNOsandANewModelForOSSandPublicGoods.md +23 -30
  97. package/docs/bookofpowerhouse/06-SNOsInActionAndPlatformEconomies.md +0 -7
  98. package/docusaurus.config.ts +64 -66
  99. package/package.json +9 -7
  100. package/scripts/generate-combined-cli-docs.ts +43 -13
  101. package/sidebars.ts +2 -0
  102. package/src/components/HomepageFeatures/index.tsx +171 -78
  103. package/src/components/HomepageFeatures/styles.module.css +1 -2
  104. package/src/css/custom.css +89 -89
  105. package/src/pages/_archive-homepage.tsx +17 -16
  106. package/src/theme/DocCardList/index.tsx +9 -8
  107. package/static.json +6 -6
  108. package/tsconfig.tsbuildinfo +1 -0
@@ -6,6 +6,7 @@ Let's start with the basics and gradually add more complex features and function
6
6
  ## What is a subgraph?
7
7
 
8
8
  A subgraph in Powerhouse is a **GraphQL-based modular data component** that extends the functionality of your document models. While document models handle the core state and operations, subgraphs can:
9
+
9
10
  1. Connect to external APIs or databases
10
11
  2. Add custom queries and mutations
11
12
  3. Automate interactions between different document models
@@ -13,8 +14,8 @@ A subgraph in Powerhouse is a **GraphQL-based modular data component** that exte
13
14
 
14
15
  ### Subgraphs can retrieve data from
15
16
 
16
- - **The Reactor** – The core Powerhouse data system or network node.
17
- - **Relational Data Stores** – Structured data storage for operational processes, offering real-time updates, for querying structured data.
17
+ - **The Reactor** – The core Powerhouse data system or network node.
18
+ - **Relational Data Stores** – Structured data storage for operational processes, offering real-time updates, for querying structured data.
18
19
  - **Analytics Stores** – Aggregated historical data, useful for insights, reporting and business intelligence.
19
20
 
20
21
  ### Subgraphs consist of
@@ -24,418 +25,146 @@ A subgraph in Powerhouse is a **GraphQL-based modular data component** that exte
24
25
  - **Context Fields** — Additional metadata that helps in resolving data efficiently.
25
26
 
26
27
  #### Additionally, context fields allow resolvers to access extra information, such as:
28
+
27
29
  - **User authentication** (e.g., checking if a user is an admin).
28
30
  - **External data sources** (e.g., analytics).
29
31
 
32
+ ## Example: Implement a search subgraph based on data from the reactor
30
33
 
34
+ In this example we implement a subgraph which allows to search through todo-list documents in a specific document drive.
31
35
 
32
- ```typescript title="Example of a context field"
33
- context: {
34
- admin: async (session) => {
35
- const admins = await operationalStore.get("admins");
36
- return admins.includes(session.user);
37
- }
38
- }
39
- ```
36
+ First we will generate the subgraph with the help of the ph cli, then we will define the GraphQL schema and implement the resolvers and finally we will start the reactor and execute a query through the GraphQL Gateway.
40
37
 
41
- ## 1. How to generate a subgraph
38
+ ### 1. Generate the subgraph
42
39
 
43
- Let's start by generating a new subgraph. For our tutorial we will create a new subgraph within our To-do List project.
40
+ Let's start by generating a new subgraph. For our tutorial we will create a new subgraph within our To-do List project.
44
41
  Open your project and start your terminal.
45
- The Powerhouse toolkit provides a command-line utility to create new subgraphs easily.
42
+ The Powerhouse toolkit provides a command-line utility to create new subgraphs easily.
46
43
 
47
44
  ```bash title="Run the following command to generate a new subgraph"
48
- ph generate --subgraph to-do-list
45
+ ph generate --subgraph search-todos
49
46
  ```
50
47
 
51
48
  ```bash title="Expected Output"
52
- Loaded templates: node_modules/@powerhousedao/codegen/dist/codegen/.hygen/templates
53
- FORCED: ./subgraphs/to-do-list/index.ts
49
+ Loaded templates: /projects/powerhouse/powerhouse/packages/codegen/dist/src/codegen/.hygen/templates
50
+ FORCED: ./subgraphs/search-todos/index.ts
54
51
  skipped: ./subgraphs/index.ts
55
52
  inject: ./subgraphs/index.ts
53
+
54
+ Loaded templates: /projects/powerhouse/powerhouse/packages/codegen/dist/src/codegen/.hygen/templates
55
+ FORCED: ./subgraphs/search-todos/resolvers.ts
56
+ FORCED: ./subgraphs/search-todos/schema.ts
56
57
  ```
57
58
 
58
59
  ### What happened?
59
- 1. A new subgraph was created in `./subgraphs/to-do-list/`
60
+
61
+ 1. A new subgraph was created in `./subgraphs/search-todos/`
60
62
  2. The subgraph was automatically registered in your project's registry
61
63
  3. Basic boilerplate code was generated with an example query
62
64
 
63
65
  If we now run `ph reactor` we will see the new subgraph being registered during the startup of the Reactor.
64
- > Registered /todolist subgraph.
65
66
 
66
- Alternatively, when you are running a local reactor with `ph reactor`, a series of subgraphs will automatically get registered, among those, one for the available document models in your Powerhouse project.
67
+ > Registered /graphql/search-todos subgraph.
67
68
 
68
69
  ```
69
70
  Initializing Subgraph Manager...
70
- > Registered /graphql/auth subgraph.
71
+ > Registered /graphql/auth subgraph.
71
72
  > Registered /graphql/system subgraph.
72
73
  > Registered /graphql/analytics subgraph.
73
74
  > Registered /d/:drive subgraph.
74
75
  > Updating router
75
- > Registered /graphql supergraph
76
- > Registered /graphql/to-do-list subgraph.
76
+ > Registered /graphql supergraph
77
+ > Registered /graphql/search-todos subgraph.
77
78
  > Updating router
78
- > Registered /graphql supergraph
79
+ > Registered /graphql supergraph
79
80
  ➜ Reactor: http://localhost:4001/d/powerhouse
80
81
  ```
81
82
 
82
- ## 2. Building a to-do list subgraph
83
-
84
- Now that we've generated our subgraph, let's build a complete To-do List subgraph that extends the functionality of our To-do List document model. This subgraph will provide additional querying capabilities and demonstrate how subgraphs work with document models.
85
-
86
- ### 2.1 Understanding the to-do list document model
83
+ ## 2. Building a search subgraph
87
84
 
88
- Before building our subgraph, let's recall the structure of our To-do List document model from the [DocumentModelCreation tutorial](/academy/MasteryTrack/DocumentModelCreation/SpecifyTheStateSchema):
89
-
90
- ```graphql
91
- type ToDoListState {
92
- items: [ToDoItem!]!
93
- stats: ToDoListStats!
94
- }
95
-
96
- type ToDoItem {
97
- id: ID!
98
- text: String!
99
- checked: Boolean!
100
- }
101
-
102
- type ToDoListStats {
103
- total: Int!
104
- checked: Int!
105
- unchecked: Int
106
- }
107
- ```
85
+ Now that we've generated our subgraph its tome to define the GraphQL schema and implement the resolvers.
108
86
 
109
- The document model has these operations:
110
- - `ADD_TODO_ITEM`: Adds a new to-do item
111
- - `UPDATE_TODO_ITEM`: Updates an existing to-do item
112
- - `DELETE_TODO_ITEM`: Deletes a to-do item
113
-
114
- ### 2.2 Define the subgraph schema
115
-
116
- Now let's create a subgraph that provides enhanced querying capabilities for our To-do List documents.
117
-
118
- **Step 1: Define the schema in `subgraphs/to-do-list/schema.ts` by creating the file:**
87
+ **Step 1: Define the schema in `subgraphs/search-todos/schema.ts` by creating the file:**
119
88
 
120
89
  ```typescript
121
- export const typeDefs = `
122
- type Query {
123
- # Dashboard-style summary query - returns high-level metrics
124
- # Similar to ToDoListStats from document model but optimized for quick queries
125
- todoList: TodoListSummary
126
-
127
- # Filtered list query - lets you get items by completion status
128
- # More flexible than the basic document model - can filter checked/unchecked
129
- todoItems(checked: Boolean): [TodoItem!]!
130
-
131
- # Count-only query - when you just need numbers, not full data
132
- # Faster than getting full list when you only need totals for dashboards
133
- todoItemsCount(checked: Boolean): Int!
134
- }
135
-
136
- # This mirrors ToDoListStats from the document model
137
- # But it's a "view" optimized for summary reports and dashboards
138
- type TodoListSummary {
139
- total: Int! # Total number of items
140
- checked: Int! # Number of completed items
141
- unchecked: Int! # Number of pending items
142
- }
90
+ import { gql } from "graphql-tag";
91
+ import type { DocumentNode } from "graphql";
143
92
 
144
- # This matches the ToDoItem from the document model
145
- # Same data structure, but accessed through subgraph queries for filtering
146
- type TodoItem {
147
- id: ID! # Unique identifier
148
- text: String! # The task description
149
- checked: Boolean! # Completion status
93
+ export const schema: DocumentNode = gql`
94
+ """
95
+ Subgraph definition
96
+ """
97
+ type Query {
98
+ searchTodos(driveId: String!, searchTerm: String!): [String!]!
150
99
  }
151
- }`
100
+ `;
152
101
  ```
153
102
 
154
-
155
- <details>
156
- <summary> #### Understanding resolvers </summary>
157
-
158
- Before diving into the technical implementation, let's understand why these three different query types matter for your product.
159
- Think of resolvers as custom API endpoints that are automatically created based on what your users actually need to know about your data.
160
-
161
- When someone asks your system a question through GraphQL, the resolver:
162
-
163
- 1. **Understands the request** - "The user wants unchecked items"
164
- 2. **Knows where to get the data** - "I need to check the todo_items database table"
165
- 3. **Applies the right filters** - "Only get items where checked = false"
166
- 4. **Returns the answer** - "Here are the 5 unchecked items"
167
-
168
- **The three resolvers serve different business needs:**
169
-
170
- - **`todoList` Resolver - The Dashboard**
171
- - **Business value**: Perfect for executive dashboards or KPI displays
172
- - **Use case**: "We have 150 total tasks, 89 completed, 61 pending"
173
- - **Users**: Executives, managers, anyone needing high-level metrics
174
-
175
- - **`todoItems` Resolver - The Detailed List**
176
- - **Business value**: Great for operational views where people need to see actual tasks
177
- - **Use case**: "Show me all pending tasks" or "Show me everything"
178
- - **Users**: Workers, operators, anyone who needs to act on specific items
179
-
180
- - **`todoItemsCount` Resolver - The Counter**
181
- - **Business value**: Super fast for analytics or when you only need numbers
182
- - **Use case**: "How many completed tasks do we have?" → "47"
183
- - **Users**: Analysts, automated systems, performance dashboards
184
-
185
- **Why this architecture matters:**
186
- - **Performance**: Count queries are much faster than getting full lists when you only need numbers
187
- - **User Experience**: Different resolvers serve different user needs efficiently
188
- - **Flexibility**: Users can ask for exactly what they need, nothing more, nothing less
189
-
190
- </details>
191
-
192
- **Step 2: Create resolvers in `subgraphs/to-do-list/resolvers.ts`:**
103
+ **Step 2: Create resolvers in `subgraphs/search-todos/resolvers.ts`:**
193
104
 
194
105
  ```typescript
195
- // subgraphs/to-do-list/resolvers.ts
196
- interface SubgraphInstance {
197
- operationalStore: any;
198
- }
199
-
200
- export const createResolvers = (subgraphInstance: SubgraphInstance) => ({
201
- Query: {
202
- todoList: async () => {
203
- const items = await subgraphInstance.operationalStore.getAll("todo_items");
204
- const total = items.length;
205
- const checked = items.filter((item: any) => item.checked).length;
206
- const unchecked = total - checked;
207
-
208
- return {
209
- total,
210
- checked,
211
- unchecked
212
- };
213
- },
214
-
215
- todoItems: async (parent: any, { checked }: any) => {
216
- let query = subgraphInstance.operationalStore.select("*").from("todo_items");
217
-
218
- if (checked !== undefined) {
219
- query = query.where("checked", checked);
220
- }
221
-
222
- const items = await query.orderBy("created_at", "asc");
223
- return items;
106
+ // subgraphs/search-todos/resolvers.ts
107
+ import { type Subgraph } from "@powerhousedao/reactor-api";
108
+ import { type ToDoListDocument } from "document-models/to-do-list/index.js";
109
+
110
+ export const getResolvers = (subgraph: Subgraph) => {
111
+ const reactor = subgraph.reactor;
112
+
113
+ return {
114
+ Query: {
115
+ searchTodos: async (
116
+ parent: unknown,
117
+ args: { driveId: string; searchTerm: string },
118
+ ) => {
119
+ const documents = await reactor.getDocuments(args.driveId);
120
+ const todoItems: string[] = [];
121
+ for (const docId of documents) {
122
+ const doc: ToDoListDocument = await reactor.getDocument(docId);
123
+ if (doc.header.documentType !== "powerhouse/todolist") {
124
+ continue;
125
+ }
126
+
127
+ const amountEntries = doc.state.global.items.filter((e) =>
128
+ e.text.includes(args.searchTerm),
129
+ ).length;
130
+ if (amountEntries > 0) {
131
+ todoItems.push(docId);
132
+ }
133
+ }
134
+ return todoItems;
135
+ },
224
136
  },
225
-
226
- todoItemsCount: async (parent: any, { checked }: any) => {
227
- let query = subgraphInstance.operationalStore.count("* as count").from("todo_items");
228
-
229
- if (checked !== undefined) {
230
- query = query.where("checked", checked);
231
- }
232
-
233
- const result = await query.first();
234
- return result?.count || 0;
235
- }
236
- }
237
- });
238
- ```
239
-
240
- **Step 3: Implement the main class in `subgraphs/to-do-list/index.ts`:**
241
-
242
- ```typescript
243
- // subgraphs/to-do-list/index.ts
244
- import { typeDefs } from './schema.js';
245
- import { createResolvers } from './resolvers.js';
246
-
247
- export default class ToDoListSubgraph {
248
- // Define the API endpoint where this subgraph will be accessible
249
- // Users can query this at: http://localhost:4001/graphql/to-do-list
250
- path = '/to-do-list';
251
-
252
- // GraphQL schema definition (what queries are available)
253
- typeDefs = typeDefs;
254
-
255
- // Query handlers (how to fetch the data)
256
- resolvers: any;
257
-
258
- // Database interface (injected by Powerhouse framework)
259
- operationalStore: any;
260
-
261
- constructor() {
262
- // Connect the resolvers to this subgraph instance
263
- // This gives resolvers access to the database through this.operationalStore
264
- this.resolvers = createResolvers(this);
265
- }
266
-
267
- // Called once when the subgraph starts up
268
- async onSetup() {
269
- await this.createOperationalTables();
270
- }
271
-
272
- // Create the database tables we need for storing todo items
273
- async createOperationalTables() {
274
- await this.operationalStore.schema.createTableIfNotExists(
275
- "todo_items", // Table name
276
- (table: any) => {
277
- table.string("id").primary(); // Unique identifier for each todo item
278
- table.string("text").notNullable(); // The actual todo task text
279
- table.boolean("checked").defaultTo(false); // Completion status (unchecked by default)
280
- table.timestamp("created_at").defaultTo(this.operationalStore.fn.now()); // When item was created
281
- table.timestamp("updated_at").defaultTo(this.operationalStore.fn.now()); // When item was last modified
282
- }
283
- );
284
- }
285
-
286
- // Event processor: Keeps subgraph data synchronized with document model changes
287
- // When users add/update/delete todos in Connect, this method handles the updates
288
- async process(event: any) {
289
- // Handle new todo item creation
290
- if (event.type === "ADD_TODO_ITEM") {
291
- await this.operationalStore.insert("todo_items", {
292
- id: event.input.id,
293
- text: event.input.text,
294
- checked: false,
295
- created_at: new Date(),
296
- updated_at: new Date()
297
- });
298
-
299
- console.log(`Added todo item: ${event.input.text}`);
300
- }
301
-
302
- // Handle todo item updates (text changes, checking/unchecking)
303
- if (event.type === "UPDATE_TODO_ITEM") {
304
- const updateData: any = {
305
- updated_at: new Date() // Always update the timestamp
306
- };
307
-
308
- // Only update fields that were actually changed
309
- if (event.input.text !== undefined) {
310
- updateData.text = event.input.text;
311
- }
312
- if (event.input.checked !== undefined) {
313
- updateData.checked = event.input.checked;
314
- }
315
-
316
- await this.operationalStore.update("todo_items")
317
- .where("id", event.input.id)
318
- .update(updateData);
319
-
320
- console.log(`Updated todo item: ${event.input.id}`);
321
- }
322
-
323
- // Handle todo item deletion
324
- if (event.type === "DELETE_TODO_ITEM") {
325
- await this.operationalStore.delete("todo_items")
326
- .where("id", event.input.id);
327
-
328
- console.log(`Deleted todo item: ${event.input.id}`);
329
- }
330
- }
331
- }
332
- ```
333
-
334
- ### 2.3 Understanding the implementation
335
-
336
- **What this multi-file approach provides:**
337
-
338
- 1. **Schema separation** (`schema.ts`): Clean GraphQL type definitions
339
- 2. **Resolver isolation** (`resolvers.ts`): Business logic separated from structure
340
- 3. **Main orchestration** (`index.ts`): Combines everything and handles lifecycle methods
341
-
342
- **Key features implemented:**
343
- - A `todo_items` operational table to store individual to-do items
344
- - Fields that match our document model structure
345
- - Timestamps for tracking when items were created and updated
346
- - Resolvers that fetch and filter todo items from the operational store
347
- - Event processing to keep the subgraph data synchronized with document model changes
348
-
349
- ### 2.4 Understanding the document model event integration
350
-
351
- Notice that our `index.ts` file already includes a `process` method - this is the **processor integration** that keeps our subgraph synchronized with To-do List document model events. When users interact with To-do List documents through Connect, this method automatically handles the updates.
352
-
353
- **How the existing processor integration works:**
354
-
355
- The `process` method in our `index.ts` file handles three types of document model events:
356
-
357
- **1. Adding new todo items:**
358
- ```typescript
359
- if (event.type === "ADD_TODO_ITEM") {
360
- await this.operationalStore.insert("todo_items", {
361
- id: event.input.id,
362
- text: event.input.text,
363
- checked: false,
364
- created_at: new Date(),
365
- updated_at: new Date()
366
- });
367
- }
137
+ };
138
+ };
368
139
  ```
369
140
 
370
- **2. Updating existing items:**
371
- ```typescript
372
- if (event.type === "UPDATE_TODO_ITEM") {
373
- // Only update fields that were actually changed
374
- const updateData = { updated_at: new Date() };
375
- if (event.input.text !== undefined) updateData.text = event.input.text;
376
- if (event.input.checked !== undefined) updateData.checked = event.input.checked;
377
-
378
- await this.operationalStore.update("todo_items")
379
- .where("id", event.input.id)
380
- .update(updateData);
381
- }
382
- ```
383
-
384
- **3. Deleting items:**
385
- ```typescript
386
- if (event.type === "DELETE_TODO_ITEM") {
387
- await this.operationalStore.delete("todo_items")
388
- .where("id", event.input.id);
389
- }
390
- ```
391
-
392
- **The integration happens automatically:**
393
- 1. **User action**: Someone adds a todo item in Connect
394
- 2. **Document model**: Processes the `ADD_TODO_ITEM` operation
395
- 3. **Framework routing**: Powerhouse automatically calls your subgraph's `process` method
396
- 4. **Subgraph response**: Your `process` method updates the operational store
397
- 5. **Query availability**: Users can now query the updated data via GraphQL
398
-
399
- ### 2.5 Summary of what we've built
400
-
401
- Our complete To-do List subgraph includes:
402
-
403
- - **GraphQL schema** (`schema.ts`): Defines `todoList`, `todoItems`, and `todoItemsCount` queries
404
- - **Resolvers** (`resolvers.ts`): Handle data fetching and filtering from the operational store
405
- - **Main subgraph class** (`index.ts`): Coordinates everything and includes:
406
- - **Operational table creation**: Sets up the `todo_items` table with proper schema
407
- - **Event processing**: The `process` method keeps subgraph data synchronized with document model changes
408
- - **Real-time updates**: Automatically handles `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, and `DELETE_TODO_ITEM` events
409
-
410
- **Key features:**
411
- - **Filtering capability**: The `todoItems` query accepts an optional `checked` parameter
412
- - **Performance optimization**: The `todoItemsCount` query returns just numbers when you don't need full data
413
- - **Real-time synchronization**: Changes in Connect immediately appear in subgraph queries
414
- - **Complete statistics**: The `todoList` query returns total, checked, and unchecked counts
415
-
416
141
  ## 3. Testing the to-do list subgraph
417
142
 
418
143
  ### 3.1. Start the reactor
144
+
419
145
  To activate the subgraph, run:
420
146
 
421
147
  ```bash
422
148
  ph reactor
423
149
  ```
424
- Or, for full system startup:
425
-
426
- ```bash title="Start the Reactor & Connect in Studio or Locally"
427
- ph dev
428
- ```
429
150
 
430
151
  You should see the subgraph being registered in the console output:
152
+
431
153
  ```
432
- > Registered /graphql/to-do-list subgraph.
154
+ > Registered /graphql/search-todos subgraph.
433
155
  ```
434
156
 
435
157
  ### 3.2. Create some test data
158
+
436
159
  Before testing queries, let's create some To-do List documents with test data:
437
160
 
438
- 1. Open Connect at `http://localhost:3001` in another terminal
161
+ 1. Start Connect
162
+
163
+ ```bash
164
+ ph connect
165
+ ```
166
+
167
+ 1. Open Connect at `http://localhost:3000` in the browser
439
168
  2. Add the 'remote' drive that is running locally via the (+) 'Add Drive' button. Add 'http://localhost:4001/d/powerhouse'
440
169
  3. Create a new To-do List document
441
170
  4. Add some test items:
@@ -444,95 +173,26 @@ Before testing queries, let's create some To-do List documents with test data:
444
173
  - "Test the subgraph" (leave unchecked)
445
174
 
446
175
  ### 3.3. Access GraphQL playground
176
+
447
177
  Open your browser and go to:
448
178
 
449
179
  ```bash
450
- http://localhost:4001/graphql/to-do-list
180
+ http://localhost:4001/graphql
451
181
  ```
452
182
 
453
183
  ### 3.4. Test the queries
454
184
 
455
- **Query 1: Get To-do List statistics**
456
- ```graphql
457
- query {
458
- todoList {
459
- total
460
- checked
461
- unchecked
462
- }
463
- }
464
- ```
465
-
466
- **Query 2: Get all to-do items**
467
- ```graphql
468
- query {
469
- todoItems {
470
- id
471
- text
472
- checked
473
- }
474
- }
475
- ```
476
-
477
- **Query 3: Get only unchecked items**
478
- ```graphql
479
- query {
480
- todoItems(checked: false) {
481
- id
482
- text
483
- checked
484
- }
485
- }
486
- ```
185
+ **Query 1: Search for Todos **
487
186
 
488
- **Query 4: Get count of completed items**
489
187
  ```graphql
490
188
  query {
491
- todoItemsCount(checked: true)
189
+ searchTodos(driveId: "powerhouse", searchTerm: "Test")
492
190
  }
493
191
  ```
494
192
 
495
- ### 3.5. Expected responses
496
-
497
- **For the statistics query:**
498
- ```json
499
- {
500
- "data": {
501
- "todoList": {
502
- "total": 3,
503
- "checked": 1,
504
- "unchecked": 2
505
- }
506
- }
507
- }
508
- ```
509
-
510
- **For the items query:**
511
- ```json
512
- {
513
- "data": {
514
- "todoItems": [
515
- {
516
- "id": "item-1",
517
- "text": "Learn about subgraphs",
518
- "checked": false
519
- },
520
- {
521
- "id": "item-2",
522
- "text": "Build a To-do List subgraph",
523
- "checked": true
524
- },
525
- {
526
- "id": "item-3",
527
- "text": "Test the subgraph",
528
- "checked": false
529
- }
530
- ]
531
- }
532
- }
533
- ```
193
+ You should get a list of the document Ids which contain the search term "Test".
534
194
 
535
- ### 3.6. Test real-time updates
195
+ ### 3.5. Test real-time updates
536
196
 
537
197
  To verify that your subgraph stays synchronized with document changes:
538
198
 
@@ -544,27 +204,26 @@ To verify that your subgraph stays synchronized with document changes:
544
204
 
545
205
  This demonstrates the real-time synchronization between the document model and the subgraph through event processing.
546
206
 
547
- ## 4. Working with the supergraph or gateway
207
+ ## 4. Working with the GraphQL Gateway
548
208
 
549
- A supergraph is a GraphQL schema that combines multiple underlying GraphQL APIs, known as subgraphs, into a single, unified graph. This architecture allows different teams to work independently on their respective services (subgraphs) while providing a single entry point for clients or users to query all available data.
209
+ The GraphQL Gateway is a GraphQL schema that combines multiple underlying GraphQL APIs, known as subgraphs, into a single, unified graph. This architecture allows different teams to work independently on their respective services (subgraphs) while providing a single entry point for clients or users to query all available data.
550
210
 
551
211
  ### 4.1 Key concepts
552
212
 
553
- * **Subgraph:** An independent GraphQL service with its own schema. Each subgraph typically represents a specific domain or microservice within a larger system.
554
- * **Gateway/Router:** A server that sits in front of the subgraphs. It receives client queries, consults the supergraph schema, and routes parts of the query to the relevant subgraphs. It then stitches the results back together before sending the final response to the client.
213
+ - **Subgraph:** An independent GraphQL service with its own schema. Each subgraph typically represents a specific domain or microservice within a larger system.
214
+ - **Gateway/Router:** A server that sits in front of the subgraphs. It receives client queries, consults the supergraph schema, and routes parts of the query to the relevant subgraphs. It then stitches the results back together before sending the final response to the client.
555
215
 
556
216
  ### 4.2 Benefits of using a supergraph
557
217
 
558
- * **Federated Architecture:** Enables a microservices-based approach where different teams can own and operate their services independently.
559
- * **Scalability:** Individual subgraphs can be scaled independently based on their specific needs.
560
- * **Improved Developer Experience:** Clients interact with a single, consistent GraphQL API, simplifying data fetching and reducing the need to manage multiple endpoints.
561
- * **Schema Evolution:** Subgraphs can evolve their schemas independently, and the supergraph can be updated without breaking existing clients, as long as breaking changes are managed carefully.
562
- * **Clear Separation of Concerns:** Each subgraph focuses on a specific domain, leading to more maintainable and understandable codebases.
563
-
218
+ - **Federated Architecture:** Enables a microservices-based approach where different teams can own and operate their services independently.
219
+ - **Scalability:** Individual subgraphs can be scaled independently based on their specific needs.
220
+ - **Improved Developer Experience:** Clients interact with a single, consistent GraphQL API, simplifying data fetching and reducing the need to manage multiple endpoints.
221
+ - **Schema Evolution:** Subgraphs can evolve their schemas independently, and the supergraph can be updated without breaking existing clients, as long as breaking changes are managed carefully.
222
+ - **Clear Separation of Concerns:** Each subgraph focuses on a specific domain, leading to more maintainable and understandable codebases.
564
223
 
565
224
  ### 4.3 Use the Powerhouse supergraph
566
225
 
567
- The Powerhouse supergraph for any given remote drive or reactor can be found under `http://localhost:4001/graphql`. The gateway / supergraph available on `/graphql` combines all the subgraphs, except for the drive subgraph (which is accessible via `/d/:driveId`). To access the endpoint, start the reactor and navigate to the URL with `graphql` appended. The following commands explain how you can test & try the supergraph.
226
+ The Powerhouse supergraph for any given remote drive or reactor can be found under `http://localhost:4001/graphql`. The gateway / supergraph available on `/graphql` combines all the subgraphs, except for the drive subgraph (which is accessible via `/d/:driveId`). To access the endpoint, start the reactor and navigate to the URL with `graphql` appended. The following commands explain how you can test & try the supergraph.
568
227
 
569
228
  - Start the reactor:
570
229
 
@@ -578,18 +237,16 @@ The Powerhouse supergraph for any given remote drive or reactor can be found und
578
237
  http://localhost:4001/graphql
579
238
  ```
580
239
 
581
- The supergraph allows you to both query & mutate data from the same endpoint.
240
+ The supergraph allows you to both query & mutate data from the same endpoint.
582
241
 
583
242
  **Example: Using the supergraph with To-do List documents**
584
243
 
585
244
  1. Create a todo document in the `powerhouse` drive using the `ToDoList_createDocument` mutation:
245
+
586
246
  ```graphql
587
247
  mutation {
588
248
  ToDoList_createDocument(
589
- input: {
590
- documentId: "my-todo-list"
591
- name: "My Test To-do List"
592
- }
249
+ input: { documentId: "my-todo-list", name: "My Test To-do List" }
593
250
  ) {
594
251
  id
595
252
  name
@@ -598,19 +255,18 @@ The supergraph allows you to both query & mutate data from the same endpoint.
598
255
  ```
599
256
 
600
257
  2. Add some items to your to-do list using the `ToDoList_addTodoItem` mutation:
258
+
601
259
  ```graphql
602
260
  mutation {
603
261
  ToDoList_addTodoItem(
604
262
  docId: "my-todo-list"
605
- input: {
606
- id: "item-1"
607
- text: "Learn about supergraphs"
608
- }
263
+ input: { id: "item-1", text: "Learn about supergraphs" }
609
264
  )
610
265
  }
611
266
  ```
612
267
 
613
268
  3. Query the document state using the `GetDocument` query:
269
+
614
270
  ```graphql
615
271
  query {
616
272
  ToDoList {
@@ -650,13 +306,14 @@ The supergraph allows you to both query & mutate data from the same endpoint.
650
306
  }
651
307
  ```
652
308
 
653
- This demonstrates how the supergraph provides a unified interface to both your document models and your custom subgraphs, allowing you to query and mutate data from the same endpoint.
309
+ This demonstrates how the supergraph provides a unified interface to both your document models and your custom subgraphs, allowing you to query and mutate data from the same endpoint.
654
310
 
655
311
  ## 5. Summary
656
312
 
657
313
  Congratulations! You've successfully built a complete To-do List subgraph that demonstrates the power of extending document models with custom GraphQL functionality. Let's recap what you've accomplished:
658
314
 
659
315
  ### Key concepts learned:
316
+
660
317
  - **Subgraphs extend document models** with additional querying and data processing capabilities
661
318
  - **Operational data stores** provide efficient storage for subgraph data
662
319
  - **Event processing** enables real-time synchronization between document models and subgraphs
@@ -670,7 +327,7 @@ This tutorial has provided you with a solid foundation for building sophisticate
670
327
  - When an invoice-related task is marked complete, update the invoice status
671
328
  - When an invoice is paid, automatically check off related tasks
672
329
 
673
- 2. **External Integrations**:
330
+ 2. **External Integrations**:
674
331
  - Sync tasks with external project management tools
675
332
  - Connect with notification systems
676
333
  - Integrate with analytics platforms
@@ -680,14 +337,6 @@ This tutorial has provided you with a solid foundation for building sophisticate
680
337
  - Add automated task assignments
681
338
  - Create custom reporting functionality
682
339
 
683
-
684
340
  ### Future enhancements
685
341
 
686
342
  Bridge Processors and Subgraphs — Currently, there's a gap in how processors and subgraphs interact. Powerhouse might improve this in future updates.
687
-
688
-
689
-
690
-
691
-
692
-
693
-