@syncular/server-hono 0.0.6-73 → 0.0.6-79
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/console/routes.d.ts +2 -2
- package/dist/console/routes.d.ts.map +1 -1
- package/dist/console/routes.js +2 -2
- package/dist/console/routes.js.map +1 -1
- package/dist/console/types.d.ts +3 -3
- package/dist/console/types.d.ts.map +1 -1
- package/dist/create-server.d.ts +4 -4
- package/dist/create-server.d.ts.map +1 -1
- package/dist/create-server.js.map +1 -1
- package/dist/routes.d.ts +4 -4
- package/dist/routes.d.ts.map +1 -1
- package/dist/routes.js +51 -1
- package/dist/routes.js.map +1 -1
- package/package.json +6 -6
- package/src/__tests__/console-routes.test.ts +6 -2
- package/src/__tests__/create-server.test.ts +6 -2
- package/src/__tests__/pull-chunk-storage.test.ts +6 -2
- package/src/__tests__/realtime-bridge.test.ts +6 -2
- package/src/__tests__/sync-rate-limit-routing.test.ts +6 -2
- package/src/console/routes.ts +5 -4
- package/src/console/types.ts +3 -1
- package/src/create-server.ts +5 -2
- package/src/routes.ts +62 -2
package/src/routes.ts
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
captureSyncException,
|
|
12
|
+
countSyncMetric,
|
|
12
13
|
createSyncTimer,
|
|
14
|
+
distributionSyncMetric,
|
|
13
15
|
ErrorResponseSchema,
|
|
14
16
|
logSyncEvent,
|
|
15
17
|
SyncCombinedRequestSchema,
|
|
@@ -20,6 +22,7 @@ import type {
|
|
|
20
22
|
ServerSyncDialect,
|
|
21
23
|
ServerTableHandler,
|
|
22
24
|
SnapshotChunkStorage,
|
|
25
|
+
SqlFamily,
|
|
23
26
|
SyncCoreDb,
|
|
24
27
|
SyncRealtimeBroadcaster,
|
|
25
28
|
SyncRealtimeEvent,
|
|
@@ -163,9 +166,10 @@ export interface SyncRoutesConfigWithRateLimit {
|
|
|
163
166
|
export interface CreateSyncRoutesOptions<
|
|
164
167
|
DB extends SyncCoreDb = SyncCoreDb,
|
|
165
168
|
Auth extends SyncAuthResult = SyncAuthResult,
|
|
169
|
+
F extends SqlFamily = SqlFamily,
|
|
166
170
|
> {
|
|
167
171
|
db: Kysely<DB>;
|
|
168
|
-
dialect: ServerSyncDialect
|
|
172
|
+
dialect: ServerSyncDialect<F>;
|
|
169
173
|
handlers: ServerTableHandler<DB, Auth>[];
|
|
170
174
|
authenticate: (c: Context) => Promise<Auth | null>;
|
|
171
175
|
sync?: SyncRoutesConfigWithRateLimit;
|
|
@@ -434,7 +438,8 @@ function emitConsoleLiveEvent(
|
|
|
434
438
|
export function createSyncRoutes<
|
|
435
439
|
DB extends SyncCoreDb = SyncCoreDb,
|
|
436
440
|
Auth extends SyncAuthResult = SyncAuthResult,
|
|
437
|
-
|
|
441
|
+
F extends SqlFamily = SqlFamily,
|
|
442
|
+
>(options: CreateSyncRoutesOptions<DB, Auth, F>): Hono {
|
|
438
443
|
const routes = new Hono();
|
|
439
444
|
routes.onError((error, c) => {
|
|
440
445
|
captureSyncException(error, {
|
|
@@ -1315,6 +1320,32 @@ export function createSyncRoutes<
|
|
|
1315
1320
|
|
|
1316
1321
|
let unregister: (() => void) | null = null;
|
|
1317
1322
|
let connRef: ReturnType<typeof createWebSocketConnection> | null = null;
|
|
1323
|
+
const connectionCountBeforeUpgrade =
|
|
1324
|
+
wsConnectionManager.getConnectionCount(clientId);
|
|
1325
|
+
let sessionStartedAtMs: number | null = null;
|
|
1326
|
+
let sessionEnded = false;
|
|
1327
|
+
|
|
1328
|
+
const finishRealtimeSession = (reason: 'closed' | 'error') => {
|
|
1329
|
+
if (sessionEnded) return;
|
|
1330
|
+
sessionEnded = true;
|
|
1331
|
+
if (sessionStartedAtMs === null) {
|
|
1332
|
+
return;
|
|
1333
|
+
}
|
|
1334
|
+
const durationMs = Math.max(0, Date.now() - sessionStartedAtMs);
|
|
1335
|
+
countSyncMetric('sync.sessions.ended', 1, {
|
|
1336
|
+
attributes: {
|
|
1337
|
+
transportPath: realtimeTransportPath,
|
|
1338
|
+
reason,
|
|
1339
|
+
},
|
|
1340
|
+
});
|
|
1341
|
+
distributionSyncMetric('sync.sessions.duration_ms', durationMs, {
|
|
1342
|
+
unit: 'millisecond',
|
|
1343
|
+
attributes: {
|
|
1344
|
+
transportPath: realtimeTransportPath,
|
|
1345
|
+
reason,
|
|
1346
|
+
},
|
|
1347
|
+
});
|
|
1348
|
+
};
|
|
1318
1349
|
|
|
1319
1350
|
const upgradeWebSocket = websocketConfig.upgradeWebSocket;
|
|
1320
1351
|
if (!upgradeWebSocket) {
|
|
@@ -1329,6 +1360,20 @@ export function createSyncRoutes<
|
|
|
1329
1360
|
transportPath: realtimeTransportPath,
|
|
1330
1361
|
});
|
|
1331
1362
|
connRef = conn;
|
|
1363
|
+
sessionStartedAtMs = Date.now();
|
|
1364
|
+
countSyncMetric('sync.sessions.started', 1, {
|
|
1365
|
+
attributes: {
|
|
1366
|
+
transportPath: realtimeTransportPath,
|
|
1367
|
+
},
|
|
1368
|
+
});
|
|
1369
|
+
if (connectionCountBeforeUpgrade > 0) {
|
|
1370
|
+
countSyncMetric('sync.transport.reconnects', 1, {
|
|
1371
|
+
attributes: {
|
|
1372
|
+
transportPath: realtimeTransportPath,
|
|
1373
|
+
source: 'server',
|
|
1374
|
+
},
|
|
1375
|
+
});
|
|
1376
|
+
}
|
|
1332
1377
|
|
|
1333
1378
|
unregister = wsConnectionManager.register(conn, initialScopeKeys);
|
|
1334
1379
|
conn.sendHeartbeat();
|
|
@@ -1345,6 +1390,7 @@ export function createSyncRoutes<
|
|
|
1345
1390
|
unregister?.();
|
|
1346
1391
|
unregister = null;
|
|
1347
1392
|
connRef = null;
|
|
1393
|
+
finishRealtimeSession('closed');
|
|
1348
1394
|
logSyncEvent({
|
|
1349
1395
|
event: 'sync.realtime.disconnect',
|
|
1350
1396
|
userId: auth.actorId,
|
|
@@ -1360,6 +1406,7 @@ export function createSyncRoutes<
|
|
|
1360
1406
|
unregister?.();
|
|
1361
1407
|
unregister = null;
|
|
1362
1408
|
connRef = null;
|
|
1409
|
+
finishRealtimeSession('error');
|
|
1363
1410
|
logSyncEvent({
|
|
1364
1411
|
event: 'sync.realtime.disconnect',
|
|
1365
1412
|
userId: auth.actorId,
|
|
@@ -1672,6 +1719,19 @@ export function createSyncRoutes<
|
|
|
1672
1719
|
tables: pushed.affectedTables,
|
|
1673
1720
|
}));
|
|
1674
1721
|
|
|
1722
|
+
const detectedConflicts = pushed.response.results.reduce(
|
|
1723
|
+
(count, result) => count + (result.status === 'conflict' ? 1 : 0),
|
|
1724
|
+
0
|
|
1725
|
+
);
|
|
1726
|
+
if (detectedConflicts > 0) {
|
|
1727
|
+
countSyncMetric('sync.conflicts.detected', detectedConflicts, {
|
|
1728
|
+
attributes: {
|
|
1729
|
+
syncPath: 'ws-push',
|
|
1730
|
+
transportPath: conn.transportPath,
|
|
1731
|
+
},
|
|
1732
|
+
});
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1675
1735
|
// WS notifications to other clients
|
|
1676
1736
|
if (
|
|
1677
1737
|
wsConnectionManager &&
|