@syncular/server 0.0.1 → 0.0.2-126
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/README.md +25 -0
- package/dist/blobs/adapters/database.d.ts.map +1 -1
- package/dist/blobs/adapters/database.js +25 -3
- package/dist/blobs/adapters/database.js.map +1 -1
- package/dist/blobs/adapters/filesystem.d.ts +31 -0
- package/dist/blobs/adapters/filesystem.d.ts.map +1 -0
- package/dist/blobs/adapters/filesystem.js +140 -0
- package/dist/blobs/adapters/filesystem.js.map +1 -0
- package/dist/blobs/adapters/s3.d.ts +3 -2
- package/dist/blobs/adapters/s3.d.ts.map +1 -1
- package/dist/blobs/adapters/s3.js +49 -0
- package/dist/blobs/adapters/s3.js.map +1 -1
- package/dist/blobs/index.d.ts +1 -0
- package/dist/blobs/index.d.ts.map +1 -1
- package/dist/blobs/index.js +6 -5
- package/dist/blobs/index.js.map +1 -1
- package/dist/clients.d.ts +1 -0
- package/dist/clients.d.ts.map +1 -1
- package/dist/clients.js.map +1 -1
- package/dist/compaction.d.ts +1 -1
- package/dist/compaction.js +1 -1
- package/dist/dialect/base.d.ts +83 -0
- package/dist/dialect/base.d.ts.map +1 -0
- package/dist/dialect/base.js +144 -0
- package/dist/dialect/base.js.map +1 -0
- package/dist/dialect/helpers.d.ts +10 -0
- package/dist/dialect/helpers.d.ts.map +1 -0
- package/dist/dialect/helpers.js +59 -0
- package/dist/dialect/helpers.js.map +1 -0
- package/dist/dialect/index.d.ts +2 -0
- package/dist/dialect/index.d.ts.map +1 -1
- package/dist/dialect/index.js +3 -1
- package/dist/dialect/index.js.map +1 -1
- package/dist/dialect/types.d.ts +38 -46
- package/dist/dialect/types.d.ts.map +1 -1
- package/dist/{shapes → handlers}/create-handler.d.ts +18 -5
- package/dist/handlers/create-handler.d.ts.map +1 -0
- package/dist/{shapes → handlers}/create-handler.js +140 -43
- package/dist/handlers/create-handler.js.map +1 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +4 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/registry.d.ts.map +1 -0
- package/dist/handlers/registry.js.map +1 -0
- package/dist/{shapes → handlers}/types.d.ts +7 -7
- package/dist/{shapes → handlers}/types.d.ts.map +1 -1
- package/dist/{shapes → handlers}/types.js.map +1 -1
- package/dist/helpers/conflict.d.ts +1 -1
- package/dist/helpers/conflict.d.ts.map +1 -1
- package/dist/helpers/emitted-change.d.ts +1 -1
- package/dist/helpers/emitted-change.d.ts.map +1 -1
- package/dist/helpers/index.js +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -16
- package/dist/index.js.map +1 -1
- package/dist/notify.d.ts +47 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +85 -0
- package/dist/notify.js.map +1 -0
- package/dist/proxy/handler.d.ts +1 -1
- package/dist/proxy/handler.d.ts.map +1 -1
- package/dist/proxy/handler.js +15 -11
- package/dist/proxy/handler.js.map +1 -1
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/index.d.ts.map +1 -1
- package/dist/proxy/index.js +3 -3
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/mutation-detector.d.ts +4 -0
- package/dist/proxy/mutation-detector.d.ts.map +1 -1
- package/dist/proxy/mutation-detector.js +209 -24
- package/dist/proxy/mutation-detector.js.map +1 -1
- package/dist/proxy/oplog.d.ts +2 -1
- package/dist/proxy/oplog.d.ts.map +1 -1
- package/dist/proxy/oplog.js +15 -9
- package/dist/proxy/oplog.js.map +1 -1
- package/dist/proxy/registry.d.ts +0 -11
- package/dist/proxy/registry.d.ts.map +1 -1
- package/dist/proxy/registry.js +0 -24
- package/dist/proxy/registry.js.map +1 -1
- package/dist/proxy/types.d.ts +2 -0
- package/dist/proxy/types.d.ts.map +1 -1
- package/dist/pull.d.ts +4 -3
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +565 -314
- package/dist/pull.js.map +1 -1
- package/dist/push.d.ts +15 -3
- package/dist/push.d.ts.map +1 -1
- package/dist/push.js +359 -229
- package/dist/push.js.map +1 -1
- package/dist/realtime/index.js +1 -1
- package/dist/realtime/types.d.ts +2 -0
- package/dist/realtime/types.d.ts.map +1 -1
- package/dist/schema.d.ts +11 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/snapshot-chunks/db-metadata.d.ts +6 -1
- package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -1
- package/dist/snapshot-chunks/db-metadata.js +261 -92
- package/dist/snapshot-chunks/db-metadata.js.map +1 -1
- package/dist/snapshot-chunks/index.d.ts +0 -1
- package/dist/snapshot-chunks/index.d.ts.map +1 -1
- package/dist/snapshot-chunks/index.js +2 -3
- package/dist/snapshot-chunks/index.js.map +1 -1
- package/dist/snapshot-chunks/types.d.ts +20 -5
- package/dist/snapshot-chunks/types.d.ts.map +1 -1
- package/dist/snapshot-chunks.d.ts +12 -8
- package/dist/snapshot-chunks.d.ts.map +1 -1
- package/dist/snapshot-chunks.js +40 -12
- package/dist/snapshot-chunks.js.map +1 -1
- package/dist/subscriptions/index.js +1 -1
- package/dist/subscriptions/resolve.d.ts +6 -6
- package/dist/subscriptions/resolve.d.ts.map +1 -1
- package/dist/subscriptions/resolve.js +53 -14
- package/dist/subscriptions/resolve.js.map +1 -1
- package/package.json +28 -7
- package/src/blobs/adapters/database.test.ts +67 -0
- package/src/blobs/adapters/database.ts +34 -9
- package/src/blobs/adapters/filesystem.test.ts +132 -0
- package/src/blobs/adapters/filesystem.ts +189 -0
- package/src/blobs/adapters/s3.test.ts +522 -0
- package/src/blobs/adapters/s3.ts +55 -2
- package/src/blobs/index.ts +1 -0
- package/src/clients.ts +1 -0
- package/src/compaction.ts +1 -1
- package/src/dialect/base.ts +292 -0
- package/src/dialect/helpers.ts +61 -0
- package/src/dialect/index.ts +2 -0
- package/src/dialect/types.ts +50 -54
- package/src/{shapes → handlers}/create-handler.ts +219 -64
- package/src/{shapes → handlers}/types.ts +10 -7
- package/src/helpers/conflict.ts +1 -1
- package/src/helpers/emitted-change.ts +1 -1
- package/src/index.ts +2 -1
- package/src/notify.test.ts +516 -0
- package/src/notify.ts +131 -0
- package/src/proxy/handler.test.ts +120 -0
- package/src/proxy/handler.ts +18 -10
- package/src/proxy/index.ts +2 -1
- package/src/proxy/mutation-detector.test.ts +71 -0
- package/src/proxy/mutation-detector.ts +227 -29
- package/src/proxy/oplog.ts +19 -10
- package/src/proxy/registry.ts +0 -33
- package/src/proxy/types.ts +2 -0
- package/src/pull.ts +788 -405
- package/src/push.ts +507 -312
- package/src/realtime/types.ts +2 -0
- package/src/schema.ts +11 -1
- package/src/snapshot-chunks/db-metadata.test.ts +169 -0
- package/src/snapshot-chunks/db-metadata.ts +347 -105
- package/src/snapshot-chunks/index.ts +0 -1
- package/src/snapshot-chunks/types.ts +31 -5
- package/src/snapshot-chunks.ts +60 -21
- package/src/subscriptions/resolve.ts +73 -18
- package/dist/shapes/create-handler.d.ts.map +0 -1
- package/dist/shapes/create-handler.js.map +0 -1
- package/dist/shapes/index.d.ts.map +0 -1
- package/dist/shapes/index.js +0 -4
- package/dist/shapes/index.js.map +0 -1
- package/dist/shapes/registry.d.ts.map +0 -1
- package/dist/shapes/registry.js.map +0 -1
- package/dist/snapshot-chunks/adapters/s3.d.ts +0 -63
- package/dist/snapshot-chunks/adapters/s3.d.ts.map +0 -1
- package/dist/snapshot-chunks/adapters/s3.js +0 -50
- package/dist/snapshot-chunks/adapters/s3.js.map +0 -1
- package/src/snapshot-chunks/adapters/s3.ts +0 -68
- /package/dist/{shapes → handlers}/index.d.ts +0 -0
- /package/dist/{shapes → handlers}/registry.d.ts +0 -0
- /package/dist/{shapes → handlers}/registry.js +0 -0
- /package/dist/{shapes → handlers}/types.js +0 -0
- /package/src/{shapes → handlers}/index.ts +0 -0
- /package/src/{shapes → handlers}/registry.ts +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server - Base Server Sync Dialect
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class that implements shared query methods for all
|
|
5
|
+
* database-specific sync dialect implementations.
|
|
6
|
+
*/
|
|
7
|
+
import { sql } from 'kysely';
|
|
8
|
+
import { coerceIsoString, coerceNumber, parseScopes } from './helpers.js';
|
|
9
|
+
/**
|
|
10
|
+
* Abstract base class for server sync dialects.
|
|
11
|
+
*
|
|
12
|
+
* Implements methods that are identical across dialects (pure SQL with no
|
|
13
|
+
* dialect-specific syntax) and methods that differ only in trivial SQL
|
|
14
|
+
* fragments (IN vs ANY, jsonb casts). Dialect-specific fragments are
|
|
15
|
+
* provided via small abstract hook methods.
|
|
16
|
+
*
|
|
17
|
+
* Genuinely different methods (DDL, transaction control, scope filtering,
|
|
18
|
+
* compaction) remain abstract for each dialect to implement.
|
|
19
|
+
*/
|
|
20
|
+
export class BaseServerSyncDialect {
|
|
21
|
+
// ===========================================================================
|
|
22
|
+
// Concrete methods (identical SQL across dialects)
|
|
23
|
+
// ===========================================================================
|
|
24
|
+
async readMaxCommitSeq(db, options) {
|
|
25
|
+
const partitionId = options?.partitionId ?? 'default';
|
|
26
|
+
const res = await sql `
|
|
27
|
+
SELECT max(commit_seq) as max_seq
|
|
28
|
+
FROM sync_commits
|
|
29
|
+
WHERE partition_id = ${partitionId}
|
|
30
|
+
`.execute(db);
|
|
31
|
+
return coerceNumber(res.rows[0]?.max_seq) ?? 0;
|
|
32
|
+
}
|
|
33
|
+
async readMinCommitSeq(db, options) {
|
|
34
|
+
const partitionId = options?.partitionId ?? 'default';
|
|
35
|
+
const res = await sql `
|
|
36
|
+
SELECT min(commit_seq) as min_seq
|
|
37
|
+
FROM sync_commits
|
|
38
|
+
WHERE partition_id = ${partitionId}
|
|
39
|
+
`.execute(db);
|
|
40
|
+
return coerceNumber(res.rows[0]?.min_seq) ?? 0;
|
|
41
|
+
}
|
|
42
|
+
async readAffectedTablesFromChanges(db, commitSeq, options) {
|
|
43
|
+
const partitionId = options?.partitionId ?? 'default';
|
|
44
|
+
const res = await sql `
|
|
45
|
+
SELECT DISTINCT "table"
|
|
46
|
+
FROM sync_changes
|
|
47
|
+
WHERE commit_seq = ${commitSeq}
|
|
48
|
+
AND partition_id = ${partitionId}
|
|
49
|
+
`.execute(db);
|
|
50
|
+
return res.rows
|
|
51
|
+
.map((r) => r.table)
|
|
52
|
+
.filter((t) => typeof t === 'string' && t.length > 0);
|
|
53
|
+
}
|
|
54
|
+
dbToScopes(value) {
|
|
55
|
+
return parseScopes(value);
|
|
56
|
+
}
|
|
57
|
+
// ===========================================================================
|
|
58
|
+
// Concrete methods using hooks (trivial dialect diffs)
|
|
59
|
+
// ===========================================================================
|
|
60
|
+
async readCommitSeqsForPull(db, args) {
|
|
61
|
+
const partitionId = args.partitionId ?? 'default';
|
|
62
|
+
if (args.tables.length === 0)
|
|
63
|
+
return [];
|
|
64
|
+
const tablesFilter = this.buildStringListFilter(args.tables);
|
|
65
|
+
const res = await sql `
|
|
66
|
+
SELECT DISTINCT commit_seq
|
|
67
|
+
FROM sync_table_commits
|
|
68
|
+
WHERE partition_id = ${partitionId}
|
|
69
|
+
AND "table" ${tablesFilter}
|
|
70
|
+
AND commit_seq > ${args.cursor}
|
|
71
|
+
ORDER BY commit_seq ASC
|
|
72
|
+
LIMIT ${args.limitCommits}
|
|
73
|
+
`.execute(db);
|
|
74
|
+
return res.rows
|
|
75
|
+
.map((r) => coerceNumber(r.commit_seq))
|
|
76
|
+
.filter((n) => typeof n === 'number' && Number.isFinite(n) && n > args.cursor);
|
|
77
|
+
}
|
|
78
|
+
async readCommits(db, commitSeqs, options) {
|
|
79
|
+
const partitionId = options?.partitionId ?? 'default';
|
|
80
|
+
if (commitSeqs.length === 0)
|
|
81
|
+
return [];
|
|
82
|
+
const seqsFilter = this.buildNumberListFilter(commitSeqs);
|
|
83
|
+
const res = await sql `
|
|
84
|
+
SELECT commit_seq, actor_id, created_at, result_json
|
|
85
|
+
FROM sync_commits
|
|
86
|
+
WHERE commit_seq ${seqsFilter}
|
|
87
|
+
AND partition_id = ${partitionId}
|
|
88
|
+
ORDER BY commit_seq ASC
|
|
89
|
+
`.execute(db);
|
|
90
|
+
return res.rows.map((row) => ({
|
|
91
|
+
commit_seq: coerceNumber(row.commit_seq) ?? 0,
|
|
92
|
+
actor_id: row.actor_id,
|
|
93
|
+
created_at: coerceIsoString(row.created_at),
|
|
94
|
+
result_json: row.result_json ?? null,
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
async recordClientCursor(db, args) {
|
|
98
|
+
const partitionId = args.partitionId ?? 'default';
|
|
99
|
+
const now = new Date().toISOString();
|
|
100
|
+
const scopesJson = JSON.stringify(args.effectiveScopes);
|
|
101
|
+
await sql `
|
|
102
|
+
INSERT INTO sync_client_cursors (partition_id, client_id, actor_id, cursor, effective_scopes, updated_at)
|
|
103
|
+
VALUES (${partitionId}, ${args.clientId}, ${args.actorId}, ${args.cursor}, ${scopesJson}, ${now})
|
|
104
|
+
ON CONFLICT(partition_id, client_id) DO UPDATE SET
|
|
105
|
+
actor_id = ${args.actorId},
|
|
106
|
+
cursor = ${args.cursor},
|
|
107
|
+
effective_scopes = ${scopesJson},
|
|
108
|
+
updated_at = ${now}
|
|
109
|
+
`.execute(db);
|
|
110
|
+
}
|
|
111
|
+
async *iterateIncrementalPullRows(db, args) {
|
|
112
|
+
const limitCommits = Math.max(1, Math.min(500, args.limitCommits));
|
|
113
|
+
const batchSize = Math.max(1, Math.min(limitCommits, args.batchSize ?? 100, 500));
|
|
114
|
+
let processedCommits = 0;
|
|
115
|
+
let cursor = args.cursor;
|
|
116
|
+
while (processedCommits < limitCommits) {
|
|
117
|
+
const remainingCommits = limitCommits - processedCommits;
|
|
118
|
+
const commitLimit = Math.min(batchSize, remainingCommits);
|
|
119
|
+
const rows = await this.readIncrementalPullRowsBatch(db, {
|
|
120
|
+
table: args.table,
|
|
121
|
+
scopes: args.scopes,
|
|
122
|
+
cursor,
|
|
123
|
+
limitCommits: commitLimit,
|
|
124
|
+
partitionId: args.partitionId,
|
|
125
|
+
});
|
|
126
|
+
if (rows.length === 0)
|
|
127
|
+
break;
|
|
128
|
+
let maxCommitSeq = cursor;
|
|
129
|
+
const commitSeqs = new Set();
|
|
130
|
+
for (const row of rows) {
|
|
131
|
+
maxCommitSeq = Math.max(maxCommitSeq, row.commit_seq);
|
|
132
|
+
commitSeqs.add(row.commit_seq);
|
|
133
|
+
yield row;
|
|
134
|
+
}
|
|
135
|
+
if (maxCommitSeq <= cursor)
|
|
136
|
+
break;
|
|
137
|
+
processedCommits += commitSeqs.size;
|
|
138
|
+
cursor = maxCommitSeq;
|
|
139
|
+
if (commitSeqs.size < commitLimit)
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/dialect/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server - Shared dialect helpers
|
|
3
|
+
*
|
|
4
|
+
* Pure helper functions used by all server sync dialect implementations.
|
|
5
|
+
*/
|
|
6
|
+
import type { StoredScopes } from '@syncular/core';
|
|
7
|
+
export declare function coerceNumber(value: unknown): number | null;
|
|
8
|
+
export declare function coerceIsoString(value: unknown): string;
|
|
9
|
+
export declare function parseScopes(value: unknown): StoredScopes;
|
|
10
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/dialect/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAU1D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAItD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAkCxD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server - Shared dialect helpers
|
|
3
|
+
*
|
|
4
|
+
* Pure helper functions used by all server sync dialect implementations.
|
|
5
|
+
*/
|
|
6
|
+
export function coerceNumber(value) {
|
|
7
|
+
if (value === null || value === undefined)
|
|
8
|
+
return null;
|
|
9
|
+
if (typeof value === 'number')
|
|
10
|
+
return Number.isFinite(value) ? value : null;
|
|
11
|
+
if (typeof value === 'bigint')
|
|
12
|
+
return Number.isFinite(Number(value)) ? Number(value) : null;
|
|
13
|
+
if (typeof value === 'string') {
|
|
14
|
+
const n = Number(value);
|
|
15
|
+
return Number.isFinite(n) ? n : null;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
export function coerceIsoString(value) {
|
|
20
|
+
if (typeof value === 'string')
|
|
21
|
+
return value;
|
|
22
|
+
if (value instanceof Date)
|
|
23
|
+
return value.toISOString();
|
|
24
|
+
return String(value);
|
|
25
|
+
}
|
|
26
|
+
export function parseScopes(value) {
|
|
27
|
+
if (value === null || value === undefined)
|
|
28
|
+
return {};
|
|
29
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [k, v] of Object.entries(value)) {
|
|
32
|
+
if (typeof v === 'string') {
|
|
33
|
+
result[k] = v;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
if (typeof value === 'string') {
|
|
39
|
+
try {
|
|
40
|
+
const parsed = JSON.parse(value);
|
|
41
|
+
if (typeof parsed === 'object' &&
|
|
42
|
+
parsed !== null &&
|
|
43
|
+
!Array.isArray(parsed)) {
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
46
|
+
if (typeof v === 'string') {
|
|
47
|
+
result[k] = v;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// ignore
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/dialect/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,UAAU,YAAY,CAAC,KAAc,EAAiB;IAC1D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5E,IAAI,OAAO,KAAK,KAAK,QAAQ;QAC3B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACb;AAED,MAAM,UAAU,eAAe,CAAC,KAAc,EAAU;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AAAA,CACtB;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAgB;IACxD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;YACtE,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,IACE,OAAO,MAAM,KAAK,QAAQ;gBAC1B,MAAM,KAAK,IAAI;gBACf,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACtB,CAAC;gBACD,MAAM,MAAM,GAAiB,EAAE,CAAC;gBAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CACjC,MAAiC,CAClC,EAAE,CAAC;oBACF,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;wBAC1B,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBAChB,CAAC;gBACH,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AAAA,CACX"}
|
package/dist/dialect/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dialect/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dialect/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/dist/dialect/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dialect/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dialect/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
|
package/dist/dialect/types.d.ts
CHANGED
|
@@ -16,6 +16,26 @@ export type DbExecutor<DB extends SyncCoreDb = SyncCoreDb> = Kysely<DB> | Transa
|
|
|
16
16
|
* Supported dialect names.
|
|
17
17
|
*/
|
|
18
18
|
export type ServerSyncDialectName = string;
|
|
19
|
+
export interface IncrementalPullRowsArgs {
|
|
20
|
+
table: string;
|
|
21
|
+
scopes: ScopeValues;
|
|
22
|
+
cursor: number;
|
|
23
|
+
limitCommits: number;
|
|
24
|
+
partitionId?: string;
|
|
25
|
+
batchSize?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface IncrementalPullRow {
|
|
28
|
+
commit_seq: number;
|
|
29
|
+
actor_id: string;
|
|
30
|
+
created_at: string;
|
|
31
|
+
change_id: number;
|
|
32
|
+
table: string;
|
|
33
|
+
row_id: string;
|
|
34
|
+
op: SyncOp;
|
|
35
|
+
row_json: unknown | null;
|
|
36
|
+
row_version: number | null;
|
|
37
|
+
scopes: StoredScopes;
|
|
38
|
+
}
|
|
19
39
|
export interface ServerSyncDialect {
|
|
20
40
|
readonly name: ServerSyncDialectName;
|
|
21
41
|
/** Create sync tables + indexes (idempotent) */
|
|
@@ -27,9 +47,13 @@ export interface ServerSyncDialect {
|
|
|
27
47
|
/** Set REPEATABLE READ (or closest equivalent) */
|
|
28
48
|
setRepeatableRead<DB extends SyncCoreDb>(trx: DbExecutor<DB>): Promise<void>;
|
|
29
49
|
/** Read the maximum committed commit_seq (0 if none) */
|
|
30
|
-
readMaxCommitSeq<DB extends SyncCoreDb>(db: DbExecutor<DB
|
|
50
|
+
readMaxCommitSeq<DB extends SyncCoreDb>(db: DbExecutor<DB>, options?: {
|
|
51
|
+
partitionId?: string;
|
|
52
|
+
}): Promise<number>;
|
|
31
53
|
/** Read the minimum committed commit_seq (0 if none) */
|
|
32
|
-
readMinCommitSeq<DB extends SyncCoreDb>(db: DbExecutor<DB
|
|
54
|
+
readMinCommitSeq<DB extends SyncCoreDb>(db: DbExecutor<DB>, options?: {
|
|
55
|
+
partitionId?: string;
|
|
56
|
+
}): Promise<number>;
|
|
33
57
|
/**
|
|
34
58
|
* Read the next commit sequence numbers that have changes for the given tables.
|
|
35
59
|
* Must return commit_seq values in ascending order.
|
|
@@ -38,9 +62,12 @@ export interface ServerSyncDialect {
|
|
|
38
62
|
cursor: number;
|
|
39
63
|
limitCommits: number;
|
|
40
64
|
tables: string[];
|
|
65
|
+
partitionId?: string;
|
|
41
66
|
}): Promise<number[]>;
|
|
42
67
|
/** Read commit metadata for commit_seq values */
|
|
43
|
-
readCommits<DB extends SyncCoreDb>(db: DbExecutor<DB>, commitSeqs: number[]
|
|
68
|
+
readCommits<DB extends SyncCoreDb>(db: DbExecutor<DB>, commitSeqs: number[], options?: {
|
|
69
|
+
partitionId?: string;
|
|
70
|
+
}): Promise<SyncCommitRow[]>;
|
|
44
71
|
/**
|
|
45
72
|
* Read changes for commit_seq values, filtered by table and scopes.
|
|
46
73
|
* Uses JSONB filtering for scope matching.
|
|
@@ -49,53 +76,15 @@ export interface ServerSyncDialect {
|
|
|
49
76
|
commitSeqs: number[];
|
|
50
77
|
table: string;
|
|
51
78
|
scopes: ScopeValues;
|
|
79
|
+
partitionId?: string;
|
|
52
80
|
}): Promise<SyncChangeRow[]>;
|
|
53
81
|
/**
|
|
54
|
-
*
|
|
82
|
+
* Incremental pull iterator for a subscription.
|
|
55
83
|
*
|
|
56
|
-
*
|
|
84
|
+
* Yields change rows joined with commit metadata and filtered by
|
|
57
85
|
* the subscription's table and scope values.
|
|
58
86
|
*/
|
|
59
|
-
|
|
60
|
-
table: string;
|
|
61
|
-
scopes: ScopeValues;
|
|
62
|
-
cursor: number;
|
|
63
|
-
limitCommits: number;
|
|
64
|
-
}): Promise<Array<{
|
|
65
|
-
commit_seq: number;
|
|
66
|
-
actor_id: string;
|
|
67
|
-
created_at: string;
|
|
68
|
-
change_id: number;
|
|
69
|
-
table: string;
|
|
70
|
-
row_id: string;
|
|
71
|
-
op: SyncOp;
|
|
72
|
-
row_json: unknown | null;
|
|
73
|
-
row_version: number | null;
|
|
74
|
-
scopes: StoredScopes;
|
|
75
|
-
}>>;
|
|
76
|
-
/**
|
|
77
|
-
* Streaming incremental pull for large result sets.
|
|
78
|
-
*
|
|
79
|
-
* Yields changes one at a time instead of loading all into memory.
|
|
80
|
-
* Use this when expecting large numbers of changes.
|
|
81
|
-
*/
|
|
82
|
-
streamIncrementalPullRows?<DB extends SyncCoreDb>(db: DbExecutor<DB>, args: {
|
|
83
|
-
table: string;
|
|
84
|
-
scopes: ScopeValues;
|
|
85
|
-
cursor: number;
|
|
86
|
-
limitCommits: number;
|
|
87
|
-
}): AsyncGenerator<{
|
|
88
|
-
commit_seq: number;
|
|
89
|
-
actor_id: string;
|
|
90
|
-
created_at: string;
|
|
91
|
-
change_id: number;
|
|
92
|
-
table: string;
|
|
93
|
-
row_id: string;
|
|
94
|
-
op: SyncOp;
|
|
95
|
-
row_json: unknown | null;
|
|
96
|
-
row_version: number | null;
|
|
97
|
-
scopes: StoredScopes;
|
|
98
|
-
}>;
|
|
87
|
+
iterateIncrementalPullRows<DB extends SyncCoreDb>(db: DbExecutor<DB>, args: IncrementalPullRowsArgs): AsyncGenerator<IncrementalPullRow>;
|
|
99
88
|
/**
|
|
100
89
|
* Optional compaction of the change log to reduce storage.
|
|
101
90
|
*
|
|
@@ -109,6 +98,7 @@ export interface ServerSyncDialect {
|
|
|
109
98
|
* Record/update a client cursor for tracking and pruning.
|
|
110
99
|
*/
|
|
111
100
|
recordClientCursor<DB extends SyncCoreDb>(db: DbExecutor<DB>, args: {
|
|
101
|
+
partitionId?: string;
|
|
112
102
|
clientId: string;
|
|
113
103
|
actorId: string;
|
|
114
104
|
cursor: number;
|
|
@@ -140,7 +130,9 @@ export interface ServerSyncDialect {
|
|
|
140
130
|
* Read distinct tables from sync_changes for a given commit.
|
|
141
131
|
* Used for realtime notifications.
|
|
142
132
|
*/
|
|
143
|
-
readAffectedTablesFromChanges<DB extends SyncCoreDb>(db: DbExecutor<DB>, commitSeq: number
|
|
133
|
+
readAffectedTablesFromChanges<DB extends SyncCoreDb>(db: DbExecutor<DB>, commitSeq: number, options?: {
|
|
134
|
+
partitionId?: string;
|
|
135
|
+
}): Promise<string[]>;
|
|
144
136
|
/**
|
|
145
137
|
* Convert database array representation to string[].
|
|
146
138
|
* For Postgres: returns as-is (native array)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dialect/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE1E;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,EAAE,SAAS,UAAU,GAAG,UAAU,IACrD,MAAM,CAAC,EAAE,CAAC,GACV,WAAW,CAAC,EAAE,CAAC,CAAC;AAEpB;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dialect/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @syncular/server - Declarative server handler helper
|
|
3
3
|
*/
|
|
4
|
-
import type {
|
|
4
|
+
import type { ScopeValuesFromPatterns, ScopeDefinition as SimpleScopeDefinition, StoredScopes, SyncOperation } from '@syncular/core';
|
|
5
|
+
import { type ColumnCodecDialect, type ColumnCodecSource } from '@syncular/core';
|
|
5
6
|
import type { Selectable, Updateable } from 'kysely';
|
|
6
7
|
import type { SyncCoreDb } from '../schema';
|
|
7
8
|
import type { ServerApplyOperationContext, ServerContext, ServerTableHandler } from './types';
|
|
@@ -20,7 +21,7 @@ export type ScopeColumnMap = Record<string, string>;
|
|
|
20
21
|
/**
|
|
21
22
|
* Options for creating a declarative server handler.
|
|
22
23
|
*/
|
|
23
|
-
export interface CreateServerHandlerOptions<ServerDB extends SyncCoreDb, ClientDB, TableName extends keyof ServerDB & keyof ClientDB & string> {
|
|
24
|
+
export interface CreateServerHandlerOptions<ServerDB extends SyncCoreDb, ClientDB, TableName extends keyof ServerDB & keyof ClientDB & string, ScopeDefs extends readonly SimpleScopeDefinition[] = readonly SimpleScopeDefinition[]> {
|
|
24
25
|
/** Table name in the database */
|
|
25
26
|
table: TableName;
|
|
26
27
|
/**
|
|
@@ -38,7 +39,7 @@ export interface CreateServerHandlerOptions<ServerDB extends SyncCoreDb, ClientD
|
|
|
38
39
|
* ]
|
|
39
40
|
* ```
|
|
40
41
|
*/
|
|
41
|
-
scopes:
|
|
42
|
+
scopes: ScopeDefs;
|
|
42
43
|
/** Primary key column name (default: 'id') */
|
|
43
44
|
primaryKey?: string;
|
|
44
45
|
/** Version column name (default: 'server_version') */
|
|
@@ -57,7 +58,7 @@ export interface CreateServerHandlerOptions<ServerDB extends SyncCoreDb, ClientD
|
|
|
57
58
|
* project_id: await getProjectsForUser(ctx.db, ctx.actorId),
|
|
58
59
|
* })
|
|
59
60
|
*/
|
|
60
|
-
resolveScopes: (ctx: ServerContext<ServerDB>) => Promise<
|
|
61
|
+
resolveScopes: (ctx: ServerContext<ServerDB>) => Promise<ScopeValuesFromPatterns<ScopeDefs>>;
|
|
61
62
|
/**
|
|
62
63
|
* Transform inbound row from client to server format.
|
|
63
64
|
* Use ctx.schemaVersion to handle older client versions.
|
|
@@ -69,6 +70,18 @@ export interface CreateServerHandlerOptions<ServerDB extends SyncCoreDb, ClientD
|
|
|
69
70
|
* Transform outbound row from server to client format.
|
|
70
71
|
*/
|
|
71
72
|
transformOutbound?: (row: Selectable<ServerDB[TableName]>) => ClientDB[TableName];
|
|
73
|
+
/**
|
|
74
|
+
* Optional column codec resolver.
|
|
75
|
+
* Receives `{ table, column, sqlType?, dialect? }` and returns a codec.
|
|
76
|
+
* Only used by default snapshot/apply paths when the corresponding
|
|
77
|
+
* transform hook is not provided.
|
|
78
|
+
*/
|
|
79
|
+
columnCodecs?: ColumnCodecSource;
|
|
80
|
+
/**
|
|
81
|
+
* Dialect used for codec dialect overrides.
|
|
82
|
+
* Default: 'sqlite'
|
|
83
|
+
*/
|
|
84
|
+
codecDialect?: ColumnCodecDialect;
|
|
72
85
|
/**
|
|
73
86
|
* Authorize an operation before applying.
|
|
74
87
|
* Return true to allow, or an error object to reject.
|
|
@@ -114,6 +127,6 @@ export interface CreateServerHandlerOptions<ServerDB extends SyncCoreDb, ClientD
|
|
|
114
127
|
* });
|
|
115
128
|
* ```
|
|
116
129
|
*/
|
|
117
|
-
export declare function createServerHandler<ServerDB extends SyncCoreDb, ClientDB, TableName extends keyof ServerDB & keyof ClientDB & string>(options: CreateServerHandlerOptions<ServerDB, ClientDB, TableName>): ServerTableHandler<ServerDB>;
|
|
130
|
+
export declare function createServerHandler<ServerDB extends SyncCoreDb, ClientDB, TableName extends keyof ServerDB & keyof ClientDB & string, ScopeDefs extends readonly SimpleScopeDefinition[] = readonly SimpleScopeDefinition[]>(options: CreateServerHandlerOptions<ServerDB, ClientDB, TableName, ScopeDefs>): ServerTableHandler<ServerDB>;
|
|
118
131
|
export {};
|
|
119
132
|
//# sourceMappingURL=create-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/create-handler.ts"],"names":[],"mappings":"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"}
|