@storacha/clawracha 0.2.2 → 0.3.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/commands.d.ts +3 -2
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +160 -25
- package/dist/handlers/process.d.ts +5 -1
- package/dist/handlers/process.d.ts.map +1 -1
- package/dist/handlers/process.js +68 -25
- package/dist/handlers/remote.d.ts +4 -0
- package/dist/handlers/remote.d.ts.map +1 -1
- package/dist/handlers/remote.js +36 -4
- package/dist/mdsync/index.d.ts +58 -15
- package/dist/mdsync/index.d.ts.map +1 -1
- package/dist/mdsync/index.js +87 -162
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +52 -106
- package/dist/sync.d.ts +3 -0
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +28 -2
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/bundle.d.ts +19 -0
- package/dist/utils/bundle.d.ts.map +1 -0
- package/dist/utils/bundle.js +67 -0
- package/dist/utils/crypto.d.ts +32 -0
- package/dist/utils/crypto.d.ts.map +1 -0
- package/dist/utils/crypto.js +90 -0
- package/package.json +4 -2
package/dist/mdsync/index.js
CHANGED
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* mdsync — CRDT markdown storage on top of UCN Pail.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Each key's value is a single DAG-CBOR block (DeserializedMarkdownEntry)
|
|
5
|
+
* containing:
|
|
6
6
|
* - The current RGA tree (full document state)
|
|
7
7
|
* - An RGA of MarkdownEvents (causal history scoped to this key)
|
|
8
8
|
* - The last changeset applied (for incremental replay during merge)
|
|
9
9
|
*
|
|
10
10
|
* On read, if the Pail has multiple heads (concurrent writes), we resolve
|
|
11
11
|
* by walking from the common ancestor forward, replaying each branch's
|
|
12
|
-
* changesets and merging event RGAs
|
|
13
|
-
* concurrent root updates.
|
|
12
|
+
* changesets and merging event RGAs.
|
|
14
13
|
*/
|
|
15
14
|
import { MemoryBlockstore, withCache } from "@storacha/ucn/block";
|
|
16
15
|
import * as CRDT from "@web3-storage/pail/crdt";
|
|
17
16
|
import { CID } from "multiformats";
|
|
18
17
|
import * as cbor from "@ipld/dag-cbor";
|
|
19
|
-
import { fromMarkdown,
|
|
18
|
+
import { fromMarkdown, RGA, computeChangeSet, applyRGAChangeSet, toMarkdown, mergeRGATrees, serializeTree, deserializeTree, serializeRGA, deserializeRGA, serializeChangeSet, deserializeChangeSet as deserializeChangeSetStruct, stripUndefined, } from "@storacha/md-merge";
|
|
20
19
|
import * as Pail from "@web3-storage/pail";
|
|
21
20
|
import { decode, encode } from "multiformats/block";
|
|
22
21
|
import { sha256 } from "multiformats/hashes/sha2";
|
|
@@ -69,40 +68,78 @@ const nohierarchyComparator = (a, b) => a.toString() === b.toString() ? 0 : a.to
|
|
|
69
68
|
/**
|
|
70
69
|
* Build a comparator from the event RGA's weighted BFS ordering.
|
|
71
70
|
* Events earlier in the BFS (closer to the root of the causal tree)
|
|
72
|
-
* compare as "less than" later events.
|
|
73
|
-
* for all RGA tree operations — it determines how concurrent inserts are
|
|
74
|
-
* ordered in the document.
|
|
71
|
+
* compare as "less than" later events.
|
|
75
72
|
*/
|
|
76
73
|
const makeComparator = (events) => {
|
|
77
74
|
const ordered = events.toWeightedArray();
|
|
78
75
|
const index = new Map(ordered.map((e, i) => [e.toString(), i]));
|
|
79
76
|
return (a, b) => (index.get(a.toString()) ?? -1) - (index.get(b.toString()) ?? -1);
|
|
80
77
|
};
|
|
78
|
+
// ---- Single-block serialization ----
|
|
81
79
|
/**
|
|
82
|
-
*
|
|
80
|
+
* Encode a DeserializedMarkdownEntry as a single DAG-CBOR block.
|
|
81
|
+
* All data (tree, events, changeset) is inlined — no CID references.
|
|
82
|
+
*/
|
|
83
|
+
export const encodeMarkdownEntry = async (entry) => {
|
|
84
|
+
const flat = {
|
|
85
|
+
type: entry.type,
|
|
86
|
+
root: serializeTree(entry.root),
|
|
87
|
+
events: serializeRGA(entry.events, serializeMarkdownEvent),
|
|
88
|
+
};
|
|
89
|
+
if (entry.type === "update") {
|
|
90
|
+
flat.changeset = serializeChangeSet(entry.changeset);
|
|
91
|
+
}
|
|
92
|
+
return await encode({
|
|
93
|
+
value: stripUndefined(flat),
|
|
94
|
+
codec: cbor,
|
|
95
|
+
hasher: sha256,
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Decode a single DAG-CBOR block back to a DeserializedMarkdownEntry.
|
|
100
|
+
*/
|
|
101
|
+
export const decodeMarkdownEntry = async (block) => {
|
|
102
|
+
const decoded = await decode({
|
|
103
|
+
bytes: block.bytes,
|
|
104
|
+
codec: cbor,
|
|
105
|
+
hasher: sha256,
|
|
106
|
+
});
|
|
107
|
+
const flat = decoded.value;
|
|
108
|
+
const eventRGA = deserializeRGA(flat.events, parseMarkdownEvent, deserializeMarkdownEvent, nohierarchyComparator);
|
|
109
|
+
const comparator = makeComparator(eventRGA);
|
|
110
|
+
const root = deserializeTree(flat.root, parseMarkdownEvent, comparator);
|
|
111
|
+
if (flat.type === "initial") {
|
|
112
|
+
return { type: "initial", root, events: eventRGA };
|
|
113
|
+
}
|
|
114
|
+
const changeset = deserializeChangeSetStruct(flat.changeset, parseMarkdownEvent);
|
|
115
|
+
return { type: "update", root, events: eventRGA, changeset };
|
|
116
|
+
};
|
|
117
|
+
// ---- Core helpers ----
|
|
118
|
+
/**
|
|
119
|
+
* Create the first entry for a key — bootstraps the RGA tree and
|
|
83
120
|
* event RGA from raw markdown. Used when a key doesn't exist yet.
|
|
84
121
|
*/
|
|
85
|
-
const firstPut =
|
|
122
|
+
const firstPut = (newMarkdown, parents) => {
|
|
86
123
|
const markdownEvent = new MarkdownEvent(parents);
|
|
87
124
|
const eventRGA = new RGA(nohierarchyComparator);
|
|
88
125
|
eventRGA.insert(undefined, markdownEvent, markdownEvent);
|
|
89
|
-
const eventBlock = await encodeRGA(eventRGA, serializeMarkdownEvent);
|
|
90
126
|
// Only one event, so comparator is trivial (all nodes have the same event).
|
|
91
127
|
const rgaRoot = fromMarkdown(newMarkdown, markdownEvent, (a, b) => 0);
|
|
92
|
-
return
|
|
128
|
+
return {
|
|
93
129
|
type: "initial",
|
|
94
130
|
root: rgaRoot,
|
|
95
131
|
events: eventRGA,
|
|
96
|
-
}
|
|
132
|
+
};
|
|
97
133
|
};
|
|
98
134
|
// ---- Public API ----
|
|
99
135
|
/**
|
|
100
136
|
* First put into an empty Pail (v0 = no existing revision).
|
|
101
|
-
* Returns
|
|
102
|
-
*
|
|
137
|
+
* Returns a single block to store. Caller is responsible for
|
|
138
|
+
* creating the Pail revision via Revision.v0Put.
|
|
103
139
|
*/
|
|
104
140
|
export const v0Put = async (newMarkdown) => {
|
|
105
|
-
|
|
141
|
+
const entry = firstPut(newMarkdown, []);
|
|
142
|
+
return encodeMarkdownEntry(entry);
|
|
106
143
|
};
|
|
107
144
|
/**
|
|
108
145
|
* Put markdown content at a key in an existing Pail.
|
|
@@ -112,135 +149,36 @@ export const v0Put = async (newMarkdown) => {
|
|
|
112
149
|
* an RGA changeset against the resolved tree, applies it, and stores the
|
|
113
150
|
* updated entry.
|
|
114
151
|
*
|
|
115
|
-
* Returns
|
|
116
|
-
* responsible for creating the Pail revision via Revision.put.
|
|
152
|
+
* Returns a single block to store, or null if no changes detected.
|
|
153
|
+
* Caller is responsible for creating the Pail revision via Revision.put.
|
|
117
154
|
*/
|
|
118
155
|
export const put = async (blocks, current, key, newMarkdown) => {
|
|
119
156
|
const mdEntry = await resolveValue(blocks, current, key);
|
|
120
157
|
if (!mdEntry) {
|
|
121
158
|
// Key doesn't exist yet — bootstrap with firstPut.
|
|
122
|
-
|
|
159
|
+
const entry = firstPut(newMarkdown, current.revision.map((r) => r.event.cid));
|
|
160
|
+
return encodeMarkdownEntry(entry);
|
|
123
161
|
}
|
|
124
162
|
const { events: eventRGA, root: rgaRoot } = mdEntry;
|
|
125
163
|
// Create a new event anchored to the current Pail revision heads.
|
|
126
164
|
const mdEvent = new MarkdownEvent(current.revision.map((r) => r.event.cid));
|
|
127
|
-
// Insert after the last event in weighted order
|
|
128
|
-
// deeper than all existing events in the causal tree, correctly representing
|
|
129
|
-
// that it incorporates all known history.
|
|
165
|
+
// Insert after the last event in weighted order.
|
|
130
166
|
const orderedNodes = eventRGA.toWeightedNodes();
|
|
131
167
|
eventRGA.insert(orderedNodes[orderedNodes.length - 1].id, mdEvent, mdEvent);
|
|
132
168
|
// Diff the current tree against the new markdown and apply.
|
|
133
169
|
const changeset = computeChangeSet(rgaRoot, newMarkdown, mdEvent);
|
|
134
170
|
if (changeset.changes.length === 0) {
|
|
135
|
-
return null; // No changes to apply
|
|
171
|
+
return null; // No changes to apply.
|
|
136
172
|
}
|
|
137
173
|
const comparator = makeComparator(eventRGA);
|
|
138
174
|
const newRoot = applyRGAChangeSet(rgaRoot, changeset, comparator);
|
|
139
|
-
return
|
|
175
|
+
return encodeMarkdownEntry({
|
|
140
176
|
type: "update",
|
|
141
177
|
root: newRoot,
|
|
142
178
|
events: eventRGA,
|
|
143
179
|
changeset,
|
|
144
180
|
});
|
|
145
181
|
};
|
|
146
|
-
// ---- Block fetching helpers ----
|
|
147
|
-
/** Decode a MarkdownEntry (CID pointers) from a DAG-CBOR block. */
|
|
148
|
-
const getMarkdownEntry = async (blocks, mdEntryCid) => {
|
|
149
|
-
const mdEntryBlock = await blocks.get(mdEntryCid);
|
|
150
|
-
if (!mdEntryBlock) {
|
|
151
|
-
throw new Error(`Could not find markdown entry block for CID ${mdEntryCid}`);
|
|
152
|
-
}
|
|
153
|
-
return (await decode({ bytes: mdEntryBlock.bytes, codec: cbor, hasher: sha256 })).value;
|
|
154
|
-
};
|
|
155
|
-
/** Fetch and decode the event RGA from its block CID. */
|
|
156
|
-
const getEventRGAFromCID = async (blocks, eventsCid) => {
|
|
157
|
-
const eventBlock = await blocks.get(eventsCid);
|
|
158
|
-
if (!eventBlock) {
|
|
159
|
-
throw new Error(`Could not find event block for CID ${eventsCid}`);
|
|
160
|
-
}
|
|
161
|
-
const eventRGA = await decodeRGA(eventBlock, parseMarkdownEvent, deserializeMarkdownEvent, nohierarchyComparator);
|
|
162
|
-
return eventRGA;
|
|
163
|
-
};
|
|
164
|
-
/** Fetch and decode an RGAChangeSet from its block CID. */
|
|
165
|
-
const getRGAChangeSetFromCID = async (blocks, changesetCid) => {
|
|
166
|
-
const changesetBlock = await blocks.get(changesetCid);
|
|
167
|
-
if (!changesetBlock) {
|
|
168
|
-
throw new Error(`Could not find changeset block for CID ${changesetCid}`);
|
|
169
|
-
}
|
|
170
|
-
return await decodeChangeSet(changesetBlock, parseMarkdownEvent);
|
|
171
|
-
};
|
|
172
|
-
/** Fetch and decode an RGA tree from its block CID, using the event RGA for ordering. */
|
|
173
|
-
const getRGATreeFromRootCID = async (blocks, rootCid, eventRGA) => {
|
|
174
|
-
const comparator = makeComparator(eventRGA);
|
|
175
|
-
const rootBlock = await blocks.get(rootCid);
|
|
176
|
-
if (!rootBlock) {
|
|
177
|
-
throw new Error(`Could not find root block for CID ${rootCid}`);
|
|
178
|
-
}
|
|
179
|
-
return await decodeTree(rootBlock, parseMarkdownEvent, comparator);
|
|
180
|
-
};
|
|
181
|
-
/**
|
|
182
|
-
* Fully deserialize a MarkdownEntry from its CID — fetches and decodes
|
|
183
|
-
* the entry, event RGA, tree, and (if update) changeset.
|
|
184
|
-
*/
|
|
185
|
-
const deserializedMarkdownEntryCID = async (blocks, mdEntryCid) => {
|
|
186
|
-
const mdEntry = await getMarkdownEntry(blocks, mdEntryCid);
|
|
187
|
-
const eventRGA = await getEventRGAFromCID(blocks, mdEntry.events);
|
|
188
|
-
const rgaRoot = await getRGATreeFromRootCID(blocks, mdEntry.root, eventRGA);
|
|
189
|
-
if (mdEntry.type === "initial") {
|
|
190
|
-
return {
|
|
191
|
-
type: "initial",
|
|
192
|
-
root: rgaRoot,
|
|
193
|
-
events: eventRGA,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
const changeset = await getRGAChangeSetFromCID(blocks, mdEntry.changeset);
|
|
197
|
-
return {
|
|
198
|
-
type: "update",
|
|
199
|
-
root: rgaRoot,
|
|
200
|
-
events: eventRGA,
|
|
201
|
-
changeset,
|
|
202
|
-
};
|
|
203
|
-
};
|
|
204
|
-
/**
|
|
205
|
-
* Serialize a DeserializedMarkdownEntry to DAG-CBOR blocks.
|
|
206
|
-
* Returns the entry's CID and all blocks that need to be stored
|
|
207
|
-
* (event RGA, tree, changeset if update, and the entry itself).
|
|
208
|
-
*/
|
|
209
|
-
const serializeMarkdownEntry = async (entry) => {
|
|
210
|
-
let blocks = [];
|
|
211
|
-
const eventBlock = await encodeRGA(entry.events, serializeMarkdownEvent);
|
|
212
|
-
blocks.push(eventBlock);
|
|
213
|
-
const rootBlock = await encodeTree(entry.root);
|
|
214
|
-
blocks.push(rootBlock);
|
|
215
|
-
const changesetBlock = entry.type === "update"
|
|
216
|
-
? await encodeChangeSet(entry.changeset)
|
|
217
|
-
: undefined;
|
|
218
|
-
if (changesetBlock) {
|
|
219
|
-
blocks.push(changesetBlock);
|
|
220
|
-
}
|
|
221
|
-
const mdEntry = entry.type === "initial"
|
|
222
|
-
? {
|
|
223
|
-
type: "initial",
|
|
224
|
-
root: rootBlock.cid,
|
|
225
|
-
events: eventBlock.cid,
|
|
226
|
-
}
|
|
227
|
-
: {
|
|
228
|
-
type: "update",
|
|
229
|
-
root: rootBlock.cid,
|
|
230
|
-
events: eventBlock.cid,
|
|
231
|
-
changeset: changesetBlock?.cid,
|
|
232
|
-
};
|
|
233
|
-
const mdEntryBlock = await encode({
|
|
234
|
-
value: mdEntry,
|
|
235
|
-
codec: cbor,
|
|
236
|
-
hasher: sha256,
|
|
237
|
-
});
|
|
238
|
-
blocks.push(mdEntryBlock);
|
|
239
|
-
return {
|
|
240
|
-
mdEntryCid: mdEntryBlock.cid,
|
|
241
|
-
additions: blocks,
|
|
242
|
-
};
|
|
243
|
-
};
|
|
244
182
|
// ---- Resolution (multi-head merge) ----
|
|
245
183
|
/**
|
|
246
184
|
* Resolve the current markdown value for a key, merging concurrent heads.
|
|
@@ -249,16 +187,8 @@ const serializeMarkdownEntry = async (entry) => {
|
|
|
249
187
|
*
|
|
250
188
|
* If there are multiple heads, finds their common ancestor in the Pail's
|
|
251
189
|
* merkle clock, then replays all events from ancestor → heads in causal order.
|
|
252
|
-
* For each "put" event:
|
|
253
|
-
* - If "initial": bootstraps the entry (must be the first event for this key)
|
|
254
|
-
* - If "update": merges the event's causal history into the running event RGA,
|
|
255
|
-
* then applies the changeset to the running tree using the merged comparator
|
|
256
|
-
* For "del" events: clears the entry (file deleted).
|
|
257
|
-
*
|
|
258
|
-
* This is analogous to how Pail resolves concurrent root updates — walk from
|
|
259
|
-
* common ancestor, replay operations in deterministic order.
|
|
260
190
|
*/
|
|
261
|
-
const resolveValue = async (blocks, current, key) => {
|
|
191
|
+
const resolveValue = async (blocks, current, key, decrypt) => {
|
|
262
192
|
const mdEntryBlockCid = await Pail.get(blocks, current.root, key);
|
|
263
193
|
if (!mdEntryBlockCid) {
|
|
264
194
|
return undefined;
|
|
@@ -266,9 +196,18 @@ const resolveValue = async (blocks, current, key) => {
|
|
|
266
196
|
// Cache event blocks in memory so EventFetcher can find them.
|
|
267
197
|
blocks = withCache(blocks, new MemoryBlockstore(current.revision.map((r) => r.event)));
|
|
268
198
|
const events = new EventFetcher(blocks);
|
|
199
|
+
// Fetch entry bytes: decrypt callback for private spaces, or raw block fetch.
|
|
200
|
+
const getEntryBytes = async (cid) => {
|
|
201
|
+
if (decrypt)
|
|
202
|
+
return decrypt(cid);
|
|
203
|
+
const block = await blocks.get(cid);
|
|
204
|
+
if (!block)
|
|
205
|
+
throw new Error(`Could not find block for CID ${cid}`);
|
|
206
|
+
return block.bytes;
|
|
207
|
+
};
|
|
269
208
|
// Fast path: single head, no merge needed.
|
|
270
209
|
if (current.revision.length === 1) {
|
|
271
|
-
return await
|
|
210
|
+
return decodeMarkdownEntry({ bytes: await getEntryBytes(mdEntryBlockCid) });
|
|
272
211
|
}
|
|
273
212
|
// Multi-head: find common ancestor and replay events in causal order.
|
|
274
213
|
const ancestor = await CRDT.findCommonAncestor(events, current.revision.map((r) => r.event.cid));
|
|
@@ -279,9 +218,10 @@ const resolveValue = async (blocks, current, key) => {
|
|
|
279
218
|
const aevent = await events.get(ancestor);
|
|
280
219
|
let { root } = aevent.value.data;
|
|
281
220
|
const rootMDEntryCid = await Pail.get(blocks, root, key);
|
|
282
|
-
let mdEntry
|
|
283
|
-
|
|
284
|
-
:
|
|
221
|
+
let mdEntry;
|
|
222
|
+
if (rootMDEntryCid) {
|
|
223
|
+
mdEntry = await decodeMarkdownEntry({ bytes: await getEntryBytes(rootMDEntryCid) });
|
|
224
|
+
}
|
|
285
225
|
// Get all events from ancestor → heads, sorted in deterministic causal order.
|
|
286
226
|
const sorted = await CRDT.findSortedEvents(events, current.revision.map((r) => r.event.cid), ancestor);
|
|
287
227
|
// Filter to only events that touch this key.
|
|
@@ -310,33 +250,24 @@ const resolveValue = async (blocks, current, key) => {
|
|
|
310
250
|
data = { ...data, ...op };
|
|
311
251
|
}
|
|
312
252
|
if (data.type === "put") {
|
|
313
|
-
// Fetch the MarkdownEntry that was stored with this event.
|
|
314
253
|
const mdEntryCid = await Pail.get(blocks, data.root, key);
|
|
315
254
|
if (!mdEntryCid) {
|
|
316
255
|
throw new Error(`Could not find markdown entry for CID ${data.root} and key ${key}`);
|
|
317
256
|
}
|
|
318
|
-
const newMDEntry = await
|
|
257
|
+
const newMDEntry = await decodeMarkdownEntry({ bytes: await getEntryBytes(mdEntryCid) });
|
|
319
258
|
if (newMDEntry.type === "initial") {
|
|
320
|
-
// First write for this key — bootstrap from the stored entry.
|
|
321
|
-
const newEventRGA = await getEventRGAFromCID(blocks, newMDEntry.events);
|
|
322
|
-
const newRoot = await getRGATreeFromRootCID(blocks, newMDEntry.root, newEventRGA);
|
|
323
259
|
if (mdEntry) {
|
|
324
|
-
// Concurrent initial —
|
|
325
|
-
|
|
326
|
-
mdEntry.events.merge(newEventRGA);
|
|
260
|
+
// Concurrent initial — merge event histories and RGA trees.
|
|
261
|
+
mdEntry.events.merge(newMDEntry.events);
|
|
327
262
|
const comparator = makeComparator(mdEntry.events);
|
|
328
263
|
mdEntry = {
|
|
329
264
|
type: "initial",
|
|
330
265
|
events: mdEntry.events,
|
|
331
|
-
root: mergeRGATrees(mdEntry.root,
|
|
266
|
+
root: mergeRGATrees(mdEntry.root, newMDEntry.root, comparator),
|
|
332
267
|
};
|
|
333
268
|
}
|
|
334
269
|
else {
|
|
335
|
-
mdEntry =
|
|
336
|
-
type: "initial",
|
|
337
|
-
events: newEventRGA,
|
|
338
|
-
root: newRoot,
|
|
339
|
-
};
|
|
270
|
+
mdEntry = newMDEntry;
|
|
340
271
|
}
|
|
341
272
|
}
|
|
342
273
|
else {
|
|
@@ -344,23 +275,17 @@ const resolveValue = async (blocks, current, key) => {
|
|
|
344
275
|
if (!mdEntry) {
|
|
345
276
|
throw new Error(`Expected existing markdown entry for update event, found none for CID ${mdEntryCid}`);
|
|
346
277
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
const eventRGA = mdEntry.events;
|
|
350
|
-
eventRGA.merge(await getEventRGAFromCID(blocks, newMDEntry.events));
|
|
351
|
-
const changeset = await getRGAChangeSetFromCID(blocks, newMDEntry.changeset);
|
|
352
|
-
// Rebuild comparator from merged event history, then apply changeset.
|
|
353
|
-
const comparator = makeComparator(eventRGA);
|
|
278
|
+
mdEntry.events.merge(newMDEntry.events);
|
|
279
|
+
const comparator = makeComparator(mdEntry.events);
|
|
354
280
|
mdEntry = {
|
|
355
281
|
type: "update",
|
|
356
|
-
events:
|
|
357
|
-
root: applyRGAChangeSet(mdEntry.root, changeset, comparator),
|
|
358
|
-
changeset,
|
|
282
|
+
events: mdEntry.events,
|
|
283
|
+
root: applyRGAChangeSet(mdEntry.root, newMDEntry.changeset, comparator),
|
|
284
|
+
changeset: newMDEntry.changeset,
|
|
359
285
|
};
|
|
360
286
|
}
|
|
361
287
|
}
|
|
362
288
|
else if (data.type === "del") {
|
|
363
|
-
// Key deleted — clear state. If re-created later, it'll be a new "initial".
|
|
364
289
|
mdEntry = undefined;
|
|
365
290
|
}
|
|
366
291
|
}
|
|
@@ -370,8 +295,8 @@ const resolveValue = async (blocks, current, key) => {
|
|
|
370
295
|
* Get the current markdown string for a key, resolving concurrent heads.
|
|
371
296
|
* Returns undefined if the key doesn't exist.
|
|
372
297
|
*/
|
|
373
|
-
export const get = async (blocks, current, key) => {
|
|
374
|
-
const mdEntry = await resolveValue(blocks, current, key);
|
|
298
|
+
export const get = async (blocks, current, key, decrypt) => {
|
|
299
|
+
const mdEntry = await resolveValue(blocks, current, key, decrypt);
|
|
375
300
|
if (!mdEntry) {
|
|
376
301
|
return undefined;
|
|
377
302
|
}
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AA0B7B,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QAqkBpD"}
|