@syncular/relay 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/client-role/forward-engine.d.ts +63 -0
- package/dist/client-role/forward-engine.d.ts.map +1 -0
- package/dist/client-role/forward-engine.js +263 -0
- package/dist/client-role/forward-engine.js.map +1 -0
- package/dist/client-role/index.d.ts +9 -0
- package/dist/client-role/index.d.ts.map +1 -0
- package/dist/client-role/index.js +9 -0
- package/dist/client-role/index.js.map +1 -0
- package/dist/client-role/pull-engine.d.ts +70 -0
- package/dist/client-role/pull-engine.d.ts.map +1 -0
- package/dist/client-role/pull-engine.js +233 -0
- package/dist/client-role/pull-engine.js.map +1 -0
- package/dist/client-role/sequence-mapper.d.ts +65 -0
- package/dist/client-role/sequence-mapper.d.ts.map +1 -0
- package/dist/client-role/sequence-mapper.js +161 -0
- package/dist/client-role/sequence-mapper.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/migrate.d.ts +18 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +99 -0
- package/dist/migrate.js.map +1 -0
- package/dist/mode-manager.d.ts +60 -0
- package/dist/mode-manager.d.ts.map +1 -0
- package/dist/mode-manager.js +114 -0
- package/dist/mode-manager.js.map +1 -0
- package/dist/realtime.d.ts +102 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +305 -0
- package/dist/realtime.js.map +1 -0
- package/dist/relay.d.ts +188 -0
- package/dist/relay.d.ts.map +1 -0
- package/dist/relay.js +315 -0
- package/dist/relay.js.map +1 -0
- package/dist/schema.d.ts +158 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +7 -0
- package/dist/schema.js.map +1 -0
- package/dist/server-role/index.d.ts +54 -0
- package/dist/server-role/index.d.ts.map +1 -0
- package/dist/server-role/index.js +198 -0
- package/dist/server-role/index.js.map +1 -0
- package/dist/server-role/pull.d.ts +25 -0
- package/dist/server-role/pull.d.ts.map +1 -0
- package/dist/server-role/pull.js +24 -0
- package/dist/server-role/pull.js.map +1 -0
- package/dist/server-role/push.d.ts +27 -0
- package/dist/server-role/push.d.ts.map +1 -0
- package/dist/server-role/push.js +98 -0
- package/dist/server-role/push.js.map +1 -0
- package/package.json +61 -0
- package/src/__tests__/relay.test.ts +464 -0
- package/src/bun-types.d.ts +50 -0
- package/src/client-role/forward-engine.ts +352 -0
- package/src/client-role/index.ts +9 -0
- package/src/client-role/pull-engine.ts +301 -0
- package/src/client-role/sequence-mapper.ts +201 -0
- package/src/index.ts +50 -0
- package/src/migrate.ts +113 -0
- package/src/mode-manager.ts +142 -0
- package/src/realtime.ts +370 -0
- package/src/relay.ts +421 -0
- package/src/schema.ts +171 -0
- package/src/server-role/index.ts +342 -0
- package/src/server-role/pull.ts +37 -0
- package/src/server-role/push.ts +130 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/relay - Server Role
|
|
3
|
+
*
|
|
4
|
+
* Hono routes for serving local clients.
|
|
5
|
+
*/
|
|
6
|
+
import { createSyncTimer, logSyncEvent, ScopeValuesSchema, SyncBootstrapStateSchema, SyncPullRequestSchema, SyncPushRequestSchema, } from '@syncular/core';
|
|
7
|
+
import { recordClientCursor } from '@syncular/server';
|
|
8
|
+
import { Hono } from 'hono';
|
|
9
|
+
import { relayPull } from './pull';
|
|
10
|
+
import { relayPushCommit } from './push';
|
|
11
|
+
function clampInt(value, min, max) {
|
|
12
|
+
return Math.max(min, Math.min(max, value));
|
|
13
|
+
}
|
|
14
|
+
function isRecord(value) {
|
|
15
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create Hono routes for relay server-role endpoints.
|
|
19
|
+
*
|
|
20
|
+
* Provides:
|
|
21
|
+
* - POST /pull (commit stream + optional bootstrap snapshots)
|
|
22
|
+
* - POST /push (commit ingestion)
|
|
23
|
+
* - GET /realtime (WebSocket wake-up notifications)
|
|
24
|
+
*/
|
|
25
|
+
export function createRelayRoutes(options) {
|
|
26
|
+
const routes = new Hono();
|
|
27
|
+
const maxOperationsPerPush = options.maxOperationsPerPush ?? 200;
|
|
28
|
+
const maxSubscriptionsPerPull = options.maxSubscriptionsPerPull ?? 200;
|
|
29
|
+
const maxPullLimitCommits = options.maxPullLimitCommits ?? 100;
|
|
30
|
+
const authenticate = options.authenticate ?? (async () => ({ actorId: 'anonymous' }));
|
|
31
|
+
// POST /pull
|
|
32
|
+
routes.post('/pull', async (c) => {
|
|
33
|
+
const auth = await authenticate(c);
|
|
34
|
+
if (!auth)
|
|
35
|
+
return c.json({ error: 'UNAUTHENTICATED' }, 401);
|
|
36
|
+
const rawBody = await c.req.json();
|
|
37
|
+
const timer = createSyncTimer();
|
|
38
|
+
if (!isRecord(rawBody)) {
|
|
39
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid JSON body' }, 400);
|
|
40
|
+
}
|
|
41
|
+
if (!rawBody.clientId || typeof rawBody.clientId !== 'string') {
|
|
42
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'clientId is required' }, 400);
|
|
43
|
+
}
|
|
44
|
+
if (!Array.isArray(rawBody.subscriptions)) {
|
|
45
|
+
return c.json({
|
|
46
|
+
error: 'INVALID_REQUEST',
|
|
47
|
+
message: 'subscriptions array is required',
|
|
48
|
+
}, 400);
|
|
49
|
+
}
|
|
50
|
+
if (rawBody.subscriptions.length > maxSubscriptionsPerPull) {
|
|
51
|
+
return c.json({
|
|
52
|
+
error: 'INVALID_REQUEST',
|
|
53
|
+
message: `Too many subscriptions (max ${maxSubscriptionsPerPull})`,
|
|
54
|
+
}, 400);
|
|
55
|
+
}
|
|
56
|
+
const subscriptions = [];
|
|
57
|
+
for (const subValue of rawBody.subscriptions) {
|
|
58
|
+
if (!isRecord(subValue)) {
|
|
59
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid subscription entry' }, 400);
|
|
60
|
+
}
|
|
61
|
+
const id = typeof subValue.id === 'string' ? subValue.id : null;
|
|
62
|
+
const shape = typeof subValue.shape === 'string' ? subValue.shape : null;
|
|
63
|
+
if (!id || !shape) {
|
|
64
|
+
return c.json({
|
|
65
|
+
error: 'INVALID_REQUEST',
|
|
66
|
+
message: 'Subscription id/shape required',
|
|
67
|
+
}, 400);
|
|
68
|
+
}
|
|
69
|
+
const scopesParsed = ScopeValuesSchema.safeParse(subValue.scopes);
|
|
70
|
+
if (!scopesParsed.success) {
|
|
71
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid subscription scopes' }, 400);
|
|
72
|
+
}
|
|
73
|
+
const rawParams = subValue.params;
|
|
74
|
+
if (rawParams !== undefined && !isRecord(rawParams)) {
|
|
75
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid subscription params' }, 400);
|
|
76
|
+
}
|
|
77
|
+
const cursor = typeof subValue.cursor === 'number' && Number.isInteger(subValue.cursor)
|
|
78
|
+
? Math.max(-1, subValue.cursor)
|
|
79
|
+
: -1;
|
|
80
|
+
const rawBootstrapState = subValue.bootstrapState;
|
|
81
|
+
const bootstrapState = rawBootstrapState === undefined || rawBootstrapState === null
|
|
82
|
+
? null
|
|
83
|
+
: (() => {
|
|
84
|
+
const parsed = SyncBootstrapStateSchema.safeParse(rawBootstrapState);
|
|
85
|
+
if (!parsed.success)
|
|
86
|
+
return null;
|
|
87
|
+
return parsed.data;
|
|
88
|
+
})();
|
|
89
|
+
if (rawBootstrapState !== undefined &&
|
|
90
|
+
rawBootstrapState !== null &&
|
|
91
|
+
bootstrapState === null) {
|
|
92
|
+
return c.json({
|
|
93
|
+
error: 'INVALID_REQUEST',
|
|
94
|
+
message: 'Invalid subscription bootstrapState',
|
|
95
|
+
}, 400);
|
|
96
|
+
}
|
|
97
|
+
subscriptions.push({
|
|
98
|
+
id,
|
|
99
|
+
shape,
|
|
100
|
+
scopes: scopesParsed.data,
|
|
101
|
+
params: rawParams,
|
|
102
|
+
cursor,
|
|
103
|
+
bootstrapState,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const request = {
|
|
107
|
+
clientId: rawBody.clientId,
|
|
108
|
+
limitCommits: clampInt(typeof rawBody.limitCommits === 'number' &&
|
|
109
|
+
Number.isInteger(rawBody.limitCommits)
|
|
110
|
+
? rawBody.limitCommits
|
|
111
|
+
: 50, 1, maxPullLimitCommits),
|
|
112
|
+
limitSnapshotRows: clampInt(typeof rawBody.limitSnapshotRows === 'number' &&
|
|
113
|
+
Number.isInteger(rawBody.limitSnapshotRows)
|
|
114
|
+
? rawBody.limitSnapshotRows
|
|
115
|
+
: 1000, 1, 5000),
|
|
116
|
+
maxSnapshotPages: clampInt(typeof rawBody.maxSnapshotPages === 'number' &&
|
|
117
|
+
Number.isInteger(rawBody.maxSnapshotPages)
|
|
118
|
+
? rawBody.maxSnapshotPages
|
|
119
|
+
: 1, 1, 10),
|
|
120
|
+
dedupeRows: typeof rawBody.dedupeRows === 'boolean'
|
|
121
|
+
? rawBody.dedupeRows
|
|
122
|
+
: undefined,
|
|
123
|
+
subscriptions,
|
|
124
|
+
};
|
|
125
|
+
const validatedRequest = SyncPullRequestSchema.safeParse(request);
|
|
126
|
+
if (!validatedRequest.success) {
|
|
127
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid pull request' }, 400);
|
|
128
|
+
}
|
|
129
|
+
const pullResult = await relayPull({
|
|
130
|
+
db: options.db,
|
|
131
|
+
dialect: options.dialect,
|
|
132
|
+
shapes: options.shapes,
|
|
133
|
+
actorId: auth.actorId,
|
|
134
|
+
request: validatedRequest.data,
|
|
135
|
+
});
|
|
136
|
+
await recordClientCursor(options.db, options.dialect, {
|
|
137
|
+
clientId: validatedRequest.data.clientId,
|
|
138
|
+
actorId: auth.actorId,
|
|
139
|
+
cursor: pullResult.clientCursor,
|
|
140
|
+
effectiveScopes: pullResult.effectiveScopes,
|
|
141
|
+
});
|
|
142
|
+
// Notify realtime about updated scope values
|
|
143
|
+
const tables = Object.keys(pullResult.effectiveScopes);
|
|
144
|
+
options.realtime.updateClientTables(request.clientId, tables);
|
|
145
|
+
logSyncEvent({
|
|
146
|
+
event: 'relay.pull',
|
|
147
|
+
userId: auth.actorId,
|
|
148
|
+
durationMs: timer(),
|
|
149
|
+
subscriptionCount: pullResult.response.subscriptions.length,
|
|
150
|
+
clientCursor: pullResult.clientCursor,
|
|
151
|
+
});
|
|
152
|
+
return c.json(pullResult.response);
|
|
153
|
+
});
|
|
154
|
+
// POST /push
|
|
155
|
+
routes.post('/push', async (c) => {
|
|
156
|
+
const auth = await authenticate(c);
|
|
157
|
+
if (!auth)
|
|
158
|
+
return c.json({ error: 'UNAUTHENTICATED' }, 401);
|
|
159
|
+
const rawBody = await c.req.json();
|
|
160
|
+
const parsed = SyncPushRequestSchema.safeParse(rawBody);
|
|
161
|
+
if (!parsed.success) {
|
|
162
|
+
return c.json({ error: 'INVALID_REQUEST', message: 'Invalid push request' }, 400);
|
|
163
|
+
}
|
|
164
|
+
const body = parsed.data;
|
|
165
|
+
if (body.operations.length > maxOperationsPerPush) {
|
|
166
|
+
return c.json({
|
|
167
|
+
error: 'TOO_MANY_OPERATIONS',
|
|
168
|
+
message: `Maximum ${maxOperationsPerPush} operations per push`,
|
|
169
|
+
}, 400);
|
|
170
|
+
}
|
|
171
|
+
const timer = createSyncTimer();
|
|
172
|
+
const pushed = await relayPushCommit({
|
|
173
|
+
db: options.db,
|
|
174
|
+
dialect: options.dialect,
|
|
175
|
+
shapes: options.shapes,
|
|
176
|
+
actorId: auth.actorId,
|
|
177
|
+
request: body,
|
|
178
|
+
});
|
|
179
|
+
logSyncEvent({
|
|
180
|
+
event: 'relay.push',
|
|
181
|
+
userId: auth.actorId,
|
|
182
|
+
durationMs: timer(),
|
|
183
|
+
operationCount: body.operations.length,
|
|
184
|
+
status: pushed.response.status,
|
|
185
|
+
commitSeq: pushed.response.commitSeq,
|
|
186
|
+
});
|
|
187
|
+
// Notify about the commit
|
|
188
|
+
if (pushed.response.ok === true &&
|
|
189
|
+
pushed.response.status === 'applied' &&
|
|
190
|
+
typeof pushed.response.commitSeq === 'number' &&
|
|
191
|
+
pushed.affectedTables.length > 0) {
|
|
192
|
+
await options.onCommit?.(pushed.response.commitSeq, pushed.affectedTables);
|
|
193
|
+
}
|
|
194
|
+
return c.json(pushed.response);
|
|
195
|
+
});
|
|
196
|
+
return routes;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server-role/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/relay - Server Role Pull Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles pulls from local clients, serving changes stored locally
|
|
5
|
+
* on the relay.
|
|
6
|
+
*/
|
|
7
|
+
import type { SyncPullRequest } from '@syncular/core';
|
|
8
|
+
import type { ServerSyncDialect, TableRegistry } from '@syncular/server';
|
|
9
|
+
import { type PullResult } from '@syncular/server';
|
|
10
|
+
import type { Kysely } from 'kysely';
|
|
11
|
+
import type { RelayDatabase } from '../schema';
|
|
12
|
+
/**
|
|
13
|
+
* Pull commits for a local client from the relay.
|
|
14
|
+
*
|
|
15
|
+
* This wraps the standard server pull with relay-specific logic:
|
|
16
|
+
* - Restricts scopes to those the relay subscribes to
|
|
17
|
+
*/
|
|
18
|
+
export declare function relayPull<DB extends RelayDatabase = RelayDatabase>(args: {
|
|
19
|
+
db: Kysely<DB>;
|
|
20
|
+
dialect: ServerSyncDialect;
|
|
21
|
+
shapes: TableRegistry<DB>;
|
|
22
|
+
actorId: string;
|
|
23
|
+
request: SyncPullRequest;
|
|
24
|
+
}): Promise<PullResult>;
|
|
25
|
+
//# sourceMappingURL=pull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/server-role/pull.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,EAAE,SAAS,aAAa,GAAG,aAAa,EACxC,IAAI,EAAE;IACN,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,OAAO,CAAC,UAAU,CAAC,CAStB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/relay - Server Role Pull Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles pulls from local clients, serving changes stored locally
|
|
5
|
+
* on the relay.
|
|
6
|
+
*/
|
|
7
|
+
import { pull } from '@syncular/server';
|
|
8
|
+
/**
|
|
9
|
+
* Pull commits for a local client from the relay.
|
|
10
|
+
*
|
|
11
|
+
* This wraps the standard server pull with relay-specific logic:
|
|
12
|
+
* - Restricts scopes to those the relay subscribes to
|
|
13
|
+
*/
|
|
14
|
+
export async function relayPull(args) {
|
|
15
|
+
// Use the standard pull - scope authorization is handled by shapes
|
|
16
|
+
return pull({
|
|
17
|
+
db: args.db,
|
|
18
|
+
dialect: args.dialect,
|
|
19
|
+
shapes: args.shapes,
|
|
20
|
+
actorId: args.actorId,
|
|
21
|
+
request: args.request,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/server-role/pull.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAmB,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIzD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAE7B,IAMD,EAAuB;IACtB,mEAAmE;IACnE,OAAO,IAAI,CAAC;QACV,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;AAAA,CACJ"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/relay - Server Role Push Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles pushes from local clients, storing them locally and
|
|
5
|
+
* queueing them for forwarding to the main server.
|
|
6
|
+
*/
|
|
7
|
+
import type { SyncPushRequest } from '@syncular/core';
|
|
8
|
+
import type { ServerSyncDialect, TableRegistry } from '@syncular/server';
|
|
9
|
+
import { type PushCommitResult } from '@syncular/server';
|
|
10
|
+
import { type Kysely } from 'kysely';
|
|
11
|
+
import type { RelayDatabase } from '../schema';
|
|
12
|
+
/**
|
|
13
|
+
* Push a commit from a local client to the relay.
|
|
14
|
+
*
|
|
15
|
+
* This wraps the standard server pushCommit with relay-specific logic:
|
|
16
|
+
* 1. Validates that operations are within the relay's scope
|
|
17
|
+
* 2. Stores the commit locally
|
|
18
|
+
* 3. Enqueues the commit for forwarding to the main server
|
|
19
|
+
*/
|
|
20
|
+
export declare function relayPushCommit<DB extends RelayDatabase = RelayDatabase>(args: {
|
|
21
|
+
db: Kysely<DB>;
|
|
22
|
+
dialect: ServerSyncDialect;
|
|
23
|
+
shapes: TableRegistry<DB>;
|
|
24
|
+
actorId: string;
|
|
25
|
+
request: SyncPushRequest;
|
|
26
|
+
}): Promise<PushCommitResult>;
|
|
27
|
+
//# sourceMappingURL=push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../../src/server-role/push.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,KAAK,gBAAgB,EAAc,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAY/C;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,EAAE,SAAS,aAAa,GAAG,aAAa,EACxC,IAAI,EAAE;IACN,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4B5B"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/relay - Server Role Push Handler
|
|
3
|
+
*
|
|
4
|
+
* Handles pushes from local clients, storing them locally and
|
|
5
|
+
* queueing them for forwarding to the main server.
|
|
6
|
+
*/
|
|
7
|
+
import { pushCommit } from '@syncular/server';
|
|
8
|
+
import { sql } from 'kysely';
|
|
9
|
+
function randomId() {
|
|
10
|
+
if (typeof crypto !== 'undefined' &&
|
|
11
|
+
typeof crypto.randomUUID === 'function') {
|
|
12
|
+
return crypto.randomUUID();
|
|
13
|
+
}
|
|
14
|
+
return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Push a commit from a local client to the relay.
|
|
18
|
+
*
|
|
19
|
+
* This wraps the standard server pushCommit with relay-specific logic:
|
|
20
|
+
* 1. Validates that operations are within the relay's scope
|
|
21
|
+
* 2. Stores the commit locally
|
|
22
|
+
* 3. Enqueues the commit for forwarding to the main server
|
|
23
|
+
*/
|
|
24
|
+
export async function relayPushCommit(args) {
|
|
25
|
+
const { request } = args;
|
|
26
|
+
// Use the standard pushCommit - scope authorization is handled by shapes
|
|
27
|
+
const result = await pushCommit({
|
|
28
|
+
db: args.db,
|
|
29
|
+
dialect: args.dialect,
|
|
30
|
+
shapes: args.shapes,
|
|
31
|
+
actorId: args.actorId,
|
|
32
|
+
request,
|
|
33
|
+
});
|
|
34
|
+
// If the commit was applied, enqueue it for forwarding to main server
|
|
35
|
+
if (result.response.ok === true &&
|
|
36
|
+
result.response.status === 'applied' &&
|
|
37
|
+
typeof result.response.commitSeq === 'number') {
|
|
38
|
+
await enqueueForForwarding(args.db, {
|
|
39
|
+
localCommitSeq: result.response.commitSeq,
|
|
40
|
+
clientId: request.clientId,
|
|
41
|
+
clientCommitId: request.clientCommitId,
|
|
42
|
+
operations: request.operations,
|
|
43
|
+
schemaVersion: request.schemaVersion,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Enqueue a locally-committed change for forwarding to the main server.
|
|
50
|
+
*/
|
|
51
|
+
async function enqueueForForwarding(db, args) {
|
|
52
|
+
const now = Date.now();
|
|
53
|
+
await sql `
|
|
54
|
+
insert into ${sql.table('relay_forward_outbox')} (
|
|
55
|
+
id,
|
|
56
|
+
local_commit_seq,
|
|
57
|
+
client_id,
|
|
58
|
+
client_commit_id,
|
|
59
|
+
operations_json,
|
|
60
|
+
schema_version,
|
|
61
|
+
status,
|
|
62
|
+
main_commit_seq,
|
|
63
|
+
error,
|
|
64
|
+
last_response_json,
|
|
65
|
+
created_at,
|
|
66
|
+
updated_at,
|
|
67
|
+
attempt_count
|
|
68
|
+
)
|
|
69
|
+
values (
|
|
70
|
+
${randomId()},
|
|
71
|
+
${args.localCommitSeq},
|
|
72
|
+
${args.clientId},
|
|
73
|
+
${args.clientCommitId},
|
|
74
|
+
${JSON.stringify(args.operations)},
|
|
75
|
+
${args.schemaVersion},
|
|
76
|
+
'pending',
|
|
77
|
+
${null},
|
|
78
|
+
${null},
|
|
79
|
+
${null},
|
|
80
|
+
${now},
|
|
81
|
+
${now},
|
|
82
|
+
${0}
|
|
83
|
+
)
|
|
84
|
+
`.execute(db);
|
|
85
|
+
// Also create a sequence map entry for this commit
|
|
86
|
+
await sql `
|
|
87
|
+
insert into ${sql.table('relay_sequence_map')} (
|
|
88
|
+
local_commit_seq,
|
|
89
|
+
main_commit_seq,
|
|
90
|
+
status,
|
|
91
|
+
created_at,
|
|
92
|
+
updated_at
|
|
93
|
+
)
|
|
94
|
+
values (${args.localCommitSeq}, ${null}, 'pending', ${now}, ${now})
|
|
95
|
+
on conflict (local_commit_seq) do nothing
|
|
96
|
+
`.execute(db);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/server-role/push.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAyB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAe,GAAG,EAAE,MAAM,QAAQ,CAAC;AAG1C,SAAS,QAAQ,GAAW;IAC1B,IACE,OAAO,MAAM,KAAK,WAAW;QAC7B,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU,EACvC,CAAC;QACD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAAA,CAC/D;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAEnC,IAMD,EAA6B;IAC5B,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEzB,yEAAyE;IACzE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC;QAC9B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO;KACR,CAAC,CAAC;IAEH,sEAAsE;IACtE,IACE,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,IAAI;QAC3B,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,SAAS;QACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAC7C,CAAC;QACD,MAAM,oBAAoB,CAAC,IAAI,CAAC,EAAE,EAAE;YAClC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,SAAS;YACzC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,aAAa,EAAE,OAAO,CAAC,aAAa;SACrC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACf;AAED;;GAEG;AACH,KAAK,UAAU,oBAAoB,CACjC,EAAc,EACd,IAMC,EACc;IACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,MAAM,GAAG,CAAA;kBACO,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC;;;;;;;;;;;;;;;;QAgB3C,QAAQ,EAAE;QACV,IAAI,CAAC,cAAc;QACnB,IAAI,CAAC,QAAQ;QACb,IAAI,CAAC,cAAc;QACnB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC;QAC/B,IAAI,CAAC,aAAa;;QAElB,IAAI;QACJ,IAAI;QACJ,IAAI;QACJ,GAAG;QACH,GAAG;QACH,CAAC;;GAEN,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEd,mDAAmD;IACnD,MAAM,GAAG,CAAA;kBACO,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC;;;;;;;cAOnC,IAAI,CAAC,cAAc,KAAK,IAAI,gBAAgB,GAAG,KAAK,GAAG;;GAElE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,CACf"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@syncular/relay",
|
|
3
|
+
"version": "0.0.1-60",
|
|
4
|
+
"description": "Edge relay for Syncular distributed sync",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Benjamin Kniffler",
|
|
7
|
+
"homepage": "https://syncular.dev",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/syncular/syncular.git",
|
|
11
|
+
"directory": "packages/relay"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/syncular/syncular/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"sync",
|
|
18
|
+
"offline-first",
|
|
19
|
+
"realtime",
|
|
20
|
+
"database",
|
|
21
|
+
"typescript",
|
|
22
|
+
"relay",
|
|
23
|
+
"edge"
|
|
24
|
+
],
|
|
25
|
+
"private": false,
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"type": "module",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"bun": "./src/index.ts",
|
|
33
|
+
"import": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"tsgo": "tsgo --noEmit",
|
|
41
|
+
"build": "rm -rf dist && tsgo",
|
|
42
|
+
"release": "bun pm pack --destination . && npm publish ./*.tgz --tag latest && rm -f ./*.tgz"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@syncular/core": "0.0.1",
|
|
46
|
+
"@syncular/server": "0.0.1"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"hono": "^4.0.0",
|
|
50
|
+
"kysely": "^0.28.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@syncular/config": "0.0.0",
|
|
54
|
+
"@syncular/server-dialect-sqlite": "0.0.1",
|
|
55
|
+
"kysely": "*"
|
|
56
|
+
},
|
|
57
|
+
"files": [
|
|
58
|
+
"dist",
|
|
59
|
+
"src"
|
|
60
|
+
]
|
|
61
|
+
}
|