@abraca/dabra 1.8.1 → 1.9.1
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/dist/abracadabra-provider.cjs +129 -3
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +129 -3
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +61 -1
- package/package.json +1 -1
- package/src/AbracadabraBaseProvider.ts +3 -3
- package/src/ContentManager.ts +160 -0
- package/src/DocConverters.ts +1707 -0
- package/src/DocTypes.ts +618 -0
- package/src/DocUtils.ts +89 -0
- package/src/DocumentManager.ts +342 -0
- package/src/E2EAbracadabraProvider.ts +189 -0
- package/src/FileBlobStore.ts +10 -0
- package/src/MetaManager.ts +100 -0
- package/src/TreeManager.ts +429 -0
- package/src/types.ts +9 -0
package/dist/index.d.ts
CHANGED
|
@@ -1160,10 +1160,17 @@ type onAwarenessChangeParameters = {
|
|
|
1160
1160
|
type onStatelessParameters = {
|
|
1161
1161
|
payload: string;
|
|
1162
1162
|
};
|
|
1163
|
+
/** Fired by E2EAbracadabraProvider when the server acknowledges an E2E
|
|
1164
|
+
* client-side compaction (via the `snapshot:compacted` stateless broadcast). */
|
|
1165
|
+
type onCompactedParameters = {
|
|
1166
|
+
docId: string; /** User id that performed the compaction; undefined if payload was malformed. */
|
|
1167
|
+
by: string | undefined;
|
|
1168
|
+
};
|
|
1163
1169
|
type onServerErrorParameters = {
|
|
1164
1170
|
source: string;
|
|
1165
1171
|
code: string;
|
|
1166
1172
|
message: string;
|
|
1173
|
+
meta?: Record<string, unknown>;
|
|
1167
1174
|
};
|
|
1168
1175
|
type StatesArray = {
|
|
1169
1176
|
clientId: number;
|
|
@@ -1804,6 +1811,13 @@ declare class FileBlobStore extends EventEmitter {
|
|
|
1804
1811
|
* the object URL reference is stale.
|
|
1805
1812
|
*/
|
|
1806
1813
|
invalidateUrl(docId: string, uploadId: string): void;
|
|
1814
|
+
/**
|
|
1815
|
+
* Clear the 404 negative-cache entry for (docId, uploadId) so the next
|
|
1816
|
+
* getBlobUrl() re-fetches from the server instead of short-circuiting.
|
|
1817
|
+
* Use on explicit user retry or after reconnect, when the file may have
|
|
1818
|
+
* become available since the last 404.
|
|
1819
|
+
*/
|
|
1820
|
+
clearNotFound(docId: string, uploadId: string): void;
|
|
1807
1821
|
/** Revoke the object URL and remove the blob from cache. */
|
|
1808
1822
|
evictBlob(docId: string, uploadId: string): Promise<void>;
|
|
1809
1823
|
/**
|
|
@@ -1830,6 +1844,31 @@ interface E2EAbracadabraProviderConfiguration extends AbracadabraProviderConfigu
|
|
|
1830
1844
|
docKeyManager: DocKeyManager;
|
|
1831
1845
|
keystore: CryptoIdentityKeystore;
|
|
1832
1846
|
client: AbracadabraClient;
|
|
1847
|
+
/**
|
|
1848
|
+
* Enable client-side compaction: after `compactionThreshold` E2E updates,
|
|
1849
|
+
* the provider merges the whole doc, re-encrypts it, and asks the server to
|
|
1850
|
+
* atomically replace its update log via the `snapshot:compact` stateless
|
|
1851
|
+
* protocol. Requires the user to have a role that `can_manage` the doc
|
|
1852
|
+
* (Owner or above); otherwise the server silently rejects.
|
|
1853
|
+
*
|
|
1854
|
+
* Default: true.
|
|
1855
|
+
*/
|
|
1856
|
+
compactionEnabled?: boolean;
|
|
1857
|
+
/**
|
|
1858
|
+
* Number of E2E updates applied in this session before compaction fires.
|
|
1859
|
+
* Default: 50. Ignored when `compactionEnabled === false`.
|
|
1860
|
+
*/
|
|
1861
|
+
compactionThreshold?: number;
|
|
1862
|
+
/**
|
|
1863
|
+
* Quiescence delay: once the threshold is crossed, wait this many ms with
|
|
1864
|
+
* no further updates before firing compaction. Debounces active editing
|
|
1865
|
+
* and reduces the chance of racing an in-flight remote update that hasn't
|
|
1866
|
+
* reached us yet (the server does not currently validate state-vector
|
|
1867
|
+
* coverage, so a compaction fired mid-flight could drop an update).
|
|
1868
|
+
*
|
|
1869
|
+
* Default: 2000 ms.
|
|
1870
|
+
*/
|
|
1871
|
+
compactionQuiescenceMs?: number;
|
|
1833
1872
|
}
|
|
1834
1873
|
declare class E2EAbracadabraProvider extends AbracadabraProvider {
|
|
1835
1874
|
private readonly docKeyManager;
|
|
@@ -1840,6 +1879,16 @@ declare class E2EAbracadabraProvider extends AbracadabraProvider {
|
|
|
1840
1879
|
/** E2E-encrypted offline store; created after the doc key is available. */
|
|
1841
1880
|
private e2eStore;
|
|
1842
1881
|
private readonly e2eServerOrigin;
|
|
1882
|
+
private readonly compactionEnabled;
|
|
1883
|
+
private readonly compactionThreshold;
|
|
1884
|
+
private readonly compactionQuiescenceMs;
|
|
1885
|
+
private updatesSinceCompaction;
|
|
1886
|
+
private compactionInFlight;
|
|
1887
|
+
/** Cleared on `snapshot:compacted` or on 30s timeout. */
|
|
1888
|
+
private compactionInFlightTimeout;
|
|
1889
|
+
/** Quiescence debounce: reset on every update, fires the actual compaction. */
|
|
1890
|
+
private compactionDebounceTimer;
|
|
1891
|
+
private destroyed;
|
|
1843
1892
|
constructor(configuration: E2EAbracadabraProviderConfiguration);
|
|
1844
1893
|
/** Fetch the doc key from the server (requires WebAuthn if not cached). */
|
|
1845
1894
|
private ensureDocKey;
|
|
@@ -1850,6 +1899,17 @@ declare class E2EAbracadabraProvider extends AbracadabraProvider {
|
|
|
1850
1899
|
/** Encrypt local updates before sending over WebSocket. */
|
|
1851
1900
|
documentUpdateHandler(update: Uint8Array, origin: unknown): void;
|
|
1852
1901
|
private _encryptAndSend;
|
|
1902
|
+
/**
|
|
1903
|
+
* Force an immediate compaction attempt, bypassing the threshold and
|
|
1904
|
+
* quiescence debounce. Resolves once the `snapshot:compact` frame has been
|
|
1905
|
+
* sent (or rejected locally for missing prerequisites — destroyed, no
|
|
1906
|
+
* doc key, or already in-flight). The server acknowledges via a
|
|
1907
|
+
* `snapshot:compacted` broadcast, which emits the `"compacted"` event.
|
|
1908
|
+
*/
|
|
1909
|
+
compactNow(): Promise<void>;
|
|
1910
|
+
private _noteUpdateApplied;
|
|
1911
|
+
private _performCompaction;
|
|
1912
|
+
private _handleCompactedBroadcast;
|
|
1853
1913
|
destroy(): void;
|
|
1854
1914
|
}
|
|
1855
1915
|
//#endregion
|
|
@@ -3097,4 +3157,4 @@ declare function wrapSeed(seed: Uint8Array, wrappingKeyBytes: Uint8Array): Promi
|
|
|
3097
3157
|
*/
|
|
3098
3158
|
declare function unwrapSeed(ciphertext: ArrayBuffer, iv: Uint8Array, wrappingKeyBytes: Uint8Array): Promise<Uint8Array>;
|
|
3099
3159
|
//#endregion
|
|
3100
|
-
export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebRTC, type AbracadabraWebRTCConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, type ChatChannel, ChatClient, type ChatClientTransport, type ChatMessage, type ChatReadCursor, type ChatReadReceipt, type ChatTypingEvent, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, type CreateNotificationInput, CryptoIdentity, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, type DevicePairingConfig, DeviceRegistrationService, type DeviceServerStatus, type DeviceTier, type DocEncryptionInfo, DocKeyManager, type DocSyncState, DocumentCache, type DocumentCacheOptions, DocumentMeta, E2EAbracadabraProvider, E2EEChannel, type E2EEIdentity, E2EOfflineStore, EffectivePermissionEntry, EffectivePermissionsResponse, EffectiveRole, EncryptedYMap, EncryptedYText, type FetchNotificationsInput, FileBlobStore, FileTransferChannel, FileTransferHandle, type FileTransferMeta, type FileTransferStatus, Forbidden, type GetChatHistoryInput, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, type IdentityDeviceEntry, type IdentityDocConfiguration, IdentityDocProvider, type IdentityProfile, type IdentityServerEntry, type IdentitySpaceEntry, InviteRow, KEY_EXCHANGE_CHANNEL, ManualSignaling, type ManualSignalingBlob, MessageTooBig, MessageType, type NotificationReadUpdate, type NotificationRecord, NotificationsClient, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, type PairingRequest, type PairingResult, PeerConnection, type PeerInfo, type PeerState, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, type SendChatMessageInput, ServerInfo, type SignalingIncoming, type SignalingOutgoing, SignalingSocket, SnapshotCreateResult, SnapshotData, SnapshotForkResult, SnapshotMeta, SnapshotRestoreResult, SpaceMeta, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onServerErrorParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
|
|
3160
|
+
export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebRTC, type AbracadabraWebRTCConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, type ChatChannel, ChatClient, type ChatClientTransport, type ChatMessage, type ChatReadCursor, type ChatReadReceipt, type ChatTypingEvent, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, type CreateNotificationInput, CryptoIdentity, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, type DevicePairingConfig, DeviceRegistrationService, type DeviceServerStatus, type DeviceTier, type DocEncryptionInfo, DocKeyManager, type DocSyncState, DocumentCache, type DocumentCacheOptions, DocumentMeta, E2EAbracadabraProvider, E2EEChannel, type E2EEIdentity, E2EOfflineStore, EffectivePermissionEntry, EffectivePermissionsResponse, EffectiveRole, EncryptedYMap, EncryptedYText, type FetchNotificationsInput, FileBlobStore, FileTransferChannel, FileTransferHandle, type FileTransferMeta, type FileTransferStatus, Forbidden, type GetChatHistoryInput, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, type IdentityDeviceEntry, type IdentityDocConfiguration, IdentityDocProvider, type IdentityProfile, type IdentityServerEntry, type IdentitySpaceEntry, InviteRow, KEY_EXCHANGE_CHANNEL, ManualSignaling, type ManualSignalingBlob, MessageTooBig, MessageType, type NotificationReadUpdate, type NotificationRecord, NotificationsClient, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, type PairingRequest, type PairingResult, PeerConnection, type PeerInfo, type PeerState, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, type SendChatMessageInput, ServerInfo, type SignalingIncoming, type SignalingOutgoing, SignalingSocket, SnapshotCreateResult, SnapshotData, SnapshotForkResult, SnapshotMeta, SnapshotRestoreResult, SpaceMeta, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onCompactedParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onServerErrorParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
|
package/package.json
CHANGED
|
@@ -375,9 +375,9 @@ export class AbracadabraBaseProvider extends EventEmitter {
|
|
|
375
375
|
try {
|
|
376
376
|
const parsed = JSON.parse(payload);
|
|
377
377
|
if (parsed?.type === "error" && parsed.source && parsed.code) {
|
|
378
|
-
const { source, code, message } = parsed;
|
|
379
|
-
console.warn(`[Abracadabra] Server error: ${source} (${code}) — ${message}
|
|
380
|
-
this.emit("serverError", { source, code, message: message ?? "" });
|
|
378
|
+
const { source, code, message, meta } = parsed;
|
|
379
|
+
console.warn(`[Abracadabra] Server error: ${source} (${code}) — ${message}`, meta ?? "");
|
|
380
|
+
this.emit("serverError", { source, code, message: message ?? "", meta });
|
|
381
381
|
return;
|
|
382
382
|
}
|
|
383
383
|
} catch {
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContentManager — read/write document content via markdown ↔ Y.js conversion.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `mcp/tools/content.ts` and `cli/commands/content.ts`.
|
|
5
|
+
*/
|
|
6
|
+
import * as Y from "yjs";
|
|
7
|
+
import type { PageMeta } from "./DocTypes.ts";
|
|
8
|
+
import { toPlain } from "./DocUtils.ts";
|
|
9
|
+
import {
|
|
10
|
+
yjsToMarkdown,
|
|
11
|
+
populateYDocFromMarkdown,
|
|
12
|
+
parseFrontmatter,
|
|
13
|
+
} from "./DocConverters.ts";
|
|
14
|
+
import type { DocumentManager } from "./DocumentManager.ts";
|
|
15
|
+
|
|
16
|
+
export interface DocumentContent {
|
|
17
|
+
label: string;
|
|
18
|
+
type?: string;
|
|
19
|
+
meta?: PageMeta;
|
|
20
|
+
title: string;
|
|
21
|
+
markdown: string;
|
|
22
|
+
children: Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
label: string;
|
|
25
|
+
type?: string;
|
|
26
|
+
meta?: PageMeta;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ContentManager {
|
|
31
|
+
constructor(private dm: DocumentManager) {}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Read document content as markdown.
|
|
35
|
+
* Returns the title extracted from the TipTap documentHeader, the markdown
|
|
36
|
+
* body, tree metadata, and immediate children.
|
|
37
|
+
*/
|
|
38
|
+
async read(docId: string): Promise<DocumentContent> {
|
|
39
|
+
const provider = await this.dm.getChildProvider(docId);
|
|
40
|
+
const fragment = provider.document.getXmlFragment("default");
|
|
41
|
+
|
|
42
|
+
const { title, markdown } = yjsToMarkdown(fragment);
|
|
43
|
+
|
|
44
|
+
// Get tree metadata + immediate children
|
|
45
|
+
const treeMap = this.dm.getTreeMap();
|
|
46
|
+
let label = title;
|
|
47
|
+
let type: string | undefined;
|
|
48
|
+
let meta: PageMeta | undefined;
|
|
49
|
+
let children: Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
type?: string;
|
|
53
|
+
meta?: PageMeta;
|
|
54
|
+
}> = [];
|
|
55
|
+
|
|
56
|
+
if (treeMap) {
|
|
57
|
+
const raw = treeMap.get(docId);
|
|
58
|
+
if (raw) {
|
|
59
|
+
const entry = toPlain(raw) as Record<string, unknown>;
|
|
60
|
+
label = (entry.label as string) || title;
|
|
61
|
+
type = entry.type as string | undefined;
|
|
62
|
+
meta = entry.meta as PageMeta | undefined;
|
|
63
|
+
}
|
|
64
|
+
// Collect immediate children sorted by order
|
|
65
|
+
treeMap.forEach((value: any, id: string) => {
|
|
66
|
+
if (value.parentId === docId) {
|
|
67
|
+
children.push({
|
|
68
|
+
id,
|
|
69
|
+
label: value.label || "Untitled",
|
|
70
|
+
type: value.type,
|
|
71
|
+
meta: value.meta,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
children.sort((a, b) => {
|
|
76
|
+
const orderA = treeMap.get(a.id)?.order ?? 0;
|
|
77
|
+
const orderB = treeMap.get(b.id)?.order ?? 0;
|
|
78
|
+
return orderA - orderB;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { label, type, meta, title, markdown, children };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Write markdown content to a document.
|
|
87
|
+
* Supports optional YAML frontmatter for title and metadata.
|
|
88
|
+
*
|
|
89
|
+
* @param mode - "replace" clears existing content first (default),
|
|
90
|
+
* "append" adds to the end.
|
|
91
|
+
*/
|
|
92
|
+
async write(
|
|
93
|
+
docId: string,
|
|
94
|
+
markdown: string,
|
|
95
|
+
mode: "replace" | "append" = "replace",
|
|
96
|
+
): Promise<void> {
|
|
97
|
+
const provider = await this.dm.getChildProvider(docId);
|
|
98
|
+
const doc = provider.document;
|
|
99
|
+
const fragment = doc.getXmlFragment("default");
|
|
100
|
+
|
|
101
|
+
// Parse optional frontmatter
|
|
102
|
+
const { title, meta, body } = parseFrontmatter(markdown);
|
|
103
|
+
|
|
104
|
+
// Update tree metadata if frontmatter provided title or meta
|
|
105
|
+
if (title || Object.keys(meta).length > 0) {
|
|
106
|
+
const treeMap = this.dm.getTreeMap();
|
|
107
|
+
const rootDoc = this.dm.rootDocument;
|
|
108
|
+
if (treeMap && rootDoc) {
|
|
109
|
+
const entry = treeMap.get(docId);
|
|
110
|
+
if (entry) {
|
|
111
|
+
rootDoc.transact(() => {
|
|
112
|
+
const updates: Record<string, unknown> = {
|
|
113
|
+
...entry,
|
|
114
|
+
updatedAt: Date.now(),
|
|
115
|
+
};
|
|
116
|
+
if (title) updates.label = title;
|
|
117
|
+
if (Object.keys(meta).length > 0) {
|
|
118
|
+
updates.meta = {
|
|
119
|
+
...(entry.meta ?? {}),
|
|
120
|
+
...meta,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
treeMap.set(docId, updates);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (mode === "replace") {
|
|
130
|
+
// Clear existing content
|
|
131
|
+
doc.transact(() => {
|
|
132
|
+
while (fragment.length > 0) {
|
|
133
|
+
fragment.delete(0);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Write new content
|
|
139
|
+
const contentToWrite = body || markdown;
|
|
140
|
+
const fallbackTitle = title || "Untitled";
|
|
141
|
+
populateYDocFromMarkdown(fragment, contentToWrite, fallbackTitle);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Get the raw Y.XmlFragment for a document (the 'default' fragment
|
|
146
|
+
* that TipTap uses for document content).
|
|
147
|
+
*/
|
|
148
|
+
async getFragment(docId: string): Promise<Y.XmlFragment> {
|
|
149
|
+
const provider = await this.dm.getChildProvider(docId);
|
|
150
|
+
return provider.document.getXmlFragment("default");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get the raw Y.Doc for a document (synced).
|
|
155
|
+
*/
|
|
156
|
+
async getDoc(docId: string): Promise<Y.Doc> {
|
|
157
|
+
const provider = await this.dm.getChildProvider(docId);
|
|
158
|
+
return provider.document;
|
|
159
|
+
}
|
|
160
|
+
}
|