Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/few-cups-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@bluecadet/launchpad-content": major
"@bluecadet/launchpad-cli": minor
---

refactor: extract content fetch pipeline into stages

Extract the fetch pipeline from LaunchpadContent into composable stage
functions (setupHooks, backup, clearOldData, fetchSources, etc.) for
better testability and modularity. Simplify state management with inline
phase tracking. Add comprehensive tests for fetch context and stages.

This is a breaking change as it modifies the API of LaunchpadContent by
adding the loadSources() method, as well as changing the fetch() and
clear() methods to accept just the source IDs instead of full source
objects.
9 changes: 9 additions & 0 deletions .changeset/full-singers-vanish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@bluecadet/launchpad-controller": patch
"@bluecadet/launchpad-content": patch
"@bluecadet/launchpad-monitor": patch
"@bluecadet/launchpad-utils": patch
"@bluecadet/launchpad-cli": patch
---

Move LaunchpadConfig type definition from cli package to utils package, allowing for declaration merging.
47 changes: 47 additions & 0 deletions .changeset/nice-pandas-punch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
"@bluecadet/launchpad-utils": minor
"@bluecadet/launchpad-controller": minor
"@bluecadet/launchpad-content": minor
"@bluecadet/launchpad-monitor": minor
"@bluecadet/launchpad-cli": minor
---

Move declaration merging to utils package instead of controller package.

This improves type safety when the controller package is not a dependency, such as when using content/monitor packages in isolation.

The API stays largely the same, with some minor adjustments to import paths and type exports.

```typescript
// OLD:
import { LaunchpadEvents, SubsystemsState } from '@bluecadet/launchpad-controller';

// NEW:
import { LaunchpadEvents, SubsystemsState } from '@bluecadet/launchpad-utils';

// ------

// OLD:

declare module '@bluecadet/launchpad-controller' {
interface LaunchpadEvents {
'plugin:myPlugin:ready': { version: string };
'plugin:myPlugin:error': { error: Error };
}

interface SubsystemsState {
myPlugin: MyPluginState;
}
}

// NEW:
declare module '@bluecadet/launchpad-utils' {
interface LaunchpadEvents {
'plugin:myPlugin:ready': { version: string };
'plugin:myPlugin:error': { error: Error };
}
interface SubsystemsState {
myPlugin: MyPluginState;
}
}
```
10 changes: 10 additions & 0 deletions .changeset/thin-ears-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@bluecadet/launchpad-content": minor
"@bluecadet/launchpad-monitor": minor
"@bluecadet/launchpad-controller": minor
"@bluecadet/launchpad-cli": minor
---

Refactor monitor and content state to use Immer. This allows us to emit patch events when state changes, which are then handled by the controller package to sync state across processes (just IPC for now).

Adds a new "watch" flag to the CLI status command to allow live monitoring of the controller status.
6 changes: 1 addition & 5 deletions docs/src/reference/content/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,12 @@ Emitted when all content has been successfully fetched.
```typescript
{
sources: string[]; // IDs of sources that were fetched
totalFiles: number; // Total number of files written
duration: number; // Time taken in milliseconds
}
```

**Example:**
```typescript
eventBus.on('content:fetch:done', (data) => {
console.log(`Fetched ${data.totalFiles} files in ${data.duration}ms`);
console.log(`Sources: ${data.sources.join(', ')}`);
});
```
Expand Down Expand Up @@ -99,14 +96,13 @@ Emitted when a source completes successfully.
```typescript
{
sourceId: string; // ID of the source
documentCount: number; // Number of documents fetched
}
```

**Example:**
```typescript
eventBus.on('content:source:done', (data) => {
console.log(`Source ${data.sourceId} fetched ${data.documentCount} documents`);
console.log(`Source ${data.sourceId} fetched`);
});
```

Expand Down
5 changes: 4 additions & 1 deletion docs/src/reference/content/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ npm install @bluecadet/launchpad-content
```typescript
import LaunchpadContent from '@bluecadet/launchpad-content';

const content = new LaunchpadContent({
const content = LaunchpadContent({
sources: [
// Content source configurations
],
Expand All @@ -51,6 +51,9 @@ const content = new LaunchpadContent({
downloadPath: './content'
});

// Load content sources
await content.loadSources();

// Start content download and processing
await content.start();
```
Expand Down
6 changes: 3 additions & 3 deletions docs/src/reference/controller/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const eventBus = controller.getEventBus();

// ✅ Type-safe - TypeScript knows the exact payload shape
eventBus.on('content:fetch:done', (data) => {
console.log(`Fetched ${data.totalFiles} files from ${data.sources.length} sources`);
// data is typed as: { sources: string[], totalFiles: number, duration: number }
console.log(`Fetched ${data.sources.length} sources`);
// data is typed as: { sources: string[] }
});
```

Expand Down Expand Up @@ -227,7 +227,7 @@ Applications and plugins can define their own events using declaration merging:

```typescript
// my-plugin.ts
declare module '@bluecadet/launchpad-controller' {
declare module '@bluecadet/launchpad-utils' {
interface LaunchpadEvents {
'plugin:myPlugin:ready': { version: string };
'plugin:myPlugin:error': { error: Error };
Expand Down
5 changes: 3 additions & 2 deletions docs/src/reference/controller/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const eventBus = controller.getEventBus();

// Listen to events
eventBus.on('content:fetch:done', (data) => {
console.log(`Fetched ${data.totalFiles} files`);
console.log(`Fetched ${data.sources.length} sources`);
});

// Emit events (from subsystems)
Expand Down Expand Up @@ -124,6 +124,7 @@ Subsystems that expose state implement `getState()`:
```typescript
interface StateProvider<TState> {
getState(): TState;
onStatePatch(handler: PatchHandler): () => void;
}
```

Expand Down Expand Up @@ -174,7 +175,7 @@ The controller uses TypeScript declaration merging to provide type-safe events w

```typescript
// Each subsystem declares its events
declare module '@bluecadet/launchpad-controller' {
declare module '@bluecadet/launchpad-utils' {
interface LaunchpadEvents {
'content:fetch:start': { timestamp: Date };
'monitor:app:started': { appName: string; pid: number };
Expand Down
22 changes: 18 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"dependencies": {
"@bluecadet/launchpad-controller": "~0.1.0",
"@bluecadet/launchpad-utils": "~2.1.0",
"ansi-escapes": "^7.1.1",
"chalk": "^5.0.0",
"dotenv": "^16.4.5",
"jiti": "^2.4.2",
Expand Down
9 changes: 8 additions & 1 deletion packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@ yargs(hideBin(process.argv))
.command(
"status",
"Show the status of the launchpad controller.",
() => {},
(yargs) => {
return yargs.option("watch", {
alias: "w",
describe: "Watch for status changes",
type: "boolean",
default: false,
});
},
async (args) => {
const { status } = await import("./commands/status.js");
await status(args);
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/commands/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ export function content(argv: GlobalLaunchpadArgs) {
return importLaunchpadContent().andThen(({ default: LaunchpadContent }) => {
const contentInstance = new LaunchpadContent(configContent, rootLogger, dir);
controller.registerSubsystem("content", contentInstance);
return controller.executeCommand({ type: "content.fetch" });

return contentInstance
.loadSources()
.andThen(() => controller.executeCommand({ type: "content.fetch" }));
});
},
}).orElse((error) => handleFatalError(error, rootLogger));
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function startForeground(argv: GlobalLaunchpadArgs): ResultAsync<void, Error> {
return importLaunchpadContent().andThen(({ default: LaunchpadContent }) => {
const contentInstance = new LaunchpadContent(contentConfig, rootLogger, dir);
controller.registerSubsystem("content", contentInstance);
return ok();
return contentInstance.loadSources();
});
}
return ok();
Expand Down
Loading