@dxos/versioning 0.10.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/lib/browser/index.mjs +417 -0
- package/dist/lib/browser/index.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -0
- package/dist/lib/node-esm/index.mjs +418 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/types/src/Branch.d.ts +3 -0
- package/dist/types/src/Branch.d.ts.map +1 -0
- package/dist/types/src/History.d.ts +3 -0
- package/dist/types/src/History.d.ts.map +1 -0
- package/dist/types/src/Version.d.ts +3 -0
- package/dist/types/src/Version.d.ts.map +1 -0
- package/dist/types/src/diff.d.ts +35 -0
- package/dist/types/src/diff.d.ts.map +1 -0
- package/dist/types/src/diff.test.d.ts +2 -0
- package/dist/types/src/diff.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +5 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/internal/index.d.ts +3 -0
- package/dist/types/src/internal/index.d.ts.map +1 -0
- package/dist/types/src/internal/model.d.ts +53 -0
- package/dist/types/src/internal/model.d.ts.map +1 -0
- package/dist/types/src/internal/types.d.ts +69 -0
- package/dist/types/src/internal/types.d.ts.map +1 -0
- package/dist/types/src/model.test.d.ts +2 -0
- package/dist/types/src/model.test.d.ts.map +1 -0
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +43 -0
- package/src/Branch.ts +21 -0
- package/src/History.ts +8 -0
- package/src/Version.ts +14 -0
- package/src/diff.test.ts +195 -0
- package/src/diff.ts +225 -0
- package/src/index.ts +8 -0
- package/src/internal/index.ts +6 -0
- package/src/internal/model.ts +189 -0
- package/src/internal/types.ts +76 -0
- package/src/model.test.ts +182 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/Branch.ts
|
|
8
|
+
var Branch_exports = {};
|
|
9
|
+
__export(Branch_exports, {
|
|
10
|
+
Branch: () => Branch,
|
|
11
|
+
Status: () => BranchStatus,
|
|
12
|
+
create: () => createBranch,
|
|
13
|
+
discard: () => discardBranch,
|
|
14
|
+
find: () => findBranch,
|
|
15
|
+
label: () => branchLabel,
|
|
16
|
+
make: () => makeBranch,
|
|
17
|
+
merge: () => mergeBranch
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// src/internal/types.ts
|
|
21
|
+
import * as Schema from "effect/Schema";
|
|
22
|
+
import { Key, Ref } from "@dxos/echo";
|
|
23
|
+
import { Text } from "@dxos/schema";
|
|
24
|
+
var Version = Schema.mutable(Schema.Struct({
|
|
25
|
+
id: Schema.String,
|
|
26
|
+
name: Schema.String,
|
|
27
|
+
target: Ref.Ref(Text.Text),
|
|
28
|
+
heads: Schema.mutable(Schema.Array(Schema.String)),
|
|
29
|
+
createdAt: Schema.String,
|
|
30
|
+
creator: Schema.optional(Schema.String),
|
|
31
|
+
message: Schema.optional(Schema.String)
|
|
32
|
+
}));
|
|
33
|
+
var BranchStatus = Schema.Literal("active", "merged", "archived");
|
|
34
|
+
var Branch = Schema.mutable(Schema.Struct({
|
|
35
|
+
id: Schema.String,
|
|
36
|
+
name: Schema.String,
|
|
37
|
+
content: Ref.Ref(Text.Text),
|
|
38
|
+
parent: Ref.Ref(Text.Text),
|
|
39
|
+
anchor: Schema.mutable(Schema.Array(Schema.String)),
|
|
40
|
+
status: BranchStatus,
|
|
41
|
+
createdAt: Schema.String,
|
|
42
|
+
creator: Schema.optional(Schema.String),
|
|
43
|
+
mergedAt: Schema.optional(Schema.String)
|
|
44
|
+
}));
|
|
45
|
+
var History = Schema.mutable(Schema.Struct({
|
|
46
|
+
branches: Schema.mutable(Schema.Array(Branch)),
|
|
47
|
+
versions: Schema.mutable(Schema.Array(Version))
|
|
48
|
+
}));
|
|
49
|
+
var makeVersion = (props) => ({
|
|
50
|
+
id: Key.EntityId.random(),
|
|
51
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
52
|
+
...props
|
|
53
|
+
});
|
|
54
|
+
var makeBranch = (props) => ({
|
|
55
|
+
id: Key.EntityId.random(),
|
|
56
|
+
status: "active",
|
|
57
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
58
|
+
...props
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// src/internal/model.ts
|
|
62
|
+
import { Text as EchoText, Obj, Ref as Ref2 } from "@dxos/echo";
|
|
63
|
+
import { checkoutVersion } from "@dxos/echo-client";
|
|
64
|
+
import { invariant } from "@dxos/invariant";
|
|
65
|
+
import { Text as Text2 } from "@dxos/schema";
|
|
66
|
+
|
|
67
|
+
// src/diff.ts
|
|
68
|
+
import { diffLines, diffWordsWithSpace } from "diff";
|
|
69
|
+
var diffSpans = (before, after) => {
|
|
70
|
+
const spans = [];
|
|
71
|
+
let offset = 0;
|
|
72
|
+
for (const change of diffWordsWithSpace(before, after)) {
|
|
73
|
+
const kind = change.added ? "insert" : change.removed ? "delete" : "equal";
|
|
74
|
+
const length = kind === "delete" ? 0 : change.value.length;
|
|
75
|
+
spans.push({
|
|
76
|
+
kind,
|
|
77
|
+
from: offset,
|
|
78
|
+
to: offset + length,
|
|
79
|
+
text: change.value
|
|
80
|
+
});
|
|
81
|
+
offset += length;
|
|
82
|
+
}
|
|
83
|
+
return spans;
|
|
84
|
+
};
|
|
85
|
+
var diffStats = (spans) => spans.reduce((stats, span) => {
|
|
86
|
+
if (span.kind === "insert") {
|
|
87
|
+
stats.insertions += span.text.length;
|
|
88
|
+
} else if (span.kind === "delete") {
|
|
89
|
+
stats.deletions += span.text.length;
|
|
90
|
+
}
|
|
91
|
+
return stats;
|
|
92
|
+
}, {
|
|
93
|
+
insertions: 0,
|
|
94
|
+
deletions: 0
|
|
95
|
+
});
|
|
96
|
+
var merge3 = ({ base, ours, theirs }) => {
|
|
97
|
+
if (ours === base) {
|
|
98
|
+
return {
|
|
99
|
+
text: theirs,
|
|
100
|
+
conflicts: 0
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (theirs === base || ours === theirs) {
|
|
104
|
+
return {
|
|
105
|
+
text: ours,
|
|
106
|
+
conflicts: 0
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const baseLines = splitLines(base);
|
|
110
|
+
const oursHunks = lineHunks(baseLines, splitLines(ours));
|
|
111
|
+
const theirsHunks = lineHunks(baseLines, splitLines(theirs));
|
|
112
|
+
const out = [];
|
|
113
|
+
let conflicts = 0;
|
|
114
|
+
let baseIndex = 0;
|
|
115
|
+
let oursCursor = 0;
|
|
116
|
+
let theirsCursor = 0;
|
|
117
|
+
while (baseIndex < baseLines.length || oursCursor < oursHunks.length || theirsCursor < theirsHunks.length) {
|
|
118
|
+
const oursHunk = oursHunks[oursCursor];
|
|
119
|
+
const theirsHunk = theirsHunks[theirsCursor];
|
|
120
|
+
const nextOurs = oursHunk?.baseStart ?? Infinity;
|
|
121
|
+
const nextTheirs = theirsHunk?.baseStart ?? Infinity;
|
|
122
|
+
const next = Math.min(nextOurs, nextTheirs);
|
|
123
|
+
while (baseIndex < Math.min(next, baseLines.length)) {
|
|
124
|
+
out.push(baseLines[baseIndex]);
|
|
125
|
+
baseIndex += 1;
|
|
126
|
+
}
|
|
127
|
+
if (next === Infinity) {
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
const oursActive = oursHunk !== void 0 && oursHunk.baseStart === next;
|
|
131
|
+
const theirsActive = theirsHunk !== void 0 && theirsHunk.baseStart === next;
|
|
132
|
+
const identical = oursActive && theirsActive && sameLines(oursHunk.lines, theirsHunk.lines) && oursHunk.baseLength === theirsHunk.baseLength;
|
|
133
|
+
const overlap = !identical && oursHunk !== void 0 && theirsHunk !== void 0 && (nextOurs === nextTheirs || oursActive && nextTheirs < hunkEnd(oursHunk) || theirsActive && nextOurs < hunkEnd(theirsHunk));
|
|
134
|
+
if (overlap) {
|
|
135
|
+
const oursRegion = [
|
|
136
|
+
oursHunk
|
|
137
|
+
];
|
|
138
|
+
const theirsRegion = [
|
|
139
|
+
theirsHunk
|
|
140
|
+
];
|
|
141
|
+
oursCursor += 1;
|
|
142
|
+
theirsCursor += 1;
|
|
143
|
+
let unionEnd = Math.max(hunkEnd(oursHunk), hunkEnd(theirsHunk));
|
|
144
|
+
let expanded = true;
|
|
145
|
+
while (expanded) {
|
|
146
|
+
expanded = false;
|
|
147
|
+
while (oursCursor < oursHunks.length && oursHunks[oursCursor].baseStart < unionEnd) {
|
|
148
|
+
const hunk = oursHunks[oursCursor];
|
|
149
|
+
oursRegion.push(hunk);
|
|
150
|
+
unionEnd = Math.max(unionEnd, hunkEnd(hunk));
|
|
151
|
+
oursCursor += 1;
|
|
152
|
+
expanded = true;
|
|
153
|
+
}
|
|
154
|
+
while (theirsCursor < theirsHunks.length && theirsHunks[theirsCursor].baseStart < unionEnd) {
|
|
155
|
+
const hunk = theirsHunks[theirsCursor];
|
|
156
|
+
theirsRegion.push(hunk);
|
|
157
|
+
unionEnd = Math.max(unionEnd, hunkEnd(hunk));
|
|
158
|
+
theirsCursor += 1;
|
|
159
|
+
expanded = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
out.push("<<<<<<< branch", ...sideContent(baseLines, theirsRegion, next, unionEnd), "=======", ...sideContent(baseLines, oursRegion, next, unionEnd), ">>>>>>> current");
|
|
163
|
+
conflicts += 1;
|
|
164
|
+
baseIndex = unionEnd;
|
|
165
|
+
} else if (identical) {
|
|
166
|
+
out.push(...oursHunk.lines);
|
|
167
|
+
baseIndex = next + oursHunk.baseLength;
|
|
168
|
+
oursCursor += 1;
|
|
169
|
+
theirsCursor += 1;
|
|
170
|
+
} else if (oursActive) {
|
|
171
|
+
out.push(...oursHunk.lines);
|
|
172
|
+
baseIndex = next + oursHunk.baseLength;
|
|
173
|
+
oursCursor += 1;
|
|
174
|
+
} else if (theirsHunk !== void 0) {
|
|
175
|
+
out.push(...theirsHunk.lines);
|
|
176
|
+
baseIndex = next + theirsHunk.baseLength;
|
|
177
|
+
theirsCursor += 1;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
text: joinLines(out, [
|
|
182
|
+
base,
|
|
183
|
+
ours,
|
|
184
|
+
theirs
|
|
185
|
+
]),
|
|
186
|
+
conflicts
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
var hunkEnd = (hunk) => hunk.baseStart + hunk.baseLength;
|
|
190
|
+
var sideContent = (baseLines, hunks, unionStart, unionEnd) => {
|
|
191
|
+
const out = [];
|
|
192
|
+
let position = unionStart;
|
|
193
|
+
for (const hunk of hunks) {
|
|
194
|
+
out.push(...baseLines.slice(position, hunk.baseStart), ...hunk.lines);
|
|
195
|
+
position = Math.max(position, hunkEnd(hunk));
|
|
196
|
+
}
|
|
197
|
+
out.push(...baseLines.slice(position, unionEnd));
|
|
198
|
+
return out;
|
|
199
|
+
};
|
|
200
|
+
var lineHunks = (baseLines, sideLines) => {
|
|
201
|
+
const hunks = [];
|
|
202
|
+
let baseIndex = 0;
|
|
203
|
+
let pending;
|
|
204
|
+
for (const change of diffLines(joinForDiff(baseLines), joinForDiff(sideLines))) {
|
|
205
|
+
const lines = chunkLines(change.value);
|
|
206
|
+
if (change.added) {
|
|
207
|
+
pending = pending ?? {
|
|
208
|
+
baseStart: baseIndex,
|
|
209
|
+
baseLength: 0,
|
|
210
|
+
lines: []
|
|
211
|
+
};
|
|
212
|
+
pending.lines.push(...lines);
|
|
213
|
+
} else if (change.removed) {
|
|
214
|
+
pending = pending ?? {
|
|
215
|
+
baseStart: baseIndex,
|
|
216
|
+
baseLength: 0,
|
|
217
|
+
lines: []
|
|
218
|
+
};
|
|
219
|
+
pending.baseLength += lines.length;
|
|
220
|
+
baseIndex += lines.length;
|
|
221
|
+
} else {
|
|
222
|
+
if (pending) {
|
|
223
|
+
hunks.push(pending);
|
|
224
|
+
pending = void 0;
|
|
225
|
+
}
|
|
226
|
+
baseIndex += lines.length;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (pending) {
|
|
230
|
+
hunks.push(pending);
|
|
231
|
+
}
|
|
232
|
+
return hunks;
|
|
233
|
+
};
|
|
234
|
+
var sameLines = (a, b) => a.length === b.length && a.every((line, index) => line === b[index]);
|
|
235
|
+
var splitLines = (text) => text === "" ? [] : stripTrailingNewline(text).split("\n");
|
|
236
|
+
var chunkLines = (value) => stripTrailingNewline(value).split("\n");
|
|
237
|
+
var stripTrailingNewline = (text) => text.endsWith("\n") ? text.slice(0, -1) : text;
|
|
238
|
+
var joinForDiff = (lines) => lines.length === 0 ? "" : `${lines.join("\n")}
|
|
239
|
+
`;
|
|
240
|
+
var joinLines = (lines, inputs) => {
|
|
241
|
+
const text = lines.join("\n");
|
|
242
|
+
const nonEmpty = inputs.filter((input) => input.length > 0);
|
|
243
|
+
const trailing = nonEmpty.length > 0 && nonEmpty.every((input) => input.endsWith("\n"));
|
|
244
|
+
return trailing && text.length > 0 ? `${text}
|
|
245
|
+
` : text;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// src/internal/model.ts
|
|
249
|
+
var __dxlog_file = "/Users/burdon/Code/dxos/dxos/.claude/worktrees/worktree-guidance-6d5eb0/packages/sdk/versioning/src/internal/model.ts";
|
|
250
|
+
var ensureHistory = (doc) => {
|
|
251
|
+
if (!doc.history) {
|
|
252
|
+
Obj.update(doc, (doc2) => {
|
|
253
|
+
doc2.history = {
|
|
254
|
+
branches: [],
|
|
255
|
+
versions: []
|
|
256
|
+
};
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
const history = doc.history;
|
|
260
|
+
invariant(history, "history not initialized", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 20, S: void 0, A: ["history", "'history not initialized'"] });
|
|
261
|
+
return history;
|
|
262
|
+
};
|
|
263
|
+
var getHeads = (text) => {
|
|
264
|
+
const version = Obj.version(text);
|
|
265
|
+
invariant(version.versioned && version.automergeHeads, "text is not versioned (not persisted?)", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 25, S: void 0, A: ["version.versioned && version.automergeHeads", "'text is not versioned (not persisted?)'"] });
|
|
266
|
+
return [
|
|
267
|
+
...version.automergeHeads
|
|
268
|
+
];
|
|
269
|
+
};
|
|
270
|
+
var contentAt = (text, heads) => {
|
|
271
|
+
const snapshot = checkoutVersion(text, [
|
|
272
|
+
...heads
|
|
273
|
+
]);
|
|
274
|
+
if (snapshot && typeof snapshot === "object" && "content" in snapshot) {
|
|
275
|
+
const { content } = snapshot;
|
|
276
|
+
return typeof content === "string" ? content : "";
|
|
277
|
+
}
|
|
278
|
+
return "";
|
|
279
|
+
};
|
|
280
|
+
var createCheckpoint = (doc, props) => {
|
|
281
|
+
const text = props.target;
|
|
282
|
+
const version = makeVersion({
|
|
283
|
+
name: props.name,
|
|
284
|
+
target: Ref2.make(text),
|
|
285
|
+
heads: getHeads(text),
|
|
286
|
+
...props.message !== void 0 && {
|
|
287
|
+
message: props.message
|
|
288
|
+
},
|
|
289
|
+
...props.creator !== void 0 && {
|
|
290
|
+
creator: props.creator
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
const history = ensureHistory(doc);
|
|
294
|
+
Obj.update(doc, () => {
|
|
295
|
+
history.versions.push(version);
|
|
296
|
+
});
|
|
297
|
+
const stored = history.versions.find(({ id }) => id === version.id);
|
|
298
|
+
invariant(stored, "checkpoint not stored", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 63, S: void 0, A: ["stored", "'checkpoint not stored'"] });
|
|
299
|
+
return stored;
|
|
300
|
+
};
|
|
301
|
+
var versionLabel = (version) => version.name || new Date(version.createdAt).toLocaleString();
|
|
302
|
+
var branchLabel = (branch) => branch.name || new Date(branch.createdAt).toLocaleString();
|
|
303
|
+
var findBranch = (doc, text) => doc.history?.branches.find((branch) => branch.content.target?.id === text.id);
|
|
304
|
+
var createBranch = (doc, props) => {
|
|
305
|
+
const parent = props.parent;
|
|
306
|
+
const anchor = props.heads ? [
|
|
307
|
+
...props.heads
|
|
308
|
+
] : getHeads(parent);
|
|
309
|
+
const baseContent = contentAt(parent, anchor);
|
|
310
|
+
const branchText = Text2.make({
|
|
311
|
+
content: baseContent
|
|
312
|
+
});
|
|
313
|
+
const db = Obj.getDatabase(doc);
|
|
314
|
+
invariant(db, "document not in a database", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 83, S: void 0, A: ["db", "'document not in a database'"] });
|
|
315
|
+
db.add(branchText);
|
|
316
|
+
Obj.setParent(branchText, doc);
|
|
317
|
+
const branch = makeBranch({
|
|
318
|
+
name: props.name,
|
|
319
|
+
content: Ref2.make(branchText),
|
|
320
|
+
parent: Ref2.make(parent),
|
|
321
|
+
anchor,
|
|
322
|
+
...props.creator !== void 0 && {
|
|
323
|
+
creator: props.creator
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
const history = ensureHistory(doc);
|
|
327
|
+
Obj.update(doc, () => {
|
|
328
|
+
history.branches.push(branch);
|
|
329
|
+
});
|
|
330
|
+
if (!history.versions.some((version) => sameHeads(version.heads, anchor))) {
|
|
331
|
+
const version = makeVersion({
|
|
332
|
+
name: `fork: ${branchLabel(branch)}`,
|
|
333
|
+
target: Ref2.make(parent),
|
|
334
|
+
heads: anchor
|
|
335
|
+
});
|
|
336
|
+
Obj.update(doc, () => {
|
|
337
|
+
history.versions.push(version);
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
const stored = history.branches.find(({ id }) => id === branch.id);
|
|
341
|
+
invariant(stored, "branch not stored", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 112, S: void 0, A: ["stored", "'branch not stored'"] });
|
|
342
|
+
return stored;
|
|
343
|
+
};
|
|
344
|
+
var restore = (doc, version) => {
|
|
345
|
+
const text = version.target.target;
|
|
346
|
+
invariant(text, "checkpoint target not loaded", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 117, S: void 0, A: ["text", "'checkpoint target not loaded'"] });
|
|
347
|
+
const historical = contentAt(text, version.heads);
|
|
348
|
+
Obj.update(text, () => {
|
|
349
|
+
EchoText.update(text, "content", historical);
|
|
350
|
+
});
|
|
351
|
+
};
|
|
352
|
+
var mergeBranch = (doc, branch) => {
|
|
353
|
+
const stored = resolveBranch(doc, branch);
|
|
354
|
+
invariant(stored.status === "active", "branch is not active", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 129, S: void 0, A: ["stored.status === 'active'", "'branch is not active'"] });
|
|
355
|
+
const parent = stored.parent.target;
|
|
356
|
+
const branchText = stored.content.target;
|
|
357
|
+
invariant(parent && branchText, "branch refs not loaded", { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 132, S: void 0, A: ["parent && branchText", "'branch refs not loaded'"] });
|
|
358
|
+
const base = contentAt(parent, stored.anchor);
|
|
359
|
+
const { text, conflicts } = merge3({
|
|
360
|
+
base,
|
|
361
|
+
ours: parent.content,
|
|
362
|
+
theirs: branchText.content
|
|
363
|
+
});
|
|
364
|
+
Obj.update(parent, () => {
|
|
365
|
+
EchoText.update(parent, "content", text);
|
|
366
|
+
});
|
|
367
|
+
Obj.update(doc, () => {
|
|
368
|
+
stored.status = "merged";
|
|
369
|
+
stored.mergedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
370
|
+
});
|
|
371
|
+
createCheckpoint(doc, {
|
|
372
|
+
name: `merge: ${branchLabel(stored)}`,
|
|
373
|
+
target: parent
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
conflicts
|
|
377
|
+
};
|
|
378
|
+
};
|
|
379
|
+
var discardBranch = (doc, branch) => {
|
|
380
|
+
const stored = resolveBranch(doc, branch);
|
|
381
|
+
Obj.update(doc, () => {
|
|
382
|
+
stored.status = "archived";
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
var resolveBranch = (doc, branch) => {
|
|
386
|
+
const stored = doc.history?.branches.find(({ id }) => id === branch.id);
|
|
387
|
+
invariant(stored, `branch not found: ${branch.id}`, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 162, S: void 0, A: ["stored", "`branch not found: ${branch.id}`"] });
|
|
388
|
+
return stored;
|
|
389
|
+
};
|
|
390
|
+
var sameHeads = (a, b) => a.length === b.length && a.every((head) => b.includes(head));
|
|
391
|
+
|
|
392
|
+
// src/History.ts
|
|
393
|
+
var History_exports = {};
|
|
394
|
+
__export(History_exports, {
|
|
395
|
+
History: () => History,
|
|
396
|
+
ensure: () => ensureHistory
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// src/Version.ts
|
|
400
|
+
var Version_exports = {};
|
|
401
|
+
__export(Version_exports, {
|
|
402
|
+
Version: () => Version,
|
|
403
|
+
contentAt: () => contentAt,
|
|
404
|
+
create: () => createCheckpoint,
|
|
405
|
+
label: () => versionLabel,
|
|
406
|
+
make: () => makeVersion,
|
|
407
|
+
restore: () => restore
|
|
408
|
+
});
|
|
409
|
+
export {
|
|
410
|
+
Branch_exports as Branch,
|
|
411
|
+
History_exports as History,
|
|
412
|
+
Version_exports as Version,
|
|
413
|
+
diffSpans,
|
|
414
|
+
diffStats,
|
|
415
|
+
merge3
|
|
416
|
+
};
|
|
417
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/Branch.ts", "../../../src/internal/types.ts", "../../../src/internal/model.ts", "../../../src/diff.ts", "../../../src/History.ts", "../../../src/Version.ts"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nexport {\n Branch,\n type MakeBranchProps as MakeProps,\n BranchStatus as Status,\n makeBranch as make,\n} from './internal/types';\nexport {\n type CreateBranchProps as CreateProps,\n type MergeResult,\n createBranch as create,\n discardBranch as discard,\n findBranch as find,\n branchLabel as label,\n mergeBranch as merge,\n} from './internal/model';\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport { Key, Ref } from '@dxos/echo';\nimport { Text } from '@dxos/schema';\n\n/**\n * Named checkpoint: a pointer to the automerge heads of a Text's backing document.\n * Heads are content-addressed change hashes, stable across peers, so a checkpoint is zero-copy.\n * Generic over any object holding a `history` field (see model.ts).\n */\nexport const Version = Schema.mutable(\n Schema.Struct({\n id: Schema.String,\n name: Schema.String,\n target: Ref.Ref(Text.Text),\n heads: Schema.mutable(Schema.Array(Schema.String)),\n createdAt: Schema.String,\n creator: Schema.optional(Schema.String),\n message: Schema.optional(Schema.String),\n }),\n);\nexport interface Version extends Schema.Schema.Type<typeof Version> {}\n\nexport const BranchStatus = Schema.Literal('active', 'merged', 'archived');\nexport type BranchStatus = Schema.Schema.Type<typeof BranchStatus>;\n\n/**\n * A draft Text forked from a parent Text at a specific revision (anchor heads).\n * The branch tree is formed by `parent` references; the root is Document.content.\n */\nexport const Branch = Schema.mutable(\n Schema.Struct({\n id: Schema.String,\n name: Schema.String,\n content: Ref.Ref(Text.Text),\n parent: Ref.Ref(Text.Text),\n anchor: Schema.mutable(Schema.Array(Schema.String)),\n status: BranchStatus,\n createdAt: Schema.String,\n creator: Schema.optional(Schema.String),\n mergedAt: Schema.optional(Schema.String),\n }),\n);\nexport interface Branch extends Schema.Schema.Type<typeof Branch> {}\n\nexport const History = Schema.mutable(\n Schema.Struct({\n branches: Schema.mutable(Schema.Array(Branch)),\n versions: Schema.mutable(Schema.Array(Version)),\n }),\n);\nexport interface History extends Schema.Schema.Type<typeof History> {}\n\nexport type MakeVersionProps = Pick<Version, 'target' | 'heads' | 'name'> &\n Partial<Pick<Version, 'creator' | 'message'>>;\n\n/** Constructs a Version checkpoint record with a generated id and creation timestamp. */\nexport const makeVersion = (props: MakeVersionProps): Version => ({\n id: Key.EntityId.random(),\n createdAt: new Date().toISOString(),\n ...props,\n});\n\nexport type MakeBranchProps = Pick<Branch, 'content' | 'parent' | 'anchor' | 'name'> & Partial<Pick<Branch, 'creator'>>;\n\n/** Constructs an active Branch record with a generated id and creation timestamp. */\nexport const makeBranch = (props: MakeBranchProps): Branch => ({\n id: Key.EntityId.random(),\n status: 'active',\n createdAt: new Date().toISOString(),\n ...props,\n});\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { Text as EchoText, Obj, Ref } from '@dxos/echo';\nimport { checkoutVersion } from '@dxos/echo-client';\nimport { invariant } from '@dxos/invariant';\nimport { Text } from '@dxos/schema';\n\nimport { merge3 } from '../diff';\nimport * as Versioning from './types';\n\n/** Any ECHO object that carries a versioning history (e.g. a markdown document). */\nexport type VersionedObject = Obj.Unknown & { history?: Versioning.History | undefined };\n\n/** Initializes the history struct on first use so existing documents need no migration. */\nexport const ensureHistory = (doc: VersionedObject): Versioning.History => {\n if (!doc.history) {\n Obj.update(doc, (doc) => {\n doc.history = { branches: [], versions: [] };\n });\n }\n const history = doc.history;\n invariant(history, 'history not initialized');\n return history;\n};\n\nconst getHeads = (text: Text.Text): string[] => {\n const version = Obj.version(text);\n invariant(version.versioned && version.automergeHeads, 'text is not versioned (not persisted?)');\n return [...version.automergeHeads];\n};\n\n/** @returns The Text content at the given automerge heads (read-only time travel). */\nexport const contentAt = (text: Text.Text, heads: readonly string[]): string => {\n // `checkoutVersion` returns `unknown` (raw historical data) — narrow via runtime checks.\n const snapshot = checkoutVersion(text, [...heads]);\n if (snapshot && typeof snapshot === 'object' && 'content' in snapshot) {\n const { content } = snapshot;\n return typeof content === 'string' ? content : '';\n }\n return '';\n};\n\nexport type CreateCheckpointProps = { target: Text.Text; name: string; message?: string; creator?: string };\n\n/**\n * Records a named checkpoint of the target Text's current automerge heads and appends it to\n * the object's history. Zero-copy: only the heads are stored.\n */\nexport const createCheckpoint = (doc: VersionedObject, props: CreateCheckpointProps): Versioning.Version => {\n const text = props.target;\n const version = Versioning.makeVersion({\n name: props.name,\n target: Ref.make(text),\n heads: getHeads(text),\n ...(props.message !== undefined && { message: props.message }),\n ...(props.creator !== undefined && { creator: props.creator }),\n });\n const history = ensureHistory(doc);\n Obj.update(doc, () => {\n history.versions.push(version);\n });\n\n // Return the stored record (the pushed plain object is detached from the database).\n const stored = history.versions.find(({ id }) => id === version.id);\n invariant(stored, 'checkpoint not stored');\n return stored;\n};\n\n/** Display label for a checkpoint: its name, or the formatted creation time when unnamed. */\nexport const versionLabel = (version: Versioning.Version): string =>\n version.name || new Date(version.createdAt).toLocaleString();\n\n/** Display label for a branch: its name, or the formatted creation time when unnamed. */\nexport const branchLabel = (branch: Versioning.Branch): string =>\n branch.name || new Date(branch.createdAt).toLocaleString();\n\n/** Find the branch record owning a given Text (undefined for the root). */\nexport const findBranch = (doc: VersionedObject, text: Text.Text): Versioning.Branch | undefined =>\n doc.history?.branches.find((branch) => branch.content.target?.id === text.id);\n\nexport type CreateBranchProps = {\n name: string;\n parent: Text.Text;\n heads?: readonly string[];\n creator?: string;\n};\n\n/**\n * Forks a draft branch: a new Text seeded with the parent's content at the anchor heads\n * (defaults to the parent's current heads), recorded in the object's history. The anchor is\n * auto-checkpointed so the fork point stays addressable in the timeline.\n */\nexport const createBranch = (doc: VersionedObject, props: CreateBranchProps): Versioning.Branch => {\n const parent = props.parent;\n const anchor = props.heads ? [...props.heads] : getHeads(parent);\n const baseContent = contentAt(parent, anchor);\n\n const branchText = Text.make({ content: baseContent });\n const db = Obj.getDatabase(doc);\n invariant(db, 'document not in a database');\n db.add(branchText);\n Obj.setParent(branchText, doc);\n\n const branch = Versioning.makeBranch({\n name: props.name,\n content: Ref.make(branchText),\n parent: Ref.make(parent),\n anchor,\n ...(props.creator !== undefined && { creator: props.creator }),\n });\n\n const history = ensureHistory(doc);\n Obj.update(doc, () => {\n history.branches.push(branch);\n });\n // The anchor must stay addressable by name in the timeline.\n if (!history.versions.some((version) => sameHeads(version.heads, anchor))) {\n const version = Versioning.makeVersion({\n name: `fork: ${branchLabel(branch)}`,\n target: Ref.make(parent),\n heads: anchor,\n });\n Obj.update(doc, () => {\n history.versions.push(version);\n });\n }\n\n // Return the stored record (the pushed plain object is detached from the database).\n const stored = history.branches.find(({ id }) => id === branch.id);\n invariant(stored, 'branch not stored');\n return stored;\n};\n\n/** Applies the checkpoint's content to the tip as a new forward edit — history is never rewritten. */\nexport const restore = (doc: VersionedObject, version: Versioning.Version): void => {\n const text = version.target.target;\n invariant(text, 'checkpoint target not loaded');\n const historical = contentAt(text, version.heads);\n Obj.update(text, () => {\n EchoText.update(text, 'content', historical);\n });\n};\n\nexport type MergeResult = { conflicts: number };\n\n/**\n * 3-way merge: base = parent@anchor, ours = parent tip, theirs = branch tip.\n * Conflicting hunks are left in the document with git-style markers for manual cleanup.\n */\nexport const mergeBranch = (doc: VersionedObject, branch: Versioning.Branch): MergeResult => {\n // Callers may hold a detached copy of the record — mutate the stored one.\n const stored = resolveBranch(doc, branch);\n invariant(stored.status === 'active', 'branch is not active');\n const parent = stored.parent.target;\n const branchText = stored.content.target;\n invariant(parent && branchText, 'branch refs not loaded');\n\n const base = contentAt(parent, stored.anchor);\n const { text, conflicts } = merge3({ base, ours: parent.content, theirs: branchText.content });\n Obj.update(parent, () => {\n EchoText.update(parent, 'content', text);\n });\n Obj.update(doc, () => {\n stored.status = 'merged';\n stored.mergedAt = new Date().toISOString();\n });\n\n createCheckpoint(doc, { name: `merge: ${branchLabel(stored)}`, target: parent });\n return { conflicts };\n};\n\n/** Archives the branch; its Text is retained for recovery. */\nexport const discardBranch = (doc: VersionedObject, branch: Versioning.Branch): void => {\n const stored = resolveBranch(doc, branch);\n Obj.update(doc, () => {\n stored.status = 'archived';\n });\n};\n\nconst resolveBranch = (doc: VersionedObject, branch: Versioning.Branch): Versioning.Branch => {\n const stored = doc.history?.branches.find(({ id }) => id === branch.id);\n invariant(stored, `branch not found: ${branch.id}`);\n return stored;\n};\n\nconst sameHeads = (a: readonly string[], b: readonly string[]) =>\n a.length === b.length && a.every((head) => b.includes(head));\n", "//\n// Copyright 2026 DXOS.org\n//\n\nimport { diffLines, diffWordsWithSpace } from 'diff';\n\n/**\n * Shared diff unit consumed by all diff renderings (inline, side-by-side, gutter).\n * Offsets index into the AFTER text; deletions are zero-width and carry the offset where\n * the removed text used to be, so widgets can render the removed content in place.\n */\nexport type DiffSpan = {\n kind: 'equal' | 'insert' | 'delete';\n from: number;\n to: number;\n text: string;\n};\n\n/** Computes word-level {@link DiffSpan}s between two texts, offset into the after text. */\nexport const diffSpans = (before: string, after: string): DiffSpan[] => {\n const spans: DiffSpan[] = [];\n let offset = 0;\n for (const change of diffWordsWithSpace(before, after)) {\n const kind = change.added ? 'insert' : change.removed ? 'delete' : 'equal';\n const length = kind === 'delete' ? 0 : change.value.length;\n spans.push({ kind, from: offset, to: offset + length, text: change.value });\n offset += length;\n }\n return spans;\n};\n\nexport type DiffStats = { insertions: number; deletions: number };\n\n/** Character counts, used for the `+N −M` branch summaries. */\nexport const diffStats = (spans: DiffSpan[]): DiffStats =>\n spans.reduce(\n (stats, span) => {\n if (span.kind === 'insert') {\n stats.insertions += span.text.length;\n } else if (span.kind === 'delete') {\n stats.deletions += span.text.length;\n }\n return stats;\n },\n { insertions: 0, deletions: 0 },\n );\n\nexport type Merge3Props = { base: string; ours: string; theirs: string };\nexport type Merge3Result = { text: string; conflicts: number };\n\n/**\n * Line-based 3-way merge. Non-overlapping hunks apply automatically; overlapping hunks\n * produce git-style conflict markers with the branch (theirs) side first, since the merge\n * flow is review-then-accept and the branch content is what was just reviewed.\n */\nexport const merge3 = ({ base, ours, theirs }: Merge3Props): Merge3Result => {\n if (ours === base) {\n return { text: theirs, conflicts: 0 };\n }\n if (theirs === base || ours === theirs) {\n return { text: ours, conflicts: 0 };\n }\n\n const baseLines = splitLines(base);\n const oursHunks = lineHunks(baseLines, splitLines(ours));\n const theirsHunks = lineHunks(baseLines, splitLines(theirs));\n\n const out: string[] = [];\n let conflicts = 0;\n let baseIndex = 0;\n let oursCursor = 0;\n let theirsCursor = 0;\n\n while (baseIndex < baseLines.length || oursCursor < oursHunks.length || theirsCursor < theirsHunks.length) {\n const oursHunk = oursHunks[oursCursor];\n const theirsHunk = theirsHunks[theirsCursor];\n const nextOurs = oursHunk?.baseStart ?? Infinity;\n const nextTheirs = theirsHunk?.baseStart ?? Infinity;\n const next = Math.min(nextOurs, nextTheirs);\n\n // Copy unchanged base lines up to the next hunk.\n while (baseIndex < Math.min(next, baseLines.length)) {\n out.push(baseLines[baseIndex]);\n baseIndex += 1;\n }\n if (next === Infinity) {\n break;\n }\n\n const oursActive = oursHunk !== undefined && oursHunk.baseStart === next;\n const theirsActive = theirsHunk !== undefined && theirsHunk.baseStart === next;\n const identical =\n oursActive &&\n theirsActive &&\n sameLines(oursHunk.lines, theirsHunk.lines) &&\n oursHunk.baseLength === theirsHunk.baseLength;\n // Hunks conflict when their consumed base intervals overlap — same start, or a staggered\n // hunk beginning inside the interval the active hunk consumes (e.g. [0,2) vs [1,2)).\n const overlap =\n !identical &&\n oursHunk !== undefined &&\n theirsHunk !== undefined &&\n (nextOurs === nextTheirs ||\n (oursActive && nextTheirs < hunkEnd(oursHunk)) ||\n (theirsActive && nextOurs < hunkEnd(theirsHunk)));\n\n if (overlap) {\n // The conflict region is the connected union of every intersecting hunk on both sides —\n // a broad hunk can overlap several smaller ones, all of which must be consumed together.\n const oursRegion = [oursHunk];\n const theirsRegion = [theirsHunk];\n oursCursor += 1;\n theirsCursor += 1;\n let unionEnd = Math.max(hunkEnd(oursHunk), hunkEnd(theirsHunk));\n let expanded = true;\n while (expanded) {\n expanded = false;\n while (oursCursor < oursHunks.length && oursHunks[oursCursor].baseStart < unionEnd) {\n const hunk = oursHunks[oursCursor];\n oursRegion.push(hunk);\n unionEnd = Math.max(unionEnd, hunkEnd(hunk));\n oursCursor += 1;\n expanded = true;\n }\n while (theirsCursor < theirsHunks.length && theirsHunks[theirsCursor].baseStart < unionEnd) {\n const hunk = theirsHunks[theirsCursor];\n theirsRegion.push(hunk);\n unionEnd = Math.max(unionEnd, hunkEnd(hunk));\n theirsCursor += 1;\n expanded = true;\n }\n }\n\n out.push(\n '<<<<<<< branch',\n ...sideContent(baseLines, theirsRegion, next, unionEnd),\n '=======',\n ...sideContent(baseLines, oursRegion, next, unionEnd),\n '>>>>>>> current',\n );\n conflicts += 1;\n baseIndex = unionEnd;\n } else if (identical) {\n out.push(...oursHunk.lines);\n baseIndex = next + oursHunk.baseLength;\n oursCursor += 1;\n theirsCursor += 1;\n } else if (oursActive) {\n out.push(...oursHunk.lines);\n baseIndex = next + oursHunk.baseLength;\n oursCursor += 1;\n } else if (theirsHunk !== undefined) {\n out.push(...theirsHunk.lines);\n baseIndex = next + theirsHunk.baseLength;\n theirsCursor += 1;\n }\n }\n\n return { text: joinLines(out, [base, ours, theirs]), conflicts };\n};\n\ntype Hunk = { baseStart: number; baseLength: number; lines: string[] };\n\nconst hunkEnd = (hunk: Hunk) => hunk.baseStart + hunk.baseLength;\n\n/** One side's content for a conflict region: its hunks plus the union's base lines they leave unchanged. */\nconst sideContent = (baseLines: string[], hunks: Hunk[], unionStart: number, unionEnd: number): string[] => {\n const out: string[] = [];\n let position = unionStart;\n for (const hunk of hunks) {\n out.push(...baseLines.slice(position, hunk.baseStart), ...hunk.lines);\n position = Math.max(position, hunkEnd(hunk));\n }\n out.push(...baseLines.slice(position, unionEnd));\n return out;\n};\n\n/** Convert jsdiff line changes into base-anchored replacement hunks. */\nconst lineHunks = (baseLines: string[], sideLines: string[]): Hunk[] => {\n const hunks: Hunk[] = [];\n let baseIndex = 0;\n let pending: Hunk | undefined;\n for (const change of diffLines(joinForDiff(baseLines), joinForDiff(sideLines))) {\n const lines = chunkLines(change.value);\n if (change.added) {\n pending = pending ?? { baseStart: baseIndex, baseLength: 0, lines: [] };\n pending.lines.push(...lines);\n } else if (change.removed) {\n pending = pending ?? { baseStart: baseIndex, baseLength: 0, lines: [] };\n pending.baseLength += lines.length;\n baseIndex += lines.length;\n } else {\n if (pending) {\n hunks.push(pending);\n pending = undefined;\n }\n baseIndex += lines.length;\n }\n }\n if (pending) {\n hunks.push(pending);\n }\n return hunks;\n};\n\nconst sameLines = (a: string[], b: string[]) => a.length === b.length && a.every((line, index) => line === b[index]);\n\nconst splitLines = (text: string): string[] => (text === '' ? [] : stripTrailingNewline(text).split('\\n'));\n\n// Unlike whole-document splitting, a diff chunk is never empty — a chunk of '\\n' is one blank\n// line (jsdiff attaches the terminator to its line), so no empty-string special case applies.\nconst chunkLines = (value: string): string[] => stripTrailingNewline(value).split('\\n');\n\nconst stripTrailingNewline = (text: string) => (text.endsWith('\\n') ? text.slice(0, -1) : text);\n\n// diffLines needs a trailing newline so the last line compares as a whole line.\nconst joinForDiff = (lines: string[]) => (lines.length === 0 ? '' : `${lines.join('\\n')}\\n`);\n\nconst joinLines = (lines: string[], inputs: string[]) => {\n const text = lines.join('\\n');\n // Preserve a trailing newline when every non-empty input has one.\n const nonEmpty = inputs.filter((input) => input.length > 0);\n const trailing = nonEmpty.length > 0 && nonEmpty.every((input) => input.endsWith('\\n'));\n return trailing && text.length > 0 ? `${text}\\n` : text;\n};\n", "//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nexport { History } from './internal/types';\nexport { type VersionedObject, ensureHistory as ensure } from './internal/model';\n", "//\n// Copyright 2026 DXOS.org\n//\n\n// @import-as-namespace\n\nexport { type MakeVersionProps as MakeProps, Version, makeVersion as make } from './internal/types';\nexport {\n type CreateCheckpointProps as CreateProps,\n contentAt,\n createCheckpoint as create,\n versionLabel as label,\n restore,\n} from './internal/model';\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Schema", "Key", "Ref", "Text", "Version", "mutable", "Struct", "id", "String", "name", "target", "heads", "Array", "createdAt", "creator", "optional", "message", "BranchStatus", "Literal", "Branch", "content", "parent", "anchor", "status", "mergedAt", "History", "branches", "versions", "makeVersion", "props", "EntityId", "random", "Date", "toISOString", "makeBranch", "Text", "EchoText", "Obj", "Ref", "checkoutVersion", "invariant", "diffLines", "diffWordsWithSpace", "diffSpans", "before", "after", "spans", "offset", "change", "kind", "added", "removed", "length", "value", "push", "from", "to", "text", "diffStats", "reduce", "stats", "span", "insertions", "deletions", "merge3", "base", "ours", "theirs", "conflicts", "baseLines", "splitLines", "oursHunks", "lineHunks", "theirsHunks", "out", "baseIndex", "oursCursor", "theirsCursor", "oursHunk", "theirsHunk", "nextOurs", "baseStart", "Infinity", "nextTheirs", "next", "Math", "min", "oursActive", "undefined", "theirsActive", "identical", "sameLines", "lines", "baseLength", "overlap", "hunkEnd", "oursRegion", "theirsRegion", "unionEnd", "max", "expanded", "hunk", "sideContent", "joinLines", "hunks", "unionStart", "position", "slice", "sideLines", "pending", "joinForDiff", "chunkLines", "a", "b", "every", "line", "index", "stripTrailingNewline", "split", "endsWith", "join", "inputs", "nonEmpty", "filter", "input", "trailing", "doc", "history", "branches", "versions", "invariant", "getHeads", "version", "versioned", "automergeHeads", "snapshot", "content", "makeVersion", "name", "props", "target", "text", "heads", "message", "undefined", "creator", "Obj", "stored", "findBranch", "find", "branch", "id", "anchor", "parent", "baseContent", "branchText", "Text", "db", "setParent", "Versioning", "make", "branchLabel", "Ref", "update", "historical", "contentAt", "EchoText", "resolveBranch", "base", "conflicts", "merge3", "ours", "theirs", "mergedAt", "createCheckpoint", "status", "sameHeads"]
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"inputs":{"src/internal/types.ts":{"bytes":7963,"imports":[{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"@dxos/echo","kind":"import-statement","external":true},{"path":"@dxos/schema","kind":"import-statement","external":true}],"format":"esm"},"src/diff.ts":{"bytes":27656,"imports":[{"path":"diff","kind":"import-statement","external":true}],"format":"esm"},"src/internal/model.ts":{"bytes":24412,"imports":[{"path":"@dxos/echo","kind":"import-statement","external":true},{"path":"@dxos/echo-client","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/schema","kind":"import-statement","external":true},{"path":"src/diff.ts","kind":"import-statement","original":"../diff"},{"path":"src/internal/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"},"src/Branch.ts":{"bytes":1548,"imports":[{"path":"src/internal/types.ts","kind":"import-statement","original":"./internal/types"},{"path":"src/internal/model.ts","kind":"import-statement","original":"./internal/model"}],"format":"esm"},"src/History.ts":{"bytes":776,"imports":[{"path":"src/internal/types.ts","kind":"import-statement","original":"./internal/types"},{"path":"src/internal/model.ts","kind":"import-statement","original":"./internal/model"}],"format":"esm"},"src/Version.ts":{"bytes":1203,"imports":[{"path":"src/internal/types.ts","kind":"import-statement","original":"./internal/types"},{"path":"src/internal/model.ts","kind":"import-statement","original":"./internal/model"}],"format":"esm"},"src/index.ts":{"bytes":796,"imports":[{"path":"src/Branch.ts","kind":"import-statement","original":"./Branch"},{"path":"src/History.ts","kind":"import-statement","original":"./History"},{"path":"src/Version.ts","kind":"import-statement","original":"./Version"},{"path":"src/diff.ts","kind":"import-statement","original":"./diff"}],"format":"esm"}},"outputs":{"dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":31191},"dist/lib/browser/index.mjs":{"imports":[{"path":"effect/Schema","kind":"import-statement","external":true},{"path":"@dxos/echo","kind":"import-statement","external":true},{"path":"@dxos/schema","kind":"import-statement","external":true},{"path":"@dxos/echo","kind":"import-statement","external":true},{"path":"@dxos/echo-client","kind":"import-statement","external":true},{"path":"@dxos/invariant","kind":"import-statement","external":true},{"path":"@dxos/schema","kind":"import-statement","external":true},{"path":"diff","kind":"import-statement","external":true}],"exports":["Branch","History","Version","diffSpans","diffStats","merge3"],"entryPoint":"src/index.ts","inputs":{"src/Branch.ts":{"bytesInOutput":279},"src/internal/types.ts":{"bytesInOutput":1257},"src/internal/model.ts":{"bytesInOutput":5653},"src/diff.ts":{"bytesInOutput":5944},"src/index.ts":{"bytesInOutput":0},"src/History.ts":{"bytesInOutput":114},"src/Version.ts":{"bytesInOutput":229}},"bytes":13963}}}
|