@powerhousedao/academy 3.3.0-dev.12 → 3.3.0-dev.14
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/CHANGELOG.md +8 -0
- package/docs/academy/02-MasteryTrack/04-WorkWithData/01-GraphQLAtPowerhouse.md +1 -1
- package/docs/academy/02-MasteryTrack/04-WorkWithData/03-UsingSubgraphs.md +1 -1
- package/docs/academy/02-MasteryTrack/04-WorkWithData/07-OperationalDbProcessorTutorial/01-TodoList-example.md +10 -14
- package/docs/academy/04-APIReferences/00-PowerhouseCLI.md +1 -1
- package/docs/academy/04-APIReferences/{04-OperationalDatabase.md → 04-RelationalDatabase.md} +18 -18
- package/docs/bookofpowerhouse/04-DevelopmentApproaches.md +1 -1
- package/package.json +1 -1
- package/sidebars.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 3.3.0-dev.14 (2025-07-17)
|
|
2
|
+
|
|
3
|
+
This was a version bump only for @powerhousedao/academy to align it with other projects, there were no code changes.
|
|
4
|
+
|
|
5
|
+
## 3.3.0-dev.13 (2025-07-17)
|
|
6
|
+
|
|
7
|
+
This was a version bump only for @powerhousedao/academy to align it with other projects, there were no code changes.
|
|
8
|
+
|
|
1
9
|
## 3.3.0-dev.12 (2025-07-17)
|
|
2
10
|
|
|
3
11
|
### 🩹 Fixes
|
|
@@ -156,7 +156,7 @@ When dealing with lists of data, GraphQL employs a pattern that includes:
|
|
|
156
156
|
|
|
157
157
|
## GraphQL Subgraphs in Powerhouse
|
|
158
158
|
|
|
159
|
-
Powerhouse structures its data into **subgraphs**, which are modular GraphQL services that connect to the Reactor (Powerhouse's core data infrastructure) or
|
|
159
|
+
Powerhouse structures its data into **subgraphs**, which are modular GraphQL services that connect to the Reactor (Powerhouse's core data infrastructure) or Data Stores fueled by data from processors. Each subgraph has its own SDL, ensuring modularity and flexibility while working within the ecosystem.
|
|
160
160
|
|
|
161
161
|
### Fetching data from the Reactor
|
|
162
162
|
|
|
@@ -14,7 +14,7 @@ A subgraph in Powerhouse is a **GraphQL-based modular data component** that exte
|
|
|
14
14
|
### Subgraphs can retrieve data from
|
|
15
15
|
|
|
16
16
|
- **The Reactor** – The core Powerhouse data system or network node.
|
|
17
|
-
- **
|
|
17
|
+
- **Relational Data Stores** – Structured data storage for operational processes, offering real-time updates, for querying structured data.
|
|
18
18
|
- **Analytics Stores** – Aggregated historical data, useful for insights, reporting and business intelligence.
|
|
19
19
|
|
|
20
20
|
### Subgraphs consist of
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
2. Define your database schema
|
|
5
5
|
3. Customize the processor to your needs
|
|
6
6
|
4. Test your processor
|
|
7
|
-
5. Use the
|
|
7
|
+
5. Use the relational database in Frontend and Subgraph
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
## Generate the Processor
|
|
@@ -25,9 +25,9 @@ The migration file has a up and a down function which gets called when either th
|
|
|
25
25
|
Below you can find the example of a todo table.
|
|
26
26
|
|
|
27
27
|
```ts
|
|
28
|
-
import { type
|
|
28
|
+
import { type IBaseRelationalDb } from "document-drive/processors/types"
|
|
29
29
|
|
|
30
|
-
export async function up(db:
|
|
30
|
+
export async function up(db: IBaseRelationalDb): Promise<void> {
|
|
31
31
|
// Create table
|
|
32
32
|
await db.schema
|
|
33
33
|
.createTable("todo")
|
|
@@ -41,7 +41,7 @@ export async function up(db: IOperationalStore): Promise<void> {
|
|
|
41
41
|
console.log(tables);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
export async function down(db:
|
|
44
|
+
export async function down(db: IBaseRelationalDb): Promise<void> {
|
|
45
45
|
// drop table
|
|
46
46
|
await db.schema.dropTable("todo").execute();
|
|
47
47
|
}
|
|
@@ -74,7 +74,7 @@ export const todoProcessorProcessorFactory =
|
|
|
74
74
|
const namespace = TodoProcessorProcessor.getNamespace(driveId);
|
|
75
75
|
|
|
76
76
|
// Create a filter for the processor
|
|
77
|
-
const filter:
|
|
77
|
+
const filter: RelationalDbProcessorFilter = {
|
|
78
78
|
branch: ["main"],
|
|
79
79
|
documentId: ["*"],
|
|
80
80
|
documentType: ["powerhouse/todo-list"],
|
|
@@ -84,7 +84,7 @@ export const todoProcessorProcessorFactory =
|
|
|
84
84
|
// Create a namespaced store for the processor
|
|
85
85
|
const store = await createNamespacedDb<TodoProcessorProcessor>(
|
|
86
86
|
namespace,
|
|
87
|
-
module.
|
|
87
|
+
module.relationalStore,
|
|
88
88
|
);
|
|
89
89
|
|
|
90
90
|
// Create the processor
|
|
@@ -108,7 +108,7 @@ In the following you'll find an example where we store all the created and udpat
|
|
|
108
108
|
```ts
|
|
109
109
|
type DocumentType = ToDoListDocument;
|
|
110
110
|
|
|
111
|
-
export class TodoIndexerProcessor extends
|
|
111
|
+
export class TodoIndexerProcessor extends RelationalDbProcessor<DB> {
|
|
112
112
|
|
|
113
113
|
static override getNamespace(driveId: string): string {
|
|
114
114
|
// Default namespace: `${this.name}_${driveId.replaceAll("-", "_")}`
|
|
@@ -116,7 +116,7 @@ export class TodoIndexerProcessor extends OperationalProcessor<DB> {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
override async initAndUpgrade(): Promise<void> {
|
|
119
|
-
await up(this.
|
|
119
|
+
await up(this.relationalDb as IBaseRelationalDb);
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
override async onStrands(
|
|
@@ -132,7 +132,7 @@ export class TodoIndexerProcessor extends OperationalProcessor<DB> {
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
for (const operation of strand.operations) {
|
|
135
|
-
await this.
|
|
135
|
+
await this.relationalDb
|
|
136
136
|
.insertInto("todo")
|
|
137
137
|
.values({
|
|
138
138
|
task: strand.documentId,
|
|
@@ -173,7 +173,7 @@ resolvers = {
|
|
|
173
173
|
resolve: async (parent, args, context, info) => {
|
|
174
174
|
const todoList = await TodoProcessor.query(
|
|
175
175
|
args.driveId ?? "powerhouse",
|
|
176
|
-
this.
|
|
176
|
+
this.relationalDb
|
|
177
177
|
)
|
|
178
178
|
.selectFrom("todo")
|
|
179
179
|
.selectAll()
|
|
@@ -197,7 +197,3 @@ resolvers = {
|
|
|
197
197
|
```
|
|
198
198
|
|
|
199
199
|
|
|
200
|
-
### useOperationalStore Hook
|
|
201
|
-
|
|
202
|
-
.....
|
|
203
|
-
|
|
@@ -392,7 +392,7 @@ Examples:
|
|
|
392
392
|
$ ph generate --drive-editor custom-drive-explorer # Generate a custom drive editor
|
|
393
393
|
$ ph generate -s MySubgraph # Generate with a specific subgraph
|
|
394
394
|
$ ph generate --skip-format # Generate without formatting
|
|
395
|
-
$ ph generate --migration-file ./migrations.ts # Generate types for an
|
|
395
|
+
$ ph generate --migration-file ./migrations.ts # Generate types for an RelationalDB Processor
|
|
396
396
|
```
|
|
397
397
|
|
|
398
398
|
## Inspect
|
package/docs/academy/04-APIReferences/{04-OperationalDatabase.md → 04-RelationalDatabase.md}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Relational Database
|
|
2
2
|
|
|
3
|
-
This page covers the
|
|
3
|
+
This page covers the relational database tools available in Powerhouse applications, providing type-safe database operations with real-time updates through PGlite integration.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
The
|
|
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
10
|
- 🔒 **Type-safe queries** with full TypeScript support
|
|
@@ -16,7 +16,7 @@ The operational database layer gives you powerful tools to work with data in you
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
18
18
|
<details>
|
|
19
|
-
<summary>Setting up your first
|
|
19
|
+
<summary>Setting up your first relational database query</summary>
|
|
20
20
|
|
|
21
21
|
### Step 1: Define your database schema
|
|
22
22
|
|
|
@@ -39,9 +39,9 @@ type MyDatabase = {
|
|
|
39
39
|
### Step 2: Create a typed query hook
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
|
-
import {
|
|
42
|
+
import { createProcessorQuery } from '@powerhousedao/reactor-browser/relational';
|
|
43
43
|
|
|
44
|
-
const useTypedQuery =
|
|
44
|
+
const useTypedQuery = createProcessorQuery<MyDatabase>();
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
### Step 3: Use it in your component
|
|
@@ -95,32 +95,32 @@ function UserList() {
|
|
|
95
95
|
|
|
96
96
|
## Core Hooks
|
|
97
97
|
|
|
98
|
-
### 1.
|
|
98
|
+
### 1. createProcessorQuery()
|
|
99
99
|
|
|
100
100
|
<details>
|
|
101
|
-
<summary>`
|
|
101
|
+
<summary>`createProcessorQuery<Schema>()`: Creates a typed query hook for your database schema</summary>
|
|
102
102
|
|
|
103
103
|
### Hook Name and Signature
|
|
104
104
|
|
|
105
105
|
```typescript
|
|
106
|
-
function
|
|
106
|
+
function createProcessorQuery<Schema>(): TypedQueryHook<Schema>
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
### Description
|
|
110
110
|
|
|
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
|
|
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.
|
|
112
112
|
|
|
113
113
|
### Usage Example
|
|
114
114
|
|
|
115
115
|
```typescript
|
|
116
|
-
import {
|
|
116
|
+
import { createProcessorQuery } from '@powerhousedao/reactor-browser/relational';
|
|
117
117
|
|
|
118
118
|
type AppDatabase = {
|
|
119
119
|
users: { id: number; name: string; email: string };
|
|
120
120
|
posts: { id: number; title: string; author_id: number };
|
|
121
121
|
};
|
|
122
122
|
|
|
123
|
-
const useTypedQuery =
|
|
123
|
+
const useTypedQuery = createProcessorQuery<AppDatabase>();
|
|
124
124
|
|
|
125
125
|
// Static query (no parameters)
|
|
126
126
|
function useAllUsers() {
|
|
@@ -242,11 +242,11 @@ function DatabaseOperations() {
|
|
|
242
242
|
- Always check if `db` is not null before using it
|
|
243
243
|
- The database instance includes both Kysely methods and live query capabilities
|
|
244
244
|
- Use this for direct database operations like inserts, updates, and deletes
|
|
245
|
-
- For queries, prefer `
|
|
245
|
+
- For queries, prefer `createProcessorQuery()` which provides better optimization
|
|
246
246
|
|
|
247
247
|
### Related Hooks
|
|
248
248
|
|
|
249
|
-
- [`
|
|
249
|
+
- [`createProcessorQuery`](#createProcessorQuery) - For optimized queries
|
|
250
250
|
- [`useOperationalQuery`](#useoperationalquery) - For manual query control
|
|
251
251
|
|
|
252
252
|
</details>
|
|
@@ -267,7 +267,7 @@ function useOperationalQuery<Schema, T, TParams>(
|
|
|
267
267
|
|
|
268
268
|
### Description
|
|
269
269
|
|
|
270
|
-
Lower-level hook for creating live queries with manual control over the query callback and parameters. Most developers should use `
|
|
270
|
+
Lower-level hook for creating live queries with manual control over the query callback and parameters. Most developers should use `createProcessorQuery()` instead, but this hook is useful for advanced use cases.
|
|
271
271
|
|
|
272
272
|
### Usage Example
|
|
273
273
|
|
|
@@ -309,12 +309,12 @@ function UserCount() {
|
|
|
309
309
|
### Notes / Caveats
|
|
310
310
|
|
|
311
311
|
- This hook doesn't include automatic parameter memoization
|
|
312
|
-
- Use `
|
|
312
|
+
- Use `createProcessorQuery()` for better developer experience and optimization
|
|
313
313
|
- Useful for cases where you need manual control over the query lifecycle
|
|
314
314
|
|
|
315
315
|
### Related Hooks
|
|
316
316
|
|
|
317
|
-
- [`
|
|
317
|
+
- [`createProcessorQuery`](#createProcessorQuery) - Recommended higher-level API
|
|
318
318
|
- [`useOperationalStore`](#useoperationalstore) - For direct database access
|
|
319
319
|
|
|
320
320
|
</details>
|
|
@@ -332,7 +332,7 @@ You need to create queries that update automatically when search terms, filters,
|
|
|
332
332
|
|
|
333
333
|
### Solution
|
|
334
334
|
|
|
335
|
-
The `
|
|
335
|
+
The `createProcessorQuery` hook automatically handles parameter changes and memoizes them using deep comparison:
|
|
336
336
|
|
|
337
337
|
```typescript
|
|
338
338
|
function useSearchResults() {
|
|
@@ -28,7 +28,7 @@ These methodologies enhance collaboration, streamline workflows, and accelerate
|
|
|
28
28
|
- This separation offers significant advantages:
|
|
29
29
|
1. **Scalability**: Write and read models can scale independently, allowing Powerhouse to support large decentralized organizations without performance bottlenecks.
|
|
30
30
|
2. **Maintainability**: By isolating business logic (commands) from query logic, developers can iterate on one without affecting the other, ensuring the system evolves efficiently.
|
|
31
|
-
3. **Flexibility**: Powerhouse supports multiple types of read models—such as
|
|
31
|
+
3. **Flexibility**: Powerhouse supports multiple types of read models—such as relational databases, full-text search, and analytics—each tailored to specific organizational needs.
|
|
32
32
|
|
|
33
33
|
### Event-driven Architectures (EDA)
|
|
34
34
|
- Event-Driven Architecture (EDA) is a foundational element of Powerhouse’s software philosophy, designed to create responsive, scalable systems that support asynchronous workflows. In EDA, events represent meaningful changes or actions, such as “Document Updated” or “Contributor Added,” and these events trigger reactions across the system in real time.
|
package/package.json
CHANGED
package/sidebars.ts
CHANGED
|
@@ -111,7 +111,7 @@ const sidebars = {
|
|
|
111
111
|
items: [
|
|
112
112
|
"academy/APIReferences/PowerhouseCLI",
|
|
113
113
|
"academy/APIReferences/ReactHooks",
|
|
114
|
-
"academy/APIReferences/
|
|
114
|
+
"academy/APIReferences/RelationalDatabase",
|
|
115
115
|
"academy/APIReferences/PHDocumentMigrationGuide",
|
|
116
116
|
],
|
|
117
117
|
},
|