@fairfox/polly 0.72.0 → 0.73.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.
Files changed (36) hide show
  1. package/dist/src/elysia/index.js +464 -4
  2. package/dist/src/elysia/index.js.map +6 -4
  3. package/dist/src/peer.d.ts +2 -0
  4. package/dist/src/peer.js +468 -4
  5. package/dist/src/peer.js.map +8 -5
  6. package/dist/src/polly-ui/ActionInput.d.ts +2 -1
  7. package/dist/src/polly-ui/ActionSelect.d.ts +2 -1
  8. package/dist/src/polly-ui/Button.d.ts +4 -0
  9. package/dist/src/polly-ui/Cluster.d.ts +2 -1
  10. package/dist/src/polly-ui/Code.d.ts +2 -1
  11. package/dist/src/polly-ui/Dropdown.d.ts +6 -0
  12. package/dist/src/polly-ui/Surface.d.ts +12 -1
  13. package/dist/src/polly-ui/Text.d.ts +23 -11
  14. package/dist/src/polly-ui/index.css +44 -18
  15. package/dist/src/polly-ui/index.js +118 -12
  16. package/dist/src/polly-ui/index.js.map +12 -11
  17. package/dist/src/polly-ui/internal/passthrough.d.ts +25 -0
  18. package/dist/src/polly-ui/styles.css +59 -18
  19. package/dist/src/polly-ui/theme.css +1 -0
  20. package/dist/src/shared/lib/peer-repo-server.d.ts +18 -0
  21. package/dist/src/shared/lib/sweep-sealed.d.ts +111 -0
  22. package/dist/tools/test/src/browser/run.js +42 -33
  23. package/dist/tools/test/src/browser/run.js.map +6 -5
  24. package/dist/tools/test/src/browser/runner-core.d.ts +32 -0
  25. package/dist/tools/test/src/e2e-mesh/index.js +193 -171
  26. package/dist/tools/test/src/e2e-mesh/index.js.map +4 -4
  27. package/dist/tools/test/src/visual/index.js +248 -229
  28. package/dist/tools/test/src/visual/index.js.map +5 -5
  29. package/dist/tools/verify/specs/tla/MeshSeed.cfg +27 -0
  30. package/dist/tools/verify/specs/tla/MeshSeed.tla +179 -0
  31. package/dist/tools/verify/specs/tla/README.md +11 -1
  32. package/dist/tools/verify/src/cli.js +79 -2
  33. package/dist/tools/verify/src/cli.js.map +7 -6
  34. package/dist/tools/visualize/src/cli.js +179 -3
  35. package/dist/tools/visualize/src/cli.js.map +6 -6
  36. package/package.json +3 -2
package/dist/src/peer.js CHANGED
@@ -162,6 +162,435 @@ var init_encryption = __esm(() => {
162
162
  };
163
163
  });
164
164
 
165
+ // node:path
166
+ var exports_path = {};
167
+ __export(exports_path, {
168
+ sep: () => sep,
169
+ resolve: () => resolve,
170
+ relative: () => relative,
171
+ posix: () => posix,
172
+ parse: () => parse,
173
+ normalize: () => normalize,
174
+ join: () => join,
175
+ isAbsolute: () => isAbsolute,
176
+ format: () => format,
177
+ extname: () => extname,
178
+ dirname: () => dirname,
179
+ delimiter: () => delimiter,
180
+ default: () => path_default,
181
+ basename: () => basename,
182
+ _makeLong: () => _makeLong
183
+ });
184
+ function assertPath(path) {
185
+ if (typeof path !== "string")
186
+ throw TypeError("Path must be a string. Received " + JSON.stringify(path));
187
+ }
188
+ function normalizeStringPosix(path, allowAboveRoot) {
189
+ var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
190
+ for (var i = 0;i <= path.length; ++i) {
191
+ if (i < path.length)
192
+ code = path.charCodeAt(i);
193
+ else if (code === 47)
194
+ break;
195
+ else
196
+ code = 47;
197
+ if (code === 47) {
198
+ if (lastSlash === i - 1 || dots === 1)
199
+ ;
200
+ else if (lastSlash !== i - 1 && dots === 2) {
201
+ if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
202
+ if (res.length > 2) {
203
+ var lastSlashIndex = res.lastIndexOf("/");
204
+ if (lastSlashIndex !== res.length - 1) {
205
+ if (lastSlashIndex === -1)
206
+ res = "", lastSegmentLength = 0;
207
+ else
208
+ res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
209
+ lastSlash = i, dots = 0;
210
+ continue;
211
+ }
212
+ } else if (res.length === 2 || res.length === 1) {
213
+ res = "", lastSegmentLength = 0, lastSlash = i, dots = 0;
214
+ continue;
215
+ }
216
+ }
217
+ if (allowAboveRoot) {
218
+ if (res.length > 0)
219
+ res += "/..";
220
+ else
221
+ res = "..";
222
+ lastSegmentLength = 2;
223
+ }
224
+ } else {
225
+ if (res.length > 0)
226
+ res += "/" + path.slice(lastSlash + 1, i);
227
+ else
228
+ res = path.slice(lastSlash + 1, i);
229
+ lastSegmentLength = i - lastSlash - 1;
230
+ }
231
+ lastSlash = i, dots = 0;
232
+ } else if (code === 46 && dots !== -1)
233
+ ++dots;
234
+ else
235
+ dots = -1;
236
+ }
237
+ return res;
238
+ }
239
+ function _format(sep, pathObject) {
240
+ var dir = pathObject.dir || pathObject.root, base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
241
+ if (!dir)
242
+ return base;
243
+ if (dir === pathObject.root)
244
+ return dir + base;
245
+ return dir + sep + base;
246
+ }
247
+ function resolve() {
248
+ var resolvedPath = "", resolvedAbsolute = false, cwd;
249
+ for (var i = arguments.length - 1;i >= -1 && !resolvedAbsolute; i--) {
250
+ var path;
251
+ if (i >= 0)
252
+ path = arguments[i];
253
+ else {
254
+ if (cwd === undefined)
255
+ cwd = process.cwd();
256
+ path = cwd;
257
+ }
258
+ if (assertPath(path), path.length === 0)
259
+ continue;
260
+ resolvedPath = path + "/" + resolvedPath, resolvedAbsolute = path.charCodeAt(0) === 47;
261
+ }
262
+ if (resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute), resolvedAbsolute)
263
+ if (resolvedPath.length > 0)
264
+ return "/" + resolvedPath;
265
+ else
266
+ return "/";
267
+ else if (resolvedPath.length > 0)
268
+ return resolvedPath;
269
+ else
270
+ return ".";
271
+ }
272
+ function normalize(path) {
273
+ if (assertPath(path), path.length === 0)
274
+ return ".";
275
+ var isAbsolute = path.charCodeAt(0) === 47, trailingSeparator = path.charCodeAt(path.length - 1) === 47;
276
+ if (path = normalizeStringPosix(path, !isAbsolute), path.length === 0 && !isAbsolute)
277
+ path = ".";
278
+ if (path.length > 0 && trailingSeparator)
279
+ path += "/";
280
+ if (isAbsolute)
281
+ return "/" + path;
282
+ return path;
283
+ }
284
+ function isAbsolute(path) {
285
+ return assertPath(path), path.length > 0 && path.charCodeAt(0) === 47;
286
+ }
287
+ function join() {
288
+ if (arguments.length === 0)
289
+ return ".";
290
+ var joined;
291
+ for (var i = 0;i < arguments.length; ++i) {
292
+ var arg = arguments[i];
293
+ if (assertPath(arg), arg.length > 0)
294
+ if (joined === undefined)
295
+ joined = arg;
296
+ else
297
+ joined += "/" + arg;
298
+ }
299
+ if (joined === undefined)
300
+ return ".";
301
+ return normalize(joined);
302
+ }
303
+ function relative(from, to) {
304
+ if (assertPath(from), assertPath(to), from === to)
305
+ return "";
306
+ if (from = resolve(from), to = resolve(to), from === to)
307
+ return "";
308
+ var fromStart = 1;
309
+ for (;fromStart < from.length; ++fromStart)
310
+ if (from.charCodeAt(fromStart) !== 47)
311
+ break;
312
+ var fromEnd = from.length, fromLen = fromEnd - fromStart, toStart = 1;
313
+ for (;toStart < to.length; ++toStart)
314
+ if (to.charCodeAt(toStart) !== 47)
315
+ break;
316
+ var toEnd = to.length, toLen = toEnd - toStart, length = fromLen < toLen ? fromLen : toLen, lastCommonSep = -1, i = 0;
317
+ for (;i <= length; ++i) {
318
+ if (i === length) {
319
+ if (toLen > length) {
320
+ if (to.charCodeAt(toStart + i) === 47)
321
+ return to.slice(toStart + i + 1);
322
+ else if (i === 0)
323
+ return to.slice(toStart + i);
324
+ } else if (fromLen > length) {
325
+ if (from.charCodeAt(fromStart + i) === 47)
326
+ lastCommonSep = i;
327
+ else if (i === 0)
328
+ lastCommonSep = 0;
329
+ }
330
+ break;
331
+ }
332
+ var fromCode = from.charCodeAt(fromStart + i), toCode = to.charCodeAt(toStart + i);
333
+ if (fromCode !== toCode)
334
+ break;
335
+ else if (fromCode === 47)
336
+ lastCommonSep = i;
337
+ }
338
+ var out = "";
339
+ for (i = fromStart + lastCommonSep + 1;i <= fromEnd; ++i)
340
+ if (i === fromEnd || from.charCodeAt(i) === 47)
341
+ if (out.length === 0)
342
+ out += "..";
343
+ else
344
+ out += "/..";
345
+ if (out.length > 0)
346
+ return out + to.slice(toStart + lastCommonSep);
347
+ else {
348
+ if (toStart += lastCommonSep, to.charCodeAt(toStart) === 47)
349
+ ++toStart;
350
+ return to.slice(toStart);
351
+ }
352
+ }
353
+ function _makeLong(path) {
354
+ return path;
355
+ }
356
+ function dirname(path) {
357
+ if (assertPath(path), path.length === 0)
358
+ return ".";
359
+ var code = path.charCodeAt(0), hasRoot = code === 47, end = -1, matchedSlash = true;
360
+ for (var i = path.length - 1;i >= 1; --i)
361
+ if (code = path.charCodeAt(i), code === 47) {
362
+ if (!matchedSlash) {
363
+ end = i;
364
+ break;
365
+ }
366
+ } else
367
+ matchedSlash = false;
368
+ if (end === -1)
369
+ return hasRoot ? "/" : ".";
370
+ if (hasRoot && end === 1)
371
+ return "//";
372
+ return path.slice(0, end);
373
+ }
374
+ function basename(path, ext) {
375
+ if (ext !== undefined && typeof ext !== "string")
376
+ throw TypeError('"ext" argument must be a string');
377
+ assertPath(path);
378
+ var start = 0, end = -1, matchedSlash = true, i;
379
+ if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
380
+ if (ext.length === path.length && ext === path)
381
+ return "";
382
+ var extIdx = ext.length - 1, firstNonSlashEnd = -1;
383
+ for (i = path.length - 1;i >= 0; --i) {
384
+ var code = path.charCodeAt(i);
385
+ if (code === 47) {
386
+ if (!matchedSlash) {
387
+ start = i + 1;
388
+ break;
389
+ }
390
+ } else {
391
+ if (firstNonSlashEnd === -1)
392
+ matchedSlash = false, firstNonSlashEnd = i + 1;
393
+ if (extIdx >= 0)
394
+ if (code === ext.charCodeAt(extIdx)) {
395
+ if (--extIdx === -1)
396
+ end = i;
397
+ } else
398
+ extIdx = -1, end = firstNonSlashEnd;
399
+ }
400
+ }
401
+ if (start === end)
402
+ end = firstNonSlashEnd;
403
+ else if (end === -1)
404
+ end = path.length;
405
+ return path.slice(start, end);
406
+ } else {
407
+ for (i = path.length - 1;i >= 0; --i)
408
+ if (path.charCodeAt(i) === 47) {
409
+ if (!matchedSlash) {
410
+ start = i + 1;
411
+ break;
412
+ }
413
+ } else if (end === -1)
414
+ matchedSlash = false, end = i + 1;
415
+ if (end === -1)
416
+ return "";
417
+ return path.slice(start, end);
418
+ }
419
+ }
420
+ function extname(path) {
421
+ assertPath(path);
422
+ var startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0;
423
+ for (var i = path.length - 1;i >= 0; --i) {
424
+ var code = path.charCodeAt(i);
425
+ if (code === 47) {
426
+ if (!matchedSlash) {
427
+ startPart = i + 1;
428
+ break;
429
+ }
430
+ continue;
431
+ }
432
+ if (end === -1)
433
+ matchedSlash = false, end = i + 1;
434
+ if (code === 46) {
435
+ if (startDot === -1)
436
+ startDot = i;
437
+ else if (preDotState !== 1)
438
+ preDotState = 1;
439
+ } else if (startDot !== -1)
440
+ preDotState = -1;
441
+ }
442
+ if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
443
+ return "";
444
+ return path.slice(startDot, end);
445
+ }
446
+ function format(pathObject) {
447
+ if (pathObject === null || typeof pathObject !== "object")
448
+ throw TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
449
+ return _format("/", pathObject);
450
+ }
451
+ function parse(path) {
452
+ assertPath(path);
453
+ var ret = { root: "", dir: "", base: "", ext: "", name: "" };
454
+ if (path.length === 0)
455
+ return ret;
456
+ var code = path.charCodeAt(0), isAbsolute2 = code === 47, start;
457
+ if (isAbsolute2)
458
+ ret.root = "/", start = 1;
459
+ else
460
+ start = 0;
461
+ var startDot = -1, startPart = 0, end = -1, matchedSlash = true, i = path.length - 1, preDotState = 0;
462
+ for (;i >= start; --i) {
463
+ if (code = path.charCodeAt(i), code === 47) {
464
+ if (!matchedSlash) {
465
+ startPart = i + 1;
466
+ break;
467
+ }
468
+ continue;
469
+ }
470
+ if (end === -1)
471
+ matchedSlash = false, end = i + 1;
472
+ if (code === 46) {
473
+ if (startDot === -1)
474
+ startDot = i;
475
+ else if (preDotState !== 1)
476
+ preDotState = 1;
477
+ } else if (startDot !== -1)
478
+ preDotState = -1;
479
+ }
480
+ if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
481
+ if (end !== -1)
482
+ if (startPart === 0 && isAbsolute2)
483
+ ret.base = ret.name = path.slice(1, end);
484
+ else
485
+ ret.base = ret.name = path.slice(startPart, end);
486
+ } else {
487
+ if (startPart === 0 && isAbsolute2)
488
+ ret.name = path.slice(1, startDot), ret.base = path.slice(1, end);
489
+ else
490
+ ret.name = path.slice(startPart, startDot), ret.base = path.slice(startPart, end);
491
+ ret.ext = path.slice(startDot, end);
492
+ }
493
+ if (startPart > 0)
494
+ ret.dir = path.slice(0, startPart - 1);
495
+ else if (isAbsolute2)
496
+ ret.dir = "/";
497
+ return ret;
498
+ }
499
+ var sep = "/", delimiter = ":", posix, path_default;
500
+ var init_path = __esm(() => {
501
+ posix = ((p) => (p.posix = p, p))({ resolve, normalize, isAbsolute, join, relative, _makeLong, dirname, basename, extname, format, parse, sep, delimiter, win32: null, posix: null });
502
+ path_default = posix;
503
+ });
504
+
505
+ // src/shared/lib/sweep-sealed.ts
506
+ var exports_sweep_sealed = {};
507
+ __export(exports_sweep_sealed, {
508
+ sweepSealed: () => sweepSealed
509
+ });
510
+ import { Automerge as Automerge3 } from "@automerge/automerge-repo/slim";
511
+ function concat(parts) {
512
+ let total = 0;
513
+ for (const part of parts)
514
+ total += part.byteLength;
515
+ const out = new Uint8Array(total);
516
+ let offset = 0;
517
+ for (const part of parts) {
518
+ out.set(part, offset);
519
+ offset += part.byteLength;
520
+ }
521
+ return out;
522
+ }
523
+ function materialise(chunks) {
524
+ const content = chunks.filter((chunk) => chunk.key[1] !== "sync-state" && chunk.data !== undefined).sort((a, b) => (a.key[1] === "snapshot" ? 0 : 1) - (b.key[1] === "snapshot" ? 0 : 1));
525
+ if (content.length === 0)
526
+ return;
527
+ try {
528
+ return Automerge3.loadIncremental(Automerge3.init(), concat(content.map((chunk) => chunk.data)));
529
+ } catch {
530
+ return;
531
+ }
532
+ }
533
+ async function collectChunksByDocument(storage, documentIds) {
534
+ const chunks = [];
535
+ if (documentIds === undefined) {
536
+ chunks.push(...await storage.loadRange([]));
537
+ } else {
538
+ for (const documentId of documentIds) {
539
+ chunks.push(...await storage.loadRange([documentId]));
540
+ }
541
+ }
542
+ const byDocument = new Map;
543
+ for (const chunk of chunks) {
544
+ const documentId = chunk.key[0];
545
+ if (documentId === undefined)
546
+ continue;
547
+ const existing = byDocument.get(documentId);
548
+ if (existing)
549
+ existing.push(chunk);
550
+ else
551
+ byDocument.set(documentId, [chunk]);
552
+ }
553
+ return byDocument;
554
+ }
555
+ function classifyDocument(documentId, chunks, context) {
556
+ const doc = materialise(chunks);
557
+ if (doc === undefined)
558
+ return { action: "ignore" };
559
+ const sealedAt = context.isSealed(doc);
560
+ if (sealedAt === undefined)
561
+ return { action: "ignore" };
562
+ const id = documentId;
563
+ if (context.repo.handles[id] !== undefined) {
564
+ return { action: "keep", entry: { documentId: id, reason: "open-handle" } };
565
+ }
566
+ if (context.at - sealedAt < context.olderThan) {
567
+ return { action: "keep", entry: { documentId: id, reason: "too-recent" } };
568
+ }
569
+ const byteSize = chunks.reduce((sum, chunk) => sum + (chunk.data?.byteLength ?? 0), 0);
570
+ return { action: "sweep", entry: { documentId: id, sealedAt, byteSize } };
571
+ }
572
+ async function sweepSealed(options) {
573
+ const { repo, storage, isSealed, olderThan } = options;
574
+ const dryRun = options.dryRun ?? false;
575
+ const now = options.now ?? Date.now;
576
+ const byDocument = await collectChunksByDocument(storage, options.documentIds);
577
+ const swept = [];
578
+ const kept = [];
579
+ const at = now();
580
+ for (const [documentId, chunks] of byDocument) {
581
+ const verdict = classifyDocument(documentId, chunks, { repo, isSealed, olderThan, at });
582
+ if (verdict.action === "keep") {
583
+ kept.push(verdict.entry);
584
+ } else if (verdict.action === "sweep") {
585
+ swept.push(verdict.entry);
586
+ if (!dryRun)
587
+ await storage.removeRange([documentId]);
588
+ }
589
+ }
590
+ return { swept, kept, dryRun };
591
+ }
592
+ var init_sweep_sealed = () => {};
593
+
165
594
  // src/shared/lib/wasm-init.ts
166
595
  import wasmPath from "@automerge/automerge/automerge.wasm";
167
596
  import { initializeWasm } from "@automerge/automerge-repo/slim";
@@ -1069,6 +1498,31 @@ function createPeerStateClient(options) {
1069
1498
  };
1070
1499
  }
1071
1500
  // src/shared/lib/peer-repo-server.ts
1501
+ async function listNodeFSDocumentIds(baseDirectory) {
1502
+ const [{ readdir }, { join: join2 }] = await Promise.all([
1503
+ import("node:fs/promises"),
1504
+ Promise.resolve().then(() => (init_path(), exports_path))
1505
+ ]);
1506
+ let shards;
1507
+ try {
1508
+ shards = await readdir(baseDirectory);
1509
+ } catch (error) {
1510
+ if (error.code === "ENOENT")
1511
+ return [];
1512
+ throw error;
1513
+ }
1514
+ const documentIds = [];
1515
+ for (const shard of shards) {
1516
+ const entries = await readdir(join2(baseDirectory, shard), {
1517
+ withFileTypes: true
1518
+ }).catch(() => []);
1519
+ for (const entry of entries) {
1520
+ if (entry.isDirectory())
1521
+ documentIds.push(shard + entry.name);
1522
+ }
1523
+ }
1524
+ return documentIds;
1525
+ }
1072
1526
  async function createPeerRepoServer(options) {
1073
1527
  const [{ Repo: Repo2 }, { WebSocketServerAdapter }, { NodeFSStorageAdapter }, ws] = await Promise.all([
1074
1528
  import("@automerge/automerge-repo/slim"),
@@ -1076,15 +1530,16 @@ async function createPeerRepoServer(options) {
1076
1530
  import("@automerge/automerge-repo-storage-nodefs"),
1077
1531
  import("ws")
1078
1532
  ]);
1079
- const wss = await (options.webSocketServer ? Promise.resolve(options.webSocketServer) : new Promise((resolve, reject) => {
1533
+ const wss = await (options.webSocketServer ? Promise.resolve(options.webSocketServer) : new Promise((resolve2, reject) => {
1080
1534
  const created = new ws.WebSocketServer({
1081
1535
  port: options.port,
1082
1536
  ...options.host !== undefined && { host: options.host }
1083
- }, () => resolve(created));
1537
+ }, () => resolve2(created));
1084
1538
  created.once("error", reject);
1085
1539
  }));
1086
1540
  const adapter = new WebSocketServerAdapter(wss);
1087
- const storage = new NodeFSStorageAdapter(options.storagePath);
1541
+ const storagePath = options.storagePath ?? "automerge-repo-data";
1542
+ const storage = new NodeFSStorageAdapter(storagePath);
1088
1543
  const repo = new Repo2({
1089
1544
  network: [adapter],
1090
1545
  storage
@@ -1095,6 +1550,11 @@ async function createPeerRepoServer(options) {
1095
1550
  webSocketServer: wss,
1096
1551
  adapter,
1097
1552
  storage,
1553
+ sweepSealed: async (sweepOptions) => {
1554
+ const documentIds = await listNodeFSDocumentIds(storagePath);
1555
+ const { sweepSealed: sweepSealed2 } = await Promise.resolve().then(() => (init_sweep_sealed(), exports_sweep_sealed));
1556
+ return sweepSealed2({ repo, storage, documentIds, ...sweepOptions });
1557
+ },
1098
1558
  close: async () => {
1099
1559
  for (const client of wss.clients) {
1100
1560
  try {
@@ -1204,7 +1664,11 @@ function $peerList(key, initialValue, options = {}) {
1204
1664
  access: options.access
1205
1665
  });
1206
1666
  }
1667
+
1668
+ // src/peer.ts
1669
+ init_sweep_sealed();
1207
1670
  export {
1671
+ sweepSealed,
1208
1672
  resetPeerState,
1209
1673
  migratePrimitive,
1210
1674
  getDocVersion,
@@ -1227,4 +1691,4 @@ export {
1227
1691
  $crdtCounter
1228
1692
  };
1229
1693
 
1230
- //# debugId=C92D0D86B1D86EE064756E2164756E21
1694
+ //# debugId=F8EEAB6080033B3464756E2164756E21