rapier-markdown-kit 1.1.91 → 1.1.92
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.
|
@@ -177,6 +177,57 @@ export function historyProjection(input, {from = 0, to = input?.source?.length,
|
|
|
177
177
|
earliestRevision: prepared.earliestRevision, complete: prepared.complete, acts, groups: groupHistoryActs(acts), ...(before ? {before} : {})};
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
// Project all reading places in one replay. Typing only invalidates this transient view.
|
|
181
|
+
export function historyPlaces(input, blocks) {
|
|
182
|
+
const prepared = prepareHistory(input);
|
|
183
|
+
if (!prepared.ok) return prepared;
|
|
184
|
+
if (!Array.isArray(blocks) || blocks.some(block => !block ||
|
|
185
|
+
!historyBoundary(prepared.source, block.from) || !historyBoundary(prepared.source, block.to) || block.to < block.from))
|
|
186
|
+
return historyFailure('range_invalid');
|
|
187
|
+
const projected = blocks.map(block => ({id: block.id, from: block.from, to: block.to,
|
|
188
|
+
source: prepared.source.slice(block.from, block.to), range: {from: block.from, to: block.to}, acts: []}));
|
|
189
|
+
let text = prepared.source;
|
|
190
|
+
for (let index = prepared.rows.length - 1; index >= 0; index--) {
|
|
191
|
+
const {record, splices} = prepared.rows[index], before = historyPreviousSource(text, splices);
|
|
192
|
+
if (before === null) return historyFailure('history_invalid');
|
|
193
|
+
for (const block of projected) {
|
|
194
|
+
const after = {...block.range, source: text.slice(block.range.from, block.range.to)};
|
|
195
|
+
let touched = false;
|
|
196
|
+
for (let at = splices.length - 1; at >= 0; at--) {
|
|
197
|
+
const mapped = historyRangeBefore(block.range, splices[at]);
|
|
198
|
+
block.range = {from: mapped.from, to: mapped.to}; touched ||= mapped.touched;
|
|
199
|
+
}
|
|
200
|
+
const previous = {...block.range, source: before.slice(block.range.from, block.range.to)};
|
|
201
|
+
if (touched && previous.source !== after.source) block.acts.push({...historyAct(record), before: previous, after});
|
|
202
|
+
}
|
|
203
|
+
text = before;
|
|
204
|
+
}
|
|
205
|
+
const acts = prepared.rows.map(({record}) => historyAct(record));
|
|
206
|
+
const present = new Map(), effects = new Map();
|
|
207
|
+
for (const act of acts) {
|
|
208
|
+
const changes = [];
|
|
209
|
+
const set = (id, value) => {
|
|
210
|
+
const prior = present.get(id) === true;
|
|
211
|
+
present.set(id, value); changes.push({id, before: prior, after: value});
|
|
212
|
+
};
|
|
213
|
+
if (act.reapplies) {
|
|
214
|
+
for (const change of effects.get(act.reapplies) || [{id: act.reapplies, after: true}]) set(change.id, change.after);
|
|
215
|
+
} else {
|
|
216
|
+
const ids = act.sourceTransactionIds || (act.sourceTransactionId ? [act.sourceTransactionId] : act.reverts ? [act.reverts] : []);
|
|
217
|
+
for (const id of ids) {
|
|
218
|
+
for (const change of (effects.get(id) || [{id, before: false, after: true}]).slice().reverse()) {
|
|
219
|
+
if (present.get(change.id) === change.after) set(change.id, change.before);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
set(act.id, true); effects.set(act.id, changes);
|
|
224
|
+
}
|
|
225
|
+
for (const block of projected) { block.acts.reverse(); delete block.range; }
|
|
226
|
+
return {ok: true, source: prepared.source, initialSource: prepared.initialSource, revision: prepared.revision,
|
|
227
|
+
earliestRevision: prepared.earliestRevision, complete: prepared.complete, acts, blocks: projected,
|
|
228
|
+
reversed: acts.filter(act => present.get(act.id) !== true).map(act => act.id)};
|
|
229
|
+
}
|
|
230
|
+
|
|
180
231
|
function minimalHistorySplice(before, after, pos = 0) {
|
|
181
232
|
let first = 0, a = before.length, b = after.length;
|
|
182
233
|
while (first < a && first < b && before[first] === after[first]) first++;
|
|
@@ -7,8 +7,8 @@ import {merge, transportInterval, transportTouchedInterval} from './ledger/merge
|
|
|
7
7
|
export {merge, transportInterval, transportTouchedInterval};
|
|
8
8
|
import {_rapierTransformSplices, _rapierRecordSplices, _rapierValidLedgerRecord, _rapierRecordMetadata, _rapierValidMetadata, _rapierValidMetadataEffect, _rapierTransformMetadata, _rapierMetadataDelta, _rapierHistoryEffects, _rapierMetadataState, _rapierReplayMetadata, _rapierHasHistoryEffect} from './ledger/journal-records.mjs';
|
|
9
9
|
export {_rapierTransformSplices, _rapierRecordSplices, _rapierValidLedgerRecord, _rapierRecordMetadata, _rapierValidMetadata, _rapierValidMetadataEffect, _rapierTransformMetadata, _rapierMetadataDelta, _rapierHistoryEffects, _rapierMetadataState, _rapierReplayMetadata, _rapierHasHistoryEffect};
|
|
10
|
-
import {replayHistory, sourceBefore, historyProjection, selectiveUndo, groupHistoryActs} from './ledger/history.mjs';
|
|
11
|
-
export {replayHistory, sourceBefore, historyProjection, selectiveUndo, groupHistoryActs};
|
|
10
|
+
import {replayHistory, sourceBefore, historyProjection, historyPlaces, selectiveUndo, groupHistoryActs} from './ledger/history.mjs';
|
|
11
|
+
export {replayHistory, sourceBefore, historyProjection, historyPlaces, selectiveUndo, groupHistoryActs};
|
|
12
12
|
|
|
13
13
|
import {transposeSource} from './ledger/transport.mjs';
|
|
14
14
|
export {transposeSource};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rapier-markdown-kit",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.92",
|
|
4
4
|
"description": "Read, render and write Self-contained Markdown: one .md file that carries its pictures, drawings and layout, and that any Markdown app can read. HTML renderer, stylesheet, text layout, Will/1 agent permissions, and an edit history with authorship and offline merge. MIT, no dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"markdown",
|