@powerhousedao/academy 3.3.0-dev.14 → 3.3.0-dev.15

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 (19) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/docs/academy/02-MasteryTrack/04-WorkWithData/03-UsingSubgraphs.md +145 -86
  3. package/docs/academy/02-MasteryTrack/04-WorkWithData/07-OperationalDbProcessorTutorial/_category_.json +8 -0
  4. package/docs/academy/04-APIReferences/01-ReactHooks.md +36 -0
  5. package/docs/academy/04-APIReferences/04-RelationalDatabase.md +46 -52
  6. package/docs/academy/04-APIReferences/05-PHDocumentMigrationGuide.md +8 -9
  7. package/package.json +1 -1
  8. package/docs/academy/02-MasteryTrack/04-WorkWithData/05-AnalyticsProcessorTutorial/05-AnalyticsTutorial +0 -4
  9. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial/01-SetupBuilderEnvironment.md → _05-AnalyticsProcessorTutorial/_01-SetupBuilderEnvironment.md} +0 -0
  10. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial/02-CreateNewPowerhouseProject.md → _05-AnalyticsProcessorTutorial/_02-CreateNewPowerhouseProject.md} +0 -0
  11. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial/03-GenerateAnAnalyticsProcessor.md → _05-AnalyticsProcessorTutorial/_03-GenerateAnAnalyticsProcessor.md} +0 -0
  12. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial/04-UpdateAnalyticsProcessor.md → _05-AnalyticsProcessorTutorial/_04-UpdateAnalyticsProcessor.md} +0 -0
  13. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/_category_.json +0 -0
  14. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/images/Create-SPV.gif +0 -0
  15. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/images/Create-a-new-asset.png +0 -0
  16. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/images/Create-a-transaction.gif +0 -0
  17. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/images/Transaction-table.png +0 -0
  18. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/images/create-a-new-RWA-document.gif +0 -0
  19. /package/docs/academy/02-MasteryTrack/04-WorkWithData/{05-AnalyticsProcessorTutorial → _05-AnalyticsProcessorTutorial}/images/granularity.png +0 -0
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 3.3.0-dev.15 (2025-07-17)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **codegen:** updated subgraph template to deal with undefined return on getDocument ([7b2862a91](https://github.com/powerhouse-inc/powerhouse/commit/7b2862a91))
6
+ - **academy:** update broken links ([cbbfe9b30](https://github.com/powerhouse-inc/powerhouse/commit/cbbfe9b30))
7
+
8
+ ### ❤️ Thank You
9
+
10
+ - acaldas
11
+ - Callme-T
12
+
1
13
  ## 3.3.0-dev.14 (2025-07-17)
2
14
 
3
15
  This was a version bump only for @powerhousedao/academy to align it with other projects, there were no code changes.
@@ -19,9 +19,9 @@ A subgraph in Powerhouse is a **GraphQL-based modular data component** that exte
19
19
 
20
20
  ### Subgraphs consist of
21
21
 
22
- - **A schema** Which defines the GraphQL Queries and Mutations.
23
- - **Resolvers** Which handle data fetching and logic.
24
- - **Context Fields** Additional metadata that helps in resolving data efficiently.
22
+ - **A schema** Which defines the GraphQL Queries and Mutations.
23
+ - **Resolvers** Which handle data fetching and logic.
24
+ - **Context Fields** Additional metadata that helps in resolving data efficiently.
25
25
 
26
26
  #### Additionally, context fields allow resolvers to access extra information, such as:
27
27
  - **User authentication** (e.g., checking if a user is an admin).
@@ -40,30 +40,30 @@ context: {
40
40
 
41
41
  ## 1. How to generate a subgraph
42
42
 
43
- Lets start by generating a new subgraph. For our tutorial we will create a new subgraph within our To-do List project.
43
+ Let's start by generating a new subgraph. For our tutorial we will create a new subgraph within our To-do List project.
44
44
  Open your project and start your terminal.
45
45
  The Powerhouse toolkit provides a command-line utility to create new subgraphs easily.
46
46
 
47
47
  ```bash title="Run the following command to generate a new subgraph"
48
- ph generate --subgraph <to-do-list-subgraph>
48
+ ph generate --subgraph to-do-list
49
49
  ```
50
50
 
51
51
  ```bash title="Expected Output"
52
52
  Loaded templates: node_modules/@powerhousedao/codegen/dist/codegen/.hygen/templates
53
- FORCED: ./subgraphs/to-do-list-subgraph/index.ts
53
+ FORCED: ./subgraphs/to-do-list/index.ts
54
54
  skipped: ./subgraphs/index.ts
55
55
  inject: ./subgraphs/index.ts
56
56
  ```
57
57
 
58
58
  ### What happened?
59
- 1. A new subgraph was created in `./subgraphs/to-do-list-subgraph/`
59
+ 1. A new subgraph was created in `./subgraphs/to-do-list/`
60
60
  2. The subgraph was automatically registered in your project's registry
61
61
  3. Basic boilerplate code was generated with an example query
62
62
 
63
63
  If we now run `ph reactor` we will see the new subgraph being registered during the startup of the Reactor.
64
64
  > Registered /todolist subgraph.
65
65
 
66
- Alternatively, when you are running a local reactor with `ph reactor` a series of subgraphs will automatically get registered, amongst those one for the available document models in your Powerhouse project.
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
67
 
68
68
  ```
69
69
  Initializing Subgraph Manager...
@@ -120,30 +120,77 @@ Now let's create a subgraph that provides enhanced querying capabilities for our
120
120
  ```typescript
121
121
  export const typeDefs = `
122
122
  type Query {
123
+ # Dashboard-style summary query - returns high-level metrics
124
+ # Similar to ToDoListStats from document model but optimized for quick queries
123
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
124
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
125
133
  todoItemsCount(checked: Boolean): Int!
126
134
  }
127
135
 
136
+ # This mirrors ToDoListStats from the document model
137
+ # But it's a "view" optimized for summary reports and dashboards
128
138
  type TodoListSummary {
129
- total: Int!
130
- checked: Int!
131
- unchecked: Int!
139
+ total: Int! # Total number of items
140
+ checked: Int! # Number of completed items
141
+ unchecked: Int! # Number of pending items
132
142
  }
133
143
 
144
+ # This matches the ToDoItem from the document model
145
+ # Same data structure, but accessed through subgraph queries for filtering
134
146
  type TodoItem {
135
- id: ID!
136
- text: String!
137
- checked: Boolean!
147
+ id: ID! # Unique identifier
148
+ text: String! # The task description
149
+ checked: Boolean! # Completion status
138
150
  }
139
151
  `;
140
152
  ```
141
153
 
154
+
155
+
156
+ #### Understanding Resolvers
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 customer 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
+
142
190
  **Step 2: Create resolvers in `subgraphs/to-do-list/resolvers.ts`:**
143
191
 
144
192
  ```typescript
145
193
  // subgraphs/to-do-list/resolvers.ts
146
- // subgraphs/to-do-list/resolvers.ts
147
194
  interface SubgraphInstance {
148
195
  operationalStore: any;
149
196
  }
@@ -196,35 +243,48 @@ import { typeDefs } from './schema.js';
196
243
  import { createResolvers } from './resolvers.js';
197
244
 
198
245
  export default class ToDoListSubgraph {
246
+ // Define the API endpoint where this subgraph will be accessible
247
+ // Users can query this at: http://localhost:4001/graphql/to-do-list
199
248
  path = '/to-do-list';
200
249
 
250
+ // GraphQL schema definition (what queries are available)
201
251
  typeDefs = typeDefs;
252
+
253
+ // Query handlers (how to fetch the data)
202
254
  resolvers: any;
255
+
256
+ // Database interface (injected by Powerhouse framework)
203
257
  operationalStore: any;
204
258
 
205
259
  constructor() {
260
+ // Connect the resolvers to this subgraph instance
261
+ // This gives resolvers access to the database through this.operationalStore
206
262
  this.resolvers = createResolvers(this);
207
263
  }
208
264
 
265
+ // Called once when the subgraph starts up
209
266
  async onSetup() {
210
267
  await this.createOperationalTables();
211
268
  }
212
269
 
270
+ // Create the database tables we need for storing todo items
213
271
  async createOperationalTables() {
214
272
  await this.operationalStore.schema.createTableIfNotExists(
215
- "todo_items",
273
+ "todo_items", // Table name
216
274
  (table: any) => {
217
- table.string("id").primary();
218
- table.string("text").notNullable();
219
- table.boolean("checked").defaultTo(false);
220
- table.timestamp("created_at").defaultTo(this.operationalStore.fn.now());
221
- table.timestamp("updated_at").defaultTo(this.operationalStore.fn.now());
275
+ table.string("id").primary(); // Unique identifier for each todo item
276
+ table.string("text").notNullable(); // The actual todo task text
277
+ table.boolean("checked").defaultTo(false); // Completion status (unchecked by default)
278
+ table.timestamp("created_at").defaultTo(this.operationalStore.fn.now()); // When item was created
279
+ table.timestamp("updated_at").defaultTo(this.operationalStore.fn.now()); // When item was last modified
222
280
  }
223
281
  );
224
282
  }
225
283
 
284
+ // Event processor: Keeps subgraph data synchronized with document model changes
285
+ // When users add/update/delete todos in Connect, this method handles the updates
226
286
  async process(event: any) {
227
- // Handle To-do List document operations
287
+ // Handle new todo item creation
228
288
  if (event.type === "ADD_TODO_ITEM") {
229
289
  await this.operationalStore.insert("todo_items", {
230
290
  id: event.input.id,
@@ -237,12 +297,13 @@ export default class ToDoListSubgraph {
237
297
  console.log(`Added todo item: ${event.input.text}`);
238
298
  }
239
299
 
300
+ // Handle todo item updates (text changes, checking/unchecking)
240
301
  if (event.type === "UPDATE_TODO_ITEM") {
241
302
  const updateData: any = {
242
- updated_at: new Date()
303
+ updated_at: new Date() // Always update the timestamp
243
304
  };
244
305
 
245
- // Only update fields that were provided
306
+ // Only update fields that were actually changed
246
307
  if (event.input.text !== undefined) {
247
308
  updateData.text = event.input.text;
248
309
  }
@@ -257,6 +318,7 @@ export default class ToDoListSubgraph {
257
318
  console.log(`Updated todo item: ${event.input.id}`);
258
319
  }
259
320
 
321
+ // Handle todo item deletion
260
322
  if (event.type === "DELETE_TODO_ITEM") {
261
323
  await this.operationalStore.delete("todo_items")
262
324
  .where("id", event.input.id);
@@ -267,11 +329,6 @@ export default class ToDoListSubgraph {
267
329
  }
268
330
  ```
269
331
 
270
- **What this schema provides:**
271
- - `todoList`: Returns statistics about all to-do items (total, checked, unchecked counts)
272
- - `todoItems`: Returns a list of to-do items, optionally filtered by checked status
273
- - `todoItemsCount`: Returns just the count of items, optionally filtered by checked status
274
-
275
332
  ### 2.3 Understanding the Implementation
276
333
 
277
334
  **What this multi-file approach provides:**
@@ -287,70 +344,72 @@ export default class ToDoListSubgraph {
287
344
  - Resolvers that fetch and filter todo items from the operational store
288
345
  - Event processing to keep the subgraph data synchronized with document model changes
289
346
 
290
- ### 2.4 Connect to Document Model Events (Processor Integration)
347
+ ### 2.4 Understanding the Document Model Event Integration
291
348
 
292
- To make our subgraph truly useful, we need to connect it to the actual To-do List document model events. This ensures that when users interact with To-do List documents through Connect, the subgraph data stays synchronized.
349
+ 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.
293
350
 
294
- Add this processor integration to your subgraph:
351
+ **How the existing processor integration works:**
295
352
 
353
+ The `process` method in our `index.ts` file handles three types of document model events:
354
+
355
+ **1. Adding new todo items:**
296
356
  ```typescript
297
- async process(event) {
298
- // Handle To-do List document operations
299
- if (event.type === "ADD_TODO_ITEM") {
300
- await this.operationalStore.insert("todo_items", {
301
- id: event.input.id,
302
- text: event.input.text,
303
- checked: false,
304
- created_at: new Date(),
305
- updated_at: new Date()
306
- });
307
-
308
- console.log(`Added todo item: ${event.input.text}`);
309
- }
310
-
311
- if (event.type === "UPDATE_TODO_ITEM") {
312
- const updateData = {
313
- updated_at: new Date()
314
- };
315
-
316
- // Only update fields that were provided
317
- if (event.input.text !== undefined) {
318
- updateData.text = event.input.text;
319
- }
320
- if (event.input.checked !== undefined) {
321
- updateData.checked = event.input.checked;
322
- }
323
-
324
- await this.operationalStore.update("todo_items")
325
- .where("id", event.input.id)
326
- .update(updateData);
327
-
328
- console.log(`Updated todo item: ${event.input.id}`);
329
- }
357
+ if (event.type === "ADD_TODO_ITEM") {
358
+ await this.operationalStore.insert("todo_items", {
359
+ id: event.input.id,
360
+ text: event.input.text,
361
+ checked: false,
362
+ created_at: new Date(),
363
+ updated_at: new Date()
364
+ });
365
+ }
366
+ ```
367
+
368
+ **2. Updating existing items:**
369
+ ```typescript
370
+ if (event.type === "UPDATE_TODO_ITEM") {
371
+ // Only update fields that were actually changed
372
+ const updateData = { updated_at: new Date() };
373
+ if (event.input.text !== undefined) updateData.text = event.input.text;
374
+ if (event.input.checked !== undefined) updateData.checked = event.input.checked;
330
375
 
331
- if (event.type === "DELETE_TODO_ITEM") {
332
- await this.operationalStore.delete("todo_items")
333
- .where("id", event.input.id);
334
-
335
- console.log(`Deleted todo item: ${event.input.id}`);
336
- }
376
+ await this.operationalStore.update("todo_items")
377
+ .where("id", event.input.id)
378
+ .update(updateData);
379
+ }
380
+ ```
381
+
382
+ **3. Deleting items:**
383
+ ```typescript
384
+ if (event.type === "DELETE_TODO_ITEM") {
385
+ await this.operationalStore.delete("todo_items")
386
+ .where("id", event.input.id);
337
387
  }
338
388
  ```
339
389
 
340
- **What this processor does:**
341
- - Listens for document model operations (`ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, `DELETE_TODO_ITEM`)
342
- - Updates the operational store in real-time when these operations occur
343
- - Provides console logging for debugging
344
- - Maintains data consistency between the document model and the subgraph
390
+ **The integration happens automatically:**
391
+ 1. **User action**: Someone adds a todo item in Connect
392
+ 2. **Document model**: Processes the `ADD_TODO_ITEM` operation
393
+ 3. **Framework routing**: Powerhouse automatically calls your subgraph's `process` method
394
+ 4. **Subgraph response**: Your `process` method updates the operational store
395
+ 5. **Query availability**: Users can now query the updated data via GraphQL
345
396
 
346
397
  ### 2.5 Summary of What We've Built
347
398
 
348
- - **Added two main queries**: `todoList` for statistics and `todoItems` for item lists
349
- - **Created an operational table** `todo_items` to store the todo items with proper schema
350
- - **Added resolvers** to fetch and filter todo items from the operational store
351
- - **Implemented event processing** to keep the subgraph data synchronized with document model changes
352
- - **The todoItems query accepts an optional checked parameter** to filter items by their completion status
353
- - **The todoList query returns the full statistics** including total, checked, and unchecked counts
399
+ Our complete To-do List subgraph includes:
400
+
401
+ - **GraphQL schema** (`schema.ts`): Defines `todoList`, `todoItems`, and `todoItemsCount` queries
402
+ - **Resolvers** (`resolvers.ts`): Handle data fetching and filtering from the operational store
403
+ - **Main subgraph class** (`index.ts`): Coordinates everything and includes:
404
+ - **Operational table creation**: Sets up the `todo_items` table with proper schema
405
+ - **Event processing**: The `process` method keeps subgraph data synchronized with document model changes
406
+ - **Real-time updates**: Automatically handles `ADD_TODO_ITEM`, `UPDATE_TODO_ITEM`, and `DELETE_TODO_ITEM` events
407
+
408
+ **Key features:**
409
+ - **Filtering capability**: The `todoItems` query accepts an optional `checked` parameter
410
+ - **Performance optimization**: The `todoItemsCount` query returns just numbers when you don't need full data
411
+ - **Real-time synchronization**: Changes in Connect immediately appear in subgraph queries
412
+ - **Complete statistics**: The `todoList` query returns total, checked, and unchecked counts
354
413
 
355
414
  ## 3. Testing the To-do List Subgraph
356
415
 
@@ -485,7 +544,7 @@ This demonstrates the real-time synchronization between the document model and t
485
544
 
486
545
  ## 4. Working with the supergraph or gateway
487
546
 
488
- 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
547
+ 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.
489
548
 
490
549
  ### 4.1 Key concepts
491
550
 
@@ -503,7 +562,7 @@ A supergraph is a GraphQL schema that combines multiple underlying GraphQL APIs,
503
562
 
504
563
  ### 4.3 Use the Powerhouse supergraph
505
564
 
506
- 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 get to the endpoint open your localhost by starting the reactor and adding `graphql` to the end of the url. The following commands explain how you can test & try the supergraph.
565
+ 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.
507
566
 
508
567
  - Start the reactor:
509
568
 
@@ -517,7 +576,7 @@ The Powerhouse supergraph for any given remote drive or reactor can be found und
517
576
  http://localhost:4001/graphql
518
577
  ```
519
578
 
520
- The supergraph allows to both query & mutate data from the same endpoint.
579
+ The supergraph allows you to both query & mutate data from the same endpoint.
521
580
 
522
581
  **Example: Using the supergraph with To-do List documents**
523
582
 
@@ -639,7 +698,7 @@ To integrate with them, register them via the Reactor API.
639
698
 
640
699
  ### Future enhancements
641
700
 
642
- Bridge Processors and Subgraphs Currently, there's a gap in how processors and subgraphs interact. Powerhouse might improve this in future updates.
701
+ Bridge Processors and Subgraphs Currently, there's a gap in how processors and subgraphs interact. Powerhouse might improve this in future updates.
643
702
 
644
703
 
645
704
 
@@ -0,0 +1,8 @@
1
+ {
2
+ "label": "RelationalDb Processor",
3
+ "position": 6,
4
+ "link": {
5
+ "type": "generated-index",
6
+ "description": "Learn how to make use of a RelationalDb Processor in this tutorial!"
7
+ }
8
+ }
@@ -50,6 +50,42 @@ const updateInvoiceName = useUpdateDocumentField('docId', 'name')
50
50
  // Combined read + write (like useState)
51
51
  const [invoiceName, updateInvoiceName] = useDocumentField('docId', 'name')
52
52
  ```
53
+ Initial documentation about the hooks can be found [here](https://github.com/powerhouse-inc/powerhouse/blob/main/packages/common/state/README.md)
54
+
55
+ ### Temporary use of new hooks on custom drive editors.
56
+
57
+
58
+ To use the new hooks in custom components or editors today, devs must:
59
+
60
+ 1. Pass in the existing Reactor instance as a prop (createReactor).
61
+ 2. Call useInitializeReactor(props.createReactor, false) in the custom component.
62
+ 3. Optionally wrap dispatch() to trigger a refresh manually, using:
63
+
64
+ const refresh = useSyncDrivesAndDocumentsWithReactor();
65
+
66
+ For maximum compatibility, consider passing data and set functions (drives, documents, etc.) directly as props instead of using the hooks inside the custom editor..
67
+
68
+ Example:
69
+
70
+ ```
71
+ +import { AtomStoreProvider } from "@powerhousedao/common";
72
+
73
+ export default function Editor(props: IProps) {
74
+ return (
75
+ + <AtomStoreProvider reactor={props.context.reactor}>
76
+ <DriveContextProvider value={props.context}>
77
+ <WagmiContext>
78
+ <BaseEditor {...props} />
79
+ </WagmiContext>
80
+ </DriveContextProvider>
81
+ + </AtomStoreProvider>
82
+ );
83
+ }
84
+ ```
85
+
86
+ Until the hooks are fully integrated and event handling is granular, the team will need to handle some of this manually or limit their use to experimental side projects and internal demos.
87
+
88
+
53
89
 
54
90
 
55
91
  ## An overview of currently available hooks
@@ -7,11 +7,11 @@ This page covers the relational database tools available in Powerhouse applicati
7
7
  The relational database layer gives you powerful tools to work with data in your Powerhouse applications. You get type-safe queries, real-time updates, and a simple API that feels familiar to React developers.
8
8
 
9
9
  **Key Benefits:**
10
- - 🔒 **Type-safe queries** with full TypeScript support
11
- - 🔄 **Live query capabilities** with real-time updates
12
- - **Automatic optimization** to prevent infinite re-renders
13
- - 🎯 **Simple API** that abstracts away complexity
14
- - 🧠 **Smart memoization** for parameters and queries
10
+ - **Type-safe queries** with full TypeScript support
11
+ - **Live query capabilities** with real-time updates
12
+ - **Automatic optimization** to prevent infinite re-renders
13
+ - **Simple API** that abstracts away complexity
14
+ - **Smart memorization** for parameters and queries
15
15
 
16
16
  ## Quick Start
17
17
 
@@ -40,23 +40,26 @@ type MyDatabase = {
40
40
 
41
41
  ```typescript
42
42
  import { createProcessorQuery } from '@powerhousedao/reactor-browser/relational';
43
+ import { MyProcessor } from './processors/my-processor';
43
44
 
44
- const useTypedQuery = createProcessorQuery<MyDatabase>();
45
+ // Create a typed query hook for your processor
46
+ const useTypedQuery = createProcessorQuery(MyProcessor);
45
47
  ```
46
48
 
47
49
  ### Step 3: Use it in your component
48
50
 
49
51
  ```typescript
50
52
  // Simple query - no parameters needed
51
- export function useUserList() {
52
- return useTypedQuery(db => {
53
+ export function useUserList(driveId: string) {
54
+ return useTypedQuery(driveId, db => {
53
55
  return db.selectFrom('users').selectAll().compile();
54
56
  });
55
57
  }
56
58
 
57
59
  // Query with parameters
58
- export function useUserById(userId: number) {
60
+ export function useUserById(driveId: string, userId: number) {
59
61
  return useTypedQuery(
62
+ driveId,
60
63
  (db, params) => {
61
64
  return db
62
65
  .selectFrom('users')
@@ -72,8 +75,8 @@ export function useUserById(userId: number) {
72
75
  ### Step 4: Use in your React component
73
76
 
74
77
  ```typescript
75
- function UserList() {
76
- const { isLoading, error, result } = useUserList();
78
+ function UserList({ driveId }: { driveId: string }) {
79
+ const { isLoading, error, result } = useUserList(driveId);
77
80
 
78
81
  if (isLoading) return <div>Loading...</div>;
79
82
  if (error) return <div>Error: {error.message}</div>;
@@ -98,40 +101,40 @@ function UserList() {
98
101
  ### 1. createProcessorQuery()
99
102
 
100
103
  <details>
101
- <summary>`createProcessorQuery<Schema>()`: Creates a typed query hook for your database schema</summary>
104
+ <summary>`createProcessorQuery(ProcessorClass)`: Creates a typed query hook factory for your processor</summary>
102
105
 
103
- ### Hook Name and Signature
106
+ ### Function Name and Signature
104
107
 
105
108
  ```typescript
106
- function createProcessorQuery<Schema>(): TypedQueryHook<Schema>
109
+ function createProcessorQuery<Schema>(
110
+ ProcessorClass: RelationalDbProcessorClass<Schema>
111
+ ): TypedQueryHook<Schema>
107
112
  ```
108
113
 
109
114
  ### Description
110
115
 
111
- Creates a typed query hook that provides type-safe database operations with live query capabilities. This is the main hook you'll use for most relational database operations in your components.
116
+ Creates a typed query hook factory for a specific processor class. This is the main function you'll use to create hooks for querying your relational database.
112
117
 
113
118
  ### Usage Example
114
119
 
115
120
  ```typescript
116
121
  import { createProcessorQuery } from '@powerhousedao/reactor-browser/relational';
122
+ import { MyProcessor } from './processors/my-processor';
117
123
 
118
- type AppDatabase = {
119
- users: { id: number; name: string; email: string };
120
- posts: { id: number; title: string; author_id: number };
121
- };
122
-
123
- const useTypedQuery = createProcessorQuery<AppDatabase>();
124
+ // Create a typed query hook for your processor
125
+ const useTypedQuery = createProcessorQuery(MyProcessor);
124
126
 
125
- // Static query (no parameters)
126
- function useAllUsers() {
127
- return useTypedQuery(db => {
127
+ // Use it to create specific query hooks
128
+ export const useUsers = (driveId: string) => {
129
+ return useTypedQuery(driveId, (db) => {
128
130
  return db.selectFrom('users').selectAll().compile();
129
131
  });
130
- }
132
+ };
131
133
 
132
- // Dynamic query with parameters
133
- function useUsersByStatus(status: string) {
134
+ // With parameters
135
+ export const useUsersByStatus = (driveId: string, status: string) => {
134
136
  return useTypedQuery(
137
+ driveId,
135
138
  (db, params) => {
136
139
  return db
137
140
  .selectFrom('users')
@@ -141,41 +144,32 @@ function useUsersByStatus(status: string) {
141
144
  },
142
145
  { status }
143
146
  );
144
- }
147
+ };
145
148
  ```
146
149
 
147
150
  ### Parameters
148
151
 
149
- The returned hook has two overloads:
150
-
151
- **Static queries (no parameters):**
152
- - `queryCallback: (db: EnhancedKysely<Schema>) => QueryCallbackReturnType` - Function that receives the database instance and returns a query
153
-
154
- **Parameterized queries:**
155
- - `queryCallback: (db: EnhancedKysely<Schema>, parameters: TParams) => QueryCallbackReturnType` - Function that receives the database instance and parameters
156
- - `parameters: TParams` - Parameters for the query (automatically memoized)
152
+ The returned hook accepts:
153
+ - `driveId`: The ID of the drive
154
+ - `queryCallback`: Function that receives the database instance and optional parameters
155
+ - `parameters`: Optional parameters for the query
157
156
 
158
157
  ### Return Value
159
158
 
160
159
  ```typescript
161
160
  {
162
- isLoading: boolean; // True while query is loading
163
- error: Error | null; // Any error that occurred
164
- result: LiveQueryResults<T> | null; // Query results with real-time updates
161
+ isLoading: boolean; // True while loading or retrying
162
+ error: Error | null; // Any error that occurred
163
+ result: LiveQueryResults<T> | null; // Query results with live updates
165
164
  }
166
165
  ```
167
166
 
168
167
  ### Notes / Caveats
169
168
 
170
- - Parameters are automatically memoized using deep comparison
171
- - Queries update in real-time when the database changes
172
- - The callback must return an object with `sql` and optional `parameters` properties
173
- - Use `.compile()` on Kysely queries to get the required format
174
-
175
- ### Related Hooks
176
-
177
- - [`useOperationalStore`](#useoperationalstore) - For direct database access
178
- - [`useOperationalQuery`](#useoperationalquery) - Lower-level query hook
169
+ - Create one `useTypedQuery` hook per processor
170
+ - The hook includes automatic retry logic for common errors
171
+ - Parameters are automatically memoized
172
+ - Queries are live and will update automatically when data changes
179
173
 
180
174
  </details>
181
175
 
@@ -246,8 +240,8 @@ function DatabaseOperations() {
246
240
 
247
241
  ### Related Hooks
248
242
 
249
- - [`createProcessorQuery`](#createProcessorQuery) - For optimized queries
250
- - [`useOperationalQuery`](#useoperationalquery) - For manual query control
243
+ - [`createProcessorQuery`](#1-createprocessorquery) - For optimized queries
244
+ - [`useOperationalQuery`](#3-useoperationalquery) - For manual query control
251
245
 
252
246
  </details>
253
247
 
@@ -314,8 +308,8 @@ function UserCount() {
314
308
 
315
309
  ### Related Hooks
316
310
 
317
- - [`createProcessorQuery`](#createProcessorQuery) - Recommended higher-level API
318
- - [`useOperationalStore`](#useoperationalstore) - For direct database access
311
+ - [`createProcessorQuery`](#1-createprocessorquery) - Recommended higher-level API
312
+ - [`useOperationalStore`](#2-useoperationalstore) - For direct database access
319
313
 
320
314
  </details>
321
315
 
@@ -1,12 +1,12 @@
1
- # PHDocument Migration Guide (v3.3.0)
1
+ # PHDocument Migration Guide
2
2
 
3
3
  :::tip
4
- This guide covers the **breaking changes** introduced in Powerhouse v3.3.0 related to PHDocument structure changes. If you're upgrading from v3.2.0 or earlier, **this migration is required** and document models must be regenerated.
4
+ This guide covers the **breaking changes** introduced in Powerhouse v4.0.0 related to PHDocument structure changes. If you're upgrading from v3.2.0 or earlier, **this migration is required** and document models must be regenerated.
5
5
  :::
6
6
 
7
7
  ## Overview
8
8
 
9
- Version 3.3.0 introduced a significant refactor of the `PHDocument` structure that consolidates document metadata into a `header` field. This change enables signed and unsigned documents with cryptographic verification capabilities, but requires updating all code that accesses document properties.
9
+ Version 4.0.0 introduced a significant refactor of the `PHDocument` structure that consolidates document metadata into a `header` field. This change enables signed and unsigned documents with cryptographic verification capabilities, but requires updating all code that accesses document properties.
10
10
 
11
11
  ## What Changed
12
12
 
@@ -28,7 +28,7 @@ const document = {
28
28
  }
29
29
  ```
30
30
 
31
- **After (v3.3.0):**
31
+ **After (v4.0.0):**
32
32
  ```javascript
33
33
  const document = {
34
34
  header: {
@@ -328,11 +328,10 @@ describe('Document Migration', () => {
328
328
 
329
329
  ## Related Documentation
330
330
 
331
- - [PHDocument Architecture](../05-Architecture/PHDocument.md)
332
- - [Document Model Creation](../02-MasteryTrack/DocumentModelCreation/WhatIsADocumentModel.md)
333
- - [GraphQL API Reference](./02-ReactorAPI.md)
334
- - [React Hooks](./01-ReactHooks.md)
331
+ - [PHDocument Architecture](/academy/Architecture/PowerhouseArchitecture)
332
+ - [Document Model Creation](/academy/MasteryTrack/DocumentModelCreation/WhatIsADocumentModel)
333
+ - [React Hooks](/academy/APIReferences/ReactHooks)
335
334
 
336
335
  ---
337
336
 
338
- *This migration guide covers the major changes in v3.3.0. For additional technical details, refer to the [RELEASE-NOTES.md](https://github.com/powerhouse-dao/powerhouse/blob/main/RELEASE-NOTES.md) in the main repository.*
337
+ *This migration guide covers the major changes in v4.0.0. For additional technical details, refer to the [RELEASE-NOTES.md](https://github.com/powerhouse-dao/powerhouse/blob/main/RELEASE-NOTES.md) in the main repository.*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerhousedao/academy",
3
- "version": "3.3.0-dev.14",
3
+ "version": "3.3.0-dev.15",
4
4
  "homepage": "https://powerhouse.academy",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +0,0 @@
1
- ## Start the Reactor & Connect
2
-
3
- ## Use the analytics modal / Explain the modal
4
-