@tpitre/story-ui 3.2.0 → 3.3.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/dist/cli/index.js +0 -29
- package/dist/mcp-server/index.js +20 -65
- package/dist/mcp-server/mcp-stdio-server.js +40 -109
- package/dist/mcp-server/routes/generateStory.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStory.js +46 -117
- package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -1
- package/dist/mcp-server/routes/generateStoryStream.js +30 -72
- package/dist/mcp-server/routes/mcpRemote.d.ts +7 -3
- package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -1
- package/dist/mcp-server/routes/mcpRemote.js +353 -254
- package/dist/story-generator/generateStory.d.ts.map +1 -1
- package/dist/story-generator/generateStory.js +25 -0
- package/package.json +2 -2
- package/dist/mcp-server/routes/hybridStories.d.ts +0 -18
- package/dist/mcp-server/routes/hybridStories.d.ts.map +0 -1
- package/dist/mcp-server/routes/hybridStories.js +0 -216
- package/dist/mcp-server/routes/memoryStories.d.ts +0 -26
- package/dist/mcp-server/routes/memoryStories.d.ts.map +0 -1
- package/dist/mcp-server/routes/memoryStories.js +0 -158
- package/dist/mcp-server/routes/storySync.d.ts +0 -26
- package/dist/mcp-server/routes/storySync.d.ts.map +0 -1
- package/dist/mcp-server/routes/storySync.js +0 -147
- package/dist/mcp-server/sessionManager.d.ts +0 -50
- package/dist/mcp-server/sessionManager.d.ts.map +0 -1
- package/dist/mcp-server/sessionManager.js +0 -125
- package/dist/story-generator/inMemoryStoryService.d.ts +0 -89
- package/dist/story-generator/inMemoryStoryService.d.ts.map +0 -1
- package/dist/story-generator/inMemoryStoryService.js +0 -128
- package/dist/story-generator/postgresStoryService.d.ts +0 -56
- package/dist/story-generator/postgresStoryService.d.ts.map +0 -1
- package/dist/story-generator/postgresStoryService.js +0 -240
- package/dist/story-generator/productionGitignoreManager.d.ts +0 -91
- package/dist/story-generator/productionGitignoreManager.d.ts.map +0 -1
- package/dist/story-generator/productionGitignoreManager.js +0 -340
- package/dist/story-generator/storyServiceFactory.d.ts +0 -22
- package/dist/story-generator/storyServiceFactory.d.ts.map +0 -1
- package/dist/story-generator/storyServiceFactory.js +0 -97
- package/dist/story-generator/storyServiceInterface.d.ts +0 -85
- package/dist/story-generator/storyServiceInterface.d.ts.map +0 -1
- package/dist/story-generator/storyServiceInterface.js +0 -5
- package/dist/story-generator/storySync.d.ts +0 -68
- package/dist/story-generator/storySync.d.ts.map +0 -1
- package/dist/story-generator/storySync.js +0 -201
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
interface SessionStory {
|
|
2
|
-
id: string;
|
|
3
|
-
fileName: string;
|
|
4
|
-
title: string;
|
|
5
|
-
prompt: string;
|
|
6
|
-
timestamp: Date;
|
|
7
|
-
keywords: string[];
|
|
8
|
-
}
|
|
9
|
-
export declare class SessionManager {
|
|
10
|
-
private static instance;
|
|
11
|
-
private sessions;
|
|
12
|
-
private currentStoryId;
|
|
13
|
-
private constructor();
|
|
14
|
-
static getInstance(): SessionManager;
|
|
15
|
-
/**
|
|
16
|
-
* Track a newly generated story in the current session
|
|
17
|
-
*/
|
|
18
|
-
trackStory(sessionId: string, story: {
|
|
19
|
-
id: string;
|
|
20
|
-
fileName: string;
|
|
21
|
-
title: string;
|
|
22
|
-
prompt: string;
|
|
23
|
-
}): void;
|
|
24
|
-
/**
|
|
25
|
-
* Get the current story being discussed
|
|
26
|
-
*/
|
|
27
|
-
getCurrentStory(sessionId: string): SessionStory | null;
|
|
28
|
-
/**
|
|
29
|
-
* Find a story by context (keywords in the user's message)
|
|
30
|
-
*/
|
|
31
|
-
findStoryByContext(sessionId: string, userMessage: string): SessionStory | null;
|
|
32
|
-
/**
|
|
33
|
-
* Get all stories in the current session
|
|
34
|
-
*/
|
|
35
|
-
getSessionStories(sessionId: string): SessionStory[];
|
|
36
|
-
/**
|
|
37
|
-
* Set the current story being discussed
|
|
38
|
-
*/
|
|
39
|
-
setCurrentStory(sessionId: string, storyId: string): void;
|
|
40
|
-
/**
|
|
41
|
-
* Clear session data (for cleanup)
|
|
42
|
-
*/
|
|
43
|
-
clearSession(sessionId: string): void;
|
|
44
|
-
/**
|
|
45
|
-
* Extract meaningful keywords from text
|
|
46
|
-
*/
|
|
47
|
-
private extractKeywords;
|
|
48
|
-
}
|
|
49
|
-
export {};
|
|
50
|
-
//# sourceMappingURL=sessionManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sessionManager.d.ts","sourceRoot":"","sources":["../../mcp-server/sessionManager.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,cAAc,CAAuB;IAE7C,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,cAAc;IAOpC;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QACnC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;KAChB;IAmBD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IASvD;;OAEG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAiC/E;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,EAAE;IAIpD;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAQlD;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM;IAO9B;;OAEG;IACH,OAAO,CAAC,eAAe;CAkCxB"}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
export class SessionManager {
|
|
2
|
-
constructor() {
|
|
3
|
-
this.sessions = new Map();
|
|
4
|
-
this.currentStoryId = null;
|
|
5
|
-
}
|
|
6
|
-
static getInstance() {
|
|
7
|
-
if (!SessionManager.instance) {
|
|
8
|
-
SessionManager.instance = new SessionManager();
|
|
9
|
-
}
|
|
10
|
-
return SessionManager.instance;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Track a newly generated story in the current session
|
|
14
|
-
*/
|
|
15
|
-
trackStory(sessionId, story) {
|
|
16
|
-
const sessionStories = this.sessions.get(sessionId) || [];
|
|
17
|
-
// Extract keywords from prompt and title for smart matching
|
|
18
|
-
const keywords = this.extractKeywords(story.prompt + ' ' + story.title);
|
|
19
|
-
const sessionStory = {
|
|
20
|
-
...story,
|
|
21
|
-
timestamp: new Date(),
|
|
22
|
-
keywords
|
|
23
|
-
};
|
|
24
|
-
sessionStories.push(sessionStory);
|
|
25
|
-
this.sessions.set(sessionId, sessionStories);
|
|
26
|
-
this.currentStoryId = story.id;
|
|
27
|
-
console.error(`[SessionManager] Tracked story: ${story.title} (${story.id}) for session ${sessionId}`);
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Get the current story being discussed
|
|
31
|
-
*/
|
|
32
|
-
getCurrentStory(sessionId) {
|
|
33
|
-
const stories = this.sessions.get(sessionId) || [];
|
|
34
|
-
if (this.currentStoryId) {
|
|
35
|
-
return stories.find(s => s.id === this.currentStoryId) || null;
|
|
36
|
-
}
|
|
37
|
-
// Return the most recent story if no current story is set
|
|
38
|
-
return stories[stories.length - 1] || null;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Find a story by context (keywords in the user's message)
|
|
42
|
-
*/
|
|
43
|
-
findStoryByContext(sessionId, userMessage) {
|
|
44
|
-
const stories = this.sessions.get(sessionId) || [];
|
|
45
|
-
if (stories.length === 0)
|
|
46
|
-
return null;
|
|
47
|
-
const messageKeywords = this.extractKeywords(userMessage.toLowerCase());
|
|
48
|
-
// Score each story based on keyword matches
|
|
49
|
-
const scoredStories = stories.map(story => {
|
|
50
|
-
const score = story.keywords.filter(keyword => messageKeywords.some(msgKeyword => msgKeyword.includes(keyword) || keyword.includes(msgKeyword))).length;
|
|
51
|
-
return { story, score };
|
|
52
|
-
});
|
|
53
|
-
// Sort by score and recency
|
|
54
|
-
scoredStories.sort((a, b) => {
|
|
55
|
-
if (a.score !== b.score)
|
|
56
|
-
return b.score - a.score;
|
|
57
|
-
return b.story.timestamp.getTime() - a.story.timestamp.getTime();
|
|
58
|
-
});
|
|
59
|
-
// Return the best match if it has any keyword matches
|
|
60
|
-
if (scoredStories[0].score > 0) {
|
|
61
|
-
this.currentStoryId = scoredStories[0].story.id;
|
|
62
|
-
console.error(`[SessionManager] Found story by context: ${scoredStories[0].story.title} (score: ${scoredStories[0].score})`);
|
|
63
|
-
return scoredStories[0].story;
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Get all stories in the current session
|
|
69
|
-
*/
|
|
70
|
-
getSessionStories(sessionId) {
|
|
71
|
-
return this.sessions.get(sessionId) || [];
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Set the current story being discussed
|
|
75
|
-
*/
|
|
76
|
-
setCurrentStory(sessionId, storyId) {
|
|
77
|
-
const stories = this.sessions.get(sessionId) || [];
|
|
78
|
-
if (stories.some(s => s.id === storyId)) {
|
|
79
|
-
this.currentStoryId = storyId;
|
|
80
|
-
console.error(`[SessionManager] Set current story to: ${storyId}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Clear session data (for cleanup)
|
|
85
|
-
*/
|
|
86
|
-
clearSession(sessionId) {
|
|
87
|
-
this.sessions.delete(sessionId);
|
|
88
|
-
if (this.currentStoryId) {
|
|
89
|
-
this.currentStoryId = null;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Extract meaningful keywords from text
|
|
94
|
-
*/
|
|
95
|
-
extractKeywords(text) {
|
|
96
|
-
// Remove common words and extract meaningful terms
|
|
97
|
-
const commonWords = new Set([
|
|
98
|
-
'a', 'an', 'the', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
|
99
|
-
'of', 'with', 'by', 'from', 'up', 'about', 'into', 'through', 'during',
|
|
100
|
-
'before', 'after', 'above', 'below', 'between', 'under', 'again', 'further',
|
|
101
|
-
'then', 'once', 'create', 'make', 'generate', 'build', 'add', 'update',
|
|
102
|
-
'component', 'story', 'please', 'should', 'would', 'could'
|
|
103
|
-
]);
|
|
104
|
-
const words = text.toLowerCase()
|
|
105
|
-
.replace(/[^a-z0-9\s]/g, ' ')
|
|
106
|
-
.split(/\s+/)
|
|
107
|
-
.filter(word => word.length > 2 && !commonWords.has(word));
|
|
108
|
-
// Also extract compound terms (like "toast notification")
|
|
109
|
-
const phrases = [];
|
|
110
|
-
const importantPhrases = [
|
|
111
|
-
'toast notification', 'banner notification', 'success message',
|
|
112
|
-
'error message', 'warning message', 'info message',
|
|
113
|
-
'dark mode', 'light mode', 'switch', 'toggle', 'button',
|
|
114
|
-
'card', 'alert', 'modal', 'dialog', 'form', 'input',
|
|
115
|
-
'table', 'list', 'grid', 'layout', 'navigation', 'menu'
|
|
116
|
-
];
|
|
117
|
-
const lowerText = text.toLowerCase();
|
|
118
|
-
for (const phrase of importantPhrases) {
|
|
119
|
-
if (lowerText.includes(phrase)) {
|
|
120
|
-
phrases.push(phrase);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
return [...new Set([...words, ...phrases])];
|
|
124
|
-
}
|
|
125
|
-
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { StoryUIConfig } from '../story-ui.config.js';
|
|
2
|
-
/**
|
|
3
|
-
* In-memory story service for production environments
|
|
4
|
-
* Stores generated stories in memory and serves them via API
|
|
5
|
-
*/
|
|
6
|
-
export declare class InMemoryStoryService {
|
|
7
|
-
private stories;
|
|
8
|
-
private config;
|
|
9
|
-
constructor(config: StoryUIConfig);
|
|
10
|
-
/**
|
|
11
|
-
* Stores a generated story in memory
|
|
12
|
-
*/
|
|
13
|
-
storeStory(story: GeneratedStory): void;
|
|
14
|
-
/**
|
|
15
|
-
* Retrieves a story by ID
|
|
16
|
-
*/
|
|
17
|
-
getStory(id: string): GeneratedStory | null;
|
|
18
|
-
/**
|
|
19
|
-
* Gets all stored stories
|
|
20
|
-
*/
|
|
21
|
-
getAllStories(): GeneratedStory[];
|
|
22
|
-
/**
|
|
23
|
-
* Deletes a story by ID
|
|
24
|
-
*/
|
|
25
|
-
deleteStory(id: string): boolean;
|
|
26
|
-
/**
|
|
27
|
-
* Clears all stories
|
|
28
|
-
*/
|
|
29
|
-
clearAllStories(): void;
|
|
30
|
-
/**
|
|
31
|
-
* Gets story content for Storybook integration
|
|
32
|
-
*/
|
|
33
|
-
getStoryContent(id: string): string | null;
|
|
34
|
-
/**
|
|
35
|
-
* Gets story metadata for listing
|
|
36
|
-
*/
|
|
37
|
-
getStoryMetadata(): StoryMetadata[];
|
|
38
|
-
/**
|
|
39
|
-
* Cleans up old stories to prevent memory leaks
|
|
40
|
-
*/
|
|
41
|
-
private cleanupOldStories;
|
|
42
|
-
/**
|
|
43
|
-
* Counts components used in a story
|
|
44
|
-
*/
|
|
45
|
-
private countComponents;
|
|
46
|
-
/**
|
|
47
|
-
* Gets memory usage statistics
|
|
48
|
-
*/
|
|
49
|
-
getMemoryStats(): MemoryStats;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Generated story interface
|
|
53
|
-
*/
|
|
54
|
-
export interface GeneratedStory {
|
|
55
|
-
id: string;
|
|
56
|
-
title: string;
|
|
57
|
-
description: string;
|
|
58
|
-
content: string;
|
|
59
|
-
createdAt: Date;
|
|
60
|
-
lastAccessed: Date;
|
|
61
|
-
prompt?: string;
|
|
62
|
-
components?: string[];
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Story metadata for listing
|
|
66
|
-
*/
|
|
67
|
-
export interface StoryMetadata {
|
|
68
|
-
id: string;
|
|
69
|
-
title: string;
|
|
70
|
-
description: string;
|
|
71
|
-
createdAt: Date;
|
|
72
|
-
lastAccessed: Date;
|
|
73
|
-
componentCount: number;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Memory usage statistics
|
|
77
|
-
*/
|
|
78
|
-
export interface MemoryStats {
|
|
79
|
-
storyCount: number;
|
|
80
|
-
totalSizeBytes: number;
|
|
81
|
-
averageSizeBytes: number;
|
|
82
|
-
oldestStory: Date | null;
|
|
83
|
-
newestStory: Date | null;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Gets or creates the global story service instance
|
|
87
|
-
*/
|
|
88
|
-
export declare function getInMemoryStoryService(config: StoryUIConfig): InMemoryStoryService;
|
|
89
|
-
//# sourceMappingURL=inMemoryStoryService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inMemoryStoryService.d.ts","sourceRoot":"","sources":["../../story-generator/inMemoryStoryService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,EAAE,aAAa;IAIjC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAWvC;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAS3C;;OAEG;IACH,aAAa,IAAI,cAAc,EAAE;IAMjC;;OAEG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,eAAe,IAAI,IAAI;IAIvB;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAK1C;;OAEG;IACH,gBAAgB,IAAI,aAAa,EAAE;IAWnC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwBzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,cAAc,IAAI,WAAW;CAgB9B;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,EAAE,IAAI,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B;AAOD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,aAAa,GAAG,oBAAoB,CAKnF"}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In-memory story service for production environments
|
|
3
|
-
* Stores generated stories in memory and serves them via API
|
|
4
|
-
*/
|
|
5
|
-
export class InMemoryStoryService {
|
|
6
|
-
constructor(config) {
|
|
7
|
-
this.stories = new Map();
|
|
8
|
-
this.config = config;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Stores a generated story in memory
|
|
12
|
-
*/
|
|
13
|
-
storeStory(story) {
|
|
14
|
-
this.stories.set(story.id, {
|
|
15
|
-
...story,
|
|
16
|
-
createdAt: new Date(),
|
|
17
|
-
lastAccessed: new Date()
|
|
18
|
-
});
|
|
19
|
-
// Clean up old stories to prevent memory leaks
|
|
20
|
-
this.cleanupOldStories();
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Retrieves a story by ID
|
|
24
|
-
*/
|
|
25
|
-
getStory(id) {
|
|
26
|
-
const story = this.stories.get(id);
|
|
27
|
-
if (story) {
|
|
28
|
-
story.lastAccessed = new Date();
|
|
29
|
-
return story;
|
|
30
|
-
}
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Gets all stored stories
|
|
35
|
-
*/
|
|
36
|
-
getAllStories() {
|
|
37
|
-
return Array.from(this.stories.values()).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Deletes a story by ID
|
|
41
|
-
*/
|
|
42
|
-
deleteStory(id) {
|
|
43
|
-
return this.stories.delete(id);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Clears all stories
|
|
47
|
-
*/
|
|
48
|
-
clearAllStories() {
|
|
49
|
-
this.stories.clear();
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Gets story content for Storybook integration
|
|
53
|
-
*/
|
|
54
|
-
getStoryContent(id) {
|
|
55
|
-
const story = this.stories.get(id);
|
|
56
|
-
return story ? story.content : null;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Gets story metadata for listing
|
|
60
|
-
*/
|
|
61
|
-
getStoryMetadata() {
|
|
62
|
-
return Array.from(this.stories.values()).map(story => ({
|
|
63
|
-
id: story.id,
|
|
64
|
-
title: story.title,
|
|
65
|
-
description: story.description,
|
|
66
|
-
createdAt: story.createdAt,
|
|
67
|
-
lastAccessed: story.lastAccessed,
|
|
68
|
-
componentCount: this.countComponents(story.content)
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Cleans up old stories to prevent memory leaks
|
|
73
|
-
*/
|
|
74
|
-
cleanupOldStories() {
|
|
75
|
-
const maxStories = 50; // Keep maximum 50 stories in memory
|
|
76
|
-
const maxAge = 24 * 60 * 60 * 1000; // 24 hours
|
|
77
|
-
const now = Date.now();
|
|
78
|
-
// Remove stories older than maxAge
|
|
79
|
-
for (const [id, story] of this.stories.entries()) {
|
|
80
|
-
if (now - story.lastAccessed.getTime() > maxAge) {
|
|
81
|
-
this.stories.delete(id);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// If still too many stories, remove oldest ones
|
|
85
|
-
if (this.stories.size > maxStories) {
|
|
86
|
-
const sortedStories = Array.from(this.stories.entries())
|
|
87
|
-
.sort(([, a], [, b]) => a.lastAccessed.getTime() - b.lastAccessed.getTime());
|
|
88
|
-
const toRemove = sortedStories.slice(0, this.stories.size - maxStories);
|
|
89
|
-
for (const [id] of toRemove) {
|
|
90
|
-
this.stories.delete(id);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Counts components used in a story
|
|
96
|
-
*/
|
|
97
|
-
countComponents(content) {
|
|
98
|
-
const componentMatches = content.match(/<[A-Z][A-Za-z0-9]*\s/g);
|
|
99
|
-
return componentMatches ? new Set(componentMatches).size : 0;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Gets memory usage statistics
|
|
103
|
-
*/
|
|
104
|
-
getMemoryStats() {
|
|
105
|
-
const stories = Array.from(this.stories.values());
|
|
106
|
-
const totalSize = stories.reduce((sum, story) => sum + story.content.length, 0);
|
|
107
|
-
return {
|
|
108
|
-
storyCount: this.stories.size,
|
|
109
|
-
totalSizeBytes: totalSize,
|
|
110
|
-
averageSizeBytes: stories.length > 0 ? Math.round(totalSize / stories.length) : 0,
|
|
111
|
-
oldestStory: stories.reduce((oldest, story) => !oldest || story.createdAt < oldest.createdAt ? story : oldest, null)?.createdAt || null,
|
|
112
|
-
newestStory: stories.reduce((newest, story) => !newest || story.createdAt > newest.createdAt ? story : newest, null)?.createdAt || null
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Global in-memory story service instance
|
|
118
|
-
*/
|
|
119
|
-
let globalStoryService = null;
|
|
120
|
-
/**
|
|
121
|
-
* Gets or creates the global story service instance
|
|
122
|
-
*/
|
|
123
|
-
export function getInMemoryStoryService(config) {
|
|
124
|
-
if (!globalStoryService) {
|
|
125
|
-
globalStoryService = new InMemoryStoryService(config);
|
|
126
|
-
}
|
|
127
|
-
return globalStoryService;
|
|
128
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import type { IStoryService, GeneratedStory, StoryMetadata, StorageStats } from './storyServiceInterface.js';
|
|
2
|
-
/**
|
|
3
|
-
* PostgreSQL Story Service
|
|
4
|
-
* Persistent story storage using PostgreSQL database
|
|
5
|
-
* Designed for Railway PostgreSQL deployments
|
|
6
|
-
*/
|
|
7
|
-
export declare class PostgresStoryService implements IStoryService {
|
|
8
|
-
private pool;
|
|
9
|
-
private initialized;
|
|
10
|
-
constructor(connectionString: string);
|
|
11
|
-
/**
|
|
12
|
-
* Initialize database schema
|
|
13
|
-
*/
|
|
14
|
-
initialize(): Promise<void>;
|
|
15
|
-
/**
|
|
16
|
-
* Store a generated story
|
|
17
|
-
*/
|
|
18
|
-
storeStory(story: GeneratedStory): Promise<void>;
|
|
19
|
-
/**
|
|
20
|
-
* Retrieve a story by ID
|
|
21
|
-
*/
|
|
22
|
-
getStory(id: string): Promise<GeneratedStory | null>;
|
|
23
|
-
/**
|
|
24
|
-
* Get all stored stories
|
|
25
|
-
*/
|
|
26
|
-
getAllStories(): Promise<GeneratedStory[]>;
|
|
27
|
-
/**
|
|
28
|
-
* Delete a story by ID
|
|
29
|
-
*/
|
|
30
|
-
deleteStory(id: string): Promise<boolean>;
|
|
31
|
-
/**
|
|
32
|
-
* Clear all stories
|
|
33
|
-
*/
|
|
34
|
-
clearAllStories(): Promise<void>;
|
|
35
|
-
/**
|
|
36
|
-
* Get story content for Storybook integration
|
|
37
|
-
*/
|
|
38
|
-
getStoryContent(id: string): Promise<string | null>;
|
|
39
|
-
/**
|
|
40
|
-
* Get story metadata for listing
|
|
41
|
-
*/
|
|
42
|
-
getStoryMetadata(): Promise<StoryMetadata[]>;
|
|
43
|
-
/**
|
|
44
|
-
* Get storage usage statistics
|
|
45
|
-
*/
|
|
46
|
-
getStorageStats(): Promise<StorageStats>;
|
|
47
|
-
/**
|
|
48
|
-
* Count unique components in story content
|
|
49
|
-
*/
|
|
50
|
-
private countComponents;
|
|
51
|
-
/**
|
|
52
|
-
* Close the connection pool
|
|
53
|
-
*/
|
|
54
|
-
close(): Promise<void>;
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=postgresStoryService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"postgresStoryService.d.ts","sourceRoot":"","sources":["../../story-generator/postgresStoryService.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI7G;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IACxD,OAAO,CAAC,IAAI,CAAU;IACtB,OAAO,CAAC,WAAW,CAAkB;gBAEzB,gBAAgB,EAAE,MAAM;IAUpC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA4BjC;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCtD;;OAEG;IACG,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAiC1D;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IA0BhD;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAmB/C;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtC;;OAEG;IACG,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKzD;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAwBlD;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IA4B9C;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|