@stratasync/server 0.2.0
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 +188 -0
- package/dist/bootstrap/bootstrap-service.d.ts +41 -0
- package/dist/bootstrap/bootstrap-service.d.ts.map +1 -0
- package/dist/bootstrap/bootstrap-service.js +411 -0
- package/dist/bootstrap/bootstrap-service.js.map +1 -0
- package/dist/config.d.ts +124 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +10 -0
- package/dist/config.js.map +1 -0
- package/dist/create-sync-server.d.ts +5 -0
- package/dist/create-sync-server.d.ts.map +1 -0
- package/dist/create-sync-server.js +96 -0
- package/dist/create-sync-server.js.map +1 -0
- package/dist/dao/sync-dao.d.ts +64 -0
- package/dist/dao/sync-dao.d.ts.map +1 -0
- package/dist/dao/sync-dao.js +137 -0
- package/dist/dao/sync-dao.js.map +1 -0
- package/dist/db.d.ts +37 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +2 -0
- package/dist/db.js.map +1 -0
- package/dist/delta/delta-publisher.d.ts +52 -0
- package/dist/delta/delta-publisher.d.ts.map +1 -0
- package/dist/delta/delta-publisher.js +217 -0
- package/dist/delta/delta-publisher.js.map +1 -0
- package/dist/delta/delta-service.d.ts +13 -0
- package/dist/delta/delta-service.d.ts.map +1 -0
- package/dist/delta/delta-service.js +36 -0
- package/dist/delta/delta-service.js.map +1 -0
- package/dist/fastify/index.d.ts +7 -0
- package/dist/fastify/index.d.ts.map +1 -0
- package/dist/fastify/index.js +5 -0
- package/dist/fastify/index.js.map +1 -0
- package/dist/fastify/middleware.d.ts +16 -0
- package/dist/fastify/middleware.d.ts.map +1 -0
- package/dist/fastify/middleware.js +101 -0
- package/dist/fastify/middleware.js.map +1 -0
- package/dist/fastify/routes.d.ts +17 -0
- package/dist/fastify/routes.d.ts.map +1 -0
- package/dist/fastify/routes.js +150 -0
- package/dist/fastify/routes.js.map +1 -0
- package/dist/fastify/validation.d.ts +59 -0
- package/dist/fastify/validation.d.ts.map +1 -0
- package/dist/fastify/validation.js +79 -0
- package/dist/fastify/validation.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/mutate/archive-mutation.d.ts +10 -0
- package/dist/mutate/archive-mutation.d.ts.map +1 -0
- package/dist/mutate/archive-mutation.js +14 -0
- package/dist/mutate/archive-mutation.js.map +1 -0
- package/dist/mutate/field-codecs.d.ts +15 -0
- package/dist/mutate/field-codecs.d.ts.map +1 -0
- package/dist/mutate/field-codecs.js +103 -0
- package/dist/mutate/field-codecs.js.map +1 -0
- package/dist/mutate/model-handlers.d.ts +32 -0
- package/dist/mutate/model-handlers.d.ts.map +1 -0
- package/dist/mutate/model-handlers.js +131 -0
- package/dist/mutate/model-handlers.js.map +1 -0
- package/dist/mutate/mutate-service.d.ts +30 -0
- package/dist/mutate/mutate-service.d.ts.map +1 -0
- package/dist/mutate/mutate-service.js +326 -0
- package/dist/mutate/mutate-service.js.map +1 -0
- package/dist/types.d.ts +101 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/composite-ids.d.ts +14 -0
- package/dist/utils/composite-ids.d.ts.map +1 -0
- package/dist/utils/composite-ids.js +15 -0
- package/dist/utils/composite-ids.js.map +1 -0
- package/dist/utils/dates.d.ts +8 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +101 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/sync-scope.d.ts +4 -0
- package/dist/utils/sync-scope.d.ts.map +1 -0
- package/dist/utils/sync-scope.js +17 -0
- package/dist/utils/sync-scope.js.map +1 -0
- package/dist/utils/sync-utils.d.ts +27 -0
- package/dist/utils/sync-utils.d.ts.map +1 -0
- package/dist/utils/sync-utils.js +94 -0
- package/dist/utils/sync-utils.js.map +1 -0
- package/dist/websocket/sync-websocket.d.ts +14 -0
- package/dist/websocket/sync-websocket.d.ts.map +1 -0
- package/dist/websocket/sync-websocket.js +326 -0
- package/dist/websocket/sync-websocket.js.map +1 -0
- package/package.json +70 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { SQL } from "drizzle-orm";
|
|
2
|
+
import type { AnyPgTable } from "drizzle-orm/pg-core";
|
|
3
|
+
import type { RedisClientType, RedisFunctions, RedisModules, RedisScripts } from "redis";
|
|
4
|
+
import type { WebSocket } from "ws";
|
|
5
|
+
import type { BootstrapService } from "./bootstrap/bootstrap-service.js";
|
|
6
|
+
import type { SyncDao } from "./dao/sync-dao.js";
|
|
7
|
+
import type { DeltaPublisherLike, DeltaSubscriberLike } from "./delta/delta-publisher.js";
|
|
8
|
+
import type { DeltaService } from "./delta/delta-service.js";
|
|
9
|
+
import type { FieldSpec } from "./mutate/field-codecs.js";
|
|
10
|
+
import type { MutateService } from "./mutate/mutate-service.js";
|
|
11
|
+
import type { ModelAction } from "./types.js";
|
|
12
|
+
export type { FieldSpec, FieldType } from "./mutate/field-codecs.js";
|
|
13
|
+
export type RedisClient = RedisClientType<RedisModules, RedisFunctions, RedisScripts>;
|
|
14
|
+
export interface SyncLogger {
|
|
15
|
+
debug(obj: Record<string, unknown>, msg?: string): void;
|
|
16
|
+
info(obj: Record<string, unknown>, msg?: string): void;
|
|
17
|
+
warn(obj: Record<string, unknown>, msg?: string): void;
|
|
18
|
+
error(obj: Record<string, unknown>, msg?: string): void;
|
|
19
|
+
}
|
|
20
|
+
export declare const noopLogger: SyncLogger;
|
|
21
|
+
export interface SyncAuthPayload {
|
|
22
|
+
userId: string;
|
|
23
|
+
email?: string;
|
|
24
|
+
name?: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface SyncAuthConfig {
|
|
27
|
+
verifyToken: (token: string) => Promise<SyncAuthPayload | null>;
|
|
28
|
+
resolveGroups: (userId: string) => Promise<string[]>;
|
|
29
|
+
}
|
|
30
|
+
export interface BootstrapFilterContext {
|
|
31
|
+
authorizedGroupIds: string[];
|
|
32
|
+
workspaceGroupIds: string[];
|
|
33
|
+
userId: string;
|
|
34
|
+
}
|
|
35
|
+
export type CursorConfig = {
|
|
36
|
+
type: "simple";
|
|
37
|
+
idField: string;
|
|
38
|
+
} | {
|
|
39
|
+
type: "composite";
|
|
40
|
+
fields: readonly string[];
|
|
41
|
+
syntheticId: (item: Record<string, unknown>) => string;
|
|
42
|
+
};
|
|
43
|
+
export interface BootstrapFieldDef {
|
|
44
|
+
fields: readonly string[];
|
|
45
|
+
dateOnlyFields?: readonly string[];
|
|
46
|
+
instantFields?: readonly string[];
|
|
47
|
+
}
|
|
48
|
+
export interface BootstrapModelConfig {
|
|
49
|
+
fields: readonly string[];
|
|
50
|
+
dateOnlyFields?: readonly string[];
|
|
51
|
+
instantFields?: readonly string[];
|
|
52
|
+
cursor: CursorConfig;
|
|
53
|
+
buildScopeWhere: (filter: BootstrapFilterContext, db: unknown) => SQL<unknown>;
|
|
54
|
+
allowedIndexedKeys?: readonly string[];
|
|
55
|
+
}
|
|
56
|
+
export interface MutationContext {
|
|
57
|
+
modelName: string;
|
|
58
|
+
modelId: string;
|
|
59
|
+
action: ModelAction;
|
|
60
|
+
payload: Record<string, unknown>;
|
|
61
|
+
data: Record<string, unknown>;
|
|
62
|
+
syncAction: {
|
|
63
|
+
id: bigint;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export interface StandardMutateConfig {
|
|
67
|
+
kind: "standard";
|
|
68
|
+
idField?: string;
|
|
69
|
+
actions: Set<ModelAction>;
|
|
70
|
+
insertFields: Record<string, FieldSpec>;
|
|
71
|
+
updateFields?: Set<string>;
|
|
72
|
+
onBeforeInsert?: (db: unknown, modelId: string, payload: Record<string, unknown>, data: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
73
|
+
onBeforeUpdate?: (db: unknown, modelId: string, payload: Record<string, unknown>, data: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
74
|
+
onAfterMutation?: (ctx: MutationContext) => void | Promise<void>;
|
|
75
|
+
}
|
|
76
|
+
export interface CompositeMutateConfig {
|
|
77
|
+
kind: "composite";
|
|
78
|
+
actions: Set<ModelAction>;
|
|
79
|
+
insertFields: Record<string, FieldSpec>;
|
|
80
|
+
buildDeleteWhere: (payload: Record<string, unknown>) => SQL<unknown>;
|
|
81
|
+
compositeId?: {
|
|
82
|
+
computeId: (modelName: string, modelId: string, payload: Record<string, unknown>) => string;
|
|
83
|
+
};
|
|
84
|
+
onAfterMutation?: (ctx: MutationContext) => void | Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
export interface SyncModelConfig {
|
|
87
|
+
table: AnyPgTable;
|
|
88
|
+
groupKey: string | "__modelId__" | null;
|
|
89
|
+
bootstrap: BootstrapModelConfig;
|
|
90
|
+
mutate: StandardMutateConfig | CompositeMutateConfig;
|
|
91
|
+
}
|
|
92
|
+
export interface WebSocketConnectionContext {
|
|
93
|
+
userId: string;
|
|
94
|
+
connId: string;
|
|
95
|
+
groups: string[];
|
|
96
|
+
}
|
|
97
|
+
export interface WebSocketHooks {
|
|
98
|
+
onMessage?: (ws: WebSocket, message: Record<string, unknown>, context: WebSocketConnectionContext) => Promise<boolean>;
|
|
99
|
+
onClose?: (ws: WebSocket, context: WebSocketConnectionContext) => Promise<void>;
|
|
100
|
+
onSubscribe?: (ws: WebSocket, context: WebSocketConnectionContext, previousContext: WebSocketConnectionContext) => Promise<void>;
|
|
101
|
+
}
|
|
102
|
+
export interface SyncServerConfig {
|
|
103
|
+
db: unknown;
|
|
104
|
+
tables: {
|
|
105
|
+
syncActions: AnyPgTable;
|
|
106
|
+
syncGroupMemberships: AnyPgTable;
|
|
107
|
+
};
|
|
108
|
+
redis?: RedisClient;
|
|
109
|
+
models: Record<string, SyncModelConfig>;
|
|
110
|
+
auth: SyncAuthConfig;
|
|
111
|
+
logger?: SyncLogger;
|
|
112
|
+
compositeIdNamespace?: string;
|
|
113
|
+
}
|
|
114
|
+
export interface SyncServer {
|
|
115
|
+
bootstrapService: BootstrapService;
|
|
116
|
+
deltaService: DeltaService;
|
|
117
|
+
mutateService: MutateService;
|
|
118
|
+
deltaPublisher: DeltaPublisherLike;
|
|
119
|
+
deltaSubscriber: DeltaSubscriberLike;
|
|
120
|
+
syncDao: SyncDao;
|
|
121
|
+
registerRoutes: (server: unknown) => void;
|
|
122
|
+
shutdown: () => Promise<void>;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAwCA,MAAM,IAAI,GAAG,GAAS,EAAE;IACtB,qEAAqE;AACvE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAe;IACpC,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;CACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-sync-server.d.ts","sourceRoot":"","sources":["../src/create-sync-server.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,UAAU,EACV,gBAAgB,EAChB,cAAc,EACf,MAAM,aAAa,CAAC;AA2BrB,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,gBAAgB,GAAG;IAAE,cAAc,CAAC,EAAE,cAAc,CAAA;CAAE,KAC7D,OAAO,CAAC,UAAU,CAuHpB,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { BootstrapService } from "./bootstrap/bootstrap-service.js";
|
|
3
|
+
import { noopLogger } from "./config.js";
|
|
4
|
+
import { SyncDao } from "./dao/sync-dao.js";
|
|
5
|
+
import { createCompositeDeltaPublisher, createDeltaPublisher, createDeltaSubscriber, createInMemoryDeltaBus, createInMemoryDeltaPublisher, createInMemoryDeltaSubscriber, } from "./delta/delta-publisher.js";
|
|
6
|
+
import { DeltaService } from "./delta/delta-service.js";
|
|
7
|
+
import { createSyncAuthMiddleware } from "./fastify/middleware.js";
|
|
8
|
+
import { registerSyncRoutes } from "./fastify/routes.js";
|
|
9
|
+
import { MutateService } from "./mutate/mutate-service.js";
|
|
10
|
+
import { registerSyncWebsocket } from "./websocket/sync-websocket.js";
|
|
11
|
+
export const createSyncServer = async (config) => {
|
|
12
|
+
const logger = config.logger ?? noopLogger;
|
|
13
|
+
// Create DAO
|
|
14
|
+
const syncDao = new SyncDao(config.db, config.tables);
|
|
15
|
+
// Set up delta publisher chain
|
|
16
|
+
const localBus = createInMemoryDeltaBus();
|
|
17
|
+
const localPublisher = createInMemoryDeltaPublisher(localBus);
|
|
18
|
+
const localSubscriber = createInMemoryDeltaSubscriber(localBus);
|
|
19
|
+
const state = {
|
|
20
|
+
deltaPublisher: null,
|
|
21
|
+
deltaSubscriber: localSubscriber,
|
|
22
|
+
redisSubscriber: null,
|
|
23
|
+
};
|
|
24
|
+
const publishers = [localPublisher];
|
|
25
|
+
if (config.redis) {
|
|
26
|
+
const serverId = `sync-${randomUUID().slice(0, 8)}`;
|
|
27
|
+
const redisPublisher = createDeltaPublisher(config.redis, serverId);
|
|
28
|
+
const redisSubscriber = createDeltaSubscriber(config.redis, serverId);
|
|
29
|
+
await redisSubscriber.start();
|
|
30
|
+
state.redisSubscriber = redisSubscriber;
|
|
31
|
+
redisSubscriber.onDelta(async (action, groups) => {
|
|
32
|
+
try {
|
|
33
|
+
await localPublisher.publish(action, groups);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
const formattedError = error instanceof Error ? error : new Error(String(error));
|
|
37
|
+
logger.error({ err: formattedError }, "Failed to relay delta");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
publishers.push(redisPublisher);
|
|
41
|
+
logger.debug({ serverId }, "Sync delta subscriber started");
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
logger.debug({}, "Sync delta bus running in-memory (no Redis)");
|
|
45
|
+
}
|
|
46
|
+
const deltaPublisher = createCompositeDeltaPublisher(publishers, logger);
|
|
47
|
+
state.deltaPublisher = deltaPublisher;
|
|
48
|
+
// Create services
|
|
49
|
+
const bootstrapService = new BootstrapService(config.db, syncDao, config.models, logger);
|
|
50
|
+
const deltaService = new DeltaService(syncDao, logger);
|
|
51
|
+
const mutateService = new MutateService(config.db, syncDao, config.models, logger);
|
|
52
|
+
// Route registration
|
|
53
|
+
const registerRoutes = (server) => {
|
|
54
|
+
const fastifyServer = server;
|
|
55
|
+
const authMiddleware = createSyncAuthMiddleware(config.auth, syncDao, logger);
|
|
56
|
+
registerSyncRoutes(fastifyServer, {
|
|
57
|
+
authMiddleware,
|
|
58
|
+
bootstrapService,
|
|
59
|
+
deltaPublisher,
|
|
60
|
+
deltaService,
|
|
61
|
+
logger,
|
|
62
|
+
mutateService,
|
|
63
|
+
});
|
|
64
|
+
registerSyncWebsocket(fastifyServer, {
|
|
65
|
+
auth: config.auth,
|
|
66
|
+
deltaSubscriber: localSubscriber,
|
|
67
|
+
hooks: config.websocketHooks,
|
|
68
|
+
logger,
|
|
69
|
+
syncDao,
|
|
70
|
+
});
|
|
71
|
+
logger.debug({}, "Sync module initialized: /sync/bootstrap, /sync/batch, /sync/deltas, /sync/mutate, /sync/ws");
|
|
72
|
+
};
|
|
73
|
+
// Shutdown
|
|
74
|
+
const shutdown = async () => {
|
|
75
|
+
if (state.redisSubscriber) {
|
|
76
|
+
await state.redisSubscriber.stop();
|
|
77
|
+
state.redisSubscriber = null;
|
|
78
|
+
}
|
|
79
|
+
if (state.deltaSubscriber) {
|
|
80
|
+
await state.deltaSubscriber.stop();
|
|
81
|
+
state.deltaSubscriber = null;
|
|
82
|
+
}
|
|
83
|
+
state.deltaPublisher = null;
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
bootstrapService,
|
|
87
|
+
deltaPublisher,
|
|
88
|
+
deltaService,
|
|
89
|
+
deltaSubscriber: localSubscriber,
|
|
90
|
+
mutateService,
|
|
91
|
+
registerRoutes,
|
|
92
|
+
shutdown,
|
|
93
|
+
syncDao,
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=create-sync-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-sync-server.js","sourceRoot":"","sources":["../src/create-sync-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { AnyPgTable } from "drizzle-orm/pg-core";
|
|
2
|
+
export interface SyncDaoTables {
|
|
3
|
+
syncActions: AnyPgTable;
|
|
4
|
+
syncGroupMemberships: AnyPgTable;
|
|
5
|
+
}
|
|
6
|
+
export interface SyncActionInsert {
|
|
7
|
+
model: string;
|
|
8
|
+
modelId: string;
|
|
9
|
+
action: string;
|
|
10
|
+
data: Record<string, unknown>;
|
|
11
|
+
groupId: string | null;
|
|
12
|
+
clientTxId: string | null;
|
|
13
|
+
clientId: string | null;
|
|
14
|
+
}
|
|
15
|
+
interface SyncActionRow {
|
|
16
|
+
id: bigint;
|
|
17
|
+
model: string;
|
|
18
|
+
modelId: string;
|
|
19
|
+
action: string;
|
|
20
|
+
data: unknown;
|
|
21
|
+
groupId: string | null;
|
|
22
|
+
clientTxId: string | null;
|
|
23
|
+
clientId: string | null;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Data access object for sync operations.
|
|
28
|
+
* Accepts Drizzle table references instead of hardcoded schema imports.
|
|
29
|
+
*/
|
|
30
|
+
export declare class SyncDao {
|
|
31
|
+
private readonly db;
|
|
32
|
+
private readonly tables;
|
|
33
|
+
constructor(db: unknown, tables: SyncDaoTables);
|
|
34
|
+
private visibleGroupCondition;
|
|
35
|
+
/**
|
|
36
|
+
* Gets the last sync ID.
|
|
37
|
+
*/
|
|
38
|
+
getLastSyncId(): Promise<bigint>;
|
|
39
|
+
/**
|
|
40
|
+
* Gets the last sync ID visible to the given groups.
|
|
41
|
+
*/
|
|
42
|
+
getLastSyncIdForGroups(groups: string[]): Promise<bigint>;
|
|
43
|
+
/**
|
|
44
|
+
* Gets sync actions after a given ID.
|
|
45
|
+
*/
|
|
46
|
+
getSyncActions(afterId: bigint, groups: string[], limit: number): Promise<SyncActionRow[]>;
|
|
47
|
+
getTouchedModelIdsAfter(afterId: bigint, groups: string[], modelName: string, modelIds: string[]): Promise<Set<string>>;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a sync action.
|
|
50
|
+
*/
|
|
51
|
+
createSyncAction(data: SyncActionInsert): Promise<SyncActionRow>;
|
|
52
|
+
/**
|
|
53
|
+
* Gets user's group memberships.
|
|
54
|
+
*/
|
|
55
|
+
getUserGroups(userId: string): Promise<string[]>;
|
|
56
|
+
/**
|
|
57
|
+
* Finds an existing sync action for a client transaction.
|
|
58
|
+
*/
|
|
59
|
+
findSyncActionByClientTx(clientId: string, clientTxId: string): Promise<{
|
|
60
|
+
id: bigint;
|
|
61
|
+
} | null>;
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=sync-dao.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-dao.d.ts","sourceRoot":"","sources":["../../src/dao/sync-dao.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAKtD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,UAAU,CAAC;IACxB,oBAAoB,EAAE,UAAU,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,IAAI,CAAC;CACjB;AAcD;;;GAGG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa;IAK9C,OAAO,CAAC,qBAAqB;IAQ7B;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAatC;;OAEG;IACG,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAa/D;;OAEG;IACG,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,EAAE,CAAC;IAYrB,uBAAuB,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EAAE,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IA2BvB;;OAEG;IACG,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IAsBtE;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAetD;;OAEG;IACG,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAelC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { and, asc, desc, eq, gt, inArray, isNull, or } from "drizzle-orm";
|
|
2
|
+
import { getColumn } from "../utils/sync-utils.js";
|
|
3
|
+
const ensureBigint = (value) => {
|
|
4
|
+
if (typeof value === "bigint") {
|
|
5
|
+
return value;
|
|
6
|
+
}
|
|
7
|
+
if (typeof value === "string") {
|
|
8
|
+
return BigInt(value);
|
|
9
|
+
}
|
|
10
|
+
throw new Error(`Expected sync ID as bigint or string, received ${typeof value}`);
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Data access object for sync operations.
|
|
14
|
+
* Accepts Drizzle table references instead of hardcoded schema imports.
|
|
15
|
+
*/
|
|
16
|
+
export class SyncDao {
|
|
17
|
+
db;
|
|
18
|
+
tables;
|
|
19
|
+
constructor(db, tables) {
|
|
20
|
+
this.db = db;
|
|
21
|
+
this.tables = tables;
|
|
22
|
+
}
|
|
23
|
+
visibleGroupCondition(groups) {
|
|
24
|
+
const groupIdCol = getColumn(this.tables.syncActions, "groupId");
|
|
25
|
+
if (groups.length === 0) {
|
|
26
|
+
return isNull(groupIdCol);
|
|
27
|
+
}
|
|
28
|
+
return or(isNull(groupIdCol), inArray(groupIdCol, groups));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Gets the last sync ID.
|
|
32
|
+
*/
|
|
33
|
+
async getLastSyncId() {
|
|
34
|
+
const idCol = getColumn(this.tables.syncActions, "id");
|
|
35
|
+
const rows = await this.db
|
|
36
|
+
.select({ id: idCol })
|
|
37
|
+
.from(this.tables.syncActions)
|
|
38
|
+
.where()
|
|
39
|
+
.orderBy(desc(idCol))
|
|
40
|
+
.limit(1);
|
|
41
|
+
const [result] = rows;
|
|
42
|
+
return result ? ensureBigint(result.id) : 0n;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Gets the last sync ID visible to the given groups.
|
|
46
|
+
*/
|
|
47
|
+
async getLastSyncIdForGroups(groups) {
|
|
48
|
+
const idCol = getColumn(this.tables.syncActions, "id");
|
|
49
|
+
const rows = await this.db
|
|
50
|
+
.select({ id: idCol })
|
|
51
|
+
.from(this.tables.syncActions)
|
|
52
|
+
.where(this.visibleGroupCondition(groups))
|
|
53
|
+
.orderBy(desc(idCol))
|
|
54
|
+
.limit(1);
|
|
55
|
+
const [result] = rows;
|
|
56
|
+
return result ? ensureBigint(result.id) : 0n;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Gets sync actions after a given ID.
|
|
60
|
+
*/
|
|
61
|
+
async getSyncActions(afterId, groups, limit) {
|
|
62
|
+
const idCol = getColumn(this.tables.syncActions, "id");
|
|
63
|
+
const rows = await this.db
|
|
64
|
+
.select()
|
|
65
|
+
.from(this.tables.syncActions)
|
|
66
|
+
.where(and(gt(idCol, afterId), this.visibleGroupCondition(groups)))
|
|
67
|
+
.orderBy(asc(idCol))
|
|
68
|
+
.limit(limit);
|
|
69
|
+
return rows;
|
|
70
|
+
}
|
|
71
|
+
async getTouchedModelIdsAfter(afterId, groups, modelName, modelIds) {
|
|
72
|
+
if (modelIds.length === 0) {
|
|
73
|
+
return new Set();
|
|
74
|
+
}
|
|
75
|
+
const idCol = getColumn(this.tables.syncActions, "id");
|
|
76
|
+
const modelCol = getColumn(this.tables.syncActions, "model");
|
|
77
|
+
const modelIdCol = getColumn(this.tables.syncActions, "modelId");
|
|
78
|
+
const rows = await this.db
|
|
79
|
+
.select({ modelId: modelIdCol })
|
|
80
|
+
.from(this.tables.syncActions)
|
|
81
|
+
.where(and(gt(idCol, afterId), this.visibleGroupCondition(groups), eq(modelCol, modelName), inArray(modelIdCol, modelIds)))
|
|
82
|
+
.limit(50_000);
|
|
83
|
+
return new Set(rows.map((row) => row.modelId));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Creates a sync action.
|
|
87
|
+
*/
|
|
88
|
+
async createSyncAction(data) {
|
|
89
|
+
const rows = await this.db
|
|
90
|
+
.insert(this.tables.syncActions)
|
|
91
|
+
.values({
|
|
92
|
+
action: data.action,
|
|
93
|
+
clientId: data.clientId,
|
|
94
|
+
clientTxId: data.clientTxId,
|
|
95
|
+
data: data.data,
|
|
96
|
+
groupId: data.groupId,
|
|
97
|
+
model: data.model,
|
|
98
|
+
modelId: data.modelId,
|
|
99
|
+
})
|
|
100
|
+
.returning();
|
|
101
|
+
const [created] = rows;
|
|
102
|
+
if (!created) {
|
|
103
|
+
throw new Error("Failed to create sync action");
|
|
104
|
+
}
|
|
105
|
+
return created;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Gets user's group memberships.
|
|
109
|
+
*/
|
|
110
|
+
async getUserGroups(userId) {
|
|
111
|
+
const userIdCol = getColumn(this.tables.syncGroupMemberships, "userId");
|
|
112
|
+
const groupIdCol = getColumn(this.tables.syncGroupMemberships, "groupId");
|
|
113
|
+
const rows = await this.db
|
|
114
|
+
.select({ groupId: groupIdCol })
|
|
115
|
+
.from(this.tables.syncGroupMemberships)
|
|
116
|
+
.where(eq(userIdCol, userId))
|
|
117
|
+
.limit(10_000);
|
|
118
|
+
return rows.map((membership) => membership.groupId);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Finds an existing sync action for a client transaction.
|
|
122
|
+
*/
|
|
123
|
+
async findSyncActionByClientTx(clientId, clientTxId) {
|
|
124
|
+
const idCol = getColumn(this.tables.syncActions, "id");
|
|
125
|
+
const clientIdCol = getColumn(this.tables.syncActions, "clientId");
|
|
126
|
+
const clientTxIdCol = getColumn(this.tables.syncActions, "clientTxId");
|
|
127
|
+
const rows = await this.db
|
|
128
|
+
.select({ id: idCol })
|
|
129
|
+
.from(this.tables.syncActions)
|
|
130
|
+
.where(and(eq(clientIdCol, clientId), eq(clientTxIdCol, clientTxId)))
|
|
131
|
+
.orderBy(asc(idCol))
|
|
132
|
+
.limit(1);
|
|
133
|
+
const [result] = rows;
|
|
134
|
+
return result ? { id: ensureBigint(result.id) } : null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=sync-dao.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-dao.js","sourceRoot":"","sources":["../../src/dao/sync-dao.ts"],"names":[],"mappings":"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"}
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AnyPgTable } from "drizzle-orm/pg-core";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal Drizzle database interface used by sync-server internals.
|
|
4
|
+
*
|
|
5
|
+
* This covers the subset of Drizzle's query builder API that sync-server
|
|
6
|
+
* actually calls. Keeping this explicit (instead of depending on Drizzle's
|
|
7
|
+
* full type) means the package stays DB-agnostic and avoids type duplication
|
|
8
|
+
* issues across workspace node_modules.
|
|
9
|
+
*/
|
|
10
|
+
export interface SyncDb {
|
|
11
|
+
select(fields?: Record<string, unknown>): SyncDbSelectBuilder;
|
|
12
|
+
insert(table: AnyPgTable): {
|
|
13
|
+
values(data: Record<string, unknown>): {
|
|
14
|
+
returning(): Promise<Record<string, unknown>[]>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
delete(table: AnyPgTable): {
|
|
18
|
+
where(condition: unknown): Promise<unknown>;
|
|
19
|
+
};
|
|
20
|
+
update(table: AnyPgTable): {
|
|
21
|
+
set(data: unknown): {
|
|
22
|
+
where(condition: unknown): Promise<unknown>;
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface SyncDbWhereResult {
|
|
27
|
+
orderBy(...args: unknown[]): {
|
|
28
|
+
limit(n: number): Promise<Record<string, unknown>[]>;
|
|
29
|
+
};
|
|
30
|
+
limit(n: number): Promise<Record<string, unknown>[]>;
|
|
31
|
+
}
|
|
32
|
+
export interface SyncDbSelectBuilder {
|
|
33
|
+
from(table: AnyPgTable): {
|
|
34
|
+
where(condition?: unknown): SyncDbWhereResult;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=db.d.ts.map
|
package/dist/db.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAAC;IAC9D,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG;QACzB,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;YACrC,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;SACjD,CAAC;KACH,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG;QACzB,KAAK,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7C,CAAC;IACF,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG;QACzB,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG;YAClB,KAAK,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;SAC7C,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG;QAC3B,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;KACtD,CAAC;IACF,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG;QACvB,KAAK,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;KAC/C,CAAC;CACH"}
|
package/dist/db.js
ADDED
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { RedisClientType, RedisFunctions, RedisModules, RedisScripts } from "redis";
|
|
2
|
+
import type { SyncLogger } from "../config.js";
|
|
3
|
+
import type { SyncActionOutput } from "../types.js";
|
|
4
|
+
type RedisClient = RedisClientType<RedisModules, RedisFunctions, RedisScripts>;
|
|
5
|
+
export declare const safeJsonStringify: (value: unknown) => string;
|
|
6
|
+
export interface DeltaPublisherLike {
|
|
7
|
+
publish(action: SyncActionOutput, groups: string[]): Promise<void>;
|
|
8
|
+
publishMany(actions: SyncActionOutput[], groups: string[]): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export interface DeltaSubscriberLike {
|
|
11
|
+
start(): Promise<void>;
|
|
12
|
+
stop(): Promise<void>;
|
|
13
|
+
onDelta(callback: DeltaSubscriberCallback): () => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Publisher for broadcasting sync deltas via Redis pub/sub
|
|
17
|
+
*/
|
|
18
|
+
export declare class DeltaPublisher implements DeltaPublisherLike {
|
|
19
|
+
private readonly redis;
|
|
20
|
+
private readonly sourceId?;
|
|
21
|
+
constructor(redis: RedisClient, sourceId?: string);
|
|
22
|
+
publish(action: SyncActionOutput, groups: string[]): Promise<void>;
|
|
23
|
+
publishMany(actions: SyncActionOutput[], groups: string[]): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export type DeltaSubscriberCallback = (action: SyncActionOutput, groups: string[]) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Subscriber for receiving sync deltas via Redis pub/sub
|
|
28
|
+
*/
|
|
29
|
+
export declare class DeltaSubscriber implements DeltaSubscriberLike {
|
|
30
|
+
private readonly callbacks;
|
|
31
|
+
private readonly redis;
|
|
32
|
+
private subscriberRedis;
|
|
33
|
+
private readonly sourceId?;
|
|
34
|
+
constructor(redis: RedisClient, sourceId?: string);
|
|
35
|
+
start(): Promise<void>;
|
|
36
|
+
stop(): Promise<void>;
|
|
37
|
+
onDelta(callback: DeltaSubscriberCallback): () => void;
|
|
38
|
+
private notifyCallbacks;
|
|
39
|
+
}
|
|
40
|
+
declare class InMemoryDeltaBus {
|
|
41
|
+
private readonly callbacks;
|
|
42
|
+
publish(action: SyncActionOutput, groups: string[]): void;
|
|
43
|
+
onDelta(callback: DeltaSubscriberCallback): () => void;
|
|
44
|
+
}
|
|
45
|
+
export declare const createDeltaPublisher: (redis: RedisClient, sourceId?: string) => DeltaPublisher;
|
|
46
|
+
export declare const createDeltaSubscriber: (redis: RedisClient, sourceId?: string) => DeltaSubscriber;
|
|
47
|
+
export declare const createInMemoryDeltaBus: () => InMemoryDeltaBus;
|
|
48
|
+
export declare const createInMemoryDeltaPublisher: (bus: InMemoryDeltaBus) => DeltaPublisherLike;
|
|
49
|
+
export declare const createInMemoryDeltaSubscriber: (bus: InMemoryDeltaBus) => DeltaSubscriberLike;
|
|
50
|
+
export declare const createCompositeDeltaPublisher: (publishers: DeltaPublisherLike[], logger?: SyncLogger) => DeltaPublisherLike;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=delta-publisher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delta-publisher.d.ts","sourceRoot":"","sources":["../../src/delta/delta-publisher.ts"],"names":[],"mappings":"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"}
|