@summerscar/dsh-mnemon-sync 0.1.3 → 0.1.4

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 (2) hide show
  1. package/package.json +1 -1
  2. package/targets.js +24 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@summerscar/dsh-mnemon-sync",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Back up and restore dsh-mnemon memory components (memory spaces, project documents, runtime memory) to S3-compatible storage or WebDAV.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/targets.js CHANGED
@@ -266,7 +266,29 @@ function parseWebDavListing(xml, remotePath) {
266
266
  modifiedAt: textOf(/<[^:>]*:?getlastmodified[^>]*>([^<]+)</iu.exec(block)),
267
267
  })
268
268
  }
269
- return entries.sort((left, right) => String(right.modifiedAt ?? '').localeCompare(String(left.modifiedAt ?? '')))
269
+ return newestFirst(entries)
270
+ }
271
+
272
+ /**
273
+ * Sort archives newest first.
274
+ *
275
+ * `modifiedAt` is an RFC 1123 string (`Sun, 09 Nov 2026 08:00:00 GMT`) from
276
+ * WebDAV and an ISO 8601 string from S3. Comparing those as text is wrong: the
277
+ * weekday and day lead the WebDAV form, so "09 Nov 23:00" sorts before
278
+ * "10 Nov 01:00" even though it is older. Parse to an instant instead.
279
+ *
280
+ * An unparseable or missing stamp sorts last rather than corrupting the order:
281
+ * a listing that cannot say when something was written should not push a
282
+ * usable row off the top.
283
+ */
284
+ function newestFirst(entries) {
285
+ const stamp = (entry) => {
286
+ const value = entry?.modifiedAt
287
+ if (typeof value !== 'string') return Number.NEGATIVE_INFINITY
288
+ const parsed = Date.parse(value)
289
+ return Number.isNaN(parsed) ? Number.NEGATIVE_INFINITY : parsed
290
+ }
291
+ return entries.sort((left, right) => stamp(right) - stamp(left))
270
292
  }
271
293
 
272
294
  function integerOf(match) {
@@ -465,7 +487,7 @@ async function listS3(target, signal) {
465
487
  modifiedAt: textOf(/<LastModified>([^<]+)<\/LastModified>/u.exec(block)),
466
488
  })
467
489
  }
468
- return entries.sort((left, right) => String(right.modifiedAt ?? '').localeCompare(String(left.modifiedAt ?? '')))
490
+ return newestFirst(entries)
469
491
  }
470
492
 
471
493
  /**