@syncular/server-hono 0.0.1-60
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/api-key-auth.d.ts +49 -0
- package/dist/api-key-auth.d.ts.map +1 -0
- package/dist/api-key-auth.js +110 -0
- package/dist/api-key-auth.js.map +1 -0
- package/dist/blobs.d.ts +69 -0
- package/dist/blobs.d.ts.map +1 -0
- package/dist/blobs.js +383 -0
- package/dist/blobs.js.map +1 -0
- package/dist/console/index.d.ts +8 -0
- package/dist/console/index.d.ts.map +1 -0
- package/dist/console/index.js +7 -0
- package/dist/console/index.js.map +1 -0
- package/dist/console/routes.d.ts +106 -0
- package/dist/console/routes.d.ts.map +1 -0
- package/dist/console/routes.js +1612 -0
- package/dist/console/routes.js.map +1 -0
- package/dist/console/schemas.d.ts +308 -0
- package/dist/console/schemas.d.ts.map +1 -0
- package/dist/console/schemas.js +201 -0
- package/dist/console/schemas.js.map +1 -0
- package/dist/create-server.d.ts +78 -0
- package/dist/create-server.d.ts.map +1 -0
- package/dist/create-server.js +99 -0
- package/dist/create-server.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/openapi.d.ts +45 -0
- package/dist/openapi.d.ts.map +1 -0
- package/dist/openapi.js +59 -0
- package/dist/openapi.js.map +1 -0
- package/dist/proxy/connection-manager.d.ts +78 -0
- package/dist/proxy/connection-manager.d.ts.map +1 -0
- package/dist/proxy/connection-manager.js +251 -0
- package/dist/proxy/connection-manager.js.map +1 -0
- package/dist/proxy/index.d.ts +8 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +8 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/routes.d.ts +74 -0
- package/dist/proxy/routes.d.ts.map +1 -0
- package/dist/proxy/routes.js +147 -0
- package/dist/proxy/routes.js.map +1 -0
- package/dist/rate-limit.d.ts +101 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +186 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/routes.d.ts +126 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +788 -0
- package/dist/routes.js.map +1 -0
- package/dist/ws.d.ts +230 -0
- package/dist/ws.d.ts.map +1 -0
- package/dist/ws.js +601 -0
- package/dist/ws.js.map +1 -0
- package/package.json +73 -0
- package/src/__tests__/create-server.test.ts +187 -0
- package/src/__tests__/pull-chunk-storage.test.ts +189 -0
- package/src/__tests__/rate-limit.test.ts +78 -0
- package/src/__tests__/realtime-bridge.test.ts +131 -0
- package/src/__tests__/ws-connection-manager.test.ts +176 -0
- package/src/api-key-auth.ts +179 -0
- package/src/blobs.ts +534 -0
- package/src/console/index.ts +17 -0
- package/src/console/routes.ts +2155 -0
- package/src/console/schemas.ts +299 -0
- package/src/create-server.ts +180 -0
- package/src/index.ts +42 -0
- package/src/openapi.ts +74 -0
- package/src/proxy/connection-manager.ts +340 -0
- package/src/proxy/index.ts +8 -0
- package/src/proxy/routes.ts +223 -0
- package/src/rate-limit.ts +321 -0
- package/src/routes.ts +1186 -0
- package/src/ws.ts +789 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - Rate limiting middleware for sync endpoints
|
|
3
|
+
*
|
|
4
|
+
* Provides per-user rate limiting to prevent DoS attacks and excessive
|
|
5
|
+
* server load from misbehaving clients.
|
|
6
|
+
*/
|
|
7
|
+
import { logSyncEvent } from '@syncular/core';
|
|
8
|
+
/**
|
|
9
|
+
* Default rate limit configuration
|
|
10
|
+
*/
|
|
11
|
+
const DEFAULT_RATE_LIMIT_CONFIG = {
|
|
12
|
+
maxRequests: 60,
|
|
13
|
+
windowMs: 60_000,
|
|
14
|
+
includeHeaders: true,
|
|
15
|
+
skipInTest: false,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* In-memory rate limiter store
|
|
19
|
+
*
|
|
20
|
+
* Note: This is suitable for single-instance deployments.
|
|
21
|
+
* For distributed deployments, use Redis or similar.
|
|
22
|
+
*/
|
|
23
|
+
class RateLimitStore {
|
|
24
|
+
windowMs;
|
|
25
|
+
entries = new Map();
|
|
26
|
+
cleanupInterval = null;
|
|
27
|
+
constructor(windowMs) {
|
|
28
|
+
this.windowMs = windowMs;
|
|
29
|
+
// Clean up expired entries periodically
|
|
30
|
+
this.cleanupInterval = setInterval(() => this.cleanup(), Math.max(windowMs, 60_000));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check and increment the rate limit counter for a key.
|
|
34
|
+
*
|
|
35
|
+
* @param key - Rate limit key (e.g., userId)
|
|
36
|
+
* @param maxRequests - Maximum requests allowed
|
|
37
|
+
* @returns Rate limit check result
|
|
38
|
+
*/
|
|
39
|
+
check(key, maxRequests) {
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
let entry = this.entries.get(key);
|
|
42
|
+
// Check if window has expired
|
|
43
|
+
if (!entry || now - entry.windowStart >= this.windowMs) {
|
|
44
|
+
entry = { count: 0, windowStart: now };
|
|
45
|
+
this.entries.set(key, entry);
|
|
46
|
+
}
|
|
47
|
+
const resetAt = entry.windowStart + this.windowMs;
|
|
48
|
+
const allowed = entry.count < maxRequests;
|
|
49
|
+
if (allowed) {
|
|
50
|
+
entry.count++;
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
allowed,
|
|
54
|
+
current: entry.count,
|
|
55
|
+
remaining: Math.max(0, maxRequests - entry.count),
|
|
56
|
+
resetAt,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Clean up expired entries
|
|
61
|
+
*/
|
|
62
|
+
cleanup() {
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
for (const [key, entry] of this.entries) {
|
|
65
|
+
if (now - entry.windowStart >= this.windowMs) {
|
|
66
|
+
this.entries.delete(key);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Stop the cleanup interval
|
|
72
|
+
*/
|
|
73
|
+
stop() {
|
|
74
|
+
if (this.cleanupInterval) {
|
|
75
|
+
clearInterval(this.cleanupInterval);
|
|
76
|
+
this.cleanupInterval = null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clear all entries (for testing)
|
|
81
|
+
*/
|
|
82
|
+
clear() {
|
|
83
|
+
this.entries.clear();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get current entry count (for monitoring)
|
|
87
|
+
*/
|
|
88
|
+
get size() {
|
|
89
|
+
return this.entries.size;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Track created stores so tests can reset state deterministically.
|
|
93
|
+
const activeStores = new Set();
|
|
94
|
+
/**
|
|
95
|
+
* Reset the global store (for testing)
|
|
96
|
+
*/
|
|
97
|
+
export function resetRateLimitStore() {
|
|
98
|
+
for (const store of activeStores) {
|
|
99
|
+
store.stop();
|
|
100
|
+
}
|
|
101
|
+
activeStores.clear();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a rate limiting middleware for Hono.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* import { createRateLimiter } from '@syncular/server-hono';
|
|
109
|
+
*
|
|
110
|
+
* const rateLimiter = createRateLimiter({
|
|
111
|
+
* maxRequests: 60,
|
|
112
|
+
* windowMs: 60_000,
|
|
113
|
+
* keyGenerator: async (c) => {
|
|
114
|
+
* const auth = await authenticate(c);
|
|
115
|
+
* return auth?.userId ?? null;
|
|
116
|
+
* },
|
|
117
|
+
* });
|
|
118
|
+
*
|
|
119
|
+
* app.use('/sync/*', rateLimiter);
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export function createRateLimiter(config) {
|
|
123
|
+
const { maxRequests = DEFAULT_RATE_LIMIT_CONFIG.maxRequests, windowMs = DEFAULT_RATE_LIMIT_CONFIG.windowMs, keyGenerator, includeHeaders = DEFAULT_RATE_LIMIT_CONFIG.includeHeaders, onRateLimited, skipInTest = DEFAULT_RATE_LIMIT_CONFIG.skipInTest, } = config;
|
|
124
|
+
const store = new RateLimitStore(windowMs);
|
|
125
|
+
activeStores.add(store);
|
|
126
|
+
return async (c, next) => {
|
|
127
|
+
// Skip in test environment if configured
|
|
128
|
+
if (skipInTest && process.env.NODE_ENV === 'test') {
|
|
129
|
+
return next();
|
|
130
|
+
}
|
|
131
|
+
// Get the rate limit key
|
|
132
|
+
const key = await keyGenerator(c);
|
|
133
|
+
if (key === null) {
|
|
134
|
+
// Skip rate limiting for this request
|
|
135
|
+
return next();
|
|
136
|
+
}
|
|
137
|
+
const result = store.check(key, maxRequests);
|
|
138
|
+
// Add rate limit headers if configured
|
|
139
|
+
if (includeHeaders) {
|
|
140
|
+
c.header('X-RateLimit-Limit', String(maxRequests));
|
|
141
|
+
c.header('X-RateLimit-Remaining', String(result.remaining));
|
|
142
|
+
c.header('X-RateLimit-Reset', String(Math.ceil(result.resetAt / 1000)));
|
|
143
|
+
}
|
|
144
|
+
if (!result.allowed) {
|
|
145
|
+
const retryAfterMs = result.resetAt - Date.now();
|
|
146
|
+
const retryAfterSec = Math.ceil(retryAfterMs / 1000);
|
|
147
|
+
// Log rate limit event
|
|
148
|
+
logSyncEvent({
|
|
149
|
+
event: 'sync.rate_limit',
|
|
150
|
+
key,
|
|
151
|
+
current: result.current,
|
|
152
|
+
maxRequests,
|
|
153
|
+
retryAfterMs,
|
|
154
|
+
});
|
|
155
|
+
// Add Retry-After header
|
|
156
|
+
c.header('Retry-After', String(retryAfterSec));
|
|
157
|
+
// Use custom handler or default response
|
|
158
|
+
if (onRateLimited) {
|
|
159
|
+
return onRateLimited(c, retryAfterMs);
|
|
160
|
+
}
|
|
161
|
+
return c.json({
|
|
162
|
+
error: 'RATE_LIMITED',
|
|
163
|
+
message: 'Too many requests. Please try again later.',
|
|
164
|
+
retryAfterMs,
|
|
165
|
+
retryAfterSec,
|
|
166
|
+
}, 429);
|
|
167
|
+
}
|
|
168
|
+
return next();
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Default sync rate limit configuration
|
|
173
|
+
*/
|
|
174
|
+
export const DEFAULT_SYNC_RATE_LIMITS = {
|
|
175
|
+
pull: {
|
|
176
|
+
maxRequests: 120, // 2 requests per second average
|
|
177
|
+
windowMs: 60_000,
|
|
178
|
+
includeHeaders: true,
|
|
179
|
+
},
|
|
180
|
+
push: {
|
|
181
|
+
maxRequests: 60, // 1 request per second average
|
|
182
|
+
windowMs: 60_000,
|
|
183
|
+
includeHeaders: true,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
|
package/dist/routes.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server-hono - Sync routes for Hono
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - POST / (combined push + pull in one round-trip)
|
|
6
|
+
* - GET /snapshot-chunks/:chunkId (download encoded snapshot chunks)
|
|
7
|
+
* - GET /realtime (optional WebSocket "wake up" notifications)
|
|
8
|
+
*/
|
|
9
|
+
import type { ServerSyncDialect, ServerTableHandler, SnapshotChunkStorage, SyncCoreDb, SyncRealtimeBroadcaster } from '@syncular/server';
|
|
10
|
+
import { type CompactOptions, type PruneOptions } from '@syncular/server';
|
|
11
|
+
import type { Context } from 'hono';
|
|
12
|
+
import { Hono } from 'hono';
|
|
13
|
+
import type { UpgradeWebSocket } from 'hono/ws';
|
|
14
|
+
import { type Kysely } from 'kysely';
|
|
15
|
+
import { type SyncRateLimitConfig } from './rate-limit';
|
|
16
|
+
import { WebSocketConnectionManager } from './ws';
|
|
17
|
+
export interface SyncAuthResult {
|
|
18
|
+
actorId: string;
|
|
19
|
+
partitionId?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* WebSocket configuration for realtime sync.
|
|
23
|
+
*
|
|
24
|
+
* Note: this endpoint is only a "wake up" mechanism; clients must still pull.
|
|
25
|
+
*/
|
|
26
|
+
export interface SyncWebSocketConfig {
|
|
27
|
+
enabled?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Runtime-provided WebSocket upgrader (e.g. from `hono/bun`'s `createBunWebSocket()`).
|
|
30
|
+
*/
|
|
31
|
+
upgradeWebSocket?: UpgradeWebSocket;
|
|
32
|
+
heartbeatIntervalMs?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Maximum number of concurrent WebSocket connections across the entire process.
|
|
35
|
+
* Default: 5000
|
|
36
|
+
*/
|
|
37
|
+
maxConnectionsTotal?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Maximum number of concurrent WebSocket connections per clientId.
|
|
40
|
+
* Default: 3
|
|
41
|
+
*/
|
|
42
|
+
maxConnectionsPerClient?: number;
|
|
43
|
+
}
|
|
44
|
+
export interface SyncRoutesConfigWithRateLimit {
|
|
45
|
+
/**
|
|
46
|
+
* Max commits per pull request.
|
|
47
|
+
* Default: 100
|
|
48
|
+
*/
|
|
49
|
+
maxPullLimitCommits?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Max subscriptions per pull request.
|
|
52
|
+
* Default: 200
|
|
53
|
+
*/
|
|
54
|
+
maxSubscriptionsPerPull?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Max snapshot rows per snapshot page.
|
|
57
|
+
* Default: 5000
|
|
58
|
+
*/
|
|
59
|
+
maxPullLimitSnapshotRows?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Max snapshot pages per subscription per pull response.
|
|
62
|
+
* Default: 10
|
|
63
|
+
*/
|
|
64
|
+
maxPullMaxSnapshotPages?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Max operations per pushed commit.
|
|
67
|
+
* Default: 200
|
|
68
|
+
*/
|
|
69
|
+
maxOperationsPerPush?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Rate limiting configuration.
|
|
72
|
+
* Set to false to disable all rate limiting.
|
|
73
|
+
*/
|
|
74
|
+
rateLimit?: SyncRateLimitConfig | false;
|
|
75
|
+
/**
|
|
76
|
+
* WebSocket realtime configuration.
|
|
77
|
+
*/
|
|
78
|
+
websocket?: SyncWebSocketConfig;
|
|
79
|
+
/**
|
|
80
|
+
* Optional pruning configuration. When enabled, the server periodically prunes
|
|
81
|
+
* old commit history based on active client cursors.
|
|
82
|
+
*/
|
|
83
|
+
prune?: {
|
|
84
|
+
/** Minimum time between prune runs. Default: 5 minutes. */
|
|
85
|
+
minIntervalMs?: number;
|
|
86
|
+
/** Pruning watermark options. */
|
|
87
|
+
options?: PruneOptions;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Optional compaction configuration. When enabled, the server periodically
|
|
91
|
+
* compacts older change history to reduce storage.
|
|
92
|
+
*/
|
|
93
|
+
compact?: {
|
|
94
|
+
/** Minimum time between compaction runs. Default: 30 minutes. */
|
|
95
|
+
minIntervalMs?: number;
|
|
96
|
+
/** Compaction options. */
|
|
97
|
+
options?: CompactOptions;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Optional multi-instance realtime broadcaster.
|
|
101
|
+
* When provided, instances publish/subscribe commit wakeups via the broadcaster.
|
|
102
|
+
*/
|
|
103
|
+
realtime?: {
|
|
104
|
+
broadcaster: SyncRealtimeBroadcaster;
|
|
105
|
+
/** Optional stable instance id (useful in tests). */
|
|
106
|
+
instanceId?: string;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export interface CreateSyncRoutesOptions<DB extends SyncCoreDb = SyncCoreDb> {
|
|
110
|
+
db: Kysely<DB>;
|
|
111
|
+
dialect: ServerSyncDialect;
|
|
112
|
+
handlers: ServerTableHandler<DB>[];
|
|
113
|
+
authenticate: (c: Context) => Promise<SyncAuthResult | null>;
|
|
114
|
+
sync?: SyncRoutesConfigWithRateLimit;
|
|
115
|
+
wsConnectionManager?: WebSocketConnectionManager;
|
|
116
|
+
/**
|
|
117
|
+
* Optional snapshot chunk storage adapter.
|
|
118
|
+
* When provided, stores snapshot chunk bodies in external storage
|
|
119
|
+
* (S3, R2, etc.) instead of inline in the database.
|
|
120
|
+
*/
|
|
121
|
+
chunkStorage?: SnapshotChunkStorage;
|
|
122
|
+
}
|
|
123
|
+
export declare function createSyncRoutes<DB extends SyncCoreDb = SyncCoreDb>(options: CreateSyncRoutesOptions<DB>): Hono;
|
|
124
|
+
export declare function getSyncWebSocketConnectionManager(routes: Hono): WebSocketConnectionManager | undefined;
|
|
125
|
+
export declare function getSyncRealtimeUnsubscribe(routes: Hono): (() => void) | undefined;
|
|
126
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
|