@abraca/dabra 2.6.0 → 2.8.0
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 +65 -7
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +65 -8
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +32 -4
- package/package.json +2 -2
- package/src/AbracadabraBaseProvider.ts +15 -0
- package/src/ContentManager.ts +8 -6
- package/src/DocUtils.ts +62 -3
- package/src/index.ts +1 -0
|
@@ -2298,6 +2298,21 @@ var QueryClient = class extends EventEmitter {
|
|
|
2298
2298
|
}
|
|
2299
2299
|
};
|
|
2300
2300
|
|
|
2301
|
+
//#endregion
|
|
2302
|
+
//#region packages/provider/src/OutgoingMessages/QueryAwarenessMessage.ts
|
|
2303
|
+
var QueryAwarenessMessage = class extends OutgoingMessage {
|
|
2304
|
+
constructor(..._args) {
|
|
2305
|
+
super(..._args);
|
|
2306
|
+
this.type = MessageType.QueryAwareness;
|
|
2307
|
+
this.description = "Queries awareness states";
|
|
2308
|
+
}
|
|
2309
|
+
get(args) {
|
|
2310
|
+
writeVarString(this.encoder, args.documentName);
|
|
2311
|
+
writeVarUint(this.encoder, this.type);
|
|
2312
|
+
return this.encoder;
|
|
2313
|
+
}
|
|
2314
|
+
};
|
|
2315
|
+
|
|
2301
2316
|
//#endregion
|
|
2302
2317
|
//#region packages/provider/src/OutgoingMessages/SyncStepOneMessage.ts
|
|
2303
2318
|
var SyncStepOneMessage = class extends OutgoingMessage {
|
|
@@ -2580,6 +2595,7 @@ var AbracadabraBaseProvider = class extends EventEmitter {
|
|
|
2580
2595
|
clients: [this.document.clientID],
|
|
2581
2596
|
documentName: this.configuration.name
|
|
2582
2597
|
});
|
|
2598
|
+
if (this.awareness) this.send(QueryAwarenessMessage, { documentName: this.configuration.name });
|
|
2583
2599
|
}
|
|
2584
2600
|
send(message, args) {
|
|
2585
2601
|
if (!this._isAttached) return;
|
|
@@ -15660,6 +15676,19 @@ function makeEntryMap(fields) {
|
|
|
15660
15676
|
return m;
|
|
15661
15677
|
}
|
|
15662
15678
|
/**
|
|
15679
|
+
* A label is a "placeholder" — i.e. carries no real user title — when it is
|
|
15680
|
+
* empty/whitespace, null/undefined, or the literal `"Untitled"` sentinel
|
|
15681
|
+
* (case-insensitive, so `"untitled"` from a `labelToFilename` round-trip is
|
|
15682
|
+
* caught too). The whole tree-label corruption class boils down to a
|
|
15683
|
+
* placeholder being allowed to overwrite a real title; `patchEntry` refuses
|
|
15684
|
+
* exactly that. Mirrors cou-sh's `isEmptyTreeLabel`.
|
|
15685
|
+
*/
|
|
15686
|
+
function isPlaceholderLabel(label) {
|
|
15687
|
+
if (typeof label !== "string") return label == null;
|
|
15688
|
+
const t = label.trim();
|
|
15689
|
+
return t === "" || t.toLowerCase() === "untitled";
|
|
15690
|
+
}
|
|
15691
|
+
/**
|
|
15663
15692
|
* Patch an EXISTING entry's fields per-key on its nested `Y.Map`, so a
|
|
15664
15693
|
* concurrent edit to a *different* field by a peer is preserved instead
|
|
15665
15694
|
* of being clobbered by a whole-entry write — the whole-entry-LWW fix
|
|
@@ -15674,21 +15703,44 @@ function makeEntryMap(fields) {
|
|
|
15674
15703
|
* Self-transacting: it batches its writes in one `Y.Doc` transaction
|
|
15675
15704
|
* (a safe reentrant no-op join when already inside one), so callers
|
|
15676
15705
|
* don't need to pass or own a transaction.
|
|
15706
|
+
*
|
|
15707
|
+
* ── NO-DESTROY LABEL INVARIANT ──────────────────────────────────────────
|
|
15708
|
+
* A `label` patch that is a placeholder (empty/whitespace/"Untitled") is
|
|
15709
|
+
* DROPPED when the entry already holds a real (non-placeholder) label —
|
|
15710
|
+
* regardless of which consumer (cou-sh title-sync, fs-sync rename
|
|
15711
|
+
* detection, MCP, table renderers, a stale snapshot) tried it. This is the
|
|
15712
|
+
* source-of-truth guard against the "card title silently becomes Untitled
|
|
15713
|
+
* / files renamed to untitled.md" corruption: a placeholder must never win
|
|
15714
|
+
* over a real title. Creating a brand-new entry with an empty label (e.g.
|
|
15715
|
+
* a fresh kanban card) is still allowed — the guard only fires when a real
|
|
15716
|
+
* label already exists. Pass `{ allowLabelClear: true }` to override (the
|
|
15717
|
+
* single legitimate "user explicitly cleared it" path).
|
|
15677
15718
|
*/
|
|
15678
|
-
function patchEntry(treeMap, id, patch, removeKeys = []) {
|
|
15719
|
+
function patchEntry(treeMap, id, patch, removeKeys = [], opts = {}) {
|
|
15679
15720
|
const apply = () => {
|
|
15680
15721
|
const raw = treeMap.get(id);
|
|
15722
|
+
let effectivePatch = patch;
|
|
15723
|
+
if (!opts.allowLabelClear && Object.hasOwn(patch, "label") && isPlaceholderLabel(patch.label)) {
|
|
15724
|
+
let existingLabel;
|
|
15725
|
+
if (raw != null && typeof raw.get === "function") existingLabel = raw.get("label");
|
|
15726
|
+
else if (raw != null && typeof raw.toJSON === "function") existingLabel = raw.toJSON()?.label;
|
|
15727
|
+
else if (raw != null && typeof raw === "object") existingLabel = raw.label;
|
|
15728
|
+
if (!isPlaceholderLabel(existingLabel)) {
|
|
15729
|
+
const { label: _dropped, ...rest } = patch;
|
|
15730
|
+
effectivePatch = rest;
|
|
15731
|
+
}
|
|
15732
|
+
}
|
|
15681
15733
|
if (raw instanceof Y.Map) {
|
|
15682
|
-
for (const [k, v] of Object.entries(
|
|
15734
|
+
for (const [k, v] of Object.entries(effectivePatch)) if (v === void 0) raw.delete(k);
|
|
15683
15735
|
else raw.set(k, v);
|
|
15684
15736
|
for (const k of removeKeys) raw.delete(k);
|
|
15685
15737
|
return;
|
|
15686
15738
|
}
|
|
15687
15739
|
const merged = {
|
|
15688
15740
|
...raw == null ? {} : toPlain(raw),
|
|
15689
|
-
...
|
|
15741
|
+
...effectivePatch
|
|
15690
15742
|
};
|
|
15691
|
-
for (const [k, v] of Object.entries(
|
|
15743
|
+
for (const [k, v] of Object.entries(effectivePatch)) if (v === void 0) delete merged[k];
|
|
15692
15744
|
for (const k of removeKeys) delete merged[k];
|
|
15693
15745
|
treeMap.set(id, makeEntryMap(merged));
|
|
15694
15746
|
};
|
|
@@ -20255,8 +20307,13 @@ var ContentManager = class {
|
|
|
20255
20307
|
}
|
|
20256
20308
|
/**
|
|
20257
20309
|
* Read document content as markdown.
|
|
20258
|
-
*
|
|
20259
|
-
* body, tree
|
|
20310
|
+
*
|
|
20311
|
+
* Returns the markdown body, tree-derived label/type/meta, and immediate
|
|
20312
|
+
* children. `title` mirrors `label` (the tree entry's display name) — it
|
|
20313
|
+
* is *not* derived from a TipTap `documentHeader`, and the markdown body
|
|
20314
|
+
* does NOT include YAML frontmatter. Callers that want frontmatter-style
|
|
20315
|
+
* round-tripping should serialise `meta`/`type` themselves on top of the
|
|
20316
|
+
* returned markdown.
|
|
20260
20317
|
*/
|
|
20261
20318
|
async read(docId) {
|
|
20262
20319
|
const fragment = (await this.dm.getChildProvider(docId)).document.getXmlFragment("default");
|
|
@@ -20291,7 +20348,7 @@ var ContentManager = class {
|
|
|
20291
20348
|
type,
|
|
20292
20349
|
meta
|
|
20293
20350
|
}));
|
|
20294
|
-
const markdown = yjsToMarkdown(fragment
|
|
20351
|
+
const { markdown } = yjsToMarkdown(fragment);
|
|
20295
20352
|
return {
|
|
20296
20353
|
label,
|
|
20297
20354
|
type,
|
|
@@ -20723,5 +20780,5 @@ var DocumentManager = class {
|
|
|
20723
20780
|
};
|
|
20724
20781
|
|
|
20725
20782
|
//#endregion
|
|
20726
|
-
export { AbracadabraBaseProvider, AbracadabraClient, AbracadabraProvider, AbracadabraWS, AbracadabraWebRTC, AuthMessageType, AwarenessError, BackgroundSyncManager, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, ChannelKeyResolver, ChatClient, ConnectionTimeout, ContentManager, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, DeviceRegistrationService, DocKeyManager, DocumentCache, DocumentManager, E2EAbracadabraProvider, E2EEChannel, E2EOfflineStore, EncryptedChatClient, EncryptedYMap, EncryptedYText, FileBlobStore, FileTransferChannel, FileTransferHandle, Forbidden, GEO_TYPE_META_SCHEMAS, HocuspocusProvider, HocuspocusProviderWebsocket, IdentityDocProvider, KEY_EXCHANGE_CHANNEL, Kind, LocalStorageDeviceSessionStorage, ManualSignaling, MessageTooBig, MessageType, MetaManager, MetaValidationError, NotificationsClient, OfflineStore, PAGE_TYPES, PeerConnection, QUERY_PREFIX, QueryClient, QueryError, RPC_PREFIX, ResetConnection, RpcClient, RpcError, SERVER_ROOT_ID, SearchIndex, SignalingSocket, SubdocMessage, TYPE_ALIASES, TokenManager, TreeManager, TypedDocTypeMismatchError, Unauthorized, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, buildBlockquoteElement, buildBlocksFromMarkdown, buildBulletListElement, buildCodeBlockElement, buildHeadingElement, buildHorizontalRuleElement, buildOrderedListElement, buildParagraphElement, buildTaskListElement, decryptChatContent, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptChatContent, encryptField, filenameToLabel, foldRecords, generateMnemonic, isEncryptedContent, makeEncryptedYMap, makeEncryptedYText, makeEntryMap, mnemonicToEd25519Seed, mnemonicToKeyPair, normalizeRootId, parseFrontmatter, patchEntry, populateYDocFromMarkdown, readAuthMessage, readBlocksFromFragment, recordFromYAny, resolvePageType, toPlain, unwrapSeed, validateMnemonic, waitForSync, withTimeout, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest, yjsToMarkdown };
|
|
20783
|
+
export { AbracadabraBaseProvider, AbracadabraClient, AbracadabraProvider, AbracadabraWS, AbracadabraWebRTC, AuthMessageType, AwarenessError, BackgroundSyncManager, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, ChannelKeyResolver, ChatClient, ConnectionTimeout, ContentManager, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, DeviceRegistrationService, DocKeyManager, DocumentCache, DocumentManager, E2EAbracadabraProvider, E2EEChannel, E2EOfflineStore, EncryptedChatClient, EncryptedYMap, EncryptedYText, FileBlobStore, FileTransferChannel, FileTransferHandle, Forbidden, GEO_TYPE_META_SCHEMAS, HocuspocusProvider, HocuspocusProviderWebsocket, IdentityDocProvider, KEY_EXCHANGE_CHANNEL, Kind, LocalStorageDeviceSessionStorage, ManualSignaling, MessageTooBig, MessageType, MetaManager, MetaValidationError, NotificationsClient, OfflineStore, PAGE_TYPES, PeerConnection, QUERY_PREFIX, QueryClient, QueryError, RPC_PREFIX, ResetConnection, RpcClient, RpcError, SERVER_ROOT_ID, SearchIndex, SignalingSocket, SubdocMessage, TYPE_ALIASES, TokenManager, TreeManager, TypedDocTypeMismatchError, Unauthorized, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, buildBlockquoteElement, buildBlocksFromMarkdown, buildBulletListElement, buildCodeBlockElement, buildHeadingElement, buildHorizontalRuleElement, buildOrderedListElement, buildParagraphElement, buildTaskListElement, decryptChatContent, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptChatContent, encryptField, filenameToLabel, foldRecords, generateMnemonic, isEncryptedContent, isPlaceholderLabel, makeEncryptedYMap, makeEncryptedYText, makeEntryMap, mnemonicToEd25519Seed, mnemonicToKeyPair, normalizeRootId, parseFrontmatter, patchEntry, populateYDocFromMarkdown, readAuthMessage, readBlocksFromFragment, recordFromYAny, resolvePageType, toPlain, unwrapSeed, validateMnemonic, waitForSync, withTimeout, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest, yjsToMarkdown };
|
|
20727
20784
|
//# sourceMappingURL=abracadabra-provider.esm.js.map
|