rapier-html 1.2.33 → 1.2.42
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/BUILD.json +21 -21
- package/README.md +22 -13
- package/dist/ledger/data.mjs +57 -4
- package/dist/ledger/document-settings.mjs +1 -0
- package/dist/ledger/format.mjs +114 -47
- package/dist/ledger/hash.mjs +43 -2
- package/dist/ledger/history.mjs +6 -0
- package/dist/ledger/inverse-source.mjs +15 -2
- package/dist/ledger/journal-records.mjs +32 -9
- package/dist/ledger/md-assets.mjs +709 -0
- package/dist/ledger/will.mjs +239 -0
- package/dist/ledger/word-sidecar.mjs +5 -0
- package/dist/page.d.mts +2 -0
- package/dist/rapier.html +85 -84
- package/dist/wrap.mjs +11 -4
- package/package.json +1 -1
|
@@ -10,7 +10,7 @@ const historyBoundary = (source, at) => Number.isSafeInteger(at) && at >= 0 && !
|
|
|
10
10
|
!(at > 0 && at < source.length && (source.charCodeAt(at - 1) & 0xFC00) === 0xD800 &&
|
|
11
11
|
(source.charCodeAt(at) & 0xFC00) === 0xDC00);
|
|
12
12
|
|
|
13
|
-
function minimalHistorySplice(before, after, pos = 0) {
|
|
13
|
+
export function minimalHistorySplice(before, after, pos = 0) {
|
|
14
14
|
let first = 0, a = before.length, b = after.length;
|
|
15
15
|
while (first < a && first < b && before[first] === after[first]) first++;
|
|
16
16
|
if (!historyBoundary(before, first) || !historyBoundary(after, first)) first--;
|
|
@@ -32,6 +32,8 @@ function historyHunks(row) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
const differentActors = (a, b) => !!a && !!b && (a.kind !== b.kind || a.id !== b.id);
|
|
36
|
+
|
|
35
37
|
export function projectInverseSource(prepared, selected, projectedEffects, options = {}) {
|
|
36
38
|
const records = prepared.records || prepared.rows.map(({record, splices}) => record.splices === splices ? record : {...record, splices});
|
|
37
39
|
if (!options.origins && !records.some(record => !prepared.effects.references.get(record.transaction.id)?.length &&
|
|
@@ -40,6 +42,7 @@ export function projectInverseSource(prepared, selected, projectedEffects, optio
|
|
|
40
42
|
try {
|
|
41
43
|
let pieces = prepared.initialSource ? [{text: prepared.initialSource, owner: null, lineage: []}] : [];
|
|
42
44
|
const all = [], byId = new Map(), byAct = new Map(), processed = [], keptInverseAncestors = new Set();
|
|
45
|
+
const actorOf = new Map(records.map(record => [record.transaction.id, record.transaction.actor]));
|
|
43
46
|
const recordsForCover = prepared.records || prepared.rows.map(({record, splices}) => record.splices === splices ? record : {...record, splices});
|
|
44
47
|
const coverGroups = new Map();
|
|
45
48
|
let coverOrigins = null;
|
|
@@ -262,7 +265,11 @@ export function projectInverseSource(prepared, selected, projectedEffects, optio
|
|
|
262
265
|
const start = boundary(row.pos), end = boundary(row.pos + row.removed.length);
|
|
263
266
|
let at = start.last, count = Math.max(0, end.first - at);
|
|
264
267
|
if (!row.removed.length) {
|
|
265
|
-
const
|
|
268
|
+
const run = pieces.slice(start.first, start.last), next = pieces[start.last];
|
|
269
|
+
let before = start.first - 1; while (before >= 0 && !pieces[before].text) before--;
|
|
270
|
+
const leftAct = before >= 0 ? byId.get(pieces[before].owner)?.actId : undefined;
|
|
271
|
+
const sameAct = leftAct !== undefined && run.some(item => item.mark?.actId === leftAct);
|
|
272
|
+
const marker = run.findIndex(item => item.mark?.inserted.length && (next && owns(next, item.mark) || !sameAct));
|
|
266
273
|
at = marker < 0 ? start.last : start.first + marker; count = 0;
|
|
267
274
|
}
|
|
268
275
|
const removed = pieces.slice(at, at + count);
|
|
@@ -276,6 +283,12 @@ export function projectInverseSource(prepared, selected, projectedEffects, optio
|
|
|
276
283
|
const id = tx.id + '#' + rowIndex + ':' + index;
|
|
277
284
|
const lineage = new Set([id]);
|
|
278
285
|
for (const piece of removed) for (const parent of piece.lineage || piece.mark?.lineage || []) lineage.add(parent);
|
|
286
|
+
if (!row.removed.length && !count && at > 0 && /[\p{L}\p{N}\p{M}]/u.test(row.inserted)) {
|
|
287
|
+
const left = pieces[at - 1], right = pieces[at];
|
|
288
|
+
const inner = left?.text && right?.text && left.owner === right.owner ? byId.get(left.owner) : null;
|
|
289
|
+
if (inner && inner.actId !== tx.id && inner.removed && differentActors(actorOf.get(inner.actId), tx.actor) && /[\p{L}\p{N}\p{M}]$/u.test(left.text) && /^[\p{L}\p{N}\p{M}]/u.test(right.text))
|
|
290
|
+
for (const parent of [inner.id, ...(left.lineage || [])]) lineage.add(parent);
|
|
291
|
+
}
|
|
279
292
|
const hunk = {id, actId: tx.id, removed: row.removed, inserted: row.inserted, before: removed, derived,
|
|
280
293
|
chosen, kept: selected.has(tx.id) && !chosen, lineage: [...lineage], supersededBy: new Set(), active: true,
|
|
281
294
|
...(coverIdsFor(tx.id) ? {coverIds: coverIdsFor(tx.id)} : {})};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
import {fields, scalar, plainPrototype} from './data.mjs';
|
|
3
3
|
import {transformText} from './source.mjs';
|
|
4
|
+
import {dataImage} from './md-assets.mjs';
|
|
4
5
|
|
|
5
6
|
const _RAPIER_TRANSACTION_ACTOR_LIMIT = 160;
|
|
6
7
|
const _RAPIER_TRANSACTION_OPERATION_LIMIT = 96;
|
|
@@ -75,7 +76,7 @@ function _rapierValidAuthored(origin) {
|
|
|
75
76
|
!/[\uD800-\uDFFF]/u.test(row.removed) && !/[\uD800-\uDFFF]/u.test(row.inserted));
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
function _rapierRecordIndex(records) {
|
|
79
|
+
function _rapierRecordIndex(records, shared = false) {
|
|
79
80
|
const byId = new Map(), splices = new Map(), metadata = new Map();
|
|
80
81
|
for (const record of records) {
|
|
81
82
|
const id = record?.transaction?.id;
|
|
@@ -99,9 +100,12 @@ function _rapierRecordIndex(records) {
|
|
|
99
100
|
}
|
|
100
101
|
cache.set(current, value);
|
|
101
102
|
for (let i = path.length - 1; i >= 0; i--) {
|
|
102
|
-
if (path[i].transaction.reverts && value != null)
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
if (path[i].transaction.reverts && value != null) {
|
|
104
|
+
value = effects
|
|
105
|
+
? Object.fromEntries(Object.entries(value).map(([key, pair]) => [key, {before: pair.after, after: pair.before}]))
|
|
106
|
+
: value.slice().reverse().map(row => ({pos: row.pos, removed: row.inserted, inserted: row.removed}));
|
|
107
|
+
if (shared) { for (const row of Object.values(value)) Object.freeze(row); Object.freeze(value); }
|
|
108
|
+
}
|
|
105
109
|
cache.set(path[i], value);
|
|
106
110
|
}
|
|
107
111
|
return value;
|
|
@@ -109,10 +113,27 @@ function _rapierRecordIndex(records) {
|
|
|
109
113
|
return {byId, splices: record => resolve(record, false), metadata: record => resolve(record, true)};
|
|
110
114
|
}
|
|
111
115
|
|
|
116
|
+
const _rapierLedgerIndexes = new WeakMap();
|
|
117
|
+
function _rapierLedgerIndex(ledger) {
|
|
118
|
+
const records = ledger || [];
|
|
119
|
+
if (!Array.isArray(records)) return _rapierRecordIndex(records);
|
|
120
|
+
const held = _rapierLedgerIndexes.get(records);
|
|
121
|
+
if (held && held.records.length === records.length && held.records.at(-1) === records.at(-1) &&
|
|
122
|
+
(held.checked || held.records.every((record, at) => record === records[at]))) {
|
|
123
|
+
if (!held.checked) { held.checked = true; queueMicrotask(() => { held.checked = false; }); }
|
|
124
|
+
return held.index;
|
|
125
|
+
}
|
|
126
|
+
if (!records.every(record => record && typeof record === 'object' && Object.isFrozen(record) && Object.isFrozen(record.transaction ?? {})))
|
|
127
|
+
return _rapierRecordIndex(records);
|
|
128
|
+
const index = _rapierRecordIndex(records, true);
|
|
129
|
+
_rapierLedgerIndexes.set(records, {records: records.slice(), index});
|
|
130
|
+
return index;
|
|
131
|
+
}
|
|
132
|
+
|
|
112
133
|
function _rapierRecordSplices(entry, ledger) {
|
|
113
134
|
try {
|
|
114
135
|
if (entry && Array.isArray(entry.splices)) return entry.splices;
|
|
115
|
-
return
|
|
136
|
+
return _rapierLedgerIndex(ledger).splices(entry);
|
|
116
137
|
} catch (_) { return null; }
|
|
117
138
|
}
|
|
118
139
|
|
|
@@ -162,7 +183,7 @@ function _rapierRecordMetadata(entry, ledger) {
|
|
|
162
183
|
try {
|
|
163
184
|
if (Object.hasOwn(entry, 'metadata')) return _rapierValidMetadataEffect(entry.metadata) ? entry.metadata : undefined;
|
|
164
185
|
if (Array.isArray(entry.splices)) return null;
|
|
165
|
-
return
|
|
186
|
+
return _rapierLedgerIndex(ledger).metadata(entry);
|
|
166
187
|
} catch (_) { return undefined; }
|
|
167
188
|
}
|
|
168
189
|
|
|
@@ -175,10 +196,10 @@ function _rapierPictureFinish(record, original, earlier, lookup) {
|
|
|
175
196
|
if (!reference || !/^\]\[[a-z0-9-]+\]$/i.test(reference.inserted) || reference.removed === reference.inserted) return false;
|
|
176
197
|
const definition = rows.find(row => row !== reference), oldLabel = reference.removed.slice(2, -1), newLabel = reference.inserted.slice(2, -1);
|
|
177
198
|
const body = (text, label) => {
|
|
178
|
-
const prefix = '[' + label + ']:
|
|
199
|
+
const prefix = '[' + label + ']: ';
|
|
179
200
|
if (typeof text !== 'string' || !text.startsWith(prefix)) return null;
|
|
180
201
|
const value = text.slice(prefix.length), end = value.indexOf(' '), bytes = end < 0 ? value : value.slice(0, end), title = end < 0 ? '' : value.slice(end);
|
|
181
|
-
return
|
|
202
|
+
return dataImage(bytes)?.codec === 'image/svg+xml' && !/[\r\n]/.test(title) ? title : null;
|
|
182
203
|
};
|
|
183
204
|
const title = body(definition.removed, oldLabel);
|
|
184
205
|
if (title === null || body(definition.inserted, newLabel) !== title) return false;
|
|
@@ -292,6 +313,7 @@ function _rapierWalkHistoryEffects(records, lookup, visit = null, observe = null
|
|
|
292
313
|
}
|
|
293
314
|
}
|
|
294
315
|
if (refs.some(id => typeof id !== 'string' || !nodes.has(id) || pictures.has(id))) return {ok: false};
|
|
316
|
+
if (tx.actor?.kind === 'agent' && refs.some(id => byId.get(id).transaction.actor?.kind !== 'agent')) return {ok: false};
|
|
295
317
|
nodes.set(tx.id, {active: true, blockers: 0, references: refs, dependents: []}); references.set(tx.id, refs.slice());
|
|
296
318
|
byId.set(tx.id, record); earlier.push(record);
|
|
297
319
|
for (const ref of refs) {
|
|
@@ -505,9 +527,10 @@ const _rapierPrepareHistoryRecords = (() => {
|
|
|
505
527
|
|
|
506
528
|
const _rapierJournalRecord = (() => {
|
|
507
529
|
const copies = new WeakMap();
|
|
530
|
+
const fixed = value => { if (value && typeof value === 'object') { for (const key of Object.keys(value)) fixed(value[key]); Object.freeze(value); } return value; };
|
|
508
531
|
return record => {
|
|
509
532
|
let copy = copies.get(record);
|
|
510
|
-
if (!copy) { copy = JSON.parse(JSON.stringify(record)); copies.set(record, copy); }
|
|
533
|
+
if (!copy) { copy = fixed(JSON.parse(JSON.stringify(record))); copies.set(record, copy); }
|
|
511
534
|
return copy;
|
|
512
535
|
};
|
|
513
536
|
})();
|