@undefineds.co/xpod 0.3.48 → 0.3.49
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/bin/xpod.js +0 -0
- package/dist/api/chatkit/pod-store.d.ts +16 -17
- package/dist/api/chatkit/pod-store.js +299 -231
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/schema.d.ts +1 -1
- package/dist/api/chatkit/service.js +13 -11
- package/dist/api/chatkit/service.js.map +1 -1
- package/dist/api/chatkit/store.d.ts +1 -0
- package/dist/api/chatkit/store.js +23 -11
- package/dist/api/chatkit/store.js.map +1 -1
- package/dist/api/chatkit/types.d.ts +17 -10
- package/dist/api/chatkit/types.js +97 -14
- package/dist/api/chatkit/types.js.map +1 -1
- package/dist/api/container/common.js +16 -2
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/routes.js +3 -0
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +3 -0
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/ChatKitV1Handler.js +1 -2
- package/dist/api/handlers/ChatKitV1Handler.js.map +1 -1
- package/dist/api/handlers/CoordinationHandler.d.ts +6 -0
- package/dist/api/handlers/CoordinationHandler.js +115 -0
- package/dist/api/handlers/CoordinationHandler.js.map +1 -0
- package/dist/api/handlers/MatrixHandler.d.ts +11 -0
- package/dist/api/handlers/MatrixHandler.js +120 -2
- package/dist/api/handlers/MatrixHandler.js.map +1 -1
- package/dist/api/handlers/RunHandler.js +33 -15
- package/dist/api/handlers/RunHandler.js.map +1 -1
- package/dist/api/handlers/index.d.ts +1 -0
- package/dist/api/handlers/index.js +1 -0
- package/dist/api/handlers/index.js.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/matrix/PodMatrixStore.d.ts +25 -1
- package/dist/api/matrix/PodMatrixStore.js +243 -38
- package/dist/api/matrix/PodMatrixStore.js.map +1 -1
- package/dist/api/matrix/index.d.ts +1 -1
- package/dist/api/matrix/index.js.map +1 -1
- package/dist/api/matrix/types.d.ts +23 -2
- package/dist/api/matrix/types.js.map +1 -1
- package/dist/api/protocol-metadata.d.ts +4 -0
- package/dist/api/protocol-metadata.js +54 -0
- package/dist/api/protocol-metadata.js.map +1 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.d.ts +42 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.js +250 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.js.map +1 -0
- package/dist/api/reconciler/ClientReconcilerCoordinator.jsonld +186 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.d.ts +39 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.js +91 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.js.map +1 -0
- package/dist/api/reconciler/ServerGroupReconcilerService.jsonld +146 -0
- package/dist/api/reconciler/WakeAgentQueue.d.ts +23 -0
- package/dist/api/reconciler/WakeAgentQueue.js +123 -0
- package/dist/api/reconciler/WakeAgentQueue.js.map +1 -0
- package/dist/api/reconciler/WakeAgentQueue.jsonld +91 -0
- package/dist/api/reconciler/coordination.d.ts +61 -0
- package/dist/api/reconciler/coordination.js +109 -0
- package/dist/api/reconciler/coordination.js.map +1 -0
- package/dist/api/reconciler/coordination.jsonld +186 -0
- package/dist/api/reconciler/index.d.ts +4 -0
- package/dist/api/reconciler/index.js +21 -0
- package/dist/api/reconciler/index.js.map +1 -0
- package/dist/api/runs/ManagedRunWorker.js +0 -5
- package/dist/api/runs/ManagedRunWorker.js.map +1 -1
- package/dist/api/runs/RunStateCenter.d.ts +1 -1
- package/dist/api/runs/RunStateCenter.js +12 -28
- package/dist/api/runs/RunStateCenter.js.map +1 -1
- package/dist/api/runs/store.d.ts +12 -15
- package/dist/api/runs/store.js +24 -15
- package/dist/api/runs/store.js.map +1 -1
- package/dist/api/tasks/TaskMaterializer.d.ts +1 -0
- package/dist/api/tasks/TaskMaterializer.js +10 -13
- package/dist/api/tasks/TaskMaterializer.js.map +1 -1
- package/dist/api/tasks/TaskService.d.ts +0 -2
- package/dist/api/tasks/TaskService.js +6 -16
- package/dist/api/tasks/TaskService.js.map +1 -1
- package/dist/api/tasks/store.d.ts +0 -2
- package/dist/api/tasks/store.js.map +1 -1
- package/dist/cli/commands/auth.d.ts +1 -1
- package/dist/cli/commands/auth.js +4 -5
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/backup.js +1 -1
- package/dist/cli/commands/backup.js.map +1 -1
- package/dist/cli/commands/login.js +1 -1
- package/dist/cli/commands/login.js.map +1 -1
- package/dist/cli/commands/pod.js +1 -1
- package/dist/cli/commands/pod.js.map +1 -1
- package/dist/cli/lib/auth-helper.d.ts +5 -3
- package/dist/cli/lib/auth-helper.js +5 -3
- package/dist/cli/lib/auth-helper.js.map +1 -1
- package/dist/cli/lib/credentials-store.d.ts +22 -4
- package/dist/cli/lib/credentials-store.js +68 -51
- package/dist/cli/lib/credentials-store.js.map +1 -1
- package/dist/components/components.jsonld +5 -1
- package/dist/components/context.jsonld +103 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/provision/LocalPodProvisioningService.d.ts +1 -0
- package/dist/provision/LocalPodProvisioningService.js +9 -0
- package/dist/provision/LocalPodProvisioningService.js.map +1 -1
- package/dist/provision/LocalPodProvisioningService.jsonld +4 -0
- package/package.json +2 -2
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PodMatrixStore = void 0;
|
|
4
4
|
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const global_logger_factory_1 = require("global-logger-factory");
|
|
5
6
|
const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
|
|
6
7
|
const models_1 = require("@undefineds.co/models");
|
|
8
|
+
const reconciler_1 = require("../reconciler");
|
|
9
|
+
const protocol_metadata_1 = require("../protocol-metadata");
|
|
7
10
|
const AuthContext_1 = require("../auth/AuthContext");
|
|
8
11
|
const schema = {
|
|
9
12
|
chat: models_1.chatResource,
|
|
@@ -12,7 +15,17 @@ const schema = {
|
|
|
12
15
|
};
|
|
13
16
|
class PodMatrixStore {
|
|
14
17
|
constructor(options) {
|
|
18
|
+
this.logger = (0, global_logger_factory_1.getLoggerFor)(this);
|
|
15
19
|
this.serverName = options.serverName;
|
|
20
|
+
this.serverGroupReconcilerService = options.serverGroupReconcilerService;
|
|
21
|
+
}
|
|
22
|
+
async getAccount(context) {
|
|
23
|
+
const matrixUserId = this.getMatrixUserId(context);
|
|
24
|
+
return {
|
|
25
|
+
userId: matrixUserId,
|
|
26
|
+
deviceId: this.deviceIdFromUserId(context.webId),
|
|
27
|
+
displayName: this.displayNameFromUserId(matrixUserId),
|
|
28
|
+
};
|
|
16
29
|
}
|
|
17
30
|
async createRoom(input, context) {
|
|
18
31
|
const db = await this.getDb(context);
|
|
@@ -21,45 +34,48 @@ class PodMatrixStore {
|
|
|
21
34
|
const roomId = this.generateRoomId(context);
|
|
22
35
|
const chatId = this.chatResourceIdFromRoomId(roomId);
|
|
23
36
|
const threadId = this.threadResourceIdFromRoomId(roomId);
|
|
37
|
+
const reconcilerOwner = 'server';
|
|
38
|
+
const coordination = (0, reconciler_1.reconcilerCoordinationMetadata)(reconcilerOwner);
|
|
24
39
|
await db.insert(models_1.chatResource).values({
|
|
25
40
|
id: chatId,
|
|
26
41
|
title: input.name ?? roomId,
|
|
27
42
|
description: input.topic ?? null,
|
|
28
|
-
author: context.
|
|
43
|
+
author: context.webId,
|
|
29
44
|
status: 'active',
|
|
30
|
-
participants: [context.
|
|
31
|
-
metadata: {
|
|
45
|
+
participants: [context.webId],
|
|
46
|
+
metadata: (0, protocol_metadata_1.withProtocolMetadata)({
|
|
32
47
|
protocol: 'matrix',
|
|
48
|
+
...coordination,
|
|
49
|
+
}, 'matrix', {
|
|
33
50
|
roomId,
|
|
34
51
|
canonicalAlias: input.room_alias_name ? `#${input.room_alias_name}:${this.getServerName(context)}` : null,
|
|
35
52
|
visibility: input.visibility === 'public' ? 'public' : 'private',
|
|
36
53
|
roomVersion: String(input.creation_content?.room_version ?? '11'),
|
|
37
54
|
federate: input.creation_content?.['m.federate'] === true,
|
|
38
|
-
members: [context.
|
|
55
|
+
members: [context.webId],
|
|
39
56
|
preset: input.preset,
|
|
40
|
-
is_direct: input.is_direct,
|
|
41
57
|
invite: input.invite ?? [],
|
|
42
|
-
},
|
|
58
|
+
}),
|
|
43
59
|
createdAt: new Date(now).toISOString(),
|
|
44
60
|
updatedAt: new Date(now).toISOString(),
|
|
45
61
|
});
|
|
46
62
|
await db.insert(models_1.threadResource).values({
|
|
47
63
|
id: threadId,
|
|
48
|
-
|
|
64
|
+
parent: this.chatParentRefFromRoomId(roomId),
|
|
49
65
|
title: input.name ?? roomId,
|
|
50
66
|
status: 'active',
|
|
51
|
-
metadata: {
|
|
67
|
+
metadata: (0, protocol_metadata_1.withProtocolMetadata)({
|
|
52
68
|
protocol: 'matrix',
|
|
53
|
-
roomId,
|
|
54
69
|
commandKind: 'chat',
|
|
55
70
|
surface_id: this.surfaceIdFromRoomId(roomId),
|
|
56
|
-
|
|
57
|
-
},
|
|
71
|
+
...coordination,
|
|
72
|
+
}, 'matrix', { roomId }),
|
|
58
73
|
createdAt: new Date(now).toISOString(),
|
|
59
74
|
updatedAt: new Date(now).toISOString(),
|
|
60
75
|
});
|
|
61
76
|
await this.appendEvent(db, {
|
|
62
77
|
roomId,
|
|
78
|
+
reconcilerOwner,
|
|
63
79
|
type: 'm.room.create',
|
|
64
80
|
sender,
|
|
65
81
|
originServerTs: now,
|
|
@@ -73,6 +89,7 @@ class PodMatrixStore {
|
|
|
73
89
|
}, context);
|
|
74
90
|
await this.appendEvent(db, {
|
|
75
91
|
roomId,
|
|
92
|
+
reconcilerOwner,
|
|
76
93
|
type: 'm.room.member',
|
|
77
94
|
sender,
|
|
78
95
|
originServerTs: now + 1,
|
|
@@ -85,6 +102,7 @@ class PodMatrixStore {
|
|
|
85
102
|
if (input.name) {
|
|
86
103
|
await this.appendEvent(db, {
|
|
87
104
|
roomId,
|
|
105
|
+
reconcilerOwner,
|
|
88
106
|
type: 'm.room.name',
|
|
89
107
|
sender,
|
|
90
108
|
originServerTs: now + 2,
|
|
@@ -95,6 +113,7 @@ class PodMatrixStore {
|
|
|
95
113
|
if (input.topic) {
|
|
96
114
|
await this.appendEvent(db, {
|
|
97
115
|
roomId,
|
|
116
|
+
reconcilerOwner,
|
|
98
117
|
type: 'm.room.topic',
|
|
99
118
|
sender,
|
|
100
119
|
originServerTs: now + 3,
|
|
@@ -105,6 +124,7 @@ class PodMatrixStore {
|
|
|
105
124
|
for (const state of input.initial_state ?? []) {
|
|
106
125
|
await this.appendEvent(db, {
|
|
107
126
|
roomId,
|
|
127
|
+
reconcilerOwner,
|
|
108
128
|
type: state.type,
|
|
109
129
|
sender,
|
|
110
130
|
originServerTs: Date.now(),
|
|
@@ -112,14 +132,40 @@ class PodMatrixStore {
|
|
|
112
132
|
content: state.content ?? {},
|
|
113
133
|
}, context);
|
|
114
134
|
}
|
|
135
|
+
for (const invitee of input.invite ?? []) {
|
|
136
|
+
await this.appendMembershipEvent(db, roomId, invitee, 'invite', context, { sender, reconcilerOwner });
|
|
137
|
+
}
|
|
115
138
|
return {
|
|
116
139
|
roomId,
|
|
140
|
+
canonicalAlias: input.room_alias_name ? `#${input.room_alias_name}:${this.getServerName(context)}` : undefined,
|
|
117
141
|
name: input.name,
|
|
118
142
|
topic: input.topic,
|
|
119
143
|
creator: sender,
|
|
144
|
+
reconcilerOwner: coordination.reconcilerOwner,
|
|
120
145
|
createdAt: now,
|
|
121
146
|
};
|
|
122
147
|
}
|
|
148
|
+
async joinRoom(roomIdOrAlias, context) {
|
|
149
|
+
const db = await this.getDb(context);
|
|
150
|
+
const roomId = await this.resolveRoomId(db, roomIdOrAlias);
|
|
151
|
+
await this.ensureRoomExists(db, roomId);
|
|
152
|
+
const sender = this.getMatrixUserId(context);
|
|
153
|
+
const existing = await this.findLatestStateEvent(db, roomId, 'm.room.member', sender, context);
|
|
154
|
+
if (existing?.content.membership !== 'join') {
|
|
155
|
+
await this.appendMembershipEvent(db, roomId, sender, 'join', context);
|
|
156
|
+
}
|
|
157
|
+
return { roomId };
|
|
158
|
+
}
|
|
159
|
+
async inviteUser(roomId, userId, context) {
|
|
160
|
+
const db = await this.getDb(context);
|
|
161
|
+
await this.ensureRoomExists(db, roomId);
|
|
162
|
+
await this.appendMembershipEvent(db, roomId, userId, 'invite', context);
|
|
163
|
+
}
|
|
164
|
+
async leaveRoom(roomId, context) {
|
|
165
|
+
const db = await this.getDb(context);
|
|
166
|
+
await this.ensureRoomExists(db, roomId);
|
|
167
|
+
await this.appendMembershipEvent(db, roomId, this.getMatrixUserId(context), 'leave', context);
|
|
168
|
+
}
|
|
123
169
|
async sendEvent(roomId, eventType, txnId, content, context) {
|
|
124
170
|
const db = await this.getDb(context);
|
|
125
171
|
await this.ensureRoomExists(db, roomId);
|
|
@@ -138,9 +184,21 @@ class PodMatrixStore {
|
|
|
138
184
|
}, context);
|
|
139
185
|
return event;
|
|
140
186
|
}
|
|
187
|
+
async setState(roomId, eventType, stateKey, content, context) {
|
|
188
|
+
const db = await this.getDb(context);
|
|
189
|
+
await this.ensureRoomExists(db, roomId);
|
|
190
|
+
return this.appendEvent(db, {
|
|
191
|
+
roomId,
|
|
192
|
+
type: eventType,
|
|
193
|
+
sender: this.getMatrixUserId(context),
|
|
194
|
+
stateKey,
|
|
195
|
+
originServerTs: Date.now(),
|
|
196
|
+
content,
|
|
197
|
+
}, context);
|
|
198
|
+
}
|
|
141
199
|
async sync(context, options = {}) {
|
|
142
200
|
const db = await this.getDb(context);
|
|
143
|
-
const rooms = await this.
|
|
201
|
+
const rooms = await this.listJoinedRoomRecords(db, context);
|
|
144
202
|
const sinceTs = this.parseSyncToken(options.since);
|
|
145
203
|
const limit = options.limit && options.limit > 0 ? options.limit : 50;
|
|
146
204
|
const join = {};
|
|
@@ -157,6 +215,9 @@ class PodMatrixStore {
|
|
|
157
215
|
events: events.map((event) => this.toClientEvent(event)),
|
|
158
216
|
limited: false,
|
|
159
217
|
},
|
|
218
|
+
'co.undefineds.coordination': {
|
|
219
|
+
reconcilerOwner: room.reconcilerOwner,
|
|
220
|
+
},
|
|
160
221
|
};
|
|
161
222
|
}
|
|
162
223
|
return {
|
|
@@ -164,6 +225,25 @@ class PodMatrixStore {
|
|
|
164
225
|
rooms: { join },
|
|
165
226
|
};
|
|
166
227
|
}
|
|
228
|
+
async listJoinedRooms(context) {
|
|
229
|
+
const db = await this.getDb(context);
|
|
230
|
+
return (await this.listJoinedRoomRecords(db, context)).map((room) => room.roomId);
|
|
231
|
+
}
|
|
232
|
+
async getMembers(roomId, context) {
|
|
233
|
+
const db = await this.getDb(context);
|
|
234
|
+
await this.ensureRoomExists(db, roomId);
|
|
235
|
+
const events = await this.listEvents(db, roomId, context, { newestFirst: true });
|
|
236
|
+
const latestByStateKey = new Map();
|
|
237
|
+
for (const event of events) {
|
|
238
|
+
if (event.type !== 'm.room.member' || event.stateKey === undefined || latestByStateKey.has(event.stateKey)) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
latestByStateKey.set(event.stateKey, event);
|
|
242
|
+
}
|
|
243
|
+
return Array.from(latestByStateKey.values())
|
|
244
|
+
.sort((left, right) => (left.originServerTs - right.originServerTs) || ((left.depth ?? 0) - (right.depth ?? 0)))
|
|
245
|
+
.map((event) => this.toClientEvent(event));
|
|
246
|
+
}
|
|
167
247
|
async listMessages(roomId, context, options = {}) {
|
|
168
248
|
const db = await this.getDb(context);
|
|
169
249
|
await this.ensureRoomExists(db, roomId);
|
|
@@ -235,12 +315,23 @@ class PodMatrixStore {
|
|
|
235
315
|
const eventId = this.generateEventId(context);
|
|
236
316
|
const depth = await this.nextEventDepth(db, input.roomId, context);
|
|
237
317
|
const originIso = new Date(input.originServerTs).toISOString();
|
|
318
|
+
const needsRoomMetadata = input.reconcilerOwner === undefined
|
|
319
|
+
|| (input.type === 'm.room.message' && this.serverGroupReconcilerService !== undefined);
|
|
320
|
+
const roomContext = needsRoomMetadata ? await this.getRoomContext(db, input.roomId) : undefined;
|
|
321
|
+
const roomMetadata = roomContext?.metadata;
|
|
322
|
+
const reconcilerOwner = input.reconcilerOwner ?? this.reconcilerOwnerFromRoomMetadata(roomMetadata);
|
|
323
|
+
const coordination = (0, reconciler_1.reconcilerCoordinationMetadata)(reconcilerOwner);
|
|
324
|
+
const messageResourceId = this.messageResourceIdFromEvent(input.roomId, eventId, input.originServerTs);
|
|
325
|
+
const thread = this.resolveDataResourceUriFromId(this.threadResourceIdFromRoomId(input.roomId), context);
|
|
326
|
+
const contentText = this.messageContentFromMatrixEvent(input.type, input.content);
|
|
327
|
+
const mentions = this.mentionsFromMatrixContent(input.content);
|
|
328
|
+
const routeTargetAgent = this.routeTargetAgentFromMatrixContent(input.content);
|
|
238
329
|
const record = {
|
|
239
330
|
eventId,
|
|
240
331
|
roomId: input.roomId,
|
|
241
332
|
type: input.type,
|
|
242
333
|
sender: input.sender,
|
|
243
|
-
senderWebId: context.
|
|
334
|
+
senderWebId: context.webId,
|
|
244
335
|
originServerTs: input.originServerTs,
|
|
245
336
|
depth,
|
|
246
337
|
txnId: input.txnId ?? undefined,
|
|
@@ -249,40 +340,93 @@ class PodMatrixStore {
|
|
|
249
340
|
createdAt: originIso,
|
|
250
341
|
};
|
|
251
342
|
await db.insert(models_1.messageResource).values({
|
|
252
|
-
id:
|
|
343
|
+
id: messageResourceId,
|
|
344
|
+
parent: this.resolveDataResourceUriFromId(this.messageParentResourceIdFromRoomId(input.roomId), context),
|
|
253
345
|
chat: this.chatResourceIdFromRoomId(input.roomId),
|
|
254
|
-
thread
|
|
255
|
-
maker: context.
|
|
346
|
+
thread,
|
|
347
|
+
maker: context.webId,
|
|
256
348
|
role: input.type === 'm.room.message' ? models_1.MessageRole.USER : models_1.MessageRole.SYSTEM,
|
|
257
|
-
content:
|
|
349
|
+
content: contentText,
|
|
258
350
|
status: models_1.MessageStatus.SENT,
|
|
259
|
-
|
|
351
|
+
mentions,
|
|
352
|
+
routeTargetAgent: routeTargetAgent ?? null,
|
|
353
|
+
metadata: (0, protocol_metadata_1.withProtocolMetadata)({
|
|
260
354
|
protocol: 'matrix',
|
|
355
|
+
commandKind: 'chat',
|
|
356
|
+
surface_id: this.surfaceIdFromRoomId(input.roomId),
|
|
357
|
+
...coordination,
|
|
358
|
+
}, 'matrix', {
|
|
261
359
|
eventId,
|
|
262
360
|
roomId: input.roomId,
|
|
263
361
|
eventType: input.type,
|
|
264
362
|
sender: input.sender,
|
|
265
|
-
senderWebId: context.
|
|
363
|
+
senderWebId: context.webId,
|
|
266
364
|
originServerTs: input.originServerTs,
|
|
267
365
|
depth,
|
|
268
366
|
txnId: input.txnId ?? null,
|
|
269
367
|
stateKey: input.stateKey ?? null,
|
|
270
368
|
content: input.content,
|
|
271
|
-
|
|
272
|
-
surface_id: this.surfaceIdFromRoomId(input.roomId),
|
|
273
|
-
chat_id: this.surfaceIdFromRoomId(input.roomId),
|
|
274
|
-
},
|
|
369
|
+
}),
|
|
275
370
|
createdAt: originIso,
|
|
276
371
|
updatedAt: originIso,
|
|
277
372
|
});
|
|
373
|
+
await this.reconcileGroupUserMessage({
|
|
374
|
+
thread,
|
|
375
|
+
triggerMessage: this.resolveDataResourceUriFromId(messageResourceId, context),
|
|
376
|
+
actor: context.webId,
|
|
377
|
+
role: input.type === 'm.room.message' ? models_1.MessageRole.USER : models_1.MessageRole.SYSTEM,
|
|
378
|
+
content: contentText,
|
|
379
|
+
reconcilerOwner,
|
|
380
|
+
mentions,
|
|
381
|
+
routeTargetAgent,
|
|
382
|
+
participants: roomContext?.participants,
|
|
383
|
+
});
|
|
278
384
|
return record;
|
|
279
385
|
}
|
|
386
|
+
async appendMembershipEvent(db, roomId, memberUserId, membership, context, options = {}) {
|
|
387
|
+
const sender = options.sender ?? this.getMatrixUserId(context);
|
|
388
|
+
return this.appendEvent(db, {
|
|
389
|
+
roomId,
|
|
390
|
+
reconcilerOwner: options.reconcilerOwner,
|
|
391
|
+
type: 'm.room.member',
|
|
392
|
+
sender,
|
|
393
|
+
originServerTs: Date.now(),
|
|
394
|
+
stateKey: memberUserId,
|
|
395
|
+
content: {
|
|
396
|
+
membership,
|
|
397
|
+
displayname: this.displayNameFromUserId(memberUserId),
|
|
398
|
+
},
|
|
399
|
+
}, context);
|
|
400
|
+
}
|
|
280
401
|
async listRooms(db) {
|
|
281
402
|
const rooms = await db.select().from(models_1.chatResource);
|
|
282
403
|
return rooms
|
|
283
404
|
.map((room) => this.chatSourceToRoomRecord(room))
|
|
284
405
|
.filter((room) => room !== undefined);
|
|
285
406
|
}
|
|
407
|
+
async listJoinedRoomRecords(db, context) {
|
|
408
|
+
const rooms = await this.listRooms(db);
|
|
409
|
+
const matrixUserId = this.getMatrixUserId(context);
|
|
410
|
+
const joined = [];
|
|
411
|
+
for (const room of rooms) {
|
|
412
|
+
const membership = await this.findLatestStateEvent(db, room.roomId, 'm.room.member', matrixUserId, context);
|
|
413
|
+
if (!membership || membership.content.membership === 'join' || membership.content.membership === 'invite') {
|
|
414
|
+
joined.push(room);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
return joined;
|
|
418
|
+
}
|
|
419
|
+
async resolveRoomId(db, roomIdOrAlias) {
|
|
420
|
+
if (!roomIdOrAlias.startsWith('#')) {
|
|
421
|
+
return roomIdOrAlias;
|
|
422
|
+
}
|
|
423
|
+
const rooms = await this.listRooms(db);
|
|
424
|
+
const room = rooms.find((candidate) => candidate.canonicalAlias === roomIdOrAlias);
|
|
425
|
+
if (!room) {
|
|
426
|
+
throw new Error(`Matrix room alias not found: ${roomIdOrAlias}`);
|
|
427
|
+
}
|
|
428
|
+
return room.roomId;
|
|
429
|
+
}
|
|
286
430
|
async listEvents(db, roomId, context, options = {}) {
|
|
287
431
|
const conditions = [
|
|
288
432
|
(0, drizzle_solid_1.eq)(models_1.messageResource.thread, this.resolveDataResourceUriFromId(this.threadResourceIdFromRoomId(roomId), context)),
|
|
@@ -317,20 +461,23 @@ class PodMatrixStore {
|
|
|
317
461
|
}
|
|
318
462
|
eventSourceToRecord(source) {
|
|
319
463
|
const metadata = this.parseJsonObject(source.metadata) ?? {};
|
|
320
|
-
const
|
|
464
|
+
const matrix = (0, protocol_metadata_1.getProtocolMetadata)(metadata, 'matrix') ?? {};
|
|
465
|
+
const content = this.parseJsonObject(matrix.content)
|
|
466
|
+
?? this.parseJsonObject(metadata.content)
|
|
321
467
|
?? this.parseJsonObject(source.content)
|
|
322
468
|
?? {};
|
|
323
|
-
const unsigned = this.parseJsonObject(
|
|
324
|
-
|
|
325
|
-
const
|
|
469
|
+
const unsigned = this.parseJsonObject(matrix.unsigned)
|
|
470
|
+
?? this.parseJsonObject(metadata.unsigned);
|
|
471
|
+
const stateKey = this.stringValue(matrix.stateKey ?? matrix.state_key ?? metadata.stateKey);
|
|
472
|
+
const txnId = this.stringValue(matrix.txnId ?? matrix.txn_id ?? metadata.txnId);
|
|
326
473
|
return {
|
|
327
|
-
eventId: this.stringValue(metadata.eventId) ?? source.id,
|
|
328
|
-
roomId: this.stringValue(metadata.roomId) ?? '',
|
|
329
|
-
type: this.stringValue(metadata.eventType) ?? 'm.room.message',
|
|
330
|
-
sender: this.stringValue(metadata.sender) ?? '',
|
|
331
|
-
senderWebId: this.stringValue(metadata.senderWebId) ?? source.maker ?? undefined,
|
|
332
|
-
originServerTs: this.numberValue(metadata.originServerTs) ?? this.isoToMillis(source.createdAt) ?? Date.now(),
|
|
333
|
-
depth: this.numberValue(metadata.depth),
|
|
474
|
+
eventId: this.stringValue(matrix.eventId ?? matrix.event_id ?? metadata.eventId) ?? source.id,
|
|
475
|
+
roomId: this.stringValue(matrix.roomId ?? matrix.room_id ?? metadata.roomId) ?? '',
|
|
476
|
+
type: this.stringValue(matrix.eventType ?? matrix.event_type ?? metadata.eventType) ?? 'm.room.message',
|
|
477
|
+
sender: this.stringValue(matrix.sender ?? metadata.sender) ?? '',
|
|
478
|
+
senderWebId: this.stringValue(matrix.senderWebId ?? matrix.sender_web_id ?? metadata.senderWebId) ?? source.maker ?? undefined,
|
|
479
|
+
originServerTs: this.numberValue(matrix.originServerTs ?? matrix.origin_server_ts ?? metadata.originServerTs) ?? this.isoToMillis(source.createdAt) ?? Date.now(),
|
|
480
|
+
depth: this.numberValue(matrix.depth ?? metadata.depth),
|
|
334
481
|
txnId: txnId ?? undefined,
|
|
335
482
|
content,
|
|
336
483
|
stateKey: stateKey ?? undefined,
|
|
@@ -342,15 +489,20 @@ class PodMatrixStore {
|
|
|
342
489
|
if (metadata.protocol !== 'matrix') {
|
|
343
490
|
return undefined;
|
|
344
491
|
}
|
|
345
|
-
const
|
|
492
|
+
const matrix = (0, protocol_metadata_1.getProtocolMetadata)(metadata, 'matrix') ?? {};
|
|
493
|
+
const roomId = this.stringValue(matrix.roomId ?? matrix.room_id ?? metadata.roomId);
|
|
346
494
|
if (!roomId) {
|
|
347
495
|
return undefined;
|
|
348
496
|
}
|
|
497
|
+
const reconcilerOwner = (0, reconciler_1.normalizeReconcilerOwner)(metadata.reconcilerOwner, 'server');
|
|
498
|
+
const coordination = (0, reconciler_1.reconcilerCoordinationMetadata)(reconcilerOwner);
|
|
349
499
|
return {
|
|
350
500
|
roomId,
|
|
501
|
+
canonicalAlias: this.stringValue(matrix.canonicalAlias ?? matrix.canonical_alias ?? metadata.canonicalAlias),
|
|
351
502
|
name: source.title ?? undefined,
|
|
352
503
|
topic: source.description ?? undefined,
|
|
353
504
|
creator: source.author ?? '',
|
|
505
|
+
reconcilerOwner: coordination.reconcilerOwner,
|
|
354
506
|
createdAt: this.isoToMillis(source.createdAt) ?? 0,
|
|
355
507
|
};
|
|
356
508
|
}
|
|
@@ -395,15 +547,59 @@ class PodMatrixStore {
|
|
|
395
547
|
}
|
|
396
548
|
return Number.isFinite(value) ? value : undefined;
|
|
397
549
|
}
|
|
550
|
+
async getRoomContext(db, roomId) {
|
|
551
|
+
const room = await db.findById(models_1.chatResource, this.chatResourceIdFromRoomId(roomId));
|
|
552
|
+
return {
|
|
553
|
+
metadata: this.parseJsonObject(room?.metadata),
|
|
554
|
+
participants: (0, reconciler_1.normalizeAgentUris)(room?.participants),
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
reconcilerOwnerFromRoomMetadata(metadata) {
|
|
558
|
+
return (0, reconciler_1.normalizeReconcilerOwner)(metadata?.reconcilerOwner, 'server');
|
|
559
|
+
}
|
|
560
|
+
async reconcileGroupUserMessage(input) {
|
|
561
|
+
if (!this.serverGroupReconcilerService || input.role !== models_1.MessageRole.USER) {
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
try {
|
|
565
|
+
await this.serverGroupReconcilerService.reconcileThreadMessage({
|
|
566
|
+
thread: input.thread,
|
|
567
|
+
triggerMessage: input.triggerMessage,
|
|
568
|
+
actor: input.actor,
|
|
569
|
+
role: 'user',
|
|
570
|
+
content: input.content,
|
|
571
|
+
reconcilerOwner: input.reconcilerOwner,
|
|
572
|
+
mentions: input.mentions,
|
|
573
|
+
routeTargetAgent: input.routeTargetAgent,
|
|
574
|
+
participants: input.participants,
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
catch (error) {
|
|
578
|
+
this.logger.warn(`Failed to enqueue Matrix group Reconciler wake: ${error}`);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
398
581
|
messageContentFromMatrixEvent(eventType, content) {
|
|
399
582
|
if (eventType === 'm.room.message' && typeof content.body === 'string') {
|
|
400
583
|
return content.body;
|
|
401
584
|
}
|
|
402
585
|
return JSON.stringify(content);
|
|
403
586
|
}
|
|
587
|
+
mentionsFromMatrixContent(content) {
|
|
588
|
+
const matrixMentions = this.parseJsonObject(content['m.mentions']);
|
|
589
|
+
return (0, reconciler_1.normalizeAgentUris)([
|
|
590
|
+
...(0, reconciler_1.normalizeAgentUris)(content.mentions),
|
|
591
|
+
...(0, reconciler_1.normalizeAgentUris)(content['co.undefineds.mentions']),
|
|
592
|
+
...(0, reconciler_1.normalizeAgentUris)(matrixMentions?.agents),
|
|
593
|
+
]);
|
|
594
|
+
}
|
|
595
|
+
routeTargetAgentFromMatrixContent(content) {
|
|
596
|
+
return this.stringValue(content.routeTargetAgent)
|
|
597
|
+
?? this.stringValue(content['co.undefineds.routeTargetAgent'])
|
|
598
|
+
?? this.stringValue(content['co.undefineds.route_target_agent']);
|
|
599
|
+
}
|
|
404
600
|
getMatrixUserId(context) {
|
|
405
601
|
const serverName = this.getServerName(context);
|
|
406
|
-
const localpart = this.localpartFromUserId(context.
|
|
602
|
+
const localpart = this.localpartFromUserId(context.webId);
|
|
407
603
|
return `@${localpart}:${serverName}`;
|
|
408
604
|
}
|
|
409
605
|
getServerName(context) {
|
|
@@ -411,7 +607,7 @@ class PodMatrixStore {
|
|
|
411
607
|
return this.serverName;
|
|
412
608
|
}
|
|
413
609
|
try {
|
|
414
|
-
return new URL(context.
|
|
610
|
+
return new URL(context.webId).host || 'localhost';
|
|
415
611
|
}
|
|
416
612
|
catch {
|
|
417
613
|
return 'localhost';
|
|
@@ -436,6 +632,9 @@ class PodMatrixStore {
|
|
|
436
632
|
generateEventId(context) {
|
|
437
633
|
return `$${this.randomId(24)}:${this.getServerName(context)}`;
|
|
438
634
|
}
|
|
635
|
+
deviceIdFromUserId(userId) {
|
|
636
|
+
return `XPOD${(0, node_crypto_1.createHash)('sha256').update(userId).digest('hex').slice(0, 12).toUpperCase()}`;
|
|
637
|
+
}
|
|
439
638
|
randomId(size) {
|
|
440
639
|
return (0, node_crypto_1.randomBytes)(size).toString('base64url');
|
|
441
640
|
}
|
|
@@ -448,15 +647,21 @@ class PodMatrixStore {
|
|
|
448
647
|
chatResourceIdFromRoomId(roomId) {
|
|
449
648
|
return `${this.surfaceIdFromRoomId(roomId)}/index.ttl#this`;
|
|
450
649
|
}
|
|
650
|
+
messageParentResourceIdFromRoomId(roomId) {
|
|
651
|
+
return `chat/${this.surfaceIdFromRoomId(roomId)}/index.ttl#this`;
|
|
652
|
+
}
|
|
451
653
|
threadResourceIdFromRoomId(roomId) {
|
|
452
654
|
return `chat/${this.surfaceIdFromRoomId(roomId)}/index.ttl#thread`;
|
|
453
655
|
}
|
|
656
|
+
chatParentRefFromRoomId(roomId) {
|
|
657
|
+
return `/.data/chat/${this.chatResourceIdFromRoomId(roomId)}`;
|
|
658
|
+
}
|
|
454
659
|
messageResourceIdFromEvent(roomId, eventId, ts) {
|
|
455
660
|
const { yyyy, MM, dd } = this.dateParts(ts);
|
|
456
661
|
return `chat/${this.surfaceIdFromRoomId(roomId)}/${yyyy}/${MM}/${dd}/messages.ttl#${this.slug(eventId)}`;
|
|
457
662
|
}
|
|
458
663
|
resolveDataResourceUriFromId(resourceId, context) {
|
|
459
|
-
const podBaseUrl = this.derivePodBaseUrl(
|
|
664
|
+
const podBaseUrl = this.derivePodBaseUrl(context.webId);
|
|
460
665
|
if (!podBaseUrl) {
|
|
461
666
|
return resourceId;
|
|
462
667
|
}
|