@gravito/ripple 3.1.0 → 4.0.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/README.md +260 -19
- package/dist/atlas/src/DB.d.ts +348 -0
- package/dist/atlas/src/OrbitAtlas.d.ts +9 -0
- package/dist/atlas/src/config/defineConfig.d.ts +14 -0
- package/dist/atlas/src/config/index.d.ts +7 -0
- package/dist/atlas/src/config/loadConfig.d.ts +41 -0
- package/dist/atlas/src/connection/Connection.d.ts +112 -0
- package/dist/atlas/src/connection/ConnectionManager.d.ts +180 -0
- package/dist/atlas/src/connection/ReplicaConnectionPool.d.ts +54 -0
- package/dist/atlas/src/drivers/BunSQLDriver.d.ts +32 -0
- package/dist/atlas/src/drivers/BunSQLPreparedStatement.d.ts +118 -0
- package/dist/atlas/src/drivers/MongoDBDriver.d.ts +36 -0
- package/dist/atlas/src/drivers/MySQLDriver.d.ts +79 -0
- package/dist/atlas/src/drivers/PostgresDriver.d.ts +96 -0
- package/dist/atlas/src/drivers/RedisDriver.d.ts +43 -0
- package/dist/atlas/src/drivers/SQLiteDriver.d.ts +45 -0
- package/dist/atlas/src/drivers/types.d.ts +260 -0
- package/dist/atlas/src/errors/index.d.ts +45 -0
- package/dist/atlas/src/grammar/Grammar.d.ts +342 -0
- package/dist/atlas/src/grammar/MongoGrammar.d.ts +47 -0
- package/dist/atlas/src/grammar/MySQLGrammar.d.ts +54 -0
- package/dist/atlas/src/grammar/NullGrammar.d.ts +35 -0
- package/dist/atlas/src/grammar/PostgresGrammar.d.ts +62 -0
- package/dist/atlas/src/grammar/SQLiteGrammar.d.ts +32 -0
- package/dist/atlas/src/index.d.ts +79 -0
- package/dist/atlas/src/migration/Migration.d.ts +64 -0
- package/dist/atlas/src/migration/MigrationRepository.d.ts +65 -0
- package/dist/atlas/src/migration/Migrator.d.ts +110 -0
- package/dist/atlas/src/migration/index.d.ts +6 -0
- package/dist/atlas/src/observability/AtlasMetrics.d.ts +33 -0
- package/dist/atlas/src/observability/AtlasObservability.d.ts +15 -0
- package/dist/atlas/src/observability/AtlasTracer.d.ts +12 -0
- package/dist/atlas/src/observability/index.d.ts +9 -0
- package/dist/atlas/src/orm/Repository.d.ts +247 -0
- package/dist/atlas/src/orm/index.d.ts +6 -0
- package/dist/atlas/src/orm/model/DirtyTracker.d.ts +121 -0
- package/dist/atlas/src/orm/model/Model.d.ts +458 -0
- package/dist/atlas/src/orm/model/ModelRegistry.d.ts +20 -0
- package/dist/atlas/src/orm/model/concerns/HasAttributes.d.ts +150 -0
- package/dist/atlas/src/orm/model/concerns/HasEvents.d.ts +36 -0
- package/dist/atlas/src/orm/model/concerns/HasPersistence.d.ts +92 -0
- package/dist/atlas/src/orm/model/concerns/HasRelationships.d.ts +117 -0
- package/dist/atlas/src/orm/model/concerns/HasSerialization.d.ts +64 -0
- package/dist/atlas/src/orm/model/concerns/applyMixins.d.ts +15 -0
- package/dist/atlas/src/orm/model/concerns/index.d.ts +12 -0
- package/dist/atlas/src/orm/model/decorators.d.ts +138 -0
- package/dist/atlas/src/orm/model/errors.d.ts +52 -0
- package/dist/atlas/src/orm/model/index.d.ts +10 -0
- package/dist/atlas/src/orm/model/relationships.d.ts +207 -0
- package/dist/atlas/src/orm/model/types.d.ts +12 -0
- package/dist/atlas/src/orm/schema/SchemaRegistry.d.ts +124 -0
- package/dist/atlas/src/orm/schema/SchemaSniffer.d.ts +54 -0
- package/dist/atlas/src/orm/schema/index.d.ts +6 -0
- package/dist/atlas/src/orm/schema/types.d.ts +85 -0
- package/dist/atlas/src/pool/AdaptivePoolManager.d.ts +98 -0
- package/dist/atlas/src/pool/PoolHealthChecker.d.ts +91 -0
- package/dist/atlas/src/pool/PoolStrategy.d.ts +129 -0
- package/dist/atlas/src/pool/PoolWarmer.d.ts +92 -0
- package/dist/atlas/src/query/Expression.d.ts +60 -0
- package/dist/atlas/src/query/NPlusOneDetector.d.ts +10 -0
- package/dist/atlas/src/query/QueryBuilder.d.ts +643 -0
- package/dist/atlas/src/query/RelationshipResolver.d.ts +23 -0
- package/dist/atlas/src/query/clauses/GroupByClause.d.ts +51 -0
- package/dist/atlas/src/query/clauses/HavingClause.d.ts +70 -0
- package/dist/atlas/src/query/clauses/JoinClause.d.ts +87 -0
- package/dist/atlas/src/query/clauses/LimitClause.d.ts +82 -0
- package/dist/atlas/src/query/clauses/OrderByClause.d.ts +69 -0
- package/dist/atlas/src/query/clauses/SelectClause.d.ts +71 -0
- package/dist/atlas/src/query/clauses/WhereClause.d.ts +167 -0
- package/dist/atlas/src/query/clauses/index.d.ts +11 -0
- package/dist/atlas/src/schema/Blueprint.d.ts +276 -0
- package/dist/atlas/src/schema/ColumnDefinition.d.ts +154 -0
- package/dist/atlas/src/schema/ForeignKeyDefinition.d.ts +37 -0
- package/dist/atlas/src/schema/MigrationGenerator.d.ts +45 -0
- package/dist/atlas/src/schema/Schema.d.ts +131 -0
- package/dist/atlas/src/schema/SchemaDiff.d.ts +73 -0
- package/dist/atlas/src/schema/TypeGenerator.d.ts +57 -0
- package/dist/atlas/src/schema/TypeWriter.d.ts +42 -0
- package/dist/atlas/src/schema/grammars/MySQLSchemaGrammar.d.ts +23 -0
- package/dist/atlas/src/schema/grammars/PostgresSchemaGrammar.d.ts +26 -0
- package/dist/atlas/src/schema/grammars/SQLiteSchemaGrammar.d.ts +28 -0
- package/dist/atlas/src/schema/grammars/SchemaGrammar.d.ts +97 -0
- package/dist/atlas/src/schema/grammars/index.d.ts +7 -0
- package/dist/atlas/src/schema/index.d.ts +8 -0
- package/dist/atlas/src/seed/Factory.d.ts +90 -0
- package/dist/atlas/src/seed/Seeder.d.ts +28 -0
- package/dist/atlas/src/seed/SeederRunner.d.ts +74 -0
- package/dist/atlas/src/seed/index.d.ts +6 -0
- package/dist/atlas/src/sharding/ShardingManager.d.ts +59 -0
- package/dist/atlas/src/types/index.d.ts +1182 -0
- package/dist/atlas/src/utils/CursorEncoding.d.ts +63 -0
- package/dist/atlas/src/utils/levenshtein.d.ts +9 -0
- package/dist/core/src/CommandKernel.d.ts +33 -0
- package/dist/core/src/ConfigManager.d.ts +39 -0
- package/dist/core/src/Container/RequestScopeManager.d.ts +62 -0
- package/dist/core/src/Container/RequestScopeMetrics.d.ts +144 -0
- package/dist/core/src/Container.d.ts +86 -11
- package/dist/core/src/ErrorHandler.d.ts +3 -0
- package/dist/core/src/HookManager.d.ts +511 -4
- package/dist/core/src/PlanetCore.d.ts +89 -0
- package/dist/core/src/RequestContext.d.ts +97 -0
- package/dist/core/src/Router.d.ts +1 -5
- package/dist/core/src/ServiceProvider.d.ts +22 -0
- package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +1 -0
- package/dist/core/src/adapters/PhotonAdapter.d.ts +5 -0
- package/dist/core/src/adapters/bun/BunContext.d.ts +4 -0
- package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +1 -0
- package/dist/core/src/adapters/types.d.ts +27 -0
- package/dist/core/src/cli/queue-commands.d.ts +6 -0
- package/dist/core/src/engine/AOTRouter.d.ts +7 -12
- package/dist/core/src/engine/FastContext.d.ts +27 -2
- package/dist/core/src/engine/Gravito.d.ts +0 -1
- package/dist/core/src/engine/MinimalContext.d.ts +25 -2
- package/dist/core/src/engine/types.d.ts +9 -1
- package/dist/core/src/error-handling/RequestScopeErrorContext.d.ts +126 -0
- package/dist/core/src/events/BackpressureManager.d.ts +215 -0
- package/dist/core/src/events/CircuitBreaker.d.ts +229 -0
- package/dist/core/src/events/DeadLetterQueue.d.ts +219 -0
- package/dist/core/src/events/EventBackend.d.ts +12 -0
- package/dist/core/src/events/EventOptions.d.ts +204 -0
- package/dist/core/src/events/EventPriorityQueue.d.ts +301 -0
- package/dist/core/src/events/FlowControlStrategy.d.ts +109 -0
- package/dist/core/src/events/IdempotencyCache.d.ts +60 -0
- package/dist/core/src/events/MessageQueueBridge.d.ts +184 -0
- package/dist/core/src/events/PriorityEscalationManager.d.ts +82 -0
- package/dist/core/src/events/RetryScheduler.d.ts +104 -0
- package/dist/core/src/events/WorkerPool.d.ts +98 -0
- package/dist/core/src/events/WorkerPoolConfig.d.ts +153 -0
- package/dist/core/src/events/WorkerPoolMetrics.d.ts +65 -0
- package/dist/core/src/events/aggregation/AggregationWindow.d.ts +77 -0
- package/dist/core/src/events/aggregation/DeduplicationManager.d.ts +135 -0
- package/dist/core/src/events/aggregation/EventAggregationManager.d.ts +108 -0
- package/dist/core/src/events/aggregation/EventBatcher.d.ts +99 -0
- package/dist/core/src/events/aggregation/types.d.ts +117 -0
- package/dist/core/src/events/index.d.ts +25 -0
- package/dist/core/src/events/observability/EventMetrics.d.ts +132 -0
- package/dist/core/src/events/observability/EventTracer.d.ts +68 -0
- package/dist/core/src/events/observability/EventTracing.d.ts +161 -0
- package/dist/core/src/events/observability/OTelEventMetrics.d.ts +332 -0
- package/dist/core/src/events/observability/ObservableHookManager.d.ts +108 -0
- package/dist/core/src/events/observability/StreamWorkerMetrics.d.ts +76 -0
- package/dist/core/src/events/observability/index.d.ts +24 -0
- package/dist/core/src/events/observability/metrics-types.d.ts +16 -0
- package/dist/core/src/events/types.d.ts +134 -0
- package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
- package/dist/core/src/exceptions/index.d.ts +1 -0
- package/dist/core/src/health/HealthProvider.d.ts +67 -0
- package/dist/core/src/http/types.d.ts +40 -0
- package/dist/core/src/index.d.ts +25 -4
- package/dist/core/src/instrumentation/index.d.ts +35 -0
- package/dist/core/src/instrumentation/opentelemetry.d.ts +178 -0
- package/dist/core/src/instrumentation/types.d.ts +182 -0
- package/dist/core/src/observability/Metrics.d.ts +244 -0
- package/dist/core/src/observability/QueueDashboard.d.ts +136 -0
- package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +350 -0
- package/dist/core/src/reliability/RetryPolicy.d.ts +217 -0
- package/dist/core/src/reliability/index.d.ts +6 -0
- package/dist/core/src/router/ControllerDispatcher.d.ts +12 -0
- package/dist/core/src/router/RequestValidator.d.ts +20 -0
- package/dist/index.js +6709 -9888
- package/dist/index.js.map +64 -62
- package/dist/photon/src/index.d.ts +19 -0
- package/dist/photon/src/middleware/ratelimit-redis.d.ts +50 -0
- package/dist/photon/src/middleware/ratelimit.d.ts +161 -0
- package/dist/photon/src/openapi.d.ts +19 -0
- package/dist/proto/ripple.proto +120 -0
- package/dist/ripple/src/RippleServer.d.ts +64 -445
- package/dist/ripple/src/channels/ChannelManager.d.ts +25 -10
- package/dist/ripple/src/drivers/NATSDriver.d.ts +87 -0
- package/dist/ripple/src/drivers/RedisDriver.d.ts +30 -1
- package/dist/ripple/src/drivers/index.d.ts +1 -0
- package/dist/ripple/src/engines/BunEngine.d.ts +98 -0
- package/dist/ripple/src/engines/IRippleEngine.d.ts +205 -0
- package/dist/ripple/src/engines/UWebSocketsEngine.d.ts +97 -0
- package/dist/ripple/src/engines/WsEngine.d.ts +69 -0
- package/dist/ripple/src/engines/index.d.ts +15 -0
- package/dist/ripple/src/index.d.ts +2 -0
- package/dist/ripple/src/middleware/InterceptorManager.d.ts +21 -0
- package/dist/ripple/src/observability/RippleMetrics.d.ts +24 -0
- package/dist/ripple/src/reliability/AckManager.d.ts +48 -0
- package/dist/ripple/src/serializers/ISerializer.d.ts +39 -0
- package/dist/ripple/src/serializers/JsonSerializer.d.ts +19 -0
- package/dist/ripple/src/serializers/ProtobufSerializer.d.ts +41 -0
- package/dist/ripple/src/serializers/index.d.ts +3 -0
- package/dist/ripple/src/tracking/SessionManager.d.ts +104 -0
- package/dist/ripple/src/tracking/index.d.ts +1 -0
- package/dist/ripple/src/types.d.ts +188 -12
- package/dist/ripple/src/utils/MessageSerializer.d.ts +33 -23
- package/dist/ripple/src/utils/TokenBucket.d.ts +25 -0
- package/package.json +25 -8
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RippleLogger } from '../logging/Logger';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for a message that is pending acknowledgement.
|
|
4
|
+
*/
|
|
5
|
+
export interface PendingAck {
|
|
6
|
+
clientId: string;
|
|
7
|
+
seq: number;
|
|
8
|
+
timer: ReturnType<typeof setTimeout>;
|
|
9
|
+
resolve: (value: boolean) => void;
|
|
10
|
+
reject: (reason: any) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Manages message acknowledgements for Ripple.
|
|
14
|
+
*
|
|
15
|
+
* @since 3.7.0
|
|
16
|
+
*/
|
|
17
|
+
export declare class AckManager {
|
|
18
|
+
private pendingAcks;
|
|
19
|
+
private nextSeq;
|
|
20
|
+
private logger;
|
|
21
|
+
constructor(logger: RippleLogger);
|
|
22
|
+
/**
|
|
23
|
+
* Register a message that requires acknowledgement.
|
|
24
|
+
*
|
|
25
|
+
* @param clientId - The ID of the client the message was sent to
|
|
26
|
+
* @param timeout - How long to wait for ACK in ms
|
|
27
|
+
* @returns A promise that resolves to true when ACKed, or false if timed out
|
|
28
|
+
*/
|
|
29
|
+
register(clientId: string, timeout?: number): {
|
|
30
|
+
seq: number;
|
|
31
|
+
promise: Promise<boolean>;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Confirm receipt of a message.
|
|
35
|
+
*
|
|
36
|
+
* @param clientId - The ID of the client that sent the ACK
|
|
37
|
+
* @param seq - The sequence number being confirmed
|
|
38
|
+
*/
|
|
39
|
+
confirm(clientId: string, seq: number): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Clear all pending ACKs for a client (e.g., on disconnect).
|
|
42
|
+
*/
|
|
43
|
+
clearClient(clientId: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get the number of pending ACKs.
|
|
46
|
+
*/
|
|
47
|
+
getPendingCount(): number;
|
|
48
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ClientMessage, ServerMessage } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for message serialization strategies.
|
|
4
|
+
*
|
|
5
|
+
* Defines how messages are converted between objects and wire format.
|
|
6
|
+
* Supports different serialization formats (e.g., JSON, Protobuf).
|
|
7
|
+
*/
|
|
8
|
+
export interface ISerializer {
|
|
9
|
+
/** The content type this serializer handles */
|
|
10
|
+
readonly contentType: 'json' | 'protobuf';
|
|
11
|
+
/**
|
|
12
|
+
* Serialize a server message for transmission.
|
|
13
|
+
*
|
|
14
|
+
* @param message - The message to serialize
|
|
15
|
+
* @returns Serialized data (string for text, Buffer/Uint8Array for binary)
|
|
16
|
+
*/
|
|
17
|
+
serialize(message: ServerMessage): string | Buffer | Uint8Array;
|
|
18
|
+
/**
|
|
19
|
+
* Deserialize a client message from wire format.
|
|
20
|
+
*
|
|
21
|
+
* @param data - The raw data received from the client
|
|
22
|
+
* @returns Parsed ClientMessage object
|
|
23
|
+
*/
|
|
24
|
+
deserialize(data: string | Buffer | ArrayBuffer | Uint8Array): ClientMessage;
|
|
25
|
+
/**
|
|
26
|
+
* Serialize message for broadcasting with caching optimization.
|
|
27
|
+
*
|
|
28
|
+
* @param message - The message to broadcast
|
|
29
|
+
*/
|
|
30
|
+
serializeForBroadcast(message: ServerMessage): string | Buffer | Uint8Array;
|
|
31
|
+
/**
|
|
32
|
+
* Clear any broadcast-related caches.
|
|
33
|
+
*/
|
|
34
|
+
clearBroadcastCache(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Get a pre-serialized PONG message for efficient heartbeats.
|
|
37
|
+
*/
|
|
38
|
+
getPongMessage(): string | Buffer | Uint8Array;
|
|
39
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ClientMessage, ServerMessage } from '../types';
|
|
2
|
+
import type { ISerializer } from './ISerializer';
|
|
3
|
+
/**
|
|
4
|
+
* Default JSON serializer implementation.
|
|
5
|
+
*
|
|
6
|
+
* Handles standard JSON serialization with optimizations for broadcasting.
|
|
7
|
+
*/
|
|
8
|
+
export declare class JsonSerializer implements ISerializer {
|
|
9
|
+
readonly contentType = "json";
|
|
10
|
+
/** Pre-serialized pong message */
|
|
11
|
+
private static readonly PONG_MESSAGE;
|
|
12
|
+
/** Cached serialized string for the current broadcast operation */
|
|
13
|
+
private broadcastCache;
|
|
14
|
+
serialize(message: ServerMessage): string;
|
|
15
|
+
deserialize(data: string | Buffer | ArrayBuffer | Uint8Array): ClientMessage;
|
|
16
|
+
serializeForBroadcast(message: ServerMessage): string;
|
|
17
|
+
clearBroadcastCache(): void;
|
|
18
|
+
getPongMessage(): string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ClientMessage, ServerMessage } from '../types';
|
|
2
|
+
import type { ISerializer } from './ISerializer';
|
|
3
|
+
/**
|
|
4
|
+
* Protobuf Serializer implementation.
|
|
5
|
+
*
|
|
6
|
+
* Uses 'ripple.proto' to serialize messages.
|
|
7
|
+
* Requires 'protobufjs' to be installed.
|
|
8
|
+
*/
|
|
9
|
+
export declare class ProtobufSerializer implements ISerializer {
|
|
10
|
+
private options;
|
|
11
|
+
readonly contentType = "protobuf";
|
|
12
|
+
private broadcastCache;
|
|
13
|
+
private initialized;
|
|
14
|
+
constructor(options?: {
|
|
15
|
+
protoPath?: string;
|
|
16
|
+
pure?: boolean;
|
|
17
|
+
});
|
|
18
|
+
/**
|
|
19
|
+
* Resolves the proto file path using a multi-level fallback strategy.
|
|
20
|
+
*
|
|
21
|
+
* Search order:
|
|
22
|
+
* 1. Relative to current file (ESM: import.meta.url)
|
|
23
|
+
* 2. From cwd as package root (common in test environments)
|
|
24
|
+
* 3. From cwd as monorepo root
|
|
25
|
+
*/
|
|
26
|
+
private resolveProtoPath;
|
|
27
|
+
/**
|
|
28
|
+
* Initialize the serializer by loading the .proto file
|
|
29
|
+
*/
|
|
30
|
+
init(): Promise<void>;
|
|
31
|
+
serialize(message: ServerMessage): Uint8Array;
|
|
32
|
+
deserialize(data: string | Buffer | ArrayBuffer | Uint8Array): ClientMessage;
|
|
33
|
+
serializeForBroadcast(message: ServerMessage): Uint8Array;
|
|
34
|
+
clearBroadcastCache(): void;
|
|
35
|
+
getPongMessage(): Uint8Array;
|
|
36
|
+
private checkInitialized;
|
|
37
|
+
private toProtoPayload;
|
|
38
|
+
private fromProtoPayload;
|
|
39
|
+
private encodeData;
|
|
40
|
+
private decodeData;
|
|
41
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Session Manager for reconnection support
|
|
3
|
+
*
|
|
4
|
+
* @module @gravito/ripple/tracking
|
|
5
|
+
*/
|
|
6
|
+
import type { RippleLogger } from '../logging/Logger';
|
|
7
|
+
/**
|
|
8
|
+
* Session data stored for reconnection.
|
|
9
|
+
*/
|
|
10
|
+
export interface SessionData {
|
|
11
|
+
/** Client ID */
|
|
12
|
+
clientId: string;
|
|
13
|
+
/** User ID if authenticated */
|
|
14
|
+
userId?: string | number;
|
|
15
|
+
/** Channels the client was subscribed to */
|
|
16
|
+
channels: string[];
|
|
17
|
+
/** User info for presence channels */
|
|
18
|
+
userInfo?: Record<string, unknown>;
|
|
19
|
+
/** Session expiry timestamp */
|
|
20
|
+
expiresAt: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Manages disconnected client sessions for reconnection support.
|
|
24
|
+
*
|
|
25
|
+
* When a client disconnects, their session is stored temporarily to allow
|
|
26
|
+
* them to reconnect and resume their subscriptions without re-authorization.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const sessionManager = new SessionManager({
|
|
31
|
+
* sessionTTL: 60000, // 1 minute
|
|
32
|
+
* maxSessions: 10000
|
|
33
|
+
* })
|
|
34
|
+
*
|
|
35
|
+
* // On disconnect
|
|
36
|
+
* const token = sessionManager.createSession({
|
|
37
|
+
* clientId: 'client-123',
|
|
38
|
+
* userId: 'user-456',
|
|
39
|
+
* channels: ['news', 'presence-lobby'],
|
|
40
|
+
* userInfo: { name: 'John' }
|
|
41
|
+
* })
|
|
42
|
+
*
|
|
43
|
+
* // On reconnect
|
|
44
|
+
* const session = sessionManager.getSession(token)
|
|
45
|
+
* if (session) {
|
|
46
|
+
* // Restore subscriptions
|
|
47
|
+
* for (const channel of session.channels) {
|
|
48
|
+
* await subscribe(session.clientId, channel)
|
|
49
|
+
* }
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare class SessionManager {
|
|
54
|
+
private config;
|
|
55
|
+
private sessions;
|
|
56
|
+
private cleanupInterval?;
|
|
57
|
+
private logger;
|
|
58
|
+
constructor(config: {
|
|
59
|
+
sessionTTL: number;
|
|
60
|
+
maxSessions: number;
|
|
61
|
+
logger?: RippleLogger;
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Create a new session for a disconnected client.
|
|
65
|
+
*
|
|
66
|
+
* @param data - Session data to store
|
|
67
|
+
* @param token - Optional specific token to use (otherwise generates new UUID)
|
|
68
|
+
* @returns Reconnection token
|
|
69
|
+
*/
|
|
70
|
+
createSession(data: Omit<SessionData, 'expiresAt'>, token?: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Get a session by reconnection token.
|
|
73
|
+
*
|
|
74
|
+
* @param token - Reconnection token
|
|
75
|
+
* @returns Session data if found and not expired, undefined otherwise
|
|
76
|
+
*/
|
|
77
|
+
getSession(token: string): SessionData | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Remove a session by token.
|
|
80
|
+
*
|
|
81
|
+
* @param token - Reconnection token
|
|
82
|
+
*/
|
|
83
|
+
removeSession(token: string): void;
|
|
84
|
+
/**
|
|
85
|
+
* Get the number of active sessions.
|
|
86
|
+
*/
|
|
87
|
+
getSessionCount(): number;
|
|
88
|
+
/**
|
|
89
|
+
* Start periodic cleanup of expired sessions.
|
|
90
|
+
*/
|
|
91
|
+
private startCleanup;
|
|
92
|
+
/**
|
|
93
|
+
* Clean up expired sessions.
|
|
94
|
+
*/
|
|
95
|
+
private cleanupExpiredSessions;
|
|
96
|
+
/**
|
|
97
|
+
* Remove the oldest session to make room for new ones.
|
|
98
|
+
*/
|
|
99
|
+
private removeOldestSession;
|
|
100
|
+
/**
|
|
101
|
+
* Shutdown the session manager and clear all sessions.
|
|
102
|
+
*/
|
|
103
|
+
shutdown(): void;
|
|
104
|
+
}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* @module @gravito/ripple
|
|
4
4
|
*/
|
|
5
5
|
import type { Server, ServerWebSocket } from 'bun';
|
|
6
|
+
import type { NATSDriverConfig } from './drivers/NATSDriver';
|
|
7
|
+
import type { RedisDriverConfig } from './drivers/RedisDriver';
|
|
6
8
|
/**
|
|
7
9
|
* Data attached to each WebSocket connection.
|
|
8
10
|
*
|
|
@@ -28,6 +30,12 @@ export interface ClientData {
|
|
|
28
30
|
channels: Set<string>;
|
|
29
31
|
/** Additional user info for presence channels */
|
|
30
32
|
userInfo?: Record<string, unknown>;
|
|
33
|
+
/** Reconnection token for session recovery (v3.6+) */
|
|
34
|
+
reconnectionToken?: string;
|
|
35
|
+
/** Session expiry timestamp (v3.6+) */
|
|
36
|
+
sessionExpiry?: number;
|
|
37
|
+
/** Remote IP address (v5.0+) */
|
|
38
|
+
remoteAddress?: string;
|
|
31
39
|
}
|
|
32
40
|
/**
|
|
33
41
|
* Supported WebSocket channel types.
|
|
@@ -172,7 +180,7 @@ export interface PresenceUserInfo {
|
|
|
172
180
|
* }
|
|
173
181
|
* ```
|
|
174
182
|
*/
|
|
175
|
-
export type ChannelAuthorizer = (channelName: string, userId: string | number | undefined, socketId: string) => boolean |
|
|
183
|
+
export type ChannelAuthorizer = (channelName: string, userId: string | number | undefined, socketId: string) => boolean | PresenceUserInfo | Promise<boolean | PresenceUserInfo>;
|
|
176
184
|
/**
|
|
177
185
|
* Interface for broadcast event classes.
|
|
178
186
|
*
|
|
@@ -260,6 +268,14 @@ export type ClientMessage = {
|
|
|
260
268
|
data: unknown;
|
|
261
269
|
} | {
|
|
262
270
|
type: 'ping';
|
|
271
|
+
} | {
|
|
272
|
+
type: 'binary';
|
|
273
|
+
channel: string;
|
|
274
|
+
event: string;
|
|
275
|
+
data: ArrayBuffer;
|
|
276
|
+
} | {
|
|
277
|
+
type: 'ack';
|
|
278
|
+
seq: number;
|
|
263
279
|
};
|
|
264
280
|
/**
|
|
265
281
|
* Error codes for Ripple WebSocket protocol.
|
|
@@ -349,17 +365,54 @@ export type ServerMessage = {
|
|
|
349
365
|
channel: string;
|
|
350
366
|
event: string;
|
|
351
367
|
data: unknown;
|
|
368
|
+
seq?: number;
|
|
369
|
+
needAck?: boolean;
|
|
352
370
|
} | {
|
|
353
371
|
type: 'presence';
|
|
354
372
|
channel: string;
|
|
355
373
|
event: 'join' | 'leave' | 'members';
|
|
356
374
|
data: unknown;
|
|
375
|
+
seq?: number;
|
|
376
|
+
needAck?: boolean;
|
|
357
377
|
} | {
|
|
358
378
|
type: 'pong';
|
|
359
379
|
} | {
|
|
360
380
|
type: 'connected';
|
|
361
381
|
socketId: string;
|
|
382
|
+
} | {
|
|
383
|
+
type: 'binary';
|
|
384
|
+
channel: string;
|
|
385
|
+
event: string;
|
|
386
|
+
data: ArrayBuffer;
|
|
387
|
+
seq?: number;
|
|
388
|
+
needAck?: boolean;
|
|
389
|
+
} | {
|
|
390
|
+
type: 'ack_received';
|
|
391
|
+
seq: number;
|
|
392
|
+
} | {
|
|
393
|
+
type: 'reconnection_token';
|
|
394
|
+
token: string;
|
|
362
395
|
};
|
|
396
|
+
/**
|
|
397
|
+
* Context for Ripple Message Interceptors (v4.0+).
|
|
398
|
+
*/
|
|
399
|
+
export interface RippleContext {
|
|
400
|
+
/** The WebSocket client connection */
|
|
401
|
+
ws: import('./engines/IRippleEngine').RippleSocket;
|
|
402
|
+
/** The message being processed */
|
|
403
|
+
message: ClientMessage | ServerMessage;
|
|
404
|
+
/** Direction of the message flow */
|
|
405
|
+
direction: 'incoming' | 'outgoing';
|
|
406
|
+
/** Channel name (optional) */
|
|
407
|
+
channel?: string;
|
|
408
|
+
/** Event name (optional) */
|
|
409
|
+
event?: string;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Middleware function for intercepting Ripple messages.
|
|
413
|
+
* Next function must be called to continue the pipeline.
|
|
414
|
+
*/
|
|
415
|
+
export type RippleInterceptor = (ctx: RippleContext, next: () => Promise<void>) => Promise<void> | void;
|
|
363
416
|
/**
|
|
364
417
|
* Driver health status information.
|
|
365
418
|
*
|
|
@@ -410,6 +463,8 @@ export declare const SERVER_MESSAGE_TYPES: {
|
|
|
410
463
|
readonly PRESENCE: "presence";
|
|
411
464
|
readonly PONG: "pong";
|
|
412
465
|
readonly CONNECTED: "connected";
|
|
466
|
+
readonly BINARY: "binary";
|
|
467
|
+
readonly RECONNECTION_TOKEN: "reconnection_token";
|
|
413
468
|
};
|
|
414
469
|
/**
|
|
415
470
|
* Client message type constants.
|
|
@@ -432,6 +487,8 @@ export declare const CLIENT_MESSAGE_TYPES: {
|
|
|
432
487
|
readonly UNSUBSCRIBE: "unsubscribe";
|
|
433
488
|
readonly WHISPER: "whisper";
|
|
434
489
|
readonly PING: "ping";
|
|
490
|
+
readonly BINARY: "binary";
|
|
491
|
+
readonly ACK: "ack";
|
|
435
492
|
};
|
|
436
493
|
/**
|
|
437
494
|
* Interface for implementing custom Ripple drivers.
|
|
@@ -445,8 +502,10 @@ export declare const CLIENT_MESSAGE_TYPES: {
|
|
|
445
502
|
* @example
|
|
446
503
|
* ```typescript
|
|
447
504
|
* // Example: Custom NATS driver implementation
|
|
448
|
-
* import {
|
|
449
|
-
|
|
505
|
+
* import type { RedisDriverConfig } from './drivers/RedisDriver'
|
|
506
|
+
import type { NATSDriverConfig } from './drivers/NATSDriver'
|
|
507
|
+
import type { ComponentHealth } from './health/HealthChecker'
|
|
508
|
+
import { connect, NatsConnection, Subscription } from 'nats'
|
|
450
509
|
*
|
|
451
510
|
* export class NatsDriver implements RippleDriver {
|
|
452
511
|
* readonly name = 'nats'
|
|
@@ -549,6 +608,35 @@ export interface RippleDriver {
|
|
|
549
608
|
* @returns Current driver status
|
|
550
609
|
*/
|
|
551
610
|
getStatus?(): DriverStatus;
|
|
611
|
+
/**
|
|
612
|
+
* Track a presence member in a channel (optional).
|
|
613
|
+
*
|
|
614
|
+
* For distributed drivers like Redis, this stores presence information
|
|
615
|
+
* in a shared backend so all server instances can see the same members.
|
|
616
|
+
*
|
|
617
|
+
* @param channel - Presence channel name
|
|
618
|
+
* @param userInfo - User information to track
|
|
619
|
+
* @since 3.6.0
|
|
620
|
+
*/
|
|
621
|
+
trackPresence?(channel: string, userInfo: PresenceUserInfo): Promise<void>;
|
|
622
|
+
/**
|
|
623
|
+
* Remove a presence member from a channel (optional).
|
|
624
|
+
*
|
|
625
|
+
* @param channel - Presence channel name
|
|
626
|
+
* @param userId - User ID to remove
|
|
627
|
+
* @since 3.6.0
|
|
628
|
+
*/
|
|
629
|
+
untrackPresence?(channel: string, userId: string | number): Promise<void>;
|
|
630
|
+
/**
|
|
631
|
+
* Get all presence members for a channel (optional).
|
|
632
|
+
*
|
|
633
|
+
* For distributed drivers, this retrieves members from the shared backend.
|
|
634
|
+
*
|
|
635
|
+
* @param channel - Presence channel name
|
|
636
|
+
* @returns Array of presence user information
|
|
637
|
+
* @since 3.6.0
|
|
638
|
+
*/
|
|
639
|
+
getPresenceMembers?(channel: string): Promise<PresenceUserInfo[]>;
|
|
552
640
|
}
|
|
553
641
|
/**
|
|
554
642
|
* Ripple server configuration.
|
|
@@ -631,15 +719,12 @@ export interface RippleConfig {
|
|
|
631
719
|
path?: string;
|
|
632
720
|
/** Authentication endpoint for private/presence channels */
|
|
633
721
|
authEndpoint?: string;
|
|
634
|
-
/** Driver to use ('local' | 'redis') */
|
|
635
|
-
driver?: 'local' | 'redis';
|
|
636
|
-
/**
|
|
637
|
-
redis?:
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
password?: string;
|
|
641
|
-
db?: number;
|
|
642
|
-
};
|
|
722
|
+
/** Driver to use for scaling ('local' | 'redis' | 'nats') */
|
|
723
|
+
driver?: 'local' | 'redis' | 'nats';
|
|
724
|
+
/** Configuration for Redis driver */
|
|
725
|
+
redis?: RedisDriverConfig;
|
|
726
|
+
/** Configuration for NATS driver (v4.0+) */
|
|
727
|
+
nats?: NATSDriverConfig;
|
|
643
728
|
/** Channel authorizer function */
|
|
644
729
|
authorizer?: ChannelAuthorizer;
|
|
645
730
|
/** Ping interval in milliseconds (default: 30000) */
|
|
@@ -655,6 +740,97 @@ export interface RippleConfig {
|
|
|
655
740
|
enabled: boolean;
|
|
656
741
|
path?: string;
|
|
657
742
|
};
|
|
743
|
+
/**
|
|
744
|
+
* Rate limiting configuration.
|
|
745
|
+
*/
|
|
746
|
+
rateLimit?: {
|
|
747
|
+
/** Max whispers per interval */
|
|
748
|
+
whisperMax?: number;
|
|
749
|
+
/** Interval in milliseconds for whisper limit (default: 1000) */
|
|
750
|
+
whisperInterval?: number;
|
|
751
|
+
};
|
|
752
|
+
/**
|
|
753
|
+
* Reconnection configuration (v3.6+).
|
|
754
|
+
*/
|
|
755
|
+
reconnection?: {
|
|
756
|
+
/** Enable server-assisted reconnection (default: false) */
|
|
757
|
+
enabled?: boolean;
|
|
758
|
+
/** Session TTL in milliseconds (default: 60000 = 1 minute) */
|
|
759
|
+
sessionTTL?: number;
|
|
760
|
+
/** Maximum number of stored sessions (default: 10000) */
|
|
761
|
+
maxSessions?: number;
|
|
762
|
+
};
|
|
763
|
+
/**
|
|
764
|
+
* Serializer to use for messages (default: 'json').
|
|
765
|
+
*
|
|
766
|
+
* 'json': Recommended for most use cases. Zero configuration,
|
|
767
|
+
* browser-native, easy debugging. No additional dependencies.
|
|
768
|
+
*
|
|
769
|
+
* 'protobuf': For specialized use cases (IoT, bandwidth-constrained networks).
|
|
770
|
+
* Requires 'protobufjs' peer dependency to be installed.
|
|
771
|
+
* Install with: npm install protobufjs
|
|
772
|
+
*/
|
|
773
|
+
serializer?: 'json' | 'protobuf';
|
|
774
|
+
/**
|
|
775
|
+
* Configuration for the serializer (v5.0+).
|
|
776
|
+
*/
|
|
777
|
+
serializerOptions?: {
|
|
778
|
+
/** Path to custom .proto file (Protobuf only) */
|
|
779
|
+
protoPath?: string;
|
|
780
|
+
/** Enable pure binary mode (no JSON envelope for payload) - Protobuf only (default: false) */
|
|
781
|
+
pure?: boolean;
|
|
782
|
+
};
|
|
783
|
+
/**
|
|
784
|
+
* Performance & Backpressure (v3.7+).
|
|
785
|
+
*/
|
|
786
|
+
backpressure?: {
|
|
787
|
+
/** High Water Mark in bytes. Force disconnect if reached. (default: 5,242,880 = 5MB) */
|
|
788
|
+
hwmHigh?: number;
|
|
789
|
+
/** Low Water Mark in bytes. Skip non-critical events if reached. (default: 1,048,576 = 1MB) */
|
|
790
|
+
hwmLow?: number;
|
|
791
|
+
/** Whether to enable automatic slow client isolation (default: false) */
|
|
792
|
+
enabled?: boolean;
|
|
793
|
+
};
|
|
794
|
+
/**
|
|
795
|
+
* Prometheus Metrics (v3.7+).
|
|
796
|
+
*/
|
|
797
|
+
metrics?: {
|
|
798
|
+
/** Enable Prometheus metrics (default: false) */
|
|
799
|
+
enabled?: boolean;
|
|
800
|
+
/** Metric name prefix (default: 'ripple') */
|
|
801
|
+
prefix?: string;
|
|
802
|
+
};
|
|
803
|
+
/**
|
|
804
|
+
* Message Interceptors (v4.0+).
|
|
805
|
+
*/
|
|
806
|
+
interceptors?: RippleInterceptor[];
|
|
807
|
+
/**
|
|
808
|
+
* WebSocket runtime/engine to use (v5.0+).
|
|
809
|
+
*
|
|
810
|
+
* - 'bun': Bun native WebSocket (default, highest performance)
|
|
811
|
+
* - 'node-uws': uWebSockets.js for Node.js (high performance, requires peer dep)
|
|
812
|
+
* - 'node-ws': ws package for Node.js (standard, best compatibility)
|
|
813
|
+
*
|
|
814
|
+
* If not specified, Ripple will auto-detect the runtime.
|
|
815
|
+
*
|
|
816
|
+
* @since 5.0.0
|
|
817
|
+
*/
|
|
818
|
+
runtime?: 'bun' | 'node-uws' | 'node-ws';
|
|
819
|
+
/**
|
|
820
|
+
* Server port to listen on (v5.0+).
|
|
821
|
+
*
|
|
822
|
+
* Required when using the engine-based architecture.
|
|
823
|
+
*
|
|
824
|
+
* @since 5.0.0
|
|
825
|
+
*/
|
|
826
|
+
port?: number;
|
|
827
|
+
/**
|
|
828
|
+
* Hostname to bind to (v5.0+).
|
|
829
|
+
*
|
|
830
|
+
* @default '0.0.0.0'
|
|
831
|
+
* @since 5.0.0
|
|
832
|
+
*/
|
|
833
|
+
hostname?: string;
|
|
658
834
|
}
|
|
659
835
|
/**
|
|
660
836
|
* Strongly-typed Bun ServerWebSocket for Ripple.
|
|
@@ -1,44 +1,54 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ISerializer } from '../serializers/ISerializer';
|
|
2
|
+
import type { ClientMessage, ServerMessage } from '../types';
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
+
* 訊息序列化器,用於 JSON 格式的訊息序列化與反序列化。
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* multi-channel broadcasting.
|
|
6
|
+
* 實現了廣播消息的緩存優化,確保相同的訊息只被序列化一次,
|
|
7
|
+
* 然後發送給所有客戶端,從而減少 CPU 開銷。
|
|
8
8
|
*/
|
|
9
|
-
export declare class MessageSerializer {
|
|
10
|
-
|
|
9
|
+
export declare class MessageSerializer implements ISerializer {
|
|
10
|
+
readonly contentType = "json";
|
|
11
|
+
/** 預序列化的 PONG 訊息 */
|
|
11
12
|
private static readonly PONG_MESSAGE;
|
|
12
|
-
/**
|
|
13
|
+
/** 廣播訊息緩存 */
|
|
13
14
|
private broadcastCache;
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
+
* 序列化伺服器訊息為 JSON 字符串。
|
|
16
17
|
*
|
|
17
|
-
* @
|
|
18
|
+
* @param message - 要序列化的訊息
|
|
19
|
+
* @returns JSON 字符串
|
|
18
20
|
*/
|
|
19
|
-
|
|
21
|
+
serialize(message: ServerMessage): string;
|
|
20
22
|
/**
|
|
21
|
-
*
|
|
23
|
+
* 將訊息反序列化為客戶端訊息物件。
|
|
22
24
|
*
|
|
23
|
-
* @param
|
|
24
|
-
* @returns
|
|
25
|
+
* @param data - 原始數據
|
|
26
|
+
* @returns 解析後的客戶端訊息
|
|
25
27
|
*/
|
|
26
|
-
|
|
28
|
+
deserialize(data: string | Buffer | ArrayBuffer): ClientMessage;
|
|
27
29
|
/**
|
|
28
|
-
*
|
|
30
|
+
* 為廣播序列化訊息,支援緩存優化。
|
|
29
31
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
+
* 第一次序列化時會緩存結果,後續相同的訊息會直接返回緩存值,
|
|
33
|
+
* 避免重複序列化。這在廣播給大量客戶端時可以顯著減少 CPU 使用。
|
|
32
34
|
*
|
|
33
|
-
* @param message -
|
|
34
|
-
* @returns
|
|
35
|
+
* @param message - 要廣播的訊息
|
|
36
|
+
* @returns 序列化的訊息
|
|
35
37
|
*/
|
|
36
38
|
serializeForBroadcast(message: ServerMessage): string;
|
|
37
39
|
/**
|
|
38
|
-
*
|
|
40
|
+
* 清除廣播訊息緩存。
|
|
39
41
|
*
|
|
40
|
-
*
|
|
41
|
-
* for the next broadcast.
|
|
42
|
+
* 應在訊息發送完成後調用,以釋放記憶體。
|
|
42
43
|
*/
|
|
43
44
|
clearBroadcastCache(): void;
|
|
45
|
+
/**
|
|
46
|
+
* 取得預序列化的 PONG 訊息。
|
|
47
|
+
*
|
|
48
|
+
* PONG 訊息是一個常用的心跳訊息,為了效率我們將其預序列化為常數,
|
|
49
|
+
* 每次都返回相同的字符串引用,無需重複序列化。
|
|
50
|
+
*
|
|
51
|
+
* @returns 預序列化的 PONG 訊息
|
|
52
|
+
*/
|
|
53
|
+
getPongMessage(): string;
|
|
44
54
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Token Bucket algorithm for rate limiting.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
export declare class TokenBucket {
|
|
7
|
+
private capacity;
|
|
8
|
+
private fillRatePerMs;
|
|
9
|
+
private tokens;
|
|
10
|
+
private lastRefill;
|
|
11
|
+
/**
|
|
12
|
+
* Create a new TokenBucket instance.
|
|
13
|
+
*
|
|
14
|
+
* @param capacity - Max tokens in the bucket.
|
|
15
|
+
* @param fillRatePerMs - Rate at which tokens are added (tokens per millisecond).
|
|
16
|
+
*/
|
|
17
|
+
constructor(capacity: number, fillRatePerMs: number);
|
|
18
|
+
/**
|
|
19
|
+
* Consume a token from the bucket.
|
|
20
|
+
*
|
|
21
|
+
* @returns true if token was consumed, false if bucket is empty.
|
|
22
|
+
*/
|
|
23
|
+
consume(): boolean;
|
|
24
|
+
private refill;
|
|
25
|
+
}
|