@tearleads/client-sdk 0.1.44 → 0.1.45
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/data/persistence/container-contents/containerContentsPersistence.js +2 -3
- package/data/persistence/container-contents/containerContentsPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerCreateIntentSettlement.js +16 -16
- package/data/persistence/container-contents/containerCreateIntentSettlement.js.map +1 -1
- package/data/persistence/container-contents/containerDeletionPersistence.js +5 -11
- package/data/persistence/container-contents/containerDeletionPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerDocumentReassignment.js +13 -13
- package/data/persistence/container-contents/containerDocumentReassignment.js.map +1 -1
- package/data/persistence/container-contents/containerHydrationPersistence.js +7 -4
- package/data/persistence/container-contents/containerHydrationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerIntentPersistence.js +43 -42
- package/data/persistence/container-contents/containerIntentPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js +15 -20
- package/data/persistence/container-contents/containerMetadataMutationPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMoveAbandonPersistence.js +1 -6
- package/data/persistence/container-contents/containerMoveAbandonPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerMoveIntentRows.js +9 -8
- package/data/persistence/container-contents/containerMoveIntentRows.js.map +1 -1
- package/data/persistence/container-contents/containerReconcilePersistence.js +4 -8
- package/data/persistence/container-contents/containerReconcilePersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRecoveryPersistence.js +20 -19
- package/data/persistence/container-contents/containerRecoveryPersistence.js.map +1 -1
- package/data/persistence/container-contents/containerRemovalWork.js +10 -10
- package/data/persistence/container-contents/containerRemovalWork.js.map +1 -1
- package/data/persistence/container-contents/containerStructuralRepair.js +21 -44
- package/data/persistence/container-contents/containerStructuralRepair.js.map +1 -1
- package/data/persistence/container-contents/documentLinkRemovalRepair.js +12 -11
- package/data/persistence/container-contents/documentLinkRemovalRepair.js.map +1 -1
- package/data/persistence/container-contents/documentMoveIntentPersistence.js +53 -28
- package/data/persistence/container-contents/documentMoveIntentPersistence.js.map +1 -1
- package/data/persistence/container-contents/documentPlacementIntentEnqueue.js +9 -8
- package/data/persistence/container-contents/documentPlacementIntentEnqueue.js.map +1 -1
- package/data/persistence/container-contents/documentPurgePlacement.js +6 -6
- package/data/persistence/container-contents/documentPurgePlacement.js.map +1 -1
- package/data/persistence/container-contents/dormantContainerMetadata.js +1 -5
- package/data/persistence/container-contents/dormantContainerMetadata.js.map +1 -1
- package/data/persistence/container-contents/pendingContainerCreate.js +5 -5
- package/data/persistence/container-contents/pendingContainerCreate.js.map +1 -1
- package/data/persistence/containers/containerPersistence.js +10 -27
- package/data/persistence/containers/containerPersistence.js.map +1 -1
- package/data/persistence/containers/documentContainerProjectionPersistence.js +2 -2
- package/data/persistence/containers/documentContainerProjectionPersistence.js.map +1 -1
- package/data/persistence/containers/documentPlacement.js +10 -10
- package/data/persistence/containers/documentPlacement.js.map +1 -1
- package/data/persistence/documents/internal/discardDocument.js +5 -5
- package/data/persistence/documents/internal/discardDocument.js.map +1 -1
- package/data/persistence/documents/internal/documentDeletionPersistence.js +7 -9
- package/data/persistence/documents/internal/documentDeletionPersistence.js.map +1 -1
- package/data/persistence/documents/internal/documentMutationPersistence.js +6 -8
- package/data/persistence/documents/internal/documentMutationPersistence.js.map +1 -1
- package/data/persistence/documents/internal/ensureDocumentsSchema.js +2 -2
- package/data/persistence/documents/internal/ensureDocumentsSchema.js.map +1 -1
- package/data/persistence/documents/internal/orphanSideRows.js +3 -22
- package/data/persistence/documents/internal/orphanSideRows.js.map +1 -1
- package/data/persistence/organizations/organizationDataUsagePersistence.js +31 -64
- package/data/persistence/organizations/organizationDataUsagePersistence.js.map +1 -1
- package/data/persistence/organizations/organizationReadModelPurge.js +1 -5
- package/data/persistence/organizations/organizationReadModelPurge.js.map +1 -1
- package/data/persistence/principalCurrentAcknowledgementPersistence.js +24 -17
- package/data/persistence/principalCurrentAcknowledgementPersistence.js.map +1 -1
- package/data/persistence/principalHistoryIncompleteRetention.js +3 -9
- package/data/persistence/principalHistoryIncompleteRetention.js.map +1 -1
- package/data/persistence/principalHistoryStagePersistence.d.ts +3 -9
- package/data/persistence/principalHistoryStagePersistence.js +15 -25
- package/data/persistence/principalHistoryStagePersistence.js.map +1 -1
- package/data/persistence/principalHistoryStageRetention.js +16 -15
- package/data/persistence/principalHistoryStageRetention.js.map +1 -1
- package/data/persistence/principalHistoryUnpublishedRetention.js +6 -13
- package/data/persistence/principalHistoryUnpublishedRetention.js.map +1 -1
- package/data/sqlite/containerSchema.d.ts +84 -180
- package/data/sqlite/containerSchema.js +14 -23
- package/data/sqlite/containerSchema.js.map +1 -1
- package/data/sqlite/documentPlacementIntentSchema.js +3 -50
- package/data/sqlite/documentPlacementIntentSchema.js.map +1 -1
- package/data/sqlite/documentSyncFailurePersistence.d.ts +16 -6
- package/data/sqlite/documentSyncFailurePersistence.js +44 -54
- package/data/sqlite/documentSyncFailurePersistence.js.map +1 -1
- package/data/sqlite/{documentPlacementIntentSchema.d.ts → localIntentSchema.d.ts} +162 -88
- package/data/sqlite/localIntentSchema.js +90 -0
- package/data/sqlite/localIntentSchema.js.map +1 -0
- package/data/sqlite/organizationDataUsageSchema.js +11 -17
- package/data/sqlite/organizationDataUsageSchema.js.map +1 -1
- package/data/sqlite/principalHistoryRetentionSchema.js +0 -15
- package/data/sqlite/principalHistoryRetentionSchema.js.map +1 -1
- package/data/sqlite/principalHistoryStageSchema.d.ts +44 -2
- package/data/sqlite/principalHistoryStageSchema.js +14 -2
- package/data/sqlite/principalHistoryStageSchema.js.map +1 -1
- package/data/sqlite/schema.d.ts +947 -2112
- package/data/sqlite/schema.js +26 -134
- package/data/sqlite/schema.js.map +1 -1
- package/package.json +1 -1
- package/workflows/container-contents/documentPriming.js +6 -10
- package/workflows/container-contents/documentPriming.js.map +1 -1
- package/workflows/container-contents/documentQueries/sql.js +11 -10
- package/workflows/container-contents/documentQueries/sql.js.map +1 -1
- package/workflows/container-contents/documentQueries.js +2 -2
- package/workflows/container-contents/documentQueries.js.map +1 -1
- package/workflows/container-contents/pendingDownloads.js +2 -5
- package/workflows/container-contents/pendingDownloads.js.map +1 -1
- package/workflows/container-contents/pendingWrites/deferredTails.js +3 -11
- package/workflows/container-contents/pendingWrites/deferredTails.js.map +1 -1
- package/workflows/container-contents/pendingWrites/sources.js +56 -80
- package/workflows/container-contents/pendingWrites/sources.js.map +1 -1
- package/workflows/container-contents/pendingWrites.js +6 -4
- package/workflows/container-contents/pendingWrites.js.map +1 -1
- package/workflows/container-contents/remoteContainerState.js +2 -1
- package/workflows/container-contents/remoteContainerState.js.map +1 -1
- package/workflows/sync/remoteReset.js +16 -23
- package/workflows/sync/remoteReset.js.map +1 -1
- package/workflows/sync/remoteResetPrincipalScope.js +1 -2
- package/workflows/sync/remoteResetPrincipalScope.js.map +1 -1
- package/workflows/sync/remoteResetScope.js +15 -8
- package/workflows/sync/remoteResetScope.js.map +1 -1
|
@@ -1,9 +1,7 @@
|
|
|
1
|
+
import { LOCAL_INTENT_LANES } from "../../../data/sqlite/schema.js";
|
|
1
2
|
import { getContainerDisplayNameSql, getContainerOrganizationAttributionSql, } from "../documentQueries/sql.js";
|
|
2
3
|
import { readNumber, readString } from "./rowReaders.js";
|
|
3
|
-
const CONTAINER_DISPLAY_NAME_SQL = getContainerDisplayNameSql(
|
|
4
|
-
containerAlias: "container",
|
|
5
|
-
projectionAlias: "container_projection",
|
|
6
|
-
});
|
|
4
|
+
const CONTAINER_DISPLAY_NAME_SQL = getContainerDisplayNameSql("container");
|
|
7
5
|
const DOCUMENT_ORGANIZATION_SQL = getContainerOrganizationAttributionSql({
|
|
8
6
|
containerAlias: "container",
|
|
9
7
|
projectionAlias: "projection",
|
|
@@ -35,8 +33,8 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
35
33
|
updates.updated_at AS updated_at,
|
|
36
34
|
NULL AS target_container_id,
|
|
37
35
|
'pending' AS operation_status,
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
stored.sync_failure_message AS last_error,
|
|
37
|
+
stored.sync_failure_attempted_at AS last_attempted_at,
|
|
40
38
|
'always' AS inclusion
|
|
41
39
|
FROM pending_update_groups updates
|
|
42
40
|
LEFT JOIN documents stored
|
|
@@ -46,9 +44,6 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
46
44
|
ON projection.local_id = updates.local_id
|
|
47
45
|
LEFT JOIN containers container
|
|
48
46
|
ON container.id = projection.container_id
|
|
49
|
-
LEFT JOIN document_sync_failures failure
|
|
50
|
-
ON failure.app_kind = 'documents'
|
|
51
|
-
AND failure.local_id = updates.local_id
|
|
52
47
|
WHERE updates.app_kind = 'documents'
|
|
53
48
|
|
|
54
49
|
UNION ALL
|
|
@@ -62,7 +57,7 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
62
57
|
SELECT
|
|
63
58
|
'document' AS object_kind,
|
|
64
59
|
NULL AS namespace,
|
|
65
|
-
|
|
60
|
+
stored.local_id AS local_id,
|
|
66
61
|
stored.document_id AS remote_id,
|
|
67
62
|
projection.title AS name,
|
|
68
63
|
projection.container_id AS container_id,
|
|
@@ -70,22 +65,20 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
70
65
|
'revalidation' AS operation_kind,
|
|
71
66
|
0 AS operation_count,
|
|
72
67
|
0 AS byte_length,
|
|
73
|
-
|
|
74
|
-
|
|
68
|
+
stored.sync_failure_attempted_at AS created_at,
|
|
69
|
+
stored.sync_failure_attempted_at AS updated_at,
|
|
75
70
|
NULL AS target_container_id,
|
|
76
71
|
'pending' AS operation_status,
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
stored.sync_failure_message AS last_error,
|
|
73
|
+
stored.sync_failure_attempted_at AS last_attempted_at,
|
|
79
74
|
'unless-item-covered' AS inclusion
|
|
80
|
-
FROM
|
|
81
|
-
LEFT JOIN documents stored
|
|
82
|
-
ON stored.app_kind = failure.app_kind
|
|
83
|
-
AND stored.local_id = failure.local_id
|
|
75
|
+
FROM documents stored
|
|
84
76
|
LEFT JOIN document_projection projection
|
|
85
|
-
ON projection.local_id =
|
|
77
|
+
ON projection.local_id = stored.local_id
|
|
86
78
|
LEFT JOIN containers container
|
|
87
79
|
ON container.id = projection.container_id
|
|
88
|
-
WHERE
|
|
80
|
+
WHERE stored.app_kind = 'documents'
|
|
81
|
+
AND stored.sync_failure_message IS NOT NULL
|
|
89
82
|
|
|
90
83
|
UNION ALL
|
|
91
84
|
|
|
@@ -104,16 +97,14 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
104
97
|
updates.updated_at AS updated_at,
|
|
105
98
|
NULL AS target_container_id,
|
|
106
99
|
'pending' AS operation_status,
|
|
107
|
-
|
|
108
|
-
|
|
100
|
+
metadata.sync_failure_message AS last_error,
|
|
101
|
+
metadata.sync_failure_attempted_at AS last_attempted_at,
|
|
109
102
|
'always' AS inclusion
|
|
110
103
|
FROM pending_update_groups updates
|
|
111
104
|
LEFT JOIN containers container ON container.id = updates.local_id
|
|
112
|
-
LEFT JOIN
|
|
113
|
-
ON
|
|
114
|
-
|
|
115
|
-
ON failure.app_kind = 'container-metadata'
|
|
116
|
-
AND failure.local_id = updates.local_id
|
|
105
|
+
LEFT JOIN documents metadata
|
|
106
|
+
ON metadata.app_kind = 'container-metadata'
|
|
107
|
+
AND metadata.local_id = updates.local_id
|
|
117
108
|
WHERE updates.app_kind = 'container-metadata'
|
|
118
109
|
-- Dormant retained metadata (container tombstoned access_revoked, row 4)
|
|
119
110
|
-- has no containers row; keep it unsurfaced until rehydration re-attaches
|
|
@@ -128,7 +119,7 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
128
119
|
SELECT
|
|
129
120
|
'container' AS object_kind,
|
|
130
121
|
NULL AS namespace,
|
|
131
|
-
|
|
122
|
+
metadata.local_id AS local_id,
|
|
132
123
|
CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,
|
|
133
124
|
${CONTAINER_DISPLAY_NAME_SQL} AS name,
|
|
134
125
|
container.id AS container_id,
|
|
@@ -136,18 +127,17 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
136
127
|
'revalidation' AS operation_kind,
|
|
137
128
|
0 AS operation_count,
|
|
138
129
|
0 AS byte_length,
|
|
139
|
-
|
|
140
|
-
|
|
130
|
+
metadata.sync_failure_attempted_at AS created_at,
|
|
131
|
+
metadata.sync_failure_attempted_at AS updated_at,
|
|
141
132
|
NULL AS target_container_id,
|
|
142
133
|
'pending' AS operation_status,
|
|
143
|
-
|
|
144
|
-
|
|
134
|
+
metadata.sync_failure_message AS last_error,
|
|
135
|
+
metadata.sync_failure_attempted_at AS last_attempted_at,
|
|
145
136
|
'unless-item-covered' AS inclusion
|
|
146
|
-
FROM
|
|
147
|
-
JOIN containers container ON container.id =
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
WHERE failure.app_kind = 'container-metadata'
|
|
137
|
+
FROM documents metadata
|
|
138
|
+
JOIN containers container ON container.id = metadata.local_id
|
|
139
|
+
WHERE metadata.app_kind = 'container-metadata'
|
|
140
|
+
AND metadata.sync_failure_message IS NOT NULL
|
|
151
141
|
|
|
152
142
|
UNION ALL
|
|
153
143
|
|
|
@@ -166,16 +156,13 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
166
156
|
updates.updated_at AS updated_at,
|
|
167
157
|
NULL AS target_container_id,
|
|
168
158
|
'pending' AS operation_status,
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
stored.sync_failure_message AS last_error,
|
|
160
|
+
stored.sync_failure_attempted_at AS last_attempted_at,
|
|
171
161
|
'always' AS inclusion
|
|
172
162
|
FROM pending_update_groups updates
|
|
173
163
|
LEFT JOIN documents stored
|
|
174
164
|
ON stored.app_kind = updates.app_kind
|
|
175
165
|
AND stored.local_id = updates.local_id
|
|
176
|
-
LEFT JOIN document_sync_failures failure
|
|
177
|
-
ON failure.app_kind = updates.app_kind
|
|
178
|
-
AND failure.local_id = updates.local_id
|
|
179
166
|
WHERE updates.app_kind NOT IN ('documents', 'container-metadata')
|
|
180
167
|
|
|
181
168
|
UNION ALL
|
|
@@ -195,8 +182,8 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
195
182
|
MAX(attachment.created_at) AS updated_at,
|
|
196
183
|
NULL AS target_container_id,
|
|
197
184
|
'pending' AS operation_status,
|
|
198
|
-
|
|
199
|
-
|
|
185
|
+
stored.sync_failure_message AS last_error,
|
|
186
|
+
stored.sync_failure_attempted_at AS last_attempted_at,
|
|
200
187
|
'always' AS inclusion
|
|
201
188
|
FROM document_pending_attachments attachment
|
|
202
189
|
LEFT JOIN documents stored
|
|
@@ -206,9 +193,6 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
206
193
|
ON projection.local_id = attachment.local_id
|
|
207
194
|
LEFT JOIN containers container
|
|
208
195
|
ON container.id = projection.container_id
|
|
209
|
-
LEFT JOIN document_sync_failures failure
|
|
210
|
-
ON failure.app_kind = 'documents'
|
|
211
|
-
AND failure.local_id = attachment.local_id
|
|
212
196
|
GROUP BY attachment.local_id
|
|
213
197
|
|
|
214
198
|
UNION ALL
|
|
@@ -216,26 +200,25 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
216
200
|
SELECT
|
|
217
201
|
'container' AS object_kind,
|
|
218
202
|
NULL AS namespace,
|
|
219
|
-
intent.
|
|
203
|
+
intent.subject_id AS local_id,
|
|
220
204
|
COALESCE(intent.remote_container_id, CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END) AS remote_id,
|
|
221
205
|
${CONTAINER_DISPLAY_NAME_SQL} AS name,
|
|
222
|
-
intent.
|
|
206
|
+
intent.subject_id AS container_id,
|
|
223
207
|
NULLIF(container.organization_id, '') AS organization_id,
|
|
224
208
|
'create' AS operation_kind,
|
|
225
209
|
1 AS operation_count,
|
|
226
210
|
0 AS byte_length,
|
|
227
211
|
intent.created_at AS created_at,
|
|
228
212
|
intent.updated_at AS updated_at,
|
|
229
|
-
intent.
|
|
213
|
+
intent.target_container_id AS target_container_id,
|
|
230
214
|
'pending' AS operation_status,
|
|
231
215
|
intent.last_error AS last_error,
|
|
232
216
|
intent.last_attempted_at AS last_attempted_at,
|
|
233
217
|
'always' AS inclusion
|
|
234
|
-
FROM
|
|
235
|
-
LEFT JOIN containers container ON container.id = intent.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
WHERE intent.intent_type = 'container.create'
|
|
218
|
+
FROM local_intents intent
|
|
219
|
+
LEFT JOIN containers container ON container.id = intent.subject_id
|
|
220
|
+
WHERE intent.lane = '${LOCAL_INTENT_LANES.containerCreate}'
|
|
221
|
+
AND intent.intent_type = 'container.create'
|
|
239
222
|
AND intent.sync_status = 'pending'
|
|
240
223
|
|
|
241
224
|
UNION ALL
|
|
@@ -243,26 +226,25 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
243
226
|
SELECT
|
|
244
227
|
'container' AS object_kind,
|
|
245
228
|
NULL AS namespace,
|
|
246
|
-
intent.
|
|
229
|
+
intent.subject_id AS local_id,
|
|
247
230
|
CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,
|
|
248
231
|
${CONTAINER_DISPLAY_NAME_SQL} AS name,
|
|
249
|
-
intent.
|
|
232
|
+
intent.subject_id AS container_id,
|
|
250
233
|
NULLIF(container.organization_id, '') AS organization_id,
|
|
251
234
|
'move' AS operation_kind,
|
|
252
235
|
1 AS operation_count,
|
|
253
236
|
0 AS byte_length,
|
|
254
237
|
intent.created_at AS created_at,
|
|
255
238
|
intent.updated_at AS updated_at,
|
|
256
|
-
intent.
|
|
239
|
+
intent.target_container_id AS target_container_id,
|
|
257
240
|
CASE WHEN intent.sync_status = 'blocked' THEN 'blocked' ELSE 'pending' END AS operation_status,
|
|
258
241
|
intent.last_error AS last_error,
|
|
259
242
|
intent.last_attempted_at AS last_attempted_at,
|
|
260
243
|
'always' AS inclusion
|
|
261
|
-
FROM
|
|
262
|
-
LEFT JOIN containers container ON container.id = intent.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
WHERE intent.intent_type = 'container.move'
|
|
244
|
+
FROM local_intents intent
|
|
245
|
+
LEFT JOIN containers container ON container.id = intent.subject_id
|
|
246
|
+
WHERE intent.lane = '${LOCAL_INTENT_LANES.containerMove}'
|
|
247
|
+
AND intent.intent_type = 'container.move'
|
|
266
248
|
|
|
267
249
|
UNION ALL
|
|
268
250
|
|
|
@@ -270,7 +252,7 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
270
252
|
'document' AS object_kind,
|
|
271
253
|
NULL AS namespace,
|
|
272
254
|
intent.local_id AS local_id,
|
|
273
|
-
intent.
|
|
255
|
+
intent.subject_id AS remote_id,
|
|
274
256
|
projection.title AS name,
|
|
275
257
|
COALESCE(projection.container_id, intent.target_container_id) AS container_id,
|
|
276
258
|
${DOCUMENT_ORGANIZATION_SQL} AS organization_id,
|
|
@@ -281,18 +263,19 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
281
263
|
intent.updated_at AS updated_at,
|
|
282
264
|
intent.target_container_id AS target_container_id,
|
|
283
265
|
CASE WHEN intent.sync_status IN ('blocked', 'unavailable') THEN 'blocked' ELSE 'pending' END AS operation_status,
|
|
284
|
-
COALESCE(NULLIF(intent.last_error, ''),
|
|
285
|
-
COALESCE(intent.last_attempted_at,
|
|
266
|
+
COALESCE(NULLIF(intent.last_error, ''), stored.sync_failure_message) AS last_error,
|
|
267
|
+
COALESCE(intent.last_attempted_at, stored.sync_failure_attempted_at) AS last_attempted_at,
|
|
286
268
|
'always' AS inclusion
|
|
287
|
-
FROM
|
|
269
|
+
FROM local_intents intent
|
|
270
|
+
LEFT JOIN documents stored
|
|
271
|
+
ON stored.app_kind = 'documents'
|
|
272
|
+
AND stored.local_id = intent.local_id
|
|
288
273
|
LEFT JOIN document_projection projection
|
|
289
274
|
ON projection.local_id = intent.local_id
|
|
290
275
|
LEFT JOIN containers container
|
|
291
276
|
ON container.id = COALESCE(projection.container_id, intent.target_container_id)
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
AND failure.local_id = intent.local_id
|
|
295
|
-
WHERE intent.intent_type IN ('document.move', 'document.link')
|
|
277
|
+
WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'
|
|
278
|
+
AND intent.intent_type IN ('document.move', 'document.link')
|
|
296
279
|
|
|
297
280
|
UNION ALL
|
|
298
281
|
|
|
@@ -311,17 +294,14 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
311
294
|
stored.updated_at AS updated_at,
|
|
312
295
|
projection.container_id AS target_container_id,
|
|
313
296
|
'pending' AS operation_status,
|
|
314
|
-
|
|
315
|
-
|
|
297
|
+
stored.sync_failure_message AS last_error,
|
|
298
|
+
stored.sync_failure_attempted_at AS last_attempted_at,
|
|
316
299
|
'unless-operation-covered' AS inclusion
|
|
317
300
|
FROM documents stored
|
|
318
301
|
LEFT JOIN document_projection projection
|
|
319
302
|
ON projection.local_id = stored.local_id
|
|
320
303
|
LEFT JOIN containers container
|
|
321
304
|
ON container.id = projection.container_id
|
|
322
|
-
LEFT JOIN document_sync_failures failure
|
|
323
|
-
ON failure.app_kind = 'documents'
|
|
324
|
-
AND failure.local_id = stored.local_id
|
|
325
305
|
WHERE stored.app_kind = 'documents'
|
|
326
306
|
AND stored.document_id IS NULL
|
|
327
307
|
|
|
@@ -346,8 +326,6 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
346
326
|
NULL AS last_attempted_at,
|
|
347
327
|
'unless-operation-covered' AS inclusion
|
|
348
328
|
FROM containers container
|
|
349
|
-
LEFT JOIN container_projection
|
|
350
|
-
ON container_projection.container_id = container.id
|
|
351
329
|
LEFT JOIN documents metadata
|
|
352
330
|
ON metadata.app_kind = 'container-metadata'
|
|
353
331
|
AND metadata.local_id = container.id
|
|
@@ -376,8 +354,6 @@ const PENDING_WRITE_SOURCE_SQL = `
|
|
|
376
354
|
NULL AS last_attempted_at,
|
|
377
355
|
'unless-item-covered' AS inclusion
|
|
378
356
|
FROM containers container
|
|
379
|
-
LEFT JOIN container_projection
|
|
380
|
-
ON container_projection.container_id = container.id
|
|
381
357
|
WHERE container.local_updated_at IS NOT NULL
|
|
382
358
|
AND (
|
|
383
359
|
container.server_updated_at IS NULL
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sources.js","sourceRoot":"","sources":["sources.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n getContainerDisplayNameSql,\n getContainerOrganizationAttributionSql,\n} from \"../documentQueries/sql\";\nimport type {\n PendingWriteCandidate,\n PendingWriteCandidateInclusion,\n} from \"./aggregation\";\nimport { readNumber, readString } from \"./rowReaders\";\n\nconst CONTAINER_DISPLAY_NAME_SQL = getContainerDisplayNameSql({\n containerAlias: \"container\",\n projectionAlias: \"container_projection\",\n});\nconst DOCUMENT_ORGANIZATION_SQL = getContainerOrganizationAttributionSql({\n containerAlias: \"container\",\n projectionAlias: \"projection\",\n});\n\nconst PENDING_WRITE_SOURCE_SQL = `\n WITH pending_update_groups AS (\n SELECT\n app_kind,\n local_id,\n COUNT(*) AS operation_count,\n MIN(created_at) AS created_at,\n MAX(created_at) AS updated_at\n FROM document_history_updates\n WHERE update_id IS NOT NULL\n GROUP BY app_kind, local_id\n )\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n updates.local_id AS local_id,\n stored.document_id AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'update' AS operation_kind,\n updates.operation_count AS operation_count,\n 0 AS byte_length,\n updates.created_at AS created_at,\n updates.updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM pending_update_groups updates\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = updates.local_id\n LEFT JOIN document_projection projection\n ON projection.local_id = updates.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = 'documents'\n AND failure.local_id = updates.local_id\n WHERE updates.app_kind = 'documents'\n\n UNION ALL\n\n -- Failure-only surface (edge-case row 13): a refused read-only\n -- revalidation records a durable failure row with NO pending work, so\n -- without this branch the refusal would never reach the queue view. The\n -- 'unless-item-covered' inclusion keeps it out whenever the document\n -- already has real operations — those candidates carry the same failure\n -- message through their own joins.\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n failure.local_id AS local_id,\n stored.document_id AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'revalidation' AS operation_kind,\n 0 AS operation_count,\n 0 AS byte_length,\n failure.attempted_at AS created_at,\n failure.attempted_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'unless-item-covered' AS inclusion\n FROM document_sync_failures failure\n LEFT JOIN documents stored\n ON stored.app_kind = failure.app_kind\n AND stored.local_id = failure.local_id\n LEFT JOIN document_projection projection\n ON projection.local_id = failure.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n WHERE failure.app_kind = 'documents'\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n updates.local_id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'update' AS operation_kind,\n updates.operation_count AS operation_count,\n 0 AS byte_length,\n updates.created_at AS created_at,\n updates.updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM pending_update_groups updates\n LEFT JOIN containers container ON container.id = updates.local_id\n LEFT JOIN container_projection\n ON container_projection.container_id = updates.local_id\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = 'container-metadata'\n AND failure.local_id = updates.local_id\n WHERE updates.app_kind = 'container-metadata'\n -- Dormant retained metadata (container tombstoned access_revoked, row 4)\n -- has no containers row; keep it unsurfaced until rehydration re-attaches\n -- the container, or it renders as an anonymous phantom item.\n AND container.id IS NOT NULL\n\n UNION ALL\n\n -- An incoming metadata quarantine can exist without outbound updates. Keep\n -- it visible as a zero-operation diagnostic while the container is live;\n -- dormant retained metadata stays hidden until rehydration re-attaches it.\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n failure.local_id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'revalidation' AS operation_kind,\n 0 AS operation_count,\n 0 AS byte_length,\n failure.attempted_at AS created_at,\n failure.attempted_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'unless-item-covered' AS inclusion\n FROM document_sync_failures failure\n JOIN containers container ON container.id = failure.local_id\n LEFT JOIN container_projection\n ON container_projection.container_id = failure.local_id\n WHERE failure.app_kind = 'container-metadata'\n\n UNION ALL\n\n SELECT\n 'unknown' AS object_kind,\n updates.app_kind AS namespace,\n updates.local_id AS local_id,\n stored.document_id AS remote_id,\n NULL AS name,\n NULL AS container_id,\n NULL AS organization_id,\n 'update' AS operation_kind,\n updates.operation_count AS operation_count,\n 0 AS byte_length,\n updates.created_at AS created_at,\n updates.updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM pending_update_groups updates\n LEFT JOIN documents stored\n ON stored.app_kind = updates.app_kind\n AND stored.local_id = updates.local_id\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = updates.app_kind\n AND failure.local_id = updates.local_id\n WHERE updates.app_kind NOT IN ('documents', 'container-metadata')\n\n UNION ALL\n\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n attachment.local_id AS local_id,\n stored.document_id AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'attachment' AS operation_kind,\n COUNT(*) AS operation_count,\n COALESCE(SUM(attachment.byte_length), 0) AS byte_length,\n MIN(attachment.created_at) AS created_at,\n MAX(attachment.created_at) AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM document_pending_attachments attachment\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = attachment.local_id\n LEFT JOIN document_projection projection\n ON projection.local_id = attachment.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = 'documents'\n AND failure.local_id = attachment.local_id\n GROUP BY attachment.local_id\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n intent.container_id AS local_id,\n COALESCE(intent.remote_container_id, CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END) AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n intent.container_id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'create' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n intent.created_at AS created_at,\n intent.updated_at AS updated_at,\n intent.parent_container_id AS target_container_id,\n 'pending' AS operation_status,\n intent.last_error AS last_error,\n intent.last_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM container_create_intents intent\n LEFT JOIN containers container ON container.id = intent.container_id\n LEFT JOIN container_projection\n ON container_projection.container_id = intent.container_id\n WHERE intent.intent_type = 'container.create'\n AND intent.sync_status = 'pending'\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n intent.container_id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n intent.container_id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'move' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n intent.created_at AS created_at,\n intent.updated_at AS updated_at,\n intent.parent_container_id AS target_container_id,\n CASE WHEN intent.sync_status = 'blocked' THEN 'blocked' ELSE 'pending' END AS operation_status,\n intent.last_error AS last_error,\n intent.last_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM container_move_intents intent\n LEFT JOIN containers container ON container.id = intent.container_id\n LEFT JOIN container_projection\n ON container_projection.container_id = intent.container_id\n WHERE intent.intent_type = 'container.move'\n\n UNION ALL\n\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n intent.local_id AS local_id,\n intent.document_id AS remote_id,\n projection.title AS name,\n COALESCE(projection.container_id, intent.target_container_id) AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'move' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n intent.created_at AS created_at,\n intent.updated_at AS updated_at,\n intent.target_container_id AS target_container_id,\n CASE WHEN intent.sync_status IN ('blocked', 'unavailable') THEN 'blocked' ELSE 'pending' END AS operation_status,\n COALESCE(NULLIF(intent.last_error, ''), failure.message) AS last_error,\n COALESCE(intent.last_attempted_at, failure.attempted_at) AS last_attempted_at,\n 'always' AS inclusion\n FROM document_move_intents intent\n LEFT JOIN document_projection projection\n ON projection.local_id = intent.local_id\n LEFT JOIN containers container\n ON container.id = COALESCE(projection.container_id, intent.target_container_id)\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = 'documents'\n AND failure.local_id = intent.local_id\n WHERE intent.intent_type IN ('document.move', 'document.link')\n\n UNION ALL\n\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n stored.local_id AS local_id,\n NULL AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'create' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n stored.updated_at AS created_at,\n stored.updated_at AS updated_at,\n projection.container_id AS target_container_id,\n 'pending' AS operation_status,\n failure.message AS last_error,\n failure.attempted_at AS last_attempted_at,\n 'unless-operation-covered' AS inclusion\n FROM documents stored\n LEFT JOIN document_projection projection\n ON projection.local_id = stored.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n LEFT JOIN document_sync_failures failure\n ON failure.app_kind = 'documents'\n AND failure.local_id = stored.local_id\n WHERE stored.app_kind = 'documents'\n AND stored.document_id IS NULL\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n container.id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'create' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n container.local_created_at AS created_at,\n container.local_updated_at AS updated_at,\n container.parent_id AS target_container_id,\n 'pending' AS operation_status,\n NULL AS last_error,\n NULL AS last_attempted_at,\n 'unless-operation-covered' AS inclusion\n FROM containers container\n LEFT JOIN container_projection\n ON container_projection.container_id = container.id\n LEFT JOIN documents metadata\n ON metadata.app_kind = 'container-metadata'\n AND metadata.local_id = container.id\n WHERE container.server_created_at IS NULL\n OR container.metadata_document_id IS NULL\n OR metadata.document_id IS NULL\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n container.id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'update' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n NULL AS created_at,\n container.local_updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n NULL AS last_error,\n NULL AS last_attempted_at,\n 'unless-item-covered' AS inclusion\n FROM containers container\n LEFT JOIN container_projection\n ON container_projection.container_id = container.id\n WHERE container.local_updated_at IS NOT NULL\n AND (\n container.server_updated_at IS NULL\n OR container.local_updated_at > container.server_updated_at\n )\n`;\n\nfunction mapPendingWriteSourceRow(\n row: Record<string, unknown>,\n): PendingWriteCandidate | null {\n const localId = readString(row, \"local_id\");\n const operationKind = readString(row, \"operation_kind\");\n if (\n !localId ||\n (operationKind !== \"attachment\" &&\n operationKind !== \"create\" &&\n operationKind !== \"move\" &&\n operationKind !== \"revalidation\" &&\n operationKind !== \"update\")\n ) {\n return null;\n }\n const rawObjectKind = readString(row, \"object_kind\");\n const objectKind =\n rawObjectKind === \"container\" || rawObjectKind === \"document\"\n ? rawObjectKind\n : \"unknown\";\n const rawInclusion = readString(row, \"inclusion\");\n const inclusion: PendingWriteCandidateInclusion =\n rawInclusion === \"unless-item-covered\" ||\n rawInclusion === \"unless-operation-covered\"\n ? rawInclusion\n : \"always\";\n\n return {\n byteLength: readNumber(row, \"byte_length\"),\n containerId: readString(row, \"container_id\"),\n // Diagnostic-only revalidation items carry NO local operations; clamping\n // them to 1 would falsely report pending local data.\n count:\n operationKind === \"revalidation\"\n ? 0\n : Math.max(1, readNumber(row, \"operation_count\")),\n createdAt: readString(row, \"created_at\"),\n inclusion,\n kind: operationKind,\n lastAttemptedAt: readString(row, \"last_attempted_at\"),\n lastError: readString(row, \"last_error\"),\n localId,\n name: readString(row, \"name\"),\n namespace: readString(row, \"namespace\"),\n objectKind,\n organizationId: readString(row, \"organization_id\"),\n remoteId: readString(row, \"remote_id\"),\n status:\n readString(row, \"operation_status\") === \"blocked\" ? \"blocked\" : \"pending\",\n targetContainerId: readString(row, \"target_container_id\"),\n updatedAt: readString(row, \"updated_at\"),\n };\n}\n\nexport async function listPersistedPendingWriteCandidates(\n execSql: ExecSql,\n): Promise<PendingWriteCandidate[]> {\n const rows = await execSql(PENDING_WRITE_SOURCE_SQL);\n return rows.flatMap((row) => {\n const candidate = mapPendingWriteSourceRow(row);\n return candidate ? [candidate] : [];\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["sources.ts"],"names":[],"mappings":"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","sourcesContent":["import { LOCAL_INTENT_LANES } from \"../../../data/sqlite/schema\";\nimport type { ExecSql } from \"../../../data/sqlite/sqlSchema\";\nimport {\n getContainerDisplayNameSql,\n getContainerOrganizationAttributionSql,\n} from \"../documentQueries/sql\";\nimport type {\n PendingWriteCandidate,\n PendingWriteCandidateInclusion,\n} from \"./aggregation\";\nimport { readNumber, readString } from \"./rowReaders\";\n\nconst CONTAINER_DISPLAY_NAME_SQL = getContainerDisplayNameSql(\"container\");\nconst DOCUMENT_ORGANIZATION_SQL = getContainerOrganizationAttributionSql({\n containerAlias: \"container\",\n projectionAlias: \"projection\",\n});\n\nconst PENDING_WRITE_SOURCE_SQL = `\n WITH pending_update_groups AS (\n SELECT\n app_kind,\n local_id,\n COUNT(*) AS operation_count,\n MIN(created_at) AS created_at,\n MAX(created_at) AS updated_at\n FROM document_history_updates\n WHERE update_id IS NOT NULL\n GROUP BY app_kind, local_id\n )\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n updates.local_id AS local_id,\n stored.document_id AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'update' AS operation_kind,\n updates.operation_count AS operation_count,\n 0 AS byte_length,\n updates.created_at AS created_at,\n updates.updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n stored.sync_failure_message AS last_error,\n stored.sync_failure_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM pending_update_groups updates\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = updates.local_id\n LEFT JOIN document_projection projection\n ON projection.local_id = updates.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n WHERE updates.app_kind = 'documents'\n\n UNION ALL\n\n -- Failure-only surface (edge-case row 13): a refused read-only\n -- revalidation records a durable failure row with NO pending work, so\n -- without this branch the refusal would never reach the queue view. The\n -- 'unless-item-covered' inclusion keeps it out whenever the document\n -- already has real operations — those candidates carry the same failure\n -- message through their own joins.\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n stored.local_id AS local_id,\n stored.document_id AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'revalidation' AS operation_kind,\n 0 AS operation_count,\n 0 AS byte_length,\n stored.sync_failure_attempted_at AS created_at,\n stored.sync_failure_attempted_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n stored.sync_failure_message AS last_error,\n stored.sync_failure_attempted_at AS last_attempted_at,\n 'unless-item-covered' AS inclusion\n FROM documents stored\n LEFT JOIN document_projection projection\n ON projection.local_id = stored.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n WHERE stored.app_kind = 'documents'\n AND stored.sync_failure_message IS NOT NULL\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n updates.local_id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'update' AS operation_kind,\n updates.operation_count AS operation_count,\n 0 AS byte_length,\n updates.created_at AS created_at,\n updates.updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n metadata.sync_failure_message AS last_error,\n metadata.sync_failure_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM pending_update_groups updates\n LEFT JOIN containers container ON container.id = updates.local_id\n LEFT JOIN documents metadata\n ON metadata.app_kind = 'container-metadata'\n AND metadata.local_id = updates.local_id\n WHERE updates.app_kind = 'container-metadata'\n -- Dormant retained metadata (container tombstoned access_revoked, row 4)\n -- has no containers row; keep it unsurfaced until rehydration re-attaches\n -- the container, or it renders as an anonymous phantom item.\n AND container.id IS NOT NULL\n\n UNION ALL\n\n -- An incoming metadata quarantine can exist without outbound updates. Keep\n -- it visible as a zero-operation diagnostic while the container is live;\n -- dormant retained metadata stays hidden until rehydration re-attaches it.\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n metadata.local_id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'revalidation' AS operation_kind,\n 0 AS operation_count,\n 0 AS byte_length,\n metadata.sync_failure_attempted_at AS created_at,\n metadata.sync_failure_attempted_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n metadata.sync_failure_message AS last_error,\n metadata.sync_failure_attempted_at AS last_attempted_at,\n 'unless-item-covered' AS inclusion\n FROM documents metadata\n JOIN containers container ON container.id = metadata.local_id\n WHERE metadata.app_kind = 'container-metadata'\n AND metadata.sync_failure_message IS NOT NULL\n\n UNION ALL\n\n SELECT\n 'unknown' AS object_kind,\n updates.app_kind AS namespace,\n updates.local_id AS local_id,\n stored.document_id AS remote_id,\n NULL AS name,\n NULL AS container_id,\n NULL AS organization_id,\n 'update' AS operation_kind,\n updates.operation_count AS operation_count,\n 0 AS byte_length,\n updates.created_at AS created_at,\n updates.updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n stored.sync_failure_message AS last_error,\n stored.sync_failure_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM pending_update_groups updates\n LEFT JOIN documents stored\n ON stored.app_kind = updates.app_kind\n AND stored.local_id = updates.local_id\n WHERE updates.app_kind NOT IN ('documents', 'container-metadata')\n\n UNION ALL\n\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n attachment.local_id AS local_id,\n stored.document_id AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'attachment' AS operation_kind,\n COUNT(*) AS operation_count,\n COALESCE(SUM(attachment.byte_length), 0) AS byte_length,\n MIN(attachment.created_at) AS created_at,\n MAX(attachment.created_at) AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n stored.sync_failure_message AS last_error,\n stored.sync_failure_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM document_pending_attachments attachment\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = attachment.local_id\n LEFT JOIN document_projection projection\n ON projection.local_id = attachment.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n GROUP BY attachment.local_id\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n intent.subject_id AS local_id,\n COALESCE(intent.remote_container_id, CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END) AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n intent.subject_id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'create' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n intent.created_at AS created_at,\n intent.updated_at AS updated_at,\n intent.target_container_id AS target_container_id,\n 'pending' AS operation_status,\n intent.last_error AS last_error,\n intent.last_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM local_intents intent\n LEFT JOIN containers container ON container.id = intent.subject_id\n WHERE intent.lane = '${LOCAL_INTENT_LANES.containerCreate}'\n AND intent.intent_type = 'container.create'\n AND intent.sync_status = 'pending'\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n intent.subject_id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n intent.subject_id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'move' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n intent.created_at AS created_at,\n intent.updated_at AS updated_at,\n intent.target_container_id AS target_container_id,\n CASE WHEN intent.sync_status = 'blocked' THEN 'blocked' ELSE 'pending' END AS operation_status,\n intent.last_error AS last_error,\n intent.last_attempted_at AS last_attempted_at,\n 'always' AS inclusion\n FROM local_intents intent\n LEFT JOIN containers container ON container.id = intent.subject_id\n WHERE intent.lane = '${LOCAL_INTENT_LANES.containerMove}'\n AND intent.intent_type = 'container.move'\n\n UNION ALL\n\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n intent.local_id AS local_id,\n intent.subject_id AS remote_id,\n projection.title AS name,\n COALESCE(projection.container_id, intent.target_container_id) AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'move' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n intent.created_at AS created_at,\n intent.updated_at AS updated_at,\n intent.target_container_id AS target_container_id,\n CASE WHEN intent.sync_status IN ('blocked', 'unavailable') THEN 'blocked' ELSE 'pending' END AS operation_status,\n COALESCE(NULLIF(intent.last_error, ''), stored.sync_failure_message) AS last_error,\n COALESCE(intent.last_attempted_at, stored.sync_failure_attempted_at) AS last_attempted_at,\n 'always' AS inclusion\n FROM local_intents intent\n LEFT JOIN documents stored\n ON stored.app_kind = 'documents'\n AND stored.local_id = intent.local_id\n LEFT JOIN document_projection projection\n ON projection.local_id = intent.local_id\n LEFT JOIN containers container\n ON container.id = COALESCE(projection.container_id, intent.target_container_id)\n WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'\n AND intent.intent_type IN ('document.move', 'document.link')\n\n UNION ALL\n\n SELECT\n 'document' AS object_kind,\n NULL AS namespace,\n stored.local_id AS local_id,\n NULL AS remote_id,\n projection.title AS name,\n projection.container_id AS container_id,\n ${DOCUMENT_ORGANIZATION_SQL} AS organization_id,\n 'create' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n stored.updated_at AS created_at,\n stored.updated_at AS updated_at,\n projection.container_id AS target_container_id,\n 'pending' AS operation_status,\n stored.sync_failure_message AS last_error,\n stored.sync_failure_attempted_at AS last_attempted_at,\n 'unless-operation-covered' AS inclusion\n FROM documents stored\n LEFT JOIN document_projection projection\n ON projection.local_id = stored.local_id\n LEFT JOIN containers container\n ON container.id = projection.container_id\n WHERE stored.app_kind = 'documents'\n AND stored.document_id IS NULL\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n container.id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'create' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n container.local_created_at AS created_at,\n container.local_updated_at AS updated_at,\n container.parent_id AS target_container_id,\n 'pending' AS operation_status,\n NULL AS last_error,\n NULL AS last_attempted_at,\n 'unless-operation-covered' AS inclusion\n FROM containers container\n LEFT JOIN documents metadata\n ON metadata.app_kind = 'container-metadata'\n AND metadata.local_id = container.id\n WHERE container.server_created_at IS NULL\n OR container.metadata_document_id IS NULL\n OR metadata.document_id IS NULL\n\n UNION ALL\n\n SELECT\n 'container' AS object_kind,\n NULL AS namespace,\n container.id AS local_id,\n CASE WHEN container.server_created_at IS NULL THEN NULL ELSE container.id END AS remote_id,\n ${CONTAINER_DISPLAY_NAME_SQL} AS name,\n container.id AS container_id,\n NULLIF(container.organization_id, '') AS organization_id,\n 'update' AS operation_kind,\n 1 AS operation_count,\n 0 AS byte_length,\n NULL AS created_at,\n container.local_updated_at AS updated_at,\n NULL AS target_container_id,\n 'pending' AS operation_status,\n NULL AS last_error,\n NULL AS last_attempted_at,\n 'unless-item-covered' AS inclusion\n FROM containers container\n WHERE container.local_updated_at IS NOT NULL\n AND (\n container.server_updated_at IS NULL\n OR container.local_updated_at > container.server_updated_at\n )\n`;\n\nfunction mapPendingWriteSourceRow(\n row: Record<string, unknown>,\n): PendingWriteCandidate | null {\n const localId = readString(row, \"local_id\");\n const operationKind = readString(row, \"operation_kind\");\n if (\n !localId ||\n (operationKind !== \"attachment\" &&\n operationKind !== \"create\" &&\n operationKind !== \"move\" &&\n operationKind !== \"revalidation\" &&\n operationKind !== \"update\")\n ) {\n return null;\n }\n const rawObjectKind = readString(row, \"object_kind\");\n const objectKind =\n rawObjectKind === \"container\" || rawObjectKind === \"document\"\n ? rawObjectKind\n : \"unknown\";\n const rawInclusion = readString(row, \"inclusion\");\n const inclusion: PendingWriteCandidateInclusion =\n rawInclusion === \"unless-item-covered\" ||\n rawInclusion === \"unless-operation-covered\"\n ? rawInclusion\n : \"always\";\n\n return {\n byteLength: readNumber(row, \"byte_length\"),\n containerId: readString(row, \"container_id\"),\n // Diagnostic-only revalidation items carry NO local operations; clamping\n // them to 1 would falsely report pending local data.\n count:\n operationKind === \"revalidation\"\n ? 0\n : Math.max(1, readNumber(row, \"operation_count\")),\n createdAt: readString(row, \"created_at\"),\n inclusion,\n kind: operationKind,\n lastAttemptedAt: readString(row, \"last_attempted_at\"),\n lastError: readString(row, \"last_error\"),\n localId,\n name: readString(row, \"name\"),\n namespace: readString(row, \"namespace\"),\n objectKind,\n organizationId: readString(row, \"organization_id\"),\n remoteId: readString(row, \"remote_id\"),\n status:\n readString(row, \"operation_status\") === \"blocked\" ? \"blocked\" : \"pending\",\n targetContainerId: readString(row, \"target_container_id\"),\n updatedAt: readString(row, \"updated_at\"),\n };\n}\n\nexport async function listPersistedPendingWriteCandidates(\n execSql: ExecSql,\n): Promise<PendingWriteCandidate[]> {\n const rows = await execSql(PENDING_WRITE_SOURCE_SQL);\n return rows.flatMap((row) => {\n const candidate = mapPendingWriteSourceRow(row);\n return candidate ? [candidate] : [];\n });\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import { sqlDocumentMoveIntentPersistence } from "../../data/persistence/contain
|
|
|
3
3
|
import { sqlDocumentsPersistence } from "../../data/persistence/documents/documentsPersistence.js";
|
|
4
4
|
import { DOCUMENTS_APP_KIND } from "../../data/persistence/documents/internal/constants.js";
|
|
5
5
|
import { clearDocumentSyncFailure, resetDocumentPendingUpdateRekeyBudget, } from "../../data/sqlite/documentPersistence.js";
|
|
6
|
-
import {
|
|
6
|
+
import { documentPlacementIntentTables, documentTables, LOCAL_INTENT_LANES, } from "../../data/sqlite/schema.js";
|
|
7
7
|
import { ensureSqlTables } from "../../data/sqlite/sqlSchema.js";
|
|
8
8
|
import { defaultContainerContentsPersistence } from "./containerPersistence.js";
|
|
9
9
|
import { groupPendingWriteCandidates } from "./pendingWrites/aggregation.js";
|
|
@@ -74,7 +74,7 @@ export async function resetPendingWriteRetryState(execSql, input) {
|
|
|
74
74
|
async function hasQueuedScopeWork(execSql, scope) {
|
|
75
75
|
await ensureSqlTables(execSql, [
|
|
76
76
|
...documentTables,
|
|
77
|
-
...
|
|
77
|
+
...documentPlacementIntentTables,
|
|
78
78
|
]);
|
|
79
79
|
const rows = await execSql(`SELECT 1 AS present
|
|
80
80
|
WHERE EXISTS (
|
|
@@ -87,8 +87,10 @@ async function hasQueuedScopeWork(execSql, scope) {
|
|
|
87
87
|
WHERE attachment.local_id = ?
|
|
88
88
|
)
|
|
89
89
|
OR EXISTS (
|
|
90
|
-
SELECT 1 FROM
|
|
91
|
-
WHERE intent.
|
|
90
|
+
SELECT 1 FROM local_intents intent
|
|
91
|
+
WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'
|
|
92
|
+
AND intent.local_id = ?
|
|
93
|
+
AND intent.intent_type IN ('document.move', 'document.link')
|
|
92
94
|
)
|
|
93
95
|
OR EXISTS (
|
|
94
96
|
SELECT 1 FROM documents stored
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pendingWrites.js","sourceRoot":"","sources":["pendingWrites.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,wEAAwE,CAAC;AACrH,OAAO,EAAE,gCAAgC,EAAE,MAAM,yEAAyE,CAAC;AAC3H,OAAO,EAAE,uBAAuB,EAAE,MAAM,uDAAuD,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,MAAM,qDAAqD,CAAC;AACzF,OAAO,EACL,wBAAwB,EACxB,qCAAqC,GACtC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"pendingWrites.js","sourceRoot":"","sources":["pendingWrites.ts"],"names":[],"mappings":"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","sourcesContent":["import { CONTAINER_METADATA_APP_KIND } from \"../../data/persistence/container-contents/containerContentsPersistence\";\nimport { sqlDocumentMoveIntentPersistence } from \"../../data/persistence/container-contents/documentMoveIntentPersistence\";\nimport { sqlDocumentsPersistence } from \"../../data/persistence/documents/documentsPersistence\";\nimport { DOCUMENTS_APP_KIND } from \"../../data/persistence/documents/internal/constants\";\nimport {\n clearDocumentSyncFailure,\n resetDocumentPendingUpdateRekeyBudget,\n} from \"../../data/sqlite/documentPersistence\";\nimport {\n documentPlacementIntentTables,\n documentTables,\n LOCAL_INTENT_LANES,\n} from \"../../data/sqlite/schema\";\nimport type { ExecSql } from \"../../data/sqlite/sqlSchema\";\nimport { ensureSqlTables } from \"../../data/sqlite/sqlSchema\";\nimport { defaultContainerContentsPersistence } from \"./containerPersistence\";\nimport { groupPendingWriteCandidates } from \"./pendingWrites/aggregation\";\nimport {\n hasDeferredTailScopeWork,\n listDeferredPendingWriteCandidates,\n} from \"./pendingWrites/deferredTails\";\nimport { listPersistedPendingWriteCandidates } from \"./pendingWrites/sources\";\nimport type { PendingWriteQueueItem } from \"./pendingWritesTypes\";\n\nexport type {\n PendingWriteQueueItem,\n PendingWriteQueueItemStatus,\n PendingWriteQueueObjectKind,\n PendingWriteQueueOperation,\n PendingWriteQueueOperationKind,\n PendingWriteQueueOperationStatus,\n} from \"./pendingWritesTypes\";\n\n/**\n * List identity-wide local state that still requires a remote write. The\n * returned diagnostic contains only navigation/display metadata and aggregate\n * counts; serialized updates, local storage keys, and upload crypto stay below\n * the workflow boundary.\n */\nexport async function listPendingWrites(\n execSql: ExecSql,\n): Promise<ReadonlyArray<PendingWriteQueueItem>> {\n await defaultContainerContentsPersistence.ensureSchema(execSql);\n await sqlDocumentsPersistence.ensureSchema(execSql);\n await sqlDocumentMoveIntentPersistence.ensureSchema(execSql);\n\n const [persisted, deferred] = await Promise.all([\n listPersistedPendingWriteCandidates(execSql),\n listDeferredPendingWriteCandidates(execSql),\n ]);\n return groupPendingWriteCandidates([...persisted, ...deferred]);\n}\n\n/**\n * Explicit manual retry for one write-queue item: reset the durable re-key\n * budget for the item's ACTUAL pending-update scope (container metadata and\n * unknown document namespaces re-key through the same recovery path as\n * ordinary documents) and clear the recorded terminal failure — the next\n * pass re-records both if they still hold. The cap protects against a\n * server driving a network-speed re-key loop; a deliberate user retry is\n * the rate-limited signal that conditions have changed (e.g. an outage that\n * burned the budget has healed). The caller re-arms the sync lanes.\n */\nexport async function resetPendingWriteRetryState(\n execSql: ExecSql,\n input: {\n localId: string;\n /** The item's `namespace` — the unrecognized documents.app_kind, if any. */\n namespace: string | null;\n objectKind: PendingWriteQueueItem[\"objectKind\"];\n },\n): Promise<void> {\n const appKind =\n input.objectKind === \"container\"\n ? CONTAINER_METADATA_APP_KIND\n : (input.namespace ??\n (input.objectKind === \"document\" ? DOCUMENTS_APP_KIND : null));\n if (appKind === null) {\n // An unknown object kind with no namespace: there is no scope to reset,\n // and guessing one could clear an unrelated scope sharing the localId.\n return;\n }\n const scope = { appKind, localId: input.localId };\n await resetDocumentPendingUpdateRekeyBudget(execSql, scope);\n if (appKind === DOCUMENTS_APP_KIND) {\n // A deliberate retry is the rate-limited signal that conditions changed:\n // a parked permission-denied move (row 7) replays once, like row 11's\n // re-key budget reset.\n await sqlDocumentMoveIntentPersistence.resetDeniedMoveIntents(execSql, {\n localId: input.localId,\n });\n }\n // Clearing the failure row is part of the re-key budget reset (edge-case\n // row 11) and only makes sense alongside queued work. A failure-only item\n // (a refused revalidation, row 13) has no queued work: its row is the\n // priming ticket that re-drives the store, so it must survive the retry\n // and clear on the next clean pass instead of vanishing with no request.\n if (await hasQueuedScopeWork(execSql, scope)) {\n await clearDocumentSyncFailure(execSql, scope);\n }\n}\n\n/**\n * Whether ANY durable outbound work exists for the scope — CRDT updates,\n * staged attachment uploads, move intents, a never-created local document, or\n * a deferred write whose only durable content is the history tail ahead of\n * its covered frontier. Mirrors the queue's own document candidate sources,\n * so \"failure-only\" here agrees with the item the panel rendered.\n */\nasync function hasQueuedScopeWork(\n execSql: ExecSql,\n scope: { appKind: string; localId: string },\n): Promise<boolean> {\n await ensureSqlTables(execSql, [\n ...documentTables,\n ...documentPlacementIntentTables,\n ]);\n const rows = await execSql(\n `SELECT 1 AS present\n WHERE EXISTS (\n SELECT 1 FROM document_history_updates pending\n WHERE pending.app_kind = ? AND pending.local_id = ?\n AND pending.update_id IS NOT NULL\n )\n OR EXISTS (\n SELECT 1 FROM document_pending_attachments attachment\n WHERE attachment.local_id = ?\n )\n OR EXISTS (\n SELECT 1 FROM local_intents intent\n WHERE intent.lane = '${LOCAL_INTENT_LANES.documentPlacement}'\n AND intent.local_id = ?\n AND intent.intent_type IN ('document.move', 'document.link')\n )\n OR EXISTS (\n SELECT 1 FROM documents stored\n WHERE stored.app_kind = ? AND stored.local_id = ?\n AND stored.document_id IS NULL\n )\n LIMIT 1`,\n [\n scope.appKind,\n scope.localId,\n scope.localId,\n scope.localId,\n scope.appKind,\n scope.localId,\n ],\n );\n if (rows.length > 0) {\n return true;\n }\n // The queue's deferred-update source has no queued rows to probe: the\n // write lives in the durable history tail, detectable only by the\n // version-vector coverage check.\n return hasDeferredTailScopeWork(execSql, scope);\n}\n"]}
|
|
@@ -18,7 +18,8 @@ import { verifyRemoteContainerDestination } from "./remoteHydration/verifiedDest
|
|
|
18
18
|
// move — one whose destination parent has not synced yet, the common boot-time
|
|
19
19
|
// case — is protected too. Pending *metadata*
|
|
20
20
|
// updates are handled separately (listRemoteContainerIdsWithPendingMetadataUpdates);
|
|
21
|
-
//
|
|
21
|
+
// structural intents live in the local outbox's container lanes, which that
|
|
22
|
+
// query does not cover.
|
|
22
23
|
export async function listRemoteContainerIdsWithPendingStructuralIntents(input) {
|
|
23
24
|
if (input.remoteContainers.length === 0) {
|
|
24
25
|
return new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remoteContainerState.js","sourceRoot":"","sources":["remoteContainerState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessManifestCheckpoint } from \"@tearleads/crypto\";\nimport {\n heldContainerBinding,\n listingRepeatsHeldOrdinaryBinding,\n} from \"../../data/containers/containerBinding\";\nimport {\n isKeyingVerificationError,\n runWithSecurityIncidentReporting,\n} from \"../../data/keyingProjectionVerification/error\";\nimport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification/types\";\nimport type { ContainerHydrationTombstone } from \"./containerPersistence\";\nimport { installContainerMetadataRecord } from \"./metadataPersistence\";\nimport { projectionGeneration } from \"./projectionGeneration\";\nimport {\n moveIndexedContainerChild,\n removeIndexedContainerChild,\n} from \"./remoteHydration/childIndex\";\nimport type { PrefetchedDestinationProjection } from \"./remoteHydration/destinationPrefetch\";\nimport { rebindReHomedContainer } from \"./remoteHydration/heldContainerRebind\";\nimport { insertRemoteContainerState } from \"./remoteHydration/insertRemoteContainer\";\nimport {\n reconcileLocalOnlyRootContainers,\n reconcileLocalOnlySystemContainers,\n} from \"./remoteHydration/reconciliation\";\nimport {\n applyRemoteContainerTimestamps,\n remoteContainerHydrationSaveOptions,\n resolveRemoteContainerHydrationLocalUpdatedAt,\n} from \"./remoteHydration/remoteContainerTimestamps\";\nimport type {\n ContainerChildIndex,\n ContainerState,\n RemoteContainer,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"./remoteHydration/types\";\nimport { verifyRemoteContainerDestination } from \"./remoteHydration/verifiedDestination\";\n\n// Container ids (restricted to the inbound page) that carry an unsynced local\n// create or move intent. Such a container's parent and local-edit timestamp are\n// owned by its structural-intent lane until that lane reconciles, so inbound\n// hydration must not revert parentId to the server value nor collapse\n// localUpdatedAt — doing so silently undoes a queued move and falsely reads\n// \"synced\". Move intents are read via listUnsyncedMoveIntents so a blocked\n// move — one whose destination parent has not synced yet, the common boot-time\n// case — is protected too. Pending *metadata*\n// updates are handled separately (listRemoteContainerIdsWithPendingMetadataUpdates);\n// these live in dedicated create/move intent tables that that query does not cover.\nexport async function listRemoteContainerIdsWithPendingStructuralIntents(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n if (input.remoteContainers.length === 0) {\n return new Set();\n }\n const remoteContainerIds = new Set(\n input.remoteContainers.map((remoteContainer) => remoteContainer.id),\n );\n\n const execSql = input.state.runtime.infra.execSql;\n const [pendingCreateIntents, unsyncedMoveIntents] = await Promise.all([\n input.state.persistence.listPendingCreateIntents(execSql),\n input.state.persistence.listUnsyncedMoveIntents(execSql),\n ]);\n const containerIdsWithPendingStructuralIntents = new Set<string>();\n for (const intent of pendingCreateIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n for (const intent of unsyncedMoveIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n return containerIdsWithPendingStructuralIntents;\n}\n\nexport async function listRemoteContainerIdsWithPendingMetadataUpdates(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n const containerIds = input.remoteContainers.flatMap((remoteContainer) => {\n const previousLocalUpdatedAt = input.state.containersById.get(\n remoteContainer.id,\n )?.container.localUpdatedAt;\n\n return previousLocalUpdatedAt &&\n previousLocalUpdatedAt.localeCompare(remoteContainer.updatedAt) > 0\n ? [remoteContainer.id]\n : [];\n });\n if (containerIds.length === 0) {\n return new Set();\n }\n\n const execSql = input.state.runtime.infra.execSql;\n return new Set(\n await input.state.persistence.listContainerIdsWithPendingUpdates(\n execSql,\n containerIds,\n ),\n );\n}\n\nfunction removeMissingHydratedContainer(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n existingState: ContainerState;\n host: RemoteContainerHydrationHost;\n previousParentId: string | null;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): void {\n const { existingState, remoteContainer, state } = input;\n if (state.containersById.get(remoteContainer.id) !== existingState) {\n return;\n }\n\n state.containersById.delete(remoteContainer.id);\n if (input.childIdsByParentId) {\n removeIndexedContainerChild(\n input.childIdsByParentId,\n remoteContainer.id,\n input.previousParentId,\n );\n input.childIdsByParentId.delete(remoteContainer.id);\n }\n input.host.updateSnapshot();\n}\n\nfunction createUpdatedRemoteContainerState(\n existingState: ContainerState,\n remoteContainer: RemoteContainer,\n): ContainerState {\n return {\n ...existingState,\n container: applyRemoteContainerTimestamps(\n existingState.container,\n remoteContainer,\n ),\n containerWriterProjection: null,\n metadataReferencedPrincipals: remoteContainer.metadataReferencedPrincipals,\n };\n}\n\nfunction installUpdatedRemoteContainerState(\n existingState: ContainerState,\n nextState: ContainerState,\n host: RemoteContainerHydrationHost,\n): void {\n const wasLocalOnly = existingState.container.serverCreatedAt == null;\n existingState.container = nextState.container;\n existingState.containerWriterProjection = nextState.containerWriterProjection;\n existingState.metadataReferencedPrincipals =\n nextState.metadataReferencedPrincipals;\n // The snapshot copied the live generation when it was taken; a hint that\n // landed during the persist leaves the live metadata projection dropped.\n if (projectionGeneration(existingState) === projectionGeneration(nextState))\n existingState.metadataWriterProjection = nextState.metadataWriterProjection;\n installContainerMetadataRecord(existingState, nextState.record);\n // A document pass may have deferred while this root was awaiting proof.\n // The first durable remote acknowledgement makes its pending creates runnable.\n if (wasLocalOnly && existingState.container.serverCreatedAt != null)\n host.requestDocumentPriming?.();\n}\n\nasync function updateExistingRemoteContainerState(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n existingState: ContainerState;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): Promise<ContainerState | null> {\n const { childIdsByParentId, existingState, host, remoteContainer, state } =\n input;\n const previousParentId = existingState.container.parentId;\n const previousLocalUpdatedAt = existingState.container.localUpdatedAt;\n // A queued, not-yet-synced local move/create owns this container's parent\n // until its intent lane reconciles. Omit the remote parent when the page scan\n // saw one; persistence also rechecks the intent transactionally so a move\n // created after that scan wins. Both paths preserve the durable local clock.\n const hasPendingStructuralIntent =\n input.containerIdsWithPendingStructuralIntents.has(remoteContainer.id);\n const nextParentId = hasPendingStructuralIntent\n ? undefined\n : remoteContainer.parentId;\n const localUpdatedAt = resolveRemoteContainerHydrationLocalUpdatedAt({\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n hasPendingStructuralIntent,\n previousLocalUpdatedAt,\n remoteContainer,\n });\n const nextState = createUpdatedRemoteContainerState(\n existingState,\n remoteContainer,\n );\n const persistenceResult = await host.persistContainerState(\n nextState,\n {\n accessEpoch: remoteContainer.metadataAccessEpoch,\n accessStateHash: remoteContainer.metadataAccessStateHash,\n documentId: remoteContainer.metadataDocumentId,\n effectiveAccessLevel: remoteContainer.effectiveAccessLevel,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n systemSlot: remoteContainer.systemSlot ?? null,\n organizationId: remoteContainer.organizationId,\n ...(nextParentId !== undefined ? { parentId: nextParentId } : {}),\n },\n false,\n remoteContainerHydrationSaveOptions({\n localUpdatedAt,\n remoteContainer,\n }),\n {\n preserveDurableStructureWhenPending: true,\n },\n );\n if (persistenceResult.status === \"missing\") {\n // Hydration persists a detached candidate so an in-flight response cannot\n // mutate mapped state before its guards settle. Retire the exact state this\n // hydration read because store-level reference cleanup cannot see the clone.\n removeMissingHydratedContainer({\n childIdsByParentId,\n existingState,\n host,\n previousParentId,\n remoteContainer,\n state,\n });\n return null;\n }\n if (persistenceResult.status !== \"persisted\") return null;\n const { record: nextRecord } = persistenceResult;\n installContainerMetadataRecord(nextState, nextRecord);\n if (input.isCurrent?.() === false) {\n return existingState;\n }\n nextState.container = {\n ...nextState.container,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n organizationId: remoteContainer.organizationId,\n parentId: nextState.container.parentId,\n };\n\n installUpdatedRemoteContainerState(existingState, nextState, host);\n moveIndexedContainerChild(\n childIdsByParentId,\n remoteContainer.id,\n previousParentId,\n existingState.container.parentId,\n );\n await reconcileLocalOnlyRootContainers({\n childIdsByParentId,\n isCurrent: input.isCurrent,\n remoteRootState: existingState,\n requestDocumentPriming: host.requestDocumentPriming,\n state,\n });\n return existingState;\n}\n\ninterface UpsertRemoteContainerStateInput {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n expectedHydrationTombstone?: ContainerHydrationTombstone | null | undefined;\n isCurrent?: (() => boolean) | undefined;\n prefetchedProjection?: PrefetchedDestinationProjection | undefined;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}\n\nexport async function upsertRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n let expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n const heldState = input.state.containersById.get(input.remoteContainer.id);\n const heldBinding = heldState\n ? heldContainerBinding(heldState)\n : await input.state.persistence.loadHeldContainerBinding(\n input.state.runtime.infra.execSql,\n input.remoteContainer.id,\n );\n const listed = input.remoteContainer;\n // A folder re-homed away from the listed organization never returns there,\n // whatever binding (possibly none, after a reset) the device holds now.\n const supersededListing =\n !listingRepeatsHeldOrdinaryBinding(heldBinding, listed) &&\n (await input.state.persistence.isSupersededContainerBinding(\n input.state.runtime.infra.execSql,\n { containerId: listed.id, organizationId: listed.organizationId },\n ));\n if (input.isCurrent?.() === false) return null;\n const verified = await verifyRemoteContainerDestination({\n ...input,\n heldBinding,\n supersededListing,\n refresh: !!input.expectedHydrationTombstone,\n onVerifiedCheckpoint: (checkpoint) => {\n expectedPlacementCheckpoint = checkpoint;\n },\n });\n if (!verified || input.isCurrent?.() === false) return null;\n input = { ...input, remoteContainer: verified };\n const existingState = input.state.containersById.get(\n input.remoteContainer.id,\n );\n const remoteState = await runWithSecurityIncidentReporting(\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: verified.id,\n objectKind: \"container\",\n operation: \"container.binding.persist\",\n organizationId: verified.organizationId,\n },\n async () =>\n (await rebindReHomedContainer({\n existingState,\n heldBinding,\n isCurrent: input.isCurrent,\n state: input.state,\n verified,\n }))\n ? persistVerifiedRemoteContainer({\n ...input,\n existingState,\n expectedPlacementCheckpoint,\n })\n : null,\n );\n if (!remoteState) {\n return null;\n }\n await reconcileLocalOnlySystemContainers({\n childIdsByParentId: input.childIdsByParentId,\n isCurrent: input.isCurrent,\n requestDocumentPriming: input.host.requestDocumentPriming,\n remoteSystemState: remoteState,\n state: input.state,\n });\n return remoteState;\n}\n\n/**\n * Upsert one listed folder, isolating a rejected proof or binding. The refusal\n * was already reported; returning no state leaves the item unapplied without\n * blocking independent folders.\n */\nexport async function upsertIsolatedRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n try {\n return await upsertRemoteContainerState(input);\n } catch (error) {\n if (\n !isKeyingVerificationError(error) &&\n !isProjectionVerificationCancelledError(error)\n )\n throw error;\n return null;\n }\n}\n\nfunction persistVerifiedRemoteContainer(\n input: UpsertRemoteContainerStateInput & {\n existingState: ContainerState | undefined;\n expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n },\n): Promise<ContainerState | null> {\n const { existingState, expectedPlacementCheckpoint } = input;\n return existingState\n ? updateExistingRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents:\n input.containerIdsWithPendingStructuralIntents,\n existingState,\n host: input.host,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n })\n : insertRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n host: input.host,\n expectedHydrationTombstone: input.expectedHydrationTombstone ?? null,\n expectedPlacementCheckpoint,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"remoteContainerState.js","sourceRoot":"","sources":["remoteContainerState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AccessManifestCheckpoint } from \"@tearleads/crypto\";\nimport {\n heldContainerBinding,\n listingRepeatsHeldOrdinaryBinding,\n} from \"../../data/containers/containerBinding\";\nimport {\n isKeyingVerificationError,\n runWithSecurityIncidentReporting,\n} from \"../../data/keyingProjectionVerification/error\";\nimport { isProjectionVerificationCancelledError } from \"../../data/keyingProjectionVerification/types\";\nimport type { ContainerHydrationTombstone } from \"./containerPersistence\";\nimport { installContainerMetadataRecord } from \"./metadataPersistence\";\nimport { projectionGeneration } from \"./projectionGeneration\";\nimport {\n moveIndexedContainerChild,\n removeIndexedContainerChild,\n} from \"./remoteHydration/childIndex\";\nimport type { PrefetchedDestinationProjection } from \"./remoteHydration/destinationPrefetch\";\nimport { rebindReHomedContainer } from \"./remoteHydration/heldContainerRebind\";\nimport { insertRemoteContainerState } from \"./remoteHydration/insertRemoteContainer\";\nimport {\n reconcileLocalOnlyRootContainers,\n reconcileLocalOnlySystemContainers,\n} from \"./remoteHydration/reconciliation\";\nimport {\n applyRemoteContainerTimestamps,\n remoteContainerHydrationSaveOptions,\n resolveRemoteContainerHydrationLocalUpdatedAt,\n} from \"./remoteHydration/remoteContainerTimestamps\";\nimport type {\n ContainerChildIndex,\n ContainerState,\n RemoteContainer,\n RemoteContainerHydrationHost,\n RemoteContainerHydrationState,\n} from \"./remoteHydration/types\";\nimport { verifyRemoteContainerDestination } from \"./remoteHydration/verifiedDestination\";\n\n// Container ids (restricted to the inbound page) that carry an unsynced local\n// create or move intent. Such a container's parent and local-edit timestamp are\n// owned by its structural-intent lane until that lane reconciles, so inbound\n// hydration must not revert parentId to the server value nor collapse\n// localUpdatedAt — doing so silently undoes a queued move and falsely reads\n// \"synced\". Move intents are read via listUnsyncedMoveIntents so a blocked\n// move — one whose destination parent has not synced yet, the common boot-time\n// case — is protected too. Pending *metadata*\n// updates are handled separately (listRemoteContainerIdsWithPendingMetadataUpdates);\n// structural intents live in the local outbox's container lanes, which that\n// query does not cover.\nexport async function listRemoteContainerIdsWithPendingStructuralIntents(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n if (input.remoteContainers.length === 0) {\n return new Set();\n }\n const remoteContainerIds = new Set(\n input.remoteContainers.map((remoteContainer) => remoteContainer.id),\n );\n\n const execSql = input.state.runtime.infra.execSql;\n const [pendingCreateIntents, unsyncedMoveIntents] = await Promise.all([\n input.state.persistence.listPendingCreateIntents(execSql),\n input.state.persistence.listUnsyncedMoveIntents(execSql),\n ]);\n const containerIdsWithPendingStructuralIntents = new Set<string>();\n for (const intent of pendingCreateIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n for (const intent of unsyncedMoveIntents) {\n if (remoteContainerIds.has(intent.containerId)) {\n containerIdsWithPendingStructuralIntents.add(intent.containerId);\n }\n }\n return containerIdsWithPendingStructuralIntents;\n}\n\nexport async function listRemoteContainerIdsWithPendingMetadataUpdates(input: {\n remoteContainers: ReadonlyArray<RemoteContainer>;\n state: RemoteContainerHydrationState;\n}): Promise<Set<string>> {\n const containerIds = input.remoteContainers.flatMap((remoteContainer) => {\n const previousLocalUpdatedAt = input.state.containersById.get(\n remoteContainer.id,\n )?.container.localUpdatedAt;\n\n return previousLocalUpdatedAt &&\n previousLocalUpdatedAt.localeCompare(remoteContainer.updatedAt) > 0\n ? [remoteContainer.id]\n : [];\n });\n if (containerIds.length === 0) {\n return new Set();\n }\n\n const execSql = input.state.runtime.infra.execSql;\n return new Set(\n await input.state.persistence.listContainerIdsWithPendingUpdates(\n execSql,\n containerIds,\n ),\n );\n}\n\nfunction removeMissingHydratedContainer(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n existingState: ContainerState;\n host: RemoteContainerHydrationHost;\n previousParentId: string | null;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): void {\n const { existingState, remoteContainer, state } = input;\n if (state.containersById.get(remoteContainer.id) !== existingState) {\n return;\n }\n\n state.containersById.delete(remoteContainer.id);\n if (input.childIdsByParentId) {\n removeIndexedContainerChild(\n input.childIdsByParentId,\n remoteContainer.id,\n input.previousParentId,\n );\n input.childIdsByParentId.delete(remoteContainer.id);\n }\n input.host.updateSnapshot();\n}\n\nfunction createUpdatedRemoteContainerState(\n existingState: ContainerState,\n remoteContainer: RemoteContainer,\n): ContainerState {\n return {\n ...existingState,\n container: applyRemoteContainerTimestamps(\n existingState.container,\n remoteContainer,\n ),\n containerWriterProjection: null,\n metadataReferencedPrincipals: remoteContainer.metadataReferencedPrincipals,\n };\n}\n\nfunction installUpdatedRemoteContainerState(\n existingState: ContainerState,\n nextState: ContainerState,\n host: RemoteContainerHydrationHost,\n): void {\n const wasLocalOnly = existingState.container.serverCreatedAt == null;\n existingState.container = nextState.container;\n existingState.containerWriterProjection = nextState.containerWriterProjection;\n existingState.metadataReferencedPrincipals =\n nextState.metadataReferencedPrincipals;\n // The snapshot copied the live generation when it was taken; a hint that\n // landed during the persist leaves the live metadata projection dropped.\n if (projectionGeneration(existingState) === projectionGeneration(nextState))\n existingState.metadataWriterProjection = nextState.metadataWriterProjection;\n installContainerMetadataRecord(existingState, nextState.record);\n // A document pass may have deferred while this root was awaiting proof.\n // The first durable remote acknowledgement makes its pending creates runnable.\n if (wasLocalOnly && existingState.container.serverCreatedAt != null)\n host.requestDocumentPriming?.();\n}\n\nasync function updateExistingRemoteContainerState(input: {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n isCurrent?: (() => boolean) | undefined;\n existingState: ContainerState;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}): Promise<ContainerState | null> {\n const { childIdsByParentId, existingState, host, remoteContainer, state } =\n input;\n const previousParentId = existingState.container.parentId;\n const previousLocalUpdatedAt = existingState.container.localUpdatedAt;\n // A queued, not-yet-synced local move/create owns this container's parent\n // until its intent lane reconciles. Omit the remote parent when the page scan\n // saw one; persistence also rechecks the intent transactionally so a move\n // created after that scan wins. Both paths preserve the durable local clock.\n const hasPendingStructuralIntent =\n input.containerIdsWithPendingStructuralIntents.has(remoteContainer.id);\n const nextParentId = hasPendingStructuralIntent\n ? undefined\n : remoteContainer.parentId;\n const localUpdatedAt = resolveRemoteContainerHydrationLocalUpdatedAt({\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n hasPendingStructuralIntent,\n previousLocalUpdatedAt,\n remoteContainer,\n });\n const nextState = createUpdatedRemoteContainerState(\n existingState,\n remoteContainer,\n );\n const persistenceResult = await host.persistContainerState(\n nextState,\n {\n accessEpoch: remoteContainer.metadataAccessEpoch,\n accessStateHash: remoteContainer.metadataAccessStateHash,\n documentId: remoteContainer.metadataDocumentId,\n effectiveAccessLevel: remoteContainer.effectiveAccessLevel,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n systemSlot: remoteContainer.systemSlot ?? null,\n organizationId: remoteContainer.organizationId,\n ...(nextParentId !== undefined ? { parentId: nextParentId } : {}),\n },\n false,\n remoteContainerHydrationSaveOptions({\n localUpdatedAt,\n remoteContainer,\n }),\n {\n preserveDurableStructureWhenPending: true,\n },\n );\n if (persistenceResult.status === \"missing\") {\n // Hydration persists a detached candidate so an in-flight response cannot\n // mutate mapped state before its guards settle. Retire the exact state this\n // hydration read because store-level reference cleanup cannot see the clone.\n removeMissingHydratedContainer({\n childIdsByParentId,\n existingState,\n host,\n previousParentId,\n remoteContainer,\n state,\n });\n return null;\n }\n if (persistenceResult.status !== \"persisted\") return null;\n const { record: nextRecord } = persistenceResult;\n installContainerMetadataRecord(nextState, nextRecord);\n if (input.isCurrent?.() === false) {\n return existingState;\n }\n nextState.container = {\n ...nextState.container,\n metadataDocumentId: remoteContainer.metadataDocumentId,\n organizationId: remoteContainer.organizationId,\n parentId: nextState.container.parentId,\n };\n\n installUpdatedRemoteContainerState(existingState, nextState, host);\n moveIndexedContainerChild(\n childIdsByParentId,\n remoteContainer.id,\n previousParentId,\n existingState.container.parentId,\n );\n await reconcileLocalOnlyRootContainers({\n childIdsByParentId,\n isCurrent: input.isCurrent,\n remoteRootState: existingState,\n requestDocumentPriming: host.requestDocumentPriming,\n state,\n });\n return existingState;\n}\n\ninterface UpsertRemoteContainerStateInput {\n childIdsByParentId?: ContainerChildIndex | undefined;\n containerIdsWithPendingMetadataUpdates: ReadonlySet<string>;\n containerIdsWithPendingStructuralIntents: ReadonlySet<string>;\n host: RemoteContainerHydrationHost;\n expectedHydrationTombstone?: ContainerHydrationTombstone | null | undefined;\n isCurrent?: (() => boolean) | undefined;\n prefetchedProjection?: PrefetchedDestinationProjection | undefined;\n remoteContainer: RemoteContainer;\n state: RemoteContainerHydrationState;\n}\n\nexport async function upsertRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n let expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n const heldState = input.state.containersById.get(input.remoteContainer.id);\n const heldBinding = heldState\n ? heldContainerBinding(heldState)\n : await input.state.persistence.loadHeldContainerBinding(\n input.state.runtime.infra.execSql,\n input.remoteContainer.id,\n );\n const listed = input.remoteContainer;\n // A folder re-homed away from the listed organization never returns there,\n // whatever binding (possibly none, after a reset) the device holds now.\n const supersededListing =\n !listingRepeatsHeldOrdinaryBinding(heldBinding, listed) &&\n (await input.state.persistence.isSupersededContainerBinding(\n input.state.runtime.infra.execSql,\n { containerId: listed.id, organizationId: listed.organizationId },\n ));\n if (input.isCurrent?.() === false) return null;\n const verified = await verifyRemoteContainerDestination({\n ...input,\n heldBinding,\n supersededListing,\n refresh: !!input.expectedHydrationTombstone,\n onVerifiedCheckpoint: (checkpoint) => {\n expectedPlacementCheckpoint = checkpoint;\n },\n });\n if (!verified || input.isCurrent?.() === false) return null;\n input = { ...input, remoteContainer: verified };\n const existingState = input.state.containersById.get(\n input.remoteContainer.id,\n );\n const remoteState = await runWithSecurityIncidentReporting(\n input.state.runtime.util.reportSecurityIncident,\n {\n objectId: verified.id,\n objectKind: \"container\",\n operation: \"container.binding.persist\",\n organizationId: verified.organizationId,\n },\n async () =>\n (await rebindReHomedContainer({\n existingState,\n heldBinding,\n isCurrent: input.isCurrent,\n state: input.state,\n verified,\n }))\n ? persistVerifiedRemoteContainer({\n ...input,\n existingState,\n expectedPlacementCheckpoint,\n })\n : null,\n );\n if (!remoteState) {\n return null;\n }\n await reconcileLocalOnlySystemContainers({\n childIdsByParentId: input.childIdsByParentId,\n isCurrent: input.isCurrent,\n requestDocumentPriming: input.host.requestDocumentPriming,\n remoteSystemState: remoteState,\n state: input.state,\n });\n return remoteState;\n}\n\n/**\n * Upsert one listed folder, isolating a rejected proof or binding. The refusal\n * was already reported; returning no state leaves the item unapplied without\n * blocking independent folders.\n */\nexport async function upsertIsolatedRemoteContainerState(\n input: UpsertRemoteContainerStateInput,\n): Promise<ContainerState | null> {\n try {\n return await upsertRemoteContainerState(input);\n } catch (error) {\n if (\n !isKeyingVerificationError(error) &&\n !isProjectionVerificationCancelledError(error)\n )\n throw error;\n return null;\n }\n}\n\nfunction persistVerifiedRemoteContainer(\n input: UpsertRemoteContainerStateInput & {\n existingState: ContainerState | undefined;\n expectedPlacementCheckpoint: AccessManifestCheckpoint | undefined;\n },\n): Promise<ContainerState | null> {\n const { existingState, expectedPlacementCheckpoint } = input;\n return existingState\n ? updateExistingRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n containerIdsWithPendingMetadataUpdates:\n input.containerIdsWithPendingMetadataUpdates,\n containerIdsWithPendingStructuralIntents:\n input.containerIdsWithPendingStructuralIntents,\n existingState,\n host: input.host,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n })\n : insertRemoteContainerState({\n childIdsByParentId: input.childIdsByParentId,\n host: input.host,\n expectedHydrationTombstone: input.expectedHydrationTombstone ?? null,\n expectedPlacementCheckpoint,\n isCurrent: input.isCurrent,\n remoteContainer: input.remoteContainer,\n state: input.state,\n });\n}\n"]}
|