@pipeup/share 0.5.4 → 0.7.0-beta.1
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 -90
- package/dist/pipeup+share.min.js +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -170,44 +170,78 @@ 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
|
|
178
|
-
|
|
179
|
-
var
|
|
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 k(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,81 +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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
304
|
+
if ("addressed" === i2.kind) {
|
|
305
|
+
void 0 !== i2.text && (e4.addressed = { text: i2.text, author: i2.author, name: i2.name, at: i2.at });
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
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);
|
|
275
319
|
continue;
|
|
276
320
|
}
|
|
277
|
-
|
|
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));
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
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));
|
|
278
331
|
}
|
|
279
332
|
}
|
|
280
|
-
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
|
+
}
|
|
281
350
|
return [...t2.values()];
|
|
282
351
|
})(this.ops.values());
|
|
283
352
|
}
|
|
284
353
|
async add(e3) {
|
|
285
354
|
let t2 = [];
|
|
286
355
|
for (let r2 of e3) {
|
|
287
|
-
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;
|
|
288
357
|
let e4 = { body: r2.body, sig: r2.sig };
|
|
289
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);
|
|
290
359
|
}
|
|
291
360
|
return t2;
|
|
292
361
|
}
|
|
293
362
|
async append(e3, t2, r2) {
|
|
294
|
-
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,
|
|
295
|
-
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);
|
|
296
365
|
let i = this.ops.get(n2.id);
|
|
297
366
|
if (i) return i;
|
|
298
367
|
"create" === n2.kind && (n2.thread = n2.id);
|
|
299
|
-
let [o] = await this.add([await
|
|
368
|
+
let [o] = await this.add([await O(n2, e3)]);
|
|
300
369
|
if (!o) throw new Error("pipeup: could not record this change");
|
|
301
370
|
return o;
|
|
302
371
|
}
|
|
303
372
|
};
|
|
304
|
-
var
|
|
305
|
-
|
|
306
|
-
var D = /^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;
|
|
307
|
-
function F() {
|
|
373
|
+
var H = /^([A-Za-z0-9_-]{16}):([A-Za-z0-9_-]{43})$/;
|
|
374
|
+
function L() {
|
|
308
375
|
return `${(function(t2 = 16) {
|
|
309
376
|
return e(crypto.getRandomValues(new Uint8Array(t2)));
|
|
310
377
|
})(12)}:${e(crypto.getRandomValues(new Uint8Array(32)))}`;
|
|
311
378
|
}
|
|
312
|
-
async function
|
|
313
|
-
let r2 =
|
|
379
|
+
async function _(e3) {
|
|
380
|
+
let r2 = H.exec(e3.trim()), n2 = r2?.[1], i = r2?.[2];
|
|
314
381
|
if (!n2 || !i) throw new Error('pipeup: data-pipeup-doc must look like "<id>:<key>", as made by newDocumentAttribute()');
|
|
315
382
|
return { id: n2, key: await crypto.subtle.importKey("raw", t(i), { name: "AES-GCM" }, false, ["encrypt", "decrypt"]) };
|
|
316
383
|
}
|
|
317
|
-
async function
|
|
384
|
+
async function z(t2, n2, i) {
|
|
318
385
|
let o = crypto.getRandomValues(new Uint8Array(12)), a2 = await crypto.subtle.encrypt({ name: "AES-GCM", iv: o, additionalData: r(i) }, t2, r(n2));
|
|
319
386
|
return { iv: e(o), data: e(new Uint8Array(a2)) };
|
|
320
387
|
}
|
|
321
|
-
var
|
|
322
|
-
var
|
|
323
|
-
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 {
|
|
324
391
|
constructor(e3, t2, r2 = 1) {
|
|
325
392
|
super("pipeup: shown here, but not saved yet"), this.id = e3, this.cause = t2, this.count = r2, this.name = "UnsavedChangeError";
|
|
326
393
|
}
|
|
327
394
|
};
|
|
328
|
-
var
|
|
395
|
+
var J = class e2 {
|
|
329
396
|
constructor(e3, t2) {
|
|
330
|
-
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) : "";
|
|
331
398
|
}
|
|
332
399
|
listeners = /* @__PURE__ */ new Set();
|
|
333
400
|
cache = [];
|
|
@@ -337,7 +404,7 @@ var K = class e2 {
|
|
|
337
404
|
unsaved = [];
|
|
338
405
|
static async open(t2) {
|
|
339
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");
|
|
340
|
-
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;
|
|
341
408
|
i && console.warn(`pipeup: ${i} saved change${1 === i ? "" : "s"} on this page couldn't be read; kept as saved`);
|
|
342
409
|
let o = new e2(r2, t2);
|
|
343
410
|
return o.refresh(false), o;
|
|
@@ -352,7 +419,7 @@ var K = class e2 {
|
|
|
352
419
|
return this.displayName;
|
|
353
420
|
}
|
|
354
421
|
set name(e3) {
|
|
355
|
-
this.displayName =
|
|
422
|
+
this.displayName = Q(e3), this.refresh(true, [], "");
|
|
356
423
|
}
|
|
357
424
|
threads() {
|
|
358
425
|
return this.cache;
|
|
@@ -363,16 +430,16 @@ var K = class e2 {
|
|
|
363
430
|
onChange(e3) {
|
|
364
431
|
return this.listeners.add(e3), () => this.listeners.delete(e3);
|
|
365
432
|
}
|
|
366
|
-
comment(e3, t2) {
|
|
367
|
-
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 } : {} }));
|
|
368
435
|
}
|
|
369
|
-
reply(e3, t2) {
|
|
370
|
-
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 } : {} }));
|
|
371
438
|
}
|
|
372
|
-
edit(e3, t2) {
|
|
439
|
+
edit(e3, t2, r2) {
|
|
373
440
|
return this.enqueue(async () => {
|
|
374
|
-
let { thread:
|
|
375
|
-
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 } : {} });
|
|
376
443
|
});
|
|
377
444
|
}
|
|
378
445
|
remove(e3) {
|
|
@@ -381,6 +448,64 @@ var K = class e2 {
|
|
|
381
448
|
await this.write({ kind: "delete", thread: t2, target: e3 });
|
|
382
449
|
});
|
|
383
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
|
+
}
|
|
384
509
|
resolve(e3) {
|
|
385
510
|
return this.enqueue(async () => {
|
|
386
511
|
await this.write({ kind: "resolve", thread: this.thread(e3) });
|
|
@@ -392,8 +517,8 @@ var K = class e2 {
|
|
|
392
517
|
});
|
|
393
518
|
}
|
|
394
519
|
sign(e3, t2) {
|
|
395
|
-
if (!
|
|
396
|
-
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}
|
|
397
522
|
${t2}`));
|
|
398
523
|
}
|
|
399
524
|
flush() {
|
|
@@ -401,7 +526,7 @@ ${t2}`));
|
|
|
401
526
|
}
|
|
402
527
|
exportFile() {
|
|
403
528
|
return (async function(e3, t2, r2) {
|
|
404
|
-
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 };
|
|
405
530
|
return JSON.stringify(n2, null, 2);
|
|
406
531
|
})(this.options.doc, this.log.all(), this.options.key);
|
|
407
532
|
}
|
|
@@ -427,7 +552,7 @@ ${t2}`));
|
|
|
427
552
|
} catch {
|
|
428
553
|
throw new Error("pipeup: this feedback could not be opened with this document");
|
|
429
554
|
}
|
|
430
|
-
})(i, { iv: o.iv, data: o.data },
|
|
555
|
+
})(i, { iv: o.iv, data: o.data }, B(n2));
|
|
431
556
|
} catch {
|
|
432
557
|
throw new Error("pipeup: this feedback could not be opened with this document's key");
|
|
433
558
|
}
|
|
@@ -446,7 +571,7 @@ ${t2}`));
|
|
|
446
571
|
try {
|
|
447
572
|
await this.persist();
|
|
448
573
|
} catch (e4) {
|
|
449
|
-
throw r2.length > 0 ? new
|
|
574
|
+
throw r2.length > 0 ? new Z(r2[0].body.id, e4, r2.length) : e4;
|
|
450
575
|
}
|
|
451
576
|
return r2.length;
|
|
452
577
|
});
|
|
@@ -462,7 +587,7 @@ ${t2}`));
|
|
|
462
587
|
try {
|
|
463
588
|
await this.persist();
|
|
464
589
|
} catch (e4) {
|
|
465
|
-
throw new
|
|
590
|
+
throw new Z(t2.body.id, e4);
|
|
466
591
|
}
|
|
467
592
|
return t2.body.id;
|
|
468
593
|
}
|
|
@@ -499,19 +624,23 @@ ${t2}`));
|
|
|
499
624
|
return e3;
|
|
500
625
|
}
|
|
501
626
|
};
|
|
502
|
-
function
|
|
627
|
+
function V(e3) {
|
|
503
628
|
let t2 = e3.trim();
|
|
504
629
|
if (!t2) throw new Error("pipeup: a comment needs some words");
|
|
505
|
-
if (t2.length >
|
|
630
|
+
if (t2.length > w) throw new Error(`pipeup: comments are limited to ${w} characters`);
|
|
506
631
|
return t2;
|
|
507
632
|
}
|
|
508
|
-
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) {
|
|
509
638
|
let t2 = e3.replace(/\s+/g, " ").trim();
|
|
510
639
|
if (!t2 || t2.length > 80) throw new Error("pipeup: choose a name of 1 to 80 characters");
|
|
511
|
-
if (
|
|
640
|
+
if (y(t2)) throw new Error("pipeup: that name is kept for AI replies; choose another");
|
|
512
641
|
return t2;
|
|
513
642
|
}
|
|
514
|
-
var
|
|
643
|
+
var X = class {
|
|
515
644
|
docs = /* @__PURE__ */ new Map();
|
|
516
645
|
profile = null;
|
|
517
646
|
async load(e3) {
|
|
@@ -887,9 +1016,9 @@ function setAttribute(html, name, value) {
|
|
|
887
1016
|
const old = attr(name).exec(tag);
|
|
888
1017
|
let next;
|
|
889
1018
|
if (old) {
|
|
890
|
-
const
|
|
891
|
-
const v2 =
|
|
892
|
-
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);
|
|
893
1022
|
} else {
|
|
894
1023
|
const at = tag.length - 1;
|
|
895
1024
|
next = `${tag.slice(0, at)} ${name}="${escaped}"${tag.slice(at)}`;
|
|
@@ -980,11 +1109,11 @@ function server(value, mailbox) {
|
|
|
980
1109
|
return mailbox ? value.replace(/\/+$/, "") : u2.origin + u2.pathname;
|
|
981
1110
|
}
|
|
982
1111
|
async function feedbackOps(file, docAttr, io) {
|
|
983
|
-
const { id, key } = await
|
|
984
|
-
const doc = await
|
|
1112
|
+
const { id, key } = await _(docAttr);
|
|
1113
|
+
const doc = await J.open({
|
|
985
1114
|
doc: id,
|
|
986
1115
|
key,
|
|
987
|
-
store: new
|
|
1116
|
+
store: new X(),
|
|
988
1117
|
identity: await l(),
|
|
989
1118
|
name: ""
|
|
990
1119
|
});
|
|
@@ -1011,11 +1140,11 @@ Run the same command with --new-doc and I will write a fresh one into the page.
|
|
|
1011
1140
|
);
|
|
1012
1141
|
throw new UsageError("the page needs a document identity");
|
|
1013
1142
|
}
|
|
1014
|
-
docAttr =
|
|
1143
|
+
docAttr = L();
|
|
1015
1144
|
html = setAttribute(html, "data-pipeup-doc", docAttr);
|
|
1016
1145
|
io.out("Gave the page a new document identity (data-pipeup-doc).");
|
|
1017
1146
|
}
|
|
1018
|
-
const { id } = await
|
|
1147
|
+
const { id } = await _(docAttr).catch(() => {
|
|
1019
1148
|
throw new UsageError("data-pipeup-doc in the page isn't a valid document identity");
|
|
1020
1149
|
});
|
|
1021
1150
|
const from = typeof flags.get("from") === "string" ? flags.get("from") : null;
|
|
@@ -1085,7 +1214,7 @@ async function addressOf(file, io) {
|
|
|
1085
1214
|
const a2 = parseShare(readAttribute(html, "data-pipeup-share"), true);
|
|
1086
1215
|
if (a2.kind === "off") throw new UsageError(`${file}: ${a2.reason}`);
|
|
1087
1216
|
const docAttr = readAttribute(html, "data-pipeup-doc");
|
|
1088
|
-
const doc = docAttr ? (await
|
|
1217
|
+
const doc = docAttr ? (await _(docAttr).catch(() => null))?.id : null;
|
|
1089
1218
|
if (!doc) throw new UsageError(`${file} has no valid data-pipeup-doc`);
|
|
1090
1219
|
return { html, a: a2, l: ladder(doc, a2.key) };
|
|
1091
1220
|
}
|