@pstdio/sdk 0.44.0 → 0.45.0-nightly.20261020145025
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/api/index.js +372 -43
- package/dist/api.d.ts +4 -4
- package/dist/client/index.js +28 -1
- package/dist/client.d.ts +2 -2
- package/dist/data.d.ts +1 -1
- package/dist/extensions/index.js +4 -2
- package/dist/extensions-react.d.ts +1 -1
- package/dist/extensions.d.ts +2 -2
- package/dist/hooks.d.ts +3 -3
- package/dist/{index-BooGkjrP.d.ts → index-2xyvngQL.d.ts} +958 -759
- package/dist/{index-B3qUeP-z.d.ts → index-COAsJaAT.d.ts} +125 -3
- package/dist/resources/index.js +372 -43
- package/dist/resources.d.ts +1 -1
- package/dist/sessions-CiG7jg2r.d.ts +2 -0
- package/dist/skills-CiG7jg2r.d.ts +2 -0
- package/dist/testing/index.js +1626 -942
- package/dist/testing.d.ts +1 -1
- package/package.json +1 -1
- package/dist/sessions-uM8AN3_e.d.ts +0 -2
- package/dist/skills-uM8AN3_e.d.ts +0 -2
package/dist/testing/index.js
CHANGED
|
@@ -1,4 +1,36 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
1
3
|
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
function __accessProp(key) {
|
|
7
|
+
return this[key];
|
|
8
|
+
}
|
|
9
|
+
var __toESMCache_node;
|
|
10
|
+
var __toESMCache_esm;
|
|
11
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
12
|
+
var canCache = mod != null && typeof mod === "object";
|
|
13
|
+
if (canCache) {
|
|
14
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
15
|
+
var cached = cache.get(mod);
|
|
16
|
+
if (cached)
|
|
17
|
+
return cached;
|
|
18
|
+
}
|
|
19
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
20
|
+
const to = isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
21
|
+
if (mod && typeof mod === "object" || typeof mod === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
if (canCache)
|
|
30
|
+
cache.set(mod, to);
|
|
31
|
+
return to;
|
|
32
|
+
};
|
|
33
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
2
34
|
var __returnValue = (v) => v;
|
|
3
35
|
function __exportSetter(name, newValue) {
|
|
4
36
|
this[name] = __returnValue.bind(null, newValue);
|
|
@@ -13,6 +45,730 @@ var __export = (target, all) => {
|
|
|
13
45
|
});
|
|
14
46
|
};
|
|
15
47
|
|
|
48
|
+
// ../../node_modules/.bun/fast-diff@1.3.0/node_modules/fast-diff/diff.js
|
|
49
|
+
var require_diff = __commonJS(function(exports, module) {
|
|
50
|
+
var DIFF_DELETE = -1;
|
|
51
|
+
var DIFF_INSERT = 1;
|
|
52
|
+
var DIFF_EQUAL = 0;
|
|
53
|
+
function diff_main(text1, text2, cursor_pos, cleanup, _fix_unicode) {
|
|
54
|
+
if (text1 === text2) {
|
|
55
|
+
if (text1) {
|
|
56
|
+
return [[DIFF_EQUAL, text1]];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (cursor_pos != null) {
|
|
61
|
+
var editdiff = find_cursor_edit_diff(text1, text2, cursor_pos);
|
|
62
|
+
if (editdiff) {
|
|
63
|
+
return editdiff;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
var commonlength = diff_commonPrefix(text1, text2);
|
|
67
|
+
var commonprefix = text1.substring(0, commonlength);
|
|
68
|
+
text1 = text1.substring(commonlength);
|
|
69
|
+
text2 = text2.substring(commonlength);
|
|
70
|
+
commonlength = diff_commonSuffix(text1, text2);
|
|
71
|
+
var commonsuffix = text1.substring(text1.length - commonlength);
|
|
72
|
+
text1 = text1.substring(0, text1.length - commonlength);
|
|
73
|
+
text2 = text2.substring(0, text2.length - commonlength);
|
|
74
|
+
var diffs = diff_compute_(text1, text2);
|
|
75
|
+
if (commonprefix) {
|
|
76
|
+
diffs.unshift([DIFF_EQUAL, commonprefix]);
|
|
77
|
+
}
|
|
78
|
+
if (commonsuffix) {
|
|
79
|
+
diffs.push([DIFF_EQUAL, commonsuffix]);
|
|
80
|
+
}
|
|
81
|
+
diff_cleanupMerge(diffs, _fix_unicode);
|
|
82
|
+
if (cleanup) {
|
|
83
|
+
diff_cleanupSemantic(diffs);
|
|
84
|
+
}
|
|
85
|
+
return diffs;
|
|
86
|
+
}
|
|
87
|
+
function diff_compute_(text1, text2) {
|
|
88
|
+
var diffs;
|
|
89
|
+
if (!text1) {
|
|
90
|
+
return [[DIFF_INSERT, text2]];
|
|
91
|
+
}
|
|
92
|
+
if (!text2) {
|
|
93
|
+
return [[DIFF_DELETE, text1]];
|
|
94
|
+
}
|
|
95
|
+
var longtext = text1.length > text2.length ? text1 : text2;
|
|
96
|
+
var shorttext = text1.length > text2.length ? text2 : text1;
|
|
97
|
+
var i = longtext.indexOf(shorttext);
|
|
98
|
+
if (i !== -1) {
|
|
99
|
+
diffs = [
|
|
100
|
+
[DIFF_INSERT, longtext.substring(0, i)],
|
|
101
|
+
[DIFF_EQUAL, shorttext],
|
|
102
|
+
[DIFF_INSERT, longtext.substring(i + shorttext.length)]
|
|
103
|
+
];
|
|
104
|
+
if (text1.length > text2.length) {
|
|
105
|
+
diffs[0][0] = diffs[2][0] = DIFF_DELETE;
|
|
106
|
+
}
|
|
107
|
+
return diffs;
|
|
108
|
+
}
|
|
109
|
+
if (shorttext.length === 1) {
|
|
110
|
+
return [
|
|
111
|
+
[DIFF_DELETE, text1],
|
|
112
|
+
[DIFF_INSERT, text2]
|
|
113
|
+
];
|
|
114
|
+
}
|
|
115
|
+
var hm = diff_halfMatch_(text1, text2);
|
|
116
|
+
if (hm) {
|
|
117
|
+
var text1_a = hm[0];
|
|
118
|
+
var text1_b = hm[1];
|
|
119
|
+
var text2_a = hm[2];
|
|
120
|
+
var text2_b = hm[3];
|
|
121
|
+
var mid_common = hm[4];
|
|
122
|
+
var diffs_a = diff_main(text1_a, text2_a);
|
|
123
|
+
var diffs_b = diff_main(text1_b, text2_b);
|
|
124
|
+
return diffs_a.concat([[DIFF_EQUAL, mid_common]], diffs_b);
|
|
125
|
+
}
|
|
126
|
+
return diff_bisect_(text1, text2);
|
|
127
|
+
}
|
|
128
|
+
function diff_bisect_(text1, text2) {
|
|
129
|
+
var text1_length = text1.length;
|
|
130
|
+
var text2_length = text2.length;
|
|
131
|
+
var max_d = Math.ceil((text1_length + text2_length) / 2);
|
|
132
|
+
var v_offset = max_d;
|
|
133
|
+
var v_length = 2 * max_d;
|
|
134
|
+
var v1 = new Array(v_length);
|
|
135
|
+
var v2 = new Array(v_length);
|
|
136
|
+
for (var x = 0;x < v_length; x++) {
|
|
137
|
+
v1[x] = -1;
|
|
138
|
+
v2[x] = -1;
|
|
139
|
+
}
|
|
140
|
+
v1[v_offset + 1] = 0;
|
|
141
|
+
v2[v_offset + 1] = 0;
|
|
142
|
+
var delta = text1_length - text2_length;
|
|
143
|
+
var front = delta % 2 !== 0;
|
|
144
|
+
var k1start = 0;
|
|
145
|
+
var k1end = 0;
|
|
146
|
+
var k2start = 0;
|
|
147
|
+
var k2end = 0;
|
|
148
|
+
for (var d = 0;d < max_d; d++) {
|
|
149
|
+
for (var k1 = -d + k1start;k1 <= d - k1end; k1 += 2) {
|
|
150
|
+
var k1_offset = v_offset + k1;
|
|
151
|
+
var x1;
|
|
152
|
+
if (k1 === -d || k1 !== d && v1[k1_offset - 1] < v1[k1_offset + 1]) {
|
|
153
|
+
x1 = v1[k1_offset + 1];
|
|
154
|
+
} else {
|
|
155
|
+
x1 = v1[k1_offset - 1] + 1;
|
|
156
|
+
}
|
|
157
|
+
var y1 = x1 - k1;
|
|
158
|
+
while (x1 < text1_length && y1 < text2_length && text1.charAt(x1) === text2.charAt(y1)) {
|
|
159
|
+
x1++;
|
|
160
|
+
y1++;
|
|
161
|
+
}
|
|
162
|
+
v1[k1_offset] = x1;
|
|
163
|
+
if (x1 > text1_length) {
|
|
164
|
+
k1end += 2;
|
|
165
|
+
} else if (y1 > text2_length) {
|
|
166
|
+
k1start += 2;
|
|
167
|
+
} else if (front) {
|
|
168
|
+
var k2_offset = v_offset + delta - k1;
|
|
169
|
+
if (k2_offset >= 0 && k2_offset < v_length && v2[k2_offset] !== -1) {
|
|
170
|
+
var x2 = text1_length - v2[k2_offset];
|
|
171
|
+
if (x1 >= x2) {
|
|
172
|
+
return diff_bisectSplit_(text1, text2, x1, y1);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
for (var k2 = -d + k2start;k2 <= d - k2end; k2 += 2) {
|
|
178
|
+
var k2_offset = v_offset + k2;
|
|
179
|
+
var x2;
|
|
180
|
+
if (k2 === -d || k2 !== d && v2[k2_offset - 1] < v2[k2_offset + 1]) {
|
|
181
|
+
x2 = v2[k2_offset + 1];
|
|
182
|
+
} else {
|
|
183
|
+
x2 = v2[k2_offset - 1] + 1;
|
|
184
|
+
}
|
|
185
|
+
var y2 = x2 - k2;
|
|
186
|
+
while (x2 < text1_length && y2 < text2_length && text1.charAt(text1_length - x2 - 1) === text2.charAt(text2_length - y2 - 1)) {
|
|
187
|
+
x2++;
|
|
188
|
+
y2++;
|
|
189
|
+
}
|
|
190
|
+
v2[k2_offset] = x2;
|
|
191
|
+
if (x2 > text1_length) {
|
|
192
|
+
k2end += 2;
|
|
193
|
+
} else if (y2 > text2_length) {
|
|
194
|
+
k2start += 2;
|
|
195
|
+
} else if (!front) {
|
|
196
|
+
var k1_offset = v_offset + delta - k2;
|
|
197
|
+
if (k1_offset >= 0 && k1_offset < v_length && v1[k1_offset] !== -1) {
|
|
198
|
+
var x1 = v1[k1_offset];
|
|
199
|
+
var y1 = v_offset + x1 - k1_offset;
|
|
200
|
+
x2 = text1_length - x2;
|
|
201
|
+
if (x1 >= x2) {
|
|
202
|
+
return diff_bisectSplit_(text1, text2, x1, y1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return [
|
|
209
|
+
[DIFF_DELETE, text1],
|
|
210
|
+
[DIFF_INSERT, text2]
|
|
211
|
+
];
|
|
212
|
+
}
|
|
213
|
+
function diff_bisectSplit_(text1, text2, x, y) {
|
|
214
|
+
var text1a = text1.substring(0, x);
|
|
215
|
+
var text2a = text2.substring(0, y);
|
|
216
|
+
var text1b = text1.substring(x);
|
|
217
|
+
var text2b = text2.substring(y);
|
|
218
|
+
var diffs = diff_main(text1a, text2a);
|
|
219
|
+
var diffsb = diff_main(text1b, text2b);
|
|
220
|
+
return diffs.concat(diffsb);
|
|
221
|
+
}
|
|
222
|
+
function diff_commonPrefix(text1, text2) {
|
|
223
|
+
if (!text1 || !text2 || text1.charAt(0) !== text2.charAt(0)) {
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
var pointermin = 0;
|
|
227
|
+
var pointermax = Math.min(text1.length, text2.length);
|
|
228
|
+
var pointermid = pointermax;
|
|
229
|
+
var pointerstart = 0;
|
|
230
|
+
while (pointermin < pointermid) {
|
|
231
|
+
if (text1.substring(pointerstart, pointermid) == text2.substring(pointerstart, pointermid)) {
|
|
232
|
+
pointermin = pointermid;
|
|
233
|
+
pointerstart = pointermin;
|
|
234
|
+
} else {
|
|
235
|
+
pointermax = pointermid;
|
|
236
|
+
}
|
|
237
|
+
pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
|
|
238
|
+
}
|
|
239
|
+
if (is_surrogate_pair_start(text1.charCodeAt(pointermid - 1))) {
|
|
240
|
+
pointermid--;
|
|
241
|
+
}
|
|
242
|
+
return pointermid;
|
|
243
|
+
}
|
|
244
|
+
function diff_commonOverlap_(text1, text2) {
|
|
245
|
+
var text1_length = text1.length;
|
|
246
|
+
var text2_length = text2.length;
|
|
247
|
+
if (text1_length == 0 || text2_length == 0) {
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
if (text1_length > text2_length) {
|
|
251
|
+
text1 = text1.substring(text1_length - text2_length);
|
|
252
|
+
} else if (text1_length < text2_length) {
|
|
253
|
+
text2 = text2.substring(0, text1_length);
|
|
254
|
+
}
|
|
255
|
+
var text_length = Math.min(text1_length, text2_length);
|
|
256
|
+
if (text1 == text2) {
|
|
257
|
+
return text_length;
|
|
258
|
+
}
|
|
259
|
+
var best = 0;
|
|
260
|
+
var length = 1;
|
|
261
|
+
while (true) {
|
|
262
|
+
var pattern = text1.substring(text_length - length);
|
|
263
|
+
var found = text2.indexOf(pattern);
|
|
264
|
+
if (found == -1) {
|
|
265
|
+
return best;
|
|
266
|
+
}
|
|
267
|
+
length += found;
|
|
268
|
+
if (found == 0 || text1.substring(text_length - length) == text2.substring(0, length)) {
|
|
269
|
+
best = length;
|
|
270
|
+
length++;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function diff_commonSuffix(text1, text2) {
|
|
275
|
+
if (!text1 || !text2 || text1.slice(-1) !== text2.slice(-1)) {
|
|
276
|
+
return 0;
|
|
277
|
+
}
|
|
278
|
+
var pointermin = 0;
|
|
279
|
+
var pointermax = Math.min(text1.length, text2.length);
|
|
280
|
+
var pointermid = pointermax;
|
|
281
|
+
var pointerend = 0;
|
|
282
|
+
while (pointermin < pointermid) {
|
|
283
|
+
if (text1.substring(text1.length - pointermid, text1.length - pointerend) == text2.substring(text2.length - pointermid, text2.length - pointerend)) {
|
|
284
|
+
pointermin = pointermid;
|
|
285
|
+
pointerend = pointermin;
|
|
286
|
+
} else {
|
|
287
|
+
pointermax = pointermid;
|
|
288
|
+
}
|
|
289
|
+
pointermid = Math.floor((pointermax - pointermin) / 2 + pointermin);
|
|
290
|
+
}
|
|
291
|
+
if (is_surrogate_pair_end(text1.charCodeAt(text1.length - pointermid))) {
|
|
292
|
+
pointermid--;
|
|
293
|
+
}
|
|
294
|
+
return pointermid;
|
|
295
|
+
}
|
|
296
|
+
function diff_halfMatch_(text1, text2) {
|
|
297
|
+
var longtext = text1.length > text2.length ? text1 : text2;
|
|
298
|
+
var shorttext = text1.length > text2.length ? text2 : text1;
|
|
299
|
+
if (longtext.length < 4 || shorttext.length * 2 < longtext.length) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
function diff_halfMatchI_(longtext, shorttext, i) {
|
|
303
|
+
var seed = longtext.substring(i, i + Math.floor(longtext.length / 4));
|
|
304
|
+
var j = -1;
|
|
305
|
+
var best_common = "";
|
|
306
|
+
var best_longtext_a, best_longtext_b, best_shorttext_a, best_shorttext_b;
|
|
307
|
+
while ((j = shorttext.indexOf(seed, j + 1)) !== -1) {
|
|
308
|
+
var prefixLength = diff_commonPrefix(longtext.substring(i), shorttext.substring(j));
|
|
309
|
+
var suffixLength = diff_commonSuffix(longtext.substring(0, i), shorttext.substring(0, j));
|
|
310
|
+
if (best_common.length < suffixLength + prefixLength) {
|
|
311
|
+
best_common = shorttext.substring(j - suffixLength, j) + shorttext.substring(j, j + prefixLength);
|
|
312
|
+
best_longtext_a = longtext.substring(0, i - suffixLength);
|
|
313
|
+
best_longtext_b = longtext.substring(i + prefixLength);
|
|
314
|
+
best_shorttext_a = shorttext.substring(0, j - suffixLength);
|
|
315
|
+
best_shorttext_b = shorttext.substring(j + prefixLength);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (best_common.length * 2 >= longtext.length) {
|
|
319
|
+
return [
|
|
320
|
+
best_longtext_a,
|
|
321
|
+
best_longtext_b,
|
|
322
|
+
best_shorttext_a,
|
|
323
|
+
best_shorttext_b,
|
|
324
|
+
best_common
|
|
325
|
+
];
|
|
326
|
+
} else {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
var hm1 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 4));
|
|
331
|
+
var hm2 = diff_halfMatchI_(longtext, shorttext, Math.ceil(longtext.length / 2));
|
|
332
|
+
var hm;
|
|
333
|
+
if (!hm1 && !hm2) {
|
|
334
|
+
return null;
|
|
335
|
+
} else if (!hm2) {
|
|
336
|
+
hm = hm1;
|
|
337
|
+
} else if (!hm1) {
|
|
338
|
+
hm = hm2;
|
|
339
|
+
} else {
|
|
340
|
+
hm = hm1[4].length > hm2[4].length ? hm1 : hm2;
|
|
341
|
+
}
|
|
342
|
+
var text1_a, text1_b, text2_a, text2_b;
|
|
343
|
+
if (text1.length > text2.length) {
|
|
344
|
+
text1_a = hm[0];
|
|
345
|
+
text1_b = hm[1];
|
|
346
|
+
text2_a = hm[2];
|
|
347
|
+
text2_b = hm[3];
|
|
348
|
+
} else {
|
|
349
|
+
text2_a = hm[0];
|
|
350
|
+
text2_b = hm[1];
|
|
351
|
+
text1_a = hm[2];
|
|
352
|
+
text1_b = hm[3];
|
|
353
|
+
}
|
|
354
|
+
var mid_common = hm[4];
|
|
355
|
+
return [text1_a, text1_b, text2_a, text2_b, mid_common];
|
|
356
|
+
}
|
|
357
|
+
function diff_cleanupSemantic(diffs) {
|
|
358
|
+
var changes = false;
|
|
359
|
+
var equalities = [];
|
|
360
|
+
var equalitiesLength = 0;
|
|
361
|
+
var lastequality = null;
|
|
362
|
+
var pointer = 0;
|
|
363
|
+
var length_insertions1 = 0;
|
|
364
|
+
var length_deletions1 = 0;
|
|
365
|
+
var length_insertions2 = 0;
|
|
366
|
+
var length_deletions2 = 0;
|
|
367
|
+
while (pointer < diffs.length) {
|
|
368
|
+
if (diffs[pointer][0] == DIFF_EQUAL) {
|
|
369
|
+
equalities[equalitiesLength++] = pointer;
|
|
370
|
+
length_insertions1 = length_insertions2;
|
|
371
|
+
length_deletions1 = length_deletions2;
|
|
372
|
+
length_insertions2 = 0;
|
|
373
|
+
length_deletions2 = 0;
|
|
374
|
+
lastequality = diffs[pointer][1];
|
|
375
|
+
} else {
|
|
376
|
+
if (diffs[pointer][0] == DIFF_INSERT) {
|
|
377
|
+
length_insertions2 += diffs[pointer][1].length;
|
|
378
|
+
} else {
|
|
379
|
+
length_deletions2 += diffs[pointer][1].length;
|
|
380
|
+
}
|
|
381
|
+
if (lastequality && lastequality.length <= Math.max(length_insertions1, length_deletions1) && lastequality.length <= Math.max(length_insertions2, length_deletions2)) {
|
|
382
|
+
diffs.splice(equalities[equalitiesLength - 1], 0, [
|
|
383
|
+
DIFF_DELETE,
|
|
384
|
+
lastequality
|
|
385
|
+
]);
|
|
386
|
+
diffs[equalities[equalitiesLength - 1] + 1][0] = DIFF_INSERT;
|
|
387
|
+
equalitiesLength--;
|
|
388
|
+
equalitiesLength--;
|
|
389
|
+
pointer = equalitiesLength > 0 ? equalities[equalitiesLength - 1] : -1;
|
|
390
|
+
length_insertions1 = 0;
|
|
391
|
+
length_deletions1 = 0;
|
|
392
|
+
length_insertions2 = 0;
|
|
393
|
+
length_deletions2 = 0;
|
|
394
|
+
lastequality = null;
|
|
395
|
+
changes = true;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
pointer++;
|
|
399
|
+
}
|
|
400
|
+
if (changes) {
|
|
401
|
+
diff_cleanupMerge(diffs);
|
|
402
|
+
}
|
|
403
|
+
diff_cleanupSemanticLossless(diffs);
|
|
404
|
+
pointer = 1;
|
|
405
|
+
while (pointer < diffs.length) {
|
|
406
|
+
if (diffs[pointer - 1][0] == DIFF_DELETE && diffs[pointer][0] == DIFF_INSERT) {
|
|
407
|
+
var deletion = diffs[pointer - 1][1];
|
|
408
|
+
var insertion = diffs[pointer][1];
|
|
409
|
+
var overlap_length1 = diff_commonOverlap_(deletion, insertion);
|
|
410
|
+
var overlap_length2 = diff_commonOverlap_(insertion, deletion);
|
|
411
|
+
if (overlap_length1 >= overlap_length2) {
|
|
412
|
+
if (overlap_length1 >= deletion.length / 2 || overlap_length1 >= insertion.length / 2) {
|
|
413
|
+
diffs.splice(pointer, 0, [
|
|
414
|
+
DIFF_EQUAL,
|
|
415
|
+
insertion.substring(0, overlap_length1)
|
|
416
|
+
]);
|
|
417
|
+
diffs[pointer - 1][1] = deletion.substring(0, deletion.length - overlap_length1);
|
|
418
|
+
diffs[pointer + 1][1] = insertion.substring(overlap_length1);
|
|
419
|
+
pointer++;
|
|
420
|
+
}
|
|
421
|
+
} else {
|
|
422
|
+
if (overlap_length2 >= deletion.length / 2 || overlap_length2 >= insertion.length / 2) {
|
|
423
|
+
diffs.splice(pointer, 0, [
|
|
424
|
+
DIFF_EQUAL,
|
|
425
|
+
deletion.substring(0, overlap_length2)
|
|
426
|
+
]);
|
|
427
|
+
diffs[pointer - 1][0] = DIFF_INSERT;
|
|
428
|
+
diffs[pointer - 1][1] = insertion.substring(0, insertion.length - overlap_length2);
|
|
429
|
+
diffs[pointer + 1][0] = DIFF_DELETE;
|
|
430
|
+
diffs[pointer + 1][1] = deletion.substring(overlap_length2);
|
|
431
|
+
pointer++;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
pointer++;
|
|
435
|
+
}
|
|
436
|
+
pointer++;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
var nonAlphaNumericRegex_ = /[^a-zA-Z0-9]/;
|
|
440
|
+
var whitespaceRegex_ = /\s/;
|
|
441
|
+
var linebreakRegex_ = /[\r\n]/;
|
|
442
|
+
var blanklineEndRegex_ = /\n\r?\n$/;
|
|
443
|
+
var blanklineStartRegex_ = /^\r?\n\r?\n/;
|
|
444
|
+
function diff_cleanupSemanticLossless(diffs) {
|
|
445
|
+
function diff_cleanupSemanticScore_(one, two) {
|
|
446
|
+
if (!one || !two) {
|
|
447
|
+
return 6;
|
|
448
|
+
}
|
|
449
|
+
var char1 = one.charAt(one.length - 1);
|
|
450
|
+
var char2 = two.charAt(0);
|
|
451
|
+
var nonAlphaNumeric1 = char1.match(nonAlphaNumericRegex_);
|
|
452
|
+
var nonAlphaNumeric2 = char2.match(nonAlphaNumericRegex_);
|
|
453
|
+
var whitespace1 = nonAlphaNumeric1 && char1.match(whitespaceRegex_);
|
|
454
|
+
var whitespace2 = nonAlphaNumeric2 && char2.match(whitespaceRegex_);
|
|
455
|
+
var lineBreak1 = whitespace1 && char1.match(linebreakRegex_);
|
|
456
|
+
var lineBreak2 = whitespace2 && char2.match(linebreakRegex_);
|
|
457
|
+
var blankLine1 = lineBreak1 && one.match(blanklineEndRegex_);
|
|
458
|
+
var blankLine2 = lineBreak2 && two.match(blanklineStartRegex_);
|
|
459
|
+
if (blankLine1 || blankLine2) {
|
|
460
|
+
return 5;
|
|
461
|
+
} else if (lineBreak1 || lineBreak2) {
|
|
462
|
+
return 4;
|
|
463
|
+
} else if (nonAlphaNumeric1 && !whitespace1 && whitespace2) {
|
|
464
|
+
return 3;
|
|
465
|
+
} else if (whitespace1 || whitespace2) {
|
|
466
|
+
return 2;
|
|
467
|
+
} else if (nonAlphaNumeric1 || nonAlphaNumeric2) {
|
|
468
|
+
return 1;
|
|
469
|
+
}
|
|
470
|
+
return 0;
|
|
471
|
+
}
|
|
472
|
+
var pointer = 1;
|
|
473
|
+
while (pointer < diffs.length - 1) {
|
|
474
|
+
if (diffs[pointer - 1][0] == DIFF_EQUAL && diffs[pointer + 1][0] == DIFF_EQUAL) {
|
|
475
|
+
var equality1 = diffs[pointer - 1][1];
|
|
476
|
+
var edit = diffs[pointer][1];
|
|
477
|
+
var equality2 = diffs[pointer + 1][1];
|
|
478
|
+
var commonOffset = diff_commonSuffix(equality1, edit);
|
|
479
|
+
if (commonOffset) {
|
|
480
|
+
var commonString = edit.substring(edit.length - commonOffset);
|
|
481
|
+
equality1 = equality1.substring(0, equality1.length - commonOffset);
|
|
482
|
+
edit = commonString + edit.substring(0, edit.length - commonOffset);
|
|
483
|
+
equality2 = commonString + equality2;
|
|
484
|
+
}
|
|
485
|
+
var bestEquality1 = equality1;
|
|
486
|
+
var bestEdit = edit;
|
|
487
|
+
var bestEquality2 = equality2;
|
|
488
|
+
var bestScore = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2);
|
|
489
|
+
while (edit.charAt(0) === equality2.charAt(0)) {
|
|
490
|
+
equality1 += edit.charAt(0);
|
|
491
|
+
edit = edit.substring(1) + equality2.charAt(0);
|
|
492
|
+
equality2 = equality2.substring(1);
|
|
493
|
+
var score = diff_cleanupSemanticScore_(equality1, edit) + diff_cleanupSemanticScore_(edit, equality2);
|
|
494
|
+
if (score >= bestScore) {
|
|
495
|
+
bestScore = score;
|
|
496
|
+
bestEquality1 = equality1;
|
|
497
|
+
bestEdit = edit;
|
|
498
|
+
bestEquality2 = equality2;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (diffs[pointer - 1][1] != bestEquality1) {
|
|
502
|
+
if (bestEquality1) {
|
|
503
|
+
diffs[pointer - 1][1] = bestEquality1;
|
|
504
|
+
} else {
|
|
505
|
+
diffs.splice(pointer - 1, 1);
|
|
506
|
+
pointer--;
|
|
507
|
+
}
|
|
508
|
+
diffs[pointer][1] = bestEdit;
|
|
509
|
+
if (bestEquality2) {
|
|
510
|
+
diffs[pointer + 1][1] = bestEquality2;
|
|
511
|
+
} else {
|
|
512
|
+
diffs.splice(pointer + 1, 1);
|
|
513
|
+
pointer--;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
pointer++;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function diff_cleanupMerge(diffs, fix_unicode) {
|
|
521
|
+
diffs.push([DIFF_EQUAL, ""]);
|
|
522
|
+
var pointer = 0;
|
|
523
|
+
var count_delete = 0;
|
|
524
|
+
var count_insert = 0;
|
|
525
|
+
var text_delete = "";
|
|
526
|
+
var text_insert = "";
|
|
527
|
+
var commonlength;
|
|
528
|
+
while (pointer < diffs.length) {
|
|
529
|
+
if (pointer < diffs.length - 1 && !diffs[pointer][1]) {
|
|
530
|
+
diffs.splice(pointer, 1);
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
switch (diffs[pointer][0]) {
|
|
534
|
+
case DIFF_INSERT:
|
|
535
|
+
count_insert++;
|
|
536
|
+
text_insert += diffs[pointer][1];
|
|
537
|
+
pointer++;
|
|
538
|
+
break;
|
|
539
|
+
case DIFF_DELETE:
|
|
540
|
+
count_delete++;
|
|
541
|
+
text_delete += diffs[pointer][1];
|
|
542
|
+
pointer++;
|
|
543
|
+
break;
|
|
544
|
+
case DIFF_EQUAL:
|
|
545
|
+
var previous_equality = pointer - count_insert - count_delete - 1;
|
|
546
|
+
if (fix_unicode) {
|
|
547
|
+
if (previous_equality >= 0 && ends_with_pair_start(diffs[previous_equality][1])) {
|
|
548
|
+
var stray = diffs[previous_equality][1].slice(-1);
|
|
549
|
+
diffs[previous_equality][1] = diffs[previous_equality][1].slice(0, -1);
|
|
550
|
+
text_delete = stray + text_delete;
|
|
551
|
+
text_insert = stray + text_insert;
|
|
552
|
+
if (!diffs[previous_equality][1]) {
|
|
553
|
+
diffs.splice(previous_equality, 1);
|
|
554
|
+
pointer--;
|
|
555
|
+
var k = previous_equality - 1;
|
|
556
|
+
if (diffs[k] && diffs[k][0] === DIFF_INSERT) {
|
|
557
|
+
count_insert++;
|
|
558
|
+
text_insert = diffs[k][1] + text_insert;
|
|
559
|
+
k--;
|
|
560
|
+
}
|
|
561
|
+
if (diffs[k] && diffs[k][0] === DIFF_DELETE) {
|
|
562
|
+
count_delete++;
|
|
563
|
+
text_delete = diffs[k][1] + text_delete;
|
|
564
|
+
k--;
|
|
565
|
+
}
|
|
566
|
+
previous_equality = k;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
if (starts_with_pair_end(diffs[pointer][1])) {
|
|
570
|
+
var stray = diffs[pointer][1].charAt(0);
|
|
571
|
+
diffs[pointer][1] = diffs[pointer][1].slice(1);
|
|
572
|
+
text_delete += stray;
|
|
573
|
+
text_insert += stray;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
if (pointer < diffs.length - 1 && !diffs[pointer][1]) {
|
|
577
|
+
diffs.splice(pointer, 1);
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
if (text_delete.length > 0 || text_insert.length > 0) {
|
|
581
|
+
if (text_delete.length > 0 && text_insert.length > 0) {
|
|
582
|
+
commonlength = diff_commonPrefix(text_insert, text_delete);
|
|
583
|
+
if (commonlength !== 0) {
|
|
584
|
+
if (previous_equality >= 0) {
|
|
585
|
+
diffs[previous_equality][1] += text_insert.substring(0, commonlength);
|
|
586
|
+
} else {
|
|
587
|
+
diffs.splice(0, 0, [
|
|
588
|
+
DIFF_EQUAL,
|
|
589
|
+
text_insert.substring(0, commonlength)
|
|
590
|
+
]);
|
|
591
|
+
pointer++;
|
|
592
|
+
}
|
|
593
|
+
text_insert = text_insert.substring(commonlength);
|
|
594
|
+
text_delete = text_delete.substring(commonlength);
|
|
595
|
+
}
|
|
596
|
+
commonlength = diff_commonSuffix(text_insert, text_delete);
|
|
597
|
+
if (commonlength !== 0) {
|
|
598
|
+
diffs[pointer][1] = text_insert.substring(text_insert.length - commonlength) + diffs[pointer][1];
|
|
599
|
+
text_insert = text_insert.substring(0, text_insert.length - commonlength);
|
|
600
|
+
text_delete = text_delete.substring(0, text_delete.length - commonlength);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
var n = count_insert + count_delete;
|
|
604
|
+
if (text_delete.length === 0 && text_insert.length === 0) {
|
|
605
|
+
diffs.splice(pointer - n, n);
|
|
606
|
+
pointer = pointer - n;
|
|
607
|
+
} else if (text_delete.length === 0) {
|
|
608
|
+
diffs.splice(pointer - n, n, [DIFF_INSERT, text_insert]);
|
|
609
|
+
pointer = pointer - n + 1;
|
|
610
|
+
} else if (text_insert.length === 0) {
|
|
611
|
+
diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete]);
|
|
612
|
+
pointer = pointer - n + 1;
|
|
613
|
+
} else {
|
|
614
|
+
diffs.splice(pointer - n, n, [DIFF_DELETE, text_delete], [DIFF_INSERT, text_insert]);
|
|
615
|
+
pointer = pointer - n + 2;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (pointer !== 0 && diffs[pointer - 1][0] === DIFF_EQUAL) {
|
|
619
|
+
diffs[pointer - 1][1] += diffs[pointer][1];
|
|
620
|
+
diffs.splice(pointer, 1);
|
|
621
|
+
} else {
|
|
622
|
+
pointer++;
|
|
623
|
+
}
|
|
624
|
+
count_insert = 0;
|
|
625
|
+
count_delete = 0;
|
|
626
|
+
text_delete = "";
|
|
627
|
+
text_insert = "";
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
if (diffs[diffs.length - 1][1] === "") {
|
|
632
|
+
diffs.pop();
|
|
633
|
+
}
|
|
634
|
+
var changes = false;
|
|
635
|
+
pointer = 1;
|
|
636
|
+
while (pointer < diffs.length - 1) {
|
|
637
|
+
if (diffs[pointer - 1][0] === DIFF_EQUAL && diffs[pointer + 1][0] === DIFF_EQUAL) {
|
|
638
|
+
if (diffs[pointer][1].substring(diffs[pointer][1].length - diffs[pointer - 1][1].length) === diffs[pointer - 1][1]) {
|
|
639
|
+
diffs[pointer][1] = diffs[pointer - 1][1] + diffs[pointer][1].substring(0, diffs[pointer][1].length - diffs[pointer - 1][1].length);
|
|
640
|
+
diffs[pointer + 1][1] = diffs[pointer - 1][1] + diffs[pointer + 1][1];
|
|
641
|
+
diffs.splice(pointer - 1, 1);
|
|
642
|
+
changes = true;
|
|
643
|
+
} else if (diffs[pointer][1].substring(0, diffs[pointer + 1][1].length) == diffs[pointer + 1][1]) {
|
|
644
|
+
diffs[pointer - 1][1] += diffs[pointer + 1][1];
|
|
645
|
+
diffs[pointer][1] = diffs[pointer][1].substring(diffs[pointer + 1][1].length) + diffs[pointer + 1][1];
|
|
646
|
+
diffs.splice(pointer + 1, 1);
|
|
647
|
+
changes = true;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
pointer++;
|
|
651
|
+
}
|
|
652
|
+
if (changes) {
|
|
653
|
+
diff_cleanupMerge(diffs, fix_unicode);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
function is_surrogate_pair_start(charCode) {
|
|
657
|
+
return charCode >= 55296 && charCode <= 56319;
|
|
658
|
+
}
|
|
659
|
+
function is_surrogate_pair_end(charCode) {
|
|
660
|
+
return charCode >= 56320 && charCode <= 57343;
|
|
661
|
+
}
|
|
662
|
+
function starts_with_pair_end(str) {
|
|
663
|
+
return is_surrogate_pair_end(str.charCodeAt(0));
|
|
664
|
+
}
|
|
665
|
+
function ends_with_pair_start(str) {
|
|
666
|
+
return is_surrogate_pair_start(str.charCodeAt(str.length - 1));
|
|
667
|
+
}
|
|
668
|
+
function remove_empty_tuples(tuples) {
|
|
669
|
+
var ret = [];
|
|
670
|
+
for (var i = 0;i < tuples.length; i++) {
|
|
671
|
+
if (tuples[i][1].length > 0) {
|
|
672
|
+
ret.push(tuples[i]);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
return ret;
|
|
676
|
+
}
|
|
677
|
+
function make_edit_splice(before, oldMiddle, newMiddle, after) {
|
|
678
|
+
if (ends_with_pair_start(before) || starts_with_pair_end(after)) {
|
|
679
|
+
return null;
|
|
680
|
+
}
|
|
681
|
+
return remove_empty_tuples([
|
|
682
|
+
[DIFF_EQUAL, before],
|
|
683
|
+
[DIFF_DELETE, oldMiddle],
|
|
684
|
+
[DIFF_INSERT, newMiddle],
|
|
685
|
+
[DIFF_EQUAL, after]
|
|
686
|
+
]);
|
|
687
|
+
}
|
|
688
|
+
function find_cursor_edit_diff(oldText, newText, cursor_pos) {
|
|
689
|
+
var oldRange = typeof cursor_pos === "number" ? { index: cursor_pos, length: 0 } : cursor_pos.oldRange;
|
|
690
|
+
var newRange = typeof cursor_pos === "number" ? null : cursor_pos.newRange;
|
|
691
|
+
var oldLength = oldText.length;
|
|
692
|
+
var newLength = newText.length;
|
|
693
|
+
if (oldRange.length === 0 && (newRange === null || newRange.length === 0)) {
|
|
694
|
+
var oldCursor = oldRange.index;
|
|
695
|
+
var oldBefore = oldText.slice(0, oldCursor);
|
|
696
|
+
var oldAfter = oldText.slice(oldCursor);
|
|
697
|
+
var maybeNewCursor = newRange ? newRange.index : null;
|
|
698
|
+
editBefore: {
|
|
699
|
+
var newCursor = oldCursor + newLength - oldLength;
|
|
700
|
+
if (maybeNewCursor !== null && maybeNewCursor !== newCursor) {
|
|
701
|
+
break editBefore;
|
|
702
|
+
}
|
|
703
|
+
if (newCursor < 0 || newCursor > newLength) {
|
|
704
|
+
break editBefore;
|
|
705
|
+
}
|
|
706
|
+
var newBefore = newText.slice(0, newCursor);
|
|
707
|
+
var newAfter = newText.slice(newCursor);
|
|
708
|
+
if (newAfter !== oldAfter) {
|
|
709
|
+
break editBefore;
|
|
710
|
+
}
|
|
711
|
+
var prefixLength = Math.min(oldCursor, newCursor);
|
|
712
|
+
var oldPrefix = oldBefore.slice(0, prefixLength);
|
|
713
|
+
var newPrefix = newBefore.slice(0, prefixLength);
|
|
714
|
+
if (oldPrefix !== newPrefix) {
|
|
715
|
+
break editBefore;
|
|
716
|
+
}
|
|
717
|
+
var oldMiddle = oldBefore.slice(prefixLength);
|
|
718
|
+
var newMiddle = newBefore.slice(prefixLength);
|
|
719
|
+
return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldAfter);
|
|
720
|
+
}
|
|
721
|
+
editAfter: {
|
|
722
|
+
if (maybeNewCursor !== null && maybeNewCursor !== oldCursor) {
|
|
723
|
+
break editAfter;
|
|
724
|
+
}
|
|
725
|
+
var cursor = oldCursor;
|
|
726
|
+
var newBefore = newText.slice(0, cursor);
|
|
727
|
+
var newAfter = newText.slice(cursor);
|
|
728
|
+
if (newBefore !== oldBefore) {
|
|
729
|
+
break editAfter;
|
|
730
|
+
}
|
|
731
|
+
var suffixLength = Math.min(oldLength - cursor, newLength - cursor);
|
|
732
|
+
var oldSuffix = oldAfter.slice(oldAfter.length - suffixLength);
|
|
733
|
+
var newSuffix = newAfter.slice(newAfter.length - suffixLength);
|
|
734
|
+
if (oldSuffix !== newSuffix) {
|
|
735
|
+
break editAfter;
|
|
736
|
+
}
|
|
737
|
+
var oldMiddle = oldAfter.slice(0, oldAfter.length - suffixLength);
|
|
738
|
+
var newMiddle = newAfter.slice(0, newAfter.length - suffixLength);
|
|
739
|
+
return make_edit_splice(oldBefore, oldMiddle, newMiddle, oldSuffix);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
if (oldRange.length > 0 && newRange && newRange.length === 0) {
|
|
743
|
+
replaceRange: {
|
|
744
|
+
var oldPrefix = oldText.slice(0, oldRange.index);
|
|
745
|
+
var oldSuffix = oldText.slice(oldRange.index + oldRange.length);
|
|
746
|
+
var prefixLength = oldPrefix.length;
|
|
747
|
+
var suffixLength = oldSuffix.length;
|
|
748
|
+
if (newLength < prefixLength + suffixLength) {
|
|
749
|
+
break replaceRange;
|
|
750
|
+
}
|
|
751
|
+
var newPrefix = newText.slice(0, prefixLength);
|
|
752
|
+
var newSuffix = newText.slice(newLength - suffixLength);
|
|
753
|
+
if (oldPrefix !== newPrefix || oldSuffix !== newSuffix) {
|
|
754
|
+
break replaceRange;
|
|
755
|
+
}
|
|
756
|
+
var oldMiddle = oldText.slice(prefixLength, oldLength - suffixLength);
|
|
757
|
+
var newMiddle = newText.slice(prefixLength, newLength - suffixLength);
|
|
758
|
+
return make_edit_splice(oldPrefix, oldMiddle, newMiddle, oldSuffix);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
function diff(text1, text2, cursor_pos, cleanup) {
|
|
764
|
+
return diff_main(text1, text2, cursor_pos, cleanup, true);
|
|
765
|
+
}
|
|
766
|
+
diff.INSERT = DIFF_INSERT;
|
|
767
|
+
diff.DELETE = DIFF_DELETE;
|
|
768
|
+
diff.EQUAL = DIFF_EQUAL;
|
|
769
|
+
module.exports = diff;
|
|
770
|
+
});
|
|
771
|
+
|
|
16
772
|
// src/testing/memory-repo-files.ts
|
|
17
773
|
var globMatcher = (pattern) => new RegExp(`^${pattern.replace(/\*\*\/|\*\*|\*|[.+^${}()|[\]\\]/g, (token) => {
|
|
18
774
|
if (token === "**/")
|
|
@@ -5885,10 +6641,16 @@ var ZodBase64 = /* @__PURE__ */ $constructor("ZodBase64", (inst, def) => {
|
|
|
5885
6641
|
$ZodBase64.init(inst, def);
|
|
5886
6642
|
ZodStringFormat.init(inst, def);
|
|
5887
6643
|
});
|
|
6644
|
+
function base642(params) {
|
|
6645
|
+
return _base64(ZodBase64, params);
|
|
6646
|
+
}
|
|
5888
6647
|
var ZodBase64URL = /* @__PURE__ */ $constructor("ZodBase64URL", (inst, def) => {
|
|
5889
6648
|
$ZodBase64URL.init(inst, def);
|
|
5890
6649
|
ZodStringFormat.init(inst, def);
|
|
5891
6650
|
});
|
|
6651
|
+
function base64url2(params) {
|
|
6652
|
+
return _base64url(ZodBase64URL, params);
|
|
6653
|
+
}
|
|
5892
6654
|
var ZodE164 = /* @__PURE__ */ $constructor("ZodE164", (inst, def) => {
|
|
5893
6655
|
$ZodE164.init(inst, def);
|
|
5894
6656
|
ZodStringFormat.init(inst, def);
|
|
@@ -6536,12 +7298,36 @@ function preprocess(fn, schema) {
|
|
|
6536
7298
|
out: schema
|
|
6537
7299
|
});
|
|
6538
7300
|
}
|
|
7301
|
+
// ../../node_modules/.bun/zod@4.5.4/node_modules/zod/v4/classic/iso.js
|
|
7302
|
+
var exports_iso = {};
|
|
7303
|
+
__export(exports_iso, {
|
|
7304
|
+
ZodISODate: () => ZodISODate,
|
|
7305
|
+
ZodISODateTime: () => ZodISODateTime,
|
|
7306
|
+
ZodISODuration: () => ZodISODuration,
|
|
7307
|
+
ZodISOTime: () => ZodISOTime,
|
|
7308
|
+
date: () => date2,
|
|
7309
|
+
datetime: () => datetime2,
|
|
7310
|
+
duration: () => duration2,
|
|
7311
|
+
time: () => time2
|
|
7312
|
+
});
|
|
7313
|
+
function datetime2(params) {
|
|
7314
|
+
return _isoDateTime(ZodISODateTime, params);
|
|
7315
|
+
}
|
|
7316
|
+
function date2(params) {
|
|
7317
|
+
return _isoDate(ZodISODate, params);
|
|
7318
|
+
}
|
|
7319
|
+
function time2(params) {
|
|
7320
|
+
return _isoTime(ZodISOTime, params);
|
|
7321
|
+
}
|
|
7322
|
+
function duration2(params) {
|
|
7323
|
+
return _isoDuration(ZodISODuration, params);
|
|
7324
|
+
}
|
|
6539
7325
|
// ../../node_modules/.bun/zod@4.5.4/node_modules/zod/v4/classic/coerce.js
|
|
6540
7326
|
var exports_coerce = {};
|
|
6541
7327
|
__export(exports_coerce, {
|
|
6542
7328
|
bigint: () => bigint2,
|
|
6543
7329
|
boolean: () => boolean3,
|
|
6544
|
-
date: () =>
|
|
7330
|
+
date: () => date3,
|
|
6545
7331
|
number: () => number3,
|
|
6546
7332
|
string: () => string3
|
|
6547
7333
|
});
|
|
@@ -6557,7 +7343,7 @@ function boolean3(params) {
|
|
|
6557
7343
|
function bigint2(params) {
|
|
6558
7344
|
return _coercedBigint(ZodBigInt, params);
|
|
6559
7345
|
}
|
|
6560
|
-
function
|
|
7346
|
+
function date3(params) {
|
|
6561
7347
|
return _coercedDate(ZodDate, params);
|
|
6562
7348
|
}
|
|
6563
7349
|
// ../pstdio-api-contracts/src/activity.ts
|
|
@@ -6666,30 +7452,6 @@ var harnessLocalId = (id) => id.slice(id.lastIndexOf(".") + 1);
|
|
|
6666
7452
|
var agentDetailsSchema = agentInfoSchema.extend({
|
|
6667
7453
|
skills: agentSkillsLayoutSchema.extend({ globalDir: string2() }).optional()
|
|
6668
7454
|
});
|
|
6669
|
-
// ../pstdio-sync-contracts/src/compatibility.ts
|
|
6670
|
-
var peerSchema = strictObject({
|
|
6671
|
-
release: string2().min(1),
|
|
6672
|
-
protocolVersions: array(number2().int().positive()).min(1),
|
|
6673
|
-
supportedFeatures: array(string2().min(1)),
|
|
6674
|
-
requiredFeatures: array(string2().min(1))
|
|
6675
|
-
});
|
|
6676
|
-
var protocolPeer = {
|
|
6677
|
-
release: "contracts-v1",
|
|
6678
|
-
protocolVersions: [1],
|
|
6679
|
-
supportedFeatures: ["atomic-groups", "retained-recovery", "revisioned-resolution"],
|
|
6680
|
-
requiredFeatures: ["atomic-groups", "retained-recovery", "revisioned-resolution"]
|
|
6681
|
-
};
|
|
6682
|
-
function negotiate(client, relay) {
|
|
6683
|
-
const common = client.protocolVersions.includes(1) && relay.protocolVersions.includes(1);
|
|
6684
|
-
const features = client.requiredFeatures.every((feature) => relay.supportedFeatures.includes(feature)) && relay.requiredFeatures.every((feature) => client.supportedFeatures.includes(feature));
|
|
6685
|
-
if (common && features)
|
|
6686
|
-
return { status: "compatible", protocolVersion: 1 };
|
|
6687
|
-
return {
|
|
6688
|
-
status: "unsupported-protocol",
|
|
6689
|
-
recoverable: true,
|
|
6690
|
-
action: "Update the local runtime or relay to a common protocol and required feature set. Local work remains saved; retry after updating."
|
|
6691
|
-
};
|
|
6692
|
-
}
|
|
6693
7455
|
// ../pstdio-sync-contracts/src/json.ts
|
|
6694
7456
|
function isJson(value) {
|
|
6695
7457
|
try {
|
|
@@ -6825,24 +7587,258 @@ async function fingerprint(value) {
|
|
|
6825
7587
|
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
6826
7588
|
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
6827
7589
|
}
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
7590
|
+
|
|
7591
|
+
// ../pstdio-sync-contracts/src/checkpoint.ts
|
|
7592
|
+
var writerPositionSchema = strictObject({
|
|
7593
|
+
environmentId: identitySchema,
|
|
7594
|
+
sequence: number2().int().positive()
|
|
7595
|
+
});
|
|
7596
|
+
var checkpointBodySchema = strictObject({
|
|
7597
|
+
protocolVersion: literal(2),
|
|
7598
|
+
scope: scopeSchema,
|
|
7599
|
+
epoch: identitySchema,
|
|
7600
|
+
generation: revisionSchema,
|
|
7601
|
+
environmentId: identitySchema,
|
|
7602
|
+
sequence: number2().int().positive(),
|
|
7603
|
+
parents: array(identitySchema),
|
|
7604
|
+
document: strictObject({ recordId: identitySchema, generation: revisionSchema, recoveryRevision: revisionSchema }),
|
|
7605
|
+
changes: array(changeSchema).min(1),
|
|
7606
|
+
resolution: resolutionSchema.optional(),
|
|
7607
|
+
rebase: strictObject({
|
|
7608
|
+
expectedSnapshotHash: fingerprintSchema,
|
|
7609
|
+
sources: array(strictObject({ operationId: identitySchema, fingerprint: fingerprintSchema })).min(1)
|
|
7610
|
+
}).optional()
|
|
7611
|
+
});
|
|
7612
|
+
var checkpointGroupSchema = checkpointBodySchema.extend({ fingerprint: fingerprintSchema }).superRefine((group, ctx) => {
|
|
7613
|
+
checkGroup({ ...group, operationId: `${group.environmentId}:${group.sequence}` }, ctx);
|
|
7614
|
+
const sources = group.rebase?.sources.map((source) => source.operationId) ?? [];
|
|
7615
|
+
if (new Set(sources).size !== sources.length || sources.some((id) => !group.parents.includes(id)))
|
|
7616
|
+
ctx.addIssue({ code: "custom", message: "Rebased sources must be unique captured parents" });
|
|
7617
|
+
if (new Set(group.parents).size !== group.parents.length || group.parents.includes(`${group.environmentId}:${group.sequence}`))
|
|
7618
|
+
ctx.addIssue({ code: "custom", message: "Checkpoint parents must be unique and cannot include itself" });
|
|
7619
|
+
if (new Set(group.changes.map((change) => change.recordId)).size !== group.changes.length || !group.changes.some((change) => change.recordId === group.document.recordId && change.shared?.kind === "text"))
|
|
7620
|
+
ctx.addIssue({ code: "custom", message: "Checkpoint needs a document delta and unique projection records" });
|
|
7621
|
+
});
|
|
7622
|
+
var coverageAckSchema = strictObject({
|
|
7623
|
+
protocolVersion: literal(2),
|
|
7624
|
+
scope: scopeSchema,
|
|
7625
|
+
epoch: identitySchema,
|
|
7626
|
+
generation: revisionSchema,
|
|
7627
|
+
environmentId: identitySchema,
|
|
7628
|
+
cut: revisionSchema,
|
|
7629
|
+
snapshotHash: fingerprintSchema,
|
|
7630
|
+
branches: array(identitySchema),
|
|
7631
|
+
recovery: array(strictObject({
|
|
7632
|
+
recordId: identitySchema,
|
|
7633
|
+
generation: revisionSchema,
|
|
7634
|
+
revision: revisionSchema,
|
|
7635
|
+
checkpointRevision: revisionSchema,
|
|
7636
|
+
baseCut: revisionSchema,
|
|
7637
|
+
branches: array(identitySchema)
|
|
7638
|
+
}).refine((recovery) => recovery.checkpointRevision <= recovery.revision, "Recovery checkpoint is in the future"))
|
|
7639
|
+
});
|
|
7640
|
+
var writerFrontierSchema = strictObject({ floor: revisionSchema });
|
|
7641
|
+
var recoveryFileSchema = strictObject({
|
|
7642
|
+
protocolVersion: literal(2),
|
|
7643
|
+
scope: scopeSchema,
|
|
7644
|
+
recordId: identitySchema,
|
|
7645
|
+
epoch: identitySchema,
|
|
7646
|
+
generation: revisionSchema,
|
|
7647
|
+
revision: revisionSchema,
|
|
7648
|
+
checkpointRevision: revisionSchema,
|
|
7649
|
+
state: string2(),
|
|
7650
|
+
checkpointVector: string2(),
|
|
7651
|
+
projectionBaseline: string2(),
|
|
7652
|
+
frozen: strictObject({
|
|
7653
|
+
identity: identitySchema,
|
|
7654
|
+
revision: revisionSchema,
|
|
7655
|
+
update: string2(),
|
|
7656
|
+
vector: string2(),
|
|
7657
|
+
group: checkpointGroupSchema.nullable(),
|
|
7658
|
+
projectionBaseline: string2()
|
|
7659
|
+
}).nullable()
|
|
7660
|
+
});
|
|
7661
|
+
var liveFrameSchema = strictObject({
|
|
7662
|
+
protocolVersion: literal(2),
|
|
7663
|
+
scope: scopeSchema,
|
|
7664
|
+
epoch: identitySchema,
|
|
7665
|
+
documentId: identitySchema,
|
|
7666
|
+
generation: revisionSchema,
|
|
7667
|
+
kind: _enum(["update", "state-vector", "barrier"]),
|
|
7668
|
+
payload: string2()
|
|
7669
|
+
});
|
|
7670
|
+
var backupCoverageSchema = strictObject({
|
|
7671
|
+
scope: scopeSchema,
|
|
7672
|
+
epoch: identitySchema,
|
|
7673
|
+
generation: revisionSchema,
|
|
7674
|
+
cut: revisionSchema,
|
|
7675
|
+
snapshotHash: fingerprintSchema,
|
|
7676
|
+
manifestHash: fingerprintSchema
|
|
7677
|
+
});
|
|
7678
|
+
var documentRotationSchema = strictObject({
|
|
7679
|
+
scope: scopeSchema,
|
|
7680
|
+
epoch: identitySchema,
|
|
7681
|
+
documentId: identitySchema,
|
|
7682
|
+
previousGeneration: revisionSchema,
|
|
7683
|
+
generation: revisionSchema,
|
|
7684
|
+
seed: string2()
|
|
7685
|
+
}).refine((rotation) => rotation.generation === rotation.previousGeneration + 1, "Document generation must advance once");
|
|
7686
|
+
var documentPositionSchema = strictObject({
|
|
7687
|
+
scope: scopeSchema,
|
|
7688
|
+
epoch: identitySchema,
|
|
7689
|
+
documentId: identitySchema,
|
|
7690
|
+
generation: revisionSchema,
|
|
7691
|
+
position: string2()
|
|
7692
|
+
});
|
|
7693
|
+
// ../pstdio-sync-contracts/src/compatibility.ts
|
|
7694
|
+
var peerSchema = strictObject({
|
|
7695
|
+
release: string2().min(1),
|
|
7696
|
+
protocolVersions: array(number2().int().positive()).min(1),
|
|
7697
|
+
supportedFeatures: array(string2().min(1)),
|
|
7698
|
+
requiredFeatures: array(string2().min(1))
|
|
7699
|
+
});
|
|
6840
7700
|
// ../pstdio-sync-contracts/src/identity.ts
|
|
6841
7701
|
var environmentIdentitySchema = strictObject({ environmentId: identitySchema });
|
|
6842
7702
|
var environmentTargetSchema = environmentIdentitySchema.extend({
|
|
6843
7703
|
workbenchId: identitySchema,
|
|
6844
7704
|
workspaceId: identitySchema
|
|
6845
7705
|
});
|
|
7706
|
+
// ../pstdio-sync-contracts/src/protocol/envelopes.ts
|
|
7707
|
+
var syncIdSchema = string2().regex(/^[A-Za-z0-9_-]{16,128}$/);
|
|
7708
|
+
var sequenceSchema = number2().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
7709
|
+
var byteLengthSchema = sequenceSchema;
|
|
7710
|
+
var payloadSchema = base642();
|
|
7711
|
+
var blobIdsSchema = array(syncIdSchema).max(1e5).refine((ids) => new Set(ids).size === ids.length, "Blob IDs must be unique");
|
|
7712
|
+
var spaceOwnerSchema = identitySchema.nullable();
|
|
7713
|
+
var updateEnvelopeSchema = strictObject({
|
|
7714
|
+
updateId: syncIdSchema,
|
|
7715
|
+
payload: payloadSchema,
|
|
7716
|
+
blobIds: blobIdsSchema
|
|
7717
|
+
});
|
|
7718
|
+
var updateResultSchema = strictObject({ sequence: sequenceSchema.min(1), duplicate: boolean2() });
|
|
7719
|
+
var stateEnvelopeSchema = strictObject({
|
|
7720
|
+
stateId: syncIdSchema,
|
|
7721
|
+
baseStateId: syncIdSchema.nullable(),
|
|
7722
|
+
through: sequenceSchema,
|
|
7723
|
+
payload: payloadSchema,
|
|
7724
|
+
summary: payloadSchema,
|
|
7725
|
+
blobIds: blobIdsSchema
|
|
7726
|
+
});
|
|
7727
|
+
var stateInfoSchema = strictObject({
|
|
7728
|
+
stateId: syncIdSchema,
|
|
7729
|
+
baseStateId: syncIdSchema.nullable(),
|
|
7730
|
+
through: sequenceSchema,
|
|
7731
|
+
byteLength: byteLengthSchema,
|
|
7732
|
+
summary: payloadSchema,
|
|
7733
|
+
deviceId: identitySchema,
|
|
7734
|
+
createdAt: exports_iso.datetime()
|
|
7735
|
+
});
|
|
7736
|
+
var stateResultSchema = strictObject({ state: stateInfoSchema });
|
|
7737
|
+
var storedUpdateSchema = strictObject({
|
|
7738
|
+
sequence: sequenceSchema.min(1),
|
|
7739
|
+
updateId: syncIdSchema,
|
|
7740
|
+
deviceId: identitySchema,
|
|
7741
|
+
payload: payloadSchema,
|
|
7742
|
+
createdAt: exports_iso.datetime()
|
|
7743
|
+
});
|
|
7744
|
+
var readRequestSchema = strictObject({ after: sequenceSchema });
|
|
7745
|
+
var readResultSchema = discriminatedUnion("status", [
|
|
7746
|
+
strictObject({
|
|
7747
|
+
status: literal("updates"),
|
|
7748
|
+
state: stateInfoSchema.nullable(),
|
|
7749
|
+
lastSequence: sequenceSchema,
|
|
7750
|
+
updates: array(storedUpdateSchema),
|
|
7751
|
+
more: boolean2()
|
|
7752
|
+
}),
|
|
7753
|
+
strictObject({
|
|
7754
|
+
status: literal("state-required"),
|
|
7755
|
+
state: stateInfoSchema.nullable(),
|
|
7756
|
+
lastSequence: sequenceSchema
|
|
7757
|
+
})
|
|
7758
|
+
]);
|
|
7759
|
+
var blobBeginSchema = strictObject({ sha256: fingerprintSchema, byteLength: byteLengthSchema });
|
|
7760
|
+
var blobStatusSchema = strictObject({
|
|
7761
|
+
partSize: number2().int().positive(),
|
|
7762
|
+
completed: boolean2(),
|
|
7763
|
+
parts: array(strictObject({ number: number2().int().positive(), sha256: fingerprintSchema, byteLength: byteLengthSchema }))
|
|
7764
|
+
});
|
|
7765
|
+
var blobReadSchema = strictObject({ offset: byteLengthSchema });
|
|
7766
|
+
var liveClientMessageSchema = strictObject({
|
|
7767
|
+
type: literal("live"),
|
|
7768
|
+
spaceOwner: spaceOwnerSchema,
|
|
7769
|
+
payload: payloadSchema
|
|
7770
|
+
});
|
|
7771
|
+
var liveServerMessageSchema = discriminatedUnion("type", [
|
|
7772
|
+
strictObject({ type: literal("ready"), protocolVersion: number2().int().positive() }),
|
|
7773
|
+
strictObject({
|
|
7774
|
+
type: literal("live"),
|
|
7775
|
+
spaceOwner: spaceOwnerSchema,
|
|
7776
|
+
deviceId: identitySchema,
|
|
7777
|
+
payload: payloadSchema
|
|
7778
|
+
}),
|
|
7779
|
+
strictObject({
|
|
7780
|
+
type: literal("changed"),
|
|
7781
|
+
spaceOwner: spaceOwnerSchema,
|
|
7782
|
+
documentId: syncIdSchema,
|
|
7783
|
+
lastSequence: sequenceSchema,
|
|
7784
|
+
stateId: syncIdSchema.nullable()
|
|
7785
|
+
})
|
|
7786
|
+
]);
|
|
7787
|
+
var syncErrorSchema = discriminatedUnion("error", [
|
|
7788
|
+
strictObject({
|
|
7789
|
+
error: literal("protocol-unsupported"),
|
|
7790
|
+
supported: array(number2().int()),
|
|
7791
|
+
message: string2()
|
|
7792
|
+
}),
|
|
7793
|
+
strictObject({ error: literal("stale-state"), state: stateInfoSchema.nullable() }),
|
|
7794
|
+
strictObject({ error: literal("missing-blobs"), blobIds: array(syncIdSchema) }),
|
|
7795
|
+
strictObject({
|
|
7796
|
+
error: _enum([
|
|
7797
|
+
"invalid-request",
|
|
7798
|
+
"unauthorized",
|
|
7799
|
+
"forbidden",
|
|
7800
|
+
"not-found",
|
|
7801
|
+
"method-not-allowed",
|
|
7802
|
+
"too-large",
|
|
7803
|
+
"quota-exceeded",
|
|
7804
|
+
"rate-limited",
|
|
7805
|
+
"unavailable"
|
|
7806
|
+
])
|
|
7807
|
+
})
|
|
7808
|
+
]);
|
|
7809
|
+
// ../pstdio-sync-contracts/src/protocol/keys.ts
|
|
7810
|
+
var spaceKeySchema = strictObject({
|
|
7811
|
+
generation: number2().int().positive(),
|
|
7812
|
+
secret: base64url2().length(43)
|
|
7813
|
+
});
|
|
7814
|
+
var spaceKeysSchema = strictObject({
|
|
7815
|
+
project: array(spaceKeySchema).min(1),
|
|
7816
|
+
personal: array(spaceKeySchema).min(1)
|
|
7817
|
+
});
|
|
7818
|
+
// ../pstdio-sync-contracts/src/protocol/routes.ts
|
|
7819
|
+
var space = { projectId: identitySchema, spaceOwner: identitySchema.nullable() };
|
|
7820
|
+
var routeSchema = discriminatedUnion("kind", [
|
|
7821
|
+
strictObject({
|
|
7822
|
+
kind: literal("document"),
|
|
7823
|
+
...space,
|
|
7824
|
+
documentId: syncIdSchema,
|
|
7825
|
+
operation: _enum(["updates", "read", "state"])
|
|
7826
|
+
}),
|
|
7827
|
+
strictObject({ kind: literal("state"), ...space, documentId: syncIdSchema, stateId: syncIdSchema }),
|
|
7828
|
+
strictObject({
|
|
7829
|
+
kind: literal("blob"),
|
|
7830
|
+
...space,
|
|
7831
|
+
blobId: syncIdSchema,
|
|
7832
|
+
operation: _enum(["begin", "finish", "read"])
|
|
7833
|
+
}),
|
|
7834
|
+
strictObject({
|
|
7835
|
+
kind: literal("part"),
|
|
7836
|
+
...space,
|
|
7837
|
+
blobId: syncIdSchema,
|
|
7838
|
+
number: number2().int().min(1).max(1e4)
|
|
7839
|
+
}),
|
|
7840
|
+
strictObject({ kind: literal("live"), projectId: identitySchema })
|
|
7841
|
+
]);
|
|
6846
7842
|
// ../pstdio-sync-contracts/src/state.ts
|
|
6847
7843
|
var checkpointSchema = strictObject({ epoch: identitySchema, sequence: revisionSchema });
|
|
6848
7844
|
var recordSchema = strictObject({
|
|
@@ -6919,6 +7915,44 @@ var replaySchema = strictObject({
|
|
|
6919
7915
|
message: "Replay must contain contiguous complete accepted groups in one scope and epoch"
|
|
6920
7916
|
});
|
|
6921
7917
|
});
|
|
7918
|
+
// ../pstdio-sync-contracts/src/retention.ts
|
|
7919
|
+
var coveredReceiptSchema = strictObject({
|
|
7920
|
+
group: checkpointGroupSchema,
|
|
7921
|
+
status: _enum(["accepted", "pending", "conflict"]),
|
|
7922
|
+
cut: revisionSchema.nullable()
|
|
7923
|
+
}).refine((receipt) => receipt.status === "accepted" === (receipt.cut !== null), "Only accepted receipts have a cut");
|
|
7924
|
+
var coveredSnapshotSchema = strictObject({
|
|
7925
|
+
protocolVersion: literal(2),
|
|
7926
|
+
scope: scopeSchema,
|
|
7927
|
+
epoch: identitySchema,
|
|
7928
|
+
generation: revisionSchema,
|
|
7929
|
+
cut: revisionSchema,
|
|
7930
|
+
covered: revisionSchema,
|
|
7931
|
+
records: dictionarySchema(recordSchema),
|
|
7932
|
+
conflicts: dictionarySchema(conflictSchema),
|
|
7933
|
+
publishedRevision: identitySchema,
|
|
7934
|
+
documents: dictionarySchema(revisionSchema),
|
|
7935
|
+
receipts: dictionarySchema(coveredReceiptSchema),
|
|
7936
|
+
writers: dictionarySchema(writerFrontierSchema),
|
|
7937
|
+
retainedBranches: array(identitySchema)
|
|
7938
|
+
});
|
|
7939
|
+
var recoveryCoverageSchema = strictObject({
|
|
7940
|
+
recordId: identitySchema,
|
|
7941
|
+
generation: revisionSchema,
|
|
7942
|
+
revision: revisionSchema,
|
|
7943
|
+
checkpointRevision: revisionSchema,
|
|
7944
|
+
baseCut: revisionSchema,
|
|
7945
|
+
branches: array(identitySchema)
|
|
7946
|
+
}).refine((recovery) => recovery.checkpointRevision <= recovery.revision, "Checkpoint cannot cover future recovery edits");
|
|
7947
|
+
var backupManifestSchema = strictObject({
|
|
7948
|
+
protocolVersion: literal(2),
|
|
7949
|
+
snapshot: coveredSnapshotSchema,
|
|
7950
|
+
assets: array(assetSchema),
|
|
7951
|
+
packages: array(assetSchema),
|
|
7952
|
+
copiesScope: scopeSchema,
|
|
7953
|
+
snapshotHash: fingerprintSchema,
|
|
7954
|
+
coverage: array(coverageAckSchema)
|
|
7955
|
+
});
|
|
6922
7956
|
// ../pstdio-sync-contracts/src/transport.ts
|
|
6923
7957
|
var relayOperationSchema = _enum([
|
|
6924
7958
|
"initialize",
|
|
@@ -6939,21 +7973,21 @@ var relayReplayResultSchema = discriminatedUnion("status", [
|
|
|
6939
7973
|
strictObject({ status: literal("replay"), batch: replaySchema }),
|
|
6940
7974
|
strictObject({ status: literal("snapshot-required"), checkpoint: checkpointSchema })
|
|
6941
7975
|
]);
|
|
6942
|
-
var
|
|
7976
|
+
var byteLengthSchema2 = number2().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
6943
7977
|
var relayAssetBeginSchema = strictObject({ uploadId: identitySchema, asset: assetSchema });
|
|
6944
7978
|
var relayAssetUploadSchema = strictObject({ uploadId: identitySchema });
|
|
6945
7979
|
var relayAssetPartSchema = strictObject({
|
|
6946
7980
|
uploadId: identitySchema,
|
|
6947
7981
|
number: number2().int().min(1).max(1e4),
|
|
6948
7982
|
sha256: fingerprintSchema,
|
|
6949
|
-
byteLength:
|
|
7983
|
+
byteLength: byteLengthSchema2
|
|
6950
7984
|
});
|
|
6951
|
-
var relayAssetReadSchema = strictObject({ asset: assetSchema, offset:
|
|
7985
|
+
var relayAssetReadSchema = strictObject({ asset: assetSchema, offset: byteLengthSchema2 }).refine(({ asset, offset }) => offset <= asset.byteLength, "Offset exceeds the asset");
|
|
6952
7986
|
var relayAssetStatusSchema = strictObject({
|
|
6953
7987
|
asset: assetSchema,
|
|
6954
7988
|
partSize: number2().int().positive(),
|
|
6955
7989
|
completed: boolean2(),
|
|
6956
|
-
parts: array(strictObject({ number: number2().int().positive(), sha256: fingerprintSchema, byteLength:
|
|
7990
|
+
parts: array(strictObject({ number: number2().int().positive(), sha256: fingerprintSchema, byteLength: byteLengthSchema2 }))
|
|
6957
7991
|
});
|
|
6958
7992
|
var relayEventSchema = strictObject({ protocolVersion: literal(1), type: _enum(["ready", "changed"]) });
|
|
6959
7993
|
var relayInitializeSchema = strictObject({ publishedRevision: identitySchema });
|
|
@@ -7791,6 +8825,14 @@ var extensionRendererRecordBaseSchema = object({
|
|
|
7791
8825
|
emptyDescription: localizableStringSchema.optional()
|
|
7792
8826
|
});
|
|
7793
8827
|
var extensionTreeRendererRecordSchema = extensionRendererRecordBaseSchema.extend({
|
|
8828
|
+
structure: array(object({
|
|
8829
|
+
id: string2(),
|
|
8830
|
+
label: localizableStringSchema.optional(),
|
|
8831
|
+
collapsible: boolean2().optional(),
|
|
8832
|
+
hiddenByDefault: boolean2().optional(),
|
|
8833
|
+
canHide: boolean2().optional(),
|
|
8834
|
+
resourceNode: object({ id: string2(), icon: string2().optional() }).optional()
|
|
8835
|
+
})).optional(),
|
|
7794
8836
|
searchable: boolean2().optional(),
|
|
7795
8837
|
searchPlaceholder: localizableStringSchema.optional(),
|
|
7796
8838
|
headerHandlerId: string2().optional(),
|
|
@@ -8148,6 +9190,11 @@ var regionSizeSchema = object({
|
|
|
8148
9190
|
});
|
|
8149
9191
|
var regionSettingsSchema = object({
|
|
8150
9192
|
showHeader: boolean2().optional(),
|
|
9193
|
+
canOpen: boolean2().optional(),
|
|
9194
|
+
canClose: boolean2().optional(),
|
|
9195
|
+
acceptsTabs: boolean2().optional(),
|
|
9196
|
+
resizable: boolean2().optional(),
|
|
9197
|
+
floatable: boolean2().optional(),
|
|
8151
9198
|
size: regionSizeSchema.optional(),
|
|
8152
9199
|
collapsible: boolean2().optional(),
|
|
8153
9200
|
alwaysShowTabs: boolean2().optional()
|
|
@@ -9569,13 +10616,15 @@ var serializeCommandError = (error) => {
|
|
|
9569
10616
|
return result;
|
|
9570
10617
|
};
|
|
9571
10618
|
// ../pstdio-api-contracts/src/extension-kernel/types/extension.ts
|
|
9572
|
-
var EXTENSION_API_VERSION = "0.2.
|
|
10619
|
+
var EXTENSION_API_VERSION = "0.2.1";
|
|
9573
10620
|
// ../pstdio-api-contracts/src/extension-kernel/types/webview-capabilities.ts
|
|
9574
10621
|
var WEBVIEW_HOST_CAPABILITY_VERSION = 1;
|
|
9575
10622
|
var WEBVIEW_DECLARABLE_CAPABILITIES = [
|
|
9576
10623
|
"clipboard.write",
|
|
9577
10624
|
"commands.execute",
|
|
9578
10625
|
"commands.stream",
|
|
10626
|
+
"harnesses.read",
|
|
10627
|
+
"resources.actions",
|
|
9579
10628
|
"navigation.open",
|
|
9580
10629
|
"page.params.update",
|
|
9581
10630
|
"placement.close",
|
|
@@ -9898,6 +10947,10 @@ var reconcileMessageHistory = (input, projection = {}) => {
|
|
|
9898
10947
|
throw error;
|
|
9899
10948
|
}
|
|
9900
10949
|
};
|
|
10950
|
+
// ../pstdio-api-contracts/src/link-icons.ts
|
|
10951
|
+
var linkIconSchema = object({
|
|
10952
|
+
data_url: string2()
|
|
10953
|
+
});
|
|
9901
10954
|
// ../pstdio-api-contracts/src/pagination.ts
|
|
9902
10955
|
var pageQuerySchema = object({ cursor: string2().optional(), limit: exports_coerce.number().optional() });
|
|
9903
10956
|
// ../pstdio-api-contracts/src/session-request-values.ts
|
|
@@ -10876,131 +11929,6 @@ var createMemoryAssets = () => {
|
|
|
10876
11929
|
return api;
|
|
10877
11930
|
};
|
|
10878
11931
|
|
|
10879
|
-
// ../pstdio-sync/src/encoding.ts
|
|
10880
|
-
var encodeBytes = (bytes) => btoa(Array.from(bytes, (byte) => String.fromCharCode(byte)).join(""));
|
|
10881
|
-
var decodeBytes = (encoded) => Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0));
|
|
10882
|
-
var encodeText = (text) => encodeBytes(new TextEncoder().encode(text));
|
|
10883
|
-
var decodeText = (encoded) => new TextDecoder().decode(decodeBytes(encoded));
|
|
10884
|
-
|
|
10885
|
-
// ../pstdio-sync/src/namespaces.ts
|
|
10886
|
-
var storageRecordId = (namespace, recordId) => JSON.stringify([...namespace, recordId]);
|
|
10887
|
-
var scopeRecordStorage = (records, namespace) => {
|
|
10888
|
-
return { id: (key) => storageRecordId(namespace, key), ...records };
|
|
10889
|
-
};
|
|
10890
|
-
var legacyNamespaceStorage = (records, namespace) => {
|
|
10891
|
-
const prefix = `${JSON.stringify(namespace).slice(0, -1)},`;
|
|
10892
|
-
const storedId = (id) => storageRecordId(namespace, id);
|
|
10893
|
-
return {
|
|
10894
|
-
read: (id) => records.read(storedId(id)),
|
|
10895
|
-
list: async () => (await records.list()).filter((record) => record.recordId.startsWith(prefix)).map((record) => ({ ...record, recordId: JSON.parse(record.recordId).at(-1) })),
|
|
10896
|
-
commit: (group) => records.commit({
|
|
10897
|
-
...group,
|
|
10898
|
-
edits: group.edits.map((edit) => ({ ...edit, recordId: storedId(edit.recordId) }))
|
|
10899
|
-
})
|
|
10900
|
-
};
|
|
10901
|
-
};
|
|
10902
|
-
|
|
10903
|
-
// ../pstdio-sync/src/graph.ts
|
|
10904
|
-
var orderOperations = (available, ids) => {
|
|
10905
|
-
const remaining = new Set(ids);
|
|
10906
|
-
const ordered = [];
|
|
10907
|
-
while (remaining.size) {
|
|
10908
|
-
const ready = [...remaining].filter((id) => available.get(id).parents.every((parent) => !remaining.has(parent)));
|
|
10909
|
-
if (!ready.length)
|
|
10910
|
-
throw new Error("Cyclic operation dependency");
|
|
10911
|
-
for (const id of ready) {
|
|
10912
|
-
ordered.push(available.get(id));
|
|
10913
|
-
remaining.delete(id);
|
|
10914
|
-
}
|
|
10915
|
-
}
|
|
10916
|
-
return ordered;
|
|
10917
|
-
};
|
|
10918
|
-
|
|
10919
|
-
// ../pstdio-sync/src/journal.ts
|
|
10920
|
-
var completedOperations = (snapshot) => {
|
|
10921
|
-
const completed = new Set;
|
|
10922
|
-
for (const receipt of Object.values(snapshot?.receipts ?? {})) {
|
|
10923
|
-
if (receipt.status !== "accepted")
|
|
10924
|
-
continue;
|
|
10925
|
-
completed.add(receipt.operationId);
|
|
10926
|
-
for (const captured of receipt.mutation.resolution?.capturedOperationIds ?? [])
|
|
10927
|
-
completed.add(captured);
|
|
10928
|
-
}
|
|
10929
|
-
return completed;
|
|
10930
|
-
};
|
|
10931
|
-
var retainAcceptance = (entry, receipt) => {
|
|
10932
|
-
if (receipt.recoveryProof)
|
|
10933
|
-
entry.recoveryProof = receipt.recoveryProof;
|
|
10934
|
-
if (receipt.status !== "accepted" || !receipt.checkpoint)
|
|
10935
|
-
return;
|
|
10936
|
-
const next = { fingerprint: receipt.fingerprint, order: receipt.order, checkpoint: receipt.checkpoint };
|
|
10937
|
-
const previous = entry.acceptance;
|
|
10938
|
-
if (previous?.fingerprint === next.fingerprint && previous.order === next.order && previous.checkpoint.epoch === next.checkpoint.epoch && previous.checkpoint.sequence === next.checkpoint.sequence)
|
|
10939
|
-
return;
|
|
10940
|
-
entry.acceptance = next;
|
|
10941
|
-
};
|
|
10942
|
-
var checkScope = (state, scope) => {
|
|
10943
|
-
if (scope.workbenchId !== state.owner.workbenchId || scope.extensionId !== state.owner.extensionId)
|
|
10944
|
-
throw new Error("Relay scope belongs to another storage owner");
|
|
10945
|
-
if (state.accepted && canonicalJson(state.accepted.scope) !== canonicalJson(scope))
|
|
10946
|
-
throw new Error("Storage is already bound to another account");
|
|
10947
|
-
};
|
|
10948
|
-
var sealOperation = async (state, operation) => {
|
|
10949
|
-
if (!state.accepted)
|
|
10950
|
-
throw new Error("Storage has not received a relay snapshot");
|
|
10951
|
-
return sealMutation({ ...operation, protocolVersion: 1, scope: state.accepted.scope });
|
|
10952
|
-
};
|
|
10953
|
-
var snapshotVersion = (snapshot) => snapshot && canonicalJson(snapshot);
|
|
10954
|
-
var receiveSnapshot = async (state, snapshot, observed) => {
|
|
10955
|
-
checkScope(state, snapshot.scope);
|
|
10956
|
-
if (snapshotVersion(state.accepted) !== snapshotVersion(observed))
|
|
10957
|
-
return;
|
|
10958
|
-
if (state.accepted?.checkpoint.epoch === snapshot.checkpoint.epoch && (snapshot.journalSequence < state.accepted.journalSequence || snapshot.checkpoint.sequence < state.accepted.checkpoint.sequence))
|
|
10959
|
-
return;
|
|
10960
|
-
for (const receipt of Object.values(snapshot.receipts)) {
|
|
10961
|
-
let entry = state.journal.find((entry) => entry.mutation.operationId === receipt.operationId);
|
|
10962
|
-
if (entry) {
|
|
10963
|
-
const sealed = await sealMutation({ ...entry.mutation, protocolVersion: 1, scope: snapshot.scope });
|
|
10964
|
-
if (sealed.fingerprint !== receipt.fingerprint)
|
|
10965
|
-
throw new Error("Received operation identity has changed content");
|
|
10966
|
-
} else {
|
|
10967
|
-
const { operationId, environmentId, parents, changes, resolution } = receipt.mutation;
|
|
10968
|
-
entry = {
|
|
10969
|
-
inputFingerprint: receipt.fingerprint,
|
|
10970
|
-
mutation: { operationId, environmentId, parents, changes, resolution }
|
|
10971
|
-
};
|
|
10972
|
-
state.journal.push(entry);
|
|
10973
|
-
}
|
|
10974
|
-
retainAcceptance(entry, receipt);
|
|
10975
|
-
}
|
|
10976
|
-
state.accepted = snapshot;
|
|
10977
|
-
};
|
|
10978
|
-
var pendingOperations = (state, environmentId) => {
|
|
10979
|
-
const completed = completedOperations(state.accepted);
|
|
10980
|
-
const entries = new Map(state.journal.map((entry) => [entry.mutation.operationId, entry]));
|
|
10981
|
-
const recovery = new Set;
|
|
10982
|
-
const visit = (id) => {
|
|
10983
|
-
if (completed.has(id) || recovery.has(id))
|
|
10984
|
-
return;
|
|
10985
|
-
const entry = entries.get(id);
|
|
10986
|
-
if (!entry)
|
|
10987
|
-
throw new Error("Journal dependency is unavailable");
|
|
10988
|
-
recovery.add(id);
|
|
10989
|
-
for (const parent of entry.mutation.parents)
|
|
10990
|
-
visit(parent);
|
|
10991
|
-
};
|
|
10992
|
-
for (const entry of state.journal)
|
|
10993
|
-
if (entry.acceptance && !completed.has(entry.mutation.operationId))
|
|
10994
|
-
visit(entry.mutation.operationId);
|
|
10995
|
-
const ordered = orderOperations(new Map([...entries].map(([id, entry]) => [id, entry.mutation])), recovery);
|
|
10996
|
-
for (const entry of state.journal) {
|
|
10997
|
-
const mutation = entry.mutation;
|
|
10998
|
-
if (mutation.environmentId === environmentId && !completed.has(mutation.operationId) && !recovery.has(mutation.operationId))
|
|
10999
|
-
ordered.push(mutation);
|
|
11000
|
-
}
|
|
11001
|
-
return ordered;
|
|
11002
|
-
};
|
|
11003
|
-
|
|
11004
11932
|
// ../../node_modules/.bun/lib0@0.2.117/node_modules/lib0/map.js
|
|
11005
11933
|
var create = () => new Map;
|
|
11006
11934
|
var copy = (m) => {
|
|
@@ -11719,13 +12647,13 @@ var equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false;
|
|
|
11719
12647
|
// ../../node_modules/.bun/lib0@0.2.117/node_modules/lib0/object.js
|
|
11720
12648
|
var isObject2 = (o) => typeof o === "object";
|
|
11721
12649
|
var assign = Object.assign;
|
|
11722
|
-
var
|
|
12650
|
+
var keys2 = Object.keys;
|
|
11723
12651
|
var forEach = (obj, f) => {
|
|
11724
12652
|
for (const key in obj) {
|
|
11725
12653
|
f(obj[key], key);
|
|
11726
12654
|
}
|
|
11727
12655
|
};
|
|
11728
|
-
var size = (obj) =>
|
|
12656
|
+
var size = (obj) => keys2(obj).length;
|
|
11729
12657
|
var isEmpty = (obj) => {
|
|
11730
12658
|
for (const _k in obj) {
|
|
11731
12659
|
return false;
|
|
@@ -13374,6 +14302,25 @@ var readStateVector = (decoder) => {
|
|
|
13374
14302
|
return ss;
|
|
13375
14303
|
};
|
|
13376
14304
|
var decodeStateVector = (decodedState) => readStateVector(new DSDecoderV1(createDecoder(decodedState)));
|
|
14305
|
+
var writeStateVector = (encoder, sv) => {
|
|
14306
|
+
writeVarUint(encoder.restEncoder, sv.size);
|
|
14307
|
+
from(sv.entries()).sort((a, b) => b[0] - a[0]).forEach(([client, clock]) => {
|
|
14308
|
+
writeVarUint(encoder.restEncoder, client);
|
|
14309
|
+
writeVarUint(encoder.restEncoder, clock);
|
|
14310
|
+
});
|
|
14311
|
+
return encoder;
|
|
14312
|
+
};
|
|
14313
|
+
var writeDocumentStateVector = (encoder, doc) => writeStateVector(encoder, getStateVector(doc.store));
|
|
14314
|
+
var encodeStateVectorV2 = (doc, encoder = new DSEncoderV2) => {
|
|
14315
|
+
if (doc instanceof Map) {
|
|
14316
|
+
writeStateVector(encoder, doc);
|
|
14317
|
+
} else {
|
|
14318
|
+
writeDocumentStateVector(encoder, doc);
|
|
14319
|
+
}
|
|
14320
|
+
return encoder.toUint8Array();
|
|
14321
|
+
};
|
|
14322
|
+
var encodeStateVector = (doc) => encodeStateVectorV2(doc, new DSEncoderV1);
|
|
14323
|
+
|
|
13377
14324
|
class EventHandler {
|
|
13378
14325
|
constructor() {
|
|
13379
14326
|
this.l = [];
|
|
@@ -13795,6 +14742,20 @@ class LazyStructReader {
|
|
|
13795
14742
|
return this.curr;
|
|
13796
14743
|
}
|
|
13797
14744
|
}
|
|
14745
|
+
var decodeUpdate = (update) => decodeUpdateV2(update, UpdateDecoderV1);
|
|
14746
|
+
var decodeUpdateV2 = (update, YDecoder = UpdateDecoderV2) => {
|
|
14747
|
+
const structs = [];
|
|
14748
|
+
const updateDecoder = new YDecoder(createDecoder(update));
|
|
14749
|
+
const lazyDecoder = new LazyStructReader(updateDecoder, false);
|
|
14750
|
+
for (let curr = lazyDecoder.curr;curr !== null; curr = lazyDecoder.next()) {
|
|
14751
|
+
structs.push(curr);
|
|
14752
|
+
}
|
|
14753
|
+
return {
|
|
14754
|
+
structs,
|
|
14755
|
+
ds: readDeleteSet(updateDecoder)
|
|
14756
|
+
};
|
|
14757
|
+
};
|
|
14758
|
+
|
|
13798
14759
|
class LazyStructWriter {
|
|
13799
14760
|
constructor(encoder) {
|
|
13800
14761
|
this.currClient = 0;
|
|
@@ -14232,6 +15193,16 @@ var updateMarkerChanges = (searchMarker, index, len) => {
|
|
|
14232
15193
|
}
|
|
14233
15194
|
}
|
|
14234
15195
|
};
|
|
15196
|
+
var getTypeChildren = (t) => {
|
|
15197
|
+
t.doc ?? warnPrematureAccess();
|
|
15198
|
+
let s = t._start;
|
|
15199
|
+
const arr = [];
|
|
15200
|
+
while (s) {
|
|
15201
|
+
arr.push(s);
|
|
15202
|
+
s = s.right;
|
|
15203
|
+
}
|
|
15204
|
+
return arr;
|
|
15205
|
+
};
|
|
14235
15206
|
var callTypeObservers = (type, transaction, event) => {
|
|
14236
15207
|
const changedType = type;
|
|
14237
15208
|
const changedParentTypes = transaction.changedParentTypes;
|
|
@@ -16823,813 +17794,507 @@ if (glo[importIdentifier] === true) {
|
|
|
16823
17794
|
}
|
|
16824
17795
|
glo[importIdentifier] = true;
|
|
16825
17796
|
|
|
16826
|
-
// ../pstdio-sync/src/
|
|
16827
|
-
var
|
|
16828
|
-
|
|
16829
|
-
|
|
16830
|
-
|
|
16831
|
-
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
|
|
16835
|
-
value: null,
|
|
16836
|
-
asset: null
|
|
17797
|
+
// ../pstdio-sync/src/document-types.ts
|
|
17798
|
+
var memoryDocumentState = (document2) => {
|
|
17799
|
+
const operations = new Map;
|
|
17800
|
+
return {
|
|
17801
|
+
document: document2,
|
|
17802
|
+
operation: async (id) => operations.get(id),
|
|
17803
|
+
remember: (id, fingerprint) => {
|
|
17804
|
+
operations.set(id, fingerprint);
|
|
17805
|
+
}
|
|
16837
17806
|
};
|
|
16838
|
-
return record;
|
|
16839
17807
|
};
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
if (record.primitive === "text")
|
|
16854
|
-
return { kind: "text", value: document2.getText("body").toString() };
|
|
16855
|
-
return { kind: "list", value: document2.getArray("items").toArray() };
|
|
16856
|
-
} finally {
|
|
16857
|
-
document2.destroy();
|
|
16858
|
-
}
|
|
16859
|
-
};
|
|
16860
|
-
var publicRecord = (record) => ({
|
|
16861
|
-
recordId: record.recordId,
|
|
16862
|
-
exists: record.revision > 0,
|
|
16863
|
-
value: structuredClone(record.value),
|
|
16864
|
-
asset: structuredClone(record.asset),
|
|
16865
|
-
deleted: record.deleted,
|
|
16866
|
-
shared: sharedValue(record)
|
|
16867
|
-
});
|
|
16868
|
-
var cellFingerprint = (map, key) => fingerprint({ exists: Object.hasOwn(map, key), value: Object.hasOwn(map, key) ? map[key] : null });
|
|
16869
|
-
var recordConflict = async (record, change) => {
|
|
16870
|
-
if (record.deleted !== change.baseDeleted)
|
|
16871
|
-
return "delete versus edit";
|
|
16872
|
-
if (change.deleted !== undefined && record.revision !== change.expectedRevision)
|
|
16873
|
-
return "delete versus edit";
|
|
16874
|
-
if (change.expectedRevision > record.revision)
|
|
16875
|
-
return "unknown base revision";
|
|
16876
|
-
if (change.asset && canonicalJson(record.asset) !== canonicalJson(change.asset.base) && canonicalJson(record.asset) !== canonicalJson(change.asset.next))
|
|
16877
|
-
return "competing asset replacements";
|
|
16878
|
-
if (change.value && await fingerprint(record.value) !== change.value.expected)
|
|
16879
|
-
return "competing JSON replacements";
|
|
16880
|
-
if (change.shared && record.primitive && change.shared.kind !== record.primitive)
|
|
16881
|
-
return "incompatible shared primitive";
|
|
16882
|
-
if (change.shared?.kind === "map") {
|
|
16883
|
-
for (const entry of change.shared.entries)
|
|
16884
|
-
if (await cellFingerprint(record.map, entry.key) !== entry.expected)
|
|
16885
|
-
return "competing map key edits";
|
|
16886
|
-
}
|
|
16887
|
-
};
|
|
16888
|
-
var applySequenceEdit = (document2, edit) => {
|
|
16889
|
-
if (edit.kind === "text.insert")
|
|
16890
|
-
document2.getText("body").insert(edit.index, edit.text);
|
|
16891
|
-
if (edit.kind === "text.delete")
|
|
16892
|
-
document2.getText("body").delete(edit.index, edit.count);
|
|
16893
|
-
if (edit.kind === "list.insert")
|
|
16894
|
-
document2.getArray("items").insert(edit.index, edit.values);
|
|
16895
|
-
if (edit.kind === "list.delete")
|
|
16896
|
-
document2.getArray("items").delete(edit.index, edit.count);
|
|
16897
|
-
};
|
|
16898
|
-
var sharedChange = async (record, edits) => {
|
|
16899
|
-
const document2 = openDocument(record);
|
|
16900
|
-
const entries = new Map;
|
|
16901
|
-
let kind;
|
|
16902
|
-
try {
|
|
16903
|
-
for (const edit of edits) {
|
|
16904
|
-
const nextKind = edit.kind.split(".")[0];
|
|
16905
|
-
if (kind && kind !== nextKind)
|
|
16906
|
-
throw new Error("One shared primitive per record");
|
|
16907
|
-
kind = nextKind;
|
|
16908
|
-
applySequenceEdit(document2, edit);
|
|
16909
|
-
if (edit.kind === "map.set" || edit.kind === "map.delete") {
|
|
16910
|
-
entries.set(edit.key, {
|
|
16911
|
-
key: edit.key,
|
|
16912
|
-
expected: await cellFingerprint(record.map, edit.key),
|
|
16913
|
-
next: edit.kind === "map.set" ? { kind: "set", value: edit.value } : { kind: "delete" }
|
|
16914
|
-
});
|
|
16915
|
-
}
|
|
17808
|
+
|
|
17809
|
+
// ../pstdio-sync/src/checkpoint-capture.ts
|
|
17810
|
+
async function captureCheckpoint(document2, owner, action, observer) {
|
|
17811
|
+
const fork = new Doc2;
|
|
17812
|
+
const baseline = encodeStateVector(document2);
|
|
17813
|
+
applyUpdate(fork, encodeStateAsUpdate(document2));
|
|
17814
|
+
const state = memoryDocumentState(fork);
|
|
17815
|
+
const store = {
|
|
17816
|
+
observer,
|
|
17817
|
+
transaction: async (target, run) => {
|
|
17818
|
+
if (target.workbenchId !== owner.workbenchId || target.extensionId !== owner.extensionId)
|
|
17819
|
+
throw new Error("A checkpoint cannot cross its storage owner");
|
|
17820
|
+
return run(state);
|
|
16916
17821
|
}
|
|
16917
|
-
|
|
16918
|
-
|
|
16919
|
-
|
|
16920
|
-
|
|
16921
|
-
return { kind, update: encodeBytes(encodeStateAsUpdate(document2)) };
|
|
17822
|
+
};
|
|
17823
|
+
try {
|
|
17824
|
+
const value = await action(store);
|
|
17825
|
+
return { value, update: encodeStateAsUpdate(fork, baseline) };
|
|
16922
17826
|
} finally {
|
|
16923
|
-
|
|
17827
|
+
fork.destroy();
|
|
16924
17828
|
}
|
|
17829
|
+
}
|
|
17830
|
+
// ../pstdio-sync/src/document-history.ts
|
|
17831
|
+
var ranges = (items) => {
|
|
17832
|
+
const merged = [];
|
|
17833
|
+
for (const item of items.sort(([a, b], [c, d]) => a - c || b - d)) {
|
|
17834
|
+
const previous = merged.at(-1);
|
|
17835
|
+
if (previous && previous[0] === item[0] && previous[1] + previous[2] === item[1] && previous[3] === item[3])
|
|
17836
|
+
previous[2] += item[2];
|
|
17837
|
+
else
|
|
17838
|
+
merged.push([...item]);
|
|
17839
|
+
}
|
|
17840
|
+
return JSON.stringify(merged);
|
|
16925
17841
|
};
|
|
16926
|
-
var
|
|
16927
|
-
const
|
|
16928
|
-
|
|
16929
|
-
|
|
16930
|
-
|
|
16931
|
-
|
|
16932
|
-
|
|
16933
|
-
|
|
17842
|
+
var documentHistory = (document2) => {
|
|
17843
|
+
const decoded = decodeUpdate(encodeStateAsUpdate(document2));
|
|
17844
|
+
const clients = new Map;
|
|
17845
|
+
for (const struct of decoded.structs) {
|
|
17846
|
+
const items = clients.get(struct.id.client) ?? [];
|
|
17847
|
+
items.push(struct);
|
|
17848
|
+
clients.set(struct.id.client, items);
|
|
17849
|
+
}
|
|
17850
|
+
const itemAt = (id) => {
|
|
17851
|
+
const items = clients.get(id.client) ?? [];
|
|
17852
|
+
let low = 0;
|
|
17853
|
+
let high = items.length;
|
|
17854
|
+
while (low < high) {
|
|
17855
|
+
const middle = low + high >>> 1;
|
|
17856
|
+
if (items[middle].id.clock + items[middle].length <= id.clock)
|
|
17857
|
+
low = middle + 1;
|
|
16934
17858
|
else
|
|
16935
|
-
|
|
17859
|
+
high = middle;
|
|
16936
17860
|
}
|
|
16937
|
-
|
|
16938
|
-
|
|
17861
|
+
return items[low];
|
|
17862
|
+
};
|
|
17863
|
+
const addresses = new Map;
|
|
17864
|
+
const address = (item) => {
|
|
17865
|
+
const chain = [];
|
|
17866
|
+
let current = item;
|
|
17867
|
+
let result;
|
|
17868
|
+
while (current) {
|
|
17869
|
+
if (addresses.has(current)) {
|
|
17870
|
+
result = addresses.get(current);
|
|
17871
|
+
break;
|
|
17872
|
+
}
|
|
17873
|
+
chain.push(current);
|
|
17874
|
+
if (typeof current.parent === "string") {
|
|
17875
|
+
result = { parent: current.parent, key: current.parentSub };
|
|
17876
|
+
break;
|
|
17877
|
+
}
|
|
17878
|
+
const origin = current.origin ?? current.rightOrigin;
|
|
17879
|
+
const previous = origin && itemAt(origin);
|
|
17880
|
+
current = previous instanceof Item ? previous : undefined;
|
|
17881
|
+
}
|
|
17882
|
+
for (const entry of chain)
|
|
17883
|
+
addresses.set(entry, result);
|
|
17884
|
+
return result;
|
|
17885
|
+
};
|
|
17886
|
+
const fieldRanges = new Map;
|
|
17887
|
+
for (const item of decoded.structs) {
|
|
17888
|
+
if (!(item instanceof Item))
|
|
17889
|
+
continue;
|
|
17890
|
+
const field = address(item);
|
|
17891
|
+
if (!field || field.key === null)
|
|
17892
|
+
continue;
|
|
17893
|
+
const key = JSON.stringify([field.parent, field.key]);
|
|
17894
|
+
const entries = fieldRanges.get(key) ?? [];
|
|
17895
|
+
entries.push([item.id.client, item.id.clock, item.length, isDeleted(decoded.ds, item.id)]);
|
|
17896
|
+
fieldRanges.set(key, entries);
|
|
17897
|
+
}
|
|
17898
|
+
const fields = new Map([...fieldRanges].map(([key, entries]) => [key, ranges(entries)]));
|
|
17899
|
+
const sequences = new Map([...document2.share].map(([name, type]) => [
|
|
17900
|
+
name,
|
|
17901
|
+
ranges(getTypeChildren(type).map((item) => [item.id.client, item.id.clock, item.length, item.deleted]))
|
|
17902
|
+
]));
|
|
17903
|
+
return { fields, sequences };
|
|
17904
|
+
};
|
|
17905
|
+
// ../pstdio-sync/src/document-author.ts
|
|
17906
|
+
var documentAuthorId = (key) => {
|
|
17907
|
+
let first = 2166136261;
|
|
17908
|
+
let second = 3339675911;
|
|
17909
|
+
for (let index = 0;index < key.length; index++) {
|
|
17910
|
+
first = Math.imul(first ^ key.charCodeAt(index), 16777619) >>> 0;
|
|
17911
|
+
second = Math.imul(second ^ key.charCodeAt(index), 2246822519) >>> 0;
|
|
17912
|
+
}
|
|
17913
|
+
return 2 ** 48 + first * 65536 + (second >>> 16);
|
|
17914
|
+
};
|
|
17915
|
+
var migrationAuthor = (document2, seed, history) => {
|
|
17916
|
+
if (!seed)
|
|
17917
|
+
return;
|
|
17918
|
+
const author = (parent, key, value, action) => {
|
|
17919
|
+
const current = document2.getMap(parent).get(key);
|
|
17920
|
+
let sequence = null;
|
|
17921
|
+
if (current?.kind === "text")
|
|
17922
|
+
sequence = history?.sequences.get(current.name) ?? null;
|
|
17923
|
+
if (current?.kind === "list")
|
|
17924
|
+
sequence = history?.sequences.get(`${current.name}:order`) ?? null;
|
|
17925
|
+
const previous = document2.clientID;
|
|
17926
|
+
document2.clientID = documentAuthorId(canonicalJson([seed, parent, key, history?.fields.get(JSON.stringify([parent, key])) ?? null, sequence, value]));
|
|
16939
17927
|
try {
|
|
16940
|
-
|
|
16941
|
-
next.shared = { kind: change.shared.kind, update: encodeBytes(encodeStateAsUpdate(document2)) };
|
|
17928
|
+
return action();
|
|
16942
17929
|
} finally {
|
|
16943
|
-
document2.
|
|
17930
|
+
document2.clientID = previous;
|
|
16944
17931
|
}
|
|
16945
|
-
}
|
|
16946
|
-
|
|
16947
|
-
next.value = change.value.next;
|
|
16948
|
-
if (change.asset)
|
|
16949
|
-
next.asset = change.asset.next;
|
|
16950
|
-
next.deleted = change.deleted ?? change.baseDeleted;
|
|
16951
|
-
next.revision++;
|
|
16952
|
-
return next;
|
|
16953
|
-
};
|
|
16954
|
-
|
|
16955
|
-
// ../pstdio-sync/src/resolution-validation.ts
|
|
16956
|
-
var parentProblem = (state, operation, captured, visited) => {
|
|
16957
|
-
for (const parent of operation.parents) {
|
|
16958
|
-
if (captured.has(parent)) {
|
|
16959
|
-
if (!visited.has(parent))
|
|
16960
|
-
return "captured branch is not in ancestry order";
|
|
16961
|
-
} else if (!state.availableParentIds.has(parent))
|
|
16962
|
-
return "uncaptured unaccepted prerequisite";
|
|
16963
|
-
}
|
|
16964
|
-
};
|
|
16965
|
-
var connectedSize = (operations, rootId) => {
|
|
16966
|
-
const captured = new Set(operations.map((operation) => operation.operationId));
|
|
16967
|
-
const edges = new Map;
|
|
16968
|
-
for (const operation of operations) {
|
|
16969
|
-
for (const parent of operation.parents.filter((id) => captured.has(id))) {
|
|
16970
|
-
edges.set(operation.operationId, new Set([...edges.get(operation.operationId) ?? [], parent]));
|
|
16971
|
-
edges.set(parent, new Set([...edges.get(parent) ?? [], operation.operationId]));
|
|
16972
|
-
}
|
|
16973
|
-
}
|
|
16974
|
-
const connected = new Set([rootId]);
|
|
16975
|
-
for (const id of connected)
|
|
16976
|
-
for (const next of edges.get(id) ?? [])
|
|
16977
|
-
connected.add(next);
|
|
16978
|
-
return connected.size;
|
|
16979
|
-
};
|
|
16980
|
-
var captureProblem = (state, mutation) => {
|
|
16981
|
-
const proposal = mutation.resolution;
|
|
16982
|
-
const captured = new Set(proposal.capturedOperationIds);
|
|
16983
|
-
if (!captured.has(proposal.conflictId))
|
|
16984
|
-
return "resolution must capture its root conflict";
|
|
16985
|
-
const visited = new Set;
|
|
16986
|
-
const recordIds = new Set;
|
|
16987
|
-
const operations = [];
|
|
16988
|
-
for (const id of proposal.capturedOperationIds) {
|
|
16989
|
-
const operation = state.operations.get(id);
|
|
16990
|
-
if (!operation || state.acceptedOperationIds.has(id))
|
|
16991
|
-
return "captured branch is unavailable";
|
|
16992
|
-
const problem = parentProblem(state, operation, captured, visited);
|
|
16993
|
-
if (problem)
|
|
16994
|
-
return problem;
|
|
16995
|
-
operations.push(operation);
|
|
16996
|
-
visited.add(id);
|
|
16997
|
-
for (const change of operation.changes)
|
|
16998
|
-
recordIds.add(change.recordId);
|
|
16999
|
-
}
|
|
17000
|
-
if (connectedSize(operations, proposal.conflictId) !== captured.size)
|
|
17001
|
-
return "unrelated captured operation";
|
|
17002
|
-
if (recordIds.size !== mutation.changes.length || mutation.changes.some((change) => !recordIds.has(change.recordId)))
|
|
17003
|
-
return "resolution omits captured records";
|
|
17004
|
-
};
|
|
17005
|
-
var validateResolution = (state, mutation) => {
|
|
17006
|
-
const proposal = mutation.resolution;
|
|
17007
|
-
if (!proposal)
|
|
17008
|
-
return;
|
|
17009
|
-
const root = state.conflicts.get(proposal.conflictId);
|
|
17010
|
-
if (!root || root.resolvedBy)
|
|
17011
|
-
return "stale conflict revision";
|
|
17012
|
-
for (const expected of proposal.expectedConflicts) {
|
|
17013
|
-
const conflict = state.conflicts.get(expected.conflictId);
|
|
17014
|
-
if (!conflict || conflict.revision !== expected.revision)
|
|
17015
|
-
return "stale conflict revision";
|
|
17016
|
-
}
|
|
17017
|
-
const captured = new Set(proposal.capturedOperationIds);
|
|
17018
|
-
const affected = [...state.conflicts.values()].filter((conflict) => conflict.alternativeOperationIds.some((id) => captured.has(id)));
|
|
17019
|
-
if (affected.length !== proposal.expectedConflicts.length || affected.some((conflict) => !proposal.expectedConflicts.some((entry) => entry.conflictId === conflict.conflictId)))
|
|
17020
|
-
return "missing captured conflict revision";
|
|
17021
|
-
if (proposal.handler && proposal.handler.publishedRevision !== state.publishedRevision)
|
|
17022
|
-
return "stale published handler revision";
|
|
17023
|
-
for (const expected of proposal.expectedInputs)
|
|
17024
|
-
if (expected.revision !== (state.records.get(expected.recordId)?.revision ?? 0))
|
|
17025
|
-
return "stale input revision";
|
|
17026
|
-
for (const change of mutation.changes) {
|
|
17027
|
-
const record = state.records.get(change.recordId) ?? blankRecord(change.recordId);
|
|
17028
|
-
if (change.shared && record.primitive && change.shared.kind !== record.primitive)
|
|
17029
|
-
return "incompatible shared primitive";
|
|
17030
|
-
}
|
|
17031
|
-
return captureProblem(state, mutation);
|
|
17932
|
+
};
|
|
17933
|
+
return author;
|
|
17032
17934
|
};
|
|
17033
17935
|
|
|
17034
|
-
// ../pstdio-sync/src/
|
|
17035
|
-
var
|
|
17036
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
17041
|
-
|
|
17042
|
-
if (
|
|
17043
|
-
|
|
17044
|
-
|
|
17045
|
-
|
|
17046
|
-
|
|
17047
|
-
|
|
17048
|
-
|
|
17049
|
-
|
|
17050
|
-
|
|
17051
|
-
|
|
17052
|
-
|
|
17053
|
-
|
|
17054
|
-
|
|
17055
|
-
|
|
17056
|
-
|
|
17057
|
-
|
|
17058
|
-
for (const expected of proposal.expectedConflicts) {
|
|
17059
|
-
const conflict = view.conflicts.get(expected.conflictId);
|
|
17060
|
-
if (!conflict)
|
|
17061
|
-
continue;
|
|
17062
|
-
view.conflicts.delete(expected.conflictId);
|
|
17063
|
-
for (const alternative of conflict.alternatives) {
|
|
17064
|
-
if (captured.has(alternative.operationId))
|
|
17065
|
-
continue;
|
|
17066
|
-
view.conflicts.set(alternative.operationId, {
|
|
17067
|
-
conflictId: alternative.operationId,
|
|
17068
|
-
revision: 1,
|
|
17069
|
-
recordIds: alternative.records.map((record) => record.recordId),
|
|
17070
|
-
alternativeOperationIds: [alternative.operationId],
|
|
17071
|
-
reason: conflict.reason,
|
|
17072
|
-
alternatives: [alternative]
|
|
17073
|
-
});
|
|
17936
|
+
// ../pstdio-sync/src/document-values.ts
|
|
17937
|
+
var import_fast_diff = __toESM(require_diff(), 1);
|
|
17938
|
+
var readValue = (value, document2) => {
|
|
17939
|
+
if (value === null || typeof value !== "object")
|
|
17940
|
+
return value ?? null;
|
|
17941
|
+
const reference = value;
|
|
17942
|
+
if (reference.kind === "text")
|
|
17943
|
+
return document2.getText(reference.name).toString();
|
|
17944
|
+
if (reference.kind === "list") {
|
|
17945
|
+
const items = document2.getMap(`${reference.name}:items`);
|
|
17946
|
+
const order = document2.getArray(`${reference.name}:order`).toArray();
|
|
17947
|
+
return order.filter((key, index) => items.has(key) && order.lastIndexOf(key) === index).map((key) => readValue(items.get(key), document2));
|
|
17948
|
+
}
|
|
17949
|
+
return Object.fromEntries([...document2.getMap(reference.name)].map(([key, entry]) => [key, readValue(entry, document2)]));
|
|
17950
|
+
};
|
|
17951
|
+
var writeText = (text, next) => {
|
|
17952
|
+
let index = 0;
|
|
17953
|
+
for (const [operation, value] of import_fast_diff.default(text.toString(), next)) {
|
|
17954
|
+
if (operation === -1)
|
|
17955
|
+
text.delete(index, value.length);
|
|
17956
|
+
else {
|
|
17957
|
+
if (operation === 1)
|
|
17958
|
+
text.insert(index, value);
|
|
17959
|
+
index += value.length;
|
|
17074
17960
|
}
|
|
17075
17961
|
}
|
|
17076
17962
|
};
|
|
17077
|
-
|
|
17078
|
-
|
|
17079
|
-
|
|
17080
|
-
|
|
17081
|
-
|
|
17082
|
-
|
|
17083
|
-
return
|
|
17084
|
-
status: "conflict",
|
|
17085
|
-
operationId: receipt.operationId,
|
|
17086
|
-
conflictId: receipt.conflictId,
|
|
17087
|
-
conflictRevision: state.accepted.conflicts[receipt.conflictId].revision
|
|
17088
|
-
};
|
|
17089
|
-
return {
|
|
17090
|
-
status: "pending",
|
|
17091
|
-
operationId: receipt.operationId,
|
|
17092
|
-
reason: receipt.reason ?? "awaiting dependency"
|
|
17093
|
-
};
|
|
17094
|
-
};
|
|
17095
|
-
var acceptedProjection = (state) => {
|
|
17096
|
-
const records = new Map(Object.entries(structuredClone(state.accepted?.records ?? {})));
|
|
17097
|
-
const operations = new Map;
|
|
17098
|
-
const outcomes = new Map;
|
|
17099
|
-
const receipts = Object.values(state.accepted?.receipts ?? {}).sort((left, right) => (left.checkpoint?.sequence ?? 0) - (right.checkpoint?.sequence ?? 0));
|
|
17100
|
-
for (const receipt of receipts) {
|
|
17101
|
-
outcomes.set(receipt.operationId, receiptOutcome(state, receipt));
|
|
17102
|
-
if (receipt.status === "accepted")
|
|
17103
|
-
for (const change of receipt.mutation.changes)
|
|
17104
|
-
operations.set(change.recordId, [...operations.get(change.recordId) ?? [], receipt.operationId]);
|
|
17105
|
-
}
|
|
17106
|
-
return {
|
|
17107
|
-
records,
|
|
17108
|
-
operations,
|
|
17109
|
-
outcomes,
|
|
17110
|
-
applied: new Set(receipts.filter((receipt) => receipt.status === "accepted").map((receipt) => receipt.operationId)),
|
|
17111
|
-
completed: completedOperations(state.accepted),
|
|
17112
|
-
conflicts: new Map(Object.values(state.accepted?.conflicts ?? {}).filter((conflict) => !conflict.resolvedBy).map((conflict) => [
|
|
17113
|
-
conflict.conflictId,
|
|
17114
|
-
{
|
|
17115
|
-
...structuredClone(conflict),
|
|
17116
|
-
reason: "Retained alternative",
|
|
17117
|
-
alternatives: []
|
|
17118
|
-
}
|
|
17119
|
-
]))
|
|
17120
|
-
};
|
|
17121
|
-
};
|
|
17122
|
-
var addConflict = (view, mutation, conflictId, reason) => {
|
|
17123
|
-
const conflict = view.conflicts.get(conflictId) ?? {
|
|
17124
|
-
conflictId,
|
|
17125
|
-
reason,
|
|
17126
|
-
revision: 1,
|
|
17127
|
-
recordIds: mutation.changes.map((change) => change.recordId),
|
|
17128
|
-
alternativeOperationIds: [],
|
|
17129
|
-
alternatives: []
|
|
17130
|
-
};
|
|
17131
|
-
if (!conflict.alternativeOperationIds.includes(mutation.operationId))
|
|
17132
|
-
conflict.alternativeOperationIds.push(mutation.operationId);
|
|
17133
|
-
conflict.alternatives.push({
|
|
17134
|
-
operationId: mutation.operationId,
|
|
17135
|
-
records: mutation.changes.map((change) => applyRecordChange(view.records.get(change.recordId) ?? blankRecord(change.recordId), change))
|
|
17136
|
-
});
|
|
17137
|
-
view.conflicts.set(conflictId, conflict);
|
|
17138
|
-
view.outcomes.set(mutation.operationId, {
|
|
17139
|
-
status: "conflict",
|
|
17140
|
-
operationId: mutation.operationId,
|
|
17141
|
-
conflictId,
|
|
17142
|
-
conflictRevision: conflict.revision
|
|
17963
|
+
var listKeys = (values) => {
|
|
17964
|
+
const seen = new Map;
|
|
17965
|
+
return values.map((value) => {
|
|
17966
|
+
const identity = value && typeof value === "object" && !Array.isArray(value) && "id" in value ? canonicalJson(["id", value.id]) : canonicalJson(["value", value]);
|
|
17967
|
+
const occurrence = seen.get(identity) ?? 0;
|
|
17968
|
+
seen.set(identity, occurrence + 1);
|
|
17969
|
+
return canonicalJson([identity, occurrence]);
|
|
17143
17970
|
});
|
|
17144
17971
|
};
|
|
17145
|
-
var
|
|
17146
|
-
const
|
|
17147
|
-
if (
|
|
17148
|
-
return
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
return
|
|
17152
|
-
};
|
|
17153
|
-
var
|
|
17154
|
-
|
|
17155
|
-
|
|
17156
|
-
const
|
|
17157
|
-
|
|
17158
|
-
|
|
17159
|
-
|
|
17160
|
-
|
|
17161
|
-
|
|
17162
|
-
|
|
17163
|
-
|
|
17164
|
-
|
|
17165
|
-
|
|
17166
|
-
|
|
17167
|
-
|
|
17168
|
-
|
|
17169
|
-
|
|
17170
|
-
};
|
|
17171
|
-
var applyOperation = (view, mutation) => {
|
|
17172
|
-
if (mutation.resolution)
|
|
17173
|
-
retainAfterResolution(view, mutation);
|
|
17174
|
-
for (const change of mutation.changes) {
|
|
17175
|
-
view.records.set(change.recordId, applyRecordChange(view.records.get(change.recordId) ?? blankRecord(change.recordId), change));
|
|
17176
|
-
view.operations.set(change.recordId, [...view.operations.get(change.recordId) ?? [], mutation.operationId]);
|
|
17177
|
-
}
|
|
17178
|
-
view.applied.add(mutation.operationId);
|
|
17179
|
-
};
|
|
17180
|
-
var projectOperation = async (view, state, entry, environmentId) => {
|
|
17181
|
-
const mutation = entry.mutation;
|
|
17182
|
-
if (view.completed.has(mutation.operationId))
|
|
17183
|
-
return;
|
|
17184
|
-
const known = state.accepted?.receipts[mutation.operationId];
|
|
17185
|
-
const retained = known?.status === "conflict" ? Object.values(state.accepted.conflicts).find((conflict) => !conflict.resolvedBy && conflict.alternativeOperationIds.includes(mutation.operationId)) : undefined;
|
|
17186
|
-
if (mutation.environmentId !== environmentId && !entry.acceptance && known?.status !== "conflict")
|
|
17187
|
-
return;
|
|
17188
|
-
if (known?.status !== "conflict" && waitingForParent(view, mutation)) {
|
|
17189
|
-
view.outcomes.set(mutation.operationId, {
|
|
17190
|
-
status: "pending",
|
|
17191
|
-
operationId: mutation.operationId,
|
|
17192
|
-
reason: "awaiting dependency"
|
|
17193
|
-
});
|
|
17194
|
-
return;
|
|
17195
|
-
}
|
|
17196
|
-
const blocked = mutation.parents.map((id) => view.outcomes.get(id)).find((outcome) => outcome?.status === "conflict");
|
|
17197
|
-
const problem = await operationProblem(view, state, mutation);
|
|
17198
|
-
if (!known && !blocked)
|
|
17199
|
-
advanceConflicts(view, mutation);
|
|
17200
|
-
if (known?.status === "conflict" || problem) {
|
|
17201
|
-
addConflict(view, mutation, retained?.conflictId ?? (mutation.resolution && view.conflicts.has(mutation.resolution.conflictId) ? mutation.resolution.conflictId : undefined) ?? blocked?.conflictId ?? mutation.operationId, problem ?? "Unaccepted dependency");
|
|
17202
|
-
return;
|
|
17203
|
-
}
|
|
17204
|
-
applyOperation(view, mutation);
|
|
17205
|
-
view.outcomes.set(mutation.operationId, localOutcome(state, entry));
|
|
17206
|
-
};
|
|
17207
|
-
var projectGroups = async (state, environmentId) => {
|
|
17208
|
-
const view = acceptedProjection(state);
|
|
17209
|
-
for (const entry of state.journal)
|
|
17210
|
-
await projectOperation(view, state, entry, environmentId);
|
|
17211
|
-
const read = (recordId) => ({
|
|
17212
|
-
...publicRecord(view.records.get(recordId) ?? blankRecord(recordId)),
|
|
17213
|
-
revision: encodeText(JSON.stringify({ owner: state.owner, recordId, operations: view.operations.get(recordId) ?? [] }))
|
|
17214
|
-
});
|
|
17215
|
-
return {
|
|
17216
|
-
read,
|
|
17217
|
-
records: view.records,
|
|
17218
|
-
operations: view.operations,
|
|
17219
|
-
outcomes: view.outcomes,
|
|
17220
|
-
conflicts: [...view.conflicts.values()],
|
|
17221
|
-
completed: view.completed
|
|
17222
|
-
};
|
|
17223
|
-
};
|
|
17224
|
-
|
|
17225
|
-
// ../pstdio-sync/src/authoring.ts
|
|
17226
|
-
var recordVersion = (state, recordId, captured) => {
|
|
17227
|
-
const token = JSON.parse(decodeText(captured));
|
|
17228
|
-
if (token.owner.workbenchId !== state.owner.workbenchId || token.owner.extensionId !== state.owner.extensionId)
|
|
17229
|
-
throw new Error("Revision belongs to another storage owner");
|
|
17230
|
-
if (token.recordId !== recordId)
|
|
17231
|
-
throw new Error("Revision belongs to another record");
|
|
17232
|
-
let record = blankRecord(recordId);
|
|
17233
|
-
for (const operationId of token.operations) {
|
|
17234
|
-
const entry = state.journal.find((entry) => entry.mutation.operationId === operationId);
|
|
17235
|
-
if (!entry)
|
|
17236
|
-
throw new Error("Unknown record revision");
|
|
17237
|
-
const change = entry.mutation.changes.find((change) => change.recordId === recordId);
|
|
17238
|
-
if (change)
|
|
17239
|
-
record = applyRecordChange(record, change);
|
|
17240
|
-
}
|
|
17241
|
-
return { record, operations: token.operations };
|
|
17242
|
-
};
|
|
17243
|
-
var authorGroup = async (state, input, environmentId) => {
|
|
17244
|
-
const parents = new Set;
|
|
17245
|
-
const { completed } = await projectGroups(state, environmentId);
|
|
17246
|
-
const changes = await Promise.all(input.edits.map(async (edit) => {
|
|
17247
|
-
const base = recordVersion(state, edit.recordId, edit.expectedRevision);
|
|
17248
|
-
for (const id of base.operations)
|
|
17249
|
-
if (!completed.has(id))
|
|
17250
|
-
parents.add(id);
|
|
17251
|
-
return {
|
|
17252
|
-
recordId: edit.recordId,
|
|
17253
|
-
expectedRevision: base.record.revision,
|
|
17254
|
-
baseDeleted: base.record.deleted,
|
|
17255
|
-
...Object.hasOwn(edit, "replace") && {
|
|
17256
|
-
value: { expected: await fingerprint(base.record.value), next: edit.replace }
|
|
17257
|
-
},
|
|
17258
|
-
...edit.shared && { shared: await sharedChange(base.record, edit.shared) },
|
|
17259
|
-
...edit.asset !== undefined && { asset: { base: base.record.asset, next: edit.asset } },
|
|
17260
|
-
...edit.deleted !== undefined && { deleted: edit.deleted }
|
|
17261
|
-
};
|
|
17262
|
-
}));
|
|
17263
|
-
return { operationId: input.operationId, environmentId, parents: [...parents], changes };
|
|
17264
|
-
};
|
|
17265
|
-
var inputFingerprint = (input) => fingerprint(input);
|
|
17266
|
-
var entryFor = async (state, input, environmentId) => ({
|
|
17267
|
-
inputFingerprint: await inputFingerprint(input),
|
|
17268
|
-
mutation: await authorGroup(state, input, environmentId)
|
|
17269
|
-
});
|
|
17270
|
-
|
|
17271
|
-
// ../pstdio-sync/src/branches.ts
|
|
17272
|
-
var workingRecords = (state, environmentId) => {
|
|
17273
|
-
const pending = pendingOperations(state, environmentId);
|
|
17274
|
-
const replaced = new Set(pending.flatMap((operation) => operation.resolution?.capturedOperationIds ?? []));
|
|
17275
|
-
const records = new Map(Object.entries(structuredClone(state.accepted?.records ?? {})));
|
|
17276
|
-
for (const mutation of pending) {
|
|
17277
|
-
if (replaced.has(mutation.operationId))
|
|
17972
|
+
var valueReference = (parent, key, kind, path) => {
|
|
17973
|
+
const current = parent.get(key);
|
|
17974
|
+
if (current?.kind === kind)
|
|
17975
|
+
return current;
|
|
17976
|
+
const reference = { kind, name: `${path.length}:${path}${key.length}:${key}:${kind}` };
|
|
17977
|
+
parent.set(key, reference);
|
|
17978
|
+
return reference;
|
|
17979
|
+
};
|
|
17980
|
+
var writeList = (document2, name, values, author) => {
|
|
17981
|
+
const items = document2.getMap(`${name}:items`);
|
|
17982
|
+
const order = document2.getArray(`${name}:order`);
|
|
17983
|
+
const keys = listKeys(values);
|
|
17984
|
+
const wanted = new Set(keys);
|
|
17985
|
+
for (const key of items.keys())
|
|
17986
|
+
if (!wanted.has(key))
|
|
17987
|
+
items.delete(key);
|
|
17988
|
+
for (let index = 0;index < keys.length; index++)
|
|
17989
|
+
writeValue(items, keys[index], values[index], `${name}:items`, author);
|
|
17990
|
+
const current = order.toArray();
|
|
17991
|
+
for (let index = current.length - 1;index >= 0; index--) {
|
|
17992
|
+
if (!wanted.has(current[index]) || current.lastIndexOf(current[index]) !== index)
|
|
17993
|
+
order.delete(index, 1);
|
|
17994
|
+
}
|
|
17995
|
+
for (let index = 0;index < keys.length; index++) {
|
|
17996
|
+
if (order.get(index) === keys[index])
|
|
17278
17997
|
continue;
|
|
17279
|
-
|
|
17280
|
-
|
|
17281
|
-
|
|
17282
|
-
|
|
17283
|
-
};
|
|
17284
|
-
var ancestors = (state, operationId) => {
|
|
17285
|
-
const available = new Map(state.journal.map((entry) => [entry.mutation.operationId, entry.mutation]));
|
|
17286
|
-
const required = new Set([operationId]);
|
|
17287
|
-
for (const id of required) {
|
|
17288
|
-
const operation = available.get(id);
|
|
17289
|
-
if (!operation)
|
|
17290
|
-
throw new Error("Branch operation is unavailable");
|
|
17291
|
-
for (const parent of operation.parents)
|
|
17292
|
-
if (state.accepted?.receipts[parent]?.status !== "accepted")
|
|
17293
|
-
required.add(parent);
|
|
17294
|
-
}
|
|
17295
|
-
return orderOperations(available, required);
|
|
17296
|
-
};
|
|
17297
|
-
var readBranch = async (state, environmentId, recordId, operationId) => {
|
|
17298
|
-
const view = await projectGroups(state, environmentId);
|
|
17299
|
-
const applied = new Set([...view.operations.values()].flat());
|
|
17300
|
-
const branch = ancestors(state, operationId);
|
|
17301
|
-
const replaced = new Set(branch.flatMap((mutation) => mutation.resolution?.capturedOperationIds ?? []));
|
|
17302
|
-
for (const mutation of branch) {
|
|
17303
|
-
if (replaced.has(mutation.operationId))
|
|
17304
|
-
continue;
|
|
17305
|
-
if (applied.has(mutation.operationId))
|
|
17306
|
-
continue;
|
|
17307
|
-
for (const change of mutation.changes) {
|
|
17308
|
-
view.records.set(change.recordId, applyRecordChange(view.records.get(change.recordId) ?? blankRecord(change.recordId), change));
|
|
17309
|
-
view.operations.set(change.recordId, [...view.operations.get(change.recordId) ?? [], mutation.operationId]);
|
|
17310
|
-
}
|
|
17311
|
-
applied.add(mutation.operationId);
|
|
17998
|
+
const previous = order.toArray().indexOf(keys[index], index);
|
|
17999
|
+
if (previous >= 0)
|
|
18000
|
+
order.delete(previous, 1);
|
|
18001
|
+
order.insert(index, [keys[index]]);
|
|
17312
18002
|
}
|
|
17313
|
-
return {
|
|
17314
|
-
...publicRecord(view.records.get(recordId) ?? blankRecord(recordId)),
|
|
17315
|
-
revision: encodeText(JSON.stringify({ owner: state.owner, recordId, operations: view.operations.get(recordId) ?? [] }))
|
|
17316
|
-
};
|
|
17317
|
-
};
|
|
17318
|
-
|
|
17319
|
-
// ../pstdio-sync/src/capture.ts
|
|
17320
|
-
var captureBranch = (state, environmentId, rootId, published = new Set) => {
|
|
17321
|
-
const available = new Map(state.journal.map((entry) => [entry.mutation.operationId, entry.mutation]));
|
|
17322
|
-
const captured = new Set([rootId]);
|
|
17323
|
-
const pending = pendingOperations(state, environmentId);
|
|
17324
|
-
let changed = true;
|
|
17325
|
-
while (changed) {
|
|
17326
|
-
const before = captured.size;
|
|
17327
|
-
for (const mutation of pending.filter((operation) => !published.has(operation.operationId)))
|
|
17328
|
-
if (mutation.parents.some((parent) => captured.has(parent)))
|
|
17329
|
-
captured.add(mutation.operationId);
|
|
17330
|
-
for (const id of captured) {
|
|
17331
|
-
const mutation = available.get(id);
|
|
17332
|
-
if (!mutation)
|
|
17333
|
-
throw new Error("Captured branch is unavailable");
|
|
17334
|
-
for (const parent of mutation.parents)
|
|
17335
|
-
if (state.accepted?.receipts[parent]?.status !== "accepted" && !published.has(parent))
|
|
17336
|
-
captured.add(parent);
|
|
17337
|
-
}
|
|
17338
|
-
changed = captured.size !== before;
|
|
17339
|
-
}
|
|
17340
|
-
return orderOperations(available, captured);
|
|
17341
18003
|
};
|
|
17342
|
-
|
|
17343
|
-
|
|
17344
|
-
|
|
17345
|
-
|
|
17346
|
-
|
|
17347
|
-
|
|
17348
|
-
|
|
17349
|
-
|
|
17350
|
-
const
|
|
17351
|
-
const
|
|
17352
|
-
|
|
17353
|
-
|
|
17354
|
-
|
|
17355
|
-
|
|
17356
|
-
|
|
17357
|
-
|
|
17358
|
-
|
|
17359
|
-
|
|
17360
|
-
|
|
17361
|
-
|
|
17362
|
-
|
|
17363
|
-
|
|
17364
|
-
|
|
17365
|
-
|
|
17366
|
-
|
|
17367
|
-
|
|
17368
|
-
|
|
17369
|
-
|
|
17370
|
-
|
|
17371
|
-
|
|
17372
|
-
|
|
17373
|
-
|
|
17374
|
-
|
|
17375
|
-
if (!keys.length)
|
|
18004
|
+
var writeValue = (parent, key, next, path, author) => {
|
|
18005
|
+
const write = () => writeValueContent(parent, key, next, path, author);
|
|
18006
|
+
if (author)
|
|
18007
|
+
author(path, key, next, write);
|
|
18008
|
+
else
|
|
18009
|
+
write();
|
|
18010
|
+
};
|
|
18011
|
+
var writeValueContent = (parent, key, next, path, author) => {
|
|
18012
|
+
const current = parent.get(key);
|
|
18013
|
+
const document2 = parent.doc;
|
|
18014
|
+
if (Array.isArray(next)) {
|
|
18015
|
+
const reference = valueReference(parent, key, "list", path);
|
|
18016
|
+
writeList(document2, reference.name, next, author);
|
|
18017
|
+
} else if (next !== null && typeof next === "object") {
|
|
18018
|
+
const reference = valueReference(parent, key, "object", path);
|
|
18019
|
+
const map = document2.getMap(reference.name);
|
|
18020
|
+
for (const field of map.keys())
|
|
18021
|
+
if (!Object.hasOwn(next, field))
|
|
18022
|
+
map.delete(field);
|
|
18023
|
+
for (const [field, value] of Object.entries(next).sort(([a], [b]) => a.localeCompare(b)))
|
|
18024
|
+
writeValue(map, field, value, reference.name, author);
|
|
18025
|
+
} else if (typeof next === "string" && (next.includes(`
|
|
18026
|
+
`) || current && typeof current === "object" && ("kind" in current) && current.kind === "text")) {
|
|
18027
|
+
const reference = valueReference(parent, key, "text", path);
|
|
18028
|
+
if (typeof current === "string")
|
|
18029
|
+
seedText(document2, reference.name, current);
|
|
18030
|
+
writeText(document2.getText(reference.name), next);
|
|
18031
|
+
} else if (current !== next)
|
|
18032
|
+
parent.set(key, next);
|
|
18033
|
+
};
|
|
18034
|
+
var seedText = (document2, name, value) => {
|
|
18035
|
+
const client = documentAuthorId(canonicalJson(["text-promotion", name, value]));
|
|
18036
|
+
if (decodeStateVector(encodeStateVector(document2)).has(client))
|
|
17376
18037
|
return;
|
|
17377
|
-
const
|
|
17378
|
-
|
|
17379
|
-
|
|
17380
|
-
|
|
17381
|
-
}
|
|
17382
|
-
|
|
17383
|
-
};
|
|
17384
|
-
var resolutionEntry = async (state, input, environmentId) => {
|
|
17385
|
-
const available = new Map(state.journal.map((entry) => [entry.mutation.operationId, entry.mutation]));
|
|
17386
|
-
const branch = input.capturedOperationIds.map((id) => {
|
|
17387
|
-
const operation = available.get(id);
|
|
17388
|
-
if (!operation)
|
|
17389
|
-
throw new Error("Captured branch is unavailable");
|
|
17390
|
-
return operation;
|
|
17391
|
-
});
|
|
17392
|
-
const ids = [...new Set(branch.flatMap((mutation) => mutation.changes.map((change) => change.recordId)))];
|
|
17393
|
-
if (input.expectedInputs.length !== ids.length)
|
|
17394
|
-
throw new Error("Resolution inputs must cover every captured record");
|
|
17395
|
-
const replaced = new Set(branch.flatMap((mutation) => mutation.resolution?.capturedOperationIds ?? []));
|
|
17396
|
-
const current = new Map(ids.map((id) => {
|
|
17397
|
-
const expected = input.expectedInputs.find((entry) => entry.recordId === id);
|
|
17398
|
-
if (!expected)
|
|
17399
|
-
throw new Error("Resolution input is unavailable");
|
|
17400
|
-
return [id, recordVersion(state, id, expected.revision).record];
|
|
17401
|
-
}));
|
|
17402
|
-
const draft = new Map([...current].map(([id, record]) => [id, structuredClone(record)]));
|
|
17403
|
-
for (const mutation of branch) {
|
|
17404
|
-
if (replaced.has(mutation.operationId))
|
|
17405
|
-
continue;
|
|
17406
|
-
for (const change of mutation.changes)
|
|
17407
|
-
draft.set(change.recordId, applyRecordChange(draft.get(change.recordId), change));
|
|
18038
|
+
const author = document2.clientID;
|
|
18039
|
+
document2.clientID = client;
|
|
18040
|
+
try {
|
|
18041
|
+
document2.getText(name).insert(0, value);
|
|
18042
|
+
} finally {
|
|
18043
|
+
document2.clientID = author;
|
|
17408
18044
|
}
|
|
17409
|
-
const changes = await Promise.all(ids.map(async (recordId) => {
|
|
17410
|
-
const base = current.get(recordId);
|
|
17411
|
-
const alternative = draft.get(recordId);
|
|
17412
|
-
const selected = input.choose === "local" ? alternative : base;
|
|
17413
|
-
return {
|
|
17414
|
-
recordId,
|
|
17415
|
-
expectedRevision: base.revision,
|
|
17416
|
-
baseDeleted: base.deleted,
|
|
17417
|
-
shared: await resolutionShared(base, alternative, input.choose),
|
|
17418
|
-
value: { expected: await fingerprint(base.value), next: selected.value },
|
|
17419
|
-
asset: { base: base.asset, next: selected.asset },
|
|
17420
|
-
deleted: selected.deleted
|
|
17421
|
-
};
|
|
17422
|
-
}));
|
|
17423
|
-
const mutation = {
|
|
17424
|
-
operationId: input.operationId,
|
|
17425
|
-
environmentId,
|
|
17426
|
-
parents: input.capturedOperationIds,
|
|
17427
|
-
changes,
|
|
17428
|
-
resolution: {
|
|
17429
|
-
conflictId: input.conflictId,
|
|
17430
|
-
expectedConflicts: input.expectedConflicts,
|
|
17431
|
-
capturedOperationIds: input.capturedOperationIds,
|
|
17432
|
-
expectedInputs: ids.map((recordId) => ({ recordId, revision: current.get(recordId).revision })),
|
|
17433
|
-
...input.handler && { handler: input.handler }
|
|
17434
|
-
}
|
|
17435
|
-
};
|
|
17436
|
-
return { inputFingerprint: await inputFingerprint(input), mutation };
|
|
17437
18045
|
};
|
|
17438
18046
|
|
|
17439
|
-
// ../pstdio-sync/src/
|
|
17440
|
-
|
|
17441
|
-
|
|
17442
|
-
|
|
17443
|
-
|
|
17444
|
-
|
|
17445
|
-
|
|
17446
|
-
|
|
17447
|
-
|
|
17448
|
-
|
|
17449
|
-
|
|
18047
|
+
// ../pstdio-sync/src/document-edits.ts
|
|
18048
|
+
var applyShared = (document2, record, name, shared, author) => {
|
|
18049
|
+
const kind = shared.kind.split(".")[0];
|
|
18050
|
+
if (record.get("sharedKind") !== kind)
|
|
18051
|
+
record.set("sharedKind", kind);
|
|
18052
|
+
switch (shared.kind) {
|
|
18053
|
+
case "map.set":
|
|
18054
|
+
case "map.delete": {
|
|
18055
|
+
const reference = valueReference(record, "shared", "object", name);
|
|
18056
|
+
const map = document2.getMap(reference.name);
|
|
18057
|
+
if (shared.kind === "map.set")
|
|
18058
|
+
writeValue(map, shared.key, shared.value, reference.name, author);
|
|
18059
|
+
else
|
|
18060
|
+
map.delete(shared.key);
|
|
18061
|
+
break;
|
|
18062
|
+
}
|
|
18063
|
+
case "text.insert":
|
|
18064
|
+
case "text.delete": {
|
|
18065
|
+
const reference = valueReference(record, "shared", "text", name);
|
|
18066
|
+
const text = document2.getText(reference.name);
|
|
18067
|
+
if (shared.kind === "text.insert")
|
|
18068
|
+
text.insert(shared.index, shared.text);
|
|
18069
|
+
else
|
|
18070
|
+
text.delete(shared.index, shared.count);
|
|
18071
|
+
break;
|
|
18072
|
+
}
|
|
18073
|
+
case "list.insert":
|
|
18074
|
+
case "list.delete": {
|
|
18075
|
+
const values = record.has("shared") ? readValue(record.get("shared"), document2) : [];
|
|
18076
|
+
if (shared.kind === "list.insert")
|
|
18077
|
+
values.splice(shared.index, 0, ...shared.values);
|
|
18078
|
+
else
|
|
18079
|
+
values.splice(shared.index, shared.count);
|
|
18080
|
+
writeValue(record, "shared", values, name, author);
|
|
18081
|
+
break;
|
|
18082
|
+
}
|
|
17450
18083
|
}
|
|
17451
18084
|
};
|
|
17452
|
-
var
|
|
17453
|
-
|
|
17454
|
-
|
|
17455
|
-
|
|
17456
|
-
|
|
17457
|
-
}
|
|
17458
|
-
try {
|
|
17459
|
-
await local.verifyComplete([asset]);
|
|
17460
|
-
return;
|
|
17461
|
-
} catch {}
|
|
17462
|
-
if (!adapter.assets) {
|
|
17463
|
-
if (required)
|
|
17464
|
-
throw new Error("Asset transport is unavailable");
|
|
18085
|
+
var applyDocumentEdit = (document2, edit, author) => {
|
|
18086
|
+
const records = document2.getMap("records");
|
|
18087
|
+
if (edit.deleted) {
|
|
18088
|
+
records.delete(edit.recordId);
|
|
18089
|
+
document2.getMap("deleted").set(edit.recordId, true);
|
|
17465
18090
|
return;
|
|
17466
18091
|
}
|
|
17467
|
-
|
|
17468
|
-
|
|
17469
|
-
|
|
17470
|
-
if (!source)
|
|
17471
|
-
throw new MissingRemoteAsset(`Required asset is incomplete: ${asset.sha256}`);
|
|
17472
|
-
return source;
|
|
17473
|
-
});
|
|
17474
|
-
} catch (error) {
|
|
17475
|
-
if (!required && error instanceof MissingRemoteAsset)
|
|
18092
|
+
let name = records.get(edit.recordId);
|
|
18093
|
+
if (!name) {
|
|
18094
|
+
if (document2.getMap("deleted").has(edit.recordId) && edit.deleted !== false)
|
|
17476
18095
|
return;
|
|
17477
|
-
|
|
18096
|
+
name = JSON.stringify(["record", edit.recordId]);
|
|
18097
|
+
records.set(edit.recordId, name);
|
|
18098
|
+
document2.getMap("deleted").delete(edit.recordId);
|
|
18099
|
+
}
|
|
18100
|
+
const record = document2.getMap(name);
|
|
18101
|
+
if (Object.hasOwn(edit, "replace"))
|
|
18102
|
+
writeValue(record, "value", edit.replace, name, author);
|
|
18103
|
+
if (edit.asset !== undefined && canonicalJson(record.get("asset") ?? null) !== canonicalJson(edit.asset))
|
|
18104
|
+
record.set("asset", structuredClone(edit.asset));
|
|
18105
|
+
for (const shared of edit.shared ?? []) {
|
|
18106
|
+
const apply = () => applyShared(document2, record, name, shared, author);
|
|
18107
|
+
if (author)
|
|
18108
|
+
author(name, "shared", shared, apply);
|
|
18109
|
+
else
|
|
18110
|
+
apply();
|
|
17478
18111
|
}
|
|
17479
18112
|
};
|
|
17480
|
-
|
|
17481
|
-
|
|
17482
|
-
|
|
17483
|
-
|
|
17484
|
-
|
|
17485
|
-
|
|
17486
|
-
|
|
17487
|
-
|
|
17488
|
-
|
|
18113
|
+
|
|
18114
|
+
// ../pstdio-sync/src/document-validation.ts
|
|
18115
|
+
var sequenceRange = (index, count, length) => {
|
|
18116
|
+
if (!Number.isSafeInteger(index) || index < 0 || index > length || !Number.isSafeInteger(count) || count < 0 || index + count > length)
|
|
18117
|
+
throw new Error("Shared edit is outside the current sequence");
|
|
18118
|
+
};
|
|
18119
|
+
var validateSequence = (value, shared) => {
|
|
18120
|
+
switch (shared.kind) {
|
|
18121
|
+
case "text.insert":
|
|
18122
|
+
case "text.delete": {
|
|
18123
|
+
const text = typeof value === "string" ? value : "";
|
|
18124
|
+
const count = shared.kind === "text.delete" ? shared.count : 0;
|
|
18125
|
+
sequenceRange(shared.index, count, text.length);
|
|
18126
|
+
return text.slice(0, shared.index) + (shared.kind === "text.insert" ? shared.text : "") + text.slice(shared.index + count);
|
|
18127
|
+
}
|
|
18128
|
+
case "list.insert":
|
|
18129
|
+
case "list.delete": {
|
|
18130
|
+
const list = Array.isArray(value) ? value : [];
|
|
18131
|
+
const count = shared.kind === "list.delete" ? shared.count : 0;
|
|
18132
|
+
sequenceRange(shared.index, count, list.length);
|
|
18133
|
+
list.splice(shared.index, count, ...shared.kind === "list.insert" ? shared.values : []);
|
|
18134
|
+
return list;
|
|
17489
18135
|
}
|
|
18136
|
+
default:
|
|
18137
|
+
return value;
|
|
18138
|
+
}
|
|
18139
|
+
};
|
|
18140
|
+
var validateEdit = (document2, edit) => {
|
|
18141
|
+
if (!Object.hasOwn(edit, "replace") && edit.asset === undefined && edit.deleted === undefined && !edit.shared?.length)
|
|
18142
|
+
throw new Error("Empty record edit");
|
|
18143
|
+
if (Object.hasOwn(edit, "replace"))
|
|
18144
|
+
canonicalJson(edit.replace);
|
|
18145
|
+
const name = document2.getMap("records").get(edit.recordId);
|
|
18146
|
+
const record = name ? document2.getMap(name) : undefined;
|
|
18147
|
+
let kind = record?.get("sharedKind");
|
|
18148
|
+
let value = record ? readValue(record.get("shared"), document2) : null;
|
|
18149
|
+
for (const shared of edit.shared ?? []) {
|
|
18150
|
+
const nextKind = shared.kind.split(".")[0];
|
|
18151
|
+
if (kind && kind !== nextKind)
|
|
18152
|
+
throw new Error("One shared primitive per record");
|
|
18153
|
+
kind = nextKind;
|
|
18154
|
+
value = validateSequence(value, shared);
|
|
18155
|
+
}
|
|
18156
|
+
};
|
|
18157
|
+
var validateDocumentGroup = (document2, group) => {
|
|
18158
|
+
if (!group.operationId || !group.edits.length)
|
|
18159
|
+
throw new Error("Empty storage commit");
|
|
18160
|
+
const seen = new Set;
|
|
18161
|
+
for (const edit of group.edits) {
|
|
18162
|
+
if (!edit.recordId || seen.has(edit.recordId))
|
|
18163
|
+
throw new Error("A commit must name each record once");
|
|
18164
|
+
seen.add(edit.recordId);
|
|
18165
|
+
validateEdit(document2, edit);
|
|
17490
18166
|
}
|
|
17491
|
-
for (const record of Object.values(snapshot.records))
|
|
17492
|
-
if (record.asset)
|
|
17493
|
-
references.set(canonicalJson(record.asset), { asset: record.asset, required: true });
|
|
17494
|
-
for (const { asset, required } of references.values())
|
|
17495
|
-
await downloadAsset(local, adapter, asset, required);
|
|
17496
18167
|
};
|
|
17497
18168
|
|
|
17498
|
-
// ../pstdio-sync/src/
|
|
17499
|
-
var
|
|
17500
|
-
|
|
17501
|
-
|
|
17502
|
-
|
|
17503
|
-
|
|
17504
|
-
|
|
17505
|
-
|
|
17506
|
-
|
|
17507
|
-
|
|
17508
|
-
|
|
17509
|
-
|
|
17510
|
-
|
|
17511
|
-
|
|
17512
|
-
|
|
18169
|
+
// ../pstdio-sync/src/document-storage.ts
|
|
18170
|
+
var outcome = (operationId) => ({
|
|
18171
|
+
operationId,
|
|
18172
|
+
state: "saved-locally",
|
|
18173
|
+
status: "saved-locally"
|
|
18174
|
+
});
|
|
18175
|
+
var readRecord = async (document2, recordId) => {
|
|
18176
|
+
const name = document2.getMap("records").get(recordId);
|
|
18177
|
+
const record = name ? document2.getMap(name) : undefined;
|
|
18178
|
+
const deleted = !record && document2.getMap("deleted").has(recordId);
|
|
18179
|
+
const shared = record?.get("sharedKind");
|
|
18180
|
+
const value = record ? readValue(record.get("value"), document2) : null;
|
|
18181
|
+
const asset = structuredClone(record?.get("asset") ?? null);
|
|
18182
|
+
const sharedValue = shared ? { kind: shared, value: readValue(record?.get("shared"), document2) } : null;
|
|
18183
|
+
return {
|
|
18184
|
+
recordId,
|
|
18185
|
+
exists: !!record || deleted,
|
|
18186
|
+
deleted,
|
|
18187
|
+
value,
|
|
18188
|
+
asset,
|
|
18189
|
+
shared: sharedValue,
|
|
18190
|
+
revision: await fingerprint({ value, asset, shared: sharedValue, deleted })
|
|
17513
18191
|
};
|
|
17514
|
-
await receive();
|
|
17515
|
-
const pending = await input.store.transaction(input.owner, async (state) => Promise.all(pendingOperations(state, input.environmentId).map(async (operation) => ({
|
|
17516
|
-
mutation: await sealOperation(state, operation),
|
|
17517
|
-
proof: state.journal.find((entry) => entry.mutation.operationId === operation.operationId)?.recoveryProof
|
|
17518
|
-
}))));
|
|
17519
|
-
const outcomes = [];
|
|
17520
|
-
for (const { mutation, proof } of pending) {
|
|
17521
|
-
await uploadMutationAssets(input.assets, adapter, mutation);
|
|
17522
|
-
const foreignRecovery = mutation.environmentId !== input.environmentId && adapter.recover;
|
|
17523
|
-
if (foreignRecovery && !proof)
|
|
17524
|
-
throw new Error("Relay recovery proof is unavailable for a retained operation");
|
|
17525
|
-
const receipt = receiptSchema.parse(foreignRecovery ? await foreignRecovery(mutation, proof) : await adapter.submit(mutation));
|
|
17526
|
-
await validateMutation(receipt.mutation);
|
|
17527
|
-
if (receipt.operationId !== mutation.operationId || receipt.fingerprint !== mutation.fingerprint)
|
|
17528
|
-
throw new Error("Relay receipt differs from the submitted operation");
|
|
17529
|
-
await input.store.transaction(input.owner, async (state) => {
|
|
17530
|
-
const entry = state.journal.find((entry) => entry.mutation.operationId === mutation.operationId);
|
|
17531
|
-
retainAcceptance(entry, receipt);
|
|
17532
|
-
});
|
|
17533
|
-
outcomes.push(receipt);
|
|
17534
|
-
}
|
|
17535
|
-
await receive();
|
|
17536
|
-
return input.store.transaction(input.owner, async (state) => {
|
|
17537
|
-
const conflicts = Object.values(state.accepted?.conflicts ?? {}).some((conflict) => !conflict.resolvedBy);
|
|
17538
|
-
if (conflicts)
|
|
17539
|
-
return { status: "conflict", outcomes };
|
|
17540
|
-
if (pendingOperations(state, input.environmentId).length)
|
|
17541
|
-
return { status: "pending", outcomes };
|
|
17542
|
-
return { status: "synchronized", outcomes };
|
|
17543
|
-
});
|
|
17544
18192
|
};
|
|
17545
|
-
|
|
17546
|
-
|
|
17547
|
-
|
|
17548
|
-
|
|
17549
|
-
|
|
18193
|
+
var createDocumentStorage = (input) => {
|
|
18194
|
+
const { owner, store } = input;
|
|
18195
|
+
const observed = async (document2, id) => {
|
|
18196
|
+
const record = await readRecord(document2, id);
|
|
18197
|
+
store.observer?.read(owner, record);
|
|
17550
18198
|
return record;
|
|
17551
18199
|
};
|
|
17552
18200
|
return {
|
|
17553
|
-
|
|
17554
|
-
|
|
17555
|
-
const
|
|
17556
|
-
return
|
|
17557
|
-
...snapshot,
|
|
17558
|
-
pending: pendingOperations(snapshot, input.environmentId),
|
|
17559
|
-
working: workingRecords(snapshot, input.environmentId)
|
|
17560
|
-
};
|
|
18201
|
+
dataVersion: (scope) => store.transaction(owner, async ({ document: document2 }) => {
|
|
18202
|
+
const prefix = `${JSON.stringify([scope]).slice(0, -1)},`;
|
|
18203
|
+
const versions = [...document2.getMap("data-migrations").keys()].filter((key) => key.startsWith(prefix));
|
|
18204
|
+
return Math.max(0, ...versions.map((key) => JSON.parse(key)[1]));
|
|
17561
18205
|
}),
|
|
17562
|
-
|
|
17563
|
-
|
|
17564
|
-
if (!entry)
|
|
17565
|
-
throw new Error("Operation not found");
|
|
17566
|
-
return sealOperation(state, entry.mutation);
|
|
18206
|
+
setDataVersion: (scope, version) => store.transaction(owner, async ({ document: document2 }) => {
|
|
18207
|
+
document2.getMap("data-migrations").set(JSON.stringify([scope, version]), true);
|
|
17567
18208
|
}),
|
|
18209
|
+
exportUpdate: () => store.transaction(owner, async ({ document: document2 }) => encodeStateAsUpdate(document2)),
|
|
18210
|
+
applyUpdate: (update) => store.transaction(owner, async ({ document: document2 }) => {
|
|
18211
|
+
applyUpdate(document2, update);
|
|
18212
|
+
}),
|
|
18213
|
+
capture: async (action) => {
|
|
18214
|
+
const update = await store.transaction(owner, async ({ document: document2 }) => encodeStateAsUpdate(document2));
|
|
18215
|
+
const snapshot = new Doc2;
|
|
18216
|
+
applyUpdate(snapshot, update);
|
|
18217
|
+
try {
|
|
18218
|
+
return await captureCheckpoint(snapshot, owner, action, store.observer);
|
|
18219
|
+
} finally {
|
|
18220
|
+
snapshot.destroy();
|
|
18221
|
+
}
|
|
18222
|
+
},
|
|
17568
18223
|
records: {
|
|
17569
|
-
|
|
17570
|
-
|
|
17571
|
-
|
|
17572
|
-
|
|
17573
|
-
|
|
17574
|
-
|
|
17575
|
-
|
|
17576
|
-
|
|
17577
|
-
|
|
17578
|
-
throw new Error("Operation identity reused with changed payload");
|
|
17579
|
-
if (!previous) {
|
|
17580
|
-
const entry = await resolutionEntry(state, proposal, input.environmentId);
|
|
17581
|
-
localOperationSchema.parse(entry.mutation);
|
|
17582
|
-
state.journal.push(entry);
|
|
17583
|
-
}
|
|
17584
|
-
return (await projectGroups(state, input.environmentId)).outcomes.get(proposal.operationId);
|
|
17585
|
-
}),
|
|
17586
|
-
read: (recordId, options) => input.store.transaction(input.owner, async (state) => {
|
|
17587
|
-
if (!options)
|
|
17588
|
-
return readRecord((await projectGroups(state, input.environmentId)).read(recordId));
|
|
17589
|
-
return readBranch(state, input.environmentId, recordId, options.operationId);
|
|
17590
|
-
}),
|
|
17591
|
-
conflicts: () => input.store.transaction(input.owner, async (state) => (await projectGroups(state, input.environmentId)).conflicts.map(({ conflictId, revision, reason, recordIds, alternativeOperationIds }) => ({
|
|
17592
|
-
conflictId,
|
|
17593
|
-
revision,
|
|
17594
|
-
reason,
|
|
17595
|
-
recordIds,
|
|
17596
|
-
alternativeOperationIds
|
|
17597
|
-
}))),
|
|
17598
|
-
commit: async (proposal) => {
|
|
17599
|
-
const group = input.store.observer?.group(input.owner, proposal) ?? proposal;
|
|
18224
|
+
read: (id, _branch) => store.transaction(owner, async ({ document: document2 }) => observed(document2, id)),
|
|
18225
|
+
list: (prefix = "") => store.transaction(owner, async ({ document: document2 }) => Promise.all([...document2.getMap("records").keys()].filter((id) => id.startsWith(prefix)).sort().map((id) => observed(document2, id)))),
|
|
18226
|
+
outcome: (id) => store.transaction(owner, async (state) => await state.operation(id) ? outcome(id) : undefined),
|
|
18227
|
+
conflicts: async () => [],
|
|
18228
|
+
inspect: (_id) => Promise.reject(new Error("Records merge automatically; there are no conflicts to inspect")),
|
|
18229
|
+
resolve: (_proposal) => Promise.reject(new Error("Records merge automatically; there are no conflicts to resolve")),
|
|
18230
|
+
commit: async (group) => {
|
|
18231
|
+
if (!group.edits.length)
|
|
18232
|
+
throw new Error("Empty storage commit");
|
|
17600
18233
|
const assets = group.edits.flatMap((edit) => edit.asset ? [edit.asset] : []);
|
|
17601
18234
|
if (assets.length) {
|
|
17602
18235
|
if (!input.assets)
|
|
17603
18236
|
throw new Error("Asset verification is unavailable");
|
|
17604
18237
|
await input.assets.verifyComplete(assets);
|
|
17605
18238
|
}
|
|
17606
|
-
|
|
17607
|
-
|
|
17608
|
-
|
|
18239
|
+
const identity = await fingerprint(group.edits.map(({ expectedRevision: _revision, ...edit }) => edit));
|
|
18240
|
+
const saved = await store.transaction(owner, async (state) => {
|
|
18241
|
+
const doc = state.document;
|
|
18242
|
+
const previous = await state.operation(group.operationId);
|
|
18243
|
+
if (previous !== undefined && previous !== identity)
|
|
17609
18244
|
throw new Error("Operation identity reused with changed payload");
|
|
17610
|
-
if (
|
|
17611
|
-
|
|
17612
|
-
|
|
17613
|
-
|
|
18245
|
+
if (previous === undefined) {
|
|
18246
|
+
validateDocumentGroup(doc, group);
|
|
18247
|
+
const author = migrationAuthor(doc, state.migrationSeed, state.migrationHistory);
|
|
18248
|
+
doc.transact(() => {
|
|
18249
|
+
for (const edit of group.edits)
|
|
18250
|
+
applyDocumentEdit(doc, edit, author);
|
|
18251
|
+
});
|
|
17614
18252
|
}
|
|
17615
|
-
|
|
17616
|
-
|
|
17617
|
-
input.store.observer?.committed(input.owner, group.edits.map((edit) => view.read(edit.recordId)), outcome);
|
|
17618
|
-
return outcome;
|
|
18253
|
+
state.remember(group.operationId, identity);
|
|
18254
|
+
return Promise.all(group.edits.map((edit) => readRecord(doc, edit.recordId)));
|
|
17619
18255
|
});
|
|
18256
|
+
const result = outcome(group.operationId);
|
|
18257
|
+
store.observer?.committed(owner, saved, result);
|
|
18258
|
+
return result;
|
|
17620
18259
|
}
|
|
17621
18260
|
}
|
|
17622
18261
|
};
|
|
17623
18262
|
};
|
|
18263
|
+
// ../pstdio-sync/src/encryption/sealing.ts
|
|
18264
|
+
var headerLength = 1 + 4 + 12;
|
|
18265
|
+
|
|
18266
|
+
// ../pstdio-sync/src/encryption/space.ts
|
|
18267
|
+
var encoder = new TextEncoder;
|
|
18268
|
+
// ../pstdio-sync/src/namespaces.ts
|
|
18269
|
+
var storageRecordId = (namespace, recordId) => JSON.stringify([...namespace, recordId]);
|
|
18270
|
+
var scopeRecordStorage = (records, namespace) => {
|
|
18271
|
+
return { id: (key) => storageRecordId(namespace, key), ...records };
|
|
18272
|
+
};
|
|
18273
|
+
var legacyNamespaceStorage = (records, namespace) => {
|
|
18274
|
+
const prefix = `${JSON.stringify(namespace).slice(0, -1)},`;
|
|
18275
|
+
const storedId = (id) => storageRecordId(namespace, id);
|
|
18276
|
+
return {
|
|
18277
|
+
read: (id) => records.read(storedId(id)),
|
|
18278
|
+
list: async () => (await records.list(prefix)).map((record) => ({
|
|
18279
|
+
...record,
|
|
18280
|
+
recordId: JSON.parse(record.recordId).at(-1)
|
|
18281
|
+
})),
|
|
18282
|
+
commit: (group) => records.commit({
|
|
18283
|
+
...group,
|
|
18284
|
+
edits: group.edits.map((edit) => ({ ...edit, recordId: storedId(edit.recordId) }))
|
|
18285
|
+
})
|
|
18286
|
+
};
|
|
18287
|
+
};
|
|
17624
18288
|
|
|
17625
18289
|
// ../pstdio-sync/src/legacy.ts
|
|
17626
18290
|
var legacyJson = (value) => JSON.parse(JSON.stringify(value));
|
|
17627
18291
|
var createLegacyRecordStorage = (input) => {
|
|
17628
|
-
const within = (namespace, action) => input.store.transaction(input.owner, (state) => action(legacyNamespaceStorage(
|
|
18292
|
+
const within = (namespace, action) => input.store.transaction(input.owner, (state) => action(legacyNamespaceStorage(createDocumentStorage({
|
|
17629
18293
|
...input,
|
|
17630
18294
|
store: { transaction: async (_owner, run) => run(state), observer: input.store.observer }
|
|
17631
18295
|
}).records, namespace)));
|
|
17632
18296
|
const namespaceApi = (namespace) => {
|
|
18297
|
+
const current = legacyNamespaceStorage(createDocumentStorage(input).records, namespace);
|
|
17633
18298
|
const read = (records, id) => records.read(id);
|
|
17634
18299
|
const replace = async (records, id, value, deleted = false) => {
|
|
17635
18300
|
const current = await read(records, id);
|
|
@@ -17646,11 +18311,10 @@ var createLegacyRecordStorage = (input) => {
|
|
|
17646
18311
|
});
|
|
17647
18312
|
};
|
|
17648
18313
|
return {
|
|
17649
|
-
get: (id) =>
|
|
17650
|
-
const record = await read(records, id);
|
|
18314
|
+
get: (id) => current.read(id).then((record) => {
|
|
17651
18315
|
return record.exists && !record.deleted ? record.value : undefined;
|
|
17652
18316
|
}),
|
|
17653
|
-
list: () =>
|
|
18317
|
+
list: () => current.list(),
|
|
17654
18318
|
set: (id, value) => within(namespace, (records) => replace(records, id, value)),
|
|
17655
18319
|
createIfAbsent: (id, value) => within(namespace, async (records) => {
|
|
17656
18320
|
const current = await read(records, id);
|
|
@@ -17736,31 +18400,49 @@ var createLegacyRecordStorage = (input) => {
|
|
|
17736
18400
|
}
|
|
17737
18401
|
};
|
|
17738
18402
|
};
|
|
17739
|
-
// src/
|
|
17740
|
-
var
|
|
17741
|
-
const
|
|
17742
|
-
const
|
|
17743
|
-
let state = { owner, accepted: null, journal: [] };
|
|
18403
|
+
// ../pstdio-sync/src/memory-document-store.ts
|
|
18404
|
+
var createMemoryDocumentStore = () => {
|
|
18405
|
+
const document2 = new Doc2;
|
|
18406
|
+
const state = memoryDocumentState(document2);
|
|
17744
18407
|
let previous = Promise.resolve();
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17750
|
-
|
|
17751
|
-
|
|
18408
|
+
let previousMigration = Promise.resolve();
|
|
18409
|
+
const transaction = async (_owner, action) => {
|
|
18410
|
+
const pending = previous;
|
|
18411
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
18412
|
+
previous = promise;
|
|
18413
|
+
await pending;
|
|
18414
|
+
try {
|
|
18415
|
+
return await action(state);
|
|
18416
|
+
} finally {
|
|
18417
|
+
resolve();
|
|
18418
|
+
}
|
|
18419
|
+
};
|
|
18420
|
+
return {
|
|
18421
|
+
transaction,
|
|
18422
|
+
async duringMigration(key, run) {
|
|
18423
|
+
const pending = previousMigration;
|
|
18424
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
18425
|
+
previousMigration = promise;
|
|
17752
18426
|
await pending;
|
|
18427
|
+
const previousSeed = state.migrationSeed;
|
|
18428
|
+
const previousHistory = state.migrationHistory;
|
|
18429
|
+
state.migrationSeed = key;
|
|
18430
|
+
state.migrationHistory = documentHistory(document2);
|
|
17753
18431
|
try {
|
|
17754
|
-
|
|
17755
|
-
const result = await action(draft);
|
|
17756
|
-
state = draft;
|
|
17757
|
-
return result;
|
|
18432
|
+
return await run();
|
|
17758
18433
|
} finally {
|
|
17759
|
-
|
|
18434
|
+
state.migrationSeed = previousSeed;
|
|
18435
|
+
state.migrationHistory = previousHistory;
|
|
18436
|
+
resolve();
|
|
17760
18437
|
}
|
|
17761
18438
|
}
|
|
17762
18439
|
};
|
|
17763
|
-
|
|
18440
|
+
};
|
|
18441
|
+
// src/testing/memory-record-owner.ts
|
|
18442
|
+
var createMemoryRecordOwner = (assets, seed = {}) => {
|
|
18443
|
+
const owner = { workbenchId: crypto.randomUUID(), extensionId: "test-extension" };
|
|
18444
|
+
const baseStore = createMemoryDocumentStore();
|
|
18445
|
+
const seedStorage = createLegacyRecordStorage({ store: baseStore, owner }).scope("project", owner.workbenchId);
|
|
17764
18446
|
const initialized = Promise.all([
|
|
17765
18447
|
...Object.entries(seed.kv ?? {}).map(([key, value]) => seedStorage.kv.set(key, value)),
|
|
17766
18448
|
...Object.entries(seed.collections ?? {}).flatMap(([name, items]) => Object.entries(items).map(([id, value]) => seedStorage.collection(name).set(id, value)))
|
|
@@ -17771,10 +18453,9 @@ var createMemoryRecordOwner = (assets, seed = {}) => {
|
|
|
17771
18453
|
return baseStore.transaction(target, action);
|
|
17772
18454
|
}
|
|
17773
18455
|
};
|
|
17774
|
-
const storage =
|
|
18456
|
+
const storage = createDocumentStorage({
|
|
17775
18457
|
store,
|
|
17776
18458
|
owner,
|
|
17777
|
-
environmentId,
|
|
17778
18459
|
assets: {
|
|
17779
18460
|
verifyComplete: assets.verifyComplete,
|
|
17780
18461
|
read: assets.read,
|
|
@@ -17783,9 +18464,15 @@ var createMemoryRecordOwner = (assets, seed = {}) => {
|
|
|
17783
18464
|
}
|
|
17784
18465
|
}
|
|
17785
18466
|
});
|
|
17786
|
-
const legacy = createLegacyRecordStorage({ store, owner
|
|
18467
|
+
const legacy = createLegacyRecordStorage({ store, owner });
|
|
17787
18468
|
return {
|
|
17788
18469
|
workbenchId: owner.workbenchId,
|
|
18470
|
+
dataVersion: storage.dataVersion,
|
|
18471
|
+
setDataVersion: storage.setDataVersion,
|
|
18472
|
+
duringMigration: async (key, run) => {
|
|
18473
|
+
await initialized;
|
|
18474
|
+
return baseStore.duringMigration(key, run);
|
|
18475
|
+
},
|
|
17789
18476
|
scope: (type, id) => ({
|
|
17790
18477
|
records: scopeRecordStorage(storage.records, [type, id, "kv"]),
|
|
17791
18478
|
legacy: legacy.scope(type, id)
|
|
@@ -17803,12 +18490,9 @@ var createMemoryStorage = (options = {}) => {
|
|
|
17803
18490
|
const existing = migrations.get(scope);
|
|
17804
18491
|
if (existing)
|
|
17805
18492
|
return existing;
|
|
17806
|
-
let version = 0;
|
|
17807
18493
|
const migrate = createDataMigrationRunner({
|
|
17808
|
-
readVersion:
|
|
17809
|
-
writeVersion:
|
|
17810
|
-
version = next;
|
|
17811
|
-
}
|
|
18494
|
+
readVersion: () => owner.dataVersion(scope),
|
|
18495
|
+
writeVersion: (next) => owner.setDataVersion(scope, next)
|
|
17812
18496
|
});
|
|
17813
18497
|
migrations.set(scope, migrate);
|
|
17814
18498
|
return migrate;
|
|
@@ -17868,7 +18552,7 @@ var createMemoryStorage = (options = {}) => {
|
|
|
17868
18552
|
const { records, legacy } = owner.scope(scopeType, scopeId);
|
|
17869
18553
|
const blobKey = JSON.stringify([scopeType, scopeId]);
|
|
17870
18554
|
const api = {
|
|
17871
|
-
migrate: migrateFor(blobKey),
|
|
18555
|
+
migrate: (version, run) => migrateFor(blobKey)(version, (previous) => owner.duringMigration(JSON.stringify(["test-extension", scopeType, scopeId, version]), () => run(previous))),
|
|
17872
18556
|
readLegacy: async (source) => structuredClone(options.legacyData?.[source]),
|
|
17873
18557
|
records,
|
|
17874
18558
|
assets,
|