serve-socket 5.4.0 → 6.0.0

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.
@@ -3,7 +3,7 @@ import { NgModule, InjectionToken, Inject, Injectable } from '@angular/core';
3
3
  import { CommonModule } from '@angular/common';
4
4
  import { HttpClientModule, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
5
5
  import { BehaviorSubject, Subject, filter, switchMap, map } from 'rxjs';
6
- import { io } from 'socket.io-client';
6
+ import { connect } from 'mqtt';
7
7
  import { pairwise, first, debounceTime, takeUntil } from 'rxjs/operators';
8
8
  import * as i2 from 'ngx-toastr';
9
9
 
@@ -72,13 +72,25 @@ var SocketSuccessEventKeys;
72
72
  SocketSuccessEventKeys["BILLING_CREDIT_NOTE_ISSUED"] = "BILLING_CREDIT_NOTE_ISSUED";
73
73
  SocketSuccessEventKeys["BILLING_REFUND_PROCESSED"] = "BILLING_REFUND_PROCESSED";
74
74
  })(SocketSuccessEventKeys || (SocketSuccessEventKeys = {}));
75
+ /**
76
+ * Topic convention (mirrors server messenger.gateway.ts):
77
+ * Server → user: serve-plus/user/{userId}/{event}
78
+ * Server → room: serve-plus/room/{roomId}/{event}
79
+ * Client → server: serve-plus/client/{userId}/{action} (payload = raw JWT string)
80
+ *
81
+ * System events handled internally (not forwarded to event subjects):
82
+ * JOIN_ROOM { roomId: string } — subscribe to serve-plus/room/{roomId}/#
83
+ * LEAVE_ROOM { roomId: string } — unsubscribe from serve-plus/room/{roomId}/#
84
+ * FORCE_DISCONNECT {} — disconnect
85
+ */
75
86
  class SocketService {
76
87
  environment;
77
- socket;
78
- url;
88
+ mqttClient;
79
89
  authToken;
80
90
  connectionKey;
91
+ userId;
81
92
  eventSubjects = new Map();
93
+ subscribedRooms = new Set();
82
94
  connectionStatusSubject = new BehaviorSubject(false);
83
95
  connectionStatus$ = this.connectionStatusSubject.asObservable();
84
96
  reconnectSubject = new Subject();
@@ -86,247 +98,239 @@ class SocketService {
86
98
  hasConnectedOnce = false;
87
99
  healthySubject = new BehaviorSubject(false);
88
100
  healthy$ = this.healthySubject.asObservable();
89
- healthCheckInterval;
90
- lastPongTime = 0;
101
+ TOPIC_PREFIX = 'serve-plus';
91
102
  constructor(environment = defaultRealtimeStoreEnvironment) {
92
103
  this.environment = environment;
93
- this.url = this.environment.apiUrl;
94
104
  }
95
- setupSocketConnection() {
96
- // Cleanup existing socket to prevent memory leaks
97
- if (this.socket) {
98
- this.socket.removeAllListeners();
99
- this.socket.disconnect();
105
+ decodeUserId(token) {
106
+ try {
107
+ const parts = token.split('.');
108
+ if (parts.length !== 3)
109
+ return undefined;
110
+ const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));
111
+ return (payload.id ?? payload.sub);
112
+ }
113
+ catch {
114
+ return undefined;
115
+ }
116
+ }
117
+ resolveBrokerUrl() {
118
+ if (this.environment.mqttUrl) {
119
+ return this.environment.mqttUrl;
100
120
  }
101
- const socketOptions = {
102
- transports: ['websocket'],
103
- autoConnect: true,
104
- reconnection: true,
105
- reconnectionAttempts: Infinity,
106
- reconnectionDelay: 1000,
107
- reconnectionDelayMax: 10000
108
- };
109
- // Add auth if token is available
110
- if (this.authToken) {
111
- socketOptions.auth = {
112
- token: this.authToken
113
- };
121
+ // Derive WebSocket MQTT URL from API URL
122
+ return this.environment.apiUrl
123
+ .replace(/^https/, 'wss')
124
+ .replace(/^http/, 'ws');
125
+ }
126
+ setupConnection() {
127
+ if (this.mqttClient) {
128
+ this.mqttClient.removeAllListeners();
129
+ this.mqttClient.end(true);
114
130
  }
115
- this.socket = io(this.url, socketOptions);
116
- this.socket.on('connect', () => {
117
- console.log('Socket connected');
131
+ if (!this.authToken) {
132
+ console.warn('[MQTT] No auth token — cannot connect');
133
+ return;
134
+ }
135
+ this.userId = this.decodeUserId(this.authToken);
136
+ if (!this.userId) {
137
+ console.warn('[MQTT] Could not decode user ID from token');
138
+ return;
139
+ }
140
+ const options = {
141
+ username: this.userId,
142
+ password: this.authToken,
143
+ clean: true,
144
+ reconnectPeriod: 5000,
145
+ connectTimeout: 15000,
146
+ };
147
+ this.mqttClient = connect(this.resolveBrokerUrl(), options);
148
+ this.mqttClient.on('connect', () => {
149
+ console.log(this.hasConnectedOnce ? '[MQTT] Reconnected' : '[MQTT] Connected');
118
150
  this.connectionStatusSubject.next(true);
119
- this.reestablishListeners();
120
- });
121
- this.socket.on('disconnect', () => {
122
- console.log('Socket disconnected');
123
- this.connectionStatusSubject.next(false);
124
- });
125
- // In Socket.IO v4 the 'reconnect' event is on the Manager (socket.io), not the socket.
126
- // hasConnectedOnce is an instance variable so it persists across resetWithNewToken() calls.
127
- // Any connect after the very first one (regardless of socket recreation) triggers stores to reload.
128
- this.socket.on('connect', () => {
151
+ this.healthySubject.next(true);
152
+ // Subscribe to personal user topic for all events and system commands
153
+ this.mqttClient.subscribe(`${this.TOPIC_PREFIX}/user/${this.userId}/#`, { qos: 1 });
154
+ // Re-subscribe to all previously joined rooms
155
+ this.subscribedRooms.forEach(roomId => {
156
+ this.mqttClient.subscribe(`${this.TOPIC_PREFIX}/room/${roomId}/#`, { qos: 1 });
157
+ });
129
158
  if (this.hasConnectedOnce) {
130
- console.log('Socket reconnected');
131
159
  this.reconnectSubject.next();
132
160
  }
133
161
  this.hasConnectedOnce = true;
134
162
  });
135
- // Keep the manager-level listener as a fallback for older versions
136
- this.socket.io.on('reconnect', () => {
137
- console.log('Socket manager reconnected');
138
- this.connectionStatusSubject.next(true);
139
- this.reconnectSubject.next();
140
- this.reestablishListeners();
163
+ this.mqttClient.on('message', (topic, message) => {
164
+ try {
165
+ const payload = JSON.parse(message.toString());
166
+ const parts = topic.split('/');
167
+ const event = parts[parts.length - 1];
168
+ // Handle server-sent system events
169
+ if (event === 'JOIN_ROOM') {
170
+ const { roomId } = payload;
171
+ this.subscribeToRoom(roomId);
172
+ return;
173
+ }
174
+ if (event === 'LEAVE_ROOM') {
175
+ const { roomId } = payload;
176
+ this.unsubscribeFromRoom(roomId);
177
+ return;
178
+ }
179
+ if (event === 'FORCE_DISCONNECT') {
180
+ this.disconnect();
181
+ return;
182
+ }
183
+ // Dispatch to registered event subjects
184
+ const subject = this.eventSubjects.get(event);
185
+ if (subject) {
186
+ console.log(`[MQTT] Event received: ${event}`, payload);
187
+ subject.next(payload);
188
+ }
189
+ }
190
+ catch (err) {
191
+ console.error(`[MQTT] Failed to parse message from topic ${topic}:`, err);
192
+ }
141
193
  });
142
- this.socket.on('connect_error', (err) => {
143
- console.error('Connection error:', err.message);
194
+ this.mqttClient.on('disconnect', () => {
195
+ console.log('[MQTT] Disconnected');
196
+ this.connectionStatusSubject.next(false);
197
+ this.healthySubject.next(false);
144
198
  });
145
- this.socket.on('reconnect_error', (err) => {
146
- console.error('Reconnection error:', err.message);
199
+ this.mqttClient.on('error', (err) => {
200
+ console.error('[MQTT] Connection error:', err.message);
147
201
  });
148
- // Socket.IO built-in ping/pong for health monitoring
149
- this.socket.io.on('ping', () => {
150
- this.lastPongTime = Date.now();
151
- this.healthySubject.next(true);
202
+ this.mqttClient.on('reconnect', () => {
203
+ console.log('[MQTT] Reconnecting...');
152
204
  });
153
- // Start health check monitoring
154
- this.startHealthCheck();
155
- }
156
- /**
157
- * Monitor connection health via ping/pong timing
158
- */
159
- startHealthCheck() {
160
- this.stopHealthCheck();
161
- this.lastPongTime = Date.now();
162
- // Check health every 30 seconds
163
- this.healthCheckInterval = setInterval(() => {
164
- if (!this.socket?.connected) {
165
- this.healthySubject.next(false);
166
- return;
167
- }
168
- const timeSinceLastPong = Date.now() - this.lastPongTime;
169
- // If no pong in last 60 seconds, connection may be stale
170
- if (timeSinceLastPong > 60000) {
171
- console.warn('[Socket] Connection appears stale, forcing reconnect');
172
- this.healthySubject.next(false);
173
- this.socket.disconnect();
174
- this.socket.connect();
175
- }
176
- else {
177
- this.healthySubject.next(true);
178
- }
179
- }, 30000);
180
205
  }
181
- stopHealthCheck() {
182
- if (this.healthCheckInterval) {
183
- clearInterval(this.healthCheckInterval);
184
- this.healthCheckInterval = undefined;
206
+ subscribeToRoom(roomId) {
207
+ this.subscribedRooms.add(roomId);
208
+ if (this.mqttClient?.connected) {
209
+ this.mqttClient.subscribe(`${this.TOPIC_PREFIX}/room/${roomId}/#`, { qos: 1 }, (err) => {
210
+ if (err) {
211
+ console.error(`[MQTT] Failed to subscribe to room ${roomId}:`, err.message);
212
+ }
213
+ else {
214
+ console.log(`[MQTT] Subscribed to room: ${roomId}`);
215
+ }
216
+ });
185
217
  }
186
218
  }
187
- reestablishListeners() {
188
- console.log('Re-establishing listeners for', this.eventSubjects.size, 'events');
189
- this.eventSubjects.forEach((subject, eventName) => {
190
- // Remove any existing listener to avoid duplicates
191
- this.socket.off(eventName);
192
- // Add the listener
193
- console.log('registering', eventName);
194
- this.socket.on(eventName, (data) => {
195
- console.log(`[Socket] Event received: ${eventName}`, data);
196
- subject.next(data);
197
- });
198
- });
219
+ unsubscribeFromRoom(roomId) {
220
+ this.subscribedRooms.delete(roomId);
221
+ if (this.mqttClient?.connected) {
222
+ this.mqttClient.unsubscribe(`${this.TOPIC_PREFIX}/room/${roomId}/#`);
223
+ }
199
224
  }
200
225
  /**
201
- * Set authentication token for socket connection
226
+ * Set authentication token for MQTT connection.
227
+ * Call connect() afterwards to open the connection.
202
228
  */
203
229
  setAuthToken(token) {
204
230
  this.authToken = token;
205
231
  }
206
232
  /**
207
- * Set connection key for socket connection
233
+ * Set connection key included in outbound message headers.
208
234
  */
209
235
  setConnectionKey(key) {
210
236
  this.connectionKey = key;
211
237
  }
212
238
  /**
213
- * Reset connection with new token
239
+ * Reset connection with new token.
240
+ * Idempotent: no-op if the same token is already active and connected.
214
241
  */
215
242
  resetWithNewToken(token) {
243
+ const tokenUnchanged = !token || token === this.authToken;
244
+ const clientActive = this.mqttClient?.connected;
245
+ if (tokenUnchanged && clientActive) {
246
+ return;
247
+ }
216
248
  if (token) {
217
249
  this.authToken = token;
218
250
  }
219
- if (this.socket) {
220
- this.socket.disconnect();
221
- }
222
- this.setupSocketConnection();
251
+ this.setupConnection();
223
252
  }
224
253
  connect(timeoutMs = 15000) {
225
- // Reuse existing connected socket
226
- if (this.socket?.connected) {
254
+ if (this.mqttClient?.connected) {
227
255
  return Promise.resolve();
228
256
  }
229
257
  return new Promise((resolve) => {
230
258
  const timeout = setTimeout(() => {
231
- // Don't rejectthe socket keeps reconnecting via reconnectionAttempts: Infinity.
232
- // Callers should rely on reconnect$ to re-authenticate once connected.
233
- console.warn('[Socket] Connection timeout — socket will keep retrying in background');
259
+ console.warn('[MQTT] Connection timeout client will keep retrying in background');
234
260
  resolve();
235
261
  }, timeoutMs);
236
- this.setupSocketConnection();
237
- if (this.socket.connected) {
262
+ if (!this.mqttClient) {
263
+ this.setupConnection();
264
+ }
265
+ if (this.mqttClient?.connected) {
238
266
  clearTimeout(timeout);
239
267
  resolve();
240
268
  return;
241
269
  }
242
- // Wait for the connect event
243
- this.socket.once('connect', () => {
270
+ this.mqttClient?.once('connect', () => {
244
271
  clearTimeout(timeout);
245
272
  resolve();
246
273
  });
247
- this.socket.on('connect_error', (err) => {
248
- // Log but don't reject — reconnection logic will keep retrying
249
- console.warn('[Socket] connect_error:', err.message);
250
- });
251
- if (!this.socket.connected) {
252
- this.socket.connect();
253
- }
254
274
  });
255
275
  }
256
276
  disconnect() {
257
- this.stopHealthCheck();
258
- if (this.socket?.connected) {
259
- this.socket.disconnect();
277
+ if (this.mqttClient?.connected) {
278
+ this.mqttClient.end();
260
279
  }
280
+ this.subscribedRooms.clear();
281
+ this.connectionStatusSubject.next(false);
261
282
  this.healthySubject.next(false);
262
283
  }
263
284
  /**
264
- * Emit event with optional authentication headers
285
+ * Emit an event to the server (client → server).
286
+ * Publishes to serve-plus/client/{userId}/{event}.
265
287
  */
266
288
  emit(event, data) {
267
- if (!this.socket || this.socket.disconnected) {
268
- console.warn('Socket not connected. Call connect() first.');
289
+ if (!this.mqttClient?.connected || !this.userId) {
290
+ console.warn('[MQTT] Not connected or no user ID. Call connect() first.');
269
291
  return;
270
292
  }
271
- // If auth token or connection key exists, wrap data with headers
272
- if (this.authToken || this.connectionKey) {
273
- const payload = {
274
- payload: data || {},
275
- headers: {
276
- ...(this.authToken && { _authToken: this.authToken }),
277
- ...(this.connectionKey && { connectionKey: this.connectionKey })
278
- }
279
- };
280
- this.socket.emit(event, payload);
281
- }
282
- else {
283
- this.socket.emit(event, data);
284
- }
293
+ const payload = {
294
+ payload: data ?? {},
295
+ headers: {
296
+ ...(this.authToken && { _authToken: this.authToken }),
297
+ ...(this.connectionKey && { connectionKey: this.connectionKey }),
298
+ },
299
+ };
300
+ this.mqttClient.publish(`${this.TOPIC_PREFIX}/client/${this.userId}/${event}`, JSON.stringify(payload), { qos: 1 });
285
301
  }
286
302
  /**
287
- * Listen to events with persistent subjects that survive reconnections
303
+ * Listen to server-sent events. Returns a persistent Observable that
304
+ * survives reconnections (matching the previous socket.io behaviour).
288
305
  */
289
306
  on(event) {
290
307
  if (!this.eventSubjects.has(event)) {
291
- const subject = new Subject();
292
- this.eventSubjects.set(event, subject);
293
- // Set up listener if socket exists and is connected
294
- if (this.socket?.connected) {
295
- console.log(`[Socket] Registering listener for event: ${event}`);
296
- this.socket.on(event, (data) => {
297
- console.log(`[Socket] Event received: ${event}`, data);
298
- subject.next(data);
299
- });
300
- }
301
- else {
302
- console.log(`[Socket] Event ${event} registered but socket not connected yet - will attach on connection`);
303
- }
308
+ this.eventSubjects.set(event, new Subject());
309
+ console.log(`[MQTT] Registered listener for event: ${event}`);
304
310
  }
305
311
  return this.eventSubjects.get(event).asObservable();
306
312
  }
307
313
  /**
308
- * Listen to event once and return as Promise
309
- * @param event - Event name to listen for
310
- * @param timeoutMs - Timeout in ms (default 30s, 0 = no timeout)
314
+ * Listen for a single event occurrence and return as a Promise.
311
315
  */
312
316
  once(event, timeoutMs = 30000) {
313
- if (!this.socket || this.socket.disconnected) {
314
- return Promise.reject(new Error('Socket not connected. Call connect() first.'));
317
+ if (!this.mqttClient?.connected) {
318
+ return Promise.reject(new Error('[MQTT] Not connected. Call connect() first.'));
315
319
  }
316
320
  return new Promise((resolve, reject) => {
317
321
  let timeoutId;
318
- const handler = (data) => {
322
+ const subscription = this.on(event).subscribe((data) => {
319
323
  if (timeoutId)
320
324
  clearTimeout(timeoutId);
325
+ subscription.unsubscribe();
321
326
  resolve(data);
322
- };
327
+ });
323
328
  if (timeoutMs > 0) {
324
329
  timeoutId = setTimeout(() => {
325
- this.socket.off(event, handler);
326
- reject(new Error(`Timeout waiting for event: ${event}`));
330
+ subscription.unsubscribe();
331
+ reject(new Error(`[MQTT] Timeout waiting for event: ${event}`));
327
332
  }, timeoutMs);
328
333
  }
329
- this.socket.once(event, handler);
330
334
  });
331
335
  }
332
336
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SocketService, deps: [{ token: REALTIME_STORE_ENVIRONMENT }], target: i0.ɵɵFactoryTarget.Injectable });
@@ -784,43 +788,48 @@ function provideRealtimeStoreEnvironment(environment) {
784
788
  }
785
789
 
786
790
  /**
787
- * Handles the socket connection lifecycle for the driver app.
788
- * Reads the driver token from localStorage and connects/reconnects with it.
791
+ * Handles the MQTT connection lifecycle for the driver app.
792
+ *
793
+ * Pattern:
794
+ * - Use setAuthToken() + connect() instead of resetWithNewToken() so an in-progress
795
+ * connection is never torn down by a duplicate call (e.g. on page refresh).
796
+ * - reconnect$ emits when the MQTT client re-establishes after a drop; use it to
797
+ * re-emit DRIVER_CONNECT so the server re-joins the driver to their rooms.
798
+ * - A 'online' event listener handles recovery when the network comes back.
789
799
  *
790
800
  * Usage:
791
- * - `AppComponent.ngOnInit`: call `connectFromStorage()` to restore session on app start.
792
- * - `LoginPage` success handler: call `connect(token)` after receiving a new token.
801
+ * - AppComponent.ngOnInit: call connectFromStorage() ONCE to restore session.
802
+ * - LoginPage success handler: call connect(token) after receiving a new token.
793
803
  */
794
804
  class DriverSocketConnectionService {
795
805
  socketService;
796
806
  TOKEN_KEY = 'driver_token';
797
- reconnectSubscription;
807
+ networkListener;
798
808
  constructor(socketService) {
799
809
  this.socketService = socketService;
810
+ this.networkListener = () => this.connectFromStorage();
811
+ window.addEventListener('online', this.networkListener);
800
812
  }
801
813
  /** Connect using a freshly obtained token (e.g. after login). */
802
814
  connect(token) {
803
815
  localStorage.setItem(this.TOKEN_KEY, token);
804
- this.socketService.resetWithNewToken(token);
805
- this.subscribeToReconnect(token);
816
+ this.socketService.setAuthToken(token);
817
+ this.socketService.connect();
806
818
  }
807
819
  /** Restore the socket connection from a persisted token (e.g. on app start). */
808
820
  connectFromStorage() {
809
821
  const token = localStorage.getItem(this.TOKEN_KEY);
810
822
  if (token) {
811
- this.socketService.resetWithNewToken(token);
812
- this.subscribeToReconnect(token);
823
+ this.socketService.setAuthToken(token);
824
+ this.socketService.connect();
813
825
  }
814
826
  }
815
827
  disconnect() {
816
- this.reconnectSubscription?.unsubscribe();
817
828
  this.socketService.disconnect();
818
- }
819
- subscribeToReconnect(token) {
820
- this.reconnectSubscription?.unsubscribe();
821
- this.reconnectSubscription = this.socketService.reconnect$.subscribe(() => {
822
- this.socketService.resetWithNewToken(token);
823
- });
829
+ if (this.networkListener) {
830
+ window.removeEventListener('online', this.networkListener);
831
+ this.networkListener = undefined;
832
+ }
824
833
  }
825
834
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DriverSocketConnectionService, deps: [{ token: SocketService }], target: i0.ɵɵFactoryTarget.Injectable });
826
835
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DriverSocketConnectionService, providedIn: 'root' });
@@ -833,42 +842,46 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
833
842
  }], ctorParameters: () => [{ type: SocketService }] });
834
843
 
835
844
  /**
836
- * Handles the socket connection lifecycle for the customer-food (online customer) app.
837
- * Reads the online customer token from localStorage and connects/reconnects with it.
845
+ * Handles the MQTT connection lifecycle for the customer-food (online customer) app.
846
+ *
847
+ * Pattern:
848
+ * - Use setAuthToken() + connect() instead of resetWithNewToken() so an in-progress
849
+ * connection is never torn down by a duplicate call (e.g. on page refresh).
850
+ * - reconnect$ emits when the MQTT client re-establishes after a drop; use it to
851
+ * re-emit CUSTOMER_CONNECT so the server re-joins the client to their rooms.
852
+ * - A 'online' event listener handles recovery when the network comes back.
838
853
  *
839
854
  * Usage:
840
- * - `AppComponent.ngOnInit`: call `connectFromStorage()` to restore session on app start.
841
- * - `LoginPage` success handler: call `connect(token)` after receiving a new token.
855
+ * - AppComponent.ngOnInit: call connectFromStorage() ONCE to restore session.
856
+ * - LoginPage success handler: call connect(token) after receiving a new token.
842
857
  */
843
858
  class OnlineCustomerSocketConnectionService {
844
859
  socketService;
845
860
  TOKEN_KEY = 'online_customer_token';
846
- reconnectSubscription;
861
+ networkListener;
847
862
  constructor(socketService) {
848
863
  this.socketService = socketService;
864
+ this.networkListener = () => this.connectFromStorage();
865
+ window.addEventListener('online', this.networkListener);
849
866
  }
850
867
  /** Connect using a freshly obtained token (e.g. after login). */
851
868
  connect(token) {
852
- this.socketService.resetWithNewToken(token);
853
- this.subscribeToReconnect(token);
869
+ this.socketService.setAuthToken(token);
870
+ this.socketService.connect();
854
871
  }
855
872
  /** Restore the socket connection from a persisted token (e.g. on app start). */
856
873
  connectFromStorage() {
857
874
  const token = localStorage.getItem(this.TOKEN_KEY);
858
875
  if (token) {
859
- this.socketService.resetWithNewToken(token);
860
- this.subscribeToReconnect(token);
876
+ this.connect(token);
861
877
  }
862
878
  }
863
879
  disconnect() {
864
- this.reconnectSubscription?.unsubscribe();
865
880
  this.socketService.disconnect();
866
- }
867
- subscribeToReconnect(token) {
868
- this.reconnectSubscription?.unsubscribe();
869
- this.reconnectSubscription = this.socketService.reconnect$.subscribe(() => {
870
- this.socketService.resetWithNewToken(token);
871
- });
881
+ if (this.networkListener) {
882
+ window.removeEventListener('online', this.networkListener);
883
+ this.networkListener = undefined;
884
+ }
872
885
  }
873
886
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: OnlineCustomerSocketConnectionService, deps: [{ token: SocketService }], target: i0.ɵɵFactoryTarget.Injectable });
874
887
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: OnlineCustomerSocketConnectionService, providedIn: 'root' });
@@ -1 +1 @@
1
- {"version":3,"file":"serve-socket.mjs","sources":["../../../projects/serve-socket/src/lib/realtime-store.module.ts","../../../projects/serve-socket/src/lib/environment/realtime-store-environment.interface.ts","../../../projects/serve-socket/src/lib/environment/realtime-store-environment.token.ts","../../../projects/serve-socket/src/lib/socket.service.ts","../../../projects/serve-socket/src/lib/base-store.ts","../../../projects/serve-socket/src/lib/stores/table.store.ts","../../../projects/serve-socket/src/lib/stores/cart.store.ts","../../../projects/serve-socket/src/lib/stores/call-waiter.store.ts","../../../projects/serve-socket/src/lib/stores/notification.store.ts","../../../projects/serve-socket/src/lib/stores/delivery-order.store.ts","../../../projects/serve-socket/src/lib/stores/reservation.store.ts","../../../projects/serve-socket/src/lib/stores/inventory.store.ts","../../../projects/serve-socket/src/lib/providers.ts","../../../projects/serve-socket/src/lib/providers/realtime-store-environment.provider.ts","../../../projects/serve-socket/src/lib/driver-socket-connection.service.ts","../../../projects/serve-socket/src/lib/online-customer-socket-connection.service.ts","../../../projects/serve-socket/src/public-api.ts","../../../projects/serve-socket/src/serve-socket.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { HttpClientModule } from '@angular/common/http';\n\n/**\n * @deprecated Use provideRealtimeStore() with standalone components instead\n */\n@NgModule({\n declarations: [],\n imports: [\n CommonModule,\n HttpClientModule // Kept for backward compatibility with Angular <14\n ],\n exports: []\n})\nexport class RealtimeStoreModule { }\n","import { SocketSuccessEventKeys } from '../socket.service';\n\nexport interface RealtimeStoreEnvironment {\n apiUrl: string;\n}\n\nexport const defaultRealtimeStoreEnvironment: RealtimeStoreEnvironment = {\n apiUrl: `http://${window.location.hostname}:3030`,\n};","import { InjectionToken } from '@angular/core';\nimport { RealtimeStoreEnvironment } from './realtime-store-environment.interface';\n\nexport const REALTIME_STORE_ENVIRONMENT = new InjectionToken<RealtimeStoreEnvironment>('REALTIME_STORE_ENVIRONMENT');","import { Injectable, Inject } from '@angular/core';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { io, Socket } from 'socket.io-client';\nimport { REALTIME_STORE_ENVIRONMENT, RealtimeStoreEnvironment, defaultRealtimeStoreEnvironment } from './environment';\n\nexport enum SocketSuccessEventKeys {\n CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS = 'CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS',\n CUSTOMER_REMOVE_FROM_CART_SUCCESS = 'CUSTOMER_REMOVE_FROM_CART_SUCCESS',\n TABLE_JOIN_REQUEST_SENT_SUCCESS = 'TABLE_JOIN_REQUEST_SENT_SUCCESS',\n TABLE_CREATED_OR_UPDATED = 'TABLE_CREATED_OR_UPDATED',\n TABLE_RELEASED = 'TABLE_RELEASED',\n HOST_JOIN_REQUEST_APPROVED_SUCCESS = 'HOST_JOIN_REQUEST_APPROVED_SUCCESS',\n HOST_JOIN_REQUEST_DECLINED = 'HOST_JOIN_REQUEST_DECLINED',\n WAITER_CALL_CREATED_SUCCESS = 'WAITER_CALL_CREATED_SUCCESS',\n WAITER_CALL_ACKNOWLEDGED_SUCCESS = 'WAITER_CALL_ACKNOWLEDGED_SUCCESS',\n ERROR_MESSAGE_SUCCESS = 'ERROR_MESSAGE_SUCCESS',\n SUCCESS_MESSAGE_SUCCESS = 'SUCCESS_MESSAGE_SUCCESS',\n WARNING_MESSAGE_SUCCESS = 'WARNING_MESSAGE_SUCCESS',\n // Delivery\n NEW_DELIVERY_ORDER = 'NEW_DELIVERY_ORDER',\n ORDER_STATUS_UPDATED = 'ORDER_STATUS_UPDATED',\n DRIVER_LOCATION_UPDATED = 'DRIVER_LOCATION_UPDATED',\n // Reservations\n RESERVATION_CREATE_OR_UPDATE_SUCCESS = 'RESERVATION_CREATE_OR_UPDATE_SUCCESS',\n RESERVATION_REMOVE_SUCCESS = 'RESERVATION_REMOVE_SUCCESS',\n // Inventory\n INVENTORY_STOCK_UPDATED = 'INVENTORY_STOCK_UPDATED',\n INVENTORY_LOW_STOCK_ALERT = 'INVENTORY_LOW_STOCK_ALERT',\n INVENTORY_PURCHASE_ORDER_UPDATED = 'INVENTORY_PURCHASE_ORDER_UPDATED',\n // Billing\n BILLING_SUBSCRIPTION_UPDATED = 'BILLING_SUBSCRIPTION_UPDATED',\n BILLING_INVOICE_ISSUED = 'BILLING_INVOICE_ISSUED',\n BILLING_PAYMENT_RECEIVED = 'BILLING_PAYMENT_RECEIVED',\n BILLING_TRIAL_EXPIRING = 'BILLING_TRIAL_EXPIRING',\n BILLING_INVOICE_OVERDUE = 'BILLING_INVOICE_OVERDUE',\n BILLING_SUBSCRIPTION_SUSPENDED = 'BILLING_SUBSCRIPTION_SUSPENDED',\n BILLING_CREDIT_NOTE_ISSUED = 'BILLING_CREDIT_NOTE_ISSUED',\n BILLING_REFUND_PROCESSED = 'BILLING_REFUND_PROCESSED',\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class SocketService {\n private socket!: Socket;\n private readonly url: string;\n private authToken?: string;\n private connectionKey?: string;\n private readonly eventSubjects = new Map<string, Subject<any>>();\n\n private readonly connectionStatusSubject = new BehaviorSubject<boolean>(false);\n public connectionStatus$ = this.connectionStatusSubject.asObservable();\n\n private readonly reconnectSubject = new Subject<void>();\n public reconnect$ = this.reconnectSubject.asObservable();\n\n private hasConnectedOnce = false;\n\n private readonly healthySubject = new BehaviorSubject<boolean>(false);\n public healthy$ = this.healthySubject.asObservable();\n\n private healthCheckInterval?: ReturnType<typeof setInterval>;\n private lastPongTime = 0;\n\n constructor(\n @Inject(REALTIME_STORE_ENVIRONMENT) private readonly environment: RealtimeStoreEnvironment = defaultRealtimeStoreEnvironment\n ) {\n this.url = this.environment.apiUrl;\n }\n\n private setupSocketConnection(): void {\n // Cleanup existing socket to prevent memory leaks\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.disconnect();\n }\n\n const socketOptions: any = {\n transports: ['websocket'],\n autoConnect: true,\n reconnection: true,\n reconnectionAttempts: Infinity,\n reconnectionDelay: 1000,\n reconnectionDelayMax: 10000\n };\n\n // Add auth if token is available\n if (this.authToken) {\n socketOptions.auth = {\n token: this.authToken\n };\n }\n\n this.socket = io(this.url, socketOptions);\n\n this.socket.on('connect', () => {\n console.log('Socket connected');\n this.connectionStatusSubject.next(true);\n this.reestablishListeners();\n });\n\n this.socket.on('disconnect', () => {\n console.log('Socket disconnected');\n this.connectionStatusSubject.next(false);\n });\n\n // In Socket.IO v4 the 'reconnect' event is on the Manager (socket.io), not the socket.\n // hasConnectedOnce is an instance variable so it persists across resetWithNewToken() calls.\n // Any connect after the very first one (regardless of socket recreation) triggers stores to reload.\n this.socket.on('connect', () => {\n if (this.hasConnectedOnce) {\n console.log('Socket reconnected');\n this.reconnectSubject.next();\n }\n this.hasConnectedOnce = true;\n });\n\n // Keep the manager-level listener as a fallback for older versions\n this.socket.io.on('reconnect', () => {\n console.log('Socket manager reconnected');\n this.connectionStatusSubject.next(true);\n this.reconnectSubject.next();\n this.reestablishListeners();\n });\n\n this.socket.on('connect_error', (err) => {\n console.error('Connection error:', err.message);\n });\n\n this.socket.on('reconnect_error', (err) => {\n console.error('Reconnection error:', err.message);\n });\n\n // Socket.IO built-in ping/pong for health monitoring\n this.socket.io.on('ping', () => {\n this.lastPongTime = Date.now();\n this.healthySubject.next(true);\n });\n\n // Start health check monitoring\n this.startHealthCheck();\n }\n\n /**\n * Monitor connection health via ping/pong timing\n */\n private startHealthCheck(): void {\n this.stopHealthCheck();\n\n this.lastPongTime = Date.now();\n\n // Check health every 30 seconds\n this.healthCheckInterval = setInterval(() => {\n if (!this.socket?.connected) {\n this.healthySubject.next(false);\n return;\n }\n\n const timeSinceLastPong = Date.now() - this.lastPongTime;\n // If no pong in last 60 seconds, connection may be stale\n if (timeSinceLastPong > 60000) {\n console.warn('[Socket] Connection appears stale, forcing reconnect');\n this.healthySubject.next(false);\n this.socket.disconnect();\n this.socket.connect();\n } else {\n this.healthySubject.next(true);\n }\n }, 30000);\n }\n\n private stopHealthCheck(): void {\n if (this.healthCheckInterval) {\n clearInterval(this.healthCheckInterval);\n this.healthCheckInterval = undefined;\n }\n }\n\n private reestablishListeners(): void {\n console.log('Re-establishing listeners for', this.eventSubjects.size, 'events');\n this.eventSubjects.forEach((subject, eventName) => {\n // Remove any existing listener to avoid duplicates\n this.socket.off(eventName);\n // Add the listener\n console.log('registering', eventName);\n\n this.socket.on(eventName, (data) => {\n console.log(`[Socket] Event received: ${eventName}`, data);\n subject.next(data);\n });\n });\n }\n\n /**\n * Set authentication token for socket connection\n */\n public setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * Set connection key for socket connection\n */\n public setConnectionKey(key: string): void {\n this.connectionKey = key;\n }\n\n /**\n * Reset connection with new token\n */\n public resetWithNewToken(token?: string): void {\n if (token) {\n this.authToken = token;\n }\n\n if (this.socket) {\n this.socket.disconnect();\n }\n\n this.setupSocketConnection();\n }\n\n public connect(timeoutMs = 15000): Promise<void> {\n // Reuse existing connected socket\n if (this.socket?.connected) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n // Don't reject — the socket keeps reconnecting via reconnectionAttempts: Infinity.\n // Callers should rely on reconnect$ to re-authenticate once connected.\n console.warn('[Socket] Connection timeout — socket will keep retrying in background');\n resolve();\n }, timeoutMs);\n\n this.setupSocketConnection();\n\n if (this.socket.connected) {\n clearTimeout(timeout);\n resolve();\n return;\n }\n\n // Wait for the connect event\n this.socket.once('connect', () => {\n clearTimeout(timeout);\n resolve();\n });\n\n this.socket.on('connect_error', (err) => {\n // Log but don't reject — reconnection logic will keep retrying\n console.warn('[Socket] connect_error:', err.message);\n });\n\n if (!this.socket.connected) {\n this.socket.connect();\n }\n });\n }\n\n public disconnect(): void {\n this.stopHealthCheck();\n if (this.socket?.connected) {\n this.socket.disconnect();\n }\n this.healthySubject.next(false);\n }\n\n /**\n * Emit event with optional authentication headers\n */\n public emit(event: string, data?: any): void {\n if (!this.socket || this.socket.disconnected) {\n console.warn('Socket not connected. Call connect() first.');\n return;\n }\n\n // If auth token or connection key exists, wrap data with headers\n if (this.authToken || this.connectionKey) {\n const payload = {\n payload: data || {},\n headers: {\n ...(this.authToken && { _authToken: this.authToken }),\n ...(this.connectionKey && { connectionKey: this.connectionKey })\n }\n };\n this.socket.emit(event, payload);\n } else {\n this.socket.emit(event, data);\n }\n }\n\n /**\n * Listen to events with persistent subjects that survive reconnections\n */\n public on<T>(event: string): Observable<T> {\n if (!this.eventSubjects.has(event)) {\n const subject = new Subject<T>();\n this.eventSubjects.set(event, subject);\n\n // Set up listener if socket exists and is connected\n if (this.socket?.connected) {\n console.log(`[Socket] Registering listener for event: ${event}`);\n this.socket.on(event, (data: T) => {\n console.log(`[Socket] Event received: ${event}`, data);\n subject.next(data);\n });\n } else {\n console.log(`[Socket] Event ${event} registered but socket not connected yet - will attach on connection`);\n }\n }\n\n return this.eventSubjects.get(event)!.asObservable();\n }\n\n /**\n * Listen to event once and return as Promise\n * @param event - Event name to listen for\n * @param timeoutMs - Timeout in ms (default 30s, 0 = no timeout)\n */\n public once<T>(event: string, timeoutMs = 30000): Promise<T> {\n if (!this.socket || this.socket.disconnected) {\n return Promise.reject(new Error('Socket not connected. Call connect() first.'));\n }\n\n return new Promise((resolve, reject) => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const handler = (data: T) => {\n if (timeoutId) clearTimeout(timeoutId);\n resolve(data);\n };\n\n if (timeoutMs > 0) {\n timeoutId = setTimeout(() => {\n this.socket.off(event, handler);\n reject(new Error(`Timeout waiting for event: ${event}`));\n }, timeoutMs);\n }\n\n this.socket.once(event, handler);\n });\n }\n}\n\n","import { BehaviorSubject, filter, map, Observable, Subject, Subscription, switchMap } from 'rxjs';\nimport { debounceTime, first, pairwise, takeUntil } from 'rxjs/operators';\nimport { SocketService } from './socket.service';\n\nexport interface Entity {\n id?: string;\n}\n\nexport abstract class BaseStore<T extends Entity> {\n protected dataSubject = new BehaviorSubject<T[]>([]);\n public data$: Observable<T[]> = this.dataSubject.asObservable();\n\n protected loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n protected errorSubject = new BehaviorSubject<string | null>(null);\n public error$: Observable<string | null> = this.errorSubject.asObservable();\n\n private readonly destroy$ = new Subject<void>();\n private refreshInProgress = false;\n\n constructor(\n protected socketService: SocketService\n ) {\n // Defer initialization to allow child class constructor parameters to be assigned\n queueMicrotask(() => {\n this.initialize().then(() => { });\n });\n }\n\n private async initialize(): Promise<void> {\n this.setupSocketSubscriptions();\n this.refresh();\n\n // Reload data after a disconnect → reconnect cycle.\n // Listening to connectionStatus$ is more reliable than reconnect$ because\n // connectionStatus$ is driven directly by socket connect/disconnect events.\n this.socketService.connectionStatus$.pipe(\n pairwise(),\n filter(([prev, curr]) => prev === true && curr === false), // detect disconnect\n switchMap(() =>\n this.socketService.connectionStatus$.pipe(\n filter(connected => connected), // wait for next reconnect\n first()\n )\n ),\n debounceTime(1000), // give server time to be fully ready\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.refresh();\n });\n }\n\n public refresh() {\n // Prevent concurrent refresh calls\n if (this.refreshInProgress) {\n return;\n }\n this.refreshInProgress = true;\n this.setLoading(true);\n\n this.preload()\n .then(x => this.dataSubject.next(x))\n .catch(err => {\n console.error(`[${this.constructor.name}] Preload failed:`, err);\n this.setError(err.message || 'Failed to load data');\n })\n .finally(() => {\n this.refreshInProgress = false;\n this.setLoading(false);\n });\n }\n\n /**\n * Clean up subscriptions when store is destroyed\n */\n public destroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // Abstract methods to be implemented by specific stores\n public abstract preload(): Promise<T[]>;\n\n protected abstract setupSocketSubscriptions(): void;\n\n // Helper methods for stores\n protected updateItems(items: T[]): void {\n console.log('setting', items);\n\n this.dataSubject.next(items);\n }\n\n protected updateItem(updatedItem: Partial<T> & Pick<T, 'id'>): void {\n console.log('upserting', updatedItem);\n\n const currentItems = this.dataSubject.value;\n const idField = 'id' as keyof T;\n\n const index = currentItems.findIndex(\n item => item[idField] === updatedItem[idField]\n );\n\n let updatedItems: T[];\n\n if (index > -1) {\n // 🔁 Update existing item\n updatedItems = currentItems.map((item, i) =>\n i === index ? { ...item, ...updatedItem } as T : item\n );\n } else {\n // ➕ Add new item\n updatedItems = [...currentItems, updatedItem as T];\n }\n\n this.dataSubject.next(updatedItems);\n }\n\n\n protected removeItem(id: string): void {\n console.log('removing', id);\n\n const currentItems = this.dataSubject.value;\n const idField = 'id' as keyof T;\n const filteredItems = currentItems.filter(item => item[idField] !== id);\n this.dataSubject.next(filteredItems);\n }\n\n protected setLoading(isLoading: boolean): void {\n this.loadingSubject.next(isLoading);\n }\n\n protected setError(error: string | null): void {\n this.errorSubject.next(error);\n }\n\n // Helper to subscribe to socket events with typesafety\n protected subscribeToEvent<R>(\n event: string,\n handler: (data: R) => void\n ): void {\n this.socketService.on<R>(event).subscribe(handler);\n }\n\n getAll(): T[] {\n return this.dataSubject.value;\n }\n\n getById(id: string): T | undefined {\n const field = 'id' as keyof T;\n return this.dataSubject.value.find(item => item[field] === id);\n }\n\n getById$(id: string): Observable<T | undefined> {\n const field = 'id' as keyof T;\n return this.data$.pipe(\n map(items => items.find(item => item[field] === id))\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\nexport interface PendingJoinRequest {\n id: string;\n name: string;\n tableId: string;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class TableStore<T extends Entity> extends BaseStore<T> {\n // Store pending customer join requests\n private pendingJoinRequestsSubject = new BehaviorSubject<PendingJoinRequest[]>([]);\n public pendingJoinRequests$ = this.pendingJoinRequestsSubject.asObservable();\n\n // Emits when the current customer has been approved to join the table\n private approvedSubject = new Subject<void>();\n public approved$ = this.approvedSubject.asObservable();\n\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.TABLE_CREATED_OR_UPDATED,\n (table) => this.updateItem(table)\n );\n\n this.subscribeToEvent<string>(\n SocketSuccessEventKeys.TABLE_RELEASED,\n (tableId) => this.removeItem(tableId)\n );\n\n this.subscribeToEvent<boolean>(\n SocketSuccessEventKeys.HOST_JOIN_REQUEST_APPROVED_SUCCESS,\n (status) => {\n if (status) {\n this.approvedSubject.next();\n }\n }\n );\n\n // Listen for customer join requests\n this.subscribeToEvent<PendingJoinRequest>(\n SocketSuccessEventKeys.TABLE_JOIN_REQUEST_SENT_SUCCESS,\n (request) => {\n console.log('[TableStore] Customer join request received:', request);\n const current = this.pendingJoinRequestsSubject.value;\n // Avoid duplicates\n if (!current.find(r => r.id === request.id)) {\n this.pendingJoinRequestsSubject.next([...current, request]);\n }\n }\n );\n }\n\n // Remove a pending join request (e.g., after approval/decline)\n public removePendingJoinRequest(customerId: string): void {\n const current = this.pendingJoinRequestsSubject.value;\n this.pendingJoinRequestsSubject.next(current.filter(r => r.id !== customerId));\n }\n\n // Clear all pending join requests\n public clearPendingJoinRequests(): void {\n this.pendingJoinRequestsSubject.next([]);\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { Injectable } from '@angular/core';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class CartStore<T extends Entity> extends BaseStore<T> {\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n console.log('[CartStore] Setting up socket subscriptions');\n console.log('[CartStore] CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS event:', SocketSuccessEventKeys.CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS);\n\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS,\n (cart) => {\n console.log('[CartStore] CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS handler called with:', cart);\n this.updateItem(cart);\n console.log(this.dataSubject.getValue());\n\n }\n );\n\n this.subscribeToEvent<string>(\n SocketSuccessEventKeys.CUSTOMER_REMOVE_FROM_CART_SUCCESS,\n (cartId) => {\n console.log('[CartStore] CUSTOMER_REMOVE_FROM_CART_SUCCESS handler called with:', cartId);\n this.removeItem(cartId);\n console.log(this.dataSubject.getValue());\n }\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class CallWaiterStore<T extends Entity> extends BaseStore<T> {\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n console.log('[CallWaiterStore] Setting up socket subscriptions');\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.WAITER_CALL_CREATED_SUCCESS,\n (request) => this.updateItem(request)\n );\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\nimport { ToastrService } from 'ngx-toastr';\n\nexport interface CartEventData {\n id: string;\n tableId: string;\n menuItemId?: string;\n customerCarts?: Array<{\n id: string;\n status?: string;\n customer?: {\n name?: string;\n };\n }>;\n}\n\nexport interface ReadyOrderAlert {\n id: string;\n cartId: string;\n tableId: string;\n customerName: string;\n timestamp: Date;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class NotificationStore {\n private readonly defaultOptions = {\n closeButton: true,\n progressBar: true\n };\n\n // Ready order alerts with dismiss functionality\n private readyOrderAlertsSubject = new BehaviorSubject<ReadyOrderAlert[]>([]);\n public readyOrderAlerts$ = this.readyOrderAlertsSubject.asObservable();\n\n constructor(\n protected socketService: SocketService,\n private readonly toastr: ToastrService\n ) {\n this.setupSocketSubscriptions();\n\n this.socketService.reconnect$.subscribe(() => {\n this.setupSocketSubscriptions();\n });\n }\n\n private setupSocketSubscriptions(): void {\n // Error messages\n this.socketService.on<{ message: string }>(SocketSuccessEventKeys.ERROR_MESSAGE_SUCCESS)\n .subscribe((data) => this.showError(data.message));\n\n // Success messages\n this.socketService.on<{ message: string }>(SocketSuccessEventKeys.SUCCESS_MESSAGE_SUCCESS)\n .subscribe((data) => this.showSuccess(data.message));\n\n // Warning messages\n this.socketService.on<{ message: string }>(SocketSuccessEventKeys.WARNING_MESSAGE_SUCCESS)\n .subscribe((data) => this.showWarning(data.message));\n\n // Cart update notifications - check for PREPARED status\n this.socketService.on<CartEventData>(SocketSuccessEventKeys.CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS)\n .subscribe((cart) => {\n console.log('[NotificationStore] Cart updated:', cart);\n\n // Check if any customer cart has PREPARED status\n const preparedCarts = cart.customerCarts?.filter(cc => cc.status === 'PREPARED') || [];\n\n if (preparedCarts.length > 0) {\n // This is a ready order - show special notification with vibration\n const customerName = preparedCarts[0]?.customer?.name || 'Customer';\n this.handleReadyOrder(cart, customerName);\n }\n // No toast for regular cart updates\n });\n\n // Cart removal notifications - just log, no toast\n this.socketService.on<string>(SocketSuccessEventKeys.CUSTOMER_REMOVE_FROM_CART_SUCCESS)\n .subscribe((cartId) => {\n console.log('[NotificationStore] Cart removed:', cartId);\n });\n }\n\n /**\n * Handle ready order notification with vibration and dismissable alert\n */\n private handleReadyOrder(cart: CartEventData, customerName: string): void {\n console.log('[NotificationStore] Ready order detected!', cart);\n\n // Vibrate device if supported\n this.vibrateDevice();\n\n // Add to ready order alerts\n const alert: ReadyOrderAlert = {\n id: `${cart.id}-${Date.now()}`,\n cartId: cart.id,\n tableId: cart.tableId,\n customerName,\n timestamp: new Date()\n };\n\n const currentAlerts = this.readyOrderAlertsSubject.value;\n this.readyOrderAlertsSubject.next([alert, ...currentAlerts]);\n\n // Also show toast with longer duration\n this.toastr.success(\n `Order ready for ${customerName}`,\n '🍽️ Order Ready!',\n {\n ...this.defaultOptions,\n timeOut: 0, // No auto-dismiss\n extendedTimeOut: 0,\n tapToDismiss: true\n }\n );\n }\n\n /**\n * Vibrate the device if supported\n */\n private vibrateDevice(): void {\n try {\n if ('vibrate' in navigator) {\n // Vibrate pattern: 200ms on, 100ms off, 200ms on\n navigator.vibrate([200, 100, 200, 100, 200]);\n }\n } catch (e) {\n console.warn('[NotificationStore] Vibration not supported', e);\n }\n }\n\n /**\n * Dismiss a ready order alert\n */\n public dismissReadyOrderAlert(alertId: string): void {\n const currentAlerts = this.readyOrderAlertsSubject.value;\n this.readyOrderAlertsSubject.next(currentAlerts.filter(a => a.id !== alertId));\n }\n\n /**\n * Dismiss all ready order alerts\n */\n public dismissAllReadyOrderAlerts(): void {\n this.readyOrderAlertsSubject.next([]);\n }\n\n // Manual notification methods\n public showError(message: string, title: string = 'Error', timeOut: number = 5000): void {\n this.toastr.error(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n public showSuccess(message: string, title: string = 'Success', timeOut: number = 3000): void {\n this.toastr.success(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n public showWarning(message: string, title: string = 'Warning', timeOut: number = 4000): void {\n this.toastr.warning(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n public showInfo(message: string, title: string = 'Info', timeOut: number = 3000): void {\n this.toastr.info(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n // Clear all toasts\n public clearAll(): void {\n this.toastr.clear();\n }\n\n // Remove a specific toast by id\n public remove(toastId: number): void {\n this.toastr.remove(toastId);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\nexport interface DeliveryLocation {\n driverId: string;\n lat: number;\n lng: number;\n orderId: string;\n timestamp?: number;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class DeliveryOrderStore<T extends Entity> extends BaseStore<T> {\n private driverLocationSubject = new BehaviorSubject<DeliveryLocation | null>(null);\n public driverLocation$ = this.driverLocationSubject.asObservable();\n\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.NEW_DELIVERY_ORDER,\n (order) => this.updateItem(order)\n );\n\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.ORDER_STATUS_UPDATED,\n (order) => this.updateItem(order)\n );\n\n this.subscribeToEvent<DeliveryLocation>(\n SocketSuccessEventKeys.DRIVER_LOCATION_UPDATED,\n (location) => this.driverLocationSubject.next(location)\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class ReservationStore<T extends Entity> extends BaseStore<T> {\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.RESERVATION_CREATE_OR_UPDATE_SUCCESS,\n (reservation) => this.updateItem(reservation)\n );\n\n this.subscribeToEvent<string>(\n SocketSuccessEventKeys.RESERVATION_REMOVE_SUCCESS,\n (reservationId) => this.removeItem(reservationId)\n );\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\nexport interface InventoryLowStockAlert {\n stockItemId: string;\n name: string;\n currentStock: number;\n threshold: number;\n branchId: string;\n}\n\nexport interface InventoryPurchaseOrderUpdate {\n purchaseOrderId: string;\n status: string;\n branchId: string;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class InventoryStore<T extends Entity> extends BaseStore<T> {\n private readonly lowStockAlertSubject = new BehaviorSubject<InventoryLowStockAlert | null>(null);\n public lowStockAlert$ = this.lowStockAlertSubject.asObservable();\n\n private readonly purchaseOrderUpdateSubject = new BehaviorSubject<InventoryPurchaseOrderUpdate | null>(null);\n public purchaseOrderUpdate$ = this.purchaseOrderUpdateSubject.asObservable();\n\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.INVENTORY_STOCK_UPDATED,\n (item) => this.updateItem(item)\n );\n\n this.subscribeToEvent<InventoryLowStockAlert>(\n SocketSuccessEventKeys.INVENTORY_LOW_STOCK_ALERT,\n (alert) => this.lowStockAlertSubject.next(alert)\n );\n\n this.subscribeToEvent<InventoryPurchaseOrderUpdate>(\n SocketSuccessEventKeys.INVENTORY_PURCHASE_ORDER_UPDATED,\n (update) => this.purchaseOrderUpdateSubject.next(update)\n );\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { EnvironmentProviders, importProvidersFrom } from '@angular/core';\nimport { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';\n\n/**\n * Provides all services needed for the realtime store to function.\n * Use this function in your standalone application's bootstrapApplication providers array.\n * \n * @example\n * ```typescript\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideRealtimeStore()\n * ]\n * });\n * ```\n */\nexport function provideRealtimeStore(): EnvironmentProviders[] {\n return [\n provideHttpClient(withInterceptorsFromDi())\n ];\n}\n","import { Provider } from '@angular/core';\nimport { REALTIME_STORE_ENVIRONMENT, RealtimeStoreEnvironment } from '../environment';\n\nexport function provideRealtimeStoreEnvironment(environment: RealtimeStoreEnvironment): Provider {\n return {\n provide: REALTIME_STORE_ENVIRONMENT,\n useValue: environment\n };\n}","import { Injectable } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { SocketService } from './socket.service';\n\n/**\n * Handles the socket connection lifecycle for the driver app.\n * Reads the driver token from localStorage and connects/reconnects with it.\n *\n * Usage:\n * - `AppComponent.ngOnInit`: call `connectFromStorage()` to restore session on app start.\n * - `LoginPage` success handler: call `connect(token)` after receiving a new token.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class DriverSocketConnectionService {\n private readonly TOKEN_KEY = 'driver_token';\n private reconnectSubscription?: Subscription;\n\n constructor(private readonly socketService: SocketService) {}\n\n /** Connect using a freshly obtained token (e.g. after login). */\n connect(token: string): void {\n localStorage.setItem(this.TOKEN_KEY, token);\n this.socketService.resetWithNewToken(token);\n this.subscribeToReconnect(token);\n }\n\n /** Restore the socket connection from a persisted token (e.g. on app start). */\n connectFromStorage(): void {\n const token = localStorage.getItem(this.TOKEN_KEY);\n if (token) {\n this.socketService.resetWithNewToken(token);\n this.subscribeToReconnect(token);\n }\n }\n\n disconnect(): void {\n this.reconnectSubscription?.unsubscribe();\n this.socketService.disconnect();\n }\n\n private subscribeToReconnect(token: string): void {\n this.reconnectSubscription?.unsubscribe();\n this.reconnectSubscription = this.socketService.reconnect$.subscribe(() => {\n this.socketService.resetWithNewToken(token);\n });\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { SocketService } from './socket.service';\n\n/**\n * Handles the socket connection lifecycle for the customer-food (online customer) app.\n * Reads the online customer token from localStorage and connects/reconnects with it.\n *\n * Usage:\n * - `AppComponent.ngOnInit`: call `connectFromStorage()` to restore session on app start.\n * - `LoginPage` success handler: call `connect(token)` after receiving a new token.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class OnlineCustomerSocketConnectionService {\n private readonly TOKEN_KEY = 'online_customer_token';\n private reconnectSubscription?: Subscription;\n\n constructor(private readonly socketService: SocketService) {}\n\n /** Connect using a freshly obtained token (e.g. after login). */\n connect(token: string): void {\n this.socketService.resetWithNewToken(token);\n this.subscribeToReconnect(token);\n }\n\n /** Restore the socket connection from a persisted token (e.g. on app start). */\n connectFromStorage(): void {\n const token = localStorage.getItem(this.TOKEN_KEY);\n if (token) {\n this.socketService.resetWithNewToken(token);\n this.subscribeToReconnect(token);\n }\n }\n\n disconnect(): void {\n this.reconnectSubscription?.unsubscribe();\n this.socketService.disconnect();\n }\n\n private subscribeToReconnect(token: string): void {\n this.reconnectSubscription?.unsubscribe();\n this.reconnectSubscription = this.socketService.reconnect$.subscribe(() => {\n this.socketService.resetWithNewToken(token);\n });\n }\n}\n","/*\n * Public API Surface of realtime-store\n */\n\nexport * from './lib/realtime-store.module';\nexport * from './lib/socket.service';\nexport * from './lib/base-store';\nexport * from './lib/stores/table.store';\nexport * from './lib/stores/cart.store';\nexport * from './lib/stores/call-waiter.store';\nexport * from './lib/stores/notification.store';\nexport * from './lib/stores/delivery-order.store';\nexport * from './lib/stores/reservation.store';\nexport * from './lib/stores/inventory.store';\nexport * from './lib/providers';\nexport * from './lib/environment';\nexport * from './lib/providers/realtime-store-environment.provider';\nexport * from './lib/driver-socket-connection.service';\nexport * from './lib/online-customer-socket-connection.service';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.SocketService"],"mappings":";;;;;;;;;AAIA;;AAEG;MASU,mBAAmB,CAAA;wGAAnB,mBAAmB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA;AAAnB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,YALxB,YAAY;AACZ,YAAA,gBAAgB;;AAIX,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,mBAAmB,YALxB,YAAY;AACZ,YAAA,gBAAgB;;;4FAIX,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAR/B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACN,oBAAA,YAAY,EAAE,EAAE;AAChB,oBAAA,OAAO,EAAE;wBACL,YAAY;AACZ,wBAAA,gBAAgB;AACnB,qBAAA;AACD,oBAAA,OAAO,EAAE;AACZ,iBAAA;;;ACRM,MAAM,+BAA+B,GAA6B;AACrE,IAAA,MAAM,EAAE,CAAA,OAAA,EAAU,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAA,KAAA,CAAO;;;MCJxC,0BAA0B,GAAG,IAAI,cAAc,CAA2B,4BAA4B;;ICEvG;AAAZ,CAAA,UAAY,sBAAsB,EAAA;AAC9B,IAAA,sBAAA,CAAA,wCAAA,CAAA,GAAA,wCAAiF;AACjF,IAAA,sBAAA,CAAA,mCAAA,CAAA,GAAA,mCAAuE;AACvE,IAAA,sBAAA,CAAA,iCAAA,CAAA,GAAA,iCAAmE;AACnE,IAAA,sBAAA,CAAA,0BAAA,CAAA,GAAA,0BAAqD;AACrD,IAAA,sBAAA,CAAA,gBAAA,CAAA,GAAA,gBAAiC;AACjC,IAAA,sBAAA,CAAA,oCAAA,CAAA,GAAA,oCAAyE;AACzE,IAAA,sBAAA,CAAA,4BAAA,CAAA,GAAA,4BAAyD;AACzD,IAAA,sBAAA,CAAA,6BAAA,CAAA,GAAA,6BAA2D;AAC3D,IAAA,sBAAA,CAAA,kCAAA,CAAA,GAAA,kCAAqE;AACrE,IAAA,sBAAA,CAAA,uBAAA,CAAA,GAAA,uBAA+C;AAC/C,IAAA,sBAAA,CAAA,yBAAA,CAAA,GAAA,yBAAmD;AACnD,IAAA,sBAAA,CAAA,yBAAA,CAAA,GAAA,yBAAmD;;AAEnD,IAAA,sBAAA,CAAA,oBAAA,CAAA,GAAA,oBAAyC;AACzC,IAAA,sBAAA,CAAA,sBAAA,CAAA,GAAA,sBAA6C;AAC7C,IAAA,sBAAA,CAAA,yBAAA,CAAA,GAAA,yBAAmD;;AAEnD,IAAA,sBAAA,CAAA,sCAAA,CAAA,GAAA,sCAA6E;AAC7E,IAAA,sBAAA,CAAA,4BAAA,CAAA,GAAA,4BAAyD;;AAEzD,IAAA,sBAAA,CAAA,yBAAA,CAAA,GAAA,yBAAmD;AACnD,IAAA,sBAAA,CAAA,2BAAA,CAAA,GAAA,2BAAuD;AACvD,IAAA,sBAAA,CAAA,kCAAA,CAAA,GAAA,kCAAqE;;AAErE,IAAA,sBAAA,CAAA,8BAAA,CAAA,GAAA,8BAA6D;AAC7D,IAAA,sBAAA,CAAA,wBAAA,CAAA,GAAA,wBAAiD;AACjD,IAAA,sBAAA,CAAA,0BAAA,CAAA,GAAA,0BAAqD;AACrD,IAAA,sBAAA,CAAA,wBAAA,CAAA,GAAA,wBAAiD;AACjD,IAAA,sBAAA,CAAA,yBAAA,CAAA,GAAA,yBAAmD;AACnD,IAAA,sBAAA,CAAA,gCAAA,CAAA,GAAA,gCAAiE;AACjE,IAAA,sBAAA,CAAA,4BAAA,CAAA,GAAA,4BAAyD;AACzD,IAAA,sBAAA,CAAA,0BAAA,CAAA,GAAA,0BAAqD;AACzD,CAAC,EAjCW,sBAAsB,KAAtB,sBAAsB,GAAA,EAAA,CAAA,CAAA;MAsCrB,aAAa,CAAA;AAsBmC,IAAA,WAAA;AArBjD,IAAA,MAAM;AACG,IAAA,GAAG;AACZ,IAAA,SAAS;AACT,IAAA,aAAa;AACJ,IAAA,aAAa,GAAG,IAAI,GAAG,EAAwB;AAE/C,IAAA,uBAAuB,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AACvE,IAAA,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE;AAErD,IAAA,gBAAgB,GAAG,IAAI,OAAO,EAAQ;AAChD,IAAA,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE;IAEhD,gBAAgB,GAAG,KAAK;AAEf,IAAA,cAAc,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AAC9D,IAAA,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE;AAE5C,IAAA,mBAAmB;IACnB,YAAY,GAAG,CAAC;AAExB,IAAA,WAAA,CACyD,cAAwC,+BAA+B,EAAA;QAAvE,IAAA,CAAA,WAAW,GAAX,WAAW;QAEhE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM;IACtC;IAEQ,qBAAqB,GAAA;;AAEzB,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACb,YAAA,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE;AAChC,YAAA,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;QAC5B;AAEA,QAAA,MAAM,aAAa,GAAQ;YACvB,UAAU,EAAE,CAAC,WAAW,CAAC;AACzB,YAAA,WAAW,EAAE,IAAI;AACjB,YAAA,YAAY,EAAE,IAAI;AAClB,YAAA,oBAAoB,EAAE,QAAQ;AAC9B,YAAA,iBAAiB,EAAE,IAAI;AACvB,YAAA,oBAAoB,EAAE;SACzB;;AAGD,QAAA,IAAI,IAAI,CAAC,SAAS,EAAE;YAChB,aAAa,CAAC,IAAI,GAAG;gBACjB,KAAK,EAAE,IAAI,CAAC;aACf;QACL;QAEA,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC;QAEzC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAK;AAC3B,YAAA,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAC/B,YAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;YACvC,IAAI,CAAC,oBAAoB,EAAE;AAC/B,QAAA,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,EAAE,MAAK;AAC9B,YAAA,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;AAClC,YAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;AAC5C,QAAA,CAAC,CAAC;;;;QAKF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,MAAK;AAC3B,YAAA,IAAI,IAAI,CAAC,gBAAgB,EAAE;AACvB,gBAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;AACjC,gBAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE;YAChC;AACA,YAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI;AAChC,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,MAAK;AAChC,YAAA,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC;AACzC,YAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;AACvC,YAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE;YAC5B,IAAI,CAAC,oBAAoB,EAAE;AAC/B,QAAA,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,GAAG,KAAI;YACpC,OAAO,CAAC,KAAK,CAAC,mBAAmB,EAAE,GAAG,CAAC,OAAO,CAAC;AACnD,QAAA,CAAC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,CAAC,GAAG,KAAI;YACtC,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,OAAO,CAAC;AACrD,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,MAAK;AAC3B,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE;AAC9B,YAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AAClC,QAAA,CAAC,CAAC;;QAGF,IAAI,CAAC,gBAAgB,EAAE;IAC3B;AAEA;;AAEG;IACK,gBAAgB,GAAA;QACpB,IAAI,CAAC,eAAe,EAAE;AAEtB,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE;;AAG9B,QAAA,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,MAAK;AACxC,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;AACzB,gBAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC/B;YACJ;YAEA,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY;;AAExD,YAAA,IAAI,iBAAiB,GAAG,KAAK,EAAE;AAC3B,gBAAA,OAAO,CAAC,IAAI,CAAC,sDAAsD,CAAC;AACpE,gBAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;AAC/B,gBAAA,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;AACxB,gBAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACzB;iBAAO;AACH,gBAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;YAClC;QACJ,CAAC,EAAE,KAAK,CAAC;IACb;IAEQ,eAAe,GAAA;AACnB,QAAA,IAAI,IAAI,CAAC,mBAAmB,EAAE;AAC1B,YAAA,aAAa,CAAC,IAAI,CAAC,mBAAmB,CAAC;AACvC,YAAA,IAAI,CAAC,mBAAmB,GAAG,SAAS;QACxC;IACJ;IAEQ,oBAAoB,GAAA;AACxB,QAAA,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC;QAC/E,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,SAAS,KAAI;;AAE9C,YAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC;;AAE1B,YAAA,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,SAAS,CAAC;YAErC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,KAAI;gBAC/B,OAAO,CAAC,GAAG,CAAC,CAAA,yBAAA,EAA4B,SAAS,CAAA,CAAE,EAAE,IAAI,CAAC;AAC1D,gBAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AACtB,YAAA,CAAC,CAAC;AACN,QAAA,CAAC,CAAC;IACN;AAEA;;AAEG;AACI,IAAA,YAAY,CAAC,KAAa,EAAA;AAC7B,QAAA,IAAI,CAAC,SAAS,GAAG,KAAK;IAC1B;AAEA;;AAEG;AACI,IAAA,gBAAgB,CAAC,GAAW,EAAA;AAC/B,QAAA,IAAI,CAAC,aAAa,GAAG,GAAG;IAC5B;AAEA;;AAEG;AACI,IAAA,iBAAiB,CAAC,KAAc,EAAA;QACnC,IAAI,KAAK,EAAE;AACP,YAAA,IAAI,CAAC,SAAS,GAAG,KAAK;QAC1B;AAEA,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE;AACb,YAAA,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;QAC5B;QAEA,IAAI,CAAC,qBAAqB,EAAE;IAChC;IAEO,OAAO,CAAC,SAAS,GAAG,KAAK,EAAA;;AAE5B,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;AACxB,YAAA,OAAO,OAAO,CAAC,OAAO,EAAE;QAC5B;AAEA,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;AAC3B,YAAA,MAAM,OAAO,GAAG,UAAU,CAAC,MAAK;;;AAG5B,gBAAA,OAAO,CAAC,IAAI,CAAC,uEAAuE,CAAC;AACrF,gBAAA,OAAO,EAAE;YACb,CAAC,EAAE,SAAS,CAAC;YAEb,IAAI,CAAC,qBAAqB,EAAE;AAE5B,YAAA,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;gBACvB,YAAY,CAAC,OAAO,CAAC;AACrB,gBAAA,OAAO,EAAE;gBACT;YACJ;;YAGA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,MAAK;gBAC7B,YAAY,CAAC,OAAO,CAAC;AACrB,gBAAA,OAAO,EAAE;AACb,YAAA,CAAC,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,GAAG,KAAI;;gBAEpC,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,GAAG,CAAC,OAAO,CAAC;AACxD,YAAA,CAAC,CAAC;AAEF,YAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE;AACxB,gBAAA,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;YACzB;AACJ,QAAA,CAAC,CAAC;IACN;IAEO,UAAU,GAAA;QACb,IAAI,CAAC,eAAe,EAAE;AACtB,QAAA,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;AACxB,YAAA,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE;QAC5B;AACA,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;IACnC;AAEA;;AAEG;IACI,IAAI,CAAC,KAAa,EAAE,IAAU,EAAA;QACjC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;AAC1C,YAAA,OAAO,CAAC,IAAI,CAAC,6CAA6C,CAAC;YAC3D;QACJ;;QAGA,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,EAAE;AACtC,YAAA,MAAM,OAAO,GAAG;gBACZ,OAAO,EAAE,IAAI,IAAI,EAAE;AACnB,gBAAA,OAAO,EAAE;AACL,oBAAA,IAAI,IAAI,CAAC,SAAS,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;AACrD,oBAAA,IAAI,IAAI,CAAC,aAAa,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE;AAClE;aACJ;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;QACpC;aAAO;YACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;QACjC;IACJ;AAEA;;AAEG;AACI,IAAA,EAAE,CAAI,KAAa,EAAA;QACtB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;AAChC,YAAA,MAAM,OAAO,GAAG,IAAI,OAAO,EAAK;YAChC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;;AAGtC,YAAA,IAAI,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE;AACxB,gBAAA,OAAO,CAAC,GAAG,CAAC,4CAA4C,KAAK,CAAA,CAAE,CAAC;gBAChE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,IAAO,KAAI;oBAC9B,OAAO,CAAC,GAAG,CAAC,CAAA,yBAAA,EAA4B,KAAK,CAAA,CAAE,EAAE,IAAI,CAAC;AACtD,oBAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;AACtB,gBAAA,CAAC,CAAC;YACN;iBAAO;AACH,gBAAA,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAA,oEAAA,CAAsE,CAAC;YAC9G;QACJ;QAEA,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,YAAY,EAAE;IACxD;AAEA;;;;AAIG;AACI,IAAA,IAAI,CAAI,KAAa,EAAE,SAAS,GAAG,KAAK,EAAA;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;YAC1C,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACnF;QAEA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACnC,YAAA,IAAI,SAAoD;AAExD,YAAA,MAAM,OAAO,GAAG,CAAC,IAAO,KAAI;AACxB,gBAAA,IAAI,SAAS;oBAAE,YAAY,CAAC,SAAS,CAAC;gBACtC,OAAO,CAAC,IAAI,CAAC;AACjB,YAAA,CAAC;AAED,YAAA,IAAI,SAAS,GAAG,CAAC,EAAE;AACf,gBAAA,SAAS,GAAG,UAAU,CAAC,MAAK;oBACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC;oBAC/B,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAA,CAAE,CAAC,CAAC;gBAC5D,CAAC,EAAE,SAAS,CAAC;YACjB;YAEA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC;AACpC,QAAA,CAAC,CAAC;IACN;AA5SS,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,kBAsBV,0BAA0B,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAtB7B,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,aAAa,cAFV,MAAM,EAAA,CAAA;;4FAET,aAAa,EAAA,UAAA,EAAA,CAAA;kBAHzB,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;0BAuBQ,MAAM;2BAAC,0BAA0B;;;MCzDpB,SAAS,CAAA;AAcb,IAAA,aAAA;AAbJ,IAAA,WAAW,GAAG,IAAI,eAAe,CAAM,EAAE,CAAC;AAC7C,IAAA,KAAK,GAAoB,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE;AAErD,IAAA,cAAc,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC;AACvD,IAAA,QAAQ,GAAwB,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE;AAE/D,IAAA,YAAY,GAAG,IAAI,eAAe,CAAgB,IAAI,CAAC;AAC1D,IAAA,MAAM,GAA8B,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE;AAE1D,IAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ;IACvC,iBAAiB,GAAG,KAAK;AAEjC,IAAA,WAAA,CACc,aAA4B,EAAA;QAA5B,IAAA,CAAA,aAAa,GAAb,aAAa;;QAGvB,cAAc,CAAC,MAAK;YAChB,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,MAAK,EAAG,CAAC,CAAC;AACrC,QAAA,CAAC,CAAC;IACN;AAEQ,IAAA,MAAM,UAAU,GAAA;QACpB,IAAI,CAAC,wBAAwB,EAAE;QAC/B,IAAI,CAAC,OAAO,EAAE;;;;AAKd,QAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CACrC,QAAQ,EAAE,EACV,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,CAAC;QACzD,SAAS,CAAC,MACN,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,IAAI,CACrC,MAAM,CAAC,SAAS,IAAI,SAAS,CAAC;QAC9B,KAAK,EAAE,CACV,CACJ,EACD,YAAY,CAAC,IAAI,CAAC;QAClB,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC3B,CAAC,SAAS,CAAC,MAAK;YACb,IAAI,CAAC,OAAO,EAAE;AAClB,QAAA,CAAC,CAAC;IACN;IAEO,OAAO,GAAA;;AAEV,QAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE;YACxB;QACJ;AACA,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC7B,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAErB,IAAI,CAAC,OAAO;AACP,aAAA,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;aAClC,KAAK,CAAC,GAAG,IAAG;AACT,YAAA,OAAO,CAAC,KAAK,CAAC,CAAA,CAAA,EAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAA,iBAAA,CAAmB,EAAE,GAAG,CAAC;YAChE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,IAAI,qBAAqB,CAAC;AACvD,QAAA,CAAC;aACA,OAAO,CAAC,MAAK;AACV,YAAA,IAAI,CAAC,iBAAiB,GAAG,KAAK;AAC9B,YAAA,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;AAC1B,QAAA,CAAC,CAAC;IACV;AAEA;;AAEG;IACI,OAAO,GAAA;AACV,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;AACpB,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;IAC5B;;AAQU,IAAA,WAAW,CAAC,KAAU,EAAA;AAC5B,QAAA,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC;AAE7B,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;IAChC;AAEU,IAAA,UAAU,CAAC,WAAuC,EAAA;AACxD,QAAA,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC;AAErC,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK;QAC3C,MAAM,OAAO,GAAG,IAAe;QAE/B,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,CAChC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,OAAO,CAAC,CACjD;AAED,QAAA,IAAI,YAAiB;AAErB,QAAA,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE;;AAEZ,YAAA,YAAY,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KACpC,CAAC,KAAK,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,WAAW,EAAO,GAAG,IAAI,CACxD;QACL;aAAO;;AAEH,YAAA,YAAY,GAAG,CAAC,GAAG,YAAY,EAAE,WAAgB,CAAC;QACtD;AAEA,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC;IACvC;AAGU,IAAA,UAAU,CAAC,EAAU,EAAA;AAC3B,QAAA,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC;AAE3B,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK;QAC3C,MAAM,OAAO,GAAG,IAAe;AAC/B,QAAA,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;AACvE,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC;IACxC;AAEU,IAAA,UAAU,CAAC,SAAkB,EAAA;AACnC,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,CAAC;IACvC;AAEU,IAAA,QAAQ,CAAC,KAAoB,EAAA;AACnC,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;IACjC;;IAGU,gBAAgB,CACtB,KAAa,EACb,OAA0B,EAAA;AAE1B,QAAA,IAAI,CAAC,aAAa,CAAC,EAAE,CAAI,KAAK,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC;IACtD;IAEA,MAAM,GAAA;AACF,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK;IACjC;AAEA,IAAA,OAAO,CAAC,EAAU,EAAA;QACd,MAAM,KAAK,GAAG,IAAe;AAC7B,QAAA,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IAClE;AAEA,IAAA,QAAQ,CAAC,EAAU,EAAA;QACf,MAAM,KAAK,GAAG,IAAe;AAC7B,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAClB,GAAG,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CACvD;IACL;AACH;;ACjJK,MAAgB,UAA6B,SAAQ,SAAY,CAAA;AAU5C,IAAA,aAAA;;AARf,IAAA,0BAA0B,GAAG,IAAI,eAAe,CAAuB,EAAE,CAAC;AAC3E,IAAA,oBAAoB,GAAG,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE;;AAGpE,IAAA,eAAe,GAAG,IAAI,OAAO,EAAQ;AACtC,IAAA,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE;AAEtD,IAAA,WAAA,CACuB,aAA4B,EAAA;QAE/C,KAAK,CAAC,aAAa,CAAC;QAFD,IAAA,CAAA,aAAa,GAAb,aAAa;IAGpC;IACmB,wBAAwB,GAAA;AACvC,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,wBAAwB,EAC/C,CAAC,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CACpC;AAED,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,cAAc,EACrC,CAAC,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CACxC;QAED,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,kCAAkC,EACzD,CAAC,MAAM,KAAI;YACP,IAAI,MAAM,EAAE;AACR,gBAAA,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE;YAC/B;AACJ,QAAA,CAAC,CACJ;;QAGD,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,+BAA+B,EACtD,CAAC,OAAO,KAAI;AACR,YAAA,OAAO,CAAC,GAAG,CAAC,8CAA8C,EAAE,OAAO,CAAC;AACpE,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK;;AAErD,YAAA,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,EAAE;AACzC,gBAAA,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/D;AACJ,QAAA,CAAC,CACJ;IACL;;AAGO,IAAA,wBAAwB,CAAC,UAAkB,EAAA;AAC9C,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK;QACrD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IAClF;;IAGO,wBAAwB,GAAA;AAC3B,QAAA,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;IAC5C;wGAzDkB,UAAU,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAV,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAU,cAFhB,MAAM,EAAA,CAAA;;4FAEA,UAAU,EAAA,UAAA,EAAA,CAAA;kBAH/B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACNK,MAAgB,SAA4B,SAAQ,SAAY,CAAA;AAE3C,IAAA,aAAA;AADvB,IAAA,WAAA,CACuB,aAA4B,EAAA;QAE/C,KAAK,CAAC,aAAa,CAAC;QAFD,IAAA,CAAA,aAAa,GAAb,aAAa;IAGpC;IAEmB,wBAAwB,GAAA;AACvC,QAAA,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,2DAA2D,EAAE,sBAAsB,CAAC,sCAAsC,CAAC;QAEvI,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,sCAAsC,EAC7D,CAAC,IAAI,KAAI;AACL,YAAA,OAAO,CAAC,GAAG,CAAC,yEAAyE,EAAE,IAAI,CAAC;AAC5F,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;AAE5C,QAAA,CAAC,CACJ;QAED,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,iCAAiC,EACxD,CAAC,MAAM,KAAI;AACP,YAAA,OAAO,CAAC,GAAG,CAAC,oEAAoE,EAAE,MAAM,CAAC;AACzF,YAAA,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;AAC5C,QAAA,CAAC,CACJ;IACL;wGA7BkB,SAAS,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAT,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,SAAS,cAFf,MAAM,EAAA,CAAA;;4FAEA,SAAS,EAAA,UAAA,EAAA,CAAA;kBAH9B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACCK,MAAgB,eAAkC,SAAQ,SAAY,CAAA;AAEjD,IAAA,aAAA;AADvB,IAAA,WAAA,CACuB,aAA4B,EAAA;QAE/C,KAAK,CAAC,aAAa,CAAC;QAFD,IAAA,CAAA,aAAa,GAAb,aAAa;IAGpC;IAEmB,wBAAwB,GAAA;AACvC,QAAA,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC;AAChE,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,2BAA2B,EAClD,CAAC,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CACxC;IACL;wGAbkB,eAAe,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAf,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,eAAe,cAFrB,MAAM,EAAA,CAAA;;4FAEA,eAAe,EAAA,UAAA,EAAA,CAAA;kBAHpC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;MCuBY,iBAAiB,CAAA;AAWZ,IAAA,aAAA;AACO,IAAA,MAAA;AAXJ,IAAA,cAAc,GAAG;AAC9B,QAAA,WAAW,EAAE,IAAI;AACjB,QAAA,WAAW,EAAE;KAChB;;AAGO,IAAA,uBAAuB,GAAG,IAAI,eAAe,CAAoB,EAAE,CAAC;AACrE,IAAA,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE;IAEtE,WAAA,CACc,aAA4B,EACrB,MAAqB,EAAA;QAD5B,IAAA,CAAA,aAAa,GAAb,aAAa;QACN,IAAA,CAAA,MAAM,GAAN,MAAM;QAEvB,IAAI,CAAC,wBAAwB,EAAE;QAE/B,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;YACzC,IAAI,CAAC,wBAAwB,EAAE;AACnC,QAAA,CAAC,CAAC;IACN;IAEQ,wBAAwB,GAAA;;QAE5B,IAAI,CAAC,aAAa,CAAC,EAAE,CAAsB,sBAAsB,CAAC,qBAAqB;AAClF,aAAA,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;QAGtD,IAAI,CAAC,aAAa,CAAC,EAAE,CAAsB,sBAAsB,CAAC,uBAAuB;AACpF,aAAA,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;QAGxD,IAAI,CAAC,aAAa,CAAC,EAAE,CAAsB,sBAAsB,CAAC,uBAAuB;AACpF,aAAA,SAAS,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;QAGxD,IAAI,CAAC,aAAa,CAAC,EAAE,CAAgB,sBAAsB,CAAC,sCAAsC;AAC7F,aAAA,SAAS,CAAC,CAAC,IAAI,KAAI;AAChB,YAAA,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,IAAI,CAAC;;YAGtD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,IAAI,EAAE;AAEtF,YAAA,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;;AAE1B,gBAAA,MAAM,YAAY,GAAG,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU;AACnE,gBAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC;YAC7C;;AAEJ,QAAA,CAAC,CAAC;;QAGN,IAAI,CAAC,aAAa,CAAC,EAAE,CAAS,sBAAsB,CAAC,iCAAiC;AACjF,aAAA,SAAS,CAAC,CAAC,MAAM,KAAI;AAClB,YAAA,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC;AAC5D,QAAA,CAAC,CAAC;IACV;AAEA;;AAEG;IACK,gBAAgB,CAAC,IAAmB,EAAE,YAAoB,EAAA;AAC9D,QAAA,OAAO,CAAC,GAAG,CAAC,2CAA2C,EAAE,IAAI,CAAC;;QAG9D,IAAI,CAAC,aAAa,EAAE;;AAGpB,QAAA,MAAM,KAAK,GAAoB;YAC3B,EAAE,EAAE,CAAA,EAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAA,CAAE;YAC9B,MAAM,EAAE,IAAI,CAAC,EAAE;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,YAAY;YACZ,SAAS,EAAE,IAAI,IAAI;SACtB;AAED,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK;AACxD,QAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,GAAG,aAAa,CAAC,CAAC;;QAG5D,IAAI,CAAC,MAAM,CAAC,OAAO,CACf,mBAAmB,YAAY,CAAA,CAAE,EACjC,kBAAkB,EAClB;YACI,GAAG,IAAI,CAAC,cAAc;YACtB,OAAO,EAAE,CAAC;AACV,YAAA,eAAe,EAAE,CAAC;AAClB,YAAA,YAAY,EAAE;AACjB,SAAA,CACJ;IACL;AAEA;;AAEG;IACK,aAAa,GAAA;AACjB,QAAA,IAAI;AACA,YAAA,IAAI,SAAS,IAAI,SAAS,EAAE;;AAExB,gBAAA,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAChD;QACJ;QAAE,OAAO,CAAC,EAAE;AACR,YAAA,OAAO,CAAC,IAAI,CAAC,6CAA6C,EAAE,CAAC,CAAC;QAClE;IACJ;AAEA;;AAEG;AACI,IAAA,sBAAsB,CAAC,OAAe,EAAA;AACzC,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK;QACxD,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IAClF;AAEA;;AAEG;IACI,0BAA0B,GAAA;AAC7B,QAAA,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;IACzC;;AAGO,IAAA,SAAS,CAAC,OAAe,EAAE,QAAgB,OAAO,EAAE,UAAkB,IAAI,EAAA;QAC7E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE;YAC9B,GAAG,IAAI,CAAC,cAAc;YACtB;AACH,SAAA,CAAC;IACN;AAEO,IAAA,WAAW,CAAC,OAAe,EAAE,QAAgB,SAAS,EAAE,UAAkB,IAAI,EAAA;QACjF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE;YAChC,GAAG,IAAI,CAAC,cAAc;YACtB;AACH,SAAA,CAAC;IACN;AAEO,IAAA,WAAW,CAAC,OAAe,EAAE,QAAgB,SAAS,EAAE,UAAkB,IAAI,EAAA;QACjF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE;YAChC,GAAG,IAAI,CAAC,cAAc;YACtB;AACH,SAAA,CAAC;IACN;AAEO,IAAA,QAAQ,CAAC,OAAe,EAAE,QAAgB,MAAM,EAAE,UAAkB,IAAI,EAAA;QAC3E,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE;YAC7B,GAAG,IAAI,CAAC,cAAc;YACtB;AACH,SAAA,CAAC;IACN;;IAGO,QAAQ,GAAA;AACX,QAAA,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;IACvB;;AAGO,IAAA,MAAM,CAAC,OAAe,EAAA;AACzB,QAAA,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IAC/B;wGA7JS,iBAAiB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAjB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cAFd,MAAM,EAAA,CAAA;;4FAET,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAH7B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACZK,MAAgB,kBAAqC,SAAQ,SAAY,CAAA;AAKpD,IAAA,aAAA;AAJf,IAAA,qBAAqB,GAAG,IAAI,eAAe,CAA0B,IAAI,CAAC;AAC3E,IAAA,eAAe,GAAG,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE;AAElE,IAAA,WAAA,CACuB,aAA4B,EAAA;QAE/C,KAAK,CAAC,aAAa,CAAC;QAFD,IAAA,CAAA,aAAa,GAAb,aAAa;IAGpC;IAEmB,wBAAwB,GAAA;AACvC,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,kBAAkB,EACzC,CAAC,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CACpC;AAED,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,oBAAoB,EAC3C,CAAC,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CACpC;QAED,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,uBAAuB,EAC9C,CAAC,QAAQ,KAAK,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC1D;IACL;wGAzBkB,kBAAkB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAlB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,kBAAkB,cAFxB,MAAM,EAAA,CAAA;;4FAEA,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAHvC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACRK,MAAgB,gBAAmC,SAAQ,SAAY,CAAA;AAElD,IAAA,aAAA;AADvB,IAAA,WAAA,CACuB,aAA4B,EAAA;QAE/C,KAAK,CAAC,aAAa,CAAC;QAFD,IAAA,CAAA,aAAa,GAAb,aAAa;IAGpC;IAEmB,wBAAwB,GAAA;AACvC,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,oCAAoC,EAC3D,CAAC,WAAW,KAAK,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAChD;AAED,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,0BAA0B,EACjD,CAAC,aAAa,KAAK,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,CACpD;IACL;wGAjBkB,gBAAgB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,cAFtB,MAAM,EAAA,CAAA;;4FAEA,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAHrC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACgBK,MAAgB,cAAiC,SAAQ,SAAY,CAAA;AAQhD,IAAA,aAAA;AAPN,IAAA,oBAAoB,GAAG,IAAI,eAAe,CAAgC,IAAI,CAAC;AACzF,IAAA,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE;AAE/C,IAAA,0BAA0B,GAAG,IAAI,eAAe,CAAsC,IAAI,CAAC;AACrG,IAAA,oBAAoB,GAAG,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE;AAE5E,IAAA,WAAA,CACuB,aAA4B,EAAA;QAE/C,KAAK,CAAC,aAAa,CAAC;QAFD,IAAA,CAAA,aAAa,GAAb,aAAa;IAGpC;IAEmB,wBAAwB,GAAA;AACvC,QAAA,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,uBAAuB,EAC9C,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAClC;QAED,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,yBAAyB,EAChD,CAAC,KAAK,KAAK,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CACnD;QAED,IAAI,CAAC,gBAAgB,CACjB,sBAAsB,CAAC,gCAAgC,EACvD,CAAC,MAAM,KAAK,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,CAC3D;IACL;wGA5BkB,cAAc,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAAd,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,cAAc,cAFpB,MAAM,EAAA,CAAA;;4FAEA,cAAc,EAAA,UAAA,EAAA,CAAA;kBAHnC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;AClBD;;;;;;;;;;;;AAYG;SACa,oBAAoB,GAAA;IAChC,OAAO;QACH,iBAAiB,CAAC,sBAAsB,EAAE;KAC7C;AACL;;ACjBM,SAAU,+BAA+B,CAAC,WAAqC,EAAA;IACjF,OAAO;AACH,QAAA,OAAO,EAAE,0BAA0B;AACnC,QAAA,QAAQ,EAAE;KACb;AACL;;ACJA;;;;;;;AAOG;MAIU,6BAA6B,CAAA;AAIT,IAAA,aAAA;IAHZ,SAAS,GAAG,cAAc;AACnC,IAAA,qBAAqB;AAE7B,IAAA,WAAA,CAA6B,aAA4B,EAAA;QAA5B,IAAA,CAAA,aAAa,GAAb,aAAa;IAAkB;;AAG5D,IAAA,OAAO,CAAC,KAAa,EAAA;QACjB,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC;AAC3C,QAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC3C,QAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IACpC;;IAGA,kBAAkB,GAAA;QACd,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAClD,IAAI,KAAK,EAAE;AACP,YAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC3C,YAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;QACpC;IACJ;IAEA,UAAU,GAAA;AACN,QAAA,IAAI,CAAC,qBAAqB,EAAE,WAAW,EAAE;AACzC,QAAA,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;IACnC;AAEQ,IAAA,oBAAoB,CAAC,KAAa,EAAA;AACtC,QAAA,IAAI,CAAC,qBAAqB,EAAE,WAAW,EAAE;AACzC,QAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AACtE,YAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC/C,QAAA,CAAC,CAAC;IACN;wGAhCS,6BAA6B,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAA7B,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,6BAA6B,cAF1B,MAAM,EAAA,CAAA;;4FAET,6BAA6B,EAAA,UAAA,EAAA,CAAA;kBAHzC,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACVD;;;;;;;AAOG;MAIU,qCAAqC,CAAA;AAIjB,IAAA,aAAA;IAHZ,SAAS,GAAG,uBAAuB;AAC5C,IAAA,qBAAqB;AAE7B,IAAA,WAAA,CAA6B,aAA4B,EAAA;QAA5B,IAAA,CAAA,aAAa,GAAb,aAAa;IAAkB;;AAG5D,IAAA,OAAO,CAAC,KAAa,EAAA;AACjB,QAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC3C,QAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IACpC;;IAGA,kBAAkB,GAAA;QACd,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAClD,IAAI,KAAK,EAAE;AACP,YAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC3C,YAAA,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;QACpC;IACJ;IAEA,UAAU,GAAA;AACN,QAAA,IAAI,CAAC,qBAAqB,EAAE,WAAW,EAAE;AACzC,QAAA,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE;IACnC;AAEQ,IAAA,oBAAoB,CAAC,KAAa,EAAA;AACtC,QAAA,IAAI,CAAC,qBAAqB,EAAE,WAAW,EAAE;AACzC,QAAA,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC,MAAK;AACtE,YAAA,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC;AAC/C,QAAA,CAAC,CAAC;IACN;wGA/BS,qCAAqC,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA;AAArC,IAAA,OAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,qCAAqC,cAFlC,MAAM,EAAA,CAAA;;4FAET,qCAAqC,EAAA,UAAA,EAAA,CAAA;kBAHjD,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,UAAU,EAAE;AACf,iBAAA;;;ACdD;;AAEG;;ACFH;;AAEG;;;;"}
1
+ {"version":3,"file":"serve-socket.mjs","sources":["../../../projects/serve-socket/src/lib/realtime-store.module.ts","../../../projects/serve-socket/src/lib/environment/realtime-store-environment.interface.ts","../../../projects/serve-socket/src/lib/environment/realtime-store-environment.token.ts","../../../projects/serve-socket/src/lib/socket.service.ts","../../../projects/serve-socket/src/lib/base-store.ts","../../../projects/serve-socket/src/lib/stores/table.store.ts","../../../projects/serve-socket/src/lib/stores/cart.store.ts","../../../projects/serve-socket/src/lib/stores/call-waiter.store.ts","../../../projects/serve-socket/src/lib/stores/notification.store.ts","../../../projects/serve-socket/src/lib/stores/delivery-order.store.ts","../../../projects/serve-socket/src/lib/stores/reservation.store.ts","../../../projects/serve-socket/src/lib/stores/inventory.store.ts","../../../projects/serve-socket/src/lib/providers.ts","../../../projects/serve-socket/src/lib/providers/realtime-store-environment.provider.ts","../../../projects/serve-socket/src/lib/driver-socket-connection.service.ts","../../../projects/serve-socket/src/lib/online-customer-socket-connection.service.ts","../../../projects/serve-socket/src/public-api.ts","../../../projects/serve-socket/src/serve-socket.ts"],"sourcesContent":["import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { HttpClientModule } from '@angular/common/http';\n\n/**\n * @deprecated Use provideRealtimeStore() with standalone components instead\n */\n@NgModule({\n declarations: [],\n imports: [\n CommonModule,\n HttpClientModule // Kept for backward compatibility with Angular <14\n ],\n exports: []\n})\nexport class RealtimeStoreModule { }\n","import { SocketSuccessEventKeys } from '../socket.service';\n\nexport interface RealtimeStoreEnvironment {\n apiUrl: string;\n /**\n * WebSocket URL for the MQTT broker (e.g. ws://localhost:9001 or wss://broker.example.com:8883).\n * If omitted, derived from apiUrl by replacing http → ws / https → wss.\n */\n mqttUrl?: string;\n}\n\nexport const defaultRealtimeStoreEnvironment: RealtimeStoreEnvironment = {\n apiUrl: `http://${window.location.hostname}:3030`,\n};","import { InjectionToken } from '@angular/core';\nimport { RealtimeStoreEnvironment } from './realtime-store-environment.interface';\n\nexport const REALTIME_STORE_ENVIRONMENT = new InjectionToken<RealtimeStoreEnvironment>('REALTIME_STORE_ENVIRONMENT');","import { Injectable, Inject } from '@angular/core';\nimport { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport { connect, MqttClient, IClientOptions } from 'mqtt';\nimport { REALTIME_STORE_ENVIRONMENT, RealtimeStoreEnvironment, defaultRealtimeStoreEnvironment } from './environment';\n\nexport enum SocketSuccessEventKeys {\n CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS = 'CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS',\n CUSTOMER_REMOVE_FROM_CART_SUCCESS = 'CUSTOMER_REMOVE_FROM_CART_SUCCESS',\n TABLE_JOIN_REQUEST_SENT_SUCCESS = 'TABLE_JOIN_REQUEST_SENT_SUCCESS',\n TABLE_CREATED_OR_UPDATED = 'TABLE_CREATED_OR_UPDATED',\n TABLE_RELEASED = 'TABLE_RELEASED',\n HOST_JOIN_REQUEST_APPROVED_SUCCESS = 'HOST_JOIN_REQUEST_APPROVED_SUCCESS',\n HOST_JOIN_REQUEST_DECLINED = 'HOST_JOIN_REQUEST_DECLINED',\n WAITER_CALL_CREATED_SUCCESS = 'WAITER_CALL_CREATED_SUCCESS',\n WAITER_CALL_ACKNOWLEDGED_SUCCESS = 'WAITER_CALL_ACKNOWLEDGED_SUCCESS',\n ERROR_MESSAGE_SUCCESS = 'ERROR_MESSAGE_SUCCESS',\n SUCCESS_MESSAGE_SUCCESS = 'SUCCESS_MESSAGE_SUCCESS',\n WARNING_MESSAGE_SUCCESS = 'WARNING_MESSAGE_SUCCESS',\n // Delivery\n NEW_DELIVERY_ORDER = 'NEW_DELIVERY_ORDER',\n ORDER_STATUS_UPDATED = 'ORDER_STATUS_UPDATED',\n DRIVER_LOCATION_UPDATED = 'DRIVER_LOCATION_UPDATED',\n // Reservations\n RESERVATION_CREATE_OR_UPDATE_SUCCESS = 'RESERVATION_CREATE_OR_UPDATE_SUCCESS',\n RESERVATION_REMOVE_SUCCESS = 'RESERVATION_REMOVE_SUCCESS',\n // Inventory\n INVENTORY_STOCK_UPDATED = 'INVENTORY_STOCK_UPDATED',\n INVENTORY_LOW_STOCK_ALERT = 'INVENTORY_LOW_STOCK_ALERT',\n INVENTORY_PURCHASE_ORDER_UPDATED = 'INVENTORY_PURCHASE_ORDER_UPDATED',\n // Billing\n BILLING_SUBSCRIPTION_UPDATED = 'BILLING_SUBSCRIPTION_UPDATED',\n BILLING_INVOICE_ISSUED = 'BILLING_INVOICE_ISSUED',\n BILLING_PAYMENT_RECEIVED = 'BILLING_PAYMENT_RECEIVED',\n BILLING_TRIAL_EXPIRING = 'BILLING_TRIAL_EXPIRING',\n BILLING_INVOICE_OVERDUE = 'BILLING_INVOICE_OVERDUE',\n BILLING_SUBSCRIPTION_SUSPENDED = 'BILLING_SUBSCRIPTION_SUSPENDED',\n BILLING_CREDIT_NOTE_ISSUED = 'BILLING_CREDIT_NOTE_ISSUED',\n BILLING_REFUND_PROCESSED = 'BILLING_REFUND_PROCESSED',\n}\n\n/**\n * Topic convention (mirrors server messenger.gateway.ts):\n * Server → user: serve-plus/user/{userId}/{event}\n * Server → room: serve-plus/room/{roomId}/{event}\n * Client → server: serve-plus/client/{userId}/{action} (payload = raw JWT string)\n *\n * System events handled internally (not forwarded to event subjects):\n * JOIN_ROOM { roomId: string } — subscribe to serve-plus/room/{roomId}/#\n * LEAVE_ROOM { roomId: string } — unsubscribe from serve-plus/room/{roomId}/#\n * FORCE_DISCONNECT {} — disconnect\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class SocketService {\n private mqttClient?: MqttClient;\n private authToken?: string;\n private connectionKey?: string;\n private userId?: string;\n private readonly eventSubjects = new Map<string, Subject<unknown>>();\n private readonly subscribedRooms = new Set<string>();\n\n private readonly connectionStatusSubject = new BehaviorSubject<boolean>(false);\n public connectionStatus$ = this.connectionStatusSubject.asObservable();\n\n private readonly reconnectSubject = new Subject<void>();\n public reconnect$ = this.reconnectSubject.asObservable();\n\n private hasConnectedOnce = false;\n\n private readonly healthySubject = new BehaviorSubject<boolean>(false);\n public healthy$ = this.healthySubject.asObservable();\n\n private readonly TOPIC_PREFIX = 'serve-plus';\n\n constructor(\n @Inject(REALTIME_STORE_ENVIRONMENT) private readonly environment: RealtimeStoreEnvironment = defaultRealtimeStoreEnvironment\n ) {}\n\n private decodeUserId(token: string): string | undefined {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return undefined;\n const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));\n return (payload.id ?? payload.sub) as string | undefined;\n } catch {\n return undefined;\n }\n }\n\n private resolveBrokerUrl(): string {\n if (this.environment.mqttUrl) {\n return this.environment.mqttUrl;\n }\n // Derive WebSocket MQTT URL from API URL\n return this.environment.apiUrl\n .replace(/^https/, 'wss')\n .replace(/^http/, 'ws');\n }\n\n private setupConnection(): void {\n if (this.mqttClient) {\n this.mqttClient.removeAllListeners();\n this.mqttClient.end(true);\n }\n\n if (!this.authToken) {\n console.warn('[MQTT] No auth token — cannot connect');\n return;\n }\n\n this.userId = this.decodeUserId(this.authToken);\n if (!this.userId) {\n console.warn('[MQTT] Could not decode user ID from token');\n return;\n }\n\n const options: IClientOptions = {\n username: this.userId,\n password: this.authToken,\n clean: true,\n reconnectPeriod: 5000,\n connectTimeout: 15000,\n };\n\n this.mqttClient = connect(this.resolveBrokerUrl(), options);\n\n this.mqttClient.on('connect', () => {\n console.log(this.hasConnectedOnce ? '[MQTT] Reconnected' : '[MQTT] Connected');\n this.connectionStatusSubject.next(true);\n this.healthySubject.next(true);\n\n // Subscribe to personal user topic for all events and system commands\n this.mqttClient!.subscribe(`${this.TOPIC_PREFIX}/user/${this.userId}/#`, { qos: 1 });\n\n // Re-subscribe to all previously joined rooms\n this.subscribedRooms.forEach(roomId => {\n this.mqttClient!.subscribe(`${this.TOPIC_PREFIX}/room/${roomId}/#`, { qos: 1 });\n });\n\n if (this.hasConnectedOnce) {\n this.reconnectSubject.next();\n }\n this.hasConnectedOnce = true;\n });\n\n this.mqttClient.on('message', (topic: string, message: Buffer) => {\n try {\n const payload = JSON.parse(message.toString()) as unknown;\n const parts = topic.split('/');\n const event = parts[parts.length - 1];\n\n // Handle server-sent system events\n if (event === 'JOIN_ROOM') {\n const { roomId } = payload as { roomId: string };\n this.subscribeToRoom(roomId);\n return;\n }\n if (event === 'LEAVE_ROOM') {\n const { roomId } = payload as { roomId: string };\n this.unsubscribeFromRoom(roomId);\n return;\n }\n if (event === 'FORCE_DISCONNECT') {\n this.disconnect();\n return;\n }\n\n // Dispatch to registered event subjects\n const subject = this.eventSubjects.get(event);\n if (subject) {\n console.log(`[MQTT] Event received: ${event}`, payload);\n subject.next(payload);\n }\n } catch (err) {\n console.error(`[MQTT] Failed to parse message from topic ${topic}:`, err);\n }\n });\n\n this.mqttClient.on('disconnect', () => {\n console.log('[MQTT] Disconnected');\n this.connectionStatusSubject.next(false);\n this.healthySubject.next(false);\n });\n\n this.mqttClient.on('error', (err: Error) => {\n console.error('[MQTT] Connection error:', err.message);\n });\n\n this.mqttClient.on('reconnect', () => {\n console.log('[MQTT] Reconnecting...');\n });\n }\n\n private subscribeToRoom(roomId: string): void {\n this.subscribedRooms.add(roomId);\n if (this.mqttClient?.connected) {\n this.mqttClient.subscribe(`${this.TOPIC_PREFIX}/room/${roomId}/#`, { qos: 1 }, (err) => {\n if (err) {\n console.error(`[MQTT] Failed to subscribe to room ${roomId}:`, err.message);\n } else {\n console.log(`[MQTT] Subscribed to room: ${roomId}`);\n }\n });\n }\n }\n\n private unsubscribeFromRoom(roomId: string): void {\n this.subscribedRooms.delete(roomId);\n if (this.mqttClient?.connected) {\n this.mqttClient.unsubscribe(`${this.TOPIC_PREFIX}/room/${roomId}/#`);\n }\n }\n\n /**\n * Set authentication token for MQTT connection.\n * Call connect() afterwards to open the connection.\n */\n public setAuthToken(token: string): void {\n this.authToken = token;\n }\n\n /**\n * Set connection key included in outbound message headers.\n */\n public setConnectionKey(key: string): void {\n this.connectionKey = key;\n }\n\n /**\n * Reset connection with new token.\n * Idempotent: no-op if the same token is already active and connected.\n */\n public resetWithNewToken(token?: string): void {\n const tokenUnchanged = !token || token === this.authToken;\n const clientActive = this.mqttClient?.connected;\n if (tokenUnchanged && clientActive) {\n return;\n }\n if (token) {\n this.authToken = token;\n }\n this.setupConnection();\n }\n\n public connect(timeoutMs = 15000): Promise<void> {\n if (this.mqttClient?.connected) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n console.warn('[MQTT] Connection timeout — client will keep retrying in background');\n resolve();\n }, timeoutMs);\n\n if (!this.mqttClient) {\n this.setupConnection();\n }\n\n if (this.mqttClient?.connected) {\n clearTimeout(timeout);\n resolve();\n return;\n }\n\n this.mqttClient?.once('connect', () => {\n clearTimeout(timeout);\n resolve();\n });\n });\n }\n\n public disconnect(): void {\n if (this.mqttClient?.connected) {\n this.mqttClient.end();\n }\n this.subscribedRooms.clear();\n this.connectionStatusSubject.next(false);\n this.healthySubject.next(false);\n }\n\n /**\n * Emit an event to the server (client → server).\n * Publishes to serve-plus/client/{userId}/{event}.\n */\n public emit(event: string, data?: unknown): void {\n if (!this.mqttClient?.connected || !this.userId) {\n console.warn('[MQTT] Not connected or no user ID. Call connect() first.');\n return;\n }\n\n const payload = {\n payload: data ?? {},\n headers: {\n ...(this.authToken && { _authToken: this.authToken }),\n ...(this.connectionKey && { connectionKey: this.connectionKey }),\n },\n };\n\n this.mqttClient.publish(\n `${this.TOPIC_PREFIX}/client/${this.userId}/${event}`,\n JSON.stringify(payload),\n { qos: 1 },\n );\n }\n\n /**\n * Listen to server-sent events. Returns a persistent Observable that\n * survives reconnections (matching the previous socket.io behaviour).\n */\n public on<T>(event: string): Observable<T> {\n if (!this.eventSubjects.has(event)) {\n this.eventSubjects.set(event, new Subject<unknown>());\n console.log(`[MQTT] Registered listener for event: ${event}`);\n }\n return (this.eventSubjects.get(event) as Subject<T>).asObservable();\n }\n\n /**\n * Listen for a single event occurrence and return as a Promise.\n */\n public once<T>(event: string, timeoutMs = 30000): Promise<T> {\n if (!this.mqttClient?.connected) {\n return Promise.reject(new Error('[MQTT] Not connected. Call connect() first.'));\n }\n\n return new Promise((resolve, reject) => {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const subscription = this.on<T>(event).subscribe((data) => {\n if (timeoutId) clearTimeout(timeoutId);\n subscription.unsubscribe();\n resolve(data);\n });\n\n if (timeoutMs > 0) {\n timeoutId = setTimeout(() => {\n subscription.unsubscribe();\n reject(new Error(`[MQTT] Timeout waiting for event: ${event}`));\n }, timeoutMs);\n }\n });\n }\n}\n\n","import { BehaviorSubject, filter, map, Observable, Subject, Subscription, switchMap } from 'rxjs';\nimport { debounceTime, first, pairwise, takeUntil } from 'rxjs/operators';\nimport { SocketService } from './socket.service';\n\nexport interface Entity {\n id?: string;\n}\n\nexport abstract class BaseStore<T extends Entity> {\n protected dataSubject = new BehaviorSubject<T[]>([]);\n public data$: Observable<T[]> = this.dataSubject.asObservable();\n\n protected loadingSubject = new BehaviorSubject<boolean>(false);\n public loading$: Observable<boolean> = this.loadingSubject.asObservable();\n\n protected errorSubject = new BehaviorSubject<string | null>(null);\n public error$: Observable<string | null> = this.errorSubject.asObservable();\n\n private readonly destroy$ = new Subject<void>();\n private refreshInProgress = false;\n\n constructor(\n protected socketService: SocketService\n ) {\n // Defer initialization to allow child class constructor parameters to be assigned\n queueMicrotask(() => {\n this.initialize().then(() => { });\n });\n }\n\n private async initialize(): Promise<void> {\n this.setupSocketSubscriptions();\n this.refresh();\n\n // Reload data after a disconnect → reconnect cycle.\n // Listening to connectionStatus$ is more reliable than reconnect$ because\n // connectionStatus$ is driven directly by socket connect/disconnect events.\n this.socketService.connectionStatus$.pipe(\n pairwise(),\n filter(([prev, curr]) => prev === true && curr === false), // detect disconnect\n switchMap(() =>\n this.socketService.connectionStatus$.pipe(\n filter(connected => connected), // wait for next reconnect\n first()\n )\n ),\n debounceTime(1000), // give server time to be fully ready\n takeUntil(this.destroy$)\n ).subscribe(() => {\n this.refresh();\n });\n }\n\n public refresh() {\n // Prevent concurrent refresh calls\n if (this.refreshInProgress) {\n return;\n }\n this.refreshInProgress = true;\n this.setLoading(true);\n\n this.preload()\n .then(x => this.dataSubject.next(x))\n .catch(err => {\n console.error(`[${this.constructor.name}] Preload failed:`, err);\n this.setError(err.message || 'Failed to load data');\n })\n .finally(() => {\n this.refreshInProgress = false;\n this.setLoading(false);\n });\n }\n\n /**\n * Clean up subscriptions when store is destroyed\n */\n public destroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // Abstract methods to be implemented by specific stores\n public abstract preload(): Promise<T[]>;\n\n protected abstract setupSocketSubscriptions(): void;\n\n // Helper methods for stores\n protected updateItems(items: T[]): void {\n console.log('setting', items);\n\n this.dataSubject.next(items);\n }\n\n protected updateItem(updatedItem: Partial<T> & Pick<T, 'id'>): void {\n console.log('upserting', updatedItem);\n\n const currentItems = this.dataSubject.value;\n const idField = 'id' as keyof T;\n\n const index = currentItems.findIndex(\n item => item[idField] === updatedItem[idField]\n );\n\n let updatedItems: T[];\n\n if (index > -1) {\n // 🔁 Update existing item\n updatedItems = currentItems.map((item, i) =>\n i === index ? { ...item, ...updatedItem } as T : item\n );\n } else {\n // ➕ Add new item\n updatedItems = [...currentItems, updatedItem as T];\n }\n\n this.dataSubject.next(updatedItems);\n }\n\n\n protected removeItem(id: string): void {\n console.log('removing', id);\n\n const currentItems = this.dataSubject.value;\n const idField = 'id' as keyof T;\n const filteredItems = currentItems.filter(item => item[idField] !== id);\n this.dataSubject.next(filteredItems);\n }\n\n protected setLoading(isLoading: boolean): void {\n this.loadingSubject.next(isLoading);\n }\n\n protected setError(error: string | null): void {\n this.errorSubject.next(error);\n }\n\n // Helper to subscribe to socket events with typesafety\n protected subscribeToEvent<R>(\n event: string,\n handler: (data: R) => void\n ): void {\n this.socketService.on<R>(event).subscribe(handler);\n }\n\n getAll(): T[] {\n return this.dataSubject.value;\n }\n\n getById(id: string): T | undefined {\n const field = 'id' as keyof T;\n return this.dataSubject.value.find(item => item[field] === id);\n }\n\n getById$(id: string): Observable<T | undefined> {\n const field = 'id' as keyof T;\n return this.data$.pipe(\n map(items => items.find(item => item[field] === id))\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\nexport interface PendingJoinRequest {\n id: string;\n name: string;\n tableId: string;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class TableStore<T extends Entity> extends BaseStore<T> {\n // Store pending customer join requests\n private pendingJoinRequestsSubject = new BehaviorSubject<PendingJoinRequest[]>([]);\n public pendingJoinRequests$ = this.pendingJoinRequestsSubject.asObservable();\n\n // Emits when the current customer has been approved to join the table\n private approvedSubject = new Subject<void>();\n public approved$ = this.approvedSubject.asObservable();\n\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.TABLE_CREATED_OR_UPDATED,\n (table) => this.updateItem(table)\n );\n\n this.subscribeToEvent<string>(\n SocketSuccessEventKeys.TABLE_RELEASED,\n (tableId) => this.removeItem(tableId)\n );\n\n this.subscribeToEvent<boolean>(\n SocketSuccessEventKeys.HOST_JOIN_REQUEST_APPROVED_SUCCESS,\n (status) => {\n if (status) {\n this.approvedSubject.next();\n }\n }\n );\n\n // Listen for customer join requests\n this.subscribeToEvent<PendingJoinRequest>(\n SocketSuccessEventKeys.TABLE_JOIN_REQUEST_SENT_SUCCESS,\n (request) => {\n console.log('[TableStore] Customer join request received:', request);\n const current = this.pendingJoinRequestsSubject.value;\n // Avoid duplicates\n if (!current.find(r => r.id === request.id)) {\n this.pendingJoinRequestsSubject.next([...current, request]);\n }\n }\n );\n }\n\n // Remove a pending join request (e.g., after approval/decline)\n public removePendingJoinRequest(customerId: string): void {\n const current = this.pendingJoinRequestsSubject.value;\n this.pendingJoinRequestsSubject.next(current.filter(r => r.id !== customerId));\n }\n\n // Clear all pending join requests\n public clearPendingJoinRequests(): void {\n this.pendingJoinRequestsSubject.next([]);\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { Injectable } from '@angular/core';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class CartStore<T extends Entity> extends BaseStore<T> {\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n console.log('[CartStore] Setting up socket subscriptions');\n console.log('[CartStore] CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS event:', SocketSuccessEventKeys.CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS);\n\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS,\n (cart) => {\n console.log('[CartStore] CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS handler called with:', cart);\n this.updateItem(cart);\n console.log(this.dataSubject.getValue());\n\n }\n );\n\n this.subscribeToEvent<string>(\n SocketSuccessEventKeys.CUSTOMER_REMOVE_FROM_CART_SUCCESS,\n (cartId) => {\n console.log('[CartStore] CUSTOMER_REMOVE_FROM_CART_SUCCESS handler called with:', cartId);\n this.removeItem(cartId);\n console.log(this.dataSubject.getValue());\n }\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class CallWaiterStore<T extends Entity> extends BaseStore<T> {\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n console.log('[CallWaiterStore] Setting up socket subscriptions');\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.WAITER_CALL_CREATED_SUCCESS,\n (request) => this.updateItem(request)\n );\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\nimport { ToastrService } from 'ngx-toastr';\n\nexport interface CartEventData {\n id: string;\n tableId: string;\n menuItemId?: string;\n customerCarts?: Array<{\n id: string;\n status?: string;\n customer?: {\n name?: string;\n };\n }>;\n}\n\nexport interface ReadyOrderAlert {\n id: string;\n cartId: string;\n tableId: string;\n customerName: string;\n timestamp: Date;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport class NotificationStore {\n private readonly defaultOptions = {\n closeButton: true,\n progressBar: true\n };\n\n // Ready order alerts with dismiss functionality\n private readyOrderAlertsSubject = new BehaviorSubject<ReadyOrderAlert[]>([]);\n public readyOrderAlerts$ = this.readyOrderAlertsSubject.asObservable();\n\n constructor(\n protected socketService: SocketService,\n private readonly toastr: ToastrService\n ) {\n this.setupSocketSubscriptions();\n\n this.socketService.reconnect$.subscribe(() => {\n this.setupSocketSubscriptions();\n });\n }\n\n private setupSocketSubscriptions(): void {\n // Error messages\n this.socketService.on<{ message: string }>(SocketSuccessEventKeys.ERROR_MESSAGE_SUCCESS)\n .subscribe((data) => this.showError(data.message));\n\n // Success messages\n this.socketService.on<{ message: string }>(SocketSuccessEventKeys.SUCCESS_MESSAGE_SUCCESS)\n .subscribe((data) => this.showSuccess(data.message));\n\n // Warning messages\n this.socketService.on<{ message: string }>(SocketSuccessEventKeys.WARNING_MESSAGE_SUCCESS)\n .subscribe((data) => this.showWarning(data.message));\n\n // Cart update notifications - check for PREPARED status\n this.socketService.on<CartEventData>(SocketSuccessEventKeys.CUSTOMER_CREATE_OR_UPDATE_CART_SUCCESS)\n .subscribe((cart) => {\n console.log('[NotificationStore] Cart updated:', cart);\n\n // Check if any customer cart has PREPARED status\n const preparedCarts = cart.customerCarts?.filter(cc => cc.status === 'PREPARED') || [];\n\n if (preparedCarts.length > 0) {\n // This is a ready order - show special notification with vibration\n const customerName = preparedCarts[0]?.customer?.name || 'Customer';\n this.handleReadyOrder(cart, customerName);\n }\n // No toast for regular cart updates\n });\n\n // Cart removal notifications - just log, no toast\n this.socketService.on<string>(SocketSuccessEventKeys.CUSTOMER_REMOVE_FROM_CART_SUCCESS)\n .subscribe((cartId) => {\n console.log('[NotificationStore] Cart removed:', cartId);\n });\n }\n\n /**\n * Handle ready order notification with vibration and dismissable alert\n */\n private handleReadyOrder(cart: CartEventData, customerName: string): void {\n console.log('[NotificationStore] Ready order detected!', cart);\n\n // Vibrate device if supported\n this.vibrateDevice();\n\n // Add to ready order alerts\n const alert: ReadyOrderAlert = {\n id: `${cart.id}-${Date.now()}`,\n cartId: cart.id,\n tableId: cart.tableId,\n customerName,\n timestamp: new Date()\n };\n\n const currentAlerts = this.readyOrderAlertsSubject.value;\n this.readyOrderAlertsSubject.next([alert, ...currentAlerts]);\n\n // Also show toast with longer duration\n this.toastr.success(\n `Order ready for ${customerName}`,\n '🍽️ Order Ready!',\n {\n ...this.defaultOptions,\n timeOut: 0, // No auto-dismiss\n extendedTimeOut: 0,\n tapToDismiss: true\n }\n );\n }\n\n /**\n * Vibrate the device if supported\n */\n private vibrateDevice(): void {\n try {\n if ('vibrate' in navigator) {\n // Vibrate pattern: 200ms on, 100ms off, 200ms on\n navigator.vibrate([200, 100, 200, 100, 200]);\n }\n } catch (e) {\n console.warn('[NotificationStore] Vibration not supported', e);\n }\n }\n\n /**\n * Dismiss a ready order alert\n */\n public dismissReadyOrderAlert(alertId: string): void {\n const currentAlerts = this.readyOrderAlertsSubject.value;\n this.readyOrderAlertsSubject.next(currentAlerts.filter(a => a.id !== alertId));\n }\n\n /**\n * Dismiss all ready order alerts\n */\n public dismissAllReadyOrderAlerts(): void {\n this.readyOrderAlertsSubject.next([]);\n }\n\n // Manual notification methods\n public showError(message: string, title: string = 'Error', timeOut: number = 5000): void {\n this.toastr.error(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n public showSuccess(message: string, title: string = 'Success', timeOut: number = 3000): void {\n this.toastr.success(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n public showWarning(message: string, title: string = 'Warning', timeOut: number = 4000): void {\n this.toastr.warning(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n public showInfo(message: string, title: string = 'Info', timeOut: number = 3000): void {\n this.toastr.info(message, title, {\n ...this.defaultOptions,\n timeOut\n });\n }\n\n // Clear all toasts\n public clearAll(): void {\n this.toastr.clear();\n }\n\n // Remove a specific toast by id\n public remove(toastId: number): void {\n this.toastr.remove(toastId);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\nexport interface DeliveryLocation {\n driverId: string;\n lat: number;\n lng: number;\n orderId: string;\n timestamp?: number;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class DeliveryOrderStore<T extends Entity> extends BaseStore<T> {\n private driverLocationSubject = new BehaviorSubject<DeliveryLocation | null>(null);\n public driverLocation$ = this.driverLocationSubject.asObservable();\n\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.NEW_DELIVERY_ORDER,\n (order) => this.updateItem(order)\n );\n\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.ORDER_STATUS_UPDATED,\n (order) => this.updateItem(order)\n );\n\n this.subscribeToEvent<DeliveryLocation>(\n SocketSuccessEventKeys.DRIVER_LOCATION_UPDATED,\n (location) => this.driverLocationSubject.next(location)\n );\n }\n}\n","import { Injectable } from '@angular/core';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class ReservationStore<T extends Entity> extends BaseStore<T> {\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.RESERVATION_CREATE_OR_UPDATE_SUCCESS,\n (reservation) => this.updateItem(reservation)\n );\n\n this.subscribeToEvent<string>(\n SocketSuccessEventKeys.RESERVATION_REMOVE_SUCCESS,\n (reservationId) => this.removeItem(reservationId)\n );\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { BaseStore, Entity } from '../base-store';\nimport { SocketService, SocketSuccessEventKeys } from '../socket.service';\n\nexport interface InventoryLowStockAlert {\n stockItemId: string;\n name: string;\n currentStock: number;\n threshold: number;\n branchId: string;\n}\n\nexport interface InventoryPurchaseOrderUpdate {\n purchaseOrderId: string;\n status: string;\n branchId: string;\n}\n\n@Injectable({\n providedIn: 'root'\n})\nexport abstract class InventoryStore<T extends Entity> extends BaseStore<T> {\n private readonly lowStockAlertSubject = new BehaviorSubject<InventoryLowStockAlert | null>(null);\n public lowStockAlert$ = this.lowStockAlertSubject.asObservable();\n\n private readonly purchaseOrderUpdateSubject = new BehaviorSubject<InventoryPurchaseOrderUpdate | null>(null);\n public purchaseOrderUpdate$ = this.purchaseOrderUpdateSubject.asObservable();\n\n constructor(\n protected override socketService: SocketService\n ) {\n super(socketService);\n }\n\n protected override setupSocketSubscriptions(): void {\n this.subscribeToEvent<T>(\n SocketSuccessEventKeys.INVENTORY_STOCK_UPDATED,\n (item) => this.updateItem(item)\n );\n\n this.subscribeToEvent<InventoryLowStockAlert>(\n SocketSuccessEventKeys.INVENTORY_LOW_STOCK_ALERT,\n (alert) => this.lowStockAlertSubject.next(alert)\n );\n\n this.subscribeToEvent<InventoryPurchaseOrderUpdate>(\n SocketSuccessEventKeys.INVENTORY_PURCHASE_ORDER_UPDATED,\n (update) => this.purchaseOrderUpdateSubject.next(update)\n );\n }\n\n public abstract override preload(): Promise<T[]>;\n}\n","import { EnvironmentProviders, importProvidersFrom } from '@angular/core';\nimport { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';\n\n/**\n * Provides all services needed for the realtime store to function.\n * Use this function in your standalone application's bootstrapApplication providers array.\n * \n * @example\n * ```typescript\n * bootstrapApplication(AppComponent, {\n * providers: [\n * provideRealtimeStore()\n * ]\n * });\n * ```\n */\nexport function provideRealtimeStore(): EnvironmentProviders[] {\n return [\n provideHttpClient(withInterceptorsFromDi())\n ];\n}\n","import { Provider } from '@angular/core';\nimport { REALTIME_STORE_ENVIRONMENT, RealtimeStoreEnvironment } from '../environment';\n\nexport function provideRealtimeStoreEnvironment(environment: RealtimeStoreEnvironment): Provider {\n return {\n provide: REALTIME_STORE_ENVIRONMENT,\n useValue: environment\n };\n}","import { Injectable } from '@angular/core';\nimport { SocketService } from './socket.service';\n\n/**\n * Handles the MQTT connection lifecycle for the driver app.\n *\n * Pattern:\n * - Use setAuthToken() + connect() instead of resetWithNewToken() so an in-progress\n * connection is never torn down by a duplicate call (e.g. on page refresh).\n * - reconnect$ emits when the MQTT client re-establishes after a drop; use it to\n * re-emit DRIVER_CONNECT so the server re-joins the driver to their rooms.\n * - A 'online' event listener handles recovery when the network comes back.\n *\n * Usage:\n * - AppComponent.ngOnInit: call connectFromStorage() ONCE to restore session.\n * - LoginPage success handler: call connect(token) after receiving a new token.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class DriverSocketConnectionService {\n private readonly TOKEN_KEY = 'driver_token';\n private networkListener?: () => void;\n\n constructor(private readonly socketService: SocketService) {\n this.networkListener = () => this.connectFromStorage();\n window.addEventListener('online', this.networkListener);\n }\n\n /** Connect using a freshly obtained token (e.g. after login). */\n connect(token: string): void {\n localStorage.setItem(this.TOKEN_KEY, token);\n this.socketService.setAuthToken(token);\n this.socketService.connect();\n }\n\n /** Restore the socket connection from a persisted token (e.g. on app start). */\n connectFromStorage(): void {\n const token = localStorage.getItem(this.TOKEN_KEY);\n if (token) {\n this.socketService.setAuthToken(token);\n this.socketService.connect();\n }\n }\n\n disconnect(): void {\n this.socketService.disconnect();\n if (this.networkListener) {\n window.removeEventListener('online', this.networkListener);\n this.networkListener = undefined;\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport { SocketService } from './socket.service';\n\n/**\n * Handles the MQTT connection lifecycle for the customer-food (online customer) app.\n *\n * Pattern:\n * - Use setAuthToken() + connect() instead of resetWithNewToken() so an in-progress\n * connection is never torn down by a duplicate call (e.g. on page refresh).\n * - reconnect$ emits when the MQTT client re-establishes after a drop; use it to\n * re-emit CUSTOMER_CONNECT so the server re-joins the client to their rooms.\n * - A 'online' event listener handles recovery when the network comes back.\n *\n * Usage:\n * - AppComponent.ngOnInit: call connectFromStorage() ONCE to restore session.\n * - LoginPage success handler: call connect(token) after receiving a new token.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class OnlineCustomerSocketConnectionService {\n private readonly TOKEN_KEY = 'online_customer_token';\n private networkListener?: () => void;\n\n constructor(private readonly socketService: SocketService) {\n this.networkListener = () => this.connectFromStorage();\n window.addEventListener('online', this.networkListener);\n }\n\n /** Connect using a freshly obtained token (e.g. after login). */\n connect(token: string): void {\n this.socketService.setAuthToken(token);\n this.socketService.connect();\n }\n\n /** Restore the socket connection from a persisted token (e.g. on app start). */\n connectFromStorage(): void {\n const token = localStorage.getItem(this.TOKEN_KEY);\n if (token) {\n this.connect(token);\n }\n }\n\n disconnect(): void {\n this.socketService.disconnect();\n if (this.networkListener) {\n window.removeEventListener('online', this.networkListener);\n this.networkListener = undefined;\n }\n }\n}\n","/*\n * Public API Surface of realtime-store\n */\n\nexport * from './lib/realtime-store.module';\nexport * from './lib/socket.service';\nexport * from './lib/base-store';\nexport * from './lib/stores/table.store';\nexport * from './lib/stores/cart.store';\nexport * from './lib/stores/call-waiter.store';\nexport * from './lib/stores/notification.store';\nexport * from './lib/stores/delivery-order.store';\nexport * from './lib/stores/reservation.store';\nexport * from './lib/stores/inventory.store';\nexport * from './lib/providers';\nexport * from './lib/environment';\nexport * from './lib/providers/realtime-store-environment.provider';\nexport * from './lib/driver-socket-connection.service';\nexport * from './lib/online-customer-socket-connection.service';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.SocketService"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -17,6 +17,11 @@ declare class RealtimeStoreModule {
17
17
 
18
18
  interface RealtimeStoreEnvironment {
19
19
  apiUrl: string;
20
+ /**
21
+ * WebSocket URL for the MQTT broker (e.g. ws://localhost:9001 or wss://broker.example.com:8883).
22
+ * If omitted, derived from apiUrl by replacing http → ws / https → wss.
23
+ */
24
+ mqttUrl?: string;
20
25
  }
21
26
  declare const defaultRealtimeStoreEnvironment: RealtimeStoreEnvironment;
22
27
 
@@ -52,13 +57,25 @@ declare enum SocketSuccessEventKeys {
52
57
  BILLING_CREDIT_NOTE_ISSUED = "BILLING_CREDIT_NOTE_ISSUED",
53
58
  BILLING_REFUND_PROCESSED = "BILLING_REFUND_PROCESSED"
54
59
  }
60
+ /**
61
+ * Topic convention (mirrors server messenger.gateway.ts):
62
+ * Server → user: serve-plus/user/{userId}/{event}
63
+ * Server → room: serve-plus/room/{roomId}/{event}
64
+ * Client → server: serve-plus/client/{userId}/{action} (payload = raw JWT string)
65
+ *
66
+ * System events handled internally (not forwarded to event subjects):
67
+ * JOIN_ROOM { roomId: string } — subscribe to serve-plus/room/{roomId}/#
68
+ * LEAVE_ROOM { roomId: string } — unsubscribe from serve-plus/room/{roomId}/#
69
+ * FORCE_DISCONNECT {} — disconnect
70
+ */
55
71
  declare class SocketService {
56
72
  private readonly environment;
57
- private socket;
58
- private readonly url;
73
+ private mqttClient?;
59
74
  private authToken?;
60
75
  private connectionKey?;
76
+ private userId?;
61
77
  private readonly eventSubjects;
78
+ private readonly subscribedRooms;
62
79
  private readonly connectionStatusSubject;
63
80
  connectionStatus$: Observable<boolean>;
64
81
  private readonly reconnectSubject;
@@ -66,42 +83,41 @@ declare class SocketService {
66
83
  private hasConnectedOnce;
67
84
  private readonly healthySubject;
68
85
  healthy$: Observable<boolean>;
69
- private healthCheckInterval?;
70
- private lastPongTime;
86
+ private readonly TOPIC_PREFIX;
71
87
  constructor(environment?: RealtimeStoreEnvironment);
72
- private setupSocketConnection;
88
+ private decodeUserId;
89
+ private resolveBrokerUrl;
90
+ private setupConnection;
91
+ private subscribeToRoom;
92
+ private unsubscribeFromRoom;
73
93
  /**
74
- * Monitor connection health via ping/pong timing
75
- */
76
- private startHealthCheck;
77
- private stopHealthCheck;
78
- private reestablishListeners;
79
- /**
80
- * Set authentication token for socket connection
94
+ * Set authentication token for MQTT connection.
95
+ * Call connect() afterwards to open the connection.
81
96
  */
82
97
  setAuthToken(token: string): void;
83
98
  /**
84
- * Set connection key for socket connection
99
+ * Set connection key included in outbound message headers.
85
100
  */
86
101
  setConnectionKey(key: string): void;
87
102
  /**
88
- * Reset connection with new token
103
+ * Reset connection with new token.
104
+ * Idempotent: no-op if the same token is already active and connected.
89
105
  */
90
106
  resetWithNewToken(token?: string): void;
91
107
  connect(timeoutMs?: number): Promise<void>;
92
108
  disconnect(): void;
93
109
  /**
94
- * Emit event with optional authentication headers
110
+ * Emit an event to the server (client → server).
111
+ * Publishes to serve-plus/client/{userId}/{event}.
95
112
  */
96
- emit(event: string, data?: any): void;
113
+ emit(event: string, data?: unknown): void;
97
114
  /**
98
- * Listen to events with persistent subjects that survive reconnections
115
+ * Listen to server-sent events. Returns a persistent Observable that
116
+ * survives reconnections (matching the previous socket.io behaviour).
99
117
  */
100
118
  on<T>(event: string): Observable<T>;
101
119
  /**
102
- * Listen to event once and return as Promise
103
- * @param event - Event name to listen for
104
- * @param timeoutMs - Timeout in ms (default 30s, 0 = no timeout)
120
+ * Listen for a single event occurrence and return as a Promise.
105
121
  */
106
122
  once<T>(event: string, timeoutMs?: number): Promise<T>;
107
123
  static ɵfac: i0.ɵɵFactoryDeclaration<SocketService, never>;
@@ -300,47 +316,57 @@ declare function provideRealtimeStore(): EnvironmentProviders[];
300
316
  declare function provideRealtimeStoreEnvironment(environment: RealtimeStoreEnvironment): Provider;
301
317
 
302
318
  /**
303
- * Handles the socket connection lifecycle for the driver app.
304
- * Reads the driver token from localStorage and connects/reconnects with it.
319
+ * Handles the MQTT connection lifecycle for the driver app.
320
+ *
321
+ * Pattern:
322
+ * - Use setAuthToken() + connect() instead of resetWithNewToken() so an in-progress
323
+ * connection is never torn down by a duplicate call (e.g. on page refresh).
324
+ * - reconnect$ emits when the MQTT client re-establishes after a drop; use it to
325
+ * re-emit DRIVER_CONNECT so the server re-joins the driver to their rooms.
326
+ * - A 'online' event listener handles recovery when the network comes back.
305
327
  *
306
328
  * Usage:
307
- * - `AppComponent.ngOnInit`: call `connectFromStorage()` to restore session on app start.
308
- * - `LoginPage` success handler: call `connect(token)` after receiving a new token.
329
+ * - AppComponent.ngOnInit: call connectFromStorage() ONCE to restore session.
330
+ * - LoginPage success handler: call connect(token) after receiving a new token.
309
331
  */
310
332
  declare class DriverSocketConnectionService {
311
333
  private readonly socketService;
312
334
  private readonly TOKEN_KEY;
313
- private reconnectSubscription?;
335
+ private networkListener?;
314
336
  constructor(socketService: SocketService);
315
337
  /** Connect using a freshly obtained token (e.g. after login). */
316
338
  connect(token: string): void;
317
339
  /** Restore the socket connection from a persisted token (e.g. on app start). */
318
340
  connectFromStorage(): void;
319
341
  disconnect(): void;
320
- private subscribeToReconnect;
321
342
  static ɵfac: i0.ɵɵFactoryDeclaration<DriverSocketConnectionService, never>;
322
343
  static ɵprov: i0.ɵɵInjectableDeclaration<DriverSocketConnectionService>;
323
344
  }
324
345
 
325
346
  /**
326
- * Handles the socket connection lifecycle for the customer-food (online customer) app.
327
- * Reads the online customer token from localStorage and connects/reconnects with it.
347
+ * Handles the MQTT connection lifecycle for the customer-food (online customer) app.
348
+ *
349
+ * Pattern:
350
+ * - Use setAuthToken() + connect() instead of resetWithNewToken() so an in-progress
351
+ * connection is never torn down by a duplicate call (e.g. on page refresh).
352
+ * - reconnect$ emits when the MQTT client re-establishes after a drop; use it to
353
+ * re-emit CUSTOMER_CONNECT so the server re-joins the client to their rooms.
354
+ * - A 'online' event listener handles recovery when the network comes back.
328
355
  *
329
356
  * Usage:
330
- * - `AppComponent.ngOnInit`: call `connectFromStorage()` to restore session on app start.
331
- * - `LoginPage` success handler: call `connect(token)` after receiving a new token.
357
+ * - AppComponent.ngOnInit: call connectFromStorage() ONCE to restore session.
358
+ * - LoginPage success handler: call connect(token) after receiving a new token.
332
359
  */
333
360
  declare class OnlineCustomerSocketConnectionService {
334
361
  private readonly socketService;
335
362
  private readonly TOKEN_KEY;
336
- private reconnectSubscription?;
363
+ private networkListener?;
337
364
  constructor(socketService: SocketService);
338
365
  /** Connect using a freshly obtained token (e.g. after login). */
339
366
  connect(token: string): void;
340
367
  /** Restore the socket connection from a persisted token (e.g. on app start). */
341
368
  connectFromStorage(): void;
342
369
  disconnect(): void;
343
- private subscribeToReconnect;
344
370
  static ɵfac: i0.ɵɵFactoryDeclaration<OnlineCustomerSocketConnectionService, never>;
345
371
  static ɵprov: i0.ɵɵInjectableDeclaration<OnlineCustomerSocketConnectionService>;
346
372
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "serve-socket",
3
- "version": "5.4.0",
3
+ "version": "6.0.0",
4
4
  "description": "Real-time WebSocket service for restaurant waiter coordination",
5
5
  "license": "MIT",
6
6
  "author": "Serve+ Team",
@@ -18,7 +18,8 @@
18
18
  ],
19
19
  "peerDependencies": {
20
20
  "@angular/common": ">=15.0.0",
21
- "@angular/core": ">=15.0.0"
21
+ "@angular/core": ">=15.0.0",
22
+ "mqtt": ">=5.0.0"
22
23
  },
23
24
  "dependencies": {
24
25
  "tslib": "^2.3.0"