@tearleads/client-sdk 0.1.68 → 0.1.71

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.
Files changed (123) hide show
  1. package/data/containers/shared/principalPolicies.js +8 -12
  2. package/data/containers/shared/principalPolicies.js.map +1 -1
  3. package/internal/api-client/ApiClient.d.ts +73 -3
  4. package/internal/api-client/apiRequestMetrics.d.ts +18 -4
  5. package/internal/api-client/apiRequestMetrics.js +55 -5
  6. package/internal/api-client/apiRequestMetrics.js.map +1 -1
  7. package/internal/api-client/durationSampleWindow.d.ts +26 -0
  8. package/internal/api-client/durationSampleWindow.js +42 -0
  9. package/internal/api-client/durationSampleWindow.js.map +1 -0
  10. package/internal/api-client/measureApiRequest.js +9 -4
  11. package/internal/api-client/measureApiRequest.js.map +1 -1
  12. package/internal/api-client/serverTiming.d.ts +12 -0
  13. package/internal/api-client/serverTiming.js +49 -0
  14. package/internal/api-client/serverTiming.js.map +1 -0
  15. package/internal/validators/documentCreateSeedRefinements.js +9 -0
  16. package/internal/validators/documentCreateSeedRefinements.js.map +1 -0
  17. package/internal/validators/operation/attachments.d.ts +48 -8
  18. package/internal/validators/operation/auth.d.ts +576 -76
  19. package/internal/validators/operation/containerMutations.d.ts +619 -44
  20. package/internal/validators/operation/containerMutations.js +7 -1
  21. package/internal/validators/operation/containerMutations.js.map +1 -1
  22. package/internal/validators/operation/documentMutations.d.ts +428 -12
  23. package/internal/validators/operation/documentMutations.js +6 -1
  24. package/internal/validators/operation/documentMutations.js.map +1 -1
  25. package/internal/validators/operation/documentSync.d.ts +33 -13
  26. package/internal/validators/operation/organizations.d.ts +648 -88
  27. package/internal/validators/operation/principals.d.ts +96 -16
  28. package/internal/validators/request/blob.d.ts +48 -8
  29. package/internal/validators/request/container.d.ts +96 -16
  30. package/internal/validators/request/container.js +5 -2
  31. package/internal/validators/request/container.js.map +1 -1
  32. package/internal/validators/request/containerMetadata.d.ts +409 -16
  33. package/internal/validators/request/containerMetadata.js +20 -3
  34. package/internal/validators/request/containerMetadata.js.map +1 -1
  35. package/internal/validators/request/document.d.ts +631 -10
  36. package/internal/validators/request/document.js +19 -1
  37. package/internal/validators/request/document.js.map +1 -1
  38. package/internal/validators/request/documentCreateSeed.js +35 -0
  39. package/internal/validators/request/documentCreateSeed.js.map +1 -0
  40. package/internal/validators/request/documentSyncSchema.d.ts +24 -4
  41. package/internal/validators/request/documentSyncSchema.js +2 -1
  42. package/internal/validators/request/documentSyncSchema.js.map +1 -1
  43. package/internal/validators/request/index.d.ts +1 -0
  44. package/internal/validators/request/index.js +1 -0
  45. package/internal/validators/request/index.js.map +1 -1
  46. package/internal/validators/request/organization.d.ts +96 -16
  47. package/internal/validators/request/organizationProvisioning.d.ts +1456 -246
  48. package/internal/validators/request/organizationProvisioning.js +9 -22
  49. package/internal/validators/request/organizationProvisioning.js.map +1 -1
  50. package/internal/validators/request/principal.d.ts +120 -20
  51. package/internal/validators/request/principalPolicyRef.d.ts +42 -0
  52. package/internal/validators/request/principalPolicyRef.js +19 -0
  53. package/internal/validators/request/principalPolicyRef.js.map +1 -0
  54. package/internal/validators/request/registration.d.ts +456 -76
  55. package/internal/validators/response/containerMetadata.d.ts +20 -0
  56. package/internal/validators/response/documentMutation.d.ts +43 -0
  57. package/internal/validators/response/documentMutation.js +12 -1
  58. package/internal/validators/response/documentMutation.js.map +1 -1
  59. package/internal/validators/response/documentSyncSchema.d.ts +13 -9
  60. package/internal/validators/response/documentSyncSchema.js +23 -18
  61. package/internal/validators/response/documentSyncSchema.js.map +1 -1
  62. package/internal/validators/response/index.d.ts +1 -1
  63. package/internal/validators/response/index.js.map +1 -1
  64. package/internal/validators/response/organizationProvisioning.d.ts +350 -0
  65. package/internal/validators/response/registration.d.ts +120 -0
  66. package/internal/validators/util/containerLimits.d.ts +8 -0
  67. package/internal/validators/util/containerLimits.js +8 -0
  68. package/internal/validators/util/containerLimits.js.map +1 -1
  69. package/package.json +1 -1
  70. package/stores/container-contents/containerState/containerStatePersistence.js +2 -0
  71. package/stores/container-contents/containerState/containerStatePersistence.js.map +1 -1
  72. package/stores/container-contents/remoteEvents/remoteEventSync.js +1 -1
  73. package/stores/container-contents/remoteEvents/remoteEventSync.js.map +1 -1
  74. package/stores/container-contents/state.js +2 -0
  75. package/stores/container-contents/state.js.map +1 -1
  76. package/stores/container-contents/syncAgent/syncAgentTypes.d.ts +5 -0
  77. package/stores/container-contents/syncAgent/syncAgentTypes.js.map +1 -1
  78. package/stores/documents/documentStore/sync/createdDocumentPersistence.js +71 -0
  79. package/stores/documents/documentStore/sync/createdDocumentPersistence.js.map +1 -0
  80. package/stores/documents/documentStore/sync/index.js +13 -2
  81. package/stores/documents/documentStore/sync/index.js.map +1 -1
  82. package/stores/documents/documentStore/sync/syncRemoteSignals.js +21 -3
  83. package/stores/documents/documentStore/sync/syncRemoteSignals.js.map +1 -1
  84. package/stores/documents/documentStore/sync/syncSeededCreate.js +50 -0
  85. package/stores/documents/documentStore/sync/syncSeededCreate.js.map +1 -0
  86. package/stores/documents/documentStore/sync/syncShared.js +16 -8
  87. package/stores/documents/documentStore/sync/syncShared.js.map +1 -1
  88. package/workflows/container-contents/container-state/create/createIntentSeed.js +60 -0
  89. package/workflows/container-contents/container-state/create/createIntentSeed.js.map +1 -0
  90. package/workflows/container-contents/container-state/create/createIntentSync.js +18 -19
  91. package/workflows/container-contents/container-state/create/createIntentSync.js.map +1 -1
  92. package/workflows/container-contents/container-state/create/createWithMetadata.js +43 -6
  93. package/workflows/container-contents/container-state/create/createWithMetadata.js.map +1 -1
  94. package/workflows/container-contents/container-state/create/createWithMetadataPlan.js +5 -1
  95. package/workflows/container-contents/container-state/create/createWithMetadataPlan.js.map +1 -1
  96. package/workflows/container-contents/container-state/remote.js +15 -0
  97. package/workflows/container-contents/container-state/remote.js.map +1 -1
  98. package/workflows/container-contents/container-state/types.js.map +1 -1
  99. package/workflows/container-contents/metadata/metadataEvents.d.ts +7 -1
  100. package/workflows/container-contents/metadata/metadataEvents.js +8 -2
  101. package/workflows/container-contents/metadata/metadataEvents.js.map +1 -1
  102. package/workflows/container-contents/remoteHydration/types.d.ts +3 -0
  103. package/workflows/container-contents/remoteHydration/types.js.map +1 -1
  104. package/workflows/containers/child/mutationRequestCore.js +2 -2
  105. package/workflows/containers/child/mutationRequestCore.js.map +1 -1
  106. package/workflows/containers/child/recitePlan.js +2 -2
  107. package/workflows/containers/child/recitePlan.js.map +1 -1
  108. package/workflows/containers/root/create.js +17 -28
  109. package/workflows/containers/root/create.js.map +1 -1
  110. package/workflows/containers/root/initialGroupPolicy.js +0 -23
  111. package/workflows/containers/root/initialGroupPolicy.js.map +1 -1
  112. package/workflows/documents/create/index.d.ts +7 -0
  113. package/workflows/documents/create/index.js +40 -2
  114. package/workflows/documents/create/index.js.map +1 -1
  115. package/workflows/documents/index.d.ts +1 -0
  116. package/workflows/documents/index.js +1 -0
  117. package/workflows/documents/index.js.map +1 -1
  118. package/workflows/documents/sync/initialSync.d.ts +39 -0
  119. package/workflows/documents/sync/initialSync.js +39 -6
  120. package/workflows/documents/sync/initialSync.js.map +1 -1
  121. package/workflows/documents/syncFailures/syncPolicyRepair.js +2 -8
  122. package/workflows/documents/syncFailures/syncPolicyRepair.js.map +1 -1
  123. package/workflows/registration/provisioningBootstrapBuilders.d.ts +12 -2
@@ -100,6 +100,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
100
100
  targets: Record<string, unknown>[];
101
101
  };
102
102
  id: string;
103
+ initialSync?: {
104
+ commitLsn: string | null;
105
+ commitLsnMode: "tracked" | "untracked";
106
+ acceptedOutgoingUpdateIds: string[];
107
+ } | undefined;
103
108
  };
104
109
  };
105
110
  organizationMetadataContainerId: string;
@@ -141,6 +146,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
141
146
  targets: Record<string, unknown>[];
142
147
  };
143
148
  id: string;
149
+ initialSync?: {
150
+ commitLsn: string | null;
151
+ commitLsnMode: "tracked" | "untracked";
152
+ acceptedOutgoingUpdateIds: string[];
153
+ } | undefined;
144
154
  };
145
155
  rootMetadataDocumentId: string;
146
156
  systemContainers: {
@@ -239,6 +249,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
239
249
  targets: Record<string, unknown>[];
240
250
  };
241
251
  id: string;
252
+ initialSync?: {
253
+ commitLsn: string | null;
254
+ commitLsnMode: "tracked" | "untracked";
255
+ acceptedOutgoingUpdateIds: string[];
256
+ } | undefined;
242
257
  };
243
258
  }[];
244
259
  userId: string;
@@ -277,6 +292,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
277
292
  targets: Record<string, unknown>[];
278
293
  };
279
294
  id: string;
295
+ initialSync?: {
296
+ commitLsn: string | null;
297
+ commitLsnMode: "tracked" | "untracked";
298
+ acceptedOutgoingUpdateIds: string[];
299
+ } | undefined;
280
300
  } | undefined;
281
301
  organizationProfileDocumentId?: string | undefined;
282
302
  rosterProfileContainer?: {
@@ -375,6 +395,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
375
395
  targets: Record<string, unknown>[];
376
396
  };
377
397
  id: string;
398
+ initialSync?: {
399
+ commitLsn: string | null;
400
+ commitLsnMode: "tracked" | "untracked";
401
+ acceptedOutgoingUpdateIds: string[];
402
+ } | undefined;
378
403
  };
379
404
  } | undefined;
380
405
  rosterProfileContainerId?: string | undefined;
@@ -413,6 +438,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
413
438
  targets: Record<string, unknown>[];
414
439
  };
415
440
  id: string;
441
+ initialSync?: {
442
+ commitLsn: string | null;
443
+ commitLsnMode: "tracked" | "untracked";
444
+ acceptedOutgoingUpdateIds: string[];
445
+ } | undefined;
416
446
  } | undefined;
417
447
  rosterProfileDocumentId?: string | undefined;
418
448
  }, {
@@ -516,6 +546,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
516
546
  targets: Record<string, unknown>[];
517
547
  };
518
548
  id: string;
549
+ initialSync?: {
550
+ commitLsn: string | null;
551
+ commitLsnMode: "tracked" | "untracked";
552
+ acceptedOutgoingUpdateIds: string[];
553
+ } | undefined;
519
554
  };
520
555
  };
521
556
  organizationMetadataContainerId: string;
@@ -557,6 +592,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
557
592
  targets: Record<string, unknown>[];
558
593
  };
559
594
  id: string;
595
+ initialSync?: {
596
+ commitLsn: string | null;
597
+ commitLsnMode: "tracked" | "untracked";
598
+ acceptedOutgoingUpdateIds: string[];
599
+ } | undefined;
560
600
  };
561
601
  rootMetadataDocumentId: string;
562
602
  systemContainers: {
@@ -655,6 +695,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
655
695
  targets: Record<string, unknown>[];
656
696
  };
657
697
  id: string;
698
+ initialSync?: {
699
+ commitLsn: string | null;
700
+ commitLsnMode: "tracked" | "untracked";
701
+ acceptedOutgoingUpdateIds: string[];
702
+ } | undefined;
658
703
  };
659
704
  }[];
660
705
  userId: string;
@@ -693,6 +738,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
693
738
  targets: Record<string, unknown>[];
694
739
  };
695
740
  id: string;
741
+ initialSync?: {
742
+ commitLsn: string | null;
743
+ commitLsnMode: "tracked" | "untracked";
744
+ acceptedOutgoingUpdateIds: string[];
745
+ } | undefined;
696
746
  } | undefined;
697
747
  organizationProfileDocumentId?: string | undefined;
698
748
  rosterProfileContainer?: {
@@ -791,6 +841,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
791
841
  targets: Record<string, unknown>[];
792
842
  };
793
843
  id: string;
844
+ initialSync?: {
845
+ commitLsn: string | null;
846
+ commitLsnMode: "tracked" | "untracked";
847
+ acceptedOutgoingUpdateIds: string[];
848
+ } | undefined;
794
849
  };
795
850
  } | undefined;
796
851
  rosterProfileContainerId?: string | undefined;
@@ -829,6 +884,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
829
884
  targets: Record<string, unknown>[];
830
885
  };
831
886
  id: string;
887
+ initialSync?: {
888
+ commitLsn: string | null;
889
+ commitLsnMode: "tracked" | "untracked";
890
+ acceptedOutgoingUpdateIds: string[];
891
+ } | undefined;
832
892
  } | undefined;
833
893
  rosterProfileDocumentId?: string | undefined;
834
894
  }, z.core.$ZodTypeInternals<{
@@ -932,6 +992,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
932
992
  targets: Record<string, unknown>[];
933
993
  };
934
994
  id: string;
995
+ initialSync?: {
996
+ commitLsn: string | null;
997
+ commitLsnMode: "tracked" | "untracked";
998
+ acceptedOutgoingUpdateIds: string[];
999
+ } | undefined;
935
1000
  };
936
1001
  };
937
1002
  organizationMetadataContainerId: string;
@@ -973,6 +1038,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
973
1038
  targets: Record<string, unknown>[];
974
1039
  };
975
1040
  id: string;
1041
+ initialSync?: {
1042
+ commitLsn: string | null;
1043
+ commitLsnMode: "tracked" | "untracked";
1044
+ acceptedOutgoingUpdateIds: string[];
1045
+ } | undefined;
976
1046
  };
977
1047
  rootMetadataDocumentId: string;
978
1048
  systemContainers: {
@@ -1071,6 +1141,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1071
1141
  targets: Record<string, unknown>[];
1072
1142
  };
1073
1143
  id: string;
1144
+ initialSync?: {
1145
+ commitLsn: string | null;
1146
+ commitLsnMode: "tracked" | "untracked";
1147
+ acceptedOutgoingUpdateIds: string[];
1148
+ } | undefined;
1074
1149
  };
1075
1150
  }[];
1076
1151
  userId: string;
@@ -1109,6 +1184,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1109
1184
  targets: Record<string, unknown>[];
1110
1185
  };
1111
1186
  id: string;
1187
+ initialSync?: {
1188
+ commitLsn: string | null;
1189
+ commitLsnMode: "tracked" | "untracked";
1190
+ acceptedOutgoingUpdateIds: string[];
1191
+ } | undefined;
1112
1192
  } | undefined;
1113
1193
  organizationProfileDocumentId?: string | undefined;
1114
1194
  rosterProfileContainer?: {
@@ -1207,6 +1287,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1207
1287
  targets: Record<string, unknown>[];
1208
1288
  };
1209
1289
  id: string;
1290
+ initialSync?: {
1291
+ commitLsn: string | null;
1292
+ commitLsnMode: "tracked" | "untracked";
1293
+ acceptedOutgoingUpdateIds: string[];
1294
+ } | undefined;
1210
1295
  };
1211
1296
  } | undefined;
1212
1297
  rosterProfileContainerId?: string | undefined;
@@ -1245,6 +1330,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1245
1330
  targets: Record<string, unknown>[];
1246
1331
  };
1247
1332
  id: string;
1333
+ initialSync?: {
1334
+ commitLsn: string | null;
1335
+ commitLsnMode: "tracked" | "untracked";
1336
+ acceptedOutgoingUpdateIds: string[];
1337
+ } | undefined;
1248
1338
  } | undefined;
1249
1339
  rosterProfileDocumentId?: string | undefined;
1250
1340
  }, {
@@ -1348,6 +1438,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1348
1438
  targets: Record<string, unknown>[];
1349
1439
  };
1350
1440
  id: string;
1441
+ initialSync?: {
1442
+ commitLsn: string | null;
1443
+ commitLsnMode: "tracked" | "untracked";
1444
+ acceptedOutgoingUpdateIds: string[];
1445
+ } | undefined;
1351
1446
  };
1352
1447
  };
1353
1448
  organizationMetadataContainerId: string;
@@ -1389,6 +1484,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1389
1484
  targets: Record<string, unknown>[];
1390
1485
  };
1391
1486
  id: string;
1487
+ initialSync?: {
1488
+ commitLsn: string | null;
1489
+ commitLsnMode: "tracked" | "untracked";
1490
+ acceptedOutgoingUpdateIds: string[];
1491
+ } | undefined;
1392
1492
  };
1393
1493
  rootMetadataDocumentId: string;
1394
1494
  systemContainers: {
@@ -1487,6 +1587,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1487
1587
  targets: Record<string, unknown>[];
1488
1588
  };
1489
1589
  id: string;
1590
+ initialSync?: {
1591
+ commitLsn: string | null;
1592
+ commitLsnMode: "tracked" | "untracked";
1593
+ acceptedOutgoingUpdateIds: string[];
1594
+ } | undefined;
1490
1595
  };
1491
1596
  }[];
1492
1597
  userId: string;
@@ -1525,6 +1630,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1525
1630
  targets: Record<string, unknown>[];
1526
1631
  };
1527
1632
  id: string;
1633
+ initialSync?: {
1634
+ commitLsn: string | null;
1635
+ commitLsnMode: "tracked" | "untracked";
1636
+ acceptedOutgoingUpdateIds: string[];
1637
+ } | undefined;
1528
1638
  } | undefined;
1529
1639
  organizationProfileDocumentId?: string | undefined;
1530
1640
  rosterProfileContainer?: {
@@ -1623,6 +1733,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1623
1733
  targets: Record<string, unknown>[];
1624
1734
  };
1625
1735
  id: string;
1736
+ initialSync?: {
1737
+ commitLsn: string | null;
1738
+ commitLsnMode: "tracked" | "untracked";
1739
+ acceptedOutgoingUpdateIds: string[];
1740
+ } | undefined;
1626
1741
  };
1627
1742
  } | undefined;
1628
1743
  rosterProfileContainerId?: string | undefined;
@@ -1661,6 +1776,11 @@ export declare const RegistrationResponseSchema: z.ZodType<{
1661
1776
  targets: Record<string, unknown>[];
1662
1777
  };
1663
1778
  id: string;
1779
+ initialSync?: {
1780
+ commitLsn: string | null;
1781
+ commitLsnMode: "tracked" | "untracked";
1782
+ acceptedOutgoingUpdateIds: string[];
1783
+ } | undefined;
1664
1784
  } | undefined;
1665
1785
  rosterProfileDocumentId?: string | undefined;
1666
1786
  }>>;
@@ -7,3 +7,11 @@ export declare const MAX_CONTAINER_PATH_LENGTH = 100;
7
7
  * bound keeps that capacity instead of letting a small body cite ~50x more.
8
8
  */
9
9
  export declare const MAX_CONTAINER_MANIFEST_HISTORY_REFS = 4096;
10
+ /**
11
+ * Maximum number of principal policy heads one container mutation may cite.
12
+ * Each citation makes the server verify that principal's stored policy, so
13
+ * the bound keeps the capacity inline signed policies (about 9.8 KiB each)
14
+ * had under the 32 MiB request ceiling instead of letting a ~170-byte reference
15
+ * multiply that work.
16
+ */
17
+ export declare const MAX_CONTAINER_PRINCIPAL_POLICY_REFS = 4096;
@@ -7,4 +7,12 @@ export const MAX_CONTAINER_PATH_LENGTH = 100;
7
7
  * bound keeps that capacity instead of letting a small body cite ~50x more.
8
8
  */
9
9
  export const MAX_CONTAINER_MANIFEST_HISTORY_REFS = 4096;
10
+ /**
11
+ * Maximum number of principal policy heads one container mutation may cite.
12
+ * Each citation makes the server verify that principal's stored policy, so
13
+ * the bound keeps the capacity inline signed policies (about 9.8 KiB each)
14
+ * had under the 32 MiB request ceiling instead of letting a ~170-byte reference
15
+ * multiply that work.
16
+ */
17
+ export const MAX_CONTAINER_PRINCIPAL_POLICY_REFS = 4096;
10
18
  //# sourceMappingURL=containerLimits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"containerLimits.js","sourceRoot":"","sources":["containerLimits.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,IAAI,CAAC","sourcesContent":["/** Maximum number of containers in a root-to-leaf path, including both ends. */\nexport const MAX_CONTAINER_PATH_LENGTH = 100;\n\n/**\n * Maximum number of stored manifests one container mutation may cite as the\n * mutated container's history. Inline bundles (8-14 KiB each) fit about this\n * many under the 32 MiB request ceiling; a reference is ~150 bytes, so the\n * bound keeps that capacity instead of letting a small body cite ~50x more.\n */\nexport const MAX_CONTAINER_MANIFEST_HISTORY_REFS = 4096;\n"]}
1
+ {"version":3,"file":"containerLimits.js","sourceRoot":"","sources":["containerLimits.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,IAAI,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,IAAI,CAAC","sourcesContent":["/** Maximum number of containers in a root-to-leaf path, including both ends. */\nexport const MAX_CONTAINER_PATH_LENGTH = 100;\n\n/**\n * Maximum number of stored manifests one container mutation may cite as the\n * mutated container's history. Inline bundles (8-14 KiB each) fit about this\n * many under the 32 MiB request ceiling; a reference is ~150 bytes, so the\n * bound keeps that capacity instead of letting a small body cite ~50x more.\n */\nexport const MAX_CONTAINER_MANIFEST_HISTORY_REFS = 4096;\n\n/**\n * Maximum number of principal policy heads one container mutation may cite.\n * Each citation makes the server verify that principal's stored policy, so\n * the bound keeps the capacity inline signed policies (about 9.8 KiB each)\n * had under the 32 MiB request ceiling instead of letting a ~170-byte reference\n * multiply that work.\n */\nexport const MAX_CONTAINER_PRINCIPAL_POLICY_REFS = 4096;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tearleads/client-sdk",
3
- "version": "0.1.68",
3
+ "version": "0.1.71",
4
4
  "description": "React-free Tearleads client runtime: local SQLite persistence, keys, sync, encrypted blobs, and domain workflows.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -4,6 +4,8 @@ import { removeMissingContainerState } from "./missingContainerState.js";
4
4
  export async function persistContainerState(state, containerState, options = {}) {
5
5
  const { expectedStateWhenMissing, isCurrent, updateView = true } = options;
6
6
  const persisted = await persistContainerMetadataStateFromRuntime({
7
+ acceptedPendingUpdateIds: options.acceptedPendingUpdateIds,
8
+ clearSyncFailure: options.clearSyncFailure,
7
9
  metadataState: containerState,
8
10
  localMetadataPatch: options.localMetadataPatch,
9
11
  localUpdate: options.localUpdate,
@@ -1 +1 @@
1
- {"version":3,"file":"containerStatePersistence.js","sourceRoot":"","sources":["containerStatePersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAC9B,wCAAwC,GACzC,MAAM,gDAAgD,CAAC;AAExD,OAAO,EAAE,+BAA+B,EAAE,MAAM,UAAU,CAAC;AAG3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAsBtE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAkC,EAClC,cAA8B,EAC9B,UAAwC,EAAE;IAE1C,MAAM,EAAE,wBAAwB,EAAE,SAAS,EAAE,UAAU,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IAC3E,MAAM,SAAS,GAAG,MAAM,wCAAwC,CAAC;QAC/D,aAAa,EAAE,cAAc;QAC7B,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;QAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;QACtD,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,mCAAmC,EACjC,OAAO,CAAC,mCAAmC;QAC7C,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,YAAY,EAAE,SAAS;KACxB,CAAC,CAAC;IACH,IAAI,SAAS,EAAE,EAAE,KAAK,KAAK,EAAE,CAAC;QAC5B,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,2BAA2B,CACzB,KAAK,EACL,wBAAwB,IAAI,cAAc,CAC3C,CAAC;QACF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/B,CAAC;IACD,cAAc,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC;IAC/C,8BAA8B,CAAC,cAAc,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACjE,IAAI,SAAS,CAAC,kBAAkB,IAAI,SAAS,CAAC,sBAAsB,EAAE,CAAC;QACrE,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC1E,IAAI,WAAW,IAAI,WAAW,KAAK,cAAc,EAAE,CAAC;YAClD,WAAW,CAAC,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC;YACjD,WAAW,CAAC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAC;YACrC,WAAW,CAAC,wBAAwB;gBAClC,cAAc,CAAC,wBAAwB,CAAC;YAC1C,8BAA8B,CAAC,WAAW,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAChE,CAAC;QACD,sEAAsE;QACtE,2EAA2E;QAC3E,2EAA2E;QAC3E,+BAA+B,CAAC,KAAK,CAAC,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,+BAA+B,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM;QACxB,MAAM,EAAE,WAAW;QACnB,GAAG,CAAC,SAAS,CAAC,mBAAmB;YAC/B,CAAC,CAAC,EAAE,mBAAmB,EAAE,IAAa,EAAE;YACxC,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,SAAS,CAAC,iBAAiB;YAC7B,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAa,EAAE;YACtC,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC","sourcesContent":["import {\n installContainerMetadataRecord,\n persistContainerMetadataStateFromRuntime,\n} from \"../../../workflows/container-contents/metadata\";\nimport type { PersistContainerStateResult } from \"../../../workflows/container-contents/remoteHydration\";\nimport { updateContainerContentsSnapshot } from \"../state\";\nimport type { ContainerState } from \"../syncAgent\";\nimport type { ContainerContentsStoreState } from \"../types\";\nimport { removeMissingContainerState } from \"./missingContainerState\";\n\ntype MetadataPersistenceInput = Parameters<\n typeof persistContainerMetadataStateFromRuntime\n>[0];\n\ninterface PersistContainerStateOptions\n extends Pick<\n MetadataPersistenceInput,\n | \"patch\"\n | \"saveOptions\"\n | \"localMetadataPatch\"\n | \"localUpdate\"\n | \"createIntentSettlement\"\n | \"moveIntentSettlement\"\n | \"preserveDurableStructureWhenPending\"\n > {\n expectedStateWhenMissing?: ContainerState | undefined;\n isCurrent?: (() => boolean) | undefined;\n updateView?: boolean | undefined;\n}\n\nexport async function persistContainerState(\n state: ContainerContentsStoreState,\n containerState: ContainerState,\n options: PersistContainerStateOptions = {},\n): Promise<PersistContainerStateResult> {\n const { expectedStateWhenMissing, isCurrent, updateView = true } = options;\n const persisted = await persistContainerMetadataStateFromRuntime({\n metadataState: containerState,\n localMetadataPatch: options.localMetadataPatch,\n localUpdate: options.localUpdate,\n patch: options.patch ?? {},\n persistence: state.persistence,\n createIntentSettlement: options.createIntentSettlement,\n moveIntentSettlement: options.moveIntentSettlement,\n preserveDurableStructureWhenPending:\n options.preserveDurableStructureWhenPending,\n runtime: state.runtime,\n saveOptions: options.saveOptions,\n stillCurrent: isCurrent,\n });\n if (isCurrent?.() === false) {\n return { status: \"stale-generation\" };\n }\n if (!persisted) {\n removeMissingContainerState(\n state,\n expectedStateWhenMissing ?? containerState,\n );\n return { status: \"missing\" };\n }\n containerState.container = persisted.container;\n installContainerMetadataRecord(containerState, persisted.record);\n if (persisted.mutationSuperseded || persisted.syncIdentitySuperseded) {\n const cachedState = state.containersById.get(containerState.container.id);\n if (cachedState && cachedState !== containerState) {\n cachedState.container = containerState.container;\n cachedState.doc = containerState.doc;\n cachedState.metadataWriterProjection =\n containerState.metadataWriterProjection;\n installContainerMetadataRecord(cachedState, persisted.record);\n }\n // The requested structural mutation was not applied. Refresh from the\n // authoritative state installed above, but make the caller fail explicitly\n // so it cannot schedule sync or report the dropped mutation as successful.\n updateContainerContentsSnapshot(state);\n return { record: persisted.record, status: \"identity-superseded\" };\n }\n if (updateView) {\n updateContainerContentsSnapshot(state);\n }\n return {\n record: persisted.record,\n status: \"persisted\",\n ...(persisted.createIntentSettled\n ? { createIntentSettled: true as const }\n : {}),\n ...(persisted.moveIntentSettled\n ? { moveIntentSettled: true as const }\n : {}),\n };\n}\n"]}
1
+ {"version":3,"file":"containerStatePersistence.js","sourceRoot":"","sources":["containerStatePersistence.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n installContainerMetadataRecord,\n persistContainerMetadataStateFromRuntime,\n} from \"../../../workflows/container-contents/metadata\";\nimport type { PersistContainerStateResult } from \"../../../workflows/container-contents/remoteHydration\";\nimport { updateContainerContentsSnapshot } from \"../state\";\nimport type { ContainerState } from \"../syncAgent\";\nimport type { ContainerContentsStoreState } from \"../types\";\nimport { removeMissingContainerState } from \"./missingContainerState\";\n\ntype MetadataPersistenceInput = Parameters<\n typeof persistContainerMetadataStateFromRuntime\n>[0];\n\ninterface PersistContainerStateOptions\n extends Pick<\n MetadataPersistenceInput,\n | \"acceptedPendingUpdateIds\"\n | \"clearSyncFailure\"\n | \"patch\"\n | \"saveOptions\"\n | \"localMetadataPatch\"\n | \"localUpdate\"\n | \"createIntentSettlement\"\n | \"moveIntentSettlement\"\n | \"preserveDurableStructureWhenPending\"\n > {\n expectedStateWhenMissing?: ContainerState | undefined;\n isCurrent?: (() => boolean) | undefined;\n updateView?: boolean | undefined;\n}\n\nexport async function persistContainerState(\n state: ContainerContentsStoreState,\n containerState: ContainerState,\n options: PersistContainerStateOptions = {},\n): Promise<PersistContainerStateResult> {\n const { expectedStateWhenMissing, isCurrent, updateView = true } = options;\n const persisted = await persistContainerMetadataStateFromRuntime({\n acceptedPendingUpdateIds: options.acceptedPendingUpdateIds,\n clearSyncFailure: options.clearSyncFailure,\n metadataState: containerState,\n localMetadataPatch: options.localMetadataPatch,\n localUpdate: options.localUpdate,\n patch: options.patch ?? {},\n persistence: state.persistence,\n createIntentSettlement: options.createIntentSettlement,\n moveIntentSettlement: options.moveIntentSettlement,\n preserveDurableStructureWhenPending:\n options.preserveDurableStructureWhenPending,\n runtime: state.runtime,\n saveOptions: options.saveOptions,\n stillCurrent: isCurrent,\n });\n if (isCurrent?.() === false) {\n return { status: \"stale-generation\" };\n }\n if (!persisted) {\n removeMissingContainerState(\n state,\n expectedStateWhenMissing ?? containerState,\n );\n return { status: \"missing\" };\n }\n containerState.container = persisted.container;\n installContainerMetadataRecord(containerState, persisted.record);\n if (persisted.mutationSuperseded || persisted.syncIdentitySuperseded) {\n const cachedState = state.containersById.get(containerState.container.id);\n if (cachedState && cachedState !== containerState) {\n cachedState.container = containerState.container;\n cachedState.doc = containerState.doc;\n cachedState.metadataWriterProjection =\n containerState.metadataWriterProjection;\n installContainerMetadataRecord(cachedState, persisted.record);\n }\n // The requested structural mutation was not applied. Refresh from the\n // authoritative state installed above, but make the caller fail explicitly\n // so it cannot schedule sync or report the dropped mutation as successful.\n updateContainerContentsSnapshot(state);\n return { record: persisted.record, status: \"identity-superseded\" };\n }\n if (updateView) {\n updateContainerContentsSnapshot(state);\n }\n return {\n record: persisted.record,\n status: \"persisted\",\n ...(persisted.createIntentSettled\n ? { createIntentSettled: true as const }\n : {}),\n ...(persisted.moveIntentSettled\n ? { moveIntentSettled: true as const }\n : {}),\n };\n}\n"]}
@@ -26,7 +26,7 @@ export function handleContainerContentsRemoteEvents(input) {
26
26
  if (addedHydrationLane) {
27
27
  observeContainerBackgroundHydration(state, requestHydration());
28
28
  }
29
- const metadataDocumentIds = listContainerMetadataDocumentUpdateIds(nextEvents, state.containersById.values(), state.locallyAcceptedMetadataUpdateIds);
29
+ const metadataDocumentIds = listContainerMetadataDocumentUpdateIds(nextEvents, state.containersById.values(), state.locallyAcceptedMetadataUpdateIds, state.plannedMetadataDocumentIds);
30
30
  for (const metadataDocumentId of metadataDocumentIds) {
31
31
  state.metadataDocumentIdsNeedingSync.add(metadataDocumentId);
32
32
  bumpMetadataSyncSeq(state.metadataSyncSignalSeqById, metadataDocumentId);
@@ -1 +1 @@
1
- {"version":3,"file":"remoteEventSync.js","sourceRoot":"","sources":["remoteEventSync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uCAAuC,EACvC,sCAAsC,GACvC,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAE,sCAAsC,EAAE,MAAM,gDAAgD,CAAC;AACxG,OAAO,EAAE,mCAAmC,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,UAAU,mCAAmC,CAAC,KAInD;IACC,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxD,4EAA4E;IAC5E,2EAA2E;IAC3E,uEAAuE;IACvE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC1E,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACzD,2EAA2E;IAC3E,sDAAsD;IACtD,2BAA2B,CACzB,KAAK,EACL,sCAAsC,CAAC,UAAU,CAAC,CACnD,CAAC;IACF,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,KAAK,MAAM,QAAQ,IAAI,uCAAuC,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,KAAK,CAAC,kCAAkC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5D,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,KAAK,CAAC,kCAAkC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,kBAAkB,EAAE,CAAC;QACvB,mCAAmC,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,mBAAmB,GAAG,sCAAsC,CAChE,UAAU,EACV,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,EAC7B,KAAK,CAAC,gCAAgC,CACvC,CAAC;IACF,KAAK,MAAM,kBAAkB,IAAI,mBAAmB,EAAE,CAAC;QACrD,KAAK,CAAC,8BAA8B,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC7D,mBAAmB,CAAC,KAAK,CAAC,yBAAyB,EAAE,kBAAkB,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,YAAY,EAAE,CAAC;IACjB,CAAC;AACH,CAAC","sourcesContent":["import {\n listContainerParentIdsForEventHydration,\n listContainerProjectionInvalidationIds,\n} from \"../../../workflows/container-contents/containerEvents\";\nimport { listContainerMetadataDocumentUpdateIds } from \"../../../workflows/container-contents/metadata\";\nimport { observeContainerBackgroundHydration } from \"../hydration/backgroundHydration\";\nimport { bumpMetadataSyncSeq } from \"../syncAgent/metadataSyncSignal\";\nimport type { ContainerContentsStoreSyncState } from \"../syncAgent/syncAgentTypes\";\nimport { invalidateCachedProjections } from \"./remoteEventProjectionInvalidation\";\n\nexport function handleContainerContentsRemoteEvents(input: {\n requestHydration: () => Promise<void>;\n scheduleSync: () => void;\n state: ContainerContentsStoreSyncState;\n}): void {\n const { requestHydration, scheduleSync, state } = input;\n // Metadata events are classified through the initialized container records.\n // Do not consume the cursor while a replacement database is still loading;\n // initialization calls this handler again once those identities exist.\n if (!state.initialized) {\n return;\n }\n const nextEvents = state.runtime.state.events.slice(state.lastEventCount);\n state.lastEventCount = state.runtime.state.events.length;\n // A peer's grant, rekey, or recite changed a manifest this client's cached\n // projections cite, without evicting this subscriber.\n invalidateCachedProjections(\n state,\n listContainerProjectionInvalidationIds(nextEvents),\n );\n let addedHydrationLane = false;\n for (const parentId of listContainerParentIdsForEventHydration(nextEvents)) {\n if (!state.containerParentIdsNeedingHydration.has(parentId)) {\n addedHydrationLane = true;\n }\n state.containerParentIdsNeedingHydration.add(parentId);\n }\n if (addedHydrationLane) {\n observeContainerBackgroundHydration(state, requestHydration());\n }\n\n const metadataDocumentIds = listContainerMetadataDocumentUpdateIds(\n nextEvents,\n state.containersById.values(),\n state.locallyAcceptedMetadataUpdateIds,\n );\n for (const metadataDocumentId of metadataDocumentIds) {\n state.metadataDocumentIdsNeedingSync.add(metadataDocumentId);\n bumpMetadataSyncSeq(state.metadataSyncSignalSeqById, metadataDocumentId);\n }\n if (metadataDocumentIds.length > 0) {\n scheduleSync();\n }\n}\n"]}
1
+ {"version":3,"file":"remoteEventSync.js","sourceRoot":"","sources":["remoteEventSync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uCAAuC,EACvC,sCAAsC,GACvC,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAE,sCAAsC,EAAE,MAAM,gDAAgD,CAAC;AACxG,OAAO,EAAE,mCAAmC,EAAE,MAAM,kCAAkC,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAElF,MAAM,UAAU,mCAAmC,CAAC,KAInD;IACC,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxD,4EAA4E;IAC5E,2EAA2E;IAC3E,uEAAuE;IACvE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC1E,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACzD,2EAA2E;IAC3E,sDAAsD;IACtD,2BAA2B,CACzB,KAAK,EACL,sCAAsC,CAAC,UAAU,CAAC,CACnD,CAAC;IACF,IAAI,kBAAkB,GAAG,KAAK,CAAC;IAC/B,KAAK,MAAM,QAAQ,IAAI,uCAAuC,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC,KAAK,CAAC,kCAAkC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5D,kBAAkB,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,KAAK,CAAC,kCAAkC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,kBAAkB,EAAE,CAAC;QACvB,mCAAmC,CAAC,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,mBAAmB,GAAG,sCAAsC,CAChE,UAAU,EACV,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,EAC7B,KAAK,CAAC,gCAAgC,EACtC,KAAK,CAAC,0BAA0B,CACjC,CAAC;IACF,KAAK,MAAM,kBAAkB,IAAI,mBAAmB,EAAE,CAAC;QACrD,KAAK,CAAC,8BAA8B,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC7D,mBAAmB,CAAC,KAAK,CAAC,yBAAyB,EAAE,kBAAkB,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,YAAY,EAAE,CAAC;IACjB,CAAC;AACH,CAAC","sourcesContent":["import {\n listContainerParentIdsForEventHydration,\n listContainerProjectionInvalidationIds,\n} from \"../../../workflows/container-contents/containerEvents\";\nimport { listContainerMetadataDocumentUpdateIds } from \"../../../workflows/container-contents/metadata\";\nimport { observeContainerBackgroundHydration } from \"../hydration/backgroundHydration\";\nimport { bumpMetadataSyncSeq } from \"../syncAgent/metadataSyncSignal\";\nimport type { ContainerContentsStoreSyncState } from \"../syncAgent/syncAgentTypes\";\nimport { invalidateCachedProjections } from \"./remoteEventProjectionInvalidation\";\n\nexport function handleContainerContentsRemoteEvents(input: {\n requestHydration: () => Promise<void>;\n scheduleSync: () => void;\n state: ContainerContentsStoreSyncState;\n}): void {\n const { requestHydration, scheduleSync, state } = input;\n // Metadata events are classified through the initialized container records.\n // Do not consume the cursor while a replacement database is still loading;\n // initialization calls this handler again once those identities exist.\n if (!state.initialized) {\n return;\n }\n const nextEvents = state.runtime.state.events.slice(state.lastEventCount);\n state.lastEventCount = state.runtime.state.events.length;\n // A peer's grant, rekey, or recite changed a manifest this client's cached\n // projections cite, without evicting this subscriber.\n invalidateCachedProjections(\n state,\n listContainerProjectionInvalidationIds(nextEvents),\n );\n let addedHydrationLane = false;\n for (const parentId of listContainerParentIdsForEventHydration(nextEvents)) {\n if (!state.containerParentIdsNeedingHydration.has(parentId)) {\n addedHydrationLane = true;\n }\n state.containerParentIdsNeedingHydration.add(parentId);\n }\n if (addedHydrationLane) {\n observeContainerBackgroundHydration(state, requestHydration());\n }\n\n const metadataDocumentIds = listContainerMetadataDocumentUpdateIds(\n nextEvents,\n state.containersById.values(),\n state.locallyAcceptedMetadataUpdateIds,\n state.plannedMetadataDocumentIds,\n );\n for (const metadataDocumentId of metadataDocumentIds) {\n state.metadataDocumentIdsNeedingSync.add(metadataDocumentId);\n bumpMetadataSyncSeq(state.metadataSyncSignalSeqById, metadataDocumentId);\n }\n if (metadataDocumentIds.length > 0) {\n scheduleSync();\n }\n}\n"]}
@@ -63,6 +63,7 @@ export function createContainerContentsStoreState(initialRuntime, persistence, l
63
63
  metadataDocumentIdsNeedingSync: new Set(),
64
64
  metadataSyncSignalSeqById: new Map(),
65
65
  persistence,
66
+ plannedMetadataDocumentIds: new Set(),
66
67
  remoteHydrationPromise: null,
67
68
  remoteHydrationGeneration: null,
68
69
  remoteHydrationStructuralGeneration: null,
@@ -118,6 +119,7 @@ function resetContainerContentsStore(state) {
118
119
  state.locallyAcceptedMetadataUpdateIds = new Set();
119
120
  state.metadataDocumentIdsNeedingSync = new Set();
120
121
  state.metadataSyncSignalSeqById = new Map();
122
+ state.plannedMetadataDocumentIds = new Set();
121
123
  state.rootLaneHydrated = false;
122
124
  state.writeChain = Promise.resolve(null);
123
125
  setContainerContentsSnapshot(state, {
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["state.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ContainerContentsPersistence } from \"../../workflows/container-contents/containerPersistence\";\nimport {\n createContainerContentsProjectionUserKeyResolver,\n didContainerContentsProjectionKeyRuntimeChange,\n} from \"../../workflows/container-contents/projectionKeys\";\nimport { didRegainSyncPrerequisites } from \"../../workflows/container-contents/syncLane\";\nimport { ContainerStateMap } from \"./containerState/containerStateMap\";\nimport { didContainerWriteRuntimeChange } from \"./remoteWrites/writeGeneration\";\nimport type {\n ContainerContentsStoreRuntime,\n ContainerContentsStoreSyncAgent,\n} from \"./syncAgent/syncAgentTypes\";\nimport type {\n ContainerContentsSnapshot,\n ContainerContentsStoreState,\n ContainerNode,\n} from \"./types\";\nimport { getSnapshotNodes } from \"./utils\";\n\nfunction areSyncStatesEqual(\n left: ContainerNode[\"syncState\"],\n right: ContainerNode[\"syncState\"],\n): boolean {\n return (\n left.lastError === right.lastError &&\n left.pendingAttachmentBytes === right.pendingAttachmentBytes &&\n left.pendingAttachmentCount === right.pendingAttachmentCount &&\n left.pendingUpdateCount === right.pendingUpdateCount &&\n left.status === right.status\n );\n}\n\nfunction areSnapshotNodesEqual(\n left: ReadonlyArray<ContainerNode>,\n right: ReadonlyArray<ContainerNode>,\n): boolean {\n if (left.length !== right.length) {\n return false;\n }\n\n return left.every((leftNode, index) => {\n const rightNode = right[index];\n return (\n rightNode !== undefined &&\n leftNode.createdAt === rightNode.createdAt &&\n leftNode.effectiveAccessLevel === rightNode.effectiveAccessLevel &&\n leftNode.id === rightNode.id &&\n leftNode.icon === rightNode.icon &&\n leftNode.kind === rightNode.kind &&\n leftNode.metadataDocumentId === rightNode.metadataDocumentId &&\n leftNode.metadataReady === rightNode.metadataReady &&\n leftNode.name === rightNode.name &&\n leftNode.organizationId === rightNode.organizationId &&\n leftNode.parentId === rightNode.parentId &&\n areSyncStatesEqual(leftNode.syncState, rightNode.syncState) &&\n leftNode.systemSlot === rightNode.systemSlot &&\n leftNode.updatedAt === rightNode.updatedAt\n );\n });\n}\n\nfunction didStructuralRuntimeChange(\n previousRuntime: ContainerContentsStoreRuntime,\n nextRuntime: ContainerContentsStoreRuntime,\n): boolean {\n // Structural sync also depends on connectivity and event delivery. Local\n // writes use only the identity and storage checks shared below.\n return (\n didContainerWriteRuntimeChange(previousRuntime, nextRuntime) ||\n previousRuntime.state.online !== nextRuntime.state.online ||\n previousRuntime.state.peerScope !== nextRuntime.state.peerScope ||\n previousRuntime.state.serverEventsConnectionGeneration !==\n nextRuntime.state.serverEventsConnectionGeneration ||\n previousRuntime.util.isRemoteSyncBlocked !==\n nextRuntime.util.isRemoteSyncBlocked\n );\n}\n\nexport function createContainerContentsStoreState(\n initialRuntime: ContainerContentsStoreRuntime,\n persistence: ContainerContentsPersistence,\n logLabel?: string | undefined,\n): ContainerContentsStoreState {\n return {\n containersById: new ContainerStateMap(),\n containerParentIdsNeedingHydration: new Set(),\n documentStoresNeedPriming: true,\n initializeGeneration: null,\n initializePromise: null,\n initialized: false,\n localContainerRefreshPromise: null,\n localContainerRefreshGeneration: null,\n localContainerRefreshStructuralGeneration: null,\n localContainersNeedRefresh: false,\n lifecycleGeneration: 0,\n lastEventCount: 0,\n listeners: new Set(),\n locallyAcceptedMetadataUpdateIds: new Set(),\n logLabel,\n metadataDocumentIdsNeedingSync: new Set(),\n metadataSyncSignalSeqById: new Map(),\n persistence,\n remoteHydrationPromise: null,\n remoteHydrationGeneration: null,\n remoteHydrationStructuralGeneration: null,\n remoteReconnectRefreshPending: false,\n resolveProjectionUserKey:\n createContainerContentsProjectionUserKeyResolver(initialRuntime),\n rootLaneHydrated: false,\n runtime: initialRuntime,\n snapshot: {\n nodes: [],\n ready: false,\n },\n syncLane: null,\n structuralGeneration: 0,\n writeGeneration: 0,\n writeChain: Promise.resolve<ContainerNode | null>(null),\n };\n}\n\nfunction emitContainerContentsStore(state: ContainerContentsStoreState) {\n for (const listener of state.listeners) {\n listener();\n }\n}\n\nfunction setContainerContentsSnapshot(\n state: ContainerContentsStoreState,\n next: ContainerContentsSnapshot,\n) {\n if (\n next.ready === state.snapshot.ready &&\n areSnapshotNodesEqual(next.nodes, state.snapshot.nodes)\n ) {\n return;\n }\n\n state.snapshot = next;\n emitContainerContentsStore(state);\n}\n\nexport function updateContainerContentsSnapshot(\n state: ContainerContentsStoreState,\n) {\n setContainerContentsSnapshot(state, {\n nodes: getSnapshotNodes(state.containersById),\n ready: true,\n });\n}\n\nfunction resetContainerContentsStore(state: ContainerContentsStoreState) {\n state.lifecycleGeneration += 1;\n state.containersById = new ContainerStateMap();\n state.containerParentIdsNeedingHydration = new Set();\n state.documentStoresNeedPriming = true;\n state.initialized = false;\n state.localContainersNeedRefresh = false;\n // Runtime events are snapshots, not a destructive queue. A replacement\n // executor or persistence adapter has not observed any of them, even when\n // their effects were already applied to the previous database. Replay the\n // snapshot after replacement initialization rebuilds metadata identities.\n state.lastEventCount = 0;\n // Accepted-echo suppression state must not survive a reset: after a\n // database loss the tree rehydrates from remote, and a retained id would\n // suppress the next matching remote update signal. Mirrors\n // clearDocumentStoreState in the document store lane.\n state.locallyAcceptedMetadataUpdateIds = new Set();\n state.metadataDocumentIdsNeedingSync = new Set();\n state.metadataSyncSignalSeqById = new Map();\n state.rootLaneHydrated = false;\n state.writeChain = Promise.resolve<ContainerNode | null>(null);\n setContainerContentsSnapshot(state, {\n nodes: [],\n ready: false,\n });\n}\n\nexport function subscribeToContainerContentsStore(\n state: ContainerContentsStoreState,\n listener: () => void,\n) {\n state.listeners.add(listener);\n return () => state.listeners.delete(listener);\n}\n\nexport function updateContainerContentsStoreRuntime(\n state: ContainerContentsStoreState,\n nextRuntime: ContainerContentsStoreRuntime,\n syncAgent: ContainerContentsStoreSyncAgent,\n) {\n const previousRuntime = state.runtime;\n const runtimeReplaced = didStructuralRuntimeChange(\n previousRuntime,\n nextRuntime,\n );\n if (didContainerWriteRuntimeChange(previousRuntime, nextRuntime)) {\n state.writeGeneration += 1;\n }\n const executorReplaced =\n previousRuntime.infra.execSql !== nextRuntime.infra.execSql;\n const serverEventsConnectionChanged =\n previousRuntime.state.serverEventsConnectionGeneration !==\n nextRuntime.state.serverEventsConnectionGeneration;\n if (runtimeReplaced) {\n state.structuralGeneration += 1;\n state.localContainersNeedRefresh = true;\n }\n const contextChanged =\n previousRuntime.auth.organizationId !== nextRuntime.auth.organizationId ||\n previousRuntime.state.containerId !== nextRuntime.state.containerId;\n if (\n didContainerContentsProjectionKeyRuntimeChange(previousRuntime, nextRuntime)\n ) {\n state.resolveProjectionUserKey =\n createContainerContentsProjectionUserKeyResolver(nextRuntime);\n }\n state.runtime = nextRuntime;\n if (serverEventsConnectionChanged) {\n state.remoteReconnectRefreshPending = true;\n }\n\n if (nextRuntime.infra.dbStatus !== \"ready\") {\n if (state.snapshot.ready || state.initialized || state.initializePromise) {\n resetContainerContentsStore(state);\n }\n return;\n }\n\n if (executorReplaced) {\n // The in-memory tree and lane markers belong to the previous executor.\n // Rebuild them from the replacement database before any remote sync can\n // observe or persist the old database's state.\n resetContainerContentsStore(state);\n syncAgent.ensureInitialized();\n syncAgent.handleRemoteEvents();\n return;\n }\n\n // Gaining authentication within a domain scope does not change identity\n // (the scope is keyed on the signing fingerprint), so the locally-loaded\n // tree stays valid. Reconcile it in place instead of resetting — resetting\n // here is what blanked Explorer and forced a re-read on first open after\n // register. Identity/storage changes are handled by scope rotation and the\n // dbStatus-loss branch above.\n if (\n state.snapshot.ready &&\n (contextChanged || didRegainSyncPrerequisites(previousRuntime, nextRuntime))\n ) {\n state.localContainersNeedRefresh = true;\n state.documentStoresNeedPriming = true;\n void syncAgent.refreshLocalContainers();\n // The refresh alone does not run the sync lane; schedule it so newly\n // eligible documents (e.g. this organization's orphans) prime now.\n syncAgent.scheduleSync();\n }\n\n syncAgent.ensureInitialized();\n\n syncAgent.handleRemoteEvents();\n\n if (runtimeReplaced) {\n void syncAgent.refreshLocalContainers();\n syncAgent.scheduleSync();\n }\n\n consumePendingContainerContentsReconnectRefresh(state, syncAgent.refresh);\n\n if (\n state.snapshot.ready &&\n didRegainSyncPrerequisites(previousRuntime, nextRuntime)\n ) {\n // A pass blocked by missing prerequisites consumes its lane request before\n // returning early. Re-arm it directly when they return even if hydration\n // finds no remote delta; this also primes unopened document stores.\n syncAgent.scheduleSync();\n syncAgent.scheduleRemoteHydration();\n }\n}\n\nexport function consumePendingContainerContentsReconnectRefresh(\n state: {\n remoteReconnectRefreshPending: boolean;\n snapshot: { ready: boolean };\n },\n refresh: () => Promise<boolean>,\n): void {\n if (!state.snapshot.ready || !state.remoteReconnectRefreshPending) return;\n state.remoteReconnectRefreshPending = false;\n void refresh().then(\n (refreshed) => {\n if (!refreshed) state.remoteReconnectRefreshPending = true;\n },\n () => {\n state.remoteReconnectRefreshPending = true;\n },\n );\n}\n\nexport function updateContainerContentsStorePersistence(\n state: ContainerContentsStoreState,\n nextPersistence: ContainerContentsPersistence,\n syncAgent: ContainerContentsStoreSyncAgent,\n): void {\n if (state.persistence === nextPersistence) {\n return;\n }\n state.persistence = nextPersistence;\n state.structuralGeneration += 1;\n state.writeGeneration += 1;\n // Persistence replacement changes the authoritative local data source even\n // when the SQLite executor itself is stable. Clear storage-backed state and\n // let initialization load the replacement before scheduling remote work.\n resetContainerContentsStore(state);\n syncAgent.ensureInitialized();\n}\n"]}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["state.ts"],"names":[],"mappings":"AACA,OAAO,EACL,gDAAgD,EAChD,8CAA8C,GAC/C,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAUhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,SAAS,kBAAkB,CACzB,IAAgC,EAChC,KAAiC;IAEjC,OAAO,CACL,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS;QAClC,IAAI,CAAC,sBAAsB,KAAK,KAAK,CAAC,sBAAsB;QAC5D,IAAI,CAAC,sBAAsB,KAAK,KAAK,CAAC,sBAAsB;QAC5D,IAAI,CAAC,kBAAkB,KAAK,KAAK,CAAC,kBAAkB;QACpD,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAC7B,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAC5B,IAAkC,EAClC,KAAmC;IAEnC,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;QACpC,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,CACL,SAAS,KAAK,SAAS;YACvB,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS;YAC1C,QAAQ,CAAC,oBAAoB,KAAK,SAAS,CAAC,oBAAoB;YAChE,QAAQ,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE;YAC5B,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;YAChC,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;YAChC,QAAQ,CAAC,kBAAkB,KAAK,SAAS,CAAC,kBAAkB;YAC5D,QAAQ,CAAC,aAAa,KAAK,SAAS,CAAC,aAAa;YAClD,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI;YAChC,QAAQ,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc;YACpD,QAAQ,CAAC,QAAQ,KAAK,SAAS,CAAC,QAAQ;YACxC,kBAAkB,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC;YAC3D,QAAQ,CAAC,UAAU,KAAK,SAAS,CAAC,UAAU;YAC5C,QAAQ,CAAC,SAAS,KAAK,SAAS,CAAC,SAAS,CAC3C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,0BAA0B,CACjC,eAA8C,EAC9C,WAA0C;IAE1C,yEAAyE;IACzE,gEAAgE;IAChE,OAAO,CACL,8BAA8B,CAAC,eAAe,EAAE,WAAW,CAAC;QAC5D,eAAe,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,CAAC,KAAK,CAAC,MAAM;QACzD,eAAe,CAAC,KAAK,CAAC,SAAS,KAAK,WAAW,CAAC,KAAK,CAAC,SAAS;QAC/D,eAAe,CAAC,KAAK,CAAC,gCAAgC;YACpD,WAAW,CAAC,KAAK,CAAC,gCAAgC;QACpD,eAAe,CAAC,IAAI,CAAC,mBAAmB;YACtC,WAAW,CAAC,IAAI,CAAC,mBAAmB,CACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,cAA6C,EAC7C,WAAyC,EACzC,QAA6B;IAE7B,OAAO;QACL,cAAc,EAAE,IAAI,iBAAiB,EAAE;QACvC,kCAAkC,EAAE,IAAI,GAAG,EAAE;QAC7C,yBAAyB,EAAE,IAAI;QAC/B,oBAAoB,EAAE,IAAI;QAC1B,iBAAiB,EAAE,IAAI;QACvB,WAAW,EAAE,KAAK;QAClB,4BAA4B,EAAE,IAAI;QAClC,+BAA+B,EAAE,IAAI;QACrC,yCAAyC,EAAE,IAAI;QAC/C,0BAA0B,EAAE,KAAK;QACjC,mBAAmB,EAAE,CAAC;QACtB,cAAc,EAAE,CAAC;QACjB,SAAS,EAAE,IAAI,GAAG,EAAE;QACpB,gCAAgC,EAAE,IAAI,GAAG,EAAE;QAC3C,QAAQ;QACR,8BAA8B,EAAE,IAAI,GAAG,EAAE;QACzC,yBAAyB,EAAE,IAAI,GAAG,EAAE;QACpC,WAAW;QACX,0BAA0B,EAAE,IAAI,GAAG,EAAE;QACrC,sBAAsB,EAAE,IAAI;QAC5B,yBAAyB,EAAE,IAAI;QAC/B,mCAAmC,EAAE,IAAI;QACzC,6BAA6B,EAAE,KAAK;QACpC,wBAAwB,EACtB,gDAAgD,CAAC,cAAc,CAAC;QAClE,gBAAgB,EAAE,KAAK;QACvB,OAAO,EAAE,cAAc;QACvB,QAAQ,EAAE;YACR,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,KAAK;SACb;QACD,QAAQ,EAAE,IAAI;QACd,oBAAoB,EAAE,CAAC;QACvB,eAAe,EAAE,CAAC;QAClB,UAAU,EAAE,OAAO,CAAC,OAAO,CAAuB,IAAI,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAkC;IACpE,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACvC,QAAQ,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,CACnC,KAAkC,EAClC,IAA+B;IAE/B,IACE,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK;QACnC,qBAAqB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EACvD,CAAC;QACD,OAAO;IACT,CAAC;IAED,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;IACtB,0BAA0B,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC7C,KAAkC;IAElC,4BAA4B,CAAC,KAAK,EAAE;QAClC,KAAK,EAAE,gBAAgB,CAAC,KAAK,CAAC,cAAc,CAAC;QAC7C,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;AACL,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAkC;IACrE,KAAK,CAAC,mBAAmB,IAAI,CAAC,CAAC;IAC/B,KAAK,CAAC,cAAc,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAC/C,KAAK,CAAC,kCAAkC,GAAG,IAAI,GAAG,EAAE,CAAC;IACrD,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC;IACvC,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;IAC1B,KAAK,CAAC,0BAA0B,GAAG,KAAK,CAAC;IACzC,uEAAuE;IACvE,0EAA0E;IAC1E,0EAA0E;IAC1E,0EAA0E;IAC1E,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;IACzB,oEAAoE;IACpE,yEAAyE;IACzE,2DAA2D;IAC3D,sDAAsD;IACtD,KAAK,CAAC,gCAAgC,GAAG,IAAI,GAAG,EAAE,CAAC;IACnD,KAAK,CAAC,8BAA8B,GAAG,IAAI,GAAG,EAAE,CAAC;IACjD,KAAK,CAAC,yBAAyB,GAAG,IAAI,GAAG,EAAE,CAAC;IAC5C,KAAK,CAAC,0BAA0B,GAAG,IAAI,GAAG,EAAE,CAAC;IAC7C,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC/B,KAAK,CAAC,UAAU,GAAG,OAAO,CAAC,OAAO,CAAuB,IAAI,CAAC,CAAC;IAC/D,4BAA4B,CAAC,KAAK,EAAE;QAClC,KAAK,EAAE,EAAE;QACT,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,iCAAiC,CAC/C,KAAkC,EAClC,QAAoB;IAEpB,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,mCAAmC,CACjD,KAAkC,EAClC,WAA0C,EAC1C,SAA0C;IAE1C,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC;IACtC,MAAM,eAAe,GAAG,0BAA0B,CAChD,eAAe,EACf,WAAW,CACZ,CAAC;IACF,IAAI,8BAA8B,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,CAAC;QACjE,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,gBAAgB,GACpB,eAAe,CAAC,KAAK,CAAC,OAAO,KAAK,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC;IAC9D,MAAM,6BAA6B,GACjC,eAAe,CAAC,KAAK,CAAC,gCAAgC;QACtD,WAAW,CAAC,KAAK,CAAC,gCAAgC,CAAC;IACrD,IAAI,eAAe,EAAE,CAAC;QACpB,KAAK,CAAC,oBAAoB,IAAI,CAAC,CAAC;QAChC,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC;IAC1C,CAAC;IACD,MAAM,cAAc,GAClB,eAAe,CAAC,IAAI,CAAC,cAAc,KAAK,WAAW,CAAC,IAAI,CAAC,cAAc;QACvE,eAAe,CAAC,KAAK,CAAC,WAAW,KAAK,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC;IACtE,IACE,8CAA8C,CAAC,eAAe,EAAE,WAAW,CAAC,EAC5E,CAAC;QACD,KAAK,CAAC,wBAAwB;YAC5B,gDAAgD,CAAC,WAAW,CAAC,CAAC;IAClE,CAAC;IACD,KAAK,CAAC,OAAO,GAAG,WAAW,CAAC;IAC5B,IAAI,6BAA6B,EAAE,CAAC;QAClC,KAAK,CAAC,6BAA6B,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC3C,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YACzE,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,uEAAuE;QACvE,wEAAwE;QACxE,+CAA+C;QAC/C,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACnC,SAAS,CAAC,iBAAiB,EAAE,CAAC;QAC9B,SAAS,CAAC,kBAAkB,EAAE,CAAC;QAC/B,OAAO;IACT,CAAC;IAED,wEAAwE;IACxE,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,2EAA2E;IAC3E,8BAA8B;IAC9B,IACE,KAAK,CAAC,QAAQ,CAAC,KAAK;QACpB,CAAC,cAAc,IAAI,0BAA0B,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC,EAC5E,CAAC;QACD,KAAK,CAAC,0BAA0B,GAAG,IAAI,CAAC;QACxC,KAAK,CAAC,yBAAyB,GAAG,IAAI,CAAC;QACvC,KAAK,SAAS,CAAC,sBAAsB,EAAE,CAAC;QACxC,qEAAqE;QACrE,mEAAmE;QACnE,SAAS,CAAC,YAAY,EAAE,CAAC;IAC3B,CAAC;IAED,SAAS,CAAC,iBAAiB,EAAE,CAAC;IAE9B,SAAS,CAAC,kBAAkB,EAAE,CAAC;IAE/B,IAAI,eAAe,EAAE,CAAC;QACpB,KAAK,SAAS,CAAC,sBAAsB,EAAE,CAAC;QACxC,SAAS,CAAC,YAAY,EAAE,CAAC;IAC3B,CAAC;IAED,+CAA+C,CAAC,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;IAE1E,IACE,KAAK,CAAC,QAAQ,CAAC,KAAK;QACpB,0BAA0B,CAAC,eAAe,EAAE,WAAW,CAAC,EACxD,CAAC;QACD,2EAA2E;QAC3E,yEAAyE;QACzE,oEAAoE;QACpE,SAAS,CAAC,YAAY,EAAE,CAAC;QACzB,SAAS,CAAC,uBAAuB,EAAE,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,+CAA+C,CAC7D,KAGC,EACD,OAA+B;IAE/B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,6BAA6B;QAAE,OAAO;IAC1E,KAAK,CAAC,6BAA6B,GAAG,KAAK,CAAC;IAC5C,KAAK,OAAO,EAAE,CAAC,IAAI,CACjB,CAAC,SAAS,EAAE,EAAE;QACZ,IAAI,CAAC,SAAS;YAAE,KAAK,CAAC,6BAA6B,GAAG,IAAI,CAAC;IAC7D,CAAC,EACD,GAAG,EAAE;QACH,KAAK,CAAC,6BAA6B,GAAG,IAAI,CAAC;IAC7C,CAAC,CACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,KAAkC,EAClC,eAA6C,EAC7C,SAA0C;IAE1C,IAAI,KAAK,CAAC,WAAW,KAAK,eAAe,EAAE,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,KAAK,CAAC,WAAW,GAAG,eAAe,CAAC;IACpC,KAAK,CAAC,oBAAoB,IAAI,CAAC,CAAC;IAChC,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC;IAC3B,2EAA2E;IAC3E,4EAA4E;IAC5E,yEAAyE;IACzE,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACnC,SAAS,CAAC,iBAAiB,EAAE,CAAC;AAChC,CAAC","sourcesContent":["import type { ContainerContentsPersistence } from \"../../workflows/container-contents/containerPersistence\";\nimport {\n createContainerContentsProjectionUserKeyResolver,\n didContainerContentsProjectionKeyRuntimeChange,\n} from \"../../workflows/container-contents/projectionKeys\";\nimport { didRegainSyncPrerequisites } from \"../../workflows/container-contents/syncLane\";\nimport { ContainerStateMap } from \"./containerState/containerStateMap\";\nimport { didContainerWriteRuntimeChange } from \"./remoteWrites/writeGeneration\";\nimport type {\n ContainerContentsStoreRuntime,\n ContainerContentsStoreSyncAgent,\n} from \"./syncAgent/syncAgentTypes\";\nimport type {\n ContainerContentsSnapshot,\n ContainerContentsStoreState,\n ContainerNode,\n} from \"./types\";\nimport { getSnapshotNodes } from \"./utils\";\n\nfunction areSyncStatesEqual(\n left: ContainerNode[\"syncState\"],\n right: ContainerNode[\"syncState\"],\n): boolean {\n return (\n left.lastError === right.lastError &&\n left.pendingAttachmentBytes === right.pendingAttachmentBytes &&\n left.pendingAttachmentCount === right.pendingAttachmentCount &&\n left.pendingUpdateCount === right.pendingUpdateCount &&\n left.status === right.status\n );\n}\n\nfunction areSnapshotNodesEqual(\n left: ReadonlyArray<ContainerNode>,\n right: ReadonlyArray<ContainerNode>,\n): boolean {\n if (left.length !== right.length) {\n return false;\n }\n\n return left.every((leftNode, index) => {\n const rightNode = right[index];\n return (\n rightNode !== undefined &&\n leftNode.createdAt === rightNode.createdAt &&\n leftNode.effectiveAccessLevel === rightNode.effectiveAccessLevel &&\n leftNode.id === rightNode.id &&\n leftNode.icon === rightNode.icon &&\n leftNode.kind === rightNode.kind &&\n leftNode.metadataDocumentId === rightNode.metadataDocumentId &&\n leftNode.metadataReady === rightNode.metadataReady &&\n leftNode.name === rightNode.name &&\n leftNode.organizationId === rightNode.organizationId &&\n leftNode.parentId === rightNode.parentId &&\n areSyncStatesEqual(leftNode.syncState, rightNode.syncState) &&\n leftNode.systemSlot === rightNode.systemSlot &&\n leftNode.updatedAt === rightNode.updatedAt\n );\n });\n}\n\nfunction didStructuralRuntimeChange(\n previousRuntime: ContainerContentsStoreRuntime,\n nextRuntime: ContainerContentsStoreRuntime,\n): boolean {\n // Structural sync also depends on connectivity and event delivery. Local\n // writes use only the identity and storage checks shared below.\n return (\n didContainerWriteRuntimeChange(previousRuntime, nextRuntime) ||\n previousRuntime.state.online !== nextRuntime.state.online ||\n previousRuntime.state.peerScope !== nextRuntime.state.peerScope ||\n previousRuntime.state.serverEventsConnectionGeneration !==\n nextRuntime.state.serverEventsConnectionGeneration ||\n previousRuntime.util.isRemoteSyncBlocked !==\n nextRuntime.util.isRemoteSyncBlocked\n );\n}\n\nexport function createContainerContentsStoreState(\n initialRuntime: ContainerContentsStoreRuntime,\n persistence: ContainerContentsPersistence,\n logLabel?: string | undefined,\n): ContainerContentsStoreState {\n return {\n containersById: new ContainerStateMap(),\n containerParentIdsNeedingHydration: new Set(),\n documentStoresNeedPriming: true,\n initializeGeneration: null,\n initializePromise: null,\n initialized: false,\n localContainerRefreshPromise: null,\n localContainerRefreshGeneration: null,\n localContainerRefreshStructuralGeneration: null,\n localContainersNeedRefresh: false,\n lifecycleGeneration: 0,\n lastEventCount: 0,\n listeners: new Set(),\n locallyAcceptedMetadataUpdateIds: new Set(),\n logLabel,\n metadataDocumentIdsNeedingSync: new Set(),\n metadataSyncSignalSeqById: new Map(),\n persistence,\n plannedMetadataDocumentIds: new Set(),\n remoteHydrationPromise: null,\n remoteHydrationGeneration: null,\n remoteHydrationStructuralGeneration: null,\n remoteReconnectRefreshPending: false,\n resolveProjectionUserKey:\n createContainerContentsProjectionUserKeyResolver(initialRuntime),\n rootLaneHydrated: false,\n runtime: initialRuntime,\n snapshot: {\n nodes: [],\n ready: false,\n },\n syncLane: null,\n structuralGeneration: 0,\n writeGeneration: 0,\n writeChain: Promise.resolve<ContainerNode | null>(null),\n };\n}\n\nfunction emitContainerContentsStore(state: ContainerContentsStoreState) {\n for (const listener of state.listeners) {\n listener();\n }\n}\n\nfunction setContainerContentsSnapshot(\n state: ContainerContentsStoreState,\n next: ContainerContentsSnapshot,\n) {\n if (\n next.ready === state.snapshot.ready &&\n areSnapshotNodesEqual(next.nodes, state.snapshot.nodes)\n ) {\n return;\n }\n\n state.snapshot = next;\n emitContainerContentsStore(state);\n}\n\nexport function updateContainerContentsSnapshot(\n state: ContainerContentsStoreState,\n) {\n setContainerContentsSnapshot(state, {\n nodes: getSnapshotNodes(state.containersById),\n ready: true,\n });\n}\n\nfunction resetContainerContentsStore(state: ContainerContentsStoreState) {\n state.lifecycleGeneration += 1;\n state.containersById = new ContainerStateMap();\n state.containerParentIdsNeedingHydration = new Set();\n state.documentStoresNeedPriming = true;\n state.initialized = false;\n state.localContainersNeedRefresh = false;\n // Runtime events are snapshots, not a destructive queue. A replacement\n // executor or persistence adapter has not observed any of them, even when\n // their effects were already applied to the previous database. Replay the\n // snapshot after replacement initialization rebuilds metadata identities.\n state.lastEventCount = 0;\n // Accepted-echo suppression state must not survive a reset: after a\n // database loss the tree rehydrates from remote, and a retained id would\n // suppress the next matching remote update signal. Mirrors\n // clearDocumentStoreState in the document store lane.\n state.locallyAcceptedMetadataUpdateIds = new Set();\n state.metadataDocumentIdsNeedingSync = new Set();\n state.metadataSyncSignalSeqById = new Map();\n state.plannedMetadataDocumentIds = new Set();\n state.rootLaneHydrated = false;\n state.writeChain = Promise.resolve<ContainerNode | null>(null);\n setContainerContentsSnapshot(state, {\n nodes: [],\n ready: false,\n });\n}\n\nexport function subscribeToContainerContentsStore(\n state: ContainerContentsStoreState,\n listener: () => void,\n) {\n state.listeners.add(listener);\n return () => state.listeners.delete(listener);\n}\n\nexport function updateContainerContentsStoreRuntime(\n state: ContainerContentsStoreState,\n nextRuntime: ContainerContentsStoreRuntime,\n syncAgent: ContainerContentsStoreSyncAgent,\n) {\n const previousRuntime = state.runtime;\n const runtimeReplaced = didStructuralRuntimeChange(\n previousRuntime,\n nextRuntime,\n );\n if (didContainerWriteRuntimeChange(previousRuntime, nextRuntime)) {\n state.writeGeneration += 1;\n }\n const executorReplaced =\n previousRuntime.infra.execSql !== nextRuntime.infra.execSql;\n const serverEventsConnectionChanged =\n previousRuntime.state.serverEventsConnectionGeneration !==\n nextRuntime.state.serverEventsConnectionGeneration;\n if (runtimeReplaced) {\n state.structuralGeneration += 1;\n state.localContainersNeedRefresh = true;\n }\n const contextChanged =\n previousRuntime.auth.organizationId !== nextRuntime.auth.organizationId ||\n previousRuntime.state.containerId !== nextRuntime.state.containerId;\n if (\n didContainerContentsProjectionKeyRuntimeChange(previousRuntime, nextRuntime)\n ) {\n state.resolveProjectionUserKey =\n createContainerContentsProjectionUserKeyResolver(nextRuntime);\n }\n state.runtime = nextRuntime;\n if (serverEventsConnectionChanged) {\n state.remoteReconnectRefreshPending = true;\n }\n\n if (nextRuntime.infra.dbStatus !== \"ready\") {\n if (state.snapshot.ready || state.initialized || state.initializePromise) {\n resetContainerContentsStore(state);\n }\n return;\n }\n\n if (executorReplaced) {\n // The in-memory tree and lane markers belong to the previous executor.\n // Rebuild them from the replacement database before any remote sync can\n // observe or persist the old database's state.\n resetContainerContentsStore(state);\n syncAgent.ensureInitialized();\n syncAgent.handleRemoteEvents();\n return;\n }\n\n // Gaining authentication within a domain scope does not change identity\n // (the scope is keyed on the signing fingerprint), so the locally-loaded\n // tree stays valid. Reconcile it in place instead of resetting — resetting\n // here is what blanked Explorer and forced a re-read on first open after\n // register. Identity/storage changes are handled by scope rotation and the\n // dbStatus-loss branch above.\n if (\n state.snapshot.ready &&\n (contextChanged || didRegainSyncPrerequisites(previousRuntime, nextRuntime))\n ) {\n state.localContainersNeedRefresh = true;\n state.documentStoresNeedPriming = true;\n void syncAgent.refreshLocalContainers();\n // The refresh alone does not run the sync lane; schedule it so newly\n // eligible documents (e.g. this organization's orphans) prime now.\n syncAgent.scheduleSync();\n }\n\n syncAgent.ensureInitialized();\n\n syncAgent.handleRemoteEvents();\n\n if (runtimeReplaced) {\n void syncAgent.refreshLocalContainers();\n syncAgent.scheduleSync();\n }\n\n consumePendingContainerContentsReconnectRefresh(state, syncAgent.refresh);\n\n if (\n state.snapshot.ready &&\n didRegainSyncPrerequisites(previousRuntime, nextRuntime)\n ) {\n // A pass blocked by missing prerequisites consumes its lane request before\n // returning early. Re-arm it directly when they return even if hydration\n // finds no remote delta; this also primes unopened document stores.\n syncAgent.scheduleSync();\n syncAgent.scheduleRemoteHydration();\n }\n}\n\nexport function consumePendingContainerContentsReconnectRefresh(\n state: {\n remoteReconnectRefreshPending: boolean;\n snapshot: { ready: boolean };\n },\n refresh: () => Promise<boolean>,\n): void {\n if (!state.snapshot.ready || !state.remoteReconnectRefreshPending) return;\n state.remoteReconnectRefreshPending = false;\n void refresh().then(\n (refreshed) => {\n if (!refreshed) state.remoteReconnectRefreshPending = true;\n },\n () => {\n state.remoteReconnectRefreshPending = true;\n },\n );\n}\n\nexport function updateContainerContentsStorePersistence(\n state: ContainerContentsStoreState,\n nextPersistence: ContainerContentsPersistence,\n syncAgent: ContainerContentsStoreSyncAgent,\n): void {\n if (state.persistence === nextPersistence) {\n return;\n }\n state.persistence = nextPersistence;\n state.structuralGeneration += 1;\n state.writeGeneration += 1;\n // Persistence replacement changes the authoritative local data source even\n // when the SQLite executor itself is stable. Clear storage-backed state and\n // let initialization load the replacement before scheduling remote work.\n resetContainerContentsStore(state);\n syncAgent.ensureInitialized();\n}\n"]}
@@ -64,6 +64,11 @@ export interface ContainerContentsStoreSyncState {
64
64
  * `clearMetadataSyncQueueIfUnchanged`.
65
65
  */
66
66
  metadataSyncSignalSeqById: Map<string, number>;
67
+ /**
68
+ * Metadata document ids of folder creates in flight. A remote hint for one
69
+ * queues the folder's first read before the create response installs the id.
70
+ */
71
+ plannedMetadataDocumentIds: Set<string>;
67
72
  containerParentIdsNeedingHydration: Set<string | null>;
68
73
  persistence: ContainerContentsPersistence;
69
74
  remoteHydrationPromise: Promise<void> | null;
@@ -1 +1 @@
1
- {"version":3,"file":"syncAgentTypes.js","sourceRoot":"","sources":["syncAgentTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerContentsPersistence } from \"../../../workflows/container-contents/containerPersistence\";\nimport type { ContainerContentsProjectionUserKeyResolver } from \"../../../workflows/container-contents/projectionKeys\";\nimport type {\n ContainerState,\n RemoteContainer,\n} from \"../../../workflows/container-contents/remoteHydration\";\nimport type { ContainerContentsStoreWorkflowRuntime } from \"../../../workflows/container-contents/runtime\";\nimport type { ContainerContentsSyncLane } from \"../../../workflows/container-contents/syncLane\";\n\nexport type ContainerContentsStoreRuntime =\n ContainerContentsStoreWorkflowRuntime;\n\nexport interface RefreshRootLaneOptions {\n readonly includeActiveRootChildLane?: boolean | undefined;\n // Extra parent lanes to re-list alongside the root lane. Used by the\n // resync_required handler to re-list affected containers' parent lanes so a\n // tombstone only visible there is still applied without the full crawl.\n readonly parentIds?: ReadonlyArray<string | null> | undefined;\n}\n\nexport interface ContainerContentsStoreSyncAgent {\n ensureInitialized: () => void;\n handleRemoteEvents: () => void;\n ingestRemoteContainer: (remoteContainer: RemoteContainer) => Promise<void>;\n primeDocumentsForSharedSubtree: (\n rootContainerId: string,\n isCurrent?: (() => boolean) | undefined,\n ) => Promise<void>;\n refreshLocalContainers: () => Promise<void>;\n refresh: (options?: { resetAllLaneWatermarks?: boolean }) => Promise<boolean>;\n refreshRootLane: (options?: RefreshRootLaneOptions) => Promise<boolean>;\n requestRemoteHydration: (options?: {\n followDiscoveredParentLanes?: boolean | undefined;\n parentIds?: ReadonlyArray<string | null> | undefined;\n resetAllLaneWatermarks?: boolean | undefined;\n }) => Promise<void>;\n scheduleRemoteHydration: () => void;\n scheduleSync: () => void;\n}\n\nexport interface ContainerContentsStoreSyncState {\n containersById: Map<string, ContainerState>;\n documentStoresNeedPriming: boolean;\n initializeGeneration: number | null;\n initializePromise: Promise<void> | null;\n initialized: boolean;\n localContainerRefreshPromise: Promise<void> | null;\n localContainerRefreshGeneration: number | null;\n localContainerRefreshStructuralGeneration: number | null;\n localContainersNeedRefresh: boolean;\n /** Invalidates asynchronous hydration work when this store is reset. */\n lifecycleGeneration: number;\n /** Invalidates structural work when its runtime or persistence is replaced. */\n structuralGeneration: number;\n /** Invalidates writes across write-relevant runtime ABA transitions. */\n writeGeneration: number;\n lastEventCount: number;\n /**\n * Update ids this client sent for container metadata documents, registered\n * before the network await of each metadata sync pass. The author's own\n * `document_update_created` echo consumes its ids here instead of arming a\n * redundant forced read-sync; a genuine peer update always carries unknown\n * ids and still forces one. Shared across all metadata docs in the store —\n * update ids are globally unique.\n */\n locallyAcceptedMetadataUpdateIds: Set<string>;\n logLabel?: string | undefined;\n metadataDocumentIdsNeedingSync: Set<string>;\n /**\n * Per-metadata-document enqueue sequence. Bumped for a specific id whenever a\n * remote event re-queues it in {@link metadataDocumentIdsNeedingSync}. A sync\n * pass snapshots the id's sequence before its GET and only clears the id if it\n * is unchanged at pass end, so a mid-pass re-queue of THIS container is not\n * erased. Keyed per id (not a single global counter) so a remote event for an\n * unrelated container does not force a redundant re-sync of this one. See\n * `clearMetadataSyncQueueIfUnchanged`.\n */\n metadataSyncSignalSeqById: Map<string, number>;\n containerParentIdsNeedingHydration: Set<string | null>;\n persistence: ContainerContentsPersistence;\n remoteHydrationPromise: Promise<void> | null;\n remoteHydrationGeneration: number | null;\n remoteHydrationStructuralGeneration: number | null;\n remoteReconnectRefreshPending: boolean;\n resolveProjectionUserKey: ContainerContentsProjectionUserKeyResolver;\n /** True after this store has fully applied an authoritative root lane. */\n rootLaneHydrated: boolean;\n runtime: ContainerContentsStoreRuntime;\n snapshot: { ready: boolean };\n syncLane: ContainerContentsSyncLane | null;\n}\n"]}
1
+ {"version":3,"file":"syncAgentTypes.js","sourceRoot":"","sources":["syncAgentTypes.ts"],"names":[],"mappings":"","sourcesContent":["import type { ContainerContentsPersistence } from \"../../../workflows/container-contents/containerPersistence\";\nimport type { ContainerContentsProjectionUserKeyResolver } from \"../../../workflows/container-contents/projectionKeys\";\nimport type {\n ContainerState,\n RemoteContainer,\n} from \"../../../workflows/container-contents/remoteHydration\";\nimport type { ContainerContentsStoreWorkflowRuntime } from \"../../../workflows/container-contents/runtime\";\nimport type { ContainerContentsSyncLane } from \"../../../workflows/container-contents/syncLane\";\n\nexport type ContainerContentsStoreRuntime =\n ContainerContentsStoreWorkflowRuntime;\n\nexport interface RefreshRootLaneOptions {\n readonly includeActiveRootChildLane?: boolean | undefined;\n // Extra parent lanes to re-list alongside the root lane. Used by the\n // resync_required handler to re-list affected containers' parent lanes so a\n // tombstone only visible there is still applied without the full crawl.\n readonly parentIds?: ReadonlyArray<string | null> | undefined;\n}\n\nexport interface ContainerContentsStoreSyncAgent {\n ensureInitialized: () => void;\n handleRemoteEvents: () => void;\n ingestRemoteContainer: (remoteContainer: RemoteContainer) => Promise<void>;\n primeDocumentsForSharedSubtree: (\n rootContainerId: string,\n isCurrent?: (() => boolean) | undefined,\n ) => Promise<void>;\n refreshLocalContainers: () => Promise<void>;\n refresh: (options?: { resetAllLaneWatermarks?: boolean }) => Promise<boolean>;\n refreshRootLane: (options?: RefreshRootLaneOptions) => Promise<boolean>;\n requestRemoteHydration: (options?: {\n followDiscoveredParentLanes?: boolean | undefined;\n parentIds?: ReadonlyArray<string | null> | undefined;\n resetAllLaneWatermarks?: boolean | undefined;\n }) => Promise<void>;\n scheduleRemoteHydration: () => void;\n scheduleSync: () => void;\n}\n\nexport interface ContainerContentsStoreSyncState {\n containersById: Map<string, ContainerState>;\n documentStoresNeedPriming: boolean;\n initializeGeneration: number | null;\n initializePromise: Promise<void> | null;\n initialized: boolean;\n localContainerRefreshPromise: Promise<void> | null;\n localContainerRefreshGeneration: number | null;\n localContainerRefreshStructuralGeneration: number | null;\n localContainersNeedRefresh: boolean;\n /** Invalidates asynchronous hydration work when this store is reset. */\n lifecycleGeneration: number;\n /** Invalidates structural work when its runtime or persistence is replaced. */\n structuralGeneration: number;\n /** Invalidates writes across write-relevant runtime ABA transitions. */\n writeGeneration: number;\n lastEventCount: number;\n /**\n * Update ids this client sent for container metadata documents, registered\n * before the network await of each metadata sync pass. The author's own\n * `document_update_created` echo consumes its ids here instead of arming a\n * redundant forced read-sync; a genuine peer update always carries unknown\n * ids and still forces one. Shared across all metadata docs in the store —\n * update ids are globally unique.\n */\n locallyAcceptedMetadataUpdateIds: Set<string>;\n logLabel?: string | undefined;\n metadataDocumentIdsNeedingSync: Set<string>;\n /**\n * Per-metadata-document enqueue sequence. Bumped for a specific id whenever a\n * remote event re-queues it in {@link metadataDocumentIdsNeedingSync}. A sync\n * pass snapshots the id's sequence before its GET and only clears the id if it\n * is unchanged at pass end, so a mid-pass re-queue of THIS container is not\n * erased. Keyed per id (not a single global counter) so a remote event for an\n * unrelated container does not force a redundant re-sync of this one. See\n * `clearMetadataSyncQueueIfUnchanged`.\n */\n metadataSyncSignalSeqById: Map<string, number>;\n /**\n * Metadata document ids of folder creates in flight. A remote hint for one\n * queues the folder's first read before the create response installs the id.\n */\n plannedMetadataDocumentIds: Set<string>;\n containerParentIdsNeedingHydration: Set<string | null>;\n persistence: ContainerContentsPersistence;\n remoteHydrationPromise: Promise<void> | null;\n remoteHydrationGeneration: number | null;\n remoteHydrationStructuralGeneration: number | null;\n remoteReconnectRefreshPending: boolean;\n resolveProjectionUserKey: ContainerContentsProjectionUserKeyResolver;\n /** True after this store has fully applied an authoritative root lane. */\n rootLaneHydrated: boolean;\n runtime: ContainerContentsStoreRuntime;\n snapshot: { ready: boolean };\n syncLane: ContainerContentsSyncLane | null;\n}\n"]}
@@ -0,0 +1,71 @@
1
+ import { mergeVersionVectors } from "../../../../internal/loro/index.js";
2
+ import { persistDocument } from "../persistence.js";
3
+ /**
4
+ * How a create that committed `seedUpdate` settles it: the row is accepted,
5
+ * the commit position is the one its first sync would have recorded, and the
6
+ * outgoing marker and frontier advance over it as the coverage pass would
7
+ * have (see `prepareDocumentOutgoingCoverage`). Null when the create did not
8
+ * commit the seed (a plain fallback or an adoption): the row stays queued and
9
+ * syncs as before.
10
+ */
11
+ function committedSeedSettlement(input) {
12
+ const { seedUpdate } = input;
13
+ const seed = input.created.response?.initialSync;
14
+ if (!seedUpdate ||
15
+ input.pendingBaseVersion === null ||
16
+ !seed?.acceptedOutgoingUpdateIds.includes(seedUpdate.id)) {
17
+ return null;
18
+ }
19
+ const baseVersion = mergeVersionVectors([
20
+ input.pendingBaseVersion,
21
+ seedUpdate.partialEndVersionVector,
22
+ ]);
23
+ const liveFrontier = input.liveRecord?.snapshotEndVersion ?? "";
24
+ return {
25
+ baseVersion,
26
+ options: {
27
+ acceptedPendingUpdateIds: [seedUpdate.id],
28
+ clearSyncFailure: true,
29
+ pendingBaseVersionOverride: baseVersion,
30
+ },
31
+ patch: {
32
+ lastCommitLsn: seed.commitLsn,
33
+ snapshotEndVersion: mergeVersionVectors([
34
+ ...(liveFrontier.length > 0 ? [liveFrontier] : []),
35
+ baseVersion,
36
+ ]),
37
+ },
38
+ };
39
+ }
40
+ /**
41
+ * Persists a just-created remote identity (documentId and content keys), and
42
+ * settles the create's seed when it committed. Preserves the optimistic
43
+ * snapshot fields: the user may have kept typing during the round trip.
44
+ */
45
+ export async function persistCreatedRemoteDocument(input) {
46
+ const { state } = input;
47
+ const settlement = committedSeedSettlement({
48
+ created: input.created,
49
+ liveRecord: state.record,
50
+ pendingBaseVersion: state.pendingBaseVersion,
51
+ seedUpdate: input.seed?.update,
52
+ });
53
+ const persisted = await persistDocument(state, input.currentDoc, { ...input.created.persistedState, ...settlement?.patch }, {
54
+ ...settlement?.options,
55
+ preserveSnapshotStructuredFields: true,
56
+ preserveSnapshotText: true,
57
+ }, input.generation);
58
+ if (persisted && settlement) {
59
+ // As the coverage pass does: merge, so a concurrent local write that
60
+ // advanced the in-memory marker is never moved backwards.
61
+ if (state.pendingBaseVersion !== null) {
62
+ state.pendingBaseVersion = mergeVersionVectors([
63
+ state.pendingBaseVersion,
64
+ settlement.baseVersion,
65
+ ]);
66
+ }
67
+ input.seed?.onCommitted();
68
+ }
69
+ return persisted;
70
+ }
71
+ //# sourceMappingURL=createdDocumentPersistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createdDocumentPersistence.js","sourceRoot":"","sources":["createdDocumentPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAMtD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAmBjD;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAAC,KAKhC;IAKC,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,WAAW,CAAC;IACjD,IACE,CAAC,UAAU;QACX,KAAK,CAAC,kBAAkB,KAAK,IAAI;QACjC,CAAC,IAAI,EAAE,yBAAyB,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,EACxD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,WAAW,GAAG,mBAAmB,CAAC;QACtC,KAAK,CAAC,kBAAkB;QACxB,UAAU,CAAC,uBAAuB;KACnC,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,KAAK,CAAC,UAAU,EAAE,kBAAkB,IAAI,EAAE,CAAC;IAChE,OAAO;QACL,WAAW;QACX,OAAO,EAAE;YACP,wBAAwB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,gBAAgB,EAAE,IAAI;YACtB,0BAA0B,EAAE,WAAW;SACxC;QACD,KAAK,EAAE;YACL,aAAa,EAAE,IAAI,CAAC,SAAS;YAC7B,kBAAkB,EAAE,mBAAmB,CAAC;gBACtC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,WAAW;aACZ,CAAC;SACH;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAAC,KAMlD;IACC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACxB,MAAM,UAAU,GAAG,uBAAuB,CAAC;QACzC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;QAC5C,UAAU,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM;KAC/B,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,MAAM,eAAe,CACrC,KAAK,EACL,KAAK,CAAC,UAAU,EAChB,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,GAAG,UAAU,EAAE,KAAK,EAAE,EACzD;QACE,GAAG,UAAU,EAAE,OAAO;QACtB,gCAAgC,EAAE,IAAI;QACtC,oBAAoB,EAAE,IAAI;KAC3B,EACD,KAAK,CAAC,UAAU,CACjB,CAAC;IACF,IAAI,SAAS,IAAI,UAAU,EAAE,CAAC;QAC5B,qEAAqE;QACrE,0DAA0D;QAC1D,IAAI,KAAK,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;YACtC,KAAK,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;gBAC7C,KAAK,CAAC,kBAAkB;gBACxB,UAAU,CAAC,WAAW;aACvB,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import { mergeVersionVectors } from \"@tearleads/loro\";\nimport type {\n createRemoteDocument,\n DocumentRecord,\n PendingUpdateRecord,\n} from \"../../../../workflows/documents\";\nimport { persistDocument } from \"../persistence\";\nimport type {\n DocumentState,\n DocumentStoreState,\n PersistedDocumentRecord,\n SaveDocumentRecordOptions,\n} from \"../state\";\nimport type { DocumentStoreSyncGeneration } from \"./syncGeneration\";\n\ntype CreatedRemoteDocument = NonNullable<\n Awaited<ReturnType<typeof createRemoteDocument>>\n>;\n\n/** A create's seed; `onCommitted` runs once its settlement persists. */\nexport interface CreateSeed {\n readonly onCommitted: () => void;\n readonly update: PendingUpdateRecord;\n}\n\n/**\n * How a create that committed `seedUpdate` settles it: the row is accepted,\n * the commit position is the one its first sync would have recorded, and the\n * outgoing marker and frontier advance over it as the coverage pass would\n * have (see `prepareDocumentOutgoingCoverage`). Null when the create did not\n * commit the seed (a plain fallback or an adoption): the row stays queued and\n * syncs as before.\n */\nfunction committedSeedSettlement(input: {\n readonly created: CreatedRemoteDocument;\n readonly liveRecord: DocumentRecord | null;\n readonly pendingBaseVersion: string | null;\n readonly seedUpdate: PendingUpdateRecord | undefined;\n}): {\n readonly baseVersion: string;\n readonly options: SaveDocumentRecordOptions;\n readonly patch: Partial<DocumentRecord>;\n} | null {\n const { seedUpdate } = input;\n const seed = input.created.response?.initialSync;\n if (\n !seedUpdate ||\n input.pendingBaseVersion === null ||\n !seed?.acceptedOutgoingUpdateIds.includes(seedUpdate.id)\n ) {\n return null;\n }\n const baseVersion = mergeVersionVectors([\n input.pendingBaseVersion,\n seedUpdate.partialEndVersionVector,\n ]);\n const liveFrontier = input.liveRecord?.snapshotEndVersion ?? \"\";\n return {\n baseVersion,\n options: {\n acceptedPendingUpdateIds: [seedUpdate.id],\n clearSyncFailure: true,\n pendingBaseVersionOverride: baseVersion,\n },\n patch: {\n lastCommitLsn: seed.commitLsn,\n snapshotEndVersion: mergeVersionVectors([\n ...(liveFrontier.length > 0 ? [liveFrontier] : []),\n baseVersion,\n ]),\n },\n };\n}\n\n/**\n * Persists a just-created remote identity (documentId and content keys), and\n * settles the create's seed when it committed. Preserves the optimistic\n * snapshot fields: the user may have kept typing during the round trip.\n */\nexport async function persistCreatedRemoteDocument(input: {\n readonly created: CreatedRemoteDocument;\n readonly currentDoc: DocumentState;\n readonly generation: DocumentStoreSyncGeneration | undefined;\n readonly seed: CreateSeed | undefined;\n readonly state: DocumentStoreState;\n}): Promise<PersistedDocumentRecord | null> {\n const { state } = input;\n const settlement = committedSeedSettlement({\n created: input.created,\n liveRecord: state.record,\n pendingBaseVersion: state.pendingBaseVersion,\n seedUpdate: input.seed?.update,\n });\n const persisted = await persistDocument(\n state,\n input.currentDoc,\n { ...input.created.persistedState, ...settlement?.patch },\n {\n ...settlement?.options,\n preserveSnapshotStructuredFields: true,\n preserveSnapshotText: true,\n },\n input.generation,\n );\n if (persisted && settlement) {\n // As the coverage pass does: merge, so a concurrent local write that\n // advanced the in-memory marker is never moved backwards.\n if (state.pendingBaseVersion !== null) {\n state.pendingBaseVersion = mergeVersionVectors([\n state.pendingBaseVersion,\n settlement.baseVersion,\n ]);\n }\n input.seed?.onCommitted();\n }\n return persisted;\n}\n"]}