@takosjp/yurucommu-core 3.4.3 → 3.4.4
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/migrations/0023_delivery_resolution_outbox.sql +33 -0
- package/migrations/0024_delivery_fanout_outbox.sql +35 -0
- package/migrations/0025_delivery_endpoint_terminal_retention.sql +6 -0
- package/migrations/0026_remote_actor_fetch_failures.sql +29 -0
- package/migrations/0027_remote_actor_tombstones.sql +12 -0
- package/migrations/0028_remote_actor_delivery_fence.sql +30 -0
- package/migrations/0029_delivery_endpoint_recipients.sql +47 -0
- package/package.json +2 -1
- package/packages/api/package.json +1 -1
- package/packages/api/src/lib/api/communities.ts +2 -0
- package/packages/api/src/lib/api/fetch.ts +69 -13
- package/packages/api/src/lib/api/normalize.ts +32 -10
- package/packages/api/src/lib/api/notifications.ts +4 -1
- package/packages/api/src/lib/rtc-client.ts +127 -29
- package/src/backend/federation-helpers.ts +1 -0
- package/src/backend/index.ts +16 -3
- package/src/backend/lib/account-migration.ts +340 -0
- package/src/backend/lib/activity-delete-cascade.ts +193 -0
- package/src/backend/lib/activitypub-actor-cache.ts +615 -48
- package/src/backend/lib/activitypub-actor-identity-sql.ts +179 -0
- package/src/backend/lib/activitypub-actor-identity.ts +39 -0
- package/src/backend/lib/activitypub-validators.ts +62 -4
- package/src/backend/lib/ap-ids.ts +36 -6
- package/src/backend/lib/ap-verify.ts +7 -17
- package/src/backend/lib/blocklist-purge.ts +676 -42
- package/src/backend/lib/blocklist.ts +278 -39
- package/src/backend/lib/community-visibility.ts +47 -33
- package/src/backend/lib/delivery/fanout-outbox.ts +336 -0
- package/src/backend/lib/delivery/planner.ts +16 -12
- package/src/backend/lib/delivery/queue-batching.ts +389 -145
- package/src/backend/lib/delivery/queue-delivery.ts +47 -25
- package/src/backend/lib/delivery/queue.ts +479 -73
- package/src/backend/lib/delivery/resolution-outbox.ts +456 -0
- package/src/backend/lib/delivery/types.ts +31 -7
- package/src/backend/lib/feed-exclude.ts +40 -28
- package/src/backend/lib/follow-edge-mutations.ts +217 -0
- package/src/backend/lib/notification-eligibility.ts +15 -9
- package/src/backend/lib/notification-push.ts +2 -2
- package/src/backend/lib/oidc-id-token.ts +66 -0
- package/src/backend/lib/personal-actor-moderation.ts +239 -0
- package/src/backend/lib/post-visibility.ts +79 -16
- package/src/backend/lib/remote-activity-id.ts +61 -0
- package/src/backend/lib/unread-counts.ts +3 -0
- package/src/backend/retention.ts +38 -1
- package/src/backend/routes/account-teardown.ts +422 -156
- package/src/backend/routes/activitypub/handlers/actor-inbox-handlers.ts +104 -105
- package/src/backend/routes/activitypub/handlers/inbound-community-scope.ts +121 -0
- package/src/backend/routes/activitypub/handlers/inbound-object-identity.ts +54 -0
- package/src/backend/routes/activitypub/handlers/inbound-reply-target.ts +34 -0
- package/src/backend/routes/activitypub/handlers/inbound-story-projection.ts +438 -0
- package/src/backend/routes/activitypub/handlers/inbox-content-handlers.ts +1121 -806
- package/src/backend/routes/activitypub/handlers/inbox-follow-handlers.ts +118 -153
- package/src/backend/routes/activitypub/handlers/inbox-interaction-handlers.ts +185 -168
- package/src/backend/routes/activitypub/handlers/inbox-shared-helpers.ts +220 -32
- package/src/backend/routes/activitypub/inbound-activity-identity.ts +16 -0
- package/src/backend/routes/activitypub/inbound-activity-reference.ts +116 -0
- package/src/backend/routes/activitypub/inbound-addressing.ts +87 -0
- package/src/backend/routes/activitypub/inbox-addressing.ts +22 -19
- package/src/backend/routes/activitypub/inbox-types.ts +14 -2
- package/src/backend/routes/activitypub/inbox.ts +81 -105
- package/src/backend/routes/activitypub/outbox.ts +0 -0
- package/src/backend/routes/activitypub.ts +6 -5
- package/src/backend/routes/actors-helpers.ts +34 -8
- package/src/backend/routes/actors.ts +328 -164
- package/src/backend/routes/auth-helpers.ts +57 -9
- package/src/backend/routes/auth.ts +10 -2
- package/src/backend/routes/communities/membership-invites.ts +4 -1
- package/src/backend/routes/communities/membership-members.ts +201 -73
- package/src/backend/routes/communities/membership-requests.ts +141 -76
- package/src/backend/routes/communities/membership-shared.ts +228 -21
- package/src/backend/routes/communities/messages.ts +9 -2
- package/src/backend/routes/communities/routes.ts +48 -13
- package/src/backend/routes/dm/contacts.ts +29 -41
- package/src/backend/routes/dm/conversations-helpers.ts +9 -1
- package/src/backend/routes/dm/messages.ts +36 -42
- package/src/backend/routes/dm/read-archive.ts +4 -2
- package/src/backend/routes/dm/requests.ts +62 -54
- package/src/backend/routes/follow-helpers.ts +200 -60
- package/src/backend/routes/follow.ts +146 -140
- package/src/backend/routes/media.ts +20 -94
- package/src/backend/routes/moderation.ts +72 -4
- package/src/backend/routes/notes.ts +3 -4
- package/src/backend/routes/notifications.ts +209 -108
- package/src/backend/routes/posts/delete-cascade.ts +253 -89
- package/src/backend/routes/posts/federation.ts +373 -0
- package/src/backend/routes/posts/interactions.ts +160 -184
- package/src/backend/routes/posts/like-mutation.ts +240 -0
- package/src/backend/routes/posts/post-helpers.ts +112 -162
- package/src/backend/routes/posts/queries.ts +150 -54
- package/src/backend/routes/posts/routes.ts +169 -329
- package/src/backend/routes/posts/transformers.ts +61 -6
- package/src/backend/routes/recommendations.ts +37 -44
- package/src/backend/routes/rtc/index.ts +26 -6
- package/src/backend/routes/search.ts +39 -55
- package/src/backend/routes/stories/interactions.ts +22 -6
- package/src/backend/routes/stories/query-helpers.ts +28 -41
- package/src/backend/routes/stories/routes.ts +125 -108
- package/src/backend/routes/takos-tools/dm.ts +17 -17
- package/src/backend/routes/takos-tools/posts.ts +189 -106
- package/src/backend/routes/takos-tools/search.ts +13 -4
- package/src/backend/routes/takos-tools/timeline.ts +35 -27
- package/src/backend/routes/takos-tools-response.ts +6 -2
- package/src/backend/routes/timeline.ts +5 -5
- package/src/backend/runtime/call-signaling-do.ts +35 -4
- package/src/backend/runtime/one-time-ticket.ts +116 -0
- package/src/backend/runtime/realtime-stream-do.ts +5 -61
- package/src/backend/runtime/signaling-hub.ts +36 -3
- package/src/backend/server.ts +95 -80
- package/src/db/d1-write.ts +67 -43
- package/src/db/schema/federation.ts +42 -1
- package/src/db/schema/messaging.ts +110 -2
- package/src/db/schema.ts +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { and, inArray, notExists, or, type SQL } from "drizzle-orm";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
activities,
|
|
5
|
+
deliveryFanouts,
|
|
6
|
+
deliveryQueue,
|
|
7
|
+
deliveryResolutions,
|
|
8
|
+
inboundActivityClaims,
|
|
9
|
+
inbox,
|
|
10
|
+
notificationArchived,
|
|
11
|
+
notificationPushJobs,
|
|
12
|
+
runBatch,
|
|
13
|
+
type Database,
|
|
14
|
+
type D1Statement,
|
|
15
|
+
} from "../../db/index.ts";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A write-time fence for deleting an Activity actor's signing material.
|
|
19
|
+
*
|
|
20
|
+
* Preliminary reads are not sufficient: a fanout/resolution worker can
|
|
21
|
+
* materialize an endpoint after the reaper checked delivery_queue and then
|
|
22
|
+
* mark its own outbox terminal before the reaper checks that table. Reuse this
|
|
23
|
+
* predicate on EVERY statement in the atomic cleanup batch so newly active
|
|
24
|
+
* work stops the remaining deletes before the Activity or signer disappears.
|
|
25
|
+
*/
|
|
26
|
+
export function activityDeliveryDrainedGuard(
|
|
27
|
+
db: Database,
|
|
28
|
+
activityWhere: SQL,
|
|
29
|
+
): SQL {
|
|
30
|
+
const targetActivityIds = () =>
|
|
31
|
+
db.select({ apId: activities.apId }).from(activities).where(activityWhere);
|
|
32
|
+
|
|
33
|
+
return and(
|
|
34
|
+
notExists(
|
|
35
|
+
db
|
|
36
|
+
.select({ id: deliveryQueue.id })
|
|
37
|
+
.from(deliveryQueue)
|
|
38
|
+
.where(
|
|
39
|
+
and(
|
|
40
|
+
inArray(deliveryQueue.activityApId, targetActivityIds()),
|
|
41
|
+
inArray(deliveryQueue.status, [
|
|
42
|
+
"pending",
|
|
43
|
+
"processing",
|
|
44
|
+
"retry_wait",
|
|
45
|
+
]),
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
notExists(
|
|
50
|
+
db
|
|
51
|
+
.select({ id: deliveryResolutions.id })
|
|
52
|
+
.from(deliveryResolutions)
|
|
53
|
+
.where(
|
|
54
|
+
and(
|
|
55
|
+
inArray(deliveryResolutions.activityApId, targetActivityIds()),
|
|
56
|
+
inArray(deliveryResolutions.status, [
|
|
57
|
+
"pending",
|
|
58
|
+
"queued",
|
|
59
|
+
"processing",
|
|
60
|
+
"retry_wait",
|
|
61
|
+
]),
|
|
62
|
+
),
|
|
63
|
+
),
|
|
64
|
+
),
|
|
65
|
+
notExists(
|
|
66
|
+
db
|
|
67
|
+
.select({ id: deliveryFanouts.id })
|
|
68
|
+
.from(deliveryFanouts)
|
|
69
|
+
.where(
|
|
70
|
+
and(
|
|
71
|
+
or(
|
|
72
|
+
inArray(deliveryFanouts.activityApId, targetActivityIds()),
|
|
73
|
+
inArray(
|
|
74
|
+
deliveryFanouts.announceActivityApId,
|
|
75
|
+
targetActivityIds(),
|
|
76
|
+
),
|
|
77
|
+
),
|
|
78
|
+
inArray(deliveryFanouts.status, ["pending", "published"]),
|
|
79
|
+
),
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
)!;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Build the atomic cleanup unit for every durable projection of matching
|
|
87
|
+
* activities while retaining the activity ledger rows themselves.
|
|
88
|
+
*
|
|
89
|
+
* The inbox FK/trigger only removes push jobs in selected non-terminal states;
|
|
90
|
+
* delivery work, archived markers, in-flight/terminal push jobs, and inbound
|
|
91
|
+
* claim leases otherwise survive. This projection-only form is also used when
|
|
92
|
+
* an object is deleted but its historical Activity must remain available.
|
|
93
|
+
*/
|
|
94
|
+
export function activityProjectionDeleteStatements(
|
|
95
|
+
db: Database,
|
|
96
|
+
activityWhere: SQL,
|
|
97
|
+
options: { readonly guard?: SQL } = {},
|
|
98
|
+
): readonly [D1Statement, ...D1Statement[]] {
|
|
99
|
+
const targetActivityIds = () =>
|
|
100
|
+
db.select({ apId: activities.apId }).from(activities).where(activityWhere);
|
|
101
|
+
const guarded = (where: SQL): SQL =>
|
|
102
|
+
options.guard ? and(where, options.guard)! : where;
|
|
103
|
+
|
|
104
|
+
return [
|
|
105
|
+
db
|
|
106
|
+
.delete(notificationPushJobs)
|
|
107
|
+
.where(
|
|
108
|
+
guarded(
|
|
109
|
+
inArray(notificationPushJobs.activityApId, targetActivityIds()),
|
|
110
|
+
),
|
|
111
|
+
) as D1Statement,
|
|
112
|
+
db
|
|
113
|
+
.delete(notificationArchived)
|
|
114
|
+
.where(
|
|
115
|
+
guarded(
|
|
116
|
+
inArray(notificationArchived.activityApId, targetActivityIds()),
|
|
117
|
+
),
|
|
118
|
+
) as D1Statement,
|
|
119
|
+
db
|
|
120
|
+
.delete(inboundActivityClaims)
|
|
121
|
+
.where(
|
|
122
|
+
guarded(
|
|
123
|
+
inArray(inboundActivityClaims.activityApId, targetActivityIds()),
|
|
124
|
+
),
|
|
125
|
+
) as D1Statement,
|
|
126
|
+
db
|
|
127
|
+
.delete(deliveryQueue)
|
|
128
|
+
.where(
|
|
129
|
+
guarded(inArray(deliveryQueue.activityApId, targetActivityIds())),
|
|
130
|
+
) as D1Statement,
|
|
131
|
+
db
|
|
132
|
+
.delete(deliveryResolutions)
|
|
133
|
+
.where(
|
|
134
|
+
guarded(inArray(deliveryResolutions.activityApId, targetActivityIds())),
|
|
135
|
+
) as D1Statement,
|
|
136
|
+
db
|
|
137
|
+
.delete(deliveryFanouts)
|
|
138
|
+
.where(
|
|
139
|
+
guarded(inArray(deliveryFanouts.activityApId, targetActivityIds())),
|
|
140
|
+
) as D1Statement,
|
|
141
|
+
// Keep the secondary Announce reference in its own statement. Combining
|
|
142
|
+
// both predicates with OR duplicates every bound value in D1, so a normal
|
|
143
|
+
// 90-id cascade would exceed the platform's 100-parameter ceiling.
|
|
144
|
+
db
|
|
145
|
+
.delete(deliveryFanouts)
|
|
146
|
+
.where(
|
|
147
|
+
guarded(
|
|
148
|
+
inArray(deliveryFanouts.announceActivityApId, targetActivityIds()),
|
|
149
|
+
),
|
|
150
|
+
) as D1Statement,
|
|
151
|
+
db
|
|
152
|
+
.delete(inbox)
|
|
153
|
+
.where(
|
|
154
|
+
guarded(inArray(inbox.activityApId, targetActivityIds())),
|
|
155
|
+
) as D1Statement,
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Build one atomic hard-delete unit for activities and every durable
|
|
161
|
+
* projection keyed by their AP IDs.
|
|
162
|
+
*
|
|
163
|
+
* Keep the activities rows until the final statement so every preceding
|
|
164
|
+
* subquery sees the same target set. Semantic edges (`likes`, `announces`,
|
|
165
|
+
* `follows`) are intentionally caller-owned because removing them also
|
|
166
|
+
* requires domain-specific counter repair.
|
|
167
|
+
*/
|
|
168
|
+
export function activityDeleteCascadeStatements(
|
|
169
|
+
db: Database,
|
|
170
|
+
activityWhere: SQL,
|
|
171
|
+
options: { readonly guard?: SQL } = {},
|
|
172
|
+
): readonly [D1Statement, ...D1Statement[]] {
|
|
173
|
+
return [
|
|
174
|
+
...activityProjectionDeleteStatements(db, activityWhere, options),
|
|
175
|
+
db
|
|
176
|
+
.delete(activities)
|
|
177
|
+
.where(
|
|
178
|
+
options.guard ? and(activityWhere, options.guard) : activityWhere,
|
|
179
|
+
) as D1Statement,
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Atomically hard-delete matching activities and all of their projections.
|
|
185
|
+
* A failed final activity delete rolls the preceding cleanup back, so the
|
|
186
|
+
* caller can retry the same idempotent predicate without partial state.
|
|
187
|
+
*/
|
|
188
|
+
export async function deleteActivitiesCascade(
|
|
189
|
+
db: Database,
|
|
190
|
+
activityWhere: SQL,
|
|
191
|
+
): Promise<void> {
|
|
192
|
+
await runBatch(db, activityDeleteCascadeStatements(db, activityWhere));
|
|
193
|
+
}
|