@lemoncloud/chatic-sockets-lib 0.2.1 → 0.3.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.
- package/dist/client-socket-v2/gateways/channel-gateway.d.ts +1 -1
- package/dist/client-socket-v2/gateways/cloud-gateway.d.ts +7 -1
- package/dist/client-socket-v2/gateways/cloud-gateway.js +3 -0
- package/dist/client-socket-v2/gateways/place-gateway.d.ts +18 -0
- package/dist/client-socket-v2/gateways/place-gateway.js +14 -0
- package/dist/client-socket-v2/gateways/profile-gateway.d.ts +18 -0
- package/dist/client-socket-v2/gateways/profile-gateway.js +14 -0
- package/dist/client-socket-v2/gateways/user-gateway.d.ts +20 -8
- package/dist/client-socket-v2/gateways/user-gateway.js +1 -1
- package/dist/client-socket-v2/index.d.ts +5 -0
- package/dist/client-socket-v2/index.js +5 -0
- package/dist/client-socket-v2/plans/channel-sync-plan.d.ts +33 -0
- package/dist/client-socket-v2/plans/channel-sync-plan.js +66 -0
- package/dist/client-socket-v2/plans/device-sync-plan.d.ts +5 -1
- package/dist/client-socket-v2/plans/device-sync-plan.js +6 -3
- package/dist/client-socket-v2/plans/place-sync-plan.d.ts +33 -0
- package/dist/client-socket-v2/plans/place-sync-plan.js +67 -0
- package/dist/client-socket-v2/plans/profile-sync-plan.d.ts +33 -0
- package/dist/client-socket-v2/plans/profile-sync-plan.js +67 -0
- package/dist/client-socket-v2/socket-runtime.d.ts +5 -1
- package/dist/client-socket-v2/socket-runtime.js +5 -1
- package/dist/client-socket-v2/sync-scheduler.d.ts +15 -1
- package/dist/client-socket-v2/sync-scheduler.js +89 -12
- package/dist/client-socket-v2/types.d.ts +22 -0
- package/dist/lib/channel/types.d.ts +27 -11
- package/dist/lib/cloud/types.d.ts +38 -2
- package/dist/lib/device/contracts.d.ts +2 -0
- package/dist/lib/place/types.d.ts +53 -0
- package/dist/lib/place/types.js +2 -0
- package/dist/lib/profile/types.d.ts +55 -0
- package/dist/lib/profile/types.js +2 -0
- package/dist/lib/socket-actions.d.ts +55 -3
- package/dist/lib/socket-actions.js +44 -2
- package/dist/lib/socket-inputs.d.ts +3 -1
- package/dist/modules/chat/model.d.ts +107 -0
- package/dist/modules/chat/model.js +28 -0
- package/dist/modules/chat/views.d.ts +50 -0
- package/dist/modules/chat/views.js +23 -0
- package/dist/modules/sockets/model.d.ts +204 -0
- package/dist/modules/sockets/model.js +28 -0
- package/dist/modules/sockets/types.d.ts +88 -0
- package/dist/modules/sockets/types.js +78 -0
- package/dist/modules/sockets/views.d.ts +67 -0
- package/dist/modules/sockets/views.js +23 -0
- package/package.json +4 -2
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import type { ClientSocketV2, DomainSyncPlan, SharedTimerScheduler, SyncScheduler, SyncTargetDescriptor } from './types';
|
|
1
|
+
import type { ClientSocketV2, DomainSyncPlan, SharedTimerScheduler, SyncBackoffOptions, SyncFailurePolicy, SyncScheduler, SyncTargetDescriptor } from './types';
|
|
2
|
+
export type { SyncBackoffOptions } from './types';
|
|
2
3
|
export interface SyncSchedulerOptions {
|
|
3
4
|
client: ClientSocketV2;
|
|
4
5
|
plans: DomainSyncPlan<any>[];
|
|
5
6
|
now?: () => number;
|
|
6
7
|
timerScheduler?: SharedTimerScheduler;
|
|
7
8
|
timerPrefix?: string;
|
|
9
|
+
backoff?: SyncBackoffOptions;
|
|
10
|
+
idleBackoff?: SyncBackoffOptions;
|
|
11
|
+
failurePolicy?: SyncFailurePolicy;
|
|
12
|
+
jitterRatio?: number;
|
|
13
|
+
random?: () => number;
|
|
8
14
|
}
|
|
9
15
|
export declare class DomainSyncScheduler implements SyncScheduler {
|
|
10
16
|
private readonly options;
|
|
@@ -14,6 +20,11 @@ export declare class DomainSyncScheduler implements SyncScheduler {
|
|
|
14
20
|
private readonly now;
|
|
15
21
|
private readonly timerScheduler?;
|
|
16
22
|
private readonly timerPrefix;
|
|
23
|
+
private readonly backoff;
|
|
24
|
+
private readonly idleBackoff?;
|
|
25
|
+
private readonly failurePolicy;
|
|
26
|
+
private readonly jitterRatio;
|
|
27
|
+
private readonly random;
|
|
17
28
|
private readonly unsubs;
|
|
18
29
|
constructor(options: SyncSchedulerOptions);
|
|
19
30
|
start: (target: SyncTargetDescriptor) => void;
|
|
@@ -30,7 +41,10 @@ export declare class DomainSyncScheduler implements SyncScheduler {
|
|
|
30
41
|
private clearTimer;
|
|
31
42
|
private scheduleNow;
|
|
32
43
|
private scheduleNext;
|
|
44
|
+
private computeInterval;
|
|
45
|
+
private jitter;
|
|
33
46
|
private toTimerKey;
|
|
34
47
|
private runEntry;
|
|
48
|
+
private handleRunFailure;
|
|
35
49
|
private handleTrigger;
|
|
36
50
|
}
|
|
@@ -10,9 +10,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.DomainSyncScheduler = void 0;
|
|
13
|
+
const defaultClassify = (error) => {
|
|
14
|
+
var _a;
|
|
15
|
+
const msg = error instanceof Error ? error.message : `${error !== null && error !== void 0 ? error : ''}`;
|
|
16
|
+
const code = (_a = /^\s*(\d{3})\b/.exec(msg)) === null || _a === void 0 ? void 0 : _a[1];
|
|
17
|
+
return code === '403' || code === '404' ? 'gone' : 'transient';
|
|
18
|
+
};
|
|
19
|
+
const DEFAULT_IDLE_BACKOFF = { factor: 2, maxMs: 60000 };
|
|
13
20
|
class DomainSyncScheduler {
|
|
14
21
|
constructor(options) {
|
|
15
|
-
var _a, _b;
|
|
22
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
16
23
|
this.options = options;
|
|
17
24
|
this.targets = new Map();
|
|
18
25
|
this.snapshots = new Map();
|
|
@@ -95,12 +102,17 @@ class DomainSyncScheduler {
|
|
|
95
102
|
const key = entry ? entry.plan.getKey(entry.target) : this.resolvePlan(target).getKey(target);
|
|
96
103
|
yield this.runEntry(key);
|
|
97
104
|
}),
|
|
105
|
+
stop: target => this.stop(target),
|
|
98
106
|
});
|
|
99
107
|
this.handleConnected = () => __awaiter(this, void 0, void 0, function* () {
|
|
100
|
-
var
|
|
108
|
+
var _k, _l;
|
|
101
109
|
const ctx = this.buildContext();
|
|
102
110
|
for (const [key, entry] of this.targets.entries()) {
|
|
103
|
-
|
|
111
|
+
// reconnect = fresh start
|
|
112
|
+
entry.failures = 0;
|
|
113
|
+
entry.goneStreak = 0;
|
|
114
|
+
entry.idleStreak = 0;
|
|
115
|
+
yield ((_l = (_k = entry.plan).onConnected) === null || _l === void 0 ? void 0 : _l.call(_k, entry.target, ctx));
|
|
104
116
|
this.scheduleNow(key);
|
|
105
117
|
}
|
|
106
118
|
});
|
|
@@ -133,13 +145,28 @@ class DomainSyncScheduler {
|
|
|
133
145
|
this.clearTimer(entry);
|
|
134
146
|
if (this.options.client.state !== 'connected')
|
|
135
147
|
return;
|
|
136
|
-
const
|
|
148
|
+
const baseMs = (_d = (_a = entry.target.intervalMs) !== null && _a !== void 0 ? _a : (_c = (_b = entry.plan).getIntervalMs) === null || _c === void 0 ? void 0 : _c.call(_b, entry.target)) !== null && _d !== void 0 ? _d : 5000;
|
|
149
|
+
const intervalMs = this.computeInterval(entry, baseMs);
|
|
137
150
|
if (this.timerScheduler) {
|
|
138
151
|
this.timerScheduler.schedule(this.toTimerKey(key), intervalMs, () => this.runEntry(key));
|
|
139
152
|
return;
|
|
140
153
|
}
|
|
141
154
|
entry.timer = setTimeout(() => void this.runEntry(key), intervalMs);
|
|
142
155
|
};
|
|
156
|
+
this.computeInterval = (entry, baseMs) => {
|
|
157
|
+
var _a, _b, _c, _d, _e, _f;
|
|
158
|
+
const failures = (_a = entry.failures) !== null && _a !== void 0 ? _a : 0;
|
|
159
|
+
if (failures > 0)
|
|
160
|
+
return this.jitter(Math.min(baseMs * Math.pow(this.backoff.factor, failures), this.backoff.maxMs));
|
|
161
|
+
const idle = (_c = (_b = entry.plan.idleBackoff) !== null && _b !== void 0 ? _b : this.idleBackoff) !== null && _c !== void 0 ? _c : DEFAULT_IDLE_BACKOFF;
|
|
162
|
+
const idleFactor = Math.max(1, (_d = idle === null || idle === void 0 ? void 0 : idle.factor) !== null && _d !== void 0 ? _d : 1);
|
|
163
|
+
const idleStreak = (_e = entry.idleStreak) !== null && _e !== void 0 ? _e : 0;
|
|
164
|
+
if (idleFactor > 1 && idleStreak > 0) {
|
|
165
|
+
return this.jitter(Math.min(baseMs * Math.pow(idleFactor, idleStreak), (_f = idle === null || idle === void 0 ? void 0 : idle.maxMs) !== null && _f !== void 0 ? _f : 60000));
|
|
166
|
+
}
|
|
167
|
+
return baseMs;
|
|
168
|
+
};
|
|
169
|
+
this.jitter = (ms) => this.jitterRatio > 0 ? Math.max(0, Math.round(ms * (1 + (this.random() * 2 - 1) * this.jitterRatio))) : ms;
|
|
143
170
|
this.toTimerKey = (key) => `${this.timerPrefix}${key}`;
|
|
144
171
|
this.runEntry = (key) => __awaiter(this, void 0, void 0, function* () {
|
|
145
172
|
const entry = this.targets.get(key);
|
|
@@ -148,33 +175,83 @@ class DomainSyncScheduler {
|
|
|
148
175
|
if (entry.inFlight)
|
|
149
176
|
return;
|
|
150
177
|
const ctx = this.buildContext();
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
178
|
+
// no snapshot write during run = unchanged = idle
|
|
179
|
+
const before = this.snapshots.get(key);
|
|
180
|
+
entry.inFlight = Promise.resolve(entry.plan.run(entry.target, ctx)).then(() => {
|
|
181
|
+
var _a;
|
|
154
182
|
entry.inFlight = undefined;
|
|
183
|
+
entry.failures = 0;
|
|
184
|
+
entry.goneStreak = 0;
|
|
185
|
+
const changed = this.snapshots.get(key) !== before;
|
|
186
|
+
entry.idleStreak = changed ? 0 : ((_a = entry.idleStreak) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
155
187
|
this.scheduleNext(key);
|
|
188
|
+
}, error => {
|
|
189
|
+
entry.inFlight = undefined;
|
|
190
|
+
this.handleRunFailure(key, error, ctx);
|
|
156
191
|
});
|
|
157
192
|
yield entry.inFlight;
|
|
158
193
|
});
|
|
194
|
+
this.handleRunFailure = (key, error, ctx) => {
|
|
195
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
196
|
+
const entry = this.targets.get(key);
|
|
197
|
+
if (!entry)
|
|
198
|
+
return;
|
|
199
|
+
const plan = (_a = entry.plan.failurePolicy) !== null && _a !== void 0 ? _a : {};
|
|
200
|
+
const sched = this.failurePolicy;
|
|
201
|
+
const classify = (_c = (_b = plan.classify) !== null && _b !== void 0 ? _b : sched.classify) !== null && _c !== void 0 ? _c : defaultClassify;
|
|
202
|
+
const stopAfter = (_e = (_d = plan.stopAfter) !== null && _d !== void 0 ? _d : sched.stopAfter) !== null && _e !== void 0 ? _e : 2;
|
|
203
|
+
const decide = (_g = (_f = plan.decide) !== null && _f !== void 0 ? _f : sched.decide) !== null && _g !== void 0 ? _g : ((info) => (info.kind === 'gone' && info.goneStreak >= stopAfter ? 'stop' : 'retry'));
|
|
204
|
+
const kind = classify(error, entry.target);
|
|
205
|
+
entry.failures = ((_h = entry.failures) !== null && _h !== void 0 ? _h : 0) + 1;
|
|
206
|
+
entry.goneStreak = kind === 'gone' ? ((_j = entry.goneStreak) !== null && _j !== void 0 ? _j : 0) + 1 : 0;
|
|
207
|
+
entry.idleStreak = 0;
|
|
208
|
+
const info = {
|
|
209
|
+
target: Object.assign({}, entry.target),
|
|
210
|
+
error,
|
|
211
|
+
kind,
|
|
212
|
+
failures: entry.failures,
|
|
213
|
+
goneStreak: entry.goneStreak,
|
|
214
|
+
};
|
|
215
|
+
const decision = decide(info);
|
|
216
|
+
if (decision === 'stop') {
|
|
217
|
+
(_l = (_k = entry.plan).onStopped) === null || _l === void 0 ? void 0 : _l.call(_k, entry.target, info, ctx);
|
|
218
|
+
this.stop(entry.target);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (decision === 'keep') {
|
|
222
|
+
entry.failures = 0;
|
|
223
|
+
entry.goneStreak = 0;
|
|
224
|
+
}
|
|
225
|
+
this.scheduleNext(key);
|
|
226
|
+
};
|
|
159
227
|
this.handleTrigger = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
160
|
-
var
|
|
161
|
-
const type = `${(
|
|
228
|
+
var _m;
|
|
229
|
+
const type = `${(_m = message === null || message === void 0 ? void 0 : message.type) !== null && _m !== void 0 ? _m : ''}`;
|
|
162
230
|
if (!type.endsWith('.sync'))
|
|
163
231
|
return;
|
|
164
|
-
const
|
|
232
|
+
const entries = [...this.targets.entries()];
|
|
165
233
|
const ctx = this.buildContext();
|
|
166
|
-
yield Promise.all(
|
|
234
|
+
yield Promise.all(entries.map(([key, entry]) => __awaiter(this, void 0, void 0, function* () {
|
|
167
235
|
if (!entry.plan.onTrigger)
|
|
168
236
|
return;
|
|
169
237
|
if (!type.startsWith(`${entry.target.type}.`))
|
|
170
238
|
return;
|
|
171
|
-
|
|
239
|
+
// nudge resets idle backoff (best-effort)
|
|
240
|
+
entry.idleStreak = 0;
|
|
241
|
+
yield entry.plan.onTrigger(entry.target, message, ctx).catch(() => undefined);
|
|
242
|
+
if (!entry.inFlight)
|
|
243
|
+
this.scheduleNext(key);
|
|
172
244
|
})));
|
|
173
245
|
});
|
|
174
246
|
this.plans = [...(options.plans || [])];
|
|
175
247
|
this.now = (_a = options.now) !== null && _a !== void 0 ? _a : (() => Date.now());
|
|
176
248
|
this.timerScheduler = options.timerScheduler;
|
|
177
249
|
this.timerPrefix = (_b = options.timerPrefix) !== null && _b !== void 0 ? _b : 'sync:';
|
|
250
|
+
this.backoff = { factor: Math.max(1, (_d = (_c = options.backoff) === null || _c === void 0 ? void 0 : _c.factor) !== null && _d !== void 0 ? _d : 2), maxMs: (_f = (_e = options.backoff) === null || _e === void 0 ? void 0 : _e.maxMs) !== null && _f !== void 0 ? _f : 30000 };
|
|
251
|
+
this.idleBackoff = options.idleBackoff;
|
|
252
|
+
this.failurePolicy = (_g = options.failurePolicy) !== null && _g !== void 0 ? _g : {};
|
|
253
|
+
this.jitterRatio = Math.max(0, (_h = options.jitterRatio) !== null && _h !== void 0 ? _h : 0.1);
|
|
254
|
+
this.random = (_j = options.random) !== null && _j !== void 0 ? _j : Math.random;
|
|
178
255
|
this.unsubs.push(options.client.onState(event => {
|
|
179
256
|
if (event.next === 'connected')
|
|
180
257
|
void this.handleConnected();
|
|
@@ -123,21 +123,43 @@ export interface SyncTargetDescriptor {
|
|
|
123
123
|
intervalMs?: number;
|
|
124
124
|
meta?: Record<string, unknown>;
|
|
125
125
|
}
|
|
126
|
+
export declare type SyncFailureKind = 'gone' | 'transient';
|
|
127
|
+
export declare type SyncFailureDecision = 'stop' | 'keep' | 'retry';
|
|
128
|
+
export interface SyncFailureInfo {
|
|
129
|
+
target: SyncTargetDescriptor;
|
|
130
|
+
error: unknown;
|
|
131
|
+
kind: SyncFailureKind;
|
|
132
|
+
failures: number;
|
|
133
|
+
goneStreak: number;
|
|
134
|
+
}
|
|
135
|
+
export interface SyncFailurePolicy {
|
|
136
|
+
classify?(error: unknown, target: SyncTargetDescriptor): SyncFailureKind;
|
|
137
|
+
decide?(info: SyncFailureInfo): SyncFailureDecision;
|
|
138
|
+
stopAfter?: number;
|
|
139
|
+
}
|
|
140
|
+
export interface SyncBackoffOptions {
|
|
141
|
+
factor?: number;
|
|
142
|
+
maxMs?: number;
|
|
143
|
+
}
|
|
126
144
|
export interface DomainSyncContext {
|
|
127
145
|
client: ClientSocketV2;
|
|
128
146
|
now(): number;
|
|
129
147
|
readSnapshot<T = unknown>(target: SyncTargetDescriptor): T | undefined;
|
|
130
148
|
writeSnapshot<T = unknown>(target: SyncTargetDescriptor, snapshot: T | undefined): void;
|
|
131
149
|
requestResync(target: SyncTargetDescriptor): Promise<void>;
|
|
150
|
+
stop(target: SyncTargetDescriptor): void;
|
|
132
151
|
}
|
|
133
152
|
export interface DomainSyncPlan<TTarget extends SyncTargetDescriptor = SyncTargetDescriptor> {
|
|
134
153
|
readonly domain: string;
|
|
154
|
+
readonly failurePolicy?: SyncFailurePolicy;
|
|
155
|
+
readonly idleBackoff?: SyncBackoffOptions;
|
|
135
156
|
supports(target: SyncTargetDescriptor): target is TTarget;
|
|
136
157
|
getKey(target: TTarget): string;
|
|
137
158
|
getIntervalMs?(target: TTarget): number;
|
|
138
159
|
onConnected?(target: TTarget, ctx: DomainSyncContext): Promise<void> | void;
|
|
139
160
|
run(target: TTarget, ctx: DomainSyncContext): Promise<void>;
|
|
140
161
|
onTrigger?(target: TTarget, message: SocketMessage<any>, ctx: DomainSyncContext): Promise<void>;
|
|
162
|
+
onStopped?(target: TTarget, info: SyncFailureInfo, ctx: DomainSyncContext): void;
|
|
141
163
|
updateLocalState?(target: TTarget, snapshot: unknown, ctx: DomainSyncContext): void;
|
|
142
164
|
}
|
|
143
165
|
export interface SyncScheduler {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { InferSocketRequest, SocketRequestMessage } from '../types';
|
|
2
2
|
import type { ChannelStereo } from '../../modules/chat/types';
|
|
3
|
+
import type { ChannelView } from '../../modules/chat/views';
|
|
3
4
|
export interface ChannelCreateRequestData {
|
|
4
5
|
stereo: ChannelStereo;
|
|
5
6
|
name?: string;
|
|
@@ -42,6 +43,9 @@ export interface ChannelUpdateJoinRequestData {
|
|
|
42
43
|
export interface ChannelSyncRequestData {
|
|
43
44
|
since?: number;
|
|
44
45
|
}
|
|
46
|
+
export interface ChannelGetRequestData {
|
|
47
|
+
id?: string;
|
|
48
|
+
}
|
|
45
49
|
export interface ChannelSyncUsersRequestData {
|
|
46
50
|
channelId: string;
|
|
47
51
|
since?: number;
|
|
@@ -50,7 +54,22 @@ declare module '../types' {
|
|
|
50
54
|
interface SocketPacketRegistry {
|
|
51
55
|
'channel.create': {
|
|
52
56
|
request: ChannelCreateRequestData;
|
|
53
|
-
response:
|
|
57
|
+
response: ChannelView;
|
|
58
|
+
error: null;
|
|
59
|
+
};
|
|
60
|
+
'channel.get': {
|
|
61
|
+
request: ChannelGetRequestData;
|
|
62
|
+
response: ChannelView;
|
|
63
|
+
error: null;
|
|
64
|
+
};
|
|
65
|
+
'channel.update': {
|
|
66
|
+
request: ChannelUpdateRequestData;
|
|
67
|
+
response: ChannelView;
|
|
68
|
+
error: null;
|
|
69
|
+
};
|
|
70
|
+
'channel.delete': {
|
|
71
|
+
request: ChannelByIdRequestData;
|
|
72
|
+
response: ChannelView;
|
|
54
73
|
error: null;
|
|
55
74
|
};
|
|
56
75
|
'channel.join': {
|
|
@@ -83,21 +102,11 @@ declare module '../types' {
|
|
|
83
102
|
response: unknown;
|
|
84
103
|
error: null;
|
|
85
104
|
};
|
|
86
|
-
'channel.update': {
|
|
87
|
-
request: ChannelUpdateRequestData;
|
|
88
|
-
response: unknown;
|
|
89
|
-
error: null;
|
|
90
|
-
};
|
|
91
105
|
'channel.update-join': {
|
|
92
106
|
request: ChannelUpdateJoinRequestData;
|
|
93
107
|
response: unknown;
|
|
94
108
|
error: null;
|
|
95
109
|
};
|
|
96
|
-
'channel.delete': {
|
|
97
|
-
request: ChannelByIdRequestData;
|
|
98
|
-
response: unknown;
|
|
99
|
-
error: null;
|
|
100
|
-
};
|
|
101
110
|
'channel.sync': {
|
|
102
111
|
request: ChannelSyncRequestData;
|
|
103
112
|
response: unknown;
|
|
@@ -155,12 +164,19 @@ export declare type ChannelDeleteRequestMessage = SocketRequestMessage<ChannelDe
|
|
|
155
164
|
export declare type ChannelSyncType = 'channel.sync';
|
|
156
165
|
export declare type ChannelSyncInput = InferSocketRequest<ChannelSyncType>;
|
|
157
166
|
export declare type ChannelSyncRequestMessage = SocketRequestMessage<ChannelSyncType>;
|
|
167
|
+
export declare type ChannelGetType = 'channel.get';
|
|
168
|
+
export declare type ChannelGetInput = InferSocketRequest<ChannelGetType>;
|
|
169
|
+
export declare type ChannelGetRequestMessage = SocketRequestMessage<ChannelGetType>;
|
|
158
170
|
export declare type ChannelSyncUsersType = 'channel.sync-users';
|
|
159
171
|
export declare type ChannelSyncUsersInput = InferSocketRequest<ChannelSyncUsersType>;
|
|
160
172
|
export declare type ChannelSyncUsersRequestMessage = SocketRequestMessage<ChannelSyncUsersType>;
|
|
173
|
+
/** @deprecated use `profile.sync` (ProfileSyncInput). 하위호환용. */
|
|
161
174
|
export declare type ChannelSyncProfileType = 'channel.sync-site-profile';
|
|
175
|
+
/** @deprecated use `profile.sync` (ProfileSyncInput). 하위호환용. */
|
|
162
176
|
export declare type ChannelSyncProfileInput = InferSocketRequest<ChannelSyncProfileType>;
|
|
177
|
+
/** @deprecated use `profile.sync` (ProfileSyncInput). 하위호환용. */
|
|
163
178
|
export declare type ChannelSyncSiteProfileInput = ChannelSyncProfileInput;
|
|
179
|
+
/** @deprecated use `profile.sync`. 하위호환용. */
|
|
164
180
|
export declare type ChannelSyncProfileRequestMessage = SocketRequestMessage<ChannelSyncProfileType>;
|
|
165
181
|
export declare type ChannelUnreadsType = 'channel.unreads';
|
|
166
182
|
export declare type ChannelUnreadsInput = InferSocketRequest<ChannelUnreadsType>;
|
|
@@ -1,18 +1,54 @@
|
|
|
1
1
|
import type { InferSocketRequest, SocketRequestMessage } from '../types';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/** cloud 공통 body 필드 — create/update 양쪽에서 동일하게 사용 */
|
|
3
|
+
export interface CloudBodyData {
|
|
4
4
|
name?: string;
|
|
5
5
|
}
|
|
6
|
+
export declare type CloudCreateRequestData = CloudBodyData;
|
|
7
|
+
export interface CloudGetRequestData {
|
|
8
|
+
id: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CloudUpdateRequestData extends CloudBodyData {
|
|
11
|
+
id?: string;
|
|
12
|
+
/** @deprecated use `id` instead. 하위호환용으로만 유지. */
|
|
13
|
+
cloudId?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CloudDeleteRequestData {
|
|
16
|
+
id: string;
|
|
17
|
+
}
|
|
6
18
|
declare module '../types' {
|
|
7
19
|
interface SocketPacketRegistry {
|
|
20
|
+
'cloud.create': {
|
|
21
|
+
request: CloudCreateRequestData;
|
|
22
|
+
response: unknown;
|
|
23
|
+
error: null;
|
|
24
|
+
};
|
|
25
|
+
'cloud.get': {
|
|
26
|
+
request: CloudGetRequestData;
|
|
27
|
+
response: unknown;
|
|
28
|
+
error: null;
|
|
29
|
+
};
|
|
8
30
|
'cloud.update': {
|
|
9
31
|
request: CloudUpdateRequestData;
|
|
10
32
|
response: unknown;
|
|
11
33
|
error: null;
|
|
12
34
|
};
|
|
35
|
+
'cloud.delete': {
|
|
36
|
+
request: CloudDeleteRequestData;
|
|
37
|
+
response: unknown;
|
|
38
|
+
error: null;
|
|
39
|
+
};
|
|
13
40
|
}
|
|
14
41
|
}
|
|
42
|
+
export declare type CloudCreateType = 'cloud.create';
|
|
43
|
+
export declare type CloudCreateInput = InferSocketRequest<CloudCreateType>;
|
|
44
|
+
export declare type CloudCreateRequestMessage = SocketRequestMessage<CloudCreateType>;
|
|
45
|
+
export declare type CloudGetType = 'cloud.get';
|
|
46
|
+
export declare type CloudGetInput = InferSocketRequest<CloudGetType>;
|
|
47
|
+
export declare type CloudGetRequestMessage = SocketRequestMessage<CloudGetType>;
|
|
15
48
|
export declare type CloudUpdateType = 'cloud.update';
|
|
16
49
|
export declare type CloudUpdateInput = InferSocketRequest<CloudUpdateType>;
|
|
17
50
|
export declare type UpdateCloudInput = CloudUpdateInput;
|
|
18
51
|
export declare type CloudUpdateRequestMessage = SocketRequestMessage<CloudUpdateType>;
|
|
52
|
+
export declare type CloudDeleteType = 'cloud.delete';
|
|
53
|
+
export declare type CloudDeleteInput = InferSocketRequest<CloudDeleteType>;
|
|
54
|
+
export declare type CloudDeleteRequestMessage = SocketRequestMessage<CloudDeleteType>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { InferSocketRequest, SocketRequestMessage } from '../types';
|
|
2
|
+
/** place(site) 공통 body 필드 — create/update 양쪽에서 동일하게 사용 */
|
|
3
|
+
export interface PlaceBodyData {
|
|
4
|
+
name?: string;
|
|
5
|
+
stereo?: string;
|
|
6
|
+
thumbnail?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare type PlaceCreateRequestData = PlaceBodyData;
|
|
9
|
+
export interface PlaceGetRequestData {
|
|
10
|
+
id: string;
|
|
11
|
+
}
|
|
12
|
+
export interface PlaceUpdateRequestData extends PlaceBodyData {
|
|
13
|
+
id?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PlaceDeleteRequestData {
|
|
16
|
+
id: string;
|
|
17
|
+
}
|
|
18
|
+
declare module '../types' {
|
|
19
|
+
interface SocketPacketRegistry {
|
|
20
|
+
'place.create': {
|
|
21
|
+
request: PlaceCreateRequestData;
|
|
22
|
+
response: unknown;
|
|
23
|
+
error: null;
|
|
24
|
+
};
|
|
25
|
+
'place.get': {
|
|
26
|
+
request: PlaceGetRequestData;
|
|
27
|
+
response: unknown;
|
|
28
|
+
error: null;
|
|
29
|
+
};
|
|
30
|
+
'place.update': {
|
|
31
|
+
request: PlaceUpdateRequestData;
|
|
32
|
+
response: unknown;
|
|
33
|
+
error: null;
|
|
34
|
+
};
|
|
35
|
+
'place.delete': {
|
|
36
|
+
request: PlaceDeleteRequestData;
|
|
37
|
+
response: unknown;
|
|
38
|
+
error: null;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export declare type PlaceCreateType = 'place.create';
|
|
43
|
+
export declare type PlaceCreateInput = InferSocketRequest<PlaceCreateType>;
|
|
44
|
+
export declare type PlaceCreateRequestMessage = SocketRequestMessage<PlaceCreateType>;
|
|
45
|
+
export declare type PlaceGetType = 'place.get';
|
|
46
|
+
export declare type PlaceGetInput = InferSocketRequest<PlaceGetType>;
|
|
47
|
+
export declare type PlaceGetRequestMessage = SocketRequestMessage<PlaceGetType>;
|
|
48
|
+
export declare type PlaceUpdateType = 'place.update';
|
|
49
|
+
export declare type PlaceUpdateInput = InferSocketRequest<PlaceUpdateType>;
|
|
50
|
+
export declare type PlaceUpdateRequestMessage = SocketRequestMessage<PlaceUpdateType>;
|
|
51
|
+
export declare type PlaceDeleteType = 'place.delete';
|
|
52
|
+
export declare type PlaceDeleteInput = InferSocketRequest<PlaceDeleteType>;
|
|
53
|
+
export declare type PlaceDeleteRequestMessage = SocketRequestMessage<PlaceDeleteType>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { InferSocketRequest, SocketRequestMessage } from '../types';
|
|
2
|
+
/** profile 단건 조회 — id 기반 (ProfileView.id = `siteId@userId`) */
|
|
3
|
+
export interface ProfileGetRequestData {
|
|
4
|
+
id: string;
|
|
5
|
+
}
|
|
6
|
+
/** profile(site-profile) set body 필드 — socials ProfileBody pass-through */
|
|
7
|
+
export interface ProfileSetRequestData {
|
|
8
|
+
id?: string;
|
|
9
|
+
userId?: string;
|
|
10
|
+
siteId?: string;
|
|
11
|
+
nick?: string;
|
|
12
|
+
thumbnail?: string;
|
|
13
|
+
active?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
/** profile 동기화 — 사이트 수준 멀티프로필 delta(since cursor). 누락 시 전체 */
|
|
17
|
+
export interface ProfileSyncRequestData {
|
|
18
|
+
since?: number;
|
|
19
|
+
}
|
|
20
|
+
declare module '../types' {
|
|
21
|
+
interface SocketPacketRegistry {
|
|
22
|
+
'profile.get': {
|
|
23
|
+
request: ProfileGetRequestData;
|
|
24
|
+
response: unknown;
|
|
25
|
+
error: null;
|
|
26
|
+
};
|
|
27
|
+
'profile.get-mine': {
|
|
28
|
+
request: Record<string, never>;
|
|
29
|
+
response: unknown;
|
|
30
|
+
error: null;
|
|
31
|
+
};
|
|
32
|
+
'profile.set': {
|
|
33
|
+
request: ProfileSetRequestData;
|
|
34
|
+
response: unknown;
|
|
35
|
+
error: null;
|
|
36
|
+
};
|
|
37
|
+
'profile.sync': {
|
|
38
|
+
request: ProfileSyncRequestData;
|
|
39
|
+
response: unknown;
|
|
40
|
+
error: null;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export declare type ProfileGetType = 'profile.get';
|
|
45
|
+
export declare type ProfileGetInput = InferSocketRequest<ProfileGetType>;
|
|
46
|
+
export declare type ProfileGetRequestMessage = SocketRequestMessage<ProfileGetType>;
|
|
47
|
+
export declare type ProfileGetMineType = 'profile.get-mine';
|
|
48
|
+
export declare type ProfileGetMineInput = InferSocketRequest<ProfileGetMineType>;
|
|
49
|
+
export declare type ProfileGetMineRequestMessage = SocketRequestMessage<ProfileGetMineType>;
|
|
50
|
+
export declare type ProfileSetType = 'profile.set';
|
|
51
|
+
export declare type ProfileSetInput = InferSocketRequest<ProfileSetType>;
|
|
52
|
+
export declare type ProfileSetRequestMessage = SocketRequestMessage<ProfileSetType>;
|
|
53
|
+
export declare type ProfileSyncType = 'profile.sync';
|
|
54
|
+
export declare type ProfileSyncInput = InferSocketRequest<ProfileSyncType>;
|
|
55
|
+
export declare type ProfileSyncRequestMessage = SocketRequestMessage<ProfileSyncType>;
|
|
@@ -30,6 +30,10 @@ export declare const SocketActionTypeLUT: {
|
|
|
30
30
|
readonly chat: "chat";
|
|
31
31
|
/** user - user/site profile operations */
|
|
32
32
|
readonly user: "user";
|
|
33
|
+
/** place - place(site) CRUD operations */
|
|
34
|
+
readonly place: "place";
|
|
35
|
+
/** profile - site profile operations */
|
|
36
|
+
readonly profile: "profile";
|
|
33
37
|
/** cloud - cloud profile operations */
|
|
34
38
|
readonly cloud: "cloud";
|
|
35
39
|
};
|
|
@@ -109,9 +113,11 @@ export declare const SocketActionTypeLUT: {
|
|
|
109
113
|
readonly delete: "delete";
|
|
110
114
|
/** sync - synchronize channel list/state */
|
|
111
115
|
readonly sync: "sync";
|
|
116
|
+
/** read - pull authoritative single-channel item */
|
|
117
|
+
readonly read: "read";
|
|
112
118
|
/** sync-users - synchronize channel users */
|
|
113
119
|
readonly 'sync-users': "sync-users";
|
|
114
|
-
/** sync
|
|
120
|
+
/** @deprecated use `profile.sync`. synchronize related site profile (하위호환) */
|
|
115
121
|
readonly 'sync-site-profile': "sync-site-profile";
|
|
116
122
|
/** unreads - get unread message summary */
|
|
117
123
|
readonly unreads: "unreads";
|
|
@@ -152,14 +158,50 @@ export declare const SocketActionTypeLUT: {
|
|
|
152
158
|
/** set-site-profile - set site profile */
|
|
153
159
|
readonly 'set-site-profile': "set-site-profile";
|
|
154
160
|
};
|
|
161
|
+
/**
|
|
162
|
+
* PlaceActionType
|
|
163
|
+
* - place(site) 도메인 액션
|
|
164
|
+
*/
|
|
165
|
+
readonly PlaceActionType: {
|
|
166
|
+
readonly '': "";
|
|
167
|
+
/** create - create a place(site) */
|
|
168
|
+
readonly create: "create";
|
|
169
|
+
/** get - get a place(site) */
|
|
170
|
+
readonly get: "get";
|
|
171
|
+
/** update - update a place(site) */
|
|
172
|
+
readonly update: "update";
|
|
173
|
+
/** delete - delete a place(site) */
|
|
174
|
+
readonly delete: "delete";
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* ProfileActionType
|
|
178
|
+
* - profile(site-profile) 도메인 액션
|
|
179
|
+
*/
|
|
180
|
+
readonly ProfileActionType: {
|
|
181
|
+
readonly '': "";
|
|
182
|
+
/** get - get site profile by id */
|
|
183
|
+
readonly get: "get";
|
|
184
|
+
/** get-mine - get current session's site profile */
|
|
185
|
+
readonly 'get-mine': "get-mine";
|
|
186
|
+
/** set - set site profile */
|
|
187
|
+
readonly set: "set";
|
|
188
|
+
/** sync - synchronize site multi-profiles (delta since cursor) */
|
|
189
|
+
readonly sync: "sync";
|
|
190
|
+
};
|
|
155
191
|
/**
|
|
156
192
|
* CloudActionType
|
|
157
193
|
* - cloud 도메인 액션
|
|
158
194
|
*/
|
|
159
195
|
readonly CloudActionType: {
|
|
160
196
|
readonly '': "";
|
|
161
|
-
/**
|
|
197
|
+
/** create - create a cloud (미구현/500) */
|
|
198
|
+
readonly create: "create";
|
|
199
|
+
/** get - get a cloud */
|
|
200
|
+
readonly get: "get";
|
|
201
|
+
/** update - update a cloud */
|
|
162
202
|
readonly update: "update";
|
|
203
|
+
/** delete - delete a cloud */
|
|
204
|
+
readonly delete: "delete";
|
|
163
205
|
};
|
|
164
206
|
};
|
|
165
207
|
declare type SocketActionKeyOf<T> = Extract<keyof T, string>;
|
|
@@ -196,6 +238,14 @@ export declare type SocketChatActionType = SocketActionKeyOf<typeof SocketAction
|
|
|
196
238
|
* type: `SocketUserActionType`
|
|
197
239
|
*/
|
|
198
240
|
export declare type SocketUserActionType = SocketActionKeyOf<typeof SocketActionTypeLUT.UserActionType>;
|
|
241
|
+
/**
|
|
242
|
+
* type: `SocketPlaceActionType`
|
|
243
|
+
*/
|
|
244
|
+
export declare type SocketPlaceActionType = SocketActionKeyOf<typeof SocketActionTypeLUT.PlaceActionType>;
|
|
245
|
+
/**
|
|
246
|
+
* type: `SocketProfileActionType`
|
|
247
|
+
*/
|
|
248
|
+
export declare type SocketProfileActionType = SocketActionKeyOf<typeof SocketActionTypeLUT.ProfileActionType>;
|
|
199
249
|
/**
|
|
200
250
|
* type: `SocketCloudActionType`
|
|
201
251
|
*/
|
|
@@ -203,7 +253,7 @@ export declare type SocketCloudActionType = SocketActionKeyOf<typeof SocketActio
|
|
|
203
253
|
/**
|
|
204
254
|
* type: `SocketActionType`
|
|
205
255
|
*/
|
|
206
|
-
export declare type SocketActionType = SocketSystemActionType | SocketSocketsActionType | SocketDeviceActionType | SocketAuthActionType | SocketChannelActionType | SocketChatActionType | SocketUserActionType | SocketCloudActionType;
|
|
256
|
+
export declare type SocketActionType = SocketSystemActionType | SocketSocketsActionType | SocketDeviceActionType | SocketAuthActionType | SocketChannelActionType | SocketChatActionType | SocketUserActionType | SocketPlaceActionType | SocketProfileActionType | SocketCloudActionType;
|
|
207
257
|
/**
|
|
208
258
|
* interface: `SocketActionTypeMap`
|
|
209
259
|
* - domain to action type map
|
|
@@ -216,6 +266,8 @@ export interface SocketActionTypeMap {
|
|
|
216
266
|
channel: SocketChannelActionType;
|
|
217
267
|
chat: SocketChatActionType;
|
|
218
268
|
user: SocketUserActionType;
|
|
269
|
+
place: SocketPlaceActionType;
|
|
270
|
+
profile: SocketProfileActionType;
|
|
219
271
|
cloud: SocketCloudActionType;
|
|
220
272
|
}
|
|
221
273
|
/**
|