evstream 1.0.2 → 1.0.4

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/.me/dump.ts ADDED
@@ -0,0 +1,102 @@
1
+ import { EvState, EvStreamManager } from 'evstream'
2
+ import { EvRedisAdapter } from 'evstream/adapter/redis'
3
+ import type Redis from 'ioredis'
4
+
5
+ type SharedStateMessage =
6
+ | { action: 'create'; key: string; initialValue: any }
7
+ | { action: 'remove'; key: string }
8
+
9
+ export class EvCustomSharedState {
10
+ private states = new Map<string, EvState>()
11
+ private redis: Redis
12
+ private pub: Redis
13
+ private manager: EvStreamManager
14
+ private adapter: EvRedisAdapter
15
+ private controlChannel = 'ev:shared-state'
16
+
17
+ constructor(options: {
18
+ redis: Redis
19
+ publisher?: Redis
20
+ manager: EvStreamManager
21
+ adapter: EvRedisAdapter
22
+ }) {
23
+ this.redis = options.redis
24
+ this.pub = options.publisher ?? options.redis
25
+ this.manager = options.manager
26
+ this.adapter = options.adapter
27
+
28
+ this.init()
29
+ }
30
+
31
+ private async init() {
32
+ await this.redis.subscribe(this.controlChannel)
33
+
34
+ this.redis.on('message', (_, raw) => {
35
+ try {
36
+ const msg = JSON.parse(raw) as SharedStateMessage
37
+ this.handleMessage(msg)
38
+ } catch {
39
+ /* ignore malformed messages */
40
+ }
41
+ })
42
+ }
43
+
44
+ private handleMessage(msg: SharedStateMessage) {
45
+ if (msg.action === 'create') {
46
+ this.createLocalState(msg.key, msg.initialValue)
47
+ }
48
+
49
+ if (msg.action === 'remove') {
50
+ this.removeLocalState(msg.key)
51
+ }
52
+ }
53
+
54
+ private createLocalState(key: string, initialValue: any) {
55
+ if (this.states.has(key)) return
56
+
57
+ const state = new EvState({
58
+ channel: key,
59
+ initialValue,
60
+ manager: this.manager,
61
+ adapter: this.adapter,
62
+ })
63
+
64
+ this.states.set(key, state)
65
+ }
66
+
67
+ private removeLocalState(key: string) {
68
+ const state = this.states.get(key)
69
+ if (!state) return
70
+
71
+ // EvState has no destroy API, so we simply stop tracking it
72
+ this.states.delete(key)
73
+ }
74
+
75
+ /* ================= PUBLIC API ================= */
76
+
77
+ async create(key: string, initialValue: any) {
78
+ await this.pub.publish(
79
+ this.controlChannel,
80
+ JSON.stringify({ action: 'create', key, initialValue })
81
+ )
82
+ }
83
+
84
+ async remove(key: string) {
85
+ await this.pub.publish(
86
+ this.controlChannel,
87
+ JSON.stringify({ action: 'remove', key })
88
+ )
89
+ }
90
+
91
+ get(key: string): EvState | undefined {
92
+ return this.states.get(key)
93
+ }
94
+
95
+ has(key: string): boolean {
96
+ return this.states.has(key)
97
+ }
98
+
99
+ keys(): string[] {
100
+ return [...this.states.keys()]
101
+ }
102
+ }
@@ -0,0 +1,40 @@
1
+ import { RedisOptions } from 'ioredis';
2
+ /**
3
+ * Configuration options for EvRedisPubSub
4
+ */
5
+ interface EvRedisPubSubOptions<T> {
6
+ /** Redis Pub/Sub channel name */
7
+ subject: string;
8
+ /** Redis connection options */
9
+ options: RedisOptions;
10
+ /** Optional initial message handler */
11
+ onMessage?: (message: T) => void;
12
+ }
13
+ /**
14
+ * Redis-based Pub/Sub helper for cross-process communication.
15
+ *
16
+ * - Uses separate publisher and subscriber connections
17
+ * - Prevents self-message delivery using instance UID
18
+ * - Typed message payload via generics
19
+ */
20
+ export declare class EvRedisPubSub<T = unknown> {
21
+ #private;
22
+ constructor({ options, subject, onMessage }: EvRedisPubSubOptions<T>);
23
+ /**
24
+ * Initializes Redis subscriptions and listeners.
25
+ */
26
+ private init;
27
+ /**
28
+ * Publishes a message to the Redis channel.
29
+ */
30
+ send(msg: T): Promise<void>;
31
+ /**
32
+ * Registers or replaces the message handler.
33
+ */
34
+ onMessage(callback: (msg: T) => void): void;
35
+ /**
36
+ * Gracefully closes Redis connections.
37
+ */
38
+ close(): Promise<void>;
39
+ }
40
+ export {};
@@ -0,0 +1,91 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
11
+ if (kind === "m") throw new TypeError("Private method is not writable");
12
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
13
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
14
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
15
+ };
16
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
17
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
18
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
19
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
20
+ };
21
+ var _EvRedisPubSub_subject, _EvRedisPubSub_pub, _EvRedisPubSub_sub, _EvRedisPubSub_instanceId, _EvRedisPubSub_onMessage;
22
+ import Redis from 'ioredis';
23
+ import { uid } from '../utils.js';
24
+ /**
25
+ * Redis-based Pub/Sub helper for cross-process communication.
26
+ *
27
+ * - Uses separate publisher and subscriber connections
28
+ * - Prevents self-message delivery using instance UID
29
+ * - Typed message payload via generics
30
+ */
31
+ export class EvRedisPubSub {
32
+ constructor({ options, subject, onMessage }) {
33
+ _EvRedisPubSub_subject.set(this, void 0);
34
+ _EvRedisPubSub_pub.set(this, void 0);
35
+ _EvRedisPubSub_sub.set(this, void 0);
36
+ _EvRedisPubSub_instanceId.set(this, void 0);
37
+ _EvRedisPubSub_onMessage.set(this, void 0);
38
+ __classPrivateFieldSet(this, _EvRedisPubSub_pub, new Redis(options), "f");
39
+ __classPrivateFieldSet(this, _EvRedisPubSub_sub, new Redis(options), "f");
40
+ __classPrivateFieldSet(this, _EvRedisPubSub_subject, subject, "f");
41
+ __classPrivateFieldSet(this, _EvRedisPubSub_onMessage, onMessage, "f");
42
+ __classPrivateFieldSet(this, _EvRedisPubSub_instanceId, uid({ prefix: subject, counter: Math.random() }), "f");
43
+ this.init();
44
+ }
45
+ /**
46
+ * Initializes Redis subscriptions and listeners.
47
+ */
48
+ init() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ __classPrivateFieldGet(this, _EvRedisPubSub_pub, "f").on('error', () => { });
51
+ __classPrivateFieldGet(this, _EvRedisPubSub_sub, "f").on('error', () => { });
52
+ yield __classPrivateFieldGet(this, _EvRedisPubSub_sub, "f").subscribe(__classPrivateFieldGet(this, _EvRedisPubSub_subject, "f"));
53
+ __classPrivateFieldGet(this, _EvRedisPubSub_sub, "f").on('message', (_, raw) => {
54
+ var _a;
55
+ try {
56
+ const data = JSON.parse(raw);
57
+ // Ignore messages from the same instance
58
+ if ((data === null || data === void 0 ? void 0 : data.uid) !== __classPrivateFieldGet(this, _EvRedisPubSub_instanceId, "f")) {
59
+ (_a = __classPrivateFieldGet(this, _EvRedisPubSub_onMessage, "f")) === null || _a === void 0 ? void 0 : _a.call(this, data.msg);
60
+ }
61
+ }
62
+ catch (_b) {
63
+ // Ignore malformed payloads
64
+ }
65
+ });
66
+ });
67
+ }
68
+ /**
69
+ * Publishes a message to the Redis channel.
70
+ */
71
+ send(msg) {
72
+ return __awaiter(this, void 0, void 0, function* () {
73
+ yield __classPrivateFieldGet(this, _EvRedisPubSub_pub, "f").publish(__classPrivateFieldGet(this, _EvRedisPubSub_subject, "f"), JSON.stringify({ uid: __classPrivateFieldGet(this, _EvRedisPubSub_instanceId, "f"), msg }));
74
+ });
75
+ }
76
+ /**
77
+ * Registers or replaces the message handler.
78
+ */
79
+ onMessage(callback) {
80
+ __classPrivateFieldSet(this, _EvRedisPubSub_onMessage, callback, "f");
81
+ }
82
+ /**
83
+ * Gracefully closes Redis connections.
84
+ */
85
+ close() {
86
+ return __awaiter(this, void 0, void 0, function* () {
87
+ yield Promise.all([__classPrivateFieldGet(this, _EvRedisPubSub_pub, "f").quit(), __classPrivateFieldGet(this, _EvRedisPubSub_sub, "f").quit()]);
88
+ });
89
+ }
90
+ }
91
+ _EvRedisPubSub_subject = new WeakMap(), _EvRedisPubSub_pub = new WeakMap(), _EvRedisPubSub_sub = new WeakMap(), _EvRedisPubSub_instanceId = new WeakMap(), _EvRedisPubSub_onMessage = new WeakMap();
@@ -1,10 +1,55 @@
1
1
  import { RedisOptions } from 'ioredis';
2
+ import { EvRedisPubSub } from './pub-sub.js';
2
3
  import { EvStateAdapter } from '../types.js';
3
- export declare class EvRedisAdapter implements EvStateAdapter {
4
+ /**
5
+ * Redis-based implementation of {@link EvStateAdapter}.
6
+ *
7
+ * This adapter enables distributed state updates using Redis Pub/Sub.
8
+ * It supports:
9
+ * - Channel-based subscriptions
10
+ * - Multiple listeners per channel
11
+ * - Self-message filtering via instance ID
12
+ *
13
+ * Designed to be used by EvState / EvStateManager for
14
+ * cross-process state synchronization.
15
+ */
16
+ declare class EvRedisAdapter implements EvStateAdapter {
4
17
  #private;
18
+ /**
19
+ * Creates a new Redis state adapter.
20
+ *
21
+ * @param options - Optional Redis connection options
22
+ */
5
23
  constructor(options?: RedisOptions);
24
+ /**
25
+ * Publishes a message to a Redis channel.
26
+ *
27
+ * The payload is wrapped with the instance ID to
28
+ * prevent self-delivery.
29
+ *
30
+ * @param channel - Redis channel name
31
+ * @param message - Message payload
32
+ */
6
33
  publish(channel: string, message: any): Promise<void>;
34
+ /**
35
+ * Subscribes to a Redis channel.
36
+ *
37
+ * Multiple listeners can be registered per channel.
38
+ * The Redis subscription is created only once per channel.
39
+ *
40
+ * @param channel - Redis channel name
41
+ * @param onMessage - Callback invoked on incoming messages
42
+ */
7
43
  subscribe(channel: string, onMessage: (message: any) => void): Promise<void>;
44
+ /**
45
+ * Unsubscribes from a Redis channel and removes all listeners.
46
+ *
47
+ * @param channel - Redis channel name
48
+ */
8
49
  unsubscribe(channel: string): Promise<void>;
50
+ /**
51
+ * Gracefully closes Redis connections.
52
+ */
9
53
  quit(): void;
10
54
  }
55
+ export { EvRedisPubSub, EvRedisAdapter };
@@ -18,35 +18,85 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
18
18
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
19
19
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
20
20
  };
21
- var _EvRedisAdapter_pub, _EvRedisAdapter_sub, _EvRedisAdapter_listeners;
21
+ var _EvRedisAdapter_pub, _EvRedisAdapter_sub, _EvRedisAdapter_listeners, _EvRedisAdapter_instanceId;
22
22
  import Redis from 'ioredis';
23
- export class EvRedisAdapter {
23
+ import { EvRedisPubSub } from './pub-sub.js';
24
+ import { uid } from '../utils.js';
25
+ /**
26
+ * Redis-based implementation of {@link EvStateAdapter}.
27
+ *
28
+ * This adapter enables distributed state updates using Redis Pub/Sub.
29
+ * It supports:
30
+ * - Channel-based subscriptions
31
+ * - Multiple listeners per channel
32
+ * - Self-message filtering via instance ID
33
+ *
34
+ * Designed to be used by EvState / EvStateManager for
35
+ * cross-process state synchronization.
36
+ */
37
+ class EvRedisAdapter {
38
+ /**
39
+ * Creates a new Redis state adapter.
40
+ *
41
+ * @param options - Optional Redis connection options
42
+ */
24
43
  constructor(options) {
44
+ /** Publisher Redis client */
25
45
  _EvRedisAdapter_pub.set(this, void 0);
46
+ /** Subscriber Redis client */
26
47
  _EvRedisAdapter_sub.set(this, void 0);
48
+ /**
49
+ * Channel → listeners mapping.
50
+ * Each channel may have multiple local handlers.
51
+ */
27
52
  _EvRedisAdapter_listeners.set(this, void 0);
53
+ /** Unique identifier for this adapter instance */
54
+ _EvRedisAdapter_instanceId.set(this, void 0);
28
55
  __classPrivateFieldSet(this, _EvRedisAdapter_pub, new Redis(options), "f");
29
56
  __classPrivateFieldSet(this, _EvRedisAdapter_sub, new Redis(options), "f");
30
57
  __classPrivateFieldSet(this, _EvRedisAdapter_listeners, new Map(), "f");
58
+ __classPrivateFieldSet(this, _EvRedisAdapter_instanceId, uid({ counter: Math.ceil(Math.random() * 100) }), "f");
31
59
  __classPrivateFieldGet(this, _EvRedisAdapter_sub, "f").on('message', (channel, message) => {
32
60
  const handlers = __classPrivateFieldGet(this, _EvRedisAdapter_listeners, "f").get(channel);
33
- if (handlers) {
34
- let parsed;
35
- try {
36
- parsed = JSON.parse(message);
37
- }
38
- catch (_a) {
39
- return;
40
- }
41
- handlers.forEach((handler) => handler(parsed));
61
+ if (!handlers)
62
+ return;
63
+ let parsed;
64
+ try {
65
+ parsed = JSON.parse(message);
42
66
  }
67
+ catch (_a) {
68
+ // Ignore malformed payloads
69
+ return;
70
+ }
71
+ // Ignore messages published by this instance
72
+ if ((parsed === null || parsed === void 0 ? void 0 : parsed.id) === __classPrivateFieldGet(this, _EvRedisAdapter_instanceId, "f"))
73
+ return;
74
+ handlers.forEach((handler) => handler(parsed === null || parsed === void 0 ? void 0 : parsed.message));
43
75
  });
44
76
  }
77
+ /**
78
+ * Publishes a message to a Redis channel.
79
+ *
80
+ * The payload is wrapped with the instance ID to
81
+ * prevent self-delivery.
82
+ *
83
+ * @param channel - Redis channel name
84
+ * @param message - Message payload
85
+ */
45
86
  publish(channel, message) {
46
87
  return __awaiter(this, void 0, void 0, function* () {
47
- yield __classPrivateFieldGet(this, _EvRedisAdapter_pub, "f").publish(channel, JSON.stringify(message));
88
+ yield __classPrivateFieldGet(this, _EvRedisAdapter_pub, "f").publish(channel, JSON.stringify({ id: __classPrivateFieldGet(this, _EvRedisAdapter_instanceId, "f"), message }));
48
89
  });
49
90
  }
91
+ /**
92
+ * Subscribes to a Redis channel.
93
+ *
94
+ * Multiple listeners can be registered per channel.
95
+ * The Redis subscription is created only once per channel.
96
+ *
97
+ * @param channel - Redis channel name
98
+ * @param onMessage - Callback invoked on incoming messages
99
+ */
50
100
  subscribe(channel, onMessage) {
51
101
  return __awaiter(this, void 0, void 0, function* () {
52
102
  if (!__classPrivateFieldGet(this, _EvRedisAdapter_listeners, "f").has(channel)) {
@@ -56,15 +106,24 @@ export class EvRedisAdapter {
56
106
  __classPrivateFieldGet(this, _EvRedisAdapter_listeners, "f").get(channel).add(onMessage);
57
107
  });
58
108
  }
109
+ /**
110
+ * Unsubscribes from a Redis channel and removes all listeners.
111
+ *
112
+ * @param channel - Redis channel name
113
+ */
59
114
  unsubscribe(channel) {
60
115
  return __awaiter(this, void 0, void 0, function* () {
61
116
  yield __classPrivateFieldGet(this, _EvRedisAdapter_sub, "f").unsubscribe(channel);
62
117
  __classPrivateFieldGet(this, _EvRedisAdapter_listeners, "f").delete(channel);
63
118
  });
64
119
  }
120
+ /**
121
+ * Gracefully closes Redis connections.
122
+ */
65
123
  quit() {
66
124
  __classPrivateFieldGet(this, _EvRedisAdapter_pub, "f").quit();
67
125
  __classPrivateFieldGet(this, _EvRedisAdapter_sub, "f").quit();
68
126
  }
69
127
  }
70
- _EvRedisAdapter_pub = new WeakMap(), _EvRedisAdapter_sub = new WeakMap(), _EvRedisAdapter_listeners = new WeakMap();
128
+ _EvRedisAdapter_pub = new WeakMap(), _EvRedisAdapter_sub = new WeakMap(), _EvRedisAdapter_listeners = new WeakMap(), _EvRedisAdapter_instanceId = new WeakMap();
129
+ export { EvRedisPubSub, EvRedisAdapter };
@@ -0,0 +1,95 @@
1
+ import type { EvStreamManager } from '../manager.js';
2
+ import type { EvRedisAdapter } from '../adapters/redis.js';
3
+ import type { EvRedisPubSub } from '../adapters/pub-sub.js';
4
+ import { EvState } from '../state.js';
5
+ /**
6
+ * Options for creating an {@link EvStateManager}.
7
+ */
8
+ interface EvStateManagerOptions {
9
+ /**
10
+ * Stream manager responsible for managing client connections
11
+ * and broadcasting state updates.
12
+ */
13
+ manager: EvStreamManager;
14
+ /**
15
+ * Optional distributed state adapter (e.g. Redis).
16
+ * Enables cross-process state propagation.
17
+ */
18
+ adapter?: EvRedisAdapter;
19
+ /**
20
+ * Optional Pub/Sub instance used to synchronize
21
+ * state creation and removal across instances.
22
+ */
23
+ pubsub?: EvRedisPubSub;
24
+ }
25
+ /**
26
+ * Manages a collection of named {@link EvState} instances.
27
+ *
28
+ * Responsibilities:
29
+ * - Create and cache state objects locally
30
+ * - Synchronize state lifecycle (create/remove) across processes
31
+ * - Bridge EvState with stream manager and adapters
32
+ *
33
+ * Internally, all state keys are converted to strings to remain
34
+ * Redis-safe and transport-friendly.
35
+ *
36
+ * @typeParam S - Mapping of state keys to their value types
37
+ */
38
+ export declare class EvStateManager<S extends Record<string, any>> {
39
+ #private;
40
+ /**
41
+ * Creates a new state manager.
42
+ *
43
+ * @param options - Initialization options
44
+ */
45
+ constructor({ manager, adapter, pubsub }: EvStateManagerOptions);
46
+ /**
47
+ * Creates a state locally without emitting Pub/Sub events.
48
+ *
49
+ * @param channel - State channel name
50
+ * @param initialValue - Initial state value
51
+ */
52
+ private createLocalState;
53
+ /**
54
+ * Removes a state locally without emitting Pub/Sub events.
55
+ *
56
+ * @param channel - State channel name
57
+ */
58
+ private removeLocalState;
59
+ /**
60
+ * Creates or returns an existing state.
61
+ *
62
+ * If Pub/Sub is enabled, the creation is broadcast
63
+ * to other instances.
64
+ *
65
+ * @param key - State key
66
+ * @param initialValue - Initial state value
67
+ */
68
+ createState<K extends keyof S>(key: K, initialValue: S[K]): EvState<S[K]>;
69
+ /**
70
+ * Retrieves an existing state.
71
+ *
72
+ * @param key - State key
73
+ */
74
+ getState<K extends keyof S>(key: K): EvState<S[K]> | undefined;
75
+ /**
76
+ * Checks whether a state exists.
77
+ *
78
+ * @param key - State key
79
+ */
80
+ hasState<K extends keyof S>(key: K): boolean;
81
+ /**
82
+ * Removes a state locally and propagates the removal
83
+ * to other instances via Pub/Sub.
84
+ *
85
+ * @param key - State key
86
+ */
87
+ removeState<K extends keyof S>(key: K): void;
88
+ /**
89
+ * Handles incoming Pub/Sub lifecycle events.
90
+ *
91
+ * @param msg - Pub/Sub message payload
92
+ */
93
+ private pubSubCallback;
94
+ }
95
+ export {};
@@ -0,0 +1,155 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _EvStateManager_states, _EvStateManager_manager, _EvStateManager_adapter, _EvStateManager_pubsub;
13
+ import { EvState } from '../state.js';
14
+ /**
15
+ * Manages a collection of named {@link EvState} instances.
16
+ *
17
+ * Responsibilities:
18
+ * - Create and cache state objects locally
19
+ * - Synchronize state lifecycle (create/remove) across processes
20
+ * - Bridge EvState with stream manager and adapters
21
+ *
22
+ * Internally, all state keys are converted to strings to remain
23
+ * Redis-safe and transport-friendly.
24
+ *
25
+ * @typeParam S - Mapping of state keys to their value types
26
+ */
27
+ export class EvStateManager {
28
+ /**
29
+ * Creates a new state manager.
30
+ *
31
+ * @param options - Initialization options
32
+ */
33
+ constructor({ manager, adapter, pubsub }) {
34
+ /**
35
+ * Internal state registry.
36
+ * Keyed by string channel name.
37
+ */
38
+ _EvStateManager_states.set(this, new Map()
39
+ /** Stream manager used by all states */
40
+ );
41
+ /** Stream manager used by all states */
42
+ _EvStateManager_manager.set(this, void 0);
43
+ /** Optional distributed adapter */
44
+ _EvStateManager_adapter.set(this, void 0);
45
+ /** Optional Pub/Sub synchronizer */
46
+ _EvStateManager_pubsub.set(this, void 0);
47
+ __classPrivateFieldSet(this, _EvStateManager_manager, manager, "f");
48
+ __classPrivateFieldSet(this, _EvStateManager_adapter, adapter, "f");
49
+ __classPrivateFieldSet(this, _EvStateManager_pubsub, pubsub, "f");
50
+ this.pubSubCallback = this.pubSubCallback.bind(this);
51
+ if (__classPrivateFieldGet(this, _EvStateManager_pubsub, "f")) {
52
+ __classPrivateFieldGet(this, _EvStateManager_pubsub, "f").onMessage(this.pubSubCallback);
53
+ }
54
+ }
55
+ /**
56
+ * Creates a state locally without emitting Pub/Sub events.
57
+ *
58
+ * @param channel - State channel name
59
+ * @param initialValue - Initial state value
60
+ */
61
+ createLocalState(channel, initialValue) {
62
+ const state = new EvState({
63
+ channel,
64
+ initialValue,
65
+ manager: __classPrivateFieldGet(this, _EvStateManager_manager, "f"),
66
+ adapter: __classPrivateFieldGet(this, _EvStateManager_adapter, "f"),
67
+ });
68
+ __classPrivateFieldGet(this, _EvStateManager_states, "f").set(channel, state);
69
+ return state;
70
+ }
71
+ /**
72
+ * Removes a state locally without emitting Pub/Sub events.
73
+ *
74
+ * @param channel - State channel name
75
+ */
76
+ removeLocalState(channel) {
77
+ __classPrivateFieldGet(this, _EvStateManager_states, "f").delete(channel);
78
+ }
79
+ /**
80
+ * Creates or returns an existing state.
81
+ *
82
+ * If Pub/Sub is enabled, the creation is broadcast
83
+ * to other instances.
84
+ *
85
+ * @param key - State key
86
+ * @param initialValue - Initial state value
87
+ */
88
+ createState(key, initialValue) {
89
+ var _a;
90
+ const channel = String(key);
91
+ if (__classPrivateFieldGet(this, _EvStateManager_states, "f").has(channel)) {
92
+ return __classPrivateFieldGet(this, _EvStateManager_states, "f").get(channel);
93
+ }
94
+ const state = this.createLocalState(channel, initialValue);
95
+ (_a = __classPrivateFieldGet(this, _EvStateManager_pubsub, "f")) === null || _a === void 0 ? void 0 : _a.send({
96
+ type: 'create',
97
+ channel,
98
+ initialValue,
99
+ });
100
+ return state;
101
+ }
102
+ /**
103
+ * Retrieves an existing state.
104
+ *
105
+ * @param key - State key
106
+ */
107
+ getState(key) {
108
+ return __classPrivateFieldGet(this, _EvStateManager_states, "f").get(String(key));
109
+ }
110
+ /**
111
+ * Checks whether a state exists.
112
+ *
113
+ * @param key - State key
114
+ */
115
+ hasState(key) {
116
+ return __classPrivateFieldGet(this, _EvStateManager_states, "f").has(String(key));
117
+ }
118
+ /**
119
+ * Removes a state locally and propagates the removal
120
+ * to other instances via Pub/Sub.
121
+ *
122
+ * @param key - State key
123
+ */
124
+ removeState(key) {
125
+ var _a;
126
+ const channel = String(key);
127
+ this.removeLocalState(channel);
128
+ (_a = __classPrivateFieldGet(this, _EvStateManager_pubsub, "f")) === null || _a === void 0 ? void 0 : _a.send({
129
+ type: 'remove',
130
+ channel,
131
+ });
132
+ }
133
+ /**
134
+ * Handles incoming Pub/Sub lifecycle events.
135
+ *
136
+ * @param msg - Pub/Sub message payload
137
+ */
138
+ pubSubCallback(msg) {
139
+ if (!msg || typeof msg.channel !== 'string')
140
+ return;
141
+ switch (msg.type) {
142
+ case 'create': {
143
+ if (!__classPrivateFieldGet(this, _EvStateManager_states, "f").has(msg.channel)) {
144
+ this.createLocalState(msg.channel, msg.initialValue);
145
+ }
146
+ break;
147
+ }
148
+ case 'remove': {
149
+ this.removeLocalState(msg.channel);
150
+ break;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ _EvStateManager_states = new WeakMap(), _EvStateManager_manager = new WeakMap(), _EvStateManager_adapter = new WeakMap(), _EvStateManager_pubsub = new WeakMap();