@syncular/server 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/blobs/adapters/database.d.ts +83 -0
- package/dist/blobs/adapters/database.d.ts.map +1 -0
- package/dist/blobs/adapters/database.js +180 -0
- package/dist/blobs/adapters/database.js.map +1 -0
- package/dist/blobs/adapters/s3.d.ts +82 -0
- package/dist/blobs/adapters/s3.d.ts.map +1 -0
- package/dist/blobs/adapters/s3.js +170 -0
- package/dist/blobs/adapters/s3.js.map +1 -0
- package/dist/blobs/index.d.ts +9 -0
- package/dist/blobs/index.d.ts.map +1 -0
- package/dist/blobs/index.js +9 -0
- package/dist/blobs/index.js.map +1 -0
- package/dist/blobs/manager.d.ts +195 -0
- package/dist/blobs/manager.d.ts.map +1 -0
- package/dist/blobs/manager.js +440 -0
- package/dist/blobs/manager.js.map +1 -0
- package/dist/blobs/migrate.d.ts +27 -0
- package/dist/blobs/migrate.d.ts.map +1 -0
- package/dist/blobs/migrate.js +119 -0
- package/dist/blobs/migrate.js.map +1 -0
- package/dist/blobs/types.d.ts +54 -0
- package/dist/blobs/types.d.ts.map +1 -0
- package/dist/blobs/types.js +5 -0
- package/dist/blobs/types.js.map +1 -0
- package/dist/clients.d.ts +14 -0
- package/dist/clients.d.ts.map +1 -0
- package/dist/clients.js +7 -0
- package/dist/clients.js.map +1 -0
- package/dist/compaction.d.ts +27 -0
- package/dist/compaction.d.ts.map +1 -0
- package/dist/compaction.js +49 -0
- package/dist/compaction.js.map +1 -0
- package/dist/dialect/index.d.ts +5 -0
- package/dist/dialect/index.d.ts.map +1 -0
- package/dist/dialect/index.js +5 -0
- package/dist/dialect/index.js.map +1 -0
- package/dist/dialect/types.d.ts +170 -0
- package/dist/dialect/types.d.ts.map +1 -0
- package/dist/dialect/types.js +8 -0
- package/dist/dialect/types.js.map +1 -0
- package/dist/helpers/conflict.d.ts +52 -0
- package/dist/helpers/conflict.d.ts.map +1 -0
- package/dist/helpers/conflict.js +49 -0
- package/dist/helpers/conflict.js.map +1 -0
- package/dist/helpers/emitted-change.d.ts +56 -0
- package/dist/helpers/emitted-change.d.ts.map +1 -0
- package/dist/helpers/emitted-change.js +46 -0
- package/dist/helpers/emitted-change.js.map +1 -0
- package/dist/helpers/index.d.ts +10 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +10 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/paginate.d.ts +49 -0
- package/dist/helpers/paginate.d.ts.map +1 -0
- package/dist/helpers/paginate.js +54 -0
- package/dist/helpers/paginate.js.map +1 -0
- package/dist/helpers/scope-strings.d.ts +74 -0
- package/dist/helpers/scope-strings.d.ts.map +1 -0
- package/dist/helpers/scope-strings.js +82 -0
- package/dist/helpers/scope-strings.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/migrate.d.ts +14 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +13 -0
- package/dist/migrate.js.map +1 -0
- package/dist/proxy/handler.d.ts +42 -0
- package/dist/proxy/handler.d.ts.map +1 -0
- package/dist/proxy/handler.js +99 -0
- package/dist/proxy/handler.js.map +1 -0
- package/dist/proxy/index.d.ts +9 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/index.js +14 -0
- package/dist/proxy/index.js.map +1 -0
- package/dist/proxy/mutation-detector.d.ts +31 -0
- package/dist/proxy/mutation-detector.d.ts.map +1 -0
- package/dist/proxy/mutation-detector.js +61 -0
- package/dist/proxy/mutation-detector.js.map +1 -0
- package/dist/proxy/oplog.d.ts +30 -0
- package/dist/proxy/oplog.d.ts.map +1 -0
- package/dist/proxy/oplog.js +110 -0
- package/dist/proxy/oplog.js.map +1 -0
- package/dist/proxy/registry.d.ts +35 -0
- package/dist/proxy/registry.d.ts.map +1 -0
- package/dist/proxy/registry.js +49 -0
- package/dist/proxy/registry.js.map +1 -0
- package/dist/proxy/types.d.ts +44 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/types.js +7 -0
- package/dist/proxy/types.js.map +1 -0
- package/dist/prune.d.ts +37 -0
- package/dist/prune.d.ts.map +1 -0
- package/dist/prune.js +112 -0
- package/dist/prune.js.map +1 -0
- package/dist/pull.d.ts +31 -0
- package/dist/pull.d.ts.map +1 -0
- package/dist/pull.js +414 -0
- package/dist/pull.js.map +1 -0
- package/dist/push.d.ts +33 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +329 -0
- package/dist/push.js.map +1 -0
- package/dist/realtime/in-memory.d.ts +13 -0
- package/dist/realtime/in-memory.d.ts.map +1 -0
- package/dist/realtime/in-memory.js +28 -0
- package/dist/realtime/in-memory.js.map +1 -0
- package/dist/realtime/index.d.ts +3 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +2 -0
- package/dist/realtime/index.js.map +1 -0
- package/dist/realtime/types.d.ts +50 -0
- package/dist/realtime/types.d.ts.map +1 -0
- package/dist/realtime/types.js +7 -0
- package/dist/realtime/types.js.map +1 -0
- package/dist/schema.d.ts +164 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +10 -0
- package/dist/schema.js.map +1 -0
- package/dist/shapes/create-handler.d.ts +119 -0
- package/dist/shapes/create-handler.d.ts.map +1 -0
- package/dist/shapes/create-handler.js +327 -0
- package/dist/shapes/create-handler.js.map +1 -0
- package/dist/shapes/index.d.ts +4 -0
- package/dist/shapes/index.d.ts.map +1 -0
- package/dist/shapes/index.js +4 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/registry.d.ts +20 -0
- package/dist/shapes/registry.d.ts.map +1 -0
- package/dist/shapes/registry.js +88 -0
- package/dist/shapes/registry.js.map +1 -0
- package/dist/shapes/types.d.ts +204 -0
- package/dist/shapes/types.d.ts.map +1 -0
- package/dist/shapes/types.js +2 -0
- package/dist/shapes/types.js.map +1 -0
- package/dist/snapshot-chunks/adapters/s3.d.ts +63 -0
- package/dist/snapshot-chunks/adapters/s3.d.ts.map +1 -0
- package/dist/snapshot-chunks/adapters/s3.js +50 -0
- package/dist/snapshot-chunks/adapters/s3.js.map +1 -0
- package/dist/snapshot-chunks/db-metadata.d.ts +33 -0
- package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -0
- package/dist/snapshot-chunks/db-metadata.js +169 -0
- package/dist/snapshot-chunks/db-metadata.js.map +1 -0
- package/dist/snapshot-chunks/index.d.ts +9 -0
- package/dist/snapshot-chunks/index.d.ts.map +1 -0
- package/dist/snapshot-chunks/index.js +9 -0
- package/dist/snapshot-chunks/index.js.map +1 -0
- package/dist/snapshot-chunks/types.d.ts +65 -0
- package/dist/snapshot-chunks/types.d.ts.map +1 -0
- package/dist/snapshot-chunks/types.js +8 -0
- package/dist/snapshot-chunks/types.js.map +1 -0
- package/dist/snapshot-chunks.d.ts +59 -0
- package/dist/snapshot-chunks.d.ts.map +1 -0
- package/dist/snapshot-chunks.js +202 -0
- package/dist/snapshot-chunks.js.map +1 -0
- package/dist/stats.d.ts +19 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +57 -0
- package/dist/stats.js.map +1 -0
- package/dist/subscriptions/index.d.ts +2 -0
- package/dist/subscriptions/index.d.ts.map +1 -0
- package/dist/subscriptions/index.js +2 -0
- package/dist/subscriptions/index.js.map +1 -0
- package/dist/subscriptions/resolve.d.ts +35 -0
- package/dist/subscriptions/resolve.d.ts.map +1 -0
- package/dist/subscriptions/resolve.js +134 -0
- package/dist/subscriptions/resolve.js.map +1 -0
- package/package.json +80 -0
- package/src/blobs/adapters/database.ts +290 -0
- package/src/blobs/adapters/s3.ts +271 -0
- package/src/blobs/index.ts +9 -0
- package/src/blobs/manager.ts +600 -0
- package/src/blobs/migrate.ts +150 -0
- package/src/blobs/types.ts +70 -0
- package/src/clients.ts +21 -0
- package/src/compaction.ts +77 -0
- package/src/dialect/index.ts +5 -0
- package/src/dialect/types.ts +222 -0
- package/src/helpers/conflict.ts +64 -0
- package/src/helpers/emitted-change.ts +69 -0
- package/src/helpers/index.ts +10 -0
- package/src/helpers/paginate.ts +82 -0
- package/src/helpers/scope-strings.ts +101 -0
- package/src/index.ts +28 -0
- package/src/migrate.ts +20 -0
- package/src/proxy/handler.ts +152 -0
- package/src/proxy/index.ts +18 -0
- package/src/proxy/mutation-detector.ts +83 -0
- package/src/proxy/oplog.ts +144 -0
- package/src/proxy/registry.ts +56 -0
- package/src/proxy/types.ts +46 -0
- package/src/prune.ts +200 -0
- package/src/pull.ts +551 -0
- package/src/push.ts +457 -0
- package/src/realtime/in-memory.ts +33 -0
- package/src/realtime/index.ts +5 -0
- package/src/realtime/types.ts +55 -0
- package/src/schema.ts +172 -0
- package/src/shapes/create-handler.ts +590 -0
- package/src/shapes/index.ts +3 -0
- package/src/shapes/registry.ts +109 -0
- package/src/shapes/types.ts +267 -0
- package/src/snapshot-chunks/adapters/s3.ts +68 -0
- package/src/snapshot-chunks/db-metadata.ts +238 -0
- package/src/snapshot-chunks/index.ts +9 -0
- package/src/snapshot-chunks/types.ts +79 -0
- package/src/snapshot-chunks.ts +301 -0
- package/src/stats.ts +104 -0
- package/src/subscriptions/index.ts +1 -0
- package/src/subscriptions/resolve.ts +185 -0
package/dist/prune.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @syncular/server - Pruning utilities
|
|
3
|
+
*
|
|
4
|
+
* Pruning strategy (initial):
|
|
5
|
+
* - Track per-client cursors in `sync_client_cursors`
|
|
6
|
+
* - Consider a client "active" if it has pulled within `activeWindowMs`
|
|
7
|
+
* - Compute watermark = min(cursor) across active clients (ignoring cursor < 0)
|
|
8
|
+
* - Delete commits with commit_seq <= watermark (cascade deletes changes)
|
|
9
|
+
*
|
|
10
|
+
* Clients behind pruned history will be forced to bootstrap.
|
|
11
|
+
*/
|
|
12
|
+
import { sql } from 'kysely';
|
|
13
|
+
function coerceNumber(value) {
|
|
14
|
+
if (value === null || value === undefined)
|
|
15
|
+
return null;
|
|
16
|
+
if (typeof value === 'number')
|
|
17
|
+
return Number.isFinite(value) ? value : null;
|
|
18
|
+
if (typeof value === 'bigint')
|
|
19
|
+
return Number.isFinite(Number(value)) ? Number(value) : null;
|
|
20
|
+
if (typeof value === 'string') {
|
|
21
|
+
const n = Number(value);
|
|
22
|
+
return Number.isFinite(n) ? n : null;
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
export async function computePruneWatermarkCommitSeq(db, options = {}) {
|
|
27
|
+
const syncDb = db;
|
|
28
|
+
const activeWindowMs = options.activeWindowMs ?? 14 * 24 * 60 * 60 * 1000;
|
|
29
|
+
const cutoffIso = new Date(Date.now() - activeWindowMs).toISOString();
|
|
30
|
+
const cursorsQ = syncDb.selectFrom('sync_client_cursors');
|
|
31
|
+
const row = await cursorsQ
|
|
32
|
+
.select(({ fn }) => fn.min('cursor').as('minCursor'))
|
|
33
|
+
.where(sql `updated_at >= ${cutoffIso}`)
|
|
34
|
+
.where(sql `cursor >= ${0}`)
|
|
35
|
+
.executeTakeFirst();
|
|
36
|
+
const minCursor = coerceNumber(row?.minCursor) ?? 0;
|
|
37
|
+
const fallbackMaxAgeMs = options.fallbackMaxAgeMs ?? 30 * 24 * 60 * 60 * 1000;
|
|
38
|
+
if (fallbackMaxAgeMs <= 0)
|
|
39
|
+
return minCursor;
|
|
40
|
+
const ageCutoffIso = new Date(Date.now() - fallbackMaxAgeMs).toISOString();
|
|
41
|
+
const commitsQ = syncDb.selectFrom('sync_commits');
|
|
42
|
+
const ageRow = await commitsQ
|
|
43
|
+
.select(({ fn }) => fn.max('commit_seq').as('maxSeq'))
|
|
44
|
+
.where(sql `created_at < ${ageCutoffIso}`)
|
|
45
|
+
.executeTakeFirst();
|
|
46
|
+
const ageSeq = coerceNumber(ageRow?.maxSeq) ?? 0;
|
|
47
|
+
return Math.max(minCursor, ageSeq);
|
|
48
|
+
}
|
|
49
|
+
export async function pruneSync(db, args) {
|
|
50
|
+
if (args.watermarkCommitSeq <= 0)
|
|
51
|
+
return 0;
|
|
52
|
+
const syncDb = db;
|
|
53
|
+
const keepNewestCommits = args.keepNewestCommits ?? 1000;
|
|
54
|
+
// Don't delete the newest N commits (even if watermark is higher)
|
|
55
|
+
const commitsQ = syncDb.selectFrom('sync_commits');
|
|
56
|
+
const maxRow = await commitsQ
|
|
57
|
+
.select(({ fn }) => fn.max('commit_seq').as('maxSeq'))
|
|
58
|
+
.executeTakeFirst();
|
|
59
|
+
const maxSeq = coerceNumber(maxRow?.maxSeq) ?? 0;
|
|
60
|
+
const minKept = Math.max(0, maxSeq - keepNewestCommits);
|
|
61
|
+
const pruneUpTo = Math.min(args.watermarkCommitSeq, minKept);
|
|
62
|
+
if (pruneUpTo <= 0)
|
|
63
|
+
return 0;
|
|
64
|
+
// Delete dependent rows explicitly to be robust across dialects and older
|
|
65
|
+
// schemas that may not have FK cascade enabled.
|
|
66
|
+
await syncDb.deleteFrom('sync_table_commits')
|
|
67
|
+
.where(sql `commit_seq <= ${pruneUpTo}`)
|
|
68
|
+
.executeTakeFirst();
|
|
69
|
+
await syncDb.deleteFrom('sync_changes')
|
|
70
|
+
.where(sql `commit_seq <= ${pruneUpTo}`)
|
|
71
|
+
.executeTakeFirst();
|
|
72
|
+
const res = await syncDb.deleteFrom('sync_commits')
|
|
73
|
+
.where(sql `commit_seq <= ${pruneUpTo}`)
|
|
74
|
+
.executeTakeFirst();
|
|
75
|
+
return Number(res?.numDeletedRows ?? 0);
|
|
76
|
+
}
|
|
77
|
+
const pruneStateByDb = new WeakMap();
|
|
78
|
+
function getPruneState(db) {
|
|
79
|
+
const existing = pruneStateByDb.get(db);
|
|
80
|
+
if (existing)
|
|
81
|
+
return existing;
|
|
82
|
+
const created = {
|
|
83
|
+
lastPruneAtMs: 0,
|
|
84
|
+
pruneInFlight: null,
|
|
85
|
+
};
|
|
86
|
+
pruneStateByDb.set(db, created);
|
|
87
|
+
return created;
|
|
88
|
+
}
|
|
89
|
+
export async function maybePruneSync(db, args) {
|
|
90
|
+
const state = getPruneState(db);
|
|
91
|
+
const now = Date.now();
|
|
92
|
+
if (now - state.lastPruneAtMs < args.minIntervalMs)
|
|
93
|
+
return 0;
|
|
94
|
+
if (state.pruneInFlight)
|
|
95
|
+
return state.pruneInFlight;
|
|
96
|
+
state.pruneInFlight = (async () => {
|
|
97
|
+
try {
|
|
98
|
+
const watermark = await computePruneWatermarkCommitSeq(db, args.options);
|
|
99
|
+
const deleted = await pruneSync(db, {
|
|
100
|
+
watermarkCommitSeq: watermark,
|
|
101
|
+
keepNewestCommits: args.options?.keepNewestCommits,
|
|
102
|
+
});
|
|
103
|
+
state.lastPruneAtMs = Date.now();
|
|
104
|
+
return deleted;
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
state.pruneInFlight = null;
|
|
108
|
+
}
|
|
109
|
+
})();
|
|
110
|
+
return state.pruneInFlight;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=prune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../src/prune.ts"],"names":[],"mappings":"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"}
|
package/dist/pull.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ScopeValues, SyncPullRequest, SyncPullResponse } from '@syncular/core';
|
|
2
|
+
import type { Kysely } from 'kysely';
|
|
3
|
+
import type { ServerSyncDialect } from './dialect/types';
|
|
4
|
+
import type { SyncCoreDb } from './schema';
|
|
5
|
+
import type { TableRegistry } from './shapes/registry';
|
|
6
|
+
import type { SnapshotChunkStorage } from './snapshot-chunks/types';
|
|
7
|
+
export interface PullResult {
|
|
8
|
+
response: SyncPullResponse;
|
|
9
|
+
/**
|
|
10
|
+
* Effective scopes for all active subscriptions (for cursor tracking).
|
|
11
|
+
* Maps subscription ID to effective scopes.
|
|
12
|
+
*/
|
|
13
|
+
effectiveScopes: ScopeValues;
|
|
14
|
+
/** Minimum nextCursor across active subscriptions (for pruning cursor tracking). */
|
|
15
|
+
clientCursor: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function pull<DB extends SyncCoreDb>(args: {
|
|
18
|
+
db: Kysely<DB>;
|
|
19
|
+
dialect: ServerSyncDialect;
|
|
20
|
+
shapes: TableRegistry<DB>;
|
|
21
|
+
actorId: string;
|
|
22
|
+
partitionId?: string;
|
|
23
|
+
request: SyncPullRequest;
|
|
24
|
+
/**
|
|
25
|
+
* Optional snapshot chunk storage adapter.
|
|
26
|
+
* When provided, stores chunk bodies in external storage (S3, etc.)
|
|
27
|
+
* instead of inline in the database.
|
|
28
|
+
*/
|
|
29
|
+
chunkStorage?: SnapshotChunkStorage;
|
|
30
|
+
}): Promise<PullResult>;
|
|
31
|
+
//# sourceMappingURL=pull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EAIX,eAAe,EACf,gBAAgB,EAGjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAcpE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,eAAe,EAAE,WAAW,CAAC;IAC7B,oFAAoF;IACpF,YAAY,EAAE,MAAM,CAAC;CACtB;AAsDD,wBAAsB,IAAI,CAAC,EAAE,SAAS,UAAU,EAAE,IAAI,EAAE;IACtD,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,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC,GAAG,OAAO,CAAC,UAAU,CAAC,CAubtB"}
|
package/dist/pull.js
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { promisify } from 'node:util';
|
|
3
|
+
import { gzip, gzipSync } from 'node:zlib';
|
|
4
|
+
import { insertSnapshotChunk, readSnapshotChunkRefByPageKey, } from './snapshot-chunks';
|
|
5
|
+
import { resolveEffectiveScopesForSubscriptions } from './subscriptions/resolve';
|
|
6
|
+
const gzipAsync = promisify(gzip);
|
|
7
|
+
const ASYNC_GZIP_MIN_BYTES = 64 * 1024;
|
|
8
|
+
async function compressSnapshotNdjson(ndjson) {
|
|
9
|
+
if (Buffer.byteLength(ndjson) < ASYNC_GZIP_MIN_BYTES) {
|
|
10
|
+
return new Uint8Array(gzipSync(ndjson));
|
|
11
|
+
}
|
|
12
|
+
const compressed = await gzipAsync(ndjson);
|
|
13
|
+
return new Uint8Array(compressed);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generate a stable cache key for snapshot chunks.
|
|
17
|
+
*/
|
|
18
|
+
function scopesToCacheKey(scopes) {
|
|
19
|
+
const sorted = Object.entries(scopes)
|
|
20
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
21
|
+
.map(([k, v]) => {
|
|
22
|
+
const arr = Array.isArray(v) ? [...v].sort() : [v];
|
|
23
|
+
return `${k}:${arr.join(',')}`;
|
|
24
|
+
})
|
|
25
|
+
.join('|');
|
|
26
|
+
return createHash('sha256').update(sorted).digest('hex');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sanitize a numeric limit parameter with bounds checking.
|
|
30
|
+
* Handles NaN, negative values, and undefined.
|
|
31
|
+
*/
|
|
32
|
+
function sanitizeLimit(value, defaultValue, min, max) {
|
|
33
|
+
if (value === undefined || value === null)
|
|
34
|
+
return defaultValue;
|
|
35
|
+
if (Number.isNaN(value))
|
|
36
|
+
return defaultValue;
|
|
37
|
+
return Math.max(min, Math.min(max, value));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Merge all scope values into a flat ScopeValues for cursor tracking.
|
|
41
|
+
*/
|
|
42
|
+
function mergeScopes(subscriptions) {
|
|
43
|
+
const result = {};
|
|
44
|
+
for (const sub of subscriptions) {
|
|
45
|
+
for (const [key, value] of Object.entries(sub.scopes)) {
|
|
46
|
+
if (!result[key])
|
|
47
|
+
result[key] = new Set();
|
|
48
|
+
const arr = Array.isArray(value) ? value : [value];
|
|
49
|
+
for (const v of arr)
|
|
50
|
+
result[key].add(v);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const merged = {};
|
|
54
|
+
for (const [key, set] of Object.entries(result)) {
|
|
55
|
+
const arr = Array.from(set);
|
|
56
|
+
if (arr.length === 0)
|
|
57
|
+
continue;
|
|
58
|
+
merged[key] = arr.length === 1 ? arr[0] : arr;
|
|
59
|
+
}
|
|
60
|
+
return merged;
|
|
61
|
+
}
|
|
62
|
+
export async function pull(args) {
|
|
63
|
+
const { request, dialect } = args;
|
|
64
|
+
const db = args.db;
|
|
65
|
+
const partitionId = args.partitionId ?? 'default';
|
|
66
|
+
// Validate and sanitize request limits
|
|
67
|
+
const limitCommits = sanitizeLimit(request.limitCommits, 50, 1, 500);
|
|
68
|
+
const limitSnapshotRows = sanitizeLimit(request.limitSnapshotRows, 1000, 1, 5000);
|
|
69
|
+
const maxSnapshotPages = sanitizeLimit(request.maxSnapshotPages, 1, 1, 50);
|
|
70
|
+
const dedupeRows = request.dedupeRows === true;
|
|
71
|
+
// Resolve effective scopes for each subscription
|
|
72
|
+
const resolved = await resolveEffectiveScopesForSubscriptions({
|
|
73
|
+
db,
|
|
74
|
+
actorId: args.actorId,
|
|
75
|
+
subscriptions: request.subscriptions ?? [],
|
|
76
|
+
shapes: args.shapes,
|
|
77
|
+
});
|
|
78
|
+
return dialect.executeInTransaction(db, async (trx) => {
|
|
79
|
+
await dialect.setRepeatableRead(trx);
|
|
80
|
+
const maxCommitSeq = await dialect.readMaxCommitSeq(trx, { partitionId });
|
|
81
|
+
const minCommitSeq = await dialect.readMinCommitSeq(trx, { partitionId });
|
|
82
|
+
const subResponses = [];
|
|
83
|
+
const activeSubscriptions = [];
|
|
84
|
+
const nextCursors = [];
|
|
85
|
+
for (const sub of resolved) {
|
|
86
|
+
const cursor = Math.max(-1, sub.cursor ?? -1);
|
|
87
|
+
// Validate shape exists (throws if not registered)
|
|
88
|
+
args.shapes.getOrThrow(sub.shape);
|
|
89
|
+
if (sub.status === 'revoked' || Object.keys(sub.scopes).length === 0) {
|
|
90
|
+
subResponses.push({
|
|
91
|
+
id: sub.id,
|
|
92
|
+
status: 'revoked',
|
|
93
|
+
scopes: {},
|
|
94
|
+
bootstrap: false,
|
|
95
|
+
nextCursor: cursor,
|
|
96
|
+
commits: [],
|
|
97
|
+
});
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const effectiveScopes = sub.scopes;
|
|
101
|
+
activeSubscriptions.push({ scopes: effectiveScopes });
|
|
102
|
+
const needsBootstrap = sub.bootstrapState != null ||
|
|
103
|
+
cursor < 0 ||
|
|
104
|
+
cursor > maxCommitSeq ||
|
|
105
|
+
(minCommitSeq > 0 && cursor < minCommitSeq - 1);
|
|
106
|
+
if (needsBootstrap) {
|
|
107
|
+
const tables = args.shapes
|
|
108
|
+
.getBootstrapOrderFor(sub.shape)
|
|
109
|
+
.map((handler) => handler.table);
|
|
110
|
+
const initState = {
|
|
111
|
+
asOfCommitSeq: maxCommitSeq,
|
|
112
|
+
tables,
|
|
113
|
+
tableIndex: 0,
|
|
114
|
+
rowCursor: null,
|
|
115
|
+
};
|
|
116
|
+
const requestedState = sub.bootstrapState ?? null;
|
|
117
|
+
const state = requestedState &&
|
|
118
|
+
typeof requestedState.asOfCommitSeq === 'number' &&
|
|
119
|
+
Array.isArray(requestedState.tables) &&
|
|
120
|
+
typeof requestedState.tableIndex === 'number'
|
|
121
|
+
? requestedState
|
|
122
|
+
: initState;
|
|
123
|
+
// If the bootstrap state's asOfCommitSeq is no longer catch-up-able, restart bootstrap.
|
|
124
|
+
const effectiveState = state.asOfCommitSeq < minCommitSeq - 1 ? initState : state;
|
|
125
|
+
const tableName = effectiveState.tables[effectiveState.tableIndex];
|
|
126
|
+
// No tables (or ran past the end): treat bootstrap as complete.
|
|
127
|
+
if (!tableName) {
|
|
128
|
+
subResponses.push({
|
|
129
|
+
id: sub.id,
|
|
130
|
+
status: 'active',
|
|
131
|
+
scopes: effectiveScopes,
|
|
132
|
+
bootstrap: true,
|
|
133
|
+
bootstrapState: null,
|
|
134
|
+
nextCursor: effectiveState.asOfCommitSeq,
|
|
135
|
+
commits: [],
|
|
136
|
+
snapshots: [],
|
|
137
|
+
});
|
|
138
|
+
nextCursors.push(effectiveState.asOfCommitSeq);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const snapshots = [];
|
|
142
|
+
let nextState = effectiveState;
|
|
143
|
+
for (let pageIndex = 0; pageIndex < maxSnapshotPages; pageIndex++) {
|
|
144
|
+
if (!nextState)
|
|
145
|
+
break;
|
|
146
|
+
const nextTableName = nextState.tables[nextState.tableIndex];
|
|
147
|
+
if (!nextTableName) {
|
|
148
|
+
nextState = null;
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
const tableHandler = args.shapes.getOrThrow(nextTableName);
|
|
152
|
+
const isFirstPage = nextState.rowCursor == null;
|
|
153
|
+
const page = await tableHandler.snapshot({
|
|
154
|
+
db: trx,
|
|
155
|
+
actorId: args.actorId,
|
|
156
|
+
scopeValues: effectiveScopes,
|
|
157
|
+
cursor: nextState.rowCursor,
|
|
158
|
+
limit: limitSnapshotRows,
|
|
159
|
+
}, sub.params);
|
|
160
|
+
const isLastPage = page.nextCursor == null;
|
|
161
|
+
// Always use NDJSON+gzip for bootstrap snapshots
|
|
162
|
+
const ttlMs = tableHandler.snapshotChunkTtlMs ?? 24 * 60 * 60 * 1000; // 24h
|
|
163
|
+
const nowIso = new Date().toISOString();
|
|
164
|
+
// Use scope hash for caching
|
|
165
|
+
const cacheKey = `${partitionId}:${scopesToCacheKey(effectiveScopes)}`;
|
|
166
|
+
const cached = await readSnapshotChunkRefByPageKey(trx, {
|
|
167
|
+
partitionId,
|
|
168
|
+
scopeKey: cacheKey,
|
|
169
|
+
scope: nextTableName,
|
|
170
|
+
asOfCommitSeq: effectiveState.asOfCommitSeq,
|
|
171
|
+
rowCursor: nextState.rowCursor,
|
|
172
|
+
rowLimit: limitSnapshotRows,
|
|
173
|
+
encoding: 'ndjson',
|
|
174
|
+
compression: 'gzip',
|
|
175
|
+
nowIso,
|
|
176
|
+
});
|
|
177
|
+
let chunkRef = cached;
|
|
178
|
+
if (!chunkRef) {
|
|
179
|
+
const lines = [];
|
|
180
|
+
for (const r of page.rows ?? []) {
|
|
181
|
+
const s = JSON.stringify(r);
|
|
182
|
+
lines.push(s === undefined ? 'null' : s);
|
|
183
|
+
}
|
|
184
|
+
const ndjson = lines.length > 0 ? `${lines.join('\n')}\n` : '';
|
|
185
|
+
const gz = await compressSnapshotNdjson(ndjson);
|
|
186
|
+
const sha256 = createHash('sha256').update(ndjson).digest('hex');
|
|
187
|
+
const expiresAt = new Date(Date.now() + Math.max(1000, ttlMs)).toISOString();
|
|
188
|
+
// Use external chunk storage if available, otherwise fall back to inline
|
|
189
|
+
if (args.chunkStorage) {
|
|
190
|
+
chunkRef = await args.chunkStorage.storeChunk({
|
|
191
|
+
partitionId,
|
|
192
|
+
scopeKey: cacheKey,
|
|
193
|
+
scope: nextTableName,
|
|
194
|
+
asOfCommitSeq: effectiveState.asOfCommitSeq,
|
|
195
|
+
rowCursor: nextState.rowCursor ?? null,
|
|
196
|
+
rowLimit: limitSnapshotRows,
|
|
197
|
+
encoding: 'ndjson',
|
|
198
|
+
compression: 'gzip',
|
|
199
|
+
sha256,
|
|
200
|
+
body: gz,
|
|
201
|
+
expiresAt,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const chunkId = randomUUID();
|
|
206
|
+
chunkRef = await insertSnapshotChunk(trx, {
|
|
207
|
+
chunkId,
|
|
208
|
+
partitionId,
|
|
209
|
+
scopeKey: cacheKey,
|
|
210
|
+
scope: nextTableName,
|
|
211
|
+
asOfCommitSeq: effectiveState.asOfCommitSeq,
|
|
212
|
+
rowCursor: nextState.rowCursor,
|
|
213
|
+
rowLimit: limitSnapshotRows,
|
|
214
|
+
encoding: 'ndjson',
|
|
215
|
+
compression: 'gzip',
|
|
216
|
+
sha256,
|
|
217
|
+
body: gz,
|
|
218
|
+
expiresAt,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
snapshots.push({
|
|
223
|
+
table: nextTableName,
|
|
224
|
+
rows: [],
|
|
225
|
+
chunks: [chunkRef],
|
|
226
|
+
isFirstPage,
|
|
227
|
+
isLastPage,
|
|
228
|
+
});
|
|
229
|
+
if (page.nextCursor != null) {
|
|
230
|
+
nextState = { ...nextState, rowCursor: page.nextCursor };
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (nextState.tableIndex + 1 < nextState.tables.length) {
|
|
234
|
+
nextState = {
|
|
235
|
+
...nextState,
|
|
236
|
+
tableIndex: nextState.tableIndex + 1,
|
|
237
|
+
rowCursor: null,
|
|
238
|
+
};
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
nextState = null;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
subResponses.push({
|
|
245
|
+
id: sub.id,
|
|
246
|
+
status: 'active',
|
|
247
|
+
scopes: effectiveScopes,
|
|
248
|
+
bootstrap: true,
|
|
249
|
+
bootstrapState: nextState,
|
|
250
|
+
nextCursor: effectiveState.asOfCommitSeq,
|
|
251
|
+
commits: [],
|
|
252
|
+
snapshots,
|
|
253
|
+
});
|
|
254
|
+
nextCursors.push(effectiveState.asOfCommitSeq);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
// Incremental pull for this subscription
|
|
258
|
+
// Read the commit window for this table up-front so the subscription cursor
|
|
259
|
+
// can advance past commits that don't match the requested scopes.
|
|
260
|
+
const scannedCommitSeqs = await dialect.readCommitSeqsForPull(trx, {
|
|
261
|
+
partitionId,
|
|
262
|
+
cursor,
|
|
263
|
+
limitCommits,
|
|
264
|
+
tables: [sub.shape],
|
|
265
|
+
});
|
|
266
|
+
const maxScannedCommitSeq = scannedCommitSeqs.length > 0
|
|
267
|
+
? scannedCommitSeqs[scannedCommitSeqs.length - 1]
|
|
268
|
+
: cursor;
|
|
269
|
+
// Use streaming when available to reduce memory pressure for large pulls
|
|
270
|
+
const pullRowStream = dialect.streamIncrementalPullRows
|
|
271
|
+
? dialect.streamIncrementalPullRows(trx, {
|
|
272
|
+
partitionId,
|
|
273
|
+
table: sub.shape,
|
|
274
|
+
scopes: effectiveScopes,
|
|
275
|
+
cursor,
|
|
276
|
+
limitCommits,
|
|
277
|
+
})
|
|
278
|
+
: null;
|
|
279
|
+
// Collect rows and compute nextCursor in a single pass
|
|
280
|
+
const incrementalRows = [];
|
|
281
|
+
let nextCursor = cursor;
|
|
282
|
+
if (pullRowStream) {
|
|
283
|
+
// Streaming path: process rows as they arrive
|
|
284
|
+
for await (const row of pullRowStream) {
|
|
285
|
+
incrementalRows.push(row);
|
|
286
|
+
nextCursor = Math.max(nextCursor, row.commit_seq);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
// Non-streaming fallback: load all rows at once
|
|
291
|
+
const rows = await dialect.readIncrementalPullRows(trx, {
|
|
292
|
+
partitionId,
|
|
293
|
+
table: sub.shape,
|
|
294
|
+
scopes: effectiveScopes,
|
|
295
|
+
cursor,
|
|
296
|
+
limitCommits,
|
|
297
|
+
});
|
|
298
|
+
incrementalRows.push(...rows);
|
|
299
|
+
for (const r of incrementalRows) {
|
|
300
|
+
nextCursor = Math.max(nextCursor, r.commit_seq);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
nextCursor = Math.max(nextCursor, maxScannedCommitSeq);
|
|
304
|
+
if (incrementalRows.length === 0) {
|
|
305
|
+
subResponses.push({
|
|
306
|
+
id: sub.id,
|
|
307
|
+
status: 'active',
|
|
308
|
+
scopes: effectiveScopes,
|
|
309
|
+
bootstrap: false,
|
|
310
|
+
nextCursor,
|
|
311
|
+
commits: [],
|
|
312
|
+
});
|
|
313
|
+
nextCursors.push(nextCursor);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (dedupeRows) {
|
|
317
|
+
const latestByRowKey = new Map();
|
|
318
|
+
for (const r of incrementalRows) {
|
|
319
|
+
const rowKey = `${r.table}\u0000${r.row_id}`;
|
|
320
|
+
const change = {
|
|
321
|
+
table: r.table,
|
|
322
|
+
row_id: r.row_id,
|
|
323
|
+
op: r.op,
|
|
324
|
+
row_json: r.row_json,
|
|
325
|
+
row_version: r.row_version,
|
|
326
|
+
scopes: dialect.dbToScopes(r.scopes),
|
|
327
|
+
};
|
|
328
|
+
latestByRowKey.set(rowKey, {
|
|
329
|
+
commitSeq: r.commit_seq,
|
|
330
|
+
createdAt: r.created_at,
|
|
331
|
+
actorId: r.actor_id,
|
|
332
|
+
changeId: r.change_id,
|
|
333
|
+
change,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
const latest = Array.from(latestByRowKey.values()).sort((a, b) => a.commitSeq - b.commitSeq || a.changeId - b.changeId);
|
|
337
|
+
const commitsBySeq = new Map();
|
|
338
|
+
for (const item of latest) {
|
|
339
|
+
let commit = commitsBySeq.get(item.commitSeq);
|
|
340
|
+
if (!commit) {
|
|
341
|
+
commit = {
|
|
342
|
+
commitSeq: item.commitSeq,
|
|
343
|
+
createdAt: item.createdAt,
|
|
344
|
+
actorId: item.actorId,
|
|
345
|
+
changes: [],
|
|
346
|
+
};
|
|
347
|
+
commitsBySeq.set(item.commitSeq, commit);
|
|
348
|
+
}
|
|
349
|
+
commit.changes.push(item.change);
|
|
350
|
+
}
|
|
351
|
+
const commits = Array.from(commitsBySeq.values()).sort((a, b) => a.commitSeq - b.commitSeq);
|
|
352
|
+
subResponses.push({
|
|
353
|
+
id: sub.id,
|
|
354
|
+
status: 'active',
|
|
355
|
+
scopes: effectiveScopes,
|
|
356
|
+
bootstrap: false,
|
|
357
|
+
nextCursor,
|
|
358
|
+
commits,
|
|
359
|
+
});
|
|
360
|
+
nextCursors.push(nextCursor);
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
const commitsBySeq = new Map();
|
|
364
|
+
const commitSeqs = [];
|
|
365
|
+
for (const r of incrementalRows) {
|
|
366
|
+
const seq = r.commit_seq;
|
|
367
|
+
let commit = commitsBySeq.get(seq);
|
|
368
|
+
if (!commit) {
|
|
369
|
+
commit = {
|
|
370
|
+
commitSeq: seq,
|
|
371
|
+
createdAt: r.created_at,
|
|
372
|
+
actorId: r.actor_id,
|
|
373
|
+
changes: [],
|
|
374
|
+
};
|
|
375
|
+
commitsBySeq.set(seq, commit);
|
|
376
|
+
commitSeqs.push(seq);
|
|
377
|
+
}
|
|
378
|
+
const change = {
|
|
379
|
+
table: r.table,
|
|
380
|
+
row_id: r.row_id,
|
|
381
|
+
op: r.op,
|
|
382
|
+
row_json: r.row_json,
|
|
383
|
+
row_version: r.row_version,
|
|
384
|
+
scopes: dialect.dbToScopes(r.scopes),
|
|
385
|
+
};
|
|
386
|
+
commit.changes.push(change);
|
|
387
|
+
}
|
|
388
|
+
const commits = commitSeqs
|
|
389
|
+
.map((seq) => commitsBySeq.get(seq))
|
|
390
|
+
.filter((c) => !!c)
|
|
391
|
+
.filter((c) => c.changes.length > 0);
|
|
392
|
+
subResponses.push({
|
|
393
|
+
id: sub.id,
|
|
394
|
+
status: 'active',
|
|
395
|
+
scopes: effectiveScopes,
|
|
396
|
+
bootstrap: false,
|
|
397
|
+
nextCursor,
|
|
398
|
+
commits,
|
|
399
|
+
});
|
|
400
|
+
nextCursors.push(nextCursor);
|
|
401
|
+
}
|
|
402
|
+
const effectiveScopes = mergeScopes(activeSubscriptions);
|
|
403
|
+
const clientCursor = nextCursors.length > 0 ? Math.min(...nextCursors) : maxCommitSeq;
|
|
404
|
+
return {
|
|
405
|
+
response: {
|
|
406
|
+
ok: true,
|
|
407
|
+
subscriptions: subResponses,
|
|
408
|
+
},
|
|
409
|
+
effectiveScopes,
|
|
410
|
+
clientCursor,
|
|
411
|
+
};
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
//# sourceMappingURL=pull.js.map
|
package/dist/pull.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../src/pull.ts"],"names":[],"mappings":"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"}
|
package/dist/push.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SyncChange, SyncPushRequest, SyncPushResponse } from '@syncular/core';
|
|
2
|
+
import type { Kysely } from 'kysely';
|
|
3
|
+
import type { ServerSyncDialect } from './dialect/types';
|
|
4
|
+
import type { SyncCoreDb } from './schema';
|
|
5
|
+
import type { TableRegistry } from './shapes/registry';
|
|
6
|
+
export interface PushCommitResult {
|
|
7
|
+
response: SyncPushResponse;
|
|
8
|
+
/**
|
|
9
|
+
* Distinct tables affected by this commit.
|
|
10
|
+
* Empty for rejected commits and for commits that emit no changes.
|
|
11
|
+
*/
|
|
12
|
+
affectedTables: string[];
|
|
13
|
+
/**
|
|
14
|
+
* Scope keys derived from emitted changes (e.g. "org:abc", "team:xyz").
|
|
15
|
+
* Computed in-transaction so callers don't need an extra DB query.
|
|
16
|
+
* Empty for rejected/cached commits.
|
|
17
|
+
*/
|
|
18
|
+
scopeKeys: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Changes emitted by this commit. Available for WS data delivery.
|
|
21
|
+
* Empty for rejected/cached commits.
|
|
22
|
+
*/
|
|
23
|
+
emittedChanges: SyncChange[];
|
|
24
|
+
}
|
|
25
|
+
export declare function pushCommit<DB extends SyncCoreDb>(args: {
|
|
26
|
+
db: Kysely<DB>;
|
|
27
|
+
dialect: ServerSyncDialect;
|
|
28
|
+
shapes: TableRegistry<DB>;
|
|
29
|
+
actorId: string;
|
|
30
|
+
partitionId?: string;
|
|
31
|
+
request: SyncPushRequest;
|
|
32
|
+
}): Promise<PushCommitResult>;
|
|
33
|
+
//# sourceMappingURL=push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAEV,MAAM,EAIP,MAAM,QAAQ,CAAC;AAEhB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKvD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;OAIG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,cAAc,EAAE,UAAU,EAAE,CAAC;CAC9B;AAoDD,wBAAsB,UAAU,CAAC,EAAE,SAAS,UAAU,EAAE,IAAI,EAAE;IAC5D,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,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,eAAe,CAAC;CAC1B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAuW5B"}
|