@luckystack/sync 0.1.9 → 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.
- package/CHANGELOG.md +14 -14
- package/CLAUDE.md +122 -104
- package/LICENSE +21 -21
- package/README.md +155 -155
- package/dist/client.d.ts +3 -1
- package/dist/client.js +235 -87
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +1251 -635
- package/dist/index.js.map +1 -1
- package/docs/error-states.md +5 -4
- package/docs/server-vs-client-handlers.md +2 -0
- package/docs/streaming.md +349 -349
- package/package.json +5 -5
package/dist/client.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StreamPayload, statusContent, BaseSessionLayout, SyncTypeMap } from '@luckystack/core/client';
|
|
2
2
|
import { Dispatch, SetStateAction, RefObject } from 'react';
|
|
3
|
+
import { Socket } from 'socket.io-client';
|
|
3
4
|
|
|
4
5
|
type SyncRequestStreamEvent<T extends StreamPayload = StreamPayload> = T;
|
|
5
6
|
type SyncRouteStreamEvent<T extends StreamPayload = StreamPayload> = T;
|
|
@@ -114,6 +115,7 @@ declare const useSyncEventTrigger: () => {
|
|
|
114
115
|
triggerSyncEvent: (name: string, clientOutput?: unknown, serverOutput?: unknown) => void;
|
|
115
116
|
triggerSyncStreamEvent: (name: string, stream: SyncRouteStreamEvent) => void;
|
|
116
117
|
};
|
|
118
|
+
declare const attachSyncReceiver: (socketInstance: Socket) => void;
|
|
117
119
|
type SocketStatusSetter = Dispatch<SetStateAction<{
|
|
118
120
|
self: statusContent;
|
|
119
121
|
[userId: string]: statusContent;
|
|
@@ -123,4 +125,4 @@ declare const initSyncRequest: ({ setSocketStatus, sessionRef }: {
|
|
|
123
125
|
sessionRef: RefObject<BaseSessionLayout | null> | null;
|
|
124
126
|
}) => Promise<void>;
|
|
125
127
|
|
|
126
|
-
export { type SyncRequestStreamEvent, type SyncRouteStreamEvent, initSyncRequest, syncRequest, useSyncEventTrigger, useSyncEvents };
|
|
128
|
+
export { type SyncRequestStreamEvent, type SyncRouteStreamEvent, attachSyncReceiver, initSyncRequest, syncRequest, useSyncEventTrigger, useSyncEvents };
|
package/dist/client.js
CHANGED
|
@@ -41,7 +41,8 @@ var getStreamCallbacksForRoute = (route) => {
|
|
|
41
41
|
var triggerSyncCallbacks = (name, clientOutput, serverOutput) => {
|
|
42
42
|
const callbacks = syncEvents[name] ?? [];
|
|
43
43
|
if (callbacks.length === 0) {
|
|
44
|
-
|
|
44
|
+
const streamCallbacks = syncStreamEvents[name] ?? [];
|
|
45
|
+
if (streamCallbacks.length === 0 && shouldLogDev()) {
|
|
45
46
|
getLogger().warn(`Sync event ${name} has no registered callback on this page`);
|
|
46
47
|
}
|
|
47
48
|
return;
|
|
@@ -81,6 +82,82 @@ var normalizeSyncError = ({
|
|
|
81
82
|
httpStatus: normalized.httpStatus
|
|
82
83
|
};
|
|
83
84
|
};
|
|
85
|
+
var prepareSyncRequest = async ({
|
|
86
|
+
name,
|
|
87
|
+
version,
|
|
88
|
+
receiver,
|
|
89
|
+
payloadData
|
|
90
|
+
}) => {
|
|
91
|
+
if (!name || typeof name !== "string") {
|
|
92
|
+
if (shouldLogDev()) {
|
|
93
|
+
getLogger().error("Invalid name for syncRequest");
|
|
94
|
+
}
|
|
95
|
+
if (shouldNotifyDev()) {
|
|
96
|
+
notify.error({ key: "sync.invalidName" });
|
|
97
|
+
}
|
|
98
|
+
return { ok: false, error: normalizeSyncError({
|
|
99
|
+
response: { status: "error", errorCode: "sync.invalidName" },
|
|
100
|
+
fallbackErrorCode: "sync.invalidName"
|
|
101
|
+
}) };
|
|
102
|
+
}
|
|
103
|
+
const parsedRoute = parseServiceRouteName(name);
|
|
104
|
+
if (parsedRoute.status === "error") {
|
|
105
|
+
if (shouldLogDev()) {
|
|
106
|
+
getLogger().error(`[syncRequest] Invalid service route name '${name}'`, void 0, { reason: parsedRoute.reason });
|
|
107
|
+
}
|
|
108
|
+
if (shouldNotifyDev()) {
|
|
109
|
+
notify.error({ key: "routing.invalidServiceRouteName" });
|
|
110
|
+
}
|
|
111
|
+
return { ok: false, error: normalizeSyncError({
|
|
112
|
+
response: {
|
|
113
|
+
status: "error",
|
|
114
|
+
errorCode: "routing.invalidServiceRouteName",
|
|
115
|
+
errorParams: [{ key: "name", value: name }]
|
|
116
|
+
},
|
|
117
|
+
fallbackErrorCode: "routing.invalidServiceRouteName"
|
|
118
|
+
}) };
|
|
119
|
+
}
|
|
120
|
+
const sanitizedName = parsedRoute.normalizedRouteName;
|
|
121
|
+
const data = payloadData && typeof payloadData === "object" ? payloadData : {};
|
|
122
|
+
if (!version || typeof version !== "string") {
|
|
123
|
+
if (shouldLogDev()) {
|
|
124
|
+
getLogger().error("Invalid version for syncRequest");
|
|
125
|
+
}
|
|
126
|
+
if (shouldNotifyDev()) {
|
|
127
|
+
notify.error({ key: "sync.invalidVersion" });
|
|
128
|
+
}
|
|
129
|
+
return { ok: false, error: normalizeSyncError({
|
|
130
|
+
response: { status: "error", errorCode: "sync.invalidVersion" },
|
|
131
|
+
fallbackErrorCode: "sync.invalidVersion"
|
|
132
|
+
}) };
|
|
133
|
+
}
|
|
134
|
+
const normalizedReceiver = typeof receiver === "string" ? receiver.trim() : "";
|
|
135
|
+
if (!normalizedReceiver) {
|
|
136
|
+
if (shouldLogDev()) {
|
|
137
|
+
getLogger().error("You need to provide a receiver for syncRequest, this can be either 'all' to trigger all sockets which we do not recommend or it can be any value such as a code e.g 'Ag2cg4'. this works together with the joinRoom and leaveRoom function");
|
|
138
|
+
}
|
|
139
|
+
if (shouldNotifyDev()) {
|
|
140
|
+
notify.error({ key: "sync.missingReceiver" });
|
|
141
|
+
}
|
|
142
|
+
return { ok: false, error: normalizeSyncError({
|
|
143
|
+
response: { status: "error", errorCode: "sync.missingReceiver" },
|
|
144
|
+
fallbackErrorCode: "sync.missingReceiver"
|
|
145
|
+
}) };
|
|
146
|
+
}
|
|
147
|
+
if (!await waitForSocket()) {
|
|
148
|
+
return { ok: false, error: normalizeSyncError({
|
|
149
|
+
response: { status: "error", errorCode: "sync.ioUnavailable" },
|
|
150
|
+
fallbackErrorCode: "sync.ioUnavailable"
|
|
151
|
+
}) };
|
|
152
|
+
}
|
|
153
|
+
if (!socket) {
|
|
154
|
+
return { ok: false, error: normalizeSyncError({
|
|
155
|
+
response: { status: "error", errorCode: "sync.ioUnavailable" },
|
|
156
|
+
fallbackErrorCode: "sync.ioUnavailable"
|
|
157
|
+
}) };
|
|
158
|
+
}
|
|
159
|
+
return { ok: true, sanitizedName, version, data, normalizedReceiver };
|
|
160
|
+
};
|
|
84
161
|
var syncRequestInternal = (params) => {
|
|
85
162
|
const runtimeParams = params;
|
|
86
163
|
const { name, version, receiver, ignoreSelf, onStream, offlineDropPolicy, signal: externalSignal } = runtimeParams;
|
|
@@ -94,85 +171,26 @@ var syncRequestInternal = (params) => {
|
|
|
94
171
|
}));
|
|
95
172
|
return;
|
|
96
173
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
if (shouldNotifyDev()) {
|
|
102
|
-
notify.error({ key: "sync.invalidName" });
|
|
103
|
-
}
|
|
104
|
-
resolve(normalizeSyncError({
|
|
105
|
-
response: { status: "error", errorCode: "sync.invalidName" },
|
|
106
|
-
fallbackErrorCode: "sync.invalidName"
|
|
107
|
-
}));
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const parsedRoute = parseServiceRouteName(name);
|
|
111
|
-
if (parsedRoute.status === "error") {
|
|
112
|
-
if (shouldLogDev()) {
|
|
113
|
-
getLogger().error(`[syncRequest] Invalid service route name '${name}'`, void 0, { reason: parsedRoute.reason });
|
|
114
|
-
}
|
|
115
|
-
if (shouldNotifyDev()) {
|
|
116
|
-
notify.error({ key: "routing.invalidServiceRouteName" });
|
|
117
|
-
}
|
|
118
|
-
resolve(normalizeSyncError({
|
|
119
|
-
response: {
|
|
120
|
-
status: "error",
|
|
121
|
-
errorCode: "routing.invalidServiceRouteName",
|
|
122
|
-
errorParams: [{ key: "name", value: name }]
|
|
123
|
-
},
|
|
124
|
-
fallbackErrorCode: "routing.invalidServiceRouteName"
|
|
125
|
-
}));
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
const sanitizedName = parsedRoute.normalizedRouteName;
|
|
129
|
-
const data = payloadData && typeof payloadData === "object" ? payloadData : {};
|
|
130
|
-
if (!version || typeof version !== "string") {
|
|
131
|
-
if (shouldLogDev()) {
|
|
132
|
-
getLogger().error("Invalid version for syncRequest");
|
|
133
|
-
}
|
|
134
|
-
if (shouldNotifyDev()) {
|
|
135
|
-
notify.error({ key: "sync.invalidVersion" });
|
|
136
|
-
}
|
|
137
|
-
resolve(normalizeSyncError({
|
|
138
|
-
response: { status: "error", errorCode: "sync.invalidVersion" },
|
|
139
|
-
fallbackErrorCode: "sync.invalidVersion"
|
|
140
|
-
}));
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const normalizedReceiver = typeof receiver === "string" ? receiver.trim() : "";
|
|
144
|
-
if (!normalizedReceiver) {
|
|
145
|
-
if (shouldLogDev()) {
|
|
146
|
-
getLogger().error("You need to provide a receiver for syncRequest, this can be either 'all' to trigger all sockets which we do not recommend or it can be any value such as a code e.g 'Ag2cg4'. this works together with the joinRoom and leaveRoom function");
|
|
147
|
-
}
|
|
148
|
-
if (shouldNotifyDev()) {
|
|
149
|
-
notify.error({ key: "sync.missingReceiver" });
|
|
150
|
-
}
|
|
151
|
-
resolve(normalizeSyncError({
|
|
152
|
-
response: { status: "error", errorCode: "sync.missingReceiver" },
|
|
153
|
-
fallbackErrorCode: "sync.missingReceiver"
|
|
154
|
-
}));
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (!await waitForSocket()) {
|
|
158
|
-
resolve(normalizeSyncError({
|
|
159
|
-
response: { status: "error", errorCode: "sync.ioUnavailable" },
|
|
160
|
-
fallbackErrorCode: "sync.ioUnavailable"
|
|
161
|
-
}));
|
|
174
|
+
const prepared = await prepareSyncRequest({ name, version, receiver, payloadData });
|
|
175
|
+
if (!prepared.ok) {
|
|
176
|
+
resolve(prepared.error);
|
|
162
177
|
return;
|
|
163
178
|
}
|
|
164
|
-
|
|
179
|
+
const { sanitizedName, version: resolvedVersion, data, normalizedReceiver } = prepared;
|
|
180
|
+
const activeSocket = socket;
|
|
181
|
+
if (!activeSocket) {
|
|
165
182
|
resolve(normalizeSyncError({
|
|
166
183
|
response: { status: "error", errorCode: "sync.ioUnavailable" },
|
|
167
184
|
fallbackErrorCode: "sync.ioUnavailable"
|
|
168
185
|
}));
|
|
169
186
|
return;
|
|
170
187
|
}
|
|
171
|
-
const fullName = `sync/${sanitizedName}/${
|
|
188
|
+
const fullName = `sync/${sanitizedName}/${resolvedVersion}`;
|
|
172
189
|
let queueId = null;
|
|
173
190
|
const runRequest = (socketInstance) => {
|
|
174
191
|
if (!canSendNow(socketInstance)) {
|
|
175
192
|
queueId ??= createQueueId();
|
|
193
|
+
let suppressOnDrop = true;
|
|
176
194
|
const enqueued = enqueueSyncRequest({
|
|
177
195
|
id: queueId,
|
|
178
196
|
key: fullName,
|
|
@@ -180,8 +198,23 @@ var syncRequestInternal = (params) => {
|
|
|
180
198
|
runRequest(s);
|
|
181
199
|
},
|
|
182
200
|
createdAt: Date.now(),
|
|
183
|
-
dropPolicy: offlineDropPolicy
|
|
201
|
+
dropPolicy: offlineDropPolicy,
|
|
202
|
+
//? SYNC-09 — settle the awaiting caller when this QUEUED request is
|
|
203
|
+
//? later EVICTED (drop-oldest by a future enqueue / age expiry)
|
|
204
|
+
//? instead of ever running. Without it the promise would hang
|
|
205
|
+
//? forever, since `run` is the only thing that could otherwise
|
|
206
|
+
//? resolve it. The default `offlineQueue.dropPolicy` is
|
|
207
|
+
//? `'drop-oldest'`, so async eviction is the NORMAL overflow path
|
|
208
|
+
//? for high-churn syncs (cursor moves), not an edge case.
|
|
209
|
+
onDrop: (reason) => {
|
|
210
|
+
if (suppressOnDrop) return;
|
|
211
|
+
resolve(normalizeSyncError({
|
|
212
|
+
response: { status: "error", errorCode: "offline.dropped", errorParams: [{ key: "reason", value: reason }] },
|
|
213
|
+
fallbackErrorCode: "offline.dropped"
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
184
216
|
});
|
|
217
|
+
suppressOnDrop = false;
|
|
185
218
|
if (!enqueued) {
|
|
186
219
|
resolve(normalizeSyncError({
|
|
187
220
|
response: { status: "error", errorCode: "offline.queueFull" },
|
|
@@ -192,30 +225,46 @@ var syncRequestInternal = (params) => {
|
|
|
192
225
|
}
|
|
193
226
|
const tempIndex = incrementResponseIndex();
|
|
194
227
|
let cleanupProgressListener = null;
|
|
228
|
+
let responseTimeout = null;
|
|
229
|
+
const clearResponseTimeout = () => {
|
|
230
|
+
if (responseTimeout) {
|
|
231
|
+
clearTimeout(responseTimeout);
|
|
232
|
+
responseTimeout = null;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
195
235
|
if (shouldLogDev()) {
|
|
196
236
|
getLogger().debug(`Client Sync Request(${String(tempIndex)})`, { syncName: sanitizedName, data, receiver: normalizedReceiver, ignoreSelf });
|
|
197
237
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
|
|
238
|
+
let serverCancelId = null;
|
|
239
|
+
const progressEventName = buildSyncProgressEventName(tempIndex);
|
|
240
|
+
const progressListener = (streamPayload) => {
|
|
241
|
+
if (typeof streamPayload.__cancelId === "string") {
|
|
242
|
+
serverCancelId = streamPayload.__cancelId;
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (typeof onStream !== "function") return;
|
|
246
|
+
if (shouldLogStream()) {
|
|
247
|
+
getLogger().debug(`Server Sync Stream(${String(tempIndex)})`, { syncName: sanitizedName, streamPayload });
|
|
248
|
+
}
|
|
249
|
+
onStream(streamPayload);
|
|
250
|
+
};
|
|
251
|
+
socketInstance.on(progressEventName, progressListener);
|
|
252
|
+
cleanupProgressListener = () => {
|
|
253
|
+
socketInstance.off(progressEventName, progressListener);
|
|
254
|
+
};
|
|
255
|
+
const syncCb = `${sanitizedName}/${resolvedVersion}`;
|
|
212
256
|
socketInstance.emit(socketEventNames.sync, { name: fullName, data, cb: syncCb, receiver: normalizedReceiver, responseIndex: tempIndex, ignoreSelf });
|
|
257
|
+
const responseEventName = buildSyncResponseEventName(tempIndex);
|
|
258
|
+
let cleanupResponseListener = null;
|
|
213
259
|
let cleanupExternalAbort = null;
|
|
214
260
|
if (externalSignal) {
|
|
215
261
|
const externalAbortHandler = () => {
|
|
216
|
-
|
|
262
|
+
clearResponseTimeout();
|
|
263
|
+
socketInstance.emit(socketEventNames.syncCancel, { cb: serverCancelId ?? syncCb });
|
|
217
264
|
cleanupProgressListener?.();
|
|
218
265
|
cleanupProgressListener = null;
|
|
266
|
+
cleanupResponseListener?.();
|
|
267
|
+
cleanupResponseListener = null;
|
|
219
268
|
cleanupExternalAbort?.();
|
|
220
269
|
cleanupExternalAbort = null;
|
|
221
270
|
resolve(normalizeSyncError({
|
|
@@ -228,8 +277,30 @@ var syncRequestInternal = (params) => {
|
|
|
228
277
|
externalSignal.removeEventListener("abort", externalAbortHandler);
|
|
229
278
|
};
|
|
230
279
|
}
|
|
231
|
-
|
|
280
|
+
const effectiveTimeoutMs = getProjectConfig().sync.requestTimeoutMs;
|
|
281
|
+
if (typeof effectiveTimeoutMs === "number" && effectiveTimeoutMs > 0) {
|
|
282
|
+
responseTimeout = setTimeout(() => {
|
|
283
|
+
responseTimeout = null;
|
|
284
|
+
cleanupProgressListener?.();
|
|
285
|
+
cleanupProgressListener = null;
|
|
286
|
+
cleanupResponseListener?.();
|
|
287
|
+
cleanupResponseListener = null;
|
|
288
|
+
cleanupExternalAbort?.();
|
|
289
|
+
cleanupExternalAbort = null;
|
|
290
|
+
if (shouldLogDev()) {
|
|
291
|
+
getLogger().error(`Sync ${sanitizedName} timed out`, void 0, { responseIndex: tempIndex });
|
|
292
|
+
}
|
|
293
|
+
resolve(normalizeSyncError({
|
|
294
|
+
response: { status: "error", errorCode: "sync.requestTimeout", httpStatus: 504 },
|
|
295
|
+
fallbackErrorCode: "sync.requestTimeout"
|
|
296
|
+
}));
|
|
297
|
+
}, effectiveTimeoutMs);
|
|
298
|
+
}
|
|
299
|
+
const responseListener = (responseData) => {
|
|
300
|
+
clearResponseTimeout();
|
|
232
301
|
cleanupProgressListener?.();
|
|
302
|
+
cleanupProgressListener = null;
|
|
303
|
+
cleanupResponseListener = null;
|
|
233
304
|
cleanupExternalAbort?.();
|
|
234
305
|
cleanupExternalAbort = null;
|
|
235
306
|
if (responseData.status === "error") {
|
|
@@ -265,9 +336,13 @@ var syncRequestInternal = (params) => {
|
|
|
265
336
|
message: typeof responseData.message === "string" && responseData.message.trim().length > 0 ? responseData.message : `sync ${sanitizedName} success`,
|
|
266
337
|
result
|
|
267
338
|
});
|
|
268
|
-
}
|
|
339
|
+
};
|
|
340
|
+
socketInstance.once(responseEventName, responseListener);
|
|
341
|
+
cleanupResponseListener = () => {
|
|
342
|
+
socketInstance.off(responseEventName, responseListener);
|
|
343
|
+
};
|
|
269
344
|
};
|
|
270
|
-
runRequest(
|
|
345
|
+
runRequest(activeSocket);
|
|
271
346
|
})();
|
|
272
347
|
});
|
|
273
348
|
};
|
|
@@ -442,6 +517,78 @@ var useSyncEventTrigger = () => {
|
|
|
442
517
|
}, []);
|
|
443
518
|
return { triggerSyncEvent, triggerSyncStreamEvent };
|
|
444
519
|
};
|
|
520
|
+
var normalizeSyncRouteKey = (value) => {
|
|
521
|
+
const sanitized = value.replaceAll(/^\/+|\/+$/g, "");
|
|
522
|
+
if (sanitized.length === 0) return "";
|
|
523
|
+
if (sanitized.startsWith("sync/")) return sanitized;
|
|
524
|
+
return `sync/${sanitized}`;
|
|
525
|
+
};
|
|
526
|
+
var getSyncRouteKeys = ({ fullName, cb }) => {
|
|
527
|
+
const keys = /* @__PURE__ */ new Set();
|
|
528
|
+
if (typeof fullName === "string") {
|
|
529
|
+
const normalized = normalizeSyncRouteKey(fullName);
|
|
530
|
+
if (normalized) keys.add(normalized);
|
|
531
|
+
}
|
|
532
|
+
if (typeof cb === "string") {
|
|
533
|
+
const normalized = normalizeSyncRouteKey(cb);
|
|
534
|
+
if (normalized) keys.add(normalized);
|
|
535
|
+
}
|
|
536
|
+
return [...keys];
|
|
537
|
+
};
|
|
538
|
+
var attachedSyncSockets = /* @__PURE__ */ new WeakSet();
|
|
539
|
+
var attachSyncReceiver = (socketInstance) => {
|
|
540
|
+
if (attachedSyncSockets.has(socketInstance)) return;
|
|
541
|
+
attachedSyncSockets.add(socketInstance);
|
|
542
|
+
socketInstance.on(socketEventNames.sync, (payload) => {
|
|
543
|
+
const { cb, clientOutput, serverOutput, message, status, fullName, errorCode, errorParams } = payload;
|
|
544
|
+
if (shouldLogDev()) {
|
|
545
|
+
getLogger().debug("Server Sync Response", { payload });
|
|
546
|
+
}
|
|
547
|
+
const routeKeys = getSyncRouteKeys({ fullName, cb });
|
|
548
|
+
if (status === "stream") {
|
|
549
|
+
if (routeKeys.length === 0) return;
|
|
550
|
+
const streamPayload = { ...payload };
|
|
551
|
+
delete streamPayload.status;
|
|
552
|
+
delete streamPayload.fullName;
|
|
553
|
+
delete streamPayload.cb;
|
|
554
|
+
delete streamPayload.errorCode;
|
|
555
|
+
delete streamPayload.errorParams;
|
|
556
|
+
delete streamPayload.httpStatus;
|
|
557
|
+
delete streamPayload.message;
|
|
558
|
+
if (shouldLogStream()) {
|
|
559
|
+
getLogger().debug("Server Sync Stream", { routeKeys, streamPayload });
|
|
560
|
+
}
|
|
561
|
+
for (const routeKey of routeKeys) {
|
|
562
|
+
triggerSyncStreamCallbacks(routeKey, streamPayload);
|
|
563
|
+
}
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
if (status === "error") {
|
|
567
|
+
if (errorCode === "sync.ignore" || message === "sync.ignore") return;
|
|
568
|
+
if (shouldNotifyDev()) {
|
|
569
|
+
if (errorCode) {
|
|
570
|
+
notify.error({ key: errorCode, params: errorParams });
|
|
571
|
+
} else if (message) {
|
|
572
|
+
notify.error({ key: message });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
if (routeKeys.length === 0) {
|
|
578
|
+
const errorMessage = `Sync response is missing fullName for cb '${cb ?? "unknown"}'.`;
|
|
579
|
+
if (shouldLogDev()) {
|
|
580
|
+
getLogger().error(errorMessage);
|
|
581
|
+
}
|
|
582
|
+
if (shouldNotifyDev()) {
|
|
583
|
+
notify.error({ key: "sync.invalidRequestFormat" });
|
|
584
|
+
}
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
for (const routeKey of routeKeys) {
|
|
588
|
+
triggerSyncCallbacks(routeKey, clientOutput, serverOutput);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
591
|
+
};
|
|
445
592
|
var buildConnectHandler = ({ setSocketStatus }) => () => {
|
|
446
593
|
if (shouldLogSocketStatus()) getLogger().info("Connected to server");
|
|
447
594
|
setSocketStatus((prev) => ({ ...prev, self: { ...prev.self, status: "CONNECTED" } }));
|
|
@@ -529,6 +676,7 @@ var initSyncRequest = async ({
|
|
|
529
676
|
socket.on(socketEventNames.connectError, connectError);
|
|
530
677
|
};
|
|
531
678
|
export {
|
|
679
|
+
attachSyncReceiver,
|
|
532
680
|
initSyncRequest,
|
|
533
681
|
syncRequest,
|
|
534
682
|
useSyncEventTrigger,
|