@pipeup/share 0.6.0 → 0.7.0-beta.2
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/cli.js +219 -94
- package/dist/pipeup+share.min.js +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -166,48 +166,82 @@ function n(e3) {
|
|
|
166
166
|
}
|
|
167
167
|
var a = /^[A-Za-z0-9_-]{43}$/;
|
|
168
168
|
var s = /* @__PURE__ */ new Map();
|
|
169
|
-
async function
|
|
169
|
+
async function l() {
|
|
170
170
|
let t2 = await crypto.subtle.generateKey({ name: "Ed25519" }, false, ["sign", "verify"]);
|
|
171
171
|
return { publicKey: e(new Uint8Array(await crypto.subtle.exportKey("raw", t2.publicKey))), privateKey: t2.privateKey };
|
|
172
172
|
}
|
|
173
|
-
async function
|
|
173
|
+
async function d(t2, r2) {
|
|
174
174
|
let n2 = await crypto.subtle.sign({ name: "Ed25519" }, t2.privateKey, r2);
|
|
175
175
|
return e(new Uint8Array(n2));
|
|
176
176
|
}
|
|
177
|
-
var u =
|
|
178
|
-
|
|
179
|
-
var c =
|
|
180
|
-
var
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
177
|
+
var u = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
178
|
+
Uint8Array.from([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
|
|
179
|
+
var c = ["Otter", "Fox", "Owl", "Bear", "Rabbit"];
|
|
180
|
+
var h = ["Red", "Orange", "Yellow", "Green", "Teal", "Blue", "Purple", "Pink", "Brown", "Grey"];
|
|
181
|
+
function p(e3) {
|
|
182
|
+
let t2 = 2166136261;
|
|
183
|
+
for (let r2 = 0; r2 < e3.length; r2++) t2 = Math.imul(t2 ^ e3.charCodeAt(r2), 16777619);
|
|
184
|
+
return t2 = Math.imul(t2 ^ t2 >>> 16, 2246822507), t2 = Math.imul(t2 ^ t2 >>> 13, 3266489909), (t2 ^ t2 >>> 16) >>> 0;
|
|
185
|
+
}
|
|
186
|
+
var f = (e3) => `${h[((e4) => Math.floor(p(e4) / c.length) % h.length)(e3)]} ${c[((e4) => p(e4) % c.length)(e3)]}`;
|
|
187
|
+
var m = (e3) => {
|
|
188
|
+
let t2 = e3.name.replace(/^AI assistant · /, "") || f(e3.author);
|
|
189
|
+
return e3.alike ? `${t2} \xB7 ${(function(e4) {
|
|
190
|
+
let t3 = p(`id:${e4}`), r2 = "";
|
|
191
|
+
for (let e5 = 0; e5 < 4; e5++, t3 >>>= 5) r2 += "0123456789ABCDEFGHJKMNPQRSTVWXYZ"[31 & t3];
|
|
192
|
+
return r2;
|
|
193
|
+
})(e3.author)}` : t2;
|
|
194
|
+
};
|
|
195
|
+
var g = "AI assistant";
|
|
196
|
+
var y = (e3) => e3 === g || e3.startsWith(`${g} `);
|
|
197
|
+
var w = 1e4;
|
|
198
|
+
var b = 2 ** 40;
|
|
199
|
+
var x = 2 ** 47;
|
|
200
|
+
var v = 1e4;
|
|
201
|
+
var k = /^[0-9a-f]{8}$/;
|
|
202
|
+
var A = /^[A-Za-z0-9_-]{43}$/;
|
|
203
|
+
var E = /^(?:[^\s@<>"]{1,64}@[^\s@<>"]{1,190}\.[^\s@<>"]{2,24}|gh:[A-Za-z0-9-]{1,39})$/;
|
|
204
|
+
var $ = /^(?:[A-Za-z0-9_-]{43}|(?:host|gh):[A-Za-z0-9._@-]{1,64})$/;
|
|
205
|
+
var M = /^[A-Za-z0-9_-]{43}$/;
|
|
206
|
+
var S = /* @__PURE__ */ new Set(["create", "reply", "edit", "delete", "resolve", "reopen", "addressed", "react", "unreact", "seen", "contact", "uncontact"]);
|
|
207
|
+
var C = /^(?:\p{Regional_Indicator}{2}|[#*0-9]\uFE0F?\u20E3|\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier})?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\p{Emoji_Modifier})?)*)$/u;
|
|
208
|
+
var N = (e3) => "string" == typeof e3 && C.test(e3) && [...e3].length <= 16;
|
|
209
|
+
async function O(e3, t2) {
|
|
186
210
|
if (e3.author !== t2.publicKey) throw new Error("pipeup: an op must be signed by its author");
|
|
187
|
-
return { body: e3, sig: await
|
|
211
|
+
return { body: e3, sig: await d(t2, r(n(e3))) };
|
|
188
212
|
}
|
|
189
|
-
var
|
|
190
|
-
var
|
|
191
|
-
var
|
|
192
|
-
function
|
|
193
|
-
if (!
|
|
213
|
+
var P2 = (e3, t2) => "string" == typeof e3 && e3.length <= t2;
|
|
214
|
+
var q = (e3) => !!e3 && "object" == typeof e3;
|
|
215
|
+
var j = (e3) => "number" == typeof e3 && Number.isFinite(e3) && e3 >= 0 && e3 <= 1;
|
|
216
|
+
function T(e3) {
|
|
217
|
+
if (!q(e3)) return false;
|
|
194
218
|
let { id: t2, path: r2, fingerprint: n2, snapshot: i, quote: o, point: a2, view: s2 } = e3;
|
|
195
|
-
if (!(
|
|
219
|
+
if (!(P2(r2, 2e3) && P2(i, 500) && "string" == typeof n2 && k.test(n2) && (void 0 === t2 || P2(t2, 200) && "" !== t2) && (void 0 === o || q(o) && P2(o.exact, v) && "" !== o.exact && P2(o.prefix, 64) && P2(o.suffix, 64)) && (void 0 === a2 || q(a2) && j(a2.x) && j(a2.y)))) return false;
|
|
196
220
|
if (void 0 !== s2) {
|
|
197
|
-
if (!
|
|
221
|
+
if (!q(s2) || Array.isArray(s2)) return false;
|
|
198
222
|
let e4 = Object.entries(s2);
|
|
199
|
-
if (e4.length > 16 || !e4.every(([e5, t3]) => e5.length <= 64 &&
|
|
223
|
+
if (e4.length > 16 || !e4.every(([e5, t3]) => e5.length <= 64 && P2(t3, 200))) return false;
|
|
200
224
|
}
|
|
201
225
|
return true;
|
|
202
226
|
}
|
|
203
|
-
function
|
|
204
|
-
if (!
|
|
227
|
+
function I(e3) {
|
|
228
|
+
if (!q(e3)) return false;
|
|
205
229
|
let { body: t2, sig: r2 } = e3;
|
|
206
|
-
if ("string" != typeof r2 || !
|
|
230
|
+
if ("string" != typeof r2 || !q(t2) || JSON.stringify({ body: t2, sig: r2 }).length > 262144) return false;
|
|
207
231
|
let n2 = t2;
|
|
208
|
-
|
|
232
|
+
if (1 !== n2.v || "string" != typeof n2.id || !A.test(n2.id) || !S.has(n2.kind) || !P2(n2.doc, 64) || "" === n2.doc || "string" != typeof n2.thread || !A.test(n2.thread) || "string" != typeof n2.author || !M.test(n2.author) || "string" != typeof n2.name || n2.name.length > 80 || n2.name !== n2.name.trim() || "number" != typeof n2.clock || !Number.isSafeInteger(n2.clock) || n2.clock < 1 || n2.clock > b || "number" != typeof n2.at || !Number.isSafeInteger(n2.at) || n2.at < 0 || n2.at > x || void 0 !== n2.text && (!P2(n2.text, w) || n2.text !== n2.text.trim()) || void 0 !== n2.target && ("string" != typeof n2.target || !A.test(n2.target)) || ("create" === n2.kind || "reply" === n2.kind || "edit" === n2.kind || "addressed" === n2.kind) && !n2.text || ("reply" === n2.kind || "edit" === n2.kind || "delete" === n2.kind) && !n2.target) return false;
|
|
233
|
+
if (void 0 !== n2.mentions) {
|
|
234
|
+
if ("create" !== n2.kind && "reply" !== n2.kind && "edit" !== n2.kind || !Array.isArray(n2.mentions) || n2.mentions.length > 20) return false;
|
|
235
|
+
let e4 = n2.text?.length ?? 0;
|
|
236
|
+
for (let t3 of n2.mentions) {
|
|
237
|
+
if (!q(t3) || !Number.isSafeInteger(t3.start) || !Number.isSafeInteger(t3.end)) return false;
|
|
238
|
+
let { start: r3, end: n3, ref: i } = t3;
|
|
239
|
+
if (r3 < 0 || n3 <= r3 || n3 > e4 || "string" != typeof i || !$.test(i)) return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return !(!("contact" !== n2.kind || "string" == typeof n2.text && E.test(n2.text)) || "seen" === n2.kind && !n2.target || !("react" !== n2.kind && "unreact" !== n2.kind || n2.target && N(n2.text)) || !("create" !== n2.kind || n2.id === n2.thread && T(n2.anchor)));
|
|
209
243
|
}
|
|
210
|
-
function
|
|
244
|
+
function F(i) {
|
|
211
245
|
return (async function(r2, n2, i2) {
|
|
212
246
|
if (!a.test(r2)) return false;
|
|
213
247
|
try {
|
|
@@ -226,17 +260,18 @@ function E(i) {
|
|
|
226
260
|
}
|
|
227
261
|
})(i.body.author, r(n(i.body)), i.sig);
|
|
228
262
|
}
|
|
229
|
-
function
|
|
263
|
+
function D(e3, t2) {
|
|
230
264
|
return e3.body.clock !== t2.body.clock ? e3.body.clock - t2.body.clock : e3.body.at !== t2.body.at ? e3.body.at - t2.body.at : e3.body.author !== t2.body.author ? e3.body.author < t2.body.author ? -1 : 1 : e3.body.id !== t2.body.id ? e3.body.id < t2.body.id ? -1 : 1 : 0;
|
|
231
265
|
}
|
|
232
|
-
function
|
|
233
|
-
|
|
266
|
+
function R(e3, t2, r2, n2, i, o) {
|
|
267
|
+
let a2 = { id: e3, author: t2, name: r2, text: n2, at: i, edited: false, deleted: false, replies: [], reactions: [] };
|
|
268
|
+
return o?.length && (a2.mentions = o), a2;
|
|
234
269
|
}
|
|
235
|
-
async function
|
|
270
|
+
async function U(t2) {
|
|
236
271
|
let i = { ...t2, id: void 0, thread: "create" === t2.kind ? void 0 : t2.thread }, o = await crypto.subtle.digest("SHA-256", r(n(i)));
|
|
237
272
|
return e(new Uint8Array(o));
|
|
238
273
|
}
|
|
239
|
-
var
|
|
274
|
+
var K = class {
|
|
240
275
|
constructor(e3) {
|
|
241
276
|
this.doc = e3;
|
|
242
277
|
}
|
|
@@ -253,85 +288,113 @@ var C = class {
|
|
|
253
288
|
threads() {
|
|
254
289
|
return (function(e3) {
|
|
255
290
|
let t2 = /* @__PURE__ */ new Map(), r2 = /* @__PURE__ */ new Map(), n2 = /* @__PURE__ */ new Map();
|
|
256
|
-
for (let { body:
|
|
257
|
-
if (
|
|
258
|
-
if (t2.has(
|
|
259
|
-
let e5 =
|
|
260
|
-
t2.set(
|
|
291
|
+
for (let { body: i2 } of [...e3].sort(D)) {
|
|
292
|
+
if (i2.name && n2.set(i2.author, i2.name), "create" === i2.kind) {
|
|
293
|
+
if (t2.has(i2.id) || !i2.anchor || void 0 === i2.text) continue;
|
|
294
|
+
let e5 = R(i2.id, i2.author, i2.name, i2.text, i2.at, i2.mentions);
|
|
295
|
+
t2.set(i2.id, { id: i2.id, anchor: i2.anchor, root: e5, resolved: false }), r2.set(i2.id, { comment: e5, thread: i2.id });
|
|
261
296
|
continue;
|
|
262
297
|
}
|
|
263
|
-
let e4 = t2.get(
|
|
298
|
+
let e4 = t2.get(i2.thread);
|
|
264
299
|
if (!e4) continue;
|
|
265
|
-
if ("resolve" ===
|
|
266
|
-
e4.resolved = "resolve" ===
|
|
300
|
+
if ("resolve" === i2.kind || "reopen" === i2.kind) {
|
|
301
|
+
e4.resolved = "resolve" === i2.kind, "reopen" === i2.kind && delete e4.addressed;
|
|
267
302
|
continue;
|
|
268
303
|
}
|
|
269
|
-
if ("addressed" ===
|
|
270
|
-
void 0 !==
|
|
304
|
+
if ("addressed" === i2.kind) {
|
|
305
|
+
void 0 !== i2.text && (e4.addressed = { text: i2.text, author: i2.author, name: i2.name, at: i2.at });
|
|
271
306
|
continue;
|
|
272
307
|
}
|
|
273
|
-
let
|
|
274
|
-
if (
|
|
275
|
-
if ("reply" ===
|
|
276
|
-
if (r2.has(
|
|
277
|
-
let t3 =
|
|
278
|
-
e4.root.replies.push(t3), r2.set(
|
|
308
|
+
let o2 = i2.target ? r2.get(i2.target) : void 0;
|
|
309
|
+
if (o2 && o2.thread === i2.thread) {
|
|
310
|
+
if ("reply" === i2.kind) {
|
|
311
|
+
if (r2.has(i2.id) || void 0 === i2.text) continue;
|
|
312
|
+
let t3 = R(i2.id, i2.author, i2.name, i2.text, i2.at, i2.mentions);
|
|
313
|
+
e4.root.replies.push(t3), r2.set(i2.id, { comment: t3, thread: i2.thread });
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if ("seen" === i2.kind) {
|
|
317
|
+
let e5 = o2.comment.seenBy ??= [];
|
|
318
|
+
e5.includes(i2.author) || e5.push(i2.author);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if ("react" === i2.kind || "unreact" === i2.kind) {
|
|
322
|
+
if (void 0 === i2.text || o2.comment.deleted) continue;
|
|
323
|
+
let e5 = o2.comment.reactions, t3 = e5.find((e6) => e6.emoji === i2.text);
|
|
324
|
+
if ("react" === i2.kind) {
|
|
325
|
+
let r3 = { author: i2.author, name: i2.name };
|
|
326
|
+
t3 ? t3.by.some((e6) => e6.author === i2.author) || t3.by.push(r3) : e5.length < 12 && e5.push({ emoji: i2.text, by: [r3] });
|
|
327
|
+
} else t3 && (t3.by = t3.by.filter((e6) => e6.author !== i2.author), t3.by.length || e5.splice(e5.indexOf(t3), 1));
|
|
279
328
|
continue;
|
|
280
329
|
}
|
|
281
|
-
|
|
330
|
+
i2.author !== o2.comment.author || o2.comment.deleted || ("edit" === i2.kind && void 0 !== i2.text && (o2.comment.text = i2.text, o2.comment.edited = true, i2.mentions ? o2.comment.mentions = i2.mentions : delete o2.comment.mentions), "delete" === i2.kind && (o2.comment.text = "", o2.comment.deleted = true, o2.comment.reactions = [], delete o2.comment.mentions));
|
|
282
331
|
}
|
|
283
332
|
}
|
|
284
|
-
for (let { comment: e4 } of r2.values())
|
|
333
|
+
for (let { comment: e4 } of r2.values()) {
|
|
334
|
+
e4.name || (e4.unnamed = true, e4.name = n2.get(e4.author) ?? "");
|
|
335
|
+
for (let t3 of e4.reactions) for (let e5 of t3.by) e5.name ||= n2.get(e5.author) ?? "";
|
|
336
|
+
}
|
|
337
|
+
let i = /* @__PURE__ */ new Map(), o = (e4, t3) => {
|
|
338
|
+
let r3 = m({ author: e4, name: t3 }).toLowerCase();
|
|
339
|
+
(i.get(r3) ?? i.set(r3, /* @__PURE__ */ new Set()).get(r3)).add(e4);
|
|
340
|
+
};
|
|
341
|
+
for (let { comment: e4 } of r2.values()) {
|
|
342
|
+
o(e4.author, e4.name);
|
|
343
|
+
for (let t3 of e4.reactions) for (let e5 of t3.by) o(e5.author, e5.name);
|
|
344
|
+
}
|
|
345
|
+
let a2 = (e4, t3) => (i.get(m({ author: e4, name: t3 }).toLowerCase())?.size ?? 0) > 1;
|
|
346
|
+
for (let { comment: e4 } of r2.values()) {
|
|
347
|
+
a2(e4.author, e4.name) && (e4.alike = true);
|
|
348
|
+
for (let t3 of e4.reactions) for (let e5 of t3.by) a2(e5.author, e5.name) && (e5.alike = true);
|
|
349
|
+
}
|
|
285
350
|
return [...t2.values()];
|
|
286
351
|
})(this.ops.values());
|
|
287
352
|
}
|
|
288
353
|
async add(e3) {
|
|
289
354
|
let t2 = [];
|
|
290
355
|
for (let r2 of e3) {
|
|
291
|
-
if (!
|
|
356
|
+
if (!I(r2) || r2.body.doc !== this.doc || this.ops.has(r2.body.id) || r2.body.id !== await U(r2.body) || !await F(r2)) continue;
|
|
292
357
|
let e4 = { body: r2.body, sig: r2.sig };
|
|
293
358
|
this.ops.set(e4.body.id, e4), this.clock = Math.max(this.clock, e4.body.clock), "create" === e4.body.kind && this.createAt.set(e4.body.author, Math.max(this.createAt.get(e4.body.author) ?? 0, e4.body.at)), this.threadAt.set(e4.body.thread, Math.max(this.threadAt.get(e4.body.thread) ?? 0, e4.body.at)), t2.push(e4);
|
|
294
359
|
}
|
|
295
360
|
return t2;
|
|
296
361
|
}
|
|
297
362
|
async append(e3, t2, r2) {
|
|
298
|
-
let n2 = { v: 1, ...r2, id: "", thread: "create" === r2.kind ? "" : r2.thread, doc: this.doc, author: e3.publicKey, name: t2, clock: Math.min(this.clock + 1,
|
|
299
|
-
n2.id = await
|
|
363
|
+
let n2 = { v: 1, ...r2, id: "", thread: "create" === r2.kind ? "" : r2.thread, doc: this.doc, author: e3.publicKey, name: t2, clock: Math.min(this.clock + 1, b), at: Math.min(Math.max(Date.now(), "create" === r2.kind ? (this.createAt.get(e3.publicKey) ?? 0) + 1 : (this.threadAt.get(r2.thread) ?? 0) + 1), x) };
|
|
364
|
+
n2.id = await U(n2);
|
|
300
365
|
let i = this.ops.get(n2.id);
|
|
301
366
|
if (i) return i;
|
|
302
367
|
"create" === n2.kind && (n2.thread = n2.id);
|
|
303
|
-
let [o] = await this.add([await
|
|
368
|
+
let [o] = await this.add([await O(n2, e3)]);
|
|
304
369
|
if (!o) throw new Error("pipeup: could not record this change");
|
|
305
370
|
return o;
|
|
306
371
|
}
|
|
307
372
|
};
|
|
308
|
-
var
|
|
309
|
-
|
|
310
|
-
var D = /^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;
|
|
311
|
-
function F() {
|
|
373
|
+
var H = /^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;
|
|
374
|
+
function L() {
|
|
312
375
|
return `${(function(t2 = 16) {
|
|
313
376
|
return e(crypto.getRandomValues(new Uint8Array(t2)));
|
|
314
377
|
})(12)}:${e(crypto.getRandomValues(new Uint8Array(32)))}`;
|
|
315
378
|
}
|
|
316
|
-
async function
|
|
317
|
-
let r2 =
|
|
379
|
+
async function _(e3) {
|
|
380
|
+
let r2 = H.exec(e3.trim()), n2 = r2?.[1], i = r2?.[2];
|
|
318
381
|
if (!n2 || !i) throw new Error('pipeup: data-pipeup-doc must look like "<id>:<key>", as made by newDocumentAttribute()');
|
|
319
382
|
return { id: n2, key: await crypto.subtle.importKey("raw", t(i), { name: "AES-GCM" }, false, ["encrypt", "decrypt"]) };
|
|
320
383
|
}
|
|
321
|
-
async function
|
|
384
|
+
async function z(t2, n2, i) {
|
|
322
385
|
let o = crypto.getRandomValues(new Uint8Array(12)), a2 = await crypto.subtle.encrypt({ name: "AES-GCM", iv: o, additionalData: r(i) }, t2, r(n2));
|
|
323
386
|
return { iv: e(o), data: e(new Uint8Array(a2)) };
|
|
324
387
|
}
|
|
325
|
-
var
|
|
326
|
-
var
|
|
327
|
-
var
|
|
388
|
+
var B = (e3) => `pipeup-file:${e3}`;
|
|
389
|
+
var G = /^[a-z][a-z0-9-]{1,23}\/[a-z][a-z0-9-]{0,31}$/;
|
|
390
|
+
var Z = class extends Error {
|
|
328
391
|
constructor(e3, t2, r2 = 1) {
|
|
329
392
|
super("pipeup: shown here, but not saved yet"), this.id = e3, this.cause = t2, this.count = r2, this.name = "UnsavedChangeError";
|
|
330
393
|
}
|
|
331
394
|
};
|
|
332
|
-
var
|
|
395
|
+
var J = class e2 {
|
|
333
396
|
constructor(e3, t2) {
|
|
334
|
-
this.log = e3, this.options = t2, this.displayName = t2.name.trim() ?
|
|
397
|
+
this.log = e3, this.options = t2, this.displayName = t2.name.trim() ? Q(t2.name) : "";
|
|
335
398
|
}
|
|
336
399
|
listeners = /* @__PURE__ */ new Set();
|
|
337
400
|
cache = [];
|
|
@@ -341,7 +404,7 @@ var K = class e2 {
|
|
|
341
404
|
unsaved = [];
|
|
342
405
|
static async open(t2) {
|
|
343
406
|
if ("string" != typeof t2.doc || "" === t2.doc || t2.doc.length > 64) throw new Error("pipeup: the document id must be 1 to 64 characters");
|
|
344
|
-
let r2 = new
|
|
407
|
+
let r2 = new K(t2.doc), n2 = await t2.store.load(t2.doc), i = n2.length - (await r2.add(n2)).length;
|
|
345
408
|
i && console.warn(`pipeup: ${i} saved change${1 === i ? "" : "s"} on this page couldn't be read; kept as saved`);
|
|
346
409
|
let o = new e2(r2, t2);
|
|
347
410
|
return o.refresh(false), o;
|
|
@@ -356,7 +419,7 @@ var K = class e2 {
|
|
|
356
419
|
return this.displayName;
|
|
357
420
|
}
|
|
358
421
|
set name(e3) {
|
|
359
|
-
this.displayName =
|
|
422
|
+
this.displayName = Q(e3), this.refresh(true, [], "");
|
|
360
423
|
}
|
|
361
424
|
threads() {
|
|
362
425
|
return this.cache;
|
|
@@ -367,16 +430,16 @@ var K = class e2 {
|
|
|
367
430
|
onChange(e3) {
|
|
368
431
|
return this.listeners.add(e3), () => this.listeners.delete(e3);
|
|
369
432
|
}
|
|
370
|
-
comment(e3, t2) {
|
|
371
|
-
return this.enqueue(() => this.write({ kind: "create", anchor: e3, text:
|
|
433
|
+
comment(e3, t2, r2) {
|
|
434
|
+
return this.enqueue(() => this.write({ kind: "create", anchor: e3, text: V(t2), ...r2?.length ? { mentions: r2 } : {} }));
|
|
372
435
|
}
|
|
373
|
-
reply(e3, t2) {
|
|
374
|
-
return this.enqueue(() => this.write({ kind: "reply", thread: this.find(e3).thread, target: e3, text:
|
|
436
|
+
reply(e3, t2, r2) {
|
|
437
|
+
return this.enqueue(() => this.write({ kind: "reply", thread: this.find(e3).thread, target: e3, text: V(t2), ...r2?.length ? { mentions: r2 } : {} }));
|
|
375
438
|
}
|
|
376
|
-
edit(e3, t2) {
|
|
439
|
+
edit(e3, t2, r2) {
|
|
377
440
|
return this.enqueue(async () => {
|
|
378
|
-
let { thread:
|
|
379
|
-
await this.write({ kind: "edit", thread:
|
|
441
|
+
let { thread: n2 } = this.mine(e3);
|
|
442
|
+
await this.write({ kind: "edit", thread: n2, target: e3, text: V(t2), ...r2?.length ? { mentions: r2 } : {} });
|
|
380
443
|
});
|
|
381
444
|
}
|
|
382
445
|
remove(e3) {
|
|
@@ -385,6 +448,64 @@ var K = class e2 {
|
|
|
385
448
|
await this.write({ kind: "delete", thread: t2, target: e3 });
|
|
386
449
|
});
|
|
387
450
|
}
|
|
451
|
+
contact(e3) {
|
|
452
|
+
let t2 = e3.trim();
|
|
453
|
+
return E.test(t2) ? this.enqueue(async () => {
|
|
454
|
+
await this.write({ kind: "contact", thread: this.me, text: t2 });
|
|
455
|
+
}) : Promise.reject(new Error("pipeup: that isn't an email address or a GitHub name"));
|
|
456
|
+
}
|
|
457
|
+
uncontact() {
|
|
458
|
+
return this.enqueue(async () => {
|
|
459
|
+
await this.write({ kind: "uncontact", thread: this.me });
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
contacts() {
|
|
463
|
+
let e3 = /* @__PURE__ */ new Map();
|
|
464
|
+
for (let { body: t2 } of [...this.log.all()].sort(D)) "contact" === t2.kind && t2.text ? e3.set(t2.author, t2.text) : "uncontact" === t2.kind && e3.delete(t2.author);
|
|
465
|
+
return e3;
|
|
466
|
+
}
|
|
467
|
+
get portable() {
|
|
468
|
+
return this.options.identity.privateKey.extractable;
|
|
469
|
+
}
|
|
470
|
+
identityCode() {
|
|
471
|
+
return (async function(e3) {
|
|
472
|
+
if (!e3.privateKey.extractable) return null;
|
|
473
|
+
let r2 = await crypto.subtle.exportKey("jwk", e3.privateKey);
|
|
474
|
+
return r2.d ? (function(e4) {
|
|
475
|
+
let t2 = ((function(e5) {
|
|
476
|
+
let t3 = 0, r3 = 0, n2 = "";
|
|
477
|
+
for (let i of e5) for (r3 = r3 << 8 | i, t3 += 8; t3 >= 5; ) n2 += u[r3 >>> t3 - 5 & 31], t3 -= 5;
|
|
478
|
+
return t3 && (n2 += u[r3 << 5 - t3 & 31]), n2;
|
|
479
|
+
})(e4) + (function(e5) {
|
|
480
|
+
let t3 = 2166136261;
|
|
481
|
+
for (let r4 of e5) t3 = Math.imul(t3 ^ r4, 16777619);
|
|
482
|
+
t3 = Math.imul(t3 ^ t3 >>> 15, 739982445);
|
|
483
|
+
let r3 = "";
|
|
484
|
+
for (let e6 = 0; e6 < 4; e6++, t3 >>>= 5) r3 += u[31 & t3];
|
|
485
|
+
return r3;
|
|
486
|
+
})(e4)).match(/.{1,4}/g).join("-");
|
|
487
|
+
return `PU1-${t2}`;
|
|
488
|
+
})(t(r2.d)) : null;
|
|
489
|
+
})(this.options.identity);
|
|
490
|
+
}
|
|
491
|
+
seen(e3) {
|
|
492
|
+
return this.enqueue(async () => {
|
|
493
|
+
for (let t2 of e3) {
|
|
494
|
+
let e4 = this.comments.get(t2);
|
|
495
|
+
e4 && !e4.comment.seenBy?.includes(this.me) && await this.write({ kind: "seen", thread: e4.thread, target: t2 });
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
react(e3, t2) {
|
|
500
|
+
return this.enqueue(async () => {
|
|
501
|
+
await this.write({ kind: "react", thread: this.find(e3).thread, target: e3, text: W(t2) });
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
unreact(e3, t2) {
|
|
505
|
+
return this.enqueue(async () => {
|
|
506
|
+
await this.write({ kind: "unreact", thread: this.find(e3).thread, target: e3, text: W(t2) });
|
|
507
|
+
});
|
|
508
|
+
}
|
|
388
509
|
resolve(e3) {
|
|
389
510
|
return this.enqueue(async () => {
|
|
390
511
|
await this.write({ kind: "resolve", thread: this.thread(e3) });
|
|
@@ -396,8 +517,8 @@ var K = class e2 {
|
|
|
396
517
|
});
|
|
397
518
|
}
|
|
398
519
|
sign(e3, t2) {
|
|
399
|
-
if (!
|
|
400
|
-
return
|
|
520
|
+
if (!G.test(e3)) throw new Error('pipeup: a signing purpose looks like "<add-on id>/<name>"');
|
|
521
|
+
return d(this.options.identity, r(`pipeup:${e3}
|
|
401
522
|
${t2}`));
|
|
402
523
|
}
|
|
403
524
|
flush() {
|
|
@@ -405,7 +526,7 @@ ${t2}`));
|
|
|
405
526
|
}
|
|
406
527
|
exportFile() {
|
|
407
528
|
return (async function(e3, t2, r2) {
|
|
408
|
-
let n2 = r2 ? { pipeup: 1, doc: e3, sealed: true, ...await
|
|
529
|
+
let n2 = r2 ? { pipeup: 1, doc: e3, sealed: true, ...await z(r2, JSON.stringify(t2), B(e3)) } : { pipeup: 1, doc: e3, sealed: false, ops: t2 };
|
|
409
530
|
return JSON.stringify(n2, null, 2);
|
|
410
531
|
})(this.options.doc, this.log.all(), this.options.key);
|
|
411
532
|
}
|
|
@@ -431,7 +552,7 @@ ${t2}`));
|
|
|
431
552
|
} catch {
|
|
432
553
|
throw new Error("pipeup: this feedback could not be opened with this document");
|
|
433
554
|
}
|
|
434
|
-
})(i, { iv: o.iv, data: o.data },
|
|
555
|
+
})(i, { iv: o.iv, data: o.data }, B(n2));
|
|
435
556
|
} catch {
|
|
436
557
|
throw new Error("pipeup: this feedback could not be opened with this document's key");
|
|
437
558
|
}
|
|
@@ -450,7 +571,7 @@ ${t2}`));
|
|
|
450
571
|
try {
|
|
451
572
|
await this.persist();
|
|
452
573
|
} catch (e4) {
|
|
453
|
-
throw r2.length > 0 ? new
|
|
574
|
+
throw r2.length > 0 ? new Z(r2[0].body.id, e4, r2.length) : e4;
|
|
454
575
|
}
|
|
455
576
|
return r2.length;
|
|
456
577
|
});
|
|
@@ -466,7 +587,7 @@ ${t2}`));
|
|
|
466
587
|
try {
|
|
467
588
|
await this.persist();
|
|
468
589
|
} catch (e4) {
|
|
469
|
-
throw new
|
|
590
|
+
throw new Z(t2.body.id, e4);
|
|
470
591
|
}
|
|
471
592
|
return t2.body.id;
|
|
472
593
|
}
|
|
@@ -503,19 +624,23 @@ ${t2}`));
|
|
|
503
624
|
return e3;
|
|
504
625
|
}
|
|
505
626
|
};
|
|
506
|
-
function
|
|
627
|
+
function V(e3) {
|
|
507
628
|
let t2 = e3.trim();
|
|
508
629
|
if (!t2) throw new Error("pipeup: a comment needs some words");
|
|
509
|
-
if (t2.length >
|
|
630
|
+
if (t2.length > w) throw new Error(`pipeup: comments are limited to ${w} characters`);
|
|
510
631
|
return t2;
|
|
511
632
|
}
|
|
512
|
-
function
|
|
633
|
+
function W(e3) {
|
|
634
|
+
if (!N(e3)) throw new Error("pipeup: a reaction is one emoji");
|
|
635
|
+
return e3;
|
|
636
|
+
}
|
|
637
|
+
function Q(e3) {
|
|
513
638
|
let t2 = e3.replace(/\s+/g, " ").trim();
|
|
514
639
|
if (!t2 || t2.length > 80) throw new Error("pipeup: choose a name of 1 to 80 characters");
|
|
515
|
-
if (
|
|
640
|
+
if (y(t2)) throw new Error("pipeup: that name is kept for AI replies; choose another");
|
|
516
641
|
return t2;
|
|
517
642
|
}
|
|
518
|
-
var
|
|
643
|
+
var X = class {
|
|
519
644
|
docs = /* @__PURE__ */ new Map();
|
|
520
645
|
profile = null;
|
|
521
646
|
async load(e3) {
|
|
@@ -891,9 +1016,9 @@ function setAttribute(html, name, value) {
|
|
|
891
1016
|
const old = attr(name).exec(tag);
|
|
892
1017
|
let next;
|
|
893
1018
|
if (old) {
|
|
894
|
-
const
|
|
895
|
-
const v2 =
|
|
896
|
-
next = tag.slice(0, old.index) + `${old[1]}${name}${old[2]}${
|
|
1019
|
+
const q2 = old[3][0] === "'" ? "'" : '"';
|
|
1020
|
+
const v2 = q2 === "'" ? value.replace(/&/g, "&").replace(/'/g, "'") : escaped;
|
|
1021
|
+
next = tag.slice(0, old.index) + `${old[1]}${name}${old[2]}${q2}${v2}${q2}` + tag.slice(old.index + old[0].length);
|
|
897
1022
|
} else {
|
|
898
1023
|
const at = tag.length - 1;
|
|
899
1024
|
next = `${tag.slice(0, at)} ${name}="${escaped}"${tag.slice(at)}`;
|
|
@@ -984,12 +1109,12 @@ function server(value, mailbox) {
|
|
|
984
1109
|
return mailbox ? value.replace(/\/+$/, "") : u2.origin + u2.pathname;
|
|
985
1110
|
}
|
|
986
1111
|
async function feedbackOps(file, docAttr, io) {
|
|
987
|
-
const { id, key } = await
|
|
988
|
-
const doc = await
|
|
1112
|
+
const { id, key } = await _(docAttr);
|
|
1113
|
+
const doc = await J.open({
|
|
989
1114
|
doc: id,
|
|
990
1115
|
key,
|
|
991
|
-
store: new
|
|
992
|
-
identity: await
|
|
1116
|
+
store: new X(),
|
|
1117
|
+
identity: await l(),
|
|
993
1118
|
name: ""
|
|
994
1119
|
});
|
|
995
1120
|
try {
|
|
@@ -1015,11 +1140,11 @@ Run the same command with --new-doc and I will write a fresh one into the page.
|
|
|
1015
1140
|
);
|
|
1016
1141
|
throw new UsageError("the page needs a document identity");
|
|
1017
1142
|
}
|
|
1018
|
-
docAttr =
|
|
1143
|
+
docAttr = L();
|
|
1019
1144
|
html = setAttribute(html, "data-pipeup-doc", docAttr);
|
|
1020
1145
|
io.out("Gave the page a new document identity (data-pipeup-doc).");
|
|
1021
1146
|
}
|
|
1022
|
-
const { id } = await
|
|
1147
|
+
const { id } = await _(docAttr).catch(() => {
|
|
1023
1148
|
throw new UsageError("data-pipeup-doc in the page isn't a valid document identity");
|
|
1024
1149
|
});
|
|
1025
1150
|
const from = typeof flags.get("from") === "string" ? flags.get("from") : null;
|
|
@@ -1089,7 +1214,7 @@ async function addressOf(file, io) {
|
|
|
1089
1214
|
const a2 = parseShare(readAttribute(html, "data-pipeup-share"), true);
|
|
1090
1215
|
if (a2.kind === "off") throw new UsageError(`${file}: ${a2.reason}`);
|
|
1091
1216
|
const docAttr = readAttribute(html, "data-pipeup-doc");
|
|
1092
|
-
const doc = docAttr ? (await
|
|
1217
|
+
const doc = docAttr ? (await _(docAttr).catch(() => null))?.id : null;
|
|
1093
1218
|
if (!doc) throw new UsageError(`${file} has no valid data-pipeup-doc`);
|
|
1094
1219
|
return { html, a: a2, l: ladder(doc, a2.key) };
|
|
1095
1220
|
}
|