@auto-engineer/pipeline 1.97.2 → 1.99.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +3 -3
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +99 -0
- package/dist/src/runtime/context.d.ts +1 -0
- package/dist/src/runtime/context.d.ts.map +1 -1
- package/dist/src/server/pipeline-server-v2.js +1 -1
- package/dist/src/server/pipeline-server.d.ts +2 -1
- package/dist/src/server/pipeline-server.d.ts.map +1 -1
- package/dist/src/server/pipeline-server.js +39 -0
- package/dist/src/server/pipeline-server.js.map +1 -1
- package/dist/src/testing/fixtures/kanban-todo.config.js +1 -1
- package/dist/src/testing/fixtures/kanban-todo.config.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/runtime/context.ts +1 -0
- package/src/server/pipeline-server-v2.specs.ts +20 -12
- package/src/server/pipeline-server-v2.ts +1 -1
- package/src/server/pipeline-server.ts +50 -1
- package/src/testing/fixtures/kanban-todo.config.ts +1 -1
package/package.json
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"get-port": "^7.1.0",
|
|
15
15
|
"jose": "^5.9.6",
|
|
16
16
|
"nanoid": "^5.0.0",
|
|
17
|
-
"@auto-engineer/
|
|
18
|
-
"@auto-engineer/
|
|
17
|
+
"@auto-engineer/file-store": "1.99.0",
|
|
18
|
+
"@auto-engineer/message-bus": "1.99.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/cors": "^2.8.17",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"publishConfig": {
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
|
-
"version": "1.
|
|
27
|
+
"version": "1.99.0",
|
|
28
28
|
"scripts": {
|
|
29
29
|
"build": "tsc && tsx ../../scripts/fix-esm-imports.ts",
|
|
30
30
|
"test": "vitest run --reporter=dot",
|
package/src/runtime/context.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface PipelineContext {
|
|
|
10
10
|
startPhased?: (handler: ForEachPhasedDescriptor, event: Event) => Promise<void>;
|
|
11
11
|
eventStore?: InMemoryEventStore;
|
|
12
12
|
messageBus?: MessageBus;
|
|
13
|
+
clearMessages?: () => Promise<void>;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export interface RuntimeConfig {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
1
2
|
import { createPipelineServerV2 } from './pipeline-server-v2.js';
|
|
2
3
|
|
|
3
4
|
describe('PipelineServerV2', () => {
|
|
@@ -46,16 +47,25 @@ describe('PipelineServerV2', () => {
|
|
|
46
47
|
|
|
47
48
|
const port = await server.start();
|
|
48
49
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const { response, dataPromise, destroy } = await new Promise<{
|
|
51
|
+
response: http.IncomingMessage;
|
|
52
|
+
dataPromise: Promise<string>;
|
|
53
|
+
destroy: () => void;
|
|
54
|
+
}>((resolve) => {
|
|
55
|
+
const req = http.get(`http://localhost:${port}/events`, (res) => {
|
|
56
|
+
const chunks: string[] = [];
|
|
57
|
+
const dataPromise = new Promise<string>((resolveData) => {
|
|
58
|
+
res.on('data', (chunk: Buffer) => {
|
|
59
|
+
chunks.push(chunk.toString());
|
|
60
|
+
resolveData(chunks.join(''));
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
resolve({ response: res, dataPromise, destroy: () => req.destroy() });
|
|
64
|
+
});
|
|
52
65
|
});
|
|
53
66
|
|
|
54
|
-
expect(response.
|
|
55
|
-
expect(response.headers
|
|
56
|
-
|
|
57
|
-
const reader = response.body!.getReader();
|
|
58
|
-
const decoder = new TextDecoder();
|
|
67
|
+
expect(response.statusCode).toBe(200);
|
|
68
|
+
expect(response.headers['content-type']).toContain('text/event-stream');
|
|
59
69
|
|
|
60
70
|
await fetch(`http://localhost:${port}/command`, {
|
|
61
71
|
method: 'POST',
|
|
@@ -63,14 +73,12 @@ describe('PipelineServerV2', () => {
|
|
|
63
73
|
body: JSON.stringify({ type: 'Ping', data: {} }),
|
|
64
74
|
});
|
|
65
75
|
|
|
66
|
-
const
|
|
67
|
-
const text = decoder.decode(value);
|
|
76
|
+
const text = await dataPromise;
|
|
68
77
|
const parsed = JSON.parse(text.replace('data: ', '').trim());
|
|
69
78
|
|
|
70
79
|
expect(parsed).toEqual({ type: 'Pong', data: { value: 42 } });
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
controller.abort();
|
|
81
|
+
destroy();
|
|
74
82
|
await server.stop();
|
|
75
83
|
});
|
|
76
84
|
|
|
@@ -67,7 +67,7 @@ export class PipelineServer {
|
|
|
67
67
|
private readonly eventCommandMapper: EventCommandMapper;
|
|
68
68
|
private readonly phasedBridge: ReturnType<typeof createPhasedBridge>;
|
|
69
69
|
private readonly sseManager: SSEManager;
|
|
70
|
-
private
|
|
70
|
+
private eventStoreContext: PipelineEventStoreContext;
|
|
71
71
|
private readonly itemKeyExtractors = new Map<string, (data: unknown) => string | undefined>();
|
|
72
72
|
private readonly commandGate: ReturnType<typeof createCommandGate>;
|
|
73
73
|
private readonly middleware: express.RequestHandler[] = [];
|
|
@@ -344,6 +344,48 @@ export class PipelineServer {
|
|
|
344
344
|
return;
|
|
345
345
|
}
|
|
346
346
|
|
|
347
|
+
if (command.type === 'Reset') {
|
|
348
|
+
// 1. Clear event store (in-memory)
|
|
349
|
+
this.clearEventStore();
|
|
350
|
+
|
|
351
|
+
// Re-apply SQLite sync wrapper on the fresh event store
|
|
352
|
+
if (this.sqliteEventStore) {
|
|
353
|
+
const originalAppend = this.eventStoreContext.eventStore.appendToStream.bind(
|
|
354
|
+
this.eventStoreContext.eventStore,
|
|
355
|
+
);
|
|
356
|
+
this.eventStoreContext.eventStore.appendToStream = async (streamName, events, options) => {
|
|
357
|
+
const result = await originalAppend(streamName, events, options);
|
|
358
|
+
await this.sqliteEventStore!.appendToStream(streamName, events);
|
|
359
|
+
return result;
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// 2. New session
|
|
364
|
+
this.currentSessionId = `session-${nanoid()}`;
|
|
365
|
+
|
|
366
|
+
// 3. Broadcast PipelineRunStarted (persists event + SSE to UI)
|
|
367
|
+
await this.broadcastPipelineRunStarted(this.currentSessionId, 'Reset');
|
|
368
|
+
|
|
369
|
+
// 4. Run Clean command synchronously to remove generated files before restarting
|
|
370
|
+
const cleanRequestId = `req-${nanoid()}`;
|
|
371
|
+
const cleanCommand: Command & { correlationId: string; requestId: string } = {
|
|
372
|
+
type: 'Clean',
|
|
373
|
+
data: {},
|
|
374
|
+
correlationId: this.currentSessionId,
|
|
375
|
+
requestId: cleanRequestId,
|
|
376
|
+
};
|
|
377
|
+
if (this.commandHandlers.has('Clean')) {
|
|
378
|
+
await this.emitCommandDispatched(this.currentSessionId, cleanRequestId, 'Clean', {});
|
|
379
|
+
await this.processCommand(cleanCommand);
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// 5. Emit PipelineStarted to trigger pipeline handlers (kicks off fresh run)
|
|
383
|
+
await this.emitPipelineStartedEvent();
|
|
384
|
+
|
|
385
|
+
res.json({ status: 'ack', sessionId: this.currentSessionId });
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
347
389
|
if (!this.commandHandlers.has(command.type)) {
|
|
348
390
|
res.status(404).json({
|
|
349
391
|
status: 'nack',
|
|
@@ -1232,9 +1274,16 @@ export class PipelineServer {
|
|
|
1232
1274
|
},
|
|
1233
1275
|
eventStore: this.eventStoreContext.eventStore,
|
|
1234
1276
|
messageBus: this.messageBus,
|
|
1277
|
+
clearMessages: async () => {
|
|
1278
|
+
this.clearEventStore();
|
|
1279
|
+
},
|
|
1235
1280
|
};
|
|
1236
1281
|
}
|
|
1237
1282
|
|
|
1283
|
+
private clearEventStore(): void {
|
|
1284
|
+
this.eventStoreContext = createPipelineEventStore();
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1238
1287
|
private routeEventToPhasedExecutor(event: EventWithCorrelation): void {
|
|
1239
1288
|
for (const pipeline of this.pipelines.values()) {
|
|
1240
1289
|
for (const handler of pipeline.descriptor.handlers) {
|
|
@@ -7,9 +7,9 @@ export default pipelineConfig({
|
|
|
7
7
|
'@auto-engineer/server-generator-apollo-emmett',
|
|
8
8
|
'@auto-engineer/narrative',
|
|
9
9
|
'@auto-engineer/generate-react-client',
|
|
10
|
-
'@auto-engineer/react-component-implementer',
|
|
11
10
|
'@auto-engineer/server-implementer',
|
|
12
11
|
'@auto-engineer/app-implementer',
|
|
12
|
+
'@auto-engineer/component-implementor-react',
|
|
13
13
|
'@auto-engineer/dev-server',
|
|
14
14
|
],
|
|
15
15
|
pipeline: createKanbanFullPipeline(),
|