sliftutils 1.4.54 → 1.4.56

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/index.d.ts CHANGED
@@ -1090,6 +1090,7 @@ declare module "sliftutils/storage/BulkDatabase2/BulkDatabaseBase" {
1090
1090
  name: string;
1091
1091
  type: "bulk" | "stream";
1092
1092
  bytes: number;
1093
+ lastModified: number;
1093
1094
  getDetails: () => Promise<BulkFileDetails>;
1094
1095
  };
1095
1096
  export type BulkFileInfoListing = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.4.54",
3
+ "version": "1.4.56",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -166,6 +166,7 @@ export type BulkFileEntry = {
166
166
  name: string;
167
167
  type: "bulk" | "stream";
168
168
  bytes: number;
169
+ lastModified: number;
169
170
  getDetails: () => Promise<BulkFileDetails>;
170
171
  };
171
172
  export type BulkFileInfoListing = {
@@ -926,39 +926,52 @@ export class BulkDatabaseBase<T extends { key: string }> {
926
926
  public async getFileInfo(): Promise<BulkFileInfoListing> {
927
927
  const { bulkFiles, streamFiles } = await this.listFiles();
928
928
  const storage = await this.storage();
929
- const sizeOf = async (name: string) => { try { return (await storage.getInfo(name))?.size ?? 0; } catch { return 0; } };
930
- const bulkInfos = await Promise.all(bulkFiles.map(async f => ({
931
- name: f.fileName,
932
- type: "bulk" as const,
933
- bytes: await sizeOf(f.fileName),
934
- getDetails: async () => {
935
- // Bulk: reader has keys + per-row keyTimes + header minTime/maxTime. Cached, so cheap.
936
- const reader = await loadFileReader(this.name, storage, f, this.subCaches.bulk);
937
- return { keys: reader.keys, minTime: reader.minTime, maxTime: reader.maxTime };
938
- },
939
- })));
940
- const streamInfos = await Promise.all(streamFiles.map(async f => ({
941
- name: f.fileName,
942
- type: "stream" as const,
943
- bytes: await sizeOf(f.fileName),
944
- getDetails: async () => {
945
- // Stream: must parse the file to walk every entry — header has no key/time bounds. Cached.
946
- const data = await loadStreamEntries(this.name, storage, [f], this.subCaches.stream);
947
- const keys = new Set<string>();
948
- let minTime = Infinity, maxTime = -Infinity;
949
- for (const e of data.entries) {
950
- if (e.time < minTime) minTime = e.time;
951
- if (e.time > maxTime) maxTime = e.time;
952
- if (e.entry.row) keys.add(e.entry.row.key as string);
953
- else if (e.entry.deletedKey !== undefined) keys.add(e.entry.deletedKey);
954
- }
955
- return {
956
- keys: [...keys],
957
- minTime: minTime === Infinity ? 0 : minTime,
958
- maxTime: maxTime === -Infinity ? 0 : maxTime,
959
- };
960
- },
961
- })));
929
+ const statOf = async (name: string) => {
930
+ try {
931
+ const info = await storage.getInfo(name);
932
+ return { bytes: info?.size ?? 0, lastModified: info?.lastModified ?? 0 };
933
+ } catch { return { bytes: 0, lastModified: 0 }; }
934
+ };
935
+ const bulkInfos = await Promise.all(bulkFiles.map(async f => {
936
+ const stat = await statOf(f.fileName);
937
+ return {
938
+ name: f.fileName,
939
+ type: "bulk" as const,
940
+ bytes: stat.bytes,
941
+ lastModified: stat.lastModified,
942
+ getDetails: async () => {
943
+ // Bulk: reader has keys + per-row keyTimes + header minTime/maxTime. Cached, so cheap.
944
+ const reader = await loadFileReader(this.name, storage, f, this.subCaches.bulk);
945
+ return { keys: reader.keys, minTime: reader.minTime, maxTime: reader.maxTime };
946
+ },
947
+ };
948
+ }));
949
+ const streamInfos = await Promise.all(streamFiles.map(async f => {
950
+ const stat = await statOf(f.fileName);
951
+ return {
952
+ name: f.fileName,
953
+ type: "stream" as const,
954
+ bytes: stat.bytes,
955
+ lastModified: stat.lastModified,
956
+ getDetails: async () => {
957
+ // Stream: must parse the file to walk every entry — header has no key/time bounds. Cached.
958
+ const data = await loadStreamEntries(this.name, storage, [f], this.subCaches.stream);
959
+ const keys = new Set<string>();
960
+ let minTime = Infinity, maxTime = -Infinity;
961
+ for (const e of data.entries) {
962
+ if (e.time < minTime) minTime = e.time;
963
+ if (e.time > maxTime) maxTime = e.time;
964
+ if (e.entry.row) keys.add(e.entry.row.key as string);
965
+ else if (e.entry.deletedKey !== undefined) keys.add(e.entry.deletedKey);
966
+ }
967
+ return {
968
+ keys: [...keys],
969
+ minTime: minTime === Infinity ? 0 : minTime,
970
+ maxTime: maxTime === -Infinity ? 0 : maxTime,
971
+ };
972
+ },
973
+ };
974
+ }));
962
975
  const files = [...bulkInfos, ...streamInfos];
963
976
  return { files, count: files.length, totalBytes: files.reduce((a, f) => a + f.bytes, 0) };
964
977
  }
@@ -969,6 +982,8 @@ export type BulkFileEntry = {
969
982
  name: string;
970
983
  type: "bulk" | "stream";
971
984
  bytes: number;
985
+ // Filesystem mtime (ms since epoch) — 0 if the storage layer didn't return one.
986
+ lastModified: number;
972
987
  // Lazy: pulled from the cached sub-reader for bulk (free if loaded), or from a parse of the stream
973
988
  // file (small — tier-0 size-capped, also cached). Call only when you need the per-file detail.
974
989
  getDetails: () => Promise<BulkFileDetails>;