@0xobelisk/graphql-server 1.2.0-pre.100

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 (87) hide show
  1. package/.turbo/turbo-build.log +8 -0
  2. package/DUAL_POOL_CONFIG.md +188 -0
  3. package/Dockerfile +35 -0
  4. package/LICENSE +92 -0
  5. package/README.md +487 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +206 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config/subscription-config.d.ts +80 -0
  11. package/dist/config/subscription-config.d.ts.map +1 -0
  12. package/dist/config/subscription-config.js +158 -0
  13. package/dist/config/subscription-config.js.map +1 -0
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +11 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/plugins/all-fields-filter-plugin.d.ts +4 -0
  19. package/dist/plugins/all-fields-filter-plugin.d.ts.map +1 -0
  20. package/dist/plugins/all-fields-filter-plugin.js +132 -0
  21. package/dist/plugins/all-fields-filter-plugin.js.map +1 -0
  22. package/dist/plugins/database-introspector.d.ts +23 -0
  23. package/dist/plugins/database-introspector.d.ts.map +1 -0
  24. package/dist/plugins/database-introspector.js +96 -0
  25. package/dist/plugins/database-introspector.js.map +1 -0
  26. package/dist/plugins/enhanced-playground.d.ts +9 -0
  27. package/dist/plugins/enhanced-playground.d.ts.map +1 -0
  28. package/dist/plugins/enhanced-playground.js +113 -0
  29. package/dist/plugins/enhanced-playground.js.map +1 -0
  30. package/dist/plugins/enhanced-server-manager.d.ts +29 -0
  31. package/dist/plugins/enhanced-server-manager.d.ts.map +1 -0
  32. package/dist/plugins/enhanced-server-manager.js +262 -0
  33. package/dist/plugins/enhanced-server-manager.js.map +1 -0
  34. package/dist/plugins/index.d.ts +9 -0
  35. package/dist/plugins/index.d.ts.map +1 -0
  36. package/dist/plugins/index.js +26 -0
  37. package/dist/plugins/index.js.map +1 -0
  38. package/dist/plugins/postgraphile-config.d.ts +94 -0
  39. package/dist/plugins/postgraphile-config.d.ts.map +1 -0
  40. package/dist/plugins/postgraphile-config.js +138 -0
  41. package/dist/plugins/postgraphile-config.js.map +1 -0
  42. package/dist/plugins/query-filter.d.ts +4 -0
  43. package/dist/plugins/query-filter.d.ts.map +1 -0
  44. package/dist/plugins/query-filter.js +42 -0
  45. package/dist/plugins/query-filter.js.map +1 -0
  46. package/dist/plugins/simple-naming.d.ts +4 -0
  47. package/dist/plugins/simple-naming.d.ts.map +1 -0
  48. package/dist/plugins/simple-naming.js +79 -0
  49. package/dist/plugins/simple-naming.js.map +1 -0
  50. package/dist/plugins/welcome-page.d.ts +11 -0
  51. package/dist/plugins/welcome-page.d.ts.map +1 -0
  52. package/dist/plugins/welcome-page.js +203 -0
  53. package/dist/plugins/welcome-page.js.map +1 -0
  54. package/dist/server.d.ts +21 -0
  55. package/dist/server.d.ts.map +1 -0
  56. package/dist/server.js +265 -0
  57. package/dist/server.js.map +1 -0
  58. package/dist/universal-subscriptions.d.ts +32 -0
  59. package/dist/universal-subscriptions.d.ts.map +1 -0
  60. package/dist/universal-subscriptions.js +318 -0
  61. package/dist/universal-subscriptions.js.map +1 -0
  62. package/dist/utils/logger/index.d.ts +80 -0
  63. package/dist/utils/logger/index.d.ts.map +1 -0
  64. package/dist/utils/logger/index.js +230 -0
  65. package/dist/utils/logger/index.js.map +1 -0
  66. package/docker-compose.yml +46 -0
  67. package/eslint.config.mjs +3 -0
  68. package/package.json +78 -0
  69. package/src/cli.ts +232 -0
  70. package/src/config/subscription-config.ts +243 -0
  71. package/src/index.ts +11 -0
  72. package/src/plugins/README.md +138 -0
  73. package/src/plugins/all-fields-filter-plugin.ts +158 -0
  74. package/src/plugins/database-introspector.ts +126 -0
  75. package/src/plugins/enhanced-playground.ts +121 -0
  76. package/src/plugins/enhanced-server-manager.ts +314 -0
  77. package/src/plugins/index.ts +9 -0
  78. package/src/plugins/postgraphile-config.ts +182 -0
  79. package/src/plugins/query-filter.ts +50 -0
  80. package/src/plugins/simple-naming.ts +105 -0
  81. package/src/plugins/welcome-page.ts +218 -0
  82. package/src/server.ts +324 -0
  83. package/src/universal-subscriptions.ts +397 -0
  84. package/src/utils/logger/README.md +209 -0
  85. package/src/utils/logger/index.ts +275 -0
  86. package/sui-indexer-schema.graphql +3691 -0
  87. package/tsconfig.json +28 -0
package/src/cli.ts ADDED
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env node
2
+
3
+ import yargs, { Argv } from 'yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import * as dotenv from 'dotenv';
6
+ import { startServer, ServerConfig } from './server';
7
+ import { systemLogger } from './utils/logger';
8
+ import packageJson from '../package.json';
9
+
10
+ // Load environment variables
11
+ dotenv.config();
12
+
13
+ // Helper function to get environment variable or default value
14
+ const getEnvOrDefault = (envKey: string, defaultValue: string): string => {
15
+ return process.env[envKey] || defaultValue;
16
+ };
17
+
18
+ const getBooleanEnvOrDefault = (envKey: string, defaultValue: boolean): boolean => {
19
+ const envValue = process.env[envKey];
20
+ if (envValue === undefined) return defaultValue;
21
+ return envValue.toLowerCase() === 'true';
22
+ };
23
+
24
+ interface StartArgs {
25
+ // Basic server configuration
26
+ port: string;
27
+ 'database-url': string;
28
+ schema: string;
29
+ endpoint: string;
30
+ cors: boolean;
31
+ subscriptions: boolean;
32
+ env: string;
33
+
34
+ // Debug configuration
35
+ debug: boolean;
36
+
37
+ // Performance configuration
38
+ 'query-timeout': number;
39
+ 'max-connections': number;
40
+ 'heartbeat-interval': number;
41
+ 'enable-metrics': boolean;
42
+
43
+ // Subscription capabilities
44
+ 'enable-live-queries': boolean;
45
+ 'enable-pg-subscriptions': boolean;
46
+ 'enable-native-websocket': boolean;
47
+ 'realtime-port'?: number;
48
+ }
49
+
50
+ interface _HealthArgs {
51
+ url: string;
52
+ }
53
+
54
+ interface _InitArgs {
55
+ output: string;
56
+ }
57
+
58
+ const cli = yargs(hideBin(process.argv))
59
+ .scriptName('dubhe-graphql-server')
60
+ .usage('$0 <command> [options]')
61
+ .version(packageJson.version)
62
+ .help('help')
63
+ .alias('h', 'help')
64
+ .alias('v', 'version')
65
+ .demandCommand(1, 'You need to specify a command')
66
+ .recommendCommands()
67
+ .strict();
68
+
69
+ // Start command
70
+ cli.command(
71
+ 'start',
72
+ 'Start GraphQL server',
73
+ (yargs: Argv) => {
74
+ return (
75
+ yargs
76
+ .option('port', {
77
+ alias: 'p',
78
+ type: 'string',
79
+ default: getEnvOrDefault('PORT', '4000'),
80
+ describe: 'Server port (env: PORT)'
81
+ })
82
+ .option('database-url', {
83
+ alias: 'd',
84
+ type: 'string',
85
+ default: getEnvOrDefault(
86
+ 'DATABASE_URL',
87
+ 'postgres://postgres:postgres@127.0.0.1:5432/postgres'
88
+ ),
89
+ describe: 'Database connection URL (env: DATABASE_URL)'
90
+ })
91
+ .option('schema', {
92
+ alias: 's',
93
+ type: 'string',
94
+ default: getEnvOrDefault('PG_SCHEMA', 'public'),
95
+ describe: 'PostgreSQL schema name (env: PG_SCHEMA)'
96
+ })
97
+ .option('endpoint', {
98
+ alias: 'e',
99
+ type: 'string',
100
+ default: getEnvOrDefault('GRAPHQL_ENDPOINT', '/graphql'),
101
+ describe: 'GraphQL endpoint path (env: GRAPHQL_ENDPOINT)'
102
+ })
103
+ .option('cors', {
104
+ type: 'boolean',
105
+ default: getBooleanEnvOrDefault('ENABLE_CORS', true),
106
+ describe: 'Enable CORS (env: ENABLE_CORS)'
107
+ })
108
+ .option('subscriptions', {
109
+ type: 'boolean',
110
+ default: getBooleanEnvOrDefault('ENABLE_SUBSCRIPTIONS', true),
111
+ describe: 'Enable GraphQL subscriptions (env: ENABLE_SUBSCRIPTIONS)'
112
+ })
113
+ .option('env', {
114
+ type: 'string',
115
+ default: getEnvOrDefault('NODE_ENV', 'development'),
116
+ choices: ['development', 'production'],
117
+ describe: 'Environment mode (env: NODE_ENV)'
118
+ })
119
+ // Debug configuration
120
+ .option('debug', {
121
+ type: 'boolean',
122
+ default: getBooleanEnvOrDefault('DEBUG', false),
123
+ describe: 'Enable debug mode (verbose logging + query logs) (env: DEBUG)'
124
+ })
125
+ // Performance configuration
126
+ .option('query-timeout', {
127
+ type: 'number',
128
+ default: parseInt(getEnvOrDefault('QUERY_TIMEOUT', '30000')),
129
+ describe: 'GraphQL query timeout in milliseconds (env: QUERY_TIMEOUT)'
130
+ })
131
+ .option('max-connections', {
132
+ type: 'number',
133
+ default: parseInt(getEnvOrDefault('MAX_CONNECTIONS', '1000')),
134
+ describe: 'Maximum database connections (env: MAX_CONNECTIONS)'
135
+ })
136
+ .option('heartbeat-interval', {
137
+ type: 'number',
138
+ default: parseInt(getEnvOrDefault('HEARTBEAT_INTERVAL', '30000')),
139
+ describe: 'WebSocket heartbeat interval in milliseconds (env: HEARTBEAT_INTERVAL)'
140
+ })
141
+ .option('enable-metrics', {
142
+ type: 'boolean',
143
+ default: getBooleanEnvOrDefault('ENABLE_METRICS', false),
144
+ describe: 'Enable performance metrics (env: ENABLE_METRICS)'
145
+ })
146
+ // Subscription capabilities
147
+ .option('enable-live-queries', {
148
+ type: 'boolean',
149
+ default: getBooleanEnvOrDefault('ENABLE_LIVE_QUERIES', true),
150
+ describe: 'Enable GraphQL live queries (env: ENABLE_LIVE_QUERIES)'
151
+ })
152
+ .option('enable-pg-subscriptions', {
153
+ type: 'boolean',
154
+ default: getBooleanEnvOrDefault('ENABLE_PG_SUBSCRIPTIONS', true),
155
+ describe: 'Enable PostgreSQL subscriptions (env: ENABLE_PG_SUBSCRIPTIONS)'
156
+ })
157
+ .option('enable-native-websocket', {
158
+ type: 'boolean',
159
+ default: getBooleanEnvOrDefault('ENABLE_NATIVE_WEBSOCKET', true),
160
+ describe: 'Enable native WebSocket support (env: ENABLE_NATIVE_WEBSOCKET)'
161
+ })
162
+ .option('realtime-port', {
163
+ type: 'number',
164
+ default: process.env.REALTIME_PORT ? parseInt(process.env.REALTIME_PORT) : undefined,
165
+ describe: 'Realtime WebSocket port (env: REALTIME_PORT)'
166
+ })
167
+
168
+ .example(
169
+ '$0 start -p 4000 -d postgres://user:pass@localhost/db',
170
+ 'Start server with custom port and database'
171
+ )
172
+ .example(
173
+ '$0 start --no-cors --no-subscriptions',
174
+ 'Start server with CORS and subscriptions disabled'
175
+ )
176
+ .example('$0 start --debug', 'Start server in debug mode (verbose logging + notifications)')
177
+ .example(
178
+ '$0 start --debug --enable-metrics',
179
+ 'Start server in debug mode with performance metrics'
180
+ )
181
+ );
182
+ },
183
+ async (argv: StartArgs) => {
184
+ try {
185
+ systemLogger.info('🚀 Starting Dubhe GraphQL server via CLI...', {
186
+ port: argv.port,
187
+ schema: argv.schema,
188
+ endpoint: argv.endpoint,
189
+ environment: argv.env
190
+ });
191
+
192
+ // Build server configuration object
193
+ const serverConfig: ServerConfig = {
194
+ // Basic server configuration
195
+ port: argv.port,
196
+ databaseUrl: argv['database-url'],
197
+ schema: argv.schema,
198
+ endpoint: argv.endpoint,
199
+ cors: argv.cors,
200
+ subscriptions: argv.subscriptions,
201
+ env: argv.env,
202
+
203
+ // Debug configuration (explicit control)
204
+ debug: argv.debug,
205
+
206
+ // Performance configuration
207
+ queryTimeout: argv['query-timeout'],
208
+ maxConnections: argv['max-connections'],
209
+ heartbeatInterval: argv['heartbeat-interval'],
210
+
211
+ // Subscription capabilities
212
+ enableLiveQueries: argv['enable-live-queries'],
213
+ enablePgSubscriptions: argv['enable-pg-subscriptions'],
214
+ enableNativeWebSocket: argv['enable-native-websocket'],
215
+ realtimePort: argv['realtime-port'],
216
+
217
+ // Debug configuration (notifications only in development or when debug is enabled)
218
+ debugNotifications: argv.debug || argv.env === 'development',
219
+ enableMetrics: argv['enable-metrics']
220
+ };
221
+
222
+ // Pass configuration object directly to startServer
223
+ await startServer(serverConfig);
224
+ } catch (error: unknown) {
225
+ systemLogger.error('Failed to start server via CLI', error);
226
+ process.exit(1);
227
+ }
228
+ }
229
+ );
230
+
231
+ // Parse command line arguments
232
+ cli.parse();
@@ -0,0 +1,243 @@
1
+ // Subscription configuration manager - supports dynamic configuration for three subscription modes
2
+
3
+ export interface SubscriptionCapabilities {
4
+ liveQueries: boolean;
5
+ pgSubscriptions: boolean;
6
+ nativeWebSocket: boolean;
7
+ }
8
+
9
+ export interface SubscriptionConfig {
10
+ // Basic configuration
11
+ enableSubscriptions: boolean;
12
+
13
+ // Capability configuration
14
+ capabilities: SubscriptionCapabilities;
15
+
16
+ // Database configuration detection
17
+ walLevel: 'minimal' | 'replica' | 'logical';
18
+
19
+ // Port configuration
20
+ graphqlPort: number;
21
+ websocketPort?: number;
22
+
23
+ // Performance configuration
24
+ maxConnections: number;
25
+ heartbeatInterval: number;
26
+
27
+ // Debug configuration
28
+ enableNotificationLogging: boolean;
29
+ enablePerformanceMetrics: boolean;
30
+ }
31
+
32
+ // Subscription configuration input parameter interface
33
+ export interface SubscriptionConfigInput {
34
+ enableSubscriptions: boolean;
35
+ databaseUrl: string;
36
+ port: string;
37
+ enableLiveQueries?: boolean;
38
+ enablePgSubscriptions?: boolean;
39
+ enableNativeWebSocket?: boolean;
40
+ realtimePort?: string;
41
+ maxConnections?: string;
42
+ heartbeatInterval?: string;
43
+ debugNotifications?: boolean;
44
+ enableMetrics?: boolean;
45
+ }
46
+
47
+ export class SubscriptionConfigManager {
48
+ private config: SubscriptionConfig;
49
+
50
+ constructor(configInput: SubscriptionConfigInput) {
51
+ this.config = this.parseConfigInput(configInput);
52
+ }
53
+
54
+ // Parse configuration from input parameters
55
+ private parseConfigInput(input: SubscriptionConfigInput): SubscriptionConfig {
56
+ const enableSubscriptions = input.enableSubscriptions;
57
+
58
+ // Auto-detect WAL level (in actual applications, query through database)
59
+ const walLevel = this.detectWalLevel(input.databaseUrl);
60
+
61
+ // Determine capabilities based on input parameters - default enable all features when subscriptions are enabled
62
+ const capabilities: SubscriptionCapabilities = {
63
+ liveQueries:
64
+ enableSubscriptions && input.enableLiveQueries !== false && walLevel === 'logical',
65
+
66
+ pgSubscriptions: enableSubscriptions && input.enablePgSubscriptions !== false,
67
+
68
+ nativeWebSocket: enableSubscriptions && input.enableNativeWebSocket !== false
69
+ };
70
+
71
+ return {
72
+ enableSubscriptions,
73
+ capabilities,
74
+ walLevel,
75
+
76
+ graphqlPort: parseInt(input.port),
77
+ websocketPort: input.realtimePort ? parseInt(input.realtimePort) : undefined,
78
+
79
+ maxConnections: parseInt(input.maxConnections || '1000'),
80
+ heartbeatInterval: parseInt(input.heartbeatInterval || '30000'),
81
+
82
+ enableNotificationLogging: input.debugNotifications === true,
83
+ enablePerformanceMetrics: input.enableMetrics === true
84
+ };
85
+ }
86
+
87
+ // Detect database WAL level
88
+ private detectWalLevel(_databaseUrl?: string): 'minimal' | 'replica' | 'logical' {
89
+ // In actual applications should query database
90
+ // SELECT setting FROM pg_settings WHERE name = 'wal_level';
91
+
92
+ // Currently return default value
93
+ return 'replica';
94
+ }
95
+
96
+ // Get current configuration
97
+ getConfig(): SubscriptionConfig {
98
+ return { ...this.config };
99
+ }
100
+
101
+ // Get recommended subscription method
102
+ getRecommendedSubscriptionMethod(): string {
103
+ if (this.config.capabilities.liveQueries) {
104
+ return 'live-queries';
105
+ } else if (this.config.capabilities.pgSubscriptions) {
106
+ return 'pg-subscriptions';
107
+ } else if (this.config.capabilities.nativeWebSocket) {
108
+ return 'native-websocket';
109
+ } else {
110
+ return 'none';
111
+ }
112
+ }
113
+
114
+ // Generate client configuration
115
+ generateClientConfig() {
116
+ const baseUrl = `http://localhost:${this.config.graphqlPort}`;
117
+
118
+ return {
119
+ graphqlEndpoint: `${baseUrl}/graphql`,
120
+ subscriptionEndpoint:
121
+ this.config.capabilities.pgSubscriptions || this.config.capabilities.liveQueries
122
+ ? `ws://localhost:${this.config.graphqlPort}/graphql`
123
+ : undefined,
124
+ nativeWebSocketEndpoint: this.config.capabilities.nativeWebSocket
125
+ ? `ws://localhost:${this.config.websocketPort || this.config.graphqlPort}`
126
+ : undefined,
127
+ capabilities: this.config.capabilities,
128
+ recommendedMethod: this.getRecommendedSubscriptionMethod()
129
+ };
130
+ }
131
+
132
+ // Generate PostGraphile configuration - simplified version, only keep listen subscriptions
133
+ generatePostGraphileConfig() {
134
+ return {
135
+ subscriptions: this.config.enableSubscriptions,
136
+ live: false, // Disable live queries, only use listen subscriptions
137
+ simpleSubscriptions: this.config.capabilities.pgSubscriptions,
138
+
139
+ // Performance configuration - optimized for listen subscriptions
140
+ pgSettings: {
141
+ statement_timeout: '30s',
142
+ default_transaction_isolation: 'read committed'
143
+ },
144
+
145
+ // Monitoring configuration
146
+ allowExplain: this.config.enablePerformanceMetrics,
147
+ disableQueryLog: !this.config.enableNotificationLogging
148
+ };
149
+ }
150
+
151
+ // Generate environment variable documentation
152
+ generateDocumentation(): string {
153
+ return `
154
+ # 📡 Subscription System Configuration Guide
155
+
156
+ ## Basic Configuration
157
+ enableSubscriptions=${
158
+ this.config.enableSubscriptions
159
+ } # Enable/disable subscription features
160
+
161
+ ## Capability Configuration (optional, auto-detect by default)
162
+ enableLiveQueries=${
163
+ this.config.capabilities.liveQueries
164
+ } # Enable @live directive (requires wal_level=logical)
165
+ enablePgSubscriptions=${
166
+ this.config.capabilities.pgSubscriptions
167
+ } # Enable PostgreSQL subscriptions
168
+ enableNativeWebSocket=${this.config.capabilities.nativeWebSocket} # Enable native WebSocket
169
+
170
+ ## Port Configuration
171
+ port=${this.config.graphqlPort} # GraphQL port
172
+ realtimePort=${
173
+ this.config.websocketPort || 'undefined'
174
+ } # Native WebSocket port (optional)
175
+
176
+ ## Performance Configuration
177
+ maxConnections=${this.config.maxConnections} # Maximum connections
178
+ heartbeatInterval=${this.config.heartbeatInterval} # Heartbeat interval (ms)
179
+
180
+ ## Debug Configuration
181
+ debugNotifications=${this.config.enableNotificationLogging} # Notification logging
182
+ enableMetrics=${this.config.enablePerformanceMetrics} # Performance metrics
183
+
184
+ ## Current Configuration Status:
185
+ - Subscription Features: ${this.config.enableSubscriptions ? '✅ Enabled' : '❌ Disabled'}
186
+ - Live Queries: ${this.config.capabilities.liveQueries ? '✅ Available' : '❌ Not Available'}
187
+ - PG Subscriptions: ${
188
+ this.config.capabilities.pgSubscriptions ? '✅ Available' : '❌ Not Available'
189
+ }
190
+ - Native WebSocket: ${
191
+ this.config.capabilities.nativeWebSocket ? '✅ Available' : '❌ Not Available'
192
+ }
193
+ - WAL Level: ${this.config.walLevel}
194
+ - Recommended Method: ${this.getRecommendedSubscriptionMethod()}
195
+ `;
196
+ }
197
+ }
198
+
199
+ // Export singleton instance - lazy initialization
200
+ let _subscriptionConfigInstance: SubscriptionConfigManager | null = null;
201
+
202
+ export const subscriptionConfig = {
203
+ getConfig(): SubscriptionConfig {
204
+ if (!_subscriptionConfigInstance) {
205
+ throw new Error(
206
+ 'Subscription config not initialized. Call refresh() first with configuration.'
207
+ );
208
+ }
209
+ return _subscriptionConfigInstance.getConfig();
210
+ },
211
+
212
+ generateClientConfig() {
213
+ if (!_subscriptionConfigInstance) {
214
+ throw new Error(
215
+ 'Subscription config not initialized. Call refresh() first with configuration.'
216
+ );
217
+ }
218
+ return _subscriptionConfigInstance.generateClientConfig();
219
+ },
220
+
221
+ generatePostGraphileConfig() {
222
+ if (!_subscriptionConfigInstance) {
223
+ throw new Error(
224
+ 'Subscription config not initialized. Call refresh() first with configuration.'
225
+ );
226
+ }
227
+ return _subscriptionConfigInstance.generatePostGraphileConfig();
228
+ },
229
+
230
+ generateDocumentation(): string {
231
+ if (!_subscriptionConfigInstance) {
232
+ throw new Error(
233
+ 'Subscription config not initialized. Call refresh() first with configuration.'
234
+ );
235
+ }
236
+ return _subscriptionConfigInstance.generateDocumentation();
237
+ },
238
+
239
+ // Initialize/refresh configuration with input parameters
240
+ refresh(configInput: SubscriptionConfigInput) {
241
+ _subscriptionConfigInstance = new SubscriptionConfigManager(configInput);
242
+ }
243
+ };
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ // import { startServer } from './server';
2
+ // import { systemLogger } from './utils/logger';
3
+
4
+ // // // Start application
5
+ // // systemLogger.info('🚀 Starting Sui Indexer GraphQL Server (Express Architecture)...', {
6
+ // // nodeVersion: process.version,
7
+ // // platform: process.platform,
8
+ // // pid: process.pid
9
+ // // });
10
+
11
+ // // startServer();
@@ -0,0 +1,138 @@
1
+ # GraphQL Server Plugin Architecture
2
+
3
+ This directory contains various functional module plugins for the Sui Indexer GraphQL server, using modular design for easy management and extension.
4
+
5
+ ## 📁 Plugin Structure
6
+
7
+ ### Core Plugins
8
+
9
+ #### `database-introspector.ts` - Database Introspector
10
+
11
+ - **Function**: Scan and analyze database table structure
12
+ - **Main Class**: `DatabaseIntrospector`
13
+ - **Responsibilities**:
14
+ - Get store\_\* dynamic tables
15
+ - Get system tables (dubhe related)
16
+ - Get field information from table_fields
17
+ - Test database connection
18
+ - Output table structure logs
19
+
20
+ #### `welcome-page.ts` - Welcome Page Generator
21
+
22
+ - **Function**: Generate server homepage
23
+ - **Main Function**: `createWelcomePage()`
24
+ - **Responsibilities**:
25
+ - Display server status and configuration information
26
+ - Show detected data tables
27
+ - Provide navigation links and usage guides
28
+ - Responsive design and beautiful interface
29
+
30
+ #### `postgraphile-config.ts` - PostGraphile Configuration Generator
31
+
32
+ - **Function**: Create PostGraphile configuration
33
+ - **Main Function**: `createPostGraphileConfig()`
34
+ - **Responsibilities**:
35
+ - Configure GraphQL endpoints and features
36
+ - Integrate enhanced Playground
37
+ - Set up subscriptions and real-time queries
38
+ - Optimize performance parameters
39
+
40
+ #### `subscription-manager.ts` - Subscription Manager
41
+
42
+ - **Function**: Manage GraphQL subscription features
43
+ - **Main Class**: `SubscriptionManager`
44
+ - **Responsibilities**:
45
+ - Load @graphile/pg-pubsub plugin
46
+ - Configure custom subscription plugins
47
+ - Error handling and fallback solutions
48
+ - Output subscription status information
49
+
50
+ #### `server-manager.ts` - Server Manager
51
+
52
+ - **Function**: Manage HTTP and WebSocket servers
53
+ - **Main Class**: `ServerManager`
54
+ - **Responsibilities**:
55
+ - Create and configure HTTP server
56
+ - Start real-time subscription server
57
+ - Database change monitoring
58
+ - Graceful shutdown handling
59
+
60
+ #### `enhanced-playground.ts` - Enhanced GraphQL Playground
61
+
62
+ - **Function**: Provide modern GraphQL IDE
63
+ - **Main Function**: `createEnhancedPlayground()`
64
+ - **Responsibilities**:
65
+ - Visual Schema Explorer
66
+ - Code export functionality
67
+ - Modern UI interface
68
+ - Keyboard shortcuts support
69
+
70
+ ## 🔧 Usage
71
+
72
+ ### Unified Import
73
+
74
+ ```typescript
75
+ import {
76
+ DatabaseIntrospector,
77
+ createPostGraphileConfig,
78
+ SubscriptionManager,
79
+ ServerManager,
80
+ WelcomePageConfig
81
+ } from './plugins';
82
+ ```
83
+
84
+ ### Typical Usage Flow
85
+
86
+ 1. **Database Scanning**: Use `DatabaseIntrospector` to get table structure
87
+ 2. **Subscription Configuration**: Load plugins through `SubscriptionManager`
88
+ 3. **Configuration Generation**: Create configuration using `createPostGraphileConfig`
89
+ 4. **Server Startup**: Manage server lifecycle through `ServerManager`
90
+
91
+ ## 🎯 Design Advantages
92
+
93
+ ### Modular Design
94
+
95
+ - Each plugin has a single clear responsibility
96
+ - Easy to test and maintain individually
97
+ - Supports independent upgrades and replacements
98
+
99
+ ### Type Safety
100
+
101
+ - Complete TypeScript support
102
+ - Clear interface definitions
103
+ - Compile-time error checking
104
+
105
+ ### Extensibility
106
+
107
+ - Plugin architecture easy to extend
108
+ - Supports custom plugin development
109
+ - Flexible and adjustable configuration
110
+
111
+ ### Error Handling
112
+
113
+ - Graceful error degradation
114
+ - Detailed log output
115
+ - Fault isolation protection
116
+
117
+ ## 📈 Extension Guide
118
+
119
+ ### Adding New Plugins
120
+
121
+ 1. Create new file in `plugins/` directory
122
+ 2. Export main interfaces and classes
123
+ 3. Add export in `index.ts`
124
+ 4. Update main entry file to use
125
+
126
+ ### Custom Configuration
127
+
128
+ - Pass configuration through environment variables
129
+ - Use interfaces to define configuration structure
130
+ - Support runtime dynamic configuration
131
+
132
+ ### Plugin Integration
133
+
134
+ - Follow unified error handling patterns
135
+ - Use consistent log formats
136
+ - Maintain interface compatibility
137
+
138
+ This architecture makes the GraphQL server more modular, maintainable, and provides a solid foundation for future feature extensions.