@things-factory/shell 9.0.25 → 9.0.34

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 (29) hide show
  1. package/dist-server/process-cleaner.d.ts +33 -0
  2. package/dist-server/process-cleaner.js +70 -75
  3. package/dist-server/process-cleaner.js.map +1 -1
  4. package/dist-server/pubsub.js +0 -23
  5. package/dist-server/pubsub.js.map +1 -1
  6. package/dist-server/server-dev.js +1 -0
  7. package/dist-server/server-dev.js.map +1 -1
  8. package/dist-server/server.js +1 -0
  9. package/dist-server/server.js.map +1 -1
  10. package/dist-server/tsconfig.tsbuildinfo +1 -1
  11. package/dist-server/utils/headless-pool/browser-factory.d.ts +27 -0
  12. package/dist-server/utils/headless-pool/browser-factory.js +144 -0
  13. package/dist-server/utils/headless-pool/browser-factory.js.map +1 -0
  14. package/dist-server/utils/headless-pool/config.d.ts +25 -0
  15. package/dist-server/utils/headless-pool/config.js +72 -0
  16. package/dist-server/utils/headless-pool/config.js.map +1 -0
  17. package/dist-server/utils/headless-pool/index.d.ts +98 -0
  18. package/dist-server/utils/headless-pool/index.js +131 -0
  19. package/dist-server/utils/headless-pool/index.js.map +1 -0
  20. package/dist-server/utils/headless-pool/pool-manager.d.ts +59 -0
  21. package/dist-server/utils/headless-pool/pool-manager.js +212 -0
  22. package/dist-server/utils/headless-pool/pool-manager.js.map +1 -0
  23. package/dist-server/utils/headless-pool/pool-stats.d.ts +29 -0
  24. package/dist-server/utils/headless-pool/pool-stats.js +80 -0
  25. package/dist-server/utils/headless-pool/pool-stats.js.map +1 -0
  26. package/dist-server/utils/index.d.ts +1 -0
  27. package/dist-server/utils/index.js +1 -0
  28. package/dist-server/utils/index.js.map +1 -1
  29. package/package.json +4 -2
@@ -0,0 +1,27 @@
1
+ import { HeadlessPoolConfig } from './config';
2
+ /**
3
+ * Browser Factory for creating and managing browser instances
4
+ */
5
+ export declare class BrowserFactory {
6
+ /**
7
+ * Create a new browser instance
8
+ */
9
+ static createBrowser(poolConfig: HeadlessPoolConfig): Promise<any>;
10
+ /**
11
+ * Validate browser instance
12
+ */
13
+ static validateBrowser(browser: any): Promise<boolean>;
14
+ /**
15
+ * Safely destroy browser instance with multiple cleanup strategies
16
+ */
17
+ static destroyBrowser(browser: any): Promise<void>;
18
+ private static gracefulDestroy;
19
+ /**
20
+ * Create browser with custom setup (for special cases like label pool)
21
+ */
22
+ static createBrowserWithSetup(poolConfig: HeadlessPoolConfig, customSetup: (browser: any) => Promise<any>): Promise<any>;
23
+ private static getLaunchSettings;
24
+ private static closeAllPages;
25
+ private static killBrowserProcess;
26
+ private static forceKillProcess;
27
+ }
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BrowserFactory = void 0;
4
+ const env_1 = require("@things-factory/env");
5
+ // Dynamic puppeteer loading with error handling
6
+ let puppeteer;
7
+ try {
8
+ puppeteer = require('puppeteer');
9
+ }
10
+ catch (err) {
11
+ env_1.logger.warn('Puppeteer not available:', err);
12
+ }
13
+ /**
14
+ * Browser Factory for creating and managing browser instances
15
+ */
16
+ class BrowserFactory {
17
+ /**
18
+ * Create a new browser instance
19
+ */
20
+ static async createBrowser(poolConfig) {
21
+ if (!puppeteer) {
22
+ throw new Error('Puppeteer is not available');
23
+ }
24
+ const launchSettings = this.getLaunchSettings(poolConfig);
25
+ try {
26
+ const browser = await puppeteer.launch(launchSettings);
27
+ env_1.logger.info(`Browser instance created with headless: ${launchSettings.headless}`);
28
+ return browser;
29
+ }
30
+ catch (error) {
31
+ env_1.logger.error('Failed to create browser instance:', error);
32
+ throw error;
33
+ }
34
+ }
35
+ /**
36
+ * Validate browser instance
37
+ */
38
+ static validateBrowser(browser) {
39
+ return Promise.race([
40
+ new Promise(resolve => setTimeout(() => resolve(false), 1500)),
41
+ browser
42
+ .version()
43
+ .then(() => true)
44
+ .catch(() => false)
45
+ ]);
46
+ }
47
+ /**
48
+ * Safely destroy browser instance with multiple cleanup strategies
49
+ */
50
+ static async destroyBrowser(browser) {
51
+ const timeout = 5000; // 5 second timeout
52
+ try {
53
+ await Promise.race([
54
+ this.gracefulDestroy(browser),
55
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Browser destruction timeout')), timeout))
56
+ ]);
57
+ env_1.logger.info('🗑️ Browser instance destroyed successfully');
58
+ }
59
+ catch (error) {
60
+ env_1.logger.warn('⚠️ Error destroying browser instance:', error);
61
+ // Force kill as last resort
62
+ await this.forceKillProcess(browser);
63
+ }
64
+ }
65
+ static async gracefulDestroy(browser) {
66
+ // Step 1: Close all pages
67
+ await this.closeAllPages(browser);
68
+ // Step 2: Standard close
69
+ await browser.close();
70
+ // Step 3: Kill browser process if still running
71
+ await this.killBrowserProcess(browser);
72
+ }
73
+ /**
74
+ * Create browser with custom setup (for special cases like label pool)
75
+ */
76
+ static async createBrowserWithSetup(poolConfig, customSetup) {
77
+ const browser = await this.createBrowser(poolConfig);
78
+ try {
79
+ const result = await customSetup(browser);
80
+ return result;
81
+ }
82
+ catch (error) {
83
+ // If setup fails, cleanup the browser
84
+ await this.destroyBrowser(browser);
85
+ throw error;
86
+ }
87
+ }
88
+ static getLaunchSettings(poolConfig) {
89
+ const settings = {
90
+ headless: poolConfig.headless || 'shell',
91
+ args: [...(poolConfig.args || [])],
92
+ handleSIGINT: false, // ★ 기본 핸들러 해제
93
+ handleSIGTERM: false,
94
+ handleSIGHUP: false
95
+ };
96
+ // Add executable path if specified in config or environment
97
+ const executablePath = poolConfig.executablePath || env_1.config.get('CHROMIUM_PATH');
98
+ if (executablePath) {
99
+ settings.executablePath = executablePath;
100
+ }
101
+ return settings;
102
+ }
103
+ static async closeAllPages(browser) {
104
+ try {
105
+ const pages = await browser.pages();
106
+ await Promise.all(pages.map((page) => page.close().catch(() => { })));
107
+ }
108
+ catch (error) {
109
+ env_1.logger.warn('Failed to close pages:', error);
110
+ }
111
+ }
112
+ static async killBrowserProcess(browser) {
113
+ try {
114
+ const process = browser.process();
115
+ if (process && !process.killed) {
116
+ // Try graceful termination first
117
+ process.kill('SIGTERM');
118
+ // Wait a bit, then force kill if still alive
119
+ await new Promise(resolve => setTimeout(resolve, 1000));
120
+ if (!process.killed) {
121
+ process.kill('SIGKILL');
122
+ env_1.logger.info('🔪 Browser process force killed');
123
+ }
124
+ }
125
+ }
126
+ catch (error) {
127
+ env_1.logger.warn('Failed to kill browser process:', error);
128
+ }
129
+ }
130
+ static async forceKillProcess(browser) {
131
+ try {
132
+ const process = browser.process();
133
+ if (process && !process.killed) {
134
+ process.kill('SIGKILL');
135
+ env_1.logger.info('💀 Browser process force killed');
136
+ }
137
+ }
138
+ catch (killError) {
139
+ env_1.logger.error('💀 Failed to force kill browser process:', killError);
140
+ }
141
+ }
142
+ }
143
+ exports.BrowserFactory = BrowserFactory;
144
+ //# sourceMappingURL=browser-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-factory.js","sourceRoot":"","sources":["../../../server/utils/headless-pool/browser-factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { config, logger } from '@things-factory/env'\nimport { HeadlessPoolConfig } from './config'\n\n// Dynamic puppeteer loading with error handling\nlet puppeteer: any\ntry {\n puppeteer = require('puppeteer')\n} catch (err) {\n logger.warn('Puppeteer not available:', err)\n}\n\n/**\n * Browser Factory for creating and managing browser instances\n */\nexport class BrowserFactory {\n /**\n * Create a new browser instance\n */\n static async createBrowser(poolConfig: HeadlessPoolConfig): Promise<any> {\n if (!puppeteer) {\n throw new Error('Puppeteer is not available')\n }\n\n const launchSettings = this.getLaunchSettings(poolConfig)\n\n try {\n const browser = await puppeteer.launch(launchSettings)\n logger.info(`Browser instance created with headless: ${launchSettings.headless}`)\n return browser\n } catch (error) {\n logger.error('Failed to create browser instance:', error)\n throw error\n }\n }\n\n /**\n * Validate browser instance\n */\n static validateBrowser(browser: any): Promise<boolean> {\n return Promise.race([\n new Promise<boolean>(resolve => setTimeout(() => resolve(false), 1500)),\n browser\n .version()\n .then(() => true)\n .catch(() => false)\n ])\n }\n\n /**\n * Safely destroy browser instance with multiple cleanup strategies\n */\n static async destroyBrowser(browser: any): Promise<void> {\n const timeout = 5000 // 5 second timeout\n\n try {\n await Promise.race([\n this.gracefulDestroy(browser),\n new Promise((_, reject) => setTimeout(() => reject(new Error('Browser destruction timeout')), timeout))\n ])\n\n logger.info('🗑️ Browser instance destroyed successfully')\n } catch (error) {\n logger.warn('⚠️ Error destroying browser instance:', error)\n\n // Force kill as last resort\n await this.forceKillProcess(browser)\n }\n }\n\n private static async gracefulDestroy(browser: any): Promise<void> {\n // Step 1: Close all pages\n await this.closeAllPages(browser)\n\n // Step 2: Standard close\n await browser.close()\n\n // Step 3: Kill browser process if still running\n await this.killBrowserProcess(browser)\n }\n\n /**\n * Create browser with custom setup (for special cases like label pool)\n */\n static async createBrowserWithSetup(\n poolConfig: HeadlessPoolConfig,\n customSetup: (browser: any) => Promise<any>\n ): Promise<any> {\n const browser = await this.createBrowser(poolConfig)\n\n try {\n const result = await customSetup(browser)\n return result\n } catch (error) {\n // If setup fails, cleanup the browser\n await this.destroyBrowser(browser)\n throw error\n }\n }\n\n private static getLaunchSettings(poolConfig: HeadlessPoolConfig) {\n const settings: any = {\n headless: poolConfig.headless || 'shell',\n args: [...(poolConfig.args || [])],\n handleSIGINT: false, // ★ 기본 핸들러 해제\n handleSIGTERM: false,\n handleSIGHUP: false\n }\n\n // Add executable path if specified in config or environment\n const executablePath = poolConfig.executablePath || config.get('CHROMIUM_PATH')\n if (executablePath) {\n settings.executablePath = executablePath\n }\n\n return settings\n }\n\n private static async closeAllPages(browser: any): Promise<void> {\n try {\n const pages = await browser.pages()\n await Promise.all(pages.map((page: any) => page.close().catch(() => {})))\n } catch (error) {\n logger.warn('Failed to close pages:', error)\n }\n }\n\n private static async killBrowserProcess(browser: any): Promise<void> {\n try {\n const process = browser.process()\n if (process && !process.killed) {\n // Try graceful termination first\n process.kill('SIGTERM')\n\n // Wait a bit, then force kill if still alive\n await new Promise(resolve => setTimeout(resolve, 1000))\n\n if (!process.killed) {\n process.kill('SIGKILL')\n logger.info('🔪 Browser process force killed')\n }\n }\n } catch (error) {\n logger.warn('Failed to kill browser process:', error)\n }\n }\n\n private static async forceKillProcess(browser: any): Promise<void> {\n try {\n const process = browser.process()\n if (process && !process.killed) {\n process.kill('SIGKILL')\n logger.info('💀 Browser process force killed')\n }\n } catch (killError) {\n logger.error('💀 Failed to force kill browser process:', killError)\n }\n }\n}\n"]}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Headless Pool Configuration
3
+ */
4
+ export type HeadlessMode = 'shell' | 'new' | boolean;
5
+ export interface HeadlessPoolConfig {
6
+ min?: number;
7
+ max?: number;
8
+ acquireTimeoutMillis?: number;
9
+ idleTimeoutMillis?: number;
10
+ testOnBorrow?: boolean;
11
+ headless?: HeadlessMode;
12
+ args?: string[];
13
+ executablePath?: string;
14
+ enableStats?: boolean;
15
+ enableRecovery?: boolean;
16
+ enableCleanup?: boolean;
17
+ customSetup?: (browser: any) => Promise<any>;
18
+ }
19
+ export declare const DEFAULT_POOL_CONFIG: Required<Omit<HeadlessPoolConfig, 'customSetup'>>;
20
+ export declare const HEADLESS_POOL_ARGUMENT_SETS: {
21
+ basic: string[];
22
+ keychain_safe: string[];
23
+ security_enhanced: string[];
24
+ };
25
+ export declare function mergeConfig(base: HeadlessPoolConfig, override?: HeadlessPoolConfig): HeadlessPoolConfig;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ /**
3
+ * Headless Pool Configuration
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HEADLESS_POOL_ARGUMENT_SETS = exports.DEFAULT_POOL_CONFIG = void 0;
7
+ exports.mergeConfig = mergeConfig;
8
+ // Default configurations
9
+ exports.DEFAULT_POOL_CONFIG = {
10
+ // Pool defaults
11
+ min: 2,
12
+ max: 10,
13
+ acquireTimeoutMillis: 15000,
14
+ idleTimeoutMillis: 300000, // 5 minutes
15
+ testOnBorrow: true,
16
+ // Browser defaults
17
+ headless: 'shell',
18
+ args: [
19
+ '--hide-scrollbars',
20
+ '--mute-audio',
21
+ '--no-sandbox',
22
+ '--use-gl=egl',
23
+ '--use-mock-keychain',
24
+ '--disable-password-manager-reauthentication',
25
+ '--disable-keychain-reauthorization',
26
+ '--disable-web-security',
27
+ '--disable-site-isolation-trials',
28
+ '--disable-extensions',
29
+ '--disable-default-apps',
30
+ '--disable-component-extensions-with-background-pages',
31
+ '--disable-background-timer-throttling',
32
+ '--disable-background-networking',
33
+ '--disable-sync',
34
+ '--disable-features=TranslateUI',
35
+ '--disable-ipc-flooding-protection'
36
+ ],
37
+ executablePath: '',
38
+ // Feature defaults
39
+ enableStats: false,
40
+ enableRecovery: false,
41
+ enableCleanup: true
42
+ };
43
+ // Common argument sets
44
+ exports.HEADLESS_POOL_ARGUMENT_SETS = {
45
+ basic: ['--hide-scrollbars', '--mute-audio', '--no-sandbox', '--use-gl=egl'],
46
+ keychain_safe: [
47
+ '--use-mock-keychain',
48
+ '--disable-password-manager-reauthentication',
49
+ '--disable-keychain-reauthorization',
50
+ '--disable-web-security',
51
+ '--disable-site-isolation-trials',
52
+ '--disable-extensions',
53
+ '--disable-default-apps',
54
+ '--disable-component-extensions-with-background-pages',
55
+ '--disable-background-timer-throttling',
56
+ '--disable-background-networking',
57
+ '--disable-sync',
58
+ '--disable-features=TranslateUI',
59
+ '--disable-ipc-flooding-protection'
60
+ ],
61
+ security_enhanced: ['--disable-setuid-sandbox', '--disable-dev-shm-usage']
62
+ };
63
+ // Helper function to merge configs
64
+ function mergeConfig(base, override = {}) {
65
+ return {
66
+ ...exports.DEFAULT_POOL_CONFIG,
67
+ ...base,
68
+ ...override,
69
+ args: [...(base.args || exports.DEFAULT_POOL_CONFIG.args), ...(override.args || [])]
70
+ };
71
+ }
72
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../server/utils/headless-pool/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAwFH,kCAOC;AArED,yBAAyB;AACZ,QAAA,mBAAmB,GAAsD;IACpF,gBAAgB;IAChB,GAAG,EAAE,CAAC;IACN,GAAG,EAAE,EAAE;IACP,oBAAoB,EAAE,KAAK;IAC3B,iBAAiB,EAAE,MAAM,EAAE,YAAY;IACvC,YAAY,EAAE,IAAI;IAElB,mBAAmB;IACnB,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE;QACJ,mBAAmB;QACnB,cAAc;QACd,cAAc;QACd,cAAc;QACd,qBAAqB;QACrB,6CAA6C;QAC7C,oCAAoC;QACpC,wBAAwB;QACxB,iCAAiC;QACjC,sBAAsB;QACtB,wBAAwB;QACxB,sDAAsD;QACtD,uCAAuC;QACvC,iCAAiC;QACjC,gBAAgB;QAChB,gCAAgC;QAChC,mCAAmC;KACpC;IACD,cAAc,EAAE,EAAE;IAElB,mBAAmB;IACnB,WAAW,EAAE,KAAK;IAClB,cAAc,EAAE,KAAK;IACrB,aAAa,EAAE,IAAI;CACpB,CAAA;AAED,uBAAuB;AACV,QAAA,2BAA2B,GAAG;IACzC,KAAK,EAAE,CAAC,mBAAmB,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,CAAC;IAE5E,aAAa,EAAE;QACb,qBAAqB;QACrB,6CAA6C;QAC7C,oCAAoC;QACpC,wBAAwB;QACxB,iCAAiC;QACjC,sBAAsB;QACtB,wBAAwB;QACxB,sDAAsD;QACtD,uCAAuC;QACvC,iCAAiC;QACjC,gBAAgB;QAChB,gCAAgC;QAChC,mCAAmC;KACpC;IAED,iBAAiB,EAAE,CAAC,0BAA0B,EAAE,yBAAyB,CAAC;CAC3E,CAAA;AAED,mCAAmC;AACnC,SAAgB,WAAW,CAAC,IAAwB,EAAE,WAA+B,EAAE;IACrF,OAAO;QACL,GAAG,2BAAmB;QACtB,GAAG,IAAI;QACP,GAAG,QAAQ;QACX,IAAI,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,2BAAmB,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;KAC7E,CAAA;AACH,CAAC","sourcesContent":["/**\n * Headless Pool Configuration\n */\n\nexport type HeadlessMode = 'shell' | 'new' | boolean\n\nexport interface HeadlessPoolConfig {\n // Pool settings\n min?: number\n max?: number\n acquireTimeoutMillis?: number\n idleTimeoutMillis?: number\n testOnBorrow?: boolean\n\n // Browser launch settings\n headless?: HeadlessMode\n args?: string[]\n executablePath?: string\n\n // Features\n enableStats?: boolean\n enableRecovery?: boolean\n enableCleanup?: boolean\n\n // Custom setup function for special cases (like label pool)\n customSetup?: (browser: any) => Promise<any>\n}\n\n// Default configurations\nexport const DEFAULT_POOL_CONFIG: Required<Omit<HeadlessPoolConfig, 'customSetup'>> = {\n // Pool defaults\n min: 2,\n max: 10,\n acquireTimeoutMillis: 15000,\n idleTimeoutMillis: 300000, // 5 minutes\n testOnBorrow: true,\n\n // Browser defaults\n headless: 'shell',\n args: [\n '--hide-scrollbars',\n '--mute-audio',\n '--no-sandbox',\n '--use-gl=egl',\n '--use-mock-keychain',\n '--disable-password-manager-reauthentication',\n '--disable-keychain-reauthorization',\n '--disable-web-security',\n '--disable-site-isolation-trials',\n '--disable-extensions',\n '--disable-default-apps',\n '--disable-component-extensions-with-background-pages',\n '--disable-background-timer-throttling',\n '--disable-background-networking',\n '--disable-sync',\n '--disable-features=TranslateUI',\n '--disable-ipc-flooding-protection'\n ],\n executablePath: '',\n\n // Feature defaults\n enableStats: false,\n enableRecovery: false,\n enableCleanup: true\n}\n\n// Common argument sets\nexport const HEADLESS_POOL_ARGUMENT_SETS = {\n basic: ['--hide-scrollbars', '--mute-audio', '--no-sandbox', '--use-gl=egl'],\n\n keychain_safe: [\n '--use-mock-keychain',\n '--disable-password-manager-reauthentication',\n '--disable-keychain-reauthorization',\n '--disable-web-security',\n '--disable-site-isolation-trials',\n '--disable-extensions',\n '--disable-default-apps',\n '--disable-component-extensions-with-background-pages',\n '--disable-background-timer-throttling',\n '--disable-background-networking',\n '--disable-sync',\n '--disable-features=TranslateUI',\n '--disable-ipc-flooding-protection'\n ],\n\n security_enhanced: ['--disable-setuid-sandbox', '--disable-dev-shm-usage']\n}\n\n// Helper function to merge configs\nexport function mergeConfig(base: HeadlessPoolConfig, override: HeadlessPoolConfig = {}): HeadlessPoolConfig {\n return {\n ...DEFAULT_POOL_CONFIG,\n ...base,\n ...override,\n args: [...(base.args || DEFAULT_POOL_CONFIG.args), ...(override.args || [])]\n }\n}\n"]}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Unified Headless Pool System for Things Factory
3
+ *
4
+ * This module provides a centralized headless browser pool system
5
+ * that can be used across all Things Factory packages.
6
+ */
7
+ import { HeadlessPool } from './pool-manager';
8
+ import { HeadlessPoolConfig } from './config';
9
+ export { HeadlessPoolConfig, HEADLESS_POOL_ARGUMENT_SETS } from './config';
10
+ export { HeadlessPool, HeadlessPoolManager } from './pool-manager';
11
+ export { PoolStats } from './pool-stats';
12
+ export { BrowserFactory } from './browser-factory';
13
+ /**
14
+ * Create a new headless browser pool
15
+ *
16
+ * @param name - Unique name for the pool
17
+ * @param config - Pool configuration options
18
+ * @returns HeadlessPool instance
19
+ *
20
+ * @example
21
+ * // Create integration pool with advanced features
22
+ * const integrationPool = createHeadlessPool('integration', {
23
+ * min: 2, max: 20,
24
+ * args: [...HEADLESS_POOL_ARGUMENT_SETS.basic, ...HEADLESS_POOL_ARGUMENT_SETS.keychain_safe],
25
+ * enableStats: true,
26
+ * enableRecovery: true
27
+ * })
28
+ *
29
+ * @example
30
+ * // Create simple pool
31
+ * const myPool = createHeadlessPool('my-pool', {
32
+ * min: 1, max: 5
33
+ * })
34
+ */
35
+ export declare function createHeadlessPool(name: string, config?: HeadlessPoolConfig): HeadlessPool;
36
+ /**
37
+ * Get existing headless browser pool by name
38
+ *
39
+ * @param name - Pool name
40
+ * @returns HeadlessPool instance
41
+ * @throws Error if pool doesn't exist
42
+ */
43
+ export declare function getHeadlessPool(name: string): HeadlessPool;
44
+ /**
45
+ * Get or create headless browser pool
46
+ * If pool exists, returns it. If not, creates with provided config.
47
+ *
48
+ * @param name - Pool name
49
+ * @param config - Pool configuration (used only if creating new pool)
50
+ * @returns HeadlessPool instance
51
+ */
52
+ export declare function getOrCreateHeadlessPool(name: string, config?: HeadlessPoolConfig): HeadlessPool;
53
+ /**
54
+ * Check if pool exists
55
+ *
56
+ * @param name - Pool name
57
+ * @returns boolean
58
+ */
59
+ export declare function hasHeadlessPool(name: string): boolean;
60
+ /**
61
+ * Get statistics for all pools
62
+ *
63
+ * @returns Object containing stats for all pools
64
+ */
65
+ export declare function getAllPoolStats(): Record<string, any>;
66
+ /**
67
+ * Clean up all headless browser pools
68
+ * Typically called during application shutdown
69
+ */
70
+ export declare function cleanupAllPools(): Promise<void>;
71
+ /**
72
+ * Reset a specific pool (cleanup and recreate)
73
+ *
74
+ * @param name - Pool name
75
+ */
76
+ export declare function resetPool(name: string): Promise<void>;
77
+ /**
78
+ * Remove pool from registry
79
+ *
80
+ * @param name - Pool name
81
+ */
82
+ export declare function removePool(name: string): void;
83
+ declare const _default: {
84
+ createHeadlessPool: typeof createHeadlessPool;
85
+ getHeadlessPool: typeof getHeadlessPool;
86
+ getOrCreateHeadlessPool: typeof getOrCreateHeadlessPool;
87
+ hasHeadlessPool: typeof hasHeadlessPool;
88
+ getAllPoolStats: typeof getAllPoolStats;
89
+ cleanupAllPools: typeof cleanupAllPools;
90
+ resetPool: typeof resetPool;
91
+ removePool: typeof removePool;
92
+ HEADLESS_POOL_ARGUMENT_SETS: {
93
+ basic: string[];
94
+ keychain_safe: string[];
95
+ security_enhanced: string[];
96
+ };
97
+ };
98
+ export default _default;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ /**
3
+ * Unified Headless Pool System for Things Factory
4
+ *
5
+ * This module provides a centralized headless browser pool system
6
+ * that can be used across all Things Factory packages.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BrowserFactory = exports.PoolStats = exports.HeadlessPoolManager = exports.HeadlessPool = exports.HEADLESS_POOL_ARGUMENT_SETS = void 0;
10
+ exports.createHeadlessPool = createHeadlessPool;
11
+ exports.getHeadlessPool = getHeadlessPool;
12
+ exports.getOrCreateHeadlessPool = getOrCreateHeadlessPool;
13
+ exports.hasHeadlessPool = hasHeadlessPool;
14
+ exports.getAllPoolStats = getAllPoolStats;
15
+ exports.cleanupAllPools = cleanupAllPools;
16
+ exports.resetPool = resetPool;
17
+ exports.removePool = removePool;
18
+ const pool_manager_1 = require("./pool-manager");
19
+ const config_1 = require("./config");
20
+ // Re-export types and utilities
21
+ var config_2 = require("./config");
22
+ Object.defineProperty(exports, "HEADLESS_POOL_ARGUMENT_SETS", { enumerable: true, get: function () { return config_2.HEADLESS_POOL_ARGUMENT_SETS; } });
23
+ var pool_manager_2 = require("./pool-manager");
24
+ Object.defineProperty(exports, "HeadlessPool", { enumerable: true, get: function () { return pool_manager_2.HeadlessPool; } });
25
+ Object.defineProperty(exports, "HeadlessPoolManager", { enumerable: true, get: function () { return pool_manager_2.HeadlessPoolManager; } });
26
+ var pool_stats_1 = require("./pool-stats");
27
+ Object.defineProperty(exports, "PoolStats", { enumerable: true, get: function () { return pool_stats_1.PoolStats; } });
28
+ var browser_factory_1 = require("./browser-factory");
29
+ Object.defineProperty(exports, "BrowserFactory", { enumerable: true, get: function () { return browser_factory_1.BrowserFactory; } });
30
+ /**
31
+ * Create a new headless browser pool
32
+ *
33
+ * @param name - Unique name for the pool
34
+ * @param config - Pool configuration options
35
+ * @returns HeadlessPool instance
36
+ *
37
+ * @example
38
+ * // Create integration pool with advanced features
39
+ * const integrationPool = createHeadlessPool('integration', {
40
+ * min: 2, max: 20,
41
+ * args: [...HEADLESS_POOL_ARGUMENT_SETS.basic, ...HEADLESS_POOL_ARGUMENT_SETS.keychain_safe],
42
+ * enableStats: true,
43
+ * enableRecovery: true
44
+ * })
45
+ *
46
+ * @example
47
+ * // Create simple pool
48
+ * const myPool = createHeadlessPool('my-pool', {
49
+ * min: 1, max: 5
50
+ * })
51
+ */
52
+ function createHeadlessPool(name, config = {}) {
53
+ return pool_manager_1.HeadlessPoolManager.createPool(name, config);
54
+ }
55
+ /**
56
+ * Get existing headless browser pool by name
57
+ *
58
+ * @param name - Pool name
59
+ * @returns HeadlessPool instance
60
+ * @throws Error if pool doesn't exist
61
+ */
62
+ function getHeadlessPool(name) {
63
+ return pool_manager_1.HeadlessPoolManager.getPool(name);
64
+ }
65
+ /**
66
+ * Get or create headless browser pool
67
+ * If pool exists, returns it. If not, creates with provided config.
68
+ *
69
+ * @param name - Pool name
70
+ * @param config - Pool configuration (used only if creating new pool)
71
+ * @returns HeadlessPool instance
72
+ */
73
+ function getOrCreateHeadlessPool(name, config = {}) {
74
+ if (pool_manager_1.HeadlessPoolManager.hasPool(name)) {
75
+ return pool_manager_1.HeadlessPoolManager.getPool(name);
76
+ }
77
+ return pool_manager_1.HeadlessPoolManager.createPool(name, config);
78
+ }
79
+ /**
80
+ * Check if pool exists
81
+ *
82
+ * @param name - Pool name
83
+ * @returns boolean
84
+ */
85
+ function hasHeadlessPool(name) {
86
+ return pool_manager_1.HeadlessPoolManager.hasPool(name);
87
+ }
88
+ /**
89
+ * Get statistics for all pools
90
+ *
91
+ * @returns Object containing stats for all pools
92
+ */
93
+ function getAllPoolStats() {
94
+ return pool_manager_1.HeadlessPoolManager.getAllPoolStats();
95
+ }
96
+ /**
97
+ * Clean up all headless browser pools
98
+ * Typically called during application shutdown
99
+ */
100
+ function cleanupAllPools() {
101
+ return pool_manager_1.HeadlessPoolManager.cleanupAll();
102
+ }
103
+ /**
104
+ * Reset a specific pool (cleanup and recreate)
105
+ *
106
+ * @param name - Pool name
107
+ */
108
+ function resetPool(name) {
109
+ return pool_manager_1.HeadlessPoolManager.resetPool(name);
110
+ }
111
+ /**
112
+ * Remove pool from registry
113
+ *
114
+ * @param name - Pool name
115
+ */
116
+ function removePool(name) {
117
+ return pool_manager_1.HeadlessPoolManager.removePool(name);
118
+ }
119
+ // Default export
120
+ exports.default = {
121
+ createHeadlessPool,
122
+ getHeadlessPool,
123
+ getOrCreateHeadlessPool,
124
+ hasHeadlessPool,
125
+ getAllPoolStats,
126
+ cleanupAllPools,
127
+ resetPool,
128
+ removePool,
129
+ HEADLESS_POOL_ARGUMENT_SETS: config_1.HEADLESS_POOL_ARGUMENT_SETS
130
+ };
131
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/utils/headless-pool/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAiCH,gDAEC;AASD,0CAEC;AAUD,0DAKC;AAQD,0CAEC;AAOD,0CAEC;AAMD,0CAEC;AAOD,8BAEC;AAOD,gCAEC;AAxGD,iDAAkE;AAClE,qCAA0E;AAE1E,gCAAgC;AAChC,mCAA0E;AAA7C,qHAAA,2BAA2B,OAAA;AACxD,+CAAkE;AAAzD,4GAAA,YAAY,OAAA;AAAE,mHAAA,mBAAmB,OAAA;AAC1C,2CAAwC;AAA/B,uGAAA,SAAS,OAAA;AAClB,qDAAkD;AAAzC,iHAAA,cAAc,OAAA;AAEvB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,kBAAkB,CAAC,IAAY,EAAE,SAA6B,EAAE;IAC9E,OAAO,kCAAmB,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACrD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,kCAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,IAAY,EAAE,SAA6B,EAAE;IACnF,IAAI,kCAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,kCAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC;IACD,OAAO,kCAAmB,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AACrD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,kCAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAC1C,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe;IAC7B,OAAO,kCAAmB,CAAC,eAAe,EAAE,CAAA;AAC9C,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe;IAC7B,OAAO,kCAAmB,CAAC,UAAU,EAAE,CAAA;AACzC,CAAC;AAED;;;;GAIG;AACH,SAAgB,SAAS,CAAC,IAAY;IACpC,OAAO,kCAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;AAC5C,CAAC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,IAAY;IACrC,OAAO,kCAAmB,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;AAC7C,CAAC;AAGD,iBAAiB;AACjB,kBAAe;IACb,kBAAkB;IAClB,eAAe;IACf,uBAAuB;IACvB,eAAe;IACf,eAAe;IACf,eAAe;IACf,SAAS;IACT,UAAU;IACV,2BAA2B,EAA3B,oCAA2B;CAC5B,CAAA","sourcesContent":["/**\n * Unified Headless Pool System for Things Factory\n * \n * This module provides a centralized headless browser pool system\n * that can be used across all Things Factory packages.\n */\n\nimport { HeadlessPoolManager, HeadlessPool } from './pool-manager'\nimport { HeadlessPoolConfig, HEADLESS_POOL_ARGUMENT_SETS } from './config'\n\n// Re-export types and utilities\nexport { HeadlessPoolConfig, HEADLESS_POOL_ARGUMENT_SETS } from './config'\nexport { HeadlessPool, HeadlessPoolManager } from './pool-manager'\nexport { PoolStats } from './pool-stats'\nexport { BrowserFactory } from './browser-factory'\n\n/**\n * Create a new headless browser pool\n * \n * @param name - Unique name for the pool\n * @param config - Pool configuration options\n * @returns HeadlessPool instance\n * \n * @example\n * // Create integration pool with advanced features\n * const integrationPool = createHeadlessPool('integration', {\n * min: 2, max: 20,\n * args: [...HEADLESS_POOL_ARGUMENT_SETS.basic, ...HEADLESS_POOL_ARGUMENT_SETS.keychain_safe],\n * enableStats: true,\n * enableRecovery: true\n * })\n * \n * @example \n * // Create simple pool\n * const myPool = createHeadlessPool('my-pool', {\n * min: 1, max: 5\n * })\n */\nexport function createHeadlessPool(name: string, config: HeadlessPoolConfig = {}): HeadlessPool {\n return HeadlessPoolManager.createPool(name, config)\n}\n\n/**\n * Get existing headless browser pool by name\n * \n * @param name - Pool name\n * @returns HeadlessPool instance\n * @throws Error if pool doesn't exist\n */\nexport function getHeadlessPool(name: string): HeadlessPool {\n return HeadlessPoolManager.getPool(name)\n}\n\n/**\n * Get or create headless browser pool\n * If pool exists, returns it. If not, creates with provided config.\n * \n * @param name - Pool name\n * @param config - Pool configuration (used only if creating new pool)\n * @returns HeadlessPool instance\n */\nexport function getOrCreateHeadlessPool(name: string, config: HeadlessPoolConfig = {}): HeadlessPool {\n if (HeadlessPoolManager.hasPool(name)) {\n return HeadlessPoolManager.getPool(name)\n }\n return HeadlessPoolManager.createPool(name, config)\n}\n\n/**\n * Check if pool exists\n * \n * @param name - Pool name\n * @returns boolean\n */\nexport function hasHeadlessPool(name: string): boolean {\n return HeadlessPoolManager.hasPool(name)\n}\n\n/**\n * Get statistics for all pools\n * \n * @returns Object containing stats for all pools\n */\nexport function getAllPoolStats() {\n return HeadlessPoolManager.getAllPoolStats()\n}\n\n/**\n * Clean up all headless browser pools\n * Typically called during application shutdown\n */\nexport function cleanupAllPools(): Promise<void> {\n return HeadlessPoolManager.cleanupAll()\n}\n\n/**\n * Reset a specific pool (cleanup and recreate)\n * \n * @param name - Pool name\n */\nexport function resetPool(name: string): Promise<void> {\n return HeadlessPoolManager.resetPool(name)\n}\n\n/**\n * Remove pool from registry\n * \n * @param name - Pool name\n */\nexport function removePool(name: string): void {\n return HeadlessPoolManager.removePool(name)\n}\n\n\n// Default export\nexport default {\n createHeadlessPool,\n getHeadlessPool,\n getOrCreateHeadlessPool,\n hasHeadlessPool,\n getAllPoolStats,\n cleanupAllPools,\n resetPool,\n removePool,\n HEADLESS_POOL_ARGUMENT_SETS\n}"]}
@@ -0,0 +1,59 @@
1
+ import { HeadlessPoolConfig } from './config';
2
+ /**
3
+ * Individual Pool Instance
4
+ */
5
+ export declare class HeadlessPool {
6
+ private pool;
7
+ private stats?;
8
+ private config;
9
+ private name;
10
+ constructor(name: string, config: HeadlessPoolConfig);
11
+ private createPool;
12
+ private createResource;
13
+ private validateResource;
14
+ private destroyResource;
15
+ private addMonitoring;
16
+ acquire(): Promise<any>;
17
+ release(resource: any): Promise<void>;
18
+ getStats(): {
19
+ poolStatus: {
20
+ utilizationRate: string;
21
+ size: number;
22
+ available: number;
23
+ borrowed: number;
24
+ pending: number;
25
+ max: number;
26
+ min: number;
27
+ };
28
+ statistics: {
29
+ averageAcquisitionTime: string;
30
+ totalCreated: number;
31
+ totalDestroyed: number;
32
+ totalAcquired: number;
33
+ totalReleased: number;
34
+ currentlyAcquired: number;
35
+ acquisitionTimes: number[];
36
+ lastActivity: string | null;
37
+ };
38
+ health: {
39
+ status: string;
40
+ message: string;
41
+ leakDetection: string;
42
+ };
43
+ };
44
+ cleanup(): Promise<void>;
45
+ reset(): Promise<void>;
46
+ }
47
+ /**
48
+ * Global Pool Manager/Registry
49
+ */
50
+ export declare class HeadlessPoolManager {
51
+ private static pools;
52
+ static createPool(name: string, config?: HeadlessPoolConfig): HeadlessPool;
53
+ static getPool(name: string): HeadlessPool;
54
+ static hasPool(name: string): boolean;
55
+ static getAllPoolStats(): Record<string, any>;
56
+ static cleanupAll(): Promise<void>;
57
+ static resetPool(name: string): Promise<void>;
58
+ static removePool(name: string): void;
59
+ }