@sylphx/lens-server 2.3.2 → 2.4.1
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/index.d.ts +241 -23
- package/dist/index.js +353 -19
- package/package.json +1 -1
- package/src/handlers/http.test.ts +227 -2
- package/src/handlers/http.ts +223 -22
- package/src/handlers/index.ts +2 -0
- package/src/handlers/ws-types.ts +39 -0
- package/src/handlers/ws.test.ts +559 -0
- package/src/handlers/ws.ts +99 -0
- package/src/index.ts +21 -0
- package/src/logging/index.ts +20 -0
- package/src/logging/structured-logger.test.ts +367 -0
- package/src/logging/structured-logger.ts +335 -0
- package/src/server/create.test.ts +198 -0
- package/src/server/create.ts +78 -9
- package/src/server/types.ts +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -528,7 +528,7 @@ type ClientSendFn = (message: unknown) => void;
|
|
|
528
528
|
/** WebSocket interface for adapters */
|
|
529
529
|
interface WebSocketLike {
|
|
530
530
|
send(data: string): void;
|
|
531
|
-
close(): void;
|
|
531
|
+
close(code?: number, reason?: string): void;
|
|
532
532
|
onmessage?: ((event: {
|
|
533
533
|
data: string;
|
|
534
534
|
}) => void) | null;
|
|
@@ -802,6 +802,45 @@ declare class SSEHandler {
|
|
|
802
802
|
* Create SSE handler (pure transport).
|
|
803
803
|
*/
|
|
804
804
|
declare function createSSEHandler(config?: SSEHandlerConfig): SSEHandler;
|
|
805
|
+
/** Error sanitization options */
|
|
806
|
+
interface ErrorSanitizationOptions {
|
|
807
|
+
/**
|
|
808
|
+
* Enable development mode - shows full error messages.
|
|
809
|
+
* Default: false (production mode - sanitized errors only)
|
|
810
|
+
*/
|
|
811
|
+
development?: boolean;
|
|
812
|
+
/**
|
|
813
|
+
* Custom error sanitizer function.
|
|
814
|
+
* Return a safe error message to send to the client.
|
|
815
|
+
*/
|
|
816
|
+
sanitize?: (error: Error) => string;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Health check options
|
|
820
|
+
*/
|
|
821
|
+
interface HealthCheckOptions {
|
|
822
|
+
/**
|
|
823
|
+
* Enable health check endpoint.
|
|
824
|
+
* Default: true
|
|
825
|
+
*/
|
|
826
|
+
enabled?: boolean;
|
|
827
|
+
/**
|
|
828
|
+
* Custom health check path.
|
|
829
|
+
* Default: "/__lens/health"
|
|
830
|
+
*/
|
|
831
|
+
path?: string;
|
|
832
|
+
/**
|
|
833
|
+
* Custom health check function.
|
|
834
|
+
* Return additional checks to include in the response.
|
|
835
|
+
*/
|
|
836
|
+
checks?: () => Promise<Record<string, {
|
|
837
|
+
status: "pass" | "fail";
|
|
838
|
+
message?: string;
|
|
839
|
+
}>> | Record<string, {
|
|
840
|
+
status: "pass" | "fail";
|
|
841
|
+
message?: string;
|
|
842
|
+
}>;
|
|
843
|
+
}
|
|
805
844
|
interface HTTPHandlerOptions {
|
|
806
845
|
/**
|
|
807
846
|
* Path prefix for Lens endpoints.
|
|
@@ -818,13 +857,23 @@ interface HTTPHandlerOptions {
|
|
|
818
857
|
pathPrefix?: string;
|
|
819
858
|
/**
|
|
820
859
|
* Custom CORS headers.
|
|
821
|
-
* Default: Allow all origins
|
|
860
|
+
* Default: Allow all origins in development, strict in production
|
|
822
861
|
*/
|
|
823
862
|
cors?: {
|
|
824
863
|
origin?: string | string[];
|
|
825
864
|
methods?: string[];
|
|
826
865
|
headers?: string[];
|
|
827
866
|
};
|
|
867
|
+
/**
|
|
868
|
+
* Error sanitization options.
|
|
869
|
+
* Controls what error information is exposed to clients.
|
|
870
|
+
*/
|
|
871
|
+
errors?: ErrorSanitizationOptions;
|
|
872
|
+
/**
|
|
873
|
+
* Health check endpoint configuration.
|
|
874
|
+
* Enabled by default at /__lens/health
|
|
875
|
+
*/
|
|
876
|
+
health?: HealthCheckOptions;
|
|
828
877
|
}
|
|
829
878
|
interface HTTPHandler {
|
|
830
879
|
/**
|
|
@@ -837,26 +886,6 @@ interface HTTPHandler {
|
|
|
837
886
|
*/
|
|
838
887
|
handle(request: Request): Promise<Response>;
|
|
839
888
|
}
|
|
840
|
-
/**
|
|
841
|
-
* Create an HTTP handler from a Lens app.
|
|
842
|
-
*
|
|
843
|
-
* @example
|
|
844
|
-
* ```typescript
|
|
845
|
-
* import { createApp, createHTTPHandler } from '@sylphx/lens-server'
|
|
846
|
-
*
|
|
847
|
-
* const app = createApp({ router })
|
|
848
|
-
* const handler = createHTTPHandler(app)
|
|
849
|
-
*
|
|
850
|
-
* // Bun
|
|
851
|
-
* Bun.serve({ port: 3000, fetch: handler })
|
|
852
|
-
*
|
|
853
|
-
* // Vercel
|
|
854
|
-
* handler
|
|
855
|
-
*
|
|
856
|
-
* // Cloudflare Workers
|
|
857
|
-
* { fetch: handler }
|
|
858
|
-
* ```
|
|
859
|
-
*/
|
|
860
889
|
declare function createHTTPHandler(server: LensServer, options?: HTTPHandlerOptions): HTTPHandler;
|
|
861
890
|
interface HandlerOptions extends HTTPHandlerOptions {
|
|
862
891
|
/**
|
|
@@ -1000,6 +1029,40 @@ interface WSHandlerOptions {
|
|
|
1000
1029
|
warn?: (message: string, ...args: unknown[]) => void;
|
|
1001
1030
|
error?: (message: string, ...args: unknown[]) => void;
|
|
1002
1031
|
};
|
|
1032
|
+
/**
|
|
1033
|
+
* Maximum message size in bytes.
|
|
1034
|
+
* Messages larger than this will be rejected.
|
|
1035
|
+
* Default: 1MB (1024 * 1024)
|
|
1036
|
+
*/
|
|
1037
|
+
maxMessageSize?: number;
|
|
1038
|
+
/**
|
|
1039
|
+
* Maximum subscriptions per client.
|
|
1040
|
+
* Prevents resource exhaustion from malicious clients.
|
|
1041
|
+
* Default: 100
|
|
1042
|
+
*/
|
|
1043
|
+
maxSubscriptionsPerClient?: number;
|
|
1044
|
+
/**
|
|
1045
|
+
* Maximum connections total.
|
|
1046
|
+
* Prevents server overload.
|
|
1047
|
+
* Default: 10000
|
|
1048
|
+
*/
|
|
1049
|
+
maxConnections?: number;
|
|
1050
|
+
/**
|
|
1051
|
+
* Rate limiting configuration.
|
|
1052
|
+
* Uses token bucket algorithm per client.
|
|
1053
|
+
*/
|
|
1054
|
+
rateLimit?: {
|
|
1055
|
+
/**
|
|
1056
|
+
* Maximum messages per window.
|
|
1057
|
+
* Default: 100
|
|
1058
|
+
*/
|
|
1059
|
+
maxMessages?: number;
|
|
1060
|
+
/**
|
|
1061
|
+
* Time window in milliseconds.
|
|
1062
|
+
* Default: 1000 (1 second)
|
|
1063
|
+
*/
|
|
1064
|
+
windowMs?: number;
|
|
1065
|
+
};
|
|
1003
1066
|
}
|
|
1004
1067
|
/**
|
|
1005
1068
|
* WebSocket adapter for Bun's websocket handler.
|
|
@@ -1495,4 +1558,159 @@ declare function coalescePatches(patches: PatchOperation3[][]): PatchOperation3[
|
|
|
1495
1558
|
* Estimate memory size of patch operations.
|
|
1496
1559
|
*/
|
|
1497
1560
|
declare function estimatePatchSize(patch: PatchOperation3[]): number;
|
|
1498
|
-
|
|
1561
|
+
/**
|
|
1562
|
+
* @sylphx/lens-server - Structured Logging
|
|
1563
|
+
*
|
|
1564
|
+
* Production-ready structured logging with JSON output.
|
|
1565
|
+
* Compatible with log aggregators (DataDog, Splunk, ELK, etc.)
|
|
1566
|
+
*/
|
|
1567
|
+
/**
|
|
1568
|
+
* Log levels (RFC 5424 severity)
|
|
1569
|
+
*/
|
|
1570
|
+
type LogLevel = "debug" | "info" | "warn" | "error" | "fatal";
|
|
1571
|
+
/**
|
|
1572
|
+
* Base log context - always included
|
|
1573
|
+
*/
|
|
1574
|
+
interface LogContext {
|
|
1575
|
+
/** Timestamp in ISO format */
|
|
1576
|
+
timestamp: string;
|
|
1577
|
+
/** Log level */
|
|
1578
|
+
level: LogLevel;
|
|
1579
|
+
/** Log message */
|
|
1580
|
+
message: string;
|
|
1581
|
+
/** Service/component name */
|
|
1582
|
+
service?: string;
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Request context for API operations
|
|
1586
|
+
*/
|
|
1587
|
+
interface RequestContext {
|
|
1588
|
+
/** Unique request/correlation ID */
|
|
1589
|
+
requestId?: string;
|
|
1590
|
+
/** Operation being executed */
|
|
1591
|
+
operation?: string;
|
|
1592
|
+
/** Client identifier */
|
|
1593
|
+
clientId?: string;
|
|
1594
|
+
/** Request duration in milliseconds */
|
|
1595
|
+
durationMs?: number;
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* Error context for error logs
|
|
1599
|
+
*/
|
|
1600
|
+
interface ErrorContext {
|
|
1601
|
+
/** Error name/type */
|
|
1602
|
+
errorType?: string;
|
|
1603
|
+
/** Error message */
|
|
1604
|
+
errorMessage?: string;
|
|
1605
|
+
/** Stack trace (only in development) */
|
|
1606
|
+
stack?: string;
|
|
1607
|
+
/** Error code */
|
|
1608
|
+
errorCode?: string;
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* WebSocket context
|
|
1612
|
+
*/
|
|
1613
|
+
interface WebSocketContext {
|
|
1614
|
+
/** Message type */
|
|
1615
|
+
messageType?: string;
|
|
1616
|
+
/** Subscription ID */
|
|
1617
|
+
subscriptionId?: string;
|
|
1618
|
+
/** Entity type */
|
|
1619
|
+
entity?: string;
|
|
1620
|
+
/** Entity ID */
|
|
1621
|
+
entityId?: string;
|
|
1622
|
+
/** Connection count */
|
|
1623
|
+
connectionCount?: number;
|
|
1624
|
+
/** Subscription count */
|
|
1625
|
+
subscriptionCount?: number;
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
* Performance context
|
|
1629
|
+
*/
|
|
1630
|
+
interface PerformanceContext {
|
|
1631
|
+
/** Memory usage in bytes */
|
|
1632
|
+
memoryUsed?: number;
|
|
1633
|
+
/** CPU usage percentage */
|
|
1634
|
+
cpuPercent?: number;
|
|
1635
|
+
/** Active connections */
|
|
1636
|
+
activeConnections?: number;
|
|
1637
|
+
/** Active subscriptions */
|
|
1638
|
+
activeSubscriptions?: number;
|
|
1639
|
+
/** Messages per second */
|
|
1640
|
+
messagesPerSecond?: number;
|
|
1641
|
+
}
|
|
1642
|
+
/**
|
|
1643
|
+
* Full log entry type
|
|
1644
|
+
*/
|
|
1645
|
+
type LogEntry = LogContext & Partial<RequestContext> & Partial<ErrorContext> & Partial<WebSocketContext> & Partial<PerformanceContext> & {
|
|
1646
|
+
[key: string]: unknown;
|
|
1647
|
+
};
|
|
1648
|
+
/**
|
|
1649
|
+
* Logger output destination
|
|
1650
|
+
*/
|
|
1651
|
+
interface LogOutput {
|
|
1652
|
+
write(entry: LogEntry): void;
|
|
1653
|
+
}
|
|
1654
|
+
/**
|
|
1655
|
+
* Structured logger configuration
|
|
1656
|
+
*/
|
|
1657
|
+
interface StructuredLoggerOptions {
|
|
1658
|
+
/** Service name for log entries */
|
|
1659
|
+
service?: string;
|
|
1660
|
+
/** Minimum log level to output */
|
|
1661
|
+
level?: LogLevel;
|
|
1662
|
+
/** Include stack traces in error logs */
|
|
1663
|
+
includeStackTrace?: boolean;
|
|
1664
|
+
/** Custom output destination */
|
|
1665
|
+
output?: LogOutput;
|
|
1666
|
+
/** Additional context to include in all logs */
|
|
1667
|
+
defaultContext?: Record<string, unknown>;
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* JSON console output (production)
|
|
1671
|
+
*/
|
|
1672
|
+
declare const jsonOutput: LogOutput;
|
|
1673
|
+
/**
|
|
1674
|
+
* Pretty console output (development)
|
|
1675
|
+
*/
|
|
1676
|
+
declare const prettyOutput: LogOutput;
|
|
1677
|
+
/**
|
|
1678
|
+
* Structured logger interface
|
|
1679
|
+
*/
|
|
1680
|
+
interface StructuredLogger {
|
|
1681
|
+
debug: (message: string, context?: Record<string, unknown>) => void;
|
|
1682
|
+
info: (message: string, context?: Record<string, unknown>) => void;
|
|
1683
|
+
warn: (message: string, context?: Record<string, unknown>) => void;
|
|
1684
|
+
error: (message: string, context?: Record<string, unknown>) => void;
|
|
1685
|
+
fatal: (message: string, context?: Record<string, unknown>) => void;
|
|
1686
|
+
child: (childContext: Record<string, unknown>) => StructuredLogger;
|
|
1687
|
+
request: (requestId: string, message: string, context?: Record<string, unknown>) => void;
|
|
1688
|
+
startOperation: (operation: string, context?: Record<string, unknown>) => (result?: {
|
|
1689
|
+
error?: Error;
|
|
1690
|
+
data?: unknown;
|
|
1691
|
+
}) => void;
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Create a structured logger instance.
|
|
1695
|
+
*
|
|
1696
|
+
* @example
|
|
1697
|
+
* ```typescript
|
|
1698
|
+
* const logger = createStructuredLogger({
|
|
1699
|
+
* service: 'lens-server',
|
|
1700
|
+
* level: 'info',
|
|
1701
|
+
* });
|
|
1702
|
+
*
|
|
1703
|
+
* logger.info('Request started', { requestId: 'abc', operation: 'getUser' });
|
|
1704
|
+
* logger.error('Request failed', { requestId: 'abc', error: err });
|
|
1705
|
+
* ```
|
|
1706
|
+
*/
|
|
1707
|
+
declare function createStructuredLogger(options?: StructuredLoggerOptions): StructuredLogger;
|
|
1708
|
+
/**
|
|
1709
|
+
* Adapter to make structured logger compatible with basic logger interface.
|
|
1710
|
+
*/
|
|
1711
|
+
declare function toBasicLogger(structuredLogger: StructuredLogger): {
|
|
1712
|
+
info: (message: string, ...args: unknown[]) => void;
|
|
1713
|
+
warn: (message: string, ...args: unknown[]) => void;
|
|
1714
|
+
error: (message: string, ...args: unknown[]) => void;
|
|
1715
|
+
};
|
|
1716
|
+
export { useContext, tryUseContext, toBasicLogger, runWithContextAsync, runWithContext, router, query, prettyOutput, optimisticPlugin, opLog, mutation, memoryStorage, jsonOutput, isOptimisticPlugin, isOpLogPlugin, hasContext, handleWebSSE, handleWebQuery, handleWebMutation, extendContext, estimatePatchSize, createWSHandler, createStructuredLogger, createServerClientProxy, createSSEHandler, createPluginManager, createHandler, createHTTPHandler, createFrameworkHandler, createContext, createApp, coalescePatches, WebSocketLike, WebSocketContext, WSHandlerOptions, WSHandler, UnsubscribeContext2 as UnsubscribeContext, SubscribeContext2 as SubscribeContext, StructuredLoggerOptions, StructuredLogger, StoredPatchEntry, StoredEntityState, ServerPlugin, ServerMetadata, LensServerConfig as ServerConfig, SelectionObject, SSEHandlerConfig as SSEHandlerOptions, SSEHandlerConfig, SSEHandler, SSEClient, RouterRoutes, RouterDef3 as RouterDef, ResolverFn, ResolverContext, RequestContext, QueryDef2 as QueryDef, QueriesMap, PluginManager, PerformanceContext, OptimisticPluginOptions, OperationsMap, OperationMeta, OperationLog, OpLogStorageConfig, OpLogStorage, OpLogPlugin, OpLogOptions, MutationsMap, MutationDef2 as MutationDef, LogOutput, LogLevel, LogEntry, LogContext, LensServer, LensResult, LensOperation, InferRouterContext3 as InferRouterContext, InferOutput, InferInput, InferApi, HandlerOptions, Handler, HTTPHandlerOptions, HTTPHandler, FrameworkHandlerOptions, ErrorContext, EntitiesMap, EnhanceOperationMetaContext, EmitResult, DisconnectContext, DEFAULT_STORAGE_CONFIG, ConnectContext, ClientSendFn, BroadcastResult, BeforeSendContext, BeforeMutationContext, AfterSendContext, AfterMutationContext };
|