@fairfox/polly 0.72.0 → 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) 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/Surface.d.ts +12 -1
  12. package/dist/src/polly-ui/Text.d.ts +23 -11
  13. package/dist/src/polly-ui/index.css +42 -9
  14. package/dist/src/polly-ui/index.js +59 -6
  15. package/dist/src/polly-ui/index.js.map +11 -10
  16. package/dist/src/polly-ui/internal/passthrough.d.ts +25 -0
  17. package/dist/src/polly-ui/styles.css +57 -9
  18. package/dist/src/polly-ui/theme.css +1 -0
  19. package/dist/src/shared/lib/peer-repo-server.d.ts +18 -0
  20. package/dist/src/shared/lib/sweep-sealed.d.ts +111 -0
  21. package/dist/tools/test/src/browser/run.js +42 -33
  22. package/dist/tools/test/src/browser/run.js.map +6 -5
  23. package/dist/tools/test/src/browser/runner-core.d.ts +32 -0
  24. package/dist/tools/test/src/e2e-mesh/index.js +193 -171
  25. package/dist/tools/test/src/e2e-mesh/index.js.map +4 -4
  26. package/dist/tools/test/src/visual/index.js +248 -229
  27. package/dist/tools/test/src/visual/index.js.map +5 -5
  28. package/dist/tools/verify/specs/tla/MeshSeed.cfg +27 -0
  29. package/dist/tools/verify/specs/tla/MeshSeed.tla +179 -0
  30. package/dist/tools/verify/specs/tla/README.md +11 -1
  31. package/dist/tools/verify/src/cli.js +55 -1
  32. package/dist/tools/verify/src/cli.js.map +6 -5
  33. package/dist/tools/visualize/src/cli.js +72 -2
  34. package/dist/tools/visualize/src/cli.js.map +5 -5
  35. package/package.json +3 -2
@@ -69,10 +69,464 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
69
69
  throw Error('Dynamic require of "' + x + '" is not supported');
70
70
  });
71
71
 
72
+ // node:path
73
+ var exports_path = {};
74
+ __export(exports_path, {
75
+ sep: () => sep,
76
+ resolve: () => resolve,
77
+ relative: () => relative,
78
+ posix: () => posix,
79
+ parse: () => parse,
80
+ normalize: () => normalize,
81
+ join: () => join,
82
+ isAbsolute: () => isAbsolute,
83
+ format: () => format,
84
+ extname: () => extname,
85
+ dirname: () => dirname,
86
+ delimiter: () => delimiter,
87
+ default: () => path_default,
88
+ basename: () => basename,
89
+ _makeLong: () => _makeLong
90
+ });
91
+ function assertPath(path) {
92
+ if (typeof path !== "string")
93
+ throw TypeError("Path must be a string. Received " + JSON.stringify(path));
94
+ }
95
+ function normalizeStringPosix(path, allowAboveRoot) {
96
+ var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
97
+ for (var i = 0;i <= path.length; ++i) {
98
+ if (i < path.length)
99
+ code = path.charCodeAt(i);
100
+ else if (code === 47)
101
+ break;
102
+ else
103
+ code = 47;
104
+ if (code === 47) {
105
+ if (lastSlash === i - 1 || dots === 1)
106
+ ;
107
+ else if (lastSlash !== i - 1 && dots === 2) {
108
+ if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
109
+ if (res.length > 2) {
110
+ var lastSlashIndex = res.lastIndexOf("/");
111
+ if (lastSlashIndex !== res.length - 1) {
112
+ if (lastSlashIndex === -1)
113
+ res = "", lastSegmentLength = 0;
114
+ else
115
+ res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
116
+ lastSlash = i, dots = 0;
117
+ continue;
118
+ }
119
+ } else if (res.length === 2 || res.length === 1) {
120
+ res = "", lastSegmentLength = 0, lastSlash = i, dots = 0;
121
+ continue;
122
+ }
123
+ }
124
+ if (allowAboveRoot) {
125
+ if (res.length > 0)
126
+ res += "/..";
127
+ else
128
+ res = "..";
129
+ lastSegmentLength = 2;
130
+ }
131
+ } else {
132
+ if (res.length > 0)
133
+ res += "/" + path.slice(lastSlash + 1, i);
134
+ else
135
+ res = path.slice(lastSlash + 1, i);
136
+ lastSegmentLength = i - lastSlash - 1;
137
+ }
138
+ lastSlash = i, dots = 0;
139
+ } else if (code === 46 && dots !== -1)
140
+ ++dots;
141
+ else
142
+ dots = -1;
143
+ }
144
+ return res;
145
+ }
146
+ function _format(sep, pathObject) {
147
+ var dir = pathObject.dir || pathObject.root, base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
148
+ if (!dir)
149
+ return base;
150
+ if (dir === pathObject.root)
151
+ return dir + base;
152
+ return dir + sep + base;
153
+ }
154
+ function resolve() {
155
+ var resolvedPath = "", resolvedAbsolute = false, cwd;
156
+ for (var i = arguments.length - 1;i >= -1 && !resolvedAbsolute; i--) {
157
+ var path;
158
+ if (i >= 0)
159
+ path = arguments[i];
160
+ else {
161
+ if (cwd === undefined)
162
+ cwd = process.cwd();
163
+ path = cwd;
164
+ }
165
+ if (assertPath(path), path.length === 0)
166
+ continue;
167
+ resolvedPath = path + "/" + resolvedPath, resolvedAbsolute = path.charCodeAt(0) === 47;
168
+ }
169
+ if (resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute), resolvedAbsolute)
170
+ if (resolvedPath.length > 0)
171
+ return "/" + resolvedPath;
172
+ else
173
+ return "/";
174
+ else if (resolvedPath.length > 0)
175
+ return resolvedPath;
176
+ else
177
+ return ".";
178
+ }
179
+ function normalize(path) {
180
+ if (assertPath(path), path.length === 0)
181
+ return ".";
182
+ var isAbsolute = path.charCodeAt(0) === 47, trailingSeparator = path.charCodeAt(path.length - 1) === 47;
183
+ if (path = normalizeStringPosix(path, !isAbsolute), path.length === 0 && !isAbsolute)
184
+ path = ".";
185
+ if (path.length > 0 && trailingSeparator)
186
+ path += "/";
187
+ if (isAbsolute)
188
+ return "/" + path;
189
+ return path;
190
+ }
191
+ function isAbsolute(path) {
192
+ return assertPath(path), path.length > 0 && path.charCodeAt(0) === 47;
193
+ }
194
+ function join() {
195
+ if (arguments.length === 0)
196
+ return ".";
197
+ var joined;
198
+ for (var i = 0;i < arguments.length; ++i) {
199
+ var arg = arguments[i];
200
+ if (assertPath(arg), arg.length > 0)
201
+ if (joined === undefined)
202
+ joined = arg;
203
+ else
204
+ joined += "/" + arg;
205
+ }
206
+ if (joined === undefined)
207
+ return ".";
208
+ return normalize(joined);
209
+ }
210
+ function relative(from, to) {
211
+ if (assertPath(from), assertPath(to), from === to)
212
+ return "";
213
+ if (from = resolve(from), to = resolve(to), from === to)
214
+ return "";
215
+ var fromStart = 1;
216
+ for (;fromStart < from.length; ++fromStart)
217
+ if (from.charCodeAt(fromStart) !== 47)
218
+ break;
219
+ var fromEnd = from.length, fromLen = fromEnd - fromStart, toStart = 1;
220
+ for (;toStart < to.length; ++toStart)
221
+ if (to.charCodeAt(toStart) !== 47)
222
+ break;
223
+ var toEnd = to.length, toLen = toEnd - toStart, length = fromLen < toLen ? fromLen : toLen, lastCommonSep = -1, i = 0;
224
+ for (;i <= length; ++i) {
225
+ if (i === length) {
226
+ if (toLen > length) {
227
+ if (to.charCodeAt(toStart + i) === 47)
228
+ return to.slice(toStart + i + 1);
229
+ else if (i === 0)
230
+ return to.slice(toStart + i);
231
+ } else if (fromLen > length) {
232
+ if (from.charCodeAt(fromStart + i) === 47)
233
+ lastCommonSep = i;
234
+ else if (i === 0)
235
+ lastCommonSep = 0;
236
+ }
237
+ break;
238
+ }
239
+ var fromCode = from.charCodeAt(fromStart + i), toCode = to.charCodeAt(toStart + i);
240
+ if (fromCode !== toCode)
241
+ break;
242
+ else if (fromCode === 47)
243
+ lastCommonSep = i;
244
+ }
245
+ var out = "";
246
+ for (i = fromStart + lastCommonSep + 1;i <= fromEnd; ++i)
247
+ if (i === fromEnd || from.charCodeAt(i) === 47)
248
+ if (out.length === 0)
249
+ out += "..";
250
+ else
251
+ out += "/..";
252
+ if (out.length > 0)
253
+ return out + to.slice(toStart + lastCommonSep);
254
+ else {
255
+ if (toStart += lastCommonSep, to.charCodeAt(toStart) === 47)
256
+ ++toStart;
257
+ return to.slice(toStart);
258
+ }
259
+ }
260
+ function _makeLong(path) {
261
+ return path;
262
+ }
263
+ function dirname(path) {
264
+ if (assertPath(path), path.length === 0)
265
+ return ".";
266
+ var code = path.charCodeAt(0), hasRoot = code === 47, end = -1, matchedSlash = true;
267
+ for (var i = path.length - 1;i >= 1; --i)
268
+ if (code = path.charCodeAt(i), code === 47) {
269
+ if (!matchedSlash) {
270
+ end = i;
271
+ break;
272
+ }
273
+ } else
274
+ matchedSlash = false;
275
+ if (end === -1)
276
+ return hasRoot ? "/" : ".";
277
+ if (hasRoot && end === 1)
278
+ return "//";
279
+ return path.slice(0, end);
280
+ }
281
+ function basename(path, ext) {
282
+ if (ext !== undefined && typeof ext !== "string")
283
+ throw TypeError('"ext" argument must be a string');
284
+ assertPath(path);
285
+ var start = 0, end = -1, matchedSlash = true, i;
286
+ if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
287
+ if (ext.length === path.length && ext === path)
288
+ return "";
289
+ var extIdx = ext.length - 1, firstNonSlashEnd = -1;
290
+ for (i = path.length - 1;i >= 0; --i) {
291
+ var code = path.charCodeAt(i);
292
+ if (code === 47) {
293
+ if (!matchedSlash) {
294
+ start = i + 1;
295
+ break;
296
+ }
297
+ } else {
298
+ if (firstNonSlashEnd === -1)
299
+ matchedSlash = false, firstNonSlashEnd = i + 1;
300
+ if (extIdx >= 0)
301
+ if (code === ext.charCodeAt(extIdx)) {
302
+ if (--extIdx === -1)
303
+ end = i;
304
+ } else
305
+ extIdx = -1, end = firstNonSlashEnd;
306
+ }
307
+ }
308
+ if (start === end)
309
+ end = firstNonSlashEnd;
310
+ else if (end === -1)
311
+ end = path.length;
312
+ return path.slice(start, end);
313
+ } else {
314
+ for (i = path.length - 1;i >= 0; --i)
315
+ if (path.charCodeAt(i) === 47) {
316
+ if (!matchedSlash) {
317
+ start = i + 1;
318
+ break;
319
+ }
320
+ } else if (end === -1)
321
+ matchedSlash = false, end = i + 1;
322
+ if (end === -1)
323
+ return "";
324
+ return path.slice(start, end);
325
+ }
326
+ }
327
+ function extname(path) {
328
+ assertPath(path);
329
+ var startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0;
330
+ for (var i = path.length - 1;i >= 0; --i) {
331
+ var code = path.charCodeAt(i);
332
+ if (code === 47) {
333
+ if (!matchedSlash) {
334
+ startPart = i + 1;
335
+ break;
336
+ }
337
+ continue;
338
+ }
339
+ if (end === -1)
340
+ matchedSlash = false, end = i + 1;
341
+ if (code === 46) {
342
+ if (startDot === -1)
343
+ startDot = i;
344
+ else if (preDotState !== 1)
345
+ preDotState = 1;
346
+ } else if (startDot !== -1)
347
+ preDotState = -1;
348
+ }
349
+ if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
350
+ return "";
351
+ return path.slice(startDot, end);
352
+ }
353
+ function format(pathObject) {
354
+ if (pathObject === null || typeof pathObject !== "object")
355
+ throw TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
356
+ return _format("/", pathObject);
357
+ }
358
+ function parse(path) {
359
+ assertPath(path);
360
+ var ret = { root: "", dir: "", base: "", ext: "", name: "" };
361
+ if (path.length === 0)
362
+ return ret;
363
+ var code = path.charCodeAt(0), isAbsolute2 = code === 47, start;
364
+ if (isAbsolute2)
365
+ ret.root = "/", start = 1;
366
+ else
367
+ start = 0;
368
+ var startDot = -1, startPart = 0, end = -1, matchedSlash = true, i = path.length - 1, preDotState = 0;
369
+ for (;i >= start; --i) {
370
+ if (code = path.charCodeAt(i), code === 47) {
371
+ if (!matchedSlash) {
372
+ startPart = i + 1;
373
+ break;
374
+ }
375
+ continue;
376
+ }
377
+ if (end === -1)
378
+ matchedSlash = false, end = i + 1;
379
+ if (code === 46) {
380
+ if (startDot === -1)
381
+ startDot = i;
382
+ else if (preDotState !== 1)
383
+ preDotState = 1;
384
+ } else if (startDot !== -1)
385
+ preDotState = -1;
386
+ }
387
+ if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
388
+ if (end !== -1)
389
+ if (startPart === 0 && isAbsolute2)
390
+ ret.base = ret.name = path.slice(1, end);
391
+ else
392
+ ret.base = ret.name = path.slice(startPart, end);
393
+ } else {
394
+ if (startPart === 0 && isAbsolute2)
395
+ ret.name = path.slice(1, startDot), ret.base = path.slice(1, end);
396
+ else
397
+ ret.name = path.slice(startPart, startDot), ret.base = path.slice(startPart, end);
398
+ ret.ext = path.slice(startDot, end);
399
+ }
400
+ if (startPart > 0)
401
+ ret.dir = path.slice(0, startPart - 1);
402
+ else if (isAbsolute2)
403
+ ret.dir = "/";
404
+ return ret;
405
+ }
406
+ var sep = "/", delimiter = ":", posix, path_default;
407
+ var init_path = __esm(() => {
408
+ posix = ((p) => (p.posix = p, p))({ resolve, normalize, isAbsolute, join, relative, _makeLong, dirname, basename, extname, format, parse, sep, delimiter, win32: null, posix: null });
409
+ path_default = posix;
410
+ });
411
+
412
+ // src/shared/lib/sweep-sealed.ts
413
+ var exports_sweep_sealed = {};
414
+ __export(exports_sweep_sealed, {
415
+ sweepSealed: () => sweepSealed
416
+ });
417
+ import { Automerge } from "@automerge/automerge-repo/slim";
418
+ function concat(parts) {
419
+ let total = 0;
420
+ for (const part of parts)
421
+ total += part.byteLength;
422
+ const out = new Uint8Array(total);
423
+ let offset = 0;
424
+ for (const part of parts) {
425
+ out.set(part, offset);
426
+ offset += part.byteLength;
427
+ }
428
+ return out;
429
+ }
430
+ function materialise(chunks) {
431
+ 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));
432
+ if (content.length === 0)
433
+ return;
434
+ try {
435
+ return Automerge.loadIncremental(Automerge.init(), concat(content.map((chunk) => chunk.data)));
436
+ } catch {
437
+ return;
438
+ }
439
+ }
440
+ async function collectChunksByDocument(storage, documentIds) {
441
+ const chunks = [];
442
+ if (documentIds === undefined) {
443
+ chunks.push(...await storage.loadRange([]));
444
+ } else {
445
+ for (const documentId of documentIds) {
446
+ chunks.push(...await storage.loadRange([documentId]));
447
+ }
448
+ }
449
+ const byDocument = new Map;
450
+ for (const chunk of chunks) {
451
+ const documentId = chunk.key[0];
452
+ if (documentId === undefined)
453
+ continue;
454
+ const existing = byDocument.get(documentId);
455
+ if (existing)
456
+ existing.push(chunk);
457
+ else
458
+ byDocument.set(documentId, [chunk]);
459
+ }
460
+ return byDocument;
461
+ }
462
+ function classifyDocument(documentId, chunks, context) {
463
+ const doc = materialise(chunks);
464
+ if (doc === undefined)
465
+ return { action: "ignore" };
466
+ const sealedAt = context.isSealed(doc);
467
+ if (sealedAt === undefined)
468
+ return { action: "ignore" };
469
+ const id = documentId;
470
+ if (context.repo.handles[id] !== undefined) {
471
+ return { action: "keep", entry: { documentId: id, reason: "open-handle" } };
472
+ }
473
+ if (context.at - sealedAt < context.olderThan) {
474
+ return { action: "keep", entry: { documentId: id, reason: "too-recent" } };
475
+ }
476
+ const byteSize = chunks.reduce((sum, chunk) => sum + (chunk.data?.byteLength ?? 0), 0);
477
+ return { action: "sweep", entry: { documentId: id, sealedAt, byteSize } };
478
+ }
479
+ async function sweepSealed(options) {
480
+ const { repo, storage, isSealed, olderThan } = options;
481
+ const dryRun = options.dryRun ?? false;
482
+ const now = options.now ?? Date.now;
483
+ const byDocument = await collectChunksByDocument(storage, options.documentIds);
484
+ const swept = [];
485
+ const kept = [];
486
+ const at = now();
487
+ for (const [documentId, chunks] of byDocument) {
488
+ const verdict = classifyDocument(documentId, chunks, { repo, isSealed, olderThan, at });
489
+ if (verdict.action === "keep") {
490
+ kept.push(verdict.entry);
491
+ } else if (verdict.action === "sweep") {
492
+ swept.push(verdict.entry);
493
+ if (!dryRun)
494
+ await storage.removeRange([documentId]);
495
+ }
496
+ }
497
+ return { swept, kept, dryRun };
498
+ }
499
+ var init_sweep_sealed = () => {};
500
+
72
501
  // src/elysia/peer-repo-plugin.ts
73
502
  import { Elysia } from "elysia";
74
503
 
75
504
  // src/shared/lib/peer-repo-server.ts
505
+ async function listNodeFSDocumentIds(baseDirectory) {
506
+ const [{ readdir }, { join: join2 }] = await Promise.all([
507
+ import("node:fs/promises"),
508
+ Promise.resolve().then(() => (init_path(), exports_path))
509
+ ]);
510
+ let shards;
511
+ try {
512
+ shards = await readdir(baseDirectory);
513
+ } catch (error) {
514
+ if (error.code === "ENOENT")
515
+ return [];
516
+ throw error;
517
+ }
518
+ const documentIds = [];
519
+ for (const shard of shards) {
520
+ const entries = await readdir(join2(baseDirectory, shard), {
521
+ withFileTypes: true
522
+ }).catch(() => []);
523
+ for (const entry of entries) {
524
+ if (entry.isDirectory())
525
+ documentIds.push(shard + entry.name);
526
+ }
527
+ }
528
+ return documentIds;
529
+ }
76
530
  async function createPeerRepoServer(options) {
77
531
  const [{ Repo }, { WebSocketServerAdapter }, { NodeFSStorageAdapter }, ws] = await Promise.all([
78
532
  import("@automerge/automerge-repo/slim"),
@@ -80,15 +534,16 @@ async function createPeerRepoServer(options) {
80
534
  import("@automerge/automerge-repo-storage-nodefs"),
81
535
  import("ws")
82
536
  ]);
83
- const wss = await (options.webSocketServer ? Promise.resolve(options.webSocketServer) : new Promise((resolve, reject) => {
537
+ const wss = await (options.webSocketServer ? Promise.resolve(options.webSocketServer) : new Promise((resolve2, reject) => {
84
538
  const created = new ws.WebSocketServer({
85
539
  port: options.port,
86
540
  ...options.host !== undefined && { host: options.host }
87
- }, () => resolve(created));
541
+ }, () => resolve2(created));
88
542
  created.once("error", reject);
89
543
  }));
90
544
  const adapter = new WebSocketServerAdapter(wss);
91
- const storage = new NodeFSStorageAdapter(options.storagePath);
545
+ const storagePath = options.storagePath ?? "automerge-repo-data";
546
+ const storage = new NodeFSStorageAdapter(storagePath);
92
547
  const repo = new Repo({
93
548
  network: [adapter],
94
549
  storage
@@ -99,6 +554,11 @@ async function createPeerRepoServer(options) {
99
554
  webSocketServer: wss,
100
555
  adapter,
101
556
  storage,
557
+ sweepSealed: async (sweepOptions) => {
558
+ const documentIds = await listNodeFSDocumentIds(storagePath);
559
+ const { sweepSealed: sweepSealed2 } = await Promise.resolve().then(() => (init_sweep_sealed(), exports_sweep_sealed));
560
+ return sweepSealed2({ repo, storage, documentIds, ...sweepOptions });
561
+ },
102
562
  close: async () => {
103
563
  for (const client of wss.clients) {
104
564
  try {
@@ -436,4 +896,4 @@ export {
436
896
  peerRepo
437
897
  };
438
898
 
439
- //# debugId=EDAD4E57925183E464756E2164756E21
899
+ //# debugId=77B9B7B157F0E2A364756E2164756E21