@gravito/radiance 1.0.3 → 1.0.5
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 +30 -7
- package/README.zh-TW.md +238 -3
- package/dist/core/src/Application.d.ts +256 -0
- package/dist/core/src/CommandKernel.d.ts +33 -0
- package/dist/core/src/ConfigManager.d.ts +65 -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 +153 -0
- package/dist/core/src/ErrorHandler.d.ts +66 -0
- package/dist/core/src/Event.d.ts +5 -0
- package/dist/core/src/EventManager.d.ts +123 -0
- package/dist/core/src/GlobalErrorHandlers.d.ts +47 -0
- package/dist/core/src/GravitoServer.d.ts +28 -0
- package/dist/core/src/HookManager.d.ts +435 -0
- package/dist/core/src/Listener.d.ts +4 -0
- package/dist/core/src/Logger.d.ts +20 -0
- package/dist/core/src/PlanetCore.d.ts +402 -0
- package/dist/core/src/RequestContext.d.ts +97 -0
- package/dist/core/src/Route.d.ts +36 -0
- package/dist/core/src/Router.d.ts +270 -0
- package/dist/core/src/ServiceProvider.d.ts +178 -0
- package/dist/core/src/adapters/GravitoEngineAdapter.d.ts +27 -0
- package/dist/core/src/adapters/bun/BunContext.d.ts +54 -0
- package/dist/core/src/adapters/bun/BunNativeAdapter.d.ts +66 -0
- package/dist/core/src/adapters/bun/BunRequest.d.ts +31 -0
- package/dist/core/src/adapters/bun/BunWebSocketHandler.d.ts +48 -0
- package/dist/core/src/adapters/bun/RadixNode.d.ts +19 -0
- package/dist/core/src/adapters/bun/RadixRouter.d.ts +32 -0
- package/dist/core/src/adapters/bun/index.d.ts +7 -0
- package/dist/core/src/adapters/bun/types.d.ts +20 -0
- package/dist/core/src/adapters/types.d.ts +235 -0
- package/dist/core/src/binary/BinaryUtils.d.ts +105 -0
- package/dist/core/src/binary/index.d.ts +5 -0
- package/dist/core/src/cli/queue-commands.d.ts +6 -0
- package/dist/core/src/compat/async-local-storage.d.ts +7 -0
- package/dist/core/src/compat/crypto.d.ts +6 -0
- package/dist/core/src/engine/AOTRouter.d.ts +139 -0
- package/dist/core/src/engine/FastContext.d.ts +141 -0
- package/dist/core/src/engine/Gravito.d.ts +131 -0
- package/dist/core/src/engine/MinimalContext.d.ts +102 -0
- package/dist/core/src/engine/analyzer.d.ts +113 -0
- package/dist/core/src/engine/constants.d.ts +23 -0
- package/dist/core/src/engine/index.d.ts +26 -0
- package/dist/core/src/engine/path.d.ts +26 -0
- package/dist/core/src/engine/pool.d.ts +83 -0
- package/dist/core/src/engine/types.d.ts +149 -0
- 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 +63 -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 +26 -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/queue-core.d.ts +77 -0
- package/dist/core/src/events/task-executor.d.ts +51 -0
- package/dist/core/src/events/types.d.ts +134 -0
- package/dist/core/src/exceptions/AuthenticationException.d.ts +8 -0
- package/dist/core/src/exceptions/AuthorizationException.d.ts +8 -0
- package/dist/core/src/exceptions/CircularDependencyException.d.ts +9 -0
- package/dist/core/src/exceptions/GravitoException.d.ts +23 -0
- package/dist/core/src/exceptions/HttpException.d.ts +9 -0
- package/dist/core/src/exceptions/ModelNotFoundException.d.ts +10 -0
- package/dist/core/src/exceptions/ValidationException.d.ts +22 -0
- package/dist/core/src/exceptions/index.d.ts +7 -0
- package/dist/core/src/ffi/NativeAccelerator.d.ts +62 -0
- package/dist/core/src/ffi/NativeHasher.d.ts +139 -0
- package/dist/core/src/ffi/cbor-fallback.d.ts +96 -0
- package/dist/core/src/ffi/hash-fallback.d.ts +33 -0
- package/dist/core/src/ffi/index.d.ts +10 -0
- package/dist/core/src/ffi/types.d.ts +135 -0
- package/dist/core/src/health/HealthProvider.d.ts +67 -0
- package/dist/core/src/helpers/Arr.d.ts +19 -0
- package/dist/core/src/helpers/Str.d.ts +38 -0
- package/dist/core/src/helpers/data.d.ts +25 -0
- package/dist/core/src/helpers/errors.d.ts +34 -0
- package/dist/core/src/helpers/response.d.ts +41 -0
- package/dist/core/src/helpers.d.ts +338 -0
- package/dist/core/src/hooks/ActionManager.d.ts +132 -0
- package/dist/core/src/hooks/AsyncDetector.d.ts +84 -0
- package/dist/core/src/hooks/FilterManager.d.ts +71 -0
- package/dist/core/src/hooks/MigrationWarner.d.ts +24 -0
- package/dist/core/src/hooks/dlq-operations.d.ts +60 -0
- package/dist/core/src/hooks/types.d.ts +107 -0
- package/dist/core/src/http/CookieJar.d.ts +51 -0
- package/dist/core/src/http/cookie.d.ts +29 -0
- package/dist/core/src/http/types.d.ts +395 -0
- package/dist/core/src/index.d.ts +565 -0
- package/dist/core/src/observability/QueueDashboard.d.ts +136 -0
- package/dist/core/src/observability/contracts.d.ts +137 -0
- package/dist/core/src/reliability/DeadLetterQueueManager.d.ts +349 -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/core/src/runtime/adapter-bun.d.ts +12 -0
- package/dist/core/src/runtime/adapter-deno.d.ts +12 -0
- package/dist/core/src/runtime/adapter-node.d.ts +12 -0
- package/dist/core/src/runtime/adapter-unknown.d.ts +13 -0
- package/dist/core/src/runtime/archive.d.ts +17 -0
- package/dist/core/src/runtime/compression.d.ts +21 -0
- package/dist/core/src/runtime/deep-equals.d.ts +56 -0
- package/dist/core/src/runtime/detection.d.ts +22 -0
- package/dist/core/src/runtime/escape.d.ts +34 -0
- package/dist/core/src/runtime/index.d.ts +44 -0
- package/dist/core/src/runtime/markdown.d.ts +44 -0
- package/dist/core/src/runtime/types.d.ts +436 -0
- package/dist/core/src/runtime-helpers.d.ts +67 -0
- package/dist/core/src/runtime.d.ts +11 -0
- package/dist/core/src/security/Encrypter.d.ts +33 -0
- package/dist/core/src/security/Hasher.d.ts +29 -0
- package/dist/core/src/testing/HttpTester.d.ts +40 -0
- package/dist/core/src/testing/TestResponse.d.ts +78 -0
- package/dist/core/src/testing/index.d.ts +2 -0
- package/dist/core/src/transpiler-utils.d.ts +170 -0
- package/dist/core/src/types/events.d.ts +94 -0
- package/dist/index.js +1 -274
- package/dist/index.js.map +3 -10
- package/dist/radiance/src/BroadcastManager.d.ts +124 -0
- package/dist/radiance/src/OrbitRadiance.d.ts +98 -0
- package/dist/radiance/src/channels/Channel.d.ts +86 -0
- package/dist/radiance/src/drivers/AblyDriver.d.ts +73 -0
- package/dist/radiance/src/drivers/BroadcastDriver.d.ts +50 -0
- package/dist/radiance/src/drivers/PusherDriver.d.ts +95 -0
- package/dist/radiance/src/drivers/RedisDriver.d.ts +83 -0
- package/dist/radiance/src/drivers/WebSocketDriver.d.ts +89 -0
- package/dist/radiance/src/index.d.ts +39 -0
- package/package.json +10 -6
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { PlanetCore } from '@gravito/core';
|
|
2
|
+
import type { BroadcastDriver } from './drivers/BroadcastDriver';
|
|
3
|
+
/**
|
|
4
|
+
* Channel authorization callback.
|
|
5
|
+
*
|
|
6
|
+
* Used to verify if a user has permission to join a specific broadcast channel.
|
|
7
|
+
*
|
|
8
|
+
* @param channel - The name of the channel to authorize
|
|
9
|
+
* @param socketId - The unique identifier for the client connection
|
|
10
|
+
* @param userId - The identifier of the user requesting access
|
|
11
|
+
* @returns True if the user is authorized to join the channel
|
|
12
|
+
*/
|
|
13
|
+
export type ChannelAuthorizationCallback = (channel: string, socketId: string, userId?: string | number) => Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Central manager for real-time event broadcasting.
|
|
16
|
+
*
|
|
17
|
+
* Orchestrates the delivery of events to various broadcast drivers and handles
|
|
18
|
+
* channel authorization logic. It acts as a bridge between Gravito's event system
|
|
19
|
+
* and external real-time services.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const manager = new BroadcastManager(core);
|
|
24
|
+
* manager.setDriver(new PusherDriver(config));
|
|
25
|
+
* await manager.broadcast(null, { name: 'orders', type: 'public' }, { id: 1 }, 'OrderCreated');
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class BroadcastManager {
|
|
29
|
+
private core;
|
|
30
|
+
private driver;
|
|
31
|
+
private authCallback?;
|
|
32
|
+
private throwOnError;
|
|
33
|
+
constructor(core: PlanetCore);
|
|
34
|
+
/**
|
|
35
|
+
* Configure error handling behavior for broadcast operations.
|
|
36
|
+
*
|
|
37
|
+
* Determines whether failures in the underlying broadcast driver should
|
|
38
|
+
* propagate as exceptions or be silently logged.
|
|
39
|
+
*
|
|
40
|
+
* @param throwOnError - Enable or disable exception propagation on failure
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* manager.setThrowOnError(false); // Log errors instead of throwing
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
setThrowOnError(throwOnError: boolean): void;
|
|
48
|
+
/**
|
|
49
|
+
* Assign the active broadcast delivery driver.
|
|
50
|
+
*
|
|
51
|
+
* Sets the driver responsible for the actual transmission of event data
|
|
52
|
+
* to the real-time service (e.g., Pusher, Ably, Redis).
|
|
53
|
+
*
|
|
54
|
+
* @param driver - The broadcast driver implementation to use
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* manager.setDriver(new RedisDriver(config));
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
setDriver(driver: BroadcastDriver): void;
|
|
62
|
+
/**
|
|
63
|
+
* Register a custom authorization logic for private channels.
|
|
64
|
+
*
|
|
65
|
+
* Provides a hook to implement business-specific permission checks
|
|
66
|
+
* before allowing a client to subscribe to restricted channels.
|
|
67
|
+
*
|
|
68
|
+
* @param callback - The authorization logic implementation
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* manager.setAuthCallback(async (channel, socketId, userId) => {
|
|
73
|
+
* return userId === 'admin';
|
|
74
|
+
* });
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
setAuthCallback(callback: ChannelAuthorizationCallback): void;
|
|
78
|
+
/**
|
|
79
|
+
* Transmit an event payload to a specific channel.
|
|
80
|
+
*
|
|
81
|
+
* Forwards the event data to the configured driver. If no driver is set,
|
|
82
|
+
* the broadcast is skipped with a warning.
|
|
83
|
+
*
|
|
84
|
+
* @param _event - The original event instance (reserved for future use)
|
|
85
|
+
* @param channel - Target channel metadata including name and visibility type
|
|
86
|
+
* @param data - The serializable payload to be transmitted
|
|
87
|
+
* @param eventName - The name of the event as it will appear on the client
|
|
88
|
+
* @throws {Error} If the driver fails and throwOnError is enabled
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* await manager.broadcast(
|
|
93
|
+
* null,
|
|
94
|
+
* { name: 'private-user.1', type: 'private' },
|
|
95
|
+
* { message: 'Hello' },
|
|
96
|
+
* 'UserMessage'
|
|
97
|
+
* );
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
broadcast(_event: unknown, channel: {
|
|
101
|
+
name: string;
|
|
102
|
+
type: string;
|
|
103
|
+
}, data: Record<string, unknown>, eventName: string): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Validate client access to a specific channel.
|
|
106
|
+
*
|
|
107
|
+
* Executes the registered authorization callback and, if available,
|
|
108
|
+
* delegates to the driver's native authorization mechanism.
|
|
109
|
+
*
|
|
110
|
+
* @param channel - The name of the channel to authorize
|
|
111
|
+
* @param socketId - The unique identifier for the client connection
|
|
112
|
+
* @param userId - The identifier of the user requesting access
|
|
113
|
+
* @returns The authorization payload or null if access is denied
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const auth = await manager.authorizeChannel('private-user.1', '123.456', 'user_1');
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
authorizeChannel(channel: string, socketId: string, userId?: string | number): Promise<{
|
|
121
|
+
auth: string;
|
|
122
|
+
channel_data?: string;
|
|
123
|
+
} | null>;
|
|
124
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { GravitoOrbit, PlanetCore } from '@gravito/core';
|
|
2
|
+
import { BroadcastManager } from './BroadcastManager';
|
|
3
|
+
import type { AblyDriverConfig } from './drivers/AblyDriver';
|
|
4
|
+
import type { PusherDriverConfig } from './drivers/PusherDriver';
|
|
5
|
+
import type { RedisDriverConfig } from './drivers/RedisDriver';
|
|
6
|
+
import type { WebSocketDriverConfig } from './drivers/WebSocketDriver';
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for the Radiance broadcasting orbit.
|
|
9
|
+
*
|
|
10
|
+
* Defines the delivery provider, its specific credentials, and optional
|
|
11
|
+
* hooks for security and error handling.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export interface OrbitRadianceOptions {
|
|
16
|
+
/**
|
|
17
|
+
* The underlying delivery service provider.
|
|
18
|
+
*
|
|
19
|
+
* - pusher: Industry standard WebSocket service
|
|
20
|
+
* - ably: High-reliability global edge network
|
|
21
|
+
* - redis: Pub/Sub for internal microservices
|
|
22
|
+
* - websocket: Direct server-to-client communication
|
|
23
|
+
*/
|
|
24
|
+
driver: 'pusher' | 'ably' | 'redis' | 'websocket';
|
|
25
|
+
/**
|
|
26
|
+
* Provider-specific connection and authentication settings.
|
|
27
|
+
*/
|
|
28
|
+
config: PusherDriverConfig | AblyDriverConfig | RedisDriverConfig | WebSocketDriverConfig;
|
|
29
|
+
/**
|
|
30
|
+
* Hook for implementing custom channel access control.
|
|
31
|
+
*
|
|
32
|
+
* @param channel - The name of the channel being accessed
|
|
33
|
+
* @param socketId - The unique client connection identifier
|
|
34
|
+
* @param userId - The authenticated user's identifier
|
|
35
|
+
* @returns True if the subscription request should be granted
|
|
36
|
+
*/
|
|
37
|
+
authorizeChannel?: (channel: string, socketId: string, userId?: string | number) => Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Control whether broadcast failures should interrupt the execution flow.
|
|
40
|
+
* @defaultValue true
|
|
41
|
+
*/
|
|
42
|
+
throwOnError?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* OrbitRadiance provides real-time event broadcasting capabilities.
|
|
46
|
+
*
|
|
47
|
+
* It abstracts various delivery providers (Pusher, Ably, etc.) and integrates
|
|
48
|
+
* seamlessly with Gravito's Event system. When installed, it enables automatic
|
|
49
|
+
* broadcasting of events that implement the `ShouldBroadcast` interface.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const radiance = OrbitRadiance.configure({
|
|
54
|
+
* driver: 'pusher',
|
|
55
|
+
* config: { appId: '...', key: '...', secret: '...' }
|
|
56
|
+
* });
|
|
57
|
+
* core.addOrbit(radiance);
|
|
58
|
+
* ```
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export declare class OrbitRadiance implements GravitoOrbit {
|
|
62
|
+
private options;
|
|
63
|
+
constructor(options: OrbitRadianceOptions);
|
|
64
|
+
/**
|
|
65
|
+
* Create a new OrbitRadiance instance with the specified configuration.
|
|
66
|
+
*
|
|
67
|
+
* This static factory method is the preferred way to initialize the orbit
|
|
68
|
+
* before adding it to the PlanetCore.
|
|
69
|
+
*
|
|
70
|
+
* @param options - The configuration settings for the broadcaster
|
|
71
|
+
* @returns A configured OrbitRadiance instance
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const orbit = OrbitRadiance.configure({
|
|
76
|
+
* driver: 'redis',
|
|
77
|
+
* config: { url: 'redis://localhost:6379' }
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
static configure(options: OrbitRadianceOptions): OrbitRadiance;
|
|
82
|
+
/**
|
|
83
|
+
* Initialize and register the broadcasting system into the core.
|
|
84
|
+
*
|
|
85
|
+
* Sets up the BroadcastManager, initializes the selected driver, and
|
|
86
|
+
* hooks into the EventManager to enable automatic event broadcasting.
|
|
87
|
+
*
|
|
88
|
+
* @param core - The PlanetCore instance where the orbit is being installed
|
|
89
|
+
* @throws {Error} If an unsupported driver is specified in options
|
|
90
|
+
*/
|
|
91
|
+
install(core: PlanetCore): Promise<void>;
|
|
92
|
+
}
|
|
93
|
+
declare module '@gravito/core' {
|
|
94
|
+
interface GravitoVariables {
|
|
95
|
+
/** Broadcaster manager for real-time events */
|
|
96
|
+
broadcast?: BroadcastManager;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base channel interface representing a broadcast destination.
|
|
3
|
+
*
|
|
4
|
+
* Channels segregate broadcast traffic. Different channel types imply different
|
|
5
|
+
* access control rules and behaviors.
|
|
6
|
+
*/
|
|
7
|
+
export interface Channel {
|
|
8
|
+
/**
|
|
9
|
+
* The unique identifier for the channel.
|
|
10
|
+
*
|
|
11
|
+
* @remarks
|
|
12
|
+
* For private/presence channels, this typically includes a prefix like 'private-' or 'presence-'.
|
|
13
|
+
*/
|
|
14
|
+
name: string;
|
|
15
|
+
/**
|
|
16
|
+
* The security level and behavior type of the channel.
|
|
17
|
+
*/
|
|
18
|
+
type: 'public' | 'private' | 'presence';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A public channel open to any subscriber.
|
|
22
|
+
*
|
|
23
|
+
* Public channels require no authorization. Any client can subscribe and listen
|
|
24
|
+
* to events broadcast on these channels.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const channel = new PublicChannel('orders');
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class PublicChannel implements Channel {
|
|
32
|
+
name: string;
|
|
33
|
+
type: "public";
|
|
34
|
+
/**
|
|
35
|
+
* Creates a new PublicChannel instance.
|
|
36
|
+
*
|
|
37
|
+
* @param name - The name of the channel (without prefixes).
|
|
38
|
+
*/
|
|
39
|
+
constructor(name: string);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A private channel requiring authorization.
|
|
43
|
+
*
|
|
44
|
+
* Private channels are secured and require the client to provide an authentication
|
|
45
|
+
* signature (usually via an auth endpoint) before subscription is allowed.
|
|
46
|
+
* Suitable for sensitive user data.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const channel = new PrivateChannel('user.123');
|
|
51
|
+
* // Driver may prefix this as 'private-user.123'
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare class PrivateChannel implements Channel {
|
|
55
|
+
name: string;
|
|
56
|
+
type: "private";
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new PrivateChannel instance.
|
|
59
|
+
*
|
|
60
|
+
* @param name - The name of the channel.
|
|
61
|
+
*/
|
|
62
|
+
constructor(name: string);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A presence channel that tracks online users.
|
|
66
|
+
*
|
|
67
|
+
* Presence channels extend private channels by adding the ability to know *who*
|
|
68
|
+
* is subscribed. They are commonly used for chat rooms, "user is typing" indicators,
|
|
69
|
+
* and online user lists.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const channel = new PresenceChannel('chat.room.1');
|
|
74
|
+
* // Driver may prefix this as 'presence-chat.room.1'
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare class PresenceChannel implements Channel {
|
|
78
|
+
name: string;
|
|
79
|
+
type: "presence";
|
|
80
|
+
/**
|
|
81
|
+
* Creates a new PresenceChannel instance.
|
|
82
|
+
*
|
|
83
|
+
* @param name - The name of the channel.
|
|
84
|
+
*/
|
|
85
|
+
constructor(name: string);
|
|
86
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { BroadcastDriver } from './BroadcastDriver';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for the Ably broadcast driver.
|
|
4
|
+
*/
|
|
5
|
+
export interface AblyDriverConfig {
|
|
6
|
+
/**
|
|
7
|
+
* The Ably API key.
|
|
8
|
+
*
|
|
9
|
+
* Format: "appId.keyId:secret"
|
|
10
|
+
*/
|
|
11
|
+
apiKey: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Ably broadcast driver implementation.
|
|
15
|
+
*
|
|
16
|
+
* Uses the Ably REST API to publish messages to channels.
|
|
17
|
+
* Suitable for high-reliability global messaging without managing infrastructure.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* This driver uses standard HTTP fetch for publishing and does not require the full Ably SDK.
|
|
21
|
+
* Presence authorization is implemented using a basic compatible format.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const driver = new AblyDriver({
|
|
26
|
+
* apiKey: 'APP_ID.KEY_ID:SECRET'
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare class AblyDriver implements BroadcastDriver {
|
|
31
|
+
private config;
|
|
32
|
+
private baseUrl;
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new AblyDriver instance.
|
|
35
|
+
*
|
|
36
|
+
* @param config - The Ably connection configuration.
|
|
37
|
+
*/
|
|
38
|
+
constructor(config: AblyDriverConfig);
|
|
39
|
+
/**
|
|
40
|
+
* Broadcast an event to an Ably channel.
|
|
41
|
+
*
|
|
42
|
+
* @param channel - The target channel metadata.
|
|
43
|
+
* @param event - The name of the event.
|
|
44
|
+
* @param data - The event payload.
|
|
45
|
+
* @throws {Error} If the Ably API request fails.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* await driver.broadcast({ name: 'orders', type: 'public' }, 'OrderCreated', { id: 123 });
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
broadcast(channel: {
|
|
53
|
+
name: string;
|
|
54
|
+
type: string;
|
|
55
|
+
}, event: string, data: Record<string, unknown>): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Authorize a client for a private or presence channel.
|
|
58
|
+
*
|
|
59
|
+
* @param channel - The channel name.
|
|
60
|
+
* @param _socketId - The socket ID (unused by Ably REST auth in this simple mode).
|
|
61
|
+
* @param userId - The user ID (used for presence).
|
|
62
|
+
* @returns The authorization object.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const auth = await driver.authorizeChannel('presence-chat', 'socket-1', 'user-1');
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
authorizeChannel(channel: string, _socketId: string, userId?: string | number): Promise<{
|
|
70
|
+
auth: string;
|
|
71
|
+
channel_data?: string;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface defining the contract for all broadcast drivers.
|
|
3
|
+
*
|
|
4
|
+
* Implementations of this interface serve as adapters for specific real-time
|
|
5
|
+
* messaging services (e.g., Pusher, Ably, Redis).
|
|
6
|
+
*/
|
|
7
|
+
export interface BroadcastDriver {
|
|
8
|
+
/**
|
|
9
|
+
* Broadcast an event to a specific channel.
|
|
10
|
+
*
|
|
11
|
+
* @param channel - The target channel metadata (name and type).
|
|
12
|
+
* @param event - The name of the event being broadcast.
|
|
13
|
+
* @param data - The payload data associated with the event.
|
|
14
|
+
* @throws {Error} If the underlying provider fails to accept the message.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* await driver.broadcast(
|
|
19
|
+
* { name: 'orders', type: 'public' },
|
|
20
|
+
* 'OrderCreated',
|
|
21
|
+
* { id: 1 }
|
|
22
|
+
* );
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
broadcast(channel: {
|
|
26
|
+
name: string;
|
|
27
|
+
type: string;
|
|
28
|
+
}, event: string, data: Record<string, unknown>): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Authorize a client to access a restricted channel.
|
|
31
|
+
*
|
|
32
|
+
* Used for private and presence channels to generate the necessary
|
|
33
|
+
* authentication signature required by the client SDK.
|
|
34
|
+
*
|
|
35
|
+
* @param channel - The name of the channel to authorize.
|
|
36
|
+
* @param socketId - The unique socket ID provided by the client.
|
|
37
|
+
* @param userId - The identifier of the user (optional).
|
|
38
|
+
* @returns A promise resolving to the auth payload expected by the client.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const auth = await driver.authorizeChannel('private-user.1', 'socket-123', 'user-1');
|
|
43
|
+
* // Returns { auth: "key:signature" }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
authorizeChannel?(channel: string, socketId: string, userId?: string | number): Promise<{
|
|
47
|
+
auth: string;
|
|
48
|
+
channel_data?: string;
|
|
49
|
+
}>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { BroadcastDriver } from './BroadcastDriver';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for the Pusher broadcast driver.
|
|
4
|
+
*/
|
|
5
|
+
export interface PusherDriverConfig {
|
|
6
|
+
/**
|
|
7
|
+
* The application ID provided by Pusher.
|
|
8
|
+
*/
|
|
9
|
+
appId: string;
|
|
10
|
+
/**
|
|
11
|
+
* The public application key.
|
|
12
|
+
*/
|
|
13
|
+
key: string;
|
|
14
|
+
/**
|
|
15
|
+
* The secret key for signing requests.
|
|
16
|
+
*/
|
|
17
|
+
secret: string;
|
|
18
|
+
/**
|
|
19
|
+
* The Pusher cluster to connect to (e.g., 'mt1', 'eu').
|
|
20
|
+
* @defaultValue 'mt1'
|
|
21
|
+
*/
|
|
22
|
+
cluster?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether to force TLS (HTTPS) for API requests.
|
|
25
|
+
* @defaultValue true
|
|
26
|
+
*/
|
|
27
|
+
useTLS?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pusher broadcast driver implementation.
|
|
31
|
+
*
|
|
32
|
+
* Interacts with the Pusher HTTP API to trigger events on channels.
|
|
33
|
+
* It handles request signing, authentication generation for private channels,
|
|
34
|
+
* and HTTP communication using the native Fetch API.
|
|
35
|
+
*
|
|
36
|
+
* @remarks
|
|
37
|
+
* This driver avoids heavy dependencies by implementing the necessary crypto
|
|
38
|
+
* signatures (HMAC-SHA256 and MD5) using standard Web Crypto or Bun APIs.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const driver = new PusherDriver({
|
|
43
|
+
* appId: '123456',
|
|
44
|
+
* key: 'my-app-key',
|
|
45
|
+
* secret: 'my-app-secret',
|
|
46
|
+
* cluster: 'us2'
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export declare class PusherDriver implements BroadcastDriver {
|
|
51
|
+
private config;
|
|
52
|
+
private baseUrl;
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new PusherDriver instance.
|
|
55
|
+
*
|
|
56
|
+
* @param config - The Pusher connection configuration.
|
|
57
|
+
*/
|
|
58
|
+
constructor(config: PusherDriverConfig);
|
|
59
|
+
/**
|
|
60
|
+
* Broadcast an event to a channel via the Pusher API.
|
|
61
|
+
*
|
|
62
|
+
* @param channel - The target channel metadata.
|
|
63
|
+
* @param event - The name of the event.
|
|
64
|
+
* @param data - The event payload.
|
|
65
|
+
* @throws {Error} If the Pusher API returns a non-200 response.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* await driver.broadcast({ name: 'news', type: 'public' }, 'BreakingNews', { title: 'Hello' });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
broadcast(channel: {
|
|
73
|
+
name: string;
|
|
74
|
+
type: string;
|
|
75
|
+
}, event: string, data: Record<string, unknown>): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Generate an authorization signature for private or presence channels.
|
|
78
|
+
*
|
|
79
|
+
* @param channel - The name of the channel.
|
|
80
|
+
* @param socketId - The client's socket ID.
|
|
81
|
+
* @param userId - The user ID (required for presence channels).
|
|
82
|
+
* @returns The auth object expected by Pusher client libraries.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const auth = await driver.authorizeChannel('private-user.1', '123.456');
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
authorizeChannel(channel: string, socketId: string, userId?: string | number): Promise<{
|
|
90
|
+
auth: string;
|
|
91
|
+
channel_data?: string;
|
|
92
|
+
}>;
|
|
93
|
+
private hmacSHA256;
|
|
94
|
+
private md5;
|
|
95
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { BroadcastDriver } from './BroadcastDriver';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for the Redis broadcast driver.
|
|
4
|
+
*/
|
|
5
|
+
export interface RedisDriverConfig {
|
|
6
|
+
/**
|
|
7
|
+
* The Redis connection URL.
|
|
8
|
+
* @example 'redis://localhost:6379'
|
|
9
|
+
*/
|
|
10
|
+
url?: string;
|
|
11
|
+
/**
|
|
12
|
+
* The Redis host address.
|
|
13
|
+
*/
|
|
14
|
+
host?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The Redis port number.
|
|
17
|
+
*/
|
|
18
|
+
port?: number;
|
|
19
|
+
/**
|
|
20
|
+
* The Redis password for authentication.
|
|
21
|
+
*/
|
|
22
|
+
password?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The Redis database index.
|
|
25
|
+
*/
|
|
26
|
+
db?: number;
|
|
27
|
+
/**
|
|
28
|
+
* The prefix to use for Pub/Sub channels.
|
|
29
|
+
* @defaultValue 'gravito:broadcast:'
|
|
30
|
+
*/
|
|
31
|
+
keyPrefix?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Redis broadcast driver implementation.
|
|
35
|
+
*
|
|
36
|
+
* Leverages Redis Pub/Sub to broadcast messages. This is ideal for internal
|
|
37
|
+
* microservices or when managing your own WebSocket server fleet that subscribes to Redis.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* This driver is an adapter and requires an external Redis client instance to be injected.
|
|
41
|
+
* It is compatible with any Redis client that exposes a `publish` method.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const driver = new RedisDriver({ keyPrefix: 'app:' });
|
|
46
|
+
* driver.setRedisClient(redis);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare class RedisDriver implements BroadcastDriver {
|
|
50
|
+
private config;
|
|
51
|
+
private redis;
|
|
52
|
+
/**
|
|
53
|
+
* Creates a new RedisDriver instance.
|
|
54
|
+
*
|
|
55
|
+
* @param config - The Redis configuration options.
|
|
56
|
+
*/
|
|
57
|
+
constructor(config: RedisDriverConfig);
|
|
58
|
+
/**
|
|
59
|
+
* Inject the Redis client instance.
|
|
60
|
+
*
|
|
61
|
+
* @param client - A compatible Redis client (must have a publish method).
|
|
62
|
+
*/
|
|
63
|
+
setRedisClient(client: {
|
|
64
|
+
publish(channel: string, message: string): Promise<number>;
|
|
65
|
+
}): void;
|
|
66
|
+
/**
|
|
67
|
+
* Broadcast an event to a Redis channel.
|
|
68
|
+
*
|
|
69
|
+
* @param channel - The target channel metadata.
|
|
70
|
+
* @param event - The name of the event.
|
|
71
|
+
* @param data - The event payload.
|
|
72
|
+
* @throws {Error} If the Redis client has not been set.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* await driver.broadcast({ name: 'system', type: 'public' }, 'Alert', { msg: 'Down' });
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
broadcast(channel: {
|
|
80
|
+
name: string;
|
|
81
|
+
type: string;
|
|
82
|
+
}, event: string, data: Record<string, unknown>): Promise<void>;
|
|
83
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Logger } from '@gravito/core';
|
|
2
|
+
import type { BroadcastDriver } from './BroadcastDriver';
|
|
3
|
+
/**
|
|
4
|
+
* Interface representing a WebSocket connection.
|
|
5
|
+
*
|
|
6
|
+
* Abstracts the native WebSocket or similar connection object to allow
|
|
7
|
+
* different underlying implementations (e.g., standard WebSocket, uWebSockets.js).
|
|
8
|
+
*/
|
|
9
|
+
export interface WebSocketConnection {
|
|
10
|
+
/**
|
|
11
|
+
* Send a message to the client.
|
|
12
|
+
*
|
|
13
|
+
* @param data - The stringified message payload.
|
|
14
|
+
*/
|
|
15
|
+
send(data: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Close the connection.
|
|
18
|
+
*/
|
|
19
|
+
close(): void;
|
|
20
|
+
/**
|
|
21
|
+
* The current state of the connection (1 = OPEN).
|
|
22
|
+
*/
|
|
23
|
+
readyState: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for the WebSocket broadcast driver.
|
|
27
|
+
*/
|
|
28
|
+
export interface WebSocketDriverConfig {
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve all active WebSocket connections.
|
|
31
|
+
*
|
|
32
|
+
* This function is called on every broadcast to get the list of recipients.
|
|
33
|
+
*/
|
|
34
|
+
getConnections(): WebSocketConnection[];
|
|
35
|
+
/**
|
|
36
|
+
* Optional strategy to filter connections based on channel subscriptions.
|
|
37
|
+
*
|
|
38
|
+
* @param channel - The name of the channel to filter by.
|
|
39
|
+
*/
|
|
40
|
+
filterConnectionsByChannel?(channel: string): WebSocketConnection[];
|
|
41
|
+
/**
|
|
42
|
+
* Logger instance for reporting broadcast failures.
|
|
43
|
+
*/
|
|
44
|
+
logger?: Logger;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Native WebSocket broadcast driver.
|
|
48
|
+
*
|
|
49
|
+
* Broadcasts events directly to connected WebSocket clients.
|
|
50
|
+
* Ideal for single-node deployments or simple setups where you want to
|
|
51
|
+
* avoid external dependencies like Pusher or Redis.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* This driver iterates over all (or filtered) connections and sends the message.
|
|
55
|
+
* It is not scalable across multiple nodes without an additional sync mechanism (like Redis).
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const driver = new WebSocketDriver({
|
|
60
|
+
* getConnections: () => Array.from(wss.clients),
|
|
61
|
+
* logger: console
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare class WebSocketDriver implements BroadcastDriver {
|
|
66
|
+
private config;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a new WebSocketDriver instance.
|
|
69
|
+
*
|
|
70
|
+
* @param config - Driver configuration.
|
|
71
|
+
*/
|
|
72
|
+
constructor(config: WebSocketDriverConfig);
|
|
73
|
+
/**
|
|
74
|
+
* Broadcast an event to WebSocket clients.
|
|
75
|
+
*
|
|
76
|
+
* @param channel - The target channel metadata.
|
|
77
|
+
* @param event - The name of the event.
|
|
78
|
+
* @param data - The event payload.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* await driver.broadcast({ name: 'chat', type: 'public' }, 'NewMessage', { text: 'Hi' });
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
broadcast(channel: {
|
|
86
|
+
name: string;
|
|
87
|
+
type: string;
|
|
88
|
+
}, event: string, data: Record<string, unknown>): Promise<void>;
|
|
89
|
+
}
|