@tearleads/client-sdk 0.1.17 → 0.1.19
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/client/principalMutationApi.d.ts +1 -1
- package/client/principalMutationApi.js +5 -13
- package/client/principalMutationApi.js.map +1 -1
- package/client/principalMutationDispatch.js +54 -0
- package/client/principalMutationDispatch.js.map +1 -0
- package/data/persistence/container-contents/documentMoveIntentPersistence.js.map +1 -1
- package/data/principals/principalMutationJournal.d.ts +2 -5
- package/data/principals/principalMutationJournal.js +3 -20
- package/data/principals/principalMutationJournal.js.map +1 -1
- package/data/principals/principalMutationJournalShape.d.ts +26 -0
- package/data/principals/principalMutationJournalShape.js +46 -0
- package/data/principals/principalMutationJournalShape.js.map +1 -0
- package/index.d.ts +1 -1
- package/index.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +267 -3
- package/internal/api-client/ApiClient.js +11 -29
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/principalPolicyRequests.d.ts +266 -1
- package/internal/api-client/principalPolicyRequests.js +43 -1
- package/internal/api-client/principalPolicyRequests.js.map +1 -1
- package/internal/loro/document.js +8 -11
- package/internal/loro/document.js.map +1 -1
- package/internal/validators/operation/organizations.d.ts +54 -0
- package/internal/validators/operation/organizations.js +19 -4
- package/internal/validators/operation/organizations.js.map +1 -1
- package/package.json +4 -4
- package/workflows/organizations/index.d.ts +1 -0
- package/workflows/organizations/index.js.map +1 -1
- package/workflows/organizations/principalMutationJournalSession.d.ts +3 -3
- package/workflows/organizations/principalMutationJournalSession.js +2 -2
- package/workflows/organizations/principalMutationJournalSession.js.map +1 -1
- package/workflows/organizations/principalMutationReceipt.js +13 -12
- package/workflows/organizations/principalMutationReceipt.js.map +1 -1
- package/workflows/organizations/principalOperationReceipt.d.ts +5 -0
- package/workflows/organizations/principalOperationReceipt.js +36 -0
- package/workflows/organizations/principalOperationReceipt.js.map +1 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CommitOrganizationGroupPolicyRequest, OrganizationPrincipalPolicyRequest } from "../validators/request/index.js";
|
|
1
|
+
import type { CommitOrganizationGroupPolicyRequest, CreateOrganizationGroupWithPolicyRequest, DeleteOrganizationGroupRequest, OrganizationPrincipalPolicyRequest } from "../validators/request/index.js";
|
|
2
2
|
import type { PrincipalPolicyBundleResponse } from "../validators/response/index.js";
|
|
3
3
|
import type { BoundedCache } from "./ApiCache.js";
|
|
4
4
|
import type { ApiRequestRuntime } from "./apiRequestRuntime.js";
|
|
@@ -550,6 +550,271 @@ export declare class PrincipalPolicyRequests {
|
|
|
550
550
|
version: number;
|
|
551
551
|
};
|
|
552
552
|
}>>;
|
|
553
|
+
createResult(organizationId: string, input: CreateOrganizationGroupWithPolicyRequest, options?: RequestResultOptions): Promise<import("./types.js").RequestResult<{
|
|
554
|
+
group: {
|
|
555
|
+
createdAt: string;
|
|
556
|
+
currentState: {
|
|
557
|
+
keyEpoch: number;
|
|
558
|
+
keyFingerprint: string;
|
|
559
|
+
memberCount: number;
|
|
560
|
+
stateHash: string;
|
|
561
|
+
version: number;
|
|
562
|
+
} | null;
|
|
563
|
+
groupId: string;
|
|
564
|
+
isBuiltin: boolean;
|
|
565
|
+
organizationId: string;
|
|
566
|
+
};
|
|
567
|
+
organizationPolicy: {
|
|
568
|
+
containerMutations: {
|
|
569
|
+
createdAt: string;
|
|
570
|
+
manifestHead: {
|
|
571
|
+
epoch: number;
|
|
572
|
+
manifestHash: string;
|
|
573
|
+
};
|
|
574
|
+
organizationId: string;
|
|
575
|
+
parentId: string | null;
|
|
576
|
+
referencedPrincipalHeads: {
|
|
577
|
+
principalType: "group";
|
|
578
|
+
keyEpoch: number;
|
|
579
|
+
keyFingerprint: string;
|
|
580
|
+
principalId: string;
|
|
581
|
+
stateHash: string;
|
|
582
|
+
version: number;
|
|
583
|
+
}[];
|
|
584
|
+
updatedAt: string;
|
|
585
|
+
accessManifest: {
|
|
586
|
+
event: {
|
|
587
|
+
body: unknown;
|
|
588
|
+
event: Record<string, unknown>;
|
|
589
|
+
eventHash: string;
|
|
590
|
+
};
|
|
591
|
+
manifest: Record<string, unknown>;
|
|
592
|
+
manifestHash: string;
|
|
593
|
+
state: Record<string, unknown>;
|
|
594
|
+
};
|
|
595
|
+
containerId: string;
|
|
596
|
+
containerKek: {
|
|
597
|
+
accessManifestHash: string;
|
|
598
|
+
containerId: string;
|
|
599
|
+
containerKeyEpoch: number;
|
|
600
|
+
containerKeyEpochId: string;
|
|
601
|
+
containerManifestHistory: {
|
|
602
|
+
event: {
|
|
603
|
+
body: unknown;
|
|
604
|
+
event: Record<string, unknown>;
|
|
605
|
+
eventHash: string;
|
|
606
|
+
};
|
|
607
|
+
manifest: Record<string, unknown>;
|
|
608
|
+
manifestHash: string;
|
|
609
|
+
state: Record<string, unknown>;
|
|
610
|
+
}[];
|
|
611
|
+
keyEpoch: Record<string, unknown>;
|
|
612
|
+
keyEpochHash: string;
|
|
613
|
+
keyring: {
|
|
614
|
+
containerId: string;
|
|
615
|
+
containerKeyEpochId: string;
|
|
616
|
+
iv: string;
|
|
617
|
+
sealed: string;
|
|
618
|
+
sealingSuite: string;
|
|
619
|
+
version: number;
|
|
620
|
+
} | null;
|
|
621
|
+
keyTargetHash: string;
|
|
622
|
+
parentContainerKeyEpochId: string | null;
|
|
623
|
+
recipientTargets: Record<string, unknown>[];
|
|
624
|
+
wraps: Record<string, unknown>[];
|
|
625
|
+
};
|
|
626
|
+
systemSlot?: string | null | undefined;
|
|
627
|
+
}[];
|
|
628
|
+
currentGrants: {
|
|
629
|
+
accessLevel: "admin" | "read" | "write";
|
|
630
|
+
containerId: string;
|
|
631
|
+
}[];
|
|
632
|
+
currentMemberEnvelopes: {
|
|
633
|
+
envelopes: {
|
|
634
|
+
kemCipherText: string;
|
|
635
|
+
memberKeyFingerprint: string;
|
|
636
|
+
userId: string;
|
|
637
|
+
wrappedKey: string;
|
|
638
|
+
}[];
|
|
639
|
+
epoch: number;
|
|
640
|
+
principalId: string;
|
|
641
|
+
principalType: "group" | "organization";
|
|
642
|
+
stateHash: string;
|
|
643
|
+
};
|
|
644
|
+
currentPayload: {
|
|
645
|
+
cipherSuite: "aes-256-gcm";
|
|
646
|
+
ciphertext: string;
|
|
647
|
+
ciphertextHash: string;
|
|
648
|
+
createdAt: string;
|
|
649
|
+
principalId: string;
|
|
650
|
+
principalType: "group" | "organization";
|
|
651
|
+
stateHash: string;
|
|
652
|
+
};
|
|
653
|
+
currentProjection: {
|
|
654
|
+
role: "member" | "admin";
|
|
655
|
+
userId: string;
|
|
656
|
+
}[];
|
|
657
|
+
currentState: {
|
|
658
|
+
createdAt: string;
|
|
659
|
+
encapsulationPublicKey: string;
|
|
660
|
+
externalAuthority: {
|
|
661
|
+
keyEpoch: number;
|
|
662
|
+
keyFingerprint: string;
|
|
663
|
+
principalId: string;
|
|
664
|
+
principalType: "group";
|
|
665
|
+
stateHash: string;
|
|
666
|
+
version: number;
|
|
667
|
+
} | null;
|
|
668
|
+
grantCount: number;
|
|
669
|
+
grantRoot: string;
|
|
670
|
+
keyEpoch: number;
|
|
671
|
+
keyFingerprint: string;
|
|
672
|
+
memberCount: number;
|
|
673
|
+
memberEnvelopesRoot: string;
|
|
674
|
+
membershipMode: "projection";
|
|
675
|
+
membershipRoot: string;
|
|
676
|
+
payloadCiphertextHash: string;
|
|
677
|
+
prevStateHash: string | null;
|
|
678
|
+
principalId: string;
|
|
679
|
+
principalType: "group" | "organization";
|
|
680
|
+
projectionRoot: string;
|
|
681
|
+
signature: string;
|
|
682
|
+
signedAt: string;
|
|
683
|
+
signerUserId: string;
|
|
684
|
+
signerUserKeyFingerprint: string;
|
|
685
|
+
stateHash: string;
|
|
686
|
+
version: number;
|
|
687
|
+
};
|
|
688
|
+
};
|
|
689
|
+
}>>;
|
|
690
|
+
deleteResult(organizationId: string, groupId: string, input: DeleteOrganizationGroupRequest, options?: RequestResultOptions): Promise<import("./types.js").RequestResult<{
|
|
691
|
+
deleted: true;
|
|
692
|
+
groupId: string;
|
|
693
|
+
organizationPolicy: {
|
|
694
|
+
containerMutations: {
|
|
695
|
+
createdAt: string;
|
|
696
|
+
manifestHead: {
|
|
697
|
+
epoch: number;
|
|
698
|
+
manifestHash: string;
|
|
699
|
+
};
|
|
700
|
+
organizationId: string;
|
|
701
|
+
parentId: string | null;
|
|
702
|
+
referencedPrincipalHeads: {
|
|
703
|
+
principalType: "group";
|
|
704
|
+
keyEpoch: number;
|
|
705
|
+
keyFingerprint: string;
|
|
706
|
+
principalId: string;
|
|
707
|
+
stateHash: string;
|
|
708
|
+
version: number;
|
|
709
|
+
}[];
|
|
710
|
+
updatedAt: string;
|
|
711
|
+
accessManifest: {
|
|
712
|
+
event: {
|
|
713
|
+
body: unknown;
|
|
714
|
+
event: Record<string, unknown>;
|
|
715
|
+
eventHash: string;
|
|
716
|
+
};
|
|
717
|
+
manifest: Record<string, unknown>;
|
|
718
|
+
manifestHash: string;
|
|
719
|
+
state: Record<string, unknown>;
|
|
720
|
+
};
|
|
721
|
+
containerId: string;
|
|
722
|
+
containerKek: {
|
|
723
|
+
accessManifestHash: string;
|
|
724
|
+
containerId: string;
|
|
725
|
+
containerKeyEpoch: number;
|
|
726
|
+
containerKeyEpochId: string;
|
|
727
|
+
containerManifestHistory: {
|
|
728
|
+
event: {
|
|
729
|
+
body: unknown;
|
|
730
|
+
event: Record<string, unknown>;
|
|
731
|
+
eventHash: string;
|
|
732
|
+
};
|
|
733
|
+
manifest: Record<string, unknown>;
|
|
734
|
+
manifestHash: string;
|
|
735
|
+
state: Record<string, unknown>;
|
|
736
|
+
}[];
|
|
737
|
+
keyEpoch: Record<string, unknown>;
|
|
738
|
+
keyEpochHash: string;
|
|
739
|
+
keyring: {
|
|
740
|
+
containerId: string;
|
|
741
|
+
containerKeyEpochId: string;
|
|
742
|
+
iv: string;
|
|
743
|
+
sealed: string;
|
|
744
|
+
sealingSuite: string;
|
|
745
|
+
version: number;
|
|
746
|
+
} | null;
|
|
747
|
+
keyTargetHash: string;
|
|
748
|
+
parentContainerKeyEpochId: string | null;
|
|
749
|
+
recipientTargets: Record<string, unknown>[];
|
|
750
|
+
wraps: Record<string, unknown>[];
|
|
751
|
+
};
|
|
752
|
+
systemSlot?: string | null | undefined;
|
|
753
|
+
}[];
|
|
754
|
+
currentGrants: {
|
|
755
|
+
accessLevel: "admin" | "read" | "write";
|
|
756
|
+
containerId: string;
|
|
757
|
+
}[];
|
|
758
|
+
currentMemberEnvelopes: {
|
|
759
|
+
envelopes: {
|
|
760
|
+
kemCipherText: string;
|
|
761
|
+
memberKeyFingerprint: string;
|
|
762
|
+
userId: string;
|
|
763
|
+
wrappedKey: string;
|
|
764
|
+
}[];
|
|
765
|
+
epoch: number;
|
|
766
|
+
principalId: string;
|
|
767
|
+
principalType: "group" | "organization";
|
|
768
|
+
stateHash: string;
|
|
769
|
+
};
|
|
770
|
+
currentPayload: {
|
|
771
|
+
cipherSuite: "aes-256-gcm";
|
|
772
|
+
ciphertext: string;
|
|
773
|
+
ciphertextHash: string;
|
|
774
|
+
createdAt: string;
|
|
775
|
+
principalId: string;
|
|
776
|
+
principalType: "group" | "organization";
|
|
777
|
+
stateHash: string;
|
|
778
|
+
};
|
|
779
|
+
currentProjection: {
|
|
780
|
+
role: "member" | "admin";
|
|
781
|
+
userId: string;
|
|
782
|
+
}[];
|
|
783
|
+
currentState: {
|
|
784
|
+
createdAt: string;
|
|
785
|
+
encapsulationPublicKey: string;
|
|
786
|
+
externalAuthority: {
|
|
787
|
+
keyEpoch: number;
|
|
788
|
+
keyFingerprint: string;
|
|
789
|
+
principalId: string;
|
|
790
|
+
principalType: "group";
|
|
791
|
+
stateHash: string;
|
|
792
|
+
version: number;
|
|
793
|
+
} | null;
|
|
794
|
+
grantCount: number;
|
|
795
|
+
grantRoot: string;
|
|
796
|
+
keyEpoch: number;
|
|
797
|
+
keyFingerprint: string;
|
|
798
|
+
memberCount: number;
|
|
799
|
+
memberEnvelopesRoot: string;
|
|
800
|
+
membershipMode: "projection";
|
|
801
|
+
membershipRoot: string;
|
|
802
|
+
payloadCiphertextHash: string;
|
|
803
|
+
prevStateHash: string | null;
|
|
804
|
+
principalId: string;
|
|
805
|
+
principalType: "group" | "organization";
|
|
806
|
+
projectionRoot: string;
|
|
807
|
+
signature: string;
|
|
808
|
+
signedAt: string;
|
|
809
|
+
signerUserId: string;
|
|
810
|
+
signerUserKeyFingerprint: string;
|
|
811
|
+
stateHash: string;
|
|
812
|
+
version: number;
|
|
813
|
+
};
|
|
814
|
+
};
|
|
815
|
+
organizationId: string;
|
|
816
|
+
}>>;
|
|
817
|
+
private groupMutation;
|
|
553
818
|
commitResult(organizationId: string, groupId: string, input: CommitOrganizationGroupPolicyRequest, options?: RequestResultOptions): Promise<import("./types.js").RequestResult<{
|
|
554
819
|
groupPolicy: {
|
|
555
820
|
containerMutations: {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { commitOrganizationGroupPolicyOperation, putPrincipalPolicyOperation, } from "../validators/operation/index.js";
|
|
1
|
+
import { commitOrganizationGroupPolicyOperation, createOrganizationGroupOperation, deleteOrganizationGroupOperation, putPrincipalPolicyOperation, } from "../validators/operation/index.js";
|
|
2
2
|
import { principalHistoryRequest } from "./principalHistoryRequest.js";
|
|
3
3
|
import { collectPrincipalPolicyPages, readPrincipalPolicyPages, } from "./principalPolicyPages.js";
|
|
4
4
|
import { readProjectionPolicyHistoryPages } from "./projectionPolicyHistoryPages.js";
|
|
5
5
|
import { dedupedRequest } from "./requestInternals.js";
|
|
6
|
+
import { createOrganizationGroup } from "./routes/organizations/createGroup.js";
|
|
7
|
+
import { deleteOrganizationGroup } from "./routes/organizations/deleteGroup.js";
|
|
6
8
|
import { commitOrganizationGroupPolicy, putPrincipalPolicy, } from "./routes/principals/policy.js";
|
|
7
9
|
export class PrincipalPolicyRequests {
|
|
8
10
|
runtime;
|
|
@@ -45,6 +47,46 @@ export class PrincipalPolicyRequests {
|
|
|
45
47
|
operation: putPrincipalPolicyOperation,
|
|
46
48
|
}).finally(() => this.cache.delete(key));
|
|
47
49
|
}
|
|
50
|
+
createResult(organizationId, input, options = {}) {
|
|
51
|
+
return this.groupMutation(organizationId, input.groupId, () => principalHistoryRequest(this.runtime, {
|
|
52
|
+
path: createOrganizationGroup.path(organizationId),
|
|
53
|
+
validator: createOrganizationGroup.isResponse,
|
|
54
|
+
method: createOrganizationGroup.method,
|
|
55
|
+
body: JSON.stringify(input),
|
|
56
|
+
options: {
|
|
57
|
+
expectedPaymentRequiredOrganizationId: organizationId,
|
|
58
|
+
...options,
|
|
59
|
+
},
|
|
60
|
+
operation: createOrganizationGroupOperation,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
deleteResult(organizationId, groupId, input, options = {}) {
|
|
64
|
+
return this.groupMutation(organizationId, groupId, () => principalHistoryRequest(this.runtime, {
|
|
65
|
+
path: deleteOrganizationGroup.path(organizationId, groupId),
|
|
66
|
+
validator: deleteOrganizationGroup.isResponse,
|
|
67
|
+
method: deleteOrganizationGroup.method,
|
|
68
|
+
body: JSON.stringify(input),
|
|
69
|
+
options: {
|
|
70
|
+
expectedPaymentRequiredOrganizationId: organizationId,
|
|
71
|
+
...options,
|
|
72
|
+
},
|
|
73
|
+
operation: deleteOrganizationGroupOperation,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
async groupMutation(organizationId, groupId, request) {
|
|
77
|
+
const groupKey = JSON.stringify(["group", groupId]);
|
|
78
|
+
const organizationKey = JSON.stringify(["organization", organizationId]);
|
|
79
|
+
this.cache.delete(groupKey);
|
|
80
|
+
this.cache.delete(organizationKey);
|
|
81
|
+
try {
|
|
82
|
+
return await request();
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
this.cache.delete(groupKey);
|
|
86
|
+
this.cache.delete(organizationKey);
|
|
87
|
+
this.clearWriterProjectionCaches();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
48
90
|
async commitResult(organizationId, groupId, input, options = {}) {
|
|
49
91
|
const groupKey = JSON.stringify(["group", groupId]);
|
|
50
92
|
const organizationKey = JSON.stringify(["organization", organizationId]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"principalPolicyRequests.js","sourceRoot":"","sources":["principalPolicyRequests.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n commitOrganizationGroupPolicyOperation,\n putPrincipalPolicyOperation,\n} from \"@tearleads/validators/operation\";\nimport type {\n CommitOrganizationGroupPolicyRequest,\n OrganizationPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport type { BoundedCache } from \"./ApiCache\";\nimport type { ApiRequestRuntime } from \"./apiRequestRuntime\";\nimport { principalHistoryRequest } from \"./principalHistoryRequest\";\nimport {\n collectPrincipalPolicyPages,\n type PrincipalPolicyPageReadOptions,\n readPrincipalPolicyPages,\n} from \"./principalPolicyPages\";\nimport { readProjectionPolicyHistoryPages } from \"./projectionPolicyHistoryPages\";\nimport { dedupedRequest } from \"./requestInternals\";\nimport {\n commitOrganizationGroupPolicy,\n putPrincipalPolicy,\n} from \"./routes/principals/policy\";\nimport type { RequestResultOptions } from \"./types\";\n\nexport class PrincipalPolicyRequests {\n constructor(\n private readonly runtime: ApiRequestRuntime,\n private readonly cache: BoundedCache<\n Promise<PrincipalPolicyBundleResponse | null>\n >,\n private readonly clearWriterProjectionCaches: () => void,\n ) {}\n\n publicPages(\n source: Parameters<typeof readProjectionPolicyHistoryPages>[1],\n options: Parameters<typeof readProjectionPolicyHistoryPages>[2] = {},\n ) {\n return readProjectionPolicyHistoryPages(this.runtime, source, options);\n }\n\n pages(\n principalType: \"group\" | \"organization\",\n principalId: string,\n options: PrincipalPolicyPageReadOptions = {},\n ) {\n return readPrincipalPolicyPages(\n this.runtime,\n principalType,\n principalId,\n options,\n );\n }\n\n get(\n principalType: \"group\" | \"organization\",\n principalId: string,\n options: RequestResultOptions = {},\n ) {\n const request = () =>\n collectPrincipalPolicyPages(\n this.runtime,\n principalType,\n principalId,\n options,\n );\n const key = JSON.stringify([principalType, principalId]);\n // Cancellation, reporting and renewal preferences belong to their caller.\n return Object.keys(options).length > 0\n ? request()\n : dedupedRequest(this.cache, key, request);\n }\n\n put(...args: Parameters<PrincipalPolicyRequests[\"putResult\"]>) {\n return this.putResult(...args).then((result) =>\n result.ok ? result.data : null,\n );\n }\n\n putResult(\n principalType: \"organization\",\n principalId: string,\n input: OrganizationPrincipalPolicyRequest,\n options: RequestResultOptions = {},\n ) {\n const key = JSON.stringify([principalType, principalId]);\n this.cache.delete(key);\n return principalHistoryRequest(this.runtime, {\n path: putPrincipalPolicy.path(principalType, principalId),\n validator: putPrincipalPolicy.isResponse,\n method: putPrincipalPolicy.method,\n body: JSON.stringify(input),\n options: {\n expectedPaymentRequiredOrganizationId: principalId,\n ...options,\n },\n operation: putPrincipalPolicyOperation,\n }).finally(() => this.cache.delete(key));\n }\n\n async commitResult(\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n options: RequestResultOptions = {},\n ) {\n const groupKey = JSON.stringify([\"group\", groupId]);\n const organizationKey = JSON.stringify([\"organization\", organizationId]);\n this.cache.delete(groupKey);\n this.cache.delete(organizationKey);\n try {\n return await principalHistoryRequest(this.runtime, {\n path: commitOrganizationGroupPolicy.path(organizationId, groupId),\n validator: commitOrganizationGroupPolicy.isResponse,\n method: commitOrganizationGroupPolicy.method,\n body: JSON.stringify(input),\n options: {\n expectedPaymentRequiredOrganizationId: organizationId,\n ...options,\n },\n operation: commitOrganizationGroupPolicyOperation,\n });\n } finally {\n this.cache.delete(groupKey);\n this.cache.delete(organizationKey);\n this.clearWriterProjectionCaches();\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"principalPolicyRequests.js","sourceRoot":"","sources":["principalPolicyRequests.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sCAAsC,EACtC,gCAAgC,EAChC,gCAAgC,EAChC,2BAA2B,GAC5B,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EACL,2BAA2B,EAE3B,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,gCAAgC,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EACL,6BAA6B,EAC7B,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AAGpC,MAAM,OAAO,uBAAuB;IAEf;IACA;IAGA;IALnB,YACmB,OAA0B,EAC1B,KAEhB,EACgB,2BAAuC;QAJvC,YAAO,GAAP,OAAO,CAAmB;QAC1B,UAAK,GAAL,KAAK,CAErB;QACgB,gCAA2B,GAA3B,2BAA2B,CAAY;IACvD,CAAC;IAEJ,WAAW,CACT,MAA8D,EAC9D,UAAkE,EAAE;QAEpE,OAAO,gCAAgC,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CACH,aAAuC,EACvC,WAAmB,EACnB,UAA0C,EAAE;QAE5C,OAAO,wBAAwB,CAC7B,IAAI,CAAC,OAAO,EACZ,aAAa,EACb,WAAW,EACX,OAAO,CACR,CAAC;IACJ,CAAC;IAED,GAAG,CACD,aAAuC,EACvC,WAAmB,EACnB,UAAgC,EAAE;QAElC,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,2BAA2B,CACzB,IAAI,CAAC,OAAO,EACZ,aAAa,EACb,WAAW,EACX,OAAO,CACR,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;QACzD,0EAA0E;QAC1E,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC;YACpC,CAAC,CAAC,OAAO,EAAE;YACX,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,GAAG,CAAC,GAAG,IAAsD;QAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC/B,CAAC;IACJ,CAAC;IAED,SAAS,CACP,aAA6B,EAC7B,WAAmB,EACnB,KAAyC,EACzC,UAAgC,EAAE;QAElC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE;YAC3C,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC;YACzD,SAAS,EAAE,kBAAkB,CAAC,UAAU;YACxC,MAAM,EAAE,kBAAkB,CAAC,MAAM;YACjC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAC3B,OAAO,EAAE;gBACP,qCAAqC,EAAE,WAAW;gBAClD,GAAG,OAAO;aACX;YACD,SAAS,EAAE,2BAA2B;SACvC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY,CACV,cAAsB,EACtB,KAA+C,EAC/C,UAAgC,EAAE;QAElC,OAAO,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,CAC5D,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE;YACpC,IAAI,EAAE,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC;YAClD,SAAS,EAAE,uBAAuB,CAAC,UAAU;YAC7C,MAAM,EAAE,uBAAuB,CAAC,MAAM;YACtC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAC3B,OAAO,EAAE;gBACP,qCAAqC,EAAE,cAAc;gBACrD,GAAG,OAAO;aACX;YACD,SAAS,EAAE,gCAAgC;SAC5C,CAAC,CACH,CAAC;IACJ,CAAC;IAED,YAAY,CACV,cAAsB,EACtB,OAAe,EACf,KAAqC,EACrC,UAAgC,EAAE;QAElC,OAAO,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,OAAO,EAAE,GAAG,EAAE,CACtD,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE;YACpC,IAAI,EAAE,uBAAuB,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;YAC3D,SAAS,EAAE,uBAAuB,CAAC,UAAU;YAC7C,MAAM,EAAE,uBAAuB,CAAC,MAAM;YACtC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAC3B,OAAO,EAAE;gBACP,qCAAqC,EAAE,cAAc;gBACrD,GAAG,OAAO;aACX;YACD,SAAS,EAAE,gCAAgC;SAC5C,CAAC,CACH,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,cAAsB,EACtB,OAAe,EACf,OAAyB;QAEzB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,EAAE,CAAC;QACzB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YACnC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,cAAsB,EACtB,OAAe,EACf,KAA2C,EAC3C,UAAgC,EAAE;QAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QACpD,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACnC,IAAI,CAAC;YACH,OAAO,MAAM,uBAAuB,CAAC,IAAI,CAAC,OAAO,EAAE;gBACjD,IAAI,EAAE,6BAA6B,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;gBACjE,SAAS,EAAE,6BAA6B,CAAC,UAAU;gBACnD,MAAM,EAAE,6BAA6B,CAAC,MAAM;gBAC5C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;gBAC3B,OAAO,EAAE;oBACP,qCAAqC,EAAE,cAAc;oBACrD,GAAG,OAAO;iBACX;gBACD,SAAS,EAAE,sCAAsC;aAClD,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;YACnC,IAAI,CAAC,2BAA2B,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;CACF","sourcesContent":["import {\n commitOrganizationGroupPolicyOperation,\n createOrganizationGroupOperation,\n deleteOrganizationGroupOperation,\n putPrincipalPolicyOperation,\n} from \"@tearleads/validators/operation\";\nimport type {\n CommitOrganizationGroupPolicyRequest,\n CreateOrganizationGroupWithPolicyRequest,\n DeleteOrganizationGroupRequest,\n OrganizationPrincipalPolicyRequest,\n} from \"@tearleads/validators/request\";\nimport type { PrincipalPolicyBundleResponse } from \"@tearleads/validators/response\";\nimport type { BoundedCache } from \"./ApiCache\";\nimport type { ApiRequestRuntime } from \"./apiRequestRuntime\";\nimport { principalHistoryRequest } from \"./principalHistoryRequest\";\nimport {\n collectPrincipalPolicyPages,\n type PrincipalPolicyPageReadOptions,\n readPrincipalPolicyPages,\n} from \"./principalPolicyPages\";\nimport { readProjectionPolicyHistoryPages } from \"./projectionPolicyHistoryPages\";\nimport { dedupedRequest } from \"./requestInternals\";\nimport { createOrganizationGroup } from \"./routes/organizations/createGroup\";\nimport { deleteOrganizationGroup } from \"./routes/organizations/deleteGroup\";\nimport {\n commitOrganizationGroupPolicy,\n putPrincipalPolicy,\n} from \"./routes/principals/policy\";\nimport type { RequestResultOptions } from \"./types\";\n\nexport class PrincipalPolicyRequests {\n constructor(\n private readonly runtime: ApiRequestRuntime,\n private readonly cache: BoundedCache<\n Promise<PrincipalPolicyBundleResponse | null>\n >,\n private readonly clearWriterProjectionCaches: () => void,\n ) {}\n\n publicPages(\n source: Parameters<typeof readProjectionPolicyHistoryPages>[1],\n options: Parameters<typeof readProjectionPolicyHistoryPages>[2] = {},\n ) {\n return readProjectionPolicyHistoryPages(this.runtime, source, options);\n }\n\n pages(\n principalType: \"group\" | \"organization\",\n principalId: string,\n options: PrincipalPolicyPageReadOptions = {},\n ) {\n return readPrincipalPolicyPages(\n this.runtime,\n principalType,\n principalId,\n options,\n );\n }\n\n get(\n principalType: \"group\" | \"organization\",\n principalId: string,\n options: RequestResultOptions = {},\n ) {\n const request = () =>\n collectPrincipalPolicyPages(\n this.runtime,\n principalType,\n principalId,\n options,\n );\n const key = JSON.stringify([principalType, principalId]);\n // Cancellation, reporting and renewal preferences belong to their caller.\n return Object.keys(options).length > 0\n ? request()\n : dedupedRequest(this.cache, key, request);\n }\n\n put(...args: Parameters<PrincipalPolicyRequests[\"putResult\"]>) {\n return this.putResult(...args).then((result) =>\n result.ok ? result.data : null,\n );\n }\n\n putResult(\n principalType: \"organization\",\n principalId: string,\n input: OrganizationPrincipalPolicyRequest,\n options: RequestResultOptions = {},\n ) {\n const key = JSON.stringify([principalType, principalId]);\n this.cache.delete(key);\n return principalHistoryRequest(this.runtime, {\n path: putPrincipalPolicy.path(principalType, principalId),\n validator: putPrincipalPolicy.isResponse,\n method: putPrincipalPolicy.method,\n body: JSON.stringify(input),\n options: {\n expectedPaymentRequiredOrganizationId: principalId,\n ...options,\n },\n operation: putPrincipalPolicyOperation,\n }).finally(() => this.cache.delete(key));\n }\n\n createResult(\n organizationId: string,\n input: CreateOrganizationGroupWithPolicyRequest,\n options: RequestResultOptions = {},\n ) {\n return this.groupMutation(organizationId, input.groupId, () =>\n principalHistoryRequest(this.runtime, {\n path: createOrganizationGroup.path(organizationId),\n validator: createOrganizationGroup.isResponse,\n method: createOrganizationGroup.method,\n body: JSON.stringify(input),\n options: {\n expectedPaymentRequiredOrganizationId: organizationId,\n ...options,\n },\n operation: createOrganizationGroupOperation,\n }),\n );\n }\n\n deleteResult(\n organizationId: string,\n groupId: string,\n input: DeleteOrganizationGroupRequest,\n options: RequestResultOptions = {},\n ) {\n return this.groupMutation(organizationId, groupId, () =>\n principalHistoryRequest(this.runtime, {\n path: deleteOrganizationGroup.path(organizationId, groupId),\n validator: deleteOrganizationGroup.isResponse,\n method: deleteOrganizationGroup.method,\n body: JSON.stringify(input),\n options: {\n expectedPaymentRequiredOrganizationId: organizationId,\n ...options,\n },\n operation: deleteOrganizationGroupOperation,\n }),\n );\n }\n\n private async groupMutation<T>(\n organizationId: string,\n groupId: string,\n request: () => Promise<T>,\n ): Promise<T> {\n const groupKey = JSON.stringify([\"group\", groupId]);\n const organizationKey = JSON.stringify([\"organization\", organizationId]);\n this.cache.delete(groupKey);\n this.cache.delete(organizationKey);\n try {\n return await request();\n } finally {\n this.cache.delete(groupKey);\n this.cache.delete(organizationKey);\n this.clearWriterProjectionCaches();\n }\n }\n\n async commitResult(\n organizationId: string,\n groupId: string,\n input: CommitOrganizationGroupPolicyRequest,\n options: RequestResultOptions = {},\n ) {\n const groupKey = JSON.stringify([\"group\", groupId]);\n const organizationKey = JSON.stringify([\"organization\", organizationId]);\n this.cache.delete(groupKey);\n this.cache.delete(organizationKey);\n try {\n return await principalHistoryRequest(this.runtime, {\n path: commitOrganizationGroupPolicy.path(organizationId, groupId),\n validator: commitOrganizationGroupPolicy.isResponse,\n method: commitOrganizationGroupPolicy.method,\n body: JSON.stringify(input),\n options: {\n expectedPaymentRequiredOrganizationId: organizationId,\n ...options,\n },\n operation: commitOrganizationGroupPolicyOperation,\n });\n } finally {\n this.cache.delete(groupKey);\n this.cache.delete(organizationKey);\n this.clearWriterProjectionCaches();\n }\n }\n}\n"]}
|
|
@@ -196,31 +196,28 @@ export function getTextValue(doc, key = "text") {
|
|
|
196
196
|
* index, so callers can both blame and re-render the prose (the per-range view)
|
|
197
197
|
* from a single pass.
|
|
198
198
|
*
|
|
199
|
-
* One Loro op (one counter) is one code point, but an astral character
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* that opens with an emoji), but the low/last unit always resolves to the
|
|
204
|
-
* inserting op — and using one position per code point avoids double-counting
|
|
205
|
-
* the two halves of a surrogate pair.
|
|
199
|
+
* One Loro op (one counter) is one code point, but an astral character spans
|
|
200
|
+
* two UTF-16 units. Loro 1.16.4 resolves the cursor at the first unit and rejects
|
|
201
|
+
* the interior low-surrogate position. Iterate code points and advance by their
|
|
202
|
+
* UTF-16 length so attribution neither splits nor double-counts a character.
|
|
206
203
|
*/
|
|
207
204
|
function collectTextCharBlame(doc, key) {
|
|
208
205
|
const text = doc.getText(key);
|
|
209
206
|
const codePoints = [];
|
|
210
207
|
const opIds = [];
|
|
211
|
-
let
|
|
208
|
+
let utf16Start = 0;
|
|
212
209
|
for (const char of text.toString()) {
|
|
213
|
-
utf16End += char.length;
|
|
214
210
|
// getCursor mints a WASM-backed Cursor each call; free it immediately after
|
|
215
211
|
// reading its op id so a long document does not pile up cursors on the heap.
|
|
216
|
-
const cursor = text.getCursor(
|
|
212
|
+
const cursor = text.getCursor(utf16Start, 1);
|
|
217
213
|
const opId = cursor?.pos();
|
|
218
214
|
cursor?.free();
|
|
219
215
|
if (opId === undefined) {
|
|
220
|
-
throw new Error(`LoroText "${key}" code point
|
|
216
|
+
throw new Error(`LoroText "${key}" code point starting at UTF-16 index ${utf16Start} has no op id.`);
|
|
221
217
|
}
|
|
222
218
|
codePoints.push(char);
|
|
223
219
|
opIds.push({ peerId: opId.peer, counter: opId.counter });
|
|
220
|
+
utf16Start += char.length;
|
|
224
221
|
}
|
|
225
222
|
return { codePoints, opIds };
|
|
226
223
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"document.js","sourceRoot":"","sources":["document.ts"],"names":[],"mappings":"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","sourcesContent":["import { base64ToBytes, bytesToBase64 } from \"@tearleads/encoding\";\nimport { LoroDoc, VersionVector } from \"loro-crdt\";\nimport { serializeCanonicalHistory } from \"./historyCanonicalization\";\nimport { getImportBlobMetadata } from \"./importMetadata\";\n\nexport { getImportBlobMetadata, type ImportBlobMode } from \"./importMetadata\";\n\nfunction isPeerIdString(value: string): value is `${number}` {\n return /^\\d+$/.test(value);\n}\n\nconst MAX_POSTGRES_INTEGER = 2_147_483_647;\n\nexport class LoroImportUnresolvedDependenciesError extends Error {\n readonly importKind: \"snapshot\" | \"updates\";\n\n constructor(importKind: \"snapshot\" | \"updates\") {\n super(\n `import${importKind === \"snapshot\" ? \"Snapshot\" : \"Updates\"} received ${\n importKind === \"snapshot\" ? \"a snapshot\" : \"updates\"\n } with unresolved pending dependencies`,\n );\n this.name = \"LoroImportUnresolvedDependenciesError\";\n this.importKind = importKind;\n }\n}\n\nexport interface VersionVectorSpan {\n peerId: `${number}`;\n startCounter: number;\n endCounter: number;\n}\n\nfunction assertSupportedVersionVectorCounter(counter: number): void {\n if (\n !Number.isInteger(counter) ||\n counter < 0 ||\n counter > MAX_POSTGRES_INTEGER\n ) {\n throw new Error(\n \"Version vector counter is outside the supported integer range.\",\n );\n }\n}\n\nfunction normalizeVersionVectorEntries(\n versionVector: VersionVector,\n): Map<`${number}`, number> {\n const entries = new Map<`${number}`, number>();\n\n for (const [peerId, counter] of versionVector.toJSON()) {\n const normalizedPeerId = String(peerId);\n if (!isPeerIdString(normalizedPeerId)) {\n throw new Error(\"Version vector contains a non-numeric peer ID.\");\n }\n assertSupportedVersionVectorCounter(counter);\n entries.set(normalizedPeerId, counter);\n }\n\n return entries;\n}\n\nexport async function derivePeerId(\n seed: string | Uint8Array,\n): Promise<`${number}`> {\n const bytes =\n typeof seed === \"string\" ? new TextEncoder().encode(seed) : seed;\n const digest = new Uint8Array(\n await crypto.subtle.digest(\"SHA-256\", bytes.slice()),\n );\n const view = new DataView(\n digest.buffer,\n digest.byteOffset,\n digest.byteLength,\n );\n const peerId = (view.getBigUint64(0, false) || 1n).toString();\n\n if (!isPeerIdString(peerId)) {\n throw new Error(\"Failed to derive a numeric peer ID.\");\n }\n\n return peerId;\n}\n\nexport async function createDocument(peerSeed: string | Uint8Array) {\n const doc = new LoroDoc();\n doc.setPeerId(await derivePeerId(peerSeed));\n return doc;\n}\n\nexport function exportAllUpdates(doc: LoroDoc): Uint8Array {\n return doc.export({ mode: \"update\" });\n}\n\n/** Deterministic, peer-uncompressed identity for an operation-log prefix. */\nexport function exportFullHistoryIdentity(\n doc: LoroDoc,\n endVersion?: string,\n): string {\n return serializeCanonicalHistory(\n doc.exportJsonUpdates(\n undefined,\n endVersion === undefined ? undefined : decodeVersionVector(endVersion),\n false,\n ),\n );\n}\n\n/**\n * Export a mergeable, full-history snapshot — the only snapshot form this\n * codebase produces. Every document is born with full durable history and\n * restored from it, so a partial (gc'd) export here is an invariant\n * violation, not a state to accommodate; fail loudly instead of publishing a\n * blob that could not safely merge concurrent frontiers.\n */\nexport function exportFullHistorySnapshot(doc: LoroDoc): Uint8Array {\n const snapshot = doc.export({ mode: \"snapshot\" });\n const metadata = getImportBlobMetadata(snapshot);\n if (\n metadata.mode !== \"snapshot\" ||\n !versionVectorsEqual(\n metadata.partialStartVersionVector,\n emptyVersionVector(),\n )\n ) {\n throw new Error(\n \"Document export lost full history; this document was restored from an incomplete source\",\n );\n }\n return snapshot;\n}\n\nexport function exportUpdatesSince(\n doc: LoroDoc,\n encodedVersionVector?: string | null,\n): Uint8Array {\n if (!encodedVersionVector) {\n return exportAllUpdates(doc);\n }\n\n return doc.export({\n mode: \"update\",\n from: VersionVector.decode(base64ToBytes(encodedVersionVector)),\n });\n}\n\nexport function encodeEncodedVersionVector(\n versionVector: VersionVector,\n): string {\n return bytesToBase64(versionVector.encode());\n}\n\nexport function encodeVersionVector(doc: LoroDoc): string {\n return encodeEncodedVersionVector(doc.oplogVersion());\n}\n\nexport function emptyVersionVector(): string {\n return encodeEncodedVersionVector(new VersionVector(undefined));\n}\n\nexport function decodeVersionVector(\n encodedVersionVector: string | null | undefined,\n): VersionVector {\n if (!encodedVersionVector) {\n return new VersionVector(undefined);\n }\n\n return VersionVector.decode(base64ToBytes(encodedVersionVector));\n}\n\nexport function getUpdateVersionVectors(update: Uint8Array): {\n partialStartVersionVector: string;\n partialEndVersionVector: string;\n} {\n const metadata = getImportBlobMetadata(update);\n\n return {\n partialStartVersionVector: metadata.partialStartVersionVector,\n partialEndVersionVector: metadata.partialEndVersionVector,\n };\n}\n\nexport function satisfiesVersionVector(\n encodedVersionVector: string | null | undefined,\n partialVersionVector: string,\n): boolean {\n const versionVector = decodeVersionVector(encodedVersionVector);\n const requiredVersionVector = decodeVersionVector(partialVersionVector);\n\n for (const [peerId, counter] of requiredVersionVector.toJSON()) {\n if ((versionVector.get(peerId) ?? 0) < counter) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function mergeVersionVectors(\n encodedVersionVectors: ReadonlyArray<string>,\n): string {\n const merged = new Map<`${number}`, number>();\n\n for (const encodedVersionVector of encodedVersionVectors) {\n for (const [normalizedPeerId, counter] of normalizeVersionVectorEntries(\n decodeVersionVector(encodedVersionVector),\n )) {\n merged.set(\n normalizedPeerId,\n Math.max(merged.get(normalizedPeerId) ?? 0, counter),\n );\n }\n }\n\n return encodeEncodedVersionVector(VersionVector.parseJSON(merged));\n}\n\nexport function listVersionVectorSpans(input: {\n partialStartVersionVector: string;\n partialEndVersionVector: string;\n}): VersionVectorSpan[] {\n const startEntries = normalizeVersionVectorEntries(\n decodeVersionVector(input.partialStartVersionVector),\n );\n const endEntries = normalizeVersionVectorEntries(\n decodeVersionVector(input.partialEndVersionVector),\n );\n const spans: VersionVectorSpan[] = [];\n\n for (const [peerId, startCounter] of startEntries) {\n const endCounter = endEntries.get(peerId) ?? 0;\n if (startCounter > endCounter) {\n throw new Error(\"Version vector end must cover start.\");\n }\n }\n\n for (const [peerId, endCounter] of endEntries) {\n const startCounter = startEntries.get(peerId) ?? 0;\n if (endCounter <= startCounter) {\n continue;\n }\n\n spans.push({ peerId, startCounter, endCounter });\n }\n\n return spans.sort((left, right) => left.peerId.localeCompare(right.peerId));\n}\n\nexport function versionVectorsEqual(\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean {\n const leftEntries = decodeVersionVector(left).toJSON();\n const rightEntries = decodeVersionVector(right).toJSON();\n\n if (leftEntries.size !== rightEntries.size) {\n return false;\n }\n\n for (const [peerId, leftCounter] of leftEntries) {\n if (rightEntries.get(peerId) !== leftCounter) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function importUpdates(doc: LoroDoc, updates: Uint8Array[]): void {\n // Reject an obsolete member before importBatch can mutate the document.\n for (const update of updates) getImportBlobMetadata(update);\n const status = doc.importBatch(updates);\n if (status.pending != null && status.pending.size > 0) {\n // importBatch applies out-of-order batches correctly but can still report\n // the intermediate pending set it saw mid-batch. Trust the document, not\n // the report: the import only genuinely failed when the document's final\n // version does not cover some batched update's end version.\n const documentVersion = encodeVersionVector(doc);\n const covered = updates.every((update) =>\n satisfiesVersionVector(\n documentVersion,\n getImportBlobMetadata(update).partialEndVersionVector,\n ),\n );\n if (!covered) {\n throw new LoroImportUnresolvedDependenciesError(\"updates\");\n }\n }\n}\n\n/**\n * Load a snapshot blob into a document. Snapshots MUST go through a single\n * `import()`, never `importBatch()`. A non-empty `pending` means the import\n * target is incompatible or dependencies are missing, so fail loudly instead\n * of silently loading a short document.\n */\nexport function importSnapshot(doc: LoroDoc, snapshot: Uint8Array): void {\n getImportBlobMetadata(snapshot);\n const status = doc.import(snapshot);\n // Reject only a genuinely incomplete import: `pending` can be an empty\n // VersionVector (size 0) rather than null when everything resolved, so test\n // for at least one unresolved dependency instead of mere presence.\n if (status.pending != null && status.pending.size > 0) {\n throw new LoroImportUnresolvedDependenciesError(\"snapshot\");\n }\n}\n\nexport function getTextValue(doc: LoroDoc, key = \"text\"): string {\n return doc.getText(key).toString();\n}\n\nexport interface TextCharOpId {\n /** Peer of the op that inserted this character. */\n peerId: `${number}`;\n /** Counter of that op — identifies the character within the peer's stream. */\n counter: number;\n}\n\nexport interface TextCharBlameSource {\n /** One entry per Unicode code point of the prose, in document order. */\n codePoints: string[];\n /** The op id that inserted each code point — same length and order as `codePoints`. */\n opIds: TextCharOpId[];\n}\n\n/**\n * Walk a LoroText's prose once, collecting each Unicode code point alongside the\n * op id `(peerId, counter)` of the op that inserted it. The two arrays share an\n * index, so callers can both blame and re-render the prose (the per-range view)\n * from a single pass.\n *\n * One Loro op (one counter) is one code point, but an astral character (emoji,\n * etc.) spans two UTF-16 units. We therefore iterate code points and index\n * `getCursor` by each code point's LAST UTF-16 unit: a leading high-surrogate\n * position yields no cursor (so iterating raw UTF-16 units would throw on prose\n * that opens with an emoji), but the low/last unit always resolves to the\n * inserting op — and using one position per code point avoids double-counting\n * the two halves of a surrogate pair.\n */\nfunction collectTextCharBlame(doc: LoroDoc, key: string): TextCharBlameSource {\n const text = doc.getText(key);\n const codePoints: string[] = [];\n const opIds: TextCharOpId[] = [];\n let utf16End = 0;\n for (const char of text.toString()) {\n utf16End += char.length;\n // getCursor mints a WASM-backed Cursor each call; free it immediately after\n // reading its op id so a long document does not pile up cursors on the heap.\n const cursor = text.getCursor(utf16End - 1, 1);\n const opId = cursor?.pos();\n cursor?.free();\n if (opId === undefined) {\n throw new Error(\n `LoroText \"${key}\" code point ending at UTF-16 index ${utf16End - 1} has no op id.`,\n );\n }\n codePoints.push(char);\n opIds.push({ peerId: opId.peer, counter: opId.counter });\n }\n return { codePoints, opIds };\n}\n\n/**\n * Per-character op-id attribution for a LoroText container's prose. Returns one\n * `(peerId, counter)` per Unicode code point — the op that inserted that\n * character — in document order; the array length equals the code-point count\n * (`[...text].length`). This is the client-side primitive for character-level\n * \"blame\": each op id resolves to a writer by intersecting it against the\n * document's edit-attribution segments.\n */\nexport function listTextCharOpIds(doc: LoroDoc, key = \"text\"): TextCharOpId[] {\n return collectTextCharBlame(doc, key).opIds;\n}\n\n/**\n * {@link listTextCharOpIds} for a persisted snapshot blob, without opening an\n * editor: rebuilds a throwaway read-only `LoroDoc` from the snapshot and reads\n * each character's op id, so blame is exact. The doc is only read, never\n * edited, so no peer id is set.\n *\n * Extraction is linear: `getCursor()` is an O(log n) b-tree lookup per code\n * point (measured ~1.8µs/char — ~90ms for a 50k-char snapshot, flat per char and\n * unaffected by tombstones). `maxCharacters` (UTF-16 length) is therefore a soft\n * guard against pathologically large prose, not a quadratic cliff: over it we\n * return `null` (\"skipped, too large\", distinct from `[]` for an empty document)\n * rather than do unbounded synchronous work on the render thread.\n */\nexport function listSnapshotCharOpIds(\n snapshot: Uint8Array,\n maxCharacters: number,\n key = \"text\",\n): TextCharOpId[] | null {\n const source = listSnapshotCharBlameSource(snapshot, maxCharacters, key);\n return source === null ? null : source.opIds;\n}\n\n/**\n * {@link listSnapshotCharBlameSource} is {@link listSnapshotCharOpIds} that also\n * returns each code point's text, so a caller can render the prose tinted by\n * writer (the per-range \"blame\" view) without a second snapshot reconstruction.\n * Same linear cost and `maxCharacters` guard.\n */\nexport function listSnapshotCharBlameSource(\n snapshot: Uint8Array,\n maxCharacters: number,\n key = \"text\",\n): TextCharBlameSource | null {\n const doc = new LoroDoc();\n try {\n importSnapshot(doc, snapshot);\n if (doc.getText(key).length > maxCharacters) {\n return null;\n }\n return collectTextCharBlame(doc, key);\n } finally {\n // The throwaway doc is WASM-backed and never returned — free it immediately\n // rather than waiting for GC, since blame rebuilds one per Info-panel load.\n doc.free();\n }\n}\n\nexport interface FieldEditor {\n /** The map key (e.g. `firstName`, `cardNumber`) of a structured document field. */\n key: string;\n /** Peer of the op that last set this field, or null if none is recorded. */\n peerId: `${number}` | null;\n}\n\n/**\n * The structured-document counterpart to {@link listSnapshotCharBlameSource}:\n * for a persisted snapshot, name the peer that last wrote each key of a LoroMap\n * (the document's `fields` map). Structured documents (contacts, cards, licenses)\n * store each field as a `LoroMap` entry — a last-writer-wins register that keeps\n * the setting op's peer, which `getLastEditor` reads. That peer resolves to a\n * writer via the same attribution segments,\n * giving per-field \"blame\". Fields carry only the peer (no op counter), so\n * resolution is peer-level. A note (or any document without this map) yields an\n * empty array. Reconstructing the small map is cheap, so there is no size cap.\n */\nexport function listSnapshotFieldEditors(\n snapshot: Uint8Array,\n mapKey: string,\n): FieldEditor[] {\n const doc = new LoroDoc();\n try {\n importSnapshot(doc, snapshot);\n const map = doc.getMap(mapKey);\n return map.keys().map((key) => ({\n key,\n peerId: map.getLastEditor(key) ?? null,\n }));\n } finally {\n doc.free();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["document.ts"],"names":[],"mappings":"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","sourcesContent":["import { base64ToBytes, bytesToBase64 } from \"@tearleads/encoding\";\nimport { LoroDoc, VersionVector } from \"loro-crdt\";\nimport { serializeCanonicalHistory } from \"./historyCanonicalization\";\nimport { getImportBlobMetadata } from \"./importMetadata\";\n\nexport { getImportBlobMetadata, type ImportBlobMode } from \"./importMetadata\";\n\nfunction isPeerIdString(value: string): value is `${number}` {\n return /^\\d+$/.test(value);\n}\n\nconst MAX_POSTGRES_INTEGER = 2_147_483_647;\n\nexport class LoroImportUnresolvedDependenciesError extends Error {\n readonly importKind: \"snapshot\" | \"updates\";\n\n constructor(importKind: \"snapshot\" | \"updates\") {\n super(\n `import${importKind === \"snapshot\" ? \"Snapshot\" : \"Updates\"} received ${\n importKind === \"snapshot\" ? \"a snapshot\" : \"updates\"\n } with unresolved pending dependencies`,\n );\n this.name = \"LoroImportUnresolvedDependenciesError\";\n this.importKind = importKind;\n }\n}\n\nexport interface VersionVectorSpan {\n peerId: `${number}`;\n startCounter: number;\n endCounter: number;\n}\n\nfunction assertSupportedVersionVectorCounter(counter: number): void {\n if (\n !Number.isInteger(counter) ||\n counter < 0 ||\n counter > MAX_POSTGRES_INTEGER\n ) {\n throw new Error(\n \"Version vector counter is outside the supported integer range.\",\n );\n }\n}\n\nfunction normalizeVersionVectorEntries(\n versionVector: VersionVector,\n): Map<`${number}`, number> {\n const entries = new Map<`${number}`, number>();\n\n for (const [peerId, counter] of versionVector.toJSON()) {\n const normalizedPeerId = String(peerId);\n if (!isPeerIdString(normalizedPeerId)) {\n throw new Error(\"Version vector contains a non-numeric peer ID.\");\n }\n assertSupportedVersionVectorCounter(counter);\n entries.set(normalizedPeerId, counter);\n }\n\n return entries;\n}\n\nexport async function derivePeerId(\n seed: string | Uint8Array,\n): Promise<`${number}`> {\n const bytes =\n typeof seed === \"string\" ? new TextEncoder().encode(seed) : seed;\n const digest = new Uint8Array(\n await crypto.subtle.digest(\"SHA-256\", bytes.slice()),\n );\n const view = new DataView(\n digest.buffer,\n digest.byteOffset,\n digest.byteLength,\n );\n const peerId = (view.getBigUint64(0, false) || 1n).toString();\n\n if (!isPeerIdString(peerId)) {\n throw new Error(\"Failed to derive a numeric peer ID.\");\n }\n\n return peerId;\n}\n\nexport async function createDocument(peerSeed: string | Uint8Array) {\n const doc = new LoroDoc();\n doc.setPeerId(await derivePeerId(peerSeed));\n return doc;\n}\n\nexport function exportAllUpdates(doc: LoroDoc): Uint8Array {\n return doc.export({ mode: \"update\" });\n}\n\n/** Deterministic, peer-uncompressed identity for an operation-log prefix. */\nexport function exportFullHistoryIdentity(\n doc: LoroDoc,\n endVersion?: string,\n): string {\n return serializeCanonicalHistory(\n doc.exportJsonUpdates(\n undefined,\n endVersion === undefined ? undefined : decodeVersionVector(endVersion),\n false,\n ),\n );\n}\n\n/**\n * Export a mergeable, full-history snapshot — the only snapshot form this\n * codebase produces. Every document is born with full durable history and\n * restored from it, so a partial (gc'd) export here is an invariant\n * violation, not a state to accommodate; fail loudly instead of publishing a\n * blob that could not safely merge concurrent frontiers.\n */\nexport function exportFullHistorySnapshot(doc: LoroDoc): Uint8Array {\n const snapshot = doc.export({ mode: \"snapshot\" });\n const metadata = getImportBlobMetadata(snapshot);\n if (\n metadata.mode !== \"snapshot\" ||\n !versionVectorsEqual(\n metadata.partialStartVersionVector,\n emptyVersionVector(),\n )\n ) {\n throw new Error(\n \"Document export lost full history; this document was restored from an incomplete source\",\n );\n }\n return snapshot;\n}\n\nexport function exportUpdatesSince(\n doc: LoroDoc,\n encodedVersionVector?: string | null,\n): Uint8Array {\n if (!encodedVersionVector) {\n return exportAllUpdates(doc);\n }\n\n return doc.export({\n mode: \"update\",\n from: VersionVector.decode(base64ToBytes(encodedVersionVector)),\n });\n}\n\nexport function encodeEncodedVersionVector(\n versionVector: VersionVector,\n): string {\n return bytesToBase64(versionVector.encode());\n}\n\nexport function encodeVersionVector(doc: LoroDoc): string {\n return encodeEncodedVersionVector(doc.oplogVersion());\n}\n\nexport function emptyVersionVector(): string {\n return encodeEncodedVersionVector(new VersionVector(undefined));\n}\n\nexport function decodeVersionVector(\n encodedVersionVector: string | null | undefined,\n): VersionVector {\n if (!encodedVersionVector) {\n return new VersionVector(undefined);\n }\n\n return VersionVector.decode(base64ToBytes(encodedVersionVector));\n}\n\nexport function getUpdateVersionVectors(update: Uint8Array): {\n partialStartVersionVector: string;\n partialEndVersionVector: string;\n} {\n const metadata = getImportBlobMetadata(update);\n\n return {\n partialStartVersionVector: metadata.partialStartVersionVector,\n partialEndVersionVector: metadata.partialEndVersionVector,\n };\n}\n\nexport function satisfiesVersionVector(\n encodedVersionVector: string | null | undefined,\n partialVersionVector: string,\n): boolean {\n const versionVector = decodeVersionVector(encodedVersionVector);\n const requiredVersionVector = decodeVersionVector(partialVersionVector);\n\n for (const [peerId, counter] of requiredVersionVector.toJSON()) {\n if ((versionVector.get(peerId) ?? 0) < counter) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function mergeVersionVectors(\n encodedVersionVectors: ReadonlyArray<string>,\n): string {\n const merged = new Map<`${number}`, number>();\n\n for (const encodedVersionVector of encodedVersionVectors) {\n for (const [normalizedPeerId, counter] of normalizeVersionVectorEntries(\n decodeVersionVector(encodedVersionVector),\n )) {\n merged.set(\n normalizedPeerId,\n Math.max(merged.get(normalizedPeerId) ?? 0, counter),\n );\n }\n }\n\n return encodeEncodedVersionVector(VersionVector.parseJSON(merged));\n}\n\nexport function listVersionVectorSpans(input: {\n partialStartVersionVector: string;\n partialEndVersionVector: string;\n}): VersionVectorSpan[] {\n const startEntries = normalizeVersionVectorEntries(\n decodeVersionVector(input.partialStartVersionVector),\n );\n const endEntries = normalizeVersionVectorEntries(\n decodeVersionVector(input.partialEndVersionVector),\n );\n const spans: VersionVectorSpan[] = [];\n\n for (const [peerId, startCounter] of startEntries) {\n const endCounter = endEntries.get(peerId) ?? 0;\n if (startCounter > endCounter) {\n throw new Error(\"Version vector end must cover start.\");\n }\n }\n\n for (const [peerId, endCounter] of endEntries) {\n const startCounter = startEntries.get(peerId) ?? 0;\n if (endCounter <= startCounter) {\n continue;\n }\n\n spans.push({ peerId, startCounter, endCounter });\n }\n\n return spans.sort((left, right) => left.peerId.localeCompare(right.peerId));\n}\n\nexport function versionVectorsEqual(\n left: string | null | undefined,\n right: string | null | undefined,\n): boolean {\n const leftEntries = decodeVersionVector(left).toJSON();\n const rightEntries = decodeVersionVector(right).toJSON();\n\n if (leftEntries.size !== rightEntries.size) {\n return false;\n }\n\n for (const [peerId, leftCounter] of leftEntries) {\n if (rightEntries.get(peerId) !== leftCounter) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function importUpdates(doc: LoroDoc, updates: Uint8Array[]): void {\n // Reject an obsolete member before importBatch can mutate the document.\n for (const update of updates) getImportBlobMetadata(update);\n const status = doc.importBatch(updates);\n if (status.pending != null && status.pending.size > 0) {\n // importBatch applies out-of-order batches correctly but can still report\n // the intermediate pending set it saw mid-batch. Trust the document, not\n // the report: the import only genuinely failed when the document's final\n // version does not cover some batched update's end version.\n const documentVersion = encodeVersionVector(doc);\n const covered = updates.every((update) =>\n satisfiesVersionVector(\n documentVersion,\n getImportBlobMetadata(update).partialEndVersionVector,\n ),\n );\n if (!covered) {\n throw new LoroImportUnresolvedDependenciesError(\"updates\");\n }\n }\n}\n\n/**\n * Load a snapshot blob into a document. Snapshots MUST go through a single\n * `import()`, never `importBatch()`. A non-empty `pending` means the import\n * target is incompatible or dependencies are missing, so fail loudly instead\n * of silently loading a short document.\n */\nexport function importSnapshot(doc: LoroDoc, snapshot: Uint8Array): void {\n getImportBlobMetadata(snapshot);\n const status = doc.import(snapshot);\n // Reject only a genuinely incomplete import: `pending` can be an empty\n // VersionVector (size 0) rather than null when everything resolved, so test\n // for at least one unresolved dependency instead of mere presence.\n if (status.pending != null && status.pending.size > 0) {\n throw new LoroImportUnresolvedDependenciesError(\"snapshot\");\n }\n}\n\nexport function getTextValue(doc: LoroDoc, key = \"text\"): string {\n return doc.getText(key).toString();\n}\n\nexport interface TextCharOpId {\n /** Peer of the op that inserted this character. */\n peerId: `${number}`;\n /** Counter of that op — identifies the character within the peer's stream. */\n counter: number;\n}\n\nexport interface TextCharBlameSource {\n /** One entry per Unicode code point of the prose, in document order. */\n codePoints: string[];\n /** The op id that inserted each code point — same length and order as `codePoints`. */\n opIds: TextCharOpId[];\n}\n\n/**\n * Walk a LoroText's prose once, collecting each Unicode code point alongside the\n * op id `(peerId, counter)` of the op that inserted it. The two arrays share an\n * index, so callers can both blame and re-render the prose (the per-range view)\n * from a single pass.\n *\n * One Loro op (one counter) is one code point, but an astral character spans\n * two UTF-16 units. Loro 1.16.4 resolves the cursor at the first unit and rejects\n * the interior low-surrogate position. Iterate code points and advance by their\n * UTF-16 length so attribution neither splits nor double-counts a character.\n */\nfunction collectTextCharBlame(doc: LoroDoc, key: string): TextCharBlameSource {\n const text = doc.getText(key);\n const codePoints: string[] = [];\n const opIds: TextCharOpId[] = [];\n let utf16Start = 0;\n for (const char of text.toString()) {\n // getCursor mints a WASM-backed Cursor each call; free it immediately after\n // reading its op id so a long document does not pile up cursors on the heap.\n const cursor = text.getCursor(utf16Start, 1);\n const opId = cursor?.pos();\n cursor?.free();\n if (opId === undefined) {\n throw new Error(\n `LoroText \"${key}\" code point starting at UTF-16 index ${utf16Start} has no op id.`,\n );\n }\n codePoints.push(char);\n opIds.push({ peerId: opId.peer, counter: opId.counter });\n utf16Start += char.length;\n }\n return { codePoints, opIds };\n}\n\n/**\n * Per-character op-id attribution for a LoroText container's prose. Returns one\n * `(peerId, counter)` per Unicode code point — the op that inserted that\n * character — in document order; the array length equals the code-point count\n * (`[...text].length`). This is the client-side primitive for character-level\n * \"blame\": each op id resolves to a writer by intersecting it against the\n * document's edit-attribution segments.\n */\nexport function listTextCharOpIds(doc: LoroDoc, key = \"text\"): TextCharOpId[] {\n return collectTextCharBlame(doc, key).opIds;\n}\n\n/**\n * {@link listTextCharOpIds} for a persisted snapshot blob, without opening an\n * editor: rebuilds a throwaway read-only `LoroDoc` from the snapshot and reads\n * each character's op id, so blame is exact. The doc is only read, never\n * edited, so no peer id is set.\n *\n * Extraction is linear: `getCursor()` is an O(log n) b-tree lookup per code\n * point (measured ~1.8µs/char — ~90ms for a 50k-char snapshot, flat per char and\n * unaffected by tombstones). `maxCharacters` (UTF-16 length) is therefore a soft\n * guard against pathologically large prose, not a quadratic cliff: over it we\n * return `null` (\"skipped, too large\", distinct from `[]` for an empty document)\n * rather than do unbounded synchronous work on the render thread.\n */\nexport function listSnapshotCharOpIds(\n snapshot: Uint8Array,\n maxCharacters: number,\n key = \"text\",\n): TextCharOpId[] | null {\n const source = listSnapshotCharBlameSource(snapshot, maxCharacters, key);\n return source === null ? null : source.opIds;\n}\n\n/**\n * {@link listSnapshotCharBlameSource} is {@link listSnapshotCharOpIds} that also\n * returns each code point's text, so a caller can render the prose tinted by\n * writer (the per-range \"blame\" view) without a second snapshot reconstruction.\n * Same linear cost and `maxCharacters` guard.\n */\nexport function listSnapshotCharBlameSource(\n snapshot: Uint8Array,\n maxCharacters: number,\n key = \"text\",\n): TextCharBlameSource | null {\n const doc = new LoroDoc();\n try {\n importSnapshot(doc, snapshot);\n if (doc.getText(key).length > maxCharacters) {\n return null;\n }\n return collectTextCharBlame(doc, key);\n } finally {\n // The throwaway doc is WASM-backed and never returned — free it immediately\n // rather than waiting for GC, since blame rebuilds one per Info-panel load.\n doc.free();\n }\n}\n\nexport interface FieldEditor {\n /** The map key (e.g. `firstName`, `cardNumber`) of a structured document field. */\n key: string;\n /** Peer of the op that last set this field, or null if none is recorded. */\n peerId: `${number}` | null;\n}\n\n/**\n * The structured-document counterpart to {@link listSnapshotCharBlameSource}:\n * for a persisted snapshot, name the peer that last wrote each key of a LoroMap\n * (the document's `fields` map). Structured documents (contacts, cards, licenses)\n * store each field as a `LoroMap` entry — a last-writer-wins register that keeps\n * the setting op's peer, which `getLastEditor` reads. That peer resolves to a\n * writer via the same attribution segments,\n * giving per-field \"blame\". Fields carry only the peer (no op counter), so\n * resolution is peer-level. A note (or any document without this map) yields an\n * empty array. Reconstructing the small map is cheap, so there is no size cap.\n */\nexport function listSnapshotFieldEditors(\n snapshot: Uint8Array,\n mapKey: string,\n): FieldEditor[] {\n const doc = new LoroDoc();\n try {\n importSnapshot(doc, snapshot);\n const map = doc.getMap(mapKey);\n return map.keys().map((key) => ({\n key,\n peerId: map.getLastEditor(key) ?? null,\n }));\n } finally {\n doc.free();\n }\n}\n"]}
|