@lemoncloud/chatic-sockets-lib 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/client-socket-v2/connection-rotation-controller.d.ts +4 -0
  2. package/dist/client-socket-v2/connection-rotation-controller.js +9 -3
  3. package/dist/client-socket-v2/create-client-socket-v2.js +155 -27
  4. package/dist/client-socket-v2/gateways/auth-gateway.d.ts +6 -0
  5. package/dist/client-socket-v2/gateways/auth-gateway.js +11 -0
  6. package/dist/client-socket-v2/gateways/channel-gateway.d.ts +38 -0
  7. package/dist/client-socket-v2/gateways/channel-gateway.js +24 -0
  8. package/dist/client-socket-v2/gateways/chat-gateway.d.ts +22 -0
  9. package/dist/client-socket-v2/gateways/chat-gateway.js +16 -0
  10. package/dist/client-socket-v2/gateways/cloud-gateway.d.ts +12 -0
  11. package/dist/client-socket-v2/gateways/cloud-gateway.js +11 -0
  12. package/dist/client-socket-v2/gateways/user-gateway.d.ts +26 -0
  13. package/dist/client-socket-v2/gateways/user-gateway.js +18 -0
  14. package/dist/client-socket-v2/index.d.ts +10 -0
  15. package/dist/client-socket-v2/index.js +9 -0
  16. package/dist/client-socket-v2/keep-alive-loop.d.ts +5 -7
  17. package/dist/client-socket-v2/keep-alive-loop.js +32 -9
  18. package/dist/client-socket-v2/message-router.d.ts +1 -0
  19. package/dist/client-socket-v2/message-router.js +4 -0
  20. package/dist/client-socket-v2/reconnect-controller.d.ts +23 -7
  21. package/dist/client-socket-v2/reconnect-controller.js +72 -9
  22. package/dist/client-socket-v2/socket-runtime.js +14 -4
  23. package/dist/client-socket-v2/socket-transport.d.ts +22 -5
  24. package/dist/client-socket-v2/socket-transport.js +79 -55
  25. package/dist/client-socket-v2/types.d.ts +45 -8
  26. package/dist/lib/auth/types.d.ts +36 -0
  27. package/dist/lib/auth/types.js +2 -0
  28. package/dist/lib/channel/types.d.ts +175 -0
  29. package/dist/lib/channel/types.js +2 -0
  30. package/dist/lib/chat/types.d.ts +79 -0
  31. package/dist/lib/chat/types.js +2 -0
  32. package/dist/lib/cloud/types.d.ts +18 -0
  33. package/dist/lib/cloud/types.js +2 -0
  34. package/dist/lib/device/types.d.ts +1 -0
  35. package/dist/lib/socket-actions.d.ts +239 -0
  36. package/dist/lib/socket-actions.js +167 -0
  37. package/dist/lib/socket-inputs.d.ts +13 -0
  38. package/dist/lib/socket-inputs.js +8 -0
  39. package/dist/lib/sockets/types.d.ts +27 -0
  40. package/dist/lib/sockets/types.js +17 -0
  41. package/dist/lib/types.d.ts +2 -0
  42. package/dist/lib/user/types.d.ts +102 -0
  43. package/dist/lib/user/types.js +2 -0
  44. package/dist/modules/chat/types.d.ts +65 -0
  45. package/dist/modules/chat/types.js +55 -0
  46. package/package.json +1 -1
@@ -4,6 +4,8 @@ export interface ConnectionRotationControllerOptions {
4
4
  reconnect?: ReconnectController;
5
5
  maxLifetimeMs?: number;
6
6
  refreshBeforeMs?: number;
7
+ /** rotation delay에 적용할 ±jitter 비율 (0~1). 동시 부트스트랩 클라이언트군의 일제 rotate burst 분산용. 기본 0.1 (±10%) */
8
+ jitterRatio?: number;
7
9
  timerScheduler?: SharedTimerScheduler;
8
10
  timerKey?: string;
9
11
  }
@@ -11,6 +13,7 @@ export declare class ConnectionRotationController {
11
13
  private readonly options;
12
14
  private readonly maxLifetimeMs;
13
15
  private readonly refreshBeforeMs;
16
+ private readonly jitterRatio;
14
17
  private readonly timerScheduler?;
15
18
  private readonly timerKey;
16
19
  private readonly unsubs;
@@ -21,6 +24,7 @@ export declare class ConnectionRotationController {
21
24
  stop: () => void;
22
25
  destroy: () => void;
23
26
  private scheduleRotation;
27
+ private computeRotationDelay;
24
28
  private rotate;
25
29
  private clearTimer;
26
30
  }
@@ -12,7 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.ConnectionRotationController = void 0;
13
13
  class ConnectionRotationController {
14
14
  constructor(options) {
15
- var _a, _b, _c;
15
+ var _a, _b, _c, _d;
16
16
  this.options = options;
17
17
  this.unsubs = [];
18
18
  this.active = false;
@@ -33,13 +33,18 @@ class ConnectionRotationController {
33
33
  this.clearTimer();
34
34
  if (!this.active)
35
35
  return;
36
- const delayMs = Math.max(0, this.maxLifetimeMs - this.refreshBeforeMs);
36
+ const delayMs = this.computeRotationDelay();
37
37
  if (this.timerScheduler) {
38
38
  this.timerScheduler.schedule(this.timerKey, delayMs, () => this.rotate());
39
39
  return;
40
40
  }
41
41
  this.timer = setTimeout(() => void this.rotate(), delayMs);
42
42
  };
43
+ this.computeRotationDelay = () => {
44
+ const baseDelay = Math.max(0, this.maxLifetimeMs - this.refreshBeforeMs);
45
+ const jitter = this.jitterRatio > 0 ? baseDelay * (Math.random() * 2 - 1) * this.jitterRatio : 0;
46
+ return Math.max(0, baseDelay + jitter);
47
+ };
43
48
  this.rotate = () => __awaiter(this, void 0, void 0, function* () {
44
49
  if (!this.active)
45
50
  return;
@@ -64,8 +69,9 @@ class ConnectionRotationController {
64
69
  };
65
70
  this.maxLifetimeMs = (_a = options.maxLifetimeMs) !== null && _a !== void 0 ? _a : 1000 * 60 * 110;
66
71
  this.refreshBeforeMs = (_b = options.refreshBeforeMs) !== null && _b !== void 0 ? _b : 1000 * 60 * 10;
72
+ this.jitterRatio = Math.max(0, Math.min(1, (_c = options.jitterRatio) !== null && _c !== void 0 ? _c : 0.1));
67
73
  this.timerScheduler = options.timerScheduler;
68
- this.timerKey = (_c = options.timerKey) !== null && _c !== void 0 ? _c : 'rotation';
74
+ this.timerKey = (_d = options.timerKey) !== null && _d !== void 0 ? _d : 'rotation';
69
75
  this.unsubs.push(options.client.onState(event => {
70
76
  if (!this.active)
71
77
  return;
@@ -11,8 +11,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.createClientSocketV2 = void 0;
13
13
  const common_1 = require("./common");
14
+ const keep_alive_loop_1 = require("./keep-alive-loop");
14
15
  const message_router_1 = require("./message-router");
15
16
  const pending_request_store_1 = require("./pending-request-store");
17
+ const reconnect_controller_1 = require("./reconnect-controller");
16
18
  const shared_timer_scheduler_1 = require("./shared-timer-scheduler");
17
19
  const socket_transport_1 = require("./socket-transport");
18
20
  const buildMid = () => `m-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -28,16 +30,29 @@ const parseMessage = (raw) => {
28
30
  }
29
31
  return (0, common_1.onlyDefined)(Object.assign(Object.assign({}, message), { type: (0, common_1.cleanString)(message.type) }));
30
32
  };
33
+ const normalizeRequestCap = (value, fallback) => {
34
+ const n = value !== null && value !== void 0 ? value : fallback;
35
+ return n > 0 ? n : Number.POSITIVE_INFINITY;
36
+ };
37
+ const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
38
+ const DEFAULT_MAX_INFLIGHT_REQUESTS = 32;
39
+ const DEFAULT_MAX_PENDING_REQUESTS = 512;
31
40
  class ClientSocketV2Impl {
32
41
  constructor(options) {
33
- var _a;
42
+ var _a, _b;
34
43
  this.options = options;
35
44
  this.router = new message_router_1.MessageRouter();
36
45
  this.stateListeners = new Set();
37
46
  this.errorListeners = new Set();
38
47
  this.messageListeners = new Set();
48
+ this.requestQueue = [];
49
+ this.inflightRequests = 0;
50
+ this.transportUnsubs = [];
39
51
  this._state = 'idle';
52
+ /** reconnect.stop이 client.disconnect를 호출하므로 재귀 진입 차단용 */
53
+ this.disconnecting = false;
40
54
  this.connect = () => __awaiter(this, void 0, void 0, function* () {
55
+ var _c;
41
56
  if (this._state === 'connected' || this._state === 'connecting')
42
57
  return;
43
58
  this.setState('connecting');
@@ -49,10 +64,27 @@ class ClientSocketV2Impl {
49
64
  this.setState('closed');
50
65
  throw error;
51
66
  }
67
+ finally {
68
+ void ((_c = this.reconnect) === null || _c === void 0 ? void 0 : _c.start().catch(() => undefined));
69
+ }
52
70
  });
53
71
  this.disconnect = (code, reason) => __awaiter(this, void 0, void 0, function* () {
54
72
  if (this._state === 'closed' || this._state === 'idle')
55
73
  return;
74
+ if (this.reconnect && !this.disconnecting) {
75
+ this.disconnecting = true;
76
+ try {
77
+ yield this.reconnect.stop(code, reason);
78
+ }
79
+ catch (error) {
80
+ this.emitError({ error, phase: 'disconnect' });
81
+ throw error;
82
+ }
83
+ finally {
84
+ this.disconnecting = false;
85
+ }
86
+ return;
87
+ }
56
88
  this.setState('closing');
57
89
  try {
58
90
  yield this.transport.disconnect(code, reason);
@@ -73,26 +105,22 @@ class ClientSocketV2Impl {
73
105
  this.transport.send(JSON.stringify(message));
74
106
  };
75
107
  this.request = (type, data, options) => __awaiter(this, void 0, void 0, function* () {
76
- var _b, _c, _d, _e, _f;
77
- const mid = (_d = (_c = (_b = this.options).createMid) === null || _c === void 0 ? void 0 : _c.call(_b)) !== null && _d !== void 0 ? _d : buildMid();
108
+ var _d, _e, _f, _g;
109
+ const mid = (_f = (_e = (_d = this.options).createMid) === null || _e === void 0 ? void 0 : _e.call(_d)) !== null && _f !== void 0 ? _f : buildMid();
78
110
  const canonicalType = this.normalizeType(type);
79
- const promise = this.pending.create(mid, {
80
- timeoutMs: (_e = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _e !== void 0 ? _e : this.options.requestTimeoutMs,
81
- onTimeout: requestMid => new Error(`408 REQUEST TIMEOUT - ${canonicalType}[${requestMid}]`),
82
- });
83
- try {
84
- this.transport.send(JSON.stringify((0, common_1.onlyDefined)({
85
- type: canonicalType,
86
- data: (_f = data) !== null && _f !== void 0 ? _f : null,
87
- mid,
88
- })));
89
- }
90
- catch (error) {
91
- this.pending.reject(mid, error);
92
- this.emitError({ error, phase: 'request' });
93
- throw error;
111
+ const timeoutMs = (_g = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _g !== void 0 ? _g : this.requestTimeoutMs;
112
+ const totalAccepted = this.inflightRequests + this.requestQueue.length;
113
+ if (totalAccepted >= this.maxPendingRequests) {
114
+ throw new Error(`429 TOO MANY REQUESTS - pending queue full (${totalAccepted}/${this.maxPendingRequests})`);
94
115
  }
95
- return promise;
116
+ return new Promise((resolve, reject) => {
117
+ const job = { mid, type: canonicalType, data, timeoutMs, resolve, reject };
118
+ if (this.inflightRequests < this.maxInflightRequests) {
119
+ this.dispatchRequest(job);
120
+ return;
121
+ }
122
+ this.requestQueue.push(job);
123
+ });
96
124
  });
97
125
  this.onState = (listener) => {
98
126
  this.stateListeners.add(listener);
@@ -107,6 +135,80 @@ class ClientSocketV2Impl {
107
135
  return () => this.messageListeners.delete(listener);
108
136
  };
109
137
  this.onType = (type, listener) => this.router.onType(type, listener);
138
+ this.destroy = () => {
139
+ var _a, _b;
140
+ /** 순서 invariant: reconnect.destroy → keepAlive.destroy → transport.disconnect (그 close 이벤트를 reconnect가 못 듣게 하기 위함) → 나머지 정리 */
141
+ (_a = this.reconnect) === null || _a === void 0 ? void 0 : _a.destroy();
142
+ (_b = this.keepAlive) === null || _b === void 0 ? void 0 : _b.destroy();
143
+ void this.transport.disconnect().catch(() => undefined);
144
+ this.transportUnsubs.splice(0).forEach(unsub => unsub());
145
+ this.rejectQueuedRequests(new Error(`499 CLIENT CLOSED REQUEST - client destroyed`));
146
+ this.pending.clear(new Error(`499 CLIENT CLOSED REQUEST - client destroyed`));
147
+ this.router.clear();
148
+ this.stateListeners.clear();
149
+ this.errorListeners.clear();
150
+ this.messageListeners.clear();
151
+ if (this.ownsTimerScheduler)
152
+ this.timerScheduler.cancelAll();
153
+ this._state = 'closed';
154
+ };
155
+ this.dispatchRequest = (job) => {
156
+ var _a;
157
+ this.inflightRequests += 1;
158
+ let released = false;
159
+ const release = () => {
160
+ if (released)
161
+ return;
162
+ released = true;
163
+ this.inflightRequests = Math.max(0, this.inflightRequests - 1);
164
+ this.dispatchNextQueuedRequest();
165
+ };
166
+ let pending;
167
+ try {
168
+ pending = this.pending.create(job.mid, {
169
+ timeoutMs: job.timeoutMs,
170
+ onTimeout: (requestMid) => new Error(`408 REQUEST TIMEOUT - ${job.type}[${requestMid}]`),
171
+ });
172
+ }
173
+ catch (error) {
174
+ release();
175
+ job.reject(error);
176
+ this.emitError({ error, phase: 'request' });
177
+ return;
178
+ }
179
+ void pending.then(value => {
180
+ job.resolve(value);
181
+ release();
182
+ }, error => {
183
+ job.reject(error);
184
+ release();
185
+ });
186
+ try {
187
+ this.transport.send(JSON.stringify((0, common_1.onlyDefined)({
188
+ type: job.type,
189
+ data: (_a = job.data) !== null && _a !== void 0 ? _a : null,
190
+ mid: job.mid,
191
+ })));
192
+ }
193
+ catch (error) {
194
+ this.pending.reject(job.mid, error);
195
+ release();
196
+ this.emitError({ error, phase: 'request' });
197
+ }
198
+ };
199
+ this.dispatchNextQueuedRequest = () => {
200
+ while (this.inflightRequests < this.maxInflightRequests && this.requestQueue.length) {
201
+ const next = this.requestQueue.shift();
202
+ if (!next)
203
+ return;
204
+ this.dispatchRequest(next);
205
+ }
206
+ };
207
+ this.rejectQueuedRequests = (reason) => {
208
+ const queued = this.requestQueue.splice(0);
209
+ queued.forEach(job => job.reject(reason));
210
+ return queued.length;
211
+ };
110
212
  this.normalizeType = (type) => {
111
213
  var _a;
112
214
  const source = (0, common_1.cleanString)(type);
@@ -115,8 +217,13 @@ class ClientSocketV2Impl {
115
217
  return ((_a = this.aliases[source]) !== null && _a !== void 0 ? _a : source);
116
218
  };
117
219
  this.handleRawMessage = (raw) => {
220
+ var _a, _b, _c, _d;
118
221
  try {
222
+ if (((_b = (_a = this.options).shouldHandleRaw) === null || _b === void 0 ? void 0 : _b.call(_a, { raw })) === false)
223
+ return;
119
224
  const message = parseMessage(raw);
225
+ if (((_d = (_c = this.options).shouldHandleMessage) === null || _d === void 0 ? void 0 : _d.call(_c, { raw, message })) === false)
226
+ return;
120
227
  const handled = this.pending.settle(message);
121
228
  const event = { message, raw };
122
229
  this.messageListeners.forEach(listener => listener(event));
@@ -127,6 +234,12 @@ class ClientSocketV2Impl {
127
234
  this.emitError({ error, phase: 'message', raw });
128
235
  }
129
236
  };
237
+ this.closeTransportInternal = (code, reason) => {
238
+ if (this._state === 'closed' || this._state === 'idle')
239
+ return;
240
+ this.setState('closing');
241
+ void this.transport.disconnect(code, reason).catch(() => undefined);
242
+ };
130
243
  this.setState = (next) => {
131
244
  const prev = this._state;
132
245
  this._state = next;
@@ -139,22 +252,37 @@ class ClientSocketV2Impl {
139
252
  this.errorListeners.forEach(listener => listener(event));
140
253
  };
141
254
  this.deviceDefaults = options.device ? (0, common_1.omitKeys)(options.device, ['tick']) : undefined;
142
- this.timerScheduler = (_a = options.timerScheduler) !== null && _a !== void 0 ? _a : new shared_timer_scheduler_1.InMemorySharedTimerScheduler(options.now ? { now: options.now } : {});
255
+ this.requestTimeoutMs = (_a = options.requestTimeoutMs) !== null && _a !== void 0 ? _a : DEFAULT_REQUEST_TIMEOUT_MS;
256
+ this.maxInflightRequests = normalizeRequestCap(options.maxInflightRequests, DEFAULT_MAX_INFLIGHT_REQUESTS);
257
+ this.maxPendingRequests = normalizeRequestCap(options.maxPendingRequests, DEFAULT_MAX_PENDING_REQUESTS);
258
+ this.ownsTimerScheduler = !options.timerScheduler;
259
+ this.timerScheduler =
260
+ (_b = options.timerScheduler) !== null && _b !== void 0 ? _b : new shared_timer_scheduler_1.InMemorySharedTimerScheduler(options.now ? { now: options.now } : {});
143
261
  this.pending = new pending_request_store_1.PendingRequestStore({
144
262
  timerScheduler: this.timerScheduler,
145
263
  timerPrefix: 'pending:',
146
264
  });
147
265
  this.aliases = Object.assign({ ping: 'system.ping' }, (options.aliases || {}));
148
- this.transport = new socket_transport_1.WebSocketTransport(options.url, options.protocols, options.socketFactory);
149
- this.transport.on('open', () => this.setState('connected'));
150
- this.transport.on('close', () => {
266
+ this.transport = new socket_transport_1.WebSocketTransport(options.url, options.protocols, options.socketFactory, {
267
+ connectTimeoutMs: options.connectTimeoutMs,
268
+ });
269
+ this.transportUnsubs.push(this.transport.on('open', () => this.setState('connected')));
270
+ this.transportUnsubs.push(this.transport.on('close', () => {
271
+ this.rejectQueuedRequests(new Error(`499 CLIENT CLOSED REQUEST - socket closed`));
151
272
  this.pending.clear(new Error(`499 CLIENT CLOSED REQUEST - socket closed`));
152
273
  this.setState('closed');
153
- });
154
- this.transport.on('error', event => {
274
+ }));
275
+ this.transportUnsubs.push(this.transport.on('error', event => {
155
276
  this.emitError({ error: event === null || event === void 0 ? void 0 : event.error, phase: 'transport' });
156
- });
157
- this.transport.on('message', event => this.handleRawMessage(event.data));
277
+ }));
278
+ this.transportUnsubs.push(this.transport.on('message', event => this.handleRawMessage(event.data)));
279
+ if (options.keepAlive !== false) {
280
+ this.keepAlive = new keep_alive_loop_1.KeepAliveLoop(Object.assign({ client: this, timerScheduler: this.timerScheduler, onPongTimeout: () => this.closeTransportInternal(1001, 'pong-timeout') }, (options.keepAlive || {})));
281
+ this.keepAlive.start();
282
+ }
283
+ if (options.reconnect !== false) {
284
+ this.reconnect = new reconnect_controller_1.AutoReconnectController(Object.assign({ client: this, timerScheduler: this.timerScheduler }, (options.reconnect || {})));
285
+ }
158
286
  }
159
287
  get state() {
160
288
  return this._state;
@@ -0,0 +1,6 @@
1
+ import type { AuthUpdateInput, AuthUpdateResponse } from '../../lib/auth/types';
2
+ import type { ClientSocketV2 } from '../types';
3
+ export interface AuthGateway {
4
+ update(data: AuthUpdateInput): Promise<AuthUpdateResponse>;
5
+ }
6
+ export declare const createAuthGateway: (client: ClientSocketV2) => AuthGateway;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuthGateway = void 0;
4
+ const create_domain_gateway_1 = require("./create-domain-gateway");
5
+ const createAuthGateway = (client) => {
6
+ const gateway = (0, create_domain_gateway_1.createDomainGateway)('auth', client);
7
+ return {
8
+ update: data => gateway.request('update', data),
9
+ };
10
+ };
11
+ exports.createAuthGateway = createAuthGateway;
@@ -0,0 +1,38 @@
1
+ import type { ChannelCreateInput, ChannelDeleteInput, ChannelGetSelfInput, ChannelInviteInput, ChannelJoinInput, ChannelLeaveInput, ChannelListUserInput, ChannelMineInput, ChannelSyncInput, ChannelSyncProfileInput, ChannelSyncUsersInput, ChannelUnreadsInput, ChannelUpdateInput, ChannelUpdateJoinInput } from '../../lib/channel/types';
2
+ import type { ClientSocketV2 } from '../types';
3
+ /**
4
+ * channel 도메인 게이트웨이.
5
+ * - 모든 응답은 @lemoncloud/chatic-socials-api 소유(pass-through)이므로 제네릭 T로 호출부에서 주입한다.
6
+ * - 미주입 시 unknown(any 아님 — 사용 전 narrowing/캐스팅 강제). 각 메서드 주석의 $socials.<View> 가 실제 응답 타입.
7
+ */
8
+ export interface ChannelGateway {
9
+ /** $socials.ChannelView */
10
+ create<T = unknown>(data: ChannelCreateInput): Promise<T>;
11
+ /** $socials.ChannelView */
12
+ update<T = unknown>(data: ChannelUpdateInput): Promise<T>;
13
+ /** $socials.ChannelView */
14
+ delete<T = unknown>(data: ChannelDeleteInput): Promise<T>;
15
+ /** $socials.JoinView */
16
+ join<T = unknown>(data: ChannelJoinInput): Promise<T>;
17
+ /** $socials.ChannelView */
18
+ leave<T = unknown>(data: ChannelLeaveInput): Promise<T>;
19
+ /** $socials.ChannelView */
20
+ getSelf<T = unknown>(data?: ChannelGetSelfInput | null): Promise<T>;
21
+ /** ListResult<$socials.ChannelView> */
22
+ mine<T = unknown>(data?: ChannelMineInput | null): Promise<T>;
23
+ /** ListResult<$socials.UserView> */
24
+ listUser<T = unknown>(data: ChannelListUserInput): Promise<T>;
25
+ /** $socials.ChannelView */
26
+ invite<T = unknown>(data: ChannelInviteInput): Promise<T>;
27
+ /** $socials.JoinView */
28
+ updateJoin<T = unknown>(data: ChannelUpdateJoinInput): Promise<T>;
29
+ /** $socials.UnreadsSummaryView */
30
+ unreads<T = unknown>(data?: ChannelUnreadsInput | null): Promise<T>;
31
+ /** $socials.ChannelSyncView */
32
+ sync<T = unknown>(data?: ChannelSyncInput | null): Promise<T>;
33
+ /** $socials.ChannelUsersSyncView */
34
+ syncUsers<T = unknown>(data?: ChannelSyncUsersInput | null): Promise<T>;
35
+ /** $socials.SiteProfileSyncView */
36
+ syncProfile<T = unknown>(data?: ChannelSyncProfileInput | null): Promise<T>;
37
+ }
38
+ export declare const createChannelGateway: (client: ClientSocketV2) => ChannelGateway;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createChannelGateway = void 0;
4
+ const create_domain_gateway_1 = require("./create-domain-gateway");
5
+ const createChannelGateway = (client) => {
6
+ const gateway = (0, create_domain_gateway_1.createDomainGateway)('channel', client);
7
+ return {
8
+ create: (data) => gateway.request('create', data),
9
+ update: (data) => gateway.request('update', data),
10
+ delete: (data) => gateway.request('delete', data),
11
+ join: (data) => gateway.request('join', data),
12
+ leave: (data) => gateway.request('leave', data),
13
+ getSelf: (data) => gateway.request('get-self', data !== null && data !== void 0 ? data : null),
14
+ mine: (data) => gateway.request('mine', data !== null && data !== void 0 ? data : null),
15
+ listUser: (data) => gateway.request('list-user', data),
16
+ invite: (data) => gateway.request('invite', data),
17
+ updateJoin: (data) => gateway.request('update-join', data),
18
+ unreads: (data) => gateway.request('unreads', data !== null && data !== void 0 ? data : null),
19
+ sync: (data) => gateway.request('sync', data !== null && data !== void 0 ? data : null),
20
+ syncUsers: (data) => gateway.request('sync-users', data !== null && data !== void 0 ? data : null),
21
+ syncProfile: (data) => gateway.request('sync-site-profile', data !== null && data !== void 0 ? data : null),
22
+ };
23
+ };
24
+ exports.createChannelGateway = createChannelGateway;
@@ -0,0 +1,22 @@
1
+ import type { ChatFeedInput, ChatReadInput, ChatSendInput, ChatUpdateInput, ChatDeleteInput, ChatGetInput } from '../../lib/chat/types';
2
+ import type { ClientSocketV2 } from '../types';
3
+ /**
4
+ * chat 도메인 게이트웨이.
5
+ * - 모든 응답은 @lemoncloud/chatic-socials-api 소유(pass-through)이므로 제네릭 T로 호출부에서 주입한다.
6
+ * - 미주입 시 unknown. 각 메서드 주석의 $socials.<View> 가 실제 응답 타입.
7
+ */
8
+ export interface ChatGateway {
9
+ /** $socials.ChatView */
10
+ send<T = unknown>(data: ChatSendInput): Promise<T>;
11
+ /** $socials.ChatView */
12
+ get<T = unknown>(data: ChatGetInput): Promise<T>;
13
+ /** $socials.JoinView */
14
+ read<T = unknown>(data: ChatReadInput): Promise<T>;
15
+ /** $socials.ChatFeedResult */
16
+ feed<T = unknown>(data: ChatFeedInput): Promise<T>;
17
+ /** $socials.ChatView */
18
+ update<T = unknown>(data: ChatUpdateInput): Promise<T>;
19
+ /** $socials.ChatView */
20
+ delete<T = unknown>(data: ChatDeleteInput): Promise<T>;
21
+ }
22
+ export declare const createChatGateway: (client: ClientSocketV2) => ChatGateway;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createChatGateway = void 0;
4
+ const create_domain_gateway_1 = require("./create-domain-gateway");
5
+ const createChatGateway = (client) => {
6
+ const gateway = (0, create_domain_gateway_1.createDomainGateway)('chat', client);
7
+ return {
8
+ send: (data) => gateway.request('send', data),
9
+ get: (data) => gateway.request('get', data),
10
+ read: (data) => gateway.request('read', data),
11
+ feed: (data) => gateway.request('feed', data),
12
+ update: (data) => gateway.request('update', data),
13
+ delete: (data) => gateway.request('delete', data),
14
+ };
15
+ };
16
+ exports.createChatGateway = createChatGateway;
@@ -0,0 +1,12 @@
1
+ import type { CloudUpdateInput } from '../../lib/cloud/types';
2
+ import type { ClientSocketV2 } from '../types';
3
+ /**
4
+ * cloud 도메인 게이트웨이.
5
+ * - 응답은 @lemoncloud/chatic-backend-api 소유(pass-through)이므로 제네릭 T로 호출부에서 주입한다.
6
+ * - 미주입 시 unknown. 주석의 $backend.<View> 가 실제 응답 타입.
7
+ */
8
+ export interface CloudGateway {
9
+ /** $backend.CloudView */
10
+ update<T = unknown>(data: CloudUpdateInput): Promise<T>;
11
+ }
12
+ export declare const createCloudGateway: (client: ClientSocketV2) => CloudGateway;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCloudGateway = void 0;
4
+ const create_domain_gateway_1 = require("./create-domain-gateway");
5
+ const createCloudGateway = (client) => {
6
+ const gateway = (0, create_domain_gateway_1.createDomainGateway)('cloud', client);
7
+ return {
8
+ update: (data) => gateway.request('update', data),
9
+ };
10
+ };
11
+ exports.createCloudGateway = createCloudGateway;
@@ -0,0 +1,26 @@
1
+ import type { UserGetSiteProfileInput, UserInviteBatchInput, UserInviteInput, UserMakeSiteInput, UserMySiteInput, UserSetSiteProfileInput, UserUpdateProfileInput, UserUpdateSiteInput } from '../../lib/user/types';
2
+ import type { ClientSocketV2 } from '../types';
3
+ /**
4
+ * user 도메인 게이트웨이.
5
+ * - 응답은 @lemoncloud/chatic-socials-api / chatic-backend-api 소유(pass-through)이므로 제네릭 T로 호출부에서 주입한다.
6
+ * - 미주입 시 unknown. 각 메서드 주석의 $socials/$backend.<View> 가 실제 응답 타입(서버가 unknown으로 둔 것은 표기 생략).
7
+ */
8
+ export interface UserGateway {
9
+ /** $socials.ProfileView */
10
+ getSiteProfile<T = unknown>(data?: UserGetSiteProfileInput | null): Promise<T>;
11
+ /** ListResult<$backend.MySiteView> */
12
+ mySite<T = unknown>(data?: UserMySiteInput | null): Promise<T>;
13
+ /** $backend.MySiteView */
14
+ makeSite<T = unknown>(data: UserMakeSiteInput): Promise<T>;
15
+ /** $backend.MyInviteView */
16
+ invite<T = unknown>(data: UserInviteInput): Promise<T>;
17
+ /** ListResult<$backend.MyInviteView> */
18
+ inviteBatch<T = unknown>(data: UserInviteBatchInput): Promise<T>;
19
+ /** $socials.UserView */
20
+ updateProfile<T = unknown>(data: UserUpdateProfileInput): Promise<T>;
21
+ /** $backend.MySiteView */
22
+ updateSite<T = unknown>(data: UserUpdateSiteInput): Promise<T>;
23
+ /** $socials.ProfileView */
24
+ setSiteProfile<T = unknown>(data: UserSetSiteProfileInput): Promise<T>;
25
+ }
26
+ export declare const createUserGateway: (client: ClientSocketV2) => UserGateway;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createUserGateway = void 0;
4
+ const create_domain_gateway_1 = require("./create-domain-gateway");
5
+ const createUserGateway = (client) => {
6
+ const gateway = (0, create_domain_gateway_1.createDomainGateway)('user', client);
7
+ return {
8
+ getSiteProfile: (data) => gateway.request('get-site-profile', data !== null && data !== void 0 ? data : null),
9
+ mySite: (data) => gateway.request('my-site', data !== null && data !== void 0 ? data : null),
10
+ makeSite: (data) => gateway.request('make-site', data),
11
+ invite: (data) => gateway.request('invite', data),
12
+ inviteBatch: (data) => gateway.request('invite-batch', data),
13
+ updateProfile: (data) => gateway.request('update-profile', data),
14
+ updateSite: (data) => gateway.request('update-site', data),
15
+ setSiteProfile: (data) => gateway.request('set-site-profile', data),
16
+ };
17
+ };
18
+ exports.createUserGateway = createUserGateway;
@@ -1,5 +1,6 @@
1
1
  import '../lib/sockets/packets';
2
2
  import '../lib/device/types';
3
+ import '../lib/auth/types';
3
4
  export * from './types';
4
5
  export * from './common';
5
6
  export { createClientSocketV2 as default } from './create-client-socket-v2';
@@ -18,6 +19,15 @@ export * from './create-device-runtime';
18
19
  export * from './plans/device-sync-plan';
19
20
  export * from './gateways/create-domain-gateway';
20
21
  export * from './gateways/device-gateway';
22
+ export * from './gateways/channel-gateway';
23
+ export * from './gateways/auth-gateway';
24
+ export * from './gateways/chat-gateway';
25
+ export * from './gateways/cloud-gateway';
26
+ export * from './gateways/user-gateway';
21
27
  export * from '../lib/types';
22
28
  export * from '../lib/device/types';
23
29
  export * from '../lib/device/contracts';
30
+ export * from '../lib/auth/types';
31
+ export * from '../lib/socket-actions';
32
+ export * from '../lib/socket-inputs';
33
+ export type { AuthUpdateInput, DeviceGetInput, DeviceSaveInput, DeviceSyncInput } from '../lib/socket-inputs';
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.default = void 0;
18
18
  require("../lib/sockets/packets");
19
19
  require("../lib/device/types");
20
+ require("../lib/auth/types");
20
21
  __exportStar(require("./types"), exports);
21
22
  __exportStar(require("./common"), exports);
22
23
  var create_client_socket_v2_1 = require("./create-client-socket-v2");
@@ -36,6 +37,14 @@ __exportStar(require("./create-device-runtime"), exports);
36
37
  __exportStar(require("./plans/device-sync-plan"), exports);
37
38
  __exportStar(require("./gateways/create-domain-gateway"), exports);
38
39
  __exportStar(require("./gateways/device-gateway"), exports);
40
+ __exportStar(require("./gateways/channel-gateway"), exports);
41
+ __exportStar(require("./gateways/auth-gateway"), exports);
42
+ __exportStar(require("./gateways/chat-gateway"), exports);
43
+ __exportStar(require("./gateways/cloud-gateway"), exports);
44
+ __exportStar(require("./gateways/user-gateway"), exports);
39
45
  __exportStar(require("../lib/types"), exports);
40
46
  __exportStar(require("../lib/device/types"), exports);
41
47
  __exportStar(require("../lib/device/contracts"), exports);
48
+ __exportStar(require("../lib/auth/types"), exports);
49
+ __exportStar(require("../lib/socket-actions"), exports);
50
+ __exportStar(require("../lib/socket-inputs"), exports);
@@ -1,16 +1,13 @@
1
- import type { KeepAliveLoopControl, ClientSocketV2, SharedTimerScheduler } from './types';
2
- export interface KeepAliveLoopOptions {
1
+ import type { KeepAliveLoopControl, ClientSocketV2, SharedTimerScheduler, KeepAliveLoopOptionsPartial } from './types';
2
+ export interface KeepAliveLoopOptions extends KeepAliveLoopOptionsPartial {
3
3
  client: ClientSocketV2;
4
- intervalMs?: number;
5
- timeoutMs?: number;
6
- buildPayload?: () => unknown;
7
- mode?: 'send' | 'request';
8
4
  timerScheduler?: SharedTimerScheduler;
9
- timerKey?: string;
10
5
  }
11
6
  export declare class KeepAliveLoop implements KeepAliveLoopControl {
12
7
  private readonly options;
13
8
  private readonly intervalMs;
9
+ private readonly pingTimeoutMs;
10
+ private readonly maxMissedPongs;
14
11
  private readonly mode;
15
12
  private readonly timerScheduler?;
16
13
  private readonly timerKey;
@@ -18,6 +15,7 @@ export declare class KeepAliveLoop implements KeepAliveLoopControl {
18
15
  private timer?;
19
16
  private running;
20
17
  private inFlight?;
18
+ private missedPongs;
21
19
  constructor(options: KeepAliveLoopOptions);
22
20
  start: () => void;
23
21
  stop: () => void;